| File: | dev/pci/drm/amd/pm/powerplay/smumgr/smu7_smumgr.c |
| Warning: | line 168, column 24 Value stored to 'adev' during its initialization is never read |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
| 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_SIZE0x20000 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)do { if (!((0 == (3 & smc_addr)))) { printk("\0014" "amdgpu: " "%s\n", "SMC address must be 4 byte aligned."); return -22; } } while (0); |
| 41 | PP_ASSERT_WITH_CODE((limit > (smc_addr + 3)), "SMC addr is beyond the SMC RAM area.", return -EINVAL)do { if (!((limit > (smc_addr + 3)))) { printk("\0014" "amdgpu: " "%s\n", "SMC addr is beyond the SMC RAM area."); return -22; } } while (0); |
| 42 | |
| 43 | cgs_write_register(hwmgr->device, mmSMC_IND_INDEX_11, smc_addr)(((struct cgs_device *)hwmgr->device)->ops->write_register (hwmgr->device,0x1AC,smc_addr)); |
| 44 | PHM_WRITE_FIELD(hwmgr->device, SMC_IND_ACCESS_CNTL, AUTO_INCREMENT_IND_11, 0)(((struct cgs_device *)hwmgr->device)->ops->write_register (hwmgr->device,0x92,((((((struct cgs_device *)hwmgr->device )->ops->read_register(hwmgr->device,0x92))) & ~0x800 ) | (0x800 & ((0) << 0xb))))); /* 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)do { if (!((0 == (3 & smc_start_address)))) { printk("\0014" "amdgpu: " "%s\n", "SMC address must be 4 byte aligned."); return -22; } } while (0); |
| 58 | PP_ASSERT_WITH_CODE((limit > (smc_start_address + byte_count)), "SMC address is beyond the SMC RAM area.", return -EINVAL)do { if (!((limit > (smc_start_address + byte_count)))) { printk ("\0014" "amdgpu: " "%s\n", "SMC address is beyond the SMC RAM area." ); return -22; } } while (0); |
| 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)(__uint32_t)(__builtin_constant_p(data) ? (__uint32_t)(((__uint32_t )(data) & 0xff) << 24 | ((__uint32_t)(data) & 0xff00 ) << 8 | ((__uint32_t)(data) & 0xff0000) >> 8 | ((__uint32_t)(data) & 0xff000000) >> 24) : __swap32md (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)(__uint32_t)(__builtin_constant_p(data) ? (__uint32_t)(((__uint32_t )(data) & 0xff) << 24 | ((__uint32_t)(data) & 0xff00 ) << 8 | ((__uint32_t)(data) & 0xff0000) >> 8 | ((__uint32_t)(data) & 0xff000000) >> 24) : __swap32md (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)do { if (!((0 == (3 & smc_start_address)))) { printk("\0014" "amdgpu: " "%s\n", "SMC address must be 4 byte aligned."); return -22; } } while (0); |
| 95 | PP_ASSERT_WITH_CODE((limit > (smc_start_address + byte_count)), "SMC address is beyond the SMC RAM area.", return -EINVAL)do { if (!((limit > (smc_start_address + byte_count)))) { printk ("\0014" "amdgpu: " "%s\n", "SMC address is beyond the SMC RAM area." ); return -22; } } while (0); |
| 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)(((struct cgs_device *)hwmgr->device)->ops->write_register (hwmgr->device,0x1AD,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)(((struct cgs_device *)hwmgr->device)->ops->read_register (hwmgr->device,0x1AD)); |
| 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)(((struct cgs_device *)hwmgr->device)->ops->write_register (hwmgr->device,0x1AD,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_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)((((((struct cgs_device *)hwmgr->device)->ops->read_ind_register (hwmgr->device,CGS_IND_REG__SMC,0x80000004))) & 0x1) >> 0x0)) |
| 163 | && (0x20100 <= cgs_read_ind_register(hwmgr->device, CGS_IND_REG__SMC, ixSMC_PC_C)(((struct cgs_device *)hwmgr->device)->ops->read_ind_register (hwmgr->device,CGS_IND_REG__SMC,0x80000370)))); |
| 164 | } |
| 165 | |
| 166 | int smu7_send_msg_to_smc(struct pp_hwmgr *hwmgr, uint16_t msg) |
| 167 | { |
| 168 | struct amdgpu_device *adev = hwmgr->adev; |
Value stored to 'adev' during its initialization is never read | |
| 169 | int ret; |
| 170 | |
| 171 | PHM_WAIT_FIELD_UNEQUAL(hwmgr, SMC_RESP_0, SMC_RESP, 0)phm_wait_for_register_unequal(hwmgr, 0x95, (0) << 0x0, 0xffff ); |
| 172 | |
| 173 | ret = PHM_READ_FIELD(hwmgr->device, SMC_RESP_0, SMC_RESP)((((((struct cgs_device *)hwmgr->device)->ops->read_register (hwmgr->device,0x95))) & 0xffff) >> 0x0); |
| 174 | |
| 175 | if (ret == 0xFE) |
| 176 | dev_dbg(adev->dev, "last message was not supported\n")do { } while(0); |
| 177 | else if (ret != 1) |
| 178 | dev_info(adev->dev,do { } while(0) |
| 179 | "\nlast message was failed ret is %d\n", ret)do { } while(0); |
| 180 | |
| 181 | cgs_write_register(hwmgr->device, mmSMC_RESP_0, 0)(((struct cgs_device *)hwmgr->device)->ops->write_register (hwmgr->device,0x95,0)); |
| 182 | cgs_write_register(hwmgr->device, mmSMC_MESSAGE_0, msg)(((struct cgs_device *)hwmgr->device)->ops->write_register (hwmgr->device,0x94,msg)); |
| 183 | |
| 184 | PHM_WAIT_FIELD_UNEQUAL(hwmgr, SMC_RESP_0, SMC_RESP, 0)phm_wait_for_register_unequal(hwmgr, 0x95, (0) << 0x0, 0xffff ); |
| 185 | |
| 186 | ret = PHM_READ_FIELD(hwmgr->device, SMC_RESP_0, SMC_RESP)((((((struct cgs_device *)hwmgr->device)->ops->read_register (hwmgr->device,0x95))) & 0xffff) >> 0x0); |
| 187 | |
| 188 | if (ret == 0xFE) |
| 189 | dev_dbg(adev->dev, "message %x was not supported\n", msg)do { } while(0); |
| 190 | else if (ret != 1) |
| 191 | dev_dbg(adev->dev,do { } while(0) |
| 192 | "failed to send message %x ret is %d \n", msg, ret)do { } while(0); |
| 193 | |
| 194 | return 0; |
| 195 | } |
| 196 | |
| 197 | int smu7_send_msg_to_smc_with_parameter(struct pp_hwmgr *hwmgr, uint16_t msg, uint32_t parameter) |
| 198 | { |
| 199 | PHM_WAIT_FIELD_UNEQUAL(hwmgr, SMC_RESP_0, SMC_RESP, 0)phm_wait_for_register_unequal(hwmgr, 0x95, (0) << 0x0, 0xffff ); |
| 200 | |
| 201 | cgs_write_register(hwmgr->device, mmSMC_MSG_ARG_0, parameter)(((struct cgs_device *)hwmgr->device)->ops->write_register (hwmgr->device,0xa4,parameter)); |
| 202 | |
| 203 | return smu7_send_msg_to_smc(hwmgr, msg); |
| 204 | } |
| 205 | |
| 206 | uint32_t smu7_get_argument(struct pp_hwmgr *hwmgr) |
| 207 | { |
| 208 | return cgs_read_register(hwmgr->device, mmSMC_MSG_ARG_0)(((struct cgs_device *)hwmgr->device)->ops->read_register (hwmgr->device,0xa4)); |
| 209 | } |
| 210 | |
| 211 | int smu7_send_msg_to_smc_offset(struct pp_hwmgr *hwmgr) |
| 212 | { |
| 213 | return smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_Test((uint16_t) 0x100), 0x20000, NULL((void *)0)); |
| 214 | } |
| 215 | |
| 216 | enum cgs_ucode_id smu7_convert_fw_type_to_cgs(uint32_t fw_type) |
| 217 | { |
| 218 | enum cgs_ucode_id result = CGS_UCODE_ID_MAXIMUM; |
| 219 | |
| 220 | switch (fw_type) { |
| 221 | case UCODE_ID_SMU0: |
| 222 | result = CGS_UCODE_ID_SMU; |
| 223 | break; |
| 224 | case UCODE_ID_SMU_SK14: |
| 225 | result = CGS_UCODE_ID_SMU_SK; |
| 226 | break; |
| 227 | case UCODE_ID_SDMA01: |
| 228 | result = CGS_UCODE_ID_SDMA0; |
| 229 | break; |
| 230 | case UCODE_ID_SDMA12: |
| 231 | result = CGS_UCODE_ID_SDMA1; |
| 232 | break; |
| 233 | case UCODE_ID_CP_CE3: |
| 234 | result = CGS_UCODE_ID_CP_CE; |
| 235 | break; |
| 236 | case UCODE_ID_CP_PFP4: |
| 237 | result = CGS_UCODE_ID_CP_PFP; |
| 238 | break; |
| 239 | case UCODE_ID_CP_ME5: |
| 240 | result = CGS_UCODE_ID_CP_ME; |
| 241 | break; |
| 242 | case UCODE_ID_CP_MEC6: |
| 243 | result = CGS_UCODE_ID_CP_MEC; |
| 244 | break; |
| 245 | case UCODE_ID_CP_MEC_JT17: |
| 246 | result = CGS_UCODE_ID_CP_MEC_JT1; |
| 247 | break; |
| 248 | case UCODE_ID_CP_MEC_JT28: |
| 249 | result = CGS_UCODE_ID_CP_MEC_JT2; |
| 250 | break; |
| 251 | case UCODE_ID_RLC_G10: |
| 252 | result = CGS_UCODE_ID_RLC_G; |
| 253 | break; |
| 254 | case UCODE_ID_MEC_STORAGE35: |
| 255 | result = CGS_UCODE_ID_STORAGE; |
| 256 | break; |
| 257 | default: |
| 258 | break; |
| 259 | } |
| 260 | |
| 261 | return result; |
| 262 | } |
| 263 | |
| 264 | |
| 265 | int smu7_read_smc_sram_dword(struct pp_hwmgr *hwmgr, uint32_t smc_addr, uint32_t *value, uint32_t limit) |
| 266 | { |
| 267 | int result; |
| 268 | |
| 269 | result = smu7_set_smc_sram_address(hwmgr, smc_addr, limit); |
| 270 | |
| 271 | *value = result ? 0 : cgs_read_register(hwmgr->device, mmSMC_IND_DATA_11)(((struct cgs_device *)hwmgr->device)->ops->read_register (hwmgr->device,0x1AD)); |
| 272 | |
| 273 | return result; |
| 274 | } |
| 275 | |
| 276 | int smu7_write_smc_sram_dword(struct pp_hwmgr *hwmgr, uint32_t smc_addr, uint32_t value, uint32_t limit) |
| 277 | { |
| 278 | int result; |
| 279 | |
| 280 | result = smu7_set_smc_sram_address(hwmgr, smc_addr, limit); |
| 281 | |
| 282 | if (result) |
| 283 | return result; |
| 284 | |
| 285 | cgs_write_register(hwmgr->device, mmSMC_IND_DATA_11, value)(((struct cgs_device *)hwmgr->device)->ops->write_register (hwmgr->device,0x1AD,value)); |
| 286 | |
| 287 | return 0; |
| 288 | } |
| 289 | |
| 290 | static int smu7_populate_single_firmware_entry(struct pp_hwmgr *hwmgr, |
| 291 | uint32_t fw_type, |
| 292 | struct SMU_Entry *entry) |
| 293 | { |
| 294 | int result = 0; |
| 295 | struct cgs_firmware_info info = {0}; |
| 296 | |
| 297 | result = cgs_get_firmware_info(hwmgr->device,(((struct cgs_device *)hwmgr->device)->ops->get_firmware_info (hwmgr->device, smu7_convert_fw_type_to_cgs(fw_type), & info)) |
| 298 | smu7_convert_fw_type_to_cgs(fw_type),(((struct cgs_device *)hwmgr->device)->ops->get_firmware_info (hwmgr->device, smu7_convert_fw_type_to_cgs(fw_type), & info)) |
| 299 | &info)(((struct cgs_device *)hwmgr->device)->ops->get_firmware_info (hwmgr->device, smu7_convert_fw_type_to_cgs(fw_type), & info)); |
| 300 | |
| 301 | if (!result) { |
| 302 | entry->version = info.fw_version; |
| 303 | entry->id = (uint16_t)fw_type; |
| 304 | entry->image_addr_high = upper_32_bits(info.mc_addr)((u32)(((info.mc_addr) >> 16) >> 16)); |
| 305 | entry->image_addr_low = lower_32_bits(info.mc_addr)((u32)(info.mc_addr)); |
| 306 | entry->meta_data_addr_high = 0; |
| 307 | entry->meta_data_addr_low = 0; |
| 308 | |
| 309 | /* digest need be excluded out */ |
| 310 | if (!hwmgr->not_vf) |
| 311 | info.image_size -= 20; |
| 312 | entry->data_size_byte = info.image_size; |
| 313 | entry->num_register_entries = 0; |
| 314 | } |
| 315 | |
| 316 | if ((fw_type == UCODE_ID_RLC_G10) |
| 317 | || (fw_type == UCODE_ID_CP_MEC6)) |
| 318 | entry->flags = 1; |
| 319 | else |
| 320 | entry->flags = 0; |
| 321 | |
| 322 | return 0; |
| 323 | } |
| 324 | |
| 325 | int smu7_request_smu_load_fw(struct pp_hwmgr *hwmgr) |
| 326 | { |
| 327 | struct smu7_smumgr *smu_data = (struct smu7_smumgr *)(hwmgr->smu_backend); |
| 328 | uint32_t fw_to_load; |
| 329 | int r = 0; |
| 330 | |
| 331 | amdgpu_ucode_init_bo(hwmgr->adev); |
| 332 | |
| 333 | if (smu_data->soft_regs_start) |
| 334 | cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC,(((struct cgs_device *)hwmgr->device)->ops->write_ind_register (hwmgr->device,CGS_IND_REG__SMC,smu_data->soft_regs_start + smum_get_offsetof(hwmgr, SMU_SoftRegisters, UcodeLoadStatus ),0x0)) |
| 335 | smu_data->soft_regs_start + smum_get_offsetof(hwmgr,(((struct cgs_device *)hwmgr->device)->ops->write_ind_register (hwmgr->device,CGS_IND_REG__SMC,smu_data->soft_regs_start + smum_get_offsetof(hwmgr, SMU_SoftRegisters, UcodeLoadStatus ),0x0)) |
| 336 | SMU_SoftRegisters, UcodeLoadStatus),(((struct cgs_device *)hwmgr->device)->ops->write_ind_register (hwmgr->device,CGS_IND_REG__SMC,smu_data->soft_regs_start + smum_get_offsetof(hwmgr, SMU_SoftRegisters, UcodeLoadStatus ),0x0)) |
| 337 | 0x0)(((struct cgs_device *)hwmgr->device)->ops->write_ind_register (hwmgr->device,CGS_IND_REG__SMC,smu_data->soft_regs_start + smum_get_offsetof(hwmgr, SMU_SoftRegisters, UcodeLoadStatus ),0x0)); |
| 338 | |
| 339 | if (hwmgr->chip_id > CHIP_TOPAZ) { /* add support for Topaz */ |
| 340 | if (hwmgr->not_vf) { |
| 341 | smum_send_msg_to_smc_with_parameter(hwmgr, |
| 342 | PPSMC_MSG_SMU_DRAM_ADDR_HI((uint16_t) 0x252), |
| 343 | upper_32_bits(smu_data->smu_buffer.mc_addr)((u32)(((smu_data->smu_buffer.mc_addr) >> 16) >> 16)), |
| 344 | NULL((void *)0)); |
| 345 | smum_send_msg_to_smc_with_parameter(hwmgr, |
| 346 | PPSMC_MSG_SMU_DRAM_ADDR_LO((uint16_t) 0x253), |
| 347 | lower_32_bits(smu_data->smu_buffer.mc_addr)((u32)(smu_data->smu_buffer.mc_addr)), |
| 348 | NULL((void *)0)); |
| 349 | } |
| 350 | fw_to_load = UCODE_ID_RLC_G_MASK0x00000400 |
| 351 | + UCODE_ID_SDMA0_MASK0x00000002 |
| 352 | + UCODE_ID_SDMA1_MASK0x00000004 |
| 353 | + UCODE_ID_CP_CE_MASK0x00000008 |
| 354 | + UCODE_ID_CP_ME_MASK0x00000020 |
| 355 | + UCODE_ID_CP_PFP_MASK0x00000010 |
| 356 | + UCODE_ID_CP_MEC_MASK0x00000040; |
| 357 | } else { |
| 358 | fw_to_load = UCODE_ID_RLC_G_MASK0x00000400 |
| 359 | + UCODE_ID_SDMA0_MASK0x00000002 |
| 360 | + UCODE_ID_SDMA1_MASK0x00000004 |
| 361 | + UCODE_ID_CP_CE_MASK0x00000008 |
| 362 | + UCODE_ID_CP_ME_MASK0x00000020 |
| 363 | + UCODE_ID_CP_PFP_MASK0x00000010 |
| 364 | + UCODE_ID_CP_MEC_MASK0x00000040 |
| 365 | + UCODE_ID_CP_MEC_JT1_MASK0x00000080 |
| 366 | + UCODE_ID_CP_MEC_JT2_MASK0x00000100; |
| 367 | } |
| 368 | |
| 369 | if (!smu_data->toc) { |
| 370 | struct SMU_DRAMData_TOC *toc; |
| 371 | |
| 372 | smu_data->toc = kzalloc(sizeof(struct SMU_DRAMData_TOC), GFP_KERNEL(0x0001 | 0x0004)); |
| 373 | if (!smu_data->toc) |
| 374 | return -ENOMEM12; |
| 375 | toc = smu_data->toc; |
| 376 | toc->num_entries = 0; |
| 377 | toc->structure_version = 1; |
| 378 | |
| 379 | PP_ASSERT_WITH_CODE(0 == smu7_populate_single_firmware_entry(hwmgr,do { if (!(0 == smu7_populate_single_firmware_entry(hwmgr, 10 , &toc->entry[toc->num_entries++]))) { printk("\0014" "amdgpu: " "%s\n", "Failed to Get Firmware Entry."); r = -22 ; goto failed; } } while (0) |
| 380 | UCODE_ID_RLC_G, &toc->entry[toc->num_entries++]),do { if (!(0 == smu7_populate_single_firmware_entry(hwmgr, 10 , &toc->entry[toc->num_entries++]))) { printk("\0014" "amdgpu: " "%s\n", "Failed to Get Firmware Entry."); r = -22 ; goto failed; } } while (0) |
| 381 | "Failed to Get Firmware Entry.", r = -EINVAL; goto failed)do { if (!(0 == smu7_populate_single_firmware_entry(hwmgr, 10 , &toc->entry[toc->num_entries++]))) { printk("\0014" "amdgpu: " "%s\n", "Failed to Get Firmware Entry."); r = -22 ; goto failed; } } while (0); |
| 382 | PP_ASSERT_WITH_CODE(0 == smu7_populate_single_firmware_entry(hwmgr,do { if (!(0 == smu7_populate_single_firmware_entry(hwmgr, 3, &toc->entry[toc->num_entries++]))) { printk("\0014" "amdgpu: " "%s\n", "Failed to Get Firmware Entry."); r = -22 ; goto failed; } } while (0) |
| 383 | UCODE_ID_CP_CE, &toc->entry[toc->num_entries++]),do { if (!(0 == smu7_populate_single_firmware_entry(hwmgr, 3, &toc->entry[toc->num_entries++]))) { printk("\0014" "amdgpu: " "%s\n", "Failed to Get Firmware Entry."); r = -22 ; goto failed; } } while (0) |
| 384 | "Failed to Get Firmware Entry.", r = -EINVAL; goto failed)do { if (!(0 == smu7_populate_single_firmware_entry(hwmgr, 3, &toc->entry[toc->num_entries++]))) { printk("\0014" "amdgpu: " "%s\n", "Failed to Get Firmware Entry."); r = -22 ; goto failed; } } while (0); |
| 385 | PP_ASSERT_WITH_CODE(0 == smu7_populate_single_firmware_entry(hwmgr,do { if (!(0 == smu7_populate_single_firmware_entry(hwmgr, 4, &toc->entry[toc->num_entries++]))) { printk("\0014" "amdgpu: " "%s\n", "Failed to Get Firmware Entry."); r = -22 ; goto failed; } } while (0) |
| 386 | UCODE_ID_CP_PFP, &toc->entry[toc->num_entries++]),do { if (!(0 == smu7_populate_single_firmware_entry(hwmgr, 4, &toc->entry[toc->num_entries++]))) { printk("\0014" "amdgpu: " "%s\n", "Failed to Get Firmware Entry."); r = -22 ; goto failed; } } while (0) |
| 387 | "Failed to Get Firmware Entry.", r = -EINVAL; goto failed)do { if (!(0 == smu7_populate_single_firmware_entry(hwmgr, 4, &toc->entry[toc->num_entries++]))) { printk("\0014" "amdgpu: " "%s\n", "Failed to Get Firmware Entry."); r = -22 ; goto failed; } } while (0); |
| 388 | PP_ASSERT_WITH_CODE(0 == smu7_populate_single_firmware_entry(hwmgr,do { if (!(0 == smu7_populate_single_firmware_entry(hwmgr, 5, &toc->entry[toc->num_entries++]))) { printk("\0014" "amdgpu: " "%s\n", "Failed to Get Firmware Entry."); r = -22 ; goto failed; } } while (0) |
| 389 | UCODE_ID_CP_ME, &toc->entry[toc->num_entries++]),do { if (!(0 == smu7_populate_single_firmware_entry(hwmgr, 5, &toc->entry[toc->num_entries++]))) { printk("\0014" "amdgpu: " "%s\n", "Failed to Get Firmware Entry."); r = -22 ; goto failed; } } while (0) |
| 390 | "Failed to Get Firmware Entry.", r = -EINVAL; goto failed)do { if (!(0 == smu7_populate_single_firmware_entry(hwmgr, 5, &toc->entry[toc->num_entries++]))) { printk("\0014" "amdgpu: " "%s\n", "Failed to Get Firmware Entry."); r = -22 ; goto failed; } } while (0); |
| 391 | PP_ASSERT_WITH_CODE(0 == smu7_populate_single_firmware_entry(hwmgr,do { if (!(0 == smu7_populate_single_firmware_entry(hwmgr, 6, &toc->entry[toc->num_entries++]))) { printk("\0014" "amdgpu: " "%s\n", "Failed to Get Firmware Entry."); r = -22 ; goto failed; } } while (0) |
| 392 | UCODE_ID_CP_MEC, &toc->entry[toc->num_entries++]),do { if (!(0 == smu7_populate_single_firmware_entry(hwmgr, 6, &toc->entry[toc->num_entries++]))) { printk("\0014" "amdgpu: " "%s\n", "Failed to Get Firmware Entry."); r = -22 ; goto failed; } } while (0) |
| 393 | "Failed to Get Firmware Entry.", r = -EINVAL; goto failed)do { if (!(0 == smu7_populate_single_firmware_entry(hwmgr, 6, &toc->entry[toc->num_entries++]))) { printk("\0014" "amdgpu: " "%s\n", "Failed to Get Firmware Entry."); r = -22 ; goto failed; } } while (0); |
| 394 | PP_ASSERT_WITH_CODE(0 == smu7_populate_single_firmware_entry(hwmgr,do { if (!(0 == smu7_populate_single_firmware_entry(hwmgr, 7, &toc->entry[toc->num_entries++]))) { printk("\0014" "amdgpu: " "%s\n", "Failed to Get Firmware Entry."); r = -22 ; goto failed; } } while (0) |
| 395 | UCODE_ID_CP_MEC_JT1, &toc->entry[toc->num_entries++]),do { if (!(0 == smu7_populate_single_firmware_entry(hwmgr, 7, &toc->entry[toc->num_entries++]))) { printk("\0014" "amdgpu: " "%s\n", "Failed to Get Firmware Entry."); r = -22 ; goto failed; } } while (0) |
| 396 | "Failed to Get Firmware Entry.", r = -EINVAL; goto failed)do { if (!(0 == smu7_populate_single_firmware_entry(hwmgr, 7, &toc->entry[toc->num_entries++]))) { printk("\0014" "amdgpu: " "%s\n", "Failed to Get Firmware Entry."); r = -22 ; goto failed; } } while (0); |
| 397 | PP_ASSERT_WITH_CODE(0 == smu7_populate_single_firmware_entry(hwmgr,do { if (!(0 == smu7_populate_single_firmware_entry(hwmgr, 8, &toc->entry[toc->num_entries++]))) { printk("\0014" "amdgpu: " "%s\n", "Failed to Get Firmware Entry."); r = -22 ; goto failed; } } while (0) |
| 398 | UCODE_ID_CP_MEC_JT2, &toc->entry[toc->num_entries++]),do { if (!(0 == smu7_populate_single_firmware_entry(hwmgr, 8, &toc->entry[toc->num_entries++]))) { printk("\0014" "amdgpu: " "%s\n", "Failed to Get Firmware Entry."); r = -22 ; goto failed; } } while (0) |
| 399 | "Failed to Get Firmware Entry.", r = -EINVAL; goto failed)do { if (!(0 == smu7_populate_single_firmware_entry(hwmgr, 8, &toc->entry[toc->num_entries++]))) { printk("\0014" "amdgpu: " "%s\n", "Failed to Get Firmware Entry."); r = -22 ; goto failed; } } while (0); |
| 400 | PP_ASSERT_WITH_CODE(0 == smu7_populate_single_firmware_entry(hwmgr,do { if (!(0 == smu7_populate_single_firmware_entry(hwmgr, 1, &toc->entry[toc->num_entries++]))) { printk("\0014" "amdgpu: " "%s\n", "Failed to Get Firmware Entry."); r = -22 ; goto failed; } } while (0) |
| 401 | UCODE_ID_SDMA0, &toc->entry[toc->num_entries++]),do { if (!(0 == smu7_populate_single_firmware_entry(hwmgr, 1, &toc->entry[toc->num_entries++]))) { printk("\0014" "amdgpu: " "%s\n", "Failed to Get Firmware Entry."); r = -22 ; goto failed; } } while (0) |
| 402 | "Failed to Get Firmware Entry.", r = -EINVAL; goto failed)do { if (!(0 == smu7_populate_single_firmware_entry(hwmgr, 1, &toc->entry[toc->num_entries++]))) { printk("\0014" "amdgpu: " "%s\n", "Failed to Get Firmware Entry."); r = -22 ; goto failed; } } while (0); |
| 403 | PP_ASSERT_WITH_CODE(0 == smu7_populate_single_firmware_entry(hwmgr,do { if (!(0 == smu7_populate_single_firmware_entry(hwmgr, 2, &toc->entry[toc->num_entries++]))) { printk("\0014" "amdgpu: " "%s\n", "Failed to Get Firmware Entry."); r = -22 ; goto failed; } } while (0) |
| 404 | UCODE_ID_SDMA1, &toc->entry[toc->num_entries++]),do { if (!(0 == smu7_populate_single_firmware_entry(hwmgr, 2, &toc->entry[toc->num_entries++]))) { printk("\0014" "amdgpu: " "%s\n", "Failed to Get Firmware Entry."); r = -22 ; goto failed; } } while (0) |
| 405 | "Failed to Get Firmware Entry.", r = -EINVAL; goto failed)do { if (!(0 == smu7_populate_single_firmware_entry(hwmgr, 2, &toc->entry[toc->num_entries++]))) { printk("\0014" "amdgpu: " "%s\n", "Failed to Get Firmware Entry."); r = -22 ; goto failed; } } while (0); |
| 406 | if (!hwmgr->not_vf) |
| 407 | PP_ASSERT_WITH_CODE(0 == smu7_populate_single_firmware_entry(hwmgr,do { if (!(0 == smu7_populate_single_firmware_entry(hwmgr, 35 , &toc->entry[toc->num_entries++]))) { printk("\0014" "amdgpu: " "%s\n", "Failed to Get Firmware Entry."); r = -22 ; goto failed; } } while (0) |
| 408 | UCODE_ID_MEC_STORAGE, &toc->entry[toc->num_entries++]),do { if (!(0 == smu7_populate_single_firmware_entry(hwmgr, 35 , &toc->entry[toc->num_entries++]))) { printk("\0014" "amdgpu: " "%s\n", "Failed to Get Firmware Entry."); r = -22 ; goto failed; } } while (0) |
| 409 | "Failed to Get Firmware Entry.", r = -EINVAL; goto failed)do { if (!(0 == smu7_populate_single_firmware_entry(hwmgr, 35 , &toc->entry[toc->num_entries++]))) { printk("\0014" "amdgpu: " "%s\n", "Failed to Get Firmware Entry."); r = -22 ; goto failed; } } while (0); |
| 410 | } |
| 411 | memcpy_toio(smu_data->header_buffer.kaddr, smu_data->toc,__builtin_memcpy((smu_data->header_buffer.kaddr), (smu_data ->toc), (sizeof(struct SMU_DRAMData_TOC))) |
| 412 | sizeof(struct SMU_DRAMData_TOC))__builtin_memcpy((smu_data->header_buffer.kaddr), (smu_data ->toc), (sizeof(struct SMU_DRAMData_TOC))); |
| 413 | smum_send_msg_to_smc_with_parameter(hwmgr, |
| 414 | PPSMC_MSG_DRV_DRAM_ADDR_HI((uint16_t) 0x250), |
| 415 | upper_32_bits(smu_data->header_buffer.mc_addr)((u32)(((smu_data->header_buffer.mc_addr) >> 16) >> 16)), |
| 416 | NULL((void *)0)); |
| 417 | smum_send_msg_to_smc_with_parameter(hwmgr, |
| 418 | PPSMC_MSG_DRV_DRAM_ADDR_LO((uint16_t) 0x251), |
| 419 | lower_32_bits(smu_data->header_buffer.mc_addr)((u32)(smu_data->header_buffer.mc_addr)), |
| 420 | NULL((void *)0)); |
| 421 | |
| 422 | smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_LoadUcodes((uint16_t) 0x254), fw_to_load, NULL((void *)0)); |
| 423 | |
| 424 | r = smu7_check_fw_load_finish(hwmgr, fw_to_load); |
| 425 | if (!r) |
| 426 | return 0; |
| 427 | |
| 428 | pr_err("SMU load firmware failed\n")printk("\0013" "amdgpu: " "SMU load firmware failed\n"); |
| 429 | |
| 430 | failed: |
| 431 | kfree(smu_data->toc); |
| 432 | smu_data->toc = NULL((void *)0); |
| 433 | return r; |
| 434 | } |
| 435 | |
| 436 | /* Check if the FW has been loaded, SMU will not return if loading has not finished. */ |
| 437 | int smu7_check_fw_load_finish(struct pp_hwmgr *hwmgr, uint32_t fw_type) |
| 438 | { |
| 439 | struct smu7_smumgr *smu_data = (struct smu7_smumgr *)(hwmgr->smu_backend); |
| 440 | uint32_t ret; |
| 441 | |
| 442 | ret = phm_wait_on_indirect_register(hwmgr, mmSMC_IND_INDEX_110x1AC, |
| 443 | smu_data->soft_regs_start + smum_get_offsetof(hwmgr, |
| 444 | SMU_SoftRegisters, UcodeLoadStatus), |
| 445 | fw_type, fw_type); |
| 446 | return ret; |
| 447 | } |
| 448 | |
| 449 | int smu7_reload_firmware(struct pp_hwmgr *hwmgr) |
| 450 | { |
| 451 | return hwmgr->smumgr_funcs->start_smu(hwmgr); |
| 452 | } |
| 453 | |
| 454 | static int smu7_upload_smc_firmware_data(struct pp_hwmgr *hwmgr, uint32_t length, uint32_t *src, uint32_t limit) |
| 455 | { |
| 456 | uint32_t byte_count = length; |
| 457 | |
| 458 | PP_ASSERT_WITH_CODE((limit >= byte_count), "SMC address is beyond the SMC RAM area.", return -EINVAL)do { if (!((limit >= byte_count))) { printk("\0014" "amdgpu: " "%s\n", "SMC address is beyond the SMC RAM area."); return - 22; } } while (0); |
| 459 | |
| 460 | cgs_write_register(hwmgr->device, mmSMC_IND_INDEX_11, 0x20000)(((struct cgs_device *)hwmgr->device)->ops->write_register (hwmgr->device,0x1AC,0x20000)); |
| 461 | PHM_WRITE_FIELD(hwmgr->device, SMC_IND_ACCESS_CNTL, AUTO_INCREMENT_IND_11, 1)(((struct cgs_device *)hwmgr->device)->ops->write_register (hwmgr->device,0x92,((((((struct cgs_device *)hwmgr->device )->ops->read_register(hwmgr->device,0x92))) & ~0x800 ) | (0x800 & ((1) << 0xb))))); |
| 462 | |
| 463 | for (; byte_count >= 4; byte_count -= 4) |
| 464 | cgs_write_register(hwmgr->device, mmSMC_IND_DATA_11, *src++)(((struct cgs_device *)hwmgr->device)->ops->write_register (hwmgr->device,0x1AD,*src++)); |
| 465 | |
| 466 | PHM_WRITE_FIELD(hwmgr->device, SMC_IND_ACCESS_CNTL, AUTO_INCREMENT_IND_11, 0)(((struct cgs_device *)hwmgr->device)->ops->write_register (hwmgr->device,0x92,((((((struct cgs_device *)hwmgr->device )->ops->read_register(hwmgr->device,0x92))) & ~0x800 ) | (0x800 & ((0) << 0xb))))); |
| 467 | |
| 468 | PP_ASSERT_WITH_CODE((0 == byte_count), "SMC size must be divisible by 4.", return -EINVAL)do { if (!((0 == byte_count))) { printk("\0014" "amdgpu: " "%s\n" , "SMC size must be divisible by 4."); return -22; } } while ( 0); |
| 469 | |
| 470 | return 0; |
| 471 | } |
| 472 | |
| 473 | |
| 474 | int smu7_upload_smu_firmware_image(struct pp_hwmgr *hwmgr) |
| 475 | { |
| 476 | int result = 0; |
| 477 | struct smu7_smumgr *smu_data = (struct smu7_smumgr *)(hwmgr->smu_backend); |
| 478 | |
| 479 | struct cgs_firmware_info info = {0}; |
| 480 | |
| 481 | if (smu_data->security_hard_key == 1) |
| 482 | cgs_get_firmware_info(hwmgr->device,(((struct cgs_device *)hwmgr->device)->ops->get_firmware_info (hwmgr->device, smu7_convert_fw_type_to_cgs(0), &info) ) |
| 483 | smu7_convert_fw_type_to_cgs(UCODE_ID_SMU), &info)(((struct cgs_device *)hwmgr->device)->ops->get_firmware_info (hwmgr->device, smu7_convert_fw_type_to_cgs(0), &info) ); |
| 484 | else |
| 485 | cgs_get_firmware_info(hwmgr->device,(((struct cgs_device *)hwmgr->device)->ops->get_firmware_info (hwmgr->device, smu7_convert_fw_type_to_cgs(14), &info )) |
| 486 | smu7_convert_fw_type_to_cgs(UCODE_ID_SMU_SK), &info)(((struct cgs_device *)hwmgr->device)->ops->get_firmware_info (hwmgr->device, smu7_convert_fw_type_to_cgs(14), &info )); |
| 487 | |
| 488 | hwmgr->is_kicker = info.is_kicker; |
| 489 | hwmgr->smu_version = info.version; |
| 490 | result = smu7_upload_smc_firmware_data(hwmgr, info.image_size, (uint32_t *)info.kptr, SMU7_SMC_SIZE0x20000); |
| 491 | |
| 492 | return result; |
| 493 | } |
| 494 | |
| 495 | static void execute_pwr_table(struct pp_hwmgr *hwmgr, const PWR_Command_Table *pvirus, int size) |
| 496 | { |
| 497 | int i; |
| 498 | uint32_t reg, data; |
| 499 | |
| 500 | for (i = 0; i < size; i++) { |
| 501 | reg = pvirus->reg; |
| 502 | data = pvirus->data; |
| 503 | if (reg != 0xffffffff) |
| 504 | cgs_write_register(hwmgr->device, reg, data)(((struct cgs_device *)hwmgr->device)->ops->write_register (hwmgr->device,reg,data)); |
| 505 | else |
| 506 | break; |
| 507 | pvirus++; |
| 508 | } |
| 509 | } |
| 510 | |
| 511 | static void execute_pwr_dfy_table(struct pp_hwmgr *hwmgr, const PWR_DFY_Section *section) |
| 512 | { |
| 513 | int i; |
| 514 | |
| 515 | cgs_write_register(hwmgr->device, mmCP_DFY_CNTL, section->dfy_cntl)(((struct cgs_device *)hwmgr->device)->ops->write_register (hwmgr->device,0x3020,section->dfy_cntl)); |
| 516 | cgs_write_register(hwmgr->device, mmCP_DFY_ADDR_HI, section->dfy_addr_hi)(((struct cgs_device *)hwmgr->device)->ops->write_register (hwmgr->device,0x3022,section->dfy_addr_hi)); |
| 517 | cgs_write_register(hwmgr->device, mmCP_DFY_ADDR_LO, section->dfy_addr_lo)(((struct cgs_device *)hwmgr->device)->ops->write_register (hwmgr->device,0x3023,section->dfy_addr_lo)); |
| 518 | for (i = 0; i < section->dfy_size; i++) |
| 519 | cgs_write_register(hwmgr->device, mmCP_DFY_DATA_0, section->dfy_data[i])(((struct cgs_device *)hwmgr->device)->ops->write_register (hwmgr->device,0x3024,section->dfy_data[i])); |
| 520 | } |
| 521 | |
| 522 | int smu7_setup_pwr_virus(struct pp_hwmgr *hwmgr) |
| 523 | { |
| 524 | execute_pwr_table(hwmgr, pwr_virus_table_pre, ARRAY_SIZE(pwr_virus_table_pre)(sizeof((pwr_virus_table_pre)) / sizeof((pwr_virus_table_pre) [0]))); |
| 525 | execute_pwr_dfy_table(hwmgr, &pwr_virus_section1); |
| 526 | execute_pwr_dfy_table(hwmgr, &pwr_virus_section2); |
| 527 | execute_pwr_dfy_table(hwmgr, &pwr_virus_section3); |
| 528 | execute_pwr_dfy_table(hwmgr, &pwr_virus_section4); |
| 529 | execute_pwr_dfy_table(hwmgr, &pwr_virus_section5); |
| 530 | execute_pwr_dfy_table(hwmgr, &pwr_virus_section6); |
| 531 | execute_pwr_table(hwmgr, pwr_virus_table_post, ARRAY_SIZE(pwr_virus_table_post)(sizeof((pwr_virus_table_post)) / sizeof((pwr_virus_table_post )[0]))); |
| 532 | |
| 533 | return 0; |
| 534 | } |
| 535 | |
| 536 | int smu7_init(struct pp_hwmgr *hwmgr) |
| 537 | { |
| 538 | struct smu7_smumgr *smu_data; |
| 539 | int r; |
| 540 | /* Allocate memory for backend private data */ |
| 541 | smu_data = (struct smu7_smumgr *)(hwmgr->smu_backend); |
| 542 | smu_data->header_buffer.data_size = |
| 543 | ((sizeof(struct SMU_DRAMData_TOC) / 4096) + 1) * 4096; |
| 544 | |
| 545 | /* Allocate FW image data structure and header buffer and |
| 546 | * send the header buffer address to SMU */ |
| 547 | r = amdgpu_bo_create_kernel((struct amdgpu_device *)hwmgr->adev, |
| 548 | smu_data->header_buffer.data_size, |
| 549 | PAGE_SIZE(1 << 12), |
| 550 | AMDGPU_GEM_DOMAIN_VRAM0x4, |
| 551 | &smu_data->header_buffer.handle, |
| 552 | &smu_data->header_buffer.mc_addr, |
| 553 | &smu_data->header_buffer.kaddr); |
| 554 | |
| 555 | if (r) |
| 556 | return -EINVAL22; |
| 557 | |
| 558 | if (!hwmgr->not_vf) |
| 559 | return 0; |
| 560 | |
| 561 | smu_data->smu_buffer.data_size = 200*4096; |
| 562 | r = amdgpu_bo_create_kernel((struct amdgpu_device *)hwmgr->adev, |
| 563 | smu_data->smu_buffer.data_size, |
| 564 | PAGE_SIZE(1 << 12), |
| 565 | AMDGPU_GEM_DOMAIN_VRAM0x4, |
| 566 | &smu_data->smu_buffer.handle, |
| 567 | &smu_data->smu_buffer.mc_addr, |
| 568 | &smu_data->smu_buffer.kaddr); |
| 569 | |
| 570 | if (r) { |
| 571 | amdgpu_bo_free_kernel(&smu_data->header_buffer.handle, |
| 572 | &smu_data->header_buffer.mc_addr, |
| 573 | &smu_data->header_buffer.kaddr); |
| 574 | return -EINVAL22; |
| 575 | } |
| 576 | |
| 577 | if (smum_is_hw_avfs_present(hwmgr) && |
| 578 | (hwmgr->feature_mask & PP_AVFS_MASK)) |
| 579 | hwmgr->avfs_supported = true1; |
| 580 | |
| 581 | return 0; |
| 582 | } |
| 583 | |
| 584 | |
| 585 | int smu7_smu_fini(struct pp_hwmgr *hwmgr) |
| 586 | { |
| 587 | struct smu7_smumgr *smu_data = (struct smu7_smumgr *)(hwmgr->smu_backend); |
| 588 | |
| 589 | amdgpu_bo_free_kernel(&smu_data->header_buffer.handle, |
| 590 | &smu_data->header_buffer.mc_addr, |
| 591 | &smu_data->header_buffer.kaddr); |
| 592 | |
| 593 | if (hwmgr->not_vf) |
| 594 | amdgpu_bo_free_kernel(&smu_data->smu_buffer.handle, |
| 595 | &smu_data->smu_buffer.mc_addr, |
| 596 | &smu_data->smu_buffer.kaddr); |
| 597 | |
| 598 | |
| 599 | kfree(smu_data->toc); |
| 600 | smu_data->toc = NULL((void *)0); |
| 601 | kfree(hwmgr->smu_backend); |
| 602 | hwmgr->smu_backend = NULL((void *)0); |
| 603 | return 0; |
| 604 | } |