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

Configure Feed

Select the types of activity you want to include in your feed.

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>

authored by

Shyam Sundar S K and committed by
Ilpo Järvinen
04199ef4 4389d380

+106 -12
+53 -5
drivers/platform/x86/amd/pmf/acpi.c
··· 320 320 return apmf_if_call_store_buffer(pdev, APMF_FUNC_SBIOS_REQUESTS, req, sizeof(*req)); 321 321 } 322 322 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 + 323 328 int apmf_get_sbios_requests(struct amd_pmf_dev *pdev, struct apmf_sbios_req *req) 324 329 { 325 330 return apmf_if_call_store_buffer(pdev, APMF_FUNC_SBIOS_REQUESTS, ··· 341 336 ret = apmf_get_sbios_requests_v2(pmf_dev, &pmf_dev->req); 342 337 if (ret) 343 338 dev_err(pmf_dev->dev, "Failed to get v2 SBIOS requests: %d\n", ret); 339 + } 340 + 341 + static void apmf_event_handler_v1(acpi_handle handle, u32 event, void *data) 342 + { 343 + struct amd_pmf_dev *pmf_dev = data; 344 + int ret; 345 + 346 + guard(mutex)(&pmf_dev->cb_mutex); 347 + 348 + ret = apmf_get_sbios_requests_v1(pmf_dev, &pmf_dev->req1); 349 + if (ret) 350 + dev_err(pmf_dev->dev, "Failed to get v1 SBIOS requests: %d\n", ret); 344 351 } 345 352 346 353 static void apmf_event_handler(acpi_handle handle, u32 event, void *data) ··· 444 427 return apmf_if_call_store_buffer(pdev, APMF_FUNC_DYN_SLIDER_DC, data, sizeof(*data)); 445 428 } 446 429 430 + static apmf_event_handler_t apmf_event_handlers[] = { 431 + [PMF_IF_V1] = apmf_event_handler_v1, 432 + [PMF_IF_V2] = apmf_event_handler_v2, 433 + }; 434 + 447 435 int apmf_install_handler(struct amd_pmf_dev *pmf_dev) 448 436 { 449 437 acpi_handle ahandle = ACPI_HANDLE(pmf_dev->dev); ··· 468 446 apmf_event_handler(ahandle, 0, pmf_dev); 469 447 } 470 448 471 - if (pmf_dev->smart_pc_enabled && pmf_dev->pmf_if_version == PMF_IF_V2) { 449 + if (!pmf_dev->smart_pc_enabled) 450 + return -EINVAL; 451 + 452 + switch (pmf_dev->pmf_if_version) { 453 + case PMF_IF_V1: 454 + if (!is_apmf_bios_input_notifications_supported(pmf_dev)) 455 + break; 456 + fallthrough; 457 + case PMF_IF_V2: 472 458 status = acpi_install_notify_handler(ahandle, ACPI_ALL_NOTIFY, 473 - apmf_event_handler_v2, pmf_dev); 459 + apmf_event_handlers[pmf_dev->pmf_if_version], pmf_dev); 474 460 if (ACPI_FAILURE(status)) { 475 - dev_err(pmf_dev->dev, "failed to install notify handler for custom BIOS inputs\n"); 461 + dev_err(pmf_dev->dev, 462 + "failed to install notify handler v%d for custom BIOS inputs\n", 463 + pmf_dev->pmf_if_version); 476 464 return -ENODEV; 477 465 } 466 + break; 467 + default: 468 + break; 478 469 } 479 470 480 471 return 0; ··· 541 506 is_apmf_func_supported(pmf_dev, APMF_FUNC_SBIOS_REQUESTS)) 542 507 acpi_remove_notify_handler(ahandle, ACPI_ALL_NOTIFY, apmf_event_handler); 543 508 544 - if (pmf_dev->smart_pc_enabled && pmf_dev->pmf_if_version == PMF_IF_V2) 545 - acpi_remove_notify_handler(ahandle, ACPI_ALL_NOTIFY, apmf_event_handler_v2); 509 + if (!pmf_dev->smart_pc_enabled) 510 + return; 511 + 512 + switch (pmf_dev->pmf_if_version) { 513 + case PMF_IF_V1: 514 + if (!is_apmf_bios_input_notifications_supported(pmf_dev)) 515 + break; 516 + fallthrough; 517 + case PMF_IF_V2: 518 + acpi_remove_notify_handler(ahandle, ACPI_ALL_NOTIFY, 519 + apmf_event_handlers[pmf_dev->pmf_if_version]); 520 + break; 521 + default: 522 + break; 523 + } 546 524 } 547 525 548 526 int apmf_acpi_init(struct amd_pmf_dev *pmf_dev)
+22
drivers/platform/x86/amd/pmf/pmf.h
··· 120 120 #define APTS_MAX_STATES 16 121 121 #define CUSTOM_BIOS_INPUT_BITS GENMASK(16, 7) 122 122 123 + typedef void (*apmf_event_handler_t)(acpi_handle handle, u32 event, void *data); 124 + 123 125 /* APTS PMF BIOS Interface */ 124 126 struct amd_pmf_apts_output { 125 127 u16 table_version; ··· 187 185 u32 stt_min_limit; 188 186 u8 skin_temp_apu; 189 187 u8 skin_temp_hs2; 188 + } __packed; 189 + 190 + /* As per APMF spec 1.3 */ 191 + struct apmf_sbios_req_v1 { 192 + u16 size; 193 + u32 pending_req; 194 + u8 rsvd; 195 + u8 cql_event; 196 + u8 amt_event; 197 + u32 fppt; 198 + u32 sppt; 199 + u32 sppt_apu_only; 200 + u32 spl; 201 + u32 stt_min_limit; 202 + u8 skin_temp_apu; 203 + u8 skin_temp_hs2; 204 + u8 enable_cnqf; 205 + u32 custom_policy[10]; 190 206 } __packed; 191 207 192 208 struct apmf_sbios_req_v2 { ··· 399 379 struct apmf_sbios_req_v2 req; /* To get custom bios pending request */ 400 380 struct mutex cb_mutex; 401 381 u32 notifications; 382 + struct apmf_sbios_req_v1 req1; 402 383 }; 403 384 404 385 struct apmf_sps_prop_granular_v2 { ··· 856 835 void amd_pmf_deinit_auto_mode(struct amd_pmf_dev *dev); 857 836 void amd_pmf_trans_automode(struct amd_pmf_dev *dev, int socket_power, ktime_t time_elapsed_ms); 858 837 int apmf_get_sbios_requests(struct amd_pmf_dev *pdev, struct apmf_sbios_req *req); 838 + int apmf_get_sbios_requests_v1(struct amd_pmf_dev *pdev, struct apmf_sbios_req_v1 *req); 859 839 int apmf_get_sbios_requests_v2(struct amd_pmf_dev *pdev, struct apmf_sbios_req_v2 *req); 860 840 861 841 void amd_pmf_update_2_cql(struct amd_pmf_dev *dev, bool is_cql_event);
+31 -7
drivers/platform/x86/amd/pmf/spc.c
··· 132 132 } 133 133 } 134 134 135 - static void amd_pmf_get_custom_bios_inputs(struct amd_pmf_dev *pdev, 136 - struct ta_pmf_enact_table *in) 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) 137 138 { 138 139 unsigned int i; 139 140 140 - if (!pdev->req.pending_req) 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 + 148 + static void amd_pmf_get_custom_bios_inputs(struct amd_pmf_dev *pdev, 149 + struct ta_pmf_enact_table *in) 150 + { 151 + if (!(pdev->req.pending_req || pdev->req1.pending_req)) 141 152 return; 142 153 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]); 154 + if (!pdev->smart_pc_enabled) 155 + return; 156 + 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; 147 170 } 148 171 149 172 /* Clear pending requests after handling */ 150 173 memset(&pdev->req, 0, sizeof(pdev->req)); 174 + memset(&pdev->req1, 0, sizeof(pdev->req1)); 151 175 } 152 176 153 177 static void amd_pmf_get_c0_residency(u16 *core_res, size_t size, struct ta_pmf_enact_table *in)