Starting from navi10, driver should send Key Database Load command to Bootloader before loading sys_drv and sos Change-Id: Ib82d21840fb77da2217dd8b8f013177e61d72990 Signed-off-by: John Clements <John.Clements@xxxxxxx> Signed-off-by: Hawking Zhang <Hawking.Zhang@xxxxxxx> --- drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c | 10 +++++++ drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h | 5 ++++ drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c | 6 ++++ drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.h | 3 ++ drivers/gpu/drm/amd/amdgpu/psp_v11_0.c | 49 ++++++++++++++++++++++++++++++- 5 files changed, 72 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c index ed580e8b..3378cb38 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c @@ -770,6 +770,16 @@ static int psp_hw_start(struct psp_context *psp) int ret; if (!amdgpu_sriov_vf(adev) || !adev->in_gpu_reset) { + + if (psp->kdb_start_addr && + (psp->funcs->bootloader_load_kdb != NULL)) { + ret = psp_bootloader_load_kdb(psp); + if (ret) { + DRM_ERROR("PSP load kdb failed!\n"); + return ret; + } + } + ret = psp_bootloader_load_sysdrv(psp); if (ret) { DRM_ERROR("PSP load sysdrv failed!\n"); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h index 8ddcec1..6f1746b 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h @@ -82,6 +82,7 @@ enum psp_reg_prog_id { struct psp_funcs { int (*init_microcode)(struct psp_context *psp); + int (*bootloader_load_kdb)(struct psp_context *psp); int (*bootloader_load_sysdrv)(struct psp_context *psp); int (*bootloader_load_sos)(struct psp_context *psp); int (*ring_init)(struct psp_context *psp, enum psp_ring_type ring_type); @@ -165,9 +166,11 @@ struct psp_context uint32_t sys_bin_size; uint32_t sos_bin_size; uint32_t toc_bin_size; + uint32_t kdb_bin_size; uint8_t *sys_start_addr; uint8_t *sos_start_addr; uint8_t *toc_start_addr; + uint8_t *kdb_start_addr; /* tmr buffer */ struct amdgpu_bo *tmr_bo; @@ -229,6 +232,8 @@ struct amdgpu_psp_funcs { (psp)->funcs->compare_sram_data((psp), (ucode), (type)) #define psp_init_microcode(psp) \ ((psp)->funcs->init_microcode ? (psp)->funcs->init_microcode((psp)) : 0) +#define psp_bootloader_load_kdb(psp) \ + ((psp)->funcs->bootloader_load_kdb ? (psp)->funcs->bootloader_load_kdb((psp)) : 0) #define psp_bootloader_load_sysdrv(psp) \ ((psp)->funcs->bootloader_load_sysdrv ? (psp)->funcs->bootloader_load_sysdrv((psp)) : 0) #define psp_bootloader_load_sos(psp) \ diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c index bf7e8ba..2042b60 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c @@ -262,6 +262,12 @@ void amdgpu_ucode_print_psp_hdr(const struct common_firmware_header *hdr) le32_to_cpu(psp_hdr_v1_1->toc_offset_bytes)); DRM_DEBUG("toc_size_bytes: %u\n", le32_to_cpu(psp_hdr_v1_1->toc_size_bytes)); + DRM_DEBUG("kdb_header_version: %u\n", + le32_to_cpu(psp_hdr_v1_1->kdb_header_version)); + DRM_DEBUG("kdb_offset_bytes: %u\n", + le32_to_cpu(psp_hdr_v1_1->kdb_offset_bytes)); + DRM_DEBUG("kdb_size_bytes: %u\n", + le32_to_cpu(psp_hdr_v1_1->kdb_size_bytes)); } } else { DRM_ERROR("Unknown PSP ucode version: %u.%u\n", diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.h index f4694445..c1fb6dc 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.h @@ -85,6 +85,9 @@ struct psp_firmware_header_v1_1 { uint32_t toc_header_version; uint32_t toc_offset_bytes; uint32_t toc_size_bytes; + uint32_t kdb_header_version; + uint32_t kdb_offset_bytes; + uint32_t kdb_size_bytes; }; /* version_major=1, version_minor=0 */ diff --git a/drivers/gpu/drm/amd/amdgpu/psp_v11_0.c b/drivers/gpu/drm/amd/amdgpu/psp_v11_0.c index e784091..ac7f352 100644 --- a/drivers/gpu/drm/amd/amdgpu/psp_v11_0.c +++ b/drivers/gpu/drm/amd/amdgpu/psp_v11_0.c @@ -106,6 +106,10 @@ static int psp_v11_0_init_microcode(struct psp_context *psp) adev->psp.toc_bin_size = le32_to_cpu(sos_hdr_v1_1->toc_size_bytes); adev->psp.toc_start_addr = (uint8_t *)adev->psp.sys_start_addr + le32_to_cpu(sos_hdr_v1_1->toc_offset_bytes); + + adev->psp.kdb_bin_size = le32_to_cpu(sos_hdr_v1_1->kdb_size_bytes); + adev->psp.kdb_start_addr = (uint8_t *)adev->psp.sys_start_addr + + le32_to_cpu(sos_hdr_v1_1->kdb_offset_bytes); } break; default: @@ -181,6 +185,48 @@ static int psp_v11_0_init_microcode(struct psp_context *psp) return err; } +static int psp_v11_0_bootloader_load_kdb(struct psp_context *psp) +{ + int ret; + uint32_t psp_gfxdrv_command_reg = 0; + struct amdgpu_device *adev = psp->adev; + uint32_t sol_reg; + + /* Check tOS sign of life register to confirm sys driver and sOS + * are already been loaded. + */ + sol_reg = RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_81); + if (sol_reg) { + psp->sos_fw_version = RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_58); + dev_info(adev->dev, "sos fw version = 0x%x.\n", psp->sos_fw_version); + return 0; + } + + /* Wait for bootloader to signify that is ready having bit 31 of C2PMSG_35 set to 1 */ + ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, mmMP0_SMN_C2PMSG_35), + 0x80000000, 0x80000000, false); + if (ret) + return ret; + + memset(psp->fw_pri_buf, 0, PSP_1_MEG); + + /* Copy PSP KDB binary to memory */ + memcpy(psp->fw_pri_buf, psp->kdb_start_addr, psp->kdb_bin_size); + + /* Provide the sys driver to bootloader */ + WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_36, + (uint32_t)(psp->fw_pri_mc_addr >> 20)); + psp_gfxdrv_command_reg = PSP_BL__LOAD_KEY_DATABASE; + WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_35, + psp_gfxdrv_command_reg); + + /* Wait for bootloader to signify that is ready having bit 31 of C2PMSG_35 set to 1*/ + ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, mmMP0_SMN_C2PMSG_35), + 0x80000000, 0x80000000, false); + + return ret; +} + static int psp_v11_0_bootloader_load_sysdrv(struct psp_context *psp) { int ret; @@ -194,7 +240,7 @@ static int psp_v11_0_bootloader_load_sysdrv(struct psp_context *psp) sol_reg = RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_81); if (sol_reg) { psp->sos_fw_version = RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_58); - printk("sos fw version = 0x%x.\n", psp->sos_fw_version); + dev_info(adev->dev, "sos fw version = 0x%x.\n", psp->sos_fw_version); return 0; } @@ -826,6 +872,7 @@ static int psp_v11_0_rlc_autoload_start(struct psp_context *psp) static const struct psp_funcs psp_v11_0_funcs = { .init_microcode = psp_v11_0_init_microcode, + .bootloader_load_kdb = psp_v11_0_bootloader_load_kdb, .bootloader_load_sysdrv = psp_v11_0_bootloader_load_sysdrv, .bootloader_load_sos = psp_v11_0_bootloader_load_sos, .ring_init = psp_v11_0_ring_init, -- 2.7.4 _______________________________________________ amd-gfx mailing list amd-gfx@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/amd-gfx