MLK-11607: ARM: imx: gpc: keep PU always on i.mx6qp
authorRobin Gong <b38343@freescale.com>
Wed, 23 Sep 2015 08:43:29 +0000 (16:43 +0800)
committerNitin Garg <nitin.garg@nxp.com>
Mon, 19 Mar 2018 19:48:41 +0000 (14:48 -0500)
Keep PU always on i.mx6qp, this patch is mostly like the below patch on v3.14
with slight difference on v4.1:
"MLK-10465: ARM: imx6qp: keep PU always on for TKT259465"

Signed-off-by: Robin Gong <b38343@freescale.com>
arch/arm/mach-imx/gpc.c

index dc692af..b8a420b 100644 (file)
@@ -85,6 +85,10 @@ static u32 gpc_mf_irqs[IMR_NUM];
 static u32 gpc_mf_request_on[IMR_NUM];
 static DEFINE_SPINLOCK(gpc_lock);
 static struct notifier_block nb_pcie;
+static struct pu_domain imx6q_pu_domain;
+static bool pu_on;      /* keep always on i.mx6qp */
+static void _imx6q_pm_pu_power_off(struct generic_pm_domain *genpd);
+static void _imx6q_pm_pu_power_on(struct generic_pm_domain *genpd);
 
 void imx_gpc_add_m4_wake_up_irq(u32 hwirq, bool enable)
 {
@@ -187,6 +191,9 @@ void imx_gpc_pre_suspend(bool arm_power_off)
        void __iomem *reg_imr1 = gpc_base + GPC_IMR1;
        int i;
 
+       if (cpu_is_imx6q() && imx_get_soc_revision() == IMX_CHIP_REVISION_2_0)
+               _imx6q_pm_pu_power_off(&imx6q_pu_domain.base);
+
        /* power down the mega-fast power domain */
        if ((cpu_is_imx6sx() || cpu_is_imx6ul()) && arm_power_off)
                imx_gpc_mf_mix_off();
@@ -206,6 +213,9 @@ void imx_gpc_post_resume(void)
        void __iomem *reg_imr1 = gpc_base + GPC_IMR1;
        int i;
 
+       if (cpu_is_imx6q() && imx_get_soc_revision() == IMX_CHIP_REVISION_2_0)
+               _imx6q_pm_pu_power_on(&imx6q_pu_domain.base);
+
        /* Keep ARM core powered on for other low-power modes */
        imx_gpc_set_arm_power_in_lpm(false);
        /* Keep M/F mix powered on for other low-power modes */
@@ -547,6 +557,10 @@ static int imx6q_pm_pu_power_off(struct generic_pm_domain *genpd)
 {
        struct pu_domain *pu = container_of(genpd, struct pu_domain, base);
 
+       if (&imx6q_pu_domain == pu && pu_on && cpu_is_imx6q() &&
+               imx_get_soc_revision() == IMX_CHIP_REVISION_2_0)
+               return 0;
+
        _imx6q_pm_pu_power_off(genpd);
 
        if (pu->reg)
@@ -555,19 +569,12 @@ static int imx6q_pm_pu_power_off(struct generic_pm_domain *genpd)
        return 0;
 }
 
-static int imx6q_pm_pu_power_on(struct generic_pm_domain *genpd)
+static void _imx6q_pm_pu_power_on(struct generic_pm_domain *genpd)
 {
        struct pu_domain *pu = container_of(genpd, struct pu_domain, base);
-       int i, ret, sw, sw2iso;
+       int i, sw, sw2iso;
        u32 val;
 
-       if (pu->reg)
-               ret = regulator_enable(pu->reg);
-       if (pu->reg && ret) {
-               pr_err("%s: failed to enable regulator: %d\n", __func__, ret);
-               return ret;
-       }
-
        /* Enable reset clocks for all devices in the PU domain */
        for (i = 0; i < pu->num_clks; i++)
                clk_prepare_enable(pu->clk[i]);
@@ -591,6 +598,29 @@ static int imx6q_pm_pu_power_on(struct generic_pm_domain *genpd)
        /* Disable reset clocks for all devices in the PU domain */
        for (i = 0; i < pu->num_clks; i++)
                clk_disable_unprepare(pu->clk[i]);
+}
+
+static int imx6q_pm_pu_power_on(struct generic_pm_domain *genpd)
+{
+       struct pu_domain *pu = container_of(genpd, struct pu_domain, base);
+       int ret;
+
+       if (cpu_is_imx6q() && imx_get_soc_revision() == IMX_CHIP_REVISION_2_0
+               && &imx6q_pu_domain == pu) {
+               if (!pu_on)
+                       pu_on = true;
+               else
+                       return 0;
+       }
+
+       if (pu->reg)
+               ret = regulator_enable(pu->reg);
+       if (pu->reg && ret) {
+               pr_err("%s: failed to enable regulator: %d\n", __func__, ret);
+               return ret;
+       }
+
+       _imx6q_pm_pu_power_on(genpd);
 
        return 0;
 }
@@ -729,7 +759,8 @@ static int imx_gpc_genpd_init(struct device *dev, struct regulator *pu_reg)
        imx6s_display_domain.num_clks = k;
 
        is_off = IS_ENABLED(CONFIG_PM);
-       if (is_off) {
+       if (is_off && !(cpu_is_imx6q() &&
+               imx_get_soc_revision() == IMX_CHIP_REVISION_2_0)) {
                _imx6q_pm_pu_power_off(&imx6q_pu_domain.base);
        } else {
                /*