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>
This commit is contained in:
parent
5a6e9f9658
commit
aadd4e1745
@ -616,6 +616,18 @@ static void radeon_do_cp_start(drm_radeon_private_t * dev_priv)
|
|||||||
|
|
||||||
dev_priv->cp_running = 1;
|
dev_priv->cp_running = 1;
|
||||||
|
|
||||||
|
/* on r420, any DMA from CP to system memory while 2D is active
|
||||||
|
* can cause a hang. workaround is to queue a CP RESYNC token
|
||||||
|
*/
|
||||||
|
if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R420) {
|
||||||
|
BEGIN_RING(3);
|
||||||
|
OUT_RING(CP_PACKET0(R300_CP_RESYNC_ADDR, 1));
|
||||||
|
OUT_RING(5); /* scratch reg 5 */
|
||||||
|
OUT_RING(0xdeadbeef);
|
||||||
|
ADVANCE_RING();
|
||||||
|
COMMIT_RING();
|
||||||
|
}
|
||||||
|
|
||||||
BEGIN_RING(8);
|
BEGIN_RING(8);
|
||||||
/* isync can only be written through cp on r5xx write it here */
|
/* isync can only be written through cp on r5xx write it here */
|
||||||
OUT_RING(CP_PACKET0(RADEON_ISYNC_CNTL, 0));
|
OUT_RING(CP_PACKET0(RADEON_ISYNC_CNTL, 0));
|
||||||
@ -653,8 +665,19 @@ static void radeon_do_cp_reset(drm_radeon_private_t * dev_priv)
|
|||||||
*/
|
*/
|
||||||
static void radeon_do_cp_stop(drm_radeon_private_t * dev_priv)
|
static void radeon_do_cp_stop(drm_radeon_private_t * dev_priv)
|
||||||
{
|
{
|
||||||
|
RING_LOCALS;
|
||||||
DRM_DEBUG("\n");
|
DRM_DEBUG("\n");
|
||||||
|
|
||||||
|
/* finish the pending CP_RESYNC token */
|
||||||
|
if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R420) {
|
||||||
|
BEGIN_RING(2);
|
||||||
|
OUT_RING(CP_PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 0));
|
||||||
|
OUT_RING(R300_RB3D_DC_FINISH);
|
||||||
|
ADVANCE_RING();
|
||||||
|
COMMIT_RING();
|
||||||
|
radeon_do_wait_for_idle(dev_priv);
|
||||||
|
}
|
||||||
|
|
||||||
RADEON_WRITE(RADEON_CP_CSQ_CNTL, RADEON_CSQ_PRIDIS_INDDIS);
|
RADEON_WRITE(RADEON_CP_CSQ_CNTL, RADEON_CSQ_PRIDIS_INDDIS);
|
||||||
|
|
||||||
dev_priv->cp_running = 0;
|
dev_priv->cp_running = 0;
|
||||||
|
@ -1099,6 +1099,9 @@ extern u32 radeon_get_scratch(drm_radeon_private_t *dev_priv, int index);
|
|||||||
# define RADEON_CSQ_PRIBM_INDBM (4 << 28)
|
# define RADEON_CSQ_PRIBM_INDBM (4 << 28)
|
||||||
# define RADEON_CSQ_PRIPIO_INDPIO (15 << 28)
|
# define RADEON_CSQ_PRIPIO_INDPIO (15 << 28)
|
||||||
|
|
||||||
|
#define R300_CP_RESYNC_ADDR 0x0778
|
||||||
|
#define R300_CP_RESYNC_DATA 0x077c
|
||||||
|
|
||||||
#define RADEON_AIC_CNTL 0x01d0
|
#define RADEON_AIC_CNTL 0x01d0
|
||||||
# define RADEON_PCIGART_TRANSLATE_EN (1 << 0)
|
# define RADEON_PCIGART_TRANSLATE_EN (1 << 0)
|
||||||
# define RS400_MSI_REARM (1 << 3)
|
# define RS400_MSI_REARM (1 << 3)
|
||||||
|
Loading…
Reference in New Issue
Block a user