Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 8 Feb 2006 20:31:53 +0100
From:      Dejan Lesjak <dejan.lesjak@ijs.si>
To:        freebsd-x11@freebsd.org
Cc:        g@esil.univ-mrs.fr, freebsd-stable@freebsd.org
Subject:   Re: BIG BIG problem with Xorg and... something else...
Message-ID:  <200602082031.55437.dejan.lesjak@ijs.si>
In-Reply-To: <1139346643.43e90cd3266be@webmail.esil.univ-mrs.fr>
References:  <1139346643.43e90cd3266be@webmail.esil.univ-mrs.fr>

next in thread | previous in thread | raw e-mail | index | archive | help
--Boundary-00=_rck6DQ8WszH7r8F
Content-Type: text/plain;
  charset="iso-8859-1"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

On Tuesday 07 February 2006 22:10, g@esil.univ-mrs.fr wrote:
> Hi all,
>
>    First don't blame me for cross-posting on stable and x11 lists but both
> seem relevant for my problem.
>
>    I'm tracking 6-STABLE. Since one week, I can't use my computer under
> FreeBSD. The boot is OK, xdm screen is OK. But if I launch a KDE session,
> I've some color problems during initializing session, then X freezes
> (before end of loading !!!) and the only way is to poweroff the computer
> !!! No ssh, no way to CTRL-ALT F1 switching to a console screen, the box is
> down...
>
>    I've googled a lot before posting here, but I've found nothing to rescue
> me... Best idea : problems with the video card (ATI Radeon X300 on DELL
> Optiplex GX280, or, in xorg language :
> (--) PCI:*(1:0:0) ATI Technologies Inc RV370 5B60 [Radeon X300 (PCIE)]
> PCI: (1:0:1) ATI Technologies Inc RV370 [Radeon X300SE])
>  are mentioned on some forums which freeze X, but only if DRI & GLX are
> enabled. I've disabled these modules.
>
>    Note I can have a text mode session without any problem in console mode
> if I CTRL-ALT-F1 switch without xdm logon. I also can have a windowmaker
> session until I don't launch a "bad" app... like firefox or any kde
> component. I can use gftp which is OpenMotif based...
>
>    I mail you from my box... but inside an XFCE FreesBie live CD session,
> which is 5.3 release based and runs like a charm : no X problem (like me
> during last year from 5.3 STABLE to 6-STABLE until previous week...). WXP
> runs without problem on another slice... So I think I can exclude hardware
> dysfunction...
>
>     The problem begins before I upgrade to KDE 3.5 and xorg 6.9. The
> upgrade has had no effect... I've sync my sources two days ago : no
> effect...
>
>     I don't know what to do ? No log, no coredump... Any idea ???
>
>    My xorg.conf (and also an uncommented version), Xorg.0.log (X.org 6.9)
> and older Xorg.8.log (Xorg 6.8, before the problem)  are viewable here :
> http://www.esil.univ-mrs.fr/~g/FreeBSD-x-problem.
>
>     Thanks a lot in advance for any idea, comment, explanation, light,
> incantation, etc.

Can you try the attached patch for xorg-server port?

--Boundary-00=_rck6DQ8WszH7r8F
Content-Type: text/x-diff; charset="iso-8859-1"; name="xo-radeon-mmap.patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
	filename="xo-radeon-mmap.patch"

Index: Makefile
===================================================================
RCS file: /usr/local/repos/freebsd/ports/x11-servers/xorg-server/Makefile,v
retrieving revision 1.33
diff -u -r1.33 Makefile
--- Makefile	21 Jan 2006 18:55:07 -0000	1.33
+++ Makefile	2 Feb 2006 15:21:15 -0000
@@ -7,6 +7,7 @@
 
 PORTNAME=	xorg-server
 PORTVERSION=	6.9.0
+PORTREVISION=	1
 CATEGORIES=	x11-servers
 MASTER_SITES=	${MASTER_SITE_XORG}
 MASTER_SITE_SUBDIR=	X11R${PORTVERSION}/src
Index: files/patch-radeon-memmap
===================================================================
RCS file: files/patch-radeon-memmap
diff -N files/patch-radeon-memmap
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ files/patch-radeon-memmap	2 Feb 2006 15:31:54 -0000
@@ -0,0 +1,1547 @@
+--- programs/Xserver/hw/xfree86/drivers/ati/radeon.h.orig	Wed Nov  9 08:30:03 2005
++++ programs/Xserver/hw/xfree86/drivers/ati/radeon.h	Thu Feb  2 16:15:03 2006
+@@ -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;
+--- programs/Xserver/hw/xfree86/drivers/ati/radeon_common.h.orig	Sun Sep 11 10:51:38 2005
++++ programs/Xserver/hw/xfree86/drivers/ati/radeon_common.h	Thu Feb  2 16:15:03 2006
+@@ -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
+  */
+--- programs/Xserver/hw/xfree86/drivers/ati/radeon_commonfuncs.c.orig	Sun Sep 11 22:58:53 2005
++++ programs/Xserver/hw/xfree86/drivers/ati/radeon_commonfuncs.c	Thu Feb  2 16:15:03 2006
+@@ -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);
+--- programs/Xserver/hw/xfree86/drivers/ati/radeon_cursor.c.orig	Tue Nov  8 10:44:41 2005
++++ programs/Xserver/hw/xfree86/drivers/ati/radeon_cursor.c	Thu Feb  2 16:15:03 2006
+@@ -31,6 +31,9 @@
+ #include "config.h"
+ #endif
+ 
++#define RADEONCTRACE(x)
++/* #define RADEONCTRACE(x) RADEONTRACE(x) */
++
+ /*
+  * Authors:
+  *   Kevin E. Martin <martin@xfree86.org>
+@@ -50,6 +53,7 @@
+ 
+ 				/* Driver data structures */
+ #include "radeon.h"
++#include "radeon_version.h"
+ #include "radeon_reg.h"
+ #include "radeon_macros.h"
+ #include "radeon_mergedfb.h"
+@@ -81,11 +85,11 @@
+ #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
+--- programs/Xserver/hw/xfree86/drivers/ati/radeon_dri.c.orig	Fri Oct 21 20:40:18 2005
++++ programs/Xserver/hw/xfree86/drivers/ati/radeon_dri.c	Thu Feb  2 16:15:03 2006
+@@ -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,
+--- programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c.orig	Wed Dec 14 20:41:19 2005
++++ programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c	Thu Feb  2 16:15:03 2006
+@@ -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 */
+ 
+@@ -732,6 +734,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,
+@@ -2252,83 +2255,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)
+@@ -2704,22 +2704,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;
+@@ -5095,7 +5121,7 @@
+     RADEONInfoPtr  info    = RADEONPTR(pScrn);
+ 
+ #ifdef XF86DRI
+-    if (info->directRenderingEnabled) {
++    if (info->directRenderingInited) {
+ 	FLUSH_RING();
+     }
+ #endif
+@@ -5453,8 +5479,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;
+@@ -5502,31 +5530,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,
+@@ -5588,6 +5591,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);
+@@ -5602,11 +5640,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,
+@@ -5653,6 +5695,9 @@
+     }
+ #endif
+ 				/* Memory manager setup */
++
++    RADEONTRACE(("Setting up accel memmap\n"));
++
+ #ifdef USE_EXA
+     if (info->useEXA && !RADEONSetupMemEXA(pScreen))
+ 	return FALSE;
+@@ -5671,8 +5716,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;
+@@ -5687,12 +5821,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);
+@@ -5729,115 +5879,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)
+ {
+@@ -6000,13 +6152,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);
+@@ -6255,6 +6400,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.
+@@ -6273,6 +6447,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) {
+@@ -6305,8 +6482,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;
+@@ -6327,31 +6505,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) ||
+@@ -6372,16 +6550,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);
+@@ -6391,6 +6569,9 @@
+ 		surf_info, 0, bufferSize - 1024);*/
+ 	}
+     }
++
++    /* Update surface images */
++    RADEONSaveSurfaces(pScrn, &info->ModeReg);
+ }
+ 
+ #if 0
+@@ -6419,35 +6600,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)
+ {
+@@ -6455,8 +6607,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);
+@@ -6474,10 +6629,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);
+ 
+@@ -6488,15 +6645,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);
+@@ -6506,6 +6662,7 @@
+ 	    info->IsSwitching) {
+ 	    pRADEONEnt->IsSecondaryRestored = FALSE;
+ 
++	    RADEONRestoreCommonRegisters(pScrn, restore);
+ 	    RADEONRestoreCrtcRegisters(pScrn, restore);
+ 	    RADEONRestoreFPRegisters(pScrn, restore);
+ 	    RADEONRestorePLLRegisters(pScrn, restore);
+@@ -6520,6 +6677,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)
+ {
+@@ -6703,6 +6873,7 @@
+     RADEONInfoPtr  info = RADEONPTR(pScrn);
+ 
+     RADEONTRACE(("RADEONSaveMode(%p)\n", save));
++    RADEONSaveMemMapRegisters(pScrn, save);
+     RADEONSaveCommonRegisters(pScrn, save);
+     if (info->IsSecondary) {
+ 	RADEONSaveCrtc2Registers(pScrn, save);
+@@ -6731,6 +6902,7 @@
+ 
+     RADEONTRACE(("RADEONSave\n"));
+     if (info->FBDev) {
++	RADEONSaveMemMapRegisters(pScrn, save);
+ 	fbdevHWSave(pScrn);
+ 	return;
+     }
+@@ -6914,6 +7086,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; 
+ 
+@@ -7822,8 +8010,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;
+ 
+@@ -7887,8 +8076,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;
+ 
+@@ -8016,11 +8206,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, 
+@@ -8028,7 +8219,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;
+@@ -8037,13 +8228,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;
+@@ -8079,6 +8270,8 @@
+ {
+     RADEONInfoPtr  info = RADEONPTR(pScrn);
+ 
++    RADEONTRACE(("RADEONModeInit()\n"));
++
+     if (!RADEONInit(pScrn, mode, &info->ModeReg)) return FALSE;
+ 
+     pScrn->vtSema = TRUE;
+@@ -8099,6 +8292,8 @@
+     ScrnInfoPtr  pScrn = xf86Screens[pScreen->myNum];
+     Bool         unblank;
+ 
++    RADEONTRACE(("RADEONSaveScreen(%d)\n", mode));
++
+     unblank = xf86IsUnblank(mode);
+     if (unblank) SetTimeSinceLastInputEvent();
+ 
+@@ -8124,6 +8319,8 @@
+     }
+ #endif
+ 
++    RADEONTRACE(("RADEONSwitchMode() !n"));
++
+     if (info->allowColorTiling) {
+ 	if (info->MergedFB) {
+ 	    if ((((RADEONMergedDisplayModePtr)mode->Private)->CRT1->Flags &
+@@ -8237,6 +8434,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);
+@@ -8300,7 +8499,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
+@@ -8328,11 +8527,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);
+     }
+ 
+@@ -8396,13 +8599,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
+@@ -8436,7 +8639,7 @@
+ 
+     RADEONTRACE(("RADEONLeaveVT\n"));
+ #ifdef XF86DRI
+-    if (RADEONPTR(pScrn)->directRenderingEnabled) {
++    if (RADEONPTR(pScrn)->directRenderingInited) {
+ 	DRILock(pScrn->pScreen, 0);
+ 	RADEONCP_STOP(pScrn, info);
+     }
+@@ -8451,9 +8654,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
+@@ -8467,11 +8670,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
+ 
+@@ -8486,8 +8695,8 @@
+ 	RADEONDisplayPowerManagementSet(pScrn, DPMSModeOn, 0);
+ 	RADEONRestore(pScrn);
+     }
+-    RADEONUnmapMem(pScrn);
+ 
++    RADEONTRACE(("Disposing accel...\n"));
+ #ifdef USE_EXA
+     if (info->useEXA && info->accelOn)
+ 	exaDriverFini(pScreen);
+@@ -8504,12 +8713,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);
+@@ -8646,6 +8860,8 @@
+     unsigned char *RADEONMMIO = info->MMIO;
+ 
+     if (!pScrn->vtSema) return;
++
++    RADEONTRACE(("RADEONDisplayPowerManagementSet(%d,0x%x)\n", PowerManagementMode, flags));
+ 
+ #ifdef XF86DRI
+     if (info->CPStarted) DRILock(pScrn->pScreen, 0);
+--- programs/Xserver/hw/xfree86/drivers/ati/radeon_reg.h.orig	Sat Sep 17 09:47:51 2005
++++ programs/Xserver/hw/xfree86/drivers/ati/radeon_reg.h	Thu Feb  2 16:15:03 2006
+@@ -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 */
+ 
+--- programs/Xserver/hw/xfree86/drivers/ati/radeon_render.c.orig	Fri Dec  9 19:15:31 2005
++++ programs/Xserver/hw/xfree86/drivers/ati/radeon_render.c	Thu Feb  2 16:15:03 2006
+@@ -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;
+ }
+ 

--Boundary-00=_rck6DQ8WszH7r8F--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200602082031.55437.dejan.lesjak>