@@ -383,8 +383,10 @@ static int amd_pstate_init_floor_perf(struct cpufreq_policy *policy)
383383 return ret ;
384384 }
385385
386- cpudata -> bios_floor_perf = floor_perf ;
387386
387+ cpudata -> bios_floor_perf = floor_perf ;
388+ cpudata -> floor_freq = perf_to_freq (cpudata -> perf , cpudata -> nominal_freq ,
389+ floor_perf );
388390 return 0 ;
389391}
390392
@@ -1288,6 +1290,46 @@ static ssize_t show_energy_performance_preference(
12881290 return sysfs_emit (buf , "%s\n" , energy_perf_strings [preference ]);
12891291}
12901292
1293+ static ssize_t store_amd_pstate_floor_freq (struct cpufreq_policy * policy ,
1294+ const char * buf , size_t count )
1295+ {
1296+ struct amd_cpudata * cpudata = policy -> driver_data ;
1297+ union perf_cached perf = READ_ONCE (cpudata -> perf );
1298+ unsigned int freq ;
1299+ u8 floor_perf ;
1300+ int ret ;
1301+
1302+ ret = kstrtouint (buf , 0 , & freq );
1303+ if (ret )
1304+ return ret ;
1305+
1306+ if (freq < policy -> cpuinfo .min_freq || freq > policy -> max )
1307+ return - EINVAL ;
1308+
1309+ floor_perf = freq_to_perf (perf , cpudata -> nominal_freq , freq );
1310+ ret = amd_pstate_set_floor_perf (policy , floor_perf );
1311+
1312+ if (!ret )
1313+ cpudata -> floor_freq = freq ;
1314+
1315+ return ret ?: count ;
1316+ }
1317+
1318+ static ssize_t show_amd_pstate_floor_freq (struct cpufreq_policy * policy , char * buf )
1319+ {
1320+ struct amd_cpudata * cpudata = policy -> driver_data ;
1321+
1322+ return sysfs_emit (buf , "%u\n" , cpudata -> floor_freq );
1323+ }
1324+
1325+ static ssize_t show_amd_pstate_floor_count (struct cpufreq_policy * policy , char * buf )
1326+ {
1327+ struct amd_cpudata * cpudata = policy -> driver_data ;
1328+ u8 count = cpudata -> floor_perf_cnt ;
1329+
1330+ return sysfs_emit (buf , "%u\n" , count );
1331+ }
1332+
12911333cpufreq_freq_attr_ro (amd_pstate_max_freq );
12921334cpufreq_freq_attr_ro (amd_pstate_lowest_nonlinear_freq );
12931335
@@ -1296,6 +1338,8 @@ cpufreq_freq_attr_ro(amd_pstate_prefcore_ranking);
12961338cpufreq_freq_attr_ro (amd_pstate_hw_prefcore );
12971339cpufreq_freq_attr_rw (energy_performance_preference );
12981340cpufreq_freq_attr_ro (energy_performance_available_preferences );
1341+ cpufreq_freq_attr_rw (amd_pstate_floor_freq );
1342+ cpufreq_freq_attr_ro (amd_pstate_floor_count );
12991343
13001344struct freq_attr_visibility {
13011345 struct freq_attr * attr ;
@@ -1320,6 +1364,12 @@ static bool epp_visibility(void)
13201364 return cppc_state == AMD_PSTATE_ACTIVE ;
13211365}
13221366
1367+ /* Determines whether amd_pstate_floor_freq related attributes should be visible */
1368+ static bool floor_freq_visibility (void )
1369+ {
1370+ return cpu_feature_enabled (X86_FEATURE_CPPC_PERF_PRIO );
1371+ }
1372+
13231373static struct freq_attr_visibility amd_pstate_attr_visibility [] = {
13241374 {& amd_pstate_max_freq , always_visible },
13251375 {& amd_pstate_lowest_nonlinear_freq , always_visible },
@@ -1328,6 +1378,8 @@ static struct freq_attr_visibility amd_pstate_attr_visibility[] = {
13281378 {& amd_pstate_hw_prefcore , prefcore_visibility },
13291379 {& energy_performance_preference , epp_visibility },
13301380 {& energy_performance_available_preferences , epp_visibility },
1381+ {& amd_pstate_floor_freq , floor_freq_visibility },
1382+ {& amd_pstate_floor_count , floor_freq_visibility },
13311383};
13321384
13331385static struct freq_attr * * get_freq_attrs (void )
@@ -1748,24 +1800,39 @@ static int amd_pstate_epp_set_policy(struct cpufreq_policy *policy)
17481800
17491801static int amd_pstate_cpu_online (struct cpufreq_policy * policy )
17501802{
1751- return amd_pstate_cppc_enable (policy );
1803+ struct amd_cpudata * cpudata = policy -> driver_data ;
1804+ union perf_cached perf = READ_ONCE (cpudata -> perf );
1805+ u8 cached_floor_perf ;
1806+ int ret ;
1807+
1808+ ret = amd_pstate_cppc_enable (policy );
1809+ if (ret )
1810+ return ret ;
1811+
1812+ cached_floor_perf = freq_to_perf (perf , cpudata -> nominal_freq , cpudata -> floor_freq );
1813+ return amd_pstate_set_floor_perf (policy , cached_floor_perf );
17521814}
17531815
17541816static int amd_pstate_cpu_offline (struct cpufreq_policy * policy )
17551817{
17561818 struct amd_cpudata * cpudata = policy -> driver_data ;
17571819 union perf_cached perf = READ_ONCE (cpudata -> perf );
1820+ int ret ;
17581821
17591822 /*
17601823 * Reset CPPC_REQ MSR to the BIOS value, this will allow us to retain the BIOS specified
17611824 * min_perf value across kexec reboots. If this CPU is just onlined normally after this, the
17621825 * limits, epp and desired perf will get reset to the cached values in cpudata struct
17631826 */
1764- return amd_pstate_update_perf (policy , perf .bios_min_perf ,
1827+ ret = amd_pstate_update_perf (policy , perf .bios_min_perf ,
17651828 FIELD_GET (AMD_CPPC_DES_PERF_MASK , cpudata -> cppc_req_cached ),
17661829 FIELD_GET (AMD_CPPC_MAX_PERF_MASK , cpudata -> cppc_req_cached ),
17671830 FIELD_GET (AMD_CPPC_EPP_PERF_MASK , cpudata -> cppc_req_cached ),
17681831 false);
1832+ if (ret )
1833+ return ret ;
1834+
1835+ return amd_pstate_set_floor_perf (policy , cpudata -> bios_floor_perf );
17691836}
17701837
17711838static int amd_pstate_suspend (struct cpufreq_policy * policy )
@@ -1787,6 +1854,10 @@ static int amd_pstate_suspend(struct cpufreq_policy *policy)
17871854 if (ret )
17881855 return ret ;
17891856
1857+ ret = amd_pstate_set_floor_perf (policy , cpudata -> bios_floor_perf );
1858+ if (ret )
1859+ return ret ;
1860+
17901861 /* set this flag to avoid setting core offline*/
17911862 cpudata -> suspended = true;
17921863
@@ -1798,15 +1869,24 @@ static int amd_pstate_resume(struct cpufreq_policy *policy)
17981869 struct amd_cpudata * cpudata = policy -> driver_data ;
17991870 union perf_cached perf = READ_ONCE (cpudata -> perf );
18001871 int cur_perf = freq_to_perf (perf , cpudata -> nominal_freq , policy -> cur );
1872+ u8 cached_floor_perf ;
1873+ int ret ;
18011874
18021875 /* Set CPPC_REQ to last sane value until the governor updates it */
1803- return amd_pstate_update_perf (policy , perf .min_limit_perf , cur_perf , perf .max_limit_perf ,
1804- 0U , false);
1876+ ret = amd_pstate_update_perf (policy , perf .min_limit_perf , cur_perf , perf .max_limit_perf ,
1877+ 0U , false);
1878+ if (ret )
1879+ return ret ;
1880+
1881+ cached_floor_perf = freq_to_perf (perf , cpudata -> nominal_freq , cpudata -> floor_freq );
1882+ return amd_pstate_set_floor_perf (policy , cached_floor_perf );
18051883}
18061884
18071885static int amd_pstate_epp_resume (struct cpufreq_policy * policy )
18081886{
18091887 struct amd_cpudata * cpudata = policy -> driver_data ;
1888+ union perf_cached perf = READ_ONCE (cpudata -> perf );
1889+ u8 cached_floor_perf ;
18101890
18111891 if (cpudata -> suspended ) {
18121892 int ret ;
@@ -1819,7 +1899,8 @@ static int amd_pstate_epp_resume(struct cpufreq_policy *policy)
18191899 cpudata -> suspended = false;
18201900 }
18211901
1822- return 0 ;
1902+ cached_floor_perf = freq_to_perf (perf , cpudata -> nominal_freq , cpudata -> floor_freq );
1903+ return amd_pstate_set_floor_perf (policy , cached_floor_perf );
18231904}
18241905
18251906static struct cpufreq_driver amd_pstate_driver = {
0 commit comments