@@ -444,9 +444,8 @@ static int amd_pstate_verify(struct cpufreq_policy_data *policy)
444
444
return 0 ;
445
445
}
446
446
447
- static int amd_pstate_target (struct cpufreq_policy * policy ,
448
- unsigned int target_freq ,
449
- unsigned int relation )
447
+ static int amd_pstate_update_freq (struct cpufreq_policy * policy ,
448
+ unsigned int target_freq , bool fast_switch )
450
449
{
451
450
struct cpufreq_freqs freqs ;
452
451
struct amd_cpudata * cpudata = policy -> driver_data ;
@@ -465,26 +464,51 @@ static int amd_pstate_target(struct cpufreq_policy *policy,
465
464
des_perf = DIV_ROUND_CLOSEST (target_freq * cap_perf ,
466
465
cpudata -> max_freq );
467
466
468
- cpufreq_freq_transition_begin (policy , & freqs );
467
+ WARN_ON (fast_switch && !policy -> fast_switch_enabled );
468
+ /*
469
+ * If fast_switch is desired, then there aren't any registered
470
+ * transition notifiers. See comment for
471
+ * cpufreq_enable_fast_switch().
472
+ */
473
+ if (!fast_switch )
474
+ cpufreq_freq_transition_begin (policy , & freqs );
475
+
469
476
amd_pstate_update (cpudata , min_perf , des_perf ,
470
- max_perf , false, policy -> governor -> flags );
471
- cpufreq_freq_transition_end (policy , & freqs , false);
477
+ max_perf , fast_switch , policy -> governor -> flags );
478
+
479
+ if (!fast_switch )
480
+ cpufreq_freq_transition_end (policy , & freqs , false);
472
481
473
482
return 0 ;
474
483
}
475
484
485
+ static int amd_pstate_target (struct cpufreq_policy * policy ,
486
+ unsigned int target_freq ,
487
+ unsigned int relation )
488
+ {
489
+ return amd_pstate_update_freq (policy , target_freq , false);
490
+ }
491
+
492
+ static unsigned int amd_pstate_fast_switch (struct cpufreq_policy * policy ,
493
+ unsigned int target_freq )
494
+ {
495
+ return amd_pstate_update_freq (policy , target_freq , true);
496
+ }
497
+
476
498
static void amd_pstate_adjust_perf (unsigned int cpu ,
477
499
unsigned long _min_perf ,
478
500
unsigned long target_perf ,
479
501
unsigned long capacity )
480
502
{
481
503
unsigned long max_perf , min_perf , des_perf ,
482
- cap_perf , lowest_nonlinear_perf ;
504
+ cap_perf , lowest_nonlinear_perf , max_freq ;
483
505
struct cpufreq_policy * policy = cpufreq_cpu_get (cpu );
484
506
struct amd_cpudata * cpudata = policy -> driver_data ;
507
+ unsigned int target_freq ;
485
508
486
509
cap_perf = READ_ONCE (cpudata -> highest_perf );
487
510
lowest_nonlinear_perf = READ_ONCE (cpudata -> lowest_nonlinear_perf );
511
+ max_freq = READ_ONCE (cpudata -> max_freq );
488
512
489
513
des_perf = cap_perf ;
490
514
if (target_perf < capacity )
@@ -501,6 +525,10 @@ static void amd_pstate_adjust_perf(unsigned int cpu,
501
525
if (max_perf < min_perf )
502
526
max_perf = min_perf ;
503
527
528
+ des_perf = clamp_t (unsigned long , des_perf , min_perf , max_perf );
529
+ target_freq = div_u64 (des_perf * max_freq , max_perf );
530
+ policy -> cur = target_freq ;
531
+
504
532
amd_pstate_update (cpudata , min_perf , des_perf , max_perf , true,
505
533
policy -> governor -> flags );
506
534
cpufreq_cpu_put (policy );
@@ -715,6 +743,7 @@ static int amd_pstate_cpu_exit(struct cpufreq_policy *policy)
715
743
716
744
freq_qos_remove_request (& cpudata -> req [1 ]);
717
745
freq_qos_remove_request (& cpudata -> req [0 ]);
746
+ policy -> fast_switch_possible = false;
718
747
kfree (cpudata );
719
748
720
749
return 0 ;
@@ -1079,7 +1108,6 @@ static int amd_pstate_epp_cpu_init(struct cpufreq_policy *policy)
1079
1108
policy -> policy = CPUFREQ_POLICY_POWERSAVE ;
1080
1109
1081
1110
if (boot_cpu_has (X86_FEATURE_CPPC )) {
1082
- policy -> fast_switch_possible = true;
1083
1111
ret = rdmsrl_on_cpu (cpudata -> cpu , MSR_AMD_CPPC_REQ , & value );
1084
1112
if (ret )
1085
1113
return ret ;
@@ -1102,7 +1130,6 @@ static int amd_pstate_epp_cpu_init(struct cpufreq_policy *policy)
1102
1130
static int amd_pstate_epp_cpu_exit (struct cpufreq_policy * policy )
1103
1131
{
1104
1132
pr_debug ("CPU %d exiting\n" , policy -> cpu );
1105
- policy -> fast_switch_possible = false;
1106
1133
return 0 ;
1107
1134
}
1108
1135
@@ -1309,6 +1336,7 @@ static struct cpufreq_driver amd_pstate_driver = {
1309
1336
.flags = CPUFREQ_CONST_LOOPS | CPUFREQ_NEED_UPDATE_LIMITS ,
1310
1337
.verify = amd_pstate_verify ,
1311
1338
.target = amd_pstate_target ,
1339
+ .fast_switch = amd_pstate_fast_switch ,
1312
1340
.init = amd_pstate_cpu_init ,
1313
1341
.exit = amd_pstate_cpu_exit ,
1314
1342
.suspend = amd_pstate_cpu_suspend ,
0 commit comments