diff options
Diffstat (limited to 'drivers/gpu/drm/radeon/radeon_cp.c')
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_cp.c | 23 |
1 files changed, 23 insertions, 0 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_cp.c b/drivers/gpu/drm/radeon/radeon_cp.c index fa063d0cfb63..4f7afc79dd82 100644 --- a/drivers/gpu/drm/radeon/radeon_cp.c +++ b/drivers/gpu/drm/radeon/radeon_cp.c | |||
@@ -616,6 +616,18 @@ static void radeon_do_cp_start(drm_radeon_private_t * dev_priv) | |||
616 | 616 | ||
617 | dev_priv->cp_running = 1; | 617 | dev_priv->cp_running = 1; |
618 | 618 | ||
619 | /* on r420, any DMA from CP to system memory while 2D is active | ||
620 | * can cause a hang. workaround is to queue a CP RESYNC token | ||
621 | */ | ||
622 | if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R420) { | ||
623 | BEGIN_RING(3); | ||
624 | OUT_RING(CP_PACKET0(R300_CP_RESYNC_ADDR, 1)); | ||
625 | OUT_RING(5); /* scratch reg 5 */ | ||
626 | OUT_RING(0xdeadbeef); | ||
627 | ADVANCE_RING(); | ||
628 | COMMIT_RING(); | ||
629 | } | ||
630 | |||
619 | BEGIN_RING(8); | 631 | BEGIN_RING(8); |
620 | /* isync can only be written through cp on r5xx write it here */ | 632 | /* isync can only be written through cp on r5xx write it here */ |
621 | OUT_RING(CP_PACKET0(RADEON_ISYNC_CNTL, 0)); | 633 | OUT_RING(CP_PACKET0(RADEON_ISYNC_CNTL, 0)); |
@@ -653,8 +665,19 @@ static void radeon_do_cp_reset(drm_radeon_private_t * dev_priv) | |||
653 | */ | 665 | */ |
654 | static void radeon_do_cp_stop(drm_radeon_private_t * dev_priv) | 666 | static void radeon_do_cp_stop(drm_radeon_private_t * dev_priv) |
655 | { | 667 | { |
668 | RING_LOCALS; | ||
656 | DRM_DEBUG("\n"); | 669 | DRM_DEBUG("\n"); |
657 | 670 | ||
671 | /* finish the pending CP_RESYNC token */ | ||
672 | if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R420) { | ||
673 | BEGIN_RING(2); | ||
674 | OUT_RING(CP_PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 0)); | ||
675 | OUT_RING(R300_RB3D_DC_FINISH); | ||
676 | ADVANCE_RING(); | ||
677 | COMMIT_RING(); | ||
678 | radeon_do_wait_for_idle(dev_priv); | ||
679 | } | ||
680 | |||
658 | RADEON_WRITE(RADEON_CP_CSQ_CNTL, RADEON_CSQ_PRIDIS_INDDIS); | 681 | RADEON_WRITE(RADEON_CP_CSQ_CNTL, RADEON_CSQ_PRIDIS_INDDIS); |
659 | 682 | ||
660 | dev_priv->cp_running = 0; | 683 | dev_priv->cp_running = 0; |