1 /* 2 * Copyright 2016 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 * Author: Huang Rui 23 * 24 */ 25 26 #include <linux/firmware.h> 27 #include "drmP.h" 28 #include "amdgpu.h" 29 #include "amdgpu_psp.h" 30 #include "amdgpu_ucode.h" 31 #include "soc15_common.h" 32 #include "psp_v3_1.h" 33 34 static void psp_set_funcs(struct amdgpu_device *adev); 35 36 static int psp_early_init(void *handle) 37 { 38 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 39 40 psp_set_funcs(adev); 41 42 return 0; 43 } 44 45 static int psp_sw_init(void *handle) 46 { 47 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 48 struct psp_context *psp = &adev->psp; 49 int ret; 50 51 switch (adev->asic_type) { 52 case CHIP_VEGA10: 53 psp->init_microcode = psp_v3_1_init_microcode; 54 psp->bootloader_load_sysdrv = psp_v3_1_bootloader_load_sysdrv; 55 psp->bootloader_load_sos = psp_v3_1_bootloader_load_sos; 56 psp->prep_cmd_buf = psp_v3_1_prep_cmd_buf; 57 psp->ring_init = psp_v3_1_ring_init; 58 psp->cmd_submit = psp_v3_1_cmd_submit; 59 psp->compare_sram_data = psp_v3_1_compare_sram_data; 60 psp->smu_reload_quirk = psp_v3_1_smu_reload_quirk; 61 break; 62 default: 63 return -EINVAL; 64 } 65 66 psp->adev = adev; 67 68 ret = psp_init_microcode(psp); 69 if (ret) { 70 DRM_ERROR("Failed to load psp firmware!\n"); 71 return ret; 72 } 73 74 return 0; 75 } 76 77 static int psp_sw_fini(void *handle) 78 { 79 return 0; 80 } 81 82 int psp_wait_for(struct psp_context *psp, uint32_t reg_index, 83 uint32_t reg_val, uint32_t mask, bool check_changed) 84 { 85 uint32_t val; 86 int i; 87 struct amdgpu_device *adev = psp->adev; 88 89 val = RREG32(reg_index); 90 91 for (i = 0; i < adev->usec_timeout; i++) { 92 if (check_changed) { 93 if (val != reg_val) 94 return 0; 95 } else { 96 if ((val & mask) == reg_val) 97 return 0; 98 } 99 udelay(1); 100 } 101 102 return -ETIME; 103 } 104 105 static int 106 psp_cmd_submit_buf(struct psp_context *psp, 107 struct amdgpu_firmware_info *ucode, 108 struct psp_gfx_cmd_resp *cmd, uint64_t fence_mc_addr, 109 int index) 110 { 111 int ret; 112 struct amdgpu_bo *cmd_buf_bo; 113 uint64_t cmd_buf_mc_addr; 114 struct psp_gfx_cmd_resp *cmd_buf_mem; 115 struct amdgpu_device *adev = psp->adev; 116 117 ret = amdgpu_bo_create_kernel(adev, PSP_CMD_BUFFER_SIZE, PAGE_SIZE, 118 AMDGPU_GEM_DOMAIN_VRAM, 119 &cmd_buf_bo, &cmd_buf_mc_addr, 120 (void **)&cmd_buf_mem); 121 if (ret) 122 return ret; 123 124 memset(cmd_buf_mem, 0, PSP_CMD_BUFFER_SIZE); 125 126 memcpy(cmd_buf_mem, cmd, sizeof(struct psp_gfx_cmd_resp)); 127 128 ret = psp_cmd_submit(psp, ucode, cmd_buf_mc_addr, 129 fence_mc_addr, index); 130 131 while (*((unsigned int *)psp->fence_buf) != index) { 132 msleep(1); 133 } 134 135 amdgpu_bo_free_kernel(&cmd_buf_bo, 136 &cmd_buf_mc_addr, 137 (void **)&cmd_buf_mem); 138 139 return ret; 140 } 141 142 static void psp_prep_tmr_cmd_buf(struct psp_gfx_cmd_resp *cmd, 143 uint64_t tmr_mc, uint32_t size) 144 { 145 cmd->cmd_id = GFX_CMD_ID_SETUP_TMR; 146 cmd->cmd.cmd_setup_tmr.buf_phy_addr_lo = (uint32_t)tmr_mc; 147 cmd->cmd.cmd_setup_tmr.buf_phy_addr_hi = (uint32_t)(tmr_mc >> 32); 148 cmd->cmd.cmd_setup_tmr.buf_size = size; 149 } 150 151 /* Set up Trusted Memory Region */ 152 static int psp_tmr_init(struct psp_context *psp) 153 { 154 int ret; 155 struct psp_gfx_cmd_resp *cmd; 156 157 cmd = kzalloc(sizeof(struct psp_gfx_cmd_resp), GFP_KERNEL); 158 if (!cmd) 159 return -ENOMEM; 160 161 /* 162 * Allocate 3M memory aligned to 1M from Frame Buffer (local 163 * physical). 164 * 165 * Note: this memory need be reserved till the driver 166 * uninitializes. 167 */ 168 ret = amdgpu_bo_create_kernel(psp->adev, 0x300000, 0x100000, 169 AMDGPU_GEM_DOMAIN_VRAM, 170 &psp->tmr_bo, &psp->tmr_mc_addr, &psp->tmr_buf); 171 if (ret) 172 goto failed; 173 174 psp_prep_tmr_cmd_buf(cmd, psp->tmr_mc_addr, 0x300000); 175 176 ret = psp_cmd_submit_buf(psp, NULL, cmd, 177 psp->fence_buf_mc_addr, 1); 178 if (ret) 179 goto failed_mem; 180 181 kfree(cmd); 182 183 return 0; 184 185 failed_mem: 186 amdgpu_bo_free_kernel(&psp->tmr_bo, &psp->tmr_mc_addr, &psp->tmr_buf); 187 failed: 188 kfree(cmd); 189 return ret; 190 } 191 192 static void psp_prep_asd_cmd_buf(struct psp_gfx_cmd_resp *cmd, 193 uint64_t asd_mc, uint64_t asd_mc_shared, 194 uint32_t size, uint32_t shared_size) 195 { 196 cmd->cmd_id = GFX_CMD_ID_LOAD_ASD; 197 cmd->cmd.cmd_load_ta.app_phy_addr_lo = lower_32_bits(asd_mc); 198 cmd->cmd.cmd_load_ta.app_phy_addr_hi = upper_32_bits(asd_mc); 199 cmd->cmd.cmd_load_ta.app_len = size; 200 201 cmd->cmd.cmd_load_ta.cmd_buf_phy_addr_lo = lower_32_bits(asd_mc_shared); 202 cmd->cmd.cmd_load_ta.cmd_buf_phy_addr_hi = upper_32_bits(asd_mc_shared); 203 cmd->cmd.cmd_load_ta.cmd_buf_len = shared_size; 204 } 205 206 static int psp_asd_load(struct psp_context *psp) 207 { 208 int ret; 209 struct amdgpu_bo *asd_bo, *asd_shared_bo; 210 uint64_t asd_mc_addr, asd_shared_mc_addr; 211 void *asd_buf, *asd_shared_buf; 212 struct psp_gfx_cmd_resp *cmd; 213 214 cmd = kzalloc(sizeof(struct psp_gfx_cmd_resp), GFP_KERNEL); 215 if (!cmd) 216 return -ENOMEM; 217 218 /* 219 * Allocate 16k memory aligned to 4k from Frame Buffer (local 220 * physical) for shared ASD <-> Driver 221 */ 222 ret = amdgpu_bo_create_kernel(psp->adev, PSP_ASD_SHARED_MEM_SIZE, PAGE_SIZE, 223 AMDGPU_GEM_DOMAIN_VRAM, 224 &asd_shared_bo, &asd_shared_mc_addr, &asd_buf); 225 if (ret) 226 goto failed; 227 228 /* 229 * Allocate 256k memory aligned to 4k from Frame Buffer (local 230 * physical) for ASD firmware 231 */ 232 ret = amdgpu_bo_create_kernel(psp->adev, PSP_ASD_BIN_SIZE, PAGE_SIZE, 233 AMDGPU_GEM_DOMAIN_VRAM, 234 &asd_bo, &asd_mc_addr, &asd_buf); 235 if (ret) 236 goto failed_mem; 237 238 memcpy(asd_buf, psp->asd_start_addr, psp->asd_ucode_size); 239 240 psp_prep_asd_cmd_buf(cmd, asd_mc_addr, asd_shared_mc_addr, 241 psp->asd_ucode_size, PSP_ASD_SHARED_MEM_SIZE); 242 243 ret = psp_cmd_submit_buf(psp, NULL, cmd, 244 psp->fence_buf_mc_addr, 2); 245 if (ret) 246 goto failed_mem1; 247 248 amdgpu_bo_free_kernel(&asd_bo, &asd_mc_addr, &asd_buf); 249 amdgpu_bo_free_kernel(&asd_shared_bo, &asd_shared_mc_addr, &asd_shared_buf); 250 kfree(cmd); 251 252 return 0; 253 254 failed_mem1: 255 amdgpu_bo_free_kernel(&asd_bo, &asd_mc_addr, &asd_buf); 256 failed_mem: 257 amdgpu_bo_free_kernel(&asd_shared_bo, &asd_shared_mc_addr, &asd_shared_buf); 258 failed: 259 kfree(cmd); 260 return ret; 261 } 262 263 static int psp_load_fw(struct amdgpu_device *adev) 264 { 265 int ret; 266 struct psp_gfx_cmd_resp *cmd; 267 int i; 268 struct amdgpu_firmware_info *ucode; 269 struct psp_context *psp = &adev->psp; 270 271 cmd = kzalloc(sizeof(struct psp_gfx_cmd_resp), GFP_KERNEL); 272 if (!cmd) 273 return -ENOMEM; 274 275 ret = psp_bootloader_load_sysdrv(psp); 276 if (ret) 277 goto failed; 278 279 ret = psp_bootloader_load_sos(psp); 280 if (ret) 281 goto failed; 282 283 ret = psp_ring_init(psp, PSP_RING_TYPE__KM); 284 if (ret) 285 goto failed; 286 287 ret = amdgpu_bo_create_kernel(adev, PSP_FENCE_BUFFER_SIZE, PAGE_SIZE, 288 AMDGPU_GEM_DOMAIN_VRAM, 289 &psp->fence_buf_bo, 290 &psp->fence_buf_mc_addr, 291 &psp->fence_buf); 292 if (ret) 293 goto failed; 294 295 memset(psp->fence_buf, 0, PSP_FENCE_BUFFER_SIZE); 296 297 ret = psp_tmr_init(psp); 298 if (ret) 299 goto failed_mem; 300 301 ret = psp_asd_load(psp); 302 if (ret) 303 goto failed_mem; 304 305 for (i = 0; i < adev->firmware.max_ucodes; i++) { 306 ucode = &adev->firmware.ucode[i]; 307 if (!ucode->fw) 308 continue; 309 310 if (ucode->ucode_id == AMDGPU_UCODE_ID_SMC && 311 psp_smu_reload_quirk(psp)) 312 continue; 313 314 ret = psp_prep_cmd_buf(ucode, cmd); 315 if (ret) 316 goto failed_mem; 317 318 ret = psp_cmd_submit_buf(psp, ucode, cmd, 319 psp->fence_buf_mc_addr, i + 3); 320 if (ret) 321 goto failed_mem; 322 323 #if 0 324 /* check if firmware loaded sucessfully */ 325 if (!amdgpu_psp_check_fw_loading_status(adev, i)) 326 return -EINVAL; 327 #endif 328 } 329 330 amdgpu_bo_free_kernel(&psp->fence_buf_bo, 331 &psp->fence_buf_mc_addr, &psp->fence_buf); 332 kfree(cmd); 333 334 return 0; 335 336 failed_mem: 337 amdgpu_bo_free_kernel(&psp->fence_buf_bo, 338 &psp->fence_buf_mc_addr, &psp->fence_buf); 339 failed: 340 kfree(cmd); 341 return ret; 342 } 343 344 static int psp_hw_init(void *handle) 345 { 346 int ret; 347 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 348 349 350 if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP) 351 return 0; 352 353 mutex_lock(&adev->firmware.mutex); 354 /* 355 * This sequence is just used on hw_init only once, no need on 356 * resume. 357 */ 358 ret = amdgpu_ucode_init_bo(adev); 359 if (ret) 360 goto failed; 361 362 ret = psp_load_fw(adev); 363 if (ret) { 364 DRM_ERROR("PSP firmware loading failed\n"); 365 goto failed; 366 } 367 368 mutex_unlock(&adev->firmware.mutex); 369 return 0; 370 371 failed: 372 adev->firmware.load_type = AMDGPU_FW_LOAD_DIRECT; 373 mutex_unlock(&adev->firmware.mutex); 374 return -EINVAL; 375 } 376 377 static int psp_hw_fini(void *handle) 378 { 379 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 380 struct psp_context *psp = &adev->psp; 381 382 if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) 383 amdgpu_ucode_fini_bo(adev); 384 385 if (psp->tmr_buf) 386 amdgpu_bo_free_kernel(&psp->tmr_bo, &psp->tmr_mc_addr, &psp->tmr_buf); 387 388 return 0; 389 } 390 391 static int psp_suspend(void *handle) 392 { 393 return 0; 394 } 395 396 static int psp_resume(void *handle) 397 { 398 int ret; 399 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 400 401 if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP) 402 return 0; 403 404 mutex_lock(&adev->firmware.mutex); 405 406 ret = psp_load_fw(adev); 407 if (ret) 408 DRM_ERROR("PSP resume failed\n"); 409 410 mutex_unlock(&adev->firmware.mutex); 411 412 return ret; 413 } 414 415 static bool psp_check_fw_loading_status(struct amdgpu_device *adev, 416 enum AMDGPU_UCODE_ID ucode_type) 417 { 418 struct amdgpu_firmware_info *ucode = NULL; 419 420 if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP) { 421 DRM_INFO("firmware is not loaded by PSP\n"); 422 return true; 423 } 424 425 if (!adev->firmware.fw_size) 426 return false; 427 428 ucode = &adev->firmware.ucode[ucode_type]; 429 if (!ucode->fw || !ucode->ucode_size) 430 return false; 431 432 return psp_compare_sram_data(&adev->psp, ucode, ucode_type); 433 } 434 435 static int psp_set_clockgating_state(void *handle, 436 enum amd_clockgating_state state) 437 { 438 return 0; 439 } 440 441 static int psp_set_powergating_state(void *handle, 442 enum amd_powergating_state state) 443 { 444 return 0; 445 } 446 447 const struct amd_ip_funcs psp_ip_funcs = { 448 .name = "psp", 449 .early_init = psp_early_init, 450 .late_init = NULL, 451 .sw_init = psp_sw_init, 452 .sw_fini = psp_sw_fini, 453 .hw_init = psp_hw_init, 454 .hw_fini = psp_hw_fini, 455 .suspend = psp_suspend, 456 .resume = psp_resume, 457 .is_idle = NULL, 458 .wait_for_idle = NULL, 459 .soft_reset = NULL, 460 .set_clockgating_state = psp_set_clockgating_state, 461 .set_powergating_state = psp_set_powergating_state, 462 }; 463 464 static const struct amdgpu_psp_funcs psp_funcs = { 465 .check_fw_loading_status = psp_check_fw_loading_status, 466 }; 467 468 static void psp_set_funcs(struct amdgpu_device *adev) 469 { 470 if (NULL == adev->firmware.funcs) 471 adev->firmware.funcs = &psp_funcs; 472 } 473 474 const struct amdgpu_ip_block_version psp_v3_1_ip_block = 475 { 476 .type = AMD_IP_BLOCK_TYPE_PSP, 477 .major = 3, 478 .minor = 1, 479 .rev = 0, 480 .funcs = &psp_ip_funcs, 481 }; 482