4747#define SMUIO_GFX_MISC_CNTL__PWR_GFXOFF_STATUS_MASK 0x00000006L
4848#define SMUIO_GFX_MISC_CNTL__PWR_GFXOFF_STATUS__SHIFT 0x1L
4949
50+ #define SMU_13_0_8_UMD_PSTATE_GFXCLK 533
51+ #define SMU_13_0_8_UMD_PSTATE_SOCCLK 533
52+ #define SMU_13_0_8_UMD_PSTATE_FCLK 800
53+
54+ #define SMU_13_0_1_UMD_PSTATE_GFXCLK 700
55+ #define SMU_13_0_1_UMD_PSTATE_SOCCLK 678
56+ #define SMU_13_0_1_UMD_PSTATE_FCLK 1800
57+
5058#define FEATURE_MASK (feature ) (1ULL << feature)
5159#define SMC_DPM_FEATURE ( \
5260 FEATURE_MASK(FEATURE_CCLK_DPM_BIT) | \
@@ -957,6 +965,9 @@ static int yellow_carp_set_soft_freq_limited_range(struct smu_context *smu,
957965 uint32_t max )
958966{
959967 enum smu_message_type msg_set_min , msg_set_max ;
968+ uint32_t min_clk = min ;
969+ uint32_t max_clk = max ;
970+
960971 int ret = 0 ;
961972
962973 if (!yellow_carp_clk_dpm_is_enabled (smu , clk_type ))
@@ -985,24 +996,67 @@ static int yellow_carp_set_soft_freq_limited_range(struct smu_context *smu,
985996 return - EINVAL ;
986997 }
987998
988- ret = smu_cmn_send_smc_msg_with_param (smu , msg_set_min , min , NULL );
999+ if (clk_type == SMU_VCLK ) {
1000+ min_clk = min << SMU_13_VCLK_SHIFT ;
1001+ max_clk = max << SMU_13_VCLK_SHIFT ;
1002+ }
1003+
1004+ ret = smu_cmn_send_smc_msg_with_param (smu , msg_set_min , min_clk , NULL );
1005+
9891006 if (ret )
9901007 goto out ;
9911008
992- ret = smu_cmn_send_smc_msg_with_param (smu , msg_set_max , max , NULL );
1009+ ret = smu_cmn_send_smc_msg_with_param (smu , msg_set_max , max_clk , NULL );
9931010 if (ret )
9941011 goto out ;
9951012
9961013out :
9971014 return ret ;
9981015}
9991016
1017+ static uint32_t yellow_carp_get_umd_pstate_clk_default (struct smu_context * smu ,
1018+ enum smu_clk_type clk_type )
1019+ {
1020+ uint32_t clk_limit = 0 ;
1021+ struct amdgpu_device * adev = smu -> adev ;
1022+
1023+ switch (clk_type ) {
1024+ case SMU_GFXCLK :
1025+ case SMU_SCLK :
1026+ if ((adev -> ip_versions [MP1_HWIP ][0 ]) == IP_VERSION (13 , 0 , 8 ))
1027+ clk_limit = SMU_13_0_8_UMD_PSTATE_GFXCLK ;
1028+ if ((adev -> ip_versions [MP1_HWIP ][0 ]) == IP_VERSION (13 , 0 , 1 ) ||
1029+ (adev -> ip_versions [MP1_HWIP ][0 ]) == IP_VERSION (13 , 0 , 3 ))
1030+ clk_limit = SMU_13_0_1_UMD_PSTATE_GFXCLK ;
1031+ break ;
1032+ case SMU_SOCCLK :
1033+ if ((adev -> ip_versions [MP1_HWIP ][0 ]) == IP_VERSION (13 , 0 , 8 ))
1034+ clk_limit = SMU_13_0_8_UMD_PSTATE_SOCCLK ;
1035+ if ((adev -> ip_versions [MP1_HWIP ][0 ]) == IP_VERSION (13 , 0 , 1 ) ||
1036+ (adev -> ip_versions [MP1_HWIP ][0 ]) == IP_VERSION (13 , 0 , 3 ))
1037+ clk_limit = SMU_13_0_1_UMD_PSTATE_SOCCLK ;
1038+ break ;
1039+ case SMU_FCLK :
1040+ if ((adev -> ip_versions [MP1_HWIP ][0 ]) == IP_VERSION (13 , 0 , 8 ))
1041+ clk_limit = SMU_13_0_8_UMD_PSTATE_FCLK ;
1042+ if ((adev -> ip_versions [MP1_HWIP ][0 ]) == IP_VERSION (13 , 0 , 1 ) ||
1043+ (adev -> ip_versions [MP1_HWIP ][0 ]) == IP_VERSION (13 , 0 , 3 ))
1044+ clk_limit = SMU_13_0_1_UMD_PSTATE_FCLK ;
1045+ break ;
1046+ default :
1047+ break ;
1048+ }
1049+
1050+ return clk_limit ;
1051+ }
1052+
10001053static int yellow_carp_print_clk_levels (struct smu_context * smu ,
10011054 enum smu_clk_type clk_type , char * buf )
10021055{
10031056 int i , idx , size = 0 , ret = 0 ;
10041057 uint32_t cur_value = 0 , value = 0 , count = 0 ;
10051058 uint32_t min , max ;
1059+ uint32_t clk_limit = 0 ;
10061060
10071061 smu_cmn_get_sysfs_buf (& buf , & size );
10081062
@@ -1044,6 +1098,7 @@ static int yellow_carp_print_clk_levels(struct smu_context *smu,
10441098 break ;
10451099 case SMU_GFXCLK :
10461100 case SMU_SCLK :
1101+ clk_limit = yellow_carp_get_umd_pstate_clk_default (smu , clk_type );
10471102 ret = yellow_carp_get_current_clk_freq (smu , clk_type , & cur_value );
10481103 if (ret )
10491104 goto print_clk_out ;
@@ -1058,7 +1113,7 @@ static int yellow_carp_print_clk_levels(struct smu_context *smu,
10581113 size += sysfs_emit_at (buf , size , "0: %uMhz %s\n" , min ,
10591114 i == 0 ? "*" : "" );
10601115 size += sysfs_emit_at (buf , size , "1: %uMhz %s\n" ,
1061- i == 1 ? cur_value : YELLOW_CARP_UMD_PSTATE_GFXCLK ,
1116+ i == 1 ? cur_value : clk_limit ,
10621117 i == 1 ? "*" : "" );
10631118 size += sysfs_emit_at (buf , size , "2: %uMhz %s\n" , max ,
10641119 i == 2 ? "*" : "" );
@@ -1107,42 +1162,102 @@ static int yellow_carp_force_clk_levels(struct smu_context *smu,
11071162 return ret ;
11081163}
11091164
1165+ static int yellow_carp_get_dpm_profile_freq (struct smu_context * smu ,
1166+ enum amd_dpm_forced_level level ,
1167+ enum smu_clk_type clk_type ,
1168+ uint32_t * min_clk ,
1169+ uint32_t * max_clk )
1170+ {
1171+ int ret = 0 ;
1172+ uint32_t clk_limit = 0 ;
1173+
1174+ clk_limit = yellow_carp_get_umd_pstate_clk_default (smu , clk_type );
1175+
1176+ switch (clk_type ) {
1177+ case SMU_GFXCLK :
1178+ case SMU_SCLK :
1179+ if (level == AMD_DPM_FORCED_LEVEL_PROFILE_PEAK )
1180+ yellow_carp_get_dpm_ultimate_freq (smu , SMU_SCLK , NULL , & clk_limit );
1181+ else if (level == AMD_DPM_FORCED_LEVEL_PROFILE_MIN_SCLK )
1182+ yellow_carp_get_dpm_ultimate_freq (smu , SMU_SCLK , & clk_limit , NULL );
1183+ break ;
1184+ case SMU_SOCCLK :
1185+ if (level == AMD_DPM_FORCED_LEVEL_PROFILE_PEAK )
1186+ yellow_carp_get_dpm_ultimate_freq (smu , SMU_SOCCLK , NULL , & clk_limit );
1187+ break ;
1188+ case SMU_FCLK :
1189+ if (level == AMD_DPM_FORCED_LEVEL_PROFILE_PEAK )
1190+ yellow_carp_get_dpm_ultimate_freq (smu , SMU_FCLK , NULL , & clk_limit );
1191+ else if (level == AMD_DPM_FORCED_LEVEL_PROFILE_MIN_MCLK )
1192+ yellow_carp_get_dpm_ultimate_freq (smu , SMU_FCLK , & clk_limit , NULL );
1193+ break ;
1194+ case SMU_VCLK :
1195+ yellow_carp_get_dpm_ultimate_freq (smu , SMU_VCLK , NULL , & clk_limit );
1196+ break ;
1197+ case SMU_DCLK :
1198+ yellow_carp_get_dpm_ultimate_freq (smu , SMU_DCLK , NULL , & clk_limit );
1199+ break ;
1200+ default :
1201+ ret = - EINVAL ;
1202+ break ;
1203+ }
1204+ * min_clk = * max_clk = clk_limit ;
1205+ return ret ;
1206+ }
1207+
11101208static int yellow_carp_set_performance_level (struct smu_context * smu ,
11111209 enum amd_dpm_forced_level level )
11121210{
11131211 struct amdgpu_device * adev = smu -> adev ;
11141212 uint32_t sclk_min = 0 , sclk_max = 0 ;
11151213 uint32_t fclk_min = 0 , fclk_max = 0 ;
11161214 uint32_t socclk_min = 0 , socclk_max = 0 ;
1215+ uint32_t vclk_min = 0 , vclk_max = 0 ;
1216+ uint32_t dclk_min = 0 , dclk_max = 0 ;
1217+
11171218 int ret = 0 ;
11181219
11191220 switch (level ) {
11201221 case AMD_DPM_FORCED_LEVEL_HIGH :
11211222 yellow_carp_get_dpm_ultimate_freq (smu , SMU_SCLK , NULL , & sclk_max );
11221223 yellow_carp_get_dpm_ultimate_freq (smu , SMU_FCLK , NULL , & fclk_max );
11231224 yellow_carp_get_dpm_ultimate_freq (smu , SMU_SOCCLK , NULL , & socclk_max );
1225+ yellow_carp_get_dpm_ultimate_freq (smu , SMU_VCLK , NULL , & vclk_max );
1226+ yellow_carp_get_dpm_ultimate_freq (smu , SMU_DCLK , NULL , & dclk_max );
11241227 sclk_min = sclk_max ;
11251228 fclk_min = fclk_max ;
11261229 socclk_min = socclk_max ;
1230+ vclk_min = vclk_max ;
1231+ dclk_min = dclk_max ;
11271232 break ;
11281233 case AMD_DPM_FORCED_LEVEL_LOW :
11291234 yellow_carp_get_dpm_ultimate_freq (smu , SMU_SCLK , & sclk_min , NULL );
11301235 yellow_carp_get_dpm_ultimate_freq (smu , SMU_FCLK , & fclk_min , NULL );
11311236 yellow_carp_get_dpm_ultimate_freq (smu , SMU_SOCCLK , & socclk_min , NULL );
1237+ yellow_carp_get_dpm_ultimate_freq (smu , SMU_VCLK , & vclk_min , NULL );
1238+ yellow_carp_get_dpm_ultimate_freq (smu , SMU_DCLK , & dclk_min , NULL );
11321239 sclk_max = sclk_min ;
11331240 fclk_max = fclk_min ;
11341241 socclk_max = socclk_min ;
1242+ vclk_max = vclk_min ;
1243+ dclk_max = dclk_min ;
11351244 break ;
11361245 case AMD_DPM_FORCED_LEVEL_AUTO :
11371246 yellow_carp_get_dpm_ultimate_freq (smu , SMU_SCLK , & sclk_min , & sclk_max );
11381247 yellow_carp_get_dpm_ultimate_freq (smu , SMU_FCLK , & fclk_min , & fclk_max );
11391248 yellow_carp_get_dpm_ultimate_freq (smu , SMU_SOCCLK , & socclk_min , & socclk_max );
1249+ yellow_carp_get_dpm_ultimate_freq (smu , SMU_VCLK , & vclk_min , & vclk_max );
1250+ yellow_carp_get_dpm_ultimate_freq (smu , SMU_DCLK , & dclk_min , & dclk_max );
11401251 break ;
11411252 case AMD_DPM_FORCED_LEVEL_PROFILE_STANDARD :
11421253 case AMD_DPM_FORCED_LEVEL_PROFILE_MIN_SCLK :
11431254 case AMD_DPM_FORCED_LEVEL_PROFILE_MIN_MCLK :
11441255 case AMD_DPM_FORCED_LEVEL_PROFILE_PEAK :
1145- /* Temporarily do nothing since the optimal clocks haven't been provided yet */
1256+ yellow_carp_get_dpm_profile_freq (smu , level , SMU_SCLK , & sclk_min , & sclk_max );
1257+ yellow_carp_get_dpm_profile_freq (smu , level , SMU_FCLK , & fclk_min , & fclk_max );
1258+ yellow_carp_get_dpm_profile_freq (smu , level , SMU_SOCCLK , & socclk_min , & socclk_max );
1259+ yellow_carp_get_dpm_profile_freq (smu , level , SMU_VCLK , & vclk_min , & vclk_max );
1260+ yellow_carp_get_dpm_profile_freq (smu , level , SMU_DCLK , & dclk_min , & dclk_max );
11461261 break ;
11471262 case AMD_DPM_FORCED_LEVEL_MANUAL :
11481263 case AMD_DPM_FORCED_LEVEL_PROFILE_EXIT :
@@ -1182,6 +1297,24 @@ static int yellow_carp_set_performance_level(struct smu_context *smu,
11821297 return ret ;
11831298 }
11841299
1300+ if (vclk_min && vclk_max ) {
1301+ ret = yellow_carp_set_soft_freq_limited_range (smu ,
1302+ SMU_VCLK ,
1303+ vclk_min ,
1304+ vclk_max );
1305+ if (ret )
1306+ return ret ;
1307+ }
1308+
1309+ if (dclk_min && dclk_max ) {
1310+ ret = yellow_carp_set_soft_freq_limited_range (smu ,
1311+ SMU_DCLK ,
1312+ dclk_min ,
1313+ dclk_max );
1314+ if (ret )
1315+ return ret ;
1316+ }
1317+
11851318 return ret ;
11861319}
11871320
0 commit comments