Skip to content

Commit 0411f0d

Browse files
committed
Merge branch 'pm-cpufreq'
* pm-cpufreq: cpufreq: intel_pstate: Simplify intel_pstate_cpu_init() cpufreq: qcom: Add support for krait based socs cpufreq: imx6q-cpufreq: Improve the logic of -EPROBE_DEFER handling cpufreq: Use scnprintf() for avoiding potential buffer overflow Documentation: intel_pstate: update links for references cpufreq: intel_pstate: Consolidate policy verification cpufreq: dt: Allow platform specific intermediate callbacks cpufreq: imx-cpufreq-dt: Correct i.MX8MP's market segment fuse location cpufreq: imx6q: read OCOTP through nvmem for imx6q cpufreq: imx6q: fix error handling cpufreq: imx-cpufreq-dt: Add "cpu-supply" property check cpufreq: ti-cpufreq: Add support for OPP_PLUS cpufreq: imx6q: Fixes unwanted cpu overclocking on i.MX6ULL
2 parents be4f654 + 5ac5411 commit 0411f0d

File tree

12 files changed

+273
-71
lines changed

12 files changed

+273
-71
lines changed

Documentation/admin-guide/pm/intel_pstate.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -734,10 +734,10 @@ References
734734
==========
735735

736736
.. [1] Kristen Accardi, *Balancing Power and Performance in the Linux Kernel*,
737-
http://events.linuxfoundation.org/sites/events/files/slides/LinuxConEurope_2015.pdf
737+
https://events.static.linuxfound.org/sites/events/files/slides/LinuxConEurope_2015.pdf
738738
739739
.. [2] *Intel® 64 and IA-32 Architectures Software Developer’s Manual Volume 3: System Programming Guide*,
740-
http://www.intel.com/content/www/us/en/architecture-and-technology/64-ia-32-architectures-software-developer-system-programming-manual-325384.html
740+
https://www.intel.com/content/www/us/en/architecture-and-technology/64-ia-32-architectures-software-developer-system-programming-manual-325384.html
741741
742742
.. [3] *Advanced Configuration and Power Interface Specification*,
743743
https://uefi.org/sites/default/files/resources/ACPI_6_3_final_Jan30.pdf

Documentation/devicetree/bindings/opp/qcom-nvmem-cpufreq.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ In 'cpu' nodes:
1919

2020
In 'operating-points-v2' table:
2121
- compatible: Should be
22-
- 'operating-points-v2-kryo-cpu' for apq8096 and msm8996.
22+
- 'operating-points-v2-kryo-cpu' for apq8096, msm8996, msm8974,
23+
apq8064, ipq8064, msm8960 and ipq8074.
2324

2425
Optional properties:
2526
--------------------

drivers/cpufreq/Kconfig.arm

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ config ARM_OMAP2PLUS_CPUFREQ
128128

129129
config ARM_QCOM_CPUFREQ_NVMEM
130130
tristate "Qualcomm nvmem based CPUFreq"
131-
depends on ARM64
131+
depends on ARCH_QCOM
132132
depends on QCOM_QFPROM
133133
depends on QCOM_SMEM
134134
select PM_OPP

drivers/cpufreq/cpufreq-dt-platdev.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,11 @@ static const struct of_device_id blacklist[] __initconst = {
141141
{ .compatible = "ti,dra7", },
142142
{ .compatible = "ti,omap3", },
143143

144+
{ .compatible = "qcom,ipq8064", },
145+
{ .compatible = "qcom,apq8064", },
146+
{ .compatible = "qcom,msm8974", },
147+
{ .compatible = "qcom,msm8960", },
148+
144149
{ }
145150
};
146151

drivers/cpufreq/cpufreq-dt.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -363,6 +363,10 @@ static int dt_cpufreq_probe(struct platform_device *pdev)
363363
dt_cpufreq_driver.resume = data->resume;
364364
if (data->suspend)
365365
dt_cpufreq_driver.suspend = data->suspend;
366+
if (data->get_intermediate) {
367+
dt_cpufreq_driver.target_intermediate = data->target_intermediate;
368+
dt_cpufreq_driver.get_intermediate = data->get_intermediate;
369+
}
366370
}
367371

368372
ret = cpufreq_register_driver(&dt_cpufreq_driver);

drivers/cpufreq/cpufreq-dt.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ struct cpufreq_policy;
1414
struct cpufreq_dt_platform_data {
1515
bool have_governor_per_policy;
1616

17+
unsigned int (*get_intermediate)(struct cpufreq_policy *policy,
18+
unsigned int index);
19+
int (*target_intermediate)(struct cpufreq_policy *policy,
20+
unsigned int index);
1721
int (*suspend)(struct cpufreq_policy *policy);
1822
int (*resume)(struct cpufreq_policy *policy);
1923
};

drivers/cpufreq/cpufreq_stats.c

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -90,35 +90,35 @@ static ssize_t show_trans_table(struct cpufreq_policy *policy, char *buf)
9090
if (policy->fast_switch_enabled)
9191
return 0;
9292

93-
len += snprintf(buf + len, PAGE_SIZE - len, " From : To\n");
94-
len += snprintf(buf + len, PAGE_SIZE - len, " : ");
93+
len += scnprintf(buf + len, PAGE_SIZE - len, " From : To\n");
94+
len += scnprintf(buf + len, PAGE_SIZE - len, " : ");
9595
for (i = 0; i < stats->state_num; i++) {
9696
if (len >= PAGE_SIZE)
9797
break;
98-
len += snprintf(buf + len, PAGE_SIZE - len, "%9u ",
98+
len += scnprintf(buf + len, PAGE_SIZE - len, "%9u ",
9999
stats->freq_table[i]);
100100
}
101101
if (len >= PAGE_SIZE)
102102
return PAGE_SIZE;
103103

104-
len += snprintf(buf + len, PAGE_SIZE - len, "\n");
104+
len += scnprintf(buf + len, PAGE_SIZE - len, "\n");
105105

106106
for (i = 0; i < stats->state_num; i++) {
107107
if (len >= PAGE_SIZE)
108108
break;
109109

110-
len += snprintf(buf + len, PAGE_SIZE - len, "%9u: ",
110+
len += scnprintf(buf + len, PAGE_SIZE - len, "%9u: ",
111111
stats->freq_table[i]);
112112

113113
for (j = 0; j < stats->state_num; j++) {
114114
if (len >= PAGE_SIZE)
115115
break;
116-
len += snprintf(buf + len, PAGE_SIZE - len, "%9u ",
116+
len += scnprintf(buf + len, PAGE_SIZE - len, "%9u ",
117117
stats->trans_table[i*stats->max_state+j]);
118118
}
119119
if (len >= PAGE_SIZE)
120120
break;
121-
len += snprintf(buf + len, PAGE_SIZE - len, "\n");
121+
len += scnprintf(buf + len, PAGE_SIZE - len, "\n");
122122
}
123123

124124
if (len >= PAGE_SIZE) {

drivers/cpufreq/imx-cpufreq-dt.c

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
#define IMX8MN_OCOTP_CFG3_SPEED_GRADE_MASK (0xf << 8)
2020
#define OCOTP_CFG3_MKT_SEGMENT_SHIFT 6
2121
#define OCOTP_CFG3_MKT_SEGMENT_MASK (0x3 << 6)
22+
#define IMX8MP_OCOTP_CFG3_MKT_SEGMENT_SHIFT 5
23+
#define IMX8MP_OCOTP_CFG3_MKT_SEGMENT_MASK (0x3 << 5)
2224

2325
/* cpufreq-dt device registered by imx-cpufreq-dt */
2426
static struct platform_device *cpufreq_dt_pdev;
@@ -31,6 +33,9 @@ static int imx_cpufreq_dt_probe(struct platform_device *pdev)
3133
int speed_grade, mkt_segment;
3234
int ret;
3335

36+
if (!of_find_property(cpu_dev->of_node, "cpu-supply", NULL))
37+
return -ENODEV;
38+
3439
ret = nvmem_cell_read_u32(cpu_dev, "speed_grade", &cell_value);
3540
if (ret)
3641
return ret;
@@ -42,7 +47,13 @@ static int imx_cpufreq_dt_probe(struct platform_device *pdev)
4247
else
4348
speed_grade = (cell_value & OCOTP_CFG3_SPEED_GRADE_MASK)
4449
>> OCOTP_CFG3_SPEED_GRADE_SHIFT;
45-
mkt_segment = (cell_value & OCOTP_CFG3_MKT_SEGMENT_MASK) >> OCOTP_CFG3_MKT_SEGMENT_SHIFT;
50+
51+
if (of_machine_is_compatible("fsl,imx8mp"))
52+
mkt_segment = (cell_value & IMX8MP_OCOTP_CFG3_MKT_SEGMENT_MASK)
53+
>> IMX8MP_OCOTP_CFG3_MKT_SEGMENT_SHIFT;
54+
else
55+
mkt_segment = (cell_value & OCOTP_CFG3_MKT_SEGMENT_MASK)
56+
>> OCOTP_CFG3_MKT_SEGMENT_SHIFT;
4657

4758
/*
4859
* Early samples without fuses written report "0 0" which may NOT

drivers/cpufreq/imx6q-cpufreq.c

Lines changed: 41 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -216,31 +216,41 @@ static struct cpufreq_driver imx6q_cpufreq_driver = {
216216
#define OCOTP_CFG3_SPEED_996MHZ 0x2
217217
#define OCOTP_CFG3_SPEED_852MHZ 0x1
218218

219-
static void imx6q_opp_check_speed_grading(struct device *dev)
219+
static int imx6q_opp_check_speed_grading(struct device *dev)
220220
{
221221
struct device_node *np;
222222
void __iomem *base;
223223
u32 val;
224+
int ret;
224225

225-
np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-ocotp");
226-
if (!np)
227-
return;
226+
if (of_find_property(dev->of_node, "nvmem-cells", NULL)) {
227+
ret = nvmem_cell_read_u32(dev, "speed_grade", &val);
228+
if (ret)
229+
return ret;
230+
} else {
231+
np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-ocotp");
232+
if (!np)
233+
return -ENOENT;
228234

229-
base = of_iomap(np, 0);
230-
if (!base) {
231-
dev_err(dev, "failed to map ocotp\n");
232-
goto put_node;
235+
base = of_iomap(np, 0);
236+
of_node_put(np);
237+
if (!base) {
238+
dev_err(dev, "failed to map ocotp\n");
239+
return -EFAULT;
240+
}
241+
242+
/*
243+
* SPEED_GRADING[1:0] defines the max speed of ARM:
244+
* 2b'11: 1200000000Hz;
245+
* 2b'10: 996000000Hz;
246+
* 2b'01: 852000000Hz; -- i.MX6Q Only, exclusive with 996MHz.
247+
* 2b'00: 792000000Hz;
248+
* We need to set the max speed of ARM according to fuse map.
249+
*/
250+
val = readl_relaxed(base + OCOTP_CFG3);
251+
iounmap(base);
233252
}
234253

235-
/*
236-
* SPEED_GRADING[1:0] defines the max speed of ARM:
237-
* 2b'11: 1200000000Hz;
238-
* 2b'10: 996000000Hz;
239-
* 2b'01: 852000000Hz; -- i.MX6Q Only, exclusive with 996MHz.
240-
* 2b'00: 792000000Hz;
241-
* We need to set the max speed of ARM according to fuse map.
242-
*/
243-
val = readl_relaxed(base + OCOTP_CFG3);
244254
val >>= OCOTP_CFG3_SPEED_SHIFT;
245255
val &= 0x3;
246256

@@ -257,9 +267,8 @@ static void imx6q_opp_check_speed_grading(struct device *dev)
257267
if (dev_pm_opp_disable(dev, 1200000000))
258268
dev_warn(dev, "failed to disable 1.2GHz OPP\n");
259269
}
260-
iounmap(base);
261-
put_node:
262-
of_node_put(np);
270+
271+
return 0;
263272
}
264273

265274
#define OCOTP_CFG3_6UL_SPEED_696MHZ 0x2
@@ -280,6 +289,9 @@ static int imx6ul_opp_check_speed_grading(struct device *dev)
280289
void __iomem *base;
281290

282291
np = of_find_compatible_node(NULL, NULL, "fsl,imx6ul-ocotp");
292+
if (!np)
293+
np = of_find_compatible_node(NULL, NULL,
294+
"fsl,imx6ull-ocotp");
283295
if (!np)
284296
return -ENOENT;
285297

@@ -378,23 +390,22 @@ static int imx6q_cpufreq_probe(struct platform_device *pdev)
378390
goto put_reg;
379391
}
380392

393+
/* Because we have added the OPPs here, we must free them */
394+
free_opp = true;
395+
381396
if (of_machine_is_compatible("fsl,imx6ul") ||
382397
of_machine_is_compatible("fsl,imx6ull")) {
383398
ret = imx6ul_opp_check_speed_grading(cpu_dev);
384-
if (ret) {
385-
if (ret == -EPROBE_DEFER)
386-
goto put_node;
387-
399+
} else {
400+
ret = imx6q_opp_check_speed_grading(cpu_dev);
401+
}
402+
if (ret) {
403+
if (ret != -EPROBE_DEFER)
388404
dev_err(cpu_dev, "failed to read ocotp: %d\n",
389405
ret);
390-
goto put_node;
391-
}
392-
} else {
393-
imx6q_opp_check_speed_grading(cpu_dev);
406+
goto out_free_opp;
394407
}
395408

396-
/* Because we have added the OPPs here, we must free them */
397-
free_opp = true;
398409
num = dev_pm_opp_get_opp_count(cpu_dev);
399410
if (num < 0) {
400411
ret = num;

drivers/cpufreq/intel_pstate.c

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2155,15 +2155,19 @@ static void intel_pstate_adjust_policy_max(struct cpudata *cpu,
21552155
}
21562156
}
21572157

2158-
static int intel_pstate_verify_policy(struct cpufreq_policy_data *policy)
2158+
static void intel_pstate_verify_cpu_policy(struct cpudata *cpu,
2159+
struct cpufreq_policy_data *policy)
21592160
{
2160-
struct cpudata *cpu = all_cpu_data[policy->cpu];
2161-
21622161
update_turbo_state();
21632162
cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq,
21642163
intel_pstate_get_max_freq(cpu));
21652164

21662165
intel_pstate_adjust_policy_max(cpu, policy);
2166+
}
2167+
2168+
static int intel_pstate_verify_policy(struct cpufreq_policy_data *policy)
2169+
{
2170+
intel_pstate_verify_cpu_policy(all_cpu_data[policy->cpu], policy);
21672171

21682172
return 0;
21692173
}
@@ -2243,10 +2247,11 @@ static int intel_pstate_cpu_init(struct cpufreq_policy *policy)
22432247
if (ret)
22442248
return ret;
22452249

2246-
if (IS_ENABLED(CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE))
2247-
policy->policy = CPUFREQ_POLICY_PERFORMANCE;
2248-
else
2249-
policy->policy = CPUFREQ_POLICY_POWERSAVE;
2250+
/*
2251+
* Set the policy to powersave to provide a valid fallback value in case
2252+
* the default cpufreq governor is neither powersave nor performance.
2253+
*/
2254+
policy->policy = CPUFREQ_POLICY_POWERSAVE;
22502255

22512256
return 0;
22522257
}
@@ -2268,12 +2273,7 @@ static int intel_cpufreq_verify_policy(struct cpufreq_policy_data *policy)
22682273
{
22692274
struct cpudata *cpu = all_cpu_data[policy->cpu];
22702275

2271-
update_turbo_state();
2272-
cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq,
2273-
intel_pstate_get_max_freq(cpu));
2274-
2275-
intel_pstate_adjust_policy_max(cpu, policy);
2276-
2276+
intel_pstate_verify_cpu_policy(cpu, policy);
22772277
intel_pstate_update_perf_limits(cpu, policy->min, policy->max);
22782278

22792279
return 0;

0 commit comments

Comments
 (0)