On the i.MX7D, the integrated anatop regulator needs to be configured and enabled with the power domains.
Signed-off-by: Nora Schiffer <[email protected]> --- drivers/power/domain/imx-gpcv2-power-domain.c | 36 ++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/drivers/power/domain/imx-gpcv2-power-domain.c b/drivers/power/domain/imx-gpcv2-power-domain.c index b94ec60fc0d..d6334d1b8c3 100644 --- a/drivers/power/domain/imx-gpcv2-power-domain.c +++ b/drivers/power/domain/imx-gpcv2-power-domain.c @@ -14,6 +14,7 @@ #include <dm/device_compat.h> #include <imx_sip.h> #include <linux/bitmap.h> +#include <power/regulator.h> #include <wait_bit.h> #include <dt-bindings/power/imx8mm-power.h> @@ -128,6 +129,7 @@ struct imx_pgc_domain { u32 hskack; } bits; + const int voltage; const bool keep_clocks; }; @@ -141,6 +143,7 @@ struct imx_gpcv2_power_domain_plat { struct power_domain pd; const struct imx_pgc_domain *domain; const struct imx_pgc_regs *regs; + struct udevice *regulator; struct clk_bulk clk; void __iomem *base; int resource_id; @@ -343,11 +346,19 @@ static int imx_gpcv2_power_domain_on(struct power_domain *power_domain) u32 pgc; int ret; + if (pdata->regulator) { + ret = regulator_enable(pdata->regulator); + if (ret) { + dev_err(dev, "failed to enable regulator: %d\n", ret); + return ret; + } + } + if (pdata->clk.count) { ret = clk_enable_bulk(&pdata->clk); if (ret) { dev_err(dev, "failed to enable reset clocks\n"); - return ret; + goto out_regulator_disable; } } @@ -392,6 +403,9 @@ static int imx_gpcv2_power_domain_on(struct power_domain *power_domain) out_clk_disable: if (pdata->clk.count) clk_disable_bulk(&pdata->clk); +out_regulator_disable: + if (pdata->regulator) + regulator_disable(pdata->regulator); return ret; } @@ -450,6 +464,14 @@ static int imx_gpcv2_power_domain_off(struct power_domain *power_domain) if (pdata->clk.count) clk_disable_bulk(&pdata->clk); + if (pdata->regulator) { + ret = regulator_disable(pdata->regulator); + if (ret) { + dev_err(dev, "failed to disable regulator: %d\n", ret); + return ret; + } + } + if (pdata->has_pd) power_domain_off(&pdata->pd); @@ -458,6 +480,8 @@ static int imx_gpcv2_power_domain_off(struct power_domain *power_domain) out_clk_disable: if (!domain->keep_clocks && pdata->clk.count) clk_disable_bulk(&pdata->clk); + if (pdata->regulator) + regulator_disable(pdata->regulator); return ret; } @@ -515,6 +539,16 @@ static int imx_gpcv2_power_domain_probe(struct udevice *dev) if (!strstr(dev->name, "power-domain")) return 0; + ret = device_get_supply_regulator(dev, "power-supply", &pdata->regulator); + if (ret) { + if (ret != -ENOENT && ret != -ENOSYS) { + dev_err(dev, "Failed to get domain's regulator (%d)\n", ret); + return ret; + } + } else if (pdata->domain->voltage) { + regulator_set_value(pdata->regulator, pdata->domain->voltage); + } + /* Grab optional power domain clock. */ ret = clk_get_bulk(dev, &pdata->clk); if (ret && ret != -ENOENT && ret != -ENOSYS) { -- 2.55.0
