[PATCH 1/4] drm/radeon: allow to allocate adjacent scratch reg

j.glisse at gmail.com j.glisse at gmail.com
Wed May 2 13:20:10 PDT 2012


From: Jerome Glisse <jglisse at redhat.com>

This add the number of adjacent scratch reg you want to allocate
or free to the scratch alloc/free function.

Signed-off-by: Jerome Glisse <jglisse at redhat.com>
---
 drivers/gpu/drm/radeon/r100.c          |   12 ++++++------
 drivers/gpu/drm/radeon/r420.c          |    4 ++--
 drivers/gpu/drm/radeon/r600.c          |   12 ++++++------
 drivers/gpu/drm/radeon/radeon.h        |    4 ++--
 drivers/gpu/drm/radeon/radeon_device.c |   31 +++++++++++++++++++++++--------
 drivers/gpu/drm/radeon/radeon_fence.c  |    6 +++---
 6 files changed, 42 insertions(+), 27 deletions(-)

diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c
index d47ffd5..80b57c5 100644
--- a/drivers/gpu/drm/radeon/r100.c
+++ b/drivers/gpu/drm/radeon/r100.c
@@ -3636,7 +3636,7 @@ int r100_ring_test(struct radeon_device *rdev, struct radeon_ring *ring)
 	unsigned i;
 	int r;
 
-	r = radeon_scratch_get(rdev, &scratch);
+	r = radeon_scratch_get(rdev, &scratch, 1);
 	if (r) {
 		DRM_ERROR("radeon: cp failed to get scratch reg (%d).\n", r);
 		return r;
@@ -3645,7 +3645,7 @@ int r100_ring_test(struct radeon_device *rdev, struct radeon_ring *ring)
 	r = radeon_ring_lock(rdev, ring, 2);
 	if (r) {
 		DRM_ERROR("radeon: cp failed to lock ring (%d).\n", r);
-		radeon_scratch_free(rdev, scratch);
+		radeon_scratch_free(rdev, scratch, 1);
 		return r;
 	}
 	radeon_ring_write(ring, PACKET0(scratch, 0));
@@ -3665,7 +3665,7 @@ int r100_ring_test(struct radeon_device *rdev, struct radeon_ring *ring)
 			  scratch, tmp);
 		r = -EINVAL;
 	}
-	radeon_scratch_free(rdev, scratch);
+	radeon_scratch_free(rdev, scratch, 1);
 	return r;
 }
 
@@ -3686,7 +3686,7 @@ int r100_ib_test(struct radeon_device *rdev, struct radeon_ring *ring)
 	unsigned i;
 	int r;
 
-	r = radeon_scratch_get(rdev, &scratch);
+	r = radeon_scratch_get(rdev, &scratch, 1);
 	if (r) {
 		DRM_ERROR("radeon: failed to get scratch reg (%d).\n", r);
 		return r;
@@ -3707,7 +3707,7 @@ int r100_ib_test(struct radeon_device *rdev, struct radeon_ring *ring)
 	ib->length_dw = 8;
 	r = radeon_ib_schedule(rdev, ib);
 	if (r) {
-		radeon_scratch_free(rdev, scratch);
+		radeon_scratch_free(rdev, scratch, 1);
 		radeon_ib_free(rdev, &ib);
 		return r;
 	}
@@ -3729,7 +3729,7 @@ int r100_ib_test(struct radeon_device *rdev, struct radeon_ring *ring)
 			  scratch, tmp);
 		r = -EINVAL;
 	}
-	radeon_scratch_free(rdev, scratch);
+	radeon_scratch_free(rdev, scratch, 1);
 	radeon_ib_free(rdev, &ib);
 	return r;
 }
diff --git a/drivers/gpu/drm/radeon/r420.c b/drivers/gpu/drm/radeon/r420.c
index 99137be..5ba459b 100644
--- a/drivers/gpu/drm/radeon/r420.c
+++ b/drivers/gpu/drm/radeon/r420.c
@@ -207,7 +207,7 @@ static void r420_cp_errata_init(struct radeon_device *rdev)
 	 * The proper workaround is to queue a RESYNC at the beginning
 	 * of the CP init, apparently.
 	 */
-	radeon_scratch_get(rdev, &rdev->config.r300.resync_scratch);
+	radeon_scratch_get(rdev, &rdev->config.r300.resync_scratch, 1);
 	radeon_ring_lock(rdev, ring, 8);
 	radeon_ring_write(ring, PACKET0(R300_CP_RESYNC_ADDR, 1));
 	radeon_ring_write(ring, rdev->config.r300.resync_scratch);
@@ -226,7 +226,7 @@ static void r420_cp_errata_fini(struct radeon_device *rdev)
 	radeon_ring_write(ring, PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 0));
 	radeon_ring_write(ring, R300_RB3D_DC_FINISH);
 	radeon_ring_unlock_commit(rdev, ring);
-	radeon_scratch_free(rdev, rdev->config.r300.resync_scratch);
+	radeon_scratch_free(rdev, rdev->config.r300.resync_scratch, 1);
 }
 
 static int r420_startup(struct radeon_device *rdev)
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c
index 0cbcd3a..02abf32 100644
--- a/drivers/gpu/drm/radeon/r600.c
+++ b/drivers/gpu/drm/radeon/r600.c
@@ -2261,7 +2261,7 @@ int r600_ring_test(struct radeon_device *rdev, struct radeon_ring *ring)
 	unsigned i, ridx = radeon_ring_index(rdev, ring);
 	int r;
 
-	r = radeon_scratch_get(rdev, &scratch);
+	r = radeon_scratch_get(rdev, &scratch, 1);
 	if (r) {
 		DRM_ERROR("radeon: cp failed to get scratch reg (%d).\n", r);
 		return r;
@@ -2270,7 +2270,7 @@ int r600_ring_test(struct radeon_device *rdev, struct radeon_ring *ring)
 	r = radeon_ring_lock(rdev, ring, 3);
 	if (r) {
 		DRM_ERROR("radeon: cp failed to lock ring %d (%d).\n", ridx, r);
-		radeon_scratch_free(rdev, scratch);
+		radeon_scratch_free(rdev, scratch, 1);
 		return r;
 	}
 	radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1));
@@ -2290,7 +2290,7 @@ int r600_ring_test(struct radeon_device *rdev, struct radeon_ring *ring)
 			  ridx, scratch, tmp);
 		r = -EINVAL;
 	}
-	radeon_scratch_free(rdev, scratch);
+	radeon_scratch_free(rdev, scratch, 1);
 	return r;
 }
 
@@ -2693,7 +2693,7 @@ int r600_ib_test(struct radeon_device *rdev, struct radeon_ring *ring)
 	int r;
 	int ring_index = radeon_ring_index(rdev, ring);
 
-	r = radeon_scratch_get(rdev, &scratch);
+	r = radeon_scratch_get(rdev, &scratch, 1);
 	if (r) {
 		DRM_ERROR("radeon: failed to get scratch reg (%d).\n", r);
 		return r;
@@ -2710,7 +2710,7 @@ int r600_ib_test(struct radeon_device *rdev, struct radeon_ring *ring)
 	ib->length_dw = 3;
 	r = radeon_ib_schedule(rdev, ib);
 	if (r) {
-		radeon_scratch_free(rdev, scratch);
+		radeon_scratch_free(rdev, scratch, 1);
 		radeon_ib_free(rdev, &ib);
 		DRM_ERROR("radeon: failed to schedule ib (%d).\n", r);
 		return r;
@@ -2733,7 +2733,7 @@ int r600_ib_test(struct radeon_device *rdev, struct radeon_ring *ring)
 			  scratch, tmp);
 		r = -EINVAL;
 	}
-	radeon_scratch_free(rdev, scratch);
+	radeon_scratch_free(rdev, scratch, 1);
 	radeon_ib_free(rdev, &ib);
 	return r;
 }
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index b899cec..4f21b68 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -533,8 +533,8 @@ struct radeon_scratch {
 	uint32_t		reg[32];
 };
 
-int radeon_scratch_get(struct radeon_device *rdev, uint32_t *reg);
-void radeon_scratch_free(struct radeon_device *rdev, uint32_t reg);
+int radeon_scratch_get(struct radeon_device *rdev, uint32_t *reg, unsigned n);
+void radeon_scratch_free(struct radeon_device *rdev, uint32_t reg, unsigned n);
 
 
 /*
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c
index 1dac27d..3880aad 100644
--- a/drivers/gpu/drm/radeon/radeon_device.c
+++ b/drivers/gpu/drm/radeon/radeon_device.c
@@ -136,13 +136,26 @@ void radeon_scratch_init(struct radeon_device *rdev)
 	}
 }
 
-int radeon_scratch_get(struct radeon_device *rdev, uint32_t *reg)
+int radeon_scratch_get(struct radeon_device *rdev, uint32_t *reg, unsigned n)
 {
-	int i;
+	unsigned i, j, c;
 
-	for (i = 0; i < rdev->scratch.num_reg; i++) {
-		if (rdev->scratch.free[i]) {
-			rdev->scratch.free[i] = false;
+	if (n >= rdev->scratch.num_reg) {
+		dump_stack();
+		dev_err(rdev->dev, "trying to allocate %d scratch reg out of %d\n",
+			n, rdev->scratch.num_reg);
+		return -EINVAL;
+	}
+	for (i = 0; i < rdev->scratch.num_reg - n; i++) {
+		for (j = 0, c = 0; j < n; j++) {
+			if (rdev->scratch.free[i+j]) {
+				c++;
+			}
+		}
+		if (c == n) {
+			for (j = 0; j < n; j++) {
+				rdev->scratch.free[i+j] = false;
+			}
 			*reg = rdev->scratch.reg[i];
 			return 0;
 		}
@@ -150,13 +163,15 @@ int radeon_scratch_get(struct radeon_device *rdev, uint32_t *reg)
 	return -EINVAL;
 }
 
-void radeon_scratch_free(struct radeon_device *rdev, uint32_t reg)
+void radeon_scratch_free(struct radeon_device *rdev, uint32_t reg, unsigned n)
 {
-	int i;
+	unsigned i, j;
 
 	for (i = 0; i < rdev->scratch.num_reg; i++) {
 		if (rdev->scratch.reg[i] == reg) {
-			rdev->scratch.free[i] = true;
+			for (j = 0; j < n; j++) {
+				rdev->scratch.free[i+j] = true;
+			}
 			return;
 		}
 	}
diff --git a/drivers/gpu/drm/radeon/radeon_fence.c b/drivers/gpu/drm/radeon/radeon_fence.c
index 7d0c331..7733429 100644
--- a/drivers/gpu/drm/radeon/radeon_fence.c
+++ b/drivers/gpu/drm/radeon/radeon_fence.c
@@ -371,12 +371,12 @@ int radeon_fence_driver_start_ring(struct radeon_device *rdev, int ring)
 	int r;
 
 	write_lock_irqsave(&rdev->fence_lock, irq_flags);
-	radeon_scratch_free(rdev, rdev->fence_drv[ring].scratch_reg);
+	radeon_scratch_free(rdev, rdev->fence_drv[ring].scratch_reg, 1);
 	if (rdev->wb.use_event) {
 		rdev->fence_drv[ring].scratch_reg = 0;
 		index = R600_WB_EVENT_OFFSET + ring * 4;
 	} else {
-		r = radeon_scratch_get(rdev, &rdev->fence_drv[ring].scratch_reg);
+		r = radeon_scratch_get(rdev, &rdev->fence_drv[ring].scratch_reg, 1);
 		if (r) {
 			dev_err(rdev->dev, "fence failed to get scratch register\n");
 			write_unlock_irqrestore(&rdev->fence_lock, irq_flags);
@@ -435,7 +435,7 @@ void radeon_fence_driver_fini(struct radeon_device *rdev)
 		radeon_fence_wait_empty(rdev, ring);
 		wake_up_all(&rdev->fence_drv[ring].queue);
 		write_lock_irqsave(&rdev->fence_lock, irq_flags);
-		radeon_scratch_free(rdev, rdev->fence_drv[ring].scratch_reg);
+		radeon_scratch_free(rdev, rdev->fence_drv[ring].scratch_reg, 1);
 		write_unlock_irqrestore(&rdev->fence_lock, irq_flags);
 		rdev->fence_drv[ring].initialized = false;
 	}
-- 
1.7.7.6



More information about the dri-devel mailing list