[PATCH 15/31] drm/amdgpu: set cp fw address set for gfx v12
Alex Deucher
alexander.deucher at amd.com
Mon Apr 29 14:33:23 UTC 2024
From: Likun Gao <Likun.Gao at amd.com>
Split PFF/ME/MEC firmware address setting function
from related load microcode funtion, as it's also
needed for rlc autolad.
Signed-off-by: Likun Gao <Likun.Gao at amd.com>
Reviewed-by: Hawking Zhang <Hawking.Zhang at amd.com>
Signed-off-by: Alex Deucher <alexander.deucher at amd.com>
---
drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c | 186 ++++++++++++++++---------
1 file changed, 122 insertions(+), 64 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c
index 2075797b8b762..afb977e1dfc81 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c
@@ -1749,6 +1749,110 @@ static void gfx_v12_0_config_gfx_rs64(struct amdgpu_device *adev)
WREG32_SOC15(GC, 0, regCP_MEC_RS64_CNTL, tmp);
}
+static void gfx_v12_0_set_pfp_ucode_start_addr(struct amdgpu_device *adev)
+{
+ const struct gfx_firmware_header_v2_0 *cp_hdr;
+ unsigned pipe_id, tmp;
+
+ cp_hdr = (const struct gfx_firmware_header_v2_0 *)
+ adev->gfx.pfp_fw->data;
+ mutex_lock(&adev->srbm_mutex);
+ for (pipe_id = 0; pipe_id < adev->gfx.me.num_pipe_per_me; pipe_id++) {
+ soc24_grbm_select(adev, 0, pipe_id, 0, 0);
+ WREG32_SOC15(GC, 0, regCP_PFP_PRGRM_CNTR_START,
+ (cp_hdr->ucode_start_addr_hi << 30) |
+ (cp_hdr->ucode_start_addr_lo >> 2));
+ WREG32_SOC15(GC, 0, regCP_PFP_PRGRM_CNTR_START_HI,
+ cp_hdr->ucode_start_addr_hi>>2);
+
+ /*
+ * Program CP_ME_CNTL to reset given PIPE to take
+ * effect of CP_PFP_PRGRM_CNTR_START.
+ */
+ tmp = RREG32_SOC15(GC, 0, regCP_ME_CNTL);
+ if (pipe_id == 0)
+ tmp = REG_SET_FIELD(tmp, CP_ME_CNTL,
+ PFP_PIPE0_RESET, 1);
+ else
+ tmp = REG_SET_FIELD(tmp, CP_ME_CNTL,
+ PFP_PIPE1_RESET, 1);
+ WREG32_SOC15(GC, 0, regCP_ME_CNTL, tmp);
+
+ /* Clear pfp pipe0 reset bit. */
+ if (pipe_id == 0)
+ tmp = REG_SET_FIELD(tmp, CP_ME_CNTL,
+ PFP_PIPE0_RESET, 0);
+ else
+ tmp = REG_SET_FIELD(tmp, CP_ME_CNTL,
+ PFP_PIPE1_RESET, 0);
+ WREG32_SOC15(GC, 0, regCP_ME_CNTL, tmp);
+ }
+ soc24_grbm_select(adev, 0, 0, 0, 0);
+ mutex_unlock(&adev->srbm_mutex);
+}
+
+static void gfx_v12_0_set_me_ucode_start_addr(struct amdgpu_device *adev)
+{
+ const struct gfx_firmware_header_v2_0 *cp_hdr;
+ unsigned pipe_id, tmp;
+
+ cp_hdr = (const struct gfx_firmware_header_v2_0 *)
+ adev->gfx.me_fw->data;
+ mutex_lock(&adev->srbm_mutex);
+ for (pipe_id = 0; pipe_id < adev->gfx.me.num_pipe_per_me; pipe_id++) {
+ soc24_grbm_select(adev, 0, pipe_id, 0, 0);
+ WREG32_SOC15(GC, 0, regCP_ME_PRGRM_CNTR_START,
+ (cp_hdr->ucode_start_addr_hi << 30) |
+ (cp_hdr->ucode_start_addr_lo >> 2) );
+ WREG32_SOC15(GC, 0, regCP_ME_PRGRM_CNTR_START_HI,
+ cp_hdr->ucode_start_addr_hi>>2);
+
+ /*
+ * Program CP_ME_CNTL to reset given PIPE to take
+ * effect of CP_ME_PRGRM_CNTR_START.
+ */
+ tmp = RREG32_SOC15(GC, 0, regCP_ME_CNTL);
+ if (pipe_id == 0)
+ tmp = REG_SET_FIELD(tmp, CP_ME_CNTL,
+ ME_PIPE0_RESET, 1);
+ else
+ tmp = REG_SET_FIELD(tmp, CP_ME_CNTL,
+ ME_PIPE1_RESET, 1);
+ WREG32_SOC15(GC, 0, regCP_ME_CNTL, tmp);
+
+ /* Clear pfp pipe0 reset bit. */
+ if (pipe_id == 0)
+ tmp = REG_SET_FIELD(tmp, CP_ME_CNTL,
+ ME_PIPE0_RESET, 0);
+ else
+ tmp = REG_SET_FIELD(tmp, CP_ME_CNTL,
+ ME_PIPE1_RESET, 0);
+ WREG32_SOC15(GC, 0, regCP_ME_CNTL, tmp);
+ }
+ soc24_grbm_select(adev, 0, 0, 0, 0);
+ mutex_unlock(&adev->srbm_mutex);
+}
+
+static void gfx_v12_0_set_mec_ucode_start_addr(struct amdgpu_device *adev)
+{
+ const struct gfx_firmware_header_v2_0 *cp_hdr;
+ unsigned pipe_id;
+
+ cp_hdr = (const struct gfx_firmware_header_v2_0 *)
+ adev->gfx.mec_fw->data;
+ mutex_lock(&adev->srbm_mutex);
+ for (pipe_id = 0; pipe_id < adev->gfx.mec.num_pipe_per_mec; pipe_id++) {
+ soc24_grbm_select(adev, 1, pipe_id, 0, 0);
+ WREG32_SOC15(GC, 0, regCP_MEC_RS64_PRGRM_CNTR_START,
+ cp_hdr->ucode_start_addr_lo >> 2 |
+ cp_hdr->ucode_start_addr_hi << 30);
+ WREG32_SOC15(GC, 0, regCP_MEC_RS64_PRGRM_CNTR_START_HI,
+ cp_hdr->ucode_start_addr_hi >> 2);
+ }
+ soc24_grbm_select(adev, 0, 0, 0, 0);
+ mutex_unlock(&adev->srbm_mutex);
+}
+
static int gfx_v12_0_wait_for_rlc_autoload_complete(struct amdgpu_device *adev)
{
uint32_t cp_status;
@@ -1774,6 +1878,12 @@ static int gfx_v12_0_wait_for_rlc_autoload_complete(struct amdgpu_device *adev)
return -ETIMEDOUT;
}
+ if (adev->firmware.load_type == AMDGPU_FW_LOAD_RLC_BACKDOOR_AUTO) {
+ gfx_v12_0_set_pfp_ucode_start_addr(adev);
+ gfx_v12_0_set_me_ucode_start_addr(adev);
+ gfx_v12_0_set_mec_ucode_start_addr(adev);
+ }
+
return 0;
}
@@ -1905,33 +2015,6 @@ static int gfx_v12_0_cp_gfx_load_pfp_microcode_rs64(struct amdgpu_device *adev)
mutex_lock(&adev->srbm_mutex);
for (pipe_id = 0; pipe_id < adev->gfx.me.num_pipe_per_me; pipe_id++) {
soc24_grbm_select(adev, 0, pipe_id, 0, 0);
- WREG32_SOC15(GC, 0, regCP_PFP_PRGRM_CNTR_START,
- (pfp_hdr->ucode_start_addr_hi << 30) |
- (pfp_hdr->ucode_start_addr_lo >> 2));
- WREG32_SOC15(GC, 0, regCP_PFP_PRGRM_CNTR_START_HI,
- pfp_hdr->ucode_start_addr_hi>>2);
-
- /*
- * Program CP_ME_CNTL to reset given PIPE to take
- * effect of CP_PFP_PRGRM_CNTR_START.
- */
- tmp = RREG32_SOC15(GC, 0, regCP_ME_CNTL);
- if (pipe_id == 0)
- tmp = REG_SET_FIELD(tmp, CP_ME_CNTL,
- PFP_PIPE0_RESET, 1);
- else
- tmp = REG_SET_FIELD(tmp, CP_ME_CNTL,
- PFP_PIPE1_RESET, 1);
- WREG32_SOC15(GC, 0, regCP_ME_CNTL, tmp);
-
- /* Clear pfp pipe0 reset bit. */
- if (pipe_id == 0)
- tmp = REG_SET_FIELD(tmp, CP_ME_CNTL,
- PFP_PIPE0_RESET, 0);
- else
- tmp = REG_SET_FIELD(tmp, CP_ME_CNTL,
- PFP_PIPE1_RESET, 0);
- WREG32_SOC15(GC, 0, regCP_ME_CNTL, tmp);
WREG32_SOC15(GC, 0, regCP_GFX_RS64_DC_BASE0_LO,
lower_32_bits(adev->gfx.pfp.pfp_fw_data_gpu_addr));
@@ -1964,6 +2047,8 @@ static int gfx_v12_0_cp_gfx_load_pfp_microcode_rs64(struct amdgpu_device *adev)
return -EINVAL;
}
+ gfx_v12_0_set_pfp_ucode_start_addr(adev);
+
return 0;
}
@@ -2075,33 +2160,6 @@ static int gfx_v12_0_cp_gfx_load_me_microcode_rs64(struct amdgpu_device *adev)
mutex_lock(&adev->srbm_mutex);
for (pipe_id = 0; pipe_id < adev->gfx.me.num_pipe_per_me; pipe_id++) {
soc24_grbm_select(adev, 0, pipe_id, 0, 0);
- WREG32_SOC15(GC, 0, regCP_ME_PRGRM_CNTR_START,
- (me_hdr->ucode_start_addr_hi << 30) |
- (me_hdr->ucode_start_addr_lo >> 2));
- WREG32_SOC15(GC, 0, regCP_ME_PRGRM_CNTR_START_HI,
- me_hdr->ucode_start_addr_hi>>2);
-
- /*
- * Program CP_ME_CNTL to reset given PIPE to take
- * effect of CP_PFP_PRGRM_CNTR_START.
- */
- tmp = RREG32_SOC15(GC, 0, regCP_ME_CNTL);
- if (pipe_id == 0)
- tmp = REG_SET_FIELD(tmp, CP_ME_CNTL,
- ME_PIPE0_RESET, 1);
- else
- tmp = REG_SET_FIELD(tmp, CP_ME_CNTL,
- ME_PIPE1_RESET, 1);
- WREG32_SOC15(GC, 0, regCP_ME_CNTL, tmp);
-
- /* Clear pfp pipe0 reset bit. */
- if (pipe_id == 0)
- tmp = REG_SET_FIELD(tmp, CP_ME_CNTL,
- ME_PIPE0_RESET, 0);
- else
- tmp = REG_SET_FIELD(tmp, CP_ME_CNTL,
- ME_PIPE1_RESET, 0);
- WREG32_SOC15(GC, 0, regCP_ME_CNTL, tmp);
WREG32_SOC15(GC, 0, regCP_GFX_RS64_DC_BASE1_LO,
lower_32_bits(adev->gfx.me.me_fw_data_gpu_addr));
@@ -2134,6 +2192,8 @@ static int gfx_v12_0_cp_gfx_load_me_microcode_rs64(struct amdgpu_device *adev)
return -EINVAL;
}
+ gfx_v12_0_set_me_ucode_start_addr(adev);
+
return 0;
}
@@ -2382,19 +2442,15 @@ static int gfx_v12_0_cp_compute_load_microcode_rs64(struct amdgpu_device *adev)
for (i = 0; i < adev->gfx.mec.num_pipe_per_mec; i++) {
soc24_grbm_select(adev, 1, i, 0, 0);
- WREG32_SOC15(GC, 0, regCP_MEC_MDBASE_LO, adev->gfx.mec.mec_fw_data_gpu_addr);
+ WREG32_SOC15(GC, 0, regCP_MEC_MDBASE_LO,
+ lower_32_bits(adev->gfx.mec.mec_fw_data_gpu_addr));
WREG32_SOC15(GC, 0, regCP_MEC_MDBASE_HI,
- upper_32_bits(adev->gfx.mec.mec_fw_data_gpu_addr));
+ upper_32_bits(adev->gfx.mec.mec_fw_data_gpu_addr));
- WREG32_SOC15(GC, 0, regCP_MEC_RS64_PRGRM_CNTR_START,
- mec_hdr->ucode_start_addr_lo >> 2 |
- mec_hdr->ucode_start_addr_hi << 30);
- WREG32_SOC15(GC, 0, regCP_MEC_RS64_PRGRM_CNTR_START_HI,
- mec_hdr->ucode_start_addr_hi >> 2);
-
- WREG32_SOC15(GC, 0, regCP_CPC_IC_BASE_LO, adev->gfx.mec.mec_fw_gpu_addr);
+ WREG32_SOC15(GC, 0, regCP_CPC_IC_BASE_LO,
+ lower_32_bits(adev->gfx.mec.mec_fw_gpu_addr));
WREG32_SOC15(GC, 0, regCP_CPC_IC_BASE_HI,
- upper_32_bits(adev->gfx.mec.mec_fw_gpu_addr));
+ upper_32_bits(adev->gfx.mec.mec_fw_gpu_addr));
}
mutex_unlock(&adev->srbm_mutex);
soc24_grbm_select(adev, 0, 0, 0, 0);
@@ -2437,6 +2493,8 @@ static int gfx_v12_0_cp_compute_load_microcode_rs64(struct amdgpu_device *adev)
return -EINVAL;
}
+ gfx_v12_0_set_mec_ucode_start_addr(adev);
+
return 0;
}
--
2.44.0
More information about the amd-gfx
mailing list