[PATCH 2/2] drm/amdgpu: support key database loading for navi10

Yuan, Xiaojie Xiaojie.Yuan at amd.com
Thu Jul 11 07:13:41 UTC 2019


Reviewed-by: Xiaojie Yuan <xiaojie.yuan at amd.com>

BR,
Xiaojie

________________________________________
From: amd-gfx <amd-gfx-bounces at lists.freedesktop.org> on behalf of Hawking Zhang <Hawking.Zhang at amd.com>
Sent: Wednesday, July 10, 2019 11:58 PM
To: amd-gfx at lists.freedesktop.org; Yuan, Xiaojie; Clements, John; Deucher, Alexander
Cc: Zhang, Hawking
Subject: [PATCH 2/2] 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

Change-Id: Ib82d21840fb77da2217dd8b8f013177e61d72990
Signed-off-by: John Clements <John.Clements at amd.com>
Signed-off-by: Hawking Zhang <Hawking.Zhang at amd.com>
---
 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 at lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx


More information about the amd-gfx mailing list