[PATCH] drm/amdgpu: fix VPE front door loading issue

Alex Deucher alexander.deucher at amd.com
Thu Aug 24 21:47:02 UTC 2023


From: Lang Yu <Lang.Yu at amd.com>

Implement proper front door loading for vpe 6.1.

Signed-off-by: Lang Yu <Lang.Yu at amd.com>
Signed-off-by: Alex Deucher <alexander.deucher at amd.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c   |  3 ++
 drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.h |  1 +
 drivers/gpu/drm/amd/amdgpu/amdgpu_vpe.c   | 38 +++++++++++++++++++++++
 drivers/gpu/drm/amd/amdgpu/amdgpu_vpe.h   |  5 +++
 drivers/gpu/drm/amd/amdgpu/psp_gfx_if.h   |  1 +
 drivers/gpu/drm/amd/amdgpu/vpe_v6_1.c     | 15 +++++++++
 6 files changed, 63 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
index 0eef555e3ef8..bd70715d329f 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
@@ -2396,6 +2396,9 @@ static int psp_get_fw_type(struct amdgpu_firmware_info *ucode,
 	case AMDGPU_UCODE_ID_VPE_CTL:
 		*type = GFX_FW_TYPE_VPEC_FW2;
 		break;
+	case AMDGPU_UCODE_ID_VPE:
+		*type = GFX_FW_TYPE_VPE;
+		break;
 	case AMDGPU_UCODE_ID_MAXIMUM:
 	default:
 		return -EINVAL;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.h
index 0b601efa2944..4db6d0090893 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.h
@@ -489,6 +489,7 @@ enum AMDGPU_UCODE_ID {
 	AMDGPU_UCODE_ID_DMCUB,
 	AMDGPU_UCODE_ID_VPE_CTX,
 	AMDGPU_UCODE_ID_VPE_CTL,
+	AMDGPU_UCODE_ID_VPE,
 	AMDGPU_UCODE_ID_MAXIMUM,
 };
 
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vpe.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vpe.c
index a84e03a9b0fc..ae070072705a 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vpe.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vpe.c
@@ -37,6 +37,17 @@
 
 static void vpe_set_ring_funcs(struct amdgpu_device *adev);
 
+int amdgpu_vpe_psp_update_sram(struct amdgpu_device *adev)
+{
+	struct amdgpu_firmware_info ucode = {
+		.ucode_id = AMDGPU_UCODE_ID_VPE,
+		.mc_addr = adev->vpe.cmdbuf_gpu_addr,
+		.ucode_size = 8,
+	};
+
+	return psp_execute_ip_fw_load(&adev->psp, &ucode);
+}
+
 int amdgpu_vpe_init_microcode(struct amdgpu_vpe *vpe)
 {
 	struct amdgpu_device *adev = vpe->ring.adev;
@@ -126,12 +137,35 @@ static int vpe_early_init(void *handle)
 	return 0;
 }
 
+
+static int vpe_common_init(struct amdgpu_vpe *vpe)
+{
+	struct amdgpu_device *adev = container_of(vpe, struct amdgpu_device, vpe);
+	int r;
+
+	r = amdgpu_bo_create_kernel(adev, PAGE_SIZE, PAGE_SIZE,
+				    AMDGPU_GEM_DOMAIN_GTT,
+				    &adev->vpe.cmdbuf_obj,
+				    &adev->vpe.cmdbuf_gpu_addr,
+				    (void **)&adev->vpe.cmdbuf_cpu_addr);
+	if (r) {
+		dev_err(adev->dev, "VPE: failed to allocate cmdbuf bo %d\n", r);
+		return r;
+	}
+
+	return 0;
+}
+
 static int vpe_sw_init(void *handle)
 {
 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
 	struct amdgpu_vpe *vpe = &adev->vpe;
 	int ret;
 
+	ret = vpe_common_init(vpe);
+	if (ret)
+		goto out;
+
 	ret = vpe_irq_init(vpe);
 	if (ret)
 		goto out;
@@ -157,6 +191,10 @@ static int vpe_sw_fini(void *handle)
 
 	vpe_ring_fini(vpe);
 
+	amdgpu_bo_free_kernel(&adev->vpe.cmdbuf_obj,
+			      &adev->vpe.cmdbuf_gpu_addr,
+			      (void **)&adev->vpe.cmdbuf_cpu_addr);
+
 	return 0;
 }
 
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vpe.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_vpe.h
index 010fa7f308fd..b590205d6a28 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vpe.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vpe.h
@@ -59,8 +59,13 @@ struct amdgpu_vpe {
 	const struct firmware		*fw;
 	uint32_t			fw_version;
 	uint32_t			feature_version;
+
+	struct amdgpu_bo		*cmdbuf_obj;
+	uint64_t			cmdbuf_gpu_addr;
+	uint32_t			*cmdbuf_cpu_addr;
 };
 
+int amdgpu_vpe_psp_update_sram(struct amdgpu_device *adev);
 int amdgpu_vpe_init_microcode(struct amdgpu_vpe *vpe);
 int amdgpu_vpe_ring_init(struct amdgpu_vpe *vpe);
 int amdgpu_vpe_ring_fini(struct amdgpu_vpe *vpe);
diff --git a/drivers/gpu/drm/amd/amdgpu/psp_gfx_if.h b/drivers/gpu/drm/amd/amdgpu/psp_gfx_if.h
index fd11115429c8..dfd60db97012 100644
--- a/drivers/gpu/drm/amd/amdgpu/psp_gfx_if.h
+++ b/drivers/gpu/drm/amd/amdgpu/psp_gfx_if.h
@@ -295,6 +295,7 @@ enum psp_gfx_fw_type {
 	GFX_FW_TYPE_RS64_MEC_P3_STACK               = 97,   /* RS64 MEC stack P3        SOC21   */
 	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,
 	GFX_FW_TYPE_MAX
 };
 
diff --git a/drivers/gpu/drm/amd/amdgpu/vpe_v6_1.c b/drivers/gpu/drm/amd/amdgpu/vpe_v6_1.c
index 1a483d38e70d..1259b150dc96 100644
--- a/drivers/gpu/drm/amd/amdgpu/vpe_v6_1.c
+++ b/drivers/gpu/drm/amd/amdgpu/vpe_v6_1.c
@@ -84,6 +84,21 @@ static int vpe_v6_1_load_microcode(struct amdgpu_vpe *vpe)
 	ret = REG_SET_FIELD(ret, VPEC_CNTL, UMSCH_INT_ENABLE, 0);
 	WREG32(vpe_get_reg_offset(vpe, 0, regVPEC_CNTL), ret);
 
+	if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) {
+		uint32_t f32_offset, f32_cntl;
+
+		f32_offset = vpe_get_reg_offset(vpe, 0, regVPEC_F32_CNTL);
+		f32_cntl = RREG32(f32_offset);
+		f32_cntl = REG_SET_FIELD(f32_cntl, VPEC_F32_CNTL, HALT, 0);
+		f32_cntl = REG_SET_FIELD(f32_cntl, VPEC_F32_CNTL, TH1_RESET, 0);
+
+		adev->vpe.cmdbuf_cpu_addr[0] = f32_offset;
+		adev->vpe.cmdbuf_cpu_addr[1] = f32_cntl;
+
+		amdgpu_vpe_psp_update_sram(adev);
+		return 0;
+	}
+
 	vpe_hdr = (const struct vpe_firmware_header_v1_0 *)adev->vpe.fw->data;
 
 	/* Thread 0(command thread) ucode offset/size */
-- 
2.41.0



More information about the amd-gfx mailing list