@@ -444,9 +444,8 @@ static int amd_pstate_verify(struct cpufreq_policy_data *policy)
444444 return 0 ;
445445}
446446
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 )
450449{
451450 struct cpufreq_freqs freqs ;
452451 struct amd_cpudata * cpudata = policy -> driver_data ;
@@ -465,26 +464,51 @@ static int amd_pstate_target(struct cpufreq_policy *policy,
465464 des_perf = DIV_ROUND_CLOSEST (target_freq * cap_perf ,
466465 cpudata -> max_freq );
467466
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+
469476 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);
472481
473482 return 0 ;
474483}
475484
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+
476498static void amd_pstate_adjust_perf (unsigned int cpu ,
477499 unsigned long _min_perf ,
478500 unsigned long target_perf ,
479501 unsigned long capacity )
480502{
481503 unsigned long max_perf , min_perf , des_perf ,
482- cap_perf , lowest_nonlinear_perf ;
504+ cap_perf , lowest_nonlinear_perf , max_freq ;
483505 struct cpufreq_policy * policy = cpufreq_cpu_get (cpu );
484506 struct amd_cpudata * cpudata = policy -> driver_data ;
507+ unsigned int target_freq ;
485508
486509 cap_perf = READ_ONCE (cpudata -> highest_perf );
487510 lowest_nonlinear_perf = READ_ONCE (cpudata -> lowest_nonlinear_perf );
511+ max_freq = READ_ONCE (cpudata -> max_freq );
488512
489513 des_perf = cap_perf ;
490514 if (target_perf < capacity )
@@ -501,6 +525,10 @@ static void amd_pstate_adjust_perf(unsigned int cpu,
501525 if (max_perf < min_perf )
502526 max_perf = min_perf ;
503527
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+
504532 amd_pstate_update (cpudata , min_perf , des_perf , max_perf , true,
505533 policy -> governor -> flags );
506534 cpufreq_cpu_put (policy );
@@ -715,6 +743,7 @@ static int amd_pstate_cpu_exit(struct cpufreq_policy *policy)
715743
716744 freq_qos_remove_request (& cpudata -> req [1 ]);
717745 freq_qos_remove_request (& cpudata -> req [0 ]);
746+ policy -> fast_switch_possible = false;
718747 kfree (cpudata );
719748
720749 return 0 ;
@@ -1079,7 +1108,6 @@ static int amd_pstate_epp_cpu_init(struct cpufreq_policy *policy)
10791108 policy -> policy = CPUFREQ_POLICY_POWERSAVE ;
10801109
10811110 if (boot_cpu_has (X86_FEATURE_CPPC )) {
1082- policy -> fast_switch_possible = true;
10831111 ret = rdmsrl_on_cpu (cpudata -> cpu , MSR_AMD_CPPC_REQ , & value );
10841112 if (ret )
10851113 return ret ;
@@ -1102,7 +1130,6 @@ static int amd_pstate_epp_cpu_init(struct cpufreq_policy *policy)
11021130static int amd_pstate_epp_cpu_exit (struct cpufreq_policy * policy )
11031131{
11041132 pr_debug ("CPU %d exiting\n" , policy -> cpu );
1105- policy -> fast_switch_possible = false;
11061133 return 0 ;
11071134}
11081135
@@ -1309,6 +1336,7 @@ static struct cpufreq_driver amd_pstate_driver = {
13091336 .flags = CPUFREQ_CONST_LOOPS | CPUFREQ_NEED_UPDATE_LIMITS ,
13101337 .verify = amd_pstate_verify ,
13111338 .target = amd_pstate_target ,
1339+ .fast_switch = amd_pstate_fast_switch ,
13121340 .init = amd_pstate_cpu_init ,
13131341 .exit = amd_pstate_cpu_exit ,
13141342 .suspend = amd_pstate_cpu_suspend ,
0 commit comments