From: Jerome Glisse <jgli...@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 <jgli...@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

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

Reply via email to