diff options
author | Alex Deucher <alex@samba.(none)> | 2008-03-07 20:59:16 -0500 |
---|---|---|
committer | Alex Deucher <alex@samba.(none)> | 2008-03-07 20:59:16 -0500 |
commit | 6c1c6af282e3e13da188a3254f1c04e73c954428 (patch) | |
tree | 2e50dc291b13961bb0cc904c3b2d90f38b8eee33 | |
parent | 3d001681ba295c9967690956fc52edd8bdb17608 (diff) |
R128: get MMIO accel working
-rw-r--r-- | src/radeon_accel.c | 121 | ||||
-rw-r--r-- | src/radeon_accelfuncs.c | 2 | ||||
-rw-r--r-- | src/radeon_commonfuncs.c | 5 | ||||
-rw-r--r-- | src/radeon_driver.c | 15 | ||||
-rw-r--r-- | src/radeon_exa.c | 9 | ||||
-rw-r--r-- | src/radeon_exa_funcs.c | 3 | ||||
-rw-r--r-- | src/radeon_reg.h | 20 |
7 files changed, 168 insertions, 7 deletions
diff --git a/src/radeon_accel.c b/src/radeon_accel.c index 05d1384..087e0a7 100644 --- a/src/radeon_accel.c +++ b/src/radeon_accel.c @@ -119,6 +119,123 @@ static struct { }; #endif +/* R128 GUI functions */ +#define R128_TIMEOUT 2000000 /* Fall out of wait loops after this count */ +/* Flush all dirty data in the Pixel Cache to memory. */ +static void +R128EngineFlush(ScrnInfoPtr pScrn) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + int i; + + OUTREGP(R128_PC_NGUI_CTLSTAT, R128_PC_FLUSH_ALL, ~R128_PC_FLUSH_ALL); + for (i = 0; i < R128_TIMEOUT; i++) { + if (!(INREG(R128_PC_NGUI_CTLSTAT) & R128_PC_BUSY)) break; + } +} + +/* Reset graphics card to known state. */ +static void +R128EngineReset(ScrnInfoPtr pScrn) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + CARD32 clock_cntl_index; + CARD32 mclk_cntl; + CARD32 gen_reset_cntl; + + R128EngineFlush(pScrn); + + clock_cntl_index = INREG(RADEON_CLOCK_CNTL_INDEX); + mclk_cntl = INPLL(pScrn, R128_MCLK_CNTL); + + OUTPLL(pScrn, R128_MCLK_CNTL, mclk_cntl | R128_FORCE_GCP | R128_FORCE_PIPE3D_CP); + + gen_reset_cntl = INREG(R128_GEN_RESET_CNTL); + + OUTREG(R128_GEN_RESET_CNTL, gen_reset_cntl | R128_SOFT_RESET_GUI); + INREG(R128_GEN_RESET_CNTL); + OUTREG(R128_GEN_RESET_CNTL, + gen_reset_cntl & (CARD32)(~R128_SOFT_RESET_GUI)); + INREG(R128_GEN_RESET_CNTL); + + OUTPLL(pScrn, R128_MCLK_CNTL, mclk_cntl); + OUTREG(RADEON_CLOCK_CNTL_INDEX, clock_cntl_index); + OUTREG(R128_GEN_RESET_CNTL, gen_reset_cntl); +} + +static void +R128WaitForFifoFunction(ScrnInfoPtr pScrn, int entries) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + int i; + + for (;;) { + for (i = 0; i < R128_TIMEOUT; i++) { + info->fifo_slots = INREG(R128_GUI_STAT) & R128_GUI_FIFOCNT_MASK; + if (info->fifo_slots >= entries) return; + } + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG, + "FIFO timed out: %d entries, stat=0x%08x, probe=0x%08x\n", + INREG(R128_GUI_STAT) & R128_GUI_FIFOCNT_MASK, + INREG(R128_GUI_STAT), + INREG(R128_GUI_PROBE)); + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "FIFO timed out, resetting engine...\n"); + R128EngineReset(pScrn); +#if 0 +#ifdef XF86DRI + R128CCE_RESET(pScrn, info); + if (info->directRenderingEnabled) { + R128CCE_START(pScrn, info); + } +#endif +#endif + } +} + +void +R128WaitForIdle(ScrnInfoPtr pScrn) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + int i; + + R128WaitForFifoFunction(pScrn, 64); + + for (;;) { + for (i = 0; i < R128_TIMEOUT; i++) { + if (!(INREG(R128_GUI_STAT) & R128_GUI_ACTIVE)) { + R128EngineFlush(pScrn); + return; + } + } + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG, + "Idle timed out: %d entries, stat=0x%08x, probe=0x%08x\n", + INREG(R128_GUI_STAT) & R128_GUI_FIFOCNT_MASK, + INREG(R128_GUI_STAT), + INREG(R128_GUI_PROBE)); + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Idle timed out, resetting engine...\n"); +#if 0 +#ifdef XF86DRI + R128CCE_STOP(pScrn, info); +#endif +#endif + R128EngineReset(pScrn); +#if 0 +#ifdef XF86DRI + R128CCE_RESET(pScrn, info); + if (info->directRenderingEnabled) { + R128CCE_START(pScrn, info); + } +#endif +#endif + } +} + /* The FIFO has 64 slots. This routines waits until at least `entries' * of these slots are empty. */ @@ -128,8 +245,10 @@ void RADEONWaitForFifoFunction(ScrnInfoPtr pScrn, int entries) unsigned char *RADEONMMIO = info->MMIO; int i; - if (IS_R128) + if (IS_R128) { + R128WaitForFifoFunction(pScrn, entries); return; + } for (;;) { for (i = 0; i < RADEON_TIMEOUT; i++) { diff --git a/src/radeon_accelfuncs.c b/src/radeon_accelfuncs.c index e3b37c1..5b872e5 100644 --- a/src/radeon_accelfuncs.c +++ b/src/radeon_accelfuncs.c @@ -1301,7 +1301,7 @@ FUNC_NAME(RADEONAccelInit)(ScreenPtr pScreen, XAAInfoRecPtr a) a->CPUToScreenTextureFormats = RADEONTextureFormats; a->CPUToScreenTextureDstFormats = RADEONDstFormats; - if (IS_R300_VARIANT || IS_AVIVO_VARIANT) { + if (IS_R300_VARIANT || IS_AVIVO_VARIANT || IS_R128) { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Render acceleration " "unsupported on Radeon 9500/9700 and newer.\n"); } else if ((info->ChipFamily == CHIP_FAMILY_RV250) || diff --git a/src/radeon_commonfuncs.c b/src/radeon_commonfuncs.c index 45dc14b..e3238d1 100644 --- a/src/radeon_commonfuncs.c +++ b/src/radeon_commonfuncs.c @@ -304,6 +304,11 @@ void FUNC_NAME(RADEONWaitForIdle)(ScrnInfoPtr pScrn) unsigned char *RADEONMMIO = info->MMIO; int i = 0; + if (IS_R128) { + R128WaitForIdle(pScrn); + return; + } + #ifdef ACCEL_CP /* Make sure the CP is idle first */ if (info->CPStarted) { diff --git a/src/radeon_driver.c b/src/radeon_driver.c index 114e80d..2e7f42a 100644 --- a/src/radeon_driver.c +++ b/src/radeon_driver.c @@ -2051,6 +2051,9 @@ static Bool RADEONPreInitDRI(ScrnInfoPtr pScrn) if (info->IsSecondary) return FALSE; + if (IS_R128) + return FALSE; + if (info->Chipset == PCI_CHIP_RN50_515E || info->Chipset == PCI_CHIP_RN50_5969 || info->Chipset == PCI_CHIP_RC410_5A61 || @@ -2272,6 +2275,9 @@ static void RADEONPreInitColorTiling(ScrnInfoPtr pScrn) if (info->ChipFamily >= CHIP_FAMILY_R600) info->allowColorTiling = FALSE; + if (IS_R128) + info->allowColorTiling = FALSE; + /* for zaphod disable tiling for now */ if (info->IsPrimary || info->IsSecondary) info->allowColorTiling = FALSE; @@ -3308,8 +3314,13 @@ Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen, return FALSE; #endif - info->dst_pitch_offset = (((pScrn->displayWidth * info->CurrentLayout.pixel_bytes / 64) - << 22) | ((info->fbLocation + pScrn->fbOffset) >> 10)); + if (IS_R128) + info->dst_pitch_offset = + ((((pScrn->displayWidth * info->CurrentLayout.pixel_bytes) / pScrn->bitsPerPixel) << 21) | + ((info->fbLocation + pScrn->fbOffset) >> 5)); + else + info->dst_pitch_offset = (((pScrn->displayWidth * info->CurrentLayout.pixel_bytes / 64) + << 22) | ((info->fbLocation + pScrn->fbOffset) >> 10)); /* Setup DRI after visuals have been established, but before fbScreenInit is * called. fbScreenInit will eventually call the driver's InitGLXVisuals diff --git a/src/radeon_exa.c b/src/radeon_exa.c index 4da4841..0928591 100644 --- a/src/radeon_exa.c +++ b/src/radeon_exa.c @@ -163,8 +163,13 @@ static Bool RADEONGetOffsetPitch(PixmapPtr pPix, int bpp, CARD32 *pitch_offset, if (offset % info->exa->pixmapOffsetAlign != 0) RADEON_FALLBACK(("Bad offset 0x%08x\n", offset)); - pitch = pitch >> 6; - *pitch_offset = (pitch << 22) | (offset >> 10); + if (IS_R128) { + pitch = pitch / pPix->drawable.bitsPerPixel; + *pitch_offset = (pitch << 21) | (offset >> 5); + } else { + pitch = pitch >> 6; + *pitch_offset = (pitch << 22) | (offset >> 10); + } /* If it's the front buffer, we've got to note that it's tiled? */ if (RADEONPixmapIsColortiled(pPix)) diff --git a/src/radeon_exa_funcs.c b/src/radeon_exa_funcs.c index 84beec3..268277a 100644 --- a/src/radeon_exa_funcs.c +++ b/src/radeon_exa_funcs.c @@ -528,12 +528,13 @@ Bool FUNC_NAME(RADEONDrawInit)(ScreenPtr pScreen) #endif /* X_BYTE_ORDER == X_BIG_ENDIAN */ info->exa->flags = EXA_OFFSCREEN_PIXMAPS; + info->exa->pixmapOffsetAlign = RADEON_BUFFER_ALIGN + 1; info->exa->pixmapPitchAlign = 64; #ifdef RENDER if (info->RenderAccel) { - if (info->ChipFamily >= CHIP_FAMILY_R600) + if ((info->ChipFamily >= CHIP_FAMILY_R600) || IS_R128) xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Render acceleration " "unsupported on R600 and newer cards.\n"); else if (IS_R300_VARIANT || (IS_AVIVO_VARIANT && info->ChipFamily <= CHIP_FAMILY_RS740)) { diff --git a/src/radeon_reg.h b/src/radeon_reg.h index 342d7b7..46b8dd5 100644 --- a/src/radeon_reg.h +++ b/src/radeon_reg.h @@ -1405,6 +1405,26 @@ # define RADEON_PPLL_ATOMIC_UPDATE_W (1 << 15) /* same as _R */ #define RADEON_PWR_MNGMT_CNTL_STATUS 0x0f60 /* PCI */ +#define R128_GUI_PROBE 0x16bc +#define R128_GUI_STAT 0x1740 +# define R128_GUI_FIFOCNT_MASK 0x0fff +# define R128_GUI_ACTIVE (1 << 31) +#define R128_PC_NGUI_CTLSTAT 0x0184 +# define R128_PC_FLUSH_GUI (3 << 0) +# define R128_PC_RI_GUI (1 << 2) +# define R128_PC_FLUSH_ALL 0x00ff +# define R128_PC_BUSY (1 << 31) +#define R128_GEN_RESET_CNTL 0x00f0 +# define R128_SOFT_RESET_GUI (1 << 0) +# define R128_SOFT_RESET_VCLK (1 << 8) +# define R128_SOFT_RESET_PCLK (1 << 9) +# define R128_SOFT_RESET_DISPENG_XCLK (1 << 11) +# define R128_SOFT_RESET_MEMCTLR_XCLK (1 << 12) +#define R128_MCLK_CNTL 0x000f /* PLL */ +# define R128_FORCE_GCP (1 << 16) +# define R128_FORCE_PIPE3D_CP (1 << 17) +# define R128_FORCE_RCP (1 << 18) + #define RADEON_RBBM_GUICNTL 0x172c # define RADEON_HOST_DATA_SWAP_NONE (0 << 0) # define RADEON_HOST_DATA_SWAP_16BIT (1 << 0) |