Commit 42989359 authored by Hawking Zhang's avatar Hawking Zhang Committed by Alex Deucher

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: default avatarJohn Clements <John.Clements@amd.com>
Signed-off-by: default avatarHawking Zhang <Hawking.Zhang@amd.com>
Reviewed-by: default avatarXiaojie Yuan <xiaojie.yuan@amd.com>
Reviewed-by: default avatarAlex Deucher <alexander.deucher@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 3840fe25
...@@ -769,6 +769,15 @@ static int psp_hw_start(struct psp_context *psp) ...@@ -769,6 +769,15 @@ static int psp_hw_start(struct psp_context *psp)
int ret; int ret;
if (!amdgpu_sriov_vf(adev) || !adev->in_gpu_reset) { 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); ret = psp_bootloader_load_sysdrv(psp);
if (ret) { if (ret) {
DRM_ERROR("PSP load sysdrv failed!\n"); DRM_ERROR("PSP load sysdrv failed!\n");
......
...@@ -79,6 +79,7 @@ enum psp_reg_prog_id { ...@@ -79,6 +79,7 @@ enum psp_reg_prog_id {
struct psp_funcs struct psp_funcs
{ {
int (*init_microcode)(struct psp_context *psp); 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_sysdrv)(struct psp_context *psp);
int (*bootloader_load_sos)(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); int (*ring_init)(struct psp_context *psp, enum psp_ring_type ring_type);
...@@ -162,9 +163,11 @@ struct psp_context ...@@ -162,9 +163,11 @@ struct psp_context
uint32_t sys_bin_size; uint32_t sys_bin_size;
uint32_t sos_bin_size; uint32_t sos_bin_size;
uint32_t toc_bin_size; uint32_t toc_bin_size;
uint32_t kdb_bin_size;
uint8_t *sys_start_addr; uint8_t *sys_start_addr;
uint8_t *sos_start_addr; uint8_t *sos_start_addr;
uint8_t *toc_start_addr; uint8_t *toc_start_addr;
uint8_t *kdb_start_addr;
/* tmr buffer */ /* tmr buffer */
struct amdgpu_bo *tmr_bo; struct amdgpu_bo *tmr_bo;
...@@ -226,6 +229,8 @@ struct amdgpu_psp_funcs { ...@@ -226,6 +229,8 @@ struct amdgpu_psp_funcs {
(psp)->funcs->compare_sram_data((psp), (ucode), (type)) (psp)->funcs->compare_sram_data((psp), (ucode), (type))
#define psp_init_microcode(psp) \ #define psp_init_microcode(psp) \
((psp)->funcs->init_microcode ? (psp)->funcs->init_microcode((psp)) : 0) ((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) \ #define psp_bootloader_load_sysdrv(psp) \
((psp)->funcs->bootloader_load_sysdrv ? (psp)->funcs->bootloader_load_sysdrv((psp)) : 0) ((psp)->funcs->bootloader_load_sysdrv ? (psp)->funcs->bootloader_load_sysdrv((psp)) : 0)
#define psp_bootloader_load_sos(psp) \ #define psp_bootloader_load_sos(psp) \
......
...@@ -262,6 +262,12 @@ void amdgpu_ucode_print_psp_hdr(const struct common_firmware_header *hdr) ...@@ -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)); le32_to_cpu(psp_hdr_v1_1->toc_offset_bytes));
DRM_DEBUG("toc_size_bytes: %u\n", DRM_DEBUG("toc_size_bytes: %u\n",
le32_to_cpu(psp_hdr_v1_1->toc_size_bytes)); 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 { } else {
DRM_ERROR("Unknown PSP ucode version: %u.%u\n", DRM_ERROR("Unknown PSP ucode version: %u.%u\n",
......
...@@ -85,6 +85,9 @@ struct psp_firmware_header_v1_1 { ...@@ -85,6 +85,9 @@ struct psp_firmware_header_v1_1 {
uint32_t toc_header_version; uint32_t toc_header_version;
uint32_t toc_offset_bytes; uint32_t toc_offset_bytes;
uint32_t toc_size_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 */ /* version_major=1, version_minor=0 */
......
...@@ -103,6 +103,9 @@ static int psp_v11_0_init_microcode(struct psp_context *psp) ...@@ -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_bin_size = le32_to_cpu(sos_hdr_v1_1->toc_size_bytes);
adev->psp.toc_start_addr = (uint8_t *)adev->psp.sys_start_addr + adev->psp.toc_start_addr = (uint8_t *)adev->psp.sys_start_addr +
le32_to_cpu(sos_hdr_v1_1->toc_offset_bytes); 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; break;
default: default:
...@@ -177,6 +180,48 @@ static int psp_v11_0_init_microcode(struct psp_context *psp) ...@@ -177,6 +180,48 @@ static int psp_v11_0_init_microcode(struct psp_context *psp)
return err; 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) static int psp_v11_0_bootloader_load_sysdrv(struct psp_context *psp)
{ {
int ret; int ret;
...@@ -190,7 +235,7 @@ static int psp_v11_0_bootloader_load_sysdrv(struct psp_context *psp) ...@@ -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); sol_reg = RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_81);
if (sol_reg) { if (sol_reg) {
psp->sos_fw_version = RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_58); 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; return 0;
} }
...@@ -822,6 +867,7 @@ static int psp_v11_0_rlc_autoload_start(struct psp_context *psp) ...@@ -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 = { static const struct psp_funcs psp_v11_0_funcs = {
.init_microcode = psp_v11_0_init_microcode, .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_sysdrv = psp_v11_0_bootloader_load_sysdrv,
.bootloader_load_sos = psp_v11_0_bootloader_load_sos, .bootloader_load_sos = psp_v11_0_bootloader_load_sos,
.ring_init = psp_v11_0_ring_init, .ring_init = psp_v11_0_ring_init,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment