Skip to content

Commit 1f68682

Browse files
committed
platform/x86/amd/pmf: Add custom BIOS input support for AMD_CPU_ID_PS
JIRA: https://issues.redhat.com/browse/RHEL-73301 commit 04199ef Author: Shyam Sundar S K <Shyam-sundar.S-k@amd.com> Date: Mon Sep 1 16:31:37 2025 +0530 platform/x86/amd/pmf: Add custom BIOS input support for AMD_CPU_ID_PS The PMF ACPI Specification (APMF) has been revised to version 1.3 to allow for additional custom BIOS inputs, enabling OEMs to have more precise thermal management of the system. This update includes adding support to the driver using the new data structure received from the BIOS through the existing APMF interfaces. Co-developed-by: Patil Rajesh Reddy <Patil.Reddy@amd.com> Signed-off-by: Patil Rajesh Reddy <Patil.Reddy@amd.com> Tested-by: Yijun Shen <Yijun.Shen@Dell.com> Signed-off-by: Shyam Sundar S K <Shyam-sundar.S-k@amd.com> Link: https://patch.msgid.link/20250901110140.2519072-7-Shyam-sundar.S-k@amd.com Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com> Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com> Signed-off-by: Steve Best <sbest@redhat.com>
1 parent 6a8aaca commit 1f68682

File tree

3 files changed

+105
-11
lines changed

3 files changed

+105
-11
lines changed

drivers/platform/x86/amd/pmf/acpi.c

Lines changed: 53 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,11 @@ int apmf_get_sbios_requests_v2(struct amd_pmf_dev *pdev, struct apmf_sbios_req_v
320320
return apmf_if_call_store_buffer(pdev, APMF_FUNC_SBIOS_REQUESTS, req, sizeof(*req));
321321
}
322322

323+
int apmf_get_sbios_requests_v1(struct amd_pmf_dev *pdev, struct apmf_sbios_req_v1 *req)
324+
{
325+
return apmf_if_call_store_buffer(pdev, APMF_FUNC_SBIOS_REQUESTS, req, sizeof(*req));
326+
}
327+
323328
int apmf_get_sbios_requests(struct amd_pmf_dev *pdev, struct apmf_sbios_req *req)
324329
{
325330
return apmf_if_call_store_buffer(pdev, APMF_FUNC_SBIOS_REQUESTS,
@@ -338,6 +343,18 @@ static void apmf_event_handler_v2(acpi_handle handle, u32 event, void *data)
338343
dev_err(pmf_dev->dev, "Failed to get v2 SBIOS requests: %d\n", ret);
339344
}
340345

346+
static void apmf_event_handler_v1(acpi_handle handle, u32 event, void *data)
347+
{
348+
struct amd_pmf_dev *pmf_dev = data;
349+
int ret;
350+
351+
guard(mutex)(&pmf_dev->cb_mutex);
352+
353+
ret = apmf_get_sbios_requests_v1(pmf_dev, &pmf_dev->req1);
354+
if (ret)
355+
dev_err(pmf_dev->dev, "Failed to get v1 SBIOS requests: %d\n", ret);
356+
}
357+
341358
static void apmf_event_handler(acpi_handle handle, u32 event, void *data)
342359
{
343360
struct amd_pmf_dev *pmf_dev = data;
@@ -427,6 +444,11 @@ int apmf_get_dyn_slider_def_dc(struct amd_pmf_dev *pdev, struct apmf_dyn_slider_
427444
return apmf_if_call_store_buffer(pdev, APMF_FUNC_DYN_SLIDER_DC, data, sizeof(*data));
428445
}
429446

447+
static apmf_event_handler_t apmf_event_handlers[] = {
448+
[PMF_IF_V1] = apmf_event_handler_v1,
449+
[PMF_IF_V2] = apmf_event_handler_v2,
450+
};
451+
430452
int apmf_install_handler(struct amd_pmf_dev *pmf_dev)
431453
{
432454
acpi_handle ahandle = ACPI_HANDLE(pmf_dev->dev);
@@ -446,13 +468,26 @@ int apmf_install_handler(struct amd_pmf_dev *pmf_dev)
446468
apmf_event_handler(ahandle, 0, pmf_dev);
447469
}
448470

449-
if (pmf_dev->smart_pc_enabled && pmf_dev->pmf_if_version == PMF_IF_V2) {
471+
if (!pmf_dev->smart_pc_enabled)
472+
return -EINVAL;
473+
474+
switch (pmf_dev->pmf_if_version) {
475+
case PMF_IF_V1:
476+
if (!is_apmf_bios_input_notifications_supported(pmf_dev))
477+
break;
478+
fallthrough;
479+
case PMF_IF_V2:
450480
status = acpi_install_notify_handler(ahandle, ACPI_ALL_NOTIFY,
451-
apmf_event_handler_v2, pmf_dev);
481+
apmf_event_handlers[pmf_dev->pmf_if_version], pmf_dev);
452482
if (ACPI_FAILURE(status)) {
453-
dev_err(pmf_dev->dev, "failed to install notify handler for custom BIOS inputs\n");
483+
dev_err(pmf_dev->dev,
484+
"failed to install notify handler v%d for custom BIOS inputs\n",
485+
pmf_dev->pmf_if_version);
454486
return -ENODEV;
455487
}
488+
break;
489+
default:
490+
break;
456491
}
457492

458493
return 0;
@@ -506,8 +541,21 @@ void apmf_acpi_deinit(struct amd_pmf_dev *pmf_dev)
506541
is_apmf_func_supported(pmf_dev, APMF_FUNC_SBIOS_REQUESTS))
507542
acpi_remove_notify_handler(ahandle, ACPI_ALL_NOTIFY, apmf_event_handler);
508543

509-
if (pmf_dev->smart_pc_enabled && pmf_dev->pmf_if_version == PMF_IF_V2)
510-
acpi_remove_notify_handler(ahandle, ACPI_ALL_NOTIFY, apmf_event_handler_v2);
544+
if (!pmf_dev->smart_pc_enabled)
545+
return;
546+
547+
switch (pmf_dev->pmf_if_version) {
548+
case PMF_IF_V1:
549+
if (!is_apmf_bios_input_notifications_supported(pmf_dev))
550+
break;
551+
fallthrough;
552+
case PMF_IF_V2:
553+
acpi_remove_notify_handler(ahandle, ACPI_ALL_NOTIFY,
554+
apmf_event_handlers[pmf_dev->pmf_if_version]);
555+
break;
556+
default:
557+
break;
558+
}
511559
}
512560

513561
int apmf_acpi_init(struct amd_pmf_dev *pmf_dev)

drivers/platform/x86/amd/pmf/pmf.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,8 @@ struct cookie_header {
120120
#define APTS_MAX_STATES 16
121121
#define CUSTOM_BIOS_INPUT_BITS GENMASK(16, 7)
122122

123+
typedef void (*apmf_event_handler_t)(acpi_handle handle, u32 event, void *data);
124+
123125
/* APTS PMF BIOS Interface */
124126
struct amd_pmf_apts_output {
125127
u16 table_version;
@@ -187,6 +189,24 @@ struct apmf_sbios_req {
187189
u8 skin_temp_hs2;
188190
} __packed;
189191

192+
/* As per APMF spec 1.3 */
193+
struct apmf_sbios_req_v1 {
194+
u16 size;
195+
u32 pending_req;
196+
u8 rsvd;
197+
u8 cql_event;
198+
u8 amt_event;
199+
u32 fppt;
200+
u32 sppt;
201+
u32 sppt_apu_only;
202+
u32 spl;
203+
u32 stt_min_limit;
204+
u8 skin_temp_apu;
205+
u8 skin_temp_hs2;
206+
u8 enable_cnqf;
207+
u32 custom_policy[10];
208+
} __packed;
209+
190210
struct apmf_sbios_req_v2 {
191211
u16 size;
192212
u32 pending_req;
@@ -379,6 +399,7 @@ struct amd_pmf_dev {
379399
struct apmf_sbios_req_v2 req; /* To get custom bios pending request */
380400
struct mutex cb_mutex;
381401
u32 notifications;
402+
struct apmf_sbios_req_v1 req1;
382403
};
383404

384405
struct apmf_sps_prop_granular_v2 {
@@ -835,6 +856,7 @@ void amd_pmf_init_auto_mode(struct amd_pmf_dev *dev);
835856
void amd_pmf_deinit_auto_mode(struct amd_pmf_dev *dev);
836857
void amd_pmf_trans_automode(struct amd_pmf_dev *dev, int socket_power, ktime_t time_elapsed_ms);
837858
int apmf_get_sbios_requests(struct amd_pmf_dev *pdev, struct apmf_sbios_req *req);
859+
int apmf_get_sbios_requests_v1(struct amd_pmf_dev *pdev, struct apmf_sbios_req_v1 *req);
838860
int apmf_get_sbios_requests_v2(struct amd_pmf_dev *pdev, struct apmf_sbios_req_v2 *req);
839861

840862
void amd_pmf_update_2_cql(struct amd_pmf_dev *dev, bool is_cql_event);

drivers/platform/x86/amd/pmf/spc.c

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -132,22 +132,46 @@ static void amd_pmf_set_ta_custom_bios_input(struct ta_pmf_enact_table *in, int
132132
}
133133
}
134134

135+
static void amd_pmf_update_bios_inputs(struct amd_pmf_dev *pdev, u32 pending_req,
136+
const struct amd_pmf_pb_bitmap *inputs,
137+
const u32 *custom_policy, struct ta_pmf_enact_table *in)
138+
{
139+
unsigned int i;
140+
141+
for (i = 0; i < ARRAY_SIZE(custom_bios_inputs); i++) {
142+
if (!(pending_req & inputs[i].bit_mask))
143+
continue;
144+
amd_pmf_set_ta_custom_bios_input(in, i, custom_policy[i]);
145+
}
146+
}
147+
135148
static void amd_pmf_get_custom_bios_inputs(struct amd_pmf_dev *pdev,
136149
struct ta_pmf_enact_table *in)
137150
{
138-
unsigned int i;
151+
if (!(pdev->req.pending_req || pdev->req1.pending_req))
152+
return;
139153

140-
if (!pdev->req.pending_req)
154+
if (!pdev->smart_pc_enabled)
141155
return;
142156

143-
for (i = 0; i < ARRAY_SIZE(custom_bios_inputs); i++) {
144-
if (!(pdev->req.pending_req & custom_bios_inputs[i].bit_mask))
145-
continue;
146-
amd_pmf_set_ta_custom_bios_input(in, i, pdev->req.custom_policy[i]);
157+
switch (pdev->pmf_if_version) {
158+
case PMF_IF_V1:
159+
if (!is_apmf_bios_input_notifications_supported(pdev))
160+
return;
161+
amd_pmf_update_bios_inputs(pdev, pdev->req1.pending_req, custom_bios_inputs_v1,
162+
pdev->req1.custom_policy, in);
163+
break;
164+
case PMF_IF_V2:
165+
amd_pmf_update_bios_inputs(pdev, pdev->req.pending_req, custom_bios_inputs,
166+
pdev->req.custom_policy, in);
167+
break;
168+
default:
169+
break;
147170
}
148171

149172
/* Clear pending requests after handling */
150173
memset(&pdev->req, 0, sizeof(pdev->req));
174+
memset(&pdev->req1, 0, sizeof(pdev->req1));
151175
}
152176

153177
static void amd_pmf_get_c0_residency(u16 *core_res, size_t size, struct ta_pmf_enact_table *in)

0 commit comments

Comments
 (0)