smu_v13_0.c revision 1.19
1/* 2 * Copyright 2020 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#include <linux/firmware.h> 24#include <linux/module.h> 25#include <linux/pci.h> 26#include <linux/reboot.h> 27 28#define SMU_13_0_PARTIAL_PPTABLE 29#define SWSMU_CODE_LAYER_L3 30 31#include "amdgpu.h" 32#include "amdgpu_smu.h" 33#include "atomfirmware.h" 34#include "amdgpu_atomfirmware.h" 35#include "amdgpu_atombios.h" 36#include "smu_v13_0.h" 37#include "soc15_common.h" 38#include "atom.h" 39#include "amdgpu_ras.h" 40#include "smu_cmn.h" 41 42#include "asic_reg/thm/thm_13_0_2_offset.h" 43#include "asic_reg/thm/thm_13_0_2_sh_mask.h" 44#include "asic_reg/mp/mp_13_0_2_offset.h" 45#include "asic_reg/mp/mp_13_0_2_sh_mask.h" 46#include "asic_reg/smuio/smuio_13_0_2_offset.h" 47#include "asic_reg/smuio/smuio_13_0_2_sh_mask.h" 48 49/* 50 * DO NOT use these for err/warn/info/debug messages. 51 * Use dev_err, dev_warn, dev_info and dev_dbg instead. 52 * They are more MGPU friendly. 53 */ 54#undef pr_err 55#undef pr_warn 56#undef pr_info 57#undef pr_debug 58 59MODULE_FIRMWARE("amdgpu/aldebaran_smc.bin"); 60MODULE_FIRMWARE("amdgpu/smu_13_0_0.bin"); 61MODULE_FIRMWARE("amdgpu/smu_13_0_7.bin"); 62MODULE_FIRMWARE("amdgpu/smu_13_0_10.bin"); 63 64#define mmMP1_SMN_C2PMSG_66 0x0282 65#define mmMP1_SMN_C2PMSG_66_BASE_IDX 0 66 67#define mmMP1_SMN_C2PMSG_82 0x0292 68#define mmMP1_SMN_C2PMSG_82_BASE_IDX 0 69 70#define mmMP1_SMN_C2PMSG_90 0x029a 71#define mmMP1_SMN_C2PMSG_90_BASE_IDX 0 72 73#define SMU13_VOLTAGE_SCALE 4 74 75#define LINK_WIDTH_MAX 6 76#define LINK_SPEED_MAX 3 77 78#define smnPCIE_LC_LINK_WIDTH_CNTL 0x11140288 79#define PCIE_LC_LINK_WIDTH_CNTL__LC_LINK_WIDTH_RD_MASK 0x00000070L 80#define PCIE_LC_LINK_WIDTH_CNTL__LC_LINK_WIDTH_RD__SHIFT 0x4 81#define smnPCIE_LC_SPEED_CNTL 0x11140290 82#define PCIE_LC_SPEED_CNTL__LC_CURRENT_DATA_RATE_MASK 0xC000 83#define PCIE_LC_SPEED_CNTL__LC_CURRENT_DATA_RATE__SHIFT 0xE 84 85static const int link_width[] = {0, 1, 2, 4, 8, 12, 16}; 86 87const int pmfw_decoded_link_speed[5] = {1, 2, 3, 4, 5}; 88const int pmfw_decoded_link_width[7] = {0, 1, 2, 4, 8, 12, 16}; 89 90int smu_v13_0_init_microcode(struct smu_context *smu) 91{ 92 struct amdgpu_device *adev = smu->adev; 93 char fw_name[30]; 94 char ucode_prefix[30]; 95 int err = 0; 96 const struct smc_firmware_header_v1_0 *hdr; 97 const struct common_firmware_header *header; 98 struct amdgpu_firmware_info *ucode = NULL; 99 100 /* doesn't need to load smu firmware in IOV mode */ 101 if (amdgpu_sriov_vf(adev)) 102 return 0; 103 104 amdgpu_ucode_ip_version_decode(adev, MP1_HWIP, ucode_prefix, sizeof(ucode_prefix)); 105 106 snprintf(fw_name, sizeof(fw_name), "amdgpu/%s.bin", ucode_prefix); 107 108 err = amdgpu_ucode_request(adev, &adev->pm.fw, fw_name); 109 if (err) 110 goto out; 111 112 hdr = (const struct smc_firmware_header_v1_0 *) adev->pm.fw->data; 113 amdgpu_ucode_print_smc_hdr(&hdr->header); 114 adev->pm.fw_version = le32_to_cpu(hdr->header.ucode_version); 115 116 if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) { 117 ucode = &adev->firmware.ucode[AMDGPU_UCODE_ID_SMC]; 118 ucode->ucode_id = AMDGPU_UCODE_ID_SMC; 119 ucode->fw = adev->pm.fw; 120 header = (const struct common_firmware_header *)ucode->fw->data; 121 adev->firmware.fw_size += 122 ALIGN(le32_to_cpu(header->ucode_size_bytes), PAGE_SIZE); 123 } 124 125out: 126 if (err) 127 amdgpu_ucode_release(&adev->pm.fw); 128 return err; 129} 130 131void smu_v13_0_fini_microcode(struct smu_context *smu) 132{ 133 struct amdgpu_device *adev = smu->adev; 134 135 amdgpu_ucode_release(&adev->pm.fw); 136 adev->pm.fw_version = 0; 137} 138 139int smu_v13_0_load_microcode(struct smu_context *smu) 140{ 141#if 0 142 struct amdgpu_device *adev = smu->adev; 143 const uint32_t *src; 144 const struct smc_firmware_header_v1_0 *hdr; 145 uint32_t addr_start = MP1_SRAM; 146 uint32_t i; 147 uint32_t smc_fw_size; 148 uint32_t mp1_fw_flags; 149 150 hdr = (const struct smc_firmware_header_v1_0 *) adev->pm.fw->data; 151 src = (const uint32_t *)(adev->pm.fw->data + 152 le32_to_cpu(hdr->header.ucode_array_offset_bytes)); 153 smc_fw_size = hdr->header.ucode_size_bytes; 154 155 for (i = 1; i < smc_fw_size/4 - 1; i++) { 156 WREG32_PCIE(addr_start, src[i]); 157 addr_start += 4; 158 } 159 160 WREG32_PCIE(MP1_Public | (smnMP1_PUB_CTRL & 0xffffffff), 161 1 & MP1_SMN_PUB_CTRL__RESET_MASK); 162 WREG32_PCIE(MP1_Public | (smnMP1_PUB_CTRL & 0xffffffff), 163 1 & ~MP1_SMN_PUB_CTRL__RESET_MASK); 164 165 for (i = 0; i < adev->usec_timeout; i++) { 166 mp1_fw_flags = RREG32_PCIE(MP1_Public | 167 (smnMP1_FIRMWARE_FLAGS & 0xffffffff)); 168 if ((mp1_fw_flags & MP1_FIRMWARE_FLAGS__INTERRUPTS_ENABLED_MASK) >> 169 MP1_FIRMWARE_FLAGS__INTERRUPTS_ENABLED__SHIFT) 170 break; 171 udelay(1); 172 } 173 174 if (i == adev->usec_timeout) 175 return -ETIME; 176#endif 177 178 return 0; 179} 180 181int smu_v13_0_init_pptable_microcode(struct smu_context *smu) 182{ 183 struct amdgpu_device *adev = smu->adev; 184 struct amdgpu_firmware_info *ucode = NULL; 185 uint32_t size = 0, pptable_id = 0; 186 int ret = 0; 187 void *table; 188 189 /* doesn't need to load smu firmware in IOV mode */ 190 if (amdgpu_sriov_vf(adev)) 191 return 0; 192 193 if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP) 194 return 0; 195 196 if (!adev->scpm_enabled) 197 return 0; 198 199 if ((adev->ip_versions[MP1_HWIP][0] == IP_VERSION(13, 0, 7)) || 200 (adev->ip_versions[MP1_HWIP][0] == IP_VERSION(13, 0, 0)) || 201 (adev->ip_versions[MP1_HWIP][0] == IP_VERSION(13, 0, 10))) 202 return 0; 203 204 /* override pptable_id from driver parameter */ 205 if (amdgpu_smu_pptable_id >= 0) { 206 pptable_id = amdgpu_smu_pptable_id; 207 dev_info(adev->dev, "override pptable id %d\n", pptable_id); 208 } else { 209 pptable_id = smu->smu_table.boot_values.pp_table_id; 210 } 211 212 /* "pptable_id == 0" means vbios carries the pptable. */ 213 if (!pptable_id) 214 return 0; 215 216 ret = smu_v13_0_get_pptable_from_firmware(smu, &table, &size, pptable_id); 217 if (ret) 218 return ret; 219 220 smu->pptable_firmware.data = table; 221 smu->pptable_firmware.size = size; 222 223 ucode = &adev->firmware.ucode[AMDGPU_UCODE_ID_PPTABLE]; 224 ucode->ucode_id = AMDGPU_UCODE_ID_PPTABLE; 225 ucode->fw = &smu->pptable_firmware; 226 adev->firmware.fw_size += 227 ALIGN(smu->pptable_firmware.size, PAGE_SIZE); 228 229 return 0; 230} 231 232int smu_v13_0_check_fw_status(struct smu_context *smu) 233{ 234 struct amdgpu_device *adev = smu->adev; 235 uint32_t mp1_fw_flags; 236 237 switch (adev->ip_versions[MP1_HWIP][0]) { 238 case IP_VERSION(13, 0, 4): 239 case IP_VERSION(13, 0, 11): 240 mp1_fw_flags = RREG32_PCIE(MP1_Public | 241 (smnMP1_V13_0_4_FIRMWARE_FLAGS & 0xffffffff)); 242 break; 243 default: 244 mp1_fw_flags = RREG32_PCIE(MP1_Public | 245 (smnMP1_FIRMWARE_FLAGS & 0xffffffff)); 246 break; 247 } 248 249 if ((mp1_fw_flags & MP1_FIRMWARE_FLAGS__INTERRUPTS_ENABLED_MASK) >> 250 MP1_FIRMWARE_FLAGS__INTERRUPTS_ENABLED__SHIFT) 251 return 0; 252 253 return -EIO; 254} 255 256int smu_v13_0_check_fw_version(struct smu_context *smu) 257{ 258 struct amdgpu_device *adev = smu->adev; 259 uint32_t if_version = 0xff, smu_version = 0xff; 260 uint8_t smu_program, smu_major, smu_minor, smu_debug; 261 int ret = 0; 262 263 ret = smu_cmn_get_smc_version(smu, &if_version, &smu_version); 264 if (ret) 265 return ret; 266 267 smu_program = (smu_version >> 24) & 0xff; 268 smu_major = (smu_version >> 16) & 0xff; 269 smu_minor = (smu_version >> 8) & 0xff; 270 smu_debug = (smu_version >> 0) & 0xff; 271 if (smu->is_apu || 272 adev->ip_versions[MP1_HWIP][0] == IP_VERSION(13, 0, 6)) 273 adev->pm.fw_version = smu_version; 274 275 /* only for dGPU w/ SMU13*/ 276 if (adev->pm.fw) 277 dev_dbg(smu->adev->dev, "smu fw reported program %d, version = 0x%08x (%d.%d.%d)\n", 278 smu_program, smu_version, smu_major, smu_minor, smu_debug); 279 280 /* 281 * 1. if_version mismatch is not critical as our fw is designed 282 * to be backward compatible. 283 * 2. New fw usually brings some optimizations. But that's visible 284 * only on the paired driver. 285 * Considering above, we just leave user a verbal message instead 286 * of halt driver loading. 287 */ 288 if (if_version != smu->smc_driver_if_version) { 289 dev_info(adev->dev, "smu driver if version = 0x%08x, smu fw if version = 0x%08x, " 290 "smu fw program = %d, smu fw version = 0x%08x (%d.%d.%d)\n", 291 smu->smc_driver_if_version, if_version, 292 smu_program, smu_version, smu_major, smu_minor, smu_debug); 293 dev_info(adev->dev, "SMU driver if version not matched\n"); 294 } 295 296 return ret; 297} 298 299static int smu_v13_0_set_pptable_v2_0(struct smu_context *smu, void **table, uint32_t *size) 300{ 301 struct amdgpu_device *adev = smu->adev; 302 uint32_t ppt_offset_bytes; 303 const struct smc_firmware_header_v2_0 *v2; 304 305 v2 = (const struct smc_firmware_header_v2_0 *) adev->pm.fw->data; 306 307 ppt_offset_bytes = le32_to_cpu(v2->ppt_offset_bytes); 308 *size = le32_to_cpu(v2->ppt_size_bytes); 309 *table = (uint8_t *)v2 + ppt_offset_bytes; 310 311 return 0; 312} 313 314static int smu_v13_0_set_pptable_v2_1(struct smu_context *smu, void **table, 315 uint32_t *size, uint32_t pptable_id) 316{ 317 struct amdgpu_device *adev = smu->adev; 318 const struct smc_firmware_header_v2_1 *v2_1; 319 struct smc_soft_pptable_entry *entries; 320 uint32_t pptable_count = 0; 321 int i = 0; 322 323 v2_1 = (const struct smc_firmware_header_v2_1 *) adev->pm.fw->data; 324 entries = (struct smc_soft_pptable_entry *) 325 ((uint8_t *)v2_1 + le32_to_cpu(v2_1->pptable_entry_offset)); 326 pptable_count = le32_to_cpu(v2_1->pptable_count); 327 for (i = 0; i < pptable_count; i++) { 328 if (le32_to_cpu(entries[i].id) == pptable_id) { 329 *table = ((uint8_t *)v2_1 + le32_to_cpu(entries[i].ppt_offset_bytes)); 330 *size = le32_to_cpu(entries[i].ppt_size_bytes); 331 break; 332 } 333 } 334 335 if (i == pptable_count) 336 return -EINVAL; 337 338 return 0; 339} 340 341static int smu_v13_0_get_pptable_from_vbios(struct smu_context *smu, void **table, uint32_t *size) 342{ 343 struct amdgpu_device *adev = smu->adev; 344 uint16_t atom_table_size; 345 uint8_t frev, crev; 346 int ret, index; 347 348 dev_info(adev->dev, "use vbios provided pptable\n"); 349 index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1, 350 powerplayinfo); 351 352 ret = amdgpu_atombios_get_data_table(adev, index, &atom_table_size, &frev, &crev, 353 (uint8_t **)table); 354 if (ret) 355 return ret; 356 357 if (size) 358 *size = atom_table_size; 359 360 return 0; 361} 362 363int smu_v13_0_get_pptable_from_firmware(struct smu_context *smu, 364 void **table, 365 uint32_t *size, 366 uint32_t pptable_id) 367{ 368 const struct smc_firmware_header_v1_0 *hdr; 369 struct amdgpu_device *adev = smu->adev; 370 uint16_t version_major, version_minor; 371 int ret; 372 373 hdr = (const struct smc_firmware_header_v1_0 *) adev->pm.fw->data; 374 if (!hdr) 375 return -EINVAL; 376 377 dev_info(adev->dev, "use driver provided pptable %d\n", pptable_id); 378 379 version_major = le16_to_cpu(hdr->header.header_version_major); 380 version_minor = le16_to_cpu(hdr->header.header_version_minor); 381 if (version_major != 2) { 382 dev_err(adev->dev, "Unsupported smu firmware version %d.%d\n", 383 version_major, version_minor); 384 return -EINVAL; 385 } 386 387 switch (version_minor) { 388 case 0: 389 ret = smu_v13_0_set_pptable_v2_0(smu, table, size); 390 break; 391 case 1: 392 ret = smu_v13_0_set_pptable_v2_1(smu, table, size, pptable_id); 393 break; 394 default: 395 ret = -EINVAL; 396 break; 397 } 398 399 return ret; 400} 401 402int smu_v13_0_setup_pptable(struct smu_context *smu) 403{ 404 struct amdgpu_device *adev = smu->adev; 405 uint32_t size = 0, pptable_id = 0; 406 void *table; 407 int ret = 0; 408 409 /* override pptable_id from driver parameter */ 410 if (amdgpu_smu_pptable_id >= 0) { 411 pptable_id = amdgpu_smu_pptable_id; 412 dev_info(adev->dev, "override pptable id %d\n", pptable_id); 413 } else { 414 pptable_id = smu->smu_table.boot_values.pp_table_id; 415 } 416 417 /* force using vbios pptable in sriov mode */ 418 if ((amdgpu_sriov_vf(adev) || !pptable_id) && (amdgpu_emu_mode != 1)) 419 ret = smu_v13_0_get_pptable_from_vbios(smu, &table, &size); 420 else 421 ret = smu_v13_0_get_pptable_from_firmware(smu, &table, &size, pptable_id); 422 423 if (ret) 424 return ret; 425 426 if (!smu->smu_table.power_play_table) 427 smu->smu_table.power_play_table = table; 428 if (!smu->smu_table.power_play_table_size) 429 smu->smu_table.power_play_table_size = size; 430 431 return 0; 432} 433 434int smu_v13_0_init_smc_tables(struct smu_context *smu) 435{ 436 struct smu_table_context *smu_table = &smu->smu_table; 437 struct smu_table *tables = smu_table->tables; 438 int ret = 0; 439 440 smu_table->driver_pptable = 441 kzalloc(tables[SMU_TABLE_PPTABLE].size, GFP_KERNEL); 442 if (!smu_table->driver_pptable) { 443 ret = -ENOMEM; 444 goto err0_out; 445 } 446 447 smu_table->max_sustainable_clocks = 448 kzalloc(sizeof(struct smu_13_0_max_sustainable_clocks), GFP_KERNEL); 449 if (!smu_table->max_sustainable_clocks) { 450 ret = -ENOMEM; 451 goto err1_out; 452 } 453 454 /* Aldebaran does not support OVERDRIVE */ 455 if (tables[SMU_TABLE_OVERDRIVE].size) { 456 smu_table->overdrive_table = 457 kzalloc(tables[SMU_TABLE_OVERDRIVE].size, GFP_KERNEL); 458 if (!smu_table->overdrive_table) { 459 ret = -ENOMEM; 460 goto err2_out; 461 } 462 463 smu_table->boot_overdrive_table = 464 kzalloc(tables[SMU_TABLE_OVERDRIVE].size, GFP_KERNEL); 465 if (!smu_table->boot_overdrive_table) { 466 ret = -ENOMEM; 467 goto err3_out; 468 } 469 470 smu_table->user_overdrive_table = 471 kzalloc(tables[SMU_TABLE_OVERDRIVE].size, GFP_KERNEL); 472 if (!smu_table->user_overdrive_table) { 473 ret = -ENOMEM; 474 goto err4_out; 475 } 476 } 477 478 smu_table->combo_pptable = 479 kzalloc(tables[SMU_TABLE_COMBO_PPTABLE].size, GFP_KERNEL); 480 if (!smu_table->combo_pptable) { 481 ret = -ENOMEM; 482 goto err5_out; 483 } 484 485 return 0; 486 487err5_out: 488 kfree(smu_table->user_overdrive_table); 489err4_out: 490 kfree(smu_table->boot_overdrive_table); 491err3_out: 492 kfree(smu_table->overdrive_table); 493err2_out: 494 kfree(smu_table->max_sustainable_clocks); 495err1_out: 496 kfree(smu_table->driver_pptable); 497err0_out: 498 return ret; 499} 500 501int smu_v13_0_fini_smc_tables(struct smu_context *smu) 502{ 503 struct smu_table_context *smu_table = &smu->smu_table; 504 struct smu_dpm_context *smu_dpm = &smu->smu_dpm; 505 506 kfree(smu_table->gpu_metrics_table); 507 kfree(smu_table->combo_pptable); 508 kfree(smu_table->user_overdrive_table); 509 kfree(smu_table->boot_overdrive_table); 510 kfree(smu_table->overdrive_table); 511 kfree(smu_table->max_sustainable_clocks); 512 kfree(smu_table->driver_pptable); 513 smu_table->gpu_metrics_table = NULL; 514 smu_table->combo_pptable = NULL; 515 smu_table->user_overdrive_table = NULL; 516 smu_table->boot_overdrive_table = NULL; 517 smu_table->overdrive_table = NULL; 518 smu_table->max_sustainable_clocks = NULL; 519 smu_table->driver_pptable = NULL; 520 kfree(smu_table->hardcode_pptable); 521 smu_table->hardcode_pptable = NULL; 522 523 kfree(smu_table->ecc_table); 524 kfree(smu_table->metrics_table); 525 kfree(smu_table->watermarks_table); 526 smu_table->ecc_table = NULL; 527 smu_table->metrics_table = NULL; 528 smu_table->watermarks_table = NULL; 529 smu_table->metrics_time = 0; 530 531 kfree(smu_dpm->dpm_context); 532 kfree(smu_dpm->golden_dpm_context); 533 kfree(smu_dpm->dpm_current_power_state); 534 kfree(smu_dpm->dpm_request_power_state); 535 smu_dpm->dpm_context = NULL; 536 smu_dpm->golden_dpm_context = NULL; 537 smu_dpm->dpm_context_size = 0; 538 smu_dpm->dpm_current_power_state = NULL; 539 smu_dpm->dpm_request_power_state = NULL; 540 541 return 0; 542} 543 544int smu_v13_0_init_power(struct smu_context *smu) 545{ 546 struct smu_power_context *smu_power = &smu->smu_power; 547 548 if (smu_power->power_context || smu_power->power_context_size != 0) 549 return -EINVAL; 550 551 smu_power->power_context = kzalloc(sizeof(struct smu_13_0_power_context), 552 GFP_KERNEL); 553 if (!smu_power->power_context) 554 return -ENOMEM; 555 smu_power->power_context_size = sizeof(struct smu_13_0_power_context); 556 557 return 0; 558} 559 560int smu_v13_0_fini_power(struct smu_context *smu) 561{ 562 struct smu_power_context *smu_power = &smu->smu_power; 563 564 if (!smu_power->power_context || smu_power->power_context_size == 0) 565 return -EINVAL; 566 567 kfree(smu_power->power_context); 568 smu_power->power_context = NULL; 569 smu_power->power_context_size = 0; 570 571 return 0; 572} 573 574int smu_v13_0_get_vbios_bootup_values(struct smu_context *smu) 575{ 576 int ret, index; 577 uint16_t size; 578 uint8_t frev, crev; 579 struct atom_common_table_header *header; 580 struct atom_firmware_info_v3_4 *v_3_4; 581 struct atom_firmware_info_v3_3 *v_3_3; 582 struct atom_firmware_info_v3_1 *v_3_1; 583 struct atom_smu_info_v3_6 *smu_info_v3_6; 584 struct atom_smu_info_v4_0 *smu_info_v4_0; 585 586 index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1, 587 firmwareinfo); 588 589 ret = amdgpu_atombios_get_data_table(smu->adev, index, &size, &frev, &crev, 590 (uint8_t **)&header); 591 if (ret) 592 return ret; 593 594 if (header->format_revision != 3) { 595 dev_err(smu->adev->dev, "unknown atom_firmware_info version! for smu13\n"); 596 return -EINVAL; 597 } 598 599 switch (header->content_revision) { 600 case 0: 601 case 1: 602 case 2: 603 v_3_1 = (struct atom_firmware_info_v3_1 *)header; 604 smu->smu_table.boot_values.revision = v_3_1->firmware_revision; 605 smu->smu_table.boot_values.gfxclk = v_3_1->bootup_sclk_in10khz; 606 smu->smu_table.boot_values.uclk = v_3_1->bootup_mclk_in10khz; 607 smu->smu_table.boot_values.socclk = 0; 608 smu->smu_table.boot_values.dcefclk = 0; 609 smu->smu_table.boot_values.vddc = v_3_1->bootup_vddc_mv; 610 smu->smu_table.boot_values.vddci = v_3_1->bootup_vddci_mv; 611 smu->smu_table.boot_values.mvddc = v_3_1->bootup_mvddc_mv; 612 smu->smu_table.boot_values.vdd_gfx = v_3_1->bootup_vddgfx_mv; 613 smu->smu_table.boot_values.cooling_id = v_3_1->coolingsolution_id; 614 smu->smu_table.boot_values.pp_table_id = 0; 615 break; 616 case 3: 617 v_3_3 = (struct atom_firmware_info_v3_3 *)header; 618 smu->smu_table.boot_values.revision = v_3_3->firmware_revision; 619 smu->smu_table.boot_values.gfxclk = v_3_3->bootup_sclk_in10khz; 620 smu->smu_table.boot_values.uclk = v_3_3->bootup_mclk_in10khz; 621 smu->smu_table.boot_values.socclk = 0; 622 smu->smu_table.boot_values.dcefclk = 0; 623 smu->smu_table.boot_values.vddc = v_3_3->bootup_vddc_mv; 624 smu->smu_table.boot_values.vddci = v_3_3->bootup_vddci_mv; 625 smu->smu_table.boot_values.mvddc = v_3_3->bootup_mvddc_mv; 626 smu->smu_table.boot_values.vdd_gfx = v_3_3->bootup_vddgfx_mv; 627 smu->smu_table.boot_values.cooling_id = v_3_3->coolingsolution_id; 628 smu->smu_table.boot_values.pp_table_id = v_3_3->pplib_pptable_id; 629 break; 630 case 4: 631 default: 632 v_3_4 = (struct atom_firmware_info_v3_4 *)header; 633 smu->smu_table.boot_values.revision = v_3_4->firmware_revision; 634 smu->smu_table.boot_values.gfxclk = v_3_4->bootup_sclk_in10khz; 635 smu->smu_table.boot_values.uclk = v_3_4->bootup_mclk_in10khz; 636 smu->smu_table.boot_values.socclk = 0; 637 smu->smu_table.boot_values.dcefclk = 0; 638 smu->smu_table.boot_values.vddc = v_3_4->bootup_vddc_mv; 639 smu->smu_table.boot_values.vddci = v_3_4->bootup_vddci_mv; 640 smu->smu_table.boot_values.mvddc = v_3_4->bootup_mvddc_mv; 641 smu->smu_table.boot_values.vdd_gfx = v_3_4->bootup_vddgfx_mv; 642 smu->smu_table.boot_values.cooling_id = v_3_4->coolingsolution_id; 643 smu->smu_table.boot_values.pp_table_id = v_3_4->pplib_pptable_id; 644 break; 645 } 646 647 smu->smu_table.boot_values.format_revision = header->format_revision; 648 smu->smu_table.boot_values.content_revision = header->content_revision; 649 650 index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1, 651 smu_info); 652 if (!amdgpu_atombios_get_data_table(smu->adev, index, &size, &frev, &crev, 653 (uint8_t **)&header)) { 654 655 if ((frev == 3) && (crev == 6)) { 656 smu_info_v3_6 = (struct atom_smu_info_v3_6 *)header; 657 658 smu->smu_table.boot_values.socclk = smu_info_v3_6->bootup_socclk_10khz; 659 smu->smu_table.boot_values.vclk = smu_info_v3_6->bootup_vclk_10khz; 660 smu->smu_table.boot_values.dclk = smu_info_v3_6->bootup_dclk_10khz; 661 smu->smu_table.boot_values.fclk = smu_info_v3_6->bootup_fclk_10khz; 662 } else if ((frev == 3) && (crev == 1)) { 663 return 0; 664 } else if ((frev == 4) && (crev == 0)) { 665 smu_info_v4_0 = (struct atom_smu_info_v4_0 *)header; 666 667 smu->smu_table.boot_values.socclk = smu_info_v4_0->bootup_socclk_10khz; 668 smu->smu_table.boot_values.dcefclk = smu_info_v4_0->bootup_dcefclk_10khz; 669 smu->smu_table.boot_values.vclk = smu_info_v4_0->bootup_vclk0_10khz; 670 smu->smu_table.boot_values.dclk = smu_info_v4_0->bootup_dclk0_10khz; 671 smu->smu_table.boot_values.fclk = smu_info_v4_0->bootup_fclk_10khz; 672 } else { 673 dev_warn(smu->adev->dev, "Unexpected and unhandled version: %d.%d\n", 674 (uint32_t)frev, (uint32_t)crev); 675 } 676 } 677 678 return 0; 679} 680 681 682int smu_v13_0_notify_memory_pool_location(struct smu_context *smu) 683{ 684 struct smu_table_context *smu_table = &smu->smu_table; 685 struct smu_table *memory_pool = &smu_table->memory_pool; 686 int ret = 0; 687 uint64_t address; 688 uint32_t address_low, address_high; 689 690 if (memory_pool->size == 0 || memory_pool->cpu_addr == NULL) 691 return ret; 692 693 address = memory_pool->mc_address; 694 address_high = (uint32_t)upper_32_bits(address); 695 address_low = (uint32_t)lower_32_bits(address); 696 697 ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_DramLogSetDramAddrHigh, 698 address_high, NULL); 699 if (ret) 700 return ret; 701 ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_DramLogSetDramAddrLow, 702 address_low, NULL); 703 if (ret) 704 return ret; 705 ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_DramLogSetDramSize, 706 (uint32_t)memory_pool->size, NULL); 707 if (ret) 708 return ret; 709 710 return ret; 711} 712 713int smu_v13_0_set_min_deep_sleep_dcefclk(struct smu_context *smu, uint32_t clk) 714{ 715 int ret; 716 717 ret = smu_cmn_send_smc_msg_with_param(smu, 718 SMU_MSG_SetMinDeepSleepDcefclk, clk, NULL); 719 if (ret) 720 dev_err(smu->adev->dev, "SMU13 attempt to set divider for DCEFCLK Failed!"); 721 722 return ret; 723} 724 725int smu_v13_0_set_driver_table_location(struct smu_context *smu) 726{ 727 struct smu_table *driver_table = &smu->smu_table.driver_table; 728 int ret = 0; 729 730 if (driver_table->mc_address) { 731 ret = smu_cmn_send_smc_msg_with_param(smu, 732 SMU_MSG_SetDriverDramAddrHigh, 733 upper_32_bits(driver_table->mc_address), 734 NULL); 735 if (!ret) 736 ret = smu_cmn_send_smc_msg_with_param(smu, 737 SMU_MSG_SetDriverDramAddrLow, 738 lower_32_bits(driver_table->mc_address), 739 NULL); 740 } 741 742 return ret; 743} 744 745int smu_v13_0_set_tool_table_location(struct smu_context *smu) 746{ 747 int ret = 0; 748 struct smu_table *tool_table = &smu->smu_table.tables[SMU_TABLE_PMSTATUSLOG]; 749 750 if (tool_table->mc_address) { 751 ret = smu_cmn_send_smc_msg_with_param(smu, 752 SMU_MSG_SetToolsDramAddrHigh, 753 upper_32_bits(tool_table->mc_address), 754 NULL); 755 if (!ret) 756 ret = smu_cmn_send_smc_msg_with_param(smu, 757 SMU_MSG_SetToolsDramAddrLow, 758 lower_32_bits(tool_table->mc_address), 759 NULL); 760 } 761 762 return ret; 763} 764 765int smu_v13_0_init_display_count(struct smu_context *smu, uint32_t count) 766{ 767 int ret = 0; 768 769 if (!smu->pm_enabled) 770 return ret; 771 772 ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_NumOfDisplays, count, NULL); 773 774 return ret; 775} 776 777int smu_v13_0_set_allowed_mask(struct smu_context *smu) 778{ 779 struct smu_feature *feature = &smu->smu_feature; 780 int ret = 0; 781 uint32_t feature_mask[2]; 782 783 if (bitmap_empty(feature->allowed, SMU_FEATURE_MAX) || 784 feature->feature_num < 64) 785 return -EINVAL; 786 787 bitmap_to_arr32(feature_mask, feature->allowed, 64); 788 789 ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetAllowedFeaturesMaskHigh, 790 feature_mask[1], NULL); 791 if (ret) 792 return ret; 793 794 return smu_cmn_send_smc_msg_with_param(smu, 795 SMU_MSG_SetAllowedFeaturesMaskLow, 796 feature_mask[0], 797 NULL); 798} 799 800int smu_v13_0_gfx_off_control(struct smu_context *smu, bool enable) 801{ 802 int ret = 0; 803 struct amdgpu_device *adev = smu->adev; 804 805 switch (adev->ip_versions[MP1_HWIP][0]) { 806 case IP_VERSION(13, 0, 0): 807 case IP_VERSION(13, 0, 1): 808 case IP_VERSION(13, 0, 3): 809 case IP_VERSION(13, 0, 4): 810 case IP_VERSION(13, 0, 5): 811 case IP_VERSION(13, 0, 7): 812 case IP_VERSION(13, 0, 8): 813 case IP_VERSION(13, 0, 10): 814 case IP_VERSION(13, 0, 11): 815 if (!(adev->pm.pp_feature & PP_GFXOFF_MASK)) 816 return 0; 817 if (enable) 818 ret = smu_cmn_send_smc_msg(smu, SMU_MSG_AllowGfxOff, NULL); 819 else 820 ret = smu_cmn_send_smc_msg(smu, SMU_MSG_DisallowGfxOff, NULL); 821 break; 822 default: 823 break; 824 } 825 826 return ret; 827} 828 829int smu_v13_0_system_features_control(struct smu_context *smu, 830 bool en) 831{ 832 return smu_cmn_send_smc_msg(smu, (en ? SMU_MSG_EnableAllSmuFeatures : 833 SMU_MSG_DisableAllSmuFeatures), NULL); 834} 835 836int smu_v13_0_notify_display_change(struct smu_context *smu) 837{ 838 int ret = 0; 839 840 if (!amdgpu_device_has_dc_support(smu->adev)) 841 ret = smu_cmn_send_smc_msg(smu, SMU_MSG_DALNotPresent, NULL); 842 843 return ret; 844} 845 846 static int 847smu_v13_0_get_max_sustainable_clock(struct smu_context *smu, uint32_t *clock, 848 enum smu_clk_type clock_select) 849{ 850 int ret = 0; 851 int clk_id; 852 853 if ((smu_cmn_to_asic_specific_index(smu, CMN2ASIC_MAPPING_MSG, SMU_MSG_GetDcModeMaxDpmFreq) < 0) || 854 (smu_cmn_to_asic_specific_index(smu, CMN2ASIC_MAPPING_MSG, SMU_MSG_GetMaxDpmFreq) < 0)) 855 return 0; 856 857 clk_id = smu_cmn_to_asic_specific_index(smu, 858 CMN2ASIC_MAPPING_CLK, 859 clock_select); 860 if (clk_id < 0) 861 return -EINVAL; 862 863 ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_GetDcModeMaxDpmFreq, 864 clk_id << 16, clock); 865 if (ret) { 866 dev_err(smu->adev->dev, "[GetMaxSustainableClock] Failed to get max DC clock from SMC!"); 867 return ret; 868 } 869 870 if (*clock != 0) 871 return 0; 872 873 /* if DC limit is zero, return AC limit */ 874 ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_GetMaxDpmFreq, 875 clk_id << 16, clock); 876 if (ret) { 877 dev_err(smu->adev->dev, "[GetMaxSustainableClock] failed to get max AC clock from SMC!"); 878 return ret; 879 } 880 881 return 0; 882} 883 884int smu_v13_0_init_max_sustainable_clocks(struct smu_context *smu) 885{ 886 struct smu_13_0_max_sustainable_clocks *max_sustainable_clocks = 887 smu->smu_table.max_sustainable_clocks; 888 int ret = 0; 889 890 max_sustainable_clocks->uclock = smu->smu_table.boot_values.uclk / 100; 891 max_sustainable_clocks->soc_clock = smu->smu_table.boot_values.socclk / 100; 892 max_sustainable_clocks->dcef_clock = smu->smu_table.boot_values.dcefclk / 100; 893 max_sustainable_clocks->display_clock = 0xFFFFFFFF; 894 max_sustainable_clocks->phy_clock = 0xFFFFFFFF; 895 max_sustainable_clocks->pixel_clock = 0xFFFFFFFF; 896 897 if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_DPM_UCLK_BIT)) { 898 ret = smu_v13_0_get_max_sustainable_clock(smu, 899 &(max_sustainable_clocks->uclock), 900 SMU_UCLK); 901 if (ret) { 902 dev_err(smu->adev->dev, "[%s] failed to get max UCLK from SMC!", 903 __func__); 904 return ret; 905 } 906 } 907 908 if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_DPM_SOCCLK_BIT)) { 909 ret = smu_v13_0_get_max_sustainable_clock(smu, 910 &(max_sustainable_clocks->soc_clock), 911 SMU_SOCCLK); 912 if (ret) { 913 dev_err(smu->adev->dev, "[%s] failed to get max SOCCLK from SMC!", 914 __func__); 915 return ret; 916 } 917 } 918 919 if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_DPM_DCEFCLK_BIT)) { 920 ret = smu_v13_0_get_max_sustainable_clock(smu, 921 &(max_sustainable_clocks->dcef_clock), 922 SMU_DCEFCLK); 923 if (ret) { 924 dev_err(smu->adev->dev, "[%s] failed to get max DCEFCLK from SMC!", 925 __func__); 926 return ret; 927 } 928 929 ret = smu_v13_0_get_max_sustainable_clock(smu, 930 &(max_sustainable_clocks->display_clock), 931 SMU_DISPCLK); 932 if (ret) { 933 dev_err(smu->adev->dev, "[%s] failed to get max DISPCLK from SMC!", 934 __func__); 935 return ret; 936 } 937 ret = smu_v13_0_get_max_sustainable_clock(smu, 938 &(max_sustainable_clocks->phy_clock), 939 SMU_PHYCLK); 940 if (ret) { 941 dev_err(smu->adev->dev, "[%s] failed to get max PHYCLK from SMC!", 942 __func__); 943 return ret; 944 } 945 ret = smu_v13_0_get_max_sustainable_clock(smu, 946 &(max_sustainable_clocks->pixel_clock), 947 SMU_PIXCLK); 948 if (ret) { 949 dev_err(smu->adev->dev, "[%s] failed to get max PIXCLK from SMC!", 950 __func__); 951 return ret; 952 } 953 } 954 955 if (max_sustainable_clocks->soc_clock < max_sustainable_clocks->uclock) 956 max_sustainable_clocks->uclock = max_sustainable_clocks->soc_clock; 957 958 return 0; 959} 960 961int smu_v13_0_get_current_power_limit(struct smu_context *smu, 962 uint32_t *power_limit) 963{ 964 int power_src; 965 int ret = 0; 966 967 if (!smu_cmn_feature_is_enabled(smu, SMU_FEATURE_PPT_BIT)) 968 return -EINVAL; 969 970 power_src = smu_cmn_to_asic_specific_index(smu, 971 CMN2ASIC_MAPPING_PWR, 972 smu->adev->pm.ac_power ? 973 SMU_POWER_SOURCE_AC : 974 SMU_POWER_SOURCE_DC); 975 if (power_src < 0) 976 return -EINVAL; 977 978 ret = smu_cmn_send_smc_msg_with_param(smu, 979 SMU_MSG_GetPptLimit, 980 power_src << 16, 981 power_limit); 982 if (ret) 983 dev_err(smu->adev->dev, "[%s] get PPT limit failed!", __func__); 984 985 return ret; 986} 987 988int smu_v13_0_set_power_limit(struct smu_context *smu, 989 enum smu_ppt_limit_type limit_type, 990 uint32_t limit) 991{ 992 int ret = 0; 993 994 if (limit_type != SMU_DEFAULT_PPT_LIMIT) 995 return -EINVAL; 996 997 if (!smu_cmn_feature_is_enabled(smu, SMU_FEATURE_PPT_BIT)) { 998 dev_err(smu->adev->dev, "Setting new power limit is not supported!\n"); 999 return -EOPNOTSUPP; 1000 } 1001 1002 ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetPptLimit, limit, NULL); 1003 if (ret) { 1004 dev_err(smu->adev->dev, "[%s] Set power limit Failed!\n", __func__); 1005 return ret; 1006 } 1007 1008 smu->current_power_limit = limit; 1009 1010 return 0; 1011} 1012 1013static int smu_v13_0_allow_ih_interrupt(struct smu_context *smu) 1014{ 1015 return smu_cmn_send_smc_msg(smu, 1016 SMU_MSG_AllowIHHostInterrupt, 1017 NULL); 1018} 1019 1020static int smu_v13_0_process_pending_interrupt(struct smu_context *smu) 1021{ 1022 int ret = 0; 1023 1024 if (smu->dc_controlled_by_gpio && 1025 smu_cmn_feature_is_enabled(smu, SMU_FEATURE_ACDC_BIT)) 1026 ret = smu_v13_0_allow_ih_interrupt(smu); 1027 1028 return ret; 1029} 1030 1031int smu_v13_0_enable_thermal_alert(struct smu_context *smu) 1032{ 1033 int ret = 0; 1034 1035 if (!smu->irq_source.num_types) 1036 return 0; 1037 1038 ret = amdgpu_irq_get(smu->adev, &smu->irq_source, 0); 1039 if (ret) 1040 return ret; 1041 1042 return smu_v13_0_process_pending_interrupt(smu); 1043} 1044 1045int smu_v13_0_disable_thermal_alert(struct smu_context *smu) 1046{ 1047 if (!smu->irq_source.num_types) 1048 return 0; 1049 1050 return amdgpu_irq_put(smu->adev, &smu->irq_source, 0); 1051} 1052 1053static uint16_t convert_to_vddc(uint8_t vid) 1054{ 1055 return (uint16_t) ((6200 - (vid * 25)) / SMU13_VOLTAGE_SCALE); 1056} 1057 1058int smu_v13_0_get_gfx_vdd(struct smu_context *smu, uint32_t *value) 1059{ 1060 struct amdgpu_device *adev = smu->adev; 1061 uint32_t vdd = 0, val_vid = 0; 1062 1063 if (!value) 1064 return -EINVAL; 1065 val_vid = (RREG32_SOC15(SMUIO, 0, regSMUSVI0_TEL_PLANE0) & 1066 SMUSVI0_TEL_PLANE0__SVI0_PLANE0_VDDCOR_MASK) >> 1067 SMUSVI0_TEL_PLANE0__SVI0_PLANE0_VDDCOR__SHIFT; 1068 1069 vdd = (uint32_t)convert_to_vddc((uint8_t)val_vid); 1070 1071 *value = vdd; 1072 1073 return 0; 1074 1075} 1076 1077int 1078smu_v13_0_display_clock_voltage_request(struct smu_context *smu, 1079 struct pp_display_clock_request 1080 *clock_req) 1081{ 1082 enum amd_pp_clock_type clk_type = clock_req->clock_type; 1083 int ret = 0; 1084 enum smu_clk_type clk_select = 0; 1085 uint32_t clk_freq = clock_req->clock_freq_in_khz / 1000; 1086 1087 if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_DPM_DCEFCLK_BIT) || 1088 smu_cmn_feature_is_enabled(smu, SMU_FEATURE_DPM_UCLK_BIT)) { 1089 switch (clk_type) { 1090 case amd_pp_dcef_clock: 1091 clk_select = SMU_DCEFCLK; 1092 break; 1093 case amd_pp_disp_clock: 1094 clk_select = SMU_DISPCLK; 1095 break; 1096 case amd_pp_pixel_clock: 1097 clk_select = SMU_PIXCLK; 1098 break; 1099 case amd_pp_phy_clock: 1100 clk_select = SMU_PHYCLK; 1101 break; 1102 case amd_pp_mem_clock: 1103 clk_select = SMU_UCLK; 1104 break; 1105 default: 1106 dev_info(smu->adev->dev, "[%s] Invalid Clock Type!", __func__); 1107 ret = -EINVAL; 1108 break; 1109 } 1110 1111 if (ret) 1112 goto failed; 1113 1114 if (clk_select == SMU_UCLK && smu->disable_uclk_switch) 1115 return 0; 1116 1117 ret = smu_v13_0_set_hard_freq_limited_range(smu, clk_select, clk_freq, 0); 1118 1119 if (clk_select == SMU_UCLK) 1120 smu->hard_min_uclk_req_from_dal = clk_freq; 1121 } 1122 1123failed: 1124 return ret; 1125} 1126 1127uint32_t smu_v13_0_get_fan_control_mode(struct smu_context *smu) 1128{ 1129 if (!smu_cmn_feature_is_enabled(smu, SMU_FEATURE_FAN_CONTROL_BIT)) 1130 return AMD_FAN_CTRL_MANUAL; 1131 else 1132 return AMD_FAN_CTRL_AUTO; 1133} 1134 1135 static int 1136smu_v13_0_auto_fan_control(struct smu_context *smu, bool auto_fan_control) 1137{ 1138 int ret = 0; 1139 1140 if (!smu_cmn_feature_is_supported(smu, SMU_FEATURE_FAN_CONTROL_BIT)) 1141 return 0; 1142 1143 ret = smu_cmn_feature_set_enabled(smu, SMU_FEATURE_FAN_CONTROL_BIT, auto_fan_control); 1144 if (ret) 1145 dev_err(smu->adev->dev, "[%s]%s smc FAN CONTROL feature failed!", 1146 __func__, (auto_fan_control ? "Start" : "Stop")); 1147 1148 return ret; 1149} 1150 1151 static int 1152smu_v13_0_set_fan_static_mode(struct smu_context *smu, uint32_t mode) 1153{ 1154 struct amdgpu_device *adev = smu->adev; 1155 1156 WREG32_SOC15(THM, 0, regCG_FDO_CTRL2, 1157 REG_SET_FIELD(RREG32_SOC15(THM, 0, regCG_FDO_CTRL2), 1158 CG_FDO_CTRL2, TMIN, 0)); 1159 WREG32_SOC15(THM, 0, regCG_FDO_CTRL2, 1160 REG_SET_FIELD(RREG32_SOC15(THM, 0, regCG_FDO_CTRL2), 1161 CG_FDO_CTRL2, FDO_PWM_MODE, mode)); 1162 1163 return 0; 1164} 1165 1166int smu_v13_0_set_fan_speed_pwm(struct smu_context *smu, 1167 uint32_t speed) 1168{ 1169 struct amdgpu_device *adev = smu->adev; 1170 uint32_t duty100, duty; 1171 uint64_t tmp64; 1172 1173 speed = MIN(speed, 255); 1174 1175 if (smu_v13_0_auto_fan_control(smu, 0)) 1176 return -EINVAL; 1177 1178 duty100 = REG_GET_FIELD(RREG32_SOC15(THM, 0, regCG_FDO_CTRL1), 1179 CG_FDO_CTRL1, FMAX_DUTY100); 1180 if (!duty100) 1181 return -EINVAL; 1182 1183 tmp64 = (uint64_t)speed * duty100; 1184 do_div(tmp64, 255); 1185 duty = (uint32_t)tmp64; 1186 1187 WREG32_SOC15(THM, 0, regCG_FDO_CTRL0, 1188 REG_SET_FIELD(RREG32_SOC15(THM, 0, regCG_FDO_CTRL0), 1189 CG_FDO_CTRL0, FDO_STATIC_DUTY, duty)); 1190 1191 return smu_v13_0_set_fan_static_mode(smu, FDO_PWM_MODE_STATIC); 1192} 1193 1194 int 1195smu_v13_0_set_fan_control_mode(struct smu_context *smu, 1196 uint32_t mode) 1197{ 1198 int ret = 0; 1199 1200 switch (mode) { 1201 case AMD_FAN_CTRL_NONE: 1202 ret = smu_v13_0_set_fan_speed_pwm(smu, 255); 1203 break; 1204 case AMD_FAN_CTRL_MANUAL: 1205 ret = smu_v13_0_auto_fan_control(smu, 0); 1206 break; 1207 case AMD_FAN_CTRL_AUTO: 1208 ret = smu_v13_0_auto_fan_control(smu, 1); 1209 break; 1210 default: 1211 break; 1212 } 1213 1214 if (ret) { 1215 dev_err(smu->adev->dev, "[%s]Set fan control mode failed!", __func__); 1216 return -EINVAL; 1217 } 1218 1219 return ret; 1220} 1221 1222int smu_v13_0_set_fan_speed_rpm(struct smu_context *smu, 1223 uint32_t speed) 1224{ 1225 struct amdgpu_device *adev = smu->adev; 1226 uint32_t crystal_clock_freq = 2500; 1227 uint32_t tach_period; 1228 int ret; 1229 1230 if (!speed) 1231 return -EINVAL; 1232 1233 ret = smu_v13_0_auto_fan_control(smu, 0); 1234 if (ret) 1235 return ret; 1236 1237 tach_period = 60 * crystal_clock_freq * 10000 / (8 * speed); 1238 WREG32_SOC15(THM, 0, regCG_TACH_CTRL, 1239 REG_SET_FIELD(RREG32_SOC15(THM, 0, regCG_TACH_CTRL), 1240 CG_TACH_CTRL, TARGET_PERIOD, 1241 tach_period)); 1242 1243 return smu_v13_0_set_fan_static_mode(smu, FDO_PWM_MODE_STATIC_RPM); 1244} 1245 1246int smu_v13_0_set_xgmi_pstate(struct smu_context *smu, 1247 uint32_t pstate) 1248{ 1249 int ret = 0; 1250 ret = smu_cmn_send_smc_msg_with_param(smu, 1251 SMU_MSG_SetXgmiMode, 1252 pstate ? XGMI_MODE_PSTATE_D0 : XGMI_MODE_PSTATE_D3, 1253 NULL); 1254 return ret; 1255} 1256 1257static int smu_v13_0_set_irq_state(struct amdgpu_device *adev, 1258 struct amdgpu_irq_src *source, 1259 unsigned tyep, 1260 enum amdgpu_interrupt_state state) 1261{ 1262 struct smu_context *smu = adev->powerplay.pp_handle; 1263 uint32_t low, high; 1264 uint32_t val = 0; 1265 1266 switch (state) { 1267 case AMDGPU_IRQ_STATE_DISABLE: 1268 /* For THM irqs */ 1269 val = RREG32_SOC15(THM, 0, regTHM_THERMAL_INT_CTRL); 1270 val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, THERM_INTH_MASK, 1); 1271 val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, THERM_INTL_MASK, 1); 1272 WREG32_SOC15(THM, 0, regTHM_THERMAL_INT_CTRL, val); 1273 1274 WREG32_SOC15(THM, 0, regTHM_THERMAL_INT_ENA, 0); 1275 1276 /* For MP1 SW irqs */ 1277 val = RREG32_SOC15(MP1, 0, regMP1_SMN_IH_SW_INT_CTRL); 1278 val = REG_SET_FIELD(val, MP1_SMN_IH_SW_INT_CTRL, INT_MASK, 1); 1279 WREG32_SOC15(MP1, 0, regMP1_SMN_IH_SW_INT_CTRL, val); 1280 1281 break; 1282 case AMDGPU_IRQ_STATE_ENABLE: 1283 /* For THM irqs */ 1284 low = max(SMU_THERMAL_MINIMUM_ALERT_TEMP, 1285 smu->thermal_range.min / SMU_TEMPERATURE_UNITS_PER_CENTIGRADES); 1286 high = min(SMU_THERMAL_MAXIMUM_ALERT_TEMP, 1287 smu->thermal_range.software_shutdown_temp); 1288 1289 val = RREG32_SOC15(THM, 0, regTHM_THERMAL_INT_CTRL); 1290 val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, MAX_IH_CREDIT, 5); 1291 val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, THERM_IH_HW_ENA, 1); 1292 val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, THERM_INTH_MASK, 0); 1293 val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, THERM_INTL_MASK, 0); 1294 val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, DIG_THERM_INTH, (high & 0xff)); 1295 val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, DIG_THERM_INTL, (low & 0xff)); 1296 val = val & (~THM_THERMAL_INT_CTRL__THERM_TRIGGER_MASK_MASK); 1297 WREG32_SOC15(THM, 0, regTHM_THERMAL_INT_CTRL, val); 1298 1299 val = (1 << THM_THERMAL_INT_ENA__THERM_INTH_CLR__SHIFT); 1300 val |= (1 << THM_THERMAL_INT_ENA__THERM_INTL_CLR__SHIFT); 1301 val |= (1 << THM_THERMAL_INT_ENA__THERM_TRIGGER_CLR__SHIFT); 1302 WREG32_SOC15(THM, 0, regTHM_THERMAL_INT_ENA, val); 1303 1304 /* For MP1 SW irqs */ 1305 val = RREG32_SOC15(MP1, 0, regMP1_SMN_IH_SW_INT); 1306 val = REG_SET_FIELD(val, MP1_SMN_IH_SW_INT, ID, 0xFE); 1307 val = REG_SET_FIELD(val, MP1_SMN_IH_SW_INT, VALID, 0); 1308 WREG32_SOC15(MP1, 0, regMP1_SMN_IH_SW_INT, val); 1309 1310 val = RREG32_SOC15(MP1, 0, regMP1_SMN_IH_SW_INT_CTRL); 1311 val = REG_SET_FIELD(val, MP1_SMN_IH_SW_INT_CTRL, INT_MASK, 0); 1312 WREG32_SOC15(MP1, 0, regMP1_SMN_IH_SW_INT_CTRL, val); 1313 1314 break; 1315 default: 1316 break; 1317 } 1318 1319 return 0; 1320} 1321 1322static int smu_v13_0_ack_ac_dc_interrupt(struct smu_context *smu) 1323{ 1324 return smu_cmn_send_smc_msg(smu, 1325 SMU_MSG_ReenableAcDcInterrupt, 1326 NULL); 1327} 1328 1329#define THM_11_0__SRCID__THM_DIG_THERM_L2H 0 /* ASIC_TEMP > CG_THERMAL_INT.DIG_THERM_INTH */ 1330#define THM_11_0__SRCID__THM_DIG_THERM_H2L 1 /* ASIC_TEMP < CG_THERMAL_INT.DIG_THERM_INTL */ 1331#define SMUIO_11_0__SRCID__SMUIO_GPIO19 83 1332 1333static int smu_v13_0_irq_process(struct amdgpu_device *adev, 1334 struct amdgpu_irq_src *source, 1335 struct amdgpu_iv_entry *entry) 1336{ 1337 struct smu_context *smu = adev->powerplay.pp_handle; 1338 uint32_t client_id = entry->client_id; 1339 uint32_t src_id = entry->src_id; 1340 /* 1341 * ctxid is used to distinguish different 1342 * events for SMCToHost interrupt. 1343 */ 1344 uint32_t ctxid = entry->src_data[0]; 1345 uint32_t data; 1346 uint32_t high; 1347 1348 if (client_id == SOC15_IH_CLIENTID_THM) { 1349 switch (src_id) { 1350 case THM_11_0__SRCID__THM_DIG_THERM_L2H: 1351 schedule_delayed_work(&smu->swctf_delayed_work, 1352 msecs_to_jiffies(AMDGPU_SWCTF_EXTRA_DELAY)); 1353 break; 1354 case THM_11_0__SRCID__THM_DIG_THERM_H2L: 1355 dev_emerg(adev->dev, "ERROR: GPU under temperature range detected\n"); 1356 break; 1357 default: 1358 dev_emerg(adev->dev, "ERROR: GPU under temperature range unknown src id (%d)\n", 1359 src_id); 1360 break; 1361 } 1362 } else if (client_id == SOC15_IH_CLIENTID_ROM_SMUIO) { 1363 dev_emerg(adev->dev, "ERROR: GPU HW Critical Temperature Fault(aka CTF) detected!\n"); 1364 /* 1365 * HW CTF just occurred. Shutdown to prevent further damage. 1366 */ 1367 dev_emerg(adev->dev, "ERROR: System is going to shutdown due to GPU HW CTF!\n"); 1368 orderly_poweroff(true); 1369 } else if (client_id == SOC15_IH_CLIENTID_MP1) { 1370 if (src_id == 0xfe) { 1371 /* ACK SMUToHost interrupt */ 1372 data = RREG32_SOC15(MP1, 0, regMP1_SMN_IH_SW_INT_CTRL); 1373 data = REG_SET_FIELD(data, MP1_SMN_IH_SW_INT_CTRL, INT_ACK, 1); 1374 WREG32_SOC15(MP1, 0, regMP1_SMN_IH_SW_INT_CTRL, data); 1375 1376 switch (ctxid) { 1377 case 0x3: 1378 dev_dbg(adev->dev, "Switched to AC mode!\n"); 1379 smu_v13_0_ack_ac_dc_interrupt(smu); 1380 adev->pm.ac_power = true; 1381 break; 1382 case 0x4: 1383 dev_dbg(adev->dev, "Switched to DC mode!\n"); 1384 smu_v13_0_ack_ac_dc_interrupt(smu); 1385 adev->pm.ac_power = false; 1386 break; 1387 case 0x7: 1388 /* 1389 * Increment the throttle interrupt counter 1390 */ 1391 atomic64_inc(&smu->throttle_int_counter); 1392 1393 if (!atomic_read(&adev->throttling_logging_enabled)) 1394 return 0; 1395 1396 if (__ratelimit(&adev->throttling_logging_rs)) 1397 schedule_work(&smu->throttling_logging_work); 1398 1399 break; 1400 case 0x8: 1401 high = smu->thermal_range.software_shutdown_temp + 1402 smu->thermal_range.software_shutdown_temp_offset; 1403 high = min_t(typeof(high), 1404 SMU_THERMAL_MAXIMUM_ALERT_TEMP, 1405 high); 1406 dev_emerg(adev->dev, "Reduce soft CTF limit to %d (by an offset %d)\n", 1407 high, 1408 smu->thermal_range.software_shutdown_temp_offset); 1409 1410 data = RREG32_SOC15(THM, 0, regTHM_THERMAL_INT_CTRL); 1411 data = REG_SET_FIELD(data, THM_THERMAL_INT_CTRL, 1412 DIG_THERM_INTH, 1413 (high & 0xff)); 1414 data = data & (~THM_THERMAL_INT_CTRL__THERM_TRIGGER_MASK_MASK); 1415 WREG32_SOC15(THM, 0, regTHM_THERMAL_INT_CTRL, data); 1416 break; 1417 case 0x9: 1418 high = min_t(typeof(high), 1419 SMU_THERMAL_MAXIMUM_ALERT_TEMP, 1420 smu->thermal_range.software_shutdown_temp); 1421 dev_emerg(adev->dev, "Recover soft CTF limit to %d\n", high); 1422 1423 data = RREG32_SOC15(THM, 0, regTHM_THERMAL_INT_CTRL); 1424 data = REG_SET_FIELD(data, THM_THERMAL_INT_CTRL, 1425 DIG_THERM_INTH, 1426 (high & 0xff)); 1427 data = data & (~THM_THERMAL_INT_CTRL__THERM_TRIGGER_MASK_MASK); 1428 WREG32_SOC15(THM, 0, regTHM_THERMAL_INT_CTRL, data); 1429 break; 1430 } 1431 } 1432 } 1433 1434 return 0; 1435} 1436 1437static const struct amdgpu_irq_src_funcs smu_v13_0_irq_funcs = { 1438 .set = smu_v13_0_set_irq_state, 1439 .process = smu_v13_0_irq_process, 1440}; 1441 1442int smu_v13_0_register_irq_handler(struct smu_context *smu) 1443{ 1444 struct amdgpu_device *adev = smu->adev; 1445 struct amdgpu_irq_src *irq_src = &smu->irq_source; 1446 int ret = 0; 1447 1448 if (amdgpu_sriov_vf(adev)) 1449 return 0; 1450 1451 irq_src->num_types = 1; 1452 irq_src->funcs = &smu_v13_0_irq_funcs; 1453 1454 ret = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_THM, 1455 THM_11_0__SRCID__THM_DIG_THERM_L2H, 1456 irq_src); 1457 if (ret) 1458 return ret; 1459 1460 ret = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_THM, 1461 THM_11_0__SRCID__THM_DIG_THERM_H2L, 1462 irq_src); 1463 if (ret) 1464 return ret; 1465 1466 /* Register CTF(GPIO_19) interrupt */ 1467 ret = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_ROM_SMUIO, 1468 SMUIO_11_0__SRCID__SMUIO_GPIO19, 1469 irq_src); 1470 if (ret) 1471 return ret; 1472 1473 ret = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_MP1, 1474 0xfe, 1475 irq_src); 1476 if (ret) 1477 return ret; 1478 1479 return ret; 1480} 1481 1482int smu_v13_0_get_max_sustainable_clocks_by_dc(struct smu_context *smu, 1483 struct pp_smu_nv_clock_table *max_clocks) 1484{ 1485 struct smu_table_context *table_context = &smu->smu_table; 1486 struct smu_13_0_max_sustainable_clocks *sustainable_clocks = NULL; 1487 1488 if (!max_clocks || !table_context->max_sustainable_clocks) 1489 return -EINVAL; 1490 1491 sustainable_clocks = table_context->max_sustainable_clocks; 1492 1493 max_clocks->dcfClockInKhz = 1494 (unsigned int) sustainable_clocks->dcef_clock * 1000; 1495 max_clocks->displayClockInKhz = 1496 (unsigned int) sustainable_clocks->display_clock * 1000; 1497 max_clocks->phyClockInKhz = 1498 (unsigned int) sustainable_clocks->phy_clock * 1000; 1499 max_clocks->pixelClockInKhz = 1500 (unsigned int) sustainable_clocks->pixel_clock * 1000; 1501 max_clocks->uClockInKhz = 1502 (unsigned int) sustainable_clocks->uclock * 1000; 1503 max_clocks->socClockInKhz = 1504 (unsigned int) sustainable_clocks->soc_clock * 1000; 1505 max_clocks->dscClockInKhz = 0; 1506 max_clocks->dppClockInKhz = 0; 1507 max_clocks->fabricClockInKhz = 0; 1508 1509 return 0; 1510} 1511 1512int smu_v13_0_set_azalia_d3_pme(struct smu_context *smu) 1513{ 1514 int ret = 0; 1515 1516 ret = smu_cmn_send_smc_msg(smu, SMU_MSG_BacoAudioD3PME, NULL); 1517 1518 return ret; 1519} 1520 1521static int smu_v13_0_wait_for_reset_complete(struct smu_context *smu, 1522 uint64_t event_arg) 1523{ 1524 int ret = 0; 1525 1526 dev_dbg(smu->adev->dev, "waiting for smu reset complete\n"); 1527 ret = smu_cmn_send_smc_msg(smu, SMU_MSG_GfxDriverResetRecovery, NULL); 1528 1529 return ret; 1530} 1531 1532int smu_v13_0_wait_for_event(struct smu_context *smu, enum smu_event_type event, 1533 uint64_t event_arg) 1534{ 1535 int ret = -EINVAL; 1536 1537 switch (event) { 1538 case SMU_EVENT_RESET_COMPLETE: 1539 ret = smu_v13_0_wait_for_reset_complete(smu, event_arg); 1540 break; 1541 default: 1542 break; 1543 } 1544 1545 return ret; 1546} 1547 1548int smu_v13_0_get_dpm_ultimate_freq(struct smu_context *smu, enum smu_clk_type clk_type, 1549 uint32_t *min, uint32_t *max) 1550{ 1551 int ret = 0, clk_id = 0; 1552 uint32_t param = 0; 1553 uint32_t clock_limit; 1554 1555 if (!smu_cmn_clk_dpm_is_enabled(smu, clk_type)) { 1556 switch (clk_type) { 1557 case SMU_MCLK: 1558 case SMU_UCLK: 1559 clock_limit = smu->smu_table.boot_values.uclk; 1560 break; 1561 case SMU_GFXCLK: 1562 case SMU_SCLK: 1563 clock_limit = smu->smu_table.boot_values.gfxclk; 1564 break; 1565 case SMU_SOCCLK: 1566 clock_limit = smu->smu_table.boot_values.socclk; 1567 break; 1568 default: 1569 clock_limit = 0; 1570 break; 1571 } 1572 1573 /* clock in Mhz unit */ 1574 if (min) 1575 *min = clock_limit / 100; 1576 if (max) 1577 *max = clock_limit / 100; 1578 1579 return 0; 1580 } 1581 1582 clk_id = smu_cmn_to_asic_specific_index(smu, 1583 CMN2ASIC_MAPPING_CLK, 1584 clk_type); 1585 if (clk_id < 0) { 1586 ret = -EINVAL; 1587 goto failed; 1588 } 1589 param = (clk_id & 0xffff) << 16; 1590 1591 if (max) { 1592 if (smu->adev->pm.ac_power) 1593 ret = smu_cmn_send_smc_msg_with_param(smu, 1594 SMU_MSG_GetMaxDpmFreq, 1595 param, 1596 max); 1597 else 1598 ret = smu_cmn_send_smc_msg_with_param(smu, 1599 SMU_MSG_GetDcModeMaxDpmFreq, 1600 param, 1601 max); 1602 if (ret) 1603 goto failed; 1604 } 1605 1606 if (min) { 1607 ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_GetMinDpmFreq, param, min); 1608 if (ret) 1609 goto failed; 1610 } 1611 1612failed: 1613 return ret; 1614} 1615 1616int smu_v13_0_set_soft_freq_limited_range(struct smu_context *smu, 1617 enum smu_clk_type clk_type, 1618 uint32_t min, 1619 uint32_t max) 1620{ 1621 int ret = 0, clk_id = 0; 1622 uint32_t param; 1623 1624 if (!smu_cmn_clk_dpm_is_enabled(smu, clk_type)) 1625 return 0; 1626 1627 clk_id = smu_cmn_to_asic_specific_index(smu, 1628 CMN2ASIC_MAPPING_CLK, 1629 clk_type); 1630 if (clk_id < 0) 1631 return clk_id; 1632 1633 if (max > 0) { 1634 param = (uint32_t)((clk_id << 16) | (max & 0xffff)); 1635 ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetSoftMaxByFreq, 1636 param, NULL); 1637 if (ret) 1638 goto out; 1639 } 1640 1641 if (min > 0) { 1642 param = (uint32_t)((clk_id << 16) | (min & 0xffff)); 1643 ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetSoftMinByFreq, 1644 param, NULL); 1645 if (ret) 1646 goto out; 1647 } 1648 1649out: 1650 return ret; 1651} 1652 1653int smu_v13_0_set_hard_freq_limited_range(struct smu_context *smu, 1654 enum smu_clk_type clk_type, 1655 uint32_t min, 1656 uint32_t max) 1657{ 1658 int ret = 0, clk_id = 0; 1659 uint32_t param; 1660 1661 if (min <= 0 && max <= 0) 1662 return -EINVAL; 1663 1664 if (!smu_cmn_clk_dpm_is_enabled(smu, clk_type)) 1665 return 0; 1666 1667 clk_id = smu_cmn_to_asic_specific_index(smu, 1668 CMN2ASIC_MAPPING_CLK, 1669 clk_type); 1670 if (clk_id < 0) 1671 return clk_id; 1672 1673 if (max > 0) { 1674 param = (uint32_t)((clk_id << 16) | (max & 0xffff)); 1675 ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetHardMaxByFreq, 1676 param, NULL); 1677 if (ret) 1678 return ret; 1679 } 1680 1681 if (min > 0) { 1682 param = (uint32_t)((clk_id << 16) | (min & 0xffff)); 1683 ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetHardMinByFreq, 1684 param, NULL); 1685 if (ret) 1686 return ret; 1687 } 1688 1689 return ret; 1690} 1691 1692int smu_v13_0_set_performance_level(struct smu_context *smu, 1693 enum amd_dpm_forced_level level) 1694{ 1695 struct smu_13_0_dpm_context *dpm_context = 1696 smu->smu_dpm.dpm_context; 1697 struct smu_13_0_dpm_table *gfx_table = 1698 &dpm_context->dpm_tables.gfx_table; 1699 struct smu_13_0_dpm_table *mem_table = 1700 &dpm_context->dpm_tables.uclk_table; 1701 struct smu_13_0_dpm_table *soc_table = 1702 &dpm_context->dpm_tables.soc_table; 1703 struct smu_13_0_dpm_table *vclk_table = 1704 &dpm_context->dpm_tables.vclk_table; 1705 struct smu_13_0_dpm_table *dclk_table = 1706 &dpm_context->dpm_tables.dclk_table; 1707 struct smu_13_0_dpm_table *fclk_table = 1708 &dpm_context->dpm_tables.fclk_table; 1709 struct smu_umd_pstate_table *pstate_table = 1710 &smu->pstate_table; 1711 struct amdgpu_device *adev = smu->adev; 1712 uint32_t sclk_min = 0, sclk_max = 0; 1713 uint32_t mclk_min = 0, mclk_max = 0; 1714 uint32_t socclk_min = 0, socclk_max = 0; 1715 uint32_t vclk_min = 0, vclk_max = 0; 1716 uint32_t dclk_min = 0, dclk_max = 0; 1717 uint32_t fclk_min = 0, fclk_max = 0; 1718 int ret = 0, i; 1719 1720 switch (level) { 1721 case AMD_DPM_FORCED_LEVEL_HIGH: 1722 sclk_min = sclk_max = gfx_table->max; 1723 mclk_min = mclk_max = mem_table->max; 1724 socclk_min = socclk_max = soc_table->max; 1725 vclk_min = vclk_max = vclk_table->max; 1726 dclk_min = dclk_max = dclk_table->max; 1727 fclk_min = fclk_max = fclk_table->max; 1728 break; 1729 case AMD_DPM_FORCED_LEVEL_LOW: 1730 sclk_min = sclk_max = gfx_table->min; 1731 mclk_min = mclk_max = mem_table->min; 1732 socclk_min = socclk_max = soc_table->min; 1733 vclk_min = vclk_max = vclk_table->min; 1734 dclk_min = dclk_max = dclk_table->min; 1735 fclk_min = fclk_max = fclk_table->min; 1736 break; 1737 case AMD_DPM_FORCED_LEVEL_AUTO: 1738 sclk_min = gfx_table->min; 1739 sclk_max = gfx_table->max; 1740 mclk_min = mem_table->min; 1741 mclk_max = mem_table->max; 1742 socclk_min = soc_table->min; 1743 socclk_max = soc_table->max; 1744 vclk_min = vclk_table->min; 1745 vclk_max = vclk_table->max; 1746 dclk_min = dclk_table->min; 1747 dclk_max = dclk_table->max; 1748 fclk_min = fclk_table->min; 1749 fclk_max = fclk_table->max; 1750 break; 1751 case AMD_DPM_FORCED_LEVEL_PROFILE_STANDARD: 1752 sclk_min = sclk_max = pstate_table->gfxclk_pstate.standard; 1753 mclk_min = mclk_max = pstate_table->uclk_pstate.standard; 1754 socclk_min = socclk_max = pstate_table->socclk_pstate.standard; 1755 vclk_min = vclk_max = pstate_table->vclk_pstate.standard; 1756 dclk_min = dclk_max = pstate_table->dclk_pstate.standard; 1757 fclk_min = fclk_max = pstate_table->fclk_pstate.standard; 1758 break; 1759 case AMD_DPM_FORCED_LEVEL_PROFILE_MIN_SCLK: 1760 sclk_min = sclk_max = pstate_table->gfxclk_pstate.min; 1761 break; 1762 case AMD_DPM_FORCED_LEVEL_PROFILE_MIN_MCLK: 1763 mclk_min = mclk_max = pstate_table->uclk_pstate.min; 1764 break; 1765 case AMD_DPM_FORCED_LEVEL_PROFILE_PEAK: 1766 sclk_min = sclk_max = pstate_table->gfxclk_pstate.peak; 1767 mclk_min = mclk_max = pstate_table->uclk_pstate.peak; 1768 socclk_min = socclk_max = pstate_table->socclk_pstate.peak; 1769 vclk_min = vclk_max = pstate_table->vclk_pstate.peak; 1770 dclk_min = dclk_max = pstate_table->dclk_pstate.peak; 1771 fclk_min = fclk_max = pstate_table->fclk_pstate.peak; 1772 break; 1773 case AMD_DPM_FORCED_LEVEL_MANUAL: 1774 case AMD_DPM_FORCED_LEVEL_PROFILE_EXIT: 1775 return 0; 1776 default: 1777 dev_err(adev->dev, "Invalid performance level %d\n", level); 1778 return -EINVAL; 1779 } 1780 1781 /* 1782 * Unset those settings for SMU 13.0.2. As soft limits settings 1783 * for those clock domains are not supported. 1784 */ 1785 if (smu->adev->ip_versions[MP1_HWIP][0] == IP_VERSION(13, 0, 2)) { 1786 mclk_min = mclk_max = 0; 1787 socclk_min = socclk_max = 0; 1788 vclk_min = vclk_max = 0; 1789 dclk_min = dclk_max = 0; 1790 fclk_min = fclk_max = 0; 1791 } 1792 1793 if (sclk_min && sclk_max) { 1794 ret = smu_v13_0_set_soft_freq_limited_range(smu, 1795 SMU_GFXCLK, 1796 sclk_min, 1797 sclk_max); 1798 if (ret) 1799 return ret; 1800 1801 pstate_table->gfxclk_pstate.curr.min = sclk_min; 1802 pstate_table->gfxclk_pstate.curr.max = sclk_max; 1803 } 1804 1805 if (mclk_min && mclk_max) { 1806 ret = smu_v13_0_set_soft_freq_limited_range(smu, 1807 SMU_MCLK, 1808 mclk_min, 1809 mclk_max); 1810 if (ret) 1811 return ret; 1812 1813 pstate_table->uclk_pstate.curr.min = mclk_min; 1814 pstate_table->uclk_pstate.curr.max = mclk_max; 1815 } 1816 1817 if (socclk_min && socclk_max) { 1818 ret = smu_v13_0_set_soft_freq_limited_range(smu, 1819 SMU_SOCCLK, 1820 socclk_min, 1821 socclk_max); 1822 if (ret) 1823 return ret; 1824 1825 pstate_table->socclk_pstate.curr.min = socclk_min; 1826 pstate_table->socclk_pstate.curr.max = socclk_max; 1827 } 1828 1829 if (vclk_min && vclk_max) { 1830 for (i = 0; i < adev->vcn.num_vcn_inst; i++) { 1831 if (adev->vcn.harvest_config & (1 << i)) 1832 continue; 1833 ret = smu_v13_0_set_soft_freq_limited_range(smu, 1834 i ? SMU_VCLK1 : SMU_VCLK, 1835 vclk_min, 1836 vclk_max); 1837 if (ret) 1838 return ret; 1839 } 1840 pstate_table->vclk_pstate.curr.min = vclk_min; 1841 pstate_table->vclk_pstate.curr.max = vclk_max; 1842 } 1843 1844 if (dclk_min && dclk_max) { 1845 for (i = 0; i < adev->vcn.num_vcn_inst; i++) { 1846 if (adev->vcn.harvest_config & (1 << i)) 1847 continue; 1848 ret = smu_v13_0_set_soft_freq_limited_range(smu, 1849 i ? SMU_DCLK1 : SMU_DCLK, 1850 dclk_min, 1851 dclk_max); 1852 if (ret) 1853 return ret; 1854 } 1855 pstate_table->dclk_pstate.curr.min = dclk_min; 1856 pstate_table->dclk_pstate.curr.max = dclk_max; 1857 } 1858 1859 if (fclk_min && fclk_max) { 1860 ret = smu_v13_0_set_soft_freq_limited_range(smu, 1861 SMU_FCLK, 1862 fclk_min, 1863 fclk_max); 1864 if (ret) 1865 return ret; 1866 1867 pstate_table->fclk_pstate.curr.min = fclk_min; 1868 pstate_table->fclk_pstate.curr.max = fclk_max; 1869 } 1870 1871 return ret; 1872} 1873 1874int smu_v13_0_set_power_source(struct smu_context *smu, 1875 enum smu_power_src_type power_src) 1876{ 1877 int pwr_source; 1878 1879 pwr_source = smu_cmn_to_asic_specific_index(smu, 1880 CMN2ASIC_MAPPING_PWR, 1881 (uint32_t)power_src); 1882 if (pwr_source < 0) 1883 return -EINVAL; 1884 1885 return smu_cmn_send_smc_msg_with_param(smu, 1886 SMU_MSG_NotifyPowerSource, 1887 pwr_source, 1888 NULL); 1889} 1890 1891int smu_v13_0_get_dpm_freq_by_index(struct smu_context *smu, 1892 enum smu_clk_type clk_type, uint16_t level, 1893 uint32_t *value) 1894{ 1895 int ret = 0, clk_id = 0; 1896 uint32_t param; 1897 1898 if (!value) 1899 return -EINVAL; 1900 1901 if (!smu_cmn_clk_dpm_is_enabled(smu, clk_type)) 1902 return 0; 1903 1904 clk_id = smu_cmn_to_asic_specific_index(smu, 1905 CMN2ASIC_MAPPING_CLK, 1906 clk_type); 1907 if (clk_id < 0) 1908 return clk_id; 1909 1910 param = (uint32_t)(((clk_id & 0xffff) << 16) | (level & 0xffff)); 1911 1912 ret = smu_cmn_send_smc_msg_with_param(smu, 1913 SMU_MSG_GetDpmFreqByIndex, 1914 param, 1915 value); 1916 if (ret) 1917 return ret; 1918 1919 *value = *value & 0x7fffffff; 1920 1921 return ret; 1922} 1923 1924static int smu_v13_0_get_dpm_level_count(struct smu_context *smu, 1925 enum smu_clk_type clk_type, 1926 uint32_t *value) 1927{ 1928 int ret; 1929 1930 ret = smu_v13_0_get_dpm_freq_by_index(smu, clk_type, 0xff, value); 1931 /* SMU v13.0.2 FW returns 0 based max level, increment by one for it */ 1932 if ((smu->adev->ip_versions[MP1_HWIP][0] == IP_VERSION(13, 0, 2)) && (!ret && value)) 1933 ++(*value); 1934 1935 return ret; 1936} 1937 1938static int smu_v13_0_get_fine_grained_status(struct smu_context *smu, 1939 enum smu_clk_type clk_type, 1940 bool *is_fine_grained_dpm) 1941{ 1942 int ret = 0, clk_id = 0; 1943 uint32_t param; 1944 uint32_t value; 1945 1946 if (!is_fine_grained_dpm) 1947 return -EINVAL; 1948 1949 if (!smu_cmn_clk_dpm_is_enabled(smu, clk_type)) 1950 return 0; 1951 1952 clk_id = smu_cmn_to_asic_specific_index(smu, 1953 CMN2ASIC_MAPPING_CLK, 1954 clk_type); 1955 if (clk_id < 0) 1956 return clk_id; 1957 1958 param = (uint32_t)(((clk_id & 0xffff) << 16) | 0xff); 1959 1960 ret = smu_cmn_send_smc_msg_with_param(smu, 1961 SMU_MSG_GetDpmFreqByIndex, 1962 param, 1963 &value); 1964 if (ret) 1965 return ret; 1966 1967 /* 1968 * BIT31: 1 - Fine grained DPM, 0 - Dicrete DPM 1969 * now, we un-support it 1970 */ 1971 *is_fine_grained_dpm = value & 0x80000000; 1972 1973 return 0; 1974} 1975 1976int smu_v13_0_set_single_dpm_table(struct smu_context *smu, 1977 enum smu_clk_type clk_type, 1978 struct smu_13_0_dpm_table *single_dpm_table) 1979{ 1980 int ret = 0; 1981 uint32_t clk; 1982 int i; 1983 1984 ret = smu_v13_0_get_dpm_level_count(smu, 1985 clk_type, 1986 &single_dpm_table->count); 1987 if (ret) { 1988 dev_err(smu->adev->dev, "[%s] failed to get dpm levels!\n", __func__); 1989 return ret; 1990 } 1991 1992 if (smu->adev->ip_versions[MP1_HWIP][0] != IP_VERSION(13, 0, 2)) { 1993 ret = smu_v13_0_get_fine_grained_status(smu, 1994 clk_type, 1995 &single_dpm_table->is_fine_grained); 1996 if (ret) { 1997 dev_err(smu->adev->dev, "[%s] failed to get fine grained status!\n", __func__); 1998 return ret; 1999 } 2000 } 2001 2002 for (i = 0; i < single_dpm_table->count; i++) { 2003 ret = smu_v13_0_get_dpm_freq_by_index(smu, 2004 clk_type, 2005 i, 2006 &clk); 2007 if (ret) { 2008 dev_err(smu->adev->dev, "[%s] failed to get dpm freq by index!\n", __func__); 2009 return ret; 2010 } 2011 2012 single_dpm_table->dpm_levels[i].value = clk; 2013 single_dpm_table->dpm_levels[i].enabled = true; 2014 2015 if (i == 0) 2016 single_dpm_table->min = clk; 2017 else if (i == single_dpm_table->count - 1) 2018 single_dpm_table->max = clk; 2019 } 2020 2021 return 0; 2022} 2023 2024int smu_v13_0_get_current_pcie_link_width_level(struct smu_context *smu) 2025{ 2026 struct amdgpu_device *adev = smu->adev; 2027 2028 return (RREG32_PCIE(smnPCIE_LC_LINK_WIDTH_CNTL) & 2029 PCIE_LC_LINK_WIDTH_CNTL__LC_LINK_WIDTH_RD_MASK) 2030 >> PCIE_LC_LINK_WIDTH_CNTL__LC_LINK_WIDTH_RD__SHIFT; 2031} 2032 2033int smu_v13_0_get_current_pcie_link_width(struct smu_context *smu) 2034{ 2035 uint32_t width_level; 2036 2037 width_level = smu_v13_0_get_current_pcie_link_width_level(smu); 2038 if (width_level > LINK_WIDTH_MAX) 2039 width_level = 0; 2040 2041 return link_width[width_level]; 2042} 2043 2044int smu_v13_0_get_current_pcie_link_speed_level(struct smu_context *smu) 2045{ 2046 struct amdgpu_device *adev = smu->adev; 2047 2048 return (RREG32_PCIE(smnPCIE_LC_SPEED_CNTL) & 2049 PCIE_LC_SPEED_CNTL__LC_CURRENT_DATA_RATE_MASK) 2050 >> PCIE_LC_SPEED_CNTL__LC_CURRENT_DATA_RATE__SHIFT; 2051} 2052 2053int smu_v13_0_get_current_pcie_link_speed(struct smu_context *smu) 2054{ 2055 uint32_t speed_level; 2056 2057 speed_level = smu_v13_0_get_current_pcie_link_speed_level(smu); 2058 if (speed_level > LINK_SPEED_MAX) 2059 speed_level = 0; 2060 2061 return link_speed[speed_level]; 2062} 2063 2064int smu_v13_0_set_vcn_enable(struct smu_context *smu, 2065 bool enable) 2066{ 2067 struct amdgpu_device *adev = smu->adev; 2068 int i, ret = 0; 2069 2070 for (i = 0; i < adev->vcn.num_vcn_inst; i++) { 2071 if (adev->vcn.harvest_config & (1 << i)) 2072 continue; 2073 2074 ret = smu_cmn_send_smc_msg_with_param(smu, enable ? 2075 SMU_MSG_PowerUpVcn : SMU_MSG_PowerDownVcn, 2076 i << 16U, NULL); 2077 if (ret) 2078 return ret; 2079 } 2080 2081 return ret; 2082} 2083 2084int smu_v13_0_set_jpeg_enable(struct smu_context *smu, 2085 bool enable) 2086{ 2087 return smu_cmn_send_smc_msg_with_param(smu, enable ? 2088 SMU_MSG_PowerUpJpeg : SMU_MSG_PowerDownJpeg, 2089 0, NULL); 2090} 2091 2092int smu_v13_0_run_btc(struct smu_context *smu) 2093{ 2094 int res; 2095 2096 res = smu_cmn_send_smc_msg(smu, SMU_MSG_RunDcBtc, NULL); 2097 if (res) 2098 dev_err(smu->adev->dev, "RunDcBtc failed!\n"); 2099 2100 return res; 2101} 2102 2103int smu_v13_0_gpo_control(struct smu_context *smu, 2104 bool enablement) 2105{ 2106 int res; 2107 2108 res = smu_cmn_send_smc_msg_with_param(smu, 2109 SMU_MSG_AllowGpo, 2110 enablement ? 1 : 0, 2111 NULL); 2112 if (res) 2113 dev_err(smu->adev->dev, "SetGpoAllow %d failed!\n", enablement); 2114 2115 return res; 2116} 2117 2118int smu_v13_0_deep_sleep_control(struct smu_context *smu, 2119 bool enablement) 2120{ 2121 struct amdgpu_device *adev = smu->adev; 2122 int ret = 0; 2123 2124 if (smu_cmn_feature_is_supported(smu, SMU_FEATURE_DS_GFXCLK_BIT)) { 2125 ret = smu_cmn_feature_set_enabled(smu, SMU_FEATURE_DS_GFXCLK_BIT, enablement); 2126 if (ret) { 2127 dev_err(adev->dev, "Failed to %s GFXCLK DS!\n", enablement ? "enable" : "disable"); 2128 return ret; 2129 } 2130 } 2131 2132 if (smu_cmn_feature_is_supported(smu, SMU_FEATURE_DS_UCLK_BIT)) { 2133 ret = smu_cmn_feature_set_enabled(smu, SMU_FEATURE_DS_UCLK_BIT, enablement); 2134 if (ret) { 2135 dev_err(adev->dev, "Failed to %s UCLK DS!\n", enablement ? "enable" : "disable"); 2136 return ret; 2137 } 2138 } 2139 2140 if (smu_cmn_feature_is_supported(smu, SMU_FEATURE_DS_FCLK_BIT)) { 2141 ret = smu_cmn_feature_set_enabled(smu, SMU_FEATURE_DS_FCLK_BIT, enablement); 2142 if (ret) { 2143 dev_err(adev->dev, "Failed to %s FCLK DS!\n", enablement ? "enable" : "disable"); 2144 return ret; 2145 } 2146 } 2147 2148 if (smu_cmn_feature_is_supported(smu, SMU_FEATURE_DS_SOCCLK_BIT)) { 2149 ret = smu_cmn_feature_set_enabled(smu, SMU_FEATURE_DS_SOCCLK_BIT, enablement); 2150 if (ret) { 2151 dev_err(adev->dev, "Failed to %s SOCCLK DS!\n", enablement ? "enable" : "disable"); 2152 return ret; 2153 } 2154 } 2155 2156 if (smu_cmn_feature_is_supported(smu, SMU_FEATURE_DS_LCLK_BIT)) { 2157 ret = smu_cmn_feature_set_enabled(smu, SMU_FEATURE_DS_LCLK_BIT, enablement); 2158 if (ret) { 2159 dev_err(adev->dev, "Failed to %s LCLK DS!\n", enablement ? "enable" : "disable"); 2160 return ret; 2161 } 2162 } 2163 2164 if (smu_cmn_feature_is_supported(smu, SMU_FEATURE_DS_VCN_BIT)) { 2165 ret = smu_cmn_feature_set_enabled(smu, SMU_FEATURE_DS_VCN_BIT, enablement); 2166 if (ret) { 2167 dev_err(adev->dev, "Failed to %s VCN DS!\n", enablement ? "enable" : "disable"); 2168 return ret; 2169 } 2170 } 2171 2172 if (smu_cmn_feature_is_supported(smu, SMU_FEATURE_DS_MP0CLK_BIT)) { 2173 ret = smu_cmn_feature_set_enabled(smu, SMU_FEATURE_DS_MP0CLK_BIT, enablement); 2174 if (ret) { 2175 dev_err(adev->dev, "Failed to %s MP0/MPIOCLK DS!\n", enablement ? "enable" : "disable"); 2176 return ret; 2177 } 2178 } 2179 2180 if (smu_cmn_feature_is_supported(smu, SMU_FEATURE_DS_MP1CLK_BIT)) { 2181 ret = smu_cmn_feature_set_enabled(smu, SMU_FEATURE_DS_MP1CLK_BIT, enablement); 2182 if (ret) { 2183 dev_err(adev->dev, "Failed to %s MP1CLK DS!\n", enablement ? "enable" : "disable"); 2184 return ret; 2185 } 2186 } 2187 2188 return ret; 2189} 2190 2191int smu_v13_0_gfx_ulv_control(struct smu_context *smu, 2192 bool enablement) 2193{ 2194 int ret = 0; 2195 2196 if (smu_cmn_feature_is_supported(smu, SMU_FEATURE_GFX_ULV_BIT)) 2197 ret = smu_cmn_feature_set_enabled(smu, SMU_FEATURE_GFX_ULV_BIT, enablement); 2198 2199 return ret; 2200} 2201 2202int smu_v13_0_baco_set_armd3_sequence(struct smu_context *smu, 2203 enum smu_baco_seq baco_seq) 2204{ 2205 struct smu_baco_context *smu_baco = &smu->smu_baco; 2206 int ret; 2207 2208 ret = smu_cmn_send_smc_msg_with_param(smu, 2209 SMU_MSG_ArmD3, 2210 baco_seq, 2211 NULL); 2212 if (ret) 2213 return ret; 2214 2215 if (baco_seq == BACO_SEQ_BAMACO || 2216 baco_seq == BACO_SEQ_BACO) 2217 smu_baco->state = SMU_BACO_STATE_ENTER; 2218 else 2219 smu_baco->state = SMU_BACO_STATE_EXIT; 2220 2221 return 0; 2222} 2223 2224bool smu_v13_0_baco_is_support(struct smu_context *smu) 2225{ 2226 struct smu_baco_context *smu_baco = &smu->smu_baco; 2227 2228 if (amdgpu_sriov_vf(smu->adev) || 2229 !smu_baco->platform_support) 2230 return false; 2231 2232 /* return true if ASIC is in BACO state already */ 2233 if (smu_v13_0_baco_get_state(smu) == SMU_BACO_STATE_ENTER) 2234 return true; 2235 2236 if (smu_cmn_feature_is_supported(smu, SMU_FEATURE_BACO_BIT) && 2237 !smu_cmn_feature_is_enabled(smu, SMU_FEATURE_BACO_BIT)) 2238 return false; 2239 2240 return true; 2241} 2242 2243enum smu_baco_state smu_v13_0_baco_get_state(struct smu_context *smu) 2244{ 2245 struct smu_baco_context *smu_baco = &smu->smu_baco; 2246 2247 return smu_baco->state; 2248} 2249 2250int smu_v13_0_baco_set_state(struct smu_context *smu, 2251 enum smu_baco_state state) 2252{ 2253 struct smu_baco_context *smu_baco = &smu->smu_baco; 2254 struct amdgpu_device *adev = smu->adev; 2255 int ret = 0; 2256 2257 if (smu_v13_0_baco_get_state(smu) == state) 2258 return 0; 2259 2260 if (state == SMU_BACO_STATE_ENTER) { 2261 ret = smu_cmn_send_smc_msg_with_param(smu, 2262 SMU_MSG_EnterBaco, 2263 (smu_baco->maco_support && amdgpu_runtime_pm != 1) ? 2264 BACO_SEQ_BAMACO : BACO_SEQ_BACO, 2265 NULL); 2266 } else { 2267 ret = smu_cmn_send_smc_msg(smu, 2268 SMU_MSG_ExitBaco, 2269 NULL); 2270 if (ret) 2271 return ret; 2272 2273 /* clear vbios scratch 6 and 7 for coming asic reinit */ 2274 WREG32(adev->bios_scratch_reg_offset + 6, 0); 2275 WREG32(adev->bios_scratch_reg_offset + 7, 0); 2276 } 2277 2278 if (!ret) 2279 smu_baco->state = state; 2280 2281 return ret; 2282} 2283 2284int smu_v13_0_baco_enter(struct smu_context *smu) 2285{ 2286 int ret = 0; 2287 2288 ret = smu_v13_0_baco_set_state(smu, 2289 SMU_BACO_STATE_ENTER); 2290 if (ret) 2291 return ret; 2292 2293 drm_msleep(10); 2294 2295 return ret; 2296} 2297 2298int smu_v13_0_baco_exit(struct smu_context *smu) 2299{ 2300 return smu_v13_0_baco_set_state(smu, 2301 SMU_BACO_STATE_EXIT); 2302} 2303 2304int smu_v13_0_set_gfx_power_up_by_imu(struct smu_context *smu) 2305{ 2306 uint16_t index; 2307 2308 index = smu_cmn_to_asic_specific_index(smu, CMN2ASIC_MAPPING_MSG, 2309 SMU_MSG_EnableGfxImu); 2310 /* Param 1 to tell PMFW to enable GFXOFF feature */ 2311 return smu_cmn_send_msg_without_waiting(smu, index, 1); 2312} 2313 2314int smu_v13_0_od_edit_dpm_table(struct smu_context *smu, 2315 enum PP_OD_DPM_TABLE_COMMAND type, 2316 long input[], uint32_t size) 2317{ 2318 struct smu_dpm_context *smu_dpm = &(smu->smu_dpm); 2319 int ret = 0; 2320 2321 /* Only allowed in manual mode */ 2322 if (smu_dpm->dpm_level != AMD_DPM_FORCED_LEVEL_MANUAL) 2323 return -EINVAL; 2324 2325 switch (type) { 2326 case PP_OD_EDIT_SCLK_VDDC_TABLE: 2327 if (size != 2) { 2328 dev_err(smu->adev->dev, "Input parameter number not correct\n"); 2329 return -EINVAL; 2330 } 2331 2332 if (input[0] == 0) { 2333 if (input[1] < smu->gfx_default_hard_min_freq) { 2334 dev_warn(smu->adev->dev, 2335 "Fine grain setting minimum sclk (%ld) MHz is less than the minimum allowed (%d) MHz\n", 2336 input[1], smu->gfx_default_hard_min_freq); 2337 return -EINVAL; 2338 } 2339 smu->gfx_actual_hard_min_freq = input[1]; 2340 } else if (input[0] == 1) { 2341 if (input[1] > smu->gfx_default_soft_max_freq) { 2342 dev_warn(smu->adev->dev, 2343 "Fine grain setting maximum sclk (%ld) MHz is greater than the maximum allowed (%d) MHz\n", 2344 input[1], smu->gfx_default_soft_max_freq); 2345 return -EINVAL; 2346 } 2347 smu->gfx_actual_soft_max_freq = input[1]; 2348 } else { 2349 return -EINVAL; 2350 } 2351 break; 2352 case PP_OD_RESTORE_DEFAULT_TABLE: 2353 if (size != 0) { 2354 dev_err(smu->adev->dev, "Input parameter number not correct\n"); 2355 return -EINVAL; 2356 } 2357 smu->gfx_actual_hard_min_freq = smu->gfx_default_hard_min_freq; 2358 smu->gfx_actual_soft_max_freq = smu->gfx_default_soft_max_freq; 2359 break; 2360 case PP_OD_COMMIT_DPM_TABLE: 2361 if (size != 0) { 2362 dev_err(smu->adev->dev, "Input parameter number not correct\n"); 2363 return -EINVAL; 2364 } 2365 if (smu->gfx_actual_hard_min_freq > smu->gfx_actual_soft_max_freq) { 2366 dev_err(smu->adev->dev, 2367 "The setting minimum sclk (%d) MHz is greater than the setting maximum sclk (%d) MHz\n", 2368 smu->gfx_actual_hard_min_freq, 2369 smu->gfx_actual_soft_max_freq); 2370 return -EINVAL; 2371 } 2372 2373 ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetHardMinGfxClk, 2374 smu->gfx_actual_hard_min_freq, 2375 NULL); 2376 if (ret) { 2377 dev_err(smu->adev->dev, "Set hard min sclk failed!"); 2378 return ret; 2379 } 2380 2381 ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetSoftMaxGfxClk, 2382 smu->gfx_actual_soft_max_freq, 2383 NULL); 2384 if (ret) { 2385 dev_err(smu->adev->dev, "Set soft max sclk failed!"); 2386 return ret; 2387 } 2388 break; 2389 default: 2390 return -ENOSYS; 2391 } 2392 2393 return ret; 2394} 2395 2396int smu_v13_0_set_default_dpm_tables(struct smu_context *smu) 2397{ 2398 struct smu_table_context *smu_table = &smu->smu_table; 2399 2400 return smu_cmn_update_table(smu, SMU_TABLE_DPMCLOCKS, 0, 2401 smu_table->clocks_table, false); 2402} 2403 2404void smu_v13_0_set_smu_mailbox_registers(struct smu_context *smu) 2405{ 2406 struct amdgpu_device *adev = smu->adev; 2407 2408 smu->param_reg = SOC15_REG_OFFSET(MP1, 0, mmMP1_SMN_C2PMSG_82); 2409 smu->msg_reg = SOC15_REG_OFFSET(MP1, 0, mmMP1_SMN_C2PMSG_66); 2410 smu->resp_reg = SOC15_REG_OFFSET(MP1, 0, mmMP1_SMN_C2PMSG_90); 2411} 2412 2413int smu_v13_0_mode1_reset(struct smu_context *smu) 2414{ 2415 int ret = 0; 2416 2417 ret = smu_cmn_send_smc_msg(smu, SMU_MSG_Mode1Reset, NULL); 2418 if (!ret) 2419 drm_msleep(SMU13_MODE1_RESET_WAIT_TIME_IN_MS); 2420 2421 return ret; 2422} 2423 2424int smu_v13_0_update_pcie_parameters(struct smu_context *smu, 2425 uint8_t pcie_gen_cap, 2426 uint8_t pcie_width_cap) 2427{ 2428 struct smu_13_0_dpm_context *dpm_context = smu->smu_dpm.dpm_context; 2429 struct smu_13_0_pcie_table *pcie_table = 2430 &dpm_context->dpm_tables.pcie_table; 2431 int num_of_levels = pcie_table->num_of_link_levels; 2432 uint32_t smu_pcie_arg; 2433 int ret, i; 2434 2435 if (!num_of_levels) 2436 return 0; 2437 2438 if (!(smu->adev->pm.pp_feature & PP_PCIE_DPM_MASK)) { 2439 if (pcie_table->pcie_gen[num_of_levels - 1] < pcie_gen_cap) 2440 pcie_gen_cap = pcie_table->pcie_gen[num_of_levels - 1]; 2441 2442 if (pcie_table->pcie_lane[num_of_levels - 1] < pcie_width_cap) 2443 pcie_width_cap = pcie_table->pcie_lane[num_of_levels - 1]; 2444 2445 /* Force all levels to use the same settings */ 2446 for (i = 0; i < num_of_levels; i++) { 2447 pcie_table->pcie_gen[i] = pcie_gen_cap; 2448 pcie_table->pcie_lane[i] = pcie_width_cap; 2449 } 2450 } else { 2451 for (i = 0; i < num_of_levels; i++) { 2452 if (pcie_table->pcie_gen[i] > pcie_gen_cap) 2453 pcie_table->pcie_gen[i] = pcie_gen_cap; 2454 if (pcie_table->pcie_lane[i] > pcie_width_cap) 2455 pcie_table->pcie_lane[i] = pcie_width_cap; 2456 } 2457 } 2458 2459 for (i = 0; i < num_of_levels; i++) { 2460 smu_pcie_arg = i << 16; 2461 smu_pcie_arg |= pcie_table->pcie_gen[i] << 8; 2462 smu_pcie_arg |= pcie_table->pcie_lane[i]; 2463 2464 ret = smu_cmn_send_smc_msg_with_param(smu, 2465 SMU_MSG_OverridePcieParameters, 2466 smu_pcie_arg, 2467 NULL); 2468 if (ret) 2469 return ret; 2470 } 2471 2472 return 0; 2473} 2474