From 8d5459f1a7f0831562d6d3f7917606708e79ccd5 Mon Sep 17 00:00:00 2001 From: Marcin Juszkiewicz Date: Mon, 9 Sep 2024 11:55:29 +0200 Subject: [PATCH 01/25] cpufreq: use proper units for frequency When I booted my RK3588 based system I noticed that cpufreq complained about system clock: [ +0.007211] cpufreq: cpufreq_online: CPU0: Running at unlisted initial frequency: 816000 KHz, changing to: 1008000 KHz Then I realized that unit is displayed wrong: "KHz" instead of "kHz". Signed-off-by: Marcin Juszkiewicz Acked-by: Viresh Kumar Link: https://patch.msgid.link/20240909095529.2325103-1-marcin.juszkiewicz@linaro.org Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/cpufreq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index f98c9438760c..1a4cae54a01b 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -1520,7 +1520,7 @@ static int cpufreq_online(unsigned int cpu) * frequency for longer duration. Hence, a BUG_ON(). */ BUG_ON(ret); - pr_info("%s: CPU%d: Running at unlisted initial frequency: %u KHz, changing to: %u KHz\n", + pr_info("%s: CPU%d: Running at unlisted initial frequency: %u kHz, changing to: %u kHz\n", __func__, policy->cpu, old_freq, policy->cur); } } From a9dedaa07b5e6034dbdd482c23aa3936958292ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Sun, 20 Oct 2024 17:39:10 +0200 Subject: [PATCH 02/25] cpufreq: Switch back to struct platform_driver::remove() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit After commit 0edb555a65d1 ("platform: Make platform_driver::remove() return void") .remove() is (again) the right callback to implement for platform drivers. Convert all platform drivers below drivers/cpufreq to use .remove(), with the eventual goal to drop struct platform_driver::remove_new(). As .remove() and .remove_new() have the same prototypes, conversion is done by just changing the structure member name in the driver initializer. Signed-off-by: Uwe Kleine-König Acked-by: Viresh Kumar Link: https://patch.msgid.link/20241020153910.324096-2-u.kleine-koenig@baylibre.com Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/acpi-cpufreq.c | 2 +- drivers/cpufreq/brcmstb-avs-cpufreq.c | 2 +- drivers/cpufreq/cpufreq-dt.c | 2 +- drivers/cpufreq/davinci-cpufreq.c | 2 +- drivers/cpufreq/imx-cpufreq-dt.c | 2 +- drivers/cpufreq/imx6q-cpufreq.c | 2 +- drivers/cpufreq/kirkwood-cpufreq.c | 2 +- drivers/cpufreq/loongson3_cpufreq.c | 2 +- drivers/cpufreq/mediatek-cpufreq-hw.c | 2 +- drivers/cpufreq/omap-cpufreq.c | 2 +- drivers/cpufreq/pcc-cpufreq.c | 2 +- drivers/cpufreq/qcom-cpufreq-hw.c | 2 +- drivers/cpufreq/qcom-cpufreq-nvmem.c | 2 +- drivers/cpufreq/qoriq-cpufreq.c | 2 +- drivers/cpufreq/raspberrypi-cpufreq.c | 2 +- drivers/cpufreq/scpi-cpufreq.c | 2 +- drivers/cpufreq/sun50i-cpufreq-nvmem.c | 2 +- drivers/cpufreq/tegra186-cpufreq.c | 2 +- drivers/cpufreq/tegra194-cpufreq.c | 2 +- drivers/cpufreq/vexpress-spc-cpufreq.c | 2 +- 20 files changed, 20 insertions(+), 20 deletions(-) diff --git a/drivers/cpufreq/acpi-cpufreq.c b/drivers/cpufreq/acpi-cpufreq.c index 0f04feb6cafa..433eb597c2b8 100644 --- a/drivers/cpufreq/acpi-cpufreq.c +++ b/drivers/cpufreq/acpi-cpufreq.c @@ -1028,7 +1028,7 @@ static struct platform_driver acpi_cpufreq_platdrv = { .driver = { .name = "acpi-cpufreq", }, - .remove_new = acpi_cpufreq_remove, + .remove = acpi_cpufreq_remove, }; static int __init acpi_cpufreq_init(void) diff --git a/drivers/cpufreq/brcmstb-avs-cpufreq.c b/drivers/cpufreq/brcmstb-avs-cpufreq.c index ea8438550b49..5d03a295a085 100644 --- a/drivers/cpufreq/brcmstb-avs-cpufreq.c +++ b/drivers/cpufreq/brcmstb-avs-cpufreq.c @@ -777,7 +777,7 @@ static struct platform_driver brcm_avs_cpufreq_platdrv = { .of_match_table = brcm_avs_cpufreq_match, }, .probe = brcm_avs_cpufreq_probe, - .remove_new = brcm_avs_cpufreq_remove, + .remove = brcm_avs_cpufreq_remove, }; module_platform_driver(brcm_avs_cpufreq_platdrv); diff --git a/drivers/cpufreq/cpufreq-dt.c b/drivers/cpufreq/cpufreq-dt.c index 983443396f8f..3a7c3372bda7 100644 --- a/drivers/cpufreq/cpufreq-dt.c +++ b/drivers/cpufreq/cpufreq-dt.c @@ -345,7 +345,7 @@ static struct platform_driver dt_cpufreq_platdrv = { .name = "cpufreq-dt", }, .probe = dt_cpufreq_probe, - .remove_new = dt_cpufreq_remove, + .remove = dt_cpufreq_remove, }; module_platform_driver(dt_cpufreq_platdrv); diff --git a/drivers/cpufreq/davinci-cpufreq.c b/drivers/cpufreq/davinci-cpufreq.c index 7d2754411d8c..8736be3a06ce 100644 --- a/drivers/cpufreq/davinci-cpufreq.c +++ b/drivers/cpufreq/davinci-cpufreq.c @@ -145,7 +145,7 @@ static struct platform_driver davinci_cpufreq_driver = { .driver = { .name = "cpufreq-davinci", }, - .remove_new = __exit_p(davinci_cpufreq_remove), + .remove = __exit_p(davinci_cpufreq_remove), }; int __init davinci_cpufreq_init(void) diff --git a/drivers/cpufreq/imx-cpufreq-dt.c b/drivers/cpufreq/imx-cpufreq-dt.c index 577bb9e2f112..1492c92ffc1a 100644 --- a/drivers/cpufreq/imx-cpufreq-dt.c +++ b/drivers/cpufreq/imx-cpufreq-dt.c @@ -183,7 +183,7 @@ static void imx_cpufreq_dt_remove(struct platform_device *pdev) static struct platform_driver imx_cpufreq_dt_driver = { .probe = imx_cpufreq_dt_probe, - .remove_new = imx_cpufreq_dt_remove, + .remove = imx_cpufreq_dt_remove, .driver = { .name = "imx-cpufreq-dt", }, diff --git a/drivers/cpufreq/imx6q-cpufreq.c b/drivers/cpufreq/imx6q-cpufreq.c index c20d3ecc5a81..f3c99f378ad6 100644 --- a/drivers/cpufreq/imx6q-cpufreq.c +++ b/drivers/cpufreq/imx6q-cpufreq.c @@ -522,7 +522,7 @@ static struct platform_driver imx6q_cpufreq_platdrv = { .name = "imx6q-cpufreq", }, .probe = imx6q_cpufreq_probe, - .remove_new = imx6q_cpufreq_remove, + .remove = imx6q_cpufreq_remove, }; module_platform_driver(imx6q_cpufreq_platdrv); diff --git a/drivers/cpufreq/kirkwood-cpufreq.c b/drivers/cpufreq/kirkwood-cpufreq.c index fd20b986d1f2..312f2654d1d5 100644 --- a/drivers/cpufreq/kirkwood-cpufreq.c +++ b/drivers/cpufreq/kirkwood-cpufreq.c @@ -189,7 +189,7 @@ static void kirkwood_cpufreq_remove(struct platform_device *pdev) static struct platform_driver kirkwood_cpufreq_platform_driver = { .probe = kirkwood_cpufreq_probe, - .remove_new = kirkwood_cpufreq_remove, + .remove = kirkwood_cpufreq_remove, .driver = { .name = "kirkwood-cpufreq", }, diff --git a/drivers/cpufreq/loongson3_cpufreq.c b/drivers/cpufreq/loongson3_cpufreq.c index 6b5e6798d9a2..61ebebf69455 100644 --- a/drivers/cpufreq/loongson3_cpufreq.c +++ b/drivers/cpufreq/loongson3_cpufreq.c @@ -386,7 +386,7 @@ static struct platform_driver loongson3_platform_driver = { }, .id_table = cpufreq_id_table, .probe = loongson3_cpufreq_probe, - .remove_new = loongson3_cpufreq_remove, + .remove = loongson3_cpufreq_remove, }; module_platform_driver(loongson3_platform_driver); diff --git a/drivers/cpufreq/mediatek-cpufreq-hw.c b/drivers/cpufreq/mediatek-cpufreq-hw.c index 8925e096d5b9..f7db5f4ad306 100644 --- a/drivers/cpufreq/mediatek-cpufreq-hw.c +++ b/drivers/cpufreq/mediatek-cpufreq-hw.c @@ -344,7 +344,7 @@ MODULE_DEVICE_TABLE(of, mtk_cpufreq_hw_match); static struct platform_driver mtk_cpufreq_hw_driver = { .probe = mtk_cpufreq_hw_driver_probe, - .remove_new = mtk_cpufreq_hw_driver_remove, + .remove = mtk_cpufreq_hw_driver_remove, .driver = { .name = "mtk-cpufreq-hw", .of_match_table = mtk_cpufreq_hw_match, diff --git a/drivers/cpufreq/omap-cpufreq.c b/drivers/cpufreq/omap-cpufreq.c index de8be0a8932d..106220c0fd11 100644 --- a/drivers/cpufreq/omap-cpufreq.c +++ b/drivers/cpufreq/omap-cpufreq.c @@ -188,7 +188,7 @@ static struct platform_driver omap_cpufreq_platdrv = { .name = "omap-cpufreq", }, .probe = omap_cpufreq_probe, - .remove_new = omap_cpufreq_remove, + .remove = omap_cpufreq_remove, }; module_platform_driver(omap_cpufreq_platdrv); diff --git a/drivers/cpufreq/pcc-cpufreq.c b/drivers/cpufreq/pcc-cpufreq.c index 771efbf51a48..ac2e90a65f0c 100644 --- a/drivers/cpufreq/pcc-cpufreq.c +++ b/drivers/cpufreq/pcc-cpufreq.c @@ -615,7 +615,7 @@ static struct platform_driver pcc_cpufreq_platdrv = { .driver = { .name = "pcc-cpufreq", }, - .remove_new = pcc_cpufreq_remove, + .remove = pcc_cpufreq_remove, }; static int __init pcc_cpufreq_init(void) diff --git a/drivers/cpufreq/qcom-cpufreq-hw.c b/drivers/cpufreq/qcom-cpufreq-hw.c index 900d6844c43d..98129565acb8 100644 --- a/drivers/cpufreq/qcom-cpufreq-hw.c +++ b/drivers/cpufreq/qcom-cpufreq-hw.c @@ -736,7 +736,7 @@ static void qcom_cpufreq_hw_driver_remove(struct platform_device *pdev) static struct platform_driver qcom_cpufreq_hw_driver = { .probe = qcom_cpufreq_hw_driver_probe, - .remove_new = qcom_cpufreq_hw_driver_remove, + .remove = qcom_cpufreq_hw_driver_remove, .driver = { .name = "qcom-cpufreq-hw", .of_match_table = qcom_cpufreq_hw_match, diff --git a/drivers/cpufreq/qcom-cpufreq-nvmem.c b/drivers/cpufreq/qcom-cpufreq-nvmem.c index 703308fb891a..08e518c89fc3 100644 --- a/drivers/cpufreq/qcom-cpufreq-nvmem.c +++ b/drivers/cpufreq/qcom-cpufreq-nvmem.c @@ -604,7 +604,7 @@ static DEFINE_SIMPLE_DEV_PM_OPS(qcom_cpufreq_pm_ops, qcom_cpufreq_suspend, NULL) static struct platform_driver qcom_cpufreq_driver = { .probe = qcom_cpufreq_probe, - .remove_new = qcom_cpufreq_remove, + .remove = qcom_cpufreq_remove, .driver = { .name = "qcom-cpufreq-nvmem", .pm = pm_sleep_ptr(&qcom_cpufreq_pm_ops), diff --git a/drivers/cpufreq/qoriq-cpufreq.c b/drivers/cpufreq/qoriq-cpufreq.c index 3519bf34d397..a37ce051236c 100644 --- a/drivers/cpufreq/qoriq-cpufreq.c +++ b/drivers/cpufreq/qoriq-cpufreq.c @@ -296,7 +296,7 @@ static struct platform_driver qoriq_cpufreq_platform_driver = { .name = "qoriq-cpufreq", }, .probe = qoriq_cpufreq_probe, - .remove_new = qoriq_cpufreq_remove, + .remove = qoriq_cpufreq_remove, }; module_platform_driver(qoriq_cpufreq_platform_driver); diff --git a/drivers/cpufreq/raspberrypi-cpufreq.c b/drivers/cpufreq/raspberrypi-cpufreq.c index e0705cc9a57d..5050932954e3 100644 --- a/drivers/cpufreq/raspberrypi-cpufreq.c +++ b/drivers/cpufreq/raspberrypi-cpufreq.c @@ -85,7 +85,7 @@ static struct platform_driver raspberrypi_cpufreq_driver = { .name = "raspberrypi-cpufreq", }, .probe = raspberrypi_cpufreq_probe, - .remove_new = raspberrypi_cpufreq_remove, + .remove = raspberrypi_cpufreq_remove, }; module_platform_driver(raspberrypi_cpufreq_driver); diff --git a/drivers/cpufreq/scpi-cpufreq.c b/drivers/cpufreq/scpi-cpufreq.c index 8d73e6e8be2a..cd89c1b9832c 100644 --- a/drivers/cpufreq/scpi-cpufreq.c +++ b/drivers/cpufreq/scpi-cpufreq.c @@ -217,7 +217,7 @@ static struct platform_driver scpi_cpufreq_platdrv = { .name = "scpi-cpufreq", }, .probe = scpi_cpufreq_probe, - .remove_new = scpi_cpufreq_remove, + .remove = scpi_cpufreq_remove, }; module_platform_driver(scpi_cpufreq_platdrv); diff --git a/drivers/cpufreq/sun50i-cpufreq-nvmem.c b/drivers/cpufreq/sun50i-cpufreq-nvmem.c index 293921acec93..352e1a69a85e 100644 --- a/drivers/cpufreq/sun50i-cpufreq-nvmem.c +++ b/drivers/cpufreq/sun50i-cpufreq-nvmem.c @@ -283,7 +283,7 @@ static void sun50i_cpufreq_nvmem_remove(struct platform_device *pdev) static struct platform_driver sun50i_cpufreq_driver = { .probe = sun50i_cpufreq_nvmem_probe, - .remove_new = sun50i_cpufreq_nvmem_remove, + .remove = sun50i_cpufreq_nvmem_remove, .driver = { .name = "sun50i-cpufreq-nvmem", }, diff --git a/drivers/cpufreq/tegra186-cpufreq.c b/drivers/cpufreq/tegra186-cpufreq.c index 7b8fcfa55038..c7761eb99f3c 100644 --- a/drivers/cpufreq/tegra186-cpufreq.c +++ b/drivers/cpufreq/tegra186-cpufreq.c @@ -276,7 +276,7 @@ static struct platform_driver tegra186_cpufreq_platform_driver = { .of_match_table = tegra186_cpufreq_of_match, }, .probe = tegra186_cpufreq_probe, - .remove_new = tegra186_cpufreq_remove, + .remove = tegra186_cpufreq_remove, }; module_platform_driver(tegra186_cpufreq_platform_driver); diff --git a/drivers/cpufreq/tegra194-cpufreq.c b/drivers/cpufreq/tegra194-cpufreq.c index 07ea7ed61b68..9055dd398e7f 100644 --- a/drivers/cpufreq/tegra194-cpufreq.c +++ b/drivers/cpufreq/tegra194-cpufreq.c @@ -818,7 +818,7 @@ static struct platform_driver tegra194_ccplex_driver = { .of_match_table = tegra194_cpufreq_of_match, }, .probe = tegra194_cpufreq_probe, - .remove_new = tegra194_cpufreq_remove, + .remove = tegra194_cpufreq_remove, }; module_platform_driver(tegra194_ccplex_driver); diff --git a/drivers/cpufreq/vexpress-spc-cpufreq.c b/drivers/cpufreq/vexpress-spc-cpufreq.c index 3fadf536c429..0f86cdb7ec8a 100644 --- a/drivers/cpufreq/vexpress-spc-cpufreq.c +++ b/drivers/cpufreq/vexpress-spc-cpufreq.c @@ -565,7 +565,7 @@ static struct platform_driver ve_spc_cpufreq_platdrv = { .name = "vexpress-spc-cpufreq", }, .probe = ve_spc_cpufreq_probe, - .remove_new = ve_spc_cpufreq_remove, + .remove = ve_spc_cpufreq_remove, }; module_platform_driver(ve_spc_cpufreq_platdrv); From 1bfe6a54d2fd979d86cc830be082834da81fa421 Mon Sep 17 00:00:00 2001 From: Dhananjay Ugwekar Date: Tue, 17 Sep 2024 09:14:35 +0000 Subject: [PATCH 03/25] cpufreq/amd-pstate: Rename MSR and shared memory specific functions Existing function names "cppc_*" and "pstate_*" for shared memory and MSR based systems are not intuitive enough, replace them with "shmem_*" and "msr_*" respectively. Signed-off-by: Dhananjay Ugwekar Reviewed-by: Mario Limonciello Link: https://lore.kernel.org/r/20240917091434.10685-1-Dhananjay.Ugwekar@amd.com Signed-off-by: Mario Limonciello --- drivers/cpufreq/amd-pstate.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c index b63863f77c67..b5a8c7f174c8 100644 --- a/drivers/cpufreq/amd-pstate.c +++ b/drivers/cpufreq/amd-pstate.c @@ -233,7 +233,7 @@ static int amd_pstate_get_energy_pref_index(struct amd_cpudata *cpudata) return index; } -static void pstate_update_perf(struct amd_cpudata *cpudata, u32 min_perf, +static void msr_update_perf(struct amd_cpudata *cpudata, u32 min_perf, u32 des_perf, u32 max_perf, bool fast_switch) { if (fast_switch) @@ -243,7 +243,7 @@ static void pstate_update_perf(struct amd_cpudata *cpudata, u32 min_perf, READ_ONCE(cpudata->cppc_req_cached)); } -DEFINE_STATIC_CALL(amd_pstate_update_perf, pstate_update_perf); +DEFINE_STATIC_CALL(amd_pstate_update_perf, msr_update_perf); static inline void amd_pstate_update_perf(struct amd_cpudata *cpudata, u32 min_perf, u32 des_perf, @@ -306,7 +306,7 @@ static int amd_pstate_set_energy_pref_index(struct amd_cpudata *cpudata, return ret; } -static inline int pstate_enable(bool enable) +static inline int msr_enable(bool enable) { int ret, cpu; unsigned long logical_proc_id_mask = 0; @@ -332,7 +332,7 @@ static inline int pstate_enable(bool enable) return 0; } -static int cppc_enable(bool enable) +static int shmem_enable(bool enable) { int cpu, ret = 0; struct cppc_perf_ctrls perf_ctrls; @@ -359,14 +359,14 @@ static int cppc_enable(bool enable) return ret; } -DEFINE_STATIC_CALL(amd_pstate_enable, pstate_enable); +DEFINE_STATIC_CALL(amd_pstate_enable, msr_enable); static inline int amd_pstate_enable(bool enable) { return static_call(amd_pstate_enable)(enable); } -static int pstate_init_perf(struct amd_cpudata *cpudata) +static int msr_init_perf(struct amd_cpudata *cpudata) { u64 cap1; @@ -385,7 +385,7 @@ static int pstate_init_perf(struct amd_cpudata *cpudata) return 0; } -static int cppc_init_perf(struct amd_cpudata *cpudata) +static int shmem_init_perf(struct amd_cpudata *cpudata) { struct cppc_perf_caps cppc_perf; @@ -420,14 +420,14 @@ static int cppc_init_perf(struct amd_cpudata *cpudata) return ret; } -DEFINE_STATIC_CALL(amd_pstate_init_perf, pstate_init_perf); +DEFINE_STATIC_CALL(amd_pstate_init_perf, msr_init_perf); static inline int amd_pstate_init_perf(struct amd_cpudata *cpudata) { return static_call(amd_pstate_init_perf)(cpudata); } -static void cppc_update_perf(struct amd_cpudata *cpudata, +static void shmem_update_perf(struct amd_cpudata *cpudata, u32 min_perf, u32 des_perf, u32 max_perf, bool fast_switch) { @@ -1897,9 +1897,9 @@ static int __init amd_pstate_init(void) current_pstate_driver->adjust_perf = amd_pstate_adjust_perf; } else { pr_debug("AMD CPPC shared memory based functionality is supported\n"); - static_call_update(amd_pstate_enable, cppc_enable); - static_call_update(amd_pstate_init_perf, cppc_init_perf); - static_call_update(amd_pstate_update_perf, cppc_update_perf); + static_call_update(amd_pstate_enable, shmem_enable); + static_call_update(amd_pstate_init_perf, shmem_init_perf); + static_call_update(amd_pstate_update_perf, shmem_update_perf); } if (amd_pstate_prefcore) { From 7820e8050d622b9bc9bf9acbe8a60f62888a135e Mon Sep 17 00:00:00 2001 From: Mario Limonciello Date: Thu, 5 Sep 2024 11:23:51 -0500 Subject: [PATCH 04/25] cpufreq/amd-pstate: Fix non kerneldoc comment The comment for amd_cppc_supported() isn't meant to be kernel doc. Fixes: cb817ec6673b7 ("cpufreq: amd-pstate: show CPPC debug message if CPPC is not supported") Link: https://lore.kernel.org/r/20240905162351.1345560-1-superm1@kernel.org Signed-off-by: Mario Limonciello --- drivers/cpufreq/amd-pstate.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c index b5a8c7f174c8..dfa9a146769b 100644 --- a/drivers/cpufreq/amd-pstate.c +++ b/drivers/cpufreq/amd-pstate.c @@ -1774,7 +1774,7 @@ static int __init amd_pstate_set_driver(int mode_idx) return -EINVAL; } -/** +/* * CPPC function is not supported for family ID 17H with model_ID ranging from 0x10 to 0x2F. * show the debug message that helps to check if the CPU has CPPC support for loading issue. */ From 67c08d303e0a1a5665b3f198037c9fae2d808090 Mon Sep 17 00:00:00 2001 From: Mario Limonciello Date: Sat, 12 Oct 2024 12:45:17 -0500 Subject: [PATCH 05/25] cpufreq/amd-pstate: Don't update CPPC request in amd_pstate_cpu_boost_update() When boost is changed the CPPC value is changed in amd_pstate_cpu_boost_update() but then changed again when refresh_frequency_limits() and all it's callbacks occur. The first is a pointless write, so instead just update the limits for the policy and let the policy refresh anchor everything properly. Fixes: c8c68c38b56f ("cpufreq: amd-pstate: initialize core precision boost state") Reviewed-by: Gautham R. Shenoy Reviewed-by: Perry Yuan Tested-by: Dhananjay Ugwekar Link: https://lore.kernel.org/r/20241012174519.897-2-mario.limonciello@amd.com Signed-off-by: Mario Limonciello --- drivers/cpufreq/amd-pstate.c | 24 +----------------------- 1 file changed, 1 insertion(+), 23 deletions(-) diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c index dfa9a146769b..13dec8b1e7a8 100644 --- a/drivers/cpufreq/amd-pstate.c +++ b/drivers/cpufreq/amd-pstate.c @@ -665,34 +665,12 @@ static void amd_pstate_adjust_perf(unsigned int cpu, static int amd_pstate_cpu_boost_update(struct cpufreq_policy *policy, bool on) { struct amd_cpudata *cpudata = policy->driver_data; - struct cppc_perf_ctrls perf_ctrls; - u32 highest_perf, nominal_perf, nominal_freq, max_freq; + u32 nominal_freq, max_freq; int ret = 0; - highest_perf = READ_ONCE(cpudata->highest_perf); - nominal_perf = READ_ONCE(cpudata->nominal_perf); nominal_freq = READ_ONCE(cpudata->nominal_freq); max_freq = READ_ONCE(cpudata->max_freq); - if (boot_cpu_has(X86_FEATURE_CPPC)) { - u64 value = READ_ONCE(cpudata->cppc_req_cached); - - value &= ~GENMASK_ULL(7, 0); - value |= on ? highest_perf : nominal_perf; - WRITE_ONCE(cpudata->cppc_req_cached, value); - - wrmsrl_on_cpu(cpudata->cpu, MSR_AMD_CPPC_REQ, value); - } else { - perf_ctrls.max_perf = on ? highest_perf : nominal_perf; - ret = cppc_set_perf(cpudata->cpu, &perf_ctrls); - if (ret) { - cpufreq_cpu_release(policy); - pr_debug("Failed to set max perf on CPU:%d. ret:%d\n", - cpudata->cpu, ret); - return ret; - } - } - if (on) policy->cpuinfo.max_freq = max_freq; else if (policy->cpuinfo.max_freq > nominal_freq * 1000) From 047a2d0c83a425e83aa58b43c2557c42fdd0af29 Mon Sep 17 00:00:00 2001 From: Mario Limonciello Date: Sat, 12 Oct 2024 12:45:18 -0500 Subject: [PATCH 06/25] cpufreq/amd-pstate: Use amd_pstate_update_min_max_limit() for EPP limits When the EPP updates are set the maximum capable frequency for the CPU is used to set the upper limit instead of that of the policy. Adjust amd_pstate_epp_update_limit() to reuse policy calculation code from amd_pstate_update_min_max_limit(). Reviewed-by: Gautham R. Shenoy Reviewed-by: Perry Yuan Tested-by: Dhananjay Ugwekar Link: https://lore.kernel.org/r/20241012174519.897-3-mario.limonciello@amd.com Signed-off-by: Mario Limonciello --- drivers/cpufreq/amd-pstate.c | 19 +++---------------- 1 file changed, 3 insertions(+), 16 deletions(-) diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c index 13dec8b1e7a8..8d2541f2c74b 100644 --- a/drivers/cpufreq/amd-pstate.c +++ b/drivers/cpufreq/amd-pstate.c @@ -1485,26 +1485,13 @@ static void amd_pstate_epp_cpu_exit(struct cpufreq_policy *policy) static int amd_pstate_epp_update_limit(struct cpufreq_policy *policy) { struct amd_cpudata *cpudata = policy->driver_data; - u32 max_perf, min_perf, min_limit_perf, max_limit_perf; + u32 max_perf, min_perf; u64 value; s16 epp; - if (cpudata->boost_supported && !policy->boost_enabled) - max_perf = READ_ONCE(cpudata->nominal_perf); - else - max_perf = READ_ONCE(cpudata->highest_perf); + max_perf = READ_ONCE(cpudata->highest_perf); min_perf = READ_ONCE(cpudata->lowest_perf); - max_limit_perf = div_u64(policy->max * max_perf, policy->cpuinfo.max_freq); - min_limit_perf = div_u64(policy->min * max_perf, policy->cpuinfo.max_freq); - - if (min_limit_perf < min_perf) - min_limit_perf = min_perf; - - if (max_limit_perf < min_limit_perf) - max_limit_perf = min_limit_perf; - - WRITE_ONCE(cpudata->max_limit_perf, max_limit_perf); - WRITE_ONCE(cpudata->min_limit_perf, min_limit_perf); + amd_pstate_update_min_max_limit(policy); max_perf = clamp_t(unsigned long, max_perf, cpudata->min_limit_perf, cpudata->max_limit_perf); From 508239724bdddf34482c4d134262f2292c1c78f0 Mon Sep 17 00:00:00 2001 From: Mario Limonciello Date: Sat, 12 Oct 2024 12:45:19 -0500 Subject: [PATCH 07/25] cpufreq/amd-pstate: Drop needless EPP initialization The EPP value doesn't need to be cached to the CPPC request in amd_pstate_epp_update_limit() because it's passed as an argument at the end to amd_pstate_set_epp() and stored at that time. Reviewed-by: Gautham R. Shenoy Reviewed-by: Perry Yuan Tested-by: Dhananjay Ugwekar Link: https://lore.kernel.org/r/20241012174519.897-4-mario.limonciello@amd.com Signed-off-by: Mario Limonciello --- drivers/cpufreq/amd-pstate.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c index 8d2541f2c74b..90868c8b214e 100644 --- a/drivers/cpufreq/amd-pstate.c +++ b/drivers/cpufreq/amd-pstate.c @@ -1528,12 +1528,6 @@ static int amd_pstate_epp_update_limit(struct cpufreq_policy *policy) if (cpudata->policy == CPUFREQ_POLICY_PERFORMANCE) epp = 0; - /* Set initial EPP value */ - if (cpu_feature_enabled(X86_FEATURE_CPPC)) { - value &= ~GENMASK_ULL(31, 24); - value |= (u64)epp << 24; - } - WRITE_ONCE(cpudata->cppc_req_cached, value); return amd_pstate_set_epp(cpudata, epp); } From 205cb215d08748fdd8f3fd67bc7aa626d4e278b0 Mon Sep 17 00:00:00 2001 From: Dhananjay Ugwekar Date: Thu, 17 Oct 2024 05:39:28 +0000 Subject: [PATCH 08/25] cpufreq/amd-pstate: Remove the redundant verify() function Merge the two verify() callback functions and rename the cpufreq_policy_data argument for better readability. Signed-off-by: Dhananjay Ugwekar Reviewed-by: Mario Limonciello Reviewed-by: Gautham R. Shenoy Link: https://lore.kernel.org/r/20241017053927.25285-2-Dhananjay.Ugwekar@amd.com Signed-off-by: Mario Limonciello --- drivers/cpufreq/amd-pstate.c | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c index 90868c8b214e..ee2decad10af 100644 --- a/drivers/cpufreq/amd-pstate.c +++ b/drivers/cpufreq/amd-pstate.c @@ -527,10 +527,10 @@ static void amd_pstate_update(struct amd_cpudata *cpudata, u32 min_perf, cpufreq_cpu_put(policy); } -static int amd_pstate_verify(struct cpufreq_policy_data *policy) +static int amd_pstate_verify(struct cpufreq_policy_data *policy_data) { - cpufreq_verify_within_cpu_limits(policy); - + cpufreq_verify_within_cpu_limits(policy_data); + pr_debug("policy_max =%d, policy_min=%d\n", policy_data->max, policy_data->min); return 0; } @@ -1638,13 +1638,6 @@ static int amd_pstate_epp_cpu_offline(struct cpufreq_policy *policy) return 0; } -static int amd_pstate_epp_verify_policy(struct cpufreq_policy_data *policy) -{ - cpufreq_verify_within_cpu_limits(policy); - pr_debug("policy_max =%d, policy_min=%d\n", policy->max, policy->min); - return 0; -} - static int amd_pstate_epp_suspend(struct cpufreq_policy *policy) { struct amd_cpudata *cpudata = policy->driver_data; @@ -1700,7 +1693,7 @@ static struct cpufreq_driver amd_pstate_driver = { static struct cpufreq_driver amd_pstate_epp_driver = { .flags = CPUFREQ_CONST_LOOPS, - .verify = amd_pstate_epp_verify_policy, + .verify = amd_pstate_verify, .setpolicy = amd_pstate_epp_set_policy, .init = amd_pstate_epp_cpu_init, .exit = amd_pstate_epp_cpu_exit, From 5d9a354cf839a652f8f6ca2b920696c6a9041801 Mon Sep 17 00:00:00 2001 From: Dhananjay Ugwekar Date: Thu, 17 Oct 2024 05:39:30 +0000 Subject: [PATCH 09/25] cpufreq/amd-pstate: Set the initial min_freq to lowest_nonlinear_freq According to the AMD architectural programmer's manual volume 2 [1], in section "17.6.4.1 CPPC_CAPABILITY_1" lowest_nonlinear_perf is described as "Reports the most energy efficient performance level (in terms of performance per watt). Above this threshold, lower performance levels generally result in increased energy efficiency. Reducing performance below this threshold does not result in total energy savings for a given computation, although it reduces instantaneous power consumption". So lowest_nonlinear_perf is the most power efficient performance level, and going below that would lead to a worse performance/watt. Also, setting the minimum frequency to lowest_nonlinear_freq (instead of lowest_freq) allows the CPU to idle at a higher frequency which leads to more time being spent in a deeper idle state (as trivial idle tasks are completed sooner). This has shown a power benefit in some systems, in other systems, power consumption has increased but so has the throughput/watt. Modify the initial policy_data->min set by cpufreq-core to lowest_nonlinear_freq, in the ->verify() callback. Also set the cpudata->req[0] to FREQ_QOS_MIN_DEFAULT_VALUE (i.e. 0), so that it also gets overriden by the check in verify function. Link: https://www.amd.com/content/dam/amd/en/documents/processor-tech-docs/programmer-references/24593.pdf [1] Signed-off-by: Dhananjay Ugwekar Reviewed-by: Mario Limonciello Link: https://lore.kernel.org/r/20241017053927.25285-3-Dhananjay.Ugwekar@amd.com Signed-off-by: Mario Limonciello --- drivers/cpufreq/amd-pstate.c | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c index ee2decad10af..b0a1c472cc3b 100644 --- a/drivers/cpufreq/amd-pstate.c +++ b/drivers/cpufreq/amd-pstate.c @@ -529,8 +529,27 @@ static void amd_pstate_update(struct amd_cpudata *cpudata, u32 min_perf, static int amd_pstate_verify(struct cpufreq_policy_data *policy_data) { + /* + * Initialize lower frequency limit (i.e.policy->min) with + * lowest_nonlinear_frequency which is the most energy efficient + * frequency. Override the initial value set by cpufreq core and + * amd-pstate qos_requests. + */ + if (policy_data->min == FREQ_QOS_MIN_DEFAULT_VALUE) { + struct cpufreq_policy *policy = cpufreq_cpu_get(policy_data->cpu); + struct amd_cpudata *cpudata; + + if (!policy) + return -EINVAL; + + cpudata = policy->driver_data; + policy_data->min = cpudata->lowest_nonlinear_freq; + cpufreq_cpu_put(policy); + } + cpufreq_verify_within_cpu_limits(policy_data); pr_debug("policy_max =%d, policy_min=%d\n", policy_data->max, policy_data->min); + return 0; } @@ -979,7 +998,7 @@ static int amd_pstate_cpu_init(struct cpufreq_policy *policy) policy->fast_switch_possible = true; ret = freq_qos_add_request(&policy->constraints, &cpudata->req[0], - FREQ_QOS_MIN, policy->cpuinfo.min_freq); + FREQ_QOS_MIN, FREQ_QOS_MIN_DEFAULT_VALUE); if (ret < 0) { dev_err(dev, "Failed to add min-freq constraint (%d)\n", ret); goto free_cpudata1; From 6f241fa50a1a45018d01f2d79a122eb519618f0e Mon Sep 17 00:00:00 2001 From: Dhananjay Ugwekar Date: Thu, 17 Oct 2024 10:05:27 +0000 Subject: [PATCH 10/25] cpufreq/amd-pstate: Call amd_pstate_register() in amd_pstate_init() Replace a similar chunk of code in amd_pstate_init() with amd_pstate_register() call. Suggested-by: Mario Limonciello Signed-off-by: Dhananjay Ugwekar Reviewed-by: Mario Limonciello Link: https://lore.kernel.org/r/20241017100528.300143-2-Dhananjay.Ugwekar@amd.com Signed-off-by: Mario Limonciello --- drivers/cpufreq/amd-pstate.c | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c index b0a1c472cc3b..856f0d11983e 100644 --- a/drivers/cpufreq/amd-pstate.c +++ b/drivers/cpufreq/amd-pstate.c @@ -1879,17 +1879,10 @@ static int __init amd_pstate_init(void) return ret; } - /* enable amd pstate feature */ - ret = amd_pstate_enable(true); - if (ret) { - pr_err("failed to enable driver mode(%d)\n", cppc_state); - return ret; - } - - ret = cpufreq_register_driver(current_pstate_driver); + ret = amd_pstate_register_driver(cppc_state); if (ret) { pr_err("failed to register with return %d\n", ret); - goto disable_driver; + return ret; } dev_root = bus_get_dev_root(&cpu_subsys); @@ -1906,7 +1899,6 @@ static int __init amd_pstate_init(void) global_attr_free: cpufreq_unregister_driver(current_pstate_driver); -disable_driver: amd_pstate_enable(false); return ret; } From e3591eebeca78117ce1d07985d42b75e6506252a Mon Sep 17 00:00:00 2001 From: Dhananjay Ugwekar Date: Thu, 17 Oct 2024 10:05:29 +0000 Subject: [PATCH 11/25] cpufreq/amd-pstate: Call amd_pstate_set_driver() in amd_pstate_register_driver() Replace a similar chunk of code in amd_pstate_register_driver() with amd_pstate_set_driver() call. Signed-off-by: Dhananjay Ugwekar Reviewed-by: Mario Limonciello Link: https://lore.kernel.org/r/20241017100528.300143-3-Dhananjay.Ugwekar@amd.com Signed-off-by: Mario Limonciello --- drivers/cpufreq/amd-pstate.c | 47 +++++++++++++++++------------------- 1 file changed, 22 insertions(+), 25 deletions(-) diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c index 856f0d11983e..5155fc0019df 100644 --- a/drivers/cpufreq/amd-pstate.c +++ b/drivers/cpufreq/amd-pstate.c @@ -1191,16 +1191,32 @@ static void amd_pstate_driver_cleanup(void) current_pstate_driver = NULL; } +static int amd_pstate_set_driver(int mode_idx) +{ + if (mode_idx >= AMD_PSTATE_DISABLE && mode_idx < AMD_PSTATE_MAX) { + cppc_state = mode_idx; + if (cppc_state == AMD_PSTATE_DISABLE) + pr_info("driver is explicitly disabled\n"); + + if (cppc_state == AMD_PSTATE_ACTIVE) + current_pstate_driver = &amd_pstate_epp_driver; + + if (cppc_state == AMD_PSTATE_PASSIVE || cppc_state == AMD_PSTATE_GUIDED) + current_pstate_driver = &amd_pstate_driver; + + return 0; + } + + return -EINVAL; +} + static int amd_pstate_register_driver(int mode) { int ret; - if (mode == AMD_PSTATE_PASSIVE || mode == AMD_PSTATE_GUIDED) - current_pstate_driver = &amd_pstate_driver; - else if (mode == AMD_PSTATE_ACTIVE) - current_pstate_driver = &amd_pstate_epp_driver; - else - return -EINVAL; + ret = amd_pstate_set_driver(mode); + if (ret) + return ret; cppc_state = mode; @@ -1726,25 +1742,6 @@ static struct cpufreq_driver amd_pstate_epp_driver = { .attr = amd_pstate_epp_attr, }; -static int __init amd_pstate_set_driver(int mode_idx) -{ - if (mode_idx >= AMD_PSTATE_DISABLE && mode_idx < AMD_PSTATE_MAX) { - cppc_state = mode_idx; - if (cppc_state == AMD_PSTATE_DISABLE) - pr_info("driver is explicitly disabled\n"); - - if (cppc_state == AMD_PSTATE_ACTIVE) - current_pstate_driver = &amd_pstate_epp_driver; - - if (cppc_state == AMD_PSTATE_PASSIVE || cppc_state == AMD_PSTATE_GUIDED) - current_pstate_driver = &amd_pstate_driver; - - return 0; - } - - return -EINVAL; -} - /* * CPPC function is not supported for family ID 17H with model_ID ranging from 0x10 to 0x2F. * show the debug message that helps to check if the CPU has CPPC support for loading issue. From 162cfa4eba7350cdcbd610c4b2af860a0ecc5f21 Mon Sep 17 00:00:00 2001 From: Dhananjay Ugwekar Date: Thu, 17 Oct 2024 10:05:31 +0000 Subject: [PATCH 12/25] cpufreq/amd-pstate: Remove the switch case in amd_pstate_init() Replace the switch case with a more readable if condition. Signed-off-by: Dhananjay Ugwekar Reviewed-by: Mario Limonciello Link: https://lore.kernel.org/r/20241017100528.300143-4-Dhananjay.Ugwekar@amd.com Signed-off-by: Mario Limonciello --- drivers/cpufreq/amd-pstate.c | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c index 5155fc0019df..13ee5cac901d 100644 --- a/drivers/cpufreq/amd-pstate.c +++ b/drivers/cpufreq/amd-pstate.c @@ -1843,21 +1843,15 @@ static int __init amd_pstate_init(void) cppc_state = CONFIG_X86_AMD_PSTATE_DEFAULT_MODE; } - switch (cppc_state) { - case AMD_PSTATE_DISABLE: + if (cppc_state == AMD_PSTATE_DISABLE) { pr_info("driver load is disabled, boot with specific mode to enable this\n"); return -ENODEV; - case AMD_PSTATE_PASSIVE: - case AMD_PSTATE_ACTIVE: - case AMD_PSTATE_GUIDED: - ret = amd_pstate_set_driver(cppc_state); - if (ret) - return ret; - break; - default: - return -EINVAL; } + ret = amd_pstate_set_driver(cppc_state); + if (ret) + return ret; + /* capability check */ if (cpu_feature_enabled(X86_FEATURE_CPPC)) { pr_debug("AMD CPPC MSR based functionality is supported\n"); From b427ac4084753d7c62ef797bed7f30203f0ef5fb Mon Sep 17 00:00:00 2001 From: Dhananjay Ugwekar Date: Thu, 17 Oct 2024 10:05:33 +0000 Subject: [PATCH 13/25] cpufreq/amd-pstate: Remove the redundant amd_pstate_set_driver() call amd_pstate_set_driver() is called twice, once in amd_pstate_init() and once as part of amd_pstate_register_driver(). Move around code and eliminate the redundancy. Signed-off-by: Dhananjay Ugwekar Reviewed-by: Mario Limonciello Link: https://lore.kernel.org/r/20241017100528.300143-5-Dhananjay.Ugwekar@amd.com Signed-off-by: Mario Limonciello --- drivers/cpufreq/amd-pstate.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c index 13ee5cac901d..6f6d961879cc 100644 --- a/drivers/cpufreq/amd-pstate.c +++ b/drivers/cpufreq/amd-pstate.c @@ -1848,9 +1848,11 @@ static int __init amd_pstate_init(void) return -ENODEV; } - ret = amd_pstate_set_driver(cppc_state); - if (ret) + ret = amd_pstate_register_driver(cppc_state); + if (ret) { + pr_err("failed to register with return %d\n", ret); return ret; + } /* capability check */ if (cpu_feature_enabled(X86_FEATURE_CPPC)) { @@ -1870,12 +1872,6 @@ static int __init amd_pstate_init(void) return ret; } - ret = amd_pstate_register_driver(cppc_state); - if (ret) { - pr_err("failed to register with return %d\n", ret); - return ret; - } - dev_root = bus_get_dev_root(&cpu_subsys); if (dev_root) { ret = sysfs_create_group(&dev_root->kobj, &amd_pstate_global_attr_group); From 0c411b39e4f4ce8861301fa201cb4f817751311e Mon Sep 17 00:00:00 2001 From: "Gautham R. Shenoy" Date: Mon, 21 Oct 2024 15:48:35 +0530 Subject: [PATCH 14/25] amd-pstate: Set min_perf to nominal_perf for active mode performance gov The amd-pstate driver sets CPPC_REQ.min_perf to CPPC_REQ.max_perf when in active mode with performance governor. Typically CPPC_REQ.max_perf is set to CPPC.highest_perf. This causes frequency throttling on power-limited platforms which causes performance regressions on certain classes of workloads. Hence, set the CPPC_REQ.min_perf to the CPPC.nominal_perf or CPPC_REQ.max_perf, whichever is lower of the two. Fixes: ffa5096a7c33 ("cpufreq: amd-pstate: implement Pstate EPP support for the AMD processors") Signed-off-by: Gautham R. Shenoy Reviewed-by: Mario Limonciello Link: https://lore.kernel.org/r/20241021101836.9047-2-gautham.shenoy@amd.com Signed-off-by: Mario Limonciello --- drivers/cpufreq/amd-pstate.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c index 6f6d961879cc..23349f50c83e 100644 --- a/drivers/cpufreq/amd-pstate.c +++ b/drivers/cpufreq/amd-pstate.c @@ -1535,7 +1535,7 @@ static int amd_pstate_epp_update_limit(struct cpufreq_policy *policy) value = READ_ONCE(cpudata->cppc_req_cached); if (cpudata->policy == CPUFREQ_POLICY_PERFORMANCE) - min_perf = max_perf; + min_perf = min(cpudata->nominal_perf, max_perf); /* Initial min/max values for CPPC Performance Controls Register */ value &= ~AMD_CPPC_MIN_PERF(~0L); From 54ab7d7c59c9444a28b67eaa10983f86ebf73c69 Mon Sep 17 00:00:00 2001 From: Swapnil Sapkal Date: Mon, 21 Oct 2024 15:48:36 +0530 Subject: [PATCH 15/25] amd-pstate: Switch to amd-pstate by default on some Server platforms Currently the default cpufreq driver for all the AMD EPYC servers is acpi-cpufreq. Going forward, switch to amd-pstate as the default driver on the AMD EPYC server platforms with CPU family 0x1A or higher. The default mode will be active mode. Testing shows that amd-pstate with active mode and performance governor provides comparable or better performance per-watt against acpi-cpufreq + performance governor. Likewise, amd-pstate with active mode and powersave governor with the energy_performance_preference=power (EPP=255) provides comparable or better performance per-watt against acpi-cpufreq + schedutil governor for a wide range of workloads. Users can still revert to using acpi-cpufreq driver on these platforms with the "amd_pstate=disable" kernel commandline parameter. Signed-off-by: Swapnil Sapkal Signed-off-by: Gautham R. Shenoy Reviewed-by: Mario Limonciello Link: https://lore.kernel.org/r/20241021101836.9047-3-gautham.shenoy@amd.com Signed-off-by: Mario Limonciello --- drivers/cpufreq/amd-pstate.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c index 23349f50c83e..3c14962adeb2 100644 --- a/drivers/cpufreq/amd-pstate.c +++ b/drivers/cpufreq/amd-pstate.c @@ -1832,10 +1832,10 @@ static int __init amd_pstate_init(void) if (cppc_state == AMD_PSTATE_UNDEFINED) { /* Disable on the following configs by default: * 1. Undefined platforms - * 2. Server platforms + * 2. Server platforms with CPUs older than Family 0x1A. */ if (amd_pstate_acpi_pm_profile_undefined() || - amd_pstate_acpi_pm_profile_server()) { + (amd_pstate_acpi_pm_profile_server() && boot_cpu_data.x86 < 0x1A)) { pr_info("driver load is disabled, boot with specific mode to enable this\n"); return -ENODEV; } From 31f9056ed243002a2ec1d8cfa871d2c3eb84cf83 Mon Sep 17 00:00:00 2001 From: Mario Limonciello Date: Thu, 17 Oct 2024 12:34:39 -0500 Subject: [PATCH 16/25] cpufreq/amd-pstate-ut: Add fix for min freq unit test commit 642aff3964b0f ("cpufreq/amd-pstate: Set the initial min_freq to lowest_nonlinear_freq") changed the initial minimum frequency to lowest nonlinear frequency, but the unit tests weren't updated and now fail. Update them to match this same change. Fixes: 642aff3964b0f ("cpufreq/amd-pstate: Set the initial min_freq to lowest_nonlinear_freq") Link: https://lore.kernel.org/r/20241017173439.4924-1-mario.limonciello@amd.com Signed-off-by: Mario Limonciello --- drivers/cpufreq/amd-pstate-ut.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/cpufreq/amd-pstate-ut.c b/drivers/cpufreq/amd-pstate-ut.c index f66701514d90..a261d7300951 100644 --- a/drivers/cpufreq/amd-pstate-ut.c +++ b/drivers/cpufreq/amd-pstate-ut.c @@ -227,10 +227,10 @@ static void amd_pstate_ut_check_freq(u32 index) goto skip_test; } - if (cpudata->min_freq != policy->min) { + if (cpudata->lowest_nonlinear_freq != policy->min) { amd_pstate_ut_cases[index].result = AMD_PSTATE_UT_RESULT_FAIL; - pr_err("%s cpu%d cpudata_min_freq=%d policy_min=%d, they should be equal!\n", - __func__, cpu, cpudata->min_freq, policy->min); + pr_err("%s cpu%d cpudata_lowest_nonlinear_freq=%d policy_min=%d, they should be equal!\n", + __func__, cpu, cpudata->lowest_nonlinear_freq, policy->min); goto skip_test; } From 7fb463aac84577b93f666658ef61e59d78c53627 Mon Sep 17 00:00:00 2001 From: Dhananjay Ugwekar Date: Wed, 23 Oct 2024 10:21:06 +0000 Subject: [PATCH 17/25] cpufreq/amd-pstate: Rename functions that enable CPPC Explicitly rename functions that enable CPPC as *_cppc_*. Signed-off-by: Dhananjay Ugwekar Reviewed-by: Mario Limonciello Reviewed-by: Perry Yuan Link: https://lore.kernel.org/r/20241023102108.5980-2-Dhananjay.Ugwekar@amd.com Signed-off-by: Mario Limonciello --- drivers/cpufreq/amd-pstate.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c index 3c14962adeb2..0b4a4d69c14d 100644 --- a/drivers/cpufreq/amd-pstate.c +++ b/drivers/cpufreq/amd-pstate.c @@ -306,7 +306,7 @@ static int amd_pstate_set_energy_pref_index(struct amd_cpudata *cpudata, return ret; } -static inline int msr_enable(bool enable) +static inline int msr_cppc_enable(bool enable) { int ret, cpu; unsigned long logical_proc_id_mask = 0; @@ -332,7 +332,7 @@ static inline int msr_enable(bool enable) return 0; } -static int shmem_enable(bool enable) +static int shmem_cppc_enable(bool enable) { int cpu, ret = 0; struct cppc_perf_ctrls perf_ctrls; @@ -359,11 +359,11 @@ static int shmem_enable(bool enable) return ret; } -DEFINE_STATIC_CALL(amd_pstate_enable, msr_enable); +DEFINE_STATIC_CALL(amd_pstate_cppc_enable, msr_cppc_enable); -static inline int amd_pstate_enable(bool enable) +static inline int amd_pstate_cppc_enable(bool enable) { - return static_call(amd_pstate_enable)(enable); + return static_call(amd_pstate_cppc_enable)(enable); } static int msr_init_perf(struct amd_cpudata *cpudata) @@ -1042,7 +1042,7 @@ static int amd_pstate_cpu_resume(struct cpufreq_policy *policy) { int ret; - ret = amd_pstate_enable(true); + ret = amd_pstate_cppc_enable(true); if (ret) pr_err("failed to enable amd-pstate during resume, return %d\n", ret); @@ -1053,7 +1053,7 @@ static int amd_pstate_cpu_suspend(struct cpufreq_policy *policy) { int ret; - ret = amd_pstate_enable(false); + ret = amd_pstate_cppc_enable(false); if (ret) pr_err("failed to disable amd-pstate during suspend, return %d\n", ret); @@ -1186,7 +1186,7 @@ static ssize_t show_energy_performance_preference( static void amd_pstate_driver_cleanup(void) { - amd_pstate_enable(false); + amd_pstate_cppc_enable(false); cppc_state = AMD_PSTATE_DISABLE; current_pstate_driver = NULL; } @@ -1220,7 +1220,7 @@ static int amd_pstate_register_driver(int mode) cppc_state = mode; - ret = amd_pstate_enable(true); + ret = amd_pstate_cppc_enable(true); if (ret) { pr_err("failed to enable cppc during amd-pstate driver registration, return %d\n", ret); @@ -1599,7 +1599,7 @@ static void amd_pstate_epp_reenable(struct amd_cpudata *cpudata) u64 value, max_perf; int ret; - ret = amd_pstate_enable(true); + ret = amd_pstate_cppc_enable(true); if (ret) pr_err("failed to enable amd pstate during resume, return %d\n", ret); @@ -1686,7 +1686,7 @@ static int amd_pstate_epp_suspend(struct cpufreq_policy *policy) cpudata->suspended = true; /* disable CPPC in lowlevel firmware */ - ret = amd_pstate_enable(false); + ret = amd_pstate_cppc_enable(false); if (ret) pr_err("failed to suspend, return %d\n", ret); @@ -1861,7 +1861,7 @@ static int __init amd_pstate_init(void) current_pstate_driver->adjust_perf = amd_pstate_adjust_perf; } else { pr_debug("AMD CPPC shared memory based functionality is supported\n"); - static_call_update(amd_pstate_enable, shmem_enable); + static_call_update(amd_pstate_cppc_enable, shmem_cppc_enable); static_call_update(amd_pstate_init_perf, shmem_init_perf); static_call_update(amd_pstate_update_perf, shmem_update_perf); } @@ -1886,7 +1886,7 @@ static int __init amd_pstate_init(void) global_attr_free: cpufreq_unregister_driver(current_pstate_driver); - amd_pstate_enable(false); + amd_pstate_cppc_enable(false); return ret; } device_initcall(amd_pstate_init); From 73070a9169b16e08b191066e513bce6c237c9221 Mon Sep 17 00:00:00 2001 From: Dhananjay Ugwekar Date: Wed, 23 Oct 2024 10:21:08 +0000 Subject: [PATCH 18/25] cpufreq/amd-pstate: Do not attempt to clear MSR_AMD_CPPC_ENABLE MSR_AMD_CPPC_ENABLE is a write once register, i.e. attempting to clear it is futile, it will not take effect. Hence, return if disable (0) argument is passed to the msr_cppc_enable() Signed-off-by: Dhananjay Ugwekar Reviewed-by: Mario Limonciello Reviewed-by: Gautham R. Shenoy Link: https://lore.kernel.org/r/20241023102108.5980-3-Dhananjay.Ugwekar@amd.com Signed-off-by: Mario Limonciello --- drivers/cpufreq/amd-pstate.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c index 0b4a4d69c14d..576251e61ce0 100644 --- a/drivers/cpufreq/amd-pstate.c +++ b/drivers/cpufreq/amd-pstate.c @@ -311,6 +311,12 @@ static inline int msr_cppc_enable(bool enable) int ret, cpu; unsigned long logical_proc_id_mask = 0; + /* + * MSR_AMD_CPPC_ENABLE is write-once, once set it cannot be cleared. + */ + if (!enable) + return 0; + if (enable == cppc_enabled) return 0; From 796ff50e127af8362035f87ba29b6b84e2dd9742 Mon Sep 17 00:00:00 2001 From: Dhananjay Ugwekar Date: Wed, 23 Oct 2024 10:21:10 +0000 Subject: [PATCH 19/25] cpufreq/amd-pstate: Call cppc_set_epp_perf in the reenable function The EPP value being set in perf_ctrls.energy_perf is not being propagated to the shared memory, fix that. Signed-off-by: Dhananjay Ugwekar Reviewed-by: Mario Limonciello Reviewed-by: Perry Yuan Reviewed-by: Gautham R. Shenoy Link: https://lore.kernel.org/r/20241023102108.5980-4-Dhananjay.Ugwekar@amd.com Signed-off-by: Mario Limonciello --- drivers/cpufreq/amd-pstate.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c index 576251e61ce0..bbeddce90823 100644 --- a/drivers/cpufreq/amd-pstate.c +++ b/drivers/cpufreq/amd-pstate.c @@ -1616,8 +1616,9 @@ static void amd_pstate_epp_reenable(struct amd_cpudata *cpudata) wrmsrl_on_cpu(cpudata->cpu, MSR_AMD_CPPC_REQ, value); } else { perf_ctrls.max_perf = max_perf; - perf_ctrls.energy_perf = AMD_CPPC_ENERGY_PERF_PREF(cpudata->epp_cached); cppc_set_perf(cpudata->cpu, &perf_ctrls); + perf_ctrls.energy_perf = AMD_CPPC_ENERGY_PERF_PREF(cpudata->epp_cached); + cppc_set_epp_perf(cpudata->cpu, &perf_ctrls, 1); } } @@ -1658,8 +1659,9 @@ static void amd_pstate_epp_offline(struct cpufreq_policy *policy) } else { perf_ctrls.desired_perf = 0; perf_ctrls.max_perf = min_perf; - perf_ctrls.energy_perf = AMD_CPPC_ENERGY_PERF_PREF(HWP_EPP_BALANCE_POWERSAVE); cppc_set_perf(cpudata->cpu, &perf_ctrls); + perf_ctrls.energy_perf = AMD_CPPC_ENERGY_PERF_PREF(HWP_EPP_BALANCE_POWERSAVE); + cppc_set_epp_perf(cpudata->cpu, &perf_ctrls, 1); } mutex_unlock(&amd_pstate_limits_lock); } From a6960e6b1b0e2cb268f427a99040c408a8d10665 Mon Sep 17 00:00:00 2001 From: Dhananjay Ugwekar Date: Wed, 23 Oct 2024 10:21:12 +0000 Subject: [PATCH 20/25] cpufreq/amd-pstate: Align offline flow of shared memory and MSR based systems Set min_perf to lowest_perf for shared memory systems, similar to the MSR based systems. Signed-off-by: Dhananjay Ugwekar Reviewed-by: Mario Limonciello Reviewed-by: Gautham R. Shenoy Link: https://lore.kernel.org/r/20241023102108.5980-5-Dhananjay.Ugwekar@amd.com Signed-off-by: Mario Limonciello --- drivers/cpufreq/amd-pstate.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c index bbeddce90823..206725219d8c 100644 --- a/drivers/cpufreq/amd-pstate.c +++ b/drivers/cpufreq/amd-pstate.c @@ -1658,6 +1658,7 @@ static void amd_pstate_epp_offline(struct cpufreq_policy *policy) wrmsrl_on_cpu(cpudata->cpu, MSR_AMD_CPPC_REQ, value); } else { perf_ctrls.desired_perf = 0; + perf_ctrls.min_perf = min_perf; perf_ctrls.max_perf = min_perf; cppc_set_perf(cpudata->cpu, &perf_ctrls); perf_ctrls.energy_perf = AMD_CPPC_ENERGY_PERF_PREF(HWP_EPP_BALANCE_POWERSAVE); From 3ac757e8db3deacc8058912d55efd1390f985d80 Mon Sep 17 00:00:00 2001 From: Mario Limonciello Date: Mon, 28 Oct 2024 09:55:41 -0500 Subject: [PATCH 21/25] cpufreq/amd-pstate: Push adjust_perf vfunc init into cpu_init As the driver can be changed in and out of different modes it's possible that adjust_perf is assigned when it shouldn't be. This could happen if an MSR design is started up in passive mode and then switches to active mode. To solve this explicitly clear `adjust_perf` in amd_pstate_epp_cpu_init(). Tested-by: Klara Modin Tested-by: Dhananjay Ugwekar Link: https://lore.kernel.org/r/20241028145542.1739160-1-superm1@kernel.org Signed-off-by: Mario Limonciello --- drivers/cpufreq/amd-pstate.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c index 206725219d8c..e480da818d6f 100644 --- a/drivers/cpufreq/amd-pstate.c +++ b/drivers/cpufreq/amd-pstate.c @@ -1504,6 +1504,8 @@ static int amd_pstate_epp_cpu_init(struct cpufreq_policy *policy) WRITE_ONCE(cpudata->cppc_cap1_cached, value); } + current_pstate_driver->adjust_perf = NULL; + return 0; free_cpudata1: @@ -1866,8 +1868,6 @@ static int __init amd_pstate_init(void) /* capability check */ if (cpu_feature_enabled(X86_FEATURE_CPPC)) { pr_debug("AMD CPPC MSR based functionality is supported\n"); - if (cppc_state != AMD_PSTATE_ACTIVE) - current_pstate_driver->adjust_perf = amd_pstate_adjust_perf; } else { pr_debug("AMD CPPC shared memory based functionality is supported\n"); static_call_update(amd_pstate_cppc_enable, shmem_cppc_enable); From ff2653ded4d99b709f62f35656d976c47a7aa476 Mon Sep 17 00:00:00 2001 From: Mario Limonciello Date: Mon, 28 Oct 2024 09:55:42 -0500 Subject: [PATCH 22/25] cpufreq/amd-pstate: Move registration after static function call update On shared memory designs the static functions need to work before registration is done or the system can hang at bootup. Move the registration later in amd_pstate_init() to solve this. Fixes: b427ac408475 ("cpufreq/amd-pstate: Remove the redundant amd_pstate_set_driver() call") Reported-by: Klara Modin Closes: https://lore.kernel.org/linux-pm/cf9c146d-bacf-444e-92e2-15ebf513af96@gmail.com/#t Tested-by: Klara Modin Tested-by: Dhananjay Ugwekar Link: https://lore.kernel.org/r/20241028145542.1739160-2-superm1@kernel.org Signed-off-by: Mario Limonciello --- drivers/cpufreq/amd-pstate.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c index e480da818d6f..f834cc8205e2 100644 --- a/drivers/cpufreq/amd-pstate.c +++ b/drivers/cpufreq/amd-pstate.c @@ -1859,12 +1859,6 @@ static int __init amd_pstate_init(void) return -ENODEV; } - ret = amd_pstate_register_driver(cppc_state); - if (ret) { - pr_err("failed to register with return %d\n", ret); - return ret; - } - /* capability check */ if (cpu_feature_enabled(X86_FEATURE_CPPC)) { pr_debug("AMD CPPC MSR based functionality is supported\n"); @@ -1875,6 +1869,12 @@ static int __init amd_pstate_init(void) static_call_update(amd_pstate_update_perf, shmem_update_perf); } + ret = amd_pstate_register_driver(cppc_state); + if (ret) { + pr_err("failed to register with return %d\n", ret); + return ret; + } + if (amd_pstate_prefcore) { ret = amd_detect_prefcore(&amd_pstate_prefcore); if (ret) From 70d8b6485b0bcd135b6699fc4252d2272818d1fb Mon Sep 17 00:00:00 2001 From: Christian Loehle Date: Sat, 9 Nov 2024 00:24:14 +0000 Subject: [PATCH 23/25] sched/cpufreq: Ensure sd is rebuilt for EAS check Ensure sugov_eas_rebuild_sd() is always called when sugov_init() succeeds. The out goto initialized sugov without forcing the rebuild. Previously the missing call to sugov_eas_rebuild_sd() could lead to EAS not being enabled on boot when it should have been, because it requires all policies to be controlled by schedutil while they might not have been initialized yet. Fixes: e7a1b32e43b1 ("cpufreq: Rebuild sched-domains when removing cpufreq driver") Signed-off-by: Christian Loehle Link: https://patch.msgid.link/35e572d9-1152-406a-9e34-2525f7548af9@arm.com Signed-off-by: Rafael J. Wysocki --- kernel/sched/cpufreq_schedutil.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/kernel/sched/cpufreq_schedutil.c b/kernel/sched/cpufreq_schedutil.c index c6ba15388ea7..28c77904ea74 100644 --- a/kernel/sched/cpufreq_schedutil.c +++ b/kernel/sched/cpufreq_schedutil.c @@ -783,9 +783,8 @@ static int sugov_init(struct cpufreq_policy *policy) if (ret) goto fail; - sugov_eas_rebuild_sd(); - out: + sugov_eas_rebuild_sd(); mutex_unlock(&global_tunables_lock); return 0; From b35ea78a4761b08b2695d98f240fec1f4e85092b Mon Sep 17 00:00:00 2001 From: "Chang S. Bae" Date: Wed, 6 Nov 2024 10:23:13 -0800 Subject: [PATCH 24/25] cpufreq: ACPI: Simplify MSR read on the boot CPU Replace the 32-bit MSR access function with a 64-bit variant to simplify the call site, eliminating unnecessary 32-bit value manipulations. Signed-off-by: Chang S. Bae Link: https://patch.msgid.link/20241106182313.165297-1-chang.seok.bae@intel.com [ rjw: Subject edit ] Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/acpi-cpufreq.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/cpufreq/acpi-cpufreq.c b/drivers/cpufreq/acpi-cpufreq.c index 433eb597c2b8..c9ebacf5c88e 100644 --- a/drivers/cpufreq/acpi-cpufreq.c +++ b/drivers/cpufreq/acpi-cpufreq.c @@ -73,20 +73,17 @@ static unsigned int acpi_pstate_strict; static bool boost_state(unsigned int cpu) { - u32 lo, hi; u64 msr; switch (boot_cpu_data.x86_vendor) { case X86_VENDOR_INTEL: case X86_VENDOR_CENTAUR: case X86_VENDOR_ZHAOXIN: - rdmsr_on_cpu(cpu, MSR_IA32_MISC_ENABLE, &lo, &hi); - msr = lo | ((u64)hi << 32); + rdmsrl_on_cpu(cpu, MSR_IA32_MISC_ENABLE, &msr); return !(msr & MSR_IA32_MISC_ENABLE_TURBO_DISABLE); case X86_VENDOR_HYGON: case X86_VENDOR_AMD: - rdmsr_on_cpu(cpu, MSR_K7_HWCR, &lo, &hi); - msr = lo | ((u64)hi << 32); + rdmsrl_on_cpu(cpu, MSR_K7_HWCR, &msr); return !(msr & MSR_K7_HWCR_CPB_DIS); } return false; From 00e2c199cb3780357790852502a74719d14554ec Mon Sep 17 00:00:00 2001 From: Srinivas Pandruvada Date: Tue, 12 Nov 2024 15:59:46 -0800 Subject: [PATCH 25/25] cpufreq: intel_pstate: Update Balance-performance EPP for Granite Rapids Update EPP default for balance_performance to 32. This will give better performance out of the box using Intel P-State powersave governor while still offering power savings compared to performance governor. This is in line with what has already been done for Emerald Rapids and Sapphire Rapids. Signed-off-by: Srinivas Pandruvada Link: https://patch.msgid.link/20241112235946.368082-1-srinivas.pandruvada@linux.intel.com [ rjw: Subject and changelog edits ] Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/intel_pstate.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c index cd2ac1ba53d2..f1db73a52bae 100644 --- a/drivers/cpufreq/intel_pstate.c +++ b/drivers/cpufreq/intel_pstate.c @@ -3658,6 +3658,8 @@ static const struct x86_cpu_id intel_epp_default[] = { X86_MATCH_VFM(INTEL_ALDERLAKE_L, HWP_SET_DEF_BALANCE_PERF_EPP(102)), X86_MATCH_VFM(INTEL_SAPPHIRERAPIDS_X, HWP_SET_DEF_BALANCE_PERF_EPP(32)), X86_MATCH_VFM(INTEL_EMERALDRAPIDS_X, HWP_SET_DEF_BALANCE_PERF_EPP(32)), + X86_MATCH_VFM(INTEL_GRANITERAPIDS_X, HWP_SET_DEF_BALANCE_PERF_EPP(32)), + X86_MATCH_VFM(INTEL_GRANITERAPIDS_D, HWP_SET_DEF_BALANCE_PERF_EPP(32)), X86_MATCH_VFM(INTEL_METEORLAKE_L, HWP_SET_EPP_VALUES(HWP_EPP_POWERSAVE, 179, 64, 16)), X86_MATCH_VFM(INTEL_ARROWLAKE, HWP_SET_EPP_VALUES(HWP_EPP_POWERSAVE,