aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/radeon/radeon_ring.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-04-08 12:52:16 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-04-08 12:52:16 -0400
commite9f37d3a8d126e73f5737ef548cdf6f618e295e4 (patch)
tree831eb4952637828a7bbafa361185e0ca57aa86ed /drivers/gpu/drm/radeon/radeon_ring.c
parent5fb6b953bb7aa86a9c8ea760934982cedc45c52b (diff)
parentc39b06951f1dc2e384650288676c5b7dcc0ec92c (diff)
Merge branch 'drm-next' of git://people.freedesktop.org/~airlied/linux
Pull drm updates from Dave Airlie: "Highlights: - drm: Generic display port aux features, primary plane support, drm master management fixes, logging cleanups, enforced locking checks (instead of docs), documentation improvements, minor number handling cleanup, pseudofs for shared inodes. - ttm: add ability to allocate from both ends - i915: broadwell features, power domain and runtime pm, per-process address space infrastructure (not enabled) - msm: power management, hdmi audio support - nouveau: ongoing GPU fault recovery, initial maxwell support, random fixes - exynos: refactored driver to clean up a lot of abstraction, DP support moved into drm, LVDS bridge support added, parallel panel support - gma500: SGX MMU support, SGX irq handling, asle irq work fixes - radeon: video engine bringup, ring handling fixes, use dp aux helpers - vmwgfx: add rendernode support" * 'drm-next' of git://people.freedesktop.org/~airlied/linux: (849 commits) DRM: armada: fix corruption while loading cursors drm/dp_helper: don't return EPROTO for defers (v2) drm/bridge: export ptn3460_init function drm/exynos: remove MODULE_DEVICE_TABLE definitions ARM: dts: exynos4412-trats2: enable exynos/fimd node ARM: dts: exynos4210-trats: enable exynos/fimd node ARM: dts: exynos4412-trats2: add panel node ARM: dts: exynos4210-trats: add panel node ARM: dts: exynos4: add MIPI DSI Master node drm/panel: add S6E8AA0 driver ARM: dts: exynos4210-universal_c210: add proper panel node drm/panel: add ld9040 driver panel/ld9040: add DT bindings panel/s6e8aa0: add DT bindings drm/exynos: add DSIM driver exynos/dsim: add DT bindings drm/exynos: disallow fbdev initialization if no device is connected drm/mipi_dsi: create dsi devices only for nodes with reg property drm/mipi_dsi: add flags to DSI messages Skip intel_crt_init for Dell XPS 8700 ...
Diffstat (limited to 'drivers/gpu/drm/radeon/radeon_ring.c')
-rw-r--r--drivers/gpu/drm/radeon/radeon_ring.c119
1 files changed, 43 insertions, 76 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_ring.c b/drivers/gpu/drm/radeon/radeon_ring.c
index 15e44a7281ab..f8050f5429e2 100644
--- a/drivers/gpu/drm/radeon/radeon_ring.c
+++ b/drivers/gpu/drm/radeon/radeon_ring.c
@@ -63,7 +63,7 @@ int radeon_ib_get(struct radeon_device *rdev, int ring,
63{ 63{
64 int r; 64 int r;
65 65
66 r = radeon_sa_bo_new(rdev, &rdev->ring_tmp_bo, &ib->sa_bo, size, 256, true); 66 r = radeon_sa_bo_new(rdev, &rdev->ring_tmp_bo, &ib->sa_bo, size, 256);
67 if (r) { 67 if (r) {
68 dev_err(rdev->dev, "failed to get a new IB (%d)\n", r); 68 dev_err(rdev->dev, "failed to get a new IB (%d)\n", r);
69 return r; 69 return r;
@@ -145,6 +145,13 @@ int radeon_ib_schedule(struct radeon_device *rdev, struct radeon_ib *ib,
145 return r; 145 return r;
146 } 146 }
147 147
148 /* grab a vm id if necessary */
149 if (ib->vm) {
150 struct radeon_fence *vm_id_fence;
151 vm_id_fence = radeon_vm_grab_id(rdev, ib->vm, ib->ring);
152 radeon_semaphore_sync_to(ib->semaphore, vm_id_fence);
153 }
154
148 /* sync with other rings */ 155 /* sync with other rings */
149 r = radeon_semaphore_sync_rings(rdev, ib->semaphore, ib->ring); 156 r = radeon_semaphore_sync_rings(rdev, ib->semaphore, ib->ring);
150 if (r) { 157 if (r) {
@@ -153,11 +160,9 @@ int radeon_ib_schedule(struct radeon_device *rdev, struct radeon_ib *ib,
153 return r; 160 return r;
154 } 161 }
155 162
156 /* if we can't remember our last VM flush then flush now! */ 163 if (ib->vm)
157 /* XXX figure out why we have to flush for every IB */ 164 radeon_vm_flush(rdev, ib->vm, ib->ring);
158 if (ib->vm /*&& !ib->vm->last_flush*/) { 165
159 radeon_ring_vm_flush(rdev, ib->ring, ib->vm);
160 }
161 if (const_ib) { 166 if (const_ib) {
162 radeon_ring_ib_execute(rdev, const_ib->ring, const_ib); 167 radeon_ring_ib_execute(rdev, const_ib->ring, const_ib);
163 radeon_semaphore_free(rdev, &const_ib->semaphore, NULL); 168 radeon_semaphore_free(rdev, &const_ib->semaphore, NULL);
@@ -172,10 +177,10 @@ int radeon_ib_schedule(struct radeon_device *rdev, struct radeon_ib *ib,
172 if (const_ib) { 177 if (const_ib) {
173 const_ib->fence = radeon_fence_ref(ib->fence); 178 const_ib->fence = radeon_fence_ref(ib->fence);
174 } 179 }
175 /* we just flushed the VM, remember that */ 180
176 if (ib->vm && !ib->vm->last_flush) { 181 if (ib->vm)
177 ib->vm->last_flush = radeon_fence_ref(ib->fence); 182 radeon_vm_fence(rdev, ib->vm, ib->fence);
178 } 183
179 radeon_ring_unlock_commit(rdev, ring); 184 radeon_ring_unlock_commit(rdev, ring);
180 return 0; 185 return 0;
181} 186}
@@ -257,6 +262,7 @@ int radeon_ib_ring_tests(struct radeon_device *rdev)
257 r = radeon_ib_test(rdev, i, ring); 262 r = radeon_ib_test(rdev, i, ring);
258 if (r) { 263 if (r) {
259 ring->ready = false; 264 ring->ready = false;
265 rdev->needs_reset = false;
260 266
261 if (i == RADEON_RING_TYPE_GFX_INDEX) { 267 if (i == RADEON_RING_TYPE_GFX_INDEX) {
262 /* oh, oh, that's really bad */ 268 /* oh, oh, that's really bad */
@@ -342,13 +348,17 @@ bool radeon_ring_supports_scratch_reg(struct radeon_device *rdev,
342 */ 348 */
343void radeon_ring_free_size(struct radeon_device *rdev, struct radeon_ring *ring) 349void radeon_ring_free_size(struct radeon_device *rdev, struct radeon_ring *ring)
344{ 350{
345 ring->rptr = radeon_ring_get_rptr(rdev, ring); 351 uint32_t rptr = radeon_ring_get_rptr(rdev, ring);
352
346 /* This works because ring_size is a power of 2 */ 353 /* This works because ring_size is a power of 2 */
347 ring->ring_free_dw = (ring->rptr + (ring->ring_size / 4)); 354 ring->ring_free_dw = rptr + (ring->ring_size / 4);
348 ring->ring_free_dw -= ring->wptr; 355 ring->ring_free_dw -= ring->wptr;
349 ring->ring_free_dw &= ring->ptr_mask; 356 ring->ring_free_dw &= ring->ptr_mask;
350 if (!ring->ring_free_dw) { 357 if (!ring->ring_free_dw) {
358 /* this is an empty ring */
351 ring->ring_free_dw = ring->ring_size / 4; 359 ring->ring_free_dw = ring->ring_size / 4;
360 /* update lockup info to avoid false positive */
361 radeon_ring_lockup_update(rdev, ring);
352 } 362 }
353} 363}
354 364
@@ -372,19 +382,13 @@ int radeon_ring_alloc(struct radeon_device *rdev, struct radeon_ring *ring, unsi
372 /* Align requested size with padding so unlock_commit can 382 /* Align requested size with padding so unlock_commit can
373 * pad safely */ 383 * pad safely */
374 radeon_ring_free_size(rdev, ring); 384 radeon_ring_free_size(rdev, ring);
375 if (ring->ring_free_dw == (ring->ring_size / 4)) {
376 /* This is an empty ring update lockup info to avoid
377 * false positive.
378 */
379 radeon_ring_lockup_update(ring);
380 }
381 ndw = (ndw + ring->align_mask) & ~ring->align_mask; 385 ndw = (ndw + ring->align_mask) & ~ring->align_mask;
382 while (ndw > (ring->ring_free_dw - 1)) { 386 while (ndw > (ring->ring_free_dw - 1)) {
383 radeon_ring_free_size(rdev, ring); 387 radeon_ring_free_size(rdev, ring);
384 if (ndw < ring->ring_free_dw) { 388 if (ndw < ring->ring_free_dw) {
385 break; 389 break;
386 } 390 }
387 r = radeon_fence_wait_next_locked(rdev, ring->idx); 391 r = radeon_fence_wait_next(rdev, ring->idx);
388 if (r) 392 if (r)
389 return r; 393 return r;
390 } 394 }
@@ -478,39 +482,17 @@ void radeon_ring_unlock_undo(struct radeon_device *rdev, struct radeon_ring *rin
478} 482}
479 483
480/** 484/**
481 * radeon_ring_force_activity - add some nop packets to the ring
482 *
483 * @rdev: radeon_device pointer
484 * @ring: radeon_ring structure holding ring information
485 *
486 * Add some nop packets to the ring to force activity (all asics).
487 * Used for lockup detection to see if the rptr is advancing.
488 */
489void radeon_ring_force_activity(struct radeon_device *rdev, struct radeon_ring *ring)
490{
491 int r;
492
493 radeon_ring_free_size(rdev, ring);
494 if (ring->rptr == ring->wptr) {
495 r = radeon_ring_alloc(rdev, ring, 1);
496 if (!r) {
497 radeon_ring_write(ring, ring->nop);
498 radeon_ring_commit(rdev, ring);
499 }
500 }
501}
502
503/**
504 * radeon_ring_lockup_update - update lockup variables 485 * radeon_ring_lockup_update - update lockup variables
505 * 486 *
506 * @ring: radeon_ring structure holding ring information 487 * @ring: radeon_ring structure holding ring information
507 * 488 *
508 * Update the last rptr value and timestamp (all asics). 489 * Update the last rptr value and timestamp (all asics).
509 */ 490 */
510void radeon_ring_lockup_update(struct radeon_ring *ring) 491void radeon_ring_lockup_update(struct radeon_device *rdev,
492 struct radeon_ring *ring)
511{ 493{
512 ring->last_rptr = ring->rptr; 494 atomic_set(&ring->last_rptr, radeon_ring_get_rptr(rdev, ring));
513 ring->last_activity = jiffies; 495 atomic64_set(&ring->last_activity, jiffies_64);
514} 496}
515 497
516/** 498/**
@@ -518,40 +500,23 @@ void radeon_ring_lockup_update(struct radeon_ring *ring)
518 * @rdev: radeon device structure 500 * @rdev: radeon device structure
519 * @ring: radeon_ring structure holding ring information 501 * @ring: radeon_ring structure holding ring information
520 * 502 *
521 * We don't need to initialize the lockup tracking information as we will either 503 */
522 * have CP rptr to a different value of jiffies wrap around which will force
523 * initialization of the lockup tracking informations.
524 *
525 * A possible false positivie is if we get call after while and last_cp_rptr ==
526 * the current CP rptr, even if it's unlikely it might happen. To avoid this
527 * if the elapsed time since last call is bigger than 2 second than we return
528 * false and update the tracking information. Due to this the caller must call
529 * radeon_ring_test_lockup several time in less than 2sec for lockup to be reported
530 * the fencing code should be cautious about that.
531 *
532 * Caller should write to the ring to force CP to do something so we don't get
533 * false positive when CP is just gived nothing to do.
534 *
535 **/
536bool radeon_ring_test_lockup(struct radeon_device *rdev, struct radeon_ring *ring) 504bool radeon_ring_test_lockup(struct radeon_device *rdev, struct radeon_ring *ring)
537{ 505{
538 unsigned long cjiffies, elapsed; 506 uint32_t rptr = radeon_ring_get_rptr(rdev, ring);
507 uint64_t last = atomic64_read(&ring->last_activity);
508 uint64_t elapsed;
539 509
540 cjiffies = jiffies; 510 if (rptr != atomic_read(&ring->last_rptr)) {
541 if (!time_after(cjiffies, ring->last_activity)) { 511 /* ring is still working, no lockup */
542 /* likely a wrap around */ 512 radeon_ring_lockup_update(rdev, ring);
543 radeon_ring_lockup_update(ring);
544 return false; 513 return false;
545 } 514 }
546 ring->rptr = radeon_ring_get_rptr(rdev, ring); 515
547 if (ring->rptr != ring->last_rptr) { 516 elapsed = jiffies_to_msecs(jiffies_64 - last);
548 /* CP is still working no lockup */
549 radeon_ring_lockup_update(ring);
550 return false;
551 }
552 elapsed = jiffies_to_msecs(cjiffies - ring->last_activity);
553 if (radeon_lockup_timeout && elapsed >= radeon_lockup_timeout) { 517 if (radeon_lockup_timeout && elapsed >= radeon_lockup_timeout) {
554 dev_err(rdev->dev, "GPU lockup CP stall for more than %lumsec\n", elapsed); 518 dev_err(rdev->dev, "ring %d stalled for more than %llumsec\n",
519 ring->idx, elapsed);
555 return true; 520 return true;
556 } 521 }
557 /* give a chance to the GPU ... */ 522 /* give a chance to the GPU ... */
@@ -709,7 +674,7 @@ int radeon_ring_init(struct radeon_device *rdev, struct radeon_ring *ring, unsig
709 if (radeon_debugfs_ring_init(rdev, ring)) { 674 if (radeon_debugfs_ring_init(rdev, ring)) {
710 DRM_ERROR("Failed to register debugfs file for rings !\n"); 675 DRM_ERROR("Failed to register debugfs file for rings !\n");
711 } 676 }
712 radeon_ring_lockup_update(ring); 677 radeon_ring_lockup_update(rdev, ring);
713 return 0; 678 return 0;
714} 679}
715 680
@@ -780,8 +745,6 @@ static int radeon_debugfs_ring_info(struct seq_file *m, void *data)
780 745
781 seq_printf(m, "driver's copy of the wptr: 0x%08x [%5d]\n", 746 seq_printf(m, "driver's copy of the wptr: 0x%08x [%5d]\n",
782 ring->wptr, ring->wptr); 747 ring->wptr, ring->wptr);
783 seq_printf(m, "driver's copy of the rptr: 0x%08x [%5d]\n",
784 ring->rptr, ring->rptr);
785 seq_printf(m, "last semaphore signal addr : 0x%016llx\n", 748 seq_printf(m, "last semaphore signal addr : 0x%016llx\n",
786 ring->last_semaphore_signal_addr); 749 ring->last_semaphore_signal_addr);
787 seq_printf(m, "last semaphore wait addr : 0x%016llx\n", 750 seq_printf(m, "last semaphore wait addr : 0x%016llx\n",
@@ -814,6 +777,8 @@ static int cayman_cp2_index = CAYMAN_RING_TYPE_CP2_INDEX;
814static int radeon_dma1_index = R600_RING_TYPE_DMA_INDEX; 777static int radeon_dma1_index = R600_RING_TYPE_DMA_INDEX;
815static int radeon_dma2_index = CAYMAN_RING_TYPE_DMA1_INDEX; 778static int radeon_dma2_index = CAYMAN_RING_TYPE_DMA1_INDEX;
816static int r600_uvd_index = R600_RING_TYPE_UVD_INDEX; 779static int r600_uvd_index = R600_RING_TYPE_UVD_INDEX;
780static int si_vce1_index = TN_RING_TYPE_VCE1_INDEX;
781static int si_vce2_index = TN_RING_TYPE_VCE2_INDEX;
817 782
818static struct drm_info_list radeon_debugfs_ring_info_list[] = { 783static struct drm_info_list radeon_debugfs_ring_info_list[] = {
819 {"radeon_ring_gfx", radeon_debugfs_ring_info, 0, &radeon_gfx_index}, 784 {"radeon_ring_gfx", radeon_debugfs_ring_info, 0, &radeon_gfx_index},
@@ -822,6 +787,8 @@ static struct drm_info_list radeon_debugfs_ring_info_list[] = {
822 {"radeon_ring_dma1", radeon_debugfs_ring_info, 0, &radeon_dma1_index}, 787 {"radeon_ring_dma1", radeon_debugfs_ring_info, 0, &radeon_dma1_index},
823 {"radeon_ring_dma2", radeon_debugfs_ring_info, 0, &radeon_dma2_index}, 788 {"radeon_ring_dma2", radeon_debugfs_ring_info, 0, &radeon_dma2_index},
824 {"radeon_ring_uvd", radeon_debugfs_ring_info, 0, &r600_uvd_index}, 789 {"radeon_ring_uvd", radeon_debugfs_ring_info, 0, &r600_uvd_index},
790 {"radeon_ring_vce1", radeon_debugfs_ring_info, 0, &si_vce1_index},
791 {"radeon_ring_vce2", radeon_debugfs_ring_info, 0, &si_vce2_index},
825}; 792};
826 793
827static int radeon_debugfs_sa_info(struct seq_file *m, void *data) 794static int radeon_debugfs_sa_info(struct seq_file *m, void *data)