soc: imx: gpcv2: add support for optional resets
authorLucas Stach <l.stach@pengutronix.de>
Mon, 10 May 2021 04:00:41 +0000 (12:00 +0800)
committerShawn Guo <shawnguo@kernel.org>
Sun, 23 May 2021 02:58:12 +0000 (10:58 +0800)
Normally the reset for the devices inside the power domain is
triggered automatically from the PGC in the power-up sequencing,
however on i.MX8MM this doesn't work for the GPU power domains.

Add support for triggering the reset explicitly during the power
up sequencing.

Tested-by: Frieder Schrempf <frieder.schrempf@kontron.de>
Reviewed-by: Frieder Schrempf <frieder.schrempf@kontron.de>
Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
Signed-off-by: Peng Fan <peng.fan@nxp.com>
Signed-off-by: Shawn Guo <shawnguo@kernel.org>
drivers/soc/imx/gpcv2.c

index fdf759a7c865d23a454f3302a409c101fc4a1faf..04ce64326c19e4e51608c792b04a7d40bc24eb85 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/pm_runtime.h>
 #include <linux/regmap.h>
 #include <linux/regulator/consumer.h>
+#include <linux/reset.h>
 #include <linux/sizes.h>
 #include <dt-bindings/power/imx7-power.h>
 #include <dt-bindings/power/imx8mq-power.h>
@@ -108,6 +109,7 @@ struct imx_pgc_domain {
        struct generic_pm_domain genpd;
        struct regmap *regmap;
        struct regulator *regulator;
+       struct reset_control *reset;
        struct clk_bulk_data *clks;
        int num_clks;
 
@@ -163,6 +165,8 @@ static int imx_pgc_power_up(struct generic_pm_domain *genpd)
                goto out_regulator_disable;
        }
 
+       reset_control_assert(domain->reset);
+
        if (domain->bits.pxx) {
                /* request the domain to power up */
                regmap_update_bits(domain->regmap, GPC_PU_PGC_SW_PUP_REQ,
@@ -185,6 +189,11 @@ static int imx_pgc_power_up(struct generic_pm_domain *genpd)
                                  GPC_PGC_CTRL_PCR);
        }
 
+       /* delay for reset to propagate */
+       udelay(5);
+
+       reset_control_deassert(domain->reset);
+
        /* request the ADB400 to power up */
        if (domain->bits.hskreq) {
                regmap_update_bits(domain->regmap, GPC_PU_PWRHSK,
@@ -540,6 +549,11 @@ static int imx_pgc_domain_probe(struct platform_device *pdev)
                return dev_err_probe(domain->dev, domain->num_clks,
                                     "Failed to get domain's clocks\n");
 
+       domain->reset = devm_reset_control_array_get_optional_exclusive(domain->dev);
+       if (IS_ERR(domain->reset))
+               return dev_err_probe(domain->dev, PTR_ERR(domain->reset),
+                                    "Failed to get domain's resets\n");
+
        pm_runtime_enable(domain->dev);
 
        if (domain->bits.map)