diff -urN xf86-video-ati.orig/src/radeon.h xf86-video-ati/src/radeon.h --- xf86-video-ati.orig/src/radeon.h 2006-01-09 06:02:16.000000000 +1100 +++ xf86-video-ati/src/radeon.h 2006-01-25 23:27:05.000000000 +1100 @@ -102,7 +102,7 @@ /* ------------------------------------- */ -#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 @@ */ #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 @@ 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 @@ 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 @@ 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 @@ #ifdef XF86DRI Bool noBackBuffer; Bool directRenderingEnabled; + Bool directRenderingInited; DRIInfoPtr pDRIInfo; int drmFD; int numVisualConfigs; diff -urN xf86-video-ati.orig/src/radeon_common.h xf86-video-ati/src/radeon_common.h --- xf86-video-ati.orig/src/radeon_common.h 2005-09-11 18:51:38.000000000 +1000 +++ xf86-video-ati/src/radeon_common.h 2006-01-25 19:37:41.000000000 +1100 @@ -474,6 +474,7 @@ #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 -urN xf86-video-ati.orig/src/radeon_commonfuncs.c xf86-video-ati/src/radeon_commonfuncs.c --- xf86-video-ati.orig/src/radeon_commonfuncs.c 2005-09-12 06:58:53.000000000 +1000 +++ xf86-video-ati/src/radeon_commonfuncs.c 2006-01-25 22:50:36.000000000 +1100 @@ -155,9 +155,11 @@ } #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 -urN xf86-video-ati.orig/src/radeon_cursor.c xf86-video-ati/src/radeon_cursor.c --- xf86-video-ati.orig/src/radeon_cursor.c 2005-11-08 20:44:41.000000000 +1100 +++ xf86-video-ati/src/radeon_cursor.c 2006-01-26 10:35:37.000000000 +1100 @@ -31,6 +31,9 @@ #include "config.h" #endif +#define RADEONCTRACE(x) +//#define RADEONCTRACE(x) RADEONTRACE(x) + /* * Authors: * Kevin E. Martin @@ -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 @@ #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 @@ "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 @@ 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 @@ 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 @@ 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 @@ 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 @@ */ 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 @@ 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 @@ 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 @@ 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 @@ 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 -urN xf86-video-ati.orig/src/radeon_dri.c xf86-video-ati/src/radeon_dri.c --- xf86-video-ati.orig/src/radeon_dri.c 2005-10-22 04:40:18.000000000 +1000 +++ xf86-video-ati/src/radeon_dri.c 2006-01-25 15:49:05.000000000 +1100 @@ -1456,10 +1456,6 @@ 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 @@ info->allowPageFlip = 0; } + info->directRenderingInited = TRUE; + return TRUE; } @@ -1665,7 +1663,9 @@ 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 @@ 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 @@ #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 -urN xf86-video-ati.orig/src/radeon_driver.c xf86-video-ati/src/radeon_driver.c --- xf86-video-ati.orig/src/radeon_driver.c 2006-01-25 11:04:45.000000000 +1100 +++ xf86-video-ati/src/radeon_driver.c 2006-01-26 10:27:08.000000000 +1100 @@ -130,6 +130,8 @@ 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 @@ 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,80 @@ 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; + { + CARD32 aper0_base = INREG(RADEON_CONFIG_APER_0_BASE); - 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; + info->mc_fb_location = (aper0_base >> 16) | + ((aper0_base + mem_size - 1) & 0xffff0000U); + } } + info->fbLocation = (info->mc_fb_location & 0xffff) << 16; - RADEONWaitForIdleMMIO(pScrn); + /* Calculate AGP aperture location */ + agp_size = ((info->mc_agp_location >> 16) - + (info->mc_agp_location & 0xffff) + 1) << 16; + agp_base = info->fbLocation + mem_size; - 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); + /* Make sure AGP size is at least 4Mb for the sake of the memory mapping + * (even if we don't actually use it, to avoid leaving a dangling map + * or invalid setting in MC_AGP_LOCATION + */ + if (agp_size < 0x400000) + agp_size = 0x400000; - OUTREG (RADEON_BUS_CNTL, bus_cntl); - RADEONWaitForIdleMMIO(pScrn); + /* If there is no room up there put AGP just below the fb */ + if (((agp_base + agp_size) & 0xfffffffful) < agp_base) + agp_base = info->fbLocation - agp_size; - /* 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); - } + /* Ok, now set our various bits & pieces */ + info->mc_agp_location = (agp_base >> 16) | + ((agp_base + agp_size - 1) & 0xffff0000U); + 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) @@ -2705,22 +2705,48 @@ 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_mem = INREG(RADEON_CONFIG_APER_SIZE) / 1024; + + /* 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. + * + * The above doesn't necessarily work. For example, I've seen machines + * with 128Mb configured as 2x64Mb apertures. However, if I always set + * HDP_APER_CNTL, it seems PCI access stops working on some cards :( + * Let's just read the setting and check how much we can access... + */ pScrn->videoRam = INREG(RADEON_CONFIG_MEMSIZE) / 1024; - if (pScrn->videoRam > 128*1024) pScrn->videoRam = 128*1024; + + /* We used to limit to 128M ... let's keep that for now until I have + * verified that my new code might lift that limitation + */ + if (pScrn->videoRam > 128*1024) + pScrn->videoRam = 128*1024; + + /* Now, set HDP_APER_CNTL only on some cards as Hui original code does */ 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)); - } + (info->ChipFamily == CHIP_FAMILY_R420)) + OUTREGP (RADEON_HOST_PATH_CNTL, RADEON_HDP_APER_CNTL, + ~RADEON_HDP_APER_CNTL); + + /* Now, read that bit. If it's set, double the accessible memory */ + if (INREG(RADEON_HOST_PATH_CNTL) & RADEON_HDP_APER_CNTL) + accessible_mem *= 2; + + /* Now trim videoRam if necessary */ + if (pScrn->videoRam > accessible_mem) + pScrn->videoRam = accessible_mem; } /* Some production boards of m6 will return 0 if it's 8 MB */ - if (pScrn->videoRam == 0) pScrn->videoRam = 8192; + if (pScrn->videoRam == 0) { + pScrn->videoRam = 8192; + OUTREG(RADEON_CONFIG_MEMSIZE, 0x800000); + } /* Check chip errata */ info->ChipErrata = 0; @@ -5097,7 +5123,7 @@ RADEONInfoPtr info = RADEONPTR(pScrn); #ifdef XF86DRI - if (info->directRenderingEnabled) { + if (info->directRenderingInited) { FLUSH_RING(); } #endif @@ -5455,8 +5481,10 @@ 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 +5532,6 @@ 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 +5593,41 @@ } } + 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 +5642,15 @@ "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 +5697,9 @@ } #endif /* Memory manager setup */ + + RADEONTRACE(("Setting up accel memmap\n")); + #ifdef USE_EXA if (info->useEXA && !RADEONSetupMemEXA(pScreen)) return FALSE; @@ -5673,8 +5718,97 @@ 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); + + /* Colormap setup */ + RADEONTRACE(("Initializing color map\n")); + if (!miCreateDefColormap(pScreen)) return FALSE; + if (!xf86HandleColormaps(pScreen, 256, info->dac6bits ? 6 : 8, + RADEONLoadPalette, NULL, + CMAP_PALETTED_TRUECOLOR +#if 0 /* This option messes up text mode! (eich@suse.de) */ + | CMAP_LOAD_EVEN_IF_OFFSCREEN +#endif + | CMAP_RELOAD_ON_MODE_SWITCH)) return FALSE; + + /* DPMS setup */ + /* 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 +5823,28 @@ info->accelOn = FALSE; } + /* Init DPMS */ + RADEONTRACE(("Initializing DPMS\n")); + xf86DPMSInit(pScreen, RADEONDisplayPowerManagementSet, 0); + /* DGA setup */ + RADEONTRACE(("Initializing DGA\n")); RADEONDGAInit(pScreen); - /* Backing store setup */ - miInitializeBackingStore(pScreen); - xf86SetBackingStore(pScreen); + /* Wrap some funcs for MergedFB */ + if(info->MergedFB) { + info->PointerMoved = pScrn->PointerMoved; + pScrn->PointerMoved = RADEONMergePointerMoved; + /* Psuedo xinerama */ + if(info->UseRADEONXinerama) { + RADEONnoPanoramiXExtension = FALSE; + RADEONXineramaExtensionInit(pScrn); + } else { + info->MouseRestrictions = FALSE; + } + } + + RADEONTRACE(("Initializing Cursor\n")); /* Set Silken Mouse */ xf86SetSilkenMouse(pScreen); @@ -5731,115 +5881,117 @@ xf86DrvMsg(scrnIndex, X_INFO, "Using software cursor\n"); } - /* Colormap setup */ - if (!miCreateDefColormap(pScreen)) return FALSE; - if (!xf86HandleColormaps(pScreen, 256, info->dac6bits ? 6 : 8, - RADEONLoadPalette, NULL, - CMAP_PALETTED_TRUECOLOR -#if 0 /* This option messes up text mode! (eich@suse.de) */ - | CMAP_LOAD_EVEN_IF_OFFSCREEN -#endif - | CMAP_RELOAD_ON_MODE_SWITCH)) return FALSE; - - /* DPMS setup */ - xf86DPMSInit(pScreen, RADEONDisplayPowerManagementSet, 0); - + /* Init Xv */ + RADEONTRACE(("Initializing Xv\n")); RADEONInitVideo(pScreen); - /* Provide SaveScreen */ - pScreen->SaveScreen = RADEONSaveScreen; - - /* Wrap CloseScreen */ + /* 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; - /* Wrap some funcs for MergedFB */ - if(info->MergedFB) { - info->PointerMoved = pScrn->PointerMoved; - pScrn->PointerMoved = RADEONMergePointerMoved; - /* Psuedo xinerama */ - if(info->UseRADEONXinerama) { - RADEONnoPanoramiXExtension = FALSE; - RADEONXineramaExtensionInit(pScrn); - } else { - info->MouseRestrictions = FALSE; - } - } - - /* Note unused options */ + /* 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; - } else { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Direct rendering disabled\n"); - } -#endif + 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; - if (!info->IsSecondary) - RADEONChangeSurfaces(pScrn); + RADEONTRACE((" Map Changed ! Applying ...\n")); - if(info->MergedFB) { - /* need this here to fix up sarea values */ - RADEONAdjustFrameMerged(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); + /* 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; + + /* 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); } + + /* 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); +} - info->BlockHandler = pScreen->BlockHandler; - pScreen->BlockHandler = RADEONBlockHandler; +static void RADEONAdjustMemMapRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + CARD32 fb, agp; + int fb_loc_changed; - return TRUE; + fb = INREG(RADEON_MC_FB_LOCATION); + agp = INREG(RADEON_MC_AGP_LOCATION); + fb_loc_changed = (fb != info->mc_fb_location); + + 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; + + 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) { @@ -6002,13 +6154,6 @@ OUTREG(RADEON_FP_VERT_STRETCH, restore->fp_vert_stretch); OUTREG(RADEON_FP_GEN_CNTL, restore->fp_gen_cntl); - /* old AIW Radeon has some BIOS initialization problem - * with display buffer underflow, only occurs to DFP - */ - if (!info->HasCRTC2) - OUTREG(RADEON_GRPH_BUFFER_CNTL, - INREG(RADEON_GRPH_BUFFER_CNTL) & ~0x7f0000); - if (info->IsMobility) { OUTREG(RADEON_BIOS_4_SCRATCH, restore->bios_4_scratch); OUTREG(RADEON_BIOS_5_SCRATCH, restore->bios_5_scratch); @@ -6257,6 +6402,35 @@ ~(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 +6449,9 @@ + 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 +6484,9 @@ 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 +6507,31 @@ &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 +6552,16 @@ } 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 +6571,9 @@ surf_info, 0, bufferSize - 1024);*/ } } + + /* Update surface images */ + RADEONSaveSurfaces(pScrn, &info->ModeReg); } #if 0 @@ -6421,35 +6602,6 @@ } #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 +6609,11 @@ 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 +6631,12 @@ * 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 +6647,14 @@ 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 +6664,7 @@ info->IsSwitching) { pRADEONEnt->IsSecondaryRestored = FALSE; + RADEONRestoreCommonRegisters(pScrn, restore); RADEONRestoreCrtcRegisters(pScrn, restore); RADEONRestoreFPRegisters(pScrn, restore); RADEONRestorePLLRegisters(pScrn, restore); @@ -6522,6 +6679,19 @@ #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 +6875,7 @@ RADEONInfoPtr info = RADEONPTR(pScrn); RADEONTRACE(("RADEONSaveMode(%p)\n", save)); + RADEONSaveMemMapRegisters(pScrn, save); RADEONSaveCommonRegisters(pScrn, save); if (info->IsSecondary) { RADEONSaveCrtc2Registers(pScrn, save); @@ -6733,6 +6904,7 @@ RADEONTRACE(("RADEONSave\n")); if (info->FBDev) { + RADEONSaveMemMapRegisters(pScrn, save); fbdevHWSave(pScrn); return; } @@ -6916,6 +7088,22 @@ 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 +8012,9 @@ } /* 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 +8078,9 @@ } /* 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 +8208,12 @@ 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 +8221,7 @@ 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 +8230,13 @@ 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 +8272,8 @@ { RADEONInfoPtr info = RADEONPTR(pScrn); + RADEONTRACE(("RADEONModeInit()\n")); + if (!RADEONInit(pScrn, mode, &info->ModeReg)) return FALSE; pScrn->vtSema = TRUE; @@ -8101,6 +8294,8 @@ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; Bool unblank; + RADEONTRACE(("RADEONSaveScreen(%d)\n", mode)); + unblank = xf86IsUnblank(mode); if (unblank) SetTimeSinceLastInputEvent(); @@ -8126,6 +8321,8 @@ } #endif + RADEONTRACE(("RADEONSwitchMode() !n")); + if (info->allowColorTiling) { if (info->MergedFB) { if ((((RADEONMergedDisplayModePtr)mode->Private)->CRT1->Flags & @@ -8239,6 +8436,8 @@ 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 +8501,7 @@ 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 +8529,15 @@ } #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); } @@ -8398,13 +8601,13 @@ } 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 */ RADEONDRIResume(pScrn->pScreen); + RADEONAdjustMemMapRegisters(pScrn, &info->ModeReg); } #endif /* this will get XVideo going again, but only if XVideo was initialised @@ -8438,7 +8641,7 @@ RADEONTRACE(("RADEONLeaveVT\n")); #ifdef XF86DRI - if (RADEONPTR(pScrn)->directRenderingEnabled) { + if (RADEONPTR(pScrn)->directRenderingInited) { DRILock(pScrn->pScreen, 0); RADEONCP_STOP(pScrn, info); } @@ -8453,9 +8656,9 @@ 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 +8672,17 @@ 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 +8697,8 @@ RADEONDisplayPowerManagementSet(pScrn, DPMSModeOn, 0); RADEONRestore(pScrn); } - RADEONUnmapMem(pScrn); + RADEONTRACE(("Disposing accel...\n")); #ifdef USE_EXA if (info->useEXA && info->accelOn) exaDriverFini(pScreen); @@ -8506,12 +8715,17 @@ } #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 +8863,8 @@ if (!pScrn->vtSema) return; + RADEONTRACE(("RADEONDisplayPowerManagementSet(%d,0x%x)\n", PowerManagementMode, flags)); + #ifdef XF86DRI if (info->CPStarted) DRILock(pScrn->pScreen, 0); #endif diff -urN xf86-video-ati.orig/src/radeon_reg.h xf86-video-ati/src/radeon_reg.h --- xf86-video-ati.orig/src/radeon_reg.h 2005-09-17 17:47:51.000000000 +1000 +++ xf86-video-ati/src/radeon_reg.h 2006-01-10 17:17:06.000000000 +1100 @@ -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 -urN xf86-video-ati.orig/src/radeon_render.c xf86-video-ati/src/radeon_render.c --- xf86-video-ati.orig/src/radeon_render.c 2005-12-10 05:15:31.000000000 +1100 +++ xf86-video-ati/src/radeon_render.c 2006-01-26 00:19:45.000000000 +1100 @@ -315,29 +315,27 @@ { 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; }