FILE
smu_v13_0_4_ppt.c
File preview with syntax highlighting.
linux-6.19.14/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_4_ppt.c
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 74static 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 109static 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 143static 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 150static 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 182err3_out: 183 kfree(smu_table->watermarks_table); 184err2_out: 185 kfree(smu_table->metrics_table); 186err1_out: 187 kfree(smu_table->clocks_table); 188err0_out: 189 return -ENOMEM; 190} 191 192static 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 211static 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 224static 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 247static 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 300static 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 388static 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 424static 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 468static 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 497static 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, start_offset = 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 start_offset = size; 506 507 switch (clk_type) { 508 case SMU_OD_SCLK: 509 size += sysfs_emit_at(buf, size, "%s:\n", "OD_SCLK"); 510 size += sysfs_emit_at(buf, size, "0: %10uMhz\n", 511 (smu->gfx_actual_hard_min_freq > 0) ? smu->gfx_actual_hard_min_freq : smu->gfx_default_hard_min_freq); 512 size += sysfs_emit_at(buf, size, "1: %10uMhz\n", 513 (smu->gfx_actual_soft_max_freq > 0) ? smu->gfx_actual_soft_max_freq : smu->gfx_default_soft_max_freq); 514 break; 515 case SMU_OD_RANGE: 516 size += sysfs_emit_at(buf, size, "%s:\n", "OD_RANGE"); 517 size += sysfs_emit_at(buf, size, "SCLK: %7uMhz %10uMhz\n", 518 smu->gfx_default_hard_min_freq, 519 smu->gfx_default_soft_max_freq); 520 break; 521 case SMU_SOCCLK: 522 case SMU_VCLK: 523 case SMU_DCLK: 524 case SMU_MCLK: 525 case SMU_FCLK: 526 ret = smu_v13_0_4_get_current_clk_freq(smu, clk_type, &cur_value); 527 if (ret) 528 break; 529 530 ret = smu_v13_0_4_get_dpm_level_count(smu, clk_type, &count); 531 if (ret) 532 break; 533 534 for (i = 0; i < count; i++) { 535 idx = (clk_type == SMU_FCLK || clk_type == SMU_MCLK) ? (count - i - 1) : i; 536 ret = smu_v13_0_4_get_dpm_freq_by_index(smu, clk_type, idx, &value); 537 if (ret) 538 break; 539 540 size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n", i, value, 541 cur_value == value ? "*" : ""); 542 } 543 break; 544 case SMU_GFXCLK: 545 case SMU_SCLK: 546 ret = smu_v13_0_4_get_current_clk_freq(smu, clk_type, &cur_value); 547 if (ret) 548 break; 549 min = (smu->gfx_actual_hard_min_freq > 0) ? smu->gfx_actual_hard_min_freq : smu->gfx_default_hard_min_freq; 550 max = (smu->gfx_actual_soft_max_freq > 0) ? smu->gfx_actual_soft_max_freq : smu->gfx_default_soft_max_freq; 551 if (cur_value == max) 552 i = 2; 553 else if (cur_value == min) 554 i = 0; 555 else 556 i = 1; 557 size += sysfs_emit_at(buf, size, "0: %uMhz %s\n", min, 558 i == 0 ? "*" : ""); 559 size += sysfs_emit_at(buf, size, "1: %uMhz %s\n", 560 i == 1 ? cur_value : 1100, /* UMD PSTATE GFXCLK 1100 */ 561 i == 1 ? "*" : ""); 562 size += sysfs_emit_at(buf, size, "2: %uMhz %s\n", max, 563 i == 2 ? "*" : ""); 564 break; 565 default: 566 break; 567 } 568 569 return size - start_offset; 570} 571 572static int smu_v13_0_4_read_sensor(struct smu_context *smu, 573 enum amd_pp_sensors sensor, 574 void *data, uint32_t *size) 575{ 576 int ret = 0; 577 578 if (!data || !size) 579 return -EINVAL; 580 581 switch (sensor) { 582 case AMDGPU_PP_SENSOR_GPU_LOAD: 583 ret = smu_v13_0_4_get_smu_metrics_data(smu, 584 METRICS_AVERAGE_GFXACTIVITY, 585 (uint32_t *)data); 586 *size = 4; 587 break; 588 case AMDGPU_PP_SENSOR_VCN_LOAD: 589 ret = smu_v13_0_4_get_smu_metrics_data(smu, 590 METRICS_AVERAGE_VCNACTIVITY, 591 (uint32_t *)data); 592 *size = 4; 593 break; 594 case AMDGPU_PP_SENSOR_GPU_AVG_POWER: 595 ret = smu_v13_0_4_get_smu_metrics_data(smu, 596 METRICS_AVERAGE_SOCKETPOWER, 597 (uint32_t *)data); 598 *size = 4; 599 break; 600 case AMDGPU_PP_SENSOR_GPU_INPUT_POWER: 601 ret = smu_v13_0_4_get_smu_metrics_data(smu, 602 METRICS_CURR_SOCKETPOWER, 603 (uint32_t *)data); 604 *size = 4; 605 break; 606 case AMDGPU_PP_SENSOR_EDGE_TEMP: 607 ret = smu_v13_0_4_get_smu_metrics_data(smu, 608 METRICS_TEMPERATURE_EDGE, 609 (uint32_t *)data); 610 *size = 4; 611 break; 612 case AMDGPU_PP_SENSOR_HOTSPOT_TEMP: 613 ret = smu_v13_0_4_get_smu_metrics_data(smu, 614 METRICS_TEMPERATURE_HOTSPOT, 615 (uint32_t *)data); 616 *size = 4; 617 break; 618 case AMDGPU_PP_SENSOR_GFX_MCLK: 619 ret = smu_v13_0_4_get_smu_metrics_data(smu, 620 METRICS_AVERAGE_UCLK, 621 (uint32_t *)data); 622 *(uint32_t *)data *= 100; 623 *size = 4; 624 break; 625 case AMDGPU_PP_SENSOR_GFX_SCLK: 626 ret = smu_v13_0_4_get_smu_metrics_data(smu, 627 METRICS_AVERAGE_GFXCLK, 628 (uint32_t *)data); 629 *(uint32_t *)data *= 100; 630 *size = 4; 631 break; 632 case AMDGPU_PP_SENSOR_VDDGFX: 633 ret = smu_v13_0_4_get_smu_metrics_data(smu, 634 METRICS_VOLTAGE_VDDGFX, 635 (uint32_t *)data); 636 *size = 4; 637 break; 638 case AMDGPU_PP_SENSOR_VDDNB: 639 ret = smu_v13_0_4_get_smu_metrics_data(smu, 640 METRICS_VOLTAGE_VDDSOC, 641 (uint32_t *)data); 642 *size = 4; 643 break; 644 case AMDGPU_PP_SENSOR_SS_APU_SHARE: 645 ret = smu_v13_0_4_get_smu_metrics_data(smu, 646 METRICS_SS_APU_SHARE, 647 (uint32_t *)data); 648 *size = 4; 649 break; 650 case AMDGPU_PP_SENSOR_SS_DGPU_SHARE: 651 ret = smu_v13_0_4_get_smu_metrics_data(smu, 652 METRICS_SS_DGPU_SHARE, 653 (uint32_t *)data); 654 *size = 4; 655 break; 656 default: 657 ret = -EOPNOTSUPP; 658 break; 659 } 660 661 return ret; 662} 663 664static int smu_v13_0_4_set_watermarks_table(struct smu_context *smu, 665 struct pp_smu_wm_range_sets *clock_ranges) 666{ 667 int i; 668 int ret = 0; 669 Watermarks_t *table = smu->smu_table.watermarks_table; 670 671 if (!table || !clock_ranges) 672 return -EINVAL; 673 674 if (clock_ranges->num_reader_wm_sets > NUM_WM_RANGES || 675 clock_ranges->num_writer_wm_sets > NUM_WM_RANGES) 676 return -EINVAL; 677 678 for (i = 0; i < clock_ranges->num_reader_wm_sets; i++) { 679 table->WatermarkRow[WM_DCFCLK][i].MinClock = 680 clock_ranges->reader_wm_sets[i].min_drain_clk_mhz; 681 table->WatermarkRow[WM_DCFCLK][i].MaxClock = 682 clock_ranges->reader_wm_sets[i].max_drain_clk_mhz; 683 table->WatermarkRow[WM_DCFCLK][i].MinMclk = 684 clock_ranges->reader_wm_sets[i].min_fill_clk_mhz; 685 table->WatermarkRow[WM_DCFCLK][i].MaxMclk = 686 clock_ranges->reader_wm_sets[i].max_fill_clk_mhz; 687 688 table->WatermarkRow[WM_DCFCLK][i].WmSetting = 689 clock_ranges->reader_wm_sets[i].wm_inst; 690 } 691 692 for (i = 0; i < clock_ranges->num_writer_wm_sets; i++) { 693 table->WatermarkRow[WM_SOCCLK][i].MinClock = 694 clock_ranges->writer_wm_sets[i].min_fill_clk_mhz; 695 table->WatermarkRow[WM_SOCCLK][i].MaxClock = 696 clock_ranges->writer_wm_sets[i].max_fill_clk_mhz; 697 table->WatermarkRow[WM_SOCCLK][i].MinMclk = 698 clock_ranges->writer_wm_sets[i].min_drain_clk_mhz; 699 table->WatermarkRow[WM_SOCCLK][i].MaxMclk = 700 clock_ranges->writer_wm_sets[i].max_drain_clk_mhz; 701 702 table->WatermarkRow[WM_SOCCLK][i].WmSetting = 703 clock_ranges->writer_wm_sets[i].wm_inst; 704 } 705 706 smu->watermarks_bitmap |= WATERMARKS_EXIST; 707 708 /* pass data to smu controller */ 709 if ((smu->watermarks_bitmap & WATERMARKS_EXIST) && 710 !(smu->watermarks_bitmap & WATERMARKS_LOADED)) { 711 ret = smu_cmn_write_watermarks_table(smu); 712 if (ret) { 713 dev_err(smu->adev->dev, "Failed to update WMTABLE!"); 714 return ret; 715 } 716 smu->watermarks_bitmap |= WATERMARKS_LOADED; 717 } 718 719 return 0; 720} 721 722static bool smu_v13_0_4_clk_dpm_is_enabled(struct smu_context *smu, 723 enum smu_clk_type clk_type) 724{ 725 enum smu_feature_mask feature_id = 0; 726 727 switch (clk_type) { 728 case SMU_MCLK: 729 case SMU_UCLK: 730 case SMU_FCLK: 731 feature_id = SMU_FEATURE_DPM_FCLK_BIT; 732 break; 733 case SMU_GFXCLK: 734 case SMU_SCLK: 735 feature_id = SMU_FEATURE_DPM_GFXCLK_BIT; 736 break; 737 case SMU_SOCCLK: 738 feature_id = SMU_FEATURE_DPM_SOCCLK_BIT; 739 break; 740 case SMU_VCLK: 741 case SMU_DCLK: 742 feature_id = SMU_FEATURE_VCN_DPM_BIT; 743 break; 744 default: 745 return true; 746 } 747 748 return smu_cmn_feature_is_enabled(smu, feature_id); 749} 750 751static int smu_v13_0_4_get_dpm_ultimate_freq(struct smu_context *smu, 752 enum smu_clk_type clk_type, 753 uint32_t *min, 754 uint32_t *max) 755{ 756 DpmClocks_t *clk_table = smu->smu_table.clocks_table; 757 uint32_t clock_limit; 758 uint32_t max_dpm_level, min_dpm_level; 759 int ret = 0; 760 761 if (!smu_v13_0_4_clk_dpm_is_enabled(smu, clk_type)) { 762 ret = smu_v13_0_get_boot_freq_by_index(smu, clk_type, &clock_limit); 763 if (ret) 764 return ret; 765 766 /* clock in Mhz unit */ 767 if (min) 768 *min = clock_limit / 100; 769 if (max) 770 *max = clock_limit / 100; 771 772 return 0; 773 } 774 775 if (max) { 776 switch (clk_type) { 777 case SMU_GFXCLK: 778 case SMU_SCLK: 779 *max = clk_table->MaxGfxClk; 780 break; 781 case SMU_MCLK: 782 case SMU_UCLK: 783 case SMU_FCLK: 784 max_dpm_level = 0; 785 break; 786 case SMU_SOCCLK: 787 max_dpm_level = clk_table->NumSocClkLevelsEnabled - 1; 788 break; 789 case SMU_VCLK: 790 case SMU_DCLK: 791 max_dpm_level = clk_table->VcnClkLevelsEnabled - 1; 792 break; 793 default: 794 return -EINVAL; 795 } 796 797 if (clk_type != SMU_GFXCLK && clk_type != SMU_SCLK) { 798 ret = smu_v13_0_4_get_dpm_freq_by_index(smu, clk_type, 799 max_dpm_level, 800 max); 801 if (ret) 802 return ret; 803 } 804 } 805 806 if (min) { 807 switch (clk_type) { 808 case SMU_GFXCLK: 809 case SMU_SCLK: 810 *min = clk_table->MinGfxClk; 811 break; 812 case SMU_MCLK: 813 case SMU_UCLK: 814 case SMU_FCLK: 815 min_dpm_level = clk_table->NumDfPstatesEnabled - 1; 816 break; 817 case SMU_SOCCLK: 818 min_dpm_level = 0; 819 break; 820 case SMU_VCLK: 821 case SMU_DCLK: 822 min_dpm_level = 0; 823 break; 824 default: 825 return -EINVAL; 826 } 827 828 if (clk_type != SMU_GFXCLK && clk_type != SMU_SCLK) { 829 ret = smu_v13_0_4_get_dpm_freq_by_index(smu, clk_type, 830 min_dpm_level, 831 min); 832 } 833 } 834 835 return ret; 836} 837 838static int smu_v13_0_4_set_soft_freq_limited_range(struct smu_context *smu, 839 enum smu_clk_type clk_type, 840 uint32_t min, 841 uint32_t max) 842{ 843 enum smu_message_type msg_set_min, msg_set_max; 844 uint32_t min_clk = min; 845 uint32_t max_clk = max; 846 int ret = 0; 847 848 if (!smu_v13_0_4_clk_dpm_is_enabled(smu, clk_type)) 849 return -EINVAL; 850 851 switch (clk_type) { 852 case SMU_GFXCLK: 853 case SMU_SCLK: 854 msg_set_min = SMU_MSG_SetHardMinGfxClk; 855 msg_set_max = SMU_MSG_SetSoftMaxGfxClk; 856 break; 857 case SMU_FCLK: 858 msg_set_min = SMU_MSG_SetHardMinFclkByFreq; 859 msg_set_max = SMU_MSG_SetSoftMaxFclkByFreq; 860 break; 861 case SMU_SOCCLK: 862 msg_set_min = SMU_MSG_SetHardMinSocclkByFreq; 863 msg_set_max = SMU_MSG_SetSoftMaxSocclkByFreq; 864 break; 865 case SMU_VCLK: 866 case SMU_DCLK: 867 msg_set_min = SMU_MSG_SetHardMinVcn; 868 msg_set_max = SMU_MSG_SetSoftMaxVcn; 869 break; 870 default: 871 return -EINVAL; 872 } 873 874 if (clk_type == SMU_VCLK) { 875 min_clk = min << SMU_13_VCLK_SHIFT; 876 max_clk = max << SMU_13_VCLK_SHIFT; 877 } 878 879 ret = smu_cmn_send_smc_msg_with_param(smu, msg_set_min, min_clk, NULL); 880 if (ret) 881 return ret; 882 883 return smu_cmn_send_smc_msg_with_param(smu, msg_set_max, 884 max_clk, NULL); 885} 886 887static int smu_v13_0_4_force_clk_levels(struct smu_context *smu, 888 enum smu_clk_type clk_type, 889 uint32_t mask) 890{ 891 uint32_t soft_min_level = 0, soft_max_level = 0; 892 uint32_t min_freq = 0, max_freq = 0; 893 int ret = 0; 894 895 soft_min_level = mask ? (ffs(mask) - 1) : 0; 896 soft_max_level = mask ? (fls(mask) - 1) : 0; 897 898 switch (clk_type) { 899 case SMU_SOCCLK: 900 case SMU_FCLK: 901 case SMU_VCLK: 902 case SMU_DCLK: 903 ret = smu_v13_0_4_get_dpm_freq_by_index(smu, clk_type, soft_min_level, &min_freq); 904 if (ret) 905 break; 906 907 ret = smu_v13_0_4_get_dpm_freq_by_index(smu, clk_type, soft_max_level, &max_freq); 908 if (ret) 909 break; 910 911 ret = smu_v13_0_4_set_soft_freq_limited_range(smu, clk_type, min_freq, max_freq); 912 break; 913 default: 914 ret = -EINVAL; 915 break; 916 } 917 918 return ret; 919} 920 921static int smu_v13_0_4_get_dpm_profile_freq(struct smu_context *smu, 922 enum amd_dpm_forced_level level, 923 enum smu_clk_type clk_type, 924 uint32_t *min_clk, 925 uint32_t *max_clk) 926{ 927 int ret = 0; 928 uint32_t clk_limit = 0; 929 930 switch (clk_type) { 931 case SMU_GFXCLK: 932 case SMU_SCLK: 933 clk_limit = SMU_13_0_4_UMD_PSTATE_GFXCLK; 934 if (level == AMD_DPM_FORCED_LEVEL_PROFILE_PEAK) 935 smu_v13_0_4_get_dpm_ultimate_freq(smu, SMU_SCLK, NULL, &clk_limit); 936 else if (level == AMD_DPM_FORCED_LEVEL_PROFILE_MIN_SCLK) 937 smu_v13_0_4_get_dpm_ultimate_freq(smu, SMU_SCLK, &clk_limit, NULL); 938 break; 939 case SMU_SOCCLK: 940 clk_limit = SMU_13_0_4_UMD_PSTATE_SOCCLK; 941 if (level == AMD_DPM_FORCED_LEVEL_PROFILE_PEAK) 942 smu_v13_0_4_get_dpm_ultimate_freq(smu, SMU_SOCCLK, NULL, &clk_limit); 943 break; 944 case SMU_FCLK: 945 clk_limit = SMU_13_0_4_UMD_PSTATE_FCLK; 946 if (level == AMD_DPM_FORCED_LEVEL_PROFILE_PEAK) 947 smu_v13_0_4_get_dpm_ultimate_freq(smu, SMU_FCLK, NULL, &clk_limit); 948 else if (level == AMD_DPM_FORCED_LEVEL_PROFILE_MIN_MCLK) 949 smu_v13_0_4_get_dpm_ultimate_freq(smu, SMU_FCLK, &clk_limit, NULL); 950 break; 951 case SMU_VCLK: 952 smu_v13_0_4_get_dpm_ultimate_freq(smu, SMU_VCLK, NULL, &clk_limit); 953 break; 954 case SMU_DCLK: 955 smu_v13_0_4_get_dpm_ultimate_freq(smu, SMU_DCLK, NULL, &clk_limit); 956 break; 957 default: 958 ret = -EINVAL; 959 break; 960 } 961 *min_clk = *max_clk = clk_limit; 962 return ret; 963} 964 965static int smu_v13_0_4_set_performance_level(struct smu_context *smu, 966 enum amd_dpm_forced_level level) 967{ 968 struct amdgpu_device *adev = smu->adev; 969 uint32_t sclk_min = 0, sclk_max = 0; 970 uint32_t fclk_min = 0, fclk_max = 0; 971 uint32_t socclk_min = 0, socclk_max = 0; 972 uint32_t vclk_min = 0, vclk_max = 0; 973 uint32_t dclk_min = 0, dclk_max = 0; 974 int ret = 0; 975 976 switch (level) { 977 case AMD_DPM_FORCED_LEVEL_HIGH: 978 smu_v13_0_4_get_dpm_ultimate_freq(smu, SMU_SCLK, NULL, &sclk_max); 979 smu_v13_0_4_get_dpm_ultimate_freq(smu, SMU_FCLK, NULL, &fclk_max); 980 smu_v13_0_4_get_dpm_ultimate_freq(smu, SMU_SOCCLK, NULL, &socclk_max); 981 smu_v13_0_4_get_dpm_ultimate_freq(smu, SMU_VCLK, NULL, &vclk_max); 982 smu_v13_0_4_get_dpm_ultimate_freq(smu, SMU_DCLK, NULL, &dclk_max); 983 sclk_min = sclk_max; 984 fclk_min = fclk_max; 985 socclk_min = socclk_max; 986 vclk_min = vclk_max; 987 dclk_min = dclk_max; 988 break; 989 case AMD_DPM_FORCED_LEVEL_LOW: 990 smu_v13_0_4_get_dpm_ultimate_freq(smu, SMU_SCLK, &sclk_min, NULL); 991 smu_v13_0_4_get_dpm_ultimate_freq(smu, SMU_FCLK, &fclk_min, NULL); 992 smu_v13_0_4_get_dpm_ultimate_freq(smu, SMU_SOCCLK, &socclk_min, NULL); 993 smu_v13_0_4_get_dpm_ultimate_freq(smu, SMU_VCLK, &vclk_min, NULL); 994 smu_v13_0_4_get_dpm_ultimate_freq(smu, SMU_DCLK, &dclk_min, NULL); 995 sclk_max = sclk_min; 996 fclk_max = fclk_min; 997 socclk_max = socclk_min; 998 vclk_max = vclk_min; 999 dclk_max = dclk_min; 1000 break; 1001 case AMD_DPM_FORCED_LEVEL_AUTO: 1002 smu_v13_0_4_get_dpm_ultimate_freq(smu, SMU_SCLK, &sclk_min, &sclk_max); 1003 smu_v13_0_4_get_dpm_ultimate_freq(smu, SMU_FCLK, &fclk_min, &fclk_max); 1004 smu_v13_0_4_get_dpm_ultimate_freq(smu, SMU_SOCCLK, &socclk_min, &socclk_max); 1005 smu_v13_0_4_get_dpm_ultimate_freq(smu, SMU_VCLK, &vclk_min, &vclk_max); 1006 smu_v13_0_4_get_dpm_ultimate_freq(smu, SMU_DCLK, &dclk_min, &dclk_max); 1007 break; 1008 case AMD_DPM_FORCED_LEVEL_PROFILE_STANDARD: 1009 case AMD_DPM_FORCED_LEVEL_PROFILE_MIN_SCLK: 1010 case AMD_DPM_FORCED_LEVEL_PROFILE_MIN_MCLK: 1011 case AMD_DPM_FORCED_LEVEL_PROFILE_PEAK: 1012 smu_v13_0_4_get_dpm_profile_freq(smu, level, SMU_SCLK, &sclk_min, &sclk_max); 1013 smu_v13_0_4_get_dpm_profile_freq(smu, level, SMU_FCLK, &fclk_min, &fclk_max); 1014 smu_v13_0_4_get_dpm_profile_freq(smu, level, SMU_SOCCLK, &socclk_min, &socclk_max); 1015 smu_v13_0_4_get_dpm_profile_freq(smu, level, SMU_VCLK, &vclk_min, &vclk_max); 1016 smu_v13_0_4_get_dpm_profile_freq(smu, level, SMU_DCLK, &dclk_min, &dclk_max); 1017 break; 1018 case AMD_DPM_FORCED_LEVEL_MANUAL: 1019 case AMD_DPM_FORCED_LEVEL_PROFILE_EXIT: 1020 return 0; 1021 default: 1022 dev_err(adev->dev, "Invalid performance level %d\n", level); 1023 return -EINVAL; 1024 } 1025 1026 if (sclk_min && sclk_max) { 1027 ret = smu_v13_0_4_set_soft_freq_limited_range(smu, 1028 SMU_SCLK, 1029 sclk_min, 1030 sclk_max); 1031 if (ret) 1032 return ret; 1033 1034 smu->gfx_actual_hard_min_freq = sclk_min; 1035 smu->gfx_actual_soft_max_freq = sclk_max; 1036 } 1037 1038 if (fclk_min && fclk_max) { 1039 ret = smu_v13_0_4_set_soft_freq_limited_range(smu, 1040 SMU_FCLK, 1041 fclk_min, 1042 fclk_max); 1043 if (ret) 1044 return ret; 1045 } 1046 1047 if (socclk_min && socclk_max) { 1048 ret = smu_v13_0_4_set_soft_freq_limited_range(smu, 1049 SMU_SOCCLK, 1050 socclk_min, 1051 socclk_max); 1052 if (ret) 1053 return ret; 1054 } 1055 1056 if (vclk_min && vclk_max) { 1057 ret = smu_v13_0_4_set_soft_freq_limited_range(smu, 1058 SMU_VCLK, 1059 vclk_min, 1060 vclk_max); 1061 if (ret) 1062 return ret; 1063 } 1064 1065 if (dclk_min && dclk_max) { 1066 ret = smu_v13_0_4_set_soft_freq_limited_range(smu, 1067 SMU_DCLK, 1068 dclk_min, 1069 dclk_max); 1070 if (ret) 1071 return ret; 1072 } 1073 return ret; 1074} 1075 1076static int smu_v13_0_4_mode2_reset(struct smu_context *smu) 1077{ 1078 return smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_GfxDeviceDriverReset, 1079 SMU_RESET_MODE_2, NULL); 1080} 1081 1082static int smu_v13_0_4_set_fine_grain_gfx_freq_parameters(struct smu_context *smu) 1083{ 1084 DpmClocks_t *clk_table = smu->smu_table.clocks_table; 1085 1086 smu->gfx_default_hard_min_freq = clk_table->MinGfxClk; 1087 smu->gfx_default_soft_max_freq = clk_table->MaxGfxClk; 1088 smu->gfx_actual_hard_min_freq = 0; 1089 smu->gfx_actual_soft_max_freq = 0; 1090 1091 return 0; 1092} 1093 1094static const struct pptable_funcs smu_v13_0_4_ppt_funcs = { 1095 .check_fw_status = smu_v13_0_check_fw_status, 1096 .check_fw_version = smu_v13_0_check_fw_version, 1097 .init_smc_tables = smu_v13_0_4_init_smc_tables, 1098 .fini_smc_tables = smu_v13_0_4_fini_smc_tables, 1099 .get_vbios_bootup_values = smu_v13_0_get_vbios_bootup_values, 1100 .system_features_control = smu_v13_0_4_system_features_control, 1101 .send_smc_msg_with_param = smu_cmn_send_smc_msg_with_param, 1102 .send_smc_msg = smu_cmn_send_smc_msg, 1103 .dpm_set_vcn_enable = smu_v13_0_set_vcn_enable, 1104 .dpm_set_jpeg_enable = smu_v13_0_set_jpeg_enable, 1105 .set_default_dpm_table = smu_v13_0_set_default_dpm_tables, 1106 .read_sensor = smu_v13_0_4_read_sensor, 1107 .is_dpm_running = smu_v13_0_4_is_dpm_running, 1108 .set_watermarks_table = smu_v13_0_4_set_watermarks_table, 1109 .get_gpu_metrics = smu_v13_0_4_get_gpu_metrics, 1110 .get_enabled_mask = smu_cmn_get_enabled_mask, 1111 .get_pp_feature_mask = smu_cmn_get_pp_feature_mask, 1112 .set_driver_table_location = smu_v13_0_set_driver_table_location, 1113 .gfx_off_control = smu_v13_0_gfx_off_control, 1114 .mode2_reset = smu_v13_0_4_mode2_reset, 1115 .get_dpm_ultimate_freq = smu_v13_0_4_get_dpm_ultimate_freq, 1116 .od_edit_dpm_table = smu_v13_0_od_edit_dpm_table, 1117 .print_clk_levels = smu_v13_0_4_print_clk_levels, 1118 .force_clk_levels = smu_v13_0_4_force_clk_levels, 1119 .set_performance_level = smu_v13_0_4_set_performance_level, 1120 .set_fine_grain_gfx_freq_parameters = smu_v13_0_4_set_fine_grain_gfx_freq_parameters, 1121 .set_gfx_power_up_by_imu = smu_v13_0_set_gfx_power_up_by_imu, 1122}; 1123 1124static void smu_v13_0_4_set_smu_mailbox_registers(struct smu_context *smu) 1125{ 1126 struct amdgpu_device *adev = smu->adev; 1127 1128 smu->param_reg = SOC15_REG_OFFSET(MP1, 0, mmMP1_SMN_C2PMSG_82); 1129 smu->msg_reg = SOC15_REG_OFFSET(MP1, 0, mmMP1_SMN_C2PMSG_66); 1130 smu->resp_reg = SOC15_REG_OFFSET(MP1, 0, mmMP1_SMN_C2PMSG_90); 1131} 1132 1133void smu_v13_0_4_set_ppt_funcs(struct smu_context *smu) 1134{ 1135 struct amdgpu_device *adev = smu->adev; 1136 1137 smu->ppt_funcs = &smu_v13_0_4_ppt_funcs; 1138 smu->message_map = smu_v13_0_4_message_map; 1139 smu->feature_map = smu_v13_0_4_feature_mask_map; 1140 smu->table_map = smu_v13_0_4_table_map; 1141 smu->smc_driver_if_version = SMU13_0_4_DRIVER_IF_VERSION; 1142 smu->is_apu = true; 1143 1144 if (amdgpu_ip_version(adev, MP1_HWIP, 0) == IP_VERSION(13, 0, 4)) 1145 smu_v13_0_4_set_smu_mailbox_registers(smu); 1146 else 1147 smu_v13_0_set_smu_mailbox_registers(smu); 1148}
~/
Read-only file preview.