diff options
-rw-r--r-- | ChangeLog | 35 | ||||
-rw-r--r-- | src/radeon.h | 21 | ||||
-rw-r--r-- | src/radeon_common.h | 3 | ||||
-rw-r--r-- | src/radeon_commonfuncs.c | 2 | ||||
-rw-r--r-- | src/radeon_cursor.c | 48 | ||||
-rw-r--r-- | src/radeon_dri.c | 17 | ||||
-rw-r--r-- | src/radeon_driver.c | 778 | ||||
-rw-r--r-- | src/radeon_reg.h | 1 | ||||
-rw-r--r-- | src/radeon_render.c | 16 |
9 files changed, 624 insertions, 297 deletions
@@ -1,3 +1,38 @@ +2006-02-17 Benjamin Herrenschmidt <benh@kernel.crashing.org> + + * src/radeon.h: + * src/radeon_common.h: + * src/radeon_commonfuncs.c: (RADEONWaitForIdle): + * src/radeon_cursor.c: (RADEONCursorAllocEXA), + (RADEONSetCursorColors), (RADEONSetCursorPosition), + (RADEONLoadCursorImage), (RADEONHideCursor), (RADEONShowCursor), + (RADEONLoadCursorARGB), (RADEONCursorInit): + * src/radeon_dri.c: (RADEONDRIScreenInit), + (RADEONDRIFinishScreenInit), (RADEONDRICloseScreen), + (RADEONDRIRefreshArea): + * src/radeon_driver.c: (RADEONMapFB), (RADEONInitMemMapRegisters), + (RADEONInitMemoryMap), (RADEONGetAccessibleVRAM), + (RADEONPreInitConfig), (RADEONLoadPalette), (RADEONBlockHandler), + (RADEONScreenInit), (RADEONRestoreMemMapRegisters), + (RADEONAdjustMemMapRegisters), (RADEONRestoreSurfaces), + (RADEONSaveSurfaces), (RADEONChangeSurfaces), (RADEONRestoreMode), + (RADEONSaveMemMapRegisters), (RADEONSaveMode), (RADEONSave), + (RADEONInitDispBandwidth), (RADEONInitPLLRegisters), + (RADEONInitPLL2Registers), (RADEONInit), (RADEONModeInit), + (RADEONSaveScreen), (RADEONSwitchMode), (RADEONDoAdjustFrame), + (RADEONAdjustFrame), (RADEONEnterVT), (RADEONLeaveVT), + (RADEONCloseScreen), (RADEONDisplayPowerManagementSet): + * src/radeon_reg.h: + * src/radeon_render.c: (RADEONSetupRenderByteswap): + Memory map and misc fixes. This completely reworks the way the driver + detects available & accessible video memory and initializes the card + internal memory map. Along the way, I re-ordered some of the stuffs + in pre-init in order to remove some dodgy codepath, fixed various + init, exit and vt switch issues, and overall made the driver more + robust. The full memory map fix requires an updated DRM. The X driver + no longer tries to position the AGP aperture, this becomes entirely + DRM responsibility. + 2006-02-16 Benjamin Herrenschmidt <benh@kernel.crashing.org> * src/radeon_accel.c: (RADEONEngineRestore): diff --git a/src/radeon.h b/src/radeon.h index 57db4e9..fb70444 100644 --- a/src/radeon.h +++ b/src/radeon.h @@ -102,7 +102,7 @@ typedef struct _region { /* ------------------------------------- */ -#define RADEON_DEBUG 0 /* Turn off debugging output */ +#define RADEON_DEBUG 1 /* Turn off debugging output */ #define RADEON_IDLE_RETRY 16 /* Fall out of idle loops after this count */ #define RADEON_TIMEOUT 2000000 /* Fall out of wait loops after this count */ #define RADEON_MMIOSIZE 0x80000 @@ -116,13 +116,13 @@ typedef struct _region { */ #if RADEON_DEBUG -#define RADEONTRACE(x) \ +#define RADEONTRACE(x) \ do { \ ErrorF("(**) %s(%d): ", RADEON_NAME, pScrn->scrnIndex); \ ErrorF x; \ -} while (0); +} while(0) #else -#define RADEONTRACE(x) +#define RADEONTRACE(x) do { } while(0) #endif @@ -147,10 +147,16 @@ typedef struct { CARD32 cap0_trig_cntl; CARD32 cap1_trig_cntl; CARD32 bus_cntl; - CARD32 surface_cntl; CARD32 bios_4_scratch; CARD32 bios_5_scratch; CARD32 bios_6_scratch; + CARD32 surface_cntl; + CARD32 surfaces[8][3]; + CARD32 mc_agp_location; + CARD32 mc_fb_location; + CARD32 display_base_addr; + CARD32 display2_base_addr; + CARD32 ov0_base_addr; /* Other registers to save for VT switches */ CARD32 dp_datatype; @@ -158,8 +164,6 @@ typedef struct { CARD32 clock_cntl_index; CARD32 amcgpio_en_reg; CARD32 amcgpio_mask; - - CARD32 surfaces[8][3]; /* CRTC registers */ CARD32 crtc_gen_cntl; @@ -326,6 +330,8 @@ typedef struct { unsigned long MMIOAddr; /* MMIO region physical address */ unsigned long BIOSAddr; /* BIOS physical address */ unsigned int fbLocation; + CARD32 mc_fb_location; + CARD32 mc_agp_location; unsigned char *MMIO; /* Map of MMIO region */ unsigned char *FB; /* Map of frame buffer */ @@ -482,6 +488,7 @@ typedef struct { #ifdef XF86DRI Bool noBackBuffer; Bool directRenderingEnabled; + Bool directRenderingInited; DRIInfoPtr pDRIInfo; int drmFD; int numVisualConfigs; diff --git a/src/radeon_common.h b/src/radeon_common.h index a6d99c8..74ce50e 100644 --- a/src/radeon_common.h +++ b/src/radeon_common.h @@ -31,7 +31,7 @@ * Converted to common header format: * Jens Owen <jens@tungstengraphics.com> * - * $XdotOrg: xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_common.h,v 1.5 2005/01/26 18:23:40 sroland Exp $ + * $XdotOrg: driver/xf86-video-ati/src/radeon_common.h,v 1.7 2005/09/11 08:51:38 airlied Exp $ * $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_common.h,v 1.8tsi Exp $ * */ @@ -474,6 +474,7 @@ typedef struct drm_radeon_set_param { #define RADEON_SETPARAM_FB_LOCATION 1 #define RADEON_SETPARAM_SWITCH_TILING 2 #define RADEON_SETPARAM_PCIGART_LOCATION 3 +#define RADEON_SETPARAM_NEW_MEMMAP 4 /* 1.14: Clients can allocate/free a surface */ diff --git a/src/radeon_commonfuncs.c b/src/radeon_commonfuncs.c index a71bf3a..7b72004 100644 --- a/src/radeon_commonfuncs.c +++ b/src/radeon_commonfuncs.c @@ -155,9 +155,11 @@ void FUNC_NAME(RADEONWaitForIdle)(ScrnInfoPtr pScrn) } #endif +#if 0 RADEONTRACE(("WaitForIdle (entering): %d entries, stat=0x%08x\n", INREG(RADEON_RBBM_STATUS) & RADEON_RBBM_FIFOCNT_MASK, INREG(RADEON_RBBM_STATUS))); +#endif /* Wait for the engine to go idle */ RADEONWaitForFifoFunction(pScrn, 64); diff --git a/src/radeon_cursor.c b/src/radeon_cursor.c index 67ec552..3c748a8 100644 --- a/src/radeon_cursor.c +++ b/src/radeon_cursor.c @@ -31,6 +31,9 @@ #include "config.h" #endif +#define RADEONCTRACE(x) +/* #define RADEONCTRACE(x) RADEONTRACE(x) */ + /* * Authors: * Kevin E. Martin <martin@xfree86.org> @@ -50,6 +53,7 @@ /* Driver data structures */ #include "radeon.h" +#include "radeon_version.h" #include "radeon_reg.h" #include "radeon_macros.h" #include "radeon_mergedfb.h" @@ -81,11 +85,11 @@ static CARD32 mono_cursor_color[] = { #define CURSOR_SWAPPING_DECL_MMIO unsigned char *RADEONMMIO = info->MMIO; #define CURSOR_SWAPPING_START() \ do { \ + COMMON_CURSOR_SWAPPING_START(); \ OUTREG(RADEON_SURFACE_CNTL, \ (info->ModeReg.surface_cntl | \ - RADEON_NONSURF_AP0_SWP_32BPP) & \ - ~RADEON_NONSURF_AP0_SWP_16BPP); \ - COMMON_CURSOR_SWAPPING_START(); \ + RADEON_NONSURF_AP0_SWP_32BPP | RADEON_NONSURF_AP1_SWP_32BPP) & \ + ~(RADEON_NONSURF_AP0_SWP_16BPP | RADEON_NONSURF_AP1_SWP_16BPP)); \ } while (0) #define CURSOR_SWAPPING_END() (OUTREG(RADEON_SURFACE_CNTL, \ info->ModeReg.surface_cntl)) @@ -133,9 +137,9 @@ RADEONCursorAllocEXA(ScreenPtr pScreen) "Using hardware cursor\n", info->cursor_offset = info->cursorArea->offset); - RADEONTRACE(("%s (0x%08x-0x%08x)\n", __func__, - info->cursor_offset, - info->cursor_offset + info->cursorArea->size)); + RADEONCTRACE(("%s (0x%08x-0x%08x)\n", __func__, + info->cursor_offset, + info->cursor_offset + info->cursorArea->size)); } } #endif @@ -149,6 +153,11 @@ static void RADEONSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg) int pixel, i; CURSOR_SWAPPING_DECL_MMIO + RADEONCTRACE(("RADEONSetCursorColors\n")); + + if (info->cursor_offset == 0) + return; + #ifdef ARGB_CURSOR /* Don't recolour cursors set with SetCursorARGB. */ if (info->cursor_argb) @@ -191,11 +200,17 @@ static void RADEONSetCursorPosition(ScrnInfoPtr pScrn, int x, int y) int total_y = pScrn->frameY1 - pScrn->frameY0; int stride = 256; + if (info->cursor_offset == 0) + return; + if(info->MergedFB) { + RADEONCTRACE(("RADEONSetCursorPositionMerged\n")); RADEONSetCursorPositionMerged(pScrn, x, y); return; } + RADEONCTRACE(("RADEONSetCursorPosition\n")); + if (x < 0) xorigin = -x+1; if (y < 0) yorigin = -y+1; if (y > total_y) y = total_y; @@ -210,6 +225,8 @@ static void RADEONSetCursorPosition(ScrnInfoPtr pScrn, int x, int y) OUTREG(RADEON_CUR_HORZ_VERT_POSN, (RADEON_CUR_LOCK | ((xorigin ? 0 : x) << 16) | (yorigin ? 0 : y))); + RADEONCTRACE(("cursor_offset: 0x%x, yorigin: %d, stride: %d\n", + info->cursor_offset, yorigin, stride)); OUTREG(RADEON_CUR_OFFSET, info->cursor_offset + yorigin * stride); } else { OUTREG(RADEON_CUR2_HORZ_VERT_OFF, (RADEON_CUR2_LOCK @@ -238,6 +255,11 @@ static void RADEONLoadCursorImage(ScrnInfoPtr pScrn, unsigned char *image) CARD8 chunk; CARD32 i, j; + if (info->cursor_offset == 0) + return; + + RADEONCTRACE(("RADEONLoadCursorImage (at %x)\n", info->cursor_offset)); + if (!info->IsSecondary) { save1 = INREG(RADEON_CRTC_GEN_CNTL) & ~(CARD32) (3 << 20); save1 |= (CARD32) (2 << 20); @@ -264,7 +286,7 @@ static void RADEONLoadCursorImage(ScrnInfoPtr pScrn, unsigned char *image) */ CURSOR_SWAPPING_START(); #define ARGB_PER_CHUNK (8 * sizeof (chunk) / 2) - for (i = 0; i < CURSOR_WIDTH * CURSOR_HEIGHT / ARGB_PER_CHUNK; i++) { + for (i = 0; i < (CURSOR_WIDTH * CURSOR_HEIGHT / ARGB_PER_CHUNK); i++) { chunk = *s++; for (j = 0; j < ARGB_PER_CHUNK; j++, chunk >>= 2) *d++ = mono_cursor_color[chunk & 3]; @@ -288,6 +310,8 @@ static void RADEONHideCursor(ScrnInfoPtr pScrn) RADEONInfoPtr info = RADEONPTR(pScrn); unsigned char *RADEONMMIO = info->MMIO; + RADEONCTRACE(("RADEONHideCursor\n")); + if (info->IsSecondary || info->MergedFB) OUTREGP(RADEON_CRTC2_GEN_CNTL, 0, ~RADEON_CRTC2_CUR_EN); @@ -301,6 +325,8 @@ static void RADEONShowCursor(ScrnInfoPtr pScrn) RADEONInfoPtr info = RADEONPTR(pScrn); unsigned char *RADEONMMIO = info->MMIO; + RADEONCTRACE(("RADEONShowCursor\n")); + if (info->IsSecondary || info->MergedFB) OUTREGP(RADEON_CRTC2_GEN_CNTL, RADEON_CRTC2_CUR_EN, ~RADEON_CRTC2_CUR_EN); @@ -351,8 +377,10 @@ static void RADEONLoadCursorARGB (ScrnInfoPtr pScrn, CursorPtr pCurs) CARD32 *image = pCurs->bits->argb; CARD32 *i; - if (!image) - return; /* XXX can't happen */ + RADEONCTRACE(("RADEONLoadCursorARGB\n")); + + if (info->cursor_offset == 0) + return; if (!info->IsSecondary) { save1 = INREG(RADEON_CRTC_GEN_CNTL) & ~(CARD32) (3 << 20); @@ -473,7 +501,7 @@ Bool RADEONCursorInit(ScreenPtr pScreen) 256); info->cursor_end = info->cursor_offset + size_bytes; } - RADEONTRACE(("RADEONCursorInit (0x%08x-0x%08x)\n", + RADEONCTRACE(("RADEONCursorInit (0x%08x-0x%08x)\n", info->cursor_offset, info->cursor_end)); } #endif diff --git a/src/radeon_dri.c b/src/radeon_dri.c index 6ff0839..755635d 100644 --- a/src/radeon_dri.c +++ b/src/radeon_dri.c @@ -1456,10 +1456,6 @@ Bool RADEONDRIScreenInit(ScreenPtr pScreen) version->version_patchlevel); info->allowColorTiling = FALSE; info->tilingEnabled = FALSE; - /* try to fix up already set mode, crt pitch, ddx major (hope that's ok to do here) */ - /* is this correct scrnIndex? flags? */ - RADEONSwitchMode(pScrn->scrnIndex, pScrn->currentMode, 0); - pScrn->AdjustFrame(pScrn->scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); pDRIInfo->ddxDriverMajorVersion = RADEON_VERSION_MAJOR; } drmFreeVersion(version); @@ -1611,6 +1607,8 @@ Bool RADEONDRIFinishScreenInit(ScreenPtr pScreen) info->allowPageFlip = 0; } + info->directRenderingInited = TRUE; + return TRUE; } @@ -1665,7 +1663,9 @@ void RADEONDRICloseScreen(ScreenPtr pScreen) drmRadeonInit drmInfo; RING_LOCALS; - /* Stop the CP */ + RADEONTRACE(("RADEONDRICloseScreen\n")); + + /* Stop the CP */ if (info->directRenderingEnabled) { /* If we've generated any CP commands, we must flush them to the * kernel module now. @@ -1775,6 +1775,9 @@ static void RADEONDRIRefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox) int i; RADEONSAREAPrivPtr pSAREAPriv = DRIGetSAREAPrivate(pScrn->pScreen); + if (!info->directRenderingInited) + return; + /* Don't want to do this when no 3d is active and pages are * right-way-round */ @@ -1784,6 +1787,10 @@ static void RADEONDRIRefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox) #ifdef USE_XAA /* XXX: implement for EXA */ /* pretty much a hack. */ + + /* Make sure accel has been properly inited */ + if (info->accel == NULL || info->accel->SetupForScreenToScreenCopy == NULL) + return; if (info->tilingEnabled) info->dst_pitch_offset |= RADEON_DST_TILE_MACRO; (*info->accel->SetupForScreenToScreenCopy)(pScrn, diff --git a/src/radeon_driver.c b/src/radeon_driver.c index 27292d3..d827c45 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.84 2006/01/13 01:02:01 alanc Exp $ */ +/* $XdotOrg: driver/xf86-video-ati/src/radeon_driver.c,v 1.85 2006/01/19 14:20:37 daniels Exp $ */ /* * Copyright 2000 ATI Technologies Inc., Markham, Ontario, and * VA Linux Systems Inc., Fremont, California. @@ -130,6 +130,8 @@ static void RADEONGetMergedFBOptions(ScrnInfoPtr pScrn); static int RADEONValidateMergeModes(ScrnInfoPtr pScrn); static void RADEONSetDynamicClock(ScrnInfoPtr pScrn, int mode); static void RADEONUpdatePanelSize(ScrnInfoPtr pScrn); +static void RADEONSaveMemMapRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save); +static void RADEONAdjustMemMapRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save); /* psuedo xinerama support */ @@ -733,6 +735,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)); info->FB = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_FRAMEBUFFER, info->PciTag, @@ -2253,83 +2256,65 @@ static Bool RADEONPreInitWeight(ScrnInfoPtr pScrn) return TRUE; } -/* Set up MC_FB_LOCATION and related registers */ -static void -RADEONSetFBLocation(ScrnInfoPtr pScrn) +static void RADEONInitMemMapRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save, + RADEONInfoPtr info) { - RADEONInfoPtr info = RADEONPTR(pScrn); - RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); + save->mc_fb_location = info->mc_fb_location; + save->mc_agp_location = info->mc_agp_location; + save->display_base_addr = info->fbLocation; + save->display2_base_addr = info->fbLocation; + save->ov0_base_addr = info->fbLocation; +} + +static void RADEONInitMemoryMap(ScrnInfoPtr pScrn) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); unsigned char *RADEONMMIO = info->MMIO; - CARD32 mc_fb_location; - CARD32 mc_agp_location = INREG(RADEON_MC_AGP_LOCATION); - CARD32 bus_cntl = INREG(RADEON_BUS_CNTL); - - OUTREG (RADEON_BUS_CNTL, bus_cntl | RADEON_BUS_MASTER_DIS); - RADEONWaitForIdleMMIO(pScrn); + unsigned long agp_size, agp_base, mem_size; - /* This function has many problems with newer cards. - * Even with older cards, all registers changed here are not - * restored properly when X quits, this will also cause - * various problems, especially with radeonfb. - * Since we don't have DRI support for R300 and above cards, - * we just hardcode these values for now. - * Need to revisit this whole function!!! - */ + /* Default to existing values */ + info->mc_fb_location = INREG(RADEON_MC_FB_LOCATION); + info->mc_agp_location = INREG(RADEON_MC_AGP_LOCATION); - if (info->IsIGP) { - mc_fb_location = INREG(RADEON_NB_TOM); + /* We shouldn't use info->videoRam here which might have been clipped + * but the real video RAM instead + */ + mem_size = INREG(RADEON_CONFIG_MEMSIZE); + if (mem_size == 0) + mem_size = 0x800000; - OUTREG(RADEON_GRPH2_BUFFER_CNTL, - INREG(RADEON_GRPH2_BUFFER_CNTL) & ~0x7f0000); - } else + /* We won't try to change MC_FB_LOCATION when using fbdev */ + if (!info->FBDev) { + if (info->IsIGP) + info->mc_fb_location = INREG(RADEON_NB_TOM); + else #ifdef XF86DRI - if ( info->directRenderingEnabled && info->drmMinor < 10 ) { - mc_fb_location = (INREG(RADEON_CONFIG_APER_SIZE) - 1) & 0xffff0000U; - } else + /* Old DRI has restrictions on the memory map */ + if ( info->directRenderingEnabled && info->drmMinor < 10 ) + info->mc_fb_location = (mem_size - 1) & 0xffff0000U; + else #endif - { - CARD32 aper0_base = INREG(RADEON_CONFIG_APER_0_BASE); - - mc_fb_location = (aper0_base >> 16) - | ((aper0_base + (INREG(RADEON_CONFIG_APER_SIZE) - 1) - ) & 0xffff0000U); - } - - info->fbLocation = (mc_fb_location & 0xffff) << 16; - - if (((mc_agp_location & 0xffff) << 16) != - ((mc_fb_location & 0xffff0000U) + 0x10000)) { - mc_agp_location = mc_fb_location & 0xffff0000U; - mc_agp_location |= (mc_agp_location + 0x10000) >> 16; - } - - RADEONWaitForIdleMMIO(pScrn); - - OUTREG(RADEON_MC_FB_LOCATION, mc_fb_location); - OUTREG(RADEON_MC_AGP_LOCATION, mc_agp_location); - OUTREG(RADEON_DISPLAY_BASE_ADDR, info->fbLocation); - if (info->HasCRTC2) - OUTREG(RADEON_DISPLAY2_BASE_ADDR, info->fbLocation); - OUTREG(RADEON_OV0_BASE_ADDR, info->fbLocation); - - OUTREG (RADEON_BUS_CNTL, bus_cntl); - RADEONWaitForIdleMMIO(pScrn); + { + CARD32 aper0_base = INREG(RADEON_CONFIG_APER_0_BASE); - /* Set display0/1 priority up on r3/4xx in the memory controller for - * high res modes if the user specifies HIGH for displaypriority - * option. - */ - if ((info->DispPriority == 2) && IS_R300_VARIANT) { - CARD32 mc_init_misc_lat_timer = INREG(R300_MC_INIT_MISC_LAT_TIMER); - if (info->MergedFB || pRADEONEnt->HasSecondary) { - mc_init_misc_lat_timer |= 0x1100; /* display 0 and 1 */ - } else { - mc_init_misc_lat_timer |= 0x0100; /* display 0 only */ + info->mc_fb_location = (aper0_base >> 16) | + ((aper0_base + mem_size - 1) & 0xffff0000U); } - OUTREG(R300_MC_INIT_MISC_LAT_TIMER, mc_init_misc_lat_timer); } - + info->fbLocation = (info->mc_fb_location & 0xffff) << 16; + + /* Just disable the damn AGP apertures for now, it may be + * re-enabled later by the DRM + */ + info->mc_agp_location = 0xffffffc0; + + 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)); } static void RADEONGetVRamType(ScrnInfoPtr pScrn) @@ -2368,6 +2353,55 @@ static void RADEONGetVRamType(ScrnInfoPtr pScrn) */ } +/* + * Depending on card genertation, chipset bugs, etc... the amount of vram + * accessible to the CPU can vary. This function is our best shot at figuring + * it out. Returns a value in KB. + */ +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; + + /* Set HDP_APER_CNTL only on cards that are known not to be broken, + * that is has the 2nd generation multifunction PCI interface + */ + if (info->ChipFamily == CHIP_FAMILY_RV280 || + info->ChipFamily == CHIP_FAMILY_RV350 || + info->ChipFamily == CHIP_FAMILY_RV380 || + info->ChipFamily == CHIP_FAMILY_R420) { + OUTREGP (RADEON_HOST_PATH_CNTL, RADEON_HDP_APER_CNTL, + ~RADEON_HDP_APER_CNTL); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Generation 2 PCI interface, using max accessible memory\n"); + return aper_size * 2; + } + + /* Older cards have all sorts of funny issues to deal with. First + * check if it's a multifunction card by reading the PCI config + * header type... Limit those to one aperture size + */ + if (pciReadByte(info->PciTag, 0xe) & 0x80) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Generation 1 PCI interface in multifunction mode" + ", accessible memory limited to one aperture\n"); + return aper_size; + } + + /* Single function older card. We read HDP_APER_CNTL to see how the BIOS + * have set it up. We don't write this as it's broken on some ASICs but + * we expect the BIOS to have done the right thing (might be too optimistic...) + */ + if (INREG(RADEON_HOST_PATH_CNTL) & RADEON_HDP_APER_CNTL) + return aper_size * 2; + + return aper_size; +} + /* This is called by RADEONPreInit to handle config file overrides for * things like chipset and memory regions. Also determine memory size * and type. If memory type ever needs an override, put it in this @@ -2705,22 +2739,25 @@ static Bool RADEONPreInitConfig(ScrnInfoPtr pScrn) OUTREG(RADEON_CONFIG_MEMSIZE, pScrn->videoRam * 1024); } else { - /* There are different HDP mapping schemes depending on single/multi funciton setting, - * chip family, HDP mode, and the generation of HDP mapping scheme. - * To make things simple, we only allow maximum 128M addressable FB. Anything more than - * 128M is configured as invisible FB to CPU that can only be accessed from chip side. - */ + CARD32 accessible; + + /* Read VRAM size from card */ pScrn->videoRam = INREG(RADEON_CONFIG_MEMSIZE) / 1024; - if (pScrn->videoRam > 128*1024) pScrn->videoRam = 128*1024; - if ((info->ChipFamily == CHIP_FAMILY_RV350) || - (info->ChipFamily == CHIP_FAMILY_RV380) || - (info->ChipFamily == CHIP_FAMILY_R420)) { - OUTREGP (RADEON_HOST_PATH_CNTL, (1<<23), ~(1<<23)); - } - } - /* Some production boards of m6 will return 0 if it's 8 MB */ - if (pScrn->videoRam == 0) pScrn->videoRam = 8192; + /* Some production boards of m6 will return 0 if it's 8 MB */ + if (pScrn->videoRam == 0) { + pScrn->videoRam = 8192; + OUTREG(RADEON_CONFIG_MEMSIZE, 0x800000); + } + + /* Get accessible memory */ + accessible = RADEONGetAccessibleVRAM(pScrn); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Detected total video RAM: %dl, max accessible: %dK\n", + pScrn->videoRam, accessible); + if (pScrn->videoRam > accessible) + pScrn->videoRam = accessible; + } /* Check chip errata */ info->ChipErrata = 0; @@ -4969,8 +5006,10 @@ static void RADEONLoadPalette(ScrnInfoPtr pScrn, int numColors, int idx, j; unsigned char r, g, b; + RADEONTRACE(("RADEONLoadPalette !\n")); + #ifdef XF86DRI - if (info->CPStarted) DRILock(pScrn->pScreen, 0); + if (info->CPStarted && pScrn->pScreen) DRILock(pScrn->pScreen, 0); #endif if (info->accelOn && pScrn->pScreen) @@ -5085,8 +5124,10 @@ static void RADEONLoadPalette(ScrnInfoPtr pScrn, int numColors, } #ifdef XF86DRI - if (info->CPStarted) DRIUnlock(pScrn->pScreen); + if (info->CPStarted && pScrn->pScreen) DRIUnlock(pScrn->pScreen); #endif + + RADEONTRACE(("LoadPalette() end\n")); } static void RADEONBlockHandler(int i, pointer blockData, @@ -5097,7 +5138,7 @@ static void RADEONBlockHandler(int i, pointer blockData, RADEONInfoPtr info = RADEONPTR(pScrn); #ifdef XF86DRI - if (info->directRenderingEnabled) { + if (info->directRenderingInited) { FLUSH_RING(); } #endif @@ -5455,8 +5496,10 @@ _X_EXPORT Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen, info->CPInUse = FALSE; info->CPStarted = FALSE; info->directRenderingEnabled = FALSE; + info->directRenderingInited = FALSE; #endif info->accelOn = FALSE; + info->accel = NULL; pScrn->fbOffset = 0; if (info->IsSecondary) pScrn->fbOffset = pScrn->videoRam * 1024; if (!RADEONMapMem(pScrn)) return FALSE; @@ -5504,31 +5547,6 @@ _X_EXPORT Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen, info->tilingEnabled = (pScrn->currentMode->Flags & (V_DBLSCAN | V_INTERLACE)) ? FALSE : TRUE; } } - - if (!info->IsSecondary) { - /* empty the surfaces */ - unsigned char *RADEONMMIO = info->MMIO; - unsigned int i; - for (i = 0; i < 8; i++) { - OUTREG(RADEON_SURFACE0_INFO + 16 * i, 0); - OUTREG(RADEON_SURFACE0_LOWER_BOUND + 16 * i, 0); - OUTREG(RADEON_SURFACE0_UPPER_BOUND + 16 * i, 0); - } - } - - if (info->FBDev) { - unsigned char *RADEONMMIO = info->MMIO; - - if (!fbdevHWModeInit(pScrn, pScrn->currentMode)) return FALSE; - info->ModeReg.surface_cntl = INREG(RADEON_SURFACE_CNTL); - } else { - if (!RADEONModeInit(pScrn, pScrn->currentMode)) return FALSE; - } - - RADEONSaveScreen(pScreen, SCREEN_SAVER_ON); - - pScrn->AdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); - /* Visual setup */ miClearVisualTypes(); if (!miSetVisualTypes(pScrn->depth, @@ -5590,6 +5608,41 @@ _X_EXPORT Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen, } } + hasDRI = info->directRenderingEnabled; +#endif + + /* Initialize the memory map, this basically calculates the values + * we'll use later on for MC_FB_LOCATION & MC_AGP_LOCATION + */ + RADEONInitMemoryMap(pScrn); + + if (!info->IsSecondary) { + /* empty the surfaces */ + unsigned char *RADEONMMIO = info->MMIO; + unsigned int i; + for (i = 0; i < 8; i++) { + OUTREG(RADEON_SURFACE0_INFO + 16 * i, 0); + OUTREG(RADEON_SURFACE0_LOWER_BOUND + 16 * i, 0); + OUTREG(RADEON_SURFACE0_UPPER_BOUND + 16 * i, 0); + } + } + + if (info->FBDev) { + unsigned char *RADEONMMIO = info->MMIO; + + if (!fbdevHWModeInit(pScrn, pScrn->currentMode)) return FALSE; + RADEONSaveMemMapRegisters(pScrn, &info->ModeReg); + info->fbLocation = (info->ModeReg.mc_fb_location & 0xffff) << 16; + info->ModeReg.surface_cntl = INREG(RADEON_SURFACE_CNTL); + info->ModeReg.surface_cntl &= ~RADEON_SURF_TRANSLATION_DIS; + } else { + if (!RADEONModeInit(pScrn, pScrn->currentMode)) return FALSE; + } + + RADEONSaveScreen(pScreen, SCREEN_SAVER_ON); + + pScrn->AdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); + /* Depth moves are disabled by default since they are extremely slow */ info->depthMoves = xf86ReturnOptValBool(info->Options, OPTION_DEPTH_MOVE, FALSE); @@ -5604,11 +5657,15 @@ _X_EXPORT Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen, "Depth moves disabled by default\n"); } - hasDRI = info->directRenderingEnabled; -#endif + /* Initial setup of surfaces */ + if (!info->IsSecondary) { + RADEONTRACE(("Setting up initial surfaces\n")); + RADEONChangeSurfaces(pScrn); + } - RADEONSetFBLocation(pScrn); + RADEONTRACE(("Initializing fb layer\n")); + /* Init fb layer */ if (!fbScreenInit(pScreen, info->FB, pScrn->virtualX, pScrn->virtualY, pScrn->xDpi, pScrn->yDpi, pScrn->displayWidth, @@ -5655,6 +5712,9 @@ _X_EXPORT Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen, } #endif /* Memory manager setup */ + + RADEONTRACE(("Setting up accel memmap\n")); + #ifdef USE_EXA if (info->useEXA && !RADEONSetupMemEXA(pScreen)) return FALSE; @@ -5673,8 +5733,85 @@ _X_EXPORT Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen, info->dst_pitch_offset = (((pScrn->displayWidth * info->CurrentLayout.pixel_bytes / 64) << 22) | ((info->fbLocation + pScrn->fbOffset) >> 10)); - /* Acceleration setup */ + /* Backing store setup */ + RADEONTRACE(("Initializing backing store\n")); + miInitializeBackingStore(pScreen); + xf86SetBackingStore(pScreen); + + /* DRI finalisation */ +#ifdef XF86DRI + /* Tell DRI about new memory map */ + if (info->directRenderingEnabled) { + drmRadeonSetParam radeonsetparam; + RADEONTRACE(("DRI New memory map param\n")); + memset(&radeonsetparam, 0, sizeof(drmRadeonSetParam)); + radeonsetparam.param = RADEON_SETPARAM_NEW_MEMMAP; + radeonsetparam.value = 1; + if (drmCommandWrite(info->drmFD, DRM_RADEON_SETPARAM, + &radeonsetparam, sizeof(drmRadeonSetParam)) < 0) + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "[drm] failed to enable new memory map\n"); + } + + if (info->cardType==CARD_PCIE && info->pciGartOffset && info->drmMinor>=19) + { + drmRadeonSetParam radeonsetparam; + RADEONTRACE(("DRI PCIGART param\n")); + memset(&radeonsetparam, 0, sizeof(drmRadeonSetParam)); + radeonsetparam.param = RADEON_SETPARAM_PCIGART_LOCATION; + radeonsetparam.value = info->pciGartOffset; + if (drmCommandWrite(info->drmFD, DRM_RADEON_SETPARAM, + &radeonsetparam, sizeof(drmRadeonSetParam)) < 0) + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "[drm] failed set pci gart location\n"); + } + if (info->directRenderingEnabled) { + RADEONTRACE(("DRI Finishing init !\n")); + info->directRenderingEnabled = RADEONDRIFinishScreenInit(pScreen); + } + if (info->directRenderingEnabled) { + /* DRI final init might have changed the memory map, we need to adjust + * our local image to make sure we restore them properly on mode + * changes or VT switches + */ + RADEONAdjustMemMapRegisters(pScrn, &info->ModeReg); + + if ((info->DispPriority == 1) && (info->cardType==CARD_AGP)) { + /* we need to re-calculate bandwidth because of AGPMode difference. */ + RADEONInitDispBandwidth(pScrn); + } + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Direct rendering enabled\n"); + + /* we might already be in tiled mode, tell drm about it */ + if (info->directRenderingEnabled && info->tilingEnabled) { + drmRadeonSetParam radeonsetparam; + memset(&radeonsetparam, 0, sizeof(drmRadeonSetParam)); + radeonsetparam.param = RADEON_SETPARAM_SWITCH_TILING; + radeonsetparam.value = info->tilingEnabled ? 1 : 0; + if (drmCommandWrite(info->drmFD, DRM_RADEON_SETPARAM, + &radeonsetparam, sizeof(drmRadeonSetParam)) < 0) + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "[drm] failed changing tiling status\n"); + } + } else { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Direct rendering disabled\n"); + } +#endif + + /* Make sure surfaces are allright since DRI setup may have changed them */ + if (!info->IsSecondary) { + RADEONTRACE(("Setting up final surfaces\n")); + RADEONChangeSurfaces(pScrn); + } + + if(info->MergedFB) + /* need this here to fix up sarea values */ + RADEONAdjustFrameMerged(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); + + /* Enable aceleration */ if (!xf86ReturnOptValBool(info->Options, OPTION_NOACCEL, FALSE)) { + RADEONTRACE(("Initializing Acceleration\n")); if (RADEONAccelInit(pScreen)) { xf86DrvMsg(scrnIndex, X_INFO, "Acceleration enabled\n"); info->accelOn = TRUE; @@ -5689,12 +5826,11 @@ _X_EXPORT Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen, info->accelOn = FALSE; } - /* DGA setup */ - RADEONDGAInit(pScreen); + /* Init DPMS */ + RADEONTRACE(("Initializing DPMS\n")); + xf86DPMSInit(pScreen, RADEONDisplayPowerManagementSet, 0); - /* Backing store setup */ - miInitializeBackingStore(pScreen); - xf86SetBackingStore(pScreen); + RADEONTRACE(("Initializing Cursor\n")); /* Set Silken Mouse */ xf86SetSilkenMouse(pScreen); @@ -5731,7 +5867,8 @@ _X_EXPORT Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen, xf86DrvMsg(scrnIndex, X_INFO, "Using software cursor\n"); } - /* Colormap setup */ + /* Colormap setup */ + RADEONTRACE(("Initializing color map\n")); if (!miCreateDefColormap(pScreen)) return FALSE; if (!xf86HandleColormaps(pScreen, 256, info->dac6bits ? 6 : 8, RADEONLoadPalette, NULL, @@ -5741,17 +5878,9 @@ _X_EXPORT Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen, #endif | CMAP_RELOAD_ON_MODE_SWITCH)) return FALSE; - /* DPMS setup */ - xf86DPMSInit(pScreen, RADEONDisplayPowerManagementSet, 0); - - RADEONInitVideo(pScreen); - - /* Provide SaveScreen */ - pScreen->SaveScreen = RADEONSaveScreen; - - /* Wrap CloseScreen */ - info->CloseScreen = pScreen->CloseScreen; - pScreen->CloseScreen = RADEONCloseScreen; + /* DGA setup */ + RADEONTRACE(("Initializing DGA\n")); + RADEONDGAInit(pScreen); /* Wrap some funcs for MergedFB */ if(info->MergedFB) { @@ -5766,80 +5895,125 @@ _X_EXPORT Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen, } } - /* Note unused options */ + /* Init Xv */ + RADEONTRACE(("Initializing Xv\n")); + RADEONInitVideo(pScreen); + + /* Provide SaveScreen & wrap BlockHandler and CloseScreen */ + /* Wrap CloseScreen */ + info->CloseScreen = pScreen->CloseScreen; + pScreen->CloseScreen = RADEONCloseScreen; + pScreen->SaveScreen = RADEONSaveScreen; + info->BlockHandler = pScreen->BlockHandler; + pScreen->BlockHandler = RADEONBlockHandler; + + /* Note unused options */ if (serverGeneration == 1) xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options); -#ifdef XF86DRI - if (info->cardType==CARD_PCIE && info->pciGartOffset && info->drmMinor>=19) - { - drmRadeonSetParam radeonsetparam; - memset(&radeonsetparam, 0, sizeof(drmRadeonSetParam)); - radeonsetparam.param = RADEON_SETPARAM_PCIGART_LOCATION; - radeonsetparam.value = info->pciGartOffset; - if (drmCommandWrite(info->drmFD, DRM_RADEON_SETPARAM, - &radeonsetparam, sizeof(drmRadeonSetParam)) < 0) - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "[drm] failed set pci gart location\n"); - } + RADEONTRACE(("RADEONScreenInit finished\n")); - /* DRI finalization */ - if (info->directRenderingEnabled) { - /* Now that mi, fb, drm and others have - done their thing, complete the DRI - setup. */ - if (!(info->directRenderingEnabled = RADEONDRIFinishScreenInit(pScreen))) { -#ifdef USE_EXA - if (info->useEXA) { - RADEONDrawInitMMIO(pScreen); - } -#endif /* USE_EXA */ -#ifdef USE_XAA - if (!info->useEXA) - RADEONAccelInitMMIO(pScreen, info->accel); -#endif /* USE_XAA */ - } - } - if (info->directRenderingEnabled) { - if ((info->DispPriority == 1) && (info->cardType==CARD_AGP)) { - /* we need to re-calculate bandwidth because of AGPMode difference. */ - RADEONInitDispBandwidth(pScrn); - } - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Direct rendering enabled\n"); + return TRUE; +} - /* we might already be in tiled mode, tell drm about it */ - if (info->directRenderingEnabled && info->tilingEnabled) { - drmRadeonSetParam radeonsetparam; - memset(&radeonsetparam, 0, sizeof(drmRadeonSetParam)); - radeonsetparam.param = RADEON_SETPARAM_SWITCH_TILING; - radeonsetparam.value = info->tilingEnabled ? 1 : 0; - if (drmCommandWrite(info->drmFD, DRM_RADEON_SETPARAM, - &radeonsetparam, sizeof(drmRadeonSetParam)) < 0) - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "[drm] failed changing tiling status\n"); +/* Write memory mapping registers */ +static void RADEONRestoreMemMapRegisters(ScrnInfoPtr pScrn, + RADEONSavePtr restore) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + int i; + + RADEONTRACE(("RADEONRestoreMemMapRegisters() : \n")); + RADEONTRACE((" MC_FB_LOCATION : 0x%08lx\n", restore->mc_fb_location)); + RADEONTRACE((" MC_AGP_LOCATION : 0x%08lx\n", restore->mc_agp_location)); + + /* Write memory mapping registers only if their value change + * since we must ensure no access is done while they are + * reprogrammed + */ + if (INREG(RADEON_MC_FB_LOCATION) != restore->mc_fb_location || + INREG(RADEON_MC_AGP_LOCATION) != restore->mc_agp_location) { + CARD32 tmp; + + RADEONTRACE((" Map Changed ! Applying ...\n")); + + /* Make sure engine is idle. We assume the CCE is stopped + * at this point + */ + RADEONWaitForIdleMMIO(pScrn); + + /* Stop display & memory access */ + tmp = INREG(RADEON_CRTC_EXT_CNTL); + OUTREG(RADEON_CRTC_EXT_CNTL, tmp | RADEON_CRTC_DISPLAY_DIS); + tmp = INREG(RADEON_CRTC_GEN_CNTL); + tmp &= ~RADEON_CRTC_CUR_EN; + tmp |= RADEON_CRTC_DISP_REQ_EN_B; + OUTREG(RADEON_CRTC_GEN_CNTL, tmp); + if (info->HasCRTC2) { + tmp = INREG(RADEON_CRTC2_GEN_CNTL); + tmp &= ~RADEON_CRTC2_CUR_EN; + tmp |= RADEON_CRTC2_DISP_DIS | RADEON_CRTC2_DISP_REQ_EN_B; + OUTREG(RADEON_CRTC2_GEN_CNTL, tmp); } + tmp = INREG(RADEON_OV0_SCALE_CNTL); + tmp &= ~RADEON_SCALER_ENABLE; + OUTREG(RADEON_OV0_SCALE_CNTL, tmp); - } else { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Direct rendering disabled\n"); + /* Make sure the chip settles down and set new map*/ + usleep(100000); + OUTREG(RADEON_MC_FB_LOCATION, restore->mc_fb_location); + OUTREG(RADEON_MC_AGP_LOCATION, restore->mc_agp_location); + /* Make sure map fully reached the chip */ + (void)INREG(RADEON_MC_FB_LOCATION); + + /* Reset the engine and HDP */ + RADEONEngineReset(pScrn); } -#endif + + /* Restore base addresses */ + OUTREG(RADEON_DISPLAY_BASE_ADDR, restore->display_base_addr); + OUTREG(RADEON_DISPLAY2_BASE_ADDR, restore->display2_base_addr); + OUTREG(RADEON_OV0_BASE_ADDR, restore->ov0_base_addr); +} - if (!info->IsSecondary) - RADEONChangeSurfaces(pScrn); +static void RADEONAdjustMemMapRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + CARD32 fb, agp; + int fb_loc_changed; - if(info->MergedFB) { - /* need this here to fix up sarea values */ - RADEONAdjustFrameMerged(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); - } + fb = INREG(RADEON_MC_FB_LOCATION); + agp = INREG(RADEON_MC_AGP_LOCATION); + fb_loc_changed = (fb != info->mc_fb_location); - info->BlockHandler = pScreen->BlockHandler; - pScreen->BlockHandler = RADEONBlockHandler; + if (fb_loc_changed || agp != info->mc_agp_location) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "DRI init changed memory map, adjusting ...\n"); + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + " MC_FB_LOCATION was: 0x%08lx is: 0x%08lx\n", + info->mc_fb_location, fb); + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + " MC_AGP_LOCATION was: 0x%08lx is: 0x%08lx\n", + info->mc_agp_location, agp); + info->mc_fb_location = fb; + info->mc_agp_location = agp; + info->fbLocation = (save->mc_fb_location & 0xffff) << 16; + info->dst_pitch_offset = + (((pScrn->displayWidth * info->CurrentLayout.pixel_bytes / 64) + << 22) | ((info->fbLocation + pScrn->fbOffset) >> 10)); - return TRUE; + + RADEONInitMemMapRegisters(pScrn, save, info); + + /* If MC_FB_LOCATION was changed, adjust the various offsets */ + if (fb_loc_changed) + RADEONRestoreMemMapRegisters(pScrn, save); + } } -/* Write common registers (initialized to 0) */ +/* Write common registers */ static void RADEONRestoreCommonRegisters(ScrnInfoPtr pScrn, RADEONSavePtr restore) { @@ -6257,6 +6431,35 @@ static void RADEONRestorePLL2Registers(ScrnInfoPtr pScrn, ~(RADEON_PIX2CLK_SRC_SEL_MASK)); } + +/* restore original surface info (for fb console). */ +static void RADEONRestoreSurfaces(ScrnInfoPtr pScrn, RADEONSavePtr restore) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + unsigned int surfnr; + + for ( surfnr = 0; surfnr < 8; surfnr++ ) { + OUTREG(RADEON_SURFACE0_INFO + 16 * surfnr, restore->surfaces[surfnr][0]); + OUTREG(RADEON_SURFACE0_LOWER_BOUND + 16 * surfnr, restore->surfaces[surfnr][1]); + OUTREG(RADEON_SURFACE0_UPPER_BOUND + 16 * surfnr, restore->surfaces[surfnr][2]); + } +} + +/* save original surface info (for fb console). */ +static void RADEONSaveSurfaces(ScrnInfoPtr pScrn, RADEONSavePtr save) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + unsigned int surfnr; + + for ( surfnr = 0; surfnr < 8; surfnr++ ) { + save->surfaces[surfnr][0] = INREG(RADEON_SURFACE0_INFO + 16 * surfnr); + save->surfaces[surfnr][1] = INREG(RADEON_SURFACE0_LOWER_BOUND + 16 * surfnr); + save->surfaces[surfnr][2] = INREG(RADEON_SURFACE0_UPPER_BOUND + 16 * surfnr); + } +} + void RADEONChangeSurfaces(ScrnInfoPtr pScrn) { /* the idea here is to only set up front buffer as tiled, and back/depth buffer when needed. @@ -6275,6 +6478,9 @@ void RADEONChangeSurfaces(ScrnInfoPtr pScrn) + RADEON_BUFFER_ALIGN) & ~RADEON_BUFFER_ALIGN); unsigned int depth_pattern, color_pattern, swap_pattern; + if (!info->allowColorTiling) + return; + swap_pattern = 0; #if X_BYTE_ORDER == X_BIG_ENDIAN switch (pScrn->bitsPerPixel) { @@ -6307,8 +6513,9 @@ void RADEONChangeSurfaces(ScrnInfoPtr pScrn) depth_pattern = R200_SURF_TILE_DEPTH_32BPP; } #ifdef XF86DRI - if (info->directRenderingEnabled && info->allowColorTiling) { + if (info->directRenderingInited) { drmRadeonSurfaceFree drmsurffree; + drmRadeonSurfaceAlloc drmsurfalloc; int retvalue; drmsurffree.address = info->frontOffset; @@ -6329,31 +6536,31 @@ void RADEONChangeSurfaces(ScrnInfoPtr pScrn) &drmsurffree, sizeof(drmsurffree)); } - if (info->tilingEnabled) { - drmRadeonSurfaceAlloc drmsurfalloc; - drmsurfalloc.size = bufferSize; - drmsurfalloc.address = info->frontOffset; + drmsurfalloc.size = bufferSize; + drmsurfalloc.address = info->frontOffset; + drmsurfalloc.flags = swap_pattern; + if (info->tilingEnabled) { if (IS_R300_VARIANT) - drmsurfalloc.flags = swap_pattern | (width_bytes / 8) | color_pattern; + drmsurfalloc.flags |= (width_bytes / 8) | color_pattern; else - drmsurfalloc.flags = swap_pattern | (width_bytes / 16) | color_pattern; - + drmsurfalloc.flags |= (width_bytes / 16) | color_pattern; + } + retvalue = drmCommandWrite(info->drmFD, DRM_RADEON_SURF_ALLOC, + &drmsurfalloc, sizeof(drmsurfalloc)); + if (retvalue < 0) + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "drm: could not allocate surface for front buffer!\n"); + + if ((info->have3DWindows) && (!info->noBackBuffer)) { + drmsurfalloc.address = info->backOffset; retvalue = drmCommandWrite(info->drmFD, DRM_RADEON_SURF_ALLOC, - &drmsurfalloc, sizeof(drmsurfalloc)); + &drmsurfalloc, sizeof(drmsurfalloc)); if (retvalue < 0) xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "drm: could not allocate surface for front buffer!\n"); - - if ((info->have3DWindows) && (!info->noBackBuffer)) { - drmsurfalloc.address = info->backOffset; - retvalue = drmCommandWrite(info->drmFD, DRM_RADEON_SURF_ALLOC, - &drmsurfalloc, sizeof(drmsurfalloc)); - if (retvalue < 0) - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "drm: could not allocate surface for back buffer!\n"); - } + "drm: could not allocate surface for back buffer!\n"); } + /* 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) || @@ -6374,16 +6581,16 @@ void RADEONChangeSurfaces(ScrnInfoPtr pScrn) } else #endif - if (info->allowColorTiling) { - unsigned int surf_info = 0; + { + unsigned int surf_info = swap_pattern; unsigned char *RADEONMMIO = info->MMIO; /* we don't need anything like WaitForFifo, no? */ if (!info->IsSecondary) { if (info->tilingEnabled) { if (IS_R300_VARIANT) - surf_info = swap_pattern | (width_bytes / 8) | color_pattern; + surf_info |= (width_bytes / 8) | color_pattern; else - surf_info = swap_pattern | (width_bytes / 16) | color_pattern; + surf_info |= (width_bytes / 16) | color_pattern; } OUTREG(RADEON_SURFACE0_INFO, surf_info); OUTREG(RADEON_SURFACE0_LOWER_BOUND, 0); @@ -6393,6 +6600,9 @@ void RADEONChangeSurfaces(ScrnInfoPtr pScrn) surf_info, 0, bufferSize - 1024);*/ } } + + /* Update surface images */ + RADEONSaveSurfaces(pScrn, &info->ModeReg); } #if 0 @@ -6421,35 +6631,6 @@ static void RADEONRestorePalette(ScrnInfoPtr pScrn, RADEONSavePtr restore) } #endif -/* restore original surface info (for fb console). */ -static void RADEONRestoreSurfaces(ScrnInfoPtr pScrn, RADEONSavePtr restore) -{ - RADEONInfoPtr info = RADEONPTR(pScrn); - unsigned char *RADEONMMIO = info->MMIO; - unsigned int surfnr; - - for ( surfnr = 0; surfnr < 8; surfnr++ ) { - OUTREG(RADEON_SURFACE0_INFO + 16 * surfnr, restore->surfaces[surfnr][0]); - OUTREG(RADEON_SURFACE0_LOWER_BOUND + 16 * surfnr, restore->surfaces[surfnr][1]); - OUTREG(RADEON_SURFACE0_UPPER_BOUND + 16 * surfnr, restore->surfaces[surfnr][2]); - } -} - -/* save original surface info (for fb console). */ -static void RADEONSaveSurfaces(ScrnInfoPtr pScrn, RADEONSavePtr save) -{ - RADEONInfoPtr info = RADEONPTR(pScrn); - unsigned char *RADEONMMIO = info->MMIO; - unsigned int surfnr; - - for ( surfnr = 0; surfnr < 8; surfnr++ ) { - save->surfaces[surfnr][0] = INREG(RADEON_SURFACE0_INFO + 16 * surfnr); - save->surfaces[surfnr][1] = INREG(RADEON_SURFACE0_LOWER_BOUND + 16 * surfnr); - save->surfaces[surfnr][2] = INREG(RADEON_SURFACE0_UPPER_BOUND + 16 * surfnr); - } -} - - /* Write out state to define a new video mode */ static void RADEONRestoreMode(ScrnInfoPtr pScrn, RADEONSavePtr restore) { @@ -6457,8 +6638,11 @@ static void RADEONRestoreMode(ScrnInfoPtr pScrn, RADEONSavePtr restore) RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); static RADEONSaveRec restore0; + RADEONTRACE(("RADEONRestoreMode()\n")); + /* For Non-dual head card, we don't have private field in the Entity */ if (!info->HasCRTC2) { + RADEONRestoreMemMapRegisters(pScrn, restore); RADEONRestoreCommonRegisters(pScrn, restore); RADEONRestoreCrtcRegisters(pScrn, restore); RADEONRestoreFPRegisters(pScrn, restore); @@ -6476,10 +6660,12 @@ static void RADEONRestoreMode(ScrnInfoPtr pScrn, RADEONSavePtr restore) * order. Regardless the order of X server issuing the calls, we * have to ensure we set registers in the right order!!! Otherwise * we may get a blank screen. + * + * We always restore MemMap first, the saverec should be up to date + * in all cases */ if (info->IsSecondary) { - if (!pRADEONEnt->RestorePrimary && !info->IsSwitching) - RADEONRestoreCommonRegisters(pScrn, restore); + RADEONRestoreMemMapRegisters(pScrn, restore); RADEONRestoreCrtc2Registers(pScrn, restore); RADEONRestorePLL2Registers(pScrn, restore); @@ -6490,15 +6676,14 @@ static void RADEONRestoreMode(ScrnInfoPtr pScrn, RADEONSavePtr restore) if (pRADEONEnt->RestorePrimary) { pRADEONEnt->RestorePrimary = FALSE; + RADEONRestoreCommonRegisters(pScrn, &restore0); RADEONRestoreCrtcRegisters(pScrn, &restore0); RADEONRestoreFPRegisters(pScrn, &restore0); RADEONRestorePLLRegisters(pScrn, &restore0); pRADEONEnt->IsSecondaryRestored = FALSE; } } else { - if (!pRADEONEnt->IsSecondaryRestored) - RADEONRestoreCommonRegisters(pScrn, restore); - + RADEONRestoreMemMapRegisters(pScrn, restore); if (info->MergedFB) { RADEONRestoreCrtc2Registers(pScrn, restore); RADEONRestorePLL2Registers(pScrn, restore); @@ -6508,6 +6693,7 @@ static void RADEONRestoreMode(ScrnInfoPtr pScrn, RADEONSavePtr restore) info->IsSwitching) { pRADEONEnt->IsSecondaryRestored = FALSE; + RADEONRestoreCommonRegisters(pScrn, restore); RADEONRestoreCrtcRegisters(pScrn, restore); RADEONRestoreFPRegisters(pScrn, restore); RADEONRestorePLLRegisters(pScrn, restore); @@ -6522,6 +6708,19 @@ static void RADEONRestoreMode(ScrnInfoPtr pScrn, RADEONSavePtr restore) #endif } +/* Read memory map */ +static void RADEONSaveMemMapRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + + save->mc_fb_location = INREG(RADEON_MC_FB_LOCATION); + save->mc_agp_location = INREG(RADEON_MC_AGP_LOCATION); + save->display_base_addr = INREG(RADEON_DISPLAY_BASE_ADDR); + save->display2_base_addr = INREG(RADEON_DISPLAY2_BASE_ADDR); + save->ov0_base_addr = INREG(RADEON_OV0_BASE_ADDR); +} + /* Read common registers */ static void RADEONSaveCommonRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save) { @@ -6705,6 +6904,7 @@ static void RADEONSaveMode(ScrnInfoPtr pScrn, RADEONSavePtr save) RADEONInfoPtr info = RADEONPTR(pScrn); RADEONTRACE(("RADEONSaveMode(%p)\n", save)); + RADEONSaveMemMapRegisters(pScrn, save); RADEONSaveCommonRegisters(pScrn, save); if (info->IsSecondary) { RADEONSaveCrtc2Registers(pScrn, save); @@ -6733,6 +6933,7 @@ static void RADEONSave(ScrnInfoPtr pScrn) RADEONTRACE(("RADEONSave\n")); if (info->FBDev) { + RADEONSaveMemMapRegisters(pScrn, save); fbdevHWSave(pScrn); return; } @@ -6916,6 +7117,22 @@ static void RADEONInitDispBandwidth(ScrnInfoPtr pScrn) int stop_req, max_stop_req; float read_return_rate, time_disp1_drop_priority; + /* + * Set display0/1 priority up on r3/4xx in the memory controller for + * high res modes if the user specifies HIGH for displaypriority + * option. + */ + if ((info->DispPriority == 2) && IS_R300_VARIANT) { + CARD32 mc_init_misc_lat_timer = INREG(R300_MC_INIT_MISC_LAT_TIMER); + if (info->MergedFB || pRADEONEnt->HasSecondary) { + mc_init_misc_lat_timer |= 0x1100; /* display 0 and 1 */ + } else { + mc_init_misc_lat_timer |= 0x0100; /* display 0 only */ + } + OUTREG(R300_MC_INIT_MISC_LAT_TIMER, mc_init_misc_lat_timer); + } + + /* R420 family not supported yet */ if (info->ChipFamily == CHIP_FAMILY_R420) return; @@ -7824,8 +8041,9 @@ static void RADEONInitFPRegisters(ScrnInfoPtr pScrn, RADEONSavePtr orig, } /* Define PLL registers for requested video mode */ -static void RADEONInitPLLRegisters(RADEONInfoPtr info, RADEONSavePtr save, - RADEONPLLPtr pll, double dot_clock) +static void RADEONInitPLLRegisters(ScrnInfoPtr pScrn, RADEONInfoPtr info, + RADEONSavePtr save, RADEONPLLPtr pll, + double dot_clock) { unsigned long freq = dot_clock * 100; @@ -7889,8 +8107,9 @@ static void RADEONInitPLLRegisters(RADEONInfoPtr info, RADEONSavePtr save, } /* Define PLL2 registers for requested video mode */ -static void RADEONInitPLL2Registers(RADEONSavePtr save, RADEONPLLPtr pll, - double dot_clock, int no_odd_postdiv) +static void RADEONInitPLL2Registers(ScrnInfoPtr pScrn, RADEONSavePtr save, + RADEONPLLPtr pll, double dot_clock, + int no_odd_postdiv) { unsigned long freq = dot_clock * 100; @@ -8018,11 +8237,12 @@ static Bool RADEONInit(ScrnInfoPtr pScrn, DisplayModePtr mode, info->Flags = mode->Flags; + RADEONInitMemMapRegisters(pScrn, save, info); RADEONInitCommonRegisters(save, info); if (info->IsSecondary) { if (!RADEONInitCrtc2Registers(pScrn, save, mode, info)) return FALSE; - RADEONInitPLL2Registers(save, &info->pll, dot_clock, info->DisplayType != MT_CRT); + RADEONInitPLL2Registers(pScrn, save, &info->pll, dot_clock, info->DisplayType != MT_CRT); } else if (info->MergedFB) { RADEONInitCommonRegisters(save, info); if (!RADEONInitCrtcRegisters(pScrn, save, @@ -8030,7 +8250,7 @@ static Bool RADEONInit(ScrnInfoPtr pScrn, DisplayModePtr mode, return FALSE; dot_clock = (((RADEONMergedDisplayModePtr)mode->Private)->CRT1)->Clock / 1000.0; if (dot_clock) { - RADEONInitPLLRegisters(info, save, &info->pll, dot_clock); + RADEONInitPLLRegisters(pScrn, info, save, &info->pll, dot_clock); } else { save->ppll_ref_div = info->SavedReg.ppll_ref_div; save->ppll_div_3 = info->SavedReg.ppll_div_3; @@ -8039,13 +8259,13 @@ static Bool RADEONInit(ScrnInfoPtr pScrn, DisplayModePtr mode, RADEONInitCrtc2Registers(pScrn, save, ((RADEONMergedDisplayModePtr)mode->Private)->CRT2, info); dot_clock = (((RADEONMergedDisplayModePtr)mode->Private)->CRT2)->Clock / 1000.0; - RADEONInitPLL2Registers(save, &info->pll, dot_clock, info->MergeType != MT_CRT); + RADEONInitPLL2Registers(pScrn, save, &info->pll, dot_clock, info->MergeType != MT_CRT); } else { if (!RADEONInitCrtcRegisters(pScrn, save, mode, info)) return FALSE; dot_clock = mode->Clock/1000.0; if (dot_clock) { - RADEONInitPLLRegisters(info, save, &info->pll, dot_clock); + RADEONInitPLLRegisters(pScrn, info, save, &info->pll, dot_clock); } else { save->ppll_ref_div = info->SavedReg.ppll_ref_div; save->ppll_div_3 = info->SavedReg.ppll_div_3; @@ -8081,6 +8301,8 @@ static Bool RADEONModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode) { RADEONInfoPtr info = RADEONPTR(pScrn); + RADEONTRACE(("RADEONModeInit()\n")); + if (!RADEONInit(pScrn, mode, &info->ModeReg)) return FALSE; pScrn->vtSema = TRUE; @@ -8101,6 +8323,8 @@ static Bool RADEONSaveScreen(ScreenPtr pScreen, int mode) ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; Bool unblank; + RADEONTRACE(("RADEONSaveScreen(%d)\n", mode)); + unblank = xf86IsUnblank(mode); if (unblank) SetTimeSinceLastInputEvent(); @@ -8126,6 +8350,8 @@ _X_EXPORT Bool RADEONSwitchMode(int scrnIndex, DisplayModePtr mode, int flags) } #endif + RADEONTRACE(("RADEONSwitchMode() !n")); + if (info->allowColorTiling) { if (info->MergedFB) { if ((((RADEONMergedDisplayModePtr)mode->Private)->CRT1->Flags & @@ -8239,6 +8465,8 @@ void RADEONDoAdjustFrame(ScrnInfoPtr pScrn, int x, int y, int clone) XF86DRISAREAPtr pSAREA; #endif + RADEONTRACE(("RADEONDoAdjustFrame(%d,%d,%d)\n", x, y, clone)); + if (info->showCache && y) { int lastline = info->FbMapSize / ((pScrn->displayWidth * pScrn->bitsPerPixel) / 8); @@ -8302,7 +8530,7 @@ void RADEONDoAdjustFrame(ScrnInfoPtr pScrn, int x, int y, int clone) Base &= ~7; /* 3 lower bits are always 0 */ #ifdef XF86DRI - if (info->directRenderingEnabled) { + if (info->directRenderingInited) { /* note cannot use pScrn->pScreen since this is unitialized when called from RADEONScreenInit, and we need to call from there to get mergedfb + pageflip working */ /*** NOTE: r3/4xx will need sarea and drm pageflip updates to handle the xytile regs for @@ -8330,11 +8558,15 @@ void RADEONDoAdjustFrame(ScrnInfoPtr pScrn, int x, int y, int clone) } #endif + RADEONTRACE((" -> reg : 0x%04x = 0x%08x\n", reg, Base)); + OUTREG(reg, Base); if (IS_R300_VARIANT) { + RADEONTRACE((" regcntl : 0x%04x = 0x%08x\n", xytilereg, crtcxytile)); OUTREG(xytilereg, crtcxytile); } else { + RADEONTRACE((" regcntl : 0x%04x = 0x%08x\n", regcntl, crtcoffsetcntl)); OUTREG(regcntl, crtcoffsetcntl); } @@ -8346,7 +8578,7 @@ _X_EXPORT void RADEONAdjustFrame(int scrnIndex, int x, int y, int flags) RADEONInfoPtr info = RADEONPTR(pScrn); #ifdef XF86DRI - if (info->CPStarted) DRILock(pScrn->pScreen, 0); + if (info->CPStarted && pScrn->pScreen) DRILock(pScrn->pScreen, 0); #endif if (info->accelOn) @@ -8361,7 +8593,7 @@ _X_EXPORT void RADEONAdjustFrame(int scrnIndex, int x, int y, int flags) } #ifdef XF86DRI - if (info->CPStarted) DRIUnlock(pScrn->pScreen); + if (info->CPStarted && pScrn->pScreen) DRIUnlock(pScrn->pScreen); #endif } @@ -8388,6 +8620,9 @@ _X_EXPORT Bool RADEONEnterVT(int scrnIndex, int flags) } } + /* Makes sure the engine is idle before doing anything */ + RADEONWaitForIdleMMIO(pScrn); + if (info->FBDev) { unsigned char *RADEONMMIO = info->MMIO; if (!fbdevHWEnterVT(scrnIndex,flags)) return FALSE; @@ -8398,13 +8633,13 @@ _X_EXPORT Bool RADEONEnterVT(int scrnIndex, int flags) } else if (!RADEONModeInit(pScrn, pScrn->currentMode)) return FALSE; - RADEONSetFBLocation(pScrn); if (!info->IsSecondary) RADEONRestoreSurfaces(pScrn, &info->ModeReg); #ifdef XF86DRI if (info->directRenderingEnabled) { - /* get the Radeon back into shape after resume */ + /* get the DRI back into shape after resume */ RADEONDRIResume(pScrn->pScreen); + RADEONAdjustMemMapRegisters(pScrn, &info->ModeReg); } #endif /* this will get XVideo going again, but only if XVideo was initialised @@ -8438,7 +8673,7 @@ _X_EXPORT void RADEONLeaveVT(int scrnIndex, int flags) RADEONTRACE(("RADEONLeaveVT\n")); #ifdef XF86DRI - if (RADEONPTR(pScrn)->directRenderingEnabled) { + if (RADEONPTR(pScrn)->directRenderingInited) { DRILock(pScrn->pScreen, 0); RADEONCP_STOP(pScrn, info); } @@ -8453,9 +8688,9 @@ _X_EXPORT void RADEONLeaveVT(int scrnIndex, int flags) fbdevHWLeaveVT(scrnIndex,flags); } - if (!info->IsSecondary) - RADEONSaveSurfaces(pScrn, save); RADEONRestore(pScrn); + + RADEONTRACE(("Ok, leaving now...\n")); } /* Called at the end of each server generation. Restore the original @@ -8469,11 +8704,17 @@ static Bool RADEONCloseScreen(int scrnIndex, ScreenPtr pScreen) RADEONTRACE(("RADEONCloseScreen\n")); + /* Mark acceleration as stopped or we might try to access the engine at + * wrong times, especially if we had DRI, after DRI has been stopped + */ + info->accelOn = FALSE; + #ifdef XF86DRI - /* Disable direct rendering */ + /* Disable direct rendering */ if (info->directRenderingEnabled) { RADEONDRICloseScreen(pScreen); info->directRenderingEnabled = FALSE; + info->directRenderingInited = FALSE; } #endif @@ -8488,8 +8729,8 @@ static Bool RADEONCloseScreen(int scrnIndex, ScreenPtr pScreen) RADEONDisplayPowerManagementSet(pScrn, DPMSModeOn, 0); RADEONRestore(pScrn); } - RADEONUnmapMem(pScrn); + RADEONTRACE(("Disposing accel...\n")); #ifdef USE_EXA if (info->useEXA && info->accelOn) exaDriverFini(pScreen); @@ -8506,12 +8747,17 @@ static Bool RADEONCloseScreen(int scrnIndex, ScreenPtr pScreen) } #endif /* USE_XAA */ + RADEONTRACE(("Disposing cusor info\n")); if (info->cursor) xf86DestroyCursorInfoRec(info->cursor); info->cursor = NULL; + RADEONTRACE(("Disposing DGA\n")); if (info->DGAModes) xfree(info->DGAModes); info->DGAModes = NULL; + RADEONTRACE(("Unmapping memory\n")); + RADEONUnmapMem(pScrn); + pScrn->vtSema = FALSE; xf86ClearPrimInitDone(info->pEnt->index); @@ -8649,6 +8895,8 @@ static void RADEONDisplayPowerManagementSet(ScrnInfoPtr pScrn, if (!pScrn->vtSema) return; + RADEONTRACE(("RADEONDisplayPowerManagementSet(%d,0x%x)\n", PowerManagementMode, flags)); + #ifdef XF86DRI if (info->CPStarted) DRILock(pScrn->pScreen, 0); #endif diff --git a/src/radeon_reg.h b/src/radeon_reg.h index 9ca6522..c5dca46 100644 --- a/src/radeon_reg.h +++ b/src/radeon_reg.h @@ -812,6 +812,7 @@ #define RADEON_HOST_DATA_LAST 0x17e0 #define RADEON_HOST_PATH_CNTL 0x0130 # define RADEON_HDP_SOFT_RESET (1 << 26) +# define RADEON_HDP_APER_CNTL (1 << 23) #define RADEON_HTOTAL_CNTL 0x0009 /* PLL */ #define RADEON_HTOTAL2_CNTL 0x002e /* PLL */ diff --git a/src/radeon_render.c b/src/radeon_render.c index 5f29157..0fab39f 100644 --- a/src/radeon_render.c +++ b/src/radeon_render.c @@ -315,29 +315,27 @@ static Bool RADEONSetupRenderByteswap(ScrnInfoPtr pScrn, int tex_bytepp) { RADEONInfoPtr info = RADEONPTR(pScrn); unsigned char *RADEONMMIO = info->MMIO; + CARD32 swapper = info->ModeReg.surface_cntl; + + swapper &= ~(RADEON_NONSURF_AP0_SWP_16BPP | RADEON_NONSURF_AP1_SWP_16BPP | + RADEON_NONSURF_AP0_SWP_32BPP | RADEON_NONSURF_AP1_SWP_32BPP); /* Set up byte swapping for the framebuffer aperture as needed */ switch (tex_bytepp) { case 1: - OUTREG(RADEON_SURFACE_CNTL, info->ModeReg.surface_cntl & - ~(RADEON_NONSURF_AP0_SWP_32BPP - | RADEON_NONSURF_AP0_SWP_16BPP)); break; case 2: - OUTREG(RADEON_SURFACE_CNTL, (info->ModeReg.surface_cntl & - ~RADEON_NONSURF_AP0_SWP_32BPP) - | RADEON_NONSURF_AP0_SWP_16BPP); + swapper |= RADEON_NONSURF_AP0_SWP_16BPP | RADEON_NONSURF_AP1_SWP_16BPP; break; case 4: - OUTREG(RADEON_SURFACE_CNTL, (info->ModeReg.surface_cntl & - ~RADEON_NONSURF_AP0_SWP_16BPP) - | RADEON_NONSURF_AP0_SWP_32BPP); + swapper |= RADEON_NONSURF_AP0_SWP_32BPP | RADEON_NONSURF_AP1_SWP_32BPP; break; default: xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "%s: Don't know what to do for " "tex_bytepp == %d!\n", __func__, tex_bytepp); return FALSE; } + OUTREG(RADEON_SURFACE_CNTL, swapper); return TRUE; } |