soc: imx: gpcv2: add support for optional resets

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>
This commit is contained in:
Lucas Stach 2021-05-10 12:00:41 +08:00 committed by Shawn Guo
parent c0ce75395f
commit fe58c887fb

View File

@ -15,6 +15,7 @@
#include <linux/pm_runtime.h> #include <linux/pm_runtime.h>
#include <linux/regmap.h> #include <linux/regmap.h>
#include <linux/regulator/consumer.h> #include <linux/regulator/consumer.h>
#include <linux/reset.h>
#include <linux/sizes.h> #include <linux/sizes.h>
#include <dt-bindings/power/imx7-power.h> #include <dt-bindings/power/imx7-power.h>
#include <dt-bindings/power/imx8mq-power.h> #include <dt-bindings/power/imx8mq-power.h>
@ -108,6 +109,7 @@ struct imx_pgc_domain {
struct generic_pm_domain genpd; struct generic_pm_domain genpd;
struct regmap *regmap; struct regmap *regmap;
struct regulator *regulator; struct regulator *regulator;
struct reset_control *reset;
struct clk_bulk_data *clks; struct clk_bulk_data *clks;
int num_clks; int num_clks;
@ -163,6 +165,8 @@ static int imx_pgc_power_up(struct generic_pm_domain *genpd)
goto out_regulator_disable; goto out_regulator_disable;
} }
reset_control_assert(domain->reset);
if (domain->bits.pxx) { if (domain->bits.pxx) {
/* request the domain to power up */ /* request the domain to power up */
regmap_update_bits(domain->regmap, GPC_PU_PGC_SW_PUP_REQ, 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); GPC_PGC_CTRL_PCR);
} }
/* delay for reset to propagate */
udelay(5);
reset_control_deassert(domain->reset);
/* request the ADB400 to power up */ /* request the ADB400 to power up */
if (domain->bits.hskreq) { if (domain->bits.hskreq) {
regmap_update_bits(domain->regmap, GPC_PU_PWRHSK, 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, return dev_err_probe(domain->dev, domain->num_clks,
"Failed to get domain's clocks\n"); "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); pm_runtime_enable(domain->dev);
if (domain->bits.map) if (domain->bits.map)