On Sun, Jan 15, 2006 at 08:51:52AM +0100, Elimar Riesebieter wrote: > How did you managed to apply that patch cleanly? There are much > FAILED when I try to apply it to the Debian source file.
I placed the patch under the patches directory, added an entry to the series file so it would be applied during the build and then made a changelog entry to affect the version string. I've attached a patch that should do all that: cd .../xorg-x11-6.9.0.dfsg.1/ patch -p0 < .../radeon-mem-map-debian.patch dpkg-buildpackage -rfakeroot Cheers, Kevin.
--- /dev/null 2006-01-16 07:15:51.148935250 +1030 +++ debian/patches/kmshanah/xorg-6.9-benh-radeon-mmap.diff 2006-01-14 11:16:21.000000000 +1030 @@ -0,0 +1,733 @@ +From: http://lists.freedesktop.org/archives/xorg/2005-December/011679.html + +Radeon mem map fix (#2): Need regression tests please +Benjamin Herrenschmidt benh at kernel.crashing.org +Sun Dec 18 22:36:38 PST 2005 + + * Previous message: Radeon mem map fix: Need regression tests please + * Next message: Radeon mem map fix (#2): Need regression tests please + * Messages sorted by: [ date ] [ thread ] [ subject ] [ author ] + +On Mon, 2005-12-19 at 17:07 +1100, Benjamin Herrenschmidt wrote: + +> I think I've get something in shape for getting the radeon memory map +> finally sane, removing all sort of hacks, and possibly fixing all sort +> of weird bugs. It works best with the very latest radeon DRM fixes to +> the same area but might well improve things all by itself + + .../... + +And here's a new rev. of the patch that fixes a couple more things. + +diff -urN xc.orig/programs/Xserver/hw/xfree86/drivers/ati/radeon.h xc/programs/Xserver/hw/xfree86/drivers/ati/radeon.h +--- xc.orig/programs/Xserver/hw/xfree86/drivers/ati/radeon.h 2005-12-15 16:53:42.000000000 +1100 ++++ xc/programs/Xserver/hw/xfree86/drivers/ati/radeon.h 2005-12-19 16:33:40.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 */ +diff -urN xc.orig/programs/Xserver/hw/xfree86/drivers/ati/radeon_cursor.c xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_cursor.c +--- xc.orig/programs/Xserver/hw/xfree86/drivers/ati/radeon_cursor.c 2005-12-15 16:53:42.000000000 +1100 ++++ xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_cursor.c 2005-12-19 14:30:41.000000000 +1100 +@@ -50,6 +50,7 @@ + + /* Driver data structures */ + #include "radeon.h" ++#include "radeon_version.h" + #include "radeon_reg.h" + #include "radeon_macros.h" + #include "radeon_mergedfb.h" +diff -urN xc.orig/programs/Xserver/hw/xfree86/drivers/ati/radeon_dri.c xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dri.c +--- xc.orig/programs/Xserver/hw/xfree86/drivers/ati/radeon_dri.c 2005-12-15 16:53:42.000000000 +1100 ++++ xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dri.c 2005-12-19 14:38:46.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); +diff -urN xc.orig/programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c +--- xc.orig/programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c 2005-12-15 16:53:43.000000000 +1100 ++++ xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c 2005-12-19 17:29:20.000000000 +1100 +@@ -129,6 +129,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 */ + +@@ -2252,83 +2254,92 @@ + 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); ++ /* If there is no room up there for at least 16Mb, put AGP down to ++ * 0x80000000. This is an arbitrary value that should be good enough. ++ * In the future, we might want to use the real gartSize that will be ++ * requested, but at least that will give us some breathing space with ++ * the default value ++ */ ++ if ((agp_base + 0x01000000) < info->fbLocation) ++ agp_base = 0x80000000u; + +- OUTREG (RADEON_BUS_CNTL, bus_cntl); +- RADEONWaitForIdleMMIO(pScrn); ++ /* 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; + +- /* Set display0/1 priority up on r3/4xx in the memory controller for +- * high res modes if the user specifies HIGH for displaypriority +- * option. ++ /* We may need to crop the AGP size. Hopefully, it will be changed later ++ * on by the DRI init again, but for now, it's the firmware setting which ++ * might overflow. + */ +- 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); +- } ++ while (agp_base > ((agp_base + agp_size) & 0xfffffffful)) ++ agp_size >>= 1; + ++ /* 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) +@@ -2704,22 +2715,28 @@ + + 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. +- */ ++ /* 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. I'm now _always_ setting ++ * RADEON_HOST_PATH_CNTL. ++ */ + 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)); +- } ++ if (pScrn->videoRam > 128*1024) ++ pScrn->videoRam = 128*1024; ++ OUTREGP (RADEON_HOST_PATH_CNTL, RADEON_HDP_APER_CNTL, ++ ~RADEON_HDP_APER_CNTL); + } + + /* 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; +@@ -5500,31 +5517,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, +@@ -5586,6 +5578,40 @@ + } + } + ++ 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); ++ } 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); +@@ -5600,11 +5626,6 @@ + "Depth moves disabled by default\n"); + } + +- hasDRI = info->directRenderingEnabled; +-#endif +- +- RADEONSetFBLocation(pScrn); +- + if (!fbScreenInit(pScreen, info->FB, + pScrn->virtualX, pScrn->virtualY, + pScrn->xDpi, pScrn->yDpi, pScrn->displayWidth, +@@ -5796,6 +5817,13 @@ + #endif /* USE_XAA */ + } + } ++ ++ /* 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->directRenderingEnabled) { + if ((info->DispPriority == 1) && (info->cardType==CARD_AGP)) { + /* we need to re-calculate bandwidth because of AGPMode difference. */ +@@ -5835,7 +5863,103 @@ + return TRUE; + } + +-/* Write common registers (initialized to 0) */ ++/* 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; ++ ++ /* Clear all surfaces */ ++ 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); ++ } ++ ++ /* 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); ++} ++ ++static void RADEONAdjustMemMapRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save) ++{ ++ RADEONInfoPtr info = RADEONPTR(pScrn); ++ unsigned char *RADEONMMIO = info->MMIO; ++ CARD32 fb, agp; ++ int fb_loc_changed; ++ ++ 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 */ + static void RADEONRestoreCommonRegisters(ScrnInfoPtr pScrn, + RADEONSavePtr restore) + { +@@ -5998,13 +6122,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); +@@ -6455,6 +6572,7 @@ + + /* 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); +@@ -6472,10 +6590,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); + +@@ -6486,15 +6606,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); +@@ -6504,6 +6623,7 @@ + info->IsSwitching) { + pRADEONEnt->IsSecondaryRestored = FALSE; + ++ RADEONRestoreCommonRegisters(pScrn, restore); + RADEONRestoreCrtcRegisters(pScrn, restore); + RADEONRestoreFPRegisters(pScrn, restore); + RADEONRestorePLLRegisters(pScrn, restore); +@@ -6518,6 +6638,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) + { +@@ -6701,6 +6834,7 @@ + RADEONInfoPtr info = RADEONPTR(pScrn); + + RADEONTRACE(("RADEONSaveMode(%p)\n", save)); ++ RADEONSaveMemMapRegisters(pScrn, save); + RADEONSaveCommonRegisters(pScrn, save); + if (info->IsSecondary) { + RADEONSaveCrtc2Registers(pScrn, save); +@@ -6729,6 +6863,7 @@ + + RADEONTRACE(("RADEONSave\n")); + if (info->FBDev) { ++ RADEONSaveMemMapRegisters(pScrn, save); + fbdevHWSave(pScrn); + return; + } +@@ -6912,6 +7047,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; + +@@ -7820,8 +7971,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; + +@@ -7885,8 +8037,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; + +@@ -8014,11 +8167,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, +@@ -8026,7 +8180,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; +@@ -8035,13 +8189,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; +@@ -8394,13 +8548,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 +diff -urN xc.orig/programs/Xserver/hw/xfree86/drivers/ati/radeon_reg.h xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_reg.h +--- xc.orig/programs/Xserver/hw/xfree86/drivers/ati/radeon_reg.h 2005-09-18 09:38:32.000000000 +1000 ++++ xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_reg.h 2005-12-19 17:27:24.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 */ + --- debian/patches/series.orig 2006-01-15 20:50:58.000000000 +1030 +++ debian/patches/series 2006-01-14 11:14:16.000000000 +1030 @@ -116,3 +116,4 @@ debian/916_add_XKBPATH_env_variable.diff debian/989_ubuntu_add_extra_modelines_from_xorg.diff -p0 debian/992_debian_allow_build_from_svn.diff +kmshanah/xorg-6.9-benh-radeon-mmap.diff -p0 --- debian/changelog.orig 2006-01-15 20:52:21.000000000 +1030 +++ debian/changelog 2006-01-14 11:24:07.000000000 +1030 @@ -1,3 +1,10 @@ +xorg-x11 (6.9.0.dfsg.1-3ks1) unstable; urgency=low + + [ Kevin Shanahan ] + * Add kmshanah/xorg-6.9-benh-radeon-mmap.diff + + -- Kevin Shanahan <[EMAIL PROTECTED]> Sat, 14 Jan 2006 11:23:26 +1030 + xorg-x11 (6.9.0.dfsg.1-3) unstable; urgency=low [ Denis Barbier ]