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

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

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/amd/amdgpu/vce_v3_0.c
Extension
.c
Size
28551 bytes
Lines
1025
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 (idx != 1 || adev->vce.harvest_config == AMDGPU_VCE_HARVEST_VCE0) {
			ring = &adev->vce.ring[0];
			WREG32(mmVCE_RB_RPTR, lower_32_bits(ring->wptr));
			WREG32(mmVCE_RB_WPTR, lower_32_bits(ring->wptr));
			WREG32(mmVCE_RB_BASE_LO, ring->gpu_addr);
			WREG32(mmVCE_RB_BASE_HI, upper_32_bits(ring->gpu_addr));
			WREG32(mmVCE_RB_SIZE, ring->ring_size / 4);

			ring = &adev->vce.ring[1];
			WREG32(mmVCE_RB_RPTR2, lower_32_bits(ring->wptr));
			WREG32(mmVCE_RB_WPTR2, lower_32_bits(ring->wptr));
			WREG32(mmVCE_RB_BASE_LO2, ring->gpu_addr);
			WREG32(mmVCE_RB_BASE_HI2, upper_32_bits(ring->gpu_addr));
			WREG32(mmVCE_RB_SIZE2, ring->ring_size / 4);

			ring = &adev->vce.ring[2];
			WREG32(mmVCE_RB_RPTR3, lower_32_bits(ring->wptr));
			WREG32(mmVCE_RB_WPTR3, lower_32_bits(ring->wptr));
			WREG32(mmVCE_RB_BASE_LO3, ring->gpu_addr);
			WREG32(mmVCE_RB_BASE_HI3, upper_32_bits(ring->gpu_addr));
			WREG32(mmVCE_RB_SIZE3, ring->ring_size / 4);
		}

		vce_v3_0_mc_resume(adev, idx);
		WREG32_FIELD(VCE_STATUS, JOB_BUSY, 1);

		if (adev->asic_type >= CHIP_STONEY)
			WREG32_P(mmVCE_VCPU_CNTL, 1, ~0x200001);
		else
			WREG32_FIELD(VCE_VCPU_CNTL, CLK_EN, 1);

		WREG32_FIELD(VCE_SOFT_RESET, ECPU_SOFT_RESET, 0);
		mdelay(100);

		r = vce_v3_0_firmware_loaded(adev);

		/* clear BUSY flag */
		WREG32_FIELD(VCE_STATUS, JOB_BUSY, 0);

		if (r) {
			DRM_ERROR("VCE not responding, giving up!!!\n");
			mutex_unlock(&adev->grbm_idx_mutex);
			return r;
		}
	}

	WREG32(mmGRBM_GFX_INDEX, mmGRBM_GFX_INDEX_DEFAULT);
	mutex_unlock(&adev->grbm_idx_mutex);

	return 0;
}

static int vce_v3_0_stop(struct amdgpu_device *adev)
{
	int idx;

	mutex_lock(&adev->grbm_idx_mutex);
	for (idx = 0; idx < 2; ++idx) {
		if (adev->vce.harvest_config & (1 << idx))
			continue;

		WREG32(mmGRBM_GFX_INDEX, GET_VCE_INSTANCE(idx));

		if (adev->asic_type >= CHIP_STONEY)
			WREG32_P(mmVCE_VCPU_CNTL, 0, ~0x200001);
		else
			WREG32_FIELD(VCE_VCPU_CNTL, CLK_EN, 0);

		/* hold on ECPU */
		WREG32_FIELD(VCE_SOFT_RESET, ECPU_SOFT_RESET, 1);

		/* clear VCE STATUS */
		WREG32(mmVCE_STATUS, 0);
	}

	WREG32(mmGRBM_GFX_INDEX, mmGRBM_GFX_INDEX_DEFAULT);
	mutex_unlock(&adev->grbm_idx_mutex);

	return 0;
}

#define ixVCE_HARVEST_FUSE_MACRO__ADDRESS     0xC0014074
#define VCE_HARVEST_FUSE_MACRO__SHIFT       27
#define VCE_HARVEST_FUSE_MACRO__MASK        0x18000000

static unsigned vce_v3_0_get_harvest_config(struct amdgpu_device *adev)
{
	u32 tmp;

	if ((adev->asic_type == CHIP_FIJI) ||

Annotation

Implementation Notes