Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a918efab authored by Christian König's avatar Christian König Committed by Alex Deucher
Browse files

drm/radeon: add VCE 1.0 support v4



Initial support for VCE 1.0 using newest firmware.

v2: rebased
v3: fix for TN
v4: fix FW size calculation

Signed-off-by: default avatarChristian König <christian.koenig@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 11586cf0
Loading
Loading
Loading
Loading
+46 −0
Original line number Diff line number Diff line
@@ -2041,6 +2041,25 @@ static int cayman_startup(struct radeon_device *rdev)
	if (r)
		rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_size = 0;

	if (rdev->family == CHIP_ARUBA) {
		r = radeon_vce_resume(rdev);
		if (!r)
			r = vce_v1_0_resume(rdev);

		if (!r)
			r = radeon_fence_driver_start_ring(rdev,
							   TN_RING_TYPE_VCE1_INDEX);
		if (!r)
			r = radeon_fence_driver_start_ring(rdev,
							   TN_RING_TYPE_VCE2_INDEX);

		if (r) {
			dev_err(rdev->dev, "VCE init error (%d).\n", r);
			rdev->ring[TN_RING_TYPE_VCE1_INDEX].ring_size = 0;
			rdev->ring[TN_RING_TYPE_VCE2_INDEX].ring_size = 0;
		}
	}

	r = radeon_fence_driver_start_ring(rdev, CAYMAN_RING_TYPE_CP1_INDEX);
	if (r) {
		dev_err(rdev->dev, "failed initializing CP fences (%d).\n", r);
@@ -2118,6 +2137,19 @@ static int cayman_startup(struct radeon_device *rdev)
			DRM_ERROR("radeon: failed initializing UVD (%d).\n", r);
	}

	ring = &rdev->ring[TN_RING_TYPE_VCE1_INDEX];
	if (ring->ring_size)
		r = radeon_ring_init(rdev, ring, ring->ring_size, 0, 0x0);

	ring = &rdev->ring[TN_RING_TYPE_VCE2_INDEX];
	if (ring->ring_size)
		r = radeon_ring_init(rdev, ring, ring->ring_size, 0, 0x0);

	if (!r)
		r = vce_v1_0_init(rdev);
	else if (r != -ENOENT)
		DRM_ERROR("radeon: failed initializing VCE (%d).\n", r);

	r = radeon_ib_pool_init(rdev);
	if (r) {
		dev_err(rdev->dev, "IB initialization failed (%d).\n", r);
@@ -2273,6 +2305,19 @@ int cayman_init(struct radeon_device *rdev)
		r600_ring_init(rdev, ring, 4096);
	}

	if (rdev->family == CHIP_ARUBA) {
		r = radeon_vce_init(rdev);
		if (!r) {
			ring = &rdev->ring[TN_RING_TYPE_VCE1_INDEX];
			ring->ring_obj = NULL;
			r600_ring_init(rdev, ring, 4096);

			ring = &rdev->ring[TN_RING_TYPE_VCE2_INDEX];
			ring->ring_obj = NULL;
			r600_ring_init(rdev, ring, 4096);
		}
	}

	rdev->ih.ring_obj = NULL;
	r600_ih_ring_init(rdev, 64 * 1024);

@@ -2326,6 +2371,7 @@ void cayman_fini(struct radeon_device *rdev)
	radeon_irq_kms_fini(rdev);
	uvd_v1_0_fini(rdev);
	radeon_uvd_fini(rdev);
	radeon_vce_fini(rdev);
	cayman_pcie_gart_fini(rdev);
	r600_vram_scratch_fini(rdev);
	radeon_gem_fini(rdev);
+1 −0
Original line number Diff line number Diff line
@@ -1719,6 +1719,7 @@ struct radeon_vce {
	struct drm_file		*filp[RADEON_MAX_VCE_HANDLES];
	unsigned		img_size[RADEON_MAX_VCE_HANDLES];
	struct delayed_work	idle_work;
	uint32_t		keyselect;
};

int radeon_vce_init(struct radeon_device *rdev);
+17 −0
Original line number Diff line number Diff line
@@ -1761,6 +1761,19 @@ static struct radeon_asic cayman_asic = {
	},
};

static struct radeon_asic_ring trinity_vce_ring = {
	.ib_execute = &radeon_vce_ib_execute,
	.emit_fence = &radeon_vce_fence_emit,
	.emit_semaphore = &radeon_vce_semaphore_emit,
	.cs_parse = &radeon_vce_cs_parse,
	.ring_test = &radeon_vce_ring_test,
	.ib_test = &radeon_vce_ib_test,
	.is_lockup = &radeon_ring_test_lockup,
	.get_rptr = &vce_v1_0_get_rptr,
	.get_wptr = &vce_v1_0_get_wptr,
	.set_wptr = &vce_v1_0_set_wptr,
};

static struct radeon_asic trinity_asic = {
	.init = &cayman_init,
	.fini = &cayman_fini,
@@ -1794,6 +1807,8 @@ static struct radeon_asic trinity_asic = {
		[R600_RING_TYPE_DMA_INDEX] = &cayman_dma_ring,
		[CAYMAN_RING_TYPE_DMA1_INDEX] = &cayman_dma_ring,
		[R600_RING_TYPE_UVD_INDEX] = &cayman_uvd_ring,
		[TN_RING_TYPE_VCE1_INDEX] = &trinity_vce_ring,
		[TN_RING_TYPE_VCE2_INDEX] = &trinity_vce_ring,
	},
	.irq = {
		.set = &evergreen_irq_set,
@@ -1930,6 +1945,8 @@ static struct radeon_asic si_asic = {
		[R600_RING_TYPE_DMA_INDEX] = &si_dma_ring,
		[CAYMAN_RING_TYPE_DMA1_INDEX] = &si_dma_ring,
		[R600_RING_TYPE_UVD_INDEX] = &cayman_uvd_ring,
		[TN_RING_TYPE_VCE1_INDEX] = &trinity_vce_ring,
		[TN_RING_TYPE_VCE2_INDEX] = &trinity_vce_ring,
	},
	.irq = {
		.set = &si_irq_set,
+3 −0
Original line number Diff line number Diff line
@@ -972,6 +972,9 @@ uint32_t vce_v1_0_get_wptr(struct radeon_device *rdev,
			   struct radeon_ring *ring);
void vce_v1_0_set_wptr(struct radeon_device *rdev,
		       struct radeon_ring *ring);
int vce_v1_0_load_fw(struct radeon_device *rdev, uint32_t *data);
unsigned vce_v1_0_bo_size(struct radeon_device *rdev);
int vce_v1_0_resume(struct radeon_device *rdev);
int vce_v1_0_init(struct radeon_device *rdev);
int vce_v1_0_start(struct radeon_device *rdev);

+20 −3
Original line number Diff line number Diff line
@@ -38,8 +38,10 @@
#define VCE_IDLE_TIMEOUT_MS	1000

/* Firmware Names */
#define FIRMWARE_TAHITI	"radeon/TAHITI_vce.bin"
#define FIRMWARE_BONAIRE	"radeon/BONAIRE_vce.bin"

MODULE_FIRMWARE(FIRMWARE_TAHITI);
MODULE_FIRMWARE(FIRMWARE_BONAIRE);

static void radeon_vce_idle_work_handler(struct work_struct *work);
@@ -63,6 +65,14 @@ int radeon_vce_init(struct radeon_device *rdev)
	INIT_DELAYED_WORK(&rdev->vce.idle_work, radeon_vce_idle_work_handler);

	switch (rdev->family) {
	case CHIP_TAHITI:
	case CHIP_PITCAIRN:
	case CHIP_VERDE:
	case CHIP_OLAND:
	case CHIP_ARUBA:
		fw_name = FIRMWARE_TAHITI;
		break;

	case CHIP_BONAIRE:
	case CHIP_KAVERI:
	case CHIP_KABINI:
@@ -125,6 +135,9 @@ int radeon_vce_init(struct radeon_device *rdev)

	/* allocate firmware, stack and heap BO */

	if (rdev->family < CHIP_BONAIRE)
		size = vce_v1_0_bo_size(rdev);
	else
		size = vce_v2_0_bo_size(rdev);
	r = radeon_bo_create(rdev, size, PAGE_SIZE, true,
			     RADEON_GEM_DOMAIN_VRAM, 0, NULL, NULL,
@@ -226,13 +239,17 @@ int radeon_vce_resume(struct radeon_device *rdev)
		return r;
	}

	memset(cpu_addr, 0, radeon_bo_size(rdev->vce.vcpu_bo));
	if (rdev->family < CHIP_BONAIRE)
		r = vce_v1_0_load_fw(rdev, cpu_addr);
	else
		memcpy(cpu_addr, rdev->vce_fw->data, rdev->vce_fw->size);

	radeon_bo_kunmap(rdev->vce.vcpu_bo);

	radeon_bo_unreserve(rdev->vce.vcpu_bo);

	return 0;
	return r;
}

/**
Loading