diff options
author | Anson Huang <Anson.Huang@nxp.com> | 2017-08-02 14:39:18 +0800 |
---|---|---|
committer | Jason Liu <jason.hui.liu@nxp.com> | 2019-02-12 10:27:48 +0800 |
commit | 86f48a3c4b9558454d82cea732d53348e37ef574 (patch) | |
tree | 8bca8a21b197c5cecae63e04a170b6913f345061 /drivers/cpufreq/imx8mq-cpufreq.c | |
parent | 13eb84451564f01a92dc98fb5a7953e9a364cdb1 (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.c | 29 |
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 |