Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'pm-6.7-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm

Pull power management fixes from Rafael Wysocki:
"These fix issues in two cpufreq drivers, in the AMD P-state driver and
in the power-capping DTPM framework.

Specifics:

- Fix the AMD P-state driver's EPP sysfs interface in the cases when
the performance governor is in use (Ayush Jain)

- Make the ->fast_switch() callback in the AMD P-state driver return
the target frequency as expected (Gautham R. Shenoy)

- Allow user space to control the range of frequencies to use via
scaling_min_freq and scaling_max_freq when AMD P-state driver is in
use (Wyes Karny)

- Prevent power domains needed for wakeup signaling from being turned
off during system suspend on Qualcomm systems and prevent
performance states votes from runtime-suspended devices from being
lost across a system suspend-resume cycle in qcom-cpufreq-nvmem
(Stephan Gerhold)

- Fix disabling the 792 Mhz OPP in the imx6q cpufreq driver for the
i.MX6ULL types that can run at that frequency (Christoph
Niedermaier)

- Eliminate unnecessary and harmful conversions to uW from the DTPM
(dynamic thermal and power management) framework (Lukasz Luba)"

* tag 'pm-6.7-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm:
cpufreq/amd-pstate: Only print supported EPP values for performance governor
cpufreq/amd-pstate: Fix scaling_min_freq and scaling_max_freq update
powercap: DTPM: Fix unneeded conversions to micro-Watts
cpufreq/amd-pstate: Fix the return value of amd_pstate_fast_switch()
pmdomain: qcom: rpmpd: Set GENPD_FLAG_ACTIVE_WAKEUP
cpufreq: qcom-nvmem: Preserve PM domain votes in system suspend
cpufreq: qcom-nvmem: Enable virtual power domain devices
cpufreq: imx6q: Don't disable 792 Mhz OPP unnecessarily

+136 -32
+56 -15
drivers/cpufreq/amd-pstate.c
··· 307 307 highest_perf = AMD_CPPC_HIGHEST_PERF(cap1); 308 308 309 309 WRITE_ONCE(cpudata->highest_perf, highest_perf); 310 - 310 + WRITE_ONCE(cpudata->max_limit_perf, highest_perf); 311 311 WRITE_ONCE(cpudata->nominal_perf, AMD_CPPC_NOMINAL_PERF(cap1)); 312 312 WRITE_ONCE(cpudata->lowest_nonlinear_perf, AMD_CPPC_LOWNONLIN_PERF(cap1)); 313 313 WRITE_ONCE(cpudata->lowest_perf, AMD_CPPC_LOWEST_PERF(cap1)); 314 - 314 + WRITE_ONCE(cpudata->min_limit_perf, AMD_CPPC_LOWEST_PERF(cap1)); 315 315 return 0; 316 316 } 317 317 ··· 329 329 highest_perf = cppc_perf.highest_perf; 330 330 331 331 WRITE_ONCE(cpudata->highest_perf, highest_perf); 332 - 332 + WRITE_ONCE(cpudata->max_limit_perf, highest_perf); 333 333 WRITE_ONCE(cpudata->nominal_perf, cppc_perf.nominal_perf); 334 334 WRITE_ONCE(cpudata->lowest_nonlinear_perf, 335 335 cppc_perf.lowest_nonlinear_perf); 336 336 WRITE_ONCE(cpudata->lowest_perf, cppc_perf.lowest_perf); 337 + WRITE_ONCE(cpudata->min_limit_perf, cppc_perf.lowest_perf); 337 338 338 339 if (cppc_state == AMD_PSTATE_ACTIVE) 339 340 return 0; ··· 433 432 u64 prev = READ_ONCE(cpudata->cppc_req_cached); 434 433 u64 value = prev; 435 434 435 + min_perf = clamp_t(unsigned long, min_perf, cpudata->min_limit_perf, 436 + cpudata->max_limit_perf); 437 + max_perf = clamp_t(unsigned long, max_perf, cpudata->min_limit_perf, 438 + cpudata->max_limit_perf); 436 439 des_perf = clamp_t(unsigned long, des_perf, min_perf, max_perf); 437 440 438 441 if ((cppc_state == AMD_PSTATE_GUIDED) && (gov_flags & CPUFREQ_GOV_DYNAMIC_SWITCHING)) { ··· 475 470 return 0; 476 471 } 477 472 473 + static int amd_pstate_update_min_max_limit(struct cpufreq_policy *policy) 474 + { 475 + u32 max_limit_perf, min_limit_perf; 476 + struct amd_cpudata *cpudata = policy->driver_data; 477 + 478 + max_limit_perf = div_u64(policy->max * cpudata->highest_perf, cpudata->max_freq); 479 + min_limit_perf = div_u64(policy->min * cpudata->highest_perf, cpudata->max_freq); 480 + 481 + WRITE_ONCE(cpudata->max_limit_perf, max_limit_perf); 482 + WRITE_ONCE(cpudata->min_limit_perf, min_limit_perf); 483 + WRITE_ONCE(cpudata->max_limit_freq, policy->max); 484 + WRITE_ONCE(cpudata->min_limit_freq, policy->min); 485 + 486 + return 0; 487 + } 488 + 478 489 static int amd_pstate_update_freq(struct cpufreq_policy *policy, 479 490 unsigned int target_freq, bool fast_switch) 480 491 { ··· 500 479 501 480 if (!cpudata->max_freq) 502 481 return -ENODEV; 482 + 483 + if (policy->min != cpudata->min_limit_freq || policy->max != cpudata->max_limit_freq) 484 + amd_pstate_update_min_max_limit(policy); 503 485 504 486 cap_perf = READ_ONCE(cpudata->highest_perf); 505 487 min_perf = READ_ONCE(cpudata->lowest_perf); ··· 542 518 static unsigned int amd_pstate_fast_switch(struct cpufreq_policy *policy, 543 519 unsigned int target_freq) 544 520 { 545 - return amd_pstate_update_freq(policy, target_freq, true); 521 + if (!amd_pstate_update_freq(policy, target_freq, true)) 522 + return target_freq; 523 + return policy->cur; 546 524 } 547 525 548 526 static void amd_pstate_adjust_perf(unsigned int cpu, ··· 557 531 struct cpufreq_policy *policy = cpufreq_cpu_get(cpu); 558 532 struct amd_cpudata *cpudata = policy->driver_data; 559 533 unsigned int target_freq; 534 + 535 + if (policy->min != cpudata->min_limit_freq || policy->max != cpudata->max_limit_freq) 536 + amd_pstate_update_min_max_limit(policy); 537 + 560 538 561 539 cap_perf = READ_ONCE(cpudata->highest_perf); 562 540 lowest_nonlinear_perf = READ_ONCE(cpudata->lowest_nonlinear_perf); ··· 775 745 /* Initial processor data capability frequencies */ 776 746 cpudata->max_freq = max_freq; 777 747 cpudata->min_freq = min_freq; 748 + cpudata->max_limit_freq = max_freq; 749 + cpudata->min_limit_freq = min_freq; 778 750 cpudata->nominal_freq = nominal_freq; 779 751 cpudata->lowest_nonlinear_freq = lowest_nonlinear_freq; 780 752 ··· 882 850 { 883 851 int i = 0; 884 852 int offset = 0; 853 + struct amd_cpudata *cpudata = policy->driver_data; 854 + 855 + if (cpudata->policy == CPUFREQ_POLICY_PERFORMANCE) 856 + return sysfs_emit_at(buf, offset, "%s\n", 857 + energy_perf_strings[EPP_INDEX_PERFORMANCE]); 885 858 886 859 while (energy_perf_strings[i] != NULL) 887 860 offset += sysfs_emit_at(buf, offset, "%s ", energy_perf_strings[i++]); 888 861 889 - sysfs_emit_at(buf, offset, "\n"); 862 + offset += sysfs_emit_at(buf, offset, "\n"); 890 863 891 864 return offset; 892 865 } ··· 1220 1183 return 0; 1221 1184 } 1222 1185 1223 - static void amd_pstate_epp_init(unsigned int cpu) 1186 + static void amd_pstate_epp_update_limit(struct cpufreq_policy *policy) 1224 1187 { 1225 - struct cpufreq_policy *policy = cpufreq_cpu_get(cpu); 1226 1188 struct amd_cpudata *cpudata = policy->driver_data; 1227 - u32 max_perf, min_perf; 1189 + u32 max_perf, min_perf, min_limit_perf, max_limit_perf; 1228 1190 u64 value; 1229 1191 s16 epp; 1230 1192 1231 1193 max_perf = READ_ONCE(cpudata->highest_perf); 1232 1194 min_perf = READ_ONCE(cpudata->lowest_perf); 1195 + max_limit_perf = div_u64(policy->max * cpudata->highest_perf, cpudata->max_freq); 1196 + min_limit_perf = div_u64(policy->min * cpudata->highest_perf, cpudata->max_freq); 1197 + 1198 + max_perf = clamp_t(unsigned long, max_perf, cpudata->min_limit_perf, 1199 + cpudata->max_limit_perf); 1200 + min_perf = clamp_t(unsigned long, min_perf, cpudata->min_limit_perf, 1201 + cpudata->max_limit_perf); 1202 + 1203 + WRITE_ONCE(cpudata->max_limit_perf, max_limit_perf); 1204 + WRITE_ONCE(cpudata->min_limit_perf, min_limit_perf); 1233 1205 1234 1206 value = READ_ONCE(cpudata->cppc_req_cached); 1235 1207 ··· 1256 1210 value &= ~AMD_CPPC_DES_PERF(~0L); 1257 1211 value |= AMD_CPPC_DES_PERF(0); 1258 1212 1259 - if (cpudata->epp_policy == cpudata->policy) 1260 - goto skip_epp; 1261 - 1262 1213 cpudata->epp_policy = cpudata->policy; 1263 1214 1264 1215 /* Get BIOS pre-defined epp value */ ··· 1265 1222 * This return value can only be negative for shared_memory 1266 1223 * systems where EPP register read/write not supported. 1267 1224 */ 1268 - goto skip_epp; 1225 + return; 1269 1226 } 1270 1227 1271 1228 if (cpudata->policy == CPUFREQ_POLICY_PERFORMANCE) ··· 1279 1236 1280 1237 WRITE_ONCE(cpudata->cppc_req_cached, value); 1281 1238 amd_pstate_set_epp(cpudata, epp); 1282 - skip_epp: 1283 - cpufreq_cpu_put(policy); 1284 1239 } 1285 1240 1286 1241 static int amd_pstate_epp_set_policy(struct cpufreq_policy *policy) ··· 1293 1252 1294 1253 cpudata->policy = policy->policy; 1295 1254 1296 - amd_pstate_epp_init(policy->cpu); 1255 + amd_pstate_epp_update_limit(policy); 1297 1256 1298 1257 return 0; 1299 1258 }
+1 -1
drivers/cpufreq/imx6q-cpufreq.c
··· 327 327 imx6x_disable_freq_in_opp(dev, 696000000); 328 328 329 329 if (of_machine_is_compatible("fsl,imx6ull")) { 330 - if (val != OCOTP_CFG3_6ULL_SPEED_792MHZ) 330 + if (val < OCOTP_CFG3_6ULL_SPEED_792MHZ) 331 331 imx6x_disable_freq_in_opp(dev, 792000000); 332 332 333 333 if (val != OCOTP_CFG3_6ULL_SPEED_900MHZ)
+70 -3
drivers/cpufreq/qcom-cpufreq-nvmem.c
··· 23 23 #include <linux/nvmem-consumer.h> 24 24 #include <linux/of.h> 25 25 #include <linux/platform_device.h> 26 + #include <linux/pm.h> 26 27 #include <linux/pm_domain.h> 27 28 #include <linux/pm_opp.h> 29 + #include <linux/pm_runtime.h> 28 30 #include <linux/slab.h> 29 31 #include <linux/soc/qcom/smem.h> 30 32 ··· 57 55 58 56 struct qcom_cpufreq_drv_cpu { 59 57 int opp_token; 58 + struct device **virt_devs; 60 59 }; 61 60 62 61 struct qcom_cpufreq_drv { ··· 427 424 .get_version = qcom_cpufreq_ipq8074_name_version, 428 425 }; 429 426 427 + static void qcom_cpufreq_suspend_virt_devs(struct qcom_cpufreq_drv *drv, unsigned int cpu) 428 + { 429 + const char * const *name = drv->data->genpd_names; 430 + int i; 431 + 432 + if (!drv->cpus[cpu].virt_devs) 433 + return; 434 + 435 + for (i = 0; *name; i++, name++) 436 + device_set_awake_path(drv->cpus[cpu].virt_devs[i]); 437 + } 438 + 439 + static void qcom_cpufreq_put_virt_devs(struct qcom_cpufreq_drv *drv, unsigned int cpu) 440 + { 441 + const char * const *name = drv->data->genpd_names; 442 + int i; 443 + 444 + if (!drv->cpus[cpu].virt_devs) 445 + return; 446 + 447 + for (i = 0; *name; i++, name++) 448 + pm_runtime_put(drv->cpus[cpu].virt_devs[i]); 449 + } 450 + 430 451 static int qcom_cpufreq_probe(struct platform_device *pdev) 431 452 { 432 453 struct qcom_cpufreq_drv *drv; ··· 505 478 of_node_put(np); 506 479 507 480 for_each_possible_cpu(cpu) { 481 + struct device **virt_devs = NULL; 508 482 struct dev_pm_opp_config config = { 509 483 .supported_hw = NULL, 510 484 }; ··· 526 498 527 499 if (drv->data->genpd_names) { 528 500 config.genpd_names = drv->data->genpd_names; 529 - config.virt_devs = NULL; 501 + config.virt_devs = &virt_devs; 530 502 } 531 503 532 504 if (config.supported_hw || config.genpd_names) { ··· 536 508 dev_err(cpu_dev, "Failed to set OPP config\n"); 537 509 goto free_opp; 538 510 } 511 + } 512 + 513 + if (virt_devs) { 514 + const char * const *name = config.genpd_names; 515 + int i, j; 516 + 517 + for (i = 0; *name; i++, name++) { 518 + ret = pm_runtime_resume_and_get(virt_devs[i]); 519 + if (ret) { 520 + dev_err(cpu_dev, "failed to resume %s: %d\n", 521 + *name, ret); 522 + 523 + /* Rollback previous PM runtime calls */ 524 + name = config.genpd_names; 525 + for (j = 0; *name && j < i; j++, name++) 526 + pm_runtime_put(virt_devs[j]); 527 + 528 + goto free_opp; 529 + } 530 + } 531 + drv->cpus[cpu].virt_devs = virt_devs; 539 532 } 540 533 } 541 534 ··· 571 522 dev_err(cpu_dev, "Failed to register platform device\n"); 572 523 573 524 free_opp: 574 - for_each_possible_cpu(cpu) 525 + for_each_possible_cpu(cpu) { 526 + qcom_cpufreq_put_virt_devs(drv, cpu); 575 527 dev_pm_opp_clear_config(drv->cpus[cpu].opp_token); 528 + } 576 529 return ret; 577 530 } 578 531 ··· 585 534 586 535 platform_device_unregister(cpufreq_dt_pdev); 587 536 588 - for_each_possible_cpu(cpu) 537 + for_each_possible_cpu(cpu) { 538 + qcom_cpufreq_put_virt_devs(drv, cpu); 589 539 dev_pm_opp_clear_config(drv->cpus[cpu].opp_token); 540 + } 590 541 } 542 + 543 + static int qcom_cpufreq_suspend(struct device *dev) 544 + { 545 + struct qcom_cpufreq_drv *drv = dev_get_drvdata(dev); 546 + unsigned int cpu; 547 + 548 + for_each_possible_cpu(cpu) 549 + qcom_cpufreq_suspend_virt_devs(drv, cpu); 550 + 551 + return 0; 552 + } 553 + 554 + static DEFINE_SIMPLE_DEV_PM_OPS(qcom_cpufreq_pm_ops, qcom_cpufreq_suspend, NULL); 591 555 592 556 static struct platform_driver qcom_cpufreq_driver = { 593 557 .probe = qcom_cpufreq_probe, 594 558 .remove_new = qcom_cpufreq_remove, 595 559 .driver = { 596 560 .name = "qcom-cpufreq-nvmem", 561 + .pm = pm_sleep_ptr(&qcom_cpufreq_pm_ops), 597 562 }, 598 563 }; 599 564
+1
drivers/pmdomain/qcom/rpmpd.c
··· 1044 1044 rpmpds[i]->pd.power_off = rpmpd_power_off; 1045 1045 rpmpds[i]->pd.power_on = rpmpd_power_on; 1046 1046 rpmpds[i]->pd.set_performance_state = rpmpd_set_performance; 1047 + rpmpds[i]->pd.flags = GENPD_FLAG_ACTIVE_WAKEUP; 1047 1048 pm_genpd_init(&rpmpds[i]->pd, NULL, true); 1048 1049 1049 1050 data->domains[i] = &rpmpds[i]->pd;
+1 -5
drivers/powercap/dtpm_cpu.c
··· 24 24 #include <linux/of.h> 25 25 #include <linux/pm_qos.h> 26 26 #include <linux/slab.h> 27 - #include <linux/units.h> 28 27 29 28 struct dtpm_cpu { 30 29 struct dtpm dtpm; ··· 103 104 if (pd->table[i].frequency < freq) 104 105 continue; 105 106 106 - return scale_pd_power_uw(pd_mask, pd->table[i].power * 107 - MICROWATT_PER_MILLIWATT); 107 + return scale_pd_power_uw(pd_mask, pd->table[i].power); 108 108 } 109 109 110 110 return 0; ··· 120 122 nr_cpus = cpumask_weight(&cpus); 121 123 122 124 dtpm->power_min = em->table[0].power; 123 - dtpm->power_min *= MICROWATT_PER_MILLIWATT; 124 125 dtpm->power_min *= nr_cpus; 125 126 126 127 dtpm->power_max = em->table[em->nr_perf_states - 1].power; 127 - dtpm->power_max *= MICROWATT_PER_MILLIWATT; 128 128 dtpm->power_max *= nr_cpus; 129 129 130 130 return 0;
+3 -8
drivers/powercap/dtpm_devfreq.c
··· 39 39 struct em_perf_domain *pd = em_pd_get(dev); 40 40 41 41 dtpm->power_min = pd->table[0].power; 42 - dtpm->power_min *= MICROWATT_PER_MILLIWATT; 43 42 44 43 dtpm->power_max = pd->table[pd->nr_perf_states - 1].power; 45 - dtpm->power_max *= MICROWATT_PER_MILLIWATT; 46 44 47 45 return 0; 48 46 } ··· 52 54 struct device *dev = devfreq->dev.parent; 53 55 struct em_perf_domain *pd = em_pd_get(dev); 54 56 unsigned long freq; 55 - u64 power; 56 57 int i; 57 58 58 59 for (i = 0; i < pd->nr_perf_states; i++) { 59 - 60 - power = pd->table[i].power * MICROWATT_PER_MILLIWATT; 61 - if (power > power_limit) 60 + if (pd->table[i].power > power_limit) 62 61 break; 63 62 } 64 63 ··· 63 68 64 69 dev_pm_qos_update_request(&dtpm_devfreq->qos_req, freq); 65 70 66 - power_limit = pd->table[i - 1].power * MICROWATT_PER_MILLIWATT; 71 + power_limit = pd->table[i - 1].power; 67 72 68 73 return power_limit; 69 74 } ··· 105 110 if (pd->table[i].frequency < freq) 106 111 continue; 107 112 108 - power = pd->table[i].power * MICROWATT_PER_MILLIWATT; 113 + power = pd->table[i].power; 109 114 power *= status.busy_time; 110 115 power >>= 10; 111 116
+4
include/linux/amd-pstate.h
··· 70 70 u32 nominal_perf; 71 71 u32 lowest_nonlinear_perf; 72 72 u32 lowest_perf; 73 + u32 min_limit_perf; 74 + u32 max_limit_perf; 75 + u32 min_limit_freq; 76 + u32 max_limit_freq; 73 77 74 78 u32 max_freq; 75 79 u32 min_freq;