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

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

drm/radeon: UVD bringup v8



Just everything needed to decode videos using UVD.

v6: just all the bugfixes and support for R7xx-SI merged in one patch
v7: UVD_CGC_GATE is a write only register, lockup detection fix
v8: split out VRAM fallback changes, remove support for RV770,
    add support for HEMLOCK, add buffer sizes checks

Signed-off-by: default avatarChristian König <christian.koenig@amd.com>
Reviewed-by: default avatarJerome Glisse <jglisse@redhat.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 4474f3a9
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -76,7 +76,7 @@ radeon-y += radeon_device.o radeon_asic.o radeon_kms.o \
	evergreen.o evergreen_cs.o evergreen_blit_shaders.o evergreen_blit_kms.o \
	evergreen_hdmi.o radeon_trace_points.o ni.o cayman_blit_shaders.o \
	atombios_encoders.o radeon_semaphore.o radeon_sa.o atombios_i2c.o si.o \
	si_blit_shaders.o radeon_prime.o
	si_blit_shaders.o radeon_prime.o radeon_uvd.o

radeon-$(CONFIG_COMPAT) += radeon_ioc32.o
radeon-$(CONFIG_VGA_SWITCHEROO) += radeon_atpx_handler.o
+39 −1
Original line number Diff line number Diff line
@@ -3360,6 +3360,9 @@ int evergreen_irq_process(struct radeon_device *rdev)
				DRM_ERROR("Unhandled interrupt: %d %d\n", src_id, src_data);
				break;
			}
		case 124: /* UVD */
			DRM_DEBUG("IH: UVD int: 0x%08x\n", src_data);
			radeon_fence_process(rdev, R600_RING_TYPE_UVD_INDEX);
			break;
		case 146:
		case 147:
@@ -3571,7 +3574,7 @@ int evergreen_copy_dma(struct radeon_device *rdev,

static int evergreen_startup(struct radeon_device *rdev)
{
	struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
	struct radeon_ring *ring;
	int r;

	/* enable pcie gen2 link */
@@ -3638,6 +3641,17 @@ static int evergreen_startup(struct radeon_device *rdev)
		return r;
	}

	r = rv770_uvd_resume(rdev);
	if (!r) {
		r = radeon_fence_driver_start_ring(rdev,
						   R600_RING_TYPE_UVD_INDEX);
		if (r)
			dev_err(rdev->dev, "UVD fences init error (%d).\n", r);
	}

	if (r)
		rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_size = 0;

	/* Enable IRQ */
	r = r600_irq_init(rdev);
	if (r) {
@@ -3647,6 +3661,7 @@ static int evergreen_startup(struct radeon_device *rdev)
	}
	evergreen_irq_set(rdev);

	ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
	r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP_RPTR_OFFSET,
			     R600_CP_RB_RPTR, R600_CP_RB_WPTR,
			     0, 0xfffff, RADEON_CP_PACKET2);
@@ -3670,6 +3685,19 @@ static int evergreen_startup(struct radeon_device *rdev)
	if (r)
		return r;

	ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
	if (ring->ring_size) {
		r = radeon_ring_init(rdev, ring, ring->ring_size,
				     R600_WB_UVD_RPTR_OFFSET,
				     UVD_RBC_RB_RPTR, UVD_RBC_RB_WPTR,
				     0, 0xfffff, RADEON_CP_PACKET2);
		if (!r)
			r = r600_uvd_init(rdev);

		if (r)
			DRM_ERROR("radeon: error initializing UVD (%d).\n", r);
	}

	r = radeon_ib_pool_init(rdev);
	if (r) {
		dev_err(rdev->dev, "IB initialization failed (%d).\n", r);
@@ -3716,8 +3744,10 @@ int evergreen_resume(struct radeon_device *rdev)
int evergreen_suspend(struct radeon_device *rdev)
{
	r600_audio_fini(rdev);
	radeon_uvd_suspend(rdev);
	r700_cp_stop(rdev);
	r600_dma_stop(rdev);
	r600_uvd_rbc_stop(rdev);
	evergreen_irq_suspend(rdev);
	radeon_wb_disable(rdev);
	evergreen_pcie_gart_disable(rdev);
@@ -3797,6 +3827,13 @@ int evergreen_init(struct radeon_device *rdev)
	rdev->ring[R600_RING_TYPE_DMA_INDEX].ring_obj = NULL;
	r600_ring_init(rdev, &rdev->ring[R600_RING_TYPE_DMA_INDEX], 64 * 1024);

	r = radeon_uvd_init(rdev);
	if (!r) {
		rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_obj = NULL;
		r600_ring_init(rdev, &rdev->ring[R600_RING_TYPE_UVD_INDEX],
			       4096);
	}

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

@@ -3843,6 +3880,7 @@ void evergreen_fini(struct radeon_device *rdev)
	radeon_ib_pool_fini(rdev);
	radeon_irq_kms_fini(rdev);
	evergreen_pcie_gart_fini(rdev);
	radeon_uvd_fini(rdev);
	r600_vram_scratch_fini(rdev);
	radeon_gem_fini(rdev);
	radeon_fence_driver_fini(rdev);
+7 −0
Original line number Diff line number Diff line
@@ -992,6 +992,13 @@
#       define TARGET_LINK_SPEED_MASK                     (0xf << 0)
#       define SELECTABLE_DEEMPHASIS                      (1 << 6)


/*
 * UVD
 */
#define UVD_RBC_RB_RPTR					0xf690
#define UVD_RBC_RB_WPTR					0xf694

/*
 * PM4
 */
+49 −0
Original line number Diff line number Diff line
@@ -933,6 +933,23 @@ void cayman_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib)
	radeon_ring_write(ring, 10); /* poll interval */
}

void cayman_uvd_semaphore_emit(struct radeon_device *rdev,
			       struct radeon_ring *ring,
			       struct radeon_semaphore *semaphore,
			       bool emit_wait)
{
	uint64_t addr = semaphore->gpu_addr;

	radeon_ring_write(ring, PACKET0(UVD_SEMA_ADDR_LOW, 0));
	radeon_ring_write(ring, (addr >> 3) & 0x000FFFFF);

	radeon_ring_write(ring, PACKET0(UVD_SEMA_ADDR_HIGH, 0));
	radeon_ring_write(ring, (addr >> 23) & 0x000FFFFF);

	radeon_ring_write(ring, PACKET0(UVD_SEMA_CMD, 0));
	radeon_ring_write(ring, 0x80 | (emit_wait ? 1 : 0));
}

static void cayman_cp_enable(struct radeon_device *rdev, bool enable)
{
	if (enable)
@@ -1684,6 +1701,16 @@ static int cayman_startup(struct radeon_device *rdev)
		return r;
	}

	r = rv770_uvd_resume(rdev);
	if (!r) {
		r = radeon_fence_driver_start_ring(rdev,
						   R600_RING_TYPE_UVD_INDEX);
		if (r)
			dev_err(rdev->dev, "UVD fences init error (%d).\n", r);
	}
	if (r)
		rdev->ring[R600_RING_TYPE_UVD_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);
@@ -1750,6 +1777,18 @@ static int cayman_startup(struct radeon_device *rdev)
	if (r)
		return r;

	ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
	if (ring->ring_size) {
		r = radeon_ring_init(rdev, ring, ring->ring_size,
				     R600_WB_UVD_RPTR_OFFSET,
				     UVD_RBC_RB_RPTR, UVD_RBC_RB_WPTR,
				     0, 0xfffff, RADEON_CP_PACKET2);
		if (!r)
			r = r600_uvd_init(rdev);
		if (r)
			DRM_ERROR("radeon: failed initializing UVD (%d).\n", r);
	}

	r = radeon_ib_pool_init(rdev);
	if (r) {
		dev_err(rdev->dev, "IB initialization failed (%d).\n", r);
@@ -1796,6 +1835,8 @@ int cayman_suspend(struct radeon_device *rdev)
	radeon_vm_manager_fini(rdev);
	cayman_cp_enable(rdev, false);
	cayman_dma_stop(rdev);
	r600_uvd_rbc_stop(rdev);
	radeon_uvd_suspend(rdev);
	evergreen_irq_suspend(rdev);
	radeon_wb_disable(rdev);
	cayman_pcie_gart_disable(rdev);
@@ -1870,6 +1911,13 @@ int cayman_init(struct radeon_device *rdev)
	ring->ring_obj = NULL;
	r600_ring_init(rdev, ring, 64 * 1024);

	r = radeon_uvd_init(rdev);
	if (!r) {
		ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
		ring->ring_obj = NULL;
		r600_ring_init(rdev, ring, 4096);
	}

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

@@ -1921,6 +1969,7 @@ void cayman_fini(struct radeon_device *rdev)
	radeon_vm_manager_fini(rdev);
	radeon_ib_pool_fini(rdev);
	radeon_irq_kms_fini(rdev);
	radeon_uvd_fini(rdev);
	cayman_pcie_gart_fini(rdev);
	r600_vram_scratch_fini(rdev);
	radeon_gem_fini(rdev);
+9 −0
Original line number Diff line number Diff line
@@ -489,6 +489,15 @@
#       define CACHE_FLUSH_AND_INV_EVENT_TS                     (0x14 << 0)
#       define CACHE_FLUSH_AND_INV_EVENT                        (0x16 << 0)

/*
 * UVD
 */
#define UVD_SEMA_ADDR_LOW				0xEF00
#define UVD_SEMA_ADDR_HIGH				0xEF04
#define UVD_SEMA_CMD					0xEF08
#define UVD_RBC_RB_RPTR					0xF690
#define UVD_RBC_RB_WPTR					0xF694

/*
 * PM4
 */
Loading