1 /* 2 * Copyright 2022 Advanced Micro Devices, Inc. 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice shall be included in 12 * all copies or substantial portions of the Software. 13 * 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20 * OTHER DEALINGS IN THE SOFTWARE. 21 * 22 */ 23 24 #include "smu_types.h" 25 #define SWSMU_CODE_LAYER_L2 26 27 #include "amdgpu.h" 28 #include "amdgpu_smu.h" 29 #include "smu_v13_0.h" 30 #include "smu13_driver_if_v13_0_4.h" 31 #include "smu_v13_0_4_ppt.h" 32 #include "smu_v13_0_4_ppsmc.h" 33 #include "smu_v13_0_4_pmfw.h" 34 #include "smu_cmn.h" 35 36 /* 37 * DO NOT use these for err/warn/info/debug messages. 38 * Use dev_err, dev_warn, dev_info and dev_dbg instead. 39 * They are more MGPU friendly. 40 */ 41 #undef pr_err 42 #undef pr_warn 43 #undef pr_info 44 #undef pr_debug 45 46 #define mmMP1_SMN_C2PMSG_66 0x0282 47 #define mmMP1_SMN_C2PMSG_66_BASE_IDX 1 48 49 #define mmMP1_SMN_C2PMSG_82 0x0292 50 #define mmMP1_SMN_C2PMSG_82_BASE_IDX 1 51 52 #define mmMP1_SMN_C2PMSG_90 0x029a 53 #define mmMP1_SMN_C2PMSG_90_BASE_IDX 1 54 55 #define FEATURE_MASK(feature) (1ULL << feature) 56 57 #define SMU_13_0_4_UMD_PSTATE_GFXCLK 938 58 #define SMU_13_0_4_UMD_PSTATE_SOCCLK 938 59 #define SMU_13_0_4_UMD_PSTATE_FCLK 1875 60 61 #define SMC_DPM_FEATURE ( \ 62 FEATURE_MASK(FEATURE_CCLK_DPM_BIT) | \ 63 FEATURE_MASK(FEATURE_VCN_DPM_BIT) | \ 64 FEATURE_MASK(FEATURE_FCLK_DPM_BIT) | \ 65 FEATURE_MASK(FEATURE_SOCCLK_DPM_BIT) | \ 66 FEATURE_MASK(FEATURE_MP0CLK_DPM_BIT) | \ 67 FEATURE_MASK(FEATURE_LCLK_DPM_BIT) | \ 68 FEATURE_MASK(FEATURE_SHUBCLK_DPM_BIT) | \ 69 FEATURE_MASK(FEATURE_DCFCLK_DPM_BIT) | \ 70 FEATURE_MASK(FEATURE_ISP_DPM_BIT) | \ 71 FEATURE_MASK(FEATURE_IPU_DPM_BIT) | \ 72 FEATURE_MASK(FEATURE_GFX_DPM_BIT)) 73 74 static struct cmn2asic_msg_mapping smu_v13_0_4_message_map[SMU_MSG_MAX_COUNT] = { 75 MSG_MAP(TestMessage, PPSMC_MSG_TestMessage, 1), 76 MSG_MAP(GetSmuVersion, PPSMC_MSG_GetPmfwVersion, 1), 77 MSG_MAP(GetDriverIfVersion, PPSMC_MSG_GetDriverIfVersion, 1), 78 MSG_MAP(AllowGfxOff, PPSMC_MSG_AllowGfxOff, 1), 79 MSG_MAP(DisallowGfxOff, PPSMC_MSG_DisallowGfxOff, 1), 80 MSG_MAP(PowerDownVcn, PPSMC_MSG_PowerDownVcn, 1), 81 MSG_MAP(PowerUpVcn, PPSMC_MSG_PowerUpVcn, 1), 82 MSG_MAP(SetHardMinVcn, PPSMC_MSG_SetHardMinVcn, 1), 83 MSG_MAP(PrepareMp1ForUnload, PPSMC_MSG_PrepareMp1ForUnload, 1), 84 MSG_MAP(SetDriverDramAddrHigh, PPSMC_MSG_SetDriverDramAddrHigh, 1), 85 MSG_MAP(SetDriverDramAddrLow, PPSMC_MSG_SetDriverDramAddrLow, 1), 86 MSG_MAP(TransferTableSmu2Dram, PPSMC_MSG_TransferTableSmu2Dram, 1), 87 MSG_MAP(TransferTableDram2Smu, PPSMC_MSG_TransferTableDram2Smu, 1), 88 MSG_MAP(GfxDeviceDriverReset, PPSMC_MSG_GfxDeviceDriverReset, 1), 89 MSG_MAP(GetEnabledSmuFeatures, PPSMC_MSG_GetEnabledSmuFeatures, 1), 90 MSG_MAP(SetHardMinSocclkByFreq, PPSMC_MSG_SetHardMinSocclkByFreq, 1), 91 MSG_MAP(SetSoftMinVcn, PPSMC_MSG_SetSoftMinVcn, 1), 92 MSG_MAP(GetGfxclkFrequency, PPSMC_MSG_GetGfxclkFrequency, 1), 93 MSG_MAP(GetFclkFrequency, PPSMC_MSG_GetFclkFrequency, 1), 94 MSG_MAP(SetSoftMaxGfxClk, PPSMC_MSG_SetSoftMaxGfxClk, 1), 95 MSG_MAP(SetHardMinGfxClk, PPSMC_MSG_SetHardMinGfxClk, 1), 96 MSG_MAP(SetSoftMaxSocclkByFreq, PPSMC_MSG_SetSoftMaxSocclkByFreq, 1), 97 MSG_MAP(SetSoftMaxFclkByFreq, PPSMC_MSG_SetSoftMaxFclkByFreq, 1), 98 MSG_MAP(SetSoftMaxVcn, PPSMC_MSG_SetSoftMaxVcn, 1), 99 MSG_MAP(SetPowerLimitPercentage, PPSMC_MSG_SetPowerLimitPercentage, 1), 100 MSG_MAP(PowerDownJpeg, PPSMC_MSG_PowerDownJpeg, 1), 101 MSG_MAP(PowerUpJpeg, PPSMC_MSG_PowerUpJpeg, 1), 102 MSG_MAP(SetHardMinFclkByFreq, PPSMC_MSG_SetHardMinFclkByFreq, 1), 103 MSG_MAP(SetSoftMinSocclkByFreq, PPSMC_MSG_SetSoftMinSocclkByFreq, 1), 104 MSG_MAP(EnableGfxImu, PPSMC_MSG_EnableGfxImu, 1), 105 MSG_MAP(PowerUpIspByTile, PPSMC_MSG_PowerUpIspByTile, 1), 106 MSG_MAP(PowerDownIspByTile, PPSMC_MSG_PowerDownIspByTile, 1), 107 }; 108 109 static struct cmn2asic_mapping smu_v13_0_4_feature_mask_map[SMU_FEATURE_COUNT] = { 110 FEA_MAP(CCLK_DPM), 111 FEA_MAP(FAN_CONTROLLER), 112 FEA_MAP(PPT), 113 FEA_MAP(TDC), 114 FEA_MAP(THERMAL), 115 FEA_MAP(VCN_DPM), 116 FEA_MAP_REVERSE(FCLK), 117 FEA_MAP_REVERSE(SOCCLK), 118 FEA_MAP(LCLK_DPM), 119 FEA_MAP(SHUBCLK_DPM), 120 FEA_MAP(DCFCLK_DPM), 121 FEA_MAP_HALF_REVERSE(GFX), 122 FEA_MAP(DS_GFXCLK), 123 FEA_MAP(DS_SOCCLK), 124 FEA_MAP(DS_LCLK), 125 FEA_MAP(DS_DCFCLK), 126 FEA_MAP(DS_FCLK), 127 FEA_MAP(DS_MP1CLK), 128 FEA_MAP(DS_MP0CLK), 129 FEA_MAP(GFX_DEM), 130 FEA_MAP(PSI), 131 FEA_MAP(PROCHOT), 132 FEA_MAP(CPUOFF), 133 FEA_MAP(STAPM), 134 FEA_MAP(S0I3), 135 FEA_MAP(PERF_LIMIT), 136 FEA_MAP(CORE_DLDO), 137 FEA_MAP(DS_VCN), 138 FEA_MAP(CPPC), 139 FEA_MAP(DF_CSTATES), 140 FEA_MAP(ATHUB_PG), 141 }; 142 143 static struct cmn2asic_mapping smu_v13_0_4_table_map[SMU_TABLE_COUNT] = { 144 TAB_MAP_VALID(WATERMARKS), 145 TAB_MAP_VALID(SMU_METRICS), 146 TAB_MAP_VALID(CUSTOM_DPM), 147 TAB_MAP_VALID(DPMCLOCKS), 148 }; 149 smu_v13_0_4_init_smc_tables(struct smu_context * smu)150 static int smu_v13_0_4_init_smc_tables(struct smu_context *smu) 151 { 152 struct smu_table_context *smu_table = &smu->smu_table; 153 struct smu_table *tables = smu_table->tables; 154 155 SMU_TABLE_INIT(tables, SMU_TABLE_WATERMARKS, sizeof(Watermarks_t), 156 PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM); 157 SMU_TABLE_INIT(tables, SMU_TABLE_DPMCLOCKS, sizeof(DpmClocks_t), 158 PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM); 159 SMU_TABLE_INIT(tables, SMU_TABLE_SMU_METRICS, sizeof(SmuMetrics_t), 160 PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM); 161 162 smu_table->clocks_table = kzalloc(sizeof(DpmClocks_t), GFP_KERNEL); 163 if (!smu_table->clocks_table) 164 goto err0_out; 165 166 smu_table->metrics_table = kzalloc(sizeof(SmuMetrics_t), GFP_KERNEL); 167 if (!smu_table->metrics_table) 168 goto err1_out; 169 smu_table->metrics_time = 0; 170 171 smu_table->watermarks_table = kzalloc(sizeof(Watermarks_t), GFP_KERNEL); 172 if (!smu_table->watermarks_table) 173 goto err2_out; 174 175 smu_table->gpu_metrics_table_size = sizeof(struct gpu_metrics_v2_1); 176 smu_table->gpu_metrics_table = kzalloc(smu_table->gpu_metrics_table_size, GFP_KERNEL); 177 if (!smu_table->gpu_metrics_table) 178 goto err3_out; 179 180 return 0; 181 182 err3_out: 183 kfree(smu_table->watermarks_table); 184 err2_out: 185 kfree(smu_table->metrics_table); 186 err1_out: 187 kfree(smu_table->clocks_table); 188 err0_out: 189 return -ENOMEM; 190 } 191 smu_v13_0_4_fini_smc_tables(struct smu_context * smu)192 static int smu_v13_0_4_fini_smc_tables(struct smu_context *smu) 193 { 194 struct smu_table_context *smu_table = &smu->smu_table; 195 196 kfree(smu_table->clocks_table); 197 smu_table->clocks_table = NULL; 198 199 kfree(smu_table->metrics_table); 200 smu_table->metrics_table = NULL; 201 202 kfree(smu_table->watermarks_table); 203 smu_table->watermarks_table = NULL; 204 205 kfree(smu_table->gpu_metrics_table); 206 smu_table->gpu_metrics_table = NULL; 207 208 return 0; 209 } 210 smu_v13_0_4_is_dpm_running(struct smu_context * smu)211 static bool smu_v13_0_4_is_dpm_running(struct smu_context *smu) 212 { 213 int ret = 0; 214 uint64_t feature_enabled; 215 216 ret = smu_cmn_get_enabled_mask(smu, &feature_enabled); 217 218 if (ret) 219 return false; 220 221 return !!(feature_enabled & SMC_DPM_FEATURE); 222 } 223 smu_v13_0_4_system_features_control(struct smu_context * smu,bool en)224 static int smu_v13_0_4_system_features_control(struct smu_context *smu, bool en) 225 { 226 struct amdgpu_device *adev = smu->adev; 227 int ret = 0; 228 229 if (!en && !adev->in_s0ix) { 230 if (adev->in_s4) { 231 /* Adds a GFX reset as workaround just before sending the 232 * MP1_UNLOAD message to prevent GC/RLC/PMFW from entering 233 * an invalid state. 234 */ 235 ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_GfxDeviceDriverReset, 236 SMU_RESET_MODE_2, NULL); 237 if (ret) 238 return ret; 239 } 240 241 ret = smu_cmn_send_smc_msg(smu, SMU_MSG_PrepareMp1ForUnload, NULL); 242 } 243 244 return ret; 245 } 246 smu_v13_0_4_get_gpu_metrics(struct smu_context * smu,void ** table)247 static ssize_t smu_v13_0_4_get_gpu_metrics(struct smu_context *smu, 248 void **table) 249 { 250 struct smu_table_context *smu_table = &smu->smu_table; 251 struct gpu_metrics_v2_1 *gpu_metrics = 252 (struct gpu_metrics_v2_1 *)smu_table->gpu_metrics_table; 253 SmuMetrics_t metrics; 254 int ret = 0; 255 256 ret = smu_cmn_get_metrics_table(smu, &metrics, true); 257 if (ret) 258 return ret; 259 260 smu_cmn_init_soft_gpu_metrics(gpu_metrics, 2, 1); 261 262 gpu_metrics->temperature_gfx = metrics.GfxTemperature; 263 gpu_metrics->temperature_soc = metrics.SocTemperature; 264 memcpy(&gpu_metrics->temperature_core[0], 265 &metrics.CoreTemperature[0], 266 sizeof(uint16_t) * 8); 267 gpu_metrics->temperature_l3[0] = metrics.L3Temperature; 268 269 gpu_metrics->average_gfx_activity = metrics.GfxActivity; 270 gpu_metrics->average_mm_activity = metrics.UvdActivity; 271 272 gpu_metrics->average_socket_power = metrics.AverageSocketPower; 273 gpu_metrics->average_gfx_power = metrics.Power[0]; 274 gpu_metrics->average_soc_power = metrics.Power[1]; 275 memcpy(&gpu_metrics->average_core_power[0], 276 &metrics.CorePower[0], 277 sizeof(uint16_t) * 8); 278 279 gpu_metrics->average_gfxclk_frequency = metrics.GfxclkFrequency; 280 gpu_metrics->average_socclk_frequency = metrics.SocclkFrequency; 281 gpu_metrics->average_uclk_frequency = metrics.MemclkFrequency; 282 gpu_metrics->average_fclk_frequency = metrics.MemclkFrequency; 283 gpu_metrics->average_vclk_frequency = metrics.VclkFrequency; 284 gpu_metrics->average_dclk_frequency = metrics.DclkFrequency; 285 286 memcpy(&gpu_metrics->current_coreclk[0], 287 &metrics.CoreFrequency[0], 288 sizeof(uint16_t) * 8); 289 gpu_metrics->current_l3clk[0] = metrics.L3Frequency; 290 291 gpu_metrics->throttle_status = metrics.ThrottlerStatus; 292 293 gpu_metrics->system_clock_counter = ktime_get_boottime_ns(); 294 295 *table = (void *)gpu_metrics; 296 297 return sizeof(struct gpu_metrics_v2_1); 298 } 299 smu_v13_0_4_get_smu_metrics_data(struct smu_context * smu,MetricsMember_t member,uint32_t * value)300 static int smu_v13_0_4_get_smu_metrics_data(struct smu_context *smu, 301 MetricsMember_t member, 302 uint32_t *value) 303 { 304 struct smu_table_context *smu_table = &smu->smu_table; 305 306 SmuMetrics_t *metrics = (SmuMetrics_t *)smu_table->metrics_table; 307 int ret = 0; 308 309 ret = smu_cmn_get_metrics_table(smu, NULL, false); 310 if (ret) 311 return ret; 312 313 switch (member) { 314 case METRICS_AVERAGE_GFXCLK: 315 *value = metrics->GfxclkFrequency; 316 break; 317 case METRICS_AVERAGE_SOCCLK: 318 *value = metrics->SocclkFrequency; 319 break; 320 case METRICS_AVERAGE_VCLK: 321 *value = metrics->VclkFrequency; 322 break; 323 case METRICS_AVERAGE_DCLK: 324 *value = metrics->DclkFrequency; 325 break; 326 case METRICS_AVERAGE_UCLK: 327 *value = metrics->MemclkFrequency; 328 break; 329 case METRICS_AVERAGE_GFXACTIVITY: 330 *value = metrics->GfxActivity / 100; 331 break; 332 case METRICS_AVERAGE_VCNACTIVITY: 333 *value = metrics->UvdActivity / 100; 334 break; 335 case METRICS_AVERAGE_SOCKETPOWER: 336 *value = (metrics->AverageSocketPower << 8) / 1000; 337 break; 338 case METRICS_CURR_SOCKETPOWER: 339 *value = (metrics->CurrentSocketPower << 8) / 1000; 340 break; 341 case METRICS_TEMPERATURE_EDGE: 342 *value = metrics->GfxTemperature / 100 * 343 SMU_TEMPERATURE_UNITS_PER_CENTIGRADES; 344 break; 345 case METRICS_TEMPERATURE_HOTSPOT: 346 *value = metrics->SocTemperature / 100 * 347 SMU_TEMPERATURE_UNITS_PER_CENTIGRADES; 348 break; 349 case METRICS_THROTTLER_STATUS: 350 *value = metrics->ThrottlerStatus; 351 break; 352 case METRICS_VOLTAGE_VDDGFX: 353 *value = metrics->Voltage[0]; 354 break; 355 case METRICS_VOLTAGE_VDDSOC: 356 *value = metrics->Voltage[1]; 357 break; 358 case METRICS_SS_APU_SHARE: 359 /* return the percentage of APU power with respect to APU's power limit. 360 * percentage is reported, this isn't boost value. Smartshift power 361 * boost/shift is only when the percentage is more than 100. 362 */ 363 if (metrics->StapmOpnLimit > 0) 364 *value = (metrics->ApuPower * 100) / metrics->StapmOpnLimit; 365 else 366 *value = 0; 367 break; 368 case METRICS_SS_DGPU_SHARE: 369 /* return the percentage of dGPU power with respect to dGPU's power limit. 370 * percentage is reported, this isn't boost value. Smartshift power 371 * boost/shift is only when the percentage is more than 100. 372 */ 373 if ((metrics->dGpuPower > 0) && 374 (metrics->StapmCurrentLimit > metrics->StapmOpnLimit)) 375 *value = (metrics->dGpuPower * 100) / 376 (metrics->StapmCurrentLimit - metrics->StapmOpnLimit); 377 else 378 *value = 0; 379 break; 380 default: 381 *value = UINT_MAX; 382 break; 383 } 384 385 return ret; 386 } 387 smu_v13_0_4_get_current_clk_freq(struct smu_context * smu,enum smu_clk_type clk_type,uint32_t * value)388 static int smu_v13_0_4_get_current_clk_freq(struct smu_context *smu, 389 enum smu_clk_type clk_type, 390 uint32_t *value) 391 { 392 MetricsMember_t member_type; 393 394 switch (clk_type) { 395 case SMU_SOCCLK: 396 member_type = METRICS_AVERAGE_SOCCLK; 397 break; 398 case SMU_VCLK: 399 member_type = METRICS_AVERAGE_VCLK; 400 break; 401 case SMU_DCLK: 402 member_type = METRICS_AVERAGE_DCLK; 403 break; 404 case SMU_MCLK: 405 member_type = METRICS_AVERAGE_UCLK; 406 break; 407 case SMU_FCLK: 408 return smu_cmn_send_smc_msg_with_param(smu, 409 SMU_MSG_GetFclkFrequency, 410 0, value); 411 case SMU_GFXCLK: 412 case SMU_SCLK: 413 return smu_cmn_send_smc_msg_with_param(smu, 414 SMU_MSG_GetGfxclkFrequency, 415 0, value); 416 break; 417 default: 418 return -EINVAL; 419 } 420 421 return smu_v13_0_4_get_smu_metrics_data(smu, member_type, value); 422 } 423 smu_v13_0_4_get_dpm_freq_by_index(struct smu_context * smu,enum smu_clk_type clk_type,uint32_t dpm_level,uint32_t * freq)424 static int smu_v13_0_4_get_dpm_freq_by_index(struct smu_context *smu, 425 enum smu_clk_type clk_type, 426 uint32_t dpm_level, 427 uint32_t *freq) 428 { 429 DpmClocks_t *clk_table = smu->smu_table.clocks_table; 430 431 if (!clk_table || clk_type >= SMU_CLK_COUNT) 432 return -EINVAL; 433 434 switch (clk_type) { 435 case SMU_SOCCLK: 436 if (dpm_level >= clk_table->NumSocClkLevelsEnabled) 437 return -EINVAL; 438 *freq = clk_table->SocClocks[dpm_level]; 439 break; 440 case SMU_VCLK: 441 if (dpm_level >= clk_table->VcnClkLevelsEnabled) 442 return -EINVAL; 443 *freq = clk_table->VClocks[dpm_level]; 444 break; 445 case SMU_DCLK: 446 if (dpm_level >= clk_table->VcnClkLevelsEnabled) 447 return -EINVAL; 448 *freq = clk_table->DClocks[dpm_level]; 449 break; 450 case SMU_UCLK: 451 case SMU_MCLK: 452 if (dpm_level >= clk_table->NumDfPstatesEnabled) 453 return -EINVAL; 454 *freq = clk_table->DfPstateTable[dpm_level].MemClk; 455 break; 456 case SMU_FCLK: 457 if (dpm_level >= clk_table->NumDfPstatesEnabled) 458 return -EINVAL; 459 *freq = clk_table->DfPstateTable[dpm_level].FClk; 460 break; 461 default: 462 return -EINVAL; 463 } 464 465 return 0; 466 } 467 smu_v13_0_4_get_dpm_level_count(struct smu_context * smu,enum smu_clk_type clk_type,uint32_t * count)468 static int smu_v13_0_4_get_dpm_level_count(struct smu_context *smu, 469 enum smu_clk_type clk_type, 470 uint32_t *count) 471 { 472 DpmClocks_t *clk_table = smu->smu_table.clocks_table; 473 474 switch (clk_type) { 475 case SMU_SOCCLK: 476 *count = clk_table->NumSocClkLevelsEnabled; 477 break; 478 case SMU_VCLK: 479 *count = clk_table->VcnClkLevelsEnabled; 480 break; 481 case SMU_DCLK: 482 *count = clk_table->VcnClkLevelsEnabled; 483 break; 484 case SMU_MCLK: 485 *count = clk_table->NumDfPstatesEnabled; 486 break; 487 case SMU_FCLK: 488 *count = clk_table->NumDfPstatesEnabled; 489 break; 490 default: 491 break; 492 } 493 494 return 0; 495 } 496 smu_v13_0_4_print_clk_levels(struct smu_context * smu,enum smu_clk_type clk_type,char * buf)497 static int smu_v13_0_4_print_clk_levels(struct smu_context *smu, 498 enum smu_clk_type clk_type, char *buf) 499 { 500 int i, idx, size = 0, ret = 0; 501 uint32_t cur_value = 0, value = 0, count = 0; 502 uint32_t min, max; 503 504 smu_cmn_get_sysfs_buf(&buf, &size); 505 506 switch (clk_type) { 507 case SMU_OD_SCLK: 508 size += sysfs_emit_at(buf, size, "%s:\n", "OD_SCLK"); 509 size += sysfs_emit_at(buf, size, "0: %10uMhz\n", 510 (smu->gfx_actual_hard_min_freq > 0) ? smu->gfx_actual_hard_min_freq : smu->gfx_default_hard_min_freq); 511 size += sysfs_emit_at(buf, size, "1: %10uMhz\n", 512 (smu->gfx_actual_soft_max_freq > 0) ? smu->gfx_actual_soft_max_freq : smu->gfx_default_soft_max_freq); 513 break; 514 case SMU_OD_RANGE: 515 size += sysfs_emit_at(buf, size, "%s:\n", "OD_RANGE"); 516 size += sysfs_emit_at(buf, size, "SCLK: %7uMhz %10uMhz\n", 517 smu->gfx_default_hard_min_freq, 518 smu->gfx_default_soft_max_freq); 519 break; 520 case SMU_SOCCLK: 521 case SMU_VCLK: 522 case SMU_DCLK: 523 case SMU_MCLK: 524 case SMU_FCLK: 525 ret = smu_v13_0_4_get_current_clk_freq(smu, clk_type, &cur_value); 526 if (ret) 527 break; 528 529 ret = smu_v13_0_4_get_dpm_level_count(smu, clk_type, &count); 530 if (ret) 531 break; 532 533 for (i = 0; i < count; i++) { 534 idx = (clk_type == SMU_FCLK || clk_type == SMU_MCLK) ? (count - i - 1) : i; 535 ret = smu_v13_0_4_get_dpm_freq_by_index(smu, clk_type, idx, &value); 536 if (ret) 537 break; 538 539 size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n", i, value, 540 cur_value == value ? "*" : ""); 541 } 542 break; 543 case SMU_GFXCLK: 544 case SMU_SCLK: 545 ret = smu_v13_0_4_get_current_clk_freq(smu, clk_type, &cur_value); 546 if (ret) 547 break; 548 min = (smu->gfx_actual_hard_min_freq > 0) ? smu->gfx_actual_hard_min_freq : smu->gfx_default_hard_min_freq; 549 max = (smu->gfx_actual_soft_max_freq > 0) ? smu->gfx_actual_soft_max_freq : smu->gfx_default_soft_max_freq; 550 if (cur_value == max) 551 i = 2; 552 else if (cur_value == min) 553 i = 0; 554 else 555 i = 1; 556 size += sysfs_emit_at(buf, size, "0: %uMhz %s\n", min, 557 i == 0 ? "*" : ""); 558 size += sysfs_emit_at(buf, size, "1: %uMhz %s\n", 559 i == 1 ? cur_value : 1100, /* UMD PSTATE GFXCLK 1100 */ 560 i == 1 ? "*" : ""); 561 size += sysfs_emit_at(buf, size, "2: %uMhz %s\n", max, 562 i == 2 ? "*" : ""); 563 break; 564 default: 565 break; 566 } 567 568 return size; 569 } 570 smu_v13_0_4_read_sensor(struct smu_context * smu,enum amd_pp_sensors sensor,void * data,uint32_t * size)571 static int smu_v13_0_4_read_sensor(struct smu_context *smu, 572 enum amd_pp_sensors sensor, 573 void *data, uint32_t *size) 574 { 575 int ret = 0; 576 577 if (!data || !size) 578 return -EINVAL; 579 580 switch (sensor) { 581 case AMDGPU_PP_SENSOR_GPU_LOAD: 582 ret = smu_v13_0_4_get_smu_metrics_data(smu, 583 METRICS_AVERAGE_GFXACTIVITY, 584 (uint32_t *)data); 585 *size = 4; 586 break; 587 case AMDGPU_PP_SENSOR_VCN_LOAD: 588 ret = smu_v13_0_4_get_smu_metrics_data(smu, 589 METRICS_AVERAGE_VCNACTIVITY, 590 (uint32_t *)data); 591 *size = 4; 592 break; 593 case AMDGPU_PP_SENSOR_GPU_AVG_POWER: 594 ret = smu_v13_0_4_get_smu_metrics_data(smu, 595 METRICS_AVERAGE_SOCKETPOWER, 596 (uint32_t *)data); 597 *size = 4; 598 break; 599 case AMDGPU_PP_SENSOR_GPU_INPUT_POWER: 600 ret = smu_v13_0_4_get_smu_metrics_data(smu, 601 METRICS_CURR_SOCKETPOWER, 602 (uint32_t *)data); 603 *size = 4; 604 break; 605 case AMDGPU_PP_SENSOR_EDGE_TEMP: 606 ret = smu_v13_0_4_get_smu_metrics_data(smu, 607 METRICS_TEMPERATURE_EDGE, 608 (uint32_t *)data); 609 *size = 4; 610 break; 611 case AMDGPU_PP_SENSOR_HOTSPOT_TEMP: 612 ret = smu_v13_0_4_get_smu_metrics_data(smu, 613 METRICS_TEMPERATURE_HOTSPOT, 614 (uint32_t *)data); 615 *size = 4; 616 break; 617 case AMDGPU_PP_SENSOR_GFX_MCLK: 618 ret = smu_v13_0_4_get_smu_metrics_data(smu, 619 METRICS_AVERAGE_UCLK, 620 (uint32_t *)data); 621 *(uint32_t *)data *= 100; 622 *size = 4; 623 break; 624 case AMDGPU_PP_SENSOR_GFX_SCLK: 625 ret = smu_v13_0_4_get_smu_metrics_data(smu, 626 METRICS_AVERAGE_GFXCLK, 627 (uint32_t *)data); 628 *(uint32_t *)data *= 100; 629 *size = 4; 630 break; 631 case AMDGPU_PP_SENSOR_VDDGFX: 632 ret = smu_v13_0_4_get_smu_metrics_data(smu, 633 METRICS_VOLTAGE_VDDGFX, 634 (uint32_t *)data); 635 *size = 4; 636 break; 637 case AMDGPU_PP_SENSOR_VDDNB: 638 ret = smu_v13_0_4_get_smu_metrics_data(smu, 639 METRICS_VOLTAGE_VDDSOC, 640 (uint32_t *)data); 641 *size = 4; 642 break; 643 case AMDGPU_PP_SENSOR_SS_APU_SHARE: 644 ret = smu_v13_0_4_get_smu_metrics_data(smu, 645 METRICS_SS_APU_SHARE, 646 (uint32_t *)data); 647 *size = 4; 648 break; 649 case AMDGPU_PP_SENSOR_SS_DGPU_SHARE: 650 ret = smu_v13_0_4_get_smu_metrics_data(smu, 651 METRICS_SS_DGPU_SHARE, 652 (uint32_t *)data); 653 *size = 4; 654 break; 655 default: 656 ret = -EOPNOTSUPP; 657 break; 658 } 659 660 return ret; 661 } 662 smu_v13_0_4_set_watermarks_table(struct smu_context * smu,struct pp_smu_wm_range_sets * clock_ranges)663 static int smu_v13_0_4_set_watermarks_table(struct smu_context *smu, 664 struct pp_smu_wm_range_sets *clock_ranges) 665 { 666 int i; 667 int ret = 0; 668 Watermarks_t *table = smu->smu_table.watermarks_table; 669 670 if (!table || !clock_ranges) 671 return -EINVAL; 672 673 if (clock_ranges->num_reader_wm_sets > NUM_WM_RANGES || 674 clock_ranges->num_writer_wm_sets > NUM_WM_RANGES) 675 return -EINVAL; 676 677 for (i = 0; i < clock_ranges->num_reader_wm_sets; i++) { 678 table->WatermarkRow[WM_DCFCLK][i].MinClock = 679 clock_ranges->reader_wm_sets[i].min_drain_clk_mhz; 680 table->WatermarkRow[WM_DCFCLK][i].MaxClock = 681 clock_ranges->reader_wm_sets[i].max_drain_clk_mhz; 682 table->WatermarkRow[WM_DCFCLK][i].MinMclk = 683 clock_ranges->reader_wm_sets[i].min_fill_clk_mhz; 684 table->WatermarkRow[WM_DCFCLK][i].MaxMclk = 685 clock_ranges->reader_wm_sets[i].max_fill_clk_mhz; 686 687 table->WatermarkRow[WM_DCFCLK][i].WmSetting = 688 clock_ranges->reader_wm_sets[i].wm_inst; 689 } 690 691 for (i = 0; i < clock_ranges->num_writer_wm_sets; i++) { 692 table->WatermarkRow[WM_SOCCLK][i].MinClock = 693 clock_ranges->writer_wm_sets[i].min_fill_clk_mhz; 694 table->WatermarkRow[WM_SOCCLK][i].MaxClock = 695 clock_ranges->writer_wm_sets[i].max_fill_clk_mhz; 696 table->WatermarkRow[WM_SOCCLK][i].MinMclk = 697 clock_ranges->writer_wm_sets[i].min_drain_clk_mhz; 698 table->WatermarkRow[WM_SOCCLK][i].MaxMclk = 699 clock_ranges->writer_wm_sets[i].max_drain_clk_mhz; 700 701 table->WatermarkRow[WM_SOCCLK][i].WmSetting = 702 clock_ranges->writer_wm_sets[i].wm_inst; 703 } 704 705 smu->watermarks_bitmap |= WATERMARKS_EXIST; 706 707 /* pass data to smu controller */ 708 if ((smu->watermarks_bitmap & WATERMARKS_EXIST) && 709 !(smu->watermarks_bitmap & WATERMARKS_LOADED)) { 710 ret = smu_cmn_write_watermarks_table(smu); 711 if (ret) { 712 dev_err(smu->adev->dev, "Failed to update WMTABLE!"); 713 return ret; 714 } 715 smu->watermarks_bitmap |= WATERMARKS_LOADED; 716 } 717 718 return 0; 719 } 720 smu_v13_0_4_clk_dpm_is_enabled(struct smu_context * smu,enum smu_clk_type clk_type)721 static bool smu_v13_0_4_clk_dpm_is_enabled(struct smu_context *smu, 722 enum smu_clk_type clk_type) 723 { 724 enum smu_feature_mask feature_id = 0; 725 726 switch (clk_type) { 727 case SMU_MCLK: 728 case SMU_UCLK: 729 case SMU_FCLK: 730 feature_id = SMU_FEATURE_DPM_FCLK_BIT; 731 break; 732 case SMU_GFXCLK: 733 case SMU_SCLK: 734 feature_id = SMU_FEATURE_DPM_GFXCLK_BIT; 735 break; 736 case SMU_SOCCLK: 737 feature_id = SMU_FEATURE_DPM_SOCCLK_BIT; 738 break; 739 case SMU_VCLK: 740 case SMU_DCLK: 741 feature_id = SMU_FEATURE_VCN_DPM_BIT; 742 break; 743 default: 744 return true; 745 } 746 747 return smu_cmn_feature_is_enabled(smu, feature_id); 748 } 749 smu_v13_0_4_get_dpm_ultimate_freq(struct smu_context * smu,enum smu_clk_type clk_type,uint32_t * min,uint32_t * max)750 static int smu_v13_0_4_get_dpm_ultimate_freq(struct smu_context *smu, 751 enum smu_clk_type clk_type, 752 uint32_t *min, 753 uint32_t *max) 754 { 755 DpmClocks_t *clk_table = smu->smu_table.clocks_table; 756 uint32_t clock_limit; 757 uint32_t max_dpm_level, min_dpm_level; 758 int ret = 0; 759 760 if (!smu_v13_0_4_clk_dpm_is_enabled(smu, clk_type)) { 761 ret = smu_v13_0_get_boot_freq_by_index(smu, clk_type, &clock_limit); 762 if (ret) 763 return ret; 764 765 /* clock in Mhz unit */ 766 if (min) 767 *min = clock_limit / 100; 768 if (max) 769 *max = clock_limit / 100; 770 771 return 0; 772 } 773 774 if (max) { 775 switch (clk_type) { 776 case SMU_GFXCLK: 777 case SMU_SCLK: 778 *max = clk_table->MaxGfxClk; 779 break; 780 case SMU_MCLK: 781 case SMU_UCLK: 782 case SMU_FCLK: 783 max_dpm_level = 0; 784 break; 785 case SMU_SOCCLK: 786 max_dpm_level = clk_table->NumSocClkLevelsEnabled - 1; 787 break; 788 case SMU_VCLK: 789 case SMU_DCLK: 790 max_dpm_level = clk_table->VcnClkLevelsEnabled - 1; 791 break; 792 default: 793 return -EINVAL; 794 } 795 796 if (clk_type != SMU_GFXCLK && clk_type != SMU_SCLK) { 797 ret = smu_v13_0_4_get_dpm_freq_by_index(smu, clk_type, 798 max_dpm_level, 799 max); 800 if (ret) 801 return ret; 802 } 803 } 804 805 if (min) { 806 switch (clk_type) { 807 case SMU_GFXCLK: 808 case SMU_SCLK: 809 *min = clk_table->MinGfxClk; 810 break; 811 case SMU_MCLK: 812 case SMU_UCLK: 813 case SMU_FCLK: 814 min_dpm_level = clk_table->NumDfPstatesEnabled - 1; 815 break; 816 case SMU_SOCCLK: 817 min_dpm_level = 0; 818 break; 819 case SMU_VCLK: 820 case SMU_DCLK: 821 min_dpm_level = 0; 822 break; 823 default: 824 return -EINVAL; 825 } 826 827 if (clk_type != SMU_GFXCLK && clk_type != SMU_SCLK) { 828 ret = smu_v13_0_4_get_dpm_freq_by_index(smu, clk_type, 829 min_dpm_level, 830 min); 831 } 832 } 833 834 return ret; 835 } 836 smu_v13_0_4_set_soft_freq_limited_range(struct smu_context * smu,enum smu_clk_type clk_type,uint32_t min,uint32_t max)837 static int smu_v13_0_4_set_soft_freq_limited_range(struct smu_context *smu, 838 enum smu_clk_type clk_type, 839 uint32_t min, 840 uint32_t max) 841 { 842 enum smu_message_type msg_set_min, msg_set_max; 843 uint32_t min_clk = min; 844 uint32_t max_clk = max; 845 int ret = 0; 846 847 if (!smu_v13_0_4_clk_dpm_is_enabled(smu, clk_type)) 848 return -EINVAL; 849 850 switch (clk_type) { 851 case SMU_GFXCLK: 852 case SMU_SCLK: 853 msg_set_min = SMU_MSG_SetHardMinGfxClk; 854 msg_set_max = SMU_MSG_SetSoftMaxGfxClk; 855 break; 856 case SMU_FCLK: 857 msg_set_min = SMU_MSG_SetHardMinFclkByFreq; 858 msg_set_max = SMU_MSG_SetSoftMaxFclkByFreq; 859 break; 860 case SMU_SOCCLK: 861 msg_set_min = SMU_MSG_SetHardMinSocclkByFreq; 862 msg_set_max = SMU_MSG_SetSoftMaxSocclkByFreq; 863 break; 864 case SMU_VCLK: 865 case SMU_DCLK: 866 msg_set_min = SMU_MSG_SetHardMinVcn; 867 msg_set_max = SMU_MSG_SetSoftMaxVcn; 868 break; 869 default: 870 return -EINVAL; 871 } 872 873 if (clk_type == SMU_VCLK) { 874 min_clk = min << SMU_13_VCLK_SHIFT; 875 max_clk = max << SMU_13_VCLK_SHIFT; 876 } 877 878 ret = smu_cmn_send_smc_msg_with_param(smu, msg_set_min, min_clk, NULL); 879 if (ret) 880 return ret; 881 882 return smu_cmn_send_smc_msg_with_param(smu, msg_set_max, 883 max_clk, NULL); 884 } 885 smu_v13_0_4_force_clk_levels(struct smu_context * smu,enum smu_clk_type clk_type,uint32_t mask)886 static int smu_v13_0_4_force_clk_levels(struct smu_context *smu, 887 enum smu_clk_type clk_type, 888 uint32_t mask) 889 { 890 uint32_t soft_min_level = 0, soft_max_level = 0; 891 uint32_t min_freq = 0, max_freq = 0; 892 int ret = 0; 893 894 soft_min_level = mask ? (ffs(mask) - 1) : 0; 895 soft_max_level = mask ? (fls(mask) - 1) : 0; 896 897 switch (clk_type) { 898 case SMU_SOCCLK: 899 case SMU_FCLK: 900 case SMU_VCLK: 901 case SMU_DCLK: 902 ret = smu_v13_0_4_get_dpm_freq_by_index(smu, clk_type, soft_min_level, &min_freq); 903 if (ret) 904 break; 905 906 ret = smu_v13_0_4_get_dpm_freq_by_index(smu, clk_type, soft_max_level, &max_freq); 907 if (ret) 908 break; 909 910 ret = smu_v13_0_4_set_soft_freq_limited_range(smu, clk_type, min_freq, max_freq); 911 break; 912 default: 913 ret = -EINVAL; 914 break; 915 } 916 917 return ret; 918 } 919 smu_v13_0_4_get_dpm_profile_freq(struct smu_context * smu,enum amd_dpm_forced_level level,enum smu_clk_type clk_type,uint32_t * min_clk,uint32_t * max_clk)920 static int smu_v13_0_4_get_dpm_profile_freq(struct smu_context *smu, 921 enum amd_dpm_forced_level level, 922 enum smu_clk_type clk_type, 923 uint32_t *min_clk, 924 uint32_t *max_clk) 925 { 926 int ret = 0; 927 uint32_t clk_limit = 0; 928 929 switch (clk_type) { 930 case SMU_GFXCLK: 931 case SMU_SCLK: 932 clk_limit = SMU_13_0_4_UMD_PSTATE_GFXCLK; 933 if (level == AMD_DPM_FORCED_LEVEL_PROFILE_PEAK) 934 smu_v13_0_4_get_dpm_ultimate_freq(smu, SMU_SCLK, NULL, &clk_limit); 935 else if (level == AMD_DPM_FORCED_LEVEL_PROFILE_MIN_SCLK) 936 smu_v13_0_4_get_dpm_ultimate_freq(smu, SMU_SCLK, &clk_limit, NULL); 937 break; 938 case SMU_SOCCLK: 939 clk_limit = SMU_13_0_4_UMD_PSTATE_SOCCLK; 940 if (level == AMD_DPM_FORCED_LEVEL_PROFILE_PEAK) 941 smu_v13_0_4_get_dpm_ultimate_freq(smu, SMU_SOCCLK, NULL, &clk_limit); 942 break; 943 case SMU_FCLK: 944 clk_limit = SMU_13_0_4_UMD_PSTATE_FCLK; 945 if (level == AMD_DPM_FORCED_LEVEL_PROFILE_PEAK) 946 smu_v13_0_4_get_dpm_ultimate_freq(smu, SMU_FCLK, NULL, &clk_limit); 947 else if (level == AMD_DPM_FORCED_LEVEL_PROFILE_MIN_MCLK) 948 smu_v13_0_4_get_dpm_ultimate_freq(smu, SMU_FCLK, &clk_limit, NULL); 949 break; 950 case SMU_VCLK: 951 smu_v13_0_4_get_dpm_ultimate_freq(smu, SMU_VCLK, NULL, &clk_limit); 952 break; 953 case SMU_DCLK: 954 smu_v13_0_4_get_dpm_ultimate_freq(smu, SMU_DCLK, NULL, &clk_limit); 955 break; 956 default: 957 ret = -EINVAL; 958 break; 959 } 960 *min_clk = *max_clk = clk_limit; 961 return ret; 962 } 963 smu_v13_0_4_set_performance_level(struct smu_context * smu,enum amd_dpm_forced_level level)964 static int smu_v13_0_4_set_performance_level(struct smu_context *smu, 965 enum amd_dpm_forced_level level) 966 { 967 struct amdgpu_device *adev = smu->adev; 968 uint32_t sclk_min = 0, sclk_max = 0; 969 uint32_t fclk_min = 0, fclk_max = 0; 970 uint32_t socclk_min = 0, socclk_max = 0; 971 uint32_t vclk_min = 0, vclk_max = 0; 972 uint32_t dclk_min = 0, dclk_max = 0; 973 int ret = 0; 974 975 switch (level) { 976 case AMD_DPM_FORCED_LEVEL_HIGH: 977 smu_v13_0_4_get_dpm_ultimate_freq(smu, SMU_SCLK, NULL, &sclk_max); 978 smu_v13_0_4_get_dpm_ultimate_freq(smu, SMU_FCLK, NULL, &fclk_max); 979 smu_v13_0_4_get_dpm_ultimate_freq(smu, SMU_SOCCLK, NULL, &socclk_max); 980 smu_v13_0_4_get_dpm_ultimate_freq(smu, SMU_VCLK, NULL, &vclk_max); 981 smu_v13_0_4_get_dpm_ultimate_freq(smu, SMU_DCLK, NULL, &dclk_max); 982 sclk_min = sclk_max; 983 fclk_min = fclk_max; 984 socclk_min = socclk_max; 985 vclk_min = vclk_max; 986 dclk_min = dclk_max; 987 break; 988 case AMD_DPM_FORCED_LEVEL_LOW: 989 smu_v13_0_4_get_dpm_ultimate_freq(smu, SMU_SCLK, &sclk_min, NULL); 990 smu_v13_0_4_get_dpm_ultimate_freq(smu, SMU_FCLK, &fclk_min, NULL); 991 smu_v13_0_4_get_dpm_ultimate_freq(smu, SMU_SOCCLK, &socclk_min, NULL); 992 smu_v13_0_4_get_dpm_ultimate_freq(smu, SMU_VCLK, &vclk_min, NULL); 993 smu_v13_0_4_get_dpm_ultimate_freq(smu, SMU_DCLK, &dclk_min, NULL); 994 sclk_max = sclk_min; 995 fclk_max = fclk_min; 996 socclk_max = socclk_min; 997 vclk_max = vclk_min; 998 dclk_max = dclk_min; 999 break; 1000 case AMD_DPM_FORCED_LEVEL_AUTO: 1001 smu_v13_0_4_get_dpm_ultimate_freq(smu, SMU_SCLK, &sclk_min, &sclk_max); 1002 smu_v13_0_4_get_dpm_ultimate_freq(smu, SMU_FCLK, &fclk_min, &fclk_max); 1003 smu_v13_0_4_get_dpm_ultimate_freq(smu, SMU_SOCCLK, &socclk_min, &socclk_max); 1004 smu_v13_0_4_get_dpm_ultimate_freq(smu, SMU_VCLK, &vclk_min, &vclk_max); 1005 smu_v13_0_4_get_dpm_ultimate_freq(smu, SMU_DCLK, &dclk_min, &dclk_max); 1006 break; 1007 case AMD_DPM_FORCED_LEVEL_PROFILE_STANDARD: 1008 case AMD_DPM_FORCED_LEVEL_PROFILE_MIN_SCLK: 1009 case AMD_DPM_FORCED_LEVEL_PROFILE_MIN_MCLK: 1010 case AMD_DPM_FORCED_LEVEL_PROFILE_PEAK: 1011 smu_v13_0_4_get_dpm_profile_freq(smu, level, SMU_SCLK, &sclk_min, &sclk_max); 1012 smu_v13_0_4_get_dpm_profile_freq(smu, level, SMU_FCLK, &fclk_min, &fclk_max); 1013 smu_v13_0_4_get_dpm_profile_freq(smu, level, SMU_SOCCLK, &socclk_min, &socclk_max); 1014 smu_v13_0_4_get_dpm_profile_freq(smu, level, SMU_VCLK, &vclk_min, &vclk_max); 1015 smu_v13_0_4_get_dpm_profile_freq(smu, level, SMU_DCLK, &dclk_min, &dclk_max); 1016 break; 1017 case AMD_DPM_FORCED_LEVEL_MANUAL: 1018 case AMD_DPM_FORCED_LEVEL_PROFILE_EXIT: 1019 return 0; 1020 default: 1021 dev_err(adev->dev, "Invalid performance level %d\n", level); 1022 return -EINVAL; 1023 } 1024 1025 if (sclk_min && sclk_max) { 1026 ret = smu_v13_0_4_set_soft_freq_limited_range(smu, 1027 SMU_SCLK, 1028 sclk_min, 1029 sclk_max); 1030 if (ret) 1031 return ret; 1032 1033 smu->gfx_actual_hard_min_freq = sclk_min; 1034 smu->gfx_actual_soft_max_freq = sclk_max; 1035 } 1036 1037 if (fclk_min && fclk_max) { 1038 ret = smu_v13_0_4_set_soft_freq_limited_range(smu, 1039 SMU_FCLK, 1040 fclk_min, 1041 fclk_max); 1042 if (ret) 1043 return ret; 1044 } 1045 1046 if (socclk_min && socclk_max) { 1047 ret = smu_v13_0_4_set_soft_freq_limited_range(smu, 1048 SMU_SOCCLK, 1049 socclk_min, 1050 socclk_max); 1051 if (ret) 1052 return ret; 1053 } 1054 1055 if (vclk_min && vclk_max) { 1056 ret = smu_v13_0_4_set_soft_freq_limited_range(smu, 1057 SMU_VCLK, 1058 vclk_min, 1059 vclk_max); 1060 if (ret) 1061 return ret; 1062 } 1063 1064 if (dclk_min && dclk_max) { 1065 ret = smu_v13_0_4_set_soft_freq_limited_range(smu, 1066 SMU_DCLK, 1067 dclk_min, 1068 dclk_max); 1069 if (ret) 1070 return ret; 1071 } 1072 return ret; 1073 } 1074 smu_v13_0_4_mode2_reset(struct smu_context * smu)1075 static int smu_v13_0_4_mode2_reset(struct smu_context *smu) 1076 { 1077 return smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_GfxDeviceDriverReset, 1078 SMU_RESET_MODE_2, NULL); 1079 } 1080 smu_v13_0_4_set_fine_grain_gfx_freq_parameters(struct smu_context * smu)1081 static int smu_v13_0_4_set_fine_grain_gfx_freq_parameters(struct smu_context *smu) 1082 { 1083 DpmClocks_t *clk_table = smu->smu_table.clocks_table; 1084 1085 smu->gfx_default_hard_min_freq = clk_table->MinGfxClk; 1086 smu->gfx_default_soft_max_freq = clk_table->MaxGfxClk; 1087 smu->gfx_actual_hard_min_freq = 0; 1088 smu->gfx_actual_soft_max_freq = 0; 1089 1090 return 0; 1091 } 1092 1093 static const struct pptable_funcs smu_v13_0_4_ppt_funcs = { 1094 .check_fw_status = smu_v13_0_check_fw_status, 1095 .check_fw_version = smu_v13_0_check_fw_version, 1096 .init_smc_tables = smu_v13_0_4_init_smc_tables, 1097 .fini_smc_tables = smu_v13_0_4_fini_smc_tables, 1098 .get_vbios_bootup_values = smu_v13_0_get_vbios_bootup_values, 1099 .system_features_control = smu_v13_0_4_system_features_control, 1100 .send_smc_msg_with_param = smu_cmn_send_smc_msg_with_param, 1101 .send_smc_msg = smu_cmn_send_smc_msg, 1102 .dpm_set_vcn_enable = smu_v13_0_set_vcn_enable, 1103 .dpm_set_jpeg_enable = smu_v13_0_set_jpeg_enable, 1104 .set_default_dpm_table = smu_v13_0_set_default_dpm_tables, 1105 .read_sensor = smu_v13_0_4_read_sensor, 1106 .is_dpm_running = smu_v13_0_4_is_dpm_running, 1107 .set_watermarks_table = smu_v13_0_4_set_watermarks_table, 1108 .get_gpu_metrics = smu_v13_0_4_get_gpu_metrics, 1109 .get_enabled_mask = smu_cmn_get_enabled_mask, 1110 .get_pp_feature_mask = smu_cmn_get_pp_feature_mask, 1111 .set_driver_table_location = smu_v13_0_set_driver_table_location, 1112 .gfx_off_control = smu_v13_0_gfx_off_control, 1113 .mode2_reset = smu_v13_0_4_mode2_reset, 1114 .get_dpm_ultimate_freq = smu_v13_0_4_get_dpm_ultimate_freq, 1115 .od_edit_dpm_table = smu_v13_0_od_edit_dpm_table, 1116 .print_clk_levels = smu_v13_0_4_print_clk_levels, 1117 .force_clk_levels = smu_v13_0_4_force_clk_levels, 1118 .set_performance_level = smu_v13_0_4_set_performance_level, 1119 .set_fine_grain_gfx_freq_parameters = smu_v13_0_4_set_fine_grain_gfx_freq_parameters, 1120 .set_gfx_power_up_by_imu = smu_v13_0_set_gfx_power_up_by_imu, 1121 }; 1122 smu_v13_0_4_set_smu_mailbox_registers(struct smu_context * smu)1123 static void smu_v13_0_4_set_smu_mailbox_registers(struct smu_context *smu) 1124 { 1125 struct amdgpu_device *adev = smu->adev; 1126 1127 smu->param_reg = SOC15_REG_OFFSET(MP1, 0, mmMP1_SMN_C2PMSG_82); 1128 smu->msg_reg = SOC15_REG_OFFSET(MP1, 0, mmMP1_SMN_C2PMSG_66); 1129 smu->resp_reg = SOC15_REG_OFFSET(MP1, 0, mmMP1_SMN_C2PMSG_90); 1130 } 1131 smu_v13_0_4_set_ppt_funcs(struct smu_context * smu)1132 void smu_v13_0_4_set_ppt_funcs(struct smu_context *smu) 1133 { 1134 struct amdgpu_device *adev = smu->adev; 1135 1136 smu->ppt_funcs = &smu_v13_0_4_ppt_funcs; 1137 smu->message_map = smu_v13_0_4_message_map; 1138 smu->feature_map = smu_v13_0_4_feature_mask_map; 1139 smu->table_map = smu_v13_0_4_table_map; 1140 smu->smc_driver_if_version = SMU13_0_4_DRIVER_IF_VERSION; 1141 smu->is_apu = true; 1142 1143 if (amdgpu_ip_version(adev, MP1_HWIP, 0) == IP_VERSION(13, 0, 4)) 1144 smu_v13_0_4_set_smu_mailbox_registers(smu); 1145 else 1146 smu_v13_0_set_smu_mailbox_registers(smu); 1147 } 1148