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

Reply via email to