FILE
smu_v14_0_0_ppt.c
File preview with syntax highlighting.
linux-6.19.14/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_0_ppt.c
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/* MALLPowerController message arguments (Defines for the Cache mode control) */ 56#define SMU_MALL_PMFW_CONTROL 0 57#define SMU_MALL_DRIVER_CONTROL 1 58 59/* 60 * MALLPowerState message arguments 61 * (Defines for the Allocate/Release Cache mode if in driver mode) 62 */ 63#define SMU_MALL_EXIT_PG 0 64#define SMU_MALL_ENTER_PG 1 65 66#define SMU_MALL_PG_CONFIG_DEFAULT SMU_MALL_PG_CONFIG_DRIVER_CONTROL_ALWAYS_ON 67 68#define SMU_14_0_0_UMD_PSTATE_GFXCLK 700 69#define SMU_14_0_0_UMD_PSTATE_SOCCLK 678 70#define SMU_14_0_0_UMD_PSTATE_FCLK 1800 71 72#define SMU_14_0_4_UMD_PSTATE_GFXCLK 938 73#define SMU_14_0_4_UMD_PSTATE_SOCCLK 938 74 75#define FEATURE_MASK(feature) (1ULL << feature) 76#define SMC_DPM_FEATURE ( \ 77 FEATURE_MASK(FEATURE_CCLK_DPM_BIT) | \ 78 FEATURE_MASK(FEATURE_VCN_DPM_BIT) | \ 79 FEATURE_MASK(FEATURE_FCLK_DPM_BIT) | \ 80 FEATURE_MASK(FEATURE_SOCCLK_DPM_BIT) | \ 81 FEATURE_MASK(FEATURE_LCLK_DPM_BIT) | \ 82 FEATURE_MASK(FEATURE_SHUBCLK_DPM_BIT) | \ 83 FEATURE_MASK(FEATURE_DCFCLK_DPM_BIT)| \ 84 FEATURE_MASK(FEATURE_ISP_DPM_BIT)| \ 85 FEATURE_MASK(FEATURE_IPU_DPM_BIT) | \ 86 FEATURE_MASK(FEATURE_GFX_DPM_BIT) | \ 87 FEATURE_MASK(FEATURE_VPE_DPM_BIT)) 88 89enum smu_mall_pg_config { 90 SMU_MALL_PG_CONFIG_PMFW_CONTROL = 0, 91 SMU_MALL_PG_CONFIG_DRIVER_CONTROL_ALWAYS_ON = 1, 92 SMU_MALL_PG_CONFIG_DRIVER_CONTROL_ALWAYS_OFF = 2, 93}; 94 95static struct cmn2asic_msg_mapping smu_v14_0_0_message_map[SMU_MSG_MAX_COUNT] = { 96 MSG_MAP(TestMessage, PPSMC_MSG_TestMessage, 1), 97 MSG_MAP(GetSmuVersion, PPSMC_MSG_GetPmfwVersion, 1), 98 MSG_MAP(GetDriverIfVersion, PPSMC_MSG_GetDriverIfVersion, 1), 99 MSG_MAP(PowerDownVcn0, PPSMC_MSG_PowerDownVcn0, 1), 100 MSG_MAP(PowerUpVcn0, PPSMC_MSG_PowerUpVcn0, 1), 101 MSG_MAP(SetHardMinVcn0, PPSMC_MSG_SetHardMinVcn0, 1), 102 MSG_MAP(PowerDownVcn1, PPSMC_MSG_PowerDownVcn1, 1), 103 MSG_MAP(PowerUpVcn1, PPSMC_MSG_PowerUpVcn1, 1), 104 MSG_MAP(SetHardMinVcn1, PPSMC_MSG_SetHardMinVcn1, 1), 105 MSG_MAP(SetSoftMinGfxclk, PPSMC_MSG_SetSoftMinGfxclk, 1), 106 MSG_MAP(PrepareMp1ForUnload, PPSMC_MSG_PrepareMp1ForUnload, 1), 107 MSG_MAP(SetDriverDramAddrHigh, PPSMC_MSG_SetDriverDramAddrHigh, 1), 108 MSG_MAP(SetDriverDramAddrLow, PPSMC_MSG_SetDriverDramAddrLow, 1), 109 MSG_MAP(TransferTableSmu2Dram, PPSMC_MSG_TransferTableSmu2Dram, 1), 110 MSG_MAP(TransferTableDram2Smu, PPSMC_MSG_TransferTableDram2Smu, 1), 111 MSG_MAP(GfxDeviceDriverReset, PPSMC_MSG_GfxDeviceDriverReset, 1), 112 MSG_MAP(GetEnabledSmuFeatures, PPSMC_MSG_GetEnabledSmuFeatures, 1), 113 MSG_MAP(SetHardMinSocclkByFreq, PPSMC_MSG_SetHardMinSocclkByFreq, 1), 114 MSG_MAP(SetSoftMinFclk, PPSMC_MSG_SetSoftMinFclk, 1), 115 MSG_MAP(SetSoftMinVcn0, PPSMC_MSG_SetSoftMinVcn0, 1), 116 MSG_MAP(SetSoftMinVcn1, PPSMC_MSG_SetSoftMinVcn1, 1), 117 MSG_MAP(EnableGfxImu, PPSMC_MSG_EnableGfxImu, 1), 118 MSG_MAP(AllowGfxOff, PPSMC_MSG_AllowGfxOff, 1), 119 MSG_MAP(DisallowGfxOff, PPSMC_MSG_DisallowGfxOff, 1), 120 MSG_MAP(SetSoftMaxGfxClk, PPSMC_MSG_SetSoftMaxGfxClk, 1), 121 MSG_MAP(SetHardMinGfxClk, PPSMC_MSG_SetHardMinGfxClk, 1), 122 MSG_MAP(SetSoftMaxSocclkByFreq, PPSMC_MSG_SetSoftMaxSocclkByFreq, 1), 123 MSG_MAP(SetSoftMaxFclkByFreq, PPSMC_MSG_SetSoftMaxFclkByFreq, 1), 124 MSG_MAP(SetSoftMaxVcn0, PPSMC_MSG_SetSoftMaxVcn0, 1), 125 MSG_MAP(SetSoftMaxVcn1, PPSMC_MSG_SetSoftMaxVcn1, 1), 126 MSG_MAP(PowerDownJpeg0, PPSMC_MSG_PowerDownJpeg0, 1), 127 MSG_MAP(PowerUpJpeg0, PPSMC_MSG_PowerUpJpeg0, 1), 128 MSG_MAP(PowerDownJpeg1, PPSMC_MSG_PowerDownJpeg1, 1), 129 MSG_MAP(PowerUpJpeg1, PPSMC_MSG_PowerUpJpeg1, 1), 130 MSG_MAP(SetHardMinFclkByFreq, PPSMC_MSG_SetHardMinFclkByFreq, 1), 131 MSG_MAP(SetSoftMinSocclkByFreq, PPSMC_MSG_SetSoftMinSocclkByFreq, 1), 132 MSG_MAP(PowerDownIspByTile, PPSMC_MSG_PowerDownIspByTile, 1), 133 MSG_MAP(PowerUpIspByTile, PPSMC_MSG_PowerUpIspByTile, 1), 134 MSG_MAP(SetHardMinIspiclkByFreq, PPSMC_MSG_SetHardMinIspiclkByFreq, 1), 135 MSG_MAP(SetHardMinIspxclkByFreq, PPSMC_MSG_SetHardMinIspxclkByFreq, 1), 136 MSG_MAP(PowerUpVpe, PPSMC_MSG_PowerUpVpe, 1), 137 MSG_MAP(PowerDownVpe, PPSMC_MSG_PowerDownVpe, 1), 138 MSG_MAP(PowerUpUmsch, PPSMC_MSG_PowerUpUmsch, 1), 139 MSG_MAP(PowerDownUmsch, PPSMC_MSG_PowerDownUmsch, 1), 140 MSG_MAP(SetSoftMaxVpe, PPSMC_MSG_SetSoftMaxVpe, 1), 141 MSG_MAP(SetSoftMinVpe, PPSMC_MSG_SetSoftMinVpe, 1), 142 MSG_MAP(MALLPowerController, PPSMC_MSG_MALLPowerController, 1), 143 MSG_MAP(MALLPowerState, PPSMC_MSG_MALLPowerState, 1), 144}; 145 146static struct cmn2asic_mapping smu_v14_0_0_feature_mask_map[SMU_FEATURE_COUNT] = { 147 FEA_MAP(CCLK_DPM), 148 FEA_MAP(FAN_CONTROLLER), 149 FEA_MAP(PPT), 150 FEA_MAP(TDC), 151 FEA_MAP(THERMAL), 152 FEA_MAP(VCN_DPM), 153 FEA_MAP_REVERSE(FCLK), 154 FEA_MAP_REVERSE(SOCCLK), 155 FEA_MAP(LCLK_DPM), 156 FEA_MAP(SHUBCLK_DPM), 157 FEA_MAP(DCFCLK_DPM), 158 FEA_MAP_HALF_REVERSE(GFX), 159 FEA_MAP(DS_GFXCLK), 160 FEA_MAP(DS_SOCCLK), 161 FEA_MAP(DS_LCLK), 162 FEA_MAP(LOW_POWER_DCNCLKS), 163 FEA_MAP(DS_FCLK), 164 FEA_MAP(DS_MP1CLK), 165 FEA_MAP(PSI), 166 FEA_MAP(PROCHOT), 167 FEA_MAP(CPUOFF), 168 FEA_MAP(STAPM), 169 FEA_MAP(S0I3), 170 FEA_MAP(PERF_LIMIT), 171 FEA_MAP(CORE_DLDO), 172 FEA_MAP(DS_VCN), 173 FEA_MAP(CPPC), 174 FEA_MAP(DF_CSTATES), 175 FEA_MAP(ATHUB_PG), 176}; 177 178static struct cmn2asic_mapping smu_v14_0_0_table_map[SMU_TABLE_COUNT] = { 179 TAB_MAP_VALID(WATERMARKS), 180 TAB_MAP_VALID(SMU_METRICS), 181 TAB_MAP_VALID(CUSTOM_DPM), 182 TAB_MAP_VALID(DPMCLOCKS), 183}; 184 185static int smu_v14_0_0_init_smc_tables(struct smu_context *smu) 186{ 187 struct smu_table_context *smu_table = &smu->smu_table; 188 struct smu_table *tables = smu_table->tables; 189 190 SMU_TABLE_INIT(tables, SMU_TABLE_WATERMARKS, sizeof(Watermarks_t), 191 PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM); 192 SMU_TABLE_INIT(tables, SMU_TABLE_DPMCLOCKS, max(sizeof(DpmClocks_t), sizeof(DpmClocks_t_v14_0_1)), 193 PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM); 194 SMU_TABLE_INIT(tables, SMU_TABLE_SMU_METRICS, sizeof(SmuMetrics_t), 195 PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM); 196 197 smu_table->metrics_table = kzalloc(sizeof(SmuMetrics_t), GFP_KERNEL); 198 if (!smu_table->metrics_table) 199 goto err0_out; 200 smu_table->metrics_time = 0; 201 202 smu_table->clocks_table = kzalloc(max(sizeof(DpmClocks_t), sizeof(DpmClocks_t_v14_0_1)), GFP_KERNEL); 203 if (!smu_table->clocks_table) 204 goto err1_out; 205 206 smu_table->watermarks_table = kzalloc(sizeof(Watermarks_t), GFP_KERNEL); 207 if (!smu_table->watermarks_table) 208 goto err2_out; 209 210 smu_table->gpu_metrics_table_size = sizeof(struct gpu_metrics_v3_0); 211 smu_table->gpu_metrics_table = kzalloc(smu_table->gpu_metrics_table_size, GFP_KERNEL); 212 if (!smu_table->gpu_metrics_table) 213 goto err3_out; 214 215 return 0; 216 217err3_out: 218 kfree(smu_table->watermarks_table); 219err2_out: 220 kfree(smu_table->clocks_table); 221err1_out: 222 kfree(smu_table->metrics_table); 223err0_out: 224 return -ENOMEM; 225} 226 227static int smu_v14_0_0_fini_smc_tables(struct smu_context *smu) 228{ 229 struct smu_table_context *smu_table = &smu->smu_table; 230 231 kfree(smu_table->clocks_table); 232 smu_table->clocks_table = NULL; 233 234 kfree(smu_table->metrics_table); 235 smu_table->metrics_table = NULL; 236 237 kfree(smu_table->watermarks_table); 238 smu_table->watermarks_table = NULL; 239 240 kfree(smu_table->gpu_metrics_table); 241 smu_table->gpu_metrics_table = NULL; 242 243 return 0; 244} 245 246static int smu_v14_0_0_system_features_control(struct smu_context *smu, bool en) 247{ 248 struct amdgpu_device *adev = smu->adev; 249 int ret = 0; 250 251 if (!en && !adev->in_s0ix) 252 ret = smu_cmn_send_smc_msg(smu, SMU_MSG_PrepareMp1ForUnload, NULL); 253 254 return ret; 255} 256 257static int smu_v14_0_0_get_smu_metrics_data(struct smu_context *smu, 258 MetricsMember_t member, 259 uint32_t *value) 260{ 261 struct smu_table_context *smu_table = &smu->smu_table; 262 263 SmuMetrics_t *metrics = (SmuMetrics_t *)smu_table->metrics_table; 264 int ret = 0; 265 266 ret = smu_cmn_get_metrics_table(smu, NULL, false); 267 if (ret) 268 return ret; 269 270 switch (member) { 271 case METRICS_AVERAGE_GFXCLK: 272 *value = metrics->GfxclkFrequency; 273 break; 274 case METRICS_AVERAGE_SOCCLK: 275 *value = metrics->SocclkFrequency; 276 break; 277 case METRICS_AVERAGE_VCLK: 278 *value = metrics->VclkFrequency; 279 break; 280 case METRICS_AVERAGE_DCLK: 281 *value = 0; 282 break; 283 case METRICS_AVERAGE_UCLK: 284 *value = metrics->MemclkFrequency; 285 break; 286 case METRICS_AVERAGE_FCLK: 287 *value = metrics->FclkFrequency; 288 break; 289 case METRICS_AVERAGE_VPECLK: 290 *value = metrics->VpeclkFrequency; 291 break; 292 case METRICS_AVERAGE_IPUCLK: 293 *value = metrics->IpuclkFrequency; 294 break; 295 case METRICS_AVERAGE_MPIPUCLK: 296 *value = metrics->MpipuclkFrequency; 297 break; 298 case METRICS_AVERAGE_GFXACTIVITY: 299 if ((smu->smc_fw_version > 0x5d4600)) 300 *value = metrics->GfxActivity; 301 else 302 *value = metrics->GfxActivity / 100; 303 break; 304 case METRICS_AVERAGE_VCNACTIVITY: 305 *value = metrics->VcnActivity / 100; 306 break; 307 case METRICS_AVERAGE_SOCKETPOWER: 308 case METRICS_CURR_SOCKETPOWER: 309 *value = (metrics->SocketPower / 1000 << 8) + 310 (metrics->SocketPower % 1000 / 10); 311 break; 312 case METRICS_TEMPERATURE_EDGE: 313 *value = metrics->GfxTemperature / 100 * 314 SMU_TEMPERATURE_UNITS_PER_CENTIGRADES; 315 break; 316 case METRICS_TEMPERATURE_HOTSPOT: 317 *value = metrics->SocTemperature / 100 * 318 SMU_TEMPERATURE_UNITS_PER_CENTIGRADES; 319 break; 320 case METRICS_THROTTLER_RESIDENCY_PROCHOT: 321 *value = metrics->ThrottleResidency_PROCHOT; 322 break; 323 case METRICS_THROTTLER_RESIDENCY_SPL: 324 *value = metrics->ThrottleResidency_SPL; 325 break; 326 case METRICS_THROTTLER_RESIDENCY_FPPT: 327 *value = metrics->ThrottleResidency_FPPT; 328 break; 329 case METRICS_THROTTLER_RESIDENCY_SPPT: 330 *value = metrics->ThrottleResidency_SPPT; 331 break; 332 case METRICS_THROTTLER_RESIDENCY_THM_CORE: 333 *value = metrics->ThrottleResidency_THM_CORE; 334 break; 335 case METRICS_THROTTLER_RESIDENCY_THM_GFX: 336 *value = metrics->ThrottleResidency_THM_GFX; 337 break; 338 case METRICS_THROTTLER_RESIDENCY_THM_SOC: 339 *value = metrics->ThrottleResidency_THM_SOC; 340 break; 341 case METRICS_VOLTAGE_VDDGFX: 342 *value = 0; 343 break; 344 case METRICS_VOLTAGE_VDDSOC: 345 *value = 0; 346 break; 347 case METRICS_SS_APU_SHARE: 348 /* return the percentage of APU power with respect to APU's power limit. 349 * percentage is reported, this isn't boost value. Smartshift power 350 * boost/shift is only when the percentage is more than 100. 351 */ 352 if (metrics->StapmOpnLimit > 0) 353 *value = (metrics->ApuPower * 100) / metrics->StapmOpnLimit; 354 else 355 *value = 0; 356 break; 357 case METRICS_SS_DGPU_SHARE: 358 /* return the percentage of dGPU power with respect to dGPU's power limit. 359 * percentage is reported, this isn't boost value. Smartshift power 360 * boost/shift is only when the percentage is more than 100. 361 */ 362 if ((metrics->dGpuPower > 0) && 363 (metrics->StapmCurrentLimit > metrics->StapmOpnLimit)) 364 *value = (metrics->dGpuPower * 100) / 365 (metrics->StapmCurrentLimit - metrics->StapmOpnLimit); 366 else 367 *value = 0; 368 break; 369 default: 370 *value = UINT_MAX; 371 break; 372 } 373 374 return ret; 375} 376 377static int smu_v14_0_0_read_sensor(struct smu_context *smu, 378 enum amd_pp_sensors sensor, 379 void *data, uint32_t *size) 380{ 381 int ret = 0; 382 383 if (!data || !size) 384 return -EINVAL; 385 386 switch (sensor) { 387 case AMDGPU_PP_SENSOR_GPU_LOAD: 388 ret = smu_v14_0_0_get_smu_metrics_data(smu, 389 METRICS_AVERAGE_GFXACTIVITY, 390 (uint32_t *)data); 391 *size = 4; 392 break; 393 case AMDGPU_PP_SENSOR_VCN_LOAD: 394 ret = smu_v14_0_0_get_smu_metrics_data(smu, 395 METRICS_AVERAGE_VCNACTIVITY, 396 (uint32_t *)data); 397 *size = 4; 398 break; 399 case AMDGPU_PP_SENSOR_GPU_AVG_POWER: 400 ret = smu_v14_0_0_get_smu_metrics_data(smu, 401 METRICS_AVERAGE_SOCKETPOWER, 402 (uint32_t *)data); 403 *size = 4; 404 break; 405 case AMDGPU_PP_SENSOR_GPU_INPUT_POWER: 406 ret = smu_v14_0_0_get_smu_metrics_data(smu, 407 METRICS_CURR_SOCKETPOWER, 408 (uint32_t *)data); 409 *size = 4; 410 break; 411 case AMDGPU_PP_SENSOR_EDGE_TEMP: 412 ret = smu_v14_0_0_get_smu_metrics_data(smu, 413 METRICS_TEMPERATURE_EDGE, 414 (uint32_t *)data); 415 *size = 4; 416 break; 417 case AMDGPU_PP_SENSOR_HOTSPOT_TEMP: 418 ret = smu_v14_0_0_get_smu_metrics_data(smu, 419 METRICS_TEMPERATURE_HOTSPOT, 420 (uint32_t *)data); 421 *size = 4; 422 break; 423 case AMDGPU_PP_SENSOR_GFX_MCLK: 424 ret = smu_v14_0_0_get_smu_metrics_data(smu, 425 METRICS_AVERAGE_UCLK, 426 (uint32_t *)data); 427 *(uint32_t *)data *= 100; 428 *size = 4; 429 break; 430 case AMDGPU_PP_SENSOR_GFX_SCLK: 431 ret = smu_v14_0_0_get_smu_metrics_data(smu, 432 METRICS_AVERAGE_GFXCLK, 433 (uint32_t *)data); 434 *(uint32_t *)data *= 100; 435 *size = 4; 436 break; 437 case AMDGPU_PP_SENSOR_VDDGFX: 438 ret = smu_v14_0_0_get_smu_metrics_data(smu, 439 METRICS_VOLTAGE_VDDGFX, 440 (uint32_t *)data); 441 *size = 4; 442 break; 443 case AMDGPU_PP_SENSOR_VDDNB: 444 ret = smu_v14_0_0_get_smu_metrics_data(smu, 445 METRICS_VOLTAGE_VDDSOC, 446 (uint32_t *)data); 447 *size = 4; 448 break; 449 case AMDGPU_PP_SENSOR_SS_APU_SHARE: 450 ret = smu_v14_0_0_get_smu_metrics_data(smu, 451 METRICS_SS_APU_SHARE, 452 (uint32_t *)data); 453 *size = 4; 454 break; 455 case AMDGPU_PP_SENSOR_SS_DGPU_SHARE: 456 ret = smu_v14_0_0_get_smu_metrics_data(smu, 457 METRICS_SS_DGPU_SHARE, 458 (uint32_t *)data); 459 *size = 4; 460 break; 461 default: 462 ret = -EOPNOTSUPP; 463 break; 464 } 465 466 return ret; 467} 468 469static bool smu_v14_0_0_is_dpm_running(struct smu_context *smu) 470{ 471 int ret = 0; 472 uint64_t feature_enabled; 473 474 ret = smu_cmn_get_enabled_mask(smu, &feature_enabled); 475 476 if (ret) 477 return false; 478 479 return !!(feature_enabled & SMC_DPM_FEATURE); 480} 481 482static int smu_v14_0_0_set_watermarks_table(struct smu_context *smu, 483 struct pp_smu_wm_range_sets *clock_ranges) 484{ 485 int i; 486 int ret = 0; 487 Watermarks_t *table = smu->smu_table.watermarks_table; 488 489 if (!table || !clock_ranges) 490 return -EINVAL; 491 492 if (clock_ranges->num_reader_wm_sets > NUM_WM_RANGES || 493 clock_ranges->num_writer_wm_sets > NUM_WM_RANGES) 494 return -EINVAL; 495 496 for (i = 0; i < clock_ranges->num_reader_wm_sets; i++) { 497 table->WatermarkRow[WM_DCFCLK][i].MinClock = 498 clock_ranges->reader_wm_sets[i].min_drain_clk_mhz; 499 table->WatermarkRow[WM_DCFCLK][i].MaxClock = 500 clock_ranges->reader_wm_sets[i].max_drain_clk_mhz; 501 table->WatermarkRow[WM_DCFCLK][i].MinMclk = 502 clock_ranges->reader_wm_sets[i].min_fill_clk_mhz; 503 table->WatermarkRow[WM_DCFCLK][i].MaxMclk = 504 clock_ranges->reader_wm_sets[i].max_fill_clk_mhz; 505 506 table->WatermarkRow[WM_DCFCLK][i].WmSetting = 507 clock_ranges->reader_wm_sets[i].wm_inst; 508 } 509 510 for (i = 0; i < clock_ranges->num_writer_wm_sets; i++) { 511 table->WatermarkRow[WM_SOCCLK][i].MinClock = 512 clock_ranges->writer_wm_sets[i].min_fill_clk_mhz; 513 table->WatermarkRow[WM_SOCCLK][i].MaxClock = 514 clock_ranges->writer_wm_sets[i].max_fill_clk_mhz; 515 table->WatermarkRow[WM_SOCCLK][i].MinMclk = 516 clock_ranges->writer_wm_sets[i].min_drain_clk_mhz; 517 table->WatermarkRow[WM_SOCCLK][i].MaxMclk = 518 clock_ranges->writer_wm_sets[i].max_drain_clk_mhz; 519 520 table->WatermarkRow[WM_SOCCLK][i].WmSetting = 521 clock_ranges->writer_wm_sets[i].wm_inst; 522 } 523 524 smu->watermarks_bitmap |= WATERMARKS_EXIST; 525 526 /* pass data to smu controller */ 527 if ((smu->watermarks_bitmap & WATERMARKS_EXIST) && 528 !(smu->watermarks_bitmap & WATERMARKS_LOADED)) { 529 ret = smu_cmn_write_watermarks_table(smu); 530 if (ret) { 531 dev_err(smu->adev->dev, "Failed to update WMTABLE!"); 532 return ret; 533 } 534 smu->watermarks_bitmap |= WATERMARKS_LOADED; 535 } 536 537 return 0; 538} 539 540static ssize_t smu_v14_0_0_get_gpu_metrics(struct smu_context *smu, 541 void **table) 542{ 543 struct smu_table_context *smu_table = &smu->smu_table; 544 struct gpu_metrics_v3_0 *gpu_metrics = 545 (struct gpu_metrics_v3_0 *)smu_table->gpu_metrics_table; 546 SmuMetrics_t metrics; 547 int ret = 0; 548 549 ret = smu_cmn_get_metrics_table(smu, &metrics, true); 550 if (ret) 551 return ret; 552 553 smu_cmn_init_soft_gpu_metrics(gpu_metrics, 3, 0); 554 555 gpu_metrics->temperature_gfx = metrics.GfxTemperature; 556 gpu_metrics->temperature_soc = metrics.SocTemperature; 557 memcpy(&gpu_metrics->temperature_core[0], 558 &metrics.CoreTemperature[0], 559 sizeof(uint16_t) * 16); 560 gpu_metrics->temperature_skin = metrics.SkinTemp; 561 562 gpu_metrics->average_gfx_activity = metrics.GfxActivity; 563 gpu_metrics->average_vcn_activity = metrics.VcnActivity; 564 memcpy(&gpu_metrics->average_ipu_activity[0], 565 &metrics.IpuBusy[0], 566 sizeof(uint16_t) * 8); 567 memcpy(&gpu_metrics->average_core_c0_activity[0], 568 &metrics.CoreC0Residency[0], 569 sizeof(uint16_t) * 16); 570 gpu_metrics->average_dram_reads = metrics.DRAMReads; 571 gpu_metrics->average_dram_writes = metrics.DRAMWrites; 572 gpu_metrics->average_ipu_reads = metrics.IpuReads; 573 gpu_metrics->average_ipu_writes = metrics.IpuWrites; 574 575 gpu_metrics->average_socket_power = metrics.SocketPower; 576 gpu_metrics->average_ipu_power = metrics.IpuPower; 577 gpu_metrics->average_apu_power = metrics.ApuPower; 578 gpu_metrics->average_gfx_power = metrics.GfxPower; 579 gpu_metrics->average_dgpu_power = metrics.dGpuPower; 580 gpu_metrics->average_all_core_power = metrics.AllCorePower; 581 gpu_metrics->average_sys_power = metrics.Psys; 582 memcpy(&gpu_metrics->average_core_power[0], 583 &metrics.CorePower[0], 584 sizeof(uint16_t) * 16); 585 586 gpu_metrics->average_gfxclk_frequency = metrics.GfxclkFrequency; 587 gpu_metrics->average_socclk_frequency = metrics.SocclkFrequency; 588 gpu_metrics->average_vpeclk_frequency = metrics.VpeclkFrequency; 589 gpu_metrics->average_fclk_frequency = metrics.FclkFrequency; 590 gpu_metrics->average_vclk_frequency = metrics.VclkFrequency; 591 gpu_metrics->average_ipuclk_frequency = metrics.IpuclkFrequency; 592 gpu_metrics->average_uclk_frequency = metrics.MemclkFrequency; 593 gpu_metrics->average_mpipu_frequency = metrics.MpipuclkFrequency; 594 595 memcpy(&gpu_metrics->current_coreclk[0], 596 &metrics.CoreFrequency[0], 597 sizeof(uint16_t) * 16); 598 gpu_metrics->current_core_maxfreq = metrics.InfrastructureCpuMaxFreq; 599 gpu_metrics->current_gfx_maxfreq = metrics.InfrastructureGfxMaxFreq; 600 601 gpu_metrics->throttle_residency_prochot = metrics.ThrottleResidency_PROCHOT; 602 gpu_metrics->throttle_residency_spl = metrics.ThrottleResidency_SPL; 603 gpu_metrics->throttle_residency_fppt = metrics.ThrottleResidency_FPPT; 604 gpu_metrics->throttle_residency_sppt = metrics.ThrottleResidency_SPPT; 605 gpu_metrics->throttle_residency_thm_core = metrics.ThrottleResidency_THM_CORE; 606 gpu_metrics->throttle_residency_thm_gfx = metrics.ThrottleResidency_THM_GFX; 607 gpu_metrics->throttle_residency_thm_soc = metrics.ThrottleResidency_THM_SOC; 608 609 gpu_metrics->time_filter_alphavalue = metrics.FilterAlphaValue; 610 gpu_metrics->system_clock_counter = ktime_get_boottime_ns(); 611 612 *table = (void *)gpu_metrics; 613 614 return sizeof(struct gpu_metrics_v3_0); 615} 616 617static int smu_v14_0_0_mode2_reset(struct smu_context *smu) 618{ 619 int ret; 620 621 ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_GfxDeviceDriverReset, 622 SMU_RESET_MODE_2, NULL); 623 624 if (ret) 625 dev_err(smu->adev->dev, "Failed to mode2 reset!\n"); 626 627 return ret; 628} 629 630static int smu_v14_0_1_get_dpm_freq_by_index(struct smu_context *smu, 631 enum smu_clk_type clk_type, 632 uint32_t dpm_level, 633 uint32_t *freq) 634{ 635 DpmClocks_t_v14_0_1 *clk_table = smu->smu_table.clocks_table; 636 637 if (!clk_table || clk_type >= SMU_CLK_COUNT) 638 return -EINVAL; 639 640 switch (clk_type) { 641 case SMU_SOCCLK: 642 if (dpm_level >= clk_table->NumSocClkLevelsEnabled) 643 return -EINVAL; 644 *freq = clk_table->SocClocks[dpm_level]; 645 break; 646 case SMU_VCLK: 647 if (dpm_level >= clk_table->Vcn0ClkLevelsEnabled) 648 return -EINVAL; 649 *freq = clk_table->VClocks0[dpm_level]; 650 break; 651 case SMU_DCLK: 652 if (dpm_level >= clk_table->Vcn0ClkLevelsEnabled) 653 return -EINVAL; 654 *freq = clk_table->DClocks0[dpm_level]; 655 break; 656 case SMU_VCLK1: 657 if (dpm_level >= clk_table->Vcn1ClkLevelsEnabled) 658 return -EINVAL; 659 *freq = clk_table->VClocks1[dpm_level]; 660 break; 661 case SMU_DCLK1: 662 if (dpm_level >= clk_table->Vcn1ClkLevelsEnabled) 663 return -EINVAL; 664 *freq = clk_table->DClocks1[dpm_level]; 665 break; 666 case SMU_UCLK: 667 case SMU_MCLK: 668 if (dpm_level >= clk_table->NumMemPstatesEnabled) 669 return -EINVAL; 670 *freq = clk_table->MemPstateTable[dpm_level].MemClk; 671 break; 672 case SMU_FCLK: 673 if (dpm_level >= clk_table->NumFclkLevelsEnabled) 674 return -EINVAL; 675 *freq = clk_table->FclkClocks_Freq[dpm_level]; 676 break; 677 default: 678 return -EINVAL; 679 } 680 681 return 0; 682} 683 684static int smu_v14_0_0_get_dpm_freq_by_index(struct smu_context *smu, 685 enum smu_clk_type clk_type, 686 uint32_t dpm_level, 687 uint32_t *freq) 688{ 689 DpmClocks_t *clk_table = smu->smu_table.clocks_table; 690 691 if (!clk_table || clk_type >= SMU_CLK_COUNT) 692 return -EINVAL; 693 694 switch (clk_type) { 695 case SMU_SOCCLK: 696 if (dpm_level >= clk_table->NumSocClkLevelsEnabled) 697 return -EINVAL; 698 *freq = clk_table->SocClocks[dpm_level]; 699 break; 700 case SMU_VCLK: 701 if (dpm_level >= clk_table->VcnClkLevelsEnabled) 702 return -EINVAL; 703 *freq = clk_table->VClocks[dpm_level]; 704 break; 705 case SMU_DCLK: 706 if (dpm_level >= clk_table->VcnClkLevelsEnabled) 707 return -EINVAL; 708 *freq = clk_table->DClocks[dpm_level]; 709 break; 710 case SMU_UCLK: 711 case SMU_MCLK: 712 if (dpm_level >= clk_table->NumMemPstatesEnabled) 713 return -EINVAL; 714 *freq = clk_table->MemPstateTable[dpm_level].MemClk; 715 break; 716 case SMU_FCLK: 717 if (dpm_level >= clk_table->NumFclkLevelsEnabled) 718 return -EINVAL; 719 *freq = clk_table->FclkClocks_Freq[dpm_level]; 720 break; 721 default: 722 return -EINVAL; 723 } 724 725 return 0; 726} 727 728static int smu_v14_0_common_get_dpm_freq_by_index(struct smu_context *smu, 729 enum smu_clk_type clk_type, 730 uint32_t dpm_level, 731 uint32_t *freq) 732{ 733 if (amdgpu_ip_version(smu->adev, MP1_HWIP, 0) == IP_VERSION(14, 0, 1)) 734 smu_v14_0_1_get_dpm_freq_by_index(smu, clk_type, dpm_level, freq); 735 else if (clk_type != SMU_VCLK1 && clk_type != SMU_DCLK1) 736 smu_v14_0_0_get_dpm_freq_by_index(smu, clk_type, dpm_level, freq); 737 738 return 0; 739} 740 741static bool smu_v14_0_0_clk_dpm_is_enabled(struct smu_context *smu, 742 enum smu_clk_type clk_type) 743{ 744 enum smu_feature_mask feature_id = 0; 745 746 switch (clk_type) { 747 case SMU_MCLK: 748 case SMU_UCLK: 749 case SMU_FCLK: 750 feature_id = SMU_FEATURE_DPM_FCLK_BIT; 751 break; 752 case SMU_GFXCLK: 753 case SMU_SCLK: 754 feature_id = SMU_FEATURE_DPM_GFXCLK_BIT; 755 break; 756 case SMU_SOCCLK: 757 feature_id = SMU_FEATURE_DPM_SOCCLK_BIT; 758 break; 759 case SMU_VCLK: 760 case SMU_DCLK: 761 case SMU_VCLK1: 762 case SMU_DCLK1: 763 feature_id = SMU_FEATURE_VCN_DPM_BIT; 764 break; 765 default: 766 return true; 767 } 768 769 return smu_cmn_feature_is_enabled(smu, feature_id); 770} 771 772static int smu_v14_0_1_get_dpm_ultimate_freq(struct smu_context *smu, 773 enum smu_clk_type clk_type, 774 uint32_t *min, 775 uint32_t *max) 776{ 777 DpmClocks_t_v14_0_1 *clk_table = smu->smu_table.clocks_table; 778 uint32_t clock_limit; 779 uint32_t max_dpm_level, min_dpm_level; 780 int ret = 0; 781 782 if (!smu_v14_0_0_clk_dpm_is_enabled(smu, clk_type)) { 783 switch (clk_type) { 784 case SMU_MCLK: 785 case SMU_UCLK: 786 clock_limit = smu->smu_table.boot_values.uclk; 787 break; 788 case SMU_FCLK: 789 clock_limit = smu->smu_table.boot_values.fclk; 790 break; 791 case SMU_GFXCLK: 792 case SMU_SCLK: 793 clock_limit = smu->smu_table.boot_values.gfxclk; 794 break; 795 case SMU_SOCCLK: 796 clock_limit = smu->smu_table.boot_values.socclk; 797 break; 798 case SMU_VCLK: 799 case SMU_VCLK1: 800 clock_limit = smu->smu_table.boot_values.vclk; 801 break; 802 case SMU_DCLK: 803 case SMU_DCLK1: 804 clock_limit = smu->smu_table.boot_values.dclk; 805 break; 806 default: 807 clock_limit = 0; 808 break; 809 } 810 811 /* clock in Mhz unit */ 812 if (min) 813 *min = clock_limit / 100; 814 if (max) 815 *max = clock_limit / 100; 816 817 return 0; 818 } 819 820 if (max) { 821 switch (clk_type) { 822 case SMU_GFXCLK: 823 case SMU_SCLK: 824 *max = clk_table->MaxGfxClk; 825 break; 826 case SMU_MCLK: 827 case SMU_UCLK: 828 max_dpm_level = 0; 829 break; 830 case SMU_FCLK: 831 max_dpm_level = clk_table->NumFclkLevelsEnabled - 1; 832 break; 833 case SMU_SOCCLK: 834 max_dpm_level = clk_table->NumSocClkLevelsEnabled - 1; 835 break; 836 case SMU_VCLK: 837 case SMU_DCLK: 838 max_dpm_level = clk_table->Vcn0ClkLevelsEnabled - 1; 839 break; 840 case SMU_VCLK1: 841 case SMU_DCLK1: 842 max_dpm_level = clk_table->Vcn1ClkLevelsEnabled - 1; 843 break; 844 default: 845 ret = -EINVAL; 846 goto failed; 847 } 848 849 if (clk_type != SMU_GFXCLK && clk_type != SMU_SCLK) { 850 ret = smu_v14_0_common_get_dpm_freq_by_index(smu, clk_type, max_dpm_level, max); 851 if (ret) 852 goto failed; 853 } 854 } 855 856 if (min) { 857 switch (clk_type) { 858 case SMU_GFXCLK: 859 case SMU_SCLK: 860 *min = clk_table->MinGfxClk; 861 break; 862 case SMU_MCLK: 863 case SMU_UCLK: 864 min_dpm_level = clk_table->NumMemPstatesEnabled - 1; 865 break; 866 case SMU_FCLK: 867 min_dpm_level = 0; 868 break; 869 case SMU_SOCCLK: 870 min_dpm_level = 0; 871 break; 872 case SMU_VCLK: 873 case SMU_DCLK: 874 case SMU_VCLK1: 875 case SMU_DCLK1: 876 min_dpm_level = 0; 877 break; 878 default: 879 ret = -EINVAL; 880 goto failed; 881 } 882 883 if (clk_type != SMU_GFXCLK && clk_type != SMU_SCLK) { 884 ret = smu_v14_0_common_get_dpm_freq_by_index(smu, clk_type, min_dpm_level, min); 885 if (ret) 886 goto failed; 887 } 888 } 889 890failed: 891 return ret; 892} 893 894static int smu_v14_0_0_get_dpm_ultimate_freq(struct smu_context *smu, 895 enum smu_clk_type clk_type, 896 uint32_t *min, 897 uint32_t *max) 898{ 899 DpmClocks_t *clk_table = smu->smu_table.clocks_table; 900 uint32_t clock_limit; 901 uint32_t max_dpm_level, min_dpm_level; 902 int ret = 0; 903 904 if (!smu_v14_0_0_clk_dpm_is_enabled(smu, clk_type)) { 905 switch (clk_type) { 906 case SMU_MCLK: 907 case SMU_UCLK: 908 clock_limit = smu->smu_table.boot_values.uclk; 909 break; 910 case SMU_FCLK: 911 clock_limit = smu->smu_table.boot_values.fclk; 912 break; 913 case SMU_GFXCLK: 914 case SMU_SCLK: 915 clock_limit = smu->smu_table.boot_values.gfxclk; 916 break; 917 case SMU_SOCCLK: 918 clock_limit = smu->smu_table.boot_values.socclk; 919 break; 920 case SMU_VCLK: 921 clock_limit = smu->smu_table.boot_values.vclk; 922 break; 923 case SMU_DCLK: 924 clock_limit = smu->smu_table.boot_values.dclk; 925 break; 926 default: 927 clock_limit = 0; 928 break; 929 } 930 931 /* clock in Mhz unit */ 932 if (min) 933 *min = clock_limit / 100; 934 if (max) 935 *max = clock_limit / 100; 936 937 return 0; 938 } 939 940 if (max) { 941 switch (clk_type) { 942 case SMU_GFXCLK: 943 case SMU_SCLK: 944 *max = clk_table->MaxGfxClk; 945 break; 946 case SMU_MCLK: 947 case SMU_UCLK: 948 max_dpm_level = 0; 949 break; 950 case SMU_FCLK: 951 max_dpm_level = clk_table->NumFclkLevelsEnabled - 1; 952 break; 953 case SMU_SOCCLK: 954 max_dpm_level = clk_table->NumSocClkLevelsEnabled - 1; 955 break; 956 case SMU_VCLK: 957 case SMU_DCLK: 958 max_dpm_level = clk_table->VcnClkLevelsEnabled - 1; 959 break; 960 default: 961 ret = -EINVAL; 962 goto failed; 963 } 964 965 if (clk_type != SMU_GFXCLK && clk_type != SMU_SCLK) { 966 ret = smu_v14_0_common_get_dpm_freq_by_index(smu, clk_type, max_dpm_level, max); 967 if (ret) 968 goto failed; 969 } 970 } 971 972 if (min) { 973 switch (clk_type) { 974 case SMU_GFXCLK: 975 case SMU_SCLK: 976 *min = clk_table->MinGfxClk; 977 break; 978 case SMU_MCLK: 979 case SMU_UCLK: 980 min_dpm_level = clk_table->NumMemPstatesEnabled - 1; 981 break; 982 case SMU_FCLK: 983 min_dpm_level = 0; 984 break; 985 case SMU_SOCCLK: 986 min_dpm_level = 0; 987 break; 988 case SMU_VCLK: 989 case SMU_DCLK: 990 min_dpm_level = 0; 991 break; 992 default: 993 ret = -EINVAL; 994 goto failed; 995 } 996 997 if (clk_type != SMU_GFXCLK && clk_type != SMU_SCLK) { 998 ret = smu_v14_0_common_get_dpm_freq_by_index(smu, clk_type, min_dpm_level, min); 999 if (ret) 1000 goto failed; 1001 } 1002 } 1003 1004failed: 1005 return ret; 1006} 1007 1008static int smu_v14_0_common_get_dpm_ultimate_freq(struct smu_context *smu, 1009 enum smu_clk_type clk_type, 1010 uint32_t *min, 1011 uint32_t *max) 1012{ 1013 if (amdgpu_ip_version(smu->adev, MP1_HWIP, 0) == IP_VERSION(14, 0, 1)) 1014 smu_v14_0_1_get_dpm_ultimate_freq(smu, clk_type, min, max); 1015 else if (clk_type != SMU_VCLK1 && clk_type != SMU_DCLK1) 1016 smu_v14_0_0_get_dpm_ultimate_freq(smu, clk_type, min, max); 1017 1018 return 0; 1019} 1020 1021static int smu_v14_0_0_get_current_clk_freq(struct smu_context *smu, 1022 enum smu_clk_type clk_type, 1023 uint32_t *value) 1024{ 1025 MetricsMember_t member_type; 1026 1027 switch (clk_type) { 1028 case SMU_SOCCLK: 1029 member_type = METRICS_AVERAGE_SOCCLK; 1030 break; 1031 case SMU_VCLK: 1032 member_type = METRICS_AVERAGE_VCLK; 1033 break; 1034 case SMU_VCLK1: 1035 member_type = METRICS_AVERAGE_VCLK1; 1036 break; 1037 case SMU_DCLK: 1038 member_type = METRICS_AVERAGE_DCLK; 1039 break; 1040 case SMU_DCLK1: 1041 member_type = METRICS_AVERAGE_DCLK1; 1042 break; 1043 case SMU_MCLK: 1044 member_type = METRICS_AVERAGE_UCLK; 1045 break; 1046 case SMU_FCLK: 1047 member_type = METRICS_AVERAGE_FCLK; 1048 break; 1049 case SMU_GFXCLK: 1050 case SMU_SCLK: 1051 member_type = METRICS_AVERAGE_GFXCLK; 1052 break; 1053 default: 1054 return -EINVAL; 1055 } 1056 1057 return smu_v14_0_0_get_smu_metrics_data(smu, member_type, value); 1058} 1059 1060static int smu_v14_0_1_get_dpm_level_count(struct smu_context *smu, 1061 enum smu_clk_type clk_type, 1062 uint32_t *count) 1063{ 1064 DpmClocks_t_v14_0_1 *clk_table = smu->smu_table.clocks_table; 1065 1066 switch (clk_type) { 1067 case SMU_SOCCLK: 1068 *count = clk_table->NumSocClkLevelsEnabled; 1069 break; 1070 case SMU_VCLK: 1071 case SMU_DCLK: 1072 *count = clk_table->Vcn0ClkLevelsEnabled; 1073 break; 1074 case SMU_VCLK1: 1075 case SMU_DCLK1: 1076 *count = clk_table->Vcn1ClkLevelsEnabled; 1077 break; 1078 case SMU_MCLK: 1079 *count = clk_table->NumMemPstatesEnabled; 1080 break; 1081 case SMU_FCLK: 1082 *count = clk_table->NumFclkLevelsEnabled; 1083 break; 1084 default: 1085 break; 1086 } 1087 1088 return 0; 1089} 1090 1091static int smu_v14_0_0_get_dpm_level_count(struct smu_context *smu, 1092 enum smu_clk_type clk_type, 1093 uint32_t *count) 1094{ 1095 DpmClocks_t *clk_table = smu->smu_table.clocks_table; 1096 1097 switch (clk_type) { 1098 case SMU_SOCCLK: 1099 *count = clk_table->NumSocClkLevelsEnabled; 1100 break; 1101 case SMU_VCLK: 1102 *count = clk_table->VcnClkLevelsEnabled; 1103 break; 1104 case SMU_DCLK: 1105 *count = clk_table->VcnClkLevelsEnabled; 1106 break; 1107 case SMU_MCLK: 1108 *count = clk_table->NumMemPstatesEnabled; 1109 break; 1110 case SMU_FCLK: 1111 *count = clk_table->NumFclkLevelsEnabled; 1112 break; 1113 default: 1114 break; 1115 } 1116 1117 return 0; 1118} 1119 1120static int smu_v14_0_common_get_dpm_level_count(struct smu_context *smu, 1121 enum smu_clk_type clk_type, 1122 uint32_t *count) 1123{ 1124 if (amdgpu_ip_version(smu->adev, MP1_HWIP, 0) == IP_VERSION(14, 0, 1)) 1125 smu_v14_0_1_get_dpm_level_count(smu, clk_type, count); 1126 else if (clk_type != SMU_VCLK1 && clk_type != SMU_DCLK1) 1127 smu_v14_0_0_get_dpm_level_count(smu, clk_type, count); 1128 1129 return 0; 1130} 1131 1132static int smu_v14_0_0_print_clk_levels(struct smu_context *smu, 1133 enum smu_clk_type clk_type, char *buf) 1134{ 1135 int i, idx, ret = 0, size = 0, start_offset = 0; 1136 uint32_t cur_value = 0, value = 0, count = 0; 1137 uint32_t min, max; 1138 1139 smu_cmn_get_sysfs_buf(&buf, &size); 1140 start_offset = size; 1141 1142 switch (clk_type) { 1143 case SMU_OD_SCLK: 1144 size += sysfs_emit_at(buf, size, "%s:\n", "OD_SCLK"); 1145 size += sysfs_emit_at(buf, size, "0: %10uMhz\n", 1146 (smu->gfx_actual_hard_min_freq > 0) ? smu->gfx_actual_hard_min_freq : smu->gfx_default_hard_min_freq); 1147 size += sysfs_emit_at(buf, size, "1: %10uMhz\n", 1148 (smu->gfx_actual_soft_max_freq > 0) ? smu->gfx_actual_soft_max_freq : smu->gfx_default_soft_max_freq); 1149 break; 1150 case SMU_OD_RANGE: 1151 size += sysfs_emit_at(buf, size, "%s:\n", "OD_RANGE"); 1152 size += sysfs_emit_at(buf, size, "SCLK: %7uMhz %10uMhz\n", 1153 smu->gfx_default_hard_min_freq, 1154 smu->gfx_default_soft_max_freq); 1155 break; 1156 case SMU_SOCCLK: 1157 case SMU_VCLK: 1158 case SMU_DCLK: 1159 case SMU_VCLK1: 1160 case SMU_DCLK1: 1161 case SMU_MCLK: 1162 case SMU_FCLK: 1163 ret = smu_v14_0_0_get_current_clk_freq(smu, clk_type, &cur_value); 1164 if (ret) 1165 break; 1166 1167 ret = smu_v14_0_common_get_dpm_level_count(smu, clk_type, &count); 1168 if (ret) 1169 break; 1170 1171 for (i = 0; i < count; i++) { 1172 idx = (clk_type == SMU_MCLK) ? (count - i - 1) : i; 1173 ret = smu_v14_0_common_get_dpm_freq_by_index(smu, clk_type, idx, &value); 1174 if (ret) 1175 break; 1176 1177 size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n", i, value, 1178 cur_value == value ? "*" : ""); 1179 } 1180 break; 1181 case SMU_GFXCLK: 1182 case SMU_SCLK: 1183 ret = smu_v14_0_0_get_current_clk_freq(smu, clk_type, &cur_value); 1184 if (ret) 1185 break; 1186 min = (smu->gfx_actual_hard_min_freq > 0) ? smu->gfx_actual_hard_min_freq : smu->gfx_default_hard_min_freq; 1187 max = (smu->gfx_actual_soft_max_freq > 0) ? smu->gfx_actual_soft_max_freq : smu->gfx_default_soft_max_freq; 1188 if (cur_value == max) 1189 i = 2; 1190 else if (cur_value == min) 1191 i = 0; 1192 else 1193 i = 1; 1194 size += sysfs_emit_at(buf, size, "0: %uMhz %s\n", min, 1195 i == 0 ? "*" : ""); 1196 size += sysfs_emit_at(buf, size, "1: %uMhz %s\n", 1197 i == 1 ? cur_value : 1100, /* UMD PSTATE GFXCLK 1100 */ 1198 i == 1 ? "*" : ""); 1199 size += sysfs_emit_at(buf, size, "2: %uMhz %s\n", max, 1200 i == 2 ? "*" : ""); 1201 break; 1202 default: 1203 break; 1204 } 1205 1206 return size - start_offset; 1207} 1208 1209static int smu_v14_0_0_set_soft_freq_limited_range(struct smu_context *smu, 1210 enum smu_clk_type clk_type, 1211 u32 min, 1212 u32 max, 1213 bool __always_unused automatic) 1214{ 1215 enum smu_message_type msg_set_min = SMU_MSG_MAX_COUNT; 1216 enum smu_message_type msg_set_max = SMU_MSG_MAX_COUNT; 1217 int ret = -EINVAL; 1218 1219 if (!smu_v14_0_0_clk_dpm_is_enabled(smu, clk_type)) 1220 return -EINVAL; 1221 1222 switch (clk_type) { 1223 case SMU_GFXCLK: 1224 case SMU_SCLK: 1225 msg_set_min = SMU_MSG_SetHardMinGfxClk; 1226 msg_set_max = SMU_MSG_SetSoftMaxGfxClk; 1227 break; 1228 case SMU_FCLK: 1229 msg_set_min = SMU_MSG_SetHardMinFclkByFreq; 1230 msg_set_max = SMU_MSG_SetSoftMaxFclkByFreq; 1231 break; 1232 case SMU_SOCCLK: 1233 msg_set_min = SMU_MSG_SetHardMinSocclkByFreq; 1234 msg_set_max = SMU_MSG_SetSoftMaxSocclkByFreq; 1235 break; 1236 case SMU_VCLK: 1237 case SMU_DCLK: 1238 msg_set_min = SMU_MSG_SetHardMinVcn0; 1239 msg_set_max = SMU_MSG_SetSoftMaxVcn0; 1240 break; 1241 case SMU_VCLK1: 1242 case SMU_DCLK1: 1243 msg_set_min = SMU_MSG_SetHardMinVcn1; 1244 msg_set_max = SMU_MSG_SetSoftMaxVcn1; 1245 break; 1246 case SMU_ISPICLK: 1247 msg_set_min = SMU_MSG_SetHardMinIspiclkByFreq; 1248 break; 1249 case SMU_ISPXCLK: 1250 msg_set_min = SMU_MSG_SetHardMinIspxclkByFreq; 1251 break; 1252 default: 1253 return -EINVAL; 1254 } 1255 1256 if (min && msg_set_min != SMU_MSG_MAX_COUNT) 1257 ret = smu_cmn_send_smc_msg_with_param(smu, msg_set_min, min, NULL); 1258 1259 if (max && msg_set_max != SMU_MSG_MAX_COUNT) 1260 ret = smu_cmn_send_smc_msg_with_param(smu, msg_set_max, max, NULL); 1261 1262 return ret; 1263} 1264 1265static int smu_v14_0_0_force_clk_levels(struct smu_context *smu, 1266 enum smu_clk_type clk_type, 1267 uint32_t mask) 1268{ 1269 uint32_t soft_min_level = 0, soft_max_level = 0; 1270 uint32_t min_freq = 0, max_freq = 0; 1271 int ret = 0; 1272 1273 soft_min_level = mask ? (ffs(mask) - 1) : 0; 1274 soft_max_level = mask ? (fls(mask) - 1) : 0; 1275 1276 switch (clk_type) { 1277 case SMU_SOCCLK: 1278 case SMU_FCLK: 1279 case SMU_VCLK: 1280 case SMU_DCLK: 1281 case SMU_VCLK1: 1282 case SMU_DCLK1: 1283 ret = smu_v14_0_common_get_dpm_freq_by_index(smu, clk_type, soft_min_level, &min_freq); 1284 if (ret) 1285 break; 1286 1287 ret = smu_v14_0_common_get_dpm_freq_by_index(smu, clk_type, soft_max_level, &max_freq); 1288 if (ret) 1289 break; 1290 1291 ret = smu_v14_0_0_set_soft_freq_limited_range(smu, clk_type, min_freq, max_freq, false); 1292 break; 1293 default: 1294 ret = -EINVAL; 1295 break; 1296 } 1297 1298 return ret; 1299} 1300 1301static int smu_v14_0_common_get_dpm_profile_freq(struct smu_context *smu, 1302 enum amd_dpm_forced_level level, 1303 enum smu_clk_type clk_type, 1304 uint32_t *min_clk, 1305 uint32_t *max_clk) 1306{ 1307 uint32_t clk_limit = 0; 1308 int ret = 0; 1309 1310 switch (clk_type) { 1311 case SMU_GFXCLK: 1312 case SMU_SCLK: 1313 if (amdgpu_ip_version(smu->adev, MP1_HWIP, 0) == IP_VERSION(14, 0, 4)) 1314 clk_limit = SMU_14_0_4_UMD_PSTATE_GFXCLK; 1315 else 1316 clk_limit = SMU_14_0_0_UMD_PSTATE_GFXCLK; 1317 if (level == AMD_DPM_FORCED_LEVEL_PROFILE_PEAK) 1318 smu_v14_0_common_get_dpm_ultimate_freq(smu, SMU_SCLK, NULL, &clk_limit); 1319 else if (level == AMD_DPM_FORCED_LEVEL_PROFILE_MIN_SCLK) 1320 smu_v14_0_common_get_dpm_ultimate_freq(smu, SMU_SCLK, &clk_limit, NULL); 1321 break; 1322 case SMU_SOCCLK: 1323 if (amdgpu_ip_version(smu->adev, MP1_HWIP, 0) == IP_VERSION(14, 0, 4)) 1324 clk_limit = SMU_14_0_4_UMD_PSTATE_SOCCLK; 1325 else 1326 clk_limit = SMU_14_0_0_UMD_PSTATE_SOCCLK; 1327 if (level == AMD_DPM_FORCED_LEVEL_PROFILE_PEAK) 1328 smu_v14_0_common_get_dpm_ultimate_freq(smu, SMU_SOCCLK, NULL, &clk_limit); 1329 break; 1330 case SMU_FCLK: 1331 if (amdgpu_ip_version(smu->adev, MP1_HWIP, 0) == IP_VERSION(14, 0, 4)) 1332 smu_v14_0_common_get_dpm_ultimate_freq(smu, SMU_FCLK, NULL, &clk_limit); 1333 else 1334 clk_limit = SMU_14_0_0_UMD_PSTATE_FCLK; 1335 if (level == AMD_DPM_FORCED_LEVEL_PROFILE_PEAK) 1336 smu_v14_0_common_get_dpm_ultimate_freq(smu, SMU_FCLK, NULL, &clk_limit); 1337 else if (level == AMD_DPM_FORCED_LEVEL_PROFILE_MIN_MCLK) 1338 smu_v14_0_common_get_dpm_ultimate_freq(smu, SMU_FCLK, &clk_limit, NULL); 1339 break; 1340 case SMU_VCLK: 1341 smu_v14_0_common_get_dpm_ultimate_freq(smu, SMU_VCLK, NULL, &clk_limit); 1342 break; 1343 case SMU_VCLK1: 1344 smu_v14_0_common_get_dpm_ultimate_freq(smu, SMU_VCLK1, NULL, &clk_limit); 1345 break; 1346 case SMU_DCLK: 1347 smu_v14_0_common_get_dpm_ultimate_freq(smu, SMU_DCLK, NULL, &clk_limit); 1348 break; 1349 case SMU_DCLK1: 1350 smu_v14_0_common_get_dpm_ultimate_freq(smu, SMU_DCLK1, NULL, &clk_limit); 1351 break; 1352 default: 1353 ret = -EINVAL; 1354 break; 1355 } 1356 *min_clk = *max_clk = clk_limit; 1357 return ret; 1358} 1359 1360static int smu_v14_0_common_set_performance_level(struct smu_context *smu, 1361 enum amd_dpm_forced_level level) 1362{ 1363 struct amdgpu_device *adev = smu->adev; 1364 uint32_t sclk_min = 0, sclk_max = 0; 1365 uint32_t fclk_min = 0, fclk_max = 0; 1366 uint32_t socclk_min = 0, socclk_max = 0; 1367 uint32_t vclk_min = 0, vclk_max = 0; 1368 uint32_t dclk_min = 0, dclk_max = 0; 1369 uint32_t vclk1_min = 0, vclk1_max = 0; 1370 uint32_t dclk1_min = 0, dclk1_max = 0; 1371 int ret = 0; 1372 1373 switch (level) { 1374 case AMD_DPM_FORCED_LEVEL_HIGH: 1375 smu_v14_0_common_get_dpm_ultimate_freq(smu, SMU_SCLK, NULL, &sclk_max); 1376 smu_v14_0_common_get_dpm_ultimate_freq(smu, SMU_FCLK, NULL, &fclk_max); 1377 smu_v14_0_common_get_dpm_ultimate_freq(smu, SMU_SOCCLK, NULL, &socclk_max); 1378 smu_v14_0_common_get_dpm_ultimate_freq(smu, SMU_VCLK, NULL, &vclk_max); 1379 smu_v14_0_common_get_dpm_ultimate_freq(smu, SMU_DCLK, NULL, &dclk_max); 1380 smu_v14_0_common_get_dpm_ultimate_freq(smu, SMU_VCLK1, NULL, &vclk1_max); 1381 smu_v14_0_common_get_dpm_ultimate_freq(smu, SMU_DCLK1, NULL, &dclk1_max); 1382 sclk_min = sclk_max; 1383 fclk_min = fclk_max; 1384 socclk_min = socclk_max; 1385 vclk_min = vclk_max; 1386 dclk_min = dclk_max; 1387 vclk1_min = vclk1_max; 1388 dclk1_min = dclk1_max; 1389 break; 1390 case AMD_DPM_FORCED_LEVEL_LOW: 1391 smu_v14_0_common_get_dpm_ultimate_freq(smu, SMU_SCLK, &sclk_min, NULL); 1392 smu_v14_0_common_get_dpm_ultimate_freq(smu, SMU_FCLK, &fclk_min, NULL); 1393 smu_v14_0_common_get_dpm_ultimate_freq(smu, SMU_SOCCLK, &socclk_min, NULL); 1394 smu_v14_0_common_get_dpm_ultimate_freq(smu, SMU_VCLK, &vclk_min, NULL); 1395 smu_v14_0_common_get_dpm_ultimate_freq(smu, SMU_DCLK, &dclk_min, NULL); 1396 smu_v14_0_common_get_dpm_ultimate_freq(smu, SMU_VCLK1, &vclk1_min, NULL); 1397 smu_v14_0_common_get_dpm_ultimate_freq(smu, SMU_DCLK1, &dclk1_min, NULL); 1398 sclk_max = sclk_min; 1399 fclk_max = fclk_min; 1400 socclk_max = socclk_min; 1401 vclk_max = vclk_min; 1402 dclk_max = dclk_min; 1403 vclk1_max = vclk1_min; 1404 dclk1_max = dclk1_min; 1405 break; 1406 case AMD_DPM_FORCED_LEVEL_AUTO: 1407 smu_v14_0_common_get_dpm_ultimate_freq(smu, SMU_SCLK, &sclk_min, &sclk_max); 1408 smu_v14_0_common_get_dpm_ultimate_freq(smu, SMU_FCLK, &fclk_min, &fclk_max); 1409 smu_v14_0_common_get_dpm_ultimate_freq(smu, SMU_SOCCLK, &socclk_min, &socclk_max); 1410 smu_v14_0_common_get_dpm_ultimate_freq(smu, SMU_VCLK, &vclk_min, &vclk_max); 1411 smu_v14_0_common_get_dpm_ultimate_freq(smu, SMU_DCLK, &dclk_min, &dclk_max); 1412 smu_v14_0_common_get_dpm_ultimate_freq(smu, SMU_VCLK1, &vclk1_min, &vclk1_max); 1413 smu_v14_0_common_get_dpm_ultimate_freq(smu, SMU_DCLK1, &dclk1_min, &dclk1_max); 1414 break; 1415 case AMD_DPM_FORCED_LEVEL_PROFILE_STANDARD: 1416 case AMD_DPM_FORCED_LEVEL_PROFILE_MIN_SCLK: 1417 case AMD_DPM_FORCED_LEVEL_PROFILE_MIN_MCLK: 1418 case AMD_DPM_FORCED_LEVEL_PROFILE_PEAK: 1419 smu_v14_0_common_get_dpm_profile_freq(smu, level, SMU_SCLK, &sclk_min, &sclk_max); 1420 smu_v14_0_common_get_dpm_profile_freq(smu, level, SMU_FCLK, &fclk_min, &fclk_max); 1421 smu_v14_0_common_get_dpm_profile_freq(smu, level, SMU_SOCCLK, &socclk_min, &socclk_max); 1422 smu_v14_0_common_get_dpm_profile_freq(smu, level, SMU_VCLK, &vclk_min, &vclk_max); 1423 smu_v14_0_common_get_dpm_profile_freq(smu, level, SMU_DCLK, &dclk_min, &dclk_max); 1424 smu_v14_0_common_get_dpm_profile_freq(smu, level, SMU_VCLK1, &vclk1_min, &vclk1_max); 1425 smu_v14_0_common_get_dpm_profile_freq(smu, level, SMU_DCLK1, &dclk1_min, &dclk1_max); 1426 break; 1427 case AMD_DPM_FORCED_LEVEL_MANUAL: 1428 case AMD_DPM_FORCED_LEVEL_PROFILE_EXIT: 1429 return 0; 1430 default: 1431 dev_err(adev->dev, "Invalid performance level %d\n", level); 1432 return -EINVAL; 1433 } 1434 1435 if (sclk_min && sclk_max) { 1436 ret = smu_v14_0_0_set_soft_freq_limited_range(smu, 1437 SMU_SCLK, 1438 sclk_min, 1439 sclk_max, 1440 false); 1441 if (ret) 1442 return ret; 1443 1444 smu->gfx_actual_hard_min_freq = sclk_min; 1445 smu->gfx_actual_soft_max_freq = sclk_max; 1446 } 1447 1448 if (fclk_min && fclk_max) { 1449 ret = smu_v14_0_0_set_soft_freq_limited_range(smu, 1450 SMU_FCLK, 1451 fclk_min, 1452 fclk_max, 1453 false); 1454 if (ret) 1455 return ret; 1456 } 1457 1458 if (socclk_min && socclk_max) { 1459 ret = smu_v14_0_0_set_soft_freq_limited_range(smu, 1460 SMU_SOCCLK, 1461 socclk_min, 1462 socclk_max, 1463 false); 1464 if (ret) 1465 return ret; 1466 } 1467 1468 if (vclk_min && vclk_max) { 1469 ret = smu_v14_0_0_set_soft_freq_limited_range(smu, 1470 SMU_VCLK, 1471 vclk_min, 1472 vclk_max, 1473 false); 1474 if (ret) 1475 return ret; 1476 } 1477 1478 if (vclk1_min && vclk1_max) { 1479 ret = smu_v14_0_0_set_soft_freq_limited_range(smu, 1480 SMU_VCLK1, 1481 vclk1_min, 1482 vclk1_max, 1483 false); 1484 if (ret) 1485 return ret; 1486 } 1487 1488 if (dclk_min && dclk_max) { 1489 ret = smu_v14_0_0_set_soft_freq_limited_range(smu, 1490 SMU_DCLK, 1491 dclk_min, 1492 dclk_max, 1493 false); 1494 if (ret) 1495 return ret; 1496 } 1497 1498 if (dclk1_min && dclk1_max) { 1499 ret = smu_v14_0_0_set_soft_freq_limited_range(smu, 1500 SMU_DCLK1, 1501 dclk1_min, 1502 dclk1_max, 1503 false); 1504 if (ret) 1505 return ret; 1506 } 1507 1508 return ret; 1509} 1510 1511static int smu_v14_0_1_set_fine_grain_gfx_freq_parameters(struct smu_context *smu) 1512{ 1513 DpmClocks_t_v14_0_1 *clk_table = smu->smu_table.clocks_table; 1514 1515 smu->gfx_default_hard_min_freq = clk_table->MinGfxClk; 1516 smu->gfx_default_soft_max_freq = clk_table->MaxGfxClk; 1517 if (smu->gfx_actual_hard_min_freq == 0) 1518 smu->gfx_actual_hard_min_freq = smu->gfx_default_hard_min_freq; 1519 if (smu->gfx_actual_soft_max_freq == 0) 1520 smu->gfx_actual_soft_max_freq = smu->gfx_default_soft_max_freq; 1521 return 0; 1522} 1523 1524static int smu_v14_0_0_set_fine_grain_gfx_freq_parameters(struct smu_context *smu) 1525{ 1526 DpmClocks_t *clk_table = smu->smu_table.clocks_table; 1527 1528 smu->gfx_default_hard_min_freq = clk_table->MinGfxClk; 1529 smu->gfx_default_soft_max_freq = clk_table->MaxGfxClk; 1530 if (smu->gfx_actual_hard_min_freq == 0) 1531 smu->gfx_actual_hard_min_freq = smu->gfx_default_hard_min_freq; 1532 if (smu->gfx_actual_soft_max_freq == 0) 1533 smu->gfx_actual_soft_max_freq = smu->gfx_default_soft_max_freq; 1534 1535 return 0; 1536} 1537 1538static int smu_v14_0_common_set_fine_grain_gfx_freq_parameters(struct smu_context *smu) 1539{ 1540 if (amdgpu_ip_version(smu->adev, MP1_HWIP, 0) == IP_VERSION(14, 0, 1)) 1541 smu_v14_0_1_set_fine_grain_gfx_freq_parameters(smu); 1542 else 1543 smu_v14_0_0_set_fine_grain_gfx_freq_parameters(smu); 1544 1545 return 0; 1546} 1547 1548static int smu_v14_0_0_set_vpe_enable(struct smu_context *smu, 1549 bool enable) 1550{ 1551 return smu_cmn_send_smc_msg_with_param(smu, enable ? 1552 SMU_MSG_PowerUpVpe : SMU_MSG_PowerDownVpe, 1553 0, NULL); 1554} 1555 1556static int smu_v14_0_0_set_isp_enable(struct smu_context *smu, 1557 bool enable) 1558{ 1559 return smu_cmn_send_smc_msg_with_param(smu, enable ? 1560 SMU_MSG_PowerUpIspByTile : SMU_MSG_PowerDownIspByTile, 1561 ISP_ALL_TILES_MASK, NULL); 1562} 1563 1564static int smu_v14_0_0_set_umsch_mm_enable(struct smu_context *smu, 1565 bool enable) 1566{ 1567 return smu_cmn_send_smc_msg_with_param(smu, enable ? 1568 SMU_MSG_PowerUpUmsch : SMU_MSG_PowerDownUmsch, 1569 0, NULL); 1570} 1571 1572static int smu_14_0_1_get_dpm_table(struct smu_context *smu, struct dpm_clocks *clock_table) 1573{ 1574 DpmClocks_t_v14_0_1 *clk_table = smu->smu_table.clocks_table; 1575 uint8_t idx; 1576 1577 /* Only the Clock information of SOC and VPE is copied to provide VPE DPM settings for use. */ 1578 for (idx = 0; idx < NUM_SOCCLK_DPM_LEVELS; idx++) { 1579 clock_table->SocClocks[idx].Freq = (idx < clk_table->NumSocClkLevelsEnabled) ? clk_table->SocClocks[idx]:0; 1580 clock_table->SocClocks[idx].Vol = 0; 1581 } 1582 1583 for (idx = 0; idx < NUM_VPE_DPM_LEVELS; idx++) { 1584 clock_table->VPEClocks[idx].Freq = (idx < clk_table->VpeClkLevelsEnabled) ? clk_table->VPEClocks[idx]:0; 1585 clock_table->VPEClocks[idx].Vol = 0; 1586 } 1587 1588 return 0; 1589} 1590 1591static int smu_14_0_0_get_dpm_table(struct smu_context *smu, struct dpm_clocks *clock_table) 1592{ 1593 DpmClocks_t *clk_table = smu->smu_table.clocks_table; 1594 uint8_t idx; 1595 1596 /* Only the Clock information of SOC and VPE is copied to provide VPE DPM settings for use. */ 1597 for (idx = 0; idx < NUM_SOCCLK_DPM_LEVELS; idx++) { 1598 clock_table->SocClocks[idx].Freq = (idx < clk_table->NumSocClkLevelsEnabled) ? clk_table->SocClocks[idx]:0; 1599 clock_table->SocClocks[idx].Vol = 0; 1600 } 1601 1602 for (idx = 0; idx < NUM_VPE_DPM_LEVELS; idx++) { 1603 clock_table->VPEClocks[idx].Freq = (idx < clk_table->VpeClkLevelsEnabled) ? clk_table->VPEClocks[idx]:0; 1604 clock_table->VPEClocks[idx].Vol = 0; 1605 } 1606 1607 return 0; 1608} 1609 1610static int smu_v14_0_common_get_dpm_table(struct smu_context *smu, struct dpm_clocks *clock_table) 1611{ 1612 if (amdgpu_ip_version(smu->adev, MP1_HWIP, 0) == IP_VERSION(14, 0, 1)) 1613 smu_14_0_1_get_dpm_table(smu, clock_table); 1614 else 1615 smu_14_0_0_get_dpm_table(smu, clock_table); 1616 1617 return 0; 1618} 1619 1620static int smu_v14_0_1_init_mall_power_gating(struct smu_context *smu, enum smu_mall_pg_config pg_config) 1621{ 1622 struct amdgpu_device *adev = smu->adev; 1623 int ret = 0; 1624 1625 if (pg_config == SMU_MALL_PG_CONFIG_PMFW_CONTROL) { 1626 ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_MALLPowerController, 1627 SMU_MALL_PMFW_CONTROL, NULL); 1628 if (ret) { 1629 dev_err(adev->dev, "Init MALL PMFW CONTROL Failure\n"); 1630 return ret; 1631 } 1632 } else { 1633 ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_MALLPowerController, 1634 SMU_MALL_DRIVER_CONTROL, NULL); 1635 if (ret) { 1636 dev_err(adev->dev, "Init MALL Driver CONTROL Failure\n"); 1637 return ret; 1638 } 1639 1640 if (pg_config == SMU_MALL_PG_CONFIG_DRIVER_CONTROL_ALWAYS_ON) { 1641 ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_MALLPowerState, 1642 SMU_MALL_EXIT_PG, NULL); 1643 if (ret) { 1644 dev_err(adev->dev, "EXIT MALL PG Failure\n"); 1645 return ret; 1646 } 1647 } else if (pg_config == SMU_MALL_PG_CONFIG_DRIVER_CONTROL_ALWAYS_OFF) { 1648 ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_MALLPowerState, 1649 SMU_MALL_ENTER_PG, NULL); 1650 if (ret) { 1651 dev_err(adev->dev, "Enter MALL PG Failure\n"); 1652 return ret; 1653 } 1654 } 1655 } 1656 1657 return ret; 1658} 1659 1660static int smu_v14_0_common_set_mall_enable(struct smu_context *smu) 1661{ 1662 enum smu_mall_pg_config pg_config = SMU_MALL_PG_CONFIG_DEFAULT; 1663 int ret = 0; 1664 1665 if (amdgpu_ip_version(smu->adev, MP1_HWIP, 0) == IP_VERSION(14, 0, 1)) 1666 ret = smu_v14_0_1_init_mall_power_gating(smu, pg_config); 1667 1668 return ret; 1669} 1670 1671static int smu_v14_0_0_restore_user_od_settings(struct smu_context *smu) 1672{ 1673 int ret; 1674 1675 ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetHardMinGfxClk, 1676 smu->gfx_actual_hard_min_freq, 1677 NULL); 1678 if (ret) { 1679 dev_err(smu->adev->dev, "Failed to restore hard min sclk!\n"); 1680 return ret; 1681 } 1682 1683 ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetSoftMaxGfxClk, 1684 smu->gfx_actual_soft_max_freq, 1685 NULL); 1686 if (ret) { 1687 dev_err(smu->adev->dev, "Failed to restore soft max sclk!\n"); 1688 return ret; 1689 } 1690 1691 return 0; 1692} 1693 1694static const struct pptable_funcs smu_v14_0_0_ppt_funcs = { 1695 .check_fw_status = smu_v14_0_check_fw_status, 1696 .check_fw_version = smu_v14_0_check_fw_version, 1697 .init_smc_tables = smu_v14_0_0_init_smc_tables, 1698 .fini_smc_tables = smu_v14_0_0_fini_smc_tables, 1699 .get_vbios_bootup_values = smu_v14_0_get_vbios_bootup_values, 1700 .system_features_control = smu_v14_0_0_system_features_control, 1701 .send_smc_msg_with_param = smu_cmn_send_smc_msg_with_param, 1702 .send_smc_msg = smu_cmn_send_smc_msg, 1703 .dpm_set_vcn_enable = smu_v14_0_set_vcn_enable, 1704 .dpm_set_jpeg_enable = smu_v14_0_set_jpeg_enable, 1705 .set_default_dpm_table = smu_v14_0_set_default_dpm_tables, 1706 .read_sensor = smu_v14_0_0_read_sensor, 1707 .is_dpm_running = smu_v14_0_0_is_dpm_running, 1708 .set_watermarks_table = smu_v14_0_0_set_watermarks_table, 1709 .get_gpu_metrics = smu_v14_0_0_get_gpu_metrics, 1710 .get_enabled_mask = smu_cmn_get_enabled_mask, 1711 .get_pp_feature_mask = smu_cmn_get_pp_feature_mask, 1712 .set_driver_table_location = smu_v14_0_set_driver_table_location, 1713 .gfx_off_control = smu_v14_0_gfx_off_control, 1714 .mode2_reset = smu_v14_0_0_mode2_reset, 1715 .get_dpm_ultimate_freq = smu_v14_0_common_get_dpm_ultimate_freq, 1716 .set_soft_freq_limited_range = smu_v14_0_0_set_soft_freq_limited_range, 1717 .restore_user_od_settings = smu_v14_0_0_restore_user_od_settings, 1718 .od_edit_dpm_table = smu_v14_0_od_edit_dpm_table, 1719 .print_clk_levels = smu_v14_0_0_print_clk_levels, 1720 .force_clk_levels = smu_v14_0_0_force_clk_levels, 1721 .set_performance_level = smu_v14_0_common_set_performance_level, 1722 .set_fine_grain_gfx_freq_parameters = smu_v14_0_common_set_fine_grain_gfx_freq_parameters, 1723 .set_gfx_power_up_by_imu = smu_v14_0_set_gfx_power_up_by_imu, 1724 .dpm_set_vpe_enable = smu_v14_0_0_set_vpe_enable, 1725 .dpm_set_isp_enable = smu_v14_0_0_set_isp_enable, 1726 .dpm_set_umsch_mm_enable = smu_v14_0_0_set_umsch_mm_enable, 1727 .get_dpm_clock_table = smu_v14_0_common_get_dpm_table, 1728 .set_mall_enable = smu_v14_0_common_set_mall_enable, 1729}; 1730 1731static void smu_v14_0_0_set_smu_mailbox_registers(struct smu_context *smu) 1732{ 1733 struct amdgpu_device *adev = smu->adev; 1734 1735 smu->param_reg = SOC15_REG_OFFSET(MP1, 0, mmMP1_SMN_C2PMSG_82); 1736 smu->msg_reg = SOC15_REG_OFFSET(MP1, 0, mmMP1_SMN_C2PMSG_66); 1737 smu->resp_reg = SOC15_REG_OFFSET(MP1, 0, mmMP1_SMN_C2PMSG_90); 1738} 1739 1740void smu_v14_0_0_set_ppt_funcs(struct smu_context *smu) 1741{ 1742 1743 smu->ppt_funcs = &smu_v14_0_0_ppt_funcs; 1744 smu->message_map = smu_v14_0_0_message_map; 1745 smu->feature_map = smu_v14_0_0_feature_mask_map; 1746 smu->table_map = smu_v14_0_0_table_map; 1747 smu->is_apu = true; 1748 1749 smu_v14_0_0_set_smu_mailbox_registers(smu); 1750}
~/
Read-only file preview.