[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