xf86-video-modesetting: 14 commits - configure.ac .gitignore man/Makefile.am man/modesetting.man src/crtc.c src/dri2.c src/driver.c src/driver.h src/drmmode_display.c src/drmmode_display.h src/exa.c src/Makefile.am src/output.c

Dave Airlie airlied at kemper.freedesktop.org
Mon Oct 3 03:30:24 PDT 2011


 .gitignore            |   79 ++
 configure.ac          |  137 -----
 man/Makefile.am       |   31 -
 man/modesetting.man   |   54 ++
 src/Makefile.am       |   12 
 src/crtc.c            |  307 -----------
 src/dri2.c            |  128 ----
 src/driver.c          |  673 +++++++++---------------
 src/driver.h          |   20 
 src/drmmode_display.c | 1349 ++++++++++++++++++++++++++++++++++++++++++++++++++
 src/drmmode_display.h |  101 +++
 src/exa.c             |  850 -------------------------------
 src/output.c          |  292 ----------
 13 files changed, 1884 insertions(+), 2149 deletions(-)

New commits:
commit d68278caa04f165c85f5d927abcf5fcc084eaa94
Author: Dave Airlie <airlied at redhat.com>
Date:   Thu Sep 29 16:06:52 2011 +0100

    check drm support dumb buffer capability

diff --git a/src/drmmode_display.c b/src/drmmode_display.c
index 375170f..dcf3eb3 100644
--- a/src/drmmode_display.c
+++ b/src/drmmode_display.c
@@ -1016,6 +1016,17 @@ static const xf86CrtcConfigFuncsRec drmmode_xf86crtc_config_funcs = {
 Bool drmmode_pre_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int cpp)
 {
 	int i, num_dvi = 0, num_hdmi = 0;
+	int ret;
+
+	/* check for dumb capability */
+	{
+		uint64_t value = 0;
+		ret = drmGetCap(drmmode->fd, DRM_CAP_DUMB_BUFFER, &value);
+		if (ret > 0 || value != 1) {
+			xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "KMS doesn't support dumb interface\n");
+			return FALSE;
+		}
+	}
 
 	xf86CrtcConfigInit(pScrn, &drmmode_xf86crtc_config_funcs);
 
commit 82ba85fca8416635ff28c19c4b38fa2fe9820481
Author: Dave Airlie <airlied at redhat.com>
Date:   Thu Sep 29 16:00:50 2011 +0100

    add initial man page

diff --git a/man/modesetting.man b/man/modesetting.man
index e69de29..34baa9c 100644
--- a/man/modesetting.man
+++ b/man/modesetting.man
@@ -0,0 +1,54 @@
+.\" shorthand for double quote that works everywhere.
+.ds q \N'34'
+.TH MODESETTING __drivermansuffix__ __vendorversion__
+.SH NAME
+modesetting \- video driver for framebuffer device
+.SH SYNOPSIS
+.nf
+.B "Section \*qDevice\*q"
+.BI "  Identifier \*q"  devname \*q
+.B  "  Driver \*qmodesetting\*q"
+.BI "  BusID  \*qpci:" bus : dev : func \*q
+\ \ ...
+.B EndSection
+.fi
+.SH DESCRIPTION
+.B modesetting
+is an __xservername__ driver for KMS devices.  This is a non-accelerated
+driver, the following framebuffer depths are supported: 8, 15, 16, 24.
+All visual types are supported for depth 8, and TrueColor visual is
+supported for the other depths.  RandR 1.2 is supported.
+.SH SUPPORTED HARDWARE
+The 
+.B modesetting
+driver supports all hardware where a KMS driver is available.
+modesetting uses the Linux DRM KMS ioctls and dumb object create/map.
+.SH CONFIGURATION DETAILS
+Please refer to __xconfigfile__(__filemansuffix__) for general configuration
+details.  This section only covers configuration details specific to
+this driver.
+.PP
+For this driver it is not required to specify modes in the screen 
+section of the config file.  The
+.B modesetting
+driver can pick up the currently used video mode from the kernel
+driver and will use it if there are no video modes configured.
+.PP
+For PCI boards you might have to add a BusID line to the Device
+section.  See above for a sample line.
+.PP
+The following driver 
+.B Options
+are supported:
+.TP
+.BI "Option \*qkmsdev\*q \*q" string \*q
+The framebuffer device to use. Default: /dev/dri/card0.
+.TP
+.BI "Option \*qShadowFB\*q \*q" boolean \*q
+Enable or disable use of the shadow framebuffer layer.  Default: on.
+.TP
+.SH "SEE ALSO"
+__xservername__(__appmansuffix__), __xconfigfile__(__filemansuffix__), Xserver(__appmansuffix__),
+X(__miscmansuffix__)
+.SH AUTHORS
+Authors include: Dave Airlie
commit bb848a788f8dae6f54eb2c03eb2046066732e6e8
Author: Dave Airlie <airlied at redhat.com>
Date:   Thu Sep 29 15:55:36 2011 +0100

    add shadowfb support, default to on.
    
    we should probably expose a bit from kernel to say if shadow is preferred
    or wasteful.

diff --git a/src/driver.c b/src/driver.c
index 1192878..bde690c 100644
--- a/src/driver.c
+++ b/src/driver.c
@@ -49,6 +49,7 @@
 #include "xf86Crtc.h"
 #include "miscstruct.h"
 #include "dixstruct.h"
+#include "shadow.h"
 #include "xf86xv.h"
 #include <X11/extensions/Xv.h>
 #include <xorg-server.h>
@@ -110,11 +111,13 @@ typedef enum
 {
     OPTION_SW_CURSOR,
     OPTION_DEVICE_PATH,
+    OPTION_SHADOW_FB,
 } modesettingOpts;
 
 static const OptionInfoRec Options[] = {
     {OPTION_SW_CURSOR, "SWcursor", OPTV_BOOLEAN, {0}, FALSE},
     {OPTION_DEVICE_PATH, "kmsdev", OPTV_STRING, {0}, FALSE },
+    {OPTION_SHADOW_FB, "ShadowFB", OPTV_BOOLEAN, {0}, FALSE },
     {-1, NULL, OPTV_NONE, {0}, FALSE}
 };
 
@@ -472,6 +475,8 @@ PreInit(ScrnInfoPtr pScrn, int flags)
 	ms->SWCursor = TRUE;
     }
 
+    ms->shadow_enable = xf86ReturnOptValBool(ms->Options, OPTION_SHADOW_FB, TRUE);
+
     ms->drmmode.fd = ms->fd;
     if (drmmode_pre_init(pScrn, &ms->drmmode, pScrn->bitsPerPixel / 8) == FALSE) {
 	xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "KMS setup failed\n");
@@ -504,11 +509,31 @@ PreInit(ScrnInfoPtr pScrn, int flags)
 	return FALSE;
     }
 
+    if (ms->shadow_enable) {
+	if (!xf86LoadSubModule(pScrn, "shadow")) {
+	    return FALSE;
+	}
+    }
+
     return TRUE;
     fail:
     return FALSE;
 }
 
+static void *
+msShadowWindow(ScreenPtr screen, CARD32 row, CARD32 offset, int mode,
+	       CARD32 *size, void *closure)
+{
+    ScrnInfoPtr pScrn = xf86Screens[screen->myNum];
+    modesettingPtr ms = modesettingPTR(pScrn);
+    int stride;
+
+    stride = (pScrn->displayWidth * pScrn->bitsPerPixel) / 8;
+    *size = stride;
+
+    return ((uint8_t *)ms->drmmode.front_bo->ptr + row * stride + offset);
+}
+
 static Bool
 CreateScreenResources(ScreenPtr pScreen)
 {
@@ -532,9 +557,19 @@ CreateScreenResources(ScreenPtr pScreen)
 	return FALSE;
 
     rootPixmap = pScreen->GetScreenPixmap(pScreen);
+
+    if (ms->shadow_enable)
+	pixels = ms->shadow_fb;
+    
     if (!pScreen->ModifyPixmapHeader(rootPixmap, -1, -1, -1, -1, -1, pixels))
 	FatalError("Couldn't adjust screen pixmap\n");
 
+    if (ms->shadow_enable) {
+	if (!shadowAdd(pScreen, rootPixmap, shadowUpdatePackedWeak(),
+		       msShadowWindow, 0, 0))
+	    return FALSE;
+    }
+
     ms->damage = DamageCreate(NULL, NULL, DamageReportNone, TRUE,
                               pScreen, rootPixmap);
 
@@ -551,6 +586,15 @@ CreateScreenResources(ScreenPtr pScreen)
 }
 
 static Bool
+msShadowInit(ScreenPtr pScreen)
+{
+    if (!shadowSetup(pScreen)) {
+	return FALSE;
+    }
+    return TRUE;
+}
+
+static Bool
 ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
 {
     ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
@@ -571,6 +615,13 @@ ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
     if (!drmmode_create_initial_bos(pScrn, &ms->drmmode))
 	return FALSE;
 
+    if (ms->shadow_enable) {
+	ms->shadow_fb = calloc(1, pScrn->displayWidth * pScrn->virtualY *
+			       ((pScrn->bitsPerPixel + 7) >> 3));
+	if (!ms->shadow_fb)
+	    ms->shadow_enable = FALSE;
+    }	
+    
     miClearVisualTypes();
 
     if (!miSetVisualTypes(pScrn->depth,
@@ -607,6 +658,12 @@ ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
 
     fbPictureInit(pScreen, NULL, 0);
 
+    if (ms->shadow_enable && !msShadowInit(pScreen)) {
+	xf86DrvMsg(scrnIndex, X_ERROR,
+		   "shadow fb init failed\n");
+	return FALSE;
+    }
+  
     ms->createScreenResources = pScreen->CreateScreenResources;
     pScreen->CreateScreenResources = CreateScreenResources;
 
@@ -715,6 +772,11 @@ CloseScreen(int scrnIndex, ScreenPtr pScreen)
 	ms->damage = NULL;
     }
 
+    if (ms->shadow_enable) {
+	shadowRemove(pScreen, pScreen->GetScreenPixmap(pScreen));
+	free(ms->shadow_fb);
+	ms->shadow_fb = NULL;
+    }
     drmmode_uevent_fini(pScrn, &ms->drmmode);
 
     drmmode_free_bos(pScrn, &ms->drmmode);
diff --git a/src/driver.h b/src/driver.h
index beb5f8d..494ca0c 100644
--- a/src/driver.h
+++ b/src/driver.h
@@ -76,6 +76,8 @@ typedef struct _modesettingRec
 
     DamagePtr damage;
     Bool dirty_enabled;
+    Bool shadow_enable;
+    void *shadow_fb;
 } modesettingRec, *modesettingPtr;
 
 #define modesettingPTR(p) ((modesettingPtr)((p)->driverPrivate))
commit f699c4dc6fd2a34555045950d75ba287723a1e06
Author: Dave Airlie <airlied at redhat.com>
Date:   Thu Sep 29 15:55:24 2011 +0100

    remove unused debug

diff --git a/src/driver.c b/src/driver.c
index d1348c9..1192878 100644
--- a/src/driver.c
+++ b/src/driver.c
@@ -558,7 +558,6 @@ ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
     VisualPtr visual;
     int ret;
 
-    ErrorF("ms is %p\n", ms);
     pScrn->pScreen = pScreen;
 
     ret = drmSetMaster(ms->fd);
commit 9772f3e16b0e15ea48463c8af7e5c28ece116dea
Author: Dave Airlie <airlied at redhat.com>
Date:   Thu Sep 29 14:13:58 2011 +0100

    add -Wall, cleanup warnings

diff --git a/configure.ac b/configure.ac
index 3d4d267..12251fe 100644
--- a/configure.ac
+++ b/configure.ac
@@ -47,6 +47,10 @@ AC_PROG_LIBTOOL
 AC_PROG_CC
 AM_PROG_CC_C_O
 
+if test "x$GCC" = "xyes"; then
+        CPPFLAGS="$CPPFLAGS -Wall"
+fi
+
 AH_TOP([#include "xorg-server.h"])
 
 AC_ARG_WITH(xorg-module-dir,
diff --git a/src/driver.c b/src/driver.c
index b56db94..d1348c9 100644
--- a/src/driver.c
+++ b/src/driver.c
@@ -33,6 +33,7 @@
 #include "config.h"
 #endif
 
+#include <unistd.h>
 #include <fcntl.h>
 #include "xf86.h"
 #include "xf86_OSproc.h"
@@ -199,8 +200,6 @@ ms_pci_probe(DriverPtr driver,
 	     int entity_num, struct pci_device *dev, intptr_t match_data)
 {
     ScrnInfoPtr scrn = NULL;
-    EntityInfoPtr entity;
-    DevUnion *private;
 
     scrn = xf86ConfigPciEntity(scrn, 0, entity_num, NULL,
 			       NULL, NULL, NULL, NULL, NULL);
@@ -239,14 +238,11 @@ ms_pci_probe(DriverPtr driver,
 static Bool
 Probe(DriverPtr drv, int flags)
 {
-    int i, numUsed, numDevSections, *usedChips;
-    EntPtr msEnt = NULL;
-    DevUnion *pPriv;
+    int i, numDevSections;
     GDevPtr *devSections;
     Bool foundScreen = FALSE;
-    int numDevs;
     char *dev;
-    ScrnInfoPtr scrn;
+    ScrnInfoPtr scrn = NULL;
 
     /* For now, just bail out for PROBE_DETECT. */
     if (flags & PROBE_DETECT)
@@ -268,7 +264,7 @@ Probe(DriverPtr drv, int flags)
 		int entity;
 		entity = xf86ClaimFbSlot(drv, 0, devSections[i], TRUE);
 		scrn = xf86ConfigFbEntity(scrn, 0, entity,
-					   NULL, NULL, NULL, NULL);
+					  NULL, NULL, NULL, NULL);
 	    }
 
 	    if (scrn)
@@ -376,17 +372,11 @@ FreeRec(ScrnInfoPtr pScrn)
 static Bool
 PreInit(ScrnInfoPtr pScrn, int flags)
 {
-    xf86CrtcConfigPtr xf86_config;
     modesettingPtr ms;
-    MessageType from = X_PROBED;
     rgb defaultWeight = { 0, 0, 0 };
     EntityInfoPtr pEnt;
     EntPtr msEnt = NULL;
     char *BusID;
-    int i;
-    char *s;
-    int num_pipe;
-    int max_width, max_height;
 
     if (pScrn->numEntities != 1)
 	return FALSE;
@@ -526,7 +516,6 @@ CreateScreenResources(ScreenPtr pScreen)
     modesettingPtr ms = modesettingPTR(pScrn);
     PixmapPtr rootPixmap;
     Bool ret;
-    int flags;
     void *pixels;
     pScreen->CreateScreenResources = ms->createScreenResources;
     ret = pScreen->CreateScreenResources(pScreen);
@@ -567,9 +556,6 @@ ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
     ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
     modesettingPtr ms = modesettingPTR(pScrn);
     VisualPtr visual;
-    unsigned long sys_mem;
-    int c;
-    MessageType from;
     int ret;
 
     ErrorF("ms is %p\n", ms);
diff --git a/src/drmmode_display.c b/src/drmmode_display.c
index 4f25bbe..375170f 100644
--- a/src/drmmode_display.c
+++ b/src/drmmode_display.c
@@ -108,11 +108,13 @@ static int dumb_bo_map(int fd, struct dumb_bo *bo)
 	return 0;
 }
 
+#if 0
 static int dumb_bo_unmap(int fd, struct dumb_bo *bo)
 {
 	bo->map_count--;
 	return 0;
 }
+#endif
 
 static int dumb_bo_destroy(int fd, struct dumb_bo *bo)
 {
@@ -260,7 +262,6 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
 		     Rotation rotation, int x, int y)
 {
 	ScrnInfoPtr pScrn = crtc->scrn;
-	//	RADEONInfoPtr info = RADEONPTR(pScrn);
 	xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn);
 	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
 	drmmode_ptr drmmode = drmmode_crtc->drmmode;
@@ -273,11 +274,8 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
 	int i;
 	int fb_id;
 	drmModeModeInfo kmode;
-	int pitch;
-	uint32_t tiling_flags = 0;
 	int height;
 
-	pitch = pScrn->displayWidth;
 	height = pScrn->virtualY;
 
 	if (drmmode->fb_id == 0) {
@@ -795,7 +793,6 @@ drmmode_output_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int num, int *num_dv
 	drmModePropertyPtr props;
 	char name[32];
 	int i;
-	const char *s;
 
 	koutput = drmModeGetConnector(drmmode->fd, drmmode->mode_res->connectors[num]);
 	if (!koutput)
@@ -938,10 +935,7 @@ drmmode_xf86crtc_resize (ScrnInfoPtr scrn, int width, int height)
 	ScreenPtr   screen = screenInfo.screens[scrn->scrnIndex];
 	uint32_t    old_fb_id;
 	int	    i, pitch, old_width, old_height, old_pitch;
-	int screen_size;
 	int cpp = (scrn->bitsPerPixel + 1) / 8;
-	struct dumb_bo *front_bo;
-	uint32_t tiling_flags = 0;
 	PixmapPtr ppix = screen->GetScreenPixmap(screen);
 	void *new_pixels;
 
@@ -949,12 +943,12 @@ drmmode_xf86crtc_resize (ScrnInfoPtr scrn, int width, int height)
 		return TRUE;
 
 	xf86DrvMsg(scrn->scrnIndex, X_INFO,
-		   "Allocate new frame buffer %dx%d stride %d\n",
-		   width, height, pitch / cpp);
+		   "Allocate new frame buffer %dx%d stride\n",
+		   width, height);
 
 	old_width = scrn->virtualX;
 	old_height = scrn->virtualY;
-	old_pitch = scrn->displayWidth;
+	old_pitch = drmmode->front_bo->pitch;
 	old_fb_id = drmmode->fb_id;
 	old_front = drmmode->front_bo;
 
@@ -1009,7 +1003,7 @@ drmmode_xf86crtc_resize (ScrnInfoPtr scrn, int width, int height)
 	drmmode->front_bo = old_front;
 	scrn->virtualX = old_width;
 	scrn->virtualY = old_height;
-	scrn->displayWidth = old_pitch;
+	scrn->displayWidth = old_pitch / cpp;
 	drmmode->fb_id = old_fb_id;
 
 	return FALSE;
@@ -1021,11 +1015,9 @@ static const xf86CrtcConfigFuncsRec drmmode_xf86crtc_config_funcs = {
 
 Bool drmmode_pre_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int cpp)
 {
-	xf86CrtcConfigPtr xf86_config;
 	int i, num_dvi = 0, num_hdmi = 0;
 
 	xf86CrtcConfigInit(pScrn, &drmmode_xf86crtc_config_funcs);
-	xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
 
 	drmmode->scrn = pScrn;
 	drmmode->cpp = cpp;
commit 1b9690d2b1f1bc33f149ff7ab8950b24029c030c
Author: Dave Airlie <airlied at redhat.com>
Date:   Thu Sep 29 14:05:43 2011 +0100

    fix server recycling

diff --git a/src/driver.c b/src/driver.c
index bc80e30..b56db94 100644
--- a/src/driver.c
+++ b/src/driver.c
@@ -570,31 +570,17 @@ ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
     unsigned long sys_mem;
     int c;
     MessageType from;
+    int ret;
 
-    /* deal with server regeneration */
-    if (ms->fd < 0) {
-	char *BusID;
-
-	BusID = malloc(64);
-	sprintf(BusID, "PCI:%d:%d:%d",
-#if XSERVER_LIBPCIACCESS
-		((ms->PciInfo->domain << 8) | ms->PciInfo->bus),
-		ms->PciInfo->dev, ms->PciInfo->func
-#else
-		((pciConfigPtr) ms->PciInfo->thisCard)->busnum,
-		((pciConfigPtr) ms->PciInfo->thisCard)->devnum,
-		((pciConfigPtr) ms->PciInfo->thisCard)->funcnum
-#endif
-	    );
-
-	ms->fd = drmOpen(NULL, BusID);
-
-	if (ms->fd < 0)
-	    return FALSE;
-    }
-
+    ErrorF("ms is %p\n", ms);
     pScrn->pScreen = pScreen;
 
+    ret = drmSetMaster(ms->fd);
+    if (ret) {
+        ErrorF("Unable to set master\n");
+        return FALSE;
+    }
+      
     /* HW dependent - FIXME */
     pScrn->displayWidth = pScrn->virtualX;
     if (!drmmode_create_initial_bos(pScrn, &ms->drmmode))
@@ -716,7 +702,9 @@ EnterVT(int scrnIndex, int flags)
     ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
     modesettingPtr ms = modesettingPTR(pScrn);
 
-    if (!xf86SetDesiredModes(pScrn))
+    pScrn->vtSema = TRUE;
+
+    if (!drmmode_set_desired_modes(pScrn, &ms->drmmode))
 	return FALSE;
 
     return TRUE;
@@ -752,8 +740,8 @@ CloseScreen(int scrnIndex, ScreenPtr pScreen)
 
     pScreen->CreateScreenResources = ms->createScreenResources;
     pScreen->BlockHandler = ms->BlockHandler;
-    drmClose(ms->fd);
-    ms->fd = -1;
+
+    drmDropMaster(ms->fd);
 
     pScrn->vtSema = FALSE;
     pScreen->CloseScreen = ms->CloseScreen;
diff --git a/src/drmmode_display.c b/src/drmmode_display.c
index d94ce03..4f25bbe 100644
--- a/src/drmmode_display.c
+++ b/src/drmmode_display.c
@@ -1329,6 +1329,12 @@ void drmmode_free_bos(ScrnInfoPtr pScrn, drmmode_ptr drmmode)
 {
 	xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
 	int i;
+
+	if (drmmode->fb_id) {
+		drmModeRmFB(drmmode->fd, drmmode->fb_id);
+		drmmode->fb_id = 0;
+	}
+
 	dumb_bo_destroy(drmmode->fd, drmmode->front_bo);
 	drmmode->front_bo = NULL;
 
commit 59a4776f7b4e0f9bbbafe62972487354a8fabda0
Author: Dave Airlie <airlied at redhat.com>
Date:   Thu Sep 29 12:38:26 2011 +0100

    port damage tracking code from st/xorg

diff --git a/src/driver.c b/src/driver.c
index 0aaafd1..bc80e30 100644
--- a/src/driver.c
+++ b/src/driver.c
@@ -307,6 +307,58 @@ GetRec(ScrnInfoPtr pScrn)
     return TRUE;
 }
 
+static void dispatch_dirty(ScreenPtr pScreen)
+{
+    ScrnInfoPtr scrn = xf86Screens[pScreen->myNum];
+    modesettingPtr ms = modesettingPTR(scrn);
+    RegionPtr dirty = DamageRegion(ms->damage);
+    unsigned num_cliprects = REGION_NUM_RECTS(dirty);
+
+    if (num_cliprects) {
+	drmModeClip *clip = alloca(num_cliprects * sizeof(drmModeClip));
+	BoxPtr rect = REGION_RECTS(dirty);
+	int i, ret;
+	    
+	/* XXX no need for copy? */
+	for (i = 0; i < num_cliprects; i++, rect++) {
+	    clip[i].x1 = rect->x1;
+	    clip[i].y1 = rect->y1;
+	    clip[i].x2 = rect->x2;
+	    clip[i].y2 = rect->y2;
+	}
+
+	/* TODO query connector property to see if this is needed */
+	ret = drmModeDirtyFB(ms->fd, ms->fb_id, clip, num_cliprects);
+	if (ret) {
+	    if (ret == -EINVAL) {
+		ms->dirty_enabled = FALSE;
+		DamageUnregister(&pScreen->GetScreenPixmap(pScreen)->drawable, ms->damage);
+		DamageDestroy(ms->damage);
+		ms->damage = NULL;
+		xf86DrvMsg(scrn->scrnIndex, X_INFO, "Disabling kernel dirty updates, not required.\n");
+		return;
+	    } else
+		ErrorF("%s: failed to send dirty (%i, %s)\n",
+		       __func__, ret, strerror(-ret));
+	}
+	
+	DamageEmpty(ms->damage);
+    }
+}
+
+static void msBlockHandler(int i, pointer blockData, pointer pTimeout,
+			   pointer pReadmask)
+{
+    ScreenPtr pScreen = screenInfo.screens[i];
+    modesettingPtr ms = modesettingPTR(xf86Screens[pScreen->myNum]);
+
+    pScreen->BlockHandler = ms->BlockHandler;
+    pScreen->BlockHandler(i, blockData, pTimeout, pReadmask);
+    pScreen->BlockHandler = msBlockHandler;
+    if (ms->dirty_enabled)
+	dispatch_dirty(pScreen);
+}
+
 static void
 FreeRec(ScrnInfoPtr pScrn)
 {
@@ -494,6 +546,18 @@ CreateScreenResources(ScreenPtr pScreen)
     if (!pScreen->ModifyPixmapHeader(rootPixmap, -1, -1, -1, -1, -1, pixels))
 	FatalError("Couldn't adjust screen pixmap\n");
 
+    ms->damage = DamageCreate(NULL, NULL, DamageReportNone, TRUE,
+                              pScreen, rootPixmap);
+
+    if (ms->damage) {
+	DamageRegister(&rootPixmap->drawable, ms->damage);
+	ms->dirty_enabled = TRUE;
+	xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Damage tracking initialized\n");
+    } else {
+	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+		   "Failed to create screen damage record\n");
+	return FALSE;
+    }
     return ret;
 }
 
@@ -596,6 +660,9 @@ ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
     ms->CloseScreen = pScreen->CloseScreen;
     pScreen->CloseScreen = CloseScreen;
 
+    ms->BlockHandler = pScreen->BlockHandler;
+    pScreen->BlockHandler = msBlockHandler;
+
     if (!xf86CrtcScreenInit(pScreen))
 	return FALSE;
 
@@ -669,6 +736,12 @@ CloseScreen(int scrnIndex, ScreenPtr pScreen)
     ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
     modesettingPtr ms = modesettingPTR(pScrn);
 
+    if (ms->damage) {
+	DamageUnregister(&pScreen->GetScreenPixmap(pScreen)->drawable, ms->damage);
+	DamageDestroy(ms->damage);
+	ms->damage = NULL;
+    }
+
     drmmode_uevent_fini(pScrn, &ms->drmmode);
 
     drmmode_free_bos(pScrn, &ms->drmmode);
@@ -678,7 +751,7 @@ CloseScreen(int scrnIndex, ScreenPtr pScreen)
     }
 
     pScreen->CreateScreenResources = ms->createScreenResources;
-
+    pScreen->BlockHandler = ms->BlockHandler;
     drmClose(ms->fd);
     ms->fd = -1;
 
diff --git a/src/driver.h b/src/driver.h
index 255dede..beb5f8d 100644
--- a/src/driver.h
+++ b/src/driver.h
@@ -30,6 +30,7 @@
 #include <errno.h>
 #include <drm.h>
 #include <xf86drm.h>
+#include <damage.h>
 
 #include "drmmode_display.h"
 #define DRV_ERROR(msg)	xf86DrvMsg(pScrn->scrnIndex, X_ERROR, msg);
@@ -68,10 +69,13 @@ typedef struct _modesettingRec
     unsigned int SaveGeneration;
 
     CreateScreenResourcesProcPtr createScreenResources;
-
+    ScreenBlockHandlerProcPtr BlockHandler;
     void *driver;
 
     drmmode_rec drmmode;
+
+    DamagePtr damage;
+    Bool dirty_enabled;
 } modesettingRec, *modesettingPtr;
 
 #define modesettingPTR(p) ((modesettingPtr)((p)->driverPrivate))
commit 7307ff4dd1a6cbfa1e4311ec2c6efc26eb81a434
Author: Dave Airlie <airlied at redhat.com>
Date:   Thu Sep 29 12:34:27 2011 +0100

    drop loading dri2

diff --git a/src/driver.c b/src/driver.c
index dee9cff..0aaafd1 100644
--- a/src/driver.c
+++ b/src/driver.c
@@ -462,10 +462,6 @@ PreInit(ScrnInfoPtr pScrn, int flags)
 	return FALSE;
     }
 
-#ifdef DRI2
-    xf86LoadSubModule(pScrn, "dri2");
-#endif
-
     return TRUE;
     fail:
     return FALSE;
commit 0ca055f7b19e60df8ba4aa44522e06e06c1222f1
Author: Dave Airlie <airlied at redhat.com>
Date:   Thu Sep 29 12:34:17 2011 +0100

    update authors/copyright

diff --git a/src/driver.c b/src/driver.c
index 9bb1cb4..dee9cff 100644
--- a/src/driver.c
+++ b/src/driver.c
@@ -1,5 +1,6 @@
 /*
  * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * Copyright 2011 Dave Airlie
  * All Rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
@@ -23,7 +24,8 @@
  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  *
  *
- * Author: Alan Hourihane <alanh at tungstengraphics.com>
+ * Original Author: Alan Hourihane <alanh at tungstengraphics.com>
+ * Rewrite: Dave Airlie <airlied at redhat.com> 
  *
  */
 
commit ac7b8e43842858b8787b1f7ede4d547eece77e5e
Author: Dave Airlie <airlied at redhat.com>
Date:   Thu Sep 29 12:30:46 2011 +0100

    gut some more unneeded code

diff --git a/src/driver.c b/src/driver.c
index be781bc..9bb1cb4 100644
--- a/src/driver.c
+++ b/src/driver.c
@@ -638,24 +638,6 @@ static void
 LeaveVT(int scrnIndex, int flags)
 {
     ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
-    modesettingPtr ms = modesettingPTR(pScrn);
-    xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
-    int o;
-
-    for (o = 0; o < config->num_crtc; o++) {
-	xf86CrtcPtr crtc = config->crtc[o];
-
-	//	cursor_destroy(crtc);
-
-	if (crtc->rotatedPixmap || crtc->rotatedData) {
-	    crtc->funcs->shadow_destroy(crtc, crtc->rotatedPixmap,
-					crtc->rotatedData);
-	    crtc->rotatedPixmap = NULL;
-	    crtc->rotatedData = NULL;
-	}
-    }
-
-    drmModeRmFB(ms->fd, ms->fb_id);
 
     pScrn->vtSema = FALSE;
 }
commit ffb6bb4deb827c369faadd77495d7cae4acc2a42
Author: Dave Airlie <airlied at redhat.com>
Date:   Thu Sep 29 12:28:59 2011 +0100

    modesetting: rewrite probing based on fbdev.
    
    This isn't perfect, it should really do more with bus id matching
    and finding the write drm device using sysfs if it can. but it removes
    lots of hardcoding of pci ids.

diff --git a/src/driver.c b/src/driver.c
index 47ffb07..be781bc 100644
--- a/src/driver.c
+++ b/src/driver.c
@@ -31,6 +31,7 @@
 #include "config.h"
 #endif
 
+#include <fcntl.h>
 #include "xf86.h"
 #include "xf86_OSproc.h"
 #include "compiler.h"
@@ -68,18 +69,19 @@ static Bool ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc,
 		       char **argv);
 static Bool PreInit(ScrnInfoPtr pScrn, int flags);
 
-#if XSERVER_LIBPCIACCESS
-static Bool
-pci_probe(DriverPtr driver,
-	  int entity_num, struct pci_device *device, intptr_t match_data);
-#else
 static Bool Probe(DriverPtr drv, int flags);
-#endif
+static Bool ms_pci_probe(DriverPtr driver,
+			 int entity_num, struct pci_device *device,
+			 intptr_t match_data);
 
-#if XSERVER_LIBPCIACCESS
-static const struct pci_id_match device_match[] = {
-    {0x8086, 0x0046, 0xffff, 0xffff, 0, 0, 0},
-    {0, 0, 0},
+#ifdef XSERVER_LIBPCIACCESS
+static const struct pci_id_match ms_device_match[] = {
+    {
+	PCI_MATCH_ANY, PCI_MATCH_ANY, PCI_MATCH_ANY, PCI_MATCH_ANY,
+	0x00030000, 0x00ffffff, 0
+    },
+
+    { 0, 0, 0 },
 };
 #endif
 
@@ -87,38 +89,29 @@ _X_EXPORT DriverRec modesetting = {
     1,
     "modesetting",
     Identify,
-#if XSERVER_LIBPCIACCESS
-    NULL,
-#else
     Probe,
-#endif
     AvailableOptions,
     NULL,
     0,
     NULL,
-#if XSERVER_LIBPCIACCESS
-    device_match,
-    pci_probe
-#endif
+    ms_device_match,
+    ms_pci_probe,
 };
 
 static SymTabRec Chipsets[] = {
-    {0x0046, "Intel Graphics Device"},
+    {0, "kms" },
     {-1, NULL}
 };
 
-static PciChipsets PciDevices[] = {
-    {0x2592, 0x0046, RES_SHARED_VGA},
-    {-1, -1, RES_UNDEFINED}
-};
-
 typedef enum
 {
     OPTION_SW_CURSOR,
+    OPTION_DEVICE_PATH,
 } modesettingOpts;
 
 static const OptionInfoRec Options[] = {
     {OPTION_SW_CURSOR, "SWcursor", OPTV_BOOLEAN, {0}, FALSE},
+    {OPTION_DEVICE_PATH, "kmsdev", OPTV_STRING, {0}, FALSE },
     {-1, NULL, OPTV_NONE, {0}, FALSE}
 };
 
@@ -171,6 +164,27 @@ Identify(int flags)
 		      Chipsets);
 }
 
+static Bool probe_hw(char *dev)
+{
+    int fd;
+    if (dev)
+	fd = open(dev, O_RDWR, 0);
+    else {
+	dev = getenv("KMSDEVICE");
+	if ((NULL == dev) || ((fd = open(dev, O_RDWR, 0)) == -1)) {
+	    dev = "/dev/dri/card0";
+	    fd = open(dev,O_RDWR, 0);
+	}
+    }
+    if (fd == -1) {
+	xf86DrvMsg(-1, X_ERROR,"open %s: %s\n", dev, strerror(errno));
+	return FALSE;
+    }
+    close(fd);
+    return TRUE;
+
+}
+
 static const OptionInfoRec *
 AvailableOptions(int chipid, int busid)
 {
@@ -179,25 +193,26 @@ AvailableOptions(int chipid, int busid)
 
 #if XSERVER_LIBPCIACCESS
 static Bool
-pci_probe(DriverPtr driver,
-	  int entity_num, struct pci_device *device, intptr_t match_data)
+ms_pci_probe(DriverPtr driver,
+	     int entity_num, struct pci_device *dev, intptr_t match_data)
 {
     ScrnInfoPtr scrn = NULL;
     EntityInfoPtr entity;
     DevUnion *private;
 
-    scrn = xf86ConfigPciEntity(scrn, 0, entity_num, PciDevices,
+    scrn = xf86ConfigPciEntity(scrn, 0, entity_num, NULL,
 			       NULL, NULL, NULL, NULL, NULL);
-    if (scrn != NULL) {
-	scrn->driverVersion = 1;
-	scrn->driverName = "modesetting";
-	scrn->name = "modesetting";
-	scrn->Probe = NULL;
-
-	entity = xf86GetEntityInfo(entity_num);
-
-	switch (device->device_id) {
-	case 0x0046:
+    if (scrn) {
+	char *devpath;
+	GDevPtr devSection = xf86GetDevFromEntity(scrn->entityList[0],
+						  scrn->entityInstanceList[0]);
+
+	devpath = xf86FindOptionValue(devSection->options, "kmsdev");
+	if (probe_hw(devpath)) {
+	    scrn->driverVersion = 1;
+	    scrn->driverName = "modesetting";
+	    scrn->name = "modeset";
+	    scrn->Probe = NULL;
 	    scrn->PreInit = PreInit;
 	    scrn->ScreenInit = ScreenInit;
 	    scrn->SwitchMode = SwitchMode;
@@ -206,12 +221,19 @@ pci_probe(DriverPtr driver,
 	    scrn->LeaveVT = LeaveVT;
 	    scrn->FreeScreen = FreeScreen;
 	    scrn->ValidMode = ValidMode;
-	    break;
-	}
+
+	    xf86DrvMsg(scrn->scrnIndex, X_CONFIG,
+		       "claimed PCI slot %d@%d:%d:%d\n", 
+		       dev->bus, dev->domain, dev->dev, dev->func);
+	    xf86DrvMsg(scrn->scrnIndex, X_INFO,
+		       "using %s\n", devpath ? devpath : "default device");
+	} else
+	    scrn = NULL;
     }
     return scrn != NULL;
 }
-#else
+#endif
+
 static Bool
 Probe(DriverPtr drv, int flags)
 {
@@ -220,9 +242,13 @@ Probe(DriverPtr drv, int flags)
     DevUnion *pPriv;
     GDevPtr *devSections;
     Bool foundScreen = FALSE;
-    pciVideoPtr *VideoInfo;
-    pciVideoPtr *ppPci;
     int numDevs;
+    char *dev;
+    ScrnInfoPtr scrn;
+
+    /* For now, just bail out for PROBE_DETECT. */
+    if (flags & PROBE_DETECT)
+	return FALSE;
 
     /*
      * Find the config file Device sections that match this
@@ -232,110 +258,41 @@ Probe(DriverPtr drv, int flags)
 	return FALSE;
     }
 
-    /*
-     * This probing is just checking the PCI data the server already
-     * collected.
-     */
-    if (!(VideoInfo = xf86GetPciVideoInfo()))
-	return FALSE;
+    for (i = 0; i < numDevSections; i++) {
 
-#if 0
-    numUsed = 0;
-    for (ppPci = VideoInfo; ppPci != NULL && *ppPci != NULL; ppPci++) {
-	for (numDevs = 0; numDevs < numDevSections; numDevs++) {
-	    if (devSections[numDevs]->busID && *devSections[numDevs]->busID) {
-		if (xf86ComparePciBusString
-		    (devSections[numDevs]->busID, (*ppPci)->bus,
-		     (*ppPci)->device, (*ppPci)->func)) {
-		    /* Claim slot */
-		    if (xf86CheckPciSlot((*ppPci)->bus, (*ppPci)->device,
-					 (*ppPci)->func)) {
-			usedChips[numUsed++] =
-			    xf86ClaimPciSlot((*ppPci)->bus, (*ppPci)->device,
-					     (*ppPci)->func, drv,
-					     (*ppPci)->chipType, NULL, TRUE);
-			ErrorF("CLAIMED %d %d %d\n", (*ppPci)->bus,
-			       (*ppPci)->device, (*ppPci)->func);
-		    }
-		}
+	dev = xf86FindOptionValue(devSections[i]->options,"kmsdev");
+	if (devSections[i]->busID) {
+	    if (probe_hw(dev)) {
+		int entity;
+		entity = xf86ClaimFbSlot(drv, 0, devSections[i], TRUE);
+		scrn = xf86ConfigFbEntity(scrn, 0, entity,
+					   NULL, NULL, NULL, NULL);
 	    }
-	}
-    }
-#else
-    /* Look for Intel i8xx devices. */
-    numUsed = xf86MatchPciInstances("modesetting", PCI_VENDOR_INTEL,
-				    Chipsets, PciDevices,
-				    devSections, numDevSections,
-				    drv, &usedChips);
-#endif
 
-    if (flags & PROBE_DETECT) {
-	if (numUsed > 0)
-	    foundScreen = TRUE;
-    } else {
-	for (i = 0; i < numUsed; i++) {
-	    ScrnInfoPtr pScrn = NULL;
-
-	    /* Allocate new ScrnInfoRec and claim the slot */
-	    if ((pScrn = xf86ConfigPciEntity(pScrn, 0, usedChips[i],
-					     PciDevices, NULL, NULL, NULL,
-					     NULL, NULL))) {
-		EntityInfoPtr pEnt;
-
-		pEnt = xf86GetEntityInfo(usedChips[i]);
-
-		pScrn->driverVersion = 1;
-		pScrn->driverName = "modesetting";
-		pScrn->name = "modesetting";
-		pScrn->Probe = Probe;
+	    if (scrn)
 		foundScreen = TRUE;
-		{
-		    /* Allocate an entity private if necessary */
-		    if (modesettingEntityIndex < 0)
-			modesettingEntityIndex =
-			    xf86AllocateEntityPrivateIndex();
-
-		    pPriv = xf86GetEntityPrivate(pScrn->entityList[0],
-						 modesettingEntityIndex);
-		    if (!pPriv->ptr) {
-			pPriv->ptr = xnfcalloc(sizeof(EntRec), 1);
-			msEnt = pPriv->ptr;
-			msEnt->lastInstance = -1;
-		    } else {
-			msEnt = pPriv->ptr;
-		    }
-
-		    /*
-		     * Set the entity instance for this instance of the driver.
-		     * For dual head per card, instance 0 is the "master"
-		     * instance, driving the primary head, and instance 1 is
-		     * the "slave".
-		     */
-		    msEnt->lastInstance++;
-		    xf86SetEntityInstanceForScreen(pScrn,
-						   pScrn->entityList[0],
-						   msEnt->lastInstance);
-		    pScrn->PreInit = PreInit;
-		    pScrn->ScreenInit = ScreenInit;
-		    pScrn->SwitchMode = SwitchMode;
-		    pScrn->AdjustFrame = AdjustFrame;
-		    pScrn->EnterVT = EnterVT;
-		    pScrn->LeaveVT = LeaveVT;
-		    pScrn->FreeScreen = FreeScreen;
-		    pScrn->ValidMode = ValidMode;
-		    break;
-		}
-	    } else
-		ErrorF("FAILED PSCRN\n");
+		scrn->driverVersion = 1;
+		scrn->driverName = "modesetting";
+		scrn->name = "modesetting";
+		scrn->Probe = Probe;
+		scrn->PreInit = PreInit;
+		scrn->ScreenInit = ScreenInit;
+		scrn->SwitchMode = SwitchMode;
+		scrn->AdjustFrame = AdjustFrame;
+		scrn->EnterVT = EnterVT;
+		scrn->LeaveVT = LeaveVT;
+		scrn->FreeScreen = FreeScreen;
+		scrn->ValidMode = ValidMode;
+
+		xf86DrvMsg(scrn->scrnIndex, X_INFO,
+			   "using %s\n", dev ? dev : "default device");
 	}
     }
 
-    free(usedChips);
     free(devSections);
 
     return foundScreen;
 }
-#endif
 
 static Bool
 GetRec(ScrnInfoPtr pScrn)
commit ec9374e4210ab36a07209e27a79922545eafd5e2
Author: Dave Airlie <airlied at redhat.com>
Date:   Thu Sep 29 11:52:51 2011 +0100

    cleanup some the drmmode_display header file

diff --git a/src/drmmode_display.h b/src/drmmode_display.h
index 2d72505..845207a 100644
--- a/src/drmmode_display.h
+++ b/src/drmmode_display.h
@@ -33,49 +33,33 @@
 #endif
 
 struct dumb_bo {
-  uint32_t handle;
-  uint32_t size;
-  void *ptr;
-  int map_count;
-  uint32_t pitch;
+    uint32_t handle;
+    uint32_t size;
+    void *ptr;
+    int map_count;
+    uint32_t pitch;
 };
 
 typedef struct {
-  int fd;
-  unsigned fb_id;
-  drmModeResPtr mode_res;
-  drmModeFBPtr mode_fb;
-  int cpp;
-  ScrnInfoPtr scrn;
+    int fd;
+    unsigned fb_id;
+    drmModeResPtr mode_res;
+    drmModeFBPtr mode_fb;
+    int cpp;
+    ScrnInfoPtr scrn;
 #ifdef HAVE_UDEV
-  struct udev_monitor *uevent_monitor;
-  InputHandlerProc uevent_handler;
+    struct udev_monitor *uevent_monitor;
+    InputHandlerProc uevent_handler;
 #endif
-  drmEventContext event_context;
-  struct dumb_bo *front_bo;
+    drmEventContext event_context;
+    struct dumb_bo *front_bo;
 } drmmode_rec, *drmmode_ptr;
 
 typedef struct {
-  drmmode_ptr drmmode;
-  unsigned old_fb_id;
-  int flip_count;
-  void *event_data;
-  unsigned int fe_frame;
-  unsigned int fe_tv_sec;
-  unsigned int fe_tv_usec;
-} drmmode_flipdata_rec, *drmmode_flipdata_ptr;
-
-typedef struct {
-  drmmode_flipdata_ptr flipdata;
-  Bool dispatch_me;
-} drmmode_flipevtcarrier_rec, *drmmode_flipevtcarrier_ptr;
-
-typedef struct {
     drmmode_ptr drmmode;
     drmModeCrtcPtr mode_crtc;
     int hw_id;
     struct dumb_bo *cursor_bo;
-  //    struct radeon_bo *rotate_bo;
     unsigned rotate_fb_id;
     uint16_t lut_r[256], lut_g[256], lut_b[256];
 } drmmode_crtc_private_rec, *drmmode_crtc_private_ptr;
@@ -103,21 +87,13 @@ typedef struct {
 
 
 extern Bool drmmode_pre_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int cpp);
-//extern Bool drmmode_set_bufmgr(ScrnInfoPtr pScrn, drmmode_ptr drmmode, struct radeon_bo_manager *bufmgr);
-//extern void drmmode_set_cursor(ScrnInfoPtr scrn, drmmode_ptr drmmode, int id, struct radeon_bo *bo);
 void drmmode_adjust_frame(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int x, int y, int flags);
 extern Bool drmmode_set_desired_modes(ScrnInfoPtr pScrn, drmmode_ptr drmmode);
-extern void drmmode_copy_fb(ScrnInfoPtr pScrn, drmmode_ptr drmmode);
 extern Bool drmmode_setup_colormap(ScreenPtr pScreen, ScrnInfoPtr pScrn);
 
 extern void drmmode_uevent_init(ScrnInfoPtr scrn, drmmode_ptr drmmode);
 extern void drmmode_uevent_fini(ScrnInfoPtr scrn, drmmode_ptr drmmode);
 
-extern int drmmode_get_height_align(ScrnInfoPtr scrn, uint32_t tiling);
-extern int drmmode_get_pitch_align(ScrnInfoPtr scrn, int bpe, uint32_t tiling);
-extern int drmmode_get_base_align(ScrnInfoPtr scrn, int bpe, uint32_t tiling);
-
-//Bool radeon_do_pageflip(ScrnInfoPtr scrn, struct radeon_bo *new_front, void *data, int ref_crtc_hw_id);
 Bool drmmode_create_initial_bos(ScrnInfoPtr pScrn, drmmode_ptr drmmode);
 void *drmmode_map_front_bo(drmmode_ptr drmmode);
 Bool drmmode_map_cursor_bos(ScrnInfoPtr pScrn, drmmode_ptr drmmode);
commit 74c284ac4ee24cd32309843d8d191e0a0339677b
Author: Dave Airlie <airlied at redhat.com>
Date:   Thu Sep 29 11:49:26 2011 +0100

    modesetting: restart driver effort from other codebases
    
    This starts a randr 1.2 compatible driver with cursors.
    
    TODO:
    libkms
    dirty handling
    server recycling.

diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..4cada5a
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,79 @@
+#
+#		X.Org module default exclusion patterns
+#		The next section if for module specific patterns
+#
+#	Do not edit the following section
+# 	GNU Build System (Autotools)
+aclocal.m4
+autom4te.cache/
+autoscan.log
+ChangeLog
+compile
+config.guess
+config.h
+config.h.in
+config.log
+config-ml.in
+config.py
+config.status
+config.status.lineno
+config.sub
+configure
+configure.scan
+depcomp
+.deps/
+INSTALL
+install-sh
+.libs/
+libtool
+libtool.m4
+ltmain.sh
+lt~obsolete.m4
+ltoptions.m4
+ltsugar.m4
+ltversion.m4
+Makefile
+Makefile.in
+mdate-sh
+missing
+mkinstalldirs
+*.pc
+py-compile
+stamp-h?
+symlink-tree
+texinfo.tex
+ylwrap
+
+#	Do not edit the following section
+# 	Edit Compile Debug Document Distribute
+*~
+*.[0-9]
+*.[0-9]x
+*.bak
+*.bin
+core
+*.dll
+*.exe
+*-ISO*.bdf
+*-JIS*.bdf
+*-KOI8*.bdf
+*.kld
+*.ko
+*.ko.cmd
+*.lai
+*.l[oa]
+*.[oa]
+*.obj
+*.patch
+*.so
+*.pcf.gz
+*.pdb
+*.tar.bz2
+*.tar.gz
+#
+#		Add & Override patterns for xf86-video-intel 
+#
+#		Edit the following section as needed
+# For example, !report.pc overrides *.pc. See 'man gitignore'
+# 
+cscope*
diff --git a/configure.ac b/configure.ac
index d1bdf10..3d4d267 100644
--- a/configure.ac
+++ b/configure.ac
@@ -20,24 +20,30 @@
 #
 # Process this file with autoconf to produce a configure script
 
-AC_PREREQ(2.57)
+AC_PREREQ([2.60])
 AC_INIT([xf86-video-modesetting],
-        0.1.0,
+        [0.1.0],
         [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg],
-        xf86-video-modesetting)
+        [xf86-video-modesetting])
 
 AC_CONFIG_SRCDIR([Makefile.am])
 AM_CONFIG_HEADER([config.h])
+
+m4_ifndef([XORG_MACROS_VERSION],
+	[m4_fatal([must install xorg-macros 1.8 or later before runnign autoconf/autogen])])
+XORG_MACROS_VERSION(1.8)
+XORG_DEFAULT_OPTIONS
+
 AC_CONFIG_AUX_DIR(.)
 
-AM_INIT_AUTOMAKE([dist-bzip2])
+AM_INIT_AUTOMAKE([foreign dist-bzip2])
+AC_SYS_LARGEFILE
 
 AM_MAINTAINER_MODE
 
 # Checks for programs.
 AC_DISABLE_STATIC
 AC_PROG_LIBTOOL
-DOLT
 AC_PROG_CC
 AM_PROG_CC_C_O
 
@@ -49,11 +55,6 @@ AC_ARG_WITH(xorg-module-dir,
             [moduledir="$withval"],
             [moduledir="$libdir/xorg/modules"])
 
-AC_ARG_WITH(gallium-dir,
-            AC_HELP_STRING([--with-gallium-dir=DIR],
-                           [gallium directory [[default=none]]]),
-            [GALLIUM_DIR="$withval"])
-
 AC_ARG_ENABLE(dri, AC_HELP_STRING([--disable-dri],
                                   [Disable DRI support [[default=auto]]]),
               [DRI="$enableval"],
@@ -74,115 +75,23 @@ sdkdir=$(pkg-config --variable=sdkdir xorg-server)
 # Checks for header files.
 AC_HEADER_STDC
 
-AC_MSG_CHECKING([whether to include DRI support])
-if test x$DRI = xauto; then
-        AC_CHECK_FILE([${sdkdir}/dri.h],
-                      [have_dri_h="yes"], [have_dri_h="no"])
-        AC_CHECK_FILE([${sdkdir}/sarea.h],
-                      [have_sarea_h="yes"], [have_sarea_h="no"])
-        AC_CHECK_FILE([${sdkdir}/dristruct.h],
-                      [have_dristruct_h="yes"], [have_dristruct_h="no"])
-	AC_CHECK_FILE([${sdkdir}/damage.h],
-                      [have_damage_h="yes"], [have_damage_h="no"])
-
-        if test "$have_dri_h" = yes -a \
-                "$have_sarea_h" = yes -a \
-                "$have_dristruct_h" = yes; then
-                DRI="yes"
-        else
-                DRI="no"
-        fi
-fi
-AC_MSG_RESULT([$DRI])
-
-save_CFLAGS="$CFLAGS"
-CFLAGS="$XORG_CFLAGS"
-AC_CHECK_DECL(XSERVER_LIBPCIACCESS,
-	      [XSERVER_LIBPCIACCESS=yes],[XSERVER_LIBPCIACCESS=no],
-	      [#include "xorg-server.h"])
-CFLAGS="$save_CFLAGS"
-
-if test x$XSERVER_LIBPCIACCESS = xyes; then
-	PKG_CHECK_MODULES([PCIACCESS], [pciaccess >= 0.10])
-else
-	PKG_CHECK_MODULES([PCIACCESS], [pciaccess >= 0.10],
-				       have_libpciaccess=yes,
-				       have_libpciaccess=no)
-fi
-AM_CONDITIONAL(XSERVER_LIBPCIACCESS, test "x$XSERVER_LIBPCIACCESS" = xyes)
-AM_CONDITIONAL(LIBPCIACCESS,
-	test "x$XSERVER_LIBPCIACCESS" = xyes -o "x$have_libpciaccess" = xyes)
-
-if test "x$XSERVER_SOURCE" = x; then
-	if test -d ../../xserver; then
-		XSERVER_SOURCE="`cd ../../xserver && pwd`"
-	fi
-fi
-	
-if test -d "$XSERVER_SOURCE"; then
-	case "$XSERVER_SOURCE" in
-	/*)
-		;;
-	*)
-		XSERVER_SOURCE="`cd $XSERVER_SOURCE && pwd`"
-		;;
-	esac
-	if test -f $srcdir/src/modes/xf86Modes.h; then
-		:
-	else
-		ln -sf $XSERVER_SOURCE/hw/xfree86/modes $srcdir/src/modes
-	fi
-	
-	if test -f $srcdir/src/parser/xf86Parser.h; then
-		:
-	else
-		ln -sf $XSERVER_SOURCE/hw/xfree86/parser $srcdir/src/parser
-	fi
-fi
-
-dnl Use lots of warning flags with GCC
-
-WARN_CFLAGS=""
+PKG_CHECK_MODULES(DRM, [libdrm >= 2.2])
+PKG_CHECK_MODULES([PCIACCESS], [pciaccess >= 0.10])
+AM_CONDITIONAL(DRM, test "x$DRM" = xyes)
 
-if test "x$GCC" = "xyes"; then
-	WARN_CFLAGS="-Wall -Wpointer-arith -Wstrict-prototypes \
-	-Wmissing-prototypes -Wmissing-declarations \
-	-Wnested-externs -fno-strict-aliasing"
+PKG_CHECK_MODULES(UDEV, [libudev], [udev=yes], [udev=no])
+if test x"$udev" = xyes; then
+        AC_DEFINE(HAVE_UDEV,1,[Enable udev-based monitor hotplug detection])
 fi
 
-AM_CONDITIONAL(DRI, test x$DRI = xyes)
-if test "$DRI" = yes; then
-        PKG_CHECK_MODULES(DRI, [libdrm xf86driproto])
-        AC_DEFINE(XF86DRI,1,[Enable DRI driver support])
-        AC_DEFINE(XF86DRI_DEVEL,1,[Enable developmental DRI driver support])
-	PKG_CHECK_MODULES(DRI_MM, [libdrm >= 2.3.1],[DRI_MM=yes], [DRI_MM=no])
-	if test "x$DRI_MM" = xyes; then
-		AC_DEFINE(XF86DRI_MM,1,[Extended DRI memory management])
-	fi
-	if test "$have_damage_h" = yes; then
-		AC_DEFINE(DAMAGE,1,[Use Damage extension])
-	fi
-	CFLAGS="$XORG_CFLAGS $DRI_CFLAGS"
-fi
-
-AC_SUBST([DRI_CFLAGS])
-AC_SUBST([XORG_CFLAGS])
-AC_SUBST([WARN_CFLAGS])
-AC_SUBST([GALLIUM_DIR])
-AC_SUBST([moduledir])
-
 DRIVER_NAME=modesetting
 AC_SUBST([DRIVER_NAME])
+AC_SUBST([moduledir])
 
-m4_ifndef([XORG_MACROS_VERSION], [AC_FATAL([must install xorg-macros 1.1.3 or later before running autoconf/autogen])])
-XORG_MACROS_VERSION(1.1.3)
-XORG_MANPAGE_SECTIONS
-XORG_RELEASE_VERSION
-
-XORG_CHECK_LINUXDOC
-
-AC_OUTPUT([
+AC_CONFIG_FILES([
 	Makefile
 	src/Makefile
 	man/Makefile
 ])
+
+AC_OUTPUT
diff --git a/man/Makefile.am b/man/Makefile.am
index 89ca862..936821c 100644
--- a/man/Makefile.am
+++ b/man/Makefile.am
@@ -25,14 +25,7 @@
 # 
 
 drivermandir = $(DRIVER_MAN_DIR)
-
-DRIVER_MAN_DIR_SUFFIX = $(DRIVER_MAN_DIR:@mandir@/man%=%)
-
-driverman_PRE = @DRIVER_NAME at .man
-
-driverman_DATA = \
-	$(driverman_PRE:man=@DRIVER_MAN_SUFFIX@) \
-	modesetting. at DRIVER_MAN_SUFFIX@
+driverman_DATA = $(DRIVER_NAME).$(DRIVER_MAN_SUFFIX)
 
 EXTRA_DIST = @DRIVER_NAME at .man
 
@@ -40,30 +33,8 @@ CLEANFILES = $(driverman_DATA)
 
 SED = sed
 
-# Strings to replace in man pages
-XORGRELSTRING = @PACKAGE_STRING@
-  XORGMANNAME = X Version 11
-
-MAN_SUBSTS = \
-	-e 's|__vendorversion__|"$(XORGRELSTRING)" "$(XORGMANNAME)"|' \
-	-e 's|__xorgversion__|"$(XORGRELSTRING)" "$(XORGMANNAME)"|' \
-	-e 's|__xservername__|Xorg|g' \
-	-e 's|__xconfigfile__|xorg.conf|g' \
-	-e 's|__projectroot__|$(prefix)|g' \
-	-e 's|__appmansuffix__|$(APP_MAN_SUFFIX)|g' \
-	-e 's|__drivermansuffix__|$(DRIVER_MAN_SUFFIX)|g' \
-	-e 's|__adminmansuffix__|$(ADMIN_MAN_SUFFIX)|g' \
-	-e 's|__miscmansuffix__|$(MISC_MAN_SUFFIX)|g' \
-	-e 's|__filemansuffix__|$(FILE_MAN_SUFFIX)|g'
-
 SUFFIXES = .$(DRIVER_MAN_SUFFIX) .man
 
 .man.$(DRIVER_MAN_SUFFIX):
 	sed $(MAN_SUBSTS) < $< > $@
 
-BUILT_SOURCES = shadows.DONE
-
-shadows.DONE:
-	-rm -f modesetting. at DRIVER_MAN_SUFFIX@
-	echo .so man$(DRIVER_MAN_DIR_SUFFIX)/modesetting.$(DRIVER_MAN_SUFFIX) > \
-		modesetting. at DRIVER_MAN_SUFFIX@
diff --git a/src/Makefile.am b/src/Makefile.am
index 23e78b7..4337977 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -25,19 +25,16 @@ SUBDIRS =
 # _ladir passes a dummy rpath to libtool so the thing will actually link
 # TODO: -nostdlib/-Bstatic/-lgcc platform magic, not installing the .a, etc.
 
-AM_CFLAGS = @WARN_CFLAGS@ @XORG_CFLAGS@ @DRI_CFLAGS@ @PCIACCESS_CFLAGS@ \
-	-I at GALLIUM_DIR@/src/gallium/include \
-	-I at GALLIUM_DIR@/src/gallium/auxiliary
+AM_CFLAGS = @XORG_CFLAGS@ @DRM_CFLAGS@ @UDEV_CFLAGS@
 
 modesetting_drv_la_LTLIBRARIES = modesetting_drv.la
-modesetting_drv_la_LDFLAGS = -module -avoid-version -ldrm
+modesetting_drv_la_LDFLAGS = -module -avoid-version
+modesetting_drv_la_LIBADD = @UDEV_LIBS@ @DRM_LIBS@
 modesetting_drv_ladir = @moduledir@/drivers
 
 modesetting_drv_la_SOURCES = \
 	 driver.c \
 	 driver.h \
-	 output.c \
-	 crtc.c \
-	 dri2.c
+	 drmmode_display.c
 
 EXTRA_DIST =
diff --git a/src/crtc.c b/src/crtc.c
deleted file mode 100644
index d4f449b..0000000
--- a/src/crtc.c
+++ /dev/null
@@ -1,307 +0,0 @@
-/*
- * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- *
- * 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, sub license, 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 NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS 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.
- *
- *
- * Author: Alan Hourihane <alanh at tungstengraphics.com>
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <unistd.h>
-#include <string.h>
-#include <assert.h>
-#include <stdlib.h>
-#include <math.h>
-#include <stdint.h>
-
-#include <xf86.h>
-#include <xf86i2c.h>
-#include <xf86Crtc.h>
-#include "driver.h"
-#include "xf86Modes.h"
-
-#define DPMS_SERVER
-#include <X11/extensions/dpms.h>
-
-struct crtc_private
-{
-    drmModeCrtcPtr drm_crtc;
-
-    /* hwcursor */
-    drmBO cursor_bo;
-};
-
-static void
-crtc_dpms(xf86CrtcPtr crtc, int mode)
-{
-    ScrnInfoPtr pScrn = crtc->scrn;
-
-    switch (mode) {
-    case DPMSModeOn:
-    case DPMSModeStandby:
-    case DPMSModeSuspend:
-	break;
-    case DPMSModeOff:
-	break;
-    }
-}
-
-static Bool
-crtc_lock(xf86CrtcPtr crtc)
-{
-    return FALSE;
-}
-
-static void
-crtc_unlock(xf86CrtcPtr crtc)
-{
-}
-
-static void
-crtc_prepare(xf86CrtcPtr crtc)
-{
-}
-
-static void
-crtc_commit(xf86CrtcPtr crtc)
-{
-}
-
-static Bool
-crtc_mode_fixup(xf86CrtcPtr crtc, DisplayModePtr mode,
-		DisplayModePtr adjusted_mode)
-{
-    return TRUE;
-}
-
-static void
-crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode,
-	      DisplayModePtr adjusted_mode, int x, int y)
-{
-    xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(crtc->scrn);
-    modesettingPtr ms = modesettingPTR(crtc->scrn);
-    xf86OutputPtr output = config->output[config->compat_output];
-    drmModeConnectorPtr drm_connector = output->driver_private;
-    struct crtc_private *crtcp = crtc->driver_private;
-    drmModeCrtcPtr drm_crtc = crtcp->drm_crtc;
-    struct drm_mode_modeinfo drm_mode;
-
-    drm_mode.clock = mode->Clock;
-    drm_mode.hdisplay = mode->HDisplay;
-    drm_mode.hsync_start = mode->HSyncStart;
-    drm_mode.hsync_end = mode->HSyncEnd;
-    drm_mode.htotal = mode->HTotal;
-    drm_mode.vdisplay = mode->VDisplay;
-    drm_mode.vsync_start = mode->VSyncStart;
-    drm_mode.vsync_end = mode->VSyncEnd;
-    drm_mode.vtotal = mode->VTotal;
-    drm_mode.flags = mode->Flags;
-    drm_mode.hskew = mode->HSkew;
-    drm_mode.vscan = mode->VScan;
-    drm_mode.vrefresh = mode->VRefresh;
-    if (!mode->name)
-	xf86SetModeDefaultName(mode);
-    strncpy(drm_mode.name, mode->name, DRM_DISPLAY_MODE_LEN);
-
-    drmModeSetCrtc(ms->fd, drm_crtc->crtc_id, ms->fb_id, x, y,
-		   &drm_connector->connector_id, 1, &drm_mode);
-}
-
-void
-crtc_load_lut(xf86CrtcPtr crtc)
-{
-    ScrnInfoPtr pScrn = crtc->scrn;
-}
-
-static void
-crtc_gamma_set(xf86CrtcPtr crtc, CARD16 * red, CARD16 * green, CARD16 * blue,
-	       int size)
-{
-}
-
-static void *
-crtc_shadow_allocate(xf86CrtcPtr crtc, int width, int height)
-{
-    ScrnInfoPtr pScrn = crtc->scrn;
-
-    return NULL;
-}
-
-static PixmapPtr
-crtc_shadow_create(xf86CrtcPtr crtc, void *data, int width, int height)
-{
-    ScrnInfoPtr pScrn = crtc->scrn;
-
-    return NULL;
-}
-
-static void
-crtc_shadow_destroy(xf86CrtcPtr crtc, PixmapPtr rotate_pixmap, void *data)
-{
-    ScrnInfoPtr pScrn = crtc->scrn;
-}
-
-static void
-crtc_destroy(xf86CrtcPtr crtc)
-{
-    modesettingPtr ms = modesettingPTR(crtc->scrn);
-    struct crtc_private *crtcp = crtc->driver_private;
-
-    if (crtcp->cursor_bo.handle)
-	drmBOUnreference(ms->fd, &crtcp->cursor_bo);
-
-    drmModeFreeCrtc(crtcp->drm_crtc);
-    xfree(crtcp);
-}
-
-static void
-crtc_load_cursor_argb(xf86CrtcPtr crtc, CARD32 * image)
-{
-    unsigned char *ptr;
-    modesettingPtr ms = modesettingPTR(crtc->scrn);
-    struct crtc_private *crtcp = crtc->driver_private;
-
-    if (!crtcp->cursor_bo.handle)
-	drmBOCreate(ms->fd, 64 * 64 * 4, 0, NULL,
-		    DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE
-		    | DRM_BO_FLAG_NO_EVICT | DRM_BO_FLAG_MAPPABLE |
-		    DRM_BO_FLAG_MEM_VRAM,
-		    DRM_BO_HINT_DONT_FENCE, &crtcp->cursor_bo);
-
-    drmBOMap(ms->fd, &crtcp->cursor_bo, DRM_BO_FLAG_WRITE,
-	     DRM_BO_HINT_DONT_FENCE, (void **)&ptr);
-
-    if (ptr)
-	memcpy(ptr, image, 64 * 64 * 4);
-
-    drmBOUnmap(ms->fd, &crtcp->cursor_bo);
-}
-
-static void
-crtc_set_cursor_position(xf86CrtcPtr crtc, int x, int y)
-{
-    modesettingPtr ms = modesettingPTR(crtc->scrn);
-    struct crtc_private *crtcp = crtc->driver_private;
-
-    drmModeMoveCursor(ms->fd, crtcp->drm_crtc->crtc_id, x, y);
-}
-
-static void
-crtc_show_cursor(xf86CrtcPtr crtc)
-{
-    modesettingPtr ms = modesettingPTR(crtc->scrn);
-    struct crtc_private *crtcp = crtc->driver_private;
-
-    if (crtcp->cursor_bo.handle)
-	drmModeSetCursor(ms->fd, crtcp->drm_crtc->crtc_id,
-			 crtcp->cursor_bo.handle, 64, 64);
-}
-
-static void
-crtc_hide_cursor(xf86CrtcPtr crtc)
-{
-    modesettingPtr ms = modesettingPTR(crtc->scrn);
-    struct crtc_private *crtcp = crtc->driver_private;
-
-    drmModeSetCursor(ms->fd, crtcp->drm_crtc->crtc_id, 0, 0, 0);
-}
-
-static const xf86CrtcFuncsRec crtc_funcs = {
-    .dpms = crtc_dpms,
-    .save = NULL,
-    .restore = NULL,
-    .lock = crtc_lock,
-    .unlock = crtc_unlock,
-    .mode_fixup = crtc_mode_fixup,
-    .prepare = crtc_prepare,
-    .mode_set = crtc_mode_set,
-    .commit = crtc_commit,
-    .gamma_set = crtc_gamma_set,
-    .shadow_create = crtc_shadow_create,
-    .shadow_allocate = crtc_shadow_allocate,
-    .shadow_destroy = crtc_shadow_destroy,
-    .set_cursor_position = crtc_set_cursor_position,
-    .show_cursor = crtc_show_cursor,
-    .hide_cursor = crtc_hide_cursor,
-    .load_cursor_image = NULL,	       /* lets convert to argb only */
-    .set_cursor_colors = NULL,	       /* using argb only */
-    .load_cursor_argb = crtc_load_cursor_argb,
-    .destroy = crtc_destroy,
-};
-
-void
-cursor_destroy(xf86CrtcPtr crtc)
-{
-    modesettingPtr ms = modesettingPTR(crtc->scrn);
-    struct crtc_private *crtcp = crtc->driver_private;
-
-    if (crtcp->cursor_bo.handle) {
-	drmBOSetStatus(ms->fd, &crtcp->cursor_bo, 0, 0, 0, 0, 0);
-	drmBOUnreference(ms->fd, &crtcp->cursor_bo);
-    }
-}
-
-void
-crtc_init(ScrnInfoPtr pScrn)
-{
-    modesettingPtr ms = modesettingPTR(pScrn);
-    xf86CrtcPtr crtc;
-    drmModeResPtr res;
-    drmModeCrtcPtr drm_crtc = NULL;
-    struct crtc_private *crtcp;
-    int c, k, p;
-
-    res = drmModeGetResources(ms->fd);
-    if (res == 0) {
-	ErrorF("Failed drmModeGetResources %d\n", errno);
-	return;
-    }
-
-    for (c = 0; c < res->count_crtcs; c++) {
-	drm_crtc = drmModeGetCrtc(ms->fd, res->crtcs[c]);
-	if (!drm_crtc)
-	    continue;
-
-	crtc = xf86CrtcCreate(pScrn, &crtc_funcs);
-	if (crtc == NULL)
-	    goto out;
-
-	crtcp = xcalloc(1, sizeof(struct crtc_private));
-	if (!crtcp) {
-	    xf86CrtcDestroy(crtc);
-	    goto out;
-	}
-
-	crtcp->drm_crtc = drm_crtc;
-
-	crtc->driver_private = crtcp;
-
-    }
-
-  out:
-    drmModeFreeResources(res);
-}
diff --git a/src/dri2.c b/src/dri2.c
deleted file mode 100644
index 7fd9fca..0000000
--- a/src/dri2.c
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- *
- * 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, sub license, 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 NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS 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.
- *
- *
- * Author: Alan Hourihane <alanh at tungstengraphics.com>
- *
- */
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "xf86.h"
-#include "xf86_OSproc.h"
-
-#include "driver.h"
-
-#include "dri2.h"
-
-extern unsigned int
-driGetPixmapHandle(PixmapPtr pPixmap, unsigned int *flags);
-
-void
-driLock(ScreenPtr pScreen)
-{
-    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
-    modesettingPtr ms = modesettingPTR(pScrn);
-
-    if (!ms->lock_held)
-	DRM_LOCK(ms->fd, ms->lock, ms->context, 0);
-
-    ms->lock_held = 1;
-}
-
-void
-driUnlock(ScreenPtr pScreen)
-{
-    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
-    modesettingPtr ms = modesettingPTR(pScrn);
-
-    if (ms->lock_held)
-	DRM_UNLOCK(ms->fd, ms->lock, ms->context);
-
-    ms->lock_held = 0;
-}
-
-static void
-driBeginClipNotify(ScreenPtr pScreen)
-{
-    driLock(pScreen);
-}
-
-static void
-driEndClipNotify(ScreenPtr pScreen)
-{
-    driUnlock(pScreen);
-}
-
-struct __DRILock
-{
-    unsigned int block_header;
-    drm_hw_lock_t lock;
-    unsigned int next_id;
-};
-
-#define DRI2_SAREA_BLOCK_HEADER(type, size) (((type) << 16) | (size))
-#define DRI2_SAREA_BLOCK_LOCK		0x0001
-
-void
-driScreenInit(ScreenPtr pScreen)
-{
-    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
-    modesettingPtr ms = modesettingPTR(pScrn);
-    DRI2InfoRec dri2info;
-    const char *driverName;
-    unsigned int sarea_handle;
-    struct __DRILock *DRILock;
-    void *p;
-
-    dri2info.version = 1;
-    dri2info.fd = ms->fd;
-    dri2info.driverSareaSize = sizeof(struct __DRILock);
-    dri2info.driverName = "i915";      /* FIXME */
-    dri2info.getPixmapHandle = driGetPixmapHandle;
-    dri2info.beginClipNotify = driBeginClipNotify;
-    dri2info.endClipNotify = driEndClipNotify;
-
-    p = DRI2ScreenInit(pScreen, &dri2info);
-    if (!p)
-	return;
-
-    DRILock = p;
-    DRILock->block_header =
-	DRI2_SAREA_BLOCK_HEADER(DRI2_SAREA_BLOCK_LOCK, sizeof *DRILock);
-    ms->lock = &DRILock->lock;
-    ms->context = 1;
-    DRILock->next_id = 2;
-    driLock(pScreen);
-
-    DRI2Connect(pScreen, &ms->fd, &driverName, &sarea_handle);
-}
-
-void
-driCloseScreen(ScreenPtr pScreen)
-{
-    driUnlock(pScreen);
-    DRI2CloseScreen(pScreen);
-}
diff --git a/src/driver.c b/src/driver.c
index 6b70d4b..47ffb07 100644
--- a/src/driver.c
+++ b/src/driver.c
@@ -34,10 +34,8 @@
 #include "xf86.h"
 #include "xf86_OSproc.h"
 #include "compiler.h"
-#include "xf86RAC.h"
 #include "xf86PciInfo.h"
 #include "xf86Pci.h"
-#include "xf86Resources.h"
 #include "mipointer.h"
 #include "micmap.h"
 #include <X11/extensions/randr.h>
@@ -59,8 +57,6 @@
 static void AdjustFrame(int scrnIndex, int x, int y, int flags);
 static Bool CloseScreen(int scrnIndex, ScreenPtr pScreen);
 static Bool EnterVT(int scrnIndex, int flags);
-static Bool SaveHWState(ScrnInfoPtr pScrn);
-static Bool RestoreHWState(ScrnInfoPtr pScrn);
 static void Identify(int flags);
 static const OptionInfoRec *AvailableOptions(int chipid, int busid);
 static ModeStatus ValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose,
@@ -82,7 +78,7 @@ static Bool Probe(DriverPtr drv, int flags);
 
 #if XSERVER_LIBPCIACCESS
 static const struct pci_id_match device_match[] = {
-    {0x8086, 0x2592, 0xffff, 0xffff, 0, 0, 0},
+    {0x8086, 0x0046, 0xffff, 0xffff, 0, 0, 0},
     {0, 0, 0},
 };
 #endif
@@ -107,12 +103,12 @@ _X_EXPORT DriverRec modesetting = {
 };
 
 static SymTabRec Chipsets[] = {
-    {0x2592, "Intel Graphics Device"},
+    {0x0046, "Intel Graphics Device"},
     {-1, NULL}
 };
 
 static PciChipsets PciDevices[] = {
-    {0x2592, 0x2592, RES_SHARED_VGA},
+    {0x2592, 0x0046, RES_SHARED_VGA},
     {-1, -1, RES_UNDEFINED}
 };
 
@@ -126,24 +122,6 @@ static const OptionInfoRec Options[] = {
     {-1, NULL, OPTV_NONE, {0}, FALSE}
 };
 
-static const char *fbSymbols[] = {
-    "fbPictureInit",
-    "fbScreenInit",
-    NULL
-};
-
-static const char *ddcSymbols[] = {
-    "xf86PrintEDID",
-    "xf86SetDDCproperties",
-    NULL
-};
-
-static const char *i2cSymbols[] = {
-    "xf86CreateI2CBusRec",
-    "xf86I2CBusInit",
-    NULL
-};
-
 int modesettingEntityIndex = -1;
 
 static MODULESETUPPROTO(Setup);
@@ -175,12 +153,6 @@ Setup(pointer module, pointer opts, int *errmaj, int *errmin)
 	xf86AddDriver(&modesetting, module, HaveDriverFuncs);
 
 	/*
-	 * Tell the loader about symbols from other modules that this module
-	 * might refer to.
-	 */
-	LoaderRefSymLists(fbSymbols, ddcSymbols, NULL);
-
-	/*
 	 * The return value must be non-NULL on success even though there
 	 * is no TearDownProc.
 	 */
@@ -225,7 +197,7 @@ pci_probe(DriverPtr driver,
 	entity = xf86GetEntityInfo(entity_num);
 
 	switch (device->device_id) {
-	case 0x2592:
+	case 0x0046:
 	    scrn->PreInit = PreInit;
 	    scrn->ScreenInit = ScreenInit;
 	    scrn->SwitchMode = SwitchMode;
@@ -358,8 +330,8 @@ Probe(DriverPtr drv, int flags)
 	}
     }
 
-    xfree(usedChips);
-    xfree(devSections);
+    free(usedChips);
+    free(devSections);
 
     return foundScreen;
 }
@@ -385,76 +357,11 @@ FreeRec(ScrnInfoPtr pScrn)
     if (!pScrn->driverPrivate)
 	return;
 
-    xfree(pScrn->driverPrivate);
+    free(pScrn->driverPrivate);
 
     pScrn->driverPrivate = NULL;
 }
 
-static void
-ProbeDDC(ScrnInfoPtr pScrn, int index)
-{
-    ConfiguredMonitor = NULL;
-}
-
-static Bool
-CreateFrontBuffer(ScrnInfoPtr pScrn)
-{
-    modesettingPtr ms = modesettingPTR(pScrn);
-    ScreenPtr pScreen = pScrn->pScreen;
-    PixmapPtr rootPixmap = pScreen->GetScreenPixmap(pScreen);
-    Bool fbAccessDisabled;
-    int flags;
-
-    pScreen->ModifyPixmapHeader(rootPixmap,
-				pScrn->virtualX, pScrn->virtualY,
-				pScrn->depth, pScrn->bitsPerPixel,
-				pScrn->displayWidth * pScrn->bitsPerPixel / 8,
-				NULL);
-    drmModeAddFB(ms->fd,
-		 pScrn->virtualX,
-		 pScrn->virtualY,
-		 pScrn->depth,
-		 pScrn->bitsPerPixel,
-		 pScrn->displayWidth * pScrn->bitsPerPixel / 8,
-		 driGetPixmapHandle(rootPixmap, &flags), &ms->fb_id);
-
-    pScrn->frameX0 = 0;
-    pScrn->frameY0 = 0;
-    AdjustFrame(pScrn->scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
-
-    return TRUE;
-}
-
-static Bool
-crtc_resize(ScrnInfoPtr pScrn, int width, int height)
-{
-    modesettingPtr ms = modesettingPTR(pScrn);
-    ScreenPtr pScreen = pScrn->pScreen;
-    PixmapPtr rootPixmap = pScreen->GetScreenPixmap(pScreen);
-    Bool fbAccessDisabled;
-    CARD8 *fbstart;
-
-    if (width == pScrn->virtualX && height == pScrn->virtualY)
-	return TRUE;
-
-    ErrorF("RESIZING TO %dx%d\n", width, height);
-
-    pScrn->virtualX = width;
-    pScrn->virtualY = height;
-
-    /* HW dependent - FIXME */
-    pScrn->displayWidth = pScrn->virtualX;
-
-    drmModeRmFB(ms->fd, ms->fb_id);
-
-    /* now create new frontbuffer */
-    return CreateFrontBuffer(pScrn);
-}
-
-static const xf86CrtcConfigFuncsRec crtc_config_funcs = {
-    crtc_resize
-};
-
 static Bool
 PreInit(ScrnInfoPtr pScrn, int flags)
 {
@@ -476,8 +383,7 @@ PreInit(ScrnInfoPtr pScrn, int flags)
     pEnt = xf86GetEntityInfo(pScrn->entityList[0]);
 
     if (flags & PROBE_DETECT) {
-	ProbeDDC(pScrn, pEnt->index);
-	return TRUE;
+	return FALSE;
     }
 
     /* Allocate driverPrivate */
@@ -503,10 +409,6 @@ PreInit(ScrnInfoPtr pScrn, int flags)
     } else
 	ms->entityPrivate = NULL;
 
-    if (xf86RegisterResources(ms->pEnt->index, NULL, ResNone)) {
-	return FALSE;
-    }
-
     if (xf86IsEntityShared(pScrn->entityList[0])) {
 	if (xf86IsPrimInitDone(pScrn->entityList[0])) {
 	    /* do something */
@@ -515,7 +417,7 @@ PreInit(ScrnInfoPtr pScrn, int flags)
 	}
     }
 
-    BusID = xalloc(64);
+    BusID = malloc(64);
     sprintf(BusID, "PCI:%d:%d:%d",
 #if XSERVER_LIBPCIACCESS
 	    ((ms->PciInfo->domain << 8) | ms->PciInfo->bus),
@@ -528,11 +430,9 @@ PreInit(ScrnInfoPtr pScrn, int flags)
 	);
 
     ms->fd = drmOpen(NULL, BusID);
-
     if (ms->fd < 0)
 	return FALSE;
 
-    pScrn->racMemFlags = RAC_FB | RAC_COLORMAP;
     pScrn->monitor = pScrn->confScreen->monitor;
     pScrn->progClock = TRUE;
     pScrn->rgbBits = 8;
@@ -562,36 +462,21 @@ PreInit(ScrnInfoPtr pScrn, int flags)
 
     /* Process the options */
     xf86CollectOptions(pScrn, NULL);
-    if (!(ms->Options = xalloc(sizeof(Options))))
+    if (!(ms->Options = malloc(sizeof(Options))))
 	return FALSE;
     memcpy(ms->Options, Options, sizeof(Options));
     xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, ms->Options);
 
-    /* Allocate an xf86CrtcConfig */
-    xf86CrtcConfigInit(pScrn, &crtc_config_funcs);
-    xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
-
-    max_width = 8192;
-    max_height = 8192;
-    xf86CrtcSetSizeRange(pScrn, 320, 200, max_width, max_height);
-
     if (xf86ReturnOptValBool(ms->Options, OPTION_SW_CURSOR, FALSE)) {
 	ms->SWCursor = TRUE;
     }
 
-    SaveHWState(pScrn);
-
-    crtc_init(pScrn);
-    output_init(pScrn);
-
-    if (!xf86InitialConfiguration(pScrn, TRUE)) {
-	xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes.\n");
-	RestoreHWState(pScrn);
-	return FALSE;
+    ms->drmmode.fd = ms->fd;
+    if (drmmode_pre_init(pScrn, &ms->drmmode, pScrn->bitsPerPixel / 8) == FALSE) {
+	xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "KMS setup failed\n");
+	goto fail;
     }
 
-    RestoreHWState(pScrn);
-
     /*
      * If the driver can do gamma correction, it should call xf86SetGamma() here.
      */
@@ -618,29 +503,13 @@ PreInit(ScrnInfoPtr pScrn, int flags)
 	return FALSE;
     }
 
-    xf86LoaderReqSymLists(fbSymbols, NULL);
-
 #ifdef DRI2
     xf86LoadSubModule(pScrn, "dri2");
 #endif
 
     return TRUE;
-}
-
-static Bool
-SaveHWState(ScrnInfoPtr pScrn)
-{
-    xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
-
-    return TRUE;
-}
-
-static Bool
-RestoreHWState(ScrnInfoPtr pScrn)
-{
-    xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
-
-    return TRUE;
+    fail:
+    return FALSE;
 }
 
 static Bool
@@ -651,25 +520,24 @@ CreateScreenResources(ScreenPtr pScreen)
     PixmapPtr rootPixmap;
     Bool ret;
     int flags;
-
+    void *pixels;
     pScreen->CreateScreenResources = ms->createScreenResources;
     ret = pScreen->CreateScreenResources(pScreen);
     pScreen->CreateScreenResources = CreateScreenResources;
 
-    rootPixmap = pScreen->GetScreenPixmap(pScreen);
+    if (!drmmode_set_desired_modes(pScrn, &ms->drmmode))
+      return FALSE;
 
-    if (!pScreen->ModifyPixmapHeader(rootPixmap, -1, -1, -1, -1, -1, NULL))
-	FatalError("Couldn't adjust screen pixmap\n");
+    drmmode_uevent_init(pScrn, &ms->drmmode);
 
-    drmModeAddFB(ms->fd,
-		 pScrn->virtualX,
-		 pScrn->virtualY,
-		 pScrn->depth,
-		 pScrn->bitsPerPixel,
-		 pScrn->displayWidth * pScrn->bitsPerPixel / 8,
-		 driGetPixmapHandle(rootPixmap, &flags), &ms->fb_id);
+    drmmode_map_cursor_bos(pScrn, &ms->drmmode);
+    pixels = drmmode_map_front_bo(&ms->drmmode);
+    if (!pixels)
+	return FALSE;
 
-    AdjustFrame(pScrn->scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
+    rootPixmap = pScreen->GetScreenPixmap(pScreen);
+    if (!pScreen->ModifyPixmapHeader(rootPixmap, -1, -1, -1, -1, -1, pixels))
+	FatalError("Couldn't adjust screen pixmap\n");
 
     return ret;
 }
@@ -688,7 +556,7 @@ ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
     if (ms->fd < 0) {
 	char *BusID;
 
-	BusID = xalloc(64);
+	BusID = malloc(64);
 	sprintf(BusID, "PCI:%d:%d:%d",
 #if XSERVER_LIBPCIACCESS
 		((ms->PciInfo->domain << 8) | ms->PciInfo->bus),
@@ -710,6 +578,8 @@ ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
 
     /* HW dependent - FIXME */
     pScrn->displayWidth = pScrn->virtualX;
+    if (!drmmode_create_initial_bos(pScrn, &ms->drmmode))
+	return FALSE;
 
     miClearVisualTypes();
 
@@ -782,10 +652,6 @@ ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
     if (serverGeneration == 1)
 	xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
 
-#ifdef DRI2
-    driScreenInit(pScreen);
-#endif
-
     return EnterVT(scrnIndex, 1);
 }
 
@@ -822,7 +688,7 @@ LeaveVT(int scrnIndex, int flags)
     for (o = 0; o < config->num_crtc; o++) {
 	xf86CrtcPtr crtc = config->crtc[o];
 
-	cursor_destroy(crtc);
+	//	cursor_destroy(crtc);
 
 	if (crtc->rotatedPixmap || crtc->rotatedData) {
 	    crtc->funcs->shadow_destroy(crtc, crtc->rotatedPixmap,
@@ -834,16 +700,6 @@ LeaveVT(int scrnIndex, int flags)
 
     drmModeRmFB(ms->fd, ms->fb_id);
 
-    RestoreHWState(pScrn);
-
-#if 0
-    drmMMLock(ms->fd, DRM_BO_MEM_VRAM, 1, 0);
-    drmMMLock(ms->fd, DRM_BO_MEM_TT, 1, 0);
-#endif
-#ifdef DRI2
-    driLock(pScrn->pScreen);
-#endif
-
     pScrn->vtSema = FALSE;
 }
 
@@ -856,29 +712,6 @@ EnterVT(int scrnIndex, int flags)
     ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
     modesettingPtr ms = modesettingPTR(pScrn);
 
-#if 0
-    if (pScrn->vtSema) {
-	drmMMUnlock(ms->fd, DRM_BO_MEM_VRAM, 1);
-	drmMMUnlock(ms->fd, DRM_BO_MEM_TT, 1);
-    }
-#endif
-
-#ifdef DRI2
-    driUnlock(pScrn->pScreen);
-#endif
-
-    /*
-     * Only save state once per server generation since that's what most
-     * drivers do.  Could change this to save state at each VT enter.
-     */
-    if (ms->SaveGeneration != serverGeneration) {
-	ms->SaveGeneration = serverGeneration;
-	SaveHWState(pScrn);
-    }
-
-    if (!flags)			       /* signals startup as we'll do this in CreateScreenResources */
-	CreateFrontBuffer(pScrn);
-
     if (!xf86SetDesiredModes(pScrn))
 	return FALSE;
 
@@ -899,16 +732,13 @@ CloseScreen(int scrnIndex, ScreenPtr pScreen)
     ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
     modesettingPtr ms = modesettingPTR(pScrn);
 
+    drmmode_uevent_fini(pScrn, &ms->drmmode);
+
+    drmmode_free_bos(pScrn, &ms->drmmode);
+
     if (pScrn->vtSema) {
 	LeaveVT(scrnIndex, 0);
-#if 0
-	drmMMUnlock(ms->fd, DRM_BO_MEM_VRAM, 1);
-	drmMMUnlock(ms->fd, DRM_BO_MEM_TT, 1);
-#endif
     }
-#ifdef DRI2
-    driCloseScreen(pScreen);
-#endif
 
     pScreen->CreateScreenResources = ms->createScreenResources;
 
diff --git a/src/driver.h b/src/driver.h
index a673f8f..255dede 100644
--- a/src/driver.h
+++ b/src/driver.h
@@ -30,9 +30,8 @@
 #include <errno.h>
 #include <drm.h>
 #include <xf86drm.h>
-#include <xf86drmMode.h>
-#include <xf86mm.h>
 
+#include "drmmode_display.h"
 #define DRV_ERROR(msg)	xf86DrvMsg(pScrn->scrnIndex, X_ERROR, msg);
 
 typedef struct
@@ -72,10 +71,7 @@ typedef struct _modesettingRec
 
     void *driver;
 
-    /* dri2 */
-    drm_context_t context;
-    drm_hw_lock_t *lock;
-    int lock_held;
+    drmmode_rec drmmode;
 } modesettingRec, *modesettingPtr;
 
 #define modesettingPTR(p) ((modesettingPtr)((p)->driverPrivate))
diff --git a/src/drmmode_display.c b/src/drmmode_display.c
new file mode 100644
index 0000000..d94ce03
--- /dev/null
+++ b/src/drmmode_display.c
@@ -0,0 +1,1340 @@
+/*
+ * 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
+
+#include <errno.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include "xf86str.h"
+#include "X11/Xatom.h"
+#include "micmap.h"
+#include "xf86cmap.h"
+#include "xf86DDC.h"
+
+#include <xf86drm.h>
+#include "xf86Crtc.h"
+#include "drmmode_display.h"
+
+/* DPMS */
+#ifdef HAVE_XEXTPROTO_71
+#include <X11/extensions/dpmsconst.h>
+#else
+#define DPMS_SERVER
+#include <X11/extensions/dpms.h>
+#endif
+
+static struct dumb_bo *dumb_bo_create(int fd,
+			  const unsigned width, const unsigned height,
+			  const unsigned bpp)
+{
+	struct drm_mode_create_dumb arg;
+	struct dumb_bo *bo;
+	int ret;
+
+	bo = calloc(1, sizeof(*bo));
+	if (!bo)
+		return NULL;
+
+	memset(&arg, 0, sizeof(arg));
+	arg.width = width;
+	arg.height = height;
+	arg.bpp = bpp;
+	
+	ret = drmIoctl(fd, DRM_IOCTL_MODE_CREATE_DUMB, &arg);
+	if (ret)
+		goto err_free;
+
+	bo->handle = arg.handle;
+	bo->size = arg.size;
+	bo->pitch = arg.pitch;
+
+	return bo;
+ err_free:
+	free(bo);
+	return NULL;
+}
+
+static int dumb_bo_map(int fd, struct dumb_bo *bo)
+{
+	struct drm_mode_map_dumb arg;
+	int ret;
+	void *map;
+
+	if (bo->ptr) {
+		bo->map_count++;
+		return 0;
+	}
+
+	memset(&arg, 0, sizeof(arg));
+	arg.handle = bo->handle;
+
+	ret = drmIoctl(fd, DRM_IOCTL_MODE_MAP_DUMB, &arg);
+	if (ret)
+		return ret;
+
+	map = mmap(0, bo->size, PROT_READ | PROT_WRITE, MAP_SHARED,
+		   fd, arg.offset);
+	if (map == MAP_FAILED)
+		return -errno;
+
+	bo->ptr = map;
+	return 0;
+}
+
+static int dumb_bo_unmap(int fd, struct dumb_bo *bo)
+{
+	bo->map_count--;
+	return 0;
+}
+
+static int dumb_bo_destroy(int fd, struct dumb_bo *bo)
+{
+	struct drm_mode_destroy_dumb arg;
+	int ret;
+	
+	if (bo->ptr) {
+		munmap(bo->ptr, bo->size);
+		bo->ptr = NULL;
+	}
+
+	memset(&arg, 0, sizeof(arg));
+	arg.handle = bo->handle;
+	ret = drmIoctl(fd, DRM_IOCTL_MODE_DESTROY_DUMB, &arg);
+	if (ret)
+		return -errno;
+
+	free(bo);
+	return 0;
+}
+
+static void
+drmmode_ConvertFromKMode(ScrnInfoPtr	scrn,
+		     drmModeModeInfo *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,
+		     drmModeModeInfo *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 void
+drmmode_crtc_dpms(xf86CrtcPtr crtc, int mode)
+{
+#if 0
+	xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn);
+//	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
+//	drmmode_ptr drmmode = drmmode_crtc->drmmode;
+
+	/* bonghits in the randr 1.2 - uses dpms to disable crtc - bad buzz */
+	if (mode == DPMSModeOff) {
+//		drmModeSetCrtc(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id,
+//			       0, 0, 0, NULL, 0, NULL);
+	}
+#endif
+}
+
+#if 0
+static PixmapPtr
+create_pixmap_for_fbcon(drmmode_ptr drmmode,
+			ScrnInfoPtr pScrn, int crtc_id)
+{
+	xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+	drmmode_crtc_private_ptr drmmode_crtc;
+	ScreenPtr pScreen = pScrn->pScreen;
+	PixmapPtr pixmap;
+	struct radeon_bo *bo;
+	drmModeFBPtr fbcon;
+	struct drm_gem_flink flink;
+
+	drmmode_crtc = xf86_config->crtc[crtc_id]->driver_private;
+
+	fbcon = drmModeGetFB(drmmode->fd, drmmode_crtc->mode_crtc->buffer_id);
+	if (fbcon == NULL)
+		return NULL;
+
+	flink.handle = fbcon->handle;
+	if (ioctl(drmmode->fd, DRM_IOCTL_GEM_FLINK, &flink) < 0) {
+		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+			   "Couldn't flink fbcon handle\n");
+		return NULL;
+	}
+
+	bo = radeon_bo_open(drmmode->bufmgr, flink.name, 0, 0, 0, 0);
+	if (bo == NULL) {
+		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+			   "Couldn't allocate bo for fbcon handle\n");
+		return NULL;
+	}
+
+	pixmap = drmmode_create_bo_pixmap(pScreen, fbcon->width, fbcon->height,
+					  fbcon->depth, fbcon->bpp,
+					  fbcon->pitch, bo);
+	if (!pixmap) 
+		return NULL;
+
+	radeon_bo_unref(bo);
+	drmModeFreeFB(fbcon);
+	return pixmap;
+}
+
+#endif
+
+static Bool
+drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
+		     Rotation rotation, int x, int y)
+{
+	ScrnInfoPtr pScrn = crtc->scrn;
+	//	RADEONInfoPtr info = RADEONPTR(pScrn);
+	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;
+	Bool ret = TRUE;
+	int i;
+	int fb_id;
+	drmModeModeInfo kmode;
+	int pitch;
+	uint32_t tiling_flags = 0;
+	int height;
+
+	pitch = pScrn->displayWidth;
+	height = pScrn->virtualY;
+
+	if (drmmode->fb_id == 0) {
+		ret = drmModeAddFB(drmmode->fd,
+				   pScrn->virtualX, height,
+                                   pScrn->depth, pScrn->bitsPerPixel,
+				   drmmode->front_bo->pitch,
+				   drmmode->front_bo->handle,
+                                   &drmmode->fb_id);
+                if (ret < 0) {
+                        ErrorF("failed to add fb %d\n", ret);
+                        return FALSE;
+                }
+        }
+
+	saved_mode = crtc->mode;
+	saved_x = crtc->x;
+	saved_y = crtc->y;
+	saved_rotation = crtc->rotation;
+
+	if (mode) {
+		crtc->mode = *mode;
+		crtc->x = x;
+		crtc->y = y;
+		crtc->rotation = rotation;
+#if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,5,99,0,0)
+		crtc->transformPresent = FALSE;
+#endif
+	}
+
+	output_ids = calloc(sizeof(uint32_t), xf86_config->num_output);
+	if (!output_ids) {
+		ret = FALSE;
+		goto done;
+	}
+
+	if (mode) {
+		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)) {
+			goto done;
+		}
+#if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,7,0,0,0)
+		crtc->funcs->gamma_set(crtc, crtc->gamma_red, crtc->gamma_green,
+				       crtc->gamma_blue, crtc->gamma_size);
+#endif
+		
+		drmmode_ConvertToKMode(crtc->scrn, &kmode, mode);
+
+		fb_id = drmmode->fb_id;
+		if (drmmode_crtc->rotate_fb_id) {
+			fb_id = drmmode_crtc->rotate_fb_id;
+			x = y = 0;
+		}
+		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;
+
+		if (crtc->scrn->pScreen)
+			xf86CrtcSetScreenSubpixelOrder(crtc->scrn->pScreen);
+		/* go through all the outputs and force DPMS them back on? */
+		for (i = 0; i < xf86_config->num_output; i++) {
+			xf86OutputPtr output = xf86_config->output[i];
+
+			if (output->crtc != crtc)
+				continue;
+
+			output->funcs->dpms(output, DPMSModeOn);
+		}
+	}
+
+#if 0
+	if (pScrn->pScreen &&
+		!xf86ReturnOptValBool(info->Options, OPTION_SW_CURSOR, FALSE))
+		xf86_reload_cursors(pScrn->pScreen);
+#endif
+done:
+	if (!ret) {
+		crtc->x = saved_x;
+		crtc->y = saved_y;
+		crtc->rotation = saved_rotation;
+		crtc->mode = saved_mode;
+	}
+#if defined(XF86_CRTC_VERSION) && XF86_CRTC_VERSION >= 3
+	else
+		crtc->active = TRUE;
+#endif
+
+	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;
+	int i;
+	uint32_t *ptr;
+
+	/* cursor should be mapped already */
+	ptr = (uint32_t *)(drmmode_crtc->cursor_bo->ptr);
+
+	for (i = 0; i < 64 * 64; i++)
+		ptr[i] = image[i];// cpu_to_le32(image[i]);
+}
+
+
+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;
+	uint32_t handle = drmmode_crtc->cursor_bo->handle;
+
+	drmModeSetCursor(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, handle, 64, 64);
+}
+
+static void
+drmmode_crtc_gamma_set(xf86CrtcPtr crtc, uint16_t *red, uint16_t *green,
+                      uint16_t *blue, int size)
+{
+	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
+	drmmode_ptr drmmode = drmmode_crtc->drmmode;
+
+	drmModeCrtcSetGamma(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id,
+			    size, red, green, blue);
+}
+
+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,
+
+    .gamma_set = drmmode_crtc_gamma_set,
+    .destroy = NULL, /* XXX */
+};
+
+int drmmode_get_crtc_id(xf86CrtcPtr crtc)
+{
+	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
+	return drmmode_crtc->hw_id;
+}
+
+static void
+drmmode_crtc_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int num)
+{
+	xf86CrtcPtr crtc;
+	drmmode_crtc_private_ptr drmmode_crtc;
+
+	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;
+}
+
+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;
+	xf86MonPtr mon = NULL;
+
+	/* 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) {
+		mon = xf86InterpretEDID(output->scrn->scrnIndex,
+					drmmode_output->edid_blob->data);
+		if (mon && drmmode_output->edid_blob->length > 128)
+			mon->flags |= MONITOR_EDID_COMPLETE_RAWDATA;
+	}
+	xf86OutputSetEDID(output, mon);
+
+	/* 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;
+	int i;
+
+	if (drmmode_output->edid_blob)
+		drmModeFreePropertyBlob(drmmode_output->edid_blob);
+	for (i = 0; i < drmmode_output->num_props; i++) {
+		drmModeFreeProperty(drmmode_output->props[i].mode_prop);
+		free(drmmode_output->props[i].atoms);
+	}
+	for (i = 0; i < drmmode_output->mode_output->count_encoders; i++) {
+		drmModeFreeEncoder(drmmode_output->mode_encoders[i]);
+		free(drmmode_output->mode_encoders);
+	}
+	free(drmmode_output->props);
+	drmModeFreeConnector(drmmode_output->mode_output);
+	free(drmmode_output);
+	output->driver_private = NULL;
+}
+
+static void
+drmmode_output_dpms(xf86OutputPtr output, int mode)
+{
+	drmmode_output_private_ptr drmmode_output = output->driver_private;
+	drmModeConnectorPtr koutput = drmmode_output->mode_output;
+	drmmode_ptr drmmode = drmmode_output->drmmode;
+
+	drmModeConnectorSetProperty(drmmode->fd, koutput->connector_id,
+				    drmmode_output->dpms_enum_id, mode);
+	return;
+}
+
+
+static Bool
+drmmode_property_ignore(drmModePropertyPtr prop)
+{
+    if (!prop)
+	return TRUE;
+    /* ignore blob prop */
+    if (prop->flags & DRM_MODE_PROP_BLOB)
+	return TRUE;
+    /* ignore standard property */
+    if (!strcmp(prop->name, "EDID") ||
+	    !strcmp(prop->name, "DPMS"))
+	return TRUE;
+
+    return FALSE;
+}
+
+static void
+drmmode_output_create_resources(xf86OutputPtr output)
+{
+    drmmode_output_private_ptr drmmode_output = output->driver_private;
+    drmModeConnectorPtr mode_output = drmmode_output->mode_output;
+    drmmode_ptr drmmode = drmmode_output->drmmode;
+    drmModePropertyPtr drmmode_prop;
+    int i, j, err;
+
+    drmmode_output->props = calloc(mode_output->count_props, sizeof(drmmode_prop_rec));
+    if (!drmmode_output->props)
+	return;
+    
+    drmmode_output->num_props = 0;
+    for (i = 0, j = 0; i < mode_output->count_props; i++) {
+	drmmode_prop = drmModeGetProperty(drmmode->fd, mode_output->props[i]);
+	if (drmmode_property_ignore(drmmode_prop)) {
+	    drmModeFreeProperty(drmmode_prop);
+	    continue;
+	}
+	drmmode_output->props[j].mode_prop = drmmode_prop;
+	drmmode_output->props[j].value = mode_output->prop_values[i];
+	drmmode_output->num_props++;
+	j++;
+    }
+
+    for (i = 0; i < drmmode_output->num_props; i++) {
+	drmmode_prop_ptr p = &drmmode_output->props[i];
+	drmmode_prop = p->mode_prop;
+
+	if (drmmode_prop->flags & DRM_MODE_PROP_RANGE) {
+	    INT32 range[2];
+	    INT32 value = p->value;
+
+	    p->num_atoms = 1;
+	    p->atoms = calloc(p->num_atoms, sizeof(Atom));
+	    if (!p->atoms)
+		continue;
+	    p->atoms[0] = MakeAtom(drmmode_prop->name, strlen(drmmode_prop->name), TRUE);
+	    range[0] = drmmode_prop->values[0];
+	    range[1] = drmmode_prop->values[1];
+	    err = RRConfigureOutputProperty(output->randr_output, p->atoms[0],
+		    FALSE, TRUE,
+		    drmmode_prop->flags & DRM_MODE_PROP_IMMUTABLE ? TRUE : FALSE,
+		    2, range);
+	    if (err != 0) {
+		xf86DrvMsg(output->scrn->scrnIndex, X_ERROR,
+			"RRConfigureOutputProperty error, %d\n", err);
+	    }
+	    err = RRChangeOutputProperty(output->randr_output, p->atoms[0],
+		    XA_INTEGER, 32, PropModeReplace, 1, &value, FALSE, TRUE);
+	    if (err != 0) {
+		xf86DrvMsg(output->scrn->scrnIndex, X_ERROR,
+			"RRChangeOutputProperty error, %d\n", err);
+	    }
+	} else if (drmmode_prop->flags & DRM_MODE_PROP_ENUM) {
+	    p->num_atoms = drmmode_prop->count_enums + 1;
+	    p->atoms = calloc(p->num_atoms, sizeof(Atom));
+	    if (!p->atoms)
+		continue;
+	    p->atoms[0] = MakeAtom(drmmode_prop->name, strlen(drmmode_prop->name), TRUE);
+	    for (j = 1; j <= drmmode_prop->count_enums; j++) {
+		struct drm_mode_property_enum *e = &drmmode_prop->enums[j-1];
+		p->atoms[j] = MakeAtom(e->name, strlen(e->name), TRUE);
+	    }
+	    err = RRConfigureOutputProperty(output->randr_output, p->atoms[0],
+		    FALSE, FALSE,
+		    drmmode_prop->flags & DRM_MODE_PROP_IMMUTABLE ? TRUE : FALSE,
+		    p->num_atoms - 1, (INT32 *)&p->atoms[1]);
+	    if (err != 0) {
+		xf86DrvMsg(output->scrn->scrnIndex, X_ERROR,
+			"RRConfigureOutputProperty error, %d\n", err);
+	    }
+	    for (j = 0; j < drmmode_prop->count_enums; j++)
+		if (drmmode_prop->enums[j].value == p->value)
+		    break;
+	    /* there's always a matching value */
+	    err = RRChangeOutputProperty(output->randr_output, p->atoms[0],
+		    XA_ATOM, 32, PropModeReplace, 1, &p->atoms[j+1], FALSE, TRUE);
+	    if (err != 0) {
+		xf86DrvMsg(output->scrn->scrnIndex, X_ERROR,
+			"RRChangeOutputProperty error, %d\n", err);
+	    }
+	}
+    }
+}
+
+static Bool
+drmmode_output_set_property(xf86OutputPtr output, Atom property,
+		RRPropertyValuePtr value)
+{
+    drmmode_output_private_ptr drmmode_output = output->driver_private;
+    drmmode_ptr drmmode = drmmode_output->drmmode;
+    int i;
+
+    for (i = 0; i < drmmode_output->num_props; i++) {
+	drmmode_prop_ptr p = &drmmode_output->props[i];
+
+	if (p->atoms[0] != property)
+	    continue;
+
+	if (p->mode_prop->flags & DRM_MODE_PROP_RANGE) {
+	    uint32_t val;
+
+	    if (value->type != XA_INTEGER || value->format != 32 ||
+		    value->size != 1)
+		return FALSE;
+	    val = *(uint32_t *)value->data;
+
+	    drmModeConnectorSetProperty(drmmode->fd, drmmode_output->output_id,
+		    p->mode_prop->prop_id, (uint64_t)val);
+	    return TRUE;
+	} else if (p->mode_prop->flags & DRM_MODE_PROP_ENUM) {
+	    Atom	atom;
+	    const char	*name;
+	    int		j;
+
+	    if (value->type != XA_ATOM || value->format != 32 || value->size != 1)
+		return FALSE;
+	    memcpy(&atom, value->data, 4);
+	    name = NameForAtom(atom);
+
+	    /* search for matching name string, then set its value down */
+	    for (j = 0; j < p->mode_prop->count_enums; j++) {
+		if (!strcmp(p->mode_prop->enums[j].name, name)) {
+		    drmModeConnectorSetProperty(drmmode->fd, drmmode_output->output_id,
+			    p->mode_prop->prop_id, p->mode_prop->enums[j].value);
+		    return TRUE;
+		}
+	    }
+	}
+    }
+
+    return TRUE;
+}
+
+static Bool
+drmmode_output_get_property(xf86OutputPtr output, Atom property)
+{
+    return TRUE;
+}
+
+static const xf86OutputFuncsRec drmmode_output_funcs = {
+    .dpms = drmmode_output_dpms,
+    .create_resources = drmmode_output_create_resources,
+#ifdef RANDR_12_INTERFACE
+    .set_property = drmmode_output_set_property,
+    .get_property = drmmode_output_get_property,
+#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",
+			       "S-video",
+			       "LVDS",
+			       "CTV",
+			       "DIN",
+			       "DisplayPort",
+			       "HDMI",
+			       "HDMI",
+			       "TV",
+			       "eDP"
+};
+
+static void
+drmmode_output_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int num, int *num_dvi, int *num_hdmi)
+{
+	xf86OutputPtr output;
+	drmModeConnectorPtr koutput;
+	drmModeEncoderPtr *kencoders = NULL;
+	drmmode_output_private_ptr drmmode_output;
+	drmModePropertyPtr props;
+	char name[32];
+	int i;
+	const char *s;
+
+	koutput = drmModeGetConnector(drmmode->fd, drmmode->mode_res->connectors[num]);
+	if (!koutput)
+		return;
+
+	kencoders = calloc(sizeof(drmModeEncoderPtr), koutput->count_encoders);
+	if (!kencoders) {
+		goto out_free_encoders;
+	}
+
+	for (i = 0; i < koutput->count_encoders; i++) {
+		kencoders[i] = drmModeGetEncoder(drmmode->fd, koutput->encoders[i]);
+		if (!kencoders[i]) {
+			goto out_free_encoders;
+		}
+	}
+
+	/* need to do smart conversion here for compat with non-kms ATI driver */
+	snprintf(name, 32, "%s-%d", output_names[koutput->connector_type], koutput->connector_type_id - 1);
+
+	output = xf86OutputCreate (pScrn, &drmmode_output_funcs, name);
+	if (!output) {
+		goto out_free_encoders;
+	}
+
+	drmmode_output = calloc(sizeof(drmmode_output_private_rec), 1);
+	if (!drmmode_output) {
+		xf86OutputDestroy(output);
+		goto out_free_encoders;
+	}
+
+	drmmode_output->output_id = drmmode->mode_res->connectors[num];
+	drmmode_output->mode_output = koutput;
+	drmmode_output->mode_encoders = kencoders;
+	drmmode_output->drmmode = drmmode;
+	output->mm_width = koutput->mmWidth;
+	output->mm_height = koutput->mmHeight;
+
+	output->subpixel_order = subpixel_conv_table[koutput->subpixel];
+	output->interlaceAllowed = TRUE;
+	output->doubleScanAllowed = TRUE;
+	output->driver_private = drmmode_output;
+	
+	output->possible_crtcs = 0x7f;
+	for (i = 0; i < koutput->count_encoders; i++) {
+		output->possible_crtcs &= kencoders[i]->possible_crtcs;
+	}
+	/* work out the possible clones later */
+	output->possible_clones = 0;
+
+	for (i = 0; i < koutput->count_props; i++) {
+		props = drmModeGetProperty(drmmode->fd, koutput->props[i]);
+		if (props && (props->flags & DRM_MODE_PROP_ENUM)) {
+			if (!strcmp(props->name, "DPMS")) {
+				drmmode_output->dpms_enum_id = koutput->props[i];
+				drmModeFreeProperty(props);
+				break;
+			}
+			drmModeFreeProperty(props);
+		}
+	}
+
+	return;
+out_free_encoders:
+	if (kencoders){
+		for (i = 0; i < koutput->count_encoders; i++)
+			drmModeFreeEncoder(kencoders[i]);
+		free(kencoders);
+	}
+	drmModeFreeConnector(koutput);
+	
+}
+
+uint32_t find_clones(ScrnInfoPtr scrn, xf86OutputPtr output)
+{
+	drmmode_output_private_ptr drmmode_output = output->driver_private, clone_drmout;
+	int i;
+	xf86OutputPtr clone_output;
+	xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
+	int index_mask = 0;
+
+	if (drmmode_output->enc_clone_mask == 0)
+		return index_mask;
+
+	for (i = 0; i < xf86_config->num_output; i++) {
+		clone_output = xf86_config->output[i];
+		clone_drmout = clone_output->driver_private;
+		if (output == clone_output)
+			continue;
+		
+		if (clone_drmout->enc_mask == 0)
+			continue;
+		if (drmmode_output->enc_clone_mask == clone_drmout->enc_mask)
+			index_mask |= (1 << i);
+	}
+	return index_mask;
+}
+
+
+static void
+drmmode_clones_init(ScrnInfoPtr scrn, drmmode_ptr drmmode)
+{
+	int i, j;
+	xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
+
+	for (i = 0; i < xf86_config->num_output; i++) {
+		xf86OutputPtr output = xf86_config->output[i];
+		drmmode_output_private_ptr drmmode_output;
+
+		drmmode_output = output->driver_private;
+		drmmode_output->enc_clone_mask = 0xff;
+		/* and all the possible encoder clones for this output together */
+		for (j = 0; j < drmmode_output->mode_output->count_encoders; j++)
+		{
+			int k;
+			for (k = 0; k < drmmode->mode_res->count_encoders; k++) {
+				if (drmmode->mode_res->encoders[k] == drmmode_output->mode_encoders[j]->encoder_id)
+					drmmode_output->enc_mask |= (1 << k);
+			}
+
+			drmmode_output->enc_clone_mask &= drmmode_output->mode_encoders[j]->possible_clones;
+		}
+	}
+
+	for (i = 0; i < xf86_config->num_output; i++) {
+		xf86OutputPtr output = xf86_config->output[i];
+		output->possible_clones = find_clones(scrn, output);
+	}
+}
+
+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;
+	struct dumb_bo *old_front = NULL;
+	Bool	    ret;
+	ScreenPtr   screen = screenInfo.screens[scrn->scrnIndex];
+	uint32_t    old_fb_id;
+	int	    i, pitch, old_width, old_height, old_pitch;
+	int screen_size;
+	int cpp = (scrn->bitsPerPixel + 1) / 8;
+	struct dumb_bo *front_bo;
+	uint32_t tiling_flags = 0;
+	PixmapPtr ppix = screen->GetScreenPixmap(screen);
+	void *new_pixels;
+
+	if (scrn->virtualX == width && scrn->virtualY == height)
+		return TRUE;
+
+	xf86DrvMsg(scrn->scrnIndex, X_INFO,
+		   "Allocate new frame buffer %dx%d stride %d\n",
+		   width, height, pitch / cpp);
+
+	old_width = scrn->virtualX;
+	old_height = scrn->virtualY;
+	old_pitch = scrn->displayWidth;
+	old_fb_id = drmmode->fb_id;
+	old_front = drmmode->front_bo;
+
+	drmmode->front_bo = dumb_bo_create(drmmode->fd, width, height, scrn->bitsPerPixel);
+	if (!drmmode->front_bo)
+		goto fail;
+
+	pitch = drmmode->front_bo->pitch;
+
+	scrn->virtualX = width;
+	scrn->virtualY = height;
+	scrn->displayWidth = pitch / cpp;
+
+	ret = drmModeAddFB(drmmode->fd, width, height, scrn->depth,
+			   scrn->bitsPerPixel, pitch,
+			   drmmode->front_bo->handle,
+			   &drmmode->fb_id);
+	if (ret)
+		goto fail;
+	
+	new_pixels  = drmmode_map_front_bo(drmmode);
+	if (!new_pixels)
+		goto fail;
+
+	screen->ModifyPixmapHeader(ppix, width, height, -1, -1,
+				   pitch, new_pixels);
+
+#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1,9,99,1,0)
+	scrn->pixmapPrivate.ptr = ppix->devPrivate.ptr;
+#endif
+
+	for (i = 0; i < xf86_config->num_crtc; i++) {
+		xf86CrtcPtr crtc = xf86_config->crtc[i];
+
+		if (!crtc->enabled)
+			continue;
+
+		drmmode_set_mode_major(crtc, &crtc->mode,
+				       crtc->rotation, crtc->x, crtc->y);
+	}
+
+	if (old_fb_id) {
+		drmModeRmFB(drmmode->fd, old_fb_id);
+		dumb_bo_destroy(drmmode->fd, old_front);
+	}
+
+	return TRUE;
+
+ fail:
+	if (drmmode->front_bo)
+		dumb_bo_destroy(drmmode->fd, drmmode->front_bo);
+	drmmode->front_bo = old_front;
+	scrn->virtualX = old_width;
+	scrn->virtualY = old_height;
+	scrn->displayWidth = old_pitch;
+	drmmode->fb_id = old_fb_id;
+
+	return FALSE;
+}
+
+static const xf86CrtcConfigFuncsRec drmmode_xf86crtc_config_funcs = {
+	drmmode_xf86crtc_resize
+};
+
+Bool drmmode_pre_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int cpp)
+{
+	xf86CrtcConfigPtr xf86_config;
+	int i, num_dvi = 0, num_hdmi = 0;
+
+	xf86CrtcConfigInit(pScrn, &drmmode_xf86crtc_config_funcs);
+	xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+
+	drmmode->scrn = 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++)
+		if (!xf86IsEntityShared(pScrn->entityList[0]) || pScrn->confScreen->device->screen == i)
+			drmmode_crtc_init(pScrn, drmmode, i);
+
+	for (i = 0; i < drmmode->mode_res->count_connectors; i++)
+		drmmode_output_init(pScrn, drmmode, i, &num_dvi, &num_hdmi);
+
+	/* workout clones */
+	drmmode_clones_init(pScrn, drmmode);
+
+	xf86InitialConfiguration(pScrn, TRUE);
+
+	return TRUE;
+}
+
+void drmmode_set_cursor(ScrnInfoPtr scrn, drmmode_ptr drmmode, int id, struct dumb_bo *bo)
+{
+	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_bo = bo;
+}
+
+void drmmode_adjust_frame(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int x, int y, int flags)
+{
+	xf86CrtcConfigPtr	config = XF86_CRTC_CONFIG_PTR(pScrn);
+	xf86OutputPtr  output = config->output[config->compat_output];
+	xf86CrtcPtr	crtc = output->crtc;
+
+	if (crtc && crtc->enabled) {
+		drmmode_set_mode_major(crtc, &crtc->mode, crtc->rotation,
+				       x, y);
+	}
+}
+
+Bool drmmode_set_desired_modes(ScrnInfoPtr pScrn, drmmode_ptr drmmode)
+{
+	xf86CrtcConfigPtr   config = XF86_CRTC_CONFIG_PTR(pScrn);
+	int c;
+
+	for (c = 0; c < config->num_crtc; c++) {
+		xf86CrtcPtr	crtc = config->crtc[c];
+		drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
+		xf86OutputPtr	output = NULL;
+		int		o;
+
+		/* Skip disabled CRTCs */
+		if (!crtc->enabled) {
+			drmModeSetCrtc(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id,
+				       0, 0, 0, NULL, 0, NULL);
+			continue;
+		}
+
+		if (config->output[config->compat_output]->crtc == crtc)
+			output = config->output[config->compat_output];
+		else
+		{
+			for (o = 0; o < config->num_output; o++)
+				if (config->output[o]->crtc == crtc)
+				{
+					output = config->output[o];
+					break;
+				}
+		}
+		/* paranoia */
+		if (!output)
+			continue;
+
+		/* Mark that we'll need to re-set the mode for sure */
+		memset(&crtc->mode, 0, sizeof(crtc->mode));
+		if (!crtc->desiredMode.CrtcHDisplay)
+		{
+			DisplayModePtr  mode = xf86OutputFindClosestMode (output, pScrn->currentMode);
+
+			if (!mode)
+				return FALSE;
+			crtc->desiredMode = *mode;
+			crtc->desiredRotation = RR_Rotate_0;
+			crtc->desiredX = 0;
+			crtc->desiredY = 0;
+		}
+
+		if (!crtc->funcs->set_mode_major(crtc, &crtc->desiredMode, crtc->desiredRotation,
+						 crtc->desiredX, crtc->desiredY))
+			return FALSE;
+	}
+	return TRUE;
+}
+
+static void drmmode_load_palette(ScrnInfoPtr pScrn, int numColors,
+                                 int *indices, LOCO *colors, VisualPtr pVisual)
+{
+    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+    uint16_t       lut_r[256], lut_g[256], lut_b[256];
+    int index, j, i;
+    int c;
+
+    for (c = 0; c < xf86_config->num_crtc; c++) {
+        xf86CrtcPtr crtc = xf86_config->crtc[c];
+	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
+
+        for (i = 0 ; i < 256; i++) {
+            lut_r[i] = drmmode_crtc->lut_r[i] << 6;
+            lut_g[i] = drmmode_crtc->lut_g[i] << 6;
+            lut_b[i] = drmmode_crtc->lut_b[i] << 6;
+        }
+
+        switch(pScrn->depth) {
+        case 15:
+            for (i = 0; i < numColors; i++) {
+                index = indices[i];
+                for (j = 0; j < 8; j++) {
+                    lut_r[index * 8 + j] = colors[index].red << 6;
+                    lut_g[index * 8 + j] = colors[index].green << 6;
+                    lut_b[index * 8 + j] = colors[index].blue << 6;
+                }
+            }
+         break;
+         case 16:
+             for (i = 0; i < numColors; i++) {
+                 index = indices[i];
+
+                  if (i <= 31) {
+                      for (j = 0; j < 8; j++) {
+                          lut_r[index * 8 + j] = colors[index].red << 6;
+                          lut_b[index * 8 + j] = colors[index].blue << 6;
+                      }
+                  }
+
+                  for (j = 0; j < 4; j++) {
+                      lut_g[index * 4 + j] = colors[index].green << 6;
+                  }
+              }
+	  break;
+          default:
+              for (i = 0; i < numColors; i++) {
+                  index = indices[i];
+                  lut_r[index] = colors[index].red << 6;
+                  lut_g[index] = colors[index].green << 6;
+                  lut_b[index] = colors[index].blue << 6;
+              }
+              break;
+          }
+
+    /* Make the change through RandR */
+#ifdef RANDR_12_INTERFACE
+        if (crtc->randr_crtc)
+            RRCrtcGammaSet(crtc->randr_crtc, lut_r, lut_g, lut_b);
+        else
+#endif
+            crtc->funcs->gamma_set(crtc, lut_r, lut_g, lut_b, 256);
+     }
+}
+
+Bool drmmode_setup_colormap(ScreenPtr pScreen, ScrnInfoPtr pScrn)
+{
+    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 0,
+                  "Initializing kms color map\n");
+    if (!miCreateDefColormap(pScreen))
+        return FALSE;
+    /* all radeons support 10 bit CLUTs */
+    if (!xf86HandleColormaps(pScreen, 256, 10,
+                             drmmode_load_palette, NULL,
+                             CMAP_PALETTED_TRUECOLOR
+#if 0 /* This option messes up text mode! (eich at suse.de) */
+                             | CMAP_LOAD_EVEN_IF_OFFSCREEN
+#endif
+                             | CMAP_RELOAD_ON_MODE_SWITCH))
+         return FALSE;
+    return TRUE;
+}
+
+#ifdef HAVE_UDEV
+static void
+drmmode_handle_uevents(int fd, void *closure)
+{
+	drmmode_ptr drmmode = closure;
+	ScrnInfoPtr scrn = drmmode->scrn;
+	struct udev_device *dev;
+	dev = udev_monitor_receive_device(drmmode->uevent_monitor);
+	if (!dev)
+		return;
+
+	RRGetInfo(screenInfo.screens[scrn->scrnIndex], TRUE);
+	udev_device_unref(dev);
+}
+#endif
+
+void drmmode_uevent_init(ScrnInfoPtr scrn, drmmode_ptr drmmode)
+{
+#ifdef HAVE_UDEV
+	struct udev *u;
+	struct udev_monitor *mon;
+
+	u = udev_new();
+	if (!u)
+		return;
+	mon = udev_monitor_new_from_netlink(u, "udev");
+	if (!mon) {
+		udev_unref(u);
+		return;
+	}
+
+	if (udev_monitor_filter_add_match_subsystem_devtype(mon,
+							    "drm",
+							    "drm_minor") < 0 ||
+	    udev_monitor_enable_receiving(mon) < 0) {
+		udev_monitor_unref(mon);
+		udev_unref(u);
+		return;
+	}
+
+	drmmode->uevent_handler =
+		xf86AddGeneralHandler(udev_monitor_get_fd(mon),
+				      drmmode_handle_uevents,
+				      drmmode);
+
+	drmmode->uevent_monitor = mon;
+#endif
+}
+
+void drmmode_uevent_fini(ScrnInfoPtr scrn, drmmode_ptr drmmode)
+{
+#ifdef HAVE_UDEV
+	if (drmmode->uevent_handler) {
+		struct udev *u = udev_monitor_get_udev(drmmode->uevent_monitor);
+		xf86RemoveGeneralHandler(drmmode->uevent_handler);
+
+		udev_monitor_unref(drmmode->uevent_monitor);
+		udev_unref(u);
+	}
+#endif
+}
+
+/* create front and cursor BOs */
+Bool drmmode_create_initial_bos(ScrnInfoPtr pScrn, drmmode_ptr drmmode)
+{
+	xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+	int width;
+	int height;
+	int bpp;
+	int i;
+
+	width = pScrn->virtualX;
+	height = pScrn->virtualY;
+	bpp = pScrn->bitsPerPixel;
+	drmmode->front_bo = dumb_bo_create(drmmode->fd, width, height, bpp);
+	if (!drmmode->front_bo)
+		return FALSE;
+
+
+	width = height = 64;
+	bpp = 32;
+	for (i = 0; i < xf86_config->num_crtc; i++) {
+		xf86CrtcPtr crtc = xf86_config->crtc[i];
+		drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
+		drmmode_crtc->cursor_bo = dumb_bo_create(drmmode->fd, width, height, bpp);
+	}
+	return TRUE;
+}
+
+void *drmmode_map_front_bo(drmmode_ptr drmmode)
+{
+	int ret;
+
+	if (drmmode->front_bo->ptr)
+		return drmmode->front_bo->ptr;
+
+	ret = dumb_bo_map(drmmode->fd, drmmode->front_bo);
+	if (ret)
+		return NULL;
+
+	return drmmode->front_bo->ptr;
+	
+}
+
+Bool drmmode_map_cursor_bos(ScrnInfoPtr pScrn, drmmode_ptr drmmode)
+{
+	xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+	int i, ret;
+	for (i = 0; i < xf86_config->num_crtc; i++) {
+		xf86CrtcPtr crtc = xf86_config->crtc[i];
+		drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
+		ret = dumb_bo_map(drmmode->fd, drmmode_crtc->cursor_bo);
+		if (ret)
+			return FALSE;
+	}
+	return TRUE;
+}
+
+void drmmode_free_bos(ScrnInfoPtr pScrn, drmmode_ptr drmmode)
+{
+	xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+	int i;
+	dumb_bo_destroy(drmmode->fd, drmmode->front_bo);
+	drmmode->front_bo = NULL;
+
+	for (i = 0; i < xf86_config->num_crtc; i++) {
+		xf86CrtcPtr crtc = xf86_config->crtc[i];
+		drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
+		dumb_bo_destroy(drmmode->fd, drmmode_crtc->cursor_bo);
+	}
+}
diff --git a/src/drmmode_display.h b/src/drmmode_display.h
new file mode 100644
index 0000000..2d72505
--- /dev/null
+++ b/src/drmmode_display.h
@@ -0,0 +1,125 @@
+/*
+ * 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
+
+#include "xf86drmMode.h"
+#ifdef HAVE_UDEV
+#include "libudev.h"
+#endif
+
+struct dumb_bo {
+  uint32_t handle;
+  uint32_t size;
+  void *ptr;
+  int map_count;
+  uint32_t pitch;
+};
+
+typedef struct {
+  int fd;
+  unsigned fb_id;
+  drmModeResPtr mode_res;
+  drmModeFBPtr mode_fb;
+  int cpp;
+  ScrnInfoPtr scrn;
+#ifdef HAVE_UDEV
+  struct udev_monitor *uevent_monitor;
+  InputHandlerProc uevent_handler;
+#endif
+  drmEventContext event_context;
+  struct dumb_bo *front_bo;
+} drmmode_rec, *drmmode_ptr;
+
+typedef struct {
+  drmmode_ptr drmmode;
+  unsigned old_fb_id;
+  int flip_count;
+  void *event_data;
+  unsigned int fe_frame;
+  unsigned int fe_tv_sec;
+  unsigned int fe_tv_usec;
+} drmmode_flipdata_rec, *drmmode_flipdata_ptr;
+
+typedef struct {
+  drmmode_flipdata_ptr flipdata;
+  Bool dispatch_me;
+} drmmode_flipevtcarrier_rec, *drmmode_flipevtcarrier_ptr;
+
+typedef struct {
+    drmmode_ptr drmmode;
+    drmModeCrtcPtr mode_crtc;
+    int hw_id;
+    struct dumb_bo *cursor_bo;
+  //    struct radeon_bo *rotate_bo;
+    unsigned rotate_fb_id;
+    uint16_t lut_r[256], lut_g[256], lut_b[256];
+} drmmode_crtc_private_rec, *drmmode_crtc_private_ptr;
+
+typedef struct {
+    drmModePropertyPtr mode_prop;
+    uint64_t value;
+    int num_atoms; /* if range prop, num_atoms == 1; if enum prop, num_atoms == num_enums + 1 */
+    Atom *atoms;
+} drmmode_prop_rec, *drmmode_prop_ptr;
+
+
+typedef struct {
+    drmmode_ptr drmmode;
+    int output_id;
+    drmModeConnectorPtr mode_output;
+    drmModeEncoderPtr *mode_encoders;
+    drmModePropertyBlobPtr edid_blob;
+    int dpms_enum_id;
+    int num_props;
+    drmmode_prop_ptr props;
+    int enc_mask;
+    int enc_clone_mask;
+} drmmode_output_private_rec, *drmmode_output_private_ptr;
+
+
+extern Bool drmmode_pre_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int cpp);
+//extern Bool drmmode_set_bufmgr(ScrnInfoPtr pScrn, drmmode_ptr drmmode, struct radeon_bo_manager *bufmgr);
+//extern void drmmode_set_cursor(ScrnInfoPtr scrn, drmmode_ptr drmmode, int id, struct radeon_bo *bo);
+void drmmode_adjust_frame(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int x, int y, int flags);
+extern Bool drmmode_set_desired_modes(ScrnInfoPtr pScrn, drmmode_ptr drmmode);
+extern void drmmode_copy_fb(ScrnInfoPtr pScrn, drmmode_ptr drmmode);
+extern Bool drmmode_setup_colormap(ScreenPtr pScreen, ScrnInfoPtr pScrn);
+
+extern void drmmode_uevent_init(ScrnInfoPtr scrn, drmmode_ptr drmmode);
+extern void drmmode_uevent_fini(ScrnInfoPtr scrn, drmmode_ptr drmmode);
+
+extern int drmmode_get_height_align(ScrnInfoPtr scrn, uint32_t tiling);
+extern int drmmode_get_pitch_align(ScrnInfoPtr scrn, int bpe, uint32_t tiling);
+extern int drmmode_get_base_align(ScrnInfoPtr scrn, int bpe, uint32_t tiling);
+
+//Bool radeon_do_pageflip(ScrnInfoPtr scrn, struct radeon_bo *new_front, void *data, int ref_crtc_hw_id);
+Bool drmmode_create_initial_bos(ScrnInfoPtr pScrn, drmmode_ptr drmmode);
+void *drmmode_map_front_bo(drmmode_ptr drmmode);
+Bool drmmode_map_cursor_bos(ScrnInfoPtr pScrn, drmmode_ptr drmmode);
+void drmmode_free_bos(ScrnInfoPtr pScrn, drmmode_ptr drmmode);
+#endif
diff --git a/src/output.c b/src/output.c
deleted file mode 100644
index 1f95a2f..0000000
--- a/src/output.c
+++ /dev/null
@@ -1,292 +0,0 @@
-/*
- * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- *
- * 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, sub license, 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 NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS 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.
- *
- *
- * Author: Alan Hourihane <alanh at tungstengraphics.com>
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <xf86.h>
-#include <xf86i2c.h>
-#include <xf86Crtc.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-
-#define DPMS_SERVER
-#include <X11/extensions/dpms.h>
-
-#include "X11/Xatom.h"
-
-#include "driver.h"
-
-static char *connector_enum_list[] = {
-    "Unknown",
-    "VGA",
-    "DVI-I",
-    "DVI-D",
-    "DVI-A",
-    "Composite",
-    "SVIDEO",
-    "LVDS",
-    "Component",
-    "9-pin DIN",
-    "DisplayPort",
-    "HDMI Type A",
-    "HDMI Type B",
-};
-
-static void
-dpms(xf86OutputPtr output, int mode)
-{
-}
-
-static void
-save(xf86OutputPtr output)
-{
-}
-
-static void
-restore(xf86OutputPtr output)
-{
-}
-
-static int
-mode_valid(xf86OutputPtr output, DisplayModePtr pMode)
-{
-    return MODE_OK;
-}
-
-static Bool
-mode_fixup(xf86OutputPtr output, DisplayModePtr mode,
-	   DisplayModePtr adjusted_mode)
-{
-    return TRUE;
-}
-
-static void
-prepare(xf86OutputPtr output)
-{
-    dpms(output, DPMSModeOff);
-}
-
-static void
-mode_set(xf86OutputPtr output, DisplayModePtr mode,
-	 DisplayModePtr adjusted_mode)
-{
-}
-
-static void
-commit(xf86OutputPtr output)
-{
-    dpms(output, DPMSModeOn);
-
-    if (output->scrn->pScreen != NULL)
-	xf86_reload_cursors(output->scrn->pScreen);
-}
-
-static xf86OutputStatus
-detect(xf86OutputPtr output)
-{
-    drmModeConnectorPtr drm_connector = output->driver_private;
-
-    switch (drm_connector->connection) {
-    case DRM_MODE_CONNECTED:
-	return XF86OutputStatusConnected;
-    case DRM_MODE_DISCONNECTED:
-	return XF86OutputStatusDisconnected;
-    default:
-	return XF86OutputStatusUnknown;
-    }
-}
-
-static DisplayModePtr
-get_modes(xf86OutputPtr output)
-{
-    drmModeConnectorPtr drm_connector = output->driver_private;
-    struct drm_mode_modeinfo *drm_mode = NULL;
-    DisplayModePtr modes = NULL, mode = NULL;
-    int i;
-
-    for (i = 0; i < drm_connector->count_modes; i++) {
-	drm_mode = &drm_connector->modes[i];
-	if (drm_mode) {
-	    mode = xcalloc(1, sizeof(DisplayModeRec));
-	    if (!mode)
-		continue;
-	    mode->type = 0;
-	    mode->Clock = drm_mode->clock;
-	    mode->HDisplay = drm_mode->hdisplay;
-	    mode->HSyncStart = drm_mode->hsync_start;
-	    mode->HSyncEnd = drm_mode->hsync_end;
-	    mode->HTotal = drm_mode->htotal;
-	    mode->VDisplay = drm_mode->vdisplay;
-	    mode->VSyncStart = drm_mode->vsync_start;
-	    mode->VSyncEnd = drm_mode->vsync_end;
-	    mode->VTotal = drm_mode->vtotal;
-	    mode->Flags = drm_mode->flags;
-	    mode->HSkew = drm_mode->hskew;
-	    mode->VScan = drm_mode->vscan;
-	    mode->VRefresh = xf86ModeVRefresh(mode);
-	    mode->Private = (void *)drm_mode;
-	    xf86SetModeDefaultName(mode);
-	    modes = xf86ModesAdd(modes, mode);
-	    xf86PrintModeline(0, mode);
-	}
-    }
-
-    return modes;
-}
-
-static void
-destroy(xf86OutputPtr output)
-{
-    drmModeFreeConnector(output->driver_private);
-}
-
-static void
-create_resources(xf86OutputPtr output)
-{
-#ifdef RANDR_12_INTERFACE
-#endif /* RANDR_12_INTERFACE */
-}
-
-#ifdef RANDR_12_INTERFACE
-static Bool
-set_property(xf86OutputPtr output, Atom property, RRPropertyValuePtr value)
-{
-    return TRUE;
-}
-#endif /* RANDR_12_INTERFACE */
-
-#ifdef RANDR_13_INTERFACE
-static Bool
-get_property(xf86OutputPtr output, Atom property)
-{
-    return TRUE;
-}
-#endif /* RANDR_13_INTERFACE */
-
-#ifdef RANDR_GET_CRTC_INTERFACE
-static xf86CrtcPtr
-get_crtc(xf86OutputPtr output)
-{
-    return NULL;
-}
-#endif
-
-static const xf86OutputFuncsRec output_funcs = {
-    .create_resources = create_resources,
-    .dpms = dpms,
-    .save = save,
-    .restore = restore,
-    .mode_valid = mode_valid,
-    .mode_fixup = mode_fixup,
-    .prepare = prepare,
-    .mode_set = mode_set,
-    .commit = commit,
-    .detect = detect,
-    .get_modes = get_modes,
-#ifdef RANDR_12_INTERFACE
-    .set_property = set_property,
-#endif
-#ifdef RANDR_13_INTERFACE
-    .get_property = get_property,
-#endif
-    .destroy = destroy,
-#ifdef RANDR_GET_CRTC_INTERFACE
-    .get_crtc = get_crtc,
-#endif
-};
-
-void
-output_init(ScrnInfoPtr pScrn)
-{
-    modesettingPtr ms = modesettingPTR(pScrn);
-    xf86OutputPtr output;
-    drmModeResPtr res;
-    drmModeConnectorPtr drm_connector = NULL;
-    drmModeEncoderPtr drm_encoder = NULL;
-    drmModeCrtcPtr crtc;
-    char *name;
-    int c, v, p;
-
-    res = drmModeGetResources(ms->fd);
-    if (res == 0) {
-	DRV_ERROR("Failed drmModeGetResources\n");
-	return;
-    }
-
-    for (c = 0; c < res->count_connectors; c++) {
-	drm_connector = drmModeGetConnector(ms->fd, res->connectors[c]);
-	if (!drm_connector)
-	    goto out;
-
-	for (p = 0; p < drm_connector->count_props; p++) {
-	    drmModePropertyPtr prop;
-
-	    prop = drmModeGetProperty(ms->fd, drm_connector->props[p]);
-
-	    name = NULL;
-	    if (prop) {
-		ErrorF("VALUES %d\n", prop->count_values);
-
-		for (v = 0; v < prop->count_values; v++)
-		    ErrorF("%s %lld\n", prop->name, prop->values[v]);
-	    }
-	}
-
-	name = connector_enum_list[drm_connector->connector_type];
-
-	output = xf86OutputCreate(pScrn, &output_funcs, name);
-	if (!output)
-	    continue;
-
-	drm_encoder = drmModeGetEncoder(ms->fd, drm_connector->encoders[0]);
-	if (drm_encoder) {
-	    output->possible_crtcs = drm_encoder->crtcs;
-	    output->possible_clones = drm_encoder->clones;
-	} else {
-	    output->possible_crtcs = 0;
-	    output->possible_clones = 0;
-	}
-	output->driver_private = drm_connector;
-	output->subpixel_order = SubPixelHorizontalRGB;
-	output->interlaceAllowed = FALSE;
-	output->doubleScanAllowed = FALSE;
-    }
-
-  out:
-    drmModeFreeResources(res);
-}
commit 4828e4172cc363e17943334ab7d75243e75d344b
Author: Dave Airlie <airlied at redhat.com>
Date:   Thu Mar 10 09:13:50 2011 +1000

    drop exa
    
    don't provide accel in this framework

diff --git a/src/Makefile.am b/src/Makefile.am
index e3cc3cc..23e78b7 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -38,7 +38,6 @@ modesetting_drv_la_SOURCES = \
 	 driver.h \
 	 output.c \
 	 crtc.c \
-	 exa.c \
 	 dri2.c
 
 EXTRA_DIST =
diff --git a/src/driver.c b/src/driver.c
index 0e6f4c8..6b70d4b 100644
--- a/src/driver.c
+++ b/src/driver.c
@@ -126,16 +126,6 @@ static const OptionInfoRec Options[] = {
     {-1, NULL, OPTV_NONE, {0}, FALSE}
 };
 
-static const char *exaSymbols[] = {
-    "exaGetVersion",
-    "exaDriverInit",
-    "exaDriverFini",
-    "exaOffscreenAlloc",
-    "exaOffscreenFree",
-    "exaWaitSync",
-    NULL
-};
-
 static const char *fbSymbols[] = {
     "fbPictureInit",
     "fbScreenInit",
@@ -188,7 +178,7 @@ Setup(pointer module, pointer opts, int *errmaj, int *errmin)
 	 * Tell the loader about symbols from other modules that this module
 	 * might refer to.
 	 */
-	LoaderRefSymLists(exaSymbols, fbSymbols, ddcSymbols, NULL);
+	LoaderRefSymLists(fbSymbols, ddcSymbols, NULL);
 
 	/*
 	 * The return value must be non-NULL on success even though there
@@ -415,14 +405,11 @@ CreateFrontBuffer(ScrnInfoPtr pScrn)
     Bool fbAccessDisabled;
     int flags;
 
-    ms->noEvict = TRUE;
     pScreen->ModifyPixmapHeader(rootPixmap,
 				pScrn->virtualX, pScrn->virtualY,
 				pScrn->depth, pScrn->bitsPerPixel,
 				pScrn->displayWidth * pScrn->bitsPerPixel / 8,
 				NULL);
-    ms->noEvict = FALSE;
-
     drmModeAddFB(ms->fd,
 		 pScrn->virtualX,
 		 pScrn->virtualY,
@@ -633,8 +620,6 @@ PreInit(ScrnInfoPtr pScrn, int flags)
 
     xf86LoaderReqSymLists(fbSymbols, NULL);
 
-    xf86LoadSubModule(pScrn, "exa");
-
 #ifdef DRI2
     xf86LoadSubModule(pScrn, "dri2");
 #endif
@@ -667,8 +652,6 @@ CreateScreenResources(ScreenPtr pScreen)
     Bool ret;
     int flags;
 
-    ms->noEvict = TRUE;
-
     pScreen->CreateScreenResources = ms->createScreenResources;
     ret = pScreen->CreateScreenResources(pScreen);
     pScreen->CreateScreenResources = CreateScreenResources;
@@ -678,8 +661,6 @@ CreateScreenResources(ScreenPtr pScreen)
     if (!pScreen->ModifyPixmapHeader(rootPixmap, -1, -1, -1, -1, -1, NULL))
 	FatalError("Couldn't adjust screen pixmap\n");
 
-    ms->noEvict = FALSE;
-
     drmModeAddFB(ms->fd,
 		 pScrn->virtualX,
 		 pScrn->virtualY,
@@ -771,8 +752,6 @@ ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
 
     xf86SetBlackWhitePixels(pScreen);
 
-    ms->exa = ExaInit(pScrn);
-
     miInitializeBackingStore(pScreen);
     xf86SetBackingStore(pScreen);
     xf86SetSilkenMouse(pScreen);
@@ -933,9 +912,6 @@ CloseScreen(int scrnIndex, ScreenPtr pScreen)
 
     pScreen->CreateScreenResources = ms->createScreenResources;
 
-    if (ms->exa)
-	ExaClose(pScrn);
-
     drmClose(ms->fd);
     ms->fd = -1;
 
diff --git a/src/driver.h b/src/driver.h
index 5b31188..a673f8f 100644
--- a/src/driver.h
+++ b/src/driver.h
@@ -32,7 +32,6 @@
 #include <xf86drm.h>
 #include <xf86drmMode.h>
 #include <xf86mm.h>
-#include "exa.h"
 
 #define DRV_ERROR(msg)	xf86DrvMsg(pScrn->scrnIndex, X_ERROR, msg);
 
@@ -71,10 +70,7 @@ typedef struct _modesettingRec
 
     CreateScreenResourcesProcPtr createScreenResources;
 
-    /* exa */
-    void *exa;
     void *driver;
-    Bool noEvict;
 
     /* dri2 */
     drm_context_t context;
diff --git a/src/exa.c b/src/exa.c
deleted file mode 100644
index f688472..0000000
--- a/src/exa.c
+++ /dev/null
@@ -1,850 +0,0 @@
-/*
- * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- *
- * 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, sub license, 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 NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS 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.
- *
- *
- * Author: Alan Hourihane <alanh at tungstengraphics.com>
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-/* FIXME ! */
-#define DRI_DRIVER_PATH "/ISO/X.Org/modular/i386/lib/dri"
-
-#include "xf86.h"
-#include "xf86_OSproc.h"
-#include "driver.h"
-#include <dlfcn.h>
-
-#include "pipe/p_winsys.h"
-#include "pipe/p_format.h"
-#include "pipe/p_context.h"
-#include "pipe/p_util.h"
-#include "pipe/p_state.h"
-#include "pipe/p_inlines.h"
-
-/* EXA winsys */
-struct exa_context
-{
-};
-
-struct exa_winsys
-{
-    struct pipe_winsys base;
-    modesettingPtr ms;
-};
-
-struct exa_buffer
-{
-    struct pipe_buffer base;
-    drmBO bo;
-    boolean userBuffer;	/** Is this a user-space buffer? */
-    //void *data;
-    //void *mapped;
-};
-
-struct exa_surface
-{
-    struct pipe_surface surface;
-};
-
-struct exa_entity
-{
-    ExaDriverPtr pExa;
-    struct exa_context *c;
-    struct pipe_winsys *ws;
-    struct pipe_context *ctx;
-    struct pipe_screen *scrn;
-};
-
-static INLINE struct exa_winsys *
-exa_get_winsys(struct pipe_winsys *ws)
-{
-    return (struct exa_winsys *)ws;
-}
-
-static INLINE struct exa_surface *
-exa_get_surface(struct pipe_surface *ps)
-{
-    return (struct exa_surface *)ps;
-}
-
-static INLINE struct exa_buffer *
-exa_get_buffer(struct pipe_buffer *buf)
-{
-    return (struct exa_buffer *)buf;
-}
-
-static void *
-exa_buffer_map(struct pipe_winsys *pws, struct pipe_buffer *buf,
-	       unsigned flags)
-{
-    struct exa_buffer *exa_buf = exa_get_buffer(buf);
-    struct exa_winsys *exa_winsys = exa_get_winsys(pws);
-    void *virtual;
-
-    drmBOMap(exa_winsys->ms->fd,
-	     &exa_buf->bo, DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, 0, &virtual);
-
-    return virtual;
-}
-
-static void
-exa_buffer_unmap(struct pipe_winsys *pws, struct pipe_buffer *buf)
-{
-    struct exa_buffer *exa_buf = exa_get_buffer(buf);
-    struct exa_winsys *exa_winsys = exa_get_winsys(pws);
-
-    drmBOUnmap(exa_winsys->ms->fd, &exa_buf->bo);
-}
-
-static void
-exa_buffer_destroy(struct pipe_winsys *pws, struct pipe_buffer *buf)
-{
-    struct exa_winsys *exa_winsys = exa_get_winsys(pws);
-    struct exa_buffer *exa_buf = exa_get_buffer(buf);
-
-    drmBOUnreference(exa_winsys->ms->fd, &exa_buf->bo);
-
-    free(exa_buf);
-}
-
-static void
-exa_flush_frontbuffer(struct pipe_winsys *pws,
-		      struct pipe_surface *surf, void *context_private)
-{
-    struct exa_buffer *exa_buf = exa_get_buffer(surf->buffer);
-
-    ErrorF("WANT TO FLUSH\n");
-}
-
-static const char *
-exa_get_name(struct pipe_winsys *pws)
-{
-    return "EXA";
-}
-
-static struct pipe_buffer *
-exa_buffer_create(struct pipe_winsys *pws,
-		  unsigned alignment, unsigned usage, unsigned size)
-{
-    struct exa_buffer *buffer = xcalloc(1, sizeof(struct exa_buffer));
-    struct exa_winsys *exa_winsys = exa_get_winsys(pws);
-    unsigned int flags = 0;
-
-    buffer->base.refcount = 1;
-    buffer->base.alignment = alignment;
-    buffer->base.usage = usage;
-    buffer->base.size = size;
-
-    if (exa_winsys->ms->noEvict) {
-	flags = DRM_BO_FLAG_NO_EVICT;
-	ErrorF("DISPLAY TARGET\n");
-    }
-
-    ErrorF("SIZE %d %d\n", size, alignment);
-    if (!buffer->bo.handle) {
-	// buffer->data = align_malloc(size, alignment);
-	drmBOCreate(exa_winsys->ms->fd, size, 0, NULL,
-		    DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE |
-		    DRM_BO_FLAG_SHAREABLE | DRM_BO_FLAG_MEM_TT |
-		    DRM_BO_FLAG_MAPPABLE | flags,
-		    0, &buffer->bo);
-    }
-
-    return &buffer->base;
-}
-
-static struct pipe_buffer *
-exa_user_buffer_create(struct pipe_winsys *pws, void *ptr, unsigned bytes)
-{
-    struct exa_buffer *buffer = xcalloc(1, sizeof(struct exa_buffer));
-
-    buffer->base.refcount = 1;
-    buffer->base.size = bytes;
-    buffer->userBuffer = TRUE;
-    //buffer->data = ptr;
-    ErrorF("USERBUFFER\n");
-
-    return &buffer->base;
-}
-
-/**
- * Round n up to next multiple.
- */
-static INLINE unsigned
-round_up(unsigned n, unsigned multiple)
-{
-    return (n + multiple - 1) & ~(multiple - 1);
-}
-
-static int
-exa_surface_alloc_storage(struct pipe_winsys *winsys,
-			  struct pipe_surface *surf,
-			  unsigned width, unsigned height,
-			  enum pipe_format format,
-			  unsigned flags, unsigned tex_usage)
-{
-    const unsigned alignment = 64;
-
-    surf->width = width;
-    surf->height = height;
-    surf->format = format;
-    pf_get_block(format, &surf->block);
-    surf->stride = round_up(surf->nblocksx * surf->block.size, alignment);
-
-    assert(!surf->buffer);
-    surf->buffer = winsys->buffer_create(winsys, alignment,
-					 PIPE_BUFFER_USAGE_PIXEL,
-					 surf->stride * height);
-    if (!surf->buffer)
-	return -1;
-
-    return 0;
-}
-
-/**
- * Called via winsys->surface_alloc() to create new surfaces.
- */
-static struct pipe_surface *
-exa_surface_alloc(struct pipe_winsys *ws)
-{
-    struct exa_surface *wms = xcalloc(1, sizeof(struct exa_surface));
-
-    assert(ws);
-
-    wms->surface.refcount = 1;
-    wms->surface.winsys = ws;
-
-    return &wms->surface;
-}
-
-static void
-exa_surface_release(struct pipe_winsys *winsys, struct pipe_surface **s)
-{
-    struct pipe_surface *surf = *s;
-
-    surf->refcount--;
-    if (surf->refcount == 0) {
-	if (surf->buffer)
-	    pipe_buffer_reference(winsys, &surf->buffer, NULL);
-	free(surf);
-    }
-    *s = NULL;
-}
-
-/*
- * Fence functions - basically nothing to do, as we don't create any actual
- * fence objects.
- */
-static void
-exa_fence_reference(struct pipe_winsys *sws, struct pipe_fence_handle **ptr,
-		    struct pipe_fence_handle *fence)
-{
-}
-
-static int
-exa_fence_signalled(struct pipe_winsys *sws, struct pipe_fence_handle *fence,
-		    unsigned flag)
-{
-    return 0;
-}
-
-static int
-exa_fence_finish(struct pipe_winsys *sws, struct pipe_fence_handle *fence,
-		 unsigned flag)
-{
-    return 0;
-}
-
-struct pipe_winsys *
-exa_get_pipe_winsys(modesettingPtr ms)
-{
-    static struct exa_winsys *ws = NULL;
-
-    if (!ws) {
-	ws = xcalloc(1, sizeof(struct exa_winsys));
-
-	/* Fill in this struct with callbacks that pipe will need to
-	 * communicate with the window system, buffer manager, etc. 
-	 */
-	ws->base.buffer_create = exa_buffer_create;
-	ws->base.user_buffer_create = exa_user_buffer_create;
-	ws->base.buffer_map = exa_buffer_map;
-	ws->base.buffer_unmap = exa_buffer_unmap;
-	ws->base.buffer_destroy = exa_buffer_destroy;
-
-	ws->base.surface_alloc = exa_surface_alloc;
-	ws->base.surface_alloc_storage = exa_surface_alloc_storage;
-	ws->base.surface_release = exa_surface_release;
-
-	ws->base.fence_reference = exa_fence_reference;
-	ws->base.fence_signalled = exa_fence_signalled;
-	ws->base.fence_finish = exa_fence_finish;
-
-	ws->base.flush_frontbuffer = exa_flush_frontbuffer;
-	ws->base.get_name = exa_get_name;
-
-	ws->ms = ms;
-    }
-
-    return &ws->base;
-}
-
-/* EXA functions */
-
-struct PixmapPriv
-{
-    drmBO bo;
-#if 0
-    dri_fence *fence;
-#endif
-    int flags;
-
-    struct pipe_texture *tex;
-    unsigned int color;
-    struct pipe_surface *src_surf;     /* for copies */
-};
-
-static enum pipe_format
-exa_get_pipe_format(int depth)
-{
-    switch (depth) {
-    case 32:
-    case 24:
-	return PIPE_FORMAT_A8R8G8B8_UNORM;
-    case 16:
-	return PIPE_FORMAT_R5G6B5_UNORM;
-    case 15:
-	return PIPE_FORMAT_A1R5G5B5_UNORM;
-    case 8:
-    case 4:
-    case 1:
-	return PIPE_FORMAT_A8R8G8B8_UNORM;	/* bad bad bad */
-    default:
-	assert(0);
-	return 0;
-    }
-}
-
-/*
- * EXA functions
- */
-
-static void
-ExaWaitMarker(ScreenPtr pScreen, int marker)
-{
-}
-
-static int
-ExaMarkSync(ScreenPtr pScreen)
-{
-    return 1;
-}
-
-Bool
-ExaPrepareAccess(PixmapPtr pPix, int index)
-{
-    ScreenPtr pScreen = pPix->drawable.pScreen;
-    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
-    modesettingPtr ms = modesettingPTR(pScrn);
-    PixmapPtr rootPixmap = pScreen->GetScreenPixmap(pScreen);
-    struct exa_entity *exa = ms->exa;
-    struct PixmapPriv *priv;
-    int ret;
-
-    priv = exaGetPixmapDriverPrivate(pPix);
-
-    if (!priv)
-	return FALSE;
-
-    if (!priv->tex)
-	return FALSE;
-    {
-	struct pipe_surface *surf =
-	    exa->scrn->get_tex_surface(exa->scrn, priv->tex, 0, 0, 0,
-				       PIPE_BUFFER_USAGE_CPU_READ |
-				       PIPE_BUFFER_USAGE_CPU_WRITE);
-	pPix->devPrivate.ptr =
-	    exa->scrn->surface_map(exa->scrn, surf,
-				   PIPE_BUFFER_USAGE_CPU_READ |
-				   PIPE_BUFFER_USAGE_CPU_WRITE);
-	exa->scrn->tex_surface_release(exa->scrn, &surf);
-    }
-
-    return TRUE;
-}
-
-void
-ExaFinishAccess(PixmapPtr pPix, int index)
-{
-    ScreenPtr pScreen = pPix->drawable.pScreen;
-    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
-    modesettingPtr ms = modesettingPTR(pScrn);
-    PixmapPtr rootPixmap = pScreen->GetScreenPixmap(pScreen);
-    struct PixmapPriv *priv;
-    struct exa_entity *exa = ms->exa;
-    int ret;
-
-    priv = exaGetPixmapDriverPrivate(pPix);
-
-    if (!priv)
-	return;
-
-    if (!priv->tex)
-	return;
-    {
-	struct pipe_surface *surf =
-	    exa->scrn->get_tex_surface(exa->scrn, priv->tex, 0, 0, 0,
-				       PIPE_BUFFER_USAGE_CPU_READ |
-				       PIPE_BUFFER_USAGE_CPU_WRITE);
-	exa->scrn->surface_unmap(exa->scrn, surf);
-	exa->scrn->tex_surface_release(exa->scrn, &surf);
-	pPix->devPrivate.ptr = NULL;
-    }
-}
-
-static void
-ExaDone(PixmapPtr pPixmap)
-{
-    ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
-    modesettingPtr ms = modesettingPTR(pScrn);
-    struct PixmapPriv *priv = exaGetPixmapDriverPrivate(pPixmap);
-    struct exa_entity *exa = ms->exa;
-
-    if (!priv)
-	return;
-
-    if (priv->src_surf)
-	exa->scrn->tex_surface_release(exa->scrn, &priv->src_surf);
-    priv->src_surf = NULL;
-}
-
-static void
-ExaDoneComposite(PixmapPtr pPixmap)
-{
-    ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
-}
-
-static Bool
-ExaPrepareSolid(PixmapPtr pPixmap, int alu, Pixel planeMask, Pixel fg)
-{
-    ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
-    modesettingPtr ms = modesettingPTR(pScrn);
-    struct PixmapPriv *priv = exaGetPixmapDriverPrivate(pPixmap);
-    struct exa_entity *exa = ms->exa;
-
-    if (pPixmap->drawable.depth < 15)
-	return FALSE;
-
-    if (!EXA_PM_IS_SOLID(&pPixmap->drawable, planeMask))
-	return FALSE;
-
-    if (!priv || !priv->tex)
-	return FALSE;
-
-    if (alu != GXcopy)
-	return FALSE;
-
-    if (!exa->ctx || !exa->ctx->surface_fill)
-	return FALSE;
-
-    priv->color = fg;
-
-    return TRUE;
-}
-
-static void
-ExaSolid(PixmapPtr pPixmap, int x0, int y0, int x1, int y1)
-{
-    ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
-    modesettingPtr ms = modesettingPTR(pScrn);
-    struct exa_entity *exa = ms->exa;
-    struct PixmapPriv *priv = exaGetPixmapDriverPrivate(pPixmap);
-    struct pipe_surface *surf =
-	exa->scrn->get_tex_surface(exa->scrn, priv->tex, 0, 0, 0,
-				   PIPE_BUFFER_USAGE_GPU_READ |
-				   PIPE_BUFFER_USAGE_GPU_WRITE);
-
-    exa->ctx->surface_fill(exa->ctx, surf, x0, y0, x1 - x0, y1 - y0,
-			   priv->color);
-
-    exa->scrn->tex_surface_release(exa->scrn, &surf);
-}
-
-static Bool
-ExaPrepareCopy(PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap, int xdir,
-	       int ydir, int alu, Pixel planeMask)
-{
-    ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum];
-    modesettingPtr ms = modesettingPTR(pScrn);
-    struct exa_entity *exa = ms->exa;
-    struct pipe_surface *src_surf;
-    struct PixmapPriv *priv = exaGetPixmapDriverPrivate(pDstPixmap);
-    struct PixmapPriv *src_priv = exaGetPixmapDriverPrivate(pSrcPixmap);
-
-    if (alu != GXcopy)
-	return FALSE;
-
-    if (pSrcPixmap->drawable.depth < 15 || pDstPixmap->drawable.depth < 15)
-	return FALSE;
-
-    if (!EXA_PM_IS_SOLID(&pSrcPixmap->drawable, planeMask))
-	return FALSE;
-
-    if (!priv || !src_priv)
-	return FALSE;
-
-    if (!priv->tex || !src_priv->tex)
-	return FALSE;
-
-    if (!exa->ctx || !exa->ctx->surface_copy)
-	return FALSE;
-
-    priv->src_surf =
-	exa->scrn->get_tex_surface(exa->scrn, src_priv->tex, 0, 0, 0,
-				   PIPE_BUFFER_USAGE_GPU_READ |
-				   PIPE_BUFFER_USAGE_GPU_WRITE);
-
-    return FALSE;
-}
-
-static void
-ExaCopy(PixmapPtr pDstPixmap, int srcX, int srcY, int dstX, int dstY,
-	int width, int height)
-{
-    ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum];
-    modesettingPtr ms = modesettingPTR(pScrn);
-    struct exa_entity *exa = ms->exa;
-    struct PixmapPriv *priv = exaGetPixmapDriverPrivate(pDstPixmap);
-    struct pipe_surface *surf =
-	exa->scrn->get_tex_surface(exa->scrn, priv->tex, 0, 0, 0,
-				   PIPE_BUFFER_USAGE_GPU_READ |
-				   PIPE_BUFFER_USAGE_GPU_WRITE);
-
-    exa->ctx->surface_copy(exa->ctx, 0, surf, dstX, dstY, priv->src_surf,
-			   srcX, srcY, width, height);
-    exa->scrn->tex_surface_release(exa->scrn, &surf);
-}
-
-static Bool
-ExaPrepareComposite(int op, PicturePtr pSrcPicture,
-		    PicturePtr pMaskPicture, PicturePtr pDstPicture,
-		    PixmapPtr pSrc, PixmapPtr pMask, PixmapPtr pDst)
-{
-    ScreenPtr pScreen = pDst->drawable.pScreen;
-    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
-
-    return FALSE;
-}
-
-static Bool
-ExaUploadToScreen(PixmapPtr pDst, int x, int y, int w, int h, char *src,
-		  int src_pitch)
-{
-    ScreenPtr pScreen = pDst->drawable.pScreen;
-    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
-
-    ErrorF("UPLOAD\n");
-
-    return FALSE;
-}
-
-static void
-ExaComposite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY,
-	     int dstX, int dstY, int width, int height)
-{
-    ScreenPtr pScreen = pDst->drawable.pScreen;
-    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
-}
-
-static Bool
-ExaCheckComposite(int op,
-		  PicturePtr pSrcPicture, PicturePtr pMaskPicture,
-		  PicturePtr pDstPicture)
-{
-    DrawablePtr pDraw = pSrcPicture->pDrawable;
-    int w = pDraw->width;
-    int h = pDraw->height;
-
-    return FALSE;
-}
-
-static void *
-ExaCreatePixmap(ScreenPtr pScreen, int size, int align)
-{
-    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
-    modesettingPtr ms = modesettingPTR(pScrn);
-    struct PixmapPriv *priv;
-    void *virtual;
-
-    priv = xcalloc(1, sizeof(struct PixmapPriv));
-    if (!priv)
-	return NULL;
-
-    return priv;
-}
-
-static void
-ExaDestroyPixmap(ScreenPtr pScreen, void *dPriv)
-{
-    struct PixmapPriv *priv = (struct PixmapPriv *)dPriv;
-    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
-    modesettingPtr ms = modesettingPTR(pScrn);
-    struct exa_entity *exa = ms->exa;
-
-    if (!priv)
-	return;
-
-    if (priv->tex)
-	exa->scrn->texture_release(exa->scrn, &priv->tex);
-
-    xfree(priv);
-}
-
-static Bool
-ExaPixmapIsOffscreen(PixmapPtr pPixmap)
-{
-    struct PixmapPriv *priv;
-    ScreenPtr pScreen = pPixmap->drawable.pScreen;
-    PixmapPtr rootPixmap = pScreen->GetScreenPixmap(pScreen);
-
-    priv = exaGetPixmapDriverPrivate(pPixmap);
-
-    if (!priv)
-	return FALSE;
-
-    if (priv->tex)
-	return TRUE;
-
-    return FALSE;
-}
-
-/* FIXME !! */
-unsigned int
-driGetPixmapHandle(PixmapPtr pPixmap, unsigned int *flags)
-{
-    ScreenPtr pScreen = pPixmap->drawable.pScreen;
-    PixmapPtr rootPixmap = pScreen->GetScreenPixmap(pScreen);
-    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
-    modesettingPtr ms = modesettingPTR(pScrn);
-    struct exa_entity *exa = ms->exa;
-    struct exa_buffer *exa_buf;
-    struct pipe_surface *surf;
-    struct PixmapPriv *priv;
-
-    *flags = 0;
-
-    if (!ms->exa) {
-	FatalError("NO MS->EXA\n");
-	return 0;
-    }
-
-    priv = exaGetPixmapDriverPrivate(pPixmap);
-
-    if (!priv) {
-	FatalError("NO PIXMAP PRIVATE\n");
-	return 0;
-    }
-
-    surf =
-	exa->scrn->get_tex_surface(exa->scrn, priv->tex, 0, 0, 0,
-				   PIPE_BUFFER_USAGE_CPU_READ |
-				   PIPE_BUFFER_USAGE_CPU_WRITE);
-    exa_buf = exa_get_buffer(surf->buffer);
-    exa->scrn->tex_surface_release(exa->scrn, &surf);
-
-    if (exa_buf->bo.handle)
-	return exa_buf->bo.handle;
-
-    return 0;
-}
-
-static Bool
-ExaModifyPixmapHeader(PixmapPtr pPixmap, int width, int height,
-		      int depth, int bitsPerPixel, int devKind,
-		      pointer pPixData)
-{
-    ScreenPtr pScreen = pPixmap->drawable.pScreen;
-    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
-    struct PixmapPriv *priv = exaGetPixmapDriverPrivate(pPixmap);
-    modesettingPtr ms = modesettingPTR(pScrn);
-    PixmapPtr rootPixmap = pScreen->GetScreenPixmap(pScreen);
-    struct exa_entity *exa = ms->exa;
-
-    if (!priv)
-	return FALSE;
-
-    if (depth <= 0)
-	depth = pPixmap->drawable.depth;
-
-    if (bitsPerPixel <= 0)
-	bitsPerPixel = pPixmap->drawable.bitsPerPixel;
-
-    if (width <= 0)
-	width = pPixmap->drawable.width;
-
-    if (height <= 0)
-	height = pPixmap->drawable.height;
-
-    if (width <= 0 || height <= 0 || depth <= 0)
-	return FALSE;
-
-    miModifyPixmapHeader(pPixmap, width, height, depth,
-			     bitsPerPixel, devKind, NULL);
-
-    /* Deal with screen resize */
-    if (priv->tex) {
-	struct pipe_surface *surf =
-	    exa->scrn->get_tex_surface(exa->scrn, priv->tex, 0, 0, 0,
-				       PIPE_BUFFER_USAGE_CPU_READ |
-				       PIPE_BUFFER_USAGE_CPU_WRITE);
-
-	ErrorF("RESIZE %d %d to %d %d\n", surf->width, surf->height, width,
-	       height);
-	if (surf->width != width || surf->height != height) {
-	    exa->scrn->texture_release(exa->scrn, &priv->tex);
-	    priv->tex = NULL;
-	}
-	exa->scrn->tex_surface_release(exa->scrn, &surf);
-    }
-
-    if (!priv->tex) {
-	struct pipe_texture template;
-
-	memset(&template, 0, sizeof(template));
-	template.target = PIPE_TEXTURE_2D;
-	template.compressed = 0;
-	template.format = exa_get_pipe_format(depth);
-	pf_get_block(template.format, &template.block);
-	template.width[0] = width;
-	template.height[0] = height;
-	template.depth[0] = 1;
-	template.last_level = 0;
-	template.tex_usage = PIPE_TEXTURE_USAGE_RENDER_TARGET;
-	priv->tex = exa->scrn->texture_create(exa->scrn, &template);
-    }
-
-    return TRUE;
-}
-
-void
-ExaClose(ScrnInfoPtr pScrn)
-{
-    modesettingPtr ms = modesettingPTR(pScrn);
-    struct exa_entity *exa = ms->exa;
-
-    exaDriverFini(pScrn->pScreen);
-
-    dlclose(ms->driver);
-}
-
-void *
-ExaInit(ScrnInfoPtr pScrn)
-{
-    modesettingPtr ms = modesettingPTR(pScrn);
-    struct exa_entity *exa;
-    ExaDriverPtr pExa;
-
-    exa = xcalloc(1, sizeof(struct exa_entity));
-    if (!exa)
-	return NULL;
-
-    pExa = exaDriverAlloc();
-    if (!pExa) {
-	goto out_err;
-    }
-
-    memset(pExa, 0, sizeof(*pExa));
-    pExa->exa_major = 2;
-    pExa->exa_minor = 4;
-    pExa->memoryBase = 0;
-    pExa->memorySize = 0;
-    pExa->offScreenBase = 0;
-    pExa->pixmapOffsetAlign = 0;
-    pExa->pixmapPitchAlign = 1;
-    pExa->flags = EXA_OFFSCREEN_PIXMAPS | EXA_HANDLES_PIXMAPS;
-    pExa->maxX = 8191;		       /* FIXME */
-    pExa->maxY = 8191;		       /* FIXME */
-    pExa->WaitMarker = ExaWaitMarker;
-    pExa->MarkSync = ExaMarkSync;
-    pExa->PrepareSolid = ExaPrepareSolid;
-    pExa->Solid = ExaSolid;
-    pExa->DoneSolid = ExaDone;
-    pExa->PrepareCopy = ExaPrepareCopy;
-    pExa->Copy = ExaCopy;
-    pExa->DoneCopy = ExaDone;
-    pExa->CheckComposite = ExaCheckComposite;
-    pExa->PrepareComposite = ExaPrepareComposite;
-    pExa->Composite = ExaComposite;
-    pExa->DoneComposite = ExaDoneComposite;
-    pExa->PixmapIsOffscreen = ExaPixmapIsOffscreen;
-    pExa->PrepareAccess = ExaPrepareAccess;
-    pExa->FinishAccess = ExaFinishAccess;
-    pExa->UploadToScreen = ExaUploadToScreen;
-    pExa->CreatePixmap = ExaCreatePixmap;
-    pExa->DestroyPixmap = ExaDestroyPixmap;
-    pExa->ModifyPixmapHeader = ExaModifyPixmapHeader;
-
-    if (!exaDriverInit(pScrn->pScreen, pExa)) {
-	goto out_err;
-    }
-
-    {
-	char filename[128];
-	char dri_driver_path[] = DRI_DRIVER_PATH;
-
-	snprintf(filename, sizeof filename,
-		 "%s/%s_dri.so", dri_driver_path, "i915");
-
-	ms->driver = dlopen(filename, RTLD_NOW | RTLD_DEEPBIND | RTLD_GLOBAL);
-	if (!ms->driver)
-		FatalError("failed to initialize i915 - for softpipe only.\n");
-
-	exa->c = xcalloc(1, sizeof(struct exa_context));
-
-	exa->ws = exa_get_pipe_winsys(ms);
-	if (!exa->ws)
-		FatalError("BAD WINSYS\n");
-
-	exa->scrn = softpipe_create_screen(exa->ws);
-	if (!exa->scrn)
-		FatalError("BAD SCREEN\n");
-
-	exa->ctx = softpipe_create(exa->scrn, exa->ws, NULL);
-	if (!exa->ctx)
-	   	FatalError("BAD CTX\n");
-
-	exa->ctx->priv = exa->c;
-    }
-
-    return (void *)exa;
-
-  out_err:
-    ExaClose(pScrn);
-
-    return NULL;
-}


More information about the xorg-commit mailing list