[PATCH] ACPI: CPPC: Don't gate FFH EPP writes on flexible address space _OSC
Mario Limonciello <[email protected]>
| Newsgroups | org.kernel.vger.linux-acpi |
|---|---|
| Message-ID | <[email protected]> |
cppc_set_epp_perf() requires osc_cpc_flexible_adr_space_confirmed before
writing the EPP and autonomous-selection registers, even when they live
in FFH. FFH access is a direct rdmsr/wrmsr and does not depend on that
_OSC bit, which only governs CPPC controls in SystemMemory/SystemIO.
As a result amd-pstate active mode fails to initialize on platforms whose
firmware does not ack CPPC in _OSC but whose EPP register is a working FFH
MSR. On an HP 255 G8 (Ryzen 5 5500U) reads succeed via the _CPC parse
path's cpc_supported_by_cpu() fallback, but the EPP write is rejected:
amd_pstate: failed to set energy perf value (-524)
amd_pstate: failed to register with return -19
Gate only SystemMemory on osc_cpc_flexible_adr_space_confirmed and allow
FFH unconditionally, matching the _CPC parse path and cpc_ffh_supported().
Fixes: aaf21ac93909 ("ACPI: CPPC: Add support for setting EPP register in FFH")
Reported-by: Giusy <[email protected]>
Closes: https://lore.kernel.org/linux-pm/[email protected]/
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Mario Limonciello <[email protected]>
---
drivers/acpi/cppc_acpi.c | 15 +++++++++++----
1 file changed, 11 insertions(+), 4 deletions(-)
diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c
index fef54fcd00b78..6b590842b5668 100644
--- a/drivers/acpi/cppc_acpi.c
+++ b/drivers/acpi/cppc_acpi.c
@@ -1766,10 +1766,18 @@ int cppc_set_epp_perf(int cpu, struct cppc_perf_ctrls *perf_ctrls, bool enable)
auto_sel_reg = &cpc_desc->cpc_regs[AUTO_SEL_ENABLE];
epp_set_reg = &cpc_desc->cpc_regs[ENERGY_PERF];
+ /*
+ * The flexible address space _OSC ack is only needed for
+ * SystemMemory/SystemIO; FFH is accessed directly and always available.
+ */
epp_ffh_sysmem = CPC_SUPPORTED(epp_set_reg) &&
- (CPC_IN_FFH(epp_set_reg) || CPC_IN_SYSTEM_MEMORY(epp_set_reg));
+ (CPC_IN_FFH(epp_set_reg) ||
+ (CPC_IN_SYSTEM_MEMORY(epp_set_reg) &&
+ osc_cpc_flexible_adr_space_confirmed));
autosel_ffh_sysmem = CPC_SUPPORTED(auto_sel_reg) &&
- (CPC_IN_FFH(auto_sel_reg) || CPC_IN_SYSTEM_MEMORY(auto_sel_reg));
+ (CPC_IN_FFH(auto_sel_reg) ||
+ (CPC_IN_SYSTEM_MEMORY(auto_sel_reg) &&
+ osc_cpc_flexible_adr_space_confirmed));
if (CPC_IN_PCC(epp_set_reg) || CPC_IN_PCC(auto_sel_reg)) {
if (pcc_ss_id < 0) {
@@ -1795,8 +1803,7 @@ int cppc_set_epp_perf(int cpu, struct cppc_perf_ctrls *perf_ctrls, bool enable)
/* after writing CPC, transfer the ownership of PCC to platform */
ret = send_pcc_cmd(pcc_ss_id, CMD_WRITE);
up_write(&pcc_ss_data->pcc_lock);
- } else if (osc_cpc_flexible_adr_space_confirmed &&
- (epp_ffh_sysmem || autosel_ffh_sysmem)) {
+ } else if (epp_ffh_sysmem || autosel_ffh_sysmem) {
if (autosel_ffh_sysmem) {
ret = cpc_write(cpu, auto_sel_reg, enable);
if (ret)
--
2.43.0