Skip to content

Commit

Permalink
soc: imx: gpc: fix power up sequencing
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Lucas Stach authored and Shawn Guo committed Mar 16, 2020
1 parent fc40200 commit e0ea2d1
Showing 1 changed file with 13 additions and 11 deletions.
24 changes: 13 additions & 11 deletions drivers/soc/imx/gpc.c
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,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);
Expand All @@ -107,17 +107,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++)
Expand Down Expand Up @@ -343,6 +344,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[] = {
Expand Down

0 comments on commit e0ea2d1

Please sign in to comment.