xf86-video-intel: 21 commits - configure.ac src/bios_reader/bios_reader.c src/bios_reader/swf_dumper.c src/common.h src/drmmode_display.c src/drmmode_display.h src/i830_accel.c src/i830_batchbuffer.h src/i830_bios.c src/i830_dri.c src/i830_driver.c src/i830_exa.c src/i830.h src/i830_memory.c src/i830_video.c src/i965_render.c src/Makefile.am src/reg_dumper/reg_dumper.h

Jesse Barnes jbarnes at kemper.freedesktop.org
Thu Aug 21 09:42:07 PDT 2008


 configure.ac                  |   13 
 src/Makefile.am               |    4 
 src/bios_reader/bios_reader.c |    2 
 src/bios_reader/swf_dumper.c  |    2 
 src/common.h                  |    4 
 src/drmmode_display.c         |  703 ++++++++++++++++++++++++++
 src/drmmode_display.h         |   73 ++
 src/i830.h                    |   20 
 src/i830_accel.c              |    2 
 src/i830_batchbuffer.h        |    6 
 src/i830_bios.c               |    6 
 src/i830_dri.c                |   39 +
 src/i830_driver.c             | 1127 ++++++++++++++++++++++++------------------
 src/i830_exa.c                |  211 +++++++
 src/i830_memory.c             |  242 +++++++--
 src/i830_video.c              |    2 
 src/i965_render.c             |   20 
 src/reg_dumper/reg_dumper.h   |    1 
 18 files changed, 1915 insertions(+), 562 deletions(-)

New commits:
commit 7a5b090abc39c380955489bad5e46d1278f38fee
Author: Jesse Barnes <jbarnes at virtuousgeek.org>
Date:   Thu Aug 21 09:40:57 2008 -0700

    Hide kernel mode setting EXA code behind XF86DRM_MODE
    
    Prevents compiler warnings in the non-kms case.

diff --git a/src/i830_exa.c b/src/i830_exa.c
index 9ba8df9..e73bc36 100644
--- a/src/i830_exa.c
+++ b/src/i830_exa.c
@@ -467,6 +467,8 @@ i830_transform_is_affine (PictTransformPtr t)
 
 static DevPrivateKey exa_pixmap_key = &exa_pixmap_key;
 
+#ifdef XF86DRM_MODE
+
 static void *
 I830EXACreatePixmap(ScreenPtr screen, int size, int align)
 {
@@ -608,6 +610,7 @@ static Bool I830EXAModifyPixmapHeader(PixmapPtr pPix, int width, int height,
     return FALSE;
 }
 
+#endif /* XF86DRM_MODE */
 
 Bool
 I830EXAInit(ScreenPtr pScreen)
@@ -650,6 +653,7 @@ I830EXAInit(ScreenPtr pScreen)
 	}
 	pI830->EXADriverPtr->flags = EXA_OFFSCREEN_PIXMAPS;
     } else {
+#ifdef XF86DRM_MODE
 	pI830->EXADriverPtr->flags = EXA_OFFSCREEN_PIXMAPS | EXA_HANDLES_PIXMAPS;
 	pI830->EXADriverPtr->PrepareAccess = I830EXAPrepareAccess;
 	pI830->EXADriverPtr->FinishAccess = I830EXAFinishAccess;
@@ -659,6 +663,7 @@ I830EXAInit(ScreenPtr pScreen)
 	pI830->EXADriverPtr->PixmapIsOffscreen = I830EXAPixmapIsOffscreen;
 	pI830->EXADriverPtr->ModifyPixmapHeader = I830EXAModifyPixmapHeader;
 #endif
+#endif /* XF86DRM_MODE */
     }
 
     DPRINTF(PFX, "EXA Mem: memoryBase 0x%x, end 0x%x, offscreen base 0x%x, "
commit 4937b98981923c599786f5007ab0580ad08e1909
Author: Jesse Barnes <jbarnes at virtuousgeek.org>
Date:   Thu Aug 21 09:39:33 2008 -0700

    Fix compiler warnings in VBIOS utils

diff --git a/src/bios_reader/bios_reader.c b/src/bios_reader/bios_reader.c
index ba773cc..9e05317 100644
--- a/src/bios_reader/bios_reader.c
+++ b/src/bios_reader/bios_reader.c
@@ -284,7 +284,7 @@ int main(int argc, char **argv)
     dump_general_features(find_section(bdb, BDB_GENERAL_FEATURES));
     dump_general_definitions(find_section(bdb, BDB_GENERAL_DEFINITIONS));
     dump_lvds_options(find_section(bdb, BDB_LVDS_OPTIONS));
-    dump_lvds_data(find_section(bdb, BDB_LVDS_LFP_DATA), bdb);
+    dump_lvds_data(find_section(bdb, BDB_LVDS_LFP_DATA), (unsigned char *)bdb);
 
     return 0;
 }
diff --git a/src/bios_reader/swf_dumper.c b/src/bios_reader/swf_dumper.c
index 5d48634..a6cf046 100644
--- a/src/bios_reader/swf_dumper.c
+++ b/src/bios_reader/swf_dumper.c
@@ -51,11 +51,13 @@ static uint32_t read32(void *base, int reg)
     return *addr;
 }
 
+#if 0
 static void write32(void *base, int reg, uint32_t val)
 {
     uint32_t *addr = (uint32_t *)((unsigned char *)(base) + reg);
     *addr = val;
 }
+#endif
 
 static void usage(void)
 {
commit 08326827fdb8abecbff20c7b051537dbad433c40
Merge: 5af5041... 0de8ca3...
Author: Jesse Barnes <jbarnes at virtuousgeek.org>
Date:   Thu Aug 21 09:30:38 2008 -0700

    Merge branch 'modesetting-gem'

commit 0de8ca36306c506356e82d500134b4eeb96a6080
Merge: f26bcb9... 5eccb5e...
Author: Jesse Barnes <jbarnes at virtuousgeek.org>
Date:   Wed Aug 20 12:11:00 2008 -0700

    Merge branch 'master' into modesetting-gem
    
    Conflicts:
    
    	configure.ac

diff --cc configure.ac
index 87dad69,47f7fe2..e6a2f6f
--- a/configure.ac
+++ b/configure.ac
@@@ -92,11 -91,7 +92,11 @@@ drm_cflags=$(pkg-config --cflags libdrm
  # Checks for header files.
  AC_HEADER_STDC
  
 +save_CFLAGS="$CFLAGS"
 +CFLAGS="$XORG_CFLAGS $DRI_CFLAGS $drm_cflags"
 +CPPFLAGS="$XORG_CFLAGS $DRI_CFLAGS $drm_cflags"
 +AC_MSG_CHECKING([whether to include DRI support])
- if test x$DRI = xauto; then
+ if test x$DRI != xno; then
          AC_CHECK_FILE([${sdkdir}/dri.h],
                        [have_dri_h="yes"], [have_dri_h="no"])
          AC_CHECK_FILE([${sdkdir}/sarea.h],
@@@ -105,13 -100,9 +105,15 @@@
                        [have_dristruct_h="yes"], [have_dristruct_h="no"])
  	AC_CHECK_FILE([${sdkdir}/damage.h],
                        [have_damage_h="yes"], [have_damage_h="no"])
 +	AC_CHECK_HEADER(xf86drmMode.h,
 +			[DRM_MODE=yes],[DRM_MODE=no]
 +			[#include "stdint.h"])
 +	if test "x$DRM_MODE" = xyes; then
 +	   	AC_DEFINE(XF86DRM_MODE,1,[DRM kernel modesetting])
 +	fi
- 
+ fi
+ AC_MSG_CHECKING([whether to include DRI support])
+ if test x$DRI = xauto; then
          if test "$have_dri_h" = yes -a \
                  "$have_sarea_h" = yes -a \
                  "$have_dristruct_h" = yes; then
commit f26bcb9cb879e2e9ee2b26c95438cf46286c0208
Merge: 67ab546... 7a1cc48...
Author: Jesse Barnes <jbarnes at virtuousgeek.org>
Date:   Tue Aug 19 15:53:18 2008 -0700

    Merge branch 'master' into modesetting-gem
    
    Conflicts:
    
    	src/i830_driver.c

diff --cc src/i830_driver.c
index 561351c,79c2078..2ce8942
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@@ -1399,354 -1347,6 +1399,354 @@@ static const char *accel_name[] 
     "UXA",
  };
  
 +static Bool
 +I830LoadSyms(ScrnInfoPtr pScrn)
 +{
 +    I830Ptr pI830 = I830PTR(pScrn);
 +
 +    if (pI830->use_drm_mode)
 +	return TRUE;
 +
 +    /* Load int10 module */
 +    if (!xf86LoadSubModule(pScrn, "int10"))
 +	return FALSE;
 +    xf86LoaderReqSymLists(I810int10Symbols, NULL);
 +
 +    /* The vgahw module should be loaded here when needed */
 +    if (!xf86LoadSubModule(pScrn, "vgahw"))
 +	return FALSE;
 +    xf86LoaderReqSymLists(I810vgahwSymbols, NULL);
 +
 +    return TRUE;
 +}
 +
 +static Bool
 +I830GetEarlyOptions(ScrnInfoPtr pScrn)
 +{
 +    I830Ptr pI830 = I830PTR(pScrn);
 +
 +    /* Process the options */
 +    xf86CollectOptions(pScrn, NULL);
 +    if (!(pI830->Options = xalloc(sizeof(I830Options))))
 +	return FALSE;
 +    memcpy(pI830->Options, I830Options, sizeof(I830Options));
 +    xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, pI830->Options);
 +
 +    if (xf86ReturnOptValBool(pI830->Options, OPTION_MODEDEBUG, FALSE)) {
 +	pI830->debug_modes = TRUE;
 +    } else {
 +	pI830->debug_modes = FALSE;
 +    }
 +
 +    if (xf86ReturnOptValBool(pI830->Options, OPTION_LVDS24BITMODE, FALSE)) {
 +	pI830->lvds_24_bit_mode = TRUE;
 +    } else {
 +	pI830->lvds_24_bit_mode = FALSE;
 +    }
 +
 +    if (xf86ReturnOptValBool(pI830->Options, OPTION_LVDSFIXEDMODE, TRUE)) {
- 	pI830->skip_panel_detect = TRUE;
-     } else {
 +	pI830->skip_panel_detect = FALSE;
++    } else {
++	pI830->skip_panel_detect = TRUE;
 +    }
 +
 +    if (xf86ReturnOptValBool(pI830->Options, OPTION_FORCEENABLEPIPEA, FALSE))
 +	pI830->quirk_flag |= QUIRK_PIPEA_FORCE;
 +
 +    return TRUE;
 +}
 +
 +static void
 +I830PreInitCrtcConfig(ScrnInfoPtr pScrn)
 +{
 +    xf86CrtcConfigPtr   xf86_config;
 +    I830Ptr pI830 = I830PTR(pScrn);
 +    int max_width, max_height;
 +
 +    if (pI830->use_drm_mode)
 +	return;
 +
 +    /* check quirks */
 +    i830_fixup_devices(pScrn);
 +
 +    /* Allocate an xf86CrtcConfig */
 +    xf86CrtcConfigInit (pScrn, &i830_xf86crtc_config_funcs);
 +    xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
 +
 +    /* See i830_exa.c comments for why we limit the framebuffer size like this.
 +     */
 +    if (IS_I965G(pI830)) {
 +	max_width = 8192;
 +	max_height = 8192;
 +    } else {
 +	max_width = 2048;
 +	max_height = 2048;
 +    }
 +    xf86CrtcSetSizeRange (pScrn, 320, 200, max_width, max_height);
 +}
 +
 +static Bool
 +I830AccelMethodInit(ScrnInfoPtr pScrn)
 +{
 +    I830Ptr pI830 = I830PTR(pScrn);
 +    MessageType from = X_PROBED;
 +    char *s;
 +    int i, num_pipe;
 +
 +    if (xf86ReturnOptValBool(pI830->Options, OPTION_NOACCEL, FALSE)) {
 +	pI830->accel = ACCEL_NONE;
 +    }
 +
 +    /*
 +     * The ugliness below:
 +     * If either XAA or EXA (exclusive) is compiled in, default to it.
 +     *
 +     * If both are compiled in, and the user didn't specify noAccel, use the
 +     * config option AccelMethod to determine which to use, defaulting to EXA
 +     * if none is specified, or if the string was unrecognized.
 +     *
 +     * All this *could* go away if we removed XAA support from this driver,
 +     * for example. :)
 +     */
 +    if (!(pI830->accel == ACCEL_NONE)) {
 +#ifdef I830_USE_UXA
 +	pI830->accel = ACCEL_UXA;
 +#endif
 +#ifdef I830_USE_EXA
 +	pI830->accel = ACCEL_EXA;
 +#endif
 +#if I830_USE_XAA + I830_USE_EXA + I830_USE_UXA >= 2
 +	from = X_DEFAULT;
 +	if ((s = (char *)xf86GetOptValString(pI830->Options,
 +					     OPTION_ACCELMETHOD))) {
 +	    if (!xf86NameCmp(s, "EXA")) {
 +		from = X_CONFIG;
 +		pI830->accel = ACCEL_EXA;
 +	    }
 +	    else if (!xf86NameCmp(s, "XAA")) {
 +		from = X_CONFIG;
 +		pI830->accel = ACCEL_XAA;
 +	    }
 +	    else if (!xf86NameCmp(s, "UXA")) {
 +		from = X_CONFIG;
 +	       pI830->accel = ACCEL_UXA;
 +	    }
 +	}
 +#endif
 +	xf86DrvMsg(pScrn->scrnIndex, from, "Using %s for acceleration\n",
 +		   accel_name[pI830->accel]);
 +    }
 +
 +    if (xf86ReturnOptValBool(pI830->Options, OPTION_SW_CURSOR, FALSE)) {
 +	pI830->SWCursor = TRUE;
 +    }
 +
 +    pI830->directRenderingDisabled =
 +	!xf86ReturnOptValBool(pI830->Options, OPTION_DRI, TRUE);
 +
 +#ifdef XF86DRI
 +    if (!pI830->directRenderingDisabled) {
 +	if ((pI830->accel == ACCEL_NONE) || pI830->SWCursor) {
 +	    xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "DRI is disabled because it "
 +		       "needs HW cursor and 2D acceleration.\n");
 +	    pI830->directRenderingDisabled = TRUE;
 +	} else if (pScrn->depth != 16 && pScrn->depth != 24) {
 +	    xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "DRI is disabled because it "
 +		       "runs only at depths 16 and 24.\n");
 +	    pI830->directRenderingDisabled = TRUE;
 +	}
 +
 +	if (!pI830->directRenderingDisabled) {
 +	    pI830->allocate_classic_textures = TRUE;
 +
 +	    from = X_PROBED;
 +
 +#ifdef XF86DRI_MM
 +	    if (!IS_I965G(pI830)) {
 +		Bool tmp;
 +
 +		if (xf86GetOptValBool(pI830->Options,
 +				      OPTION_INTELTEXPOOL, &tmp)) {
 +		    from = X_CONFIG;
 +		    if (!tmp)
 +			pI830->allocate_classic_textures = FALSE;
 +		}
 +	    }
 +#endif /* XF86DRI_MM */
 +	}
 +    }
 +#endif /* XF86DRI */
 +
 +    I830MapMMIO(pScrn);
 +
 +    if (pI830->debug_modes) {
 +	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
 +		   "Hardware state on X startup:\n");
 +	i830DumpRegs (pScrn);
 +    }
 +
 +    i830TakeRegSnapshot(pScrn);
 +
 +    if (DEVICE_ID(pI830->PciInfo) == PCI_CHIP_E7221_G)
 +	num_pipe = 1;
 +    else
 +	if (IS_MOBILE(pI830) || IS_I9XX(pI830))
 +	    num_pipe = 2;
 +	else
 +	    num_pipe = 1;
 +    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "%d display pipe%s available.\n",
 +	       num_pipe, num_pipe > 1 ? "s" : "");
 +
 +    I830PreInitDDC(pScrn);
 +    for (i = 0; i < num_pipe; i++) {
 +	i830_crtc_init(pScrn, i);
 +    }
 +    I830SetupOutputs(pScrn);
 +
 +    SaveHWState(pScrn);
 +    if (!xf86InitialConfiguration (pScrn, FALSE))
 +    {
 +	xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes.\n");
 +	RestoreHWState(pScrn);
 +	PreInitCleanup(pScrn);
 +	return FALSE;
 +    }
 +    RestoreHWState(pScrn);
 +
 +    /* XXX This should go away, replaced by xf86Crtc.c support for it */
 +    pI830->rotation = RR_Rotate_0;
 +
 +    /*
 +     * Let's setup the mobile systems to check the lid status
 +     */
 +    if (IS_MOBILE(pI830)) {
 +	pI830->checkDevices = TRUE;
 +
 +	if (!xf86ReturnOptValBool(pI830->Options, OPTION_CHECKDEVICES, TRUE)) {
 +	    pI830->checkDevices = FALSE;
 +	    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Monitoring connected displays disabled\n");
 +	} else
 +	    if (pI830->entityPrivate && !I830IsPrimary(pScrn) &&
 +		!I830PTR(pI830->entityPrivate->pScrn_1)->checkDevices) {
 +		/* If checklid is off, on the primary head, then
 +		 * turn it off on the secondary*/
 +		xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Monitoring connected displays disabled\n");
 +		pI830->checkDevices = FALSE;
 +	    } else
 +		xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Monitoring connected displays enabled\n");
 +    } else
 +	pI830->checkDevices = FALSE;
 +
 +    pI830->stolen_size = I830DetectMemory(pScrn);
 +
 +    return TRUE;
 +}
 +
 +static Bool
 +I830DrmModeInit(ScrnInfoPtr pScrn)
 +{
 +#ifdef XF86DRM_MODE
 +    I830Ptr pI830 = I830PTR(pScrn);
 +    char *bus_id;
 +    char *s;
 +
 +    /* Default to EXA but allow override */
 +    pI830->accel = ACCEL_EXA;
 +
 +    if ((s = (char *)xf86GetOptValString(pI830->Options, OPTION_ACCELMETHOD))) {
 +	if (!xf86NameCmp(s, "EXA"))
 +	    pI830->accel = ACCEL_EXA;
 +	else if (!xf86NameCmp(s, "UXA"))
 +	    pI830->accel = ACCEL_UXA;
 +	else
 +	    pI830->accel = ACCEL_EXA;
 +    }
 +
 +    bus_id = DRICreatePCIBusID(pI830->PciInfo);
 +    if (drmmode_pre_init(pScrn, &pI830->drmmode, bus_id, "i915",
 +			 pI830->cpp) == FALSE) {
 +	xfree(bus_id);
 +	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
 +		   "Kernel modesetting setup failed\n");
 +	PreInitCleanup(pScrn);
 +	return FALSE;
 +    }
 +
 +    pI830->drmmode.create_new_fb = i830_create_new_fb;
 +
 +    pI830->drmSubFD = pI830->drmmode.fd;
 +    xfree(bus_id);
 +
 +    pI830->directRenderingDisabled = FALSE;
 +    pI830->allocate_classic_textures = FALSE;
 +
 +    i830_init_bufmgr(pScrn);
 +#endif
 +
 +    return TRUE;
 +}
 +
 +static void
 +I830XvInit(ScrnInfoPtr pScrn)
 +{
 +    I830Ptr pI830 = I830PTR(pScrn);
 +    MessageType from = X_PROBED;
 +
 +    pI830->XvDisabled =
 +	!xf86ReturnOptValBool(pI830->Options, OPTION_XVIDEO, TRUE);
 +
 +#ifdef I830_XV
 +    if (xf86GetOptValInteger(pI830->Options, OPTION_VIDEO_KEY,
 +			     &(pI830->colorKey))) {
 +	from = X_CONFIG;
 +    } else if (xf86GetOptValInteger(pI830->Options, OPTION_COLOR_KEY,
 +				    &(pI830->colorKey))) {
 +	from = X_CONFIG;
 +    } else {
 +	pI830->colorKey =
 +	    (1 << pScrn->offset.red) | (1 << pScrn->offset.green) |
 +	    (((pScrn->mask.blue >> pScrn->offset.blue) - 1) <<
 +	     pScrn->offset.blue);
 +	from = X_DEFAULT;
 +    }
 +    xf86DrvMsg(pScrn->scrnIndex, from, "video overlay key set to 0x%x\n",
 +	       pI830->colorKey);
 +#endif
 +#ifdef INTEL_XVMC
 +    pI830->XvMCEnabled = FALSE;
 +    from =  (!pI830->directRenderingDisabled &&
 +	     xf86GetOptValBool(pI830->Options, OPTION_XVMC,
 +			       &pI830->XvMCEnabled)) ? X_CONFIG : X_DEFAULT;
 +    xf86DrvMsg(pScrn->scrnIndex, from, "Intel XvMC decoder %sabled\n",
 +	       pI830->XvMCEnabled ? "en" : "dis");
 +#endif
 +}
 +
 +static void
 +I830DriOptsInit(ScrnInfoPtr pScrn)
 +{
 +#ifdef XF86DRI
 +    I830Ptr pI830 = I830PTR(pScrn);
 +    MessageType from = X_PROBED;
 +
 +    pI830->allowPageFlip = FALSE;
 +    from = (!pI830->directRenderingDisabled &&
 +	    xf86GetOptValBool(pI830->Options, OPTION_PAGEFLIP,
 +			      &pI830->allowPageFlip)) ? X_CONFIG : X_DEFAULT;
 +
 +    xf86DrvMsg(pScrn->scrnIndex, from, "Will%s try to enable page flipping\n",
 +	       pI830->allowPageFlip ? "" : " not");
 +
 +    pI830->TripleBuffer = FALSE;
 +    from =  (!pI830->directRenderingDisabled &&
 +	     xf86GetOptValBool(pI830->Options, OPTION_TRIPLEBUFFER,
 +			       &pI830->TripleBuffer)) ? X_CONFIG : X_DEFAULT;
 +
 +    xf86DrvMsg(pScrn->scrnIndex, from, "Triple buffering %sabled\n",
 +	       pI830->TripleBuffer ? "en" : "dis");
 +#endif /* XF86DRI */
 +}
 +
  /**
   * This is called per zaphod head (so usually just once) to do initialization
   * before the Screen is created.
commit 67ab5462527c5ed94ed073421b60e85a213ea267
Author: Jesse Barnes <jbarnes at virtuousgeek.org>
Date:   Tue Aug 19 15:46:52 2008 -0700

    Use GTT mapping for EXA PrepareAccess function
    
    Makes software fallbacks *much* faster.

diff --git a/src/i830_exa.c b/src/i830_exa.c
index e59ceaa..9ba8df9 100644
--- a/src/i830_exa.c
+++ b/src/i830_exa.c
@@ -535,7 +535,7 @@ static Bool I830EXAPrepareAccess(PixmapPtr pPix, int index)
 	I830Sync(scrn);
 	i830->need_sync = FALSE;
     }
-    if (dri_bo_map(driver_priv->bo, 1)) {
+    if (dri_gem_bo_map_gtt(driver_priv->bo)) {
 	xf86DrvMsg(scrn->scrnIndex, X_WARNING, "%s: bo map failed\n",
 		   __FUNCTION__);
 	return FALSE;
commit 547cf774801bea2177d1224204f7de0dbf6baf3c
Author: Jesse Barnes <jbarnes at virtuousgeek.org>
Date:   Tue Aug 19 15:45:26 2008 -0700

    Don't allocate EXA offscreen space if kernel mode setting is active
    
    We'll use GEM alloc & free routines in that case.

diff --git a/src/i830_memory.c b/src/i830_memory.c
index 4128494..443cc4e 100644
--- a/src/i830_memory.c
+++ b/src/i830_memory.c
@@ -1447,7 +1447,7 @@ i830_allocate_2d_memory(ScrnInfoPtr pScrn)
 	return FALSE;
 
 #ifdef I830_USE_EXA
-    if (pI830->accel == ACCEL_EXA) {
+    if (pI830->accel == ACCEL_EXA && !pI830->use_drm_mode) {
 	if (pI830->exa_offscreen == NULL) {
 	    /* Default EXA to having 3 screens worth of offscreen memory space
 	     * (for pixmaps).
commit 2ddd85f8aef5da1aebbfe9fab510858e7a41860d
Author: Jesse Barnes <jbarnes at virtuousgeek.org>
Date:   Tue Aug 19 15:41:41 2008 -0700

    Bail out if kernel mode setting is active but DRI fails

diff --git a/src/i830_driver.c b/src/i830_driver.c
index 289f8b8..561351c 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -3448,11 +3448,15 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
    if (pI830->directRenderingEnabled) {
       pI830->directRenderingOpen = TRUE;
       xf86DrvMsg(pScrn->scrnIndex, X_INFO, "direct rendering: Enabled\n");
-   } else {
+   } else if (!pI830->use_drm_mode) {
       if (pI830->directRenderingDisabled)
 	 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "direct rendering: Disabled\n");
       else
 	 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "direct rendering: Failed\n");
+   } else {
+       xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+		  "failed to enable direct rendering, aborting\n");
+       return FALSE;
    }
 #else
    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "direct rendering: Not available\n");
commit b8ee31cd80a945d1fbbfc45234ffe34a109b5717
Author: Jesse Barnes <jbarnes at virtuousgeek.org>
Date:   Sat Aug 16 12:18:01 2008 -0700

    Remove last TTM bits
    
    Makes it build again with drm#modesetting-gem.

diff --git a/src/i830_memory.c b/src/i830_memory.c
index d14d86f..4128494 100644
--- a/src/i830_memory.c
+++ b/src/i830_memory.c
@@ -1030,7 +1030,6 @@ i830_allocate_overlay(ScrnInfoPtr pScrn)
 {
     I830Ptr pI830 = I830PTR(pScrn);
     int flags = 0;
-    int mem_space = DRM_BO_FLAG_MEM_TT;
 
     /* Only allocate if overlay is going to be enabled. */
     if (!pI830->XvEnabled)
@@ -1053,7 +1052,7 @@ i830_allocate_overlay(ScrnInfoPtr pScrn)
 
     if (flags & NEED_PHYSICAL_ADDR)
 	if (pI830->use_drm_mode)
-	    mem_space = DRM_BO_FLAG_MEM_VRAM;
+	    ; /* need physical addr */
 
     return TRUE;
 }
commit c1687f9ca9ce7b52043272e877e070c810e6599f
Author: Jesse Barnes <jbarnes at virtuousgeek.org>
Date:   Thu Aug 14 15:48:02 2008 -0700

    Map/unmap render state only when bo is available
    
    Otherwise just use the GTT address.

diff --git a/src/i965_render.c b/src/i965_render.c
index bd693ca..a4334c6 100644
--- a/src/i965_render.c
+++ b/src/i965_render.c
@@ -1441,6 +1441,7 @@ gen4_render_state_init(ScrnInfoPtr pScrn)
 {
     I830Ptr pI830 = I830PTR(pScrn);
     struct gen4_render_state *render_state;
+    int ret;
 
     if (pI830->gen4_render_state == NULL)
 	pI830->gen4_render_state = calloc(sizeof(*render_state), 1);
@@ -1449,12 +1450,19 @@ gen4_render_state_init(ScrnInfoPtr pScrn)
 
     render_state->card_state_offset = pI830->gen4_render_state_mem->offset;
 
-    if (dri_bo_map(pI830->gen4_render_state_mem->bo, 1)) {
-	xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Failed to map gen4 state\n");
-	return;
+    if (pI830->gen4_render_state_mem->bo) {
+	ret = dri_bo_map(pI830->gen4_render_state_mem->bo, 1);
+	if (ret) {
+	    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+		       "Failed to map gen4 state\n");
+	    return;
+	}
+	render_state->card_state = pI830->gen4_render_state_mem->bo->virtual;
+    } else {
+	render_state->card_state = (gen4_state_t *)
+	    (pI830->FbBase + render_state->card_state_offset);
     }
 
-    render_state->card_state = pI830->gen4_render_state_mem->bo->virtual;
     gen4_state_init(render_state);
 }
 
@@ -1466,8 +1474,10 @@ gen4_render_state_cleanup(ScrnInfoPtr pScrn)
 {
     I830Ptr pI830 = I830PTR(pScrn);
 
-    dri_bo_unmap(pI830->gen4_render_state_mem->bo);
-    dri_bo_unreference(pI830->gen4_render_state_mem->bo);
+    if (pI830->gen4_render_state_mem->bo) {
+	dri_bo_unmap(pI830->gen4_render_state_mem->bo);
+	dri_bo_unreference(pI830->gen4_render_state_mem->bo);
+    }
     pI830->gen4_render_state->card_state = NULL;
 }
 
commit 380c80712f78b3673b64ea07746a8e25e15fba8e
Author: Jesse Barnes <jbarnes at virtuousgeek.org>
Date:   Thu Aug 14 15:39:57 2008 -0700

    Fixup AccelMethod kernel mode setting code
    
    Allow UXA or EXA in the kernel mode setting case, defaulting to EXA.

diff --git a/src/i830_driver.c b/src/i830_driver.c
index 3ad811e..289f8b8 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -1648,6 +1648,19 @@ I830DrmModeInit(ScrnInfoPtr pScrn)
 #ifdef XF86DRM_MODE
     I830Ptr pI830 = I830PTR(pScrn);
     char *bus_id;
+    char *s;
+
+    /* Default to EXA but allow override */
+    pI830->accel = ACCEL_EXA;
+
+    if ((s = (char *)xf86GetOptValString(pI830->Options, OPTION_ACCELMETHOD))) {
+	if (!xf86NameCmp(s, "EXA"))
+	    pI830->accel = ACCEL_EXA;
+	else if (!xf86NameCmp(s, "UXA"))
+	    pI830->accel = ACCEL_UXA;
+	else
+	    pI830->accel = ACCEL_EXA;
+    }
 
     bus_id = DRICreatePCIBusID(pI830->PciInfo);
     if (drmmode_pre_init(pScrn, &pI830->drmmode, bus_id, "i915",
@@ -1664,7 +1677,6 @@ I830DrmModeInit(ScrnInfoPtr pScrn)
     pI830->drmSubFD = pI830->drmmode.fd;
     xfree(bus_id);
 
-    pI830->accel = ACCEL_EXA;
     pI830->directRenderingDisabled = FALSE;
     pI830->allocate_classic_textures = FALSE;
 
commit 4475dfb541c988ad19b177e60f31f333e2fb3355
Author: Jesse Barnes <jbarnes at virtuousgeek.org>
Date:   Thu Aug 14 15:38:07 2008 -0700

    Use pwrite for cursor updates
    
    Don't open code map/memcpy/unmap, let libdrm do that for us if necessary.

diff --git a/src/drmmode_display.c b/src/drmmode_display.c
index a65e948..5154b42 100644
--- a/src/drmmode_display.c
+++ b/src/drmmode_display.c
@@ -216,16 +216,13 @@ drmmode_load_cursor_argb (xf86CrtcPtr crtc, CARD32 *image)
 	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
 	ScrnInfoPtr pScrn = crtc->scrn;
 	I830Ptr pI830 = I830PTR(pScrn);
-	void *ptr;
+	int ret;
 
 	/* cursor should be mapped already */
-	if (dri_bo_map(pI830->cursor_mem->bo, 1))
+	ret = dri_bo_subdata(pI830->cursor_mem->bo, 0, 64*64*4, image);
+	if (ret)
 		xf86DrvMsg(crtc->scrn->scrnIndex, X_ERROR,
-			   "failed to map cursor");
-
-	ptr = pI830->cursor_mem->bo->virtual;
-
-	memcpy (ptr, image, 64 * 64 * 4);
+			   "failed to set cursor: %s", strerror(-ret));
 
 	return;
 }
commit cb217d4bfd941d0fa9ceae3e483dd1ca1d768e86
Author: Jesse Barnes <jbarnes at virtuousgeek.org>
Date:   Wed Aug 13 16:55:39 2008 -0700

    Make EXA & UXA share bo getting function
    
    Needed for proper acceleration & batch buffer handling.

diff --git a/src/i830.h b/src/i830.h
index 3ae9e89..612c6a9 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -92,11 +92,14 @@ unsigned long long I830TexOffsetStart(PixmapPtr pPix);
 #ifdef I830_USE_UXA
 #include "uxa.h"
 Bool i830_uxa_init(ScreenPtr pScreen);
-dri_bo *i830_uxa_get_pixmap_bo (PixmapPtr pixmap);
 void i830_uxa_create_screen_resources(ScreenPtr pScreen);
 void i830_uxa_block_handler (ScreenPtr pScreen);
 #endif
 
+#if defined(I830_USE_UXA) || defined(I830_USE_EXA)
+dri_bo *i830_get_pixmap_bo (PixmapPtr pixmap);
+#endif
+
 #ifdef I830_USE_XAA
 Bool I830XAAInit(ScreenPtr pScreen);
 #endif
diff --git a/src/i830_batchbuffer.h b/src/i830_batchbuffer.h
index 4c1198d..2a23cae 100644
--- a/src/i830_batchbuffer.h
+++ b/src/i830_batchbuffer.h
@@ -78,13 +78,13 @@ intel_batch_emit_reloc_pixmap(I830Ptr pI830, PixmapPtr pPixmap,
 			      uint32_t read_domains, uint32_t write_domain,
 			      uint32_t delta)
 {
-#if I830_USE_UXA
-    dri_bo *bo = i830_uxa_get_pixmap_bo(pPixmap);
+#if I830_USE_UXA || I830_USE_EXA
+    dri_bo *bo = i830_get_pixmap_bo(pPixmap);
 #endif
     uint32_t offset;
     assert(pI830->batch_ptr != NULL);
     assert(intel_batch_space(pI830) >= 4);
-#if I830_USE_UXA
+#if I830_USE_UXA || I830_USE_EXA
     if (bo) {
 	intel_batch_emit_reloc(pI830, bo, read_domains, write_domain, delta);
 	return;
diff --git a/src/i830_exa.c b/src/i830_exa.c
index 504bfc1..e59ceaa 100644
--- a/src/i830_exa.c
+++ b/src/i830_exa.c
@@ -735,15 +735,27 @@ i830_uxa_set_pixmap_bo (PixmapPtr pixmap, dri_bo *bo)
 }
 
 dri_bo *
-i830_uxa_get_pixmap_bo (PixmapPtr pixmap)
+i830_get_pixmap_bo(PixmapPtr pixmap)
 {
-    return dixLookupPrivate(&pixmap->devPrivates, uxa_pixmap_key);
+    ScreenPtr screen = pixmap->drawable.pScreen;
+    ScrnInfoPtr scrn = xf86Screens[screen->myNum];
+    I830Ptr i830 = I830PTR(scrn);
+
+    if (i830->accel == ACCEL_UXA) {
+	return dixLookupPrivate(&pixmap->devPrivates, uxa_pixmap_key);
+    } else if (i830->accel == ACCEL_EXA) {
+	struct i830_exa_pixmap_priv *driver_priv =
+	    exaGetPixmapDriverPrivate(pixmap);
+	return driver_priv ? driver_priv->bo : NULL;
+    }
+
+    return NULL;
 }
 
 static Bool
 i830_uxa_prepare_access (PixmapPtr pixmap, uxa_access_t access)
 {
-    dri_bo *bo = i830_uxa_get_pixmap_bo (pixmap);
+    dri_bo *bo = i830_get_pixmap_bo (pixmap);
 
     if (bo) {
 	ScreenPtr screen = pixmap->drawable.pScreen;
@@ -765,7 +777,7 @@ i830_uxa_prepare_access (PixmapPtr pixmap, uxa_access_t access)
 static void
 i830_uxa_finish_access (PixmapPtr pixmap)
 {
-    dri_bo *bo = i830_uxa_get_pixmap_bo (pixmap);
+    dri_bo *bo = i830_get_pixmap_bo (pixmap);
 
     if (bo) {
 	ScreenPtr screen = pixmap->drawable.pScreen;
@@ -794,7 +806,7 @@ i830_uxa_block_handler (ScreenPtr screen)
 static Bool
 i830_uxa_pixmap_is_offscreen(PixmapPtr pixmap)
 {
-    return i830_uxa_get_pixmap_bo (pixmap) != NULL;
+    return i830_get_pixmap_bo (pixmap) != NULL;
 }
 
 static PixmapPtr
@@ -835,7 +847,7 @@ static Bool
 i830_uxa_destroy_pixmap (PixmapPtr pixmap)
 {
     if (pixmap->refcnt == 1) {
-	dri_bo  *bo = i830_uxa_get_pixmap_bo (pixmap);
+	dri_bo  *bo = i830_get_pixmap_bo (pixmap);
     
 	if (bo)
 	    dri_bo_unreference (bo);
commit 1ab7239b73a5e298cadaf44e5605cf05855f08e9
Author: Jesse Barnes <jbarnes at virtuousgeek.org>
Date:   Tue Aug 12 18:16:37 2008 -0700

    Map gen4 render state buffer before initializing

diff --git a/src/i965_render.c b/src/i965_render.c
index 391e063..bd693ca 100644
--- a/src/i965_render.c
+++ b/src/i965_render.c
@@ -1448,9 +1448,13 @@ gen4_render_state_init(ScrnInfoPtr pScrn)
     render_state = pI830->gen4_render_state;
 
     render_state->card_state_offset = pI830->gen4_render_state_mem->offset;
-    render_state->card_state = (gen4_state_t *)
-	(pI830->FbBase + render_state->card_state_offset);
 
+    if (dri_bo_map(pI830->gen4_render_state_mem->bo, 1)) {
+	xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Failed to map gen4 state\n");
+	return;
+    }
+
+    render_state->card_state = pI830->gen4_render_state_mem->bo->virtual;
     gen4_state_init(render_state);
 }
 
@@ -1462,6 +1466,8 @@ gen4_render_state_cleanup(ScrnInfoPtr pScrn)
 {
     I830Ptr pI830 = I830PTR(pScrn);
 
+    dri_bo_unmap(pI830->gen4_render_state_mem->bo);
+    dri_bo_unreference(pI830->gen4_render_state_mem->bo);
     pI830->gen4_render_state->card_state = NULL;
 }
 
commit 603f48e31b021c4dc0bbf7b5efbb2e68aeb421d5
Author: Jesse Barnes <jbarnes at virtuousgeek.org>
Date:   Tue Aug 12 18:04:08 2008 -0700

    Don't set tiling (yet) if kernel mode setting is active

diff --git a/src/i830_memory.c b/src/i830_memory.c
index fe70908..d14d86f 100644
--- a/src/i830_memory.c
+++ b/src/i830_memory.c
@@ -193,7 +193,7 @@ i830_bind_memory(ScrnInfoPtr pScrn, i830_memory *mem)
 	mem->bound = TRUE;
     }
 
-    if (mem->tiling != TILE_NONE && pI830->use_drm_mode) {
+    if (mem->tiling != TILE_NONE && !pI830->use_drm_mode) {
 	mem->fence_nr = i830_set_tiling(pScrn, mem->offset, mem->pitch,
 					mem->allocated_size, mem->tiling);
     }
@@ -741,8 +741,6 @@ i830_allocate_memory_bo(ScrnInfoPtr pScrn, const char *name,
 
     mem->bo = dri_bo_alloc (pI830->bufmgr, name, size, align);
 
-    ErrorF("alloc'd bo for %s\n", name);
-
     if (!mem->bo) {
 	xfree(mem->name);
 	xfree(mem);
commit f744aa8d4b22374e1de6dda4facb673c3c428d4d
Author: Jesse Barnes <jbarnes at virtuousgeek.org>
Date:   Tue Aug 12 18:02:21 2008 -0700

    Don't run old accel init code
    
    Had the wrong logic.  Throw in a couple of cleanups while we're there.

diff --git a/src/i830_driver.c b/src/i830_driver.c
index 2681135..3ad811e 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -1878,8 +1878,10 @@ I830PreInit(ScrnInfoPtr pScrn, int flags)
    if (pI830->use_drm_mode) {
        if (!I830DrmModeInit(pScrn))
 	   return FALSE;
-   } else if (!I830AccelMethodInit(pScrn))
-       return FALSE;
+   } else {
+       if (!I830AccelMethodInit(pScrn))
+	   return FALSE;
+   }
 
    I830XvInit(pScrn);
 
@@ -2661,9 +2663,6 @@ I830BlockHandler(int i,
 #endif
 
        pI830->need_mi_flush = FALSE;
-#ifdef XF86DRI
-       drmCommandNone(pI830->drmSubFD, DRM_I915_GEM_THROTTLE);
-#endif
     }
 
     if (pI830->accel == ACCEL_UXA)
@@ -2675,7 +2674,7 @@ I830BlockHandler(int i,
      * (except for mode setting, where it may occur naturally).
      * Check & ack the condition.
      */
-    if (pScrn->vtSema && !DSPARB_HWCONTROL(pI830)) {
+    if (!pI830->use_drm_mode && pScrn->vtSema && !DSPARB_HWCONTROL(pI830)) {
 	if (xf86_config->crtc[0]->enabled &&
 		(INREG(PIPEASTAT) & FIFO_UNDERRUN)) {
 	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "underrun on pipe A!\n");
@@ -3641,7 +3640,8 @@ I830EnterVT(int scrnIndex, int flags)
 
    intel_batch_init(pScrn);
 
-   if ((pI830->accel == ACCEL_EXA || pI830->accel == ACCEL_UXA) && IS_I965G(pI830))
+   if ((pI830->accel == ACCEL_EXA || pI830->accel == ACCEL_UXA) &&
+       IS_I965G(pI830))
       gen4_render_state_init(pScrn);
 
    if (!pI830->use_drm_mode) {
commit 2321c865f3da9fd321910236a92b32e0af1aa458
Author: Jesse Barnes <jbarnes at virtuousgeek.org>
Date:   Tue Aug 12 17:59:16 2008 -0700

    Don't wait for ring if kernel mode setting is active
    
    We won't have the ring mapped.

diff --git a/src/i830_accel.c b/src/i830_accel.c
index a301818..386e653 100644
--- a/src/i830_accel.c
+++ b/src/i830_accel.c
@@ -220,7 +220,7 @@ I830Sync(ScrnInfoPtr pScrn)
 
        if (!pI830->memory_manager)
 	   i830_refresh_ring(pScrn);
-   } else {
+   } else if (!pI830->use_drm_mode) {
        i830_wait_ring_idle(pScrn);
    }
 
commit a1b334a4c8ae090744e802f8d41a36ea631d6c84
Author: Jesse Barnes <jbarnes at virtuousgeek.org>
Date:   Tue Aug 12 17:58:29 2008 -0700

    Update DRM based modesetting support
    
    Just a checkpoint, still needs a lot of work to properly handle resize, rotate
    & cursor handling.

diff --git a/src/drmmode_display.c b/src/drmmode_display.c
index 5bbb97c..a65e948 100644
--- a/src/drmmode_display.c
+++ b/src/drmmode_display.c
@@ -33,17 +33,18 @@
 #include "i830.h"
 #include "sarea.h"
 
-static Bool drmmode_resize_fb(ScrnInfoPtr scrn, drmmode_ptr drmmode, int width, int height);
+static Bool drmmode_resize_fb(ScrnInfoPtr scrn, drmmode_ptr drmmode,
+			      int width, int height);
 
 static Bool
 drmmode_xf86crtc_resize (ScrnInfoPtr scrn, int width, int height)
 {
 	xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
-	drmmode_crtc_private_ptr drmmode_crtc = xf86_config->crtc[0]->driver_private;
+	drmmode_crtc_private_ptr drmmode_crtc =
+		xf86_config->crtc[0]->driver_private;
 	drmmode_ptr drmmode = drmmode_crtc->drmmode;
 	Bool ret;
 
-	ErrorF("resize called %d %d\n", width, height);
 	ret = drmmode_resize_fb(scrn, drmmode, width, height);
 	scrn->virtualX = width;
 	scrn->virtualY = height;
@@ -51,21 +52,21 @@ drmmode_xf86crtc_resize (ScrnInfoPtr scrn, int width, int height)
 }
 
 static void
-drmmode_ConvertFromKMode(ScrnInfoPtr	scrn,
-		     struct drm_mode_modeinfo *kmode,
-		     DisplayModePtr	mode)
+drmmode_ConvertFromKMode(ScrnInfoPtr scrn,
+			 struct drm_mode_modeinfo *kmode,
+			 DisplayModePtr	mode)
 {
 	memset(mode, 0, sizeof(DisplayModeRec));
 	mode->status = MODE_OK;
-	
+
 	mode->Clock = kmode->clock;
-	
+
 	mode->HDisplay = kmode->hdisplay;
 	mode->HSyncStart = kmode->hsync_start;
 	mode->HSyncEnd = kmode->hsync_end;
 	mode->HTotal = kmode->htotal;
 	mode->HSkew = kmode->hskew;
-    
+
 	mode->VDisplay = kmode->vdisplay;
 	mode->VSyncStart = kmode->vsync_start;
 	mode->VSyncEnd = kmode->vsync_end;
@@ -83,9 +84,9 @@ drmmode_ConvertFromKMode(ScrnInfoPtr	scrn,
 }
 
 static void
-drmmode_ConvertToKMode(ScrnInfoPtr	scrn,
-		     struct drm_mode_modeinfo *kmode,
-		     DisplayModePtr	mode)
+drmmode_ConvertToKMode(ScrnInfoPtr scrn,
+		       struct drm_mode_modeinfo *kmode,
+		       DisplayModePtr mode)
 {
 	memset(kmode, 0, sizeof(*kmode));
 
@@ -95,7 +96,7 @@ drmmode_ConvertToKMode(ScrnInfoPtr	scrn,
 	kmode->hsync_end = mode->HSyncEnd;
 	kmode->htotal = mode->HTotal;
 	kmode->hskew = mode->HSkew;
-    
+
 	kmode->vdisplay = mode->VDisplay;
 	kmode->vsync_start = mode->VSyncStart;
 	kmode->vsync_end = mode->VSyncEnd;
@@ -121,7 +122,7 @@ drmmode_crtc_dpms(xf86CrtcPtr drmmode_crtc, int mode)
 
 static Bool
 drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
-		     Rotation rotation, int x, int y)
+		       Rotation rotation, int x, int y)
 {
 	xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn);
 	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
@@ -160,7 +161,8 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
 			continue;
 
 		drmmode_output = output->driver_private;
-		output_ids[output_count] = drmmode_output->mode_output->connector_id;
+		output_ids[output_count] =
+			drmmode_output->mode_output->connector_id;
 		output_count++;
 	}
 
@@ -175,9 +177,13 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
 	if (drmmode_crtc->rotate_fb_id)
 		fb_id = drmmode_crtc->rotate_fb_id;
 	ErrorF("fb id is %d\n", fb_id);
-	drmModeSetCrtc(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id,
-		       fb_id, x, y, output_ids, output_count, &kmode);
-
+	ret = drmModeSetCrtc(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id,
+			     fb_id, x, y, output_ids, output_count, &kmode);
+	if (ret)
+		xf86DrvMsg(crtc->scrn->scrnIndex, X_ERROR,
+			   "failed to set mode: %s", strerror(-ret));
+	else
+		ret = TRUE;
 
 done:
 	if (!ret) {
@@ -192,7 +198,7 @@ done:
 static void
 drmmode_set_cursor_colors (xf86CrtcPtr crtc, int bg, int fg)
 {
-  
+
 }
 
 static void
@@ -208,10 +214,16 @@ static void
 drmmode_load_cursor_argb (xf86CrtcPtr crtc, CARD32 *image)
 {
 	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
+	ScrnInfoPtr pScrn = crtc->scrn;
+	I830Ptr pI830 = I830PTR(pScrn);
 	void *ptr;
 
 	/* cursor should be mapped already */
-	ptr = drmmode_crtc->cursor_map;
+	if (dri_bo_map(pI830->cursor_mem->bo, 1))
+		xf86DrvMsg(crtc->scrn->scrnIndex, X_ERROR,
+			   "failed to map cursor");
+
+	ptr = pI830->cursor_mem->bo->virtual;
 
 	memcpy (ptr, image, 64 * 64 * 4);
 
@@ -224,9 +236,9 @@ drmmode_hide_cursor (xf86CrtcPtr crtc)
 {
 	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
 	drmmode_ptr drmmode = drmmode_crtc->drmmode;
-	
-	drmModeSetCursor(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, 0, 64, 64);
 
+	drmModeSetCursor(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id,
+			 0, 64, 64);
 }
 
 static void
@@ -234,8 +246,11 @@ drmmode_show_cursor (xf86CrtcPtr crtc)
 {
 	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
 	drmmode_ptr drmmode = drmmode_crtc->drmmode;
+	ScrnInfoPtr pScrn = crtc->scrn;
+	I830Ptr pI830 = I830PTR(pScrn);
 
-	drmModeSetCursor(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, drmmode_crtc->cursor_handle, 64, 64);
+	drmModeSetCursor(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id,
+			 pI830->cursor_mem->bo->handle, 64, 64);
 }
 
 static void *
@@ -250,23 +265,24 @@ drmmode_crtc_shadow_allocate(xf86CrtcPtr crtc, int width, int height)
 	size = rotate_pitch * height;
 
 #if 0
-	drmmode_crtc->rotate_bo = dri_bo_alloc(drmmode->bufmgr, "rotate",
-					     size, 4096, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_CACHED | DRM_BO_FLAG_CACHED_MAPPED);
+	drmmode_crtc->rotate_bo =
+		dri_bo_alloc(drmmode->bufmgr, "rotate", size, 4096);
 
 	if (!drmmode_crtc->rotate_bo) {
 		xf86DrvMsg(crtc->scrn->scrnIndex, X_ERROR,
 			   "Couldn't allocate shadow memory for rotated CRTC\n");
 		return NULL;
 	}
-		
+
 	dri_bo_map(drmmode_crtc->rotate_bo, 1);
 
 	ret = drmModeAddFB(drmmode->fd, width, height, crtc->scrn->depth,
-			   crtc->scrn->bitsPerPixel, rotate_pitch, dri_bo_get_handle(drmmode_crtc->rotate_bo), &drmmode_crtc->rotate_fb_id);
-	if (ret) {
+			   crtc->scrn->bitsPerPixel, rotate_pitch,
+			   drmmode_crtc->rotate_bo->handle,
+			   &drmmode_crtc->rotate_fb_id);
+	if (ret)
 		ErrorF("failed to add rotate fb\n");
-	}
-       
+
 	return drmmode_crtc->rotate_bo->virtual;
 #endif
 	return NULL;
@@ -280,19 +296,19 @@ drmmode_crtc_shadow_create(xf86CrtcPtr crtc, void *data, int width, int height)
 	drmmode_ptr drmmode = drmmode_crtc->drmmode;
 	unsigned long rotate_pitch;
 	PixmapPtr rotate_pixmap;
-	
+
 	if (!data)
 		data = drmmode_crtc_shadow_allocate (crtc, width, height);
 
 	rotate_pitch = pScrn->displayWidth * drmmode->cpp;
-	
+
 	rotate_pixmap = GetScratchPixmapHeader(pScrn->pScreen,
 					       width, height,
 					       pScrn->depth,
 					       pScrn->bitsPerPixel,
 					       rotate_pitch,
 					       data);
-	
+
 	if (rotate_pixmap == NULL) {
 		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
 			   "Couldn't allocate shadow pixmap for rotated CRTC\n");
@@ -307,8 +323,8 @@ drmmode_crtc_shadow_destroy(xf86CrtcPtr crtc, PixmapPtr rotate_pixmap, void *dat
 	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
 
 	if (rotate_pixmap)
-	    FreeScratchPixmapHeader(rotate_pixmap);
-	
+		FreeScratchPixmapHeader(rotate_pixmap);
+
 	if (data) {
 #if 0
 		/* Be sure to sync acceleration before the memory gets unbound. */
@@ -322,25 +338,25 @@ drmmode_crtc_shadow_destroy(xf86CrtcPtr crtc, PixmapPtr rotate_pixmap, void *dat
 }
 
 static const xf86CrtcFuncsRec drmmode_crtc_funcs = {
-    .dpms = drmmode_crtc_dpms,
-    .set_mode_major = drmmode_set_mode_major,
-    .set_cursor_colors = drmmode_set_cursor_colors,
-    .set_cursor_position = drmmode_set_cursor_position,
-    .show_cursor = drmmode_show_cursor,
-    .hide_cursor = drmmode_hide_cursor,
-    .load_cursor_argb = drmmode_load_cursor_argb,
-
-    .shadow_create = drmmode_crtc_shadow_create,
-    .shadow_allocate = drmmode_crtc_shadow_allocate,
-    .shadow_destroy = drmmode_crtc_shadow_destroy,
+	.dpms = drmmode_crtc_dpms,
+	.set_mode_major = drmmode_set_mode_major,
+	.set_cursor_colors = drmmode_set_cursor_colors,
+	.set_cursor_position = drmmode_set_cursor_position,
+	.show_cursor = drmmode_show_cursor,
+	.hide_cursor = drmmode_hide_cursor,
+	.load_cursor_argb = drmmode_load_cursor_argb,
+
+	.shadow_create = drmmode_crtc_shadow_create,
+	.shadow_allocate = drmmode_crtc_shadow_allocate,
+	.shadow_destroy = drmmode_crtc_shadow_destroy,
 #if 0
-    .gamma_set = i830_crtc_gamma_set,
-    .shadow_create = i830_crtc_shadow_create,
-    .shadow_allocate = i830_crtc_shadow_allocate,
-    .shadow_destroy = i830_crtc_shadow_destroy,
-    .set_cursor_colors = i830_crtc_set_cursor_colors,
+	.gamma_set = i830_crtc_gamma_set,
+	.shadow_create = i830_crtc_shadow_create,
+	.shadow_allocate = i830_crtc_shadow_allocate,
+	.shadow_destroy = i830_crtc_shadow_destroy,
+	.set_cursor_colors = i830_crtc_set_cursor_colors,
 #endif
-    .destroy = NULL, /* XXX */
+	.destroy = NULL, /* XXX */
 };
 
 
@@ -349,23 +365,19 @@ drmmode_crtc_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int num)
 {
 	xf86CrtcPtr crtc;
 	drmmode_crtc_private_ptr drmmode_crtc;
+	I830Ptr pI830 = I830PTR(pScrn);
+	int ret;
 
 	crtc = xf86CrtcCreate(pScrn, &drmmode_crtc_funcs);
 	if (crtc == NULL)
 		return;
 
 	drmmode_crtc = xnfcalloc(sizeof(drmmode_crtc_private_rec), 1);
-	drmmode_crtc->mode_crtc = drmModeGetCrtc(drmmode->fd, drmmode->mode_res->crtcs[num]);
+	drmmode_crtc->mode_crtc = drmModeGetCrtc(drmmode->fd,
+						 drmmode->mode_res->crtcs[num]);
 	drmmode_crtc->drmmode = drmmode;
 	crtc->driver_private = drmmode_crtc;
 
-#if 0
-	drmmode_crtc->cursor_handle = drmmode->alloc_cursor(pScrn, num, 64, 64, &drmmode_crtc->cursor_map);
-	if (!drmmode_crtc->cursor_handle) {
-		ErrorF("failed to allocate cursor for crtc\n");
-		return;	  
-	}
-#endif
 	return;
 }
 
@@ -377,9 +389,10 @@ drmmode_output_detect(xf86OutputPtr output)
 	drmmode_ptr drmmode = drmmode_output->drmmode;
 	xf86OutputStatus status;
 	drmModeFreeConnector(drmmode_output->mode_output);
-	
-	drmmode_output->mode_output = drmModeGetConnector(drmmode->fd, drmmode_output->output_id);
-	
+
+	drmmode_output->mode_output =
+		drmModeGetConnector(drmmode->fd, drmmode_output->output_id);
+
 	switch (drmmode_output->mode_output->connection) {
 	case DRM_MODE_CONNECTED:
 		status = XF86OutputStatusConnected;
@@ -414,26 +427,33 @@ drmmode_output_get_modes(xf86OutputPtr output)
 	/* look for an EDID property */
 	for (i = 0; i < koutput->count_props; i++) {
 		props = drmModeGetProperty(drmmode->fd, koutput->props[i]);
-		if (props && (props->flags & DRM_MODE_PROP_BLOB)) {
-			if (!strcmp(props->name, "EDID")) {
-				if (drmmode_output->edid_blob)
-					drmModeFreePropertyBlob(drmmode_output->edid_blob);
-				drmmode_output->edid_blob = drmModeGetPropertyBlob(drmmode->fd, koutput->prop_values[i]);
-			}
-			drmModeFreeProperty(props);
+		if (!props || !(props->flags & DRM_MODE_PROP_BLOB))
+			continue;
+
+		if (!strcmp(props->name, "EDID") && drmmode_output->edid_blob) {
+			drmModeFreePropertyBlob(drmmode_output->edid_blob);
+			drmmode_output->edid_blob =
+				drmModeGetPropertyBlob(drmmode->fd,
+						       koutput->prop_values[i]);
 		}
+		drmModeFreeProperty(props);
 	}
 
 	if (drmmode_output->edid_blob)
-		xf86OutputSetEDID(output, xf86InterpretEDID(output->scrn->scrnIndex, drmmode_output->edid_blob->data));
+		xf86OutputSetEDID(output,
+				  xf86InterpretEDID(output->scrn->scrnIndex,
+						    drmmode_output->edid_blob->data));
 	else
-		xf86OutputSetEDID(output, xf86InterpretEDID(output->scrn->scrnIndex, NULL));
+		xf86OutputSetEDID(output,
+				  xf86InterpretEDID(output->scrn->scrnIndex,
+						    NULL));
 
 	/* modes should already be available */
 	for (i = 0; i < koutput->count_modes; i++) {
 		Mode = xnfalloc(sizeof(DisplayModeRec));
 
-		drmmode_ConvertFromKMode(output->scrn, &koutput->modes[i], Mode);
+		drmmode_ConvertFromKMode(output->scrn, &koutput->modes[i],
+					 Mode);
 		Modes = xf86ModesAdd(Modes, Mode);
 
 	}
@@ -459,21 +479,21 @@ drmmode_output_dpms(xf86OutputPtr output, int mode)
 }
 
 static const xf86OutputFuncsRec drmmode_output_funcs = {
-    .dpms = drmmode_output_dpms,
+	.dpms = drmmode_output_dpms,
 #if 0
 
-    .save = drmmode_crt_save,
-    .restore = drmmode_crt_restore,
-    .mode_fixup = drmmode_crt_mode_fixup,
-    .prepare = drmmode_output_prepare,
-    .mode_set = drmmode_crt_mode_set,
-    .commit = drmmode_output_commit,
+	.save = drmmode_crt_save,
+	.restore = drmmode_crt_restore,
+	.mode_fixup = drmmode_crt_mode_fixup,
+	.prepare = drmmode_output_prepare,
+	.mode_set = drmmode_crt_mode_set,
+	.commit = drmmode_output_commit,
 #endif
-    .detect = drmmode_output_detect,
-    .mode_valid = drmmode_output_mode_valid,
+	.detect = drmmode_output_detect,
+	.mode_valid = drmmode_output_mode_valid,
 
-    .get_modes = drmmode_output_get_modes,
-    .destroy = drmmode_output_destroy
+	.get_modes = drmmode_output_get_modes,
+	.destroy = drmmode_output_destroy
 };
 
 static int subpixel_conv_table[7] = { 0, SubPixelUnknown,
@@ -497,7 +517,7 @@ const char *output_names[] = { "None",
 			       "HDMI",
 			       "HDMI",
 };
-   
+
 
 static void
 drmmode_output_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int num)
@@ -508,7 +528,8 @@ drmmode_output_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int num)
 	drmmode_output_private_ptr drmmode_output;
 	char name[32];
 
-	koutput = drmModeGetConnector(drmmode->fd, drmmode->mode_res->connectors[num]);
+	koutput = drmModeGetConnector(drmmode->fd,
+				      drmmode->mode_res->connectors[num]);
 	if (!koutput)
 		return;
 
@@ -518,7 +539,8 @@ drmmode_output_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int num)
 		return;
 	}
 
-	snprintf(name, 32, "%s%d", output_names[koutput->connector_type], koutput->connector_type_id);
+	snprintf(name, 32, "%s%d", output_names[koutput->connector_type],
+		 koutput->connector_type_id);
 
 	output = xf86OutputCreate (pScrn, &drmmode_output_funcs, name);
 	if (!output) {
@@ -550,7 +572,8 @@ drmmode_output_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int num)
 	return;
 }
 
-Bool drmmode_pre_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, char *busId, char *driver_name, int cpp)
+Bool drmmode_pre_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, char *busId,
+		      char *driver_name, int cpp)
 {
 	xf86CrtcConfigPtr   xf86_config;
 	int i;
@@ -576,7 +599,8 @@ Bool drmmode_pre_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, char *busId, char
 	if (!drmmode->mode_res)
 		return FALSE;
 
-	xf86CrtcSetSizeRange(pScrn, 320, 200, drmmode->mode_res->max_width, drmmode->mode_res->max_height);
+	xf86CrtcSetSizeRange(pScrn, 320, 200, drmmode->mode_res->max_width,
+			     drmmode->mode_res->max_height);
 	for (i = 0; i < drmmode->mode_res->count_crtcs; i++)
 		drmmode_crtc_init(pScrn, drmmode, i);
 
@@ -589,14 +613,16 @@ Bool drmmode_pre_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, char *busId, char
 }
 
 #if 0
-Bool drmmode_set_bufmgr(ScrnInfoPtr pScrn, drmmode_ptr drmmode, dri_bufmgr *bufmgr)
+Bool drmmode_set_bufmgr(ScrnInfoPtr pScrn, drmmode_ptr drmmode,
+			dri_bufmgr *bufmgr)
 {
 	drmmode->bufmgr = bufmgr;
 	return TRUE;
 }
 #endif
 
-void drmmode_set_fb(ScrnInfoPtr scrn, drmmode_ptr drmmode, int width, int height, int pitch, dri_bo *bo)
+void drmmode_set_fb(ScrnInfoPtr scrn, drmmode_ptr drmmode, int width,
+		    int height, int pitch, dri_bo *bo)
 {
 	int ret;
 
@@ -616,23 +642,14 @@ void drmmode_set_fb(ScrnInfoPtr scrn, drmmode_ptr drmmode, int width, int height
 	ErrorF("Add fb id %d %d %d\n", drmmode->fb_id, width, height);
 }
 
-void drmmode_set_cursor(ScrnInfoPtr scrn, drmmode_ptr drmmode, int id, void *ptr, uint32_t handle)
-{
-  	xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
-	xf86CrtcPtr crtc = xf86_config->crtc[id];
-	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
-	
-
-	drmmode_crtc->cursor_handle = handle;
-	drmmode_crtc->cursor_map = ptr;
-}
-
-#if 0
 Bool drmmode_is_rotate_pixmap(ScrnInfoPtr pScrn, pointer pPixData, dri_bo **bo)
 {
-	xf86CrtcConfigPtr	config = XF86_CRTC_CONFIG_PTR (pScrn);
+	xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR (pScrn);
 	int i;
 
+	return FALSE;
+
+#if 0
 	for (i = 0; i < config->num_crtc; i++) {
 		xf86CrtcPtr crtc = config->crtc[i];
 		drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
@@ -646,11 +663,11 @@ Bool drmmode_is_rotate_pixmap(ScrnInfoPtr pScrn, pointer pPixData, dri_bo **bo)
 		}
 	}
 	return FALSE;
-
-}
 #endif
+}
 
-static Bool drmmode_resize_fb(ScrnInfoPtr scrn, drmmode_ptr drmmode, int width, int height)
+static Bool drmmode_resize_fb(ScrnInfoPtr scrn, drmmode_ptr drmmode, int width,
+			      int height)
 {
 	uint32_t handle;
 	int pitch;
@@ -658,7 +675,8 @@ static Bool drmmode_resize_fb(ScrnInfoPtr scrn, drmmode_ptr drmmode, int width,
 
 	return FALSE;
 
-	if (drmmode->mode_fb->width == width && drmmode->mode_fb->height == height)
+	if (drmmode->mode_fb->width == width &&
+	    drmmode->mode_fb->height == height)
 		return TRUE;
 
 	if (!drmmode->create_new_fb)
@@ -668,7 +686,7 @@ static Bool drmmode_resize_fb(ScrnInfoPtr scrn, drmmode_ptr drmmode, int width,
 	if (handle == 0)
 		return FALSE;
 
-	ret = drmModeReplaceFB(drmmode->fd, drmmode->fb_id, 
+	ret = drmModeReplaceFB(drmmode->fd, drmmode->fb_id,
 			       width, height,
 			       scrn->depth, scrn->bitsPerPixel, pitch,
 			       handle);
@@ -680,7 +698,7 @@ static Bool drmmode_resize_fb(ScrnInfoPtr scrn, drmmode_ptr drmmode, int width,
 	drmmode->mode_fb = drmModeGetFB(drmmode->fd, drmmode->fb_id);
 	if (!drmmode->mode_fb)
 		return FALSE;
-	
+
 	return TRUE;
 }
 
diff --git a/src/drmmode_display.h b/src/drmmode_display.h
index 112ee03..fc7c1df 100644
--- a/src/drmmode_display.h
+++ b/src/drmmode_display.h
@@ -33,23 +33,21 @@
 #include "xf86drmMode.h"
 
 typedef struct {
-  int fd;
-  uint32_t fb_id;
-  drmModeResPtr mode_res;
-  drmModeFBPtr mode_fb;
-  int cpp;
-  //  dri_bufmgr *bufmgr;
-
-  uint32_t (*create_new_fb)(ScrnInfoPtr pScrn, int width, int height, int *pitch);
+    int fd;
+    uint32_t fb_id;
+    drmModeResPtr mode_res;
+    drmModeFBPtr mode_fb;
+    int cpp;
+    uint32_t (*create_new_fb)(ScrnInfoPtr pScrn, int width, int height,
+			      int *pitch);
 } drmmode_rec, *drmmode_ptr;
 
 typedef struct {
 
     drmmode_ptr drmmode;
     drmModeCrtcPtr mode_crtc;
-    uint32_t cursor_handle;
-    void *cursor_map;
-  //    dri_bo *rotate_bo;
+    dri_bo *cursor;
+    dri_bo *rotate_bo;
     int rotate_fb_id;
 } drmmode_crtc_private_rec, *drmmode_crtc_private_ptr;
 
@@ -62,10 +60,14 @@ typedef struct {
 } drmmode_output_private_rec, *drmmode_output_private_ptr;
 
 
-extern Bool drmmode_pre_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, char *busId, char *driver_name, int cpp);
-//extern Bool drmmode_set_bufmgr(ScrnInfoPtr pScrn, drmmode_ptr drmmode, dri_bufmgr *bufmgr);
-extern void drmmode_set_fb(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int width, int height, int pitch, dri_bo *bo);
-//extern Bool drmmode_is_rotate_pixmap(ScrnInfoPtr pScrn, pointer pPixData, dri_bo **bo);
-extern void drmmode_set_cursor(ScrnInfoPtr scrn, drmmode_ptr drmmode, int id, void *ptr, uint32_t handle);
-#endif
-#endif
+extern Bool drmmode_pre_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode,
+			     char *busId, char *driver_name, int cpp);
+extern void drmmode_set_fb(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int width,
+			   int height, int pitch, dri_bo *bo);
+extern Bool drmmode_is_rotate_pixmap(ScrnInfoPtr pScrn, pointer pPixData,
+				     dri_bo **bo);
+extern void drmmode_set_cursor(ScrnInfoPtr scrn, drmmode_ptr drmmode, int id,
+			       void *ptr, uint32_t handle);
+#endif /* XF86DRM_MODE */
+
+#endif /* DRMMODE_DISPLAY_H */
commit 5d78cf7cf0d23f60e6d61a92cbc2065b440027d3
Author: Jesse Barnes <jbarnes at virtuousgeek.org>
Date:   Tue Aug 12 17:56:59 2008 -0700

    Add EXA pixmap management functions for kernel mode setting
    
    Mostly pulled over from the old kernel modesetting code; a few updates were
    necessary.

diff --git a/src/i830.h b/src/i830.h
index 769fd52..3ae9e89 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -726,6 +726,10 @@ typedef struct _I830Rec {
 unsigned long intel_get_pixmap_offset(PixmapPtr pPix);
 unsigned long intel_get_pixmap_pitch(PixmapPtr pPix);
 
+struct i830_exa_pixmap_priv {
+    dri_bo *bo;
+};
+
 /* Batchbuffer support macros and functions */
 #include "i830_batchbuffer.h"
 
diff --git a/src/i830_exa.c b/src/i830_exa.c
index 25b5370..504bfc1 100644
--- a/src/i830_exa.c
+++ b/src/i830_exa.c
@@ -467,92 +467,147 @@ i830_transform_is_affine (PictTransformPtr t)
 
 static DevPrivateKey exa_pixmap_key = &exa_pixmap_key;
 
+static void *
+I830EXACreatePixmap(ScreenPtr screen, int size, int align)
+{
+    ScrnInfoPtr scrn = xf86Screens[screen->myNum];
+    I830Ptr i830 = I830PTR(scrn);
+    struct i830_exa_pixmap_priv *new_priv;
+
+    new_priv = xcalloc(1, sizeof(struct i830_exa_pixmap_priv));
+    if (!new_priv)
+        return NULL;
+
+    if (size == 0)
+	return new_priv;
+
+    new_priv->bo = dri_bo_alloc(i830->bufmgr, "pixmap", size,
+				i830->accel_pixmap_offset_alignment);
+    if (!new_priv->bo) {
+	xfree(new_priv);
+	return NULL;
+    }
+
+    return new_priv;
+}
+
 static void
-i830_exa_set_pixmap_bo (PixmapPtr pixmap, dri_bo *bo)
+I830EXADestroyPixmap(ScreenPtr pScreen, void *driverPriv)
 {
-    dixSetPrivate(&pixmap->devPrivates, exa_pixmap_key, bo);
+    struct i830_exa_pixmap_priv *priv = driverPriv;
+
+    if (priv->bo)
+	dri_bo_unreference(priv->bo);
+    xfree(priv);
 }
 
-dri_bo *
-i830_exa_get_pixmap_bo (PixmapPtr pixmap)
+static Bool I830EXAPixmapIsOffscreen(PixmapPtr pPix)
 {
-    return dixLookupPrivate(&pixmap->devPrivates, exa_pixmap_key);
+    struct i830_exa_pixmap_priv *driver_priv = exaGetPixmapDriverPrivate(pPix);
+
+    if (driver_priv && driver_priv->bo)
+	return TRUE;
+
+    return FALSE;
 }
 
 static Bool I830EXAPrepareAccess(PixmapPtr pPix, int index)
 {
-    dri_bo *bo = i830_exa_get_pixmap_bo(pPix);
+    ScreenPtr screen = pPix->drawable.pScreen;
+    ScrnInfoPtr scrn = xf86Screens[screen->myNum];
+    I830Ptr i830 = I830PTR(scrn);
+    struct i830_exa_pixmap_priv *driver_priv = exaGetPixmapDriverPrivate(pPix);
 
-    if (bo) {
-	ScreenPtr screen = pPix->drawable.pScreen;
-	ScrnInfoPtr scrn = xf86Screens[screen->myNum];
-	I830Ptr i830 = I830PTR(scrn);
+    if (!driver_priv) {
+	xf86DrvMsg(scrn->scrnIndex, X_WARNING, "%s: no driver private?\n",
+		   __FUNCTION__);
+	return FALSE;
+    }
 
-	intel_batch_flush(scrn);
-	if (i830->need_sync) {
-	    I830Sync(scrn);
-	    i830->need_sync = FALSE;
-	}
-	if (dri_bo_map(bo, 1))
-	    return FALSE;
-        pPix->devPrivate.ptr = bo->virtual;
+    if (!driver_priv->bo) {
+	xf86DrvMsg(scrn->scrnIndex, X_WARNING, "%s: no buffer object?\n",
+		   __FUNCTION__);
+	return TRUE;
     }
+
+    intel_batch_flush(scrn);
+    if (i830->need_sync) {
+	I830Sync(scrn);
+	i830->need_sync = FALSE;
+    }
+    if (dri_bo_map(driver_priv->bo, 1)) {
+	xf86DrvMsg(scrn->scrnIndex, X_WARNING, "%s: bo map failed\n",
+		   __FUNCTION__);
+	return FALSE;
+    }
+    pPix->devPrivate.ptr = driver_priv->bo->virtual;
+
     return TRUE;
 }
 
 static void I830EXAFinishAccess(PixmapPtr pPix, int index)
 {
-    dri_bo *bo = i830_exa_get_pixmap_bo(pPix);
+    ScreenPtr screen = pPix->drawable.pScreen;
+    ScrnInfoPtr scrn = xf86Screens[screen->myNum];
+    I830Ptr i830 = I830PTR(scrn);
+    struct i830_exa_pixmap_priv *driver_priv = exaGetPixmapDriverPrivate(pPix);
 
-    if (bo) {
-	ScreenPtr screen = pPix->drawable.pScreen;
-	ScrnInfoPtr scrn = xf86Screens[screen->myNum];
-	I830Ptr i830 = I830PTR(scrn);
+    if (!driver_priv) {
+	xf86DrvMsg(scrn->scrnIndex, X_WARNING, "%s: no driver private?\n",
+		   __FUNCTION__);
+	return;
+    }
 
-	dri_bo_unmap(bo);
-	pPix->devPrivate.ptr = NULL;
-	if (bo == i830->front_buffer->bo)
-	    i830->need_flush = TRUE;
+    if (!driver_priv->bo) {
+	xf86DrvMsg(scrn->scrnIndex, X_WARNING, "%s: no buffer object?\n",
+		   __FUNCTION__);
+	return;
     }
+
+    dri_bo_unmap(driver_priv->bo);
+    pPix->devPrivate.ptr = NULL;
+    if (driver_priv->bo == i830->front_buffer->bo)
+	i830->need_flush = TRUE;
 }
-#if 0
-static Bool I830EXAModifyPixmapHeader(PixmapPtr pPixmap, int width, int height,
+
+static Bool I830EXAModifyPixmapHeader(PixmapPtr pPix, int width, int height,
 				      int depth, int bitsPerPixel, int devKind,
 				      pointer pPixData)
 {
-    ScreenPtr	pScreen = pPixmap->drawable.pScreen;
+    ScreenPtr	pScreen = pPix->drawable.pScreen;
     ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
     I830Ptr pI830 = I830PTR(pScrn);
-    dri_bo *bo = i830_exa_get_pixmap_bo(pPixmap);
+    struct i830_exa_pixmap_priv *driver_priv = exaGetPixmapDriverPrivate(pPix);
+
+    if (!driver_priv)
+	return FALSE;
 
     if (pI830->use_drm_mode &&
 	drmmode_is_rotate_pixmap(pScrn, pPixData, &driver_priv->bo)) {
 	/* this is a rotate pixmap */
-	dri_bo_unmap(bo);
-	dri_bo_reference(bo);
-        miModifyPixmapHeader(pPixmap, width, height, depth,
+	dri_bo_unmap(driver_priv->bo);
+	dri_bo_reference(driver_priv->bo);
+        miModifyPixmapHeader(pPix, width, height, depth,
 			     bitsPerPixel, devKind, NULL);
     }
 
     if (pPixData == pI830->FbBase + pScrn->fbOffset) {
-	/* this is the front buffer pixmap so set it up as such..*/
-        driver_priv->flags |= I830_EXA_PIXMAP_IS_FRONTBUFFER;
-
-	ErrorF("FRONTBUFFER HANDLE CHANGING %p\n", driver_priv->bo);
-	/* get a reference to the front buffer handle */
 	if (driver_priv->bo)
 		dri_bo_unreference(driver_priv->bo);
-	bo = intel_ttm_bo_create_from_handle(pI830->bufmgr, "front",
-					     pI830->front_buffer->bo->handle);
+	driver_priv->bo =
+	    intel_bo_gem_create_from_name(pI830->bufmgr, "front",
+					  pI830->front_buffer->gem_name);
+	if (!driver_priv->bo)
+	    return FALSE;
 
-	miModifyPixmapHeader(pPixmap, width, height, depth,
+	miModifyPixmapHeader(pPix, width, height, depth,
 			     bitsPerPixel, devKind, NULL);
 
 	return TRUE;
     }
     return FALSE;
 }
-#endif
+
 
 Bool
 I830EXAInit(ScreenPtr pScreen)
@@ -598,6 +653,12 @@ I830EXAInit(ScreenPtr pScreen)
 	pI830->EXADriverPtr->flags = EXA_OFFSCREEN_PIXMAPS | EXA_HANDLES_PIXMAPS;
 	pI830->EXADriverPtr->PrepareAccess = I830EXAPrepareAccess;
 	pI830->EXADriverPtr->FinishAccess = I830EXAFinishAccess;
+#if EXA_VERSION_MINOR >= 4
+	pI830->EXADriverPtr->CreatePixmap = I830EXACreatePixmap;
+	pI830->EXADriverPtr->DestroyPixmap = I830EXADestroyPixmap;
+	pI830->EXADriverPtr->PixmapIsOffscreen = I830EXAPixmapIsOffscreen;
+	pI830->EXADriverPtr->ModifyPixmapHeader = I830EXAModifyPixmapHeader;
+#endif
     }
 
     DPRINTF(PFX, "EXA Mem: memoryBase 0x%x, end 0x%x, offscreen base 0x%x, "
@@ -645,7 +706,8 @@ I830EXAInit(ScreenPtr pScreen)
  	pI830->EXADriverPtr->DoneComposite = i830_done_composite;
     }
 #if EXA_VERSION_MINOR >= 2
-    pI830->EXADriverPtr->PixmapIsOffscreen = i830_exa_pixmap_is_offscreen;
+    if (!pI830->use_drm_mode)
+	pI830->EXADriverPtr->PixmapIsOffscreen = i830_exa_pixmap_is_offscreen;
 #endif
 
     if(!exaDriverInit(pScreen, pI830->EXADriverPtr)) {
commit 173b909a71955997ed6366e70faebf63fe922a8e
Author: Jesse Barnes <jbarnes at virtuousgeek.org>
Date:   Fri Aug 8 18:11:13 2008 -0700

    Make it actually build the kernel stuff if possible
    
    Fixup the kernel stuff to have a slightly better chance of working.  Still need
    to fixup the EXA pixmap functions.

diff --git a/configure.ac b/configure.ac
index 6120227..87dad69 100644
--- a/configure.ac
+++ b/configure.ac
@@ -85,12 +85,16 @@ XORG_DRIVER_CHECK_EXT(DPMSExtension, xextproto)
 # Checks for pkg-config packages
 PKG_CHECK_MODULES(XORG, [xorg-server xproto fontsproto $REQUIRED_MODULES])
 sdkdir=$(pkg-config --variable=sdkdir xorg-server)
+drm_cflags=$(pkg-config --cflags libdrm)
 
 # Checks for libraries.
 
 # Checks for header files.
 AC_HEADER_STDC
 
+save_CFLAGS="$CFLAGS"
+CFLAGS="$XORG_CFLAGS $DRI_CFLAGS $drm_cflags"
+CPPFLAGS="$XORG_CFLAGS $DRI_CFLAGS $drm_cflags"
 AC_MSG_CHECKING([whether to include DRI support])
 if test x$DRI = xauto; then
         AC_CHECK_FILE([${sdkdir}/dri.h],
@@ -101,7 +105,9 @@ if test x$DRI = xauto; then
                       [have_dristruct_h="yes"], [have_dristruct_h="no"])
 	AC_CHECK_FILE([${sdkdir}/damage.h],
                       [have_damage_h="yes"], [have_damage_h="no"])
-	AC_CHECK_HEADER(xf86drmMode.h,[DRM_MODE=yes],[DRM_MODE=no],[#include "stdint.h"])
+	AC_CHECK_HEADER(xf86drmMode.h,
+			[DRM_MODE=yes],[DRM_MODE=no]
+			[#include "stdint.h"])
 	if test "x$DRM_MODE" = xyes; then
 	   	AC_DEFINE(XF86DRM_MODE,1,[DRM kernel modesetting])
 	fi
@@ -116,8 +122,6 @@ if test x$DRI = xauto; then
 fi
 AC_MSG_RESULT([$DRI])
 
-save_CFLAGS="$CFLAGS"
-CFLAGS="$XORG_CFLAGS"
 AC_CHECK_HEADER(xf86Modes.h,[XMODES=yes],[XMODES=no],[#include "xorg-server.h"])
 AC_CHECK_DECL(XSERVER_LIBPCIACCESS,
 	      [XSERVER_LIBPCIACCESS=yes],[XSERVER_LIBPCIACCESS=no],
diff --git a/src/drmmode_display.c b/src/drmmode_display.c
index b329090..5bbb97c 100644
--- a/src/drmmode_display.c
+++ b/src/drmmode_display.c
@@ -30,7 +30,7 @@
 #endif
 
 #ifdef XF86DRM_MODE
-#include "radeon.h"
+#include "i830.h"
 #include "sarea.h"
 
 static Bool drmmode_resize_fb(ScrnInfoPtr scrn, drmmode_ptr drmmode, int width, int height);
@@ -208,9 +208,6 @@ static void
 drmmode_load_cursor_argb (xf86CrtcPtr crtc, CARD32 *image)
 {
 	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
-	drmmode_ptr drmmode = drmmode_crtc->drmmode;
-
-	int ret;
 	void *ptr;
 
 	/* cursor should be mapped already */
@@ -246,7 +243,6 @@ drmmode_crtc_shadow_allocate(xf86CrtcPtr crtc, int width, int height)
 {
 	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
 	drmmode_ptr drmmode = drmmode_crtc->drmmode;
-	int ret;
 	int size;
 	unsigned long rotate_pitch;
 
@@ -309,7 +305,6 @@ static void
 drmmode_crtc_shadow_destroy(xf86CrtcPtr crtc, PixmapPtr rotate_pixmap, void *data)
 {
 	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
-	drmmode_ptr drmmode = drmmode_crtc->drmmode;
 
 	if (rotate_pixmap)
 	    FreeScratchPixmapHeader(rotate_pixmap);
@@ -354,9 +349,6 @@ drmmode_crtc_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int num)
 {
 	xf86CrtcPtr crtc;
 	drmmode_crtc_private_ptr drmmode_crtc;
-	int cursor_size = 64 * 64 * 4;
-	uint32_t mask;
-	int ret;
 
 	crtc = xf86CrtcCreate(pScrn, &drmmode_crtc_funcs);
 	if (crtc == NULL)
@@ -604,15 +596,16 @@ Bool drmmode_set_bufmgr(ScrnInfoPtr pScrn, drmmode_ptr drmmode, dri_bufmgr *bufm
 }
 #endif
 
-void drmmode_set_fb(ScrnInfoPtr scrn, drmmode_ptr drmmode, int width, int height, int pitch, uint32_t handle)
+void drmmode_set_fb(ScrnInfoPtr scrn, drmmode_ptr drmmode, int width, int height, int pitch, dri_bo *bo)
 {
 	int ret;
 
 	ret = drmModeAddFB(drmmode->fd, width, height, scrn->depth,
-			   scrn->bitsPerPixel, pitch, handle, &drmmode->fb_id);
+			   scrn->bitsPerPixel, pitch, bo->handle,
+			   &drmmode->fb_id);
 
 	if (ret) {
-		ErrorF("Failed to add fb\n");
+		ErrorF("Failed to add fb: %s\n", strerror(-ret));
 	}
 
 	drmmode->mode_fb = drmModeGetFB(drmmode->fd, drmmode->fb_id);
diff --git a/src/drmmode_display.h b/src/drmmode_display.h
index 59e6307..112ee03 100644
--- a/src/drmmode_display.h
+++ b/src/drmmode_display.h
@@ -29,11 +29,12 @@
 
 #ifdef XF86DRM_MODE
 
+#include "dri_bufmgr.h"
 #include "xf86drmMode.h"
 
 typedef struct {
   int fd;
-  int fb_id;
+  uint32_t fb_id;
   drmModeResPtr mode_res;
   drmModeFBPtr mode_fb;
   int cpp;
@@ -63,7 +64,7 @@ typedef struct {
 
 extern Bool drmmode_pre_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, char *busId, char *driver_name, int cpp);
 //extern Bool drmmode_set_bufmgr(ScrnInfoPtr pScrn, drmmode_ptr drmmode, dri_bufmgr *bufmgr);
-extern void drmmode_set_fb(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int width, int height, int pitch, uint32_t handle);
+extern void drmmode_set_fb(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int width, int height, int pitch, dri_bo *bo);
 //extern Bool drmmode_is_rotate_pixmap(ScrnInfoPtr pScrn, pointer pPixData, dri_bo **bo);
 extern void drmmode_set_cursor(ScrnInfoPtr scrn, drmmode_ptr drmmode, int id, void *ptr, uint32_t handle);
 #endif
diff --git a/src/i830_dri.c b/src/i830_dri.c
index 9d7271e..ca3bc62 100644
--- a/src/i830_dri.c
+++ b/src/i830_dri.c
@@ -159,7 +159,7 @@ I830InitDma(ScrnInfoPtr pScrn)
    info.func = I830_INIT_DMA;
 
    /* Initialize fields that are used in the absence of GEM */
-   if (!pI830->memory_manager) {
+   if (!pI830->memory_manager && !pI830->use_drm_mode) {
        info.ring_start = ring->mem->offset + pI830->LinearAddr;
        info.ring_end = ring->mem->end + pI830->LinearAddr;
        info.ring_size = ring->mem->size;
diff --git a/src/i830_driver.c b/src/i830_driver.c
index 01073fe..2681135 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -1668,7 +1668,7 @@ I830DrmModeInit(ScrnInfoPtr pScrn)
     pI830->directRenderingDisabled = FALSE;
     pI830->allocate_classic_textures = FALSE;
 
-    I830InitBufMgr(pScrn);
+    i830_init_bufmgr(pScrn);
 #endif
 
     return TRUE;
@@ -1860,7 +1860,9 @@ I830PreInit(ScrnInfoPtr pScrn, int flags)
    if (!xf86SetDefaultVisual(pScrn, -1))
       return FALSE;
 
-   hwp = VGAHWPTR(pScrn);
+   if (!pI830->use_drm_mode)
+       hwp = VGAHWPTR(pScrn);
+
    pI830->cpp = pScrn->bitsPerPixel / 8;
 
    pI830->preinit = TRUE;
@@ -1873,9 +1875,10 @@ I830PreInit(ScrnInfoPtr pScrn, int flags)
 
    I830PreInitCrtcConfig(pScrn);
 
-   if (pI830->use_drm_mode && !I830DrmModeInit(pScrn))
-       return FALSE;
-   else if (!I830AccelMethodInit(pScrn))
+   if (pI830->use_drm_mode) {
+       if (!I830DrmModeInit(pScrn))
+	   return FALSE;
+   } else if (!I830AccelMethodInit(pScrn))
        return FALSE;
 
    I830XvInit(pScrn);
@@ -2910,9 +2913,10 @@ i830_init_bufmgr(ScrnInfoPtr pScrn)
 {
    I830Ptr pI830 = I830PTR(pScrn);
 
-   if (pI830->bufmgr) return;
+   if (pI830->bufmgr)
+       return;
 
-   if (pI830->memory_manager) {
+   if (pI830->memory_manager || pI830->use_drm_mode) {
       int batch_size;
 
       batch_size = 4096 * 4;
@@ -3093,30 +3097,10 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
 
    if (pI830->use_drm_mode) {
 #ifdef XF86DRM_MODE
-       uint64_t size;
-       int ret;
-       ret = drmMMInfo(pI830->drmSubFD, DRM_BO_MEM_VRAM, &size);
-       if (ret) {
-         xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
-                     "Kernel memory manager has no VRAM allocation\n");
-          return FALSE;
-       }
-       pI830->stolen_size = size * GTT_PAGE_SIZE;
-       xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-                 "Kernel stolen allocator is %dkb\n",
-		  pI830->stolen_size / KB(1));
-
-       ret = drmMMInfo(pI830->drmSubFD, DRM_BO_MEM_TT, &size);
-       if (ret) {
-          xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
-                     "Kernel memory manager has no TT allocation\n");
-          return FALSE;
-       }
-       pScrn->videoRam = (size * GTT_PAGE_SIZE) / KB(1);
-       xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-                 "Kernel AGP allocator is %dkb\n", pScrn->videoRam);
+       pI830->stolen_size = 0;
+       pScrn->videoRam = ~0UL / KB(1);
 #endif
-    } else {
+   } else {
        I830AdjustMemory(pScreen);
    }
 
@@ -3308,7 +3292,6 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
        DPRINTF(PFX, "assert( if(!I830MapMem(pScrn)) )\n");
        if (!I830MapMem(pScrn))
  	   return FALSE;
-
        pScrn->memPhysBase = (unsigned long)pI830->FbBase;
    }
 
@@ -3443,7 +3426,7 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
 
 #ifdef I830_XV
    /* Init video */
-   if (pI830->XvEnabled)
+   if (pI830->XvEnabled && !pI830->use_drm_mode)
       I830InitVideo(pScreen);
 #endif
 
@@ -3682,7 +3665,6 @@ I830EnterVT(int scrnIndex, int flags)
 
        if (pI830->power_context)
 	   OUTREG(PWRCTXA, pI830->power_context->offset | PWRCTX_EN);
-
        /* Clear the framebuffer */
        memset(pI830->FbBase + pScrn->fbOffset, 0,
 	      pScrn->virtualY * pScrn->displayWidth * pI830->cpp);
diff --git a/src/i830_exa.c b/src/i830_exa.c
index 2041741..25b5370 100644
--- a/src/i830_exa.c
+++ b/src/i830_exa.c
@@ -465,16 +465,104 @@ i830_transform_is_affine (PictTransformPtr t)
     return t->matrix[2][0] == 0 && t->matrix[2][1] == 0;
 }
 
-/*
- * TODO:
- *   - Dual head?
- */
+static DevPrivateKey exa_pixmap_key = &exa_pixmap_key;
+
+static void
+i830_exa_set_pixmap_bo (PixmapPtr pixmap, dri_bo *bo)
+{
+    dixSetPrivate(&pixmap->devPrivates, exa_pixmap_key, bo);
+}
+
+dri_bo *
+i830_exa_get_pixmap_bo (PixmapPtr pixmap)
+{
+    return dixLookupPrivate(&pixmap->devPrivates, exa_pixmap_key);
+}
+
+static Bool I830EXAPrepareAccess(PixmapPtr pPix, int index)
+{
+    dri_bo *bo = i830_exa_get_pixmap_bo(pPix);
+
+    if (bo) {
+	ScreenPtr screen = pPix->drawable.pScreen;
+	ScrnInfoPtr scrn = xf86Screens[screen->myNum];
+	I830Ptr i830 = I830PTR(scrn);
+
+	intel_batch_flush(scrn);
+	if (i830->need_sync) {
+	    I830Sync(scrn);
+	    i830->need_sync = FALSE;
+	}
+	if (dri_bo_map(bo, 1))
+	    return FALSE;
+        pPix->devPrivate.ptr = bo->virtual;
+    }
+    return TRUE;
+}
+
+static void I830EXAFinishAccess(PixmapPtr pPix, int index)
+{
+    dri_bo *bo = i830_exa_get_pixmap_bo(pPix);
+
+    if (bo) {
+	ScreenPtr screen = pPix->drawable.pScreen;
+	ScrnInfoPtr scrn = xf86Screens[screen->myNum];
+	I830Ptr i830 = I830PTR(scrn);
+
+	dri_bo_unmap(bo);
+	pPix->devPrivate.ptr = NULL;
+	if (bo == i830->front_buffer->bo)
+	    i830->need_flush = TRUE;
+    }
+}
+#if 0
+static Bool I830EXAModifyPixmapHeader(PixmapPtr pPixmap, int width, int height,
+				      int depth, int bitsPerPixel, int devKind,
+				      pointer pPixData)
+{
+    ScreenPtr	pScreen = pPixmap->drawable.pScreen;
+    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+    I830Ptr pI830 = I830PTR(pScrn);
+    dri_bo *bo = i830_exa_get_pixmap_bo(pPixmap);
+
+    if (pI830->use_drm_mode &&
+	drmmode_is_rotate_pixmap(pScrn, pPixData, &driver_priv->bo)) {
+	/* this is a rotate pixmap */
+	dri_bo_unmap(bo);
+	dri_bo_reference(bo);
+        miModifyPixmapHeader(pPixmap, width, height, depth,
+			     bitsPerPixel, devKind, NULL);
+    }
+
+    if (pPixData == pI830->FbBase + pScrn->fbOffset) {
+	/* this is the front buffer pixmap so set it up as such..*/
+        driver_priv->flags |= I830_EXA_PIXMAP_IS_FRONTBUFFER;
+
+	ErrorF("FRONTBUFFER HANDLE CHANGING %p\n", driver_priv->bo);
+	/* get a reference to the front buffer handle */
+	if (driver_priv->bo)
+		dri_bo_unreference(driver_priv->bo);
+	bo = intel_ttm_bo_create_from_handle(pI830->bufmgr, "front",
+					     pI830->front_buffer->bo->handle);
+
+	miModifyPixmapHeader(pPixmap, width, height, depth,
+			     bitsPerPixel, devKind, NULL);
+
+	return TRUE;
+    }
+    return FALSE;
+}
+#endif
+
 Bool
 I830EXAInit(ScreenPtr pScreen)
 {
     ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
     I830Ptr pI830 = I830PTR(pScrn);
 
+    if (!dixRequestPrivate(exa_pixmap_key, 0))
+	return FALSE;
+
     pI830->EXADriverPtr = exaDriverAlloc();
     if (pI830->EXADriverPtr == NULL) {
 	pI830->accel = ACCEL_NONE;
@@ -495,16 +583,22 @@ I830EXAInit(ScreenPtr pScreen)
 	       "EXA compatibility mode.  Output rotation rendering "
 	       "performance may suffer\n");
 #endif
-    pI830->EXADriverPtr->memoryBase = pI830->FbBase;
-    if (pI830->exa_offscreen) {
-	pI830->EXADriverPtr->offScreenBase = pI830->exa_offscreen->offset;
-	pI830->EXADriverPtr->memorySize = pI830->exa_offscreen->offset +
-	pI830->exa_offscreen->size;
+    if (!pI830->use_drm_mode) {
+	pI830->EXADriverPtr->memoryBase = pI830->FbBase;
+	if (pI830->exa_offscreen) {
+	    pI830->EXADriverPtr->offScreenBase = pI830->exa_offscreen->offset;
+	    pI830->EXADriverPtr->memorySize = pI830->exa_offscreen->offset +
+		pI830->exa_offscreen->size;
+	} else {
+	    pI830->EXADriverPtr->offScreenBase = pI830->FbMapSize;
+	    pI830->EXADriverPtr->memorySize = pI830->FbMapSize;
+	}
+	pI830->EXADriverPtr->flags = EXA_OFFSCREEN_PIXMAPS;
     } else {
-	pI830->EXADriverPtr->offScreenBase = pI830->FbMapSize;
-	pI830->EXADriverPtr->memorySize = pI830->FbMapSize;
+	pI830->EXADriverPtr->flags = EXA_OFFSCREEN_PIXMAPS | EXA_HANDLES_PIXMAPS;
+	pI830->EXADriverPtr->PrepareAccess = I830EXAPrepareAccess;
+	pI830->EXADriverPtr->FinishAccess = I830EXAFinishAccess;
     }
-    pI830->EXADriverPtr->flags = EXA_OFFSCREEN_PIXMAPS;
 
     DPRINTF(PFX, "EXA Mem: memoryBase 0x%x, end 0x%x, offscreen base 0x%x, "
 	    "memorySize 0x%x\n",
diff --git a/src/i830_memory.c b/src/i830_memory.c
index 57b9d27..fe70908 100644
--- a/src/i830_memory.c
+++ b/src/i830_memory.c
@@ -741,6 +741,8 @@ i830_allocate_memory_bo(ScrnInfoPtr pScrn, const char *name,
 
     mem->bo = dri_bo_alloc (pI830->bufmgr, name, size, align);
 
+    ErrorF("alloc'd bo for %s\n", name);
+
     if (!mem->bo) {
 	xfree(mem->name);
 	xfree(mem);
@@ -757,7 +759,7 @@ i830_allocate_memory_bo(ScrnInfoPtr pScrn, const char *name,
 	mem->lifetime_fixed_offset = TRUE;
 
     /* Bind it if we currently control the VT */
-    if (pScrn->vtSema) {
+    if (pScrn->vtSema || pI830->use_drm_mode) {
 	if (!i830_bind_memory(pScrn, mem)) {
 	    dri_bo_unreference (mem->bo);
 	    xfree(mem->name);
@@ -1227,8 +1229,10 @@ i830_allocate_framebuffer(ScrnInfoPtr pScrn, I830Ptr pI830, BoxPtr FbMemBox,
 
     if (pI830->use_drm_mode) {
 #ifdef XF86DRM_MODE
+	ErrorF("setting kernel fb to new front buffer\n");
+	ErrorF("front_buffer->bo->size: %ld\n", front_buffer->bo->size);
         drmmode_set_fb(pScrn, &pI830->drmmode, pScrn->virtualX, fb_height,
-		       pScrn->displayWidth * pI830->cpp, &front_buffer->bo);
+		       pScrn->displayWidth * pI830->cpp, front_buffer->bo);
 #endif
     } else if (pI830->FbBase)
 	memset (pI830->FbBase + front_buffer->offset, 0, size);
@@ -1986,12 +1990,14 @@ i830_bind_all_memory(ScrnInfoPtr pScrn)
 	for (mem = pI830->memory_list->next; mem->next != NULL;
 	     mem = mem->next)
 	{
-	    if (!i830_bind_memory(pScrn, mem)) {
+	    if (!mem->bound && !i830_bind_memory(pScrn, mem)) {
 		/* This shouldn't happen */
 		FatalError("Couldn't bind memory for %s\n", mem->name);
 	    }
 	}
 	for (mem = pI830->bo_list; mem != NULL; mem = mem->next) {
+	    if (mem->bound)
+		continue;
 	    if (!mem->lifetime_fixed_offset && !i830_bind_memory(pScrn, mem))
 		FatalError("Couldn't bind memory for BO %s\n", mem->name);
 	}
commit b1aef6f63c151dcb202fce869e4b80598b4b2052
Author: Jesse Barnes <jbarnes at virtuousgeek.org>
Date:   Fri Aug 8 11:54:18 2008 -0700

    Initial port of kernel modesetting from old intel-kernelmode branch
    
    Thanks airlied!

diff --git a/configure.ac b/configure.ac
index b24a154..6120227 100644
--- a/configure.ac
+++ b/configure.ac
@@ -101,6 +101,10 @@ if test x$DRI = xauto; then
                       [have_dristruct_h="yes"], [have_dristruct_h="no"])
 	AC_CHECK_FILE([${sdkdir}/damage.h],
                       [have_damage_h="yes"], [have_damage_h="no"])
+	AC_CHECK_HEADER(xf86drmMode.h,[DRM_MODE=yes],[DRM_MODE=no],[#include "stdint.h"])
+	if test "x$DRM_MODE" = xyes; then
+	   	AC_DEFINE(XF86DRM_MODE,1,[DRM kernel modesetting])
+	fi
 
         if test "$have_dri_h" = yes -a \
                 "$have_sarea_h" = yes -a \
diff --git a/src/Makefile.am b/src/Makefile.am
index dd92c8d..1b1b67c 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -130,7 +130,9 @@ intel_drv_la_SOURCES = \
 	 i830_xaa.c \
 	 i830_render.c \
 	 i915_render.c \
-	 i965_render.c
+	 i965_render.c \
+	 drmmode_display.c \
+	 drmmode_display.h
 
 INTEL_G4A =				\
 	packed_yuv_sf.g4a		\
diff --git a/src/common.h b/src/common.h
index f2ae502..ece1def 100644
--- a/src/common.h
+++ b/src/common.h
@@ -370,7 +370,9 @@ extern int I810_DEBUG;
 /* mark chipsets without overlay hw */
 #define OVERLAY_NOEXIST(pI810) (IS_GM45(pI810) || IS_G4X(pI810))
 /* chipsets require graphics mem for hardware status page */
-#define HWS_NEED_GFX(pI810) (IS_G33CLASS(pI810) || IS_GM45(pI810) || IS_G4X(pI810))
+#define HWS_NEED_GFX(pI810) (!pI810->use_drm_mode && \
+			     (IS_G33CLASS(pI810) || IS_GM45(pI810) || \
+			      IS_G4X(pI810)))
 /* chipsets require status page in non stolen memory */
 #define HWS_NEED_NONSTOLEN(pI810) (IS_GM45(pI810) || IS_G4X(pI810))
 #define SUPPORTS_INTEGRATED_HDMI(pI810) (IS_GM45(pI810) || IS_G4X(pI810))
diff --git a/src/drmmode_display.c b/src/drmmode_display.c
new file mode 100644
index 0000000..b329090
--- /dev/null
+++ b/src/drmmode_display.c
@@ -0,0 +1,695 @@
+/*
+ * Copyright © 2007 Red Hat, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ *    Dave Airlie <airlied at redhat.com>
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef XF86DRM_MODE
+#include "radeon.h"
+#include "sarea.h"
+
+static Bool drmmode_resize_fb(ScrnInfoPtr scrn, drmmode_ptr drmmode, int width, int height);
+
+static Bool
+drmmode_xf86crtc_resize (ScrnInfoPtr scrn, int width, int height)
+{
+	xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
+	drmmode_crtc_private_ptr drmmode_crtc = xf86_config->crtc[0]->driver_private;
+	drmmode_ptr drmmode = drmmode_crtc->drmmode;
+	Bool ret;
+
+	ErrorF("resize called %d %d\n", width, height);
+	ret = drmmode_resize_fb(scrn, drmmode, width, height);
+	scrn->virtualX = width;
+	scrn->virtualY = height;
+	return ret;
+}
+
+static void
+drmmode_ConvertFromKMode(ScrnInfoPtr	scrn,
+		     struct drm_mode_modeinfo *kmode,
+		     DisplayModePtr	mode)
+{
+	memset(mode, 0, sizeof(DisplayModeRec));
+	mode->status = MODE_OK;
+	
+	mode->Clock = kmode->clock;
+	
+	mode->HDisplay = kmode->hdisplay;
+	mode->HSyncStart = kmode->hsync_start;
+	mode->HSyncEnd = kmode->hsync_end;
+	mode->HTotal = kmode->htotal;
+	mode->HSkew = kmode->hskew;
+    
+	mode->VDisplay = kmode->vdisplay;
+	mode->VSyncStart = kmode->vsync_start;
+	mode->VSyncEnd = kmode->vsync_end;
+	mode->VTotal = kmode->vtotal;
+	mode->VScan = kmode->vscan;
+
+	mode->Flags = kmode->flags; //& FLAG_BITS;
+	mode->name = strdup(kmode->name);
+
+	if (kmode->type & DRM_MODE_TYPE_DRIVER)
+		mode->type = M_T_DRIVER;
+	if (kmode->type & DRM_MODE_TYPE_PREFERRED)
+		mode->type |= M_T_PREFERRED;
+	xf86SetModeCrtc (mode, scrn->adjustFlags);
+}
+
+static void
+drmmode_ConvertToKMode(ScrnInfoPtr	scrn,
+		     struct drm_mode_modeinfo *kmode,
+		     DisplayModePtr	mode)
+{
+	memset(kmode, 0, sizeof(*kmode));
+
+	kmode->clock = mode->Clock;
+	kmode->hdisplay = mode->HDisplay;
+	kmode->hsync_start = mode->HSyncStart;
+	kmode->hsync_end = mode->HSyncEnd;
+	kmode->htotal = mode->HTotal;
+	kmode->hskew = mode->HSkew;
+    
+	kmode->vdisplay = mode->VDisplay;
+	kmode->vsync_start = mode->VSyncStart;
+	kmode->vsync_end = mode->VSyncEnd;
+	kmode->vtotal = mode->VTotal;
+	kmode->vscan = mode->VScan;
+
+	kmode->flags = mode->Flags; //& FLAG_BITS;
+	if (mode->name)
+		strncpy(kmode->name, mode->name, DRM_DISPLAY_MODE_LEN);
+	kmode->name[DRM_DISPLAY_MODE_LEN-1] = 0;
+
+}
+
+static const xf86CrtcConfigFuncsRec drmmode_xf86crtc_config_funcs = {
+	drmmode_xf86crtc_resize
+};
+
+static void
+drmmode_crtc_dpms(xf86CrtcPtr drmmode_crtc, int mode)
+{
+
+}
+
+static Bool
+drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
+		     Rotation rotation, int x, int y)
+{
+	xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn);
+	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
+	drmmode_ptr drmmode = drmmode_crtc->drmmode;
+	int saved_x, saved_y;
+	Rotation saved_rotation;
+	DisplayModeRec saved_mode;
+	uint32_t *output_ids;
+	int output_count = 0;
+	int ret = TRUE;
+	int i;
+	int fb_id;
+	struct drm_mode_modeinfo kmode;
+
+	saved_mode = crtc->mode;
+	saved_x = crtc->x;
+	saved_y = crtc->y;
+	saved_rotation = crtc->rotation;
+
+	crtc->mode = *mode;
+	crtc->x = x;
+	crtc->y = y;
+	crtc->rotation = rotation;
+
+	output_ids = xcalloc(sizeof(uint32_t), xf86_config->num_output);
+	if (!output_ids) {
+		ret = FALSE;
+		goto done;
+	}
+
+	for (i = 0; i < xf86_config->num_output; i++) {
+		xf86OutputPtr output = xf86_config->output[i];
+		drmmode_output_private_ptr drmmode_output;
+
+		if (output->crtc != crtc)
+			continue;
+
+		drmmode_output = output->driver_private;
+		output_ids[output_count] = drmmode_output->mode_output->connector_id;
+		output_count++;
+	}
+
+	if (!xf86CrtcRotate(crtc, mode, rotation)) {
+		goto done;
+	}
+
+	drmmode_ConvertToKMode(crtc->scrn, &kmode, mode);
+
+
+	fb_id = drmmode->fb_id;
+	if (drmmode_crtc->rotate_fb_id)
+		fb_id = drmmode_crtc->rotate_fb_id;
+	ErrorF("fb id is %d\n", fb_id);
+	drmModeSetCrtc(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id,
+		       fb_id, x, y, output_ids, output_count, &kmode);
+
+
+done:
+	if (!ret) {
+		crtc->x = saved_x;
+		crtc->y = saved_y;
+		crtc->rotation = saved_rotation;
+		crtc->mode = saved_mode;
+	}
+	return ret;
+}
+
+static void
+drmmode_set_cursor_colors (xf86CrtcPtr crtc, int bg, int fg)
+{
+  
+}
+
+static void
+drmmode_set_cursor_position (xf86CrtcPtr crtc, int x, int y)
+{
+	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
+	drmmode_ptr drmmode = drmmode_crtc->drmmode;
+
+	drmModeMoveCursor(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, x, y);
+}
+
+static void
+drmmode_load_cursor_argb (xf86CrtcPtr crtc, CARD32 *image)
+{
+	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
+	drmmode_ptr drmmode = drmmode_crtc->drmmode;
+
+	int ret;
+	void *ptr;
+
+	/* cursor should be mapped already */
+	ptr = drmmode_crtc->cursor_map;
+
+	memcpy (ptr, image, 64 * 64 * 4);
+
+	return;
+}
+
+
+static void
+drmmode_hide_cursor (xf86CrtcPtr crtc)
+{
+	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
+	drmmode_ptr drmmode = drmmode_crtc->drmmode;
+	
+	drmModeSetCursor(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, 0, 64, 64);
+
+}
+
+static void
+drmmode_show_cursor (xf86CrtcPtr crtc)
+{
+	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
+	drmmode_ptr drmmode = drmmode_crtc->drmmode;
+
+	drmModeSetCursor(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, drmmode_crtc->cursor_handle, 64, 64);
+}
+
+static void *
+drmmode_crtc_shadow_allocate(xf86CrtcPtr crtc, int width, int height)
+{
+	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
+	drmmode_ptr drmmode = drmmode_crtc->drmmode;
+	int ret;
+	int size;
+	unsigned long rotate_pitch;
+
+	rotate_pitch = crtc->scrn->displayWidth * drmmode->cpp;
+	size = rotate_pitch * height;
+
+#if 0
+	drmmode_crtc->rotate_bo = dri_bo_alloc(drmmode->bufmgr, "rotate",
+					     size, 4096, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_CACHED | DRM_BO_FLAG_CACHED_MAPPED);
+
+	if (!drmmode_crtc->rotate_bo) {
+		xf86DrvMsg(crtc->scrn->scrnIndex, X_ERROR,
+			   "Couldn't allocate shadow memory for rotated CRTC\n");
+		return NULL;
+	}
+		
+	dri_bo_map(drmmode_crtc->rotate_bo, 1);
+
+	ret = drmModeAddFB(drmmode->fd, width, height, crtc->scrn->depth,
+			   crtc->scrn->bitsPerPixel, rotate_pitch, dri_bo_get_handle(drmmode_crtc->rotate_bo), &drmmode_crtc->rotate_fb_id);
+	if (ret) {
+		ErrorF("failed to add rotate fb\n");
+	}
+       
+	return drmmode_crtc->rotate_bo->virtual;
+#endif
+	return NULL;
+}
+
+static PixmapPtr
+drmmode_crtc_shadow_create(xf86CrtcPtr crtc, void *data, int width, int height)
+{
+	ScrnInfoPtr pScrn = crtc->scrn;
+	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
+	drmmode_ptr drmmode = drmmode_crtc->drmmode;
+	unsigned long rotate_pitch;
+	PixmapPtr rotate_pixmap;
+	
+	if (!data)
+		data = drmmode_crtc_shadow_allocate (crtc, width, height);
+
+	rotate_pitch = pScrn->displayWidth * drmmode->cpp;
+	
+	rotate_pixmap = GetScratchPixmapHeader(pScrn->pScreen,
+					       width, height,
+					       pScrn->depth,
+					       pScrn->bitsPerPixel,
+					       rotate_pitch,
+					       data);
+	
+	if (rotate_pixmap == NULL) {
+		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+			   "Couldn't allocate shadow pixmap for rotated CRTC\n");
+	}
+	return rotate_pixmap;
+
+}
+
+static void
+drmmode_crtc_shadow_destroy(xf86CrtcPtr crtc, PixmapPtr rotate_pixmap, void *data)
+{
+	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
+	drmmode_ptr drmmode = drmmode_crtc->drmmode;
+
+	if (rotate_pixmap)
+	    FreeScratchPixmapHeader(rotate_pixmap);
+	
+	if (data) {
+#if 0
+		/* Be sure to sync acceleration before the memory gets unbound. */
+		drmModeRmFB(drmmode->fd, drmmode_crtc->rotate_fb_id);
+		drmmode_crtc->rotate_fb_id = 0;
+		dri_bo_unreference(drmmode_crtc->rotate_bo);
+		drmmode_crtc->rotate_bo = NULL;
+#endif
+	}
+
+}
+
+static const xf86CrtcFuncsRec drmmode_crtc_funcs = {
+    .dpms = drmmode_crtc_dpms,
+    .set_mode_major = drmmode_set_mode_major,
+    .set_cursor_colors = drmmode_set_cursor_colors,
+    .set_cursor_position = drmmode_set_cursor_position,
+    .show_cursor = drmmode_show_cursor,
+    .hide_cursor = drmmode_hide_cursor,
+    .load_cursor_argb = drmmode_load_cursor_argb,
+
+    .shadow_create = drmmode_crtc_shadow_create,
+    .shadow_allocate = drmmode_crtc_shadow_allocate,
+    .shadow_destroy = drmmode_crtc_shadow_destroy,
+#if 0
+    .gamma_set = i830_crtc_gamma_set,
+    .shadow_create = i830_crtc_shadow_create,
+    .shadow_allocate = i830_crtc_shadow_allocate,
+    .shadow_destroy = i830_crtc_shadow_destroy,
+    .set_cursor_colors = i830_crtc_set_cursor_colors,
+#endif
+    .destroy = NULL, /* XXX */
+};
+
+
+static void
+drmmode_crtc_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int num)
+{
+	xf86CrtcPtr crtc;
+	drmmode_crtc_private_ptr drmmode_crtc;
+	int cursor_size = 64 * 64 * 4;
+	uint32_t mask;
+	int ret;
+
+	crtc = xf86CrtcCreate(pScrn, &drmmode_crtc_funcs);
+	if (crtc == NULL)
+		return;
+
+	drmmode_crtc = xnfcalloc(sizeof(drmmode_crtc_private_rec), 1);
+	drmmode_crtc->mode_crtc = drmModeGetCrtc(drmmode->fd, drmmode->mode_res->crtcs[num]);
+	drmmode_crtc->drmmode = drmmode;
+	crtc->driver_private = drmmode_crtc;
+
+#if 0
+	drmmode_crtc->cursor_handle = drmmode->alloc_cursor(pScrn, num, 64, 64, &drmmode_crtc->cursor_map);
+	if (!drmmode_crtc->cursor_handle) {
+		ErrorF("failed to allocate cursor for crtc\n");
+		return;	  
+	}
+#endif
+	return;
+}
+
+static xf86OutputStatus
+drmmode_output_detect(xf86OutputPtr output)
+{
+	/* go to the hw and retrieve a new output struct */
+	drmmode_output_private_ptr drmmode_output = output->driver_private;
+	drmmode_ptr drmmode = drmmode_output->drmmode;
+	xf86OutputStatus status;
+	drmModeFreeConnector(drmmode_output->mode_output);
+	
+	drmmode_output->mode_output = drmModeGetConnector(drmmode->fd, drmmode_output->output_id);
+	
+	switch (drmmode_output->mode_output->connection) {
+	case DRM_MODE_CONNECTED:
+		status = XF86OutputStatusConnected;
+		break;
+	case DRM_MODE_DISCONNECTED:
+		status = XF86OutputStatusDisconnected;
+		break;
+	default:
+	case DRM_MODE_UNKNOWNCONNECTION:
+		status = XF86OutputStatusUnknown;
+		break;
+	}
+	return status;
+}
+
+static Bool
+drmmode_output_mode_valid(xf86OutputPtr output, DisplayModePtr pModes)
+{
+	return MODE_OK;
+}
+
+static DisplayModePtr
+drmmode_output_get_modes(xf86OutputPtr output)
+{
+	drmmode_output_private_ptr drmmode_output = output->driver_private;
+	drmModeConnectorPtr koutput = drmmode_output->mode_output;
+	drmmode_ptr drmmode = drmmode_output->drmmode;
+	int i;
+	DisplayModePtr Modes = NULL, Mode;
+	drmModePropertyPtr props;
+
+	/* look for an EDID property */
+	for (i = 0; i < koutput->count_props; i++) {
+		props = drmModeGetProperty(drmmode->fd, koutput->props[i]);
+		if (props && (props->flags & DRM_MODE_PROP_BLOB)) {
+			if (!strcmp(props->name, "EDID")) {
+				if (drmmode_output->edid_blob)
+					drmModeFreePropertyBlob(drmmode_output->edid_blob);
+				drmmode_output->edid_blob = drmModeGetPropertyBlob(drmmode->fd, koutput->prop_values[i]);
+			}
+			drmModeFreeProperty(props);
+		}
+	}
+
+	if (drmmode_output->edid_blob)
+		xf86OutputSetEDID(output, xf86InterpretEDID(output->scrn->scrnIndex, drmmode_output->edid_blob->data));
+	else
+		xf86OutputSetEDID(output, xf86InterpretEDID(output->scrn->scrnIndex, NULL));
+
+	/* modes should already be available */
+	for (i = 0; i < koutput->count_modes; i++) {
+		Mode = xnfalloc(sizeof(DisplayModeRec));
+
+		drmmode_ConvertFromKMode(output->scrn, &koutput->modes[i], Mode);
+		Modes = xf86ModesAdd(Modes, Mode);
+
+	}
+	return Modes;
+}
+
+static void
+drmmode_output_destroy(xf86OutputPtr output)
+{
+	drmmode_output_private_ptr drmmode_output = output->driver_private;
+
+	if (drmmode_output->edid_blob)
+		drmModeFreePropertyBlob(drmmode_output->edid_blob);
+	drmModeFreeConnector(drmmode_output->mode_output);
+	xfree(drmmode_output);
+	output->driver_private = NULL;
+}
+
+static void
+drmmode_output_dpms(xf86OutputPtr output, int mode)
+{
+	return;
+}
+
+static const xf86OutputFuncsRec drmmode_output_funcs = {
+    .dpms = drmmode_output_dpms,
+#if 0
+
+    .save = drmmode_crt_save,
+    .restore = drmmode_crt_restore,
+    .mode_fixup = drmmode_crt_mode_fixup,
+    .prepare = drmmode_output_prepare,
+    .mode_set = drmmode_crt_mode_set,
+    .commit = drmmode_output_commit,
+#endif
+    .detect = drmmode_output_detect,
+    .mode_valid = drmmode_output_mode_valid,
+
+    .get_modes = drmmode_output_get_modes,
+    .destroy = drmmode_output_destroy
+};
+
+static int subpixel_conv_table[7] = { 0, SubPixelUnknown,
+				      SubPixelHorizontalRGB,
+				      SubPixelHorizontalBGR,
+				      SubPixelVerticalRGB,
+				      SubPixelVerticalBGR,
+				      SubPixelNone };
+
+const char *output_names[] = { "None",
+			       "VGA",
+			       "DVI",
+			       "DVI",
+			       "DVI",
+			       "Composite"
+			       "TV",
+			       "LVDS",
+			       "CTV",
+			       "DIN",
+			       "DP",
+			       "HDMI",
+			       "HDMI",
+};
+   
+
+static void
+drmmode_output_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int num)
+{
+	xf86OutputPtr output;
+	drmModeConnectorPtr koutput;
+	drmModeEncoderPtr kencoder;
+	drmmode_output_private_ptr drmmode_output;
+	char name[32];
+
+	koutput = drmModeGetConnector(drmmode->fd, drmmode->mode_res->connectors[num]);
+	if (!koutput)
+		return;
+
+	kencoder = drmModeGetEncoder(drmmode->fd, koutput->encoders[0]);
+	if (!kencoder) {
+		drmModeFreeConnector(koutput);
+		return;
+	}
+
+	snprintf(name, 32, "%s%d", output_names[koutput->connector_type], koutput->connector_type_id);
+
+	output = xf86OutputCreate (pScrn, &drmmode_output_funcs, name);
+	if (!output) {
+		drmModeFreeEncoder(kencoder);
+		drmModeFreeConnector(koutput);
+		return;
+	}
+
+	drmmode_output = xcalloc(sizeof(drmmode_output_private_rec), 1);
+	if (!drmmode_output) {
+		xf86OutputDestroy(output);
+		drmModeFreeConnector(koutput);
+		drmModeFreeEncoder(kencoder);
+		return;
+	}
+
+	drmmode_output->output_id = drmmode->mode_res->connectors[num];
+	drmmode_output->mode_output = koutput;
+	drmmode_output->mode_encoder = kencoder;
+	drmmode_output->drmmode = drmmode;
+	output->mm_width = koutput->mmWidth;
+	output->mm_height = koutput->mmHeight;
+
+	output->subpixel_order = subpixel_conv_table[koutput->subpixel];
+	output->driver_private = drmmode_output;
+
+	output->possible_crtcs = kencoder->possible_crtcs;
+	output->possible_clones = kencoder->possible_clones;
+	return;
+}
+
+Bool drmmode_pre_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, char *busId, char *driver_name, int cpp)
+{
+	xf86CrtcConfigPtr   xf86_config;
+	int i;
+	Bool ret;
+
+	/* Create a bus Id */
+	/* Low level DRM open */
+	ret = DRIOpenDRMMaster(pScrn, SAREA_MAX, busId, driver_name);
+	if (!ret) {
+		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+			   "[dri] DRIGetVersion failed to open the DRM\n"
+			   "[dri] Disabling DRI.\n");
+		return FALSE;
+	}
+
+	drmmode->fd = DRIMasterFD(pScrn);
+
+	xf86CrtcConfigInit(pScrn, &drmmode_xf86crtc_config_funcs);
+	xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+
+	drmmode->cpp = cpp;
+	drmmode->mode_res = drmModeGetResources(drmmode->fd);
+	if (!drmmode->mode_res)
+		return FALSE;
+
+	xf86CrtcSetSizeRange(pScrn, 320, 200, drmmode->mode_res->max_width, drmmode->mode_res->max_height);
+	for (i = 0; i < drmmode->mode_res->count_crtcs; i++)
+		drmmode_crtc_init(pScrn, drmmode, i);
+
+	for (i = 0; i < drmmode->mode_res->count_connectors; i++)
+		drmmode_output_init(pScrn, drmmode, i);
+
+	xf86InitialConfiguration(pScrn, FALSE);
+
+	return TRUE;
+}
+
+#if 0
+Bool drmmode_set_bufmgr(ScrnInfoPtr pScrn, drmmode_ptr drmmode, dri_bufmgr *bufmgr)
+{
+	drmmode->bufmgr = bufmgr;
+	return TRUE;
+}
+#endif
+
+void drmmode_set_fb(ScrnInfoPtr scrn, drmmode_ptr drmmode, int width, int height, int pitch, uint32_t handle)
+{
+	int ret;
+
+	ret = drmModeAddFB(drmmode->fd, width, height, scrn->depth,
+			   scrn->bitsPerPixel, pitch, handle, &drmmode->fb_id);
+
+	if (ret) {
+		ErrorF("Failed to add fb\n");
+	}
+
+	drmmode->mode_fb = drmModeGetFB(drmmode->fd, drmmode->fb_id);
+	if (!drmmode->mode_fb)
+		return;
+
+
+	ErrorF("Add fb id %d %d %d\n", drmmode->fb_id, width, height);
+}
+
+void drmmode_set_cursor(ScrnInfoPtr scrn, drmmode_ptr drmmode, int id, void *ptr, uint32_t handle)
+{
+  	xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
+	xf86CrtcPtr crtc = xf86_config->crtc[id];
+	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
+	
+
+	drmmode_crtc->cursor_handle = handle;
+	drmmode_crtc->cursor_map = ptr;
+}
+
+#if 0
+Bool drmmode_is_rotate_pixmap(ScrnInfoPtr pScrn, pointer pPixData, dri_bo **bo)
+{
+	xf86CrtcConfigPtr	config = XF86_CRTC_CONFIG_PTR (pScrn);
+	int i;
+
+	for (i = 0; i < config->num_crtc; i++) {
+		xf86CrtcPtr crtc = config->crtc[i];
+		drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
+
+		if (!drmmode_crtc->rotate_bo)
+			continue;
+
+		if (drmmode_crtc->rotate_bo->virtual == pPixData) {
+			*bo = drmmode_crtc->rotate_bo;
+			return TRUE;
+		}
+	}
+	return FALSE;
+
+}
+#endif
+
+static Bool drmmode_resize_fb(ScrnInfoPtr scrn, drmmode_ptr drmmode, int width, int height)
+{
+	uint32_t handle;
+	int pitch;
+	int ret;
+
+	return FALSE;
+
+	if (drmmode->mode_fb->width == width && drmmode->mode_fb->height == height)
+		return TRUE;
+
+	if (!drmmode->create_new_fb)
+		return FALSE;
+
+	handle = drmmode->create_new_fb(scrn, width, height, &pitch);
+	if (handle == 0)
+		return FALSE;
+
+	ret = drmModeReplaceFB(drmmode->fd, drmmode->fb_id, 
+			       width, height,
+			       scrn->depth, scrn->bitsPerPixel, pitch,
+			       handle);
+
+	if (ret)
+		return FALSE;
+
+	drmModeFreeFB(drmmode->mode_fb);
+	drmmode->mode_fb = drmModeGetFB(drmmode->fd, drmmode->fb_id);
+	if (!drmmode->mode_fb)
+		return FALSE;
+	
+	return TRUE;
+}
+
+#endif
+
diff --git a/src/drmmode_display.h b/src/drmmode_display.h
new file mode 100644
index 0000000..59e6307
--- /dev/null
+++ b/src/drmmode_display.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright © 2007 Red Hat, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ *     Dave Airlie <airlied at redhat.com>
+ *
+ */
+#ifndef DRMMODE_DISPLAY_H
+#define DRMMODE_DISPLAY_H
+
+#ifdef XF86DRM_MODE
+
+#include "xf86drmMode.h"
+
+typedef struct {
+  int fd;
+  int fb_id;
+  drmModeResPtr mode_res;
+  drmModeFBPtr mode_fb;
+  int cpp;
+  //  dri_bufmgr *bufmgr;
+
+  uint32_t (*create_new_fb)(ScrnInfoPtr pScrn, int width, int height, int *pitch);
+} drmmode_rec, *drmmode_ptr;
+
+typedef struct {
+
+    drmmode_ptr drmmode;
+    drmModeCrtcPtr mode_crtc;
+    uint32_t cursor_handle;
+    void *cursor_map;
+  //    dri_bo *rotate_bo;
+    int rotate_fb_id;
+} drmmode_crtc_private_rec, *drmmode_crtc_private_ptr;
+
+typedef struct {
+    drmmode_ptr drmmode;
+    int output_id;
+    drmModeConnectorPtr mode_output;
+    drmModeEncoderPtr mode_encoder;
+    drmModePropertyBlobPtr edid_blob;
+} drmmode_output_private_rec, *drmmode_output_private_ptr;
+
+
+extern Bool drmmode_pre_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, char *busId, char *driver_name, int cpp);
+//extern Bool drmmode_set_bufmgr(ScrnInfoPtr pScrn, drmmode_ptr drmmode, dri_bufmgr *bufmgr);
+extern void drmmode_set_fb(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int width, int height, int pitch, uint32_t handle);
+//extern Bool drmmode_is_rotate_pixmap(ScrnInfoPtr pScrn, pointer pPixData, dri_bo **bo);
+extern void drmmode_set_cursor(ScrnInfoPtr scrn, drmmode_ptr drmmode, int id, void *ptr, uint32_t handle);
+#endif
+#endif
diff --git a/src/i830.h b/src/i830.h
index e2b4885..769fd52 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -77,6 +77,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #ifdef DAMAGE
 #include "damage.h"
 #endif
+#include "drmmode_display.h"
 #endif
 #include "dri_bufmgr.h"
 #include "intel_bufmgr.h"
@@ -702,6 +703,12 @@ typedef struct _I830Rec {
 
    enum last_3d *last_3d;
 
+   Bool use_drm_mode;
+#ifdef XF86DRM_MODE
+   drmmode_rec drmmode;
+   int drm_mm_init;
+#endif
+
    /** Enables logging of debug output related to mode switching. */
    Bool debug_modes;
    unsigned int quirk_flag;
@@ -832,7 +839,9 @@ void i830_init_bufmgr(ScrnInfoPtr pScrn);
 Bool i830_allocate_xvmc_buffer(ScrnInfoPtr pScrn, const char *name,
                                i830_memory **buffer, unsigned long size, int flags);
 #endif
-
+extern void i830_update_front_offset(ScrnInfoPtr pScrn);
+extern uint32_t i830_create_new_fb(ScrnInfoPtr pScrn, int width, int height,
+				   int *pitch);
 extern Bool I830IsPrimary(ScrnInfoPtr pScrn);
 
 extern Bool I830I2CInit(ScrnInfoPtr pScrn, I2CBusPtr *bus_ptr, int i2c_reg,
diff --git a/src/i830_bios.c b/src/i830_bios.c
index fe55d23..ff49025 100644
--- a/src/i830_bios.c
+++ b/src/i830_bios.c
@@ -180,11 +180,17 @@ i830_bios_init(ScrnInfoPtr pScrn)
     int vbt_off, bdb_off;
     unsigned char *bios;
     vbeInfoPtr	pVbe;
+    pointer pVBEModule = NULL;
 
     bios = xalloc(INTEL_VBIOS_SIZE);
     if (bios == NULL)
 	return -1;
 
+    /* Load vbe module */
+    if (!(pVBEModule = xf86LoadSubModule(pScrn, "vbe")))
+	return FALSE;
+    xf86LoaderReqSymLists(I810vbeSymbols, NULL);
+
     pVbe = VBEInit(NULL, pI830->pEnt->index);
     if (pVbe != NULL) {
 	memcpy(bios, xf86int10Addr(pVbe->pInt10,
diff --git a/src/i830_dri.c b/src/i830_dri.c
index d40ada5..9d7271e 100644
--- a/src/i830_dri.c
+++ b/src/i830_dri.c
@@ -766,20 +766,22 @@ I830InitTextureHeap(ScrnInfoPtr pScrn)
    }
 }
 
-/**
- * Sets up mappings for static, lifetime-fixed allocations, and inital SAREA
- * setup.
+/*
+ * Map registers & ring buffer
  */
-Bool
-I830DRIDoMappings(ScreenPtr pScreen)
+static Bool
+I830DRIMapHW(ScreenPtr pScreen)
 {
    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
    I830Ptr pI830 = I830PTR(pScrn);
    DRIInfoPtr pDRIInfo = pI830->pDRIInfo;
    I830DRIPtr pI830DRI = pDRIInfo->devPrivate;
-   drmI830Sarea *sarea = (drmI830Sarea *) DRIGetSAREAPrivate(pScreen);
 
-   DPRINTF(PFX, "I830DRIDoMappings\n");
+   /* Kernel deals with direct hw access in this case */
+   if (pI830->use_drm_mode)
+       return TRUE;
+
+   DPRINTF(PFX, "I830DRIMapHW\n");
    pI830DRI->regsSize = I830_REG_SIZE;
    if (drmAddMap(pI830->drmSubFD, (drm_handle_t)pI830->MMIOAddr,
 		 pI830DRI->regsSize, DRM_REGISTERS, 0,
@@ -806,6 +808,27 @@ I830DRIDoMappings(ScreenPtr pScreen)
 		  (int)pI830->ring_map);
    }
 
+   return TRUE;
+}
+
+/**
+ * Sets up mappings for static, lifetime-fixed allocations, and inital SAREA
+ * setup.
+ */
+Bool
+I830DRIDoMappings(ScreenPtr pScreen)
+{
+   ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+   I830Ptr pI830 = I830PTR(pScrn);
+   DRIInfoPtr pDRIInfo = pI830->pDRIInfo;
+   I830DRIPtr pI830DRI = pDRIInfo->devPrivate;
+   drmI830Sarea *sarea = (drmI830Sarea *) DRIGetSAREAPrivate(pScreen);
+
+   if (!I830DRIMapHW(pScreen)) {
+       DRICloseScreen(pScreen);
+       return FALSE;
+   }
+
    if (!I830InitDma(pScrn)) {
       DRICloseScreen(pScreen);
       return FALSE;
diff --git a/src/i830_driver.c b/src/i830_driver.c
index 8ea05af..01073fe 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -177,6 +177,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include "xf86_OSproc.h"
 #include "xf86Resources.h"
 #include "xf86RAC.h"
+#include "xf86Priv.h"
 #include "xf86cmap.h"
 #include "compiler.h"
 #include "mibstore.h"
@@ -426,17 +427,6 @@ I830FreeRec(ScrnInfoPtr pScrn)
    pScrn->driverPrivate = NULL;
 }
 
-static void
-I830ProbeDDC(ScrnInfoPtr pScrn, int index)
-{
-   vbeInfoPtr pVbe;
-
-   /* The vbe module gets loaded in PreInit(), so no need to load it here. */
-
-   pVbe = VBEInit(NULL, index);
-   ConfiguredMonitor = vbeDoEDID(pVbe, NULL);
-}
-
 static int
 I830DetectMemory(ScrnInfoPtr pScrn)
 {
@@ -835,11 +825,12 @@ I830LoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices,
    }
 }
 
-static void
+void
 i830_update_front_offset(ScrnInfoPtr pScrn)
 {
    ScreenPtr pScreen = pScrn->pScreen;
    I830Ptr pI830 = I830PTR(pScrn);
+   int pitch = pScrn->displayWidth * pI830->cpp;
 
    /* Update buffer locations, which may have changed as a result of
     * i830_bind_all_memory().
@@ -851,9 +842,9 @@ i830_update_front_offset(ScrnInfoPtr pScrn)
     */
    if (!pI830->starting && pI830->accel != ACCEL_UXA) {
       if (!pScreen->ModifyPixmapHeader(pScreen->GetScreenPixmap(pScreen),
-				       -1, -1, -1, -1, -1,
-				       (pointer)(pI830->FbBase +
-						 pScrn->fbOffset)))
+				       pScrn->virtualX, pScrn->virtualY, -1, -1,
+				       pitch, (pointer)(pI830->FbBase +
+							pScrn->fbOffset)))
        FatalError("Couldn't adjust screen pixmap\n");
    }
 }
@@ -1116,6 +1107,10 @@ i830SetHotkeyControl(ScrnInfoPtr pScrn, int mode)
    I830Ptr pI830 = I830PTR(pScrn);
    uint8_t gr18;
 
+   /* Don't mess with kernel settings... */
+   if (pI830->use_drm_mode)
+       return;
+
    gr18 = pI830->readControl(pI830, GRX, 0x18);
    if (mode == HOTKEY_BIOS_SWITCH)
       gr18 &= ~HOTKEY_VBIOS_SWITCH_BLOCK;
@@ -1124,6 +1119,45 @@ i830SetHotkeyControl(ScrnInfoPtr pScrn, int mode)
    pI830->writeControl(pI830, GRX, 0x18, gr18);
 }
 
+#ifdef XF86DRM_MODE
+/*
+ * DRM mode setting Linux only at this point... later on we could
+ * add a wrapper here.
+ */
+#include <linux/kd.h>
+
+static Bool i830_kernel_mode_enabled(ScrnInfoPtr pScrn)
+{
+#if XSERVER_LIBPCIACCESS
+    struct pci_device *PciInfo;
+#else
+    pciVideoPtr PciInfo;
+#endif
+    EntityInfoPtr pEnt;
+    char *busIdString;
+    int ret;
+
+    pEnt = xf86GetEntityInfo(pScrn->entityList[0]);
+    PciInfo = xf86GetPciInfoForEntity(pEnt->index);
+
+    if (!xf86LoaderCheckSymbol("DRICreatePCIBusID"))
+	return FALSE;
+
+    busIdString = DRICreatePCIBusID(PciInfo);
+
+    ret = drmCheckModesettingSupported(busIdString);
+    xfree(busIdString);
+    if (ret)
+	return FALSE;
+
+    ioctl(xf86Info.consoleFd, KDSETMODE, KD_TEXT);
+
+    return TRUE;
+}
+#else
+#define i830_kernel_mode_enabled(x) FALSE
+#endif
+
 static Bool
 i830_detect_chipset(ScrnInfoPtr pScrn)
 {
@@ -1133,6 +1167,11 @@ i830_detect_chipset(ScrnInfoPtr pScrn)
     uint32_t capid;
     int fb_bar, mmio_bar;
 
+
+    /* We have to use PIO to probe, because we haven't mapped yet. */
+    if (!pI830->use_drm_mode)
+	I830SetPIOAccess(pI830);
+
     switch (DEVICE_ID(pI830->PciInfo)) {
     case PCI_CHIP_I830_M:
 	chipname = "830M";
@@ -1260,6 +1299,19 @@ i830_detect_chipset(ScrnInfoPtr pScrn)
     xf86DrvMsg(pScrn->scrnIndex, from, "Chipset: \"%s\"\n",
 	       (pScrn->chipset != NULL) ? pScrn->chipset : "Unknown i8xx");
 
+    /* Check if the HW cursor needs physical address. */
+    if (IS_MOBILE(pI830) || IS_I9XX(pI830))
+	pI830->CursorNeedsPhysical = TRUE;
+    else
+	pI830->CursorNeedsPhysical = FALSE;
+
+    if (IS_I965G(pI830) || IS_G33CLASS(pI830))
+	pI830->CursorNeedsPhysical = FALSE;
+
+    /* Skip the rest if the kernel is taking care of things */
+    if (pI830->use_drm_mode)
+	return TRUE;
+
     /* Now that we know the chipset, figure out the resource base addrs */
     if (IS_I9XX(pI830)) {
 	fb_bar = 2;
@@ -1347,6 +1399,342 @@ static const char *accel_name[] =
    "UXA",
 };
 
+static Bool
+I830LoadSyms(ScrnInfoPtr pScrn)
+{
+    I830Ptr pI830 = I830PTR(pScrn);
+
+    if (pI830->use_drm_mode)
+	return TRUE;
+
+    /* Load int10 module */
+    if (!xf86LoadSubModule(pScrn, "int10"))
+	return FALSE;
+    xf86LoaderReqSymLists(I810int10Symbols, NULL);
+
+    /* The vgahw module should be loaded here when needed */
+    if (!xf86LoadSubModule(pScrn, "vgahw"))
+	return FALSE;
+    xf86LoaderReqSymLists(I810vgahwSymbols, NULL);
+
+    return TRUE;
+}
+
+static Bool
+I830GetEarlyOptions(ScrnInfoPtr pScrn)
+{
+    I830Ptr pI830 = I830PTR(pScrn);
+
+    /* Process the options */
+    xf86CollectOptions(pScrn, NULL);
+    if (!(pI830->Options = xalloc(sizeof(I830Options))))
+	return FALSE;
+    memcpy(pI830->Options, I830Options, sizeof(I830Options));
+    xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, pI830->Options);
+
+    if (xf86ReturnOptValBool(pI830->Options, OPTION_MODEDEBUG, FALSE)) {
+	pI830->debug_modes = TRUE;
+    } else {
+	pI830->debug_modes = FALSE;
+    }
+
+    if (xf86ReturnOptValBool(pI830->Options, OPTION_LVDS24BITMODE, FALSE)) {
+	pI830->lvds_24_bit_mode = TRUE;
+    } else {
+	pI830->lvds_24_bit_mode = FALSE;
+    }
+
+    if (xf86ReturnOptValBool(pI830->Options, OPTION_LVDSFIXEDMODE, TRUE)) {
+	pI830->skip_panel_detect = TRUE;
+    } else {
+	pI830->skip_panel_detect = FALSE;
+    }
+
+    if (xf86ReturnOptValBool(pI830->Options, OPTION_FORCEENABLEPIPEA, FALSE))
+	pI830->quirk_flag |= QUIRK_PIPEA_FORCE;
+
+    return TRUE;
+}
+
+static void
+I830PreInitCrtcConfig(ScrnInfoPtr pScrn)
+{
+    xf86CrtcConfigPtr   xf86_config;
+    I830Ptr pI830 = I830PTR(pScrn);
+    int max_width, max_height;
+
+    if (pI830->use_drm_mode)
+	return;
+
+    /* check quirks */
+    i830_fixup_devices(pScrn);
+
+    /* Allocate an xf86CrtcConfig */
+    xf86CrtcConfigInit (pScrn, &i830_xf86crtc_config_funcs);
+    xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+
+    /* See i830_exa.c comments for why we limit the framebuffer size like this.
+     */
+    if (IS_I965G(pI830)) {
+	max_width = 8192;
+	max_height = 8192;
+    } else {
+	max_width = 2048;
+	max_height = 2048;
+    }
+    xf86CrtcSetSizeRange (pScrn, 320, 200, max_width, max_height);
+}
+
+static Bool
+I830AccelMethodInit(ScrnInfoPtr pScrn)
+{
+    I830Ptr pI830 = I830PTR(pScrn);
+    MessageType from = X_PROBED;
+    char *s;
+    int i, num_pipe;
+
+    if (xf86ReturnOptValBool(pI830->Options, OPTION_NOACCEL, FALSE)) {
+	pI830->accel = ACCEL_NONE;
+    }
+
+    /*
+     * The ugliness below:
+     * If either XAA or EXA (exclusive) is compiled in, default to it.
+     *
+     * If both are compiled in, and the user didn't specify noAccel, use the
+     * config option AccelMethod to determine which to use, defaulting to EXA
+     * if none is specified, or if the string was unrecognized.
+     *
+     * All this *could* go away if we removed XAA support from this driver,
+     * for example. :)
+     */
+    if (!(pI830->accel == ACCEL_NONE)) {
+#ifdef I830_USE_UXA
+	pI830->accel = ACCEL_UXA;
+#endif
+#ifdef I830_USE_EXA
+	pI830->accel = ACCEL_EXA;
+#endif
+#if I830_USE_XAA + I830_USE_EXA + I830_USE_UXA >= 2
+	from = X_DEFAULT;
+	if ((s = (char *)xf86GetOptValString(pI830->Options,
+					     OPTION_ACCELMETHOD))) {
+	    if (!xf86NameCmp(s, "EXA")) {
+		from = X_CONFIG;
+		pI830->accel = ACCEL_EXA;
+	    }
+	    else if (!xf86NameCmp(s, "XAA")) {
+		from = X_CONFIG;
+		pI830->accel = ACCEL_XAA;
+	    }
+	    else if (!xf86NameCmp(s, "UXA")) {
+		from = X_CONFIG;
+	       pI830->accel = ACCEL_UXA;
+	    }
+	}
+#endif
+	xf86DrvMsg(pScrn->scrnIndex, from, "Using %s for acceleration\n",
+		   accel_name[pI830->accel]);
+    }
+
+    if (xf86ReturnOptValBool(pI830->Options, OPTION_SW_CURSOR, FALSE)) {
+	pI830->SWCursor = TRUE;
+    }
+
+    pI830->directRenderingDisabled =
+	!xf86ReturnOptValBool(pI830->Options, OPTION_DRI, TRUE);
+
+#ifdef XF86DRI
+    if (!pI830->directRenderingDisabled) {
+	if ((pI830->accel == ACCEL_NONE) || pI830->SWCursor) {
+	    xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "DRI is disabled because it "
+		       "needs HW cursor and 2D acceleration.\n");
+	    pI830->directRenderingDisabled = TRUE;
+	} else if (pScrn->depth != 16 && pScrn->depth != 24) {
+	    xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "DRI is disabled because it "
+		       "runs only at depths 16 and 24.\n");
+	    pI830->directRenderingDisabled = TRUE;
+	}
+
+	if (!pI830->directRenderingDisabled) {
+	    pI830->allocate_classic_textures = TRUE;
+
+	    from = X_PROBED;
+
+#ifdef XF86DRI_MM
+	    if (!IS_I965G(pI830)) {
+		Bool tmp;
+
+		if (xf86GetOptValBool(pI830->Options,
+				      OPTION_INTELTEXPOOL, &tmp)) {
+		    from = X_CONFIG;
+		    if (!tmp)
+			pI830->allocate_classic_textures = FALSE;
+		}
+	    }
+#endif /* XF86DRI_MM */
+	}
+    }
+#endif /* XF86DRI */
+
+    I830MapMMIO(pScrn);
+
+    if (pI830->debug_modes) {
+	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+		   "Hardware state on X startup:\n");
+	i830DumpRegs (pScrn);
+    }
+
+    i830TakeRegSnapshot(pScrn);
+
+    if (DEVICE_ID(pI830->PciInfo) == PCI_CHIP_E7221_G)
+	num_pipe = 1;
+    else
+	if (IS_MOBILE(pI830) || IS_I9XX(pI830))
+	    num_pipe = 2;
+	else
+	    num_pipe = 1;
+    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "%d display pipe%s available.\n",
+	       num_pipe, num_pipe > 1 ? "s" : "");
+
+    I830PreInitDDC(pScrn);
+    for (i = 0; i < num_pipe; i++) {
+	i830_crtc_init(pScrn, i);
+    }
+    I830SetupOutputs(pScrn);
+
+    SaveHWState(pScrn);
+    if (!xf86InitialConfiguration (pScrn, FALSE))
+    {
+	xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes.\n");
+	RestoreHWState(pScrn);
+	PreInitCleanup(pScrn);
+	return FALSE;
+    }
+    RestoreHWState(pScrn);
+
+    /* XXX This should go away, replaced by xf86Crtc.c support for it */
+    pI830->rotation = RR_Rotate_0;
+
+    /*
+     * Let's setup the mobile systems to check the lid status
+     */
+    if (IS_MOBILE(pI830)) {
+	pI830->checkDevices = TRUE;
+
+	if (!xf86ReturnOptValBool(pI830->Options, OPTION_CHECKDEVICES, TRUE)) {
+	    pI830->checkDevices = FALSE;
+	    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Monitoring connected displays disabled\n");
+	} else
+	    if (pI830->entityPrivate && !I830IsPrimary(pScrn) &&
+		!I830PTR(pI830->entityPrivate->pScrn_1)->checkDevices) {
+		/* If checklid is off, on the primary head, then
+		 * turn it off on the secondary*/
+		xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Monitoring connected displays disabled\n");
+		pI830->checkDevices = FALSE;
+	    } else
+		xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Monitoring connected displays enabled\n");
+    } else
+	pI830->checkDevices = FALSE;
+
+    pI830->stolen_size = I830DetectMemory(pScrn);
+
+    return TRUE;
+}
+
+static Bool
+I830DrmModeInit(ScrnInfoPtr pScrn)
+{
+#ifdef XF86DRM_MODE
+    I830Ptr pI830 = I830PTR(pScrn);
+    char *bus_id;
+
+    bus_id = DRICreatePCIBusID(pI830->PciInfo);
+    if (drmmode_pre_init(pScrn, &pI830->drmmode, bus_id, "i915",
+			 pI830->cpp) == FALSE) {
+	xfree(bus_id);
+	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+		   "Kernel modesetting setup failed\n");
+	PreInitCleanup(pScrn);
+	return FALSE;
+    }
+
+    pI830->drmmode.create_new_fb = i830_create_new_fb;
+
+    pI830->drmSubFD = pI830->drmmode.fd;
+    xfree(bus_id);
+
+    pI830->accel = ACCEL_EXA;
+    pI830->directRenderingDisabled = FALSE;
+    pI830->allocate_classic_textures = FALSE;
+
+    I830InitBufMgr(pScrn);
+#endif
+
+    return TRUE;
+}
+
+static void
+I830XvInit(ScrnInfoPtr pScrn)
+{
+    I830Ptr pI830 = I830PTR(pScrn);
+    MessageType from = X_PROBED;
+
+    pI830->XvDisabled =
+	!xf86ReturnOptValBool(pI830->Options, OPTION_XVIDEO, TRUE);
+
+#ifdef I830_XV
+    if (xf86GetOptValInteger(pI830->Options, OPTION_VIDEO_KEY,
+			     &(pI830->colorKey))) {
+	from = X_CONFIG;
+    } else if (xf86GetOptValInteger(pI830->Options, OPTION_COLOR_KEY,
+				    &(pI830->colorKey))) {
+	from = X_CONFIG;
+    } else {
+	pI830->colorKey =
+	    (1 << pScrn->offset.red) | (1 << pScrn->offset.green) |
+	    (((pScrn->mask.blue >> pScrn->offset.blue) - 1) <<
+	     pScrn->offset.blue);
+	from = X_DEFAULT;
+    }
+    xf86DrvMsg(pScrn->scrnIndex, from, "video overlay key set to 0x%x\n",
+	       pI830->colorKey);
+#endif
+#ifdef INTEL_XVMC
+    pI830->XvMCEnabled = FALSE;
+    from =  (!pI830->directRenderingDisabled &&
+	     xf86GetOptValBool(pI830->Options, OPTION_XVMC,
+			       &pI830->XvMCEnabled)) ? X_CONFIG : X_DEFAULT;
+    xf86DrvMsg(pScrn->scrnIndex, from, "Intel XvMC decoder %sabled\n",
+	       pI830->XvMCEnabled ? "en" : "dis");
+#endif
+}
+
+static void
+I830DriOptsInit(ScrnInfoPtr pScrn)
+{
+#ifdef XF86DRI
+    I830Ptr pI830 = I830PTR(pScrn);
+    MessageType from = X_PROBED;
+
+    pI830->allowPageFlip = FALSE;
+    from = (!pI830->directRenderingDisabled &&
+	    xf86GetOptValBool(pI830->Options, OPTION_PAGEFLIP,
+			      &pI830->allowPageFlip)) ? X_CONFIG : X_DEFAULT;
+
+    xf86DrvMsg(pScrn->scrnIndex, from, "Will%s try to enable page flipping\n",
+	       pI830->allowPageFlip ? "" : " not");
+
+    pI830->TripleBuffer = FALSE;
+    from =  (!pI830->directRenderingDisabled &&
+	     xf86GetOptValBool(pI830->Options, OPTION_TRIPLEBUFFER,
+			       &pI830->TripleBuffer)) ? X_CONFIG : X_DEFAULT;
+
+    xf86DrvMsg(pScrn->scrnIndex, from, "Triple buffering %sabled\n",
+	       pI830->TripleBuffer ? "en" : "dis");
+#endif /* XF86DRI */
+}
+
 /**
  * This is called per zaphod head (so usually just once) to do initialization
  * before the Screen is created.
@@ -1357,48 +1745,24 @@ static const char *accel_name[] =
 static Bool
 I830PreInit(ScrnInfoPtr pScrn, int flags)
 {
-   xf86CrtcConfigPtr   xf86_config;
    vgaHWPtr hwp;
    I830Ptr pI830;
-   MessageType from = X_PROBED;
    rgb defaultWeight = { 0, 0, 0 };
    EntityInfoPtr pEnt;
-   I830EntPtr pI830Ent = NULL;					
+   I830EntPtr pI830Ent = NULL;
    int flags24;
-   int i;
-   char *s;
-   pointer pVBEModule = NULL;
-   int num_pipe;
-   int max_width, max_height;
+   Gamma zeros = { 0.0, 0.0, 0.0 };
+   int drm_mode_setting;
 
    if (pScrn->numEntities != 1)
       return FALSE;
 
-   /* Load int10 module */
-   if (!xf86LoadSubModule(pScrn, "int10"))
-      return FALSE;
-   xf86LoaderReqSymLists(I810int10Symbols, NULL);
-
-   /* Load vbe module */
-   if (!(pVBEModule = xf86LoadSubModule(pScrn, "vbe")))
-      return FALSE;
-   xf86LoaderReqSymLists(I810vbeSymbols, NULL);
+   drm_mode_setting = i830_kernel_mode_enabled(pScrn);
 
    pEnt = xf86GetEntityInfo(pScrn->entityList[0]);
 
-   if (flags & PROBE_DETECT) {
-      I830ProbeDDC(pScrn, pEnt->index);
-      return TRUE;
-   }
-
-   /* The vgahw module should be loaded here when needed */
-   if (!xf86LoadSubModule(pScrn, "vgahw"))
-      return FALSE;
-   xf86LoaderReqSymLists(I810vgahwSymbols, NULL);
-
-   /* Allocate a vgaHWRec */
-   if (!vgaHWGetHWRec(pScrn))
-      return FALSE;
+   if (flags & PROBE_DETECT)
+       return TRUE;
 
    /* Allocate driverPrivate */
    if (!I830GetRec(pScrn))
@@ -1407,6 +1771,17 @@ I830PreInit(ScrnInfoPtr pScrn, int flags)
    pI830 = I830PTR(pScrn);
    pI830->SaveGeneration = -1;
    pI830->pEnt = pEnt;
+   pI830->use_drm_mode = drm_mode_setting;
+
+   if (!I830LoadSyms(pScrn))
+       return FALSE;
+
+   if (!drm_mode_setting) {
+       /* Allocate a vgaHWRec */
+       if (!vgaHWGetHWRec(pScrn))
+	   return FALSE;
+       hwp = VGAHWPTR(pScrn);
+   }
 
    pScrn->displayWidth = 640; /* default it */
 
@@ -1424,7 +1799,7 @@ I830PreInit(ScrnInfoPtr pScrn, int flags)
 	pI830Ent = xf86GetEntityPrivate(pScrn->entityList[0],
 					I830EntityIndex)->ptr;
         pI830->entityPrivate = pI830Ent;
-    } else 
+    } else
         pI830->entityPrivate = NULL;
 
    if (xf86RegisterResources(pI830->pEnt->index, NULL, ResNone)) {
@@ -1490,284 +1865,31 @@ I830PreInit(ScrnInfoPtr pScrn, int flags)
 
    pI830->preinit = TRUE;
 
-   /* Process the options */
-   xf86CollectOptions(pScrn, NULL);
-   if (!(pI830->Options = xalloc(sizeof(I830Options))))
-      return FALSE;
-   memcpy(pI830->Options, I830Options, sizeof(I830Options));
-   xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, pI830->Options);
-
-   if (xf86ReturnOptValBool(pI830->Options, OPTION_MODEDEBUG, FALSE)) {
-      pI830->debug_modes = TRUE;
-   } else {
-      pI830->debug_modes = FALSE;
-   }
-
-   if (xf86ReturnOptValBool(pI830->Options, OPTION_LVDS24BITMODE, FALSE)) {
-      pI830->lvds_24_bit_mode = TRUE;
-   } else {
-      pI830->lvds_24_bit_mode = FALSE;
-   }
-
-   if (xf86ReturnOptValBool(pI830->Options, OPTION_LVDSFIXEDMODE, TRUE)) {
-      pI830->skip_panel_detect = TRUE;
-   } else {
-      pI830->skip_panel_detect = FALSE;
-   }
-
-   if (xf86ReturnOptValBool(pI830->Options, OPTION_FORCEENABLEPIPEA, FALSE))
-       pI830->quirk_flag |= QUIRK_PIPEA_FORCE;
-
-   /* We have to use PIO to probe, because we haven't mapped yet. */
-   I830SetPIOAccess(pI830);
+   if (!I830GetEarlyOptions(pScrn))
+       return FALSE;
 
    if (!i830_detect_chipset(pScrn))
        return FALSE;
 
-   /* check quirks */
-   i830_fixup_devices(pScrn);
-
-   /* Allocate an xf86CrtcConfig */
-   xf86CrtcConfigInit (pScrn, &i830_xf86crtc_config_funcs);
-   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
-
-   /* See i830_exa.c comments for why we limit the framebuffer size like this.
-    */
-   if (IS_I965G(pI830)) {
-      max_width = 8192;
-      max_height = 8192;
-   } else {
-      max_width = 2048;
-      max_height = 2048;
-   }
-   xf86CrtcSetSizeRange (pScrn, 320, 200, max_width, max_height);
-
-   /* Some of the probing needs MMIO access, so map it here. */
-   I830MapMMIO(pScrn);
+   I830PreInitCrtcConfig(pScrn);
 
-   if (pI830->debug_modes) {
-      xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Hardware state on X startup:\n");
-      i830DumpRegs (pScrn);
-   }
-
-   i830TakeRegSnapshot(pScrn);
+   if (pI830->use_drm_mode && !I830DrmModeInit(pScrn))
+       return FALSE;
+   else if (!I830AccelMethodInit(pScrn))
+       return FALSE;
 
-   if (DEVICE_ID(pI830->PciInfo) == PCI_CHIP_E7221_G)
-      num_pipe = 1;
-   else
-   if (IS_MOBILE(pI830) || IS_I9XX(pI830))
-      num_pipe = 2;
-   else
-      num_pipe = 1;
-   xf86DrvMsg(pScrn->scrnIndex, X_INFO, "%d display pipe%s available.\n",
-	      num_pipe, num_pipe > 1 ? "s" : "");
+   I830XvInit(pScrn);
 
-   if (xf86ReturnOptValBool(pI830->Options, OPTION_NOACCEL, FALSE)) {
-      pI830->accel = ACCEL_NONE;
-   }
+   I830DriOptsInit(pScrn);
 
-   /*
-    * The ugliness below:
-    * If either XAA or EXA (exclusive) is compiled in, default to it.
-    * 
-    * If both are compiled in, and the user didn't specify noAccel, use the
-    * config option AccelMethod to determine which to use, defaulting to EXA
-    * if none is specified, or if the string was unrecognized.
-    *
-    * All this *could* go away if we removed XAA support from this driver,
-    * for example. :)
-    */
-   if (pI830->accel == ACCEL_UNINIT) {
-      pI830->accel = ACCEL_NONE;
-#ifdef I830_USE_XAA
-      pI830->accel = ACCEL_XAA;
-#endif
-#ifdef I830_USE_UXA
-      pI830->accel = ACCEL_UXA;
-#endif
-#ifdef I830_USE_EXA
-      pI830->accel = ACCEL_EXA;
-#endif
-#if I830_USE_XAA + I830_USE_EXA + I830_USE_UXA >= 2
-       from = X_DEFAULT;
-       if ((s = (char *)xf86GetOptValString(pI830->Options,
-					    OPTION_ACCELMETHOD))) {
-	   if (!xf86NameCmp(s, "EXA")) {
-	       from = X_CONFIG;
-	       pI830->accel = ACCEL_EXA;
-	   }
-	   else if (!xf86NameCmp(s, "XAA")) {
-	       from = X_CONFIG;
-	       pI830->accel = ACCEL_XAA;
-	   }
-	   else if (!xf86NameCmp(s, "UXA")) {
-	       from = X_CONFIG;
-	       pI830->accel = ACCEL_UXA;
-	   }
-       }
-#endif
-   }
-   xf86DrvMsg(pScrn->scrnIndex, from, "Using %s acceleration\n",
-	      accel_name[pI830->accel]);
-
-   if (xf86ReturnOptValBool(pI830->Options, OPTION_SW_CURSOR, FALSE)) {
-      pI830->SWCursor = TRUE;
+   if (!xf86SetGamma(pScrn, zeros)) {
+       PreInitCleanup(pScrn);
+       return FALSE;
    }
 
-   pI830->directRenderingDisabled =
-	!xf86ReturnOptValBool(pI830->Options, OPTION_DRI, TRUE);
-
-#ifdef XF86DRI
-   if (!pI830->directRenderingDisabled) {
-      if (pI830->accel == ACCEL_NONE || pI830->SWCursor) {
-	 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "DRI is disabled because it "
-		    "needs HW cursor and 2D acceleration.\n");
-	 pI830->directRenderingDisabled = TRUE;
-      } else if (pScrn->depth != 16 && pScrn->depth != 24) {
-	 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "DRI is disabled because it "
-		    "runs only at depths 16 and 24.\n");
-	 pI830->directRenderingDisabled = TRUE;
-      }
-
-      if (!pI830->directRenderingDisabled) {
-	 pI830->allocate_classic_textures = TRUE;
-
-	 from = X_PROBED;
-
-#ifdef XF86DRI
-	 if (!IS_I965G(pI830)) {
-	    Bool tmp;
-
-	    if (xf86GetOptValBool(pI830->Options,
-				  OPTION_INTELTEXPOOL, &tmp)) {
-	       from = X_CONFIG;
-	       if (!tmp)
-		  pI830->allocate_classic_textures = FALSE;
-	    }
-	 }
-#endif
-      }
-   } 
-   
-#endif
-
    if (i830_bios_init(pScrn))
-      xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
-		 "VBIOS initialization failed.\n");
-
-   I830PreInitDDC(pScrn);
-   for (i = 0; i < num_pipe; i++) {
-       i830_crtc_init(pScrn, i);
-   }
-   I830SetupOutputs(pScrn);
-
-   SaveHWState(pScrn);
-   if (!xf86InitialConfiguration (pScrn, FALSE))
-   {
-      xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes.\n");
-      RestoreHWState(pScrn);
-      PreInitCleanup(pScrn);
-      return FALSE;
-   }
-   RestoreHWState(pScrn);
-
-   /* XXX This should go away, replaced by xf86Crtc.c support for it */
-   pI830->rotation = RR_Rotate_0;
-
-   /*
-    * Let's setup the mobile systems to check the lid status
-    */
-   if (IS_MOBILE(pI830)) {
-      pI830->checkDevices = TRUE;
-
-      if (!xf86ReturnOptValBool(pI830->Options, OPTION_CHECKDEVICES, TRUE)) {
-         pI830->checkDevices = FALSE;
-         xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Monitoring connected displays disabled\n");
-      } else
-      if (pI830->entityPrivate && !I830IsPrimary(pScrn) &&
-          !I830PTR(pI830->entityPrivate->pScrn_1)->checkDevices) {
-         /* If checklid is off, on the primary head, then 
-          * turn it off on the secondary*/
-         xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Monitoring connected displays disabled\n");
-         pI830->checkDevices = FALSE;
-      } else
-         xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Monitoring connected displays enabled\n");
-   } else
-      pI830->checkDevices = FALSE;
-
-   pI830->stolen_size = I830DetectMemory(pScrn);
-
-   pI830->XvDisabled =
-	!xf86ReturnOptValBool(pI830->Options, OPTION_XVIDEO, TRUE);
-
-#ifdef I830_XV
-   if (xf86GetOptValInteger(pI830->Options, OPTION_VIDEO_KEY,
-			    &(pI830->colorKey))) {
-      from = X_CONFIG;
-   } else if (xf86GetOptValInteger(pI830->Options, OPTION_COLOR_KEY,
-			    &(pI830->colorKey))) {
-      from = X_CONFIG;
-   } else {
-      pI830->colorKey = (1 << pScrn->offset.red) |
-			(1 << pScrn->offset.green) |
-			(((pScrn->mask.blue >> pScrn->offset.blue) - 1) <<
-			 pScrn->offset.blue);
-      from = X_DEFAULT;
-   }
-   xf86DrvMsg(pScrn->scrnIndex, from, "video overlay key set to 0x%x\n",
-	      pI830->colorKey);
-#endif
-
-#ifdef XF86DRI
-   pI830->allowPageFlip = FALSE;
-   from = (!pI830->directRenderingDisabled &&
-	   xf86GetOptValBool(pI830->Options, OPTION_PAGEFLIP,
-			     &pI830->allowPageFlip)) ? X_CONFIG : X_DEFAULT;
-
-   xf86DrvMsg(pScrn->scrnIndex, from, "Will%s try to enable page flipping\n",
-	      pI830->allowPageFlip ? "" : " not");
-#endif
-
-#ifdef XF86DRI
-   pI830->TripleBuffer = FALSE;
-   from =  (!pI830->directRenderingDisabled &&
-	    xf86GetOptValBool(pI830->Options, OPTION_TRIPLEBUFFER,
-			      &pI830->TripleBuffer)) ? X_CONFIG : X_DEFAULT;
-
-   xf86DrvMsg(pScrn->scrnIndex, from, "Triple buffering %sabled\n",
-	      pI830->TripleBuffer ? "en" : "dis");
-#endif
-
-#ifdef INTEL_XVMC
-   pI830->XvMCEnabled = FALSE;
-   from =  (!pI830->directRenderingDisabled &&
-	    xf86GetOptValBool(pI830->Options, OPTION_XVMC,
-			      &pI830->XvMCEnabled)) ? X_CONFIG : X_DEFAULT;
-   xf86DrvMsg(pScrn->scrnIndex, from, "Intel XvMC decoder %sabled\n",
-	   pI830->XvMCEnabled ? "en" : "dis");
-#endif
-
-   /*
-    * If the driver can do gamma correction, it should call xf86SetGamma() here.
-    */
-
-   {
-      Gamma zeros = { 0.0, 0.0, 0.0 };
-
-      if (!xf86SetGamma(pScrn, zeros)) {
-         PreInitCleanup(pScrn);
-	 return FALSE;
-      }
-   }
-
-   /* Check if the HW cursor needs physical address. */
-   if (IS_MOBILE(pI830) || IS_I9XX(pI830))
-      pI830->CursorNeedsPhysical = TRUE;
-   else
-      pI830->CursorNeedsPhysical = FALSE;
-
-   if (IS_I965G(pI830) || IS_G33CLASS(pI830))
-      pI830->CursorNeedsPhysical = FALSE;
+       xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+		  "VBIOS initialization failed.\n");
 
    /*
     * XXX If we knew the pre-initialised GTT format for certain, we could
@@ -1780,8 +1902,8 @@ I830PreInit(ScrnInfoPtr pScrn, int flags)
 		 "Using HW Cursor because it's enabled on primary head.\n");
           pI830->SWCursor = FALSE;
         }
-   } else 
-   if (pI830->StolenOnly && pI830->CursorNeedsPhysical && !pI830->SWCursor) {
+   } else if (pI830->StolenOnly && pI830->CursorNeedsPhysical &&
+	      !pI830->SWCursor) {
       xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
 		 "HW Cursor disabled because it needs agpgart memory.\n");
       pI830->SWCursor = TRUE;
@@ -1854,21 +1976,16 @@ I830PreInit(ScrnInfoPtr pScrn, int flags)
       xf86LoaderReqSymLists(I810ramdacSymbols, NULL);
    }
 
-   i830CompareRegsToSnapshot(pScrn, "After PreInit");
+   if (!pI830->use_drm_mode) {
+       i830CompareRegsToSnapshot(pScrn, "After PreInit");
 
-   I830UnmapMMIO(pScrn);
-
-   /*  We won't be using the VGA access after the probe. */
-   I830SetMMIOAccess(pI830);
-   xf86SetOperatingState(resVgaIo, pI830->pEnt->index, ResUnusedOpr);
-   xf86SetOperatingState(resVgaMem, pI830->pEnt->index, ResDisableOpr);
+       I830UnmapMMIO(pScrn);
 
-#if 0
-   if (I830IsPrimary(pScrn)) {
-      vbeFree(pI830->pVbe);
+       /*  We won't be using the VGA access after the probe. */
+       I830SetMMIOAccess(pI830);
+       xf86SetOperatingState(resVgaIo, pI830->pEnt->index, ResUnusedOpr);
+       xf86SetOperatingState(resVgaMem, pI830->pEnt->index, ResDisableOpr);
    }
-   pI830->pVbe = NULL;
-#endif
 
 #if defined(XF86DRI)
    /* Load the dri module if requested. */
@@ -2819,68 +2936,16 @@ i830_init_bufmgr(ScrnInfoPtr pScrn)
 }
 
 
-static Bool
-I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
+static void
+I830AdjustMemory(ScreenPtr pScreen)
 {
    ScrnInfoPtr pScrn;
-   vgaHWPtr hwp;
    I830Ptr pI830;
-   VisualPtr visual;
-   I830Ptr pI8301 = NULL;
    unsigned long sys_mem;
-   int c;
    MessageType from;
-#ifdef XF86DRI
-   xf86CrtcConfigPtr config;
-#endif
 
    pScrn = xf86Screens[pScreen->myNum];
    pI830 = I830PTR(pScrn);
-   hwp = VGAHWPTR(pScrn);
-
-   pScrn->displayWidth = (pScrn->virtualX + 63) & ~63;
-
-   /*
-    * The "VideoRam" config file parameter specifies the maximum amount of
-    * memory that will be used/allocated.  When not present, we allow the
-    * driver to allocate as much memory as it wishes to satisfy its
-    * allocations, but if agpgart support isn't available, it gets limited
-    * to the amount of pre-allocated ("stolen") memory.
-    *
-    * Note that in using this value for allocator initialization, we're
-    * limiting aperture allocation to the VideoRam option, rather than limiting
-    * actual memory allocation, so alignment and things will cause less than
-    * VideoRam to be actually used.
-    */
-   if (pI830->pEnt->device->videoRam == 0) {
-      from = X_DEFAULT;
-      pScrn->videoRam = pI830->FbMapSize / KB(1);
-   } else {
-#if 0
-      from = X_CONFIG;
-      pScrn->videoRam = pI830->pEnt->device->videoRam;
-#else
-      /* Disable VideoRam configuration, at least for now.  Previously,
-       * VideoRam was necessary to avoid overly low limits on allocated
-       * memory, so users created larger, yet still small, fixed allocation
-       * limits in their config files.  Now, the driver wants to allocate more,
-       * and the old intention of the VideoRam lines that had been entered is
-       * obsolete.
-       */
-      from = X_DEFAULT;
-      pScrn->videoRam = pI830->FbMapSize / KB(1);
-
-      if (pScrn->videoRam != pI830->pEnt->device->videoRam) {
-	 xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
-		    "VideoRam configuration found, which is no longer "
-		    "recommended.\n");
-	 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-		    "Continuing with default %dkB VideoRam instead of %d "
-		    "kB.\n",
-		    pScrn->videoRam, pI830->pEnt->device->videoRam);
-      }
-#endif
-   }
 
    /* Limit videoRam to how much we might be able to allocate from AGP */
    sys_mem = I830CheckAvailableMemory(pScrn);
@@ -2931,6 +2996,129 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
 		 "Cannot support DRI with frame buffer width > 2048.\n");
       pI830->directRenderingDisabled = TRUE;
    }
+}
+
+static void
+I830SwapPipes(ScrnInfoPtr pScrn)
+{
+   I830Ptr pI830 = I830PTR(pScrn);
+   xf86CrtcConfigPtr config;
+   int c;
+
+   config = XF86_CRTC_CONFIG_PTR(pScrn);
+
+   /*
+    * If an LVDS display is present, swap the plane/pipe mappings so we can
+    * use FBC on the builtin display.
+    * Note: 965+ chips can compress either plane, so we leave the mapping
+    *       alone in that case.
+    * Also make sure the DRM can handle the swap.
+    */
+   if (I830LVDSPresent(pScrn) && !IS_I965GM(pI830) && !IS_GM45(pI830) &&
+       (!pI830->directRenderingEnabled ||
+	(pI830->directRenderingEnabled && pI830->drmMinor >= 10))) {
+       xf86DrvMsg(pScrn->scrnIndex, X_INFO, "adjusting plane->pipe mappings "
+		  "to allow for framebuffer compression\n");
+       for (c = 0; c < config->num_crtc; c++) {
+	   xf86CrtcPtr	      crtc = config->crtc[c];
+	   I830CrtcPrivatePtr   intel_crtc = crtc->driver_private;
+
+	   if (intel_crtc->pipe == 0)
+	       intel_crtc->plane = 1;
+	   else if (intel_crtc->pipe == 1)
+	       intel_crtc->plane = 0;
+      }
+   }
+}
+
+static Bool
+I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
+{
+   ScrnInfoPtr pScrn;
+   vgaHWPtr hwp;
+   I830Ptr pI830;
+   VisualPtr visual;
+   I830Ptr pI8301 = NULL;
+   MessageType from;
+
+   pScrn = xf86Screens[pScreen->myNum];
+   pI830 = I830PTR(pScrn);
+
+   if (!pI830->use_drm_mode)
+       hwp = VGAHWPTR(pScrn);
+
+   pScrn->displayWidth = (pScrn->virtualX + 63) & ~63;
+
+   /*
+    * The "VideoRam" config file parameter specifies the maximum amount of
+    * memory that will be used/allocated.  When not present, we allow the
+    * driver to allocate as much memory as it wishes to satisfy its
+    * allocations, but if agpgart support isn't available, it gets limited
+    * to the amount of pre-allocated ("stolen") memory.
+    *
+    * Note that in using this value for allocator initialization, we're
+    * limiting aperture allocation to the VideoRam option, rather than limiting
+    * actual memory allocation, so alignment and things will cause less than
+    * VideoRam to be actually used.
+    */
+   if (pI830->pEnt->device->videoRam == 0) {
+      from = X_DEFAULT;
+      pScrn->videoRam = pI830->FbMapSize / KB(1);
+   } else {
+#if 0
+      from = X_CONFIG;
+      pScrn->videoRam = pI830->pEnt->device->videoRam;
+#else
+      /* Disable VideoRam configuration, at least for now.  Previously,
+       * VideoRam was necessary to avoid overly low limits on allocated
+       * memory, so users created larger, yet still small, fixed allocation
+       * limits in their config files.  Now, the driver wants to allocate more,
+       * and the old intention of the VideoRam lines that had been entered is
+       * obsolete.
+       */
+      from = X_DEFAULT;
+      pScrn->videoRam = pI830->FbMapSize / KB(1);
+
+      if (pScrn->videoRam != pI830->pEnt->device->videoRam) {
+	 xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+		    "VideoRam configuration found, which is no longer "
+		    "recommended.\n");
+	 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+		    "Continuing with default %dkB VideoRam instead of %d "
+		    "kB.\n",
+		    pScrn->videoRam, pI830->pEnt->device->videoRam);
+      }
+#endif
+   }
+
+   if (pI830->use_drm_mode) {
+#ifdef XF86DRM_MODE
+       uint64_t size;
+       int ret;
+       ret = drmMMInfo(pI830->drmSubFD, DRM_BO_MEM_VRAM, &size);
+       if (ret) {
+         xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+                     "Kernel memory manager has no VRAM allocation\n");
+          return FALSE;
+       }
+       pI830->stolen_size = size * GTT_PAGE_SIZE;
+       xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+                 "Kernel stolen allocator is %dkb\n",
+		  pI830->stolen_size / KB(1));
+
+       ret = drmMMInfo(pI830->drmSubFD, DRM_BO_MEM_TT, &size);
+       if (ret) {
+          xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+                     "Kernel memory manager has no TT allocation\n");
+          return FALSE;
+       }
+       pScrn->videoRam = (size * GTT_PAGE_SIZE) / KB(1);
+       xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+                 "Kernel AGP allocator is %dkb\n", pScrn->videoRam);
+#endif
+    } else {
+       I830AdjustMemory(pScreen);
+   }
 
 #ifdef XF86DRI
    /* If DRI hasn't been explicitly disabled, try to initialize it.
@@ -2969,6 +3157,12 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
 	   pI830->fb_compression = FALSE;
    }
 
+   if (pI830->use_drm_mode && pI830->fb_compression == TRUE) {
+       xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+		  "Kernel mode setting active, disabling FBC.\n");
+       pI830->fb_compression = FALSE;
+   }
+
    xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Framebuffer compression %sabled\n",
 	      pI830->fb_compression ? "en" : "dis");
    xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Tiling %sabled\n", pI830->tiling ?
@@ -3010,7 +3204,8 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
 
 
    /* Need MMIO mapped to do GTT lookups during memory allocation. */
-   I830MapMMIO(pScrn);
+   if (!pI830->use_drm_mode)
+       I830MapMMIO(pScrn);
 
    if (!i830_memory_init(pScrn)) {
        xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
@@ -3051,7 +3246,7 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
    pI830->XvEnabled = FALSE;
 #endif
 
-   if (pI830->accel != ACCEL_NONE) {
+   if (pI830->accel != ACCEL_NONE && !pI830->use_drm_mode) {
       if (pI830->memory_manager == NULL && pI830->LpRing->mem->size == 0) {
 	  xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
 		     "Disabling acceleration because the ring buffer "
@@ -3092,69 +3287,49 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
    }
 
    if (pI830->directRenderingEnabled)
-      pI830->directRenderingEnabled = I830DRIDoMappings(pScreen);
+       pI830->directRenderingEnabled = I830DRIDoMappings(pScreen);
 
    /* If we failed for any reason, free DRI memory. */
    if (!pI830->directRenderingEnabled)
-      i830_free_3d_memory(pScrn);
-
-   config = XF86_CRTC_CONFIG_PTR(pScrn);
-
-   /*
-    * If an LVDS display is present, swap the plane/pipe mappings so we can
-    * use FBC on the builtin display.
-    * Note: 965+ chips can compress either plane, so we leave the mapping
-    *       alone in that case.
-    * Also make sure the DRM can handle the swap.
-    */
-   if (I830LVDSPresent(pScrn) && !IS_I965GM(pI830) && !IS_GM45(pI830) &&
-       (!pI830->directRenderingEnabled ||
-	(pI830->directRenderingEnabled && pI830->drmMinor >= 10))) {
-       xf86DrvMsg(pScrn->scrnIndex, X_INFO, "adjusting plane->pipe mappings "
-		  "to allow for framebuffer compression\n");
-       for (c = 0; c < config->num_crtc; c++) {
-	   xf86CrtcPtr	      crtc = config->crtc[c];
-	   I830CrtcPrivatePtr   intel_crtc = crtc->driver_private;
-
-	   if (intel_crtc->pipe == 0)
-	       intel_crtc->plane = 1;
-	   else if (intel_crtc->pipe == 1)
-	       intel_crtc->plane = 0;
-      }
-   }
+       i830_free_3d_memory(pScrn);
 
+   if (!pI830->use_drm_mode)
+       I830SwapPipes(pScrn);
 #else
    pI830->directRenderingEnabled = FALSE;
 #endif
 
 #ifdef XF86DRI
-
    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Page Flipping %sabled\n",
 	      pI830->allowPageFlip ? "en" : "dis");
 #endif
 
-   DPRINTF(PFX, "assert( if(!I830MapMem(pScrn)) )\n");
-   if (!I830MapMem(pScrn))
-      return FALSE;
+   if (!pI830->use_drm_mode) {
+       DPRINTF(PFX, "assert( if(!I830MapMem(pScrn)) )\n");
+       if (!I830MapMem(pScrn))
+ 	   return FALSE;
 
-   pScrn->memPhysBase = (unsigned long)pI830->FbBase;
+       pScrn->memPhysBase = (unsigned long)pI830->FbBase;
+   }
 
    if (I830IsPrimary(pScrn)) {
-      pScrn->fbOffset = pI830->front_buffer->offset;
+        pScrn->fbOffset = pI830->front_buffer->offset;
    } else {
-      pScrn->fbOffset = pI8301->front_buffer_2->offset;
+       pScrn->fbOffset = pI8301->front_buffer_2->offset;
    }
 
    pI830->xoffset = (pScrn->fbOffset / pI830->cpp) % pScrn->displayWidth;
    pI830->yoffset = (pScrn->fbOffset / pI830->cpp) / pScrn->displayWidth;
 
-   i830_init_bufmgr(pScrn);
+   if (!pI830->use_drm_mode) {
+       vgaHWSetMmioFuncs(hwp, pI830->MMIOBase, 0);
+       vgaHWGetIOBase(hwp);
+       DPRINTF(PFX, "assert( if(!vgaHWMapMem(pScrn)) )\n");
+       if (!vgaHWMapMem(pScrn))
+	   return FALSE;
+   }
 
-   vgaHWSetMmioFuncs(hwp, pI830->MMIOBase, 0);
-   vgaHWGetIOBase(hwp);
-   DPRINTF(PFX, "assert( if(!vgaHWMapMem(pScrn)) )\n");
-   if (!vgaHWMapMem(pScrn))
-      return FALSE;
+   i830_init_bufmgr(pScrn);
 
    DPRINTF(PFX, "assert( if(!I830EnterVT(scrnIndex, 0)) )\n");
 
@@ -3395,21 +3570,22 @@ I830LeaveVT(int scrnIndex, int flags)
 
    I830Sync(pScrn);
 
-   RestoreHWState(pScrn);
-
-   /* Evict everything from the bufmgr, as we're about to lose ownership of
-    * the graphics memory.
-    */
-   if (!pI830->memory_manager)
-      intel_bufmgr_fake_evict_all(pI830->bufmgr);
-   intel_batch_teardown(pScrn);
+   if (!pI830->use_drm_mode) {
+       RestoreHWState(pScrn);
+       /* Evict everything from the bufmgr, as we're about to lose ownership of
+	* the graphics memory.
+	*/
+       if (!pI830->memory_manager)
+	   intel_bufmgr_fake_evict_all(pI830->bufmgr);
+       intel_batch_teardown(pScrn);
 
-   if (!pI830->memory_manager)
-      i830_stop_ring(pScrn, TRUE);
+       if (!pI830->memory_manager)
+	   i830_stop_ring(pScrn, TRUE);
 
-   if (pI830->debug_modes) {
-      i830CompareRegsToSnapshot(pScrn, "After LeaveVT");
-      i830DumpRegs (pScrn);
+       if (pI830->debug_modes) {
+	   i830CompareRegsToSnapshot(pScrn, "After LeaveVT");
+	   i830DumpRegs (pScrn);
+       }
    }
 
    if (I830IsPrimary(pScrn))
@@ -3452,7 +3628,8 @@ I830EnterVT(int scrnIndex, int flags)
     */
    if (pI830->SaveGeneration != serverGeneration) {
       pI830->SaveGeneration = serverGeneration;
-      SaveHWState(pScrn);
+      if (!pI830->use_drm_mode)
+	  SaveHWState(pScrn);
    }
 
    pI830->leaving = FALSE;
@@ -3484,39 +3661,43 @@ I830EnterVT(int scrnIndex, int flags)
    if ((pI830->accel == ACCEL_EXA || pI830->accel == ACCEL_UXA) && IS_I965G(pI830))
       gen4_render_state_init(pScrn);
 
-   if (i830_check_error_state(pScrn)) {
-      xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
-		 "Existing errors found in hardware state.\n");
-   }
+   if (!pI830->use_drm_mode) {
+       if (i830_check_error_state(pScrn)) {
+	   xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+		      "Existing errors found in hardware state.\n");
+       }
 
-   /* Re-set up the ring. */
-   if (!pI830->memory_manager) {
-      i830_stop_ring(pScrn, FALSE);
-      i830_start_ring(pScrn);
-   }
-   if (!pI830->SWCursor)
-      I830InitHWCursor(pScrn);
+       /* Re-set up the ring. */
+       if (!pI830->memory_manager) {
+	   i830_stop_ring(pScrn, FALSE);
+	   i830_start_ring(pScrn);
+       }
+       if (!pI830->SWCursor)
+	   I830InitHWCursor(pScrn);
 
-   /* Tell the BIOS that we're in control of mode setting now. */
-   i830_init_bios_control(pScrn);
+       /* Tell the BIOS that we're in control of mode setting now. */
+       i830_init_bios_control(pScrn);
 
-   i830_init_clock_gating(pScrn);
+       i830_init_clock_gating(pScrn);
 
-   if (pI830->power_context)
-       OUTREG(PWRCTXA, pI830->power_context->offset | PWRCTX_EN);
+       if (pI830->power_context)
+	   OUTREG(PWRCTXA, pI830->power_context->offset | PWRCTX_EN);
 
-   /* Clear the framebuffer */
-   memset(pI830->FbBase + pScrn->fbOffset, 0,
-	  pScrn->virtualY * pScrn->displayWidth * pI830->cpp);
+       /* Clear the framebuffer */
+       memset(pI830->FbBase + pScrn->fbOffset, 0,
+	      pScrn->virtualY * pScrn->displayWidth * pI830->cpp);
+   }
 
    if (!xf86SetDesiredModes (pScrn))
       return FALSE;
-   
-   if (pI830->debug_modes) {
-      xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Hardware state at EnterVT:\n");
-      i830DumpRegs (pScrn);
+
+   if (!pI830->use_drm_mode) {
+       if (pI830->debug_modes) {
+	   xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Hardware state at EnterVT:\n");
+	   i830DumpRegs (pScrn);
+       }
+       i830DescribeOutputConfiguration(pScrn);
    }
-   i830DescribeOutputConfiguration(pScrn);
 
 #ifdef XF86DRI
    if (pI830->directRenderingEnabled) {
@@ -3614,9 +3795,11 @@ I830CloseScreen(int scrnIndex, ScreenPtr pScreen)
       TimerCancel(pI830->devicesTimer);
    pI830->devicesTimer = NULL;
 
-   DPRINTF(PFX, "\nUnmapping memory\n");
-   I830UnmapMem(pScrn);
-   vgaHWUnmapMem(pScrn);
+   if (!pI830->use_drm_mode) {
+       DPRINTF(PFX, "\nUnmapping memory\n");
+       I830UnmapMem(pScrn);
+       vgaHWUnmapMem(pScrn);
+   }
 
    if (pI830->ScanlineColorExpandBuffers) {
       xfree(pI830->ScanlineColorExpandBuffers);
diff --git a/src/i830_memory.c b/src/i830_memory.c
index ff5def6..57b9d27 100644
--- a/src/i830_memory.c
+++ b/src/i830_memory.c
@@ -184,7 +184,7 @@ i830_bind_memory(ScrnInfoPtr pScrn, i830_memory *mem)
 	if (!pI830->gtt_acquired)
 	    return TRUE;
 
-	if (mem->key != -1 && 
+	if (mem->key != -1 &&
 	    !xf86BindGARTMemory(pScrn->scrnIndex, mem->key, mem->agp_offset))
 	{
 	    return FALSE;
@@ -193,7 +193,7 @@ i830_bind_memory(ScrnInfoPtr pScrn, i830_memory *mem)
 	mem->bound = TRUE;
     }
 
-    if (mem->tiling != TILE_NONE) {
+    if (mem->tiling != TILE_NONE && pI830->use_drm_mode) {
 	mem->fence_nr = i830_set_tiling(pScrn, mem->offset, mem->pitch,
 					mem->allocated_size, mem->tiling);
     }
@@ -204,10 +204,12 @@ i830_bind_memory(ScrnInfoPtr pScrn, i830_memory *mem)
 static Bool
 i830_unbind_memory(ScrnInfoPtr pScrn, i830_memory *mem)
 {
+    I830Ptr pI830 = I830PTR(pScrn);
+
     if (mem == NULL || !mem->bound)
 	return TRUE;
 
-    if (mem->tiling != TILE_NONE)
+    if (mem->tiling != TILE_NONE && !pI830->use_drm_mode)
 	i830_clear_tiling(pScrn, mem->fence_nr);
 
 #ifdef XF86DRI
@@ -460,22 +462,24 @@ i830_allocator_init(ScrnInfoPtr pScrn, unsigned long offset, unsigned long size)
 				   ALIGN_BOTH_ENDS | NEED_NON_STOLEN);
 
 	if (pI830->memory_manager != NULL) {
-	    struct drm_i915_gem_init init;
-	    int ret;
-
-	    init.gtt_start = pI830->memory_manager->offset;
-	    init.gtt_end = pI830->memory_manager->offset +
-		pI830->memory_manager->size;
-
-	    /* Tell the kernel to manage it */
-	    ret = ioctl(pI830->drmSubFD, DRM_IOCTL_I915_GEM_INIT, &init);
-	    if (ret != 0) {
-		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
-			   "Failed to initialize kernel memory manager\n");
-		i830_free_memory(pScrn, pI830->memory_manager);
-		pI830->memory_manager = NULL;
+	    if (!pI830->use_drm_mode) {
+		struct drm_i915_gem_init init;
+		int ret;
+
+		init.gtt_start = pI830->memory_manager->offset;
+		init.gtt_end = pI830->memory_manager->offset +
+		    pI830->memory_manager->size;
+
+		/* Tell the kernel to manage it */
+		ret = ioctl(pI830->drmSubFD, DRM_IOCTL_I915_GEM_INIT, &init);
+		if (ret != 0) {
+		    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+			       "Failed to initialize kernel memory manager\n");
+		    i830_free_memory(pScrn, pI830->memory_manager);
+		    pI830->memory_manager = NULL;
+		}
+		i830_init_bufmgr(pScrn);
 	    }
-	    i830_init_bufmgr(pScrn);
 	} else {
 	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
 		       "Failed to allocate space for kernel memory manager\n");
@@ -800,8 +804,9 @@ i830_allocate_memory(ScrnInfoPtr pScrn, const char *name,
 #ifdef XF86DRI
     I830Ptr pI830 = I830PTR(pScrn);
 
-    if (pI830->memory_manager && !(flags & NEED_PHYSICAL_ADDR) &&
-	!(flags & NEED_LIFETIME_FIXED))
+    if (pI830->use_drm_mode || (pI830->memory_manager &&
+				!(flags & NEED_PHYSICAL_ADDR) &&
+				!(flags & NEED_LIFETIME_FIXED)))
     {
 	return i830_allocate_memory_bo(pScrn, name, size, alignment, flags);
     } else
@@ -1025,6 +1030,7 @@ i830_allocate_overlay(ScrnInfoPtr pScrn)
 {
     I830Ptr pI830 = I830PTR(pScrn);
     int flags = 0;
+    int mem_space = DRM_BO_FLAG_MEM_TT;
 
     /* Only allocate if overlay is going to be enabled. */
     if (!pI830->XvEnabled)
@@ -1045,6 +1051,10 @@ i830_allocate_overlay(ScrnInfoPtr pScrn)
 	/* This failure isn't fatal. */
     }
 
+    if (flags & NEED_PHYSICAL_ADDR)
+	if (pI830->use_drm_mode)
+	    mem_space = DRM_BO_FLAG_MEM_VRAM;
+
     return TRUE;
 }
 #endif
@@ -1122,7 +1132,7 @@ i830_allocate_framebuffer(ScrnInfoPtr pScrn, I830Ptr pI830, BoxPtr FbMemBox,
     /* We'll allocate the fb such that the root window will fit regardless of
      * rotation.
      */
-    if (pScrn->virtualX > pScrn->virtualY)
+    if (!pI830->use_drm_mode && pScrn->virtualX > pScrn->virtualY)
 	fb_height = pScrn->virtualX;
     else
 	fb_height = pScrn->virtualY;
@@ -1186,7 +1196,7 @@ i830_allocate_framebuffer(ScrnInfoPtr pScrn, I830Ptr pI830, BoxPtr FbMemBox,
      * acceleration operations (non-XY COLOR_BLT) can't be done to tiled
      * buffers.
      */
-    if (pI830->accel <= ACCEL_XAA && IS_I965G(pI830))
+    if ((pI830->accel <= ACCEL_XAA && IS_I965G(pI830)) || pI830->use_drm_mode)
 	tiling = FALSE;
     else
 	tiling = pI830->tiling;
@@ -1215,8 +1225,14 @@ i830_allocate_framebuffer(ScrnInfoPtr pScrn, I830Ptr pI830, BoxPtr FbMemBox,
 	return NULL;
     }
 
-    if (pI830->FbBase)
+    if (pI830->use_drm_mode) {
+#ifdef XF86DRM_MODE
+        drmmode_set_fb(pScrn, &pI830->drmmode, pScrn->virtualX, fb_height,
+		       pScrn->displayWidth * pI830->cpp, &front_buffer->bo);
+#endif
+    } else if (pI830->FbBase)
 	memset (pI830->FbBase + front_buffer->offset, 0, size);
+
     return front_buffer;
 }
 
@@ -1225,10 +1241,15 @@ i830_allocate_cursor_buffers(ScrnInfoPtr pScrn)
 {
     I830Ptr pI830 = I830PTR(pScrn);
     xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
-    int flags = pI830->CursorNeedsPhysical ? NEED_PHYSICAL_ADDR : 0;
+    int flags;
     int i;
     long size;
 
+    if (pI830->use_drm_mode)
+	pI830->CursorNeedsPhysical = FALSE;
+
+    flags = pI830->CursorNeedsPhysical ? NEED_PHYSICAL_ADDR : 0;
+
     /* Try to allocate one big blob for our cursor memory.  This works
      * around a limitation in the FreeBSD AGP driver that allows only one
      * physical allocation larger than a page, and could allow us
@@ -1341,18 +1362,20 @@ i830_allocate_2d_memory(ScrnInfoPtr pScrn)
     unsigned int pitch = pScrn->displayWidth * pI830->cpp;
     long size;
 
-    if (!pI830->StolenOnly &&
-	(!xf86AgpGARTSupported() || !xf86AcquireGART(pScrn->scrnIndex))) {
-	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
-		   "AGP GART support is either not available or cannot "
-		   "be used.\n"
-		   "\tMake sure your kernel has agpgart support or has\n"
-		   "\tthe agpgart module loaded.\n");
-	return FALSE;
-    }
+    if (!pI830->use_drm_mode) {
+	if (!pI830->StolenOnly &&
+	    (!xf86AgpGARTSupported() || !xf86AcquireGART(pScrn->scrnIndex))) {
+	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+		       "AGP GART support is either not available or cannot "
+		       "be used.\n"
+		       "\tMake sure your kernel has agpgart support or has\n"
+		       "\tthe agpgart module loaded.\n");
+	    return FALSE;
+	}
 
-    /* Allocate the ring buffer first, so it ends up in stolen mem. */
-    i830_allocate_ringbuffer(pScrn);
+	/* Allocate the ring buffer first, so it ends up in stolen mem. */
+	i830_allocate_ringbuffer(pScrn);
+    }
 
     if (pI830->fb_compression)
 	i830_setup_fb_compression(pScrn);
@@ -1950,13 +1973,15 @@ i830_bind_all_memory(ScrnInfoPtr pScrn)
     if (pI830->StolenOnly == TRUE || pI830->memory_list == NULL)
 	return TRUE;
 
-    if (xf86AgpGARTSupported() && !pI830->gtt_acquired) {
+    if (pI830->use_drm_mode || (xf86AgpGARTSupported() &&
+				!pI830->gtt_acquired)) {
 	i830_memory *mem;
 
-	if (!xf86AcquireGART(pScrn->scrnIndex))
-	    return FALSE;
-
-	pI830->gtt_acquired = TRUE;
+	if (!pI830->use_drm_mode) {
+	    if (!xf86AcquireGART(pScrn->scrnIndex))
+		return FALSE;
+	    pI830->gtt_acquired = TRUE;
+	}
 
 	for (mem = pI830->memory_list->next; mem->next != NULL;
 	     mem = mem->next)
@@ -1971,7 +1996,7 @@ i830_bind_all_memory(ScrnInfoPtr pScrn)
 		FatalError("Couldn't bind memory for BO %s\n", mem->name);
 	}
     }
-    if (!pI830->SWCursor)
+    if (!pI830->SWCursor && !pI830->use_drm_mode)
 	i830_update_cursor_offsets(pScrn);
 
     return TRUE;
@@ -1986,7 +2011,8 @@ i830_unbind_all_memory(ScrnInfoPtr pScrn)
     if (pI830->StolenOnly == TRUE)
 	return TRUE;
 
-    if (xf86AgpGARTSupported() && pI830->gtt_acquired) {
+    if (pI830->use_drm_mode || (xf86AgpGARTSupported() &&
+				pI830->gtt_acquired)) {
 	i830_memory *mem;
 
 	for (mem = pI830->memory_list->next; mem->next != NULL;
@@ -2002,10 +2028,12 @@ i830_unbind_all_memory(ScrnInfoPtr pScrn)
 		i830_unbind_memory(pScrn, mem);
 	}
 
-	pI830->gtt_acquired = FALSE;
+	if (!pI830->use_drm_mode) {
+	    pI830->gtt_acquired = FALSE;
 
-	if (!xf86ReleaseGART(pScrn->scrnIndex))
-	    return FALSE;
+	    if (!xf86ReleaseGART(pScrn->scrnIndex))
+		return FALSE;
+	}
     }
 
     return TRUE;
@@ -2057,3 +2085,118 @@ Bool i830_allocate_xvmc_buffer(ScrnInfoPtr pScrn, const char *name,
     return TRUE;
 }
 #endif
+
+#ifdef XF86DRI_MM
+#if 0
+static i830_memory *
+i830_allocate_framebuffer_new(ScrnInfoPtr pScrn, I830Ptr pI830, BoxPtr FbMemBox)
+{
+    unsigned int pitch = pScrn->displayWidth * pI830->cpp;
+    unsigned long minspace, avail;
+    int cacheLines;
+    int align;
+    long size, fb_height;
+    char *name;
+    int flags;
+    i830_memory *front_buffer = NULL;
+    Bool tiling;
+
+    flags = ALLOW_SHARING;
+
+    /* Clear everything first. */
+    memset(FbMemBox, 0, sizeof(*FbMemBox));
+
+    fb_height = pScrn->virtualY;
+
+    FbMemBox->x1 = 0;
+    FbMemBox->x2 = pScrn->displayWidth;
+    FbMemBox->y1 = 0;
+    FbMemBox->y2 = fb_height;
+
+    /* Calculate how much framebuffer memory to allocate.  For the
+     * initial allocation, calculate a reasonable minimum.  This is
+     * enough for the virtual screen size, plus some pixmap cache
+     * space if we're using XAA.
+     */
+    minspace = pitch * pScrn->virtualY;
+    avail = pScrn->videoRam * 1024;
+    cacheLines = 0;
+
+    size = pitch * (fb_height + cacheLines);
+    size = ROUND_TO_PAGE(size);
+
+    name = "front buffer";
+
+    /* Front buffer tiling has to be disabled with G965 XAA because some of the
+     * acceleration operations (non-XY COLOR_BLT) can't be done to tiled
+     * buffers.
+     */
+    if (!(pI830->accel == ACCEL_EXA) && IS_I965G(pI830))
+	tiling = FALSE;
+    else
+	tiling = pI830->tiling;
+
+    if (pI830->use_drm_mode)
+      tiling = FALSE;
+
+    /* Attempt to allocate it tiled first if we have page flipping on. */
+    if (tiling && IsTileable(pScrn, pitch)) {
+	/* XXX: probably not the case on 965 */
+	if (IS_I9XX(pI830))
+	    align = MB(1);
+	else
+	    align = KB(512);
+	front_buffer = i830_allocate_memory_tiled(pScrn, name, size,
+						  pitch, align, flags,
+						  TILE_XMAJOR);
+    }
+
+    /* If not, attempt it linear */
+    if (front_buffer == NULL) {
+	front_buffer = i830_allocate_memory(pScrn, name, size, KB(64), flags);
+    }
+
+    if (front_buffer == NULL) {
+	xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to allocate "
+		   "framebuffer. Is your VideoRAM set too low?\n");
+
+	return NULL;
+    }
+
+    return front_buffer;
+}
+#endif
+uint32_t
+i830_create_new_fb(ScrnInfoPtr pScrn, int width, int height, int *pitch)
+{
+    return 0;
+
+#if 0
+    I830Ptr pI830 = I830PTR(pScrn);
+    i830_memory *old_buffer;
+
+    pScrn->virtualX = width;
+    pScrn->virtualY = height;
+    pScrn->displayWidth = (pScrn->virtualX + 63) & ~63;
+
+    *pitch = pScrn->displayWidth * pI830->cpp;
+
+    old_buffer = pI830->front_buffer;
+
+    pI830->front_buffer =
+	i830_allocate_framebuffer_new(pScrn, pI830, &pI830->FbMemBox);
+
+    ErrorF("old front size %08lx, new front size %08lx\n",
+	   old_buffer->bo->size, pI830->front_buffer->bo->size);
+    ErrorF("old front offset %08lx, new front offset %08lx\n",
+	   old_buffer->bo->offset, pI830->front_buffer->bo->offset);
+
+    i830_free_memory(pScrn, old_buffer);
+
+    i830_update_front_offset(pScrn);
+
+    return pI830->front_buffer->bo->handle;
+#endif
+}
+
+#endif
diff --git a/src/i830_video.c b/src/i830_video.c
index 1719835..5e6ebd7 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -2394,7 +2394,7 @@ I830PutImage(ScrnInfoPtr pScrn,
     /* fixup pointers */
 #ifdef INTEL_XVMC
     if (id == FOURCC_XVMC && IS_I915(pI830)) {
-	pPriv->YBuf0offset = (uint32_t)buf;
+	pPriv->YBuf0offset = (uint32_t)((uint64_t)buf);
 	pPriv->VBuf0offset = pPriv->YBuf0offset + (dstPitch2 * height);
 	pPriv->UBuf0offset = pPriv->VBuf0offset + (dstPitch * height / 2);
 	destId = FOURCC_YV12;
diff --git a/src/reg_dumper/reg_dumper.h b/src/reg_dumper/reg_dumper.h
index 241b241..9f24d5c 100644
--- a/src/reg_dumper/reg_dumper.h
+++ b/src/reg_dumper/reg_dumper.h
@@ -52,6 +52,7 @@ struct pci_info_rec {
 typedef struct _i830 {
     /* Fields in common with the real pI830 */
     struct pci_info_rec *PciInfo;
+    Bool use_drm_mode;
 
     /* Fields used for setting up reg_dumper */
     struct pci_device *pci_dev;


More information about the xorg-commit mailing list