forked from Minki/linux
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 <John.Clements@amd.com> Signed-off-by: Hawking Zhang <Hawking.Zhang@amd.com> Reviewed-by: Xiaojie Yuan <xiaojie.yuan@amd.com> Reviewed-by: Alex Deucher <alexander.deucher@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
3840fe256a
commit
4298935924
@ -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 {
|
|||||||
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
|
|||||||
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 {
|
|||||||
(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)
|
|||||||
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 {
|
|||||||
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)
|
|||||||
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 @@ out:
|
|||||||
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)
|
|||||||
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)
|
|||||||
|
|
||||||
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,
|
||||||
|
Loading…
Reference in New Issue
Block a user