summaryrefslogtreecommitdiff
path: root/drivers/cpufreq/imx8mq-cpufreq.c
diff options
context:
space:
mode:
authorAnson Huang <Anson.Huang@nxp.com>2017-08-02 14:39:18 +0800
committerJason Liu <jason.hui.liu@nxp.com>2019-02-12 10:27:48 +0800
commit86f48a3c4b9558454d82cea732d53348e37ef574 (patch)
tree8bca8a21b197c5cecae63e04a170b6913f345061 /drivers/cpufreq/imx8mq-cpufreq.c
parent13eb84451564f01a92dc98fb5a7953e9a364cdb1 (diff)
MLK-16121-1 cpufreq: imx8mq: add gpio regulator support
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>
Diffstat (limited to 'drivers/cpufreq/imx8mq-cpufreq.c')
-rw-r--r--drivers/cpufreq/imx8mq-cpufreq.c29
1 files changed, 29 insertions, 0 deletions
diff --git a/drivers/cpufreq/imx8mq-cpufreq.c b/drivers/cpufreq/imx8mq-cpufreq.c
index 0457ee24febe..63a9006d2855 100644
--- a/drivers/cpufreq/imx8mq-cpufreq.c
+++ b/drivers/cpufreq/imx8mq-cpufreq.c
@@ -16,8 +16,12 @@
#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