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

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

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/amd/amdgpu/vcn_v4_0.c
Extension
.c
Size
73037 bytes
Lines
2336
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_vcn_is_disabled_vcn(adev, VCN_ENCODE_RING, i)) {
				adev->vcn.harvest_config |= 1 << i;
				dev_info(adev->dev, "VCN%d is disabled by hypervisor\n", i);
			}
		}
	}

	for (i = 0; i < adev->vcn.num_vcn_inst; ++i)
		/* re-use enc ring as unified ring */
		adev->vcn.inst[i].num_enc_rings = 1;

	vcn_v4_0_set_unified_ring_funcs(adev);
	vcn_v4_0_set_irq_funcs(adev);
	vcn_v4_0_set_ras_funcs(adev);

	for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
		adev->vcn.inst[i].set_pg_state = vcn_v4_0_set_pg_state;

		r = amdgpu_vcn_early_init(adev, i);
		if (r)
			return r;
	}

	return 0;
}

static int vcn_v4_0_fw_shared_init(struct amdgpu_device *adev, int inst_idx)
{
	struct amdgpu_vcn4_fw_shared *fw_shared;

	fw_shared = adev->vcn.inst[inst_idx].fw_shared.cpu_addr;
	fw_shared->present_flag_0 = cpu_to_le32(AMDGPU_FW_SHARED_FLAG_0_UNIFIED_QUEUE);
	fw_shared->sq.is_enabled = 1;

	fw_shared->present_flag_0 |= cpu_to_le32(AMDGPU_VCN_SMU_DPM_INTERFACE_FLAG);
	fw_shared->smu_dpm_interface.smu_interface_type = (adev->flags & AMD_IS_APU) ?
		AMDGPU_VCN_SMU_DPM_INTERFACE_APU : AMDGPU_VCN_SMU_DPM_INTERFACE_DGPU;

	if (amdgpu_ip_version(adev, VCN_HWIP, 0) ==
	    IP_VERSION(4, 0, 2)) {
		fw_shared->present_flag_0 |= AMDGPU_FW_SHARED_FLAG_0_DRM_KEY_INJECT;
		fw_shared->drm_key_wa.method =
			AMDGPU_DRM_KEY_INJECT_WORKAROUND_VCNFW_ASD_HANDSHAKING;
	}

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

	return 0;
}

/**
 * vcn_v4_0_sw_init - sw init for VCN block
 *
 * @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
 *
 * Load firmware and sw initialization
 */
static int vcn_v4_0_sw_init(struct amdgpu_ip_block *ip_block)
{
	struct amdgpu_ring *ring;
	struct amdgpu_device *adev = ip_block->adev;
	int i, r;

	for (i = 0; i < adev->vcn.num_vcn_inst; i++) {
		if (adev->vcn.harvest_config & (1 << i))
			continue;

		r = amdgpu_vcn_sw_init(adev, i);
		if (r)
			return r;

		amdgpu_vcn_setup_ucode(adev, i);

		r = amdgpu_vcn_resume(adev, i);
		if (r)
			return r;

		/* Init instance 0 sched_score to 1, so it's scheduled after other instances */
		if (i == 0)
			atomic_set(&adev->vcn.inst[i].sched_score, 1);
		else
			atomic_set(&adev->vcn.inst[i].sched_score, 0);

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

Annotation

Implementation Notes