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

cpufreq: amd-pstate: Add boost mode support for AMD P-State

If the sbios supports the boost mode of AMD P-State, let's switch to
boost enabled by default.

Signed-off-by: Huang Rui <ray.huang@amd.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>

authored by

Huang Rui and committed by
Rafael J. Wysocki
41271016 60e10f89

+66 -3
+66 -3
drivers/cpufreq/amd-pstate.c
··· 87 87 struct amd_cpudata { 88 88 int cpu; 89 89 90 + struct freq_qos_request req[2]; 90 91 u64 cppc_req_cached; 91 92 92 93 u32 highest_perf; ··· 99 98 u32 min_freq; 100 99 u32 nominal_freq; 101 100 u32 lowest_nonlinear_freq; 101 + 102 + bool boost_supported; 102 103 }; 103 104 104 105 static inline int pstate_enable(bool enable) ··· 377 374 return lowest_nonlinear_freq * 1000; 378 375 } 379 376 377 + static int amd_pstate_set_boost(struct cpufreq_policy *policy, int state) 378 + { 379 + struct amd_cpudata *cpudata = policy->driver_data; 380 + int ret; 381 + 382 + if (!cpudata->boost_supported) { 383 + pr_err("Boost mode is not supported by this processor or SBIOS\n"); 384 + return -EINVAL; 385 + } 386 + 387 + if (state) 388 + policy->cpuinfo.max_freq = cpudata->max_freq; 389 + else 390 + policy->cpuinfo.max_freq = cpudata->nominal_freq; 391 + 392 + policy->max = policy->cpuinfo.max_freq; 393 + 394 + ret = freq_qos_update_request(&cpudata->req[1], 395 + policy->cpuinfo.max_freq); 396 + if (ret < 0) 397 + return ret; 398 + 399 + return 0; 400 + } 401 + 402 + static void amd_pstate_boost_init(struct amd_cpudata *cpudata) 403 + { 404 + u32 highest_perf, nominal_perf; 405 + 406 + highest_perf = READ_ONCE(cpudata->highest_perf); 407 + nominal_perf = READ_ONCE(cpudata->nominal_perf); 408 + 409 + if (highest_perf <= nominal_perf) 410 + return; 411 + 412 + cpudata->boost_supported = true; 413 + amd_pstate_driver.boost_enabled = true; 414 + } 415 + 380 416 static int amd_pstate_cpu_init(struct cpufreq_policy *policy) 381 417 { 382 418 int min_freq, max_freq, nominal_freq, lowest_nonlinear_freq, ret; ··· 434 392 435 393 ret = amd_pstate_init_perf(cpudata); 436 394 if (ret) 437 - goto free_cpudata; 395 + goto free_cpudata1; 438 396 439 397 min_freq = amd_get_min_freq(cpudata); 440 398 max_freq = amd_get_max_freq(cpudata); ··· 445 403 dev_err(dev, "min_freq(%d) or max_freq(%d) value is incorrect\n", 446 404 min_freq, max_freq); 447 405 ret = -EINVAL; 448 - goto free_cpudata; 406 + goto free_cpudata1; 449 407 } 450 408 451 409 policy->cpuinfo.transition_latency = AMD_PSTATE_TRANSITION_LATENCY; ··· 463 421 if (boot_cpu_has(X86_FEATURE_CPPC)) 464 422 policy->fast_switch_possible = true; 465 423 424 + ret = freq_qos_add_request(&policy->constraints, &cpudata->req[0], 425 + FREQ_QOS_MIN, policy->cpuinfo.min_freq); 426 + if (ret < 0) { 427 + dev_err(dev, "Failed to add min-freq constraint (%d)\n", ret); 428 + goto free_cpudata1; 429 + } 430 + 431 + ret = freq_qos_add_request(&policy->constraints, &cpudata->req[1], 432 + FREQ_QOS_MAX, policy->cpuinfo.max_freq); 433 + if (ret < 0) { 434 + dev_err(dev, "Failed to add max-freq constraint (%d)\n", ret); 435 + goto free_cpudata2; 436 + } 437 + 466 438 /* Initial processor data capability frequencies */ 467 439 cpudata->max_freq = max_freq; 468 440 cpudata->min_freq = min_freq; ··· 485 429 486 430 policy->driver_data = cpudata; 487 431 432 + amd_pstate_boost_init(cpudata); 433 + 488 434 return 0; 489 435 490 - free_cpudata: 436 + free_cpudata2: 437 + freq_qos_remove_request(&cpudata->req[0]); 438 + free_cpudata1: 491 439 kfree(cpudata); 492 440 return ret; 493 441 } ··· 502 442 503 443 cpudata = policy->driver_data; 504 444 445 + freq_qos_remove_request(&cpudata->req[1]); 446 + freq_qos_remove_request(&cpudata->req[0]); 505 447 kfree(cpudata); 506 448 507 449 return 0; ··· 515 453 .target = amd_pstate_target, 516 454 .init = amd_pstate_cpu_init, 517 455 .exit = amd_pstate_cpu_exit, 456 + .set_boost = amd_pstate_set_boost, 518 457 .name = "amd-pstate", 519 458 }; 520 459