summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Deucher <alexdeucher@gmail.com>2009-02-19 21:18:07 -0500
committerAlex Deucher <alexdeucher@gmail.com>2009-02-19 21:18:07 -0500
commit27f8ca2cce65be2bcb3375231886d5444d251808 (patch)
treec2ed403242c3a3daa8fba10c866512872dda5a21
parente6475282486f4895bc68f6b093ecbb1aa6d25f72 (diff)
R6xx/R7xx: add wait for idle MMIO path
-rw-r--r--src/radeon_accel.c34
-rw-r--r--src/radeon_commonfuncs.c75
-rw-r--r--src/radeon_reg.h7
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)