Index: radeon_accel.c =================================================================== RCS file: /cvs/xorg/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_accel.c,v retrieving revision 1.10 diff -u -p -b -r1.10 radeon_accel.c --- xc.orig/programs/Xserver/hw/xfree86/drivers/ati/radeon_accel.c 12 Aug 2004 05:00:22 -0000 1.10 +++ xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_accel.c 15 Oct 2004 21:13:47 -0000 @@ -168,6 +168,31 @@ void RADEONEngineReset(ScrnInfoPtr pScrn CARD32 rbbm_soft_reset; CARD32 host_path_cntl; + /* The following RBBM_SOFT_RESET sequence can help un-wedge + * an R300 after the command processor got stuck. + */ + rbbm_soft_reset = INREG(RADEON_RBBM_SOFT_RESET); + OUTREG(RADEON_RBBM_SOFT_RESET, (rbbm_soft_reset | + RADEON_SOFT_RESET_CP | + RADEON_SOFT_RESET_HI | + RADEON_SOFT_RESET_SE | + RADEON_SOFT_RESET_RE | + RADEON_SOFT_RESET_PP | + RADEON_SOFT_RESET_E2 | + RADEON_SOFT_RESET_RB)); + INREG(RADEON_RBBM_SOFT_RESET); + OUTREG(RADEON_RBBM_SOFT_RESET, (rbbm_soft_reset & (CARD32) + ~(RADEON_SOFT_RESET_CP | + RADEON_SOFT_RESET_HI | + RADEON_SOFT_RESET_SE | + RADEON_SOFT_RESET_RE | + RADEON_SOFT_RESET_PP | + RADEON_SOFT_RESET_E2 | + RADEON_SOFT_RESET_RB))); + INREG(RADEON_RBBM_SOFT_RESET); + OUTREG(RADEON_RBBM_SOFT_RESET, rbbm_soft_reset); + INREG(RADEON_RBBM_SOFT_RESET); + RADEONEngineFlush(pScrn); clock_cntl_index = INREG(RADEON_CLOCK_CNTL_INDEX); @@ -531,6 +556,30 @@ void RADEONCPFlushIndirect(ScrnInfoPtr p buffer->idx); } + /* TODO: Fix this more elegantly. + * Sometimes (especially with multiple DRI clients), this code + * runs immediately after a DRI client issues a rendering command. + * + * The accel code regularly inserts WAIT_UNTIL_IDLE into the + * command buffer that is sent with the indirect buffer below. + * The accel code fails to set the 3D cache flush registers for + * the R300 before sending WAIT_UNTIL_IDLE. Sending a cache flush + * on these new registers is not necessary for pure 2D functionality, + * but it *is* necessary after 3D operations. + * Without the cache flushes before WAIT_UNTIL_IDLE, the R300 locks up. + * + * The CP_IDLE call into the DRM indirectly flushes all caches and + * thus avoids the lockup problem, but the solution is far from ideal. + * Better solutions could be: + * - always flush caches when entering the X server + * - track the type of rendering commands somewhere and issue + * cache flushes when they change + * However, I don't feel confident enough with the control flow + * inside the X server to implement either fix. -- nh + */ + if (IS_R300_VARIANT) + drmCommandNone(info->drmFD, DRM_RADEON_CP_IDLE); + indirect.idx = buffer->idx; indirect.start = start; indirect.end = buffer->used; @@ -570,6 +619,10 @@ void RADEONCPReleaseIndirect(ScrnInfoPtr buffer->idx); } + /* Hack for the R300 (see RADEONCPFlushIndirect for explanation) */ + if (IS_R300_VARIANT) + drmCommandNone(info->drmFD, DRM_RADEON_CP_IDLE); + indirect.idx = buffer->idx; indirect.start = start; indirect.end = buffer->used; Index: radeon_common.h =================================================================== RCS file: /cvs/xorg/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_common.h,v retrieving revision 1.3 diff -u -p -b -r1.3 radeon_common.h --- xc.orig/programs/Xserver/hw/xfree86/drivers/ati/radeon_common.h 16 Jun 2004 09:43:58 -0000 1.3 +++ xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_common.h 15 Oct 2004 21:13:50 -0000 @@ -93,7 +93,8 @@ typedef struct { enum { DRM_RADEON_INIT_CP = 0x01, DRM_RADEON_CLEANUP_CP = 0x02, - DRM_RADEON_INIT_R200_CP = 0x03 + DRM_RADEON_INIT_R200_CP = 0x03, + DRM_RADEON_INIT_R300_CP = 0x04 } func; unsigned long sarea_priv_offset; int is_pci; Index: radeon_dri.c =================================================================== RCS file: /cvs/xorg/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dri.c,v retrieving revision 1.7 diff -u -p -b -r1.7 radeon_dri.c --- xc.orig/programs/Xserver/hw/xfree86/drivers/ati/radeon_dri.c 12 Aug 2004 05:00:22 -0000 1.7 +++ xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dri.c 15 Oct 2004 21:13:55 -0000 @@ -1025,7 +1025,9 @@ static int RADEONDRIKernelInit(RADEONInf memset(&drmInfo, 0, sizeof(drmRadeonInit)); - if ( info->ChipFamily >= CHIP_FAMILY_R200 ) + if ( info->ChipFamily >= CHIP_FAMILY_R300 ) + drmInfo.func = DRM_RADEON_INIT_R300_CP; + else if ( info->ChipFamily >= CHIP_FAMILY_R200 ) drmInfo.func = DRM_RADEON_INIT_R200_CP; else drmInfo.func = DRM_RADEON_INIT_CP; @@ -1184,6 +1186,12 @@ Bool RADEONDRIScreenInit(ScreenPtr pScre int major, minor, patch; drmVersionPtr version; + if (info->ChipFamily >= CHIP_FAMILY_R300) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Direct rendering support is highly experimental for " + "Radeon 9500/9700 and newer cards\n"); + } + /* Check that the GLX, DRI, and DRM modules have been loaded by testing * for known symbols in each module. */ @@ -1236,7 +1244,9 @@ Bool RADEONDRIScreenInit(ScreenPtr pScre info->pDRIInfo = pDRIInfo; pDRIInfo->drmDriverName = RADEON_DRIVER_NAME; - if ( info->ChipFamily >= CHIP_FAMILY_R200 ) + if ( info->ChipFamily >= CHIP_FAMILY_R300 ) + pDRIInfo->clientDriverName = R300_DRIVER_NAME; + else if ( info->ChipFamily >= CHIP_FAMILY_R200 ) pDRIInfo->clientDriverName = R200_DRIVER_NAME; else pDRIInfo->clientDriverName = RADEON_DRIVER_NAME; @@ -1371,6 +1381,9 @@ Bool RADEONDRIScreenInit(ScreenPtr pScre } else if (info->ChipFamily >= CHIP_FAMILY_R200) { req_minor = 5; req_patch = 0; + } else if (info->ChipFamily >= CHIP_FAMILY_R300) { + req_minor = 11; + req_patch = 1; } else { #if X_BYTE_ORDER == X_LITTLE_ENDIAN req_minor = 1; Index: radeon_driver.c =================================================================== RCS file: /cvs/xorg/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c,v retrieving revision 1.19 diff -u -p -b -r1.19 radeon_driver.c --- xc.orig/programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c 25 Aug 2004 00:30:41 -0000 1.19 +++ xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c 15 Oct 2004 21:14:10 -0000 @@ -4526,11 +4526,13 @@ Bool RADEONScreenInit(int scrnIndex, Scr (pScrn->displayWidth * pScrn->virtualY * info->CurrentLayout.pixel_bytes * 3 + 1023) / 1024); info->directRenderingEnabled = FALSE; +#if 0 } else if (info->ChipFamily >= CHIP_FAMILY_R300) { info->directRenderingEnabled = FALSE; xf86DrvMsg(scrnIndex, X_WARNING, "Direct rendering not yet supported on " "Radeon 9500 and newer cards\n"); +#endif } else if (info->IsSecondary) { info->directRenderingEnabled = FALSE; } else if (xf86IsEntityShared(info->pEnt->index)) { Index: radeon_version.h =================================================================== RCS file: /cvs/xorg/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_version.h,v retrieving revision 1.2 diff -u -p -b -r1.2 radeon_version.h --- xc.orig/programs/Xserver/hw/xfree86/drivers/ati/radeon_version.h 23 Apr 2004 19:26:46 -0000 1.2 +++ xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_version.h 15 Oct 2004 21:14:10 -0000 @@ -38,6 +38,7 @@ #define RADEON_NAME "RADEON" #define RADEON_DRIVER_NAME "radeon" #define R200_DRIVER_NAME "r200" +#define R300_DRIVER_NAME "r300" #define RADEON_VERSION_MAJOR 4 #define RADEON_VERSION_MINOR 0