@@ -389,7 +389,8 @@ static inline int amd_pstate_cppc_enable(struct cpufreq_policy *policy)
389389static int msr_init_perf (struct amd_cpudata * cpudata )
390390{
391391 union perf_cached perf = READ_ONCE (cpudata -> perf );
392- u64 cap1 , numerator ;
392+ u64 cap1 , numerator , cppc_req ;
393+ u8 min_perf ;
393394
394395 int ret = rdmsrl_safe_on_cpu (cpudata -> cpu , MSR_AMD_CPPC_CAP1 ,
395396 & cap1 );
@@ -400,6 +401,22 @@ static int msr_init_perf(struct amd_cpudata *cpudata)
400401 if (ret )
401402 return ret ;
402403
404+ ret = rdmsrl_on_cpu (cpudata -> cpu , MSR_AMD_CPPC_REQ , & cppc_req );
405+ if (ret )
406+ return ret ;
407+
408+ WRITE_ONCE (cpudata -> cppc_req_cached , cppc_req );
409+ min_perf = FIELD_GET (AMD_CPPC_MIN_PERF_MASK , cppc_req );
410+
411+ /*
412+ * Clear out the min_perf part to check if the rest of the MSR is 0, if yes, this is an
413+ * indication that the min_perf value is the one specified through the BIOS option
414+ */
415+ cppc_req &= ~(AMD_CPPC_MIN_PERF_MASK );
416+
417+ if (!cppc_req )
418+ perf .bios_min_perf = min_perf ;
419+
403420 perf .highest_perf = numerator ;
404421 perf .max_limit_perf = numerator ;
405422 perf .min_limit_perf = FIELD_GET (AMD_CPPC_LOWEST_PERF_MASK , cap1 );
@@ -554,6 +571,10 @@ static void amd_pstate_update(struct amd_cpudata *cpudata, u8 min_perf,
554571 if (!policy )
555572 return ;
556573
574+ /* limit the max perf when core performance boost feature is disabled */
575+ if (!cpudata -> boost_supported )
576+ max_perf = min_t (u8 , perf .nominal_perf , max_perf );
577+
557578 des_perf = clamp_t (u8 , des_perf , min_perf , max_perf );
558579
559580 policy -> cur = perf_to_freq (perf , cpudata -> nominal_freq , des_perf );
@@ -563,10 +584,6 @@ static void amd_pstate_update(struct amd_cpudata *cpudata, u8 min_perf,
563584 des_perf = 0 ;
564585 }
565586
566- /* limit the max perf when core performance boost feature is disabled */
567- if (!cpudata -> boost_supported )
568- max_perf = min_t (u8 , perf .nominal_perf , max_perf );
569-
570587 if (trace_amd_pstate_perf_enabled () && amd_pstate_sample (cpudata )) {
571588 trace_amd_pstate_perf (min_perf , des_perf , max_perf , cpudata -> freq ,
572589 cpudata -> cur .mperf , cpudata -> cur .aperf , cpudata -> cur .tsc ,
@@ -580,20 +597,26 @@ static int amd_pstate_verify(struct cpufreq_policy_data *policy_data)
580597{
581598 /*
582599 * Initialize lower frequency limit (i.e.policy->min) with
583- * lowest_nonlinear_frequency which is the most energy efficient
584- * frequency. Override the initial value set by cpufreq core and
585- * amd-pstate qos_requests.
600+ * lowest_nonlinear_frequency or the min frequency (if) specified in BIOS,
601+ * Override the initial value set by cpufreq core and amd-pstate qos_requests.
586602 */
587603 if (policy_data -> min == FREQ_QOS_MIN_DEFAULT_VALUE ) {
588604 struct cpufreq_policy * policy __free (put_cpufreq_policy ) =
589605 cpufreq_cpu_get (policy_data -> cpu );
590606 struct amd_cpudata * cpudata ;
607+ union perf_cached perf ;
591608
592609 if (!policy )
593610 return - EINVAL ;
594611
595612 cpudata = policy -> driver_data ;
596- policy_data -> min = cpudata -> lowest_nonlinear_freq ;
613+ perf = READ_ONCE (cpudata -> perf );
614+
615+ if (perf .bios_min_perf )
616+ policy_data -> min = perf_to_freq (perf , cpudata -> nominal_freq ,
617+ perf .bios_min_perf );
618+ else
619+ policy_data -> min = cpudata -> lowest_nonlinear_freq ;
597620 }
598621
599622 cpufreq_verify_within_cpu_limits (policy_data );
@@ -1021,6 +1044,10 @@ static int amd_pstate_cpu_init(struct cpufreq_policy *policy)
10211044static void amd_pstate_cpu_exit (struct cpufreq_policy * policy )
10221045{
10231046 struct amd_cpudata * cpudata = policy -> driver_data ;
1047+ union perf_cached perf = READ_ONCE (cpudata -> perf );
1048+
1049+ /* Reset CPPC_REQ MSR to the BIOS value */
1050+ amd_pstate_update_perf (policy , perf .bios_min_perf , 0U , 0U , 0U , false);
10241051
10251052 freq_qos_remove_request (& cpudata -> req [1 ]);
10261053 freq_qos_remove_request (& cpudata -> req [0 ]);
@@ -1302,6 +1329,12 @@ static ssize_t amd_pstate_show_status(char *buf)
13021329 return sysfs_emit (buf , "%s\n" , amd_pstate_mode_string [cppc_state ]);
13031330}
13041331
1332+ int amd_pstate_get_status (void )
1333+ {
1334+ return cppc_state ;
1335+ }
1336+ EXPORT_SYMBOL_GPL (amd_pstate_get_status );
1337+
13051338int amd_pstate_update_status (const char * buf , size_t size )
13061339{
13071340 int mode_idx ;
@@ -1416,7 +1449,6 @@ static int amd_pstate_epp_cpu_init(struct cpufreq_policy *policy)
14161449 struct amd_cpudata * cpudata ;
14171450 union perf_cached perf ;
14181451 struct device * dev ;
1419- u64 value ;
14201452 int ret ;
14211453
14221454 /*
@@ -1481,12 +1513,6 @@ static int amd_pstate_epp_cpu_init(struct cpufreq_policy *policy)
14811513 cpudata -> epp_default = AMD_CPPC_EPP_BALANCE_PERFORMANCE ;
14821514 }
14831515
1484- if (cpu_feature_enabled (X86_FEATURE_CPPC )) {
1485- ret = rdmsrl_on_cpu (cpudata -> cpu , MSR_AMD_CPPC_REQ , & value );
1486- if (ret )
1487- return ret ;
1488- WRITE_ONCE (cpudata -> cppc_req_cached , value );
1489- }
14901516 ret = amd_pstate_set_epp (policy , cpudata -> epp_default );
14911517 if (ret )
14921518 return ret ;
@@ -1506,6 +1532,11 @@ static void amd_pstate_epp_cpu_exit(struct cpufreq_policy *policy)
15061532 struct amd_cpudata * cpudata = policy -> driver_data ;
15071533
15081534 if (cpudata ) {
1535+ union perf_cached perf = READ_ONCE (cpudata -> perf );
1536+
1537+ /* Reset CPPC_REQ MSR to the BIOS value */
1538+ amd_pstate_update_perf (policy , perf .bios_min_perf , 0U , 0U , 0U , false);
1539+
15091540 kfree (cpudata );
15101541 policy -> driver_data = NULL ;
15111542 }
@@ -1556,21 +1587,38 @@ static int amd_pstate_epp_set_policy(struct cpufreq_policy *policy)
15561587 return 0 ;
15571588}
15581589
1559- static int amd_pstate_epp_cpu_online (struct cpufreq_policy * policy )
1590+ static int amd_pstate_cpu_online (struct cpufreq_policy * policy )
15601591{
1561- pr_debug ("AMD CPU Core %d going online\n" , policy -> cpu );
1562-
15631592 return amd_pstate_cppc_enable (policy );
15641593}
15651594
1566- static int amd_pstate_epp_cpu_offline (struct cpufreq_policy * policy )
1595+ static int amd_pstate_cpu_offline (struct cpufreq_policy * policy )
15671596{
1568- return 0 ;
1597+ struct amd_cpudata * cpudata = policy -> driver_data ;
1598+ union perf_cached perf = READ_ONCE (cpudata -> perf );
1599+
1600+ /*
1601+ * Reset CPPC_REQ MSR to the BIOS value, this will allow us to retain the BIOS specified
1602+ * min_perf value across kexec reboots. If this CPU is just onlined normally after this, the
1603+ * limits, epp and desired perf will get reset to the cached values in cpudata struct
1604+ */
1605+ return amd_pstate_update_perf (policy , perf .bios_min_perf , 0U , 0U , 0U , false);
15691606}
15701607
1571- static int amd_pstate_epp_suspend (struct cpufreq_policy * policy )
1608+ static int amd_pstate_suspend (struct cpufreq_policy * policy )
15721609{
15731610 struct amd_cpudata * cpudata = policy -> driver_data ;
1611+ union perf_cached perf = READ_ONCE (cpudata -> perf );
1612+ int ret ;
1613+
1614+ /*
1615+ * Reset CPPC_REQ MSR to the BIOS value, this will allow us to retain the BIOS specified
1616+ * min_perf value across kexec reboots. If this CPU is just resumed back without kexec,
1617+ * the limits, epp and desired perf will get reset to the cached values in cpudata struct
1618+ */
1619+ ret = amd_pstate_update_perf (policy , perf .bios_min_perf , 0U , 0U , 0U , false);
1620+ if (ret )
1621+ return ret ;
15741622
15751623 /* invalidate to ensure it's rewritten during resume */
15761624 cpudata -> cppc_req_cached = 0 ;
@@ -1581,6 +1629,17 @@ static int amd_pstate_epp_suspend(struct cpufreq_policy *policy)
15811629 return 0 ;
15821630}
15831631
1632+ static int amd_pstate_resume (struct cpufreq_policy * policy )
1633+ {
1634+ struct amd_cpudata * cpudata = policy -> driver_data ;
1635+ union perf_cached perf = READ_ONCE (cpudata -> perf );
1636+ int cur_perf = freq_to_perf (perf , cpudata -> nominal_freq , policy -> cur );
1637+
1638+ /* Set CPPC_REQ to last sane value until the governor updates it */
1639+ return amd_pstate_update_perf (policy , perf .min_limit_perf , cur_perf , perf .max_limit_perf ,
1640+ 0U , false);
1641+ }
1642+
15841643static int amd_pstate_epp_resume (struct cpufreq_policy * policy )
15851644{
15861645 struct amd_cpudata * cpudata = policy -> driver_data ;
@@ -1606,6 +1665,10 @@ static struct cpufreq_driver amd_pstate_driver = {
16061665 .fast_switch = amd_pstate_fast_switch ,
16071666 .init = amd_pstate_cpu_init ,
16081667 .exit = amd_pstate_cpu_exit ,
1668+ .online = amd_pstate_cpu_online ,
1669+ .offline = amd_pstate_cpu_offline ,
1670+ .suspend = amd_pstate_suspend ,
1671+ .resume = amd_pstate_resume ,
16091672 .set_boost = amd_pstate_set_boost ,
16101673 .update_limits = amd_pstate_update_limits ,
16111674 .name = "amd-pstate" ,
@@ -1618,9 +1681,9 @@ static struct cpufreq_driver amd_pstate_epp_driver = {
16181681 .setpolicy = amd_pstate_epp_set_policy ,
16191682 .init = amd_pstate_epp_cpu_init ,
16201683 .exit = amd_pstate_epp_cpu_exit ,
1621- .offline = amd_pstate_epp_cpu_offline ,
1622- .online = amd_pstate_epp_cpu_online ,
1623- .suspend = amd_pstate_epp_suspend ,
1684+ .offline = amd_pstate_cpu_offline ,
1685+ .online = amd_pstate_cpu_online ,
1686+ .suspend = amd_pstate_suspend ,
16241687 .resume = amd_pstate_epp_resume ,
16251688 .update_limits = amd_pstate_update_limits ,
16261689 .set_boost = amd_pstate_set_boost ,
0 commit comments