summaryrefslogtreecommitdiff
path: root/drivers/cpufreq/qcom-cpufreq-hw.c
diff options
context:
space:
mode:
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>2019-09-05 09:02:51 +0200
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2019-09-05 09:02:51 +0200
commit1c5c1b5d8efe21efa74b7a21e8c078711b984ae4 (patch)
tree83001d4114512e7e95d10c4cab04664173fdbbd0 /drivers/cpufreq/qcom-cpufreq-hw.c
parentbeb4e08e21ad964c11203a4ae6c7ba16a35df4f5 (diff)
parentf75d2accca7785657311653c125bb22f342dc5d9 (diff)
downloadlinux-1c5c1b5d8efe21efa74b7a21e8c078711b984ae4.tar.gz
Merge branch 'cpufreq/arm/linux-next' of git://git.kernel.org/pub/scm/linux/kernel/git/vireshk/pm
Pull ARM cpufreq driver changes for 5.4 from Viresh Kumar: "This contains: - Minor fixes for mediatek driver (Andrew-sh.Cheng and Fabien Parent). - Minor updates for imx driver (Anson Huang). - Minor fix for ti-cpufreq driver (Gustavo A. R. Silva). - Minor fix for ap806 driver (Hariprasad Kelam). - Significant updates to qcom cpufreq drivers, mostly to support CPR stuff (Jorge Ramirez-Ortiz, Niklas Cassel, Sibi Sankar, Douglas RAILLARD and Sricharan R). - New sun50i cpufreq driver (Yangtao Li). It also contains a few OPP changes which were required because of dependencies for the qcom cpufreq changes." * 'cpufreq/arm/linux-next' of git://git.kernel.org/pub/scm/linux/kernel/git/vireshk/pm: (22 commits) cpufreq: Add qcs404 to cpufreq-dt-platdev blacklist cpufreq: qcom: Add support for qcs404 on nvmem driver cpufreq: qcom: Refactor the driver to make it easier to extend cpufreq: qcom: Re-organise kryo cpufreq to use it for other nvmem based qcom socs dt-bindings: opp: Add qcom-opp bindings with properties needed for CPR dt-bindings: opp: qcom-nvmem: Support pstates provided by a power domain cpufreq: mediatek: Add support for mt8183 cpufreq: mediatek: change to regulator_get_optional cpufreq: imx-cpufreq-dt: Add i.MX8MN support cpufreq: Use imx-cpufreq-dt for i.MX8MN's speed grading cpufreq: qcom-hw: invoke frequency-invariance setter function cpufreq: qcom-hw: Update logic to detect turbo frequency cpufreq: mediatek-cpufreq: Add compatible for MT8516 cpufreq: ti-cpufreq: Mark expected switch fall-through dt-bindings: opp: qcom-nvmem: Make speedbin related properties optional dt-bindings: opp: Re-organise kryo cpufreq to use it for other nvmem based qcom socs opp: Add dev_pm_opp_find_level_exact() opp: Return genpd virtual devices from dev_pm_opp_attach_genpd() opp: Not all power-domains are scalable cpufreq: ap806: Add NULL check after kcalloc ...
Diffstat (limited to 'drivers/cpufreq/qcom-cpufreq-hw.c')
-rw-r--r--drivers/cpufreq/qcom-cpufreq-hw.c23
1 files changed, 15 insertions, 8 deletions
diff --git a/drivers/cpufreq/qcom-cpufreq-hw.c b/drivers/cpufreq/qcom-cpufreq-hw.c
index 4b0b50403901..a9ae2f84a4ef 100644
--- a/drivers/cpufreq/qcom-cpufreq-hw.c
+++ b/drivers/cpufreq/qcom-cpufreq-hw.c
@@ -20,6 +20,7 @@
#define LUT_VOLT GENMASK(11, 0)
#define LUT_ROW_SIZE 32
#define CLK_HW_DIV 2
+#define LUT_TURBO_IND 1
/* Register offsets */
#define REG_ENABLE 0x0
@@ -34,9 +35,12 @@ static int qcom_cpufreq_hw_target_index(struct cpufreq_policy *policy,
unsigned int index)
{
void __iomem *perf_state_reg = policy->driver_data;
+ unsigned long freq = policy->freq_table[index].frequency;
writel_relaxed(index, perf_state_reg);
+ arch_set_freq_scale(policy->related_cpus, freq,
+ policy->cpuinfo.max_freq);
return 0;
}
@@ -63,6 +67,7 @@ static unsigned int qcom_cpufreq_hw_fast_switch(struct cpufreq_policy *policy,
{
void __iomem *perf_state_reg = policy->driver_data;
int index;
+ unsigned long freq;
index = policy->cached_resolved_idx;
if (index < 0)
@@ -70,16 +75,19 @@ static unsigned int qcom_cpufreq_hw_fast_switch(struct cpufreq_policy *policy,
writel_relaxed(index, perf_state_reg);
- return policy->freq_table[index].frequency;
+ freq = policy->freq_table[index].frequency;
+ arch_set_freq_scale(policy->related_cpus, freq,
+ policy->cpuinfo.max_freq);
+
+ return freq;
}
static int qcom_cpufreq_hw_read_lut(struct device *cpu_dev,
struct cpufreq_policy *policy,
void __iomem *base)
{
- u32 data, src, lval, i, core_count, prev_cc = 0, prev_freq = 0, freq;
+ u32 data, src, lval, i, core_count, prev_freq = 0, freq;
u32 volt;
- unsigned int max_cores = cpumask_weight(policy->cpus);
struct cpufreq_frequency_table *table;
table = kcalloc(LUT_MAX_ENTRIES + 1, sizeof(*table), GFP_KERNEL);
@@ -102,12 +110,12 @@ static int qcom_cpufreq_hw_read_lut(struct device *cpu_dev,
else
freq = cpu_hw_rate / 1000;
- if (freq != prev_freq && core_count == max_cores) {
+ if (freq != prev_freq && core_count != LUT_TURBO_IND) {
table[i].frequency = freq;
dev_pm_opp_add(cpu_dev, freq * 1000, volt);
dev_dbg(cpu_dev, "index=%d freq=%d, core_count %d\n", i,
freq, core_count);
- } else {
+ } else if (core_count == LUT_TURBO_IND) {
table[i].frequency = CPUFREQ_ENTRY_INVALID;
}
@@ -115,14 +123,14 @@ static int qcom_cpufreq_hw_read_lut(struct device *cpu_dev,
* Two of the same frequencies with the same core counts means
* end of table
*/
- if (i > 0 && prev_freq == freq && prev_cc == core_count) {
+ if (i > 0 && prev_freq == freq) {
struct cpufreq_frequency_table *prev = &table[i - 1];
/*
* Only treat the last frequency that might be a boost
* as the boost frequency
*/
- if (prev_cc != max_cores) {
+ if (prev->frequency == CPUFREQ_ENTRY_INVALID) {
prev->frequency = prev_freq;
prev->flags = CPUFREQ_BOOST_FREQ;
dev_pm_opp_add(cpu_dev, prev_freq * 1000, volt);
@@ -131,7 +139,6 @@ static int qcom_cpufreq_hw_read_lut(struct device *cpu_dev,
break;
}
- prev_cc = core_count;
prev_freq = freq;
}