diff options
author | Alex Deucher <alexdeucher@gmail.com> | 2009-09-21 00:48:45 -0400 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2009-09-21 00:48:45 -0400 |
commit | aadd4e17452d3d5c2269cd2b000b7de7cfb6c79e (patch) | |
tree | 7db901a331809805874891319e0624c055a08662 /drivers/gpu/drm/radeon/radeon_cp.c | |
parent | 5a6e9f9658c853fea8ebbf64cd36287f00a011a2 (diff) |
drm/radeon: some r420s have a CP race with the DMA engine.
This patch makes sure the CP doesn't DMA do VRAM while 2D
is active by inserting a CP resync token.
todo: port to kms.
Signed-off-by: Dave Airlie <airlied@redhat.com>
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; |