|
@@ -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,
|