MLK-16121-1 cpufreq: imx8mq: add gpio regulator support
authorAnson Huang <Anson.Huang@nxp.com>
Wed, 2 Aug 2017 06:39:18 +0000 (14:39 +0800)
committerLeonard Crestez <leonard.crestez@nxp.com>
Wed, 17 Apr 2019 23:51:34 +0000 (02:51 +0300)
i.MX8MQ can run at over-drive mode which needs
increasing VDD_ARM voltage, add gpio regulator support
for over-drive mode.

Signed-off-by: Anson Huang <Anson.Huang@nxp.com>
(cherry picked from commit 86f48a3c4b9558454d82cea732d53348e37ef574)

drivers/cpufreq/imx8mq-cpufreq.c

index c0123e2..d44c616 100644 (file)
 #include <linux/of.h>
 #include <linux/pm_opp.h>
 #include <linux/platform_device.h>
+#include <linux/regulator/consumer.h>
 #include <linux/suspend.h>
 
+#define DC_VOLTAGE_MIN         900000
+#define DC_VOLTAGE_MAX         1000000
+
 static struct device *cpu_dev;
 static bool free_opp;
 static struct cpufreq_frequency_table *freq_table;
@@ -30,6 +34,7 @@ static struct clk *arm_pll_clk;
 static struct clk *arm_pll_out_clk;
 static struct clk *sys1_pll_800m_clk;
 struct thermal_cooling_device *cdev;
+static struct regulator *dc_reg;
 
 static int imx8mq_set_target(struct cpufreq_policy *policy, unsigned int index)
 {
@@ -57,10 +62,32 @@ static int imx8mq_set_target(struct cpufreq_policy *policy, unsigned int index)
        dev_dbg(cpu_dev, "%u MHz --> %u MHz\n",
                old_freq / 1000, new_freq / 1000);
 
+       if (new_freq == suspend_freq) {
+               if (!IS_ERR(dc_reg)) {
+                       ret = regulator_set_voltage_tol(dc_reg, DC_VOLTAGE_MAX, 0);
+                       if (ret) {
+                               dev_err(cpu_dev, "failed to scale dc_reg up: %d\n", ret);
+                               mutex_unlock(&set_cpufreq_lock);
+                               return ret;
+                       }
+               }
+       }
+
        clk_set_parent(arm_a53_src_clk, sys1_pll_800m_clk);
        clk_set_rate(arm_pll_clk, new_freq * 1000);
        clk_set_parent(arm_a53_src_clk, arm_pll_out_clk);
 
+       if (old_freq == suspend_freq) {
+               if (!IS_ERR(dc_reg)) {
+                       ret = regulator_set_voltage_tol(dc_reg, DC_VOLTAGE_MIN, 0);
+                       if (ret) {
+                               dev_err(cpu_dev, "failed to scale dc_reg down: %d\n", ret);
+                               mutex_unlock(&set_cpufreq_lock);
+                               return ret;
+                       }
+               }
+       }
+
        /* Ensure the arm clock divider is what we expect */
        ret = clk_set_rate(a53_clk, new_freq * 1000);
        if (ret)
@@ -149,6 +176,8 @@ static int imx8mq_cpufreq_probe(struct platform_device *pdev)
                goto put_clk;
        }
 
+       dc_reg = regulator_get_optional(cpu_dev, "dc");
+
        /*
         * We expect an OPP table supplied by platform.
         * Just, incase the platform did not supply the OPP