[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#345729: Possible fix



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 <kmshanah@disenchant.net>  Sat, 14 Jan 2006 11:23:26 +1030
+
 xorg-x11 (6.9.0.dfsg.1-3) unstable; urgency=low
 
   [ Denis Barbier ]

Reply to: