Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 05f6e10e authored by Kyle Yan's avatar Kyle Yan
Browse files

soc: qcom: pil: Always assert and deassert restart signals on SDM845



SDM845 brings in new reset signal ALT_RESET which is part of the MSS
subsystem. New usage of boot IMEM means that modem is not in a complete
reset state at pil_boot and therefore full reset is needed at the start.

Change-Id: I9d6787422dd5e2971c4b484386efd51deea2027a
Signed-off-by: default avatarKyle Yan <kyan@codeaurora.org>
parent 8e80530c
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -18,6 +18,8 @@ Required properties:
		      "halt_nc" is required.
		      "pdc_sync" is the power domain register introduced in
		      sdm845 for power domain of subsystems.
		      If alternative reset is required, "alt_reset" maps to
		      mss_alt_ares.
- interrupts:         The modem watchdog interrupt
- vdd_cx-supply:      Reference to the regulator that supplies the vdd_cx domain.
- vdd_cx-voltage:     Voltage corner/level(max) for cx rail.
+49 −12
Original line number Diff line number Diff line
@@ -225,6 +225,16 @@ static void pil_mss_pdc_sync(struct q6v5_data *drv, bool pdc_sync)
	}
}

static void pil_mss_alt_reset(struct q6v5_data *drv, u32 val)
{
	if (drv->alt_reset) {
		writel_relaxed(val, drv->alt_reset);
		/* Ensure alt reset is written before restart reg */
		wmb();
		udelay(2);
	}
}

static int pil_mss_restart_reg(struct q6v5_data *drv, u32 mss_restart)
{
	int ret = 0;
@@ -256,6 +266,32 @@ static int pil_mss_restart_reg(struct q6v5_data *drv, u32 mss_restart)
	return ret;
}

static int pil_mss_assert_resets(struct q6v5_data *drv)
{
	int ret = 0;

	pil_mss_pdc_sync(drv, 1);
	pil_mss_alt_reset(drv, 1);
	ret = pil_mss_restart_reg(drv, true);

	return ret;
}

static int pil_mss_deassert_resets(struct q6v5_data *drv)
{
	int ret = 0;

	ret = pil_mss_restart_reg(drv, 0);
	if (ret)
		return ret;
	/* Wait 6 32kHz sleep cycles for reset */
	udelay(200);
	pil_mss_alt_reset(drv, 0);
	pil_mss_pdc_sync(drv, false);

	return ret;
}

static int pil_msa_wait_for_mba_ready(struct q6v5_data *drv)
{
	struct device *dev = drv->desc.dev;
@@ -325,8 +361,10 @@ int pil_mss_shutdown(struct pil_desc *pil)
									ret);
	}

	pil_mss_pdc_sync(drv, 1);
	ret = pil_mss_restart_reg(drv, 1);
	pil_mss_assert_resets(drv);
	/* Wait 6 32kHz sleep cycles for reset */
	udelay(200);
	ret = pil_mss_deassert_resets(drv);

	if (drv->is_booted) {
		pil_mss_disable_clks(drv);
@@ -485,17 +523,18 @@ static int pil_mss_reset(struct pil_desc *pil)
	if (ret)
		goto err_power;

	/* Deassert reset to subsystem and wait for propagation */
	ret = pil_mss_restart_reg(drv, 0);
	if (ret)
		goto err_restart;

	pil_mss_pdc_sync(drv, 0);

	ret = pil_mss_enable_clks(drv);
	if (ret)
		goto err_clks;

	/* Assert reset to subsystem */
	pil_mss_assert_resets(drv);
	/* Wait 6 32kHz sleep cycles for reset */
	udelay(200);
	ret = pil_mss_deassert_resets(drv);
	if (ret)
		goto err_restart;

	if (modem_dbg_cfg)
		writel_relaxed(modem_dbg_cfg, drv->reg_base + QDSP6SS_DBG_CFG);

@@ -543,13 +582,11 @@ static int pil_mss_reset(struct pil_desc *pil)

err_q6v5_reset:
	modem_log_rmb_regs(drv->rmb_base);
err_restart:
	pil_mss_disable_clks(drv);
	if (drv->ahb_clk_vote)
		clk_disable_unprepare(drv->ahb_clk);
err_clks:
	pil_mss_pdc_sync(drv, 1);
	pil_mss_restart_reg(drv, 1);
err_restart:
	pil_mss_power_down(drv);
err_power:
	return ret;
+7 −0
Original line number Diff line number Diff line
@@ -291,6 +291,13 @@ static int pil_mss_loadable_init(struct modem_data *drv,
						res->start, resource_size(res));
	}

	q6->alt_reset = NULL;
	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "alt_reset");
	if (res) {
		q6->alt_reset = devm_ioremap(&pdev->dev,
						res->start, resource_size(res));
	}

	q6->vreg = NULL;

	prop = of_find_property(pdev->dev.of_node, "vdd_mss-supply", NULL);
+1 −0
Original line number Diff line number Diff line
@@ -45,6 +45,7 @@ struct q6v5_data {
	void __iomem *axi_halt_nc;
	void __iomem *restart_reg;
	void __iomem *pdc_sync;
	void __iomem *alt_reset;
	struct regulator *vreg;
	struct regulator *vreg_cx;
	struct regulator *vreg_mx;