From 3f48f9795cbc98d8b08a109f9c3d6699411d8ef2 Mon Sep 17 00:00:00 2001 From: Finley Xiao Date: Wed, 12 Apr 2017 18:38:58 +0800 Subject: [PATCH] cpufreq: dt: support checking initial rate Bootloader or kernel sets CPU frequency to an initial value before cpufreq starts on rockchip platform, if cpu's opp table is modified to a specified value, it will cause an issue. For example, the initial frequency is 816MHz and voltage set by hardware is 900mV: 1. there is only one opp whose frequency is 816MHz and voltage is 850mV in opp table list, as they frequency is equal, the voltage will not be changed, it is still 900mV and a little too large relative to 850mV. 2. there is only one opp whose frequency is 1200MHz and voltage is 1100mV in opp table list, as it doesn't set voltage to 1100mV before set frequency to 1200MHz in the dev_pm_opp_set_rate function, the initial voltage 900mV cann't supply for 1200MHz, the system crash. Change-Id: Iba41536367ba5802dd8f7f37e245f0e5781eb643 Signed-off-by: Finley Xiao --- drivers/cpufreq/cpufreq-dt.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/drivers/cpufreq/cpufreq-dt.c b/drivers/cpufreq/cpufreq-dt.c index 37604c72c9b9..4202e81de3a5 100644 --- a/drivers/cpufreq/cpufreq-dt.c +++ b/drivers/cpufreq/cpufreq-dt.c @@ -29,6 +29,8 @@ #include #include +#define MAX_CLUSTERS 2 + struct private_data { struct device *cpu_dev; struct thermal_cooling_device *cdev; @@ -153,9 +155,11 @@ static int cpufreq_init(struct cpufreq_policy *policy) struct cpumask cpus; #endif unsigned int transition_latency; + unsigned long cur_freq; bool opp_v1 = false; const char *name; int ret; + static int check_init; cpu_dev = get_cpu_device(policy->cpu); if (!cpu_dev) { @@ -297,6 +301,13 @@ static int cpufreq_init(struct cpufreq_policy *policy) policy->cpuinfo.transition_latency = transition_latency; + if (check_init < MAX_CLUSTERS) { + ret = dev_pm_opp_check_initial_rate(cpu_dev, &cur_freq); + if (!ret) + policy->cur = cur_freq / 1000; + check_init++; + } + return 0; out_free_cpufreq_table: @@ -373,11 +384,8 @@ static void cpufreq_ready(struct cpufreq_policy *policy) } static struct cpufreq_driver dt_cpufreq_driver = { -#ifdef CONFIG_ARCH_ROCKCHIP - .flags = CPUFREQ_STICKY | CPUFREQ_HAVE_GOVERNOR_PER_POLICY, -#else - .flags = CPUFREQ_STICKY | CPUFREQ_NEED_INITIAL_FREQ_CHECK, -#endif + .flags = CPUFREQ_STICKY | CPUFREQ_NEED_INITIAL_FREQ_CHECK | + CPUFREQ_HAVE_GOVERNOR_PER_POLICY, .verify = cpufreq_generic_frequency_table_verify, .target_index = set_target, .get = cpufreq_generic_get, -- 2.34.1