drivers/gpu/drm/amd/amdgpu/vcn_v3_0.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/amd/amdgpu/vcn_v3_0.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/amd/amdgpu/vcn_v3_0.c
Extension
.c
Size
78485 bytes
Lines
2390
Domain
Driver Families
Bucket
drivers/gpu
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

if (amdgpu_sriov_vf(adev)) {
			ring->doorbell_index = vcn_doorbell_index + i * (adev->vcn.inst[i].num_enc_rings + 1);
		} else {
			ring->doorbell_index = (adev->doorbell_index.vcn.vcn_ring0_1 << 1) + 8 * i;
		}
		ring->vm_hub = AMDGPU_MMHUB0(0);
		sprintf(ring->name, "vcn_dec_%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);
		if (r)
			return r;

		for (j = 0; j < adev->vcn.inst[i].num_enc_rings; ++j) {
			enum amdgpu_ring_priority_level hw_prio = amdgpu_vcn_get_enc_ring_prio(j);

			/* VCN ENC TRAP */
			r = amdgpu_irq_add_id(adev, amdgpu_ih_clientid_vcns[i],
				j + VCN_2_0__SRCID__UVD_ENC_GENERAL_PURPOSE, &adev->vcn.inst[i].irq);
			if (r)
				return r;

			ring = &adev->vcn.inst[i].ring_enc[j];
			ring->use_doorbell = true;
			if (amdgpu_sriov_vf(adev)) {
				ring->doorbell_index = vcn_doorbell_index + i * (adev->vcn.inst[i].num_enc_rings + 1) + 1 + j;
			} else {
				ring->doorbell_index = (adev->doorbell_index.vcn.vcn_ring0_1 << 1) + 2 + j + 8 * i;
			}
			ring->vm_hub = AMDGPU_MMHUB0(0);
			sprintf(ring->name, "vcn_enc_%d.%d", i, j);
			r = amdgpu_ring_init(adev, ring, 512, &adev->vcn.inst[i].irq, 0,
					     hw_prio, &adev->vcn.inst[i].sched_score);
			if (r)
				return r;
		}

		fw_shared = adev->vcn.inst[i].fw_shared.cpu_addr;
		fw_shared->present_flag_0 |= cpu_to_le32(AMDGPU_VCN_SW_RING_FLAG) |
					     cpu_to_le32(AMDGPU_VCN_MULTI_QUEUE_FLAG) |
					     cpu_to_le32(AMDGPU_VCN_FW_SHARED_FLAG_0_RB);
		fw_shared->sw_ring.is_enabled = cpu_to_le32(DEC_SW_RING_ENABLED);
		fw_shared->present_flag_0 |= AMDGPU_VCN_SMU_VERSION_INFO_FLAG;
		if (amdgpu_ip_version(adev, UVD_HWIP, 0) == IP_VERSION(3, 1, 2))
			fw_shared->smu_interface_info.smu_interface_type = 2;
		else if (amdgpu_ip_version(adev, UVD_HWIP, 0) ==
			 IP_VERSION(3, 1, 1))
			fw_shared->smu_interface_info.smu_interface_type = 1;

		if (amdgpu_vcnfw_log)
			amdgpu_vcn_fwlog_init(&adev->vcn.inst[i]);

		if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG)
			adev->vcn.inst[i].pause_dpg_mode = vcn_v3_0_pause_dpg_mode;
		adev->vcn.inst[i].reset = vcn_v3_0_reset;
	}

	adev->vcn.supported_reset =
		amdgpu_get_soft_full_reset_mask(&adev->vcn.inst[0].ring_enc[0]);
	if (!amdgpu_sriov_vf(adev))
		adev->vcn.supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE;

	if (amdgpu_sriov_vf(adev)) {
		r = amdgpu_virt_alloc_mm_table(adev);
		if (r)
			return r;
	}

	r = amdgpu_vcn_reg_dump_init(adev, vcn_reg_list_3_0, ARRAY_SIZE(vcn_reg_list_3_0));
	if (r)
		return r;

	r = amdgpu_vcn_sysfs_reset_mask_init(adev);
	if (r)
		return r;

	return 0;
}

/**
 * vcn_v3_0_sw_fini - sw fini for VCN block
 *
 * @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
 *
 * VCN suspend and free up sw allocation
 */
static int vcn_v3_0_sw_fini(struct amdgpu_ip_block *ip_block)
{
	struct amdgpu_device *adev = ip_block->adev;
	int i, r, idx;

Annotation

Implementation Notes