diff options
author | Alex Deucher <alexdeucher@gmail.com> | 2009-02-19 21:18:07 -0500 |
---|---|---|
committer | Alex Deucher <alexdeucher@gmail.com> | 2009-02-19 21:18:07 -0500 |
commit | 27f8ca2cce65be2bcb3375231886d5444d251808 (patch) | |
tree | c2ed403242c3a3daa8fba10c866512872dda5a21 | |
parent | e6475282486f4895bc68f6b093ecbb1aa6d25f72 (diff) |
R6xx/R7xx: add wait for idle MMIO path
-rw-r--r-- | src/radeon_accel.c | 34 | ||||
-rw-r--r-- | src/radeon_commonfuncs.c | 75 | ||||
-rw-r--r-- | src/radeon_reg.h | 7 |
3 files changed, 85 insertions, 31 deletions
diff --git a/src/radeon_accel.c b/src/radeon_accel.c index 2b17cd15..dffbc576 100644 --- a/src/radeon_accel.c +++ b/src/radeon_accel.c @@ -93,6 +93,7 @@ /* X and server generic header files */ #include "xf86.h" +static void R600EngineReset(ScrnInfoPtr pScrn); #ifdef USE_XAA static struct { @@ -150,6 +151,37 @@ void RADEONWaitForFifoFunction(ScrnInfoPtr pScrn, int entries) } } +void R600WaitForFifoFunction(ScrnInfoPtr pScrn, int entries) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + int i; + + for (;;) { + for (i = 0; i < RADEON_TIMEOUT; i++) { + if (info->ChipFamily >= CHIP_FAMILY_RV770) + info->accel_state->fifo_slots = + INREG(R600_GRBM_STATUS) & R700_CMDFIFO_AVAIL_MASK; + else + info->accel_state->fifo_slots = + INREG(R600_GRBM_STATUS) & R600_CMDFIFO_AVAIL_MASK; + if (info->accel_state->fifo_slots >= entries) return; + } + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG, + "FIFO timed out: stat=0x%08x\n", + (unsigned int)INREG(R600_GRBM_STATUS)); + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "FIFO timed out, resetting engine...\n"); + R600EngineReset(pScrn); +#ifdef XF86DRI + if (info->directRenderingEnabled) { + RADEONCP_RESET(pScrn, info); + RADEONCP_START(pScrn, info); + } +#endif + } +} + /* Flush all dirty data in the Pixel Cache to memory */ void RADEONEngineFlush(ScrnInfoPtr pScrn) { @@ -307,7 +339,7 @@ void RADEONEngineReset(ScrnInfoPtr pScrn) } /* Reset graphics card to known state */ -void R600EngineReset(ScrnInfoPtr pScrn) +static void R600EngineReset(ScrnInfoPtr pScrn) { RADEONInfoPtr info = RADEONPTR(pScrn); unsigned char *RADEONMMIO = info->MMIO; diff --git a/src/radeon_commonfuncs.c b/src/radeon_commonfuncs.c index d69a9d8e..f7a1a602 100644 --- a/src/radeon_commonfuncs.c +++ b/src/radeon_commonfuncs.c @@ -746,39 +746,56 @@ void FUNC_NAME(RADEONWaitForIdle)(ScrnInfoPtr pScrn) } #endif -#if 0 - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG, - "WaitForIdle (entering): %d entries, stat=0x%08x\n", - INREG(RADEON_RBBM_STATUS) & RADEON_RBBM_FIFOCNT_MASK, - INREG(RADEON_RBBM_STATUS)); -#endif - - if (info->ChipFamily >= CHIP_FAMILY_R600) - return; - - /* Wait for the engine to go idle */ - RADEONWaitForFifoFunction(pScrn, 64); + if (info->ChipFamily >= CHIP_FAMILY_R600) { + /* Wait for the engine to go idle */ + if (info->ChipFamily >= CHIP_FAMILY_RV770) + R600WaitForFifoFunction(pScrn, 8); + else + R600WaitForFifoFunction(pScrn, 16); - for (;;) { - for (i = 0; i < RADEON_TIMEOUT; i++) { - if (!(INREG(RADEON_RBBM_STATUS) & RADEON_RBBM_ACTIVE)) { - RADEONEngineFlush(pScrn); - return; + for (;;) { + for (i = 0; i < RADEON_TIMEOUT; i++) { + if (!(INREG(R600_GRBM_STATUS) & R600_GUI_ACTIVE)) + return; } - } - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG, - "Idle timed out: %u entries, stat=0x%08x\n", - (unsigned int)INREG(RADEON_RBBM_STATUS) & RADEON_RBBM_FIFOCNT_MASK, - (unsigned int)INREG(RADEON_RBBM_STATUS)); - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Idle timed out, resetting engine...\n"); - RADEONEngineReset(pScrn); - RADEONEngineRestore(pScrn); + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG, + "Idle timed out: stat=0x%08x\n", + (unsigned int)INREG(R600_GRBM_STATUS)); + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Idle timed out, resetting engine...\n"); + R600EngineReset(pScrn); #ifdef XF86DRI - if (info->directRenderingEnabled) { - RADEONCP_RESET(pScrn, info); - RADEONCP_START(pScrn, info); + if (info->directRenderingEnabled) { + RADEONCP_RESET(pScrn, info); + RADEONCP_START(pScrn, info); + } +#endif } + } else { + /* Wait for the engine to go idle */ + RADEONWaitForFifoFunction(pScrn, 64); + + for (;;) { + for (i = 0; i < RADEON_TIMEOUT; i++) { + if (!(INREG(RADEON_RBBM_STATUS) & RADEON_RBBM_ACTIVE)) { + RADEONEngineFlush(pScrn); + return; + } + } + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG, + "Idle timed out: %u entries, stat=0x%08x\n", + (unsigned int)INREG(RADEON_RBBM_STATUS) & RADEON_RBBM_FIFOCNT_MASK, + (unsigned int)INREG(RADEON_RBBM_STATUS)); + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Idle timed out, resetting engine...\n"); + RADEONEngineReset(pScrn); + RADEONEngineRestore(pScrn); +#ifdef XF86DRI + if (info->directRenderingEnabled) { + RADEONCP_RESET(pScrn, info); + RADEONCP_START(pScrn, info); + } #endif + } } } diff --git a/src/radeon_reg.h b/src/radeon_reg.h index 7f0281a7..4d743a40 100644 --- a/src/radeon_reg.h +++ b/src/radeon_reg.h @@ -5368,10 +5368,15 @@ #define R500_DYN_SCLK_PWMEM_PIPE 0x000d /* PLL */ /* r6xx/r7xx stuff */ +#define R600_GRBM_STATUS 0x8010 +# define R600_CMDFIFO_AVAIL_MASK 0x1f +# define R700_CMDFIFO_AVAIL_MASK 0xf +# define R600_GUI_ACTIVE (1 << 31) + #define R600_GRBM_SOFT_RESET 0x8020 # define R600_SOFT_RESET_CP (1 << 0) -#define R600_WAIT_UNTIL 0x8040 +#define R600_WAIT_UNTIL 0x8040 #define R600_CP_ME_CNTL 0x86d8 # define R600_CP_ME_HALT (1 << 28) |