summaryrefslogtreecommitdiff
path: root/drivers/cpufreq
diff options
context:
space:
mode:
authorBai Ping <ping.bai@nxp.com>2016-08-30 13:01:29 +0800
committerJason Liu <jason.hui.liu@nxp.com>2019-02-12 10:24:54 +0800
commit939190d04d22b05ba638fb6433e03ccb38afc58c (patch)
treef9426002394928111176365a654edcbc5831b34b /drivers/cpufreq
parent928a7adddbeefe90dcd85aa420d30c91f1fb7a2c (diff)
MLK-13133-02 cpufreq: imx: Fix system hang when entring low bus mode on imx6ull
On i.MX6ULL, when the CPU freq is running at 198MHz or 396MHz, the system will enter low bus mode if no device need high bus mode. The first time the system entering low bus mode, CPU freq will be set to 24MHz, if cpufreq change the CPU freq from 198MHz(396MHz) to 396MHz(198MHz), the CPU freq will be set to 198MHz or 396 MHz. At this time, if the CPU enter low power idle, system will hang. Signed-off-by: Bai Ping <ping.bai@nxp.com>
Diffstat (limited to 'drivers/cpufreq')
-rw-r--r--drivers/cpufreq/imx6q-cpufreq.c23
1 files changed, 20 insertions, 3 deletions
diff --git a/drivers/cpufreq/imx6q-cpufreq.c b/drivers/cpufreq/imx6q-cpufreq.c
index ac1be0506d26..19bf3321af7d 100644
--- a/drivers/cpufreq/imx6q-cpufreq.c
+++ b/drivers/cpufreq/imx6q-cpufreq.c
@@ -54,6 +54,7 @@ static unsigned int transition_latency;
static u32 *imx6_soc_volt;
static u32 soc_opp_count;
static bool ignore_dc_reg;
+static bool low_power_run_support;
static int imx6q_set_target(struct cpufreq_policy *policy, unsigned int index)
{
@@ -95,8 +96,12 @@ static int imx6q_set_target(struct cpufreq_policy *policy, unsigned int index)
* CPU freq is increasing, so need to ensure
* that bus frequency is increased too.
*/
- if (old_freq <= FREQ_396_MHZ && new_freq > FREQ_396_MHZ)
+ if (low_power_run_support) {
+ if (old_freq == freq_table[0].frequency)
+ request_bus_freq(BUS_FREQ_HIGH);
+ } else if (old_freq <= FREQ_396_MHZ && new_freq > FREQ_396_MHZ) {
request_bus_freq(BUS_FREQ_HIGH);
+ }
/* scaling up? scale voltage before frequency */
if (new_freq > old_freq) {
@@ -214,8 +219,12 @@ static int imx6q_set_target(struct cpufreq_policy *policy, unsigned int index)
* If CPU is dropped to the lowest level, release the need
* for a high bus frequency.
*/
- if (old_freq > FREQ_396_MHZ && new_freq <= FREQ_396_MHZ)
+ if (low_power_run_support) {
+ if (new_freq == freq_table[0].frequency)
+ release_bus_freq(BUS_FREQ_HIGH);
+ } else if (old_freq > FREQ_396_MHZ && new_freq <= FREQ_396_MHZ) {
release_bus_freq(BUS_FREQ_HIGH);
+ }
return 0;
}
@@ -232,8 +241,12 @@ static int imx6q_cpufreq_init(struct cpufreq_policy *policy)
dev_err(cpu_dev, "imx6 cpufreq init failed!\n");
return ret;
}
- if (policy->cur > FREQ_396_MHZ)
+ if (low_power_run_support && policy->cur > freq_table[0].frequency) {
request_bus_freq(BUS_FREQ_HIGH);
+ } else if (policy->cur > FREQ_396_MHZ) {
+ request_bus_freq(BUS_FREQ_HIGH);
+ }
+
return 0;
}
@@ -356,6 +369,10 @@ static int imx6q_cpufreq_probe(struct platform_device *pdev)
of_property_read_u32(np, "fsl,arm-soc-shared", &i);
if (i == 1)
soc_reg = arm_reg;
+
+ /* On i.MX6ULL, check the 24MHz low power run mode support */
+ low_power_run_support = of_property_read_bool(np, "fsl,low-power-run");
+
/*
* We expect an OPP table supplied by platform.
* Just, incase the platform did not supply the OPP