xf86-video-intel: Branch 'glucose' - 201 commits - configure.ac .gitignore man/intel.man README src/bios_reader/bios_dumper.c src/bios_reader/bios_reader.c src/bios_reader/Makefile.am src/ch7017/ch7017.c src/ch7017/Makefile.am src/ch7xxx/ch7xxx.c src/ch7xxx/Makefile.am src/common.h src/exa_sf.g4a src/exa_sf_mask.g4a src/exa_sf_rotation.g4a src/exa_wm_maskca.g4a src/exa_wm_maskca_srcalpha.g4a src/exa_wm_masknoca.g4a src/exa_wm_nomask.g4a src/exa_wm_rotation.g4a src/i2c_vid.h src/i810_dri.c src/i810_driver.c src/i810.h src/i810_reg.h src/i830_accel.c src/i830_bios.c src/i830_bios.h src/i830_common.h src/i830_crt.c src/i830_debug.c src/i830_display.c src/i830_display.h src/i830_dri.c src/i830_driver.c src/i830_dvo.c src/i830_exa.c src/i830.h src/i830_lvds.c src/i830_memory.c src/i830_quirks.c src/i830_reg.h src/i830_render.c src/i830_sdvo.c src/i830_sdvo_regs.h src/i830_tv.c src/i830_video.c src/i830_video.h src/i830_xaa.c src/i915_reg.h src/i915_render.c src/i915_video.c src/i965_render.c src/i965_video.c src/ivch/ivch.c src/ivch/ivch_reg.h src/ivch/Makefile.am src/Makefile.am src/packed_yuv_sf.g4a src/packed_yuv_wm.g4a src/reg_dumper/main.c src/sil164/Makefile.am src/sil164/sil164.c src/tfp410/Makefile.am src/tfp410/tfp410.c src/tfp410/tfp410.h src/tfp410/tfp410_module.c src/tfp410/tfp410_reg.h src/xvmc/I810XvMC.h

Alan Hourihane alanh at kemper.freedesktop.org
Tue Sep 11 06:56:13 PDT 2007


 .gitignore                     |    1 
 README                         |   23 
 configure.ac                   |   67 
 man/intel.man                  |   79 
 src/Makefile.am                |    5 
 src/bios_reader/Makefile.am    |    2 
 src/bios_reader/bios_dumper.c  |    3 
 src/bios_reader/bios_reader.c  |    9 
 src/ch7017/Makefile.am         |    4 
 src/ch7017/ch7017.c            |    2 
 src/ch7xxx/Makefile.am         |    3 
 src/ch7xxx/ch7xxx.c            |    2 
 src/common.h                   |   88 
 src/exa_sf.g4a                 |   28 
 src/exa_sf_mask.g4a            |   25 
 src/exa_sf_rotation.g4a        |   26 
 src/exa_wm_maskca.g4a          |   26 
 src/exa_wm_maskca_srcalpha.g4a |   26 
 src/exa_wm_masknoca.g4a        |   26 
 src/exa_wm_nomask.g4a          |   26 
 src/exa_wm_rotation.g4a        |   26 
 src/i2c_vid.h                  |  130 +
 src/i810.h                     |   13 
 src/i810_dri.c                 |   20 
 src/i810_driver.c              |  271 ++
 src/i810_reg.h                 |  190 +
 src/i830.h                     |  145 -
 src/i830_accel.c               |   17 
 src/i830_bios.c                |   63 
 src/i830_bios.h                |   49 
 src/i830_common.h              |   25 
 src/i830_crt.c                 |  171 +
 src/i830_debug.c               |  209 +
 src/i830_display.c             |  512 +++-
 src/i830_display.h             |    4 
 src/i830_dri.c                 |  123 -
 src/i830_driver.c              |  656 +++--
 src/i830_dvo.c                 |  284 ++
 src/i830_exa.c                 |  180 +
 src/i830_lvds.c                |  304 +-
 src/i830_memory.c              |  426 ++-
 src/i830_quirks.c              |   94 
 src/i830_reg.h                 |   33 
 src/i830_render.c              |  128 -
 src/i830_sdvo.c                |   66 
 src/i830_sdvo_regs.h           |    6 
 src/i830_tv.c                  |   97 
 src/i830_video.c               | 4577 ++++++++++++++++++++---------------------
 src/i830_video.h               |   17 
 src/i830_xaa.c                 |  118 -
 src/i915_reg.h                 |   11 
 src/i915_render.c              |   56 
 src/i915_video.c               |  164 -
 src/i965_render.c              |  129 -
 src/i965_video.c               |   29 
 src/ivch/Makefile.am           |    3 
 src/ivch/ivch.c                |  211 +
 src/ivch/ivch_reg.h            |  208 +
 src/packed_yuv_sf.g4a          |   28 
 src/packed_yuv_wm.g4a          |   28 
 src/reg_dumper/main.c          |   10 
 src/sil164/Makefile.am         |    3 
 src/sil164/sil164.c            |    2 
 src/tfp410/Makefile.am         |   16 
 src/tfp410/tfp410.c            |  265 ++
 src/tfp410/tfp410.h            |   33 
 src/tfp410/tfp410_module.c     |   38 
 src/tfp410/tfp410_reg.h        |  104 
 src/xvmc/I810XvMC.h            |    1 
 69 files changed, 7000 insertions(+), 3764 deletions(-)

New commits:
diff-tree 59580cd3bae179011a4df0ecaeed1abdd739299f (from parents)
Merge: 0c28b4d459e293a14f9b19dc1108afbe920b00b6 d02336290bea30de3c390b8121046c38fd6b0f62
Author: Alan Hourihane <alanh at localhost.(none)>
Date:   Tue Sep 11 15:55:52 2007 +0100

    Merge branch 'master' of
    git+ssh://git.freedesktop.org/git/xorg/driver/xf86-video-intel into glucose
    
    Conflicts:
    
    	src/i830_display.c
    	src/i830_memory.c
    	src/i830_video.c

diff --cc src/i830_memory.c
index 3fc184b,3da489d..22a9619
@@@ -1009,10 -1136,10 +1136,10 @@@
  	return FALSE;
  
  #ifdef I830_USE_EXA
 -    if (pI830->useEXA) {
 +    if (pI830->AccelMethod == USE_EXA) {
  	if (pI830->exa_offscreen == NULL) {
  	    /* Default EXA to having 3 screens worth of offscreen memory space
- 	     * (for pixmaps), plus a double-buffered, 1920x1088 video's worth.
+ 	     * (for pixmaps).
  	     *
  	     * XXX: It would be nice to auto-size it larger if the user
  	     * specified a larger size, or to fit along with texture and FB
diff-tree d02336290bea30de3c390b8121046c38fd6b0f62 (from d9f2b3c0d2d08a4b7fad865dab7deb6224b57999)
Author: Jesse Barnes <jbarnes at nietzche.virtuousgeek.org>
Date:   Tue Sep 11 04:28:14 2007 -0700

    Fix plane/pipe mapping compat code
    
    Move plane->pipe mapping adjustment to ScreenInit so we can check
    against the DRM driver version accurately.

diff --git a/src/i830_driver.c b/src/i830_driver.c
index 27ec918..4786195 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -850,35 +850,24 @@ I830SetupOutputs(ScrnInfoPtr pScrn)
       output->possible_crtcs = crtc_mask;
       output->possible_clones = i830_output_clones (pScrn, intel_output->clone_mask);
    }
+}
 
-   /* Only recent DRM drivers can support plane<->pipe reversal */
-   if (pI830->directRenderingEnabled && pI830->drmMinor < 10)
-       goto out;
+static int
+I830LVDSPresent(ScrnInfoPtr pScrn)
+{
+   xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR (pScrn);
+   int o, lvds_detected = FALSE;
 
-   /*
-    * If an LVDS display is present, swap the plane/pipe mappings so we can
-    * use FBC on the builtin display.
-    * Note: 965+ chips can compress either plane, so we leave the mapping
-    *       alone in that case.
-    */
-   if (lvds_detected && !IS_I965GM(pI830)) {
-       xf86DrvMsg(pScrn->scrnIndex, X_INFO, "adjusting plane->pipe mappings "
-		  "to allow for framebuffer compression\n");
-       for (c = 0; c < config->num_crtc; c++) {
-	   xf86CrtcPtr	      crtc = config->crtc[c];
-	   I830CrtcPrivatePtr   intel_crtc = crtc->driver_private;
+   for (o = 0; o < config->num_output; o++) {
+      xf86OutputPtr	   output = config->output[o];
+      I830OutputPrivatePtr intel_output = output->driver_private;
 
-	   if (intel_crtc->pipe == 0)
-	       intel_crtc->plane = 1;
-	   else if (intel_crtc->pipe == 1)
-	       intel_crtc->plane = 0;
-      }
+      if (intel_output->type == I830_OUTPUT_LVDS)
+	  lvds_detected = TRUE;
    }
 
-out:
-   return;
+   return lvds_detected;
 }
-
 /**
  * Setup the CRTCs
  */
@@ -2719,15 +2708,31 @@ I830ScreenInit(int scrnIndex, ScreenPtr 
 
    config = XF86_CRTC_CONFIG_PTR(pScrn);
    sPriv = DRIGetSAREAPrivate(pScreen);
-   /* Setup pipe->plane mappings for DRI & DRM */
-   for (c = 0; c < config->num_crtc; c++) {
-       xf86CrtcPtr crtc = config->crtc[c];
-       I830CrtcPrivatePtr intel_crtc = crtc->driver_private;
-
-       if (intel_crtc->plane == 0)
-	   sPriv->planeA_pipe = intel_crtc->pipe;
-       else if (intel_crtc->plane == 1)
-	   sPriv->planeB_pipe = intel_crtc->pipe;
+
+   /*
+    * If an LVDS display is present, swap the plane/pipe mappings so we can
+    * use FBC on the builtin display.
+    * Note: 965+ chips can compress either plane, so we leave the mapping
+    *       alone in that case.
+    * Also, only flip the pipes if the DRM can support it.
+    */
+   if (I830LVDSPresent(pScrn) && !IS_I965GM(pI830) &&
+       (!pI830->directRenderingEnabled ||
+	(pI830->directRenderingEnabled && pI830->drmMinor >= 10))) {
+       xf86DrvMsg(pScrn->scrnIndex, X_INFO, "adjusting plane->pipe mappings "
+		  "to allow for framebuffer compression\n");
+       for (c = 0; c < config->num_crtc; c++) {
+	   xf86CrtcPtr	      crtc = config->crtc[c];
+	   I830CrtcPrivatePtr   intel_crtc = crtc->driver_private;
+
+	   if (intel_crtc->pipe == 0) {
+	       intel_crtc->plane = 1;
+	       sPriv->planeB_pipe = 0;
+	   } else if (intel_crtc->pipe == 1) {
+	       intel_crtc->plane = 0;
+	       sPriv->planeA_pipe = 1;
+	   }
+      }
    }
 
    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "drm planeA pipe: %d, "
diff-tree d9f2b3c0d2d08a4b7fad865dab7deb6224b57999 (from 4c7542ef43a5267e470ca1608a2ae57abf9783ec)
Author: Jesse Barnes <jbarnes at nietzche.virtuousgeek.org>
Date:   Mon Sep 10 23:49:34 2007 -0700

    Fix crash in ScreenInit
    
    Use pScreen directly when getting at the SAREA private, since
    pScrn->pScreen may not be initialized yet.

diff --git a/src/i830_driver.c b/src/i830_driver.c
index ea22855..27ec918 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -2718,7 +2718,7 @@ I830ScreenInit(int scrnIndex, ScreenPtr 
    }
 
    config = XF86_CRTC_CONFIG_PTR(pScrn);
-   sPriv = DRIGetSAREAPrivate(pScrn->pScreen);
+   sPriv = DRIGetSAREAPrivate(pScreen);
    /* Setup pipe->plane mappings for DRI & DRM */
    for (c = 0; c < config->num_crtc; c++) {
        xf86CrtcPtr crtc = config->crtc[c];
diff-tree 4c7542ef43a5267e470ca1608a2ae57abf9783ec (from 286f5df0b62f571cbb4dbf120679d3af029b8775)
Author: Jesse Barnes <jesse.barnes at intel.com>
Date:   Mon Sep 10 23:30:50 2007 -0700

    Only swap planes and pipes if DRM supports it
    
    We want to associate plane A with pipe B on pre-965 mobile chips, since that's
    the only way to get framebuffer compression on the builtin LVDS on those
    platforms.  However, if we do this swapping and DRM isn't aware of it, we may
    end up requesting vblank events for the wrong pipe, or setting up SAREA buffer
    swap state incorrectly.
    
    This mod checks whether DRM supports the new plane->pipe swapping behavior, and
    only enables the swapping if so.  This should fix the bugs Lukas found and
    debugged.  Reviewed by Michel Danzer.

diff --git a/src/i830_common.h b/src/i830_common.h
index 9c8616c..a652428 100644
--- a/src/i830_common.h
+++ b/src/i830_common.h
@@ -124,14 +124,17 @@ typedef struct {
         unsigned int rotated_tiled;
         unsigned int rotated2_tiled;
 
-	int pipeA_x;
-	int pipeA_y;
-	int pipeA_w;
-	int pipeA_h;
-	int pipeB_x;
-	int pipeB_y;
-	int pipeB_w;
-	int pipeB_h;
+	int planeA_x;
+	int planeA_y;
+	int planeA_w;
+	int planeA_h;
+	int planeB_x;
+	int planeB_y;
+	int planeB_w;
+	int planeB_h;
+
+	int planeA_pipe;
+	int planeB_pipe;
 
 	/* Triple buffering */
 	drm_handle_t third_handle;
diff --git a/src/i830_display.c b/src/i830_display.c
index d8be8d9..92e52ed 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -414,14 +414,14 @@ i830PipeSetBase(xf86CrtcPtr crtc, int x,
 	if (!sPriv)
 	    return;
 
-	switch (pipe) {
+	switch (plane) {
 	case 0:
-	    sPriv->pipeA_x = x;
-	    sPriv->pipeA_y = y;
+	    sPriv->planeA_x = x;
+	    sPriv->planeA_y = y;
 	    break;
 	case 1:
-	    sPriv->pipeB_x = x;
-	    sPriv->pipeB_y = y;
+	    sPriv->planeB_x = x;
+	    sPriv->planeB_y = y;
 	    break;
 	default:
 	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
@@ -763,14 +763,14 @@ i830_crtc_dpms(xf86CrtcPtr crtc, int mod
 	if (!sPriv)
 	    return;
 
-	switch (pipe) {
+	switch (plane) {
 	case 0:
-	    sPriv->pipeA_w = enabled ? crtc->mode.HDisplay : 0;
-	    sPriv->pipeA_h = enabled ? crtc->mode.VDisplay : 0;
+	    sPriv->planeA_w = enabled ? crtc->mode.HDisplay : 0;
+	    sPriv->planeA_h = enabled ? crtc->mode.VDisplay : 0;
 	    break;
 	case 1:
-	    sPriv->pipeB_w = enabled ? crtc->mode.HDisplay : 0;
-	    sPriv->pipeB_h = enabled ? crtc->mode.VDisplay : 0;
+	    sPriv->planeB_w = enabled ? crtc->mode.HDisplay : 0;
+	    sPriv->planeB_h = enabled ? crtc->mode.VDisplay : 0;
 	    break;
 	default:
 	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
diff --git a/src/i830_dri.c b/src/i830_dri.c
index 32f6510..2654ae6 100644
--- a/src/i830_dri.c
+++ b/src/i830_dri.c
@@ -91,7 +91,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
 #define DRM_VBLANK_FLIP 0x8000000
 
 typedef struct drm_i915_flip {
-   int pipes;
+   int planes;
 } drm_i915_flip_t;
 
 #undef DRM_IOCTL_I915_FLIP
@@ -1288,20 +1288,20 @@ I830DRISwapContext(ScreenPtr pScreen, DR
 #ifdef DAMAGE
       /* Try flipping back to the front page if necessary */
       if (sPriv && !sPriv->pf_enabled && sPriv->pf_current_page != 0) {
-	 drm_i915_flip_t flip = { .pipes = 0 };
+	 drm_i915_flip_t flip = { .planes = 0 };
 
 	 if (sPriv->pf_current_page & (0x3 << 2)) {
 	    sPriv->pf_current_page = sPriv->pf_current_page & 0x3;
 	    sPriv->pf_current_page |= (sPriv->third_handle ? 2 : 1) << 2;
 
-	    flip.pipes |= 0x2;
+	    flip.planes |= 0x2;
 	 }
 
 	 if (sPriv->pf_current_page & 0x3) {
 	    sPriv->pf_current_page = sPriv->pf_current_page & (0x3 << 2);
 	    sPriv->pf_current_page |= sPriv->third_handle ? 2 : 1;
 
-	    flip.pipes |= 0x1;
+	    flip.planes |= 0x1;
 	 }
 
 	 drmCommandWrite(pI830->drmSubFD, DRM_I915_FLIP, &flip, sizeof(flip));
@@ -1634,14 +1634,14 @@ I830DRIClipNotify(ScreenPtr pScreen, Win
       unsigned numvisible[2] = { 0, 0 };
       int i, j;
 
-      crtcBox[0].x1 = sPriv->pipeA_x;
-      crtcBox[0].y1 = sPriv->pipeA_y;
-      crtcBox[0].x2 = crtcBox[0].x1 + sPriv->pipeA_w;
-      crtcBox[0].y2 = crtcBox[0].y1 + sPriv->pipeA_h;
-      crtcBox[1].x1 = sPriv->pipeB_x;
-      crtcBox[1].y1 = sPriv->pipeB_y;
-      crtcBox[1].x2 = crtcBox[1].x1 + sPriv->pipeB_w;
-      crtcBox[1].y2 = crtcBox[1].y1 + sPriv->pipeB_h;
+      crtcBox[0].x1 = sPriv->planeA_x;
+      crtcBox[0].y1 = sPriv->planeA_y;
+      crtcBox[0].x2 = crtcBox[0].x1 + sPriv->planeA_w;
+      crtcBox[0].y2 = crtcBox[0].y1 + sPriv->planeA_h;
+      crtcBox[1].x1 = sPriv->planeB_x;
+      crtcBox[1].y1 = sPriv->planeB_y;
+      crtcBox[1].x2 = crtcBox[1].x1 + sPriv->planeB_w;
+      crtcBox[1].y2 = crtcBox[1].y1 + sPriv->planeB_h;
 
       for (i = 0; i < 2; i++) {
 	 for (j = 0; j < num; j++) {
diff --git a/src/i830_driver.c b/src/i830_driver.c
index b168fd4..ea22855 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -851,6 +851,10 @@ I830SetupOutputs(ScrnInfoPtr pScrn)
       output->possible_clones = i830_output_clones (pScrn, intel_output->clone_mask);
    }
 
+   /* Only recent DRM drivers can support plane<->pipe reversal */
+   if (pI830->directRenderingEnabled && pI830->drmMinor < 10)
+       goto out;
+
    /*
     * If an LVDS display is present, swap the plane/pipe mappings so we can
     * use FBC on the builtin display.
@@ -858,6 +862,8 @@ I830SetupOutputs(ScrnInfoPtr pScrn)
     *       alone in that case.
     */
    if (lvds_detected && !IS_I965GM(pI830)) {
+       xf86DrvMsg(pScrn->scrnIndex, X_INFO, "adjusting plane->pipe mappings "
+		  "to allow for framebuffer compression\n");
        for (c = 0; c < config->num_crtc; c++) {
 	   xf86CrtcPtr	      crtc = config->crtc[c];
 	   I830CrtcPrivatePtr   intel_crtc = crtc->driver_private;
@@ -868,6 +874,9 @@ I830SetupOutputs(ScrnInfoPtr pScrn)
 	       intel_crtc->plane = 0;
       }
    }
+
+out:
+   return;
 }
 
 /**
@@ -2249,11 +2258,13 @@ I830ScreenInit(int scrnIndex, ScreenPtr 
    VisualPtr visual;
    I830Ptr pI8301 = NULL;
    unsigned long sys_mem;
-   int i;
+   int i, c;
    Bool allocation_done = FALSE;
    MessageType from;
 #ifdef XF86DRI
    Bool driDisabled;
+   drmI830Sarea *sPriv;
+   xf86CrtcConfigPtr config;
 #ifdef XF86DRI_MM
    unsigned long savedMMSize;
 #endif
@@ -2706,6 +2717,22 @@ I830ScreenInit(int scrnIndex, ScreenPtr 
       i830_free_3d_memory(pScrn);
    }
 
+   config = XF86_CRTC_CONFIG_PTR(pScrn);
+   sPriv = DRIGetSAREAPrivate(pScrn->pScreen);
+   /* Setup pipe->plane mappings for DRI & DRM */
+   for (c = 0; c < config->num_crtc; c++) {
+       xf86CrtcPtr crtc = config->crtc[c];
+       I830CrtcPrivatePtr intel_crtc = crtc->driver_private;
+
+       if (intel_crtc->plane == 0)
+	   sPriv->planeA_pipe = intel_crtc->pipe;
+       else if (intel_crtc->plane == 1)
+	   sPriv->planeB_pipe = intel_crtc->pipe;
+   }
+
+   xf86DrvMsg(pScrn->scrnIndex, X_INFO, "drm planeA pipe: %d, "
+	      "planeB pipe: %d\n", sPriv->planeA_pipe, sPriv->planeB_pipe);
+
 #else
    pI830->directRenderingEnabled = FALSE;
 #endif
diff-tree 286f5df0b62f571cbb4dbf120679d3af029b8775 (from 2a8592f2ebcba86b1127aa889155d58a3dc186ca)
Author: Keith Packard <keithp at koto.keithp.com>
Date:   Thu Sep 6 14:31:55 2007 -0700

    Switch to pci_device_map_range/pci_device_unmap_range APIs.
    
    With the libpciaccess change that added these new APIs, use them
    for all mapping.

diff --git a/src/i810.h b/src/i810.h
index 2031408..8023c38 100644
--- a/src/i810.h
+++ b/src/i810.h
@@ -190,8 +190,6 @@ typedef struct _I810Rec {
    IOADDRESS ioBase;
    EntityInfoPtr pEnt;
 #if XSERVER_LIBPCIACCESS
-   int mmio_bar;
-   int fb_bar;
    struct pci_device *PciInfo;
 #else
    pciVideoPtr PciInfo;
diff --git a/src/i810_driver.c b/src/i810_driver.c
index e55f942..a6c13ed 100644
--- a/src/i810_driver.c
+++ b/src/i810_driver.c
@@ -1080,8 +1080,7 @@ I810PreInit(ScrnInfoPtr pScrn, int flags
 	      (pScrn->chipset != NULL) ? pScrn->chipset : "Unknown i810");
 
 #if XSERVER_LIBPCIACCESS
-   pI810->fb_bar = 0;
-   pI810->LinearAddr = pI810->PciInfo->regions[pI810->fb_bar].base_addr;
+   pI810->LinearAddr = pI810->PciInfo->regions[0].base_addr;
 #else
    if (pI810->pEnt->device->MemBase != 0) {
       pI810->LinearAddr = pI810->pEnt->device->MemBase;
@@ -1102,8 +1101,7 @@ I810PreInit(ScrnInfoPtr pScrn, int flags
 	      (unsigned long)pI810->LinearAddr);
 
 #if XSERVER_LIBPCIACCESS
-   pI810->mmio_bar = 1;
-   pI810->MMIOAddr = pI810->PciInfo->regions[pI810->mmio_bar].base_addr;
+   pI810->MMIOAddr = pI810->PciInfo->regions[1].base_addr;
 #else
    if (pI810->pEnt->device->IOBase != 0) {
       pI810->MMIOAddr = pI810->pEnt->device->IOBase;
@@ -1409,7 +1407,11 @@ I810MapMMIO(ScrnInfoPtr pScrn)
 #endif
 
 #if XSERVER_LIBPCIACCESS
-   err = pci_device_map_region (device, pI810->mmio_bar, TRUE);
+   err = pci_device_map_range (device,
+			       pI810->MMIOAddr,
+			       I810_REG_SIZE,
+			       PCI_DEV_MAP_FLAG_WRITABLE,
+			       (void **) &pI810->MMIOBase);
    if (err) 
    {
       xf86DrvMsg (pScrn->scrnIndex, X_ERROR,
@@ -1417,7 +1419,6 @@ I810MapMMIO(ScrnInfoPtr pScrn)
 		  strerror (err), err);
       return FALSE;
    }
-   pI810->MMIOBase = device->regions[pI810->mmio_bar].memory;
 #else
    pI810->MMIOBase = xf86MapPciMem(pScrn->scrnIndex, mmioFlags,
 				   pI810->PciTag,
@@ -1432,19 +1433,22 @@ static Bool
 I810MapMem(ScrnInfoPtr pScrn)
 {
    I810Ptr pI810 = I810PTR(pScrn);
-   long i;
 #if XSERVER_LIBPCIACCESS
    struct pci_device *const device = pI810->PciInfo;
    int err;
+#else
+   long i;
 #endif
 
-   for (i = 2; i < pI810->FbMapSize; i <<= 1) ;
-
    if (!I810MapMMIO(pScrn))
       return FALSE;
 
 #if XSERVER_LIBPCIACCESS
-   err = pci_device_map_region (device, pI810->fb_bar, TRUE);
+   err = pci_device_map_range (device,
+			       pI810->LinearAddr,
+			       pI810->FbMapSize,
+			       PCI_DEV_MAP_FLAG_WRITABLE | PCI_DEV_MAP_FLAG_WRITE_COMBINE,
+			       (void **) &pI810->FbBase);
    if (err) 
    {
       xf86DrvMsg (pScrn->scrnIndex, X_ERROR,
@@ -1452,9 +1456,9 @@ I810MapMem(ScrnInfoPtr pScrn)
 		  strerror (err), err);
       return FALSE;
    }
-   pI810->FbBase = device->regions[pI810->fb_bar].memory;
-   pI810->FbMapSize = device->regions[pI810->fb_bar].size;
 #else
+   for (i = 2; i < pI810->FbMapSize; i <<= 1) ;
+
    pI810->FbBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_FRAMEBUFFER,
 				 pI810->PciTag,
 				 pI810->LinearAddr, i);
@@ -1473,7 +1477,7 @@ I810UnmapMMIO(ScrnInfoPtr pScrn)
    I810Ptr pI810 = I810PTR(pScrn);
 
 #if XSERVER_LIBPCIACCESS
-   pci_device_unmap_region (pI810->PciInfo, pI810->mmio_bar);
+   pci_device_unmap_range (pI810->PciInfo, pI810->MMIOBase, I810_REG_SIZE);
 #else
    xf86UnMapVidMem(pScrn->scrnIndex, (pointer) pI810->MMIOBase,
 		   I810_REG_SIZE);
@@ -1487,7 +1491,7 @@ I810UnmapMem(ScrnInfoPtr pScrn)
    I810Ptr pI810 = I810PTR(pScrn);
 
 #if XSERVER_LIBPCIACCESS
-   pci_device_unmap_region (pI810->PciInfo, pI810->fb_bar);
+   pci_device_unmap_range (pI810->PciInfo, pI810->FbBase, pI810->FbMapSize);
 #else
    xf86UnMapVidMem(pScrn->scrnIndex, (pointer) pI810->FbBase,
 		   pI810->FbMapSize);
diff --git a/src/i830.h b/src/i830.h
index 4f176f8..71c46b4 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -291,6 +291,7 @@ typedef struct _I830Rec {
 
    /* These are set in PreInit and never changed. */
    long FbMapSize;
+   long GTTMapSize;
 
    i830_memory *memory_list;	/**< Linked list of video memory allocations */
    long stolen_size;		/**< bytes of pre-bound stolen memory */
@@ -367,9 +368,6 @@ typedef struct _I830Rec {
    EntityInfoPtr pEnt;
 #if XSERVER_LIBPCIACCESS
    struct pci_device *PciInfo;
-   int mmio_bar;
-   int fb_bar;
-   int gtt_bar;
 #else
    pciVideoPtr PciInfo;
    PCITAG PciTag;
diff --git a/src/i830_driver.c b/src/i830_driver.c
index 983be76..b168fd4 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -565,41 +565,19 @@ I830MapMMIO(ScrnInfoPtr pScrn)
    I830Ptr pI830 = I830PTR(pScrn);
 
 #if XSERVER_LIBPCIACCESS
-   pI830->GTTBase = NULL;
    device = pI830->PciInfo;
-   err = pci_device_map_region (device, pI830->mmio_bar, TRUE);
+   err = pci_device_map_range (device,
+			       pI830->MMIOAddr,
+			       I810_REG_SIZE,
+			       PCI_DEV_MAP_FLAG_WRITABLE,
+			       (void **) &pI830->MMIOBase);
    if (err) 
    {
       xf86DrvMsg (pScrn->scrnIndex, X_ERROR,
-		  "Unable to map mmio BAR. %s (%d)\n",
+		  "Unable to map mmio range. %s (%d)\n",
 		  strerror (err), err);
       return FALSE;
    }
-   pI830->MMIOBase = device->regions[pI830->mmio_bar].memory;
-   pI830->gtt_bar = -1;
-	
-   /* XXX GTT aperture base needs figuring out */
-   if (IS_I9XX(pI830)) 
-   {
-      if (IS_I965G(pI830))
-      {
-	 pI830->GTTBase = (unsigned char *) pI830->MMIOBase + (512 * 1024);
-      }
-      else
-      {
-	 pI830->gtt_bar = 3;
-	 err = pci_device_map_region (device, pI830->gtt_bar, TRUE);
-	 if (err)
-	 {
-	    xf86DrvMsg (pScrn->scrnIndex, X_ERROR,
-			"Unable to map GTT BAR. %s (%d)\n",
-			strerror (err), err);
-	    pI830->GTTBase = NULL;
-	 }
-	 else
-	    pI830->GTTBase = device->regions[pI830->gtt_bar].memory;
-      }
-   }
 #else
 
 #if !defined(__alpha__)
@@ -613,35 +591,50 @@ I830MapMMIO(ScrnInfoPtr pScrn)
 				   pI830->MMIOAddr, I810_REG_SIZE);
    if (!pI830->MMIOBase)
       return FALSE;
+#endif
 
    /* Set up the GTT mapping for the various places it has been moved over
     * time.
     */
    if (IS_I9XX(pI830)) {
-      if (IS_I965G(pI830)) {
-	 pI830->GTTBase = xf86MapPciMem(pScrn->scrnIndex, mmioFlags,
-					pI830->PciTag,
-					pI830->MMIOAddr + (512 * 1024),
-					512 * 1024);
-	 if (pI830->GTTBase == NULL)
-	    return FALSE;
-      } else {
-	 CARD32 gttaddr = pI830->PciInfo->memBase[3] & 0xFFFFFF00;
-
-	 pI830->GTTBase = xf86MapPciMem(pScrn->scrnIndex, mmioFlags,
-					pI830->PciTag,
-					gttaddr,
-					pI830->FbMapSize / 1024);
-	 if (pI830->GTTBase == NULL)
-	    return FALSE;
+      CARD32   gttaddr;
+      
+      if (IS_I965G(pI830)) 
+      {
+	 gttaddr = pI830->MMIOAddr + (512 * 1024);
+	 pI830->GTTMapSize = 512 * 1024;
       }
+      else
+      {
+	 gttaddr = I810_MEMBASE(pI830->PciInfo, 3) & 0xFFFFFF00;
+	 pI830->GTTMapSize = pI830->FbMapSize / 1024;
+      }
+#if XSERVER_LIBPCIACCESS
+      err = pci_device_map_range (device,
+				  gttaddr, pI830->GTTMapSize,
+				  PCI_DEV_MAP_FLAG_WRITABLE,
+				  (void **) &pI830->GTTBase);
+      if (err)
+      {
+	 xf86DrvMsg (pScrn->scrnIndex, X_ERROR,
+		     "Unable to map GTT range. %s (%d)\n",
+		     strerror (err), err);
+	 return FALSE;
+      }
+#else
+      pI830->GTTBase = xf86MapPciMem(pScrn->scrnIndex, mmioFlags,
+				     pI830->PciTag,
+				     gttaddr, pI830->GTTMapSize);
+      if (pI830->GTTBase == NULL)
+	 return FALSE;
+#endif
    } else {
       /* The GTT aperture on i830 is write-only.  We could probably map the
        * actual physical pages that back it, but leave it alone for now.
        */
       pI830->GTTBase = NULL;
+      pI830->GTTMapSize = 0;
    }
-#endif /* else HAVE_PCI_ACCESS */
 
    return TRUE;
 }
@@ -663,16 +656,9 @@ I830MapMem(ScrnInfoPtr pScrn)
       return FALSE;
 
 #if XSERVER_LIBPCIACCESS
-   err = pci_device_map_region (device, pI830->fb_bar, TRUE);
-   if (err) 
-   {
-      xf86DrvMsg (pScrn->scrnIndex, X_ERROR,
-		  "Unable to map frame buffer BAR. %s (%d)\n",
-		  strerror (err), err);
-      return FALSE;
-   }
-   pI830->FbBase = device->regions[pI830->fb_bar].memory;
-   pI830->FbMapSize = device->regions[pI830->fb_bar].size;
+   err = pci_device_map_range (device, pI830->LinearAddr, pI830->FbMapSize,
+			       PCI_DEV_MAP_FLAG_WRITABLE | PCI_DEV_MAP_FLAG_WRITE_COMBINE,
+			       (void **) &pI830->FbBase);
 #else
    pI830->FbBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_FRAMEBUFFER,
 				 pI830->PciTag,
@@ -695,7 +681,7 @@ I830UnmapMMIO(ScrnInfoPtr pScrn)
    I830Ptr pI830 = I830PTR(pScrn);
 
 #if XSERVER_LIBPCIACCESS
-   pci_device_unmap_region (pI830->PciInfo, pI830->mmio_bar);
+   pci_device_unmap_range (pI830->PciInfo, pI830->MMIOBase, I810_REG_SIZE);
 #else
    xf86UnMapVidMem(pScrn->scrnIndex, (pointer) pI830->MMIOBase,
 		   I810_REG_SIZE);
@@ -703,23 +689,12 @@ I830UnmapMMIO(ScrnInfoPtr pScrn)
    pI830->MMIOBase = NULL;
 
    if (IS_I9XX(pI830)) {
-      if (IS_I965G(pI830))
-      {
 #if XSERVER_LIBPCIACCESS
-	 ;
+      pci_device_unmap_range (pI830->PciInfo, pI830->GTTBase, pI830->GTTMapSize);
 #else
-	 xf86UnMapVidMem(pScrn->scrnIndex, pI830->GTTBase, 512 * 1024);
+      xf86UnMapVidMem(pScrn->scrnIndex, pI830->GTTBase, pI830->GTTMapSize);
 #endif
-      }
-      else 
-      {
-#if XSERVER_LIBPCIACCESS
-	 pci_device_unmap_region (pI830->PciInfo, pI830->gtt_bar);
-#else
-	 xf86UnMapVidMem(pScrn->scrnIndex, pI830->GTTBase,
-			 pI830->FbMapSize / 1024);
-#endif
-      }
+      pI830->GTTBase = NULL;
    }
 }
 
@@ -728,8 +703,12 @@ I830UnmapMem(ScrnInfoPtr pScrn)
 {
    I830Ptr pI830 = I830PTR(pScrn);
 
+#if XSERVER_LIBPCIACCESS
+   pci_device_unmap_range (pI830->PciInfo, pI830->FbBase, pI830->FbMapSize);
+#else
    xf86UnMapVidMem(pScrn->scrnIndex, (pointer) pI830->FbBase,
 		   pI830->FbMapSize);
+#endif
    pI830->FbBase = NULL;
    I830UnmapMMIO(pScrn);
    return TRUE;
@@ -1017,6 +996,7 @@ I830PreInit(ScrnInfoPtr pScrn, int flags
    int num_pipe;
    int max_width, max_height;
    uint32_t	capid;
+   int fb_bar, mmio_bar;
 
    if (pScrn->numEntities != 1)
       return FALSE;
@@ -1266,61 +1246,45 @@ I830PreInit(ScrnInfoPtr pScrn, int flags
    xf86DrvMsg(pScrn->scrnIndex, from, "Chipset: \"%s\"\n",
 	      (pScrn->chipset != NULL) ? pScrn->chipset : "Unknown i8xx");
 
-#if XSERVER_LIBPCIACCESS
    if (IS_I9XX(pI830))
-      pI830->fb_bar = 2;
+   {
+      fb_bar = 2;
+      mmio_bar = 0;
+   }
    else
-      pI830->fb_bar = 0;
-   pI830->LinearAddr = pI830->PciInfo->regions[pI830->fb_bar].base_addr;
-#else
+   {
+      fb_bar = 0;
+      mmio_bar = 1;
+   }
+
    if (pI830->pEnt->device->MemBase != 0) {
       pI830->LinearAddr = pI830->pEnt->device->MemBase;
       from = X_CONFIG;
    } else {
-      if (IS_I9XX(pI830)) {
-	 pI830->LinearAddr = pI830->PciInfo->memBase[2] & 0xFF000000;
-	 from = X_PROBED;
-      } else if (pI830->PciInfo->memBase[1] != 0) {
-	 /* XXX Check mask. */
-	 pI830->LinearAddr = pI830->PciInfo->memBase[0] & 0xFF000000;
-	 from = X_PROBED;
-      } else {
+      pI830->LinearAddr = I810_MEMBASE (pI830->PciInfo, fb_bar);
+      if (pI830->LinearAddr == 0) {
 	 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
 		    "No valid FB address in PCI config space\n");
 	 PreInitCleanup(pScrn);
 	 return FALSE;
       }
    }
-#endif
 
    xf86DrvMsg(pScrn->scrnIndex, from, "Linear framebuffer at 0x%lX\n",
 	      (unsigned long)pI830->LinearAddr);
 
-#if XSERVER_LIBPCIACCESS
-   if (IS_I9XX(pI830))
-      pI830->mmio_bar = 0;
-   else
-      pI830->mmio_bar = 1;
-   pI830->MMIOAddr = pI830->PciInfo->regions[pI830->mmio_bar].base_addr;
-#else
    if (pI830->pEnt->device->IOBase != 0) {
       pI830->MMIOAddr = pI830->pEnt->device->IOBase;
       from = X_CONFIG;
    } else {
-      if (IS_I9XX(pI830)) {
-	 pI830->MMIOAddr = pI830->PciInfo->memBase[0] & 0xFFF80000;
-	 from = X_PROBED;
-      } else if (pI830->PciInfo->memBase[1]) {
-	 pI830->MMIOAddr = pI830->PciInfo->memBase[1] & 0xFFF80000;
-	 from = X_PROBED;
-      } else {
+      pI830->MMIOAddr = I810_MEMBASE (pI830->PciInfo, mmio_bar);
+      if (pI830->MMIOAddr == 0) {
 	 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
 		    "No valid MMIO address in PCI config space\n");
 	 PreInitCleanup(pScrn);
 	 return FALSE;
       }
    }
-#endif
 
    xf86DrvMsg(pScrn->scrnIndex, from, "IO registers at addr 0x%lX\n",
 	      (unsigned long)pI830->MMIOAddr);
@@ -1365,7 +1329,7 @@ I830PreInit(ScrnInfoPtr pScrn, int flags
    } else {
       if (IS_I9XX(pI830)) {
 #if XSERVER_LIBPCIACCESS
-	 pI830->FbMapSize = pI830->PciInfo->regions[pI830->fb_bar].size;
+	 pI830->FbMapSize = pI830->PciInfo->regions[fb_bar].size;
 #else
 	 pI830->FbMapSize = 1UL << pciGetBaseSize(pI830->PciTag, 2, TRUE,
 						  NULL);
diff --git a/src/reg_dumper/main.c b/src/reg_dumper/main.c
index b3c50de..5c8ef9e 100644
--- a/src/reg_dumper/main.c
+++ b/src/reg_dumper/main.c
@@ -40,6 +40,7 @@ int main(int argc, char **argv)
     I830Rec i830;
     ScrnInfoRec scrn;
     int err, mmio_bar;
+    void *mmio;
 
     err = pci_system_init();
     if (err != 0) {
@@ -68,12 +69,17 @@ int main(int argc, char **argv)
 
     mmio_bar = IS_I9XX((&i830)) ? 0 : 1;
 
-    err = pci_device_map_region(dev, mmio_bar, 1);
+    err = pci_device_map_range (dev,
+				dev->regions[mmio_bar].base_addr,
+				dev->regions[mmio_bar].size, 
+				PCI_DEV_MAP_FLAG_WRITABLE,
+				&mmio);
+    
     if (err != 0) {
 	fprintf(stderr, "Couldn't map MMIO region: %s\n", strerror(err));
 	exit(1);
     }
-    i830.mmio = i830.pci_dev->regions[mmio_bar].memory;
+    i830.mmio = mmio;
 
     scrn.scrnIndex = 0;
     scrn.pI830 = &i830;
diff-tree 2a8592f2ebcba86b1127aa889155d58a3dc186ca (from 7fd9a98178cdebda4213796fdc452a8a265a1197)
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Wed Sep 5 14:52:56 2007 +0800

    Fix G33 GTT stolen mem range
    
    G33 GTT table lives in seperate stolen mem with
    graphics data stolen mem.

diff --git a/src/i830_driver.c b/src/i830_driver.c
index 9fa231d..983be76 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -483,6 +483,9 @@ I830DetectMemory(ScrnInfoPtr pScrn)
    range = gtt_size + 4;
 
    if (IS_I85X(pI830) || IS_I865G(pI830) || IS_I9XX(pI830)) {
+      /* G33 has seperate GTT stolen mem */
+      if (IS_G33CLASS(pI830))
+	  range = 0;
       switch (gmch_ctrl & I830_GMCH_GMS_MASK) {
       case I855_GMCH_GMS_STOLEN_1M:
 	 memsize = MB(1) - KB(range);
diff-tree 7fd9a98178cdebda4213796fdc452a8a265a1197 (from c6e637cd683dc60567b3b4f69b7f2b4c338c89ea)
Author: Keith Packard <keithp at koto.keithp.com>
Date:   Tue Aug 28 16:00:01 2007 -0700

    Don't set supported TV formats until after RandR initialized.
    
    The TV format property cannot be configured until RandR has been
    initialized.

diff --git a/src/i830_tv.c b/src/i830_tv.c
index d86e984..940250e 100644
--- a/src/i830_tv.c
+++ b/src/i830_tv.c
@@ -1507,6 +1507,9 @@ i830_tv_format_configure_property (xf86O
     int			    num_atoms = 0;
     int			    i;
     
+    if (!output->randr_output)
+	return Success;
+
     for (i = 0; i < NUM_TV_MODES; i++)
 	if (!tv_modes[i].component_only || dev_priv->type == TV_TYPE_COMPONENT)
 	    current_atoms[num_atoms++] = tv_format_name_atoms[i];
diff-tree c6e637cd683dc60567b3b4f69b7f2b4c338c89ea (from ddd6053987b9ca9bd3722ddbdfd412a3d8d252cf)
Author: Keith Packard <keithp at koto.keithp.com>
Date:   Tue Aug 28 12:17:15 2007 -0700

    Limit TV formats to those supported by current connection

diff --git a/src/i830_exa.c b/src/i830_exa.c
index fa50da0..273c626 100644
--- a/src/i830_exa.c
+++ b/src/i830_exa.c
@@ -124,7 +124,7 @@ i830_pixmap_tiled(PixmapPtr pPixmap)
     return FALSE;
 }
 
-Bool
+static Bool
 i830_exa_pixmap_is_offscreen(PixmapPtr pPixmap)
 {
     ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
diff --git a/src/i830_tv.c b/src/i830_tv.c
index c90d41e..d86e984 100644
--- a/src/i830_tv.c
+++ b/src/i830_tv.c
@@ -1264,14 +1264,13 @@ static const DisplayModeRec reported_mod
  * \return TRUE if TV is connected.
  * \return FALSE if TV is disconnected.
  */
-static void
+static int
 i830_tv_detect_type (xf86CrtcPtr    crtc,
 		xf86OutputPtr  output)
 {
     ScrnInfoPtr		    pScrn = output->scrn;
     I830Ptr		    pI830 = I830PTR(pScrn);
     I830OutputPrivatePtr    intel_output = output->driver_private;
-    struct i830_tv_priv	    *dev_priv = intel_output->dev_priv;
     CARD32		    tv_ctl, save_tv_ctl;
     CARD32		    tv_dac, save_tv_dac;
     int			    type = TV_TYPE_UNKNOWN;
@@ -1337,9 +1336,14 @@ i830_tv_detect_type (xf86CrtcPtr    crtc
 	type = TV_TYPE_NONE;
     }
 
-    dev_priv->type = type;
+    return type;
 }
 
+#ifdef RANDR_12_INTERFACE
+static int
+i830_tv_format_configure_property (xf86OutputPtr output);
+#endif
+
 /**
  * Detect the TV connection.
  *
@@ -1354,17 +1358,26 @@ i830_tv_detect(xf86OutputPtr output)
     I830OutputPrivatePtr    intel_output = output->driver_private;
     struct i830_tv_priv	    *dev_priv = intel_output->dev_priv;
     int			    dpms_mode;
+    int			    type = dev_priv->type;
 
     mode = reported_modes[0];
     xf86SetModeCrtc (&mode, INTERLACE_HALVE_V);
     crtc = i830GetLoadDetectPipe (output, &mode, &dpms_mode);
     if (crtc)
     {
-        i830_tv_detect_type (crtc, output);
+        type = i830_tv_detect_type (crtc, output);
         i830ReleaseLoadDetectPipe (output, dpms_mode);
     }
 
-    switch (dev_priv->type) {
+    if (type != dev_priv->type)
+    {
+	dev_priv->type = type;
+#ifdef RANDR_12_INTERFACE
+	i830_tv_format_configure_property (output);
+#endif
+    }
+	
+    switch (type) {
     case TV_TYPE_NONE:
         return XF86OutputStatusDisconnected;
     case TV_TYPE_UNKNOWN:
@@ -1477,6 +1490,32 @@ i830_tv_format_set_property (xf86OutputP
     return err == Success;
 }
 
+    
+/**
+ * Configure the TV_FORMAT property to list only supported formats
+ *
+ * Unless the connector is component, list only the formats supported by
+ * svideo and composite
+ */
+
+static int
+i830_tv_format_configure_property (xf86OutputPtr output)
+{
+    I830OutputPrivatePtr    intel_output = output->driver_private;
+    struct i830_tv_priv	    *dev_priv = intel_output->dev_priv;
+    Atom		    current_atoms[NUM_TV_MODES];
+    int			    num_atoms = 0;
+    int			    i;
+    
+    for (i = 0; i < NUM_TV_MODES; i++)
+	if (!tv_modes[i].component_only || dev_priv->type == TV_TYPE_COMPONENT)
+	    current_atoms[num_atoms++] = tv_format_name_atoms[i];
+    
+    return RRConfigureOutputProperty(output->randr_output, tv_format_atom,
+				     TRUE, FALSE, FALSE, 
+				     num_atoms, (INT32 *) current_atoms);
+}
+
 #endif /* RANDR_12_INTERFACE */
 
 static void
@@ -1500,10 +1539,8 @@ i830_tv_create_resources(xf86OutputPtr o
 					    strlen (tv_modes[i].name),
 					    TRUE);
 
-    err = RRConfigureOutputProperty(output->randr_output, tv_format_atom,
-				    TRUE, FALSE, FALSE, 
-				    NUM_TV_MODES, (INT32 *) tv_format_name_atoms);
-    
+    err = i830_tv_format_configure_property (output);
+
     if (err != 0) {
 	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
 		   "RRConfigureOutputProperty error, %d\n", err);
diff --git a/src/xvmc/I810XvMC.h b/src/xvmc/I810XvMC.h
index ba8c792..dc2cab8 100644
--- a/src/xvmc/I810XvMC.h
+++ b/src/xvmc/I810XvMC.h
@@ -41,6 +41,7 @@ THE USE OR OTHER DEALINGS IN THE SOFTWAR
 /* #define XVMC_DEBUG(x) do {x; }while(0); */
 #define XVMC_DEBUG(x)
 
+#include <stdint.h>
 #include "xf86drm.h"
 #include "i810_common.h"
 #include <X11/Xlibint.h>
diff-tree ddd6053987b9ca9bd3722ddbdfd412a3d8d252cf (from 3fbbd0afde49c53a5a8661f75c8c8c4be3020c30)
Author: Keith Packard <keithp at koto.keithp.com>
Date:   Tue Aug 28 12:30:46 2007 -0700

    Add register defines for hw binning

diff --git a/src/i810_reg.h b/src/i810_reg.h
index 03e10d6..598fc8c 100644
--- a/src/i810_reg.h
+++ b/src/i810_reg.h
@@ -346,19 +346,33 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN
 #define IPEIR                  0x2088
 #define IPEHR                  0x208C
 #define INST_DONE                0x2090
+#define SCPD0                    0x209c	/* debug */
 #define INST_PS                  0x20c4
 #define IPEIR_I965                  0x2064 /* i965 */
 #define IPEHR_I965                  0x2068 /* i965 */
 #define INST_DONE_I965              0x206c
 #define INST_PS_I965                0x2070
+
+/* Current active ring head address: 
+ */
 #define ACTHD                 0x2074
+
+/* Current primary/secondary DMA fetch addresses:
+ */
 #define DMA_FADD_P             0x2078
+#define DMA_FADD_S               0x20d4
 #define INST_DONE_1              0x207c
 
 #define CACHE_MODE_0           0x2120
 #define CACHE_MODE_1           0x2124
 #define MI_ARB_STATE           0x20e4
 
+/* Start addresses for each of the primary rings:
+ */
+#define PR0_STR                  0x20f0
+#define PR1_STR                  0x20f4
+#define PR2_STR                  0x20f8
+
 #define WIZ_CTL                0x7c00
 #define WIZ_CTL_SINGLE_SUBSPAN  (1<<6)
 #define WIZ_CTL_IGNORE_STALLS  (1<<5)
diff-tree 3fbbd0afde49c53a5a8661f75c8c8c4be3020c30 (from 0fdbf64b34e4114c2b89d696b268b9c7464f1efd)
Author: Michel Dänzer <michel at tungstengraphics.com>
Date:   Tue Aug 28 17:48:20 2007 +0200

    Fix build against pre-pci-rework xserver.

diff --git a/src/common.h b/src/common.h
index cfe00fc..40ea038 100644
--- a/src/common.h
+++ b/src/common.h
@@ -444,7 +444,9 @@ extern int I810_DEBUG;
 
 #define PIPE_NAME(n)			('A' + (n))
 
+#if XSERVER_LIBPCIACCESS
 struct pci_device *
 intel_host_bridge (void);
+#endif
    
 #endif /* _INTEL_COMMON_H_ */
diff-tree 0fdbf64b34e4114c2b89d696b268b9c7464f1efd (from 3411eb0dbae470b910af3116a4ab960c821b9b20)
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Tue Aug 28 21:56:21 2007 +0800

    Fix i915 a8 color buffer blending
    
    From spec, i915 engine uses green channel when reading from 8bit
    color buffer for blending, and also writes back green channel.
    Fix blend factor in dest alpha case by using dest color instead.
    Now rendercheck can pass a8 tests.

diff --git a/src/i915_render.c b/src/i915_render.c
index 7546dfd..ca85bf7 100644
--- a/src/i915_render.c
+++ b/src/i915_render.c
@@ -123,6 +123,17 @@ static CARD32 i915_get_blend_cntl(int op
             sblend = BLENDFACT_ZERO;
     }
 
+    /* i915 engine reads 8bit color buffer into green channel in cases
+       like color buffer blending .etc, and also writes back green channel.
+       So with dst_alpha blend we should use color factor. See spec on
+       "8-bit rendering" */
+    if ((dst_format == PICT_a8) && i915_blend_op[op].dst_alpha) {
+        if (sblend == BLENDFACT_DST_ALPHA)
+            sblend = BLENDFACT_DST_COLR;
+        else if (sblend == BLENDFACT_INV_DST_ALPHA)
+            sblend = BLENDFACT_INV_DST_COLR;
+    }
+
     /* If the source alpha is being used, then we should only be in a case
      * where the source blend factor is 0, and the source blend value is the
      * mask channels multiplied by the source picture's alpha.
diff-tree 3411eb0dbae470b910af3116a4ab960c821b9b20 (from 387fed6daa7426e4a85d30ba7cf608b5f41d24bb)
Author: Keith Packard <keithp at koto.keithp.com>
Date:   Sun Aug 26 23:09:01 2007 -0700

    i830_driver.c changes for libpciaccess.
    
    Change to use libpciaccess APIs, including computing and using BAR indices
    for various mapping activities.

diff --git a/src/i830_driver.c b/src/i830_driver.c
index ab42fd9..9fa231d 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -201,6 +201,9 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include "dri.h"
 #include <sys/ioctl.h>
 #include <errno.h>
+#ifdef XF86DRI_MM
+#include "xf86mm.h"
+#endif
 #endif
 
 #ifdef I830_USE_EXA
@@ -418,16 +421,23 @@ static int
 I830DetectMemory(ScrnInfoPtr pScrn)
 {
    I830Ptr pI830 = I830PTR(pScrn);
+#if !XSERVER_LIBPCIACCESS
    PCITAG bridge;
-   CARD16 gmch_ctrl;
+#endif
+   uint16_t gmch_ctrl;
    int memsize = 0, gtt_size;
    int range;
 #if 0
    VbeInfoBlock *vbeInfo;
 #endif
 
+#if XSERVER_LIBPCIACCESS
+   struct pci_device *bridge = intel_host_bridge ();
+   pci_device_cfg_read_u16(bridge, & gmch_ctrl, I830_GMCH_CTRL);
+#else
    bridge = pciTag(0, 0, 0);		/* This is always the host bridge */
    gmch_ctrl = pciReadWord(bridge, I830_GMCH_CTRL);
+#endif
 
    if (IS_I965G(pI830)) {
       /* The 965 may have a GTT that is actually larger than is necessary
@@ -543,9 +553,52 @@ I830DetectMemory(ScrnInfoPtr pScrn)
 static Bool
 I830MapMMIO(ScrnInfoPtr pScrn)
 {
+#if XSERVER_LIBPCIACCESS
+   int err;
+   struct pci_device *device;
+#else
    int mmioFlags;
+#endif
    I830Ptr pI830 = I830PTR(pScrn);
 
+#if XSERVER_LIBPCIACCESS
+   pI830->GTTBase = NULL;
+   device = pI830->PciInfo;
+   err = pci_device_map_region (device, pI830->mmio_bar, TRUE);
+   if (err) 
+   {
+      xf86DrvMsg (pScrn->scrnIndex, X_ERROR,
+		  "Unable to map mmio BAR. %s (%d)\n",
+		  strerror (err), err);
+      return FALSE;
+   }
+   pI830->MMIOBase = device->regions[pI830->mmio_bar].memory;
+   pI830->gtt_bar = -1;
+	
+   /* XXX GTT aperture base needs figuring out */
+   if (IS_I9XX(pI830)) 
+   {
+      if (IS_I965G(pI830))
+      {
+	 pI830->GTTBase = (unsigned char *) pI830->MMIOBase + (512 * 1024);
+      }
+      else
+      {
+	 pI830->gtt_bar = 3;
+	 err = pci_device_map_region (device, pI830->gtt_bar, TRUE);
+	 if (err)
+	 {
+	    xf86DrvMsg (pScrn->scrnIndex, X_ERROR,
+			"Unable to map GTT BAR. %s (%d)\n",
+			strerror (err), err);
+	    pI830->GTTBase = NULL;
+	 }
+	 else
+	    pI830->GTTBase = device->regions[pI830->gtt_bar].memory;
+      }
+   }
+#else
+
 #if !defined(__alpha__)
    mmioFlags = VIDMEM_MMIO | VIDMEM_READSIDEEFFECT;
 #else
@@ -585,6 +638,7 @@ I830MapMMIO(ScrnInfoPtr pScrn)
        */
       pI830->GTTBase = NULL;
    }
+#endif /* else HAVE_PCI_ACCESS */
 
    return TRUE;
 }
@@ -594,6 +648,10 @@ I830MapMem(ScrnInfoPtr pScrn)
 {
    I830Ptr pI830 = I830PTR(pScrn);
    long i;
+#if XSERVER_LIBPCIACCESS
+   struct pci_device *const device = pI830->PciInfo;
+   int err;
+#endif
 
    for (i = 2; i < pI830->FbMapSize; i <<= 1) ;
    pI830->FbMapSize = i;
@@ -601,11 +659,24 @@ I830MapMem(ScrnInfoPtr pScrn)
    if (!I830MapMMIO(pScrn))
       return FALSE;
 
+#if XSERVER_LIBPCIACCESS
+   err = pci_device_map_region (device, pI830->fb_bar, TRUE);
+   if (err) 
+   {
+      xf86DrvMsg (pScrn->scrnIndex, X_ERROR,
+		  "Unable to map frame buffer BAR. %s (%d)\n",
+		  strerror (err), err);
+      return FALSE;
+   }
+   pI830->FbBase = device->regions[pI830->fb_bar].memory;
+   pI830->FbMapSize = device->regions[pI830->fb_bar].size;
+#else
    pI830->FbBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_FRAMEBUFFER,
 				 pI830->PciTag,
 				 pI830->LinearAddr, pI830->FbMapSize);
    if (!pI830->FbBase)
       return FALSE;
+#endif
 
    if (I830IsPrimary(pScrn) && pI830->LpRing->mem != NULL) {
       pI830->LpRing->virtual_start =
@@ -620,16 +691,31 @@ I830UnmapMMIO(ScrnInfoPtr pScrn)
 {
    I830Ptr pI830 = I830PTR(pScrn);
 
+#if XSERVER_LIBPCIACCESS
+   pci_device_unmap_region (pI830->PciInfo, pI830->mmio_bar);
+#else
    xf86UnMapVidMem(pScrn->scrnIndex, (pointer) pI830->MMIOBase,
 		   I810_REG_SIZE);
+#endif
    pI830->MMIOBase = NULL;
 
    if (IS_I9XX(pI830)) {
       if (IS_I965G(pI830))
+      {
+#if XSERVER_LIBPCIACCESS
+	 ;
+#else
 	 xf86UnMapVidMem(pScrn->scrnIndex, pI830->GTTBase, 512 * 1024);
-      else {
+#endif
+      }
+      else 
+      {
+#if XSERVER_LIBPCIACCESS
+	 pci_device_unmap_region (pI830->PciInfo, pI830->gtt_bar);
+#else
 	 xf86UnMapVidMem(pScrn->scrnIndex, pI830->GTTBase,
 			 pI830->FbMapSize / 1024);
+#endif
       }
    }
 }
@@ -927,6 +1013,7 @@ I830PreInit(ScrnInfoPtr pScrn, int flags
    const char *chipname;
    int num_pipe;
    int max_width, max_height;
+   uint32_t	capid;
 
    if (pScrn->numEntities != 1)
       return FALSE;
@@ -971,8 +1058,10 @@ I830PreInit(ScrnInfoPtr pScrn, int flags
       return FALSE;
 
    pI830->PciInfo = xf86GetPciInfoForEntity(pI830->pEnt->index);
+#if !XSERVER_LIBPCIACCESS
    pI830->PciTag = pciTag(pI830->PciInfo->bus, pI830->PciInfo->device,
 			  pI830->PciInfo->func);
+#endif
 
     /* Allocate an entity private if necessary */
     if (xf86IsEntityShared(pScrn->entityList[0])) {
@@ -1061,7 +1150,7 @@ I830PreInit(ScrnInfoPtr pScrn, int flags
    /* We have to use PIO to probe, because we haven't mapped yet. */
    I830SetPIOAccess(pI830);
 
-   switch (pI830->PciInfo->chipType) {
+   switch (DEVICE_ID(pI830->PciInfo)) {
    case PCI_CHIP_I830_M:
       chipname = "830M";
       break;
@@ -1070,8 +1159,12 @@ I830PreInit(ScrnInfoPtr pScrn, int flags
       break;
    case PCI_CHIP_I855_GM:
       /* Check capid register to find the chipset variant */
-      pI830->variant = (pciReadLong(pI830->PciTag, I85X_CAPID)
-				>> I85X_VARIANT_SHIFT) & I85X_VARIANT_MASK;
+#if XSERVER_LIBPCIACCESS
+      pci_device_cfg_read_u32 (pI830->PciInfo, &capid, I85X_CAPID);
+#else
+      capid = pciReadLong (pI830->PciTag, I85X_CAPID);
+#endif
+      pI830->variant = (capid >> I85X_VARIANT_SHIFT) & I85X_VARIANT_MASK;
       switch (pI830->variant) {
       case I855_GM:
 	 chipname = "855GM";
@@ -1155,11 +1248,11 @@ I830PreInit(ScrnInfoPtr pScrn, int flags
       from = X_CONFIG;
       xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipID override: 0x%04X\n",
 		 pI830->pEnt->device->chipID);
-      pI830->PciInfo->chipType = pI830->pEnt->device->chipID;
+      DEVICE_ID(pI830->PciInfo) = pI830->pEnt->device->chipID;
    } else {
       from = X_PROBED;
       pScrn->chipset = (char *)xf86TokenToString(I830Chipsets,
-						 pI830->PciInfo->chipType);
+						 DEVICE_ID(pI830->PciInfo));
    }
 
    if (pI830->pEnt->device->chipRev >= 0) {
@@ -1170,6 +1263,13 @@ I830PreInit(ScrnInfoPtr pScrn, int flags
    xf86DrvMsg(pScrn->scrnIndex, from, "Chipset: \"%s\"\n",
 	      (pScrn->chipset != NULL) ? pScrn->chipset : "Unknown i8xx");
 
+#if XSERVER_LIBPCIACCESS
+   if (IS_I9XX(pI830))
+      pI830->fb_bar = 2;
+   else
+      pI830->fb_bar = 0;
+   pI830->LinearAddr = pI830->PciInfo->regions[pI830->fb_bar].base_addr;
+#else
    if (pI830->pEnt->device->MemBase != 0) {
       pI830->LinearAddr = pI830->pEnt->device->MemBase;
       from = X_CONFIG;
@@ -1188,10 +1288,18 @@ I830PreInit(ScrnInfoPtr pScrn, int flags
 	 return FALSE;
       }
    }
+#endif
 
    xf86DrvMsg(pScrn->scrnIndex, from, "Linear framebuffer at 0x%lX\n",
 	      (unsigned long)pI830->LinearAddr);
 
+#if XSERVER_LIBPCIACCESS
+   if (IS_I9XX(pI830))
+      pI830->mmio_bar = 0;
+   else
+      pI830->mmio_bar = 1;
+   pI830->MMIOAddr = pI830->PciInfo->regions[pI830->mmio_bar].base_addr;
+#else
    if (pI830->pEnt->device->IOBase != 0) {
       pI830->MMIOAddr = pI830->pEnt->device->IOBase;
       from = X_CONFIG;
@@ -1209,6 +1317,7 @@ I830PreInit(ScrnInfoPtr pScrn, int flags
 	 return FALSE;
       }
    }
+#endif
 
    xf86DrvMsg(pScrn->scrnIndex, from, "IO registers at addr 0x%lX\n",
 	      (unsigned long)pI830->MMIOAddr);
@@ -1232,11 +1341,19 @@ I830PreInit(ScrnInfoPtr pScrn, int flags
    xf86CrtcSetSizeRange (pScrn, 320, 200, max_width, max_height);
 
    if (IS_I830(pI830) || IS_845G(pI830)) {
+#if XSERVER_LIBPCIACCESS
+      uint16_t		gmch_ctrl;
+      struct pci_device *bridge;
+
+      bridge = intel_host_bridge ();
+      pci_device_cfg_read_u16 (bridge, &gmch_ctrl, I830_GMCH_CTRL);
+#else
       PCITAG bridge;
       CARD16 gmch_ctrl;
 
       bridge = pciTag(0, 0, 0);		/* This is always the host bridge */
       gmch_ctrl = pciReadWord(bridge, I830_GMCH_CTRL);
+#endif
       if ((gmch_ctrl & I830_GMCH_MEM_MASK) == I830_GMCH_MEM_128M) {
 	 pI830->FbMapSize = 0x8000000;
       } else {
@@ -1244,8 +1361,12 @@ I830PreInit(ScrnInfoPtr pScrn, int flags
       }
    } else {
       if (IS_I9XX(pI830)) {
+#if XSERVER_LIBPCIACCESS
+	 pI830->FbMapSize = pI830->PciInfo->regions[pI830->fb_bar].size;
+#else
 	 pI830->FbMapSize = 1UL << pciGetBaseSize(pI830->PciTag, 2, TRUE,
 						  NULL);
+#endif
       } else {
 	 /* 128MB aperture for later i8xx series. */
 	 pI830->FbMapSize = 0x8000000;
@@ -1275,7 +1396,7 @@ I830PreInit(ScrnInfoPtr pScrn, int flags
 		(1 << 23) | (2 << 16));
 #endif
 
-   if (pI830->PciInfo->chipType == PCI_CHIP_E7221_G)
+   if (DEVICE_ID(pI830->PciInfo) == PCI_CHIP_E7221_G)
       num_pipe = 1;
    else
    if (IS_MOBILE(pI830) || IS_I9XX(pI830))
diff-tree 387fed6daa7426e4a85d30ba7cf608b5f41d24bb (from 2c794192052ca55c3263e27e13d16aafe8caa92c)
Author: Keith Packard <keithp at koto.keithp.com>
Date:   Sun Aug 26 23:06:57 2007 -0700

    i810_driver.c changes for libpciaccess.
    
    This includes new probe code (intel_pci_probe) and changes for i810 to
    use BAR indices to refer to suitable portions of the device mappings.

diff --git a/src/i810_driver.c b/src/i810_driver.c
index 972b6d5..e55f942 100644
--- a/src/i810_driver.c
+++ b/src/i810_driver.c
@@ -94,7 +94,16 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN
 /* Required Functions: */
 
 static void I810Identify(int flags);
+
+#if XSERVER_LIBPCIACCESS
+static Bool intel_pci_probe (DriverPtr		drv,
+			     int		entity_num,
+			     struct pci_device	*dev,
+			     intptr_t		match_data);
+#else
 static Bool I810Probe(DriverPtr drv, int flags);
+#endif
+
 #ifndef I830_ONLY
 static Bool I810PreInit(ScrnInfoPtr pScrn, int flags);
 static Bool I810ScreenInit(int Index, ScreenPtr pScreen, int argc,
@@ -112,14 +121,59 @@ static ModeStatus I810ValidMode(int scrn
 #endif /* I830_ONLY */
 
 
+#if XSERVER_LIBPCIACCESS
+
+#define INTEL_DEVICE_MATCH(d,i) \
+    { 0x8086, (d), PCI_MATCH_ANY, PCI_MATCH_ANY, 0, 0, (i) }
+
+static const struct pci_id_match intel_device_match[] = {
+#ifndef I830_ONLY
+   INTEL_DEVICE_MATCH (PCI_CHIP_I810, 0 ),
+   INTEL_DEVICE_MATCH (PCI_CHIP_I810_DC100, 0 ),
+   INTEL_DEVICE_MATCH (PCI_CHIP_I810_E, 0 ),
+   INTEL_DEVICE_MATCH (PCI_CHIP_I815, 0 ),
+#endif
+   INTEL_DEVICE_MATCH (PCI_CHIP_I830_M, 0 ),
+   INTEL_DEVICE_MATCH (PCI_CHIP_845_G, 0 ),
+   INTEL_DEVICE_MATCH (PCI_CHIP_I855_GM, 0 ),
+   INTEL_DEVICE_MATCH (PCI_CHIP_I865_G, 0 ),
+   INTEL_DEVICE_MATCH (PCI_CHIP_I915_G, 0 ),
+   INTEL_DEVICE_MATCH (PCI_CHIP_E7221_G, 0 ),
+   INTEL_DEVICE_MATCH (PCI_CHIP_I915_GM, 0 ),
+   INTEL_DEVICE_MATCH (PCI_CHIP_I945_G, 0 ),
+   INTEL_DEVICE_MATCH (PCI_CHIP_I945_GM, 0 ),
+   INTEL_DEVICE_MATCH (PCI_CHIP_I945_GME, 0 ),
+   INTEL_DEVICE_MATCH (PCI_CHIP_I965_G, 0 ),
+   INTEL_DEVICE_MATCH (PCI_CHIP_I965_G_1, 0 ),
+   INTEL_DEVICE_MATCH (PCI_CHIP_I965_Q, 0 ),
+   INTEL_DEVICE_MATCH (PCI_CHIP_I946_GZ, 0 ),
+   INTEL_DEVICE_MATCH (PCI_CHIP_I965_GM, 0 ),
+   INTEL_DEVICE_MATCH (PCI_CHIP_I965_GME, 0 ),
+   INTEL_DEVICE_MATCH (PCI_CHIP_G33_G, 0 ),
+   INTEL_DEVICE_MATCH (PCI_CHIP_Q35_G, 0 ),
+   INTEL_DEVICE_MATCH (PCI_CHIP_Q33_G, 0 ),
+    { 0, 0, 0 },
+};
+
+#endif /* XSERVER_LIBPCIACCESS */
+
 _X_EXPORT DriverRec I810 = {
    I810_VERSION,
    I810_DRIVER_NAME,
    I810Identify,
+#if XSERVER_LIBPCIACCESS
+   NULL,
+#else
    I810Probe,
+#endif
    I810AvailableOptions,
    NULL,
-   0
+   0,
+   NULL,
+#if XSERVER_LIBPCIACCESS
+   intel_device_match,
+   intel_pci_probe
+#endif
 };
 
 /* *INDENT-OFF* */
@@ -429,7 +483,13 @@ i810Setup(pointer module, pointer opts, 
     */
    if (!setupDone) {
       setupDone = 1;
-      xf86AddDriver(&I810, module, 0);
+      xf86AddDriver(&I810, module,
+#if XSERVER_LIBPCIACCESS
+		    HaveDriverFuncs
+#else
+		    0
+#endif
+		    );
 
       /*
        * Tell the loader about symbols from other modules that this module
@@ -517,6 +577,113 @@ I810AvailableOptions(int chipid, int bus
 #endif
 }
 
+#if XSERVER_LIBPCIACCESS
+struct pci_device *
+intel_host_bridge (void)
+{
+    static const struct pci_slot_match bridge_match = {
+	0, 0, 0, PCI_MATCH_ANY, 0
+    };
+    struct pci_device_iterator	*slot_iterator;
+    struct pci_device		*bridge;
+
+    slot_iterator = pci_slot_match_iterator_create (&bridge_match);
+    bridge = pci_device_next (slot_iterator);
+    pci_iterator_destroy (slot_iterator);
+    return bridge;
+}
+
+/*
+ * intel_pci_probe --
+ *
+ * Look through the PCI bus to find cards that are intel boards.
+ * Setup the dispatch table for the rest of the driver functions.
+ *
+ */
+static Bool intel_pci_probe (DriverPtr		driver,
+			     int		entity_num,
+			     struct pci_device	*device,
+			     intptr_t		match_data)
+{
+    ScrnInfoPtr	    scrn = NULL;
+    EntityInfoPtr   entity;
+    I830EntPtr	    i830_ent = NULL;
+    DevUnion	    *private;
+
+    scrn = xf86ConfigPciEntity (scrn, 0, entity_num, I810PciChipsets,
+				NULL,
+				NULL, NULL, NULL, NULL);
+    if (scrn != NULL)
+    {
+	scrn->driverVersion = I810_VERSION;
+	scrn->driverName = I810_DRIVER_NAME;
+	scrn->name = I810_NAME;
+	scrn->Probe = NULL;
+
+	entity = xf86GetEntityInfo (entity_num);
+	
+	switch (DEVICE_ID(device)) {
+#ifndef I830_ONLY
+	case PCI_CHIP_I810:
+	case PCI_CHIP_I810_DC100:
+	case PCI_CHIP_I810_E:
+	case PCI_CHIP_I815:
+	    scrn->PreInit = I810PreInit;
+	    scrn->ScreenInit = I810ScreenInit;
+	    scrn->SwitchMode = I810SwitchMode;
+	    scrn->AdjustFrame = I810AdjustFrame;
+	    scrn->EnterVT = I810EnterVT;
+	    scrn->LeaveVT = I810LeaveVT;
+	    scrn->FreeScreen = I810FreeScreen;
+	    scrn->ValidMode = I810ValidMode;
+	    break;
+#endif
+	case PCI_CHIP_845_G:
+	case PCI_CHIP_I865_G:
+	    /*
+	     * These two chips have only one pipe, and
+	     * cannot do dual-head
+	     */
+	    I830InitpScrn(scrn);
+	    break;
+	default:
+	    /*
+	     * Everything else is an i830-ish dual-pipe chip
+	     */
+	    xf86SetEntitySharable(entity_num);
+
+	    /* Allocate an entity private if necessary */		
+	    if (I830EntityIndex < 0)					
+		I830EntityIndex = xf86AllocateEntityPrivateIndex();	
+
+	    private = xf86GetEntityPrivate(scrn->entityList[0],
+					   I830EntityIndex);	
+	    i830_ent = private->ptr;
+	    if (!i830_ent)
+	    {
+		private->ptr = xnfcalloc(sizeof(I830EntRec), 1);
+		i830_ent = private->ptr;
+		i830_ent->lastInstance = -1;
+	    }
+
+	    /*
+	     * 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".
+	     */
+	    i830_ent->lastInstance++;
+	    xf86SetEntityInstanceForScreen(scrn,			
+					   scrn->entityList[0],
+					   i830_ent->lastInstance);	
+	    I830InitpScrn(scrn);
+	    break;
+	}
+    }
+    return scrn != NULL;
+}
+#else /* XSERVER_LIBPCIACCESS */
+
 /*
  * I810Probe --
  *
@@ -678,6 +845,7 @@ I810Probe(DriverPtr drv, int flags)
 
    return foundScreen;
 }
+#endif /* else XSERVER_LIBPCIACCESS */
 
 #ifndef I830_ONLY
 static void
@@ -769,8 +937,10 @@ I810PreInit(ScrnInfoPtr pScrn, int flags
    pI810->ioBase = hwp->PIOOffset;
 
    pI810->PciInfo = xf86GetPciInfoForEntity(pI810->pEnt->index);
+#if !XSERVER_LIBPCIACCESS
    pI810->PciTag = pciTag(pI810->PciInfo->bus, pI810->PciInfo->device,
 			  pI810->PciInfo->func);
+#endif
 
    if (xf86RegisterResources(pI810->pEnt->index, NULL, ResNone))
       return FALSE;
@@ -899,7 +1069,7 @@ I810PreInit(ScrnInfoPtr pScrn, int flags
    } else {
       from = X_PROBED;
       pScrn->chipset = (char *)xf86TokenToString(I810Chipsets,
-						 pI810->PciInfo->chipType);
+						 DEVICE_ID(pI810->PciInfo));
    }
    if (pI810->pEnt->device->chipRev >= 0) {
       xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipRev override: %d\n",
@@ -909,6 +1079,10 @@ I810PreInit(ScrnInfoPtr pScrn, int flags
    xf86DrvMsg(pScrn->scrnIndex, from, "Chipset: \"%s\"\n",
 	      (pScrn->chipset != NULL) ? pScrn->chipset : "Unknown i810");
 
+#if XSERVER_LIBPCIACCESS
+   pI810->fb_bar = 0;
+   pI810->LinearAddr = pI810->PciInfo->regions[pI810->fb_bar].base_addr;
+#else
    if (pI810->pEnt->device->MemBase != 0) {
       pI810->LinearAddr = pI810->pEnt->device->MemBase;
       from = X_CONFIG;
@@ -923,9 +1097,14 @@ I810PreInit(ScrnInfoPtr pScrn, int flags
 	 return FALSE;
       }
    }
+#endif
    xf86DrvMsg(pScrn->scrnIndex, from, "Linear framebuffer at 0x%lX\n",
 	      (unsigned long)pI810->LinearAddr);
 
+#if XSERVER_LIBPCIACCESS
+   pI810->mmio_bar = 1;
+   pI810->MMIOAddr = pI810->PciInfo->regions[pI810->mmio_bar].base_addr;
+#else
    if (pI810->pEnt->device->IOBase != 0) {
       pI810->MMIOAddr = pI810->pEnt->device->IOBase;
       from = X_CONFIG;
@@ -940,6 +1119,7 @@ I810PreInit(ScrnInfoPtr pScrn, int flags
 	 return FALSE;
       }
    }
+#endif
    xf86DrvMsg(pScrn->scrnIndex, from, "IO registers at addr 0x%lX\n",
 	      (unsigned long)pI810->MMIOAddr);
 
@@ -956,8 +1136,13 @@ I810PreInit(ScrnInfoPtr pScrn, int flags
    /* Find out memory bus frequency.
     */
    {
-      unsigned long whtcfg_pamr_drp = pciReadLong(pI810->PciTag,
-						  WHTCFG_PAMR_DRP);
+      uint32_t whtcfg_pamr_drp;
+    
+#if XSERVER_LIBPCIACCESS
+      pci_device_cfg_read_u32(pI810->PciInfo, & whtcfg_pamr_drp, WHTCFG_PAMR_DRP);
+#else
+      whtcfg_pamr_drp = pciReadLong(pI810->PciTag, WHTCFG_PAMR_DRP);
+#endif
 
       /* Need this for choosing watermarks.
        */
@@ -1010,11 +1195,19 @@ I810PreInit(ScrnInfoPtr pScrn, int flags
 
    /* Calculate Fixed Offsets depending on graphics aperture size */
    {
+#if XSERVER_LIBPCIACCESS
+      struct pci_device *bridge = intel_host_bridge ();
+      uint32_t   smram_miscc;
+      
+      pci_device_cfg_read_u32 (bridge, & smram_miscc, SMRAM_MISCC);
+#else
       PCITAG bridge;
       long smram_miscc;
 
       bridge = pciTag(0, 0, 0);		/* This is always the host bridge */
       smram_miscc = pciReadLong(bridge, SMRAM_MISCC);
+#endif
+
       if ((smram_miscc & GFX_MEM_WIN_SIZE) == GFX_MEM_WIN_32M) {
 	 pI810->FbMapSize = 0x1000000;
 	 pI810->DepthOffset = 0x1000000;
@@ -1204,6 +1397,10 @@ I810MapMMIO(ScrnInfoPtr pScrn)
 {
    int mmioFlags;
    I810Ptr pI810 = I810PTR(pScrn);
+#if XSERVER_LIBPCIACCESS
+   struct pci_device *const device = pI810->PciInfo;
+   int err;
+#endif
 
 #if !defined(__alpha__)
    mmioFlags = VIDMEM_MMIO | VIDMEM_READSIDEEFFECT;
@@ -1211,11 +1408,23 @@ I810MapMMIO(ScrnInfoPtr pScrn)
    mmioFlags = VIDMEM_MMIO | VIDMEM_READSIDEEFFECT | VIDMEM_SPARSE;
 #endif
 
+#if XSERVER_LIBPCIACCESS
+   err = pci_device_map_region (device, pI810->mmio_bar, TRUE);
+   if (err) 
+   {
+      xf86DrvMsg (pScrn->scrnIndex, X_ERROR,
+		  "Unable to map mmio BAR. %s (%d)\n",
+		  strerror (err), err);
+      return FALSE;
+   }
+   pI810->MMIOBase = device->regions[pI810->mmio_bar].memory;
+#else
    pI810->MMIOBase = xf86MapPciMem(pScrn->scrnIndex, mmioFlags,
 				   pI810->PciTag,
 				   pI810->MMIOAddr, I810_REG_SIZE);
    if (!pI810->MMIOBase)
       return FALSE;
+#endif
    return TRUE;
 }
 
@@ -1224,17 +1433,34 @@ I810MapMem(ScrnInfoPtr pScrn)
 {
    I810Ptr pI810 = I810PTR(pScrn);
    long i;
+#if XSERVER_LIBPCIACCESS
+   struct pci_device *const device = pI810->PciInfo;
+   int err;
+#endif
 
    for (i = 2; i < pI810->FbMapSize; i <<= 1) ;
 
    if (!I810MapMMIO(pScrn))
       return FALSE;
 
+#if XSERVER_LIBPCIACCESS
+   err = pci_device_map_region (device, pI810->fb_bar, TRUE);
+   if (err) 
+   {
+      xf86DrvMsg (pScrn->scrnIndex, X_ERROR,
+		  "Unable to map frame buffer BAR. %s (%d)\n",
+		  strerror (err), err);
+      return FALSE;
+   }
+   pI810->FbBase = device->regions[pI810->fb_bar].memory;
+   pI810->FbMapSize = device->regions[pI810->fb_bar].size;
+#else
    pI810->FbBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_FRAMEBUFFER,
 				 pI810->PciTag,
 				 pI810->LinearAddr, i);
    if (!pI810->FbBase)
       return FALSE;
+#endif
 
    pI810->LpRing->virtual_start = pI810->FbBase + pI810->LpRing->mem.Start;
 
@@ -1246,8 +1472,12 @@ I810UnmapMMIO(ScrnInfoPtr pScrn)
 {
    I810Ptr pI810 = I810PTR(pScrn);
 
+#if XSERVER_LIBPCIACCESS
+   pci_device_unmap_region (pI810->PciInfo, pI810->mmio_bar);
+#else
    xf86UnMapVidMem(pScrn->scrnIndex, (pointer) pI810->MMIOBase,
 		   I810_REG_SIZE);
+#endif
    pI810->MMIOBase = NULL;
 }
 
@@ -1256,8 +1486,12 @@ I810UnmapMem(ScrnInfoPtr pScrn)
 {
    I810Ptr pI810 = I810PTR(pScrn);
 
+#if XSERVER_LIBPCIACCESS
+   pci_device_unmap_region (pI810->PciInfo, pI810->fb_bar);
+#else
    xf86UnMapVidMem(pScrn->scrnIndex, (pointer) pI810->FbBase,
 		   pI810->FbMapSize);
+#endif
    pI810->FbBase = NULL;
    I810UnmapMMIO(pScrn);
    return TRUE;
diff-tree 2c794192052ca55c3263e27e13d16aafe8caa92c (from 70e8e5957200401474967a467663ae049e9080f2)
Author: Keith Packard <keithp at koto.keithp.com>
Date:   Sun Aug 26 22:46:19 2007 -0700

    Mechanical API conversions for libpciaccess.
    
    Uncomplicated API transistions for libpciaccess usage:
    
    	Legacy xf86 API		libpciaccess API
    	---------------		----------------
    	xf86ReadPciBIOS 	pci_device_read_rom
    	pciReadWord 		pci_device_cfg_read_u16
    	pciWriteByte 		pci_device_cfg_write_u8
    
    And, more use of the API-independent DEVICE_ID/SUBVENDOR_ID/SUBSYS_ID macros
    to pull PCI identification data from the underlying structure.

diff --git a/src/i830_bios.c b/src/i830_bios.c
index 7703c80..7ed791e 100644
--- a/src/i830_bios.c
+++ b/src/i830_bios.c
@@ -97,7 +97,11 @@ i830_bios_get (ScrnInfoPtr pScrn)
 	       INTEL_VBIOS_SIZE);
 	vbeFree (pVbe);
     } else {
+#if XSERVER_LIBPCIACCESS
+	pci_device_read_rom (pI830->PciInfo, bios);
+#else
 	xf86ReadPciBIOS(0, pI830->PciTag, 0, bios, INTEL_VBIOS_SIZE);
+#endif
     }
 
     if (0)
diff --git a/src/i830_display.c b/src/i830_display.c
index 0ab0de7..d8be8d9 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -868,9 +868,14 @@ i830_get_core_clock_speed(ScrnInfoPtr pS
     else if (IS_I945GM(pI830) || IS_845G(pI830))
 	return 200000;
     else if (IS_I915GM(pI830)) {
-	CARD16 gcfgc = pciReadWord(pI830->PciTag, I915_GCFGC);
+	uint16_t gcfgc;
 
-	if (gcfgc & I915_LOW_FREQUENCY_ENABLE)
+#if XSERVER_LIBPCIACCESS
+      pci_device_cfg_read_u16 (pI830->PciInfo, &gcfgc, I915_GCFGC);
+#else
+      gcfgc = pciReadWord(pI830->PciTag, I915_GCFGC);
+#endif
+      if (gcfgc & I915_LOW_FREQUENCY_ENABLE)
 	    return 133000;
 	else {
 	    switch (gcfgc & I915_DISPLAY_CLOCK_MASK) {
@@ -884,8 +889,14 @@ i830_get_core_clock_speed(ScrnInfoPtr pS
     } else if (IS_I865G(pI830))
 	return 266000;
     else if (IS_I855(pI830)) {
+#if XSERVER_LIBPCIACCESS
+        struct pci_device *bridge = intel_host_bridge ();
+	uint16_t hpllcc;
+	pci_device_cfg_read_u16 (bridge, &hpllcc, I855_HPLLCC);
+#else
 	PCITAG bridge = pciTag(0, 0, 0); /* This is always the host bridge */
 	CARD16 hpllcc = pciReadWord(bridge, I855_HPLLCC);
+#endif
 
 	/* Assume that the hardware is in the high speed state.  This
 	 * should be the default.
diff --git a/src/i830_lvds.c b/src/i830_lvds.c
index 18e5c2b..0b6b192 100644
--- a/src/i830_lvds.c
+++ b/src/i830_lvds.c
@@ -84,7 +84,11 @@ i830_lvds_set_backlight(xf86OutputPtr ou
     CARD32 blc_pwm_ctl;
 
     if (i830_lvds_backlight_legacy(pI830))
+#if XSERVER_LIBPCIACCESS
+	pci_device_cfg_write_u8 (pI830->PciInfo, 0xfe, LEGACY_BACKLIGHT_BRIGHTNESS);
+#else
 	pciWriteByte(pI830->PciTag, LEGACY_BACKLIGHT_BRIGHTNESS, 0xfe);
+#endif
 
     blc_pwm_ctl = INREG(BLC_PWM_CTL);
     blc_pwm_ctl &= ~BACKLIGHT_DUTY_CYCLE_MASK;
diff --git a/src/i830_quirks.c b/src/i830_quirks.c
index fb10570..28b8ff9 100644
--- a/src/i830_quirks.c
+++ b/src/i830_quirks.c
@@ -84,9 +84,9 @@ void i830_fixup_devices(ScrnInfoPtr scrn
     i830_quirk_ptr p = i830_quirk_list;
 
     while (p && p->chipType != 0) {
-	if (pI830->PciInfo->chipType == p->chipType &&
-		pI830->PciInfo->subsysVendor == p->subsysVendor &&
-		(pI830->PciInfo->subsysCard == p->subsysCard ||
+	if (DEVICE_ID(pI830->PciInfo) == p->chipType &&
+		SUBVENDOR_ID(pI830->PciInfo) == p->subsysVendor &&
+		(SUBSYS_ID(pI830->PciInfo) == p->subsysCard ||
 		 p->subsysCard == SUBSYS_ANY))
 	    p->hook(pI830);
 	++p;
diff --git a/src/i830_tv.c b/src/i830_tv.c
index a77bf98..c90d41e 100644
--- a/src/i830_tv.c
+++ b/src/i830_tv.c
@@ -1138,7 +1138,7 @@ i830_tv_mode_set(xf86OutputPtr output, D
 	tv_mode->dda3_inc << TV_SCDDA3_INC_SHIFT;
 
     /* Enable two fixes for the chips that need them. */
-    if (pI830->PciInfo->chipType < PCI_CHIP_I945_G)
+    if (DEVICE_ID(pI830->PciInfo) < PCI_CHIP_I945_G)
 	tv_ctl |= TV_ENC_C0_FIX | TV_ENC_SDP_FIX;
 
     OUTREG(TV_H_CTL_1, hctl1);
diff-tree 70e8e5957200401474967a467663ae049e9080f2 (from 5516cc781bd488c936af225123812a61ed5874b8)
Author: Keith Packard <keithp at koto.keithp.com>
Date:   Sun Aug 26 22:40:25 2007 -0700

    Change DRI interface to fill in PCI data from new libpciaccess structure.
    
    The DRI interface requires bus identification for each DRI object; pull that
    data from the libpciaccess structures as necessary.

diff --git a/src/i810_dri.c b/src/i810_dri.c
index 72718d3..e5e1565 100644
--- a/src/i810_dri.c
+++ b/src/i810_dri.c
@@ -354,9 +354,15 @@ I810DRIScreenInit(ScreenPtr pScreen)
    } else {
       pDRIInfo->busIdString = xalloc(64);
       sprintf(pDRIInfo->busIdString, "PCI:%d:%d:%d",
+#if XSERVER_LIBPCIACCESS
+	      ((pI810->PciInfo->domain << 8) | pI810->PciInfo->bus),
+	      pI810->PciInfo->dev, pI810->PciInfo->func
+#else
 	      ((pciConfigPtr) pI810->PciInfo->thisCard)->busnum,
 	      ((pciConfigPtr) pI810->PciInfo->thisCard)->devnum,
-	      ((pciConfigPtr) pI810->PciInfo->thisCard)->funcnum);
+	      ((pciConfigPtr) pI810->PciInfo->thisCard)->funcnum
+#endif
+	      );
    }
    pDRIInfo->ddxDriverMajorVersion = I810_MAJOR_VERSION;
    pDRIInfo->ddxDriverMinorVersion = I810_MINOR_VERSION;
@@ -972,12 +978,20 @@ I810DRIScreenInit(ScreenPtr pScreen)
 
    if (!pI810DRI->irq) {
       pI810DRI->irq = drmGetInterruptFromBusID(pI810->drmSubFD,
+#if XSERVER_LIBPCIACCESS
+					       ((pI810->PciInfo->domain << 8) |
+						pI810->PciInfo->bus),
+					       pI810->PciInfo->dev,
+					       pI810->PciInfo->func
+#else
 					       ((pciConfigPtr) pI810->
 						PciInfo->thisCard)->busnum,
 					       ((pciConfigPtr) pI810->
 						PciInfo->thisCard)->devnum,
 					       ((pciConfigPtr) pI810->
-						PciInfo->thisCard)->funcnum);
+						PciInfo->thisCard)->funcnum
+#endif
+					       );
       if ((drmCtlInstHandler(pI810->drmSubFD, pI810DRI->irq)) != 0) {
 	 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
 		    "[drm] failure adding irq handler, there is a device "
@@ -991,7 +1005,7 @@ I810DRIScreenInit(ScreenPtr pScreen)
    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
 	      "[drm] dma control initialized, using IRQ %d\n", pI810DRI->irq);
 
-   pI810DRI->deviceID = pI810->PciInfo->chipType;
+   pI810DRI->deviceID = DEVICE_ID(pI810->PciInfo);
    pI810DRI->width = pScrn->virtualX;
    pI810DRI->height = pScrn->virtualY;
    pI810DRI->mem = pScrn->videoRam * 1024;
diff --git a/src/i830_dri.c b/src/i830_dri.c
index e2b42b4..32f6510 100644
--- a/src/i830_dri.c
+++ b/src/i830_dri.c
@@ -539,9 +539,15 @@ I830DRIScreenInit(ScreenPtr pScreen)
    } else {
       pDRIInfo->busIdString = xalloc(64);
       sprintf(pDRIInfo->busIdString, "PCI:%d:%d:%d",
+#if XSERVER_LIBPCIACCESS
+	      ((pI830->PciInfo->domain << 8) | pI830->PciInfo->bus),
+	      pI830->PciInfo->dev, pI830->PciInfo->func
+#else
 	      ((pciConfigPtr) pI830->PciInfo->thisCard)->busnum,
 	      ((pciConfigPtr) pI830->PciInfo->thisCard)->devnum,
-	      ((pciConfigPtr) pI830->PciInfo->thisCard)->funcnum);
+	      ((pciConfigPtr) pI830->PciInfo->thisCard)->funcnum
+#endif
+	      );
    }
    pDRIInfo->ddxDriverMajorVersion = I830_MAJOR_VERSION;
    pDRIInfo->ddxDriverMinorVersion = I830_MINOR_VERSION;
@@ -978,13 +984,13 @@ I830DRIDoMappings(ScreenPtr pScreen)
       return FALSE;
    }
 
-   if (pI830->PciInfo->chipType != PCI_CHIP_845_G &&
-       pI830->PciInfo->chipType != PCI_CHIP_I830_M) {
+   if (DEVICE_ID(pI830->PciInfo) != PCI_CHIP_845_G &&
+       DEVICE_ID(pI830->PciInfo) != PCI_CHIP_I830_M) {
       I830SetParam(pScrn, I830_SETPARAM_USE_MI_BATCHBUFFER_START, 1 );
    }
 
    pI830DRI = (I830DRIPtr) pI830->pDRIInfo->devPrivate;
-   pI830DRI->deviceID = pI830->PciInfo->chipType;
+   pI830DRI->deviceID = DEVICE_ID(pI830->PciInfo);
    pI830DRI->width = pScrn->virtualX;
    pI830DRI->height = pScrn->virtualY;
    pI830DRI->mem = pScrn->videoRam * 1024;
@@ -1020,12 +1026,20 @@ I830DRIResume(ScreenPtr pScreen)
 
    {
       pI830DRI->irq = drmGetInterruptFromBusID(pI830->drmSubFD,
+#if XSERVER_LIBPCIACCESS
+					       ((pI830->PciInfo->domain << 8) |
+						pI830->PciInfo->bus),
+					       pI830->PciInfo->dev,
+					       pI830->PciInfo->func
+#else
 					       ((pciConfigPtr) pI830->
 						PciInfo->thisCard)->busnum,
 					       ((pciConfigPtr) pI830->
 						PciInfo->thisCard)->devnum,
 					       ((pciConfigPtr) pI830->
-						PciInfo->thisCard)->funcnum);
+						PciInfo->thisCard)->funcnum
+#endif
+					       );
 
       if (drmCtlInstHandler(pI830->drmSubFD, pI830DRI->irq)) {
 	 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
@@ -1108,12 +1122,20 @@ I830DRIFinishScreenInit(ScreenPtr pScree
       I830DRIPtr pI830DRI = (I830DRIPtr) pI830->pDRIInfo->devPrivate;
 
       pI830DRI->irq = drmGetInterruptFromBusID(pI830->drmSubFD,
+#if XSERVER_LIBPCIACCESS
+					       ((pI830->PciInfo->domain << 8) |
+						pI830->PciInfo->bus),
+					       pI830->PciInfo->dev,
+					       pI830->PciInfo->func
+#else
 					       ((pciConfigPtr) pI830->
 						PciInfo->thisCard)->busnum,
 					       ((pciConfigPtr) pI830->
 						PciInfo->thisCard)->devnum,
 					       ((pciConfigPtr) pI830->
-						PciInfo->thisCard)->funcnum);
+						PciInfo->thisCard)->funcnum
+#endif
+					       );
 
       if (drmCtlInstHandler(pI830->drmSubFD, pI830DRI->irq)) {
 	 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
diff-tree 5516cc781bd488c936af225123812a61ed5874b8 (from daada59b5f8c2294b524a4b5920dc6b1c213642f)
Author: Keith Packard <keithp at koto.keithp.com>
Date:   Sun Aug 26 22:37:38 2007 -0700

    Add libpciaccess declarations to I810Rec and I830Rec.
    
    Using libpciaccess requires a different type for PciInfo (struct pci_device
    instead of pciVideoPtr) and it requires knowing which BAR each memory region
    needs to be mapped from. Add these definitions to the driver private record
    along with the includes necessary to use libpciaccess.

diff --git a/src/i810.h b/src/i810.h
index ff9134e..2031408 100644
--- a/src/i810.h
+++ b/src/i810.h
@@ -50,6 +50,11 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN
 #include "vbe.h"
 #include "vgaHW.h"
 
+#include "xorg-server.h"
+#ifdef XSERVER_LIBPCIACCESS
+#include <pciaccess.h>
+#endif
+
 #ifdef XF86DRI
 #include "xf86drm.h"
 #include "sarea.h"
@@ -184,8 +189,14 @@ typedef struct _I810Rec {
    unsigned long MMIOAddr;
    IOADDRESS ioBase;
    EntityInfoPtr pEnt;
+#if XSERVER_LIBPCIACCESS
+   int mmio_bar;
+   int fb_bar;
+   struct pci_device *PciInfo;
+#else
    pciVideoPtr PciInfo;
    PCITAG PciTag;
+#endif
 
    I810RingBuffer *LpRing;
    unsigned int BR[20];
diff --git a/src/i830.h b/src/i830.h
index b0c8f0f..4f176f8 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -61,6 +61,11 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN
 #include "xf86Crtc.h"
 #include "xf86RandR12.h"
 
+#include "xorg-server.h"
+#ifdef XSERVER_LIBPCIACCESS
+#include <pciaccess.h>
+#endif
+
 #ifdef XF86DRI
 #include "xf86drm.h"
 #include "sarea.h"
@@ -360,8 +365,15 @@ typedef struct _I830Rec {
    unsigned long MMIOAddr;
    IOADDRESS ioBase;
    EntityInfoPtr pEnt;
+#if XSERVER_LIBPCIACCESS
+   struct pci_device *PciInfo;
+   int mmio_bar;
+   int fb_bar;
+   int gtt_bar;
+#else
    pciVideoPtr PciInfo;
    PCITAG PciTag;
+#endif
    CARD8 variant;
 
    unsigned int BR[20];
diff-tree daada59b5f8c2294b524a4b5920dc6b1c213642f (from 3d3bf493a3973f4067433d27a4d7ddfecaa18f1c)
Author: Keith Packard <keithp at koto.keithp.com>
Date:   Sun Aug 26 22:32:39 2007 -0700

    Change IS_Ixxx tests to work with or without libpciaccess.
    
    libpciaccess has a new structure that holds the PCI identifier data; borrow
    macros from the mga driver to work with either the old xf86-specific
    structure or the new libpciaccess structure.

diff --git a/src/common.h b/src/common.h
index fa96a5d..cfe00fc 100644
--- a/src/common.h
+++ b/src/common.h
@@ -384,26 +384,42 @@ extern int I810_DEBUG;
 #define PCI_CHIP_Q33_G_BRIDGE 	0x29D0
 #endif
 
-#define IS_I810(pI810) (pI810->PciInfo->chipType == PCI_CHIP_I810 ||	\
-			pI810->PciInfo->chipType == PCI_CHIP_I810_DC100 || \
-			pI810->PciInfo->chipType == PCI_CHIP_I810_E)
-#define IS_I815(pI810) (pI810->PciInfo->chipType == PCI_CHIP_I815)
-#define IS_I830(pI810) (pI810->PciInfo->chipType == PCI_CHIP_I830_M)
-#define IS_845G(pI810) (pI810->PciInfo->chipType == PCI_CHIP_845_G)
-#define IS_I85X(pI810)  (pI810->PciInfo->chipType == PCI_CHIP_I855_GM)
-#define IS_I852(pI810)  (pI810->PciInfo->chipType == PCI_CHIP_I855_GM && (pI810->variant == I852_GM || pI810->variant == I852_GME))
-#define IS_I855(pI810)  (pI810->PciInfo->chipType == PCI_CHIP_I855_GM && (pI810->variant == I855_GM || pI810->variant == I855_GME))
-#define IS_I865G(pI810) (pI810->PciInfo->chipType == PCI_CHIP_I865_G)
-
-#define IS_I915G(pI810) (pI810->PciInfo->chipType == PCI_CHIP_I915_G || pI810->PciInfo->chipType == PCI_CHIP_E7221_G)
-#define IS_I915GM(pI810) (pI810->PciInfo->chipType == PCI_CHIP_I915_GM)
-#define IS_I945G(pI810) (pI810->PciInfo->chipType == PCI_CHIP_I945_G)
-#define IS_I945GM(pI810) (pI810->PciInfo->chipType == PCI_CHIP_I945_GM || pI810->PciInfo->chipType == PCI_CHIP_I945_GME)
-#define IS_I965GM(pI810) (pI810->PciInfo->chipType == PCI_CHIP_I965_GM || pI810->PciInfo->chipType == PCI_CHIP_I965_GME)
-#define IS_I965G(pI810) (pI810->PciInfo->chipType == PCI_CHIP_I965_G || pI810->PciInfo->chipType == PCI_CHIP_I965_G_1 || pI810->PciInfo->chipType == PCI_CHIP_I965_Q || pI810->PciInfo->chipType == PCI_CHIP_I946_GZ || pI810->PciInfo->chipType == PCI_CHIP_I965_GM || pI810->PciInfo->chipType == PCI_CHIP_I965_GME)
-#define IS_G33CLASS(pI810) (pI810->PciInfo->chipType == PCI_CHIP_G33_G ||\
- 			    pI810->PciInfo->chipType == PCI_CHIP_Q35_G ||\
- 			    pI810->PciInfo->chipType == PCI_CHIP_Q33_G)
+#if XSERVER_LIBPCIACCESS
+#define I810_MEMBASE(p,n) (p)->regions[(n)].base_addr
+#define VENDOR_ID(p)      (p)->vendor_id
+#define DEVICE_ID(p)      (p)->device_id
+#define SUBVENDOR_ID(p)	  (p)->subvendor_id
+#define SUBSYS_ID(p)      (p)->subdevice_id
+#define CHIP_REVISION(p)  (p)->revision
+#else
+#define I810_MEMBASE(p,n) (p)->memBase[n]
+#define VENDOR_ID(p)      (p)->vendor
+#define DEVICE_ID(p)      (p)->chipType
+#define SUBVENDOR_ID(p)	  (p)->subsysVendor
+#define SUBSYS_ID(p)      (p)->subsysCard
+#define CHIP_REVISION(p)  (p)->chipRev
+#endif
+
+#define IS_I810(pI810) (DEVICE_ID(pI810->PciInfo) == PCI_CHIP_I810 ||	\
+			DEVICE_ID(pI810->PciInfo) == PCI_CHIP_I810_DC100 || \
+			DEVICE_ID(pI810->PciInfo) == PCI_CHIP_I810_E)
+#define IS_I815(pI810) (DEVICE_ID(pI810->PciInfo) == PCI_CHIP_I815)
+#define IS_I830(pI810) (DEVICE_ID(pI810->PciInfo) == PCI_CHIP_I830_M)
+#define IS_845G(pI810) (DEVICE_ID(pI810->PciInfo) == PCI_CHIP_845_G)
+#define IS_I85X(pI810)  (DEVICE_ID(pI810->PciInfo) == PCI_CHIP_I855_GM)
+#define IS_I852(pI810)  (DEVICE_ID(pI810->PciInfo) == PCI_CHIP_I855_GM && (pI810->variant == I852_GM || pI810->variant == I852_GME))
+#define IS_I855(pI810)  (DEVICE_ID(pI810->PciInfo) == PCI_CHIP_I855_GM && (pI810->variant == I855_GM || pI810->variant == I855_GME))
+#define IS_I865G(pI810) (DEVICE_ID(pI810->PciInfo) == PCI_CHIP_I865_G)
+
+#define IS_I915G(pI810) (DEVICE_ID(pI810->PciInfo) == PCI_CHIP_I915_G || DEVICE_ID(pI810->PciInfo) == PCI_CHIP_E7221_G)
+#define IS_I915GM(pI810) (DEVICE_ID(pI810->PciInfo) == PCI_CHIP_I915_GM)
+#define IS_I945G(pI810) (DEVICE_ID(pI810->PciInfo) == PCI_CHIP_I945_G)
+#define IS_I945GM(pI810) (DEVICE_ID(pI810->PciInfo) == PCI_CHIP_I945_GM || DEVICE_ID(pI810->PciInfo) == PCI_CHIP_I945_GME)
+#define IS_I965GM(pI810) (DEVICE_ID(pI810->PciInfo) == PCI_CHIP_I965_GM || DEVICE_ID(pI810->PciInfo) == PCI_CHIP_I965_GME)
+#define IS_I965G(pI810) (DEVICE_ID(pI810->PciInfo) == PCI_CHIP_I965_G || DEVICE_ID(pI810->PciInfo) == PCI_CHIP_I965_G_1 || DEVICE_ID(pI810->PciInfo) == PCI_CHIP_I965_Q || DEVICE_ID(pI810->PciInfo) == PCI_CHIP_I946_GZ || DEVICE_ID(pI810->PciInfo) == PCI_CHIP_I965_GM || DEVICE_ID(pI810->PciInfo) == PCI_CHIP_I965_GME)
+#define IS_G33CLASS(pI810) (DEVICE_ID(pI810->PciInfo) == PCI_CHIP_G33_G ||\
+ 			    DEVICE_ID(pI810->PciInfo) == PCI_CHIP_Q35_G ||\
+ 			    DEVICE_ID(pI810->PciInfo) == PCI_CHIP_Q33_G)
 #define IS_I9XX(pI810) (IS_I915G(pI810) || IS_I915GM(pI810) || IS_I945G(pI810) || IS_I945GM(pI810) || IS_I965G(pI810) || IS_G33CLASS(pI810))
 
 #define IS_MOBILE(pI810) (IS_I830(pI810) || IS_I85X(pI810) || IS_I915GM(pI810) || IS_I945GM(pI810) || IS_I965GM(pI810))
@@ -428,4 +444,7 @@ extern int I810_DEBUG;
 
 #define PIPE_NAME(n)			('A' + (n))
 
+struct pci_device *
+intel_host_bridge (void);
+   
 #endif /* _INTEL_COMMON_H_ */
diff-tree 3d3bf493a3973f4067433d27a4d7ddfecaa18f1c (from 5faf9cc6afe1c30fa88bc6446088a6fa47fc5d0b)
Author: Keith Packard <keithp at koto.keithp.com>
Date:   Sun Aug 26 22:27:34 2007 -0700

    Intel driver configuration (only) changes for X server libpciaccess usage.
    
    Detect whether the target X server uses libpciaccess, using it in the driver
    compilation as necessary. This change means that utilities that used to use
    libpciaccess will not do so unless the driver itself uses libpciaccess. Yes,
    that could be fixed, but it doesn't seem that important.
    
    This patch does not include any code changes necessary to actually have the
    driver build against an X server using libpciaccess.

diff --git a/configure.ac b/configure.ac
index 8c2b5ec..1c7ad04 100644
--- a/configure.ac
+++ b/configure.ac
@@ -78,9 +78,6 @@ XORG_DRIVER_CHECK_EXT(DPMSExtension, xex
 PKG_CHECK_MODULES(XORG, [xorg-server xproto xvmc fontsproto $REQUIRED_MODULES])
 sdkdir=$(pkg-config --variable=sdkdir xorg-server)
 
-PKG_CHECK_MODULES([PCIACCESS], [pciaccess >= 0.5.0], have_pciaccess=yes, have_pciaccess=no)
-AM_CONDITIONAL(HAVE_PCIACCESS, test "x$have_pciaccess" = xyes)
-
 # Checks for libraries.
 
 # Checks for header files.
@@ -112,8 +109,16 @@ AC_MSG_RESULT([$DRI])
 save_CFLAGS="$CFLAGS"
 CFLAGS="$XORG_CFLAGS"
 AC_CHECK_HEADER(xf86Modes.h,[XMODES=yes],[XMODES=no],[#include "xorg-server.h"])
+AC_CHECK_DECL(XSERVER_LIBPCIACCESS,
+	      [XSERVER_LIBPCIACCESS=yes],[XSERVER_LIBPCIACCESS=no],
+	      [#include "xorg-server.h"])
 CFLAGS="$save_CFLAGS"
 
+if test x$XSERVER_LIBPCIACCESS = xyes; then
+	PKG_CHECK_MODULES([PCIACCESS], [pciaccess >= 0.8.0])
+fi
+
+AM_CONDITIONAL(XSERVER_LIBPCIACCESS, test "x$XSERVER_LIBPCIACCESS" = xyes)
 AM_CONDITIONAL(XMODES, test "x$XMODES" = xno)
 
 if test "x$XSERVER_SOURCE" = x; then
diff --git a/src/Makefile.am b/src/Makefile.am
index 50e913e..13cbf91 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -18,7 +18,7 @@
 #  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.
 
-if HAVE_PCIACCESS
+if XSERVER_LIBPCIACCESS
 REGDUMPER = reg_dumper
 endif
 
diff --git a/src/bios_reader/Makefile.am b/src/bios_reader/Makefile.am
index 8e03693..a4adecb 100644
--- a/src/bios_reader/Makefile.am
+++ b/src/bios_reader/Makefile.am
@@ -2,7 +2,7 @@ AM_CFLAGS = @WARN_CFLAGS@ @XORG_CFLAGS@ 
 
 noinst_PROGRAMS = bios_reader  $(BIOS_DUMPER)
 
-if HAVE_PCIACCESS
+if XSERVER_LIBPCIACCESS
 BIOS_DUMPER = bios_dumper
 
 bios_dumper_SOURCES = bios_dumper.c
diff-tree 5faf9cc6afe1c30fa88bc6446088a6fa47fc5d0b (from a9e1d42a47cef79d8bbde2afd89d26aed964e344)
Author: Keith Packard <keithp at koto.keithp.com>
Date:   Sun Aug 26 09:34:06 2007 -0700

    Sort quirk table, add Dell Latitude X1

diff --git a/src/i830_quirks.c b/src/i830_quirks.c
index 89fb11e..fb10570 100644
--- a/src/i830_quirks.c
+++ b/src/i830_quirks.c
@@ -54,19 +54,27 @@ static void quirk_mac_mini (I830Ptr pI83
     pI830->quirk_flag |= QUIRK_IGNORE_MACMINI_LVDS;
 }
 
+/* keep this list sorted by OEM, then by chip ID */
 static i830_quirk i830_quirk_list[] = {
-    /* Lenovo T61 has no TV output */
-    { PCI_CHIP_I965_GM, 0x17aa, 0x20b5, quirk_ignore_tv },
+    /* Aopen mini pc */
+    { PCI_CHIP_I945_GM, 0xa0a0, SUBSYS_ANY, quirk_ignore_lvds },
+    
+    /* Apple Mac mini has no lvds, but macbook pro does */
+    { PCI_CHIP_I945_GM, 0x8086, 0x7270, quirk_mac_mini },
+    
+    /* Dell Latitude X1 */
+    { PCI_CHIP_I945_GM, 0x1028, 0x01a3, quirk_ignore_tv },
+    
     /* Lenovo X60s has no TV output */
     { PCI_CHIP_I945_GM, 0x17aa, 0x201a, quirk_ignore_tv },
-    /* Panasonic Toughbook CF-Y4 has no TV output */
-    { PCI_CHIP_I915_GM, 0x10f7, 0x8338, quirk_ignore_tv },
+    /* Lenovo T61 has no TV output */
+    { PCI_CHIP_I965_GM, 0x17aa, 0x20b5, quirk_ignore_tv },
     /* Lenovo 3000 v200 */
     { PCI_CHIP_I965_GM, 0x17aa, 0x3c18, quirk_ignore_tv },
-    /* Aopen mini pc */
-    { PCI_CHIP_I945_GM, 0xa0a0, SUBSYS_ANY, quirk_ignore_lvds },
-    /* Mac mini has no lvds, but macbook pro does */
-    { PCI_CHIP_I945_GM, 0x8086, 0x7270, quirk_mac_mini },
+    
+    /* Panasonic Toughbook CF-Y4 has no TV output */
+    { PCI_CHIP_I915_GM, 0x10f7, 0x8338, quirk_ignore_tv },
+    
     { 0, 0, 0, NULL },
 };
 
diff-tree a9e1d42a47cef79d8bbde2afd89d26aed964e344 (from ffc2907f7f2eb039004eff0014c5563a01463fb0)
Author: Keith Packard <keithp at koto.keithp.com>
Date:   Sat Aug 25 12:54:11 2007 -0700

    Lenovo 201a is x60s, not x61s

diff --git a/src/i830_quirks.c b/src/i830_quirks.c
index 3176cd4..89fb11e 100644
--- a/src/i830_quirks.c
+++ b/src/i830_quirks.c
@@ -57,8 +57,8 @@ static void quirk_mac_mini (I830Ptr pI83
 static i830_quirk i830_quirk_list[] = {
     /* Lenovo T61 has no TV output */
     { PCI_CHIP_I965_GM, 0x17aa, 0x20b5, quirk_ignore_tv },
-    /* Lenovo X61s has no TV output */
-    { PCI_CHIP_I965_GM, 0x17aa, 0x201a, quirk_ignore_tv },
+    /* Lenovo X60s has no TV output */
+    { PCI_CHIP_I945_GM, 0x17aa, 0x201a, quirk_ignore_tv },
     /* Panasonic Toughbook CF-Y4 has no TV output */
     { PCI_CHIP_I915_GM, 0x10f7, 0x8338, quirk_ignore_tv },
     /* Lenovo 3000 v200 */
diff-tree ffc2907f7f2eb039004eff0014c5563a01463fb0 (from 0c20fbabd18c19b2753cb60280f89e240ce5645f)
Author: Keith Packard <keithp at koto.keithp.com>
Date:   Sat Aug 25 12:31:21 2007 -0700

    Thinkpad X61s has no TV out

diff --git a/src/i830_quirks.c b/src/i830_quirks.c
index b75baef..3176cd4 100644
--- a/src/i830_quirks.c
+++ b/src/i830_quirks.c
@@ -57,6 +57,8 @@ static void quirk_mac_mini (I830Ptr pI83
 static i830_quirk i830_quirk_list[] = {
     /* Lenovo T61 has no TV output */
     { PCI_CHIP_I965_GM, 0x17aa, 0x20b5, quirk_ignore_tv },
+    /* Lenovo X61s has no TV output */
+    { PCI_CHIP_I965_GM, 0x17aa, 0x201a, quirk_ignore_tv },
     /* Panasonic Toughbook CF-Y4 has no TV output */
     { PCI_CHIP_I915_GM, 0x10f7, 0x8338, quirk_ignore_tv },
     /* Lenovo 3000 v200 */
diff-tree 0c20fbabd18c19b2753cb60280f89e240ce5645f (from e443f83dd6f110156743c93f7d793cdddb8195a1)
Author: Keith Packard <keithp at koto.keithp.com>
Date:   Fri Aug 17 22:21:47 2007 -0700

    Make sure XV_PIPE is used whenever possible.
    
    The code was not consistently using XV_PIPE when the desired crtc contained
    any portion of the video output.

diff --git a/src/i830_video.c b/src/i830_video.c
index 926e122..2128eb8 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -1712,11 +1712,14 @@ i830_covering_crtc (ScrnInfoPtr pScrn,
 	i830_crtc_box (crtc, &crtc_box);
 	i830_box_intersect (&cover_box, &crtc_box, box);
 	coverage = i830_box_area (&cover_box);
+	if (coverage && crtc == desired)
+	{
+	    *crtc_box_ret = crtc_box;
+	    return crtc;
+	}
 	if (coverage > best_coverage)
 	{
 	    *crtc_box_ret = crtc_box;
-	    if (crtc == desired)
-		return crtc;
 	    best_crtc = crtc;
 	    best_coverage = coverage;
 	}
diff-tree e443f83dd6f110156743c93f7d793cdddb8195a1 (from bd874b11bbfe582aebd3115771f90807e75afc31)
Author: Eric Anholt <eric at anholt.net>
Date:   Fri Aug 17 18:13:49 2007 -0700

    Tune acceleration architecture allocator sizes down.

diff --git a/src/i830_memory.c b/src/i830_memory.c
index 99315db..3da489d 100644
--- a/src/i830_memory.c
+++ b/src/i830_memory.c
@@ -849,7 +849,6 @@ i830_allocate_framebuffer(ScrnInfoPtr pS
 	    int size;
 
 	    size = 3 * pitch * pScrn->virtualY;
-	    size += 1920 * 1088 * 2 * 2;
 	    size = ROUND_TO_PAGE(size);
 
 	    cacheLines = (size + pitch - 1) / pitch;
@@ -1140,14 +1139,13 @@ i830_allocate_2d_memory(ScrnInfoPtr pScr
     if (pI830->useEXA) {
 	if (pI830->exa_offscreen == NULL) {
 	    /* Default EXA to having 3 screens worth of offscreen memory space
-	     * (for pixmaps), plus a double-buffered, 1920x1088 video's worth.
+	     * (for pixmaps).
 	     *
 	     * XXX: It would be nice to auto-size it larger if the user
 	     * specified a larger size, or to fit along with texture and FB
 	     * memory if a low videoRam is specified.
 	     */
 	    size = 3 * pitch * pScrn->virtualY;
-	    size += 1920 * 1088 * 2 * 2;
 	    size = ROUND_TO_PAGE(size);
 
 	    pI830->exa_offscreen = i830_allocate_memory(pScrn, "exa offscreen",
diff-tree bd874b11bbfe582aebd3115771f90807e75afc31 (from 9ad33dd65a79277ef75a6e95373614852725f5a9)
Author: Eric Anholt <eric at anholt.net>
Date:   Fri Aug 17 17:49:21 2007 -0700

    Replace AA allocator usage with i830_memory.c for RandR rotation.
    
    This requires EXA 2.2 (server 1.3) for rotated performance with EXA, because
    the i830_memory.c allocation may not fall within what EXA considers the
    offscreen area, so the PixmapIsOffscreen hook is needed.

diff --git a/src/i830.h b/src/i830.h
index 6888a9b..b0c8f0f 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -234,12 +234,7 @@ typedef struct _I830CrtcPrivateRec {
     /* Lookup table values to be set when the CRTC is enabled */
     CARD8 lut_r[256], lut_g[256], lut_b[256];
 
-#ifdef I830_USE_XAA
-    FBLinearPtr rotate_mem_xaa;
-#endif
-#ifdef I830_USE_EXA
-    ExaOffscreenArea *rotate_mem_exa;
-#endif
+    i830_memory *rotate_mem;
     /* Card virtual address of the cursor */
     unsigned long cursor_offset;
     unsigned long cursor_argb_offset;
@@ -689,14 +684,6 @@ Bool i830_unbind_all_memory(ScrnInfoPtr 
 
 Bool I830BindAGPMemory(ScrnInfoPtr pScrn);
 Bool I830UnbindAGPMemory(ScrnInfoPtr pScrn);
-#ifdef I830_USE_XAA
-FBLinearPtr
-i830_xf86AllocateOffscreenLinear(ScreenPtr pScreen, int length,
-				 int granularity,
-				 MoveLinearCallbackProcPtr moveCB,
-				 RemoveLinearCallbackProcPtr removeCB,
-				 pointer privData);
-#endif /* I830_USE_EXA */
 
 /* i830_modes.c */
 DisplayModePtr i830_ddc_get_modes(xf86OutputPtr output);
diff --git a/src/i830_display.c b/src/i830_display.c
index a076446..0ab0de7 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -1291,59 +1291,24 @@ static void *
 i830_crtc_shadow_allocate (xf86CrtcPtr crtc, int width, int height)
 {
     ScrnInfoPtr pScrn = crtc->scrn;
-    ScreenPtr pScreen = pScrn->pScreen;
     I830Ptr pI830 = I830PTR(pScrn);
     I830CrtcPrivatePtr intel_crtc = crtc->driver_private;
     unsigned long rotate_pitch;
-    unsigned long rotate_offset;
     int align = KB(4), size;
 
     rotate_pitch = pScrn->displayWidth * pI830->cpp;
     size = rotate_pitch * height;
 
-#ifdef I830_USE_EXA
-    /* We could get close to what we want here by just creating a pixmap like
-     * normal, but we have to lock it down in framebuffer, and there is no
-     * setter for offscreen area locking in EXA currently.  So, we just
-     * allocate offscreen memory and fake up a pixmap header for it.
-     */
-    if (pI830->useEXA) {
-	assert(intel_crtc->rotate_mem_exa == NULL);
-
-	intel_crtc->rotate_mem_exa = exaOffscreenAlloc(pScreen, size, align,
-						       TRUE, NULL, NULL);
-	if (intel_crtc->rotate_mem_exa == NULL) {
-	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
-		       "Couldn't allocate shadow memory for rotated CRTC\n");
-	    return NULL;
-	}
-	rotate_offset = intel_crtc->rotate_mem_exa->offset;
-    }
-#endif /* I830_USE_EXA */
-#ifdef I830_USE_XAA
-    if (!pI830->useEXA) {
-	/* The XFree86 linear allocator operates in units of screen pixels,
-	 * sadly.
-	 */
-	size = (size + pI830->cpp - 1) / pI830->cpp;
-	align = (align + pI830->cpp - 1) / pI830->cpp;
-
-	assert(intel_crtc->rotate_mem_xaa == NULL);
-
-	intel_crtc->rotate_mem_xaa =
-	    i830_xf86AllocateOffscreenLinear(pScreen, size, align,
-					     NULL, NULL, NULL);
-	if (intel_crtc->rotate_mem_xaa == NULL) {
-	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
-		       "Couldn't allocate shadow memory for rotated CRTC\n");
-	    return NULL;
-	}
-	rotate_offset = pI830->front_buffer->offset +
-	    intel_crtc->rotate_mem_xaa->offset * pI830->cpp;
+    assert(intel_crtc->rotate_mem == NULL);
+    intel_crtc->rotate_mem = i830_allocate_memory(pScrn, "rotated crtc",
+						  size, align, 0);
+    if (intel_crtc->rotate_mem == NULL) {
+	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+		   "Couldn't allocate shadow memory for rotated CRTC\n");
+	return NULL;
     }
-#endif /* I830_USE_XAA */
 
-    return pI830->FbBase + rotate_offset;
+    return pI830->FbBase + intel_crtc->rotate_mem->offset;
 }
     
 /**
@@ -1380,26 +1345,16 @@ static void
 i830_crtc_shadow_destroy(xf86CrtcPtr crtc, PixmapPtr rotate_pixmap, void *data)
 {
     ScrnInfoPtr pScrn = crtc->scrn;
-    I830Ptr pI830 = I830PTR(pScrn);
     I830CrtcPrivatePtr intel_crtc = crtc->driver_private;
 
     if (rotate_pixmap)
 	FreeScratchPixmapHeader(rotate_pixmap);
-    
-    if (data)
-    {
-#ifdef I830_USE_EXA
-	if (pI830->useEXA && intel_crtc->rotate_mem_exa != NULL) {
-	    exaOffscreenFree(pScrn->pScreen, intel_crtc->rotate_mem_exa);
-	    intel_crtc->rotate_mem_exa = NULL;
-	}
-#endif /* I830_USE_EXA */
-#ifdef I830_USE_XAA
-	if (!pI830->useEXA) {
-	    xf86FreeOffscreenLinear(intel_crtc->rotate_mem_xaa);
-	    intel_crtc->rotate_mem_xaa = NULL;
-	}
-#endif /* I830_USE_XAA */
+
+    if (data) {
+	/* Be sure to sync acceleration before the memory gets unbound. */
+	I830Sync(pScrn);
+	i830_free_memory(pScrn, intel_crtc->rotate_mem);
+	intel_crtc->rotate_mem = NULL;
     }
 }
 
diff --git a/src/i830_driver.c b/src/i830_driver.c
index 81e8118..ab42fd9 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -1562,7 +1562,11 @@ I830PreInit(ScrnInfoPtr pScrn, int flags
 
       memset(&req, 0, sizeof(req));
       req.majorversion = 2;
+#if EXA_VERSION_MINOR >= 2
+      req.minorversion = 2;
+#else
       req.minorversion = 1;
+#endif
       if (!LoadSubModule(pScrn->module, "exa", NULL, NULL, NULL, &req,
 		&errmaj, &errmin)) {
 	 LoaderErrorMsg(NULL, "exa", errmaj, errmin);
diff --git a/src/i830_exa.c b/src/i830_exa.c
index fdf94d7..fa50da0 100644
--- a/src/i830_exa.c
+++ b/src/i830_exa.c
@@ -124,6 +124,22 @@ i830_pixmap_tiled(PixmapPtr pPixmap)
     return FALSE;
 }
 
+Bool
+i830_exa_pixmap_is_offscreen(PixmapPtr pPixmap)
+{
+    ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
+    I830Ptr pI830 = I830PTR(pScrn);
+
+    if ((void *)pPixmap->devPrivate.ptr >= (void *)pI830->FbBase &&
+	(void *)pPixmap->devPrivate.ptr <
+	(void *)(pI830->FbBase + pI830->FbMapSize))
+    {
+	return TRUE;
+    } else {
+	return FALSE;
+    }
+}
+
 /**
  * I830EXASync - wait for a command to finish
  * @pScreen: current screen
@@ -456,7 +472,17 @@ I830EXAInit(ScreenPtr pScreen)
 
     pI830->bufferOffset = 0;
     pI830->EXADriverPtr->exa_major = 2;
+    /* If compiled against EXA 2.2, require 2.2 so we can use the
+     * PixmapIsOffscreen hook.
+     */
+#if EXA_VERSION_MINOR >= 2
+    pI830->EXADriverPtr->exa_minor = 2;
+#else
     pI830->EXADriverPtr->exa_minor = 1;
+    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+	       "EXA compatibility mode.  Output rotation rendering "
+	       "performance may suffer\n");
+#endif
     pI830->EXADriverPtr->memoryBase = pI830->FbBase;
     pI830->EXADriverPtr->offScreenBase = pI830->exa_offscreen->offset;
     pI830->EXADriverPtr->memorySize = pI830->exa_offscreen->offset +
@@ -552,6 +578,9 @@ I830EXAInit(ScreenPtr pScreen)
  	pI830->EXADriverPtr->Composite = i965_composite;
  	pI830->EXADriverPtr->DoneComposite = i830_done_composite;
     }
+#if EXA_VERSION_MINOR >= 2
+    pI830->EXADriverPtr->PixmapIsOffscreen = i830_exa_pixmap_is_offscreen;
+#endif
 
     /* UploadToScreen/DownloadFromScreen */
     if (0)
diff --git a/src/i830_memory.c b/src/i830_memory.c
index d6fa852..99315db 100644
--- a/src/i830_memory.c
+++ b/src/i830_memory.c
@@ -1684,41 +1684,3 @@ I830CheckAvailableMemory(ScrnInfoPtr pSc
 
     return maxPages * 4;
 }
-
-#ifdef I830_USE_XAA
-/**
- * Allocates memory from the XF86 linear allocator, but also purges
- * memory if possible to cause the allocation to succeed.
- */
-FBLinearPtr
-i830_xf86AllocateOffscreenLinear(ScreenPtr pScreen, int length,
-				 int granularity,
-				 MoveLinearCallbackProcPtr moveCB,
-				 RemoveLinearCallbackProcPtr removeCB,
-				 pointer privData)
-{
-    FBLinearPtr linear;
-    int max_size;
-
-    linear = xf86AllocateOffscreenLinear(pScreen, length, granularity, moveCB,
-					 removeCB, privData);
-    if (linear != NULL)
-	return linear;
-
-    /* The above allocation didn't succeed, so purge unlocked stuff and try
-     * again.
-     */
-    xf86QueryLargestOffscreenLinear(pScreen, &max_size, granularity,
-				    PRIORITY_EXTREME);
-
-    if (max_size < length)
-	return NULL;
-
-    xf86PurgeUnlockedOffscreenAreas(pScreen);
-
-    linear = xf86AllocateOffscreenLinear(pScreen, length, granularity, moveCB,
-					 removeCB, privData);
-
-    return linear;
-}
-#endif
diff-tree 9ad33dd65a79277ef75a6e95373614852725f5a9 (from 3655a1ecb62f6c387a16fa87cf6f00bf7835dce4)
Author: Eric Anholt <eric at anholt.net>
Date:   Fri Aug 17 16:46:48 2007 -0700

    Use i830_memory.c instead of the AA's allocator for XV buffers.
    
    This should fix issues with XV being allocated into XAA's tiled pixmap
    cache and resulting bad rendering.  Its also brings us closer to being able
    to shrink the size of the pixmap cache on XAA, which is of limited utility.

diff --git a/src/i830.h b/src/i830.h
index 1cfcb9a..6888a9b 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -641,6 +641,14 @@ extern void I830SubsequentSolidFillRect(
 
 Bool i830_allocator_init(ScrnInfoPtr pScrn, unsigned long offset,
 			 unsigned long size);
+i830_memory * i830_allocate_memory(ScrnInfoPtr pScrn, const char *name,
+				   unsigned long size, unsigned long alignment,
+				   int flags);
+i830_memory *i830_allocate_memory_tiled(ScrnInfoPtr pScrn, const char *name,
+					unsigned long size,
+					unsigned long pitch,
+					unsigned long alignment, int flags,
+					enum tile_format tile_format);
 void i830_describe_allocations(ScrnInfoPtr pScrn, int verbosity,
 			       const char *prefix);
 void i830_reset_allocations(ScrnInfoPtr pScrn);
diff --git a/src/i830_memory.c b/src/i830_memory.c
index 15d3a48..d6fa852 100644
--- a/src/i830_memory.c
+++ b/src/i830_memory.c
@@ -515,7 +515,7 @@ i830_allocate_agp_memory(ScrnInfoPtr pSc
  * The memory will be bound automatically when the driver is in control of the
  * VT.
  */
-static i830_memory *
+i830_memory *
 i830_allocate_memory(ScrnInfoPtr pScrn, const char *name,
 		     unsigned long size, unsigned long alignment, int flags)
 {
@@ -544,7 +544,7 @@ i830_allocate_memory(ScrnInfoPtr pScrn, 
  * some search across all allocation options to fix this, probably, but that
  * would be another rewrite.
  */
-static i830_memory *
+i830_memory *
 i830_allocate_memory_tiled(ScrnInfoPtr pScrn, const char *name,
 			   unsigned long size, unsigned long pitch,
 			   unsigned long alignment, int flags,
diff --git a/src/i830_video.c b/src/i830_video.c
index b4f9e74..926e122 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -107,9 +107,6 @@ static int I830QueryImageAttributesTextu
 
 static void I830BlockHandler(int, pointer, pointer, pointer);
 
-static void
-I830FreeMemory(ScrnInfoPtr pScrn, struct linear_alloc *linear);
-
 #define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE)
 
 static Atom xvBrightness, xvContrast, xvSaturation, xvColorKey, xvPipe, xvDoubleBuffer;
@@ -841,7 +838,7 @@ I830SetupImageVideoOverlay(ScreenPtr pSc
     pPriv->saturation = 128;
     pPriv->current_crtc = NULL;
     pPriv->desired_crtc = NULL;
-    memset(&pPriv->linear, 0, sizeof(pPriv->linear));
+    pPriv->buf = NULL;
     pPriv->currentBuf = 0;
     pPriv->gamma5 = 0xc0c0c0;
     pPriv->gamma4 = 0x808080;
@@ -955,7 +952,7 @@ I830SetupImageVideoTextured(ScreenPtr pS
 
 	pPriv->textured = TRUE;
 	pPriv->videoStatus = 0;
-	memset(&pPriv->linear, 0, sizeof(pPriv->linear));
+	pPriv->buf = NULL;
 	pPriv->currentBuf = 0;
 	pPriv->doubleBuffer = 0;
 
@@ -1015,7 +1012,10 @@ I830StopVideo(ScrnInfoPtr pScrn, pointer
 	    if (pI830->entityPrivate)
 		pI830->entityPrivate->XvInUse = -1;
 	}
-	I830FreeMemory(pScrn, &pPriv->linear);
+	/* Sync before freeing the buffer, because the pages will be unbound.
+	 */
+	I830Sync(pScrn);
+	i830_free_memory(pScrn, pPriv->buf);
 	pPriv->videoStatus = 0;
     } else {
 	if (pPriv->videoStatus & CLIENT_VIDEO_ON) {
@@ -2075,112 +2075,6 @@ i830_display_video(ScrnInfoPtr pScrn, xf
     i830_overlay_continue (pScrn, scaleChanged);
 }
 
-#ifdef I830_USE_EXA
-static void
-I830VideoSave(ScreenPtr pScreen, ExaOffscreenArea *area)
-{
-    struct linear_alloc *linear = area->privData;
-
-    linear->exa = NULL;
-    linear->offset = 0;
-}
-#endif /* I830_USE_EXA */
-
-/**
- * Allocates linear memory using the XFree86 (XAA) or EXA allocator.
- *
- * \param pPriv adaptor the memory is being allocated for.
- * \param size size of the allocation, in bytes.
- * \param alignment offset alignment of the allocation, in bytes.
- *
- * \return byte offset of the allocated memory from the start of framebuffer.
- */
-static void
-I830AllocateMemory(ScrnInfoPtr pScrn, struct linear_alloc *linear, int size,
-		   int align)
-{
-    ScreenPtr pScreen = pScrn->pScreen;
-    I830Ptr pI830 = I830PTR(pScrn);
-
-#ifdef I830_USE_EXA
-    if (pI830->useEXA) {
-	if (linear->exa != NULL) {
-	    if (linear->exa->size >= size)
-		return;
-
-	    exaOffscreenFree(pScreen, linear->exa);
-	    linear->offset = 0;
-	}
-
-	linear->exa = exaOffscreenAlloc(pScreen, size, align, TRUE,
-					I830VideoSave, linear);
-	if (linear->exa == NULL)
-	    return;
-	linear->offset = linear->exa->offset;
-    }
-#endif /* I830_USE_EXA */
-#ifdef I830_USE_XAA
-    if (!pI830->useEXA) {
-	/* Converts an offset from XAA's linear allocator to an offset from the
-	 * start of fb.
-	 */
-#define XAA_OFFSET_TO_OFFSET(x) \
-	(pI830->front_buffer->offset + (x * pI830->cpp))
-
-	/* The XFree86 linear allocator operates in units of screen pixels,
-	 * sadly.
-	 */
-	size = (size + pI830->cpp - 1) / pI830->cpp;
-	align = (align + pI830->cpp - 1) / pI830->cpp;
-
-	if (linear->xaa != NULL) {
-	    if (linear->xaa->size >= size) {
-		linear->offset = XAA_OFFSET_TO_OFFSET(linear->xaa->offset);
-		return;
-	    }
-
-	    if (xf86ResizeOffscreenLinear(linear->xaa, size)) {
-		linear->offset = XAA_OFFSET_TO_OFFSET(linear->xaa->offset);
-		return;
-	    }
-
-	    xf86FreeOffscreenLinear(linear->xaa);
-	}
-
-	linear->xaa = i830_xf86AllocateOffscreenLinear(pScreen, size, align,
-						       NULL, NULL, NULL);
-	if (linear->xaa == NULL)
-	    return;
-
-	linear->offset = XAA_OFFSET_TO_OFFSET(linear->xaa->offset);
-    }
-#endif /* I830_USE_XAA */
-}
-
-static void
-I830FreeMemory(ScrnInfoPtr pScrn, struct linear_alloc *linear)
-{
-    I830Ptr pI830 = I830PTR(pScrn);
-
-#ifdef I830_USE_EXA
-    if (pI830->useEXA) {
-	if (linear->exa != NULL) {
-	    exaOffscreenFree(pScrn->pScreen, linear->exa);
-	    linear->exa = NULL;
-	}
-    }
-#endif /* I830_USE_EXA */
-#ifdef I830_USE_XAA
-    if (!pI830->useEXA) {
-	if (linear->xaa != NULL) {
-	    xf86FreeOffscreenLinear(linear->xaa);
-	    linear->xaa = NULL;
-	}
-    }
-#endif /* I830_USE_XAA */
-    linear->offset = 0;
-}
-
 static Bool
 i830_clip_video_helper (ScrnInfoPtr pScrn,
 			xf86CrtcPtr *crtc_ret,
@@ -2293,7 +2187,7 @@ I830PutImage(ScrnInfoPtr pScrn,
     int top, left, npixels, nlines, size;
     BoxRec dstBox;
     int pitchAlignMask;
-    int extraLinear;
+    int alloc_size, extraLinear;
     xf86CrtcPtr	crtc;
 
     if (pPriv->textured)
@@ -2410,19 +2304,38 @@ I830PutImage(ScrnInfoPtr pScrn,
     else
 	extraLinear = 0;
 
-    /* size is multiplied by 2 because we have two buffers that are flipping */
-    I830AllocateMemory(pScrn, &pPriv->linear,
-		       extraLinear + (pPriv->doubleBuffer ? size * 2 : size),
-		       16);
+    alloc_size = size;
+    if (pPriv->doubleBuffer)
+	alloc_size *= 2;
+    alloc_size += extraLinear;
+
+    if (pPriv->buf) {
+	/* Wait for any previous acceleration to the buffer to have completed.
+	 * When we start using BOs for rendering, we won't have to worry
+	 * because mapping or freeing will take care of it automatically.
+	 */
+	I830Sync(pScrn);
+    }
+
+    /* Free the current buffer if we're going to have to reallocate */
+    if (pPriv->buf && pPriv->buf->size < alloc_size) {
+	i830_free_memory(pScrn, pPriv->buf);
+	pPriv->buf = NULL;
+    }
 
-    if (pPriv->linear.offset == 0)
+    if (pPriv->buf == NULL) {
+	pPriv->buf = i830_allocate_memory(pScrn, "xv buffer", alloc_size, 16,
+					  0);
+    }
+
+    if (pPriv->buf == NULL)
 	return BadAlloc;
 
-    pPriv->extra_offset = pPriv->linear.offset +
+    pPriv->extra_offset = pPriv->buf->offset +
     (pPriv->doubleBuffer ? size * 2 : size);
 
     /* fixup pointers */
-    pPriv->YBuf0offset = pPriv->linear.offset;
+    pPriv->YBuf0offset = pPriv->buf->offset;
     if (pI830->rotation & (RR_Rotate_90 | RR_Rotate_270)) {
 	pPriv->UBuf0offset = pPriv->YBuf0offset + (dstPitch * 2 * width);
 	pPriv->VBuf0offset = pPriv->UBuf0offset + (dstPitch * width / 2);
@@ -2654,7 +2567,11 @@ I830BlockHandler(int i,
 	    }
 	} else {				/* FREE_TIMER */
 	    if (pPriv->freeTime < now) {
-		I830FreeMemory(pScrn, &pPriv->linear);
+		/* Sync before freeing the buffer, because the pages will be
+		 * unbound.
+		 */
+		I830Sync(pScrn);
+		i830_free_memory(pScrn, pPriv->buf);
 		pPriv->videoStatus = 0;
 	    }
 	}
@@ -2666,7 +2583,7 @@ I830BlockHandler(int i,
  ***************************************************************************/
 
 typedef struct {
-    struct linear_alloc linear;
+    i830_memory *buf;
     Bool isOn;
 } OffscreenPrivRec, *OffscreenPrivPtr;
 
@@ -2711,8 +2628,8 @@ I830AllocateSurface(ScrnInfoPtr pScrn,
     fbpitch = pI830->cpp * pScrn->displayWidth;
     size = pitch * h;
 
-    I830AllocateMemory(pScrn, &pPriv->linear, size, 16);
-    if (pPriv->linear.offset == 0) {
+    pPriv->buf = i830_allocate_memory(pScrn, "xv surface buffer", size, 16, 0);
+    if (pPriv->buf == NULL) {
 	xfree(surface->pitches);
 	xfree(surface->offsets);
 	xfree(pPriv);
@@ -2727,7 +2644,7 @@ I830AllocateSurface(ScrnInfoPtr pScrn,
     surface->pScrn = pScrn;
     surface->id = id;
     surface->pitches[0] = pitch;
-    surface->offsets[0] = pPriv->linear.offset;
+    surface->offsets[0] = pPriv->buf->offset;
     surface->devPrivate.ptr = (pointer) pPriv;
 
     memset(pI830->FbBase + surface->offsets[0], 0, size);
@@ -2760,10 +2677,13 @@ I830StopSurface(XF86SurfacePtr surface)
 static int
 I830FreeSurface(XF86SurfacePtr surface)
 {
+    ScrnInfoPtr pScrn = surface->pScrn;
     OffscreenPrivPtr pPriv = (OffscreenPrivPtr) surface->devPrivate.ptr;
 
     I830StopSurface(surface);
-    I830FreeMemory(surface->pScrn, &pPriv->linear);
+    /* Sync before freeing the buffer, because the pages will be unbound. */
+    I830Sync(pScrn);
+    i830_free_memory(surface->pScrn, pPriv->buf);
     xfree(surface->pitches);
     xfree(surface->offsets);
     xfree(surface->devPrivate.ptr);
diff --git a/src/i830_video.h b/src/i830_video.h
index 7e2d149..23954e1 100644
--- a/src/i830_video.h
+++ b/src/i830_video.h
@@ -27,18 +27,6 @@ THE USE OR OTHER DEALINGS IN THE SOFTWAR
 #include "xf86.h"
 #include "xf86_OSproc.h"
 
-/* Ugly mess to support the old XF86 allocator or EXA using the same code.
- */
-struct linear_alloc {
-#ifdef I830_USE_XAA
-   FBLinearPtr xaa;
-#endif
-#ifdef I830_USE_EXA
-   ExaOffscreenArea *exa;
-#endif
-   unsigned int offset;
-};
-
 typedef struct {
    CARD32 YBuf0offset;
    CARD32 UBuf0offset;
@@ -70,7 +58,7 @@ typedef struct {
    CARD32 videoStatus;
    Time offTime;
    Time freeTime;
-   struct linear_alloc linear;
+   i830_memory *buf; /** YUV data buffer */
    unsigned int extra_offset;
 
    Bool overlayOK;
diff-tree 3655a1ecb62f6c387a16fa87cf6f00bf7835dce4 (from parents)
Merge: e5c336eaa32be8f9379a2c1dd51006b85bc8b270 2231cdcd8f1ee81b3e59cc5e3a325c22ee0f40e4
Author: Jesse Barnes <jbarnes at nietzche.virtuousgeek.org>
Date:   Thu Aug 16 12:04:20 2007 -0700

    Merge branch 'master' of ssh://git.freedesktop.org/git/xorg/driver/xf86-video-intel

diff-tree e5c336eaa32be8f9379a2c1dd51006b85bc8b270 (from 5126a71f82767b9e23cd590453718f3364789740)
Author: Jesse Barnes <jbarnes at nietzche.virtuousgeek.org>
Date:   Thu Aug 16 12:04:02 2007 -0700

    Disambiguate plane and pipe mapping, use plane A on pipe B on pre-965 LVDS
    
    Add a new 'plane' field to the intel_crtc private structure for tracking
    planes separate from pipes.  This allows pre-965 chips to use plane A
    on pipe B, enabling framebuffer compression for builtin LVDS displays.

diff --git a/src/i830.h b/src/i830.h
index ca48b52..1cfcb9a 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -225,6 +225,7 @@ extern const char *i830_output_type_name
 
 typedef struct _I830CrtcPrivateRec {
     int			    pipe;
+    int			    plane;
 
     Bool    		    enabled;
     
diff --git a/src/i830_display.c b/src/i830_display.c
index 706b9ba..a076446 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -372,10 +372,11 @@ i830PipeSetBase(xf86CrtcPtr crtc, int x,
     I830Ptr pI830 = I830PTR(pScrn);
     I830CrtcPrivatePtr	intel_crtc = crtc->driver_private;
     int pipe = intel_crtc->pipe;
+    int plane = intel_crtc->plane;
     unsigned long Start, Offset;
-    int dspbase = (pipe == 0 ? DSPABASE : DSPBBASE);
-    int dspsurf = (pipe == 0 ? DSPASURF : DSPBSURF);
-    int dsptileoff = (pipe == 0 ? DSPATILEOFF : DSPBTILEOFF);
+    int dspbase = (plane == 0 ? DSPABASE : DSPBBASE);
+    int dspsurf = (plane == 0 ? DSPASURF : DSPBSURF);
+    int dsptileoff = (plane == 0 ? DSPATILEOFF : DSPBTILEOFF);
 
     Offset = ((y * pScrn->displayWidth + x) * pI830->cpp);
     if (pI830->front_buffer == NULL) {
@@ -523,8 +524,7 @@ i830_use_fb_compression(xf86CrtcPtr crtc
     ScrnInfoPtr pScrn = crtc->scrn;
     I830Ptr pI830 = I830PTR(pScrn);
     I830CrtcPrivatePtr	intel_crtc = crtc->driver_private;
-    int pipe = intel_crtc->pipe;
-    int plane = (pipe == 0 ? FBC_CTL_PLANEA : FBC_CTL_PLANEB);
+    int plane = (intel_crtc->plane == 0 ? FBC_CTL_PLANEA : FBC_CTL_PLANEB);
 
     if (!pI830->fb_compression)
 	return FALSE;
@@ -569,17 +569,15 @@ i830_enable_fb_compression(xf86CrtcPtr c
     I830CrtcPrivatePtr	intel_crtc = crtc->driver_private;
     uint32_t fbc_ctl = 0;
     unsigned long compressed_stride;
-    int pipe = intel_crtc->pipe;
-    /* FIXME: plane & pipe might not always be equal */
-    int plane = (pipe == 0 ? FBC_CTL_PLANEA : FBC_CTL_PLANEB);
+    int plane = (intel_crtc->plane == 0 ? FBC_CTL_PLANEA : FBC_CTL_PLANEB);
     unsigned long uncompressed_stride = pScrn->displayWidth * pI830->cpp;
     unsigned long interval = 1000;
 
     if (INREG(FBC_CONTROL) & FBC_CTL_EN) {
-	char cur_pipe = (INREG(FBC_CONTROL2) & 1) ? 'b' : 'a';
+	char cur_plane = (INREG(FBC_CONTROL2) & 1) ? 'b' : 'a';
 	xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "fbc already enabled on "
-		   "pipe %c, not enabling on pipe %c\n", cur_pipe, pipe ? 'b' :
-		   'a');
+		   "plane %c, not enabling on plane %c\n", cur_plane,
+		   plane ? 'b' : 'a');
 	return;
     }
 
@@ -615,7 +613,7 @@ i830_enable_fb_compression(xf86CrtcPtr c
     fbc_ctl |= FBC_CTL_UNCOMPRESSIBLE;
     OUTREG(FBC_CONTROL, fbc_ctl);
 
-    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "fbc enabled on plane %c\n", pipe ?
+    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "fbc enabled on plane %c\n", plane ?
 	       'b' : 'a');
 }
 
@@ -625,7 +623,7 @@ i830_disable_fb_compression(xf86CrtcPtr 
     ScrnInfoPtr pScrn = crtc->scrn;
     I830Ptr pI830 = I830PTR(pScrn);
     uint32_t fbc_ctl;
-    char pipe = (INREG(FBC_CONTROL2) & 1) ? 'b' : 'a';
+    char plane = (INREG(FBC_CONTROL2) & 1) ? 'b' : 'a';
 
     /* Disable compression */
     fbc_ctl = INREG(FBC_CONTROL);
@@ -635,7 +633,7 @@ i830_disable_fb_compression(xf86CrtcPtr 
     /* Wait for compressing bit to clear */
     while (INREG(FBC_STATUS) & FBC_STAT_COMPRESSING)
 	; /* nothing */
-    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "fbc disabled on pipe %c\n", pipe);
+    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "fbc disabled on pipe %c\n", plane);
 }
 
 /**
@@ -651,10 +649,11 @@ i830_crtc_dpms(xf86CrtcPtr crtc, int mod
     I830Ptr pI830 = I830PTR(pScrn);
     I830CrtcPrivatePtr intel_crtc = crtc->driver_private;
     int pipe = intel_crtc->pipe;
+    int plane = intel_crtc->plane;
     int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B;
-    int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR;
-    int dspbase_reg = (pipe == 0) ? DSPABASE : DSPBBASE;
     int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF;
+    int dspcntr_reg = (plane == 0) ? DSPACNTR : DSPBCNTR;
+    int dspbase_reg = (plane == 0) ? DSPABASE : DSPBBASE;
     CARD32 temp;
 
     /* XXX: When our outputs are all unaware of DPMS modes other than off and
@@ -951,10 +950,10 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, Dis
     I830Ptr pI830 = I830PTR(pScrn);
     I830CrtcPrivatePtr intel_crtc = crtc->driver_private;
     int pipe = intel_crtc->pipe;
+    int plane = intel_crtc->plane;
     int fp_reg = (pipe == 0) ? FPA0 : FPB0;
     int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B;
-    int dpll_md_reg = (intel_crtc->pipe == 0) ? DPLL_A_MD : DPLL_B_MD;
-    int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR;
+    int dpll_md_reg = (pipe == 0) ? DPLL_A_MD : DPLL_B_MD;
     int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF;
     int htot_reg = (pipe == 0) ? HTOTAL_A : HTOTAL_B;
     int hblank_reg = (pipe == 0) ? HBLANK_A : HBLANK_B;
@@ -962,10 +961,11 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, Dis
     int vtot_reg = (pipe == 0) ? VTOTAL_A : VTOTAL_B;
     int vblank_reg = (pipe == 0) ? VBLANK_A : VBLANK_B;
     int vsync_reg = (pipe == 0) ? VSYNC_A : VSYNC_B;
-    int dspsize_reg = (pipe == 0) ? DSPASIZE : DSPBSIZE;
-    int dspstride_reg = (pipe == 0) ? DSPASTRIDE : DSPBSTRIDE;
-    int dsppos_reg = (pipe == 0) ? DSPAPOS : DSPBPOS;
     int pipesrc_reg = (pipe == 0) ? PIPEASRC : PIPEBSRC;
+    int dspcntr_reg = (plane == 0) ? DSPACNTR : DSPBCNTR;
+    int dspstride_reg = (plane == 0) ? DSPASTRIDE : DSPBSTRIDE;
+    int dsppos_reg = (plane == 0) ? DSPAPOS : DSPBPOS;
+    int dspsize_reg = (plane == 0) ? DSPASIZE : DSPBSIZE;
     int i;
     int refclk;
     intel_clock_t clock;
@@ -1415,8 +1415,11 @@ i830DescribeOutputConfiguration(ScrnInfo
 
     for (i = 0; i < xf86_config->num_crtc; i++) {
 	xf86CrtcPtr crtc = xf86_config->crtc[i];
-	CARD32 dspcntr = INREG(DSPACNTR + (DSPBCNTR - DSPACNTR) * i);
-	CARD32 pipeconf = INREG(PIPEACONF + (PIPEBCONF - PIPEACONF) * i);
+	I830CrtcPrivatePtr intel_crtc = crtc ? crtc->driver_private : NULL;
+	CARD32 dspcntr = intel_crtc->plane == 0 ? INREG(DSPACNTR) :
+	    INREG(DSPBCNTR);
+	CARD32 pipeconf = i == 0 ? INREG(PIPEACONF) :
+	    INREG(PIPEBCONF);
 	Bool hw_plane_enable = (dspcntr & DISPLAY_PLANE_ENABLE) != 0;
 	Bool hw_pipe_enable = (pipeconf & PIPEACONF_ENABLE) != 0;
 
@@ -1425,8 +1428,8 @@ i830DescribeOutputConfiguration(ScrnInfo
 		   'A' + i, crtc->enabled ? "on" : "off");
 	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
 		   "  Display plane %c is now %s and connected to pipe %c.\n",
-		   'A' + i,
-		   crtc->enabled ? "enabled" : "disabled",
+		   'A' + intel_crtc->plane,
+		   hw_plane_enable ? "enabled" : "disabled",
 		   dspcntr & DISPPLANE_SEL_PIPE_MASK ? 'B' : 'A');
 	if (hw_pipe_enable != crtc->enabled) {
 	    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
@@ -1730,6 +1733,7 @@ i830_crtc_init(ScrnInfoPtr pScrn, int pi
     intel_crtc = xnfcalloc (sizeof (I830CrtcPrivateRec), 1);
     intel_crtc->pipe = pipe;
     intel_crtc->dpms_mode = DPMSModeOff;
+    intel_crtc->plane = pipe;
 
     /* Initialize the LUTs for when we turn on the CRTC. */
     for (i = 0; i < 256; i++) {
diff --git a/src/i830_driver.c b/src/i830_driver.c
index 712b2dd..81e8118 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -742,7 +742,8 @@ I830SetupOutputs(ScrnInfoPtr pScrn)
 {
    xf86CrtcConfigPtr	config = XF86_CRTC_CONFIG_PTR (pScrn);
    I830Ptr  pI830 = I830PTR(pScrn);
-   int	    o;
+   int	    o, c;
+   Bool	    lvds_detected = FALSE;
 
    /* everyone has at least a single analog output */
    i830_crt_init(pScrn);
@@ -765,7 +766,9 @@ I830SetupOutputs(ScrnInfoPtr pScrn)
       xf86OutputPtr	   output = config->output[o];
       I830OutputPrivatePtr intel_output = output->driver_private;
       int		   crtc_mask;
-      int		   c;
+
+      if (intel_output->type == I830_OUTPUT_LVDS)
+	  lvds_detected = TRUE;
       
       crtc_mask = 0;
       for (c = 0; c < config->num_crtc; c++)
@@ -779,6 +782,24 @@ I830SetupOutputs(ScrnInfoPtr pScrn)
       output->possible_crtcs = crtc_mask;
       output->possible_clones = i830_output_clones (pScrn, intel_output->clone_mask);
    }
+
+   /*
+    * If an LVDS display is present, swap the plane/pipe mappings so we can
+    * use FBC on the builtin display.
+    * Note: 965+ chips can compress either plane, so we leave the mapping
+    *       alone in that case.
+    */
+   if (lvds_detected && !IS_I965GM(pI830)) {
+       for (c = 0; c < config->num_crtc; c++) {
+	   xf86CrtcPtr	      crtc = config->crtc[c];
+	   I830CrtcPrivatePtr   intel_crtc = crtc->driver_private;
+
+	   if (intel_crtc->pipe == 0)
+	       intel_crtc->plane = 1;
+	   else if (intel_crtc->pipe == 1)
+	       intel_crtc->plane = 0;
+      }
+   }
 }
 
 /**
diff --git a/src/i830_tv.c b/src/i830_tv.c
index e3aeaf9..a77bf98 100644
--- a/src/i830_tv.c
+++ b/src/i830_tv.c
@@ -878,11 +878,11 @@ i830_tv_restore(xf86OutputPtr output)
     OUTREG(TV_CLR_LEVEL, dev_priv->save_TV_CLR_LEVEL);
 
     {
-	int pipeconf_reg = (intel_crtc->pipe == 0)?PIPEACONF:PIPEBCONF;
-	int dspcntr_reg = (intel_crtc->pipe == 0)?DSPACNTR : DSPBCNTR;
+	int pipeconf_reg = (intel_crtc->pipe == 0) ? PIPEACONF : PIPEBCONF;
+	int dspcntr_reg = (intel_crtc->plane == 0) ? DSPACNTR : DSPBCNTR;
 	int pipeconf = INREG(pipeconf_reg);
 	int dspcntr = INREG(dspcntr_reg);
-	int dspbase_reg = (intel_crtc->pipe == 0) ? DSPABASE : DSPBBASE;
+	int dspbase_reg = (intel_crtc->plane == 0) ? DSPABASE : DSPBBASE;
 	/* Pipe must be off here */
 	OUTREG(dspcntr_reg, dspcntr & ~DISPLAY_PLANE_ENABLE);
 	/* Flush the plane changes */
@@ -1182,11 +1182,11 @@ i830_tv_mode_set(xf86OutputPtr output, D
     OUTREG(TV_CLR_LEVEL, ((video_levels->black << TV_BLACK_LEVEL_SHIFT) |
 		(video_levels->blank << TV_BLANK_LEVEL_SHIFT)));
     {
-	int pipeconf_reg = (intel_crtc->pipe == 0)?PIPEACONF:PIPEBCONF;
-	int dspcntr_reg = (intel_crtc->pipe == 0)?DSPACNTR : DSPBCNTR;
+	int pipeconf_reg = (intel_crtc->pipe == 0) ? PIPEACONF : PIPEBCONF;
+	int dspcntr_reg = (intel_crtc->plane == 0) ? DSPACNTR : DSPBCNTR;
 	int pipeconf = INREG(pipeconf_reg);
 	int dspcntr = INREG(dspcntr_reg);
-	int dspbase_reg = (intel_crtc->pipe == 0) ? DSPABASE : DSPBBASE;
+	int dspbase_reg = (intel_crtc->plane == 0) ? DSPABASE : DSPBBASE;
 	int xpos = 0x0, ypos = 0x0;
 	unsigned int xsize, ysize;
 	/* Pipe must be off here */
diff-tree 2231cdcd8f1ee81b3e59cc5e3a325c22ee0f40e4 (from a69db6f7fe1703b473e5c1d1e0088ccc203f4d5a)
Author: Dave Airlie <airlied at redhat.com>
Date:   Thu Aug 16 17:15:54 2007 +1000

    i915: add support for render to a8

diff --git a/src/i915_render.c b/src/i915_render.c
index 7f25d90..7546dfd 100644
--- a/src/i915_render.c
+++ b/src/i915_render.c
@@ -155,16 +155,9 @@ static Bool i915_get_dest_format(Picture
     case PICT_x1r5g5b5:
         *dst_format = COLR_BUF_ARGB1555;
         break;
-    /* COLR_BUF_8BIT is special for YUV surfaces.  While we may end up being
-     * able to use it depending on how the hardware implements it, disable it
-     * for now while we don't know what exactly it does (what channel does it
-     * read from?
-     */
-    /*
     case PICT_a8:
         *dst_format = COLR_BUF_8BIT;
         break;
-    */
     case PICT_a4r4g4b4:
     case PICT_x4r4g4b4:
 	*dst_format = COLR_BUF_ARGB4444;
@@ -313,6 +306,7 @@ i915_prepare_composite(int op, PicturePt
     I830Ptr pI830 = I830PTR(pScrn);
     CARD32 dst_format, dst_offset, dst_pitch;
     CARD32 blendctl;
+    int out_reg = FS_OC;
 
     IntelEmitInvarientState(pScrn);
     *pI830->last_3d = LAST_3D_RENDER;
@@ -412,6 +406,9 @@ i915_prepare_composite(int op, PicturePt
 	ADVANCE_LP_RING();
     }
 
+    if (dst_format == COLR_BUF_8BIT)
+	out_reg = FS_U0;
+
     FS_BEGIN();
 
     /* Declare the registers necessary for our program.  I don't think the
@@ -432,7 +429,7 @@ i915_prepare_composite(int op, PicturePt
 
     if (!pMask) {
 	/* No mask, so move to output color */
-	i915_fs_mov(FS_OC, i915_fs_operand_reg(FS_R0));
+	i915_fs_mov(out_reg, i915_fs_operand_reg(FS_R0));
     } else {
 	/* Load the pMaskPicture texel */
 	i915_fs_texld(FS_R1, FS_S1, FS_T1);
@@ -453,17 +450,20 @@ i915_prepare_composite(int op, PicturePt
 	    PICT_FORMAT_RGB(pMaskPicture->format))
 	{
 	    if (i915_blend_op[op].src_alpha) {
-		i915_fs_mul(FS_OC, i915_fs_operand(FS_R0, W, W, W, W),
+		i915_fs_mul(out_reg, i915_fs_operand(FS_R0, W, W, W, W),
 			    i915_fs_operand_reg(FS_R1));
 	    } else {
-		i915_fs_mul(FS_OC, i915_fs_operand_reg(FS_R0),
+		i915_fs_mul(out_reg, i915_fs_operand_reg(FS_R0),
 			    i915_fs_operand_reg(FS_R1));
 	    }
 	} else {
-	    i915_fs_mul(FS_OC, i915_fs_operand_reg(FS_R0),
+	    i915_fs_mul(out_reg, i915_fs_operand_reg(FS_R0),
 			i915_fs_operand(FS_R1, W, W, W, W));
 	}
     }
+    if (dst_format == COLR_BUF_8BIT)
+	i915_fs_mov(FS_OC, i915_fs_operand(out_reg, W, W, W, W));
+
     FS_END();
 
     return TRUE;
diff-tree a69db6f7fe1703b473e5c1d1e0088ccc203f4d5a (from 5126a71f82767b9e23cd590453718f3364789740)
Author: Dave Airlie <airlied at redhat.com>
Date:   Wed Aug 15 18:28:50 2007 +1000

    intel: don't setup texOffsetStart unless using EXA

diff --git a/src/i830_dri.c b/src/i830_dri.c
index a4fc97c..e2b42b4 100644
--- a/src/i830_dri.c
+++ b/src/i830_dri.c
@@ -602,6 +602,7 @@ I830DRIScreenInit(ScreenPtr pScreen)
 #endif
 #if DRIINFO_MAJOR_VERSION > 5 || \
     (DRIINFO_MAJOR_VERSION == 5 && DRIINFO_MINOR_VERSION >= 3)
+      if (pI830->useEXA)
 	 pDRIInfo->texOffsetStart = I830TexOffsetStart;
 #endif
 
diff-tree 5126a71f82767b9e23cd590453718f3364789740 (from d9f89a1af7e7ff4056727060cdf2e35c15a4dcdd)
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Tue Aug 14 13:54:55 2007 +0800

    Fix seg fault introduced in tiling patch when TV detect
    
    When TV does load detect, fb hasn't been setup, so we should check
    that in i830_display_tiled(). Caught by Nanhai.

diff --git a/src/i830_display.c b/src/i830_display.c
index 7a229b2..706b9ba 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -511,7 +511,7 @@ i830_display_tiled(xf86CrtcPtr crtc)
     if (crtc->rotatedData)
 	return FALSE;
 
-    if (pI830->front_buffer->tiling != TILE_NONE)
+    if (pI830->front_buffer && pI830->front_buffer->tiling != TILE_NONE)
 	return TRUE;
 
     return FALSE;
diff-tree d9f89a1af7e7ff4056727060cdf2e35c15a4dcdd (from 5bc194d3d3c87bb0128d9ac10f090f031345eb37)
Author: Keith Packard <keithp at koto.keithp.com>
Date:   Fri Aug 10 17:59:33 2007 -0700

    Save/restore tile-mode offset registers DSPATILEOFF and DSPBTILEOFF
    
    Now that the driver sets these registers, they must be saved and restored.

diff --git a/src/i830.h b/src/i830.h
index 7ae17b4..ca48b52 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -499,6 +499,7 @@ typedef struct _I830Rec {
    CARD32 saveDSPAPOS;
    CARD32 saveDSPABASE;
    CARD32 saveDSPASURF;
+   CARD32 saveDSPATILEOFF;
    CARD32 saveFPB0;
    CARD32 saveFPB1;
    CARD32 saveDPLL_B;
@@ -515,6 +516,7 @@ typedef struct _I830Rec {
    CARD32 saveDSPBPOS;
    CARD32 saveDSPBBASE;
    CARD32 saveDSPBSURF;
+   CARD32 saveDSPBTILEOFF;
    CARD32 saveVCLK_DIVISOR_VGA0;
    CARD32 saveVCLK_DIVISOR_VGA1;
    CARD32 saveVCLK_POST_DIV;
diff --git a/src/i830_driver.c b/src/i830_driver.c
index acb8354..712b2dd 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -1816,6 +1816,8 @@ SaveHWState(ScrnInfoPtr pScrn)
    if (IS_I965G(pI830)) {
       pI830->saveDSPASURF = INREG(DSPASURF);
       pI830->saveDSPBSURF = INREG(DSPBSURF);
+      pI830->saveDSPATILEOFF = INREG(DSPATILEOFF);
+      pI830->saveDSPBTILEOFF = INREG(DSPBTILEOFF);
    }
 
    pI830->saveVCLK_DIVISOR_VGA0 = INREG(VCLK_DIVISOR_VGA0);
@@ -1910,7 +1912,10 @@ RestoreHWState(ScrnInfoPtr pScrn)
    OUTREG(PIPEASRC, pI830->savePIPEASRC);
    OUTREG(DSPABASE, pI830->saveDSPABASE);
    if (IS_I965G(pI830))
+   {
       OUTREG(DSPASURF, pI830->saveDSPASURF);
+      OUTREG(DSPATILEOFF, pI830->saveDSPATILEOFF);
+   }
    OUTREG(PIPEACONF, pI830->savePIPEACONF);
    i830WaitForVblank(pScrn);
    OUTREG(DSPACNTR, pI830->saveDSPACNTR);
@@ -1947,7 +1952,10 @@ RestoreHWState(ScrnInfoPtr pScrn)
       OUTREG(PIPEBSRC, pI830->savePIPEBSRC);
       OUTREG(DSPBBASE, pI830->saveDSPBBASE);
       if (IS_I965G(pI830))
+      {
 	 OUTREG(DSPBSURF, pI830->saveDSPBSURF);
+	 OUTREG(DSPBTILEOFF, pI830->saveDSPBTILEOFF);
+      }
       OUTREG(PIPEBCONF, pI830->savePIPEBCONF);
       i830WaitForVblank(pScrn);
       OUTREG(DSPBCNTR, pI830->saveDSPBCNTR);
diff-tree 5bc194d3d3c87bb0128d9ac10f090f031345eb37 (from 64b943c79cf957a4c54482720195d7f27b7f0c0d)
Author: Keith Packard <keithp at koto.keithp.com>
Date:   Fri Aug 10 17:54:32 2007 -0700

    Set DSPATILEOFF/DSPBTILEOFF to handle 965 tiled frame buffers.
    
    DSPATILEOFF and DSPBTILEOFF replace DSPASURF and DSPBSURF when the frame
    buffer is in tiled mode.

diff --git a/src/i830_display.c b/src/i830_display.c
index a77da1b..7a229b2 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -375,6 +375,7 @@ i830PipeSetBase(xf86CrtcPtr crtc, int x,
     unsigned long Start, Offset;
     int dspbase = (pipe == 0 ? DSPABASE : DSPBBASE);
     int dspsurf = (pipe == 0 ? DSPASURF : DSPBSURF);
+    int dsptileoff = (pipe == 0 ? DSPATILEOFF : DSPBTILEOFF);
 
     Offset = ((y * pScrn->displayWidth + x) * pI830->cpp);
     if (pI830->front_buffer == NULL) {
@@ -399,6 +400,7 @@ i830PipeSetBase(xf86CrtcPtr crtc, int x,
 	POSTING_READ(dspbase);
         OUTREG(dspsurf, Start);
 	POSTING_READ(dspsurf);
+	OUTREG(dsptileoff, (y << 16) | x);
     } else {
 	OUTREG(dspbase, Start + Offset);
 	POSTING_READ(dspbase);
diff-tree 64b943c79cf957a4c54482720195d7f27b7f0c0d (from ba9a503ba2099025e393f3382bb453985ef23497)
Author: Eric Anholt <eric at anholt.net>
Date:   Fri Aug 10 15:48:05 2007 -0700

    Add #if 0-ed fence debugging code.  It's noisy, and of little use to most.

diff --git a/src/i830_debug.c b/src/i830_debug.c
index 055ca93..8b4b76f 100644
--- a/src/i830_debug.c
+++ b/src/i830_debug.c
@@ -334,6 +334,19 @@ DEBUGSTRING(i830_debug_sdvo)
 		     enable, pipe, stall, detected, sdvoextra, gang);
 }
 
+#if 0
+DEBUGSTRING(i810_debug_fence_new)
+{
+    char *enable = (val & FENCE_VALID) ? "enabled" : "disabled";
+    char format = (val & I965_FENCE_Y_MAJOR) ? 'Y' : 'X';
+    int pitch = ((val & 0xffc) >> 2) * 128;
+    unsigned int offset = val & 0xfffff000;
+
+    return XNFprintf("%s, %c tile walk, %d pitch, 0x%08x offset",
+		     enable, format, pitch, offset);
+}
+#endif
+
 #define DEFINEREG(reg) \
 	{ reg, #reg, NULL, 0 }
 #define DEFINEREG2(reg, func) \
@@ -465,6 +478,25 @@ static struct i830SnapshotRec {
     DEFINEREG(TV_H_LUMA_59),
     DEFINEREG(TV_H_CHROMA_0),
     DEFINEREG(TV_H_CHROMA_59),
+
+#if 0
+    DEFINEREG2(FENCE_NEW + 0, i810_debug_fence_new),
+    DEFINEREG2(FENCE_NEW + 8, i810_debug_fence_new),
+    DEFINEREG2(FENCE_NEW + 16, i810_debug_fence_new),
+    DEFINEREG2(FENCE_NEW + 24, i810_debug_fence_new),
+    DEFINEREG2(FENCE_NEW + 32, i810_debug_fence_new),
+    DEFINEREG2(FENCE_NEW + 40, i810_debug_fence_new),
+    DEFINEREG2(FENCE_NEW + 48, i810_debug_fence_new),
+    DEFINEREG2(FENCE_NEW + 56, i810_debug_fence_new),
+    DEFINEREG2(FENCE_NEW + 64, i810_debug_fence_new),
+    DEFINEREG2(FENCE_NEW + 72, i810_debug_fence_new),
+    DEFINEREG2(FENCE_NEW + 80, i810_debug_fence_new),
+    DEFINEREG2(FENCE_NEW + 88, i810_debug_fence_new),
+    DEFINEREG2(FENCE_NEW + 96, i810_debug_fence_new),
+    DEFINEREG2(FENCE_NEW + 104, i810_debug_fence_new),
+    DEFINEREG2(FENCE_NEW + 112, i810_debug_fence_new),
+    DEFINEREG2(FENCE_NEW + 120, i810_debug_fence_new),
+#endif
 };
 #undef DEFINEREG
 #define NUM_I830_SNAPSHOTREGS (sizeof(i830_snapshot) / sizeof(i830_snapshot[0]))
diff-tree ba9a503ba2099025e393f3382bb453985ef23497 (from b7751c7d1d6bcf310824295c3bab4ff36760c791)
Author: Eric Anholt <eric at anholt.net>
Date:   Fri Aug 10 15:06:58 2007 -0700

    Don't force tiling on if it is disabled in configuration but fbc is possible.

diff --git a/src/i830_driver.c b/src/i830_driver.c
index 6a03ff6..acb8354 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -2275,12 +2275,6 @@ I830ScreenInit(int scrnIndex, ScreenPtr 
 	   pI830->fb_compression = FALSE;
    }
 
-   if (pI830->fb_compression && !pI830->tiling) {
-       xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Framebuffer compression enabled, "
-		  "forcing tiling on.\n");
-       pI830->tiling = TRUE;
-   }
-
    xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Framebuffer compression %sabled\n",
 	      pI830->fb_compression ? "en" : "dis");
    xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Tiling %sabled\n", pI830->tiling ?
diff-tree b7751c7d1d6bcf310824295c3bab4ff36760c791 (from cb36635a053d4ac3971fea05060d31dbd3d382d2)
Author: Eric Anholt <eric at anholt.net>
Date:   Fri Aug 10 17:42:09 2007 -0700

    Fix stack-smashing in the last commit.

diff --git a/src/i830_memory.c b/src/i830_memory.c
index 6ba2cd1..15d3a48 100644
--- a/src/i830_memory.c
+++ b/src/i830_memory.c
@@ -660,7 +660,7 @@ i830_describe_allocations(ScrnInfoPtr pS
 		   "%sMemory allocation layout:\n", prefix);
 
     for (mem = pI830->memory_list->next; mem->next != NULL; mem = mem->next) {
-	char phys_suffix[30] = "";
+	char phys_suffix[32] = "";
 	char *tile_suffix = "";
 
 	if (mem->offset >= pI830->stolen_size &&
@@ -672,7 +672,8 @@ i830_describe_allocations(ScrnInfoPtr pS
 	}
 
 	if (mem->bus_addr != 0)
-	    sprintf(phys_suffix, ", 0x%16llx physical\n", mem->bus_addr);
+	    snprintf(phys_suffix, sizeof(phys_suffix),
+		    ", 0x%016llx physical\n", mem->bus_addr);
 	if (mem->tiling == TILE_XMAJOR)
 	    tile_suffix = " X tiled";
 	else if (mem->tiling == TILE_YMAJOR)
diff-tree cb36635a053d4ac3971fea05060d31dbd3d382d2 (from ed1b106fabf3a18489bdb3083326f27387a9cb72)
Author: Eric Anholt <eric at anholt.net>
Date:   Fri Aug 10 14:16:59 2007 -0700

    Attempt to fix several front buffer tiling failure cases.
    
    Front buffer tiling is now disabled with G965 and XAA.  Some of the acceleration
    that i830_xaa.c does can't be supported on tiled buffers.
    
    Adds a tiling field to struct i830_memory, and uses it instead of separate
    variables for each potential tiled buffer.

diff --git a/src/i830.h b/src/i830.h
index f72e1d6..7ae17b4 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -117,6 +117,12 @@ typedef CARD8(*I830ReadIndexedByteFunc)(
 typedef void (*I830WriteByteFunc)(I830Ptr pI830, IOADDRESS addr, CARD8 value);
 typedef CARD8(*I830ReadByteFunc)(I830Ptr pI830, IOADDRESS addr);
 
+enum tile_format {
+    TILE_NONE,
+    TILE_XMAJOR,
+    TILE_YMAJOR
+};
+
 /** Record of a linear allocation in the aperture. */
 typedef struct _i830_memory i830_memory;
 struct _i830_memory {
@@ -148,6 +154,8 @@ struct _i830_memory {
      */
     unsigned long agp_offset;
 
+    enum tile_format tiling;
+
     /** Description of the allocation, for logging */
     char *name;
 
@@ -316,8 +324,6 @@ typedef struct _I830Rec {
 
    i830_memory *logical_context;
 
-   unsigned int front_tiled;
-
 #ifdef XF86DRI
    i830_memory *back_buffer;
    i830_memory *third_buffer;
@@ -331,10 +337,6 @@ typedef struct _I830Rec {
    int mmModeFlags;
    int mmSize;
 
-   unsigned int back_tiled;
-   unsigned int third_tiled;
-   unsigned int depth_tiled;
-
    Bool want_vblank_interrupts;
 #ifdef DAMAGE
    DamagePtr pDamage;
diff --git a/src/i830_display.c b/src/i830_display.c
index d5f7586..a77da1b 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -505,14 +505,14 @@ i830_display_tiled(xf86CrtcPtr crtc)
     ScrnInfoPtr pScrn = crtc->scrn;
     I830Ptr pI830 = I830PTR(pScrn);
 
-    if (!pI830->tiling)
-	return FALSE;
-
     /* Rotated data is currently linear, allocated either via XAA or EXA */
     if (crtc->rotatedData)
 	return FALSE;
 
-    return TRUE;
+    if (pI830->front_buffer->tiling != TILE_NONE)
+	return TRUE;
+
+    return FALSE;
 }
 
 static Bool
diff --git a/src/i830_dri.c b/src/i830_dri.c
index ca1190c..a4fc97c 100644
--- a/src/i830_dri.c
+++ b/src/i830_dri.c
@@ -1658,10 +1658,13 @@ I830UpdateDRIBuffers(ScrnInfoPtr pScrn, 
 
    I830DRIUnmapScreenRegions(pScrn, sarea);
 
-   sarea->front_tiled = pI830->front_tiled;
-   sarea->back_tiled = pI830->back_tiled;
-   sarea->third_tiled = pI830->third_tiled;
-   sarea->depth_tiled = pI830->depth_tiled;
+   sarea->front_tiled = (pI830->front_buffer->tiling != TILE_NONE);
+   sarea->back_tiled = (pI830->back_buffer->tiling != TILE_NONE);
+   if (pI830->third_buffer != NULL)
+       sarea->third_tiled = (pI830->third_buffer->tiling != TILE_NONE);
+   else
+       sarea->third_tiled = FALSE;
+   sarea->depth_tiled = (pI830->depth_buffer->tiling != TILE_NONE);
    sarea->rotated_tiled = FALSE;
 
    sarea->front_offset = pI830->front_buffer->offset;
diff --git a/src/i830_exa.c b/src/i830_exa.c
index 023a845..fdf94d7 100644
--- a/src/i830_exa.c
+++ b/src/i830_exa.c
@@ -97,19 +97,30 @@ const int I830PatternROP[16] =
     ROP_1
 };
 
-/* FIXME: use pixmap private instead */
+/**
+ * Returns whether a given pixmap is tiled or not.
+ *
+ * Currently, we only have one pixmap that might be tiled, which is the front
+ * buffer.  At the point where we are tiling some pixmaps managed by the
+ * general allocator, we should move this to using pixmap privates.
+ */
 Bool
-i830_pixmap_tiled(PixmapPtr p)
+i830_pixmap_tiled(PixmapPtr pPixmap)
 {
-    ScreenPtr pScreen = p->drawable.pScreen;
+    ScreenPtr pScreen = pPixmap->drawable.pScreen;
     ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
     I830Ptr pI830 = I830PTR(pScrn);
+    unsigned long offset;
 
-    if (!pI830->tiling)
-	return FALSE;
-
-    if (p == pScreen->GetScreenPixmap(pScreen))
+    /* Don't use exaGetPixmapOffset becuase we might be called from XAA code. */
+    offset = (long)pPixmap->devPrivate.ptr -
+	(long)pI830->FbBase;
+    if (offset == pI830->front_buffer->offset &&
+	pI830->front_buffer->tiling != TILE_NONE)
+    {
 	return TRUE;
+    }
+
     return FALSE;
 }
 
diff --git a/src/i830_memory.c b/src/i830_memory.c
index 93b054c..6ba2cd1 100644
--- a/src/i830_memory.c
+++ b/src/i830_memory.c
@@ -108,12 +108,6 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN
 
 #define ALIGN(i,m)    (((i) + (m) - 1) & ~((m) - 1))
 
-enum tile_format {
-    TILING_NONE,
-    TILING_XMAJOR,
-    TILING_YMAJOR
-};
-
 static void i830_set_fence(ScrnInfoPtr pScrn, int nr, unsigned int offset,
 			   unsigned int pitch, unsigned int size,
 			   enum tile_format tile_format);
@@ -536,6 +530,8 @@ i830_allocate_memory(ScrnInfoPtr pScrn, 
 	return NULL;
     }
 
+    mem->tiling = TILE_NONE;
+
     return mem;
 }
 
@@ -560,7 +556,7 @@ i830_allocate_memory_tiled(ScrnInfoPtr p
     i830_memory *mem;
     int fence_divide, i;
 
-    if (tile_format == TILING_NONE)
+    if (tile_format == TILE_NONE)
 	return i830_allocate_memory(pScrn, name, size, alignment, flags);
 
     /* Only allocate page-sized increments. */
@@ -637,19 +633,11 @@ i830_allocate_memory_tiled(ScrnInfoPtr p
     }
 
     mem->size = size;
+    mem->tiling = tile_format;
 
     return mem;
 }
 
-static void
-i830_describe_tiling(ScrnInfoPtr pScrn, int verbosity, const char *prefix,
-		     i830_memory *mem, unsigned int tiling_mode)
-{
-    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
-		   "%s%s is %stiled\n", prefix, mem->name,
-		   (tiling_mode == FENCE_LINEAR) ? "not " : "");
-}
-
 void
 i830_describe_allocations(ScrnInfoPtr pScrn, int verbosity, const char *prefix)
 {
@@ -672,6 +660,8 @@ i830_describe_allocations(ScrnInfoPtr pS
 		   "%sMemory allocation layout:\n", prefix);
 
     for (mem = pI830->memory_list->next; mem->next != NULL; mem = mem->next) {
+	char phys_suffix[30] = "";
+	char *tile_suffix = "";
 
 	if (mem->offset >= pI830->stolen_size &&
 	    mem->prev->offset < pI830->stolen_size)
@@ -681,42 +671,21 @@ i830_describe_allocations(ScrnInfoPtr pS
 			   prefix, pI830->stolen_size);
 	}
 
-	if (mem->bus_addr == 0) {
-	    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
-			   "%s0x%08lx-0x%08lx: %s (%ld kB)\n", prefix,
-			   mem->offset, mem->end - 1, mem->name,
-			   mem->size / 1024);
-	} else {
-	    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
-			   "%s0x%08lx-0x%08lx: %s "
-			   "(%ld kB, 0x%16llx physical)\n",
-			   prefix,
-			   mem->offset, mem->end - 1, mem->name,
-			   mem->size / 1024, mem->bus_addr);
-	}
+	if (mem->bus_addr != 0)
+	    sprintf(phys_suffix, ", 0x%16llx physical\n", mem->bus_addr);
+	if (mem->tiling == TILE_XMAJOR)
+	    tile_suffix = " X tiled";
+	else if (mem->tiling == TILE_YMAJOR)
+	    tile_suffix = " Y tiled";
+
+	xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
+		       "%s0x%08lx-0x%08lx: %s (%ld kB%s)%s\n", prefix,
+		       mem->offset, mem->end - 1, mem->name,
+		       mem->size / 1024, phys_suffix, tile_suffix);
     }
     xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
 		   "%s0x%08lx:            end of aperture\n",
 		   prefix, pI830->FbMapSize);
-
-    if (pI830->front_buffer != NULL) {
-	i830_describe_tiling(pScrn, verbosity, prefix, pI830->front_buffer,
-			     pI830->front_tiled);
-    }
-#ifdef XF86DRI
-    if (pI830->back_buffer != NULL) {
-	i830_describe_tiling(pScrn, verbosity, prefix, pI830->back_buffer,
-			     pI830->back_tiled);
-    }
-    if (pI830->third_buffer != NULL) {
-	i830_describe_tiling(pScrn, verbosity, prefix, pI830->third_buffer,
-			     pI830->third_tiled);
-    }
-    if (pI830->depth_buffer != NULL) {
-	i830_describe_tiling(pScrn, verbosity, prefix, pI830->depth_buffer,
-			     pI830->depth_tiled);
-    }
-#endif
 }
 
 static Bool
@@ -835,6 +804,7 @@ i830_allocate_framebuffer(ScrnInfoPtr pS
     long size, fb_height;
     char *name;
     i830_memory *front_buffer = NULL;
+    Bool tiling;
 
     /* Clear everything first. */
     memset(FbMemBox, 0, sizeof(*FbMemBox));
@@ -903,8 +873,17 @@ i830_allocate_framebuffer(ScrnInfoPtr pS
 
     name = secondary ? "secondary front buffer" : "front buffer";
 
+    /* Front buffer tiling has to be disabled with G965 XAA because some of the
+     * acceleration operations (non-XY COLOR_BLT) can't be done to tiled
+     * buffers.
+     */
+    if (!pI830->useEXA && IS_I965G(pI830))
+	tiling = FALSE;
+    else
+	tiling = pI830->tiling;
+
     /* Attempt to allocate it tiled first if we have page flipping on. */
-    if (pI830->tiling && IsTileable(pScrn, pitch)) {
+    if (tiling && IsTileable(pScrn, pitch)) {
 	/* XXX: probably not the case on 965 */
 	if (IS_I9XX(pI830))
 	    align = MB(1);
@@ -912,14 +891,12 @@ i830_allocate_framebuffer(ScrnInfoPtr pS
 	    align = KB(512);
 	front_buffer = i830_allocate_memory_tiled(pScrn, name, size,
 						  pitch, align,
-						  0, TILING_XMAJOR);
-	pI830->front_tiled = FENCE_XMAJOR;
+						  0, TILE_XMAJOR);
     }
 
     /* If not, attempt it linear */
     if (front_buffer == NULL) {
 	front_buffer = i830_allocate_memory(pScrn, name, size, KB(64), flags);
-	pI830->front_tiled = FENCE_LINEAR;
     }
 
     if (front_buffer == NULL) {
@@ -1240,7 +1217,7 @@ myLog2(unsigned int n)
 
 static Bool
 i830_allocate_backbuffer(ScrnInfoPtr pScrn, i830_memory **buffer,
-			 unsigned int *tiled, const char *name)
+			 const char *name)
 {
     I830Ptr pI830 = I830PTR(pScrn);
     unsigned int pitch = pScrn->displayWidth * pI830->cpp;
@@ -1258,8 +1235,7 @@ i830_allocate_backbuffer(ScrnInfoPtr pSc
 	size = ROUND_TO_PAGE(pitch * ALIGN(height, 16));
 	*buffer = i830_allocate_memory_tiled(pScrn, name, size, pitch,
 					     GTT_PAGE_SIZE, ALIGN_BOTH_ENDS,
-					     TILING_XMAJOR);
-	*tiled = FENCE_XMAJOR;
+					     TILE_XMAJOR);
     }
 
     /* Otherwise, just allocate it linear */
@@ -1267,7 +1243,6 @@ i830_allocate_backbuffer(ScrnInfoPtr pSc
 	size = ROUND_TO_PAGE(pitch * height);
 	*buffer = i830_allocate_memory(pScrn, name, size, GTT_PAGE_SIZE,
 				       ALIGN_BOTH_ENDS);
-	*tiled = FENCE_LINEAR;
     }
 
     if (*buffer == NULL) {
@@ -1303,14 +1278,12 @@ i830_allocate_depthbuffer(ScrnInfoPtr pS
 	/* The 965 requires that the depth buffer be in Y Major format, while
 	 * the rest appear to fail when handed that format.
 	 */
-	tile_format = IS_I965G(pI830) ? TILING_YMAJOR: TILING_XMAJOR;
+	tile_format = IS_I965G(pI830) ? TILE_YMAJOR: TILE_XMAJOR;
 
 	pI830->depth_buffer =
 	    i830_allocate_memory_tiled(pScrn, "depth buffer", size, pitch,
 				       GTT_PAGE_SIZE, ALIGN_BOTH_ENDS,
 				       tile_format);
-	pI830->depth_tiled = (tile_format == TILING_YMAJOR) ? FENCE_YMAJOR :
-	    FENCE_XMAJOR;
     }
 
     /* Otherwise, allocate it linear. */
@@ -1319,7 +1292,6 @@ i830_allocate_depthbuffer(ScrnInfoPtr pS
 	pI830->depth_buffer =
 	    i830_allocate_memory(pScrn, "depth buffer", size, GTT_PAGE_SIZE,
 				 0);
-	pI830->depth_tiled = FENCE_LINEAR;
     }
 
     if (pI830->depth_buffer == NULL) {
@@ -1405,13 +1377,11 @@ i830_allocate_3d_memory(ScrnInfoPtr pScr
 	    return FALSE;
     }
 
-    if (!i830_allocate_backbuffer(pScrn, &pI830->back_buffer,
-				  &pI830->back_tiled, "back buffer"))
+    if (!i830_allocate_backbuffer(pScrn, &pI830->back_buffer, "back buffer"))
 	return FALSE;
 
     if (pI830->TripleBuffer && !i830_allocate_backbuffer(pScrn,
 							 &pI830->third_buffer,
-							 &pI830->third_tiled,
 							 "third buffer")) {
        xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
 		  "Failed to allocate third buffer, triple buffering "
@@ -1447,7 +1417,7 @@ i830_set_fence(ScrnInfoPtr pScrn, int nr
     DPRINTF(PFX, "i830_set_fence(): %d, 0x%08x, %d, %d kByte\n",
 	    nr, offset, pitch, size / 1024);
 
-    assert(tile_format != TILING_NONE);
+    assert(tile_format != TILE_NONE);
 
     if (IS_I965G(pI830)) {
 	if (nr < 0 || nr >= FENCE_NEW_NR) {
@@ -1457,18 +1427,18 @@ i830_set_fence(ScrnInfoPtr pScrn, int nr
 	}
 
 	switch (tile_format) {
-	case TILING_XMAJOR:
+	case TILE_XMAJOR:
             pI830->fence[nr] = (((pitch / 128) - 1) << 2) | offset | 1;
 	    pI830->fence[nr] |= I965_FENCE_X_MAJOR;
             break;
-	case TILING_YMAJOR:
+	case TILE_YMAJOR:
             /* YMajor can be 128B aligned but the current code dictates
              * otherwise. This isn't a problem apart from memory waste.
              * FIXME */
             pI830->fence[nr] = (((pitch / 128) - 1) << 2) | offset | 1;
 	    pI830->fence[nr] |= I965_FENCE_Y_MAJOR;
             break;
-	case TILING_NONE:
+	case TILE_NONE:
             break;
 	}
 
@@ -1516,13 +1486,13 @@ i830_set_fence(ScrnInfoPtr pScrn, int nr
     val = offset | FENCE_VALID;
 
     switch (tile_format) {
-    case TILING_XMAJOR:
+    case TILE_XMAJOR:
 	val |= FENCE_X_MAJOR;
 	break;
-    case TILING_YMAJOR:
+    case TILE_YMAJOR:
 	val |= FENCE_Y_MAJOR;
 	break;
-    case TILING_NONE:
+    case TILE_NONE:
 	break;
     }
 
@@ -1590,7 +1560,7 @@ i830_set_fence(ScrnInfoPtr pScrn, int nr
     }
 
     if ((IS_I945G(pI830) || IS_I945GM(pI830) || IS_G33CLASS(pI830))
-	    && tile_format == TILING_YMAJOR)
+	    && tile_format == TILE_YMAJOR)
 	fence_pitch = pitch / 128;
     else if (IS_I9XX(pI830))
 	fence_pitch = pitch / 512;
diff --git a/src/i830_xaa.c b/src/i830_xaa.c
index aa06a80..fabac20 100644
--- a/src/i830_xaa.c
+++ b/src/i830_xaa.c
@@ -269,40 +269,39 @@ I830XAAInit(ScreenPtr pScreen)
     return TRUE;
 }
 
-#ifdef XF86DRI
 static unsigned int
-CheckTiling(ScrnInfoPtr pScrn)
+I830CheckTiling(ScrnInfoPtr pScrn)
 {
    I830Ptr pI830 = I830PTR(pScrn);
-   unsigned int tiled = 0;
 
-    /* Check tiling */
-   if (IS_I965G(pI830)) {
-      if (pI830->bufferOffset == pScrn->fbOffset && pI830->front_tiled == FENCE_XMAJOR)
-         tiled = 1;
-      if (pI830->back_buffer != NULL &&
-	  pI830->bufferOffset == pI830->back_buffer->offset &&
-	  pI830->back_tiled == FENCE_XMAJOR) {
-         tiled = 1;
-      }
-      if (pI830->third_buffer != NULL &&
-	  pI830->bufferOffset == pI830->third_buffer->offset &&
-	  pI830->third_tiled == FENCE_XMAJOR) {
-         tiled = 1;
-      }
-      /* not really supported as it's always YMajor tiled */
-      if (pI830->depth_buffer != NULL &&
-	  pI830->bufferOffset == pI830->depth_buffer->offset &&
-	  pI830->depth_tiled == FENCE_XMAJOR) {
-         tiled = 1;
-      }
+   if (pI830->bufferOffset == pI830->front_buffer->offset &&
+       pI830->front_buffer->tiling != TILE_NONE)
+   {
+       return TRUE;
+   }
+#ifdef XF86DRI
+   if (pI830->back_buffer != NULL &&
+       pI830->bufferOffset == pI830->back_buffer->offset &&
+       pI830->back_buffer->tiling != TILE_NONE)
+   {
+       return TRUE;
    }
+   if (pI830->depth_buffer != NULL &&
+       pI830->bufferOffset == pI830->depth_buffer->offset &&
+       pI830->depth_buffer->tiling != TILE_NONE)
+   {
+       return TRUE;
+   }
+   if (pI830->third_buffer != NULL &&
+       pI830->bufferOffset == pI830->third_buffer->offset &&
+       pI830->third_buffer->tiling != TILE_NONE)
+   {
+       return TRUE;
+   }
+#endif
 
-   return tiled;
+   return FALSE;
 }
-#else
-#define CheckTiling(pScrn) 0
-#endif
 
 void
 I830SetupForSolidFill(ScrnInfoPtr pScrn, int color, int rop,
@@ -314,16 +313,20 @@ I830SetupForSolidFill(ScrnInfoPtr pScrn,
 	ErrorF("I830SetupForFillRectSolid color: %x rop: %x mask: %x\n",
 	       color, rop, planemask);
 
+    if (IS_I965G(pI830) && I830CheckTiling(pScrn)) {
+	pI830->BR[13] = (pScrn->displayWidth * pI830->cpp) >> 4;
+    } else {
+	pI830->BR[13] = (pScrn->displayWidth * pI830->cpp);
+    }
+
 #ifdef I830_USE_EXA
     /* This function gets used by I830DRIInitBuffers(), and we might not have
      * XAAGetPatternROP() available.  So just use the ROPs from our EXA code
      * if available.
      */
-    pI830->BR[13] = ((I830PatternROP[rop] << 16) |
-		     (pScrn->displayWidth * pI830->cpp));
+    pI830->BR[13] |= (I830PatternROP[rop] << 16);
 #else
-    pI830->BR[13] = ((XAAGetPatternROP(rop) << 16) |
-		     (pScrn->displayWidth * pI830->cpp));
+    pI830->BR[13] |= ((XAAGetPatternROP(rop) << 16);
 #endif
 
     pI830->BR[16] = color;
@@ -381,7 +384,12 @@ I830SetupForScreenToScreenCopy(ScrnInfoP
 	ErrorF("I830SetupForScreenToScreenCopy %d %d %x %x %d\n",
 	       xdir, ydir, rop, planemask, transparency_color);
 
-    pI830->BR[13] = (pScrn->displayWidth * pI830->cpp);
+    if (IS_I965G(pI830) && I830CheckTiling(pScrn)) {
+	pI830->BR[13] = (pScrn->displayWidth * pI830->cpp) >> 4;
+    } else {
+	pI830->BR[13] = (pScrn->displayWidth * pI830->cpp);
+    }
+
 #ifdef I830_USE_EXA
     /* This function gets used by I830DRIInitBuffers(), and we might not have
      * XAAGetCopyROP() available.  So just use the ROPs from our EXA code
@@ -411,7 +419,7 @@ I830SubsequentScreenToScreenCopy(ScrnInf
 {
     I830Ptr pI830 = I830PTR(pScrn);
     int dst_x2, dst_y2;
-    unsigned int tiled = CheckTiling(pScrn);
+    unsigned int tiled = I830CheckTiling(pScrn);
 
     if (I810_DEBUG & DEBUG_VERBOSE_ACCEL)
 	ErrorF("I830SubsequentScreenToScreenCopy %d,%d - %d,%d %dx%d\n",
@@ -420,10 +428,6 @@ I830SubsequentScreenToScreenCopy(ScrnInf
     dst_x2 = dst_x1 + w;
     dst_y2 = dst_y1 + h;
 
-    if (tiled)
-        pI830->BR[13] = ((pI830->BR[13] & 0xFFFF) >> 2) | 
-					(pI830->BR[13] & 0xFFFF0000);
-
     {
 	BEGIN_LP_RING(8);
 
@@ -463,7 +467,11 @@ I830SetupForMono8x8PatternFill(ScrnInfoP
     pI830->BR[18] = bg;
     pI830->BR[19] = fg;
 
-    pI830->BR[13] = (pScrn->displayWidth * pI830->cpp);	/* In bytes */
+    if (IS_I965G(pI830) && I830CheckTiling(pScrn)) {
+	pI830->BR[13] = (pScrn->displayWidth * pI830->cpp) >> 4;
+    } else {
+	pI830->BR[13] = (pScrn->displayWidth * pI830->cpp);
+    }
     pI830->BR[13] |= XAAGetPatternROP(rop) << 16;
     if (bg == -1)
 	pI830->BR[13] |= (1 << 28);
@@ -487,7 +495,7 @@ I830SubsequentMono8x8PatternFillRect(Scr
 {
     I830Ptr pI830 = I830PTR(pScrn);
     int x1, x2, y1, y2;
-    unsigned int tiled = CheckTiling(pScrn);
+    unsigned int tiled = I830CheckTiling(pScrn);
 
     x1 = x;
     x2 = x + w;
@@ -497,10 +505,6 @@ I830SubsequentMono8x8PatternFillRect(Scr
     if (I810_DEBUG & DEBUG_VERBOSE_ACCEL)
 	ErrorF("I830SubsequentMono8x8PatternFillRect\n");
 
-    if (tiled)
-        pI830->BR[13] = ((pI830->BR[13] & 0xFFFF) >> 2) | 
-					(pI830->BR[13] & 0xFFFF0000);
-
     {
 	BEGIN_LP_RING(10);
 
@@ -560,7 +564,11 @@ I830SetupForScanlineCPUToScreenColorExpa
 	       fg, bg, rop, planemask);
 
     /* Fill out register values */
-    pI830->BR[13] = (pScrn->displayWidth * pI830->cpp);
+    if (IS_I965G(pI830) && I830CheckTiling(pScrn)) {
+	pI830->BR[13] = (pScrn->displayWidth * pI830->cpp) >> 4;
+    } else {
+	pI830->BR[13] = (pScrn->displayWidth * pI830->cpp);
+    }
     pI830->BR[13] |= XAAGetCopyROP(rop) << 16;
     if (bg == -1)
 	pI830->BR[13] |= (1 << 29);
@@ -603,7 +611,7 @@ static void
 I830SubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno)
 {
     I830Ptr pI830 = I830PTR(pScrn);
-    unsigned int tiled = CheckTiling(pScrn);
+    unsigned int tiled = I830CheckTiling(pScrn);
 
     if (pI830->init == 0) {
 	pI830->BR[12] = (pI830->AccelInfoRec->ScanlineColorExpandBuffers[0] -
@@ -621,10 +629,6 @@ I830SubsequentColorExpandScanline(ScrnIn
 	ErrorF("I830SubsequentColorExpandScanline %d (addr %x)\n",
 	       bufno, pI830->BR[12]);
 
-    if (tiled)
-        pI830->BR[13] = ((pI830->BR[13] & 0xFFFF) >> 2) | 
-					(pI830->BR[13] & 0xFFFF0000);
-
     {
 	BEGIN_LP_RING(8);
 
@@ -666,7 +670,11 @@ I830SetupForScanlineImageWrite(ScrnInfoP
 	ErrorF("I830SetupForScanlineImageWrite %x %x\n", rop, planemask);
 
     /* Fill out register values */
-    pI830->BR[13] = (pScrn->displayWidth * pI830->cpp);
+    if (IS_I965G(pI830) && I830CheckTiling(pScrn)) {
+	pI830->BR[13] = (pScrn->displayWidth * pI830->cpp) >> 4;
+    } else {
+	pI830->BR[13] = (pScrn->displayWidth * pI830->cpp);
+    }
     pI830->BR[13] |= XAAGetCopyROP(rop) << 16;
 
     switch (pScrn->bitsPerPixel) {
@@ -703,7 +711,7 @@ static void
 I830SubsequentImageWriteScanline(ScrnInfoPtr pScrn, int bufno)
 {
     I830Ptr pI830 = I830PTR(pScrn);
-    unsigned int tiled = CheckTiling(pScrn);
+    unsigned int tiled = I830CheckTiling(pScrn);
 
     if (pI830->init == 0) {
 	pI830->BR[12] = (pI830->AccelInfoRec->ScanlineColorExpandBuffers[0] -
diff --git a/src/i915_render.c b/src/i915_render.c
index 9c937f2..7f25d90 100644
--- a/src/i915_render.c
+++ b/src/i915_render.c
@@ -285,10 +285,9 @@ i915_texture_setup(PicturePtr pPict, Pix
 
     pI830->mapstate[unit * 3 + 0] = offset;
     pI830->mapstate[unit * 3 + 1] = format |
+	MS3_USE_FENCE_REGS |
 	((pPix->drawable.height - 1) << MS3_HEIGHT_SHIFT) |
 	((pPix->drawable.width - 1) << MS3_WIDTH_SHIFT);
-    if (pI830->tiling)
-	pI830->mapstate[unit * 3 + 1] |= MS3_USE_FENCE_REGS;
     pI830->mapstate[unit * 3 + 2] = ((pitch / 4) - 1) << MS4_PITCH_SHIFT;
 
     pI830->samplerstate[unit * 3 + 0] = (MIPFILTER_NONE <<
diff --git a/src/i915_video.c b/src/i915_video.c
index e116fe2..a6447b1 100644
--- a/src/i915_video.c
+++ b/src/i915_video.c
@@ -149,7 +149,7 @@ I915DisplayVideoTextured(ScrnInfoPtr pSc
       OUT_RING(_3DSTATE_MAP_STATE | 3);
       OUT_RING(0x00000001);	/* texture map #1 */
       OUT_RING(pPriv->YBuf0offset);
-      ms3 = MAPSURF_422;
+      ms3 = MAPSURF_422 | MS3_USE_FENCE_REGS;
       switch (id) {
       case FOURCC_YUY2:
 	 ms3 |= MT_422_YCRCB_NORMAL;
@@ -160,8 +160,6 @@ I915DisplayVideoTextured(ScrnInfoPtr pSc
       }
       ms3 |= (height - 1) << MS3_HEIGHT_SHIFT;
       ms3 |= (width - 1) << MS3_WIDTH_SHIFT;
-      if (pI830->tiling)
-	 ms3 |= MS3_USE_FENCE_REGS;
       OUT_RING(ms3);
       OUT_RING(((video_pitch / 4) - 1) << MS4_PITCH_SHIFT);
       ADVANCE_LP_RING();
@@ -248,29 +246,23 @@ I915DisplayVideoTextured(ScrnInfoPtr pSc
       OUT_RING(0x00000007);
 
       OUT_RING(pPriv->YBuf0offset);
-      ms3 = MAPSURF_8BIT | MT_8BIT_I8;
+      ms3 = MAPSURF_8BIT | MT_8BIT_I8 | MS3_USE_FENCE_REGS;
       ms3 |= (height - 1) << MS3_HEIGHT_SHIFT;
       ms3 |= (width - 1) << MS3_WIDTH_SHIFT;
-      if (pI830->tiling)
-	 ms3 |= MS3_USE_FENCE_REGS;
       OUT_RING(ms3);
       OUT_RING(((video_pitch * 2 / 4) - 1) << MS4_PITCH_SHIFT);
 
       OUT_RING(pPriv->UBuf0offset);
-      ms3 = MAPSURF_8BIT | MT_8BIT_I8;
+      ms3 = MAPSURF_8BIT | MT_8BIT_I8 | MS3_USE_FENCE_REGS;
       ms3 |= (height / 2 - 1) << MS3_HEIGHT_SHIFT;
       ms3 |= (width / 2 - 1) << MS3_WIDTH_SHIFT;
-      if (pI830->tiling)
-	 ms3 |= MS3_USE_FENCE_REGS;
       OUT_RING(ms3);
       OUT_RING(((video_pitch / 4) - 1) << MS4_PITCH_SHIFT);
 
       OUT_RING(pPriv->VBuf0offset);
-      ms3 = MAPSURF_8BIT | MT_8BIT_I8;
+      ms3 = MAPSURF_8BIT | MT_8BIT_I8 | MS3_USE_FENCE_REGS;
       ms3 |= (height / 2 - 1) << MS3_HEIGHT_SHIFT;
       ms3 |= (width / 2 - 1) << MS3_WIDTH_SHIFT;
-      if (pI830->tiling)
-	 ms3 |= MS3_USE_FENCE_REGS;
       OUT_RING(ms3);
       OUT_RING(((video_pitch / 4) - 1) << MS4_PITCH_SHIFT);
       ADVANCE_LP_RING();
diff-tree ed1b106fabf3a18489bdb3083326f27387a9cb72 (from f71b9358b4157a8cfdc694ddef8ca3f98926ca91)
Author: Keith Packard <keithp at koto.keithp.com>
Date:   Fri Aug 10 14:31:16 2007 -0700

    Clean up tv mode name allocation and copy.
    
    TV mode names used to contain the signalling standard along with the pixel
    size. The signalling has been moved to the TV_FORMAT property, but the
    allocation and initialization of the mode name was left a bit messy as a
    result.

diff --git a/src/i830_tv.c b/src/i830_tv.c
index aba0e3b..e3aeaf9 100644
--- a/src/i830_tv.c
+++ b/src/i830_tv.c
@@ -1415,10 +1415,8 @@ i830_tv_get_modes(xf86OutputPtr output)
 	    continue;
 
 	mode_ptr = xnfcalloc(1, sizeof(DisplayModeRec));
-    	mode_ptr->name = xnfalloc(strlen(tv_mode->name) + 
-				  strlen(input->name) + 4);
-	sprintf(mode_ptr->name, "%s", input->name);
-
+    	mode_ptr->name = xnfalloc(strlen(input->name) + 1);
+	strcpy (mode_ptr->name, input->name);
 
 	mode_ptr->HDisplay = hactive_s;
 	mode_ptr->HSyncStart = hactive_s + 1;
diff-tree f71b9358b4157a8cfdc694ddef8ca3f98926ca91 (from e6746d0f286ef9d9a87f748d40e5421c268f2f7d)
Author: Jesse Barnes <jesse.barnes at intel.com>
Date:   Fri Aug 10 15:53:04 2007 -0400

    Cleanup tiling and FBC driver output.
    
    Remove an extra "FBC enabled" message from i830_memory.c (only report errors
    if they occur), and don't print the "forcing FBC on" message if tiling was
    already enabled, as it's redundant and confusing.

diff --git a/src/i830_driver.c b/src/i830_driver.c
index 693e12a..6a03ff6 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -2275,7 +2275,7 @@ I830ScreenInit(int scrnIndex, ScreenPtr 
 	   pI830->fb_compression = FALSE;
    }
 
-   if (pI830->fb_compression) {
+   if (pI830->fb_compression && !pI830->tiling) {
        xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Framebuffer compression enabled, "
 		  "forcing tiling on.\n");
        pI830->tiling = TRUE;
diff --git a/src/i830_memory.c b/src/i830_memory.c
index ccd26b3..93b054c 100644
--- a/src/i830_memory.c
+++ b/src/i830_memory.c
@@ -1073,10 +1073,7 @@ static void i830_setup_fb_compression(Sc
     }
 
 out:
-    if (pI830->fb_compression)
-	xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Framebuffer compression "
-		   "enabled\n");
-    else
+    if (!pI830->fb_compression)
 	xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Allocation error, framebuffer"
 		   " compression disabled\n");
 	
diff-tree e6746d0f286ef9d9a87f748d40e5421c268f2f7d (from e0fcf645a228094620b8f7fdd580963611bdd6ef)
Author: Jesse Barnes <jesse.barnes at intel.com>
Date:   Fri Aug 10 15:48:15 2007 -0400

    Enable tiling by default on 965.

diff --git a/man/intel.man b/man/intel.man
index 5909fdd..2b19711 100644
--- a/man/intel.man
+++ b/man/intel.man
@@ -85,7 +85,7 @@ Default: enabled on supported configurat
 .BI "Option \*qTiling\*q \*q" boolean \*q
 This option controls whether memory buffers are allocated in tiled mode.  In
 many cases (especially for complex rendering), tiling can improve performance.
-Default: enabled on supported configurations.
+Default: enabled.
 .TP
 .BI "Option \*qDRI\*q \*q" boolean \*q
 Disable or enable DRI support.
diff --git a/src/i830.h b/src/i830.h
index 17dfb72..f72e1d6 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -721,17 +721,8 @@ i830_get_transformed_coordinates(int x, 
 
 void i830_enter_render(ScrnInfoPtr);
 
-static inline int i830_tiling_supported(I830Ptr pI830)
-{
-    if (IS_I965G(pI830))
-	return FALSE;
-    return TRUE;
-}
-
 static inline int i830_fb_compression_supported(I830Ptr pI830)
 {
-    if (!i830_tiling_supported(pI830))
-	return FALSE;
     if (!IS_MOBILE(pI830))
 	return FALSE;
     if (IS_I810(pI830) || IS_I815(pI830) || IS_I830(pI830))
diff --git a/src/i830_driver.c b/src/i830_driver.c
index f293bfd..693e12a 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -2250,11 +2250,8 @@ I830ScreenInit(int scrnIndex, ScreenPtr 
       pI830->CacheLines = -1;
    }
 
-   /* Enable tiling by default where supported */
-   if (i830_tiling_supported(pI830))
-       pI830->tiling = TRUE;
-   else
-       pI830->tiling = FALSE;
+   /* Enable tiling by default */
+   pI830->tiling = TRUE;
 
    /* Allow user override if they set a value */
    if (xf86IsOptionSet(pI830->Options, OPTION_TILING)) {
diff-tree e0fcf645a228094620b8f7fdd580963611bdd6ef (from 7b143e5c8397da077c0e02455c21c5a99cf50942)
Author: Jesse Barnes <jesse.barnes at intel.com>
Date:   Fri Aug 10 15:43:06 2007 -0400

    Tiling fixes for 965
    
    This should be close to the last set of tiling fixes for 965 chipsets.
    Prior to this commit, the 965 composite hook didn't take tiling into
    account, nor did 965 textured video, which caused display corruption.
    However, there seems to be at least one last bug to squash--on occasion,
    a configuration with tiling enabled won't properly display text.  This
    is likely another tiling related problem with the composite hook.

diff --git a/src/i830.h b/src/i830.h
index c2321d4..17dfb72 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -739,6 +739,8 @@ static inline int i830_fb_compression_su
     return TRUE;
 }
 
+Bool i830_pixmap_tiled(PixmapPtr p);
+
 extern const int I830PatternROP[16];
 extern const int I830CopyROP[16];
 
diff --git a/src/i830_display.c b/src/i830_display.c
index 6fe7be7..d5f7586 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -498,6 +498,23 @@ i830_pipe_a_require_deactivate (ScrnInfo
     return;
 }
 
+/* FIXME: use pixmap private instead if possible */
+static Bool
+i830_display_tiled(xf86CrtcPtr crtc)
+{
+    ScrnInfoPtr pScrn = crtc->scrn;
+    I830Ptr pI830 = I830PTR(pScrn);
+
+    if (!pI830->tiling)
+	return FALSE;
+
+    /* Rotated data is currently linear, allocated either via XAA or EXA */
+    if (crtc->rotatedData)
+	return FALSE;
+
+    return TRUE;
+}
+
 static Bool
 i830_use_fb_compression(xf86CrtcPtr crtc)
 {
@@ -510,6 +527,9 @@ i830_use_fb_compression(xf86CrtcPtr crtc
     if (!pI830->fb_compression)
 	return FALSE;
 
+    if (!i830_display_tiled(crtc))
+	return FALSE;
+
     /* Pre-965 only supports plane A */
     if (!IS_I965GM(pI830) && plane != FBC_CTL_PLANEA)
 	return FALSE;
@@ -1078,7 +1098,7 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, Dis
     else
 	dspcntr |= DISPPLANE_SEL_PIPE_B;
 
-    if (pI830->tiling)
+    if (IS_I965G(pI830) && i830_display_tiled(crtc))
 	dspcntr |= DISPLAY_PLANE_TILED;
 
     pipeconf = INREG(pipeconf_reg);
diff --git a/src/i830_exa.c b/src/i830_exa.c
index b0029d1..023a845 100644
--- a/src/i830_exa.c
+++ b/src/i830_exa.c
@@ -97,8 +97,9 @@ const int I830PatternROP[16] =
     ROP_1
 };
 
-static Bool
-exaPixmapTiled(PixmapPtr p)
+/* FIXME: use pixmap private instead */
+Bool
+i830_pixmap_tiled(PixmapPtr p)
 {
     ScreenPtr pScreen = p->drawable.pScreen;
     ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
@@ -189,7 +190,7 @@ I830EXASolid(PixmapPtr pPixmap, int x1, 
 	if (pPixmap->drawable.bitsPerPixel == 32)
 	    cmd |= XY_COLOR_BLT_WRITE_ALPHA | XY_COLOR_BLT_WRITE_RGB;
 
-	if (IS_I965G(pI830) && exaPixmapTiled(pPixmap)) {
+	if (IS_I965G(pI830) && i830_pixmap_tiled(pPixmap)) {
 	    assert((pitch % 512) == 0);
 	    pitch >>= 2;
 	    cmd |= XY_COLOR_BLT_TILED;
@@ -274,13 +275,13 @@ I830EXACopy(PixmapPtr pDstPixmap, int sr
 	    cmd |= XY_SRC_COPY_BLT_WRITE_ALPHA | XY_SRC_COPY_BLT_WRITE_RGB;
 
 	if (IS_I965G(pI830)) {
-	    if (exaPixmapTiled(pDstPixmap)) {
+	    if (i830_pixmap_tiled(pDstPixmap)) {
 		assert((dst_pitch % 512) == 0);
 		dst_pitch >>= 2;
 		cmd |= XY_SRC_COPY_BLT_DST_TILED;
 	    }
 
-	    if (exaPixmapTiled(pI830->pSrcPixmap)) {
+	    if (i830_pixmap_tiled(pI830->pSrcPixmap)) {
 		assert((src_pitch % 512) == 0);
 		src_pitch >>= 2;
 		cmd |= XY_SRC_COPY_BLT_SRC_TILED;
diff --git a/src/i965_render.c b/src/i965_render.c
index ec64ddd..ad3b53e 100644
--- a/src/i965_render.c
+++ b/src/i965_render.c
@@ -392,9 +392,11 @@ i965_prepare_composite(int op, PicturePt
 {
     ScrnInfoPtr pScrn = xf86Screens[pSrcPicture->pDrawable->pScreen->myNum];
     I830Ptr pI830 = I830PTR(pScrn);
-    CARD32 src_offset, src_pitch;
-    CARD32 mask_offset = 0, mask_pitch = 0;
-    CARD32 dst_format, dst_offset, dst_pitch;
+    CARD32 src_offset, src_pitch, src_tile_format = 0, src_tiled = 0;
+    CARD32 mask_offset = 0, mask_pitch = 0, mask_tile_format = 0,
+	mask_tiled = 0;
+    CARD32 dst_format, dst_offset, dst_pitch, dst_tile_format = 0,
+	dst_tiled = 0;
     Bool rotation_program = FALSE;
 
     IntelEmitInvarientState(pScrn);
@@ -402,11 +404,23 @@ i965_prepare_composite(int op, PicturePt
 
     src_offset = intel_get_pixmap_offset(pSrc);
     src_pitch = intel_get_pixmap_pitch(pSrc);
+    if (i830_pixmap_tiled(pSrc)) {
+	src_tiled = 1;
+	src_tile_format = 0; /* Tiled X */
+    }
     dst_offset = intel_get_pixmap_offset(pDst);
     dst_pitch = intel_get_pixmap_pitch(pDst);
+    if (i830_pixmap_tiled(pDst)) {
+	dst_tiled = 1;
+	dst_tile_format = 0; /* Tiled X */
+    }
     if (pMask) {
 	mask_offset = intel_get_pixmap_offset(pMask);
 	mask_pitch = intel_get_pixmap_pitch(pMask);
+	if (i830_pixmap_tiled(pMask)) {
+	    mask_tiled = 1;
+	    mask_tile_format = 0; /* Tiled X */
+	}
     }
     pI830->scale_units[0][0] = pSrc->drawable.width;
     pI830->scale_units[0][1] = pSrc->drawable.height;
@@ -634,6 +648,8 @@ i965_prepare_composite(int op, PicturePt
     dest_surf_state->ss2.mip_count = 0;
     dest_surf_state->ss2.render_target_rotation = 0;
     dest_surf_state->ss3.pitch = dst_pitch - 1;
+    dest_surf_state->ss3.tile_walk = dst_tile_format;
+    dest_surf_state->ss3.tiled_surface = dst_tiled;
 
     dest_surf_state = (void *)(state_base + dest_surf_offset);
     memcpy (dest_surf_state, &dest_surf_state_local, sizeof (dest_surf_state_local));
@@ -660,6 +676,8 @@ i965_prepare_composite(int op, PicturePt
     src_surf_state->ss2.mip_count = 0;
     src_surf_state->ss2.render_target_rotation = 0;
     src_surf_state->ss3.pitch = src_pitch - 1;
+    src_surf_state->ss3.tile_walk = src_tile_format;
+    src_surf_state->ss3.tiled_surface = src_tiled;
 
     src_surf_state = (void *)(state_base + src_surf_offset);
     memcpy (src_surf_state, &src_surf_state_local, sizeof (src_surf_state_local));
@@ -688,6 +706,8 @@ i965_prepare_composite(int op, PicturePt
    	mask_surf_state->ss2.mip_count = 0;
    	mask_surf_state->ss2.render_target_rotation = 0;
    	mask_surf_state->ss3.pitch = mask_pitch - 1;
+	mask_surf_state->ss3.tile_walk = mask_tile_format;
+	mask_surf_state->ss3.tiled_surface = mask_tiled;
 
 	mask_surf_state = (void *)(state_base + mask_surf_offset);
 	memcpy (mask_surf_state, &mask_surf_state_local, sizeof (mask_surf_state_local));
diff --git a/src/i965_video.c b/src/i965_video.c
index 3084233..6ed7f01 100644
--- a/src/i965_video.c
+++ b/src/i965_video.c
@@ -378,6 +378,8 @@ I965DisplayVideoTextured(ScrnInfoPtr pSc
     dest_surf_state->ss2.mip_count = 0;
     dest_surf_state->ss2.render_target_rotation = 0;
     dest_surf_state->ss3.pitch = pPixmap->devKind - 1;
+    dest_surf_state->ss3.tiled_surface = i830_pixmap_tiled(pPixmap);
+    dest_surf_state->ss3.tile_walk = 0; /* TileX */
 
     /* Set up the source surface state buffer */
     memset(src_surf_state, 0, sizeof(*src_surf_state));
@@ -408,6 +410,7 @@ I965DisplayVideoTextured(ScrnInfoPtr pSc
     src_surf_state->ss2.mip_count = 0;
     src_surf_state->ss2.render_target_rotation = 0;
     src_surf_state->ss3.pitch = video_pitch - 1;
+    /* FIXME: account for tiling if we ever do it */
 
     /* Set up a binding table for our two surfaces.  Only the PS will use it */
     /* XXX: are these offset from the right place? */
diff-tree 7b143e5c8397da077c0e02455c21c5a99cf50942 (from 14691b24da5aa29d8c41ac7b7c61828e3cd9eab7)
Author: Dave Airlie <airlied at redhat.com>
Date:   Thu Aug 9 12:14:44 2007 +1000

    i965: increase composite vertex buffer size and alignment to be safe

diff --git a/src/i965_render.c b/src/i965_render.c
index 018208a..ec64ddd 100644
--- a/src/i965_render.c
+++ b/src/i965_render.c
@@ -285,7 +285,7 @@ static int next_offset, total_state_size
 static char *state_base;
 static int state_base_offset;
 static float *vb;
-static int vb_size = (4 * 4) * 4 ; /* 4 DWORDS per vertex*/
+static int vb_size = (6 * 4) * 4 ; /* 6 DWORDS per vertex - and mask*/
 
 static CARD32 src_blend, dst_blend;
 
@@ -496,7 +496,7 @@ i965_prepare_composite(int op, PicturePt
    	next_offset = mask_sampler_offset + sizeof(*mask_sampler_state);
     }
     /* Align VB to native size of elements, for safety */
-    vb_offset = ALIGN(next_offset, 8);
+    vb_offset = ALIGN(next_offset, 32);
     next_offset = vb_offset + vb_size;
 
     /* And then the general state: */
diff-tree 14691b24da5aa29d8c41ac7b7c61828e3cd9eab7 (from 5e18c6af9051da654d2a6a97553ef4fe777bb61e)
Author: Dave Airlie <airlied at linux.ie>
Date:   Thu Aug 9 09:41:32 2007 +1000

    i965: fix memcpy of the sf_kernel when a mask is needed

diff --git a/src/i965_render.c b/src/i965_render.c
index c528813..018208a 100644
--- a/src/i965_render.c
+++ b/src/i965_render.c
@@ -793,7 +793,8 @@ i965_prepare_composite(int op, PicturePt
      * back to SF which then hands pixels off to WM.
      */
     if (pMask)
-	memcpy(sf_kernel, sf_kernel_static_mask, sizeof (sf_kernel_static));
+	memcpy(sf_kernel, sf_kernel_static_mask,
+		sizeof (sf_kernel_static_mask));
     else if (rotation_program)
 	memcpy(sf_kernel, sf_kernel_static_rotation, 
 		sizeof (sf_kernel_static_rotation));
diff-tree 5e18c6af9051da654d2a6a97553ef4fe777bb61e (from b0ec670cdb0b6ca6fc0f4f165fa3ee5a20d7c985)
Author: Carl Worth <cworth at cworth.org>
Date:   Wed Aug 8 11:13:37 2007 -0700

    Allow 965 composite acceleration to A8 destinations.
    
    Note that this is a slowdown in text rendering due to the high overhead of our
    compositing setup, but appears to be correct according to rendercheck.

diff --git a/src/i965_render.c b/src/i965_render.c
index 744501a..c528813 100644
--- a/src/i965_render.c
+++ b/src/i965_render.c
@@ -161,16 +161,9 @@ static Bool i965_get_dest_format(Picture
     case PICT_x1r5g5b5:
         *dst_format = BRW_SURFACEFORMAT_B5G5R5X1_UNORM;
         break;
-    /* COLR_BUF_8BIT is special for YUV surfaces.  While we may end up being
-     * able to use it depending on how the hardware implements it, disable it
-     * for now while we don't know what exactly it does (what channel does it
-     * read from?
-     */
-    /*
     case PICT_a8:
-        *dst_format = COLR_BUF_8BIT;
+        *dst_format = BRW_SURFACEFORMAT_A8_UNORM;
         break;
-    */
     case PICT_a4r4g4b4:
     case PICT_x4r4g4b4:
 	*dst_format = BRW_SURFACEFORMAT_B4G4R4A4_UNORM;
diff-tree b0ec670cdb0b6ca6fc0f4f165fa3ee5a20d7c985 (from 92af2f4bbcb395cbde097776718449d99843ad67)
Author: Eric Anholt <eric at anholt.net>
Date:   Wed Aug 8 11:03:51 2007 -0700

    Bug #11593: Remove dead struct vch_bdb_20 which was angering the sun compiler.

diff --git a/src/i830_bios.h b/src/i830_bios.h
index cb7666e..9e8356a 100644
--- a/src/i830_bios.h
+++ b/src/i830_bios.h
@@ -130,9 +130,6 @@ struct aimdb_block {
     CARD16  aimdb_size;
 } __attribute__((packed));
 
-struct vch_bdb_20 {
-} __attribute__((packed));
-
 struct vch_panel_data {
     CARD16	fp_timing_offset;
     CARD8	fp_timing_size;
diff-tree 92af2f4bbcb395cbde097776718449d99843ad67 (from parents)
Merge: da82a47a558597f3653e2b33bc6adbab18574b57 e0be352f5017f0e645a4ff8a40961d9c2b98863a
Author: Eric Anholt <eric at anholt.net>
Date:   Tue Aug 7 15:18:17 2007 -0700

    Merge branch 'origin'
    
    Conflicts:
    
    	src/i830_exa.c

diff-tree da82a47a558597f3653e2b33bc6adbab18574b57 (from 3510d5728fa972b36d022b4f9189d46ff98d7b16)
Author: Eric Anholt <eric at anholt.net>
Date:   Mon Aug 6 17:01:37 2007 -0700

    Fix EXA rendering with tiled front buffer on pre-965.
    
    The 915 and earlier appear to respect the fence registers, while only the 965
    requires the per-operation tiling setting and pitch shifting.  This will also
    fix issues with rendering on the 965 involving multiple cliprects, where the
    pitch would get divided repeatedly.
    
    This removes the offset < 4096 fallback, which essentially resulted in no
    acceleration to tiled buffers, hiding the issues.

diff --git a/src/i830.h b/src/i830.h
index 64a3690..c2321d4 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -405,10 +405,8 @@ typedef struct _I830Rec {
    CloseScreenProcPtr CloseScreen;
 
 #ifdef I830_USE_EXA
-   unsigned int copy_src_pitch;
-   unsigned int copy_src_off;
-   unsigned int copy_src_tiled;
    ExaDriverPtr	EXADriverPtr;
+   PixmapPtr pSrcPixmap;
 #endif
 
    I830WriteIndexedByteFunc writeControl;
diff --git a/src/i830_exa.c b/src/i830_exa.c
index 19f4e30..b0029d1 100644
--- a/src/i830_exa.c
+++ b/src/i830_exa.c
@@ -152,10 +152,8 @@ I830EXAPrepareSolid(PixmapPtr pPixmap, i
 	I830FALLBACK("pixmap offset not aligned");
     if (pitch % pI830->EXADriverPtr->pixmapPitchAlign != 0)
 	I830FALLBACK("pixmap pitch not aligned");
-    if (exaPixmapTiled(pPixmap) && offset > 4096)
-	I830FALLBACK("offset limited to 4k for tiled targets");
 
-    pI830->BR[13] = (pitch & 0xffff);
+    pI830->BR[13] = (I830PatternROP[alu] & 0xff) << 16 ;
     switch (pPixmap->drawable.bitsPerPixel) {
 	case 8:
 	    break;
@@ -168,7 +166,6 @@ I830EXAPrepareSolid(PixmapPtr pPixmap, i
 	    pI830->BR[13] |= ((1 << 24) | (1 << 25));
 	    break;
     }
-    pI830->BR[13] |= (I830PatternROP[alu] & 0xff) << 16 ;
     pI830->BR[16] = fg;
     return TRUE;
 }
@@ -178,10 +175,11 @@ I830EXASolid(PixmapPtr pPixmap, int x1, 
 {
     ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
     I830Ptr pI830 = I830PTR(pScrn);
-    unsigned long offset;
+    unsigned long offset, pitch;
     uint32_t cmd;
 
     offset = exaGetPixmapOffset(pPixmap);
+    pitch = exaGetPixmapPitch(pPixmap);
 
     {
 	BEGIN_LP_RING(6);
@@ -191,16 +189,15 @@ I830EXASolid(PixmapPtr pPixmap, int x1, 
 	if (pPixmap->drawable.bitsPerPixel == 32)
 	    cmd |= XY_COLOR_BLT_WRITE_ALPHA | XY_COLOR_BLT_WRITE_RGB;
 
-	if (exaPixmapTiled(pPixmap)) {
-	    /* Fixup pitch for destination if tiled */
-	    pI830->BR[13] = (ROUND_TO(pI830->BR[13] & 0xffff, 512) >> 2) |
-		(pI830->BR[13] & 0xffff0000);
+	if (IS_I965G(pI830) && exaPixmapTiled(pPixmap)) {
+	    assert((pitch % 512) == 0);
+	    pitch >>= 2;
 	    cmd |= XY_COLOR_BLT_TILED;
 	}
 
 	OUT_RING(cmd);
 
-	OUT_RING(pI830->BR[13]);
+	OUT_RING(pI830->BR[13] | pitch);
 	OUT_RING((y1 << 16) | (x1 & 0xffff));
 	OUT_RING((y2 << 16) | (x2 & 0xffff));
 	OUT_RING(offset);
@@ -233,17 +230,9 @@ I830EXAPrepareCopy(PixmapPtr pSrcPixmap,
     if (!EXA_PM_IS_SOLID(&pSrcPixmap->drawable, planemask))
 	I830FALLBACK("planemask is not solid");
 
-    pI830->copy_src_pitch = exaGetPixmapPitch(pSrcPixmap);
-    pI830->copy_src_off = exaGetPixmapOffset(pSrcPixmap);
-    pI830->copy_src_tiled = exaPixmapTiled(pSrcPixmap);
-
-    if (pI830->copy_src_tiled && pI830->copy_src_off > 4096)
-	I830FALLBACK("offset limited to 4k for tiled targets");
-    if (exaPixmapTiled(pDstPixmap) && exaGetPixmapOffset(pDstPixmap) > 4096)
-	I830FALLBACK("offset limited to 4k for tiled targets");
+    pI830->pSrcPixmap = pSrcPixmap;
 
-    pI830->BR[13] = exaGetPixmapPitch(pDstPixmap);
-    pI830->BR[13] |= I830CopyROP[alu] << 16;
+    pI830->BR[13] = I830CopyROP[alu] << 16;
 
     switch (pSrcPixmap->drawable.bitsPerPixel) {
     case 8:
@@ -266,12 +255,15 @@ I830EXACopy(PixmapPtr pDstPixmap, int sr
     I830Ptr pI830 = I830PTR(pScrn);
     uint32_t cmd;
     int dst_x2, dst_y2;
-    unsigned int dst_off;
+    unsigned int dst_off, dst_pitch, src_off, src_pitch;
 
     dst_x2 = dst_x1 + w;
     dst_y2 = dst_y1 + h;
 
     dst_off = exaGetPixmapOffset(pDstPixmap);
+    dst_pitch = exaGetPixmapPitch(pDstPixmap);
+    src_off = exaGetPixmapOffset(pI830->pSrcPixmap);
+    src_pitch = exaGetPixmapPitch(pI830->pSrcPixmap);
 
     {
 	BEGIN_LP_RING(8);
@@ -281,29 +273,29 @@ I830EXACopy(PixmapPtr pDstPixmap, int sr
 	if (pDstPixmap->drawable.bitsPerPixel == 32)
 	    cmd |= XY_SRC_COPY_BLT_WRITE_ALPHA | XY_SRC_COPY_BLT_WRITE_RGB;
 
-	if (exaPixmapTiled(pDstPixmap)) {
-	    /* Fixup pitch for destination if tiled */
-	    pI830->BR[13] = (ROUND_TO(pI830->BR[13] & 0xffff, 512) >> 2) |
-		(pI830->BR[13] & 0xffff0000);
-	    cmd |= XY_SRC_COPY_BLT_DST_TILED;
-	}
+	if (IS_I965G(pI830)) {
+	    if (exaPixmapTiled(pDstPixmap)) {
+		assert((dst_pitch % 512) == 0);
+		dst_pitch >>= 2;
+		cmd |= XY_SRC_COPY_BLT_DST_TILED;
+	    }
 
-	if (pI830->copy_src_tiled) {
-	    pI830->copy_src_pitch =
-		(ROUND_TO(pI830->copy_src_pitch & 0xffff, 512) >> 2) |
-		(pI830->copy_src_pitch & 0xffff0000);
-	    cmd |= XY_SRC_COPY_BLT_SRC_TILED;
+	    if (exaPixmapTiled(pI830->pSrcPixmap)) {
+		assert((src_pitch % 512) == 0);
+		src_pitch >>= 2;
+		cmd |= XY_SRC_COPY_BLT_SRC_TILED;
+	    }
 	}
 
 	OUT_RING(cmd);
 
-	OUT_RING(pI830->BR[13]);
+	OUT_RING(pI830->BR[13] | dst_pitch);
 	OUT_RING((dst_y1 << 16) | (dst_x1 & 0xffff));
 	OUT_RING((dst_y2 << 16) | (dst_x2 & 0xffff));
 	OUT_RING(dst_off);
 	OUT_RING((src_y1 << 16) | (src_x1 & 0xffff));
-	OUT_RING(pI830->copy_src_pitch);
-	OUT_RING(pI830->copy_src_off);
+	OUT_RING(src_pitch);
+	OUT_RING(src_off);
 
 	ADVANCE_LP_RING();
     }
diff --git a/src/i830_xaa.c b/src/i830_xaa.c
index ec8a879..aa06a80 100644
--- a/src/i830_xaa.c
+++ b/src/i830_xaa.c
@@ -126,7 +126,6 @@ I830XAAInit(ScreenPtr pScreen)
     if (!infoPtr)
 	return FALSE;
 
-    pI830->bufferOffset = 0;
     infoPtr->Flags = LINEAR_FRAMEBUFFER | OFFSCREEN_PIXMAPS | PIXMAP_CACHE;
 
     /* Use the same sync function as the I830.
@@ -235,6 +234,7 @@ I830XAAInit(ScreenPtr pScreen)
 	    infoPtr->RestoreAccelState = I830RestoreAccelState;
     }
 
+    /* Set up pI830->bufferOffset */
     I830SelectBuffer(pScrn, I830_SELECT_FRONT);
 
     if (!XAAInit(pScreen, infoPtr))
diff-tree e0be352f5017f0e645a4ff8a40961d9c2b98863a (from 7431abee5fb971d1f8bc7ac4bea137f6ece9418b)
Author: Jesse Barnes <jesse.barnes at intel.com>
Date:   Tue Aug 7 12:37:25 2007 -0700

    Fixup pitch in Prepare* functions, since actual hooks may
    be called many times for the same pixmap, and we don't want
    to keep dividing the pitch by 4.

diff --git a/src/i830_exa.c b/src/i830_exa.c
index ed57605..3486537 100644
--- a/src/i830_exa.c
+++ b/src/i830_exa.c
@@ -153,6 +153,8 @@ I830EXAPrepareSolid(PixmapPtr pPixmap, i
     if ( pitch % pI830->EXADriverPtr->pixmapPitchAlign != 0)
 	I830FALLBACK("pixmap pitch not aligned");
 
+    if (exaPixmapTiled(pPixmap))
+	pitch /= 4;
     pI830->BR[13] = (pitch & 0xffff);
     switch (pPixmap->drawable.bitsPerPixel) {
 	case 8:
@@ -189,12 +191,8 @@ I830EXASolid(PixmapPtr pPixmap, int x1, 
 	if (pPixmap->drawable.bitsPerPixel == 32)
 	    cmd |= XY_COLOR_BLT_WRITE_ALPHA | XY_COLOR_BLT_WRITE_RGB;
 
-	if (exaPixmapTiled(pPixmap)) {
-	    /* Fixup pitch for destination if tiled */
-	    pI830->BR[13] = ((pI830->BR[13] & 0xffff) >> 2) |
-		(pI830->BR[13] & 0xffff0000);
+	if (exaPixmapTiled(pPixmap))
 	    cmd |= XY_COLOR_BLT_TILED;
-	}
 
 	OUT_RING(cmd);
 
@@ -232,10 +230,16 @@ I830EXAPrepareCopy(PixmapPtr pSrcPixmap,
 	I830FALLBACK("planemask is not solid");
 
     pI830->copy_src_pitch = exaGetPixmapPitch(pSrcPixmap);
+    if (exaPixmapTiled(pSrcPixmap))
+	pI830->copy_src_pitch /= 4;
+
     pI830->copy_src_off = exaGetPixmapOffset(pSrcPixmap);
     pI830->copy_src_tiled = exaPixmapTiled(pSrcPixmap);
 
     pI830->BR[13] = exaGetPixmapPitch(pDstPixmap);
+    if (exaPixmapTiled(pDstPixmap))
+	pI830->BR[13] /= 4;
+
     pI830->BR[13] |= I830CopyROP[alu] << 16;
 
     switch (pSrcPixmap->drawable.bitsPerPixel) {
@@ -274,17 +278,11 @@ I830EXACopy(PixmapPtr pDstPixmap, int sr
 	if (pDstPixmap->drawable.bitsPerPixel == 32)
 	    cmd |= XY_SRC_COPY_BLT_WRITE_ALPHA | XY_SRC_COPY_BLT_WRITE_RGB;
 
-	if (exaPixmapTiled(pDstPixmap)) {
-	    /* Fixup pitch for destination if tiled */
-	    pI830->BR[13] = ((pI830->BR[13] & 0xffff) >> 2) |
-		(pI830->BR[13] & 0xffff0000);
+	if (exaPixmapTiled(pDstPixmap))
 	    cmd |= XY_SRC_COPY_BLT_DST_TILED;
-	}
 
-	if (pI830->copy_src_tiled) {
-	    pI830->copy_src_pitch >>= 2;
+	if (pI830->copy_src_tiled)
 	    cmd |= XY_SRC_COPY_BLT_SRC_TILED;
-	}
 
 	OUT_RING(cmd);
 
diff-tree 7431abee5fb971d1f8bc7ac4bea137f6ece9418b (from 9e1914270a0978ec4dfae757d3dd57ca7ffe17e5)
Author: Brice Goglin <bgoglin at debian.org>
Date:   Tue Aug 7 09:13:00 2007 +0200

    Define INTEL_VERSION_MAJOR/MINOR/PATCH using PACKAGE_VERSION_*

diff --git a/configure.ac b/configure.ac
index 9b76b65..8c2b5ec 100644
--- a/configure.ac
+++ b/configure.ac
@@ -26,16 +26,6 @@ AC_INIT([xf86-video-intel],
         [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg],
         xf86-video-intel)
 
-AC_DEFINE_UNQUOTED([INTEL_VERSION_MAJOR],
-		   [$(echo $PACKAGE_VERSION | sed -e 's/^\([[0-9]]*\)\.[[0-9]]*\.[[0-9]]*/\1/')],
-		   [Major version])
-AC_DEFINE_UNQUOTED([INTEL_VERSION_MINOR],
-		   [$(echo $PACKAGE_VERSION | sed -e 's/^[[0-9]]*\.\([[0-9]]*\)\.[[0-9]]*/\1/')],
-		   [Minor version])
-AC_DEFINE_UNQUOTED([INTEL_VERSION_PATCH],
-		   [$(echo $PACKAGE_VERSION | sed -e 's/^[[0-9]]*\.[[0-9]]*\.\([[0-9]]*\)/\1/')],
-		   [Patch version])
-
 AC_CONFIG_SRCDIR([Makefile.am])
 AM_CONFIG_HEADER([config.h])
 AC_CONFIG_AUX_DIR(.)
diff --git a/src/i810.h b/src/i810.h
index 614de52..ff9134e 100644
--- a/src/i810.h
+++ b/src/i810.h
@@ -66,6 +66,10 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN
 #define I810_DRIVER_NAME "intel"
 #define I810_LEGACY_DRIVER_NAME "i810"
 
+#define INTEL_VERSION_MAJOR PACKAGE_VERSION_MAJOR
+#define INTEL_VERSION_MINOR PACKAGE_VERSION_MINOR
+#define INTEL_VERSION_PATCH PACKAGE_VERSION_PATCHLEVEL
+
 /* HWMC Surfaces */
 #define I810_MAX_SURFACES 7
 #define I810_MAX_SUBPICTURES 2
diff-tree 9e1914270a0978ec4dfae757d3dd57ca7ffe17e5 (from 5ff05dffe229e35da7619762628fdd0f125585e8)
Author: Jesse Barnes <jesse.barnes at intel.com>
Date:   Mon Aug 6 17:55:00 2007 -0700

    Remove 4k offset checks from Copy & Solid hooks.
    Reading the docs too literally can cause you to hide bugs with false fixes...

diff --git a/src/i830_exa.c b/src/i830_exa.c
index 0e9cd5b..ed57605 100644
--- a/src/i830_exa.c
+++ b/src/i830_exa.c
@@ -152,8 +152,6 @@ I830EXAPrepareSolid(PixmapPtr pPixmap, i
 	I830FALLBACK("pixmap offset not aligned");
     if ( pitch % pI830->EXADriverPtr->pixmapPitchAlign != 0)
 	I830FALLBACK("pixmap pitch not aligned");
-    if ( exaPixmapTiled(pPixmap) && offset > 4096)
-	I830FALLBACK("offset limited to 4k for tiled targets");
 
     pI830->BR[13] = (pitch & 0xffff);
     switch (pPixmap->drawable.bitsPerPixel) {
@@ -193,7 +191,7 @@ I830EXASolid(PixmapPtr pPixmap, int x1, 
 
 	if (exaPixmapTiled(pPixmap)) {
 	    /* Fixup pitch for destination if tiled */
-	    pI830->BR[13] = (ROUND_TO(pI830->BR[13] & 0xffff, 512) >> 2) | 
+	    pI830->BR[13] = ((pI830->BR[13] & 0xffff) >> 2) |
 		(pI830->BR[13] & 0xffff0000);
 	    cmd |= XY_COLOR_BLT_TILED;
 	}
@@ -237,12 +235,6 @@ I830EXAPrepareCopy(PixmapPtr pSrcPixmap,
     pI830->copy_src_off = exaGetPixmapOffset(pSrcPixmap);
     pI830->copy_src_tiled = exaPixmapTiled(pSrcPixmap);
 
-    if (pI830->copy_src_tiled && pI830->copy_src_off > 4096)
-	I830FALLBACK("offset limited to 4k for tiled targets");
-    if (exaPixmapTiled(pDstPixmap) &&
-	exaGetPixmapOffset(pDstPixmap) > 4096)
-	I830FALLBACK("offset limited to 4k for tiled targets");
-
     pI830->BR[13] = exaGetPixmapPitch(pDstPixmap);
     pI830->BR[13] |= I830CopyROP[alu] << 16;
 
@@ -284,15 +276,13 @@ I830EXACopy(PixmapPtr pDstPixmap, int sr
 
 	if (exaPixmapTiled(pDstPixmap)) {
 	    /* Fixup pitch for destination if tiled */
-	    pI830->BR[13] = (ROUND_TO(pI830->BR[13] & 0xffff, 512) >> 2) | 
+	    pI830->BR[13] = ((pI830->BR[13] & 0xffff) >> 2) |
 		(pI830->BR[13] & 0xffff0000);
 	    cmd |= XY_SRC_COPY_BLT_DST_TILED;
 	}
 
 	if (pI830->copy_src_tiled) {
-	    pI830->copy_src_pitch =
-		(ROUND_TO(pI830->copy_src_pitch & 0xffff, 512) >> 2) | 
-		(pI830->copy_src_pitch & 0xffff0000);
+	    pI830->copy_src_pitch >>= 2;
 	    cmd |= XY_SRC_COPY_BLT_SRC_TILED;
 	}
 
diff-tree 3510d5728fa972b36d022b4f9189d46ff98d7b16 (from 5ff05dffe229e35da7619762628fdd0f125585e8)
Author: Eric Anholt <eric at anholt.net>
Date:   Mon Aug 6 16:44:39 2007 -0700

    Fix accumulated whitespace nits in i830_exa.c

diff --git a/src/i830_exa.c b/src/i830_exa.c
index 0e9cd5b..19f4e30 100644
--- a/src/i830_exa.c
+++ b/src/i830_exa.c
@@ -54,7 +54,7 @@ do {							\
 #define I830FALLBACK(s, arg...) 			\
 do { 							\
 	return FALSE;					\
-} while(0) 
+} while(0)
 #endif
 
 const int I830CopyROP[16] =
@@ -148,11 +148,11 @@ I830EXAPrepareSolid(PixmapPtr pPixmap, i
     offset = exaGetPixmapOffset(pPixmap);
     pitch = exaGetPixmapPitch(pPixmap);
 
-    if ( offset % pI830->EXADriverPtr->pixmapOffsetAlign != 0)
+    if (offset % pI830->EXADriverPtr->pixmapOffsetAlign != 0)
 	I830FALLBACK("pixmap offset not aligned");
-    if ( pitch % pI830->EXADriverPtr->pixmapPitchAlign != 0)
+    if (pitch % pI830->EXADriverPtr->pixmapPitchAlign != 0)
 	I830FALLBACK("pixmap pitch not aligned");
-    if ( exaPixmapTiled(pPixmap) && offset > 4096)
+    if (exaPixmapTiled(pPixmap) && offset > 4096)
 	I830FALLBACK("offset limited to 4k for tiled targets");
 
     pI830->BR[13] = (pitch & 0xffff);
@@ -181,8 +181,8 @@ I830EXASolid(PixmapPtr pPixmap, int x1, 
     unsigned long offset;
     uint32_t cmd;
 
-    offset = exaGetPixmapOffset(pPixmap);  
-    
+    offset = exaGetPixmapOffset(pPixmap);
+
     {
 	BEGIN_LP_RING(6);
 
@@ -193,7 +193,7 @@ I830EXASolid(PixmapPtr pPixmap, int x1, 
 
 	if (exaPixmapTiled(pPixmap)) {
 	    /* Fixup pitch for destination if tiled */
-	    pI830->BR[13] = (ROUND_TO(pI830->BR[13] & 0xffff, 512) >> 2) | 
+	    pI830->BR[13] = (ROUND_TO(pI830->BR[13] & 0xffff, 512) >> 2) |
 		(pI830->BR[13] & 0xffff0000);
 	    cmd |= XY_COLOR_BLT_TILED;
 	}
@@ -239,8 +239,7 @@ I830EXAPrepareCopy(PixmapPtr pSrcPixmap,
 
     if (pI830->copy_src_tiled && pI830->copy_src_off > 4096)
 	I830FALLBACK("offset limited to 4k for tiled targets");
-    if (exaPixmapTiled(pDstPixmap) &&
-	exaGetPixmapOffset(pDstPixmap) > 4096)
+    if (exaPixmapTiled(pDstPixmap) && exaGetPixmapOffset(pDstPixmap) > 4096)
 	I830FALLBACK("offset limited to 4k for tiled targets");
 
     pI830->BR[13] = exaGetPixmapPitch(pDstPixmap);
@@ -284,14 +283,14 @@ I830EXACopy(PixmapPtr pDstPixmap, int sr
 
 	if (exaPixmapTiled(pDstPixmap)) {
 	    /* Fixup pitch for destination if tiled */
-	    pI830->BR[13] = (ROUND_TO(pI830->BR[13] & 0xffff, 512) >> 2) | 
+	    pI830->BR[13] = (ROUND_TO(pI830->BR[13] & 0xffff, 512) >> 2) |
 		(pI830->BR[13] & 0xffff0000);
 	    cmd |= XY_SRC_COPY_BLT_DST_TILED;
 	}
 
 	if (pI830->copy_src_tiled) {
 	    pI830->copy_src_pitch =
-		(ROUND_TO(pI830->copy_src_pitch & 0xffff, 512) >> 2) | 
+		(ROUND_TO(pI830->copy_src_pitch & 0xffff, 512) >> 2) |
 		(pI830->copy_src_pitch & 0xffff0000);
 	    cmd |= XY_SRC_COPY_BLT_SRC_TILED;
 	}
@@ -460,11 +459,12 @@ I830EXAInit(ScreenPtr pScreen)
 	pI830->exa_offscreen->size;
     pI830->EXADriverPtr->flags = EXA_OFFSCREEN_PIXMAPS;
 
-    DPRINTF(PFX, "EXA Mem: memoryBase 0x%x, end 0x%x, offscreen base 0x%x, memorySize 0x%x\n",
-		pI830->EXADriverPtr->memoryBase,
-		pI830->EXADriverPtr->memoryBase + pI830->EXADriverPtr->memorySize,
-		pI830->EXADriverPtr->offScreenBase,
-		pI830->EXADriverPtr->memorySize);
+    DPRINTF(PFX, "EXA Mem: memoryBase 0x%x, end 0x%x, offscreen base 0x%x, "
+	    "memorySize 0x%x\n",
+	    pI830->EXADriverPtr->memoryBase,
+	    pI830->EXADriverPtr->memoryBase + pI830->EXADriverPtr->memorySize,
+	    pI830->EXADriverPtr->offScreenBase,
+	    pI830->EXADriverPtr->memorySize);
 
 
     /* Limits are described in the BLT engine chapter under Graphics Data Size
diff-tree 5ff05dffe229e35da7619762628fdd0f125585e8 (from ba90d944329dd8c79a757c38128964fbbe4ab898)
Author: Jesse Barnes <jesse.barnes at intel.com>
Date:   Mon Aug 6 16:01:10 2007 -0700

    More tiled rendering fixes: - check for tiling, not just offset in PrepareSolid - combine pI830->tiling and frontbuffer checks into new exaPixmapTiled function for readability

diff --git a/src/i830_exa.c b/src/i830_exa.c
index 88853a7..0e9cd5b 100644
--- a/src/i830_exa.c
+++ b/src/i830_exa.c
@@ -98,9 +98,14 @@ const int I830PatternROP[16] =
 };
 
 static Bool
-exaPixmapInFrontbuffer(PixmapPtr p)
+exaPixmapTiled(PixmapPtr p)
 {
     ScreenPtr pScreen = p->drawable.pScreen;
+    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+    I830Ptr pI830 = I830PTR(pScrn);
+
+    if (!pI830->tiling)
+	return FALSE;
 
     if (p == pScreen->GetScreenPixmap(pScreen))
 	return TRUE;
@@ -147,7 +152,7 @@ I830EXAPrepareSolid(PixmapPtr pPixmap, i
 	I830FALLBACK("pixmap offset not aligned");
     if ( pitch % pI830->EXADriverPtr->pixmapPitchAlign != 0)
 	I830FALLBACK("pixmap pitch not aligned");
-    if ( pI830->tiling && offset > 4096)
+    if ( exaPixmapTiled(pPixmap) && offset > 4096)
 	I830FALLBACK("offset limited to 4k for tiled targets");
 
     pI830->BR[13] = (pitch & 0xffff);
@@ -186,7 +191,7 @@ I830EXASolid(PixmapPtr pPixmap, int x1, 
 	if (pPixmap->drawable.bitsPerPixel == 32)
 	    cmd |= XY_COLOR_BLT_WRITE_ALPHA | XY_COLOR_BLT_WRITE_RGB;
 
-	if (pI830->tiling && exaPixmapInFrontbuffer(pPixmap)) {
+	if (exaPixmapTiled(pPixmap)) {
 	    /* Fixup pitch for destination if tiled */
 	    pI830->BR[13] = (ROUND_TO(pI830->BR[13] & 0xffff, 512) >> 2) | 
 		(pI830->BR[13] & 0xffff0000);
@@ -230,12 +235,11 @@ I830EXAPrepareCopy(PixmapPtr pSrcPixmap,
 
     pI830->copy_src_pitch = exaGetPixmapPitch(pSrcPixmap);
     pI830->copy_src_off = exaGetPixmapOffset(pSrcPixmap);
-    pI830->copy_src_tiled = (pI830->tiling &&
-			     exaPixmapInFrontbuffer(pSrcPixmap));
+    pI830->copy_src_tiled = exaPixmapTiled(pSrcPixmap);
 
     if (pI830->copy_src_tiled && pI830->copy_src_off > 4096)
 	I830FALLBACK("offset limited to 4k for tiled targets");
-    if (pI830->tiling && exaPixmapInFrontbuffer(pDstPixmap) &&
+    if (exaPixmapTiled(pDstPixmap) &&
 	exaGetPixmapOffset(pDstPixmap) > 4096)
 	I830FALLBACK("offset limited to 4k for tiled targets");
 
@@ -278,7 +282,7 @@ I830EXACopy(PixmapPtr pDstPixmap, int sr
 	if (pDstPixmap->drawable.bitsPerPixel == 32)
 	    cmd |= XY_SRC_COPY_BLT_WRITE_ALPHA | XY_SRC_COPY_BLT_WRITE_RGB;
 
-	if (pI830->tiling && exaPixmapInFrontbuffer(pDstPixmap)) {
+	if (exaPixmapTiled(pDstPixmap)) {
 	    /* Fixup pitch for destination if tiled */
 	    pI830->BR[13] = (ROUND_TO(pI830->BR[13] & 0xffff, 512) >> 2) | 
 		(pI830->BR[13] & 0xffff0000);
diff-tree ba90d944329dd8c79a757c38128964fbbe4ab898 (from 322a163cfbda885adc6bb09c1f976d36617ea83b)
Author: Eric Anholt <eric at anholt.net>
Date:   Fri Aug 3 16:46:09 2007 -0700

    Add the file mode for bios_dumper output so it doesn't have 000 permissions.

diff --git a/src/bios_reader/bios_dumper.c b/src/bios_reader/bios_dumper.c
index c0dbdcf..6f163d5 100644
--- a/src/bios_reader/bios_dumper.c
+++ b/src/bios_reader/bios_dumper.c
@@ -29,6 +29,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <stdarg.h>
+#include <sys/stat.h>
 #include <fcntl.h>
 #include <errno.h>
 #include <pciaccess.h>
@@ -80,7 +81,7 @@ int main(int argc, char **argv)
 	exit(1);
     }
 
-    fd = open(argv[1], O_RDWR | O_CREAT | O_TRUNC);
+    fd = open(argv[1], O_RDWR | O_CREAT | O_TRUNC, DEFFILEMODE);
     if (fd < 0) {
 	fprintf(stderr, "Couldn't open output: %s\n", strerror(errno));
 	exit(1);
diff-tree 322a163cfbda885adc6bb09c1f976d36617ea83b (from ffbab2ee5dc227b2a8a5ffd1717ae00e8e37f956)
Author: Eric Anholt <eric at anholt.net>
Date:   Fri Aug 3 10:46:39 2007 -0700

    Quirk away the nonexistent TV connector on the Panasonic CF-Y4.

diff --git a/src/i830_quirks.c b/src/i830_quirks.c
index e209fea..b75baef 100644
--- a/src/i830_quirks.c
+++ b/src/i830_quirks.c
@@ -57,6 +57,8 @@ static void quirk_mac_mini (I830Ptr pI83
 static i830_quirk i830_quirk_list[] = {
     /* Lenovo T61 has no TV output */
     { PCI_CHIP_I965_GM, 0x17aa, 0x20b5, quirk_ignore_tv },
+    /* Panasonic Toughbook CF-Y4 has no TV output */
+    { PCI_CHIP_I915_GM, 0x10f7, 0x8338, quirk_ignore_tv },
     /* Lenovo 3000 v200 */
     { PCI_CHIP_I965_GM, 0x17aa, 0x3c18, quirk_ignore_tv },
     /* Aopen mini pc */
diff-tree ffbab2ee5dc227b2a8a5ffd1717ae00e8e37f956 (from 019dbfda294aaafb28d8bea0fe2f5dadc2ea3e0b)
Author: Jesse Barnes <jesse.barnes at intel.com>
Date:   Fri Aug 3 21:27:52 2007 -0700

    Limit Solid & Copy offsets to 4k when rendering to tiled targets

diff --git a/src/i830_exa.c b/src/i830_exa.c
index 5da153e..88853a7 100644
--- a/src/i830_exa.c
+++ b/src/i830_exa.c
@@ -147,6 +147,8 @@ I830EXAPrepareSolid(PixmapPtr pPixmap, i
 	I830FALLBACK("pixmap offset not aligned");
     if ( pitch % pI830->EXADriverPtr->pixmapPitchAlign != 0)
 	I830FALLBACK("pixmap pitch not aligned");
+    if ( pI830->tiling && offset > 4096)
+	I830FALLBACK("offset limited to 4k for tiled targets");
 
     pI830->BR[13] = (pitch & 0xffff);
     switch (pPixmap->drawable.bitsPerPixel) {
@@ -231,6 +233,12 @@ I830EXAPrepareCopy(PixmapPtr pSrcPixmap,
     pI830->copy_src_tiled = (pI830->tiling &&
 			     exaPixmapInFrontbuffer(pSrcPixmap));
 
+    if (pI830->copy_src_tiled && pI830->copy_src_off > 4096)
+	I830FALLBACK("offset limited to 4k for tiled targets");
+    if (pI830->tiling && exaPixmapInFrontbuffer(pDstPixmap) &&
+	exaGetPixmapOffset(pDstPixmap) > 4096)
+	I830FALLBACK("offset limited to 4k for tiled targets");
+
     pI830->BR[13] = exaGetPixmapPitch(pDstPixmap);
     pI830->BR[13] |= I830CopyROP[alu] << 16;
 
diff-tree 019dbfda294aaafb28d8bea0fe2f5dadc2ea3e0b (from parents)
Merge: 3d3c0e8c55f639a501c0756948b518abd903d7d0 15f71edba37738f8ba279fa07452fda10cc65298
Author: Jesse Barnes <jesse.barnes at intel.com>
Date:   Fri Aug 3 20:45:14 2007 -0700

    Merge branch 'master' of ssh://git.freedesktop.org/git/xorg/driver/xf86-video-intel

diff-tree 3d3c0e8c55f639a501c0756948b518abd903d7d0 (from 0da4f2b0cd7203377ad10407928a367b8c6d310e)
Author: Jesse Barnes <jesse.barnes at intel.com>
Date:   Fri Aug 3 20:40:45 2007 -0700

    Tiled rendering & fbc fixes:
      - actually enable tiling in DSP(A|B)CNTR if needed
      - add logic to EXA routines for tiled case (still needs work)
      - enable/disable fbc on DPMS events (meant moving functions higher in file)
      - fix fence register pitch programming (use correct pitch instead of kludged value)

diff --git a/src/i810_reg.h b/src/i810_reg.h
index d1fed22..03e10d6 100644
--- a/src/i810_reg.h
+++ b/src/i810_reg.h
@@ -2029,6 +2029,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN
 #define DSPBCNTR		0x71180
 #define DISPLAY_PLANE_ENABLE 			(1<<31)
 #define DISPLAY_PLANE_DISABLE			0
+#define DISPLAY_PLANE_TILED			(1<<10)
 #define DISPPLANE_GAMMA_ENABLE			(1<<30)
 #define DISPPLANE_GAMMA_DISABLE			0
 #define DISPPLANE_PIXFORMAT_MASK		(0xf<<26)
@@ -2168,12 +2169,15 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN
 #define XY_COLOR_BLT_CMD		((2<<29)|(0x50<<22)|(0x4))
 #define XY_COLOR_BLT_WRITE_ALPHA	(1<<21)
 #define XY_COLOR_BLT_WRITE_RGB		(1<<20)
+#define XY_COLOR_BLT_TILED		(1<<11)
 
 #define XY_SETUP_CLIP_BLT_CMD		((2<<29)|(3<<22)|1)
 
 #define XY_SRC_COPY_BLT_CMD		((2<<29)|(0x53<<22)|6)
 #define XY_SRC_COPY_BLT_WRITE_ALPHA	(1<<21)
 #define XY_SRC_COPY_BLT_WRITE_RGB	(1<<20)
+#define XY_SRC_COPY_BLT_SRC_TILED	(1<<15)
+#define XY_SRC_COPY_BLT_DST_TILED	(1<<11)
 
 #define SRC_COPY_BLT_CMD		((2<<29)|(0x43<<22)|0x4)
 #define SRC_COPY_BLT_WRITE_ALPHA	(1<<21)
diff --git a/src/i830.h b/src/i830.h
index a8de0e6..64a3690 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -407,6 +407,7 @@ typedef struct _I830Rec {
 #ifdef I830_USE_EXA
    unsigned int copy_src_pitch;
    unsigned int copy_src_off;
+   unsigned int copy_src_tiled;
    ExaDriverPtr	EXADriverPtr;
 #endif
 
diff --git a/src/i830_display.c b/src/i830_display.c
index 26873fe..6fe7be7 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -498,6 +498,123 @@ i830_pipe_a_require_deactivate (ScrnInfo
     return;
 }
 
+static Bool
+i830_use_fb_compression(xf86CrtcPtr crtc)
+{
+    ScrnInfoPtr pScrn = crtc->scrn;
+    I830Ptr pI830 = I830PTR(pScrn);
+    I830CrtcPrivatePtr	intel_crtc = crtc->driver_private;
+    int pipe = intel_crtc->pipe;
+    int plane = (pipe == 0 ? FBC_CTL_PLANEA : FBC_CTL_PLANEB);
+
+    if (!pI830->fb_compression)
+	return FALSE;
+
+    /* Pre-965 only supports plane A */
+    if (!IS_I965GM(pI830) && plane != FBC_CTL_PLANEA)
+	return FALSE;
+
+    /* Need 15, 16, or 32 (w/alpha) pixel format */
+    if (!(pScrn->bitsPerPixel == 16 || /* covers 15 bit mode as well */
+	  pScrn->bitsPerPixel == 32)) /* mode_set dtrt if fbc is in use */
+	return FALSE;
+
+    /*
+     * No checks for pixel multiply, incl. horizontal, or interlaced modes
+     * since they're currently unused.
+     */
+    return TRUE;
+}
+
+/*
+ * Several restrictions:
+ *   - DSP[AB]CNTR - no line duplication && no pixel multiplier
+ *   - pixel format == 15 bit, 16 bit, or 32 bit xRGB_8888
+ *   - no alpha buffer discard
+ *   - no dual wide display
+ *   - progressive mode only (DSP[AB]CNTR)
+ *   - uncompressed fb is <= 2048 in width, 0 mod 8
+ *   - uncompressed fb is <= 1536 in height, 0 mod 2
+ *   - SR display watermarks must be equal between 16bpp and 32bpp?
+ *
+ * FIXME: verify above conditions are true
+ */
+static void
+i830_enable_fb_compression(xf86CrtcPtr crtc)
+{
+    ScrnInfoPtr pScrn = crtc->scrn;
+    I830Ptr pI830 = I830PTR(pScrn);
+    I830CrtcPrivatePtr	intel_crtc = crtc->driver_private;
+    uint32_t fbc_ctl = 0;
+    unsigned long compressed_stride;
+    int pipe = intel_crtc->pipe;
+    /* FIXME: plane & pipe might not always be equal */
+    int plane = (pipe == 0 ? FBC_CTL_PLANEA : FBC_CTL_PLANEB);
+    unsigned long uncompressed_stride = pScrn->displayWidth * pI830->cpp;
+    unsigned long interval = 1000;
+
+    if (INREG(FBC_CONTROL) & FBC_CTL_EN) {
+	char cur_pipe = (INREG(FBC_CONTROL2) & 1) ? 'b' : 'a';
+	xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "fbc already enabled on "
+		   "pipe %c, not enabling on pipe %c\n", cur_pipe, pipe ? 'b' :
+		   'a');
+	return;
+    }
+
+    compressed_stride = pI830->compressed_front_buffer->size /
+	FBC_LL_SIZE;
+
+    if (uncompressed_stride < compressed_stride)
+	compressed_stride = uncompressed_stride;
+
+    /* FBC_CTL wants 64B units */
+    compressed_stride = (compressed_stride / 64) - 1;
+
+    /* Set it up... */
+    /* Wait for compressing bit to clear */
+    while (INREG(FBC_STATUS) & FBC_STAT_COMPRESSING)
+	; /* nothing */
+    i830WaitForVblank(pScrn);
+    OUTREG(FBC_CFB_BASE, pI830->compressed_front_buffer->bus_addr);
+    OUTREG(FBC_LL_BASE, pI830->compressed_ll_buffer->bus_addr + 6);
+    OUTREG(FBC_CONTROL2, FBC_CTL_FENCE_DBL | FBC_CTL_IDLE_FULL |
+	   FBC_CTL_CPU_FENCE | plane);
+
+    /* Zero buffers */
+    memset(pI830->FbBase + pI830->compressed_front_buffer->offset, 0,
+	   pI830->compressed_front_buffer->size);
+    memset(pI830->FbBase + pI830->compressed_ll_buffer->offset, 0,
+	   pI830->compressed_ll_buffer->size);
+
+    /* enable it... */
+    fbc_ctl |= FBC_CTL_EN | FBC_CTL_PERIODIC;
+    fbc_ctl |= (compressed_stride & 0xff) << FBC_CTL_STRIDE_SHIFT;
+    fbc_ctl |= (interval & 0x2fff) << FBC_CTL_INTERVAL_SHIFT;
+    fbc_ctl |= FBC_CTL_UNCOMPRESSIBLE;
+    OUTREG(FBC_CONTROL, fbc_ctl);
+
+    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "fbc enabled on plane %c\n", pipe ?
+	       'b' : 'a');
+}
+
+static void
+i830_disable_fb_compression(xf86CrtcPtr crtc)
+{
+    ScrnInfoPtr pScrn = crtc->scrn;
+    I830Ptr pI830 = I830PTR(pScrn);
+    uint32_t fbc_ctl;
+    char pipe = (INREG(FBC_CONTROL2) & 1) ? 'b' : 'a';
+
+    /* Disable compression */
+    fbc_ctl = INREG(FBC_CONTROL);
+    fbc_ctl &= ~FBC_CTL_EN;
+    OUTREG(FBC_CONTROL, fbc_ctl);
+
+    /* Wait for compressing bit to clear */
+    while (INREG(FBC_STATUS) & FBC_STAT_COMPRESSING)
+	; /* nothing */
+    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "fbc disabled on pipe %c\n", pipe);
+}
 
 /**
  * Sets the power management mode of the pipe and plane.
@@ -561,8 +678,16 @@ i830_crtc_dpms(xf86CrtcPtr crtc, int mod
 
 	/* Give the overlay scaler a chance to enable if it's on this pipe */
 	i830_crtc_dpms_video(crtc, TRUE);
+
+	/* Reenable compression if needed */
+	if (i830_use_fb_compression(crtc))
+	    i830_enable_fb_compression(crtc);
 	break;
     case DPMSModeOff:
+	/* Shut off compression if in use */
+	if (i830_use_fb_compression(crtc))
+	    i830_disable_fb_compression(crtc);
+
 	/* Give the overlay scaler a chance to disable if it's on this pipe */
 	i830_crtc_dpms_video(crtc, FALSE);
 
@@ -656,112 +781,6 @@ i830_crtc_unlock (xf86CrtcPtr crtc)
 #endif
 }
 
-static Bool
-i830_use_fb_compression(xf86CrtcPtr crtc)
-{
-    ScrnInfoPtr pScrn = crtc->scrn;
-    I830Ptr pI830 = I830PTR(pScrn);
-    I830CrtcPrivatePtr	intel_crtc = crtc->driver_private;
-    int pipe = intel_crtc->pipe;
-    int plane = (pipe == 0 ? FBC_CTL_PLANEA : FBC_CTL_PLANEB);
-
-    if (!pI830->fb_compression)
-	return FALSE;
-
-    /* Pre-965 only supports plane A */
-    if (!IS_I965GM(pI830) && plane != FBC_CTL_PLANEA)
-	return FALSE;
-
-    /* Need 15, 16, or 32 (w/alpha) pixel format */
-    if (!(pScrn->bitsPerPixel == 16 || /* covers 15 bit mode as well */
-	  pScrn->bitsPerPixel == 32)) /* mode_set dtrt if fbc is in use */
-	return FALSE;
-
-    /*
-     * No checks for pixel multiply, incl. horizontal, or interlaced modes
-     * since they're currently unused.
-     */
-    return TRUE;
-}
-
-/*
- * Several restrictions:
- *   - DSP[AB]CNTR - no line duplication && no pixel multiplier
- *   - pixel format == 15 bit, 16 bit, or 32 bit xRGB_8888
- *   - no alpha buffer discard
- *   - no dual wide display
- *   - progressive mode only (DSP[AB]CNTR)
- *   - uncompressed fb is <= 2048 in width, 0 mod 8
- *   - uncompressed fb is <= 1536 in height, 0 mod 2
- *   - SR display watermarks must be equal between 16bpp and 32bpp?
- *
- * FIXME: verify above conditions are true
- */
-static void
-i830_enable_fb_compression(xf86CrtcPtr crtc)
-{
-    ScrnInfoPtr pScrn = crtc->scrn;
-    I830Ptr pI830 = I830PTR(pScrn);
-    I830CrtcPrivatePtr	intel_crtc = crtc->driver_private;
-    uint32_t fbc_ctl;
-    unsigned long compressed_stride;
-    int pipe = intel_crtc->pipe;
-    int plane = (pipe == 0 ? FBC_CTL_PLANEA : FBC_CTL_PLANEB);
-    unsigned long uncompressed_stride = pScrn->displayWidth * pI830->cpp;
-    unsigned long interval = 1000;
-
-    if (INREG(FBC_CONTROL) & FBC_CTL_EN) {
-	char cur_pipe = (INREG(FBC_CONTROL2) & 1) ? 'b' : 'a';
-	xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "fbc already enabled on "
-		   "pipe %c, not enabling on pipe %c\n", cur_pipe, pipe ? 'b' :
-		   'a');
-	return;
-    }
-
-    compressed_stride = pI830->compressed_front_buffer->size /
-	FBC_LL_SIZE;
-
-    if (uncompressed_stride < compressed_stride)
-	compressed_stride = uncompressed_stride;
-
-    /* FBC_CTL wants 64B units */
-    compressed_stride = (compressed_stride / 64) - 1;
-
-    /* Set it up... */
-    OUTREG(FBC_CFB_BASE, pI830->compressed_front_buffer->bus_addr);
-    OUTREG(FBC_LL_BASE, pI830->compressed_ll_buffer->bus_addr + FBC_LL_PAD);
-    OUTREG(FBC_CONTROL2, FBC_CTL_CPU_FENCE | plane);
-
-    /* enable it... */
-    fbc_ctl = INREG(FBC_CONTROL);
-    fbc_ctl |= FBC_CTL_EN | FBC_CTL_PERIODIC;
-    fbc_ctl |= (compressed_stride & 0xff) << FBC_CTL_STRIDE_SHIFT;
-    fbc_ctl |= (interval & 0x2fff) << FBC_CTL_INTERVAL_SHIFT;
-    OUTREG(FBC_CONTROL, fbc_ctl);
-
-    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "fbc enabled on pipe %c\n", pipe ?
-	       'b' : 'a');
-}
-
-static void
-i830_disable_fb_compression(xf86CrtcPtr crtc)
-{
-    ScrnInfoPtr pScrn = crtc->scrn;
-    I830Ptr pI830 = I830PTR(pScrn);
-    uint32_t fbc_ctl;
-    char pipe = (INREG(FBC_CONTROL2) & 1) ? 'b' : 'a';
-
-    /* Disable compression */
-    fbc_ctl = INREG(FBC_CONTROL);
-    fbc_ctl &= ~FBC_CTL_EN;
-    OUTREG(FBC_CONTROL, fbc_ctl);
-
-    /* Wait for compressing bit to clear */
-    while (INREG(FBC_STATUS) & FBC_STAT_COMPRESSING)
-	; /* nothing */
-    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "fbc disabled on pipe %c\n", pipe);
-}
-
 static void
 i830_crtc_prepare (xf86CrtcPtr crtc)
 {
@@ -1059,6 +1078,9 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, Dis
     else
 	dspcntr |= DISPPLANE_SEL_PIPE_B;
 
+    if (pI830->tiling)
+	dspcntr |= DISPLAY_PLANE_TILED;
+
     pipeconf = INREG(pipeconf_reg);
     if (pipe == 0 && !IS_I965G(pI830))
     {
diff --git a/src/i830_exa.c b/src/i830_exa.c
index fed4067..5da153e 100644
--- a/src/i830_exa.c
+++ b/src/i830_exa.c
@@ -97,6 +97,16 @@ const int I830PatternROP[16] =
     ROP_1
 };
 
+static Bool
+exaPixmapInFrontbuffer(PixmapPtr p)
+{
+    ScreenPtr pScreen = p->drawable.pScreen;
+
+    if (p == pScreen->GetScreenPixmap(pScreen))
+	return TRUE;
+    return FALSE;
+}
+
 /**
  * I830EXASync - wait for a command to finish
  * @pScreen: current screen
@@ -162,16 +172,26 @@ I830EXASolid(PixmapPtr pPixmap, int x1, 
     ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
     I830Ptr pI830 = I830PTR(pScrn);
     unsigned long offset;
+    uint32_t cmd;
 
     offset = exaGetPixmapOffset(pPixmap);  
     
     {
 	BEGIN_LP_RING(6);
+
+	cmd = XY_COLOR_BLT_CMD;
+
 	if (pPixmap->drawable.bitsPerPixel == 32)
-	    OUT_RING(XY_COLOR_BLT_CMD | XY_COLOR_BLT_WRITE_ALPHA
-			| XY_COLOR_BLT_WRITE_RGB);
-	else
-	    OUT_RING(XY_COLOR_BLT_CMD);
+	    cmd |= XY_COLOR_BLT_WRITE_ALPHA | XY_COLOR_BLT_WRITE_RGB;
+
+	if (pI830->tiling && exaPixmapInFrontbuffer(pPixmap)) {
+	    /* Fixup pitch for destination if tiled */
+	    pI830->BR[13] = (ROUND_TO(pI830->BR[13] & 0xffff, 512) >> 2) | 
+		(pI830->BR[13] & 0xffff0000);
+	    cmd |= XY_COLOR_BLT_TILED;
+	}
+
+	OUT_RING(cmd);
 
 	OUT_RING(pI830->BR[13]);
 	OUT_RING((y1 << 16) | (x1 & 0xffff));
@@ -208,6 +228,8 @@ I830EXAPrepareCopy(PixmapPtr pSrcPixmap,
 
     pI830->copy_src_pitch = exaGetPixmapPitch(pSrcPixmap);
     pI830->copy_src_off = exaGetPixmapOffset(pSrcPixmap);
+    pI830->copy_src_tiled = (pI830->tiling &&
+			     exaPixmapInFrontbuffer(pSrcPixmap));
 
     pI830->BR[13] = exaGetPixmapPitch(pDstPixmap);
     pI830->BR[13] |= I830CopyROP[alu] << 16;
@@ -231,6 +253,7 @@ I830EXACopy(PixmapPtr pDstPixmap, int sr
 {
     ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum];
     I830Ptr pI830 = I830PTR(pScrn);
+    uint32_t cmd;
     int dst_x2, dst_y2;
     unsigned int dst_off;
 
@@ -242,11 +265,26 @@ I830EXACopy(PixmapPtr pDstPixmap, int sr
     {
 	BEGIN_LP_RING(8);
 
+	cmd = XY_SRC_COPY_BLT_CMD;
+
 	if (pDstPixmap->drawable.bitsPerPixel == 32)
-	    OUT_RING(XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA |
-		     XY_SRC_COPY_BLT_WRITE_RGB);
-	else
-	    OUT_RING(XY_SRC_COPY_BLT_CMD);
+	    cmd |= XY_SRC_COPY_BLT_WRITE_ALPHA | XY_SRC_COPY_BLT_WRITE_RGB;
+
+	if (pI830->tiling && exaPixmapInFrontbuffer(pDstPixmap)) {
+	    /* Fixup pitch for destination if tiled */
+	    pI830->BR[13] = (ROUND_TO(pI830->BR[13] & 0xffff, 512) >> 2) | 
+		(pI830->BR[13] & 0xffff0000);
+	    cmd |= XY_SRC_COPY_BLT_DST_TILED;
+	}
+
+	if (pI830->copy_src_tiled) {
+	    pI830->copy_src_pitch =
+		(ROUND_TO(pI830->copy_src_pitch & 0xffff, 512) >> 2) | 
+		(pI830->copy_src_pitch & 0xffff0000);
+	    cmd |= XY_SRC_COPY_BLT_SRC_TILED;
+	}
+
+	OUT_RING(cmd);
 
 	OUT_RING(pI830->BR[13]);
 	OUT_RING((dst_y1 << 16) | (dst_x1 & 0xffff));
diff --git a/src/i830_memory.c b/src/i830_memory.c
index b38a5df..ccd26b3 100644
--- a/src/i830_memory.c
+++ b/src/i830_memory.c
@@ -1453,11 +1453,6 @@ i830_set_fence(ScrnInfoPtr pScrn, int nr
     assert(tile_format != TILING_NONE);
 
     if (IS_I965G(pI830)) {
-        if (tile_format == TILING_XMAJOR)
-            pitch = 512;
-        else
-            pitch = 128;
- 
 	if (nr < 0 || nr >= FENCE_NEW_NR) {
 	    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
 		       "i830_set_fence(): fence %d out of range\n",nr);
diff --git a/src/i830_reg.h b/src/i830_reg.h
index 8a2a98a..df22ed4 100644
--- a/src/i830_reg.h
+++ b/src/i830_reg.h
@@ -36,6 +36,7 @@
 #define   FBC_CTL_EN		(1<<31)
 #define   FBC_CTL_PERIODIC	(1<<30)
 #define   FBC_CTL_INTERVAL_SHIFT (16)
+#define   FBC_CTL_UNCOMPRESSIBLE (1<<14)
 #define   FBC_CTL_STRIDE_SHIFT	(5)
 #define   FBC_CTL_FENCENO	(1<<0)
 #define FBC_COMMAND		0x0320c
@@ -46,9 +47,15 @@
 #define   FBC_STAT_MODIFIED	(1<<29)
 #define   FBC_STAT_CURRENT_LINE	(1<<0)
 #define FBC_CONTROL2		0x03214
+#define   FBC_CTL_FENCE_DBL	(0<<4)
+#define   FBC_CTL_IDLE_IMM	(0<<2)
+#define   FBC_CTL_IDLE_FULL	(1<<2)
+#define   FBC_CTL_IDLE_LINE	(2<<2)
+#define   FBC_CTL_IDLE_DEBUG	(3<<2)
 #define   FBC_CTL_CPU_FENCE	(1<<1)
 #define   FBC_CTL_PLANEA	(0<<0)
 #define   FBC_CTL_PLANEB	(1<<0)
+#define FBC_FENCE_OFF		0x0321b
 
 #define FBC_LL_SIZE		(1536)
 #define FBC_LL_PAD		(32)
diff-tree 0da4f2b0cd7203377ad10407928a367b8c6d310e (from f403a50afbcef1e54f554481c72037338bd5357c)
Author: Jesse Barnes <jesse.barnes at intel.com>
Date:   Tue Jul 31 16:22:36 2007 -0700

    Legacy backlight changes:
      - add support for 965GM
      - make sure legacy enabled systems don't reduce the range of backlight values we can present to the user

diff --git a/src/i810_reg.h b/src/i810_reg.h
index 248df04..d1fed22 100644
--- a/src/i810_reg.h
+++ b/src/i810_reg.h
@@ -822,6 +822,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN
 # define PP_SEQUENCE_MASK			0x30000000
 
 #define PP_CONTROL	0x61204
+# define POWER_DOWN_ON_RESET			(1 << 1)
 # define POWER_TARGET_ON			(1 << 0)
 
 #define LVDSPP_ON       0x61208
@@ -1066,6 +1067,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN
 
 #define BLC_PWM_CTL		0x61254
 #define BACKLIGHT_MODULATION_FREQ_SHIFT		(17)
+#define BACKLIGHT_MODULATION_FREQ_SHIFT2	(16)
 /**
  * This is the most significant 15 bits of the number of backlight cycles in a
  * complete cycle of the modulated backlight control.
@@ -1073,7 +1075,9 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN
  * The actual value is this field multiplied by two.
  */
 #define BACKLIGHT_MODULATION_FREQ_MASK		(0x7fff << 17)
+#define BACKLIGHT_MODULATION_FREQ_MASK2		(0xffff << 16)
 #define BLM_LEGACY_MODE				(1 << 16)
+
 /**
  * This is the number of cycles out of the backlight modulation cycle for which
  * the backlight is on.
@@ -1084,6 +1088,10 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN
 #define BACKLIGHT_DUTY_CYCLE_SHIFT		(0)
 #define BACKLIGHT_DUTY_CYCLE_MASK		(0xffff)
 
+/* On 965+ backlight control is in another register */
+#define BLC_PWM_CTL2			0x61250
+#define 	BLM_LEGACY_MODE2	(1 << 30)
+
 #define BLM_CTL			0x61260
 #define BLM_THRESHOLD_0		0x61270
 #define BLM_THRESHOLD_1		0x61274
diff --git a/src/i830.h b/src/i830.h
index bf072a1..a8de0e6 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -532,6 +532,7 @@ typedef struct _I830Rec {
    CARD32 savePaletteB[256];
    CARD32 saveSWF[17];
    CARD32 saveBLC_PWM_CTL;
+   CARD32 saveBLC_PWM_CTL2;
    CARD32 saveFBC_CFB_BASE;
    CARD32 saveFBC_LL_BASE;
    CARD32 saveFBC_CONTROL2;
diff --git a/src/i830_lvds.c b/src/i830_lvds.c
index 246008b..18e5c2b 100644
--- a/src/i830_lvds.c
+++ b/src/i830_lvds.c
@@ -46,6 +46,30 @@ struct i830_lvds_priv {
     int		    backlight_duty_cycle;
 };
 
+/**
+ * Use legacy backlight controls?
+ *
+ * \param pI830 device in question
+ *
+ * Returns TRUE if legacy backlight should be used, false otherwise.
+ */
+static int
+i830_lvds_backlight_legacy(I830Ptr pI830)
+{
+    CARD32 blc_pwm_ctl, blc_pwm_ctl2;
+
+    /* 965GM+ change the location of the legacy control bit */
+    if (IS_I965GM(pI830)) {
+	blc_pwm_ctl2 = INREG(BLC_PWM_CTL2);
+	if (blc_pwm_ctl2 & BLM_LEGACY_MODE2)
+	    return TRUE;
+    } else {
+	blc_pwm_ctl = INREG(BLC_PWM_CTL);
+	if (blc_pwm_ctl & BLM_LEGACY_MODE)
+	    return TRUE;
+    }
+    return FALSE;
+}
 
 /**
  * Sets the backlight level.
@@ -59,18 +83,12 @@ i830_lvds_set_backlight(xf86OutputPtr ou
     I830Ptr pI830 = I830PTR(pScrn);
     CARD32 blc_pwm_ctl;
 
+    if (i830_lvds_backlight_legacy(pI830))
+	pciWriteByte(pI830->PciTag, LEGACY_BACKLIGHT_BRIGHTNESS, 0xfe);
+
     blc_pwm_ctl = INREG(BLC_PWM_CTL);
-    if (blc_pwm_ctl & BLM_LEGACY_MODE)
-    {
-	pciWriteByte (pI830->PciTag, 
-		      LEGACY_BACKLIGHT_BRIGHTNESS,
-		      level & 0xff);
-    }
-    else
-    {
-	blc_pwm_ctl &= ~BACKLIGHT_DUTY_CYCLE_MASK;
-	OUTREG(BLC_PWM_CTL, blc_pwm_ctl | (level << BACKLIGHT_DUTY_CYCLE_SHIFT));
-    }
+    blc_pwm_ctl &= ~BACKLIGHT_DUTY_CYCLE_MASK;
+    OUTREG(BLC_PWM_CTL, blc_pwm_ctl | (level << BACKLIGHT_DUTY_CYCLE_SHIFT));
 }
 
 /**
@@ -82,12 +100,24 @@ i830_lvds_get_max_backlight(xf86OutputPt
     ScrnInfoPtr pScrn = output->scrn;
     I830Ptr	pI830 = I830PTR(pScrn);
     CARD32	pwm_ctl = INREG(BLC_PWM_CTL);
+    CARD32	val;
+
+    if (IS_I965GM(pI830)) {
+	val = ((pwm_ctl & BACKLIGHT_MODULATION_FREQ_MASK2) >>
+	       BACKLIGHT_MODULATION_FREQ_SHIFT2);
+    } else {
+	val = ((pwm_ctl & BACKLIGHT_MODULATION_FREQ_MASK) >>
+	       BACKLIGHT_MODULATION_FREQ_SHIFT) * 2;
+    }
     
-    if (pwm_ctl & BLM_LEGACY_MODE)
-	return 0xff;
-    else
-	return ((pwm_ctl & BACKLIGHT_MODULATION_FREQ_MASK) >>
-		BACKLIGHT_MODULATION_FREQ_SHIFT) * 2;
+    /*
+     * In legacy control mode, backlight value is calculated:
+     * if (LBB[7:0] != 0xff)
+     *     backlight = BLC_PWM_CTL[15:0] *  BPC[7:0]
+     * else
+     *     backlight = BLC_PWM_CTL[15:0]
+     */
+    return val;
 }
 
 /**
@@ -138,21 +168,15 @@ i830_lvds_save (xf86OutputPtr output)
     ScrnInfoPtr		    pScrn = output->scrn;
     I830Ptr		    pI830 = I830PTR(pScrn);
 
+    if (IS_I965GM(pI830))
+	pI830->saveBLC_PWM_CTL2 = INREG(BLC_PWM_CTL2);
     pI830->savePP_ON = INREG(LVDSPP_ON);
     pI830->savePP_OFF = INREG(LVDSPP_OFF);
     pI830->savePP_CONTROL = INREG(PP_CONTROL);
     pI830->savePP_CYCLE = INREG(PP_CYCLE);
     pI830->saveBLC_PWM_CTL = INREG(BLC_PWM_CTL);
-    if (pI830->saveBLC_PWM_CTL & BLM_LEGACY_MODE)
-    {
-	dev_priv->backlight_duty_cycle = pciReadByte (pI830->PciTag,
-						      LEGACY_BACKLIGHT_BRIGHTNESS);
-    }
-    else
-    {
-	dev_priv->backlight_duty_cycle = (pI830->saveBLC_PWM_CTL &
-					  BACKLIGHT_DUTY_CYCLE_MASK);
-    }
+    dev_priv->backlight_duty_cycle = (pI830->saveBLC_PWM_CTL &
+				      BACKLIGHT_DUTY_CYCLE_MASK);
 
     /*
      * If the light is off at server startup, just make it full brightness
@@ -167,6 +191,8 @@ i830_lvds_restore(xf86OutputPtr output)
     ScrnInfoPtr	pScrn = output->scrn;
     I830Ptr	pI830 = I830PTR(pScrn);
 
+    if (IS_I965GM(pI830))
+	OUTREG(BLC_PWM_CTL2, pI830->saveBLC_PWM_CTL2);
     OUTREG(BLC_PWM_CTL, pI830->saveBLC_PWM_CTL);
     OUTREG(LVDSPP_ON, pI830->savePP_ON);
     OUTREG(LVDSPP_OFF, pI830->savePP_OFF);
diff-tree 15f71edba37738f8ba279fa07452fda10cc65298 (from f403a50afbcef1e54f554481c72037338bd5357c)
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Sat Jul 28 17:43:29 2007 +0800

    Update Lenovo TV quirk info

diff --git a/src/i830_quirks.c b/src/i830_quirks.c
index 8a4b07c..e209fea 100644
--- a/src/i830_quirks.c
+++ b/src/i830_quirks.c
@@ -57,6 +57,7 @@ static void quirk_mac_mini (I830Ptr pI83
 static i830_quirk i830_quirk_list[] = {
     /* Lenovo T61 has no TV output */
     { PCI_CHIP_I965_GM, 0x17aa, 0x20b5, quirk_ignore_tv },
+    /* Lenovo 3000 v200 */
     { PCI_CHIP_I965_GM, 0x17aa, 0x3c18, quirk_ignore_tv },
     /* Aopen mini pc */
     { PCI_CHIP_I945_GM, 0xa0a0, SUBSYS_ANY, quirk_ignore_lvds },
diff-tree f403a50afbcef1e54f554481c72037338bd5357c (from 34c82ad7ce83394db47588693b578cf91991bf1c)
Author: Wang Zhenyu <zhenyu.z.wang at intel.com>
Date:   Fri Jul 27 09:24:24 2007 +0800

    Add another Lenovo TV output quirk
    
    From issue report http://lists.freedesktop.org/archives/xorg/2007-July/026644.html

diff --git a/src/i830_quirks.c b/src/i830_quirks.c
index 1bf4692..8a4b07c 100644
--- a/src/i830_quirks.c
+++ b/src/i830_quirks.c
@@ -57,6 +57,7 @@ static void quirk_mac_mini (I830Ptr pI83
 static i830_quirk i830_quirk_list[] = {
     /* Lenovo T61 has no TV output */
     { PCI_CHIP_I965_GM, 0x17aa, 0x20b5, quirk_ignore_tv },
+    { PCI_CHIP_I965_GM, 0x17aa, 0x3c18, quirk_ignore_tv },
     /* Aopen mini pc */
     { PCI_CHIP_I945_GM, 0xa0a0, SUBSYS_ANY, quirk_ignore_lvds },
     /* Mac mini has no lvds, but macbook pro does */
diff-tree 34c82ad7ce83394db47588693b578cf91991bf1c (from 0fd3ba0518b3cde9ca0e4e2fc1854c00d8a43d5c)
Author: Wang Zhenyu <zhenyu.z.wang at intel.com>
Date:   Fri Jul 27 09:14:13 2007 +0800

    Add quirk support
    
    This one trys to use a flag for possible quirks. It adds a quirk
    for my Lenovo T61 TV output, and ports some origin LVDS quirks to it.

diff --git a/src/Makefile.am b/src/Makefile.am
index 858ffd1..50e913e 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -90,6 +90,7 @@ intel_drv_la_SOURCES = \
 	 i830_debug.h \
 	 i830_display.c \
 	 i830_display.h \
+         i830_quirks.c \
          i830_driver.c \
 	 i830_dvo.c \
          i830.h \
diff --git a/src/i830.h b/src/i830.h
index aa2b240..bf072a1 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -541,6 +541,7 @@ typedef struct _I830Rec {
 
    /** Enables logging of debug output related to mode switching. */
    Bool debug_modes;
+   unsigned int quirk_flag;
 } I830Rec;
 
 #define I830PTR(p) ((I830Ptr)((p)->driverPrivate))
@@ -750,4 +751,10 @@ extern const int I830CopyROP[16];
 #define _845_DRAM_RW_CONTROL 0x90
 #define DRAM_WRITE    0x33330000
 
+/* quirk flag definition */
+#define QUIRK_IGNORE_TV			0x00000001
+#define QUIRK_IGNORE_LVDS		0x00000002
+#define QUIRK_IGNORE_MACMINI_LVDS 	0x00000004
+extern void i830_fixup_devices(ScrnInfoPtr);
+
 #endif /* _I830_H_ */
diff --git a/src/i830_driver.c b/src/i830_driver.c
index 9bb12c6..f293bfd 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -1192,6 +1192,9 @@ I830PreInit(ScrnInfoPtr pScrn, int flags
    xf86DrvMsg(pScrn->scrnIndex, from, "IO registers at addr 0x%lX\n",
 	      (unsigned long)pI830->MMIOAddr);
 
+   /* check quirks */
+   i830_fixup_devices(pScrn);
+
    /* Allocate an xf86CrtcConfig */
    xf86CrtcConfigInit (pScrn, &i830_xf86crtc_config_funcs);
    xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
diff --git a/src/i830_lvds.c b/src/i830_lvds.c
index e2c6e3c..246008b 100644
--- a/src/i830_lvds.c
+++ b/src/i830_lvds.c
@@ -462,6 +462,9 @@ i830_lvds_init(ScrnInfoPtr pScrn)
     DisplayModePtr	    modes, scan, bios_mode;
     struct i830_lvds_priv   *dev_priv;
 
+    if (pI830->quirk_flag & QUIRK_IGNORE_LVDS)
+	return;
+
     output = xf86OutputCreate (pScrn, &i830_lvds_output_funcs, "LVDS");
     if (!output)
 	return;
@@ -575,29 +578,23 @@ i830_lvds_init(ScrnInfoPtr pScrn)
     /* Blacklist machines with BIOSes that list an LVDS panel without actually
      * having one.
      */
-    if (pI830->PciInfo->chipType == PCI_CHIP_I945_GM) {
-	if (pI830->PciInfo->subsysVendor == 0xa0a0)  /* aopen mini pc */
-	    goto disable_exit;
-
-	if ((pI830->PciInfo->subsysVendor == 0x8086) &&
-	    (pI830->PciInfo->subsysCard == 0x7270)) {
-	    /* It's a Mac Mini or Macbook Pro.
-	     *
-	     * Apple hardware is out to get us.  The macbook pro has a real
-	     * LVDS panel, but the mac mini does not, and they have the same
-	     * device IDs.  We'll distinguish by panel size, on the assumption
-	     * that Apple isn't about to make any machines with an 800x600
-	     * display.
-	     */
+    if (pI830->quirk_flag & QUIRK_IGNORE_MACMINI_LVDS) {
+	/* It's a Mac Mini or Macbook Pro.
+	 *
+	 * Apple hardware is out to get us.  The macbook pro has a real
+	 * LVDS panel, but the mac mini does not, and they have the same
+	 * device IDs.  We'll distinguish by panel size, on the assumption
+	 * that Apple isn't about to make any machines with an 800x600
+	 * display.
+	 */
 
-	    if (dev_priv->panel_fixed_mode != NULL &&
+	if (dev_priv->panel_fixed_mode != NULL &&
 		dev_priv->panel_fixed_mode->HDisplay == 800 &&
 		dev_priv->panel_fixed_mode->VDisplay == 600)
-	    {
-		xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-			   "Suspected Mac Mini, ignoring the LVDS\n");
-		goto disable_exit;
-	    }
+	{
+	    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+		    "Suspected Mac Mini, ignoring the LVDS\n");
+	    goto disable_exit;
 	}
     }
 
diff --git a/src/i830_quirks.c b/src/i830_quirks.c
new file mode 100644
index 0000000..1bf4692
--- /dev/null
+++ b/src/i830_quirks.c
@@ -0,0 +1,80 @@
+/*
+ * Copyright © 2007 Intel Corporation
+ *
+ * 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:
+ *    Zhenyu Wang <zhenyu.z.wang at intel.com>
+ *
+ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "i830.h"
+
+#define SUBSYS_ANY (~0)
+
+typedef struct {
+    int chipType;
+    int subsysVendor;
+    int subsysCard;
+    void (*hook)(I830Ptr);
+} i830_quirk, *i830_quirk_ptr;
+
+static void quirk_ignore_tv (I830Ptr pI830)
+{
+    pI830->quirk_flag |= QUIRK_IGNORE_TV;
+}
+
+static void quirk_ignore_lvds (I830Ptr pI830)
+{
+    pI830->quirk_flag |= QUIRK_IGNORE_LVDS;
+}
+
+static void quirk_mac_mini (I830Ptr pI830)
+{
+    pI830->quirk_flag |= QUIRK_IGNORE_MACMINI_LVDS;
+}
+
+static i830_quirk i830_quirk_list[] = {
+    /* Lenovo T61 has no TV output */
+    { PCI_CHIP_I965_GM, 0x17aa, 0x20b5, quirk_ignore_tv },
+    /* Aopen mini pc */
+    { PCI_CHIP_I945_GM, 0xa0a0, SUBSYS_ANY, quirk_ignore_lvds },
+    /* Mac mini has no lvds, but macbook pro does */
+    { PCI_CHIP_I945_GM, 0x8086, 0x7270, quirk_mac_mini },
+    { 0, 0, 0, NULL },
+};
+
+void i830_fixup_devices(ScrnInfoPtr scrn)
+{
+    I830Ptr pI830 = I830PTR(scrn);
+    i830_quirk_ptr p = i830_quirk_list;
+
+    while (p && p->chipType != 0) {
+	if (pI830->PciInfo->chipType == p->chipType &&
+		pI830->PciInfo->subsysVendor == p->subsysVendor &&
+		(pI830->PciInfo->subsysCard == p->subsysCard ||
+		 p->subsysCard == SUBSYS_ANY))
+	    p->hook(pI830);
+	++p;
+    }
+}
diff --git a/src/i830_tv.c b/src/i830_tv.c
index 8337d86..aba0e3b 100644
--- a/src/i830_tv.c
+++ b/src/i830_tv.c
@@ -1625,6 +1625,9 @@ i830_tv_init(ScrnInfoPtr pScrn)
     struct i830_tv_priv	    *dev_priv;
     CARD32		    tv_dac_on, tv_dac_off, save_tv_dac;
 
+    if (pI830->quirk_flag & QUIRK_IGNORE_TV)
+	return;
+
     if ((INREG(TV_CTL) & TV_FUSE_STATE_MASK) == TV_FUSE_STATE_DISABLED)
 	return;
 
diff-tree 0fd3ba0518b3cde9ca0e4e2fc1854c00d8a43d5c (from 45962eed51120ff77326c29d72cf8b6cd8a934b5)
Author: Brice Goglin <Brice.Goglin at ens-lyon.org>
Date:   Wed Jul 25 20:11:32 2007 +0200

    Fix typo in intel.man
    
    Reported by A. Costa" <agcosta at gis.net> in
    http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=432061

diff --git a/man/intel.man b/man/intel.man
index 33dc319..5909fdd 100644
--- a/man/intel.man
+++ b/man/intel.man
@@ -141,7 +141,7 @@ and that is used with the 3D driver in M
 upwards. If the size is set too high to make room for pre-allocated
 VideoRam, the driver will try to reduce it automatically. If you use only
 older Mesa or DRM versions, you may set this value to zero, and
-atctivate the legacy texture pool (see 
+activate the legacy texture pool (see 
 .B "Option \*qLegacy3D\*q"
 ). If you run 3D programs with large texture memory requirements, you might
 gain some performance by increasing this value.
diff-tree 45962eed51120ff77326c29d72cf8b6cd8a934b5 (from b1af2c0e01c54ef1d40fd0ca1ede29a1dd7ed97b)
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Mon Jul 23 09:50:17 2007 +0800

    Fix a typo in i915 render
    
    Fence setting is in mapstate actually. This fixes rotation in
    tiled fb case, thanks Keith to report this.

diff --git a/src/i915_render.c b/src/i915_render.c
index 9d5bc0a..9c937f2 100644
--- a/src/i915_render.c
+++ b/src/i915_render.c
@@ -288,7 +288,7 @@ i915_texture_setup(PicturePtr pPict, Pix
 	((pPix->drawable.height - 1) << MS3_HEIGHT_SHIFT) |
 	((pPix->drawable.width - 1) << MS3_WIDTH_SHIFT);
     if (pI830->tiling)
-	pI830->samplerstate[unit * 3 + 1] |= MS3_USE_FENCE_REGS;
+	pI830->mapstate[unit * 3 + 1] |= MS3_USE_FENCE_REGS;
     pI830->mapstate[unit * 3 + 2] = ((pitch / 4) - 1) << MS4_PITCH_SHIFT;
 
     pI830->samplerstate[unit * 3 + 0] = (MIPFILTER_NONE <<
diff-tree b1af2c0e01c54ef1d40fd0ca1ede29a1dd7ed97b (from c7920a0e819308762fca3d6fc7ab194bd565b06a)
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Fri Jul 20 15:18:48 2007 +0800

    Fix device id info for 945GME, 965GME
    
    which do have new host bridge ids

diff --git a/src/common.h b/src/common.h
index cc07e49..fa96a5d 100644
--- a/src/common.h
+++ b/src/common.h
@@ -331,10 +331,14 @@ extern int I810_DEBUG;
 
 #ifndef PCI_CHIP_I945_GM
 #define PCI_CHIP_I945_GM        0x27A2
-#define PCI_CHIP_I945_GME	0x27AE
 #define PCI_CHIP_I945_GM_BRIDGE 0x27A0
 #endif
 
+#ifndef PCI_CHIP_I945_GME
+#define PCI_CHIP_I945_GME	 0x27AE
+#define PCI_CHIP_I945_GME_BRIDGE 0x27AC
+#endif
+
 #ifndef PCI_CHIP_I965_G_1
 #define PCI_CHIP_I965_G_1		0x2982
 #define PCI_CHIP_I965_G_1_BRIDGE 	0x2980
@@ -357,10 +361,14 @@ extern int I810_DEBUG;
 
 #ifndef PCI_CHIP_I965_GM
 #define PCI_CHIP_I965_GM        0x2A02
-#define PCI_CHIP_I965_GME	0x2A12
 #define PCI_CHIP_I965_GM_BRIDGE 0x2A00
 #endif
 
+#ifndef PCI_CHIP_I965_GME
+#define PCI_CHIP_I965_GME       0x2A12
+#define PCI_CHIP_I965_GME_BRIDGE 0x2A10
+#endif
+
 #ifndef PCI_CHIP_G33_G
 #define PCI_CHIP_G33_G		0x29C2
 #define PCI_CHIP_G33_G_BRIDGE 	0x29C0
diff-tree c7920a0e819308762fca3d6fc7ab194bd565b06a (from 37652b68880f1881b90bd22218cfe86eca7e5974)
Author: Dave Airlie <airlied at linux.ie>
Date:   Thu Jul 19 15:09:54 2007 +1000

    strip out remainder of drmmm code in driver

diff --git a/src/i830_driver.c b/src/i830_driver.c
index 3e90eea..9bb12c6 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -2863,11 +2863,7 @@ I830LeaveVT(int scrnIndex, int flags)
       DRILock(screenInfo.screens[pScrn->scrnIndex], 0);
 #ifdef XF86DRI_MM
       if (pI830->mmModeFlags & I830_KERNEL_MM) {
-#ifndef XSERVER_LIBDRM_MM
-	 I830DrmMMLock(pI830->drmSubFD, DRM_BO_MEM_TT);
-#else
 	 drmMMLock(pI830->drmSubFD, DRM_BO_MEM_TT);
-#endif
       }
 #endif /* XF86DRI_MM */
       I830DRISetVBlankInterrupt (pScrn, FALSE);
@@ -2972,11 +2968,7 @@ I830EnterVT(int scrnIndex, int flags)
 
 #ifdef XF86DRI_MM
 	 if (pI830->mmModeFlags & I830_KERNEL_MM) {
-#ifndef XSERVER_LIBDRM_MM
-	    I830DrmMMUnlock(pI830->drmSubFD, DRM_BO_MEM_TT);
-#else
 	    drmMMUnlock(pI830->drmSubFD, DRM_BO_MEM_TT);
-#endif
 	 }
 #endif /* XF86DRI_MM */
 
@@ -3035,11 +3027,7 @@ I830CloseScreen(int scrnIndex, ScreenPtr
 #endif
 #ifdef XF86DRI_MM
       if (pI830->mmModeFlags & I830_KERNEL_MM) {
-#ifndef XSERVER_LIBDRM_MM
-	 I830DrmMMTakedown(pI830->drmSubFD, DRM_BO_MEM_TT);
-#else
 	 drmMMTakedown(pI830->drmSubFD, DRM_BO_MEM_TT);	 
-#endif
       }
 #endif /* XF86DRI_MM */
       pI830->directRenderingOpen = FALSE;
diff-tree 37652b68880f1881b90bd22218cfe86eca7e5974 (from e40f6a4923d1323702406266e90eae3218a8a44e)
Author: Dave Airlie <airlied at linux.ie>
Date:   Tue Jul 17 14:03:21 2007 +1000

    intel: oops I commited pixman local workaround - undo it

diff --git a/configure.ac b/configure.ac
index ec2864d..9b76b65 100644
--- a/configure.ac
+++ b/configure.ac
@@ -85,7 +85,7 @@ XORG_DRIVER_CHECK_EXT(XF86DRI, xextproto
 XORG_DRIVER_CHECK_EXT(DPMSExtension, xextproto)
 
 # Checks for pkg-config packages
-PKG_CHECK_MODULES(XORG, [pixman xorg-server xproto xvmc fontsproto $REQUIRED_MODULES])
+PKG_CHECK_MODULES(XORG, [xorg-server xproto xvmc fontsproto $REQUIRED_MODULES])
 sdkdir=$(pkg-config --variable=sdkdir xorg-server)
 
 PKG_CHECK_MODULES([PCIACCESS], [pciaccess >= 0.5.0], have_pciaccess=yes, have_pciaccess=no)
diff-tree e40f6a4923d1323702406266e90eae3218a8a44e (from 1e169be25b2e4ab34afd4b8ae8ae0041f6069125)
Author: Dave Airlie <airlied at linux.ie>
Date:   Tue Jul 17 09:20:07 2007 +1000

    intel: actually 2.3.1 should be good enough

diff --git a/configure.ac b/configure.ac
index 48c8cb2..ec2864d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -183,7 +183,7 @@ 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.2],[DRI_MM=yes], [DRI_MM=no])
+	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
diff-tree 1e169be25b2e4ab34afd4b8ae8ae0041f6069125 (from ff2be3995d33f9e4b7f63b380f166b6168c9b9c6)
Author: Dave Airlie <airlied at linux.ie>
Date:   Tue Jul 17 09:17:31 2007 +1000

    intel: don't try and use TTM memory manager with old libdrm interface
    
    I probably need to release a libdrm with this interface in it now..

diff --git a/configure.ac b/configure.ac
index ec30376..48c8cb2 100644
--- a/configure.ac
+++ b/configure.ac
@@ -85,7 +85,7 @@ XORG_DRIVER_CHECK_EXT(XF86DRI, xextproto
 XORG_DRIVER_CHECK_EXT(DPMSExtension, xextproto)
 
 # Checks for pkg-config packages
-PKG_CHECK_MODULES(XORG, [xorg-server xproto xvmc fontsproto $REQUIRED_MODULES])
+PKG_CHECK_MODULES(XORG, [pixman xorg-server xproto xvmc fontsproto $REQUIRED_MODULES])
 sdkdir=$(pkg-config --variable=sdkdir xorg-server)
 
 PKG_CHECK_MODULES([PCIACCESS], [pciaccess >= 0.5.0], have_pciaccess=yes, have_pciaccess=no)
@@ -183,7 +183,7 @@ 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.2],[DRI_MM=yes], [DRI_MM=no])
+	PKG_CHECK_MODULES(DRI_MM, [libdrm >= 2.3.2],[DRI_MM=yes], [DRI_MM=no])
 	if test "x$DRI_MM" = xyes; then
 		AC_DEFINE(XF86DRI_MM,1,[Extended DRI memory management])
 	fi
diff --git a/src/i830.h b/src/i830.h
index b85ee26..aa2b240 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -750,10 +750,4 @@ extern const int I830CopyROP[16];
 #define _845_DRAM_RW_CONTROL 0x90
 #define DRAM_WRITE    0x33330000
 
-/* 
- * Xserver MM compatibility. Remove code guarded by this when the
- * XServer contains the libdrm mm code
- */
-#undef XSERVER_LIBDRM_MM
-
 #endif /* _I830_H_ */
diff --git a/src/i830_driver.c b/src/i830_driver.c
index 51a17f0..3e90eea 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -2116,83 +2116,6 @@ IntelEmitInvarientState(ScrnInfoPtr pScr
    }
 }
 
-#ifdef XF86DRI_MM
-#ifndef XSERVER_LIBDRM_MM
-
-static int
-I830DrmMMInit(int drmFD, unsigned long pageOffs, unsigned long pageSize,
-	      unsigned memType)
-{
-
-   drm_mm_init_arg_t arg;
-   int ret;
-   
-   memset(&arg, 0, sizeof(arg));
-   arg.req.op = mm_init;
-   arg.req.p_offset = pageOffs;
-   arg.req.p_size = pageSize;
-   arg.req.mem_type = memType;
-
-   ret = ioctl(drmFD, DRM_IOCTL_MM_INIT, &arg);
-   
-   if (ret)
-      return -errno;
-   
-   return 0;
-   
-}
-
-static int
-I830DrmMMTakedown(int drmFD, unsigned memType)
-{
-   drm_mm_init_arg_t arg;
-   int ret = 0;
-   
-   memset(&arg, 0, sizeof(arg));
-   arg.req.op = mm_takedown;
-   arg.req.mem_type = memType;
-   if (ioctl(drmFD, DRM_IOCTL_MM_INIT, &arg)) {
-      ret = -errno;
-   }
-   
-   return ret;
-}
-
-static int I830DrmMMLock(int fd, unsigned memType)
-{
-    drm_mm_init_arg_t arg;
-    int ret;
-
-    memset(&arg, 0, sizeof(arg));
-    arg.req.op = mm_lock;
-    arg.req.mem_type = memType;
-
-    do{
-	ret = ioctl(fd, DRM_IOCTL_MM_INIT, &arg);
-    } while (ret && errno == EAGAIN);
-    
-    return ret;	
-}
-
-static int I830DrmMMUnlock(int fd, unsigned memType)
-{
-    drm_mm_init_arg_t arg;
-    int ret;
-
-    memset(&arg, 0, sizeof(arg));
-    arg.req.op = mm_unlock;
-    arg.req.mem_type = memType;
-
-    do{
-	ret = ioctl(fd, DRM_IOCTL_MM_INIT, &arg);
-    } while (ret && errno == EAGAIN);
-    
-    return ret;	
-}
-
-#endif
-#endif /* XF86DRI_MM */
-
 static Bool
 I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
 {
@@ -2866,13 +2789,8 @@ I830ScreenInit(int scrnIndex, ScreenPtr 
 	 unsigned long aperStart = ROUND_TO(pI830->memory_manager->offset,
 					    GTT_PAGE_SIZE) / GTT_PAGE_SIZE;
 
-#ifndef XSERVER_LIBDRM_MM
-	 if (I830DrmMMInit(pI830->drmSubFD, aperStart, aperEnd - aperStart,
-			   DRM_BO_MEM_TT)) {
-#else
 	 if (drmMMInit(pI830->drmSubFD, aperStart, aperEnd - aperStart,
 		       DRM_BO_MEM_TT)) {
-#endif	   
 	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 
 		       "Could not initialize the DRM memory manager.\n");
 	    
diff-tree ff2be3995d33f9e4b7f63b380f166b6168c9b9c6 (from 00f4587025a3879626623135b0a153fcdb906719)
Author: Keith Packard <keithp at neko.keithp.com>
Date:   Fri Jul 13 12:47:18 2007 -0700

    Remove hard-coded CRT blanking frobbing for load detection.
    
    CRT blanking needn't be adjusted to perform load detection on 9xx chips, and
    the 8xx load detection path now adjusts blanking just during load detection.
    Adjusting the blanking interval turned out to cause many monitors to fail to
    sync.

diff --git a/src/i830_crt.c b/src/i830_crt.c
index 9e6180e..d7762a0 100644
--- a/src/i830_crt.c
+++ b/src/i830_crt.c
@@ -97,8 +97,6 @@ static Bool
 i830_crt_mode_fixup(xf86OutputPtr output, DisplayModePtr mode,
 		    DisplayModePtr adjusted_mode)
 {
-    /* disable blanking so we can detect monitors */
-    adjusted_mode->CrtcVBlankStart = adjusted_mode->CrtcVTotal - 3;
     return TRUE;
 }
 
@@ -360,8 +358,8 @@ i830_crt_detect(xf86OutputPtr output)
 	    return XF86OutputStatusDisconnected;
     }
 
-//    if (i830_crt_detect_ddc(output))
-//	return XF86OutputStatusConnected;
+    if (i830_crt_detect_ddc(output))
+	return XF86OutputStatusConnected;
 
     /* Use the load-detect method if we have no other way of telling. */
     crtc = i830GetLoadDetectPipe (output, NULL, &dpms_mode);
diff --git a/src/i830_display.c b/src/i830_display.c
index 16af496..26873fe 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -1509,6 +1509,8 @@ i830GetLoadDetectPipe(xf86OutputPtr outp
 	output->funcs->mode_set (output, &crtc->mode, &crtc->mode);
 	output->funcs->commit (output);
     }
+    /* let the output get through one full cycle before testing */
+    i830WaitForVblank (pScrn);
 
     return crtc;
 }
diff-tree 00f4587025a3879626623135b0a153fcdb906719 (from 6f18300aed1340348c6d395f326061b5315be643)
Author: Keith Packard <keithp at neko.keithp.com>
Date:   Fri Jul 13 10:58:06 2007 -0700

    Ensure pipe/output active before doing load detection.
    
    If the pipe or output have been set to DPMSOff, then load detection will not
    work correctly. Also, share the load detection configuration code between
    crt and tv outputs.

diff --git a/src/i830.h b/src/i830.h
index 409057c..b85ee26 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -220,6 +220,8 @@ typedef struct _I830CrtcPrivateRec {
 
     Bool    		    enabled;
     
+    int			    dpms_mode;
+    
     /* Lookup table values to be set when the CRTC is enabled */
     CARD8 lut_r[256], lut_g[256], lut_b[256];
 
diff --git a/src/i830_crt.c b/src/i830_crt.c
index 1900dfb..9e6180e 100644
--- a/src/i830_crt.c
+++ b/src/i830_crt.c
@@ -349,8 +349,9 @@ i830_crt_detect(xf86OutputPtr output)
 {
     ScrnInfoPtr		    pScrn = output->scrn;
     I830Ptr		    pI830 = I830PTR(pScrn);
-    xf86CrtcPtr	    crtc;
-
+    xf86CrtcPtr		    crtc;
+    int			    dpms_mode;
+    
     if (IS_I945G(pI830) || IS_I945GM(pI830) || IS_I965G(pI830) ||
 	    IS_G33CLASS(pI830)) {
 	if (i830_crt_detect_hotplug(output))
@@ -359,49 +360,18 @@ i830_crt_detect(xf86OutputPtr output)
 	    return XF86OutputStatusDisconnected;
     }
 
-    if (i830_crt_detect_ddc(output))
-	return XF86OutputStatusConnected;
+//    if (i830_crt_detect_ddc(output))
+//	return XF86OutputStatusConnected;
 
     /* Use the load-detect method if we have no other way of telling. */
-    crtc = i830GetLoadDetectPipe (output);
+    crtc = i830GetLoadDetectPipe (output, NULL, &dpms_mode);
     
     if (crtc)
     {
-	/* VESA 640x480x72Hz mode to set on the pipe */
-	static DisplayModeRec   mode = {
-	    NULL, NULL, "640x480", MODE_OK, M_T_DEFAULT,
-	    31500,
-	    640, 664, 704, 832, 0,
-	    480, 489, 491, 520, 0,
-	    V_NHSYNC | V_NVSYNC,
-	    0, 0,
-	    0, 0, 0, 0, 0, 0, 0,
-	    0, 0, 0, 0, 0, 0,
-	    FALSE, FALSE, 0, NULL, 0, 0.0, 0.0
-	};
 	Bool			connected;
-	I830OutputPrivatePtr	intel_output = output->driver_private;
-	
-	if (!crtc->enabled)
-	{
-	    xf86SetModeCrtc (&mode, INTERLACE_HALVE_V);
-	    /*
-	     * Give us some border at the bottom for load detection on i8xx
-	     */
-	    mode.CrtcVBlankStart = mode.CrtcVSyncStart;
-	    if (mode.CrtcVBlankEnd - mode.CrtcVBlankStart < 3)
-		mode.CrtcVBlankStart = mode.CrtcVBlankEnd - 3;
-	    xf86CrtcSetMode (crtc, &mode, RR_Rotate_0, 0, 0);
-	}
-	else if (intel_output->load_detect_temp)
-	{
-	    /* Add this output to the crtc */
-	    output->funcs->mode_set (output, &crtc->mode, &crtc->mode);
-	    output->funcs->commit (output);
-	}
-	connected = i830_crt_detect_load (crtc, output);
 
-	i830ReleaseLoadDetectPipe (output);
+	connected = i830_crt_detect_load (crtc, output);
+	i830ReleaseLoadDetectPipe (output, dpms_mode);
 	if (connected)
 	    return XF86OutputStatusConnected;
 	else
diff --git a/src/i830_display.c b/src/i830_display.c
index ff25b29..16af496 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -605,6 +605,8 @@ i830_crtc_dpms(xf86CrtcPtr crtc, int mod
 	break;
     }
 
+    intel_crtc->dpms_mode = mode;
+
 #ifdef XF86DRI
     if (pI830->directRenderingEnabled) {
 	drmI830Sarea *sPriv = (drmI830Sarea *) DRIGetSAREAPrivate(pScrn->pScreen);
@@ -1424,58 +1426,116 @@ i830DescribeOutputConfiguration(ScrnInfo
  * \return crtc, or NULL if no pipes are available.
  */
     
+/* VESA 640x480x72Hz mode to set on the pipe */
+static DisplayModeRec   load_detect_mode = {
+    NULL, NULL, "640x480", MODE_OK, M_T_DEFAULT,
+    31500,
+    640, 664, 704, 832, 0,
+    480, 489, 491, 520, 0,
+    V_NHSYNC | V_NVSYNC,
+    0, 0,
+
+    640, 640, 664, 704, 832, 832, 0,
+    480, 489, 489, 491, 520, 520,
+    FALSE, FALSE, 0, NULL, 0, 0.0, 0.0
+};
+
 xf86CrtcPtr
-i830GetLoadDetectPipe(xf86OutputPtr output)
+i830GetLoadDetectPipe(xf86OutputPtr output, DisplayModePtr mode, int *dpms_mode)
 {
     ScrnInfoPtr		    pScrn = output->scrn;
     xf86CrtcConfigPtr	    xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
     I830OutputPrivatePtr    intel_output = output->driver_private;
+    I830CrtcPrivatePtr	    intel_crtc;
     xf86CrtcPtr		    supported_crtc =NULL;
-    xf86CrtcPtr		    detect_crtc = NULL;
+    xf86CrtcPtr		    crtc = NULL;
     int			    i;
 
     if (output->crtc) 
-	return output->crtc;
+    {
+	crtc = output->crtc;
+	/*
+	 * Make sure the crtc and output are running
+	 */
+	intel_crtc = crtc->driver_private;
+	*dpms_mode = intel_crtc->dpms_mode;
+	if (intel_crtc->dpms_mode != DPMSModeOn)
+	{
+	    crtc->funcs->dpms (crtc, DPMSModeOn);
+	    output->funcs->dpms (output, DPMSModeOn);
+	}
+	return crtc;
+    }
 
     for (i = 0; i < xf86_config->num_crtc; i++)
     {
-	xf86CrtcPtr crtc;
+	xf86CrtcPtr possible_crtc;
 	if (!(output->possible_crtcs & (1 << i)))
 	    continue;
-	crtc = xf86_config->crtc[i];
-	if (!crtc->enabled)
+	possible_crtc = xf86_config->crtc[i];
+	if (!possible_crtc->enabled)
 	{
-	    detect_crtc = crtc;
+	    crtc = possible_crtc;
 	    break;
 	}
 	if (!supported_crtc)
-	    supported_crtc = crtc;
+	    supported_crtc = possible_crtc;
+    }
+    if (!crtc)
+    {
+	crtc = supported_crtc;
+	if (!crtc)
+	    return NULL;
     }
-    if (!detect_crtc)
-	detect_crtc = supported_crtc;
-    if (!detect_crtc)
-	return NULL;
 
-    output->crtc = detect_crtc;
+    output->crtc = crtc;
     intel_output->load_detect_temp = TRUE;
+    
+    intel_crtc = crtc->driver_private;
+    *dpms_mode = intel_crtc->dpms_mode;
 
-    return detect_crtc;
+    if (!crtc->enabled)
+    {
+	if (!mode)
+	    mode = &load_detect_mode;
+	xf86CrtcSetMode (crtc, mode, RR_Rotate_0, 0, 0);
+    }
+    else
+    {
+	if (intel_crtc->dpms_mode != DPMSModeOn)
+	    crtc->funcs->dpms (crtc, DPMSModeOn);
+
+	/* Add this output to the crtc */
+	output->funcs->mode_set (output, &crtc->mode, &crtc->mode);
+	output->funcs->commit (output);
+    }
+
+    return crtc;
 }
 
 void
-i830ReleaseLoadDetectPipe(xf86OutputPtr output)
+i830ReleaseLoadDetectPipe(xf86OutputPtr output, int dpms_mode)
 {
     ScrnInfoPtr		    pScrn = output->scrn;
     I830OutputPrivatePtr    intel_output = output->driver_private;
+    xf86CrtcPtr		    crtc = output->crtc;
     
     if (intel_output->load_detect_temp) 
     {
-	xf86CrtcPtr crtc = output->crtc;
 	output->crtc = NULL;
 	intel_output->load_detect_temp = FALSE;
 	crtc->enabled = xf86CrtcInUse (crtc);
 	xf86DisableUnusedFunctions(pScrn);
     }
+    /*
+     * Switch crtc and output back off if necessary
+     */
+    if (crtc->enabled && dpms_mode != DPMSModeOn)
+    {
+	if (output->crtc == crtc)
+	    output->funcs->dpms (output, dpms_mode);
+	crtc->funcs->dpms (crtc, dpms_mode);
+    }
 }
 
 /* Returns the clock of the currently programmed mode of the given pipe. */
@@ -1623,6 +1683,7 @@ i830_crtc_init(ScrnInfoPtr pScrn, int pi
 
     intel_crtc = xnfcalloc (sizeof (I830CrtcPrivateRec), 1);
     intel_crtc->pipe = pipe;
+    intel_crtc->dpms_mode = DPMSModeOff;
 
     /* Initialize the LUTs for when we turn on the CRTC. */
     for (i = 0; i < 256; i++) {
diff --git a/src/i830_display.h b/src/i830_display.h
index 07dfe93..1eeb7f1 100644
--- a/src/i830_display.h
+++ b/src/i830_display.h
@@ -32,8 +32,8 @@ void i830PipeSetBase(xf86CrtcPtr crtc, i
 void i830WaitForVblank(ScrnInfoPtr pScrn);
 void i830DescribeOutputConfiguration(ScrnInfoPtr pScrn);
 
-xf86CrtcPtr i830GetLoadDetectPipe(xf86OutputPtr output);
-void i830ReleaseLoadDetectPipe(xf86OutputPtr output);
+xf86CrtcPtr i830GetLoadDetectPipe(xf86OutputPtr output, DisplayModePtr mode, int *dpms_mode);
+void i830ReleaseLoadDetectPipe(xf86OutputPtr output, int dpms_mode);
 void i830_crtc_init(ScrnInfoPtr pScrn, int pipe);
 void i830_crtc_load_lut(xf86CrtcPtr crtc);
 DisplayModePtr i830_crtc_mode_get(ScrnInfoPtr pScrn, xf86CrtcPtr crtc);
diff --git a/src/i830_tv.c b/src/i830_tv.c
index 1c818ba..8337d86 100644
--- a/src/i830_tv.c
+++ b/src/i830_tv.c
@@ -1353,24 +1353,15 @@ i830_tv_detect(xf86OutputPtr output)
     DisplayModeRec	    mode;
     I830OutputPrivatePtr    intel_output = output->driver_private;
     struct i830_tv_priv	    *dev_priv = intel_output->dev_priv;
+    int			    dpms_mode;
 
-    crtc = i830GetLoadDetectPipe (output);
+    mode = reported_modes[0];
+    xf86SetModeCrtc (&mode, INTERLACE_HALVE_V);
+    crtc = i830GetLoadDetectPipe (output, &mode, &dpms_mode);
     if (crtc)
     {
-	if (!crtc->enabled)
-        {
-            /* we only need the pixel clock set correctly here */
-            mode = reported_modes[0];
-            xf86SetModeCrtc (&mode, INTERLACE_HALVE_V);
-	    crtc->funcs->mode_set(crtc, &mode, &mode, 0, 0);
-        }
-	else if (intel_output->load_detect_temp)
-	{
-	    output->funcs->mode_set (output, &crtc->mode, &crtc->mode);
-	    output->funcs->commit (output);
-	}
         i830_tv_detect_type (crtc, output);
-        i830ReleaseLoadDetectPipe (output);
+        i830ReleaseLoadDetectPipe (output, dpms_mode);
     }
 
     switch (dev_priv->type) {
diff-tree 6f18300aed1340348c6d395f326061b5315be643 (from 04130ac6b705aa49161fb6dae83ad0bdd76e89d9)
Author: Keith Packard <keithp at neko.keithp.com>
Date:   Mon Jul 9 21:29:55 2007 -0700

    Eliminate bogus (and harmful) blanking adjustment for load detect.
    
    Instead of always adding blanking to mode lines, use the FORCE_BORDER option
    on i9xx hardware where it works, and dynamically add a bit of border if
    necessary on i8xx hardware to make load detection work. This may cause
    flashing when a usable crtc is not otherwise idle when load detection is
    requested.

diff --git a/src/i830_crt.c b/src/i830_crt.c
index 6d70f39..1900dfb 100644
--- a/src/i830_crt.c
+++ b/src/i830_crt.c
@@ -209,10 +209,8 @@ i830_crt_detect_load (xf86CrtcPtr	    cr
     CARD32		    dsl;
     CARD8		    st00;
     int			    bclrpat_reg, pipeconf_reg, pipe_dsl_reg;
-    int			    vtotal_reg;
-    int			    vblank_reg;
+    int			    vtotal_reg, vblank_reg, vsync_reg;
     int			    pipe = i830_crtc->pipe;
-    int			    count, detect;
     Bool		    present;
 
     if (pipe == 0) 
@@ -220,6 +218,7 @@ i830_crt_detect_load (xf86CrtcPtr	    cr
 	bclrpat_reg = BCLRPAT_A;
 	vtotal_reg = VTOTAL_A;
 	vblank_reg = VBLANK_A;
+	vsync_reg = VSYNC_A;
 	pipeconf_reg = PIPEACONF;
 	pipe_dsl_reg = PIPEA_DSL;
     }
@@ -228,6 +227,7 @@ i830_crt_detect_load (xf86CrtcPtr	    cr
 	bclrpat_reg = BCLRPAT_B;
 	vtotal_reg = VTOTAL_B;
 	vblank_reg = VBLANK_B;
+	vsync_reg = VSYNC_B;
 	pipeconf_reg = PIPEBCONF;
 	pipe_dsl_reg = PIPEB_DSL;
     }
@@ -242,45 +242,78 @@ i830_crt_detect_load (xf86CrtcPtr	    cr
     vblank_start = (vblank & 0xfff) + 1;
     vblank_end = ((vblank >> 16) & 0xfff) + 1;
     
-    /* sample in the vertical border, selecting the larger one */
-    if (vblank_start - vactive >= vtotal - vblank_end)
-	vsample = (vblank_start + vactive) >> 1;
-    else
-	vsample = (vtotal + vblank_end) >> 1;
-
     /* Set the border color to purple. */
     OUTREG(bclrpat_reg, 0x500050);
     
-    /*
-     * Wait for the border to be displayed
-     */
-    while (INREG(pipe_dsl_reg) >= vactive)
-	;
-    while ((dsl = INREG(pipe_dsl_reg)) <= vsample)
-	;
-    /*
-     * Watch ST00 for an entire scanline
-     */
-    detect = 0;
-    count = 0;
-    do {
-	count++;
-	/* Read the ST00 VGA status register */
-	st00 = pI830->readStandard(pI830, 0x3c2);
-	if (st00 & (1 << 4))
-	    detect++;
-    } while ((INREG(pipe_dsl_reg) == dsl));
+    if (IS_I9XX (pI830))
+    {
+	CARD32	pipeconf = INREG(pipeconf_reg);
+	OUTREG(pipeconf_reg, pipeconf | PIPECONF_FORCE_BORDER);
+	
+	st00 = pI830->readStandard (pI830, 0x3c2);
+	present = (st00 & (1 << 4)) != 0;
+	OUTREG(pipeconf_reg, pipeconf);
+    }
+    else
+    {
+	Bool	restore_vblank = FALSE;
+	int	count, detect;
+
+	/*
+	 * If there isn't any border, add some.
+	 * Yes, this will flicker
+	 */
+	if (vblank_start <= vactive && vblank_end >= vtotal)
+	{
+	    CARD32  vsync = INREG(vsync_reg);
+	    CARD32  vsync_start = (vsync & 0xffff) + 1;
+
+	    vblank_start = vsync_start;
+	    OUTREG(vblank_reg, (vblank_start - 1) | ((vblank_end - 1) << 16));
+	    restore_vblank = TRUE;
+	}
+	
+	/* sample in the vertical border, selecting the larger one */
+	if (vblank_start - vactive >= vtotal - vblank_end)
+	    vsample = (vblank_start + vactive) >> 1;
+	else
+	    vsample = (vtotal + vblank_end) >> 1;
+
+	/*
+	 * Wait for the border to be displayed
+	 */
+	while (INREG(pipe_dsl_reg) >= vactive)
+	    ;
+	while ((dsl = INREG(pipe_dsl_reg)) <= vsample)
+	    ;
+	/*
+	 * Watch ST00 for an entire scanline
+	 */
+	detect = 0;
+	count = 0;
+	do {
+	    count++;
+	    /* Read the ST00 VGA status register */
+	    st00 = pI830->readStandard(pI830, 0x3c2);
+	    if (st00 & (1 << 4))
+		detect++;
+	} while ((INREG(pipe_dsl_reg) == dsl));
+	
+	/* restore vblank if necessary */
+	if (restore_vblank)
+	    OUTREG(vblank_reg, vblank);
+	/*
+	 * If more than 3/4 of the scanline detected a monitor,
+	 * then it is assumed to be present. This works even on i830,
+	 * where there isn't any way to force the border color across
+	 * the screen
+	 */
+	present = detect * 4 > count * 3;
+    }
 
     /* Restore previous settings */
     OUTREG(bclrpat_reg, save_bclrpat);
 
-    /*
-     * If more than 3/4 of the scanline detected a monitor,
-     * then it is assumed to be present. This works even on i830,
-     * where there isn't any way to force the border color across
-     * the screen
-     */
-    present = detect * 4 > count * 3;
     return present;
 }
 
@@ -352,10 +385,17 @@ i830_crt_detect(xf86OutputPtr output)
 	if (!crtc->enabled)
 	{
 	    xf86SetModeCrtc (&mode, INTERLACE_HALVE_V);
+	    /*
+	     * Give us some border at the bottom for load detection on i8xx
+	     */
+	    mode.CrtcVBlankStart = mode.CrtcVSyncStart;
+	    if (mode.CrtcVBlankEnd - mode.CrtcVBlankStart < 3)
+		mode.CrtcVBlankStart = mode.CrtcVBlankEnd - 3;
 	    xf86CrtcSetMode (crtc, &mode, RR_Rotate_0, 0, 0);
 	}
 	else if (intel_output->load_detect_temp)
 	{
+	    /* Add this output to the crtc */
 	    output->funcs->mode_set (output, &crtc->mode, &crtc->mode);
 	    output->funcs->commit (output);
 	}
diff --git a/src/i830_display.c b/src/i830_display.c
index f3b5c50..ff25b29 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -1169,13 +1169,6 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, Dis
     OUTREG(vtot_reg, (adjusted_mode->CrtcVDisplay - 1) |
 	((adjusted_mode->CrtcVTotal - 1) << 16));
     
-    /*
-     * Give us some border at the bottom for load detection
-     */
-    adjusted_mode->CrtcVBlankStart = adjusted_mode->CrtcVSyncStart;
-    if (adjusted_mode->CrtcVBlankEnd - adjusted_mode->CrtcVBlankStart < 3)
-	adjusted_mode->CrtcVBlankStart = adjusted_mode->CrtcVBlankEnd - 3;
-    
     OUTREG(vblank_reg, (adjusted_mode->CrtcVBlankStart - 1) |
 	((adjusted_mode->CrtcVBlankEnd - 1) << 16));
     OUTREG(vsync_reg, (adjusted_mode->CrtcVSyncStart - 1) |
@@ -1437,25 +1430,36 @@ i830GetLoadDetectPipe(xf86OutputPtr outp
     ScrnInfoPtr		    pScrn = output->scrn;
     xf86CrtcConfigPtr	    xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
     I830OutputPrivatePtr    intel_output = output->driver_private;
-    xf86CrtcPtr	    crtc;
+    xf86CrtcPtr		    supported_crtc =NULL;
+    xf86CrtcPtr		    detect_crtc = NULL;
     int			    i;
 
     if (output->crtc) 
 	return output->crtc;
 
     for (i = 0; i < xf86_config->num_crtc; i++)
-	if (output->possible_crtcs & (1 << i))
+    {
+	xf86CrtcPtr crtc;
+	if (!(output->possible_crtcs & (1 << i)))
+	    continue;
+	crtc = xf86_config->crtc[i];
+	if (!crtc->enabled)
+	{
+	    detect_crtc = crtc;
 	    break;
-
-    if (i == xf86_config->num_crtc)
+	}
+	if (!supported_crtc)
+	    supported_crtc = crtc;
+    }
+    if (!detect_crtc)
+	detect_crtc = supported_crtc;
+    if (!detect_crtc)
 	return NULL;
 
-    crtc = xf86_config->crtc[i];
-
-    output->crtc = crtc;
+    output->crtc = detect_crtc;
     intel_output->load_detect_temp = TRUE;
 
-    return crtc;
+    return detect_crtc;
 }
 
 void
diff-tree 04130ac6b705aa49161fb6dae83ad0bdd76e89d9 (from 88f8b688e2316ae4a1f7485f0010ce90de54783a)
Author: Wang Zhenyu <zhenyu.z.wang at intel.com>
Date:   Wed Jul 11 11:42:56 2007 +0800

    Fix i915 rendering for tiled buffer
    
    Make it to check fence register for dest buffer.

diff --git a/src/i915_render.c b/src/i915_render.c
index 2148883..9d5bc0a 100644
--- a/src/i915_render.c
+++ b/src/i915_render.c
@@ -373,12 +373,9 @@ i915_prepare_composite(int op, PicturePt
 	CARD32 ss2;
 
 	BEGIN_LP_RING(16);
-	/* color buffer
-	 * XXX: Need to add USE_FENCE if we ever tile the X Server's pixmaps or
-	 * visible screen.
-	 */
 	OUT_RING(_3DSTATE_BUF_INFO_CMD);
-	OUT_RING(BUF_3D_ID_COLOR_BACK| BUF_3D_PITCH(dst_pitch));
+	OUT_RING(BUF_3D_ID_COLOR_BACK| BUF_3D_USE_FENCE|
+		BUF_3D_PITCH(dst_pitch));
 	OUT_RING(BUF_3D_ADDR(dst_offset));
 
 	OUT_RING(_3DSTATE_DST_BUF_VARS_CMD);
diff-tree 88f8b688e2316ae4a1f7485f0010ce90de54783a (from bf831117b4659cc4f2774098dee938505f780a9b)
Author: Eric Anholt <eric at anholt.net>
Date:   Mon Jul 9 12:56:13 2007 -0700

    Fix some physical address handling for >4GB addresses.
    
    The upper bits would have been inappropriately dropped on G33-class hardware,
    and on G965-class hardware in a 32-bit environment.  The only use of physical
    addresses on these should be for FBC, though, and FBC requires addresses
    below 4GB.  This is unresolved.

diff --git a/src/i830.h b/src/i830.h
index 8b6c5e6..409057c 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -134,7 +134,7 @@ struct _i830_memory {
      * Physical (or more properly, bus) address of the allocation.
      * Only set if requested during allocation.
      */
-    unsigned long bus_addr;
+    uint64_t bus_addr;
     /** AGP memory handle */
     int key;
     /**
@@ -235,7 +235,7 @@ typedef struct _I830CrtcPrivateRec {
     /* Physical or virtual addresses of the cursor for setting in the cursor
      * registers.
      */
-    unsigned long cursor_addr;
+    uint64_t cursor_addr;
     unsigned long cursor_argb_addr;
     Bool	cursor_is_argb;
 } I830CrtcPrivateRec, *I830CrtcPrivatePtr;
diff --git a/src/i830_memory.c b/src/i830_memory.c
index a589738..b38a5df 100644
--- a/src/i830_memory.c
+++ b/src/i830_memory.c
@@ -319,9 +319,9 @@ i830_allocator_init(ScrnInfoPtr pScrn, u
  * physical address.
  *
  * \return physical address if successful.
- * \return (unsigned long)-1 if unsuccessful.
+ * \return (uint64_t)-1 if unsuccessful.
  */
-static unsigned long
+static uint64_t
 i830_get_gtt_physical(ScrnInfoPtr pScrn, unsigned long offset)
 {
     I830Ptr pI830 = I830PTR(pScrn);
@@ -334,8 +334,11 @@ i830_get_gtt_physical(ScrnInfoPtr pScrn,
     gttentry = INGTT(offset / 1024);
 
     /* Mask out these reserved bits on this hardware. */
-    if (!IS_I965G(pI830))
+    if (!IS_I9XX(pI830) || IS_I915G(pI830) || IS_I915GM(pI830) ||
+	IS_I945G(pI830) || IS_I945GM(pI830))
+    {
 	gttentry &= ~PTE_ADDRESS_MASK_HIGH;
+    }
 
     /* If it's not a mapping type we know, then bail. */
     if ((gttentry & PTE_MAPPING_TYPE_MASK) != PTE_MAPPING_TYPE_UNCACHED &&
@@ -346,19 +349,10 @@ i830_get_gtt_physical(ScrnInfoPtr pScrn,
 		   (unsigned int)(gttentry & PTE_MAPPING_TYPE_MASK));
 	return -1;
     }
-    /* If we can't represent the address with an unsigned long, bail. */
-    if (sizeof(unsigned long) == 4 &&
-	(gttentry & PTE_ADDRESS_MASK_HIGH) != 0)
-    {
-	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
-		   "High memory PTE (0x%08x) on 32-bit system\n",
-		   (unsigned int)gttentry);
-	return -1;
-    }
     assert((gttentry & PTE_VALID) != 0);
 
     return (gttentry & PTE_ADDRESS_MASK) |
-	(gttentry & PTE_ADDRESS_MASK_HIGH << (32 - 4));
+	((uint64_t)(gttentry & PTE_ADDRESS_MASK_HIGH) << (32 - 4));
 }
 
 /**
@@ -366,14 +360,15 @@ i830_get_gtt_physical(ScrnInfoPtr pScrn,
  * physical address.
  *
  * \return physical address if successful.
- * \return (unsigned long)-1 if unsuccessful.
+ * \return (uint64_t)-1 if unsuccessful.
  */
-static unsigned long
+static uint64_t
 i830_get_stolen_physical(ScrnInfoPtr pScrn, unsigned long offset,
 			 unsigned long size)
 {
     I830Ptr pI830 = I830PTR(pScrn);
-    unsigned long physical, scan;
+    uint64_t physical;
+    unsigned long scan;
 
     /* Check that the requested region is within stolen memory. */
     if (offset + size >= pI830->stolen_size)
@@ -387,11 +382,12 @@ i830_get_stolen_physical(ScrnInfoPtr pSc
      * contiguously.
      */
     for (scan = offset + 4096; scan < offset + size; scan += 4096) {
-	unsigned long scan_physical = i830_get_gtt_physical(pScrn, scan);
+	uint64_t scan_physical = i830_get_gtt_physical(pScrn, scan);
 
 	if ((scan - offset) != (scan_physical - physical)) {
 	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
-		       "Non-contiguous GTT entries: (%ld,%ld) vs (%ld,%ld)\n",
+		       "Non-contiguous GTT entries: (%ld,0x16%llx) vs "
+		       "(%ld,0x%16llx)\n",
 		       scan, scan_physical, offset, physical);
 	    return -1;
 	}
@@ -444,7 +440,7 @@ i830_allocate_aperture(ScrnInfoPtr pScrn
 	    mem->bus_addr = i830_get_stolen_physical(pScrn, mem->offset,
 						     mem->size);
 
-	    if (mem->bus_addr == ((unsigned long)-1)) {
+	    if (mem->bus_addr == ((uint64_t)-1)) {
 		/* Move the start of the allocation to just past the end of
 		 * stolen memory.
 		 */
@@ -498,11 +494,15 @@ i830_allocate_agp_memory(ScrnInfoPtr pSc
 
     size = mem->size - (mem->agp_offset - mem->offset);
 
-    if (flags & NEED_PHYSICAL_ADDR)
+    if (flags & NEED_PHYSICAL_ADDR) {
+	unsigned long agp_bus_addr;
+
 	mem->key = xf86AllocateGARTMemory(pScrn->scrnIndex, size, 2,
-					  &mem->bus_addr);
-    else
+					  &agp_bus_addr);
+	mem->bus_addr = agp_bus_addr;
+    } else {
 	mem->key = xf86AllocateGARTMemory(pScrn->scrnIndex, size, 0, NULL);
+    }
     if (mem->key == -1 || ((flags & NEED_PHYSICAL_ADDR) && mem->bus_addr == 0))
     {
 	return FALSE;
@@ -688,7 +688,8 @@ i830_describe_allocations(ScrnInfoPtr pS
 			   mem->size / 1024);
 	} else {
 	    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
-			   "%s0x%08lx-0x%08lx: %s (%ld kB, 0x%08lx physical)\n",
+			   "%s0x%08lx-0x%08lx: %s "
+			   "(%ld kB, 0x%16llx physical)\n",
 			   prefix,
 			   mem->offset, mem->end - 1, mem->name,
 			   mem->size / 1024, mem->bus_addr);
@@ -956,9 +957,13 @@ i830_allocate_cursor_buffers(ScrnInfoPtr
 	unsigned long cursor_offset_base = pI830->cursor_mem->offset;
 	unsigned long cursor_addr_base, offset = 0;
 
-	if (pI830->CursorNeedsPhysical)
-	    cursor_addr_base = pI830->cursor_mem->bus_addr;
-	else
+	if (pI830->CursorNeedsPhysical) {
+	    /* On any hardware that requires physical addresses for cursors,
+	     * the PTEs don't support memory above 4GB, so we can safely
+	     * ignore the top 32 bits of cursor_mem->bus_addr.
+	     */
+	    cursor_addr_base = (unsigned long)pI830->cursor_mem->bus_addr;
+	} else
 	    cursor_addr_base = pI830->cursor_mem->offset;
 
 	/* Set up the offsets for our cursors in each CRTC. */
diff-tree bf831117b4659cc4f2774098dee938505f780a9b (from b426866fe1be2ad3861559beff69186379a6afad)
Author: Jesse Barnes <jbarnes at hobbes.virtuousgeek.org>
Date:   Sat Jul 7 10:15:32 2007 -0700

    FBC fixes:
      - allow FBC and Tiling to be forced off if configured to do so
      - only touch FBC registers if pI830->fb_compression is true

diff --git a/src/i830_display.c b/src/i830_display.c
index 853f4e4..f3b5c50 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -747,7 +747,7 @@ i830_disable_fb_compression(xf86CrtcPtr 
     ScrnInfoPtr pScrn = crtc->scrn;
     I830Ptr pI830 = I830PTR(pScrn);
     uint32_t fbc_ctl;
-    char pipe = (INREG(FBC_CONTROL2) & 1) ? 'b' : 'a';;
+    char pipe = (INREG(FBC_CONTROL2) & 1) ? 'b' : 'a';
 
     /* Disable compression */
     fbc_ctl = INREG(FBC_CONTROL);
@@ -764,7 +764,8 @@ static void
 i830_crtc_prepare (xf86CrtcPtr crtc)
 {
     /* Temporarily turn off FB compression during modeset */
-    i830_disable_fb_compression(crtc);
+    if (i830_use_fb_compression(crtc))
+        i830_disable_fb_compression(crtc);
     crtc->funcs->dpms (crtc, DPMSModeOff);
 }
 
diff --git a/src/i830_driver.c b/src/i830_driver.c
index dcbed22..51a17f0 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -1753,10 +1753,12 @@ SaveHWState(ScrnInfoPtr pScrn)
    vgaRegPtr vgaReg = &hwp->SavedReg;
    int i;
 
-   pI830->saveFBC_CFB_BASE = INREG(FBC_CFB_BASE);
-   pI830->saveFBC_LL_BASE = INREG(FBC_LL_BASE);
-   pI830->saveFBC_CONTROL2 = INREG(FBC_CONTROL2);
-   pI830->saveFBC_CONTROL = INREG(FBC_CONTROL);
+   if (pI830->fb_compression) {
+       pI830->saveFBC_CFB_BASE = INREG(FBC_CFB_BASE);
+       pI830->saveFBC_LL_BASE = INREG(FBC_LL_BASE);
+       pI830->saveFBC_CONTROL2 = INREG(FBC_CONTROL2);
+       pI830->saveFBC_CONTROL = INREG(FBC_CONTROL);
+   }
 
    /* Save video mode information for native mode-setting. */
    pI830->saveDSPACNTR = INREG(DSPACNTR);
@@ -1982,10 +1984,12 @@ RestoreHWState(ScrnInfoPtr pScrn)
    OUTREG(SWF31, pI830->saveSWF[15]);
    OUTREG(SWF32, pI830->saveSWF[16]);
 
-   OUTREG(FBC_CFB_BASE, pI830->saveFBC_CFB_BASE);
-   OUTREG(FBC_LL_BASE, pI830->saveFBC_LL_BASE);
-   OUTREG(FBC_CONTROL2, pI830->saveFBC_CONTROL2);
-   OUTREG(FBC_CONTROL, pI830->saveFBC_CONTROL);
+   if (pI830->fb_compression) {
+       OUTREG(FBC_CFB_BASE, pI830->saveFBC_CFB_BASE);
+       OUTREG(FBC_LL_BASE, pI830->saveFBC_LL_BASE);
+       OUTREG(FBC_CONTROL2, pI830->saveFBC_CONTROL2);
+       OUTREG(FBC_CONTROL, pI830->saveFBC_CONTROL);
+   }
 
    vgaHWRestore(pScrn, vgaReg, VGA_SR_FONTS);
    vgaHWLock(hwp);
@@ -2320,14 +2324,19 @@ I830ScreenInit(int scrnIndex, ScreenPtr 
       pI830->CacheLines = -1;
    }
 
-   /* Enable tiling by default where supported or if the user forced it on */
+   /* Enable tiling by default where supported */
    if (i830_tiling_supported(pI830))
        pI830->tiling = TRUE;
    else
        pI830->tiling = FALSE;
 
-   if (xf86ReturnOptValBool(pI830->Options, OPTION_TILING, FALSE))
-       pI830->tiling = TRUE;
+   /* Allow user override if they set a value */
+   if (xf86IsOptionSet(pI830->Options, OPTION_TILING)) {
+       if (xf86ReturnOptValBool(pI830->Options, OPTION_TILING, FALSE))
+	   pI830->tiling = TRUE;
+       else
+	   pI830->tiling = FALSE;
+   }
 
    /* Enable FB compression if possible */
    if (i830_fb_compression_supported(pI830))
@@ -2335,8 +2344,13 @@ I830ScreenInit(int scrnIndex, ScreenPtr 
    else
        pI830->fb_compression = FALSE;
 
-   if (xf86ReturnOptValBool(pI830->Options, OPTION_FBC, FALSE))
-       pI830->fb_compression = TRUE;
+   /* Again, allow user override if set */
+   if (xf86IsOptionSet(pI830->Options, OPTION_FBC)) {
+       if (xf86ReturnOptValBool(pI830->Options, OPTION_FBC, FALSE))
+	   pI830->fb_compression = TRUE;
+       else
+	   pI830->fb_compression = FALSE;
+   }
 
    if (pI830->fb_compression) {
        xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Framebuffer compression enabled, "
diff-tree b426866fe1be2ad3861559beff69186379a6afad (from 377c58373daa6bef5d37ead2b6f9a769a905b6fa)
Author: Jesse Barnes <jesse.barnes at intel.com>
Date:   Fri Jul 6 20:48:40 2007 -0700

    Fix manpage to reflect default behavior.

diff --git a/man/intel.man b/man/intel.man
index 8bd3f28..33dc319 100644
--- a/man/intel.man
+++ b/man/intel.man
@@ -80,12 +80,12 @@ This option controls whether the framebu
 If possible, the front buffer will be allocated in a tiled format and compressed
 periodically to save memory bandwidth and power.
 This option is only available on mobile chipsets.
-Default: disabled.
+Default: enabled on supported configurations.
 .TP
 .BI "Option \*qTiling\*q \*q" boolean \*q
 This option controls whether memory buffers are allocated in tiled mode.  In
 many cases (especially for complex rendering), tiling can improve performance.
-Default: enabled.
+Default: enabled on supported configurations.
 .TP
 .BI "Option \*qDRI\*q \*q" boolean \*q
 Disable or enable DRI support.
diff-tree 377c58373daa6bef5d37ead2b6f9a769a905b6fa (from 9c0388dc8d4c6495fae21af6da644b34e20173d1)
Author: Jesse Barnes <jesse.barnes at intel.com>
Date:   Fri Jul 6 20:39:19 2007 -0700

    Fix naming of FBC plane enable bits (mistakenly called them pipes earlier).

diff --git a/src/i830_display.c b/src/i830_display.c
index dc52c0b..853f4e4 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -661,13 +661,13 @@ i830_use_fb_compression(xf86CrtcPtr crtc
     I830Ptr pI830 = I830PTR(pScrn);
     I830CrtcPrivatePtr	intel_crtc = crtc->driver_private;
     int pipe = intel_crtc->pipe;
-    int plane = (pipe == 0 ? FBC_CTL_PIPEA : FBC_CTL_PIPEB);
+    int plane = (pipe == 0 ? FBC_CTL_PLANEA : FBC_CTL_PLANEB);
 
     if (!pI830->fb_compression)
 	return FALSE;
 
-    /* Pre-965 only supports plane A, which is synonymous with pipe A for now */
-    if (!IS_I965GM(pI830) && plane != FBC_CTL_PIPEA)
+    /* Pre-965 only supports plane A */
+    if (!IS_I965GM(pI830) && plane != FBC_CTL_PLANEA)
 	return FALSE;
 
     /* Need 15, 16, or 32 (w/alpha) pixel format */
@@ -704,7 +704,7 @@ i830_enable_fb_compression(xf86CrtcPtr c
     uint32_t fbc_ctl;
     unsigned long compressed_stride;
     int pipe = intel_crtc->pipe;
-    int plane = (pipe == 0 ? FBC_CTL_PIPEA : FBC_CTL_PIPEB);
+    int plane = (pipe == 0 ? FBC_CTL_PLANEA : FBC_CTL_PLANEB);
     unsigned long uncompressed_stride = pScrn->displayWidth * pI830->cpp;
     unsigned long interval = 1000;
 
diff --git a/src/i830_reg.h b/src/i830_reg.h
index d1670c3..8a2a98a 100644
--- a/src/i830_reg.h
+++ b/src/i830_reg.h
@@ -47,8 +47,8 @@
 #define   FBC_STAT_CURRENT_LINE	(1<<0)
 #define FBC_CONTROL2		0x03214
 #define   FBC_CTL_CPU_FENCE	(1<<1)
-#define   FBC_CTL_PIPEA		(0<<0)
-#define   FBC_CTL_PIPEB		(1<<0)
+#define   FBC_CTL_PLANEA	(0<<0)
+#define   FBC_CTL_PLANEB	(1<<0)
 
 #define FBC_LL_SIZE		(1536)
 #define FBC_LL_PAD		(32)
diff-tree 9c0388dc8d4c6495fae21af6da644b34e20173d1 (from cecbc71fdc9af832cef23427696f6f654f7d6104)
Author: Jesse Barnes <jesse.barnes at intel.com>
Date:   Fri Jul 6 20:38:41 2007 -0700

    Update man page with current behavior.

diff --git a/man/intel.man b/man/intel.man
index 3173bc7..8bd3f28 100644
--- a/man/intel.man
+++ b/man/intel.man
@@ -75,12 +75,17 @@ driver attempts to allocate space for at
 HD-sized XV video.  The default used for a specific configuration can be found
 by examining the __xservername__ log file.
 .TP
-.BI "Option \*qFrameBufferCompression\*q \*q" boolean \*q
+.BI "Option \*qFramebufferCompression\*q \*q" boolean \*q
 This option controls whether the framebuffer compression feature is enabled.
 If possible, the front buffer will be allocated in a tiled format and compressed
 periodically to save memory bandwidth and power.
-.TP
 This option is only available on mobile chipsets.
+Default: disabled.
+.TP
+.BI "Option \*qTiling\*q \*q" boolean \*q
+This option controls whether memory buffers are allocated in tiled mode.  In
+many cases (especially for complex rendering), tiling can improve performance.
+Default: enabled.
 .TP
 .BI "Option \*qDRI\*q \*q" boolean \*q
 Disable or enable DRI support.
diff-tree cecbc71fdc9af832cef23427696f6f654f7d6104 (from 4359df9419d2d02a2f9d9adc7f5a49ecf07ddd30)
Author: Jesse Barnes <jesse.barnes at intel.com>
Date:   Fri Jul 6 16:36:34 2007 -0700

    Fix debug output in fbc enable/disable routines.  Add logic to make sure fbc
    isn't enabled twice on two different pipes.

diff --git a/src/i830_display.c b/src/i830_display.c
index c79676d..dc52c0b 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -708,6 +708,14 @@ i830_enable_fb_compression(xf86CrtcPtr c
     unsigned long uncompressed_stride = pScrn->displayWidth * pI830->cpp;
     unsigned long interval = 1000;
 
+    if (INREG(FBC_CONTROL) & FBC_CTL_EN) {
+	char cur_pipe = (INREG(FBC_CONTROL2) & 1) ? 'b' : 'a';
+	xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "fbc already enabled on "
+		   "pipe %c, not enabling on pipe %c\n", cur_pipe, pipe ? 'b' :
+		   'a');
+	return;
+    }
+
     compressed_stride = pI830->compressed_front_buffer->size /
 	FBC_LL_SIZE;
 
@@ -730,7 +738,7 @@ i830_enable_fb_compression(xf86CrtcPtr c
     OUTREG(FBC_CONTROL, fbc_ctl);
 
     xf86DrvMsg(pScrn->scrnIndex, X_INFO, "fbc enabled on pipe %c\n", pipe ?
-	       "a" : "b");
+	       'b' : 'a');
 }
 
 static void
@@ -739,6 +747,7 @@ i830_disable_fb_compression(xf86CrtcPtr 
     ScrnInfoPtr pScrn = crtc->scrn;
     I830Ptr pI830 = I830PTR(pScrn);
     uint32_t fbc_ctl;
+    char pipe = (INREG(FBC_CONTROL2) & 1) ? 'b' : 'a';;
 
     /* Disable compression */
     fbc_ctl = INREG(FBC_CONTROL);
@@ -748,7 +757,7 @@ i830_disable_fb_compression(xf86CrtcPtr 
     /* Wait for compressing bit to clear */
     while (INREG(FBC_STATUS) & FBC_STAT_COMPRESSING)
 	; /* nothing */
-    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "fbc disabled\n");
+    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "fbc disabled on pipe %c\n", pipe);
 }
 
 static void
diff-tree 4359df9419d2d02a2f9d9adc7f5a49ecf07ddd30 (from ca593a5219549df94a6d234ebbcf9e7c44723c9b)
Author: Jesse Barnes <jesse.barnes at intel.com>
Date:   Fri Jul 6 16:17:45 2007 -0700

    Fix tiling and fb compression defaults for 965 (not yet fully supported).

diff --git a/src/i830.h b/src/i830.h
index 4748b81..8b6c5e6 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -727,6 +727,8 @@ static inline int i830_tiling_supported(
 
 static inline int i830_fb_compression_supported(I830Ptr pI830)
 {
+    if (!i830_tiling_supported(pI830))
+	return FALSE;
     if (!IS_MOBILE(pI830))
 	return FALSE;
     if (IS_I810(pI830) || IS_I815(pI830) || IS_I830(pI830))
diff --git a/src/i830_driver.c b/src/i830_driver.c
index a380971..dcbed22 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -2334,9 +2334,9 @@ I830ScreenInit(int scrnIndex, ScreenPtr 
        pI830->fb_compression = TRUE;
    else
        pI830->fb_compression = FALSE;
-   /* ... but disable if requested */
-   if (!xf86ReturnOptValBool(pI830->Options, OPTION_FBC, TRUE))
-       pI830->fb_compression = FALSE;
+
+   if (xf86ReturnOptValBool(pI830->Options, OPTION_FBC, FALSE))
+       pI830->fb_compression = TRUE;
 
    if (pI830->fb_compression) {
        xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Framebuffer compression enabled, "
diff-tree ca593a5219549df94a6d234ebbcf9e7c44723c9b (from 8798ef11321ee6957919279076758d47ad956cf3)
Author: Jesse Barnes <jesse.barnes at intel.com>
Date:   Fri Jul 6 16:10:52 2007 -0700

    FBC and tiling changes
      - change framebuffer option name to "FramebufferCompression"
      - add new "Tiling" option (controls all tiling, not just front buffer)
      - add debug message to fb compression enable/disable routines
      - update man page with new options

diff --git a/src/i830.h b/src/i830.h
index 1358e3e..4748b81 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -343,7 +343,7 @@ typedef struct _I830Rec {
    Bool NeedRingBufferLow;
    Bool allowPageFlip;
    Bool TripleBuffer;
-   Bool disableTiling;
+   Bool tiling;
    Bool fb_compression;
 
    int backPitch;
@@ -718,6 +718,22 @@ i830_get_transformed_coordinates(int x, 
 
 void i830_enter_render(ScrnInfoPtr);
 
+static inline int i830_tiling_supported(I830Ptr pI830)
+{
+    if (IS_I965G(pI830))
+	return FALSE;
+    return TRUE;
+}
+
+static inline int i830_fb_compression_supported(I830Ptr pI830)
+{
+    if (!IS_MOBILE(pI830))
+	return FALSE;
+    if (IS_I810(pI830) || IS_I815(pI830) || IS_I830(pI830))
+	return FALSE;
+    return TRUE;
+}
+
 extern const int I830PatternROP[16];
 extern const int I830CopyROP[16];
 
diff --git a/src/i830_display.c b/src/i830_display.c
index 0befef9..c79676d 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -728,6 +728,9 @@ i830_enable_fb_compression(xf86CrtcPtr c
     fbc_ctl |= (compressed_stride & 0xff) << FBC_CTL_STRIDE_SHIFT;
     fbc_ctl |= (interval & 0x2fff) << FBC_CTL_INTERVAL_SHIFT;
     OUTREG(FBC_CONTROL, fbc_ctl);
+
+    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "fbc enabled on pipe %c\n", pipe ?
+	       "a" : "b");
 }
 
 static void
@@ -745,6 +748,7 @@ i830_disable_fb_compression(xf86CrtcPtr 
     /* Wait for compressing bit to clear */
     while (INREG(FBC_STATUS) & FBC_STAT_COMPRESSING)
 	; /* nothing */
+    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "fbc disabled\n");
 }
 
 static void
diff --git a/src/i830_driver.c b/src/i830_driver.c
index 5f934fe..a380971 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -287,6 +287,7 @@ typedef enum {
    OPTION_CHECKDEVICES,
    OPTION_MODEDEBUG,
    OPTION_FBC,
+   OPTION_TILING,
 #ifdef XF86DRI_MM
    OPTION_INTELTEXPOOL,
    OPTION_INTELMMSIZE,
@@ -308,7 +309,8 @@ static OptionInfoRec I830Options[] = {
    {OPTION_VIDEO_KEY,	"VideoKey",	OPTV_INTEGER,	{0},	FALSE},
    {OPTION_CHECKDEVICES, "CheckDevices",OPTV_BOOLEAN,	{0},	FALSE},
    {OPTION_MODEDEBUG,	"ModeDebug",	OPTV_BOOLEAN,	{0},	FALSE},
-   {OPTION_FBC,		"FrameBufferCompression", OPTV_BOOLEAN, {0}, FALSE},
+   {OPTION_FBC,		"FramebufferCompression", OPTV_BOOLEAN, {0}, TRUE},
+   {OPTION_TILING,	"Tiling",	OPTV_BOOLEAN,	{0},	TRUE},
 #ifdef XF86DRI_MM
    {OPTION_INTELTEXPOOL,"Legacy3D",     OPTV_BOOLEAN,	{0},	FALSE},
    {OPTION_INTELMMSIZE, "AperTexSize",  OPTV_INTEGER,	{0},	FALSE},
@@ -2318,12 +2320,34 @@ I830ScreenInit(int scrnIndex, ScreenPtr 
       pI830->CacheLines = -1;
    }
 
-   if (xf86ReturnOptValBool(pI830->Options, OPTION_FBC, FALSE))
+   /* Enable tiling by default where supported or if the user forced it on */
+   if (i830_tiling_supported(pI830))
+       pI830->tiling = TRUE;
+   else
+       pI830->tiling = FALSE;
+
+   if (xf86ReturnOptValBool(pI830->Options, OPTION_TILING, FALSE))
+       pI830->tiling = TRUE;
+
+   /* Enable FB compression if possible */
+   if (i830_fb_compression_supported(pI830))
        pI830->fb_compression = TRUE;
    else
        pI830->fb_compression = FALSE;
+   /* ... but disable if requested */
+   if (!xf86ReturnOptValBool(pI830->Options, OPTION_FBC, TRUE))
+       pI830->fb_compression = FALSE;
 
-   pI830->disableTiling = FALSE;
+   if (pI830->fb_compression) {
+       xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Framebuffer compression enabled, "
+		  "forcing tiling on.\n");
+       pI830->tiling = TRUE;
+   }
+
+   xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Framebuffer compression %sabled\n",
+	      pI830->fb_compression ? "en" : "dis");
+   xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Tiling %sabled\n", pI830->tiling ?
+	      "en" : "dis");
 
    if (I830IsPrimary(pScrn)) {
       /* Alloc our pointers for the primary head */
@@ -2413,7 +2437,6 @@ I830ScreenInit(int scrnIndex, ScreenPtr 
        * 3: untiled, small
        */
 
-      pI830->disableTiling = FALSE;
 #ifdef XF86DRI_MM
       savedMMSize = pI830->mmSize;
 #define MM_TURNS 4
@@ -2426,7 +2449,7 @@ I830ScreenInit(int scrnIndex, ScreenPtr 
 
 	 if (i >= MM_TURNS/2) {
 	    /* For further allocations, disable tiling */
-	    pI830->disableTiling = TRUE;
+	    pI830->tiling = FALSE;
 	    pScrn->displayWidth = savedDisplayWidth;
 	    if (pI830->allowPageFlip)
 	       xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
@@ -2481,9 +2504,8 @@ I830ScreenInit(int scrnIndex, ScreenPtr 
 #endif
 	 pI830->directRenderingDisabled = TRUE;
       }
-   } else
+   }
 #endif
-      pI830->disableTiling = TRUE; /* no DRI - so disableTiling */
 
    if (!allocation_done) {
       if (!i830_allocate_2d_memory(pScrn)) {
@@ -2501,7 +2523,7 @@ I830ScreenInit(int scrnIndex, ScreenPtr 
    if (!IS_I965G(pI830) && pScrn->displayWidth > 2048) {
       xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
 		 "Cannot support DRI with frame buffer width > 2048.\n");
-      pI830->disableTiling = TRUE;
+      pI830->tiling = FALSE;
       pI830->directRenderingDisabled = TRUE;
    }
 
diff --git a/src/i830_memory.c b/src/i830_memory.c
index 7134600..a589738 100644
--- a/src/i830_memory.c
+++ b/src/i830_memory.c
@@ -903,9 +903,7 @@ i830_allocate_framebuffer(ScrnInfoPtr pS
     name = secondary ? "secondary front buffer" : "front buffer";
 
     /* Attempt to allocate it tiled first if we have page flipping on. */
-    if ((!pI830->disableTiling && pI830->allowPageFlip &&
-	 IsTileable(pScrn, pitch)) || pI830->fb_compression)
-    {
+    if (pI830->tiling && IsTileable(pScrn, pitch)) {
 	/* XXX: probably not the case on 965 */
 	if (IS_I9XX(pI830))
 	    align = MB(1);
@@ -1253,7 +1251,7 @@ i830_allocate_backbuffer(ScrnInfoPtr pSc
 	height = pScrn->virtualX;
 
     /* Try to allocate on the best tile-friendly boundaries. */
-    if (!pI830->disableTiling && IsTileable(pScrn, pitch))
+    if (pI830->tiling && IsTileable(pScrn, pitch))
     {
 	size = ROUND_TO_PAGE(pitch * ALIGN(height, 16));
 	*buffer = i830_allocate_memory_tiled(pScrn, name, size, pitch,
@@ -1294,7 +1292,7 @@ i830_allocate_depthbuffer(ScrnInfoPtr pS
 	height = pScrn->virtualX;
 
     /* First try allocating it tiled */
-    if (!pI830->disableTiling && IsTileable(pScrn, pitch))
+    if (pI830->tiling && IsTileable(pScrn, pitch))
     {
 	enum tile_format tile_format;
 
diff --git a/src/i915_render.c b/src/i915_render.c
index b2dacfe..2148883 100644
--- a/src/i915_render.c
+++ b/src/i915_render.c
@@ -287,7 +287,7 @@ i915_texture_setup(PicturePtr pPict, Pix
     pI830->mapstate[unit * 3 + 1] = format |
 	((pPix->drawable.height - 1) << MS3_HEIGHT_SHIFT) |
 	((pPix->drawable.width - 1) << MS3_WIDTH_SHIFT);
-    if (!pI830->disableTiling)
+    if (pI830->tiling)
 	pI830->samplerstate[unit * 3 + 1] |= MS3_USE_FENCE_REGS;
     pI830->mapstate[unit * 3 + 2] = ((pitch / 4) - 1) << MS4_PITCH_SHIFT;
 
diff --git a/src/i915_video.c b/src/i915_video.c
index f1bf4cc..e116fe2 100644
--- a/src/i915_video.c
+++ b/src/i915_video.c
@@ -160,7 +160,7 @@ I915DisplayVideoTextured(ScrnInfoPtr pSc
       }
       ms3 |= (height - 1) << MS3_HEIGHT_SHIFT;
       ms3 |= (width - 1) << MS3_WIDTH_SHIFT;
-      if (!pI830->disableTiling)
+      if (pI830->tiling)
 	 ms3 |= MS3_USE_FENCE_REGS;
       OUT_RING(ms3);
       OUT_RING(((video_pitch / 4) - 1) << MS4_PITCH_SHIFT);
@@ -251,7 +251,7 @@ I915DisplayVideoTextured(ScrnInfoPtr pSc
       ms3 = MAPSURF_8BIT | MT_8BIT_I8;
       ms3 |= (height - 1) << MS3_HEIGHT_SHIFT;
       ms3 |= (width - 1) << MS3_WIDTH_SHIFT;
-      if (!pI830->disableTiling)
+      if (pI830->tiling)
 	 ms3 |= MS3_USE_FENCE_REGS;
       OUT_RING(ms3);
       OUT_RING(((video_pitch * 2 / 4) - 1) << MS4_PITCH_SHIFT);
@@ -260,7 +260,7 @@ I915DisplayVideoTextured(ScrnInfoPtr pSc
       ms3 = MAPSURF_8BIT | MT_8BIT_I8;
       ms3 |= (height / 2 - 1) << MS3_HEIGHT_SHIFT;
       ms3 |= (width / 2 - 1) << MS3_WIDTH_SHIFT;
-      if (!pI830->disableTiling)
+      if (pI830->tiling)
 	 ms3 |= MS3_USE_FENCE_REGS;
       OUT_RING(ms3);
       OUT_RING(((video_pitch / 4) - 1) << MS4_PITCH_SHIFT);
@@ -269,7 +269,7 @@ I915DisplayVideoTextured(ScrnInfoPtr pSc
       ms3 = MAPSURF_8BIT | MT_8BIT_I8;
       ms3 |= (height / 2 - 1) << MS3_HEIGHT_SHIFT;
       ms3 |= (width / 2 - 1) << MS3_WIDTH_SHIFT;
-      if (!pI830->disableTiling)
+      if (pI830->tiling)
 	 ms3 |= MS3_USE_FENCE_REGS;
       OUT_RING(ms3);
       OUT_RING(((video_pitch / 4) - 1) << MS4_PITCH_SHIFT);
diff-tree 8798ef11321ee6957919279076758d47ad956cf3 (from parents)
Merge: 8919b2292147add41a1c1c6e5e673257cb6c6c6e 3c552af65d28fafec1d09484a8914b690b961349
Author: Jesse Barnes <jbarnes at nietzche.virtuousgeek.org>
Date:   Thu Jul 5 12:21:31 2007 -0700

    Merge branch 'master' into fbc

diff-tree 8919b2292147add41a1c1c6e5e673257cb6c6c6e (from 407b124af8f7bb42abe4eecc87476c4c3e555cd0)
Author: Jesse Barnes <jbarnes at nietzche.virtuousgeek.org>
Date:   Thu Jul 5 12:21:06 2007 -0700

    Re-add tiling kludge, but only for 965.

diff --git a/src/i830_memory.c b/src/i830_memory.c
index 904476a..7134600 100644
--- a/src/i830_memory.c
+++ b/src/i830_memory.c
@@ -1450,6 +1450,11 @@ i830_set_fence(ScrnInfoPtr pScrn, int nr
     assert(tile_format != TILING_NONE);
 
     if (IS_I965G(pI830)) {
+        if (tile_format == TILING_XMAJOR)
+            pitch = 512;
+        else
+            pitch = 128;
+ 
 	if (nr < 0 || nr >= FENCE_NEW_NR) {
 	    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
 		       "i830_set_fence(): fence %d out of range\n",nr);
diff-tree 407b124af8f7bb42abe4eecc87476c4c3e555cd0 (from 7a87b9d2a2eb4d281dce67586756ff5653b2805a)
Author: Jesse Barnes <jbarnes at nietzche.virtuousgeek.org>
Date:   Thu Jul 5 11:31:34 2007 -0700

    Remove tiling kludge.  May need more fixes for 965.

diff --git a/src/i830_memory.c b/src/i830_memory.c
index f4271ef..904476a 100644
--- a/src/i830_memory.c
+++ b/src/i830_memory.c
@@ -1444,8 +1444,6 @@ i830_set_fence(ScrnInfoPtr pScrn, int nr
     CARD32 fence_mask = 0;
     unsigned int fence_pitch;
 
-    pitch = 512;
-
     DPRINTF(PFX, "i830_set_fence(): %d, 0x%08x, %d, %d kByte\n",
 	    nr, offset, pitch, size / 1024);
 
diff-tree 7a87b9d2a2eb4d281dce67586756ff5653b2805a (from fecf964534f5ba6d40480cb13adc89094946a51e)
Author: Jesse Barnes <jbarnes at nietzche.virtuousgeek.org>
Date:   Thu Jul 5 11:23:06 2007 -0700

    Revert discard alpha change, requires other fixes to work.

diff --git a/src/i830_display.c b/src/i830_display.c
index 6bfa7e6..db02402 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -1032,10 +1032,7 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, Dis
 	    dspcntr |= DISPPLANE_16BPP;
 	break;
     case 32:
-	if (pI830->fb_compression)
-	    dspcntr |= DISPPLANE_32BPP;
-	else
-	    dspcntr |= DISPPLANE_32BPP_NO_ALPHA;
+	dspcntr |= DISPPLANE_32BPP_NO_ALPHA;
 	break;
     default:
 	FatalError("unknown display bpp\n");
diff-tree fecf964534f5ba6d40480cb13adc89094946a51e (from 60ee7b6a91b2b8c447130c60cd8b19eb68119777)
Author: Jesse Barnes <jbarnes at nietzche.virtuousgeek.org>
Date:   Thu Jul 5 10:59:23 2007 -0700

    FBC fixes:
      - properly check several FBC enablement constraints
      - don't use alpha discard if FBC is in use

diff --git a/src/i830_display.c b/src/i830_display.c
index 1feb13b..6bfa7e6 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -654,6 +654,34 @@ i830_crtc_unlock (xf86CrtcPtr crtc)
 #endif
 }
 
+static Bool
+i830_use_fb_compression(xf86CrtcPtr crtc)
+{
+    ScrnInfoPtr pScrn = crtc->scrn;
+    I830Ptr pI830 = I830PTR(pScrn);
+    I830CrtcPrivatePtr	intel_crtc = crtc->driver_private;
+    int pipe = intel_crtc->pipe;
+    int plane = (pipe == 0 ? FBC_CTL_PIPEA : FBC_CTL_PIPEB);
+
+    if (!pI830->fb_compression)
+	return FALSE;
+
+    /* Pre-965 only supports plane A, which is synonymous with pipe A for now */
+    if (!IS_I965GM(pI830) && plane != FBC_CTL_PIPEA)
+	return FALSE;
+
+    /* Need 15, 16, or 32 (w/alpha) pixel format */
+    if (!(pScrn->bitsPerPixel == 16 || /* covers 15 bit mode as well */
+	  pScrn->bitsPerPixel == 32)) /* mode_set dtrt if fbc is in use */
+	return FALSE;
+
+    /*
+     * No checks for pixel multiply, incl. horizontal, or interlaced modes
+     * since they're currently unused.
+     */
+    return TRUE;
+}
+
 /*
  * Several restrictions:
  *   - DSP[AB]CNTR - no line duplication && no pixel multiplier
@@ -661,6 +689,9 @@ i830_crtc_unlock (xf86CrtcPtr crtc)
  *   - no alpha buffer discard
  *   - no dual wide display
  *   - progressive mode only (DSP[AB]CNTR)
+ *   - uncompressed fb is <= 2048 in width, 0 mod 8
+ *   - uncompressed fb is <= 1536 in height, 0 mod 2
+ *   - SR display watermarks must be equal between 16bpp and 32bpp?
  *
  * FIXME: verify above conditions are true
  */
@@ -719,20 +750,14 @@ i830_disable_fb_compression(xf86CrtcPtr 
 static void
 i830_crtc_prepare (xf86CrtcPtr crtc)
 {
-    ScrnInfoPtr pScrn = crtc->scrn;
-    I830Ptr pI830 = I830PTR(pScrn);
-    crtc->funcs->dpms (crtc, DPMSModeOff);
-
     /* Temporarily turn off FB compression during modeset */
-    if (pI830->fb_compression)
-	i830_disable_fb_compression(crtc);
+    i830_disable_fb_compression(crtc);
+    crtc->funcs->dpms (crtc, DPMSModeOff);
 }
 
 static void
 i830_crtc_commit (xf86CrtcPtr crtc)
 {
-    ScrnInfoPtr pScrn = crtc->scrn;
-    I830Ptr pI830 = I830PTR(pScrn);
     I830CrtcPrivatePtr	intel_crtc = crtc->driver_private;
     Bool		deactivate = FALSE;
 
@@ -748,7 +773,7 @@ i830_crtc_commit (xf86CrtcPtr crtc)
 	i830_pipe_a_require_deactivate (crtc->scrn);
 
     /* Reenable FB compression if possible */
-    if (pI830->fb_compression)
+    if (i830_use_fb_compression(crtc))
 	i830_enable_fb_compression(crtc);
 }
 
@@ -1007,7 +1032,10 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, Dis
 	    dspcntr |= DISPPLANE_16BPP;
 	break;
     case 32:
-	dspcntr |= DISPPLANE_32BPP_NO_ALPHA;
+	if (pI830->fb_compression)
+	    dspcntr |= DISPPLANE_32BPP;
+	else
+	    dspcntr |= DISPPLANE_32BPP_NO_ALPHA;
 	break;
     default:
 	FatalError("unknown display bpp\n");
diff-tree 60ee7b6a91b2b8c447130c60cd8b19eb68119777 (from f02036aedcd7866c567a6adc070eda3dad872105)
Author: Jesse Barnes <jbarnes at nietzche.virtuousgeek.org>
Date:   Tue Jul 3 14:20:34 2007 -0700

    Fixup line length buffer padding, add kludge for front buffer tile
    pitch.

diff --git a/src/i830_display.c b/src/i830_display.c
index 5b1d6ea..1feb13b 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -678,7 +678,7 @@ i830_enable_fb_compression(xf86CrtcPtr c
     unsigned long interval = 1000;
 
     compressed_stride = pI830->compressed_front_buffer->size /
-	FBC_COMPRESSED_LINES;
+	FBC_LL_SIZE;
 
     if (uncompressed_stride < compressed_stride)
 	compressed_stride = uncompressed_stride;
@@ -688,7 +688,7 @@ i830_enable_fb_compression(xf86CrtcPtr c
 
     /* Set it up... */
     OUTREG(FBC_CFB_BASE, pI830->compressed_front_buffer->bus_addr);
-    OUTREG(FBC_LL_BASE, pI830->compressed_ll_buffer->bus_addr);
+    OUTREG(FBC_LL_BASE, pI830->compressed_ll_buffer->bus_addr + FBC_LL_PAD);
     OUTREG(FBC_CONTROL2, FBC_CTL_CPU_FENCE | plane);
 
     /* enable it... */
diff --git a/src/i830_memory.c b/src/i830_memory.c
index 8703f2d..f4271ef 100644
--- a/src/i830_memory.c
+++ b/src/i830_memory.c
@@ -1052,8 +1052,7 @@ static void i830_setup_fb_compression(Sc
      */
     pI830->compressed_front_buffer =
 	i830_allocate_memory(pScrn, "compressed frame buffer",
-			     MB(6), KB(4),
-			     NEED_PHYSICAL_ADDR);
+			     MB(6), KB(4), NEED_PHYSICAL_ADDR);
 
     if (!pI830->compressed_front_buffer) {
 	pI830->fb_compression = FALSE;
@@ -1062,7 +1061,8 @@ static void i830_setup_fb_compression(Sc
 
     pI830->compressed_ll_buffer =
 	i830_allocate_memory(pScrn, "compressed ll buffer",
-			     1568, KB(4), NEED_PHYSICAL_ADDR);
+			     FBC_LL_SIZE + FBC_LL_PAD, KB(4),
+			     NEED_PHYSICAL_ADDR);
     if (!pI830->compressed_ll_buffer) {
 	i830_free_memory(pScrn, pI830->compressed_front_buffer);
 	pI830->fb_compression = FALSE;
@@ -1444,6 +1444,8 @@ i830_set_fence(ScrnInfoPtr pScrn, int nr
     CARD32 fence_mask = 0;
     unsigned int fence_pitch;
 
+    pitch = 512;
+
     DPRINTF(PFX, "i830_set_fence(): %d, 0x%08x, %d, %d kByte\n",
 	    nr, offset, pitch, size / 1024);
 
diff --git a/src/i830_reg.h b/src/i830_reg.h
index b5fa1b9..d1670c3 100644
--- a/src/i830_reg.h
+++ b/src/i830_reg.h
@@ -50,7 +50,8 @@
 #define   FBC_CTL_PIPEA		(0<<0)
 #define   FBC_CTL_PIPEB		(1<<0)
 
-#define FBC_COMPRESSED_LINES	(1536+32)
+#define FBC_LL_SIZE		(1536)
+#define FBC_LL_PAD		(32)
 
 #define I830_SET_FIELD( var, mask, value ) (var &= ~(mask), var |= value)
 
diff-tree 3c552af65d28fafec1d09484a8914b690b961349 (from 2b9961eb9ce8734565ecdb01cb11610714d7f610)
Author: Eric Anholt <eric at anholt.net>
Date:   Mon Jul 2 18:33:47 2007 -0700

    Update documentation and bump driver version to 2.1.0.

diff --git a/README b/README
index bcb0205..c91c661 100644
--- a/README
+++ b/README
@@ -1,6 +1,6 @@
 Information for Intel graphics driver users
 Eric Anholt
-2007-04-02
+2007-07-02
 
 This document provides a brief summary of the Intel graphics support provided
 by the xf86-video-intel driver.  More information can also be found in the
@@ -15,9 +15,14 @@ Supported Hardware:
 	i845
 	i852
 	i855
-	i915
-	i945
-	i965
+	915G
+	915GM
+	945G
+	945GM/GME
+	946GZ
+	G965
+	GM/GME965
+	G33/Q33/Q35
 
 Features
 - Full support for 8, 15, 16, and 24 bit pixel depths.
@@ -70,6 +75,9 @@ Known Limitations
   release.
 - Gray output with integrated TV-out and PAL TVs.
 - EXA support unstable on i845.
+- Some GM965 systems, such as the Thinkpad T61, probe the TV as being connected
+  even when no output connector is available.  This results in the gnome-panel
+  issue noted below.
 
 Common issues not caused by the driver
 - Font sizes (DPI) are wrong.  Some displays incorrectly report their
@@ -80,7 +88,7 @@ Common issues not caused by the driver
 - gnome-panel is located in the middle of the screen.  gnome-panel places
   itself within head #0's boundaries, which doesn't work well with a second
   head covering the same area as head #0 but larger.
-- Older resolution-changing applicationss have poor results in
+- Older resolution-changing applications have poor results in
   multihead systems.  Previous extensions such as RandR 1.1 exposed only a
   single output to client programs, and those requests map poorly to multi-head
   systems.  Currently, those requests map to just one of the outputs in the
diff --git a/configure.ac b/configure.ac
index a39635e..ec30376 100644
--- a/configure.ac
+++ b/configure.ac
@@ -22,7 +22,7 @@
 
 AC_PREREQ(2.57)
 AC_INIT([xf86-video-intel],
-        2.0.0,
+        2.1.0,
         [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg],
         xf86-video-intel)
 
diff --git a/man/intel.man b/man/intel.man
index 8991619..75280a7 100644
--- a/man/intel.man
+++ b/man/intel.man
@@ -24,14 +24,15 @@ the 830M and later.
 .SH SUPPORTED HARDWARE
 .B intel
 supports the i810, i810-DC100, i810e, i815, i830M, 845G, 852GM, 855GM,
-865G, 915G, 915GM, 945G, 945GM, 965G, 965Q, 946GZ and 965GM chipsets.
+865G, 915G, 915GM, 945G, 945GM, 965G, 965Q, 946GZ, 965GM, 945GME,
+G33, Q33, and Q35 chipsets.
 
 .SH CONFIGURATION DETAILS
 Please refer to __xconfigfile__(__filemansuffix__) for general configuration
 details.  This section only covers configuration details specific to this
 driver.
 .PP
-The Intel 8xx and 9xx families of integrated graphics chipsets has a unified
+The Intel 8xx and 9xx families of integrated graphics chipsets have a unified
 memory architecture and uses system memory for video ram.  For the i810 and
 i815 family of chipset, operating system support for allocating system
 memory for video use is required in order to use this driver.  For the 830M
@@ -66,12 +67,9 @@ Default: undefined.
 .TP
 .BI "Option \*qCacheLines\*q \*q" integer \*q
 This allows the user to change the amount of graphics memory used for
-2D acceleration and video.  Decreasing this amount leaves more for 3D
-textures.  Increasing it can improve 2D performance at the expense of
-3D performance.
-.TP
-This option only takes effect when XAA acceleration is enabled.
-.TP
+2D acceleration and video when XAA acceleration is enabled.  Decreasing this
+amount leaves more for 3D textures.  Increasing it can improve 2D performance
+at the expense of 3D performance.
 Default: depends on the resolution, depth, and available video memory.  The
 driver attempts to allocate space for at 3 screenfuls of pixmaps plus an
 HD-sized XV video.  The default used for a specific configuration can be found
@@ -145,7 +143,7 @@ the full benefit without triple bufferin
 .B "Option \*qTripleBuffer\*q"
 ).
 Default for i810: The option is not used.
-Default for i830 and above: Disabled.
+Default for i830 and above: Disabled (This option is currently unstable).
 .TP
 .BI "Option \*qTripleBuffer\*q \*q" boolean \*q
 Enable support for triple buffering. This should improve 3D performance at the
@@ -202,5 +200,5 @@ support reworked for XFree86 4.3 by Davi
 Keith Whitwell. Lid status support added by Alan Hourihane. Textured video
 support for 915G and later chips, RandR 1.2 and hardware modesetting added
 by Eric Anholt and Keith Packard. EXA and Render acceleration added by Wang
-Zhenyu. TV out support added by Zou Nan Hai and Keith Packard. 965GM support
-added by Wang Zhenyu.
+Zhenyu. TV out support added by Zou Nan Hai and Keith Packard. 965GM, G33,
+Q33, and Q35 support added by Wang Zhenyu.
diff-tree f02036aedcd7866c567a6adc070eda3dad872105 (from b384c608978dcd3d2ea6c0018179673cb4735f4c)
Author: Jesse Barnes <jbarnes at nietzche.virtuousgeek.org>
Date:   Mon Jul 2 15:42:02 2007 -0700

    Framebuffer compression changes:
      - move FBC register definitions to i830_reg.h
      - add fix from Arjan for 965 depth buffer tiling
      - add VT switch and clear-at-server-start code for FBC registers

diff --git a/src/i830.h b/src/i830.h
index 29982ec..1358e3e 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -530,6 +530,10 @@ typedef struct _I830Rec {
    CARD32 savePaletteB[256];
    CARD32 saveSWF[17];
    CARD32 saveBLC_PWM_CTL;
+   CARD32 saveFBC_CFB_BASE;
+   CARD32 saveFBC_LL_BASE;
+   CARD32 saveFBC_CONTROL2;
+   CARD32 saveFBC_CONTROL;
 
    enum last_3d *last_3d;
 
diff --git a/src/i830_display.c b/src/i830_display.c
index f3b24b2..5b1d6ea 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -38,6 +38,7 @@
 
 #include "xf86.h"
 #include "i830.h"
+#include "i830_reg.h"
 #include "i830_bios.h"
 #include "i830_display.h"
 #include "i830_debug.h"
@@ -653,28 +654,6 @@ i830_crtc_unlock (xf86CrtcPtr crtc)
 #endif
 }
 
-#define FBC_CFB_BASE		0x03200 /* 4k page aligned */
-#define FBC_LL_BASE		0x03204 /* 4k page aligned */
-#define FBC_CONTROL		0x03208
-#define   FBC_CTL_EN		(1<<31)
-#define   FBC_CTL_PERIODIC	(1<<30)
-#define   FBC_CTL_INTERVAL_SHIFT (16)
-#define   FBC_CTL_STRIDE_SHIFT	(5)
-#define   FBC_CTL_FENCENO	(1<<0)
-#define FBC_COMMAND		0x0320c
-#define   FBC_CMD_COMPRESS	(1<<0)
-#define FBC_STATUS		0x03210
-#define   FBC_STAT_COMPRESSING	(1<<31)
-#define   FBC_STAT_COMPRESSED	(1<<30)
-#define   FBC_STAT_MODIFIED	(1<<29)
-#define   FBC_STAT_CURRENT_LINE	(1<<0)
-#define FBC_CONTROL2		0x03214
-#define   FBC_CTL_CPU_FENCE	(1<<1)
-#define   FBC_CTL_PIPEA		(0<<0)
-#define   FBC_CTL_PIPEB		(1<<0)
-
-#define FBC_COMPRESSED_LINES	(1536+32)
-
 /*
  * Several restrictions:
  *   - DSP[AB]CNTR - no line duplication && no pixel multiplier
@@ -718,9 +697,6 @@ i830_enable_fb_compression(xf86CrtcPtr c
     fbc_ctl |= (compressed_stride & 0xff) << FBC_CTL_STRIDE_SHIFT;
     fbc_ctl |= (interval & 0x2fff) << FBC_CTL_INTERVAL_SHIFT;
     OUTREG(FBC_CONTROL, fbc_ctl);
-
-    /* and request immediate compression */
-    OUTREG(FBC_COMMAND, FBC_CMD_COMPRESS);
 }
 
 static void
diff --git a/src/i830_driver.c b/src/i830_driver.c
index 42d0f87..5f934fe 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -192,6 +192,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include "vbe.h"
 #include "shadow.h"
 #include "i830.h"
+#include "i830_reg.h"
 #include "i830_display.h"
 #include "i830_debug.h"
 #include "i830_bios.h"
@@ -1750,6 +1751,11 @@ SaveHWState(ScrnInfoPtr pScrn)
    vgaRegPtr vgaReg = &hwp->SavedReg;
    int i;
 
+   pI830->saveFBC_CFB_BASE = INREG(FBC_CFB_BASE);
+   pI830->saveFBC_LL_BASE = INREG(FBC_LL_BASE);
+   pI830->saveFBC_CONTROL2 = INREG(FBC_CONTROL2);
+   pI830->saveFBC_CONTROL = INREG(FBC_CONTROL);
+
    /* Save video mode information for native mode-setting. */
    pI830->saveDSPACNTR = INREG(DSPACNTR);
    pI830->savePIPEACONF = INREG(PIPEACONF);
@@ -1974,6 +1980,11 @@ RestoreHWState(ScrnInfoPtr pScrn)
    OUTREG(SWF31, pI830->saveSWF[15]);
    OUTREG(SWF32, pI830->saveSWF[16]);
 
+   OUTREG(FBC_CFB_BASE, pI830->saveFBC_CFB_BASE);
+   OUTREG(FBC_LL_BASE, pI830->saveFBC_LL_BASE);
+   OUTREG(FBC_CONTROL2, pI830->saveFBC_CONTROL2);
+   OUTREG(FBC_CONTROL, pI830->saveFBC_CONTROL);
+
    vgaHWRestore(pScrn, vgaReg, VGA_SR_FONTS);
    vgaHWLock(hwp);
 
diff --git a/src/i830_memory.c b/src/i830_memory.c
index 5e553f1..8703f2d 100644
--- a/src/i830_memory.c
+++ b/src/i830_memory.c
@@ -104,6 +104,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN
 
 #include "i830.h"
 #include "i810_reg.h"
+#include "i830_reg.h"
 
 #define ALIGN(i,m)    (((i) + (m) - 1) & ~((m) - 1))
 
@@ -1032,6 +1033,12 @@ static void i830_setup_fb_compression(Sc
 	goto out;
     }
 
+    /* Clear out any stale state */
+    OUTREG(FBC_CFB_BASE, 0);
+    OUTREG(FBC_LL_BASE, 0);
+    OUTREG(FBC_CONTROL2, 0);
+    OUTREG(FBC_CONTROL, 0);
+
     /*
      * Compressed framebuffer limitations:
      *   - contiguous, physical, uncached memory
@@ -1302,7 +1309,8 @@ i830_allocate_depthbuffer(ScrnInfoPtr pS
 	    i830_allocate_memory_tiled(pScrn, "depth buffer", size, pitch,
 				       GTT_PAGE_SIZE, ALIGN_BOTH_ENDS,
 				       tile_format);
-	pI830->depth_tiled = FENCE_XMAJOR;
+	pI830->depth_tiled = (tile_format == TILING_YMAJOR) ? FENCE_YMAJOR :
+	    FENCE_XMAJOR;
     }
 
     /* Otherwise, allocate it linear. */
diff --git a/src/i830_reg.h b/src/i830_reg.h
index 7a8df9f..b5fa1b9 100644
--- a/src/i830_reg.h
+++ b/src/i830_reg.h
@@ -29,6 +29,29 @@
 #ifndef _I830_REG_H_
 #define _I830_REG_H_
 
+/* Framebuffer compression */
+#define FBC_CFB_BASE		0x03200 /* 4k page aligned */
+#define FBC_LL_BASE		0x03204 /* 4k page aligned */
+#define FBC_CONTROL		0x03208
+#define   FBC_CTL_EN		(1<<31)
+#define   FBC_CTL_PERIODIC	(1<<30)
+#define   FBC_CTL_INTERVAL_SHIFT (16)
+#define   FBC_CTL_STRIDE_SHIFT	(5)
+#define   FBC_CTL_FENCENO	(1<<0)
+#define FBC_COMMAND		0x0320c
+#define   FBC_CMD_COMPRESS	(1<<0)
+#define FBC_STATUS		0x03210
+#define   FBC_STAT_COMPRESSING	(1<<31)
+#define   FBC_STAT_COMPRESSED	(1<<30)
+#define   FBC_STAT_MODIFIED	(1<<29)
+#define   FBC_STAT_CURRENT_LINE	(1<<0)
+#define FBC_CONTROL2		0x03214
+#define   FBC_CTL_CPU_FENCE	(1<<1)
+#define   FBC_CTL_PIPEA		(0<<0)
+#define   FBC_CTL_PIPEB		(1<<0)
+
+#define FBC_COMPRESSED_LINES	(1536+32)
+
 #define I830_SET_FIELD( var, mask, value ) (var &= ~(mask), var |= value)
 
 #define CMD_3D (0x3<<29)
diff-tree 2b9961eb9ce8734565ecdb01cb11610714d7f610 (from 3d9ee8b2991ec0da8cc21b8455ff7f00fd0335b5)
Author: Eric Anholt <eric at anholt.net>
Date:   Mon Jul 2 15:16:33 2007 -0700

    Fix reversed LVDS dither enabling logic on GM965.

diff --git a/src/i830_display.c b/src/i830_display.c
index aba86ae..ebde525 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -1019,9 +1019,9 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, Dis
 	if (IS_I965G(pI830))
 	{
 	    if ((lvds & LVDS_A3_POWER_MASK) == LVDS_A3_POWER_UP)
-		lvds |= LVDS_DITHER_ENABLE;
-	    else
 		lvds &= ~LVDS_DITHER_ENABLE;
+	    else
+		lvds |= LVDS_DITHER_ENABLE;
 	}
 
 	OUTREG(LVDS, lvds);
diff-tree 3d9ee8b2991ec0da8cc21b8455ff7f00fd0335b5 (from 1e2e301348b4168aeed38b3fdc6b0e43d5678a86)
Author: Eric Anholt <eric at anholt.net>
Date:   Mon Jul 2 14:38:28 2007 -0700

    Bug #11365: Disable the panel fitter unless it's needed for the chosen mode.
    
    The automatic panel scaling appears to choose bad sampling on some GM965
    hardware for 1:1 mapping modes, and there's no real sense in having it on
    if we just want 1:1.

diff --git a/src/i830_lvds.c b/src/i830_lvds.c
index d469815..e2c6e3c 100644
--- a/src/i830_lvds.c
+++ b/src/i830_lvds.c
@@ -261,17 +261,23 @@ i830_lvds_mode_set(xf86OutputPtr output,
     I830CrtcPrivatePtr	    intel_crtc = output->crtc->driver_private;
     CARD32		    pfit_control;
 
-    /* The LVDS pin pair will already have been turned on in the
+    /* The LVDS pin pair will already have been turned on in
      * i830_crtc_mode_set since it has a large impact on the DPLL settings.
      */
 
-    /* Enable automatic panel scaling so that non-native modes fill the
-     * screen.  Should be enabled before the pipe is enabled, according to
+    /* Enable automatic panel scaling for non-native modes so that they fill
+     * the screen.  Should be enabled before the pipe is enabled, according to
      * register description and PRM.
      */
-    pfit_control = (PFIT_ENABLE |
-		    VERT_AUTO_SCALE | HORIZ_AUTO_SCALE |
-		    VERT_INTERP_BILINEAR | HORIZ_INTERP_BILINEAR);
+    if (mode->HDisplay != adjusted_mode->HDisplay ||
+	mode->VDisplay != adjusted_mode->VDisplay)
+    {
+	pfit_control = PFIT_ENABLE |
+	    VERT_AUTO_SCALE | HORIZ_AUTO_SCALE |
+	    VERT_INTERP_BILINEAR | HORIZ_INTERP_BILINEAR;
+    } else {
+	pfit_control = 0;
+    }
 
     if (!IS_I965G(pI830)) {
 	if (dev_priv->panel_wants_dither)
diff-tree b384c608978dcd3d2ea6c0018179673cb4735f4c (from 1e2e301348b4168aeed38b3fdc6b0e43d5678a86)
Author: Jesse Barnes <jbarnes at nietzche.virtuousgeek.org>
Date:   Mon Jul 2 09:32:28 2007 -0700

    Enable framebuffer compression (use Option "FrameBufferCompression"
    "true" in your xorg.conf).  Should save ~0.5W during typical 2D usage.

diff --git a/man/intel.man b/man/intel.man
index 8991619..3e443cd 100644
--- a/man/intel.man
+++ b/man/intel.man
@@ -77,6 +77,13 @@ driver attempts to allocate space for at
 HD-sized XV video.  The default used for a specific configuration can be found
 by examining the __xservername__ log file.
 .TP
+.BI "Option \*qFrameBufferCompression\*q \*q" boolean \*q
+This option controls whether the framebuffer compression feature is enabled.
+If possible, the front buffer will be allocated in a tiled format and compressed
+periodically to save memory bandwidth and power.
+.TP
+This option is only available on mobile chipsets.
+.TP
 .BI "Option \*qDRI\*q \*q" boolean \*q
 Disable or enable DRI support.
 Default: DRI is enabled for configurations where it is supported.
diff --git a/src/i830.h b/src/i830.h
index 9dda33a..29982ec 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -287,6 +287,8 @@ typedef struct _I830Rec {
 
    i830_memory *front_buffer;
    i830_memory *front_buffer_2;
+   i830_memory *compressed_front_buffer;
+   i830_memory *compressed_ll_buffer;
    /* One big buffer for all cursors for kernels that support this */
    i830_memory *cursor_mem;
    /* separate small buffers for kernels that support this */
@@ -342,6 +344,7 @@ typedef struct _I830Rec {
    Bool allowPageFlip;
    Bool TripleBuffer;
    Bool disableTiling;
+   Bool fb_compression;
 
    int backPitch;
 
diff --git a/src/i830_display.c b/src/i830_display.c
index aba86ae..f3b24b2 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -653,15 +653,110 @@ i830_crtc_unlock (xf86CrtcPtr crtc)
 #endif
 }
 
+#define FBC_CFB_BASE		0x03200 /* 4k page aligned */
+#define FBC_LL_BASE		0x03204 /* 4k page aligned */
+#define FBC_CONTROL		0x03208
+#define   FBC_CTL_EN		(1<<31)
+#define   FBC_CTL_PERIODIC	(1<<30)
+#define   FBC_CTL_INTERVAL_SHIFT (16)
+#define   FBC_CTL_STRIDE_SHIFT	(5)
+#define   FBC_CTL_FENCENO	(1<<0)
+#define FBC_COMMAND		0x0320c
+#define   FBC_CMD_COMPRESS	(1<<0)
+#define FBC_STATUS		0x03210
+#define   FBC_STAT_COMPRESSING	(1<<31)
+#define   FBC_STAT_COMPRESSED	(1<<30)
+#define   FBC_STAT_MODIFIED	(1<<29)
+#define   FBC_STAT_CURRENT_LINE	(1<<0)
+#define FBC_CONTROL2		0x03214
+#define   FBC_CTL_CPU_FENCE	(1<<1)
+#define   FBC_CTL_PIPEA		(0<<0)
+#define   FBC_CTL_PIPEB		(1<<0)
+
+#define FBC_COMPRESSED_LINES	(1536+32)
+
+/*
+ * Several restrictions:
+ *   - DSP[AB]CNTR - no line duplication && no pixel multiplier
+ *   - pixel format == 15 bit, 16 bit, or 32 bit xRGB_8888
+ *   - no alpha buffer discard
+ *   - no dual wide display
+ *   - progressive mode only (DSP[AB]CNTR)
+ *
+ * FIXME: verify above conditions are true
+ */
+static void
+i830_enable_fb_compression(xf86CrtcPtr crtc)
+{
+    ScrnInfoPtr pScrn = crtc->scrn;
+    I830Ptr pI830 = I830PTR(pScrn);
+    I830CrtcPrivatePtr	intel_crtc = crtc->driver_private;
+    uint32_t fbc_ctl;
+    unsigned long compressed_stride;
+    int pipe = intel_crtc->pipe;
+    int plane = (pipe == 0 ? FBC_CTL_PIPEA : FBC_CTL_PIPEB);
+    unsigned long uncompressed_stride = pScrn->displayWidth * pI830->cpp;
+    unsigned long interval = 1000;
+
+    compressed_stride = pI830->compressed_front_buffer->size /
+	FBC_COMPRESSED_LINES;
+
+    if (uncompressed_stride < compressed_stride)
+	compressed_stride = uncompressed_stride;
+
+    /* FBC_CTL wants 64B units */
+    compressed_stride = (compressed_stride / 64) - 1;
+
+    /* Set it up... */
+    OUTREG(FBC_CFB_BASE, pI830->compressed_front_buffer->bus_addr);
+    OUTREG(FBC_LL_BASE, pI830->compressed_ll_buffer->bus_addr);
+    OUTREG(FBC_CONTROL2, FBC_CTL_CPU_FENCE | plane);
+
+    /* enable it... */
+    fbc_ctl = INREG(FBC_CONTROL);
+    fbc_ctl |= FBC_CTL_EN | FBC_CTL_PERIODIC;
+    fbc_ctl |= (compressed_stride & 0xff) << FBC_CTL_STRIDE_SHIFT;
+    fbc_ctl |= (interval & 0x2fff) << FBC_CTL_INTERVAL_SHIFT;
+    OUTREG(FBC_CONTROL, fbc_ctl);
+
+    /* and request immediate compression */
+    OUTREG(FBC_COMMAND, FBC_CMD_COMPRESS);
+}
+
+static void
+i830_disable_fb_compression(xf86CrtcPtr crtc)
+{
+    ScrnInfoPtr pScrn = crtc->scrn;
+    I830Ptr pI830 = I830PTR(pScrn);
+    uint32_t fbc_ctl;
+
+    /* Disable compression */
+    fbc_ctl = INREG(FBC_CONTROL);
+    fbc_ctl &= ~FBC_CTL_EN;
+    OUTREG(FBC_CONTROL, fbc_ctl);
+
+    /* Wait for compressing bit to clear */
+    while (INREG(FBC_STATUS) & FBC_STAT_COMPRESSING)
+	; /* nothing */
+}
+
 static void
 i830_crtc_prepare (xf86CrtcPtr crtc)
 {
+    ScrnInfoPtr pScrn = crtc->scrn;
+    I830Ptr pI830 = I830PTR(pScrn);
     crtc->funcs->dpms (crtc, DPMSModeOff);
+
+    /* Temporarily turn off FB compression during modeset */
+    if (pI830->fb_compression)
+	i830_disable_fb_compression(crtc);
 }
 
 static void
 i830_crtc_commit (xf86CrtcPtr crtc)
 {
+    ScrnInfoPtr pScrn = crtc->scrn;
+    I830Ptr pI830 = I830PTR(pScrn);
     I830CrtcPrivatePtr	intel_crtc = crtc->driver_private;
     Bool		deactivate = FALSE;
 
@@ -675,6 +770,10 @@ i830_crtc_commit (xf86CrtcPtr crtc)
 	xf86_reload_cursors (crtc->scrn->pScreen);
     if (deactivate)
 	i830_pipe_a_require_deactivate (crtc->scrn);
+
+    /* Reenable FB compression if possible */
+    if (pI830->fb_compression)
+	i830_enable_fb_compression(crtc);
 }
 
 void
diff --git a/src/i830_driver.c b/src/i830_driver.c
index 7f1fe2c..42d0f87 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -285,6 +285,7 @@ typedef enum {
    OPTION_COLOR_KEY,
    OPTION_CHECKDEVICES,
    OPTION_MODEDEBUG,
+   OPTION_FBC,
 #ifdef XF86DRI_MM
    OPTION_INTELTEXPOOL,
    OPTION_INTELMMSIZE,
@@ -306,6 +307,7 @@ static OptionInfoRec I830Options[] = {
    {OPTION_VIDEO_KEY,	"VideoKey",	OPTV_INTEGER,	{0},	FALSE},
    {OPTION_CHECKDEVICES, "CheckDevices",OPTV_BOOLEAN,	{0},	FALSE},
    {OPTION_MODEDEBUG,	"ModeDebug",	OPTV_BOOLEAN,	{0},	FALSE},
+   {OPTION_FBC,		"FrameBufferCompression", OPTV_BOOLEAN, {0}, FALSE},
 #ifdef XF86DRI_MM
    {OPTION_INTELTEXPOOL,"Legacy3D",     OPTV_BOOLEAN,	{0},	FALSE},
    {OPTION_INTELMMSIZE, "AperTexSize",  OPTV_INTEGER,	{0},	FALSE},
@@ -2305,6 +2307,11 @@ I830ScreenInit(int scrnIndex, ScreenPtr 
       pI830->CacheLines = -1;
    }
 
+   if (xf86ReturnOptValBool(pI830->Options, OPTION_FBC, FALSE))
+       pI830->fb_compression = TRUE;
+   else
+       pI830->fb_compression = FALSE;
+
    pI830->disableTiling = FALSE;
 
    if (I830IsPrimary(pScrn)) {
diff --git a/src/i830_memory.c b/src/i830_memory.c
index afdd93d..5e553f1 100644
--- a/src/i830_memory.c
+++ b/src/i830_memory.c
@@ -902,8 +902,8 @@ i830_allocate_framebuffer(ScrnInfoPtr pS
     name = secondary ? "secondary front buffer" : "front buffer";
 
     /* Attempt to allocate it tiled first if we have page flipping on. */
-    if (!pI830->disableTiling && pI830->allowPageFlip &&
-	IsTileable(pScrn, pitch))
+    if ((!pI830->disableTiling && pI830->allowPageFlip &&
+	 IsTileable(pScrn, pitch)) || pI830->fb_compression)
     {
 	/* XXX: probably not the case on 965 */
 	if (IS_I9XX(pI830))
@@ -1022,6 +1022,56 @@ i830_allocate_cursor_buffers(ScrnInfoPtr
     return TRUE;
 }
 
+static void i830_setup_fb_compression(ScrnInfoPtr pScrn)
+{
+    I830Ptr pI830 = I830PTR(pScrn);
+
+    /* Only mobile chips since 845 support this feature */
+    if (!IS_MOBILE(pI830)) {
+	pI830->fb_compression = FALSE;
+	goto out;
+    }
+
+    /*
+     * Compressed framebuffer limitations:
+     *   - contiguous, physical, uncached memory
+     *   - ideally as large as the front buffer(s), smaller sizes cache less
+     *   - uncompressed buffer must be tiled w/pitch 2k-16k
+     *   - uncompressed fb is <= 2048 in width, 0 mod 8
+     *   - uncompressed fb is <= 1536 in height, 0 mod 2
+     *   - compressed fb stride is <= uncompressed stride
+     *   - SR display watermarks must be equal between 16bpp and 32bpp?
+     *   - both compressed and line buffers must be in stolen memory
+     */
+    pI830->compressed_front_buffer =
+	i830_allocate_memory(pScrn, "compressed frame buffer",
+			     MB(6), KB(4),
+			     NEED_PHYSICAL_ADDR);
+
+    if (!pI830->compressed_front_buffer) {
+	pI830->fb_compression = FALSE;
+	goto out;
+    }
+
+    pI830->compressed_ll_buffer =
+	i830_allocate_memory(pScrn, "compressed ll buffer",
+			     1568, KB(4), NEED_PHYSICAL_ADDR);
+    if (!pI830->compressed_ll_buffer) {
+	i830_free_memory(pScrn, pI830->compressed_front_buffer);
+	pI830->fb_compression = FALSE;
+	goto out;
+    }
+
+out:
+    if (pI830->fb_compression)
+	xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Framebuffer compression "
+		   "enabled\n");
+    else
+	xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Allocation error, framebuffer"
+		   " compression disabled\n");
+	
+    return;
+}
 /*
  * Allocate memory for 2D operation.  This includes the (front) framebuffer,
  * ring buffer, scratch memory, HW cursor.
@@ -1046,6 +1096,9 @@ i830_allocate_2d_memory(ScrnInfoPtr pScr
     /* Allocate the ring buffer first, so it ends up in stolen mem. */
     i830_allocate_ringbuffer(pScrn);
 
+    if (pI830->fb_compression)
+	i830_setup_fb_compression(pScrn);
+
     /* Next, allocate other fixed-size allocations we have. */
     if (!pI830->SWCursor && !i830_allocate_cursor_buffers(pScrn)) {
 	xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
diff-tree 1e2e301348b4168aeed38b3fdc6b0e43d5678a86 (from 11862c2e1f23b77b56d7bd8b384579b5e3ae377b)
Author: Keith Packard <keithp at dulcimer.keithp.com>
Date:   Sat Jun 30 12:45:24 2007 -0700

    Fix load detection to use border region instead of blanking.
    
    Make sure there is some border area to use by changing how the pipe is
    configured, then pick a scanline in the middle of the border for load
    detection. This lets the load detect code use an active pipe instead of
    requiring an idle one.

diff --git a/src/i830_crt.c b/src/i830_crt.c
index d9f4ee6..6d70f39 100644
--- a/src/i830_crt.c
+++ b/src/i830_crt.c
@@ -201,15 +201,16 @@ i830_crt_detect_load (xf86CrtcPtr	    cr
     ScrnInfoPtr		    pScrn = output->scrn;
     I830Ptr		    pI830 = I830PTR(pScrn);
     I830CrtcPrivatePtr	    i830_crtc = I830CrtcPrivate(crtc);
-    I830OutputPrivatePtr    intel_output = output->driver_private;
     CARD32		    save_bclrpat;
     CARD32		    save_vtotal;
     CARD32		    vtotal, vactive;
     CARD32		    vsample;
+    CARD32		    vblank, vblank_start, vblank_end;
     CARD32		    dsl;
     CARD8		    st00;
     int			    bclrpat_reg, pipeconf_reg, pipe_dsl_reg;
     int			    vtotal_reg;
+    int			    vblank_reg;
     int			    pipe = i830_crtc->pipe;
     int			    count, detect;
     Bool		    present;
@@ -218,6 +219,7 @@ i830_crt_detect_load (xf86CrtcPtr	    cr
     {
 	bclrpat_reg = BCLRPAT_A;
 	vtotal_reg = VTOTAL_A;
+	vblank_reg = VBLANK_A;
 	pipeconf_reg = PIPEACONF;
 	pipe_dsl_reg = PIPEA_DSL;
     }
@@ -225,18 +227,26 @@ i830_crt_detect_load (xf86CrtcPtr	    cr
     {
 	bclrpat_reg = BCLRPAT_B;
 	vtotal_reg = VTOTAL_B;
+	vblank_reg = VBLANK_B;
 	pipeconf_reg = PIPEBCONF;
 	pipe_dsl_reg = PIPEB_DSL;
     }
 
     save_bclrpat = INREG(bclrpat_reg);
     save_vtotal = INREG(vtotal_reg);
+    vblank = INREG(vblank_reg);
+    
+    vtotal = ((save_vtotal >> 16) & 0xfff) + 1;
+    vactive = (save_vtotal & 0x7ff) + 1;
 
-    vtotal = (save_vtotal >> 16) & 0xfff;
-    vactive = save_vtotal & 0x7ff;
+    vblank_start = (vblank & 0xfff) + 1;
+    vblank_end = ((vblank >> 16) & 0xfff) + 1;
     
-    /* sample the middle of the blanking interval */
-    vsample = ((vtotal - 3) + (vactive)) >> 1;
+    /* sample in the vertical border, selecting the larger one */
+    if (vblank_start - vactive >= vtotal - vblank_end)
+	vsample = (vblank_start + vactive) >> 1;
+    else
+	vsample = (vtotal + vblank_end) >> 1;
 
     /* Set the border color to purple. */
     OUTREG(bclrpat_reg, 0x500050);
@@ -271,8 +281,6 @@ i830_crt_detect_load (xf86CrtcPtr	    cr
      * the screen
      */
     present = detect * 4 > count * 3;
-    xf86DrvMsg (pScrn->scrnIndex, X_ERROR, "present: %s (%d of %d) at %ld desired %ld temp %d\n",
-		present ? "TRUE" : "FALSE", detect, count, dsl, vsample, intel_output->load_detect_temp);
     return present;
 }
 
@@ -341,11 +349,16 @@ i830_crt_detect(xf86OutputPtr output)
 	Bool			connected;
 	I830OutputPrivatePtr	intel_output = output->driver_private;
 	
-	if (intel_output->load_detect_temp)
+	if (!crtc->enabled)
 	{
 	    xf86SetModeCrtc (&mode, INTERLACE_HALVE_V);
 	    xf86CrtcSetMode (crtc, &mode, RR_Rotate_0, 0, 0);
 	}
+	else if (intel_output->load_detect_temp)
+	{
+	    output->funcs->mode_set (output, &crtc->mode, &crtc->mode);
+	    output->funcs->commit (output);
+	}
 	connected = i830_crt_detect_load (crtc, output);
 
 	i830ReleaseLoadDetectPipe (output);
@@ -384,6 +397,7 @@ i830_crt_init(ScrnInfoPtr pScrn)
 {
     xf86OutputPtr	    output;
     I830OutputPrivatePtr    i830_output;
+    I830Ptr		    pI830 = I830PTR(pScrn);
 
     output = xf86OutputCreate (pScrn, &i830_crt_output_funcs, "VGA");
     if (!output)
@@ -395,7 +409,11 @@ i830_crt_init(ScrnInfoPtr pScrn)
 	return;
     }
     i830_output->type = I830_OUTPUT_ANALOG;
-    i830_output->pipe_mask = ((1 << 0) | (1 << 1));
+    /* i830 (almador) cannot place the analog adaptor on pipe B */
+    if (IS_I830(pI830))
+	i830_output->pipe_mask = (1 << 0);
+    else
+	i830_output->pipe_mask = ((1 << 0) | (1 << 1));
     i830_output->clone_mask = ((1 << I830_OUTPUT_ANALOG) |
 			       (1 << I830_OUTPUT_DVO_TMDS));
     
diff --git a/src/i830_display.c b/src/i830_display.c
index 16ef2cc..aba86ae 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -1054,6 +1054,14 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, Dis
 	((adjusted_mode->CrtcHSyncEnd - 1) << 16));
     OUTREG(vtot_reg, (adjusted_mode->CrtcVDisplay - 1) |
 	((adjusted_mode->CrtcVTotal - 1) << 16));
+    
+    /*
+     * Give us some border at the bottom for load detection
+     */
+    adjusted_mode->CrtcVBlankStart = adjusted_mode->CrtcVSyncStart;
+    if (adjusted_mode->CrtcVBlankEnd - adjusted_mode->CrtcVBlankStart < 3)
+	adjusted_mode->CrtcVBlankStart = adjusted_mode->CrtcVBlankEnd - 3;
+    
     OUTREG(vblank_reg, (adjusted_mode->CrtcVBlankStart - 1) |
 	((adjusted_mode->CrtcVBlankEnd - 1) << 16));
     OUTREG(vsync_reg, (adjusted_mode->CrtcVSyncStart - 1) |
@@ -1322,7 +1330,7 @@ i830GetLoadDetectPipe(xf86OutputPtr outp
 	return output->crtc;
 
     for (i = 0; i < xf86_config->num_crtc; i++)
-	if (!xf86CrtcInUse (xf86_config->crtc[i]))
+	if (output->possible_crtcs & (1 << i))
 	    break;
 
     if (i == xf86_config->num_crtc)
@@ -1344,9 +1352,10 @@ i830ReleaseLoadDetectPipe(xf86OutputPtr 
     
     if (intel_output->load_detect_temp) 
     {
-	output->crtc->enabled = FALSE;
+	xf86CrtcPtr crtc = output->crtc;
 	output->crtc = NULL;
 	intel_output->load_detect_temp = FALSE;
+	crtc->enabled = xf86CrtcInUse (crtc);
 	xf86DisableUnusedFunctions(pScrn);
     }
 }
diff --git a/src/i830_dvo.c b/src/i830_dvo.c
index 2521ee3..cb461d7 100644
--- a/src/i830_dvo.c
+++ b/src/i830_dvo.c
@@ -462,13 +462,13 @@ i830_dvo_init(ScrnInfoPtr pScrn)
 					  "TMDS");
 		break;
 	    case I830_OUTPUT_DVO_LVDS:
-		intel_output->pipe_mask = (1 << 1);
+		intel_output->pipe_mask = ((1 << 0) | (1 << 1));
 		intel_output->clone_mask = (1 << I830_OUTPUT_DVO_LVDS);
 		output = xf86OutputCreate(pScrn, &i830_dvo_output_funcs,
 					  "LVDS");
 		break;
 	    case I830_OUTPUT_DVO_TVOUT:
-		intel_output->pipe_mask = (1 << 1);
+		intel_output->pipe_mask = ((1 << 0) | (1 << 1));
 		intel_output->clone_mask = (1 << I830_OUTPUT_DVO_TVOUT);
 		output = xf86OutputCreate(pScrn, &i830_dvo_output_funcs,
 					  "TV");
diff --git a/src/i830_tv.c b/src/i830_tv.c
index b95986f..1c818ba 100644
--- a/src/i830_tv.c
+++ b/src/i830_tv.c
@@ -1357,13 +1357,18 @@ i830_tv_detect(xf86OutputPtr output)
     crtc = i830GetLoadDetectPipe (output);
     if (crtc)
     {
-        if (intel_output->load_detect_temp)
+	if (!crtc->enabled)
         {
             /* we only need the pixel clock set correctly here */
             mode = reported_modes[0];
             xf86SetModeCrtc (&mode, INTERLACE_HALVE_V);
 	    crtc->funcs->mode_set(crtc, &mode, &mode, 0, 0);
         }
+	else if (intel_output->load_detect_temp)
+	{
+	    output->funcs->mode_set (output, &crtc->mode, &crtc->mode);
+	    output->funcs->commit (output);
+	}
         i830_tv_detect_type (crtc, output);
         i830ReleaseLoadDetectPipe (output);
     }
diff-tree 11862c2e1f23b77b56d7bd8b384579b5e3ae377b (from 6503eb45023d0db9a94cb9d1e14a26af07a6628d)
Author: Alan Coopersmith <alan.coopersmith at sun.com>
Date:   Thu Jun 28 23:31:28 2007 -0700

    Add *~ to .gitignore to skip emacs & patch backup files

diff --git a/.gitignore b/.gitignore
index 8109409..410a074 100644
--- a/.gitignore
+++ b/.gitignore
@@ -5,6 +5,7 @@ Makefile.in
 *.la
 *.lo
 *.o
+*~
 aclocal.m4
 autom4te.cache
 compile
diff-tree 6503eb45023d0db9a94cb9d1e14a26af07a6628d (from 5257e36f502676fd6a44bbb8e747d9138ed3bc5c)
Author: Alan Coopersmith <alan.coopersmith at sun.com>
Date:   Thu Jun 28 23:30:35 2007 -0700

    Add AM_PROG_CC_C_O to configure.ac
    
    Clears automake-1.10 warning: src/bios_reader/Makefile.am:8: compiling
     `bios_dumper.c' with per-target flags requires `AM_PROG_CC_C_O' in
     `configure.ac'

diff --git a/configure.ac b/configure.ac
index 51203fe..a39635e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -48,6 +48,7 @@ AM_MAINTAINER_MODE
 AC_DISABLE_STATIC
 AC_PROG_LIBTOOL
 AC_PROG_CC
+AM_PROG_CC_C_O
 
 AC_CHECK_PROG(gen4asm, [intel-gen4asm], yes, no)
 AM_CONDITIONAL(HAVE_GEN4ASM, test x$gen4asm = xyes)
diff-tree 5257e36f502676fd6a44bbb8e747d9138ed3bc5c (from 16bfcb8042519f24b4494fd621814f39949ceeb6)
Author: Keith Packard <keithp at neko.keithp.com>
Date:   Thu Jun 28 15:29:52 2007 -0700

    Handle dual-channel LVDS on i855.
    
    Just as with i9xx LVDS, the i855 LVDS can operate in dual-channel mode with
    a modified P2 divisor value (7 instead of 14). Just using the existing 9xx
    code for 855 appears to work fine.

diff --git a/src/i830_display.c b/src/i830_display.c
index f6e99be..16ef2cc 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -92,7 +92,7 @@ typedef struct {
 #define I8XX_P2_SLOW		      4
 #define I8XX_P2_FAST		      2
 #define I8XX_P2_LVDS_SLOW	      14
-#define I8XX_P2_LVDS_FAST	      14 /* No fast option */
+#define I8XX_P2_LVDS_FAST	      7
 #define I8XX_P2_SLOW_LIMIT	 165000
 
 #define I9XX_DOT_MIN		  20000
@@ -311,8 +311,7 @@ i830FindBestPLL(xf86CrtcPtr crtc, int ta
     const intel_limit_t   *limit = intel_limit (crtc);
     int err = target;
 
-    if (IS_I9XX(pI830) && i830PipeHasType(crtc, I830_OUTPUT_LVDS) &&
-	(INREG(LVDS) & LVDS_PORT_EN) != 0)
+    if (i830PipeHasType(crtc, I830_OUTPUT_LVDS))
     {
 	/* For LVDS, if the panel is on, just rely on its current settings for
 	 * dual-channel.  We haven't figured out how to reliably set up
@@ -1006,7 +1005,7 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, Dis
 	/* Set the B0-B3 data pairs corresponding to whether we're going to
 	 * set the DPLLs for dual-channel mode or not.
 	 */
-	if (clock.p2 == 7)
+	if (clock.p2 == I9XX_P2_LVDS_FAST)
 	    lvds |= LVDS_B0B3_POWER_UP | LVDS_CLKB_POWER_UP;
 	else
 	    lvds &= ~(LVDS_B0B3_POWER_UP | LVDS_CLKB_POWER_UP);
diff-tree 16bfcb8042519f24b4494fd621814f39949ceeb6 (from 9675ccb30818bf831ac4c634751ab4bfe35f7bfe)
Author: Keith Packard <keithp at neko.keithp.com>
Date:   Thu Jun 28 15:27:56 2007 -0700

    Decode PLL registers in LVDS mode a bit better in debug code.
    
    LVDS mode changes how the PLL works in fairly dramatic ways; the debug code
    wasn't properly accounting for those differences resulting in fairly bogus
    debug output.

diff --git a/src/i830_debug.c b/src/i830_debug.c
index bda263c..055ca93 100644
--- a/src/i830_debug.c
+++ b/src/i830_debug.c
@@ -571,39 +571,91 @@ void i830DumpRegs (ScrnInfoPtr pScrn)
     {
 	fp = INREG(pipe == 0 ? FPA0 : FPB0);
 	dpll = INREG(pipe == 0 ? DPLL_A : DPLL_B);
-	switch ((dpll >> 24) & 0x3) {
-	case 0:
-	    p2 = 10;
-	    break;
-	case 1:
-	    p2 = 5;
-	    break;
-	default:
-	    p2 = 1;
-	    xf86DrvMsg (pScrn->scrnIndex, X_WARNING, "p2 out of range\n");
-	    break;
+	if (IS_I9XX(pI830)) 
+	{
+	    CARD32  lvds = INREG(LVDS);
+	    if ((lvds & LVDS_PORT_EN) &&
+		(lvds & LVDS_PIPEB_SELECT) == (pipe << 30))
+	    {
+		if ((lvds & LVDS_CLKB_POWER_MASK) == LVDS_CLKB_POWER_UP)
+		    p2 = 7;
+		else
+		    p2 = 14;
+	    }
+	    else
+	    {
+		switch ((dpll >> 24) & 0x3) {
+		case 0:
+		    p2 = 10;
+		    break;
+		case 1:
+		    p2 = 5;
+		    break;
+		default:
+		    p2 = 1;
+		    xf86DrvMsg (pScrn->scrnIndex, X_WARNING, "p2 out of range\n");
+		    break;
+		}
+	    }
+	    switch ((dpll >> 16) & 0xff) {
+	    case 1:
+		p1 = 1; break;
+	    case 2:
+		p1 = 2; break;
+	    case 4:
+		p1 = 3; break;
+	    case 8:
+		p1 = 4; break;
+	    case 16:
+		p1 = 5; break;
+	    case 32:
+		p1 = 6; break;
+	    case 64:
+		p1 = 7; break;
+	    case 128:
+		p1 = 8; break;
+	    default:
+		p1 = 1;
+		xf86DrvMsg (pScrn->scrnIndex, X_WARNING, "p1 out of range\n");
+		break;
+	    }
 	}
-	switch ((dpll >> 16) & 0xff) {
-	case 1:
-	    p1 = 1; break;
-	case 2:
-	    p1 = 2; break;
-	case 4:
-	    p1 = 3; break;
-	case 8:
-	    p1 = 4; break;
-	case 16:
-	    p1 = 5; break;
-	case 32:
-	    p1 = 6; break;
-	case 64:
-	    p1 = 7; break;
-	case 128:
-	    p1 = 8; break;
-	default:
-	    p1 = 1;
-	    xf86DrvMsg (pScrn->scrnIndex, X_WARNING, "p1 out of range\n");
-	    break;
+	else
+	{
+	    CARD32  lvds = INREG(LVDS);
+	    if (IS_I85X (pI830) && 
+		(lvds & LVDS_PORT_EN) &&
+		(lvds & LVDS_PIPEB_SELECT) == (pipe << 30))
+	    {
+		if ((lvds & LVDS_CLKB_POWER_MASK) == LVDS_CLKB_POWER_UP)
+		    p2 = 7;
+		else
+		    p2 = 14;
+		switch ((dpll >> 16) & 0x3f) {
+		case 0x01:  p1 = 1; break;
+		case 0x02:  p1 = 2; break;
+		case 0x04:  p1 = 3; break;
+		case 0x08:  p1 = 4; break;
+		case 0x10:  p1 = 5; break;
+		case 0x20:  p1 = 6; break;
+		default:
+		    p1 = 1;
+		    xf86DrvMsg (pScrn->scrnIndex, X_WARNING, "LVDS P1 0x%x invalid encoding\n",
+				(dpll >> 16) & 0x3f);
+		    break;
+		}
+	    }
+	    else
+	    {
+		if (dpll & (1 << 23))
+		    p2 = 4;
+		else
+		    p2 = 2;
+		if (dpll & PLL_P1_DIVIDE_BY_TWO)
+		    p1 = 2;
+		else
+		    p1 = ((dpll >> 16) & 0x3f) + 2;
+	    }
 	}
 	switch ((dpll >> 13) & 0x3) {
 	case 0:
diff-tree 9675ccb30818bf831ac4c634751ab4bfe35f7bfe (from 7a2300c88ae59f5b7c3ce89d33147e3f0ca23c18)
Author: Wang Zhenyu <zhenyu.z.wang at intel.com>
Date:   Wed Jun 27 09:23:33 2007 +0800

    EXA: fallback mask transform on i965
    
    It needs to fix shader programs which hasn't been done yet.

diff --git a/src/i965_render.c b/src/i965_render.c
index 2ab1a6b..744501a 100644
--- a/src/i965_render.c
+++ b/src/i965_render.c
@@ -429,6 +429,8 @@ i965_prepare_composite(int op, PicturePt
 	    rotation_program = TRUE;
     } else {
 	pI830->transform[1] = pMaskPicture->transform;
+	if (pI830->transform[1])
+	    I830FALLBACK("i965 mask transform not implemented!\n");
 	pI830->scale_units[1][0] = pMask->drawable.width;
 	pI830->scale_units[1][1] = pMask->drawable.height;
     }
diff-tree 7a2300c88ae59f5b7c3ce89d33147e3f0ca23c18 (from fff4a3b58fa18ee2ad91f998d190e90b77c051ab)
Author: Wang Zhenyu <zhenyu.z.wang at intel.com>
Date:   Wed Jun 27 09:19:22 2007 +0800

    EXA: don't have to check offscreen size
    
    DDX will check it for EXA_OFFSCREEN_PIXMAPS flag

diff --git a/src/i830_exa.c b/src/i830_exa.c
index 22618dc..fed4067 100644
--- a/src/i830_exa.c
+++ b/src/i830_exa.c
@@ -400,7 +400,7 @@ I830EXAInit(ScreenPtr pScreen)
 	return FALSE;
     }
     memset(pI830->EXADriverPtr, 0, sizeof(*pI830->EXADriverPtr));
-    
+
     pI830->bufferOffset = 0;
     pI830->EXADriverPtr->exa_major = 2;
     pI830->EXADriverPtr->exa_minor = 1;
@@ -408,21 +408,14 @@ I830EXAInit(ScreenPtr pScreen)
     pI830->EXADriverPtr->offScreenBase = pI830->exa_offscreen->offset;
     pI830->EXADriverPtr->memorySize = pI830->exa_offscreen->offset +
 	pI830->exa_offscreen->size;
-	   
+    pI830->EXADriverPtr->flags = EXA_OFFSCREEN_PIXMAPS;
+
     DPRINTF(PFX, "EXA Mem: memoryBase 0x%x, end 0x%x, offscreen base 0x%x, memorySize 0x%x\n",
 		pI830->EXADriverPtr->memoryBase,
 		pI830->EXADriverPtr->memoryBase + pI830->EXADriverPtr->memorySize,
 		pI830->EXADriverPtr->offScreenBase,
 		pI830->EXADriverPtr->memorySize);
 
-    if(pI830->EXADriverPtr->memorySize >
-       pI830->EXADriverPtr->offScreenBase)
-	pI830->EXADriverPtr->flags = EXA_OFFSCREEN_PIXMAPS;
-    else {
-	xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Not enough video RAM for "
-		   "offscreen memory manager. Xv disabled\n");
-	/* disable Xv here... */
-    }
 
     /* Limits are described in the BLT engine chapter under Graphics Data Size
      * Limitations, and the descriptions of SURFACE_STATE, 3DSTATE_BUFFER_INFO,
diff-tree fff4a3b58fa18ee2ad91f998d190e90b77c051ab (from 0a8a4afd3c59011d6b1f5b39aedfb9bce0e55c48)
Author: Carl Worth <cworth at cworth.org>
Date:   Mon Jun 25 23:15:58 2007 -0700

    Use local structures for vs_state, sf_state, and wm_state

diff --git a/src/i965_render.c b/src/i965_render.c
index d79edd1..2ab1a6b 100644
--- a/src/i965_render.c
+++ b/src/i965_render.c
@@ -268,9 +268,9 @@ static struct brw_sampler_state *src_sam
 static struct brw_sampler_state *mask_sampler_state, mask_sampler_state_local;
 static struct brw_sampler_default_color *default_color_state;
 
-static struct brw_vs_unit_state *vs_state;
-static struct brw_sf_unit_state *sf_state;
-static struct brw_wm_unit_state *wm_state;
+static struct brw_vs_unit_state *vs_state, vs_state_local;
+static struct brw_sf_unit_state *sf_state, sf_state_local;
+static struct brw_wm_unit_state *wm_state, wm_state_local;
 static struct brw_cc_unit_state *cc_state, cc_state_local;
 static struct brw_cc_viewport *cc_viewport;
 
@@ -530,9 +530,6 @@ i965_prepare_composite(int op, PicturePt
     state_base_offset = ALIGN(state_base_offset, 64);
     state_base = (char *)(pI830->FbBase + state_base_offset);
 
-    vs_state = (void *)(state_base + vs_offset);
-    sf_state = (void *)(state_base + sf_offset);
-    wm_state = (void *)(state_base + wm_offset);
     sf_kernel = (void *)(state_base + sf_kernel_offset);
     ps_kernel = (void *)(state_base + ps_kernel_offset);
     sip_kernel = (void *)(state_base + sip_kernel_offset);
@@ -786,12 +783,16 @@ i965_prepare_composite(int op, PicturePt
     }
 
     /* Set up the vertex shader to be disabled (passthrough) */
+    vs_state = &vs_state_local;
     memset(vs_state, 0, sizeof(*vs_state));
     vs_state->thread4.nr_urb_entries = URB_VS_ENTRIES;
     vs_state->thread4.urb_entry_allocation_size = URB_VS_ENTRY_SIZE - 1;
     vs_state->vs6.vs_enable = 0;
     vs_state->vs6.vert_cache_disable = 1;
 
+    vs_state = (void *)(state_base + vs_offset);
+    memcpy (vs_state, &vs_state_local, sizeof (vs_state_local));
+
     /* Set up the SF kernel to do coord interp: for each attribute,
      * calculate dA/dx and dA/dy.  Hand these interpolation coefficients
      * back to SF which then hands pixels off to WM.
@@ -804,6 +805,7 @@ i965_prepare_composite(int op, PicturePt
     else
 	memcpy(sf_kernel, sf_kernel_static, sizeof (sf_kernel_static));
 
+    sf_state = &sf_state_local;
     memset(sf_state, 0, sizeof(*sf_state));
     sf_state->thread0.kernel_start_pointer =
 	(state_base_offset + sf_kernel_offset) >> 6;
@@ -835,6 +837,9 @@ i965_prepare_composite(int op, PicturePt
     sf_state->sf6.dest_org_vbias = 0x8;
     sf_state->sf6.dest_org_hbias = 0x8;
 
+    sf_state = (void *)(state_base + sf_offset);
+    memcpy (sf_state, &sf_state_local, sizeof (sf_state_local));
+
    /* Set up the PS kernel (dispatched by WM) */
     if (pMask) {
 	if (pMaskPicture->componentAlpha && 
@@ -856,6 +861,7 @@ i965_prepare_composite(int op, PicturePt
 	       sizeof (ps_kernel_static_nomask));
     }
 
+    wm_state = &wm_state_local;
     memset(wm_state, 0, sizeof (*wm_state));
     wm_state->thread0.kernel_start_pointer =
 	(state_base_offset + ps_kernel_offset) >> 6;
@@ -893,6 +899,9 @@ i965_prepare_composite(int op, PicturePt
     wm_state->wm5.enable_8_pix = 0;
     wm_state->wm5.early_depth_test = 1;
 
+    wm_state = (void *)(state_base + wm_offset);
+    memcpy (wm_state, &wm_state_local, sizeof (wm_state_local));
+
     /* Begin the long sequence of commands needed to set up the 3D
      * rendering pipe
      */
diff-tree 0a8a4afd3c59011d6b1f5b39aedfb9bce0e55c48 (from 499166a60fcbf16021bd9ec233790ba55803aa44)
Author: Carl Worth <cworth at cworth.org>
Date:   Mon Jun 25 23:12:23 2007 -0700

    Use local structure for src_sampler_state and mask_sampler_state

diff --git a/src/i965_render.c b/src/i965_render.c
index 0882271..d79edd1 100644
--- a/src/i965_render.c
+++ b/src/i965_render.c
@@ -264,8 +264,8 @@ static int urb_cs_start, urb_cs_size;
 static struct brw_surface_state *dest_surf_state, dest_surf_state_local;
 static struct brw_surface_state *src_surf_state, src_surf_state_local;
 static struct brw_surface_state *mask_surf_state, mask_surf_state_local;
-static struct brw_sampler_state *src_sampler_state;
-static struct brw_sampler_state *mask_sampler_state;
+static struct brw_sampler_state *src_sampler_state, src_sampler_state_local;
+static struct brw_sampler_state *mask_sampler_state, mask_sampler_state_local;
 static struct brw_sampler_default_color *default_color_state;
 
 static struct brw_vs_unit_state *vs_state;
@@ -539,10 +539,6 @@ i965_prepare_composite(int op, PicturePt
 
     cc_viewport = (void *)(state_base + cc_viewport_offset);
 
-    src_sampler_state = (void *)(state_base + src_sampler_offset);
-    if (pMask)
-	mask_sampler_state = (void *)(state_base + mask_sampler_offset);
-
     binding_table = (void *)(state_base + binding_table_offset);
 
     vb = (void *)(state_base + vb_offset);
@@ -712,6 +708,7 @@ i965_prepare_composite(int op, PicturePt
    	binding_table[2] = state_base_offset + mask_surf_offset;
 
     /* PS kernel use this sampler */
+    src_sampler_state = &src_sampler_state_local;
     memset(src_sampler_state, 0, sizeof(*src_sampler_state));
     src_sampler_state->ss0.lod_preclamp = 1; /* GL mode */
     switch(pSrcPicture->filter) {
@@ -748,7 +745,11 @@ i965_prepare_composite(int op, PicturePt
     }
     src_sampler_state->ss3.chroma_key_enable = 0; /* disable chromakey */
 
+    src_sampler_state = (void *)(state_base + src_sampler_offset);
+    memcpy (src_sampler_state, &src_sampler_state_local, sizeof (src_sampler_state_local));
+
     if (pMask) {
+	mask_sampler_state = &mask_sampler_state_local;
    	memset(mask_sampler_state, 0, sizeof(*mask_sampler_state));
    	mask_sampler_state->ss0.lod_preclamp = 1; /* GL mode */
    	switch(pMaskPicture->filter) {
@@ -779,6 +780,9 @@ i965_prepare_composite(int op, PicturePt
    	    mask_sampler_state->ss1.t_wrap_mode = BRW_TEXCOORDMODE_WRAP;
     	}
    	mask_sampler_state->ss3.chroma_key_enable = 0; /* disable chromakey */
+
+	mask_sampler_state = (void *)(state_base + mask_sampler_offset);
+	memcpy (mask_sampler_state, &mask_sampler_state_local, sizeof (mask_sampler_state_local));
     }
 
     /* Set up the vertex shader to be disabled (passthrough) */
diff-tree 499166a60fcbf16021bd9ec233790ba55803aa44 (from a418ef7316808b239884a90c3fe890220bcc0242)
Author: Carl Worth <cworth at cworth.org>
Date:   Mon Jun 25 23:09:17 2007 -0700

    Use local structure for mask_surf_state

diff --git a/src/i965_render.c b/src/i965_render.c
index eb74cd5..0882271 100644
--- a/src/i965_render.c
+++ b/src/i965_render.c
@@ -263,7 +263,7 @@ static int urb_cs_start, urb_cs_size;
 
 static struct brw_surface_state *dest_surf_state, dest_surf_state_local;
 static struct brw_surface_state *src_surf_state, src_surf_state_local;
-static struct brw_surface_state *mask_surf_state;
+static struct brw_surface_state *mask_surf_state, mask_surf_state_local;
 static struct brw_sampler_state *src_sampler_state;
 static struct brw_sampler_state *mask_sampler_state;
 static struct brw_sampler_default_color *default_color_state;
@@ -539,9 +539,6 @@ i965_prepare_composite(int op, PicturePt
 
     cc_viewport = (void *)(state_base + cc_viewport_offset);
 
-    if (pMask)
-	mask_surf_state = (void *)(state_base + mask_surf_offset);
-
     src_sampler_state = (void *)(state_base + src_sampler_offset);
     if (pMask)
 	mask_sampler_state = (void *)(state_base + mask_sampler_offset);
@@ -681,6 +678,7 @@ i965_prepare_composite(int op, PicturePt
 
     /* setup mask surface */
     if (pMask) {
+	mask_surf_state = &mask_surf_state_local;
    	memset(mask_surf_state, 0, sizeof(*mask_surf_state));
 	mask_surf_state->ss0.surface_type = BRW_SURFACE_2D;
    	mask_surf_state->ss0.surface_format =
@@ -702,6 +700,9 @@ i965_prepare_composite(int op, PicturePt
    	mask_surf_state->ss2.mip_count = 0;
    	mask_surf_state->ss2.render_target_rotation = 0;
    	mask_surf_state->ss3.pitch = mask_pitch - 1;
+
+	mask_surf_state = (void *)(state_base + mask_surf_offset);
+	memcpy (mask_surf_state, &mask_surf_state_local, sizeof (mask_surf_state_local));
     }
 
     /* Set up a binding table for our surfaces.  Only the PS will use it */
diff-tree a418ef7316808b239884a90c3fe890220bcc0242 (from 0e3c0b17826b7b5a21ee2c1d789b084fc167f1ed)
Author: Carl Worth <cworth at cworth.org>
Date:   Mon Jun 25 23:07:19 2007 -0700

    Use local structure for src_surf_state

diff --git a/src/i965_render.c b/src/i965_render.c
index 09a4362..eb74cd5 100644
--- a/src/i965_render.c
+++ b/src/i965_render.c
@@ -262,7 +262,7 @@ static int urb_sf_start, urb_sf_size;
 static int urb_cs_start, urb_cs_size;
 
 static struct brw_surface_state *dest_surf_state, dest_surf_state_local;
-static struct brw_surface_state *src_surf_state;
+static struct brw_surface_state *src_surf_state, src_surf_state_local;
 static struct brw_surface_state *mask_surf_state;
 static struct brw_sampler_state *src_sampler_state;
 static struct brw_sampler_state *mask_sampler_state;
@@ -539,7 +539,6 @@ i965_prepare_composite(int op, PicturePt
 
     cc_viewport = (void *)(state_base + cc_viewport_offset);
 
-    src_surf_state = (void *)(state_base + src_surf_offset);
     if (pMask)
 	mask_surf_state = (void *)(state_base + mask_surf_offset);
 
@@ -655,6 +654,7 @@ i965_prepare_composite(int op, PicturePt
     memcpy (dest_surf_state, &dest_surf_state_local, sizeof (dest_surf_state_local));
 
     /* Set up the source surface state buffer */
+    src_surf_state = &src_surf_state_local;
     memset(src_surf_state, 0, sizeof(*src_surf_state));
     src_surf_state->ss0.surface_type = BRW_SURFACE_2D;
     src_surf_state->ss0.surface_format = i965_get_card_format(pSrcPicture);
@@ -676,6 +676,9 @@ i965_prepare_composite(int op, PicturePt
     src_surf_state->ss2.render_target_rotation = 0;
     src_surf_state->ss3.pitch = src_pitch - 1;
 
+    src_surf_state = (void *)(state_base + src_surf_offset);
+    memcpy (src_surf_state, &src_surf_state_local, sizeof (src_surf_state_local));
+
     /* setup mask surface */
     if (pMask) {
    	memset(mask_surf_state, 0, sizeof(*mask_surf_state));
diff-tree 0e3c0b17826b7b5a21ee2c1d789b084fc167f1ed (from 41a2c0f15446d59678461648f476fa71d40d44e0)
Author: Carl Worth <cworth at cworth.org>
Date:   Mon Jun 25 23:05:50 2007 -0700

    Use local structure for dest_surf_state

diff --git a/src/i965_render.c b/src/i965_render.c
index 71953e7..09a4362 100644
--- a/src/i965_render.c
+++ b/src/i965_render.c
@@ -261,7 +261,7 @@ static int urb_clip_start, urb_clip_size
 static int urb_sf_start, urb_sf_size;
 static int urb_cs_start, urb_cs_size;
 
-static struct brw_surface_state *dest_surf_state;
+static struct brw_surface_state *dest_surf_state, dest_surf_state_local;
 static struct brw_surface_state *src_surf_state;
 static struct brw_surface_state *mask_surf_state;
 static struct brw_sampler_state *src_sampler_state;
@@ -539,7 +539,6 @@ i965_prepare_composite(int op, PicturePt
 
     cc_viewport = (void *)(state_base + cc_viewport_offset);
 
-    dest_surf_state = (void *)(state_base + dest_surf_offset);
     src_surf_state = (void *)(state_base + src_surf_offset);
     if (pMask)
 	mask_surf_state = (void *)(state_base + mask_surf_offset);
@@ -628,6 +627,7 @@ i965_prepare_composite(int op, PicturePt
     memcpy (sip_kernel, sip_kernel_static, sizeof (sip_kernel_static));
 
     /* Set up the state buffer for the destination surface */
+    dest_surf_state = &dest_surf_state_local;
     memset(dest_surf_state, 0, sizeof(*dest_surf_state));
     dest_surf_state->ss0.surface_type = BRW_SURFACE_2D;
     dest_surf_state->ss0.data_return_format = BRW_SURFACERETURNFORMAT_FLOAT32;
@@ -651,6 +651,9 @@ i965_prepare_composite(int op, PicturePt
     dest_surf_state->ss2.render_target_rotation = 0;
     dest_surf_state->ss3.pitch = dst_pitch - 1;
 
+    dest_surf_state = (void *)(state_base + dest_surf_offset);
+    memcpy (dest_surf_state, &dest_surf_state_local, sizeof (dest_surf_state_local));
+
     /* Set up the source surface state buffer */
     memset(src_surf_state, 0, sizeof(*src_surf_state));
     src_surf_state->ss0.surface_type = BRW_SURFACE_2D;
diff-tree 41a2c0f15446d59678461648f476fa71d40d44e0 (from 59f2150caca7eb374a2db43a472ba85f50d23274)
Author: Carl Worth <cworth at cworth.org>
Date:   Mon Jun 25 23:03:47 2007 -0700

    Use local structure for cc_state

diff --git a/src/i965_render.c b/src/i965_render.c
index 347bca0..71953e7 100644
--- a/src/i965_render.c
+++ b/src/i965_render.c
@@ -271,7 +271,7 @@ static struct brw_sampler_default_color 
 static struct brw_vs_unit_state *vs_state;
 static struct brw_sf_unit_state *sf_state;
 static struct brw_wm_unit_state *wm_state;
-static struct brw_cc_unit_state *cc_state;
+static struct brw_cc_unit_state *cc_state, cc_state_local;
 static struct brw_cc_viewport *cc_viewport;
 
 static struct brw_instruction *sf_kernel;
@@ -533,7 +533,6 @@ i965_prepare_composite(int op, PicturePt
     vs_state = (void *)(state_base + vs_offset);
     sf_state = (void *)(state_base + sf_offset);
     wm_state = (void *)(state_base + wm_offset);
-    cc_state = (void *)(state_base + cc_offset);
     sf_kernel = (void *)(state_base + sf_kernel_offset);
     ps_kernel = (void *)(state_base + ps_kernel_offset);
     sip_kernel = (void *)(state_base + sip_kernel_offset);
@@ -594,6 +593,7 @@ i965_prepare_composite(int op, PicturePt
     cc_viewport->max_depth = 1.e35;
 
     /* Color calculator state */
+    cc_state = &cc_state_local;
     memset(cc_state, 0, sizeof(*cc_state));
     cc_state->cc0.stencil_enable = 0;   /* disable stencil */
     cc_state->cc2.depth_test = 0;       /* disable depth test */
@@ -621,6 +621,9 @@ i965_prepare_composite(int op, PicturePt
     cc_state->cc6.clamp_pre_alpha_blend = 1;
     cc_state->cc6.clamp_range = 0;  /* clamp range [0,1] */
 
+    cc_state = (void *)(state_base + cc_offset);
+    memcpy (cc_state, &cc_state_local, sizeof (cc_state_local));
+
     /* Upload system kernel */
     memcpy (sip_kernel, sip_kernel_static, sizeof (sip_kernel_static));
 
diff-tree 59f2150caca7eb374a2db43a472ba85f50d23274 (from 66aa0e61e1e8d2216a9c0555be5be004ed0a3192)
Author: Carl Worth <cworth at cworth.org>
Date:   Mon Jun 25 11:28:57 2007 -0700

    Remove redundant i830WaitSync from i965_prepare_composite
    
    There were two calls to i830WaitSync, and between them no state was
    being changed---just offsets were being computed.

diff --git a/src/i965_render.c b/src/i965_render.c
index e69a939..347bca0 100644
--- a/src/i965_render.c
+++ b/src/i965_render.c
@@ -437,9 +437,6 @@ i965_prepare_composite(int op, PicturePt
 
     binding_table_entries = 2; /* default no mask */
 
-    /* Wait for sync before we start setting up our new state */
-    i830WaitSync(pScrn);
-
     /* Set up our layout of state in framebuffer.  First the general state: */
     next_offset = 0;
     vs_offset = ALIGN(next_offset, 64);
diff-tree 66aa0e61e1e8d2216a9c0555be5be004ed0a3192 (from f8d7cbc6e1322acad3351591336cefcfba7d9aaf)
Author: Dave Mueller <dave.mueller at gmx.ch>
Date:   Fri Jun 22 16:45:27 2007 -0700

    Bug #11171: Add support for the Ti TFP410 DVO TMDS transmitter.

diff --git a/configure.ac b/configure.ac
index 66992fc..51203fe 100644
--- a/configure.ac
+++ b/configure.ac
@@ -230,5 +230,6 @@ AC_OUTPUT([
 	src/ivch/Makefile
 	src/reg_dumper/Makefile
 	src/sil164/Makefile
+	src/tfp410/Makefile
 	man/Makefile
 ])
diff --git a/src/Makefile.am b/src/Makefile.am
index 2b5799c..858ffd1 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -22,7 +22,7 @@ if HAVE_PCIACCESS
 REGDUMPER = reg_dumper
 endif
 
-SUBDIRS = xvmc bios_reader ch7017 ch7xxx ivch sil164 $(REGDUMPER)
+SUBDIRS = xvmc bios_reader ch7017 ch7xxx ivch sil164 tfp410 $(REGDUMPER)
 
 # this is obnoxious:
 # -module lets us name the module exactly how we want
diff --git a/src/i830_dvo.c b/src/i830_dvo.c
index 5666d26..2521ee3 100644
--- a/src/i830_dvo.c
+++ b/src/i830_dvo.c
@@ -36,11 +36,16 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
 
 #include "sil164/sil164.h"
 #include "ch7xxx/ch7xxx.h"
+#include "tfp410/tfp410.h"
 
 static const char *SIL164Symbols[] = {
     "Sil164VidOutput",
     NULL
 };
+static const char *TFP410Symbols[] = {
+    "Tfp410VidOutput",
+    NULL
+};
 static const char *CH7xxxSymbols[] = {
     "CH7xxxVidOutput",
     NULL
@@ -84,6 +89,14 @@ struct _I830DVODriver i830_dvo_drivers[]
 	.address = 0x04, /* Might also be 0x44, 0x84, 0xc4 */
 	.symbols = ivch_symbols
     },
+    {
+	.type = I830_OUTPUT_DVO_TMDS,
+	.modulename = "tfp410",
+	.fntablename = "TFP410VidOutput",
+	.dvo_reg = DVOC,
+	.address = (TFP410_ADDR_1<<1),
+	.symbols = TFP410Symbols
+    },
     /*
     { I830_OUTPUT_DVO_LVDS, "ch7017", "ch7017_methods",
       0xea, ch7017_symbols, NULL, NULL, NULL }
diff --git a/src/tfp410/Makefile.am b/src/tfp410/Makefile.am
new file mode 100644
index 0000000..89a27d0
--- /dev/null
+++ b/src/tfp410/Makefile.am
@@ -0,0 +1,16 @@
+# this is obnoxious:
+# -module lets us name the module exactly how we want
+# -avoid-version prevents gratuitous .0.0.0 version numbers on the end
+# _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@ @XMODES_CFLAGS@ @XORG_CFLAGS@ @DRI_CFLAGS@
+
+tfp410_la_LTLIBRARIES = tfp410.la
+tfp410_la_LDFLAGS = -module -avoid-version
+tfp410_ladir = @moduledir@/drivers
+
+tfp410_la_SOURCES = \
+	tfp410.c \
+	tfp410_module.c \
+	tfp410.h \
+	tfp410_reg.h
diff --git a/src/tfp410/tfp410.c b/src/tfp410/tfp410.c
new file mode 100644
index 0000000..fecb64c
--- /dev/null
+++ b/src/tfp410/tfp410.c
@@ -0,0 +1,265 @@
+/* -*- c-basic-offset: 4 -*- */
+/*
+ * Copyright © 2007 Dave Mueller
+ *
+ * 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 Mueller <dave.mueller at gmx.ch>
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86Resources.h"
+#include "compiler.h"
+#include "miscstruct.h"
+#include "xf86i2c.h"
+#include "xf86Crtc.h"
+#define DPMS_SERVER
+#include <X11/extensions/dpms.h>
+
+#include "../i2c_vid.h"
+#include "tfp410.h"
+#include "tfp410_reg.h"
+
+static Bool
+tfp410ReadByte(TFP410Ptr tfp, int addr, CARD8 *ch)
+{
+    if (!xf86I2CReadByte(&(tfp->d), addr, ch)) {
+	xf86DrvMsg(tfp->d.pI2CBus->scrnIndex, X_ERROR,
+		   "Unable to read from %s Slave %d.\n",
+		   tfp->d.pI2CBus->BusName, tfp->d.SlaveAddr);
+	return FALSE;
+    }
+    return TRUE;
+}
+
+static Bool
+tfp410WriteByte(TFP410Ptr tfp, int addr, CARD8 ch)
+{
+    if (!xf86I2CWriteByte(&(tfp->d), addr, ch)) {
+	xf86DrvMsg(tfp->d.pI2CBus->scrnIndex, X_ERROR,
+		   "Unable to write to %s Slave %d.\n",
+		   tfp->d.pI2CBus->BusName, tfp->d.SlaveAddr);
+	return FALSE;
+    }
+    return TRUE;
+}
+
+static int
+tfp410GetID(TFP410Ptr tfp, int addr)
+{
+    unsigned char ch1, ch2;
+
+    if (tfp410ReadByte(tfp, addr+0, &ch1) &&
+        tfp410ReadByte(tfp, addr+1, &ch2)) {
+
+	return ((ch2<<8) & 0xFF00) | (ch1 & 0x00FF);
+    }
+    return -1;
+}
+
+/* Ti TFP410 driver for chip on i2c bus */
+static void *
+tfp410_init(I2CBusPtr b, I2CSlaveAddr addr)
+{
+    /* this will detect the tfp410 chip on the specified i2c bus */
+    TFP410Ptr tfp;
+    int id;
+
+    xf86DrvMsg(b->scrnIndex, X_INFO, "detecting tfp410\n");
+
+    tfp = xcalloc(1, sizeof(TFP410Rec));
+    if (tfp == NULL)
+	return NULL;
+
+    tfp->d.DevName = "TFP410 TMDS Controller";
+    tfp->d.SlaveAddr = addr;
+    tfp->d.pI2CBus = b;
+    tfp->d.StartTimeout = b->StartTimeout;
+    tfp->d.BitTimeout = b->BitTimeout;
+    tfp->d.AcknTimeout = b->AcknTimeout;
+    tfp->d.ByteTimeout = b->ByteTimeout;
+    tfp->d.DriverPrivate.ptr = tfp;
+
+    if ((id = tfp410GetID(tfp, TFP410_VID_LO)) != TFP410_VID) {
+	xf86DrvMsg(tfp->d.pI2CBus->scrnIndex, X_ERROR,
+		   "tfp410 not detected got VID %X: from %s Slave %d.\n",
+		   id, tfp->d.pI2CBus->BusName, tfp->d.SlaveAddr);
+	goto out;
+    }
+
+    if ((id = tfp410GetID(tfp, TFP410_DID_LO)) != TFP410_DID) {
+	xf86DrvMsg(tfp->d.pI2CBus->scrnIndex, X_ERROR,
+		   "tfp410 not detected got DID %X: from %s Slave %d.\n",
+		   id, tfp->d.pI2CBus->BusName, tfp->d.SlaveAddr);
+	goto out;
+    }
+
+    if (!xf86I2CDevInit(&(tfp->d))) {
+	goto out;
+    }
+
+    return tfp;
+
+out:
+    xfree(tfp);
+    return NULL;
+}
+
+static xf86OutputStatus
+tfp410_detect(I2CDevPtr d)
+{
+    TFP410Ptr tfp = TFPPTR(d);
+    xf86OutputStatus ret = XF86OutputStatusDisconnected;
+    unsigned char ctl2;
+
+    if (tfp410ReadByte(tfp, TFP410_CTL_2, &ctl2)) {
+	if (ctl2 & TFP410_CTL_2_HTPLG)
+	    ret = XF86OutputStatusConnected;
+	else
+	    ret = XF86OutputStatusDisconnected;
+    }
+
+    return ret;
+}
+
+static ModeStatus
+tfp410_mode_valid(I2CDevPtr d, DisplayModePtr mode)
+{
+    return MODE_OK;
+}
+
+static void
+tfp410_mode_set(I2CDevPtr d, DisplayModePtr mode, DisplayModePtr adjusted_mode)
+{
+    /* As long as the basics are set up, since we don't have clock dependencies
+     * in the mode setup, we can just leave the registers alone and everything
+     * will work fine.
+     */
+    /* don't do much */
+    return;
+}
+
+/* set the tfp410 power state */
+static void
+tfp410_dpms(I2CDevPtr d, int mode)
+{
+    TFP410Ptr tfp = TFPPTR(d);
+    unsigned char ctl1;
+
+    if (!tfp410ReadByte(tfp, TFP410_CTL_1, &ctl1))
+	return;
+
+    if (mode == DPMSModeOn)
+	ctl1 |= TFP410_CTL_1_PD;
+    else
+	ctl1 &= ~TFP410_CTL_1_PD;
+
+    tfp410WriteByte(tfp, TFP410_CTL_1, ctl1);
+}
+
+static void
+tfp410_dump_regs(I2CDevPtr d)
+{
+    TFP410Ptr tfp = TFPPTR(d);
+    CARD8 val, val2;
+
+    tfp410ReadByte(tfp, TFP410_REV, &val);
+    xf86DrvMsg(tfp->d.pI2CBus->scrnIndex, X_INFO,
+	       "TFP410_REV: 0x%02X\n", val);
+    tfp410ReadByte(tfp, TFP410_CTL_1, &val);
+    xf86DrvMsg(tfp->d.pI2CBus->scrnIndex, X_INFO,
+	       "TFP410_CTL1: 0x%02X\n", val);
+    tfp410ReadByte(tfp, TFP410_CTL_2, &val);
+    xf86DrvMsg(tfp->d.pI2CBus->scrnIndex, X_INFO,
+	       "TFP410_CTL2: 0x%02X\n", val);
+    tfp410ReadByte(tfp, TFP410_CTL_3, &val);
+    xf86DrvMsg(tfp->d.pI2CBus->scrnIndex, X_INFO,
+	       "TFP410_CTL3: 0x%02X\n", val);
+    tfp410ReadByte(tfp, TFP410_USERCFG, &val);
+    xf86DrvMsg(tfp->d.pI2CBus->scrnIndex, X_INFO,
+	       "TFP410_USERCFG: 0x%02X\n", val);
+    tfp410ReadByte(tfp, TFP410_DE_DLY, &val);
+    xf86DrvMsg(tfp->d.pI2CBus->scrnIndex, X_INFO,
+	       "TFP410_DE_DLY: 0x%02X\n", val);
+    tfp410ReadByte(tfp, TFP410_DE_CTL, &val);
+    xf86DrvMsg(tfp->d.pI2CBus->scrnIndex, X_INFO,
+	       "TFP410_DE_CTL: 0x%02X\n", val);
+    tfp410ReadByte(tfp, TFP410_DE_TOP, &val);
+    xf86DrvMsg(tfp->d.pI2CBus->scrnIndex, X_INFO,
+	       "TFP410_DE_TOP: 0x%02X\n", val);
+    tfp410ReadByte(tfp, TFP410_DE_CNT_LO, &val);
+    tfp410ReadByte(tfp, TFP410_DE_CNT_HI, &val2);
+    xf86DrvMsg(tfp->d.pI2CBus->scrnIndex, X_INFO,
+	       "TFP410_DE_CNT: 0x%02X%02X\n", val2, val);
+    tfp410ReadByte(tfp, TFP410_DE_LIN_LO, &val);
+    tfp410ReadByte(tfp, TFP410_DE_LIN_HI, &val2);
+    xf86DrvMsg(tfp->d.pI2CBus->scrnIndex, X_INFO,
+	       "TFP410_DE_LIN: 0x%02X%02X\n", val2, val);
+    tfp410ReadByte(tfp, TFP410_H_RES_LO, &val);
+    tfp410ReadByte(tfp, TFP410_H_RES_HI, &val2);
+    xf86DrvMsg(tfp->d.pI2CBus->scrnIndex, X_INFO,
+	       "TFP410_H_RES: 0x%02X%02X\n", val2, val);
+    tfp410ReadByte(tfp, TFP410_V_RES_LO, &val);
+    tfp410ReadByte(tfp, TFP410_V_RES_HI, &val2);
+    xf86DrvMsg(tfp->d.pI2CBus->scrnIndex, X_INFO,
+	       "TFP410_V_RES: 0x%02X%02X\n", val2, val);
+}
+
+static void
+tfp410_save(I2CDevPtr d)
+{
+    TFP410Ptr tfp = TFPPTR(d);
+
+    if (!tfp410ReadByte(tfp, TFP410_CTL_1, &tfp->SavedReg.ctl1))
+	return;
+
+    if (!tfp410ReadByte(tfp, TFP410_CTL_2, &tfp->SavedReg.ctl2))
+	return;
+}
+
+static void
+tfp410_restore(I2CDevPtr d)
+{
+    TFP410Ptr tfp = TFPPTR(d);
+
+    /* Restore it powered down initially */
+    tfp410WriteByte(tfp, TFP410_CTL_1, tfp->SavedReg.ctl1 & ~0x1);
+
+    tfp410WriteByte(tfp, TFP410_CTL_2, tfp->SavedReg.ctl2);
+    tfp410WriteByte(tfp, TFP410_CTL_1, tfp->SavedReg.ctl1);
+}
+
+I830I2CVidOutputRec TFP410VidOutput = {
+    .init = tfp410_init,
+    .detect = tfp410_detect,
+    .mode_valid = tfp410_mode_valid,
+    .mode_set = tfp410_mode_set,
+    .dpms = tfp410_dpms,
+    .dump_regs = tfp410_dump_regs,
+    .save = tfp410_save,
+    .restore = tfp410_restore,
+};
diff --git a/src/tfp410/tfp410.h b/src/tfp410/tfp410.h
new file mode 100644
index 0000000..fb3f452
--- /dev/null
+++ b/src/tfp410/tfp410.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright © 2007 Dave Mueller
+ *
+ * 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 Mueller <dave.mueller at gmx.ch>
+ *
+ */
+
+#ifndef TFP410_H
+#define TFP410_H
+
+#define TFP410_ADDR_1 0x38
+
+#endif
diff --git a/src/tfp410/tfp410_module.c b/src/tfp410/tfp410_module.c
new file mode 100644
index 0000000..c05b21a
--- /dev/null
+++ b/src/tfp410/tfp410_module.c
@@ -0,0 +1,38 @@
+/* -*- c-basic-offset: 4 -*- */
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "xf86Module.h"
+
+static MODULESETUPPROTO(tfp410Setup);
+
+static XF86ModuleVersionInfo tfp410VersRec = {
+    "tfp410",
+    MODULEVENDORSTRING,
+    MODINFOSTRING1,
+    MODINFOSTRING2,
+    XORG_VERSION_CURRENT,
+    1, 0, 0,
+    ABI_CLASS_VIDEODRV,
+    ABI_VIDEODRV_VERSION,
+    MOD_CLASS_NONE,
+    { 0,0,0,0 }
+};
+
+_X_EXPORT XF86ModuleData tfp410ModuleData = {
+    &tfp410VersRec,
+    tfp410Setup,
+    NULL
+};
+
+static pointer
+tfp410Setup(pointer module, pointer opts, int *errmaj, int *errmin)
+{
+    return (pointer)1;
+}
diff --git a/src/tfp410/tfp410_reg.h b/src/tfp410/tfp410_reg.h
new file mode 100644
index 0000000..45afa9b
--- /dev/null
+++ b/src/tfp410/tfp410_reg.h
@@ -0,0 +1,104 @@
+/* -*- c-basic-offset: 4 -*- */
+/*
+ * Copyright © 2007 Dave Mueller
+ *
+ * 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 Mueller <dave.mueller at gmx.ch>
+ *
+ */
+
+#ifndef TFP410_REG_H
+#define TFP410_REG_H
+
+/* register definitions according to the TFP410 data sheet */
+#define TFP410_VID 0x014C
+#define TFP410_DID 0x0410
+
+#define TFP410_VID_LO 0x00
+#define TFP410_VID_HI 0x01
+#define TFP410_DID_LO 0x02
+#define TFP410_DID_HI 0x03
+#define TFP410_REV    0x04
+
+#define TFP410_CTL_1 0x08
+#define TFP410_CTL_1_TDIS (1<<6)
+#define TFP410_CTL_1_VEN (1<<5)
+#define TFP410_CTL_1_HEN (1<<4)
+#define TFP410_CTL_1_DSEL (1<<3)
+#define TFP410_CTL_1_BSEL (1<<2)
+#define TFP410_CTL_1_EDGE (1<<1)
+#define TFP410_CTL_1_PD   (1<<0)
+
+#define TFP410_CTL_2 0x09
+#define TFP410_CTL_2_VLOW (1<<7)
+#define TFP410_CTL_2_MSEL_MASK (0x7<<4)
+#define TFP410_CTL_2_MSEL (1<<4)
+#define TFP410_CTL_2_TSEL (1<<3)
+#define TFP410_CTL_2_RSEN (1<<2)
+#define TFP410_CTL_2_HTPLG (1<<1)
+#define TFP410_CTL_2_MDI (1<<0)
+
+#define TFP410_CTL_3 0x0A
+#define TFP410_CTL_3_DK_MASK (0x7<<5)
+#define TFP410_CTL_3_DK (1<<5)
+#define TFP410_CTL_3_DKEN (1<<4)
+#define TFP410_CTL_3_CTL_MASK (0x7<<1)
+#define TFP410_CTL_3_CTL (1<<1)
+
+#define TFP410_USERCFG 0x0B
+
+#define TFP410_DE_DLY 0x32
+
+#define TFP410_DE_CTL 0x33
+#define TFP410_DE_CTL_DEGEN (1<<6)
+#define TFP410_DE_CTL_VSPOL (1<<5)
+#define TFP410_DE_CTL_HSPOL (1<<4)
+#define TFP410_DE_CTL_DEDLY8 (1<<0)
+
+#define TFP410_DE_TOP 0x34
+
+#define TFP410_DE_CNT_LO 0x36
+#define TFP410_DE_CNT_HI 0x37
+
+#define TFP410_DE_LIN_LO 0x38
+#define TFP410_DE_LIN_HI 0x39
+
+#define TFP410_H_RES_LO 0x3A
+#define TFP410_H_RES_HI 0x3B
+
+#define TFP410_V_RES_LO 0x3C
+#define TFP410_V_RES_HI 0x3D
+
+typedef struct _TFP410SaveRec {
+    CARD8 ctl1;
+    CARD8 ctl2;
+} TFP410SaveRec;
+
+typedef struct {
+    I2CDevRec d;
+    TFP410SaveRec SavedReg;
+    TFP410SaveRec ModeReg;
+} TFP410Rec, *TFP410Ptr;
+
+#define TFPPTR(d) ((TFP410Ptr)(d->DriverPrivate.ptr))
+
+#endif
diff-tree f8d7cbc6e1322acad3351591336cefcfba7d9aaf (from ec236c76b93aea5f2ee1e8b8509cde4625974fcb)
Author: Eric Anholt <eric at anholt.net>
Date:   Fri Jun 22 16:29:21 2007 -0700

    Move the ivch's fixed panel mode support to i830_dvo.c for other LVDS drivers.
    
    This also results in removal of the setup hook, which was being called
    unconditionally and breaking non-ivch dvo drivers.

diff --git a/src/i2c_vid.h b/src/i2c_vid.h
index 1a21fca..6c4e95d 100644
--- a/src/i2c_vid.h
+++ b/src/i2c_vid.h
@@ -30,12 +30,6 @@ typedef struct _I830I2CVidOutputRec {
      * Returns NULL if the device does not exist.
      */
     void *(*init)(I2CBusPtr b, I2CSlaveAddr addr);
-    
-    /**
-     * Setup the device for use, after the relevant output has been created
-     */
-    Bool
-    (*setup) (I2CDevPtr d, xf86OutputPtr output);
 
     /**
      * Called to allow the output a chance to create properties after the
diff --git a/src/i830.h b/src/i830.h
index 8947524..9dda33a 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -209,6 +209,8 @@ struct _I830DVODriver {
    I830I2CVidOutputRec *vid_rec;
    void *dev_priv;
    pointer modhandle;
+   DisplayModePtr panel_fixed_mode;
+   Bool panel_wants_dither;
 };
 
 extern const char *i830_output_type_names[];
diff --git a/src/i830_dvo.c b/src/i830_dvo.c
index dfd39ff..5666d26 100644
--- a/src/i830_dvo.c
+++ b/src/i830_dvo.c
@@ -60,20 +60,30 @@ static const char *ch7017_symbols[] = {
 /* driver list */
 struct _I830DVODriver i830_dvo_drivers[] =
 {
-    {I830_OUTPUT_DVO_TMDS, "sil164", "SIL164VidOutput", DVOC,
-     (SIL164_ADDR_1<<1), SIL164Symbols, NULL , NULL, NULL},
-    {I830_OUTPUT_DVO_TMDS | I830_OUTPUT_DVO_TVOUT, "ch7xxx", "CH7xxxVidOutput", DVOC,
-     (CH7xxx_ADDR_1<<1), CH7xxxSymbols, NULL , NULL, NULL},
-    {I830_OUTPUT_DVO_LVDS, "ivch", "ivch_methods", DVOA,
-     0x04, ivch_symbols, NULL, NULL, NULL},
-    /*
-    {I830_OUTPUT_DVO_LVDS, "ivch", "ivch_methods",
-     0x44, ivch_symbols, NULL, NULL, NULL},
-    {I830_OUTPUT_DVO_LVDS, "ivch", "ivch_methods",
-     0x84, ivch_symbols, NULL, NULL, NULL},
-    {I830_OUTPUT_DVO_LVDS, "ivch", "ivch_methods",
-     0xc4, ivch_symbols, NULL, NULL, NULL},
-    */
+    {
+	.type = I830_OUTPUT_DVO_TMDS,
+	.modulename = "sil164",
+	.fntablename = "SIL164VidOutput",
+	.dvo_reg = DVOC,
+	.address = (SIL164_ADDR_1<<1),
+	.symbols = SIL164Symbols
+    },
+    {
+	.type = I830_OUTPUT_DVO_TMDS,
+	.modulename = "ch7xxx",
+	.fntablename = "CH7xxxVidOutput",
+	.dvo_reg = DVOC,
+	.address = (CH7xxx_ADDR_1<<1),
+	.symbols = CH7xxxSymbols
+    },
+    {
+	.type = I830_OUTPUT_DVO_LVDS,
+	.modulename = "ivch",
+	.fntablename = "ivch_methods",
+	.dvo_reg = DVOA,
+	.address = 0x04, /* Might also be 0x44, 0x84, 0xc4 */
+	.symbols = ivch_symbols
+    },
     /*
     { I830_OUTPUT_DVO_LVDS, "ch7017", "ch7017_methods",
       0xea, ch7017_symbols, NULL, NULL, NULL }
@@ -140,6 +150,7 @@ static int
 i830_dvo_mode_valid(xf86OutputPtr output, DisplayModePtr pMode)
 {
     I830OutputPrivatePtr    intel_output = output->driver_private;
+    struct _I830DVODriver   *drv = intel_output->i2c_drv;
     void		    *dev_priv = intel_output->i2c_drv->dev_priv;
 
     if (pMode->Flags & V_DBLSCAN)
@@ -147,6 +158,13 @@ i830_dvo_mode_valid(xf86OutputPtr output
 
     /* XXX: Validate clock range */
 
+    if (drv->panel_fixed_mode) {
+	if (pMode->HDisplay > drv->panel_fixed_mode->HDisplay)
+	    return MODE_PANEL;
+	if (pMode->VDisplay > drv->panel_fixed_mode->VDisplay)
+	    return MODE_PANEL;
+    }
+
     return intel_output->i2c_drv->vid_rec->mode_valid(dev_priv, pMode);
 }
 
@@ -155,6 +173,25 @@ i830_dvo_mode_fixup(xf86OutputPtr output
 		    DisplayModePtr adjusted_mode)
 {
     I830OutputPrivatePtr    intel_output = output->driver_private;
+    struct _I830DVODriver   *drv = intel_output->i2c_drv;
+
+    /* If we have timings from the BIOS for the panel, put them in
+     * to the adjusted mode.  The CRTC will be set up for this mode,
+     * with the panel scaling set up to source from the H/VDisplay
+     * of the original mode.
+     */
+    if (drv->panel_fixed_mode != NULL) {
+	adjusted_mode->HDisplay = drv->panel_fixed_mode->HDisplay;
+	adjusted_mode->HSyncStart = drv->panel_fixed_mode->HSyncStart;
+	adjusted_mode->HSyncEnd = drv->panel_fixed_mode->HSyncEnd;
+	adjusted_mode->HTotal = drv->panel_fixed_mode->HTotal;
+	adjusted_mode->VDisplay = drv->panel_fixed_mode->VDisplay;
+	adjusted_mode->VSyncStart = drv->panel_fixed_mode->VSyncStart;
+	adjusted_mode->VSyncEnd = drv->panel_fixed_mode->VSyncEnd;
+	adjusted_mode->VTotal = drv->panel_fixed_mode->VTotal;
+	adjusted_mode->Clock = drv->panel_fixed_mode->Clock;
+	xf86SetModeCrtc(adjusted_mode, INTERLACE_HALVE_V);
+    }
 
     if (intel_output->i2c_drv->vid_rec->mode_fixup)
 	return intel_output->i2c_drv->vid_rec->mode_fixup (intel_output->i2c_drv->dev_priv,
@@ -235,6 +272,7 @@ static DisplayModePtr
 i830_dvo_get_modes(xf86OutputPtr output)
 {
     I830OutputPrivatePtr    intel_output = output->driver_private;
+    struct _I830DVODriver   *drv = intel_output->i2c_drv;
     DisplayModePtr	    modes;
 
     /* We should probably have an i2c driver get_modes function for those
@@ -253,6 +291,9 @@ i830_dvo_get_modes(xf86OutputPtr output)
 	    return modes;
     }
 
+    if (drv->panel_fixed_mode != NULL)
+	return xf86DuplicateMode(drv->panel_fixed_mode);
+
     return NULL;
 }
 
@@ -436,7 +477,19 @@ i830_dvo_init(ScrnInfoPtr pScrn)
 	    drv->dev_priv = ret_ptr;
 	    intel_output->i2c_drv = drv;
 	    intel_output->pI2CBus = pI2CBus;
-	    drv->vid_rec->setup (drv->dev_priv, output);
+
+	    if (intel_output->type == I830_OUTPUT_DVO_LVDS) {
+		/* For our LVDS chipsets, we should hopefully be able to
+		 * dig the fixed panel mode out of the BIOS data.  However,
+		 * it's in a different format from the BIOS data on chipsets
+		 * with integrated LVDS (stored in AIM headers, liekly),
+		 * so for now, just get the current mode being output through
+		 * DVO.
+		 */
+		drv->panel_fixed_mode = i830_dvo_get_current_mode(output);
+		drv->panel_wants_dither = TRUE;
+	    }
+
 	    return;
 	}
 	xf86UnloadSubModule(drv->modhandle);
diff --git a/src/ivch/ivch.c b/src/ivch/ivch.c
index eac878e..bd11dd4 100644
--- a/src/ivch/ivch.c
+++ b/src/ivch/ivch.c
@@ -49,9 +49,6 @@ struct ivch_priv {
 
     xf86OutputPtr   output;
 
-    DisplayModePtr  panel_fixed_mode;
-    Bool	    panel_wants_dither;
-
     CARD16    	    width;
     CARD16    	    height;
 
@@ -189,6 +186,9 @@ ivch_init(I2CBusPtr b, I2CSlaveAddr addr
 	goto out;
     }
 
+    ivch_read(priv, VR20, &priv->width);
+    ivch_read(priv, VR21, &priv->height);
+
     return priv;
 
 out:
@@ -196,60 +196,18 @@ out:
     return NULL;
 }
 
-/** Gets the panel mode */
-static Bool
-ivch_setup (I2CDevPtr d, xf86OutputPtr output)
-{
-    struct ivch_priv	*priv = d->DriverPrivate.ptr;
-
-    priv->output = output;
-    ivch_read (priv, VR20, &priv->width);
-    ivch_read (priv, VR21, &priv->height);
-    
-    priv->panel_fixed_mode = i830_bios_get_panel_mode (output->scrn, &priv->panel_wants_dither);
-    if (!priv->panel_fixed_mode)
-    {
-	priv->panel_fixed_mode = i830_dvo_get_current_mode (output);
-	priv->panel_wants_dither = TRUE;
-    }
-
-    return TRUE;
-}
-
 static xf86OutputStatus
 ivch_detect(I2CDevPtr d)
 {
     return XF86OutputStatusConnected;
 }
 
-static DisplayModePtr
-ivch_get_modes (I2CDevPtr d)
-{
-    struct ivch_priv	*priv = d->DriverPrivate.ptr;
-
-    if (priv->panel_fixed_mode)
-	return xf86DuplicateMode (priv->panel_fixed_mode);
-
-    return NULL;
-}
-
 static ModeStatus
 ivch_mode_valid(I2CDevPtr d, DisplayModePtr mode)
 {
-    struct ivch_priv	*priv = d->DriverPrivate.ptr;
-    DisplayModePtr	panel_fixed_mode = priv->panel_fixed_mode;
-    
     if (mode->Clock > 112000)
 	return MODE_CLOCK_HIGH;
 
-    if (panel_fixed_mode)
-    {
-	if (mode->HDisplay > panel_fixed_mode->HDisplay)
-	    return MODE_PANEL;
-	if (mode->VDisplay > panel_fixed_mode->VDisplay)
-	    return MODE_PANEL;
-    }
-    
     return MODE_OK;
 }
 
@@ -291,33 +249,6 @@ ivch_dpms(I2CDevPtr d, int mode)
     usleep (16 * 1000);
 }
 
-static Bool
-ivch_mode_fixup(I2CDevPtr d, DisplayModePtr mode, DisplayModePtr adjusted_mode)
-{
-    struct ivch_priv	*priv = d->DriverPrivate.ptr;
-    DisplayModePtr	panel_fixed_mode = priv->panel_fixed_mode;
-    
-    /* If we have timings from the BIOS for the panel, put them in
-     * to the adjusted mode.  The CRTC will be set up for this mode,
-     * with the panel scaling set up to source from the H/VDisplay
-     * of the original mode.
-     */
-    if (panel_fixed_mode != NULL) {
-	adjusted_mode->HDisplay = panel_fixed_mode->HDisplay;
-	adjusted_mode->HSyncStart = panel_fixed_mode->HSyncStart;
-	adjusted_mode->HSyncEnd = panel_fixed_mode->HSyncEnd;
-	adjusted_mode->HTotal = panel_fixed_mode->HTotal;
-	adjusted_mode->VDisplay = panel_fixed_mode->VDisplay;
-	adjusted_mode->VSyncStart = panel_fixed_mode->VSyncStart;
-	adjusted_mode->VSyncEnd = panel_fixed_mode->VSyncEnd;
-	adjusted_mode->VTotal = panel_fixed_mode->VTotal;
-	adjusted_mode->Clock = panel_fixed_mode->Clock;
-	xf86SetModeCrtc(adjusted_mode, INTERLACE_HALVE_V);
-    }
-
-    return TRUE;
-}
-    
 static void
 ivch_mode_set(I2CDevPtr d, DisplayModePtr mode, DisplayModePtr adjusted_mode)
 {
@@ -420,14 +351,11 @@ ivch_restore(I2CDevPtr d)
 
 I830I2CVidOutputRec ivch_methods = {
     .init = ivch_init,
-    .setup = ivch_setup,
     .dpms = ivch_dpms,
     .save = ivch_save,
     .restore = ivch_restore,
     .mode_valid = ivch_mode_valid,
-    .mode_fixup = ivch_mode_fixup,
     .mode_set = ivch_mode_set,
     .detect = ivch_detect,
-    .get_modes = ivch_get_modes,
     .dump_regs = ivch_dump_regs,
 };
diff-tree ec236c76b93aea5f2ee1e8b8509cde4625974fcb (from d957c6b8e1dde8e11c1db3431e0ff58c5d984880)
Author: Keith Packard <keithp at neko.keithp.com>
Date:   Fri Jun 22 16:32:46 2007 +0100

    I830 needs to have plane/pipe/pll started in mode_set.
    
    The patch for the i855 to stop enabling plane/pipe/pll in mode_set broke the
    i830. Revert that just for the i830, leaving it enabled for the i855.

diff --git a/src/i830_display.c b/src/i830_display.c
index 1f0f5b8..f6e99be 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -963,7 +963,7 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, Dis
      * will be run after the mode is set. On 9xx, it helps.
      * On 855, it can lock up the chip (and the entire machine)
      */
-    if (IS_I9XX (pI830))
+    if (!IS_I85X (pI830))
     {
 	dspcntr |= DISPLAY_PLANE_ENABLE;
 	pipeconf |= PIPEACONF_ENABLE;
diff-tree d957c6b8e1dde8e11c1db3431e0ff58c5d984880 (from a67c2965385001bcb8987265f698ff0f5809cd11)
Author: Keith Packard <keithp at neko.keithp.com>
Date:   Fri Jun 22 01:32:02 2007 +0100

    Increase vblank wait timeout from 20ms to 30ms. 49.6Hz < 20ms.
    
    The x40 LVDS mode has a 49.6Hz vertical refresh. Waiting for only 20ms can
    sometimes cause the driver to start programming the hardware before the
    vblank has occurred, which will lock up the i855 chipset. Extend this to
    30ms (the maximum timeout used by the BIOS) to ensure this doesn't happen.
    
    Detecting actual vblank occurance using the various status registers should
    also be possible but isn't yet working.

diff --git a/src/i830_display.c b/src/i830_display.c
index 2df1fcc..1f0f5b8 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -362,7 +362,7 @@ void
 i830WaitForVblank(ScrnInfoPtr pScreen)
 {
     /* Wait for 20ms, i.e. one cycle at 50hz. */
-    usleep(20000);
+    usleep(30000);
 }
 
 void
diff-tree a67c2965385001bcb8987265f698ff0f5809cd11 (from d6e46f67ab3af1ad3bfa72acb0efd9fe79dbf1dc)
Author: Keith Packard <keithp at neko.keithp.com>
Date:   Thu Jun 21 23:59:38 2007 +0100

    Follow BIOS configuration for Legacy Backlight Brightness.
    
    The backlight control in the LVDS controller can either operate in 'normal'
    mode or 'legacy' mode. In legacy mode, it uses the PCI config space register
    0xf4 which can range from 0 to 0xff. In normal mode, it reads the range and
    current value from the BLC_PWM_CTL register.

diff --git a/src/i810_reg.h b/src/i810_reg.h
index 6001297..248df04 100644
--- a/src/i810_reg.h
+++ b/src/i810_reg.h
@@ -1056,6 +1056,14 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN
 #define RENCLK_GATE_D2		0x6208
 #define RAMCLK_GATE_D		0x6210		/* CRL only */
 
+/*
+ * This is a PCI config space register to manipulate backlight brightness
+ * It is used when the BLM_LEGACY_MODE is turned on. When enabled, the first
+ * byte of this config register sets brightness within the range from
+ * 0 to 0xff
+ */
+#define LEGACY_BACKLIGHT_BRIGHTNESS 0xf4
+
 #define BLC_PWM_CTL		0x61254
 #define BACKLIGHT_MODULATION_FREQ_SHIFT		(17)
 /**
diff --git a/src/i830_lvds.c b/src/i830_lvds.c
index ee278aa..d469815 100644
--- a/src/i830_lvds.c
+++ b/src/i830_lvds.c
@@ -59,8 +59,18 @@ i830_lvds_set_backlight(xf86OutputPtr ou
     I830Ptr pI830 = I830PTR(pScrn);
     CARD32 blc_pwm_ctl;
 
-    blc_pwm_ctl = INREG(BLC_PWM_CTL) & ~BACKLIGHT_DUTY_CYCLE_MASK;
-    OUTREG(BLC_PWM_CTL, blc_pwm_ctl | (level << BACKLIGHT_DUTY_CYCLE_SHIFT));
+    blc_pwm_ctl = INREG(BLC_PWM_CTL);
+    if (blc_pwm_ctl & BLM_LEGACY_MODE)
+    {
+	pciWriteByte (pI830->PciTag, 
+		      LEGACY_BACKLIGHT_BRIGHTNESS,
+		      level & 0xff);
+    }
+    else
+    {
+	blc_pwm_ctl &= ~BACKLIGHT_DUTY_CYCLE_MASK;
+	OUTREG(BLC_PWM_CTL, blc_pwm_ctl | (level << BACKLIGHT_DUTY_CYCLE_SHIFT));
+    }
 }
 
 /**
@@ -71,9 +81,13 @@ i830_lvds_get_max_backlight(xf86OutputPt
 {
     ScrnInfoPtr pScrn = output->scrn;
     I830Ptr	pI830 = I830PTR(pScrn);
+    CARD32	pwm_ctl = INREG(BLC_PWM_CTL);
     
-    return ((INREG(BLC_PWM_CTL) & BACKLIGHT_MODULATION_FREQ_MASK) >>
-	BACKLIGHT_MODULATION_FREQ_SHIFT) * 2;
+    if (pwm_ctl & BLM_LEGACY_MODE)
+	return 0xff;
+    else
+	return ((pwm_ctl & BACKLIGHT_MODULATION_FREQ_MASK) >>
+		BACKLIGHT_MODULATION_FREQ_SHIFT) * 2;
 }
 
 /**
@@ -129,8 +143,16 @@ i830_lvds_save (xf86OutputPtr output)
     pI830->savePP_CONTROL = INREG(PP_CONTROL);
     pI830->savePP_CYCLE = INREG(PP_CYCLE);
     pI830->saveBLC_PWM_CTL = INREG(BLC_PWM_CTL);
-    dev_priv->backlight_duty_cycle = (pI830->saveBLC_PWM_CTL &
-				      BACKLIGHT_DUTY_CYCLE_MASK);
+    if (pI830->saveBLC_PWM_CTL & BLM_LEGACY_MODE)
+    {
+	dev_priv->backlight_duty_cycle = pciReadByte (pI830->PciTag,
+						      LEGACY_BACKLIGHT_BRIGHTNESS);
+    }
+    else
+    {
+	dev_priv->backlight_duty_cycle = (pI830->saveBLC_PWM_CTL &
+					  BACKLIGHT_DUTY_CYCLE_MASK);
+    }
 
     /*
      * If the light is off at server startup, just make it full brightness
diff-tree d6e46f67ab3af1ad3bfa72acb0efd9fe79dbf1dc (from 9d104634cf03bea82d1467f01e577cb8d2e4b554)
Author: Keith Packard <keithp at neko.keithp.com>
Date:   Thu Jun 21 20:16:36 2007 +0100

    Eliminate some uninitialized variable warnings

diff --git a/src/i830_dvo.c b/src/i830_dvo.c
index d81e5dd..dfd39ff 100644
--- a/src/i830_dvo.c
+++ b/src/i830_dvo.c
@@ -179,6 +179,7 @@ i830_dvo_mode_set(xf86OutputPtr output, 
 
     switch (dvo_reg) {
     case DVOA:
+    default:
 	dvo_srcdim_reg = DVOA_SRCDIM;
 	break;
     case DVOB:
diff --git a/src/i830_video.c b/src/i830_video.c
index 43e25bb..b4f9e74 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -1702,6 +1702,10 @@ i830_covering_crtc (ScrnInfoPtr pScrn,
 
     best_crtc = NULL;
     best_coverage = 0;
+    crtc_box_ret->x1 = 0;
+    crtc_box_ret->x2 = 0;
+    crtc_box_ret->y1 = 0;
+    crtc_box_ret->y2 = 0;
     for (c = 0; c < xf86_config->num_crtc; c++)
     {
 	crtc = xf86_config->crtc[c];
diff-tree 9d104634cf03bea82d1467f01e577cb8d2e4b554 (from 3bbf313ba541526a893915f8b6c64b1eccf325e0)
Author: Keith Packard <keithp at neko.keithp.com>
Date:   Thu Jun 21 01:15:39 2007 +0100

    Add 3DSTATE_CLEAR_PARAMETERS bits

diff --git a/src/i915_reg.h b/src/i915_reg.h
index 6b40d70..682a157 100644
--- a/src/i915_reg.h
+++ b/src/i915_reg.h
@@ -109,6 +109,13 @@
 /* 3DSTATE_CHROMA_KEY */
 
 /* 3DSTATE_CLEAR_PARAMETERS, p150 */
+#define _3DSTATE_CLEAR_PARAMETERS   (CMD_3D | (0x1d<<24) | (0x9c<<16) | 5)
+/* Dword 1 */
+#define CLEARPARAM_CLEAR_RECT	    (1 << 16)
+#define CLEARPARAM_ZONE_INIT	    (0 << 16)
+#define CLEARPARAM_WRITE_COLOR	    (1 << 2)
+#define CLEARPARAM_WRITE_DEPTH	    (1 << 1)
+#define CLEARPARAM_WRITE_STENCIL    (1 << 0)
 
 /* 3DSTATE_CONSTANT_BLEND_COLOR, p153 */
 #define _3DSTATE_CONST_BLEND_COLOR_CMD	(CMD_3D | (0x1d<<24) | (0x88<<16))
diff-tree 3bbf313ba541526a893915f8b6c64b1eccf325e0 (from acef342c870f3b5b781e48c8bf44739aa5ee8ffa)
Author: Wang Zhenyu <zhenyu.z.wang at intel.com>
Date:   Tue Jun 19 09:33:50 2007 +0800

    Fix left G33 issues
    
    Be sure to check G33 chip type in:
    - sdvo output
    - Y-major tile
    - crt detect
    - and xaa composite
    Sorry for that I should have fixed them very earlier...

diff --git a/src/i830_crt.c b/src/i830_crt.c
index bbb4a83..d9f4ee6 100644
--- a/src/i830_crt.c
+++ b/src/i830_crt.c
@@ -310,7 +310,8 @@ i830_crt_detect(xf86OutputPtr output)
     I830Ptr		    pI830 = I830PTR(pScrn);
     xf86CrtcPtr	    crtc;
 
-    if (IS_I945G(pI830) || IS_I945GM(pI830) || IS_I965G(pI830)) {
+    if (IS_I945G(pI830) || IS_I945GM(pI830) || IS_I965G(pI830) ||
+	    IS_G33CLASS(pI830)) {
 	if (i830_crt_detect_hotplug(output))
 	    return XF86OutputStatusConnected;
 	else
diff --git a/src/i830_debug.c b/src/i830_debug.c
index 9354958..bda263c 100644
--- a/src/i830_debug.c
+++ b/src/i830_debug.c
@@ -224,7 +224,7 @@ DEBUGSTRING(i830_debug_dpll)
 	break;
     }
 
-    if (IS_I945G(pI830) || IS_I945GM(pI830)) {
+    if (IS_I945G(pI830) || IS_I945GM(pI830) || IS_G33CLASS(pI830)) {
 	sprintf(sdvoextra, ", SDVO mult %d",
 		(int)((val & SDVO_MULTIPLIER_MASK) >>
 		SDVO_MULTIPLIER_SHIFT_HIRES) + 1);
diff --git a/src/i830_display.c b/src/i830_display.c
index 6965337..2df1fcc 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -706,7 +706,7 @@ i830_get_core_clock_speed(ScrnInfoPtr pS
     /* Core clock values taken from the published datasheets.
      * The 830 may go up to 166 Mhz, which we should check.
      */
-    if (IS_I945G(pI830))
+    if (IS_I945G(pI830) || IS_G33CLASS(pI830))
 	return 400000;
     else if (IS_I915G(pI830))
 	return 333000;
@@ -869,7 +869,7 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, Dis
 	if (is_sdvo)
 	{
 	    dpll |= DPLL_DVO_HIGH_SPEED;
-	    if (IS_I945G(pI830) || IS_I945GM(pI830))
+	    if (IS_I945G(pI830) || IS_I945GM(pI830) || IS_G33CLASS(pI830))
 	    {
 		int sdvo_pixel_multiply = adjusted_mode->Clock / mode->Clock;
 		dpll |= (sdvo_pixel_multiply - 1) << SDVO_MULTIPLIER_SHIFT_HIRES;
diff --git a/src/i830_memory.c b/src/i830_memory.c
index 17d4c4e..afdd93d 100644
--- a/src/i830_memory.c
+++ b/src/i830_memory.c
@@ -790,7 +790,7 @@ IsTileable(ScrnInfoPtr pScrn, int pitch)
     switch (pitch) {
     case 128:
     case 256:
-	if (IS_I945G(pI830) || IS_I945GM(pI830))
+	if (IS_I945G(pI830) || IS_I945GM(pI830) || IS_G33CLASS(pI830))
 	    return TRUE;
 	else
 	    return FALSE;
@@ -1528,7 +1528,8 @@ i830_set_fence(ScrnInfoPtr pScrn, int nr
    	}
     }
 
-    if ((IS_I945G(pI830) || IS_I945GM(pI830)) && tile_format == TILING_YMAJOR)
+    if ((IS_I945G(pI830) || IS_I945GM(pI830) || IS_G33CLASS(pI830))
+	    && tile_format == TILING_YMAJOR)
 	fence_pitch = pitch / 128;
     else if (IS_I9XX(pI830))
 	fence_pitch = pitch / 512;
diff --git a/src/i830_sdvo.c b/src/i830_sdvo.c
index 3916dba..2767715 100644
--- a/src/i830_sdvo.c
+++ b/src/i830_sdvo.c
@@ -747,7 +747,7 @@ i830_sdvo_mode_set(xf86OutputPtr output,
     sdvo_pixel_multiply = i830_sdvo_get_pixel_multiplier(mode);
     if (IS_I965G(pI830)) {
 	/* done in crtc_mode_set as the dpll_md reg must be written early */
-    } else if (IS_I945G(pI830) || IS_I945GM(pI830)) {
+    } else if (IS_I945G(pI830) || IS_I945GM(pI830) || IS_G33CLASS(pI830)) {
 	/* done in crtc_mode_set as it lives inside the dpll register */
     } else {
 	sdvox |= (sdvo_pixel_multiply - 1) << SDVO_PORT_MULTIPLY_SHIFT;
diff --git a/src/i830_xaa.c b/src/i830_xaa.c
index 790299c..ec8a879 100644
--- a/src/i830_xaa.c
+++ b/src/i830_xaa.c
@@ -249,7 +249,7 @@ I830XAAInit(ScreenPtr pScreen)
 	    pI830->xaa_composite = i830_composite;
 	    pI830->xaa_done_composite = i830_done_composite;
 	} else if (IS_I915G(pI830) || IS_I915GM(pI830) ||
-		   IS_I945G(pI830) || IS_I945GM(pI830))
+		   IS_I945G(pI830) || IS_I945GM(pI830) || IS_G33CLASS(pI830))
 	{
 	    pI830->xaa_check_composite = i915_check_composite;
 	    pI830->xaa_prepare_composite = i915_prepare_composite;
diff-tree acef342c870f3b5b781e48c8bf44739aa5ee8ffa (from fbbb41bc5e03478cb46ee8f64ef68b23ff3fc14b)
Author: Eric Anholt <eric at anholt.net>
Date:   Mon Jun 18 11:57:48 2007 -0700

    Bug #11295: Disable textured video on i915 with framebuffer width too large.

diff --git a/src/i830_video.c b/src/i830_video.c
index 1ee43dd..43e25bb 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -569,7 +569,9 @@ I830InitVideo(ScreenPtr pScreen)
     /* Set up textured video if we can do it at this depth and we are on
      * supported hardware.
      */
-    if (pScrn->bitsPerPixel >= 16 && (IS_I9XX(pI830) || IS_I965G(pI830))) {
+    if (pScrn->bitsPerPixel >= 16 && (IS_I9XX(pI830) || IS_I965G(pI830)) &&
+	!(!IS_I965G(pI830) && pScrn->displayWidth > 2048))
+    {
 	texturedAdaptor = I830SetupImageVideoTextured(pScreen);
 	if (texturedAdaptor != NULL) {
 	    adaptors[num_adaptors++] = texturedAdaptor;
diff-tree fbbb41bc5e03478cb46ee8f64ef68b23ff3fc14b (from d5ca000ece145a35fd6df0dcf3fb3460bd2d64e3)
Author: Keith Packard <keithp at neko.keithp.com>
Date:   Sun Jun 17 14:59:24 2007 +0100

    Let DPMS functions enable plane/pipe/output on 8xx hardware.
    
    On 855, letting crtc_mode_set enable the plane and pipe will occasionally
    hang the chip. Instead, wait for crtc_enable to light things up. For 9xx,
    leave things alone.

diff --git a/src/i830_display.c b/src/i830_display.c
index adc7479..6965337 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -958,11 +958,17 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, Dis
 	else
 	    pipeconf &= ~PIPEACONF_DOUBLE_WIDE;
     }
-#if 1
-    dspcntr |= DISPLAY_PLANE_ENABLE;
-    pipeconf |= PIPEACONF_ENABLE;
-    dpll |= DPLL_VCO_ENABLE;
-#endif
+    /*
+     * This "shouldn't" be needed as the dpms on code
+     * will be run after the mode is set. On 9xx, it helps.
+     * On 855, it can lock up the chip (and the entire machine)
+     */
+    if (IS_I9XX (pI830))
+    {
+	dspcntr |= DISPLAY_PLANE_ENABLE;
+	pipeconf |= PIPEACONF_ENABLE;
+	dpll |= DPLL_VCO_ENABLE;
+    }
     
     /* Disable the panel fitter if it was on our pipe */
     if (i830_panel_fitter_pipe (pI830) == pipe)
diff-tree d5ca000ece145a35fd6df0dcf3fb3460bd2d64e3 (from 6b2ae93506d6795f87d6993bebfcb4e6632508ee)
Author: Rémi Cardona <remi at gentoo.org>
Date:   Sat Jun 16 13:17:54 2007 +0100

    Include stdint.h to get uint64_t

diff --git a/src/i830_common.h b/src/i830_common.h
index 5c2d919..9c8616c 100644
--- a/src/i830_common.h
+++ b/src/i830_common.h
@@ -31,6 +31,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
 #ifndef _I830_COMMON_H_
 #define _I830_COMMON_H_
 
+#include <stdint.h>
 
 #define I830_NR_TEX_REGIONS 255	/* maximum due to use of chars for next/prev */
 #define I830_LOG_MIN_TEX_REGION_SIZE 14
diff-tree 6b2ae93506d6795f87d6993bebfcb4e6632508ee (from 671ba03befebfdd7256855858987aabc28b2e8cd)
Author: Dave Airlie <airlied at linux.ie>
Date:   Fri Jun 15 23:30:04 2007 +1000

    sdvo: add support for RGB outputs on SDVO
    
    This lights up my monitor VGA-1 - it doesn't look the best though

diff --git a/src/i830_sdvo.c b/src/i830_sdvo.c
index 24c9c99..3916dba 100644
--- a/src/i830_sdvo.c
+++ b/src/i830_sdvo.c
@@ -1280,6 +1280,18 @@ i830_sdvo_init(ScrnInfoPtr pScrn, int ou
         output->subpixel_order = SubPixelHorizontalRGB;
 	name_prefix="TMDS";
     }
+    else if (dev_priv->caps.output_flags & SDVO_OUTPUT_RGB0)
+    {
+	dev_priv->active_outputs = SDVO_OUTPUT_RGB0;
+        output->subpixel_order = SubPixelHorizontalRGB;
+	name_prefix="VGA";
+    }
+    else if (dev_priv->caps.output_flags & SDVO_OUTPUT_RGB1)
+    {
+	dev_priv->active_outputs = SDVO_OUTPUT_RGB1;
+        output->subpixel_order = SubPixelHorizontalRGB;
+	name_prefix="VGA";
+    }
     else
     {
 	unsigned char	bytes[2];
@@ -1318,6 +1330,6 @@ i830_sdvo_init(ScrnInfoPtr pScrn, int ou
 	       dev_priv->pixel_clock_max / 1000.0,
 	       (dev_priv->caps.sdvo_inputs_mask & 0x1) ? 'Y' : 'N',
 	       (dev_priv->caps.sdvo_inputs_mask & 0x2) ? 'Y' : 'N',
-	       dev_priv->caps.output_flags & SDVO_OUTPUT_TMDS0 ? 'Y' : 'N',
-	       dev_priv->caps.output_flags & SDVO_OUTPUT_TMDS1 ? 'Y' : 'N');
+	       dev_priv->caps.output_flags & (SDVO_OUTPUT_RGB0 | SDVO_OUTPUT_TMDS0) ? 'Y' : 'N',
+	       dev_priv->caps.output_flags & (SDVO_OUTPUT_RGB1 | SDVO_OUTPUT_TMDS1) ? 'Y' : 'N');
 }
diff-tree 671ba03befebfdd7256855858987aabc28b2e8cd (from 6c29e0bae5f1e7cee02b678418394abb971594eb)
Author: Eric Anholt <eric at anholt.net>
Date:   Wed Jun 13 16:30:26 2007 -0700

    Fix and enable the 915-class planar textured video path.

diff --git a/src/i830_video.c b/src/i830_video.c
index c1ddc98..1ee43dd 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -2347,9 +2347,8 @@ I830PutImage(ScrnInfoPtr pScrn,
     case FOURCC_I420:
 	srcPitch = (width + 3) & ~3;
 	srcPitch2 = ((width >> 1) + 3) & ~3;
-	if (pPriv->textured) {
+	if (pPriv->textured && IS_I965G(pI830))
 	    destId = FOURCC_YUY2;
-	}
 	break;
     case FOURCC_UYVY:
     case FOURCC_YUY2:
@@ -2450,7 +2449,7 @@ I830PutImage(ScrnInfoPtr pScrn,
     case FOURCC_I420:
 	top &= ~1;
 	nlines = ((((y2 + 0xffff) >> 16) + 1) & ~1) - top;
-	if (pPriv->textured) {
+	if (pPriv->textured && IS_I965G(pI830)) {
 	    I830CopyPlanarToPackedData(pScrn, pPriv, buf, srcPitch, srcPitch2,
 				       dstPitch, height, top, left, nlines,
 				       npixels, id);
diff --git a/src/i915_video.c b/src/i915_video.c
index d02f770..f1bf4cc 100644
--- a/src/i915_video.c
+++ b/src/i915_video.c
@@ -48,7 +48,7 @@ I915DisplayVideoTextured(ScrnInfoPtr pSc
 			 PixmapPtr pPixmap)
 {
    I830Ptr pI830 = I830PTR(pScrn);
-   CARD32 format, ms3, s2, s5;
+   CARD32 format, ms3, s5;
    BoxPtr pbox;
    int nbox, dxo, dyo, pix_xoff, pix_yoff;
    Bool planar;
@@ -68,11 +68,8 @@ I915DisplayVideoTextured(ScrnInfoPtr pSc
       planar = TRUE;
       break;
    default:
-#if 0
       ErrorF("Unknown format 0x%x\n", id);
-#endif
-      planar = FALSE;
-      break;
+      return;
    }
 
    IntelEmitInvarientState(pScrn);
@@ -96,18 +93,14 @@ I915DisplayVideoTextured(ScrnInfoPtr pSc
 
    OUT_RING(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(2) |
 	    I1_LOAD_S(4) | I1_LOAD_S(5) | I1_LOAD_S(6) | 3);
-   s2 = S2_TEXCOORD_FMT(0, TEXCOORDFMT_2D);
-   if (planar)
-      s2 |= S2_TEXCOORD_FMT(1, TEXCOORDFMT_2D);
-   else
-      s2 |= S2_TEXCOORD_FMT(1, TEXCOORDFMT_NOT_PRESENT);
-   s2 |= S2_TEXCOORD_FMT(2, TEXCOORDFMT_NOT_PRESENT) |
-      S2_TEXCOORD_FMT(3, TEXCOORDFMT_NOT_PRESENT) |
-      S2_TEXCOORD_FMT(4, TEXCOORDFMT_NOT_PRESENT) |
-      S2_TEXCOORD_FMT(5, TEXCOORDFMT_NOT_PRESENT) |
-      S2_TEXCOORD_FMT(6, TEXCOORDFMT_NOT_PRESENT) |
-      S2_TEXCOORD_FMT(7, TEXCOORDFMT_NOT_PRESENT);
-   OUT_RING(s2);
+   OUT_RING(S2_TEXCOORD_FMT(0, TEXCOORDFMT_2D) |
+	    S2_TEXCOORD_FMT(1, TEXCOORDFMT_NOT_PRESENT) |
+	    S2_TEXCOORD_FMT(2, TEXCOORDFMT_NOT_PRESENT) |
+	    S2_TEXCOORD_FMT(3, TEXCOORDFMT_NOT_PRESENT) |
+	    S2_TEXCOORD_FMT(4, TEXCOORDFMT_NOT_PRESENT) |
+	    S2_TEXCOORD_FMT(5, TEXCOORDFMT_NOT_PRESENT) |
+	    S2_TEXCOORD_FMT(6, TEXCOORDFMT_NOT_PRESENT) |
+	    S2_TEXCOORD_FMT(7, TEXCOORDFMT_NOT_PRESENT));
    OUT_RING((1 << S4_POINT_WIDTH_SHIFT) | S4_LINE_WIDTH_ONE |
 	    S4_CULLMODE_NONE | S4_VFMT_XY);
    s5 = 0x0;
@@ -148,7 +141,9 @@ I915DisplayVideoTextured(ScrnInfoPtr pSc
 	       (FILTER_LINEAR << SS2_MAG_FILTER_SHIFT) |
 	       (FILTER_LINEAR << SS2_MIN_FILTER_SHIFT));
       OUT_RING((TEXCOORDMODE_CLAMP_EDGE << SS3_TCX_ADDR_MODE_SHIFT) |
-	       (TEXCOORDMODE_CLAMP_EDGE << SS3_TCY_ADDR_MODE_SHIFT));
+	       (TEXCOORDMODE_CLAMP_EDGE << SS3_TCY_ADDR_MODE_SHIFT) |
+	       (0 << SS3_TEXTUREMAP_INDEX_SHIFT) |
+	       SS3_NORMALIZED_COORDS);
       OUT_RING(0x00000000);
 
       OUT_RING(_3DSTATE_MAP_STATE | 3);
@@ -168,7 +163,7 @@ I915DisplayVideoTextured(ScrnInfoPtr pSc
       if (!pI830->disableTiling)
 	 ms3 |= MS3_USE_FENCE_REGS;
       OUT_RING(ms3);
-      OUT_RING(((video_pitch / 4) - 1) << 21);
+      OUT_RING(((video_pitch / 4) - 1) << MS4_PITCH_SHIFT);
       ADVANCE_LP_RING();
 
       FS_BEGIN();
@@ -179,8 +174,7 @@ I915DisplayVideoTextured(ScrnInfoPtr pSc
    } else {
       FS_LOCALS(16);
 
-      BEGIN_LP_RING(1 + 18 + 11 + 11);
-      OUT_RING(MI_NOOP);
+      BEGIN_LP_RING(18 + 11 + 11);
       /* For the planar formats, we set up three samplers -- one for each plane,
        * in a Y8 format.  Because I couldn't get the special PLANAR_TO_PACKED
        * shader setup to work, I did the manual pixel shader:
@@ -226,23 +220,29 @@ I915DisplayVideoTextured(ScrnInfoPtr pSc
       OUT_RING(_3DSTATE_SAMPLER_STATE | 9);
       OUT_RING(0x00000007);
       /* sampler 0 */
-      OUT_RING(0x00000000);
       OUT_RING((FILTER_LINEAR << SS2_MAG_FILTER_SHIFT) |
 	       (FILTER_LINEAR << SS2_MIN_FILTER_SHIFT));
       OUT_RING((TEXCOORDMODE_CLAMP_EDGE << SS3_TCX_ADDR_MODE_SHIFT) |
-	       (TEXCOORDMODE_CLAMP_EDGE << SS3_TCY_ADDR_MODE_SHIFT));
-      /* sampler 1 */
+	       (TEXCOORDMODE_CLAMP_EDGE << SS3_TCY_ADDR_MODE_SHIFT) |
+	       (0 << SS3_TEXTUREMAP_INDEX_SHIFT) |
+	       SS3_NORMALIZED_COORDS);
       OUT_RING(0x00000000);
+      /* sampler 1 */
       OUT_RING((FILTER_LINEAR << SS2_MAG_FILTER_SHIFT) |
 	       (FILTER_LINEAR << SS2_MIN_FILTER_SHIFT));
       OUT_RING((TEXCOORDMODE_CLAMP_EDGE << SS3_TCX_ADDR_MODE_SHIFT) |
-	       (TEXCOORDMODE_CLAMP_EDGE << SS3_TCY_ADDR_MODE_SHIFT));
-      /* sampler 2 */
+	       (TEXCOORDMODE_CLAMP_EDGE << SS3_TCY_ADDR_MODE_SHIFT) |
+	       (1 << SS3_TEXTUREMAP_INDEX_SHIFT) |
+	       SS3_NORMALIZED_COORDS);
       OUT_RING(0x00000000);
+      /* sampler 2 */
       OUT_RING((FILTER_LINEAR << SS2_MAG_FILTER_SHIFT) |
 	       (FILTER_LINEAR << SS2_MIN_FILTER_SHIFT));
       OUT_RING((TEXCOORDMODE_CLAMP_EDGE << SS3_TCX_ADDR_MODE_SHIFT) |
-	       (TEXCOORDMODE_CLAMP_EDGE << SS3_TCY_ADDR_MODE_SHIFT));
+	       (TEXCOORDMODE_CLAMP_EDGE << SS3_TCY_ADDR_MODE_SHIFT) |
+	       (2 << SS3_TEXTUREMAP_INDEX_SHIFT) |
+	       SS3_NORMALIZED_COORDS);
+      OUT_RING(0x00000000);
 
       OUT_RING(_3DSTATE_MAP_STATE | 9);
       OUT_RING(0x00000007);
@@ -251,36 +251,39 @@ I915DisplayVideoTextured(ScrnInfoPtr pSc
       ms3 = MAPSURF_8BIT | MT_8BIT_I8;
       ms3 |= (height - 1) << MS3_HEIGHT_SHIFT;
       ms3 |= (width - 1) << MS3_WIDTH_SHIFT;
+      if (!pI830->disableTiling)
+	 ms3 |= MS3_USE_FENCE_REGS;
       OUT_RING(ms3);
-      OUT_RING(((video_pitch * 2 / 4) - 1) << 21);
+      OUT_RING(((video_pitch * 2 / 4) - 1) << MS4_PITCH_SHIFT);
 
       OUT_RING(pPriv->UBuf0offset);
       ms3 = MAPSURF_8BIT | MT_8BIT_I8;
       ms3 |= (height / 2 - 1) << MS3_HEIGHT_SHIFT;
       ms3 |= (width / 2 - 1) << MS3_WIDTH_SHIFT;
+      if (!pI830->disableTiling)
+	 ms3 |= MS3_USE_FENCE_REGS;
       OUT_RING(ms3);
-      OUT_RING(((video_pitch / 4) - 1) << 21);
+      OUT_RING(((video_pitch / 4) - 1) << MS4_PITCH_SHIFT);
 
       OUT_RING(pPriv->VBuf0offset);
       ms3 = MAPSURF_8BIT | MT_8BIT_I8;
       ms3 |= (height / 2 - 1) << MS3_HEIGHT_SHIFT;
       ms3 |= (width / 2 - 1) << MS3_WIDTH_SHIFT;
+      if (!pI830->disableTiling)
+	 ms3 |= MS3_USE_FENCE_REGS;
       OUT_RING(ms3);
-      OUT_RING(((video_pitch / 4) - 1) << 21);
+      OUT_RING(((video_pitch / 4) - 1) << MS4_PITCH_SHIFT);
       ADVANCE_LP_RING();
 
       FS_BEGIN();
       /* Declare samplers */
-      i915_fs_dcl(FS_S0);
-      i915_fs_dcl(FS_S1);
-      i915_fs_dcl(FS_S2);
-      i915_fs_dcl(FS_T0);
-      i915_fs_dcl(FS_T1);
+      i915_fs_dcl(FS_S0); /* Y */
+      i915_fs_dcl(FS_S1); /* U */
+      i915_fs_dcl(FS_S2); /* V */
+      i915_fs_dcl(FS_T0); /* normalized coords */
 
-      /* Load samplers to temporaries.  Y (sampler 0) gets the un-halved coords-
-       * from t1.
-       */
-      i915_fs_texld(FS_R1, FS_S0, FS_T1);
+      /* Load samplers to temporaries. */
+      i915_fs_texld(FS_R1, FS_S0, FS_T0);
       i915_fs_texld(FS_R2, FS_S1, FS_T0);
       i915_fs_texld(FS_R3, FS_S2, FS_T0);
 
@@ -293,16 +296,17 @@ I915DisplayVideoTextured(ScrnInfoPtr pSc
       i915_fs_add(FS_R0, i915_fs_operand_reg(FS_R0),
                  i915_fs_operand_reg(FS_C0));
       /* dot-product the YUV data in R0 by the vectors of coefficients for
-       * calculating R, G, and B, storing the results in the R, G, or B channels
-       * of the output color.
+       * calculating R, G, and B, storing the results in the R, G, or B
+       * channels of the output color.  The OC results are implicitly clamped
+       * at the end of the program.
        */
-      i915_fs_dp3_masked(FS_OC, MASK_X | MASK_SATURATE,
+      i915_fs_dp3_masked(FS_OC, MASK_X,
                         i915_fs_operand_reg(FS_R0),
                         i915_fs_operand_reg(FS_C1));
-      i915_fs_dp3_masked(FS_OC, MASK_Y | MASK_SATURATE,
+      i915_fs_dp3_masked(FS_OC, MASK_Y,
                         i915_fs_operand_reg(FS_R0),
                         i915_fs_operand_reg(FS_C2));
-      i915_fs_dp3_masked(FS_OC, MASK_Z | MASK_SATURATE,
+      i915_fs_dp3_masked(FS_OC, MASK_Z,
                         i915_fs_operand_reg(FS_R0),
                         i915_fs_operand_reg(FS_C3));
       /* Set alpha of the output to 1.0, by wiring W to 1 and not actually using
@@ -342,19 +346,13 @@ I915DisplayVideoTextured(ScrnInfoPtr pSc
       int box_x2 = pbox->x2;
       int box_y2 = pbox->y2;
       float src_scale_x, src_scale_y;
-      int vert_data_count;
 
       pbox++;
 
-      src_scale_x = (float)src_w / (float)drw_w;
-      src_scale_y  = (float)src_h / (float)drw_h;
-
-      if (!planar)
-	 vert_data_count = 12;
-      else
-	 vert_data_count = 18;
+      src_scale_x = ((float)src_w / width) / drw_w;
+      src_scale_y  = ((float)src_h / height) / drw_h;
 
-      BEGIN_LP_RING(vert_data_count + 8);
+      BEGIN_LP_RING(8 + 12);
       OUT_RING(MI_NOOP);
       OUT_RING(MI_NOOP);
       OUT_RING(MI_NOOP);
@@ -366,47 +364,25 @@ I915DisplayVideoTextured(ScrnInfoPtr pSc
       /* vertex data - rect list consists of bottom right, bottom left, and top
        * left vertices.
        */
-      OUT_RING(PRIM3D_INLINE | PRIM3D_RECTLIST |
-	       (vert_data_count - 1));
+      OUT_RING(PRIM3D_INLINE | PRIM3D_RECTLIST | (12 - 1));
 
       /* bottom right */
       OUT_RING_F(box_x2 + pix_xoff);
       OUT_RING_F(box_y2 + pix_yoff);
-      if (!planar) {
-	 OUT_RING_F((box_x2 - dxo) * src_scale_x);
-	 OUT_RING_F((box_y2 - dyo) * src_scale_y);
-      } else {
-	 OUT_RING_F((box_x2 - dxo) * src_scale_x / 2.0);
-	 OUT_RING_F((box_y2 - dyo) * src_scale_y / 2.0);
-	 OUT_RING_F((box_x2 - dxo) * src_scale_x);
-	 OUT_RING_F((box_y2 - dyo) * src_scale_y);
-      }
+      OUT_RING_F((box_x2 - dxo) * src_scale_x);
+      OUT_RING_F((box_y2 - dyo) * src_scale_y);
 
       /* bottom left */
       OUT_RING_F(box_x1 + pix_xoff);
       OUT_RING_F(box_y2 + pix_yoff);
-      if (!planar) {
-	 OUT_RING_F((box_x1 - dxo) * src_scale_x);
-	 OUT_RING_F((box_y2 - dyo) * src_scale_y);
-      } else {
-	 OUT_RING_F((box_x1 - dxo) * src_scale_x / 2.0);
-	 OUT_RING_F((box_y2 - dyo) * src_scale_y / 2.0);
-	 OUT_RING_F((box_x1 - dxo) * src_scale_x);
-	 OUT_RING_F((box_y2 - dyo) * src_scale_y);
-      }
+      OUT_RING_F((box_x1 - dxo) * src_scale_x);
+      OUT_RING_F((box_y2 - dyo) * src_scale_y);
 
       /* top left */
       OUT_RING_F(box_x1 + pix_xoff);
       OUT_RING_F(box_y1 + pix_yoff);
-      if (!planar) {
-	 OUT_RING_F((box_x1 - dxo) * src_scale_x);
-	 OUT_RING_F((box_y1 - dyo) * src_scale_y);
-      } else {
-	 OUT_RING_F((box_x1 - dxo) * src_scale_x / 2.0);
-	 OUT_RING_F((box_y1 - dyo) * src_scale_y / 2.0);
-	 OUT_RING_F((box_x1 - dxo) * src_scale_x);
-	 OUT_RING_F((box_y1 - dyo) * src_scale_y);
-      }
+      OUT_RING_F((box_x1 - dxo) * src_scale_x);
+      OUT_RING_F((box_y1 - dyo) * src_scale_y);
 
       ADVANCE_LP_RING();
    }
diff-tree 6c29e0bae5f1e7cee02b678418394abb971594eb (from 420e41e7921d3cc07c784fd17936ec8a675f3b20)
Author: Eric Anholt <eric at anholt.net>
Date:   Wed Jun 13 13:40:39 2007 -0700

    Improve the drm_i915_flip_t check.

diff --git a/configure.ac b/configure.ac
index da9fd3f..66992fc 100644
--- a/configure.ac
+++ b/configure.ac
@@ -191,11 +191,14 @@ if test "$DRI" = yes; then
 	fi
 
 	save_CFLAGS="$CFLAGS"
-	CFLAGS="$DRI_CFLAGS"
+	CFLAGS="$XORG_CFLAGS $DRI_CFLAGS"
 	AC_CHECK_TYPE(drm_i915_flip_t,
 		      [AC_DEFINE(HAVE_I915_FLIP, 1,
 			         [Have drm_i915_flip_t and related definitions])],
-		      [], [#include <i915_drm.h>])
+		      [], [
+#include <inttypes.h>
+#include <i915_drm.h>
+])
 	CFLAGS="$save_CFLAGS"
 fi
 
diff-tree 420e41e7921d3cc07c784fd17936ec8a675f3b20 (from 51612e5ac3ddfb2bb172c58f2dfff9631093b69c)
Author: Eric Anholt <eric at anholt.net>
Date:   Wed Jun 13 13:34:26 2007 -0700

    Revert "Replace failure-prone configure test for fresh libdrm with a simple ifndef."
    
    This reverts commit c2b130354aecffbeb2a2d23c7371461feaf5766a.
    
    Sadly, a non-working DRM_IOCTL_I915_FLIP already existed.

diff --git a/configure.ac b/configure.ac
index 53d23ed..da9fd3f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -189,6 +189,14 @@ if test "$DRI" = yes; then
 	if test "$have_damage_h" = yes; then
 		AC_DEFINE(DAMAGE,1,[Use Damage extension])
 	fi
+
+	save_CFLAGS="$CFLAGS"
+	CFLAGS="$DRI_CFLAGS"
+	AC_CHECK_TYPE(drm_i915_flip_t,
+		      [AC_DEFINE(HAVE_I915_FLIP, 1,
+			         [Have drm_i915_flip_t and related definitions])],
+		      [], [#include <i915_drm.h>])
+	CFLAGS="$save_CFLAGS"
 fi
 
 AM_CONDITIONAL(VIDEO_DEBUG, test x$VIDEO_DEBUG = xyes)
diff --git a/src/i830_dri.c b/src/i830_dri.c
index 6ec56cf..ca1190c 100644
--- a/src/i830_dri.c
+++ b/src/i830_dri.c
@@ -83,8 +83,10 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
 
 #include "i915_drm.h"
 
-/* This block can be removed when libdrm >= 2.3.1 is required. */
-#ifndef DRM_IOCTL_I915_FLIP
+/* This block and the corresponding configure test can be removed when
+ * libdrm >= 2.3.1 is required.
+ */
+#ifndef HAVE_I915_FLIP
 
 #define DRM_VBLANK_FLIP 0x8000000
 
diff-tree 51612e5ac3ddfb2bb172c58f2dfff9631093b69c (from ceb6dd72443c094212b0281c42cbe92e9a29f682)
Author: Eric Anholt <eric at anholt.net>
Date:   Tue Jun 12 16:09:54 2007 -0700

    On hang, dump up to the head pointer, not just up to the tail.

diff --git a/src/i830_debug.c b/src/i830_debug.c
index 19eb17a..9354958 100644
--- a/src/i830_debug.c
+++ b/src/i830_debug.c
@@ -666,7 +666,8 @@ i830_dump_ring(ScrnInfoPtr pScrn)
     virt = pI830->LpRing->virtual_start;
     ErrorF ("Ring at virtual 0x%x head 0x%x tail 0x%x count %d\n",
 	    (unsigned int) virt, head, tail, (((tail + mask + 1) - head) & mask) >> 2);
-    for (ring = (head - 128) & mask; ring != tail; ring = (ring + 4) & mask)
+    for (ring = (head - 128) & mask; ring != ((head + 4) & mask);
+	 ring = (ring + 4) & mask)
     {
 	ErrorF ("\t%08x: %08x\n", ring, *(volatile unsigned int *) (virt + ring));
     }
diff-tree ceb6dd72443c094212b0281c42cbe92e9a29f682 (from c2b130354aecffbeb2a2d23c7371461feaf5766a)
Author: Eric Anholt <eric at anholt.net>
Date:   Mon Jun 4 16:37:53 2007 -0700

    Fix context switching between DRI and X.
    
    Now, all 3D pipeline consumers in the driver just call
    IntelEmitInvariantState(), which handles basic state setup, the caching of that
    state setup, and notifying DRI clients.  This also removes a mistaken idle
    wait in the Render code which was papering over the brokenness in the context
    switching.

diff --git a/src/i830.h b/src/i830.h
index e4d5070..8947524 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -307,7 +307,6 @@ typedef struct _I830Rec {
    Rotation rotation;
    void (*PointerMoved)(int, int, int);
    CreateScreenResourcesProcPtr    CreateScreenResources;
-   int *used3D;
 
    i830_memory *logical_context;
 
@@ -527,7 +526,7 @@ typedef struct _I830Rec {
    CARD32 saveSWF[17];
    CARD32 saveBLC_PWM_CTL;
 
-   enum last_3d last_3d;
+   enum last_3d *last_3d;
 
    /** Enables logging of debug output related to mode switching. */
    Bool debug_modes;
diff --git a/src/i830_dri.c b/src/i830_dri.c
index 4746be0..6ec56cf 100644
--- a/src/i830_dri.c
+++ b/src/i830_dri.c
@@ -1196,7 +1196,7 @@ I830DRISwapContext(ScreenPtr pScreen, DR
       if (I810_DEBUG & DEBUG_VERBOSE_DRI)
 	 ErrorF("i830DRISwapContext (in)\n");
 
-      pI830->last_3d = LAST_3D_OTHER;
+      *pI830->last_3d = LAST_3D_OTHER;
 
       if (!pScrn->vtSema)
      	 return;
diff --git a/src/i830_driver.c b/src/i830_driver.c
index 3133d77..7f1fe2c 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -2045,22 +2045,25 @@ I830InitFBManager(
    return ret;
 }
 
-/* Initialize the first context */
+/**
+ * Intialiazes the hardware for the 3D pipeline use in the 2D driver.
+ *
+ * Some state caching is performed to avoid redundant state emits.  This
+ * function is also responsible for marking the state as clobbered for DRI
+ * clients.
+ */
 void
 IntelEmitInvarientState(ScrnInfoPtr pScrn)
 {
    I830Ptr pI830 = I830PTR(pScrn);
    CARD32 ctx_addr;
-#ifdef XF86DRI
-   drmI830Sarea *sarea;
-#endif
 
-   if (pI830->noAccel || !I830IsPrimary(pScrn))
+   if (pI830->noAccel)
       return;
 
 #ifdef XF86DRI
    if (pI830->directRenderingEnabled) {
-      sarea = DRIGetSAREAPrivate(pScrn->pScreen);
+      drmI830Sarea *sarea = DRIGetSAREAPrivate(pScrn->pScreen);
 
       /* Mark that the X Server was the last holder of the context */
       if (sarea)
@@ -2068,6 +2071,12 @@ IntelEmitInvarientState(ScrnInfoPtr pScr
    }
 #endif
 
+   /* If we've emitted our state since the last clobber by another client,
+    * skip it.
+    */
+   if (*pI830->last_3d != LAST_3D_OTHER)
+      return;
+
    ctx_addr = pI830->logical_context->offset;
    assert((pI830->logical_context->offset & 2047) == 0);
    {
@@ -2304,13 +2313,14 @@ I830ScreenInit(int scrnIndex, ScreenPtr 
          pI830->LpRing = xcalloc(1, sizeof(I830RingBuffer));
       if (!pI830->overlayOn)
          pI830->overlayOn = xalloc(sizeof(Bool));
-      if (!pI830->used3D)
-         pI830->used3D = xalloc(sizeof(int));
-      if (!pI830->LpRing || !pI830->overlayOn || !pI830->used3D) {
+      if (!pI830->last_3d)
+         pI830->last_3d = xalloc(sizeof(enum last_3d));
+      if (!pI830->LpRing || !pI830->overlayOn || !pI830->last_3d) {
          xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
 		 "Could not allocate primary data structures.\n");
          return FALSE;
       }
+      *pI830->last_3d = LAST_3D_OTHER;
       *pI830->overlayOn = FALSE;
       if (pI830->entityPrivate)
          pI830->entityPrivate->XvInUse = -1;
@@ -2320,7 +2330,7 @@ I830ScreenInit(int scrnIndex, ScreenPtr 
       pI830->LpRing = pI8301->LpRing;
       pI830->overlay_regs = pI8301->overlay_regs;
       pI830->overlayOn = pI8301->overlayOn;
-      pI830->used3D = pI8301->used3D;
+      pI830->last_3d = pI8301->last_3d;
    }
 
    /* Need MMIO mapped to do GTT lookups during memory allocation. */
@@ -3012,15 +3022,11 @@ I830EnterVT(int scrnIndex, int flags)
     */
    i830SetHotkeyControl(pScrn, HOTKEY_DRIVER_NOTIFY);
 
-   /* Needed for rotation */
-   IntelEmitInvarientState(pScrn);
-
    if (pI830->checkDevices)
       pI830->devicesTimer = TimerSet(NULL, 0, 1000, I830CheckDevicesTimer, pScrn);
 
-   /* Force invarient 3D state to be emitted */
-   *pI830->used3D = 1<<31;
-   pI830->last_3d = LAST_3D_OTHER;
+   /* Mark 3D state as being clobbered */
+   *pI830->last_3d = LAST_3D_OTHER;
 
    return TRUE;
 }
@@ -3111,8 +3117,8 @@ I830CloseScreen(int scrnIndex, ScreenPtr
       pI830->LpRing = NULL;
       xfree(pI830->overlayOn);
       pI830->overlayOn = NULL;
-      xfree(pI830->used3D);
-      pI830->used3D = NULL;
+      xfree(pI830->last_3d);
+      pI830->last_3d = NULL;
    }
 
    pScrn->PointerMoved = pI830->PointerMoved;
diff --git a/src/i830_exa.c b/src/i830_exa.c
index bb60c0a..22618dc 100644
--- a/src/i830_exa.c
+++ b/src/i830_exa.c
@@ -270,22 +270,6 @@ I830EXADoneCopy(PixmapPtr pDstPixmap)
 #endif
 }
 
-void
-i830_enter_render(ScrnInfoPtr pScrn)
-{
-    I830Ptr pI830 = I830PTR(pScrn);
-#ifdef XF86DRI
-    if (pI830->directRenderingEnabled) {
-        drmI830Sarea *pSAREAPriv = DRIGetSAREAPrivate(pScrn->pScreen);
-	pSAREAPriv->ctxOwner = DRIGetContext(pScrn->pScreen);
-    }
-#endif
-    if (pI830->last_3d != LAST_3D_RENDER) {
-	i830WaitSync(pScrn);
-	pI830->last_3d = LAST_3D_RENDER;
-    }
-}
-
 #define xFixedToFloat(val) \
 	((float)xFixedToInt(val) + ((float)xFixedFrac(val) / 65536.0))
 
diff --git a/src/i830_render.c b/src/i830_render.c
index 957953e..90b884f 100644
--- a/src/i830_render.c
+++ b/src/i830_render.c
@@ -400,7 +400,8 @@ i830_prepare_composite(int op, PicturePt
     I830Ptr pI830 = I830PTR(pScrn);
     CARD32 dst_format, dst_offset, dst_pitch;
 
-    i830_enter_render(pScrn);
+    IntelEmitInvarientState(pScrn);
+    *pI830->last_3d = LAST_3D_RENDER;
 
     i830_get_dest_format(pDstPicture, &dst_format);
     dst_offset = intel_get_pixmap_offset(pDst);
diff --git a/src/i915_render.c b/src/i915_render.c
index d5a8579..b2dacfe 100644
--- a/src/i915_render.c
+++ b/src/i915_render.c
@@ -315,7 +315,8 @@ i915_prepare_composite(int op, PicturePt
     CARD32 dst_format, dst_offset, dst_pitch;
     CARD32 blendctl;
 
-    i830_enter_render(pScrn);
+    IntelEmitInvarientState(pScrn);
+    *pI830->last_3d = LAST_3D_RENDER;
 
     i915_get_dest_format(pDstPicture, &dst_format);
     dst_offset = intel_get_pixmap_offset(pDst);
diff --git a/src/i915_video.c b/src/i915_video.c
index e4e0f1a..d02f770 100644
--- a/src/i915_video.c
+++ b/src/i915_video.c
@@ -75,13 +75,8 @@ I915DisplayVideoTextured(ScrnInfoPtr pSc
       break;
    }
 
-   /* Tell the rotation code that we have stomped its invariant state by
-    * setting a high bit.  We don't use any invariant 3D state for video, so we
-    * don't have to worry about it ourselves.
-    */
-   *pI830->used3D |= 1 << 30;
-
-   pI830->last_3d = LAST_3D_VIDEO;
+   IntelEmitInvarientState(pScrn);
+   *pI830->last_3d = LAST_3D_VIDEO;
 
    BEGIN_LP_RING(20);
 
diff --git a/src/i965_render.c b/src/i965_render.c
index 956baf3..e69a939 100644
--- a/src/i965_render.c
+++ b/src/i965_render.c
@@ -404,7 +404,8 @@ i965_prepare_composite(int op, PicturePt
     CARD32 dst_format, dst_offset, dst_pitch;
     Bool rotation_program = FALSE;
 
-    i830_enter_render(pScrn);
+    IntelEmitInvarientState(pScrn);
+    *pI830->last_3d = LAST_3D_RENDER;
 
     src_offset = intel_get_pixmap_offset(pSrc);
     src_pitch = intel_get_pixmap_pitch(pSrc);
diff --git a/src/i965_video.c b/src/i965_video.c
index 17d2006..3084233 100644
--- a/src/i965_video.c
+++ b/src/i965_video.c
@@ -200,20 +200,8 @@ I965DisplayVideoTextured(ScrnInfoPtr pSc
 
     assert((id == FOURCC_UYVY) || (id == FOURCC_YUY2));
 
-    /* Tell the rotation code that we have stomped its invariant state by
-     * setting a high bit.  We don't use any invariant 3D state for video, so
-     * we don't have to worry about it ourselves.
-     */
-    *pI830->used3D |= 1 << 30;
-
-#ifdef XF86DRI
-    /* Tell the DRI that we're smashing its state. */
-    if (pI830->directRenderingEnabled) {
-	drmI830Sarea *pSAREAPriv = DRIGetSAREAPrivate(pScrn->pScreen);
-
-	pSAREAPriv->ctxOwner = DRIGetContext(pScrn->pScreen);
-    }
-#endif /* XF86DRI */
+    IntelEmitInvarientState(pScrn);
+    *pI830->last_3d = LAST_3D_VIDEO;
 
     next_offset = 0;
 
diff-tree c2b130354aecffbeb2a2d23c7371461feaf5766a (from 0e1deb607f94e4aa3ec4b9df8ff7a07a1c95e31d)
Author: Eric Anholt <eric at anholt.net>
Date:   Tue Jun 12 08:49:21 2007 -0700

    Replace failure-prone configure test for fresh libdrm with a simple ifndef.

diff --git a/configure.ac b/configure.ac
index da9fd3f..53d23ed 100644
--- a/configure.ac
+++ b/configure.ac
@@ -189,14 +189,6 @@ if test "$DRI" = yes; then
 	if test "$have_damage_h" = yes; then
 		AC_DEFINE(DAMAGE,1,[Use Damage extension])
 	fi
-
-	save_CFLAGS="$CFLAGS"
-	CFLAGS="$DRI_CFLAGS"
-	AC_CHECK_TYPE(drm_i915_flip_t,
-		      [AC_DEFINE(HAVE_I915_FLIP, 1,
-			         [Have drm_i915_flip_t and related definitions])],
-		      [], [#include <i915_drm.h>])
-	CFLAGS="$save_CFLAGS"
 fi
 
 AM_CONDITIONAL(VIDEO_DEBUG, test x$VIDEO_DEBUG = xyes)
diff --git a/src/i830_dri.c b/src/i830_dri.c
index a17770b..4746be0 100644
--- a/src/i830_dri.c
+++ b/src/i830_dri.c
@@ -83,10 +83,8 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
 
 #include "i915_drm.h"
 
-/* This block and the corresponding configure test can be removed when
- * libdrm >= 2.3.1 is required.
- */
-#ifndef HAVE_I915_FLIP
+/* This block can be removed when libdrm >= 2.3.1 is required. */
+#ifndef DRM_IOCTL_I915_FLIP
 
 #define DRM_VBLANK_FLIP 0x8000000
 
diff-tree 0e1deb607f94e4aa3ec4b9df8ff7a07a1c95e31d (from 8d7a0ccd4f674659eb781def2cfdc3a6e5a219ce)
Author: Eric Anholt <eric at anholt.net>
Date:   Mon Jun 11 17:33:33 2007 -0700

    Fix a typo in _3DSTATE_DEPTH_SUBRECT_DISABLE definition.
    
    This is already fixed in the definition in the 3d driver.

diff --git a/src/i915_reg.h b/src/i915_reg.h
index 6751de6..6b40d70 100644
--- a/src/i915_reg.h
+++ b/src/i915_reg.h
@@ -133,9 +133,9 @@
 #define _3DSTATE_DEPTH_OFFSET_SCALE       (CMD_3D | (0x1d<<24) | (0x97<<16))
 /* scale in dword 1 */
 
-
+/* The depth subrectangle is not supported, but must be disabled. */
 /* 3DSTATE_DEPTH_SUBRECT_DISABLE, p160 */
-#define _3DSTATE_DEPTH_SUBRECT_DISABLE    (CMD_3D | (0x1c<<24) | (0x11<19) | 0x2)
+#define _3DSTATE_DEPTH_SUBRECT_DISABLE	(CMD_3D | (0x1c<<24) | (0x11<<19) | (1 << 1) | (0 << 0))
 
 /* p161 */
 #define _3DSTATE_DST_BUF_VARS_CMD	(CMD_3D | (0x1d<<24) | (0x85<<16))
diff-tree 8d7a0ccd4f674659eb781def2cfdc3a6e5a219ce (from 15caa64a497dcc0eacb0f91166d9b70206a8db35)
Author: Eric Anholt <eric at anholt.net>
Date:   Mon Jun 11 17:33:07 2007 -0700

    Clean up some nits in i915_video.c setup.
    
    - The screen dimensions were used for the clipping despite drawing being done
      to any pixmap, not necessarily the screen.
    - One piece of state setup was not documented anywhere, and isn't used in other
      3d hardware paths that also work.
    - A 3DSTATE_MODES_1 command (830-class only) was issued even though it no
      longer exists.

diff --git a/src/i915_video.c b/src/i915_video.c
index e837097..e4e0f1a 100644
--- a/src/i915_video.c
+++ b/src/i915_video.c
@@ -83,7 +83,7 @@ I915DisplayVideoTextured(ScrnInfoPtr pSc
 
    pI830->last_3d = LAST_3D_VIDEO;
 
-   BEGIN_LP_RING(24);
+   BEGIN_LP_RING(20);
 
    /* flush map & render cache */
    OUT_RING(MI_FLUSH | MI_WRITE_DIRTY_STATE | MI_INVALIDATE_MAP_CACHE);
@@ -94,16 +94,11 @@ I915DisplayVideoTextured(ScrnInfoPtr pSc
    OUT_RING(DRAW_DITHER_OFS_X(pPixmap->drawable.x & 3) |
 	    DRAW_DITHER_OFS_Y(pPixmap->drawable.y & 3));
    OUT_RING(0x00000000);	/* ymin, xmin */
-   OUT_RING((pScrn->virtualX - 1) |
-	    (pScrn->virtualY - 1) << 16); /* ymax, xmax */
+   OUT_RING((pPixmap->drawable.width - 1) |
+	    (pPixmap->drawable.height - 1) << 16); /* ymax, xmax */
    OUT_RING(0x00000000);	/* yorigin, xorigin */
    OUT_RING(MI_NOOP);
 
-   OUT_RING(0x7c000003);	/* unknown command */
-   OUT_RING(0x7d070000);
-   OUT_RING(0x00000000);
-   OUT_RING(0x68000002);
-
    OUT_RING(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(2) |
 	    I1_LOAD_S(4) | I1_LOAD_S(5) | I1_LOAD_S(6) | 3);
    s2 = S2_TEXCOORD_FMT(0, TEXCOORDFMT_2D);
diff-tree 15caa64a497dcc0eacb0f91166d9b70206a8db35 (from 404fd47573f855b0442d49a383542fc093825ad0)
Author: Keith Packard <keithp at neko.keithp.com>
Date:   Fri Jun 8 18:44:28 2007 -0700

    Add description for how to use the frame and pixel counter registers.
    
    The 24-bit frame and pixel counters were not described in detail and
    will be useful for DRM.

diff --git a/src/i810_reg.h b/src/i810_reg.h
index 8df664e..6001297 100644
--- a/src/i810_reg.h
+++ b/src/i810_reg.h
@@ -1967,9 +1967,30 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN
 #define DSPFW1			0x70034
 #define DSPFW2			0x70038
 #define DSPFW3			0x7003c
+/*
+ * The two pipe frame counter registers are not synchronized, so
+ * reading a stable value is somewhat tricky. The following code 
+ * should work:
+ *
+ *  do {
+ *    high1 = ((INREG(PIPEAFRAMEHIGH) & PIPE_FRAME_HIGH_MASK) >> PIPE_FRAME_HIGH_SHIFT;
+ *    low1 =  ((INREG(PIPEAFRAMEPIXEL) & PIPE_FRAME_LOW_MASK) >> PIPE_FRAME_LOW_SHIFT);
+ *    high2 = ((INREG(PIPEAFRAMEHIGH) & PIPE_FRAME_HIGH_MASK) >> PIPE_FRAME_HIGH_SHIFT);
+ *  } while (high1 != high2);
+ *  frame = (high1 << 8) | low1;
+ */
 #define PIPEAFRAMEHIGH		0x70040
+#define PIPE_FRAME_HIGH_MASK	0x0000ffff
+#define PIPE_FRAME_HIGH_SHIFT	0
 #define PIPEAFRAMEPIXEL		0x70044
-
+#define PIPE_FRAME_LOW_MASK	0xff000000
+#define PIPE_FRAME_LOW_SHIFT	24
+/*
+ * Pixel within the current frame is counted in the PIPEAFRAMEPIXEL register
+ * and is 24 bits wide.
+ */
+#define PIPE_PIXEL_MASK		0x00ffffff
+#define PIPE_PIXEL_SHIFT	0
 
 #define PIPEB_DSL		0x71000
 
diff-tree 404fd47573f855b0442d49a383542fc093825ad0 (from f4c05973d391bdb0a9b0eadb155548310baa98fd)
Author: Wang Zhenyu <zhenyu.z.wang at intel.com>
Date:   Wed Jun 6 11:01:48 2007 +0800

    Enable overlay on G33 class chipsets
    
    Which have to use gfx vm offset fot setup overlay regs.

diff --git a/src/common.h b/src/common.h
index 2369a75..cc07e49 100644
--- a/src/common.h
+++ b/src/common.h
@@ -399,6 +399,8 @@ extern int I810_DEBUG;
 #define IS_I9XX(pI810) (IS_I915G(pI810) || IS_I915GM(pI810) || IS_I945G(pI810) || IS_I945GM(pI810) || IS_I965G(pI810) || IS_G33CLASS(pI810))
 
 #define IS_MOBILE(pI810) (IS_I830(pI810) || IS_I85X(pI810) || IS_I915GM(pI810) || IS_I945GM(pI810) || IS_I965GM(pI810))
+/* mark chipsets for using gfx VM offset for overlay */
+#define OVERLAY_NOPHYSICAL(pI810) (IS_G33CLASS(pI810))
 
 #define GTT_PAGE_SIZE			KB(4)
 #define ROUND_TO(x, y)			(((x) + (y) - 1) / (y) * (y))
diff --git a/src/i830_memory.c b/src/i830_memory.c
index 747cfcc..17d4c4e 100644
--- a/src/i830_memory.c
+++ b/src/i830_memory.c
@@ -747,15 +747,19 @@ static Bool
 i830_allocate_overlay(ScrnInfoPtr pScrn)
 {
     I830Ptr pI830 = I830PTR(pScrn);
+    int flags = NEED_PHYSICAL_ADDR;
 
     /* Only allocate if overlay is going to be enabled. */
     if (!pI830->XvEnabled)
 	return TRUE;
 
+    if (OVERLAY_NOPHYSICAL(pI830))
+	flags = 0;
+
     if (!IS_I965G(pI830)) {
 	pI830->overlay_regs = i830_allocate_memory(pScrn, "overlay registers",
 						   OVERLAY_SIZE, GTT_PAGE_SIZE,
-						   NEED_PHYSICAL_ADDR);
+						   flags);
 	if (pI830->overlay_regs == NULL) {
 	    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
 		       "Failed to allocate Overlay register space.\n");
diff --git a/src/i830_video.c b/src/i830_video.c
index e5efcaa..c1ddc98 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -428,7 +428,10 @@ i830_overlay_on(ScrnInfoPtr pScrn)
     OUT_RING(MI_FLUSH | MI_WRITE_DIRTY_STATE);
     OUT_RING(MI_NOOP);
     OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_FLIP_ON);
-    OUT_RING(pI830->overlay_regs->bus_addr | OFC_UPDATE);
+    if (OVERLAY_NOPHYSICAL(pI830))
+	OUT_RING(pI830->overlay_regs->offset | OFC_UPDATE);
+    else
+	OUT_RING(pI830->overlay_regs->bus_addr | OFC_UPDATE);
     /* Wait for the overlay to light up before attempting to use it */
     OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
     OUT_RING(MI_NOOP);
@@ -458,7 +461,10 @@ i830_overlay_continue(ScrnInfoPtr pScrn,
     if (!*pI830->overlayOn)
 	return;
 
-    flip_addr = pI830->overlay_regs->bus_addr;
+    if (OVERLAY_NOPHYSICAL(pI830))
+	flip_addr = pI830->overlay_regs->offset;
+    else
+	flip_addr = pI830->overlay_regs->bus_addr;
     if (update_filter)
 	flip_addr |= OFC_UPDATE;
     OVERLAY_DEBUG ("overlay_continue cmd 0x%08lx -> 0x%08lx sta 0x%08lx\n",
@@ -507,7 +513,10 @@ i830_overlay_off(ScrnInfoPtr pScrn)
 	OUT_RING(MI_FLUSH | MI_WRITE_DIRTY_STATE);
 	OUT_RING(MI_NOOP);
 	OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_FLIP_CONTINUE);
-	OUT_RING(pI830->overlay_regs->bus_addr);
+	if (OVERLAY_NOPHYSICAL(pI830))
+	    OUT_RING(pI830->overlay_regs->offset);
+	else
+	    OUT_RING(pI830->overlay_regs->bus_addr);
 	OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
 	OUT_RING(MI_NOOP);
 	ADVANCE_LP_RING();
@@ -572,7 +581,7 @@ I830InitVideo(ScreenPtr pScreen)
     }
 
     /* Set up overlay video if we can do it at this depth. */
-    if (!IS_I965G(pI830) && !IS_G33CLASS(pI830) && pScrn->bitsPerPixel != 8 &&
+    if (!IS_I965G(pI830) && pScrn->bitsPerPixel != 8 &&
 	pI830->overlay_regs != NULL)
     {
 	overlayAdaptor = I830SetupImageVideoOverlay(pScreen);
diff-tree f4c05973d391bdb0a9b0eadb155548310baa98fd (from 36fcaeb2ef94db5399071540bba106dec3db81d5)
Author: Wang Zhenyu <zhenyu.z.wang at intel.com>
Date:   Tue Jun 5 11:07:41 2007 -0700

    Add support for the G33, Q33, and Q35 chipsets.
    
    These chipsets require that the hardware status page be referenced by an offset
    in the GTT rather than a physical memory address, so the X Server allocates it
    rather than the DRM.

diff --git a/src/common.h b/src/common.h
index c879333..2369a75 100644
--- a/src/common.h
+++ b/src/common.h
@@ -361,6 +361,21 @@ extern int I810_DEBUG;
 #define PCI_CHIP_I965_GM_BRIDGE 0x2A00
 #endif
 
+#ifndef PCI_CHIP_G33_G
+#define PCI_CHIP_G33_G		0x29C2
+#define PCI_CHIP_G33_G_BRIDGE 	0x29C0
+#endif
+
+#ifndef PCI_CHIP_Q35_G
+#define PCI_CHIP_Q35_G		0x29B2
+#define PCI_CHIP_Q35_G_BRIDGE 	0x29B0
+#endif
+
+#ifndef PCI_CHIP_Q33_G
+#define PCI_CHIP_Q33_G		0x29D2
+#define PCI_CHIP_Q33_G_BRIDGE 	0x29D0
+#endif
+
 #define IS_I810(pI810) (pI810->PciInfo->chipType == PCI_CHIP_I810 ||	\
 			pI810->PciInfo->chipType == PCI_CHIP_I810_DC100 || \
 			pI810->PciInfo->chipType == PCI_CHIP_I810_E)
@@ -378,7 +393,10 @@ extern int I810_DEBUG;
 #define IS_I945GM(pI810) (pI810->PciInfo->chipType == PCI_CHIP_I945_GM || pI810->PciInfo->chipType == PCI_CHIP_I945_GME)
 #define IS_I965GM(pI810) (pI810->PciInfo->chipType == PCI_CHIP_I965_GM || pI810->PciInfo->chipType == PCI_CHIP_I965_GME)
 #define IS_I965G(pI810) (pI810->PciInfo->chipType == PCI_CHIP_I965_G || pI810->PciInfo->chipType == PCI_CHIP_I965_G_1 || pI810->PciInfo->chipType == PCI_CHIP_I965_Q || pI810->PciInfo->chipType == PCI_CHIP_I946_GZ || pI810->PciInfo->chipType == PCI_CHIP_I965_GM || pI810->PciInfo->chipType == PCI_CHIP_I965_GME)
-#define IS_I9XX(pI810) (IS_I915G(pI810) || IS_I915GM(pI810) || IS_I945G(pI810) || IS_I945GM(pI810) || IS_I965G(pI810))
+#define IS_G33CLASS(pI810) (pI810->PciInfo->chipType == PCI_CHIP_G33_G ||\
+ 			    pI810->PciInfo->chipType == PCI_CHIP_Q35_G ||\
+ 			    pI810->PciInfo->chipType == PCI_CHIP_Q33_G)
+#define IS_I9XX(pI810) (IS_I915G(pI810) || IS_I915GM(pI810) || IS_I945G(pI810) || IS_I945GM(pI810) || IS_I965G(pI810) || IS_G33CLASS(pI810))
 
 #define IS_MOBILE(pI810) (IS_I830(pI810) || IS_I85X(pI810) || IS_I915GM(pI810) || IS_I945GM(pI810) || IS_I965GM(pI810))
 
diff --git a/src/i810_driver.c b/src/i810_driver.c
index 5b04a47..972b6d5 100644
--- a/src/i810_driver.c
+++ b/src/i810_driver.c
@@ -147,6 +147,9 @@ static SymTabRec I810Chipsets[] = {
    {PCI_CHIP_I946_GZ,		"946GZ"},
    {PCI_CHIP_I965_GM,		"965GM"},
    {PCI_CHIP_I965_GME,		"965GME/GLE"},
+   {PCI_CHIP_G33_G,		"G33"},
+   {PCI_CHIP_Q35_G,		"Q35"},
+   {PCI_CHIP_Q33_G,		"Q33"},
    {-1,				NULL}
 };
 
@@ -173,6 +176,9 @@ static PciChipsets I810PciChipsets[] = {
    {PCI_CHIP_I946_GZ,		PCI_CHIP_I946_GZ,	RES_SHARED_VGA},
    {PCI_CHIP_I965_GM,		PCI_CHIP_I965_GM,	RES_SHARED_VGA},
    {PCI_CHIP_I965_GME,		PCI_CHIP_I965_GME,	RES_SHARED_VGA},
+   {PCI_CHIP_G33_G,		PCI_CHIP_G33_G,		RES_SHARED_VGA},
+   {PCI_CHIP_Q35_G,		PCI_CHIP_Q35_G,		RES_SHARED_VGA},
+   {PCI_CHIP_Q33_G,		PCI_CHIP_Q33_G,		RES_SHARED_VGA},
    {-1,				-1, RES_UNDEFINED }
 };
 
@@ -620,6 +626,9 @@ I810Probe(DriverPtr drv, int flags)
 	    case PCI_CHIP_I946_GZ:
 	    case PCI_CHIP_I965_GM:
 	    case PCI_CHIP_I965_GME:
+ 	    case PCI_CHIP_G33_G:
+ 	    case PCI_CHIP_Q35_G:
+ 	    case PCI_CHIP_Q33_G:
     	       xf86SetEntitySharable(usedChips[i]);
 
     	       /* Allocate an entity private if necessary */		
diff --git a/src/i810_reg.h b/src/i810_reg.h
index 234d124..8df664e 100644
--- a/src/i810_reg.h
+++ b/src/i810_reg.h
@@ -525,6 +525,9 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN
 #define PGETBL_SIZE_512KB   (0 << 1)
 #define PGETBL_SIZE_256KB   (1 << 1)
 #define PGETBL_SIZE_128KB   (2 << 1)
+#define G33_PGETBL_SIZE_MASK		(3 << 8)
+#define G33_PGETBL_SIZE_1M		(1 << 8)
+#define G33_PGETBL_SIZE_2M		(2 << 8)
 
 #define I830_PTE_BASE			0x10000
 #define PTE_ADDRESS_MASK		0xfffff000
@@ -2076,12 +2079,12 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN
 #define I830_GMCH_MEM_64M	0x1
 #define I830_GMCH_MEM_128M	0
 
-#define I830_GMCH_GMS_MASK			0x70
-#define I830_GMCH_GMS_DISABLED		0x00
+#define I830_GMCH_GMS_MASK			0xF0
+#define I830_GMCH_GMS_DISABLED			0x00
 #define I830_GMCH_GMS_LOCAL			0x10
-#define I830_GMCH_GMS_STOLEN_512	0x20
-#define I830_GMCH_GMS_STOLEN_1024	0x30
-#define I830_GMCH_GMS_STOLEN_8192	0x40
+#define I830_GMCH_GMS_STOLEN_512		0x20
+#define I830_GMCH_GMS_STOLEN_1024		0x30
+#define I830_GMCH_GMS_STOLEN_8192		0x40
 
 #define I830_RDRAM_CHANNEL_TYPE		0x03010
 #define I830_RDRAM_ND(x)			(((x) & 0x20) >> 5)
@@ -2096,6 +2099,8 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN
 #define I855_GMCH_GMS_STOLEN_32M		(0x5 << 4)
 #define I915G_GMCH_GMS_STOLEN_48M		(0x6 << 4)
 #define I915G_GMCH_GMS_STOLEN_64M		(0x7 << 4)
+#define G33_GMCH_GMS_STOLEN_128M		(0x8 << 4)
+#define G33_GMCH_GMS_STOLEN_256M		(0x9 << 4)
 
 #define I85X_CAPID			0x44
 #define I85X_VARIANT_MASK			0x7
diff --git a/src/i830.h b/src/i830.h
index 76cc6e8..e4d5070 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -319,6 +319,7 @@ typedef struct _I830Rec {
    i830_memory *depth_buffer;
    i830_memory *textures;		/**< Compatibility texture memory */
    i830_memory *memory_manager;		/**< DRI memory manager aperture */
+   i830_memory *hw_status;		/* for G33 hw status page alloc */
 
    int TexGranularity;
    int drmMinor;
diff --git a/src/i830_common.h b/src/i830_common.h
index f853ccd..5c2d919 100644
--- a/src/i830_common.h
+++ b/src/i830_common.h
@@ -54,6 +54,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
 #define DRM_I830_DESTROY_HEAP             0x0c
 #define DRM_I830_SET_VBLANK_PIPE	  0x0d
 #define DRM_I830_GET_VBLANK_PIPE	  0x0e
+#define DRM_I830_HWS_PAGE_ADDR		  0x11
 
 
 typedef struct {
@@ -224,4 +225,8 @@ typedef struct {
 	int pipe;
 } drmI830VBlankPipe;
 
+typedef struct {
+	uint64_t addr;
+} drmI830HWS;
+
 #endif /* _I830_DRM_H_ */
diff --git a/src/i830_dri.c b/src/i830_dri.c
index 663ef14..a17770b 100644
--- a/src/i830_dri.c
+++ b/src/i830_dri.c
@@ -232,6 +232,22 @@ I830SetParam(ScrnInfoPtr pScrn, int para
    return TRUE;
 }
 
+static Bool
+I830SetHWS(ScrnInfoPtr pScrn, int addr)
+{
+    I830Ptr pI830 = I830PTR(pScrn);
+    drmI830HWS hws;
+
+    hws.addr = addr;
+
+    if (drmCommandWrite(pI830->drmSubFD, DRM_I830_HWS_PAGE_ADDR,
+		&hws, sizeof(drmI830HWS))) {
+	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+		"G33 status page initialization Failed\n");
+	return FALSE;
+    }
+    return TRUE;
+}
 
 static Bool
 I830InitVisualConfigs(ScreenPtr pScreen)
@@ -933,6 +949,12 @@ I830DRIDoMappings(ScreenPtr pScreen)
       return FALSE;
    }
 
+   if (IS_G33CLASS(pI830)) {
+       if (!I830SetHWS(pScrn, pI830->hw_status->offset)) {
+	   DRICloseScreen(pScreen);
+	   return FALSE;
+       }
+   }
    /* init to zero to be safe */
    sarea->front_handle = 0;
    sarea->back_handle = 0;
diff --git a/src/i830_driver.c b/src/i830_driver.c
index 1290d6d..3133d77 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -236,6 +236,9 @@ static SymTabRec I830Chipsets[] = {
    {PCI_CHIP_I946_GZ,		"946GZ"},
    {PCI_CHIP_I965_GM,		"965GM"},
    {PCI_CHIP_I965_GME,		"965GME/GLE"},
+   {PCI_CHIP_G33_G,		"G33"},
+   {PCI_CHIP_Q35_G,		"Q35"},
+   {PCI_CHIP_Q33_G,		"Q33"},
    {-1,				NULL}
 };
 
@@ -256,6 +259,9 @@ static PciChipsets I830PciChipsets[] = {
    {PCI_CHIP_I946_GZ,		PCI_CHIP_I946_GZ,	RES_SHARED_VGA},
    {PCI_CHIP_I965_GM,		PCI_CHIP_I965_GM,	RES_SHARED_VGA},
    {PCI_CHIP_I965_GME,		PCI_CHIP_I965_GME,	RES_SHARED_VGA},
+   {PCI_CHIP_G33_G,		PCI_CHIP_G33_G,		RES_SHARED_VGA},
+   {PCI_CHIP_Q35_G,		PCI_CHIP_Q35_G,		RES_SHARED_VGA},
+   {PCI_CHIP_Q33_G,		PCI_CHIP_Q33_G,		RES_SHARED_VGA},
    {-1,				-1,			RES_UNDEFINED}
 };
 
@@ -436,6 +442,19 @@ I830DetectMemory(ScrnInfoPtr pScrn)
       default:
 	 FatalError("Unknown GTT size value: %08x\n", (int)INREG(PGETBL_CTL));
       }
+   } else if (IS_G33CLASS(pI830)) {
+      /* G33's GTT size is detect in GMCH_CTRL */
+      switch (gmch_ctrl & G33_PGETBL_SIZE_MASK) {
+      case G33_PGETBL_SIZE_1M:
+	 gtt_size = 1024;
+	 break;
+      case G33_PGETBL_SIZE_2M:
+	 gtt_size = 2048;
+	 break;
+      default:
+	 FatalError("Unknown GTT size value: %08x\n",
+		    (int)(gmch_ctrl & G33_PGETBL_SIZE_MASK));
+      }
    } else {
       /* Older chipsets only had GTT appropriately sized for the aperture. */
       gtt_size = pI830->FbMapSize / (1024*1024);
@@ -473,6 +492,14 @@ I830DetectMemory(ScrnInfoPtr pScrn)
 	 if (IS_I9XX(pI830))
 	    memsize = MB(64) - KB(range);
 	 break;
+      case G33_GMCH_GMS_STOLEN_128M:
+	 if (IS_G33CLASS(pI830))
+	     memsize = MB(128) - KB(range);
+	 break;
+      case G33_GMCH_GMS_STOLEN_256M:
+	 if (IS_G33CLASS(pI830))
+	     memsize = MB(256) - KB(range);
+	 break;
       }
    } else {
       switch (gmch_ctrl & I830_GMCH_GMS_MASK) {
@@ -1076,6 +1103,15 @@ I830PreInit(ScrnInfoPtr pScrn, int flags
    case PCI_CHIP_I965_GME:
       chipname = "965GME/GLE";
       break;
+   case PCI_CHIP_G33_G:
+      chipname = "G33";
+      break;
+   case PCI_CHIP_Q35_G:
+      chipname = "Q35";
+      break;
+   case PCI_CHIP_Q33_G:
+      chipname = "Q33";
+      break;
    default:
       chipname = "unknown chipset";
       break;
@@ -1430,7 +1466,7 @@ I830PreInit(ScrnInfoPtr pScrn, int flags
    else
       pI830->CursorNeedsPhysical = FALSE;
 
-   if (IS_I965G(pI830))
+   if (IS_I965G(pI830) || IS_G33CLASS(pI830))
       pI830->CursorNeedsPhysical = FALSE;
 
    /*
diff --git a/src/i830_exa.c b/src/i830_exa.c
index 88d1b97..bb60c0a 100644
--- a/src/i830_exa.c
+++ b/src/i830_exa.c
@@ -509,7 +509,7 @@ I830EXAInit(ScreenPtr pScreen)
     	pI830->EXADriverPtr->Composite = i830_composite;
     	pI830->EXADriverPtr->DoneComposite = i830_done_composite;
     } else if (IS_I915G(pI830) || IS_I915GM(pI830) ||
-	       IS_I945G(pI830) || IS_I945GM(pI830))
+	       IS_I945G(pI830) || IS_I945GM(pI830) || IS_G33CLASS(pI830))
     {
 	pI830->EXADriverPtr->CheckComposite = i915_check_composite;
    	pI830->EXADriverPtr->PrepareComposite = i915_prepare_composite;
diff --git a/src/i830_memory.c b/src/i830_memory.c
index 3ae10cf..747cfcc 100644
--- a/src/i830_memory.c
+++ b/src/i830_memory.c
@@ -1312,6 +1312,22 @@ i830_allocate_texture_memory(ScrnInfoPtr
     return TRUE;
 }
 
+static Bool
+i830_allocate_hwstatus(ScrnInfoPtr pScrn)
+{
+#define HWSTATUS_PAGE_SIZE (4*1024)
+    I830Ptr pI830 = I830PTR(pScrn);
+
+    pI830->hw_status = i830_allocate_memory(pScrn, "G33 hw status",
+	    HWSTATUS_PAGE_SIZE, GTT_PAGE_SIZE, 0);
+    if (pI830->hw_status == NULL) {
+	xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+		"Failed to allocate hw status page for G33.\n");
+	return FALSE;
+    }
+    return TRUE;
+}
+
 Bool
 i830_allocate_3d_memory(ScrnInfoPtr pScrn)
 {
@@ -1319,6 +1335,11 @@ i830_allocate_3d_memory(ScrnInfoPtr pScr
 
     DPRINTF(PFX, "i830_allocate_3d_memory\n");
 
+    if (IS_G33CLASS(pI830)) {
+	if (!i830_allocate_hwstatus(pScrn))
+	    return FALSE;
+    }
+
     if (!i830_allocate_backbuffer(pScrn, &pI830->back_buffer,
 				  &pI830->back_tiled, "back buffer"))
 	return FALSE;
diff --git a/src/i830_video.c b/src/i830_video.c
index b8726a8..e5efcaa 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -572,7 +572,7 @@ I830InitVideo(ScreenPtr pScreen)
     }
 
     /* Set up overlay video if we can do it at this depth. */
-    if (!IS_I965G(pI830) && pScrn->bitsPerPixel != 8 &&
+    if (!IS_I965G(pI830) && !IS_G33CLASS(pI830) && pScrn->bitsPerPixel != 8 &&
 	pI830->overlay_regs != NULL)
     {
 	overlayAdaptor = I830SetupImageVideoOverlay(pScreen);
diff-tree 36fcaeb2ef94db5399071540bba106dec3db81d5 (from 8a19e7d57bc23dd163b45e0ab7deca4f074c934d)
Author: Eric Anholt <eric at anholt.net>
Date:   Mon Jun 4 15:58:31 2007 -0700

    Fix misplaced merge of 1280x768 panel fixup.

diff --git a/src/i830_lvds.c b/src/i830_lvds.c
index ecc91aa..ee278aa 100644
--- a/src/i830_lvds.c
+++ b/src/i830_lvds.c
@@ -496,7 +496,16 @@ i830_lvds_init(ScrnInfoPtr pScrn)
 	    dev_priv->panel_fixed_mode = i830_crtc_mode_get(pScrn, crtc);
 	    if (dev_priv->panel_fixed_mode != NULL)
 		dev_priv->panel_fixed_mode->type |= M_T_PREFERRED;
+	}
+    }
 
+    /* Get the LVDS fixed mode out of the BIOS.  We should support LVDS with
+     * the BIOS being unavailable or broken, but lack the configuration options
+     * for now.
+     */
+    bios_mode = i830_bios_get_panel_mode(pScrn, &dev_priv->panel_wants_dither);
+    if (bios_mode != NULL) {
+	if (dev_priv->panel_fixed_mode != NULL) {
 	    /* Fixup for a 1280x768 panel with the horizontal trimmed
 	     * down to 1024 for text mode.
 	     */
@@ -512,16 +521,7 @@ i830_lvds_init(ScrnInfoPtr pScrn)
 		dev_priv->panel_fixed_mode->HSyncEnd = 1440;
 		dev_priv->panel_fixed_mode->HTotal = 1688;
 	    }
-	}
-    }
 
-    /* Get the LVDS fixed mode out of the BIOS.  We should support LVDS with
-     * the BIOS being unavailable or broken, but lack the configuration options
-     * for now.
-     */
-    bios_mode = i830_bios_get_panel_mode(pScrn, &dev_priv->panel_wants_dither);
-    if (bios_mode != NULL) {
-	if (dev_priv->panel_fixed_mode != NULL) {
 	    if (pI830->debug_modes &&
 		!xf86ModesEqual(dev_priv->panel_fixed_mode, bios_mode))
 	    {
diff-tree 8a19e7d57bc23dd163b45e0ab7deca4f074c934d (from e986f6cb62f8644c5fa835bd7dfb7b014c2677c5)
Author: Keith Packard <keithp at dulcimer.keithp.com>
Date:   Tue Jun 5 00:09:57 2007 -0700

    Always ensure the pipe A is lit when activating overlay on pipe B.
    
    Ok, so moving video from pipe A to pipe B still requires that pipe A be
    active during the transition. Instead of trying to be fancy, just ensure
    that pipe A is running on each transition to pipe B.

diff --git a/src/i830_video.c b/src/i830_video.c
index 382b1eb..b8726a8 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -416,18 +416,12 @@ i830_overlay_on(ScrnInfoPtr pScrn)
 	return;
 
     /*
-     * On I830, if pipe A is off the first time the overlay
-     * is enabled, it will fail to turn and blank the entire 
-     * screen. Light up pipe A in this case to provide a clock
-     * for the overlay hardware
+     * On I830, if pipe A is off when the overlayis enabled, it will fail to
+     * turn on and blank the entire screen or lock up the ring. Light up pipe
+     * A in this case to provide a clock for the overlay hardware
      */
-    if (pPriv->current_crtc && 
-	i830_crtc_pipe (pPriv->current_crtc) != 0 &&
-	!pPriv->started_video)
-    {
-	pPriv->started_video = TRUE;
+    if (pPriv->current_crtc && i830_crtc_pipe (pPriv->current_crtc) != 0)
 	deactivate = i830_pipe_a_require_activate (pScrn);
-    }
 
     overlay->OCMD &= ~OVERLAY_ENABLE;
     BEGIN_LP_RING(6);
diff --git a/src/i830_video.h b/src/i830_video.h
index 88a7bd9..7e2d149 100644
--- a/src/i830_video.h
+++ b/src/i830_video.h
@@ -77,7 +77,6 @@ typedef struct {
    int oneLineMode;
    int scaleRatio;
    Bool textured;
-   Bool started_video;
 } I830PortPrivRec, *I830PortPrivPtr;
 
 #define GET_PORT_PRIVATE(pScrn) \
diff-tree e986f6cb62f8644c5fa835bd7dfb7b014c2677c5 (from 0984c1fc0963f1ebab31f5b8fce5ad4c387fbd2c)
Author: Keith Packard <keithp at dulcimer.keithp.com>
Date:   Mon Jun 4 23:52:23 2007 -0700

    Automatically switch overlay when crtcs are reconfigured.
    
    As crtcs are disabled and enabled, make sure the automatic crtc selection
    mechanism drives overlay configuration at each request to display an image.

diff --git a/src/i830_video.c b/src/i830_video.c
index 155bcc1..382b1eb 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -345,27 +345,55 @@ CompareOverlay(I830Ptr pI830, CARD32 * o
 }
 #endif
 
-static int
-I830CrtcPipe (xf86CrtcPtr crtc)
-{
-    if (crtc == NULL)
-	return 0;
-    return ((I830CrtcPrivatePtr) crtc->driver_private)->pipe;
-}
+static void
+I830SetOneLineModeRatio(ScrnInfoPtr pScrn);
 
-static xf86CrtcPtr
-I830CrtcForPipe (ScrnInfoPtr pScrn, int pipe)
+static void
+i830_overlay_switch_to_crtc (ScrnInfoPtr pScrn, xf86CrtcPtr crtc)
 {
-    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
-    int			c;
+    I830Ptr		pI830 = I830PTR(pScrn);
+    I830PortPrivPtr	pPriv = GET_PORT_PRIVATE(pScrn);
+    I830CrtcPrivatePtr  intel_crtc = crtc->driver_private;
+    int			pipeconf_reg = intel_crtc->pipe == 0 ? PIPEACONF : PIPEBCONF;
 
-    for (c = 0; c < xf86_config->num_crtc; c++)
+    if (INREG(pipeconf_reg) & PIPEACONF_DOUBLE_WIDE)
+	pPriv->overlayOK = FALSE;
+    else
+	pPriv->overlayOK = TRUE;
+    
+    if (!pPriv->overlayOK)
+	return;
+
+    /* Check we have an LFP connected */
+    if (i830PipeHasType(crtc, I830_OUTPUT_LVDS)) 
     {
-	xf86CrtcPtr crtc = xf86_config->crtc[c];
-	if (I830CrtcPipe (crtc) == pipe)
-	    return crtc;
+
+	int	vtotal_reg = intel_crtc->pipe ? VTOTAL_A : VTOTAL_B;
+	CARD32	size = intel_crtc->pipe ? INREG(PIPEBSRC) : INREG(PIPEASRC);
+	CARD32	active;
+	CARD32	hsize, vsize;
+
+	hsize = (size >> 16) & 0x7FF;
+	vsize = size & 0x7FF;
+	active = INREG(vtotal_reg) & 0x7FF;
+
+	if (vsize < active && hsize > 1024)
+	    I830SetOneLineModeRatio(pScrn);
+
+	if (pPriv->scaleRatio & 0xFFFE0000) 
+	{
+	    /* Possible bogus ratio, using in-accurate fallback */
+	    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+		       "Bogus panel fit register, Xvideo positioning may not "
+		       "be accurate.\n");
+	    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+		       "Using fallback ratio - was 0x%x, now 0x%x\n",
+		       pPriv->scaleRatio,
+		       (int)(((float)active * 65536)/(float)vsize));
+
+	    pPriv->scaleRatio = (int)(((float)active * 65536) / (float)vsize);
+	}
     }
-    return NULL;
 }
 
 /*
@@ -383,7 +411,6 @@ i830_overlay_on(ScrnInfoPtr pScrn)
     I830OverlayRegPtr	overlay = I830OVERLAYREG(pI830);
     I830PortPrivPtr	pPriv = pI830->adaptor->pPortPrivates[0].ptr;
     Bool		deactivate = FALSE;
-    xf86CrtcPtr		crtc0 = NULL;
     
     if (*pI830->overlayOn)
 	return;
@@ -633,7 +660,7 @@ I830ResetVideo(ScrnInfoPtr pScrn)
      * Select which pipe the overlay is enabled on.
      */
     overlay->OCONFIG &= ~OVERLAY_PIPE_MASK;
-    if (I830CrtcPipe (pPriv->current_crtc) == 0)
+    if (i830_crtc_pipe (pPriv->current_crtc) == 0)
 	overlay->OCONFIG |= OVERLAY_PIPE_A;
     else 
 	overlay->OCONFIG |= OVERLAY_PIPE_B;
@@ -1717,9 +1744,6 @@ i830_display_video(ScrnInfoPtr pScrn, xf
     OVERLAY_DEBUG("I830DisplayVideo: %dx%d (pitch %d)\n", width, height,
 		  dstPitch);
 
-    if (!pPriv->overlayOK)
-	return;
-
 #if VIDEO_DEBUG
     CompareOverlay(pI830, (CARD32 *) overlay, 0x100);
 #endif
@@ -1737,9 +1761,14 @@ i830_display_video(ScrnInfoPtr pScrn, xf
     if (crtc != pPriv->current_crtc)
     {
         pPriv->current_crtc = crtc;
-        I830ResetVideo (pScrn);
+	i830_overlay_switch_to_crtc (pScrn, crtc);
+	if (pPriv->overlayOK)
+	    I830ResetVideo (pScrn);
     }
 
+    if (!pPriv->overlayOK)
+	return;
+
     switch (crtc->rotation & 0xf) {
     case RR_Rotate_0:
 	dstBox->x1 -= crtc->x;
@@ -2271,7 +2300,7 @@ I830PutImage(ScrnInfoPtr pScrn,
 
     if (pI830->entityPrivate) {
 	if (pI830->entityPrivate->XvInUse != -1 &&
-	    pI830->entityPrivate->XvInUse != I830CrtcPipe (pPriv->current_crtc)) {
+	    pI830->entityPrivate->XvInUse != i830_crtc_pipe (pPriv->current_crtc)) {
 #ifdef PANORAMIX
 	    if (!noPanoramiXExtension) {
 		return Success; /* faked for trying to share it */
@@ -2282,7 +2311,7 @@ I830PutImage(ScrnInfoPtr pScrn,
 	    }
 	}
 
-	pI830->entityPrivate->XvInUse = I830CrtcPipe (pPriv->current_crtc);;
+	pI830->entityPrivate->XvInUse = i830_crtc_pipe (pPriv->current_crtc);;
     }
 
     /* overlay limits */
@@ -2766,7 +2795,7 @@ I830DisplaySurface(XF86SurfacePtr surfac
 
     if (pI830->entityPrivate) {
 	if (pI830->entityPrivate->XvInUse != -1 &&
-	    pI830->entityPrivate->XvInUse != I830CrtcPipe (pI830Priv->current_crtc)) {
+	    pI830->entityPrivate->XvInUse != i830_crtc_pipe (pI830Priv->current_crtc)) {
 #ifdef PANORAMIX
 	    if (!noPanoramiXExtension) {
 		return Success; /* faked for trying to share it */
@@ -2777,7 +2806,7 @@ I830DisplaySurface(XF86SurfacePtr surfac
 	    }
 	}
 
-	pI830->entityPrivate->XvInUse = I830CrtcPipe (pI830Priv->current_crtc);
+	pI830->entityPrivate->XvInUse = i830_crtc_pipe (pI830Priv->current_crtc);
     }
 
     x1 = src_x;
@@ -2861,7 +2890,6 @@ i830_crtc_dpms_video(xf86CrtcPtr crtc, B
     ScrnInfoPtr pScrn = crtc->scrn;
     I830Ptr pI830 = I830PTR(pScrn);
     I830PortPrivPtr pPriv;
-    I830CrtcPrivatePtr intel_crtc = crtc->driver_private;
 
     if (pI830->adaptor == NULL)
 	return;
@@ -2872,53 +2900,12 @@ i830_crtc_dpms_video(xf86CrtcPtr crtc, B
 
     pPriv = GET_PORT_PRIVATE(pScrn);
 
-    /* Check if it's the crtc the overlay is on */
     if (crtc != pPriv->current_crtc)
 	return;
 
+    /* Check if it's the crtc the overlay is on */
     if (on) {
-	int size, hsize, vsize, active;
-	int pipeconf_reg = intel_crtc->pipe == 0 ? PIPEACONF : PIPEBCONF;
-	char pipename = intel_crtc->pipe == 0 ? 'A' : 'B';
-
-	pPriv->overlayOK = TRUE;
-
-	if (INREG(pipeconf_reg) & PIPEACONF_DOUBLE_WIDE) {
-	    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
-		       "Disabling XVideo output because Pipe %c is in "
-		       "double-wide mode.\n", pipename);
-	    pPriv->overlayOK = FALSE;
-	} else if (!pPriv->overlayOK) {
-	    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
-		       "Re-enabling XVideo output because Pipe %c is now in "
-		       "single-wide mode.\n", pipename);
-	    pPriv->overlayOK = TRUE;
-	}
-
-	/* Check we have an LFP connected */
-	if (i830PipeHasType(crtc, I830_OUTPUT_LVDS)) {
-	    int vtotal_reg = intel_crtc->pipe ? VTOTAL_A : VTOTAL_B;
-	    size = intel_crtc->pipe ? INREG(PIPEBSRC) : INREG(PIPEASRC);
-	    hsize = (size >> 16) & 0x7FF;
-	    vsize = size & 0x7FF;
-	    active = INREG(vtotal_reg) & 0x7FF;
-
-	    if (vsize < active && hsize > 1024)
-		I830SetOneLineModeRatio(pScrn);
-
-	    if (pPriv->scaleRatio & 0xFFFE0000) {
-		/* Possible bogus ratio, using in-accurate fallback */
-		xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
-			   "Bogus panel fit register, Xvideo positioning may not "
-			   "be accurate.\n");
-		xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
-			   "Using fallback ratio - was 0x%x, now 0x%x\n",
-			   pPriv->scaleRatio,
-			   (int)(((float)active * 65536)/(float)vsize));
-
-		pPriv->scaleRatio = (int)(((float)active * 65536) / (float)vsize);
-	    }
-	}
+	i830_overlay_switch_to_crtc (pScrn, crtc);
     } else {
 	/* We stop the video when mode switching, so we don't lock up
 	 * the engine. The overlayOK will determine whether we can re-enable
diff-tree 0984c1fc0963f1ebab31f5b8fce5ad4c387fbd2c (from 88ee25ebad78e54d243d728b775a69365359b5fb)
Author: Wang Zhenyu <zhenyu.z.wang at intel.com>
Date:   Thu May 31 10:17:26 2007 +0800

    Add pci ids for 945GME

diff --git a/src/common.h b/src/common.h
index 6aa0412..c879333 100644
--- a/src/common.h
+++ b/src/common.h
@@ -331,6 +331,7 @@ extern int I810_DEBUG;
 
 #ifndef PCI_CHIP_I945_GM
 #define PCI_CHIP_I945_GM        0x27A2
+#define PCI_CHIP_I945_GME	0x27AE
 #define PCI_CHIP_I945_GM_BRIDGE 0x27A0
 #endif
 
@@ -374,7 +375,7 @@ extern int I810_DEBUG;
 #define IS_I915G(pI810) (pI810->PciInfo->chipType == PCI_CHIP_I915_G || pI810->PciInfo->chipType == PCI_CHIP_E7221_G)
 #define IS_I915GM(pI810) (pI810->PciInfo->chipType == PCI_CHIP_I915_GM)
 #define IS_I945G(pI810) (pI810->PciInfo->chipType == PCI_CHIP_I945_G)
-#define IS_I945GM(pI810) (pI810->PciInfo->chipType == PCI_CHIP_I945_GM)
+#define IS_I945GM(pI810) (pI810->PciInfo->chipType == PCI_CHIP_I945_GM || pI810->PciInfo->chipType == PCI_CHIP_I945_GME)
 #define IS_I965GM(pI810) (pI810->PciInfo->chipType == PCI_CHIP_I965_GM || pI810->PciInfo->chipType == PCI_CHIP_I965_GME)
 #define IS_I965G(pI810) (pI810->PciInfo->chipType == PCI_CHIP_I965_G || pI810->PciInfo->chipType == PCI_CHIP_I965_G_1 || pI810->PciInfo->chipType == PCI_CHIP_I965_Q || pI810->PciInfo->chipType == PCI_CHIP_I946_GZ || pI810->PciInfo->chipType == PCI_CHIP_I965_GM || pI810->PciInfo->chipType == PCI_CHIP_I965_GME)
 #define IS_I9XX(pI810) (IS_I915G(pI810) || IS_I915GM(pI810) || IS_I945G(pI810) || IS_I945GM(pI810) || IS_I965G(pI810))
diff --git a/src/i810_driver.c b/src/i810_driver.c
index 6b6dd25..5b04a47 100644
--- a/src/i810_driver.c
+++ b/src/i810_driver.c
@@ -140,6 +140,7 @@ static SymTabRec I810Chipsets[] = {
    {PCI_CHIP_I915_GM,		"915GM"},
    {PCI_CHIP_I945_G,		"945G"},
    {PCI_CHIP_I945_GM,		"945GM"},
+   {PCI_CHIP_I945_GME,		"945GME"},
    {PCI_CHIP_I965_G,		"965G"},
    {PCI_CHIP_I965_G_1,		"965G"},
    {PCI_CHIP_I965_Q,		"965Q"},
@@ -165,6 +166,7 @@ static PciChipsets I810PciChipsets[] = {
    {PCI_CHIP_I915_GM,		PCI_CHIP_I915_GM,	RES_SHARED_VGA},
    {PCI_CHIP_I945_G,		PCI_CHIP_I945_G,	RES_SHARED_VGA},
    {PCI_CHIP_I945_GM,		PCI_CHIP_I945_GM,	RES_SHARED_VGA},
+   {PCI_CHIP_I945_GME,		PCI_CHIP_I945_GME,	RES_SHARED_VGA},
    {PCI_CHIP_I965_G,		PCI_CHIP_I965_G,	RES_SHARED_VGA},
    {PCI_CHIP_I965_G_1,		PCI_CHIP_I965_G_1,	RES_SHARED_VGA},
    {PCI_CHIP_I965_Q,		PCI_CHIP_I965_Q,	RES_SHARED_VGA},
@@ -611,6 +613,7 @@ I810Probe(DriverPtr drv, int flags)
 	    case PCI_CHIP_I915_GM:
 	    case PCI_CHIP_I945_G:
 	    case PCI_CHIP_I945_GM:
+	    case PCI_CHIP_I945_GME:
 	    case PCI_CHIP_I965_G:
 	    case PCI_CHIP_I965_G_1:
 	    case PCI_CHIP_I965_Q:
diff --git a/src/i830_driver.c b/src/i830_driver.c
index f5c9d32..1290d6d 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -229,6 +229,7 @@ static SymTabRec I830Chipsets[] = {
    {PCI_CHIP_I915_GM,		"915GM"},
    {PCI_CHIP_I945_G,		"945G"},
    {PCI_CHIP_I945_GM,		"945GM"},
+   {PCI_CHIP_I945_GME,		"945GME"},
    {PCI_CHIP_I965_G,		"965G"},
    {PCI_CHIP_I965_G_1,		"965G"},
    {PCI_CHIP_I965_Q,		"965Q"},
@@ -248,6 +249,7 @@ static PciChipsets I830PciChipsets[] = {
    {PCI_CHIP_I915_GM,		PCI_CHIP_I915_GM,	RES_SHARED_VGA},
    {PCI_CHIP_I945_G,		PCI_CHIP_I945_G,	RES_SHARED_VGA},
    {PCI_CHIP_I945_GM,		PCI_CHIP_I945_GM,	RES_SHARED_VGA},
+   {PCI_CHIP_I945_GME,		PCI_CHIP_I945_GME,	RES_SHARED_VGA},
    {PCI_CHIP_I965_G,		PCI_CHIP_I965_G,	RES_SHARED_VGA},
    {PCI_CHIP_I965_G_1,		PCI_CHIP_I965_G_1,	RES_SHARED_VGA},
    {PCI_CHIP_I965_Q,		PCI_CHIP_I965_Q,	RES_SHARED_VGA},
@@ -1055,6 +1057,9 @@ I830PreInit(ScrnInfoPtr pScrn, int flags
    case PCI_CHIP_I945_GM:
       chipname = "945GM";
       break;
+   case PCI_CHIP_I945_GME:
+      chipname = "945GME";
+      break;
    case PCI_CHIP_I965_G:
    case PCI_CHIP_I965_G_1:
       chipname = "965G";
diff-tree 88ee25ebad78e54d243d728b775a69365359b5fb (from 92e4deb50e049cc83cbde4995ba0b901feceb15a)
Author: Wang Zhenyu <zhenyu.z.wang at intel.com>
Date:   Thu May 31 10:13:30 2007 +0800

    Add pci ids for 965GME/GLE chip

diff --git a/src/common.h b/src/common.h
index f45fc8e..6aa0412 100644
--- a/src/common.h
+++ b/src/common.h
@@ -356,6 +356,7 @@ extern int I810_DEBUG;
 
 #ifndef PCI_CHIP_I965_GM
 #define PCI_CHIP_I965_GM        0x2A02
+#define PCI_CHIP_I965_GME	0x2A12
 #define PCI_CHIP_I965_GM_BRIDGE 0x2A00
 #endif
 
@@ -374,8 +375,8 @@ extern int I810_DEBUG;
 #define IS_I915GM(pI810) (pI810->PciInfo->chipType == PCI_CHIP_I915_GM)
 #define IS_I945G(pI810) (pI810->PciInfo->chipType == PCI_CHIP_I945_G)
 #define IS_I945GM(pI810) (pI810->PciInfo->chipType == PCI_CHIP_I945_GM)
-#define IS_I965GM(pI810) (pI810->PciInfo->chipType == PCI_CHIP_I965_GM)
-#define IS_I965G(pI810) (pI810->PciInfo->chipType == PCI_CHIP_I965_G || pI810->PciInfo->chipType == PCI_CHIP_I965_G_1 || pI810->PciInfo->chipType == PCI_CHIP_I965_Q || pI810->PciInfo->chipType == PCI_CHIP_I946_GZ || pI810->PciInfo->chipType == PCI_CHIP_I965_GM)
+#define IS_I965GM(pI810) (pI810->PciInfo->chipType == PCI_CHIP_I965_GM || pI810->PciInfo->chipType == PCI_CHIP_I965_GME)
+#define IS_I965G(pI810) (pI810->PciInfo->chipType == PCI_CHIP_I965_G || pI810->PciInfo->chipType == PCI_CHIP_I965_G_1 || pI810->PciInfo->chipType == PCI_CHIP_I965_Q || pI810->PciInfo->chipType == PCI_CHIP_I946_GZ || pI810->PciInfo->chipType == PCI_CHIP_I965_GM || pI810->PciInfo->chipType == PCI_CHIP_I965_GME)
 #define IS_I9XX(pI810) (IS_I915G(pI810) || IS_I915GM(pI810) || IS_I945G(pI810) || IS_I945GM(pI810) || IS_I965G(pI810))
 
 #define IS_MOBILE(pI810) (IS_I830(pI810) || IS_I85X(pI810) || IS_I915GM(pI810) || IS_I945GM(pI810) || IS_I965GM(pI810))
diff --git a/src/i810_driver.c b/src/i810_driver.c
index baca21c..6b6dd25 100644
--- a/src/i810_driver.c
+++ b/src/i810_driver.c
@@ -145,6 +145,7 @@ static SymTabRec I810Chipsets[] = {
    {PCI_CHIP_I965_Q,		"965Q"},
    {PCI_CHIP_I946_GZ,		"946GZ"},
    {PCI_CHIP_I965_GM,		"965GM"},
+   {PCI_CHIP_I965_GME,		"965GME/GLE"},
    {-1,				NULL}
 };
 
@@ -169,6 +170,7 @@ static PciChipsets I810PciChipsets[] = {
    {PCI_CHIP_I965_Q,		PCI_CHIP_I965_Q,	RES_SHARED_VGA},
    {PCI_CHIP_I946_GZ,		PCI_CHIP_I946_GZ,	RES_SHARED_VGA},
    {PCI_CHIP_I965_GM,		PCI_CHIP_I965_GM,	RES_SHARED_VGA},
+   {PCI_CHIP_I965_GME,		PCI_CHIP_I965_GME,	RES_SHARED_VGA},
    {-1,				-1, RES_UNDEFINED }
 };
 
@@ -614,6 +616,7 @@ I810Probe(DriverPtr drv, int flags)
 	    case PCI_CHIP_I965_Q:
 	    case PCI_CHIP_I946_GZ:
 	    case PCI_CHIP_I965_GM:
+	    case PCI_CHIP_I965_GME:
     	       xf86SetEntitySharable(usedChips[i]);
 
     	       /* Allocate an entity private if necessary */		
diff --git a/src/i830_driver.c b/src/i830_driver.c
index 8e74903..f5c9d32 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -234,6 +234,7 @@ static SymTabRec I830Chipsets[] = {
    {PCI_CHIP_I965_Q,		"965Q"},
    {PCI_CHIP_I946_GZ,		"946GZ"},
    {PCI_CHIP_I965_GM,		"965GM"},
+   {PCI_CHIP_I965_GME,		"965GME/GLE"},
    {-1,				NULL}
 };
 
@@ -252,6 +253,7 @@ static PciChipsets I830PciChipsets[] = {
    {PCI_CHIP_I965_Q,		PCI_CHIP_I965_Q,	RES_SHARED_VGA},
    {PCI_CHIP_I946_GZ,		PCI_CHIP_I946_GZ,	RES_SHARED_VGA},
    {PCI_CHIP_I965_GM,		PCI_CHIP_I965_GM,	RES_SHARED_VGA},
+   {PCI_CHIP_I965_GME,		PCI_CHIP_I965_GME,	RES_SHARED_VGA},
    {-1,				-1,			RES_UNDEFINED}
 };
 
@@ -1066,6 +1068,9 @@ I830PreInit(ScrnInfoPtr pScrn, int flags
    case PCI_CHIP_I965_GM:
       chipname = "965GM";
       break;
+   case PCI_CHIP_I965_GME:
+      chipname = "965GME/GLE";
+      break;
    default:
       chipname = "unknown chipset";
       break;
diff-tree 92e4deb50e049cc83cbde4995ba0b901feceb15a (from 888a4a5f469bf955e3ee3e184b628808ae8a4498)
Author: Keith Packard <keithp at neko.keithp.com>
Date:   Wed May 30 11:49:07 2007 -0600

    Extend XV_PIPE range to include new -1 value

diff --git a/src/i830_video.c b/src/i830_video.c
index 4517975..155bcc1 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -229,7 +229,7 @@ static XF86VideoFormatRec Formats[NUM_FO
 
 #define CLONE_ATTRIBUTES 1
 static XF86AttributeRec CloneAttributes[CLONE_ATTRIBUTES] = {
-    {XvSettable | XvGettable, 0, 1, "XV_PIPE"}
+    {XvSettable | XvGettable, -1, 1, "XV_PIPE"}
 };
 
 #define NUM_ATTRIBUTES 5
diff-tree 888a4a5f469bf955e3ee3e184b628808ae8a4498 (from 516fb73ffee0aea7cf892e6703d37f8ecf52b812)
Author: Wang Zhenyu <zhenyu.z.wang at intel.com>
Date:   Wed May 30 14:42:35 2007 +0800

    Fix i965 render's draw clip rectangle
    
    Use scrn's virtual size is not correct in rotation rendering.
    This fixes initial rotation problem on i965.

diff --git a/src/i965_render.c b/src/i965_render.c
index 848774e..956baf3 100644
--- a/src/i965_render.c
+++ b/src/i965_render.c
@@ -945,8 +945,8 @@ i965_prepare_composite(int op, PicturePt
 	 */
    	OUT_RING(BRW_3DSTATE_DRAWING_RECTANGLE | 2); /* XXX 3 for BLC or CTG */
    	OUT_RING(0x00000000);	/* ymin, xmin */
-   	OUT_RING((pScrn->virtualX - 1) |
- 	         (pScrn->virtualY - 1) << 16); /* ymax, xmax */
+	OUT_RING(DRAW_YMAX(pDst->drawable.height - 1) |
+		 DRAW_XMAX(pDst->drawable.width - 1)); /* ymax, xmax */
    	OUT_RING(0x00000000);	/* yorigin, xorigin */
 
 	/* skip the depth buffer */
diff-tree 516fb73ffee0aea7cf892e6703d37f8ecf52b812 (from 72462568da589054828b72ace83232a71636ee73)
Author: Eric Anholt <eric at anholt.net>
Date:   Tue May 29 10:22:25 2007 -0700

    Remove README statement that 830M panels are unsupported.

diff --git a/README b/README
index f209baa..bcb0205 100644
--- a/README
+++ b/README
@@ -57,11 +57,6 @@ options.
 
 
 Known Limitations
-- Bug #8534: i830 laptop panels not supported.  The driver
-  will fail to recognize them, and only function through VGA output.  Two
-  partial DVO chip drivers (ivch and ch7017) are included which contain some of
-  the code necessary for i830 laptop panel support, but some I2C debugging will
-  be necessary to get those drivers to attach.
 - No support for "zaphod mode" dualhead.  This is the mode in which two
   Device sections are placed in the config file, and doesn't support DRI or
   many other features.  Instead, only "MergedFB-style" dualhead is supported.
diff-tree 72462568da589054828b72ace83232a71636ee73 (from 906b974bfeeed18d79c244ad3db4f5d30e13e4c8)
Author: Eric Anholt <eric at anholt.net>
Date:   Tue May 29 10:21:12 2007 -0700

    Expand manpage description of outputs supported.

diff --git a/man/intel.man b/man/intel.man
index daf9030..8991619 100644
--- a/man/intel.man
+++ b/man/intel.man
@@ -168,11 +168,28 @@ Enable printing of additional debugging 
 the server log.
 
 .PP
-The 830M and newer driver supports RandR 1.2, exposing the VGA, LVDS
-(laptop panel), TMDS (DVI on SDVO/DVO cards), and TV (on 915GM/945GM)
-outputs.  Per-output configuration is done through the
-.B Monitor
-section of __xconfigfile__(__filemansuffix__).
+The 830M and newer driver supports the following outputs through RandR 1.2:
+.PP
+.TP
+.BI "VGA"
+Analog VGA output
+.TP
+.BI "LVDS"
+Laptop panel
+.TP
+.BI "TV"
+Integrated TV output
+.TP
+.BI "TMDS-1"
+First DVI SDVO output
+.TP
+.BI "TMDS-2"
+Second DVI SDVO output
+.PP
+SDVO and DVO TV outputs are not supported by the driver at this time.
+.PP
+See __xconfigfile__(__filemansuffix__) for information on associating Monitor
+sections with these outputs for configuration.
 
 .SH "SEE ALSO"
 __xservername__(__appmansuffix__), __xconfigfile__(__filemansuffix__), xorgconfig(__appmansuffix__), Xserver(__appmansuffix__), X(__miscmansuffix__)
diff-tree 906b974bfeeed18d79c244ad3db4f5d30e13e4c8 (from 4b2781291844b61b397e257a0fdb43e964e5f603)
Author: Eric Anholt <eric at anholt.net>
Date:   Tue May 29 09:49:08 2007 -0700

    Add a fixup to LVDS panel mode detection for 1280x768 panel from text mode.
    
    Apparently some BIOSes will program a small mode with large blanking instead of
    using the pannel fitter.

diff --git a/src/i830_lvds.c b/src/i830_lvds.c
index 566c868..ecc91aa 100644
--- a/src/i830_lvds.c
+++ b/src/i830_lvds.c
@@ -496,6 +496,22 @@ i830_lvds_init(ScrnInfoPtr pScrn)
 	    dev_priv->panel_fixed_mode = i830_crtc_mode_get(pScrn, crtc);
 	    if (dev_priv->panel_fixed_mode != NULL)
 		dev_priv->panel_fixed_mode->type |= M_T_PREFERRED;
+
+	    /* Fixup for a 1280x768 panel with the horizontal trimmed
+	     * down to 1024 for text mode.
+	     */
+	    if (!xf86ModesEqual(dev_priv->panel_fixed_mode, bios_mode) &&
+		dev_priv->panel_fixed_mode->HDisplay == 1024 &&
+		dev_priv->panel_fixed_mode->HSyncStart == 1200 &&
+		dev_priv->panel_fixed_mode->HSyncEnd == 1312 &&
+		dev_priv->panel_fixed_mode->HTotal == 1688 &&
+		dev_priv->panel_fixed_mode->VDisplay == 768)
+	    {
+		dev_priv->panel_fixed_mode->HDisplay = 1280;
+		dev_priv->panel_fixed_mode->HSyncStart = 1328;
+		dev_priv->panel_fixed_mode->HSyncEnd = 1440;
+		dev_priv->panel_fixed_mode->HTotal = 1688;
+	    }
 	}
     }
 
diff-tree 4b2781291844b61b397e257a0fdb43e964e5f603 (from 2a365eab0178c28782fba97bdd22365f30ce8963)
Author: Keith Packard <keithp at neko.keithp.com>
Date:   Sat May 26 10:09:11 2007 -0700

    Mark IVCH as connected when detected

diff --git a/src/ivch/ivch.c b/src/ivch/ivch.c
index e0755c0..eac878e 100644
--- a/src/ivch/ivch.c
+++ b/src/ivch/ivch.c
@@ -219,7 +219,7 @@ ivch_setup (I2CDevPtr d, xf86OutputPtr o
 static xf86OutputStatus
 ivch_detect(I2CDevPtr d)
 {
-    return XF86OutputStatusUnknown;
+    return XF86OutputStatusConnected;
 }
 
 static DisplayModePtr
diff-tree 2a365eab0178c28782fba97bdd22365f30ce8963 (from ff8c8cb869a3c780dbd826f7c94f06e4f3fda6af)
Author: Keith Packard <keithp at dulcimer.keithp.com>
Date:   Sun May 27 12:35:55 2007 -0700

    On i830, Pipe B cannot be lit the first time unless Pipe A is running.
    
    I don't understand it, but just like the video overlay, if Pipe A is not
    running, Pipe B will not turn the first time it is activated. This
    patch restructures the code used for the video overlay to share it
    with the crtc commit function.

diff --git a/src/i830.h b/src/i830.h
index 35f8192..76cc6e8 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -216,6 +216,8 @@ extern const char *i830_output_type_name
 typedef struct _I830CrtcPrivateRec {
     int			    pipe;
 
+    Bool    		    enabled;
+    
     /* Lookup table values to be set when the CRTC is enabled */
     CARD8 lut_r[256], lut_g[256], lut_b[256];
 
@@ -579,6 +581,15 @@ extern void I830InitVideo(ScreenPtr pScr
 extern void i830_crtc_dpms_video(xf86CrtcPtr crtc, Bool on);
 #endif
 
+int
+i830_crtc_pipe (xf86CrtcPtr crtc);
+
+Bool
+i830_pipe_a_require_activate (ScrnInfoPtr scrn);
+
+void
+i830_pipe_a_require_deactivate (ScrnInfoPtr scrn);
+
 #ifdef XF86DRI
 extern Bool I830Allocate3DMemory(ScrnInfoPtr pScrn, const int flags);
 extern void I830SetupMemoryTiling(ScrnInfoPtr pScrn);
diff --git a/src/i830_display.c b/src/i830_display.c
index 023a1aa..adc7479 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -429,6 +429,76 @@ i830PipeSetBase(xf86CrtcPtr crtc, int x,
 #endif
 }
 
+/*
+ * Both crtc activation and video overlay enablement on pipe B
+ * will fail on i830 if pipe A is not running. This function
+ * makes sure pipe A is active for these cases
+ */
+
+int
+i830_crtc_pipe (xf86CrtcPtr crtc)
+{
+    if (crtc == NULL)
+	return 0;
+    return ((I830CrtcPrivatePtr) crtc->driver_private)->pipe;
+}
+
+static xf86CrtcPtr
+i830_crtc_for_pipe (ScrnInfoPtr scrn, int pipe)
+{
+    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
+    int			c;
+
+    for (c = 0; c < xf86_config->num_crtc; c++)
+    {
+	xf86CrtcPtr crtc = xf86_config->crtc[c];
+	if (i830_crtc_pipe (crtc) == pipe)
+	    return crtc;
+    }
+    return NULL;
+}
+
+Bool
+i830_pipe_a_require_activate (ScrnInfoPtr scrn)
+{
+    xf86CrtcPtr	crtc = i830_crtc_for_pipe (scrn, 0);
+    /* VESA 640x480x72Hz mode to set on the pipe */
+    static DisplayModeRec   mode = {
+	NULL, NULL, "640x480", MODE_OK, M_T_DEFAULT,
+	31500,
+	640, 664, 704, 832, 0,
+	480, 489, 491, 520, 0,
+	V_NHSYNC | V_NVSYNC,
+	0, 0,
+	0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0,
+	FALSE, FALSE, 0, NULL, 0, 0.0, 0.0
+    };
+
+    if (!crtc)
+	return FALSE;
+    if (crtc->enabled)
+	return FALSE;
+    xf86SetModeCrtc (&mode, INTERLACE_HALVE_V);
+    crtc->funcs->mode_set (crtc, &mode, &mode, 0, 0);
+    crtc->funcs->dpms (crtc, DPMSModeOn);
+    return TRUE;
+}
+
+void
+i830_pipe_a_require_deactivate (ScrnInfoPtr scrn)
+{
+    xf86CrtcPtr	crtc = i830_crtc_for_pipe (scrn, 0);
+
+    if (!crtc)
+	return;
+    if (crtc->enabled)
+	return;
+    crtc->funcs->dpms (crtc, DPMSModeOff);
+    return;
+}
+
+
 /**
  * Sets the power management mode of the pipe and plane.
  *
@@ -593,9 +663,19 @@ i830_crtc_prepare (xf86CrtcPtr crtc)
 static void
 i830_crtc_commit (xf86CrtcPtr crtc)
 {
+    I830CrtcPrivatePtr	intel_crtc = crtc->driver_private;
+    Bool		deactivate = FALSE;
+
+    if (!intel_crtc->enabled && intel_crtc->pipe != 0)
+	deactivate = i830_pipe_a_require_activate (crtc->scrn);
+    
+    intel_crtc->enabled = TRUE;
+    
     crtc->funcs->dpms (crtc, DPMSModeOn);
     if (crtc->scrn->pScreen != NULL)
 	xf86_reload_cursors (crtc->scrn->pScreen);
+    if (deactivate)
+	i830_pipe_a_require_deactivate (crtc->scrn);
 }
 
 void
diff --git a/src/i830_video.c b/src/i830_video.c
index d57519b..4517975 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -382,6 +382,7 @@ i830_overlay_on(ScrnInfoPtr pScrn)
     I830Ptr		pI830 = I830PTR(pScrn);
     I830OverlayRegPtr	overlay = I830OVERLAYREG(pI830);
     I830PortPrivPtr	pPriv = pI830->adaptor->pPortPrivates[0].ptr;
+    Bool		deactivate = FALSE;
     xf86CrtcPtr		crtc0 = NULL;
     
     if (*pI830->overlayOn)
@@ -393,30 +394,12 @@ i830_overlay_on(ScrnInfoPtr pScrn)
      * screen. Light up pipe A in this case to provide a clock
      * for the overlay hardware
      */
-    if (!pPriv->started_video)
+    if (pPriv->current_crtc && 
+	i830_crtc_pipe (pPriv->current_crtc) != 0 &&
+	!pPriv->started_video)
     {
 	pPriv->started_video = TRUE;
-	crtc0 = I830CrtcForPipe (pScrn, 0);
-	if (!crtc0->enabled)
-	{
-	    /* VESA 640x480x72Hz mode to set on the pipe */
-	    static DisplayModeRec   mode = {
-		NULL, NULL, "640x480", MODE_OK, M_T_DEFAULT,
-		31500,
-		640, 664, 704, 832, 0,
-		480, 489, 491, 520, 0,
-		V_NHSYNC | V_NVSYNC,
-		0, 0,
-		0, 0, 0, 0, 0, 0, 0,
-		0, 0, 0, 0, 0, 0,
-		FALSE, FALSE, 0, NULL, 0, 0.0, 0.0
-	    };
-	    xf86SetModeCrtc (&mode, INTERLACE_HALVE_V);
-	    crtc0->funcs->mode_set (crtc0, &mode, &mode, 0, 0);
-	    crtc0->funcs->dpms (crtc0, DPMSModeOn);
-	}
-	else
-	    crtc0 = NULL;
+	deactivate = i830_pipe_a_require_activate (pScrn);
     }
 
     overlay->OCMD &= ~OVERLAY_ENABLE;
@@ -435,8 +418,8 @@ i830_overlay_on(ScrnInfoPtr pScrn)
      * If we turned pipe A on up above, turn it
      * back off
      */
-    if (crtc0)
-	crtc0->funcs->dpms (crtc0, DPMSModeOff);
+    if (deactivate)
+	i830_pipe_a_require_deactivate (pScrn);
 
     OVERLAY_DEBUG("overlay_on\n");
     *pI830->overlayOn = TRUE;
diff-tree ff8c8cb869a3c780dbd826f7c94f06e4f3fda6af (from 33f635d79fe891079558fd909d564f3cf424c482)
Author: Keith Packard <keithp at dulcimer.keithp.com>
Date:   Fri May 25 20:29:59 2007 -0700

    Compute and clip to crtc before call to xf86XVClipVideoHelper.
    
    By clipping to the crtc ahead of time, xf86XVClipVideoHelper will
    correctly clip to the bounds of the crtc, eliminating the need for any
    custom crtc clipping.
    
    Also, replace the broken xf86XVFillKeyHelper with a private version that
    doesn't end up stuck with the wrong clip list when the root window changes
    size.

diff --git a/src/i830_video.c b/src/i830_video.c
index c2d3b4b..d57519b 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -1636,38 +1636,35 @@ UpdateCoeff(int taps, double fCutoff, Bo
     }
 }
 
-/*
- * Return the number of pixels from 'box' covered by 'crtc'.
- * That is, the area of the intersection of 'box' and 'crtc'
- */
-static int
-I830CrtcBoxCoverage (xf86CrtcPtr crtc, BoxPtr box)
+static void
+i830_box_intersect (BoxPtr dest, BoxPtr a, BoxPtr b)
 {
-    BoxRec   dest;
-    BoxRec   pipe;
+    dest->x1 = a->x1 > b->x1 ? a->x1 : b->x1;
+    dest->x2 = a->x2 < b->x2 ? a->x2 : b->x2;
+    dest->y1 = a->y1 > b->y1 ? a->y1 : b->y1;
+    dest->y2 = a->y2 < b->y2 ? a->y2 : b->y2;
+    if (dest->x1 >= dest->x2 || dest->y1 >= dest->y2)
+	dest->x1 = dest->x2 = dest->y1 = dest->y2 = 0;
+}
 
+static void
+i830_crtc_box (xf86CrtcPtr crtc, BoxPtr crtc_box)
+{
     if (crtc->enabled)
     {
-	pipe.x1 = crtc->x;
-	pipe.x2 = crtc->x + xf86ModeWidth (&crtc->mode, crtc->rotation);
-	pipe.y1 = crtc->y;
-	pipe.y2 = crtc->y + xf86ModeHeight (&crtc->mode, crtc->rotation);
+	crtc_box->x1 = crtc->x;
+	crtc_box->x2 = crtc->x + xf86ModeWidth (&crtc->mode, crtc->rotation);
+	crtc_box->y1 = crtc->y;
+	crtc_box->y2 = crtc->y + xf86ModeHeight (&crtc->mode, crtc->rotation);
     }
     else
-    {
-	pipe.x1 = pipe.x2 = 0;
-	pipe.y1 = pipe.y2 = 0;
-    }
-    dest.x1 = pipe.x1 > box->x1 ? pipe.x1 : box->x1;
-    dest.x2 = pipe.x2 < box->x2 ? pipe.x2 : box->x2;
-    dest.y1 = pipe.y1 > box->y1 ? pipe.y1 : box->y1;
-    dest.y2 = pipe.y2 < box->y2 ? pipe.y2 : box->y2;
-    if (dest.x1 >= dest.x2 || dest.y1 >= dest.y2)
-    {
-	dest.x1 = dest.x2 = 0;
-	dest.y1 = dest.y2 = 0;
-    }
-    return (int) (dest.x2 - dest.x1) * (int) (dest.y2 - dest.y1);
+	crtc_box->x1 = crtc_box->x2 = crtc_box->y1 = crtc_box->y2 = 0;
+}
+
+static int
+i830_box_area (BoxPtr box)
+{
+    return (int) (box->x2 - box->x1) * (int) (box->y2 - box->y1);
 }
 
 /*
@@ -1677,21 +1674,28 @@ I830CrtcBoxCoverage (xf86CrtcPtr crtc, B
  */
 
 static xf86CrtcPtr
-I830CoveringCrtc (ScrnInfoPtr pScrn, BoxPtr pBox, xf86CrtcPtr desired)
+i830_covering_crtc (ScrnInfoPtr pScrn,
+		    BoxPtr	box,
+		    xf86CrtcPtr desired,
+		    BoxPtr	crtc_box_ret)
 {
     xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
     xf86CrtcPtr		crtc, best_crtc;
     int			coverage, best_coverage;
     int			c;
+    BoxRec		crtc_box, cover_box;
 
     best_crtc = NULL;
     best_coverage = 0;
     for (c = 0; c < xf86_config->num_crtc; c++)
     {
 	crtc = xf86_config->crtc[c];
-	coverage = I830CrtcBoxCoverage (crtc, pBox);
+	i830_crtc_box (crtc, &crtc_box);
+	i830_box_intersect (&cover_box, &crtc_box, box);
+	coverage = i830_box_area (&cover_box);
 	if (coverage > best_coverage)
 	{
+	    *crtc_box_ret = crtc_box;
 	    if (crtc == desired)
 		return crtc;
 	    best_crtc = crtc;
@@ -1713,19 +1717,19 @@ i830_swidth (I830Ptr pI830, unsigned int
 }
 
 static void
-I830DisplayVideo(ScrnInfoPtr pScrn, int id, short width, short height,
-		 int dstPitch, int x1, int y1, int x2, int y2, BoxPtr dstBox,
-		 short src_w, short src_h, short drw_w, short drw_h)
+i830_display_video(ScrnInfoPtr pScrn, xf86CrtcPtr crtc,
+		   int id, short width, short height,
+		   int dstPitch, int x1, int y1, int x2, int y2, BoxPtr dstBox,
+		   short src_w, short src_h, short drw_w, short drw_h)
 {
-    I830Ptr pI830 = I830PTR(pScrn);
-    I830PortPrivPtr pPriv = pI830->adaptor->pPortPrivates[0].ptr;
+    I830Ptr		pI830 = I830PTR(pScrn);
+    I830PortPrivPtr	pPriv = pI830->adaptor->pPortPrivates[0].ptr;
     I830OverlayRegPtr	overlay = I830OVERLAYREG(pI830);
-    unsigned int swidth, swidthy, swidthuv;
-    unsigned int mask, shift, offsety, offsetu;
-    xf86CrtcPtr crtc;
-    int		tmp;
-    CARD32	OCMD;
-    Bool	scaleChanged = FALSE;
+    unsigned int	swidth, swidthy, swidthuv;
+    unsigned int	mask, shift, offsety, offsetu;
+    int			tmp;
+    CARD32		OCMD;
+    Bool		scaleChanged = FALSE;
 
     OVERLAY_DEBUG("I830DisplayVideo: %dx%d (pitch %d)\n", width, height,
 		  dstPitch);
@@ -1736,23 +1740,23 @@ I830DisplayVideo(ScrnInfoPtr pScrn, int 
 #if VIDEO_DEBUG
     CompareOverlay(pI830, (CARD32 *) overlay, 0x100);
 #endif
-
-    crtc = I830CoveringCrtc (pScrn, dstBox, pPriv->desired_crtc);
-    if (crtc != pPriv->current_crtc)
-    {
-        pPriv->current_crtc = crtc;
-        I830ResetVideo (pScrn);
-    }
-
+    
     /*
      * If the video isn't visible on any CRTC, turn it off
      */
     if (!crtc)
     {
+	pPriv->current_crtc = NULL;
 	i830_overlay_off (pScrn);
 	return;
     }
     
+    if (crtc != pPriv->current_crtc)
+    {
+        pPriv->current_crtc = crtc;
+        I830ResetVideo (pScrn);
+    }
+
     switch (crtc->rotation & 0xf) {
     case RR_Rotate_0:
 	dstBox->x1 -= crtc->x;
@@ -1792,44 +1796,6 @@ I830DisplayVideo(ScrnInfoPtr pScrn, int 
 	break;
     }
 
-    /* Fix up the dstBox if outside the visible screen */
-    {
-	int offset_x = (dstBox->x1 < 0) ? -dstBox->x1 : 0;
-	int offset_y = (dstBox->y1 < 0) ? -dstBox->y1 : 0;
-	int offset, offset2;
-
-	/* align */
-	offset_x = (offset_x + 3) & ~3;
-	offset_y = (offset_y + 3) & ~3;
-
-	if (crtc->rotation & (RR_Rotate_90 | RR_Rotate_270)) {
-	    height -= offset_x;
-	    width -= offset_y;
-	} else {
-	    height -= offset_y;
-	    width -= offset_x;
-	}
-
-	if (id == FOURCC_I420 || id == FOURCC_YV12) {
-	    offset = ((offset_x/2) + (dstPitch * offset_y)) * 2;
-	    offset2 = ((offset_x/2) + ((dstPitch/2) * offset_y));
-	} else {
-	    offset = ((offset_x*2) + (dstPitch * offset_y));
-	    offset2 = ((offset_x*2) + ((dstPitch/2) * offset_y));
-	}
-
-	/* buffer locations */
-	pPriv->YBuf0offset += offset;
-	pPriv->UBuf0offset += offset2;
-	pPriv->VBuf0offset += offset2;
-
-	if(pPriv->doubleBuffer) {
-	    pPriv->YBuf1offset += offset;
-	    pPriv->UBuf1offset += offset2;
-	    pPriv->VBuf1offset += offset2;
-	}
-    }
-
     if (crtc->rotation & (RR_Rotate_90 | RR_Rotate_270)) {
 	tmp = width;
 	width = height;
@@ -1851,32 +1817,6 @@ I830DisplayVideo(ScrnInfoPtr pScrn, int 
 	drw_h = ((drw_h * pPriv->scaleRatio) >> 16) + 1;
     }
 
-    {
-	/* Keep the engine happy and clip to the real vertical size just
-	 * in case an LFP is in use and it's not at it's native resolution.
-	 */
-	int vactive = I830CrtcPipe (pPriv->current_crtc) ? (INREG(VTOTAL_B) & 0x7FF) : (INREG(VTOTAL_A) & 0x7FF);
-	int hactive = pPriv->current_crtc->mode.HDisplay;
-
-	vactive += 1;
-
-	if (dstBox->y1 < 0) dstBox->y1 = 0;
-	if (dstBox->y2 < 0) dstBox->y2 = 0;
-	if (dstBox->x1 < 0) dstBox->x1 = 0;
-	if (dstBox->x2 < 0) dstBox->x2 = 0;
-	if (dstBox->y1 > vactive) dstBox->y1 = vactive;
-	if (dstBox->y2 > vactive) dstBox->y2 = vactive;
-	if (dstBox->x1 > hactive) dstBox->x1 = hactive;
-	if (dstBox->x2 > hactive) dstBox->x2 = hactive;
-
-	/* nothing do to */
-	if (dstBox->x2 - dstBox->x1 <= 2 || dstBox->y2 - dstBox->y1 < N_VERT_Y_TAPS)
-	{
-	    OVERLAY_DEBUG("NOTHING TO DO\n");
-	    return;
-	}
-    }
-
     if (IS_I9XX(pI830)) {
 	shift = 6;
 	mask = 0x3f;
@@ -2220,6 +2160,84 @@ I830FreeMemory(ScrnInfoPtr pScrn, struct
     linear->offset = 0;
 }
 
+static Bool
+i830_clip_video_helper (ScrnInfoPtr pScrn,
+			xf86CrtcPtr *crtc_ret,
+			BoxPtr	    dst,
+			INT32	    *xa,
+			INT32	    *xb,
+			INT32	    *ya,
+			INT32	    *yb,
+			RegionPtr   reg,
+			INT32	    width,
+			INT32	    height)
+{
+    Bool	ret;
+    RegionRec	crtc_region_local;
+    RegionPtr	crtc_region = reg;
+    
+    /*
+     * For overlay video, compute the relevant CRTC and
+     * clip video to that
+     */
+    if (crtc_ret)
+    {
+	I830Ptr		pI830 = I830PTR(pScrn);
+	I830PortPrivPtr pPriv = pI830->adaptor->pPortPrivates[0].ptr;
+	BoxRec		crtc_box;
+	xf86CrtcPtr	crtc = i830_covering_crtc (pScrn, dst,
+						   pPriv->desired_crtc,
+						   &crtc_box);
+	
+	if (crtc)
+	{
+	    REGION_INIT (pScreen, &crtc_region_local, &crtc_box, 1);
+	    crtc_region = &crtc_region_local;
+	    REGION_INTERSECT (pScreen, crtc_region, crtc_region, reg);
+	}
+	*crtc_ret = crtc;
+    }
+    ret = xf86XVClipVideoHelper (dst, xa, xb, ya, yb, 
+				 crtc_region, width, height);
+    if (crtc_region != reg)
+	REGION_UNINIT (pScreen, &crtc_region_local);
+    return ret;
+}
+
+static void
+i830_fill_colorkey (ScreenPtr pScreen, CARD32 key, RegionPtr clipboxes)
+{
+   DrawablePtr root = &WindowTable[pScreen->myNum]->drawable;
+   XID	       pval[2];
+   BoxPtr      pbox = REGION_RECTS(clipboxes);
+   int	       i, nbox = REGION_NUM_RECTS(clipboxes);
+   xRectangle  *rects;
+   GCPtr       gc;
+
+   if(!xf86Screens[pScreen->myNum]->vtSema) return;
+
+   gc = GetScratchGC(root->depth, pScreen);
+   pval[0] = key;
+   pval[1] = IncludeInferiors;
+   (void) ChangeGC(gc, GCForeground|GCSubwindowMode, pval);
+   ValidateGC(root, gc);
+
+   rects = xalloc (nbox * sizeof(xRectangle));
+
+   for(i = 0; i < nbox; i++, pbox++) 
+   {
+      rects[i].x = pbox->x1;
+      rects[i].y = pbox->y1;
+      rects[i].width = pbox->x2 - pbox->x1;
+      rects[i].height = pbox->y2 - pbox->y1;
+   }
+   
+   (*gc->ops->PolyFillRect)(root, gc, nbox, rects);
+   
+   xfree (rects);
+   FreeScratchGC (gc);
+}
+
 /*
  * The source rectangle of the video is defined by (src_x, src_y, src_w, src_h).
  * The dest rectangle of the video is defined by (drw_x, drw_y, drw_w, drw_h).
@@ -2255,6 +2273,7 @@ I830PutImage(ScrnInfoPtr pScrn,
     BoxRec dstBox;
     int pitchAlignMask;
     int extraLinear;
+    xf86CrtcPtr	crtc;
 
     if (pPriv->textured)
 	overlay = NULL;
@@ -2301,8 +2320,10 @@ I830PutImage(ScrnInfoPtr pScrn,
     dstBox.y1 = drw_y;
     dstBox.y2 = drw_y + drw_h;
 
-    if (!xf86XVClipVideoHelper(&dstBox, &x1, &x2, &y1, &y2, clipBoxes,
-			       width, height))
+    if (!i830_clip_video_helper(pScrn, 
+				pPriv->textured ? NULL : &crtc,
+				&dstBox, &x1, &x2, &y1, &y2, clipBoxes,
+				width, height))
 	return Success;
 
     destId = id;
@@ -2455,14 +2476,15 @@ I830PutImage(ScrnInfoPtr pScrn,
     }
 
     if (!pPriv->textured) {
+	i830_display_video(pScrn, crtc, destId, width, height, dstPitch,
+			   x1, y1, x2, y2, &dstBox, src_w, src_h,
+			   drw_w, drw_h);
+	
 	/* update cliplist */
 	if (!RegionsEqual(&pPriv->clip, clipBoxes)) {
 	    REGION_COPY(pScrn->pScreen, &pPriv->clip, clipBoxes);
-	    xf86XVFillKeyHelper(pScreen, pPriv->colorKey, clipBoxes);
+	    i830_fill_colorkey (pScreen, pPriv->colorKey, clipBoxes);
 	}
-
-	I830DisplayVideo(pScrn, destId, width, height, dstPitch,
-			 x1, y1, x2, y2, &dstBox, src_w, src_h, drw_w, drw_h);
     } else if (IS_I965G(pI830)) {
 	I965DisplayVideoTextured(pScrn, pPriv, destId, clipBoxes, width, height,
 				 dstPitch, x1, y1, x2, y2,
@@ -2754,8 +2776,8 @@ I830DisplaySurface(XF86SurfacePtr surfac
     I830Ptr pI830 = I830PTR(pScrn);
     I830PortPrivPtr pI830Priv = GET_PORT_PRIVATE(pScrn);
     INT32 x1, y1, x2, y2;
-    INT32 loops = 0;
     BoxRec dstBox;
+    xf86CrtcPtr crtc;
 
     OVERLAY_DEBUG("I830DisplaySurface\n");
 
@@ -2785,43 +2807,24 @@ I830DisplaySurface(XF86SurfacePtr surfac
     dstBox.y1 = drw_y;
     dstBox.y2 = drw_y + drw_h;
 
-    if (!xf86XVClipVideoHelper(&dstBox, &x1, &x2, &y1, &y2, clipBoxes,
-			       surface->width, surface->height))
+    if (!i830_clip_video_helper (pScrn, &crtc, &dstBox,
+				 &x1, &x2, &y1, &y2, clipBoxes,
+				 surface->width, surface->height))
 	return Success;
 
     /* fixup pointers */
     pI830Priv->YBuf0offset = surface->offsets[0];
     pI830Priv->YBuf1offset = pI830Priv->YBuf0offset;
 
-    /* Make sure this buffer isn't in use */
-    loops = 0;
-    if (*pI830->overlayOn && pI830Priv->doubleBuffer) 
-    {
-	while (loops < 1000000) {
-#if USE_USLEEP_FOR_VIDEO
-	    usleep(10);
-#endif
-	    if (((INREG(DOVSTA) & OC_BUF) >> 20) == pI830Priv->currentBuf) {
-		break;
-	    }
-	    loops++;
-	}
-	if (loops >= 1000000) {
-	    ErrorF("loops (1) maxed out for buffer %d\n", pI830Priv->currentBuf);
-#if 0
-	    pI830Priv->currentBuf = !pI830Priv->currentBuf;
-#endif
-	}
-
-	/* buffer swap */
-	pI830Priv->currentBuf = !pI830Priv->currentBuf;
-    }
+    /* Pick the idle buffer */
+    if (!pI830Priv->textured && *pI830->overlayOn && pI830Priv->doubleBuffer) 
+	pI830Priv->currentBuf = !((INREG(DOVSTA) & OC_BUF) >> 20);
 
-    I830DisplayVideo(pScrn, surface->id, surface->width, surface->height,
+    i830_display_video(pScrn, crtc, surface->id, surface->width, surface->height,
 		     surface->pitches[0], x1, y1, x2, y2, &dstBox,
 		     src_w, src_h, drw_w, drw_h);
 
-    xf86XVFillKeyHelper(pScreen, pI830Priv->colorKey, clipBoxes);
+    i830_fill_colorkey (pScreen, pI830Priv->colorKey, clipBoxes);
 
     pPriv->isOn = TRUE;
     /* we've prempted the XvImage stream so set its free timer */
diff-tree 33f635d79fe891079558fd909d564f3cf424c482 (from ff0ac8ea63dd6e55573652c5826c482881da0d62)
Author: Keith Packard <keithp at dulcimer.keithp.com>
Date:   Fri May 25 17:32:06 2007 -0700

    Ensure Pipe A is active when enabling overlay the first time.
    
    The overlay on the i830 appears to be clocked by Pipe A when being enabled.
    If pipe A is not running, it will freeze the overlay and blank the screen.
    Setting a random mode on the Pipe and turning it on fixes this problem
    nicely.

diff --git a/src/i830_video.c b/src/i830_video.c
index e2d132e..c2d3b4b 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -321,6 +321,9 @@ typedef struct {
     CARD16 RESERVEDG[0x100 / 2 - N_HORIZ_UV_TAPS * N_PHASES];
 } I830OverlayRegRec, *I830OverlayRegPtr;
 
+#define I830OVERLAYREG(pI830) ((I830OverlayRegPtr)\
+			       ((pI830)->FbBase + \
+				(pI830)->overlay_regs->offset))
 #if VIDEO_DEBUG
 static void
 CompareOverlay(I830Ptr pI830, CARD32 * overlay, int size)
@@ -342,6 +345,29 @@ CompareOverlay(I830Ptr pI830, CARD32 * o
 }
 #endif
 
+static int
+I830CrtcPipe (xf86CrtcPtr crtc)
+{
+    if (crtc == NULL)
+	return 0;
+    return ((I830CrtcPrivatePtr) crtc->driver_private)->pipe;
+}
+
+static xf86CrtcPtr
+I830CrtcForPipe (ScrnInfoPtr pScrn, int pipe)
+{
+    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+    int			c;
+
+    for (c = 0; c < xf86_config->num_crtc; c++)
+    {
+	xf86CrtcPtr crtc = xf86_config->crtc[c];
+	if (I830CrtcPipe (crtc) == pipe)
+	    return crtc;
+    }
+    return NULL;
+}
+
 /*
  * This is more or less the correct way to initalise, update, and shut down
  * the overlay.
@@ -353,40 +379,91 @@ CompareOverlay(I830Ptr pI830, CARD32 * o
 static void
 i830_overlay_on(ScrnInfoPtr pScrn)
 {
-    I830Ptr pI830 = I830PTR(pScrn);
-    I830OverlayRegPtr	overlay = (I830OverlayRegPtr) (pI830->FbBase +
-						       pI830->overlay_regs->offset);
-
+    I830Ptr		pI830 = I830PTR(pScrn);
+    I830OverlayRegPtr	overlay = I830OVERLAYREG(pI830);
+    I830PortPrivPtr	pPriv = pI830->adaptor->pPortPrivates[0].ptr;
+    xf86CrtcPtr		crtc0 = NULL;
+    
     if (*pI830->overlayOn)
 	return;
 
+    /*
+     * On I830, if pipe A is off the first time the overlay
+     * is enabled, it will fail to turn and blank the entire 
+     * screen. Light up pipe A in this case to provide a clock
+     * for the overlay hardware
+     */
+    if (!pPriv->started_video)
+    {
+	pPriv->started_video = TRUE;
+	crtc0 = I830CrtcForPipe (pScrn, 0);
+	if (!crtc0->enabled)
+	{
+	    /* VESA 640x480x72Hz mode to set on the pipe */
+	    static DisplayModeRec   mode = {
+		NULL, NULL, "640x480", MODE_OK, M_T_DEFAULT,
+		31500,
+		640, 664, 704, 832, 0,
+		480, 489, 491, 520, 0,
+		V_NHSYNC | V_NVSYNC,
+		0, 0,
+		0, 0, 0, 0, 0, 0, 0,
+		0, 0, 0, 0, 0, 0,
+		FALSE, FALSE, 0, NULL, 0, 0.0, 0.0
+	    };
+	    xf86SetModeCrtc (&mode, INTERLACE_HALVE_V);
+	    crtc0->funcs->mode_set (crtc0, &mode, &mode, 0, 0);
+	    crtc0->funcs->dpms (crtc0, DPMSModeOn);
+	}
+	else
+	    crtc0 = NULL;
+    }
+
     overlay->OCMD &= ~OVERLAY_ENABLE;
-    BEGIN_LP_RING(4);
+    BEGIN_LP_RING(6);
     OUT_RING(MI_FLUSH | MI_WRITE_DIRTY_STATE);
     OUT_RING(MI_NOOP);
     OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_FLIP_ON);
     OUT_RING(pI830->overlay_regs->bus_addr | OFC_UPDATE);
+    /* Wait for the overlay to light up before attempting to use it */
+    OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
+    OUT_RING(MI_NOOP);
     ADVANCE_LP_RING();
+    i830WaitSync(pScrn);
+    
+    /*
+     * If we turned pipe A on up above, turn it
+     * back off
+     */
+    if (crtc0)
+	crtc0->funcs->dpms (crtc0, DPMSModeOff);
+
     OVERLAY_DEBUG("overlay_on\n");
     *pI830->overlayOn = TRUE;
+
+    overlay->OCMD |= OVERLAY_ENABLE;
 }
 
 static void
-i830_overlay_continue(ScrnInfoPtr pScrn)
+i830_overlay_continue(ScrnInfoPtr pScrn, Bool update_filter)
 {
-    I830Ptr pI830 = I830PTR(pScrn);
-    I830OverlayRegPtr	overlay = (I830OverlayRegPtr) (pI830->FbBase +
-						       pI830->overlay_regs->offset);
+    I830Ptr		pI830 = I830PTR(pScrn);
+    CARD32		flip_addr;
+    I830OverlayRegPtr	overlay = I830OVERLAYREG(pI830);
 
     if (!*pI830->overlayOn)
 	return;
 
-    overlay->OCMD |= OVERLAY_ENABLE;
+    flip_addr = pI830->overlay_regs->bus_addr;
+    if (update_filter)
+	flip_addr |= OFC_UPDATE;
+    OVERLAY_DEBUG ("overlay_continue cmd 0x%08lx -> 0x%08lx sta 0x%08lx\n",
+		   overlay->OCMD, INREG(OCMD_REGISTER), INREG(DOVSTA));
     BEGIN_LP_RING(4);
     OUT_RING(MI_FLUSH | MI_WRITE_DIRTY_STATE);
     OUT_RING(MI_NOOP);
     OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_FLIP_CONTINUE);
-    OUT_RING(pI830->overlay_regs->bus_addr | OFC_UPDATE);
+    OUT_RING(flip_addr);
     ADVANCE_LP_RING();
     OVERLAY_DEBUG("overlay_continue\n");
 }
@@ -395,22 +472,43 @@ static void
 i830_overlay_off(ScrnInfoPtr pScrn)
 {
     I830Ptr pI830 = I830PTR(pScrn);
-    I830OverlayRegPtr	overlay = (I830OverlayRegPtr) (pI830->FbBase +
-						       pI830->overlay_regs->offset);
+    I830OverlayRegPtr	overlay = I830OVERLAYREG(pI830);
 
     if (!*pI830->overlayOn)
 	return;
 
-    overlay->OCMD &= ~OVERLAY_ENABLE;
-    BEGIN_LP_RING(6);
-    OUT_RING(MI_FLUSH | MI_WRITE_DIRTY_STATE);
-    OUT_RING(MI_NOOP);
-    OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_FLIP_CONTINUE);
-    OUT_RING(pI830->overlay_regs->bus_addr | OFC_UPDATE);
-    OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
-    OUT_RING(MI_NOOP);
-    ADVANCE_LP_RING();
-    i830WaitSync(pScrn);
+    /*
+     * Wait for overlay to go idle. This has to be
+     * separated from the turning off state by a WaitSync
+     * to ensure the overlay will not read OCMD early and
+     * disable the overlay before the commands here are
+     * executed
+     */
+    {
+	BEGIN_LP_RING(2);
+	OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
+	OUT_RING(MI_NOOP);
+	ADVANCE_LP_RING();
+	i830WaitSync(pScrn);
+    }
+    
+    /*
+     * Turn overlay off
+     */
+    {
+	overlay->OCMD &= ~OVERLAY_ENABLE;
+	OVERLAY_DEBUG ("overlay_off cmd 0x%08lx -> 0x%08lx sta 0x%08lx\n",
+		       overlay->OCMD, INREG(OCMD_REGISTER), INREG(DOVSTA));
+	BEGIN_LP_RING(6);
+	OUT_RING(MI_FLUSH | MI_WRITE_DIRTY_STATE);
+	OUT_RING(MI_NOOP);
+	OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_FLIP_CONTINUE);
+	OUT_RING(pI830->overlay_regs->bus_addr);
+	OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
+	OUT_RING(MI_NOOP);
+	ADVANCE_LP_RING();
+	i830WaitSync(pScrn);
+    }
     *pI830->overlayOn = FALSE;
     OVERLAY_DEBUG("overlay_off\n");
 }
@@ -490,21 +588,12 @@ I830InitVideo(ScreenPtr pScreen)
     xfree(adaptors);
 }
 
-static int
-I830CrtcPipe (xf86CrtcPtr crtc)
-{
-    if (crtc == NULL)
-	return 0;
-    return ((I830CrtcPrivatePtr) crtc->driver_private)->pipe;
-}
-
 static void
 I830ResetVideo(ScrnInfoPtr pScrn)
 {
     I830Ptr pI830 = I830PTR(pScrn);
     I830PortPrivPtr pPriv = pI830->adaptor->pPortPrivates[0].ptr;
-    I830OverlayRegPtr overlay =
-    (I830OverlayRegPtr) (pI830->FbBase + pI830->overlay_regs->offset);
+    I830OverlayRegPtr	overlay = I830OVERLAYREG(pI830);
 
     OVERLAY_DEBUG("I830ResetVideo: base: %p, offset: 0x%lx, obase: %p\n",
 		  pI830->FbBase, pI830->overlay_regs->offset, overlay);
@@ -938,7 +1027,7 @@ I830SetPortAttribute(ScrnInfoPtr pScrn,
 	return Success;
     }
 
-    overlay = (I830OverlayRegPtr) (pI830->FbBase + pI830->overlay_regs->offset);
+    overlay = I830OVERLAYREG(pI830);
 
     if (attribute == xvBrightness) {
 	if ((value < -128) || (value > 127))
@@ -946,20 +1035,20 @@ I830SetPortAttribute(ScrnInfoPtr pScrn,
 	pPriv->brightness = value;
 	overlay->OCLRC0 = (pPriv->contrast << 18) | (pPriv->brightness & 0xff);
 	OVERLAY_DEBUG("BRIGHTNESS\n");
-	i830_overlay_continue (pScrn);
+	i830_overlay_continue (pScrn, FALSE);
     } else if (attribute == xvContrast) {
 	if ((value < 0) || (value > 255))
 	    return BadValue;
 	pPriv->contrast = value;
 	overlay->OCLRC0 = (pPriv->contrast << 18) | (pPriv->brightness & 0xff);
 	OVERLAY_DEBUG("CONTRAST\n");
-	i830_overlay_continue (pScrn);
+	i830_overlay_continue (pScrn, FALSE);
     } else if (attribute == xvSaturation) {
 	if ((value < 0) || (value > 1023))
 	    return BadValue;
 	pPriv->saturation = value;
 	overlay->OCLRC1 = pPriv->saturation;
-	i830_overlay_continue (pScrn);
+	i830_overlay_continue (pScrn, FALSE);
     } else if (attribute == xvPipe) {
 	xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
 	if ((value < -1) || (value > xf86_config->num_crtc))
@@ -997,7 +1086,7 @@ I830SetPortAttribute(ScrnInfoPtr pScrn,
 	    break;
 	}
 	OVERLAY_DEBUG("COLORKEY\n");
-	i830_overlay_continue (pScrn);
+	i830_overlay_continue (pScrn, FALSE);
 	REGION_EMPTY(pScrn->pScreen, &pPriv->clip);
     } else if(attribute == xvDoubleBuffer) {
 	if ((value < 0) || (value > 1))
@@ -1612,6 +1701,17 @@ I830CoveringCrtc (ScrnInfoPtr pScrn, Box
     return best_crtc;
 }
 
+static int
+i830_swidth (I830Ptr pI830, unsigned int offset,
+	     unsigned int width, unsigned int mask, int shift)
+{
+    int	swidth = ((offset + width + mask) >> shift) - (offset >> shift);
+    if (IS_I9XX(pI830))
+	swidth <<= 1;
+    swidth -= 1;
+    return swidth << 2;
+}
+
 static void
 I830DisplayVideo(ScrnInfoPtr pScrn, int id, short width, short height,
 		 int dstPitch, int x1, int y1, int x2, int y2, BoxPtr dstBox,
@@ -1619,12 +1719,13 @@ I830DisplayVideo(ScrnInfoPtr pScrn, int 
 {
     I830Ptr pI830 = I830PTR(pScrn);
     I830PortPrivPtr pPriv = pI830->adaptor->pPortPrivates[0].ptr;
-    I830OverlayRegPtr overlay =
-    (I830OverlayRegPtr) (pI830->FbBase + pI830->overlay_regs->offset);
-    unsigned int swidth;
+    I830OverlayRegPtr	overlay = I830OVERLAYREG(pI830);
+    unsigned int swidth, swidthy, swidthuv;
     unsigned int mask, shift, offsety, offsetu;
     xf86CrtcPtr crtc;
-    int tmp;
+    int		tmp;
+    CARD32	OCMD;
+    Bool	scaleChanged = FALSE;
 
     OVERLAY_DEBUG("I830DisplayVideo: %dx%d (pitch %d)\n", width, height,
 		  dstPitch);
@@ -1652,9 +1753,6 @@ I830DisplayVideo(ScrnInfoPtr pScrn, int 
 	return;
     }
     
-    /* Ensure overlay is turned on with OVERLAY_ENABLE at 0 */
-    i830_overlay_on (pScrn);
-
     switch (crtc->rotation & 0xf) {
     case RR_Rotate_0:
 	dstBox->x1 -= crtc->x;
@@ -1798,48 +1896,16 @@ I830DisplayVideo(ScrnInfoPtr pScrn, int 
     switch (id) {
     case FOURCC_YV12:
     case FOURCC_I420:
-	swidth = width;
-
-	overlay->SWIDTH = swidth;
-	swidth /= 2;
-	overlay->SWIDTH |= (swidth & 0x7ff) << 16;
-
-	swidth = ((offsety + width + mask) >> shift) -
-	(offsety >> shift);
-
-	if (IS_I9XX(pI830))
-	    swidth <<= 1;
-
-	swidth -= 1;
-
-	OVERLAY_DEBUG("Y width is %d, swidth is %d\n", width, swidth);
-
-	overlay->SWIDTHSW = swidth << 2;
-
-	swidth = ((offsetu + (width / 2) + mask) >> shift) -
-	(offsetu >> shift);
-
-	if (IS_I9XX(pI830))
-	    swidth <<= 1;
-
-	swidth -= 1;
-
-	OVERLAY_DEBUG("UV width is %d, swidthsw is %d\n", width / 2, swidth);
-
-	overlay->SWIDTHSW |= swidth << 18;
-
-	OVERLAY_DEBUG("HEIGHT is %d\n",height);
-
+	overlay->SWIDTH = width | ((width/2 & 0x7ff) << 16);
+	swidthy  = i830_swidth (pI830, offsety, width, mask, shift);
+	swidthuv = i830_swidth (pI830, offsetu, width/2, mask, shift);
+	overlay->SWIDTHSW = (swidthy) | (swidthuv << 16);
 	overlay->SHEIGHT = height | ((height / 2) << 16);
 	break;
     case FOURCC_UYVY:
     case FOURCC_YUY2:
     default:
-	swidth = width;
-	overlay->SWIDTH = swidth;
-
-	OVERLAY_DEBUG("Y width is %d\n", swidth);
-
+	overlay->SWIDTH = width;
 	swidth = ((offsety + (width << 1) + mask) >> shift) -
 	(offsety >> shift);
 
@@ -1848,18 +1914,18 @@ I830DisplayVideo(ScrnInfoPtr pScrn, int 
 
 	swidth -= 1;
 
-	OVERLAY_DEBUG("swidthsw is %d\n", swidth);
-
-	overlay->SWIDTHSW = swidth << 2;
-
-	OVERLAY_DEBUG("HEIGHT is %d\n",height);
+	swidth <<= 2;
+	
+	OVERLAY_DEBUG("swidthsw is old %d new %d\n",
+		      swidth,
+		      i830_swidth (pI830, offsety, width << 1,
+				   mask, shift));
 
+	overlay->SWIDTHSW = swidth;
 	overlay->SHEIGHT = height;
 	break;
     }
 
-    overlay->OCMD = OVERLAY_ENABLE;
-
     overlay->DWINPOS = (dstBox->y1 << 16) | dstBox->x1;
 
     overlay->DWINSZ = (((dstBox->y2 - dstBox->y1) << 16) |
@@ -1869,59 +1935,14 @@ I830DisplayVideo(ScrnInfoPtr pScrn, int 
 		  dstBox->x1, dstBox->y1, dstBox->x2, dstBox->y2);
 
     /* buffer locations */
-    if (IS_I965G(pI830))
-    {
-	overlay->OBUF_0Y = 0;
-	overlay->OBUF_0U = 0;
-	overlay->OBUF_0V = 0;
-	overlay->OSTART_0Y = pPriv->YBuf0offset;
-	overlay->OSTART_0U = pPriv->UBuf0offset;
-	overlay->OSTART_0V = pPriv->VBuf0offset;
-	if(pPriv->doubleBuffer) {
-	    overlay->OBUF_1Y = 0;
-	    overlay->OBUF_1U = 0;
-	    overlay->OBUF_1V = 0;
-	    overlay->OSTART_1Y = pPriv->YBuf1offset;
-	    overlay->OSTART_1U = pPriv->UBuf1offset;
-	    overlay->OSTART_1V = pPriv->VBuf1offset;
-	}
-    } else {
-	overlay->OBUF_0Y = pPriv->YBuf0offset;
-	overlay->OBUF_0U = pPriv->UBuf0offset;
-	overlay->OBUF_0V = pPriv->VBuf0offset;
-	if(pPriv->doubleBuffer) {
-	    overlay->OBUF_1Y = pPriv->YBuf1offset;
-	    overlay->OBUF_1U = pPriv->UBuf1offset;
-	    overlay->OBUF_1V = pPriv->VBuf1offset;
-	}
-    }
-
-    OVERLAY_DEBUG("Buffers: Y0: 0x%lx, U0: 0x%lx, V0: 0x%lx\n",
-		  overlay->OBUF_0Y, overlay->OBUF_0U, overlay->OBUF_0V);
-    OVERLAY_DEBUG("Buffers: Y1: 0x%lx, U1: 0x%lx, V1: 0x%lx\n",
-		  overlay->OBUF_1Y, overlay->OBUF_1U, overlay->OBUF_1V);
-
-#if 0
-    {
-	int i;
-
-	ErrorF("First 32 bytes of Y data:\n");
-	for (i = 0; i < 32; i++)
-	    ErrorF(" %02x",
-		   ((unsigned char *)pI830->FbBase + pPriv->YBuf0offset)[i]);
-	ErrorF("\n");
-	ErrorF("First 16 bytes of U data:\n");
-	for (i = 0; i < 16; i++)
-	    ErrorF(" %02x",
-		   ((unsigned char *)pI830->FbBase + pPriv->UBuf0offset)[i]);
-	ErrorF("\n");
-	ErrorF("First 16 bytes of V data:\n");
-	for (i = 0; i < 16; i++)
-	    ErrorF(" %02x",
-		   ((unsigned char *)pI830->FbBase + pPriv->VBuf0offset)[i]);
-	ErrorF("\n");
+    overlay->OBUF_0Y = pPriv->YBuf0offset;
+    overlay->OBUF_0U = pPriv->UBuf0offset;
+    overlay->OBUF_0V = pPriv->VBuf0offset;
+    if(pPriv->doubleBuffer) {
+	overlay->OBUF_1Y = pPriv->YBuf1offset;
+	overlay->OBUF_1U = pPriv->UBuf1offset;
+	overlay->OBUF_1V = pPriv->VBuf1offset;
     }
-#endif
 
     OVERLAY_DEBUG("pos: 0x%lx, size: 0x%lx\n",
 		  overlay->DWINPOS, overlay->DWINSZ);
@@ -1933,7 +1954,6 @@ I830DisplayVideo(ScrnInfoPtr pScrn, int 
      */
 
     {
-	Bool scaleChanged = FALSE;
 	int xscaleInt, xscaleFract, yscaleInt, yscaleFract;
 	int xscaleIntUV, xscaleFractUV;
 	int yscaleIntUV, yscaleFractUV;
@@ -2033,22 +2053,24 @@ I830DisplayVideo(ScrnInfoPtr pScrn, int 
 	    for (i = 0; i < N_PHASES; i++) {
 		for (j = 0; j < N_HORIZ_Y_TAPS; j++) {
 		    pos = i * N_HORIZ_Y_TAPS + j;
-		    overlay->Y_HCOEFS[pos] = xcoeffY[pos].sign << 15 |
-		    xcoeffY[pos].exponent << 12 |
-		    xcoeffY[pos].mantissa;
+		    overlay->Y_HCOEFS[pos] = (xcoeffY[pos].sign << 15 |
+					      xcoeffY[pos].exponent << 12 |
+					      xcoeffY[pos].mantissa);
 		}
 	    }
 	    for (i = 0; i < N_PHASES; i++) {
 		for (j = 0; j < N_HORIZ_UV_TAPS; j++) {
 		    pos = i * N_HORIZ_UV_TAPS + j;
-		    overlay->UV_HCOEFS[pos] = xcoeffUV[pos].sign << 15 |
-		    xcoeffUV[pos].exponent << 12 |
-		    xcoeffUV[pos].mantissa;
+		    overlay->UV_HCOEFS[pos] = (xcoeffUV[pos].sign << 15 |
+					       xcoeffUV[pos].exponent << 12 |
+					       xcoeffUV[pos].mantissa);
 		}
 	    }
 	}
     }
 
+    OCMD = OVERLAY_ENABLE;
+    
     switch (id) {
     case FOURCC_YV12:
     case FOURCC_I420:
@@ -2060,32 +2082,36 @@ I830DisplayVideo(ScrnInfoPtr pScrn, int 
 	OVERLAY_DEBUG("UV stride is %d, Y stride is %d\n",
 		      dstPitch, dstPitch * 2);
 	overlay->OSTRIDE = (dstPitch * 2) | (dstPitch << 16);
-	overlay->OCMD &= ~SOURCE_FORMAT;
-	overlay->OCMD &= ~OV_BYTE_ORDER;
-	overlay->OCMD |= YUV_420;
+	OCMD &= ~SOURCE_FORMAT;
+	OCMD &= ~OV_BYTE_ORDER;
+	OCMD |= YUV_420;
 	break;
     case FOURCC_UYVY:
     case FOURCC_YUY2:
     default:
 	OVERLAY_DEBUG("YUV422\n");
 	overlay->OSTRIDE = dstPitch;
-	overlay->OCMD &= ~SOURCE_FORMAT;
-	overlay->OCMD |= YUV_422;
-	overlay->OCMD &= ~OV_BYTE_ORDER;
+	OCMD &= ~SOURCE_FORMAT;
+	OCMD |= YUV_422;
+	OCMD &= ~OV_BYTE_ORDER;
 	if (id == FOURCC_UYVY)
-	    overlay->OCMD |= Y_SWAP;
+	    OCMD |= Y_SWAP;
 	break;
     }
 
-    overlay->OCMD &= ~(BUFFER_SELECT | FIELD_SELECT);
+    OCMD &= ~(BUFFER_SELECT | FIELD_SELECT);
     if (pPriv->currentBuf == 0)
-	overlay->OCMD |= BUFFER0;
+	OCMD |= BUFFER0;
     else
-	overlay->OCMD |= BUFFER1;
+	OCMD |= BUFFER1;
 
-    OVERLAY_DEBUG("OCMD is 0x%lx\n", overlay->OCMD);
+    overlay->OCMD = OCMD;
+    OVERLAY_DEBUG("OCMD is 0x%lx\n", OCMD);
 
-    i830_overlay_continue (pScrn);
+    /* make sure the overlay is on */
+    i830_overlay_on (pScrn);
+    /* and show this frame */
+    i830_overlay_continue (pScrn, scaleChanged);
 }
 
 #ifdef I830_USE_EXA
@@ -2233,8 +2259,7 @@ I830PutImage(ScrnInfoPtr pScrn,
     if (pPriv->textured)
 	overlay = NULL;
     else
-	overlay = (I830OverlayRegPtr) (pI830->FbBase + 
-				       pI830->overlay_regs->offset);
+	overlay = I830OVERLAYREG(pI830);
 
 #if 0
     ErrorF("I830PutImage: src: (%d,%d)(%d,%d), dst: (%d,%d)(%d,%d)\n"
diff --git a/src/i830_video.h b/src/i830_video.h
index 7e2d149..88a7bd9 100644
--- a/src/i830_video.h
+++ b/src/i830_video.h
@@ -77,6 +77,7 @@ typedef struct {
    int oneLineMode;
    int scaleRatio;
    Bool textured;
+   Bool started_video;
 } I830PortPrivRec, *I830PortPrivPtr;
 
 #define GET_PORT_PRIVATE(pScrn) \
diff-tree ff0ac8ea63dd6e55573652c5826c482881da0d62 (from 109e5d597b76f7414601cb39c07b133ebf1b0e61)
Author: Keith Packard <keithp at dulcimer.keithp.com>
Date:   Fri May 25 17:26:15 2007 -0700

    Xv does not require directRendering

diff --git a/src/i830_driver.c b/src/i830_driver.c
index 2cbddb0..8e74903 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -2293,18 +2293,18 @@ I830ScreenInit(int scrnIndex, ScreenPtr 
 #endif
    }
 
+#ifdef I830_XV
+    /*
+     * Set this so that the overlay allocation is factored in when
+     * appropriate.
+     */
+    pI830->XvEnabled = !pI830->XvDisabled;
+#endif
+
    if (!pI830->directRenderingDisabled) {
       int savedDisplayWidth = pScrn->displayWidth;
       Bool tiled = FALSE;
 
-#ifdef I830_XV
-      /*
-       * Set this so that the overlay allocation is factored in when
-       * appropriate.
-       */
-      pI830->XvEnabled = !pI830->XvDisabled;
-#endif
-
       if (IS_I965G(pI830)) {
 	 int tile_pixels = 512 / pI830->cpp;
 	 pScrn->displayWidth = (pScrn->displayWidth + tile_pixels - 1) &
diff-tree 109e5d597b76f7414601cb39c07b133ebf1b0e61 (from dfb1ec9a07f74125cb1724d41ed4342c4714e12b)
Author: Keith Packard <keithp at dulcimer.keithp.com>
Date:   Thu May 24 11:40:50 2007 -0700

    Clean up CRTC selection. Remove more overlay blocking.
    
    Create separate CRTC selection function, use ints instead of floats for
    coverage measurement. Remove pipe stalls waiting for overlay update.

diff --git a/src/i830_video.c b/src/i830_video.c
index e8ba7a8..e2d132e 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -361,13 +361,11 @@ i830_overlay_on(ScrnInfoPtr pScrn)
 	return;
 
     overlay->OCMD &= ~OVERLAY_ENABLE;
-    BEGIN_LP_RING(6);
+    BEGIN_LP_RING(4);
     OUT_RING(MI_FLUSH | MI_WRITE_DIRTY_STATE);
     OUT_RING(MI_NOOP);
     OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_FLIP_ON);
     OUT_RING(pI830->overlay_regs->bus_addr | OFC_UPDATE);
-    OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
-    OUT_RING(MI_NOOP);
     ADVANCE_LP_RING();
     OVERLAY_DEBUG("overlay_on\n");
     *pI830->overlayOn = TRUE;
@@ -384,13 +382,11 @@ i830_overlay_continue(ScrnInfoPtr pScrn)
 	return;
 
     overlay->OCMD |= OVERLAY_ENABLE;
-    BEGIN_LP_RING(6);
+    BEGIN_LP_RING(4);
     OUT_RING(MI_FLUSH | MI_WRITE_DIRTY_STATE);
     OUT_RING(MI_NOOP);
     OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_FLIP_CONTINUE);
     OUT_RING(pI830->overlay_regs->bus_addr | OFC_UPDATE);
-    OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
-    OUT_RING(MI_NOOP);
     ADVANCE_LP_RING();
     OVERLAY_DEBUG("overlay_continue\n");
 }
@@ -1551,8 +1547,12 @@ UpdateCoeff(int taps, double fCutoff, Bo
     }
 }
 
-static float
-I830CrtcVideoCoverage (xf86CrtcPtr crtc, BoxPtr video)
+/*
+ * Return the number of pixels from 'box' covered by 'crtc'.
+ * That is, the area of the intersection of 'box' and 'crtc'
+ */
+static int
+I830CrtcBoxCoverage (xf86CrtcPtr crtc, BoxPtr box)
 {
     BoxRec   dest;
     BoxRec   pipe;
@@ -1569,19 +1569,47 @@ I830CrtcVideoCoverage (xf86CrtcPtr crtc,
 	pipe.x1 = pipe.x2 = 0;
 	pipe.y1 = pipe.y2 = 0;
     }
-    dest.x1 = pipe.x1 > video->x1 ? pipe.x1 : video->x1;
-    dest.x2 = pipe.x2 < video->x2 ? pipe.x2 : video->x2;
-    dest.y1 = pipe.y1 > video->y1 ? pipe.y1 : video->y1;
-    dest.y2 = pipe.y2 < video->y2 ? pipe.y2 : video->y2;
+    dest.x1 = pipe.x1 > box->x1 ? pipe.x1 : box->x1;
+    dest.x2 = pipe.x2 < box->x2 ? pipe.x2 : box->x2;
+    dest.y1 = pipe.y1 > box->y1 ? pipe.y1 : box->y1;
+    dest.y2 = pipe.y2 < box->y2 ? pipe.y2 : box->y2;
     if (dest.x1 >= dest.x2 || dest.y1 >= dest.y2)
     {
 	dest.x1 = dest.x2 = 0;
 	dest.y1 = dest.y2 = 0;
     }
-    if (video->x1 >= video->x2 || video->y1 >= video->y2)
-	return 0.0;
-    return (((float) (dest.x2 - dest.x1) * (float) (dest.y2 - dest.y1)) /
-	    ((float) (video->x2 - video->x1) * (float) (video->y2 - video->y1)));
+    return (int) (dest.x2 - dest.x1) * (int) (dest.y2 - dest.y1);
+}
+
+/*
+ * Return the crtc covering 'box'. If two crtcs cover a portion of
+ * 'box', then prefer 'desired'. If 'desired' is NULL, then prefer the crtc
+ * with greater coverage
+ */
+
+static xf86CrtcPtr
+I830CoveringCrtc (ScrnInfoPtr pScrn, BoxPtr pBox, xf86CrtcPtr desired)
+{
+    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+    xf86CrtcPtr		crtc, best_crtc;
+    int			coverage, best_coverage;
+    int			c;
+
+    best_crtc = NULL;
+    best_coverage = 0;
+    for (c = 0; c < xf86_config->num_crtc; c++)
+    {
+	crtc = xf86_config->crtc[c];
+	coverage = I830CrtcBoxCoverage (crtc, pBox);
+	if (coverage > best_coverage)
+	{
+	    if (crtc == desired)
+		return crtc;
+	    best_crtc = crtc;
+	    best_coverage = coverage;
+	}
+    }
+    return best_crtc;
 }
 
 static void
@@ -1608,35 +1636,11 @@ I830DisplayVideo(ScrnInfoPtr pScrn, int 
     CompareOverlay(pI830, (CARD32 *) overlay, 0x100);
 #endif
 
+    crtc = I830CoveringCrtc (pScrn, dstBox, pPriv->desired_crtc);
+    if (crtc != pPriv->current_crtc)
     {
-	int		    coverage;
-	int		    c;
-	xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
-
-	crtc = NULL;
-	for (c = 0; c < xf86_config->num_crtc; c++)
-	{
-	    xf86CrtcPtr	this_crtc = xf86_config->crtc[c];
-	    coverage = I830CrtcVideoCoverage (this_crtc, dstBox);
-	    if (coverage)
-	    {
-		if (this_crtc == pPriv->desired_crtc)
-		{
-		    crtc = this_crtc;
-		    best_coverage = 1.0;
-		}
-		else if (coverage > best_coverage)
-		{
-		    crtc = this_crtc;
-		    best_coverage = coverage;
-		}
-	    }
-	}
-	if (crtc != pPriv->current_crtc)
-	{
-	    pPriv->current_crtc = crtc;
-	    I830ResetVideo (pScrn);
-	}
+        pPriv->current_crtc = crtc;
+        I830ResetVideo (pScrn);
     }
 
     /*
@@ -2221,7 +2225,7 @@ I830PutImage(ScrnInfoPtr pScrn,
     PixmapPtr pPixmap;
     INT32 x1, x2, y1, y2;
     int srcPitch, srcPitch2 = 0, dstPitch, destId;
-    int top, left, npixels, nlines, size, loops;
+    int top, left, npixels, nlines, size;
     BoxRec dstBox;
     int pitchAlignMask;
     int extraLinear;
diff-tree dfb1ec9a07f74125cb1724d41ed4342c4714e12b (from d172344599585e11388e59659dc9aaa86d7a31c1)
Author: Keith Packard <keithp at dulcimer.keithp.com>
Date:   Thu May 24 11:23:44 2007 -0700

    Eliminate blocking for video overlay.
    
    No need to block for the overlay; just use the idle buffer.  This will
    always work because the buffer switch occurs at vblank time, so there is
    always plenty of time to get the next buffer contents in place before it
    starts getting scanned to the screen.

diff --git a/src/i830_video.c b/src/i830_video.c
index 9cbd220..e8ba7a8 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -134,7 +134,7 @@ static Atom xvGamma0, xvGamma1, xvGamma2
 #define IMAGE_MAX_HEIGHT_LEGACY	1088
 
 /* overlay debugging printf function */
-#if 1
+#if 0
 #define OVERLAY_DEBUG ErrorF
 #else
 #define OVERLAY_DEBUG if (0) ErrorF
@@ -950,23 +950,20 @@ I830SetPortAttribute(ScrnInfoPtr pScrn,
 	pPriv->brightness = value;
 	overlay->OCLRC0 = (pPriv->contrast << 18) | (pPriv->brightness & 0xff);
 	OVERLAY_DEBUG("BRIGHTNESS\n");
-	if (*pI830->overlayOn)
-	    i830_overlay_continue (pScrn);
+	i830_overlay_continue (pScrn);
     } else if (attribute == xvContrast) {
 	if ((value < 0) || (value > 255))
 	    return BadValue;
 	pPriv->contrast = value;
 	overlay->OCLRC0 = (pPriv->contrast << 18) | (pPriv->brightness & 0xff);
 	OVERLAY_DEBUG("CONTRAST\n");
-	if (*pI830->overlayOn)
-	    i830_overlay_continue (pScrn);
+	i830_overlay_continue (pScrn);
     } else if (attribute == xvSaturation) {
 	if ((value < 0) || (value > 1023))
 	    return BadValue;
 	pPriv->saturation = value;
 	overlay->OCLRC1 = pPriv->saturation;
-	if (*pI830->overlayOn)
-	    i830_overlay_continue (pScrn);
+	i830_overlay_continue (pScrn);
     } else if (attribute == xvPipe) {
 	xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
 	if ((value < -1) || (value > xf86_config->num_crtc))
@@ -1004,8 +1001,7 @@ I830SetPortAttribute(ScrnInfoPtr pScrn,
 	    break;
 	}
 	OVERLAY_DEBUG("COLORKEY\n");
-	if (*pI830->overlayOn)
-	    i830_overlay_continue (pScrn);
+	i830_overlay_continue (pScrn);
 	REGION_EMPTY(pScrn->pScreen, &pPriv->clip);
     } else if(attribute == xvDoubleBuffer) {
 	if ((value < 0) || (value > 1))
@@ -1613,9 +1609,8 @@ I830DisplayVideo(ScrnInfoPtr pScrn, int 
 #endif
 
     {
-	float best_coverage = 0.0;
-	float coverage;
-	int c;
+	int		    coverage;
+	int		    c;
 	xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
 
 	crtc = NULL;
@@ -1644,6 +1639,18 @@ I830DisplayVideo(ScrnInfoPtr pScrn, int 
 	}
     }
 
+    /*
+     * If the video isn't visible on any CRTC, turn it off
+     */
+    if (!crtc)
+    {
+	i830_overlay_off (pScrn);
+	return;
+    }
+    
+    /* Ensure overlay is turned on with OVERLAY_ENABLE at 0 */
+    i830_overlay_on (pScrn);
+
     switch (crtc->rotation & 0xf) {
     case RR_Rotate_0:
 	dstBox->x1 -= crtc->x;
@@ -1683,15 +1690,6 @@ I830DisplayVideo(ScrnInfoPtr pScrn, int 
 	break;
     }
 
-    /* When in dual head with different bpp setups we need to refresh the
-     * color key, so let's reset the video parameters and refresh here.
-     * In MergedFB mode, we may need to flip pipes too. */
-    if (pI830->entityPrivate)
-	I830ResetVideo(pScrn);
-
-    /* Ensure overlay is turned on with OVERLAY_ENABLE at 0 */
-    i830_overlay_on (pScrn);
-
     /* Fix up the dstBox if outside the visible screen */
     {
 	int offset_x = (dstBox->x1 < 0) ? -dstBox->x1 : 0;
@@ -1770,22 +1768,8 @@ I830DisplayVideo(ScrnInfoPtr pScrn, int 
 	if (dstBox->x2 > hactive) dstBox->x2 = hactive;
 
 	/* nothing do to */
-	if ((!dstBox->x1 && !dstBox->x2) || (!dstBox->y1 && !dstBox->y2)) {
-	    OVERLAY_DEBUG("NOTHING TO DO\n");
-	    return;
-	}
-	if ((dstBox->x1 == (hactive) && 
-	     dstBox->x2 == (hactive)) || 
-	    (dstBox->y1 == vactive && 
-	     dstBox->y2 == vactive)) {
-	    OVERLAY_DEBUG("NOTHING TO DO\n");
-	    return;
-	}
-	if ((dstBox->y2 - dstBox->y1) <= N_VERT_Y_TAPS) {
-	    OVERLAY_DEBUG("NOTHING TO DO\n");
-	    return;
-	}
-	if ((dstBox->x2 - dstBox->x1) <= 2) {
+	if (dstBox->x2 - dstBox->x1 <= 2 || dstBox->y2 - dstBox->y1 < N_VERT_Y_TAPS)
+	{
 	    OVERLAY_DEBUG("NOTHING TO DO\n");
 	    return;
 	}
@@ -1874,8 +1858,8 @@ I830DisplayVideo(ScrnInfoPtr pScrn, int 
 
     overlay->DWINPOS = (dstBox->y1 << 16) | dstBox->x1;
 
-    overlay->DWINSZ = ((dstBox->y2 - dstBox->y1) << 16) |
-    (dstBox->x2 - dstBox->x1);
+    overlay->DWINSZ = (((dstBox->y2 - dstBox->y1) << 16) |
+		       (dstBox->x2 - dstBox->x1));
 
     OVERLAY_DEBUG("dstBox: x1: %d, y1: %d, x2: %d, y2: %d\n",
 		  dstBox->x1, dstBox->y1, dstBox->x2, dstBox->y2);
@@ -2387,47 +2371,15 @@ I830PutImage(ScrnInfoPtr pScrn,
 	}
     }
 
-    /* Make sure this buffer isn't in use */
-    loops = 0;
-    if (!pPriv->textured && *pI830->overlayOn && pPriv->doubleBuffer &&
-	(overlay->OCMD & OVERLAY_ENABLE))
-    {
-	while (loops < 1000000) {
-#if USE_USLEEP_FOR_VIDEO
-	    usleep(10);
-#endif
-	    if (((INREG(DOVSTA) & OC_BUF) >> 20) == pPriv->currentBuf) {
-		break;
-	    }
-	    loops++;
-	}
-	if (loops >= 1000000) {
-	    ErrorF("loops (1) maxed out for buffer %d\n", pPriv->currentBuf);
-#if 0
-	    pPriv->currentBuf = !pPriv->currentBuf;
-#endif
-	}
-
-	/* buffer swap */
-	if (pPriv->currentBuf == 0)
-	    pPriv->currentBuf = 1;
-	else
-	    pPriv->currentBuf = 0;
-    }
+    /* Pick the idle buffer */
+    if (!pPriv->textured && *pI830->overlayOn && pPriv->doubleBuffer)
+	pPriv->currentBuf = !((INREG(DOVSTA) & OC_BUF) >> 20);
 
     /* copy data */
     top = y1 >> 16;
     left = (x1 >> 16) & ~1;
     npixels = ((((x2 + 0xffff) >> 16) + 1) & ~1) - left;
 
-    if (pPriv->textured) {
-	/* For textured video, we don't double buffer, and instead just wait for
-	 * acceleration to finish before writing the new video data into
-	 * framebuffer.
-	 */
-	i830WaitSync(pScrn);
-    }
-
     switch (id) {
     case FOURCC_YV12:
     case FOURCC_I420:
diff-tree d172344599585e11388e59659dc9aaa86d7a31c1 (from 02935ced3fba598a01d908ae49ccc30cbcc765a8)
Author: Keith Packard <keithp at dulcimer.keithp.com>
Date:   Wed May 23 20:00:16 2007 -0700

    Reformat i830_video.c to four-space indents.
    
    Yes, I can't stand it anymore. it's a huge patch, but
    git-diff -w shows no changes.

diff --git a/src/i830_video.c b/src/i830_video.c
index 2462d5d..9cbd220 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -1,42 +1,29 @@
 /***************************************************************************
- 
-Copyright 2000 Intel Corporation.  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 INTEL, 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.
+ Copyright 2000 Intel Corporation.  All Rights Reserved. 
 
-**************************************************************************/
-/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i810/i830_video.c,v 1.11tsi Exp $ */
+ 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 INTEL, 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.
 
-/*
- * Reformatted with GNU indent (2.2.8), using the following options:
- *
- *    -bad -bap -c41 -cd0 -ncdb -ci6 -cli0 -cp0 -ncs -d0 -di3 -i3 -ip3 -l78
- *    -lp -npcs -psl -sob -ss -br -ce -sc -hnl
- *
- * This provides a good match with the original i810 code and preferred
- * XFree86 formatting conventions.
- *
- * When editing this driver, please follow the existing formatting, and edit
- * with <TAB> characters expanded at 8-column intervals.
- */
+ **************************************************************************/
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i810/i830_video.c,v 1.11tsi Exp $ */
 
 /*
  * i830_video.c: i830/i845 Xv driver. 
@@ -219,139 +206,139 @@ void exaMoveInPixmap (PixmapPtr pPixmap)
 #define MAX_CUTOFF_FREQ		3.0
 
 #define RGB16ToColorKey(c) \
-	(((c & 0xF800) << 8) | ((c & 0x07E0) << 5) | ((c & 0x001F) << 3))
+(((c & 0xF800) << 8) | ((c & 0x07E0) << 5) | ((c & 0x001F) << 3))
 
 #define RGB15ToColorKey(c) \
-        (((c & 0x7c00) << 9) | ((c & 0x03E0) << 6) | ((c & 0x001F) << 3))
+(((c & 0x7c00) << 9) | ((c & 0x03E0) << 6) | ((c & 0x001F) << 3))
 
 /* client libraries expect an encoding */
 static XF86VideoEncodingRec DummyEncoding[1] = {
-   {
-      0,
-      "XV_IMAGE",
-      IMAGE_MAX_WIDTH, IMAGE_MAX_HEIGHT,
-      {1, 1}
-   }
+    {
+	0,
+	"XV_IMAGE",
+	IMAGE_MAX_WIDTH, IMAGE_MAX_HEIGHT,
+	{1, 1}
+    }
 };
 
 #define NUM_FORMATS 3
 
 static XF86VideoFormatRec Formats[NUM_FORMATS] = {
-   {15, TrueColor}, {16, TrueColor}, {24, TrueColor}
+    {15, TrueColor}, {16, TrueColor}, {24, TrueColor}
 };
 
 #define CLONE_ATTRIBUTES 1
 static XF86AttributeRec CloneAttributes[CLONE_ATTRIBUTES] = {
-   {XvSettable | XvGettable, 0, 1, "XV_PIPE"}
+    {XvSettable | XvGettable, 0, 1, "XV_PIPE"}
 };
 
 #define NUM_ATTRIBUTES 5
 static XF86AttributeRec Attributes[NUM_ATTRIBUTES] = {
-   {XvSettable | XvGettable, 0, (1 << 24) - 1, "XV_COLORKEY"},
-   {XvSettable | XvGettable, -128, 127, "XV_BRIGHTNESS"},
-   {XvSettable | XvGettable, 0, 255, "XV_CONTRAST"},
-   {XvSettable | XvGettable, 0, 1023, "XV_SATURATION"},
-   {XvSettable | XvGettable, 0, 1, "XV_DOUBLE_BUFFER"}
+    {XvSettable | XvGettable, 0, (1 << 24) - 1, "XV_COLORKEY"},
+    {XvSettable | XvGettable, -128, 127, "XV_BRIGHTNESS"},
+    {XvSettable | XvGettable, 0, 255, "XV_CONTRAST"},
+    {XvSettable | XvGettable, 0, 1023, "XV_SATURATION"},
+    {XvSettable | XvGettable, 0, 1, "XV_DOUBLE_BUFFER"}
 };
 
 #define NUM_TEXTURED_ATTRIBUTES 2
 static XF86AttributeRec TexturedAttributes[NUM_ATTRIBUTES] = {
-   {XvSettable | XvGettable, -128, 127, "XV_BRIGHTNESS"},
-   {XvSettable | XvGettable, 0, 255, "XV_CONTRAST"},
+    {XvSettable | XvGettable, -128, 127, "XV_BRIGHTNESS"},
+    {XvSettable | XvGettable, 0, 255, "XV_CONTRAST"},
 };
 
 #define GAMMA_ATTRIBUTES 6
 static XF86AttributeRec GammaAttributes[GAMMA_ATTRIBUTES] = {
-   {XvSettable | XvGettable, 0, 0xffffff, "XV_GAMMA0"},
-   {XvSettable | XvGettable, 0, 0xffffff, "XV_GAMMA1"},
-   {XvSettable | XvGettable, 0, 0xffffff, "XV_GAMMA2"},
-   {XvSettable | XvGettable, 0, 0xffffff, "XV_GAMMA3"},
-   {XvSettable | XvGettable, 0, 0xffffff, "XV_GAMMA4"},
-   {XvSettable | XvGettable, 0, 0xffffff, "XV_GAMMA5"}
+    {XvSettable | XvGettable, 0, 0xffffff, "XV_GAMMA0"},
+    {XvSettable | XvGettable, 0, 0xffffff, "XV_GAMMA1"},
+    {XvSettable | XvGettable, 0, 0xffffff, "XV_GAMMA2"},
+    {XvSettable | XvGettable, 0, 0xffffff, "XV_GAMMA3"},
+    {XvSettable | XvGettable, 0, 0xffffff, "XV_GAMMA4"},
+    {XvSettable | XvGettable, 0, 0xffffff, "XV_GAMMA5"}
 };
 
 #define NUM_IMAGES 4
 
 static XF86ImageRec Images[NUM_IMAGES] = {
-   XVIMAGE_YUY2,
-   XVIMAGE_YV12,
-   XVIMAGE_I420,
-   XVIMAGE_UYVY
+    XVIMAGE_YUY2,
+    XVIMAGE_YV12,
+    XVIMAGE_I420,
+    XVIMAGE_UYVY
 };
 
 typedef struct {
-   CARD32 OBUF_0Y;
-   CARD32 OBUF_1Y;
-   CARD32 OBUF_0U;
-   CARD32 OBUF_0V;
-   CARD32 OBUF_1U;
-   CARD32 OBUF_1V;
-   CARD32 OSTRIDE;
-   CARD32 YRGB_VPH;
-   CARD32 UV_VPH;
-   CARD32 HORZ_PH;
-   CARD32 INIT_PHS;
-   CARD32 DWINPOS;
-   CARD32 DWINSZ;
-   CARD32 SWIDTH;
-   CARD32 SWIDTHSW;
-   CARD32 SHEIGHT;
-   CARD32 YRGBSCALE;
-   CARD32 UVSCALE;
-   CARD32 OCLRC0;
-   CARD32 OCLRC1;
-   CARD32 DCLRKV;
-   CARD32 DCLRKM;
-   CARD32 SCLRKVH;
-   CARD32 SCLRKVL;
-   CARD32 SCLRKEN;
-   CARD32 OCONFIG;
-   CARD32 OCMD;
-   CARD32 RESERVED1;			/* 0x6C */
-   CARD32 OSTART_0Y; 		/* for i965 */
-   CARD32 OSTART_1Y;		/* for i965 */
-   CARD32 OSTART_0U;
-   CARD32 OSTART_0V;
-   CARD32 OSTART_1U;
-   CARD32 OSTART_1V;
-   CARD32 OTILEOFF_0Y;
-   CARD32 OTILEOFF_1Y;
-   CARD32 OTILEOFF_0U;
-   CARD32 OTILEOFF_0V;
-   CARD32 OTILEOFF_1U;
-   CARD32 OTILEOFF_1V;
-   CARD32 FASTHSCALE;			/* 0xA0 */
-   CARD32 UVSCALEV;			/* 0xA4 */
-
-   CARD32 RESERVEDC[(0x200 - 0xA8) / 4];		   /* 0xA8 - 0x1FC */
-   CARD16 Y_VCOEFS[N_VERT_Y_TAPS * N_PHASES];		   /* 0x200 */
-   CARD16 RESERVEDD[0x100 / 2 - N_VERT_Y_TAPS * N_PHASES];
-   CARD16 Y_HCOEFS[N_HORIZ_Y_TAPS * N_PHASES];		   /* 0x300 */
-   CARD16 RESERVEDE[0x200 / 2 - N_HORIZ_Y_TAPS * N_PHASES];
-   CARD16 UV_VCOEFS[N_VERT_UV_TAPS * N_PHASES];		   /* 0x500 */
-   CARD16 RESERVEDF[0x100 / 2 - N_VERT_UV_TAPS * N_PHASES];
-   CARD16 UV_HCOEFS[N_HORIZ_UV_TAPS * N_PHASES];	   /* 0x600 */
-   CARD16 RESERVEDG[0x100 / 2 - N_HORIZ_UV_TAPS * N_PHASES];
+    CARD32 OBUF_0Y;
+    CARD32 OBUF_1Y;
+    CARD32 OBUF_0U;
+    CARD32 OBUF_0V;
+    CARD32 OBUF_1U;
+    CARD32 OBUF_1V;
+    CARD32 OSTRIDE;
+    CARD32 YRGB_VPH;
+    CARD32 UV_VPH;
+    CARD32 HORZ_PH;
+    CARD32 INIT_PHS;
+    CARD32 DWINPOS;
+    CARD32 DWINSZ;
+    CARD32 SWIDTH;
+    CARD32 SWIDTHSW;
+    CARD32 SHEIGHT;
+    CARD32 YRGBSCALE;
+    CARD32 UVSCALE;
+    CARD32 OCLRC0;
+    CARD32 OCLRC1;
+    CARD32 DCLRKV;
+    CARD32 DCLRKM;
+    CARD32 SCLRKVH;
+    CARD32 SCLRKVL;
+    CARD32 SCLRKEN;
+    CARD32 OCONFIG;
+    CARD32 OCMD;
+    CARD32 RESERVED1;			/* 0x6C */
+    CARD32 OSTART_0Y; 		/* for i965 */
+    CARD32 OSTART_1Y;		/* for i965 */
+    CARD32 OSTART_0U;
+    CARD32 OSTART_0V;
+    CARD32 OSTART_1U;
+    CARD32 OSTART_1V;
+    CARD32 OTILEOFF_0Y;
+    CARD32 OTILEOFF_1Y;
+    CARD32 OTILEOFF_0U;
+    CARD32 OTILEOFF_0V;
+    CARD32 OTILEOFF_1U;
+    CARD32 OTILEOFF_1V;
+    CARD32 FASTHSCALE;			/* 0xA0 */
+    CARD32 UVSCALEV;			/* 0xA4 */
+
+    CARD32 RESERVEDC[(0x200 - 0xA8) / 4];		   /* 0xA8 - 0x1FC */
+    CARD16 Y_VCOEFS[N_VERT_Y_TAPS * N_PHASES];		   /* 0x200 */
+    CARD16 RESERVEDD[0x100 / 2 - N_VERT_Y_TAPS * N_PHASES];
+    CARD16 Y_HCOEFS[N_HORIZ_Y_TAPS * N_PHASES];		   /* 0x300 */
+    CARD16 RESERVEDE[0x200 / 2 - N_HORIZ_Y_TAPS * N_PHASES];
+    CARD16 UV_VCOEFS[N_VERT_UV_TAPS * N_PHASES];		   /* 0x500 */
+    CARD16 RESERVEDF[0x100 / 2 - N_VERT_UV_TAPS * N_PHASES];
+    CARD16 UV_HCOEFS[N_HORIZ_UV_TAPS * N_PHASES];	   /* 0x600 */
+    CARD16 RESERVEDG[0x100 / 2 - N_HORIZ_UV_TAPS * N_PHASES];
 } I830OverlayRegRec, *I830OverlayRegPtr;
 
 #if VIDEO_DEBUG
 static void
 CompareOverlay(I830Ptr pI830, CARD32 * overlay, int size)
 {
-   int i;
-   CARD32 val;
-   int bad = 0;
-
-   for (i = 0; i < size; i += 4) {
-      val = INREG(0x30100 + i);
-      if (val != overlay[i / 4]) {
-	 OVERLAY_DEBUG("0x%05x value doesn't match (0x%lx != 0x%lx)\n",
-		0x30100 + i, val, overlay[i / 4]);
-	 bad++;
-      }
-   }
-   if (!bad)
-      OVERLAY_DEBUG("CompareOverlay: no differences\n");
+    int i;
+    CARD32 val;
+    int bad = 0;
+
+    for (i = 0; i < size; i += 4) {
+	val = INREG(0x30100 + i);
+	if (val != overlay[i / 4]) {
+	    OVERLAY_DEBUG("0x%05x value doesn't match (0x%lx != 0x%lx)\n",
+			  0x30100 + i, val, overlay[i / 4]);
+	    bad++;
+	}
+    }
+    if (!bad)
+	OVERLAY_DEBUG("CompareOverlay: no differences\n");
 }
 #endif
 
@@ -369,7 +356,7 @@ i830_overlay_on(ScrnInfoPtr pScrn)
     I830Ptr pI830 = I830PTR(pScrn);
     I830OverlayRegPtr	overlay = (I830OverlayRegPtr) (pI830->FbBase +
 						       pI830->overlay_regs->offset);
-    
+
     if (*pI830->overlayOn)
 	return;
 
@@ -414,10 +401,10 @@ i830_overlay_off(ScrnInfoPtr pScrn)
     I830Ptr pI830 = I830PTR(pScrn);
     I830OverlayRegPtr	overlay = (I830OverlayRegPtr) (pI830->FbBase +
 						       pI830->overlay_regs->offset);
-    
+
     if (!*pI830->overlayOn)
 	return;
-    
+
     overlay->OCMD &= ~OVERLAY_ENABLE;
     BEGIN_LP_RING(6);
     OUT_RING(MI_FLUSH | MI_WRITE_DIRTY_STATE);
@@ -435,165 +422,165 @@ i830_overlay_off(ScrnInfoPtr pScrn)
 void
 I830InitVideo(ScreenPtr pScreen)
 {
-   ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
-   I830Ptr pI830 = I830PTR(pScrn);
-   XF86VideoAdaptorPtr *adaptors, *newAdaptors = NULL;
-   XF86VideoAdaptorPtr overlayAdaptor = NULL, texturedAdaptor = NULL;
-   int num_adaptors;
+    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+    I830Ptr pI830 = I830PTR(pScrn);
+    XF86VideoAdaptorPtr *adaptors, *newAdaptors = NULL;
+    XF86VideoAdaptorPtr overlayAdaptor = NULL, texturedAdaptor = NULL;
+    int num_adaptors;
 
 #if 0
-   {
-      I830OverlayRegRec tmp;
+    {
+	I830OverlayRegRec tmp;
+
+	ErrorF("sizeof I830OverlayRegRec is 0x%x\n", sizeof(I830OverlayRegRec));
+	ErrorF("Reserved C, D, E, F, G are %x, %x, %x, %x, %x\n",
+	       (unsigned long)&(tmp.RESERVEDC[0]) - (unsigned long)&tmp,
+	       (unsigned long)&(tmp.RESERVEDD[0]) - (unsigned long)&tmp,
+	       (unsigned long)&(tmp.RESERVEDE[0]) - (unsigned long)&tmp,
+	       (unsigned long)&(tmp.RESERVEDF[0]) - (unsigned long)&tmp,
+	       (unsigned long)&(tmp.RESERVEDG[0]) - (unsigned long)&tmp);
+    }
+#endif
+
+    num_adaptors = xf86XVListGenericAdaptors(pScrn, &adaptors);
+    /* Give our adaptor list enough space for the overlay and/or texture video
+     * adaptors.
+     */
+    newAdaptors = xalloc((num_adaptors + 2) * sizeof(XF86VideoAdaptorPtr *));
+    if (newAdaptors == NULL)
+	return;
+
+    memcpy(newAdaptors, adaptors, num_adaptors * sizeof(XF86VideoAdaptorPtr));
+    adaptors = newAdaptors;
 
-      ErrorF("sizeof I830OverlayRegRec is 0x%x\n", sizeof(I830OverlayRegRec));
-      ErrorF("Reserved C, D, E, F, G are %x, %x, %x, %x, %x\n",
-	     (unsigned long)&(tmp.RESERVEDC[0]) - (unsigned long)&tmp,
-	     (unsigned long)&(tmp.RESERVEDD[0]) - (unsigned long)&tmp,
-	     (unsigned long)&(tmp.RESERVEDE[0]) - (unsigned long)&tmp,
-	     (unsigned long)&(tmp.RESERVEDF[0]) - (unsigned long)&tmp,
-	     (unsigned long)&(tmp.RESERVEDG[0]) - (unsigned long)&tmp);
-   }
-#endif
-
-   num_adaptors = xf86XVListGenericAdaptors(pScrn, &adaptors);
-   /* Give our adaptor list enough space for the overlay and/or texture video
-    * adaptors.
-    */
-   newAdaptors = xalloc((num_adaptors + 2) * sizeof(XF86VideoAdaptorPtr *));
-   if (newAdaptors == NULL)
-      return;
-
-   memcpy(newAdaptors, adaptors, num_adaptors * sizeof(XF86VideoAdaptorPtr));
-   adaptors = newAdaptors;
-
-   /* Add the adaptors supported by our hardware.  First, set up the atoms
-    * that will be used by both output adaptors.
-    */
-   xvBrightness = MAKE_ATOM("XV_BRIGHTNESS");
-   xvContrast = MAKE_ATOM("XV_CONTRAST");
-
-   /* Set up textured video if we can do it at this depth and we are on
-    * supported hardware.
-    */
-   if (pScrn->bitsPerPixel >= 16 && (IS_I9XX(pI830) || IS_I965G(pI830))) {
-      texturedAdaptor = I830SetupImageVideoTextured(pScreen);
-      if (texturedAdaptor != NULL) {
-	 adaptors[num_adaptors++] = texturedAdaptor;
-	 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Set up textured video\n");
-      } else {
-	 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
-		    "Failed to set up textured video\n");
-      }
-   }
-
-   /* Set up overlay video if we can do it at this depth. */
-   if (!IS_I965G(pI830) && pScrn->bitsPerPixel != 8 &&
-       pI830->overlay_regs != NULL)
-   {
-      overlayAdaptor = I830SetupImageVideoOverlay(pScreen);
-      if (overlayAdaptor != NULL) {
-	 adaptors[num_adaptors++] = overlayAdaptor;
-	 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Set up overlay video\n");
-      } else {
-	 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
-		    "Failed to set up overlay video\n");
-      }
-      I830InitOffscreenImages(pScreen);
-   }
+    /* Add the adaptors supported by our hardware.  First, set up the atoms
+     * that will be used by both output adaptors.
+     */
+    xvBrightness = MAKE_ATOM("XV_BRIGHTNESS");
+    xvContrast = MAKE_ATOM("XV_CONTRAST");
+
+    /* Set up textured video if we can do it at this depth and we are on
+     * supported hardware.
+     */
+    if (pScrn->bitsPerPixel >= 16 && (IS_I9XX(pI830) || IS_I965G(pI830))) {
+	texturedAdaptor = I830SetupImageVideoTextured(pScreen);
+	if (texturedAdaptor != NULL) {
+	    adaptors[num_adaptors++] = texturedAdaptor;
+	    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Set up textured video\n");
+	} else {
+	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+		       "Failed to set up textured video\n");
+	}
+    }
+
+    /* Set up overlay video if we can do it at this depth. */
+    if (!IS_I965G(pI830) && pScrn->bitsPerPixel != 8 &&
+	pI830->overlay_regs != NULL)
+    {
+	overlayAdaptor = I830SetupImageVideoOverlay(pScreen);
+	if (overlayAdaptor != NULL) {
+	    adaptors[num_adaptors++] = overlayAdaptor;
+	    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Set up overlay video\n");
+	} else {
+	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+		       "Failed to set up overlay video\n");
+	}
+	I830InitOffscreenImages(pScreen);
+    }
 
-   if (num_adaptors)
-      xf86XVScreenInit(pScreen, adaptors, num_adaptors);
+    if (num_adaptors)
+	xf86XVScreenInit(pScreen, adaptors, num_adaptors);
 
-   xfree(adaptors);
+    xfree(adaptors);
 }
 
 static int
 I830CrtcPipe (xf86CrtcPtr crtc)
 {
-   if (crtc == NULL)
-      return 0;
-   return ((I830CrtcPrivatePtr) crtc->driver_private)->pipe;
+    if (crtc == NULL)
+	return 0;
+    return ((I830CrtcPrivatePtr) crtc->driver_private)->pipe;
 }
 
 static void
 I830ResetVideo(ScrnInfoPtr pScrn)
 {
-   I830Ptr pI830 = I830PTR(pScrn);
-   I830PortPrivPtr pPriv = pI830->adaptor->pPortPrivates[0].ptr;
-   I830OverlayRegPtr overlay =
-	 (I830OverlayRegPtr) (pI830->FbBase + pI830->overlay_regs->offset);
-
-   OVERLAY_DEBUG("I830ResetVideo: base: %p, offset: 0x%lx, obase: %p\n",
-	   pI830->FbBase, pI830->overlay_regs->offset, overlay);
-   /*
-    * Default to maximum image size in YV12
-    */
-
-   memset(overlay, 0, sizeof(*overlay));
-   overlay->YRGB_VPH = 0;
-   overlay->UV_VPH = 0;
-   overlay->HORZ_PH = 0;
-   overlay->INIT_PHS = 0;
-   overlay->DWINPOS = 0;
-   overlay->DWINSZ = 0;
-   overlay->SWIDTH = 0;
-   overlay->SWIDTHSW = 0;
-   overlay->SHEIGHT = 0;
-   overlay->OCLRC0 = (pPriv->contrast << 18) | (pPriv->brightness & 0xff);
-   overlay->OCLRC1 = pPriv->saturation;
+    I830Ptr pI830 = I830PTR(pScrn);
+    I830PortPrivPtr pPriv = pI830->adaptor->pPortPrivates[0].ptr;
+    I830OverlayRegPtr overlay =
+    (I830OverlayRegPtr) (pI830->FbBase + pI830->overlay_regs->offset);
+
+    OVERLAY_DEBUG("I830ResetVideo: base: %p, offset: 0x%lx, obase: %p\n",
+		  pI830->FbBase, pI830->overlay_regs->offset, overlay);
+    /*
+     * Default to maximum image size in YV12
+     */
+
+    memset(overlay, 0, sizeof(*overlay));
+    overlay->YRGB_VPH = 0;
+    overlay->UV_VPH = 0;
+    overlay->HORZ_PH = 0;
+    overlay->INIT_PHS = 0;
+    overlay->DWINPOS = 0;
+    overlay->DWINSZ = 0;
+    overlay->SWIDTH = 0;
+    overlay->SWIDTHSW = 0;
+    overlay->SHEIGHT = 0;
+    overlay->OCLRC0 = (pPriv->contrast << 18) | (pPriv->brightness & 0xff);
+    overlay->OCLRC1 = pPriv->saturation;
 #if 0
-   overlay->AWINPOS = 0;
-   overlay->AWINSZ = 0;
+    overlay->AWINPOS = 0;
+    overlay->AWINSZ = 0;
 #endif
-   overlay->FASTHSCALE = 0;
+    overlay->FASTHSCALE = 0;
 
-   /*
-    * Enable destination color keying
-    */
-   switch (pScrn->depth) {
-   case 8:
-      overlay->DCLRKV = 0;
-      overlay->DCLRKM = 0xffffff | DEST_KEY_ENABLE;
-      break;
-   case 15:
-      overlay->DCLRKV = RGB15ToColorKey(pPriv->colorKey);
-      overlay->DCLRKM = 0x070707 | DEST_KEY_ENABLE;
-      break;
-   case 16:
-      overlay->DCLRKV = RGB16ToColorKey(pPriv->colorKey);
-      overlay->DCLRKM = 0x070307 | DEST_KEY_ENABLE;
-      break;
-   default:
-      overlay->DCLRKV = pPriv->colorKey;
-      overlay->DCLRKM = DEST_KEY_ENABLE;
-      break;
-   }
-
-   overlay->SCLRKVH = 0;
-   overlay->SCLRKVL = 0;
-   overlay->SCLRKEN = 0;		/* source color key disable */
-   overlay->OCONFIG = CC_OUT_8BIT;
-
-   /*
-    * Select which pipe the overlay is enabled on.
-    */
-   overlay->OCONFIG &= ~OVERLAY_PIPE_MASK;
-   if (I830CrtcPipe (pPriv->current_crtc) == 0)
-      overlay->OCONFIG |= OVERLAY_PIPE_A;
-   else 
-      overlay->OCONFIG |= OVERLAY_PIPE_B;
+    /*
+     * Enable destination color keying
+     */
+    switch (pScrn->depth) {
+    case 8:
+	overlay->DCLRKV = 0;
+	overlay->DCLRKM = 0xffffff | DEST_KEY_ENABLE;
+	break;
+    case 15:
+	overlay->DCLRKV = RGB15ToColorKey(pPriv->colorKey);
+	overlay->DCLRKM = 0x070707 | DEST_KEY_ENABLE;
+	break;
+    case 16:
+	overlay->DCLRKV = RGB16ToColorKey(pPriv->colorKey);
+	overlay->DCLRKM = 0x070307 | DEST_KEY_ENABLE;
+	break;
+    default:
+	overlay->DCLRKV = pPriv->colorKey;
+	overlay->DCLRKM = DEST_KEY_ENABLE;
+	break;
+    }
+
+    overlay->SCLRKVH = 0;
+    overlay->SCLRKVL = 0;
+    overlay->SCLRKEN = 0;		/* source color key disable */
+    overlay->OCONFIG = CC_OUT_8BIT;
+
+    /*
+     * Select which pipe the overlay is enabled on.
+     */
+    overlay->OCONFIG &= ~OVERLAY_PIPE_MASK;
+    if (I830CrtcPipe (pPriv->current_crtc) == 0)
+	overlay->OCONFIG |= OVERLAY_PIPE_A;
+    else 
+	overlay->OCONFIG |= OVERLAY_PIPE_B;
 
 #if 0
-   /* 
-    * XXX DUMP REGISTER CODE !!!
-    * This allows us to dump the complete i845 registers and compare
-    * with warm boot situations before we upload our first copy.
-    */
-   {
-      int i;
-      for (i = 0x30000; i < 0x31000; i += 4)
-	 ErrorF("0x%x 0x%lx\n", i, INREG(i));
-   }
+    /* 
+     * XXX DUMP REGISTER CODE !!!
+     * This allows us to dump the complete i845 registers and compare
+     * with warm boot situations before we upload our first copy.
+     */
+    {
+	int i;
+	for (i = 0x30000; i < 0x31000; i += 4)
+	    ErrorF("0x%x 0x%lx\n", i, INREG(i));
+    }
 #endif
 }
 
@@ -606,336 +593,336 @@ I830ResetVideo(ScrnInfoPtr pScrn)
 static void
 I830SetOneLineModeRatio(ScrnInfoPtr pScrn)
 {
-   I830Ptr pI830 = I830PTR(pScrn);
-   I830PortPrivPtr pPriv = pI830->adaptor->pPortPrivates[0].ptr;
-   CARD32 panelFitControl = INREG(PFIT_CONTROLS);
-   int vertScale;
-
-   pPriv->scaleRatio = 0x10000;
-
-   if (panelFitControl & PFIT_ON_MASK) {
-      if (panelFitControl & PFIT_AUTOVSCALE_MASK) {
-         vertScale = INREG(PFIT_AUTOSCALE_RATIO) >> 16;
-      } else {
-         vertScale = INREG(PFIT_PROGRAMMED_SCALE_RATIO) >> 16;
-      }
-
-      if (vertScale != 0)
-         pPriv->scaleRatio = ((double) 0x10000 / (double)vertScale) * 0x10000;
- 
-      pPriv->oneLineMode = TRUE;
+    I830Ptr pI830 = I830PTR(pScrn);
+    I830PortPrivPtr pPriv = pI830->adaptor->pPortPrivates[0].ptr;
+    CARD32 panelFitControl = INREG(PFIT_CONTROLS);
+    int vertScale;
 
-      xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Enabling Xvideo one-line mode\n");
-   }
+    pPriv->scaleRatio = 0x10000;
 
-   if (pPriv->scaleRatio == 0x10000)
-      pPriv->oneLineMode = FALSE;
+    if (panelFitControl & PFIT_ON_MASK) {
+	if (panelFitControl & PFIT_AUTOVSCALE_MASK) {
+	    vertScale = INREG(PFIT_AUTOSCALE_RATIO) >> 16;
+	} else {
+	    vertScale = INREG(PFIT_PROGRAMMED_SCALE_RATIO) >> 16;
+	}
+
+	if (vertScale != 0)
+	    pPriv->scaleRatio = ((double) 0x10000 / (double)vertScale) * 0x10000;
+
+	pPriv->oneLineMode = TRUE;
+
+	xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Enabling Xvideo one-line mode\n");
+    }
+
+    if (pPriv->scaleRatio == 0x10000)
+	pPriv->oneLineMode = FALSE;
 }
 
 static CARD32 I830BoundGammaElt (CARD32 elt, CARD32 eltPrev)
 {
-   elt &= 0xff;
-   eltPrev &= 0xff;
-   if (elt < eltPrev)
-      elt = eltPrev;
-   else if ((elt - eltPrev) > 0x7e)
-      elt = eltPrev + 0x7e;
-   return elt;
+    elt &= 0xff;
+    eltPrev &= 0xff;
+    if (elt < eltPrev)
+	elt = eltPrev;
+    else if ((elt - eltPrev) > 0x7e)
+	elt = eltPrev + 0x7e;
+    return elt;
 }
 
 static CARD32 I830BoundGamma (CARD32 gamma, CARD32 gammaPrev)
 {
-   return (I830BoundGammaElt (gamma >> 24, gammaPrev >> 24) << 24 |
-	   I830BoundGammaElt (gamma >> 16, gammaPrev >> 16) << 16 |
-	   I830BoundGammaElt (gamma >>  8, gammaPrev >>  8) <<  8 |
-	   I830BoundGammaElt (gamma      , gammaPrev      ));
+    return (I830BoundGammaElt (gamma >> 24, gammaPrev >> 24) << 24 |
+	    I830BoundGammaElt (gamma >> 16, gammaPrev >> 16) << 16 |
+	    I830BoundGammaElt (gamma >>  8, gammaPrev >>  8) <<  8 |
+	    I830BoundGammaElt (gamma      , gammaPrev      ));
 }
 
 static void
 I830UpdateGamma(ScrnInfoPtr pScrn)
 {
-   I830Ptr pI830 = I830PTR(pScrn);
-   I830PortPrivPtr pPriv = pI830->adaptor->pPortPrivates[0].ptr;
-   CARD32   gamma0 = pPriv->gamma0;
-   CARD32   gamma1 = pPriv->gamma1;
-   CARD32   gamma2 = pPriv->gamma2;
-   CARD32   gamma3 = pPriv->gamma3;
-   CARD32   gamma4 = pPriv->gamma4;
-   CARD32   gamma5 = pPriv->gamma5;
+    I830Ptr pI830 = I830PTR(pScrn);
+    I830PortPrivPtr pPriv = pI830->adaptor->pPortPrivates[0].ptr;
+    CARD32   gamma0 = pPriv->gamma0;
+    CARD32   gamma1 = pPriv->gamma1;
+    CARD32   gamma2 = pPriv->gamma2;
+    CARD32   gamma3 = pPriv->gamma3;
+    CARD32   gamma4 = pPriv->gamma4;
+    CARD32   gamma5 = pPriv->gamma5;
 
 #if 0
-   ErrorF ("Original gamma: 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx\n",
-	   gamma0, gamma1, gamma2, gamma3, gamma4, gamma5);
+    ErrorF ("Original gamma: 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx\n",
+	    gamma0, gamma1, gamma2, gamma3, gamma4, gamma5);
 #endif
-   gamma1 = I830BoundGamma (gamma1, gamma0);
-   gamma2 = I830BoundGamma (gamma2, gamma1);
-   gamma3 = I830BoundGamma (gamma3, gamma2);
-   gamma4 = I830BoundGamma (gamma4, gamma3);
-   gamma5 = I830BoundGamma (gamma5, gamma4);
+    gamma1 = I830BoundGamma (gamma1, gamma0);
+    gamma2 = I830BoundGamma (gamma2, gamma1);
+    gamma3 = I830BoundGamma (gamma3, gamma2);
+    gamma4 = I830BoundGamma (gamma4, gamma3);
+    gamma5 = I830BoundGamma (gamma5, gamma4);
 #if 0
-   ErrorF ("Bounded  gamma: 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx\n",
-	   gamma0, gamma1, gamma2, gamma3, gamma4, gamma5);
+    ErrorF ("Bounded  gamma: 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx\n",
+	    gamma0, gamma1, gamma2, gamma3, gamma4, gamma5);
 #endif
 
-   OUTREG(OGAMC5, gamma5);
-   OUTREG(OGAMC4, gamma4);
-   OUTREG(OGAMC3, gamma3);
-   OUTREG(OGAMC2, gamma2);
-   OUTREG(OGAMC1, gamma1);
-   OUTREG(OGAMC0, gamma0);
+    OUTREG(OGAMC5, gamma5);
+    OUTREG(OGAMC4, gamma4);
+    OUTREG(OGAMC3, gamma3);
+    OUTREG(OGAMC2, gamma2);
+    OUTREG(OGAMC1, gamma1);
+    OUTREG(OGAMC0, gamma0);
 }
 
 static XF86VideoAdaptorPtr
 I830SetupImageVideoOverlay(ScreenPtr pScreen)
 {
-   ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
-   I830Ptr pI830 = I830PTR(pScrn);
-   XF86VideoAdaptorPtr adapt;
-   I830PortPrivPtr pPriv;
-   XF86AttributePtr att;
-
-   OVERLAY_DEBUG("I830SetupImageVideoOverlay\n");
-
-   if (!(adapt = xcalloc(1, sizeof(XF86VideoAdaptorRec) +
-			 sizeof(I830PortPrivRec) + sizeof(DevUnion))))
-      return NULL;
-
-   adapt->type = XvWindowMask | XvInputMask | XvImageMask;
-   adapt->flags = VIDEO_OVERLAID_IMAGES /*| VIDEO_CLIP_TO_VIEWPORT*/;
-   adapt->name = "Intel(R) Video Overlay";
-   adapt->nEncodings = 1;
-   adapt->pEncodings = DummyEncoding;
-   /* update the DummyEncoding for these two chipsets */
-   if (IS_845G(pI830) || IS_I830(pI830)) {
-      adapt->pEncodings->width = IMAGE_MAX_WIDTH_LEGACY;
-      adapt->pEncodings->height = IMAGE_MAX_HEIGHT_LEGACY;
-   }
-   adapt->nFormats = NUM_FORMATS;
-   adapt->pFormats = Formats;
-   adapt->nPorts = 1;
-   adapt->pPortPrivates = (DevUnion *) (&adapt[1]);
-
-   pPriv = (I830PortPrivPtr) (&adapt->pPortPrivates[1]);
-
-   adapt->pPortPrivates[0].ptr = (pointer) (pPriv);
-   adapt->nAttributes = NUM_ATTRIBUTES;
-   adapt->nAttributes += CLONE_ATTRIBUTES;
-   if (IS_I9XX(pI830))
-      adapt->nAttributes += GAMMA_ATTRIBUTES; /* has gamma */
-   adapt->pAttributes = xnfalloc(sizeof(XF86AttributeRec) * adapt->nAttributes);
-   /* Now copy the attributes */
-   att = adapt->pAttributes;
-   memcpy((char *)att, (char*)Attributes, sizeof(XF86AttributeRec)* NUM_ATTRIBUTES);
-   att+=NUM_ATTRIBUTES;
-   memcpy((char*)att, (char*)CloneAttributes, sizeof(XF86AttributeRec) * CLONE_ATTRIBUTES);
-   att+=CLONE_ATTRIBUTES;
-   if (IS_I9XX(pI830)) {
-      memcpy((char*)att, (char*)GammaAttributes, sizeof(XF86AttributeRec) * GAMMA_ATTRIBUTES);
-      att+=GAMMA_ATTRIBUTES;
-   }
-   adapt->nImages = NUM_IMAGES;
-   adapt->pImages = Images;
-   adapt->PutVideo = NULL;
-   adapt->PutStill = NULL;
-   adapt->GetVideo = NULL;
-   adapt->GetStill = NULL;
-   adapt->StopVideo = I830StopVideo;
-   adapt->SetPortAttribute = I830SetPortAttribute;
-   adapt->GetPortAttribute = I830GetPortAttribute;
-   adapt->QueryBestSize = I830QueryBestSize;
-   adapt->PutImage = I830PutImage;
-   adapt->QueryImageAttributes = I830QueryImageAttributesOverlay;
-
-   pPriv->textured = FALSE;
-   pPriv->colorKey = pI830->colorKey & ((1 << pScrn->depth) - 1);
-   pPriv->videoStatus = 0;
-   pPriv->brightness = 0;
-   pPriv->contrast = 64;
-   pPriv->saturation = 128;
-   pPriv->current_crtc = NULL;
-   pPriv->desired_crtc = NULL;
-   memset(&pPriv->linear, 0, sizeof(pPriv->linear));
-   pPriv->currentBuf = 0;
-   pPriv->gamma5 = 0xc0c0c0;
-   pPriv->gamma4 = 0x808080;
-   pPriv->gamma3 = 0x404040;
-   pPriv->gamma2 = 0x202020;
-   pPriv->gamma1 = 0x101010;
-   pPriv->gamma0 = 0x080808;
-   pPriv->doubleBuffer = 1;
-
-   /* gotta uninit this someplace */
-   REGION_NULL(pScreen, &pPriv->clip);
-
-   pI830->adaptor = adapt;
-
-   /* With LFP's we need to detect whether we're in One Line Mode, which
-    * essentially means a resolution greater than 1024x768, and fix up
-    * the scaler accordingly. */
-   pPriv->scaleRatio = 0x10000;
-   pPriv->oneLineMode = FALSE;
-
-   /*
-    * Initialise pPriv->overlayOK.  Set it to TRUE here so that a warning will
-    * be generated if i830_crtc_dpms_video() sets it to FALSE during mode
-    * setup.
-    */
-   pPriv->overlayOK = TRUE;
-
-   pI830->BlockHandler = pScreen->BlockHandler;
-   pScreen->BlockHandler = I830BlockHandler;
-
-   xvColorKey = MAKE_ATOM("XV_COLORKEY");
-   xvBrightness = MAKE_ATOM("XV_BRIGHTNESS");
-   xvContrast = MAKE_ATOM("XV_CONTRAST");
-   xvSaturation = MAKE_ATOM("XV_SATURATION");
-   xvDoubleBuffer = MAKE_ATOM("XV_DOUBLE_BUFFER");
-
-   /* Allow the pipe to be switched from pipe A to B when in clone mode */
-   xvPipe = MAKE_ATOM("XV_PIPE");
-   
-   if (IS_I9XX(pI830)) {
-     xvGamma0 = MAKE_ATOM("XV_GAMMA0");
-     xvGamma1 = MAKE_ATOM("XV_GAMMA1");
-     xvGamma2 = MAKE_ATOM("XV_GAMMA2");
-     xvGamma3 = MAKE_ATOM("XV_GAMMA3");
-     xvGamma4 = MAKE_ATOM("XV_GAMMA4");
-     xvGamma5 = MAKE_ATOM("XV_GAMMA5");
-   }
+    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+    I830Ptr pI830 = I830PTR(pScrn);
+    XF86VideoAdaptorPtr adapt;
+    I830PortPrivPtr pPriv;
+    XF86AttributePtr att;
+
+    OVERLAY_DEBUG("I830SetupImageVideoOverlay\n");
+
+    if (!(adapt = xcalloc(1, sizeof(XF86VideoAdaptorRec) +
+			  sizeof(I830PortPrivRec) + sizeof(DevUnion))))
+	return NULL;
+
+    adapt->type = XvWindowMask | XvInputMask | XvImageMask;
+    adapt->flags = VIDEO_OVERLAID_IMAGES /*| VIDEO_CLIP_TO_VIEWPORT*/;
+    adapt->name = "Intel(R) Video Overlay";
+    adapt->nEncodings = 1;
+    adapt->pEncodings = DummyEncoding;
+    /* update the DummyEncoding for these two chipsets */
+    if (IS_845G(pI830) || IS_I830(pI830)) {
+	adapt->pEncodings->width = IMAGE_MAX_WIDTH_LEGACY;
+	adapt->pEncodings->height = IMAGE_MAX_HEIGHT_LEGACY;
+    }
+    adapt->nFormats = NUM_FORMATS;
+    adapt->pFormats = Formats;
+    adapt->nPorts = 1;
+    adapt->pPortPrivates = (DevUnion *) (&adapt[1]);
+
+    pPriv = (I830PortPrivPtr) (&adapt->pPortPrivates[1]);
+
+    adapt->pPortPrivates[0].ptr = (pointer) (pPriv);
+    adapt->nAttributes = NUM_ATTRIBUTES;
+    adapt->nAttributes += CLONE_ATTRIBUTES;
+    if (IS_I9XX(pI830))
+	adapt->nAttributes += GAMMA_ATTRIBUTES; /* has gamma */
+    adapt->pAttributes = xnfalloc(sizeof(XF86AttributeRec) * adapt->nAttributes);
+    /* Now copy the attributes */
+    att = adapt->pAttributes;
+    memcpy((char *)att, (char*)Attributes, sizeof(XF86AttributeRec)* NUM_ATTRIBUTES);
+    att+=NUM_ATTRIBUTES;
+    memcpy((char*)att, (char*)CloneAttributes, sizeof(XF86AttributeRec) * CLONE_ATTRIBUTES);
+    att+=CLONE_ATTRIBUTES;
+    if (IS_I9XX(pI830)) {
+	memcpy((char*)att, (char*)GammaAttributes, sizeof(XF86AttributeRec) * GAMMA_ATTRIBUTES);
+	att+=GAMMA_ATTRIBUTES;
+    }
+    adapt->nImages = NUM_IMAGES;
+    adapt->pImages = Images;
+    adapt->PutVideo = NULL;
+    adapt->PutStill = NULL;
+    adapt->GetVideo = NULL;
+    adapt->GetStill = NULL;
+    adapt->StopVideo = I830StopVideo;
+    adapt->SetPortAttribute = I830SetPortAttribute;
+    adapt->GetPortAttribute = I830GetPortAttribute;
+    adapt->QueryBestSize = I830QueryBestSize;
+    adapt->PutImage = I830PutImage;
+    adapt->QueryImageAttributes = I830QueryImageAttributesOverlay;
+
+    pPriv->textured = FALSE;
+    pPriv->colorKey = pI830->colorKey & ((1 << pScrn->depth) - 1);
+    pPriv->videoStatus = 0;
+    pPriv->brightness = 0;
+    pPriv->contrast = 64;
+    pPriv->saturation = 128;
+    pPriv->current_crtc = NULL;
+    pPriv->desired_crtc = NULL;
+    memset(&pPriv->linear, 0, sizeof(pPriv->linear));
+    pPriv->currentBuf = 0;
+    pPriv->gamma5 = 0xc0c0c0;
+    pPriv->gamma4 = 0x808080;
+    pPriv->gamma3 = 0x404040;
+    pPriv->gamma2 = 0x202020;
+    pPriv->gamma1 = 0x101010;
+    pPriv->gamma0 = 0x080808;
+    pPriv->doubleBuffer = 1;
+
+    /* gotta uninit this someplace */
+    REGION_NULL(pScreen, &pPriv->clip);
+
+    pI830->adaptor = adapt;
+
+    /* With LFP's we need to detect whether we're in One Line Mode, which
+     * essentially means a resolution greater than 1024x768, and fix up
+     * the scaler accordingly. */
+    pPriv->scaleRatio = 0x10000;
+    pPriv->oneLineMode = FALSE;
+
+    /*
+     * Initialise pPriv->overlayOK.  Set it to TRUE here so that a warning will
+     * be generated if i830_crtc_dpms_video() sets it to FALSE during mode
+     * setup.
+     */
+    pPriv->overlayOK = TRUE;
+
+    pI830->BlockHandler = pScreen->BlockHandler;
+    pScreen->BlockHandler = I830BlockHandler;
+
+    xvColorKey = MAKE_ATOM("XV_COLORKEY");
+    xvBrightness = MAKE_ATOM("XV_BRIGHTNESS");
+    xvContrast = MAKE_ATOM("XV_CONTRAST");
+    xvSaturation = MAKE_ATOM("XV_SATURATION");
+    xvDoubleBuffer = MAKE_ATOM("XV_DOUBLE_BUFFER");
+
+    /* Allow the pipe to be switched from pipe A to B when in clone mode */
+    xvPipe = MAKE_ATOM("XV_PIPE");
+
+    if (IS_I9XX(pI830)) {
+	xvGamma0 = MAKE_ATOM("XV_GAMMA0");
+	xvGamma1 = MAKE_ATOM("XV_GAMMA1");
+	xvGamma2 = MAKE_ATOM("XV_GAMMA2");
+	xvGamma3 = MAKE_ATOM("XV_GAMMA3");
+	xvGamma4 = MAKE_ATOM("XV_GAMMA4");
+	xvGamma5 = MAKE_ATOM("XV_GAMMA5");
+    }
 
-   I830ResetVideo(pScrn);
+    I830ResetVideo(pScrn);
 
-   I830UpdateGamma(pScrn);
+    I830UpdateGamma(pScrn);
 
-   return adapt;
+    return adapt;
 }
 
 static XF86VideoAdaptorPtr
 I830SetupImageVideoTextured(ScreenPtr pScreen)
 {
-   XF86VideoAdaptorPtr adapt;
-   XF86AttributePtr attrs;
-   I830PortPrivPtr portPrivs;
-   DevUnion *devUnions;
-   int nports = 16, i;
-   int nAttributes;
-
-   OVERLAY_DEBUG("I830SetupImageVideoOverlay\n");
-
-   nAttributes = NUM_TEXTURED_ATTRIBUTES;
-
-   adapt = xcalloc(1, sizeof(XF86VideoAdaptorRec));
-   portPrivs = xcalloc(nports, sizeof(I830PortPrivRec));
-   devUnions = xcalloc(nports, sizeof(DevUnion));
-   attrs = xcalloc(nAttributes, sizeof(XF86AttributeRec));
-   if (adapt == NULL || portPrivs == NULL || devUnions == NULL ||
-       attrs == NULL)
-   {
-      xfree(adapt);
-      xfree(portPrivs);
-      xfree(devUnions);
-      xfree(attrs);
-      return NULL;
-   }
-
-   adapt->type = XvWindowMask | XvInputMask | XvImageMask;
-   adapt->flags = 0;
-   adapt->name = "Intel(R) Textured Video";
-   adapt->nEncodings = 1;
-   adapt->pEncodings = DummyEncoding;
-   adapt->nFormats = NUM_FORMATS;
-   adapt->pFormats = Formats;
-   adapt->nPorts = nports;
-   adapt->pPortPrivates = devUnions;
-   adapt->nAttributes = nAttributes;
-   adapt->pAttributes = attrs;
-   memcpy(attrs, TexturedAttributes, nAttributes * sizeof(XF86AttributeRec));
-   adapt->nImages = NUM_IMAGES;
-   adapt->pImages = Images;
-   adapt->PutVideo = NULL;
-   adapt->PutStill = NULL;
-   adapt->GetVideo = NULL;
-   adapt->GetStill = NULL;
-   adapt->StopVideo = I830StopVideo;
-   adapt->SetPortAttribute = I830SetPortAttribute;
-   adapt->GetPortAttribute = I830GetPortAttribute;
-   adapt->QueryBestSize = I830QueryBestSize;
-   adapt->PutImage = I830PutImage;
-   adapt->QueryImageAttributes = I830QueryImageAttributesTextured;
-
-   for (i = 0; i < nports; i++) {
-      I830PortPrivPtr pPriv = &portPrivs[i];
-
-      pPriv->textured = TRUE;
-      pPriv->videoStatus = 0;
-      memset(&pPriv->linear, 0, sizeof(pPriv->linear));
-      pPriv->currentBuf = 0;
-      pPriv->doubleBuffer = 0;
+    XF86VideoAdaptorPtr adapt;
+    XF86AttributePtr attrs;
+    I830PortPrivPtr portPrivs;
+    DevUnion *devUnions;
+    int nports = 16, i;
+    int nAttributes;
+
+    OVERLAY_DEBUG("I830SetupImageVideoOverlay\n");
+
+    nAttributes = NUM_TEXTURED_ATTRIBUTES;
+
+    adapt = xcalloc(1, sizeof(XF86VideoAdaptorRec));
+    portPrivs = xcalloc(nports, sizeof(I830PortPrivRec));
+    devUnions = xcalloc(nports, sizeof(DevUnion));
+    attrs = xcalloc(nAttributes, sizeof(XF86AttributeRec));
+    if (adapt == NULL || portPrivs == NULL || devUnions == NULL ||
+	attrs == NULL)
+    {
+	xfree(adapt);
+	xfree(portPrivs);
+	xfree(devUnions);
+	xfree(attrs);
+	return NULL;
+    }
+
+    adapt->type = XvWindowMask | XvInputMask | XvImageMask;
+    adapt->flags = 0;
+    adapt->name = "Intel(R) Textured Video";
+    adapt->nEncodings = 1;
+    adapt->pEncodings = DummyEncoding;
+    adapt->nFormats = NUM_FORMATS;
+    adapt->pFormats = Formats;
+    adapt->nPorts = nports;
+    adapt->pPortPrivates = devUnions;
+    adapt->nAttributes = nAttributes;
+    adapt->pAttributes = attrs;
+    memcpy(attrs, TexturedAttributes, nAttributes * sizeof(XF86AttributeRec));
+    adapt->nImages = NUM_IMAGES;
+    adapt->pImages = Images;
+    adapt->PutVideo = NULL;
+    adapt->PutStill = NULL;
+    adapt->GetVideo = NULL;
+    adapt->GetStill = NULL;
+    adapt->StopVideo = I830StopVideo;
+    adapt->SetPortAttribute = I830SetPortAttribute;
+    adapt->GetPortAttribute = I830GetPortAttribute;
+    adapt->QueryBestSize = I830QueryBestSize;
+    adapt->PutImage = I830PutImage;
+    adapt->QueryImageAttributes = I830QueryImageAttributesTextured;
+
+    for (i = 0; i < nports; i++) {
+	I830PortPrivPtr pPriv = &portPrivs[i];
+
+	pPriv->textured = TRUE;
+	pPriv->videoStatus = 0;
+	memset(&pPriv->linear, 0, sizeof(pPriv->linear));
+	pPriv->currentBuf = 0;
+	pPriv->doubleBuffer = 0;
 
-      /* gotta uninit this someplace, XXX: shouldn't be necessary for textured */
-      REGION_NULL(pScreen, &pPriv->clip);
+	/* gotta uninit this someplace, XXX: shouldn't be necessary for textured */
+	REGION_NULL(pScreen, &pPriv->clip);
 
-      adapt->pPortPrivates[i].ptr = (pointer) (pPriv);
-   }
+	adapt->pPortPrivates[i].ptr = (pointer) (pPriv);
+    }
 
-   return adapt;
+    return adapt;
 }
 
 static Bool
 RegionsEqual(RegionPtr A, RegionPtr B)
 {
-   int *dataA, *dataB;
-   int num;
+    int *dataA, *dataB;
+    int num;
 
-   num = REGION_NUM_RECTS(A);
-   if (num != REGION_NUM_RECTS(B))
-      return FALSE;
-
-   if ((A->extents.x1 != B->extents.x1) ||
-       (A->extents.x2 != B->extents.x2) ||
-       (A->extents.y1 != B->extents.y1) || (A->extents.y2 != B->extents.y2))
-      return FALSE;
-
-   dataA = (int *)REGION_RECTS(A);
-   dataB = (int *)REGION_RECTS(B);
-
-   while (num--) {
-      if ((dataA[0] != dataB[0]) || (dataA[1] != dataB[1]))
-	 return FALSE;
-      dataA += 2;
-      dataB += 2;
-   }
+    num = REGION_NUM_RECTS(A);
+    if (num != REGION_NUM_RECTS(B))
+	return FALSE;
+
+    if ((A->extents.x1 != B->extents.x1) ||
+	(A->extents.x2 != B->extents.x2) ||
+	(A->extents.y1 != B->extents.y1) || (A->extents.y2 != B->extents.y2))
+	return FALSE;
+
+    dataA = (int *)REGION_RECTS(A);
+    dataB = (int *)REGION_RECTS(B);
+
+    while (num--) {
+	if ((dataA[0] != dataB[0]) || (dataA[1] != dataB[1]))
+	    return FALSE;
+	dataA += 2;
+	dataB += 2;
+    }
 
-   return TRUE;
+    return TRUE;
 }
 
 static void
 I830StopVideo(ScrnInfoPtr pScrn, pointer data, Bool shutdown)
 {
-   I830PortPrivPtr pPriv = (I830PortPrivPtr) data;
-   I830Ptr pI830 = I830PTR(pScrn);
+    I830PortPrivPtr pPriv = (I830PortPrivPtr) data;
+    I830Ptr pI830 = I830PTR(pScrn);
+
+    if (pPriv->textured)
+	return;
 
-   if (pPriv->textured)
-      return;
+    OVERLAY_DEBUG("I830StopVideo\n");
 
-   OVERLAY_DEBUG("I830StopVideo\n");
+    REGION_EMPTY(pScrn->pScreen, &pPriv->clip);
 
-   REGION_EMPTY(pScrn->pScreen, &pPriv->clip);
-
-   if (shutdown) {
-      if (pPriv->videoStatus & CLIENT_VIDEO_ON) {
-	 i830_overlay_off(pScrn);
-         if (pI830->entityPrivate)
-            pI830->entityPrivate->XvInUse = -1;
-      }
-      I830FreeMemory(pScrn, &pPriv->linear);
-      pPriv->videoStatus = 0;
-   } else {
-      if (pPriv->videoStatus & CLIENT_VIDEO_ON) {
-	 pPriv->videoStatus |= OFF_TIMER;
-	 pPriv->offTime = currentTime.milliseconds + OFF_DELAY;
-      }
-   }
+    if (shutdown) {
+	if (pPriv->videoStatus & CLIENT_VIDEO_ON) {
+	    i830_overlay_off(pScrn);
+	    if (pI830->entityPrivate)
+		pI830->entityPrivate->XvInUse = -1;
+	}
+	I830FreeMemory(pScrn, &pPriv->linear);
+	pPriv->videoStatus = 0;
+    } else {
+	if (pPriv->videoStatus & CLIENT_VIDEO_ON) {
+	    pPriv->videoStatus |= OFF_TIMER;
+	    pPriv->offTime = currentTime.milliseconds + OFF_DELAY;
+	}
+    }
 
 }
 
@@ -943,148 +930,148 @@ static int
 I830SetPortAttribute(ScrnInfoPtr pScrn,
 		     Atom attribute, INT32 value, pointer data)
 {
-   I830PortPrivPtr pPriv = (I830PortPrivPtr) data;
-   I830Ptr pI830 = I830PTR(pScrn);
-   I830OverlayRegPtr overlay;
-
-   if (pPriv->textured) {
-      /* XXX: Currently the brightness/saturation attributes aren't hooked up.
-       * However, apps expect them to be there, and the spec seems to let us
-       * sneak out of actually implementing them for now.
-       */
-      return Success;
-   }
-
-   overlay = (I830OverlayRegPtr) (pI830->FbBase + pI830->overlay_regs->offset);
-
-   if (attribute == xvBrightness) {
-      if ((value < -128) || (value > 127))
-	 return BadValue;
-      pPriv->brightness = value;
-      overlay->OCLRC0 = (pPriv->contrast << 18) | (pPriv->brightness & 0xff);
-      OVERLAY_DEBUG("BRIGHTNESS\n");
-      if (*pI830->overlayOn)
-	 i830_overlay_continue (pScrn);
-   } else if (attribute == xvContrast) {
-      if ((value < 0) || (value > 255))
-	 return BadValue;
-      pPriv->contrast = value;
-      overlay->OCLRC0 = (pPriv->contrast << 18) | (pPriv->brightness & 0xff);
-      OVERLAY_DEBUG("CONTRAST\n");
-      if (*pI830->overlayOn)
-	 i830_overlay_continue (pScrn);
-   } else if (attribute == xvSaturation) {
-      if ((value < 0) || (value > 1023))
-	 return BadValue;
-      pPriv->saturation = value;
-      overlay->OCLRC1 = pPriv->saturation;
-      if (*pI830->overlayOn)
-	 i830_overlay_continue (pScrn);
-   } else if (attribute == xvPipe) {
-      xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
-      if ((value < -1) || (value > xf86_config->num_crtc))
-         return BadValue;
-      if (value < 0)
-	 pPriv->desired_crtc = NULL;
-      else
-	 pPriv->desired_crtc = xf86_config->crtc[value];
-      /*
-       * Leave this to be updated at the next frame
-       */
-   } else if (attribute == xvGamma0 && (IS_I9XX(pI830))) {
-      pPriv->gamma0 = value; 
-   } else if (attribute == xvGamma1 && (IS_I9XX(pI830))) {
-      pPriv->gamma1 = value;
-   } else if (attribute == xvGamma2 && (IS_I9XX(pI830))) {
-      pPriv->gamma2 = value;
-   } else if (attribute == xvGamma3 && (IS_I9XX(pI830))) {
-      pPriv->gamma3 = value;
-   } else if (attribute == xvGamma4 && (IS_I9XX(pI830))) {
-      pPriv->gamma4 = value;
-   } else if (attribute == xvGamma5 && (IS_I9XX(pI830))) {
-      pPriv->gamma5 = value;
-   } else if (attribute == xvColorKey) {
-      pPriv->colorKey = value;
-      switch (pScrn->depth) {
-      case 16:
-	 overlay->DCLRKV = RGB16ToColorKey(pPriv->colorKey);
-	 break;
-      case 15:
-	 overlay->DCLRKV = RGB15ToColorKey(pPriv->colorKey);
-	 break;
-      default:
-	 overlay->DCLRKV = pPriv->colorKey;
-	 break;
-      }
-      OVERLAY_DEBUG("COLORKEY\n");
-      if (*pI830->overlayOn)
-	 i830_overlay_continue (pScrn);
-      REGION_EMPTY(pScrn->pScreen, &pPriv->clip);
-   } else if(attribute == xvDoubleBuffer) {
-      if ((value < 0) || (value > 1))
-         return BadValue;
-      /* Do not allow buffer change while playing video */
-      if(!*pI830->overlayOn)
-     	 pPriv->doubleBuffer = value;
-   } else
-      return BadMatch;
-
-   /* Ensure that the overlay is off, ready for updating */
-   if ((attribute == xvGamma0 ||
-        attribute == xvGamma1 ||
-        attribute == xvGamma2 ||
-        attribute == xvGamma3 ||
-        attribute == xvGamma4 ||
-        attribute == xvGamma5) && (IS_I9XX(pI830))) {
-        OVERLAY_DEBUG("GAMMA\n");
+    I830PortPrivPtr pPriv = (I830PortPrivPtr) data;
+    I830Ptr pI830 = I830PTR(pScrn);
+    I830OverlayRegPtr overlay;
+
+    if (pPriv->textured) {
+	/* XXX: Currently the brightness/saturation attributes aren't hooked up.
+	 * However, apps expect them to be there, and the spec seems to let us
+	 * sneak out of actually implementing them for now.
+	 */
+	return Success;
+    }
+
+    overlay = (I830OverlayRegPtr) (pI830->FbBase + pI830->overlay_regs->offset);
+
+    if (attribute == xvBrightness) {
+	if ((value < -128) || (value > 127))
+	    return BadValue;
+	pPriv->brightness = value;
+	overlay->OCLRC0 = (pPriv->contrast << 18) | (pPriv->brightness & 0xff);
+	OVERLAY_DEBUG("BRIGHTNESS\n");
+	if (*pI830->overlayOn)
+	    i830_overlay_continue (pScrn);
+    } else if (attribute == xvContrast) {
+	if ((value < 0) || (value > 255))
+	    return BadValue;
+	pPriv->contrast = value;
+	overlay->OCLRC0 = (pPriv->contrast << 18) | (pPriv->brightness & 0xff);
+	OVERLAY_DEBUG("CONTRAST\n");
+	if (*pI830->overlayOn)
+	    i830_overlay_continue (pScrn);
+    } else if (attribute == xvSaturation) {
+	if ((value < 0) || (value > 1023))
+	    return BadValue;
+	pPriv->saturation = value;
+	overlay->OCLRC1 = pPriv->saturation;
+	if (*pI830->overlayOn)
+	    i830_overlay_continue (pScrn);
+    } else if (attribute == xvPipe) {
+	xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+	if ((value < -1) || (value > xf86_config->num_crtc))
+	    return BadValue;
+	if (value < 0)
+	    pPriv->desired_crtc = NULL;
+	else
+	    pPriv->desired_crtc = xf86_config->crtc[value];
+	/*
+	 * Leave this to be updated at the next frame
+	 */
+    } else if (attribute == xvGamma0 && (IS_I9XX(pI830))) {
+	pPriv->gamma0 = value; 
+    } else if (attribute == xvGamma1 && (IS_I9XX(pI830))) {
+	pPriv->gamma1 = value;
+    } else if (attribute == xvGamma2 && (IS_I9XX(pI830))) {
+	pPriv->gamma2 = value;
+    } else if (attribute == xvGamma3 && (IS_I9XX(pI830))) {
+	pPriv->gamma3 = value;
+    } else if (attribute == xvGamma4 && (IS_I9XX(pI830))) {
+	pPriv->gamma4 = value;
+    } else if (attribute == xvGamma5 && (IS_I9XX(pI830))) {
+	pPriv->gamma5 = value;
+    } else if (attribute == xvColorKey) {
+	pPriv->colorKey = value;
+	switch (pScrn->depth) {
+	case 16:
+	    overlay->DCLRKV = RGB16ToColorKey(pPriv->colorKey);
+	    break;
+	case 15:
+	    overlay->DCLRKV = RGB15ToColorKey(pPriv->colorKey);
+	    break;
+	default:
+	    overlay->DCLRKV = pPriv->colorKey;
+	    break;
+	}
+	OVERLAY_DEBUG("COLORKEY\n");
+	if (*pI830->overlayOn)
+	    i830_overlay_continue (pScrn);
+	REGION_EMPTY(pScrn->pScreen, &pPriv->clip);
+    } else if(attribute == xvDoubleBuffer) {
+	if ((value < 0) || (value > 1))
+	    return BadValue;
+	/* Do not allow buffer change while playing video */
+	if(!*pI830->overlayOn)
+	    pPriv->doubleBuffer = value;
+    } else
+	return BadMatch;
+
+    /* Ensure that the overlay is off, ready for updating */
+    if ((attribute == xvGamma0 ||
+	 attribute == xvGamma1 ||
+	 attribute == xvGamma2 ||
+	 attribute == xvGamma3 ||
+	 attribute == xvGamma4 ||
+	 attribute == xvGamma5) && (IS_I9XX(pI830))) {
+	OVERLAY_DEBUG("GAMMA\n");
 	I830UpdateGamma(pScrn);
-   }
+    }
 
-   return Success;
+    return Success;
 }
 
 static int
 I830GetPortAttribute(ScrnInfoPtr pScrn,
 		     Atom attribute, INT32 * value, pointer data)
 {
-   I830Ptr pI830 = I830PTR(pScrn);
-   I830PortPrivPtr pPriv = (I830PortPrivPtr) data;
+    I830Ptr pI830 = I830PTR(pScrn);
+    I830PortPrivPtr pPriv = (I830PortPrivPtr) data;
 
-   if (attribute == xvBrightness) {
-      *value = pPriv->brightness;
-   } else if (attribute == xvContrast) {
-      *value = pPriv->contrast;
-   } else if (attribute == xvSaturation) {
-      *value = pPriv->saturation;
-   } else if (attribute == xvPipe) {
-      int		c;
-      xf86CrtcConfigPtr	xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
-      for (c = 0; c < xf86_config->num_crtc; c++)
-	 if (xf86_config->crtc[c] == pPriv->desired_crtc)
-	    break;
-      if (c == xf86_config->num_crtc)
-	 c = -1;
-      *value = c;
-   } else if (attribute == xvGamma0 && (IS_I9XX(pI830))) {
-      *value = pPriv->gamma0;
-   } else if (attribute == xvGamma1 && (IS_I9XX(pI830))) {
-      *value = pPriv->gamma1;
-   } else if (attribute == xvGamma2 && (IS_I9XX(pI830))) {
-      *value = pPriv->gamma2;
-   } else if (attribute == xvGamma3 && (IS_I9XX(pI830))) {
-      *value = pPriv->gamma3;
-   } else if (attribute == xvGamma4 && (IS_I9XX(pI830))) {
-      *value = pPriv->gamma4;
-   } else if (attribute == xvGamma5 && (IS_I9XX(pI830))) {
-      *value = pPriv->gamma5;
-   } else if (attribute == xvColorKey) {
-      *value = pPriv->colorKey;
-   } else if (attribute == xvDoubleBuffer) {
-      *value = pPriv->doubleBuffer;
-   } else 
-      return BadMatch;
+    if (attribute == xvBrightness) {
+	*value = pPriv->brightness;
+    } else if (attribute == xvContrast) {
+	*value = pPriv->contrast;
+    } else if (attribute == xvSaturation) {
+	*value = pPriv->saturation;
+    } else if (attribute == xvPipe) {
+	int		c;
+	xf86CrtcConfigPtr	xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+	for (c = 0; c < xf86_config->num_crtc; c++)
+	    if (xf86_config->crtc[c] == pPriv->desired_crtc)
+		break;
+	if (c == xf86_config->num_crtc)
+	    c = -1;
+	*value = c;
+    } else if (attribute == xvGamma0 && (IS_I9XX(pI830))) {
+	*value = pPriv->gamma0;
+    } else if (attribute == xvGamma1 && (IS_I9XX(pI830))) {
+	*value = pPriv->gamma1;
+    } else if (attribute == xvGamma2 && (IS_I9XX(pI830))) {
+	*value = pPriv->gamma2;
+    } else if (attribute == xvGamma3 && (IS_I9XX(pI830))) {
+	*value = pPriv->gamma3;
+    } else if (attribute == xvGamma4 && (IS_I9XX(pI830))) {
+	*value = pPriv->gamma4;
+    } else if (attribute == xvGamma5 && (IS_I9XX(pI830))) {
+	*value = pPriv->gamma5;
+    } else if (attribute == xvColorKey) {
+	*value = pPriv->colorKey;
+    } else if (attribute == xvDoubleBuffer) {
+	*value = pPriv->doubleBuffer;
+    } else 
+	return BadMatch;
 
-   return Success;
+    return Success;
 }
 
 static void
@@ -1094,13 +1081,13 @@ I830QueryBestSize(ScrnInfoPtr pScrn,
 		  short drw_w, short drw_h,
 		  unsigned int *p_w, unsigned int *p_h, pointer data)
 {
-   if (vid_w > (drw_w << 1))
-      drw_w = vid_w >> 1;
-   if (vid_h > (drw_h << 1))
-      drw_h = vid_h >> 1;
+    if (vid_w > (drw_w << 1))
+	drw_w = vid_w >> 1;
+    if (vid_h > (drw_h << 1))
+	drw_h = vid_h >> 1;
 
-   *p_w = drw_w;
-   *p_h = drw_h;
+    *p_w = drw_w;
+    *p_h = drw_h;
 }
 
 static void
@@ -1109,95 +1096,95 @@ I830CopyPackedData(ScrnInfoPtr pScrn, I8
 		   int srcPitch,
 		   int dstPitch, int top, int left, int h, int w)
 {
-   I830Ptr pI830 = I830PTR(pScrn);
-   unsigned char *src, *dst;
-   int i,j;
-   unsigned char *s;
+    I830Ptr pI830 = I830PTR(pScrn);
+    unsigned char *src, *dst;
+    int i,j;
+    unsigned char *s;
 
 #if 0
-   ErrorF("I830CopyPackedData: (%d,%d) (%d,%d)\n"
-	  "srcPitch: %d, dstPitch: %d\n", top, left, h, w,
-	  srcPitch, dstPitch);
-#endif
-
-   src = buf + (top * srcPitch) + (left << 1);
-
-   if (pPriv->currentBuf == 0)
-      dst = pI830->FbBase + pPriv->YBuf0offset;
-   else
-      dst = pI830->FbBase + pPriv->YBuf1offset;
-
-   switch (pI830->rotation) {
-      case RR_Rotate_0:
-         w <<= 1;
-         for (i = 0; i < h; i++) {
-            memcpy(dst, src, w);
-            src += srcPitch;
-            dst += dstPitch;
-         }
-	 break;
-      case RR_Rotate_90:
-         h <<= 1;
-         for (i = 0; i < h; i+=2) {
-            s = src;
-            for (j = 0; j < w; j++) {
+    ErrorF("I830CopyPackedData: (%d,%d) (%d,%d)\n"
+	   "srcPitch: %d, dstPitch: %d\n", top, left, h, w,
+	   srcPitch, dstPitch);
+#endif
+
+    src = buf + (top * srcPitch) + (left << 1);
+
+    if (pPriv->currentBuf == 0)
+	dst = pI830->FbBase + pPriv->YBuf0offset;
+    else
+	dst = pI830->FbBase + pPriv->YBuf1offset;
+
+    switch (pI830->rotation) {
+    case RR_Rotate_0:
+	w <<= 1;
+	for (i = 0; i < h; i++) {
+	    memcpy(dst, src, w);
+	    src += srcPitch;
+	    dst += dstPitch;
+	}
+	break;
+    case RR_Rotate_90:
+	h <<= 1;
+	for (i = 0; i < h; i+=2) {
+	    s = src;
+	    for (j = 0; j < w; j++) {
 		/* Copy Y */
-               dst[(i + 0) + ((w - j - 1) * dstPitch)] = *s++; 
+		dst[(i + 0) + ((w - j - 1) * dstPitch)] = *s++; 
 		(void)*s++;
-            }
-            src += srcPitch;
-         }
-         h >>= 1;
-   	 src = buf + (top * srcPitch) + (left << 1);
-         for (i = 0; i < h; i+=2) {
-            for (j = 0; j < w; j+=2) {
+	    }
+	    src += srcPitch;
+	}
+	h >>= 1;
+	src = buf + (top * srcPitch) + (left << 1);
+	for (i = 0; i < h; i+=2) {
+	    for (j = 0; j < w; j+=2) {
 		/* Copy U */
 		dst[((i*2) + 1) + ((w - j - 1) * dstPitch)] = src[(j*2) + 1 + (i * srcPitch)];
 		dst[((i*2) + 1) + ((w - j - 2) * dstPitch)] = src[(j*2) + 1 + ((i+1) * srcPitch)];
 		/* Copy V */
 		dst[((i*2) + 3) + ((w - j - 1) * dstPitch)] = src[(j*2) + 3 + (i * srcPitch)];
 		dst[((i*2) + 3) + ((w - j - 2) * dstPitch)] = src[(j*2) + 3 + ((i+1) * srcPitch)];
-            }
-         }
-         break;
-      case RR_Rotate_180:
-         w <<= 1;
-         for (i = 0; i < h; i++) {
-            s = src;
-            for (j = 0; j < w; j+=4) {
-               dst[(w - j - 4) + ((h - i - 1) * dstPitch)] = *s++;
-               dst[(w - j - 3) + ((h - i - 1) * dstPitch)] = *s++;
-               dst[(w - j - 2) + ((h - i - 1) * dstPitch)] = *s++;
-               dst[(w - j - 1) + ((h - i - 1) * dstPitch)] = *s++;
-            }
-            src += srcPitch;
-         }
-         break;
-      case RR_Rotate_270:
-         h <<= 1;
-         for (i = 0; i < h; i+=2) {
-            s = src;
-            for (j = 0; j < w; j++) {
+	    }
+	}
+	break;
+    case RR_Rotate_180:
+	w <<= 1;
+	for (i = 0; i < h; i++) {
+	    s = src;
+	    for (j = 0; j < w; j+=4) {
+		dst[(w - j - 4) + ((h - i - 1) * dstPitch)] = *s++;
+		dst[(w - j - 3) + ((h - i - 1) * dstPitch)] = *s++;
+		dst[(w - j - 2) + ((h - i - 1) * dstPitch)] = *s++;
+		dst[(w - j - 1) + ((h - i - 1) * dstPitch)] = *s++;
+	    }
+	    src += srcPitch;
+	}
+	break;
+    case RR_Rotate_270:
+	h <<= 1;
+	for (i = 0; i < h; i+=2) {
+	    s = src;
+	    for (j = 0; j < w; j++) {
 		/* Copy Y */
-               dst[(h - i - 2) + (j * dstPitch)] = *s++;
+		dst[(h - i - 2) + (j * dstPitch)] = *s++;
 		(void)*s++;
-            }
-            src += srcPitch;
-         }
-         h >>= 1;
-   	 src = buf + (top * srcPitch) + (left << 1);
-         for (i = 0; i < h; i+=2) {
-            for (j = 0; j < w; j+=2) {
+	    }
+	    src += srcPitch;
+	}
+	h >>= 1;
+	src = buf + (top * srcPitch) + (left << 1);
+	for (i = 0; i < h; i+=2) {
+	    for (j = 0; j < w; j+=2) {
 		/* Copy U */
 		dst[(((h - i)*2) - 3) + (j * dstPitch)] = src[(j*2) + 1 + (i * srcPitch)];
 		dst[(((h - i)*2) - 3) + ((j - 1) * dstPitch)] = src[(j*2) + 1 + ((i+1) * srcPitch)];
 		/* Copy V */
 		dst[(((h - i)*2) - 1) + (j * dstPitch)] = src[(j*2) + 3 + (i * srcPitch)];
 		dst[(((h - i)*2) - 1) + ((j - 1) * dstPitch)] = src[(j*2) + 3 + ((i+1) * srcPitch)];
-            }
-         }
-         break;
-   }
+	    }
+	}
+	break;
+    }
 }
 
 /* Copies planar data in *buf to UYVY-packed data in the screen atYBufXOffset.
@@ -1208,55 +1195,55 @@ I830CopyPlanarToPackedData(ScrnInfoPtr p
 			   int srcPitch2, int dstPitch, int srcH,
 			   int top, int left, int h, int w, int id)
 {
-   I830Ptr pI830 = I830PTR(pScrn);
-   CARD8 *dst1, *srcy, *srcu, *srcv;
-   int y;
-
-   if (pPriv->currentBuf == 0)
-      dst1 = pI830->FbBase + pPriv->YBuf0offset;
-   else
-      dst1 = pI830->FbBase + pPriv->YBuf1offset;
-
-   srcy = buf + (top * srcPitch) + left;
-   if (id == FOURCC_YV12) {
-      srcu = buf + (srcH * srcPitch) + ((top / 2) * srcPitch2) + (left / 2);
-      srcv = buf + (srcH * srcPitch) + ((srcH / 2) * srcPitch2) +
-	    ((top / 2) * srcPitch2) + (left / 2);
-   } else {
-      srcv = buf + (srcH * srcPitch) + ((top / 2) * srcPitch2) + (left / 2);
-      srcu = buf + (srcH * srcPitch) + ((srcH / 2) * srcPitch2) +
-	    ((top / 2) * srcPitch2) + (left / 2);
-   }
-
-   for (y = 0; y < h; y++) {
-      CARD32 *dst = (CARD32 *)dst1;
-      CARD8 *sy = srcy;
-      CARD8 *su = srcu;
-      CARD8 *sv = srcv;
-      int i;
-
-      i = w / 2;
-      while(i > 4) {
-	 dst[0] = sy[0] | (sy[1] << 16) | (sv[0] << 8) | (su[0] << 24);
-	 dst[1] = sy[2] | (sy[3] << 16) | (sv[1] << 8) | (su[1] << 24);
-	 dst[2] = sy[4] | (sy[5] << 16) | (sv[2] << 8) | (su[2] << 24);
-	 dst[3] = sy[6] | (sy[7] << 16) | (sv[3] << 8) | (su[3] << 24);
-	 dst += 4; su += 4; sv += 4; sy += 8;
-	 i -= 4;
-      }
-      while(i--) {
-	 dst[0] = sy[0] | (sy[1] << 16) | (sv[0] << 8) | (su[0] << 24);
-	 dst++; su++; sv++;
-	 sy += 2;
-      }
-
-      dst1 += dstPitch;
-      srcy += srcPitch;
-      if (y & 1) {
-	 srcu += srcPitch2;
-	 srcv += srcPitch2;
-      }	
-   }
+    I830Ptr pI830 = I830PTR(pScrn);
+    CARD8 *dst1, *srcy, *srcu, *srcv;
+    int y;
+
+    if (pPriv->currentBuf == 0)
+	dst1 = pI830->FbBase + pPriv->YBuf0offset;
+    else
+	dst1 = pI830->FbBase + pPriv->YBuf1offset;
+
+    srcy = buf + (top * srcPitch) + left;
+    if (id == FOURCC_YV12) {
+	srcu = buf + (srcH * srcPitch) + ((top / 2) * srcPitch2) + (left / 2);
+	srcv = buf + (srcH * srcPitch) + ((srcH / 2) * srcPitch2) +
+	((top / 2) * srcPitch2) + (left / 2);
+    } else {
+	srcv = buf + (srcH * srcPitch) + ((top / 2) * srcPitch2) + (left / 2);
+	srcu = buf + (srcH * srcPitch) + ((srcH / 2) * srcPitch2) +
+	((top / 2) * srcPitch2) + (left / 2);
+    }
+
+    for (y = 0; y < h; y++) {
+	CARD32 *dst = (CARD32 *)dst1;
+	CARD8 *sy = srcy;
+	CARD8 *su = srcu;
+	CARD8 *sv = srcv;
+	int i;
+
+	i = w / 2;
+	while(i > 4) {
+	    dst[0] = sy[0] | (sy[1] << 16) | (sv[0] << 8) | (su[0] << 24);
+	    dst[1] = sy[2] | (sy[3] << 16) | (sv[1] << 8) | (su[1] << 24);
+	    dst[2] = sy[4] | (sy[5] << 16) | (sv[2] << 8) | (su[2] << 24);
+	    dst[3] = sy[6] | (sy[7] << 16) | (sv[3] << 8) | (su[3] << 24);
+	    dst += 4; su += 4; sv += 4; sy += 8;
+	    i -= 4;
+	}
+	while(i--) {
+	    dst[0] = sy[0] | (sy[1] << 16) | (sv[0] << 8) | (su[0] << 24);
+	    dst++; su++; sv++;
+	    sy += 2;
+	}
+
+	dst1 += dstPitch;
+	srcy += srcPitch;
+	if (y & 1) {
+	    srcu += srcPitch2;
+	    srcv += srcPitch2;
+	}	
+    }
 }
 
 static void
@@ -1265,340 +1252,340 @@ I830CopyPlanarData(ScrnInfoPtr pScrn, I8
 		   int srcPitch2, int dstPitch, int srcH, int top, int left,
 		   int h, int w, int id)
 {
-   I830Ptr pI830 = I830PTR(pScrn);
-   int i, j = 0;
-   unsigned char *src1, *src2, *src3, *dst1, *dst2, *dst3;
-   unsigned char *s;
-   int dstPitch2 = dstPitch << 1;
+    I830Ptr pI830 = I830PTR(pScrn);
+    int i, j = 0;
+    unsigned char *src1, *src2, *src3, *dst1, *dst2, *dst3;
+    unsigned char *s;
+    int dstPitch2 = dstPitch << 1;
 
 #if 0
-   ErrorF("I830CopyPlanarData: srcPitch %d, srcPitch %d, dstPitch %d\n"
-	  "nlines %d, npixels %d, top %d, left %d\n",
-	  srcPitch, srcPitch2, dstPitch,
-	  h, w, top, left);
+    ErrorF("I830CopyPlanarData: srcPitch %d, srcPitch %d, dstPitch %d\n"
+	   "nlines %d, npixels %d, top %d, left %d\n",
+	   srcPitch, srcPitch2, dstPitch,
+	   h, w, top, left);
 #endif
 
-   /* Copy Y data */
-   src1 = buf + (top * srcPitch) + left;
+    /* Copy Y data */
+    src1 = buf + (top * srcPitch) + left;
 #if 0
-   ErrorF("src1 is %p, offset is %ld\n", src1,
-	  (unsigned long)src1 - (unsigned long)buf);
+    ErrorF("src1 is %p, offset is %ld\n", src1,
+	   (unsigned long)src1 - (unsigned long)buf);
 #endif
-   if (pPriv->currentBuf == 0)
-      dst1 = pI830->FbBase + pPriv->YBuf0offset;
-   else
-      dst1 = pI830->FbBase + pPriv->YBuf1offset;
-
-   switch (pI830->rotation) {
-      case RR_Rotate_0:
-         for (i = 0; i < h; i++) {
-            memcpy(dst1, src1, w);
-            src1 += srcPitch;
-            dst1 += dstPitch2;
-         }
-	 break;
-      case RR_Rotate_90:
-         for (i = 0; i < h; i++) {
-            s = src1;
-            for (j = 0; j < w; j++) {
-               dst1[(i) + ((w - j - 1) * dstPitch2)] = *s++;
-            }
-            src1 += srcPitch;
-         }
-         break;
-      case RR_Rotate_180:
-         for (i = 0; i < h; i++) {
-            s = src1;
-            for (j = 0; j < w; j++) {
-               dst1[(w - j - 1) + ((h - i - 1) * dstPitch2)] = *s++;
-            }
-            src1 += srcPitch;
-         }
-         break;
-      case RR_Rotate_270:
-         for (i = 0; i < h; i++) {
-            s = src1;
-            for (j = 0; j < w; j++) {
-               dst1[(h - i - 1) + (j * dstPitch2)] = *s++;
-            }
-            src1 += srcPitch;
-         }
-         break;
-   }
+    if (pPriv->currentBuf == 0)
+	dst1 = pI830->FbBase + pPriv->YBuf0offset;
+    else
+	dst1 = pI830->FbBase + pPriv->YBuf1offset;
+
+    switch (pI830->rotation) {
+    case RR_Rotate_0:
+	for (i = 0; i < h; i++) {
+	    memcpy(dst1, src1, w);
+	    src1 += srcPitch;
+	    dst1 += dstPitch2;
+	}
+	break;
+    case RR_Rotate_90:
+	for (i = 0; i < h; i++) {
+	    s = src1;
+	    for (j = 0; j < w; j++) {
+		dst1[(i) + ((w - j - 1) * dstPitch2)] = *s++;
+	    }
+	    src1 += srcPitch;
+	}
+	break;
+    case RR_Rotate_180:
+	for (i = 0; i < h; i++) {
+	    s = src1;
+	    for (j = 0; j < w; j++) {
+		dst1[(w - j - 1) + ((h - i - 1) * dstPitch2)] = *s++;
+	    }
+	    src1 += srcPitch;
+	}
+	break;
+    case RR_Rotate_270:
+	for (i = 0; i < h; i++) {
+	    s = src1;
+	    for (j = 0; j < w; j++) {
+		dst1[(h - i - 1) + (j * dstPitch2)] = *s++;
+	    }
+	    src1 += srcPitch;
+	}
+	break;
+    }
 
-   /* Copy V data for YV12, or U data for I420 */
-   src2 = buf + (srcH * srcPitch) + ((top * srcPitch) >> 2) + (left >> 1);
+    /* Copy V data for YV12, or U data for I420 */
+    src2 = buf + (srcH * srcPitch) + ((top * srcPitch) >> 2) + (left >> 1);
 #if 0
-   ErrorF("src2 is %p, offset is %ld\n", src2,
-	  (unsigned long)src2 - (unsigned long)buf);
+    ErrorF("src2 is %p, offset is %ld\n", src2,
+	   (unsigned long)src2 - (unsigned long)buf);
 #endif
-   if (pPriv->currentBuf == 0) {
-      if (id == FOURCC_I420)
-	 dst2 = pI830->FbBase + pPriv->UBuf0offset;
-      else
-	 dst2 = pI830->FbBase + pPriv->VBuf0offset;
-   } else {
-      if (id == FOURCC_I420)
-	 dst2 = pI830->FbBase + pPriv->UBuf1offset;
-      else
-	 dst2 = pI830->FbBase + pPriv->VBuf1offset;
-   }
-
-   switch (pI830->rotation) {
-      case RR_Rotate_0:
-         for (i = 0; i < h / 2; i++) {
-            memcpy(dst2, src2, w / 2);
-            src2 += srcPitch2;
-            dst2 += dstPitch;
-         }
-         break;
-      case RR_Rotate_90:
-         for (i = 0; i < (h/2); i++) {
-            s = src2;
-            for (j = 0; j < (w/2); j++) {
-               dst2[(i) + (((w/2) - j - 1) * (dstPitch))] = *s++;
-            }
-            src2 += srcPitch2;
-         }
-         break;
-      case RR_Rotate_180:
-         for (i = 0; i < (h/2); i++) {
-            s = src2;
-            for (j = 0; j < (w/2); j++) {
-               dst2[((w/2) - j - 1) + (((h/2) - i - 1) * dstPitch)] = *s++;
-            }
-            src2 += srcPitch2;
-         }
-         break;
-      case RR_Rotate_270:
-         for (i = 0; i < (h/2); i++) {
-            s = src2;
-            for (j = 0; j < (w/2); j++) {
-               dst2[((h/2) - i - 1) + (j * dstPitch)] = *s++;
-            }
-            src2 += srcPitch2;
-         }
-         break;
-   }
-
-   /* Copy U data for YV12, or V data for I420 */
-   src3 = buf + (srcH * srcPitch) + ((srcH >> 1) * srcPitch2) +
-	 ((top * srcPitch) >> 2) + (left >> 1);
+    if (pPriv->currentBuf == 0) {
+	if (id == FOURCC_I420)
+	    dst2 = pI830->FbBase + pPriv->UBuf0offset;
+	else
+	    dst2 = pI830->FbBase + pPriv->VBuf0offset;
+    } else {
+	if (id == FOURCC_I420)
+	    dst2 = pI830->FbBase + pPriv->UBuf1offset;
+	else
+	    dst2 = pI830->FbBase + pPriv->VBuf1offset;
+    }
+
+    switch (pI830->rotation) {
+    case RR_Rotate_0:
+	for (i = 0; i < h / 2; i++) {
+	    memcpy(dst2, src2, w / 2);
+	    src2 += srcPitch2;
+	    dst2 += dstPitch;
+	}
+	break;
+    case RR_Rotate_90:
+	for (i = 0; i < (h/2); i++) {
+	    s = src2;
+	    for (j = 0; j < (w/2); j++) {
+		dst2[(i) + (((w/2) - j - 1) * (dstPitch))] = *s++;
+	    }
+	    src2 += srcPitch2;
+	}
+	break;
+    case RR_Rotate_180:
+	for (i = 0; i < (h/2); i++) {
+	    s = src2;
+	    for (j = 0; j < (w/2); j++) {
+		dst2[((w/2) - j - 1) + (((h/2) - i - 1) * dstPitch)] = *s++;
+	    }
+	    src2 += srcPitch2;
+	}
+	break;
+    case RR_Rotate_270:
+	for (i = 0; i < (h/2); i++) {
+	    s = src2;
+	    for (j = 0; j < (w/2); j++) {
+		dst2[((h/2) - i - 1) + (j * dstPitch)] = *s++;
+	    }
+	    src2 += srcPitch2;
+	}
+	break;
+    }
+
+    /* Copy U data for YV12, or V data for I420 */
+    src3 = buf + (srcH * srcPitch) + ((srcH >> 1) * srcPitch2) +
+    ((top * srcPitch) >> 2) + (left >> 1);
 #if 0
-   ErrorF("src3 is %p, offset is %ld\n", src3,
-	  (unsigned long)src3 - (unsigned long)buf);
+    ErrorF("src3 is %p, offset is %ld\n", src3,
+	   (unsigned long)src3 - (unsigned long)buf);
 #endif
-   if (pPriv->currentBuf == 0) {
-      if (id == FOURCC_I420)
-	 dst3 = pI830->FbBase + pPriv->VBuf0offset;
-      else
-	 dst3 = pI830->FbBase + pPriv->UBuf0offset;
-   } else {
-      if (id == FOURCC_I420)
-	 dst3 = pI830->FbBase + pPriv->VBuf1offset;
-      else
-	 dst3 = pI830->FbBase + pPriv->UBuf1offset;
-   }
-
-   switch (pI830->rotation) {
-      case RR_Rotate_0:
-         for (i = 0; i < h / 2; i++) {
-            memcpy(dst3, src3, w / 2);
-            src3 += srcPitch2;
-            dst3 += dstPitch;
-         }
-         break;
-      case RR_Rotate_90:
-         for (i = 0; i < (h/2); i++) {
-            s = src3;
-            for (j = 0; j < (w/2); j++) {
-               dst3[(i) + (((w/2) - j - 1) * (dstPitch))] = *s++;
-            }
-            src3 += srcPitch2;
-         }
-         break;
-      case RR_Rotate_180:
-         for (i = 0; i < (h/2); i++) {
-            s = src3;
-            for (j = 0; j < (w/2); j++) {
-               dst3[((w/2) - j - 1) + (((h/2) - i - 1) * dstPitch)] = *s++;
-            }
-            src3 += srcPitch2;
-         }
-         break;
-      case RR_Rotate_270:
-         for (i = 0; i < (h/2); i++) {
-            s = src3;
-            for (j = 0; j < (w/2); j++) {
-               dst3[((h/2) - i - 1) + (j * dstPitch)] = *s++;
-            }
-            src3 += srcPitch2;
-         }
-         break;
-   }
+    if (pPriv->currentBuf == 0) {
+	if (id == FOURCC_I420)
+	    dst3 = pI830->FbBase + pPriv->VBuf0offset;
+	else
+	    dst3 = pI830->FbBase + pPriv->UBuf0offset;
+    } else {
+	if (id == FOURCC_I420)
+	    dst3 = pI830->FbBase + pPriv->VBuf1offset;
+	else
+	    dst3 = pI830->FbBase + pPriv->UBuf1offset;
+    }
+
+    switch (pI830->rotation) {
+    case RR_Rotate_0:
+	for (i = 0; i < h / 2; i++) {
+	    memcpy(dst3, src3, w / 2);
+	    src3 += srcPitch2;
+	    dst3 += dstPitch;
+	}
+	break;
+    case RR_Rotate_90:
+	for (i = 0; i < (h/2); i++) {
+	    s = src3;
+	    for (j = 0; j < (w/2); j++) {
+		dst3[(i) + (((w/2) - j - 1) * (dstPitch))] = *s++;
+	    }
+	    src3 += srcPitch2;
+	}
+	break;
+    case RR_Rotate_180:
+	for (i = 0; i < (h/2); i++) {
+	    s = src3;
+	    for (j = 0; j < (w/2); j++) {
+		dst3[((w/2) - j - 1) + (((h/2) - i - 1) * dstPitch)] = *s++;
+	    }
+	    src3 += srcPitch2;
+	}
+	break;
+    case RR_Rotate_270:
+	for (i = 0; i < (h/2); i++) {
+	    s = src3;
+	    for (j = 0; j < (w/2); j++) {
+		dst3[((h/2) - i - 1) + (j * dstPitch)] = *s++;
+	    }
+	    src3 += srcPitch2;
+	}
+	break;
+    }
 }
 
 typedef struct {
-   CARD8 sign;
-   CARD16 mantissa;
-   CARD8 exponent;
+    CARD8 sign;
+    CARD16 mantissa;
+    CARD8 exponent;
 } coeffRec, *coeffPtr;
 
 static Bool
 SetCoeffRegs(double *coeff, int mantSize, coeffPtr pCoeff, int pos)
 {
-   int maxVal, icoeff, res;
-   int sign;
-   double c;
-
-   sign = 0;
-   maxVal = 1 << mantSize;
-   c = *coeff;
-   if (c < 0.0) {
-      sign = 1;
-      c = -c;
-   }
-
-   res = 12 - mantSize;
-   if ((icoeff = (int)(c * 4 * maxVal + 0.5)) < maxVal) {
-      pCoeff[pos].exponent = 3;
-      pCoeff[pos].mantissa = icoeff << res;
-      *coeff = (double)icoeff / (double)(4 * maxVal);
-   } else if ((icoeff = (int)(c * 2 * maxVal + 0.5)) < maxVal) {
-      pCoeff[pos].exponent = 2;
-      pCoeff[pos].mantissa = icoeff << res;
-      *coeff = (double)icoeff / (double)(2 * maxVal);
-   } else if ((icoeff = (int)(c * maxVal + 0.5)) < maxVal) {
-      pCoeff[pos].exponent = 1;
-      pCoeff[pos].mantissa = icoeff << res;
-      *coeff = (double)icoeff / (double)(maxVal);
-   } else if ((icoeff = (int)(c * maxVal * 0.5 + 0.5)) < maxVal) {
-      pCoeff[pos].exponent = 0;
-      pCoeff[pos].mantissa = icoeff << res;
-      *coeff = (double)icoeff / (double)(maxVal / 2);
-   } else {
-      /* Coeff out of range */
-      return FALSE;
-   }
-
-   pCoeff[pos].sign = sign;
-   if (sign)
-      *coeff = -(*coeff);
-   return TRUE;
+    int maxVal, icoeff, res;
+    int sign;
+    double c;
+
+    sign = 0;
+    maxVal = 1 << mantSize;
+    c = *coeff;
+    if (c < 0.0) {
+	sign = 1;
+	c = -c;
+    }
+
+    res = 12 - mantSize;
+    if ((icoeff = (int)(c * 4 * maxVal + 0.5)) < maxVal) {
+	pCoeff[pos].exponent = 3;
+	pCoeff[pos].mantissa = icoeff << res;
+	*coeff = (double)icoeff / (double)(4 * maxVal);
+    } else if ((icoeff = (int)(c * 2 * maxVal + 0.5)) < maxVal) {
+	pCoeff[pos].exponent = 2;
+	pCoeff[pos].mantissa = icoeff << res;
+	*coeff = (double)icoeff / (double)(2 * maxVal);
+    } else if ((icoeff = (int)(c * maxVal + 0.5)) < maxVal) {
+	pCoeff[pos].exponent = 1;
+	pCoeff[pos].mantissa = icoeff << res;
+	*coeff = (double)icoeff / (double)(maxVal);
+    } else if ((icoeff = (int)(c * maxVal * 0.5 + 0.5)) < maxVal) {
+	pCoeff[pos].exponent = 0;
+	pCoeff[pos].mantissa = icoeff << res;
+	*coeff = (double)icoeff / (double)(maxVal / 2);
+    } else {
+	/* Coeff out of range */
+	return FALSE;
+    }
+
+    pCoeff[pos].sign = sign;
+    if (sign)
+	*coeff = -(*coeff);
+    return TRUE;
 }
 
 static void
 UpdateCoeff(int taps, double fCutoff, Bool isHoriz, Bool isY, coeffPtr pCoeff)
 {
-   int i, j, j1, num, pos, mantSize;
-   double pi = 3.1415926535, val, sinc, window, sum;
-   double rawCoeff[MAX_TAPS * 32], coeffs[N_PHASES][MAX_TAPS];
-   double diff;
-   int tapAdjust[MAX_TAPS], tap2Fix;
-   Bool isVertAndUV;
-
-   if (isHoriz)
-      mantSize = 7;
-   else
-      mantSize = 6;
-
-   isVertAndUV = !isHoriz && !isY;
-   num = taps * 16;
-   for (i = 0; i < num  * 2; i++) {
-      val = (1.0 / fCutoff) * taps * pi * (i - num) / (2 * num);
-      if (val == 0.0)
-	 sinc = 1.0;
-      else
-	 sinc = sin(val) / val;
-
-      /* Hamming window */
-      window = (0.5 - 0.5 * cos(i * pi / num));
-      rawCoeff[i] = sinc * window;
-   }
-
-   for (i = 0; i < N_PHASES; i++) {
-      /* Normalise the coefficients. */
-      sum = 0.0;
-      for (j = 0; j < taps; j++) {
-	 pos = i + j * 32;
-	 sum += rawCoeff[pos];
-      }
-      for (j = 0; j < taps; j++) {
-	 pos = i + j * 32;
-	 coeffs[i][j] = rawCoeff[pos] / sum;
-      }
-
-      /* Set the register values. */
-      for (j = 0; j < taps; j++) {
-	 pos = j + i * taps;
-	 if ((j == (taps - 1) / 2) && !isVertAndUV)
-	    SetCoeffRegs(&coeffs[i][j], mantSize + 2, pCoeff, pos);
-	 else
-	    SetCoeffRegs(&coeffs[i][j], mantSize, pCoeff, pos);
-      }
-
-      tapAdjust[0] = (taps - 1) / 2;
-      for (j = 1, j1 = 1; j <= tapAdjust[0]; j++, j1++) {
-	 tapAdjust[j1] = tapAdjust[0] - j;
-	 tapAdjust[++j1] = tapAdjust[0] + j;
-      }
-
-      /* Adjust the coefficients. */
-      sum = 0.0;
-      for (j = 0; j < taps; j++)
-	 sum += coeffs[i][j];
-      if (sum != 1.0) {
-	 for (j1 = 0; j1 < taps; j1++) {
-	    tap2Fix = tapAdjust[j1];
-	    diff = 1.0 - sum;
-	    coeffs[i][tap2Fix] += diff;
-	    pos = tap2Fix + i * taps;
-	    if ((tap2Fix == (taps - 1) / 2) && !isVertAndUV)
-	       SetCoeffRegs(&coeffs[i][tap2Fix], mantSize + 2, pCoeff, pos);
+    int i, j, j1, num, pos, mantSize;
+    double pi = 3.1415926535, val, sinc, window, sum;
+    double rawCoeff[MAX_TAPS * 32], coeffs[N_PHASES][MAX_TAPS];
+    double diff;
+    int tapAdjust[MAX_TAPS], tap2Fix;
+    Bool isVertAndUV;
+
+    if (isHoriz)
+	mantSize = 7;
+    else
+	mantSize = 6;
+
+    isVertAndUV = !isHoriz && !isY;
+    num = taps * 16;
+    for (i = 0; i < num  * 2; i++) {
+	val = (1.0 / fCutoff) * taps * pi * (i - num) / (2 * num);
+	if (val == 0.0)
+	    sinc = 1.0;
+	else
+	    sinc = sin(val) / val;
+
+	/* Hamming window */
+	window = (0.5 - 0.5 * cos(i * pi / num));
+	rawCoeff[i] = sinc * window;
+    }
+
+    for (i = 0; i < N_PHASES; i++) {
+	/* Normalise the coefficients. */
+	sum = 0.0;
+	for (j = 0; j < taps; j++) {
+	    pos = i + j * 32;
+	    sum += rawCoeff[pos];
+	}
+	for (j = 0; j < taps; j++) {
+	    pos = i + j * 32;
+	    coeffs[i][j] = rawCoeff[pos] / sum;
+	}
+
+	/* Set the register values. */
+	for (j = 0; j < taps; j++) {
+	    pos = j + i * taps;
+	    if ((j == (taps - 1) / 2) && !isVertAndUV)
+		SetCoeffRegs(&coeffs[i][j], mantSize + 2, pCoeff, pos);
 	    else
-	       SetCoeffRegs(&coeffs[i][tap2Fix], mantSize, pCoeff, pos);
+		SetCoeffRegs(&coeffs[i][j], mantSize, pCoeff, pos);
+	}
 
-	    sum = 0.0;
-	    for (j = 0; j < taps; j++)
-	       sum += coeffs[i][j];
-	    if (sum == 1.0)
-	       break;
-	 }
-      }
-   }
+	tapAdjust[0] = (taps - 1) / 2;
+	for (j = 1, j1 = 1; j <= tapAdjust[0]; j++, j1++) {
+	    tapAdjust[j1] = tapAdjust[0] - j;
+	    tapAdjust[++j1] = tapAdjust[0] + j;
+	}
+
+	/* Adjust the coefficients. */
+	sum = 0.0;
+	for (j = 0; j < taps; j++)
+	    sum += coeffs[i][j];
+	if (sum != 1.0) {
+	    for (j1 = 0; j1 < taps; j1++) {
+		tap2Fix = tapAdjust[j1];
+		diff = 1.0 - sum;
+		coeffs[i][tap2Fix] += diff;
+		pos = tap2Fix + i * taps;
+		if ((tap2Fix == (taps - 1) / 2) && !isVertAndUV)
+		    SetCoeffRegs(&coeffs[i][tap2Fix], mantSize + 2, pCoeff, pos);
+		else
+		    SetCoeffRegs(&coeffs[i][tap2Fix], mantSize, pCoeff, pos);
+
+		sum = 0.0;
+		for (j = 0; j < taps; j++)
+		    sum += coeffs[i][j];
+		if (sum == 1.0)
+		    break;
+	    }
+	}
+    }
 }
 
 static float
 I830CrtcVideoCoverage (xf86CrtcPtr crtc, BoxPtr video)
 {
-   BoxRec   dest;
-   BoxRec   pipe;
+    BoxRec   dest;
+    BoxRec   pipe;
 
-   if (crtc->enabled)
-   {
-      pipe.x1 = crtc->x;
-      pipe.x2 = crtc->x + xf86ModeWidth (&crtc->mode, crtc->rotation);
-      pipe.y1 = crtc->y;
-      pipe.y2 = crtc->y + xf86ModeHeight (&crtc->mode, crtc->rotation);
-   }
-   else
-   {
-      pipe.x1 = pipe.x2 = 0;
-      pipe.y1 = pipe.y2 = 0;
-   }
-   dest.x1 = pipe.x1 > video->x1 ? pipe.x1 : video->x1;
-   dest.x2 = pipe.x2 < video->x2 ? pipe.x2 : video->x2;
-   dest.y1 = pipe.y1 > video->y1 ? pipe.y1 : video->y1;
-   dest.y2 = pipe.y2 < video->y2 ? pipe.y2 : video->y2;
-   if (dest.x1 >= dest.x2 || dest.y1 >= dest.y2)
-   {
-      dest.x1 = dest.x2 = 0;
-      dest.y1 = dest.y2 = 0;
-   }
-   if (video->x1 >= video->x2 || video->y1 >= video->y2)
-      return 0.0;
-   return (((float) (dest.x2 - dest.x1) * (float) (dest.y2 - dest.y1)) /
-	   ((float) (video->x2 - video->x1) * (float) (video->y2 - video->y1)));
+    if (crtc->enabled)
+    {
+	pipe.x1 = crtc->x;
+	pipe.x2 = crtc->x + xf86ModeWidth (&crtc->mode, crtc->rotation);
+	pipe.y1 = crtc->y;
+	pipe.y2 = crtc->y + xf86ModeHeight (&crtc->mode, crtc->rotation);
+    }
+    else
+    {
+	pipe.x1 = pipe.x2 = 0;
+	pipe.y1 = pipe.y2 = 0;
+    }
+    dest.x1 = pipe.x1 > video->x1 ? pipe.x1 : video->x1;
+    dest.x2 = pipe.x2 < video->x2 ? pipe.x2 : video->x2;
+    dest.y1 = pipe.y1 > video->y1 ? pipe.y1 : video->y1;
+    dest.y2 = pipe.y2 < video->y2 ? pipe.y2 : video->y2;
+    if (dest.x1 >= dest.x2 || dest.y1 >= dest.y2)
+    {
+	dest.x1 = dest.x2 = 0;
+	dest.y1 = dest.y2 = 0;
+    }
+    if (video->x1 >= video->x2 || video->y1 >= video->y2)
+	return 0.0;
+    return (((float) (dest.x2 - dest.x1) * (float) (dest.y2 - dest.y1)) /
+	    ((float) (video->x2 - video->x1) * (float) (video->y2 - video->y1)));
 }
 
 static void
@@ -1606,521 +1593,521 @@ I830DisplayVideo(ScrnInfoPtr pScrn, int 
 		 int dstPitch, int x1, int y1, int x2, int y2, BoxPtr dstBox,
 		 short src_w, short src_h, short drw_w, short drw_h)
 {
-   I830Ptr pI830 = I830PTR(pScrn);
-   I830PortPrivPtr pPriv = pI830->adaptor->pPortPrivates[0].ptr;
-   I830OverlayRegPtr overlay =
-	 (I830OverlayRegPtr) (pI830->FbBase + pI830->overlay_regs->offset);
-   unsigned int swidth;
-   unsigned int mask, shift, offsety, offsetu;
-   xf86CrtcPtr crtc;
-   int tmp;
+    I830Ptr pI830 = I830PTR(pScrn);
+    I830PortPrivPtr pPriv = pI830->adaptor->pPortPrivates[0].ptr;
+    I830OverlayRegPtr overlay =
+    (I830OverlayRegPtr) (pI830->FbBase + pI830->overlay_regs->offset);
+    unsigned int swidth;
+    unsigned int mask, shift, offsety, offsetu;
+    xf86CrtcPtr crtc;
+    int tmp;
 
-   OVERLAY_DEBUG("I830DisplayVideo: %dx%d (pitch %d)\n", width, height,
-		 dstPitch);
+    OVERLAY_DEBUG("I830DisplayVideo: %dx%d (pitch %d)\n", width, height,
+		  dstPitch);
 
-   if (!pPriv->overlayOK)
-      return;
+    if (!pPriv->overlayOK)
+	return;
 
 #if VIDEO_DEBUG
-   CompareOverlay(pI830, (CARD32 *) overlay, 0x100);
+    CompareOverlay(pI830, (CARD32 *) overlay, 0x100);
 #endif
 
-   {
-      float best_coverage = 0.0;
-      float coverage;
-      int c;
-      xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
-      
-      crtc = NULL;
-      for (c = 0; c < xf86_config->num_crtc; c++)
-      {
-	 xf86CrtcPtr	this_crtc = xf86_config->crtc[c];
-	 coverage = I830CrtcVideoCoverage (this_crtc, dstBox);
-	 if (coverage)
-	 {
-	    if (this_crtc == pPriv->desired_crtc)
-	    {
-	       crtc = this_crtc;
-	       best_coverage = 1.0;
-	    }
-	    else if (coverage > best_coverage)
+    {
+	float best_coverage = 0.0;
+	float coverage;
+	int c;
+	xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+
+	crtc = NULL;
+	for (c = 0; c < xf86_config->num_crtc; c++)
+	{
+	    xf86CrtcPtr	this_crtc = xf86_config->crtc[c];
+	    coverage = I830CrtcVideoCoverage (this_crtc, dstBox);
+	    if (coverage)
 	    {
-	       crtc = this_crtc;
-	       best_coverage = coverage;
+		if (this_crtc == pPriv->desired_crtc)
+		{
+		    crtc = this_crtc;
+		    best_coverage = 1.0;
+		}
+		else if (coverage > best_coverage)
+		{
+		    crtc = this_crtc;
+		    best_coverage = coverage;
+		}
 	    }
-	 }
-      }
-      if (crtc != pPriv->current_crtc)
-      {
-	 pPriv->current_crtc = crtc;
-	 I830ResetVideo (pScrn);
-      }
-   }
-
-   switch (crtc->rotation & 0xf) {
-	case RR_Rotate_0:
-		dstBox->x1 -= crtc->x;
-		dstBox->x2 -= crtc->x;
-		dstBox->y1 -= crtc->y;
-		dstBox->y2 -= crtc->y;
-		break;
-	case RR_Rotate_90:
-		tmp = dstBox->x1;
-		dstBox->x1 = dstBox->y1 - crtc->x;
-		dstBox->y1 = pScrn->virtualY - tmp - crtc->y;
-		tmp = dstBox->x2;
-		dstBox->x2 = dstBox->y2 - crtc->x;
-		dstBox->y2 = pScrn->virtualY - tmp - crtc->y;
-		tmp = dstBox->y1;
-		dstBox->y1 = dstBox->y2;
-		dstBox->y2 = tmp;
-		break;
-	case RR_Rotate_180:
-		tmp = dstBox->x1;
-		dstBox->x1 = pScrn->virtualX - dstBox->x2 - crtc->x;
-		dstBox->x2 = pScrn->virtualX - tmp - crtc->x;
-		tmp = dstBox->y1;
-		dstBox->y1 = pScrn->virtualY - dstBox->y2 - crtc->y;
-		dstBox->y2 = pScrn->virtualY - tmp - crtc->y;
-		break;
-	case RR_Rotate_270:
-		tmp = dstBox->x1;
-		dstBox->x1 = pScrn->virtualX - dstBox->y1 - crtc->x;
-		dstBox->y1 = tmp - crtc->y;
-		tmp = dstBox->x2;
-		dstBox->x2 = pScrn->virtualX - dstBox->y2 - crtc->x;
-		dstBox->y2 = tmp - crtc->y;
-		tmp = dstBox->x1;
-		dstBox->x1 = dstBox->x2;
-		dstBox->x2 = tmp;
-		break;
-   }
+	}
+	if (crtc != pPriv->current_crtc)
+	{
+	    pPriv->current_crtc = crtc;
+	    I830ResetVideo (pScrn);
+	}
+    }
+
+    switch (crtc->rotation & 0xf) {
+    case RR_Rotate_0:
+	dstBox->x1 -= crtc->x;
+	dstBox->x2 -= crtc->x;
+	dstBox->y1 -= crtc->y;
+	dstBox->y2 -= crtc->y;
+	break;
+    case RR_Rotate_90:
+	tmp = dstBox->x1;
+	dstBox->x1 = dstBox->y1 - crtc->x;
+	dstBox->y1 = pScrn->virtualY - tmp - crtc->y;
+	tmp = dstBox->x2;
+	dstBox->x2 = dstBox->y2 - crtc->x;
+	dstBox->y2 = pScrn->virtualY - tmp - crtc->y;
+	tmp = dstBox->y1;
+	dstBox->y1 = dstBox->y2;
+	dstBox->y2 = tmp;
+	break;
+    case RR_Rotate_180:
+	tmp = dstBox->x1;
+	dstBox->x1 = pScrn->virtualX - dstBox->x2 - crtc->x;
+	dstBox->x2 = pScrn->virtualX - tmp - crtc->x;
+	tmp = dstBox->y1;
+	dstBox->y1 = pScrn->virtualY - dstBox->y2 - crtc->y;
+	dstBox->y2 = pScrn->virtualY - tmp - crtc->y;
+	break;
+    case RR_Rotate_270:
+	tmp = dstBox->x1;
+	dstBox->x1 = pScrn->virtualX - dstBox->y1 - crtc->x;
+	dstBox->y1 = tmp - crtc->y;
+	tmp = dstBox->x2;
+	dstBox->x2 = pScrn->virtualX - dstBox->y2 - crtc->x;
+	dstBox->y2 = tmp - crtc->y;
+	tmp = dstBox->x1;
+	dstBox->x1 = dstBox->x2;
+	dstBox->x2 = tmp;
+	break;
+    }
+
+    /* When in dual head with different bpp setups we need to refresh the
+     * color key, so let's reset the video parameters and refresh here.
+     * In MergedFB mode, we may need to flip pipes too. */
+    if (pI830->entityPrivate)
+	I830ResetVideo(pScrn);
+
+    /* Ensure overlay is turned on with OVERLAY_ENABLE at 0 */
+    i830_overlay_on (pScrn);
+
+    /* Fix up the dstBox if outside the visible screen */
+    {
+	int offset_x = (dstBox->x1 < 0) ? -dstBox->x1 : 0;
+	int offset_y = (dstBox->y1 < 0) ? -dstBox->y1 : 0;
+	int offset, offset2;
+
+	/* align */
+	offset_x = (offset_x + 3) & ~3;
+	offset_y = (offset_y + 3) & ~3;
+
+	if (crtc->rotation & (RR_Rotate_90 | RR_Rotate_270)) {
+	    height -= offset_x;
+	    width -= offset_y;
+	} else {
+	    height -= offset_y;
+	    width -= offset_x;
+	}
+
+	if (id == FOURCC_I420 || id == FOURCC_YV12) {
+	    offset = ((offset_x/2) + (dstPitch * offset_y)) * 2;
+	    offset2 = ((offset_x/2) + ((dstPitch/2) * offset_y));
+	} else {
+	    offset = ((offset_x*2) + (dstPitch * offset_y));
+	    offset2 = ((offset_x*2) + ((dstPitch/2) * offset_y));
+	}
+
+	/* buffer locations */
+	pPriv->YBuf0offset += offset;
+	pPriv->UBuf0offset += offset2;
+	pPriv->VBuf0offset += offset2;
+
+	if(pPriv->doubleBuffer) {
+	    pPriv->YBuf1offset += offset;
+	    pPriv->UBuf1offset += offset2;
+	    pPriv->VBuf1offset += offset2;
+	}
+    }
+
+    if (crtc->rotation & (RR_Rotate_90 | RR_Rotate_270)) {
+	tmp = width;
+	width = height;
+	height = tmp;
+	tmp = drw_w;
+	drw_w = drw_h;
+	drw_h = tmp;
+	tmp = src_w;
+	src_w = src_h;
+	src_h = tmp;
+    }
+
+    if (pPriv->oneLineMode) {
+	/* change the coordinates with panel fitting active */
+	dstBox->y1 = (((dstBox->y1 - 1) * pPriv->scaleRatio) >> 16) + 1;
+	dstBox->y2 = ((dstBox->y2 * pPriv->scaleRatio) >> 16) + 1;
+
+	/* Now, alter the height, so we scale to the correct size */
+	drw_h = ((drw_h * pPriv->scaleRatio) >> 16) + 1;
+    }
+
+    {
+	/* Keep the engine happy and clip to the real vertical size just
+	 * in case an LFP is in use and it's not at it's native resolution.
+	 */
+	int vactive = I830CrtcPipe (pPriv->current_crtc) ? (INREG(VTOTAL_B) & 0x7FF) : (INREG(VTOTAL_A) & 0x7FF);
+	int hactive = pPriv->current_crtc->mode.HDisplay;
+
+	vactive += 1;
+
+	if (dstBox->y1 < 0) dstBox->y1 = 0;
+	if (dstBox->y2 < 0) dstBox->y2 = 0;
+	if (dstBox->x1 < 0) dstBox->x1 = 0;
+	if (dstBox->x2 < 0) dstBox->x2 = 0;
+	if (dstBox->y1 > vactive) dstBox->y1 = vactive;
+	if (dstBox->y2 > vactive) dstBox->y2 = vactive;
+	if (dstBox->x1 > hactive) dstBox->x1 = hactive;
+	if (dstBox->x2 > hactive) dstBox->x2 = hactive;
+
+	/* nothing do to */
+	if ((!dstBox->x1 && !dstBox->x2) || (!dstBox->y1 && !dstBox->y2)) {
+	    OVERLAY_DEBUG("NOTHING TO DO\n");
+	    return;
+	}
+	if ((dstBox->x1 == (hactive) && 
+	     dstBox->x2 == (hactive)) || 
+	    (dstBox->y1 == vactive && 
+	     dstBox->y2 == vactive)) {
+	    OVERLAY_DEBUG("NOTHING TO DO\n");
+	    return;
+	}
+	if ((dstBox->y2 - dstBox->y1) <= N_VERT_Y_TAPS) {
+	    OVERLAY_DEBUG("NOTHING TO DO\n");
+	    return;
+	}
+	if ((dstBox->x2 - dstBox->x1) <= 2) {
+	    OVERLAY_DEBUG("NOTHING TO DO\n");
+	    return;
+	}
+    }
 
-   /* When in dual head with different bpp setups we need to refresh the
-    * color key, so let's reset the video parameters and refresh here.
-    * In MergedFB mode, we may need to flip pipes too. */
-   if (pI830->entityPrivate)
-      I830ResetVideo(pScrn);
-
-   /* Ensure overlay is turned on with OVERLAY_ENABLE at 0 */
-   i830_overlay_on (pScrn);
-
-   /* Fix up the dstBox if outside the visible screen */
-   {
-      int offset_x = (dstBox->x1 < 0) ? -dstBox->x1 : 0;
-      int offset_y = (dstBox->y1 < 0) ? -dstBox->y1 : 0;
-      int offset, offset2;
-
-      /* align */
-      offset_x = (offset_x + 3) & ~3;
-      offset_y = (offset_y + 3) & ~3;
-
-      if (crtc->rotation & (RR_Rotate_90 | RR_Rotate_270)) {
-         height -= offset_x;
-         width -= offset_y;
-      } else {
-         height -= offset_y;
-         width -= offset_x;
-      }
-
-      if (id == FOURCC_I420 || id == FOURCC_YV12) {
-         offset = ((offset_x/2) + (dstPitch * offset_y)) * 2;
-         offset2 = ((offset_x/2) + ((dstPitch/2) * offset_y));
-      } else {
-         offset = ((offset_x*2) + (dstPitch * offset_y));
-         offset2 = ((offset_x*2) + ((dstPitch/2) * offset_y));
-      }
-
-      /* buffer locations */
-      pPriv->YBuf0offset += offset;
-      pPriv->UBuf0offset += offset2;
-      pPriv->VBuf0offset += offset2;
-
-      if(pPriv->doubleBuffer) {
-         pPriv->YBuf1offset += offset;
-         pPriv->UBuf1offset += offset2;
-         pPriv->VBuf1offset += offset2;
-      }
-   }
-
-   if (crtc->rotation & (RR_Rotate_90 | RR_Rotate_270)) {
-      tmp = width;
-      width = height;
-      height = tmp;
-      tmp = drw_w;
-      drw_w = drw_h;
-      drw_h = tmp;
-      tmp = src_w;
-      src_w = src_h;
-      src_h = tmp;
-   }
-
-   if (pPriv->oneLineMode) {
-      /* change the coordinates with panel fitting active */
-      dstBox->y1 = (((dstBox->y1 - 1) * pPriv->scaleRatio) >> 16) + 1;
-      dstBox->y2 = ((dstBox->y2 * pPriv->scaleRatio) >> 16) + 1;
- 
-      /* Now, alter the height, so we scale to the correct size */
-      drw_h = ((drw_h * pPriv->scaleRatio) >> 16) + 1;
-   }
-
-   {
-      /* Keep the engine happy and clip to the real vertical size just
-       * in case an LFP is in use and it's not at it's native resolution.
-       */
-      int vactive = I830CrtcPipe (pPriv->current_crtc) ? (INREG(VTOTAL_B) & 0x7FF) : (INREG(VTOTAL_A) & 0x7FF);
-      int hactive = pPriv->current_crtc->mode.HDisplay;
-
-      vactive += 1;
-
-      if (dstBox->y1 < 0) dstBox->y1 = 0;
-      if (dstBox->y2 < 0) dstBox->y2 = 0;
-      if (dstBox->x1 < 0) dstBox->x1 = 0;
-      if (dstBox->x2 < 0) dstBox->x2 = 0;
-      if (dstBox->y1 > vactive) dstBox->y1 = vactive;
-      if (dstBox->y2 > vactive) dstBox->y2 = vactive;
-      if (dstBox->x1 > hactive) dstBox->x1 = hactive;
-      if (dstBox->x2 > hactive) dstBox->x2 = hactive;
-
-      /* nothing do to */
-      if ((!dstBox->x1 && !dstBox->x2) || (!dstBox->y1 && !dstBox->y2)) {
-         OVERLAY_DEBUG("NOTHING TO DO\n");
-         return;
-      }
-      if ((dstBox->x1 == (hactive) && 
-           dstBox->x2 == (hactive)) || 
-          (dstBox->y1 == vactive && 
-           dstBox->y2 == vactive)) {
-         OVERLAY_DEBUG("NOTHING TO DO\n");
-         return;
-      }
-      if ((dstBox->y2 - dstBox->y1) <= N_VERT_Y_TAPS) {
-         OVERLAY_DEBUG("NOTHING TO DO\n");
-         return;
-      }
-      if ((dstBox->x2 - dstBox->x1) <= 2) {
-         OVERLAY_DEBUG("NOTHING TO DO\n");
-         return;
-      }
-   }
-
-   if (IS_I9XX(pI830)) {
-      shift = 6;
-      mask = 0x3f;
-   } else {
-      shift = 5;
-      mask = 0x1f;
-   }
-
-   if (pPriv->currentBuf == 0) {
-      offsety = pPriv->YBuf0offset;
-      offsetu = pPriv->UBuf0offset;
-   } else {
-      offsety = pPriv->YBuf1offset;
-      offsetu = pPriv->UBuf1offset;
-   }
-
-   switch (id) {
-   case FOURCC_YV12:
-   case FOURCC_I420:
-      swidth = width;
-
-      overlay->SWIDTH = swidth;
-      swidth /= 2;
-      overlay->SWIDTH |= (swidth & 0x7ff) << 16;
-
-      swidth = ((offsety + width + mask) >> shift) -
-	    (offsety >> shift);
-
-      if (IS_I9XX(pI830))
-         swidth <<= 1;
-
-      swidth -= 1;
-
-      OVERLAY_DEBUG("Y width is %d, swidth is %d\n", width, swidth);
-
-      overlay->SWIDTHSW = swidth << 2;
-
-      swidth = ((offsetu + (width / 2) + mask) >> shift) -
-	    (offsetu >> shift);
-
-      if (IS_I9XX(pI830))
-         swidth <<= 1;
-
-      swidth -= 1;
-
-      OVERLAY_DEBUG("UV width is %d, swidthsw is %d\n", width / 2, swidth);
-
-      overlay->SWIDTHSW |= swidth << 18;
-
-      OVERLAY_DEBUG("HEIGHT is %d\n",height);
-
-      overlay->SHEIGHT = height | ((height / 2) << 16);
-      break;
-   case FOURCC_UYVY:
-   case FOURCC_YUY2:
-   default:
-      swidth = width;
-      overlay->SWIDTH = swidth;
-
-      OVERLAY_DEBUG("Y width is %d\n", swidth);
-
-      swidth = ((offsety + (width << 1) + mask) >> shift) -
-	    (offsety >> shift);
-
-      if (IS_I9XX(pI830))
-         swidth <<= 1;
-
-      swidth -= 1;
-
-      OVERLAY_DEBUG("swidthsw is %d\n", swidth);
-
-      overlay->SWIDTHSW = swidth << 2;
-
-      OVERLAY_DEBUG("HEIGHT is %d\n",height);
-
-      overlay->SHEIGHT = height;
-      break;
-   }
-
-   overlay->OCMD = OVERLAY_ENABLE;
-
-   overlay->DWINPOS = (dstBox->y1 << 16) | dstBox->x1;
-
-   overlay->DWINSZ = ((dstBox->y2 - dstBox->y1) << 16) |
-	 (dstBox->x2 - dstBox->x1);
-
-   OVERLAY_DEBUG("dstBox: x1: %d, y1: %d, x2: %d, y2: %d\n",
-		 dstBox->x1, dstBox->y1, dstBox->x2, dstBox->y2);
-
-   /* buffer locations */
-   if (IS_I965G(pI830))
-   {
-      overlay->OBUF_0Y = 0;
-      overlay->OBUF_0U = 0;
-      overlay->OBUF_0V = 0;
-      overlay->OSTART_0Y = pPriv->YBuf0offset;
-      overlay->OSTART_0U = pPriv->UBuf0offset;
-      overlay->OSTART_0V = pPriv->VBuf0offset;
-      if(pPriv->doubleBuffer) {
-         overlay->OBUF_1Y = 0;
-         overlay->OBUF_1U = 0;
-         overlay->OBUF_1V = 0;
-         overlay->OSTART_1Y = pPriv->YBuf1offset;
-         overlay->OSTART_1U = pPriv->UBuf1offset;
-         overlay->OSTART_1V = pPriv->VBuf1offset;
-      }
-   } else {
-      overlay->OBUF_0Y = pPriv->YBuf0offset;
-      overlay->OBUF_0U = pPriv->UBuf0offset;
-      overlay->OBUF_0V = pPriv->VBuf0offset;
-      if(pPriv->doubleBuffer) {
-         overlay->OBUF_1Y = pPriv->YBuf1offset;
-         overlay->OBUF_1U = pPriv->UBuf1offset;
-         overlay->OBUF_1V = pPriv->VBuf1offset;
-      }
-   }
-
-   OVERLAY_DEBUG("Buffers: Y0: 0x%lx, U0: 0x%lx, V0: 0x%lx\n",
-		 overlay->OBUF_0Y, overlay->OBUF_0U, overlay->OBUF_0V);
-   OVERLAY_DEBUG("Buffers: Y1: 0x%lx, U1: 0x%lx, V1: 0x%lx\n",
-		 overlay->OBUF_1Y, overlay->OBUF_1U, overlay->OBUF_1V);
+    if (IS_I9XX(pI830)) {
+	shift = 6;
+	mask = 0x3f;
+    } else {
+	shift = 5;
+	mask = 0x1f;
+    }
+
+    if (pPriv->currentBuf == 0) {
+	offsety = pPriv->YBuf0offset;
+	offsetu = pPriv->UBuf0offset;
+    } else {
+	offsety = pPriv->YBuf1offset;
+	offsetu = pPriv->UBuf1offset;
+    }
+
+    switch (id) {
+    case FOURCC_YV12:
+    case FOURCC_I420:
+	swidth = width;
+
+	overlay->SWIDTH = swidth;
+	swidth /= 2;
+	overlay->SWIDTH |= (swidth & 0x7ff) << 16;
+
+	swidth = ((offsety + width + mask) >> shift) -
+	(offsety >> shift);
+
+	if (IS_I9XX(pI830))
+	    swidth <<= 1;
+
+	swidth -= 1;
+
+	OVERLAY_DEBUG("Y width is %d, swidth is %d\n", width, swidth);
+
+	overlay->SWIDTHSW = swidth << 2;
+
+	swidth = ((offsetu + (width / 2) + mask) >> shift) -
+	(offsetu >> shift);
+
+	if (IS_I9XX(pI830))
+	    swidth <<= 1;
+
+	swidth -= 1;
+
+	OVERLAY_DEBUG("UV width is %d, swidthsw is %d\n", width / 2, swidth);
+
+	overlay->SWIDTHSW |= swidth << 18;
+
+	OVERLAY_DEBUG("HEIGHT is %d\n",height);
+
+	overlay->SHEIGHT = height | ((height / 2) << 16);
+	break;
+    case FOURCC_UYVY:
+    case FOURCC_YUY2:
+    default:
+	swidth = width;
+	overlay->SWIDTH = swidth;
+
+	OVERLAY_DEBUG("Y width is %d\n", swidth);
+
+	swidth = ((offsety + (width << 1) + mask) >> shift) -
+	(offsety >> shift);
+
+	if (IS_I9XX(pI830))
+	    swidth <<= 1;
+
+	swidth -= 1;
+
+	OVERLAY_DEBUG("swidthsw is %d\n", swidth);
+
+	overlay->SWIDTHSW = swidth << 2;
+
+	OVERLAY_DEBUG("HEIGHT is %d\n",height);
+
+	overlay->SHEIGHT = height;
+	break;
+    }
+
+    overlay->OCMD = OVERLAY_ENABLE;
+
+    overlay->DWINPOS = (dstBox->y1 << 16) | dstBox->x1;
+
+    overlay->DWINSZ = ((dstBox->y2 - dstBox->y1) << 16) |
+    (dstBox->x2 - dstBox->x1);
+
+    OVERLAY_DEBUG("dstBox: x1: %d, y1: %d, x2: %d, y2: %d\n",
+		  dstBox->x1, dstBox->y1, dstBox->x2, dstBox->y2);
+
+    /* buffer locations */
+    if (IS_I965G(pI830))
+    {
+	overlay->OBUF_0Y = 0;
+	overlay->OBUF_0U = 0;
+	overlay->OBUF_0V = 0;
+	overlay->OSTART_0Y = pPriv->YBuf0offset;
+	overlay->OSTART_0U = pPriv->UBuf0offset;
+	overlay->OSTART_0V = pPriv->VBuf0offset;
+	if(pPriv->doubleBuffer) {
+	    overlay->OBUF_1Y = 0;
+	    overlay->OBUF_1U = 0;
+	    overlay->OBUF_1V = 0;
+	    overlay->OSTART_1Y = pPriv->YBuf1offset;
+	    overlay->OSTART_1U = pPriv->UBuf1offset;
+	    overlay->OSTART_1V = pPriv->VBuf1offset;
+	}
+    } else {
+	overlay->OBUF_0Y = pPriv->YBuf0offset;
+	overlay->OBUF_0U = pPriv->UBuf0offset;
+	overlay->OBUF_0V = pPriv->VBuf0offset;
+	if(pPriv->doubleBuffer) {
+	    overlay->OBUF_1Y = pPriv->YBuf1offset;
+	    overlay->OBUF_1U = pPriv->UBuf1offset;
+	    overlay->OBUF_1V = pPriv->VBuf1offset;
+	}
+    }
+
+    OVERLAY_DEBUG("Buffers: Y0: 0x%lx, U0: 0x%lx, V0: 0x%lx\n",
+		  overlay->OBUF_0Y, overlay->OBUF_0U, overlay->OBUF_0V);
+    OVERLAY_DEBUG("Buffers: Y1: 0x%lx, U1: 0x%lx, V1: 0x%lx\n",
+		  overlay->OBUF_1Y, overlay->OBUF_1U, overlay->OBUF_1V);
 
 #if 0
-   {
-      int i;
+    {
+	int i;
+
+	ErrorF("First 32 bytes of Y data:\n");
+	for (i = 0; i < 32; i++)
+	    ErrorF(" %02x",
+		   ((unsigned char *)pI830->FbBase + pPriv->YBuf0offset)[i]);
+	ErrorF("\n");
+	ErrorF("First 16 bytes of U data:\n");
+	for (i = 0; i < 16; i++)
+	    ErrorF(" %02x",
+		   ((unsigned char *)pI830->FbBase + pPriv->UBuf0offset)[i]);
+	ErrorF("\n");
+	ErrorF("First 16 bytes of V data:\n");
+	for (i = 0; i < 16; i++)
+	    ErrorF(" %02x",
+		   ((unsigned char *)pI830->FbBase + pPriv->VBuf0offset)[i]);
+	ErrorF("\n");
+    }
+#endif
+
+    OVERLAY_DEBUG("pos: 0x%lx, size: 0x%lx\n",
+		  overlay->DWINPOS, overlay->DWINSZ);
+    OVERLAY_DEBUG("dst: %d x %d, src: %d x %d\n", drw_w, drw_h, src_w, src_h);
+
+    /* 
+     * Calculate horizontal and vertical scaling factors and polyphase
+     * coefficients.
+     */
+
+    {
+	Bool scaleChanged = FALSE;
+	int xscaleInt, xscaleFract, yscaleInt, yscaleFract;
+	int xscaleIntUV, xscaleFractUV;
+	int yscaleIntUV, yscaleFractUV;
+	/* UV is half the size of Y -- YUV420 */
+	int uvratio = 2;
+	CARD32 newval;
+	coeffRec xcoeffY[N_HORIZ_Y_TAPS * N_PHASES];
+	coeffRec xcoeffUV[N_HORIZ_UV_TAPS * N_PHASES];
+	int i, j, pos;
+
+	/*
+	 * Y down-scale factor as a multiple of 4096.
+	 */
+	xscaleFract = ((src_w - 1) << 12) / drw_w;
+	yscaleFract = ((src_h - 1) << 12) / drw_h;
+
+	/* Calculate the UV scaling factor. */
+	xscaleFractUV = xscaleFract / uvratio;
+	yscaleFractUV = yscaleFract / uvratio;
+
+	/*
+	 * To keep the relative Y and UV ratios exact, round the Y scales
+	 * to a multiple of the Y/UV ratio.
+	 */
+	xscaleFract = xscaleFractUV * uvratio;
+	yscaleFract = yscaleFractUV * uvratio;
+
+	/* Integer (un-multiplied) values. */
+	xscaleInt = xscaleFract >> 12;
+	yscaleInt = yscaleFract >> 12;
+
+	xscaleIntUV = xscaleFractUV >> 12;
+	yscaleIntUV = yscaleFractUV >> 12;
+
+	OVERLAY_DEBUG("xscale: %x.%03x, yscale: %x.%03x\n", xscaleInt,
+		      xscaleFract & 0xFFF, yscaleInt, yscaleFract & 0xFFF);
+	OVERLAY_DEBUG("UV xscale: %x.%03x, UV yscale: %x.%03x\n", xscaleIntUV,
+		      xscaleFractUV & 0xFFF, yscaleIntUV, yscaleFractUV & 0xFFF);
+
+	/* shouldn't get here */
+	if (xscaleInt > 7) {
+	    OVERLAY_DEBUG("xscale: bad scale\n");
+	    return;
+	}
+
+	/* shouldn't get here */
+	if (xscaleIntUV > 7) {
+	    OVERLAY_DEBUG("xscaleUV: bad scale\n");
+	    return;
+	}
+
+	newval = (xscaleInt << 16) |
+	((xscaleFract & 0xFFF) << 3) | ((yscaleFract & 0xFFF) << 20);
+	if (newval != overlay->YRGBSCALE) {
+	    scaleChanged = TRUE;
+	    overlay->YRGBSCALE = newval;
+	}
+
+	newval = (xscaleIntUV << 16) | ((xscaleFractUV & 0xFFF) << 3) |
+	((yscaleFractUV & 0xFFF) << 20);
+	if (newval != overlay->UVSCALE) {
+	    scaleChanged = TRUE;
+	    overlay->UVSCALE = newval;
+	}
+
+	newval = yscaleInt << 16 | yscaleIntUV;
+	if (newval != overlay->UVSCALEV) {
+	    scaleChanged = TRUE;
+	    overlay->UVSCALEV = newval;
+	}
+
+	/* Recalculate coefficients if the scaling changed. */
+
+	/*
+	 * Only Horizontal coefficients so far.
+	 */
+	if (scaleChanged) {
+	    double fCutoffY;
+	    double fCutoffUV;
+
+	    fCutoffY = xscaleFract / 4096.0;
+	    fCutoffUV = xscaleFractUV / 4096.0;
+
+	    /* Limit to between 1.0 and 3.0. */
+	    if (fCutoffY < MIN_CUTOFF_FREQ)
+		fCutoffY = MIN_CUTOFF_FREQ;
+	    if (fCutoffY > MAX_CUTOFF_FREQ)
+		fCutoffY = MAX_CUTOFF_FREQ;
+	    if (fCutoffUV < MIN_CUTOFF_FREQ)
+		fCutoffUV = MIN_CUTOFF_FREQ;
+	    if (fCutoffUV > MAX_CUTOFF_FREQ)
+		fCutoffUV = MAX_CUTOFF_FREQ;
+
+	    UpdateCoeff(N_HORIZ_Y_TAPS, fCutoffY, TRUE, TRUE, xcoeffY);
+	    UpdateCoeff(N_HORIZ_UV_TAPS, fCutoffUV, TRUE, FALSE, xcoeffUV);
+
+	    for (i = 0; i < N_PHASES; i++) {
+		for (j = 0; j < N_HORIZ_Y_TAPS; j++) {
+		    pos = i * N_HORIZ_Y_TAPS + j;
+		    overlay->Y_HCOEFS[pos] = xcoeffY[pos].sign << 15 |
+		    xcoeffY[pos].exponent << 12 |
+		    xcoeffY[pos].mantissa;
+		}
+	    }
+	    for (i = 0; i < N_PHASES; i++) {
+		for (j = 0; j < N_HORIZ_UV_TAPS; j++) {
+		    pos = i * N_HORIZ_UV_TAPS + j;
+		    overlay->UV_HCOEFS[pos] = xcoeffUV[pos].sign << 15 |
+		    xcoeffUV[pos].exponent << 12 |
+		    xcoeffUV[pos].mantissa;
+		}
+	    }
+	}
+    }
 
-      ErrorF("First 32 bytes of Y data:\n");
-      for (i = 0; i < 32; i++)
-	 ErrorF(" %02x",
-		((unsigned char *)pI830->FbBase + pPriv->YBuf0offset)[i]);
-      ErrorF("\n");
-      ErrorF("First 16 bytes of U data:\n");
-      for (i = 0; i < 16; i++)
-	 ErrorF(" %02x",
-		((unsigned char *)pI830->FbBase + pPriv->UBuf0offset)[i]);
-      ErrorF("\n");
-      ErrorF("First 16 bytes of V data:\n");
-      for (i = 0; i < 16; i++)
-	 ErrorF(" %02x",
-		((unsigned char *)pI830->FbBase + pPriv->VBuf0offset)[i]);
-      ErrorF("\n");
-   }
-#endif
-
-   OVERLAY_DEBUG("pos: 0x%lx, size: 0x%lx\n",
-		 overlay->DWINPOS, overlay->DWINSZ);
-   OVERLAY_DEBUG("dst: %d x %d, src: %d x %d\n", drw_w, drw_h, src_w, src_h);
-
-   /* 
-    * Calculate horizontal and vertical scaling factors and polyphase
-    * coefficients.
-    */
-
-   {
-      Bool scaleChanged = FALSE;
-      int xscaleInt, xscaleFract, yscaleInt, yscaleFract;
-      int xscaleIntUV, xscaleFractUV;
-      int yscaleIntUV, yscaleFractUV;
-      /* UV is half the size of Y -- YUV420 */
-      int uvratio = 2;
-      CARD32 newval;
-      coeffRec xcoeffY[N_HORIZ_Y_TAPS * N_PHASES];
-      coeffRec xcoeffUV[N_HORIZ_UV_TAPS * N_PHASES];
-      int i, j, pos;
-
-      /*
-       * Y down-scale factor as a multiple of 4096.
-       */
-      xscaleFract = ((src_w - 1) << 12) / drw_w;
-      yscaleFract = ((src_h - 1) << 12) / drw_h;
-
-      /* Calculate the UV scaling factor. */
-      xscaleFractUV = xscaleFract / uvratio;
-      yscaleFractUV = yscaleFract / uvratio;
-
-      /*
-       * To keep the relative Y and UV ratios exact, round the Y scales
-       * to a multiple of the Y/UV ratio.
-       */
-      xscaleFract = xscaleFractUV * uvratio;
-      yscaleFract = yscaleFractUV * uvratio;
-
-      /* Integer (un-multiplied) values. */
-      xscaleInt = xscaleFract >> 12;
-      yscaleInt = yscaleFract >> 12;
-
-      xscaleIntUV = xscaleFractUV >> 12;
-      yscaleIntUV = yscaleFractUV >> 12;
-
-      OVERLAY_DEBUG("xscale: %x.%03x, yscale: %x.%03x\n", xscaleInt,
-		    xscaleFract & 0xFFF, yscaleInt, yscaleFract & 0xFFF);
-      OVERLAY_DEBUG("UV xscale: %x.%03x, UV yscale: %x.%03x\n", xscaleIntUV,
-		    xscaleFractUV & 0xFFF, yscaleIntUV, yscaleFractUV & 0xFFF);
-
-      /* shouldn't get here */
-      if (xscaleInt > 7) {
-         OVERLAY_DEBUG("xscale: bad scale\n");
-	 return;
-      }
-
-      /* shouldn't get here */
-      if (xscaleIntUV > 7) {
-         OVERLAY_DEBUG("xscaleUV: bad scale\n");
-         return;
-      }
-
-      newval = (xscaleInt << 16) |
-	    ((xscaleFract & 0xFFF) << 3) | ((yscaleFract & 0xFFF) << 20);
-      if (newval != overlay->YRGBSCALE) {
-	 scaleChanged = TRUE;
-	 overlay->YRGBSCALE = newval;
-      }
-
-      newval = (xscaleIntUV << 16) | ((xscaleFractUV & 0xFFF) << 3) |
-	    ((yscaleFractUV & 0xFFF) << 20);
-      if (newval != overlay->UVSCALE) {
-	 scaleChanged = TRUE;
-	 overlay->UVSCALE = newval;
-      }
-
-      newval = yscaleInt << 16 | yscaleIntUV;
-      if (newval != overlay->UVSCALEV) {
-	 scaleChanged = TRUE;
-	 overlay->UVSCALEV = newval;
-      }
-
-      /* Recalculate coefficients if the scaling changed. */
-
-      /*
-       * Only Horizontal coefficients so far.
-       */
-      if (scaleChanged) {
-	 double fCutoffY;
-	 double fCutoffUV;
-
-	 fCutoffY = xscaleFract / 4096.0;
-	 fCutoffUV = xscaleFractUV / 4096.0;
-
-	 /* Limit to between 1.0 and 3.0. */
-	 if (fCutoffY < MIN_CUTOFF_FREQ)
-	    fCutoffY = MIN_CUTOFF_FREQ;
-	 if (fCutoffY > MAX_CUTOFF_FREQ)
-	    fCutoffY = MAX_CUTOFF_FREQ;
-	 if (fCutoffUV < MIN_CUTOFF_FREQ)
-	    fCutoffUV = MIN_CUTOFF_FREQ;
-	 if (fCutoffUV > MAX_CUTOFF_FREQ)
-	    fCutoffUV = MAX_CUTOFF_FREQ;
-
-	 UpdateCoeff(N_HORIZ_Y_TAPS, fCutoffY, TRUE, TRUE, xcoeffY);
-	 UpdateCoeff(N_HORIZ_UV_TAPS, fCutoffUV, TRUE, FALSE, xcoeffUV);
-
-	 for (i = 0; i < N_PHASES; i++) {
-	    for (j = 0; j < N_HORIZ_Y_TAPS; j++) {
-	       pos = i * N_HORIZ_Y_TAPS + j;
-	       overlay->Y_HCOEFS[pos] = xcoeffY[pos].sign << 15 |
-					xcoeffY[pos].exponent << 12 |
-					xcoeffY[pos].mantissa;
-	    }
-	 }
-	 for (i = 0; i < N_PHASES; i++) {
-	    for (j = 0; j < N_HORIZ_UV_TAPS; j++) {
-	       pos = i * N_HORIZ_UV_TAPS + j;
-	       overlay->UV_HCOEFS[pos] = xcoeffUV[pos].sign << 15 |
-					 xcoeffUV[pos].exponent << 12 |
-					 xcoeffUV[pos].mantissa;
-	    }
-	 }
-      }
-   }
-
-   switch (id) {
-   case FOURCC_YV12:
-   case FOURCC_I420:
-      OVERLAY_DEBUG("YUV420\n");
+    switch (id) {
+    case FOURCC_YV12:
+    case FOURCC_I420:
+	OVERLAY_DEBUG("YUV420\n");
 #if 0
-      /* set UV vertical phase to -0.25 */
-      overlay->UV_VPH = 0x30003000;
+	/* set UV vertical phase to -0.25 */
+	overlay->UV_VPH = 0x30003000;
 #endif
-      OVERLAY_DEBUG("UV stride is %d, Y stride is %d\n",
-		    dstPitch, dstPitch * 2);
-      overlay->OSTRIDE = (dstPitch * 2) | (dstPitch << 16);
-      overlay->OCMD &= ~SOURCE_FORMAT;
-      overlay->OCMD &= ~OV_BYTE_ORDER;
-      overlay->OCMD |= YUV_420;
-      break;
-   case FOURCC_UYVY:
-   case FOURCC_YUY2:
-   default:
-      OVERLAY_DEBUG("YUV422\n");
-      overlay->OSTRIDE = dstPitch;
-      overlay->OCMD &= ~SOURCE_FORMAT;
-      overlay->OCMD |= YUV_422;
-      overlay->OCMD &= ~OV_BYTE_ORDER;
-      if (id == FOURCC_UYVY)
-	 overlay->OCMD |= Y_SWAP;
-      break;
-   }
-
-   overlay->OCMD &= ~(BUFFER_SELECT | FIELD_SELECT);
-   if (pPriv->currentBuf == 0)
-      overlay->OCMD |= BUFFER0;
-   else
-      overlay->OCMD |= BUFFER1;
+	OVERLAY_DEBUG("UV stride is %d, Y stride is %d\n",
+		      dstPitch, dstPitch * 2);
+	overlay->OSTRIDE = (dstPitch * 2) | (dstPitch << 16);
+	overlay->OCMD &= ~SOURCE_FORMAT;
+	overlay->OCMD &= ~OV_BYTE_ORDER;
+	overlay->OCMD |= YUV_420;
+	break;
+    case FOURCC_UYVY:
+    case FOURCC_YUY2:
+    default:
+	OVERLAY_DEBUG("YUV422\n");
+	overlay->OSTRIDE = dstPitch;
+	overlay->OCMD &= ~SOURCE_FORMAT;
+	overlay->OCMD |= YUV_422;
+	overlay->OCMD &= ~OV_BYTE_ORDER;
+	if (id == FOURCC_UYVY)
+	    overlay->OCMD |= Y_SWAP;
+	break;
+    }
+
+    overlay->OCMD &= ~(BUFFER_SELECT | FIELD_SELECT);
+    if (pPriv->currentBuf == 0)
+	overlay->OCMD |= BUFFER0;
+    else
+	overlay->OCMD |= BUFFER1;
 
-   OVERLAY_DEBUG("OCMD is 0x%lx\n", overlay->OCMD);
+    OVERLAY_DEBUG("OCMD is 0x%lx\n", overlay->OCMD);
 
-   i830_overlay_continue (pScrn);
+    i830_overlay_continue (pScrn);
 }
 
 #ifdef I830_USE_EXA
 static void
 I830VideoSave(ScreenPtr pScreen, ExaOffscreenArea *area)
 {
-   struct linear_alloc *linear = area->privData;
+    struct linear_alloc *linear = area->privData;
 
-   linear->exa = NULL;
-   linear->offset = 0;
+    linear->exa = NULL;
+    linear->offset = 0;
 }
 #endif /* I830_USE_EXA */
 
@@ -2137,86 +2124,86 @@ static void
 I830AllocateMemory(ScrnInfoPtr pScrn, struct linear_alloc *linear, int size,
 		   int align)
 {
-   ScreenPtr pScreen = pScrn->pScreen;
-   I830Ptr pI830 = I830PTR(pScrn);
+    ScreenPtr pScreen = pScrn->pScreen;
+    I830Ptr pI830 = I830PTR(pScrn);
 
 #ifdef I830_USE_EXA
-   if (pI830->useEXA) {
-      if (linear->exa != NULL) {
-	 if (linear->exa->size >= size)
+    if (pI830->useEXA) {
+	if (linear->exa != NULL) {
+	    if (linear->exa->size >= size)
+		return;
+
+	    exaOffscreenFree(pScreen, linear->exa);
+	    linear->offset = 0;
+	}
+
+	linear->exa = exaOffscreenAlloc(pScreen, size, align, TRUE,
+					I830VideoSave, linear);
+	if (linear->exa == NULL)
 	    return;
-
-	 exaOffscreenFree(pScreen, linear->exa);
-	 linear->offset = 0;
-      }
-
-      linear->exa = exaOffscreenAlloc(pScreen, size, align, TRUE,
-				      I830VideoSave, linear);
-      if (linear->exa == NULL)
-	 return;
-      linear->offset = linear->exa->offset;
-   }
+	linear->offset = linear->exa->offset;
+    }
 #endif /* I830_USE_EXA */
 #ifdef I830_USE_XAA
-   if (!pI830->useEXA) {
-      /* Converts an offset from XAA's linear allocator to an offset from the
-       * start of fb.
-       */
+    if (!pI830->useEXA) {
+	/* Converts an offset from XAA's linear allocator to an offset from the
+	 * start of fb.
+	 */
 #define XAA_OFFSET_TO_OFFSET(x) \
 	(pI830->front_buffer->offset + (x * pI830->cpp))
 
-      /* The XFree86 linear allocator operates in units of screen pixels,
-       * sadly.
-       */
-      size = (size + pI830->cpp - 1) / pI830->cpp;
-      align = (align + pI830->cpp - 1) / pI830->cpp;
-
-      if (linear->xaa != NULL) {
-	 if (linear->xaa->size >= size) {
-	    linear->offset = XAA_OFFSET_TO_OFFSET(linear->xaa->offset);
-	    return;
-	 }
+	/* The XFree86 linear allocator operates in units of screen pixels,
+	 * sadly.
+	 */
+	size = (size + pI830->cpp - 1) / pI830->cpp;
+	align = (align + pI830->cpp - 1) / pI830->cpp;
+
+	if (linear->xaa != NULL) {
+	    if (linear->xaa->size >= size) {
+		linear->offset = XAA_OFFSET_TO_OFFSET(linear->xaa->offset);
+		return;
+	    }
 
-	 if (xf86ResizeOffscreenLinear(linear->xaa, size)) {
-	    linear->offset = XAA_OFFSET_TO_OFFSET(linear->xaa->offset);
-	    return;
-	 }
+	    if (xf86ResizeOffscreenLinear(linear->xaa, size)) {
+		linear->offset = XAA_OFFSET_TO_OFFSET(linear->xaa->offset);
+		return;
+	    }
 
-	 xf86FreeOffscreenLinear(linear->xaa);
-      }
+	    xf86FreeOffscreenLinear(linear->xaa);
+	}
 
-      linear->xaa = i830_xf86AllocateOffscreenLinear(pScreen, size, align,
-						     NULL, NULL, NULL);
-      if (linear->xaa == NULL)
-	 return;
+	linear->xaa = i830_xf86AllocateOffscreenLinear(pScreen, size, align,
+						       NULL, NULL, NULL);
+	if (linear->xaa == NULL)
+	    return;
 
-      linear->offset = XAA_OFFSET_TO_OFFSET(linear->xaa->offset);
-   }
+	linear->offset = XAA_OFFSET_TO_OFFSET(linear->xaa->offset);
+    }
 #endif /* I830_USE_XAA */
 }
 
 static void
 I830FreeMemory(ScrnInfoPtr pScrn, struct linear_alloc *linear)
 {
-   I830Ptr pI830 = I830PTR(pScrn);
+    I830Ptr pI830 = I830PTR(pScrn);
 
 #ifdef I830_USE_EXA
-   if (pI830->useEXA) {
-      if (linear->exa != NULL) {
-	 exaOffscreenFree(pScrn->pScreen, linear->exa);
-	 linear->exa = NULL;
-      }
-   }
+    if (pI830->useEXA) {
+	if (linear->exa != NULL) {
+	    exaOffscreenFree(pScrn->pScreen, linear->exa);
+	    linear->exa = NULL;
+	}
+    }
 #endif /* I830_USE_EXA */
 #ifdef I830_USE_XAA
-   if (!pI830->useEXA) {
-      if (linear->xaa != NULL) {
-	 xf86FreeOffscreenLinear(linear->xaa);
-	 linear->xaa = NULL;
-      }
-   }
+    if (!pI830->useEXA) {
+	if (linear->xaa != NULL) {
+	    xf86FreeOffscreenLinear(linear->xaa);
+	    linear->xaa = NULL;
+	}
+    }
 #endif /* I830_USE_XAA */
-   linear->offset = 0;
+    linear->offset = 0;
 }
 
 /*
@@ -2243,274 +2230,274 @@ I830PutImage(ScrnInfoPtr pScrn,
 	     Bool sync, RegionPtr clipBoxes, pointer data,
 	     DrawablePtr pDraw)
 {
-   I830Ptr pI830 = I830PTR(pScrn);
-   I830PortPrivPtr pPriv = (I830PortPrivPtr) data;
-   ScreenPtr pScreen = screenInfo.screens[pScrn->scrnIndex];
-   I830OverlayRegPtr overlay;
-   PixmapPtr pPixmap;
-   INT32 x1, x2, y1, y2;
-   int srcPitch, srcPitch2 = 0, dstPitch, destId;
-   int top, left, npixels, nlines, size, loops;
-   BoxRec dstBox;
-   int pitchAlignMask;
-   int extraLinear;
-
-   if (pPriv->textured)
-       overlay = NULL;
-   else
-       overlay = (I830OverlayRegPtr) (pI830->FbBase + 
-	       pI830->overlay_regs->offset);
+    I830Ptr pI830 = I830PTR(pScrn);
+    I830PortPrivPtr pPriv = (I830PortPrivPtr) data;
+    ScreenPtr pScreen = screenInfo.screens[pScrn->scrnIndex];
+    I830OverlayRegPtr overlay;
+    PixmapPtr pPixmap;
+    INT32 x1, x2, y1, y2;
+    int srcPitch, srcPitch2 = 0, dstPitch, destId;
+    int top, left, npixels, nlines, size, loops;
+    BoxRec dstBox;
+    int pitchAlignMask;
+    int extraLinear;
+
+    if (pPriv->textured)
+	overlay = NULL;
+    else
+	overlay = (I830OverlayRegPtr) (pI830->FbBase + 
+				       pI830->overlay_regs->offset);
 
 #if 0
-   ErrorF("I830PutImage: src: (%d,%d)(%d,%d), dst: (%d,%d)(%d,%d)\n"
+    ErrorF("I830PutImage: src: (%d,%d)(%d,%d), dst: (%d,%d)(%d,%d)\n"
 	   "width %d, height %d\n", src_x, src_y, src_w, src_h, drw_x, drw_y,
 	   drw_w, drw_h, width, height);
 #endif
 
-   if (pI830->entityPrivate) {
-	 if (pI830->entityPrivate->XvInUse != -1 &&
-	     pI830->entityPrivate->XvInUse != I830CrtcPipe (pPriv->current_crtc)) {
+    if (pI830->entityPrivate) {
+	if (pI830->entityPrivate->XvInUse != -1 &&
+	    pI830->entityPrivate->XvInUse != I830CrtcPipe (pPriv->current_crtc)) {
 #ifdef PANORAMIX
-		if (!noPanoramiXExtension) {
-			return Success; /* faked for trying to share it */
-		} else
+	    if (!noPanoramiXExtension) {
+		return Success; /* faked for trying to share it */
+	    } else
 #endif
-		{
-			return BadAlloc;
-		}
-	 }
+	    {
+		return BadAlloc;
+	    }
+	}
 
-      pI830->entityPrivate->XvInUse = I830CrtcPipe (pPriv->current_crtc);;
-   }
+	pI830->entityPrivate->XvInUse = I830CrtcPipe (pPriv->current_crtc);;
+    }
 
-   /* overlay limits */
-   if(src_w > (drw_w * 7))
-      drw_w = src_w * 7;
-
-   if(src_h > (drw_h * 7))
-      drw_h = src_h * 7;
-
-   /* Clip */
-   x1 = src_x;
-   x2 = src_x + src_w;
-   y1 = src_y;
-   y2 = src_y + src_h;
-
-   dstBox.x1 = drw_x;
-   dstBox.x2 = drw_x + drw_w;
-   dstBox.y1 = drw_y;
-   dstBox.y2 = drw_y + drw_h;
-
-   if (!xf86XVClipVideoHelper(&dstBox, &x1, &x2, &y1, &y2, clipBoxes,
-			      width, height))
-      return Success;
-
-   destId = id;
-   switch (id) {
-   case FOURCC_YV12:
-   case FOURCC_I420:
-      srcPitch = (width + 3) & ~3;
-      srcPitch2 = ((width >> 1) + 3) & ~3;
-      if (pPriv->textured) {
-	 destId = FOURCC_YUY2;
-      }
-      break;
-   case FOURCC_UYVY:
-   case FOURCC_YUY2:
-   default:
-      srcPitch = width << 1;
-      break;
-   }
-
-   /* Only needs to be DWORD-aligned for textured on i915, but overlay has
-    * stricter requirements.
-    */
-   if (pPriv->textured) {
-      pitchAlignMask = 3;
-   } else {
-      if (IS_I965G(pI830))
-	 pitchAlignMask = 255;
-      else
-	 pitchAlignMask = 63;
-   }
-
-   /* Determine the desired destination pitch (representing the chroma's pitch,
-    * in the planar case.
-    */
-   switch (destId) {
-   case FOURCC_YV12:
-   case FOURCC_I420:
-      if (pI830->rotation & (RR_Rotate_90 | RR_Rotate_270)) {
-         dstPitch = ((height / 2) + pitchAlignMask) & ~pitchAlignMask;
-         size = dstPitch * width * 3;
-      } else {
-         dstPitch = ((width / 2) + pitchAlignMask) & ~pitchAlignMask;
-         size = dstPitch * height * 3;
-      }
-      break;
-   case FOURCC_UYVY:
-   case FOURCC_YUY2:
-   default:
-      if (pI830->rotation & (RR_Rotate_90 | RR_Rotate_270)) {
-         dstPitch = ((height << 1) + pitchAlignMask) & ~pitchAlignMask;
-         size = dstPitch * width;
-      } else {
-         dstPitch = ((width << 1) + pitchAlignMask) & ~pitchAlignMask;
-         size = dstPitch * height;
-      }
-      break;
-   }
+    /* overlay limits */
+    if(src_w > (drw_w * 7))
+	drw_w = src_w * 7;
+
+    if(src_h > (drw_h * 7))
+	drw_h = src_h * 7;
+
+    /* Clip */
+    x1 = src_x;
+    x2 = src_x + src_w;
+    y1 = src_y;
+    y2 = src_y + src_h;
+
+    dstBox.x1 = drw_x;
+    dstBox.x2 = drw_x + drw_w;
+    dstBox.y1 = drw_y;
+    dstBox.y2 = drw_y + drw_h;
+
+    if (!xf86XVClipVideoHelper(&dstBox, &x1, &x2, &y1, &y2, clipBoxes,
+			       width, height))
+	return Success;
+
+    destId = id;
+    switch (id) {
+    case FOURCC_YV12:
+    case FOURCC_I420:
+	srcPitch = (width + 3) & ~3;
+	srcPitch2 = ((width >> 1) + 3) & ~3;
+	if (pPriv->textured) {
+	    destId = FOURCC_YUY2;
+	}
+	break;
+    case FOURCC_UYVY:
+    case FOURCC_YUY2:
+    default:
+	srcPitch = width << 1;
+	break;
+    }
+
+    /* Only needs to be DWORD-aligned for textured on i915, but overlay has
+     * stricter requirements.
+     */
+    if (pPriv->textured) {
+	pitchAlignMask = 3;
+    } else {
+	if (IS_I965G(pI830))
+	    pitchAlignMask = 255;
+	else
+	    pitchAlignMask = 63;
+    }
+
+    /* Determine the desired destination pitch (representing the chroma's pitch,
+     * in the planar case.
+     */
+    switch (destId) {
+    case FOURCC_YV12:
+    case FOURCC_I420:
+	if (pI830->rotation & (RR_Rotate_90 | RR_Rotate_270)) {
+	    dstPitch = ((height / 2) + pitchAlignMask) & ~pitchAlignMask;
+	    size = dstPitch * width * 3;
+	} else {
+	    dstPitch = ((width / 2) + pitchAlignMask) & ~pitchAlignMask;
+	    size = dstPitch * height * 3;
+	}
+	break;
+    case FOURCC_UYVY:
+    case FOURCC_YUY2:
+    default:
+	if (pI830->rotation & (RR_Rotate_90 | RR_Rotate_270)) {
+	    dstPitch = ((height << 1) + pitchAlignMask) & ~pitchAlignMask;
+	    size = dstPitch * width;
+	} else {
+	    dstPitch = ((width << 1) + pitchAlignMask) & ~pitchAlignMask;
+	    size = dstPitch * height;
+	}
+	break;
+    }
 #if 0
-   ErrorF("srcPitch: %d, dstPitch: %d, size: %d\n", srcPitch, dstPitch, size);
+    ErrorF("srcPitch: %d, dstPitch: %d, size: %d\n", srcPitch, dstPitch, size);
 #endif
 
-   if (IS_I965G(pI830))
-      extraLinear = BRW_LINEAR_EXTRA;
-   else
-      extraLinear = 0;
-
-   /* size is multiplied by 2 because we have two buffers that are flipping */
-   I830AllocateMemory(pScrn, &pPriv->linear,
-		      extraLinear + (pPriv->doubleBuffer ? size * 2 : size),
-		      16);
-
-   if (pPriv->linear.offset == 0)
-      return BadAlloc;
-
-   pPriv->extra_offset = pPriv->linear.offset +
-      (pPriv->doubleBuffer ? size * 2 : size);
-
-   /* fixup pointers */
-   pPriv->YBuf0offset = pPriv->linear.offset;
-   if (pI830->rotation & (RR_Rotate_90 | RR_Rotate_270)) {
-      pPriv->UBuf0offset = pPriv->YBuf0offset + (dstPitch * 2 * width);
-      pPriv->VBuf0offset = pPriv->UBuf0offset + (dstPitch * width / 2);
-      if(pPriv->doubleBuffer) {
-         pPriv->YBuf1offset = pPriv->YBuf0offset + size;
-         pPriv->UBuf1offset = pPriv->YBuf1offset + (dstPitch * 2 * width);
-         pPriv->VBuf1offset = pPriv->UBuf1offset + (dstPitch * width / 2);
-      }
-   } else {
-      pPriv->UBuf0offset = pPriv->YBuf0offset + (dstPitch * 2 * height);
-      pPriv->VBuf0offset = pPriv->UBuf0offset + (dstPitch * height / 2);
-      if(pPriv->doubleBuffer) {
-         pPriv->YBuf1offset = pPriv->YBuf0offset + size;
-         pPriv->UBuf1offset = pPriv->YBuf1offset + (dstPitch * 2 * height);
-         pPriv->VBuf1offset = pPriv->UBuf1offset + (dstPitch * height / 2);
-      }
-   }
-
-   /* Make sure this buffer isn't in use */
-   loops = 0;
-   if (!pPriv->textured && *pI830->overlayOn && pPriv->doubleBuffer &&
-       (overlay->OCMD & OVERLAY_ENABLE))
-   {
-      while (loops < 1000000) {
+    if (IS_I965G(pI830))
+	extraLinear = BRW_LINEAR_EXTRA;
+    else
+	extraLinear = 0;
+
+    /* size is multiplied by 2 because we have two buffers that are flipping */
+    I830AllocateMemory(pScrn, &pPriv->linear,
+		       extraLinear + (pPriv->doubleBuffer ? size * 2 : size),
+		       16);
+
+    if (pPriv->linear.offset == 0)
+	return BadAlloc;
+
+    pPriv->extra_offset = pPriv->linear.offset +
+    (pPriv->doubleBuffer ? size * 2 : size);
+
+    /* fixup pointers */
+    pPriv->YBuf0offset = pPriv->linear.offset;
+    if (pI830->rotation & (RR_Rotate_90 | RR_Rotate_270)) {
+	pPriv->UBuf0offset = pPriv->YBuf0offset + (dstPitch * 2 * width);
+	pPriv->VBuf0offset = pPriv->UBuf0offset + (dstPitch * width / 2);
+	if(pPriv->doubleBuffer) {
+	    pPriv->YBuf1offset = pPriv->YBuf0offset + size;
+	    pPriv->UBuf1offset = pPriv->YBuf1offset + (dstPitch * 2 * width);
+	    pPriv->VBuf1offset = pPriv->UBuf1offset + (dstPitch * width / 2);
+	}
+    } else {
+	pPriv->UBuf0offset = pPriv->YBuf0offset + (dstPitch * 2 * height);
+	pPriv->VBuf0offset = pPriv->UBuf0offset + (dstPitch * height / 2);
+	if(pPriv->doubleBuffer) {
+	    pPriv->YBuf1offset = pPriv->YBuf0offset + size;
+	    pPriv->UBuf1offset = pPriv->YBuf1offset + (dstPitch * 2 * height);
+	    pPriv->VBuf1offset = pPriv->UBuf1offset + (dstPitch * height / 2);
+	}
+    }
+
+    /* Make sure this buffer isn't in use */
+    loops = 0;
+    if (!pPriv->textured && *pI830->overlayOn && pPriv->doubleBuffer &&
+	(overlay->OCMD & OVERLAY_ENABLE))
+    {
+	while (loops < 1000000) {
 #if USE_USLEEP_FOR_VIDEO
-         usleep(10);
+	    usleep(10);
 #endif
-         if (((INREG(DOVSTA) & OC_BUF) >> 20) == pPriv->currentBuf) {
-	    break;
-         }
-         loops++;
-      }
-      if (loops >= 1000000) {
-         ErrorF("loops (1) maxed out for buffer %d\n", pPriv->currentBuf);
+	    if (((INREG(DOVSTA) & OC_BUF) >> 20) == pPriv->currentBuf) {
+		break;
+	    }
+	    loops++;
+	}
+	if (loops >= 1000000) {
+	    ErrorF("loops (1) maxed out for buffer %d\n", pPriv->currentBuf);
 #if 0
-         pPriv->currentBuf = !pPriv->currentBuf;
+	    pPriv->currentBuf = !pPriv->currentBuf;
 #endif
-      }
+	}
 
-      /* buffer swap */
-      if (pPriv->currentBuf == 0)
-         pPriv->currentBuf = 1;
-      else
-         pPriv->currentBuf = 0;
-   }
-
-   /* copy data */
-   top = y1 >> 16;
-   left = (x1 >> 16) & ~1;
-   npixels = ((((x2 + 0xffff) >> 16) + 1) & ~1) - left;
-
-   if (pPriv->textured) {
-      /* For textured video, we don't double buffer, and instead just wait for
-       * acceleration to finish before writing the new video data into
-       * framebuffer.
-       */
-      i830WaitSync(pScrn);
-   }
-
-   switch (id) {
-   case FOURCC_YV12:
-   case FOURCC_I420:
-      top &= ~1;
-      nlines = ((((y2 + 0xffff) >> 16) + 1) & ~1) - top;
-      if (pPriv->textured) {
-	 I830CopyPlanarToPackedData(pScrn, pPriv, buf, srcPitch, srcPitch2,
-				    dstPitch, height, top, left, nlines,
-				    npixels, id);
-      } else {
-	 I830CopyPlanarData(pScrn, pPriv, buf, srcPitch, srcPitch2, dstPitch,
-			    height, top, left, nlines, npixels, id);
-      }
-      break;
-   case FOURCC_UYVY:
-   case FOURCC_YUY2:
-   default:
-      nlines = ((y2 + 0xffff) >> 16) - top;
-      I830CopyPackedData(pScrn, pPriv, buf, srcPitch, dstPitch, top, left,
-			 nlines, npixels);
-      break;
-   }
-
-   if (pDraw->type == DRAWABLE_WINDOW) {
-      pPixmap = (*pScreen->GetWindowPixmap)((WindowPtr)pDraw);
-   } else {
-      pPixmap = (PixmapPtr)pDraw;
-   }
+	/* buffer swap */
+	if (pPriv->currentBuf == 0)
+	    pPriv->currentBuf = 1;
+	else
+	    pPriv->currentBuf = 0;
+    }
+
+    /* copy data */
+    top = y1 >> 16;
+    left = (x1 >> 16) & ~1;
+    npixels = ((((x2 + 0xffff) >> 16) + 1) & ~1) - left;
+
+    if (pPriv->textured) {
+	/* For textured video, we don't double buffer, and instead just wait for
+	 * acceleration to finish before writing the new video data into
+	 * framebuffer.
+	 */
+	i830WaitSync(pScrn);
+    }
+
+    switch (id) {
+    case FOURCC_YV12:
+    case FOURCC_I420:
+	top &= ~1;
+	nlines = ((((y2 + 0xffff) >> 16) + 1) & ~1) - top;
+	if (pPriv->textured) {
+	    I830CopyPlanarToPackedData(pScrn, pPriv, buf, srcPitch, srcPitch2,
+				       dstPitch, height, top, left, nlines,
+				       npixels, id);
+	} else {
+	    I830CopyPlanarData(pScrn, pPriv, buf, srcPitch, srcPitch2, dstPitch,
+			       height, top, left, nlines, npixels, id);
+	}
+	break;
+    case FOURCC_UYVY:
+    case FOURCC_YUY2:
+    default:
+	nlines = ((y2 + 0xffff) >> 16) - top;
+	I830CopyPackedData(pScrn, pPriv, buf, srcPitch, dstPitch, top, left,
+			   nlines, npixels);
+	break;
+    }
+
+    if (pDraw->type == DRAWABLE_WINDOW) {
+	pPixmap = (*pScreen->GetWindowPixmap)((WindowPtr)pDraw);
+    } else {
+	pPixmap = (PixmapPtr)pDraw;
+    }
 
 #ifdef I830_USE_EXA
-   if (pI830->useEXA) {
-       /* Force the pixmap into framebuffer so we can draw to it. */
-       exaMoveInPixmap(pPixmap);
-   }
-#endif
-
-   if (((char *)pPixmap->devPrivate.ptr < (char *)pI830->FbBase) ||
-       ((char *)pPixmap->devPrivate.ptr >= (char *)pI830->FbBase +
-	pI830->FbMapSize)) {
-      /* If the pixmap wasn't in framebuffer, then we have no way in XAA to
-       * force it there.  So, we simply refuse to draw and fail.
-       */
-      return BadAlloc;
-   }
-
-   if (!pPriv->textured) {
-      /* update cliplist */
-      if (!RegionsEqual(&pPriv->clip, clipBoxes)) {
- 	REGION_COPY(pScrn->pScreen, &pPriv->clip, clipBoxes);
-	 xf86XVFillKeyHelper(pScreen, pPriv->colorKey, clipBoxes);
-      }
-
-      I830DisplayVideo(pScrn, destId, width, height, dstPitch,
-		       x1, y1, x2, y2, &dstBox, src_w, src_h, drw_w, drw_h);
-   } else if (IS_I965G(pI830)) {
-      I965DisplayVideoTextured(pScrn, pPriv, destId, clipBoxes, width, height,
-			       dstPitch, x1, y1, x2, y2,
-			       src_w, src_h, drw_w, drw_h, pPixmap);
-   } else {
-      I915DisplayVideoTextured(pScrn, pPriv, destId, clipBoxes, width, height,
-			       dstPitch, x1, y1, x2, y2,
-			       src_w, src_h, drw_w, drw_h, pPixmap);
-   }
-   if (pPriv->textured) {
-      DamageDamageRegion(pDraw, clipBoxes);
-   }
+    if (pI830->useEXA) {
+	/* Force the pixmap into framebuffer so we can draw to it. */
+	exaMoveInPixmap(pPixmap);
+    }
+#endif
+
+    if (((char *)pPixmap->devPrivate.ptr < (char *)pI830->FbBase) ||
+	((char *)pPixmap->devPrivate.ptr >= (char *)pI830->FbBase +
+	 pI830->FbMapSize)) {
+	/* If the pixmap wasn't in framebuffer, then we have no way in XAA to
+	 * force it there.  So, we simply refuse to draw and fail.
+	 */
+	return BadAlloc;
+    }
+
+    if (!pPriv->textured) {
+	/* update cliplist */
+	if (!RegionsEqual(&pPriv->clip, clipBoxes)) {
+	    REGION_COPY(pScrn->pScreen, &pPriv->clip, clipBoxes);
+	    xf86XVFillKeyHelper(pScreen, pPriv->colorKey, clipBoxes);
+	}
+
+	I830DisplayVideo(pScrn, destId, width, height, dstPitch,
+			 x1, y1, x2, y2, &dstBox, src_w, src_h, drw_w, drw_h);
+    } else if (IS_I965G(pI830)) {
+	I965DisplayVideoTextured(pScrn, pPriv, destId, clipBoxes, width, height,
+				 dstPitch, x1, y1, x2, y2,
+				 src_w, src_h, drw_w, drw_h, pPixmap);
+    } else {
+	I915DisplayVideoTextured(pScrn, pPriv, destId, clipBoxes, width, height,
+				 dstPitch, x1, y1, x2, y2,
+				 src_w, src_h, drw_w, drw_h, pPixmap);
+    }
+    if (pPriv->textured) {
+	DamageDamageRegion(pDraw, clipBoxes);
+    }
 
-   pPriv->videoStatus = CLIENT_VIDEO_ON;
+    pPriv->videoStatus = CLIENT_VIDEO_ON;
 
-   return Success;
+    return Success;
 }
 
 static int
@@ -2519,75 +2506,75 @@ I830QueryImageAttributes(ScrnInfoPtr pSc
 			 unsigned short *w, unsigned short *h,
 			 int *pitches, int *offsets, Bool textured)
 {
-   I830Ptr pI830 = I830PTR(pScrn);
-   int size, tmp;
+    I830Ptr pI830 = I830PTR(pScrn);
+    int size, tmp;
 
 #if 0
-   ErrorF("I830QueryImageAttributes: w is %d, h is %d\n", *w, *h);
+    ErrorF("I830QueryImageAttributes: w is %d, h is %d\n", *w, *h);
 #endif
 
-   if (IS_845G(pI830) || IS_I830(pI830)) {
-      if (*w > IMAGE_MAX_WIDTH_LEGACY)
-	 *w = IMAGE_MAX_WIDTH_LEGACY;
-      if (*h > IMAGE_MAX_HEIGHT_LEGACY)
-	 *h = IMAGE_MAX_HEIGHT_LEGACY;
-   } else {
-      if (*w > IMAGE_MAX_WIDTH)
-	 *w = IMAGE_MAX_WIDTH;
-      if (*h > IMAGE_MAX_HEIGHT)
-	 *h = IMAGE_MAX_HEIGHT;
-   }
-
-   *w = (*w + 1) & ~1;
-   if (offsets)
-      offsets[0] = 0;
-
-   switch (id) {
-      /* IA44 is for XvMC only */
-   case FOURCC_IA44:
-   case FOURCC_AI44:
-      if (pitches)
-	 pitches[0] = *w;
-      size = *w * *h;
-      break;
-   case FOURCC_YV12:
-   case FOURCC_I420:
-      *h = (*h + 1) & ~1;
-      size = (*w + 3) & ~3;
-      if (pitches)
-	 pitches[0] = size;
-      size *= *h;
-      if (offsets)
-	 offsets[1] = size;
-      tmp = ((*w >> 1) + 3) & ~3;
-      if (pitches)
-	 pitches[1] = pitches[2] = tmp;
-      tmp *= (*h >> 1);
-      size += tmp;
-      if (offsets)
-	 offsets[2] = size;
-      size += tmp;
+    if (IS_845G(pI830) || IS_I830(pI830)) {
+	if (*w > IMAGE_MAX_WIDTH_LEGACY)
+	    *w = IMAGE_MAX_WIDTH_LEGACY;
+	if (*h > IMAGE_MAX_HEIGHT_LEGACY)
+	    *h = IMAGE_MAX_HEIGHT_LEGACY;
+    } else {
+	if (*w > IMAGE_MAX_WIDTH)
+	    *w = IMAGE_MAX_WIDTH;
+	if (*h > IMAGE_MAX_HEIGHT)
+	    *h = IMAGE_MAX_HEIGHT;
+    }
+
+    *w = (*w + 1) & ~1;
+    if (offsets)
+	offsets[0] = 0;
+
+    switch (id) {
+	/* IA44 is for XvMC only */
+    case FOURCC_IA44:
+    case FOURCC_AI44:
+	if (pitches)
+	    pitches[0] = *w;
+	size = *w * *h;
+	break;
+    case FOURCC_YV12:
+    case FOURCC_I420:
+	*h = (*h + 1) & ~1;
+	size = (*w + 3) & ~3;
+	if (pitches)
+	    pitches[0] = size;
+	size *= *h;
+	if (offsets)
+	    offsets[1] = size;
+	tmp = ((*w >> 1) + 3) & ~3;
+	if (pitches)
+	    pitches[1] = pitches[2] = tmp;
+	tmp *= (*h >> 1);
+	size += tmp;
+	if (offsets)
+	    offsets[2] = size;
+	size += tmp;
 #if 0
-      if (pitches)
-	 ErrorF("pitch 0 is %d, pitch 1 is %d, pitch 2 is %d\n", pitches[0],
-		pitches[1], pitches[2]);
-      if (offsets)
-	 ErrorF("offset 1 is %d, offset 2 is %d\n", offsets[1], offsets[2]);
-      if (offsets)
-	 ErrorF("size is %d\n", size);
-#endif
-      break;
-   case FOURCC_UYVY:
-   case FOURCC_YUY2:
-   default:
-      size = *w << 1;
-      if (pitches)
-	 pitches[0] = size;
-      size *= *h;
-      break;
-   }
+	if (pitches)
+	    ErrorF("pitch 0 is %d, pitch 1 is %d, pitch 2 is %d\n", pitches[0],
+		   pitches[1], pitches[2]);
+	if (offsets)
+	    ErrorF("offset 1 is %d, offset 2 is %d\n", offsets[1], offsets[2]);
+	if (offsets)
+	    ErrorF("size is %d\n", size);
+#endif
+	break;
+    case FOURCC_UYVY:
+    case FOURCC_YUY2:
+    default:
+	size = *w << 1;
+	if (pitches)
+	    pitches[0] = size;
+	size *= *h;
+	break;
+    }
 
-   return size;
+    return size;
 }
 
 static int
@@ -2596,7 +2583,7 @@ I830QueryImageAttributesOverlay(ScrnInfo
 				unsigned short *w, unsigned short *h,
 				int *pitches, int *offsets)
 {
-   return I830QueryImageAttributes(pScrn, id, w, h, pitches, offsets, FALSE);
+    return I830QueryImageAttributes(pScrn, id, w, h, pitches, offsets, FALSE);
 }
 
 static int
@@ -2605,50 +2592,50 @@ I830QueryImageAttributesTextured(ScrnInf
 				 unsigned short *w, unsigned short *h,
 				 int *pitches, int *offsets)
 {
-   return I830QueryImageAttributes(pScrn, id, w, h, pitches, offsets, TRUE);
+    return I830QueryImageAttributes(pScrn, id, w, h, pitches, offsets, TRUE);
 }
 
 static void
 I830BlockHandler(int i,
 		 pointer blockData, pointer pTimeout, pointer pReadmask)
 {
-   ScreenPtr pScreen = screenInfo.screens[i];
-   ScrnInfoPtr pScrn = xf86Screens[i];
-   I830Ptr pI830 = I830PTR(pScrn);
-   I830PortPrivPtr pPriv = GET_PORT_PRIVATE(pScrn);
+    ScreenPtr pScreen = screenInfo.screens[i];
+    ScrnInfoPtr pScrn = xf86Screens[i];
+    I830Ptr pI830 = I830PTR(pScrn);
+    I830PortPrivPtr pPriv = GET_PORT_PRIVATE(pScrn);
 
-   pScreen->BlockHandler = pI830->BlockHandler;
+    pScreen->BlockHandler = pI830->BlockHandler;
 
-   (*pScreen->BlockHandler) (i, blockData, pTimeout, pReadmask);
+    (*pScreen->BlockHandler) (i, blockData, pTimeout, pReadmask);
 
-   pScreen->BlockHandler = I830BlockHandler;
+    pScreen->BlockHandler = I830BlockHandler;
 
-   if (pPriv->videoStatus & TIMER_MASK) {
+    if (pPriv->videoStatus & TIMER_MASK) {
 #if 1
-      Time now = currentTime.milliseconds;
+	Time now = currentTime.milliseconds;
 #else
-      UpdateCurrentTime();
+	UpdateCurrentTime();
 #endif
-      if (pPriv->videoStatus & OFF_TIMER) {
-	 if (pPriv->offTime < now) {
-	    /* Turn off the overlay */
-	    OVERLAY_DEBUG("BLOCKHANDLER\n");
-
-	    i830_overlay_off (pScrn);
-
-	    pPriv->videoStatus = FREE_TIMER;
-	    pPriv->freeTime = now + FREE_DELAY;
-       
-            if (pI830->entityPrivate)
-               pI830->entityPrivate->XvInUse = -1;
-	 }
-      } else {				/* FREE_TIMER */
-	 if (pPriv->freeTime < now) {
-	    I830FreeMemory(pScrn, &pPriv->linear);
-	    pPriv->videoStatus = 0;
-	 }
-      }
-   }
+	if (pPriv->videoStatus & OFF_TIMER) {
+	    if (pPriv->offTime < now) {
+		/* Turn off the overlay */
+		OVERLAY_DEBUG("BLOCKHANDLER\n");
+
+		i830_overlay_off (pScrn);
+
+		pPriv->videoStatus = FREE_TIMER;
+		pPriv->freeTime = now + FREE_DELAY;
+
+		if (pI830->entityPrivate)
+		    pI830->entityPrivate->XvInUse = -1;
+	    }
+	} else {				/* FREE_TIMER */
+	    if (pPriv->freeTime < now) {
+		I830FreeMemory(pScrn, &pPriv->linear);
+		pPriv->videoStatus = 0;
+	    }
+	}
+    }
 }
 
 /***************************************************************************
@@ -2656,8 +2643,8 @@ I830BlockHandler(int i,
  ***************************************************************************/
 
 typedef struct {
-   struct linear_alloc linear;
-   Bool isOn;
+    struct linear_alloc linear;
+    Bool isOn;
 } OffscreenPrivRec, *OffscreenPrivPtr;
 
 static int
@@ -2666,111 +2653,111 @@ I830AllocateSurface(ScrnInfoPtr pScrn,
 		    unsigned short w,
 		    unsigned short h, XF86SurfacePtr surface)
 {
-   int pitch, fbpitch, size;
-   OffscreenPrivPtr pPriv;
-   I830Ptr pI830 = I830PTR(pScrn);
-
-   OVERLAY_DEBUG("I830AllocateSurface\n");
-
-   if (IS_845G(pI830) || IS_I830(pI830)) {
-      if ((w > IMAGE_MAX_WIDTH_LEGACY) || (h > IMAGE_MAX_HEIGHT_LEGACY))
-         return BadAlloc;
-   } else {
-      if ((w > IMAGE_MAX_WIDTH) || (h > IMAGE_MAX_HEIGHT))
-         return BadAlloc;
-   }
-
-   /* What to do when rotated ?? */
-   if (pI830->rotation != RR_Rotate_0)
-      return BadAlloc;
-
-   if (!(surface->pitches = xalloc(sizeof(int))))
-      return BadAlloc;
-   if (!(surface->offsets = xalloc(sizeof(int)))) {
-      xfree(surface->pitches);
-      return BadAlloc;
-   }
-   if (!(pPriv = xalloc(sizeof(OffscreenPrivRec)))) {
-      xfree(surface->pitches);
-      xfree(surface->offsets);
-      return BadAlloc;
-   }
-
-   w = (w + 1) & ~1;
-   pitch = ((w << 1) + 15) & ~15;
-   fbpitch = pI830->cpp * pScrn->displayWidth;
-   size = pitch * h;
-
-   I830AllocateMemory(pScrn, &pPriv->linear, size, 16);
-   if (pPriv->linear.offset == 0) {
-      xfree(surface->pitches);
-      xfree(surface->offsets);
-      xfree(pPriv);
-      return BadAlloc;
-   }
-
-   surface->width = w;
-   surface->height = h;
-
-   pPriv->isOn = FALSE;
-
-   surface->pScrn = pScrn;
-   surface->id = id;
-   surface->pitches[0] = pitch;
-   surface->offsets[0] = pPriv->linear.offset;
-   surface->devPrivate.ptr = (pointer) pPriv;
+    int pitch, fbpitch, size;
+    OffscreenPrivPtr pPriv;
+    I830Ptr pI830 = I830PTR(pScrn);
+
+    OVERLAY_DEBUG("I830AllocateSurface\n");
+
+    if (IS_845G(pI830) || IS_I830(pI830)) {
+	if ((w > IMAGE_MAX_WIDTH_LEGACY) || (h > IMAGE_MAX_HEIGHT_LEGACY))
+	    return BadAlloc;
+    } else {
+	if ((w > IMAGE_MAX_WIDTH) || (h > IMAGE_MAX_HEIGHT))
+	    return BadAlloc;
+    }
+
+    /* What to do when rotated ?? */
+    if (pI830->rotation != RR_Rotate_0)
+	return BadAlloc;
+
+    if (!(surface->pitches = xalloc(sizeof(int))))
+	return BadAlloc;
+    if (!(surface->offsets = xalloc(sizeof(int)))) {
+	xfree(surface->pitches);
+	return BadAlloc;
+    }
+    if (!(pPriv = xalloc(sizeof(OffscreenPrivRec)))) {
+	xfree(surface->pitches);
+	xfree(surface->offsets);
+	return BadAlloc;
+    }
+
+    w = (w + 1) & ~1;
+    pitch = ((w << 1) + 15) & ~15;
+    fbpitch = pI830->cpp * pScrn->displayWidth;
+    size = pitch * h;
+
+    I830AllocateMemory(pScrn, &pPriv->linear, size, 16);
+    if (pPriv->linear.offset == 0) {
+	xfree(surface->pitches);
+	xfree(surface->offsets);
+	xfree(pPriv);
+	return BadAlloc;
+    }
+
+    surface->width = w;
+    surface->height = h;
+
+    pPriv->isOn = FALSE;
+
+    surface->pScrn = pScrn;
+    surface->id = id;
+    surface->pitches[0] = pitch;
+    surface->offsets[0] = pPriv->linear.offset;
+    surface->devPrivate.ptr = (pointer) pPriv;
 
-   memset(pI830->FbBase + surface->offsets[0], 0, size);
+    memset(pI830->FbBase + surface->offsets[0], 0, size);
 
-   return Success;
+    return Success;
 }
 
 static int
 I830StopSurface(XF86SurfacePtr surface)
 {
-   OffscreenPrivPtr pPriv = (OffscreenPrivPtr) surface->devPrivate.ptr;
-   ScrnInfoPtr pScrn = surface->pScrn;
+    OffscreenPrivPtr pPriv = (OffscreenPrivPtr) surface->devPrivate.ptr;
+    ScrnInfoPtr pScrn = surface->pScrn;
 
-   if (pPriv->isOn) {
-      I830Ptr pI830 = I830PTR(pScrn);
+    if (pPriv->isOn) {
+	I830Ptr pI830 = I830PTR(pScrn);
 
-      OVERLAY_DEBUG("StopSurface\n");
+	OVERLAY_DEBUG("StopSurface\n");
 
-      i830_overlay_off (pScrn);
+	i830_overlay_off (pScrn);
 
-      if (pI830->entityPrivate)
-         pI830->entityPrivate->XvInUse = -1;
+	if (pI830->entityPrivate)
+	    pI830->entityPrivate->XvInUse = -1;
 
-      pPriv->isOn = FALSE;
-   }
+	pPriv->isOn = FALSE;
+    }
 
-   return Success;
+    return Success;
 }
 
 static int
 I830FreeSurface(XF86SurfacePtr surface)
 {
-   OffscreenPrivPtr pPriv = (OffscreenPrivPtr) surface->devPrivate.ptr;
+    OffscreenPrivPtr pPriv = (OffscreenPrivPtr) surface->devPrivate.ptr;
 
-   I830StopSurface(surface);
-   I830FreeMemory(surface->pScrn, &pPriv->linear);
-   xfree(surface->pitches);
-   xfree(surface->offsets);
-   xfree(surface->devPrivate.ptr);
+    I830StopSurface(surface);
+    I830FreeMemory(surface->pScrn, &pPriv->linear);
+    xfree(surface->pitches);
+    xfree(surface->offsets);
+    xfree(surface->devPrivate.ptr);
 
-   return Success;
+    return Success;
 }
 
 static int
 I830GetSurfaceAttribute(ScrnInfoPtr pScrn, Atom attribute, INT32 * value)
 {
-   return I830GetPortAttribute(pScrn, attribute, value, NULL);
+    return I830GetPortAttribute(pScrn, attribute, value, NULL);
 }
 
 static int
 I830SetSurfaceAttribute(ScrnInfoPtr pScrn, Atom attribute, INT32 value)
 {
-   return I830SetPortAttribute(pScrn, attribute, value, NULL);
+    return I830SetPortAttribute(pScrn, attribute, value, NULL);
 }
 
 static int
@@ -2780,198 +2767,198 @@ I830DisplaySurface(XF86SurfacePtr surfac
 		   short src_w, short src_h,
 		   short drw_w, short drw_h, RegionPtr clipBoxes)
 {
-   OffscreenPrivPtr pPriv = (OffscreenPrivPtr) surface->devPrivate.ptr;
-   ScrnInfoPtr pScrn = surface->pScrn;
-   ScreenPtr pScreen = screenInfo.screens[pScrn->scrnIndex];
-   I830Ptr pI830 = I830PTR(pScrn);
-   I830PortPrivPtr pI830Priv = GET_PORT_PRIVATE(pScrn);
-   INT32 x1, y1, x2, y2;
-   INT32 loops = 0;
-   BoxRec dstBox;
-
-   OVERLAY_DEBUG("I830DisplaySurface\n");
-
-   if (pI830->entityPrivate) {
-	 if (pI830->entityPrivate->XvInUse != -1 &&
-	     pI830->entityPrivate->XvInUse != I830CrtcPipe (pI830Priv->current_crtc)) {
+    OffscreenPrivPtr pPriv = (OffscreenPrivPtr) surface->devPrivate.ptr;
+    ScrnInfoPtr pScrn = surface->pScrn;
+    ScreenPtr pScreen = screenInfo.screens[pScrn->scrnIndex];
+    I830Ptr pI830 = I830PTR(pScrn);
+    I830PortPrivPtr pI830Priv = GET_PORT_PRIVATE(pScrn);
+    INT32 x1, y1, x2, y2;
+    INT32 loops = 0;
+    BoxRec dstBox;
+
+    OVERLAY_DEBUG("I830DisplaySurface\n");
+
+    if (pI830->entityPrivate) {
+	if (pI830->entityPrivate->XvInUse != -1 &&
+	    pI830->entityPrivate->XvInUse != I830CrtcPipe (pI830Priv->current_crtc)) {
 #ifdef PANORAMIX
-		if (!noPanoramiXExtension) {
-			return Success; /* faked for trying to share it */
-		} else
+	    if (!noPanoramiXExtension) {
+		return Success; /* faked for trying to share it */
+	    } else
 #endif
-		{
-			return BadAlloc;
-		}
-	 }
+	    {
+		return BadAlloc;
+	    }
+	}
 
-      pI830->entityPrivate->XvInUse = I830CrtcPipe (pI830Priv->current_crtc);
-   }
+	pI830->entityPrivate->XvInUse = I830CrtcPipe (pI830Priv->current_crtc);
+    }
 
-   x1 = src_x;
-   x2 = src_x + src_w;
-   y1 = src_y;
-   y2 = src_y + src_h;
-
-   dstBox.x1 = drw_x;
-   dstBox.x2 = drw_x + drw_w;
-   dstBox.y1 = drw_y;
-   dstBox.y2 = drw_y + drw_h;
-
-   if (!xf86XVClipVideoHelper(&dstBox, &x1, &x2, &y1, &y2, clipBoxes,
-			      surface->width, surface->height))
-      return Success;
-
-   /* fixup pointers */
-   pI830Priv->YBuf0offset = surface->offsets[0];
-   pI830Priv->YBuf1offset = pI830Priv->YBuf0offset;
-
-   /* Make sure this buffer isn't in use */
-   loops = 0;
-   if (*pI830->overlayOn && pI830Priv->doubleBuffer) 
-   {
-      while (loops < 1000000) {
+    x1 = src_x;
+    x2 = src_x + src_w;
+    y1 = src_y;
+    y2 = src_y + src_h;
+
+    dstBox.x1 = drw_x;
+    dstBox.x2 = drw_x + drw_w;
+    dstBox.y1 = drw_y;
+    dstBox.y2 = drw_y + drw_h;
+
+    if (!xf86XVClipVideoHelper(&dstBox, &x1, &x2, &y1, &y2, clipBoxes,
+			       surface->width, surface->height))
+	return Success;
+
+    /* fixup pointers */
+    pI830Priv->YBuf0offset = surface->offsets[0];
+    pI830Priv->YBuf1offset = pI830Priv->YBuf0offset;
+
+    /* Make sure this buffer isn't in use */
+    loops = 0;
+    if (*pI830->overlayOn && pI830Priv->doubleBuffer) 
+    {
+	while (loops < 1000000) {
 #if USE_USLEEP_FOR_VIDEO
-         usleep(10);
+	    usleep(10);
 #endif
-         if (((INREG(DOVSTA) & OC_BUF) >> 20) == pI830Priv->currentBuf) {
-	    break;
-         }
-         loops++;
-      }
-      if (loops >= 1000000) {
-         ErrorF("loops (1) maxed out for buffer %d\n", pI830Priv->currentBuf);
+	    if (((INREG(DOVSTA) & OC_BUF) >> 20) == pI830Priv->currentBuf) {
+		break;
+	    }
+	    loops++;
+	}
+	if (loops >= 1000000) {
+	    ErrorF("loops (1) maxed out for buffer %d\n", pI830Priv->currentBuf);
 #if 0
-         pI830Priv->currentBuf = !pI830Priv->currentBuf;
+	    pI830Priv->currentBuf = !pI830Priv->currentBuf;
 #endif
-      }
+	}
 
-      /* buffer swap */
-      pI830Priv->currentBuf = !pI830Priv->currentBuf;
-   }
-
-   I830DisplayVideo(pScrn, surface->id, surface->width, surface->height,
-		    surface->pitches[0], x1, y1, x2, y2, &dstBox,
-		    src_w, src_h, drw_w, drw_h);
-
-   xf86XVFillKeyHelper(pScreen, pI830Priv->colorKey, clipBoxes);
-
-   pPriv->isOn = TRUE;
-   /* we've prempted the XvImage stream so set its free timer */
-   if (pI830Priv->videoStatus & CLIENT_VIDEO_ON) {
-      REGION_EMPTY(pScrn->pScreen, &pI830Priv->clip);
-      UpdateCurrentTime();
-      pI830Priv->videoStatus = FREE_TIMER;
-      pI830Priv->freeTime = currentTime.milliseconds + FREE_DELAY;
-      pScrn->pScreen->BlockHandler = I830BlockHandler;
-   }
+	/* buffer swap */
+	pI830Priv->currentBuf = !pI830Priv->currentBuf;
+    }
+
+    I830DisplayVideo(pScrn, surface->id, surface->width, surface->height,
+		     surface->pitches[0], x1, y1, x2, y2, &dstBox,
+		     src_w, src_h, drw_w, drw_h);
+
+    xf86XVFillKeyHelper(pScreen, pI830Priv->colorKey, clipBoxes);
+
+    pPriv->isOn = TRUE;
+    /* we've prempted the XvImage stream so set its free timer */
+    if (pI830Priv->videoStatus & CLIENT_VIDEO_ON) {
+	REGION_EMPTY(pScrn->pScreen, &pI830Priv->clip);
+	UpdateCurrentTime();
+	pI830Priv->videoStatus = FREE_TIMER;
+	pI830Priv->freeTime = currentTime.milliseconds + FREE_DELAY;
+	pScrn->pScreen->BlockHandler = I830BlockHandler;
+    }
 
-   return Success;
+    return Success;
 }
 
 static void
 I830InitOffscreenImages(ScreenPtr pScreen)
 {
-   XF86OffscreenImagePtr offscreenImages;
-   ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
-   I830Ptr pI830 = I830PTR(pScrn);
-
-   /* need to free this someplace */
-   if (!(offscreenImages = xalloc(sizeof(XF86OffscreenImageRec)))) {
-      return;
-   }
-
-   offscreenImages[0].image = &Images[0];
-   offscreenImages[0].flags = VIDEO_OVERLAID_IMAGES /*| VIDEO_CLIP_TO_VIEWPORT*/;
-   offscreenImages[0].alloc_surface = I830AllocateSurface;
-   offscreenImages[0].free_surface = I830FreeSurface;
-   offscreenImages[0].display = I830DisplaySurface;
-   offscreenImages[0].stop = I830StopSurface;
-   offscreenImages[0].setAttribute = I830SetSurfaceAttribute;
-   offscreenImages[0].getAttribute = I830GetSurfaceAttribute;
-   if (IS_845G(pI830) || IS_I830(pI830)) {
-      offscreenImages[0].max_width = IMAGE_MAX_WIDTH_LEGACY;
-      offscreenImages[0].max_height = IMAGE_MAX_HEIGHT_LEGACY;
-   } else {
-      offscreenImages[0].max_width = IMAGE_MAX_WIDTH;
-      offscreenImages[0].max_height = IMAGE_MAX_HEIGHT; 
-   }
-   offscreenImages[0].num_attributes = 1;
-   offscreenImages[0].attributes = Attributes;
+    XF86OffscreenImagePtr offscreenImages;
+    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+    I830Ptr pI830 = I830PTR(pScrn);
+
+    /* need to free this someplace */
+    if (!(offscreenImages = xalloc(sizeof(XF86OffscreenImageRec)))) {
+	return;
+    }
+
+    offscreenImages[0].image = &Images[0];
+    offscreenImages[0].flags = VIDEO_OVERLAID_IMAGES /*| VIDEO_CLIP_TO_VIEWPORT*/;
+    offscreenImages[0].alloc_surface = I830AllocateSurface;
+    offscreenImages[0].free_surface = I830FreeSurface;
+    offscreenImages[0].display = I830DisplaySurface;
+    offscreenImages[0].stop = I830StopSurface;
+    offscreenImages[0].setAttribute = I830SetSurfaceAttribute;
+    offscreenImages[0].getAttribute = I830GetSurfaceAttribute;
+    if (IS_845G(pI830) || IS_I830(pI830)) {
+	offscreenImages[0].max_width = IMAGE_MAX_WIDTH_LEGACY;
+	offscreenImages[0].max_height = IMAGE_MAX_HEIGHT_LEGACY;
+    } else {
+	offscreenImages[0].max_width = IMAGE_MAX_WIDTH;
+	offscreenImages[0].max_height = IMAGE_MAX_HEIGHT; 
+    }
+    offscreenImages[0].num_attributes = 1;
+    offscreenImages[0].attributes = Attributes;
 
-   xf86XVRegisterOffscreenImages(pScreen, offscreenImages, 1);
+    xf86XVRegisterOffscreenImages(pScreen, offscreenImages, 1);
 }
 
 void
 i830_crtc_dpms_video(xf86CrtcPtr crtc, Bool on)
 {
-   ScrnInfoPtr pScrn = crtc->scrn;
-   I830Ptr pI830 = I830PTR(pScrn);
-   I830PortPrivPtr pPriv;
-   I830CrtcPrivatePtr intel_crtc = crtc->driver_private;
-
-   if (pI830->adaptor == NULL)
-      return;
-
-   /* No overlay scaler on the 965. */
-   if (IS_I965G(pI830))
-      return;
-
-   pPriv = GET_PORT_PRIVATE(pScrn);
-
-   /* Check if it's the crtc the overlay is on */
-   if (crtc != pPriv->current_crtc)
-      return;
-
-   if (on) {
-      int size, hsize, vsize, active;
-      int pipeconf_reg = intel_crtc->pipe == 0 ? PIPEACONF : PIPEBCONF;
-      char pipename = intel_crtc->pipe == 0 ? 'A' : 'B';
-
-      pPriv->overlayOK = TRUE;
-
-      if (INREG(pipeconf_reg) & PIPEACONF_DOUBLE_WIDE) {
-	 xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
-		    "Disabling XVideo output because Pipe %c is in "
-		    "double-wide mode.\n", pipename);
-	 pPriv->overlayOK = FALSE;
-      } else if (!pPriv->overlayOK) {
-	 xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
-		    "Re-enabling XVideo output because Pipe %c is now in "
-		    "single-wide mode.\n", pipename);
-	 pPriv->overlayOK = TRUE;
-      }
-
-      /* Check we have an LFP connected */
-      if (i830PipeHasType(crtc, I830_OUTPUT_LVDS)) {
-	 int vtotal_reg = intel_crtc->pipe ? VTOTAL_A : VTOTAL_B;
-	 size = intel_crtc->pipe ? INREG(PIPEBSRC) : INREG(PIPEASRC);
-	 hsize = (size >> 16) & 0x7FF;
-	 vsize = size & 0x7FF;
-	 active = INREG(vtotal_reg) & 0x7FF;
+    ScrnInfoPtr pScrn = crtc->scrn;
+    I830Ptr pI830 = I830PTR(pScrn);
+    I830PortPrivPtr pPriv;
+    I830CrtcPrivatePtr intel_crtc = crtc->driver_private;
+
+    if (pI830->adaptor == NULL)
+	return;
 
-	 if (vsize < active && hsize > 1024)
-	    I830SetOneLineModeRatio(pScrn);
+    /* No overlay scaler on the 965. */
+    if (IS_I965G(pI830))
+	return;
 
-	 if (pPriv->scaleRatio & 0xFFFE0000) {
-	    /* Possible bogus ratio, using in-accurate fallback */
+    pPriv = GET_PORT_PRIVATE(pScrn);
+
+    /* Check if it's the crtc the overlay is on */
+    if (crtc != pPriv->current_crtc)
+	return;
+
+    if (on) {
+	int size, hsize, vsize, active;
+	int pipeconf_reg = intel_crtc->pipe == 0 ? PIPEACONF : PIPEBCONF;
+	char pipename = intel_crtc->pipe == 0 ? 'A' : 'B';
+
+	pPriv->overlayOK = TRUE;
+
+	if (INREG(pipeconf_reg) & PIPEACONF_DOUBLE_WIDE) {
 	    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
-		       "Bogus panel fit register, Xvideo positioning may not "
-		       "be accurate.\n");
+		       "Disabling XVideo output because Pipe %c is in "
+		       "double-wide mode.\n", pipename);
+	    pPriv->overlayOK = FALSE;
+	} else if (!pPriv->overlayOK) {
 	    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
-		       "Using fallback ratio - was 0x%x, now 0x%x\n",
-		       pPriv->scaleRatio,
-		       (int)(((float)active * 65536)/(float)vsize));
-
-	    pPriv->scaleRatio = (int)(((float)active * 65536) / (float)vsize);
-	 }
-      }
-   } else {
-      /* We stop the video when mode switching, so we don't lock up
-       * the engine. The overlayOK will determine whether we can re-enable
-       * with the current video on completion of the mode switch.
-       */
-      I830StopVideo(pScrn, pPriv, TRUE);
-      pPriv->overlayOK = FALSE;
-      pPriv->oneLineMode = FALSE;
-   }
+		       "Re-enabling XVideo output because Pipe %c is now in "
+		       "single-wide mode.\n", pipename);
+	    pPriv->overlayOK = TRUE;
+	}
+
+	/* Check we have an LFP connected */
+	if (i830PipeHasType(crtc, I830_OUTPUT_LVDS)) {
+	    int vtotal_reg = intel_crtc->pipe ? VTOTAL_A : VTOTAL_B;
+	    size = intel_crtc->pipe ? INREG(PIPEBSRC) : INREG(PIPEASRC);
+	    hsize = (size >> 16) & 0x7FF;
+	    vsize = size & 0x7FF;
+	    active = INREG(vtotal_reg) & 0x7FF;
+
+	    if (vsize < active && hsize > 1024)
+		I830SetOneLineModeRatio(pScrn);
+
+	    if (pPriv->scaleRatio & 0xFFFE0000) {
+		/* Possible bogus ratio, using in-accurate fallback */
+		xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+			   "Bogus panel fit register, Xvideo positioning may not "
+			   "be accurate.\n");
+		xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+			   "Using fallback ratio - was 0x%x, now 0x%x\n",
+			   pPriv->scaleRatio,
+			   (int)(((float)active * 65536)/(float)vsize));
+
+		pPriv->scaleRatio = (int)(((float)active * 65536) / (float)vsize);
+	    }
+	}
+    } else {
+	/* We stop the video when mode switching, so we don't lock up
+	 * the engine. The overlayOK will determine whether we can re-enable
+	 * with the current video on completion of the mode switch.
+	 */
+	I830StopVideo(pScrn, pPriv, TRUE);
+	pPriv->overlayOK = FALSE;
+	pPriv->oneLineMode = FALSE;
+    }
 }
diff-tree 02935ced3fba598a01d908ae49ccc30cbcc765a8 (from 08753f9b79f3f09879a18b552d90d88dbf52d4be)
Author: Keith Packard <keithp at dulcimer.keithp.com>
Date:   Wed May 23 19:24:25 2007 -0700

    Clean up overlay management.
    
    Create separate on/continue/off functions for overlay.
    Manage overlayOn boolean within those functions.
    Eliminate redundant management code in other routines.

diff --git a/src/i830_video.c b/src/i830_video.c
index 852c00f..2462d5d 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -357,80 +357,81 @@ CompareOverlay(I830Ptr pI830, CARD32 * o
 
 /*
  * This is more or less the correct way to initalise, update, and shut down
- * the overlay.  Note OVERLAY_OFF should be used only after disabling the
- * overlay in OCMD and calling OVERLAY_UPDATE.
+ * the overlay.
  *
  * XXX Need to make sure that the overlay engine is cleanly shutdown in
  * all modes of server exit.
  */
 
 static void
-i830_overlay_update(ScrnInfoPtr pScrn)
+i830_overlay_on(ScrnInfoPtr pScrn)
 {
     I830Ptr pI830 = I830PTR(pScrn);
+    I830OverlayRegPtr	overlay = (I830OverlayRegPtr) (pI830->FbBase +
+						       pI830->overlay_regs->offset);
+    
+    if (*pI830->overlayOn)
+	return;
 
-    BEGIN_LP_RING(8);
+    overlay->OCMD &= ~OVERLAY_ENABLE;
+    BEGIN_LP_RING(6);
     OUT_RING(MI_FLUSH | MI_WRITE_DIRTY_STATE);
     OUT_RING(MI_NOOP);
-    if (!*pI830->overlayOn) {
-	OUT_RING(MI_NOOP);
-	OUT_RING(MI_NOOP);
-	OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_FLIP_ON);
-	OVERLAY_DEBUG("Overlay goes from off to on\n");
-	*pI830->overlayOn = TRUE;
-    } else {
-	OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
-	OUT_RING(MI_NOOP);
-	OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_FLIP_CONTINUE);
-    }
-    if (IS_I965G(pI830))
-	OUT_RING(pI830->overlay_regs->offset | OFC_UPDATE);
-    else
-	OUT_RING(pI830->overlay_regs->bus_addr | OFC_UPDATE);
+    OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_FLIP_ON);
+    OUT_RING(pI830->overlay_regs->bus_addr | OFC_UPDATE);
     OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
     OUT_RING(MI_NOOP);
     ADVANCE_LP_RING();
-    OVERLAY_DEBUG("OVERLAY_UPDATE\n");
+    OVERLAY_DEBUG("overlay_on\n");
+    *pI830->overlayOn = TRUE;
 }
 
-#define OVERLAY_UPDATE	i830_overlay_update(pScrn)
+static void
+i830_overlay_continue(ScrnInfoPtr pScrn)
+{
+    I830Ptr pI830 = I830PTR(pScrn);
+    I830OverlayRegPtr	overlay = (I830OverlayRegPtr) (pI830->FbBase +
+						       pI830->overlay_regs->offset);
+
+    if (!*pI830->overlayOn)
+	return;
+
+    overlay->OCMD |= OVERLAY_ENABLE;
+    BEGIN_LP_RING(6);
+    OUT_RING(MI_FLUSH | MI_WRITE_DIRTY_STATE);
+    OUT_RING(MI_NOOP);
+    OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_FLIP_CONTINUE);
+    OUT_RING(pI830->overlay_regs->bus_addr | OFC_UPDATE);
+    OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
+    OUT_RING(MI_NOOP);
+    ADVANCE_LP_RING();
+    OVERLAY_DEBUG("overlay_continue\n");
+}
 
 static void
 i830_overlay_off(ScrnInfoPtr pScrn)
 {
     I830Ptr pI830 = I830PTR(pScrn);
-    if (*pI830->overlayOn) {
-	int spin = 1000000;
-	I830OverlayRegPtr overlay =					
-	  (I830OverlayRegPtr) (pI830->FbBase + pI830->overlay_regs->offset);
-	overlay->OCMD &= ~OVERLAY_ENABLE;
-	BEGIN_LP_RING(6);
-	OUT_RING(MI_FLUSH | MI_WRITE_DIRTY_STATE);
-	OUT_RING(MI_NOOP);
-	OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_FLIP_CONTINUE);
-	if (IS_I965G(pI830))
-	    OUT_RING(pI830->overlay_regs->offset | OFC_UPDATE);
-	else
-	    OUT_RING(pI830->overlay_regs->bus_addr | OFC_UPDATE);
-	OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
-	OUT_RING(MI_NOOP);
-	ADVANCE_LP_RING();
-	i830WaitSync(pScrn);
-	*pI830->overlayOn = FALSE;
-	OUTREG(OCMD_REGISTER, INREG(OCMD_REGISTER) & ~OVERLAY_ENABLE);
-	OVERLAY_DEBUG("Overlay goes from on to off\n");
-	while (spin != 0 && (INREG(OCMD_REGISTER) & OVERLAY_ENABLE)){
-	    OVERLAY_DEBUG("SPIN %d\n",spin);
-	    spin--;
-	}
-	if (spin == 0)
-	    OVERLAY_DEBUG("OVERLAY FAILED TO GO OFF\n");
-	OVERLAY_DEBUG("OVERLAY_OFF\n");
-    }
+    I830OverlayRegPtr	overlay = (I830OverlayRegPtr) (pI830->FbBase +
+						       pI830->overlay_regs->offset);
+    
+    if (!*pI830->overlayOn)
+	return;
+    
+    overlay->OCMD &= ~OVERLAY_ENABLE;
+    BEGIN_LP_RING(6);
+    OUT_RING(MI_FLUSH | MI_WRITE_DIRTY_STATE);
+    OUT_RING(MI_NOOP);
+    OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_FLIP_CONTINUE);
+    OUT_RING(pI830->overlay_regs->bus_addr | OFC_UPDATE);
+    OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
+    OUT_RING(MI_NOOP);
+    ADVANCE_LP_RING();
+    i830WaitSync(pScrn);
+    *pI830->overlayOn = FALSE;
+    OVERLAY_DEBUG("overlay_off\n");
 }
 
-#define OVERLAY_OFF i830_overlay_off(pScrn)
-
 void
 I830InitVideo(ScreenPtr pScreen)
 {
@@ -582,8 +583,6 @@ I830ResetVideo(ScrnInfoPtr pScrn)
    else 
       overlay->OCONFIG |= OVERLAY_PIPE_B;
 
-   overlay->OCMD = YUV_420;
-
 #if 0
    /* 
     * XXX DUMP REGISTER CODE !!!
@@ -925,11 +924,7 @@ I830StopVideo(ScrnInfoPtr pScrn, pointer
 
    if (shutdown) {
       if (pPriv->videoStatus & CLIENT_VIDEO_ON) {
-
-	 I830ResetVideo(pScrn);
-	 OVERLAY_UPDATE;
-	 OVERLAY_OFF;
-
+	 i830_overlay_off(pScrn);
          if (pI830->entityPrivate)
             pI830->entityPrivate->XvInUse = -1;
       }
@@ -967,10 +962,9 @@ I830SetPortAttribute(ScrnInfoPtr pScrn,
 	 return BadValue;
       pPriv->brightness = value;
       overlay->OCLRC0 = (pPriv->contrast << 18) | (pPriv->brightness & 0xff);
-      if (*pI830->overlayOn)
-         OVERLAY_UPDATE;
       OVERLAY_DEBUG("BRIGHTNESS\n");
-      OVERLAY_UPDATE;
+      if (*pI830->overlayOn)
+	 i830_overlay_continue (pScrn);
    } else if (attribute == xvContrast) {
       if ((value < 0) || (value > 255))
 	 return BadValue;
@@ -978,14 +972,14 @@ I830SetPortAttribute(ScrnInfoPtr pScrn,
       overlay->OCLRC0 = (pPriv->contrast << 18) | (pPriv->brightness & 0xff);
       OVERLAY_DEBUG("CONTRAST\n");
       if (*pI830->overlayOn)
-         OVERLAY_UPDATE;
+	 i830_overlay_continue (pScrn);
    } else if (attribute == xvSaturation) {
       if ((value < 0) || (value > 1023))
 	 return BadValue;
       pPriv->saturation = value;
       overlay->OCLRC1 = pPriv->saturation;
-      overlay->OCMD &= ~OVERLAY_ENABLE;
-      OVERLAY_UPDATE;
+      if (*pI830->overlayOn)
+	 i830_overlay_continue (pScrn);
    } else if (attribute == xvPipe) {
       xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
       if ((value < -1) || (value > xf86_config->num_crtc))
@@ -994,6 +988,9 @@ I830SetPortAttribute(ScrnInfoPtr pScrn,
 	 pPriv->desired_crtc = NULL;
       else
 	 pPriv->desired_crtc = xf86_config->crtc[value];
+      /*
+       * Leave this to be updated at the next frame
+       */
    } else if (attribute == xvGamma0 && (IS_I9XX(pI830))) {
       pPriv->gamma0 = value; 
    } else if (attribute == xvGamma1 && (IS_I9XX(pI830))) {
@@ -1021,7 +1018,7 @@ I830SetPortAttribute(ScrnInfoPtr pScrn,
       }
       OVERLAY_DEBUG("COLORKEY\n");
       if (*pI830->overlayOn)
-         OVERLAY_UPDATE;
+	 i830_overlay_continue (pScrn);
       REGION_EMPTY(pScrn->pScreen, &pPriv->clip);
    } else if(attribute == xvDoubleBuffer) {
       if ((value < 0) || (value > 1))
@@ -1706,11 +1703,7 @@ I830DisplayVideo(ScrnInfoPtr pScrn, int 
       I830ResetVideo(pScrn);
 
    /* Ensure overlay is turned on with OVERLAY_ENABLE at 0 */
-   if (!*pI830->overlayOn) {
-      OVERLAY_DEBUG("TURNING ON OVERLAY BEFORE UPDATE\n");
-      I830ResetVideo(pScrn);
-      OVERLAY_UPDATE;
-   }
+   i830_overlay_on (pScrn);
 
    /* Fix up the dstBox if outside the visible screen */
    {
@@ -2117,7 +2110,7 @@ I830DisplayVideo(ScrnInfoPtr pScrn, int 
 
    OVERLAY_DEBUG("OCMD is 0x%lx\n", overlay->OCMD);
 
-   OVERLAY_UPDATE;
+   i830_overlay_continue (pScrn);
 }
 
 #ifdef I830_USE_EXA
@@ -2641,9 +2634,7 @@ I830BlockHandler(int i,
 	    /* Turn off the overlay */
 	    OVERLAY_DEBUG("BLOCKHANDLER\n");
 
-	    I830ResetVideo(pScrn);
-            OVERLAY_UPDATE;
-            OVERLAY_OFF;
+	    i830_overlay_off (pScrn);
 
 	    pPriv->videoStatus = FREE_TIMER;
 	    pPriv->freeTime = now + FREE_DELAY;
@@ -2745,9 +2736,7 @@ I830StopSurface(XF86SurfacePtr surface)
 
       OVERLAY_DEBUG("StopSurface\n");
 
-      I830ResetVideo(pScrn);
-      OVERLAY_UPDATE;
-      OVERLAY_OFF;
+      i830_overlay_off (pScrn);
 
       if (pI830->entityPrivate)
          pI830->entityPrivate->XvInUse = -1;
@@ -2763,9 +2752,7 @@ I830FreeSurface(XF86SurfacePtr surface)
 {
    OffscreenPrivPtr pPriv = (OffscreenPrivPtr) surface->devPrivate.ptr;
 
-   if (pPriv->isOn) {
-      I830StopSurface(surface);
-   }
+   I830StopSurface(surface);
    I830FreeMemory(surface->pScrn, &pPriv->linear);
    xfree(surface->pitches);
    xfree(surface->offsets);
@@ -2798,8 +2785,6 @@ I830DisplaySurface(XF86SurfacePtr surfac
    ScreenPtr pScreen = screenInfo.screens[pScrn->scrnIndex];
    I830Ptr pI830 = I830PTR(pScrn);
    I830PortPrivPtr pI830Priv = GET_PORT_PRIVATE(pScrn);
-   I830OverlayRegPtr overlay =
-	 (I830OverlayRegPtr) (pI830->FbBase + pI830->overlay_regs->offset);
    INT32 x1, y1, x2, y2;
    INT32 loops = 0;
    BoxRec dstBox;
@@ -2842,7 +2827,8 @@ I830DisplaySurface(XF86SurfacePtr surfac
 
    /* Make sure this buffer isn't in use */
    loops = 0;
-   if (*pI830->overlayOn && pI830Priv->doubleBuffer && (overlay->OCMD & OVERLAY_ENABLE)) {
+   if (*pI830->overlayOn && pI830Priv->doubleBuffer) 
+   {
       while (loops < 1000000) {
 #if USE_USLEEP_FOR_VIDEO
          usleep(10);
@@ -2860,10 +2846,7 @@ I830DisplaySurface(XF86SurfacePtr surfac
       }
 
       /* buffer swap */
-      if (pI830Priv->currentBuf == 0)
-         pI830Priv->currentBuf = 1;
-      else
-         pI830Priv->currentBuf = 0;
+      pI830Priv->currentBuf = !pI830Priv->currentBuf;
    }
 
    I830DisplayVideo(pScrn, surface->id, surface->width, surface->height,
diff-tree 08753f9b79f3f09879a18b552d90d88dbf52d4be (from aa187186dc4f2d770a642060fe54f547ea8952b3)
Author: Keith Packard <keithp at dulcimer.keithp.com>
Date:   Wed May 23 18:59:10 2007 -0700

    Use FLIP_CONTINUE with ~OVERLAY_ENABLE to turn overlay off.
    
    This makes the overlay work on i830 with the modesetting driver. I don't
    know why the pre-modesetting driver worked without this, but it did.
    A more 'correct' fix would be welcome, but this does seem to do the trick.

diff --git a/src/i830_video.c b/src/i830_video.c
index 145d25a..852c00f 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -401,10 +401,13 @@ i830_overlay_off(ScrnInfoPtr pScrn)
     I830Ptr pI830 = I830PTR(pScrn);
     if (*pI830->overlayOn) {
 	int spin = 1000000;
+	I830OverlayRegPtr overlay =					
+	  (I830OverlayRegPtr) (pI830->FbBase + pI830->overlay_regs->offset);
+	overlay->OCMD &= ~OVERLAY_ENABLE;
 	BEGIN_LP_RING(6);
 	OUT_RING(MI_FLUSH | MI_WRITE_DIRTY_STATE);
 	OUT_RING(MI_NOOP);
-	OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_FLIP_OFF);
+	OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_FLIP_CONTINUE);
 	if (IS_I965G(pI830))
 	    OUT_RING(pI830->overlay_regs->offset | OFC_UPDATE);
 	else
diff-tree aa187186dc4f2d770a642060fe54f547ea8952b3 (from f5017a06a271bba0ace3c5415b78e78bc0c96f22)
Author: Keith Packard <keithp at dulcimer.keithp.com>
Date:   Mon May 21 10:49:08 2007 -0700

    Automatically select crtc based on coverage.
    
    By default, select crtc based on which one covers more of the video output.
    pipe property can be used to override selection when both have partial
    coverage.

diff --git a/src/i830_video.c b/src/i830_video.c
index 02ddff5..145d25a 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -147,7 +147,7 @@ static Atom xvGamma0, xvGamma1, xvGamma2
 #define IMAGE_MAX_HEIGHT_LEGACY	1088
 
 /* overlay debugging printf function */
-#if 0
+#if 1
 #define OVERLAY_DEBUG ErrorF
 #else
 #define OVERLAY_DEBUG if (0) ErrorF
@@ -159,68 +159,6 @@ void exaMoveInPixmap (PixmapPtr pPixmap)
 #endif
 
 /*
- * This is more or less the correct way to initalise, update, and shut down
- * the overlay.  Note OVERLAY_OFF should be used only after disabling the
- * overlay in OCMD and calling OVERLAY_UPDATE.
- *
- * XXX Need to make sure that the overlay engine is cleanly shutdown in
- * all modes of server exit.
- */
-
-#define OVERLAY_UPDATE						\
-   do { 								\
-      BEGIN_LP_RING(8);							\
-      OUT_RING(MI_FLUSH | MI_WRITE_DIRTY_STATE);                       	\
-      OUT_RING(MI_NOOP);    						\
-      if (!*pI830->overlayOn) {						\
-	 OUT_RING(MI_NOOP);						\
-	 OUT_RING(MI_NOOP);						\
-	 OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_FLIP_ON);		\
-	 OVERLAY_DEBUG("Overlay goes from off to on\n");		\
-	 *pI830->overlayOn = TRUE;					\
-      } else {								\
-	 OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);	\
-	 OUT_RING(MI_NOOP);						\
-	 OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_FLIP_CONTINUE);		\
-      }									\
-      if (IS_I965G(pI830)) 						\
-         OUT_RING(pI830->overlay_regs->offset | OFC_UPDATE); 		\
-      else								\
-	 OUT_RING(pI830->overlay_regs->bus_addr | OFC_UPDATE);		\
-      OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);		\
-      OUT_RING(MI_NOOP);						\
-      ADVANCE_LP_RING();						\
-      OVERLAY_DEBUG("OVERLAY_UPDATE\n");				\
-   } while(0)
-
-#define OVERLAY_OFF							\
-   do { 								\
-      if (*pI830->overlayOn) {						\
-	 int spin = 1000000;						\
-	 BEGIN_LP_RING(6);						\
-         OUT_RING(MI_FLUSH | MI_WRITE_DIRTY_STATE);                   	\
-         OUT_RING(MI_NOOP);    						\
-	 OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_FLIP_OFF);		\
-         if (IS_I965G(pI830)) 						\
-            OUT_RING(pI830->overlay_regs->offset | OFC_UPDATE);		\
-         else								\
-	    OUT_RING(pI830->overlay_regs->bus_addr | OFC_UPDATE);	\
-	 OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);	\
-	 OUT_RING(MI_NOOP);						\
-	 ADVANCE_LP_RING();						\
-	 *pI830->overlayOn = FALSE;					\
-	 OVERLAY_DEBUG("Overlay goes from on to off\n");		\
-         while (spin != 0 && (INREG(OCMD_REGISTER) & OVERLAY_ENABLE)){	\
-		OVERLAY_DEBUG("SPIN %d\n",spin);			\
-		spin--;							\
- 	 }								\
-	 if (spin == 0)							\
-		OVERLAY_DEBUG("OVERLAY FAILED TO GO OFF\n");		\
-	 OVERLAY_DEBUG("OVERLAY_OFF\n");				\
-      }									\
-   } while(0)
-
-/*
  * OCMD - Overlay Command Register
  */
 #define OCMD_REGISTER		0x30168
@@ -417,6 +355,79 @@ CompareOverlay(I830Ptr pI830, CARD32 * o
 }
 #endif
 
+/*
+ * This is more or less the correct way to initalise, update, and shut down
+ * the overlay.  Note OVERLAY_OFF should be used only after disabling the
+ * overlay in OCMD and calling OVERLAY_UPDATE.
+ *
+ * XXX Need to make sure that the overlay engine is cleanly shutdown in
+ * all modes of server exit.
+ */
+
+static void
+i830_overlay_update(ScrnInfoPtr pScrn)
+{
+    I830Ptr pI830 = I830PTR(pScrn);
+
+    BEGIN_LP_RING(8);
+    OUT_RING(MI_FLUSH | MI_WRITE_DIRTY_STATE);
+    OUT_RING(MI_NOOP);
+    if (!*pI830->overlayOn) {
+	OUT_RING(MI_NOOP);
+	OUT_RING(MI_NOOP);
+	OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_FLIP_ON);
+	OVERLAY_DEBUG("Overlay goes from off to on\n");
+	*pI830->overlayOn = TRUE;
+    } else {
+	OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
+	OUT_RING(MI_NOOP);
+	OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_FLIP_CONTINUE);
+    }
+    if (IS_I965G(pI830))
+	OUT_RING(pI830->overlay_regs->offset | OFC_UPDATE);
+    else
+	OUT_RING(pI830->overlay_regs->bus_addr | OFC_UPDATE);
+    OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
+    OUT_RING(MI_NOOP);
+    ADVANCE_LP_RING();
+    OVERLAY_DEBUG("OVERLAY_UPDATE\n");
+}
+
+#define OVERLAY_UPDATE	i830_overlay_update(pScrn)
+
+static void
+i830_overlay_off(ScrnInfoPtr pScrn)
+{
+    I830Ptr pI830 = I830PTR(pScrn);
+    if (*pI830->overlayOn) {
+	int spin = 1000000;
+	BEGIN_LP_RING(6);
+	OUT_RING(MI_FLUSH | MI_WRITE_DIRTY_STATE);
+	OUT_RING(MI_NOOP);
+	OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_FLIP_OFF);
+	if (IS_I965G(pI830))
+	    OUT_RING(pI830->overlay_regs->offset | OFC_UPDATE);
+	else
+	    OUT_RING(pI830->overlay_regs->bus_addr | OFC_UPDATE);
+	OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
+	OUT_RING(MI_NOOP);
+	ADVANCE_LP_RING();
+	i830WaitSync(pScrn);
+	*pI830->overlayOn = FALSE;
+	OUTREG(OCMD_REGISTER, INREG(OCMD_REGISTER) & ~OVERLAY_ENABLE);
+	OVERLAY_DEBUG("Overlay goes from on to off\n");
+	while (spin != 0 && (INREG(OCMD_REGISTER) & OVERLAY_ENABLE)){
+	    OVERLAY_DEBUG("SPIN %d\n",spin);
+	    spin--;
+	}
+	if (spin == 0)
+	    OVERLAY_DEBUG("OVERLAY FAILED TO GO OFF\n");
+	OVERLAY_DEBUG("OVERLAY_OFF\n");
+    }
+}
+
+#define OVERLAY_OFF i830_overlay_off(pScrn)
+
 void
 I830InitVideo(ScreenPtr pScreen)
 {
@@ -1557,6 +1568,39 @@ UpdateCoeff(int taps, double fCutoff, Bo
    }
 }
 
+static float
+I830CrtcVideoCoverage (xf86CrtcPtr crtc, BoxPtr video)
+{
+   BoxRec   dest;
+   BoxRec   pipe;
+
+   if (crtc->enabled)
+   {
+      pipe.x1 = crtc->x;
+      pipe.x2 = crtc->x + xf86ModeWidth (&crtc->mode, crtc->rotation);
+      pipe.y1 = crtc->y;
+      pipe.y2 = crtc->y + xf86ModeHeight (&crtc->mode, crtc->rotation);
+   }
+   else
+   {
+      pipe.x1 = pipe.x2 = 0;
+      pipe.y1 = pipe.y2 = 0;
+   }
+   dest.x1 = pipe.x1 > video->x1 ? pipe.x1 : video->x1;
+   dest.x2 = pipe.x2 < video->x2 ? pipe.x2 : video->x2;
+   dest.y1 = pipe.y1 > video->y1 ? pipe.y1 : video->y1;
+   dest.y2 = pipe.y2 < video->y2 ? pipe.y2 : video->y2;
+   if (dest.x1 >= dest.x2 || dest.y1 >= dest.y2)
+   {
+      dest.x1 = dest.x2 = 0;
+      dest.y1 = dest.y2 = 0;
+   }
+   if (video->x1 >= video->x2 || video->y1 >= video->y2)
+      return 0.0;
+   return (((float) (dest.x2 - dest.x1) * (float) (dest.y2 - dest.y1)) /
+	   ((float) (video->x2 - video->x1) * (float) (video->y2 - video->y1)));
+}
+
 static void
 I830DisplayVideo(ScrnInfoPtr pScrn, int id, short width, short height,
 		 int dstPitch, int x1, int y1, int x2, int y2, BoxPtr dstBox,
@@ -1568,6 +1612,7 @@ I830DisplayVideo(ScrnInfoPtr pScrn, int 
 	 (I830OverlayRegPtr) (pI830->FbBase + pI830->overlay_regs->offset);
    unsigned int swidth;
    unsigned int mask, shift, offsety, offsetu;
+   xf86CrtcPtr crtc;
    int tmp;
 
    OVERLAY_DEBUG("I830DisplayVideo: %dx%d (pitch %d)\n", width, height,
@@ -1580,39 +1625,71 @@ I830DisplayVideo(ScrnInfoPtr pScrn, int 
    CompareOverlay(pI830, (CARD32 *) overlay, 0x100);
 #endif
 
-   switch (pI830->rotation) {
+   {
+      float best_coverage = 0.0;
+      float coverage;
+      int c;
+      xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+      
+      crtc = NULL;
+      for (c = 0; c < xf86_config->num_crtc; c++)
+      {
+	 xf86CrtcPtr	this_crtc = xf86_config->crtc[c];
+	 coverage = I830CrtcVideoCoverage (this_crtc, dstBox);
+	 if (coverage)
+	 {
+	    if (this_crtc == pPriv->desired_crtc)
+	    {
+	       crtc = this_crtc;
+	       best_coverage = 1.0;
+	    }
+	    else if (coverage > best_coverage)
+	    {
+	       crtc = this_crtc;
+	       best_coverage = coverage;
+	    }
+	 }
+      }
+      if (crtc != pPriv->current_crtc)
+      {
+	 pPriv->current_crtc = crtc;
+	 I830ResetVideo (pScrn);
+      }
+   }
+
+   switch (crtc->rotation & 0xf) {
 	case RR_Rotate_0:
-		dstBox->x1 -= pScrn->frameX0;
-		dstBox->x2 -= pScrn->frameX0;
-		dstBox->y1 -= pScrn->frameY0;
-		dstBox->y2 -= pScrn->frameY0;
+		dstBox->x1 -= crtc->x;
+		dstBox->x2 -= crtc->x;
+		dstBox->y1 -= crtc->y;
+		dstBox->y2 -= crtc->y;
 		break;
 	case RR_Rotate_90:
 		tmp = dstBox->x1;
-		dstBox->x1 = dstBox->y1 - pScrn->frameX0;
-		dstBox->y1 = pScrn->virtualY - tmp - pScrn->frameY0;
+		dstBox->x1 = dstBox->y1 - crtc->x;
+		dstBox->y1 = pScrn->virtualY - tmp - crtc->y;
 		tmp = dstBox->x2;
-		dstBox->x2 = dstBox->y2 - pScrn->frameX0;
-		dstBox->y2 = pScrn->virtualY - tmp - pScrn->frameY0;
+		dstBox->x2 = dstBox->y2 - crtc->x;
+		dstBox->y2 = pScrn->virtualY - tmp - crtc->y;
 		tmp = dstBox->y1;
 		dstBox->y1 = dstBox->y2;
 		dstBox->y2 = tmp;
 		break;
 	case RR_Rotate_180:
 		tmp = dstBox->x1;
-		dstBox->x1 = pScrn->virtualX - dstBox->x2 - pScrn->frameX0;
-		dstBox->x2 = pScrn->virtualX - tmp - pScrn->frameX0;
+		dstBox->x1 = pScrn->virtualX - dstBox->x2 - crtc->x;
+		dstBox->x2 = pScrn->virtualX - tmp - crtc->x;
 		tmp = dstBox->y1;
-		dstBox->y1 = pScrn->virtualY - dstBox->y2 - pScrn->frameY0;
-		dstBox->y2 = pScrn->virtualY - tmp - pScrn->frameY0;
+		dstBox->y1 = pScrn->virtualY - dstBox->y2 - crtc->y;
+		dstBox->y2 = pScrn->virtualY - tmp - crtc->y;
 		break;
 	case RR_Rotate_270:
 		tmp = dstBox->x1;
-		dstBox->x1 = pScrn->virtualX - dstBox->y1 - pScrn->frameX0;
-		dstBox->y1 = tmp - pScrn->frameY0;
+		dstBox->x1 = pScrn->virtualX - dstBox->y1 - crtc->x;
+		dstBox->y1 = tmp - crtc->y;
 		tmp = dstBox->x2;
-		dstBox->x2 = pScrn->virtualX - dstBox->y2 - pScrn->frameX0;
-		dstBox->y2 = tmp - pScrn->frameY0;
+		dstBox->x2 = pScrn->virtualX - dstBox->y2 - crtc->x;
+		dstBox->y2 = tmp - crtc->y;
 		tmp = dstBox->x1;
 		dstBox->x1 = dstBox->x2;
 		dstBox->x2 = tmp;
@@ -1642,7 +1719,7 @@ I830DisplayVideo(ScrnInfoPtr pScrn, int 
       offset_x = (offset_x + 3) & ~3;
       offset_y = (offset_y + 3) & ~3;
 
-      if (pI830->rotation & (RR_Rotate_90 | RR_Rotate_270)) {
+      if (crtc->rotation & (RR_Rotate_90 | RR_Rotate_270)) {
          height -= offset_x;
          width -= offset_y;
       } else {
@@ -1670,7 +1747,7 @@ I830DisplayVideo(ScrnInfoPtr pScrn, int 
       }
    }
 
-   if (pI830->rotation & (RR_Rotate_90 | RR_Rotate_270)) {
+   if (crtc->rotation & (RR_Rotate_90 | RR_Rotate_270)) {
       tmp = width;
       width = height;
       height = tmp;
@@ -1696,6 +1773,7 @@ I830DisplayVideo(ScrnInfoPtr pScrn, int 
        * in case an LFP is in use and it's not at it's native resolution.
        */
       int vactive = I830CrtcPipe (pPriv->current_crtc) ? (INREG(VTOTAL_B) & 0x7FF) : (INREG(VTOTAL_A) & 0x7FF);
+      int hactive = pPriv->current_crtc->mode.HDisplay;
 
       vactive += 1;
 
@@ -1705,16 +1783,16 @@ I830DisplayVideo(ScrnInfoPtr pScrn, int 
       if (dstBox->x2 < 0) dstBox->x2 = 0;
       if (dstBox->y1 > vactive) dstBox->y1 = vactive;
       if (dstBox->y2 > vactive) dstBox->y2 = vactive;
-      if (dstBox->x1 > pScrn->currentMode->HDisplay) dstBox->x1 = pScrn->currentMode->HDisplay - 1;
-      if (dstBox->x2 > pScrn->currentMode->HDisplay) dstBox->x2 = pScrn->currentMode->HDisplay - 1;
+      if (dstBox->x1 > hactive) dstBox->x1 = hactive;
+      if (dstBox->x2 > hactive) dstBox->x2 = hactive;
 
       /* nothing do to */
       if ((!dstBox->x1 && !dstBox->x2) || (!dstBox->y1 && !dstBox->y2)) {
          OVERLAY_DEBUG("NOTHING TO DO\n");
          return;
       }
-      if ((dstBox->x1 == (pScrn->currentMode->HDisplay - 1) && 
-           dstBox->x2 == (pScrn->currentMode->HDisplay - 1)) || 
+      if ((dstBox->x1 == (hactive) && 
+           dstBox->x2 == (hactive)) || 
           (dstBox->y1 == vactive && 
            dstBox->y2 == vactive)) {
          OVERLAY_DEBUG("NOTHING TO DO\n");
diff-tree f5017a06a271bba0ace3c5415b78e78bc0c96f22 (from 2df87256df755e972eb884bc742832038a020b2c)
Author: Keith Packard <keithp at dulcimer.keithp.com>
Date:   Sun May 20 17:25:33 2007 -0700

    Use CRTCs instead of pipe indices for video pipe selection.
    
    Replace pipe indices with crtc indices and store references to the xf86Crtc
    objects in the video private structure.

diff --git a/src/i830_video.c b/src/i830_video.c
index d2f9724..02ddff5 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -492,6 +492,14 @@ I830InitVideo(ScreenPtr pScreen)
    xfree(adaptors);
 }
 
+static int
+I830CrtcPipe (xf86CrtcPtr crtc)
+{
+   if (crtc == NULL)
+      return 0;
+   return ((I830CrtcPrivatePtr) crtc->driver_private)->pipe;
+}
+
 static void
 I830ResetVideo(ScrnInfoPtr pScrn)
 {
@@ -555,7 +563,7 @@ I830ResetVideo(ScrnInfoPtr pScrn)
     * Select which pipe the overlay is enabled on.
     */
    overlay->OCONFIG &= ~OVERLAY_PIPE_MASK;
-   if (pPriv->pipe == 0)
+   if (I830CrtcPipe (pPriv->current_crtc) == 0)
       overlay->OCONFIG |= OVERLAY_PIPE_A;
    else 
       overlay->OCONFIG |= OVERLAY_PIPE_B;
@@ -731,7 +739,8 @@ I830SetupImageVideoOverlay(ScreenPtr pSc
    pPriv->brightness = 0;
    pPriv->contrast = 64;
    pPriv->saturation = 128;
-   pPriv->pipe = 0;  /* XXX must choose pipe wisely */
+   pPriv->current_crtc = NULL;
+   pPriv->desired_crtc = NULL;
    memset(&pPriv->linear, 0, sizeof(pPriv->linear));
    pPriv->currentBuf = 0;
    pPriv->gamma5 = 0xc0c0c0;
@@ -964,20 +973,13 @@ I830SetPortAttribute(ScrnInfoPtr pScrn,
       overlay->OCMD &= ~OVERLAY_ENABLE;
       OVERLAY_UPDATE;
    } else if (attribute == xvPipe) {
-      if ((value < 0) || (value > 1))
+      xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+      if ((value < -1) || (value > xf86_config->num_crtc))
          return BadValue;
-      pPriv->pipe = value;
-      /*
-       * Select which pipe the overlay is enabled on.
-       */
-      overlay->OCONFIG &= ~OVERLAY_PIPE_MASK;
-      if (pPriv->pipe == 0)
-         overlay->OCONFIG |= OVERLAY_PIPE_A;
-      else 
-         overlay->OCONFIG |= OVERLAY_PIPE_B;
-      OVERLAY_DEBUG("PIPE CHANGE\n");
-      if (*pI830->overlayOn)
-         OVERLAY_UPDATE;
+      if (value < 0)
+	 pPriv->desired_crtc = NULL;
+      else
+	 pPriv->desired_crtc = xf86_config->crtc[value];
    } else if (attribute == xvGamma0 && (IS_I9XX(pI830))) {
       pPriv->gamma0 = value; 
    } else if (attribute == xvGamma1 && (IS_I9XX(pI830))) {
@@ -1044,7 +1046,14 @@ I830GetPortAttribute(ScrnInfoPtr pScrn,
    } else if (attribute == xvSaturation) {
       *value = pPriv->saturation;
    } else if (attribute == xvPipe) {
-      *value = pPriv->pipe;
+      int		c;
+      xf86CrtcConfigPtr	xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+      for (c = 0; c < xf86_config->num_crtc; c++)
+	 if (xf86_config->crtc[c] == pPriv->desired_crtc)
+	    break;
+      if (c == xf86_config->num_crtc)
+	 c = -1;
+      *value = c;
    } else if (attribute == xvGamma0 && (IS_I9XX(pI830))) {
       *value = pPriv->gamma0;
    } else if (attribute == xvGamma1 && (IS_I9XX(pI830))) {
@@ -1686,7 +1695,7 @@ I830DisplayVideo(ScrnInfoPtr pScrn, int 
       /* Keep the engine happy and clip to the real vertical size just
        * in case an LFP is in use and it's not at it's native resolution.
        */
-      int vactive = pPriv->pipe ? (INREG(VTOTAL_B) & 0x7FF) : (INREG(VTOTAL_A) & 0x7FF);
+      int vactive = I830CrtcPipe (pPriv->current_crtc) ? (INREG(VTOTAL_B) & 0x7FF) : (INREG(VTOTAL_A) & 0x7FF);
 
       vactive += 1;
 
@@ -2186,7 +2195,7 @@ I830PutImage(ScrnInfoPtr pScrn,
 
    if (pI830->entityPrivate) {
 	 if (pI830->entityPrivate->XvInUse != -1 &&
-	     pI830->entityPrivate->XvInUse != pPriv->pipe) {
+	     pI830->entityPrivate->XvInUse != I830CrtcPipe (pPriv->current_crtc)) {
 #ifdef PANORAMIX
 		if (!noPanoramiXExtension) {
 			return Success; /* faked for trying to share it */
@@ -2197,7 +2206,7 @@ I830PutImage(ScrnInfoPtr pScrn,
 		}
 	 }
 
-      pI830->entityPrivate->XvInUse = pPriv->pipe;
+      pI830->entityPrivate->XvInUse = I830CrtcPipe (pPriv->current_crtc);;
    }
 
    /* overlay limits */
@@ -2718,7 +2727,7 @@ I830DisplaySurface(XF86SurfacePtr surfac
 
    if (pI830->entityPrivate) {
 	 if (pI830->entityPrivate->XvInUse != -1 &&
-	     pI830->entityPrivate->XvInUse != pI830Priv->pipe) {
+	     pI830->entityPrivate->XvInUse != I830CrtcPipe (pI830Priv->current_crtc)) {
 #ifdef PANORAMIX
 		if (!noPanoramiXExtension) {
 			return Success; /* faked for trying to share it */
@@ -2729,7 +2738,7 @@ I830DisplaySurface(XF86SurfacePtr surfac
 		}
 	 }
 
-      pI830->entityPrivate->XvInUse = pI830Priv->pipe;
+      pI830->entityPrivate->XvInUse = I830CrtcPipe (pI830Priv->current_crtc);
    }
 
    x1 = src_x;
@@ -2832,7 +2841,6 @@ void
 i830_crtc_dpms_video(xf86CrtcPtr crtc, Bool on)
 {
    ScrnInfoPtr pScrn = crtc->scrn;
-   xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
    I830Ptr pI830 = I830PTR(pScrn);
    I830PortPrivPtr pPriv;
    I830CrtcPrivatePtr intel_crtc = crtc->driver_private;
@@ -2846,14 +2854,14 @@ i830_crtc_dpms_video(xf86CrtcPtr crtc, B
 
    pPriv = GET_PORT_PRIVATE(pScrn);
 
-   /* Check if it's the pipe the overlay is on */
-   if (intel_crtc->pipe != pPriv->pipe)
+   /* Check if it's the crtc the overlay is on */
+   if (crtc != pPriv->current_crtc)
       return;
 
    if (on) {
       int size, hsize, vsize, active;
-      int pipeconf_reg = pPriv->pipe == 0 ? PIPEACONF : PIPEBCONF;
-      char pipename = pPriv->pipe == 0 ? 'A' : 'B';
+      int pipeconf_reg = intel_crtc->pipe == 0 ? PIPEACONF : PIPEBCONF;
+      char pipename = intel_crtc->pipe == 0 ? 'A' : 'B';
 
       pPriv->overlayOK = TRUE;
 
@@ -2870,10 +2878,9 @@ i830_crtc_dpms_video(xf86CrtcPtr crtc, B
       }
 
       /* Check we have an LFP connected */
-      if (i830PipeHasType(xf86_config->crtc[pPriv->pipe],
-			  I830_OUTPUT_LVDS)) {
-	 int vtotal_reg = pPriv->pipe ? VTOTAL_A : VTOTAL_B;
-	 size = pPriv->pipe ? INREG(PIPEBSRC) : INREG(PIPEASRC);
+      if (i830PipeHasType(crtc, I830_OUTPUT_LVDS)) {
+	 int vtotal_reg = intel_crtc->pipe ? VTOTAL_A : VTOTAL_B;
+	 size = intel_crtc->pipe ? INREG(PIPEBSRC) : INREG(PIPEASRC);
 	 hsize = (size >> 16) & 0x7FF;
 	 vsize = size & 0x7FF;
 	 active = INREG(vtotal_reg) & 0x7FF;
diff --git a/src/i830_video.h b/src/i830_video.h
index 854d0b8..7e2d149 100644
--- a/src/i830_video.h
+++ b/src/i830_video.h
@@ -53,7 +53,8 @@ typedef struct {
    int brightness;
    int contrast;
    int saturation;
-   int pipe;
+   xf86CrtcPtr current_crtc;
+   xf86CrtcPtr desired_crtc;
    int doubleBuffer;
 
    RegionRec clip;
diff-tree 2df87256df755e972eb884bc742832038a020b2c (from 9971fac87622c93503540196e1756fded3d4869e)
Author: Keith Packard <keithp at dulcimer.keithp.com>
Date:   Sun May 20 17:23:26 2007 -0700

    Dump pending ring on crash.
    
    When the hardware locks up, dump the pending commands in the ring for
    analysis.

diff --git a/src/i830_debug.c b/src/i830_debug.c
index 73b5d1c..19eb17a 100644
--- a/src/i830_debug.c
+++ b/src/i830_debug.c
@@ -649,6 +649,30 @@ void i830DumpRegs (ScrnInfoPtr pScrn)
 }
 
 #ifndef REG_DUMPER
+
+#define NUM_RING_DUMP	64
+
+static void
+i830_dump_ring(ScrnInfoPtr pScrn)
+{
+    I830Ptr pI830 = I830PTR(pScrn);
+    unsigned int head, tail, ring, mask;
+    volatile unsigned char *virt;
+    
+    head = (INREG (LP_RING + RING_HEAD)) & I830_HEAD_MASK;
+    tail = INREG (LP_RING + RING_TAIL) & I830_TAIL_MASK;
+    mask = pI830->LpRing->tail_mask;
+    
+    virt = pI830->LpRing->virtual_start;
+    ErrorF ("Ring at virtual 0x%x head 0x%x tail 0x%x count %d\n",
+	    (unsigned int) virt, head, tail, (((tail + mask + 1) - head) & mask) >> 2);
+    for (ring = (head - 128) & mask; ring != tail; ring = (ring + 4) & mask)
+    {
+	ErrorF ("\t%08x: %08x\n", ring, *(volatile unsigned int *) (virt + ring));
+    }
+    ErrorF ("Ring end\n");
+}
+
 /* Famous last words
  */
 void
@@ -678,6 +702,7 @@ i830_dump_error_state(ScrnInfoPtr pScrn)
 
     ErrorF("hwstam: %x ier: %x imr: %x iir: %x\n",
 	   INREG16(HWSTAM), INREG16(IER), INREG16(IMR), INREG16(IIR));
+    i830_dump_ring (pScrn);
 }
 
 void
diff-tree 9971fac87622c93503540196e1756fded3d4869e (from 5390a2e2611950d3f48cc735df4a0c37bc5377a5)
Author: Michel Dänzer <michel at tungstengraphics.com>
Date:   Tue May 22 10:46:39 2007 +0200

    i830: Provide new DRI texOffsetStart hook when available with EXA.

diff --git a/src/i830.h b/src/i830.h
index 8dcc4b5..35f8192 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -77,6 +77,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN
 #include "exa.h"
 Bool I830EXAInit(ScreenPtr pScreen);
 #define EXA_LINEAR_EXTRA	(64*1024)
+unsigned long long I830TexOffsetStart(PixmapPtr pPix);
 #endif
 
 #ifdef I830_USE_XAA
diff --git a/src/i830_dri.c b/src/i830_dri.c
index 9498661..663ef14 100644
--- a/src/i830_dri.c
+++ b/src/i830_dri.c
@@ -576,17 +576,26 @@ I830DRIScreenInit(ScreenPtr pScreen)
    pDRIInfo->bufferRequests = DRI_ALL_WINDOWS;
 
    {
-#if DRI_SUPPORTS_CLIP_NOTIFY && DRIINFO_MAJOR_VERSION == 5 && \
-    DRIINFO_MINOR_VERSION >= 1
+#if DRIINFO_MAJOR_VERSION == 5 && DRIINFO_MINOR_VERSION >= 1
       int major, minor, patch;
 
       DRIQueryVersion(&major, &minor, &patch);
 
+#if DRIINFO_MAJOR_VERSION == 5 && DRIINFO_MINOR_VERSION >= 3
+      if (minor >= 3)
+#endif
+#if DRIINFO_MAJOR_VERSION > 5 || \
+    (DRIINFO_MAJOR_VERSION == 5 && DRIINFO_MINOR_VERSION >= 3)
+	 pDRIInfo->texOffsetStart = I830TexOffsetStart;
+#endif
+
+#if DRI_SUPPORTS_CLIP_NOTIFY && DRIINFO_MAJOR_VERSION == 5
       if (minor >= 1)
 #endif
 #if DRI_SUPPORTS_CLIP_NOTIFY
 	 pDRIInfo->ClipNotify = I830DRIClipNotify;
 #endif
+#endif /* DRIINFO_MAJOR_VERSION == 5 && DRIINFO_MINOR_VERSION >= 1 */
    }
 
    pDRIInfo->TransitionTo2d = I830DRITransitionTo2d;
diff --git a/src/i830_exa.c b/src/i830_exa.c
index ff21fbb..88d1b97 100644
--- a/src/i830_exa.c
+++ b/src/i830_exa.c
@@ -541,3 +541,19 @@ I830EXAInit(ScreenPtr pScreen)
 
     return TRUE;
 }
+
+#ifdef XF86DRI
+
+#ifndef ExaOffscreenMarkUsed
+extern void ExaOffscreenMarkUsed(PixmapPtr);
+#endif
+
+unsigned long long
+I830TexOffsetStart(PixmapPtr pPix)
+{
+    exaMoveInPixmap(pPix);
+    ExaOffscreenMarkUsed(pPix);
+
+    return exaGetPixmapOffset(pPix);
+}
+#endif
diff-tree 5390a2e2611950d3f48cc735df4a0c37bc5377a5 (from 4120a20626998272424225261f2cf7960b7ec0ca)
Author: Michel Dänzer <michel at tungstengraphics.com>
Date:   Fri May 18 17:51:36 2007 +0200

    Update vblank pipes when a pipe gets disabled.

diff --git a/src/i830_display.c b/src/i830_display.c
index 9caab85..023a1aa 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -540,6 +540,8 @@ i830_crtc_dpms(xf86CrtcPtr crtc, int mod
 	drmI830Sarea *sPriv = (drmI830Sarea *) DRIGetSAREAPrivate(pScrn->pScreen);
 	Bool enabled = crtc->enabled && mode != DPMSModeOff;
 
+	I830DRISetVBlankInterrupt (pScrn, TRUE);
+
 	if (!sPriv)
 	    return;
 
diff-tree 4120a20626998272424225261f2cf7960b7ec0ca (from 8db28aeaa6e908017b40bd9180f144a2972f6278)
Author: Wang Zhenyu <zhenyu.z.wang at intel.com>
Date:   Fri May 18 10:10:34 2007 +0800

    EXA: add render enter helper function
    
    That notify mesa rendering is smashing the state, and check last 3d
    operation to do sync after we're swapped in or others.

diff --git a/src/i830.h b/src/i830.h
index ab52da0..8dcc4b5 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -695,6 +695,8 @@ void
 i830_get_transformed_coordinates(int x, int y, PictTransformPtr transform,
 				 float *x_out, float *y_out);
 
+void i830_enter_render(ScrnInfoPtr);
+
 extern const int I830PatternROP[16];
 extern const int I830CopyROP[16];
 
diff --git a/src/i830_exa.c b/src/i830_exa.c
index 1741732..ff21fbb 100644
--- a/src/i830_exa.c
+++ b/src/i830_exa.c
@@ -270,6 +270,22 @@ I830EXADoneCopy(PixmapPtr pDstPixmap)
 #endif
 }
 
+void
+i830_enter_render(ScrnInfoPtr pScrn)
+{
+    I830Ptr pI830 = I830PTR(pScrn);
+#ifdef XF86DRI
+    if (pI830->directRenderingEnabled) {
+        drmI830Sarea *pSAREAPriv = DRIGetSAREAPrivate(pScrn->pScreen);
+	pSAREAPriv->ctxOwner = DRIGetContext(pScrn->pScreen);
+    }
+#endif
+    if (pI830->last_3d != LAST_3D_RENDER) {
+	i830WaitSync(pScrn);
+	pI830->last_3d = LAST_3D_RENDER;
+    }
+}
+
 #define xFixedToFloat(val) \
 	((float)xFixedToInt(val) + ((float)xFixedFrac(val) / 65536.0))
 
diff --git a/src/i830_render.c b/src/i830_render.c
index 077afa1..957953e 100644
--- a/src/i830_render.c
+++ b/src/i830_render.c
@@ -400,12 +400,12 @@ i830_prepare_composite(int op, PicturePt
     I830Ptr pI830 = I830PTR(pScrn);
     CARD32 dst_format, dst_offset, dst_pitch;
 
+    i830_enter_render(pScrn);
+
     i830_get_dest_format(pDstPicture, &dst_format);
     dst_offset = intel_get_pixmap_offset(pDst);
     dst_pitch = intel_get_pixmap_pitch(pDst);
 
-    pI830->last_3d = LAST_3D_RENDER;
-
     if (!i830_texture_setup(pSrcPicture, pSrc, 0))
 	I830FALLBACK("fail to setup src texture\n");
     if (pMask != NULL) {
@@ -632,9 +632,5 @@ i830_composite(PixmapPtr pDst, int srcX,
 void
 i830_done_composite(PixmapPtr pDst)
 {
-#if ALWAYS_SYNC
-    ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum];
-
-    I830Sync(pScrn);
-#endif
+    /* NO-OP */
 }
diff --git a/src/i915_render.c b/src/i915_render.c
index 5b2ed89..d5a8579 100644
--- a/src/i915_render.c
+++ b/src/i915_render.c
@@ -315,11 +315,7 @@ i915_prepare_composite(int op, PicturePt
     CARD32 dst_format, dst_offset, dst_pitch;
     CARD32 blendctl;
 
-#ifdef I830DEBUG
-    ErrorF("Enter i915 prepareComposite\n");
-#endif
-
-    pI830->last_3d = LAST_3D_RENDER;
+    i830_enter_render(pScrn);
 
     i915_get_dest_format(pDstPicture, &dst_format);
     dst_offset = intel_get_pixmap_offset(pDst);
diff --git a/src/i965_render.c b/src/i965_render.c
index bfbb77e..848774e 100644
--- a/src/i965_render.c
+++ b/src/i965_render.c
@@ -404,15 +404,7 @@ i965_prepare_composite(int op, PicturePt
     CARD32 dst_format, dst_offset, dst_pitch;
     Bool rotation_program = FALSE;
 
-#ifdef XF86DRI
-    if (pI830->directRenderingEnabled) {
-        drmI830Sarea *pSAREAPriv = DRIGetSAREAPrivate(pScrn->pScreen);
-
-        pSAREAPriv->ctxOwner = DRIGetContext(pScrn->pScreen);
-    }
-#endif
-
-    pI830->last_3d = LAST_3D_RENDER;
+    i830_enter_render(pScrn);
 
     src_offset = intel_get_pixmap_offset(pSrc);
     src_pitch = intel_get_pixmap_pitch(pSrc);
diff-tree 8db28aeaa6e908017b40bd9180f144a2972f6278 (from 16e50a91dd8b3676e8ce06052c549ab27e6843b7)
Author: Wang Zhenyu <zhenyu.z.wang at intel.com>
Date:   Fri May 18 09:54:34 2007 +0800

    Fix ring debug code
    
    Use proper unsigned type for timer variables, and try to dump 965G state.

diff --git a/src/i830_accel.c b/src/i830_accel.c
index 045b3b6..5cbad44 100644
--- a/src/i830_accel.c
+++ b/src/i830_accel.c
@@ -96,10 +96,10 @@ I830WaitLpRing(ScrnInfoPtr pScrn, int n,
    I830Ptr pI830 = I830PTR(pScrn);
    I830RingBuffer *ring = pI830->LpRing;
    int iters = 0;
-   int start = 0;
-   int now = 0;
+   unsigned int start = 0;
+   unsigned int now = 0;
    int last_head = 0;
-   int first = 0;
+   unsigned int first = 0;
 
    /* If your system hasn't moved the head pointer in 2 seconds, I'm going to
     * call it crashed.
@@ -128,9 +128,12 @@ I830WaitLpRing(ScrnInfoPtr pScrn, int n,
 	 start = now;
 	 last_head = ring->head;
       } else if (now - start > timeout_millis) {
-	 ErrorF("Error in I830WaitLpRing(), now is %d, start is %d\n", now,
-		start);
-	 i830_dump_error_state(pScrn);
+	 ErrorF("Error in I830WaitLpRing(), timeout for %d seconds\n",
+		timeout_millis/1000);
+	 if (IS_I965G(pI830))
+	     i965_dump_error_state(pScrn);
+	 else
+	     i830_dump_error_state(pScrn);
 	 ErrorF("space: %d wanted %d\n", ring->space, n);
 #ifdef XF86DRI
 	 if (pI830->directRenderingEnabled) {
@@ -153,7 +156,7 @@ I830WaitLpRing(ScrnInfoPtr pScrn, int n,
    if (I810_DEBUG & DEBUG_VERBOSE_ACCEL) {
       now = GetTimeInMillis();
       if (now - first) {
-	 ErrorF("Elapsed %d ms\n", now - first);
+	 ErrorF("Elapsed %u ms\n", now - first);
 	 ErrorF("space: %d wanted %d\n", ring->space, n);
       }
    }
diff-tree 16e50a91dd8b3676e8ce06052c549ab27e6843b7 (from 12a9fcfe1b25cee850380d8ce11ef11cde9aaacb)
Author: Wang Zhenyu <zhenyu.z.wang at intel.com>
Date:   Fri May 18 09:53:36 2007 +0800

    EXA: remove a flush cmd in i915 render code

diff --git a/src/i915_render.c b/src/i915_render.c
index 4d42242..5b2ed89 100644
--- a/src/i915_render.c
+++ b/src/i915_render.c
@@ -375,7 +375,7 @@ i915_prepare_composite(int op, PicturePt
     {
 	CARD32 ss2;
 
-	BEGIN_LP_RING(18);
+	BEGIN_LP_RING(16);
 	/* color buffer
 	 * XXX: Need to add USE_FENCE if we ever tile the X Server's pixmaps or
 	 * visible screen.
@@ -408,10 +408,6 @@ i915_prepare_composite(int op, PicturePt
 	OUT_RING(S6_CBUF_BLEND_ENABLE | S6_COLOR_WRITE_ENABLE |
 		 (BLENDFUNC_ADD << S6_CBUF_BLEND_FUNC_SHIFT) | blendctl);
 
-	/* issue a flush */
-	OUT_RING(MI_FLUSH | MI_WRITE_DIRTY_STATE | MI_INVALIDATE_MAP_CACHE);
-	OUT_RING(MI_NOOP);
-
 	/* draw rect is unconditional */
 	OUT_RING(_3DSTATE_DRAW_RECT_CMD);
 	OUT_RING(0x00000000);
diff-tree 12a9fcfe1b25cee850380d8ce11ef11cde9aaacb (from parents)
Merge: b930bb9d6da8c24dbe0949afb7bb2aa4bcb24687 e89d5f275442915cc7777e75d3fcf7e7ed0f2084
Author: Keith Packard <keithp at neko.keithp.com>
Date:   Thu May 17 15:11:29 2007 -0700

    Merge branch 'master' of git+ssh://git.freedesktop.org/git/xorg/driver/xf86-video-intel

diff-tree e89d5f275442915cc7777e75d3fcf7e7ed0f2084 (from a441954630c6cdabbf463bfc3404160f97a04b4f)
Author: Keith Packard <keithp at dulcimer.keithp.com>
Date:   Thu May 17 15:00:12 2007 -0700

    Make each output control clones/crtcs. Split DVO into LVDS, TMDS, TV.
    
    Move clone/crtc config into each output where it's easier to understand (no
    need for a switch statement in I830PrepareOutputs. Also, split DVO into
    three sub-types (TMDS, LVDS, TVOUT) as those have different cloning
    abilities.

diff --git a/src/i830.h b/src/i830.h
index 0fe5d41..ab52da0 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -191,15 +191,12 @@ typedef struct {
    external chips are via DVO or SDVO output */
 #define I830_OUTPUT_UNUSED 0
 #define I830_OUTPUT_ANALOG 1
-#define I830_OUTPUT_DVO 2
-#define I830_OUTPUT_SDVO 3
-#define I830_OUTPUT_LVDS 4
-#define I830_OUTPUT_TVOUT 5
-
-#define I830_DVO_CHIP_NONE 0
-#define I830_DVO_CHIP_LVDS 1
-#define I830_DVO_CHIP_TMDS 2
-#define I830_DVO_CHIP_TVOUT 4
+#define I830_OUTPUT_DVO_TMDS 2
+#define I830_OUTPUT_DVO_LVDS 3
+#define I830_OUTPUT_DVO_TVOUT 4
+#define I830_OUTPUT_SDVO 5
+#define I830_OUTPUT_LVDS 6
+#define I830_OUTPUT_TVOUT 7
 
 struct _I830DVODriver {
    int type;
@@ -246,6 +243,8 @@ typedef struct _I830OutputPrivateRec {
    I2CBusPtr		    pDDCBus;
    struct _I830DVODriver    *i2c_drv;
    Bool			    load_detect_temp;
+   int                      pipe_mask;
+   int			    clone_mask;
    /** Output-private structure.  Should replace i2c_drv */
    void			    *dev_priv;
 } I830OutputPrivateRec, *I830OutputPrivatePtr;
diff --git a/src/i830_crt.c b/src/i830_crt.c
index 879ae9f..bbb4a83 100644
--- a/src/i830_crt.c
+++ b/src/i830_crt.c
@@ -394,6 +394,9 @@ i830_crt_init(ScrnInfoPtr pScrn)
 	return;
     }
     i830_output->type = I830_OUTPUT_ANALOG;
+    i830_output->pipe_mask = ((1 << 0) | (1 << 1));
+    i830_output->clone_mask = ((1 << I830_OUTPUT_ANALOG) |
+			       (1 << I830_OUTPUT_DVO_TMDS));
     
     output->driver_private = i830_output;
     output->interlaceAllowed = FALSE;
diff --git a/src/i830_display.c b/src/i830_display.c
index 4b205ba..9caab85 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -752,7 +752,9 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, Dis
 	case I830_OUTPUT_SDVO:
 	    is_sdvo = TRUE;
 	    break;
-	case I830_OUTPUT_DVO:
+	case I830_OUTPUT_DVO_TMDS:
+	case I830_OUTPUT_DVO_LVDS:
+	case I830_OUTPUT_DVO_TVOUT:
 	    is_dvo = TRUE;
 	    break;
 	case I830_OUTPUT_TVOUT:
diff --git a/src/i830_driver.c b/src/i830_driver.c
index b4d9d08..2cbddb0 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -728,44 +728,20 @@ I830SetupOutputs(ScrnInfoPtr pScrn)
    {
       xf86OutputPtr	   output = config->output[o];
       I830OutputPrivatePtr intel_output = output->driver_private;
-      int		   crtc_mask = 0, clone_mask = 0;
+      int		   crtc_mask;
+      int		   c;
       
-      /*
-       * Valid crtcs
-       */
-      switch (intel_output->type) {
-      case I830_OUTPUT_DVO:
-      case I830_OUTPUT_SDVO:
-	 crtc_mask = ((1 << 0)|
-		      (1 << 1));
-	 clone_mask = ((1 << I830_OUTPUT_ANALOG) |
-		       (1 << I830_OUTPUT_DVO) |
-		       (1 << I830_OUTPUT_SDVO));
-	 break;
-      case I830_OUTPUT_ANALOG:
-	 crtc_mask = ((1 << 0));
-	 /*
-	  * 915 cannot do double-wide on pipe B
-	  * 830 cannot put CRT on pipe B
-	  */
-	 if (!IS_I915G(pI830) && !IS_I915GM (pI830) && !IS_I830(pI830))
-	    crtc_mask |= ((1 << 1));
-	 clone_mask = ((1 << I830_OUTPUT_ANALOG) |
-		       (1 << I830_OUTPUT_DVO) |
-		       (1 << I830_OUTPUT_SDVO));
-	 break;
-      case I830_OUTPUT_LVDS:
-	 crtc_mask = (1 << 1);
-	 clone_mask = (1 << I830_OUTPUT_LVDS);
-	 break;
-      case I830_OUTPUT_TVOUT:
-	 crtc_mask = ((1 << 0) |
-		      (1 << 1));
-	 clone_mask = (1 << I830_OUTPUT_TVOUT);
-	 break;
+      crtc_mask = 0;
+      for (c = 0; c < config->num_crtc; c++)
+      {
+	 xf86CrtcPtr	      crtc = config->crtc[c];
+	 I830CrtcPrivatePtr   intel_crtc = crtc->driver_private;
+
+	 if (intel_output->pipe_mask & (1 << intel_crtc->pipe))
+	    crtc_mask |= (1 << c);
       }
       output->possible_crtcs = crtc_mask;
-      output->possible_clones = i830_output_clones (pScrn, clone_mask);
+      output->possible_clones = i830_output_clones (pScrn, intel_output->clone_mask);
    }
 }
 
diff --git a/src/i830_dvo.c b/src/i830_dvo.c
index b69105e..d81e5dd 100644
--- a/src/i830_dvo.c
+++ b/src/i830_dvo.c
@@ -60,22 +60,22 @@ static const char *ch7017_symbols[] = {
 /* driver list */
 struct _I830DVODriver i830_dvo_drivers[] =
 {
-    {I830_DVO_CHIP_TMDS, "sil164", "SIL164VidOutput", DVOC,
+    {I830_OUTPUT_DVO_TMDS, "sil164", "SIL164VidOutput", DVOC,
      (SIL164_ADDR_1<<1), SIL164Symbols, NULL , NULL, NULL},
-    {I830_DVO_CHIP_TMDS | I830_DVO_CHIP_TVOUT, "ch7xxx", "CH7xxxVidOutput", DVOC,
+    {I830_OUTPUT_DVO_TMDS | I830_OUTPUT_DVO_TVOUT, "ch7xxx", "CH7xxxVidOutput", DVOC,
      (CH7xxx_ADDR_1<<1), CH7xxxSymbols, NULL , NULL, NULL},
-    {I830_DVO_CHIP_LVDS, "ivch", "ivch_methods", DVOA,
+    {I830_OUTPUT_DVO_LVDS, "ivch", "ivch_methods", DVOA,
      0x04, ivch_symbols, NULL, NULL, NULL},
     /*
-    {I830_DVO_CHIP_LVDS, "ivch", "ivch_methods",
+    {I830_OUTPUT_DVO_LVDS, "ivch", "ivch_methods",
      0x44, ivch_symbols, NULL, NULL, NULL},
-    {I830_DVO_CHIP_LVDS, "ivch", "ivch_methods",
+    {I830_OUTPUT_DVO_LVDS, "ivch", "ivch_methods",
      0x84, ivch_symbols, NULL, NULL, NULL},
-    {I830_DVO_CHIP_LVDS, "ivch", "ivch_methods",
+    {I830_OUTPUT_DVO_LVDS, "ivch", "ivch_methods",
      0xc4, ivch_symbols, NULL, NULL, NULL},
     */
     /*
-    { I830_DVO_CHIP_LVDS, "ch7017", "ch7017_methods",
+    { I830_OUTPUT_DVO_LVDS, "ch7017", "ch7017_methods",
       0xea, ch7017_symbols, NULL, NULL, NULL }
     */
 };
@@ -351,7 +351,6 @@ i830_dvo_init(ScrnInfoPtr pScrn)
     intel_output = xnfcalloc (sizeof (I830OutputPrivateRec), 1);
     if (!intel_output)
 	return;
-    intel_output->type = I830_OUTPUT_DVO;
 
     /* Set up the DDC bus */
     ret = I830I2CInit(pScrn, &intel_output->pDDCBus, GPIOD, "DVODDC_D");
@@ -374,7 +373,7 @@ i830_dvo_init(ScrnInfoPtr pScrn)
 	ret_ptr = NULL;
 	drv->vid_rec = LoaderSymbol(drv->fntablename);
 
-	if (drv->type & I830_DVO_CHIP_LVDS)
+	if (drv->type == I830_OUTPUT_DVO_LVDS)
 	    gpio = GPIOB;
 	else
 	    gpio = GPIOE;
@@ -396,14 +395,29 @@ i830_dvo_init(ScrnInfoPtr pScrn)
 	    ret_ptr = drv->vid_rec->init(pI2CBus, drv->address);
 
 	if (ret_ptr != NULL) {
-	    xf86OutputPtr output;
+	    xf86OutputPtr output = NULL;
 
-	    if (drv->type & I830_DVO_CHIP_LVDS) {
+	    intel_output->type = drv->type;
+	    switch (drv->type) {
+	    case I830_OUTPUT_DVO_TMDS:
+		intel_output->pipe_mask = ((1 << 0) | (1 << 1));
+		intel_output->clone_mask = ((1 << I830_OUTPUT_ANALOG) |
+					    (1 << I830_OUTPUT_DVO_TMDS));
+		output = xf86OutputCreate(pScrn, &i830_dvo_output_funcs,
+					  "TMDS");
+		break;
+	    case I830_OUTPUT_DVO_LVDS:
+		intel_output->pipe_mask = (1 << 1);
+		intel_output->clone_mask = (1 << I830_OUTPUT_DVO_LVDS);
 		output = xf86OutputCreate(pScrn, &i830_dvo_output_funcs,
 					  "LVDS");
-	    } else {
+		break;
+	    case I830_OUTPUT_DVO_TVOUT:
+		intel_output->pipe_mask = (1 << 1);
+		intel_output->clone_mask = (1 << I830_OUTPUT_DVO_TVOUT);
 		output = xf86OutputCreate(pScrn, &i830_dvo_output_funcs,
-					  "TMDS");
+					  "TV");
+		break;
 	    }
 	    if (output == NULL) {
 		xf86DestroyI2CBusRec(pI2CBus, TRUE, TRUE);
diff --git a/src/i830_lvds.c b/src/i830_lvds.c
index e909812..566c868 100644
--- a/src/i830_lvds.c
+++ b/src/i830_lvds.c
@@ -445,6 +445,9 @@ i830_lvds_init(ScrnInfoPtr pScrn)
 	return;
     }
     intel_output->type = I830_OUTPUT_LVDS;
+    intel_output->pipe_mask = (1 << 1);
+    intel_output->clone_mask = (1 << I830_OUTPUT_LVDS);
+    
     output->driver_private = intel_output;
     output->subpixel_order = SubPixelHorizontalRGB;
     output->interlaceAllowed = FALSE;
diff --git a/src/i830_sdvo.c b/src/i830_sdvo.c
index 43b55a0..24c9c99 100644
--- a/src/i830_sdvo.c
+++ b/src/i830_sdvo.c
@@ -1179,6 +1179,8 @@ i830_sdvo_init(ScrnInfoPtr pScrn, int ou
     
     dev_priv = (struct i830_sdvo_priv *) (intel_output + 1);
     intel_output->type = I830_OUTPUT_SDVO;
+    intel_output->pipe_mask = ((1 << 0) | (1 << 1));
+    intel_output->clone_mask = (1 << I830_OUTPUT_SDVO);
 
     /* While it's the same bus, we just initialize a new copy to avoid trouble
      * with tracking refcounting ourselves, since the XFree86 DDX bits don't.
diff --git a/src/i830_tv.c b/src/i830_tv.c
index 336214f..b95986f 100644
--- a/src/i830_tv.c
+++ b/src/i830_tv.c
@@ -1669,6 +1669,8 @@ i830_tv_init(ScrnInfoPtr pScrn)
     }
     dev_priv = (struct i830_tv_priv *) (intel_output + 1);
     intel_output->type = I830_OUTPUT_TVOUT;
+    intel_output->pipe_mask = ((1 << 0) | (1 << 1));
+    intel_output->clone_mask = (1 << I830_OUTPUT_TVOUT);
     intel_output->dev_priv = dev_priv;
     dev_priv->type = TV_TYPE_UNKNOWN;
 
diff-tree a441954630c6cdabbf463bfc3404160f97a04b4f (from c0daa0a982e7074af4b50653b4a45b0a6352b43d)
Author: Keith Packard <keithp at dulcimer.keithp.com>
Date:   Thu May 17 14:11:49 2007 -0700

    Enable panel fitter on ivch DVO.
    
    Using BIOS source code as a guide, set up the panel fitter on the ivch. This
    involves setting the pipe to the panel fixed mode, the DVO to the source
    size and assigning vertical and horizontal scaling factors in the ivch
    itself.

diff --git a/src/ivch/ivch.c b/src/ivch/ivch.c
index a76e339..e0755c0 100644
--- a/src/ivch/ivch.c
+++ b/src/ivch/ivch.c
@@ -157,8 +157,6 @@ ivch_init(I2CBusPtr b, I2CSlaveAddr addr
     struct	ivch_priv *priv;
     CARD16	temp;
 
-    xf86DrvMsg(b->scrnIndex, X_INFO, "detecting ivch\n");
-
     priv = xcalloc(1, sizeof(struct ivch_priv));
     if (priv == NULL)
 	return NULL;
@@ -191,10 +189,6 @@ ivch_init(I2CBusPtr b, I2CSlaveAddr addr
 	goto out;
     }
 
-    ivch_read (priv, VR01, &temp); xf86DrvMsg (priv->d.pI2CBus->scrnIndex, X_INFO,
-					       "ivch VR01 0x%x\n", temp);
-    ivch_read (priv, VR40, &temp); xf86DrvMsg (priv->d.pI2CBus->scrnIndex, X_INFO,
-					       "ivch VR40 0x%x\n", temp);
     return priv;
 
 out:
@@ -250,7 +244,9 @@ ivch_mode_valid(I2CDevPtr d, DisplayMode
 
     if (panel_fixed_mode)
     {
-	if (!xf86ModesEqual (mode, panel_fixed_mode))
+	if (mode->HDisplay > panel_fixed_mode->HDisplay)
+	    return MODE_PANEL;
+	if (mode->VDisplay > panel_fixed_mode->VDisplay)
 	    return MODE_PANEL;
     }
     
@@ -280,8 +276,6 @@ ivch_dpms(I2CDevPtr d, int mode)
     else
 	vr01 &= ~(VR01_LCD_ENABLE | VR01_DVO_ENABLE);
 
-    vr01 &= ~VR01_PANEL_FIT_ENABLE;
-
     ivch_write(priv, VR01, vr01);
 
     /* Wait for the panel to make its state transition */
@@ -300,6 +294,27 @@ ivch_dpms(I2CDevPtr d, int mode)
 static Bool
 ivch_mode_fixup(I2CDevPtr d, DisplayModePtr mode, DisplayModePtr adjusted_mode)
 {
+    struct ivch_priv	*priv = d->DriverPrivate.ptr;
+    DisplayModePtr	panel_fixed_mode = priv->panel_fixed_mode;
+    
+    /* If we have timings from the BIOS for the panel, put them in
+     * to the adjusted mode.  The CRTC will be set up for this mode,
+     * with the panel scaling set up to source from the H/VDisplay
+     * of the original mode.
+     */
+    if (panel_fixed_mode != NULL) {
+	adjusted_mode->HDisplay = panel_fixed_mode->HDisplay;
+	adjusted_mode->HSyncStart = panel_fixed_mode->HSyncStart;
+	adjusted_mode->HSyncEnd = panel_fixed_mode->HSyncEnd;
+	adjusted_mode->HTotal = panel_fixed_mode->HTotal;
+	adjusted_mode->VDisplay = panel_fixed_mode->VDisplay;
+	adjusted_mode->VSyncStart = panel_fixed_mode->VSyncStart;
+	adjusted_mode->VSyncEnd = panel_fixed_mode->VSyncEnd;
+	adjusted_mode->VTotal = panel_fixed_mode->VTotal;
+	adjusted_mode->Clock = panel_fixed_mode->Clock;
+	xf86SetModeCrtc(adjusted_mode, INTERLACE_HALVE_V);
+    }
+
     return TRUE;
 }
     
@@ -310,22 +325,32 @@ ivch_mode_set(I2CDevPtr d, DisplayModePt
     CARD16		vr40 = 0;
     CARD16		vr01;
 
-    ivch_read (priv, VR01, &vr01);
-    /* Disable panel fitting for now, until we can test. */
-    if (adjusted_mode->HDisplay != priv->width || adjusted_mode->VDisplay != priv->height)
+    vr01 = 0;
+    vr40 = (VR40_STALL_ENABLE |
+	    VR40_VERTICAL_INTERP_ENABLE |
+	    VR40_HORIZONTAL_INTERP_ENABLE);
+    
+    if (mode->HDisplay != adjusted_mode->HDisplay || 
+	mode->VDisplay != adjusted_mode->VDisplay)
     {
+	CARD16	x_ratio, y_ratio;
+	
 	vr01 |= VR01_PANEL_FIT_ENABLE;
-	vr40 |= VR40_AUTO_RATIO_ENABLE;
+	vr40 |= VR40_CLOCK_GATING_ENABLE;
+	x_ratio = (((mode->HDisplay - 1) << 16) / (adjusted_mode->HDisplay - 1)) >> 2;
+	y_ratio = (((mode->VDisplay - 1) << 16) / (adjusted_mode->VDisplay - 1)) >> 2;
+	ivch_write (priv, VR42, x_ratio);
+	ivch_write (priv, VR41, y_ratio);
     }
     else
     {
 	vr01 &= ~VR01_PANEL_FIT_ENABLE;
-	vr40 &= ~VR40_AUTO_RATIO_ENABLE;
+	vr40 &= ~VR40_CLOCK_GATING_ENABLE;
     }
+    vr40 &= ~VR40_AUTO_RATIO_ENABLE;
 
     ivch_write(priv, VR01, vr01);
     ivch_write(priv, VR40, vr40);
-    ivch_dpms(d, DPMSModeOn);
 
     ivch_dump_regs(d);
 }
diff --git a/src/ivch/ivch_reg.h b/src/ivch/ivch_reg.h
index fe5507a..bcd8c56 100644
--- a/src/ivch/ivch_reg.h
+++ b/src/ivch/ivch_reg.h
@@ -46,6 +46,9 @@
  * @{
  */
 #define VR01		0x01
+/**
+ * Enable the panel fitter
+ */
 # define VR01_PANEL_FIT_ENABLE		(1 << 3)
 /**
  * Enables the LCD display.
@@ -185,26 +188,33 @@
  */
 #define VR40		0x40
 # define VR40_STALL_ENABLE		(1 << 13)
-# define VR40_VERTICAL_INTERP_ENABLE	(1 << 11)
+# define VR40_VERTICAL_INTERP_ENABLE	(1 << 12)
+# define VR40_ENHANCED_PANEL_FITTING	(1 << 11)
 # define VR40_HORIZONTAL_INTERP_ENABLE	(1 << 10)
 # define VR40_AUTO_RATIO_ENABLE		(1 << 9)
-# define VR40_PANEL_FIT_ENABLE		(1 << 8)
+# define VR40_CLOCK_GATING_ENABLE	(1 << 8)
 /** @} */
 
 /** @defgroup VR41 Panel Fitting Vertical Ratio
  * @{
+ *
+ * (((image_height - 1) << 16) / ((panel_height - 1))) >> 2
  */
 /** @} */
+#define VR41		0x41
 
 /** @defgroup VR42 Panel Fitting Horizontal Ratio
  * @{
+ * (((image_width - 1) << 16) / ((panel_width - 1))) >> 2
  */
 /** @} */
+#define VR42		0x42
 
 /** @defgroup VR43 Horizontal Image Size
  * @{
  */
 /** @} */
+#define VR43		0x43
 
 /** @defgroup VR44 Panel Fitting Coefficient 0
  * @{
diff-tree c0daa0a982e7074af4b50653b4a45b0a6352b43d (from b28817a87a1608e849e4a9a736dda43533a84b0c)
Author: Keith Packard <keithp at dulcimer.keithp.com>
Date:   Wed May 16 14:02:00 2007 -0700

    Change DVO module interface to pass more state across. Fix IVCH display.
    
    The DVO module interface reflected most of the xf86Output API to the
    underlying functions; finish that work given the changes that have since
    occurred in the xf86Output API.
    
    Move the LVDS-specific code into the IVCH module and make that work on the
    Thinkpad X30 (an i830-based laptop). Panel scaling does not work yet.

diff --git a/src/ch7017/ch7017.c b/src/ch7017/ch7017.c
index 7070c7d..8e3a6ef 100644
--- a/src/ch7017/ch7017.c
+++ b/src/ch7017/ch7017.c
@@ -144,7 +144,7 @@ ch7017_mode_valid(I2CDevPtr d, DisplayMo
 }
 
 static void
-ch7017_mode_set(I2CDevPtr d, DisplayModePtr mode)
+ch7017_mode_set(I2CDevPtr d, DisplayModePtr mode, DisplayModePtr adjusted_mode)
 {
     struct ch7017_priv *priv = d->DriverPrivate.ptr;
     CARD8 lvds_pll_feedback_div, lvds_pll_vco_control;
diff --git a/src/ch7xxx/ch7xxx.c b/src/ch7xxx/ch7xxx.c
index 0a96555..09a9627 100644
--- a/src/ch7xxx/ch7xxx.c
+++ b/src/ch7xxx/ch7xxx.c
@@ -206,7 +206,7 @@ ch7xxx_mode_valid(I2CDevPtr d, DisplayMo
 }
 
 static void
-ch7xxx_mode_set(I2CDevPtr d, DisplayModePtr mode)
+ch7xxx_mode_set(I2CDevPtr d, DisplayModePtr mode, DisplayModePtr adjusted_mode)
 {
     struct ch7xxx_priv *dev_priv = d->DriverPrivate.ptr;
     CARD8 tvco, tpcp, tpd, tlpf, idf;
diff --git a/src/i2c_vid.h b/src/i2c_vid.h
index 3be394d..1a21fca 100644
--- a/src/i2c_vid.h
+++ b/src/i2c_vid.h
@@ -1,16 +1,142 @@
-/* this needs to go in the server */
+/*
+ * Copyright © 2006 Eric Anholt
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  The copyright holders make no representations
+ * about the suitability of this software for any purpose.  It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
 #ifndef I2C_VID_H
 #define I2C_VID_H
+#include <randrstr.h>
 
 typedef struct _I830I2CVidOutputRec {
+    /**
+     * Initialize the device at startup time.
+     * Returns NULL if the device does not exist.
+     */
     void *(*init)(I2CBusPtr b, I2CSlaveAddr addr);
-    xf86OutputStatus (*detect)(I2CDevPtr d);
-    ModeStatus (*mode_valid)(I2CDevPtr d, DisplayModePtr mode);
-    void (*mode_set)(I2CDevPtr d, DisplayModePtr mode);
+    
+    /**
+     * Setup the device for use, after the relevant output has been created
+     */
+    Bool
+    (*setup) (I2CDevPtr d, xf86OutputPtr output);
+
+    /**
+     * Called to allow the output a chance to create properties after the
+     * RandR objects have been created.
+     */
+    void
+    (*create_resources)(I2CDevPtr d);
+
+    /**
+     * Turns the output on/off, or sets intermediate power levels if available.
+     *
+     * Unsupported intermediate modes drop to the lower power setting.  If the
+     * mode is DPMSModeOff, the output must be disabled, as the DPLL may be
+     * disabled afterwards.
+     */
     void (*dpms)(I2CDevPtr d, int mode);
-    void (*dump_regs)(I2CDevPtr d);
+    
+    /**
+     * Saves the output's state for restoration on VT switch.
+     */
     void (*save)(I2CDevPtr d);
+
+    /**
+     * Restore's the output's state at VT switch.
+     */
     void (*restore)(I2CDevPtr d);
+
+    /**
+     * Callback for testing a video mode for a given output.
+     *
+     * This function should only check for cases where a mode can't be supported
+     * on the output specifically, and not represent generic CRTC limitations.
+     *
+     * \return MODE_OK if the mode is valid, or another MODE_* otherwise.
+     */
+    int (*mode_valid)(I2CDevPtr d, DisplayModePtr mode);
+
+    /**
+     * Callback to adjust the mode to be set in the CRTC.
+     *
+     * This allows an output to adjust the clock or even the entire set of
+     * timings, which is used for panels with fixed timings or for
+     * buses with clock limitations.
+     */
+    Bool (*mode_fixup)(I2CDevPtr d, DisplayModePtr mode, DisplayModePtr adjusted_mode);
+
+    /**
+     * Callback for preparing mode changes on an output
+     */
+    void (*prepare)(I2CDevPtr d);
+
+    /**
+     * Callback for committing mode changes on an output
+     */
+    void (*commit)(I2CDevPtr d);
+    
+    /**
+     * Callback for setting up a video mode after fixups have been made.
+     *
+     * This is only called while the output is disabled.  The dpms callback
+     * must be all that's necessary for the output, to turn the output on
+     * after this function is called.
+     */
+    void (*mode_set)(I2CDevPtr d, DisplayModePtr mode, DisplayModePtr adjusted_mode);
+    
+    /**
+     * Probe for a connected output, and return detect_status.
+     */
+    xf86OutputStatus (*detect)(I2CDevPtr d);
+
+    /**
+     * Query the device for the modes it provides.
+     *
+     * This function may also update MonInfo, mm_width, and mm_height.
+     *
+     * \return singly-linked list of modes or NULL if no modes found.
+     */
+    DisplayModePtr
+    (*get_modes)(I2CDevPtr d);
+    
+#ifdef RANDR_12_INTERFACE
+    /**
+     * Callback when an output's property has changed.
+     */
+    Bool
+    (*set_property)(I2CDevPtr d, Atom property, RRPropertyValuePtr value);
+#endif
+
+    /**
+     * Clean up driver-specific bits of the output
+     */
+    void (*destroy) (I2CDevPtr d);
+
+    /**
+     * Debugging hook to dump device registers to log file
+     */
+    void (*dump_regs)(I2CDevPtr d);
 } I830I2CVidOutputRec, *I830I2CVidOutputPtr;
 
+/* XXX change this name to avoid driver-specific prefix */
+DisplayModePtr
+i830_dvo_get_current_mode (xf86OutputPtr output);
+
 #endif
diff --git a/src/i830.h b/src/i830.h
index c91be79..0fe5d41 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -205,6 +205,7 @@ struct _I830DVODriver {
    int type;
    char *modulename;
    char *fntablename;
+   unsigned int dvo_reg;
    int address;
    const char **symbols;
    I830I2CVidOutputRec *vid_rec;
@@ -466,13 +467,6 @@ typedef struct _I830Rec {
 
    int ddc2;
 
-   /* The BIOS's fixed timings for the LVDS */
-   DisplayModePtr panel_fixed_mode;
-
-   int backlight_duty_cycle;  /* restore backlight to this value */
-   
-   Bool panel_wants_dither;
-
    CARD32 saveDSPACNTR;
    CARD32 saveDSPBCNTR;
    CARD32 savePIPEACONF;
@@ -637,9 +631,6 @@ extern Bool I830I2CInit(ScrnInfoPtr pScr
 /* return a mask of output indices matching outputs against type_mask */
 int i830_output_clones (ScrnInfoPtr pScrn, int type_mask);
 
-/* i830_bios.c */
-DisplayModePtr i830_bios_get_panel_mode(ScrnInfoPtr pScrn);
-
 /* i830_display.c */
 Bool
 i830PipeHasType (xf86CrtcPtr crtc, int type);
diff --git a/src/i830_dvo.c b/src/i830_dvo.c
index 129651c..b69105e 100644
--- a/src/i830_dvo.c
+++ b/src/i830_dvo.c
@@ -60,11 +60,11 @@ static const char *ch7017_symbols[] = {
 /* driver list */
 struct _I830DVODriver i830_dvo_drivers[] =
 {
-    {I830_DVO_CHIP_TMDS, "sil164", "SIL164VidOutput",
+    {I830_DVO_CHIP_TMDS, "sil164", "SIL164VidOutput", DVOC,
      (SIL164_ADDR_1<<1), SIL164Symbols, NULL , NULL, NULL},
-    {I830_DVO_CHIP_TMDS | I830_DVO_CHIP_TVOUT, "ch7xxx", "CH7xxxVidOutput",
+    {I830_DVO_CHIP_TMDS | I830_DVO_CHIP_TVOUT, "ch7xxx", "CH7xxxVidOutput", DVOC,
      (CH7xxx_ADDR_1<<1), CH7xxxSymbols, NULL , NULL, NULL},
-    {I830_DVO_CHIP_LVDS, "ivch", "ivch_methods",
+    {I830_DVO_CHIP_LVDS, "ivch", "ivch_methods", DVOA,
      0x04, ivch_symbols, NULL, NULL, NULL},
     /*
     {I830_DVO_CHIP_LVDS, "ivch", "ivch_methods",
@@ -88,20 +88,18 @@ i830_dvo_dpms(xf86OutputPtr output, int 
     ScrnInfoPtr		    pScrn = output->scrn;
     I830Ptr		    pI830 = I830PTR(pScrn);
     I830OutputPrivatePtr    intel_output = output->driver_private;
-    void *		    dev_priv = intel_output->i2c_drv->dev_priv;
-    unsigned int	    dvo_reg;
-
-    if (intel_output->i2c_drv->type & I830_DVO_CHIP_LVDS)
-	dvo_reg = DVOA;
-    else
-	dvo_reg = DVOC;
+    struct _I830DVODriver   *drv = intel_output->i2c_drv;
+    void *		    dev_priv = drv->dev_priv;
+    unsigned int	    dvo_reg = drv->dvo_reg;
 
     if (mode == DPMSModeOn) {
 	OUTREG(dvo_reg, INREG(dvo_reg) | DVO_ENABLE);
+	POSTING_READ(dvo_reg);
 	(*intel_output->i2c_drv->vid_rec->dpms)(dev_priv, mode);
     } else {
 	(*intel_output->i2c_drv->vid_rec->dpms)(dev_priv, mode);
 	OUTREG(dvo_reg, INREG(dvo_reg) & ~DVO_ENABLE);
+	POSTING_READ(dvo_reg);
     }
 }
 
@@ -131,18 +129,18 @@ i830_dvo_restore(xf86OutputPtr output)
     I830OutputPrivatePtr    intel_output = output->driver_private;
     void *		    dev_priv = intel_output->i2c_drv->dev_priv;
 
+    (*intel_output->i2c_drv->vid_rec->restore)(dev_priv);
+
     OUTREG(DVOA, pI830->saveDVOA);
     OUTREG(DVOB, pI830->saveDVOB);
     OUTREG(DVOC, pI830->saveDVOC);
-
-    (*intel_output->i2c_drv->vid_rec->restore)(dev_priv);
 }
 
 static int
 i830_dvo_mode_valid(xf86OutputPtr output, DisplayModePtr pMode)
 {
     I830OutputPrivatePtr    intel_output = output->driver_private;
-    void *dev_priv = intel_output->i2c_drv->dev_priv;
+    void		    *dev_priv = intel_output->i2c_drv->dev_priv;
 
     if (pMode->Flags & V_DBLSCAN)
 	return MODE_NO_DBLESCAN;
@@ -156,8 +154,11 @@ static Bool
 i830_dvo_mode_fixup(xf86OutputPtr output, DisplayModePtr mode,
 		    DisplayModePtr adjusted_mode)
 {
-    /* XXX: Hook this up to a DVO driver function */
+    I830OutputPrivatePtr    intel_output = output->driver_private;
 
+    if (intel_output->i2c_drv->vid_rec->mode_fixup)
+	return intel_output->i2c_drv->vid_rec->mode_fixup (intel_output->i2c_drv->dev_priv,
+							   mode, adjusted_mode);
     return TRUE;
 }
 
@@ -170,21 +171,26 @@ i830_dvo_mode_set(xf86OutputPtr output, 
     xf86CrtcPtr	    crtc = output->crtc;
     I830CrtcPrivatePtr	    intel_crtc = crtc->driver_private;
     I830OutputPrivatePtr    intel_output = output->driver_private;
+    struct _I830DVODriver   *drv = intel_output->i2c_drv;
     int			    pipe = intel_crtc->pipe;
     CARD32		    dvo;
-    unsigned int	    dvo_reg, dvo_srcdim_reg;
+    unsigned int	    dvo_reg = drv->dvo_reg, dvo_srcdim_reg;
     int			    dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B;
 
-    if (intel_output->i2c_drv->type & I830_DVO_CHIP_LVDS) {
-	dvo_reg = DVOA;
+    switch (dvo_reg) {
+    case DVOA:
 	dvo_srcdim_reg = DVOA_SRCDIM;
-    } else {
-	dvo_reg = DVOC;
+	break;
+    case DVOB:
+	dvo_srcdim_reg = DVOB_SRCDIM;
+	break;
+    case DVOC:
 	dvo_srcdim_reg = DVOC_SRCDIM;
+	break;
     }
 
     intel_output->i2c_drv->vid_rec->mode_set(intel_output->i2c_drv->dev_priv,
-					     mode);
+					     mode, adjusted_mode);
 
     /* Save the data order, since I don't know what it should be set to. */
     dvo = INREG(dvo_reg) & (DVO_PRESERVE_MASK | DVO_DATA_ORDER_GBRG);
@@ -227,8 +233,6 @@ i830_dvo_detect(xf86OutputPtr output)
 static DisplayModePtr
 i830_dvo_get_modes(xf86OutputPtr output)
 {
-    ScrnInfoPtr		    pScrn = output->scrn;
-    I830Ptr		    pI830 = I830PTR(pScrn);
     I830OutputPrivatePtr    intel_output = output->driver_private;
     DisplayModePtr	    modes;
 
@@ -241,11 +245,11 @@ i830_dvo_get_modes(xf86OutputPtr output)
     if (modes != NULL)
 	return modes;
 
-    if (intel_output->i2c_drv->type & I830_DVO_CHIP_LVDS &&
-	pI830->panel_fixed_mode != NULL)
+    if (intel_output->i2c_drv->vid_rec->get_modes)
     {
-	xf86PrintModeline(pScrn->scrnIndex, pI830->panel_fixed_mode);
-	return xf86DuplicateMode(pI830->panel_fixed_mode);
+	modes = intel_output->i2c_drv->vid_rec->get_modes (intel_output->i2c_drv->dev_priv);
+	if (modes != NULL)
+	    return modes;
     }
 
     return NULL;
@@ -258,11 +262,12 @@ i830_dvo_destroy (xf86OutputPtr output)
 
     if (intel_output)
     {
+	if (intel_output->i2c_drv->vid_rec->destroy)
+	    intel_output->i2c_drv->vid_rec->destroy (intel_output->i2c_drv->dev_priv);
 	if (intel_output->pI2CBus)
 	    xf86DestroyI2CBusRec (intel_output->pI2CBus, TRUE, TRUE);
 	if (intel_output->pDDCBus)
 	    xf86DestroyI2CBusRec (intel_output->pDDCBus, TRUE, TRUE);
-	/* XXX sub module cleanup? */
 	xfree (intel_output);
     }
 }
@@ -287,35 +292,49 @@ static const xf86OutputFuncsRec i830_dvo
  * Other chips with DVO LVDS will need to extend this to deal with the LVDS
  * chip being on DVOB/C and having multiple pipes.
  */
-static void
-i830_dvo_get_panel_timings(xf86OutputPtr output)
+DisplayModePtr
+i830_dvo_get_current_mode (xf86OutputPtr output)
 {
     ScrnInfoPtr		    pScrn = output->scrn;
+    I830OutputPrivatePtr    intel_output = output->driver_private;
     I830Ptr		    pI830 = I830PTR(pScrn);
-    CARD32 dvoa = INREG(DVOA);
-
-    if (!IS_I830(pI830))
-	return;
+    struct _I830DVODriver   *drv = intel_output->i2c_drv;
+    unsigned int	    dvo_reg = drv->dvo_reg;
+    CARD32		    dvo = INREG(dvo_reg);
+    DisplayModePtr    	    mode = NULL;
 
-    assert(pI830->fixed_panel_mode == NULL);
-
-    /* If the DVOA port is active, that'll be the LVDS, so we can pull out
+    /* If the DVO port is active, that'll be the LVDS, so we can pull out
      * its timings to get how the BIOS set up the panel.
      */
-    if (dvoa & DVO_ENABLE) {
-	xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
-	int pipe = (dvoa & DVO_PIPE_B_SELECT) ? 1 : 0;
-	xf86CrtcPtr crtc = xf86_config->crtc[pipe];
-
-	pI830->panel_fixed_mode = i830_crtc_mode_get(pScrn, crtc);
-	if (pI830->panel_fixed_mode != NULL)
-	    pI830->panel_fixed_mode->type |= M_T_PREFERRED;
-
-	if (dvoa & DVO_HSYNC_ACTIVE_HIGH)
-	    pI830->panel_fixed_mode->Flags |= V_PHSYNC;
-	if (dvoa & DVO_VSYNC_ACTIVE_HIGH)
-	    pI830->panel_fixed_mode->Flags |= V_PVSYNC;
+    if (dvo & DVO_ENABLE) 
+    {
+	xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+	int		    pipe = (dvo & DVO_PIPE_B_SELECT) ? 1 : 0;
+	int		    c;
+
+	for (c = 0; c < xf86_config->num_crtc; c++)
+	{
+	    xf86CrtcPtr		crtc = xf86_config->crtc[c];
+	    I830CrtcPrivatePtr	intel_crtc = crtc->driver_private;
+
+	    if (intel_crtc->pipe == pipe)
+	    {
+		mode = i830_crtc_mode_get(pScrn, crtc);
+
+		if (mode)
+		{
+		    mode->type |= M_T_PREFERRED;
+
+		    if (dvo & DVO_HSYNC_ACTIVE_HIGH)
+			mode->Flags |= V_PHSYNC;
+		    if (dvo & DVO_VSYNC_ACTIVE_HIGH)
+			mode->Flags |= V_PVSYNC;
+		}
+		break;
+	    }
+	}
     }
+    return mode;
 }
 
 void
@@ -394,9 +413,6 @@ i830_dvo_init(ScrnInfoPtr pScrn)
 		return;
 	    }
 
-	    if (drv->type & I830_DVO_CHIP_LVDS)
-		i830_dvo_get_panel_timings(output);
-
 	    output->driver_private = intel_output;
 	    output->subpixel_order = SubPixelHorizontalRGB;
 	    output->interlaceAllowed = FALSE;
@@ -405,6 +421,7 @@ i830_dvo_init(ScrnInfoPtr pScrn)
 	    drv->dev_priv = ret_ptr;
 	    intel_output->i2c_drv = drv;
 	    intel_output->pI2CBus = pI2CBus;
+	    drv->vid_rec->setup (drv->dev_priv, output);
 	    return;
 	}
 	xf86UnloadSubModule(drv->modhandle);
diff --git a/src/i830_lvds.c b/src/i830_lvds.c
index d16eccb..e909812 100644
--- a/src/i830_lvds.c
+++ b/src/i830_lvds.c
@@ -35,14 +35,27 @@
 #include "i830_display.h"
 #include "X11/Xatom.h"
 
+struct i830_lvds_priv {
+    /* The BIOS's fixed timings for the LVDS */
+    DisplayModePtr panel_fixed_mode;
+    
+    /* The panel needs dithering enabled */
+    Bool	    panel_wants_dither;
+
+    /* restore backlight to this value */
+    int		    backlight_duty_cycle;
+};
+
+
 /**
  * Sets the backlight level.
  *
  * \param level backlight level, from 0 to i830_lvds_get_max_backlight().
  */
 static void
-i830_lvds_set_backlight(ScrnInfoPtr pScrn, int level)
+i830_lvds_set_backlight(xf86OutputPtr output, int level)
 {
+    ScrnInfoPtr pScrn = output->scrn;
     I830Ptr pI830 = I830PTR(pScrn);
     CARD32 blc_pwm_ctl;
 
@@ -54,9 +67,10 @@ i830_lvds_set_backlight(ScrnInfoPtr pScr
  * Returns the maximum level of the backlight duty cycle field.
  */
 static CARD32
-i830_lvds_get_max_backlight(ScrnInfoPtr pScrn)
+i830_lvds_get_max_backlight(xf86OutputPtr output)
 {
-    I830Ptr pI830 = I830PTR(pScrn);
+    ScrnInfoPtr pScrn = output->scrn;
+    I830Ptr	pI830 = I830PTR(pScrn);
     
     return ((INREG(BLC_PWM_CTL) & BACKLIGHT_MODULATION_FREQ_MASK) >>
 	BACKLIGHT_MODULATION_FREQ_SHIFT) * 2;
@@ -66,10 +80,13 @@ i830_lvds_get_max_backlight(ScrnInfoPtr 
  * Sets the power state for the panel.
  */
 static void
-i830SetLVDSPanelPower(ScrnInfoPtr pScrn, Bool on)
+i830SetLVDSPanelPower(xf86OutputPtr output, Bool on)
 {
-    I830Ptr pI830 = I830PTR(pScrn);
-    CARD32 pp_status;
+    I830OutputPrivatePtr    intel_output = output->driver_private;
+    struct i830_lvds_priv   *dev_priv = intel_output->dev_priv;
+    ScrnInfoPtr		    pScrn = output->scrn;
+    I830Ptr		    pI830 = I830PTR(pScrn);
+    CARD32		    pp_status;
 
     if (on) {
 	OUTREG(PP_CONTROL, INREG(PP_CONTROL) | POWER_TARGET_ON);
@@ -77,9 +94,9 @@ i830SetLVDSPanelPower(ScrnInfoPtr pScrn,
 	    pp_status = INREG(PP_STATUS);
 	} while ((pp_status & PP_ON) == 0);
 
-	i830_lvds_set_backlight(pScrn, pI830->backlight_duty_cycle);
+	i830_lvds_set_backlight(output, dev_priv->backlight_duty_cycle);
     } else {
-	i830_lvds_set_backlight(pScrn, 0);
+	i830_lvds_set_backlight(output, 0);
 
 	OUTREG(PP_CONTROL, INREG(PP_CONTROL) & ~POWER_TARGET_ON);
 	do {
@@ -91,12 +108,10 @@ i830SetLVDSPanelPower(ScrnInfoPtr pScrn,
 static void
 i830_lvds_dpms (xf86OutputPtr output, int mode)
 {
-    ScrnInfoPtr	pScrn = output->scrn;
-
     if (mode == DPMSModeOn)
-	i830SetLVDSPanelPower(pScrn, TRUE);
+	i830SetLVDSPanelPower(output, TRUE);
     else
-	i830SetLVDSPanelPower(pScrn, FALSE);
+	i830SetLVDSPanelPower(output, FALSE);
 
     /* XXX: We never power down the LVDS pairs. */
 }
@@ -104,22 +119,24 @@ i830_lvds_dpms (xf86OutputPtr output, in
 static void
 i830_lvds_save (xf86OutputPtr output)
 {
-    ScrnInfoPtr	pScrn = output->scrn;
-    I830Ptr	pI830 = I830PTR(pScrn);
+    I830OutputPrivatePtr    intel_output = output->driver_private;
+    struct i830_lvds_priv   *dev_priv = intel_output->dev_priv;
+    ScrnInfoPtr		    pScrn = output->scrn;
+    I830Ptr		    pI830 = I830PTR(pScrn);
 
     pI830->savePP_ON = INREG(LVDSPP_ON);
     pI830->savePP_OFF = INREG(LVDSPP_OFF);
     pI830->savePP_CONTROL = INREG(PP_CONTROL);
     pI830->savePP_CYCLE = INREG(PP_CYCLE);
     pI830->saveBLC_PWM_CTL = INREG(BLC_PWM_CTL);
-    pI830->backlight_duty_cycle = (pI830->saveBLC_PWM_CTL &
-				   BACKLIGHT_DUTY_CYCLE_MASK);
+    dev_priv->backlight_duty_cycle = (pI830->saveBLC_PWM_CTL &
+				      BACKLIGHT_DUTY_CYCLE_MASK);
 
     /*
      * If the light is off at server startup, just make it full brightness
      */
-    if (pI830->backlight_duty_cycle == 0)
-	pI830->backlight_duty_cycle = i830_lvds_get_max_backlight(pScrn);
+    if (dev_priv->backlight_duty_cycle == 0)
+	dev_priv->backlight_duty_cycle = i830_lvds_get_max_backlight(output);
 }
 
 static void
@@ -134,17 +151,17 @@ i830_lvds_restore(xf86OutputPtr output)
     OUTREG(PP_CYCLE, pI830->savePP_CYCLE);
     OUTREG(PP_CONTROL, pI830->savePP_CONTROL);
     if (pI830->savePP_CONTROL & POWER_TARGET_ON)
-	i830SetLVDSPanelPower(pScrn, TRUE);
+	i830SetLVDSPanelPower(output, TRUE);
     else
-	i830SetLVDSPanelPower(pScrn, FALSE);
+	i830SetLVDSPanelPower(output, FALSE);
 }
 
 static int
 i830_lvds_mode_valid(xf86OutputPtr output, DisplayModePtr pMode)
 {
-    ScrnInfoPtr pScrn = output->scrn;
-    I830Ptr pI830 = I830PTR(pScrn);
-    DisplayModePtr  pFixedMode = pI830->panel_fixed_mode;
+    I830OutputPrivatePtr    intel_output = output->driver_private;
+    struct i830_lvds_priv   *dev_priv = intel_output->dev_priv;
+    DisplayModePtr	    pFixedMode = dev_priv->panel_fixed_mode;
 
     if (pFixedMode)
     {
@@ -161,10 +178,11 @@ static Bool
 i830_lvds_mode_fixup(xf86OutputPtr output, DisplayModePtr mode,
 		     DisplayModePtr adjusted_mode)
 {
-    ScrnInfoPtr pScrn = output->scrn;
-    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
-    I830Ptr pI830 = I830PTR(pScrn);
-    I830CrtcPrivatePtr intel_crtc = output->crtc->driver_private;
+    I830OutputPrivatePtr    intel_output = output->driver_private;
+    struct i830_lvds_priv   *dev_priv = intel_output->dev_priv;
+    ScrnInfoPtr		    pScrn = output->scrn;
+    xf86CrtcConfigPtr	    xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+    I830CrtcPrivatePtr	    intel_crtc = output->crtc->driver_private;
     int i;
 
     for (i = 0; i < xf86_config->num_output; i++) {
@@ -189,16 +207,16 @@ i830_lvds_mode_fixup(xf86OutputPtr outpu
      * with the panel scaling set up to source from the H/VDisplay
      * of the original mode.
      */
-    if (pI830->panel_fixed_mode != NULL) {
-	adjusted_mode->HDisplay = pI830->panel_fixed_mode->HDisplay;
-	adjusted_mode->HSyncStart = pI830->panel_fixed_mode->HSyncStart;
-	adjusted_mode->HSyncEnd = pI830->panel_fixed_mode->HSyncEnd;
-	adjusted_mode->HTotal = pI830->panel_fixed_mode->HTotal;
-	adjusted_mode->VDisplay = pI830->panel_fixed_mode->VDisplay;
-	adjusted_mode->VSyncStart = pI830->panel_fixed_mode->VSyncStart;
-	adjusted_mode->VSyncEnd = pI830->panel_fixed_mode->VSyncEnd;
-	adjusted_mode->VTotal = pI830->panel_fixed_mode->VTotal;
-	adjusted_mode->Clock = pI830->panel_fixed_mode->Clock;
+    if (dev_priv->panel_fixed_mode != NULL) {
+	adjusted_mode->HDisplay = dev_priv->panel_fixed_mode->HDisplay;
+	adjusted_mode->HSyncStart = dev_priv->panel_fixed_mode->HSyncStart;
+	adjusted_mode->HSyncEnd = dev_priv->panel_fixed_mode->HSyncEnd;
+	adjusted_mode->HTotal = dev_priv->panel_fixed_mode->HTotal;
+	adjusted_mode->VDisplay = dev_priv->panel_fixed_mode->VDisplay;
+	adjusted_mode->VSyncStart = dev_priv->panel_fixed_mode->VSyncStart;
+	adjusted_mode->VSyncEnd = dev_priv->panel_fixed_mode->VSyncEnd;
+	adjusted_mode->VTotal = dev_priv->panel_fixed_mode->VTotal;
+	adjusted_mode->Clock = dev_priv->panel_fixed_mode->Clock;
 	xf86SetModeCrtc(adjusted_mode, INTERLACE_HALVE_V);
     }
 
@@ -214,10 +232,12 @@ static void
 i830_lvds_mode_set(xf86OutputPtr output, DisplayModePtr mode,
 		   DisplayModePtr adjusted_mode)
 {
-    ScrnInfoPtr pScrn = output->scrn;
-    I830Ptr pI830 = I830PTR(pScrn);
-    I830CrtcPrivatePtr intel_crtc = output->crtc->driver_private;
-    CARD32 pfit_control;
+    I830OutputPrivatePtr    intel_output = output->driver_private;
+    struct i830_lvds_priv   *dev_priv = intel_output->dev_priv;
+    ScrnInfoPtr		    pScrn = output->scrn;
+    I830Ptr		    pI830 = I830PTR(pScrn);
+    I830CrtcPrivatePtr	    intel_crtc = output->crtc->driver_private;
+    CARD32		    pfit_control;
 
     /* The LVDS pin pair will already have been turned on in the
      * i830_crtc_mode_set since it has a large impact on the DPLL settings.
@@ -232,7 +252,7 @@ i830_lvds_mode_set(xf86OutputPtr output,
 		    VERT_INTERP_BILINEAR | HORIZ_INTERP_BILINEAR);
 
     if (!IS_I965G(pI830)) {
-	if (pI830->panel_wants_dither)
+	if (dev_priv->panel_wants_dither)
 	    pfit_control |= PANEL_8TO6_DITHER_ENABLE;
     } else {
 	pfit_control |= intel_crtc->pipe << PFIT_PIPE_SHIFT;
@@ -260,8 +280,7 @@ static DisplayModePtr
 i830_lvds_get_modes(xf86OutputPtr output)
 {
     I830OutputPrivatePtr    intel_output = output->driver_private;
-    ScrnInfoPtr		    pScrn = output->scrn;
-    I830Ptr		    pI830 = I830PTR(pScrn);
+    struct i830_lvds_priv   *dev_priv = intel_output->dev_priv;
     xf86MonPtr		    edid_mon;
     DisplayModePtr	    modes;
 
@@ -290,8 +309,8 @@ i830_lvds_get_modes(xf86OutputPtr output
 	}
     }
 
-    if (pI830->panel_fixed_mode != NULL)
-	return xf86DuplicateMode(pI830->panel_fixed_mode);
+    if (dev_priv->panel_fixed_mode != NULL)
+	return xf86DuplicateMode(dev_priv->panel_fixed_mode);
 
     return NULL;
 }
@@ -302,7 +321,12 @@ i830_lvds_destroy (xf86OutputPtr output)
     I830OutputPrivatePtr    intel_output = output->driver_private;
 
     if (intel_output)
+    {
+	struct i830_lvds_priv	*dev_priv = intel_output->dev_priv;
+	
+        xf86DeleteMode (&dev_priv->panel_fixed_mode, dev_priv->panel_fixed_mode);
 	xfree (intel_output);
+    }
 }
 
 #ifdef RANDR_12_INTERFACE
@@ -314,10 +338,11 @@ static void
 i830_lvds_create_resources(xf86OutputPtr output)
 {
 #ifdef RANDR_12_INTERFACE
-    ScrnInfoPtr pScrn = output->scrn;
-    I830Ptr pI830 = I830PTR(pScrn);
-    INT32 range[2];
-    int data, err;
+    I830OutputPrivatePtr    intel_output = output->driver_private;
+    struct i830_lvds_priv   *dev_priv = intel_output->dev_priv;
+    ScrnInfoPtr		    pScrn = output->scrn;
+    INT32		    range[2];
+    int			    data, err;
 
     /* Set up the backlight property, which takes effect immediately
      * and accepts values only within the range.
@@ -329,7 +354,7 @@ i830_lvds_create_resources(xf86OutputPtr
 	TRUE);
 
     range[0] = 0;
-    range[1] = i830_lvds_get_max_backlight(pScrn);
+    range[1] = i830_lvds_get_max_backlight(output);
     err = RRConfigureOutputProperty(output->randr_output, backlight_atom,
 				    FALSE, TRUE, FALSE, 2, range);
     if (err != 0) {
@@ -337,7 +362,7 @@ i830_lvds_create_resources(xf86OutputPtr
 		   "RRConfigureOutputProperty error, %d\n", err);
     }
     /* Set the current value of the backlight property */
-    data = pI830->backlight_duty_cycle;
+    data = dev_priv->backlight_duty_cycle;
     err = RRChangeOutputProperty(output->randr_output, backlight_atom,
 				 XA_INTEGER, 32, PropModeReplace, 1, &data,
 				 FALSE, TRUE);
@@ -354,8 +379,8 @@ static Bool
 i830_lvds_set_property(xf86OutputPtr output, Atom property,
 		       RRPropertyValuePtr value)
 {
-    ScrnInfoPtr pScrn = output->scrn;
-    I830Ptr pI830 = I830PTR(pScrn);
+    I830OutputPrivatePtr    intel_output = output->driver_private;
+    struct i830_lvds_priv   *dev_priv = intel_output->dev_priv;
     
     if (property == backlight_atom) {
 	INT32 val;
@@ -367,13 +392,13 @@ i830_lvds_set_property(xf86OutputPtr out
 	}
 
 	val = *(INT32 *)value->data;
-	if (val < 0 || val > i830_lvds_get_max_backlight(pScrn))
+	if (val < 0 || val > i830_lvds_get_max_backlight(output))
 	    return FALSE;
 
-	if (val != pI830->backlight_duty_cycle)
+	if (val != dev_priv->backlight_duty_cycle)
 	{
-	    i830_lvds_set_backlight(pScrn, val);
-	    pI830->backlight_duty_cycle = val;
+	    i830_lvds_set_backlight(output, val);
+	    dev_priv->backlight_duty_cycle = val;
 	}
 	return TRUE;
     }
@@ -407,11 +432,13 @@ i830_lvds_init(ScrnInfoPtr pScrn)
     xf86OutputPtr	    output;
     I830OutputPrivatePtr    intel_output;
     DisplayModePtr	    modes, scan, bios_mode;
+    struct i830_lvds_priv   *dev_priv;
 
     output = xf86OutputCreate (pScrn, &i830_lvds_output_funcs, "LVDS");
     if (!output)
 	return;
-    intel_output = xnfcalloc (sizeof (I830OutputPrivateRec), 1);
+    intel_output = xnfcalloc (sizeof (I830OutputPrivateRec) + 
+			      sizeof (struct i830_lvds_priv), 1);
     if (!intel_output)
     {
 	xf86OutputDestroy (output);
@@ -423,6 +450,9 @@ i830_lvds_init(ScrnInfoPtr pScrn)
     output->interlaceAllowed = FALSE;
     output->doubleScanAllowed = FALSE;
 
+    dev_priv = (struct i830_lvds_priv *) (intel_output + 1);
+    intel_output->dev_priv = dev_priv;
+
     /* Set up the LVDS DDC channel.  Most panels won't support it, but it can
      * be useful if available.
      */
@@ -444,7 +474,7 @@ i830_lvds_init(ScrnInfoPtr pScrn)
 	    scan->prev = scan->next;
 	if (scan->next != NULL)
 	    scan->next = scan->prev;
-	pI830->panel_fixed_mode = scan;
+	dev_priv->panel_fixed_mode = scan;
     }
     /* Delete the mode list */
     while (modes != NULL)
@@ -453,16 +483,16 @@ i830_lvds_init(ScrnInfoPtr pScrn)
     /* If we didn't get EDID, try checking if the panel is already turned on.
      * If so, assume that whatever is currently programmed is the correct mode.
      */
-    if (pI830->panel_fixed_mode == NULL) {
+    if (dev_priv->panel_fixed_mode == NULL) {
 	CARD32 lvds = INREG(LVDS);
 	int pipe = (lvds & LVDS_PIPEB_SELECT) ? 1 : 0;
 	xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
 	xf86CrtcPtr crtc = xf86_config->crtc[pipe];
 
 	if (lvds & LVDS_PORT_EN) {
-	    pI830->panel_fixed_mode = i830_crtc_mode_get(pScrn, crtc);
-	    if (pI830->panel_fixed_mode != NULL)
-		pI830->panel_fixed_mode->type |= M_T_PREFERRED;
+	    dev_priv->panel_fixed_mode = i830_crtc_mode_get(pScrn, crtc);
+	    if (dev_priv->panel_fixed_mode != NULL)
+		dev_priv->panel_fixed_mode->type |= M_T_PREFERRED;
 	}
     }
 
@@ -470,11 +500,11 @@ i830_lvds_init(ScrnInfoPtr pScrn)
      * the BIOS being unavailable or broken, but lack the configuration options
      * for now.
      */
-    bios_mode = i830_bios_get_panel_mode(pScrn);
+    bios_mode = i830_bios_get_panel_mode(pScrn, &dev_priv->panel_wants_dither);
     if (bios_mode != NULL) {
-	if (pI830->panel_fixed_mode != NULL) {
+	if (dev_priv->panel_fixed_mode != NULL) {
 	    if (pI830->debug_modes &&
-		!xf86ModesEqual(pI830->panel_fixed_mode, bios_mode))
+		!xf86ModesEqual(dev_priv->panel_fixed_mode, bios_mode))
 	    {
 		xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
 			   "BIOS panel mode data doesn't match probed data, "
@@ -482,12 +512,12 @@ i830_lvds_init(ScrnInfoPtr pScrn)
 		xf86DrvMsg(pScrn->scrnIndex, X_INFO, "BIOS mode:\n");
 		xf86PrintModeline(pScrn->scrnIndex, bios_mode);
 		xf86DrvMsg(pScrn->scrnIndex, X_INFO, "probed mode:\n");
-		xf86PrintModeline(pScrn->scrnIndex, pI830->panel_fixed_mode);
+		xf86PrintModeline(pScrn->scrnIndex, dev_priv->panel_fixed_mode);
 		xfree(bios_mode->name);
 		xfree(bios_mode);
 	    }
 	}  else {
-	    pI830->panel_fixed_mode = bios_mode;
+	    dev_priv->panel_fixed_mode = bios_mode;
 	}
     } else {
 	xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
@@ -513,9 +543,9 @@ i830_lvds_init(ScrnInfoPtr pScrn)
 	     * display.
 	     */
 
-	    if (pI830->panel_fixed_mode != NULL &&
-		pI830->panel_fixed_mode->HDisplay == 800 &&
-		pI830->panel_fixed_mode->VDisplay == 600)
+	    if (dev_priv->panel_fixed_mode != NULL &&
+		dev_priv->panel_fixed_mode->HDisplay == 800 &&
+		dev_priv->panel_fixed_mode->VDisplay == 600)
 	    {
 		xf86DrvMsg(pScrn->scrnIndex, X_INFO,
 			   "Suspected Mac Mini, ignoring the LVDS\n");
diff --git a/src/ivch/ivch.c b/src/ivch/ivch.c
index efc74f8..a76e339 100644
--- a/src/ivch/ivch.c
+++ b/src/ivch/ivch.c
@@ -38,17 +38,42 @@
 #include "xf86Crtc.h"
 #define DPMS_SERVER
 #include <X11/extensions/dpms.h>
+#include <unistd.h>
 
 #include "../i2c_vid.h"
+#include "../i830_bios.h"
 #include "ivch_reg.h"
 
 struct ivch_priv {
-    I2CDevRec d;
+    I2CDevRec	    d;
 
-    CARD16 save_VR01;
-    CARD16 save_VR40;
+    xf86OutputPtr   output;
+
+    DisplayModePtr  panel_fixed_mode;
+    Bool	    panel_wants_dither;
+
+    CARD16    	    width;
+    CARD16    	    height;
+
+    CARD16	    save_VR01;
+    CARD16	    save_VR40;
 };
 
+struct vch_capabilities {
+    struct aimdb_block	aimdb_block;
+    CARD8		panel_type;
+    CARD8		set_panel_type;
+    CARD8		slave_address;
+    CARD8		capabilities;
+#define VCH_PANEL_FITTING_SUPPORT	(0x3 << 0)
+#define VCH_PANEL_FITTING_TEXT		(1 << 2)
+#define VCH_PANEL_FITTING_GRAPHICS	(1 << 3)
+#define VCH_PANEL_FITTING_RATIO		(1 << 4)
+#define VCH_DITHERING			(1 << 5)
+    CARD8		backlight_gpio;
+    CARD8		set_panel_type_us_gpios;
+} __attribute__ ((packed));
+
 static void
 ivch_dump_regs(I2CDevPtr d);
 
@@ -129,8 +154,8 @@ ivch_write(struct ivch_priv *priv, int a
 static void *
 ivch_init(I2CBusPtr b, I2CSlaveAddr addr)
 {
-    struct ivch_priv *priv;
-    CARD16 temp;
+    struct	ivch_priv *priv;
+    CARD16	temp;
 
     xf86DrvMsg(b->scrnIndex, X_INFO, "detecting ivch\n");
 
@@ -138,6 +163,7 @@ ivch_init(I2CBusPtr b, I2CSlaveAddr addr
     if (priv == NULL)
 	return NULL;
 
+    priv->output = NULL;
     priv->d.DevName = "i82807aa \"ivch\" LVDS/CMOS panel controller";
     priv->d.SlaveAddr = addr;
     priv->d.pI2CBus = b;
@@ -165,6 +191,10 @@ ivch_init(I2CBusPtr b, I2CSlaveAddr addr
 	goto out;
     }
 
+    ivch_read (priv, VR01, &temp); xf86DrvMsg (priv->d.pI2CBus->scrnIndex, X_INFO,
+					       "ivch VR01 0x%x\n", temp);
+    ivch_read (priv, VR40, &temp); xf86DrvMsg (priv->d.pI2CBus->scrnIndex, X_INFO,
+					       "ivch VR40 0x%x\n", temp);
     return priv;
 
 out:
@@ -172,18 +202,58 @@ out:
     return NULL;
 }
 
+/** Gets the panel mode */
+static Bool
+ivch_setup (I2CDevPtr d, xf86OutputPtr output)
+{
+    struct ivch_priv	*priv = d->DriverPrivate.ptr;
+
+    priv->output = output;
+    ivch_read (priv, VR20, &priv->width);
+    ivch_read (priv, VR21, &priv->height);
+    
+    priv->panel_fixed_mode = i830_bios_get_panel_mode (output->scrn, &priv->panel_wants_dither);
+    if (!priv->panel_fixed_mode)
+    {
+	priv->panel_fixed_mode = i830_dvo_get_current_mode (output);
+	priv->panel_wants_dither = TRUE;
+    }
+
+    return TRUE;
+}
+
 static xf86OutputStatus
 ivch_detect(I2CDevPtr d)
 {
     return XF86OutputStatusUnknown;
 }
 
+static DisplayModePtr
+ivch_get_modes (I2CDevPtr d)
+{
+    struct ivch_priv	*priv = d->DriverPrivate.ptr;
+
+    if (priv->panel_fixed_mode)
+	return xf86DuplicateMode (priv->panel_fixed_mode);
+
+    return NULL;
+}
+
 static ModeStatus
 ivch_mode_valid(I2CDevPtr d, DisplayModePtr mode)
 {
+    struct ivch_priv	*priv = d->DriverPrivate.ptr;
+    DisplayModePtr	panel_fixed_mode = priv->panel_fixed_mode;
+    
     if (mode->Clock > 112000)
 	return MODE_CLOCK_HIGH;
 
+    if (panel_fixed_mode)
+    {
+	if (!xf86ModesEqual (mode, panel_fixed_mode))
+	    return MODE_PANEL;
+    }
+    
     return MODE_OK;
 }
 
@@ -193,37 +263,68 @@ ivch_dpms(I2CDevPtr d, int mode)
 {
     struct ivch_priv *priv = d->DriverPrivate.ptr;
     int i;
-    CARD16 temp;
+    CARD16 vr01, vr30, backlight;
 
     /* Set the new power state of the panel. */
-    if (!ivch_read(priv, VR01, &temp))
+    if (!ivch_read(priv, VR01, &vr01))
 	return;
 
     if (mode == DPMSModeOn)
-	temp |= VR01_LCD_ENABLE | VR01_DVO_ENABLE;
+	backlight = 1;
     else
-	temp &= ~(VR01_LCD_ENABLE | VR01_DVO_ENABLE);
+	backlight = 0;
+    ivch_write(priv, VR80, backlight);
+    
+    if (mode == DPMSModeOn)
+	vr01 |= VR01_LCD_ENABLE | VR01_DVO_ENABLE;
+    else
+	vr01 &= ~(VR01_LCD_ENABLE | VR01_DVO_ENABLE);
+
+    vr01 &= ~VR01_PANEL_FIT_ENABLE;
 
-    ivch_write(priv, VR01, temp);
+    ivch_write(priv, VR01, vr01);
 
     /* Wait for the panel to make its state transition */
-    for (i = 0; i < 1000; i++) {
-	if (!ivch_read(priv, VR30, &temp))
+    for (i = 0; i < 100; i++) {
+	if (!ivch_read(priv, VR30, &vr30))
 	    break;
 
-	if (((temp & VR30_PANEL_ON) != 0) == (mode == DPMSModeOn))
+	if (((vr30 & VR30_PANEL_ON) != 0) == (mode == DPMSModeOn))
 	    break;
+	usleep (1000);
     }
+    /* And wait some more; without this, the vch fails to resync sometimes */
+    usleep (16 * 1000);
 }
 
+static Bool
+ivch_mode_fixup(I2CDevPtr d, DisplayModePtr mode, DisplayModePtr adjusted_mode)
+{
+    return TRUE;
+}
+    
 static void
-ivch_mode_set(I2CDevPtr d, DisplayModePtr mode)
+ivch_mode_set(I2CDevPtr d, DisplayModePtr mode, DisplayModePtr adjusted_mode)
 {
-    struct ivch_priv *priv = d->DriverPrivate.ptr;
+    struct ivch_priv	*priv = d->DriverPrivate.ptr;
+    CARD16		vr40 = 0;
+    CARD16		vr01;
 
+    ivch_read (priv, VR01, &vr01);
     /* Disable panel fitting for now, until we can test. */
-    ivch_write(priv, VR40, 0);
+    if (adjusted_mode->HDisplay != priv->width || adjusted_mode->VDisplay != priv->height)
+    {
+	vr01 |= VR01_PANEL_FIT_ENABLE;
+	vr40 |= VR40_AUTO_RATIO_ENABLE;
+    }
+    else
+    {
+	vr01 &= ~VR01_PANEL_FIT_ENABLE;
+	vr40 &= ~VR40_AUTO_RATIO_ENABLE;
+    }
 
+    ivch_write(priv, VR01, vr01);
+    ivch_write(priv, VR40, vr40);
     ivch_dpms(d, DPMSModeOn);
 
     ivch_dump_regs(d);
@@ -244,6 +345,33 @@ ivch_dump_regs(I2CDevPtr d)
     ivch_read(priv, VR40, &val);
     xf86DrvMsg(priv->d.pI2CBus->scrnIndex, X_INFO, "VR40: 0x%04x\n", val);
 
+    /* GPIO registers */
+    ivch_read(priv, VR80, &val);
+    xf86DrvMsg(priv->d.pI2CBus->scrnIndex, X_INFO, "VR80: 0x%04x\n", val);
+    ivch_read(priv, VR81, &val);
+    xf86DrvMsg(priv->d.pI2CBus->scrnIndex, X_INFO, "VR81: 0x%04x\n", val);
+    ivch_read(priv, VR82, &val);
+    xf86DrvMsg(priv->d.pI2CBus->scrnIndex, X_INFO, "VR82: 0x%04x\n", val);
+    ivch_read(priv, VR83, &val);
+    xf86DrvMsg(priv->d.pI2CBus->scrnIndex, X_INFO, "VR83: 0x%04x\n", val);
+    ivch_read(priv, VR84, &val);
+    xf86DrvMsg(priv->d.pI2CBus->scrnIndex, X_INFO, "VR84: 0x%04x\n", val);
+    ivch_read(priv, VR85, &val);
+    xf86DrvMsg(priv->d.pI2CBus->scrnIndex, X_INFO, "VR85: 0x%04x\n", val);
+    ivch_read(priv, VR86, &val);
+    xf86DrvMsg(priv->d.pI2CBus->scrnIndex, X_INFO, "VR86: 0x%04x\n", val);
+    ivch_read(priv, VR87, &val);
+    xf86DrvMsg(priv->d.pI2CBus->scrnIndex, X_INFO, "VR87: 0x%04x\n", val);
+    ivch_read(priv, VR88, &val);
+    xf86DrvMsg(priv->d.pI2CBus->scrnIndex, X_INFO, "VR88: 0x%04x\n", val);
+
+    /* Scratch register 0 - AIM Panel type */
+    ivch_read(priv, VR8E, &val);
+    xf86DrvMsg(priv->d.pI2CBus->scrnIndex, X_INFO, "VR8E: 0x%04x\n", val);
+
+    /* Scratch register 1 - Status register */
+    ivch_read(priv, VR8F, &val);
+    xf86DrvMsg(priv->d.pI2CBus->scrnIndex, X_INFO, "VR8F: 0x%04x\n", val);
 }
 
 static void
@@ -267,11 +395,14 @@ ivch_restore(I2CDevPtr d)
 
 I830I2CVidOutputRec ivch_methods = {
     .init = ivch_init,
-    .detect = ivch_detect,
-    .mode_valid = ivch_mode_valid,
-    .mode_set = ivch_mode_set,
+    .setup = ivch_setup,
     .dpms = ivch_dpms,
-    .dump_regs = ivch_dump_regs,
     .save = ivch_save,
     .restore = ivch_restore,
+    .mode_valid = ivch_mode_valid,
+    .mode_fixup = ivch_mode_fixup,
+    .mode_set = ivch_mode_set,
+    .detect = ivch_detect,
+    .get_modes = ivch_get_modes,
+    .dump_regs = ivch_dump_regs,
 };
diff --git a/src/ivch/ivch_reg.h b/src/ivch/ivch_reg.h
index 112c97d..fe5507a 100644
--- a/src/ivch/ivch_reg.h
+++ b/src/ivch/ivch_reg.h
@@ -35,14 +35,14 @@
 #ifndef I82807AA_REG_H
 #define I82807AA_REG_H
 
-/** @defgroup VR00
+/** @defgroup VR00 VCH Revision & GMBus Base Addr
  * @{
  */
 #define VR00		0x00
 # define VR00_BASE_ADDRESS_MASK		0x007f
 /** @} */
 
-/** @defgroup VR01
+/** @defgroup VR01 VCH Functionality Enable
  * @{
  */
 #define VR01		0x01
@@ -59,7 +59,7 @@
 # define VR01_DVO_ENABLE		(1 << 0)
 /** @} */
 
-/** @defgroup VR10
+/** @defgroup VR10 LCD Interface Format
  * @{
  */
 #define VR10		0x10
@@ -75,7 +75,79 @@
 # define VR10_INTERFACE_2X24		(3 << 2)
 /** @} */
 
-/** @defgroup VR30
+/** @defgroup VR11 CMOS Output Control
+ * @{
+ */
+/** @} */
+
+/** @defgroup VR12 LVDS Output Control
+ * @{
+ */
+/** @} */
+
+/** @defgroup VR18 PLL clock select
+ * @{
+ */
+/** @} */
+
+/** @defgroup VR19 PLL clock divisor M
+ * @{
+ */
+/** @} */
+
+/** @defgroup VR1A PLL clock divisor N
+ * @{
+ */
+/** @} */
+
+/** @defgroup VR1F FIFO Pre-load
+ * @{
+ */
+/** @} */
+
+/** @defgroup VR20 LCD Horizontal Display Size
+ * @{
+ */
+#define VR20	0x20
+/** @} */
+
+/** @defgroup VR21 LCD Vertical Display Size
+ * @{
+ */
+#define VR21	0x20
+/** @} */
+
+/** @defgroup VR22 Horizontal TRP to DE Start Delay
+ * @{
+ */
+/** @} */
+
+/** @defgroup VR23 Horizontal TRP to DE End Delay
+ * @{
+ */
+/** @} */
+
+/** @defgroup VR24 Horizontal TRP To LP Start Delay
+ * @{
+ */
+/** @} */
+
+/** @defgroup VR25 Horizontal TRP To LP End Delay
+ * @{
+ */
+/** @} */
+
+/** @defgroup VR26 Vertical TRP To FLM Start Delay
+ * @{
+ */
+/** @} */
+
+/** @defgroup VR27 Vertical TRP To FLM End Delay
+ * @{
+ */
+/** @} */
+
+/** @defgroup VR30 Panel power down status
  * @{
  */
 #define VR30		0x30
@@ -83,6 +155,31 @@
 # define VR30_PANEL_ON			(1 << 15)
 /** @} */
 
+/** @defgroup VR31 Tpon Panel power on sequencing delay
+ * @{
+ */
+/** @} */
+
+/** @defgroup VR32 Tpon Panel power off sequencing delay
+ * @{
+ */
+/** @} */
+
+/** @defgroup VR33 Tstay Panel power off stay down delay
+ * @{
+ */
+/** @} */
+
+/** @defgroup VR34 Maximal FLM Pulse Interval
+ * @{
+ */
+/** @} */
+
+/** @defgroup VR35 Maximal LP Pulse Interval
+ * @{
+ */
+/** @} */
+
 /** @defgroup VR40
  * @{
  */
@@ -90,8 +187,95 @@
 # define VR40_STALL_ENABLE		(1 << 13)
 # define VR40_VERTICAL_INTERP_ENABLE	(1 << 11)
 # define VR40_HORIZONTAL_INTERP_ENABLE	(1 << 10)
-# define VR40_RATIO_ENABLE		(1 << 9)
+# define VR40_AUTO_RATIO_ENABLE		(1 << 9)
 # define VR40_PANEL_FIT_ENABLE		(1 << 8)
 /** @} */
 
+/** @defgroup VR41 Panel Fitting Vertical Ratio
+ * @{
+ */
+/** @} */
+
+/** @defgroup VR42 Panel Fitting Horizontal Ratio
+ * @{
+ */
+/** @} */
+
+/** @defgroup VR43 Horizontal Image Size
+ * @{
+ */
+/** @} */
+
+/** @defgroup VR44 Panel Fitting Coefficient 0
+ * @{
+ */
+/** @} */
+
+/** @defgroup VR45 Panel Fitting Coefficient 1
+ * @{
+ */
+/** @} */
+
+/** @defgroup VR46 Panel Fitting Coefficient 2
+ * @{
+ */
+/** @} */
+
+/** @defgroup VR47 Panel Fitting Coefficient 3
+ * @{
+ */
+/** @} */
+
+/** @defgroup VR48 Panel Fitting Coefficient 4
+ * @{
+ */
+/** @} */
+
+/** @defgroup VR49 Panel Fitting Coefficient 5
+ * @{
+ */
+/** @} */
+
+/** @defgroup VR80 GPIO 0
+ * @{
+ */
+/** @} */
+
+#define VR80	    0x80
+#define VR81	    0x81
+#define VR82	    0x82
+#define VR83	    0x83
+#define VR84	    0x84
+#define VR85	    0x85
+#define VR86	    0x86
+#define VR87	    0x87
+    
+/** @defgroup VR88 GPIO 8
+ * @{
+ */
+/** @} */
+
+#define VR88	    0x88
+
+/** @defgroup VR8E Graphics BIOS scratch 0
+ * @{
+ */
+#define VR8E	    0x8E
+# define VR8E_PANEL_TYPE_MASK		(0xf << 0)
+# define VR8E_PANEL_INTERFACE_CMOS	(0 << 4)
+# define VR8E_PANEL_INTERFACE_LVDS	(1 << 4)
+# define VR8E_FORCE_DEFAULT_PANEL	(1 << 5)
+/** @} */
+
+/** @defgroup VR8F Graphics BIOS scratch 1
+ * @{
+ */
+#define VR8F	    0x8F
+# define VR8F_VCH_PRESENT		(1 << 0)
+# define VR8F_DISPLAY_CONN		(1 << 1)
+# define VR8F_POWER_MASK		(0x3c)
+# define VR8F_POWER_POS			(2)
+/** @} */
+
+
 #endif /* I82807AA_REG_H */
diff --git a/src/sil164/sil164.c b/src/sil164/sil164.c
index 80b1b6a..60a03e2 100644
--- a/src/sil164/sil164.c
+++ b/src/sil164/sil164.c
@@ -144,7 +144,7 @@ sil164_mode_valid(I2CDevPtr d, DisplayMo
 }
 
 static void
-sil164_mode_set(I2CDevPtr d, DisplayModePtr mode)
+sil164_mode_set(I2CDevPtr d, DisplayModePtr mode, DisplayModePtr adjusted_mode)
 {
     /* As long as the basics are set up, since we don't have clock dependencies
      * in the mode setup, we can just leave the registers alone and everything
diff-tree b28817a87a1608e849e4a9a736dda43533a84b0c (from b31bef1a8effa9acb6de7edd206b9d8c48d88144)
Author: Keith Packard <keithp at dulcimer.keithp.com>
Date:   Wed May 16 13:59:36 2007 -0700

    Add i830_bios_get_aim_data_block to read AIM data from BIOS
    
    Add-in modules have per-module data in the BIOS which contains configuration
    information which cannot be entirely discovered.

diff --git a/src/bios_reader/bios_reader.c b/src/bios_reader/bios_reader.c
index a52bcc7..9ec73c1 100644
--- a/src/bios_reader/bios_reader.c
+++ b/src/bios_reader/bios_reader.c
@@ -30,16 +30,11 @@
 #include <string.h>
 #include <sys/types.h>
 
+#include "../i830_bios.h"
+
 #define _PARSE_EDID_
 #include "edid.h"
 
-/* Define some types so we can reuse i830_bios.h */
-typedef void *ScrnInfoPtr;
-typedef int Bool;
-#define TRUE 1
-#define FALSE 0
-#include "../i830_bios.h"
-
 
 /* Make a fake pI830 so we can easily pull i830_bios.c code in here. */
 struct _fake_i830 {
diff --git a/src/i830_bios.c b/src/i830_bios.c
index 0d00917..7703c80 100644
--- a/src/i830_bios.c
+++ b/src/i830_bios.c
@@ -77,8 +77,8 @@ i830DumpBIOSToFile(ScrnInfoPtr pScrn, un
  * feed an updated VBT back through that, compared to what we'll fetch using
  * this method of groping around in the BIOS data.
  */
-static unsigned char *
-i830GetBIOS(ScrnInfoPtr pScrn)
+unsigned char *
+i830_bios_get (ScrnInfoPtr pScrn)
 {
     I830Ptr pI830 = I830PTR(pScrn);
     struct vbt_header *vbt;
@@ -131,7 +131,7 @@ i830GetBIOS(ScrnInfoPtr pScrn)
  * detecting the panel mode is preferable.
  */
 DisplayModePtr
-i830_bios_get_panel_mode(ScrnInfoPtr pScrn)
+i830_bios_get_panel_mode(ScrnInfoPtr pScrn, Bool *wants_dither)
 {
     I830Ptr pI830 = I830PTR(pScrn);
     struct vbt_header *vbt;
@@ -140,7 +140,7 @@ i830_bios_get_panel_mode(ScrnInfoPtr pSc
     int panel_type = -1;
     unsigned char *bios;
 
-    bios = i830GetBIOS(pScrn);
+    bios = i830_bios_get (pScrn);
 
     if (bios == NULL)
 	return NULL;
@@ -156,6 +156,7 @@ i830_bios_get_panel_mode(ScrnInfoPtr pSc
 	return NULL;
     }
 
+    *wants_dither = FALSE;
     for (bdb_block_off = bdb->header_size; bdb_block_off < bdb->bdb_size;
 	 bdb_block_off += block_size)
     {
@@ -175,7 +176,7 @@ i830_bios_get_panel_mode(ScrnInfoPtr pSc
 	    lvds1 = (struct lvds_bdb_1 *)(bios + start);
 	    panel_type = lvds1->panel_type;
 	    if (lvds1->caps & LVDS_CAP_DITHER)
-		pI830->panel_wants_dither = TRUE;
+		*wants_dither = TRUE;
 	    break;
 	case 41:
 	    if (panel_type == -1)
@@ -243,3 +244,51 @@ i830_bios_get_panel_mode(ScrnInfoPtr pSc
     xfree(bios);
     return NULL;
 }
+
+unsigned char *
+i830_bios_get_aim_data_block (ScrnInfoPtr pScrn, int aim, int data_block)
+{
+    unsigned char   *bios;
+    int		    bdb_off;
+    int		    vbt_off;
+    int		    aim_off;
+    struct vbt_header *vbt;
+    struct aimdb_header *aimdb;
+    struct aimdb_block *aimdb_block;
+
+    bios = i830_bios_get (pScrn);
+    if (!bios)
+	return NULL;
+
+    vbt_off = INTEL_BIOS_16(0x1a);
+    vbt = (struct vbt_header *)(bios + vbt_off);
+
+    aim_off = vbt->aim_offset[aim];
+    if (!aim_off)
+    {
+	free (bios);
+	return NULL;
+    }
+    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "aim_off %d\n", aim_off);
+    aimdb = (struct aimdb_header *) (bios + vbt_off + aim_off);
+    bdb_off = aimdb->aimdb_header_size;
+    while (bdb_off < aimdb->aimdb_size)
+    {
+	aimdb_block = (struct aimdb_block *) (bios + vbt_off + aim_off + bdb_off);
+	if (aimdb_block->aimdb_id == data_block)
+	{
+	    unsigned char   *aim = malloc (aimdb_block->aimdb_size + sizeof (struct aimdb_block));
+	    if (!aim)
+	    {
+		free (bios);
+		return NULL;
+	    }
+	    memcpy (aim, aimdb_block, aimdb_block->aimdb_size + sizeof (struct aimdb_block));
+	    free (bios);
+	    return aim;
+	}
+	bdb_off += aimdb_block->aimdb_size + sizeof (struct aimdb_block);
+    }
+    free (bios);
+    return NULL;
+}
diff --git a/src/i830_bios.h b/src/i830_bios.h
index 881d5c8..cb7666e 100644
--- a/src/i830_bios.h
+++ b/src/i830_bios.h
@@ -25,6 +25,11 @@
  *
  */
 
+#ifndef _I830_BIOS_H_
+#define _I830_BIOS_H_
+
+#include <xf86str.h>
+
 struct vbt_header {
     char signature[20];			/**< Always starts with 'VBT$' */
     CARD16 version;			/**< decimal */
@@ -33,10 +38,7 @@ struct vbt_header {
     CARD8 vbt_checksum;
     CARD8 reserved0;
     CARD32 bdb_offset;			/**< from beginning of VBT */
-    CARD32 aim1_offset;			/**< from beginning of VBT */
-    CARD32 aim2_offset;			/**< from beginning of VBT */
-    CARD32 aim3_offset;			/**< from beginning of VBT */
-    CARD32 aim4_offset;			/**< from beginning of VBT */
+    CARD32 aim_offset[4];		/**< from beginning of VBT */
 } __attribute__((packed));
 
 struct bdb_header {
@@ -114,3 +116,45 @@ struct lvds_bdb_2 {
     CARD8 table_size;	/* not sure on this one */
     struct lvds_bdb_2_entry panels[16];
 } __attribute__((packed));
+
+struct aimdb_header {
+    char    signature[16];
+    char    oem_device[20];
+    CARD16  aimdb_version;
+    CARD16  aimdb_header_size;
+    CARD16  aimdb_size;
+} __attribute__((packed));
+
+struct aimdb_block {
+    CARD8   aimdb_id;
+    CARD16  aimdb_size;
+} __attribute__((packed));
+
+struct vch_bdb_20 {
+} __attribute__((packed));
+
+struct vch_panel_data {
+    CARD16	fp_timing_offset;
+    CARD8	fp_timing_size;
+    CARD16	dvo_timing_offset;
+    CARD8	dvo_timing_size;
+    CARD16	text_fitting_offset;
+    CARD8	text_fitting_size;
+    CARD16	graphics_fitting_offset;
+    CARD8	graphics_fitting_size;
+} __attribute__((packed));
+
+struct vch_bdb_22 {
+    struct aimdb_block	    aimdb_block;
+    struct vch_panel_data   panels[16];
+} __attribute__((packed));
+
+unsigned char *
+i830_bios_get (ScrnInfoPtr pScrn);
+
+DisplayModePtr i830_bios_get_panel_mode(ScrnInfoPtr pScrn, Bool *wants_dither);
+
+unsigned char *
+i830_bios_get_aim_data_block (ScrnInfoPtr pScrn, int aim, int data_block);
+
+#endif /* _I830_BIOS_H_ */
diff-tree b31bef1a8effa9acb6de7edd206b9d8c48d88144 (from 3b769af53e0ef6ef9b56afd679446c73a0e63ea5)
Author: Keith Packard <keithp at work.jf.intel.com>
Date:   Sat May 12 20:04:31 2007 -0700

    Deal with i830 CRT load detection which cannot use FORCE_BORDER.
    
    Chips newer than the i830 can force the border color for the active period
    of the screen, allowing the load detection to easily see the right data. In
    addition, newer chips appear to have more sensible load detection hardware
    which either ignores inactive periods on the screen or performs some
    longer-term averaging. The i830 appears to provide unfiltered samples of the
    detected load.
    
    For the i830, then, emit a border at the bottom of the screen and, for load
    detection, simply turn it purple and wait for the current line to be within
    the border. Sample an entire scanline, counting the number of times the load
    detection sees a monitor. In my testing, the presence of a monitor will
    cause the detection to succeed every time, while the absense will cause it
    to fail about 75% of the time. The code here, checks for presence at least
    75% of the time, which should be adequate.
    
    Also, as the new mode configuration code has already taken care to enable
    the CRT output, eliminate much of the load detection code which is simply
    duplicating functionality from the general mode setting code. This should
    result in faster load detection as this code will now run in no more than
    one frame time. It does burn the CPU the whole time though, polling the
    displayed scanline register.

diff --git a/src/i810_reg.h b/src/i810_reg.h
index c3db5c9..234d124 100644
--- a/src/i810_reg.h
+++ b/src/i810_reg.h
@@ -1938,6 +1938,8 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN
 #define TV_V_CHROMA_42		0x684a8
 /** @} */
 
+#define PIPEA_DSL		0x70000
+
 #define PIPEACONF 0x70008
 #define PIPEACONF_ENABLE	(1<<31)
 #define PIPEACONF_DISABLE	0
@@ -1966,6 +1968,8 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN
 #define PIPEAFRAMEPIXEL		0x70044
 
 
+#define PIPEB_DSL		0x71000
+
 #define PIPEBCONF 0x71008
 #define PIPEBCONF_ENABLE	(1<<31)
 #define PIPEBCONF_DISABLE	0
diff --git a/src/i830.h b/src/i830.h
index 7b0ab15..c91be79 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -489,6 +489,7 @@ typedef struct _I830Rec {
    CARD32 saveVTOTAL_A;
    CARD32 saveVBLANK_A;
    CARD32 saveVSYNC_A;
+   CARD32 saveBCLRPAT_A;
    CARD32 saveDSPASTRIDE;
    CARD32 saveDSPASIZE;
    CARD32 saveDSPAPOS;
@@ -504,6 +505,7 @@ typedef struct _I830Rec {
    CARD32 saveVTOTAL_B;
    CARD32 saveVBLANK_B;
    CARD32 saveVSYNC_B;
+   CARD32 saveBCLRPAT_B;
    CARD32 saveDSPBSTRIDE;
    CARD32 saveDSPBSIZE;
    CARD32 saveDSPBPOS;
diff --git a/src/i830_crt.c b/src/i830_crt.c
index fbb4adc..879ae9f 100644
--- a/src/i830_crt.c
+++ b/src/i830_crt.c
@@ -97,6 +97,8 @@ static Bool
 i830_crt_mode_fixup(xf86OutputPtr output, DisplayModePtr mode,
 		    DisplayModePtr adjusted_mode)
 {
+    /* disable blanking so we can detect monitors */
+    adjusted_mode->CrtcVBlankStart = adjusted_mode->CrtcVTotal - 3;
     return TRUE;
 }
 
@@ -106,7 +108,7 @@ i830_crt_mode_set(xf86OutputPtr output, 
 {
     ScrnInfoPtr		    pScrn = output->scrn;
     I830Ptr		    pI830 = I830PTR(pScrn);
-    xf86CrtcPtr	    crtc = output->crtc;
+    xf86CrtcPtr		    crtc = output->crtc;
     I830CrtcPrivatePtr	    i830_crtc = crtc->driver_private;
     int			    dpll_md_reg;
     CARD32		    adpa, dpll_md;
@@ -132,9 +134,15 @@ i830_crt_mode_set(xf86OutputPtr output, 
 	adpa |= ADPA_VSYNC_ACTIVE_HIGH;
 
     if (i830_crtc->pipe == 0)
+    {
 	adpa |= ADPA_PIPE_A_SELECT;
+	OUTREG(BCLRPAT_A, 0);
+    }
     else
+    {
 	adpa |= ADPA_PIPE_B_SELECT;
+	OUTREG(BCLRPAT_B, 0);
+    }
 
     OUTREG(ADPA, adpa);
 }
@@ -193,58 +201,79 @@ i830_crt_detect_load (xf86CrtcPtr	    cr
     ScrnInfoPtr		    pScrn = output->scrn;
     I830Ptr		    pI830 = I830PTR(pScrn);
     I830CrtcPrivatePtr	    i830_crtc = I830CrtcPrivate(crtc);
-    CARD32		    save_adpa, adpa, pipeconf, bclrpat;
+    I830OutputPrivatePtr    intel_output = output->driver_private;
+    CARD32		    save_bclrpat;
+    CARD32		    save_vtotal;
+    CARD32		    vtotal, vactive;
+    CARD32		    vsample;
+    CARD32		    dsl;
     CARD8		    st00;
-    int			    pipeconf_reg, bclrpat_reg, dpll_reg;
+    int			    bclrpat_reg, pipeconf_reg, pipe_dsl_reg;
+    int			    vtotal_reg;
     int			    pipe = i830_crtc->pipe;
+    int			    count, detect;
+    Bool		    present;
 
     if (pipe == 0) 
     {
 	bclrpat_reg = BCLRPAT_A;
+	vtotal_reg = VTOTAL_A;
 	pipeconf_reg = PIPEACONF;
-	dpll_reg = DPLL_A;
+	pipe_dsl_reg = PIPEA_DSL;
     }
     else 
     {
 	bclrpat_reg = BCLRPAT_B;
+	vtotal_reg = VTOTAL_B;
 	pipeconf_reg = PIPEBCONF;
-	dpll_reg = DPLL_B;
+	pipe_dsl_reg = PIPEB_DSL;
     }
 
-    adpa = INREG(ADPA);
-    save_adpa = adpa;
+    save_bclrpat = INREG(bclrpat_reg);
+    save_vtotal = INREG(vtotal_reg);
 
-    /* Enable CRT output. */
-    adpa |= ADPA_DAC_ENABLE;
-    if (pipe == 1)
- 	adpa |= ADPA_PIPE_B_SELECT;
-    else
- 	adpa &= ~ADPA_PIPE_B_SELECT;
-    adpa |= ADPA_VSYNC_CNTL_ENABLE | ADPA_HSYNC_CNTL_ENABLE;
-    OUTREG(ADPA, adpa);
+    vtotal = (save_vtotal >> 16) & 0xfff;
+    vactive = save_vtotal & 0x7ff;
+    
+    /* sample the middle of the blanking interval */
+    vsample = ((vtotal - 3) + (vactive)) >> 1;
 
     /* Set the border color to purple. */
-    bclrpat = INREG(bclrpat_reg);
-    OUTREG(bclrpat_reg, 0x00500050);
-
-    i830WaitForVblank(pScrn);
-
-    /* Force the border color through the active region */
-    pipeconf = INREG(pipeconf_reg);
-    OUTREG(pipeconf_reg, pipeconf | PIPECONF_FORCE_BORDER);
-
-    /* Read the ST00 VGA status register */
-    st00 = pI830->readStandard(pI830, 0x3c2);
+    OUTREG(bclrpat_reg, 0x500050);
+    
+    /*
+     * Wait for the border to be displayed
+     */
+    while (INREG(pipe_dsl_reg) >= vactive)
+	;
+    while ((dsl = INREG(pipe_dsl_reg)) <= vsample)
+	;
+    /*
+     * Watch ST00 for an entire scanline
+     */
+    detect = 0;
+    count = 0;
+    do {
+	count++;
+	/* Read the ST00 VGA status register */
+	st00 = pI830->readStandard(pI830, 0x3c2);
+	if (st00 & (1 << 4))
+	    detect++;
+    } while ((INREG(pipe_dsl_reg) == dsl));
 
     /* Restore previous settings */
-    OUTREG(bclrpat_reg, bclrpat);
-    OUTREG(pipeconf_reg, pipeconf);
-    OUTREG(ADPA, save_adpa);
+    OUTREG(bclrpat_reg, save_bclrpat);
 
-    if (st00 & (1 << 4))
-	return TRUE;
-    else
-	return FALSE;
+    /*
+     * If more than 3/4 of the scanline detected a monitor,
+     * then it is assumed to be present. This works even on i830,
+     * where there isn't any way to force the border color across
+     * the screen
+     */
+    present = detect * 4 > count * 3;
+    xf86DrvMsg (pScrn->scrnIndex, X_ERROR, "present: %s (%d of %d) at %ld desired %ld temp %d\n",
+		present ? "TRUE" : "FALSE", detect, count, dsl, vsample, intel_output->load_detect_temp);
+    return present;
 }
 
 /**
diff --git a/src/i830_display.c b/src/i830_display.c
index 727d1b2..4b205ba 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -1255,6 +1255,7 @@ i830ReleaseLoadDetectPipe(xf86OutputPtr 
     
     if (intel_output->load_detect_temp) 
     {
+	output->crtc->enabled = FALSE;
 	output->crtc = NULL;
 	intel_output->load_detect_temp = FALSE;
 	xf86DisableUnusedFunctions(pScrn);
diff --git a/src/i830_driver.c b/src/i830_driver.c
index 1d8b7f8..b4d9d08 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -744,6 +744,12 @@ I830SetupOutputs(ScrnInfoPtr pScrn)
 	 break;
       case I830_OUTPUT_ANALOG:
 	 crtc_mask = ((1 << 0));
+	 /*
+	  * 915 cannot do double-wide on pipe B
+	  * 830 cannot put CRT on pipe B
+	  */
+	 if (!IS_I915G(pI830) && !IS_I915GM (pI830) && !IS_I830(pI830))
+	    crtc_mask |= ((1 << 1));
 	 clone_mask = ((1 << I830_OUTPUT_ANALOG) |
 		       (1 << I830_OUTPUT_DVO) |
 		       (1 << I830_OUTPUT_SDVO));
@@ -1735,6 +1741,7 @@ SaveHWState(ScrnInfoPtr pScrn)
    pI830->saveVTOTAL_A = INREG(VTOTAL_A);
    pI830->saveVBLANK_A = INREG(VBLANK_A);
    pI830->saveVSYNC_A = INREG(VSYNC_A);
+   pI830->saveBCLRPAT_A = INREG(BCLRPAT_A);
    pI830->saveDSPASTRIDE = INREG(DSPASTRIDE);
    pI830->saveDSPASIZE = INREG(DSPASIZE);
    pI830->saveDSPAPOS = INREG(DSPAPOS);
@@ -1759,6 +1766,7 @@ SaveHWState(ScrnInfoPtr pScrn)
       pI830->saveVTOTAL_B = INREG(VTOTAL_B);
       pI830->saveVBLANK_B = INREG(VBLANK_B);
       pI830->saveVSYNC_B = INREG(VSYNC_B);
+      pI830->saveBCLRPAT_B = INREG(BCLRPAT_B);
       pI830->saveDSPBSTRIDE = INREG(DSPBSTRIDE);
       pI830->saveDSPBSIZE = INREG(DSPBSIZE);
       pI830->saveDSPBPOS = INREG(DSPBPOS);
@@ -1857,6 +1865,7 @@ RestoreHWState(ScrnInfoPtr pScrn)
    OUTREG(VTOTAL_A, pI830->saveVTOTAL_A);
    OUTREG(VBLANK_A, pI830->saveVBLANK_A);
    OUTREG(VSYNC_A, pI830->saveVSYNC_A);
+   OUTREG(BCLRPAT_A, pI830->saveBCLRPAT_A);
    
    OUTREG(DSPASTRIDE, pI830->saveDSPASTRIDE);
    OUTREG(DSPASIZE, pI830->saveDSPASIZE);
@@ -1894,6 +1903,7 @@ RestoreHWState(ScrnInfoPtr pScrn)
       OUTREG(VTOTAL_B, pI830->saveVTOTAL_B);
       OUTREG(VBLANK_B, pI830->saveVBLANK_B);
       OUTREG(VSYNC_B, pI830->saveVSYNC_B);
+      OUTREG(BCLRPAT_B, pI830->saveBCLRPAT_B);
       OUTREG(DSPBSTRIDE, pI830->saveDSPBSTRIDE);
       OUTREG(DSPBSIZE, pI830->saveDSPBSIZE);
       OUTREG(DSPBPOS, pI830->saveDSPBPOS);
diff-tree b930bb9d6da8c24dbe0949afb7bb2aa4bcb24687 (from 775fc125aa7ecd0f054959ef210be2df4dc54345)
Author: Eric Anholt <eric at anholt.net>
Date:   Thu May 3 13:44:12 2007 -0700

    Disable vblank interrupts when no DRI clients are running.
    (cherry picked from commit 6621dd71ada839f4c1742e9e5b272e924cee21d9)

diff --git a/src/i830.h b/src/i830.h
index 8034302..7b0ab15 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -326,6 +326,7 @@ typedef struct _I830Rec {
    unsigned int third_tiled;
    unsigned int depth_tiled;
 
+   Bool want_vblank_interrupts;
 #ifdef DAMAGE
    DamagePtr pDamage;
    RegionRec driRegion;
diff --git a/src/i830_dri.c b/src/i830_dri.c
index 2203c9e..9498661 100644
--- a/src/i830_dri.c
+++ b/src/i830_dri.c
@@ -590,13 +590,13 @@ I830DRIScreenInit(ScreenPtr pScreen)
    }
 
    pDRIInfo->TransitionTo2d = I830DRITransitionTo2d;
+   pDRIInfo->TransitionTo3d = I830DRITransitionTo3d;
 
 #if DRIINFO_MAJOR_VERSION > 5 || \
     (DRIINFO_MAJOR_VERSION == 5 && DRIINFO_MINOR_VERSION >= 1)
    if (!pDRIInfo->ClipNotify)
 #endif
    {
-      pDRIInfo->TransitionTo3d = I830DRITransitionTo3d;
       pDRIInfo->TransitionSingleToMulti3D = I830DRITransitionSingleToMulti3d;
       pDRIInfo->TransitionMultiToSingle3D = I830DRITransitionMultiToSingle3d;
    }
@@ -1543,16 +1543,24 @@ I830DRITransitionTo3d(ScreenPtr pScreen)
    I830Ptr pI830 = I830PTR(pScrn);
 
    I830DRISetPfMask(pScreen, pI830->allowPageFlip ? 0x3 : 0);
+
+   pI830->want_vblank_interrupts = TRUE;
+   I830DRISetVBlankInterrupt(pScrn, TRUE);
 }
 
 static void
 I830DRITransitionTo2d(ScreenPtr pScreen)
 {
+   ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+   I830Ptr pI830 = I830PTR(pScrn);
    drmI830Sarea *sPriv = (drmI830Sarea *) DRIGetSAREAPrivate(pScreen);
 
    I830DRISetPfMask(pScreen, 0);
 
    sPriv->pf_enabled = 0;
+
+   pI830->want_vblank_interrupts = FALSE;
+   I830DRISetVBlankInterrupt(pScrn, FALSE);
 }
 
 #if DRI_SUPPORTS_CLIP_NOTIFY
@@ -1684,6 +1692,12 @@ I830DRISetVBlankInterrupt (ScrnInfoPtr p
     xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
     drmI830VBlankPipe pipe;
 
+    /* If we have no 3d running, then don't bother enabling the vblank
+     * interrupt.
+     */
+    if (!pI830->want_vblank_interrupts)
+	on = FALSE;
+
     if (pI830->directRenderingEnabled && pI830->drmMinor >= 5) {
 	if (on) {
 	    if (xf86_config->num_crtc > 1 && xf86_config->crtc[1]->enabled)
diff-tree 3b769af53e0ef6ef9b56afd679446c73a0e63ea5 (from 775fc125aa7ecd0f054959ef210be2df4dc54345)
Author: Eric Anholt <eric at anholt.net>
Date:   Thu May 3 13:44:12 2007 -0700

    Disable vblank interrupts when no DRI clients are running.

diff --git a/src/i830.h b/src/i830.h
index 8034302..7b0ab15 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -326,6 +326,7 @@ typedef struct _I830Rec {
    unsigned int third_tiled;
    unsigned int depth_tiled;
 
+   Bool want_vblank_interrupts;
 #ifdef DAMAGE
    DamagePtr pDamage;
    RegionRec driRegion;
diff --git a/src/i830_dri.c b/src/i830_dri.c
index 2203c9e..9498661 100644
--- a/src/i830_dri.c
+++ b/src/i830_dri.c
@@ -590,13 +590,13 @@ I830DRIScreenInit(ScreenPtr pScreen)
    }
 
    pDRIInfo->TransitionTo2d = I830DRITransitionTo2d;
+   pDRIInfo->TransitionTo3d = I830DRITransitionTo3d;
 
 #if DRIINFO_MAJOR_VERSION > 5 || \
     (DRIINFO_MAJOR_VERSION == 5 && DRIINFO_MINOR_VERSION >= 1)
    if (!pDRIInfo->ClipNotify)
 #endif
    {
-      pDRIInfo->TransitionTo3d = I830DRITransitionTo3d;
       pDRIInfo->TransitionSingleToMulti3D = I830DRITransitionSingleToMulti3d;
       pDRIInfo->TransitionMultiToSingle3D = I830DRITransitionMultiToSingle3d;
    }
@@ -1543,16 +1543,24 @@ I830DRITransitionTo3d(ScreenPtr pScreen)
    I830Ptr pI830 = I830PTR(pScrn);
 
    I830DRISetPfMask(pScreen, pI830->allowPageFlip ? 0x3 : 0);
+
+   pI830->want_vblank_interrupts = TRUE;
+   I830DRISetVBlankInterrupt(pScrn, TRUE);
 }
 
 static void
 I830DRITransitionTo2d(ScreenPtr pScreen)
 {
+   ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+   I830Ptr pI830 = I830PTR(pScrn);
    drmI830Sarea *sPriv = (drmI830Sarea *) DRIGetSAREAPrivate(pScreen);
 
    I830DRISetPfMask(pScreen, 0);
 
    sPriv->pf_enabled = 0;
+
+   pI830->want_vblank_interrupts = FALSE;
+   I830DRISetVBlankInterrupt(pScrn, FALSE);
 }
 
 #if DRI_SUPPORTS_CLIP_NOTIFY
@@ -1684,6 +1692,12 @@ I830DRISetVBlankInterrupt (ScrnInfoPtr p
     xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
     drmI830VBlankPipe pipe;
 
+    /* If we have no 3d running, then don't bother enabling the vblank
+     * interrupt.
+     */
+    if (!pI830->want_vblank_interrupts)
+	on = FALSE;
+
     if (pI830->directRenderingEnabled && pI830->drmMinor >= 5) {
 	if (on) {
 	    if (xf86_config->num_crtc > 1 && xf86_config->crtc[1]->enabled)
diff-tree 775fc125aa7ecd0f054959ef210be2df4dc54345 (from 34f362d099d255f8f0bb34e9de30f953ee770163)
Author: Dave Airlie <airlied at airlied2.(none)>
Date:   Thu May 3 20:58:50 2007 +1000

    i810: be a bit more verbose about disabling DRI

diff --git a/src/i810_driver.c b/src/i810_driver.c
index 2a8b9fc..baca21c 100644
--- a/src/i810_driver.c
+++ b/src/i810_driver.c
@@ -848,11 +848,11 @@ I810PreInit(ScrnInfoPtr pScrn, int flags
 
    if (!pI810->directRenderingDisabled) {
      if (pI810->noAccel) {
-       xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "DRI is disabled because it "
+       xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "DRI is disabled because it "
 		  "needs 2D acceleration.\n");
        pI810->directRenderingDisabled=TRUE;
      } else if (pScrn->depth!=16) {
-       xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "DRI is disabled because it "
+       xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "DRI is disabled because it "
 		  "runs only at 16-bit depth.\n");
        pI810->directRenderingDisabled=TRUE;
      }
diff-tree 34f362d099d255f8f0bb34e9de30f953ee770163 (from f850d4727a2ad55c2116d0788f6684b2a0192d24)
Author: Eric Anholt <eric at anholt.net>
Date:   Wed May 2 15:40:49 2007 -0700

    Fix typo s/i/index/ in LoadPalette for depth 16.
    
    Reported by:	Haihao Xiang <haihao.xiang at intel.com>

diff --git a/src/i830_driver.c b/src/i830_driver.c
index 43f4e04..1d8b7f8 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -647,7 +647,7 @@ I830LoadPalette(ScrnInfoPtr pScrn, int n
 	 for (i = 0; i < numColors; i++) {
 	    index = indices[i];
 
-	    if (i <= 31) {
+	    if (index <= 31) {
 	       for (j = 0; j < 8; j++) {
 		  lut_r[index * 8 + j] = colors[index].red << 8;
 		  lut_b[index * 8 + j] = colors[index].blue << 8;
diff-tree f850d4727a2ad55c2116d0788f6684b2a0192d24 (from f3168e3b0c5664a322ca6bb1c81fc94844cb30ab)
Author: Eric Anholt <eric at anholt.net>
Date:   Wed May 2 14:16:21 2007 -0700

    Make up a fixed panel timing for DVO LVDS, and use DVOA for DVO LVDS.
    
    The fixed panel timing will only be available when the LVDS is already on
    at X startup.
    
    So far, our only mostly-working LVDS driver is for the i830, and on i830 the
    LVDS is always on DVOA, so use that for all LVDS chips.  This may need to
    change if we support the ch7017 I've seen used on embedded i845, for example.

diff --git a/src/i830_dvo.c b/src/i830_dvo.c
index 96b29e7..129651c 100644
--- a/src/i830_dvo.c
+++ b/src/i830_dvo.c
@@ -89,13 +89,19 @@ i830_dvo_dpms(xf86OutputPtr output, int 
     I830Ptr		    pI830 = I830PTR(pScrn);
     I830OutputPrivatePtr    intel_output = output->driver_private;
     void *		    dev_priv = intel_output->i2c_drv->dev_priv;
+    unsigned int	    dvo_reg;
+
+    if (intel_output->i2c_drv->type & I830_DVO_CHIP_LVDS)
+	dvo_reg = DVOA;
+    else
+	dvo_reg = DVOC;
 
     if (mode == DPMSModeOn) {
-	OUTREG(DVOC, INREG(DVOC) | DVO_ENABLE);
+	OUTREG(dvo_reg, INREG(dvo_reg) | DVO_ENABLE);
 	(*intel_output->i2c_drv->vid_rec->dpms)(dev_priv, mode);
     } else {
 	(*intel_output->i2c_drv->vid_rec->dpms)(dev_priv, mode);
-	OUTREG(DVOC, INREG(DVOC) & ~DVO_ENABLE);
+	OUTREG(dvo_reg, INREG(dvo_reg) & ~DVO_ENABLE);
     }
 }
 
@@ -166,18 +172,27 @@ i830_dvo_mode_set(xf86OutputPtr output, 
     I830OutputPrivatePtr    intel_output = output->driver_private;
     int			    pipe = intel_crtc->pipe;
     CARD32		    dvo;
+    unsigned int	    dvo_reg, dvo_srcdim_reg;
     int			    dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B;
 
+    if (intel_output->i2c_drv->type & I830_DVO_CHIP_LVDS) {
+	dvo_reg = DVOA;
+	dvo_srcdim_reg = DVOA_SRCDIM;
+    } else {
+	dvo_reg = DVOC;
+	dvo_srcdim_reg = DVOC_SRCDIM;
+    }
+
     intel_output->i2c_drv->vid_rec->mode_set(intel_output->i2c_drv->dev_priv,
 					     mode);
 
     /* Save the data order, since I don't know what it should be set to. */
-    dvo = INREG(DVOC) & (DVO_PRESERVE_MASK | DVO_DATA_ORDER_GBRG);
+    dvo = INREG(dvo_reg) & (DVO_PRESERVE_MASK | DVO_DATA_ORDER_GBRG);
     dvo |= DVO_DATA_ORDER_FP | DVO_BORDER_ENABLE | DVO_BLANK_ACTIVE_HIGH;
 
     if (pipe == 1)
 	dvo |= DVO_PIPE_B_SELECT;
-
+    dvo |= DVO_PIPE_STALL;
     if (adjusted_mode->Flags & V_PHSYNC)
 	dvo |= DVO_HSYNC_ACTIVE_HIGH;
     if (adjusted_mode->Flags & V_PVSYNC)
@@ -188,11 +203,11 @@ i830_dvo_mode_set(xf86OutputPtr output, 
     /*OUTREG(DVOB_SRCDIM,
       (adjusted_mode->HDisplay << DVO_SRCDIM_HORIZONTAL_SHIFT) |
       (adjusted_mode->VDisplay << DVO_SRCDIM_VERTICAL_SHIFT));*/
-    OUTREG(DVOC_SRCDIM,
+    OUTREG(dvo_srcdim_reg,
 	   (adjusted_mode->HDisplay << DVO_SRCDIM_HORIZONTAL_SHIFT) |
 	   (adjusted_mode->VDisplay << DVO_SRCDIM_VERTICAL_SHIFT));
     /*OUTREG(DVOB, dvo);*/
-    OUTREG(DVOC, dvo);
+    OUTREG(dvo_reg, dvo);
 }
 
 /**
@@ -209,6 +224,33 @@ i830_dvo_detect(xf86OutputPtr output)
     return intel_output->i2c_drv->vid_rec->detect(dev_priv);
 }
 
+static DisplayModePtr
+i830_dvo_get_modes(xf86OutputPtr output)
+{
+    ScrnInfoPtr		    pScrn = output->scrn;
+    I830Ptr		    pI830 = I830PTR(pScrn);
+    I830OutputPrivatePtr    intel_output = output->driver_private;
+    DisplayModePtr	    modes;
+
+    /* We should probably have an i2c driver get_modes function for those
+     * devices which will have a fixed set of modes determined by the chip
+     * (TV-out, for example), but for now with just TMDS and LVDS, that's not
+     * the case.
+     */
+    modes = i830_ddc_get_modes(output);
+    if (modes != NULL)
+	return modes;
+
+    if (intel_output->i2c_drv->type & I830_DVO_CHIP_LVDS &&
+	pI830->panel_fixed_mode != NULL)
+    {
+	xf86PrintModeline(pScrn->scrnIndex, pI830->panel_fixed_mode);
+	return xf86DuplicateMode(pI830->panel_fixed_mode);
+    }
+
+    return NULL;
+}
+
 static void
 i830_dvo_destroy (xf86OutputPtr output)
 {
@@ -235,10 +277,47 @@ static const xf86OutputFuncsRec i830_dvo
     .mode_set = i830_dvo_mode_set,
     .commit = i830_output_commit,
     .detect = i830_dvo_detect,
-    .get_modes = i830_ddc_get_modes,
+    .get_modes = i830_dvo_get_modes,
     .destroy = i830_dvo_destroy
 };
 
+/**
+ * Attempts to get a fixed panel timing for LVDS (currently only the i830).
+ *
+ * Other chips with DVO LVDS will need to extend this to deal with the LVDS
+ * chip being on DVOB/C and having multiple pipes.
+ */
+static void
+i830_dvo_get_panel_timings(xf86OutputPtr output)
+{
+    ScrnInfoPtr		    pScrn = output->scrn;
+    I830Ptr		    pI830 = I830PTR(pScrn);
+    CARD32 dvoa = INREG(DVOA);
+
+    if (!IS_I830(pI830))
+	return;
+
+    assert(pI830->fixed_panel_mode == NULL);
+
+    /* If the DVOA port is active, that'll be the LVDS, so we can pull out
+     * its timings to get how the BIOS set up the panel.
+     */
+    if (dvoa & DVO_ENABLE) {
+	xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+	int pipe = (dvoa & DVO_PIPE_B_SELECT) ? 1 : 0;
+	xf86CrtcPtr crtc = xf86_config->crtc[pipe];
+
+	pI830->panel_fixed_mode = i830_crtc_mode_get(pScrn, crtc);
+	if (pI830->panel_fixed_mode != NULL)
+	    pI830->panel_fixed_mode->type |= M_T_PREFERRED;
+
+	if (dvoa & DVO_HSYNC_ACTIVE_HIGH)
+	    pI830->panel_fixed_mode->Flags |= V_PHSYNC;
+	if (dvoa & DVO_VSYNC_ACTIVE_HIGH)
+	    pI830->panel_fixed_mode->Flags |= V_PVSYNC;
+    }
+}
+
 void
 i830_dvo_init(ScrnInfoPtr pScrn)
 {
@@ -315,6 +394,9 @@ i830_dvo_init(ScrnInfoPtr pScrn)
 		return;
 	    }
 
+	    if (drv->type & I830_DVO_CHIP_LVDS)
+		i830_dvo_get_panel_timings(output);
+
 	    output->driver_private = intel_output;
 	    output->subpixel_order = SubPixelHorizontalRGB;
 	    output->interlaceAllowed = FALSE;
diff-tree f3168e3b0c5664a322ca6bb1c81fc94844cb30ab (from 1fc630f24f8ad9e304cb0761f9cacca2224203c4)
Author: Eric Anholt <eric at anholt.net>
Date:   Wed May 2 14:08:30 2007 -0700

    Disable non-working GTT decoding on i830, and fix map/unmap of GTT.

diff --git a/src/i830_driver.c b/src/i830_driver.c
index ad88f56..43f4e04 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -544,7 +544,10 @@ I830MapMMIO(ScrnInfoPtr pScrn)
 	    return FALSE;
       }
    } else {
-      pI830->GTTBase = pI830->MMIOBase + I830_PTE_BASE;
+      /* The GTT aperture on i830 is write-only.  We could probably map the
+       * actual physical pages that back it, but leave it alone for now.
+       */
+      pI830->GTTBase = NULL;
    }
 
    return TRUE;
@@ -584,6 +587,15 @@ I830UnmapMMIO(ScrnInfoPtr pScrn)
    xf86UnMapVidMem(pScrn->scrnIndex, (pointer) pI830->MMIOBase,
 		   I810_REG_SIZE);
    pI830->MMIOBase = NULL;
+
+   if (IS_I9XX(pI830)) {
+      if (IS_I965G(pI830))
+	 xf86UnMapVidMem(pScrn->scrnIndex, pI830->GTTBase, 512 * 1024);
+      else {
+	 xf86UnMapVidMem(pScrn->scrnIndex, pI830->GTTBase,
+			 pI830->FbMapSize / 1024);
+      }
+   }
 }
 
 static Bool
@@ -2279,6 +2291,9 @@ I830ScreenInit(int scrnIndex, ScreenPtr 
       pI830->used3D = pI8301->used3D;
    }
 
+   /* Need MMIO mapped to do GTT lookups during memory allocation. */
+   I830MapMMIO(pScrn);
+
 #if defined(XF86DRI)
    /*
     * If DRI is potentially usable, check if there is enough memory available
@@ -2419,6 +2434,8 @@ I830ScreenInit(int scrnIndex, ScreenPtr 
       allocation_done = TRUE;
    }
 
+   I830UnmapMMIO(pScrn);
+
    i830_describe_allocations(pScrn, 1, "");
 
    if (!IS_I965G(pI830) && pScrn->displayWidth > 2048) {
diff --git a/src/i830_memory.c b/src/i830_memory.c
index 9cf14e4..3ae10cf 100644
--- a/src/i830_memory.c
+++ b/src/i830_memory.c
@@ -324,7 +324,13 @@ static unsigned long
 i830_get_gtt_physical(ScrnInfoPtr pScrn, unsigned long offset)
 {
     I830Ptr pI830 = I830PTR(pScrn);
-    CARD32 gttentry = INGTT(offset / 1024);
+    CARD32 gttentry;
+
+    /* We don't have GTTBase set up on i830 yet. */
+    if (pI830->GTTBase == NULL)
+	return -1;
+
+    gttentry = INGTT(offset / 1024);
 
     /* Mask out these reserved bits on this hardware. */
     if (!IS_I965G(pI830))
diff-tree 1fc630f24f8ad9e304cb0761f9cacca2224203c4 (from d0ec37e9c0ceab1080700cd7be4a7cc58552d465)
Author: Eric Anholt <eric at anholt.net>
Date:   Wed May 2 13:29:21 2007 -0700

    Add DVO[ABC] register debugging.

diff --git a/src/i810_reg.h b/src/i810_reg.h
index 491c389..c3db5c9 100644
--- a/src/i810_reg.h
+++ b/src/i810_reg.h
@@ -1196,6 +1196,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN
 #define DVO_PIPE_STALL_UNUSED		(0 << 28)
 #define DVO_PIPE_STALL			(1 << 28)
 #define DVO_PIPE_STALL_TV		(2 << 28)
+#define DVO_PIPE_STALL_MASK		(3 << 28)
 #define DVO_USE_VGA_SYNC		(1 << 15)
 #define DVO_DATA_ORDER_I740		(0 << 14)
 #define DVO_DATA_ORDER_FP		(1 << 14)
diff --git a/src/i830_debug.c b/src/i830_debug.c
index c0261a6..73b5d1c 100644
--- a/src/i830_debug.c
+++ b/src/i830_debug.c
@@ -286,6 +286,33 @@ DEBUGSTRING(i830_debug_lvds)
 		     enable, pipe, depth, channels);
 }
 
+DEBUGSTRING(i830_debug_dvo)
+{
+    char *enable = val & DVO_ENABLE ? "enabled" : "disabled";
+    char pipe = val & DVO_PIPE_B_SELECT ? 'B' : 'A';
+    char *stall;
+    char hsync = val & DVO_HSYNC_ACTIVE_HIGH ? '+' : '-';
+    char vsync = val & DVO_VSYNC_ACTIVE_HIGH ? '+' : '-';
+
+    switch (val & DVO_PIPE_STALL_MASK) {
+    case DVO_PIPE_STALL_UNUSED:
+	stall = "no stall";
+	break;
+    case DVO_PIPE_STALL:
+	stall = "stall";
+	break;
+    case DVO_PIPE_STALL_TV:
+	stall = "TV stall";
+	break;
+    default:
+	stall = "unknown stall";
+	break;
+    }
+
+    return XNFprintf("%s, pipe %c, %s, %chsync, %cvsync",
+		     enable, pipe, stall, hsync, vsync);
+}
+
 DEBUGSTRING(i830_debug_sdvo)
 {
     char *enable = val & SDVO_ENABLE ? "enabled" : "disabled";
@@ -339,9 +366,9 @@ static struct i830SnapshotRec {
 
     DEFINEREG2(ADPA, i830_debug_adpa),
     DEFINEREG2(LVDS, i830_debug_lvds),
-    DEFINEREG(DVOA),
-    DEFINEREG(DVOB),
-    DEFINEREG(DVOC),
+    DEFINEREG2(DVOA, i830_debug_dvo),
+    DEFINEREG2(DVOB, i830_debug_dvo),
+    DEFINEREG2(DVOC, i830_debug_dvo),
     DEFINEREG(DVOA_SRCDIM),
     DEFINEREG(DVOB_SRCDIM),
     DEFINEREG(DVOC_SRCDIM),
diff-tree d0ec37e9c0ceab1080700cd7be4a7cc58552d465 (from 490d05f99d2b62dd612d514d9ae0badbac9285ce)
Author: Eric Anholt <eric at anholt.net>
Date:   Tue May 1 15:56:37 2007 -0700

    Make the DVO output name LVDS if it's an LVDS chip.

diff --git a/src/i830_dvo.c b/src/i830_dvo.c
index 4b37228..96b29e7 100644
--- a/src/i830_dvo.c
+++ b/src/i830_dvo.c
@@ -242,7 +242,6 @@ static const xf86OutputFuncsRec i830_dvo
 void
 i830_dvo_init(ScrnInfoPtr pScrn)
 {
-    xf86OutputPtr output;
     I830OutputPrivatePtr intel_output;
     int ret;
     int i;
@@ -251,27 +250,15 @@ i830_dvo_init(ScrnInfoPtr pScrn)
     int gpio_inited = 0;
     I2CBusPtr pI2CBus = NULL;
 
-    output = xf86OutputCreate (pScrn, &i830_dvo_output_funcs,
-				   "TMDS");
-    if (!output)
-	return;
     intel_output = xnfcalloc (sizeof (I830OutputPrivateRec), 1);
     if (!intel_output)
-    {
-	xf86OutputDestroy (output);
 	return;
-    }
     intel_output->type = I830_OUTPUT_DVO;
-    output->driver_private = intel_output;
-    output->subpixel_order = SubPixelHorizontalRGB;
-    output->interlaceAllowed = FALSE;
-    output->doubleScanAllowed = FALSE;
-    
+
     /* Set up the DDC bus */
     ret = I830I2CInit(pScrn, &intel_output->pDDCBus, GPIOD, "DVODDC_D");
-    if (!ret)
-    {
-	xf86OutputDestroy (output);
+    if (!ret) {
+	xfree(intel_output);
 	return;
     }
 
@@ -311,6 +298,28 @@ i830_dvo_init(ScrnInfoPtr pScrn)
 	    ret_ptr = drv->vid_rec->init(pI2CBus, drv->address);
 
 	if (ret_ptr != NULL) {
+	    xf86OutputPtr output;
+
+	    if (drv->type & I830_DVO_CHIP_LVDS) {
+		output = xf86OutputCreate(pScrn, &i830_dvo_output_funcs,
+					  "LVDS");
+	    } else {
+		output = xf86OutputCreate(pScrn, &i830_dvo_output_funcs,
+					  "TMDS");
+	    }
+	    if (output == NULL) {
+		xf86DestroyI2CBusRec(pI2CBus, TRUE, TRUE);
+		xf86DestroyI2CBusRec(intel_output->pDDCBus, TRUE, TRUE);
+		xfree(intel_output);
+		xf86UnloadSubModule(drv->modhandle);
+		return;
+	    }
+
+	    output->driver_private = intel_output;
+	    output->subpixel_order = SubPixelHorizontalRGB;
+	    output->interlaceAllowed = FALSE;
+	    output->doubleScanAllowed = FALSE;
+
 	    drv->dev_priv = ret_ptr;
 	    intel_output->i2c_drv = drv;
 	    intel_output->pI2CBus = pI2CBus;
@@ -322,5 +331,6 @@ i830_dvo_init(ScrnInfoPtr pScrn)
     /* Didn't find a chip, so tear down. */
     if (pI2CBus != NULL)
 	xf86DestroyI2CBusRec(pI2CBus, TRUE, TRUE);
-    xf86OutputDestroy (output);
+    xf86DestroyI2CBusRec(intel_output->pDDCBus, TRUE, TRUE);
+    xfree(intel_output);
 }
diff-tree 490d05f99d2b62dd612d514d9ae0badbac9285ce (from c7bb34e83d7c459d932d01070cfeffbbf6c703ac)
Author: Eric Anholt <eric at anholt.net>
Date:   Tue May 1 15:47:01 2007 -0700

    Fix typo in previous commit with s/XF86_DRI/XF86DRI/

diff --git a/src/i830_memory.c b/src/i830_memory.c
index 23e7dbc..9cf14e4 100644
--- a/src/i830_memory.c
+++ b/src/i830_memory.c
@@ -250,7 +250,7 @@ i830_free_3d_memory(ScrnInfoPtr pScrn)
 {
     I830Ptr pI830 = I830PTR(pScrn);
 
-#ifdef XF86_DRI
+#ifdef XF86DRI
     i830_free_memory(pScrn, pI830->back_buffer);
     pI830->back_buffer = NULL;
     i830_free_memory(pScrn, pI830->third_buffer);
diff-tree c7bb34e83d7c459d932d01070cfeffbbf6c703ac (from cae0ae237b79fa7d3a82dfc8d3fb595ccb6c63e1)
Author: Dave Airlie <airlied at linux.ie>
Date:   Wed May 2 14:25:39 2007 +1000

    disable all outputs on EnterVT
    
    This disables all outputs on EnterVT as the SDVO output can confuse
    the VGA output if the BIOS has enabled it on the same pipe but X
    isn't going to use the SDVO.
    
    Worked out on irc with keithp

diff --git a/src/i830_driver.c b/src/i830_driver.c
index 4990b8f..ad88f56 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -2870,6 +2870,8 @@ I830EnterVT(int scrnIndex, int flags)
 {
    ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
    I830Ptr  pI830 = I830PTR(pScrn);
+   xf86CrtcConfigPtr	config = XF86_CRTC_CONFIG_PTR(pScrn);
+   int o;
 
    DPRINTF(PFX, "Enter VT\n");
 
@@ -2900,6 +2902,11 @@ I830EnterVT(int scrnIndex, int flags)
    memset(pI830->FbBase + pScrn->fbOffset, 0,
 	  pScrn->virtualY * pScrn->displayWidth * pI830->cpp);
 
+   for (o = 0; o < config->num_output; o++) {
+   	xf86OutputPtr  output = config->output[o];
+	output->funcs->dpms(output, DPMSModeOff);
+   }
+
    if (!xf86SetDesiredModes (pScrn))
       return FALSE;
    
diff-tree cae0ae237b79fa7d3a82dfc8d3fb595ccb6c63e1 (from 6748d620fbf39dd98982856c09256bdec0fc82a1)
Author: Samuel Thibault <samuel.thibault at ens-lyon.org>
Date:   Tue May 1 12:41:18 2007 -0700

    Bug #10714: Fix build without DRI.

diff --git a/src/i830.h b/src/i830.h
index f69ad73..8034302 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -307,6 +307,9 @@ typedef struct _I830Rec {
    int *used3D;
 
    i830_memory *logical_context;
+
+   unsigned int front_tiled;
+
 #ifdef XF86DRI
    i830_memory *back_buffer;
    i830_memory *third_buffer;
@@ -319,7 +322,6 @@ typedef struct _I830Rec {
    int mmModeFlags;
    int mmSize;
 
-   unsigned int front_tiled;
    unsigned int back_tiled;
    unsigned int third_tiled;
    unsigned int depth_tiled;
diff --git a/src/i830_memory.c b/src/i830_memory.c
index 2cc9327..23e7dbc 100644
--- a/src/i830_memory.c
+++ b/src/i830_memory.c
@@ -231,11 +231,13 @@ i830_reset_allocations(ScrnInfoPtr pScrn
     pI830->exa_965_state = NULL;
     pI830->overlay_regs = NULL;
     pI830->logical_context = NULL;
+#ifdef XF86DRI
     pI830->back_buffer = NULL;
     pI830->third_buffer = NULL;
     pI830->depth_buffer = NULL;
     pI830->textures = NULL;
     pI830->memory_manager = NULL;
+#endif
     pI830->LpRing->mem = NULL;
 
     /* Reset the fence register allocation. */
@@ -248,6 +250,7 @@ i830_free_3d_memory(ScrnInfoPtr pScrn)
 {
     I830Ptr pI830 = I830PTR(pScrn);
 
+#ifdef XF86_DRI
     i830_free_memory(pScrn, pI830->back_buffer);
     pI830->back_buffer = NULL;
     i830_free_memory(pScrn, pI830->third_buffer);
@@ -258,6 +261,7 @@ i830_free_3d_memory(ScrnInfoPtr pScrn)
     pI830->textures = NULL;
     i830_free_memory(pScrn, pI830->memory_manager);
     pI830->memory_manager = NULL;
+#endif
 }
 
 /**
@@ -691,6 +695,7 @@ i830_describe_allocations(ScrnInfoPtr pS
 	i830_describe_tiling(pScrn, verbosity, prefix, pI830->front_buffer,
 			     pI830->front_tiled);
     }
+#ifdef XF86DRI
     if (pI830->back_buffer != NULL) {
 	i830_describe_tiling(pScrn, verbosity, prefix, pI830->back_buffer,
 			     pI830->back_tiled);
@@ -703,6 +708,7 @@ i830_describe_allocations(ScrnInfoPtr pS
 	i830_describe_tiling(pScrn, verbosity, prefix, pI830->depth_buffer,
 			     pI830->depth_tiled);
     }
+#endif
 }
 
 static Bool
@@ -1330,7 +1336,6 @@ i830_allocate_3d_memory(ScrnInfoPtr pScr
 }
 #endif
 
-#ifdef XF86DRI
 /**
  * Sets up a fence area for the hardware.
  *
@@ -1529,7 +1534,6 @@ i830_set_fence(ScrnInfoPtr pScrn, int nr
 
     pI830->fence[nr] = val;
 }
-#endif
 
 /**
  * Called at EnterVT to grab the AGP GART and bind our allocations.
diff-tree 6748d620fbf39dd98982856c09256bdec0fc82a1 (from a4f1a7872f6f959bb4bc6568face710bee3589de)
Author: Eric Anholt <eric at anholt.net>
Date:   Mon Apr 30 17:27:23 2007 -0700

    Ignore VideoRam now that its original purpose is obsolete.
    
    It had been necessary to allow more than a small amount of memory to be
    allocated, but now those old small allocations people had configured are
    getting in the way.

diff --git a/man/intel.man b/man/intel.man
index 178ff0a..daf9030 100644
--- a/man/intel.man
+++ b/man/intel.man
@@ -43,17 +43,10 @@ NetBSD, and Solaris have such kernel dri
 By default, the i810 will use 8 megabytes
 of system memory for graphics.  For the 830M and later, the driver will
 automatically size its memory allocation according to the features it will
-support.  The amount of memory used may be limited by using the
+support.  The
 .B VideoRam
-entry in the config file
-.B "Device"
-section.  Limiting the amount of memory used may result in features being
-disabled, so if you choose to configure it, it is advisable to check the
-__xservername__
-log file to see if any features have been disabled because of insufficient
-video memory.  In particular, DRI support or tiling mode may be disabled
-with insufficient video memory.  Either of these being disabled will
-reduce performance for 3D applications.
+option, which in the past had been necessary to allow more than some small
+amount of memory to be allocated, is now ignored.
 .PP
 The following driver
 .B Options
diff --git a/src/i830_driver.c b/src/i830_driver.c
index e38b77b..4990b8f 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -2162,8 +2162,30 @@ I830ScreenInit(int scrnIndex, ScreenPtr 
       from = X_DEFAULT;
       pScrn->videoRam = pI830->FbMapSize / KB(1);
    } else {
+#if 0
       from = X_CONFIG;
       pScrn->videoRam = pI830->pEnt->device->videoRam;
+#else
+      /* Disable VideoRam configuration, at least for now.  Previously,
+       * VideoRam was necessary to avoid overly low limits on allocated
+       * memory, so users created larger, yet still small, fixed allocation
+       * limits in their config files.  Now, the driver wants to allocate more,
+       * and the old intention of the VideoRam lines that had been entered is
+       * obsolete.
+       */
+      from = X_DEFAULT;
+      pScrn->videoRam = pI830->FbMapSize / KB(1);
+
+      if (pScrn->videoRam != pI830->pEnt->device->videoRam) {
+	 xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+		    "VideoRam configuration found, which is no longer "
+		    "recommended.\n");
+	 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+		    "Continuing with default %dkB VideoRam instead of %d "
+		    "kB.\n",
+		    pScrn->videoRam, pI830->pEnt->device->videoRam);
+      }
+#endif
    }
 
    /* Limit videoRam to how much we might be able to allocate from AGP */
diff-tree a4f1a7872f6f959bb4bc6568face710bee3589de (from 7d0d34cfdcc67d07e7667e13a9413743853134f8)
Author: Eric Anholt <eric at anholt.net>
Date:   Mon Apr 30 17:13:09 2007 -0700

    Allow physical-memory allocations within stolen memory.
    
    Because stolen memory happens to be a contiguous block of high system memory,
    we can just read the GTT entries for it to get physical addresses for our
    allocations there if needed.  This reduces fragmentation of the aperture space,
    and will often reclaim up to 7 MB of memory that had been left unused since the
    simplified aperture manager was put in place, but without reintroducing the
    complexities of the old aperture manager.

diff --git a/src/common.h b/src/common.h
index f299e5d..f45fc8e 100644
--- a/src/common.h
+++ b/src/common.h
@@ -233,6 +233,7 @@ union intfloat {
 #define INREG8(addr)        *(volatile CARD8  *)(RecPtr->MMIOBase + (addr))
 #define INREG16(addr)       *(volatile CARD16 *)(RecPtr->MMIOBase + (addr))
 #define INREG(addr)         *(volatile CARD32 *)(RecPtr->MMIOBase + (addr))
+#define INGTT(addr)         *(volatile CARD32 *)(RecPtr->GTTBase + (addr))
 #define POSTING_READ(addr)  (void)INREG(addr)
 
 #define OUTREG8(addr, val) do {						\
diff --git a/src/i810_reg.h b/src/i810_reg.h
index bc944fe..491c389 100644
--- a/src/i810_reg.h
+++ b/src/i810_reg.h
@@ -526,6 +526,15 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN
 #define PGETBL_SIZE_256KB   (1 << 1)
 #define PGETBL_SIZE_128KB   (2 << 1)
 
+#define I830_PTE_BASE			0x10000
+#define PTE_ADDRESS_MASK		0xfffff000
+#define PTE_ADDRESS_MASK_HIGH		0x000000f0 /* i915+ */
+#define PTE_MAPPING_TYPE_UNCACHED	(0 << 1)
+#define PTE_MAPPING_TYPE_DCACHE		(1 << 1) /* i830 only */
+#define PTE_MAPPING_TYPE_CACHED		(3 << 1)
+#define PTE_MAPPING_TYPE_MASK		(3 << 1)
+#define PTE_VALID			(1 << 0)
+
 /** @defgroup PGE_ERR
  * @{
  */
@@ -577,18 +586,6 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN
 # define PGTBL_ERR_HOST_GTT_PTE			(1 << 0)
 /** @} */
 
-/* Page table entries loaded via mmio region, p323
- */
-#define PTE_BASE         0x10000
-#define PTE_ADDR_MASK       0x3FFFF000
-#define PTE_TYPE_MASK       0x00000006
-#define PTE_LOCAL           0x00000002
-#define PTE_MAIN_UNCACHED   0x00000000
-#define PTE_MAIN_CACHED     0x00000006
-#define PTE_VALID_MASK      0x00000001
-#define PTE_VALID           0x00000001
-
-
 /* Ring buffer registers, p277, overview p19
  */
 #define LP_RING     0x2030
diff --git a/src/i830.h b/src/i830.h
index d81857b..f69ad73 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -261,6 +261,7 @@ enum last_3d {
 
 typedef struct _I830Rec {
    unsigned char *MMIOBase;
+   unsigned char *GTTBase;
    unsigned char *FbBase;
    int cpp;
 
diff --git a/src/i830_driver.c b/src/i830_driver.c
index 235ee2a..e38b77b 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -521,6 +521,32 @@ I830MapMMIO(ScrnInfoPtr pScrn)
 				   pI830->MMIOAddr, I810_REG_SIZE);
    if (!pI830->MMIOBase)
       return FALSE;
+
+   /* Set up the GTT mapping for the various places it has been moved over
+    * time.
+    */
+   if (IS_I9XX(pI830)) {
+      if (IS_I965G(pI830)) {
+	 pI830->GTTBase = xf86MapPciMem(pScrn->scrnIndex, mmioFlags,
+					pI830->PciTag,
+					pI830->MMIOAddr + (512 * 1024),
+					512 * 1024);
+	 if (pI830->GTTBase == NULL)
+	    return FALSE;
+      } else {
+	 CARD32 gttaddr = pI830->PciInfo->memBase[3] & 0xFFFFFF00;
+
+	 pI830->GTTBase = xf86MapPciMem(pScrn->scrnIndex, mmioFlags,
+					pI830->PciTag,
+					gttaddr,
+					pI830->FbMapSize / 1024);
+	 if (pI830->GTTBase == NULL)
+	    return FALSE;
+      }
+   } else {
+      pI830->GTTBase = pI830->MMIOBase + I830_PTE_BASE;
+   }
+
    return TRUE;
 }
 
@@ -1136,6 +1162,27 @@ I830PreInit(ScrnInfoPtr pScrn, int flags
    }
    xf86CrtcSetSizeRange (pScrn, 320, 200, max_width, max_height);
 
+   if (IS_I830(pI830) || IS_845G(pI830)) {
+      PCITAG bridge;
+      CARD16 gmch_ctrl;
+
+      bridge = pciTag(0, 0, 0);		/* This is always the host bridge */
+      gmch_ctrl = pciReadWord(bridge, I830_GMCH_CTRL);
+      if ((gmch_ctrl & I830_GMCH_MEM_MASK) == I830_GMCH_MEM_128M) {
+	 pI830->FbMapSize = 0x8000000;
+      } else {
+	 pI830->FbMapSize = 0x4000000; /* 64MB - has this been tested ?? */
+      }
+   } else {
+      if (IS_I9XX(pI830)) {
+	 pI830->FbMapSize = 1UL << pciGetBaseSize(pI830->PciTag, 2, TRUE,
+						  NULL);
+      } else {
+	 /* 128MB aperture for later i8xx series. */
+	 pI830->FbMapSize = 0x8000000;
+      }
+   }
+
    /* Some of the probing needs MMIO access, so map it here. */
    I830MapMMIO(pScrn);
 
@@ -1159,27 +1206,6 @@ I830PreInit(ScrnInfoPtr pScrn, int flags
 		(1 << 23) | (2 << 16));
 #endif
 
-   if (IS_I830(pI830) || IS_845G(pI830)) {
-      PCITAG bridge;
-      CARD16 gmch_ctrl;
-
-      bridge = pciTag(0, 0, 0);		/* This is always the host bridge */
-      gmch_ctrl = pciReadWord(bridge, I830_GMCH_CTRL);
-      if ((gmch_ctrl & I830_GMCH_MEM_MASK) == I830_GMCH_MEM_128M) {
-	 pI830->FbMapSize = 0x8000000;
-      } else {
-	 pI830->FbMapSize = 0x4000000; /* 64MB - has this been tested ?? */
-      }
-   } else {
-      if (IS_I9XX(pI830)) {
-	 pI830->FbMapSize = 1UL << pciGetBaseSize(pI830->PciTag, 2, TRUE,
-						  NULL);
-      } else {
-	 /* 128MB aperture for later i8xx series. */
-	 pI830->FbMapSize = 0x8000000;
-      }
-   }
-
    if (pI830->PciInfo->chipType == PCI_CHIP_E7221_G)
       num_pipe = 1;
    else
diff --git a/src/i830_memory.c b/src/i830_memory.c
index 268d6c5..2cc9327 100644
--- a/src/i830_memory.c
+++ b/src/i830_memory.c
@@ -309,6 +309,86 @@ i830_allocator_init(ScrnInfoPtr pScrn, u
     return TRUE;
 }
 
+/**
+ * Reads a GTT entry for the memory at the given offset and returns the
+ * physical address.
+ *
+ * \return physical address if successful.
+ * \return (unsigned long)-1 if unsuccessful.
+ */
+static unsigned long
+i830_get_gtt_physical(ScrnInfoPtr pScrn, unsigned long offset)
+{
+    I830Ptr pI830 = I830PTR(pScrn);
+    CARD32 gttentry = INGTT(offset / 1024);
+
+    /* Mask out these reserved bits on this hardware. */
+    if (!IS_I965G(pI830))
+	gttentry &= ~PTE_ADDRESS_MASK_HIGH;
+
+    /* If it's not a mapping type we know, then bail. */
+    if ((gttentry & PTE_MAPPING_TYPE_MASK) != PTE_MAPPING_TYPE_UNCACHED &&
+	(gttentry & PTE_MAPPING_TYPE_MASK) != PTE_MAPPING_TYPE_CACHED)
+    {
+	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+		   "Unusable physical mapping type 0x%08x\n",
+		   (unsigned int)(gttentry & PTE_MAPPING_TYPE_MASK));
+	return -1;
+    }
+    /* If we can't represent the address with an unsigned long, bail. */
+    if (sizeof(unsigned long) == 4 &&
+	(gttentry & PTE_ADDRESS_MASK_HIGH) != 0)
+    {
+	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+		   "High memory PTE (0x%08x) on 32-bit system\n",
+		   (unsigned int)gttentry);
+	return -1;
+    }
+    assert((gttentry & PTE_VALID) != 0);
+
+    return (gttentry & PTE_ADDRESS_MASK) |
+	(gttentry & PTE_ADDRESS_MASK_HIGH << (32 - 4));
+}
+
+/**
+ * Reads the GTT entries for stolen memory at the given offset, returning the
+ * physical address.
+ *
+ * \return physical address if successful.
+ * \return (unsigned long)-1 if unsuccessful.
+ */
+static unsigned long
+i830_get_stolen_physical(ScrnInfoPtr pScrn, unsigned long offset,
+			 unsigned long size)
+{
+    I830Ptr pI830 = I830PTR(pScrn);
+    unsigned long physical, scan;
+
+    /* Check that the requested region is within stolen memory. */
+    if (offset + size >= pI830->stolen_size)
+	return -1;
+
+    physical = i830_get_gtt_physical(pScrn, offset);
+    if (physical == -1)
+	return -1;
+
+    /* Check that the following pages in our allocation follow the first page
+     * contiguously.
+     */
+    for (scan = offset + 4096; scan < offset + size; scan += 4096) {
+	unsigned long scan_physical = i830_get_gtt_physical(pScrn, scan);
+
+	if ((scan - offset) != (scan_physical - physical)) {
+	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+		       "Non-contiguous GTT entries: (%ld,%ld) vs (%ld,%ld)\n",
+		       scan, scan_physical, offset, physical);
+	    return -1;
+	}
+    }
+
+    return physical;
+}
+
 /* Allocate aperture space for the given size and alignment, and returns the
  * memory allocation.
  *
@@ -341,13 +421,25 @@ i830_allocate_aperture(ScrnInfoPtr pScrn
 	alignment = GTT_PAGE_SIZE;
 
     for (scan = pI830->memory_list; scan->next != NULL; scan = scan->next) {
-	mem->offset = scan->end;
-	/* For allocations requiring physical addresses, we have to use AGP
-	 * memory, so move the allocation up out of stolen memory.
-	 */
-	if ((flags & NEED_PHYSICAL_ADDR) && mem->offset < pI830->stolen_size)
-	    mem->offset = pI830->stolen_size;
-	mem->offset = ROUND_TO(mem->offset, alignment);
+	mem->offset = ROUND_TO(scan->end, alignment);
+	if ((flags & NEED_PHYSICAL_ADDR) && mem->offset < pI830->stolen_size) {
+	    /* If the allocation is entirely within stolen memory, and we're
+	     * able to get the physical addresses out of the GTT and check that
+	     * it's contiguous (it ought to be), then we can do our physical
+	     * allocations there and not bother the kernel about it.  This
+	     * helps avoid aperture fragmentation from our physical
+	     * allocations.
+	     */
+	    mem->bus_addr = i830_get_stolen_physical(pScrn, mem->offset,
+						     mem->size);
+
+	    if (mem->bus_addr == ((unsigned long)-1)) {
+		/* Move the start of the allocation to just past the end of
+		 * stolen memory.
+		 */
+		mem->offset = ROUND_TO(pI830->stolen_size, alignment);
+	    }
+	}
 
 	mem->end = mem->offset + size;
 	if (flags & ALIGN_BOTH_ENDS)
@@ -385,11 +477,8 @@ i830_allocate_agp_memory(ScrnInfoPtr pSc
     if (mem->key != -1)
 	return TRUE;
 
-    if (mem->offset + mem->size <= pI830->stolen_size &&
-	!(flags & NEED_PHYSICAL_ADDR))
-    {
+    if (mem->offset + mem->size <= pI830->stolen_size)
 	return TRUE;
-    }
 
     if (mem->offset < pI830->stolen_size)
 	mem->agp_offset = pI830->stolen_size;
diff-tree 7d0d34cfdcc67d07e7667e13a9413743853134f8 (from 138ac8f36cb4e4b3776f313955372522646acbb2)
Author: Eric Anholt <eric at anholt.net>
Date:   Mon Apr 30 10:39:54 2007 -0700

    Disable some clock gating functions documented to work incorrectly.

diff --git a/src/i810_reg.h b/src/i810_reg.h
index eaa8bb5..bc944fe 100644
--- a/src/i810_reg.h
+++ b/src/i810_reg.h
@@ -958,7 +958,101 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN
 
 #define D_STATE			0x6104
 #define DSPCLK_GATE_D		0x6200
+# define TVRUNIT_CLOCK_GATE_DISABLE		(1 << 23) /* 915-945 */
+# define TVCUNIT_CLOCK_GATE_DISABLE		(1 << 22) /* 915-945 */
+# define TVFUNIT_CLOCK_GATE_DISABLE		(1 << 21) /* 915-945 */
+# define TVEUNIT_CLOCK_GATE_DISABLE		(1 << 20) /* 915-945 */
+# define DVSUNIT_CLOCK_GATE_DISABLE		(1 << 19) /* 915-945 */
+# define DSSUNIT_CLOCK_GATE_DISABLE		(1 << 18) /* 915-945 */
+# define DDBUNIT_CLOCK_GATE_DISABLE		(1 << 17) /* 915-945 */
+# define DPRUNIT_CLOCK_GATE_DISABLE		(1 << 16) /* 915-945 */
+# define DPFUNIT_CLOCK_GATE_DISABLE		(1 << 15) /* 915-945 */
+# define DPBMUNIT_CLOCK_GATE_DISABLE		(1 << 14) /* 915-945 */
+# define DPLSUNIT_CLOCK_GATE_DISABLE		(1 << 13) /* 915-945 */
+# define DPLUNIT_CLOCK_GATE_DISABLE		(1 << 12) /* 915-945 */
+# define DPOUNIT_CLOCK_GATE_DISABLE		(1 << 11)
+# define DPBUNIT_CLOCK_GATE_DISABLE		(1 << 10)
+# define DPCUNIT_CLOCK_GATE_DISABLE		(1 << 9)
+# define DPUNIT_CLOCK_GATE_DISABLE		(1 << 8)
+# define VRUNIT_CLOCK_GATE_DISABLE		(1 << 7) /* 915+: reserved */
+# define OVHUNIT_CLOCK_GATE_DISABLE		(1 << 6) /* 830-865 */
+# define DPIOUNIT_CLOCK_GATE_DISABLE		(1 << 6) /* 915-945 */
+# define OVFUNIT_CLOCK_GATE_DISABLE		(1 << 5)
+# define OVBUNIT_CLOCK_GATE_DISABLE		(1 << 4)
+/**
+ * This bit must be set on the 830 to prevent hangs when turning off the
+ * overlay scaler.
+ */
+# define OVRUNIT_CLOCK_GATE_DISABLE		(1 << 3)
+# define OVCUNIT_CLOCK_GATE_DISABLE		(1 << 2)
+# define OVUUNIT_CLOCK_GATE_DISABLE		(1 << 1)
+# define ZVUNIT_CLOCK_GATE_DISABLE		(1 << 0) /* 830 */
+# define OVLUNIT_CLOCK_GATE_DISABLE		(1 << 0) /* 845,865 */
+
 #define RENCLK_GATE_D1		0x6204
+# define BLITTER_CLOCK_GATE_DISABLE		(1 << 13) /* 945GM only */
+# define MPEG_CLOCK_GATE_DISABLE		(1 << 12) /* 945GM only */
+# define PC_FE_CLOCK_GATE_DISABLE		(1 << 11)
+# define PC_BE_CLOCK_GATE_DISABLE		(1 << 10)
+# define WINDOWER_CLOCK_GATE_DISABLE		(1 << 9)
+# define INTERPOLATOR_CLOCK_GATE_DISABLE	(1 << 8)
+# define COLOR_CALCULATOR_CLOCK_GATE_DISABLE	(1 << 7)
+# define MOTION_COMP_CLOCK_GATE_DISABLE		(1 << 6)
+# define MAG_CLOCK_GATE_DISABLE			(1 << 5)
+/** This bit must be unset on 855,865 */
+# define MECI_CLOCK_GATE_DISABLE		(1 << 4)
+# define DCMP_CLOCK_GATE_DISABLE		(1 << 3)
+# define MEC_CLOCK_GATE_DISABLE			(1 << 2)
+# define MECO_CLOCK_GATE_DISABLE		(1 << 1)
+/** This bit must be set on 855,865. */
+# define SV_CLOCK_GATE_DISABLE			(1 << 0)
+# define I915_MPEG_CLOCK_GATE_DISABLE		(1 << 16)
+# define I915_VLD_IP_PR_CLOCK_GATE_DISABLE	(1 << 15)
+# define I915_MOTION_COMP_CLOCK_GATE_DISABLE	(1 << 14)
+# define I915_BD_BF_CLOCK_GATE_DISABLE		(1 << 13)
+# define I915_SF_SE_CLOCK_GATE_DISABLE		(1 << 12)
+# define I915_WM_CLOCK_GATE_DISABLE		(1 << 11)
+# define I915_IZ_CLOCK_GATE_DISABLE		(1 << 10)
+# define I915_PI_CLOCK_GATE_DISABLE		(1 << 9)
+# define I915_DI_CLOCK_GATE_DISABLE		(1 << 8)
+# define I915_SH_SV_CLOCK_GATE_DISABLE		(1 << 7)
+# define I915_PL_DG_QC_FT_CLOCK_GATE_DISABLE	(1 << 6)
+# define I915_SC_CLOCK_GATE_DISABLE		(1 << 5)
+# define I915_FL_CLOCK_GATE_DISABLE		(1 << 4)
+# define I915_DM_CLOCK_GATE_DISABLE		(1 << 3)
+# define I915_PS_CLOCK_GATE_DISABLE		(1 << 2)
+# define I915_CC_CLOCK_GATE_DISABLE		(1 << 1)
+# define I915_BY_CLOCK_GATE_DISABLE		(1 << 0)
+
+# define I965_RCZ_CLOCK_GATE_DISABLE		(1 << 30)
+/** This bit must always be set on 965G/965GM */
+# define I965_RCC_CLOCK_GATE_DISABLE		(1 << 29)
+# define I965_RCPB_CLOCK_GATE_DISABLE		(1 << 28)
+# define I965_DAP_CLOCK_GATE_DISABLE		(1 << 27)
+# define I965_ROC_CLOCK_GATE_DISABLE		(1 << 26)
+# define I965_GW_CLOCK_GATE_DISABLE		(1 << 25)
+# define I965_TD_CLOCK_GATE_DISABLE		(1 << 24)
+/** This bit must always be set on 965G */
+# define I965_ISC_CLOCK_GATE_DISABLE		(1 << 23)
+# define I965_IC_CLOCK_GATE_DISABLE		(1 << 22)
+# define I965_EU_CLOCK_GATE_DISABLE		(1 << 21)
+# define I965_IF_CLOCK_GATE_DISABLE		(1 << 20)
+# define I965_TC_CLOCK_GATE_DISABLE		(1 << 19)
+# define I965_SO_CLOCK_GATE_DISABLE		(1 << 17)
+# define I965_FBC_CLOCK_GATE_DISABLE		(1 << 16)
+# define I965_MARI_CLOCK_GATE_DISABLE		(1 << 15)
+# define I965_MASF_CLOCK_GATE_DISABLE		(1 << 14)
+# define I965_MAWB_CLOCK_GATE_DISABLE		(1 << 13)
+# define I965_EM_CLOCK_GATE_DISABLE		(1 << 12)
+# define I965_UC_CLOCK_GATE_DISABLE		(1 << 11)
+# define I965_SI_CLOCK_GATE_DISABLE		(1 << 6)
+# define I965_MT_CLOCK_GATE_DISABLE		(1 << 5)
+# define I965_PL_CLOCK_GATE_DISABLE		(1 << 4)
+# define I965_DG_CLOCK_GATE_DISABLE		(1 << 3)
+# define I965_QC_CLOCK_GATE_DISABLE		(1 << 2)
+# define I965_FT_CLOCK_GATE_DISABLE		(1 << 1)
+# define I965_DM_CLOCK_GATE_DISABLE		(1 << 0)
+
 #define RENCLK_GATE_D2		0x6208
 #define RAMCLK_GATE_D		0x6210		/* CRL only */
 
diff --git a/src/i830_driver.c b/src/i830_driver.c
index 2c1e514..235ee2a 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -1653,6 +1653,19 @@ SetHWOperatingState(ScrnInfoPtr pScrn)
 
    DPRINTF(PFX, "SetHWOperatingState\n");
 
+   /* Disable clock gating reported to work incorrectly according to the specs.
+    */
+   if (IS_I965GM(pI830)) {
+      OUTREG(RENCLK_GATE_D1, I965_RCC_CLOCK_GATE_DISABLE);
+   } else if (IS_I965G(pI830)) {
+      OUTREG(RENCLK_GATE_D1,
+	     I965_RCC_CLOCK_GATE_DISABLE | I965_ISC_CLOCK_GATE_DISABLE);
+   } else if (IS_I855(pI830) || IS_I865G(pI830)) {
+      OUTREG(RENCLK_GATE_D1, SV_CLOCK_GATE_DISABLE);
+   } else if (IS_I830(pI830)) {
+      OUTREG(DSPCLK_GATE_D, OVRUNIT_CLOCK_GATE_DISABLE);
+   }
+
    if (!pI830->noAccel)
       SetRingRegs(pScrn);
    SetFenceRegs(pScrn);
diff-tree 138ac8f36cb4e4b3776f313955372522646acbb2 (from 0cd524e5411e35c8483c02ecc5062625809e6fc6)
Author: Wang Zhenyu <zhenyu.z.wang at intel.com>
Date:   Sun Apr 29 14:43:19 2007 +0800

    Alloc state mem buffer on 965G for xaa rotation
    
    965G needs state mem buffer to setup render pipeline.
    Thanks Barry Scrott for report this.

diff --git a/src/i830_memory.c b/src/i830_memory.c
index 15d241b..268d6c5 100644
--- a/src/i830_memory.c
+++ b/src/i830_memory.c
@@ -957,20 +957,18 @@ i830_allocate_2d_memory(ScrnInfoPtr pScr
 		   "Failed to allocate logical context space.\n");
 	return FALSE;
     }
-#ifdef I830_USE_EXA
-    if (pI830->useEXA) {
-	if (IS_I965G(pI830) && pI830->exa_965_state == NULL) {
-	    pI830->exa_965_state =
-		i830_allocate_memory(pScrn, "exa G965 state buffer",
-				     EXA_LINEAR_EXTRA, GTT_PAGE_SIZE, 0);
-	    if (pI830->exa_965_state == NULL) {
-		xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
-			   "Failed to allocate exa state buffer for 965.\n");
-		return FALSE;
-	    }
+
+    /* even in XAA, 965G needs state mem buffer for rendering */
+    if (IS_I965G(pI830) && !pI830->noAccel && pI830->exa_965_state == NULL) {
+	pI830->exa_965_state =
+	    i830_allocate_memory(pScrn, "exa G965 state buffer",
+		    EXA_LINEAR_EXTRA, GTT_PAGE_SIZE, 0);
+	if (pI830->exa_965_state == NULL) {
+	    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+		    "Failed to allocate exa state buffer for 965.\n");
+	    return FALSE;
 	}
     }
-#endif
 
 #ifdef I830_XV
     /* Allocate overlay register space and optional XAA linear allocator
diff-tree 0cd524e5411e35c8483c02ecc5062625809e6fc6 (from 880314aabe6326ed56517034940f0e10fb16e866)
Author: Kristian Høgsberg <krh at redhat.com>
Date:   Wed Apr 25 18:09:10 2007 -0400

    Implement the custom I2C protocol used by the ivch DVO.
    
    The ihch DVO uses a modified I2C addressing scheme as described
    in section 5.2 of the data sheet.  Implement this by over-riding
    the I2C read and write word routines.

diff --git a/src/i830_dvo.c b/src/i830_dvo.c
index 0bb25bd..4b37228 100644
--- a/src/i830_dvo.c
+++ b/src/i830_dvo.c
@@ -45,13 +45,11 @@ static const char *CH7xxxSymbols[] = {
     "CH7xxxVidOutput",
     NULL
 };
-
-#if 0
 static const char *ivch_symbols[] = {
     "ivch_methods",
     NULL
 };
-#endif
+
 #if 0
 static const char *ch7017_symbols[] = {
     "ch7017_methods",
@@ -66,9 +64,9 @@ struct _I830DVODriver i830_dvo_drivers[]
      (SIL164_ADDR_1<<1), SIL164Symbols, NULL , NULL, NULL},
     {I830_DVO_CHIP_TMDS | I830_DVO_CHIP_TVOUT, "ch7xxx", "CH7xxxVidOutput",
      (CH7xxx_ADDR_1<<1), CH7xxxSymbols, NULL , NULL, NULL},
-    /*
     {I830_DVO_CHIP_LVDS, "ivch", "ivch_methods",
      0x04, ivch_symbols, NULL, NULL, NULL},
+    /*
     {I830_DVO_CHIP_LVDS, "ivch", "ivch_methods",
      0x44, ivch_symbols, NULL, NULL, NULL},
     {I830_DVO_CHIP_LVDS, "ivch", "ivch_methods",
diff --git a/src/ivch/ivch.c b/src/ivch/ivch.c
index 71f41f5..efc74f8 100644
--- a/src/ivch/ivch.c
+++ b/src/ivch/ivch.c
@@ -60,26 +60,69 @@ ivch_dump_regs(I2CDevPtr d);
 static Bool
 ivch_read(struct ivch_priv *priv, int addr, CARD16 *data)
 {
-    if (!xf86I2CReadWord(&priv->d, addr, data)) {
-	xf86DrvMsg(priv->d.pI2CBus->scrnIndex, X_ERROR,
-		   "Unable to read register 0x%02x from %s:%d.\n",
-		   addr, priv->d.pI2CBus->BusName, priv->d.SlaveAddr);
-	return FALSE;
-    }
+    I2CBusPtr b = priv->d.pI2CBus;
+    I2CByte *p = (I2CByte *) data;
+
+    if (!b->I2CStart(b, priv->d.StartTimeout))
+	goto fail;
+
+    if (!b->I2CPutByte(&priv->d, priv->d.SlaveAddr | 1))
+	goto fail;
+
+    if (!b->I2CPutByte(&priv->d, addr))
+	goto fail;
+
+    if (!b->I2CGetByte(&priv->d, p++, FALSE))
+	goto fail;
+
+    if (!b->I2CGetByte(&priv->d, p++, TRUE))
+	goto fail;
+
+    b->I2CStop(&priv->d);
+
     return TRUE;
-}
 
+ fail:
+    xf86DrvMsg(priv->d.pI2CBus->scrnIndex, X_ERROR,
+	       "ivch: Unable to read register 0x%02x from %s:%02x.\n",
+	       addr, priv->d.pI2CBus->BusName, priv->d.SlaveAddr);
+    b->I2CStop(&priv->d);
+
+    return FALSE;
+}
+ 
 /** Writes a 16-bit register on the ivch */
 static Bool
 ivch_write(struct ivch_priv *priv, int addr, CARD16 data)
 {
-    if (!xf86I2CWriteWord(&priv->d, addr, data)) {
-	xf86DrvMsg(priv->d.pI2CBus->scrnIndex, X_ERROR,
-		   "Unable to write register 0x%02x to %s:%d.\n",
-		   addr, priv->d.pI2CBus->BusName, priv->d.SlaveAddr);
-	return FALSE;
-    }
+    I2CBusPtr b = priv->d.pI2CBus;
+
+    if (!b->I2CStart(b, priv->d.StartTimeout))
+	goto fail;
+
+    if (!b->I2CPutByte(&priv->d, priv->d.SlaveAddr))
+	goto fail;
+
+    if (!b->I2CPutByte(&priv->d, addr))
+	goto fail;
+
+    if (!b->I2CPutByte(&priv->d, data & 0xff))
+	goto fail;
+
+    if (!b->I2CPutByte(&priv->d, data >> 8))
+	goto fail;
+
+    b->I2CStop(&priv->d);
+
     return TRUE;
+
+ fail:
+    b->I2CStop(&priv->d);
+    xf86DrvMsg(priv->d.pI2CBus->scrnIndex, X_ERROR,
+	       "Unable to write register 0x%02x to %s:%d.\n",
+	       addr, priv->d.pI2CBus->BusName, priv->d.SlaveAddr);
+
+    return FALSE;
 }
 
 /** Probes the given bus and slave address for an ivch */
@@ -104,18 +147,18 @@ ivch_init(I2CBusPtr b, I2CSlaveAddr addr
     priv->d.ByteTimeout = b->ByteTimeout;
     priv->d.DriverPrivate.ptr = priv;
 
-    if (!xf86I2CReadWord(&priv->d, VR00, &temp))
+    if (!ivch_read(priv, VR00, &temp))
 	goto out;
 
     /* Since the identification bits are probably zeroes, which doesn't seem
      * very unique, check that the value in the base address field matches
      * the address it's responding on.
      */
-    if ((temp & VR00_BASE_ADDRESS_MASK) != priv->d.SlaveAddr) {
+    if ((temp & VR00_BASE_ADDRESS_MASK) != (priv->d.SlaveAddr >> 1)) {
 	xf86DrvMsg(priv->d.pI2CBus->scrnIndex, X_ERROR,
 		   "ivch detect failed due to address mismatch "
 		   "(%d vs %d)\n",
-		   (temp & VR00_BASE_ADDRESS_MASK), priv->d.SlaveAddr);
+		   (temp & VR00_BASE_ADDRESS_MASK), priv->d.SlaveAddr >> 1);
     }
 
     if (!xf86I2CDevInit(&priv->d)) {
diff-tree 880314aabe6326ed56517034940f0e10fb16e866 (from b23eae55c8cdd73e0aba1bf7ced283d402ee6470)
Author: Keith Packard <keithp at guitar.keithp.com>
Date:   Tue Apr 24 11:37:08 2007 -0700

    CRTC Rotation under XAA wasn't hitting accelerated path.
    
    The server rotation code is now using the root window in IncludeInferiors
    mode rather than using the screen pixmap. Change the XAA Composite code
    to check for this case now.

diff --git a/src/i830_xaa.c b/src/i830_xaa.c
index 3440341..790299c 100644
--- a/src/i830_xaa.c
+++ b/src/i830_xaa.c
@@ -782,12 +782,12 @@ i830_xaa_composite(CARD8	op,
     if (pMask != NULL || op != PictOpSrc || pSrc->pDrawable == NULL)
 	goto fallback;
 
-    if (pSrc->pDrawable->type != DRAWABLE_PIXMAP ||
+    if (pSrc->pDrawable->type != DRAWABLE_WINDOW ||
 	pDst->pDrawable->type != DRAWABLE_PIXMAP)
     {
 	goto fallback;
     }
-    pSrcPixmap = (PixmapPtr)pSrc->pDrawable;
+    pSrcPixmap = (*pScreen->GetWindowPixmap) ((WindowPtr) pSrc->pDrawable);
     pDstPixmap = (PixmapPtr)pDst->pDrawable;
 
     /* Check if the dest is one of our shadow pixmaps */
diff-tree b23eae55c8cdd73e0aba1bf7ced283d402ee6470 (from parents)
Merge: 31bf269afed0a830e79cbbd9d4b1ee9843af326c cebdb8bfc6170a0fb441039f4422917fd0c77e70
Author: Keith Packard <keithp at neko.keithp.com>
Date:   Thu Apr 19 20:38:18 2007 -0700

    Merge branch 'origin'

diff-tree 31bf269afed0a830e79cbbd9d4b1ee9843af326c (from 60e891915af7d0f522c9c3f966599fa07779f7aa)
Author: Keith Packard <keithp at neko.keithp.com>
Date:   Thu Apr 19 20:03:41 2007 -0700

    Update version to 2.0.0

diff --git a/configure.ac b/configure.ac
index a06d3e4..da9fd3f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -22,7 +22,7 @@
 
 AC_PREREQ(2.57)
 AC_INIT([xf86-video-intel],
-        1.9.94,
+        2.0.0,
         [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg],
         xf86-video-intel)
 
diff-tree cebdb8bfc6170a0fb441039f4422917fd0c77e70 (from cca389769001c657435f056e1f1c26b0f52a48bd)
Author: Wang Zhenyu <zhenyu.z.wang at intel.com>
Date:   Fri Apr 20 10:54:34 2007 +0800

    EXA: set enabling bits properly for i830
    
    This was found when debug exa on a 865GV, we should set
    pipeline state bits properly, otherwise the engine will hang.

diff --git a/src/i830_render.c b/src/i830_render.c
index 36d41f3..077afa1 100644
--- a/src/i830_render.c
+++ b/src/i830_render.c
@@ -515,9 +515,16 @@ i830_prepare_composite(int op, PicturePt
 	OUT_RING(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(8) | 0);
 	OUT_RING(S8_ENABLE_COLOR_BLEND | S8_BLENDFUNC_ADD | blendctl | 
 		 S8_ENABLE_COLOR_BUFFER_WRITE);
+
+	OUT_RING(_3DSTATE_ENABLES_1_CMD | DISABLE_LOGIC_OP | 
+		DISABLE_STENCIL_TEST | DISABLE_DEPTH_BIAS | 
+		DISABLE_SPEC_ADD | DISABLE_FOG | DISABLE_ALPHA_TEST | 
+		ENABLE_COLOR_BLEND | DISABLE_DEPTH_TEST);
 	/* We have to explicitly say we don't want write disabled */
-	OUT_RING(_3DSTATE_ENABLES_2_CMD | ENABLE_COLOR_MASK);
-	OUT_RING(MI_NOOP); 
+	OUT_RING(_3DSTATE_ENABLES_2_CMD | ENABLE_COLOR_MASK |
+		DISABLE_STENCIL_WRITE | ENABLE_TEX_CACHE |
+		DISABLE_DITHER | ENABLE_COLOR_WRITE |
+		DISABLE_DEPTH_WRITE);
 	ADVANCE_LP_RING();
     }
 
diff-tree 60e891915af7d0f522c9c3f966599fa07779f7aa (from cca389769001c657435f056e1f1c26b0f52a48bd)
Author: Keith Packard <keithp at neko.keithp.com>
Date:   Thu Apr 19 14:02:23 2007 -0700

    Eliminate LinearAlloc option and code.
    
    With the fixes to the 2D frame buffer allocation that allows up to 65536
    lines of 2D frame buffer in XAA mode, the old linear allocation hacks are no
    longer necessary.

diff --git a/man/intel.man b/man/intel.man
index 5ce31ea..178ff0a 100644
--- a/man/intel.man
+++ b/man/intel.man
@@ -121,12 +121,6 @@ other drivers.
 Disable or enable XVideo support.
 Default: XVideo is enabled for configurations where it is supported.
 .TP
-.BI "Option \*qLinearAlloc\*q \*q" integer \*q
-Allows more memory for the offscreen allocator. This usually helps in
-situations where HDTV movies are required to play but not enough offscreen
-memory is usually available. Set this to 8160 for upto 1920x1080 HDTV support.
-Default 0KB (off).
-.TP
 .BI "Option \*qLegacy3D\*q \*q" boolean \*q
 Enable support for the legacy i915_dri.so 3D driver.
 This will, among other things, make the 2D driver tell libGL to
diff --git a/src/i830.h b/src/i830.h
index 4cb31b6..d81857b 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -298,9 +298,7 @@ typedef struct _I830Rec {
 #ifdef I830_XV
    /* For Xvideo */
    i830_memory *overlay_regs;
-   i830_memory *xaa_linear;
 #endif
-   unsigned long LinearAlloc;
    XF86ModReqInfo shadowReq; /* to test for later libshadow */
    Rotation rotation;
    void (*PointerMoved)(int, int, int);
diff --git a/src/i830_driver.c b/src/i830_driver.c
index e3bf330..2c1e514 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -274,7 +274,6 @@ typedef enum {
    OPTION_VIDEO_KEY,
    OPTION_COLOR_KEY,
    OPTION_CHECKDEVICES,
-   OPTION_LINEARALLOC,
    OPTION_MODEDEBUG,
 #ifdef XF86DRI_MM
    OPTION_INTELTEXPOOL,
@@ -296,7 +295,6 @@ static OptionInfoRec I830Options[] = {
    {OPTION_COLOR_KEY,	"ColorKey",	OPTV_INTEGER,	{0},	FALSE},
    {OPTION_VIDEO_KEY,	"VideoKey",	OPTV_INTEGER,	{0},	FALSE},
    {OPTION_CHECKDEVICES, "CheckDevices",OPTV_BOOLEAN,	{0},	FALSE},
-   {OPTION_LINEARALLOC, "LinearAlloc",  OPTV_INTEGER,   {0},    FALSE},
    {OPTION_MODEDEBUG,	"ModeDebug",	OPTV_BOOLEAN,	{0},	FALSE},
 #ifdef XF86DRI_MM
    {OPTION_INTELTEXPOOL,"Legacy3D",     OPTV_BOOLEAN,	{0},	FALSE},
@@ -1300,13 +1298,6 @@ I830PreInit(ScrnInfoPtr pScrn, int flags
    
 #endif
 
-   pI830->LinearAlloc = 0;
-   if (xf86GetOptValULong(pI830->Options, OPTION_LINEARALLOC,
-			    &(pI830->LinearAlloc))) {
-      if (pI830->LinearAlloc < 0)
-         pI830->LinearAlloc = 0;
-   }
-
    I830PreInitDDC(pScrn);
    for (i = 0; i < num_pipe; i++) {
        i830_crtc_init(pScrn, i);
@@ -2544,17 +2535,6 @@ I830ScreenInit(int scrnIndex, ScreenPtr 
 	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
 		       "Failed to init memory manager\n");
 	 }
-
-	 if (pI830->xaa_linear != NULL &&
-	     xf86InitFBManagerLinear(pScreen,
-				     pI830->xaa_linear->offset / pI830->cpp,
-				     pI830->xaa_linear->size / pI830->cpp))
-	 {
-            xf86DrvMsg(scrnIndex, X_INFO,
-		       "Using %ld bytes of offscreen memory for linear "
-		       "(offset=0x%lx)\n", pI830->xaa_linear->size,
-		       pI830->xaa_linear->offset);
-	 }
       } else {
 	 if (!I830InitFBManager(pScreen, &(pI8301->FbMemBox2))) {
 	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
diff --git a/src/i830_memory.c b/src/i830_memory.c
index 20b33bc..15d241b 100644
--- a/src/i830_memory.c
+++ b/src/i830_memory.c
@@ -230,7 +230,6 @@ i830_reset_allocations(ScrnInfoPtr pScrn
     pI830->exa_offscreen = NULL;
     pI830->exa_965_state = NULL;
     pI830->overlay_regs = NULL;
-    pI830->xaa_linear = NULL;
     pI830->logical_context = NULL;
     pI830->back_buffer = NULL;
     pI830->third_buffer = NULL;
@@ -663,16 +662,6 @@ i830_allocate_overlay(ScrnInfoPtr pScrn)
 	}
     }
 
-    if (!pI830->useEXA && pI830->LinearAlloc) {
-	pI830->xaa_linear = i830_allocate_memory(pScrn, "XAA linear memory",
-						 KB(pI830->LinearAlloc),
-						 GTT_PAGE_SIZE, 0);
-	if (pI830->xaa_linear == NULL) {
-	    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
-		       "Failed to allocate linear buffer space\n");
-	}
-    }
-
     return TRUE;
 }
 #endif
diff-tree cca389769001c657435f056e1f1c26b0f52a48bd (from 07797fee88d6be0dfb30394a419dd86f8a3c9095)
Author: Keith Packard <keithp at neko.keithp.com>
Date:   Thu Apr 19 13:15:23 2007 -0700

    Clean up 1.2 xserver build support.
    
    Convert relative X server source path to absolute.  Check for local copies
    of needed header files before building, rather than requiring server source.
    Remove extra duplicate -I elements in AM_CFLAGS in sub directories.

diff --git a/configure.ac b/configure.ac
index 2d26553..a06d3e4 100644
--- a/configure.ac
+++ b/configure.ac
@@ -131,19 +131,14 @@ if test "x$XSERVER_SOURCE" = x; then
 	fi
 fi
 	
-if test "x$XMODES" = xyes; then
-	echo built-in mode code
-	AC_DEFINE(XMODES, 1,[X server has built-in mode code])
-	XMODES_CFLAGS=
-else
-	echo symlink mode code
-	if test "x$XSERVER_SOURCE" = x; then
-		AC_MSG_ERROR([Must have X server >= 1.3 source tree for mode setting code. Please specify --with-xserver-source])
-	fi
-	XMODES_CFLAGS='-DXF86_MODES_RENAME -I$(top_srcdir)/src/modes -I$(top_srcdir)/src/parser'
-fi
-
 if test -d "$XSERVER_SOURCE"; then
+	case "$XSERVER_SOURCE" in
+	/*)
+		;;
+	*)
+		XSERVER_SOURCE="`cd $XSERVER_SOURCE && pwd`"
+		;;
+	esac
 	if test -f src/modes/xf86Modes.h; then
 		:
 	else
@@ -156,6 +151,20 @@ if test -d "$XSERVER_SOURCE"; then
 		ln -sf $XSERVER_SOURCE/hw/xfree86/parser src/parser
 	fi
 fi
+
+if test "x$XMODES" = xyes; then
+	AC_MSG_NOTICE([X server has new mode code])
+	AC_DEFINE(XMODES, 1,[X server has built-in mode code])
+	XMODES_CFLAGS=
+else
+	if test -f src/modes/xf86Modes.h -a -f src/parser/xf86Parser.h; then
+		AC_MSG_NOTICE([X server is missing new mode code, using local copy])
+	else
+		AC_MSG_ERROR([Must have X server >= 1.3 source tree for mode setting code. Please specify --with-xserver-source])
+	fi
+	XMODES_CFLAGS='-DXF86_MODES_RENAME -I$(top_srcdir)/src -I$(top_srcdir)/src/modes -I$(top_srcdir)/src/parser'
+fi
+
 AC_SUBST([XMODES_CFLAGS])
 
 dnl Use lots of warning flags with GCC
diff --git a/src/ch7017/Makefile.am b/src/ch7017/Makefile.am
index 9858941..71c5085 100644
--- a/src/ch7017/Makefile.am
+++ b/src/ch7017/Makefile.am
@@ -3,8 +3,7 @@
 # -avoid-version prevents gratuitous .0.0.0 version numbers on the end
 # _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@ @XMODES_CFLAGS@ @XORG_CFLAGS@ @DRI_CFLAGS@ \
-	-I$(srcdir)/.. -I$(srcdir)/../modes
+AM_CFLAGS = @WARN_CFLAGS@ @XMODES_CFLAGS@ @XORG_CFLAGS@ @DRI_CFLAGS@
 
 ch7017_la_LTLIBRARIES = ch7017.la
 ch7017_la_LDFLAGS = -module -avoid-version
diff --git a/src/ch7xxx/Makefile.am b/src/ch7xxx/Makefile.am
index 49a5aa3..fdf6e9e 100644
--- a/src/ch7xxx/Makefile.am
+++ b/src/ch7xxx/Makefile.am
@@ -3,8 +3,7 @@
 # -avoid-version prevents gratuitous .0.0.0 version numbers on the end
 # _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@ @XMODES_CFLAGS@ @XORG_CFLAGS@ @DRI_CFLAGS@ \
-	-I$(srcdir)/.. -I$(srcdir)/../modes
+AM_CFLAGS = @WARN_CFLAGS@ @XMODES_CFLAGS@ @XORG_CFLAGS@ @DRI_CFLAGS@
 
 ch7xxx_la_LTLIBRARIES = ch7xxx.la
 ch7xxx_la_LDFLAGS = -module -avoid-version
diff --git a/src/ivch/Makefile.am b/src/ivch/Makefile.am
index cf05c01..1dc9cb3 100644
--- a/src/ivch/Makefile.am
+++ b/src/ivch/Makefile.am
@@ -3,8 +3,7 @@
 # -avoid-version prevents gratuitous .0.0.0 version numbers on the end
 # _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@ @XMODES_CFLAGS@ @XORG_CFLAGS@ @DRI_CFLAGS@ \
-	-I$(srcdir)/.. -I$(srcdir)/../modes
+AM_CFLAGS = @WARN_CFLAGS@ @XMODES_CFLAGS@ @XORG_CFLAGS@ @DRI_CFLAGS@
 
 ivch_la_LTLIBRARIES = ivch.la
 ivch_la_LDFLAGS = -module -avoid-version
diff --git a/src/sil164/Makefile.am b/src/sil164/Makefile.am
index de17bd0..497ee9f 100644
--- a/src/sil164/Makefile.am
+++ b/src/sil164/Makefile.am
@@ -3,8 +3,7 @@
 # -avoid-version prevents gratuitous .0.0.0 version numbers on the end
 # _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@ @XMODES_CFLAGS@ @XORG_CFLAGS@ @DRI_CFLAGS@ \
-	-I$(srcdir)/.. -I$(srcdir)/../modes
+AM_CFLAGS = @WARN_CFLAGS@ @XMODES_CFLAGS@ @XORG_CFLAGS@ @DRI_CFLAGS@
 
 sil164_la_LTLIBRARIES = sil164.la
 sil164_la_LDFLAGS = -module -avoid-version
diff-tree 07797fee88d6be0dfb30394a419dd86f8a3c9095 (from 163c565527e8cda1f5a47c7fd63f04c80feaf3c7)
Author: Keith Packard <keithp at neko.keithp.com>
Date:   Thu Apr 19 13:01:37 2007 -0700

    Fix mismatching braces when XF86DRI_MM is not defined.
    
    A closing brace was left inside #ifdef XF86DRI_MM while the matching
    open brace was outside.

diff --git a/src/i830_driver.c b/src/i830_driver.c
index c857498..e3bf330 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -1294,8 +1294,8 @@ I830PreInit(ScrnInfoPtr pScrn, int flags
 		    "Will try to reserve %d kiB of AGP aperture space\n"
 		    "\tfor the DRM memory manager.\n",
 		    pI830->mmSize);
-      }
 #endif
+      }
    } 
    
 #endif
diff-tree 163c565527e8cda1f5a47c7fd63f04c80feaf3c7 (from 378ceea3d9ddbec7a08ac2f07f9a8cd9cf3cef36)
Author: Keith Packard <keithp at neko.keithp.com>
Date:   Thu Apr 19 13:00:03 2007 -0700

    Use I2C delay function instead of usleep.
    
    usleep isn't always available, and we have an existing delay mechanism
    available to use.

diff --git a/src/i830_sdvo.c b/src/i830_sdvo.c
index e1a4a44..43b55a0 100644
--- a/src/i830_sdvo.c
+++ b/src/i830_sdvo.c
@@ -302,7 +302,7 @@ i830_sdvo_read_response(xf86OutputPtr ou
 	if (status != SDVO_CMD_STATUS_PENDING)
 	    return status;
 
-        usleep(50);
+        intel_output->pI2CBus->I2CUDelay(intel_output->pI2CBus, 50);
     }
 
     return status;
diff-tree 378ceea3d9ddbec7a08ac2f07f9a8cd9cf3cef36 (from db4b9e18810990e8900bdf54aa3091b876ea2658)
Author: Wang Zhenyu <zhenyu.z.wang at intel.com>
Date:   Thu Apr 19 17:30:28 2007 +0800

    Fix mem list order and remove extra unbind call when free memory

diff --git a/src/i830_memory.c b/src/i830_memory.c
index 315f4ba..20b33bc 100644
--- a/src/i830_memory.c
+++ b/src/i830_memory.c
@@ -184,8 +184,6 @@ i830_free_memory(ScrnInfoPtr pScrn, i830
     if (mem == NULL)
 	return;
 
-    i830_unbind_memory(pScrn, mem);
-
     /* Disconnect from the list of allocations */
     if (mem->prev != NULL)
 	mem->prev->next = mem->next;
@@ -368,7 +366,7 @@ i830_allocate_aperture(ScrnInfoPtr pScrn
     mem->prev = scan;
     mem->next = scan->next;
     scan->next = mem;
-    mem->next->prev = scan;
+    mem->next->prev = mem;
 
     return mem;
 }
diff-tree db4b9e18810990e8900bdf54aa3091b876ea2658 (from 3f5111940e35989d334aa99cd1b0eb26293ebf1b)
Author: Alan Hourihane <alanh at fairlite.demon.co.uk>
Date:   Wed Apr 18 13:52:08 2007 +0100

    Fix return status

diff --git a/src/i830_sdvo.c b/src/i830_sdvo.c
index 53a6ece..e1a4a44 100644
--- a/src/i830_sdvo.c
+++ b/src/i830_sdvo.c
@@ -305,7 +305,7 @@ i830_sdvo_read_response(xf86OutputPtr ou
         usleep(50);
     }
 
-    return SDVO_CMD_STATUS_SUCCESS;
+    return status;
 }
 
 int
diff-tree 3f5111940e35989d334aa99cd1b0eb26293ebf1b (from 902388fa06f85486fe8010807ab53e4926cc979a)
Author: Alan Hourihane <alanh at fairlite.demon.co.uk>
Date:   Wed Apr 18 13:27:59 2007 +0100

    Update read_response to include the try on PENDING status
    
    and remove it from get attached displays call.

diff --git a/src/i830_sdvo.c b/src/i830_sdvo.c
index cf72848..53a6ece 100644
--- a/src/i830_sdvo.c
+++ b/src/i830_sdvo.c
@@ -271,33 +271,41 @@ i830_sdvo_read_response(xf86OutputPtr ou
     I830OutputPrivatePtr    intel_output = output->driver_private;
     int			    i;
     CARD8		    status;
+    CARD8		    retry = 50;
 
-    /* Read the command response */
-    for (i = 0; i < response_len; i++) {
-	i830_sdvo_read_byte(output, SDVO_I2C_RETURN_0 + i,
+    while (retry--) {
+    	/* Read the command response */
+    	for (i = 0; i < response_len; i++) {
+	    i830_sdvo_read_byte(output, SDVO_I2C_RETURN_0 + i,
 			    &((CARD8 *)response)[i]);
-    }
+    	}
 
-    /* Read the return status */
-    i830_sdvo_read_byte(output, SDVO_I2C_CMD_STATUS, &status);
+    	/* Read the return status */
+    	i830_sdvo_read_byte(output, SDVO_I2C_CMD_STATUS, &status);
 
-    /* Write the SDVO command logging */
-    if (pI830->debug_modes) {
-	xf86DrvMsg(intel_output->pI2CBus->scrnIndex, X_INFO,
+    	/* Write the SDVO command logging */
+    	if (pI830->debug_modes) {
+	    xf86DrvMsg(intel_output->pI2CBus->scrnIndex, X_INFO,
 		   "%s: R: ", SDVO_NAME(SDVO_PRIV(intel_output)));
-	for (i = 0; i < response_len; i++)
-	    LogWrite(1, "%02X ", ((CARD8 *)response)[i]);
-	for (; i < 8; i++)
-	    LogWrite(1, "   ");
-	if (status <= SDVO_CMD_STATUS_SCALING_NOT_SUPP) {
-	    LogWrite(1, "(%s)", cmd_status_names[status]);
-	} else {
-	    LogWrite(1, "(??? %d)", status);
-	}
-	LogWrite(1, "\n");
+	    for (i = 0; i < response_len; i++)
+	    	LogWrite(1, "%02X ", ((CARD8 *)response)[i]);
+	    for (; i < 8; i++)
+	    	LogWrite(1, "   ");
+	    if (status <= SDVO_CMD_STATUS_SCALING_NOT_SUPP) {
+	    	LogWrite(1, "(%s)", cmd_status_names[status]);
+	    } else {
+	    	LogWrite(1, "(??? %d)", status);
+	    }
+	    LogWrite(1, "\n");
+    	}
+
+	if (status != SDVO_CMD_STATUS_PENDING)
+	    return status;
+
+        usleep(50);
     }
 
-    return status;
+    return SDVO_CMD_STATUS_SUCCESS;
 }
 
 int
@@ -1074,19 +1082,12 @@ i830_sdvo_detect(xf86OutputPtr output)
 {
     CARD8 response[2];
     CARD8 status;
-    CARD8 retry = 50;
 
     i830_sdvo_write_cmd(output, SDVO_CMD_GET_ATTACHED_DISPLAYS, NULL, 0);
+    status = i830_sdvo_read_response(output, &response, 2);
 
-    while (retry--) {
-    	status = i830_sdvo_read_response(output, &response, 2);
-
-	if (status == SDVO_CMD_STATUS_SUCCESS)
-	    break;
-    
-    	if (status != SDVO_CMD_STATUS_PENDING)
-	    return XF86OutputStatusUnknown;
-    }
+    if (status != SDVO_CMD_STATUS_SUCCESS)
+	return XF86OutputStatusUnknown;
 
     if (response[0] != 0 || response[1] != 0)
 	return XF86OutputStatusConnected;
diff-tree 902388fa06f85486fe8010807ab53e4926cc979a (from 8abecae202b609375b6754dbd5ecce3d59036daf)
Author: Eric Anholt <eric at anholt.net>
Date:   Tue Apr 17 14:21:25 2007 -0700

    Don't try to init the XAA linear region unless we allocated memory for it.
    
    Reported by JM Ibanez

diff --git a/src/i830_driver.c b/src/i830_driver.c
index f0ca973..c857498 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -2545,7 +2545,7 @@ I830ScreenInit(int scrnIndex, ScreenPtr 
 		       "Failed to init memory manager\n");
 	 }
 
-	 if (pI830->LinearAlloc &&
+	 if (pI830->xaa_linear != NULL &&
 	     xf86InitFBManagerLinear(pScreen,
 				     pI830->xaa_linear->offset / pI830->cpp,
 				     pI830->xaa_linear->size / pI830->cpp))
diff-tree 8abecae202b609375b6754dbd5ecce3d59036daf (from 2dbe8d678b02b724c4f06255383f49bb4c2708b0)
Author: Eric Anholt <eric at anholt.net>
Date:   Tue Apr 17 12:28:43 2007 -0700

    Fix i852 EXA Composite acceleration setup.
    
    Reported by JM Ibanez.

diff --git a/src/i830_exa.c b/src/i830_exa.c
index dfc8f99..1741732 100644
--- a/src/i830_exa.c
+++ b/src/i830_exa.c
@@ -487,9 +487,7 @@ I830EXAInit(ScreenPtr pScreen)
     pI830->EXADriverPtr->DoneCopy = I830EXADoneCopy;
 
     /* Composite */
-    if (IS_I865G(pI830) || IS_I855(pI830) ||
-	       IS_845G(pI830) || IS_I830(pI830))
-    {
+    if (!IS_I9XX(pI830)) {
     	pI830->EXADriverPtr->CheckComposite = i830_check_composite;
     	pI830->EXADriverPtr->PrepareComposite = i830_prepare_composite;
     	pI830->EXADriverPtr->Composite = i830_composite;
diff-tree 2dbe8d678b02b724c4f06255383f49bb4c2708b0 (from a089ac11beb4c801928c17780401e913bc0d5257)
Author: Timo Aaltonen <tjaalton at cc.hut.fi>
Date:   Mon Apr 16 14:14:19 2007 -0700

    Fix build against xserver 1.2.

diff --git a/src/ch7017/Makefile.am b/src/ch7017/Makefile.am
index d757b3c..9858941 100644
--- a/src/ch7017/Makefile.am
+++ b/src/ch7017/Makefile.am
@@ -3,9 +3,8 @@
 # -avoid-version prevents gratuitous .0.0.0 version numbers on the end
 # _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 = @XMODES_CFLAGS@ @XORG_CFLAGS@ @DRI_CFLAGS@ -I$(srcdir)/.. -I$(srcdir)/../modes
-
-AM_CFLAGS = @WARN_CFLAGS@ @XORG_CFLAGS@ @DRI_CFLAGS@ @XMODES_CFLAGS@
+AM_CFLAGS = @WARN_CFLAGS@ @XMODES_CFLAGS@ @XORG_CFLAGS@ @DRI_CFLAGS@ \
+	-I$(srcdir)/.. -I$(srcdir)/../modes
 
 ch7017_la_LTLIBRARIES = ch7017.la
 ch7017_la_LDFLAGS = -module -avoid-version
diff-tree a089ac11beb4c801928c17780401e913bc0d5257 (from 37ee68a95ca8c86ebe9abafaaf55b060dd2a2f73)
Author: Eric Anholt <eric at anholt.net>
Date:   Tue Apr 17 11:01:05 2007 -0700

    Add all the possible ivch slave addresses (still commented out).

diff --git a/src/i830_dvo.c b/src/i830_dvo.c
index 04750e5..0bb25bd 100644
--- a/src/i830_dvo.c
+++ b/src/i830_dvo.c
@@ -68,7 +68,13 @@ struct _I830DVODriver i830_dvo_drivers[]
      (CH7xxx_ADDR_1<<1), CH7xxxSymbols, NULL , NULL, NULL},
     /*
     {I830_DVO_CHIP_LVDS, "ivch", "ivch_methods",
-     (0x2 << 1), ivch_symbols, NULL, NULL, NULL},
+     0x04, ivch_symbols, NULL, NULL, NULL},
+    {I830_DVO_CHIP_LVDS, "ivch", "ivch_methods",
+     0x44, ivch_symbols, NULL, NULL, NULL},
+    {I830_DVO_CHIP_LVDS, "ivch", "ivch_methods",
+     0x84, ivch_symbols, NULL, NULL, NULL},
+    {I830_DVO_CHIP_LVDS, "ivch", "ivch_methods",
+     0xc4, ivch_symbols, NULL, NULL, NULL},
     */
     /*
     { I830_DVO_CHIP_LVDS, "ch7017", "ch7017_methods",
diff-tree 37ee68a95ca8c86ebe9abafaaf55b060dd2a2f73 (from ac9181c014638dbeb334b40b4029d0ccb2b7a0fc)
Author: Eric Anholt <eric at anholt.net>
Date:   Tue Apr 17 10:50:02 2007 -0700

    Bug #10438: Fix 965 XV when sourcing from less than the full image.
    
    Bob deinterlacing in MythTV, and the zoom options in totem would result in
    attempting to source from outside the video instead of scaling appropriately.

diff --git a/src/i965_video.c b/src/i965_video.c
index 9e96527..17d2006 100644
--- a/src/i965_video.c
+++ b/src/i965_video.c
@@ -172,6 +172,7 @@ I965DisplayVideoTextured(ScrnInfoPtr pSc
     struct brw_instruction *ps_kernel;
     struct brw_instruction *sip_kernel;
     float *vb;
+    float src_scale_x, src_scale_y;
     CARD32 *binding_table;
     Bool first_output = TRUE;
     int dest_surf_offset, src_surf_offset, src_sampler_offset, vs_offset;
@@ -672,6 +673,10 @@ I965DisplayVideoTextured(ScrnInfoPtr pSc
     dxo = dstRegion->extents.x1;
     dyo = dstRegion->extents.y1;
 
+    /* Use normalized texture coordinates */
+    src_scale_x = ((float)src_w / width) / (float)drw_w;
+    src_scale_y = ((float)src_h / height) / (float)drw_h;
+
     pbox = REGION_RECTS(dstRegion);
     nbox = REGION_NUM_RECTS(dstRegion);
     while (nbox--) {
@@ -680,7 +685,6 @@ I965DisplayVideoTextured(ScrnInfoPtr pSc
 	int box_x2 = pbox->x2;
 	int box_y2 = pbox->y2;
 	int i;
-	float src_scale_x, src_scale_y;
 
 	if (!first_output) {
 	    /* Since we use the same little vertex buffer over and over, sync
@@ -691,10 +695,6 @@ I965DisplayVideoTextured(ScrnInfoPtr pSc
 
 	pbox++;
 
-	/* Use normalized texture coordinates */
-	src_scale_x = (float)1.0 / (float)drw_w;
-	src_scale_y = (float)1.0 / (float)drw_h;
-
 	i = 0;
 	vb[i++] = (box_x2 - dxo) * src_scale_x;
 	vb[i++] = (box_y2 - dyo) * src_scale_y;
diff-tree ac9181c014638dbeb334b40b4029d0ccb2b7a0fc (from ab5bdee8a62c842ae32aaef57eb841ebcb644d2b)
Author: Alan Hourihane <alanh at fairlite.demon.co.uk>
Date:   Tue Apr 17 16:30:17 2007 +0100

    Check for the PENDING message when reading the attached
    displays. Ensures the command has completed before continuing.
    
    (probably need to check PENDING in other SDVO calls too)

diff --git a/src/i830_sdvo.c b/src/i830_sdvo.c
index f0723a9..cf72848 100644
--- a/src/i830_sdvo.c
+++ b/src/i830_sdvo.c
@@ -1074,12 +1074,19 @@ i830_sdvo_detect(xf86OutputPtr output)
 {
     CARD8 response[2];
     CARD8 status;
+    CARD8 retry = 50;
 
     i830_sdvo_write_cmd(output, SDVO_CMD_GET_ATTACHED_DISPLAYS, NULL, 0);
-    status = i830_sdvo_read_response(output, &response, 2);
 
-    if (status != SDVO_CMD_STATUS_SUCCESS)
-	return XF86OutputStatusUnknown;
+    while (retry--) {
+    	status = i830_sdvo_read_response(output, &response, 2);
+
+	if (status == SDVO_CMD_STATUS_SUCCESS)
+	    break;
+    
+    	if (status != SDVO_CMD_STATUS_PENDING)
+	    return XF86OutputStatusUnknown;
+    }
 
     if (response[0] != 0 || response[1] != 0)
 	return XF86OutputStatusConnected;
diff --git a/src/i830_sdvo_regs.h b/src/i830_sdvo_regs.h
index 437ff50..72e58a0 100644
--- a/src/i830_sdvo_regs.h
+++ b/src/i830_sdvo_regs.h
@@ -38,7 +38,11 @@
 #define SDVO_OUTPUT_SCART0  (1 << 5)
 #define SDVO_OUTPUT_LVDS0   (1 << 6)
 #define SDVO_OUTPUT_TMDS1   (1 << 8)
-#define SDVO_OUTPUT_RGB1    (1 << 13)
+#define SDVO_OUTPUT_RGB1    (1 << 9)
+#define SDVO_OUTPUT_CVBS1   (1 << 10)
+#define SDVO_OUTPUT_SVID1   (1 << 11)
+#define SDVO_OUTPUT_YPRPB1  (1 << 12)
+#define SDVO_OUTPUT_SCART1  (1 << 13)
 #define SDVO_OUTPUT_LVDS1   (1 << 14)
 #define SDVO_OUTPUT_LAST    (14)
 
diff-tree ab5bdee8a62c842ae32aaef57eb841ebcb644d2b (from 1a29750b8dba1371d7d0802744cdf2f3bfa83c13)
Author: Wang Zhenyu <zhenyu.z.wang at intel.com>
Date:   Tue Apr 17 16:23:46 2007 +0800

    EXA: fix i830 render
    
    Fix tex blend pipeline in case that src/mask pict has no
    alpha. Unmask color buffer write disable bits. These make
    rendercheck run fine on 855GM.

diff --git a/src/i830_render.c b/src/i830_render.c
index ec80c0b..36d41f3 100644
--- a/src/i830_render.c
+++ b/src/i830_render.c
@@ -83,6 +83,7 @@ struct formatinfo {
 #define TB0C_ARG2_SEL_TEXEL3		(9 << 12)
 #define TB0C_ARG1_REPLICATE_ALPHA 	(1<<11)
 #define TB0C_ARG1_INVERT		(1<<10)
+#define TB0C_ARG1_SEL_ONE		(0 << 6)
 #define TB0C_ARG1_SEL_TEXEL0		(6 << 6)
 #define TB0C_ARG1_SEL_TEXEL1		(7 << 6)
 #define TB0C_ARG1_SEL_TEXEL2		(8 << 6)
@@ -107,6 +108,7 @@ struct formatinfo {
 #define TB0A_ARG2_SEL_TEXEL2		(8 << 12)
 #define TB0A_ARG2_SEL_TEXEL3		(9 << 12)
 #define TB0A_ARG1_INVERT		(1<<10)
+#define TB0A_ARG1_SEL_ONE		(0 << 6)
 #define TB0A_ARG1_SEL_TEXEL0		(6 << 6)
 #define TB0A_ARG1_SEL_TEXEL1		(7 << 6)
 #define TB0A_ARG1_SEL_TEXEL2		(8 << 6)
@@ -418,7 +420,7 @@ i830_prepare_composite(int op, PicturePt
     {
 	CARD32 cblend, ablend, blendctl, vf2;
 
-	BEGIN_LP_RING(26);
+	BEGIN_LP_RING(30);
 
 	/* color buffer */
 	OUT_RING(_3DSTATE_BUF_INFO_CMD);
@@ -455,16 +457,28 @@ i830_prepare_composite(int op, PicturePt
 	OUT_RING(vf2); /* TEXCOORDFMT_2D */
 	OUT_RING(S3_CULLMODE_NONE | S3_VERTEXHAS_XY);
 
-	/* For (src In mask) operation */
-	/* IN operator: Multiply src by mask components or mask alpha.*/
-	/* TEXBLENDOP_MODULE: arg1*arg2 */
+	/* We use two pipes for color and alpha, and do (src In mask)
+	   in one stage. Arg1 is from src pict, and arg2 is from mask pict.
+	   Be sure to force 1.0 when src or mask pict has no alpha channel.
+	 */
 	cblend = TB0C_LAST_STAGE | TB0C_RESULT_SCALE_1X | TB0C_OP_MODULE |
 		 TB0C_OUTPUT_WRITE_CURRENT;
 	ablend = TB0A_RESULT_SCALE_1X | TB0A_OP_MODULE |
 		 TB0A_OUTPUT_WRITE_CURRENT;
 
-	cblend |= TB0C_ARG1_SEL_TEXEL0;
-	ablend |= TB0A_ARG1_SEL_TEXEL0;
+	if (PICT_FORMAT_A(pSrcPicture->format) != 0) {
+	    ablend |= TB0A_ARG1_SEL_TEXEL0;
+	    cblend |= TB0C_ARG1_SEL_TEXEL0;
+	} else {
+	    ablend |= TB0A_ARG1_SEL_ONE;
+	    if (pMask && pMaskPicture->componentAlpha 
+		    && PICT_FORMAT_RGB(pMaskPicture->format)
+		    && i830_blend_op[op].src_alpha)
+		cblend |= TB0C_ARG1_SEL_ONE;
+	    else
+		cblend |= TB0C_ARG1_SEL_TEXEL0;
+	}
+
 	if (pMask) {
 	    if (pMaskPicture->componentAlpha && 
 		    PICT_FORMAT_RGB(pMaskPicture->format)) {
@@ -474,10 +488,16 @@ i830_prepare_composite(int op, PicturePt
 		else 
 		    cblend |= TB0C_ARG2_SEL_TEXEL1;
 	    } else {
-		cblend |= (TB0C_ARG2_SEL_TEXEL1 | 
-			TB0C_ARG2_REPLICATE_ALPHA);
+		if (PICT_FORMAT_A(pMaskPicture->format) != 0)
+		    cblend |= (TB0C_ARG2_SEL_TEXEL1 | 
+			    TB0C_ARG2_REPLICATE_ALPHA);
+		else
+		    cblend |= TB0C_ARG2_SEL_ONE;
 	    }
-	    ablend |= TB0A_ARG2_SEL_TEXEL1;
+	    if (PICT_FORMAT_A(pMaskPicture->format) != 0)
+		ablend |= TB0A_ARG2_SEL_TEXEL1;
+	    else
+		ablend |= TB0A_ARG2_SEL_ONE;
 	} else {
 	    cblend |= TB0C_ARG2_SEL_ONE;
 	    ablend |= TB0A_ARG2_SEL_ONE;
@@ -490,9 +510,14 @@ i830_prepare_composite(int op, PicturePt
 	OUT_RING(0);
 
 	blendctl = i830_get_blend_cntl(op, pMaskPicture, pDstPicture->format);
+	OUT_RING(_3DSTATE_INDPT_ALPHA_BLEND_CMD | DISABLE_INDPT_ALPHA_BLEND);
+	OUT_RING(MI_NOOP);
 	OUT_RING(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(8) | 0);
 	OUT_RING(S8_ENABLE_COLOR_BLEND | S8_BLENDFUNC_ADD | blendctl | 
 		 S8_ENABLE_COLOR_BUFFER_WRITE);
+	/* We have to explicitly say we don't want write disabled */
+	OUT_RING(_3DSTATE_ENABLES_2_CMD | ENABLE_COLOR_MASK);
+	OUT_RING(MI_NOOP); 
 	ADVANCE_LP_RING();
     }
 
diff-tree 1a29750b8dba1371d7d0802744cdf2f3bfa83c13 (from 3a634bbd198650c1597dec4306d99928374c30f3)
Author: Wang Zhenyu <zhenyu.z.wang at intel.com>
Date:   Mon Apr 16 16:21:39 2007 +0800

    EXA: fix 830/845G pict format
    
    Fallback in 830/845G when pict format is a8, x8r8g8b8 or
    x8b8g8r8. The hw doesn't support them.

diff --git a/src/i830_render.c b/src/i830_render.c
index 380c808..ec80c0b 100644
--- a/src/i830_render.c
+++ b/src/i830_render.c
@@ -149,7 +149,7 @@ static struct formatinfo i830_tex_format
     {PICT_r5g6b5,   MT_16BIT_RGB565   },
     {PICT_a1r5g5b5, MT_16BIT_ARGB1555 },
     {PICT_x1r5g5b5, MT_16BIT_ARGB1555 },
-    {PICT_a8,       MT_8BIT_A8       },	 /* mesa does I8 */
+    {PICT_a8,       MT_8BIT_A8        },
 };
 
 static Bool i830_get_dest_format(PicturePtr pDstPicture, CARD32 *dst_format)
@@ -220,6 +220,8 @@ static CARD32 i830_get_blend_cntl(int op
 
 static Bool i830_check_composite_texture(PicturePtr pPict, int unit)
 {
+    ScrnInfoPtr pScrn = xf86Screens[pPict->pDrawable->pScreen->myNum];
+    I830Ptr pI830 = I830PTR(pScrn);
     int w = pPict->pDrawable->width;
     int h = pPict->pDrawable->height;
     int i;
@@ -237,6 +239,13 @@ static Bool i830_check_composite_texture
         I830FALLBACK("Unsupported picture format 0x%x\n",
 		     (int)pPict->format);
 
+    if (IS_I830(pI830) || IS_845G(pI830)) {
+	if (pPict->format == PICT_x8r8g8b8 || 
+		pPict->format == PICT_x8b8g8r8 || 
+		pPict->format == PICT_a8)
+	    I830FALLBACK("830/845G don't support a8, x8r8g8b8, x8b8g8r8\n");
+    }
+
     if (pPict->repeat && pPict->repeatType != RepeatNormal)
 	I830FALLBACK("unsupport repeat type\n");
 
diff-tree 3a634bbd198650c1597dec4306d99928374c30f3 (from 3bcb9a0b4ba7f3df346b5708617a7aafcbe2490a)
Author: Wang Zhenyu <zhenyu.z.wang at intel.com>
Date:   Mon Apr 16 15:14:49 2007 +0800

    EXA: Add i830 supported pict format XRGB8888, XBGR8888

diff --git a/src/i830_reg.h b/src/i830_reg.h
index 989646f..7a8df9f 100644
--- a/src/i830_reg.h
+++ b/src/i830_reg.h
@@ -659,6 +659,8 @@
 #define    MT_16BIT_DIB_RGB565_8888	   (7<<3)
 #define    MT_32BIT_ARGB8888		   (0<<3) /* SURFACE_32BIT */
 #define    MT_32BIT_ABGR8888		   (1<<3)
+#define    MT_32BIT_XRGB8888		   (2<<3)
+#define    MT_32BIT_XBGR8888		   (3<<3)
 #define    MT_32BIT_BUMP_XLDVDU_8888	   (6<<3)
 #define    MT_32BIT_DIB_8888		   (7<<3)
 #define    MT_411_YUV411		   (0<<3) /* SURFACE_411 */
diff --git a/src/i830_render.c b/src/i830_render.c
index f5e144b..380c808 100644
--- a/src/i830_render.c
+++ b/src/i830_render.c
@@ -143,10 +143,10 @@ static struct blendinfo i830_blend_op[] 
 
 static struct formatinfo i830_tex_formats[] = {
     {PICT_a8r8g8b8, MT_32BIT_ARGB8888 },
-    {PICT_x8r8g8b8, MT_32BIT_ARGB8888 },
+    {PICT_x8r8g8b8, MT_32BIT_XRGB8888 },
     {PICT_a8b8g8r8, MT_32BIT_ABGR8888 },
-    {PICT_x8b8g8r8, MT_32BIT_ABGR8888 },
-    {PICT_r5g6b5,   MT_16BIT_RGB565	  },
+    {PICT_x8b8g8r8, MT_32BIT_XBGR8888 },
+    {PICT_r5g6b5,   MT_16BIT_RGB565   },
     {PICT_a1r5g5b5, MT_16BIT_ARGB1555 },
     {PICT_x1r5g5b5, MT_16BIT_ARGB1555 },
     {PICT_a8,       MT_8BIT_A8       },	 /* mesa does I8 */
diff-tree 3bcb9a0b4ba7f3df346b5708617a7aafcbe2490a (from 64c30cf896f8bde3ee74c92b970132ab91b418cd)
Author: Wang Zhenyu <zhenyu.z.wang at intel.com>
Date:   Mon Apr 16 14:27:49 2007 +0800

    EXA: i830 render misc fix and cleanups
    
    Try to map texture stream when setup texture map, and use
    correct order in load_immediate_1 cmd, which fixed crash on
    845GV. Also remove some flush cmds.

diff --git a/src/i830_render.c b/src/i830_render.c
index d587805..f5e144b 100644
--- a/src/i830_render.c
+++ b/src/i830_render.c
@@ -305,7 +305,7 @@ i830_texture_setup(PicturePtr pPict, Pix
 	else
 	    format |= MAPSURF_32BIT;
 
-	BEGIN_LP_RING(8);
+	BEGIN_LP_RING(10);
 	OUT_RING(_3DSTATE_LOAD_STATE_IMMEDIATE_2 | LOAD_TEXTURE_MAP(unit) | 4);
 	OUT_RING((offset & TM0S0_ADDRESS_MASK) | TM0S0_USE_FENCE); 
 	OUT_RING(((pPix->drawable.height - 1) << TM0S1_HEIGHT_SHIFT) |
@@ -318,7 +318,24 @@ i830_texture_setup(PicturePtr pPict, Pix
 		 TEXCOORDTYPE_CARTESIAN | ENABLE_ADDR_V_CNTL |
 		 TEXCOORD_ADDR_V_MODE(wrap_mode) |
 		 ENABLE_ADDR_U_CNTL | TEXCOORD_ADDR_U_MODE(wrap_mode));
-	OUT_RING(MI_NOOP);
+	/* map texel stream */
+	OUT_RING(_3DSTATE_MAP_COORD_SETBIND_CMD);
+	if (unit == 0)
+	    OUT_RING(TEXBIND_SET0(TEXCOORDSRC_VTXSET_0) |
+		    TEXBIND_SET1(TEXCOORDSRC_KEEP) |
+		    TEXBIND_SET2(TEXCOORDSRC_KEEP) |
+		    TEXBIND_SET3(TEXCOORDSRC_KEEP));
+	else
+	    OUT_RING(TEXBIND_SET0(TEXCOORDSRC_VTXSET_0) |
+		    TEXBIND_SET1(TEXCOORDSRC_VTXSET_1) |
+		    TEXBIND_SET2(TEXCOORDSRC_KEEP) |
+		    TEXBIND_SET3(TEXCOORDSRC_KEEP));
+	OUT_RING(_3DSTATE_MAP_TEX_STREAM_CMD | (unit << 16) |
+		DISABLE_TEX_STREAM_BUMP | 
+		ENABLE_TEX_STREAM_COORD_SET |
+		TEX_STREAM_COORD_SET(unit) |
+		ENABLE_TEX_STREAM_MAP_IDX |
+		TEX_STREAM_MAP_IDX(unit));
 	ADVANCE_LP_RING();
      }
 
@@ -392,7 +409,7 @@ i830_prepare_composite(int op, PicturePt
     {
 	CARD32 cblend, ablend, blendctl, vf2;
 
-	BEGIN_LP_RING(34);
+	BEGIN_LP_RING(26);
 
 	/* color buffer */
 	OUT_RING(_3DSTATE_BUF_INFO_CMD);
@@ -403,8 +420,6 @@ i830_prepare_composite(int op, PicturePt
 	OUT_RING(_3DSTATE_DST_BUF_VARS_CMD);
 	OUT_RING(dst_format);
 
-      	OUT_RING(MI_FLUSH | MI_WRITE_DIRTY_STATE | MI_INVALIDATE_MAP_CACHE);
-      	OUT_RING(MI_NOOP);		/* pad to quadword */
 	/* defaults */
 	OUT_RING(_3DSTATE_DFLT_Z_CMD);
 	OUT_RING(0);
@@ -421,32 +436,16 @@ i830_prepare_composite(int op, PicturePt
 	OUT_RING(DRAW_YMAX(pDst->drawable.height - 1) |
 		DRAW_XMAX(pDst->drawable.width - 1));
 	OUT_RING(0); /* yorig, xorig */
-	OUT_RING(MI_NOOP);
 
-	OUT_RING(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(3) | 0);
-	OUT_RING((1 << S3_POINT_WIDTH_SHIFT) | (2 << S3_LINE_WIDTH_SHIFT) |
-		S3_CULLMODE_NONE | S3_VERTEXHAS_XY);
-	OUT_RING(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(2) | 0);
+	OUT_RING(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(2) | 
+		I1_LOAD_S(3) | 1);
 	if (pMask)
 	    vf2 = 2 << 12; /* 2 texture coord sets */
 	else
 	    vf2 = 1 << 12;
-	vf2 |= (TEXCOORDFMT_2D << 16);
-	if (pMask)
-	    vf2 |= (TEXCOORDFMT_2D << 18);
-	else
-	    vf2 |= (TEXCOORDFMT_1D << 18);
-
-	vf2 |= (TEXCOORDFMT_1D << 20);
-	vf2 |= (TEXCOORDFMT_1D << 22);
-	vf2 |= (TEXCOORDFMT_1D << 24);
-	vf2 |= (TEXCOORDFMT_1D << 26);
-	vf2 |= (TEXCOORDFMT_1D << 28);
-	vf2 |= (TEXCOORDFMT_1D << 30);
-	OUT_RING(vf2);
+	OUT_RING(vf2); /* TEXCOORDFMT_2D */
+	OUT_RING(S3_CULLMODE_NONE | S3_VERTEXHAS_XY);
 
-      	OUT_RING(MI_FLUSH | MI_WRITE_DIRTY_STATE | MI_INVALIDATE_MAP_CACHE);
-      	OUT_RING(MI_NOOP);		/* pad to quadword */
 	/* For (src In mask) operation */
 	/* IN operator: Multiply src by mask components or mask alpha.*/
 	/* TEXBLENDOP_MODULE: arg1*arg2 */
@@ -481,9 +480,6 @@ i830_prepare_composite(int op, PicturePt
 	OUT_RING(ablend);
 	OUT_RING(0);
 
-      	OUT_RING(MI_FLUSH | MI_WRITE_DIRTY_STATE | MI_INVALIDATE_MAP_CACHE);
-      	OUT_RING(MI_NOOP);		/* pad to quadword */
-
 	blendctl = i830_get_blend_cntl(op, pMaskPicture, pDstPicture->format);
 	OUT_RING(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(8) | 0);
 	OUT_RING(S8_ENABLE_COLOR_BLEND | S8_BLENDFUNC_ADD | blendctl | 
diff-tree 64c30cf896f8bde3ee74c92b970132ab91b418cd (from b67adb6de34cede0e31f02f26cd5ec7b1adfa586)
Author: Wang Zhenyu <zhenyu.z.wang at intel.com>
Date:   Mon Apr 16 13:58:50 2007 +0800

    Update intel.man with 965GM chipset support

diff --git a/man/intel.man b/man/intel.man
index 80b327d..5ce31ea 100644
--- a/man/intel.man
+++ b/man/intel.man
@@ -24,7 +24,7 @@ the 830M and later.
 .SH SUPPORTED HARDWARE
 .B intel
 supports the i810, i810-DC100, i810e, i815, i830M, 845G, 852GM, 855GM,
-865G, 915G, 915GM, 945G, 945GM, 965G, 965Q and 946GZ chipsets.
+865G, 915G, 915GM, 945G, 945GM, 965G, 965Q, 946GZ and 965GM chipsets.
 
 .SH CONFIGURATION DETAILS
 Please refer to __xconfigfile__(__filemansuffix__) for general configuration
@@ -198,4 +198,5 @@ support reworked for XFree86 4.3 by Davi
 Keith Whitwell. Lid status support added by Alan Hourihane. Textured video
 support for 915G and later chips, RandR 1.2 and hardware modesetting added
 by Eric Anholt and Keith Packard. EXA and Render acceleration added by Wang
-Zhenyu. TV out support added by Zou Nan Hai and Keith Packard.
+Zhenyu. TV out support added by Zou Nan Hai and Keith Packard. 965GM support
+added by Wang Zhenyu.
diff-tree b67adb6de34cede0e31f02f26cd5ec7b1adfa586 (from b5b243e4120d6a048fb6bbe8814fe3184271e9d9)
Author: Wang Zhenyu <zhenyu.z.wang at intel.com>
Date:   Fri Apr 13 22:34:52 2007 +0800

    Fix crash on G965 XAA with LinearAlloc option
    
    We should alloc xaa_linear mem in LinearAlloc case, otherwise
    we get crash when initializing xf86 fb manager.

diff --git a/src/i830_memory.c b/src/i830_memory.c
index b26dd00..315f4ba 100644
--- a/src/i830_memory.c
+++ b/src/i830_memory.c
@@ -651,7 +651,7 @@ i830_allocate_overlay(ScrnInfoPtr pScrn)
     I830Ptr pI830 = I830PTR(pScrn);
 
     /* Only allocate if overlay is going to be enabled. */
-    if (!pI830->XvEnabled || IS_I965G(pI830))
+    if (!pI830->XvEnabled)
 	return TRUE;
 
     if (!IS_I965G(pI830)) {
diff-tree b5b243e4120d6a048fb6bbe8814fe3184271e9d9 (from 08cd5f9b0f086e51112008d50de48556372899f9)
Author: Eric Anholt <eric at anholt.net>
Date:   Thu Apr 12 12:34:23 2007 -0700

    Add license headers to 965 programs.

diff --git a/src/exa_sf.g4a b/src/exa_sf.g4a
index 8c1398f..5a02399 100644
--- a/src/exa_sf.g4a
+++ b/src/exa_sf.g4a
@@ -1,3 +1,31 @@
+/*
+ * Copyright © 2006 Intel Corporation
+ *
+ * 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:
+ *    Keith Packard <keithp at keithp.com>
+ *    Eric Anholt <eric at anholt.net>
+ *
+ */
+
 send (1) 0 g6<1>F g1.12<0,1,0>F math inv scalar mlen 1 rlen 1 { align1 };
 send (1) 0 g6.4<1>F g1.20<0,1,0>F math inv scalar mlen 1 rlen 1 { align1 };
 add (8) g7<1>F g4<8,8,1>F -g3<8,8,1>F { align1 };
diff --git a/src/exa_sf_mask.g4a b/src/exa_sf_mask.g4a
index a7e2d32..a0d6efc 100644
--- a/src/exa_sf_mask.g4a
+++ b/src/exa_sf_mask.g4a
@@ -1,3 +1,28 @@
+/*
+ * Copyright © 2006 Intel Corporation
+ *
+ * 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:
+ *    Wang Zhenyu <zhenyu.z.wang at intel.com>
+ */
 
 /* FIXME how to setup second coeffient for mask tex coord */
 
diff --git a/src/exa_sf_rotation.g4a b/src/exa_sf_rotation.g4a
index 4c93553..59d40d4 100644
--- a/src/exa_sf_rotation.g4a
+++ b/src/exa_sf_rotation.g4a
@@ -1,3 +1,29 @@
+/*
+ * Copyright © 2007 Intel Corporation
+ *
+ * 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:
+ *    Wang Zhenyu <zhenyu.z.wang at intel.com>
+ */
+
 /* 1/dx */
 send (1) 0 g6<1>F g1.12<0,1,0>F math inv scalar mlen 1 rlen 1 { align1 };
 /* 1/dy */
diff --git a/src/exa_wm_maskca.g4a b/src/exa_wm_maskca.g4a
index fa923f6..0e96aa0 100644
--- a/src/exa_wm_maskca.g4a
+++ b/src/exa_wm_maskca.g4a
@@ -1,4 +1,30 @@
 /*
+ * Copyright © 2007 Intel Corporation
+ *
+ * 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:
+ *    Wang Zhenyu <zhenyu.z.wang at intel.com>
+ */
+
+/*
  * This's for exa composite operation in no mask picture case.
  * The simplest case is just sending what src picture has to dst picture.
  * XXX: This is still experimental, and should be fixed to support multiple texture
diff --git a/src/exa_wm_maskca_srcalpha.g4a b/src/exa_wm_maskca_srcalpha.g4a
index e233968..a92c9e4 100644
--- a/src/exa_wm_maskca_srcalpha.g4a
+++ b/src/exa_wm_maskca_srcalpha.g4a
@@ -1,4 +1,30 @@
 /*
+ * Copyright © 2007 Intel Corporation
+ *
+ * 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:
+ *    Wang Zhenyu <zhenyu.z.wang at intel.com>
+ */
+
+/*
  * This's for exa composite operation in no mask picture case.
  * The simplest case is just sending what src picture has to dst picture.
  * XXX: This is still experimental, and should be fixed to support multiple texture
diff --git a/src/exa_wm_masknoca.g4a b/src/exa_wm_masknoca.g4a
index c2049fd..2e9e3c9 100644
--- a/src/exa_wm_masknoca.g4a
+++ b/src/exa_wm_masknoca.g4a
@@ -1,4 +1,30 @@
 /*
+ * Copyright © 2006 Intel Corporation
+ *
+ * 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:
+ *    Wang Zhenyu <zhenyu.z.wang at intel.com>
+ */
+
+/*
  * This's for exa composite operation in no mask picture case.
  * The simplest case is just sending what src picture has to dst picture.
  * XXX: This is still experimental, and should be fixed to support multiple texture
diff --git a/src/exa_wm_nomask.g4a b/src/exa_wm_nomask.g4a
index 8e851a3..f92dc1a 100644
--- a/src/exa_wm_nomask.g4a
+++ b/src/exa_wm_nomask.g4a
@@ -1,4 +1,30 @@
 /*
+ * Copyright © 2006 Intel Corporation
+ *
+ * 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:
+ *    Wang Zhenyu <zhenyu.z.wang at intel.com>
+ */
+
+/*
  * This's for exa composite operation in no mask picture case.
  * The simplest case is just sending what src picture has to dst picture.
  */
diff --git a/src/exa_wm_rotation.g4a b/src/exa_wm_rotation.g4a
index b12f81c..613a5cb 100644
--- a/src/exa_wm_rotation.g4a
+++ b/src/exa_wm_rotation.g4a
@@ -1,4 +1,30 @@
 /*
+ * Copyright © 2007 Intel Corporation
+ *
+ * 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:
+ *    Wang Zhenyu <zhenyu.z.wang at intel.com>
+ */
+
+/*
  * This's for exa composite operation in no mask picture case.
  * The simplest case is just sending what src picture has to dst picture.
  */
diff --git a/src/packed_yuv_sf.g4a b/src/packed_yuv_sf.g4a
index 8c1398f..5a02399 100644
--- a/src/packed_yuv_sf.g4a
+++ b/src/packed_yuv_sf.g4a
@@ -1,3 +1,31 @@
+/*
+ * Copyright © 2006 Intel Corporation
+ *
+ * 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:
+ *    Keith Packard <keithp at keithp.com>
+ *    Eric Anholt <eric at anholt.net>
+ *
+ */
+
 send (1) 0 g6<1>F g1.12<0,1,0>F math inv scalar mlen 1 rlen 1 { align1 };
 send (1) 0 g6.4<1>F g1.20<0,1,0>F math inv scalar mlen 1 rlen 1 { align1 };
 add (8) g7<1>F g4<8,8,1>F -g3<8,8,1>F { align1 };
diff --git a/src/packed_yuv_wm.g4a b/src/packed_yuv_wm.g4a
index 4b6391b..5e31f10 100644
--- a/src/packed_yuv_wm.g4a
+++ b/src/packed_yuv_wm.g4a
@@ -1,3 +1,31 @@
+/*
+ * Copyright © 2006 Intel Corporation
+ *
+ * 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:
+ *    Keith Packard <keithp at keithp.com>
+ *    Eric Anholt <eric at anholt.net>
+ *
+ */
+
 /* The initial payload of the thread is always g0.
  * WM_URB (incoming URB entries) is g3
  * X0_R is g4


More information about the xorg-commit mailing list