[PATCH 05/13] drm/amdgpu: VCN 5_0_2 add support for multi-instance

<[email protected]> Sun, 9 Aug 2026 23:36:36 -0400
Newsgroups org.freedesktop.lists.amd-gfx
Message-ID <[email protected]>
From: Sonny Jiang <[email protected]>

VCN 5.0.2 has two VCN instances per MID. Update the SOC configuration
and VCN 5.0.2 initialization to handle multiple instances

Signed-off-by: Sonny Jiang <[email protected]>
Reviewed-by: Leo Liu <[email protected]>
---
 drivers/gpu/drm/amd/amdgpu/soc_v1_0.c   |  2 +-
 drivers/gpu/drm/amd/amdgpu/vcn_v5_0_2.c | 54 ++++++++++++++++++++-----
 2 files changed, 45 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/soc_v1_0.c b/drivers/gpu/drm/amd/amdgpu/soc_v1_0.c
index 04c49e23d79b..db48bf2bc213 100644
--- a/drivers/gpu/drm/amd/amdgpu/soc_v1_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/soc_v1_0.c
@@ -850,7 +850,7 @@ int soc_v1_0_init_soc_config(struct amdgpu_device *adev)
 	adev->sdma.num_instances = NUM_XCC(adev->sdma.sdma_mask);
 
 	adev->vcn.harvest_config = 0;
-	adev->vcn.num_inst_per_aid = 1;
+	adev->vcn.num_inst_per_aid = 2;
 	adev->vcn.inst_mask = 1;
 	adev->vcn.num_vcn_inst = hweight32(adev->vcn.inst_mask);
 
diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v5_0_2.c b/drivers/gpu/drm/amd/amdgpu/vcn_v5_0_2.c
index 5291ebbc5c3e..6ffb34974a0d 100644
--- a/drivers/gpu/drm/amd/amdgpu/vcn_v5_0_2.c
+++ b/drivers/gpu/drm/amd/amdgpu/vcn_v5_0_2.c
@@ -112,6 +112,11 @@ static int vcn_v5_0_2_sw_init(struct amdgpu_ip_block *ip_block)
 	if (r)
 		return r;
 
+	r = amdgpu_irq_add_id(adev, SOC_V1_0_IH_CLIENTID_VCN1,
+		VCN_5_0__SRCID__UVD_ENC_GENERAL_PURPOSE, &adev->vcn.inst->irq);
+	if (r)
+		return r;
+
 	for (i = 0; i < adev->vcn.num_vcn_inst; i++) {
 		vcn_inst = GET_INST(VCN, i);
 
@@ -132,7 +137,7 @@ static int vcn_v5_0_2_sw_init(struct amdgpu_ip_block *ip_block)
 			(adev->doorbell_index.vcn.vcn_ring0_1 << 1) + 11 * vcn_inst;
 
 		ring->vm_hub = AMDGPU_MMHUB0(adev->vcn.inst[i].aid_id);
-		sprintf(ring->name, "vcn_unified_%d", adev->vcn.inst[i].aid_id);
+		sprintf(ring->name, "vcn_unified_%d", i);
 
 		r = amdgpu_ring_init(adev, ring, 512, &adev->vcn.inst[i].irq, 0,
 					AMDGPU_RING_PRIO_DEFAULT, &adev->vcn.inst[i].sched_score);
@@ -218,7 +223,7 @@ static int vcn_v5_0_2_hw_init(struct amdgpu_ip_block *ip_block)
 			adev->nbio.funcs->vcn_doorbell_range(adev, ring->use_doorbell,
 				((adev->doorbell_index.vcn.vcn_ring0_1 << 1) +
 				 11 * vcn_inst),
-				adev->vcn.inst[i].aid_id);
+				vcn_inst);
 
 		/* Re-init fw_shared, if required */
 		vcn_v5_0_2_fw_shared_init(adev, i);
@@ -587,7 +592,7 @@ static int vcn_v5_0_2_start_dpg_mode(struct amdgpu_vcn_inst *vinst,
 			(uint32_t *)adev->vcn.inst[inst_idx].dpg_sram_cpu_addr;
 		/* Use dummy register 0xDEADBEEF passing AID selection to PSP FW */
 		WREG32_SOC24_DPG_MODE(inst_idx, 0xDEADBEEF,
-				adev->vcn.inst[inst_idx].aid_id, 0, true);
+				vcn_inst, 0, true);
 	}
 
 	/* enable VCPU clock */
@@ -1141,17 +1146,46 @@ static int vcn_v5_0_2_set_pg_state(struct amdgpu_vcn_inst *vinst,
 static int vcn_v5_0_2_process_interrupt(struct amdgpu_device *adev, struct amdgpu_irq_src *source,
 	struct amdgpu_iv_entry *entry)
 {
-	uint32_t i, inst;
-
-	i = node_id_to_phys_map[entry->node_id];
+	uint32_t mid, cid;
+	int i, inst;
 
 	DRM_DEV_DEBUG(adev->dev, "IH: VCN TRAP\n");
 
-	for (inst = 0; inst < adev->vcn.num_vcn_inst; ++inst)
-		if (adev->vcn.inst[inst].aid_id == i)
+	switch (entry->client_id) {
+	case SOC_V1_0_IH_CLIENTID_VCN:
+		cid = 0;
+		break;
+	case SOC_V1_0_IH_CLIENTID_VCN1:
+		cid = 1;
+		break;
+	default:
+		dev_WARN_ONCE(adev->dev, 1,
+				"Interrupt received for unknown VCN client_id %d",
+				entry->client_id);
+		return 0;
+	}
+
+	switch (entry->node_id) {
+	case 0:
+		mid = 0;
+		break;
+	case 8:
+		mid = 1;
+		break;
+	default:
+		dev_WARN_ONCE(adev->dev, 1,
+				"Interrupt received for unknown VCN instance %d",
+				entry->node_id);
+		return 0;
+	}
+
+	inst = mid * adev->vcn.num_inst_per_aid + cid;
+
+	for (i = 0; i < adev->vcn.num_vcn_inst; i++)
+		if (GET_INST(VCN, i) == inst)
 			break;
 
-	if (inst >= adev->vcn.num_vcn_inst) {
+	if (i >= adev->vcn.num_vcn_inst) {
 		dev_WARN_ONCE(adev->dev, 1,
 				"Interrupt received for unknown VCN instance %d",
 				entry->node_id);
@@ -1160,7 +1194,7 @@ static int vcn_v5_0_2_process_interrupt(struct amdgpu_device *adev, struct amdgp
 
 	switch (entry->src_id) {
 	case VCN_5_0__SRCID__UVD_ENC_GENERAL_PURPOSE:
-		amdgpu_fence_process(&adev->vcn.inst[inst].ring_enc[0]);
+		amdgpu_fence_process(&adev->vcn.inst[i].ring_enc[0]);
 		break;
 	default:
 		DRM_DEV_ERROR(adev->dev, "Unhandled interrupt: %d %d\n",
-- 
2.43.0