From 708b8589f2605a170b572478a2fb3755bb9f272f Mon Sep 17 00:00:00 2001 From: Feifei Xu Date: Mon, 28 Jul 2025 18:58:08 +0800 Subject: [PATCH] drm/amdgpu: Add rlcv firmware for frontdoor loading. Rlcv is required to be loaded for frontdoor. 1. Add 2 rlcv ucode ids: AMDGPU_UCODE_RLC_IRAM_1 and AMDGPU_UCODE_RLC_DRAM_1 2. Add rlc_firmware_header_v2_5 for above 2 rlcv headers. 3. Add 2 types in psp_fw_gfx_if interface interacting with asp: GFX_FW_TYPE_RLX6_UCODE_CORE1 - RLCV IRAM GFX_FW_TYPE_RLX6_DRAM_BOOT_CORE1 - RLCV DRAM BOOT Signed-off-by: Feifei Xu Reviewed-by: Hawking Zhang Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c | 8 +++++ drivers/gpu/drm/amd/amdgpu/amdgpu_rlc.c | 37 ++++++++++++++++++++++- drivers/gpu/drm/amd/amdgpu/amdgpu_rlc.h | 4 +++ drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c | 34 +++++++++++++++++++++ drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.h | 12 ++++++++ drivers/gpu/drm/amd/amdgpu/psp_gfx_if.h | 2 ++ 6 files changed, 96 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c index 0b10497d487c3..f810dac096b24 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c @@ -2719,6 +2719,12 @@ static int psp_get_fw_type(struct amdgpu_firmware_info *ucode, case AMDGPU_UCODE_ID_RLC_DRAM: *type = GFX_FW_TYPE_RLC_DRAM_BOOT; break; + case AMDGPU_UCODE_ID_RLC_IRAM_1: + *type = GFX_FW_TYPE_RLX6_UCODE_CORE1; + break; + case AMDGPU_UCODE_ID_RLC_DRAM_1: + *type = GFX_FW_TYPE_RLX6_DRAM_BOOT_CORE1; + break; case AMDGPU_UCODE_ID_GLOBAL_TAP_DELAYS: *type = GFX_FW_TYPE_GLOBAL_TAP_DELAYS; break; @@ -2887,6 +2893,8 @@ static void psp_print_fw_hdr(struct psp_context *psp, amdgpu_ucode_print_gfx_hdr(hdr); break; case AMDGPU_UCODE_ID_RLC_G: + case AMDGPU_UCODE_ID_RLC_DRAM_1: + case AMDGPU_UCODE_ID_RLC_IRAM_1: hdr = (struct common_firmware_header *)adev->gfx.rlc_fw->data; amdgpu_ucode_print_rlc_hdr(hdr); break; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_rlc.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_rlc.c index 5aa830a02d80b..572a60e1b3cbb 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_rlc.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_rlc.c @@ -515,6 +515,40 @@ static void amdgpu_gfx_rlc_init_microcode_v2_4(struct amdgpu_device *adev) } } +static void amdgpu_gfx_rlc_init_microcode_v2_5(struct amdgpu_device *adev) +{ + const struct rlc_firmware_header_v2_5 *rlc_hdr; + struct amdgpu_firmware_info *info; + + rlc_hdr = (const struct rlc_firmware_header_v2_5 *)adev->gfx.rlc_fw->data; + adev->gfx.rlc.rlc_1_iram_ucode_size_bytes = + le32_to_cpu(rlc_hdr->rlc_1_iram_ucode_size_bytes); + adev->gfx.rlc.rlc_1_iram_ucode = (u8 *)rlc_hdr + + le32_to_cpu(rlc_hdr->rlc_1_iram_ucode_offset_bytes); + adev->gfx.rlc.rlc_1_dram_ucode_size_bytes = + le32_to_cpu(rlc_hdr->rlc_1_dram_ucode_size_bytes); + adev->gfx.rlc.rlc_1_dram_ucode = (u8 *)rlc_hdr + + le32_to_cpu(rlc_hdr->rlc_1_dram_ucode_offset_bytes); + + if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) { + if (adev->gfx.rlc.rlc_1_iram_ucode_size_bytes) { + info = &adev->firmware.ucode[AMDGPU_UCODE_ID_RLC_IRAM_1]; + info->ucode_id = AMDGPU_UCODE_ID_RLC_IRAM_1; + info->fw = adev->gfx.rlc_fw; + adev->firmware.fw_size += + ALIGN(adev->gfx.rlc.rlc_1_iram_ucode_size_bytes, PAGE_SIZE); + } + + if (adev->gfx.rlc.rlc_1_dram_ucode_size_bytes) { + info = &adev->firmware.ucode[AMDGPU_UCODE_ID_RLC_DRAM_1]; + info->ucode_id = AMDGPU_UCODE_ID_RLC_DRAM_1; + info->fw = adev->gfx.rlc_fw; + adev->firmware.fw_size += + ALIGN(adev->gfx.rlc.rlc_1_dram_ucode_size_bytes, PAGE_SIZE); + } + } +} + int amdgpu_gfx_rlc_init_microcode(struct amdgpu_device *adev, uint16_t version_major, uint16_t version_minor) @@ -545,6 +579,7 @@ int amdgpu_gfx_rlc_init_microcode(struct amdgpu_device *adev, amdgpu_gfx_rlc_init_microcode_v2_3(adev); if (version_minor == 4) amdgpu_gfx_rlc_init_microcode_v2_4(adev); - + if (version_minor == 5) + amdgpu_gfx_rlc_init_microcode_v2_5(adev); return 0; } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_rlc.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_rlc.h index 3e2d2e333907d..32408574548dd 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_rlc.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_rlc.h @@ -311,6 +311,8 @@ struct amdgpu_rlc { u32 save_restore_list_srm_size_bytes; u32 rlc_iram_ucode_size_bytes; u32 rlc_dram_ucode_size_bytes; + u32 rlc_1_iram_ucode_size_bytes; + u32 rlc_1_dram_ucode_size_bytes; u32 rlcp_ucode_size_bytes; u32 rlcv_ucode_size_bytes; u32 global_tap_delays_ucode_size_bytes; @@ -326,6 +328,8 @@ struct amdgpu_rlc { u8 *save_restore_list_srm; u8 *rlc_iram_ucode; u8 *rlc_dram_ucode; + u8 *rlc_1_iram_ucode; + u8 *rlc_1_dram_ucode; u8 *rlcp_ucode; u8 *rlcv_ucode; u8 *global_tap_delays_ucode; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c index e96f24e9ad571..1ab61e7b35db6 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c @@ -166,6 +166,8 @@ void amdgpu_ucode_print_rlc_hdr(const struct common_firmware_header *hdr) container_of(rlc_hdr_v2_2, struct rlc_firmware_header_v2_3, v2_2); const struct rlc_firmware_header_v2_4 *rlc_hdr_v2_4 = container_of(rlc_hdr_v2_3, struct rlc_firmware_header_v2_4, v2_3); + const struct rlc_firmware_header_v2_5 *rlc_hdr_v2_5 = + container_of(rlc_hdr_v2_2, struct rlc_firmware_header_v2_5, v2_2); switch (version_minor) { case 0: @@ -287,6 +289,26 @@ void amdgpu_ucode_print_rlc_hdr(const struct common_firmware_header *hdr) DRM_DEBUG("se3_tap_delays_ucode_offset_bytes: %u\n", le32_to_cpu(rlc_hdr_v2_4->se3_tap_delays_ucode_offset_bytes)); break; + case 5: + /* rlc_hdr v2_5 */ + DRM_INFO("rlc_iram_ucode_size_bytes: %u\n", + le32_to_cpu(rlc_hdr_v2_5->v2_2.rlc_iram_ucode_size_bytes)); + DRM_INFO("rlc_iram_ucode_offset_bytes: %u\n", + le32_to_cpu(rlc_hdr_v2_5->v2_2.rlc_iram_ucode_offset_bytes)); + DRM_INFO("rlc_dram_ucode_size_bytes: %u\n", + le32_to_cpu(rlc_hdr_v2_5->v2_2.rlc_dram_ucode_size_bytes)); + DRM_INFO("rlc_dram_ucode_offset_bytes: %u\n", + le32_to_cpu(rlc_hdr_v2_5->v2_2.rlc_dram_ucode_offset_bytes)); + /* rlc_hdr v2_5 */ + DRM_INFO("rlc_1_iram_ucode_size_bytes: %u\n", + le32_to_cpu(rlc_hdr_v2_5->rlc_1_iram_ucode_size_bytes)); + DRM_INFO("rlc_1_iram_ucode_offset_bytes: %u\n", + le32_to_cpu(rlc_hdr_v2_5->rlc_1_iram_ucode_offset_bytes)); + DRM_INFO("rlc_1_dram_ucode_size_bytes: %u\n", + le32_to_cpu(rlc_hdr_v2_5->rlc_1_dram_ucode_size_bytes)); + DRM_INFO("rlc_1_dram_ucode_offset_bytes: %u\n", + le32_to_cpu(rlc_hdr_v2_5->rlc_1_dram_ucode_offset_bytes)); + break; default: DRM_ERROR("Unknown RLC v2 ucode: v2.%u\n", version_minor); break; @@ -631,6 +653,10 @@ const char *amdgpu_ucode_name(enum AMDGPU_UCODE_ID ucode_id) return "RLC_IRAM"; case AMDGPU_UCODE_ID_RLC_DRAM: return "RLC_DRAM"; + case AMDGPU_UCODE_ID_RLC_IRAM_1: + return "RLC_IRAM_1"; + case AMDGPU_UCODE_ID_RLC_DRAM_1: + return "RLC_DRAM_1"; case AMDGPU_UCODE_ID_RLC_G: return "RLC_G"; case AMDGPU_UCODE_ID_RLC_P: @@ -911,6 +937,14 @@ static int amdgpu_ucode_init_single_fw(struct amdgpu_device *adev, ucode->ucode_size = adev->gfx.rlc.rlc_dram_ucode_size_bytes; ucode_addr = adev->gfx.rlc.rlc_dram_ucode; break; + case AMDGPU_UCODE_ID_RLC_IRAM_1: + ucode->ucode_size = adev->gfx.rlc.rlc_1_iram_ucode_size_bytes; + ucode_addr = adev->gfx.rlc.rlc_1_iram_ucode; + break; + case AMDGPU_UCODE_ID_RLC_DRAM_1: + ucode->ucode_size = adev->gfx.rlc.rlc_1_dram_ucode_size_bytes; + ucode_addr = adev->gfx.rlc.rlc_1_dram_ucode; + break; case AMDGPU_UCODE_ID_RLC_P: ucode->ucode_size = adev->gfx.rlc.rlcp_ucode_size_bytes; ucode_addr = adev->gfx.rlc.rlcp_ucode; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.h index 6349aad6da35b..f316776fe950a 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.h @@ -300,6 +300,15 @@ struct rlc_firmware_header_v2_4 { uint32_t se3_tap_delays_ucode_offset_bytes; }; +/* version_major=2, version_minor=5 */ +struct rlc_firmware_header_v2_5 { + struct rlc_firmware_header_v2_2 v2_2; + uint32_t rlc_1_iram_ucode_size_bytes; + uint32_t rlc_1_iram_ucode_offset_bytes; + uint32_t rlc_1_dram_ucode_size_bytes; + uint32_t rlc_1_dram_ucode_offset_bytes; +}; + /* version_major=1, version_minor=0 */ struct sdma_firmware_header_v1_0 { struct common_firmware_header header; @@ -449,6 +458,7 @@ union amdgpu_firmware_header { struct rlc_firmware_header_v2_2 rlc_v2_2; struct rlc_firmware_header_v2_3 rlc_v2_3; struct rlc_firmware_header_v2_4 rlc_v2_4; + struct rlc_firmware_header_v2_5 rlc_v2_5; struct sdma_firmware_header_v1_0 sdma; struct sdma_firmware_header_v1_1 sdma_v1_1; struct sdma_firmware_header_v2_0 sdma_v2_0; @@ -512,6 +522,8 @@ enum AMDGPU_UCODE_ID { AMDGPU_UCODE_ID_RLC_RESTORE_LIST_SRM_MEM, AMDGPU_UCODE_ID_RLC_IRAM, AMDGPU_UCODE_ID_RLC_DRAM, + AMDGPU_UCODE_ID_RLC_IRAM_1, + AMDGPU_UCODE_ID_RLC_DRAM_1, AMDGPU_UCODE_ID_RLC_P, AMDGPU_UCODE_ID_RLC_V, AMDGPU_UCODE_ID_RLC_G, diff --git a/drivers/gpu/drm/amd/amdgpu/psp_gfx_if.h b/drivers/gpu/drm/amd/amdgpu/psp_gfx_if.h index 73f87131a7e9f..e8f768638fd59 100644 --- a/drivers/gpu/drm/amd/amdgpu/psp_gfx_if.h +++ b/drivers/gpu/drm/amd/amdgpu/psp_gfx_if.h @@ -299,6 +299,8 @@ enum psp_gfx_fw_type { GFX_FW_TYPE_RS64_MEC_P1_STACK = 95, /* RS64 MEC stack P1 SOC21 */ GFX_FW_TYPE_RS64_MEC_P2_STACK = 96, /* RS64 MEC stack P2 SOC21 */ GFX_FW_TYPE_RS64_MEC_P3_STACK = 97, /* RS64 MEC stack P3 SOC21 */ + GFX_FW_TYPE_RLX6_UCODE_CORE1 = 98, /* RLCV_IRAM MI */ + GFX_FW_TYPE_RLX6_DRAM_BOOT_CORE1 = 99, /* RLCV DRAM BOOT MI */ GFX_FW_TYPE_VPEC_FW1 = 100, /* VPEC FW1 To Save VPE */ GFX_FW_TYPE_VPEC_FW2 = 101, /* VPEC FW2 To Save VPE */ GFX_FW_TYPE_VPE = 102, -- 2.47.3