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

Commit 5e884f60 authored by Alex Deucher's avatar Alex Deucher
Browse files

drm/radeon: restructure UVD code to handle UVD PG (v2)



When we PG (powergate) UVD, we need to re-initialize it
before we can use it again.

v2: rebase on UVD stop fixes

Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 9e9d9762
Loading
Loading
Loading
Loading
+5 −9
Original line number Diff line number Diff line
@@ -69,6 +69,7 @@ static void cik_pcie_gen3_enable(struct radeon_device *rdev);
static void cik_program_aspm(struct radeon_device *rdev);
static void cik_init_pg(struct radeon_device *rdev);
static void cik_init_cg(struct radeon_device *rdev);
static void cik_uvd_resume(struct radeon_device *rdev);

/* get temperature in millidegrees */
int ci_get_temp(struct radeon_device *rdev)
@@ -7619,8 +7620,9 @@ static int cik_startup(struct radeon_device *rdev)
		return r;
	}

	r = cik_uvd_resume(rdev);
	r = radeon_uvd_resume(rdev);
	if (!r) {
		cik_uvd_resume(rdev);
		r = radeon_fence_driver_start_ring(rdev,
						   R600_RING_TYPE_UVD_INDEX);
		if (r)
@@ -7708,7 +7710,7 @@ static int cik_startup(struct radeon_device *rdev)
				     UVD_RBC_RB_RPTR, UVD_RBC_RB_WPTR,
				     0, 0xfffff, RADEON_CP_PACKET2);
		if (!r)
			r = r600_uvd_init(rdev);
			r = r600_uvd_init(rdev, true);
		if (r)
			DRM_ERROR("radeon: failed initializing UVD (%d).\n", r);
	}
@@ -8598,15 +8600,10 @@ int cik_set_uvd_clocks(struct radeon_device *rdev, u32 vclk, u32 dclk)
	return r;
}

int cik_uvd_resume(struct radeon_device *rdev)
static void cik_uvd_resume(struct radeon_device *rdev)
{
	uint64_t addr;
	uint32_t size;
	int r;

	r = radeon_uvd_resume(rdev);
	if (r)
		return r;

	/* programm the VCPU memory controller bits 0-27 */
	addr = rdev->uvd.gpu_addr >> 3;
@@ -8632,7 +8629,6 @@ int cik_uvd_resume(struct radeon_device *rdev)
	addr = (rdev->uvd.gpu_addr >> 32) & 0xFF;
	WREG32(UVD_LMI_EXT40_ADDR, addr | (0x9 << 16) | (0x1 << 31));

	return 0;
}

static void cik_pcie_gen3_enable(struct radeon_device *rdev)
+1 −1
Original line number Diff line number Diff line
@@ -5296,7 +5296,7 @@ static int evergreen_startup(struct radeon_device *rdev)
				     UVD_RBC_RB_RPTR, UVD_RBC_RB_WPTR,
				     0, 0xfffff, RADEON_CP_PACKET2);
		if (!r)
			r = r600_uvd_init(rdev);
			r = r600_uvd_init(rdev, true);

		if (r)
			DRM_ERROR("radeon: error initializing UVD (%d).\n", r);
+1 −1
Original line number Diff line number Diff line
@@ -2230,7 +2230,7 @@ static int cayman_startup(struct radeon_device *rdev)
				     UVD_RBC_RB_RPTR, UVD_RBC_RB_WPTR,
				     0, 0xfffff, RADEON_CP_PACKET2);
		if (!r)
			r = r600_uvd_init(rdev);
			r = r600_uvd_init(rdev, true);
		if (r)
			DRM_ERROR("radeon: failed initializing UVD (%d).\n", r);
	}
+40 −34
Original line number Diff line number Diff line
@@ -2623,7 +2623,7 @@ void r600_dma_fini(struct radeon_device *rdev)
/*
 * UVD
 */
int r600_uvd_rbc_start(struct radeon_device *rdev)
static int r600_uvd_rbc_start(struct radeon_device *rdev, bool ring_test)
{
	struct radeon_ring *ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
	uint64_t rptr_addr;
@@ -2664,6 +2664,7 @@ int r600_uvd_rbc_start(struct radeon_device *rdev)
	rb_bufsz = (0x1 << 8) | rb_bufsz;
	WREG32(UVD_RBC_RB_CNTL, rb_bufsz);

	if (ring_test) {
		ring->ready = true;
		r = radeon_ring_test(rdev, R600_RING_TYPE_UVD_INDEX, ring);
		if (r) {
@@ -2697,14 +2698,13 @@ int r600_uvd_rbc_start(struct radeon_device *rdev)
		radeon_ring_write(ring, 3);

		radeon_ring_unlock_commit(rdev, ring);
	}

	return 0;
}

void r600_uvd_stop(struct radeon_device *rdev)
void r600_do_uvd_stop(struct radeon_device *rdev)
{
	struct radeon_ring *ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];

	/* force RBC into idle state */
	WREG32(UVD_RBC_RB_CNTL, 0x11010101);

@@ -2723,11 +2723,17 @@ void r600_uvd_stop(struct radeon_device *rdev)
	/* Unstall UMC and register bus */
	WREG32_P(UVD_LMI_CTRL2, 0, ~(1 << 8));
	WREG32_P(UVD_RB_ARB_CTRL, 0, ~(1 << 3));
}

void r600_uvd_stop(struct radeon_device *rdev)
{
	struct radeon_ring *ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];

	r600_do_uvd_stop(rdev);
	ring->ready = false;
}

int r600_uvd_init(struct radeon_device *rdev)
int r600_uvd_init(struct radeon_device *rdev, bool ring_test)
{
	int i, j, r;
	/* disable byte swapping */
@@ -2815,17 +2821,17 @@ int r600_uvd_init(struct radeon_device *rdev)

	if (r) {
		DRM_ERROR("UVD not responding, giving up!!!\n");
		radeon_set_uvd_clocks(rdev, 0, 0);
		return r;
		goto done;
	}

	/* enable interupt */
	WREG32_P(UVD_MASTINT_EN, 3<<1, ~(3 << 1));

	r = r600_uvd_rbc_start(rdev);
	r = r600_uvd_rbc_start(rdev, ring_test);
	if (!r)
		DRM_INFO("UVD initialized successfully.\n");

done:
	/* lower clocks again */
	radeon_set_uvd_clocks(rdev, 0, 0);

+1 −3
Original line number Diff line number Diff line
@@ -424,8 +424,7 @@ void rs780_dpm_debugfs_print_current_performance_level(struct radeon_device *rde
						       struct seq_file *m);

/* uvd */
int r600_uvd_init(struct radeon_device *rdev);
int r600_uvd_rbc_start(struct radeon_device *rdev);
int r600_uvd_init(struct radeon_device *rdev, bool ring_test);
void r600_uvd_stop(struct radeon_device *rdev);
int r600_uvd_ib_test(struct radeon_device *rdev, struct radeon_ring *ring);
void r600_uvd_fence_emit(struct radeon_device *rdev,
@@ -696,7 +695,6 @@ u32 cik_get_xclk(struct radeon_device *rdev);
uint32_t cik_pciep_rreg(struct radeon_device *rdev, uint32_t reg);
void cik_pciep_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v);
int cik_set_uvd_clocks(struct radeon_device *rdev, u32 vclk, u32 dclk);
int cik_uvd_resume(struct radeon_device *rdev);
void cik_sdma_fence_ring_emit(struct radeon_device *rdev,
			      struct radeon_fence *fence);
void cik_sdma_semaphore_ring_emit(struct radeon_device *rdev,
Loading