2 * Copyright 2016 Advanced Micro Devices, Inc.
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:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
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.
26 #include <linux/firmware.h>
29 #include "amdgpu_psp.h"
30 #include "amdgpu_ucode.h"
31 #include "soc15_common.h"
33 #include "psp_v10_0.h"
35 static void psp_set_funcs(struct amdgpu_device
*adev
);
37 static int psp_early_init(void *handle
)
39 struct amdgpu_device
*adev
= (struct amdgpu_device
*)handle
;
40 struct psp_context
*psp
= &adev
->psp
;
44 switch (adev
->asic_type
) {
48 psp_v3_1_set_psp_funcs(psp
);
51 psp_v10_0_set_psp_funcs(psp
);
59 if (adev
->firmware
.load_type
!= AMDGPU_FW_LOAD_PSP
)
65 static int psp_sw_init(void *handle
)
67 struct amdgpu_device
*adev
= (struct amdgpu_device
*)handle
;
68 struct psp_context
*psp
= &adev
->psp
;
71 ret
= psp_init_microcode(psp
);
73 DRM_ERROR("Failed to load psp firmware!\n");
80 static int psp_sw_fini(void *handle
)
82 struct amdgpu_device
*adev
= (struct amdgpu_device
*)handle
;
84 if (adev
->firmware
.load_type
!= AMDGPU_FW_LOAD_PSP
)
87 release_firmware(adev
->psp
.sos_fw
);
88 adev
->psp
.sos_fw
= NULL
;
89 release_firmware(adev
->psp
.asd_fw
);
90 adev
->psp
.asd_fw
= NULL
;
94 int psp_wait_for(struct psp_context
*psp
, uint32_t reg_index
,
95 uint32_t reg_val
, uint32_t mask
, bool check_changed
)
99 struct amdgpu_device
*adev
= psp
->adev
;
101 for (i
= 0; i
< adev
->usec_timeout
; i
++) {
102 val
= RREG32(reg_index
);
107 if ((val
& mask
) == reg_val
)
117 psp_cmd_submit_buf(struct psp_context
*psp
,
118 struct amdgpu_firmware_info
*ucode
,
119 struct psp_gfx_cmd_resp
*cmd
, uint64_t fence_mc_addr
,
124 memset(psp
->cmd_buf_mem
, 0, PSP_CMD_BUFFER_SIZE
);
126 memcpy(psp
->cmd_buf_mem
, cmd
, sizeof(struct psp_gfx_cmd_resp
));
128 ret
= psp_cmd_submit(psp
, ucode
, psp
->cmd_buf_mc_addr
,
129 fence_mc_addr
, index
);
131 while (*((unsigned int *)psp
->fence_buf
) != index
) {
136 ucode
->tmr_mc_addr_lo
= psp
->cmd_buf_mem
->resp
.fw_addr_lo
;
137 ucode
->tmr_mc_addr_hi
= psp
->cmd_buf_mem
->resp
.fw_addr_hi
;
143 static void psp_prep_tmr_cmd_buf(struct psp_gfx_cmd_resp
*cmd
,
144 uint64_t tmr_mc
, uint32_t size
)
146 cmd
->cmd_id
= GFX_CMD_ID_SETUP_TMR
;
147 cmd
->cmd
.cmd_setup_tmr
.buf_phy_addr_lo
= lower_32_bits(tmr_mc
);
148 cmd
->cmd
.cmd_setup_tmr
.buf_phy_addr_hi
= upper_32_bits(tmr_mc
);
149 cmd
->cmd
.cmd_setup_tmr
.buf_size
= size
;
152 /* Set up Trusted Memory Region */
153 static int psp_tmr_init(struct psp_context
*psp
)
158 * Allocate 3M memory aligned to 1M from Frame Buffer (local
161 * Note: this memory need be reserved till the driver
164 ret
= amdgpu_bo_create_kernel(psp
->adev
, 0x300000, 0x100000,
165 AMDGPU_GEM_DOMAIN_VRAM
,
166 &psp
->tmr_bo
, &psp
->tmr_mc_addr
, &psp
->tmr_buf
);
171 static int psp_tmr_load(struct psp_context
*psp
)
174 struct psp_gfx_cmd_resp
*cmd
;
176 cmd
= kzalloc(sizeof(struct psp_gfx_cmd_resp
), GFP_KERNEL
);
180 psp_prep_tmr_cmd_buf(cmd
, psp
->tmr_mc_addr
, 0x300000);
182 ret
= psp_cmd_submit_buf(psp
, NULL
, cmd
,
183 psp
->fence_buf_mc_addr
, 1);
196 static void psp_prep_asd_cmd_buf(struct psp_gfx_cmd_resp
*cmd
,
197 uint64_t asd_mc
, uint64_t asd_mc_shared
,
198 uint32_t size
, uint32_t shared_size
)
200 cmd
->cmd_id
= GFX_CMD_ID_LOAD_ASD
;
201 cmd
->cmd
.cmd_load_ta
.app_phy_addr_lo
= lower_32_bits(asd_mc
);
202 cmd
->cmd
.cmd_load_ta
.app_phy_addr_hi
= upper_32_bits(asd_mc
);
203 cmd
->cmd
.cmd_load_ta
.app_len
= size
;
205 cmd
->cmd
.cmd_load_ta
.cmd_buf_phy_addr_lo
= lower_32_bits(asd_mc_shared
);
206 cmd
->cmd
.cmd_load_ta
.cmd_buf_phy_addr_hi
= upper_32_bits(asd_mc_shared
);
207 cmd
->cmd
.cmd_load_ta
.cmd_buf_len
= shared_size
;
210 static int psp_asd_init(struct psp_context
*psp
)
215 * Allocate 16k memory aligned to 4k from Frame Buffer (local
216 * physical) for shared ASD <-> Driver
218 ret
= amdgpu_bo_create_kernel(psp
->adev
, PSP_ASD_SHARED_MEM_SIZE
,
219 PAGE_SIZE
, AMDGPU_GEM_DOMAIN_VRAM
,
221 &psp
->asd_shared_mc_addr
,
222 &psp
->asd_shared_buf
);
227 static int psp_asd_load(struct psp_context
*psp
)
230 struct psp_gfx_cmd_resp
*cmd
;
232 /* If PSP version doesn't match ASD version, asd loading will be failed.
233 * add workaround to bypass it for sriov now.
234 * TODO: add version check to make it common
236 if (amdgpu_sriov_vf(psp
->adev
))
239 cmd
= kzalloc(sizeof(struct psp_gfx_cmd_resp
), GFP_KERNEL
);
243 memset(psp
->fw_pri_buf
, 0, PSP_1_MEG
);
244 memcpy(psp
->fw_pri_buf
, psp
->asd_start_addr
, psp
->asd_ucode_size
);
246 psp_prep_asd_cmd_buf(cmd
, psp
->fw_pri_mc_addr
, psp
->asd_shared_mc_addr
,
247 psp
->asd_ucode_size
, PSP_ASD_SHARED_MEM_SIZE
);
249 ret
= psp_cmd_submit_buf(psp
, NULL
, cmd
,
250 psp
->fence_buf_mc_addr
, 2);
257 static int psp_hw_start(struct psp_context
*psp
)
259 struct amdgpu_device
*adev
= psp
->adev
;
262 if (!amdgpu_sriov_vf(adev
) || !adev
->in_gpu_reset
) {
263 ret
= psp_bootloader_load_sysdrv(psp
);
267 ret
= psp_bootloader_load_sos(psp
);
272 ret
= psp_ring_create(psp
, PSP_RING_TYPE__KM
);
276 ret
= psp_tmr_load(psp
);
280 ret
= psp_asd_load(psp
);
287 static int psp_np_fw_load(struct psp_context
*psp
)
290 struct amdgpu_firmware_info
*ucode
;
291 struct amdgpu_device
* adev
= psp
->adev
;
293 for (i
= 0; i
< adev
->firmware
.max_ucodes
; i
++) {
294 ucode
= &adev
->firmware
.ucode
[i
];
298 if (ucode
->ucode_id
== AMDGPU_UCODE_ID_SMC
&&
299 psp_smu_reload_quirk(psp
))
301 if (amdgpu_sriov_vf(adev
) &&
302 (ucode
->ucode_id
== AMDGPU_UCODE_ID_SDMA0
303 || ucode
->ucode_id
== AMDGPU_UCODE_ID_SDMA1
304 || ucode
->ucode_id
== AMDGPU_UCODE_ID_RLC_G
))
305 /*skip ucode loading in SRIOV VF */
308 ret
= psp_prep_cmd_buf(ucode
, psp
->cmd
);
312 ret
= psp_cmd_submit_buf(psp
, ucode
, psp
->cmd
,
313 psp
->fence_buf_mc_addr
, i
+ 3);
318 /* check if firmware loaded sucessfully */
319 if (!amdgpu_psp_check_fw_loading_status(adev
, i
))
327 static int psp_load_fw(struct amdgpu_device
*adev
)
330 struct psp_context
*psp
= &adev
->psp
;
332 if (amdgpu_sriov_vf(adev
) && adev
->in_gpu_reset
!= 0)
335 psp
->cmd
= kzalloc(sizeof(struct psp_gfx_cmd_resp
), GFP_KERNEL
);
339 ret
= amdgpu_bo_create_kernel(adev
, PSP_1_MEG
, PSP_1_MEG
,
340 AMDGPU_GEM_DOMAIN_GTT
,
342 &psp
->fw_pri_mc_addr
,
347 ret
= amdgpu_bo_create_kernel(adev
, PSP_FENCE_BUFFER_SIZE
, PAGE_SIZE
,
348 AMDGPU_GEM_DOMAIN_VRAM
,
350 &psp
->fence_buf_mc_addr
,
355 ret
= amdgpu_bo_create_kernel(adev
, PSP_CMD_BUFFER_SIZE
, PAGE_SIZE
,
356 AMDGPU_GEM_DOMAIN_VRAM
,
357 &psp
->cmd_buf_bo
, &psp
->cmd_buf_mc_addr
,
358 (void **)&psp
->cmd_buf_mem
);
362 memset(psp
->fence_buf
, 0, PSP_FENCE_BUFFER_SIZE
);
364 ret
= psp_ring_init(psp
, PSP_RING_TYPE__KM
);
368 ret
= psp_tmr_init(psp
);
372 ret
= psp_asd_init(psp
);
377 ret
= psp_hw_start(psp
);
381 ret
= psp_np_fw_load(psp
);
388 amdgpu_bo_free_kernel(&psp
->cmd_buf_bo
,
389 &psp
->cmd_buf_mc_addr
,
390 (void **)&psp
->cmd_buf_mem
);
392 amdgpu_bo_free_kernel(&psp
->fence_buf_bo
,
393 &psp
->fence_buf_mc_addr
, &psp
->fence_buf
);
395 amdgpu_bo_free_kernel(&psp
->fw_pri_bo
,
396 &psp
->fw_pri_mc_addr
, &psp
->fw_pri_buf
);
403 static int psp_hw_init(void *handle
)
406 struct amdgpu_device
*adev
= (struct amdgpu_device
*)handle
;
409 if (adev
->firmware
.load_type
!= AMDGPU_FW_LOAD_PSP
)
412 mutex_lock(&adev
->firmware
.mutex
);
414 * This sequence is just used on hw_init only once, no need on
417 ret
= amdgpu_ucode_init_bo(adev
);
421 ret
= psp_load_fw(adev
);
423 DRM_ERROR("PSP firmware loading failed\n");
427 mutex_unlock(&adev
->firmware
.mutex
);
431 adev
->firmware
.load_type
= AMDGPU_FW_LOAD_DIRECT
;
432 mutex_unlock(&adev
->firmware
.mutex
);
436 static int psp_hw_fini(void *handle
)
438 struct amdgpu_device
*adev
= (struct amdgpu_device
*)handle
;
439 struct psp_context
*psp
= &adev
->psp
;
441 if (adev
->firmware
.load_type
!= AMDGPU_FW_LOAD_PSP
)
444 amdgpu_ucode_fini_bo(adev
);
446 psp_ring_destroy(psp
, PSP_RING_TYPE__KM
);
448 amdgpu_bo_free_kernel(&psp
->tmr_bo
, &psp
->tmr_mc_addr
, &psp
->tmr_buf
);
449 amdgpu_bo_free_kernel(&psp
->fw_pri_bo
,
450 &psp
->fw_pri_mc_addr
, &psp
->fw_pri_buf
);
451 amdgpu_bo_free_kernel(&psp
->fence_buf_bo
,
452 &psp
->fence_buf_mc_addr
, &psp
->fence_buf
);
453 amdgpu_bo_free_kernel(&psp
->asd_shared_bo
, &psp
->asd_shared_mc_addr
,
454 &psp
->asd_shared_buf
);
455 amdgpu_bo_free_kernel(&psp
->cmd_buf_bo
, &psp
->cmd_buf_mc_addr
,
456 (void **)&psp
->cmd_buf_mem
);
464 static int psp_suspend(void *handle
)
467 struct amdgpu_device
*adev
= (struct amdgpu_device
*)handle
;
468 struct psp_context
*psp
= &adev
->psp
;
470 if (adev
->firmware
.load_type
!= AMDGPU_FW_LOAD_PSP
)
473 ret
= psp_ring_stop(psp
, PSP_RING_TYPE__KM
);
475 DRM_ERROR("PSP ring stop failed\n");
482 static int psp_resume(void *handle
)
485 struct amdgpu_device
*adev
= (struct amdgpu_device
*)handle
;
486 struct psp_context
*psp
= &adev
->psp
;
488 if (adev
->firmware
.load_type
!= AMDGPU_FW_LOAD_PSP
)
491 DRM_INFO("PSP is resuming...\n");
493 mutex_lock(&adev
->firmware
.mutex
);
495 ret
= psp_hw_start(psp
);
499 ret
= psp_np_fw_load(psp
);
503 mutex_unlock(&adev
->firmware
.mutex
);
508 DRM_ERROR("PSP resume failed\n");
509 mutex_unlock(&adev
->firmware
.mutex
);
513 int psp_gpu_reset(struct amdgpu_device
*adev
)
515 if (adev
->firmware
.load_type
!= AMDGPU_FW_LOAD_PSP
)
518 return psp_mode1_reset(&adev
->psp
);
521 static bool psp_check_fw_loading_status(struct amdgpu_device
*adev
,
522 enum AMDGPU_UCODE_ID ucode_type
)
524 struct amdgpu_firmware_info
*ucode
= NULL
;
526 if (adev
->firmware
.load_type
!= AMDGPU_FW_LOAD_PSP
) {
527 DRM_INFO("firmware is not loaded by PSP\n");
531 if (!adev
->firmware
.fw_size
)
534 ucode
= &adev
->firmware
.ucode
[ucode_type
];
535 if (!ucode
->fw
|| !ucode
->ucode_size
)
538 return psp_compare_sram_data(&adev
->psp
, ucode
, ucode_type
);
541 static int psp_set_clockgating_state(void *handle
,
542 enum amd_clockgating_state state
)
547 static int psp_set_powergating_state(void *handle
,
548 enum amd_powergating_state state
)
553 const struct amd_ip_funcs psp_ip_funcs
= {
555 .early_init
= psp_early_init
,
557 .sw_init
= psp_sw_init
,
558 .sw_fini
= psp_sw_fini
,
559 .hw_init
= psp_hw_init
,
560 .hw_fini
= psp_hw_fini
,
561 .suspend
= psp_suspend
,
562 .resume
= psp_resume
,
564 .check_soft_reset
= NULL
,
565 .wait_for_idle
= NULL
,
567 .set_clockgating_state
= psp_set_clockgating_state
,
568 .set_powergating_state
= psp_set_powergating_state
,
571 static const struct amdgpu_psp_funcs psp_funcs
= {
572 .check_fw_loading_status
= psp_check_fw_loading_status
,
575 static void psp_set_funcs(struct amdgpu_device
*adev
)
577 if (NULL
== adev
->firmware
.funcs
)
578 adev
->firmware
.funcs
= &psp_funcs
;
581 const struct amdgpu_ip_block_version psp_v3_1_ip_block
=
583 .type
= AMD_IP_BLOCK_TYPE_PSP
,
587 .funcs
= &psp_ip_funcs
,
590 const struct amdgpu_ip_block_version psp_v10_0_ip_block
=
592 .type
= AMD_IP_BLOCK_TYPE_PSP
,
596 .funcs
= &psp_ip_funcs
,