Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/amdgpu: use powerplay module for dgpu in Vi.

delete non-pp code and files. It was just a temporary
solution and not support dynamic power management.

Signed-off-by: Rex Zhu <Rex.Zhu@amd.com>
Acked-by: Edward O'Callaghan <funfunctor@folklore1984.net>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>

authored by

Rex Zhu and committed by
Alex Deucher
9487dd15 a8ca3413

+6 -3114
+1 -4
drivers/gpu/drm/amd/amdgpu/Makefile
··· 52 52 amdgpu-y += \ 53 53 amdgpu_dpm.o \ 54 54 amdgpu_powerplay.o \ 55 - cz_smc.o cz_dpm.o \ 56 - tonga_smc.o tonga_dpm.o \ 57 - fiji_smc.o fiji_dpm.o \ 58 - iceland_smc.o iceland_dpm.o 55 + cz_smc.o cz_dpm.o 59 56 60 57 # add DCE block 61 58 amdgpu-y += \
+2 -11
drivers/gpu/drm/amd/amdgpu/amdgpu_powerplay.c
··· 80 80 amd_pp->ip_funcs = &kv_dpm_ip_funcs; 81 81 break; 82 82 #endif 83 - case CHIP_TOPAZ: 84 - amd_pp->ip_funcs = &iceland_dpm_ip_funcs; 85 - break; 86 - case CHIP_TONGA: 87 - amd_pp->ip_funcs = &tonga_dpm_ip_funcs; 88 - break; 89 - case CHIP_FIJI: 90 - amd_pp->ip_funcs = &fiji_dpm_ip_funcs; 91 - break; 92 83 case CHIP_CARRIZO: 93 84 case CHIP_STONEY: 94 85 amd_pp->ip_funcs = &cz_dpm_ip_funcs; ··· 101 110 switch (adev->asic_type) { 102 111 case CHIP_POLARIS11: 103 112 case CHIP_POLARIS10: 104 - adev->pp_enabled = true; 105 - break; 106 113 case CHIP_TONGA: 107 114 case CHIP_FIJI: 108 115 case CHIP_TOPAZ: 116 + adev->pp_enabled = true; 117 + break; 109 118 case CHIP_CARRIZO: 110 119 case CHIP_STONEY: 111 120 adev->pp_enabled = (amdgpu_powerplay == 0) ? false : true;
-186
drivers/gpu/drm/amd/amdgpu/fiji_dpm.c
··· 1 - /* 2 - * Copyright 2014 Advanced Micro Devices, Inc. 3 - * 4 - * Permission is hereby granted, free of charge, to any person obtaining a 5 - * copy of this software and associated documentation files (the "Software"), 6 - * to deal in the Software without restriction, including without limitation 7 - * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 - * and/or sell copies of the Software, and to permit persons to whom the 9 - * Software is furnished to do so, subject to the following conditions: 10 - * 11 - * The above copyright notice and this permission notice shall be included in 12 - * all copies or substantial portions of the Software. 13 - * 14 - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 18 - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19 - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20 - * OTHER DEALINGS IN THE SOFTWARE. 21 - * 22 - */ 23 - 24 - #include <linux/firmware.h> 25 - #include "drmP.h" 26 - #include "amdgpu.h" 27 - #include "fiji_smum.h" 28 - 29 - MODULE_FIRMWARE("amdgpu/fiji_smc.bin"); 30 - 31 - static void fiji_dpm_set_funcs(struct amdgpu_device *adev); 32 - 33 - static int fiji_dpm_early_init(void *handle) 34 - { 35 - struct amdgpu_device *adev = (struct amdgpu_device *)handle; 36 - 37 - fiji_dpm_set_funcs(adev); 38 - 39 - return 0; 40 - } 41 - 42 - static int fiji_dpm_init_microcode(struct amdgpu_device *adev) 43 - { 44 - char fw_name[30] = "amdgpu/fiji_smc.bin"; 45 - int err; 46 - 47 - err = request_firmware(&adev->pm.fw, fw_name, adev->dev); 48 - if (err) 49 - goto out; 50 - err = amdgpu_ucode_validate(adev->pm.fw); 51 - 52 - out: 53 - if (err) { 54 - DRM_ERROR("Failed to load firmware \"%s\"", fw_name); 55 - release_firmware(adev->pm.fw); 56 - adev->pm.fw = NULL; 57 - } 58 - return err; 59 - } 60 - 61 - static int fiji_dpm_sw_init(void *handle) 62 - { 63 - int ret; 64 - struct amdgpu_device *adev = (struct amdgpu_device *)handle; 65 - 66 - ret = fiji_dpm_init_microcode(adev); 67 - if (ret) 68 - return ret; 69 - 70 - return 0; 71 - } 72 - 73 - static int fiji_dpm_sw_fini(void *handle) 74 - { 75 - struct amdgpu_device *adev = (struct amdgpu_device *)handle; 76 - 77 - release_firmware(adev->pm.fw); 78 - adev->pm.fw = NULL; 79 - 80 - return 0; 81 - } 82 - 83 - static int fiji_dpm_hw_init(void *handle) 84 - { 85 - int ret; 86 - struct amdgpu_device *adev = (struct amdgpu_device *)handle; 87 - 88 - mutex_lock(&adev->pm.mutex); 89 - 90 - ret = fiji_smu_init(adev); 91 - if (ret) { 92 - DRM_ERROR("SMU initialization failed\n"); 93 - goto fail; 94 - } 95 - 96 - ret = fiji_smu_start(adev); 97 - if (ret) { 98 - DRM_ERROR("SMU start failed\n"); 99 - goto fail; 100 - } 101 - 102 - mutex_unlock(&adev->pm.mutex); 103 - return 0; 104 - 105 - fail: 106 - adev->firmware.smu_load = false; 107 - mutex_unlock(&adev->pm.mutex); 108 - return -EINVAL; 109 - } 110 - 111 - static int fiji_dpm_hw_fini(void *handle) 112 - { 113 - struct amdgpu_device *adev = (struct amdgpu_device *)handle; 114 - mutex_lock(&adev->pm.mutex); 115 - fiji_smu_fini(adev); 116 - mutex_unlock(&adev->pm.mutex); 117 - return 0; 118 - } 119 - 120 - static int fiji_dpm_suspend(void *handle) 121 - { 122 - struct amdgpu_device *adev = (struct amdgpu_device *)handle; 123 - 124 - fiji_dpm_hw_fini(adev); 125 - 126 - return 0; 127 - } 128 - 129 - static int fiji_dpm_resume(void *handle) 130 - { 131 - struct amdgpu_device *adev = (struct amdgpu_device *)handle; 132 - 133 - fiji_dpm_hw_init(adev); 134 - 135 - return 0; 136 - } 137 - 138 - static int fiji_dpm_set_clockgating_state(void *handle, 139 - enum amd_clockgating_state state) 140 - { 141 - return 0; 142 - } 143 - 144 - static int fiji_dpm_set_powergating_state(void *handle, 145 - enum amd_powergating_state state) 146 - { 147 - return 0; 148 - } 149 - 150 - const struct amd_ip_funcs fiji_dpm_ip_funcs = { 151 - .name = "fiji_dpm", 152 - .early_init = fiji_dpm_early_init, 153 - .late_init = NULL, 154 - .sw_init = fiji_dpm_sw_init, 155 - .sw_fini = fiji_dpm_sw_fini, 156 - .hw_init = fiji_dpm_hw_init, 157 - .hw_fini = fiji_dpm_hw_fini, 158 - .suspend = fiji_dpm_suspend, 159 - .resume = fiji_dpm_resume, 160 - .is_idle = NULL, 161 - .wait_for_idle = NULL, 162 - .soft_reset = NULL, 163 - .set_clockgating_state = fiji_dpm_set_clockgating_state, 164 - .set_powergating_state = fiji_dpm_set_powergating_state, 165 - }; 166 - 167 - static const struct amdgpu_dpm_funcs fiji_dpm_funcs = { 168 - .get_temperature = NULL, 169 - .pre_set_power_state = NULL, 170 - .set_power_state = NULL, 171 - .post_set_power_state = NULL, 172 - .display_configuration_changed = NULL, 173 - .get_sclk = NULL, 174 - .get_mclk = NULL, 175 - .print_power_state = NULL, 176 - .debugfs_print_current_performance_level = NULL, 177 - .force_performance_level = NULL, 178 - .vblank_too_short = NULL, 179 - .powergate_uvd = NULL, 180 - }; 181 - 182 - static void fiji_dpm_set_funcs(struct amdgpu_device *adev) 183 - { 184 - if (NULL == adev->pm.funcs) 185 - adev->pm.funcs = &fiji_dpm_funcs; 186 - }
-863
drivers/gpu/drm/amd/amdgpu/fiji_smc.c
··· 1 - /* 2 - * Copyright 2014 Advanced Micro Devices, Inc. 3 - * 4 - * Permission is hereby granted, free of charge, to any person obtaining a 5 - * copy of this software and associated documentation files (the "Software"), 6 - * to deal in the Software without restriction, including without limitation 7 - * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 - * and/or sell copies of the Software, and to permit persons to whom the 9 - * Software is furnished to do so, subject to the following conditions: 10 - * 11 - * The above copyright notice and this permission notice shall be included in 12 - * all copies or substantial portions of the Software. 13 - * 14 - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 18 - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19 - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20 - * OTHER DEALINGS IN THE SOFTWARE. 21 - * 22 - */ 23 - 24 - #include <linux/firmware.h> 25 - #include "drmP.h" 26 - #include "amdgpu.h" 27 - #include "fiji_ppsmc.h" 28 - #include "fiji_smum.h" 29 - #include "smu_ucode_xfer_vi.h" 30 - #include "amdgpu_ucode.h" 31 - 32 - #include "smu/smu_7_1_3_d.h" 33 - #include "smu/smu_7_1_3_sh_mask.h" 34 - 35 - #define FIJI_SMC_SIZE 0x20000 36 - 37 - static int fiji_set_smc_sram_address(struct amdgpu_device *adev, uint32_t smc_address, uint32_t limit) 38 - { 39 - uint32_t val; 40 - 41 - if (smc_address & 3) 42 - return -EINVAL; 43 - 44 - if ((smc_address + 3) > limit) 45 - return -EINVAL; 46 - 47 - WREG32(mmSMC_IND_INDEX_0, smc_address); 48 - 49 - val = RREG32(mmSMC_IND_ACCESS_CNTL); 50 - val = REG_SET_FIELD(val, SMC_IND_ACCESS_CNTL, AUTO_INCREMENT_IND_0, 0); 51 - WREG32(mmSMC_IND_ACCESS_CNTL, val); 52 - 53 - return 0; 54 - } 55 - 56 - static int fiji_copy_bytes_to_smc(struct amdgpu_device *adev, uint32_t smc_start_address, const uint8_t *src, uint32_t byte_count, uint32_t limit) 57 - { 58 - uint32_t addr; 59 - uint32_t data, orig_data; 60 - int result = 0; 61 - uint32_t extra_shift; 62 - unsigned long flags; 63 - 64 - if (smc_start_address & 3) 65 - return -EINVAL; 66 - 67 - if ((smc_start_address + byte_count) > limit) 68 - return -EINVAL; 69 - 70 - addr = smc_start_address; 71 - 72 - spin_lock_irqsave(&adev->smc_idx_lock, flags); 73 - while (byte_count >= 4) { 74 - /* Bytes are written into the SMC addres space with the MSB first */ 75 - data = (src[0] << 24) + (src[1] << 16) + (src[2] << 8) + src[3]; 76 - 77 - result = fiji_set_smc_sram_address(adev, addr, limit); 78 - 79 - if (result) 80 - goto out; 81 - 82 - WREG32(mmSMC_IND_DATA_0, data); 83 - 84 - src += 4; 85 - byte_count -= 4; 86 - addr += 4; 87 - } 88 - 89 - if (0 != byte_count) { 90 - /* Now write odd bytes left, do a read modify write cycle */ 91 - data = 0; 92 - 93 - result = fiji_set_smc_sram_address(adev, addr, limit); 94 - if (result) 95 - goto out; 96 - 97 - orig_data = RREG32(mmSMC_IND_DATA_0); 98 - extra_shift = 8 * (4 - byte_count); 99 - 100 - while (byte_count > 0) { 101 - data = (data << 8) + *src++; 102 - byte_count--; 103 - } 104 - 105 - data <<= extra_shift; 106 - data |= (orig_data & ~((~0UL) << extra_shift)); 107 - 108 - result = fiji_set_smc_sram_address(adev, addr, limit); 109 - if (result) 110 - goto out; 111 - 112 - WREG32(mmSMC_IND_DATA_0, data); 113 - } 114 - 115 - out: 116 - spin_unlock_irqrestore(&adev->smc_idx_lock, flags); 117 - return result; 118 - } 119 - 120 - static int fiji_program_jump_on_start(struct amdgpu_device *adev) 121 - { 122 - static unsigned char data[] = {0xE0, 0x00, 0x80, 0x40}; 123 - fiji_copy_bytes_to_smc(adev, 0x0, data, 4, sizeof(data)+1); 124 - 125 - return 0; 126 - } 127 - 128 - static bool fiji_is_smc_ram_running(struct amdgpu_device *adev) 129 - { 130 - uint32_t val = RREG32_SMC(ixSMC_SYSCON_CLOCK_CNTL_0); 131 - val = REG_GET_FIELD(val, SMC_SYSCON_CLOCK_CNTL_0, ck_disable); 132 - 133 - return ((0 == val) && (0x20100 <= RREG32_SMC(ixSMC_PC_C))); 134 - } 135 - 136 - static int wait_smu_response(struct amdgpu_device *adev) 137 - { 138 - int i; 139 - uint32_t val; 140 - 141 - for (i = 0; i < adev->usec_timeout; i++) { 142 - val = RREG32(mmSMC_RESP_0); 143 - if (REG_GET_FIELD(val, SMC_RESP_0, SMC_RESP)) 144 - break; 145 - udelay(1); 146 - } 147 - 148 - if (i == adev->usec_timeout) 149 - return -EINVAL; 150 - 151 - return 0; 152 - } 153 - 154 - static int fiji_send_msg_to_smc_offset(struct amdgpu_device *adev) 155 - { 156 - if (wait_smu_response(adev)) { 157 - DRM_ERROR("Failed to send previous message\n"); 158 - return -EINVAL; 159 - } 160 - 161 - WREG32(mmSMC_MSG_ARG_0, 0x20000); 162 - WREG32(mmSMC_MESSAGE_0, PPSMC_MSG_Test); 163 - 164 - if (wait_smu_response(adev)) { 165 - DRM_ERROR("Failed to send message\n"); 166 - return -EINVAL; 167 - } 168 - 169 - return 0; 170 - } 171 - 172 - static int fiji_send_msg_to_smc(struct amdgpu_device *adev, PPSMC_Msg msg) 173 - { 174 - if (!fiji_is_smc_ram_running(adev)) 175 - { 176 - return -EINVAL; 177 - } 178 - 179 - if (wait_smu_response(adev)) { 180 - DRM_ERROR("Failed to send previous message\n"); 181 - return -EINVAL; 182 - } 183 - 184 - WREG32(mmSMC_MESSAGE_0, msg); 185 - 186 - if (wait_smu_response(adev)) { 187 - DRM_ERROR("Failed to send message\n"); 188 - return -EINVAL; 189 - } 190 - 191 - return 0; 192 - } 193 - 194 - static int fiji_send_msg_to_smc_without_waiting(struct amdgpu_device *adev, 195 - PPSMC_Msg msg) 196 - { 197 - if (wait_smu_response(adev)) { 198 - DRM_ERROR("Failed to send previous message\n"); 199 - return -EINVAL; 200 - } 201 - 202 - WREG32(mmSMC_MESSAGE_0, msg); 203 - 204 - return 0; 205 - } 206 - 207 - static int fiji_send_msg_to_smc_with_parameter(struct amdgpu_device *adev, 208 - PPSMC_Msg msg, 209 - uint32_t parameter) 210 - { 211 - if (!fiji_is_smc_ram_running(adev)) 212 - return -EINVAL; 213 - 214 - if (wait_smu_response(adev)) { 215 - DRM_ERROR("Failed to send previous message\n"); 216 - return -EINVAL; 217 - } 218 - 219 - WREG32(mmSMC_MSG_ARG_0, parameter); 220 - 221 - return fiji_send_msg_to_smc(adev, msg); 222 - } 223 - 224 - static int fiji_send_msg_to_smc_with_parameter_without_waiting( 225 - struct amdgpu_device *adev, 226 - PPSMC_Msg msg, uint32_t parameter) 227 - { 228 - if (wait_smu_response(adev)) { 229 - DRM_ERROR("Failed to send previous message\n"); 230 - return -EINVAL; 231 - } 232 - 233 - WREG32(mmSMC_MSG_ARG_0, parameter); 234 - 235 - return fiji_send_msg_to_smc_without_waiting(adev, msg); 236 - } 237 - 238 - #if 0 /* not used yet */ 239 - static int fiji_wait_for_smc_inactive(struct amdgpu_device *adev) 240 - { 241 - int i; 242 - uint32_t val; 243 - 244 - if (!fiji_is_smc_ram_running(adev)) 245 - return -EINVAL; 246 - 247 - for (i = 0; i < adev->usec_timeout; i++) { 248 - val = RREG32_SMC(ixSMC_SYSCON_CLOCK_CNTL_0); 249 - if (REG_GET_FIELD(val, SMC_SYSCON_CLOCK_CNTL_0, cken) == 0) 250 - break; 251 - udelay(1); 252 - } 253 - 254 - if (i == adev->usec_timeout) 255 - return -EINVAL; 256 - 257 - return 0; 258 - } 259 - #endif 260 - 261 - static int fiji_smu_upload_firmware_image(struct amdgpu_device *adev) 262 - { 263 - const struct smc_firmware_header_v1_0 *hdr; 264 - uint32_t ucode_size; 265 - uint32_t ucode_start_address; 266 - const uint8_t *src; 267 - uint32_t val; 268 - uint32_t byte_count; 269 - uint32_t *data; 270 - unsigned long flags; 271 - 272 - if (!adev->pm.fw) 273 - return -EINVAL; 274 - 275 - /* Skip SMC ucode loading on SR-IOV capable boards. 276 - * vbios does this for us in asic_init in that case. 277 - */ 278 - if (amdgpu_sriov_bios(adev)) 279 - return 0; 280 - 281 - hdr = (const struct smc_firmware_header_v1_0 *)adev->pm.fw->data; 282 - amdgpu_ucode_print_smc_hdr(&hdr->header); 283 - 284 - adev->pm.fw_version = le32_to_cpu(hdr->header.ucode_version); 285 - ucode_size = le32_to_cpu(hdr->header.ucode_size_bytes); 286 - ucode_start_address = le32_to_cpu(hdr->ucode_start_addr); 287 - src = (const uint8_t *) 288 - (adev->pm.fw->data + le32_to_cpu(hdr->header.ucode_array_offset_bytes)); 289 - 290 - if (ucode_size & 3) { 291 - DRM_ERROR("SMC ucode is not 4 bytes aligned\n"); 292 - return -EINVAL; 293 - } 294 - 295 - if (ucode_size > FIJI_SMC_SIZE) { 296 - DRM_ERROR("SMC address is beyond the SMC RAM area\n"); 297 - return -EINVAL; 298 - } 299 - 300 - spin_lock_irqsave(&adev->smc_idx_lock, flags); 301 - WREG32(mmSMC_IND_INDEX_0, ucode_start_address); 302 - 303 - val = RREG32(mmSMC_IND_ACCESS_CNTL); 304 - val = REG_SET_FIELD(val, SMC_IND_ACCESS_CNTL, AUTO_INCREMENT_IND_0, 1); 305 - WREG32(mmSMC_IND_ACCESS_CNTL, val); 306 - 307 - byte_count = ucode_size; 308 - data = (uint32_t *)src; 309 - for (; byte_count >= 4; data++, byte_count -= 4) 310 - WREG32(mmSMC_IND_DATA_0, data[0]); 311 - 312 - val = RREG32(mmSMC_IND_ACCESS_CNTL); 313 - val = REG_SET_FIELD(val, SMC_IND_ACCESS_CNTL, AUTO_INCREMENT_IND_0, 0); 314 - WREG32(mmSMC_IND_ACCESS_CNTL, val); 315 - spin_unlock_irqrestore(&adev->smc_idx_lock, flags); 316 - 317 - return 0; 318 - } 319 - 320 - #if 0 /* not used yet */ 321 - static int fiji_read_smc_sram_dword(struct amdgpu_device *adev, 322 - uint32_t smc_address, 323 - uint32_t *value, 324 - uint32_t limit) 325 - { 326 - int result; 327 - unsigned long flags; 328 - 329 - spin_lock_irqsave(&adev->smc_idx_lock, flags); 330 - result = fiji_set_smc_sram_address(adev, smc_address, limit); 331 - if (result == 0) 332 - *value = RREG32(mmSMC_IND_DATA_0); 333 - spin_unlock_irqrestore(&adev->smc_idx_lock, flags); 334 - return result; 335 - } 336 - 337 - static int fiji_write_smc_sram_dword(struct amdgpu_device *adev, 338 - uint32_t smc_address, 339 - uint32_t value, 340 - uint32_t limit) 341 - { 342 - int result; 343 - unsigned long flags; 344 - 345 - spin_lock_irqsave(&adev->smc_idx_lock, flags); 346 - result = fiji_set_smc_sram_address(adev, smc_address, limit); 347 - if (result == 0) 348 - WREG32(mmSMC_IND_DATA_0, value); 349 - spin_unlock_irqrestore(&adev->smc_idx_lock, flags); 350 - return result; 351 - } 352 - 353 - static int fiji_smu_stop_smc(struct amdgpu_device *adev) 354 - { 355 - uint32_t val = RREG32_SMC(ixSMC_SYSCON_RESET_CNTL); 356 - val = REG_SET_FIELD(val, SMC_SYSCON_RESET_CNTL, rst_reg, 1); 357 - WREG32_SMC(ixSMC_SYSCON_RESET_CNTL, val); 358 - 359 - val = RREG32_SMC(ixSMC_SYSCON_CLOCK_CNTL_0); 360 - val = REG_SET_FIELD(val, SMC_SYSCON_CLOCK_CNTL_0, ck_disable, 1); 361 - WREG32_SMC(ixSMC_SYSCON_CLOCK_CNTL_0, val); 362 - 363 - return 0; 364 - } 365 - #endif 366 - 367 - static enum AMDGPU_UCODE_ID fiji_convert_fw_type(uint32_t fw_type) 368 - { 369 - switch (fw_type) { 370 - case UCODE_ID_SDMA0: 371 - return AMDGPU_UCODE_ID_SDMA0; 372 - case UCODE_ID_SDMA1: 373 - return AMDGPU_UCODE_ID_SDMA1; 374 - case UCODE_ID_CP_CE: 375 - return AMDGPU_UCODE_ID_CP_CE; 376 - case UCODE_ID_CP_PFP: 377 - return AMDGPU_UCODE_ID_CP_PFP; 378 - case UCODE_ID_CP_ME: 379 - return AMDGPU_UCODE_ID_CP_ME; 380 - case UCODE_ID_CP_MEC: 381 - case UCODE_ID_CP_MEC_JT1: 382 - case UCODE_ID_CP_MEC_JT2: 383 - return AMDGPU_UCODE_ID_CP_MEC1; 384 - case UCODE_ID_RLC_G: 385 - return AMDGPU_UCODE_ID_RLC_G; 386 - default: 387 - DRM_ERROR("ucode type is out of range!\n"); 388 - return AMDGPU_UCODE_ID_MAXIMUM; 389 - } 390 - } 391 - 392 - static int fiji_smu_populate_single_firmware_entry(struct amdgpu_device *adev, 393 - uint32_t fw_type, 394 - struct SMU_Entry *entry) 395 - { 396 - enum AMDGPU_UCODE_ID id = fiji_convert_fw_type(fw_type); 397 - struct amdgpu_firmware_info *ucode = &adev->firmware.ucode[id]; 398 - const struct gfx_firmware_header_v1_0 *header = NULL; 399 - uint64_t gpu_addr; 400 - uint32_t data_size; 401 - 402 - if (ucode->fw == NULL) 403 - return -EINVAL; 404 - gpu_addr = ucode->mc_addr; 405 - header = (const struct gfx_firmware_header_v1_0 *)ucode->fw->data; 406 - data_size = le32_to_cpu(header->header.ucode_size_bytes); 407 - 408 - if ((fw_type == UCODE_ID_CP_MEC_JT1) || 409 - (fw_type == UCODE_ID_CP_MEC_JT2)) { 410 - gpu_addr += le32_to_cpu(header->jt_offset) << 2; 411 - data_size = le32_to_cpu(header->jt_size) << 2; 412 - } 413 - 414 - entry->version = (uint16_t)le32_to_cpu(header->header.ucode_version); 415 - entry->id = (uint16_t)fw_type; 416 - entry->image_addr_high = upper_32_bits(gpu_addr); 417 - entry->image_addr_low = lower_32_bits(gpu_addr); 418 - entry->meta_data_addr_high = 0; 419 - entry->meta_data_addr_low = 0; 420 - entry->data_size_byte = data_size; 421 - entry->num_register_entries = 0; 422 - 423 - if (fw_type == UCODE_ID_RLC_G) 424 - entry->flags = 1; 425 - else 426 - entry->flags = 0; 427 - 428 - return 0; 429 - } 430 - 431 - static int fiji_smu_request_load_fw(struct amdgpu_device *adev) 432 - { 433 - struct fiji_smu_private_data *private = (struct fiji_smu_private_data *)adev->smu.priv; 434 - struct SMU_DRAMData_TOC *toc; 435 - uint32_t fw_to_load; 436 - 437 - WREG32_SMC(ixSOFT_REGISTERS_TABLE_28, 0); 438 - 439 - fiji_send_msg_to_smc_with_parameter(adev, PPSMC_MSG_SMU_DRAM_ADDR_HI, private->smu_buffer_addr_high); 440 - fiji_send_msg_to_smc_with_parameter(adev, PPSMC_MSG_SMU_DRAM_ADDR_LO, private->smu_buffer_addr_low); 441 - 442 - toc = (struct SMU_DRAMData_TOC *)private->header; 443 - toc->num_entries = 0; 444 - toc->structure_version = 1; 445 - 446 - if (!adev->firmware.smu_load) 447 - return 0; 448 - 449 - if (fiji_smu_populate_single_firmware_entry(adev, UCODE_ID_RLC_G, 450 - &toc->entry[toc->num_entries++])) { 451 - DRM_ERROR("Failed to get firmware entry for RLC\n"); 452 - return -EINVAL; 453 - } 454 - 455 - if (fiji_smu_populate_single_firmware_entry(adev, UCODE_ID_CP_CE, 456 - &toc->entry[toc->num_entries++])) { 457 - DRM_ERROR("Failed to get firmware entry for CE\n"); 458 - return -EINVAL; 459 - } 460 - 461 - if (fiji_smu_populate_single_firmware_entry(adev, UCODE_ID_CP_PFP, 462 - &toc->entry[toc->num_entries++])) { 463 - DRM_ERROR("Failed to get firmware entry for PFP\n"); 464 - return -EINVAL; 465 - } 466 - 467 - if (fiji_smu_populate_single_firmware_entry(adev, UCODE_ID_CP_ME, 468 - &toc->entry[toc->num_entries++])) { 469 - DRM_ERROR("Failed to get firmware entry for ME\n"); 470 - return -EINVAL; 471 - } 472 - 473 - if (fiji_smu_populate_single_firmware_entry(adev, UCODE_ID_CP_MEC, 474 - &toc->entry[toc->num_entries++])) { 475 - DRM_ERROR("Failed to get firmware entry for MEC\n"); 476 - return -EINVAL; 477 - } 478 - 479 - if (fiji_smu_populate_single_firmware_entry(adev, UCODE_ID_CP_MEC_JT1, 480 - &toc->entry[toc->num_entries++])) { 481 - DRM_ERROR("Failed to get firmware entry for MEC_JT1\n"); 482 - return -EINVAL; 483 - } 484 - 485 - if (fiji_smu_populate_single_firmware_entry(adev, UCODE_ID_CP_MEC_JT2, 486 - &toc->entry[toc->num_entries++])) { 487 - DRM_ERROR("Failed to get firmware entry for MEC_JT2\n"); 488 - return -EINVAL; 489 - } 490 - 491 - if (fiji_smu_populate_single_firmware_entry(adev, UCODE_ID_SDMA0, 492 - &toc->entry[toc->num_entries++])) { 493 - DRM_ERROR("Failed to get firmware entry for SDMA0\n"); 494 - return -EINVAL; 495 - } 496 - 497 - if (fiji_smu_populate_single_firmware_entry(adev, UCODE_ID_SDMA1, 498 - &toc->entry[toc->num_entries++])) { 499 - DRM_ERROR("Failed to get firmware entry for SDMA1\n"); 500 - return -EINVAL; 501 - } 502 - 503 - fiji_send_msg_to_smc_with_parameter(adev, PPSMC_MSG_DRV_DRAM_ADDR_HI, private->header_addr_high); 504 - fiji_send_msg_to_smc_with_parameter(adev, PPSMC_MSG_DRV_DRAM_ADDR_LO, private->header_addr_low); 505 - 506 - fw_to_load = UCODE_ID_RLC_G_MASK | 507 - UCODE_ID_SDMA0_MASK | 508 - UCODE_ID_SDMA1_MASK | 509 - UCODE_ID_CP_CE_MASK | 510 - UCODE_ID_CP_ME_MASK | 511 - UCODE_ID_CP_PFP_MASK | 512 - UCODE_ID_CP_MEC_MASK; 513 - 514 - if (fiji_send_msg_to_smc_with_parameter_without_waiting(adev, PPSMC_MSG_LoadUcodes, fw_to_load)) { 515 - DRM_ERROR("Fail to request SMU load ucode\n"); 516 - return -EINVAL; 517 - } 518 - 519 - return 0; 520 - } 521 - 522 - static uint32_t fiji_smu_get_mask_for_fw_type(uint32_t fw_type) 523 - { 524 - switch (fw_type) { 525 - case AMDGPU_UCODE_ID_SDMA0: 526 - return UCODE_ID_SDMA0_MASK; 527 - case AMDGPU_UCODE_ID_SDMA1: 528 - return UCODE_ID_SDMA1_MASK; 529 - case AMDGPU_UCODE_ID_CP_CE: 530 - return UCODE_ID_CP_CE_MASK; 531 - case AMDGPU_UCODE_ID_CP_PFP: 532 - return UCODE_ID_CP_PFP_MASK; 533 - case AMDGPU_UCODE_ID_CP_ME: 534 - return UCODE_ID_CP_ME_MASK; 535 - case AMDGPU_UCODE_ID_CP_MEC1: 536 - return UCODE_ID_CP_MEC_MASK; 537 - case AMDGPU_UCODE_ID_CP_MEC2: 538 - return UCODE_ID_CP_MEC_MASK; 539 - case AMDGPU_UCODE_ID_RLC_G: 540 - return UCODE_ID_RLC_G_MASK; 541 - default: 542 - DRM_ERROR("ucode type is out of range!\n"); 543 - return 0; 544 - } 545 - } 546 - 547 - static int fiji_smu_check_fw_load_finish(struct amdgpu_device *adev, 548 - uint32_t fw_type) 549 - { 550 - uint32_t fw_mask = fiji_smu_get_mask_for_fw_type(fw_type); 551 - int i; 552 - 553 - for (i = 0; i < adev->usec_timeout; i++) { 554 - if (fw_mask == (RREG32_SMC(ixSOFT_REGISTERS_TABLE_28) & fw_mask)) 555 - break; 556 - udelay(1); 557 - } 558 - 559 - if (i == adev->usec_timeout) { 560 - DRM_ERROR("check firmware loading failed\n"); 561 - return -EINVAL; 562 - } 563 - 564 - return 0; 565 - } 566 - 567 - static int fiji_smu_start_in_protection_mode(struct amdgpu_device *adev) 568 - { 569 - int result; 570 - uint32_t val; 571 - int i; 572 - 573 - /* Assert reset */ 574 - val = RREG32_SMC(ixSMC_SYSCON_RESET_CNTL); 575 - val = REG_SET_FIELD(val, SMC_SYSCON_RESET_CNTL, rst_reg, 1); 576 - WREG32_SMC(ixSMC_SYSCON_RESET_CNTL, val); 577 - 578 - result = fiji_smu_upload_firmware_image(adev); 579 - if (result) 580 - return result; 581 - 582 - /* Clear status */ 583 - WREG32_SMC(ixSMU_STATUS, 0); 584 - 585 - /* Enable clock */ 586 - val = RREG32_SMC(ixSMC_SYSCON_CLOCK_CNTL_0); 587 - val = REG_SET_FIELD(val, SMC_SYSCON_CLOCK_CNTL_0, ck_disable, 0); 588 - WREG32_SMC(ixSMC_SYSCON_CLOCK_CNTL_0, val); 589 - 590 - /* De-assert reset */ 591 - val = RREG32_SMC(ixSMC_SYSCON_RESET_CNTL); 592 - val = REG_SET_FIELD(val, SMC_SYSCON_RESET_CNTL, rst_reg, 0); 593 - WREG32_SMC(ixSMC_SYSCON_RESET_CNTL, val); 594 - 595 - /* Set SMU Auto Start */ 596 - val = RREG32_SMC(ixSMU_INPUT_DATA); 597 - val = REG_SET_FIELD(val, SMU_INPUT_DATA, AUTO_START, 1); 598 - WREG32_SMC(ixSMU_INPUT_DATA, val); 599 - 600 - /* Clear firmware interrupt enable flag */ 601 - WREG32_SMC(ixFIRMWARE_FLAGS, 0); 602 - 603 - for (i = 0; i < adev->usec_timeout; i++) { 604 - val = RREG32_SMC(ixRCU_UC_EVENTS); 605 - if (REG_GET_FIELD(val, RCU_UC_EVENTS, INTERRUPTS_ENABLED)) 606 - break; 607 - udelay(1); 608 - } 609 - 610 - if (i == adev->usec_timeout) { 611 - DRM_ERROR("Interrupt is not enabled by firmware\n"); 612 - return -EINVAL; 613 - } 614 - 615 - /* Call Test SMU message with 0x20000 offset 616 - * to trigger SMU start 617 - */ 618 - fiji_send_msg_to_smc_offset(adev); 619 - DRM_INFO("[FM]try triger smu start\n"); 620 - /* Wait for done bit to be set */ 621 - for (i = 0; i < adev->usec_timeout; i++) { 622 - val = RREG32_SMC(ixSMU_STATUS); 623 - if (REG_GET_FIELD(val, SMU_STATUS, SMU_DONE)) 624 - break; 625 - udelay(1); 626 - } 627 - 628 - if (i == adev->usec_timeout) { 629 - DRM_ERROR("Timeout for SMU start\n"); 630 - return -EINVAL; 631 - } 632 - 633 - /* Check pass/failed indicator */ 634 - val = RREG32_SMC(ixSMU_STATUS); 635 - if (!REG_GET_FIELD(val, SMU_STATUS, SMU_PASS)) { 636 - DRM_ERROR("SMU Firmware start failed\n"); 637 - return -EINVAL; 638 - } 639 - DRM_INFO("[FM]smu started\n"); 640 - /* Wait for firmware to initialize */ 641 - for (i = 0; i < adev->usec_timeout; i++) { 642 - val = RREG32_SMC(ixFIRMWARE_FLAGS); 643 - if(REG_GET_FIELD(val, FIRMWARE_FLAGS, INTERRUPTS_ENABLED)) 644 - break; 645 - udelay(1); 646 - } 647 - 648 - if (i == adev->usec_timeout) { 649 - DRM_ERROR("SMU firmware initialization failed\n"); 650 - return -EINVAL; 651 - } 652 - DRM_INFO("[FM]smu initialized\n"); 653 - 654 - return 0; 655 - } 656 - 657 - static int fiji_smu_start_in_non_protection_mode(struct amdgpu_device *adev) 658 - { 659 - int i, result; 660 - uint32_t val; 661 - 662 - /* wait for smc boot up */ 663 - for (i = 0; i < adev->usec_timeout; i++) { 664 - val = RREG32_SMC(ixRCU_UC_EVENTS); 665 - val = REG_GET_FIELD(val, RCU_UC_EVENTS, boot_seq_done); 666 - if (val) 667 - break; 668 - udelay(1); 669 - } 670 - 671 - if (i == adev->usec_timeout) { 672 - DRM_ERROR("SMC boot sequence is not completed\n"); 673 - return -EINVAL; 674 - } 675 - 676 - /* Clear firmware interrupt enable flag */ 677 - WREG32_SMC(ixFIRMWARE_FLAGS, 0); 678 - 679 - /* Assert reset */ 680 - val = RREG32_SMC(ixSMC_SYSCON_RESET_CNTL); 681 - val = REG_SET_FIELD(val, SMC_SYSCON_RESET_CNTL, rst_reg, 1); 682 - WREG32_SMC(ixSMC_SYSCON_RESET_CNTL, val); 683 - 684 - result = fiji_smu_upload_firmware_image(adev); 685 - if (result) 686 - return result; 687 - 688 - /* Set smc instruct start point at 0x0 */ 689 - fiji_program_jump_on_start(adev); 690 - 691 - /* Enable clock */ 692 - val = RREG32_SMC(ixSMC_SYSCON_CLOCK_CNTL_0); 693 - val = REG_SET_FIELD(val, SMC_SYSCON_CLOCK_CNTL_0, ck_disable, 0); 694 - WREG32_SMC(ixSMC_SYSCON_CLOCK_CNTL_0, val); 695 - 696 - /* De-assert reset */ 697 - val = RREG32_SMC(ixSMC_SYSCON_RESET_CNTL); 698 - val = REG_SET_FIELD(val, SMC_SYSCON_RESET_CNTL, rst_reg, 0); 699 - WREG32_SMC(ixSMC_SYSCON_RESET_CNTL, val); 700 - 701 - /* Wait for firmware to initialize */ 702 - for (i = 0; i < adev->usec_timeout; i++) { 703 - val = RREG32_SMC(ixFIRMWARE_FLAGS); 704 - if (REG_GET_FIELD(val, FIRMWARE_FLAGS, INTERRUPTS_ENABLED)) 705 - break; 706 - udelay(1); 707 - } 708 - 709 - if (i == adev->usec_timeout) { 710 - DRM_ERROR("Timeout for SMC firmware initialization\n"); 711 - return -EINVAL; 712 - } 713 - 714 - return 0; 715 - } 716 - 717 - int fiji_smu_start(struct amdgpu_device *adev) 718 - { 719 - int result; 720 - uint32_t val; 721 - 722 - if (!fiji_is_smc_ram_running(adev)) { 723 - val = RREG32_SMC(ixSMU_FIRMWARE); 724 - if (!REG_GET_FIELD(val, SMU_FIRMWARE, SMU_MODE)) { 725 - DRM_INFO("[FM]start smu in nonprotection mode\n"); 726 - result = fiji_smu_start_in_non_protection_mode(adev); 727 - if (result) 728 - return result; 729 - } else { 730 - DRM_INFO("[FM]start smu in protection mode\n"); 731 - result = fiji_smu_start_in_protection_mode(adev); 732 - if (result) 733 - return result; 734 - } 735 - } 736 - 737 - return fiji_smu_request_load_fw(adev); 738 - } 739 - 740 - static const struct amdgpu_smumgr_funcs fiji_smumgr_funcs = { 741 - .check_fw_load_finish = fiji_smu_check_fw_load_finish, 742 - .request_smu_load_fw = NULL, 743 - .request_smu_specific_fw = NULL, 744 - }; 745 - 746 - int fiji_smu_init(struct amdgpu_device *adev) 747 - { 748 - struct fiji_smu_private_data *private; 749 - uint32_t image_size = ((sizeof(struct SMU_DRAMData_TOC) / 4096) + 1) * 4096; 750 - uint32_t smu_internal_buffer_size = 200*4096; 751 - struct amdgpu_bo **toc_buf = &adev->smu.toc_buf; 752 - struct amdgpu_bo **smu_buf = &adev->smu.smu_buf; 753 - uint64_t mc_addr; 754 - void *toc_buf_ptr; 755 - void *smu_buf_ptr; 756 - int ret; 757 - 758 - private = kzalloc(sizeof(struct fiji_smu_private_data), GFP_KERNEL); 759 - if (NULL == private) 760 - return -ENOMEM; 761 - 762 - /* allocate firmware buffers */ 763 - if (adev->firmware.smu_load) 764 - amdgpu_ucode_init_bo(adev); 765 - 766 - adev->smu.priv = private; 767 - adev->smu.fw_flags = 0; 768 - 769 - /* Allocate FW image data structure and header buffer */ 770 - ret = amdgpu_bo_create(adev, image_size, PAGE_SIZE, 771 - true, AMDGPU_GEM_DOMAIN_VRAM, 772 - AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED, 773 - NULL, NULL, toc_buf); 774 - if (ret) { 775 - DRM_ERROR("Failed to allocate memory for TOC buffer\n"); 776 - return -ENOMEM; 777 - } 778 - 779 - /* Allocate buffer for SMU internal buffer */ 780 - ret = amdgpu_bo_create(adev, smu_internal_buffer_size, PAGE_SIZE, 781 - true, AMDGPU_GEM_DOMAIN_VRAM, 782 - AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED, 783 - NULL, NULL, smu_buf); 784 - if (ret) { 785 - DRM_ERROR("Failed to allocate memory for SMU internal buffer\n"); 786 - return -ENOMEM; 787 - } 788 - 789 - /* Retrieve GPU address for header buffer and internal buffer */ 790 - ret = amdgpu_bo_reserve(adev->smu.toc_buf, false); 791 - if (ret) { 792 - amdgpu_bo_unref(&adev->smu.toc_buf); 793 - DRM_ERROR("Failed to reserve the TOC buffer\n"); 794 - return -EINVAL; 795 - } 796 - 797 - ret = amdgpu_bo_pin(adev->smu.toc_buf, AMDGPU_GEM_DOMAIN_VRAM, &mc_addr); 798 - if (ret) { 799 - amdgpu_bo_unreserve(adev->smu.toc_buf); 800 - amdgpu_bo_unref(&adev->smu.toc_buf); 801 - DRM_ERROR("Failed to pin the TOC buffer\n"); 802 - return -EINVAL; 803 - } 804 - 805 - ret = amdgpu_bo_kmap(*toc_buf, &toc_buf_ptr); 806 - if (ret) { 807 - amdgpu_bo_unreserve(adev->smu.toc_buf); 808 - amdgpu_bo_unref(&adev->smu.toc_buf); 809 - DRM_ERROR("Failed to map the TOC buffer\n"); 810 - return -EINVAL; 811 - } 812 - 813 - amdgpu_bo_unreserve(adev->smu.toc_buf); 814 - private->header_addr_low = lower_32_bits(mc_addr); 815 - private->header_addr_high = upper_32_bits(mc_addr); 816 - private->header = toc_buf_ptr; 817 - 818 - ret = amdgpu_bo_reserve(adev->smu.smu_buf, false); 819 - if (ret) { 820 - amdgpu_bo_unref(&adev->smu.smu_buf); 821 - amdgpu_bo_unref(&adev->smu.toc_buf); 822 - DRM_ERROR("Failed to reserve the SMU internal buffer\n"); 823 - return -EINVAL; 824 - } 825 - 826 - ret = amdgpu_bo_pin(adev->smu.smu_buf, AMDGPU_GEM_DOMAIN_VRAM, &mc_addr); 827 - if (ret) { 828 - amdgpu_bo_unreserve(adev->smu.smu_buf); 829 - amdgpu_bo_unref(&adev->smu.smu_buf); 830 - amdgpu_bo_unref(&adev->smu.toc_buf); 831 - DRM_ERROR("Failed to pin the SMU internal buffer\n"); 832 - return -EINVAL; 833 - } 834 - 835 - ret = amdgpu_bo_kmap(*smu_buf, &smu_buf_ptr); 836 - if (ret) { 837 - amdgpu_bo_unreserve(adev->smu.smu_buf); 838 - amdgpu_bo_unref(&adev->smu.smu_buf); 839 - amdgpu_bo_unref(&adev->smu.toc_buf); 840 - DRM_ERROR("Failed to map the SMU internal buffer\n"); 841 - return -EINVAL; 842 - } 843 - 844 - amdgpu_bo_unreserve(adev->smu.smu_buf); 845 - private->smu_buffer_addr_low = lower_32_bits(mc_addr); 846 - private->smu_buffer_addr_high = upper_32_bits(mc_addr); 847 - 848 - adev->smu.smumgr_funcs = &fiji_smumgr_funcs; 849 - 850 - return 0; 851 - } 852 - 853 - int fiji_smu_fini(struct amdgpu_device *adev) 854 - { 855 - amdgpu_bo_unref(&adev->smu.toc_buf); 856 - amdgpu_bo_unref(&adev->smu.smu_buf); 857 - kfree(adev->smu.priv); 858 - adev->smu.priv = NULL; 859 - if (adev->firmware.fw_buf) 860 - amdgpu_ucode_fini_bo(adev); 861 - 862 - return 0; 863 - }
-42
drivers/gpu/drm/amd/amdgpu/fiji_smum.h
··· 1 - /* 2 - * Copyright 2014 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 - #ifndef FIJI_SMUMGR_H 25 - #define FIJI_SMUMGR_H 26 - 27 - #include "fiji_ppsmc.h" 28 - 29 - int fiji_smu_init(struct amdgpu_device *adev); 30 - int fiji_smu_fini(struct amdgpu_device *adev); 31 - int fiji_smu_start(struct amdgpu_device *adev); 32 - 33 - struct fiji_smu_private_data 34 - { 35 - uint8_t *header; 36 - uint32_t smu_buffer_addr_high; 37 - uint32_t smu_buffer_addr_low; 38 - uint32_t header_addr_high; 39 - uint32_t header_addr_low; 40 - }; 41 - 42 - #endif
-200
drivers/gpu/drm/amd/amdgpu/iceland_dpm.c
··· 1 - /* 2 - * Copyright 2014 Advanced Micro Devices, Inc. 3 - * 4 - * Permission is hereby granted, free of charge, to any person obtaining a 5 - * copy of this software and associated documentation files (the "Software"), 6 - * to deal in the Software without restriction, including without limitation 7 - * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 - * and/or sell copies of the Software, and to permit persons to whom the 9 - * Software is furnished to do so, subject to the following conditions: 10 - * 11 - * The above copyright notice and this permission notice shall be included in 12 - * all copies or substantial portions of the Software. 13 - * 14 - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 18 - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19 - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20 - * OTHER DEALINGS IN THE SOFTWARE. 21 - * 22 - */ 23 - 24 - #include <linux/firmware.h> 25 - #include "drmP.h" 26 - #include "amdgpu.h" 27 - #include "iceland_smum.h" 28 - 29 - MODULE_FIRMWARE("amdgpu/topaz_smc.bin"); 30 - 31 - static void iceland_dpm_set_funcs(struct amdgpu_device *adev); 32 - 33 - static int iceland_dpm_early_init(void *handle) 34 - { 35 - struct amdgpu_device *adev = (struct amdgpu_device *)handle; 36 - 37 - iceland_dpm_set_funcs(adev); 38 - 39 - return 0; 40 - } 41 - 42 - static int iceland_dpm_init_microcode(struct amdgpu_device *adev) 43 - { 44 - char fw_name[30] = "amdgpu/topaz_smc.bin"; 45 - int err; 46 - 47 - err = request_firmware(&adev->pm.fw, fw_name, adev->dev); 48 - if (err) 49 - goto out; 50 - err = amdgpu_ucode_validate(adev->pm.fw); 51 - 52 - out: 53 - if (err) { 54 - DRM_ERROR("Failed to load firmware \"%s\"", fw_name); 55 - release_firmware(adev->pm.fw); 56 - adev->pm.fw = NULL; 57 - } 58 - return err; 59 - } 60 - 61 - static int iceland_dpm_sw_init(void *handle) 62 - { 63 - int ret; 64 - struct amdgpu_device *adev = (struct amdgpu_device *)handle; 65 - 66 - ret = iceland_dpm_init_microcode(adev); 67 - if (ret) 68 - return ret; 69 - 70 - return 0; 71 - } 72 - 73 - static int iceland_dpm_sw_fini(void *handle) 74 - { 75 - struct amdgpu_device *adev = (struct amdgpu_device *)handle; 76 - 77 - release_firmware(adev->pm.fw); 78 - adev->pm.fw = NULL; 79 - 80 - return 0; 81 - } 82 - 83 - static int iceland_dpm_hw_init(void *handle) 84 - { 85 - int ret; 86 - struct amdgpu_device *adev = (struct amdgpu_device *)handle; 87 - 88 - mutex_lock(&adev->pm.mutex); 89 - 90 - /* smu init only needs to be called at startup, not resume. 91 - * It should be in sw_init, but requires the fw info gathered 92 - * in sw_init from other IP modules. 93 - */ 94 - ret = iceland_smu_init(adev); 95 - if (ret) { 96 - DRM_ERROR("SMU initialization failed\n"); 97 - goto fail; 98 - } 99 - 100 - ret = iceland_smu_start(adev); 101 - if (ret) { 102 - DRM_ERROR("SMU start failed\n"); 103 - goto fail; 104 - } 105 - 106 - mutex_unlock(&adev->pm.mutex); 107 - return 0; 108 - 109 - fail: 110 - adev->firmware.smu_load = false; 111 - mutex_unlock(&adev->pm.mutex); 112 - return -EINVAL; 113 - } 114 - 115 - static int iceland_dpm_hw_fini(void *handle) 116 - { 117 - struct amdgpu_device *adev = (struct amdgpu_device *)handle; 118 - 119 - mutex_lock(&adev->pm.mutex); 120 - /* smu fini only needs to be called at teardown, not suspend. 121 - * It should be in sw_fini, but we put it here for symmetry 122 - * with smu init. 123 - */ 124 - iceland_smu_fini(adev); 125 - mutex_unlock(&adev->pm.mutex); 126 - return 0; 127 - } 128 - 129 - static int iceland_dpm_suspend(void *handle) 130 - { 131 - return 0; 132 - } 133 - 134 - static int iceland_dpm_resume(void *handle) 135 - { 136 - int ret; 137 - struct amdgpu_device *adev = (struct amdgpu_device *)handle; 138 - 139 - mutex_lock(&adev->pm.mutex); 140 - 141 - ret = iceland_smu_start(adev); 142 - if (ret) { 143 - DRM_ERROR("SMU start failed\n"); 144 - goto fail; 145 - } 146 - 147 - fail: 148 - mutex_unlock(&adev->pm.mutex); 149 - return ret; 150 - } 151 - 152 - static int iceland_dpm_set_clockgating_state(void *handle, 153 - enum amd_clockgating_state state) 154 - { 155 - return 0; 156 - } 157 - 158 - static int iceland_dpm_set_powergating_state(void *handle, 159 - enum amd_powergating_state state) 160 - { 161 - return 0; 162 - } 163 - 164 - const struct amd_ip_funcs iceland_dpm_ip_funcs = { 165 - .name = "iceland_dpm", 166 - .early_init = iceland_dpm_early_init, 167 - .late_init = NULL, 168 - .sw_init = iceland_dpm_sw_init, 169 - .sw_fini = iceland_dpm_sw_fini, 170 - .hw_init = iceland_dpm_hw_init, 171 - .hw_fini = iceland_dpm_hw_fini, 172 - .suspend = iceland_dpm_suspend, 173 - .resume = iceland_dpm_resume, 174 - .is_idle = NULL, 175 - .wait_for_idle = NULL, 176 - .soft_reset = NULL, 177 - .set_clockgating_state = iceland_dpm_set_clockgating_state, 178 - .set_powergating_state = iceland_dpm_set_powergating_state, 179 - }; 180 - 181 - static const struct amdgpu_dpm_funcs iceland_dpm_funcs = { 182 - .get_temperature = NULL, 183 - .pre_set_power_state = NULL, 184 - .set_power_state = NULL, 185 - .post_set_power_state = NULL, 186 - .display_configuration_changed = NULL, 187 - .get_sclk = NULL, 188 - .get_mclk = NULL, 189 - .print_power_state = NULL, 190 - .debugfs_print_current_performance_level = NULL, 191 - .force_performance_level = NULL, 192 - .vblank_too_short = NULL, 193 - .powergate_uvd = NULL, 194 - }; 195 - 196 - static void iceland_dpm_set_funcs(struct amdgpu_device *adev) 197 - { 198 - if (NULL == adev->pm.funcs) 199 - adev->pm.funcs = &iceland_dpm_funcs; 200 - }
-677
drivers/gpu/drm/amd/amdgpu/iceland_smc.c
··· 1 - /* 2 - * Copyright 2014 Advanced Micro Devices, Inc. 3 - * 4 - * Permission is hereby granted, free of charge, to any person obtaining a 5 - * copy of this software and associated documentation files (the "Software"), 6 - * to deal in the Software without restriction, including without limitation 7 - * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 - * and/or sell copies of the Software, and to permit persons to whom the 9 - * Software is furnished to do so, subject to the following conditions: 10 - * 11 - * The above copyright notice and this permission notice shall be included in 12 - * all copies or substantial portions of the Software. 13 - * 14 - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 18 - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19 - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20 - * OTHER DEALINGS IN THE SOFTWARE. 21 - * 22 - */ 23 - 24 - #include <linux/firmware.h> 25 - #include "drmP.h" 26 - #include "amdgpu.h" 27 - #include "ppsmc.h" 28 - #include "iceland_smum.h" 29 - #include "smu_ucode_xfer_vi.h" 30 - #include "amdgpu_ucode.h" 31 - 32 - #include "smu/smu_7_1_1_d.h" 33 - #include "smu/smu_7_1_1_sh_mask.h" 34 - 35 - #define ICELAND_SMC_SIZE 0x20000 36 - 37 - static int iceland_set_smc_sram_address(struct amdgpu_device *adev, 38 - uint32_t smc_address, uint32_t limit) 39 - { 40 - uint32_t val; 41 - 42 - if (smc_address & 3) 43 - return -EINVAL; 44 - 45 - if ((smc_address + 3) > limit) 46 - return -EINVAL; 47 - 48 - WREG32(mmSMC_IND_INDEX_0, smc_address); 49 - 50 - val = RREG32(mmSMC_IND_ACCESS_CNTL); 51 - val = REG_SET_FIELD(val, SMC_IND_ACCESS_CNTL, AUTO_INCREMENT_IND_0, 0); 52 - WREG32(mmSMC_IND_ACCESS_CNTL, val); 53 - 54 - return 0; 55 - } 56 - 57 - static int iceland_copy_bytes_to_smc(struct amdgpu_device *adev, 58 - uint32_t smc_start_address, 59 - const uint8_t *src, 60 - uint32_t byte_count, uint32_t limit) 61 - { 62 - uint32_t addr; 63 - uint32_t data, orig_data; 64 - int result = 0; 65 - uint32_t extra_shift; 66 - unsigned long flags; 67 - 68 - if (smc_start_address & 3) 69 - return -EINVAL; 70 - 71 - if ((smc_start_address + byte_count) > limit) 72 - return -EINVAL; 73 - 74 - addr = smc_start_address; 75 - 76 - spin_lock_irqsave(&adev->smc_idx_lock, flags); 77 - while (byte_count >= 4) { 78 - /* Bytes are written into the SMC addres space with the MSB first */ 79 - data = (src[0] << 24) + (src[1] << 16) + (src[2] << 8) + src[3]; 80 - 81 - result = iceland_set_smc_sram_address(adev, addr, limit); 82 - 83 - if (result) 84 - goto out; 85 - 86 - WREG32(mmSMC_IND_DATA_0, data); 87 - 88 - src += 4; 89 - byte_count -= 4; 90 - addr += 4; 91 - } 92 - 93 - if (0 != byte_count) { 94 - /* Now write odd bytes left, do a read modify write cycle */ 95 - data = 0; 96 - 97 - result = iceland_set_smc_sram_address(adev, addr, limit); 98 - if (result) 99 - goto out; 100 - 101 - orig_data = RREG32(mmSMC_IND_DATA_0); 102 - extra_shift = 8 * (4 - byte_count); 103 - 104 - while (byte_count > 0) { 105 - data = (data << 8) + *src++; 106 - byte_count--; 107 - } 108 - 109 - data <<= extra_shift; 110 - data |= (orig_data & ~((~0UL) << extra_shift)); 111 - 112 - result = iceland_set_smc_sram_address(adev, addr, limit); 113 - if (result) 114 - goto out; 115 - 116 - WREG32(mmSMC_IND_DATA_0, data); 117 - } 118 - 119 - out: 120 - spin_unlock_irqrestore(&adev->smc_idx_lock, flags); 121 - return result; 122 - } 123 - 124 - static void iceland_start_smc(struct amdgpu_device *adev) 125 - { 126 - uint32_t val = RREG32_SMC(ixSMC_SYSCON_RESET_CNTL); 127 - 128 - val = REG_SET_FIELD(val, SMC_SYSCON_RESET_CNTL, rst_reg, 0); 129 - WREG32_SMC(ixSMC_SYSCON_RESET_CNTL, val); 130 - } 131 - 132 - static void iceland_reset_smc(struct amdgpu_device *adev) 133 - { 134 - uint32_t val = RREG32_SMC(ixSMC_SYSCON_RESET_CNTL); 135 - 136 - val = REG_SET_FIELD(val, SMC_SYSCON_RESET_CNTL, rst_reg, 1); 137 - WREG32_SMC(ixSMC_SYSCON_RESET_CNTL, val); 138 - } 139 - 140 - static int iceland_program_jump_on_start(struct amdgpu_device *adev) 141 - { 142 - static unsigned char data[] = {0xE0, 0x00, 0x80, 0x40}; 143 - iceland_copy_bytes_to_smc(adev, 0x0, data, 4, sizeof(data)+1); 144 - 145 - return 0; 146 - } 147 - 148 - static void iceland_stop_smc_clock(struct amdgpu_device *adev) 149 - { 150 - uint32_t val = RREG32_SMC(ixSMC_SYSCON_CLOCK_CNTL_0); 151 - 152 - val = REG_SET_FIELD(val, SMC_SYSCON_CLOCK_CNTL_0, ck_disable, 1); 153 - WREG32_SMC(ixSMC_SYSCON_CLOCK_CNTL_0, val); 154 - } 155 - 156 - static void iceland_start_smc_clock(struct amdgpu_device *adev) 157 - { 158 - uint32_t val = RREG32_SMC(ixSMC_SYSCON_CLOCK_CNTL_0); 159 - 160 - val = REG_SET_FIELD(val, SMC_SYSCON_CLOCK_CNTL_0, ck_disable, 0); 161 - WREG32_SMC(ixSMC_SYSCON_CLOCK_CNTL_0, val); 162 - } 163 - 164 - static bool iceland_is_smc_ram_running(struct amdgpu_device *adev) 165 - { 166 - uint32_t val = RREG32_SMC(ixSMC_SYSCON_CLOCK_CNTL_0); 167 - val = REG_GET_FIELD(val, SMC_SYSCON_CLOCK_CNTL_0, ck_disable); 168 - 169 - return ((0 == val) && (0x20100 <= RREG32_SMC(ixSMC_PC_C))); 170 - } 171 - 172 - static int wait_smu_response(struct amdgpu_device *adev) 173 - { 174 - int i; 175 - uint32_t val; 176 - 177 - for (i = 0; i < adev->usec_timeout; i++) { 178 - val = RREG32(mmSMC_RESP_0); 179 - if (REG_GET_FIELD(val, SMC_RESP_0, SMC_RESP)) 180 - break; 181 - udelay(1); 182 - } 183 - 184 - if (i == adev->usec_timeout) 185 - return -EINVAL; 186 - 187 - return 0; 188 - } 189 - 190 - static int iceland_send_msg_to_smc(struct amdgpu_device *adev, PPSMC_Msg msg) 191 - { 192 - if (!iceland_is_smc_ram_running(adev)) 193 - return -EINVAL; 194 - 195 - if (wait_smu_response(adev)) { 196 - DRM_ERROR("Failed to send previous message\n"); 197 - return -EINVAL; 198 - } 199 - 200 - WREG32(mmSMC_MESSAGE_0, msg); 201 - 202 - if (wait_smu_response(adev)) { 203 - DRM_ERROR("Failed to send message\n"); 204 - return -EINVAL; 205 - } 206 - 207 - return 0; 208 - } 209 - 210 - static int iceland_send_msg_to_smc_without_waiting(struct amdgpu_device *adev, 211 - PPSMC_Msg msg) 212 - { 213 - if (!iceland_is_smc_ram_running(adev)) 214 - return -EINVAL; 215 - 216 - if (wait_smu_response(adev)) { 217 - DRM_ERROR("Failed to send previous message\n"); 218 - return -EINVAL; 219 - } 220 - 221 - WREG32(mmSMC_MESSAGE_0, msg); 222 - 223 - return 0; 224 - } 225 - 226 - static int iceland_send_msg_to_smc_with_parameter(struct amdgpu_device *adev, 227 - PPSMC_Msg msg, 228 - uint32_t parameter) 229 - { 230 - WREG32(mmSMC_MSG_ARG_0, parameter); 231 - 232 - return iceland_send_msg_to_smc(adev, msg); 233 - } 234 - 235 - static int iceland_send_msg_to_smc_with_parameter_without_waiting( 236 - struct amdgpu_device *adev, 237 - PPSMC_Msg msg, uint32_t parameter) 238 - { 239 - WREG32(mmSMC_MSG_ARG_0, parameter); 240 - 241 - return iceland_send_msg_to_smc_without_waiting(adev, msg); 242 - } 243 - 244 - #if 0 /* not used yet */ 245 - static int iceland_wait_for_smc_inactive(struct amdgpu_device *adev) 246 - { 247 - int i; 248 - uint32_t val; 249 - 250 - if (!iceland_is_smc_ram_running(adev)) 251 - return -EINVAL; 252 - 253 - for (i = 0; i < adev->usec_timeout; i++) { 254 - val = RREG32_SMC(ixSMC_SYSCON_CLOCK_CNTL_0); 255 - if (REG_GET_FIELD(val, SMC_SYSCON_CLOCK_CNTL_0, cken) == 0) 256 - break; 257 - udelay(1); 258 - } 259 - 260 - if (i == adev->usec_timeout) 261 - return -EINVAL; 262 - 263 - return 0; 264 - } 265 - #endif 266 - 267 - static int iceland_smu_upload_firmware_image(struct amdgpu_device *adev) 268 - { 269 - const struct smc_firmware_header_v1_0 *hdr; 270 - uint32_t ucode_size; 271 - uint32_t ucode_start_address; 272 - const uint8_t *src; 273 - uint32_t val; 274 - uint32_t byte_count; 275 - uint32_t data; 276 - unsigned long flags; 277 - int i; 278 - 279 - if (!adev->pm.fw) 280 - return -EINVAL; 281 - 282 - /* Skip SMC ucode loading on SR-IOV capable boards. 283 - * vbios does this for us in asic_init in that case. 284 - */ 285 - if (amdgpu_sriov_bios(adev)) 286 - return 0; 287 - 288 - hdr = (const struct smc_firmware_header_v1_0 *)adev->pm.fw->data; 289 - amdgpu_ucode_print_smc_hdr(&hdr->header); 290 - 291 - adev->pm.fw_version = le32_to_cpu(hdr->header.ucode_version); 292 - ucode_size = le32_to_cpu(hdr->header.ucode_size_bytes); 293 - ucode_start_address = le32_to_cpu(hdr->ucode_start_addr); 294 - src = (const uint8_t *) 295 - (adev->pm.fw->data + le32_to_cpu(hdr->header.ucode_array_offset_bytes)); 296 - 297 - if (ucode_size & 3) { 298 - DRM_ERROR("SMC ucode is not 4 bytes aligned\n"); 299 - return -EINVAL; 300 - } 301 - 302 - if (ucode_size > ICELAND_SMC_SIZE) { 303 - DRM_ERROR("SMC address is beyond the SMC RAM area\n"); 304 - return -EINVAL; 305 - } 306 - 307 - for (i = 0; i < adev->usec_timeout; i++) { 308 - val = RREG32_SMC(ixRCU_UC_EVENTS); 309 - if (REG_GET_FIELD(val, RCU_UC_EVENTS, boot_seq_done) == 0) 310 - break; 311 - udelay(1); 312 - } 313 - val = RREG32_SMC(ixSMC_SYSCON_MISC_CNTL); 314 - WREG32_SMC(ixSMC_SYSCON_MISC_CNTL, val | 1); 315 - 316 - iceland_stop_smc_clock(adev); 317 - iceland_reset_smc(adev); 318 - 319 - spin_lock_irqsave(&adev->smc_idx_lock, flags); 320 - WREG32(mmSMC_IND_INDEX_0, ucode_start_address); 321 - 322 - val = RREG32(mmSMC_IND_ACCESS_CNTL); 323 - val = REG_SET_FIELD(val, SMC_IND_ACCESS_CNTL, AUTO_INCREMENT_IND_0, 1); 324 - WREG32(mmSMC_IND_ACCESS_CNTL, val); 325 - 326 - byte_count = ucode_size; 327 - while (byte_count >= 4) { 328 - data = (src[0] << 24) + (src[1] << 16) + (src[2] << 8) + src[3]; 329 - WREG32(mmSMC_IND_DATA_0, data); 330 - src += 4; 331 - byte_count -= 4; 332 - } 333 - val = RREG32(mmSMC_IND_ACCESS_CNTL); 334 - val = REG_SET_FIELD(val, SMC_IND_ACCESS_CNTL, AUTO_INCREMENT_IND_0, 0); 335 - WREG32(mmSMC_IND_ACCESS_CNTL, val); 336 - spin_unlock_irqrestore(&adev->smc_idx_lock, flags); 337 - 338 - return 0; 339 - } 340 - 341 - #if 0 /* not used yet */ 342 - static int iceland_read_smc_sram_dword(struct amdgpu_device *adev, 343 - uint32_t smc_address, 344 - uint32_t *value, 345 - uint32_t limit) 346 - { 347 - int result; 348 - unsigned long flags; 349 - 350 - spin_lock_irqsave(&adev->smc_idx_lock, flags); 351 - result = iceland_set_smc_sram_address(adev, smc_address, limit); 352 - if (result == 0) 353 - *value = RREG32(mmSMC_IND_DATA_0); 354 - spin_unlock_irqrestore(&adev->smc_idx_lock, flags); 355 - return result; 356 - } 357 - 358 - static int iceland_write_smc_sram_dword(struct amdgpu_device *adev, 359 - uint32_t smc_address, 360 - uint32_t value, 361 - uint32_t limit) 362 - { 363 - int result; 364 - unsigned long flags; 365 - 366 - spin_lock_irqsave(&adev->smc_idx_lock, flags); 367 - result = iceland_set_smc_sram_address(adev, smc_address, limit); 368 - if (result == 0) 369 - WREG32(mmSMC_IND_DATA_0, value); 370 - spin_unlock_irqrestore(&adev->smc_idx_lock, flags); 371 - return result; 372 - } 373 - 374 - static int iceland_smu_stop_smc(struct amdgpu_device *adev) 375 - { 376 - iceland_reset_smc(adev); 377 - iceland_stop_smc_clock(adev); 378 - 379 - return 0; 380 - } 381 - #endif 382 - 383 - static int iceland_smu_start_smc(struct amdgpu_device *adev) 384 - { 385 - int i; 386 - uint32_t val; 387 - 388 - iceland_program_jump_on_start(adev); 389 - iceland_start_smc_clock(adev); 390 - iceland_start_smc(adev); 391 - 392 - for (i = 0; i < adev->usec_timeout; i++) { 393 - val = RREG32_SMC(ixFIRMWARE_FLAGS); 394 - if (REG_GET_FIELD(val, FIRMWARE_FLAGS, INTERRUPTS_ENABLED) == 1) 395 - break; 396 - udelay(1); 397 - } 398 - return 0; 399 - } 400 - 401 - static enum AMDGPU_UCODE_ID iceland_convert_fw_type(uint32_t fw_type) 402 - { 403 - switch (fw_type) { 404 - case UCODE_ID_SDMA0: 405 - return AMDGPU_UCODE_ID_SDMA0; 406 - case UCODE_ID_SDMA1: 407 - return AMDGPU_UCODE_ID_SDMA1; 408 - case UCODE_ID_CP_CE: 409 - return AMDGPU_UCODE_ID_CP_CE; 410 - case UCODE_ID_CP_PFP: 411 - return AMDGPU_UCODE_ID_CP_PFP; 412 - case UCODE_ID_CP_ME: 413 - return AMDGPU_UCODE_ID_CP_ME; 414 - case UCODE_ID_CP_MEC: 415 - case UCODE_ID_CP_MEC_JT1: 416 - return AMDGPU_UCODE_ID_CP_MEC1; 417 - case UCODE_ID_CP_MEC_JT2: 418 - return AMDGPU_UCODE_ID_CP_MEC2; 419 - case UCODE_ID_RLC_G: 420 - return AMDGPU_UCODE_ID_RLC_G; 421 - default: 422 - DRM_ERROR("ucode type is out of range!\n"); 423 - return AMDGPU_UCODE_ID_MAXIMUM; 424 - } 425 - } 426 - 427 - static uint32_t iceland_smu_get_mask_for_fw_type(uint32_t fw_type) 428 - { 429 - switch (fw_type) { 430 - case AMDGPU_UCODE_ID_SDMA0: 431 - return UCODE_ID_SDMA0_MASK; 432 - case AMDGPU_UCODE_ID_SDMA1: 433 - return UCODE_ID_SDMA1_MASK; 434 - case AMDGPU_UCODE_ID_CP_CE: 435 - return UCODE_ID_CP_CE_MASK; 436 - case AMDGPU_UCODE_ID_CP_PFP: 437 - return UCODE_ID_CP_PFP_MASK; 438 - case AMDGPU_UCODE_ID_CP_ME: 439 - return UCODE_ID_CP_ME_MASK; 440 - case AMDGPU_UCODE_ID_CP_MEC1: 441 - return UCODE_ID_CP_MEC_MASK | UCODE_ID_CP_MEC_JT1_MASK; 442 - case AMDGPU_UCODE_ID_CP_MEC2: 443 - return UCODE_ID_CP_MEC_MASK; 444 - case AMDGPU_UCODE_ID_RLC_G: 445 - return UCODE_ID_RLC_G_MASK; 446 - default: 447 - DRM_ERROR("ucode type is out of range!\n"); 448 - return 0; 449 - } 450 - } 451 - 452 - static int iceland_smu_populate_single_firmware_entry(struct amdgpu_device *adev, 453 - uint32_t fw_type, 454 - struct SMU_Entry *entry) 455 - { 456 - enum AMDGPU_UCODE_ID id = iceland_convert_fw_type(fw_type); 457 - struct amdgpu_firmware_info *ucode = &adev->firmware.ucode[id]; 458 - const struct gfx_firmware_header_v1_0 *header = NULL; 459 - uint64_t gpu_addr; 460 - uint32_t data_size; 461 - 462 - if (ucode->fw == NULL) 463 - return -EINVAL; 464 - 465 - gpu_addr = ucode->mc_addr; 466 - header = (const struct gfx_firmware_header_v1_0 *)ucode->fw->data; 467 - data_size = le32_to_cpu(header->header.ucode_size_bytes); 468 - 469 - entry->version = (uint16_t)le32_to_cpu(header->header.ucode_version); 470 - entry->id = (uint16_t)fw_type; 471 - entry->image_addr_high = upper_32_bits(gpu_addr); 472 - entry->image_addr_low = lower_32_bits(gpu_addr); 473 - entry->meta_data_addr_high = 0; 474 - entry->meta_data_addr_low = 0; 475 - entry->data_size_byte = data_size; 476 - entry->num_register_entries = 0; 477 - entry->flags = 0; 478 - 479 - return 0; 480 - } 481 - 482 - static int iceland_smu_request_load_fw(struct amdgpu_device *adev) 483 - { 484 - struct iceland_smu_private_data *private = (struct iceland_smu_private_data *)adev->smu.priv; 485 - struct SMU_DRAMData_TOC *toc; 486 - uint32_t fw_to_load; 487 - 488 - toc = (struct SMU_DRAMData_TOC *)private->header; 489 - toc->num_entries = 0; 490 - toc->structure_version = 1; 491 - 492 - if (!adev->firmware.smu_load) 493 - return 0; 494 - 495 - if (iceland_smu_populate_single_firmware_entry(adev, UCODE_ID_RLC_G, 496 - &toc->entry[toc->num_entries++])) { 497 - DRM_ERROR("Failed to get firmware entry for RLC\n"); 498 - return -EINVAL; 499 - } 500 - 501 - if (iceland_smu_populate_single_firmware_entry(adev, UCODE_ID_CP_CE, 502 - &toc->entry[toc->num_entries++])) { 503 - DRM_ERROR("Failed to get firmware entry for CE\n"); 504 - return -EINVAL; 505 - } 506 - 507 - if (iceland_smu_populate_single_firmware_entry(adev, UCODE_ID_CP_PFP, 508 - &toc->entry[toc->num_entries++])) { 509 - DRM_ERROR("Failed to get firmware entry for PFP\n"); 510 - return -EINVAL; 511 - } 512 - 513 - if (iceland_smu_populate_single_firmware_entry(adev, UCODE_ID_CP_ME, 514 - &toc->entry[toc->num_entries++])) { 515 - DRM_ERROR("Failed to get firmware entry for ME\n"); 516 - return -EINVAL; 517 - } 518 - 519 - if (iceland_smu_populate_single_firmware_entry(adev, UCODE_ID_CP_MEC, 520 - &toc->entry[toc->num_entries++])) { 521 - DRM_ERROR("Failed to get firmware entry for MEC\n"); 522 - return -EINVAL; 523 - } 524 - 525 - if (iceland_smu_populate_single_firmware_entry(adev, UCODE_ID_CP_MEC_JT1, 526 - &toc->entry[toc->num_entries++])) { 527 - DRM_ERROR("Failed to get firmware entry for MEC_JT1\n"); 528 - return -EINVAL; 529 - } 530 - 531 - if (iceland_smu_populate_single_firmware_entry(adev, UCODE_ID_SDMA0, 532 - &toc->entry[toc->num_entries++])) { 533 - DRM_ERROR("Failed to get firmware entry for SDMA0\n"); 534 - return -EINVAL; 535 - } 536 - 537 - if (iceland_smu_populate_single_firmware_entry(adev, UCODE_ID_SDMA1, 538 - &toc->entry[toc->num_entries++])) { 539 - DRM_ERROR("Failed to get firmware entry for SDMA1\n"); 540 - return -EINVAL; 541 - } 542 - 543 - iceland_send_msg_to_smc_with_parameter(adev, PPSMC_MSG_DRV_DRAM_ADDR_HI, private->header_addr_high); 544 - iceland_send_msg_to_smc_with_parameter(adev, PPSMC_MSG_DRV_DRAM_ADDR_LO, private->header_addr_low); 545 - 546 - fw_to_load = UCODE_ID_RLC_G_MASK | 547 - UCODE_ID_SDMA0_MASK | 548 - UCODE_ID_SDMA1_MASK | 549 - UCODE_ID_CP_CE_MASK | 550 - UCODE_ID_CP_ME_MASK | 551 - UCODE_ID_CP_PFP_MASK | 552 - UCODE_ID_CP_MEC_MASK | 553 - UCODE_ID_CP_MEC_JT1_MASK; 554 - 555 - 556 - if (iceland_send_msg_to_smc_with_parameter_without_waiting(adev, PPSMC_MSG_LoadUcodes, fw_to_load)) { 557 - DRM_ERROR("Fail to request SMU load ucode\n"); 558 - return -EINVAL; 559 - } 560 - 561 - return 0; 562 - } 563 - 564 - static int iceland_smu_check_fw_load_finish(struct amdgpu_device *adev, 565 - uint32_t fw_type) 566 - { 567 - uint32_t fw_mask = iceland_smu_get_mask_for_fw_type(fw_type); 568 - int i; 569 - 570 - for (i = 0; i < adev->usec_timeout; i++) { 571 - if (fw_mask == (RREG32_SMC(ixSOFT_REGISTERS_TABLE_27) & fw_mask)) 572 - break; 573 - udelay(1); 574 - } 575 - 576 - if (i == adev->usec_timeout) { 577 - DRM_ERROR("check firmware loading failed\n"); 578 - return -EINVAL; 579 - } 580 - 581 - return 0; 582 - } 583 - 584 - int iceland_smu_start(struct amdgpu_device *adev) 585 - { 586 - int result; 587 - 588 - result = iceland_smu_upload_firmware_image(adev); 589 - if (result) 590 - return result; 591 - result = iceland_smu_start_smc(adev); 592 - if (result) 593 - return result; 594 - 595 - return iceland_smu_request_load_fw(adev); 596 - } 597 - 598 - static const struct amdgpu_smumgr_funcs iceland_smumgr_funcs = { 599 - .check_fw_load_finish = iceland_smu_check_fw_load_finish, 600 - .request_smu_load_fw = NULL, 601 - .request_smu_specific_fw = NULL, 602 - }; 603 - 604 - int iceland_smu_init(struct amdgpu_device *adev) 605 - { 606 - struct iceland_smu_private_data *private; 607 - uint32_t image_size = ((sizeof(struct SMU_DRAMData_TOC) / 4096) + 1) * 4096; 608 - struct amdgpu_bo **toc_buf = &adev->smu.toc_buf; 609 - uint64_t mc_addr; 610 - void *toc_buf_ptr; 611 - int ret; 612 - 613 - private = kzalloc(sizeof(struct iceland_smu_private_data), GFP_KERNEL); 614 - if (NULL == private) 615 - return -ENOMEM; 616 - 617 - /* allocate firmware buffers */ 618 - if (adev->firmware.smu_load) 619 - amdgpu_ucode_init_bo(adev); 620 - 621 - adev->smu.priv = private; 622 - adev->smu.fw_flags = 0; 623 - 624 - /* Allocate FW image data structure and header buffer */ 625 - ret = amdgpu_bo_create(adev, image_size, PAGE_SIZE, 626 - true, AMDGPU_GEM_DOMAIN_VRAM, 627 - AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED, 628 - NULL, NULL, toc_buf); 629 - if (ret) { 630 - DRM_ERROR("Failed to allocate memory for TOC buffer\n"); 631 - return -ENOMEM; 632 - } 633 - 634 - /* Retrieve GPU address for header buffer and internal buffer */ 635 - ret = amdgpu_bo_reserve(adev->smu.toc_buf, false); 636 - if (ret) { 637 - amdgpu_bo_unref(&adev->smu.toc_buf); 638 - DRM_ERROR("Failed to reserve the TOC buffer\n"); 639 - return -EINVAL; 640 - } 641 - 642 - ret = amdgpu_bo_pin(adev->smu.toc_buf, AMDGPU_GEM_DOMAIN_VRAM, &mc_addr); 643 - if (ret) { 644 - amdgpu_bo_unreserve(adev->smu.toc_buf); 645 - amdgpu_bo_unref(&adev->smu.toc_buf); 646 - DRM_ERROR("Failed to pin the TOC buffer\n"); 647 - return -EINVAL; 648 - } 649 - 650 - ret = amdgpu_bo_kmap(*toc_buf, &toc_buf_ptr); 651 - if (ret) { 652 - amdgpu_bo_unreserve(adev->smu.toc_buf); 653 - amdgpu_bo_unref(&adev->smu.toc_buf); 654 - DRM_ERROR("Failed to map the TOC buffer\n"); 655 - return -EINVAL; 656 - } 657 - 658 - amdgpu_bo_unreserve(adev->smu.toc_buf); 659 - private->header_addr_low = lower_32_bits(mc_addr); 660 - private->header_addr_high = upper_32_bits(mc_addr); 661 - private->header = toc_buf_ptr; 662 - 663 - adev->smu.smumgr_funcs = &iceland_smumgr_funcs; 664 - 665 - return 0; 666 - } 667 - 668 - int iceland_smu_fini(struct amdgpu_device *adev) 669 - { 670 - amdgpu_bo_unref(&adev->smu.toc_buf); 671 - kfree(adev->smu.priv); 672 - adev->smu.priv = NULL; 673 - if (adev->firmware.fw_buf) 674 - amdgpu_ucode_fini_bo(adev); 675 - 676 - return 0; 677 - }
-41
drivers/gpu/drm/amd/amdgpu/iceland_smum.h
··· 1 - /* 2 - * Copyright 2014 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 - #ifndef ICELAND_SMUM_H 25 - #define ICELAND_SMUM_H 26 - 27 - #include "ppsmc.h" 28 - 29 - extern int iceland_smu_init(struct amdgpu_device *adev); 30 - extern int iceland_smu_fini(struct amdgpu_device *adev); 31 - extern int iceland_smu_start(struct amdgpu_device *adev); 32 - 33 - struct iceland_smu_private_data 34 - { 35 - uint8_t *header; 36 - uint8_t *mec_image; 37 - uint32_t header_addr_high; 38 - uint32_t header_addr_low; 39 - }; 40 - 41 - #endif
-186
drivers/gpu/drm/amd/amdgpu/tonga_dpm.c
··· 1 - /* 2 - * Copyright 2014 Advanced Micro Devices, Inc. 3 - * 4 - * Permission is hereby granted, free of charge, to any person obtaining a 5 - * copy of this software and associated documentation files (the "Software"), 6 - * to deal in the Software without restriction, including without limitation 7 - * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 - * and/or sell copies of the Software, and to permit persons to whom the 9 - * Software is furnished to do so, subject to the following conditions: 10 - * 11 - * The above copyright notice and this permission notice shall be included in 12 - * all copies or substantial portions of the Software. 13 - * 14 - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 18 - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19 - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20 - * OTHER DEALINGS IN THE SOFTWARE. 21 - * 22 - */ 23 - 24 - #include <linux/firmware.h> 25 - #include "drmP.h" 26 - #include "amdgpu.h" 27 - #include "tonga_smum.h" 28 - 29 - MODULE_FIRMWARE("amdgpu/tonga_smc.bin"); 30 - 31 - static void tonga_dpm_set_funcs(struct amdgpu_device *adev); 32 - 33 - static int tonga_dpm_early_init(void *handle) 34 - { 35 - struct amdgpu_device *adev = (struct amdgpu_device *)handle; 36 - 37 - tonga_dpm_set_funcs(adev); 38 - 39 - return 0; 40 - } 41 - 42 - static int tonga_dpm_init_microcode(struct amdgpu_device *adev) 43 - { 44 - char fw_name[30] = "amdgpu/tonga_smc.bin"; 45 - int err; 46 - err = request_firmware(&adev->pm.fw, fw_name, adev->dev); 47 - if (err) 48 - goto out; 49 - err = amdgpu_ucode_validate(adev->pm.fw); 50 - 51 - out: 52 - if (err) { 53 - DRM_ERROR("Failed to load firmware \"%s\"", fw_name); 54 - release_firmware(adev->pm.fw); 55 - adev->pm.fw = NULL; 56 - } 57 - return err; 58 - } 59 - 60 - static int tonga_dpm_sw_init(void *handle) 61 - { 62 - int ret; 63 - struct amdgpu_device *adev = (struct amdgpu_device *)handle; 64 - 65 - ret = tonga_dpm_init_microcode(adev); 66 - if (ret) 67 - return ret; 68 - 69 - return 0; 70 - } 71 - 72 - static int tonga_dpm_sw_fini(void *handle) 73 - { 74 - struct amdgpu_device *adev = (struct amdgpu_device *)handle; 75 - 76 - release_firmware(adev->pm.fw); 77 - adev->pm.fw = NULL; 78 - 79 - return 0; 80 - } 81 - 82 - static int tonga_dpm_hw_init(void *handle) 83 - { 84 - int ret; 85 - struct amdgpu_device *adev = (struct amdgpu_device *)handle; 86 - 87 - mutex_lock(&adev->pm.mutex); 88 - 89 - /* smu init only needs to be called at startup, not resume. 90 - * It should be in sw_init, but requires the fw info gathered 91 - * in sw_init from other IP modules. 92 - */ 93 - ret = tonga_smu_init(adev); 94 - if (ret) { 95 - DRM_ERROR("SMU initialization failed\n"); 96 - goto fail; 97 - } 98 - 99 - ret = tonga_smu_start(adev); 100 - if (ret) { 101 - DRM_ERROR("SMU start failed\n"); 102 - goto fail; 103 - } 104 - 105 - mutex_unlock(&adev->pm.mutex); 106 - return 0; 107 - 108 - fail: 109 - adev->firmware.smu_load = false; 110 - mutex_unlock(&adev->pm.mutex); 111 - return -EINVAL; 112 - } 113 - 114 - static int tonga_dpm_hw_fini(void *handle) 115 - { 116 - struct amdgpu_device *adev = (struct amdgpu_device *)handle; 117 - 118 - mutex_lock(&adev->pm.mutex); 119 - /* smu fini only needs to be called at teardown, not suspend. 120 - * It should be in sw_fini, but we put it here for symmetry 121 - * with smu init. 122 - */ 123 - tonga_smu_fini(adev); 124 - mutex_unlock(&adev->pm.mutex); 125 - return 0; 126 - } 127 - 128 - static int tonga_dpm_suspend(void *handle) 129 - { 130 - return tonga_dpm_hw_fini(handle); 131 - } 132 - 133 - static int tonga_dpm_resume(void *handle) 134 - { 135 - return tonga_dpm_hw_init(handle); 136 - } 137 - 138 - static int tonga_dpm_set_clockgating_state(void *handle, 139 - enum amd_clockgating_state state) 140 - { 141 - return 0; 142 - } 143 - 144 - static int tonga_dpm_set_powergating_state(void *handle, 145 - enum amd_powergating_state state) 146 - { 147 - return 0; 148 - } 149 - 150 - const struct amd_ip_funcs tonga_dpm_ip_funcs = { 151 - .name = "tonga_dpm", 152 - .early_init = tonga_dpm_early_init, 153 - .late_init = NULL, 154 - .sw_init = tonga_dpm_sw_init, 155 - .sw_fini = tonga_dpm_sw_fini, 156 - .hw_init = tonga_dpm_hw_init, 157 - .hw_fini = tonga_dpm_hw_fini, 158 - .suspend = tonga_dpm_suspend, 159 - .resume = tonga_dpm_resume, 160 - .is_idle = NULL, 161 - .wait_for_idle = NULL, 162 - .soft_reset = NULL, 163 - .set_clockgating_state = tonga_dpm_set_clockgating_state, 164 - .set_powergating_state = tonga_dpm_set_powergating_state, 165 - }; 166 - 167 - static const struct amdgpu_dpm_funcs tonga_dpm_funcs = { 168 - .get_temperature = NULL, 169 - .pre_set_power_state = NULL, 170 - .set_power_state = NULL, 171 - .post_set_power_state = NULL, 172 - .display_configuration_changed = NULL, 173 - .get_sclk = NULL, 174 - .get_mclk = NULL, 175 - .print_power_state = NULL, 176 - .debugfs_print_current_performance_level = NULL, 177 - .force_performance_level = NULL, 178 - .vblank_too_short = NULL, 179 - .powergate_uvd = NULL, 180 - }; 181 - 182 - static void tonga_dpm_set_funcs(struct amdgpu_device *adev) 183 - { 184 - if (NULL == adev->pm.funcs) 185 - adev->pm.funcs = &tonga_dpm_funcs; 186 - }
-862
drivers/gpu/drm/amd/amdgpu/tonga_smc.c
··· 1 - /* 2 - * Copyright 2014 Advanced Micro Devices, Inc. 3 - * 4 - * Permission is hereby granted, free of charge, to any person obtaining a 5 - * copy of this software and associated documentation files (the "Software"), 6 - * to deal in the Software without restriction, including without limitation 7 - * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 - * and/or sell copies of the Software, and to permit persons to whom the 9 - * Software is furnished to do so, subject to the following conditions: 10 - * 11 - * The above copyright notice and this permission notice shall be included in 12 - * all copies or substantial portions of the Software. 13 - * 14 - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 18 - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19 - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20 - * OTHER DEALINGS IN THE SOFTWARE. 21 - * 22 - */ 23 - 24 - #include <linux/firmware.h> 25 - #include "drmP.h" 26 - #include "amdgpu.h" 27 - #include "tonga_ppsmc.h" 28 - #include "tonga_smum.h" 29 - #include "smu_ucode_xfer_vi.h" 30 - #include "amdgpu_ucode.h" 31 - 32 - #include "smu/smu_7_1_2_d.h" 33 - #include "smu/smu_7_1_2_sh_mask.h" 34 - 35 - #define TONGA_SMC_SIZE 0x20000 36 - 37 - static int tonga_set_smc_sram_address(struct amdgpu_device *adev, uint32_t smc_address, uint32_t limit) 38 - { 39 - uint32_t val; 40 - 41 - if (smc_address & 3) 42 - return -EINVAL; 43 - 44 - if ((smc_address + 3) > limit) 45 - return -EINVAL; 46 - 47 - WREG32(mmSMC_IND_INDEX_0, smc_address); 48 - 49 - val = RREG32(mmSMC_IND_ACCESS_CNTL); 50 - val = REG_SET_FIELD(val, SMC_IND_ACCESS_CNTL, AUTO_INCREMENT_IND_0, 0); 51 - WREG32(mmSMC_IND_ACCESS_CNTL, val); 52 - 53 - return 0; 54 - } 55 - 56 - static int tonga_copy_bytes_to_smc(struct amdgpu_device *adev, uint32_t smc_start_address, const uint8_t *src, uint32_t byte_count, uint32_t limit) 57 - { 58 - uint32_t addr; 59 - uint32_t data, orig_data; 60 - int result = 0; 61 - uint32_t extra_shift; 62 - unsigned long flags; 63 - 64 - if (smc_start_address & 3) 65 - return -EINVAL; 66 - 67 - if ((smc_start_address + byte_count) > limit) 68 - return -EINVAL; 69 - 70 - addr = smc_start_address; 71 - 72 - spin_lock_irqsave(&adev->smc_idx_lock, flags); 73 - while (byte_count >= 4) { 74 - /* Bytes are written into the SMC addres space with the MSB first */ 75 - data = (src[0] << 24) + (src[1] << 16) + (src[2] << 8) + src[3]; 76 - 77 - result = tonga_set_smc_sram_address(adev, addr, limit); 78 - 79 - if (result) 80 - goto out; 81 - 82 - WREG32(mmSMC_IND_DATA_0, data); 83 - 84 - src += 4; 85 - byte_count -= 4; 86 - addr += 4; 87 - } 88 - 89 - if (0 != byte_count) { 90 - /* Now write odd bytes left, do a read modify write cycle */ 91 - data = 0; 92 - 93 - result = tonga_set_smc_sram_address(adev, addr, limit); 94 - if (result) 95 - goto out; 96 - 97 - orig_data = RREG32(mmSMC_IND_DATA_0); 98 - extra_shift = 8 * (4 - byte_count); 99 - 100 - while (byte_count > 0) { 101 - data = (data << 8) + *src++; 102 - byte_count--; 103 - } 104 - 105 - data <<= extra_shift; 106 - data |= (orig_data & ~((~0UL) << extra_shift)); 107 - 108 - result = tonga_set_smc_sram_address(adev, addr, limit); 109 - if (result) 110 - goto out; 111 - 112 - WREG32(mmSMC_IND_DATA_0, data); 113 - } 114 - 115 - out: 116 - spin_unlock_irqrestore(&adev->smc_idx_lock, flags); 117 - return result; 118 - } 119 - 120 - static int tonga_program_jump_on_start(struct amdgpu_device *adev) 121 - { 122 - static unsigned char data[] = {0xE0, 0x00, 0x80, 0x40}; 123 - tonga_copy_bytes_to_smc(adev, 0x0, data, 4, sizeof(data)+1); 124 - 125 - return 0; 126 - } 127 - 128 - static bool tonga_is_smc_ram_running(struct amdgpu_device *adev) 129 - { 130 - uint32_t val = RREG32_SMC(ixSMC_SYSCON_CLOCK_CNTL_0); 131 - val = REG_GET_FIELD(val, SMC_SYSCON_CLOCK_CNTL_0, ck_disable); 132 - 133 - return ((0 == val) && (0x20100 <= RREG32_SMC(ixSMC_PC_C))); 134 - } 135 - 136 - static int wait_smu_response(struct amdgpu_device *adev) 137 - { 138 - int i; 139 - uint32_t val; 140 - 141 - for (i = 0; i < adev->usec_timeout; i++) { 142 - val = RREG32(mmSMC_RESP_0); 143 - if (REG_GET_FIELD(val, SMC_RESP_0, SMC_RESP)) 144 - break; 145 - udelay(1); 146 - } 147 - 148 - if (i == adev->usec_timeout) 149 - return -EINVAL; 150 - 151 - return 0; 152 - } 153 - 154 - static int tonga_send_msg_to_smc_offset(struct amdgpu_device *adev) 155 - { 156 - if (wait_smu_response(adev)) { 157 - DRM_ERROR("Failed to send previous message\n"); 158 - return -EINVAL; 159 - } 160 - 161 - WREG32(mmSMC_MSG_ARG_0, 0x20000); 162 - WREG32(mmSMC_MESSAGE_0, PPSMC_MSG_Test); 163 - 164 - if (wait_smu_response(adev)) { 165 - DRM_ERROR("Failed to send message\n"); 166 - return -EINVAL; 167 - } 168 - 169 - return 0; 170 - } 171 - 172 - static int tonga_send_msg_to_smc(struct amdgpu_device *adev, PPSMC_Msg msg) 173 - { 174 - if (!tonga_is_smc_ram_running(adev)) 175 - { 176 - return -EINVAL; 177 - } 178 - 179 - if (wait_smu_response(adev)) { 180 - DRM_ERROR("Failed to send previous message\n"); 181 - return -EINVAL; 182 - } 183 - 184 - WREG32(mmSMC_MESSAGE_0, msg); 185 - 186 - if (wait_smu_response(adev)) { 187 - DRM_ERROR("Failed to send message\n"); 188 - return -EINVAL; 189 - } 190 - 191 - return 0; 192 - } 193 - 194 - static int tonga_send_msg_to_smc_without_waiting(struct amdgpu_device *adev, 195 - PPSMC_Msg msg) 196 - { 197 - if (wait_smu_response(adev)) { 198 - DRM_ERROR("Failed to send previous message\n"); 199 - return -EINVAL; 200 - } 201 - 202 - WREG32(mmSMC_MESSAGE_0, msg); 203 - 204 - return 0; 205 - } 206 - 207 - static int tonga_send_msg_to_smc_with_parameter(struct amdgpu_device *adev, 208 - PPSMC_Msg msg, 209 - uint32_t parameter) 210 - { 211 - if (!tonga_is_smc_ram_running(adev)) 212 - return -EINVAL; 213 - 214 - if (wait_smu_response(adev)) { 215 - DRM_ERROR("Failed to send previous message\n"); 216 - return -EINVAL; 217 - } 218 - 219 - WREG32(mmSMC_MSG_ARG_0, parameter); 220 - 221 - return tonga_send_msg_to_smc(adev, msg); 222 - } 223 - 224 - static int tonga_send_msg_to_smc_with_parameter_without_waiting( 225 - struct amdgpu_device *adev, 226 - PPSMC_Msg msg, uint32_t parameter) 227 - { 228 - if (wait_smu_response(adev)) { 229 - DRM_ERROR("Failed to send previous message\n"); 230 - return -EINVAL; 231 - } 232 - 233 - WREG32(mmSMC_MSG_ARG_0, parameter); 234 - 235 - return tonga_send_msg_to_smc_without_waiting(adev, msg); 236 - } 237 - 238 - #if 0 /* not used yet */ 239 - static int tonga_wait_for_smc_inactive(struct amdgpu_device *adev) 240 - { 241 - int i; 242 - uint32_t val; 243 - 244 - if (!tonga_is_smc_ram_running(adev)) 245 - return -EINVAL; 246 - 247 - for (i = 0; i < adev->usec_timeout; i++) { 248 - val = RREG32_SMC(ixSMC_SYSCON_CLOCK_CNTL_0); 249 - if (REG_GET_FIELD(val, SMC_SYSCON_CLOCK_CNTL_0, cken) == 0) 250 - break; 251 - udelay(1); 252 - } 253 - 254 - if (i == adev->usec_timeout) 255 - return -EINVAL; 256 - 257 - return 0; 258 - } 259 - #endif 260 - 261 - static int tonga_smu_upload_firmware_image(struct amdgpu_device *adev) 262 - { 263 - const struct smc_firmware_header_v1_0 *hdr; 264 - uint32_t ucode_size; 265 - uint32_t ucode_start_address; 266 - const uint8_t *src; 267 - uint32_t val; 268 - uint32_t byte_count; 269 - uint32_t *data; 270 - unsigned long flags; 271 - 272 - if (!adev->pm.fw) 273 - return -EINVAL; 274 - 275 - /* Skip SMC ucode loading on SR-IOV capable boards. 276 - * vbios does this for us in asic_init in that case. 277 - */ 278 - if (amdgpu_sriov_bios(adev)) 279 - return 0; 280 - 281 - hdr = (const struct smc_firmware_header_v1_0 *)adev->pm.fw->data; 282 - amdgpu_ucode_print_smc_hdr(&hdr->header); 283 - 284 - adev->pm.fw_version = le32_to_cpu(hdr->header.ucode_version); 285 - ucode_size = le32_to_cpu(hdr->header.ucode_size_bytes); 286 - ucode_start_address = le32_to_cpu(hdr->ucode_start_addr); 287 - src = (const uint8_t *) 288 - (adev->pm.fw->data + le32_to_cpu(hdr->header.ucode_array_offset_bytes)); 289 - 290 - if (ucode_size & 3) { 291 - DRM_ERROR("SMC ucode is not 4 bytes aligned\n"); 292 - return -EINVAL; 293 - } 294 - 295 - if (ucode_size > TONGA_SMC_SIZE) { 296 - DRM_ERROR("SMC address is beyond the SMC RAM area\n"); 297 - return -EINVAL; 298 - } 299 - 300 - spin_lock_irqsave(&adev->smc_idx_lock, flags); 301 - WREG32(mmSMC_IND_INDEX_0, ucode_start_address); 302 - 303 - val = RREG32(mmSMC_IND_ACCESS_CNTL); 304 - val = REG_SET_FIELD(val, SMC_IND_ACCESS_CNTL, AUTO_INCREMENT_IND_0, 1); 305 - WREG32(mmSMC_IND_ACCESS_CNTL, val); 306 - 307 - byte_count = ucode_size; 308 - data = (uint32_t *)src; 309 - for (; byte_count >= 4; data++, byte_count -= 4) 310 - WREG32(mmSMC_IND_DATA_0, data[0]); 311 - 312 - val = RREG32(mmSMC_IND_ACCESS_CNTL); 313 - val = REG_SET_FIELD(val, SMC_IND_ACCESS_CNTL, AUTO_INCREMENT_IND_0, 0); 314 - WREG32(mmSMC_IND_ACCESS_CNTL, val); 315 - spin_unlock_irqrestore(&adev->smc_idx_lock, flags); 316 - 317 - return 0; 318 - } 319 - 320 - #if 0 /* not used yet */ 321 - static int tonga_read_smc_sram_dword(struct amdgpu_device *adev, 322 - uint32_t smc_address, 323 - uint32_t *value, 324 - uint32_t limit) 325 - { 326 - int result; 327 - unsigned long flags; 328 - 329 - spin_lock_irqsave(&adev->smc_idx_lock, flags); 330 - result = tonga_set_smc_sram_address(adev, smc_address, limit); 331 - if (result == 0) 332 - *value = RREG32(mmSMC_IND_DATA_0); 333 - spin_unlock_irqrestore(&adev->smc_idx_lock, flags); 334 - return result; 335 - } 336 - 337 - static int tonga_write_smc_sram_dword(struct amdgpu_device *adev, 338 - uint32_t smc_address, 339 - uint32_t value, 340 - uint32_t limit) 341 - { 342 - int result; 343 - unsigned long flags; 344 - 345 - spin_lock_irqsave(&adev->smc_idx_lock, flags); 346 - result = tonga_set_smc_sram_address(adev, smc_address, limit); 347 - if (result == 0) 348 - WREG32(mmSMC_IND_DATA_0, value); 349 - spin_unlock_irqrestore(&adev->smc_idx_lock, flags); 350 - return result; 351 - } 352 - 353 - static int tonga_smu_stop_smc(struct amdgpu_device *adev) 354 - { 355 - uint32_t val = RREG32_SMC(ixSMC_SYSCON_RESET_CNTL); 356 - val = REG_SET_FIELD(val, SMC_SYSCON_RESET_CNTL, rst_reg, 1); 357 - WREG32_SMC(ixSMC_SYSCON_RESET_CNTL, val); 358 - 359 - val = RREG32_SMC(ixSMC_SYSCON_CLOCK_CNTL_0); 360 - val = REG_SET_FIELD(val, SMC_SYSCON_CLOCK_CNTL_0, ck_disable, 1); 361 - WREG32_SMC(ixSMC_SYSCON_CLOCK_CNTL_0, val); 362 - 363 - return 0; 364 - } 365 - #endif 366 - 367 - static enum AMDGPU_UCODE_ID tonga_convert_fw_type(uint32_t fw_type) 368 - { 369 - switch (fw_type) { 370 - case UCODE_ID_SDMA0: 371 - return AMDGPU_UCODE_ID_SDMA0; 372 - case UCODE_ID_SDMA1: 373 - return AMDGPU_UCODE_ID_SDMA1; 374 - case UCODE_ID_CP_CE: 375 - return AMDGPU_UCODE_ID_CP_CE; 376 - case UCODE_ID_CP_PFP: 377 - return AMDGPU_UCODE_ID_CP_PFP; 378 - case UCODE_ID_CP_ME: 379 - return AMDGPU_UCODE_ID_CP_ME; 380 - case UCODE_ID_CP_MEC: 381 - case UCODE_ID_CP_MEC_JT1: 382 - return AMDGPU_UCODE_ID_CP_MEC1; 383 - case UCODE_ID_CP_MEC_JT2: 384 - return AMDGPU_UCODE_ID_CP_MEC2; 385 - case UCODE_ID_RLC_G: 386 - return AMDGPU_UCODE_ID_RLC_G; 387 - default: 388 - DRM_ERROR("ucode type is out of range!\n"); 389 - return AMDGPU_UCODE_ID_MAXIMUM; 390 - } 391 - } 392 - 393 - static int tonga_smu_populate_single_firmware_entry(struct amdgpu_device *adev, 394 - uint32_t fw_type, 395 - struct SMU_Entry *entry) 396 - { 397 - enum AMDGPU_UCODE_ID id = tonga_convert_fw_type(fw_type); 398 - struct amdgpu_firmware_info *ucode = &adev->firmware.ucode[id]; 399 - const struct gfx_firmware_header_v1_0 *header = NULL; 400 - uint64_t gpu_addr; 401 - uint32_t data_size; 402 - 403 - if (ucode->fw == NULL) 404 - return -EINVAL; 405 - 406 - gpu_addr = ucode->mc_addr; 407 - header = (const struct gfx_firmware_header_v1_0 *)ucode->fw->data; 408 - data_size = le32_to_cpu(header->header.ucode_size_bytes); 409 - 410 - if ((fw_type == UCODE_ID_CP_MEC_JT1) || 411 - (fw_type == UCODE_ID_CP_MEC_JT2)) { 412 - gpu_addr += le32_to_cpu(header->jt_offset) << 2; 413 - data_size = le32_to_cpu(header->jt_size) << 2; 414 - } 415 - 416 - entry->version = (uint16_t)le32_to_cpu(header->header.ucode_version); 417 - entry->id = (uint16_t)fw_type; 418 - entry->image_addr_high = upper_32_bits(gpu_addr); 419 - entry->image_addr_low = lower_32_bits(gpu_addr); 420 - entry->meta_data_addr_high = 0; 421 - entry->meta_data_addr_low = 0; 422 - entry->data_size_byte = data_size; 423 - entry->num_register_entries = 0; 424 - 425 - if (fw_type == UCODE_ID_RLC_G) 426 - entry->flags = 1; 427 - else 428 - entry->flags = 0; 429 - 430 - return 0; 431 - } 432 - 433 - static int tonga_smu_request_load_fw(struct amdgpu_device *adev) 434 - { 435 - struct tonga_smu_private_data *private = (struct tonga_smu_private_data *)adev->smu.priv; 436 - struct SMU_DRAMData_TOC *toc; 437 - uint32_t fw_to_load; 438 - 439 - WREG32_SMC(ixSOFT_REGISTERS_TABLE_28, 0); 440 - 441 - tonga_send_msg_to_smc_with_parameter(adev, PPSMC_MSG_SMU_DRAM_ADDR_HI, private->smu_buffer_addr_high); 442 - tonga_send_msg_to_smc_with_parameter(adev, PPSMC_MSG_SMU_DRAM_ADDR_LO, private->smu_buffer_addr_low); 443 - 444 - toc = (struct SMU_DRAMData_TOC *)private->header; 445 - toc->num_entries = 0; 446 - toc->structure_version = 1; 447 - 448 - if (!adev->firmware.smu_load) 449 - return 0; 450 - 451 - if (tonga_smu_populate_single_firmware_entry(adev, UCODE_ID_RLC_G, 452 - &toc->entry[toc->num_entries++])) { 453 - DRM_ERROR("Failed to get firmware entry for RLC\n"); 454 - return -EINVAL; 455 - } 456 - 457 - if (tonga_smu_populate_single_firmware_entry(adev, UCODE_ID_CP_CE, 458 - &toc->entry[toc->num_entries++])) { 459 - DRM_ERROR("Failed to get firmware entry for CE\n"); 460 - return -EINVAL; 461 - } 462 - 463 - if (tonga_smu_populate_single_firmware_entry(adev, UCODE_ID_CP_PFP, 464 - &toc->entry[toc->num_entries++])) { 465 - DRM_ERROR("Failed to get firmware entry for PFP\n"); 466 - return -EINVAL; 467 - } 468 - 469 - if (tonga_smu_populate_single_firmware_entry(adev, UCODE_ID_CP_ME, 470 - &toc->entry[toc->num_entries++])) { 471 - DRM_ERROR("Failed to get firmware entry for ME\n"); 472 - return -EINVAL; 473 - } 474 - 475 - if (tonga_smu_populate_single_firmware_entry(adev, UCODE_ID_CP_MEC, 476 - &toc->entry[toc->num_entries++])) { 477 - DRM_ERROR("Failed to get firmware entry for MEC\n"); 478 - return -EINVAL; 479 - } 480 - 481 - if (tonga_smu_populate_single_firmware_entry(adev, UCODE_ID_CP_MEC_JT1, 482 - &toc->entry[toc->num_entries++])) { 483 - DRM_ERROR("Failed to get firmware entry for MEC_JT1\n"); 484 - return -EINVAL; 485 - } 486 - 487 - if (tonga_smu_populate_single_firmware_entry(adev, UCODE_ID_CP_MEC_JT2, 488 - &toc->entry[toc->num_entries++])) { 489 - DRM_ERROR("Failed to get firmware entry for MEC_JT2\n"); 490 - return -EINVAL; 491 - } 492 - 493 - if (tonga_smu_populate_single_firmware_entry(adev, UCODE_ID_SDMA0, 494 - &toc->entry[toc->num_entries++])) { 495 - DRM_ERROR("Failed to get firmware entry for SDMA0\n"); 496 - return -EINVAL; 497 - } 498 - 499 - if (tonga_smu_populate_single_firmware_entry(adev, UCODE_ID_SDMA1, 500 - &toc->entry[toc->num_entries++])) { 501 - DRM_ERROR("Failed to get firmware entry for SDMA1\n"); 502 - return -EINVAL; 503 - } 504 - 505 - tonga_send_msg_to_smc_with_parameter(adev, PPSMC_MSG_DRV_DRAM_ADDR_HI, private->header_addr_high); 506 - tonga_send_msg_to_smc_with_parameter(adev, PPSMC_MSG_DRV_DRAM_ADDR_LO, private->header_addr_low); 507 - 508 - fw_to_load = UCODE_ID_RLC_G_MASK | 509 - UCODE_ID_SDMA0_MASK | 510 - UCODE_ID_SDMA1_MASK | 511 - UCODE_ID_CP_CE_MASK | 512 - UCODE_ID_CP_ME_MASK | 513 - UCODE_ID_CP_PFP_MASK | 514 - UCODE_ID_CP_MEC_MASK; 515 - 516 - if (tonga_send_msg_to_smc_with_parameter_without_waiting(adev, PPSMC_MSG_LoadUcodes, fw_to_load)) { 517 - DRM_ERROR("Fail to request SMU load ucode\n"); 518 - return -EINVAL; 519 - } 520 - 521 - return 0; 522 - } 523 - 524 - static uint32_t tonga_smu_get_mask_for_fw_type(uint32_t fw_type) 525 - { 526 - switch (fw_type) { 527 - case AMDGPU_UCODE_ID_SDMA0: 528 - return UCODE_ID_SDMA0_MASK; 529 - case AMDGPU_UCODE_ID_SDMA1: 530 - return UCODE_ID_SDMA1_MASK; 531 - case AMDGPU_UCODE_ID_CP_CE: 532 - return UCODE_ID_CP_CE_MASK; 533 - case AMDGPU_UCODE_ID_CP_PFP: 534 - return UCODE_ID_CP_PFP_MASK; 535 - case AMDGPU_UCODE_ID_CP_ME: 536 - return UCODE_ID_CP_ME_MASK; 537 - case AMDGPU_UCODE_ID_CP_MEC1: 538 - return UCODE_ID_CP_MEC_MASK; 539 - case AMDGPU_UCODE_ID_CP_MEC2: 540 - return UCODE_ID_CP_MEC_MASK; 541 - case AMDGPU_UCODE_ID_RLC_G: 542 - return UCODE_ID_RLC_G_MASK; 543 - default: 544 - DRM_ERROR("ucode type is out of range!\n"); 545 - return 0; 546 - } 547 - } 548 - 549 - static int tonga_smu_check_fw_load_finish(struct amdgpu_device *adev, 550 - uint32_t fw_type) 551 - { 552 - uint32_t fw_mask = tonga_smu_get_mask_for_fw_type(fw_type); 553 - int i; 554 - 555 - for (i = 0; i < adev->usec_timeout; i++) { 556 - if (fw_mask == (RREG32_SMC(ixSOFT_REGISTERS_TABLE_28) & fw_mask)) 557 - break; 558 - udelay(1); 559 - } 560 - 561 - if (i == adev->usec_timeout) { 562 - DRM_ERROR("check firmware loading failed\n"); 563 - return -EINVAL; 564 - } 565 - 566 - return 0; 567 - } 568 - 569 - static int tonga_smu_start_in_protection_mode(struct amdgpu_device *adev) 570 - { 571 - int result; 572 - uint32_t val; 573 - int i; 574 - 575 - /* Assert reset */ 576 - val = RREG32_SMC(ixSMC_SYSCON_RESET_CNTL); 577 - val = REG_SET_FIELD(val, SMC_SYSCON_RESET_CNTL, rst_reg, 1); 578 - WREG32_SMC(ixSMC_SYSCON_RESET_CNTL, val); 579 - 580 - result = tonga_smu_upload_firmware_image(adev); 581 - if (result) 582 - return result; 583 - 584 - /* Clear status */ 585 - WREG32_SMC(ixSMU_STATUS, 0); 586 - 587 - /* Enable clock */ 588 - val = RREG32_SMC(ixSMC_SYSCON_CLOCK_CNTL_0); 589 - val = REG_SET_FIELD(val, SMC_SYSCON_CLOCK_CNTL_0, ck_disable, 0); 590 - WREG32_SMC(ixSMC_SYSCON_CLOCK_CNTL_0, val); 591 - 592 - /* De-assert reset */ 593 - val = RREG32_SMC(ixSMC_SYSCON_RESET_CNTL); 594 - val = REG_SET_FIELD(val, SMC_SYSCON_RESET_CNTL, rst_reg, 0); 595 - WREG32_SMC(ixSMC_SYSCON_RESET_CNTL, val); 596 - 597 - /* Set SMU Auto Start */ 598 - val = RREG32_SMC(ixSMU_INPUT_DATA); 599 - val = REG_SET_FIELD(val, SMU_INPUT_DATA, AUTO_START, 1); 600 - WREG32_SMC(ixSMU_INPUT_DATA, val); 601 - 602 - /* Clear firmware interrupt enable flag */ 603 - WREG32_SMC(ixFIRMWARE_FLAGS, 0); 604 - 605 - for (i = 0; i < adev->usec_timeout; i++) { 606 - val = RREG32_SMC(ixRCU_UC_EVENTS); 607 - if (REG_GET_FIELD(val, RCU_UC_EVENTS, INTERRUPTS_ENABLED)) 608 - break; 609 - udelay(1); 610 - } 611 - 612 - if (i == adev->usec_timeout) { 613 - DRM_ERROR("Interrupt is not enabled by firmware\n"); 614 - return -EINVAL; 615 - } 616 - 617 - /* Call Test SMU message with 0x20000 offset 618 - * to trigger SMU start 619 - */ 620 - tonga_send_msg_to_smc_offset(adev); 621 - 622 - /* Wait for done bit to be set */ 623 - for (i = 0; i < adev->usec_timeout; i++) { 624 - val = RREG32_SMC(ixSMU_STATUS); 625 - if (REG_GET_FIELD(val, SMU_STATUS, SMU_DONE)) 626 - break; 627 - udelay(1); 628 - } 629 - 630 - if (i == adev->usec_timeout) { 631 - DRM_ERROR("Timeout for SMU start\n"); 632 - return -EINVAL; 633 - } 634 - 635 - /* Check pass/failed indicator */ 636 - val = RREG32_SMC(ixSMU_STATUS); 637 - if (!REG_GET_FIELD(val, SMU_STATUS, SMU_PASS)) { 638 - DRM_ERROR("SMU Firmware start failed\n"); 639 - return -EINVAL; 640 - } 641 - 642 - /* Wait for firmware to initialize */ 643 - for (i = 0; i < adev->usec_timeout; i++) { 644 - val = RREG32_SMC(ixFIRMWARE_FLAGS); 645 - if(REG_GET_FIELD(val, FIRMWARE_FLAGS, INTERRUPTS_ENABLED)) 646 - break; 647 - udelay(1); 648 - } 649 - 650 - if (i == adev->usec_timeout) { 651 - DRM_ERROR("SMU firmware initialization failed\n"); 652 - return -EINVAL; 653 - } 654 - 655 - return 0; 656 - } 657 - 658 - static int tonga_smu_start_in_non_protection_mode(struct amdgpu_device *adev) 659 - { 660 - int i, result; 661 - uint32_t val; 662 - 663 - /* wait for smc boot up */ 664 - for (i = 0; i < adev->usec_timeout; i++) { 665 - val = RREG32_SMC(ixRCU_UC_EVENTS); 666 - val = REG_GET_FIELD(val, RCU_UC_EVENTS, boot_seq_done); 667 - if (val) 668 - break; 669 - udelay(1); 670 - } 671 - 672 - if (i == adev->usec_timeout) { 673 - DRM_ERROR("SMC boot sequence is not completed\n"); 674 - return -EINVAL; 675 - } 676 - 677 - /* Clear firmware interrupt enable flag */ 678 - WREG32_SMC(ixFIRMWARE_FLAGS, 0); 679 - 680 - /* Assert reset */ 681 - val = RREG32_SMC(ixSMC_SYSCON_RESET_CNTL); 682 - val = REG_SET_FIELD(val, SMC_SYSCON_RESET_CNTL, rst_reg, 1); 683 - WREG32_SMC(ixSMC_SYSCON_RESET_CNTL, val); 684 - 685 - result = tonga_smu_upload_firmware_image(adev); 686 - if (result) 687 - return result; 688 - 689 - /* Set smc instruct start point at 0x0 */ 690 - tonga_program_jump_on_start(adev); 691 - 692 - /* Enable clock */ 693 - val = RREG32_SMC(ixSMC_SYSCON_CLOCK_CNTL_0); 694 - val = REG_SET_FIELD(val, SMC_SYSCON_CLOCK_CNTL_0, ck_disable, 0); 695 - WREG32_SMC(ixSMC_SYSCON_CLOCK_CNTL_0, val); 696 - 697 - /* De-assert reset */ 698 - val = RREG32_SMC(ixSMC_SYSCON_RESET_CNTL); 699 - val = REG_SET_FIELD(val, SMC_SYSCON_RESET_CNTL, rst_reg, 0); 700 - WREG32_SMC(ixSMC_SYSCON_RESET_CNTL, val); 701 - 702 - /* Wait for firmware to initialize */ 703 - for (i = 0; i < adev->usec_timeout; i++) { 704 - val = RREG32_SMC(ixFIRMWARE_FLAGS); 705 - if (REG_GET_FIELD(val, FIRMWARE_FLAGS, INTERRUPTS_ENABLED)) 706 - break; 707 - udelay(1); 708 - } 709 - 710 - if (i == adev->usec_timeout) { 711 - DRM_ERROR("Timeout for SMC firmware initialization\n"); 712 - return -EINVAL; 713 - } 714 - 715 - return 0; 716 - } 717 - 718 - int tonga_smu_start(struct amdgpu_device *adev) 719 - { 720 - int result; 721 - uint32_t val; 722 - 723 - if (!tonga_is_smc_ram_running(adev)) { 724 - val = RREG32_SMC(ixSMU_FIRMWARE); 725 - if (!REG_GET_FIELD(val, SMU_FIRMWARE, SMU_MODE)) { 726 - result = tonga_smu_start_in_non_protection_mode(adev); 727 - if (result) 728 - return result; 729 - } else { 730 - result = tonga_smu_start_in_protection_mode(adev); 731 - if (result) 732 - return result; 733 - } 734 - } 735 - 736 - return tonga_smu_request_load_fw(adev); 737 - } 738 - 739 - static const struct amdgpu_smumgr_funcs tonga_smumgr_funcs = { 740 - .check_fw_load_finish = tonga_smu_check_fw_load_finish, 741 - .request_smu_load_fw = NULL, 742 - .request_smu_specific_fw = NULL, 743 - }; 744 - 745 - int tonga_smu_init(struct amdgpu_device *adev) 746 - { 747 - struct tonga_smu_private_data *private; 748 - uint32_t image_size = ((sizeof(struct SMU_DRAMData_TOC) / 4096) + 1) * 4096; 749 - uint32_t smu_internal_buffer_size = 200*4096; 750 - struct amdgpu_bo **toc_buf = &adev->smu.toc_buf; 751 - struct amdgpu_bo **smu_buf = &adev->smu.smu_buf; 752 - uint64_t mc_addr; 753 - void *toc_buf_ptr; 754 - void *smu_buf_ptr; 755 - int ret; 756 - 757 - private = kzalloc(sizeof(struct tonga_smu_private_data), GFP_KERNEL); 758 - if (NULL == private) 759 - return -ENOMEM; 760 - 761 - /* allocate firmware buffers */ 762 - if (adev->firmware.smu_load) 763 - amdgpu_ucode_init_bo(adev); 764 - 765 - adev->smu.priv = private; 766 - adev->smu.fw_flags = 0; 767 - 768 - /* Allocate FW image data structure and header buffer */ 769 - ret = amdgpu_bo_create(adev, image_size, PAGE_SIZE, 770 - true, AMDGPU_GEM_DOMAIN_VRAM, 771 - AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED, 772 - NULL, NULL, toc_buf); 773 - if (ret) { 774 - DRM_ERROR("Failed to allocate memory for TOC buffer\n"); 775 - return -ENOMEM; 776 - } 777 - 778 - /* Allocate buffer for SMU internal buffer */ 779 - ret = amdgpu_bo_create(adev, smu_internal_buffer_size, PAGE_SIZE, 780 - true, AMDGPU_GEM_DOMAIN_VRAM, 781 - AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED, 782 - NULL, NULL, smu_buf); 783 - if (ret) { 784 - DRM_ERROR("Failed to allocate memory for SMU internal buffer\n"); 785 - return -ENOMEM; 786 - } 787 - 788 - /* Retrieve GPU address for header buffer and internal buffer */ 789 - ret = amdgpu_bo_reserve(adev->smu.toc_buf, false); 790 - if (ret) { 791 - amdgpu_bo_unref(&adev->smu.toc_buf); 792 - DRM_ERROR("Failed to reserve the TOC buffer\n"); 793 - return -EINVAL; 794 - } 795 - 796 - ret = amdgpu_bo_pin(adev->smu.toc_buf, AMDGPU_GEM_DOMAIN_VRAM, &mc_addr); 797 - if (ret) { 798 - amdgpu_bo_unreserve(adev->smu.toc_buf); 799 - amdgpu_bo_unref(&adev->smu.toc_buf); 800 - DRM_ERROR("Failed to pin the TOC buffer\n"); 801 - return -EINVAL; 802 - } 803 - 804 - ret = amdgpu_bo_kmap(*toc_buf, &toc_buf_ptr); 805 - if (ret) { 806 - amdgpu_bo_unreserve(adev->smu.toc_buf); 807 - amdgpu_bo_unref(&adev->smu.toc_buf); 808 - DRM_ERROR("Failed to map the TOC buffer\n"); 809 - return -EINVAL; 810 - } 811 - 812 - amdgpu_bo_unreserve(adev->smu.toc_buf); 813 - private->header_addr_low = lower_32_bits(mc_addr); 814 - private->header_addr_high = upper_32_bits(mc_addr); 815 - private->header = toc_buf_ptr; 816 - 817 - ret = amdgpu_bo_reserve(adev->smu.smu_buf, false); 818 - if (ret) { 819 - amdgpu_bo_unref(&adev->smu.smu_buf); 820 - amdgpu_bo_unref(&adev->smu.toc_buf); 821 - DRM_ERROR("Failed to reserve the SMU internal buffer\n"); 822 - return -EINVAL; 823 - } 824 - 825 - ret = amdgpu_bo_pin(adev->smu.smu_buf, AMDGPU_GEM_DOMAIN_VRAM, &mc_addr); 826 - if (ret) { 827 - amdgpu_bo_unreserve(adev->smu.smu_buf); 828 - amdgpu_bo_unref(&adev->smu.smu_buf); 829 - amdgpu_bo_unref(&adev->smu.toc_buf); 830 - DRM_ERROR("Failed to pin the SMU internal buffer\n"); 831 - return -EINVAL; 832 - } 833 - 834 - ret = amdgpu_bo_kmap(*smu_buf, &smu_buf_ptr); 835 - if (ret) { 836 - amdgpu_bo_unreserve(adev->smu.smu_buf); 837 - amdgpu_bo_unref(&adev->smu.smu_buf); 838 - amdgpu_bo_unref(&adev->smu.toc_buf); 839 - DRM_ERROR("Failed to map the SMU internal buffer\n"); 840 - return -EINVAL; 841 - } 842 - 843 - amdgpu_bo_unreserve(adev->smu.smu_buf); 844 - private->smu_buffer_addr_low = lower_32_bits(mc_addr); 845 - private->smu_buffer_addr_high = upper_32_bits(mc_addr); 846 - 847 - adev->smu.smumgr_funcs = &tonga_smumgr_funcs; 848 - 849 - return 0; 850 - } 851 - 852 - int tonga_smu_fini(struct amdgpu_device *adev) 853 - { 854 - amdgpu_bo_unref(&adev->smu.toc_buf); 855 - amdgpu_bo_unref(&adev->smu.smu_buf); 856 - kfree(adev->smu.priv); 857 - adev->smu.priv = NULL; 858 - if (adev->firmware.fw_buf) 859 - amdgpu_ucode_fini_bo(adev); 860 - 861 - return 0; 862 - }
-42
drivers/gpu/drm/amd/amdgpu/tonga_smum.h
··· 1 - /* 2 - * Copyright 2014 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 - #ifndef TONGA_SMUMGR_H 25 - #define TONGA_SMUMGR_H 26 - 27 - #include "tonga_ppsmc.h" 28 - 29 - int tonga_smu_init(struct amdgpu_device *adev); 30 - int tonga_smu_fini(struct amdgpu_device *adev); 31 - int tonga_smu_start(struct amdgpu_device *adev); 32 - 33 - struct tonga_smu_private_data 34 - { 35 - uint8_t *header; 36 - uint32_t smu_buffer_addr_high; 37 - uint32_t smu_buffer_addr_low; 38 - uint32_t header_addr_high; 39 - uint32_t header_addr_low; 40 - }; 41 - 42 - #endif
+3
drivers/gpu/drm/amd/amdgpu/vi.c
··· 79 79 #endif 80 80 #include "dce_virtual.h" 81 81 82 + MODULE_FIRMWARE("amdgpu/topaz_smc.bin"); 83 + MODULE_FIRMWARE("amdgpu/tonga_smc.bin"); 84 + MODULE_FIRMWARE("amdgpu/fiji_smc.bin"); 82 85 MODULE_FIRMWARE("amdgpu/polaris10_smc.bin"); 83 86 MODULE_FIRMWARE("amdgpu/polaris10_smc_sk.bin"); 84 87 MODULE_FIRMWARE("amdgpu/polaris11_smc.bin");