[PATCH 4/5] drm/radeon: Use write-combined CPU mappings of rings and IBs on >= SI

Michel Dänzer michel at daenzer.net
Thu Jul 17 03:01:09 PDT 2014


From: Michel Dänzer <michel.daenzer at amd.com>

Signed-off-by: Michel Dänzer <michel.daenzer at amd.com>
---
 drivers/gpu/drm/radeon/cik.c         |  3 +++
 drivers/gpu/drm/radeon/cik_sdma.c    |  4 ++++
 drivers/gpu/drm/radeon/ni.c          |  3 +++
 drivers/gpu/drm/radeon/ni_dma.c      |  4 ++++
 drivers/gpu/drm/radeon/radeon_ring.c | 22 +++++++++++++++++-----
 5 files changed, 31 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c
index a9fd3e7..df39095 100644
--- a/drivers/gpu/drm/radeon/cik.c
+++ b/drivers/gpu/drm/radeon/cik.c
@@ -4181,6 +4181,9 @@ u32 cik_gfx_get_wptr(struct radeon_device *rdev,
 void cik_gfx_set_wptr(struct radeon_device *rdev,
 		      struct radeon_ring *ring)
 {
+	/* Make IB/ring buffer writes land before the WPTR register write */
+	wmb();
+
 	WREG32(CP_RB0_WPTR, ring->wptr);
 	(void)RREG32(CP_RB0_WPTR);
 }
diff --git a/drivers/gpu/drm/radeon/cik_sdma.c b/drivers/gpu/drm/radeon/cik_sdma.c
index a7f66c8..3396b28 100644
--- a/drivers/gpu/drm/radeon/cik_sdma.c
+++ b/drivers/gpu/drm/radeon/cik_sdma.c
@@ -112,12 +112,16 @@ void cik_sdma_set_wptr(struct radeon_device *rdev,
 {
 	u32 reg;
 
+	/* Make IB/ring buffer writes land before the WPTR register write */
+	wmb();
+
 	if (ring->idx == R600_RING_TYPE_DMA_INDEX)
 		reg = SDMA0_GFX_RB_WPTR + SDMA0_REGISTER_OFFSET;
 	else
 		reg = SDMA0_GFX_RB_WPTR + SDMA1_REGISTER_OFFSET;
 
 	WREG32(reg, (ring->wptr << 2) & 0x3fffc);
+	(void)RREG32(reg);
 }
 
 /**
diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c
index 327b85f..b589fe7 100644
--- a/drivers/gpu/drm/radeon/ni.c
+++ b/drivers/gpu/drm/radeon/ni.c
@@ -1449,6 +1449,9 @@ u32 cayman_gfx_get_wptr(struct radeon_device *rdev,
 void cayman_gfx_set_wptr(struct radeon_device *rdev,
 			 struct radeon_ring *ring)
 {
+	/* Make IB/ring buffer writes land before the WPTR register write */
+	wmb();
+
 	if (ring->idx == RADEON_RING_TYPE_GFX_INDEX) {
 		WREG32(CP_RB0_WPTR, ring->wptr);
 		(void)RREG32(CP_RB0_WPTR);
diff --git a/drivers/gpu/drm/radeon/ni_dma.c b/drivers/gpu/drm/radeon/ni_dma.c
index 6378e02..119fc69 100644
--- a/drivers/gpu/drm/radeon/ni_dma.c
+++ b/drivers/gpu/drm/radeon/ni_dma.c
@@ -103,12 +103,16 @@ void cayman_dma_set_wptr(struct radeon_device *rdev,
 {
 	u32 reg;
 
+	/* Make IB/ring buffer writes land before the WPTR register write */
+	wmb();
+
 	if (ring->idx == R600_RING_TYPE_DMA_INDEX)
 		reg = DMA_RB_WPTR + DMA0_REGISTER_OFFSET;
 	else
 		reg = DMA_RB_WPTR + DMA1_REGISTER_OFFSET;
 
 	WREG32(reg, (ring->wptr << 2) & 0x3fffc);
+	(void)RREG32(reg);
 }
 
 /**
diff --git a/drivers/gpu/drm/radeon/radeon_ring.c b/drivers/gpu/drm/radeon/radeon_ring.c
index 71439f0..62e9e57 100644
--- a/drivers/gpu/drm/radeon/radeon_ring.c
+++ b/drivers/gpu/drm/radeon/radeon_ring.c
@@ -201,10 +201,22 @@ int radeon_ib_pool_init(struct radeon_device *rdev)
 	if (rdev->ib_pool_ready) {
 		return 0;
 	}
-	r = radeon_sa_bo_manager_init(rdev, &rdev->ring_tmp_bo,
-				      RADEON_IB_POOL_SIZE*64*1024,
-				      RADEON_GPU_PAGE_SIZE,
-				      RADEON_GEM_DOMAIN_GTT, 0);
+
+	if (rdev->family >= CHIP_TAHITI) {
+		r = radeon_sa_bo_manager_init(rdev, &rdev->ring_tmp_bo,
+					      RADEON_IB_POOL_SIZE*64*1024,
+					      RADEON_GPU_PAGE_SIZE,
+					      RADEON_GEM_DOMAIN_GTT,
+					      RADEON_GEM_GTT_WC);
+	} else {
+		/* Without GPUVM, it's better to stick to cacheable GTT due
+		 * to the command stream patching
+		 */
+		r = radeon_sa_bo_manager_init(rdev, &rdev->ring_tmp_bo,
+					      RADEON_IB_POOL_SIZE*64*1024,
+					      RADEON_GPU_PAGE_SIZE,
+					      RADEON_GEM_DOMAIN_GTT, 0);
+	}
 	if (r) {
 		return r;
 	}
@@ -640,7 +652,7 @@ int radeon_ring_init(struct radeon_device *rdev, struct radeon_ring *ring, unsig
 	/* Allocate ring buffer */
 	if (ring->ring_obj == NULL) {
 		r = radeon_bo_create(rdev, ring->ring_size, PAGE_SIZE, true,
-				     RADEON_GEM_DOMAIN_GTT, 0,
+				     RADEON_GEM_DOMAIN_GTT, RADEON_GEM_GTT_WC,
 				     NULL, &ring->ring_obj);
 		if (r) {
 			dev_err(rdev->dev, "(%d) ring create failed\n", r);
-- 
2.0.0



More information about the dri-devel mailing list