From 32eaeae0ef193b64a67177006bdf5d9130d83fd3 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Mon, 8 Jul 2019 13:33:22 -0500 Subject: drm/amdgpu/psp: add a mutex to protect access to the psp ring We need to serialize access to the psp ring if there are multiple callers at runtime. Reviewed-by: Hawking Zhang Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h index 6039acc84346..e28cf5e4016e 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h @@ -201,6 +201,7 @@ struct psp_context uint8_t *ta_ras_start_addr; struct psp_xgmi_context xgmi_context; struct psp_ras_context ras; + struct mutex mutex; }; struct amdgpu_psp_funcs { -- cgit v1.2.3-59-g8ed1b From 3840fe256ae431d79e93988757a6f89db8192237 Mon Sep 17 00:00:00 2001 From: Hawking Zhang Date: Thu, 11 Jul 2019 22:02:02 +0800 Subject: drm/amdgpu: switch to macro for psp bootloader command The command will be sent to psp bootloader from driver to ask psp bootloader to exerise tOS, sys_drv and kdb loading Signed-off-by: Hawking Zhang Reviewed-by: Alex Deucher Reviewed-by: Xiaojie Yuan Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h | 6 ++++++ drivers/gpu/drm/amd/amdgpu/psp_v11_0.c | 4 ++-- drivers/gpu/drm/amd/amdgpu/psp_v3_1.c | 4 ++-- 3 files changed, 10 insertions(+), 4 deletions(-) (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h index e28cf5e4016e..6dcad432de1b 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h @@ -42,6 +42,12 @@ struct psp_context; struct psp_xgmi_node_info; struct psp_xgmi_topology_info; +enum psp_bootloader_cmd { + PSP_BL__LOAD_SYSDRV = 0x10000, + PSP_BL__LOAD_SOSDRV = 0x20000, + PSP_BL__LOAD_KEY_DATABASE = 0x80000, +}; + enum psp_ring_type { PSP_RING_TYPE__INVALID = 0, diff --git a/drivers/gpu/drm/amd/amdgpu/psp_v11_0.c b/drivers/gpu/drm/amd/amdgpu/psp_v11_0.c index 61744e2d16fb..a5f84b62cd8f 100644 --- a/drivers/gpu/drm/amd/amdgpu/psp_v11_0.c +++ b/drivers/gpu/drm/amd/amdgpu/psp_v11_0.c @@ -208,7 +208,7 @@ static int psp_v11_0_bootloader_load_sysdrv(struct psp_context *psp) /* 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 = 1 << 16; + psp_gfxdrv_command_reg = PSP_BL__LOAD_SYSDRV; WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_35, psp_gfxdrv_command_reg); @@ -249,7 +249,7 @@ static int psp_v11_0_bootloader_load_sos(struct psp_context *psp) /* Provide the PSP secure OS to bootloader */ WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_36, (uint32_t)(psp->fw_pri_mc_addr >> 20)); - psp_gfxdrv_command_reg = 2 << 16; + psp_gfxdrv_command_reg = PSP_BL__LOAD_SOSDRV; WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_35, psp_gfxdrv_command_reg); diff --git a/drivers/gpu/drm/amd/amdgpu/psp_v3_1.c b/drivers/gpu/drm/amd/amdgpu/psp_v3_1.c index 2ea772692037..019c47feee42 100644 --- a/drivers/gpu/drm/amd/amdgpu/psp_v3_1.c +++ b/drivers/gpu/drm/amd/amdgpu/psp_v3_1.c @@ -155,7 +155,7 @@ static int psp_v3_1_bootloader_load_sysdrv(struct psp_context *psp) /* 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 = 1 << 16; + psp_gfxdrv_command_reg = PSP_BL__LOAD_SYSDRV; WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_35, psp_gfxdrv_command_reg); @@ -218,7 +218,7 @@ static int psp_v3_1_bootloader_load_sos(struct psp_context *psp) /* Provide the PSP secure OS to bootloader */ WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_36, (uint32_t)(psp->fw_pri_mc_addr >> 20)); - psp_gfxdrv_command_reg = 2 << 16; + psp_gfxdrv_command_reg = PSP_BL__LOAD_SOSDRV; WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_35, psp_gfxdrv_command_reg); -- cgit v1.2.3-59-g8ed1b From 4298935924a9057f2424636d1d29ae7caef4764a Mon Sep 17 00:00:00 2001 From: Hawking Zhang Date: Thu, 11 Jul 2019 00:13:54 +0800 Subject: drm/amdgpu: support key database loading for navi10 Starting from navi10, driver should send Key Database Load command to bootloader before loading sys_drv and sos Signed-off-by: John Clements Signed-off-by: Hawking Zhang Reviewed-by: Xiaojie Yuan Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c | 9 ++++++ 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 | 48 ++++++++++++++++++++++++++++++- 5 files changed, 70 insertions(+), 1 deletion(-) (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c index 9882d90e765e..c5b7049cc01d 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c @@ -769,6 +769,15 @@ 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 6dcad432de1b..e0fc2a790e53 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h @@ -79,6 +79,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); @@ -162,9 +163,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; @@ -226,6 +229,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 c352a519ddd4..bfaa0eac3213 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 f46944453c6e..c1fb6dc86440 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 a5f84b62cd8f..41b72588adcf 100644 --- a/drivers/gpu/drm/amd/amdgpu/psp_v11_0.c +++ b/drivers/gpu/drm/amd/amdgpu/psp_v11_0.c @@ -103,6 +103,9 @@ 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: @@ -177,6 +180,48 @@ out: 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; @@ -190,7 +235,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; } @@ -822,6 +867,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, -- cgit v1.2.3-59-g8ed1b