summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLucas Stach <l.stach@pengutronix.de>2020-03-13 11:09:12 +0100
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2020-04-24 08:01:18 +0200
commit617dcdd3d27d0f5059bafe88d44750b13efc4e5c (patch)
treed6352dae5f3dd5814d0759d20a3da49981840538
parent1fec728da800320099a7c6fd10e5e766379b043c (diff)
downloadlinux-617dcdd3d27d0f5059bafe88d44750b13efc4e5c.tar.gz
linux-617dcdd3d27d0f5059bafe88d44750b13efc4e5c.tar.bz2
linux-617dcdd3d27d0f5059bafe88d44750b13efc4e5c.zip
soc: imx: gpc: fix power up sequencing
[ Upstream commit e0ea2d11f8a08ba7066ff897e16c5217215d1e68 ] Currently we wait only until the PGC inverts the isolation setting before disabling the peripheral clocks. This doesn't ensure that the reset is properly propagated through the peripheral devices in the power domain. Wait until the PGC signals that the power up request is done and wait a bit for resets to propagate before disabling the clocks. Signed-off-by: Lucas Stach <l.stach@pengutronix.de> Signed-off-by: Shawn Guo <shawnguo@kernel.org> Signed-off-by: Sasha Levin <sashal@kernel.org>
-rw-r--r--drivers/soc/imx/gpc.c24
1 files changed, 13 insertions, 11 deletions
diff --git a/drivers/soc/imx/gpc.c b/drivers/soc/imx/gpc.c
index 3a12123de466..0e083fe8b893 100644
--- a/drivers/soc/imx/gpc.c
+++ b/drivers/soc/imx/gpc.c
@@ -97,8 +97,8 @@ static int imx6_pm_domain_power_off(struct generic_pm_domain *genpd)
static int imx6_pm_domain_power_on(struct generic_pm_domain *genpd)
{
struct imx_pm_domain *pd = to_imx_pm_domain(genpd);
- int i, ret, sw, sw2iso;
- u32 val;
+ int i, ret;
+ u32 val, req;
if (pd->supply) {
ret = regulator_enable(pd->supply);
@@ -117,17 +117,18 @@ static int imx6_pm_domain_power_on(struct generic_pm_domain *genpd)
regmap_update_bits(pd->regmap, pd->reg_offs + GPC_PGC_CTRL_OFFS,
0x1, 0x1);
- /* Read ISO and ISO2SW power up delays */
- regmap_read(pd->regmap, pd->reg_offs + GPC_PGC_PUPSCR_OFFS, &val);
- sw = val & 0x3f;
- sw2iso = (val >> 8) & 0x3f;
-
/* Request GPC to power up domain */
- val = BIT(pd->cntr_pdn_bit + 1);
- regmap_update_bits(pd->regmap, GPC_CNTR, val, val);
+ req = BIT(pd->cntr_pdn_bit + 1);
+ regmap_update_bits(pd->regmap, GPC_CNTR, req, req);
- /* Wait ISO + ISO2SW IPG clock cycles */
- udelay(DIV_ROUND_UP(sw + sw2iso, pd->ipg_rate_mhz));
+ /* Wait for the PGC to handle the request */
+ ret = regmap_read_poll_timeout(pd->regmap, GPC_CNTR, val, !(val & req),
+ 1, 50);
+ if (ret)
+ pr_err("powerup request on domain %s timed out\n", genpd->name);
+
+ /* Wait for reset to propagate through peripherals */
+ usleep_range(5, 10);
/* Disable reset clocks for all devices in the domain */
for (i = 0; i < pd->num_clks; i++)
@@ -329,6 +330,7 @@ static const struct regmap_config imx_gpc_regmap_config = {
.rd_table = &access_table,
.wr_table = &access_table,
.max_register = 0x2ac,
+ .fast_io = true,
};
static struct generic_pm_domain *imx_gpc_onecell_domains[] = {