drm/amdgpu: add save restore list cntl gpm and srm firmware support
authorHuang Rui <ray.huang@amd.com>
Mon, 22 Jan 2018 12:48:14 +0000 (20:48 +0800)
committerAlex Deucher <alexander.deucher@amd.com>
Tue, 15 May 2018 18:43:36 +0000 (13:43 -0500)
RLC save/restore list cntl/gpm_mem/srm_mem ucodes are used for CGPG and gfxoff
function.

Signed-off-by: Huang Rui <ray.huang@amd.com>
Acked-by: Alex Deucher <alexander.deucher@amd.com>
Acked-by: Christian König <christian.koenig@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/amdgpu/amdgpu.h
drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c
drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.h
drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c
drivers/gpu/drm/amd/amdgpu/psp_v10_0.c
include/uapi/drm/amdgpu_drm.h

index d64ef30..5ad8939 100644 (file)
@@ -774,9 +774,18 @@ struct amdgpu_rlc {
        u32 starting_offsets_start;
        u32 reg_list_format_size_bytes;
        u32 reg_list_size_bytes;
+       u32 reg_list_format_direct_reg_list_length;
+       u32 save_restore_list_cntl_size_bytes;
+       u32 save_restore_list_gpm_size_bytes;
+       u32 save_restore_list_srm_size_bytes;
 
        u32 *register_list_format;
        u32 *register_restore;
+       u8 *save_restore_list_cntl;
+       u8 *save_restore_list_gpm;
+       u8 *save_restore_list_srm;
+
+       bool is_rlc_v2_1;
 };
 
 #define AMDGPU_MAX_COMPUTE_QUEUES KGD_MAX_QUEUES
@@ -943,6 +952,12 @@ struct amdgpu_gfx {
        uint32_t                        ce_feature_version;
        uint32_t                        pfp_feature_version;
        uint32_t                        rlc_feature_version;
+       uint32_t                        rlc_srlc_fw_version;
+       uint32_t                        rlc_srlc_feature_version;
+       uint32_t                        rlc_srlg_fw_version;
+       uint32_t                        rlc_srlg_feature_version;
+       uint32_t                        rlc_srls_fw_version;
+       uint32_t                        rlc_srls_feature_version;
        uint32_t                        mec_feature_version;
        uint32_t                        mec2_feature_version;
        struct amdgpu_ring              gfx_ring[AMDGPU_MAX_GFX_RINGS];
index d602f8b..eb4785e 100644 (file)
@@ -215,6 +215,18 @@ static int amdgpu_firmware_info(struct drm_amdgpu_info_firmware *fw_info,
                fw_info->ver = adev->gfx.rlc_fw_version;
                fw_info->feature = adev->gfx.rlc_feature_version;
                break;
+       case AMDGPU_INFO_FW_GFX_RLC_RESTORE_LIST_CNTL:
+               fw_info->ver = adev->gfx.rlc_srlc_fw_version;
+               fw_info->feature = adev->gfx.rlc_srlc_feature_version;
+               break;
+       case AMDGPU_INFO_FW_GFX_RLC_RESTORE_LIST_GPM_MEM:
+               fw_info->ver = adev->gfx.rlc_srlg_fw_version;
+               fw_info->feature = adev->gfx.rlc_srlg_feature_version;
+               break;
+       case AMDGPU_INFO_FW_GFX_RLC_RESTORE_LIST_SRM_MEM:
+               fw_info->ver = adev->gfx.rlc_srls_fw_version;
+               fw_info->feature = adev->gfx.rlc_srls_feature_version;
+               break;
        case AMDGPU_INFO_FW_GFX_MEC:
                if (query_fw->index == 0) {
                        fw_info->ver = adev->gfx.mec_fw_version;
@@ -1149,6 +1161,30 @@ static int amdgpu_debugfs_firmware_info(struct seq_file *m, void *data)
        seq_printf(m, "RLC feature version: %u, firmware version: 0x%08x\n",
                   fw_info.feature, fw_info.ver);
 
+       /* RLC SAVE RESTORE LIST CNTL */
+       query_fw.fw_type = AMDGPU_INFO_FW_GFX_RLC_RESTORE_LIST_CNTL;
+       ret = amdgpu_firmware_info(&fw_info, &query_fw, adev);
+       if (ret)
+               return ret;
+       seq_printf(m, "RLC SRLC feature version: %u, firmware version: 0x%08x\n",
+                  fw_info.feature, fw_info.ver);
+
+       /* RLC SAVE RESTORE LIST GPM MEM */
+       query_fw.fw_type = AMDGPU_INFO_FW_GFX_RLC_RESTORE_LIST_GPM_MEM;
+       ret = amdgpu_firmware_info(&fw_info, &query_fw, adev);
+       if (ret)
+               return ret;
+       seq_printf(m, "RLC SRLG feature version: %u, firmware version: 0x%08x\n",
+                  fw_info.feature, fw_info.ver);
+
+       /* RLC SAVE RESTORE LIST SRM MEM */
+       query_fw.fw_type = AMDGPU_INFO_FW_GFX_RLC_RESTORE_LIST_SRM_MEM;
+       ret = amdgpu_firmware_info(&fw_info, &query_fw, adev);
+       if (ret)
+               return ret;
+       seq_printf(m, "RLC SRLS feature version: %u, firmware version: 0x%08x\n",
+                  fw_info.feature, fw_info.ver);
+
        /* MEC */
        query_fw.fw_type = AMDGPU_INFO_FW_GFX_MEC;
        query_fw.index = 0;
index 84d6525..0c74c09 100644 (file)
@@ -337,7 +337,10 @@ static int amdgpu_ucode_init_single_fw(struct amdgpu_device *adev,
            (ucode->ucode_id != AMDGPU_UCODE_ID_CP_MEC1 &&
             ucode->ucode_id != AMDGPU_UCODE_ID_CP_MEC2 &&
             ucode->ucode_id != AMDGPU_UCODE_ID_CP_MEC1_JT &&
-            ucode->ucode_id != AMDGPU_UCODE_ID_CP_MEC2_JT)) {
+            ucode->ucode_id != AMDGPU_UCODE_ID_CP_MEC2_JT &&
+            ucode->ucode_id != AMDGPU_UCODE_ID_RLC_RESTORE_LIST_CNTL &&
+            ucode->ucode_id != AMDGPU_UCODE_ID_RLC_RESTORE_LIST_GPM_MEM &&
+            ucode->ucode_id != AMDGPU_UCODE_ID_RLC_RESTORE_LIST_SRM_MEM)) {
                ucode->ucode_size = le32_to_cpu(header->ucode_size_bytes);
 
                memcpy(ucode->kaddr, (void *)((uint8_t *)ucode->fw->data +
@@ -359,6 +362,18 @@ static int amdgpu_ucode_init_single_fw(struct amdgpu_device *adev,
                                              le32_to_cpu(header->ucode_array_offset_bytes) +
                                              le32_to_cpu(cp_hdr->jt_offset) * 4),
                       ucode->ucode_size);
+       } else if (ucode->ucode_id == AMDGPU_UCODE_ID_RLC_RESTORE_LIST_CNTL) {
+               ucode->ucode_size = adev->gfx.rlc.save_restore_list_cntl_size_bytes;
+               memcpy(ucode->kaddr, adev->gfx.rlc.save_restore_list_cntl,
+                      ucode->ucode_size);
+       } else if (ucode->ucode_id == AMDGPU_UCODE_ID_RLC_RESTORE_LIST_GPM_MEM) {
+               ucode->ucode_size = adev->gfx.rlc.save_restore_list_gpm_size_bytes;
+               memcpy(ucode->kaddr, adev->gfx.rlc.save_restore_list_gpm,
+                      ucode->ucode_size);
+       } else if (ucode->ucode_id == AMDGPU_UCODE_ID_RLC_RESTORE_LIST_SRM_MEM) {
+               ucode->ucode_size = adev->gfx.rlc.save_restore_list_srm_size_bytes;
+               memcpy(ucode->kaddr, adev->gfx.rlc.save_restore_list_srm,
+                      ucode->ucode_size);
        }
 
        return 0;
index 0b262f4..08e3857 100644 (file)
@@ -187,6 +187,9 @@ enum AMDGPU_UCODE_ID {
        AMDGPU_UCODE_ID_CP_MEC2,
        AMDGPU_UCODE_ID_CP_MEC2_JT,
        AMDGPU_UCODE_ID_RLC_G,
+       AMDGPU_UCODE_ID_RLC_RESTORE_LIST_CNTL,
+       AMDGPU_UCODE_ID_RLC_RESTORE_LIST_GPM_MEM,
+       AMDGPU_UCODE_ID_RLC_RESTORE_LIST_SRM_MEM,
        AMDGPU_UCODE_ID_STORAGE,
        AMDGPU_UCODE_ID_SMC,
        AMDGPU_UCODE_ID_UVD,
index 587a873..73b76fa 100644 (file)
@@ -41,7 +41,6 @@
 #define GFX9_MEC_HPD_SIZE 2048
 #define RLCG_UCODE_LOADING_START_ADDRESS 0x00002000L
 #define RLC_SAVE_RESTORE_ADDR_STARTING_OFFSET 0x00000000L
-#define GFX9_RLC_FORMAT_DIRECT_REG_LIST_LENGTH 34
 
 #define mmPWR_MISC_CNTL_STATUS                                 0x0183
 #define mmPWR_MISC_CNTL_STATUS_BASE_IDX                                0
@@ -401,6 +400,27 @@ static void gfx_v9_0_free_microcode(struct amdgpu_device *adev)
        kfree(adev->gfx.rlc.register_list_format);
 }
 
+static void gfx_v9_0_init_rlc_ext_microcode(struct amdgpu_device *adev)
+{
+       const struct rlc_firmware_header_v2_1 *rlc_hdr;
+
+       rlc_hdr = (const struct rlc_firmware_header_v2_1 *)adev->gfx.rlc_fw->data;
+       adev->gfx.rlc_srlc_fw_version = le32_to_cpu(rlc_hdr->save_restore_list_cntl_ucode_ver);
+       adev->gfx.rlc_srlc_feature_version = le32_to_cpu(rlc_hdr->save_restore_list_cntl_feature_ver);
+       adev->gfx.rlc.save_restore_list_cntl_size_bytes = le32_to_cpu(rlc_hdr->save_restore_list_cntl_size_bytes);
+       adev->gfx.rlc.save_restore_list_cntl = (u8 *)rlc_hdr + le32_to_cpu(rlc_hdr->save_restore_list_cntl_offset_bytes);
+       adev->gfx.rlc_srlg_fw_version = le32_to_cpu(rlc_hdr->save_restore_list_gpm_ucode_ver);
+       adev->gfx.rlc_srlg_feature_version = le32_to_cpu(rlc_hdr->save_restore_list_gpm_feature_ver);
+       adev->gfx.rlc.save_restore_list_gpm_size_bytes = le32_to_cpu(rlc_hdr->save_restore_list_gpm_size_bytes);
+       adev->gfx.rlc.save_restore_list_gpm = (u8 *)rlc_hdr + le32_to_cpu(rlc_hdr->save_restore_list_gpm_offset_bytes);
+       adev->gfx.rlc_srls_fw_version = le32_to_cpu(rlc_hdr->save_restore_list_srm_ucode_ver);
+       adev->gfx.rlc_srls_feature_version = le32_to_cpu(rlc_hdr->save_restore_list_srm_feature_ver);
+       adev->gfx.rlc.save_restore_list_srm_size_bytes = le32_to_cpu(rlc_hdr->save_restore_list_srm_size_bytes);
+       adev->gfx.rlc.save_restore_list_srm = (u8 *)rlc_hdr + le32_to_cpu(rlc_hdr->save_restore_list_srm_offset_bytes);
+       adev->gfx.rlc.reg_list_format_direct_reg_list_length =
+                       le32_to_cpu(rlc_hdr->reg_list_format_direct_reg_list_length);
+}
+
 static int gfx_v9_0_init_microcode(struct amdgpu_device *adev)
 {
        const char *chip_name;
@@ -412,6 +432,8 @@ static int gfx_v9_0_init_microcode(struct amdgpu_device *adev)
        const struct rlc_firmware_header_v2_0 *rlc_hdr;
        unsigned int *tmp = NULL;
        unsigned int i = 0;
+       uint16_t version_major;
+       uint16_t version_minor;
 
        DRM_DEBUG("\n");
 
@@ -468,6 +490,12 @@ static int gfx_v9_0_init_microcode(struct amdgpu_device *adev)
                goto out;
        err = amdgpu_ucode_validate(adev->gfx.rlc_fw);
        rlc_hdr = (const struct rlc_firmware_header_v2_0 *)adev->gfx.rlc_fw->data;
+
+       version_major = le16_to_cpu(rlc_hdr->header.header_version_major);
+       version_minor = le16_to_cpu(rlc_hdr->header.header_version_minor);
+       if (version_major == 2 && version_minor == 1)
+               adev->gfx.rlc.is_rlc_v2_1 = true;
+
        adev->gfx.rlc_fw_version = le32_to_cpu(rlc_hdr->header.ucode_version);
        adev->gfx.rlc_feature_version = le32_to_cpu(rlc_hdr->ucode_feature_version);
        adev->gfx.rlc.save_and_restore_offset =
@@ -508,6 +536,9 @@ static int gfx_v9_0_init_microcode(struct amdgpu_device *adev)
        for (i = 0 ; i < (rlc_hdr->reg_list_size_bytes >> 2); i++)
                adev->gfx.rlc.register_restore[i] = le32_to_cpu(tmp[i]);
 
+       if (adev->gfx.rlc.is_rlc_v2_1)
+               gfx_v9_0_init_rlc_ext_microcode(adev);
+
        snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_mec.bin", chip_name);
        err = request_firmware(&adev->gfx.mec_fw, fw_name, adev->dev);
        if (err)
@@ -566,6 +597,26 @@ static int gfx_v9_0_init_microcode(struct amdgpu_device *adev)
                adev->firmware.fw_size +=
                        ALIGN(le32_to_cpu(header->ucode_size_bytes), PAGE_SIZE);
 
+               if (adev->gfx.rlc.is_rlc_v2_1) {
+                       info = &adev->firmware.ucode[AMDGPU_UCODE_ID_RLC_RESTORE_LIST_CNTL];
+                       info->ucode_id = AMDGPU_UCODE_ID_RLC_RESTORE_LIST_CNTL;
+                       info->fw = adev->gfx.rlc_fw;
+                       adev->firmware.fw_size +=
+                               ALIGN(adev->gfx.rlc.save_restore_list_cntl_size_bytes, PAGE_SIZE);
+
+                       info = &adev->firmware.ucode[AMDGPU_UCODE_ID_RLC_RESTORE_LIST_GPM_MEM];
+                       info->ucode_id = AMDGPU_UCODE_ID_RLC_RESTORE_LIST_GPM_MEM;
+                       info->fw = adev->gfx.rlc_fw;
+                       adev->firmware.fw_size +=
+                               ALIGN(adev->gfx.rlc.save_restore_list_gpm_size_bytes, PAGE_SIZE);
+
+                       info = &adev->firmware.ucode[AMDGPU_UCODE_ID_RLC_RESTORE_LIST_SRM_MEM];
+                       info->ucode_id = AMDGPU_UCODE_ID_RLC_RESTORE_LIST_SRM_MEM;
+                       info->fw = adev->gfx.rlc_fw;
+                       adev->firmware.fw_size +=
+                               ALIGN(adev->gfx.rlc.save_restore_list_srm_size_bytes, PAGE_SIZE);
+               }
+
                info = &adev->firmware.ucode[AMDGPU_UCODE_ID_CP_MEC1];
                info->ucode_id = AMDGPU_UCODE_ID_CP_MEC1;
                info->fw = adev->gfx.mec_fw;
@@ -1781,7 +1832,7 @@ static int gfx_v9_0_init_rlc_save_restore_list(struct amdgpu_device *adev)
 
        /* setup unique_indirect_regs array and indirect_start_offsets array */
        gfx_v9_0_parse_ind_reg_list(register_list_format,
-                               GFX9_RLC_FORMAT_DIRECT_REG_LIST_LENGTH,
+                               adev->gfx.rlc.reg_list_format_direct_reg_list_length,
                                adev->gfx.rlc.reg_list_format_size_bytes >> 2,
                                unique_indirect_regs,
                                &unique_indirect_reg_count,
index 8873d83..0ff136d 100644 (file)
@@ -70,6 +70,15 @@ psp_v10_0_get_fw_type(struct amdgpu_firmware_info *ucode, enum psp_gfx_fw_type *
        case AMDGPU_UCODE_ID_RLC_G:
                *type = GFX_FW_TYPE_RLC_G;
                break;
+       case AMDGPU_UCODE_ID_RLC_RESTORE_LIST_CNTL:
+               *type = GFX_FW_TYPE_RLC_RESTORE_LIST_CNTL;
+               break;
+       case AMDGPU_UCODE_ID_RLC_RESTORE_LIST_GPM_MEM:
+               *type = GFX_FW_TYPE_RLC_RESTORE_LIST_GPM_MEM;
+               break;
+       case AMDGPU_UCODE_ID_RLC_RESTORE_LIST_SRM_MEM:
+               *type = GFX_FW_TYPE_RLC_RESTORE_LIST_SRM_MEM;
+               break;
        case AMDGPU_UCODE_ID_SMC:
                *type = GFX_FW_TYPE_SMU;
                break;
index 78fe828..081d256 100644 (file)
@@ -630,6 +630,12 @@ struct drm_amdgpu_cs_chunk_data {
        #define AMDGPU_INFO_FW_ASD              0x0d
        /* Subquery id: Query VCN firmware version */
        #define AMDGPU_INFO_FW_VCN              0x0e
+       /* Subquery id: Query GFX RLC SRLC firmware version */
+       #define AMDGPU_INFO_FW_GFX_RLC_RESTORE_LIST_CNTL 0x0f
+       /* Subquery id: Query GFX RLC SRLG firmware version */
+       #define AMDGPU_INFO_FW_GFX_RLC_RESTORE_LIST_GPM_MEM 0x10
+       /* Subquery id: Query GFX RLC SRLS firmware version */
+       #define AMDGPU_INFO_FW_GFX_RLC_RESTORE_LIST_SRM_MEM 0x11
 /* number of bytes moved for TTM migration */
 #define AMDGPU_INFO_NUM_BYTES_MOVED            0x0f
 /* the used VRAM size */