diff options
Diffstat (limited to 'src/radeon_driver.c')
-rw-r--r-- | src/radeon_driver.c | 432 |
1 files changed, 275 insertions, 157 deletions
diff --git a/src/radeon_driver.c b/src/radeon_driver.c index 38ff68f..7155e42 100644 --- a/src/radeon_driver.c +++ b/src/radeon_driver.c @@ -1,5 +1,5 @@ /* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c,v 1.117 2004/02/19 22:38:12 tsi Exp $ */ -/* $XdotOrg: driver/xf86-video-ati/src/radeon_driver.c,v 1.92.2.17 2006/04/24 07:46:37 benh Exp $ */ +/* $XdotOrg: driver/xf86-video-ati/src/radeon_driver.c,v 1.116 2006/04/29 21:30:23 daenzer Exp $ */ /* * Copyright 2000 ATI Technologies Inc., Markham, Ontario, and * VA Linux Systems Inc., Fremont, California. @@ -67,6 +67,9 @@ * */ +#include <string.h> +#include <stdio.h> + /* Driver data structures */ #include "radeon.h" #include "radeon_reg.h" @@ -90,6 +93,7 @@ /* X and server generic header files */ #include "xf86.h" +#include "xf86_ansic.h" /* For xf86getsecs() */ #include "xf86_OSproc.h" #include "xf86RAC.h" #include "xf86Resources.h" @@ -129,77 +133,18 @@ static void RADEONInitDispBandwidth(ScrnInfoPtr pScrn); static void RADEONGetMergedFBOptions(ScrnInfoPtr pScrn); static int RADEONValidateMergeModes(ScrnInfoPtr pScrn); static void RADEONSetDynamicClock(ScrnInfoPtr pScrn, int mode); +static void RADEONForceSomeClocks(ScrnInfoPtr pScrn); static void RADEONUpdatePanelSize(ScrnInfoPtr pScrn); static void RADEONSaveMemMapRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save); + +#ifdef XF86DRI static void RADEONAdjustMemMapRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save); +#endif /* psuedo xinerama support */ extern Bool RADEONnoPanoramiXExtension; -typedef enum { - OPTION_NOACCEL, - OPTION_SW_CURSOR, - OPTION_DAC_6BIT, - OPTION_DAC_8BIT, -#ifdef XF86DRI - OPTION_BUS_TYPE, - OPTION_CP_PIO, - OPTION_USEC_TIMEOUT, - OPTION_AGP_MODE, - OPTION_AGP_FW, - OPTION_GART_SIZE, - OPTION_GART_SIZE_OLD, - OPTION_RING_SIZE, - OPTION_BUFFER_SIZE, - OPTION_DEPTH_MOVE, - OPTION_PAGE_FLIP, - OPTION_NO_BACKBUFFER, - OPTION_XV_DMA, - OPTION_FBTEX_PERCENT, -#endif - OPTION_PANEL_OFF, - OPTION_DDC_MODE, - OPTION_MONITOR_LAYOUT, - OPTION_IGNORE_EDID, - OPTION_FBDEV, - OPTION_MERGEDFB, - OPTION_CRT2HSYNC, - OPTION_CRT2VREFRESH, - OPTION_CRT2POS, - OPTION_METAMODES, - OPTION_MERGEDDPI, - OPTION_RADEONXINERAMA, - OPTION_CRT2ISSCRN0, - OPTION_MERGEDFBNONRECT, - OPTION_MERGEDFBMOUSER, - OPTION_DISP_PRIORITY, - OPTION_PANEL_SIZE, - OPTION_MIN_DOTCLOCK, - OPTION_COLOR_TILING, -#ifdef XvExtension - OPTION_VIDEO_KEY, - OPTION_RAGE_THEATRE_CRYSTAL, - OPTION_RAGE_THEATRE_TUNER_PORT, - OPTION_RAGE_THEATRE_COMPOSITE_PORT, - OPTION_RAGE_THEATRE_SVIDEO_PORT, - OPTION_TUNER_TYPE, - OPTION_RAGE_THEATRE_MICROC_PATH, - OPTION_RAGE_THEATRE_MICROC_TYPE, -#endif -#ifdef RENDER - OPTION_RENDER_ACCEL, - OPTION_SUBPIXEL_ORDER, -#endif - OPTION_SHOWCACHE, - OPTION_DYNAMIC_CLOCKS, - OPTION_BIOS_HOTKEYS, - OPTION_VGA_ACCESS, - OPTION_REVERSE_DDC, - OPTION_LVDS_PROBE_PLL, - OPTION_ACCELMETHOD -} RADEONOpts; - static const OptionInfoRec RADEONOptions[] = { { OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE }, { OPTION_SW_CURSOR, "SWcursor", OPTV_BOOLEAN, {0}, FALSE }, @@ -220,6 +165,10 @@ static const OptionInfoRec RADEONOptions[] = { { OPTION_NO_BACKBUFFER, "NoBackBuffer", OPTV_BOOLEAN, {0}, FALSE }, { OPTION_XV_DMA, "DMAForXv", OPTV_BOOLEAN, {0}, FALSE }, { OPTION_FBTEX_PERCENT, "FBTexPercent", OPTV_INTEGER, {0}, FALSE }, + { OPTION_DEPTH_BITS, "DepthBits", OPTV_INTEGER, {0}, FALSE }, +#ifdef USE_EXA + { OPTION_ACCEL_DFS, "AccelDFS", OPTV_BOOLEAN, {0}, FALSE }, +#endif #endif { OPTION_PANEL_OFF, "PanelOff", OPTV_BOOLEAN, {0}, FALSE }, { OPTION_DDC_MODE, "DDCMode", OPTV_BOOLEAN, {0}, FALSE }, @@ -261,6 +210,7 @@ static const OptionInfoRec RADEONOptions[] = { { OPTION_REVERSE_DDC, "ReverseDDC", OPTV_BOOLEAN, {0}, FALSE }, { OPTION_LVDS_PROBE_PLL, "LVDSProbePLL", OPTV_BOOLEAN, {0}, FALSE }, { OPTION_ACCELMETHOD, "AccelMethod", OPTV_STRING, {0}, FALSE }, + { OPTION_CONSTANTDPI, "ConstantDPI", OPTV_BOOLEAN, {0}, FALSE }, { -1, NULL, OPTV_NONE, {0}, FALSE } }; @@ -324,6 +274,7 @@ static const char *fbSymbols[] = { #ifdef USE_EXA static const char *exaSymbols[] = { + "exaDriverAlloc", "exaDriverInit", "exaDriverFini", "exaOffscreenAlloc", @@ -518,7 +469,7 @@ static const RADEONTMDSPll default_tmds_pll[CHIP_FAMILY_LAST][4] = {{15000, 0xa1b}, {0xffffffff, 0xa3f}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_R200*/ {{15500, 0x81b}, {0xffffffff, 0x83f}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_RV250*/ {{0, 0}, {0, 0}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_RS300*/ - {{13000, 0x400f4}, {15000, 0x400f7}, {0xffffffff, 0x400f7/*0x40111*/}, {0, 0}}, /*CHIP_FAMILY_RV280*/ + {{13000, 0x400f4}, {15000, 0x400f7}, {0xffffffff, 0x40111}, {0, 0}}, /*CHIP_FAMILY_RV280*/ {{0xffffffff, 0xb01cb}, {0, 0}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_R300*/ {{0xffffffff, 0xb01cb}, {0, 0}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_R350*/ {{15000, 0xb0155}, {0xffffffff, 0xb01cb}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_RV350*/ @@ -708,7 +659,7 @@ static Bool RADEONMapMMIO(ScrnInfoPtr pScrn) VIDMEM_MMIO | VIDMEM_READSIDEEFFECT, info->PciTag, info->MMIOAddr, - RADEON_MMIOSIZE); + info->MMIOSize); } if (!info->MMIO) return FALSE; @@ -725,7 +676,7 @@ static Bool RADEONUnmapMMIO(ScrnInfoPtr pScrn) if (info->FBDev) fbdevHWUnmapMMIO(pScrn); else { - xf86UnMapVidMem(pScrn->scrnIndex, info->MMIO, RADEON_MMIOSIZE); + xf86UnMapVidMem(pScrn->scrnIndex, info->MMIO, info->MMIOSize); } info->MMIO = NULL; return TRUE; @@ -739,7 +690,7 @@ static Bool RADEONMapFB(ScrnInfoPtr pScrn) if (info->FBDev) { info->FB = fbdevHWMapVidmem(pScrn); } else { - RADEONTRACE(("Map: 0x%08x, 0x%08x\n", info->LinearAddr, info->FbMapSize)); + RADEONTRACE(("Map: 0x%08lx, 0x%08lx\n", info->LinearAddr, info->FbMapSize)); info->FB = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_FRAMEBUFFER, info->PciTag, @@ -2295,7 +2246,7 @@ static void RADEONInitMemoryMap(ScrnInfoPtr pScrn) { RADEONInfoPtr info = RADEONPTR(pScrn); unsigned char *RADEONMMIO = info->MMIO; - unsigned long agp_size, agp_base, mem_size; + unsigned long mem_size; /* Default to existing values */ info->mc_fb_location = INREG(RADEON_MC_FB_LOCATION); @@ -2360,8 +2311,6 @@ static void RADEONInitMemoryMap(ScrnInfoPtr pScrn) RADEONTRACE(("RADEONInitMemoryMap() : \n")); RADEONTRACE((" mem_size : 0x%08lx\n", mem_size)); - RADEONTRACE((" agp_size : 0x%08lx\n", agp_size)); - RADEONTRACE((" agp_base : 0x%08lx\n", agp_base)); RADEONTRACE((" MC_FB_LOCATION : 0x%08lx\n", info->mc_fb_location)); RADEONTRACE((" MC_AGP_LOCATION : 0x%08lx\n", info->mc_agp_location)); } @@ -2414,9 +2363,6 @@ static void RADEONGetVRamType(ScrnInfoPtr pScrn) static CARD32 RADEONGetAccessibleVRAM(ScrnInfoPtr pScrn) { RADEONInfoPtr info = RADEONPTR(pScrn); - EntityInfoPtr pEnt = info->pEnt; - GDevPtr dev = pEnt->device; - MessageType from; unsigned char *RADEONMMIO = info->MMIO; CARD32 aper_size = INREG(RADEON_CONFIG_APER_SIZE) / 1024; @@ -2428,7 +2374,7 @@ static CARD32 RADEONGetAccessibleVRAM(ScrnInfoPtr pScrn) if (info->directRenderingEnabled && info->pKernelDRMVersion->version_minor < 23) { xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "[dri] limiting video memory to one aperture of %dK\n", + "[dri] limiting video memory to one aperture of %ldK\n", aper_size); xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "[dri] detected radeon kernel module version 1.%d but" @@ -2519,8 +2465,8 @@ static Bool RADEONPreInitVRAM(ScrnInfoPtr pScrn) accessible = bar_size; xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Detected total video RAM=%dK, accessible=%dK " - "(PCI BAR=%dK)\n", + "Detected total video RAM=%dK, accessible=%ldK " + "(PCI BAR=%ldK)\n", pScrn->videoRam, accessible, bar_size); if (pScrn->videoRam > accessible) pScrn->videoRam = accessible; @@ -3011,8 +2957,9 @@ static Bool RADEONPreInitChipType(ScrnInfoPtr pScrn) "Option ShowCache enabled\n"); #ifdef RENDER - info->RenderAccel = xf86ReturnOptValBool (info->Options, - OPTION_RENDER_ACCEL, TRUE); + info->RenderAccel = xf86ReturnOptValBool(info->Options, OPTION_RENDER_ACCEL, + info->Chipset != PCI_CHIP_RN50_515E && + info->Chipset != PCI_CHIP_RN50_5969); #endif return TRUE; @@ -4355,10 +4302,13 @@ static Bool RADEONPreInitModes(ScrnInfoPtr pScrn, xf86Int10InfoPtr pInt10) /* Set DPI */ /* xf86SetDpi(pScrn, 0, 0); */ - if(info->MergedFB) + if (info->MergedFB) { RADEONMergedFBSetDpi(pScrn, info->CRT2pScrn, info->CRT2Position); - else + } else { xf86SetDpi(pScrn, 0, 0); + info->RADEONDPIVX = pScrn->virtualX; + info->RADEONDPIVY = pScrn->virtualY; + } /* Get ScreenInit function */ if (!xf86LoadSubModule(pScrn, "fb")) return FALSE; @@ -4393,6 +4343,8 @@ static Bool RADEONPreInitAccel(ScrnInfoPtr pScrn) char *optstr; #endif + info->useEXA = FALSE; + if (!xf86ReturnOptValBool(info->Options, OPTION_NOACCEL, FALSE)) { int errmaj = 0, errmin = 0; @@ -4418,7 +4370,7 @@ static Bool RADEONPreInitAccel(ScrnInfoPtr pScrn) #ifdef USE_EXA if (info->useEXA) { - info->exaReq.majorversion = 1; + info->exaReq.majorversion = 2; info->exaReq.minorversion = 0; if (!LoadSubModule(pScrn->module, "exa", NULL, NULL, NULL, @@ -4460,13 +4412,32 @@ static Bool RADEONPreInitAccel(ScrnInfoPtr pScrn) static Bool RADEONPreInitInt10(ScrnInfoPtr pScrn, xf86Int10InfoPtr *ppInt10) { +#if !defined(__powerpc__) RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + CARD32 fp2_gen_ctl_save = 0; -#if !defined(__powerpc__) if (xf86LoadSubModule(pScrn, "int10")) { xf86LoaderReqSymLists(int10Symbols, NULL); + + /* The VGA BIOS on the RV100/QY cannot be read when the digital output + * is enabled. Clear and restore FP2_ON around int10 to avoid this. + */ + if (info->PciInfo->chipType == PCI_CHIP_RV100_QY) { + fp2_gen_ctl_save = INREG(RADEON_FP2_GEN_CNTL); + if (fp2_gen_ctl_save & RADEON_FP2_ON) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "disabling digital out\n"); + OUTREG(RADEON_FP2_GEN_CNTL, fp2_gen_ctl_save & ~RADEON_FP2_ON); + } + } + xf86DrvMsg(pScrn->scrnIndex,X_INFO,"initializing int10\n"); *ppInt10 = xf86InitInt10(info->pEnt->index); + + if (fp2_gen_ctl_save & RADEON_FP2_ON) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "re-enabling digital out\n"); + OUTREG(RADEON_FP2_GEN_CNTL, fp2_gen_ctl_save); + } } #endif return TRUE; @@ -4497,6 +4468,26 @@ static Bool RADEONPreInitDRI(ScrnInfoPtr pScrn) if (info->IsSecondary) return FALSE; + if (info->Chipset == PCI_CHIP_RN50_515E || + info->Chipset == PCI_CHIP_RN50_5969) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Direct rendering not supported on RN50\n"); + return FALSE; + } + + if (info->Chipset == PCI_CHIP_RS400_5A41 || + info->Chipset == PCI_CHIP_RS400_5A42 || + info->Chipset == PCI_CHIP_RC410_5A61 || + info->Chipset == PCI_CHIP_RC410_5A62 || + info->Chipset == PCI_CHIP_RS480_5954 || + info->Chipset == PCI_CHIP_RS480_5955 || + info->Chipset == PCI_CHIP_RS482_5974 || + info->Chipset == PCI_CHIP_RS482_5975) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Direct rendering broken on XPRESS 200 and 200M\n"); + return FALSE; + } + if (xf86ReturnOptValBool(info->Options, OPTION_NOACCEL, FALSE)) { xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "[dri] Acceleration disabled, not initializing the DRI\n"); @@ -4671,15 +4662,12 @@ static void RADEONPreInitColorTiling(ScrnInfoPtr pScrn) { RADEONInfoPtr info = RADEONPTR(pScrn); + info->allowColorTiling = xf86ReturnOptValBool(info->Options, + OPTION_COLOR_TILING, TRUE); if (IS_R300_VARIANT) { - /* false by default on R3/4xx */ - info->allowColorTiling = xf86ReturnOptValBool(info->Options, - OPTION_COLOR_TILING, FALSE); info->MaxSurfaceWidth = 3968; /* one would have thought 4096...*/ info->MaxLines = 4096; } else { - info->allowColorTiling = xf86ReturnOptValBool(info->Options, - OPTION_COLOR_TILING, TRUE); info->MaxSurfaceWidth = 2048; info->MaxLines = 2048; } @@ -4816,7 +4804,7 @@ _X_EXPORT Bool RADEONPreInit(ScrnInfoPtr pScrn, int flags) const char *s; char* microc_path = NULL; char* microc_type = NULL; - + MessageType from; RADEONTRACE(("RADEONPreInit\n")); if (pScrn->numEntities != 1) return FALSE; @@ -4838,6 +4826,7 @@ _X_EXPORT Bool RADEONPreInit(ScrnInfoPtr pScrn, int flags) info->PciInfo->device, info->PciInfo->func); info->MMIOAddr = info->PciInfo->memBase[2] & 0xffffff00; + info->MMIOSize = (1 << info->PciInfo->size[2]); if (info->pEnt->device->IOBase) { xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "MMIO address override, using 0x%08lx instead of 0x%08lx\n", @@ -4849,7 +4838,7 @@ _X_EXPORT Bool RADEONPreInit(ScrnInfoPtr pScrn, int flags) goto fail1; } xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "MMIO registers at 0x%08lx\n", info->MMIOAddr); + "MMIO registers at 0x%08lx: size %ldKB\n", info->MMIOAddr, info->MMIOSize / 1024); if(!RADEONMapMMIO(pScrn)) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, @@ -5056,6 +5045,25 @@ _X_EXPORT Bool RADEONPreInit(ScrnInfoPtr pScrn, int flags) info->DispPriority = 1; } + info->constantDPI = -1; + from = X_DEFAULT; + if (xf86GetOptValBool(info->Options, OPTION_CONSTANTDPI, &info->constantDPI)) { + from = X_CONFIG; + } else { + if (monitorResolution > 0) { + info->constantDPI = TRUE; + from = X_CMDLINE; + xf86DrvMsg(pScrn->scrnIndex, from, + "\"-dpi %d\" given in command line, assuming \"ConstantDPI\" set\n", + monitorResolution); + } else { + info->constantDPI = FALSE; + } + } + xf86DrvMsg(pScrn->scrnIndex, from, + "X server will %skeep DPI constant for all screen sizes\n", + info->constantDPI ? "" : "not "); + if (xf86ReturnOptValBool(info->Options, OPTION_FBDEV, FALSE)) { /* check for Linux framebuffer device */ @@ -5337,6 +5345,7 @@ Bool RADEONSetupMemXAA_DRI(int scrnIndex, ScreenPtr pScreen) ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; RADEONInfoPtr info = RADEONPTR(pScrn); int cpp = info->CurrentLayout.pixel_bytes; + int depthCpp = (info->depthBits - 8) / 4; int width_bytes = pScrn->displayWidth * cpp; int bufferSize; int depthSize; @@ -5367,7 +5376,7 @@ Bool RADEONSetupMemXAA_DRI(int scrnIndex, ScreenPtr pScreen) */ info->depthPitch = (pScrn->displayWidth + 31) & ~31; depthSize = ((((pScrn->virtualY + 15) & ~15) * info->depthPitch - * cpp + RADEON_BUFFER_ALIGN) & ~RADEON_BUFFER_ALIGN); + * depthCpp + RADEON_BUFFER_ALIGN) & ~RADEON_BUFFER_ALIGN); switch (info->CPMode) { case RADEON_DEFAULT_CP_PIO_MODE: @@ -5581,7 +5590,7 @@ Bool RADEONSetupMemXAA_DRI(int scrnIndex, ScreenPtr pScreen) info->depthOffset); if (info->cardType==CARD_PCIE) xf86DrvMsg(scrnIndex, X_INFO, - "Will use %d kb for PCI GART table at offset 0x%x\n", + "Will use %d kb for PCI GART table at offset 0x%lx\n", info->pciGartSize/1024, info->pciGartOffset); xf86DrvMsg(scrnIndex, X_INFO, "Will use %d kb for textures at offset 0x%x\n", @@ -5593,7 +5602,7 @@ Bool RADEONSetupMemXAA_DRI(int scrnIndex, ScreenPtr pScreen) info->backPitchOffset = (((info->backPitch * cpp / 64) << 22) | ((info->backOffset + info->fbLocation) >> 10)); - info->depthPitchOffset = (((info->depthPitch * cpp / 64) << 22) | + info->depthPitchOffset = (((info->depthPitch * depthCpp / 64) << 22) | ((info->depthOffset + info->fbLocation) >> 10)); return TRUE; } @@ -5673,11 +5682,13 @@ _X_EXPORT Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen, char* s; #endif - RADEONTRACE(("RADEONScreenInit %x %d\n", + RADEONTRACE(("RADEONScreenInit %lx %ld\n", pScrn->memPhysBase, pScrn->fbOffset)); info->accelOn = FALSE; +#ifdef USE_XAA info->accel = NULL; +#endif pScrn->fbOffset = 0; if (info->IsSecondary) pScrn->fbOffset = pScrn->videoRam * 1024; if (!RADEONMapMem(pScrn)) return FALSE; @@ -5699,6 +5710,9 @@ _X_EXPORT Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen, } } + if ((!info->IsSecondary) && (IS_R300_VARIANT || IS_RV100_VARIANT)) + RADEONForceSomeClocks(pScrn); + if (info->allowColorTiling && (pScrn->virtualX > info->MaxSurfaceWidth)) { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Color tiling not supported with virtual x resolutions larger than %d, disabling\n", @@ -5728,6 +5742,26 @@ _X_EXPORT Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen, miSetPixmapDepths (); #ifdef XF86DRI + if (info->directRenderingEnabled) { + MessageType from; + + info->depthBits = pScrn->depth; + + from = xf86GetOptValInteger(info->Options, OPTION_DEPTH_BITS, + &info->depthBits) + ? X_CONFIG : X_DEFAULT; + + if (info->depthBits != 16 && info->depthBits != 24) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Value for Option \"DepthBits\" must be 16 or 24\n"); + info->depthBits = pScrn->depth; + from = X_DEFAULT; + } + + xf86DrvMsg(pScrn->scrnIndex, from, + "Using %d bit depth buffer\n", info->depthBits); + } + /* Setup DRI after visuals have been established, but before fbScreenInit is * called. fbScreenInit will eventually call the driver's InitGLXVisuals * call back. */ @@ -5891,21 +5925,36 @@ _X_EXPORT Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen, #ifdef USE_EXA if (info->useEXA) { #ifdef XF86DRI - /* Reserve approx. half of offscreen memory for local textures by - * default, can be overridden with Option "FBTexPercent". - * Round down to a whole number of texture regions. - */ - info->textureSize = 50; + MessageType from = X_DEFAULT; - if (xf86GetOptValInteger(info->Options, OPTION_FBTEX_PERCENT, - &(info->textureSize))) { - if (info->textureSize < 0 || info->textureSize > 100) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Illegal texture memory percentage: %dx, setting to default 50%\n", - info->textureSize); - info->textureSize = 50; + if (hasDRI) { + info->accelDFS = info->cardType != CARD_AGP; + + if (xf86GetOptValInteger(info->Options, OPTION_ACCEL_DFS, + &info->accelDFS)) { + from = X_CONFIG; + } + + /* Reserve approx. half of offscreen memory for local textures by + * default, can be overridden with Option "FBTexPercent". + * Round down to a whole number of texture regions. + */ + info->textureSize = 50; + + if (xf86GetOptValInteger(info->Options, OPTION_FBTEX_PERCENT, + &(info->textureSize))) { + if (info->textureSize < 0 || info->textureSize > 100) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Illegal texture memory percentage: %dx, setting to default 50%%\n", + info->textureSize); + info->textureSize = 50; + } } } + + xf86DrvMsg(pScrn->scrnIndex, from, + "%ssing accelerated EXA DownloadFromScreen hook\n", + info->accelDFS ? "U" : "Not u"); #endif /* XF86DRI */ if (!RADEONSetupMemEXA(pScreen)) @@ -6127,7 +6176,7 @@ static void RADEONRestoreMemMapRegisters(ScrnInfoPtr pScrn, { RADEONInfoPtr info = RADEONPTR(pScrn); unsigned char *RADEONMMIO = info->MMIO; - int i, timeout; + int timeout; RADEONTRACE(("RADEONRestoreMemMapRegisters() : \n")); RADEONTRACE((" MC_FB_LOCATION : 0x%08lx\n", restore->mc_fb_location)); @@ -6191,8 +6240,8 @@ static void RADEONRestoreMemMapRegisters(ScrnInfoPtr pScrn, xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Timeout trying to update memory controller settings !\n"); xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "MC_STATUS = 0x%08x (on entry = 0x%08x)\n", - INREG(RADEON_MC_STATUS), old_mc_status); + "MC_STATUS = 0x%08x (on entry = 0x%08x)\n", + INREG(RADEON_MC_STATUS), (unsigned int)old_mc_status); xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "You will probably crash now ... \n"); /* Nothing we can do except maybe try to kill the server, @@ -6266,6 +6315,7 @@ static void RADEONRestoreMemMapRegisters(ScrnInfoPtr pScrn, RADEONTRACE(("Memory map updated.\n")); } +#ifdef XF86DRI static void RADEONAdjustMemMapRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save) { RADEONInfoPtr info = RADEONPTR(pScrn); @@ -6300,7 +6350,30 @@ static void RADEONAdjustMemMapRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save) if (fb_loc_changed) RADEONRestoreMemMapRegisters(pScrn, save); } + +#ifdef USE_EXA + if (info->accelDFS) + { + drmRadeonGetParam gp; + int gart_base; + + memset(&gp, 0, sizeof(gp)); + gp.param = RADEON_PARAM_GART_BASE; + gp.value = &gart_base; + + if (drmCommandWriteRead(info->drmFD, DRM_RADEON_GETPARAM, &gp, + sizeof(gp)) < 0) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Failed to determine GART area MC location, not using " + "accelerated DownloadFromScreen hook!\n"); + info->accelDFS = FALSE; + } else { + info->gartLocation = gart_base; + } + } +#endif /* USE_EXA */ } +#endif /* Write common registers */ static void RADEONRestoreCommonRegisters(ScrnInfoPtr pScrn, @@ -6373,7 +6446,7 @@ static void RADEONRestoreCrtcRegisters(ScrnInfoPtr pScrn, RADEONInfoPtr info = RADEONPTR(pScrn); unsigned char *RADEONMMIO = info->MMIO; - RADEONTRACE(("Programming CRTC1, offset: 0x%08x\n", + RADEONTRACE(("Programming CRTC1, offset: 0x%08lx\n", restore->crtc_offset)); /* We prevent the CRTC from hitting the memory controller until @@ -6421,7 +6494,7 @@ static void RADEONRestoreCrtc2Registers(ScrnInfoPtr pScrn, unsigned char *RADEONMMIO = info->MMIO; CARD32 crtc2_gen_cntl; - RADEONTRACE(("Programming CRTC2, offset: 0x%08x\n", + RADEONTRACE(("Programming CRTC2, offset: 0x%08lx\n", restore->crtc2_offset)); crtc2_gen_cntl = INREG(RADEON_CRTC2_GEN_CNTL) & @@ -6666,7 +6739,7 @@ static void RADEONRestorePLLRegisters(ScrnInfoPtr pScrn, | RADEON_PPLL_ATOMIC_UPDATE_EN | RADEON_PPLL_VGA_ATOMIC_UPDATE_EN)); - RADEONTRACE(("Wrote: 0x%08x 0x%08x 0x%08x (0x%08x)\n", + RADEONTRACE(("Wrote: 0x%08x 0x%08x 0x%08lx (0x%08x)\n", restore->ppll_ref_div, restore->ppll_div_3, restore->htotal_cntl, @@ -6725,12 +6798,12 @@ static void RADEONRestorePLL2Registers(ScrnInfoPtr pScrn, | RADEON_P2PLL_ATOMIC_UPDATE_EN | RADEON_P2PLL_VGA_ATOMIC_UPDATE_EN)); - RADEONTRACE(("Wrote: 0x%08x 0x%08x 0x%08x (0x%08x)\n", + RADEONTRACE(("Wrote: 0x%08lx 0x%08lx 0x%08lx (0x%08x)\n", restore->p2pll_ref_div, restore->p2pll_div_0, restore->htotal_cntl2, INPLL(pScrn, RADEON_P2PLL_CNTL))); - RADEONTRACE(("Wrote: rd=%d, fd=%d, pd=%d\n", + RADEONTRACE(("Wrote: rd=%ld, fd=%ld, pd=%ld\n", restore->p2pll_ref_div & RADEON_P2PLL_REF_DIV_MASK, restore->p2pll_div_0 & RADEON_P2PLL_FB0_DIV_MASK, (restore->p2pll_div_0 & RADEON_P2PLL_POST0_DIV_MASK) >>16)); @@ -6787,7 +6860,7 @@ void RADEONChangeSurfaces(ScrnInfoPtr pScrn) int width_bytes = pScrn->displayWidth * cpp; int bufferSize = ((((pScrn->virtualY + 15) & ~15) * width_bytes + RADEON_BUFFER_ALIGN) & ~RADEON_BUFFER_ALIGN); - unsigned int depth_pattern, color_pattern, swap_pattern; + unsigned int color_pattern, swap_pattern; if (!info->allowColorTiling) return; @@ -6806,28 +6879,21 @@ void RADEONChangeSurfaces(ScrnInfoPtr pScrn) #endif if (info->ChipFamily < CHIP_FAMILY_R200) { color_pattern = RADEON_SURF_TILE_COLOR_MACRO; - if (cpp == 2) - depth_pattern = RADEON_SURF_TILE_DEPTH_16BPP; - else - depth_pattern = RADEON_SURF_TILE_DEPTH_32BPP; } else if (IS_R300_VARIANT) { color_pattern = R300_SURF_TILE_COLOR_MACRO; - if (cpp == 2) - depth_pattern = R300_SURF_TILE_COLOR_MACRO; - else - depth_pattern = R300_SURF_TILE_COLOR_MACRO | R300_SURF_TILE_DEPTH_32BPP; } else { color_pattern = R200_SURF_TILE_COLOR_MACRO; - if (cpp == 2) - depth_pattern = R200_SURF_TILE_DEPTH_16BPP; - else - depth_pattern = R200_SURF_TILE_DEPTH_32BPP; } #ifdef XF86DRI if (info->directRenderingInited) { drmRadeonSurfaceFree drmsurffree; drmRadeonSurfaceAlloc drmsurfalloc; int retvalue; + int depthCpp = (info->depthBits - 8) / 4; + int depth_width_bytes = pScrn->displayWidth * depthCpp; + int depthBufferSize = ((((pScrn->virtualY + 15) & ~15) * depth_width_bytes + + RADEON_BUFFER_ALIGN) & ~RADEON_BUFFER_ALIGN); + unsigned int depth_pattern; drmsurffree.address = info->frontOffset; retvalue = drmCommandWrite(info->drmFD, DRM_RADEON_SURF_FREE, @@ -6872,17 +6938,34 @@ void RADEONChangeSurfaces(ScrnInfoPtr pScrn) "drm: could not allocate surface for back buffer!\n"); } + if (info->ChipFamily < CHIP_FAMILY_R200) { + if (depthCpp == 2) + depth_pattern = RADEON_SURF_TILE_DEPTH_16BPP; + else + depth_pattern = RADEON_SURF_TILE_DEPTH_32BPP; + } else if (IS_R300_VARIANT) { + if (depthCpp == 2) + depth_pattern = R300_SURF_TILE_COLOR_MACRO; + else + depth_pattern = R300_SURF_TILE_COLOR_MACRO | R300_SURF_TILE_DEPTH_32BPP; + } else { + if (depthCpp == 2) + depth_pattern = R200_SURF_TILE_DEPTH_16BPP; + else + depth_pattern = R200_SURF_TILE_DEPTH_32BPP; + } + /* rv100 and probably the derivative igps don't have depth tiling on all the time? */ if (info->have3DWindows && ((info->ChipFamily != CHIP_FAMILY_RV100) || (info->ChipFamily != CHIP_FAMILY_RS100) || (info->ChipFamily != CHIP_FAMILY_RS200))) { drmRadeonSurfaceAlloc drmsurfalloc; - drmsurfalloc.size = bufferSize; + drmsurfalloc.size = depthBufferSize; drmsurfalloc.address = info->depthOffset; if (IS_R300_VARIANT) - drmsurfalloc.flags = swap_pattern | (width_bytes / 8) | depth_pattern; + drmsurfalloc.flags = swap_pattern | (depth_width_bytes / 8) | depth_pattern; else - drmsurfalloc.flags = swap_pattern | (width_bytes / 16) | depth_pattern; + drmsurfalloc.flags = swap_pattern | (depth_width_bytes / 16) | depth_pattern; retvalue = drmCommandWrite(info->drmFD, DRM_RADEON_SURF_ALLOC, &drmsurfalloc, sizeof(drmsurfalloc)); if (retvalue < 0) @@ -7163,7 +7246,7 @@ static void RADEONSavePLLRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save) save->ppll_div_3 = INPLL(pScrn, RADEON_PPLL_DIV_3); save->htotal_cntl = INPLL(pScrn, RADEON_HTOTAL_CNTL); - RADEONTRACE(("Read: 0x%08x 0x%08x 0x%08x\n", + RADEONTRACE(("Read: 0x%08x 0x%08x 0x%08lx\n", save->ppll_ref_div, save->ppll_div_3, save->htotal_cntl)); @@ -7180,11 +7263,11 @@ static void RADEONSavePLL2Registers(ScrnInfoPtr pScrn, RADEONSavePtr save) save->p2pll_div_0 = INPLL(pScrn, RADEON_P2PLL_DIV_0); save->htotal_cntl2 = INPLL(pScrn, RADEON_HTOTAL2_CNTL); - RADEONTRACE(("Read: 0x%08x 0x%08x 0x%08x\n", + RADEONTRACE(("Read: 0x%08lx 0x%08lx 0x%08lx\n", save->p2pll_ref_div, save->p2pll_div_0, save->htotal_cntl2)); - RADEONTRACE(("Read: rd=%d, fd=%d, pd=%d\n", + RADEONTRACE(("Read: rd=%ld, fd=%ld, pd=%ld\n", save->p2pll_ref_div & RADEON_P2PLL_REF_DIV_MASK, save->p2pll_div_0 & RADEON_P2PLL_FB0_DIV_MASK, (save->p2pll_div_0 & RADEON_P2PLL_POST0_DIV_MASK) >> 16)); @@ -7632,15 +7715,7 @@ static void RADEONInitDispBandwidth(ScrnInfoPtr pScrn) if (critical_point < temp) critical_point = temp; */ if (info->DispPriority == 2) { - if (mode2) { - /*??some R300 cards have problem with this set to 0, when CRTC2 is enabled.*/ - if (info->ChipFamily == CHIP_FAMILY_R300) - critical_point += 0x10; - else - critical_point = 0; - } - else - critical_point = 0; + critical_point = 0; } /* @@ -7649,6 +7724,11 @@ static void RADEONInitDispBandwidth(ScrnInfoPtr pScrn) */ if (max_stop_req - critical_point < 4) critical_point = 0; + if (critical_point == 0 && mode2 && info->ChipFamily == CHIP_FAMILY_R300) { + /* some R300 cards have problem with this set to 0, when CRTC2 is enabled.*/ + critical_point = 0x10; + } + temp = info->SavedReg.grph_buffer_cntl; temp &= ~(RADEON_GRPH_STOP_REQ_MASK); temp |= (stop_req << RADEON_GRPH_STOP_REQ_SHIFT); @@ -7670,7 +7750,7 @@ static void RADEONInitDispBandwidth(ScrnInfoPtr pScrn) (critical_point << RADEON_GRPH_CRITICAL_POINT_SHIFT))); RADEONTRACE(("GRPH_BUFFER_CNTL from %x to %x\n", - info->SavedReg.grph_buffer_cntl, INREG(RADEON_GRPH_BUFFER_CNTL))); + (unsigned int)info->SavedReg.grph_buffer_cntl, INREG(RADEON_GRPH_BUFFER_CNTL))); if (mode2) { stop_req = mode2->HDisplay * info2->CurrentLayout.pixel_bytes / 16; @@ -7702,21 +7782,23 @@ static void RADEONInitDispBandwidth(ScrnInfoPtr pScrn) disp_latency) * disp_drain_rate2 + 0.5); if (info->DispPriority == 2) { - if (info->ChipFamily == CHIP_FAMILY_R300) - critical_point2 += 0x10; - else - critical_point2 = 0; + critical_point2 = 0; } if (max_stop_req - critical_point2 < 4) critical_point2 = 0; } + if (critical_point2 == 0 && info->ChipFamily == CHIP_FAMILY_R300) { + /* some R300 cards have problem with this set to 0 */ + critical_point2 = 0x10; + } + OUTREG(RADEON_GRPH2_BUFFER_CNTL, ((temp & ~RADEON_GRPH_CRITICAL_POINT_MASK) | (critical_point2 << RADEON_GRPH_CRITICAL_POINT_SHIFT))); RADEONTRACE(("GRPH2_BUFFER_CNTL from %x to %x\n", - info->SavedReg.grph2_buffer_cntl, INREG(RADEON_GRPH2_BUFFER_CNTL))); + (unsigned int)info->SavedReg.grph2_buffer_cntl, INREG(RADEON_GRPH2_BUFFER_CNTL))); } } @@ -7908,7 +7990,7 @@ static Bool RADEONInitCrtcRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save, save->tv_dac_cntl |= (0x03 | (2<<8) | (0x58<<16)); } - RADEONTRACE(("Pitch = %d bytes (virtualX = %d, displayWidth = %d)\n", + RADEONTRACE(("Pitch = %ld bytes (virtualX = %d, displayWidth = %d)\n", save->crtc_pitch, pScrn->virtualX, info->CurrentLayout.displayWidth)); return TRUE; @@ -8113,7 +8195,7 @@ static Bool RADEONInitCrtc2Registers(ScrnInfoPtr pScrn, RADEONSavePtr save, } #endif - RADEONTRACE(("Pitch = %d bytes (virtualX = %d, displayWidth = %d)\n", + RADEONTRACE(("Pitch = %ld bytes (virtualX = %d, displayWidth = %d)\n", save->crtc2_pitch, pScrn->virtualX, info->CurrentLayout.displayWidth)); @@ -8286,7 +8368,7 @@ static void RADEONInitFPRegisters(ScrnInfoPtr pScrn, RADEONSavePtr orig, save->tmds_pll_cntl = (orig->tmds_pll_cntl & 0xfff00000) | tmp; } else save->tmds_pll_cntl = tmp; - RADEONTRACE(("TMDS_PLL from %x to %x\n", + RADEONTRACE(("TMDS_PLL from %lx to %lx\n", orig->tmds_pll_cntl, save->tmds_pll_cntl)); @@ -8418,7 +8500,7 @@ static void RADEONInitPLLRegisters(ScrnInfoPtr pScrn, RADEONInfoPtr info, pll->reference_freq); save->post_div = post_div->divider; - RADEONTRACE(("dc=%d, of=%d, fd=%d, pd=%d\n", + RADEONTRACE(("dc=%ld, of=%ld, fd=%d, pd=%d\n", save->dot_clock_freq, save->pll_output_freq, save->feedback_div, @@ -8480,7 +8562,7 @@ static void RADEONInitPLL2Registers(ScrnInfoPtr pScrn, RADEONSavePtr save, pll->reference_freq); save->post_div_2 = post_div->divider; - RADEONTRACE(("dc=%d, of=%d, fd=%d, pd=%d\n", + RADEONTRACE(("dc=%ld, of=%ld, fd=%d, pd=%d\n", save->dot_clock_freq_2, save->pll_output_freq_2, save->feedback_div_2, @@ -8657,6 +8739,26 @@ static Bool RADEONSaveScreen(ScreenPtr pScreen, int mode) return TRUE; } +static void +RADEONResetDPI(ScrnInfoPtr pScrn, Bool force) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + ScreenPtr pScreen = screenInfo.screens[pScrn->scrnIndex]; + + if(force || + (info->RADEONDPIVX != pScrn->virtualX) || + (info->RADEONDPIVY != pScrn->virtualY) + ) { + + pScreen->mmWidth = (pScrn->virtualX * 254 + pScrn->xDpi * 5) / (pScrn->xDpi * 10); + pScreen->mmHeight = (pScrn->virtualY * 254 + pScrn->yDpi * 5) / (pScrn->yDpi * 10); + + info->RADEONDPIVX = pScrn->virtualX; + info->RADEONDPIVY = pScrn->virtualY; + + } +} + _X_EXPORT Bool RADEONSwitchMode(int scrnIndex, DisplayModePtr mode, int flags) { ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; @@ -8741,8 +8843,11 @@ _X_EXPORT Bool RADEONSwitchMode(int scrnIndex, DisplayModePtr mode, int flags) /* Since RandR (indirectly) uses SwitchMode(), we need to * update our Xinerama info here, too, in case of resizing */ - if(info->MergedFB) { - RADEONUpdateXineramaScreenInfo(pScrn); + if (info->MergedFB) { + RADEONMergedFBResetDpi(pScrn, FALSE); + RADEONUpdateXineramaScreenInfo(pScrn); + } else if(info->constantDPI) { + RADEONResetDPI(pScrn, FALSE); } return ret; @@ -8781,7 +8886,7 @@ void RADEONDoAdjustFrame(ScrnInfoPtr pScrn, int x, int y, int clone) { RADEONInfoPtr info = RADEONPTR(pScrn); unsigned char *RADEONMMIO = info->MMIO; - int reg, Base, regcntl, crtcoffsetcntl, xytilereg, crtcxytile; + int reg, Base, regcntl, crtcoffsetcntl, xytilereg, crtcxytile = 0; #ifdef XF86DRI RADEONSAREAPrivPtr pSAREAPriv; XF86DRISAREAPtr pSAREA; @@ -9060,8 +9165,11 @@ static Bool RADEONCloseScreen(int scrnIndex, ScreenPtr pScreen) RADEONTRACE(("Disposing accel...\n")); #ifdef USE_EXA - if (info->useEXA && info->accelOn) + if (info->exa) { exaDriverFini(pScreen); + xfree(info->exa); + info->exa = NULL; + } #endif /* USE_EXA */ #ifdef USE_XAA if (!info->useEXA) { @@ -9620,6 +9728,16 @@ RADEONGetMergedFBOptions(ScrnInfoPtr pScrn) } } +static void RADEONForceSomeClocks(ScrnInfoPtr pScrn) +{ + /* It appears from r300 and rv100 may need some clocks forced-on */ + CARD32 tmp; + + tmp = INPLL(pScrn, RADEON_SCLK_CNTL); + tmp |= RADEON_SCLK_FORCE_CP | RADEON_SCLK_FORCE_VIP; + OUTPLL(pScrn, RADEON_SCLK_CNTL, tmp); +} + static void RADEONSetDynamicClock(ScrnInfoPtr pScrn, int mode) { RADEONInfoPtr info = RADEONPTR(pScrn); |