diff options
| -rw-r--r-- | drivers/gpu/drm/radeon/radeon_cp.c | 23 | ||||
| -rw-r--r-- | drivers/gpu/drm/radeon/radeon_drv.h | 3 |
2 files changed, 26 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; |
diff --git a/drivers/gpu/drm/radeon/radeon_drv.h b/drivers/gpu/drm/radeon/radeon_drv.h index bc79ad6199bc..cb0cfe4b3082 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.h +++ b/drivers/gpu/drm/radeon/radeon_drv.h | |||
| @@ -1099,6 +1099,9 @@ extern u32 radeon_get_scratch(drm_radeon_private_t *dev_priv, int index); | |||
| 1099 | # define RADEON_CSQ_PRIBM_INDBM (4 << 28) | 1099 | # define RADEON_CSQ_PRIBM_INDBM (4 << 28) |
| 1100 | # define RADEON_CSQ_PRIPIO_INDPIO (15 << 28) | 1100 | # define RADEON_CSQ_PRIPIO_INDPIO (15 << 28) |
| 1101 | 1101 | ||
| 1102 | #define R300_CP_RESYNC_ADDR 0x0778 | ||
| 1103 | #define R300_CP_RESYNC_DATA 0x077c | ||
| 1104 | |||
| 1102 | #define RADEON_AIC_CNTL 0x01d0 | 1105 | #define RADEON_AIC_CNTL 0x01d0 |
| 1103 | # define RADEON_PCIGART_TRANSLATE_EN (1 << 0) | 1106 | # define RADEON_PCIGART_TRANSLATE_EN (1 << 0) |
| 1104 | # define RS400_MSI_REARM (1 << 3) | 1107 | # define RS400_MSI_REARM (1 << 3) |
