[PATCH 49/53] drm/radeon: restructure UVD code to handle UVD PG (v2)

Alex Deucher alexdeucher at gmail.com
Mon Aug 12 09:43:41 PDT 2013


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: Alex Deucher <alexander.deucher at amd.com>
---
 drivers/gpu/drm/radeon/cik.c         | 14 +++----
 drivers/gpu/drm/radeon/evergreen.c   |  2 +-
 drivers/gpu/drm/radeon/ni.c          |  2 +-
 drivers/gpu/drm/radeon/r600.c        | 74 +++++++++++++++++++-----------------
 drivers/gpu/drm/radeon/radeon_asic.h |  4 +-
 drivers/gpu/drm/radeon/rv770.c       |  2 +-
 drivers/gpu/drm/radeon/si.c          |  2 +-
 7 files changed, 50 insertions(+), 50 deletions(-)

diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c
index 736a416..59b866a 100644
--- a/drivers/gpu/drm/radeon/cik.c
+++ b/drivers/gpu/drm/radeon/cik.c
@@ -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)
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c
index 2ce12ee..710c1d4 100644
--- a/drivers/gpu/drm/radeon/evergreen.c
+++ b/drivers/gpu/drm/radeon/evergreen.c
@@ -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);
diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c
index 21f2ece..bc298a35 100644
--- a/drivers/gpu/drm/radeon/ni.c
+++ b/drivers/gpu/drm/radeon/ni.c
@@ -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);
 	}
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c
index 3db2e4d..8a60015 100644
--- a/drivers/gpu/drm/radeon/r600.c
+++ b/drivers/gpu/drm/radeon/r600.c
@@ -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,47 +2664,47 @@ int r600_uvd_rbc_start(struct radeon_device *rdev)
 	rb_bufsz = (0x1 << 8) | rb_bufsz;
 	WREG32(UVD_RBC_RB_CNTL, rb_bufsz);
 
-	ring->ready = true;
-	r = radeon_ring_test(rdev, R600_RING_TYPE_UVD_INDEX, ring);
-	if (r) {
-		ring->ready = false;
-		return r;
-	}
+	if (ring_test) {
+		ring->ready = true;
+		r = radeon_ring_test(rdev, R600_RING_TYPE_UVD_INDEX, ring);
+		if (r) {
+			ring->ready = false;
+			return r;
+		}
 
-	r = radeon_ring_lock(rdev, ring, 10);
-	if (r) {
-		DRM_ERROR("radeon: ring failed to lock UVD ring (%d).\n", r);
-		return r;
-	}
+		r = radeon_ring_lock(rdev, ring, 10);
+		if (r) {
+			DRM_ERROR("radeon: ring failed to lock UVD ring (%d).\n", r);
+			return r;
+		}
 
-	tmp = PACKET0(UVD_SEMA_WAIT_FAULT_TIMEOUT_CNTL, 0);
-	radeon_ring_write(ring, tmp);
-	radeon_ring_write(ring, 0xFFFFF);
+		tmp = PACKET0(UVD_SEMA_WAIT_FAULT_TIMEOUT_CNTL, 0);
+		radeon_ring_write(ring, tmp);
+		radeon_ring_write(ring, 0xFFFFF);
 
-	tmp = PACKET0(UVD_SEMA_WAIT_INCOMPLETE_TIMEOUT_CNTL, 0);
-	radeon_ring_write(ring, tmp);
-	radeon_ring_write(ring, 0xFFFFF);
+		tmp = PACKET0(UVD_SEMA_WAIT_INCOMPLETE_TIMEOUT_CNTL, 0);
+		radeon_ring_write(ring, tmp);
+		radeon_ring_write(ring, 0xFFFFF);
 
-	tmp = PACKET0(UVD_SEMA_SIGNAL_INCOMPLETE_TIMEOUT_CNTL, 0);
-	radeon_ring_write(ring, tmp);
-	radeon_ring_write(ring, 0xFFFFF);
+		tmp = PACKET0(UVD_SEMA_SIGNAL_INCOMPLETE_TIMEOUT_CNTL, 0);
+		radeon_ring_write(ring, tmp);
+		radeon_ring_write(ring, 0xFFFFF);
 
-	/* Clear timeout status bits */
-	radeon_ring_write(ring, PACKET0(UVD_SEMA_TIMEOUT_STATUS, 0));
-	radeon_ring_write(ring, 0x8);
+		/* Clear timeout status bits */
+		radeon_ring_write(ring, PACKET0(UVD_SEMA_TIMEOUT_STATUS, 0));
+		radeon_ring_write(ring, 0x8);
 
-	radeon_ring_write(ring, PACKET0(UVD_SEMA_CNTL, 0));
-	radeon_ring_write(ring, 3);
+		radeon_ring_write(ring, PACKET0(UVD_SEMA_CNTL, 0));
+		radeon_ring_write(ring, 3);
 
-	radeon_ring_unlock_commit(rdev, ring);
+		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);
 
diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h
index 1e386c4..3570817 100644
--- a/drivers/gpu/drm/radeon/radeon_asic.h
+++ b/drivers/gpu/drm/radeon/radeon_asic.h
@@ -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,
diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c
index 8f78d21..379b19f 100644
--- a/drivers/gpu/drm/radeon/rv770.c
+++ b/drivers/gpu/drm/radeon/rv770.c
@@ -1928,7 +1928,7 @@ static int rv770_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);
diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c
index 4f91e1f..da23ce8 100644
--- a/drivers/gpu/drm/radeon/si.c
+++ b/drivers/gpu/drm/radeon/si.c
@@ -6421,7 +6421,7 @@ static int si_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);
 		}
-- 
1.8.3.1



More information about the dri-devel mailing list