From: Jerome Glisse <jglisse@xxxxxxxxxx> 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@xxxxxxxxxx> --- 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@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/dri-devel