1 /* 2 * Copyright 2023 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_v14_0.h" 30 #include "smu14_driver_if_v14_0_0.h" 31 #include "smu_v14_0_0_ppt.h" 32 #include "smu_v14_0_0_ppsmc.h" 33 #include "smu_v14_0_0_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 0 48 49 #define mmMP1_SMN_C2PMSG_82 0x0292 50 #define mmMP1_SMN_C2PMSG_82_BASE_IDX 0 51 52 #define mmMP1_SMN_C2PMSG_90 0x029a 53 #define mmMP1_SMN_C2PMSG_90_BASE_IDX 0 54 55 #define FEATURE_MASK(feature) (1ULL << feature) 56 #define SMC_DPM_FEATURE ( \ 57 FEATURE_MASK(FEATURE_CCLK_DPM_BIT) | \ 58 FEATURE_MASK(FEATURE_VCN_DPM_BIT) | \ 59 FEATURE_MASK(FEATURE_FCLK_DPM_BIT) | \ 60 FEATURE_MASK(FEATURE_SOCCLK_DPM_BIT) | \ 61 FEATURE_MASK(FEATURE_LCLK_DPM_BIT) | \ 62 FEATURE_MASK(FEATURE_SHUBCLK_DPM_BIT) | \ 63 FEATURE_MASK(FEATURE_DCFCLK_DPM_BIT)| \ 64 FEATURE_MASK(FEATURE_ISP_DPM_BIT)| \ 65 FEATURE_MASK(FEATURE_IPU_DPM_BIT) | \ 66 FEATURE_MASK(FEATURE_GFX_DPM_BIT) | \ 67 FEATURE_MASK(FEATURE_VPE_DPM_BIT)) 68 69 static struct cmn2asic_msg_mapping smu_v14_0_0_message_map[SMU_MSG_MAX_COUNT] = { 70 MSG_MAP(TestMessage, PPSMC_MSG_TestMessage, 1), 71 MSG_MAP(GetSmuVersion, PPSMC_MSG_GetPmfwVersion, 1), 72 MSG_MAP(GetDriverIfVersion, PPSMC_MSG_GetDriverIfVersion, 1), 73 MSG_MAP(PowerDownVcn, PPSMC_MSG_PowerDownVcn, 1), 74 MSG_MAP(PowerUpVcn, PPSMC_MSG_PowerUpVcn, 1), 75 MSG_MAP(SetHardMinVcn, PPSMC_MSG_SetHardMinVcn, 1), 76 MSG_MAP(SetSoftMinGfxclk, PPSMC_MSG_SetSoftMinGfxclk, 1), 77 MSG_MAP(PrepareMp1ForUnload, PPSMC_MSG_PrepareMp1ForUnload, 1), 78 MSG_MAP(SetDriverDramAddrHigh, PPSMC_MSG_SetDriverDramAddrHigh, 1), 79 MSG_MAP(SetDriverDramAddrLow, PPSMC_MSG_SetDriverDramAddrLow, 1), 80 MSG_MAP(TransferTableSmu2Dram, PPSMC_MSG_TransferTableSmu2Dram, 1), 81 MSG_MAP(TransferTableDram2Smu, PPSMC_MSG_TransferTableDram2Smu, 1), 82 MSG_MAP(GfxDeviceDriverReset, PPSMC_MSG_GfxDeviceDriverReset, 1), 83 MSG_MAP(GetEnabledSmuFeatures, PPSMC_MSG_GetEnabledSmuFeatures, 1), 84 MSG_MAP(SetHardMinSocclkByFreq, PPSMC_MSG_SetHardMinSocclkByFreq, 1), 85 MSG_MAP(SetSoftMinFclk, PPSMC_MSG_SetSoftMinFclk, 1), 86 MSG_MAP(SetSoftMinVcn, PPSMC_MSG_SetSoftMinVcn, 1), 87 MSG_MAP(EnableGfxImu, PPSMC_MSG_EnableGfxImu, 1), 88 MSG_MAP(AllowGfxOff, PPSMC_MSG_AllowGfxOff, 1), 89 MSG_MAP(DisallowGfxOff, PPSMC_MSG_DisallowGfxOff, 1), 90 MSG_MAP(SetSoftMaxGfxClk, PPSMC_MSG_SetSoftMaxGfxClk, 1), 91 MSG_MAP(SetHardMinGfxClk, PPSMC_MSG_SetHardMinGfxClk, 1), 92 MSG_MAP(SetSoftMaxSocclkByFreq, PPSMC_MSG_SetSoftMaxSocclkByFreq, 1), 93 MSG_MAP(SetSoftMaxFclkByFreq, PPSMC_MSG_SetSoftMaxFclkByFreq, 1), 94 MSG_MAP(SetSoftMaxVcn, PPSMC_MSG_SetSoftMaxVcn, 1), 95 MSG_MAP(PowerDownJpeg, PPSMC_MSG_PowerDownJpeg, 1), 96 MSG_MAP(PowerUpJpeg, PPSMC_MSG_PowerUpJpeg, 1), 97 MSG_MAP(SetHardMinFclkByFreq, PPSMC_MSG_SetHardMinFclkByFreq, 1), 98 MSG_MAP(SetSoftMinSocclkByFreq, PPSMC_MSG_SetSoftMinSocclkByFreq, 1), 99 MSG_MAP(PowerDownIspByTile, PPSMC_MSG_PowerDownIspByTile, 1), 100 MSG_MAP(PowerUpIspByTile, PPSMC_MSG_PowerUpIspByTile, 1), 101 MSG_MAP(SetHardMinIspiclkByFreq, PPSMC_MSG_SetHardMinIspiclkByFreq, 1), 102 MSG_MAP(SetHardMinIspxclkByFreq, PPSMC_MSG_SetHardMinIspxclkByFreq, 1), 103 MSG_MAP(PowerUpVpe, PPSMC_MSG_PowerUpVpe, 1), 104 MSG_MAP(PowerDownVpe, PPSMC_MSG_PowerDownVpe, 1), 105 MSG_MAP(PowerUpUmsch, PPSMC_MSG_PowerUpUmsch, 1), 106 MSG_MAP(PowerDownUmsch, PPSMC_MSG_PowerDownUmsch, 1), 107 MSG_MAP(SetSoftMaxVpe, PPSMC_MSG_SetSoftMaxVpe, 1), 108 MSG_MAP(SetSoftMinVpe, PPSMC_MSG_SetSoftMinVpe, 1), 109 }; 110 111 static struct cmn2asic_mapping smu_v14_0_0_feature_mask_map[SMU_FEATURE_COUNT] = { 112 FEA_MAP(CCLK_DPM), 113 FEA_MAP(FAN_CONTROLLER), 114 FEA_MAP(PPT), 115 FEA_MAP(TDC), 116 FEA_MAP(THERMAL), 117 FEA_MAP(VCN_DPM), 118 FEA_MAP_REVERSE(FCLK), 119 FEA_MAP_REVERSE(SOCCLK), 120 FEA_MAP(LCLK_DPM), 121 FEA_MAP(SHUBCLK_DPM), 122 FEA_MAP(DCFCLK_DPM), 123 FEA_MAP_HALF_REVERSE(GFX), 124 FEA_MAP(DS_GFXCLK), 125 FEA_MAP(DS_SOCCLK), 126 FEA_MAP(DS_LCLK), 127 FEA_MAP(LOW_POWER_DCNCLKS), 128 FEA_MAP(DS_FCLK), 129 FEA_MAP(DS_MP1CLK), 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_v14_0_0_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 150 static int smu_v14_0_0_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->metrics_table = kzalloc(sizeof(SmuMetrics_t), GFP_KERNEL); 163 if (!smu_table->metrics_table) 164 goto err0_out; 165 smu_table->metrics_time = 0; 166 167 smu_table->clocks_table = kzalloc(sizeof(DpmClocks_t), GFP_KERNEL); 168 if (!smu_table->clocks_table) 169 goto err1_out; 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_v3_0); 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->clocks_table); 186 err1_out: 187 kfree(smu_table->metrics_table); 188 err0_out: 189 return -ENOMEM; 190 } 191 192 static int smu_v14_0_0_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 211 static int smu_v14_0_0_system_features_control(struct smu_context *smu, bool en) 212 { 213 struct amdgpu_device *adev = smu->adev; 214 int ret = 0; 215 216 if (!en && !adev->in_s0ix) 217 ret = smu_cmn_send_smc_msg(smu, SMU_MSG_PrepareMp1ForUnload, NULL); 218 219 return ret; 220 } 221 222 static int smu_v14_0_0_get_smu_metrics_data(struct smu_context *smu, 223 MetricsMember_t member, 224 uint32_t *value) 225 { 226 struct smu_table_context *smu_table = &smu->smu_table; 227 228 SmuMetrics_t *metrics = (SmuMetrics_t *)smu_table->metrics_table; 229 int ret = 0; 230 231 ret = smu_cmn_get_metrics_table(smu, NULL, false); 232 if (ret) 233 return ret; 234 235 switch (member) { 236 case METRICS_AVERAGE_GFXCLK: 237 *value = metrics->GfxclkFrequency; 238 break; 239 case METRICS_AVERAGE_SOCCLK: 240 *value = metrics->SocclkFrequency; 241 break; 242 case METRICS_AVERAGE_VCLK: 243 *value = metrics->VclkFrequency; 244 break; 245 case METRICS_AVERAGE_DCLK: 246 *value = 0; 247 break; 248 case METRICS_AVERAGE_UCLK: 249 *value = metrics->MemclkFrequency; 250 break; 251 case METRICS_AVERAGE_FCLK: 252 *value = metrics->FclkFrequency; 253 break; 254 case METRICS_AVERAGE_VPECLK: 255 *value = metrics->VpeclkFrequency; 256 break; 257 case METRICS_AVERAGE_IPUCLK: 258 *value = metrics->IpuclkFrequency; 259 break; 260 case METRICS_AVERAGE_MPIPUCLK: 261 *value = metrics->MpipuclkFrequency; 262 break; 263 case METRICS_AVERAGE_GFXACTIVITY: 264 *value = metrics->GfxActivity / 100; 265 break; 266 case METRICS_AVERAGE_VCNACTIVITY: 267 *value = metrics->VcnActivity / 100; 268 break; 269 case METRICS_AVERAGE_SOCKETPOWER: 270 case METRICS_CURR_SOCKETPOWER: 271 *value = (metrics->SocketPower / 1000 << 8) + 272 (metrics->SocketPower % 1000 / 10); 273 break; 274 case METRICS_TEMPERATURE_EDGE: 275 *value = metrics->GfxTemperature / 100 * 276 SMU_TEMPERATURE_UNITS_PER_CENTIGRADES; 277 break; 278 case METRICS_TEMPERATURE_HOTSPOT: 279 *value = metrics->SocTemperature / 100 * 280 SMU_TEMPERATURE_UNITS_PER_CENTIGRADES; 281 break; 282 case METRICS_THROTTLER_RESIDENCY_PROCHOT: 283 *value = metrics->ThrottleResidency_PROCHOT; 284 break; 285 case METRICS_THROTTLER_RESIDENCY_SPL: 286 *value = metrics->ThrottleResidency_SPL; 287 break; 288 case METRICS_THROTTLER_RESIDENCY_FPPT: 289 *value = metrics->ThrottleResidency_FPPT; 290 break; 291 case METRICS_THROTTLER_RESIDENCY_SPPT: 292 *value = metrics->ThrottleResidency_SPPT; 293 break; 294 case METRICS_THROTTLER_RESIDENCY_THM_CORE: 295 *value = metrics->ThrottleResidency_THM_CORE; 296 break; 297 case METRICS_THROTTLER_RESIDENCY_THM_GFX: 298 *value = metrics->ThrottleResidency_THM_GFX; 299 break; 300 case METRICS_THROTTLER_RESIDENCY_THM_SOC: 301 *value = metrics->ThrottleResidency_THM_SOC; 302 break; 303 case METRICS_VOLTAGE_VDDGFX: 304 *value = 0; 305 break; 306 case METRICS_VOLTAGE_VDDSOC: 307 *value = 0; 308 break; 309 case METRICS_SS_APU_SHARE: 310 /* return the percentage of APU power with respect to APU's power limit. 311 * percentage is reported, this isn't boost value. Smartshift power 312 * boost/shift is only when the percentage is more than 100. 313 */ 314 if (metrics->StapmOpnLimit > 0) 315 *value = (metrics->ApuPower * 100) / metrics->StapmOpnLimit; 316 else 317 *value = 0; 318 break; 319 case METRICS_SS_DGPU_SHARE: 320 /* return the percentage of dGPU power with respect to dGPU's power limit. 321 * percentage is reported, this isn't boost value. Smartshift power 322 * boost/shift is only when the percentage is more than 100. 323 */ 324 if ((metrics->dGpuPower > 0) && 325 (metrics->StapmCurrentLimit > metrics->StapmOpnLimit)) 326 *value = (metrics->dGpuPower * 100) / 327 (metrics->StapmCurrentLimit - metrics->StapmOpnLimit); 328 else 329 *value = 0; 330 break; 331 default: 332 *value = UINT_MAX; 333 break; 334 } 335 336 return ret; 337 } 338 339 static int smu_v14_0_0_read_sensor(struct smu_context *smu, 340 enum amd_pp_sensors sensor, 341 void *data, uint32_t *size) 342 { 343 int ret = 0; 344 345 if (!data || !size) 346 return -EINVAL; 347 348 switch (sensor) { 349 case AMDGPU_PP_SENSOR_GPU_LOAD: 350 ret = smu_v14_0_0_get_smu_metrics_data(smu, 351 METRICS_AVERAGE_GFXACTIVITY, 352 (uint32_t *)data); 353 *size = 4; 354 break; 355 case AMDGPU_PP_SENSOR_GPU_AVG_POWER: 356 ret = smu_v14_0_0_get_smu_metrics_data(smu, 357 METRICS_AVERAGE_SOCKETPOWER, 358 (uint32_t *)data); 359 *size = 4; 360 break; 361 case AMDGPU_PP_SENSOR_GPU_INPUT_POWER: 362 ret = smu_v14_0_0_get_smu_metrics_data(smu, 363 METRICS_CURR_SOCKETPOWER, 364 (uint32_t *)data); 365 *size = 4; 366 break; 367 case AMDGPU_PP_SENSOR_EDGE_TEMP: 368 ret = smu_v14_0_0_get_smu_metrics_data(smu, 369 METRICS_TEMPERATURE_EDGE, 370 (uint32_t *)data); 371 *size = 4; 372 break; 373 case AMDGPU_PP_SENSOR_HOTSPOT_TEMP: 374 ret = smu_v14_0_0_get_smu_metrics_data(smu, 375 METRICS_TEMPERATURE_HOTSPOT, 376 (uint32_t *)data); 377 *size = 4; 378 break; 379 case AMDGPU_PP_SENSOR_GFX_MCLK: 380 ret = smu_v14_0_0_get_smu_metrics_data(smu, 381 METRICS_AVERAGE_UCLK, 382 (uint32_t *)data); 383 *(uint32_t *)data *= 100; 384 *size = 4; 385 break; 386 case AMDGPU_PP_SENSOR_GFX_SCLK: 387 ret = smu_v14_0_0_get_smu_metrics_data(smu, 388 METRICS_AVERAGE_GFXCLK, 389 (uint32_t *)data); 390 *(uint32_t *)data *= 100; 391 *size = 4; 392 break; 393 case AMDGPU_PP_SENSOR_VDDGFX: 394 ret = smu_v14_0_0_get_smu_metrics_data(smu, 395 METRICS_VOLTAGE_VDDGFX, 396 (uint32_t *)data); 397 *size = 4; 398 break; 399 case AMDGPU_PP_SENSOR_VDDNB: 400 ret = smu_v14_0_0_get_smu_metrics_data(smu, 401 METRICS_VOLTAGE_VDDSOC, 402 (uint32_t *)data); 403 *size = 4; 404 break; 405 case AMDGPU_PP_SENSOR_SS_APU_SHARE: 406 ret = smu_v14_0_0_get_smu_metrics_data(smu, 407 METRICS_SS_APU_SHARE, 408 (uint32_t *)data); 409 *size = 4; 410 break; 411 case AMDGPU_PP_SENSOR_SS_DGPU_SHARE: 412 ret = smu_v14_0_0_get_smu_metrics_data(smu, 413 METRICS_SS_DGPU_SHARE, 414 (uint32_t *)data); 415 *size = 4; 416 break; 417 default: 418 ret = -EOPNOTSUPP; 419 break; 420 } 421 422 return ret; 423 } 424 425 static bool smu_v14_0_0_is_dpm_running(struct smu_context *smu) 426 { 427 int ret = 0; 428 uint64_t feature_enabled; 429 430 ret = smu_cmn_get_enabled_mask(smu, &feature_enabled); 431 432 if (ret) 433 return false; 434 435 return !!(feature_enabled & SMC_DPM_FEATURE); 436 } 437 438 static int smu_v14_0_0_set_watermarks_table(struct smu_context *smu, 439 struct pp_smu_wm_range_sets *clock_ranges) 440 { 441 int i; 442 int ret = 0; 443 Watermarks_t *table = smu->smu_table.watermarks_table; 444 445 if (!table || !clock_ranges) 446 return -EINVAL; 447 448 if (clock_ranges->num_reader_wm_sets > NUM_WM_RANGES || 449 clock_ranges->num_writer_wm_sets > NUM_WM_RANGES) 450 return -EINVAL; 451 452 for (i = 0; i < clock_ranges->num_reader_wm_sets; i++) { 453 table->WatermarkRow[WM_DCFCLK][i].MinClock = 454 clock_ranges->reader_wm_sets[i].min_drain_clk_mhz; 455 table->WatermarkRow[WM_DCFCLK][i].MaxClock = 456 clock_ranges->reader_wm_sets[i].max_drain_clk_mhz; 457 table->WatermarkRow[WM_DCFCLK][i].MinMclk = 458 clock_ranges->reader_wm_sets[i].min_fill_clk_mhz; 459 table->WatermarkRow[WM_DCFCLK][i].MaxMclk = 460 clock_ranges->reader_wm_sets[i].max_fill_clk_mhz; 461 462 table->WatermarkRow[WM_DCFCLK][i].WmSetting = 463 clock_ranges->reader_wm_sets[i].wm_inst; 464 } 465 466 for (i = 0; i < clock_ranges->num_writer_wm_sets; i++) { 467 table->WatermarkRow[WM_SOCCLK][i].MinClock = 468 clock_ranges->writer_wm_sets[i].min_fill_clk_mhz; 469 table->WatermarkRow[WM_SOCCLK][i].MaxClock = 470 clock_ranges->writer_wm_sets[i].max_fill_clk_mhz; 471 table->WatermarkRow[WM_SOCCLK][i].MinMclk = 472 clock_ranges->writer_wm_sets[i].min_drain_clk_mhz; 473 table->WatermarkRow[WM_SOCCLK][i].MaxMclk = 474 clock_ranges->writer_wm_sets[i].max_drain_clk_mhz; 475 476 table->WatermarkRow[WM_SOCCLK][i].WmSetting = 477 clock_ranges->writer_wm_sets[i].wm_inst; 478 } 479 480 smu->watermarks_bitmap |= WATERMARKS_EXIST; 481 482 /* pass data to smu controller */ 483 if ((smu->watermarks_bitmap & WATERMARKS_EXIST) && 484 !(smu->watermarks_bitmap & WATERMARKS_LOADED)) { 485 ret = smu_cmn_write_watermarks_table(smu); 486 if (ret) { 487 dev_err(smu->adev->dev, "Failed to update WMTABLE!"); 488 return ret; 489 } 490 smu->watermarks_bitmap |= WATERMARKS_LOADED; 491 } 492 493 return 0; 494 } 495 496 static ssize_t smu_v14_0_0_get_gpu_metrics(struct smu_context *smu, 497 void **table) 498 { 499 struct smu_table_context *smu_table = &smu->smu_table; 500 struct gpu_metrics_v3_0 *gpu_metrics = 501 (struct gpu_metrics_v3_0 *)smu_table->gpu_metrics_table; 502 SmuMetrics_t metrics; 503 int ret = 0; 504 505 ret = smu_cmn_get_metrics_table(smu, &metrics, true); 506 if (ret) 507 return ret; 508 509 smu_cmn_init_soft_gpu_metrics(gpu_metrics, 3, 0); 510 511 gpu_metrics->temperature_gfx = metrics.GfxTemperature; 512 gpu_metrics->temperature_soc = metrics.SocTemperature; 513 memcpy(&gpu_metrics->temperature_core[0], 514 &metrics.CoreTemperature[0], 515 sizeof(uint16_t) * 16); 516 gpu_metrics->temperature_skin = metrics.SkinTemp; 517 518 gpu_metrics->average_gfx_activity = metrics.GfxActivity; 519 gpu_metrics->average_vcn_activity = metrics.VcnActivity; 520 memcpy(&gpu_metrics->average_ipu_activity[0], 521 &metrics.IpuBusy[0], 522 sizeof(uint16_t) * 8); 523 memcpy(&gpu_metrics->average_core_c0_activity[0], 524 &metrics.CoreC0Residency[0], 525 sizeof(uint16_t) * 16); 526 gpu_metrics->average_dram_reads = metrics.DRAMReads; 527 gpu_metrics->average_dram_writes = metrics.DRAMWrites; 528 gpu_metrics->average_ipu_reads = metrics.IpuReads; 529 gpu_metrics->average_ipu_writes = metrics.IpuWrites; 530 531 gpu_metrics->average_socket_power = metrics.SocketPower; 532 gpu_metrics->average_ipu_power = metrics.IpuPower; 533 gpu_metrics->average_apu_power = metrics.ApuPower; 534 gpu_metrics->average_gfx_power = metrics.GfxPower; 535 gpu_metrics->average_dgpu_power = metrics.dGpuPower; 536 gpu_metrics->average_all_core_power = metrics.AllCorePower; 537 gpu_metrics->average_sys_power = metrics.Psys; 538 memcpy(&gpu_metrics->average_core_power[0], 539 &metrics.CorePower[0], 540 sizeof(uint16_t) * 16); 541 542 gpu_metrics->average_gfxclk_frequency = metrics.GfxclkFrequency; 543 gpu_metrics->average_socclk_frequency = metrics.SocclkFrequency; 544 gpu_metrics->average_vpeclk_frequency = metrics.VpeclkFrequency; 545 gpu_metrics->average_fclk_frequency = metrics.FclkFrequency; 546 gpu_metrics->average_vclk_frequency = metrics.VclkFrequency; 547 gpu_metrics->average_ipuclk_frequency = metrics.IpuclkFrequency; 548 gpu_metrics->average_uclk_frequency = metrics.MemclkFrequency; 549 gpu_metrics->average_mpipu_frequency = metrics.MpipuclkFrequency; 550 551 memcpy(&gpu_metrics->current_coreclk[0], 552 &metrics.CoreFrequency[0], 553 sizeof(uint16_t) * 16); 554 gpu_metrics->current_core_maxfreq = metrics.InfrastructureCpuMaxFreq; 555 gpu_metrics->current_gfx_maxfreq = metrics.InfrastructureGfxMaxFreq; 556 557 gpu_metrics->throttle_residency_prochot = metrics.ThrottleResidency_PROCHOT; 558 gpu_metrics->throttle_residency_spl = metrics.ThrottleResidency_SPL; 559 gpu_metrics->throttle_residency_fppt = metrics.ThrottleResidency_FPPT; 560 gpu_metrics->throttle_residency_sppt = metrics.ThrottleResidency_SPPT; 561 gpu_metrics->throttle_residency_thm_core = metrics.ThrottleResidency_THM_CORE; 562 gpu_metrics->throttle_residency_thm_gfx = metrics.ThrottleResidency_THM_GFX; 563 gpu_metrics->throttle_residency_thm_soc = metrics.ThrottleResidency_THM_SOC; 564 565 gpu_metrics->time_filter_alphavalue = metrics.FilterAlphaValue; 566 gpu_metrics->system_clock_counter = ktime_get_boottime_ns(); 567 568 *table = (void *)gpu_metrics; 569 570 return sizeof(struct gpu_metrics_v3_0); 571 } 572 573 static int smu_v14_0_0_mode2_reset(struct smu_context *smu) 574 { 575 int ret; 576 577 ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_GfxDeviceDriverReset, 578 SMU_RESET_MODE_2, NULL); 579 580 if (ret) 581 dev_err(smu->adev->dev, "Failed to mode2 reset!\n"); 582 583 return ret; 584 } 585 586 static int smu_v14_0_0_get_dpm_freq_by_index(struct smu_context *smu, 587 enum smu_clk_type clk_type, 588 uint32_t dpm_level, 589 uint32_t *freq) 590 { 591 DpmClocks_t *clk_table = smu->smu_table.clocks_table; 592 593 if (!clk_table || clk_type >= SMU_CLK_COUNT) 594 return -EINVAL; 595 596 switch (clk_type) { 597 case SMU_SOCCLK: 598 if (dpm_level >= clk_table->NumSocClkLevelsEnabled) 599 return -EINVAL; 600 *freq = clk_table->SocClocks[dpm_level]; 601 break; 602 case SMU_VCLK: 603 if (dpm_level >= clk_table->VcnClkLevelsEnabled) 604 return -EINVAL; 605 *freq = clk_table->VClocks[dpm_level]; 606 break; 607 case SMU_DCLK: 608 if (dpm_level >= clk_table->VcnClkLevelsEnabled) 609 return -EINVAL; 610 *freq = clk_table->DClocks[dpm_level]; 611 break; 612 case SMU_UCLK: 613 case SMU_MCLK: 614 if (dpm_level >= clk_table->NumMemPstatesEnabled) 615 return -EINVAL; 616 *freq = clk_table->MemPstateTable[dpm_level].MemClk; 617 break; 618 case SMU_FCLK: 619 if (dpm_level >= clk_table->NumFclkLevelsEnabled) 620 return -EINVAL; 621 *freq = clk_table->FclkClocks_Freq[dpm_level]; 622 break; 623 default: 624 return -EINVAL; 625 } 626 627 return 0; 628 } 629 630 static bool smu_v14_0_0_clk_dpm_is_enabled(struct smu_context *smu, 631 enum smu_clk_type clk_type) 632 { 633 enum smu_feature_mask feature_id = 0; 634 635 switch (clk_type) { 636 case SMU_MCLK: 637 case SMU_UCLK: 638 case SMU_FCLK: 639 feature_id = SMU_FEATURE_DPM_FCLK_BIT; 640 break; 641 case SMU_GFXCLK: 642 case SMU_SCLK: 643 feature_id = SMU_FEATURE_DPM_GFXCLK_BIT; 644 break; 645 case SMU_SOCCLK: 646 feature_id = SMU_FEATURE_DPM_SOCCLK_BIT; 647 break; 648 case SMU_VCLK: 649 case SMU_DCLK: 650 feature_id = SMU_FEATURE_VCN_DPM_BIT; 651 break; 652 default: 653 return true; 654 } 655 656 return smu_cmn_feature_is_enabled(smu, feature_id); 657 } 658 659 static int smu_v14_0_0_get_dpm_ultimate_freq(struct smu_context *smu, 660 enum smu_clk_type clk_type, 661 uint32_t *min, 662 uint32_t *max) 663 { 664 DpmClocks_t *clk_table = smu->smu_table.clocks_table; 665 uint32_t clock_limit; 666 uint32_t max_dpm_level, min_dpm_level; 667 int ret = 0; 668 669 if (!smu_v14_0_0_clk_dpm_is_enabled(smu, clk_type)) { 670 switch (clk_type) { 671 case SMU_MCLK: 672 case SMU_UCLK: 673 clock_limit = smu->smu_table.boot_values.uclk; 674 break; 675 case SMU_FCLK: 676 clock_limit = smu->smu_table.boot_values.fclk; 677 break; 678 case SMU_GFXCLK: 679 case SMU_SCLK: 680 clock_limit = smu->smu_table.boot_values.gfxclk; 681 break; 682 case SMU_SOCCLK: 683 clock_limit = smu->smu_table.boot_values.socclk; 684 break; 685 case SMU_VCLK: 686 clock_limit = smu->smu_table.boot_values.vclk; 687 break; 688 case SMU_DCLK: 689 clock_limit = smu->smu_table.boot_values.dclk; 690 break; 691 default: 692 clock_limit = 0; 693 break; 694 } 695 696 /* clock in Mhz unit */ 697 if (min) 698 *min = clock_limit / 100; 699 if (max) 700 *max = clock_limit / 100; 701 702 return 0; 703 } 704 705 if (max) { 706 switch (clk_type) { 707 case SMU_GFXCLK: 708 case SMU_SCLK: 709 *max = clk_table->MaxGfxClk; 710 break; 711 case SMU_MCLK: 712 case SMU_UCLK: 713 case SMU_FCLK: 714 max_dpm_level = 0; 715 break; 716 case SMU_SOCCLK: 717 max_dpm_level = clk_table->NumSocClkLevelsEnabled - 1; 718 break; 719 case SMU_VCLK: 720 case SMU_DCLK: 721 max_dpm_level = clk_table->VcnClkLevelsEnabled - 1; 722 break; 723 default: 724 ret = -EINVAL; 725 goto failed; 726 } 727 728 if (clk_type != SMU_GFXCLK && clk_type != SMU_SCLK) { 729 ret = smu_v14_0_0_get_dpm_freq_by_index(smu, clk_type, max_dpm_level, max); 730 if (ret) 731 goto failed; 732 } 733 } 734 735 if (min) { 736 switch (clk_type) { 737 case SMU_GFXCLK: 738 case SMU_SCLK: 739 *min = clk_table->MinGfxClk; 740 break; 741 case SMU_MCLK: 742 case SMU_UCLK: 743 min_dpm_level = clk_table->NumMemPstatesEnabled - 1; 744 break; 745 case SMU_FCLK: 746 min_dpm_level = clk_table->NumFclkLevelsEnabled - 1; 747 break; 748 case SMU_SOCCLK: 749 min_dpm_level = 0; 750 break; 751 case SMU_VCLK: 752 case SMU_DCLK: 753 min_dpm_level = 0; 754 break; 755 default: 756 ret = -EINVAL; 757 goto failed; 758 } 759 760 if (clk_type != SMU_GFXCLK && clk_type != SMU_SCLK) { 761 ret = smu_v14_0_0_get_dpm_freq_by_index(smu, clk_type, min_dpm_level, min); 762 if (ret) 763 goto failed; 764 } 765 } 766 767 failed: 768 return ret; 769 } 770 771 static int smu_v14_0_0_get_current_clk_freq(struct smu_context *smu, 772 enum smu_clk_type clk_type, 773 uint32_t *value) 774 { 775 MetricsMember_t member_type; 776 777 switch (clk_type) { 778 case SMU_SOCCLK: 779 member_type = METRICS_AVERAGE_SOCCLK; 780 break; 781 case SMU_VCLK: 782 member_type = METRICS_AVERAGE_VCLK; 783 break; 784 case SMU_DCLK: 785 member_type = METRICS_AVERAGE_DCLK; 786 break; 787 case SMU_MCLK: 788 member_type = METRICS_AVERAGE_UCLK; 789 break; 790 case SMU_FCLK: 791 member_type = METRICS_AVERAGE_FCLK; 792 break; 793 case SMU_GFXCLK: 794 case SMU_SCLK: 795 member_type = METRICS_AVERAGE_GFXCLK; 796 break; 797 default: 798 return -EINVAL; 799 } 800 801 return smu_v14_0_0_get_smu_metrics_data(smu, member_type, value); 802 } 803 804 static int smu_v14_0_0_get_dpm_level_count(struct smu_context *smu, 805 enum smu_clk_type clk_type, 806 uint32_t *count) 807 { 808 DpmClocks_t *clk_table = smu->smu_table.clocks_table; 809 810 switch (clk_type) { 811 case SMU_SOCCLK: 812 *count = clk_table->NumSocClkLevelsEnabled; 813 break; 814 case SMU_VCLK: 815 *count = clk_table->VcnClkLevelsEnabled; 816 break; 817 case SMU_DCLK: 818 *count = clk_table->VcnClkLevelsEnabled; 819 break; 820 case SMU_MCLK: 821 *count = clk_table->NumMemPstatesEnabled; 822 break; 823 case SMU_FCLK: 824 *count = clk_table->NumFclkLevelsEnabled; 825 break; 826 default: 827 break; 828 } 829 830 return 0; 831 } 832 833 static int smu_v14_0_0_print_clk_levels(struct smu_context *smu, 834 enum smu_clk_type clk_type, char *buf) 835 { 836 int i, size = 0, ret = 0; 837 uint32_t cur_value = 0, value = 0, count = 0; 838 uint32_t min, max; 839 840 smu_cmn_get_sysfs_buf(&buf, &size); 841 842 switch (clk_type) { 843 case SMU_OD_SCLK: 844 size += sysfs_emit_at(buf, size, "%s:\n", "OD_SCLK"); 845 size += sysfs_emit_at(buf, size, "0: %10uMhz\n", 846 (smu->gfx_actual_hard_min_freq > 0) ? smu->gfx_actual_hard_min_freq : smu->gfx_default_hard_min_freq); 847 size += sysfs_emit_at(buf, size, "1: %10uMhz\n", 848 (smu->gfx_actual_soft_max_freq > 0) ? smu->gfx_actual_soft_max_freq : smu->gfx_default_soft_max_freq); 849 break; 850 case SMU_OD_RANGE: 851 size += sysfs_emit_at(buf, size, "%s:\n", "OD_RANGE"); 852 size += sysfs_emit_at(buf, size, "SCLK: %7uMhz %10uMhz\n", 853 smu->gfx_default_hard_min_freq, 854 smu->gfx_default_soft_max_freq); 855 break; 856 case SMU_SOCCLK: 857 case SMU_VCLK: 858 case SMU_DCLK: 859 case SMU_MCLK: 860 case SMU_FCLK: 861 ret = smu_v14_0_0_get_current_clk_freq(smu, clk_type, &cur_value); 862 if (ret) 863 break; 864 865 ret = smu_v14_0_0_get_dpm_level_count(smu, clk_type, &count); 866 if (ret) 867 break; 868 869 for (i = 0; i < count; i++) { 870 ret = smu_v14_0_0_get_dpm_freq_by_index(smu, clk_type, i, &value); 871 if (ret) 872 break; 873 874 size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n", i, value, 875 cur_value == value ? "*" : ""); 876 } 877 break; 878 case SMU_GFXCLK: 879 case SMU_SCLK: 880 ret = smu_v14_0_0_get_current_clk_freq(smu, clk_type, &cur_value); 881 if (ret) 882 break; 883 min = (smu->gfx_actual_hard_min_freq > 0) ? smu->gfx_actual_hard_min_freq : smu->gfx_default_hard_min_freq; 884 max = (smu->gfx_actual_soft_max_freq > 0) ? smu->gfx_actual_soft_max_freq : smu->gfx_default_soft_max_freq; 885 if (cur_value == max) 886 i = 2; 887 else if (cur_value == min) 888 i = 0; 889 else 890 i = 1; 891 size += sysfs_emit_at(buf, size, "0: %uMhz %s\n", min, 892 i == 0 ? "*" : ""); 893 size += sysfs_emit_at(buf, size, "1: %uMhz %s\n", 894 i == 1 ? cur_value : 1100, /* UMD PSTATE GFXCLK 1100 */ 895 i == 1 ? "*" : ""); 896 size += sysfs_emit_at(buf, size, "2: %uMhz %s\n", max, 897 i == 2 ? "*" : ""); 898 break; 899 default: 900 break; 901 } 902 903 return size; 904 } 905 906 static int smu_v14_0_0_set_soft_freq_limited_range(struct smu_context *smu, 907 enum smu_clk_type clk_type, 908 uint32_t min, 909 uint32_t max) 910 { 911 enum smu_message_type msg_set_min, msg_set_max; 912 int ret = 0; 913 914 if (!smu_v14_0_0_clk_dpm_is_enabled(smu, clk_type)) 915 return -EINVAL; 916 917 switch (clk_type) { 918 case SMU_GFXCLK: 919 case SMU_SCLK: 920 msg_set_min = SMU_MSG_SetHardMinGfxClk; 921 msg_set_max = SMU_MSG_SetSoftMaxGfxClk; 922 break; 923 case SMU_FCLK: 924 msg_set_min = SMU_MSG_SetHardMinFclkByFreq; 925 msg_set_max = SMU_MSG_SetSoftMaxFclkByFreq; 926 break; 927 case SMU_SOCCLK: 928 msg_set_min = SMU_MSG_SetHardMinSocclkByFreq; 929 msg_set_max = SMU_MSG_SetSoftMaxSocclkByFreq; 930 break; 931 case SMU_VCLK: 932 case SMU_DCLK: 933 msg_set_min = SMU_MSG_SetHardMinVcn; 934 msg_set_max = SMU_MSG_SetSoftMaxVcn; 935 break; 936 default: 937 return -EINVAL; 938 } 939 940 ret = smu_cmn_send_smc_msg_with_param(smu, msg_set_min, min, NULL); 941 if (ret) 942 return ret; 943 944 return smu_cmn_send_smc_msg_with_param(smu, msg_set_max, 945 max, NULL); 946 } 947 948 static int smu_v14_0_0_force_clk_levels(struct smu_context *smu, 949 enum smu_clk_type clk_type, 950 uint32_t mask) 951 { 952 uint32_t soft_min_level = 0, soft_max_level = 0; 953 uint32_t min_freq = 0, max_freq = 0; 954 int ret = 0; 955 956 soft_min_level = mask ? (ffs(mask) - 1) : 0; 957 soft_max_level = mask ? (fls(mask) - 1) : 0; 958 959 switch (clk_type) { 960 case SMU_SOCCLK: 961 case SMU_FCLK: 962 case SMU_VCLK: 963 case SMU_DCLK: 964 ret = smu_v14_0_0_get_dpm_freq_by_index(smu, clk_type, soft_min_level, &min_freq); 965 if (ret) 966 break; 967 968 ret = smu_v14_0_0_get_dpm_freq_by_index(smu, clk_type, soft_max_level, &max_freq); 969 if (ret) 970 break; 971 972 ret = smu_v14_0_0_set_soft_freq_limited_range(smu, clk_type, min_freq, max_freq); 973 break; 974 default: 975 ret = -EINVAL; 976 break; 977 } 978 979 return ret; 980 } 981 982 static int smu_v14_0_0_set_performance_level(struct smu_context *smu, 983 enum amd_dpm_forced_level level) 984 { 985 struct amdgpu_device *adev = smu->adev; 986 uint32_t sclk_min = 0, sclk_max = 0; 987 uint32_t fclk_min = 0, fclk_max = 0; 988 uint32_t socclk_min = 0, socclk_max = 0; 989 int ret = 0; 990 991 switch (level) { 992 case AMD_DPM_FORCED_LEVEL_HIGH: 993 smu_v14_0_0_get_dpm_ultimate_freq(smu, SMU_SCLK, NULL, &sclk_max); 994 smu_v14_0_0_get_dpm_ultimate_freq(smu, SMU_FCLK, NULL, &fclk_max); 995 smu_v14_0_0_get_dpm_ultimate_freq(smu, SMU_SOCCLK, NULL, &socclk_max); 996 sclk_min = sclk_max; 997 fclk_min = fclk_max; 998 socclk_min = socclk_max; 999 break; 1000 case AMD_DPM_FORCED_LEVEL_LOW: 1001 smu_v14_0_0_get_dpm_ultimate_freq(smu, SMU_SCLK, &sclk_min, NULL); 1002 smu_v14_0_0_get_dpm_ultimate_freq(smu, SMU_FCLK, &fclk_min, NULL); 1003 smu_v14_0_0_get_dpm_ultimate_freq(smu, SMU_SOCCLK, &socclk_min, NULL); 1004 sclk_max = sclk_min; 1005 fclk_max = fclk_min; 1006 socclk_max = socclk_min; 1007 break; 1008 case AMD_DPM_FORCED_LEVEL_AUTO: 1009 smu_v14_0_0_get_dpm_ultimate_freq(smu, SMU_SCLK, &sclk_min, &sclk_max); 1010 smu_v14_0_0_get_dpm_ultimate_freq(smu, SMU_FCLK, &fclk_min, &fclk_max); 1011 smu_v14_0_0_get_dpm_ultimate_freq(smu, SMU_SOCCLK, &socclk_min, &socclk_max); 1012 break; 1013 case AMD_DPM_FORCED_LEVEL_PROFILE_STANDARD: 1014 case AMD_DPM_FORCED_LEVEL_PROFILE_MIN_SCLK: 1015 case AMD_DPM_FORCED_LEVEL_PROFILE_MIN_MCLK: 1016 case AMD_DPM_FORCED_LEVEL_PROFILE_PEAK: 1017 /* Temporarily do nothing since the optimal clocks haven't been provided yet */ 1018 break; 1019 case AMD_DPM_FORCED_LEVEL_MANUAL: 1020 case AMD_DPM_FORCED_LEVEL_PROFILE_EXIT: 1021 return 0; 1022 default: 1023 dev_err(adev->dev, "Invalid performance level %d\n", level); 1024 return -EINVAL; 1025 } 1026 1027 if (sclk_min && sclk_max) { 1028 ret = smu_v14_0_0_set_soft_freq_limited_range(smu, 1029 SMU_SCLK, 1030 sclk_min, 1031 sclk_max); 1032 if (ret) 1033 return ret; 1034 1035 smu->gfx_actual_hard_min_freq = sclk_min; 1036 smu->gfx_actual_soft_max_freq = sclk_max; 1037 } 1038 1039 if (fclk_min && fclk_max) { 1040 ret = smu_v14_0_0_set_soft_freq_limited_range(smu, 1041 SMU_FCLK, 1042 fclk_min, 1043 fclk_max); 1044 if (ret) 1045 return ret; 1046 } 1047 1048 if (socclk_min && socclk_max) { 1049 ret = smu_v14_0_0_set_soft_freq_limited_range(smu, 1050 SMU_SOCCLK, 1051 socclk_min, 1052 socclk_max); 1053 if (ret) 1054 return ret; 1055 } 1056 1057 return ret; 1058 } 1059 1060 static int smu_v14_0_0_set_fine_grain_gfx_freq_parameters(struct smu_context *smu) 1061 { 1062 DpmClocks_t *clk_table = smu->smu_table.clocks_table; 1063 1064 smu->gfx_default_hard_min_freq = clk_table->MinGfxClk; 1065 smu->gfx_default_soft_max_freq = clk_table->MaxGfxClk; 1066 smu->gfx_actual_hard_min_freq = 0; 1067 smu->gfx_actual_soft_max_freq = 0; 1068 1069 return 0; 1070 } 1071 1072 static int smu_v14_0_0_set_vpe_enable(struct smu_context *smu, 1073 bool enable) 1074 { 1075 return smu_cmn_send_smc_msg_with_param(smu, enable ? 1076 SMU_MSG_PowerUpVpe : SMU_MSG_PowerDownVpe, 1077 0, NULL); 1078 } 1079 1080 static int smu_v14_0_0_set_umsch_mm_enable(struct smu_context *smu, 1081 bool enable) 1082 { 1083 return smu_cmn_send_smc_msg_with_param(smu, enable ? 1084 SMU_MSG_PowerUpUmsch : SMU_MSG_PowerDownUmsch, 1085 0, NULL); 1086 } 1087 1088 static int smu_14_0_0_get_dpm_table(struct smu_context *smu, struct dpm_clocks *clock_table) 1089 { 1090 DpmClocks_t *clk_table = smu->smu_table.clocks_table; 1091 uint8_t idx; 1092 1093 /* Only the Clock information of SOC and VPE is copied to provide VPE DPM settings for use. */ 1094 for (idx = 0; idx < NUM_SOCCLK_DPM_LEVELS; idx++) { 1095 clock_table->SocClocks[idx].Freq = (idx < clk_table->NumSocClkLevelsEnabled) ? clk_table->SocClocks[idx]:0; 1096 clock_table->SocClocks[idx].Vol = 0; 1097 } 1098 1099 for (idx = 0; idx < NUM_VPE_DPM_LEVELS; idx++) { 1100 clock_table->VPEClocks[idx].Freq = (idx < clk_table->VpeClkLevelsEnabled) ? clk_table->VPEClocks[idx]:0; 1101 clock_table->VPEClocks[idx].Vol = 0; 1102 } 1103 1104 return 0; 1105 } 1106 1107 static const struct pptable_funcs smu_v14_0_0_ppt_funcs = { 1108 .check_fw_status = smu_v14_0_check_fw_status, 1109 .check_fw_version = smu_v14_0_check_fw_version, 1110 .init_smc_tables = smu_v14_0_0_init_smc_tables, 1111 .fini_smc_tables = smu_v14_0_0_fini_smc_tables, 1112 .get_vbios_bootup_values = smu_v14_0_get_vbios_bootup_values, 1113 .system_features_control = smu_v14_0_0_system_features_control, 1114 .send_smc_msg_with_param = smu_cmn_send_smc_msg_with_param, 1115 .send_smc_msg = smu_cmn_send_smc_msg, 1116 .dpm_set_vcn_enable = smu_v14_0_set_vcn_enable, 1117 .dpm_set_jpeg_enable = smu_v14_0_set_jpeg_enable, 1118 .set_default_dpm_table = smu_v14_0_set_default_dpm_tables, 1119 .read_sensor = smu_v14_0_0_read_sensor, 1120 .is_dpm_running = smu_v14_0_0_is_dpm_running, 1121 .set_watermarks_table = smu_v14_0_0_set_watermarks_table, 1122 .get_gpu_metrics = smu_v14_0_0_get_gpu_metrics, 1123 .get_enabled_mask = smu_cmn_get_enabled_mask, 1124 .get_pp_feature_mask = smu_cmn_get_pp_feature_mask, 1125 .set_driver_table_location = smu_v14_0_set_driver_table_location, 1126 .gfx_off_control = smu_v14_0_gfx_off_control, 1127 .mode2_reset = smu_v14_0_0_mode2_reset, 1128 .get_dpm_ultimate_freq = smu_v14_0_0_get_dpm_ultimate_freq, 1129 .od_edit_dpm_table = smu_v14_0_od_edit_dpm_table, 1130 .print_clk_levels = smu_v14_0_0_print_clk_levels, 1131 .force_clk_levels = smu_v14_0_0_force_clk_levels, 1132 .set_performance_level = smu_v14_0_0_set_performance_level, 1133 .set_fine_grain_gfx_freq_parameters = smu_v14_0_0_set_fine_grain_gfx_freq_parameters, 1134 .set_gfx_power_up_by_imu = smu_v14_0_set_gfx_power_up_by_imu, 1135 .dpm_set_vpe_enable = smu_v14_0_0_set_vpe_enable, 1136 .dpm_set_umsch_mm_enable = smu_v14_0_0_set_umsch_mm_enable, 1137 .get_dpm_clock_table = smu_14_0_0_get_dpm_table, 1138 }; 1139 1140 static void smu_v14_0_0_set_smu_mailbox_registers(struct smu_context *smu) 1141 { 1142 struct amdgpu_device *adev = smu->adev; 1143 1144 smu->param_reg = SOC15_REG_OFFSET(MP1, 0, mmMP1_SMN_C2PMSG_82); 1145 smu->msg_reg = SOC15_REG_OFFSET(MP1, 0, mmMP1_SMN_C2PMSG_66); 1146 smu->resp_reg = SOC15_REG_OFFSET(MP1, 0, mmMP1_SMN_C2PMSG_90); 1147 } 1148 1149 void smu_v14_0_0_set_ppt_funcs(struct smu_context *smu) 1150 { 1151 1152 smu->ppt_funcs = &smu_v14_0_0_ppt_funcs; 1153 smu->message_map = smu_v14_0_0_message_map; 1154 smu->feature_map = smu_v14_0_0_feature_mask_map; 1155 smu->table_map = smu_v14_0_0_table_map; 1156 smu->is_apu = true; 1157 1158 smu_v14_0_0_set_smu_mailbox_registers(smu); 1159 } 1160