1 /* 2 * Copyright 2015 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 25 #include "pp_debug.h" 26 #include "smumgr.h" 27 #include "smu_ucode_xfer_vi.h" 28 #include "ppatomctrl.h" 29 #include "cgs_common.h" 30 #include "smu7_ppsmc.h" 31 #include "smu7_smumgr.h" 32 #include "smu7_common.h" 33 34 #include "polaris10_pwrvirus.h" 35 36 #define SMU7_SMC_SIZE 0x20000 37 38 static int smu7_set_smc_sram_address(struct pp_hwmgr *hwmgr, uint32_t smc_addr, uint32_t limit) 39 { 40 PP_ASSERT_WITH_CODE((0 == (3 & smc_addr)), "SMC address must be 4 byte aligned.", return -EINVAL); 41 PP_ASSERT_WITH_CODE((limit > (smc_addr + 3)), "SMC addr is beyond the SMC RAM area.", return -EINVAL); 42 43 cgs_write_register(hwmgr->device, mmSMC_IND_INDEX_11, smc_addr); 44 PHM_WRITE_FIELD(hwmgr->device, SMC_IND_ACCESS_CNTL, AUTO_INCREMENT_IND_11, 0); /* on ci, SMC_IND_ACCESS_CNTL is different */ 45 return 0; 46 } 47 48 49 int smu7_copy_bytes_from_smc(struct pp_hwmgr *hwmgr, uint32_t smc_start_address, uint32_t *dest, uint32_t byte_count, uint32_t limit) 50 { 51 uint32_t data; 52 uint32_t addr; 53 uint8_t *dest_byte; 54 uint8_t i, data_byte[4] = {0}; 55 uint32_t *pdata = (uint32_t *)&data_byte; 56 57 PP_ASSERT_WITH_CODE((0 == (3 & smc_start_address)), "SMC address must be 4 byte aligned.", return -EINVAL); 58 PP_ASSERT_WITH_CODE((limit > (smc_start_address + byte_count)), "SMC address is beyond the SMC RAM area.", return -EINVAL); 59 60 addr = smc_start_address; 61 62 while (byte_count >= 4) { 63 smu7_read_smc_sram_dword(hwmgr, addr, &data, limit); 64 65 *dest = PP_SMC_TO_HOST_UL(data); 66 67 dest += 1; 68 byte_count -= 4; 69 addr += 4; 70 } 71 72 if (byte_count) { 73 smu7_read_smc_sram_dword(hwmgr, addr, &data, limit); 74 *pdata = PP_SMC_TO_HOST_UL(data); 75 /* Cast dest into byte type in dest_byte. This way, we don't overflow if the allocated memory is not 4-byte aligned. */ 76 dest_byte = (uint8_t *)dest; 77 for (i = 0; i < byte_count; i++) 78 dest_byte[i] = data_byte[i]; 79 } 80 81 return 0; 82 } 83 84 85 int smu7_copy_bytes_to_smc(struct pp_hwmgr *hwmgr, uint32_t smc_start_address, 86 const uint8_t *src, uint32_t byte_count, uint32_t limit) 87 { 88 int result; 89 uint32_t data = 0; 90 uint32_t original_data; 91 uint32_t addr = 0; 92 uint32_t extra_shift; 93 94 PP_ASSERT_WITH_CODE((0 == (3 & smc_start_address)), "SMC address must be 4 byte aligned.", return -EINVAL); 95 PP_ASSERT_WITH_CODE((limit > (smc_start_address + byte_count)), "SMC address is beyond the SMC RAM area.", return -EINVAL); 96 97 addr = smc_start_address; 98 99 while (byte_count >= 4) { 100 /* Bytes are written into the SMC addres space with the MSB first. */ 101 data = src[0] * 0x1000000 + src[1] * 0x10000 + src[2] * 0x100 + src[3]; 102 103 result = smu7_set_smc_sram_address(hwmgr, addr, limit); 104 105 if (0 != result) 106 return result; 107 108 cgs_write_register(hwmgr->device, mmSMC_IND_DATA_11, data); 109 110 src += 4; 111 byte_count -= 4; 112 addr += 4; 113 } 114 115 if (0 != byte_count) { 116 117 data = 0; 118 119 result = smu7_set_smc_sram_address(hwmgr, addr, limit); 120 121 if (0 != result) 122 return result; 123 124 125 original_data = cgs_read_register(hwmgr->device, mmSMC_IND_DATA_11); 126 127 extra_shift = 8 * (4 - byte_count); 128 129 while (byte_count > 0) { 130 /* Bytes are written into the SMC addres space with the MSB first. */ 131 data = (0x100 * data) + *src++; 132 byte_count--; 133 } 134 135 data <<= extra_shift; 136 137 data |= (original_data & ~((~0UL) << extra_shift)); 138 139 result = smu7_set_smc_sram_address(hwmgr, addr, limit); 140 141 if (0 != result) 142 return result; 143 144 cgs_write_register(hwmgr->device, mmSMC_IND_DATA_11, data); 145 } 146 147 return 0; 148 } 149 150 151 int smu7_program_jump_on_start(struct pp_hwmgr *hwmgr) 152 { 153 static const unsigned char data[4] = { 0xE0, 0x00, 0x80, 0x40 }; 154 155 smu7_copy_bytes_to_smc(hwmgr, 0x0, data, 4, sizeof(data)+1); 156 157 return 0; 158 } 159 160 bool smu7_is_smc_ram_running(struct pp_hwmgr *hwmgr) 161 { 162 return ((0 == PHM_READ_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, SMC_SYSCON_CLOCK_CNTL_0, ck_disable)) 163 && (0x20100 <= cgs_read_ind_register(hwmgr->device, CGS_IND_REG__SMC, ixSMC_PC_C))); 164 } 165 166 int smu7_send_msg_to_smc(struct pp_hwmgr *hwmgr, uint16_t msg) 167 { 168 int ret; 169 170 PHM_WAIT_FIELD_UNEQUAL(hwmgr, SMC_RESP_0, SMC_RESP, 0); 171 172 ret = PHM_READ_FIELD(hwmgr->device, SMC_RESP_0, SMC_RESP); 173 174 if (ret == 0xFE) 175 pr_debug("last message was not supported\n"); 176 else if (ret != 1) 177 pr_info("\n last message was failed ret is %d\n", ret); 178 179 cgs_write_register(hwmgr->device, mmSMC_RESP_0, 0); 180 cgs_write_register(hwmgr->device, mmSMC_MESSAGE_0, msg); 181 182 PHM_WAIT_FIELD_UNEQUAL(hwmgr, SMC_RESP_0, SMC_RESP, 0); 183 184 ret = PHM_READ_FIELD(hwmgr->device, SMC_RESP_0, SMC_RESP); 185 186 if (ret == 0xFE) 187 pr_debug("message %x was not supported\n", msg); 188 else if (ret != 1) 189 pr_info("\n failed to send message %x ret is %d \n", msg, ret); 190 191 return 0; 192 } 193 194 int smu7_send_msg_to_smc_without_waiting(struct pp_hwmgr *hwmgr, uint16_t msg) 195 { 196 cgs_write_register(hwmgr->device, mmSMC_MESSAGE_0, msg); 197 198 return 0; 199 } 200 201 int smu7_send_msg_to_smc_with_parameter(struct pp_hwmgr *hwmgr, uint16_t msg, uint32_t parameter) 202 { 203 PHM_WAIT_FIELD_UNEQUAL(hwmgr, SMC_RESP_0, SMC_RESP, 0); 204 205 cgs_write_register(hwmgr->device, mmSMC_MSG_ARG_0, parameter); 206 207 return smu7_send_msg_to_smc(hwmgr, msg); 208 } 209 210 int smu7_send_msg_to_smc_with_parameter_without_waiting(struct pp_hwmgr *hwmgr, uint16_t msg, uint32_t parameter) 211 { 212 cgs_write_register(hwmgr->device, mmSMC_MSG_ARG_0, parameter); 213 214 return smu7_send_msg_to_smc_without_waiting(hwmgr, msg); 215 } 216 217 int smu7_send_msg_to_smc_offset(struct pp_hwmgr *hwmgr) 218 { 219 cgs_write_register(hwmgr->device, mmSMC_MSG_ARG_0, 0x20000); 220 221 cgs_write_register(hwmgr->device, mmSMC_MESSAGE_0, PPSMC_MSG_Test); 222 223 PHM_WAIT_FIELD_UNEQUAL(hwmgr, SMC_RESP_0, SMC_RESP, 0); 224 225 if (1 != PHM_READ_FIELD(hwmgr->device, SMC_RESP_0, SMC_RESP)) 226 pr_info("Failed to send Message.\n"); 227 228 return 0; 229 } 230 231 enum cgs_ucode_id smu7_convert_fw_type_to_cgs(uint32_t fw_type) 232 { 233 enum cgs_ucode_id result = CGS_UCODE_ID_MAXIMUM; 234 235 switch (fw_type) { 236 case UCODE_ID_SMU: 237 result = CGS_UCODE_ID_SMU; 238 break; 239 case UCODE_ID_SMU_SK: 240 result = CGS_UCODE_ID_SMU_SK; 241 break; 242 case UCODE_ID_SDMA0: 243 result = CGS_UCODE_ID_SDMA0; 244 break; 245 case UCODE_ID_SDMA1: 246 result = CGS_UCODE_ID_SDMA1; 247 break; 248 case UCODE_ID_CP_CE: 249 result = CGS_UCODE_ID_CP_CE; 250 break; 251 case UCODE_ID_CP_PFP: 252 result = CGS_UCODE_ID_CP_PFP; 253 break; 254 case UCODE_ID_CP_ME: 255 result = CGS_UCODE_ID_CP_ME; 256 break; 257 case UCODE_ID_CP_MEC: 258 result = CGS_UCODE_ID_CP_MEC; 259 break; 260 case UCODE_ID_CP_MEC_JT1: 261 result = CGS_UCODE_ID_CP_MEC_JT1; 262 break; 263 case UCODE_ID_CP_MEC_JT2: 264 result = CGS_UCODE_ID_CP_MEC_JT2; 265 break; 266 case UCODE_ID_RLC_G: 267 result = CGS_UCODE_ID_RLC_G; 268 break; 269 case UCODE_ID_MEC_STORAGE: 270 result = CGS_UCODE_ID_STORAGE; 271 break; 272 default: 273 break; 274 } 275 276 return result; 277 } 278 279 280 int smu7_read_smc_sram_dword(struct pp_hwmgr *hwmgr, uint32_t smc_addr, uint32_t *value, uint32_t limit) 281 { 282 int result; 283 284 result = smu7_set_smc_sram_address(hwmgr, smc_addr, limit); 285 286 *value = result ? 0 : cgs_read_register(hwmgr->device, mmSMC_IND_DATA_11); 287 288 return result; 289 } 290 291 int smu7_write_smc_sram_dword(struct pp_hwmgr *hwmgr, uint32_t smc_addr, uint32_t value, uint32_t limit) 292 { 293 int result; 294 295 result = smu7_set_smc_sram_address(hwmgr, smc_addr, limit); 296 297 if (result) 298 return result; 299 300 cgs_write_register(hwmgr->device, mmSMC_IND_DATA_11, value); 301 302 return 0; 303 } 304 305 /* Convert the firmware type to SMU type mask. For MEC, we need to check all MEC related type */ 306 307 static uint32_t smu7_get_mask_for_firmware_type(uint32_t fw_type) 308 { 309 uint32_t result = 0; 310 311 switch (fw_type) { 312 case UCODE_ID_SDMA0: 313 result = UCODE_ID_SDMA0_MASK; 314 break; 315 case UCODE_ID_SDMA1: 316 result = UCODE_ID_SDMA1_MASK; 317 break; 318 case UCODE_ID_CP_CE: 319 result = UCODE_ID_CP_CE_MASK; 320 break; 321 case UCODE_ID_CP_PFP: 322 result = UCODE_ID_CP_PFP_MASK; 323 break; 324 case UCODE_ID_CP_ME: 325 result = UCODE_ID_CP_ME_MASK; 326 break; 327 case UCODE_ID_CP_MEC: 328 case UCODE_ID_CP_MEC_JT1: 329 case UCODE_ID_CP_MEC_JT2: 330 result = UCODE_ID_CP_MEC_MASK; 331 break; 332 case UCODE_ID_RLC_G: 333 result = UCODE_ID_RLC_G_MASK; 334 break; 335 default: 336 pr_info("UCode type is out of range! \n"); 337 result = 0; 338 } 339 340 return result; 341 } 342 343 static int smu7_populate_single_firmware_entry(struct pp_hwmgr *hwmgr, 344 uint32_t fw_type, 345 struct SMU_Entry *entry) 346 { 347 int result = 0; 348 struct cgs_firmware_info info = {0}; 349 350 result = cgs_get_firmware_info(hwmgr->device, 351 smu7_convert_fw_type_to_cgs(fw_type), 352 &info); 353 354 if (!result) { 355 entry->version = info.fw_version; 356 entry->id = (uint16_t)fw_type; 357 entry->image_addr_high = upper_32_bits(info.mc_addr); 358 entry->image_addr_low = lower_32_bits(info.mc_addr); 359 entry->meta_data_addr_high = 0; 360 entry->meta_data_addr_low = 0; 361 362 /* digest need be excluded out */ 363 if (!hwmgr->not_vf) 364 info.image_size -= 20; 365 entry->data_size_byte = info.image_size; 366 entry->num_register_entries = 0; 367 } 368 369 if ((fw_type == UCODE_ID_RLC_G) 370 || (fw_type == UCODE_ID_CP_MEC)) 371 entry->flags = 1; 372 else 373 entry->flags = 0; 374 375 return 0; 376 } 377 378 int smu7_request_smu_load_fw(struct pp_hwmgr *hwmgr) 379 { 380 struct smu7_smumgr *smu_data = (struct smu7_smumgr *)(hwmgr->smu_backend); 381 uint32_t fw_to_load; 382 int r = 0; 383 384 if (!hwmgr->reload_fw) { 385 pr_info("skip reloading...\n"); 386 return 0; 387 } 388 389 if (smu_data->soft_regs_start) 390 cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, 391 smu_data->soft_regs_start + smum_get_offsetof(hwmgr, 392 SMU_SoftRegisters, UcodeLoadStatus), 393 0x0); 394 395 if (hwmgr->chip_id > CHIP_TOPAZ) { /* add support for Topaz */ 396 if (hwmgr->not_vf) { 397 smu7_send_msg_to_smc_with_parameter(hwmgr, 398 PPSMC_MSG_SMU_DRAM_ADDR_HI, 399 upper_32_bits(smu_data->smu_buffer.mc_addr)); 400 smu7_send_msg_to_smc_with_parameter(hwmgr, 401 PPSMC_MSG_SMU_DRAM_ADDR_LO, 402 lower_32_bits(smu_data->smu_buffer.mc_addr)); 403 } 404 fw_to_load = UCODE_ID_RLC_G_MASK 405 + UCODE_ID_SDMA0_MASK 406 + UCODE_ID_SDMA1_MASK 407 + UCODE_ID_CP_CE_MASK 408 + UCODE_ID_CP_ME_MASK 409 + UCODE_ID_CP_PFP_MASK 410 + UCODE_ID_CP_MEC_MASK; 411 } else { 412 fw_to_load = UCODE_ID_RLC_G_MASK 413 + UCODE_ID_SDMA0_MASK 414 + UCODE_ID_SDMA1_MASK 415 + UCODE_ID_CP_CE_MASK 416 + UCODE_ID_CP_ME_MASK 417 + UCODE_ID_CP_PFP_MASK 418 + UCODE_ID_CP_MEC_MASK 419 + UCODE_ID_CP_MEC_JT1_MASK 420 + UCODE_ID_CP_MEC_JT2_MASK; 421 } 422 423 if (!smu_data->toc) { 424 struct SMU_DRAMData_TOC *toc; 425 426 smu_data->toc = kzalloc(sizeof(struct SMU_DRAMData_TOC), GFP_KERNEL); 427 if (!smu_data->toc) 428 return -ENOMEM; 429 toc = smu_data->toc; 430 toc->num_entries = 0; 431 toc->structure_version = 1; 432 433 PP_ASSERT_WITH_CODE(0 == smu7_populate_single_firmware_entry(hwmgr, 434 UCODE_ID_RLC_G, &toc->entry[toc->num_entries++]), 435 "Failed to Get Firmware Entry.", r = -EINVAL; goto failed); 436 PP_ASSERT_WITH_CODE(0 == smu7_populate_single_firmware_entry(hwmgr, 437 UCODE_ID_CP_CE, &toc->entry[toc->num_entries++]), 438 "Failed to Get Firmware Entry.", r = -EINVAL; goto failed); 439 PP_ASSERT_WITH_CODE(0 == smu7_populate_single_firmware_entry(hwmgr, 440 UCODE_ID_CP_PFP, &toc->entry[toc->num_entries++]), 441 "Failed to Get Firmware Entry.", r = -EINVAL; goto failed); 442 PP_ASSERT_WITH_CODE(0 == smu7_populate_single_firmware_entry(hwmgr, 443 UCODE_ID_CP_ME, &toc->entry[toc->num_entries++]), 444 "Failed to Get Firmware Entry.", r = -EINVAL; goto failed); 445 PP_ASSERT_WITH_CODE(0 == smu7_populate_single_firmware_entry(hwmgr, 446 UCODE_ID_CP_MEC, &toc->entry[toc->num_entries++]), 447 "Failed to Get Firmware Entry.", r = -EINVAL; goto failed); 448 PP_ASSERT_WITH_CODE(0 == smu7_populate_single_firmware_entry(hwmgr, 449 UCODE_ID_CP_MEC_JT1, &toc->entry[toc->num_entries++]), 450 "Failed to Get Firmware Entry.", r = -EINVAL; goto failed); 451 PP_ASSERT_WITH_CODE(0 == smu7_populate_single_firmware_entry(hwmgr, 452 UCODE_ID_CP_MEC_JT2, &toc->entry[toc->num_entries++]), 453 "Failed to Get Firmware Entry.", r = -EINVAL; goto failed); 454 PP_ASSERT_WITH_CODE(0 == smu7_populate_single_firmware_entry(hwmgr, 455 UCODE_ID_SDMA0, &toc->entry[toc->num_entries++]), 456 "Failed to Get Firmware Entry.", r = -EINVAL; goto failed); 457 PP_ASSERT_WITH_CODE(0 == smu7_populate_single_firmware_entry(hwmgr, 458 UCODE_ID_SDMA1, &toc->entry[toc->num_entries++]), 459 "Failed to Get Firmware Entry.", r = -EINVAL; goto failed); 460 if (!hwmgr->not_vf) 461 PP_ASSERT_WITH_CODE(0 == smu7_populate_single_firmware_entry(hwmgr, 462 UCODE_ID_MEC_STORAGE, &toc->entry[toc->num_entries++]), 463 "Failed to Get Firmware Entry.", r = -EINVAL; goto failed); 464 } 465 memcpy_toio(smu_data->header_buffer.kaddr, smu_data->toc, 466 sizeof(struct SMU_DRAMData_TOC)); 467 smu7_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_DRV_DRAM_ADDR_HI, upper_32_bits(smu_data->header_buffer.mc_addr)); 468 smu7_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_DRV_DRAM_ADDR_LO, lower_32_bits(smu_data->header_buffer.mc_addr)); 469 470 if (smu7_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_LoadUcodes, fw_to_load)) 471 pr_err("Fail to Request SMU Load uCode"); 472 473 return r; 474 475 failed: 476 kfree(smu_data->toc); 477 smu_data->toc = NULL; 478 return r; 479 } 480 481 /* Check if the FW has been loaded, SMU will not return if loading has not finished. */ 482 int smu7_check_fw_load_finish(struct pp_hwmgr *hwmgr, uint32_t fw_type) 483 { 484 struct smu7_smumgr *smu_data = (struct smu7_smumgr *)(hwmgr->smu_backend); 485 uint32_t fw_mask = smu7_get_mask_for_firmware_type(fw_type); 486 uint32_t ret; 487 488 ret = phm_wait_on_indirect_register(hwmgr, mmSMC_IND_INDEX_11, 489 smu_data->soft_regs_start + smum_get_offsetof(hwmgr, 490 SMU_SoftRegisters, UcodeLoadStatus), 491 fw_mask, fw_mask); 492 return ret; 493 } 494 495 int smu7_reload_firmware(struct pp_hwmgr *hwmgr) 496 { 497 return hwmgr->smumgr_funcs->start_smu(hwmgr); 498 } 499 500 static int smu7_upload_smc_firmware_data(struct pp_hwmgr *hwmgr, uint32_t length, uint32_t *src, uint32_t limit) 501 { 502 uint32_t byte_count = length; 503 504 PP_ASSERT_WITH_CODE((limit >= byte_count), "SMC address is beyond the SMC RAM area.", return -EINVAL); 505 506 cgs_write_register(hwmgr->device, mmSMC_IND_INDEX_11, 0x20000); 507 PHM_WRITE_FIELD(hwmgr->device, SMC_IND_ACCESS_CNTL, AUTO_INCREMENT_IND_11, 1); 508 509 for (; byte_count >= 4; byte_count -= 4) 510 cgs_write_register(hwmgr->device, mmSMC_IND_DATA_11, *src++); 511 512 PHM_WRITE_FIELD(hwmgr->device, SMC_IND_ACCESS_CNTL, AUTO_INCREMENT_IND_11, 0); 513 514 PP_ASSERT_WITH_CODE((0 == byte_count), "SMC size must be divisible by 4.", return -EINVAL); 515 516 return 0; 517 } 518 519 520 int smu7_upload_smu_firmware_image(struct pp_hwmgr *hwmgr) 521 { 522 int result = 0; 523 struct smu7_smumgr *smu_data = (struct smu7_smumgr *)(hwmgr->smu_backend); 524 525 struct cgs_firmware_info info = {0}; 526 527 if (smu_data->security_hard_key == 1) 528 cgs_get_firmware_info(hwmgr->device, 529 smu7_convert_fw_type_to_cgs(UCODE_ID_SMU), &info); 530 else 531 cgs_get_firmware_info(hwmgr->device, 532 smu7_convert_fw_type_to_cgs(UCODE_ID_SMU_SK), &info); 533 534 hwmgr->is_kicker = info.is_kicker; 535 hwmgr->smu_version = info.version; 536 result = smu7_upload_smc_firmware_data(hwmgr, info.image_size, (uint32_t *)info.kptr, SMU7_SMC_SIZE); 537 538 return result; 539 } 540 541 static void execute_pwr_table(struct pp_hwmgr *hwmgr, const PWR_Command_Table *pvirus, int size) 542 { 543 int i; 544 uint32_t reg, data; 545 546 for (i = 0; i < size; i++) { 547 reg = pvirus->reg; 548 data = pvirus->data; 549 if (reg != 0xffffffff) 550 cgs_write_register(hwmgr->device, reg, data); 551 else 552 break; 553 pvirus++; 554 } 555 } 556 557 static void execute_pwr_dfy_table(struct pp_hwmgr *hwmgr, const PWR_DFY_Section *section) 558 { 559 int i; 560 561 cgs_write_register(hwmgr->device, mmCP_DFY_CNTL, section->dfy_cntl); 562 cgs_write_register(hwmgr->device, mmCP_DFY_ADDR_HI, section->dfy_addr_hi); 563 cgs_write_register(hwmgr->device, mmCP_DFY_ADDR_LO, section->dfy_addr_lo); 564 for (i = 0; i < section->dfy_size; i++) 565 cgs_write_register(hwmgr->device, mmCP_DFY_DATA_0, section->dfy_data[i]); 566 } 567 568 int smu7_setup_pwr_virus(struct pp_hwmgr *hwmgr) 569 { 570 execute_pwr_table(hwmgr, pwr_virus_table_pre, ARRAY_SIZE(pwr_virus_table_pre)); 571 execute_pwr_dfy_table(hwmgr, &pwr_virus_section1); 572 execute_pwr_dfy_table(hwmgr, &pwr_virus_section2); 573 execute_pwr_dfy_table(hwmgr, &pwr_virus_section3); 574 execute_pwr_dfy_table(hwmgr, &pwr_virus_section4); 575 execute_pwr_dfy_table(hwmgr, &pwr_virus_section5); 576 execute_pwr_dfy_table(hwmgr, &pwr_virus_section6); 577 execute_pwr_table(hwmgr, pwr_virus_table_post, ARRAY_SIZE(pwr_virus_table_post)); 578 579 return 0; 580 } 581 582 int smu7_init(struct pp_hwmgr *hwmgr) 583 { 584 struct smu7_smumgr *smu_data; 585 int r; 586 /* Allocate memory for backend private data */ 587 smu_data = (struct smu7_smumgr *)(hwmgr->smu_backend); 588 smu_data->header_buffer.data_size = 589 ((sizeof(struct SMU_DRAMData_TOC) / 4096) + 1) * 4096; 590 591 /* Allocate FW image data structure and header buffer and 592 * send the header buffer address to SMU */ 593 r = amdgpu_bo_create_kernel((struct amdgpu_device *)hwmgr->adev, 594 smu_data->header_buffer.data_size, 595 PAGE_SIZE, 596 AMDGPU_GEM_DOMAIN_VRAM, 597 &smu_data->header_buffer.handle, 598 (u64 *)&smu_data->header_buffer.mc_addr, 599 &smu_data->header_buffer.kaddr); 600 601 if (r) 602 return -EINVAL; 603 604 if (!hwmgr->not_vf) 605 return 0; 606 607 smu_data->smu_buffer.data_size = 200*4096; 608 r = amdgpu_bo_create_kernel((struct amdgpu_device *)hwmgr->adev, 609 smu_data->smu_buffer.data_size, 610 PAGE_SIZE, 611 AMDGPU_GEM_DOMAIN_VRAM, 612 &smu_data->smu_buffer.handle, 613 (u64 *)&smu_data->smu_buffer.mc_addr, 614 &smu_data->smu_buffer.kaddr); 615 616 if (r) { 617 amdgpu_bo_free_kernel(&smu_data->header_buffer.handle, 618 (u64 *)&smu_data->header_buffer.mc_addr, 619 &smu_data->header_buffer.kaddr); 620 return -EINVAL; 621 } 622 623 if (smum_is_hw_avfs_present(hwmgr)) 624 hwmgr->avfs_supported = true; 625 626 return 0; 627 } 628 629 630 int smu7_smu_fini(struct pp_hwmgr *hwmgr) 631 { 632 struct smu7_smumgr *smu_data = (struct smu7_smumgr *)(hwmgr->smu_backend); 633 634 amdgpu_bo_free_kernel(&smu_data->header_buffer.handle, 635 (u64 *)&smu_data->header_buffer.mc_addr, 636 &smu_data->header_buffer.kaddr); 637 638 if (hwmgr->not_vf) 639 amdgpu_bo_free_kernel(&smu_data->smu_buffer.handle, 640 (u64 *)&smu_data->smu_buffer.mc_addr, 641 &smu_data->smu_buffer.kaddr); 642 643 644 kfree(smu_data->toc); 645 smu_data->toc = NULL; 646 kfree(hwmgr->smu_backend); 647 hwmgr->smu_backend = NULL; 648 return 0; 649 } 650