summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Deucher <alex@samba.(none)>2008-03-07 20:59:16 -0500
committerAlex Deucher <alex@samba.(none)>2008-03-07 20:59:16 -0500
commit6c1c6af282e3e13da188a3254f1c04e73c954428 (patch)
tree2e50dc291b13961bb0cc904c3b2d90f38b8eee33
parent3d001681ba295c9967690956fc52edd8bdb17608 (diff)
R128: get MMIO accel working
-rw-r--r--src/radeon_accel.c121
-rw-r--r--src/radeon_accelfuncs.c2
-rw-r--r--src/radeon_commonfuncs.c5
-rw-r--r--src/radeon_driver.c15
-rw-r--r--src/radeon_exa.c9
-rw-r--r--src/radeon_exa_funcs.c3
-rw-r--r--src/radeon_reg.h20
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)