@@ -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 );
@@ -581,20 +598,26 @@ static int amd_pstate_verify(struct cpufreq_policy_data *policy_data)
581598{
582599 /*
583600 * Initialize lower frequency limit (i.e.policy->min) with
584- * lowest_nonlinear_frequency which is the most energy efficient
585- * frequency. Override the initial value set by cpufreq core and
586- * amd-pstate qos_requests.
601+ * lowest_nonlinear_frequency or the min frequency (if) specified in BIOS,
602+ * Override the initial value set by cpufreq core and amd-pstate qos_requests.
587603 */
588604 if (policy_data -> min == FREQ_QOS_MIN_DEFAULT_VALUE ) {
589605 struct cpufreq_policy * policy __free (put_cpufreq_policy ) =
590606 cpufreq_cpu_get (policy_data -> cpu );
591607 struct amd_cpudata * cpudata ;
608+ union perf_cached perf ;
592609
593610 if (!policy )
594611 return - EINVAL ;
595612
596613 cpudata = policy -> driver_data ;
597- policy_data -> min = cpudata -> lowest_nonlinear_freq ;
614+ perf = READ_ONCE (cpudata -> perf );
615+
616+ if (perf .bios_min_perf )
617+ policy_data -> min = perf_to_freq (perf , cpudata -> nominal_freq ,
618+ perf .bios_min_perf );
619+ else
620+ policy_data -> min = cpudata -> lowest_nonlinear_freq ;
598621 }
599622
600623 cpufreq_verify_within_cpu_limits (policy_data );
@@ -1027,6 +1050,10 @@ static int amd_pstate_cpu_init(struct cpufreq_policy *policy)
10271050static void amd_pstate_cpu_exit (struct cpufreq_policy * policy )
10281051{
10291052 struct amd_cpudata * cpudata = policy -> driver_data ;
1053+ union perf_cached perf = READ_ONCE (cpudata -> perf );
1054+
1055+ /* Reset CPPC_REQ MSR to the BIOS value */
1056+ amd_pstate_update_perf (policy , perf .bios_min_perf , 0U , 0U , 0U , false);
10301057
10311058 freq_qos_remove_request (& cpudata -> req [1 ]);
10321059 freq_qos_remove_request (& cpudata -> req [0 ]);
@@ -1422,7 +1449,6 @@ static int amd_pstate_epp_cpu_init(struct cpufreq_policy *policy)
14221449 struct amd_cpudata * cpudata ;
14231450 union perf_cached perf ;
14241451 struct device * dev ;
1425- u64 value ;
14261452 int ret ;
14271453
14281454 /*
@@ -1487,12 +1513,6 @@ static int amd_pstate_epp_cpu_init(struct cpufreq_policy *policy)
14871513 cpudata -> epp_default = AMD_CPPC_EPP_BALANCE_PERFORMANCE ;
14881514 }
14891515
1490- if (cpu_feature_enabled (X86_FEATURE_CPPC )) {
1491- ret = rdmsrl_on_cpu (cpudata -> cpu , MSR_AMD_CPPC_REQ , & value );
1492- if (ret )
1493- return ret ;
1494- WRITE_ONCE (cpudata -> cppc_req_cached , value );
1495- }
14961516 ret = amd_pstate_set_epp (policy , cpudata -> epp_default );
14971517 if (ret )
14981518 return ret ;
@@ -1512,6 +1532,11 @@ static void amd_pstate_epp_cpu_exit(struct cpufreq_policy *policy)
15121532 struct amd_cpudata * cpudata = policy -> driver_data ;
15131533
15141534 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+
15151540 kfree (cpudata );
15161541 policy -> driver_data = NULL ;
15171542 }
@@ -1562,31 +1587,60 @@ static int amd_pstate_epp_set_policy(struct cpufreq_policy *policy)
15621587 return 0 ;
15631588}
15641589
1565- static int amd_pstate_epp_cpu_online (struct cpufreq_policy * policy )
1590+ static int amd_pstate_cpu_online (struct cpufreq_policy * policy )
15661591{
1567- pr_debug ("AMD CPU Core %d going online\n" , policy -> cpu );
1568-
15691592 return amd_pstate_cppc_enable (policy );
15701593}
15711594
1572- static int amd_pstate_epp_cpu_offline (struct cpufreq_policy * policy )
1595+ static int amd_pstate_cpu_offline (struct cpufreq_policy * policy )
15731596{
1574- 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);
15751606}
15761607
1577- static int amd_pstate_epp_suspend (struct cpufreq_policy * policy )
1608+ static int amd_pstate_suspend (struct cpufreq_policy * policy )
15781609{
15791610 struct amd_cpudata * cpudata = policy -> driver_data ;
1611+ union perf_cached perf = READ_ONCE (cpudata -> perf );
1612+ int ret ;
15801613
1581- /* invalidate to ensure it's rewritten during resume */
1582- cpudata -> cppc_req_cached = 0 ;
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 ,
1620+ FIELD_GET (AMD_CPPC_DES_PERF_MASK , cpudata -> cppc_req_cached ),
1621+ FIELD_GET (AMD_CPPC_MAX_PERF_MASK , cpudata -> cppc_req_cached ),
1622+ FIELD_GET (AMD_CPPC_EPP_PERF_MASK , cpudata -> cppc_req_cached ),
1623+ false);
1624+ if (ret )
1625+ return ret ;
15831626
15841627 /* set this flag to avoid setting core offline*/
15851628 cpudata -> suspended = true;
15861629
15871630 return 0 ;
15881631}
15891632
1633+ static int amd_pstate_resume (struct cpufreq_policy * policy )
1634+ {
1635+ struct amd_cpudata * cpudata = policy -> driver_data ;
1636+ union perf_cached perf = READ_ONCE (cpudata -> perf );
1637+ int cur_perf = freq_to_perf (perf , cpudata -> nominal_freq , policy -> cur );
1638+
1639+ /* Set CPPC_REQ to last sane value until the governor updates it */
1640+ return amd_pstate_update_perf (policy , perf .min_limit_perf , cur_perf , perf .max_limit_perf ,
1641+ 0U , false);
1642+ }
1643+
15901644static int amd_pstate_epp_resume (struct cpufreq_policy * policy )
15911645{
15921646 struct amd_cpudata * cpudata = policy -> driver_data ;
@@ -1612,6 +1666,10 @@ static struct cpufreq_driver amd_pstate_driver = {
16121666 .fast_switch = amd_pstate_fast_switch ,
16131667 .init = amd_pstate_cpu_init ,
16141668 .exit = amd_pstate_cpu_exit ,
1669+ .online = amd_pstate_cpu_online ,
1670+ .offline = amd_pstate_cpu_offline ,
1671+ .suspend = amd_pstate_suspend ,
1672+ .resume = amd_pstate_resume ,
16151673 .set_boost = amd_pstate_set_boost ,
16161674 .update_limits = amd_pstate_update_limits ,
16171675 .name = "amd-pstate" ,
@@ -1624,9 +1682,9 @@ static struct cpufreq_driver amd_pstate_epp_driver = {
16241682 .setpolicy = amd_pstate_epp_set_policy ,
16251683 .init = amd_pstate_epp_cpu_init ,
16261684 .exit = amd_pstate_epp_cpu_exit ,
1627- .offline = amd_pstate_epp_cpu_offline ,
1628- .online = amd_pstate_epp_cpu_online ,
1629- .suspend = amd_pstate_epp_suspend ,
1685+ .offline = amd_pstate_cpu_offline ,
1686+ .online = amd_pstate_cpu_online ,
1687+ .suspend = amd_pstate_suspend ,
16301688 .resume = amd_pstate_epp_resume ,
16311689 .update_limits = amd_pstate_update_limits ,
16321690 .set_boost = amd_pstate_set_boost ,
0 commit comments