xf86-video-intel: Branch 'drm-gem' - 52 commits - configure.ac src/common.h src/i810_driver.c src/i810_reg.h src/i830_bios.c src/i830_bios.h src/i830_debug.c src/i830_display.c src/i830_dri.c src/i830_driver.c src/i830.h src/i830_hdmi.c src/i830_hwmc.c src/i830_hwmc.h src/i830_lvds.c src/i830_memory.c src/i830_quirks.c src/i830_sdvo.c src/i830_sdvo.h src/i830_sdvo_regs.h src/i830_tv.c src/i830_video.c src/i830_video.h src/i915_hwmc.c src/i915_hwmc.h src/i915_video.c src/i965_render.c src/i965_video.c src/Makefile.am src/reg_dumper/.gitignore src/reg_dumper/hotplug.c src/reg_dumper/Makefile.am src/xvmc/I810XvMC.c src/xvmc/i915_structs.h src/xvmc/i915_xvmc.c src/xvmc/intel_xvmc.c src/xvmc/intel_xvmc_dump.c src/xvmc/intel_xvmc.h

Carl Worth cworth at kemper.freedesktop.org
Fri Jul 18 10:44:45 PDT 2008


 configure.ac               |    4 
 src/Makefile.am            |    9 
 src/common.h               |   36 -
 src/i810_driver.c          |   20 
 src/i810_reg.h             |   42 +
 src/i830.h                 |    9 
 src/i830_bios.c            |   90 ++
 src/i830_bios.h            |   93 +++
 src/i830_debug.c           |   49 +
 src/i830_display.c         |   73 ++
 src/i830_dri.c             |   19 
 src/i830_driver.c          |   85 ++
 src/i830_hdmi.c            |  233 +++++++
 src/i830_hwmc.c            |    5 
 src/i830_hwmc.h            |    7 
 src/i830_lvds.c            |   43 +
 src/i830_memory.c          |   15 
 src/i830_quirks.c          |    9 
 src/i830_sdvo.c            |  257 +++++++-
 src/i830_sdvo.h            |    2 
 src/i830_sdvo_regs.h       |   36 +
 src/i830_tv.c              |    4 
 src/i830_video.c           |   73 +-
 src/i830_video.h           |    2 
 src/i915_hwmc.c            |   35 -
 src/i915_hwmc.h            |    1 
 src/i915_video.c           |   10 
 src/i965_render.c          |   75 +-
 src/i965_video.c           |    2 
 src/reg_dumper/.gitignore  |    1 
 src/reg_dumper/Makefile.am |    9 
 src/reg_dumper/hotplug.c   |  151 ++++
 src/xvmc/I810XvMC.c        |    2 
 src/xvmc/i915_structs.h    |   81 ++
 src/xvmc/i915_xvmc.c       | 1385 +++++++++++++++++++++------------------------
 src/xvmc/intel_xvmc.c      |   12 
 src/xvmc/intel_xvmc.h      |    3 
 src/xvmc/intel_xvmc_dump.c |   31 -
 38 files changed, 2105 insertions(+), 908 deletions(-)

New commits:
commit a6ad50402cb879b08de95f94959bb1f59701c1ff
Merge: e9916b9... c4565a9...
Author: Carl Worth <cworth at cworth.org>
Date:   Thu Jul 17 00:38:54 2008 -0700

    Merge branch 'master' into drm-gem
    
    Conflicts:
    
    	configure.ac
    	src/reg_dumper/Makefile.am

diff --cc configure.ac
index e62502c,2dabd4f..254fef4
--- a/configure.ac
+++ b/configure.ac
@@@ -196,12 -196,15 +196,16 @@@ if test "x$GCC" = "xyes"; the
  	-Wnested-externs -fno-strict-aliasing"
  fi
  
 +PKG_CHECK_MODULES(DRM, [libdrm >= 2.4.0])
  AM_CONDITIONAL(DRI, test x$DRI = xyes)
  if test "$DRI" = yes; then
 -        PKG_CHECK_MODULES(DRI, [libdrm xf86driproto glproto])
 +        PKG_CHECK_MODULES(DRI, [xf86driproto glproto])
          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.4.0],[DRI_MM=yes], [DRI_MM=no])
+ 	if test "x$DRI_MM" = xyes; then
+ 		AC_DEFINE(XF86DRI_MM,1,[Extended DRI memory management])
+ 	fi
  	if test "$have_damage_h" = yes; then
  		AC_DEFINE(DAMAGE,1,[Use Damage extension])
  	fi
diff --cc src/i830_memory.c
index 3d6e245,0a2faeb..08a2201
--- a/src/i830_memory.c
+++ b/src/i830_memory.c
@@@ -459,10 -456,11 +459,11 @@@ i830_allocator_init(ScrnInfoPtr pScrn, 
  	}
  	if (pI830->fb_compression)
  	    mmsize -= MB(6) + ROUND_TO_PAGE(FBC_LL_SIZE + FBC_LL_PAD);
 -	/* Can't do TTM on stolen memory */
 +	/* Can't do GEM on stolen memory */
  	mmsize -= pI830->stolen_size;
  
- 	if (HWS_NEED_GFX(pI830) && IS_IGD_GM(pI830))
+ 	/* new chipsets need non-stolen status page */
+ 	if (HWS_NEED_GFX(pI830) && HWS_NEED_NONSTOLEN(pI830))
  	    mmsize -= HWSTATUS_PAGE_SIZE;
  
  	/* Create the aperture allocation */
diff --cc src/reg_dumper/Makefile.am
index 1c8db20,d49a59b..1127581
--- a/src/reg_dumper/Makefile.am
+++ b/src/reg_dumper/Makefile.am
@@@ -1,4 -1,4 +1,4 @@@
- noinst_PROGRAMS = intel_reg_dumper intel_idle intel_stepping intel_statuspage
 -noinst_PROGRAMS = intel_reg_dumper intel_idle intel_stepping intel_hotplug
++noinst_PROGRAMS = intel_reg_dumper intel_idle intel_stepping intel_statuspage intel_hotplug
  
  intel_reg_dumper_SOURCES = \
  	main.c \
@@@ -15,11 -21,7 +21,12 @@@ intel_hotplug_SOURCES = 
  intel_stepping_SOURCES = \
  	stepping.c
  
 +intel_statuspage_SOURCES = \
 +	statuspage.c \
 +	reg_dumper.h \
 +	util.c
 +
+ intel_hotplug_LDADD = $(PCIACCESS_LIBS)
  intel_reg_dumper_LDADD = $(PCIACCESS_LIBS)
  intel_idle_LDADD = $(PCIACCESS_LIBS)
  intel_stepping_LDADD = $(PCIACCESS_LIBS)
commit c4565a9811487402d899d0933cc63e27ffe1ff08
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Wed Jul 16 10:45:28 2008 +0800

    Only initialize integrated TV encoder for mobile chips

diff --git a/src/i830_driver.c b/src/i830_driver.c
index c880833..e29dd10 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -940,7 +940,7 @@ I830SetupOutputs(ScrnInfoPtr pScrn)
    } else {
       i830_dvo_init(pScrn);
    }
-   if (IS_I9XX(pI830) && !IS_I915G(pI830))
+   if (IS_I9XX(pI830) && IS_MOBILE(pI830))
       i830_tv_init(pScrn);
    
    for (o = 0; o < config->num_output; o++)
commit bca316863b79148b2f51a97d58b94e52ba3eae9f
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Tue Jul 15 13:35:21 2008 +0800

    xvmc: use vector based structure
    
    This is more clear to read MV components.

diff --git a/src/xvmc/i915_xvmc.c b/src/xvmc/i915_xvmc.c
index 27d1380..c32073a 100644
--- a/src/xvmc/i915_xvmc.c
+++ b/src/xvmc/i915_xvmc.c
@@ -39,9 +39,9 @@
                                  SIZE_Y420(surface->width, surface->height))
 
 typedef union {
-    short s[4];
-    uint  u[2];
-} su_t;
+    int16_t component[2];
+    int32_t v;
+} vector_t;
 
 #if 0
 static int findOverlap(unsigned int width, unsigned int height,
@@ -835,10 +835,7 @@ static void i915_mc_mpeg_macroblock_0mv(XvMCContext *context, XvMCMacroBlock *mb
 static void i915_mc_mpeg_macroblock_1fbmv(XvMCContext *context, XvMCMacroBlock *mb)
 {
     struct i915_3dmpeg_macroblock_1fbmv macroblock_1fbmv;
-
-    /* Motion Vectors */
-    su_t fmv;
-    su_t bmv;
+    vector_t mv0[2];
 
     /* 3DMPEG_MACROBLOCK(1fbmv) */
     memset(&macroblock_1fbmv, 0, sizeof(macroblock_1fbmv));
@@ -859,13 +856,13 @@ static void i915_mc_mpeg_macroblock_1fbmv(XvMCContext *context, XvMCMacroBlock *
     macroblock_1fbmv.header.dw1.coded_block_pattern = mb->coded_block_pattern;
     macroblock_1fbmv.header.dw1.skipped_macroblocks = 0;
 
-    fmv.s[0] = mb->PMV[0][0][0];
-    fmv.s[1] = mb->PMV[0][0][1];
-    bmv.s[0] = mb->PMV[0][1][0];
-    bmv.s[1] = mb->PMV[0][1][1];
+    mv0[0].component[0] = mb->PMV[0][0][0];
+    mv0[0].component[1] = mb->PMV[0][0][1];
+    mv0[1].component[0] = mb->PMV[0][1][0];
+    mv0[1].component[1] = mb->PMV[0][1][1];
 
-    macroblock_1fbmv.dw2 = fmv.u[0];
-    macroblock_1fbmv.dw3 = bmv.u[0];
+    macroblock_1fbmv.dw2 = mv0[0].v;
+    macroblock_1fbmv.dw3 = mv0[1].v;
 
     intelBatchbufferData(&macroblock_1fbmv, sizeof(macroblock_1fbmv), 0);
 }
@@ -873,10 +870,8 @@ static void i915_mc_mpeg_macroblock_1fbmv(XvMCContext *context, XvMCMacroBlock *
 static void i915_mc_mpeg_macroblock_2fbmv(XvMCContext *context, XvMCMacroBlock *mb, unsigned int ps)
 {
     struct i915_3dmpeg_macroblock_2fbmv macroblock_2fbmv;
-
-    /* Motion Vectors */
-    su_t fmv;
-    su_t bmv;
+    vector_t mv0[2];
+    vector_t mv1[2];
 
     /* 3DMPEG_MACROBLOCK(2fbmv) */
     memset(&macroblock_2fbmv, 0, sizeof(macroblock_2fbmv));
@@ -897,41 +892,33 @@ static void i915_mc_mpeg_macroblock_2fbmv(XvMCContext *context, XvMCMacroBlock *
     macroblock_2fbmv.header.dw1.coded_block_pattern = mb->coded_block_pattern;
     macroblock_2fbmv.header.dw1.skipped_macroblocks = 0;
 
-    fmv.s[0] = mb->PMV[0][0][0];
-    fmv.s[1] = mb->PMV[0][0][1];
-    fmv.s[2] = mb->PMV[1][0][0];
-    fmv.s[3] = mb->PMV[1][0][1];
-    bmv.s[0] = mb->PMV[0][1][0];
-    bmv.s[1] = mb->PMV[0][1][1];
-    bmv.s[2] = mb->PMV[1][1][0];
-    bmv.s[3] = mb->PMV[1][1][1];
+    mv0[0].component[0] = mb->PMV[0][0][0];
+    mv0[0].component[1] = mb->PMV[0][0][1];
+    mv0[1].component[0] = mb->PMV[0][1][0];
+    mv0[1].component[1] = mb->PMV[0][1][1];
+    mv1[0].component[0] = mb->PMV[1][0][0];
+    mv1[0].component[1] = mb->PMV[1][0][1];
+    mv1[1].component[0] = mb->PMV[1][1][0];
+    mv1[1].component[1] = mb->PMV[1][1][1];
 
     if ((ps & XVMC_FRAME_PICTURE) == XVMC_FRAME_PICTURE) {
         if ((mb->motion_type & 3) == XVMC_PREDICTION_FIELD) {
-            fmv.s[0] = mb->PMV[0][0][0];
-            fmv.s[1] = mb->PMV[0][0][1] >> 1;
-            fmv.s[2] = mb->PMV[1][0][0];
-            fmv.s[3] = mb->PMV[1][0][1] >> 1;
-            bmv.s[0] = mb->PMV[0][1][0];
-            bmv.s[1] = mb->PMV[0][1][1] >> 1;
-            bmv.s[2] = mb->PMV[1][1][0];
-            bmv.s[3] = mb->PMV[1][1][1] >> 1;
+            mv0[0].component[1] = mb->PMV[0][0][1] >> 1;
+            mv0[1].component[1] = mb->PMV[0][1][1] >> 1;
+            mv1[0].component[1] = mb->PMV[1][0][1] >> 1;
+            mv1[1].component[1] = mb->PMV[1][1][1] >> 1;
         } else if ((mb->motion_type & 3) == XVMC_PREDICTION_DUAL_PRIME) {
-            fmv.s[0] = mb->PMV[0][0][0];
-            fmv.s[1] = mb->PMV[0][0][1] >> 1;
-            fmv.s[2] = mb->PMV[0][0][0];
-            fmv.s[3] = mb->PMV[0][0][1] >> 1;  // MPEG2 MV[0][1] isn't used
-            bmv.s[0] = mb->PMV[1][0][0];
-            bmv.s[1] = mb->PMV[1][0][1] >> 1;
-            bmv.s[2] = mb->PMV[1][1][0];
-            bmv.s[3] = mb->PMV[1][1][1] >> 1;
+            mv0[0].component[1] = mb->PMV[0][0][1] >> 1;
+            mv0[1].component[1] = mb->PMV[0][1][1] >> 1;  // MPEG2 MV[0][1] isn't used
+            mv1[0].component[1] = mb->PMV[1][0][1] >> 1;
+            mv1[1].component[1] = mb->PMV[1][1][1] >> 1;
         }
     }
 
-    macroblock_2fbmv.dw2 = fmv.u[0];
-    macroblock_2fbmv.dw3 = bmv.u[0];
-    macroblock_2fbmv.dw4 = fmv.u[1];
-    macroblock_2fbmv.dw5 = bmv.u[1];
+    macroblock_2fbmv.dw2 = mv0[0].v;
+    macroblock_2fbmv.dw3 = mv0[1].v;
+    macroblock_2fbmv.dw4 = mv1[0].v;
+    macroblock_2fbmv.dw5 = mv1[1].v;
 
     intelBatchbufferData(&macroblock_2fbmv, sizeof(macroblock_2fbmv), 0);
 }
commit 0c67219d0e6cfc858af2eb375c2f9473d0f6db60
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Tue Jul 15 13:29:33 2008 +0800

    move FBC register dump out of display registers
    
    This makes it easier to read.

diff --git a/src/i830_debug.c b/src/i830_debug.c
index 2b5708e..7930346 100644
--- a/src/i830_debug.c
+++ b/src/i830_debug.c
@@ -537,15 +537,6 @@ static struct i830SnapshotRec {
     DEFINEREG2(PIPEASRC, i830_debug_yxminus1),
     DEFINEREG2(PIPEASTAT, i830_debug_pipestat),
 
-    DEFINEREG(FBC_CFB_BASE),
-    DEFINEREG(FBC_LL_BASE),
-    DEFINEREG(FBC_CONTROL),
-    DEFINEREG(FBC_COMMAND),
-    DEFINEREG(FBC_STATUS),
-    DEFINEREG(FBC_CONTROL2),
-    DEFINEREG(FBC_FENCE_OFF),
-    DEFINEREG(FBC_MOD_NUM),
-
     DEFINEREG2(FPA0, i830_debug_fp),
     DEFINEREG2(FPA1, i830_debug_fp),
     DEFINEREG2(DPLL_A, i830_debug_dpll),
@@ -623,6 +614,15 @@ static struct i830SnapshotRec {
     DEFINEREG(TV_H_CHROMA_0),
     DEFINEREG(TV_H_CHROMA_59),
 
+    DEFINEREG(FBC_CFB_BASE),
+    DEFINEREG(FBC_LL_BASE),
+    DEFINEREG(FBC_CONTROL),
+    DEFINEREG(FBC_COMMAND),
+    DEFINEREG(FBC_STATUS),
+    DEFINEREG(FBC_CONTROL2),
+    DEFINEREG(FBC_FENCE_OFF),
+    DEFINEREG(FBC_MOD_NUM),
+
     DEFINEREG(MI_MODE),
     /* DEFINEREG(MI_DISPLAY_POWER_DOWN), CRL only */
     DEFINEREG(MI_ARB_STATE),
commit a76ae7cab3001ce6639ae23fb0769c4e46b57e71
Author: lipeng <peng.li at linux.intel.com>
Date:   Tue Jul 15 10:26:33 2008 -0700

    Fix GPIO pin usage for DDC on second HDMI port.

diff --git a/src/i830_hdmi.c b/src/i830_hdmi.c
index 72d4c63..b738463 100644
--- a/src/i830_hdmi.c
+++ b/src/i830_hdmi.c
@@ -225,7 +225,7 @@ i830_hdmi_init(ScrnInfoPtr pScrn, int output_reg)
     if (output_reg == SDVOB)
 	I830I2CInit(pScrn, &intel_output->pDDCBus, GPIOE, "HDMIDDC_B");
     else
-	I830I2CInit(pScrn, &intel_output->pDDCBus, GPIOE, "HDMIDDC_C");
+	I830I2CInit(pScrn, &intel_output->pDDCBus, GPIOD, "HDMIDDC_C");
 
     xf86DrvMsg(pScrn->scrnIndex, X_INFO,
 	       "HDMI output %d detected\n",
commit 5054a86b1b362f3f63310afb9ef2d37c9f1cfca5
Author: Eric Anholt <eric at anholt.net>
Date:   Mon Jul 14 13:43:31 2008 -0700

    Fix DSPARB setting on 845/865, which have only the AEND field and 96 entries.

diff --git a/src/i830_driver.c b/src/i830_driver.c
index 0a49d3a..c880833 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -1994,7 +1994,16 @@ i830_set_dsparb(ScrnInfoPtr pScrn)
 	   OUTREG(DSPARB, (95 << DSPARB_CSTART_SHIFT) |
 		  (48 << DSPARB_BSTART_SHIFT));
    } else {
-       OUTREG(DSPARB, 254 << DSPARB_BEND_SHIFT | 128 << DSPARB_AEND_SHIFT);
+       if (IS_MOBILE(pI830)) {
+	   /* The 830 has 288 entries, and the 855 has 256. */
+	   OUTREG(DSPARB, 254 << DSPARB_BEND_SHIFT | 128 << DSPARB_AEND_SHIFT);
+       } else {
+	   /* The 845/865 only have a AEND field.  Though the field size would
+	    * allow 128 entries, the 865 rendered the cursor wrong then.
+	    * The BIOS set it up for 96.
+	    */
+	   OUTREG(DSPARB, 95 << DSPARB_AEND_SHIFT);
+       }
    }
 }
 
commit 8ac00ca97995e36514ff593fec3c0f0d316ed138
Author: Julien Cristau <jcristau at debian.org>
Date:   Fri Jun 6 13:40:20 2008 +0200

    Link the driver with -lpciaccess and -ldrm if needed
    
    This makes sure the driver ends up with a DT_NEEDED reference to
    the libraries it's using.

diff --git a/src/Makefile.am b/src/Makefile.am
index 45f8b19..1e4ad28 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -36,6 +36,10 @@ AM_CFLAGS = @WARN_CFLAGS@ @XORG_CFLAGS@ @DRI_CFLAGS@ @PCIACCESS_CFLAGS@ \
 intel_drv_la_LTLIBRARIES = intel_drv.la
 intel_drv_la_LDFLAGS = -module -avoid-version
 intel_drv_ladir = @moduledir@/drivers
+intel_drv_la_LIBADD =
+if XSERVER_LIBPCIACCESS
+intel_drv_la_LIBADD += @PCIACCESS_LIBS@
+endif
 
 XMODE_SRCS=\
 	 local_xf86Rename.h \
@@ -203,6 +207,8 @@ endif
 if DRI
 intel_drv_la_SOURCES += \
 	$(INTEL_DRI_SRCS)
+intel_drv_la_LIBADD += \
+	$(DRI_LIBS)
 endif
 
 if XVMC
commit d61182511b1520b04133d28480e1ffaacbaeb753
Author: Julien Cristau <jcristau at debian.org>
Date:   Sun Jul 6 12:00:52 2008 +0200

    Fix gen4asm rule to work with a build dir

diff --git a/src/Makefile.am b/src/Makefile.am
index 9dd9b37..45f8b19 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -185,7 +185,7 @@ if HAVE_GEN4ASM
 
 SUFFIXES = .g4a .g4b
 .g4a.g4b:
-	m4 -s $*.g4a > $*.g4m && intel-gen4asm -o $@ $*.g4m && rm $*.g4m
+	m4 -I$(srcdir) -s $< > $*.g4m && intel-gen4asm -o $@ $*.g4m && rm $*.g4m
 
 $(INTEL_G4B): $(INTEL_G4I)
 
commit 757c00927a6f5760135136450b8d02d0f999ac1c
Author: Carl Worth <cworth at cworth.org>
Date:   Mon Jul 7 15:58:27 2008 -0700

    Use up to 256 separate vertex buffers
    
    This allows us to only call i830WaitSync once every 128 calls to composite
    rather than on every call. However, we do need to also call MI_FLUSH to
    avoid the vertex cache getting in our way, (since our "separate" buffers
    are all allocated as one contiguous chunk).

diff --git a/src/i965_render.c b/src/i965_render.c
index 3c7379c..1cbfe24 100644
--- a/src/i965_render.c
+++ b/src/i965_render.c
@@ -60,7 +60,7 @@ do { 							\
 #endif
 
 #define MAX_VERTEX_PER_COMPOSITE    24
-#define MAX_VERTEX_BUFFERS	    1
+#define MAX_VERTEX_BUFFERS	    256
 
 struct blendinfo {
     Bool dst_alpha;
@@ -1401,7 +1401,8 @@ i965_composite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY,
     }
     assert (i * 4 <= sizeof(card_state->vb));
 
-    BEGIN_BATCH(11);
+    BEGIN_BATCH(12);
+    OUT_BATCH(MI_FLUSH);
     /* Set up the pointer to our (single) vertex buffer */
     OUT_BATCH(BRW_3DSTATE_VERTEX_BUFFERS | 3);
     OUT_BATCH((0 << VB0_BUFFER_INDEX_SHIFT) |
commit 0c548cd040d0c5e1812470ccdf6de86b6a2926d7
Author: Carl Worth <cworth at cworth.org>
Date:   Mon Jul 7 14:01:15 2008 -0700

    Allow for multiple vertex buffers (though only use one for now)
    
    Using more than one (in the future) will allow for doing less frequent calls
    to i830WaitSync.

diff --git a/src/i965_render.c b/src/i965_render.c
index a9e3227..3c7379c 100644
--- a/src/i965_render.c
+++ b/src/i965_render.c
@@ -59,6 +59,9 @@ do { 							\
 } while(0)
 #endif
 
+#define MAX_VERTEX_PER_COMPOSITE    24
+#define MAX_VERTEX_BUFFERS	    1
+
 struct blendinfo {
     Bool dst_alpha;
     Bool src_alpha;
@@ -500,7 +503,7 @@ typedef struct _gen4_state {
     struct brw_cc_viewport cc_viewport;
     PAD64 (brw_cc_viewport, 0);
 
-    float vb[(2 + 3 + 3) * 3];   /* (dst, src, mask) 3 vertices, 4 bytes */
+    float vb[MAX_VERTEX_PER_COMPOSITE * MAX_VERTEX_BUFFERS];
 } gen4_state_t;
 
 /** Private data for gen4 render accel implementation. */
@@ -510,6 +513,7 @@ struct gen4_render_state {
 
     int binding_table_index;
     int surface_state_index;
+    int vb_offset;
     int vertex_size;
 };
 
@@ -969,6 +973,7 @@ i965_prepare_composite(int op, PicturePtr pSrcPicture,
 	i830WaitSync(pScrn);
 	render_state->binding_table_index = 0;
 	render_state->surface_state_index = 0;
+	render_state->vb_offset = 0;
     }
 
     binding_table = card_state->binding_table +
@@ -1347,12 +1352,12 @@ i965_composite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY,
 	}
     }
 
-    /* Wait for any existing composite rectangles to land before we overwrite
-     * the VB with the next one.
-     */
-    i830WaitSync(pScrn);
+    if (render_state->vb_offset + MAX_VERTEX_PER_COMPOSITE >= ARRAY_SIZE(card_state->vb)) {
+	i830WaitSync(pScrn);
+	render_state->vb_offset = 0;
+    }
 
-    i = 0;
+    i = render_state->vb_offset;
     /* rect (x2,y2) */
     vb[i++] = (float)(dstX + w);
     vb[i++] = (float)(dstY + h);
@@ -1402,7 +1407,8 @@ i965_composite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY,
     OUT_BATCH((0 << VB0_BUFFER_INDEX_SHIFT) |
 	      VB0_VERTEXDATA |
 	      (render_state->vertex_size << VB0_BUFFER_PITCH_SHIFT));
-    OUT_BATCH(render_state->card_state_offset + offsetof(gen4_state_t, vb));
+    OUT_BATCH(render_state->card_state_offset + offsetof(gen4_state_t, vb) +
+	      render_state->vb_offset * 4);
     OUT_BATCH(3);
     OUT_BATCH(0); // ignore for VERTEXDATA, but still there
 
@@ -1418,6 +1424,8 @@ i965_composite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY,
     OUT_BATCH(0); /* index buffer offset, ignored */
     ADVANCE_BATCH();
 
+    render_state->vb_offset = i;
+
 #ifdef I830DEBUG
     ErrorF("sync after 3dprimitive\n");
     I830Sync(pScrn);
commit cc2249333cd462b4d99d110a12c454ca141b2be8
Author: Carl Worth <cworth at cworth.org>
Date:   Mon Jul 7 13:25:42 2008 -0700

    Move VERTEX_BUFFERS setup from prepare_composite to composite
    
    This is in preparation for having larger (or multiple) vertex buffers
    in the future.

diff --git a/src/i965_render.c b/src/i965_render.c
index a13aec2..a9e3227 100644
--- a/src/i965_render.c
+++ b/src/i965_render.c
@@ -510,6 +510,7 @@ struct gen4_render_state {
 
     int binding_table_index;
     int surface_state_index;
+    int vertex_size;
 };
 
 /**
@@ -1195,6 +1196,8 @@ i965_prepare_composite(int op, PicturePtr pSrcPicture,
 	int selem = is_affine ? 2 : 3;
 	uint32_t    w_component;
 	uint32_t    src_format;
+
+	render_state->vertex_size = 4 * (2 + nelem * selem);
 	
 	if (is_affine)
 	{
@@ -1206,17 +1209,9 @@ i965_prepare_composite(int op, PicturePtr pSrcPicture,
 	    src_format = BRW_SURFACEFORMAT_R32G32B32_FLOAT;
 	    w_component = BRW_VFCOMPONENT_STORE_SRC;
 	}
-	BEGIN_BATCH(pMask?12:10);
-	/* Set up the pointer to our (single) vertex buffer */
-	OUT_BATCH(BRW_3DSTATE_VERTEX_BUFFERS | 3);
-	OUT_BATCH((0 << VB0_BUFFER_INDEX_SHIFT) |
-		  VB0_VERTEXDATA |
-		  ((4 * (2 + nelem * selem)) << VB0_BUFFER_PITCH_SHIFT));
-	OUT_BATCH(state_base_offset + offsetof(gen4_state_t, vb));
-        OUT_BATCH(3);
-	OUT_BATCH(0); // ignore for VERTEXDATA, but still there
-
+	BEGIN_BATCH(pMask?7:5);
 	/* Set up our vertex elements, sourced from the single vertex buffer.
+	 * that will be set up later.
 	 */
 	
 	OUT_BATCH(BRW_3DSTATE_VERTEX_ELEMENTS | ((2 * (1 + nelem)) - 1));
@@ -1271,6 +1266,7 @@ i965_composite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY,
     ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum];
     I830Ptr pI830 = I830PTR(pScrn);
     gen4_state_t *card_state = pI830->gen4_render_state->card_state;
+    struct gen4_render_state *render_state = pI830->gen4_render_state;
     Bool has_mask;
     Bool is_affine_src, is_affine_mask, is_affine;
     float src_x[3], src_y[3], src_w[3], mask_x[3], mask_y[3], mask_w[3];
@@ -1400,20 +1396,28 @@ i965_composite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY,
     }
     assert (i * 4 <= sizeof(card_state->vb));
 
-    {
-      BEGIN_BATCH(6);
-      OUT_BATCH(BRW_3DPRIMITIVE |
-		BRW_3DPRIMITIVE_VERTEX_SEQUENTIAL |
-		(_3DPRIM_RECTLIST << BRW_3DPRIMITIVE_TOPOLOGY_SHIFT) |
-		(0 << 9) |  /* CTG - indirect vertex count */
-		4);
-      OUT_BATCH(3);  /* vertex count per instance */
-      OUT_BATCH(0); /* start vertex offset */
-      OUT_BATCH(1); /* single instance */
-      OUT_BATCH(0); /* start instance location */
-      OUT_BATCH(0); /* index buffer offset, ignored */
-      ADVANCE_BATCH();
-    }
+    BEGIN_BATCH(11);
+    /* Set up the pointer to our (single) vertex buffer */
+    OUT_BATCH(BRW_3DSTATE_VERTEX_BUFFERS | 3);
+    OUT_BATCH((0 << VB0_BUFFER_INDEX_SHIFT) |
+	      VB0_VERTEXDATA |
+	      (render_state->vertex_size << VB0_BUFFER_PITCH_SHIFT));
+    OUT_BATCH(render_state->card_state_offset + offsetof(gen4_state_t, vb));
+    OUT_BATCH(3);
+    OUT_BATCH(0); // ignore for VERTEXDATA, but still there
+
+    OUT_BATCH(BRW_3DPRIMITIVE |
+	      BRW_3DPRIMITIVE_VERTEX_SEQUENTIAL |
+	      (_3DPRIM_RECTLIST << BRW_3DPRIMITIVE_TOPOLOGY_SHIFT) |
+	      (0 << 9) |  /* CTG - indirect vertex count */
+	      4);
+    OUT_BATCH(3);  /* vertex count per instance */
+    OUT_BATCH(0); /* start vertex offset */
+    OUT_BATCH(1); /* single instance */
+    OUT_BATCH(0); /* start instance location */
+    OUT_BATCH(0); /* index buffer offset, ignored */
+    ADVANCE_BATCH();
+
 #ifdef I830DEBUG
     ErrorF("sync after 3dprimitive\n");
     I830Sync(pScrn);
commit 3c0f2bcc9965155fecab606edae68874427d3423
Author: Jesse Barnes <jbarnes at jbarnes-t61.(none)>
Date:   Thu Jul 10 12:57:25 2008 -0700

    Add VBIOS based TV connector detection
    
    Now that the VBIOS code supports it, we can use the general features block to
    detect whether a TV connector is present on a given platform.
    
    Reviewed by Nanhai Zou.

diff --git a/src/i830_tv.c b/src/i830_tv.c
index cde929a..651f77b 100644
--- a/src/i830_tv.c
+++ b/src/i830_tv.c
@@ -1715,6 +1715,10 @@ i830_tv_init(ScrnInfoPtr pScrn)
 	    (tv_dac_off & TVDAC_STATE_CHG_EN) != 0)
 	return;
 
+    i830_bios_get_tv(pScrn);
+    if (!pI830->tv_present) /* VBIOS claims no TV connector */
+	return;
+
     output = xf86OutputCreate (pScrn, &i830_tv_output_funcs, "TV");
 
     if (!output)
commit e00d9435609bcff1afb71aa6638a6b42a64f5178
Author: Jesse Barnes <jbarnes at jbarnes-t61.(none)>
Date:   Thu Jul 10 12:55:12 2008 -0700

    Improve VBIOS feature detection, add SSC support
    
    Improve the VBIOS feature detection and use it to find whether the platform
    supports spread spectrum clocking.  Use the specified reference clock, but
    disable SSC if multiple heads are active, since it can cause problems in cloned
    configurations.
    
    Reviewed by Nanhai Zou.

diff --git a/src/i830.h b/src/i830.h
index 570db13..68690f7 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -554,6 +554,10 @@ typedef struct _I830Rec {
    OptionInfoPtr Options;
 
    Bool lvds_24_bit_mode;
+   Bool lvds_use_ssc;
+   int lvds_ssc_freq; /* in MHz */
+
+   Bool tv_present; /* TV connector present (from VBIOS) */
 
    Bool StolenOnly;
 
diff --git a/src/i830_bios.c b/src/i830_bios.c
index 57ee278..a8193fc 100644
--- a/src/i830_bios.c
+++ b/src/i830_bios.c
@@ -70,6 +70,32 @@ i830DumpBIOSToFile(ScrnInfoPtr pScrn, unsigned char *bios)
     fclose(f);
 }
 
+static void *
+find_section(struct bdb_header *bdb, int section_id)
+{
+	unsigned char *base = (unsigned char *)bdb;
+	int index = 0;
+	uint16_t total, current_size;
+	unsigned char current_id;
+
+	/* skip to first section */
+	index += bdb->header_size;
+	total = bdb->bdb_size;
+
+	/* walk the sections looking for section_id */
+	while (index < total) {
+		current_id = *(base + index);
+		index++;
+		current_size = *((uint16_t *)(base + index));
+		index += 2;
+		if (current_id == section_id)
+			return base + index;
+		index += current_size;
+	}
+
+	return NULL;
+}
+
 /**
  * Loads the Video BIOS and checks that the VBT exists.
  *
@@ -127,6 +153,70 @@ i830_bios_get (ScrnInfoPtr pScrn)
     return bios;
 }
 
+void
+i830_bios_get_ssc(ScrnInfoPtr pScrn)
+{
+    I830Ptr pI830 = I830PTR(pScrn);
+    struct vbt_header *vbt;
+    struct bdb_header *bdb;
+    struct bdb_general_features *bdb_features;
+    int vbt_off, bdb_off;
+    unsigned char *bios;
+
+    bios = i830_bios_get(pScrn);
+
+    if (bios == NULL)
+	return;
+
+    vbt_off = INTEL_BIOS_16(0x1a);
+    vbt = (struct vbt_header *)(bios + vbt_off);
+    bdb_off = vbt_off + vbt->bdb_offset;
+    bdb = (struct bdb_header *)(bios + bdb_off);
+
+    bdb_features = find_section(bdb, BDB_GENERAL_FEATURES);
+    if (!bdb_features)
+	return;
+
+    pI830->lvds_use_ssc = bdb_features->enable_ssc;
+    if (pI830->lvds_use_ssc) {
+	if (IS_I855(pI830))
+	    pI830->lvds_ssc_freq = bdb_features->ssc_freq ? 66 : 48;
+	else
+	    pI830->lvds_ssc_freq = bdb_features->ssc_freq ? 100 : 96;
+    }
+
+    xfree(bios);
+}
+
+void
+i830_bios_get_tv(ScrnInfoPtr pScrn)
+{
+    I830Ptr pI830 = I830PTR(pScrn);
+    struct vbt_header *vbt;
+    struct bdb_header *bdb;
+    struct bdb_general_features *bdb_features;
+    int vbt_off, bdb_off;
+    unsigned char *bios;
+
+    bios = i830_bios_get(pScrn);
+
+    if (bios == NULL)
+	return;
+
+    vbt_off = INTEL_BIOS_16(0x1a);
+    vbt = (struct vbt_header *)(bios + vbt_off);
+    bdb_off = vbt_off + vbt->bdb_offset;
+    bdb = (struct bdb_header *)(bios + bdb_off);
+
+    bdb_features = find_section(bdb, BDB_GENERAL_FEATURES);
+    if (!bdb_features)
+	return;
+
+    pI830->tv_present = bdb_features->int_tv_support;
+
+    xfree(bios);
+}
+
 /**
  * Returns the BIOS's fixed panel mode.
  *
diff --git a/src/i830_bios.h b/src/i830_bios.h
index 95230f5..c1ba50d 100644
--- a/src/i830_bios.h
+++ b/src/i830_bios.h
@@ -49,6 +49,97 @@ struct bdb_header {
     uint16_t bdb_size;			/**< in bytes */
 } __attribute__((packed));
 
+/*
+ * There are several types of BIOS data blocks (BDBs), each block has
+ * an ID and size in the first 3 bytes (ID in first, size in next 2).
+ * Known types are listed below.
+ */
+#define BDB_GENERAL_FEATURES	  1
+#define BDB_GENERAL_DEFINITIONS	  2
+#define BDB_OLD_TOGGLE_LIST	  3
+#define BDB_MODE_SUPPORT_LIST	  4
+#define BDB_GENERIC_MODE_TABLE	  5
+#define BDB_EXT_MMIO_REGS	  6
+#define BDB_SWF_IO		  7
+#define BDB_SWF_MMIO		  8
+#define BDB_DOT_CLOCK_TABLE	  9
+#define BDB_MODE_REMOVAL_TABLE	 10
+#define BDB_CHILD_DEVICE_TABLE	 11
+#define BDB_DRIVER_FEATURES	 12
+#define BDB_DRIVER_PERSISTENCE	 13
+#define BDB_EXT_TABLE_PTRS	 14
+#define BDB_DOT_CLOCK_OVERRIDE	 15
+#define BDB_DISPLAY_SELECT	 16
+/* 17 rsvd */
+#define BDB_DRIVER_ROTATION	 18
+#define BDB_DISPLAY_REMOVE	 19
+#define BDB_OEM_CUSTOM		 20
+#define BDB_EFP_LIST		 21 /* workarounds for VGA hsync/vsync */
+#define BDB_SDVO_LVDS_OPTIONS	 22
+#define BDB_SDVO_PANEL_DTDS	 23
+#define BDB_SDVO_LVDS_PNP_IDS	 24
+#define BDB_SDVO_LVDS_POWER_SEQ	 25
+#define BDB_TV_OPTIONS		 26
+#define BDB_LVDS_OPTIONS	 40
+#define BDB_LVDS_LFP_DATA_PTRS	 41
+#define BDB_LVDS_LFP_DATA	 42
+#define BDB_LVDS_BACKLIGHT	 43
+#define BDB_LVDS_POWER		 44
+#define BDB_SKIP		254 /* VBIOS private block, ignore */
+
+struct bdb_general_features {
+        /* bits 1 */
+	unsigned char panel_fitting:2;
+	unsigned char flexaim:1;
+	unsigned char msg_enable:1;
+	unsigned char clear_screen:3;
+	unsigned char color_flip:1;
+
+        /* bits 2 */
+	unsigned char download_ext_vbt:1;
+	unsigned char enable_ssc:1;
+	unsigned char ssc_freq:1;
+	unsigned char enable_lfp_on_override:1;
+	unsigned char disable_ssc_ddt:1;
+	unsigned char rsvd8:3; /* finish byte */
+
+        /* bits 3 */
+	unsigned char disable_smooth_vision:1;
+	unsigned char single_dvi:1;
+	unsigned char rsvd9:6; /* finish byte */
+
+        /* bits 4 */
+	unsigned char legacy_monitor_detect;
+
+        /* bits 5 */
+	unsigned char int_crt_support:1;
+	unsigned char int_tv_support:1;
+	unsigned char rsvd11:6; /* finish byte */
+} __attribute__((packed));
+
+struct bdb_general_definitions {
+	/* DDC GPIO */
+	unsigned char crt_ddc_gmbus_pin;
+
+	/* DPMS bits */
+	unsigned char dpms_acpi:1;
+	unsigned char skip_boot_crt_detect:1;
+	unsigned char dpms_aim:1;
+	unsigned char rsvd1:5; /* finish byte */
+
+	/* boot device bits */
+	unsigned char boot_display[2];
+	unsigned char child_dev_size;
+
+	/* device info */
+	unsigned char tv_or_lvds_info[33];
+	unsigned char dev1[33];
+	unsigned char dev2[33];
+	unsigned char dev3[33];
+	unsigned char dev4[33];
+	/* may be another device block here on some platforms */
+};
+
 #define LVDS_CAP_EDID			(1 << 6)
 #define LVDS_CAP_DITHER			(1 << 5)
 #define LVDS_CAP_PFIT_AUTO_RATIO	(1 << 4)
@@ -150,6 +241,8 @@ struct vch_bdb_22 {
 unsigned char *
 i830_bios_get (ScrnInfoPtr pScrn);
 
+void i830_bios_get_ssc(ScrnInfoPtr pScrn);
+void i830_bios_get_tv(ScrnInfoPtr pScrn);
 DisplayModePtr i830_bios_get_panel_mode(ScrnInfoPtr pScrn, Bool *wants_dither);
 
 unsigned char *
diff --git a/src/i830_display.c b/src/i830_display.c
index 306fed4..3967b69 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -1128,7 +1128,7 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode,
     int dsppos_reg = (plane == 0) ? DSPAPOS : DSPBPOS;
     int dspsize_reg = (plane == 0) ? DSPASIZE : DSPBSIZE;
     int pipestat_reg = (pipe == 0) ? PIPEASTAT : PIPEBSTAT;
-    int i;
+    int i, num_outputs = 0;
     int refclk;
     intel_clock_t clock;
     uint32_t dpll = 0, fp = 0, dspcntr, pipeconf, lvds_bits = 0;
@@ -1168,9 +1168,19 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode,
 	    is_crt = TRUE;
 	    break;
 	}
+
+	num_outputs++;
     }
 
-    if (IS_I9XX(pI830)) {
+    if (num_outputs > 1)
+	xf86DrvMsg(pScrn->scrnIndex, X_INFO, "clone detected, disabling SSC\n");
+
+    /* Don't use SSC when cloned */
+    if (pI830->lvds_use_ssc && num_outputs < 2) {
+	refclk = pI830->lvds_ssc_freq * 1000;
+	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+		   "using SSC reference clock of %d MHz\n", refclk / 1000);
+    } else if (IS_I9XX(pI830)) {
 	refclk = 96000;
     } else {
 	refclk = 48000;
@@ -1246,10 +1256,8 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode,
 /*	dpll |= PLL_REF_INPUT_TVCLKINBC; */
 	dpll |= 3;
     }
-#if 0
-    else if (is_lvds)
+    else if (is_lvds && pI830->lvds_use_ssc && num_outputs < 2)
 	dpll |= PLLB_REF_INPUT_SPREADSPECTRUMIN;
-#endif
     else
 	dpll |= PLL_REF_INPUT_DREFCLK;
 
diff --git a/src/i830_lvds.c b/src/i830_lvds.c
index d1bbb3a..c7f2434 100644
--- a/src/i830_lvds.c
+++ b/src/i830_lvds.c
@@ -1341,6 +1341,9 @@ i830_lvds_init(ScrnInfoPtr pScrn)
 	goto disable_exit;
     }
 
+    /* Update pI830 w/SSC info, if any */
+    i830_bios_get_ssc(pScrn);
+
  skip_panel_fixed_mode_setup:
 
     /* Blacklist machines with BIOSes that list an LVDS panel without actually
commit 7332132a79e5b5c208d43e93dfe0c8b12eb1728d
Author: Jesse Barnes <jbarnes at jbarnes-t61.(none)>
Date:   Mon Jul 7 10:48:56 2008 -0700

    Improve FBC size checking
    
    In hindsight, this is obvious, since nowhere do we tell the FBC unit how much
    memory it has available.  We need to make sure the compressed buffer is big
    enough to handle the uncompresed buffer, both in terms of vertical size and
    total framebuffer size, or the compressor could overwrite the memory
    immediately following the compressed buffer.

diff --git a/src/i830_display.c b/src/i830_display.c
index df3a6be..306fed4 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -693,6 +693,7 @@ i830_use_fb_compression(xf86CrtcPtr crtc)
     xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
     I830Ptr pI830 = I830PTR(pScrn);
     I830CrtcPrivatePtr	intel_crtc = crtc->driver_private;
+    unsigned long uncompressed_size;
     int plane = (intel_crtc->plane == 0 ? FBC_CTL_PLANEA : FBC_CTL_PLANEB);
     int i, count = 0;
 
@@ -724,6 +725,19 @@ i830_use_fb_compression(xf86CrtcPtr crtc)
 	  pScrn->bitsPerPixel == 32)) /* mode_set dtrt if fbc is in use */
 	return FALSE;
 
+    /* Can't cache more lines than we can track */
+    if (crtc->mode.VDisplay > FBC_LL_SIZE)
+	return FALSE;
+
+    /*
+     * Make sure the compressor doesn't go past the end of our compressed
+     * buffer if the uncompressed size is large.
+     */
+    uncompressed_size = crtc->mode.HDisplay * crtc->mode.VDisplay *
+	pI830->cpp;
+    if (pI830->compressed_front_buffer->size < uncompressed_size)
+	return FALSE;
+
     /*
      * No checks for pixel multiply, incl. horizontal, or interlaced modes
      * since they're currently unused.
commit f2ec3fd8f2c63b1bc0745802dcf737eda4bb42b6
Author: Stefan Dirsch <sndirsch at suse.de>
Date:   Thu Jul 3 23:12:13 2008 +0200

    Add pipea force enable quirk for another 855GM machine.
    
    Fixes Novell Bug #406123, thanks Christoph.

diff --git a/src/i830_quirks.c b/src/i830_quirks.c
index e81b27c..5eb01be 100644
--- a/src/i830_quirks.c
+++ b/src/i830_quirks.c
@@ -286,6 +286,8 @@ static i830_quirk i830_quirk_list[] = {
     { PCI_CHIP_I915_GM, 0x1179, 0x0001, quirk_pipea_force },
     /* Intel 855GM hardware (See LP: #216490) */
     { PCI_CHIP_I855_GM, 0x1028, 0x00c8, quirk_pipea_force },
+    /* Intel 855GM hardware (See Novell Bugzilla #406123) */
+    { PCI_CHIP_I855_GM, 0x10cf, 0x1215, quirk_pipea_force },
 
     /* ThinkPad X40 needs pipe A force quirk */
     { PCI_CHIP_I855_GM, 0x1014, 0x0557, quirk_pipea_force },
commit a34a4e3f6420e2b06bbdaa124fe0ccb1bc6a0bd9
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Thu Jul 3 01:03:14 2008 +0800

    Fix official name for GM45 chipset

diff --git a/src/common.h b/src/common.h
index b67b20b..57db6cb 100644
--- a/src/common.h
+++ b/src/common.h
@@ -303,9 +303,9 @@ extern int I810_DEBUG;
 #define PCI_CHIP_Q33_G_BRIDGE 	0x29D0
 #endif
 
-#ifndef PCI_CHIP_IGD_GM
-#define PCI_CHIP_IGD_GM		0x2A42
-#define PCI_CHIP_IGD_GM_BRIDGE  0x2A40
+#ifndef PCI_CHIP_GM45_GM
+#define PCI_CHIP_GM45_GM	0x2A42
+#define PCI_CHIP_GM45_BRIDGE    0x2A40
 #endif
 
 #ifndef PCI_CHIP_IGD_E_G
@@ -354,26 +354,26 @@ extern int I810_DEBUG;
 #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_IGD_GM(pI810) (DEVICE_ID(pI810->PciInfo) == PCI_CHIP_IGD_GM)
+#define IS_GM45(pI810) (DEVICE_ID(pI810->PciInfo) == PCI_CHIP_GM45_GM)
 #define IS_G4X(pI810) (DEVICE_ID(pI810->PciInfo) == PCI_CHIP_IGD_E_G || DEVICE_ID(pI810->PciInfo) == PCI_CHIP_G45_G || DEVICE_ID(pI810->PciInfo) == PCI_CHIP_Q45_G)
 #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_G35_G || 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 || IS_IGD_GM(pI810) || IS_G4X(pI810))
+#define IS_I965G(pI810) (DEVICE_ID(pI810->PciInfo) == PCI_CHIP_I965_G || DEVICE_ID(pI810->PciInfo) == PCI_CHIP_G35_G || 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 || IS_GM45(pI810) || IS_G4X(pI810))
 #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_I915(pI810) (IS_I915G(pI810) || IS_I915GM(pI810) || IS_I945G(pI810) || IS_I945GM(pI810) || IS_G33CLASS(pI810))
 
-#define IS_MOBILE(pI810) (IS_I830(pI810) || IS_I85X(pI810) || IS_I915GM(pI810) || IS_I945GM(pI810) || IS_I965GM(pI810) || IS_IGD_GM(pI810))
+#define IS_MOBILE(pI810) (IS_I830(pI810) || IS_I85X(pI810) || IS_I915GM(pI810) || IS_I945GM(pI810) || IS_I965GM(pI810) || IS_GM45(pI810))
 /* mark chipsets for using gfx VM offset for overlay */
 #define OVERLAY_NOPHYSICAL(pI810) (IS_G33CLASS(pI810) || IS_I965G(pI810))
 /* mark chipsets without overlay hw */
-#define OVERLAY_NOEXIST(pI810) (IS_IGD_GM(pI810) || IS_G4X(pI810))
+#define OVERLAY_NOEXIST(pI810) (IS_GM45(pI810) || IS_G4X(pI810))
 /* chipsets require graphics mem for hardware status page */
-#define HWS_NEED_GFX(pI810) (IS_G33CLASS(pI810) || IS_IGD_GM(pI810) || IS_G4X(pI810))
+#define HWS_NEED_GFX(pI810) (IS_G33CLASS(pI810) || IS_GM45(pI810) || IS_G4X(pI810))
 /* chipsets require status page in non stolen memory */
-#define HWS_NEED_NONSTOLEN(pI810) (IS_IGD_GM(pI810) || IS_G4X(pI810))
-#define SUPPORTS_INTEGRATED_HDMI(pI810) (IS_IGD_GM(pI810) || IS_G4X(pI810))
+#define HWS_NEED_NONSTOLEN(pI810) (IS_GM45(pI810) || IS_G4X(pI810))
+#define SUPPORTS_INTEGRATED_HDMI(pI810) (IS_GM45(pI810) || IS_G4X(pI810))
 
 #define GTT_PAGE_SIZE			KB(4)
 #define ROUND_TO(x, y)			(((x) + (y) - 1) / (y) * (y))
diff --git a/src/i810_driver.c b/src/i810_driver.c
index de4f3cb..8540646 100644
--- a/src/i810_driver.c
+++ b/src/i810_driver.c
@@ -152,7 +152,7 @@ static const struct pci_id_match intel_device_match[] = {
    INTEL_DEVICE_MATCH (PCI_CHIP_G33_G, 0 ),
    INTEL_DEVICE_MATCH (PCI_CHIP_Q35_G, 0 ),
    INTEL_DEVICE_MATCH (PCI_CHIP_Q33_G, 0 ),
-   INTEL_DEVICE_MATCH (PCI_CHIP_IGD_GM, 0 ),
+   INTEL_DEVICE_MATCH (PCI_CHIP_GM45_GM, 0 ),
    INTEL_DEVICE_MATCH (PCI_CHIP_IGD_E_G, 0 ),
    INTEL_DEVICE_MATCH (PCI_CHIP_G45_G, 0 ),
    INTEL_DEVICE_MATCH (PCI_CHIP_Q45_G, 0 ),
@@ -208,7 +208,7 @@ static SymTabRec I810Chipsets[] = {
    {PCI_CHIP_G33_G,		"G33"},
    {PCI_CHIP_Q35_G,		"Q35"},
    {PCI_CHIP_Q33_G,		"Q33"},
-   {PCI_CHIP_IGD_GM,		"Intel Integrated Graphics Device"},
+   {PCI_CHIP_GM45_GM,		"Mobile Intel® GM45 Express Chipset"},
    {PCI_CHIP_IGD_E_G,		"Intel Integrated Graphics Device"},
    {PCI_CHIP_G45_G,		"G45/G43"},
    {PCI_CHIP_Q45_G,		"Q45/Q43"},
@@ -241,7 +241,7 @@ static PciChipsets I810PciChipsets[] = {
    {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},
-   {PCI_CHIP_IGD_GM,		PCI_CHIP_IGD_GM,	RES_SHARED_VGA},
+   {PCI_CHIP_GM45_GM,		PCI_CHIP_GM45_GM,	RES_SHARED_VGA},
    {PCI_CHIP_IGD_E_G,		PCI_CHIP_IGD_E_G,	RES_SHARED_VGA},
    {PCI_CHIP_G45_G,		PCI_CHIP_G45_G,		RES_SHARED_VGA},
    {PCI_CHIP_Q45_G,		PCI_CHIP_Q45_G,		RES_SHARED_VGA},
@@ -808,7 +808,7 @@ I810Probe(DriverPtr drv, int flags)
  	    case PCI_CHIP_G33_G:
  	    case PCI_CHIP_Q35_G:
  	    case PCI_CHIP_Q33_G:
- 	    case PCI_CHIP_IGD_GM:
+ 	    case PCI_CHIP_GM45_GM:
 	    case PCI_CHIP_IGD_E_G:
 	    case PCI_CHIP_G45_G:
 	    case PCI_CHIP_Q45_G:
diff --git a/src/i830_display.c b/src/i830_display.c
index abe9875..df3a6be 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -668,7 +668,7 @@ i830_enable_fb_compression(xf86CrtcPtr crtc)
     ScrnInfoPtr pScrn = crtc->scrn;
     I830Ptr pI830 = I830PTR(pScrn);
 
-    if (IS_IGD_GM(pI830))
+    if (IS_GM45(pI830))
 	return i830_enable_fb_compression2(crtc);
 
     i830_enable_fb_compression_8xx(crtc);
@@ -680,7 +680,7 @@ i830_disable_fb_compression(xf86CrtcPtr crtc)
     ScrnInfoPtr pScrn = crtc->scrn;
     I830Ptr pI830 = I830PTR(pScrn);
 
-    if (IS_IGD_GM(pI830))
+    if (IS_GM45(pI830))
 	return i830_disable_fb_compression2(crtc);
 
     i830_disable_fb_compression_8xx(crtc);
@@ -1209,7 +1209,7 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode,
 	    dpll |= DPLLB_LVDS_P2_CLOCK_DIV_14;
 	    break;
 	}
-	if (IS_I965G(pI830) && !IS_IGD_GM(pI830))
+	if (IS_I965G(pI830) && !IS_GM45(pI830))
 	    dpll |= (6 << PLL_LOAD_PULSE_PHASE_SHIFT);
     } else {
 	if (is_lvds) {
diff --git a/src/i830_driver.c b/src/i830_driver.c
index dff7d51..0a49d3a 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -251,7 +251,7 @@ static SymTabRec I830Chipsets[] = {
    {PCI_CHIP_G33_G,		"G33"},
    {PCI_CHIP_Q35_G,		"Q35"},
    {PCI_CHIP_Q33_G,		"Q33"},
-   {PCI_CHIP_IGD_GM,		"Intel Integrated Graphics Device"},
+   {PCI_CHIP_GM45_GM,		"Mobile Intel® GM45 Express Chipset"},
    {PCI_CHIP_IGD_E_G,		"Intel Integrated Graphics Device"},
    {PCI_CHIP_G45_G,		"G45/G43"},
    {PCI_CHIP_Q45_G,		"Q45/Q43"},
@@ -278,7 +278,7 @@ static PciChipsets I830PciChipsets[] = {
    {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},
-   {PCI_CHIP_IGD_GM,		PCI_CHIP_IGD_GM,	RES_SHARED_VGA},
+   {PCI_CHIP_GM45_GM,		PCI_CHIP_GM45_GM,	RES_SHARED_VGA},
    {PCI_CHIP_IGD_E_G,		PCI_CHIP_IGD_E_G,	RES_SHARED_VGA},
    {PCI_CHIP_G45_G,		PCI_CHIP_G45_G,		RES_SHARED_VGA},
    {PCI_CHIP_Q45_G,		PCI_CHIP_Q45_G,		RES_SHARED_VGA},
@@ -653,7 +653,7 @@ I830MapMMIO(ScrnInfoPtr pScrn)
 
       if (IS_I965G(pI830)) 
       {
-	 if (IS_IGD_GM(pI830) || IS_G4X(pI830)) {
+	 if (IS_GM45(pI830) || IS_G4X(pI830)) {
 	     gttaddr = pI830->MMIOAddr + MB(2);
 	     pI830->GTTMapSize = MB(2);
 	 } else {
@@ -973,7 +973,7 @@ i830_init_clock_gating(ScrnInfoPtr pScrn)
 
     /* Disable clock gating reported to work incorrectly according to the specs.
      */
-    if (IS_IGD_GM(pI830)) {
+    if (IS_GM45(pI830)) {
 	OUTREG(RENCLK_GATE_D1, 0);
 	OUTREG(RENCLK_GATE_D2, 0);
 	OUTREG(RAMCLK_GATE_D, 0);
@@ -1218,7 +1218,9 @@ i830_detect_chipset(ScrnInfoPtr pScrn)
     case PCI_CHIP_Q33_G:
 	chipname = "Q33";
 	break;
-    case PCI_CHIP_IGD_GM:
+    case PCI_CHIP_GM45_GM:
+	chipname = "Mobile Intel® GM45 Express Chipset";
+	break;
     case PCI_CHIP_IGD_E_G:
 	chipname = "Intel Integrated Graphics Device";
 	break;
@@ -1985,7 +1987,7 @@ i830_set_dsparb(ScrnInfoPtr pScrn)
     * FIFO RAM entries equally between planes A and B.
     */
    if (IS_I9XX(pI830)) {
-       if (IS_I965GM(pI830) || IS_IGD_GM(pI830))
+       if (IS_I965GM(pI830) || IS_GM45(pI830))
 	   OUTREG(DSPARB, (127 << DSPARB_CSTART_SHIFT) |
 		  (64 << DSPARB_BSTART_SHIFT));
        else
@@ -2143,7 +2145,7 @@ SaveHWState(ScrnInfoPtr pScrn)
       pI830->saveRAMCLK_GATE_D = INREG(RAMCLK_GATE_D);
    }
 
-   if (IS_I965GM(pI830) || IS_IGD_GM(pI830))
+   if (IS_I965GM(pI830) || IS_GM45(pI830))
       pI830->savePWRCTXA = INREG(PWRCTXA);
 
    if (IS_MOBILE(pI830) && !IS_I830(pI830))
@@ -2213,7 +2215,7 @@ RestoreHWState(ScrnInfoPtr pScrn)
       OUTREG(RAMCLK_GATE_D, pI830->saveRAMCLK_GATE_D);
    }
 
-   if (IS_I965GM(pI830) || IS_IGD_GM(pI830))
+   if (IS_I965GM(pI830) || IS_GM45(pI830))
       OUTREG(PWRCTXA, pI830->savePWRCTXA);
 
    /*
@@ -2623,7 +2625,7 @@ i830_try_memory_allocation(ScrnInfoPtr pScrn)
     if (!i830_allocate_2d_memory(pScrn))
 	goto failed;
 
-    if (IS_I965GM(pI830) || IS_IGD_GM(pI830))
+    if (IS_I965GM(pI830) || IS_GM45(pI830))
 	if (!i830_allocate_pwrctx(pScrn))
 	    goto failed;
 
@@ -3036,7 +3038,7 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
     *       alone in that case.
     * Also make sure the DRM can handle the swap.
     */
-   if (I830LVDSPresent(pScrn) && !IS_I965GM(pI830) && !IS_IGD_GM(pI830) &&
+   if (I830LVDSPresent(pScrn) && !IS_I965GM(pI830) && !IS_GM45(pI830) &&
        (!pI830->directRenderingEnabled ||
 	(pI830->directRenderingEnabled && pI830->drmMinor >= 10))) {
        xf86DrvMsg(pScrn->scrnIndex, X_INFO, "adjusting plane->pipe mappings "
diff --git a/src/i830_lvds.c b/src/i830_lvds.c
index b5e0c45..d1bbb3a 100644
--- a/src/i830_lvds.c
+++ b/src/i830_lvds.c
@@ -134,7 +134,7 @@ i830_set_lvds_backlight_method(xf86OutputPtr output)
 
     if (i830_kernel_backlight_available(output)) {
 	    method = BCM_KERNEL;
-    } else if (IS_I965GM(pI830) || IS_IGD_GM(pI830)) {
+    } else if (IS_I965GM(pI830) || IS_GM45(pI830)) {
 	blc_pwm_ctl2 = INREG(BLC_PWM_CTL2);
 	if (blc_pwm_ctl2 & BLM_LEGACY_MODE2)
 	    method = BCM_COMBO;
@@ -182,7 +182,7 @@ i830_lvds_get_backlight_max_native(xf86OutputPtr output)
     uint32_t pwm_ctl = INREG(BLC_PWM_CTL);
     int val;
 
-    if (IS_I965GM(pI830) || IS_IGD_GM(pI830)) {
+    if (IS_I965GM(pI830) || IS_GM45(pI830)) {
 	val = ((pwm_ctl & BACKLIGHT_MODULATION_FREQ_MASK2) >>
 	       BACKLIGHT_MODULATION_FREQ_SHIFT2);
     } else {
@@ -453,7 +453,7 @@ i830_lvds_save (xf86OutputPtr output)
     ScrnInfoPtr		    pScrn = output->scrn;
     I830Ptr		    pI830 = I830PTR(pScrn);
 
-    if (IS_I965GM(pI830) || IS_IGD_GM(pI830))
+    if (IS_I965GM(pI830) || IS_GM45(pI830))
 	pI830->saveBLC_PWM_CTL2 = INREG(BLC_PWM_CTL2);
     pI830->savePP_ON = INREG(LVDSPP_ON);
     pI830->savePP_OFF = INREG(LVDSPP_OFF);
@@ -470,7 +470,7 @@ i830_lvds_restore(xf86OutputPtr output)
     ScrnInfoPtr	pScrn = output->scrn;
     I830Ptr	pI830 = I830PTR(pScrn);
 
-    if (IS_I965GM(pI830) || IS_IGD_GM(pI830))
+    if (IS_I965GM(pI830) || IS_GM45(pI830))
 	OUTREG(BLC_PWM_CTL2, pI830->saveBLC_PWM_CTL2);
     OUTREG(BLC_PWM_CTL, pI830->saveBLC_PWM_CTL);
     OUTREG(LVDSPP_ON, pI830->savePP_ON);
diff --git a/src/i830_memory.c b/src/i830_memory.c
index 6e7a838..0a2faeb 100644
--- a/src/i830_memory.c
+++ b/src/i830_memory.c
@@ -1282,7 +1282,7 @@ static void i830_setup_fb_compression(ScrnInfoPtr pScrn)
 	goto out;
     }
 
-    if (IS_IGD_GM(pI830)) {
+    if (IS_GM45(pI830)) {
 	/* Update i830_display.c too if compression ratio changes */
 	compressed_size = fb_height * (pScrn->displayWidth / 4);
     } else {
@@ -1309,7 +1309,7 @@ static void i830_setup_fb_compression(ScrnInfoPtr pScrn)
 	goto out;
     }
 
-    if (!IS_IGD_GM(pI830)) {
+    if (!IS_GM45(pI830)) {
 	pI830->compressed_ll_buffer =
 	    i830_allocate_memory(pScrn, "compressed ll buffer",
 				 FBC_LL_SIZE + FBC_LL_PAD, KB(4),
diff --git a/src/i830_quirks.c b/src/i830_quirks.c
index f7659f0..e81b27c 100644
--- a/src/i830_quirks.c
+++ b/src/i830_quirks.c
@@ -266,9 +266,9 @@ static i830_quirk i830_quirk_list[] = {
     { PCI_CHIP_I965_GM, 0x144d, 0xc510, quirk_ignore_tv },
 
     /* HP Compaq 6730s has no TV output */
-    { PCI_CHIP_IGD_GM, 0x103c, 0x30e8, quirk_ignore_tv },
+    { PCI_CHIP_GM45_GM, 0x103c, 0x30e8, quirk_ignore_tv },
     /* HP Pavilion ze4944ea needs pipe A force quirk (See LP: #242389) */
-    { PCI_CHIP_IGD_GM, 0x103c, 0x3084, quirk_pipea_force },
+    { PCI_CHIP_GM45_GM, 0x103c, 0x3084, quirk_pipea_force },
 
     /* Thinkpad R31 needs pipe A force quirk */
     { PCI_CHIP_I830_M, 0x1014, 0x0505, quirk_pipea_force },
diff --git a/src/i965_render.c b/src/i965_render.c
index a3c7f49..a13aec2 100644
--- a/src/i965_render.c
+++ b/src/i965_render.c
@@ -1035,7 +1035,7 @@ i965_prepare_composite(int op, PicturePtr pSrcPicture,
         BEGIN_BATCH(12);
 
         /* Match Mesa driver setup */
-	if (IS_IGD_GM(pI830) || IS_G4X(pI830))
+	if (IS_GM45(pI830) || IS_G4X(pI830))
 	    OUT_BATCH(NEW_PIPELINE_SELECT | PIPELINE_SELECT_3D);
 	else
 	    OUT_BATCH(BRW_PIPELINE_SELECT | PIPELINE_SELECT_3D);
diff --git a/src/i965_video.c b/src/i965_video.c
index 4572e13..4c79259 100644
--- a/src/i965_video.c
+++ b/src/i965_video.c
@@ -584,7 +584,7 @@ I965DisplayVideoTextured(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv, int id,
     {
 	BEGIN_BATCH(12);
 	/* Match Mesa driver setup */
-	if (IS_IGD_GM(pI830) || IS_G4X(pI830))
+	if (IS_GM45(pI830) || IS_G4X(pI830))
 	    OUT_BATCH(NEW_PIPELINE_SELECT | PIPELINE_SELECT_3D);
 	else
 	    OUT_BATCH(BRW_PIPELINE_SELECT | PIPELINE_SELECT_3D);
commit 6506ac7aa008436158db4f4196802cab462f3446
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Wed Jul 2 11:12:54 2008 +0800

    Give asus and eeepc backlight method higher priority
    
    On #16418, Evgeniy Manachkin <sfstudio at mail.ru> reported that
    last asus and eeepc backlight patch is wrong, as acpi_video0 method
    will take priority and doesn't work.

diff --git a/src/i830_lvds.c b/src/i830_lvds.c
index af82ee7..b5e0c45 100644
--- a/src/i830_lvds.c
+++ b/src/i830_lvds.c
@@ -83,12 +83,12 @@ struct i830_lvds_priv {
  * List of available kernel interfaces in priority order
  */
 static char *backlight_interfaces[] = {
+    "asus-laptop",
+    "eeepc",
     "thinkpad_screen",
     "acpi_video1",
     "acpi_video0",
     "fujitsu-laptop",
-    "asus-laptop",
-    "eeepc",
     NULL,
 };
 
commit 55678c64bc6e3ed613ea6db14c105c18a0cf28ce
Author: Dave Airlie <airlied at linux.ie>
Date:   Tue Jul 1 18:51:18 2008 +1000

    intel: fix drm check.
    
    The -mm check is broken now that 2.3.1 is out.. make it 2.4.0, to be fixed
    with GEM etc.

diff --git a/configure.ac b/configure.ac
index af87299..2dabd4f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -201,7 +201,7 @@ if test "$DRI" = yes; then
         PKG_CHECK_MODULES(DRI, [libdrm xf86driproto glproto])
         AC_DEFINE(XF86DRI,1,[Enable DRI driver support])
         AC_DEFINE(XF86DRI_DEVEL,1,[Enable developmental DRI driver support])
-	PKG_CHECK_MODULES(DRI_MM, [libdrm >= 2.3.1],[DRI_MM=yes], [DRI_MM=no])
+	PKG_CHECK_MODULES(DRI_MM, [libdrm >= 2.4.0],[DRI_MM=yes], [DRI_MM=no])
 	if test "x$DRI_MM" = xyes; then
 		AC_DEFINE(XF86DRI_MM,1,[Extended DRI memory management])
 	fi
commit 0597d94001afe0a9a34104285ce4dffc75b68071
Author: Roland Test-tools Bär <roland at verifysoft.de>
Date:   Mon Jun 30 10:32:42 2008 -0700

    i810: Remove an effectively unused variable (only used in an incorrect free())
    
    Bug #15401.

diff --git a/src/xvmc/I810XvMC.c b/src/xvmc/I810XvMC.c
index 03be251..ce5395a 100644
--- a/src/xvmc/I810XvMC.c
+++ b/src/xvmc/I810XvMC.c
@@ -130,7 +130,6 @@ Status XvMCCreateContext(Display *display, XvPortID port,
 			 int surface_type_id, int width, int height, int flags,
 			 XvMCContext *context) {  
   i810XvMCContext *pI810XvMC;
-  char busIdString[10];
   int priv_count;
   uint *priv_data;
   uint magic;
@@ -217,7 +216,6 @@ Status XvMCCreateContext(Display *display, XvPortID port,
   /* Open DRI Device */
   if((pI810XvMC->fd = drmOpen("i810",NULL)) < 0) {
     printf("DRM Device for i810 could not be opened.\n");
-    free(busIdString);
     free(pI810XvMC);
     return BadAccess;
   } /* !pI810XvMC->fd */
commit 37661d916e8384f537d5ed8cbec66a93795c6a05
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Fri Jun 27 11:21:59 2008 +0800

    Fix SDVOC typo

diff --git a/src/i830_driver.c b/src/i830_driver.c
index 28505c8..dff7d51 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -931,7 +931,7 @@ I830SetupOutputs(ScrnInfoPtr pScrn)
 	    i830_hdmi_init(pScrn, SDVOB);
       }
 
-      if (INREG(SDVOB) & SDVO_DETECTED) {
+      if (INREG(SDVOC) & SDVO_DETECTED) {
 	 Bool found = i830_sdvo_init(pScrn, SDVOC);
 
 	 if (!found && SUPPORTS_INTEGRATED_HDMI(pI830))
commit 7834a3b118ae4e034f064257762d5c25ada5fe52
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Fri Jun 27 09:54:35 2008 +0800

    xvmc: fix motion_type dump for frame/field picture

diff --git a/src/xvmc/intel_xvmc_dump.c b/src/xvmc/intel_xvmc_dump.c
index 12fc52a..419bd0d 100644
--- a/src/xvmc/intel_xvmc_dump.c
+++ b/src/xvmc/intel_xvmc_dump.c
@@ -116,18 +116,25 @@ void intel_xvmc_dump_render(XvMCContext *context, unsigned int picture_structure
 	    fprintf(fp, "intra ");
 	fprintf(fp, ")  ");
 	fprintf(fp, "mc type ");
-	if (mb->motion_type & XVMC_PREDICTION_FIELD)
-	    fprintf(fp, "(field)  ");
-	else if (mb->motion_type & XVMC_PREDICTION_FRAME)
-	    fprintf(fp, "(frame)  ");
-	else if (mb->motion_type & XVMC_PREDICTION_DUAL_PRIME)
-	    fprintf(fp, "(dual-prime)  ");
-	else if (mb->motion_type & XVMC_PREDICTION_16x8)
-	    fprintf(fp, "(16x8)  ");
-	else if (mb->motion_type & XVMC_PREDICTION_4MV)
-	    fprintf(fp, "(4MV)  ");
-	else
-	    fprintf(fp, "(none)  ");
+	if (picture_structure == XVMC_FRAME_PICTURE) {
+	    if (mb->motion_type & XVMC_PREDICTION_FIELD)
+		fprintf(fp, "(field)  ");
+	    else if (mb->motion_type & XVMC_PREDICTION_FRAME)
+		fprintf(fp, "(frame)  ");
+	    else if (mb->motion_type & XVMC_PREDICTION_DUAL_PRIME)
+		fprintf(fp, "(dual-prime)  ");
+	    else
+		fprintf(fp, "(unknown %d)  ", mb->motion_type);
+	} else { /* field */
+	    if (mb->motion_type & XVMC_PREDICTION_FIELD)
+		fprintf(fp, "(field)  ");
+	    else if (mb->motion_type & XVMC_PREDICTION_DUAL_PRIME)
+		fprintf(fp, "(dual-prime)  ");
+	    else if (mb->motion_type & XVMC_PREDICTION_16x8)
+		fprintf(fp, "(16x8)  ");
+	    else
+		fprintf(fp, "(unknown %d)  ", mb->motion_type);
+	}
 
 	if (mb->dct_type == XVMC_DCT_TYPE_FRAME)
 	    fprintf(fp, "dct type (frame)  ");
commit 989ec9e8a69f909cb64f17e4465982613b4b054d
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Fri Jun 27 09:39:02 2008 +0800

    xvmc: Don't copy on xvmc surface in PutImage
    
    As xvmc rendering result has already been in fb, we shouldn't
    do extra copy on it. Although special care is required for i915
    xvmc surface pitch alignment, which must be at least 1KB aligned.
    So video display function should take it into acount instead of
    always setting Y pitch to be double of U/V pitch.

diff --git a/src/common.h b/src/common.h
index 1765bb5..b67b20b 100644
--- a/src/common.h
+++ b/src/common.h
@@ -362,6 +362,7 @@ extern int I810_DEBUG;
  			    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_I915(pI810) (IS_I915G(pI810) || IS_I915GM(pI810) || IS_I945G(pI810) || IS_I945GM(pI810) || IS_G33CLASS(pI810))
 
 #define IS_MOBILE(pI810) (IS_I830(pI810) || IS_I85X(pI810) || IS_I915GM(pI810) || IS_I945GM(pI810) || IS_I965GM(pI810) || IS_IGD_GM(pI810))
 /* mark chipsets for using gfx VM offset for overlay */
diff --git a/src/i830.h b/src/i830.h
index 00a5059..570db13 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -417,7 +417,6 @@ typedef struct _I830Rec {
 #ifdef INTEL_XVMC
    /* For XvMC */
    Bool XvMCEnabled;
-   Bool IsXvMCSurface;
 #endif
 
    XF86ModReqInfo shadowReq; /* to test for later libshadow */
diff --git a/src/i830_hwmc.c b/src/i830_hwmc.c
index 22fb69e..787d93d 100644
--- a/src/i830_hwmc.c
+++ b/src/i830_hwmc.c
@@ -56,7 +56,7 @@ Bool intel_xvmc_probe(ScrnInfoPtr pScrn)
 	return FALSE;
 
     if (IS_I9XX(pI830)) {
-	if (!IS_I965G(pI830))
+	if (IS_I915(pI830))
 	    ret = intel_xvmc_set_driver(&i915_xvmc_driver);
 	/*
 	else
diff --git a/src/i830_video.c b/src/i830_video.c
index 7b81b04..486f670 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -2210,7 +2210,8 @@ I830PutImage(ScrnInfoPtr pScrn,
     I830OverlayRegPtr overlay;
     PixmapPtr pPixmap;
     INT32 x1, x2, y1, y2;
-    int srcPitch, srcPitch2 = 0, dstPitch, destId;
+    int srcPitch = 0, srcPitch2 = 0, dstPitch, destId;
+    int dstPitch2 = 0;
     int top, left, npixels, nlines, size;
     BoxRec dstBox;
     int pitchAlignMask;
@@ -2285,13 +2286,11 @@ I830PutImage(ScrnInfoPtr pScrn,
     case FOURCC_I420:
 	srcPitch = (width + 0x3) & ~0x3;
 	srcPitch2 = ((width >> 1) + 0x3) & ~0x3;
+	break;
 #ifdef INTEL_XVMC
-        if (pI830->IsXvMCSurface) {
-            srcPitch = (width + 0x3ff) & ~0x3ff;
-            srcPitch2 = ((width >> 1) + 0x3ff) & ~0x3ff;
-        }
-#endif
+    case FOURCC_XVMC:
 	break;
+#endif
     case FOURCC_UYVY:
     case FOURCC_YUY2:
     default:
@@ -2304,6 +2303,11 @@ I830PutImage(ScrnInfoPtr pScrn,
      */
     if (pPriv->textured) {
 	pitchAlignMask = 3;
+#ifdef INTEL_XVMC
+	/* for i915 xvmc, hw requires at least 1kb aligned surface */
+	if ((id == FOURCC_XVMC) && IS_I915(pI830))
+	    pitchAlignMask = 0x3ff;
+#endif
     } else {
 	if (IS_I965G(pI830))
 	    pitchAlignMask = 255;
@@ -2317,9 +2321,6 @@ I830PutImage(ScrnInfoPtr pScrn,
     switch (destId) {
     case FOURCC_YV12:
     case FOURCC_I420:
-#ifdef INTEL_XVMC
-    case FOURCC_XVMC:
-#endif
 	if (pPriv->rotation & (RR_Rotate_90 | RR_Rotate_270)) {
 	    dstPitch = ((height / 2) + pitchAlignMask) & ~pitchAlignMask;
 	    size = dstPitch * width * 3;
@@ -2339,7 +2340,14 @@ I830PutImage(ScrnInfoPtr pScrn,
 	    size = dstPitch * height;
 	}
 	break;
-    default:  
+#ifdef INTEL_XVMC
+    case FOURCC_XVMC:
+	dstPitch = ((width / 2) + pitchAlignMask ) & ~pitchAlignMask;
+	dstPitch2 = (width + pitchAlignMask ) & ~pitchAlignMask;
+	size = 0;
+	break;
+#endif
+    default:
 	dstPitch = 0;
 	size = 0;
 	break;
@@ -2384,24 +2392,35 @@ I830PutImage(ScrnInfoPtr pScrn,
     (pPriv->doubleBuffer ? size * 2 : size);
 
     /* fixup pointers */
-    pPriv->YBuf0offset = pPriv->buf->offset;
-    if (pPriv->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);
-	}
+#ifdef INTEL_XVMC
+    if (id == FOURCC_XVMC && IS_I915(pI830)) {
+	pPriv->YBuf0offset = (uint32_t)buf;
+	pPriv->VBuf0offset = pPriv->YBuf0offset + (dstPitch2 * height);
+	pPriv->UBuf0offset = pPriv->VBuf0offset + (dstPitch * height / 2);
+	destId = FOURCC_YV12;
     } 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);
+#endif
+	pPriv->YBuf0offset = pPriv->buf->offset;
+	if (pPriv->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);
+	    }
 	}
+#ifdef INTEL_XVMC
     }
+#endif
 
     /* Pick the idle buffer */
     if (!pPriv->textured && *pI830->overlayOn && pPriv->doubleBuffer)
@@ -2473,7 +2492,7 @@ I830PutImage(ScrnInfoPtr pScrn,
 				 src_w, src_h, drw_w, drw_h, pPixmap);
     } else {
 	I915DisplayVideoTextured(pScrn, pPriv, destId, clipBoxes, width, height,
-				 dstPitch, x1, y1, x2, y2,
+				 dstPitch, dstPitch2, x1, y1, x2, y2,
 				 src_w, src_h, drw_w, drw_h, pPixmap);
     }
     if (pPriv->textured) {
diff --git a/src/i830_video.h b/src/i830_video.h
index 52e6b4f..91f767f 100644
--- a/src/i830_video.h
+++ b/src/i830_video.h
@@ -78,7 +78,7 @@ typedef struct {
 
 void I915DisplayVideoTextured(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv,
 			      int id, RegionPtr dstRegion, short width,
-			      short height, int video_pitch,
+			      short height, int video_pitch, int video_pitch2,
 			      int x1, int y1, int x2, int y2,
 			      short src_w, short src_h,
 			      short drw_w, short drw_h,
diff --git a/src/i915_hwmc.c b/src/i915_hwmc.c
index c345175..659638e 100644
--- a/src/i915_hwmc.c
+++ b/src/i915_hwmc.c
@@ -790,7 +790,6 @@ static int i915_xvmc_put_image(ScrnInfoPtr pScrn,
 	short height, Bool sync, RegionPtr clipBoxes, pointer data,
 	DrawablePtr pDraw)
 {
-    I830Ptr pI830 = I830PTR(pScrn);
     I915XvMCPtr pXvMC = (I915XvMCPtr)xvmc_driver->devPrivate;
     struct intel_xvmc_command *xvmc_cmd = (struct intel_xvmc_command *)buf;
     int ret;
@@ -806,10 +805,8 @@ static int i915_xvmc_put_image(ScrnInfoPtr pScrn,
 		    return 1;
 		}
 
-		buf = pI830->FbBase +
-		    pXvMC->sfprivs[xvmc_cmd->srfNo]->surface->offset;
-		id = xvmc_cmd->real_id;
-		pI830->IsXvMCSurface = 1;
+		/* use char *buf to hold our surface offset...hacky! */
+		buf = (unsigned char *)pXvMC->sfprivs[xvmc_cmd->srfNo]->surface->offset;
 		break;
 	    default:
 		return 0;
@@ -819,7 +816,6 @@ static int i915_xvmc_put_image(ScrnInfoPtr pScrn,
     ret = pXvMC->savePutImage(pScrn, src_x, src_y, drw_x, drw_y, src_w, src_h,
                         drw_w, drw_h, id, buf, width, height, sync, clipBoxes,
 			data, pDraw);
-    pI830->IsXvMCSurface = 0;
     return ret;
 }
 
diff --git a/src/i915_hwmc.h b/src/i915_hwmc.h
index 7d90afc..8f6557d 100644
--- a/src/i915_hwmc.h
+++ b/src/i915_hwmc.h
@@ -29,6 +29,7 @@
 
 #include "i830_hwmc.h"
 
+/* i915 hw requires surface to be at least 1KB aligned */
 #define STRIDE(w)               (((w) + 0x3ff) & ~0x3ff)
 #define SIZE_Y420(w, h)         (h * STRIDE(w))
 #define SIZE_UV420(w, h)        ((h >> 1) * STRIDE(w >> 1))
diff --git a/src/i915_video.c b/src/i915_video.c
index aeb3729..d2da94b 100644
--- a/src/i915_video.c
+++ b/src/i915_video.c
@@ -42,7 +42,7 @@
 void
 I915DisplayVideoTextured(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv, int id,
 			 RegionPtr dstRegion,
-			 short width, short height, int video_pitch,
+			 short width, short height, int video_pitch, int video_pitch2,
 			 int x1, int y1, int x2, int y2,
 			 short src_w, short src_h, short drw_w, short drw_h,
 			 PixmapPtr pPixmap)
@@ -271,7 +271,13 @@ I915DisplayVideoTextured(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv, int id,
       ms3 |= (height - 1) << MS3_HEIGHT_SHIFT;
       ms3 |= (width - 1) << MS3_WIDTH_SHIFT;
       OUT_BATCH(ms3);
-      OUT_BATCH(((video_pitch * 2 / 4) - 1) << MS4_PITCH_SHIFT);
+      /* check to see if Y has special pitch than normal double u/v pitch,
+       * e.g i915 XvMC hw requires at least 1K alignment, so Y pitch might
+       * be same as U/V's.*/
+      if (video_pitch2)
+	  OUT_BATCH(((video_pitch2 / 4) - 1) << MS4_PITCH_SHIFT);
+      else
+	  OUT_BATCH(((video_pitch * 2 / 4) - 1) << MS4_PITCH_SHIFT);
 
       OUT_BATCH(pPriv->UBuf0offset);
       ms3 = MAPSURF_8BIT | MT_8BIT_I8 | MS3_USE_FENCE_REGS;
commit 550082070a3fdb951e3cf08974dc56276c0a739c
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Thu Jun 26 14:22:34 2008 +0800

    xvmc: enlarge batch buffer size

diff --git a/src/i830_hwmc.c b/src/i830_hwmc.c
index 7586ff7..22fb69e 100644
--- a/src/i830_hwmc.c
+++ b/src/i830_hwmc.c
@@ -122,9 +122,10 @@ Bool intel_xvmc_screen_init(ScreenPtr pScreen)
 Bool intel_xvmc_init_batch(ScrnInfoPtr pScrn)
 {
     I830Ptr pI830 = I830PTR(pScrn);
+    int size = KB(64);
 
     if (!i830_allocate_xvmc_buffer(pScrn, "[XvMC] batch buffer",
-                                   &(xvmc_driver->batch), 8 * 1024,
+                                   &(xvmc_driver->batch), size,
                                    ALIGN_BOTH_ENDS))
         return FALSE;
 
commit d50cec6ef9e2178ea663e58d548390f0f3da7692
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Thu Jun 26 14:20:05 2008 +0800

    xvmc: only allocate memory requiring physical address on 915G
    
    Later 945-ish chipset can use graphics address instead.

diff --git a/src/i915_hwmc.c b/src/i915_hwmc.c
index 973cabf..c345175 100644
--- a/src/i915_hwmc.c
+++ b/src/i915_hwmc.c
@@ -319,8 +319,8 @@ static Bool i915_allocate_xvmc_buffers(ScrnInfoPtr pScrn, I915XvMCContextPriv *c
     I830Ptr pI830 = I830PTR(pScrn);
     int flags = ALIGN_BOTH_ENDS;
 
-    if (IS_I915G(pI830) || IS_I915GM(pI830) ||
-	    IS_I945G(pI830) || IS_I945GM(pI830))
+    /* on 915G/GM, load indirect can only use physical address...sigh */
+    if (IS_I915G(pI830) || IS_I915GM(pI830))
         flags |= NEED_PHYSICAL_ADDR;
 
     if (!i830_allocate_xvmc_buffer(pScrn, "[XvMC]Static Indirect State",
@@ -353,14 +353,14 @@ static Bool i915_allocate_xvmc_buffers(ScrnInfoPtr pScrn, I915XvMCContextPriv *c
         return FALSE;
     }
 
-    if (!i830_allocate_xvmc_buffer(pScrn, "[XvMC]Correction Data Buffer", 
+    if (!i830_allocate_xvmc_buffer(pScrn, "[XvMC]Correction Data Buffer",
                                    &(ctxpriv->mcCorrdata), 512 * 1024,
                                    ALIGN_BOTH_ENDS)) {
         return FALSE;
     }
 
-    if (0)
-	i830_describe_allocations(pScrn, 1, "");
+    if (1)
+	i830_describe_allocations(pScrn, 1, "i915_mc: ");
 
     return TRUE;
 }
@@ -500,29 +500,32 @@ static int i915_xvmc_create_context (ScrnInfoPtr pScrn, XvMCContextPtr pContext,
     contextRec->sis.handle = ctxpriv->sis_handle;
     contextRec->sis.offset = ctxpriv->mcStaticIndirectState->offset;
     contextRec->sis.size = ctxpriv->mcStaticIndirectState->size;
-    contextRec->sis.bus_addr = ctxpriv->mcStaticIndirectState->bus_addr;
     contextRec->ssb.handle = ctxpriv->ssb_handle;
     contextRec->ssb.offset = ctxpriv->mcSamplerState->offset;
     contextRec->ssb.size = ctxpriv->mcSamplerState->size;
-    contextRec->ssb.bus_addr = ctxpriv->mcSamplerState->bus_addr;
     contextRec->msb.handle = ctxpriv->msb_handle;
     contextRec->msb.offset = ctxpriv->mcMapState->offset;
     contextRec->msb.size = ctxpriv->mcMapState->size;
-    contextRec->msb.bus_addr = ctxpriv->mcMapState->bus_addr;
     contextRec->psp.handle = ctxpriv->psp_handle;
     contextRec->psp.offset = ctxpriv->mcPixelShaderProgram->offset;
     contextRec->psp.size = ctxpriv->mcPixelShaderProgram->size;
-    contextRec->psp.bus_addr = ctxpriv->mcPixelShaderProgram->bus_addr;
     contextRec->psc.handle = ctxpriv->psc_handle;
     contextRec->psc.offset = ctxpriv->mcPixelShaderConstants->offset;
     contextRec->psc.size = ctxpriv->mcPixelShaderConstants->size;
-    contextRec->psc.bus_addr = ctxpriv->mcPixelShaderConstants->bus_addr;
     contextRec->corrdata.handle = ctxpriv->corrdata_handle;
     contextRec->corrdata.offset = ctxpriv->mcCorrdata->offset;
     contextRec->corrdata.size = ctxpriv->mcCorrdata->size;
     contextRec->sarea_priv_offset = sizeof(XF86DRISAREARec);
     contextRec->deviceID = pI830DRI->deviceID;
 
+    if (IS_I915G(pI830) || IS_I915GM(pI830)) {
+	contextRec->sis.bus_addr = ctxpriv->mcStaticIndirectState->bus_addr;
+	contextRec->ssb.bus_addr = ctxpriv->mcSamplerState->bus_addr;
+	contextRec->msb.bus_addr = ctxpriv->mcMapState->bus_addr;
+	contextRec->psp.bus_addr = ctxpriv->mcPixelShaderProgram->bus_addr;
+	contextRec->psc.bus_addr = ctxpriv->mcPixelShaderConstants->bus_addr;
+    }
+
     pXvMC->ncontexts++;
     pXvMC->contexts[i] = pContext->context_id;
     pXvMC->ctxprivs[i] = ctxpriv;
diff --git a/src/xvmc/i915_xvmc.c b/src/xvmc/i915_xvmc.c
index f412125..27d1380 100644
--- a/src/xvmc/i915_xvmc.c
+++ b/src/xvmc/i915_xvmc.c
@@ -350,9 +350,9 @@ static void i915_mc_one_time_state_init(XvMCContext *context)
     psp_state *psp = NULL;
     psc_state *psc = NULL;
     i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData;
-    int mem_select = 1;
     struct i915_3dstate_load_state_immediate_1 *load_state_immediate_1;
     struct i915_3dstate_load_indirect *load_indirect;
+    int mem_select;
 
     /* 3DSTATE_LOAD_STATE_IMMEDIATE_1 */
     one_time_load_state_imm1_size = sizeof(*load_state_immediate_1) + sizeof(*s3) + sizeof(*s6);
@@ -398,13 +398,14 @@ static void i915_mc_one_time_state_init(XvMCContext *context)
     load_indirect->dw0.length = (one_time_load_indirect_size >> 2) - 2;
 
     if (pI915XvMC->deviceID == PCI_CHIP_I915_G ||
-        pI915XvMC->deviceID == PCI_CHIP_I915_GM ||
-        pI915XvMC->deviceID == PCI_CHIP_I945_G ||
-        pI915XvMC->deviceID == PCI_CHIP_I945_GM)
-        mem_select = 0;
+        pI915XvMC->deviceID == PCI_CHIP_I915_GM)
+	mem_select = 0; /* use physical address */
+    else
+	mem_select = 1; /* use gfx address */
 
     load_indirect->dw0.mem_select = mem_select;
 
+
     /* Dynamic indirect state buffer */
     dis = (dis_state *)(++load_indirect);
     dis->dw0.valid = 0;
@@ -420,7 +421,7 @@ static void i915_mc_one_time_state_init(XvMCContext *context)
     if (mem_select)
         ssb->dw0.buffer_address = (pI915XvMC->ssb.offset >> 2);
     else
-        ssb->dw0.buffer_address = (pI915XvMC->ssb.bus_addr >> 2);
+	ssb->dw0.buffer_address = (pI915XvMC->ssb.bus_addr >> 2);
 
     /* Pixel shader program buffer */
     psp = (psp_state *)(++ssb);
@@ -429,9 +430,9 @@ static void i915_mc_one_time_state_init(XvMCContext *context)
     psp->dw1.length = 66; /* 4 + 16 + 16 + 31 - 1 */
 
     if (mem_select)
-        psp->dw0.buffer_address = (pI915XvMC->psp.offset >> 2);
+	psp->dw0.buffer_address = (pI915XvMC->psp.offset >> 2);
     else
-        psp->dw0.buffer_address = (pI915XvMC->psp.bus_addr >> 2);
+	psp->dw0.buffer_address = (pI915XvMC->psp.bus_addr >> 2);
 
     /* Pixel shader constant buffer */
     psc = (psc_state *)(++psp);
@@ -725,7 +726,7 @@ static void i915_mc_load_indirect_render_init(XvMCContext *context)
     sis_state *sis;
     msb_state *msb;
     struct i915_3dstate_load_indirect *load_indirect;
-    int mem_select = 1;
+    int mem_select;
 
     mc_render_load_indirect_size = sizeof(*load_indirect) + sizeof(*sis)
 					+ sizeof(*msb);
@@ -738,10 +739,10 @@ static void i915_mc_load_indirect_render_init(XvMCContext *context)
     load_indirect->dw0.length = (mc_render_load_indirect_size >> 2) - 2;
 
     if (pI915XvMC->deviceID == PCI_CHIP_I915_G ||
-        pI915XvMC->deviceID == PCI_CHIP_I915_GM ||
-        pI915XvMC->deviceID == PCI_CHIP_I945_G ||
-        pI915XvMC->deviceID == PCI_CHIP_I945_GM)
+        pI915XvMC->deviceID == PCI_CHIP_I915_GM)
         mem_select = 0;
+    else
+	mem_select = 1;
 
     load_indirect->dw0.mem_select = mem_select;
 
@@ -752,9 +753,9 @@ static void i915_mc_load_indirect_render_init(XvMCContext *context)
     sis->dw1.length = 16; /* 4 * 3 + 2 + 3 - 1 */
 
     if (mem_select)
-        sis->dw0.buffer_address = (pI915XvMC->sis.offset >> 2);
+	sis->dw0.buffer_address = (pI915XvMC->sis.offset >> 2);
     else
-        sis->dw0.buffer_address = (pI915XvMC->sis.bus_addr >> 2);
+	sis->dw0.buffer_address = (pI915XvMC->sis.bus_addr >> 2);
 
     /* Map state buffer (reference buffer info) */
     msb = (msb_state *)(++sis);
@@ -763,9 +764,9 @@ static void i915_mc_load_indirect_render_init(XvMCContext *context)
     msb->dw1.length = 23; /* 3 * 8 - 1 */
 
     if (mem_select)
-        msb->dw0.buffer_address = (pI915XvMC->msb.offset >> 2);
+	msb->dw0.buffer_address = (pI915XvMC->msb.offset >> 2);
     else
-        msb->dw0.buffer_address = (pI915XvMC->msb.bus_addr >> 2);
+	msb->dw0.buffer_address = (pI915XvMC->msb.bus_addr >> 2);
 }
 
 static void i915_mc_load_indirect_render_emit(void)
@@ -1613,9 +1614,7 @@ static Status i915_xvmc_mc_create_context(Display *display, XvMCContext *context
     pI915XvMC->psc.size = tmpComm->psc.size;
 
     if (pI915XvMC->deviceID == PCI_CHIP_I915_G ||
-        pI915XvMC->deviceID == PCI_CHIP_I915_GM ||
-        pI915XvMC->deviceID == PCI_CHIP_I945_G ||
-        pI915XvMC->deviceID == PCI_CHIP_I945_GM) {
+        pI915XvMC->deviceID == PCI_CHIP_I915_GM) {
         pI915XvMC->sis.bus_addr = tmpComm->sis.bus_addr;
         pI915XvMC->ssb.bus_addr = tmpComm->ssb.bus_addr;
         pI915XvMC->msb.bus_addr = tmpComm->msb.bus_addr;
commit d1c34d8c0e7ae2a1d952791343e131837fbfda99
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Thu Jun 26 10:05:21 2008 +0800

    xvmc: init mc render load indirect command once

diff --git a/src/xvmc/i915_xvmc.c b/src/xvmc/i915_xvmc.c
index f04eb51..f412125 100644
--- a/src/xvmc/i915_xvmc.c
+++ b/src/xvmc/i915_xvmc.c
@@ -134,6 +134,10 @@ static uint32_t *one_time_load_state_imm1;
 static uint32_t *one_time_load_indirect;
 static int one_time_load_state_imm1_size, one_time_load_indirect_size;
 
+/* load indirect buffer for mc rendering */
+static uint32_t *mc_render_load_indirect;
+static int mc_render_load_indirect_size;
+
 static void i915_mc_one_time_context_init(XvMCContext *context)
 {
     unsigned int dest, src0, src1, src2;
@@ -715,24 +719,23 @@ static void i915_flush(int map, int render)
     intelBatchbufferData(&mi_flush, sizeof(mi_flush), 0);
 }
 
-static void i915_mc_load_sis_msb_buffers(XvMCContext *context)
+static void i915_mc_load_indirect_render_init(XvMCContext *context)
 {
-    struct i915_3dstate_load_indirect *load_indirect;
-    sis_state *sis = NULL;
-    msb_state *msb = NULL;
     i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData;
-    void *base = NULL;
-    unsigned int size;
+    sis_state *sis;
+    msb_state *msb;
+    struct i915_3dstate_load_indirect *load_indirect;
     int mem_select = 1;
 
-    /* 3DSTATE_LOAD_INDIRECT */
-    size = sizeof(*load_indirect) + sizeof(*sis) + sizeof(*msb);
-    base = calloc(1, size);
-    load_indirect = (struct i915_3dstate_load_indirect *)base;
+    mc_render_load_indirect_size = sizeof(*load_indirect) + sizeof(*sis)
+					+ sizeof(*msb);
+    mc_render_load_indirect = calloc(1, mc_render_load_indirect_size);
+
+    load_indirect = (struct i915_3dstate_load_indirect *)mc_render_load_indirect;
     load_indirect->dw0.type = CMD_3D;
     load_indirect->dw0.opcode = OPC_3DSTATE_LOAD_INDIRECT;
     load_indirect->dw0.block_mask = BLOCK_SIS | BLOCK_MSB;
-    load_indirect->dw0.length = (size >> 2) - 2;
+    load_indirect->dw0.length = (mc_render_load_indirect_size >> 2) - 2;
 
     if (pI915XvMC->deviceID == PCI_CHIP_I915_G ||
         pI915XvMC->deviceID == PCI_CHIP_I915_GM ||
@@ -742,30 +745,32 @@ static void i915_mc_load_sis_msb_buffers(XvMCContext *context)
 
     load_indirect->dw0.mem_select = mem_select;
 
-    /* SIS */
+    /* Static Indirect state buffer (dest buffer info) */
     sis = (sis_state *)(++load_indirect);
     sis->dw0.valid = 1;
     sis->dw0.force = 1;
-    sis->dw1.length = 16; // 4 * 3 + 2 + 3 - 1
+    sis->dw1.length = 16; /* 4 * 3 + 2 + 3 - 1 */
 
     if (mem_select)
         sis->dw0.buffer_address = (pI915XvMC->sis.offset >> 2);
     else
         sis->dw0.buffer_address = (pI915XvMC->sis.bus_addr >> 2);
 
-    /* MSB */
+    /* Map state buffer (reference buffer info) */
     msb = (msb_state *)(++sis);
     msb->dw0.valid = 1;
     msb->dw0.force = 1;
-    msb->dw1.length = 23; // 3 * 8 - 1
+    msb->dw1.length = 23; /* 3 * 8 - 1 */
 
     if (mem_select)
         msb->dw0.buffer_address = (pI915XvMC->msb.offset >> 2);
     else
         msb->dw0.buffer_address = (pI915XvMC->msb.bus_addr >> 2);
+}
 
-    intelBatchbufferData(base, size, 0);
-    free(base);
+static void i915_mc_load_indirect_render_emit(void)
+{
+    i915_emit_batch(mc_render_load_indirect, mc_render_load_indirect_size, 0);
 }
 
 static void i915_mc_mpeg_set_origin(XvMCContext *context, XvMCMacroBlock *mb)
@@ -1646,7 +1651,7 @@ static Status i915_xvmc_mc_create_context(Display *display, XvMCContext *context
     pI915XvMC->port = context->port;
     pI915XvMC->ref = 1;
 
-    /* preinit state buffers */
+    /* pre-init state buffers */
     i915_mc_one_time_context_init(context);
     i915_mc_one_time_state_init(context);
 
@@ -1654,6 +1659,7 @@ static Status i915_xvmc_mc_create_context(Display *display, XvMCContext *context
 
     i915_mc_map_state_init(context);
 
+    i915_mc_load_indirect_render_init(context);
     return Success;
 }
 
@@ -1669,6 +1675,7 @@ static int i915_xvmc_mc_destroy_context(Display *display, XvMCContext *context)
 
     free(one_time_load_state_imm1);
     free(one_time_load_indirect);
+    free(mc_render_load_indirect);
     return Success;
 }
 
@@ -1917,7 +1924,9 @@ static int i915_xvmc_mc_render_surface(Display *display, XvMCContext *context,
 	    flags, picture_coding_type);
     /* setup reference surfaces */
     i915_mc_map_state_set(context, privPast, privFuture);
-    i915_mc_load_sis_msb_buffers(context);
+
+    i915_mc_load_indirect_render_emit();
+
     i915_mc_mpeg_set_origin(context, &macroblock_array->macro_blocks[first_macroblock]);
 
     for (i = first_macroblock; i < (num_macroblocks + first_macroblock); i++) {
commit 75e38fa8348198ba151afa37e10be3b0b0b468f8
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Thu Jun 26 09:47:28 2008 +0800

    xvmc: init dest and reference buffer once
    
    Init them right after context create, and only update buffer address
    info later.

diff --git a/src/xvmc/i915_structs.h b/src/xvmc/i915_structs.h
index 7e786e7..b5185cb 100644
--- a/src/xvmc/i915_structs.h
+++ b/src/xvmc/i915_structs.h
@@ -354,7 +354,7 @@ struct i915_3dstate_dest_buffer_variables_mpeg
         unsigned rcontrol : 1;
         unsigned decode_mode : 2;
     } dw1;
-        
+
     struct {
         unsigned pad0 : 1;
         unsigned picture_coding_type : 2;
@@ -374,6 +374,15 @@ struct i915_3dstate_dest_buffer_variables_mpeg
     } dw2;
 };
 
+struct i915_mc_static_indirect_state_buffer {
+    struct i915_3dstate_buffer_info dest_y;
+    struct i915_3dstate_buffer_info dest_u;
+    struct i915_3dstate_buffer_info dest_v;
+    struct i915_3dstate_dest_buffer_variables dest_buf;
+    struct i915_3dstate_dest_buffer_variables_mpeg dest_buf_mpeg;
+    struct i915_3dstate_buffer_info corr;
+};
+
 #define MAP_MAP0        0x0001
 #define MAP_MAP1        0x0002
 #define MAP_MAP2        0x0004
@@ -434,7 +443,18 @@ struct i915_3dstate_map_state
         unsigned map_mask : 16;
         unsigned pad0 : 16;
     } dw1;
-//    struct texture_map *tms;
+};
+
+struct i915_mc_map_state {
+    struct i915_3dstate_map_state y_map;
+    struct texture_map y_forward;
+    struct texture_map y_backward;
+    struct i915_3dstate_map_state u_map;
+    struct texture_map u_forward;
+    struct texture_map u_backward;
+    struct i915_3dstate_map_state v_map;
+    struct texture_map v_forward;
+    struct texture_map v_backward;
 };
 
 #define SAMPLER_SAMPLER0        0x0001
diff --git a/src/xvmc/i915_xvmc.c b/src/xvmc/i915_xvmc.c
index 45acf9b..f04eb51 100644
--- a/src/xvmc/i915_xvmc.c
+++ b/src/xvmc/i915_xvmc.c
@@ -447,290 +447,272 @@ static void i915_mc_one_time_state_emit(void)
     i915_emit_batch(one_time_load_indirect, one_time_load_indirect_size, 0);
 }
 
-static void i915_flush(int map, int render)
+static void i915_mc_static_indirect_state_init(XvMCContext *context)
 {
-    struct i915_mi_flush mi_flush;
-
-    memset(&mi_flush, 0, sizeof(mi_flush));
-    mi_flush.dw0.type = CMD_MI;
-    mi_flush.dw0.opcode = OPC_MI_FLUSH;
-    mi_flush.dw0.map_cache_invalidate = map;
-    mi_flush.dw0.render_cache_flush_inhibit = render;
+    i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData;
+    struct i915_mc_static_indirect_state_buffer *buffer_info =
+	(struct i915_mc_static_indirect_state_buffer *)pI915XvMC->sis.map;
 
-    intelBatchbufferData(&mi_flush, sizeof(mi_flush), 0);
+    memset(buffer_info, 0, sizeof(*buffer_info));
+    /* dest Y */
+    buffer_info->dest_y.dw0.type = CMD_3D;
+    buffer_info->dest_y.dw0.opcode = OPC_3DSTATE_BUFFER_INFO;
+    buffer_info->dest_y.dw0.length = 1;
+    buffer_info->dest_y.dw1.aux_id = 0;
+    buffer_info->dest_y.dw1.buffer_id = BUFFERID_COLOR_BACK;
+    buffer_info->dest_y.dw1.fence_regs = 0;    /* disabled */ /* FIXME: tiled y for performance */
+    buffer_info->dest_y.dw1.tiled_surface = 0; /* linear */
+    buffer_info->dest_y.dw1.walk = TILEWALK_XMAJOR;
+
+    /* dest U */
+    buffer_info->dest_u.dw0.type = CMD_3D;
+    buffer_info->dest_u.dw0.opcode = OPC_3DSTATE_BUFFER_INFO;
+    buffer_info->dest_u.dw0.length = 1;
+    buffer_info->dest_u.dw1.aux_id = 0;
+    buffer_info->dest_u.dw1.buffer_id = BUFFERID_COLOR_AUX;
+    buffer_info->dest_u.dw1.fence_regs = 0;
+    buffer_info->dest_u.dw1.tiled_surface = 0;
+    buffer_info->dest_u.dw1.walk = TILEWALK_XMAJOR;
+
+    /* dest V */
+    buffer_info->dest_v.dw0.type = CMD_3D;
+    buffer_info->dest_v.dw0.opcode = OPC_3DSTATE_BUFFER_INFO;
+    buffer_info->dest_v.dw0.length = 1;
+    buffer_info->dest_v.dw1.aux_id = 1;
+    buffer_info->dest_v.dw1.buffer_id = BUFFERID_COLOR_AUX;
+    buffer_info->dest_v.dw1.fence_regs = 0;
+    buffer_info->dest_v.dw1.tiled_surface = 0;
+    buffer_info->dest_v.dw1.walk = TILEWALK_XMAJOR;
+
+    buffer_info->dest_buf.dw0.type = CMD_3D;
+    buffer_info->dest_buf.dw0.opcode = OPC_3DSTATE_DEST_BUFFER_VARIABLES;
+    buffer_info->dest_buf.dw0.length = 0;
+    buffer_info->dest_buf.dw1.dest_v_bias = 8; /* 0.5 */
+    buffer_info->dest_buf.dw1.dest_h_bias = 8; /* 0.5 */
+    buffer_info->dest_buf.dw1.color_fmt = COLORBUFFER_8BIT;
+    buffer_info->dest_buf.dw1.v_ls = 0; /* fill later */
+    buffer_info->dest_buf.dw1.v_ls_offset = 0; /* fill later */
+
+    buffer_info->dest_buf_mpeg.dw0.type = CMD_3D;
+    buffer_info->dest_buf_mpeg.dw0.opcode = OPC_3DSTATE_DEST_BUFFER_VARIABLES_MPEG;
+    buffer_info->dest_buf_mpeg.dw0.length = 1;
+    buffer_info->dest_buf_mpeg.dw1.decode_mode = MPEG_DECODE_MC;
+    buffer_info->dest_buf_mpeg.dw1.rcontrol = 0;               /* for MPEG-1/MPEG-2 */
+    buffer_info->dest_buf_mpeg.dw1.bidir_avrg_control = 0;     /* for MPEG-1/MPEG-2/MPEG-4 */
+    buffer_info->dest_buf_mpeg.dw1.abort_on_error = 1;
+    buffer_info->dest_buf_mpeg.dw1.intra8 = 0;         /* 16-bit formatted correction data */
+    buffer_info->dest_buf_mpeg.dw1.tff = 1; /* fill later */
+
+    buffer_info->dest_buf_mpeg.dw1.v_subsample_factor = MC_SUB_1V;
+    buffer_info->dest_buf_mpeg.dw1.h_subsample_factor = MC_SUB_1H;
+
+    buffer_info->corr.dw0.type = CMD_3D;
+    buffer_info->corr.dw0.opcode = OPC_3DSTATE_BUFFER_INFO;
+    buffer_info->corr.dw0.length = 1;
+    buffer_info->corr.dw1.aux_id = 0;
+    buffer_info->corr.dw1.buffer_id = BUFFERID_MC_INTRA_CORR;
+    buffer_info->corr.dw1.aux_id = 0;
+    buffer_info->corr.dw1.fence_regs = 0;
+    buffer_info->corr.dw1.tiled_surface = 0;
+    buffer_info->corr.dw1.walk = 0;
+    buffer_info->corr.dw1.pitch = 0;
+    buffer_info->corr.dw2.base_address = (pI915XvMC->corrdata.offset >> 2);  /* starting DWORD address */
 }
 
-/* for MC picture rendering */
-static void i915_mc_static_indirect_state_buffer(XvMCContext *context,
-	XvMCSurface *surface,
-	unsigned int picture_structure,
-	unsigned int flags,
-	unsigned int picture_coding_type)
+static void i915_mc_static_indirect_state_set(XvMCContext *context, XvMCSurface *dest,
+	unsigned int picture_structure, unsigned int flags, unsigned int picture_coding_type)
 {
-    struct i915_3dstate_buffer_info *buffer_info;
-    struct i915_3dstate_dest_buffer_variables *dest_buffer_variables;
-    struct i915_3dstate_dest_buffer_variables_mpeg *dest_buffer_variables_mpeg;
-    i915XvMCSurface *pI915Surface = (i915XvMCSurface *)surface->privData;
     i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData;
-    unsigned int w = surface->width;
-
-    /* 3DSTATE_BUFFER_INFO */
-    /* DEST Y */
-    buffer_info = (struct i915_3dstate_buffer_info *)pI915XvMC->sis.map;
-    memset(buffer_info, 0, sizeof(*buffer_info));
-    buffer_info->dw0.type = CMD_3D;
-    buffer_info->dw0.opcode = OPC_3DSTATE_BUFFER_INFO;
-    buffer_info->dw0.length = 1;
-    buffer_info->dw1.aux_id = 0;
-    buffer_info->dw1.buffer_id = BUFFERID_COLOR_BACK;
-    buffer_info->dw1.fence_regs = 0;    /* disabled */ /* FIXME: tiled y for performance */
-    buffer_info->dw1.tiled_surface = 0; /* linear */
-    buffer_info->dw1.walk = TILEWALK_XMAJOR;
-    buffer_info->dw1.pitch = (pI915Surface->yStride >> 2);      /* in DWords */
-    buffer_info->dw2.base_address = (YOFFSET(pI915Surface) >> 2);    /* starting DWORD address */
-
-    /* DEST U */
-    ++buffer_info;
-    memset(buffer_info, 0, sizeof(*buffer_info));
-    buffer_info->dw0.type = CMD_3D;
-    buffer_info->dw0.opcode = OPC_3DSTATE_BUFFER_INFO;
-    buffer_info->dw0.length = 1;
-    buffer_info->dw1.aux_id = 0;
-    buffer_info->dw1.buffer_id = BUFFERID_COLOR_AUX;
-    buffer_info->dw1.fence_regs = 0;
-    buffer_info->dw1.tiled_surface = 0;
-    buffer_info->dw1.walk = TILEWALK_XMAJOR;
-    buffer_info->dw1.pitch = (pI915Surface->uvStride >> 2);      /* in DWords */
-    buffer_info->dw2.base_address = (UOFFSET(pI915Surface) >> 2);      /* starting DWORD address */
-
-    /* DEST V */
-    ++buffer_info;
-    memset(buffer_info, 0, sizeof(*buffer_info));
-    buffer_info->dw0.type = CMD_3D;
-    buffer_info->dw0.opcode = OPC_3DSTATE_BUFFER_INFO;
-    buffer_info->dw0.length = 1;
-    buffer_info->dw1.aux_id = 1;
-    buffer_info->dw1.buffer_id = BUFFERID_COLOR_AUX;
-    buffer_info->dw1.fence_regs = 0;
-    buffer_info->dw1.tiled_surface = 0;
-    buffer_info->dw1.walk = TILEWALK_XMAJOR;
-    buffer_info->dw1.pitch = (pI915Surface->uvStride >> 2);      /* in Dwords */
-    buffer_info->dw2.base_address = (VOFFSET(pI915Surface) >> 2);      /* starting DWORD address */
-
-    /* 3DSTATE_DEST_BUFFER_VARIABLES */
-    dest_buffer_variables = (struct i915_3dstate_dest_buffer_variables *)(++buffer_info);
-    memset(dest_buffer_variables, 0, sizeof(*dest_buffer_variables));
-    dest_buffer_variables->dw0.type = CMD_3D;
-    dest_buffer_variables->dw0.opcode = OPC_3DSTATE_DEST_BUFFER_VARIABLES;
-    dest_buffer_variables->dw0.length = 0;
-    dest_buffer_variables->dw1.dest_v_bias = 8; /* 0.5 */
-    dest_buffer_variables->dw1.dest_h_bias = 8; /* 0.5 */
-    dest_buffer_variables->dw1.color_fmt = COLORBUFFER_8BIT;
-    dest_buffer_variables->dw1.v_ls = 0;
-    dest_buffer_variables->dw1.v_ls_offset = 0;
+    i915XvMCSurface *pI915Surface = (i915XvMCSurface *)dest->privData;
+    struct i915_mc_static_indirect_state_buffer *buffer_info =
+	(struct i915_mc_static_indirect_state_buffer *)pI915XvMC->sis.map;
+    unsigned int w = dest->width;
+
+    buffer_info->dest_y.dw1.pitch = (pI915Surface->yStride >> 2);      /* in DWords */
+    buffer_info->dest_y.dw2.base_address = (YOFFSET(pI915Surface) >> 2);    /* starting DWORD address */
+    buffer_info->dest_u.dw1.pitch = (pI915Surface->uvStride >> 2);      /* in DWords */
+    buffer_info->dest_u.dw2.base_address = (UOFFSET(pI915Surface) >> 2);      /* starting DWORD address */
+    buffer_info->dest_v.dw1.pitch = (pI915Surface->uvStride >> 2);      /* in Dwords */
+    buffer_info->dest_v.dw2.base_address = (VOFFSET(pI915Surface) >> 2);      /* starting DWORD address */
 
     if ((picture_structure & XVMC_FRAME_PICTURE) == XVMC_FRAME_PICTURE) {
         ;
     } else if ((picture_structure & XVMC_FRAME_PICTURE) == XVMC_TOP_FIELD) {
-        dest_buffer_variables->dw1.v_ls = 1;
+        buffer_info->dest_buf.dw1.v_ls = 1;
     } else if ((picture_structure & XVMC_FRAME_PICTURE) == XVMC_BOTTOM_FIELD) {
-        dest_buffer_variables->dw1.v_ls = 1;
-        dest_buffer_variables->dw1.v_ls_offset = 1;
+        buffer_info->dest_buf.dw1.v_ls = 1;
+        buffer_info->dest_buf.dw1.v_ls_offset = 1;
     }
 
-    /* 3DSTATE_DEST_BUFFER_VARIABLES_MPEG */
-    dest_buffer_variables_mpeg = (struct i915_3dstate_dest_buffer_variables_mpeg *)(++dest_buffer_variables);
-    memset(dest_buffer_variables_mpeg, 0, sizeof(*dest_buffer_variables_mpeg));
-    dest_buffer_variables_mpeg->dw0.type = CMD_3D;
-    dest_buffer_variables_mpeg->dw0.opcode = OPC_3DSTATE_DEST_BUFFER_VARIABLES_MPEG;
-    dest_buffer_variables_mpeg->dw0.length = 1;
-    dest_buffer_variables_mpeg->dw1.decode_mode = MPEG_DECODE_MC;
-    dest_buffer_variables_mpeg->dw1.rcontrol = 0;               /* for MPEG-1/MPEG-2 */
-    dest_buffer_variables_mpeg->dw1.bidir_avrg_control = 0;     /* for MPEG-1/MPEG-2/MPEG-4 */
-    dest_buffer_variables_mpeg->dw1.abort_on_error = 1;
-    dest_buffer_variables_mpeg->dw1.intra8 = 0;         /* 16-bit formatted correction data */
-    dest_buffer_variables_mpeg->dw1.tff = 1;
-
     if (picture_structure & XVMC_FRAME_PICTURE) {
         ;
     } else if (picture_structure & XVMC_TOP_FIELD) {
         if (flags & XVMC_SECOND_FIELD)
-            dest_buffer_variables_mpeg->dw1.tff = 0;
+            buffer_info->dest_buf_mpeg.dw1.tff = 0;
         else
-            dest_buffer_variables_mpeg->dw1.tff = 1;
+            buffer_info->dest_buf_mpeg.dw1.tff = 1;
     } else if (picture_structure & XVMC_BOTTOM_FIELD) {
         if (flags & XVMC_SECOND_FIELD)
-            dest_buffer_variables_mpeg->dw1.tff = 1;
+            buffer_info->dest_buf_mpeg.dw1.tff = 1;
         else
-            dest_buffer_variables_mpeg->dw1.tff = 0;
+            buffer_info->dest_buf_mpeg.dw1.tff = 0;
     }
 
-    dest_buffer_variables_mpeg->dw1.v_subsample_factor = MC_SUB_1V;
-    dest_buffer_variables_mpeg->dw1.h_subsample_factor = MC_SUB_1H;
-    dest_buffer_variables_mpeg->dw1.picture_width = (w >> 4);     /* in macroblocks */
-    dest_buffer_variables_mpeg->dw2.picture_coding_type = picture_coding_type;
-
-    /* 3DSATE_BUFFER_INFO */
-    /* CORRECTION DATA */
-    buffer_info = (struct i915_3dstate_buffer_info *)(++dest_buffer_variables_mpeg);
-    memset(buffer_info, 0, sizeof(*buffer_info));
-    buffer_info->dw0.type = CMD_3D;
-    buffer_info->dw0.opcode = OPC_3DSTATE_BUFFER_INFO;
-    buffer_info->dw0.length = 1;
-    buffer_info->dw1.aux_id = 0;
-    buffer_info->dw1.buffer_id = BUFFERID_MC_INTRA_CORR;
-    buffer_info->dw1.aux_id = 0;
-    buffer_info->dw1.fence_regs = 0;
-    buffer_info->dw1.tiled_surface = 0;
-    buffer_info->dw1.walk = 0;
-    buffer_info->dw1.pitch = 0;
-    buffer_info->dw2.base_address = (pI915XvMC->corrdata.offset >> 2);  /* starting DWORD address */
+    buffer_info->dest_buf_mpeg.dw1.picture_width = (dest->width >> 4);     /* in macroblocks */
+    buffer_info->dest_buf_mpeg.dw2.picture_coding_type = picture_coding_type;
 }
 
-static void i915_mc_map_state_buffer(XvMCContext *context,
-                                       i915XvMCSurface *privTarget,
-                                       i915XvMCSurface *privPast,
-                                       i915XvMCSurface *privFuture)
+static void i915_mc_map_state_init(XvMCContext *context)
 {
-    struct i915_3dstate_map_state *map_state;
-    struct texture_map *tm;
     i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData;
-    unsigned int w = context->width, h = context->height;
+    unsigned int w = context->width;
+    unsigned int h = context->height;
+    struct i915_mc_map_state *map_state;
 
-    /* 3DSATE_MAP_STATE: Y */
-    map_state = (struct i915_3dstate_map_state *)pI915XvMC->msb.map;
-    memset(map_state, 0, sizeof(*map_state));
-    map_state->dw0.type = CMD_3D;
-    map_state->dw0.opcode = OPC_3DSTATE_MAP_STATE;
-    map_state->dw0.retain = 1;
-    map_state->dw0.length = 6;
-    map_state->dw1.map_mask = MAP_MAP0 | MAP_MAP1;
+    map_state = (struct i915_mc_map_state *)pI915XvMC->msb.map;
 
-    /* texture map: Forward (Past) */
-    tm = (struct texture_map *)(++map_state);
-    memset(tm, 0, sizeof(*tm));
-    tm->tm0.v_ls_offset = 0;
-    tm->tm0.v_ls = 0;
-    tm->tm0.base_address = (YOFFSET(privPast) >> 2);
-    tm->tm1.tile_walk = TILEWALK_XMAJOR;        /* FIXME: tiled y for performace */
-    tm->tm1.tiled_surface = 0;
-    tm->tm1.utilize_fence_regs = 0;
-    tm->tm1.texel_fmt = 0;      /* 8bit */
-    tm->tm1.surface_fmt = 1;    /* 8bit */
-    tm->tm1.width = w - 1;
-    tm->tm1.height = h - 1;
-    tm->tm2.depth = 0;
-    tm->tm2.max_lod = 0;
-    tm->tm2.cube_face = 0;
-    tm->tm2.pitch = (privPast->yStride >> 2) - 1;       /* in DWords - 1 */
+    memset(map_state, 0, sizeof(*map_state));
 
-    /* texture map: Backward (Future) */
-    ++tm;
-    memset(tm, 0, sizeof(*tm));
-    tm->tm0.v_ls_offset = 0;
-    tm->tm0.v_ls = 0;
-    tm->tm0.base_address = (YOFFSET(privFuture) >> 2);
-    tm->tm1.tile_walk = TILEWALK_XMAJOR;
-    tm->tm1.tiled_surface = 0;
-    tm->tm1.utilize_fence_regs = 0;
-    tm->tm1.texel_fmt = 0;      /* 8bit */
-    tm->tm1.surface_fmt = 1;    /* 8bit */
-    tm->tm1.width = w - 1;
-    tm->tm1.height = h - 1;
-    tm->tm2.depth = 0;
-    tm->tm2.max_lod = 0;
-    tm->tm2.cube_face = 0;
-    tm->tm2.pitch = (privFuture->yStride >> 2) - 1;
+    /* 3DSATE_MAP_STATE: Y */
+    map_state->y_map.dw0.type = CMD_3D;
+    map_state->y_map.dw0.opcode = OPC_3DSTATE_MAP_STATE;
+    map_state->y_map.dw0.retain = 1;
+    map_state->y_map.dw0.length = 6;
+    map_state->y_map.dw1.map_mask = MAP_MAP0 | MAP_MAP1;
+
+    /* Y Forward (Past) */
+    map_state->y_forward.tm0.v_ls_offset = 0;
+    map_state->y_forward.tm0.v_ls = 0;
+    map_state->y_forward.tm1.tile_walk = TILEWALK_XMAJOR;
+    map_state->y_forward.tm1.tiled_surface = 0;
+    map_state->y_forward.tm1.utilize_fence_regs = 0;
+    map_state->y_forward.tm1.texel_fmt = 0;      /* 8bit */
+    map_state->y_forward.tm1.surface_fmt = 1;    /* 8bit */
+    map_state->y_forward.tm1.width = w - 1;
+    map_state->y_forward.tm1.height = h - 1;
+    map_state->y_forward.tm2.depth = 0;
+    map_state->y_forward.tm2.max_lod = 0;
+    map_state->y_forward.tm2.cube_face = 0;
+
+    /* Y Backward (Future) */
+    map_state->y_backward.tm0.v_ls_offset = 0;
+    map_state->y_backward.tm0.v_ls = 0;
+    map_state->y_backward.tm1.tile_walk = TILEWALK_XMAJOR;
+    map_state->y_backward.tm1.tiled_surface = 0;
+    map_state->y_backward.tm1.utilize_fence_regs = 0;
+    map_state->y_backward.tm1.texel_fmt = 0;      /* 8bit */
+    map_state->y_backward.tm1.surface_fmt = 1;    /* 8bit */
+    map_state->y_backward.tm1.width = w - 1;
+    map_state->y_backward.tm1.height = h - 1;
+    map_state->y_backward.tm2.depth = 0;
+    map_state->y_backward.tm2.max_lod = 0;
+    map_state->y_backward.tm2.cube_face = 0;
 
     /* 3DSATE_MAP_STATE: U */
-    map_state = (struct i915_3dstate_map_state *)(++tm);
-    memset(map_state, 0, sizeof(*map_state));
-    map_state->dw0.type = CMD_3D;
-    map_state->dw0.opcode = OPC_3DSTATE_MAP_STATE;
-    map_state->dw0.retain = 1;
-    map_state->dw0.length = 6;
-    map_state->dw1.map_mask = MAP_MAP0 | MAP_MAP1;
+    map_state->u_map.dw0.type = CMD_3D;
+    map_state->u_map.dw0.opcode = OPC_3DSTATE_MAP_STATE;
+    map_state->u_map.dw0.retain = 1;
+    map_state->u_map.dw0.length = 6;
+    map_state->u_map.dw1.map_mask = MAP_MAP0 | MAP_MAP1;
+
+    /* U Forward */
+    map_state->u_forward.tm0.v_ls_offset = 0;
+    map_state->u_forward.tm0.v_ls = 0;
+    map_state->u_forward.tm1.tile_walk = TILEWALK_XMAJOR;
+    map_state->u_forward.tm1.tiled_surface = 0;
+    map_state->u_forward.tm1.utilize_fence_regs = 0;
+    map_state->u_forward.tm1.texel_fmt = 0;      /* 8bit */
+    map_state->u_forward.tm1.surface_fmt = 1;    /* 8bit */
+    map_state->u_forward.tm1.width = (w >> 1) - 1;
+    map_state->u_forward.tm1.height = (h >> 1) - 1;
+    map_state->u_forward.tm2.depth = 0;
+    map_state->u_forward.tm2.max_lod = 0;
+    map_state->u_forward.tm2.cube_face = 0;
+
+    /* U Backward */
+    map_state->u_backward.tm0.v_ls_offset = 0;
+    map_state->u_backward.tm0.v_ls = 0;
+    map_state->u_backward.tm1.tile_walk = TILEWALK_XMAJOR;
+    map_state->u_backward.tm1.tiled_surface = 0;
+    map_state->u_backward.tm1.utilize_fence_regs = 0;
+    map_state->u_backward.tm1.texel_fmt = 0;
+    map_state->u_backward.tm1.surface_fmt = 1;
+    map_state->u_backward.tm1.width = (w >> 1) - 1;
+    map_state->u_backward.tm1.height = (h >> 1) - 1;
+    map_state->u_backward.tm2.depth = 0;
+    map_state->u_backward.tm2.max_lod = 0;
+    map_state->u_backward.tm2.cube_face = 0;
 
-    /* texture map: Forward */
-    tm = (struct texture_map *)(++map_state);
-    memset(tm, 0, sizeof(*tm));
-    tm->tm0.v_ls_offset = 0;
-    tm->tm0.v_ls = 0;
-    tm->tm0.base_address = (UOFFSET(privPast) >> 2);
-    tm->tm1.tile_walk = TILEWALK_XMAJOR;
-    tm->tm1.tiled_surface = 0;
-    tm->tm1.utilize_fence_regs = 0;
-    tm->tm1.texel_fmt = 0;      /* 8bit */
-    tm->tm1.surface_fmt = 1;    /* 8bit */
-    tm->tm1.width = (w >> 1) - 1;
-    tm->tm1.height = (h >> 1) - 1;
-    tm->tm2.depth = 0;
-    tm->tm2.max_lod = 0;
-    tm->tm2.cube_face = 0;
-    tm->tm2.pitch = (privPast->uvStride >> 2) - 1;       /* in DWords - 1 */
+    /* 3DSATE_MAP_STATE: V */
+    map_state->v_map.dw0.type = CMD_3D;
+    map_state->v_map.dw0.opcode = OPC_3DSTATE_MAP_STATE;
+    map_state->v_map.dw0.retain = 1;
+    map_state->v_map.dw0.length = 6;
+    map_state->v_map.dw1.map_mask = MAP_MAP0 | MAP_MAP1;
+
+    /* V Forward */
+    map_state->v_forward.tm0.v_ls_offset = 0;
+    map_state->v_forward.tm0.v_ls = 0;
+    map_state->v_forward.tm1.tile_walk = TILEWALK_XMAJOR;
+    map_state->v_forward.tm1.tiled_surface = 0;
+    map_state->v_forward.tm1.utilize_fence_regs = 0;
+    map_state->v_forward.tm1.texel_fmt = 0;
+    map_state->v_forward.tm1.surface_fmt = 1;
+    map_state->v_forward.tm1.width = (w >> 1) - 1;
+    map_state->v_forward.tm1.height = (h >> 1) - 1;
+    map_state->v_forward.tm2.depth = 0;
+    map_state->v_forward.tm2.max_lod = 0;
+    map_state->v_forward.tm2.cube_face = 0;
+
+    /* V Backward */
+    map_state->v_backward.tm0.v_ls_offset = 0;
+    map_state->v_backward.tm0.v_ls = 0;
+    map_state->v_backward.tm1.tile_walk = TILEWALK_XMAJOR;
+    map_state->v_backward.tm1.tiled_surface = 0;
+    map_state->v_backward.tm1.utilize_fence_regs = 0;
+    map_state->v_backward.tm1.texel_fmt = 0;
+    map_state->v_backward.tm1.surface_fmt = 1;
+    map_state->v_backward.tm1.width = (w >> 1) - 1;
+    map_state->v_backward.tm1.height = (h >> 1) - 1;
+    map_state->v_backward.tm2.depth = 0;
+    map_state->v_backward.tm2.max_lod = 0;
+    map_state->v_backward.tm2.cube_face = 0;
+}
 
-    /* texture map: Backward */
-    ++tm;
-    memset(tm, 0, sizeof(*tm));
-    tm->tm0.v_ls_offset = 0;
-    tm->tm0.v_ls = 0;
-    tm->tm0.base_address = (UOFFSET(privFuture) >> 2);
-    tm->tm1.tile_walk = TILEWALK_XMAJOR;
-    tm->tm1.tiled_surface = 0;
-    tm->tm1.utilize_fence_regs = 0;
-    tm->tm1.texel_fmt = 0;
-    tm->tm1.surface_fmt = 1;
-    tm->tm1.width = (w >> 1) - 1;
-    tm->tm1.height = (h >> 1) - 1;
-    tm->tm2.depth = 0;
-    tm->tm2.max_lod = 0;
-    tm->tm2.cube_face = 0;
-    tm->tm2.pitch = (privFuture->uvStride >> 2) - 1;
+static void i915_mc_map_state_set(XvMCContext *context,
+	i915XvMCSurface *privPast,
+	i915XvMCSurface *privFuture)
+{
+    i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData;
+    struct i915_mc_map_state *map_state;
+
+    map_state = (struct i915_mc_map_state *)pI915XvMC->msb.map;
+
+    map_state->y_forward.tm0.base_address = (YOFFSET(privPast) >> 2);
+    map_state->y_forward.tm2.pitch = (privPast->yStride >> 2) - 1;       /* in DWords - 1 */
+    map_state->y_backward.tm0.base_address = (YOFFSET(privFuture) >> 2);
+    map_state->y_backward.tm2.pitch = (privFuture->yStride >> 2) - 1;
+    map_state->u_forward.tm0.base_address = (UOFFSET(privPast) >> 2);
+    map_state->u_forward.tm2.pitch = (privPast->uvStride >> 2) - 1;       /* in DWords - 1 */
+    map_state->u_backward.tm0.base_address = (UOFFSET(privFuture) >> 2);
+    map_state->u_backward.tm2.pitch = (privFuture->uvStride >> 2) - 1;
+    map_state->v_forward.tm0.base_address = (VOFFSET(privPast) >> 2);
+    map_state->v_forward.tm2.pitch = (privPast->uvStride >> 2) - 1;       /* in DWords - 1 */
+    map_state->v_backward.tm0.base_address = (VOFFSET(privFuture) >> 2);
+    map_state->v_backward.tm2.pitch = (privFuture->uvStride >> 2) - 1;
+}
 
-    /* 3DSATE_MAP_STATE: V */
-    map_state = (struct i915_3dstate_map_state *)(++tm);
-    memset(map_state, 0, sizeof(*map_state));
-    map_state->dw0.type = CMD_3D;
-    map_state->dw0.opcode = OPC_3DSTATE_MAP_STATE;
-    map_state->dw0.retain = 1;
-    map_state->dw0.length = 6;
-    map_state->dw1.map_mask = MAP_MAP0 | MAP_MAP1;
+static void i915_flush(int map, int render)
+{
+    struct i915_mi_flush mi_flush;
 
-    /* texture map: Forward */
-    tm = (struct texture_map *)(++map_state);
-    memset(tm, 0, sizeof(*tm));
-    tm->tm0.v_ls_offset = 0;
-    tm->tm0.v_ls = 0;
-    tm->tm0.base_address = (VOFFSET(privPast) >> 2);
-    tm->tm1.tile_walk = TILEWALK_XMAJOR;
-    tm->tm1.tiled_surface = 0;
-    tm->tm1.utilize_fence_regs = 0;
-    tm->tm1.texel_fmt = 0;
-    tm->tm1.surface_fmt = 1;
-    tm->tm1.width = (w >> 1) - 1;
-    tm->tm1.height = (h >> 1) - 1;
-    tm->tm2.depth = 0;
-    tm->tm2.max_lod = 0;
-    tm->tm2.cube_face = 0;
-    tm->tm2.pitch = (privPast->uvStride >> 2) - 1;       /* in DWords - 1 */
+    memset(&mi_flush, 0, sizeof(mi_flush));
+    mi_flush.dw0.type = CMD_MI;
+    mi_flush.dw0.opcode = OPC_MI_FLUSH;
+    mi_flush.dw0.map_cache_invalidate = map;
+    mi_flush.dw0.render_cache_flush_inhibit = render;
 
-    /* texture map: Backward */
-    ++tm;
-    memset(tm, 0, sizeof(*tm));
-    tm->tm0.v_ls_offset = 0;
-    tm->tm0.v_ls = 0;
-    tm->tm0.base_address = (VOFFSET(privFuture) >> 2);
-    tm->tm1.tile_walk = TILEWALK_XMAJOR;
-    tm->tm1.tiled_surface = 0;
-    tm->tm1.utilize_fence_regs = 0;
-    tm->tm1.texel_fmt = 0;
-    tm->tm1.surface_fmt = 1;
-    tm->tm1.width = (w >> 1) - 1;
-    tm->tm1.height = (h >> 1) - 1;
-    tm->tm2.depth = 0;
-    tm->tm2.max_lod = 0;
-    tm->tm2.cube_face = 0;
-    tm->tm2.pitch = (privFuture->uvStride >> 2) - 1;
+    intelBatchbufferData(&mi_flush, sizeof(mi_flush), 0);
 }
 
 static void i915_mc_load_sis_msb_buffers(XvMCContext *context)
@@ -1668,6 +1650,10 @@ static Status i915_xvmc_mc_create_context(Display *display, XvMCContext *context
     i915_mc_one_time_context_init(context);
     i915_mc_one_time_state_init(context);
 
+    i915_mc_static_indirect_state_init(context);
+
+    i915_mc_map_state_init(context);
+
     return Success;
 }
 
@@ -1927,10 +1913,10 @@ static int i915_xvmc_mc_render_surface(Display *display, XvMCContext *context,
 
     i915_mc_one_time_state_emit();
 
-    i915_mc_static_indirect_state_buffer(context, target_surface,
-                                         picture_structure, flags,
-                                         picture_coding_type);
-    i915_mc_map_state_buffer(context, privTarget, privPast, privFuture);
+    i915_mc_static_indirect_state_set(context, target_surface, picture_structure,
+	    flags, picture_coding_type);
+    /* setup reference surfaces */
+    i915_mc_map_state_set(context, privPast, privFuture);
     i915_mc_load_sis_msb_buffers(context);
     i915_mc_mpeg_set_origin(context, &macroblock_array->macro_blocks[first_macroblock]);
 
commit b4d8ca8b38e495b56bb3b4143e5dfe91ee651f15
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Wed Jun 25 14:27:16 2008 +0800

    xvmc: init one-time mc context once
    
    Don't setup one-time mc context everytime, as the content is always
    unchanged. And several structs got packed layout inside to ease static
    state initialization.

diff --git a/src/xvmc/i915_structs.h b/src/xvmc/i915_structs.h
index a25d734..7e786e7 100644
--- a/src/xvmc/i915_structs.h
+++ b/src/xvmc/i915_structs.h
@@ -28,6 +28,8 @@
 #ifndef _I915_STRUCTS_H
 #define _I915_STRUCTS_H
 
+#include <stdint.h>
+
 /* MI_INSTRUCTION */
 #define CMD_MI          0x00
 
@@ -532,6 +534,9 @@ struct i915_3dstate_sampler_state
         unsigned sampler_masker : 16;
         unsigned pad0 : 16;
     } dw1;
+    /* we always use two samplers for mc */
+    struct texture_sampler sampler0;
+    struct texture_sampler sampler1;
 };
 
 struct arithmetic_inst
@@ -641,17 +646,48 @@ union shader_inst
     struct declaration_inst d;
 };
 
+struct i915_3dstate_pixel_shader_header {
+    unsigned length : 9;
+    unsigned pad0 : 6;
+    unsigned retain : 1;
+    unsigned opcode : 13;
+    unsigned type : 3;
+};
+
 struct i915_3dstate_pixel_shader_program
 {
-    struct {
-        unsigned length : 9;
-        unsigned pad0 : 6;
-        unsigned retain : 1;
-        unsigned opcode : 13;
-        unsigned type : 3;
-    } dw0;
-
-    // union shader_inst *insts;
+    struct i915_3dstate_pixel_shader_header shader0;
+    /* mov oC, c0.0000 */
+    uint32_t inst0[3];
+
+    struct i915_3dstate_pixel_shader_header shader1;
+    /* dcl t0.xy */
+    /* dcl t1.xy */
+    /* dcl_2D s0 */
+    /* texld r0, t0, s0 */
+    /* mov oC, r0 */
+    uint32_t inst1[3*5];
+
+    struct i915_3dstate_pixel_shader_header shader2;
+    /* dcl t2.xy */
+    /* dcl t3.xy */
+    /* dcl_2D s1 */
+    /* texld r0, t2, s1 */
+    /* mov oC, r0 */
+    uint32_t inst2[3*5];
+
+    struct i915_3dstate_pixel_shader_header shader3;
+    /* dcl t0.xy */
+    /* dcl t1.xy */
+    /* dcl t2.xy */
+    /* dcl t3.xy */
+    /* dcl_2D s0 */
+    /* dcl_2D s1 */
+    /* texld r0, t0, s0 */
+    /* texld r0, t2, s1 */
+    /* add r0, r0, r1*/
+    /* mov oC, r0 */
+    uint32_t inst3[3*10];
 };
 
 #define REG_CR0         0x00000001
@@ -707,7 +743,8 @@ struct i915_3dstate_pixel_shader_constants
     struct {
         unsigned reg_mask;
     } dw1;
-    // struct shader_constant *consts;
+    /* we only need one constant */
+    struct shader_constant value;
 };
 
 #define BLOCK_SIS       0x01
diff --git a/src/xvmc/i915_xvmc.c b/src/xvmc/i915_xvmc.c
index bd31de4..45acf9b 100644
--- a/src/xvmc/i915_xvmc.c
+++ b/src/xvmc/i915_xvmc.c
@@ -81,6 +81,372 @@ static int findOverlap(unsigned int width, unsigned int height,
 }
 #endif
 
+static void i915_inst_arith(unsigned int *inst,
+                            unsigned int op,
+                            unsigned int dest,
+                            unsigned int mask,
+                            unsigned int saturate,
+                            unsigned int src0, unsigned int src1, unsigned int src2)
+{
+    dest = UREG(GET_UREG_TYPE(dest), GET_UREG_NR(dest));
+    *inst = (op | A0_DEST(dest) | mask | saturate | A0_SRC0(src0));
+    inst++;
+    *inst = (A1_SRC0(src0) | A1_SRC1(src1));
+    inst++;
+    *inst = (A2_SRC1(src1) | A2_SRC2(src2));
+}
+
+static void i915_inst_decl(unsigned int *inst,
+                           unsigned int type,
+                           unsigned int nr,
+                           unsigned int d0_flags)
+{
+    unsigned int reg = UREG(type, nr);
+
+    *inst = (D0_DCL | D0_DEST(reg) | d0_flags);
+    inst++;
+    *inst = D1_MBZ;
+    inst++;
+    *inst = D2_MBZ;
+}
+
+static void i915_inst_texld(unsigned int *inst,
+                              unsigned int op,
+                              unsigned int dest,
+                              unsigned int coord,
+                              unsigned int sampler)
+{
+   dest = UREG(GET_UREG_TYPE(dest), GET_UREG_NR(dest));
+   *inst = (op | T0_DEST(dest) | T0_SAMPLER(sampler));
+   inst++;
+   *inst = T1_ADDRESS_REG(coord);
+   inst++;
+   *inst = T2_MBZ;
+}
+
+static void i915_emit_batch(void *data, int size, int flag)
+{
+    intelBatchbufferData(data, size, flag);
+}
+
+/* one time context initialization buffer */
+static uint32_t *one_time_load_state_imm1;
+static uint32_t *one_time_load_indirect;
+static int one_time_load_state_imm1_size, one_time_load_indirect_size;
+
+static void i915_mc_one_time_context_init(XvMCContext *context)
+{
+    unsigned int dest, src0, src1, src2;
+    i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData;
+    int i;
+    struct i915_3dstate_sampler_state *sampler_state;
+    struct i915_3dstate_pixel_shader_program *pixel_shader_program;
+    struct i915_3dstate_pixel_shader_constants *pixel_shader_constants;
+
+    /* sampler static state */
+    sampler_state = (struct i915_3dstate_sampler_state *)pI915XvMC->ssb.map;
+    /* pixel shader static state */
+    pixel_shader_program = (struct i915_3dstate_pixel_shader_program *)pI915XvMC->psp.map;
+    /* pixel shader contant static state */
+    pixel_shader_constants = (struct i915_3dstate_pixel_shader_constants *)pI915XvMC->psc.map;
+
+    memset(sampler_state, 0, sizeof(*sampler_state));
+    sampler_state->dw0.type = CMD_3D;
+    sampler_state->dw0.opcode = OPC_3DSTATE_SAMPLER_STATE;
+    sampler_state->dw0.length = 6;
+    sampler_state->dw1.sampler_masker = SAMPLER_SAMPLER0 | SAMPLER_SAMPLER1;
+
+    sampler_state->sampler0.ts0.reverse_gamma = 0;
+    sampler_state->sampler0.ts0.planar2packet = 0;
+    sampler_state->sampler0.ts0.color_conversion = 0;
+    sampler_state->sampler0.ts0.chromakey_index = 0;
+    sampler_state->sampler0.ts0.base_level = 0;
+    sampler_state->sampler0.ts0.mip_filter = MIPFILTER_NONE;        /* NONE */
+    sampler_state->sampler0.ts0.mag_filter = MAPFILTER_LINEAR;      /* LINEAR */
+    sampler_state->sampler0.ts0.min_filter = MAPFILTER_LINEAR;      /* LINEAR */
+    sampler_state->sampler0.ts0.lod_bias = 0;       /* 0.0 */
+    sampler_state->sampler0.ts0.shadow_enable = 0;
+    sampler_state->sampler0.ts0.max_anisotropy = ANISORATIO_2;
+    sampler_state->sampler0.ts0.shadow_function = PREFILTEROP_ALWAYS;
+    sampler_state->sampler0.ts1.min_lod = 0;        /* 0.0 Maximum Mip Level */
+    sampler_state->sampler0.ts1.kill_pixel = 0;
+    sampler_state->sampler0.ts1.keyed_texture_filter = 0;
+    sampler_state->sampler0.ts1.chromakey_enable = 0;
+    sampler_state->sampler0.ts1.tcx_control = TEXCOORDMODE_CLAMP;
+    sampler_state->sampler0.ts1.tcy_control = TEXCOORDMODE_CLAMP;
+    sampler_state->sampler0.ts1.tcz_control = TEXCOORDMODE_CLAMP;
+    sampler_state->sampler0.ts1.normalized_coor = 0;
+    sampler_state->sampler0.ts1.map_index = 0;
+    sampler_state->sampler0.ts1.east_deinterlacer = 0;
+    sampler_state->sampler0.ts2.default_color = 0;
+
+    sampler_state->sampler1.ts0.reverse_gamma = 0;
+    sampler_state->sampler1.ts0.planar2packet = 0;
+    sampler_state->sampler1.ts0.color_conversion = 0;
+    sampler_state->sampler1.ts0.chromakey_index = 0;
+    sampler_state->sampler1.ts0.base_level = 0;
+    sampler_state->sampler1.ts0.mip_filter = MIPFILTER_NONE;        /* NONE */
+    sampler_state->sampler1.ts0.mag_filter = MAPFILTER_LINEAR;      /* LINEAR */
+    sampler_state->sampler1.ts0.min_filter = MAPFILTER_LINEAR;      /* LINEAR */
+    sampler_state->sampler1.ts0.lod_bias = 0;       /* 0.0 */
+    sampler_state->sampler1.ts0.shadow_enable = 0;
+    sampler_state->sampler1.ts0.max_anisotropy = ANISORATIO_2;
+    sampler_state->sampler1.ts0.shadow_function = PREFILTEROP_ALWAYS;
+    sampler_state->sampler1.ts1.min_lod = 0;        /* 0.0 Maximum Mip Level */
+    sampler_state->sampler1.ts1.kill_pixel = 0;
+    sampler_state->sampler1.ts1.keyed_texture_filter = 0;
+    sampler_state->sampler1.ts1.chromakey_enable = 0;
+    sampler_state->sampler1.ts1.tcx_control = TEXCOORDMODE_CLAMP;
+    sampler_state->sampler1.ts1.tcy_control = TEXCOORDMODE_CLAMP;
+    sampler_state->sampler1.ts1.tcz_control = TEXCOORDMODE_CLAMP;
+    sampler_state->sampler1.ts1.normalized_coor = 0;
+    sampler_state->sampler1.ts1.map_index = 1;
+    sampler_state->sampler1.ts1.east_deinterlacer = 0;
+    sampler_state->sampler1.ts2.default_color = 0;
+
+    memset(pixel_shader_program, 0, sizeof(*pixel_shader_program));
+    pixel_shader_program->shader0.type = CMD_3D;
+    pixel_shader_program->shader0.opcode = OPC_3DSTATE_PIXEL_SHADER_PROGRAM;
+    pixel_shader_program->shader0.retain = 1;
+    pixel_shader_program->shader0.length = 2; /* 1 inst */
+    i = 0;
+
+    dest = UREG(REG_TYPE_OC, 0);
+    src0 = UREG(REG_TYPE_CONST, 0);
+    src1 = 0;
+    src2 = 0;
+    i915_inst_arith(&pixel_shader_program->inst0[i], A0_MOV,
+	    dest, A0_DEST_CHANNEL_ALL, A0_DEST_SATURATE, src0, src1, src2);
+
+    pixel_shader_program->shader1.type = CMD_3D;
+    pixel_shader_program->shader1.opcode = OPC_3DSTATE_PIXEL_SHADER_PROGRAM;
+    pixel_shader_program->shader1.retain = 1;
+    pixel_shader_program->shader1.length = 14; /* 5 inst */
+    i = 0;
+    /* dcl t0.xy */
+    i915_inst_decl(&pixel_shader_program->inst1[i], REG_TYPE_T, T_TEX0, D0_CHANNEL_XY);
+    i+=3;
+    /* dcl t1.xy */
+    i915_inst_decl(&pixel_shader_program->inst1[i], REG_TYPE_T, T_TEX1, D0_CHANNEL_XY);
+    /* dcl_2D s0 */
+    i += 3;
+    i915_inst_decl(&pixel_shader_program->inst1[i], REG_TYPE_S, 0, D0_SAMPLE_TYPE_2D);
+    /* texld r0, t0, s0 */
+    i += 3;
+    dest = UREG(REG_TYPE_R, 0);
+    src0 = UREG(REG_TYPE_T, 0); /* COORD */
+    src1 = UREG(REG_TYPE_S, 0); /* SAMPLER */
+    i915_inst_texld(&pixel_shader_program->inst1[i], T0_TEXLD, dest, src0, src1);
+    /* mov oC, r0 */
+    i += 3;
+    dest = UREG(REG_TYPE_OC, 0);
+    src0 = UREG(REG_TYPE_R, 0);
+    src1 = src2 = 0;
+    i915_inst_arith(&pixel_shader_program->inst1[i], A0_MOV, dest, A0_DEST_CHANNEL_ALL,
+                    A0_DEST_SATURATE, src0, src1, src2);
+
+
+    pixel_shader_program->shader2.type = CMD_3D;
+    pixel_shader_program->shader2.opcode = OPC_3DSTATE_PIXEL_SHADER_PROGRAM;
+    pixel_shader_program->shader2.retain = 1;
+    pixel_shader_program->shader2.length = 14; /* 5 inst */
+    i = 0;
+    /* dcl t2.xy */
+    i915_inst_decl(&pixel_shader_program->inst2[i], REG_TYPE_T, T_TEX2, D0_CHANNEL_XY);
+    /* dcl t3.xy */
+    i += 3;
+    i915_inst_decl(&pixel_shader_program->inst2[i], REG_TYPE_T, T_TEX3, D0_CHANNEL_XY);
+    /* dcl_2D s1 */
+    i += 3;
+    i915_inst_decl(&pixel_shader_program->inst2[i], REG_TYPE_S, 1, D0_SAMPLE_TYPE_2D);
+    /* texld r0, t2, s1 */
+    i += 3;
+    dest = UREG(REG_TYPE_R, 0);
+    src0 = UREG(REG_TYPE_T, 2); /* COORD */
+    src1 = UREG(REG_TYPE_S, 1); /* SAMPLER */
+    i915_inst_texld(&pixel_shader_program->inst2[i], T0_TEXLD, dest, src0, src1);
+    /* mov oC, r0 */
+    i += 3;
+    dest = UREG(REG_TYPE_OC, 0);
+    src0 = UREG(REG_TYPE_R, 0);
+    src1 = src2 = 0;
+    i915_inst_arith(&pixel_shader_program->inst2[i], A0_MOV, dest, A0_DEST_CHANNEL_ALL,
+                    A0_DEST_SATURATE, src0, src1, src2);
+
+    /* Shader 3 */
+    pixel_shader_program->shader3.type = CMD_3D;
+    pixel_shader_program->shader3.opcode = OPC_3DSTATE_PIXEL_SHADER_PROGRAM;
+    pixel_shader_program->shader3.retain = 1;
+    pixel_shader_program->shader3.length = 29; /* 10 inst */
+    i = 0;
+    /* dcl t0.xy */
+    i915_inst_decl(&pixel_shader_program->inst3[i], REG_TYPE_T, T_TEX0, D0_CHANNEL_XY);
+    /* dcl t1.xy */
+    i += 3;
+    i915_inst_decl(&pixel_shader_program->inst3[i], REG_TYPE_T, T_TEX1, D0_CHANNEL_XY);
+    /* dcl t2.xy */
+    i += 3;
+    i915_inst_decl(&pixel_shader_program->inst3[i], REG_TYPE_T, T_TEX2, D0_CHANNEL_XY);
+    /* dcl t3.xy */
+    i += 3;
+    i915_inst_decl(&pixel_shader_program->inst3[i], REG_TYPE_T, T_TEX3, D0_CHANNEL_XY);
+    /* dcl_2D s0 */
+    i += 3;
+    i915_inst_decl(&pixel_shader_program->inst3[i], REG_TYPE_S, 0, D0_SAMPLE_TYPE_2D);
+    /* dcl_2D s1 */
+    i += 3;
+    i915_inst_decl(&pixel_shader_program->inst3[i], REG_TYPE_S, 1, D0_SAMPLE_TYPE_2D);
+    /* texld r0, t0, s0 */
+    i += 3;
+    dest = UREG(REG_TYPE_R, 0);
+    src0 = UREG(REG_TYPE_T, 0); /* COORD */
+    src1 = UREG(REG_TYPE_S, 0); /* SAMPLER */
+    i915_inst_texld(&pixel_shader_program->inst3[i], T0_TEXLD, dest, src0, src1);
+    /* texld r1, t2, s1 */
+    i += 3;
+    dest = UREG(REG_TYPE_R, 1);
+    src0 = UREG(REG_TYPE_T, 2); /* COORD */
+    src1 = UREG(REG_TYPE_S, 1); /* SAMPLER */
+    i915_inst_texld(&pixel_shader_program->inst3[i], T0_TEXLD, dest, src0, src1);
+    /* add r0, r0, r1 */
+    i += 3;
+    dest = UREG(REG_TYPE_R, 0);
+    src0 = UREG(REG_TYPE_R, 0);
+    src1 = UREG(REG_TYPE_R, 1);
+    src2 = 0;
+    i915_inst_arith(&pixel_shader_program->inst3[i], A0_ADD, dest, A0_DEST_CHANNEL_ALL,
+                    0 /* A0_DEST_SATURATE */, src0, src1, src2);
+    /* mul oC, r0, c0 */
+    i += 3;
+    dest = UREG(REG_TYPE_OC, 0);
+    src0 = UREG(REG_TYPE_R, 0);
+    src1 = UREG(REG_TYPE_CONST, 0);
+    src2 = 0;
+    i915_inst_arith(&pixel_shader_program->inst3[i], A0_MUL, dest, A0_DEST_CHANNEL_ALL,
+                    A0_DEST_SATURATE, src0, src1, src2);
+
+    memset(pixel_shader_constants, 0, sizeof(*pixel_shader_constants));
+    pixel_shader_constants->dw0.type = CMD_3D;
+    pixel_shader_constants->dw0.opcode = OPC_3DSTATE_PIXEL_SHADER_CONSTANTS;
+    pixel_shader_constants->dw0.length = 4;
+    pixel_shader_constants->dw1.reg_mask = REG_CR0;
+    pixel_shader_constants->value.x = 0.5;
+    pixel_shader_constants->value.y = 0.5;
+    pixel_shader_constants->value.z = 0.5;
+    pixel_shader_constants->value.w = 0.5;
+
+}
+
+static void i915_mc_one_time_state_init(XvMCContext *context)
+{
+    struct s3_dword *s3 = NULL;
+    struct s6_dword *s6 = NULL;
+    dis_state *dis = NULL;
+    ssb_state *ssb = NULL;
+    psp_state *psp = NULL;
+    psc_state *psc = NULL;
+    i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData;
+    int mem_select = 1;
+    struct i915_3dstate_load_state_immediate_1 *load_state_immediate_1;
+    struct i915_3dstate_load_indirect *load_indirect;
+
+    /* 3DSTATE_LOAD_STATE_IMMEDIATE_1 */
+    one_time_load_state_imm1_size = sizeof(*load_state_immediate_1) + sizeof(*s3) + sizeof(*s6);
+    one_time_load_state_imm1 = calloc(1, one_time_load_state_imm1_size);
+    load_state_immediate_1 = (struct i915_3dstate_load_state_immediate_1 *)one_time_load_state_imm1;
+    load_state_immediate_1->dw0.type = CMD_3D;
+    load_state_immediate_1->dw0.opcode = OPC_3DSTATE_LOAD_STATE_IMMEDIATE_1;
+    load_state_immediate_1->dw0.load_s3 = 1;
+    load_state_immediate_1->dw0.load_s6 = 1;
+    load_state_immediate_1->dw0.length = (one_time_load_state_imm1_size >> 2) - 2;
+
+    s3 = (struct s3_dword *)(++load_state_immediate_1);
+    s3->set0_pcd = 1;
+    s3->set1_pcd = 1;
+    s3->set2_pcd = 1;
+    s3->set3_pcd = 1;
+    s3->set4_pcd = 1;
+    s3->set5_pcd = 1;
+    s3->set6_pcd = 1;
+    s3->set7_pcd = 1;
+
+    s6 = (struct s6_dword *)(++s3);
+    s6->alpha_test_enable = 0;
+    s6->alpha_test_function = 0;
+    s6->alpha_reference_value = 0;
+    s6->depth_test_enable = 1;
+    s6->depth_test_function = 0;
+    s6->color_buffer_blend = 0;
+    s6->color_blend_function = 0;
+    s6->src_blend_factor = 1;
+    s6->dest_blend_factor = 1;
+    s6->depth_buffer_write = 0;
+    s6->color_buffer_write = 1;
+    s6->triangle_pv = 0;
+
+    /* 3DSTATE_LOAD_INDIRECT */
+    one_time_load_indirect_size = sizeof(*load_indirect) + sizeof(*dis) + sizeof(*ssb) + sizeof(*psp) + sizeof(*psc);
+    one_time_load_indirect = calloc(1, one_time_load_indirect_size);
+    load_indirect = (struct i915_3dstate_load_indirect *)one_time_load_indirect;
+    load_indirect->dw0.type = CMD_3D;
+    load_indirect->dw0.opcode = OPC_3DSTATE_LOAD_INDIRECT;
+    load_indirect->dw0.block_mask = BLOCK_DIS | BLOCK_SSB | BLOCK_PSP | BLOCK_PSC;
+    load_indirect->dw0.length = (one_time_load_indirect_size >> 2) - 2;
+
+    if (pI915XvMC->deviceID == PCI_CHIP_I915_G ||
+        pI915XvMC->deviceID == PCI_CHIP_I915_GM ||
+        pI915XvMC->deviceID == PCI_CHIP_I945_G ||
+        pI915XvMC->deviceID == PCI_CHIP_I945_GM)
+        mem_select = 0;
+
+    load_indirect->dw0.mem_select = mem_select;
+
+    /* Dynamic indirect state buffer */
+    dis = (dis_state *)(++load_indirect);
+    dis->dw0.valid = 0;
+    dis->dw0.reset = 0;
+    dis->dw0.buffer_address = 0;
+
+    /* Sample state buffer */
+    ssb = (ssb_state *)(++dis);
+    ssb->dw0.valid = 1;
+    ssb->dw0.force = 1;
+    ssb->dw1.length = 7; /* 8 - 1 */
+
+    if (mem_select)
+        ssb->dw0.buffer_address = (pI915XvMC->ssb.offset >> 2);
+    else
+        ssb->dw0.buffer_address = (pI915XvMC->ssb.bus_addr >> 2);
+
+    /* Pixel shader program buffer */
+    psp = (psp_state *)(++ssb);
+    psp->dw0.valid = 1;
+    psp->dw0.force = 1;
+    psp->dw1.length = 66; /* 4 + 16 + 16 + 31 - 1 */
+
+    if (mem_select)
+        psp->dw0.buffer_address = (pI915XvMC->psp.offset >> 2);
+    else
+        psp->dw0.buffer_address = (pI915XvMC->psp.bus_addr >> 2);
+
+    /* Pixel shader constant buffer */
+    psc = (psc_state *)(++psp);
+    psc->dw0.valid = 1;
+    psc->dw0.force = 1;
+    psc->dw1.length = 5; /* 6 - 1 */
+
+    if (mem_select)
+        psc->dw0.buffer_address = (pI915XvMC->psc.offset >> 2);
+    else
+        psc->dw0.buffer_address = (pI915XvMC->psc.bus_addr >> 2);
+}
+
+static void i915_mc_one_time_state_emit(void)
+{
+    i915_emit_batch(one_time_load_state_imm1, one_time_load_state_imm1_size, 0);
+    i915_emit_batch(one_time_load_indirect, one_time_load_indirect_size, 0);
+}
+
 static void i915_flush(int map, int render)
 {
     struct i915_mi_flush mi_flush;
@@ -582,392 +948,6 @@ static void i915_mc_mpeg_macroblock_2fbmv(XvMCContext *context, XvMCMacroBlock *
     intelBatchbufferData(&macroblock_2fbmv, sizeof(macroblock_2fbmv), 0);
 }
 
-/* for MC context initialization */
-static void i915_mc_sampler_state_buffer(XvMCContext *context)
-{
-    struct i915_3dstate_sampler_state *sampler_state;
-    struct texture_sampler *ts;
-    i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData;
-
-    /* 3DSATE_SAMPLER_STATE */
-    sampler_state = (struct i915_3dstate_sampler_state *)pI915XvMC->ssb.map;
-    memset(sampler_state, 0, sizeof(*sampler_state));
-    sampler_state->dw0.type = CMD_3D;
-    sampler_state->dw0.opcode = OPC_3DSTATE_SAMPLER_STATE;
-    sampler_state->dw0.length = 6;
-    sampler_state->dw1.sampler_masker = SAMPLER_SAMPLER0 | SAMPLER_SAMPLER1;
-
-    /* Sampler 0 */
-    ts = (struct texture_sampler *)(++sampler_state);
-    memset(ts, 0, sizeof(*ts));
-    ts->ts0.reverse_gamma = 0;
-    ts->ts0.planar2packet = 0;
-    ts->ts0.color_conversion = 0;
-    ts->ts0.chromakey_index = 0;
-    ts->ts0.base_level = 0;
-    ts->ts0.mip_filter = MIPFILTER_NONE;        /* NONE */
-    ts->ts0.mag_filter = MAPFILTER_LINEAR;      /* LINEAR */
-    ts->ts0.min_filter = MAPFILTER_LINEAR;      /* LINEAR */
-    ts->ts0.lod_bias = 0;       /* 0.0 */
-    ts->ts0.shadow_enable = 0;
-    ts->ts0.max_anisotropy = ANISORATIO_2;
-    ts->ts0.shadow_function = PREFILTEROP_ALWAYS;
-    ts->ts1.min_lod = 0;        /* 0.0 Maximum Mip Level */
-    ts->ts1.kill_pixel = 0;
-    ts->ts1.keyed_texture_filter = 0;
-    ts->ts1.chromakey_enable = 0;
-    ts->ts1.tcx_control = TEXCOORDMODE_CLAMP;
-    ts->ts1.tcy_control = TEXCOORDMODE_CLAMP;
-    ts->ts1.tcz_control = TEXCOORDMODE_CLAMP;
-    ts->ts1.normalized_coor = 0;
-    ts->ts1.map_index = 0;
-    ts->ts1.east_deinterlacer = 0;
-    ts->ts2.default_color = 0;
-
-    /* Sampler 1 */
-    ++ts;
-    memset(ts, 0, sizeof(*ts));
-    ts->ts0.reverse_gamma = 0;
-    ts->ts0.planar2packet = 0;
-    ts->ts0.color_conversion = 0;
-    ts->ts0.chromakey_index = 0;
-    ts->ts0.base_level = 0;
-    ts->ts0.mip_filter = MIPFILTER_NONE;        /* NONE */
-    ts->ts0.mag_filter = MAPFILTER_LINEAR;      /* LINEAR */
-    ts->ts0.min_filter = MAPFILTER_LINEAR;      /* LINEAR */
-    ts->ts0.lod_bias = 0;       /* 0.0 */
-    ts->ts0.shadow_enable = 0;
-    ts->ts0.max_anisotropy = ANISORATIO_2;
-    ts->ts0.shadow_function = PREFILTEROP_ALWAYS;
-    ts->ts1.min_lod = 0;        /* 0.0 Maximum Mip Level */
-    ts->ts1.kill_pixel = 0;
-    ts->ts1.keyed_texture_filter = 0;
-    ts->ts1.chromakey_enable = 0;
-    ts->ts1.tcx_control = TEXCOORDMODE_CLAMP;
-    ts->ts1.tcy_control = TEXCOORDMODE_CLAMP;
-    ts->ts1.tcz_control = TEXCOORDMODE_CLAMP;
-    ts->ts1.normalized_coor = 0;
-    ts->ts1.map_index = 1;
-    ts->ts1.east_deinterlacer = 0;
-    ts->ts2.default_color = 0;
-}
-
-static void i915_inst_arith(unsigned int *inst,
-                            unsigned int op,
-                            unsigned int dest,
-                            unsigned int mask,
-                            unsigned int saturate,
-                            unsigned int src0, unsigned int src1, unsigned int src2)
-{
-    dest = UREG(GET_UREG_TYPE(dest), GET_UREG_NR(dest));
-    *inst = (op | A0_DEST(dest) | mask | saturate | A0_SRC0(src0));
-    inst++;
-    *inst = (A1_SRC0(src0) | A1_SRC1(src1));
-    inst++;
-    *inst = (A2_SRC1(src1) | A2_SRC2(src2));
-}
-
-static void i915_inst_decl(unsigned int *inst,
-                           unsigned int type,
-                           unsigned int nr,
-                           unsigned int d0_flags)
-{
-    unsigned int reg = UREG(type, nr);
-
-    *inst = (D0_DCL | D0_DEST(reg) | d0_flags);
-    inst++;
-    *inst = D1_MBZ;
-    inst++;
-    *inst = D2_MBZ;
-}
-
-static void i915_inst_texld(unsigned int *inst,
-                              unsigned int op,
-                              unsigned int dest,
-                              unsigned int coord,
-                              unsigned int sampler)
-{
-   dest = UREG(GET_UREG_TYPE(dest), GET_UREG_NR(dest));
-   *inst = (op | T0_DEST(dest) | T0_SAMPLER(sampler));
-   inst++;
-   *inst = T1_ADDRESS_REG(coord);
-   inst++;
-   *inst = T2_MBZ;
-}
-
-static void i915_mc_pixel_shader_program_buffer(XvMCContext *context)
-{
-    struct i915_3dstate_pixel_shader_program *pixel_shader_program;
-    i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData;
-    unsigned int *inst;
-    unsigned int dest, src0, src1, src2;
-
-    /* Shader 0 */
-    pixel_shader_program = (struct i915_3dstate_pixel_shader_program *)pI915XvMC->psp.map;
-    memset(pixel_shader_program, 0, sizeof(*pixel_shader_program));
-    pixel_shader_program->dw0.type = CMD_3D;
-    pixel_shader_program->dw0.opcode = OPC_3DSTATE_PIXEL_SHADER_PROGRAM;
-    pixel_shader_program->dw0.retain = 1;
-    pixel_shader_program->dw0.length = 2;
-    /* mov oC, c0.0000 */
-    inst = (unsigned int*)(++pixel_shader_program);
-    dest = UREG(REG_TYPE_OC, 0);
-    src0 = UREG(REG_TYPE_CONST, 0);
-    src1 = 0;
-    src2 = 0;
-    i915_inst_arith(inst, A0_MOV, dest, A0_DEST_CHANNEL_ALL,
-                    A0_DEST_SATURATE, src0, src1, src2);
-    inst += 3;
-
-    /* Shader 1 */
-    pixel_shader_program = (struct i915_3dstate_pixel_shader_program *)inst;
-    memset(pixel_shader_program, 0, sizeof(*pixel_shader_program));
-    pixel_shader_program->dw0.type = CMD_3D;
-    pixel_shader_program->dw0.opcode = OPC_3DSTATE_PIXEL_SHADER_PROGRAM;
-    pixel_shader_program->dw0.retain = 1;
-    pixel_shader_program->dw0.length = 14;
-    /* dcl t0.xy */
-    inst = (unsigned int*)(++pixel_shader_program);
-    i915_inst_decl(inst, REG_TYPE_T, T_TEX0, D0_CHANNEL_XY);
-    /* dcl t1.xy */
-    inst += 3;
-    i915_inst_decl(inst, REG_TYPE_T, T_TEX1, D0_CHANNEL_XY);
-    /* dcl_2D s0 */
-    inst += 3;
-    i915_inst_decl(inst, REG_TYPE_S, 0, D0_SAMPLE_TYPE_2D);
-    /* texld r0, t0, s0 */
-    inst += 3;
-    dest = UREG(REG_TYPE_R, 0);
-    src0 = UREG(REG_TYPE_T, 0); /* COORD */
-    src1 = UREG(REG_TYPE_S, 0); /* SAMPLER */
-    i915_inst_texld(inst, T0_TEXLD, dest, src0, src1);
-    /* mov oC, r0 */
-    inst += 3;
-    dest = UREG(REG_TYPE_OC, 0);
-    src0 = UREG(REG_TYPE_R, 0);
-    src1 = src2 = 0;
-    i915_inst_arith(inst, A0_MOV, dest, A0_DEST_CHANNEL_ALL,
-                    A0_DEST_SATURATE, src0, src1, src2);
-    inst += 3;
-
-    /* Shader 2 */
-    pixel_shader_program = (struct i915_3dstate_pixel_shader_program *)inst;
-    memset(pixel_shader_program, 0, sizeof(*pixel_shader_program));
-    pixel_shader_program->dw0.type = CMD_3D;
-    pixel_shader_program->dw0.opcode = OPC_3DSTATE_PIXEL_SHADER_PROGRAM;
-    pixel_shader_program->dw0.retain = 1;
-    pixel_shader_program->dw0.length = 14;
-    /* dcl t2.xy */
-    inst = (unsigned int*)(++pixel_shader_program);
-    i915_inst_decl(inst, REG_TYPE_T, T_TEX2, D0_CHANNEL_XY);
-    /* dcl t3.xy */
-    inst += 3;
-    i915_inst_decl(inst, REG_TYPE_T, T_TEX3, D0_CHANNEL_XY);
-    /* dcl_2D s1 */
-    inst += 3;
-    i915_inst_decl(inst, REG_TYPE_S, 1, D0_SAMPLE_TYPE_2D);
-    /* texld r0, t2, s1 */
-    inst += 3;
-    dest = UREG(REG_TYPE_R, 0);
-    src0 = UREG(REG_TYPE_T, 2); /* COORD */
-    src1 = UREG(REG_TYPE_S, 1); /* SAMPLER */
-    i915_inst_texld(inst, T0_TEXLD, dest, src0, src1);
-    /* mov oC, r0 */
-    inst += 3;
-    dest = UREG(REG_TYPE_OC, 0);
-    src0 = UREG(REG_TYPE_R, 0);
-    src1 = src2 = 0;
-    i915_inst_arith(inst, A0_MOV, dest, A0_DEST_CHANNEL_ALL,
-                    A0_DEST_SATURATE, src0, src1, src2);
-    inst += 3;
-
-    /* Shader 3 */
-    pixel_shader_program = (struct i915_3dstate_pixel_shader_program *)inst;
-    memset(pixel_shader_program, 0, sizeof(*pixel_shader_program));
-    pixel_shader_program->dw0.type = CMD_3D;
-    pixel_shader_program->dw0.opcode = OPC_3DSTATE_PIXEL_SHADER_PROGRAM;
-    pixel_shader_program->dw0.retain = 1;
-    pixel_shader_program->dw0.length = 29;
-    /* dcl t0.xy */
-    inst = (unsigned int*)(++pixel_shader_program);
-    i915_inst_decl(inst, REG_TYPE_T, T_TEX0, D0_CHANNEL_XY);
-    /* dcl t1.xy */
-    inst += 3;
-    i915_inst_decl(inst, REG_TYPE_T, T_TEX1, D0_CHANNEL_XY);
-    /* dcl t2.xy */
-    inst += 3;
-    i915_inst_decl(inst, REG_TYPE_T, T_TEX2, D0_CHANNEL_XY);
-    /* dcl t3.xy */
-    inst += 3;
-    i915_inst_decl(inst, REG_TYPE_T, T_TEX3, D0_CHANNEL_XY);
-    /* dcl_2D s0 */
-    inst += 3;
-    i915_inst_decl(inst, REG_TYPE_S, 0, D0_SAMPLE_TYPE_2D);
-    /* dcl_2D s1 */
-    inst += 3;
-    i915_inst_decl(inst, REG_TYPE_S, 1, D0_SAMPLE_TYPE_2D);
-    /* texld r0, t0, s0 */
-    inst += 3;
-    dest = UREG(REG_TYPE_R, 0);
-    src0 = UREG(REG_TYPE_T, 0); /* COORD */
-    src1 = UREG(REG_TYPE_S, 0); /* SAMPLER */
-    i915_inst_texld(inst, T0_TEXLD, dest, src0, src1);
-    /* texld r1, t2, s1 */
-    inst += 3;
-    dest = UREG(REG_TYPE_R, 1);
-    src0 = UREG(REG_TYPE_T, 2); /* COORD */
-    src1 = UREG(REG_TYPE_S, 1); /* SAMPLER */
-    i915_inst_texld(inst, T0_TEXLD, dest, src0, src1);
-    /* add r0, r0, r1 */
-    inst += 3;
-    dest = UREG(REG_TYPE_R, 0);
-    src0 = UREG(REG_TYPE_R, 0);
-    src1 = UREG(REG_TYPE_R, 1);
-    src2 = 0;
-    i915_inst_arith(inst, A0_ADD, dest, A0_DEST_CHANNEL_ALL,
-                    0 /* A0_DEST_SATURATE */, src0, src1, src2);
-    /* mul oC, r0, c0 */
-    inst += 3;
-    dest = UREG(REG_TYPE_OC, 0);
-    src0 = UREG(REG_TYPE_R, 0);
-    src1 = UREG(REG_TYPE_CONST, 0);
-    src2 = 0;
-    i915_inst_arith(inst, A0_MUL, dest, A0_DEST_CHANNEL_ALL,
-                    A0_DEST_SATURATE, src0, src1, src2);
-    inst += 3;
-}
-
-static void i915_mc_pixel_shader_constants_buffer(XvMCContext *context)
-{
-    struct i915_3dstate_pixel_shader_constants *pixel_shader_constants;
-    i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData;
-    float *value;
-
-    pixel_shader_constants = (struct i915_3dstate_pixel_shader_constants *)pI915XvMC->psc.map;
-    memset(pixel_shader_constants, 0, sizeof(*pixel_shader_constants));
-    pixel_shader_constants->dw0.type = CMD_3D;
-    pixel_shader_constants->dw0.opcode = OPC_3DSTATE_PIXEL_SHADER_CONSTANTS;
-    pixel_shader_constants->dw0.length = 4;
-    pixel_shader_constants->dw1.reg_mask = REG_CR0;
-    value = (float *)(++pixel_shader_constants);
-    *(value++) = 0.5;
-    *(value++) = 0.5;
-    *(value++) = 0.5;
-    *(value++) = 0.5;
-}
-
-static void i915_mc_one_time_state_initialization(XvMCContext *context)
-{
-    struct i915_3dstate_load_state_immediate_1 *load_state_immediate_1 = NULL;
-    struct s3_dword *s3 = NULL;
-    struct s6_dword *s6 = NULL;
-    struct i915_3dstate_load_indirect *load_indirect = NULL;
-    dis_state *dis = NULL;
-    ssb_state *ssb = NULL;
-    psp_state *psp = NULL;
-    psc_state *psc = NULL;
-    i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData;
-    unsigned int size;
-    void *base = NULL;
-    int mem_select = 1;
-
-    /* 3DSTATE_LOAD_STATE_IMMEDIATE_1 */
-    size = sizeof(*load_state_immediate_1) + sizeof(*s3) + sizeof(*s6);
-    base = calloc(1, size);
-    load_state_immediate_1 = (struct i915_3dstate_load_state_immediate_1 *)base;
-    load_state_immediate_1->dw0.type = CMD_3D;
-    load_state_immediate_1->dw0.opcode = OPC_3DSTATE_LOAD_STATE_IMMEDIATE_1;
-    load_state_immediate_1->dw0.load_s3 = 1;
-    load_state_immediate_1->dw0.load_s6 = 1;
-    load_state_immediate_1->dw0.length = (size >> 2) - 2;
-
-    s3 = (struct s3_dword *)(++load_state_immediate_1);
-    s3->set0_pcd = 1;
-    s3->set1_pcd = 1;
-    s3->set2_pcd = 1;
-    s3->set3_pcd = 1;
-    s3->set4_pcd = 1;
-    s3->set5_pcd = 1;
-    s3->set6_pcd = 1;
-    s3->set7_pcd = 1;
-
-    s6 = (struct s6_dword *)(++s3);
-    s6->alpha_test_enable = 0;
-    s6->alpha_test_function = 0;
-    s6->alpha_reference_value = 0;
-    s6->depth_test_enable = 1;
-    s6->depth_test_function = 0;
-    s6->color_buffer_blend = 0;
-    s6->color_blend_function = 0;
-    s6->src_blend_factor = 1;
-    s6->dest_blend_factor = 1;
-    s6->depth_buffer_write = 0;
-    s6->color_buffer_write = 1;
-    s6->triangle_pv = 0;
-
-    intelBatchbufferData(base, size, 0);
-    free(base);
-
-    /* 3DSTATE_LOAD_INDIRECT */
-    size = sizeof(*load_indirect) + sizeof(*dis) + sizeof(*ssb) + sizeof(*psp) + sizeof(*psc);
-    base = calloc(1, size);
-    load_indirect = (struct i915_3dstate_load_indirect *)base;
-    load_indirect->dw0.type = CMD_3D;
-    load_indirect->dw0.opcode = OPC_3DSTATE_LOAD_INDIRECT;
-    load_indirect->dw0.block_mask = BLOCK_DIS | BLOCK_SSB | BLOCK_PSP | BLOCK_PSC;
-    load_indirect->dw0.length = (size >> 2) - 2;
-
-    if (pI915XvMC->deviceID == PCI_CHIP_I915_G ||
-        pI915XvMC->deviceID == PCI_CHIP_I915_GM ||
-        pI915XvMC->deviceID == PCI_CHIP_I945_G ||
-        pI915XvMC->deviceID == PCI_CHIP_I945_GM)
-        mem_select = 0;
-
-    load_indirect->dw0.mem_select = mem_select;
-
-    /* DIS */
-    dis = (dis_state *)(++load_indirect);
-    dis->dw0.valid = 0;
-    dis->dw0.reset = 0;
-    dis->dw0.buffer_address = 0;
-
-    /* SSB */
-    ssb = (ssb_state *)(++dis);
-    ssb->dw0.valid = 1;
-    ssb->dw0.force = 1;
-    ssb->dw1.length = 7; /* 8 - 1 */
-
-    if (mem_select)
-        ssb->dw0.buffer_address = (pI915XvMC->ssb.offset >> 2);
-    else
-        ssb->dw0.buffer_address = (pI915XvMC->ssb.bus_addr >> 2);
-
-    /* PSP */
-    psp = (psp_state *)(++ssb);
-    psp->dw0.valid = 1;
-    psp->dw0.force = 1;
-    psp->dw1.length = 66; /* 4 + 16 + 16 + 31 - 1 */
-
-    if (mem_select)
-        psp->dw0.buffer_address = (pI915XvMC->psp.offset >> 2);
-    else
-        psp->dw0.buffer_address = (pI915XvMC->psp.bus_addr >> 2);
-
-    /* PSC */
-    psc = (psc_state *)(++psp);
-    psc->dw0.valid = 1;
-    psc->dw0.force = 1;
-    psc->dw1.length = 5; /* 6 - 1 */
-
-    if (mem_select)
-        psc->dw0.buffer_address = (pI915XvMC->psc.offset >> 2);
-    else
-        psc->dw0.buffer_address = (pI915XvMC->psc.bus_addr >> 2);
-
-    intelBatchbufferData(base, size, 0);
-    free(base);
-}
-
 #if 0
 static void i915_mc_invalidate_subcontext_buffers(XvMCContext *context, unsigned int mask)
 {
@@ -1683,6 +1663,11 @@ static Status i915_xvmc_mc_create_context(Display *display, XvMCContext *context
     pI915XvMC->last_flip = 0;
     pI915XvMC->port = context->port;
     pI915XvMC->ref = 1;
+
+    /* preinit state buffers */
+    i915_mc_one_time_context_init(context);
+    i915_mc_one_time_state_init(context);
+
     return Success;
 }
 
@@ -1695,6 +1680,9 @@ static int i915_xvmc_mc_destroy_context(Display *display, XvMCContext *context)
 
     /* Pass Control to the X server to destroy the drm_context_t */
     i915_release_resource(display,context);
+
+    free(one_time_load_state_imm1);
+    free(one_time_load_indirect);
     return Success;
 }
 
@@ -1937,10 +1925,7 @@ static int i915_xvmc_mc_render_surface(Display *display, XvMCContext *context,
     // i915_mc_invalidate_subcontext_buffers(context, BLOCK_SIS | BLOCK_DIS | BLOCK_SSB
     // | BLOCK_MSB | BLOCK_PSP | BLOCK_PSC);
 
-    i915_mc_sampler_state_buffer(context);
-    i915_mc_pixel_shader_program_buffer(context);
-    i915_mc_pixel_shader_constants_buffer(context);
-    i915_mc_one_time_state_initialization(context);
+    i915_mc_one_time_state_emit();
 
     i915_mc_static_indirect_state_buffer(context, target_surface,
                                          picture_structure, flags,
diff --git a/src/xvmc/intel_xvmc.h b/src/xvmc/intel_xvmc.h
index 4d8b605..c4dfd77 100644
--- a/src/xvmc/intel_xvmc.h
+++ b/src/xvmc/intel_xvmc.h
@@ -38,6 +38,7 @@
 #include <string.h>
 #include <assert.h>
 #include <signal.h>
+#include <stdint.h>
 
 #include <xf86drm.h>
 #include "i830_common.h"
commit 54f3f528e4804b958936ac773e7a507b2676f815
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Mon Jun 23 15:51:49 2008 +0800

    xvmc: environ debug option support
    
    export INTEL_XVMC_DEBUG=1

diff --git a/src/xvmc/intel_xvmc.c b/src/xvmc/intel_xvmc.c
index 0db3ca6..8fabb35 100644
--- a/src/xvmc/intel_xvmc.c
+++ b/src/xvmc/intel_xvmc.c
@@ -98,9 +98,17 @@ unsigned int mb_bytes_420[] = {
     768  /* 111111 */
 };
 
+int DEBUG;
+
 static int error_base;
 static int event_base;
 
+static void intel_xvmc_debug_init(void)
+{
+    if (getenv("INTEL_XVMC_DEBUG"))
+	DEBUG = 1;
+}
+
 /* locking */
 static void intel_xvmc_try_heavy_lock(drm_context_t ctx)
 {
@@ -282,6 +290,8 @@ Status XvMCCreateContext(Display *display, XvPortID port,
         return BadValue;
     }
 
+    intel_xvmc_debug_init();
+
     /* Open DRI Device */
     if((fd = drmOpen("i915", NULL)) < 0) {
         XVMC_ERR("DRM Device could not be opened.");
diff --git a/src/xvmc/intel_xvmc.h b/src/xvmc/intel_xvmc.h
index 3119623..4d8b605 100644
--- a/src/xvmc/intel_xvmc.h
+++ b/src/xvmc/intel_xvmc.h
@@ -56,7 +56,7 @@
 
 #include "intel_batchbuffer.h"
 
-#define DEBUG 0
+extern int DEBUG;
 
 #define XVMC_ERR(s, arg...)					\
     do {							\
commit 7a705081788bf957409e17baa5f189241589057c
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Mon Jun 23 15:49:29 2008 +0800

    xvmc: formalize surface type definition
    
    We should also carefully select surface type id.

diff --git a/src/i830_hwmc.h b/src/i830_hwmc.h
index 6920e01..4db9aea 100644
--- a/src/i830_hwmc.h
+++ b/src/i830_hwmc.h
@@ -47,6 +47,13 @@
 #define XVMC_I945_MPEG2_VLD	0x04
 #define XVMC_I965_MPEG2_VLD	0x08
 
+/* supported surface types */
+enum {
+    SURFACE_TYPE_MPEG2_MPML = FOURCC_XVMC, /* mpeg2 MP at ML */
+    SURFACE_TYPE_MPEG1_MPML,		   /* mpeg1 MP at ML */
+    SURFACE_TYPE_MAX
+};
+
 /* common header for context private */
 struct hwmc_buffer
 {
diff --git a/src/i915_hwmc.c b/src/i915_hwmc.c
index 50e1106..973cabf 100644
--- a/src/i915_hwmc.c
+++ b/src/i915_hwmc.c
@@ -111,7 +111,7 @@ static XF86MCImageIDList yv12_subpicture_list =
 
 static XF86MCSurfaceInfoRec i915_YV12_mpg2_surface =
 {
-    FOURCC_YV12,
+    SURFACE_TYPE_MPEG2_MPML,
     XVMC_CHROMA_FORMAT_420,
     0,
     720,
@@ -127,7 +127,7 @@ static XF86MCSurfaceInfoRec i915_YV12_mpg2_surface =
 
 static XF86MCSurfaceInfoRec i915_YV12_mpg1_surface =
 {
-    FOURCC_YV12,
+    SURFACE_TYPE_MPEG1_MPML,
     XVMC_CHROMA_FORMAT_420,
     0,
     720,
diff --git a/src/xvmc/i915_xvmc.c b/src/xvmc/i915_xvmc.c
index 519de5a..bd31de4 100644
--- a/src/xvmc/i915_xvmc.c
+++ b/src/xvmc/i915_xvmc.c
@@ -1850,9 +1850,8 @@ static int i915_xvmc_mc_render_surface(Display *display, XvMCContext *context,
     if (!(privTarget = target_surface->privData))
         return XvMCBadSurface;
 
-    /* Test For YV12 Surface */
-    if (context->surface_type_id != FOURCC_YV12) {
-        XVMC_ERR("HWMC only possible on YV12 Surfaces.");
+    if (context->surface_type_id >= SURFACE_TYPE_MAX) {
+        XVMC_ERR("Unsupprted surface_type_id %d.", context->surface_type_id);
         return BadValue;
     }
 
commit 0283d22f510ba47dfdac2806a58e46649c26580b
Author: Jesse Barnes <jbarnes at jbarnes-t61.(none)>
Date:   Fri Jun 27 13:39:31 2008 -0700

    Add pipea force enable quirk for HP Pavilion ze4944ea
    
    Fixes bug #16540, thanks Bryce.

diff --git a/src/i830_quirks.c b/src/i830_quirks.c
index 1beda4b..f7659f0 100644
--- a/src/i830_quirks.c
+++ b/src/i830_quirks.c
@@ -267,6 +267,8 @@ static i830_quirk i830_quirk_list[] = {
 
     /* HP Compaq 6730s has no TV output */
     { PCI_CHIP_IGD_GM, 0x103c, 0x30e8, quirk_ignore_tv },
+    /* HP Pavilion ze4944ea needs pipe A force quirk (See LP: #242389) */
+    { PCI_CHIP_IGD_GM, 0x103c, 0x3084, quirk_pipea_force },
 
     /* Thinkpad R31 needs pipe A force quirk */
     { PCI_CHIP_I830_M, 0x1014, 0x0505, quirk_pipea_force },
commit 08903abe4dc0295c7ed7d1ff1a22e0e579540c15
Author: Jesse Barnes <jbarnes at jbarnes-t61.(none)>
Date:   Fri Jun 27 13:37:10 2008 -0700

    Add pipe a force enable quirk for Lenovo T60
    
    Fixes bug #16494.

diff --git a/src/i830_quirks.c b/src/i830_quirks.c
index 1bd8885..1beda4b 100644
--- a/src/i830_quirks.c
+++ b/src/i830_quirks.c
@@ -288,6 +288,9 @@ static i830_quirk i830_quirk_list[] = {
     /* ThinkPad X40 needs pipe A force quirk */
     { PCI_CHIP_I855_GM, 0x1014, 0x0557, quirk_pipea_force },
 
+    /* ThinkPad T60 needs pipe A force quirk (bug #16494) */
+    { PCI_CHIP_I945_GM, 0x17aa, 0x201a, quirk_pipea_force },
+
     /* Sony vaio PCG-r600HFP (fix bug 13722) */
     { PCI_CHIP_I830_M, 0x104d, 0x8100, quirk_ivch_dvob },
     /* Sony vaio VGN-SZ4MN (See LP: #212163) */
commit 05df8c0b31721a9ccc7215fb1cda1115758367c7
Author: Hong Liu <hong.liu at intel.com>
Date:   Fri Jun 20 10:57:14 2008 +0800

    Fix SDVO HDMI output.
    
    While some cards had enough initialized at startup to work already, others
    required that the driver actually initialize the required AVI info frame.

diff --git a/src/i830_sdvo.c b/src/i830_sdvo.c
index cdfc9c6..d9b76d4 100644
--- a/src/i830_sdvo.c
+++ b/src/i830_sdvo.c
@@ -92,6 +92,9 @@ struct i830_sdvo_priv {
      */
     struct i830_sdvo_tv_format tv_format;
 
+    /** supported encoding mode, used to determine whether HDMI is supported */
+    struct i830_sdvo_encode encode;
+
     /** DDC bus used by this SDVO output */
     uint8_t ddc_bus;
 
@@ -229,6 +232,19 @@ const static struct _sdvo_cmd_name {
     SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_CONTROL_BUS_SWITCH),
     SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SDTV_RESOLUTION_SUPPORT),
     SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SUPPORTED_ENHANCEMENTS),
+    /* HDMI op code */
+    SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SUPP_ENCODE),
+    SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_ENCODE),
+    SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_PIXEL_REPLI),
+    SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_COLORIMETRY_CAP),
+    SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_COLORIMETRY),
+    SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_AUDIO_ENCRYPT_PREFER),
+    SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_AUDIO_STAT),
+    SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HBUF_INDEX),
+    SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_HBUF_INDEX),
+    SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HBUF_INFO),
+    SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HBUF_AV_SPLIT),
+    SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HBUF_TXRATE),
 };
 
 static I2CSlaveAddr slaveAddr;
@@ -741,6 +757,190 @@ i830_sdvo_get_mode_from_dtd(DisplayModePtr mode, struct i830_sdvo_dtd *dtd)
 }
 
 static Bool
+i830_sdvo_get_supp_encode(xf86OutputPtr output, struct i830_sdvo_encode *encode)
+{
+    uint8_t status;
+
+    i830_sdvo_write_cmd(output, SDVO_CMD_GET_SUPP_ENCODE, NULL, 0);
+    status = i830_sdvo_read_response(output, encode, sizeof(*encode));
+    if (status != SDVO_CMD_STATUS_SUCCESS) {
+	memset(encode, 0, sizeof(*encode));
+	return FALSE;
+    }
+
+    return TRUE;
+}
+
+static Bool
+i830_sdvo_set_encode(xf86OutputPtr output, uint8_t mode)
+{
+    uint8_t status;
+
+    i830_sdvo_write_cmd(output, SDVO_CMD_SET_ENCODE, &mode, 1);
+    status = i830_sdvo_read_response(output, NULL, 0);
+
+    return (status == SDVO_CMD_STATUS_SUCCESS);
+}
+
+static Bool
+i830_sdvo_set_colorimetry(xf86OutputPtr output, uint8_t mode)
+{
+    uint8_t status;
+
+    i830_sdvo_write_cmd(output, SDVO_CMD_SET_COLORIMETRY, &mode, 1);
+    status = i830_sdvo_read_response(output, NULL, 0);
+
+    return (status == SDVO_CMD_STATUS_SUCCESS);
+}
+
+#if 0
+static Bool
+i830_sdvo_set_pixel_repli(xf86OutputPtr output, uint8_t repli)
+{
+    uint8_t status;
+
+    i830_sdvo_write_cmd(output, SDVO_CMD_SET_PIXEL_REPLI, &repli, 1);
+    status = i830_sdvo_read_response(output, NULL, 0);
+
+    return (status == SDVO_CMD_STATUS_SUCCESS);
+}
+#endif
+
+static void i830_sdvo_dump_hdmi_buf(xf86OutputPtr output)
+{
+    int i, j;
+    uint8_t set_buf_index[2];
+    uint8_t av_split;
+    uint8_t buf_size;
+    uint8_t buf[48];
+    uint8_t *pos;
+
+    i830_sdvo_write_cmd(output, SDVO_CMD_GET_HBUF_AV_SPLIT, NULL, 0);
+    i830_sdvo_read_response(output, &av_split, 1);
+
+    for (i = 0; i <= av_split; i++) {
+	set_buf_index[0] = i; set_buf_index[1] = 0;
+	i830_sdvo_write_cmd(output, SDVO_CMD_SET_HBUF_INDEX,
+				set_buf_index, 2);
+	i830_sdvo_write_cmd(output, SDVO_CMD_GET_HBUF_INFO, NULL, 0);
+	i830_sdvo_read_response(output, &buf_size, 1);
+
+	pos = buf;
+	for (j = 0; j <= buf_size; j += 8) {
+	    i830_sdvo_write_cmd(output, SDVO_CMD_GET_HBUF_DATA, NULL, 0);
+	    i830_sdvo_read_response(output, pos, 8);
+	    pos += 8;
+	}
+    }
+}
+
+static void i830_sdvo_set_hdmi_buf(xf86OutputPtr output, int index,
+				uint8_t *data, int8_t size, uint8_t tx_rate)
+{
+    uint8_t set_buf_index[2];
+
+    set_buf_index[0] = index;
+    set_buf_index[1] = 0;
+
+    i830_sdvo_write_cmd(output, SDVO_CMD_SET_HBUF_INDEX, set_buf_index, 2);
+
+    for (; size > 0; size -= 8) {
+	i830_sdvo_write_cmd(output, SDVO_CMD_SET_HBUF_DATA, data, 8);
+	data += 8;
+    }
+
+    i830_sdvo_write_cmd(output, SDVO_CMD_SET_HBUF_TXRATE, &tx_rate, 1);
+}
+
+static uint8_t i830_sdvo_calc_hbuf_csum(uint8_t *data, uint8_t size)
+{
+    uint8_t csum = 0;
+    int i;
+
+    for (i = 0; i < size; i++)
+	csum += data[i];
+
+    return 0x100 - csum;
+}
+
+#define DIP_TYPE_AVI	0x82
+#define DIP_VERSION_AVI	0x2
+#define DIP_LEN_AVI	13
+
+struct dip_infoframe {
+    uint8_t type;
+    uint8_t version;
+    uint8_t len;
+    uint8_t checksum;
+    union {
+	struct {
+	    /* Packet Byte #1 */
+	    uint8_t S:2;
+	    uint8_t B:2;
+	    uint8_t A:1;
+	    uint8_t Y:2;
+	    uint8_t rsvd1:1;
+	    /* Packet Byte #2 */
+	    uint8_t R:4;
+	    uint8_t M:2;
+	    uint8_t C:2;
+	    /* Packet Byte #3 */
+	    uint8_t SC:2;
+	    uint8_t Q:2;
+	    uint8_t EC:3;
+	    uint8_t ITC:1;
+	    /* Packet Byte #4 */
+	    uint8_t VIC:7;
+	    uint8_t rsvd2:1;
+	    /* Packet Byte #5 */
+	    uint8_t PR:4;
+	    uint8_t rsvd3:4;
+	    /* Packet Byte #6~13 */
+	    uint16_t top_bar_end;
+	    uint16_t bottom_bar_start;
+	    uint16_t left_bar_end;
+	    uint16_t right_bar_start;
+	} avi;
+	struct {
+	    /* Packet Byte #1 */
+	    uint8_t CC:3;
+	    uint8_t rsvd1:1;
+	    uint8_t CT:4;
+	    /* Packet Byte #2 */
+	    uint8_t SS:2;
+	    uint8_t SF:3;
+	    uint8_t rsvd2:3;
+	    /* Packet Byte #3 */
+	    uint8_t CXT:5;
+	    uint8_t rsvd3:3;
+	    /* Packet Byte #4 */
+	    uint8_t CA;
+	    /* Packet Byte #5 */
+	    uint8_t rsvd4:3;
+	    uint8_t LSV:4;
+	    uint8_t DM_INH:1;
+	} audio;
+	uint8_t payload[28];
+    } __attribute__ ((packed)) u;
+} __attribute__((packed));
+
+static void i830_sdvo_set_avi_infoframe(xf86OutputPtr output,
+					DisplayModePtr mode)
+{
+    struct dip_infoframe avi_if = {
+	.type = DIP_TYPE_AVI,
+	.version = DIP_VERSION_AVI,
+	.len = DIP_LEN_AVI,
+    };
+
+    avi_if.u.avi.PR = i830_sdvo_get_pixel_multiplier(mode) - 1;
+    avi_if.checksum = i830_sdvo_calc_hbuf_csum((uint8_t *)&avi_if,
+					4 + avi_if.len);
+    i830_sdvo_set_hdmi_buf(output, 1, (uint8_t *)&avi_if, 4 + avi_if.len,
+			SDVO_HBUF_TX_VSYNC);
+}
+
+static Bool
 i830_sdvo_mode_fixup(xf86OutputPtr output, DisplayModePtr mode,
 		     DisplayModePtr adjusted_mode)
 {
@@ -827,6 +1027,9 @@ i830_sdvo_mode_set(xf86OutputPtr output, DisplayModePtr mode,
 			&in_out, sizeof(in_out));
     status = i830_sdvo_read_response(output, NULL, 0);
 
+    if (dev_priv->encode.hdmi_rev)
+	i830_sdvo_set_avi_infoframe(output, mode);
+
     i830_sdvo_get_dtd_from_mode(&input_dtd, mode);
 
     /* If it's a TV, we already set the output timing in mode_fixup.
@@ -1203,6 +1406,15 @@ i830_sdvo_dump_device(xf86OutputPtr output)
     i830_sdvo_dump_cmd(output, SDVO_CMD_GET_TV_FORMAT);
     i830_sdvo_dump_cmd(output, SDVO_CMD_GET_SDTV_RESOLUTION_SUPPORT);
     i830_sdvo_dump_cmd(output, SDVO_CMD_GET_SUPPORTED_ENHANCEMENTS);
+
+    i830_sdvo_dump_cmd(output, SDVO_CMD_GET_SUPP_ENCODE);
+    i830_sdvo_dump_cmd(output, SDVO_CMD_GET_ENCODE);
+    i830_sdvo_dump_cmd(output, SDVO_CMD_GET_PIXEL_REPLI);
+    i830_sdvo_dump_cmd(output, SDVO_CMD_GET_COLORIMETRY_CAP);
+    i830_sdvo_dump_cmd(output, SDVO_CMD_GET_COLORIMETRY);
+    i830_sdvo_dump_cmd(output, SDVO_CMD_GET_AUDIO_ENCRYPT_PREFER);
+    i830_sdvo_dump_cmd(output, SDVO_CMD_GET_AUDIO_STAT);
+    i830_sdvo_dump_hdmi_buf(output);
 }
 
 void
@@ -1621,17 +1833,22 @@ i830_sdvo_init(ScrnInfoPtr pScrn, int output_device)
 
     i830_sdvo_get_capabilities(output, &dev_priv->caps);
 
-    if (dev_priv->caps.output_flags & SDVO_OUTPUT_TMDS0)
-    {
-	dev_priv->controlled_output = SDVO_OUTPUT_TMDS0;
-        output->subpixel_order = SubPixelHorizontalRGB;
-	name_prefix="TMDS";
-    }
-    else if (dev_priv->caps.output_flags & SDVO_OUTPUT_TMDS1)
+    if (dev_priv->caps.output_flags & (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_TMDS1))
     {
-	dev_priv->controlled_output = SDVO_OUTPUT_TMDS1;
+	if (dev_priv->caps.output_flags & SDVO_OUTPUT_TMDS0)
+	    dev_priv->controlled_output = SDVO_OUTPUT_TMDS0;
+	else
+	    dev_priv->controlled_output = SDVO_OUTPUT_TMDS1;
         output->subpixel_order = SubPixelHorizontalRGB;
 	name_prefix="TMDS";
+
+	i830_sdvo_get_supp_encode(output, &dev_priv->encode);
+	if (dev_priv->encode.hdmi_rev != 0) {
+	    /* enable hdmi encoding mode if supported */
+	    i830_sdvo_set_encode(output, SDVO_ENCODE_HDMI);
+	    i830_sdvo_set_colorimetry(output, SDVO_COLORIMETRY_RGB256);
+	    name_prefix = "HDMI";
+	}
     }
     else if (dev_priv->caps.output_flags & SDVO_OUTPUT_SVID0)
     {
diff --git a/src/i830_sdvo_regs.h b/src/i830_sdvo_regs.h
index dc2522a..747f2cd 100644
--- a/src/i830_sdvo_regs.h
+++ b/src/i830_sdvo_regs.h
@@ -511,3 +511,39 @@ struct i830_sdvo_enhancements_arg {
 # define SDVO_CONTROL_BUS_DDC2				(1 << 2)
 # define SDVO_CONTROL_BUS_DDC3				(1 << 3)
 
+/* HDMI op codes */
+#define SDVO_CMD_GET_SUPP_ENCODE	0x9d
+#define SDVO_CMD_GET_ENCODE		0x9e
+#define SDVO_CMD_SET_ENCODE		0x9f
+  #define SDVO_ENCODE_DVI	0x0
+  #define SDVO_ENCODE_HDMI	0x1
+#define SDVO_CMD_SET_PIXEL_REPLI	0x8b
+#define SDVO_CMD_GET_PIXEL_REPLI	0x8c
+#define SDVO_CMD_GET_COLORIMETRY_CAP	0x8d
+#define SDVO_CMD_SET_COLORIMETRY	0x8e
+  #define SDVO_COLORIMETRY_RGB256   0x0
+  #define SDVO_COLORIMETRY_RGB220   0x1
+  #define SDVO_COLORIMETRY_YCrCb422 0x3
+  #define SDVO_COLORIMETRY_YCrCb444 0x4
+#define SDVO_CMD_GET_COLORIMETRY	0x8f
+#define SDVO_CMD_GET_AUDIO_ENCRYPT_PREFER 0x90
+#define SDVO_CMD_SET_AUDIO_STAT		0x91
+#define SDVO_CMD_GET_AUDIO_STAT		0x92
+#define SDVO_CMD_SET_HBUF_INDEX		0x93
+#define SDVO_CMD_GET_HBUF_INDEX		0x94
+#define SDVO_CMD_GET_HBUF_INFO		0x95
+#define SDVO_CMD_SET_HBUF_AV_SPLIT	0x96
+#define SDVO_CMD_GET_HBUF_AV_SPLIT	0x97
+#define SDVO_CMD_SET_HBUF_DATA		0x98
+#define SDVO_CMD_GET_HBUF_DATA		0x99
+#define SDVO_CMD_SET_HBUF_TXRATE	0x9a
+#define SDVO_CMD_GET_HBUF_TXRATE	0x9b
+  #define SDVO_HBUF_TX_DISABLED	(0 << 6)
+  #define SDVO_HBUF_TX_ONCE	(2 << 6)
+  #define SDVO_HBUF_TX_VSYNC	(3 << 6)
+#define SDVO_CMD_GET_AUDIO_TX_INFO	0x9c
+
+struct i830_sdvo_encode{
+    uint8_t dvi_rev;
+    uint8_t hdmi_rev;
+} __attribute__ ((packed));
commit 59f39e0ea0ad48c52d9b8f7afb6e04ce95db717e
Author: Jesse Barnes <jbarnes at jbarnes-t61.(none)>
Date:   Tue Jun 24 11:01:46 2008 -0700

    Remove ErrorF debugging from modeset ioctl
    
    Oops.

diff --git a/src/i830_display.c b/src/i830_display.c
index 43a761c..abe9875 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -749,12 +749,10 @@ static void i830_modeset_ctl(xf86CrtcPtr crtc, int pre)
 	/* On -> off is a pre modeset */
 	modeset.cmd = _DRM_PRE_MODESET;
 	ioctl(pI830->drmSubFD, DRM_IOCTL_MODESET_CTL, &modeset);
-	ErrorF("modeset: on -> off on plane %d\n", modeset.crtc);
     } else if (!pre && intel_crtc->dpms_mode == DPMSModeOff) {
 	/* Off -> on means post modeset */
 	modeset.cmd = _DRM_POST_MODESET;
 	ioctl(pI830->drmSubFD, DRM_IOCTL_MODESET_CTL, &modeset);
-	ErrorF("modeset: off -> on on plane %d\n", modeset.crtc);
     }
 }
 #else
commit 1056d79809a3765f81113f3988bd948c1f9c673a
Author: Jesse Barnes <jbarnes at jbarnes-t61.(none)>
Date:   Tue Jun 24 10:44:23 2008 -0700

    Fix back buffer damage handler for 965+ chips
    
    When page flipping is enabled, we need to make sure any changes to the front
    buffer are reflected in the back buffer(s) or corruption might occur at page
    flip time.  So make the damage handler work on 965 by adding appropriate tiling
    flags and pitch adjustments.

diff --git a/src/i830_dri.c b/src/i830_dri.c
index 4361ad0..57fb0a4 100644
--- a/src/i830_dri.c
+++ b/src/i830_dri.c
@@ -996,26 +996,35 @@ static void
 I830DRIDoRefreshArea (ScrnInfoPtr pScrn, int num, BoxPtr pbox, uint32_t dst)
 {
    I830Ptr pI830 = I830PTR(pScrn);
-   int i, cmd, br13 = (pScrn->displayWidth * pI830->cpp) | (0xcc << 16);
+   unsigned int i, cmd, pitch, flags;
+
+   pitch = pScrn->displayWidth * pI830->cpp;
+   flags = 0xcc << 16; /* ROP_S */
 
    if (pScrn->bitsPerPixel == 32) {
       cmd = (XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA |
 	     XY_SRC_COPY_BLT_WRITE_RGB);
-      br13 |= 3 << 24;
+      flags |= 3 << 24;
    } else {
       cmd = (XY_SRC_COPY_BLT_CMD);
-      br13 |= 1 << 24;
+      flags |= 1 << 24;
+   }
+
+   /* We can assume tiled buffers if page flipping is on */
+   if (IS_I965G(pI830)) {
+       cmd |= XY_SRC_COPY_BLT_DST_TILED | XY_SRC_COPY_BLT_SRC_TILED;
+       pitch >>= 2;
    }
 
    for (i = 0 ; i < num ; i++, pbox++) {
       BEGIN_BATCH(8);
       OUT_BATCH(cmd);
-      OUT_BATCH(br13);
+      OUT_BATCH(flags | pitch);
       OUT_BATCH((pbox->y1 << 16) | pbox->x1);
       OUT_BATCH((pbox->y2 << 16) | pbox->x2);
       OUT_BATCH(dst);
       OUT_BATCH((pbox->y1 << 16) | pbox->x1);
-      OUT_BATCH(br13 & 0xffff);
+      OUT_BATCH(pitch);
       OUT_BATCH(pI830->front_buffer->offset);
       ADVANCE_BATCH();
    }
commit 65eee25d7d2ca979205f3776d620dbb36bf68a13
Author: Jesse Barnes <jbarnes at jbarnes-t61.(none)>
Date:   Tue Jun 24 10:41:46 2008 -0700

    Add support for keeping vblank counters sane across mode setting
    
    The DRM supports disabling of vblank interrupts when not in use, but in order
    to function properly it must also be aware of mode setting, which will reset
    the frame counter to 0.  Add code to call into the DRM before and after mode
    setting, so that it can account for any lost vblank events.

diff --git a/src/i830_display.c b/src/i830_display.c
index 7857ee3..43a761c 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -35,6 +35,7 @@
 #include <assert.h>
 #include <stdlib.h>
 #include <math.h>
+#include <sys/ioctl.h>
 
 #include "xf86.h"
 #include "i830.h"
@@ -730,6 +731,39 @@ i830_use_fb_compression(xf86CrtcPtr crtc)
     return TRUE;
 }
 
+#if defined(DRM_IOCTL_MODESET_CTL) && defined(XF86DRI)
+static void i830_modeset_ctl(xf86CrtcPtr crtc, int pre)
+{
+    ScrnInfoPtr pScrn = crtc->scrn;
+    I830Ptr pI830 = I830PTR(pScrn);
+    I830CrtcPrivatePtr intel_crtc = crtc->driver_private;
+    struct drm_modeset_ctl modeset;
+
+    modeset.crtc = intel_crtc->plane;
+
+    /*
+     * DPMS will be called many times (especially off), but we only
+     * want to catch the transition from on->off and off->on.
+     */
+    if (pre && intel_crtc->dpms_mode != DPMSModeOff) {
+	/* On -> off is a pre modeset */
+	modeset.cmd = _DRM_PRE_MODESET;
+	ioctl(pI830->drmSubFD, DRM_IOCTL_MODESET_CTL, &modeset);
+	ErrorF("modeset: on -> off on plane %d\n", modeset.crtc);
+    } else if (!pre && intel_crtc->dpms_mode == DPMSModeOff) {
+	/* Off -> on means post modeset */
+	modeset.cmd = _DRM_POST_MODESET;
+	ioctl(pI830->drmSubFD, DRM_IOCTL_MODESET_CTL, &modeset);
+	ErrorF("modeset: off -> on on plane %d\n", modeset.crtc);
+    }
+}
+#else
+static void i830_modeset_ctl(xf86CrtcPtr crtc, int dpms_state)
+{
+    return;
+}
+#endif /* DRM_IOCTL_MODESET_CTL && XF86DRI */
+
 /**
  * Sets the power management mode of the pipe and plane.
  *
@@ -797,8 +831,10 @@ i830_crtc_dpms(xf86CrtcPtr crtc, int mode)
 	/* Reenable compression if needed */
 	if (i830_use_fb_compression(crtc))
 	    i830_enable_fb_compression(crtc);
+	i830_modeset_ctl(crtc, 0);
 	break;
     case DPMSModeOff:
+	i830_modeset_ctl(crtc, 1);
 	/* Shut off compression if in use */
 	if (i830_use_fb_compression(crtc))
 	    i830_disable_fb_compression(crtc);
commit 6b6be2b2a7179c1c9fa12989e16076aae105f4e2
Author: Eric Anholt <eric at anholt.net>
Date:   Thu Jun 19 15:01:00 2008 -0700

    Fix a crash in i830_sdvo_init error paths by setting up dev_priv earlier.

diff --git a/src/i830_sdvo.c b/src/i830_sdvo.c
index 8914e1b..cdfc9c6 100644
--- a/src/i830_sdvo.c
+++ b/src/i830_sdvo.c
@@ -1527,10 +1527,12 @@ i830_sdvo_init(ScrnInfoPtr pScrn, int output_device)
 	return FALSE;
     }
     output->driver_private = intel_output;
+    dev_priv = (struct i830_sdvo_priv *) (intel_output + 1);
+    intel_output->dev_priv = dev_priv;
+
     output->interlaceAllowed = FALSE;
     output->doubleScanAllowed = FALSE;
     
-    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);
@@ -1572,7 +1574,6 @@ i830_sdvo_init(ScrnInfoPtr pScrn, int output_device)
     }
 
     intel_output->pI2CBus = i2cbus;
-    intel_output->dev_priv = dev_priv;
 
     /* Read the regs to test if we can talk to the device */
     for (i = 0; i < 0x40; i++) {
commit 65ad29d78793c7804f133a58de80ffaa0404ca28
Author: Eric Anholt <eric at anholt.net>
Date:   Thu Jun 19 14:27:30 2008 -0700

    Automatically detect the presence of HDMI.
    
    Now, SDVO is only probed if the SDVO detected bit is set.  If the SDVO probe
    fails, but the detect bit is set, assume that it's an HDMI output.

diff --git a/src/common.h b/src/common.h
index 5efdc0c..1765bb5 100644
--- a/src/common.h
+++ b/src/common.h
@@ -372,6 +372,7 @@ extern int I810_DEBUG;
 #define HWS_NEED_GFX(pI810) (IS_G33CLASS(pI810) || IS_IGD_GM(pI810) || IS_G4X(pI810))
 /* chipsets require status page in non stolen memory */
 #define HWS_NEED_NONSTOLEN(pI810) (IS_IGD_GM(pI810) || IS_G4X(pI810))
+#define SUPPORTS_INTEGRATED_HDMI(pI810) (IS_IGD_GM(pI810) || IS_G4X(pI810))
 
 #define GTT_PAGE_SIZE			KB(4)
 #define ROUND_TO(x, y)			(((x) + (y) - 1) / (y) * (y))
diff --git a/src/i830_driver.c b/src/i830_driver.c
index 5782d48..28505c8 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -924,13 +924,19 @@ I830SetupOutputs(ScrnInfoPtr pScrn)
       i830_lvds_init(pScrn);
 
    if (IS_I9XX(pI830)) {
-#if 1
-      i830_sdvo_init(pScrn, SDVOB);
-      i830_sdvo_init(pScrn, SDVOC);
-#else
-      i830_hdmi_init(pScrn, SDVOB);
-      i830_hdmi_init(pScrn, SDVOC);
-#endif
+      if (INREG(SDVOB) & SDVO_DETECTED) {
+	 Bool found = i830_sdvo_init(pScrn, SDVOB);
+
+	 if (!found && SUPPORTS_INTEGRATED_HDMI(pI830))
+	    i830_hdmi_init(pScrn, SDVOB);
+      }
+
+      if (INREG(SDVOB) & SDVO_DETECTED) {
+	 Bool found = i830_sdvo_init(pScrn, SDVOC);
+
+	 if (!found && SUPPORTS_INTEGRATED_HDMI(pI830))
+	    i830_hdmi_init(pScrn, SDVOC);
+      }
    } else {
       i830_dvo_init(pScrn);
    }
diff --git a/src/i830_sdvo.c b/src/i830_sdvo.c
index 331059b..8914e1b 100644
--- a/src/i830_sdvo.c
+++ b/src/i830_sdvo.c
@@ -1503,7 +1503,7 @@ i830_sdvo_select_ddc_bus(struct i830_sdvo_priv *dev_priv)
     dev_priv->ddc_bus = 1 << num_bits;
 }
 
-void
+Bool
 i830_sdvo_init(ScrnInfoPtr pScrn, int output_device)
 {
     xf86OutputPtr	    output;
@@ -1518,13 +1518,13 @@ i830_sdvo_init(ScrnInfoPtr pScrn, int output_device)
 
     output = xf86OutputCreate (pScrn, &i830_sdvo_output_funcs,NULL);
     if (!output)
-	return;
+	return FALSE;
     intel_output = xnfcalloc (sizeof (I830OutputPrivateRec) +
 			      sizeof (struct i830_sdvo_priv), 1);
     if (!intel_output)
     {
 	xf86OutputDestroy (output);
-	return;
+	return FALSE;
     }
     output->driver_private = intel_output;
     output->interlaceAllowed = FALSE;
@@ -1546,7 +1546,7 @@ i830_sdvo_init(ScrnInfoPtr pScrn, int output_device)
     if (i2cbus == NULL)
     {
 	xf86OutputDestroy (output);
-	return;
+	return FALSE;
     }
 
     if (output_device == SDVOB) {
@@ -1568,7 +1568,7 @@ i830_sdvo_init(ScrnInfoPtr pScrn, int output_device)
 		   "Failed to initialize %s I2C device\n",
 		   SDVO_NAME(dev_priv));
 	xf86OutputDestroy (output);
-	return;
+	return FALSE;
     }
 
     intel_output->pI2CBus = i2cbus;
@@ -1581,7 +1581,7 @@ i830_sdvo_init(ScrnInfoPtr pScrn, int output_device)
 		       "No SDVO device found on SDVO%c\n",
 		       output_device == SDVOB ? 'B' : 'C');
 	    xf86OutputDestroy (output);
-	    return;
+	    return FALSE;
 	}
     }
 
@@ -1594,7 +1594,7 @@ i830_sdvo_init(ScrnInfoPtr pScrn, int output_device)
     if (ddcbus == NULL) 
     {
 	xf86OutputDestroy (output);
-	return;
+	return FALSE;
     }
     if (output_device == SDVOB)
         ddcbus->BusName = "SDVOB DDC Bus";
@@ -1611,7 +1611,7 @@ i830_sdvo_init(ScrnInfoPtr pScrn, int output_device)
     if (!xf86I2CBusInit(ddcbus)) 
     {
 	xf86OutputDestroy (output);
-	return;
+	return FALSE;
     }
 
     intel_output->pI2CBus = i2cbus;
@@ -1670,7 +1670,7 @@ i830_sdvo_init(ScrnInfoPtr pScrn, int output_device)
     if (!xf86OutputRename (output, name))
     {
 	xf86OutputDestroy (output);
-	return;
+	return FALSE;
     }
 
     i830_sdvo_select_ddc_bus(dev_priv);
@@ -1718,4 +1718,5 @@ i830_sdvo_init(ScrnInfoPtr pScrn, int output_device)
     REPORT_OUTPUT_FLAG(SDVO_OUTPUT_SCART1, "SCART1");
     REPORT_OUTPUT_FLAG(SDVO_OUTPUT_LVDS1, "LVDS1");
 
+    return TRUE;
 }
diff --git a/src/i830_sdvo.h b/src/i830_sdvo.h
index 1368e43..798a88d 100644
--- a/src/i830_sdvo.h
+++ b/src/i830_sdvo.h
@@ -25,7 +25,7 @@
  *
  */
 
-void
+Bool
 i830_sdvo_init(ScrnInfoPtr pScrn, int output_device);
 
 int
commit ea0d21006ec71bc56acde7291e5f8d28e54b83fe
Author: Eric Anholt <eric at anholt.net>
Date:   Thu Jun 19 14:10:29 2008 -0700

    Fix hdmi POSTING_READ to use the register number instead of the register value.
    
    We won't dwell too long on how this ever worked.

diff --git a/src/i830_hdmi.c b/src/i830_hdmi.c
index c256296..72d4c63 100644
--- a/src/i830_hdmi.c
+++ b/src/i830_hdmi.c
@@ -82,7 +82,7 @@ i830_hdmi_mode_set(xf86OutputPtr output, DisplayModePtr mode,
 	sdvox |= SDVO_PIPE_B_SELECT;
 
     OUTREG(dev_priv->output_reg, sdvox);
-    POSTING_READ(sdvox);
+    POSTING_READ(dev_priv->output_reg);
 }
 
 static void
commit 2fa9240a3b685a0c3d0e2644fc144c927b67b6b3
Author: Eric Anholt <eric at anholt.net>
Date:   Thu Mar 20 15:14:46 2008 -0700

    Get HDMI output working.
    
    HDMI, despite claiming to have pixel multiply support, actually doesn't
    want it, at least in the way that SDVO did.  Disable it.
    
    Also disable the NULL_PACKETS_DURING_VSYNC bit.  Despite the docs telling us
    to set it, the output doesn't like it when you do that, and the BIOS doesn't
    set it.
    
    Also add a posting read to SDVOx setting.  Without it, half the X starts
    wouldn't get anything on the screen.  (interestingly, it was every other
    startup, not just a chance).

diff --git a/src/i830_hdmi.c b/src/i830_hdmi.c
index 931a55c..c256296 100644
--- a/src/i830_hdmi.c
+++ b/src/i830_hdmi.c
@@ -52,25 +52,13 @@ i830_hdmi_mode_valid(xf86OutputPtr output, DisplayModePtr mode)
     return MODE_OK;
 }
 
-static int
-i830_hdmi_get_pixel_multiplier(DisplayModePtr mode)
-{
-    if (mode->Clock >= 100000)
-	return 1;
-    else if (mode->Clock >= 50000)
-	return 2;
-    else
-	return 4;
-}
-
 static Bool
 i830_hdmi_mode_fixup(xf86OutputPtr output, DisplayModePtr mode,
 		     DisplayModePtr adjusted_mode)
 {
-    /* Make the CRTC code factor in the SDVO pixel multiplier.
+    /* The HDMI output doesn't need the pixel multiplication that SDVO does,
+     * so no fixup.
      */
-    adjusted_mode->Clock *= i830_hdmi_get_pixel_multiplier(mode);
-
     return TRUE;
 }
 
@@ -88,13 +76,13 @@ i830_hdmi_mode_set(xf86OutputPtr output, DisplayModePtr mode,
 
     sdvox = SDVO_ENCODING_HDMI |
 	SDVO_BORDER_ENABLE |
-	SDVO_NULL_PACKETS_DURING_VSYNC |
 	SDVO_VSYNC_ACTIVE_HIGH |
 	SDVO_HSYNC_ACTIVE_HIGH;
     if (intel_crtc->pipe == 1)
 	sdvox |= SDVO_PIPE_B_SELECT;
 
     OUTREG(dev_priv->output_reg, sdvox);
+    POSTING_READ(sdvox);
 }
 
 static void
commit dc8ab9d35b261b6105a62949cfb47a3554531d0b
Author: Eric Anholt <eric at anholt.net>
Date:   Thu Mar 20 13:49:47 2008 -0700

    Set the sync active bits like we're supposed to, matching the BIOS.

diff --git a/src/i810_reg.h b/src/i810_reg.h
index ecc2686..515e73d 100644
--- a/src/i810_reg.h
+++ b/src/i810_reg.h
@@ -1262,8 +1262,9 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 /** Requird for HDMI operation */
 #define SDVO_NULL_PACKETS_DURING_VSYNC		(1 << 9)
 #define SDVO_BORDER_ENABLE			(1 << 7)
-/** new with 965, default is to be set */
+/** New with 965, default is to be set */
 #define SDVO_VSYNC_ACTIVE_HIGH			(1 << 4)
+/** New with 965, default is to be set */
 #define SDVO_HSYNC_ACTIVE_HIGH			(1 << 3)
 /** 915/945 only, read-only bit */
 #define SDVOB_PCIE_CONCURRENCY			(1 << 3)
diff --git a/src/i830_hdmi.c b/src/i830_hdmi.c
index 77a51c6..931a55c 100644
--- a/src/i830_hdmi.c
+++ b/src/i830_hdmi.c
@@ -88,7 +88,9 @@ i830_hdmi_mode_set(xf86OutputPtr output, DisplayModePtr mode,
 
     sdvox = SDVO_ENCODING_HDMI |
 	SDVO_BORDER_ENABLE |
-	SDVO_NULL_PACKETS_DURING_VSYNC;
+	SDVO_NULL_PACKETS_DURING_VSYNC |
+	SDVO_VSYNC_ACTIVE_HIGH |
+	SDVO_HSYNC_ACTIVE_HIGH;
     if (intel_crtc->pipe == 1)
 	sdvox |= SDVO_PIPE_B_SELECT;
 
commit af13826ed063b60a1e4179101e8889b4ab7a9d0b
Author: Eric Anholt <eric at anholt.net>
Date:   Mon Mar 10 11:51:05 2008 -0700

    Add pixel multiplier support for HDMI

diff --git a/src/i830_hdmi.c b/src/i830_hdmi.c
index a5d2265..77a51c6 100644
--- a/src/i830_hdmi.c
+++ b/src/i830_hdmi.c
@@ -52,10 +52,25 @@ i830_hdmi_mode_valid(xf86OutputPtr output, DisplayModePtr mode)
     return MODE_OK;
 }
 
+static int
+i830_hdmi_get_pixel_multiplier(DisplayModePtr mode)
+{
+    if (mode->Clock >= 100000)
+	return 1;
+    else if (mode->Clock >= 50000)
+	return 2;
+    else
+	return 4;
+}
+
 static Bool
 i830_hdmi_mode_fixup(xf86OutputPtr output, DisplayModePtr mode,
 		     DisplayModePtr adjusted_mode)
 {
+    /* Make the CRTC code factor in the SDVO pixel multiplier.
+     */
+    adjusted_mode->Clock *= i830_hdmi_get_pixel_multiplier(mode);
+
     return TRUE;
 }
 
commit 9a05662918223477eb1cf6f80ffac08712721c70
Author: Eric Anholt <eric at anholt.net>
Date:   Mon Mar 10 11:47:15 2008 -0700

    The phase shift its are now reserved, and add HDMI clock limits.

diff --git a/src/i830_display.c b/src/i830_display.c
index 7697d4f..7857ee3 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -1175,7 +1175,7 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode,
 	    dpll |= DPLLB_LVDS_P2_CLOCK_DIV_14;
 	    break;
 	}
-	if (IS_I965G(pI830))
+	if (IS_I965G(pI830) && !IS_IGD_GM(pI830))
 	    dpll |= (6 << PLL_LOAD_PULSE_PHASE_SHIFT);
     } else {
 	if (is_lvds) {
diff --git a/src/i830_hdmi.c b/src/i830_hdmi.c
index 103443f..a5d2265 100644
--- a/src/i830_hdmi.c
+++ b/src/i830_hdmi.c
@@ -43,6 +43,12 @@ struct i830_hdmi_priv {
 static int
 i830_hdmi_mode_valid(xf86OutputPtr output, DisplayModePtr mode)
 {
+    if (mode->Clock > 165000)
+	return MODE_CLOCK_HIGH;
+
+    if (mode->Clock < 20000)
+	return MODE_CLOCK_LOW;
+
     return MODE_OK;
 }
 
commit beba1dd3561e38573ed9f507328caf7f8fb9f84a
Author: Eric Anholt <eric at anholt.net>
Date:   Thu Mar 6 16:05:17 2008 -0800

    Initial HDMI work.  Not currently hooked up at startup.

diff --git a/src/Makefile.am b/src/Makefile.am
index 0784c06..9dd9b37 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -100,6 +100,7 @@ intel_drv_la_SOURCES = \
          i830_driver.c \
 	 i830_dvo.c \
          i830.h \
+	 i830_hdmi.c \
          i830_i2c.c \
          i830_io.c \
 	 i830_lvds.c \
diff --git a/src/i810_reg.h b/src/i810_reg.h
index dcf14bf..ecc2686 100644
--- a/src/i810_reg.h
+++ b/src/i810_reg.h
@@ -1216,6 +1216,9 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 # define FP_M2_DIV_SHIFT			0
 
 #define PORT_HOTPLUG_EN		0x61110
+# define HDMIB_HOTPLUG_INT_EN			(1 << 29)
+# define HDMIC_HOTPLUG_INT_EN			(1 << 28)
+# define HDMID_HOTPLUG_INT_EN			(1 << 27)
 # define SDVOB_HOTPLUG_INT_EN			(1 << 26)
 # define SDVOC_HOTPLUG_INT_EN			(1 << 25)
 # define TV_HOTPLUG_INT_EN			(1 << 18)
@@ -1223,6 +1226,9 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 # define CRT_HOTPLUG_FORCE_DETECT		(1 << 3)
 
 #define PORT_HOTPLUG_STAT	0x61114
+# define HDMIB_HOTPLUG_INT_STATUS		(1 << 29)
+# define HDMIC_HOTPLUG_INT_STATUS		(1 << 28)
+# define HDMID_HOTPLUG_INT_STATUS		(1 << 27)
 # define CRT_HOTPLUG_INT_STATUS			(1 << 11)
 # define TV_HOTPLUG_INT_STATUS			(1 << 10)
 # define CRT_HOTPLUG_MONITOR_MASK		(3 << 8)
@@ -1251,6 +1257,10 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #define SDVO_PHASE_SELECT_DEFAULT		(6 << 19)
 #define SDVO_CLOCK_OUTPUT_INVERT		(1 << 18)
 #define SDVOC_GANG_MODE				(1 << 16)
+#define SDVO_ENCODING_SDVO			(0x0 << 10)
+#define SDVO_ENCODING_HDMI			(0x2 << 10)
+/** Requird for HDMI operation */
+#define SDVO_NULL_PACKETS_DURING_VSYNC		(1 << 9)
 #define SDVO_BORDER_ENABLE			(1 << 7)
 /** new with 965, default is to be set */
 #define SDVO_VSYNC_ACTIVE_HIGH			(1 << 4)
diff --git a/src/i830.h b/src/i830.h
index 2a804ab..00a5059 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -238,6 +238,7 @@ typedef struct {
 #define I830_OUTPUT_SDVO 5
 #define I830_OUTPUT_LVDS 6
 #define I830_OUTPUT_TVOUT 7
+#define I830_OUTPUT_HDMI 8
 
 struct _I830DVODriver {
    int type;
@@ -802,6 +803,9 @@ void i830_crt_init(ScrnInfoPtr pScrn);
 /* i830_dvo.c */
 void i830_dvo_init(ScrnInfoPtr pScrn);
 
+/* i830_hdmi.c */
+void i830_hdmi_init(ScrnInfoPtr pScrn, int output_reg);
+
 /* i830_lvds.c */
 void i830_lvds_init(ScrnInfoPtr pScrn);
 
diff --git a/src/i830_display.c b/src/i830_display.c
index 56a718d..7697d4f 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -1103,6 +1103,7 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode,
 	    lvds_bits = intel_output->lvds_bits;
 	    break;
 	case I830_OUTPUT_SDVO:
+	case I830_OUTPUT_HDMI:
 	    is_sdvo = TRUE;
 	    if (intel_output->needs_tv_clock)
 		is_tv = TRUE;
diff --git a/src/i830_driver.c b/src/i830_driver.c
index 604665e..5782d48 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -924,8 +924,13 @@ I830SetupOutputs(ScrnInfoPtr pScrn)
       i830_lvds_init(pScrn);
 
    if (IS_I9XX(pI830)) {
+#if 1
       i830_sdvo_init(pScrn, SDVOB);
       i830_sdvo_init(pScrn, SDVOC);
+#else
+      i830_hdmi_init(pScrn, SDVOB);
+      i830_hdmi_init(pScrn, SDVOC);
+#endif
    } else {
       i830_dvo_init(pScrn);
    }
diff --git a/src/i830_hdmi.c b/src/i830_hdmi.c
new file mode 100644
index 0000000..103443f
--- /dev/null
+++ b/src/i830_hdmi.c
@@ -0,0 +1,222 @@
+/*
+ * 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:
+ *    Eric Anholt <eric at anholt.net>
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "xf86.h"
+#include "i830.h"
+#include "xf86Modes.h"
+#include "i830_display.h"
+
+struct i830_hdmi_priv {
+    uint32_t output_reg;
+
+    uint32_t save_SDVO;
+};
+
+static int
+i830_hdmi_mode_valid(xf86OutputPtr output, DisplayModePtr mode)
+{
+    return MODE_OK;
+}
+
+static Bool
+i830_hdmi_mode_fixup(xf86OutputPtr output, DisplayModePtr mode,
+		     DisplayModePtr adjusted_mode)
+{
+    return TRUE;
+}
+
+static void
+i830_hdmi_mode_set(xf86OutputPtr output, DisplayModePtr mode,
+		   DisplayModePtr adjusted_mode)
+{
+    ScrnInfoPtr pScrn = output->scrn;
+    I830OutputPrivatePtr intel_output = output->driver_private;
+    struct i830_hdmi_priv *dev_priv = intel_output->dev_priv;
+    I830Ptr pI830 = I830PTR(pScrn);
+    xf86CrtcPtr crtc = output->crtc;
+    I830CrtcPrivatePtr intel_crtc = crtc->driver_private;
+    uint32_t sdvox;
+
+    sdvox = SDVO_ENCODING_HDMI |
+	SDVO_BORDER_ENABLE |
+	SDVO_NULL_PACKETS_DURING_VSYNC;
+    if (intel_crtc->pipe == 1)
+	sdvox |= SDVO_PIPE_B_SELECT;
+
+    OUTREG(dev_priv->output_reg, sdvox);
+}
+
+static void
+i830_hdmi_dpms(xf86OutputPtr output, int mode)
+{
+    ScrnInfoPtr pScrn = output->scrn;
+    I830OutputPrivatePtr intel_output = output->driver_private;
+    struct i830_hdmi_priv *dev_priv = intel_output->dev_priv;
+    I830Ptr pI830 = I830PTR(pScrn);
+    uint32_t  temp;
+
+    if (mode == DPMSModeOff) {
+	temp = INREG(dev_priv->output_reg);
+	OUTREG(dev_priv->output_reg, temp & ~SDVO_ENABLE);
+    } else {
+	temp = INREG(dev_priv->output_reg);
+	OUTREG(dev_priv->output_reg, temp | SDVO_ENABLE);
+    }
+}
+
+static void
+i830_hdmi_save(xf86OutputPtr output)
+{
+    ScrnInfoPtr pScrn = output->scrn;
+    I830OutputPrivatePtr intel_output = output->driver_private;
+    struct i830_hdmi_priv *dev_priv = intel_output->dev_priv;
+    I830Ptr pI830 = I830PTR(pScrn);
+
+    dev_priv->save_SDVO = INREG(dev_priv->output_reg);
+}
+
+static void
+i830_hdmi_restore(xf86OutputPtr output)
+{
+    ScrnInfoPtr pScrn = output->scrn;
+    I830OutputPrivatePtr intel_output = output->driver_private;
+    struct i830_hdmi_priv *dev_priv = intel_output->dev_priv;
+    I830Ptr pI830 = I830PTR(pScrn);
+
+    OUTREG(dev_priv->output_reg, dev_priv->save_SDVO);
+}
+
+/**
+ * Uses CRT_HOTPLUG_EN and CRT_HOTPLUG_STAT to detect HDMI connection.
+ *
+ * \return TRUE if HDMI port is connected.
+ * \return FALSE if HDMI port is disconnected.
+ */
+static xf86OutputStatus
+i830_hdmi_detect(xf86OutputPtr output)
+{
+    ScrnInfoPtr	pScrn = output->scrn;
+    I830OutputPrivatePtr intel_output = output->driver_private;
+    struct i830_hdmi_priv *dev_priv = intel_output->dev_priv;
+    I830Ptr pI830 = I830PTR(pScrn);
+    uint32_t temp, bit;
+
+    temp = INREG(PORT_HOTPLUG_EN);
+
+    OUTREG(PORT_HOTPLUG_EN,
+	   temp |
+	   HDMIB_HOTPLUG_INT_EN |
+	   HDMIC_HOTPLUG_INT_EN |
+	   HDMID_HOTPLUG_INT_EN);
+
+    POSTING_READ(PORT_HOTPLUG_EN);
+
+    switch (dev_priv->output_reg) {
+    case SDVOB:
+	bit = HDMIB_HOTPLUG_INT_STATUS;
+	break;
+    case SDVOC:
+	bit = HDMIC_HOTPLUG_INT_STATUS;
+	break;
+    default:
+	return XF86OutputStatusUnknown;
+    }
+
+    if ((INREG(PORT_HOTPLUG_STAT) & bit) != 0)
+	return XF86OutputStatusConnected;
+    else
+	return XF86OutputStatusDisconnected;
+}
+
+static void
+i830_hdmi_destroy (xf86OutputPtr output)
+{
+    I830OutputPrivatePtr intel_output = output->driver_private;
+
+    if (intel_output != NULL) {
+	xf86DestroyI2CBusRec(intel_output->pDDCBus, FALSE, FALSE);
+	xfree(intel_output);
+    }
+}
+
+static const xf86OutputFuncsRec i830_hdmi_output_funcs = {
+    .dpms = i830_hdmi_dpms,
+    .save = i830_hdmi_save,
+    .restore = i830_hdmi_restore,
+    .mode_valid = i830_hdmi_mode_valid,
+    .mode_fixup = i830_hdmi_mode_fixup,
+    .prepare = i830_output_prepare,
+    .mode_set = i830_hdmi_mode_set,
+    .commit = i830_output_commit,
+    .detect = i830_hdmi_detect,
+    .get_modes = i830_ddc_get_modes,
+    .destroy = i830_hdmi_destroy
+};
+
+void
+i830_hdmi_init(ScrnInfoPtr pScrn, int output_reg)
+{
+    xf86OutputPtr output;
+    I830OutputPrivatePtr intel_output;
+    struct i830_hdmi_priv *dev_priv;
+
+    output = xf86OutputCreate(pScrn, &i830_hdmi_output_funcs,
+			      (output_reg == SDVOB) ? "HDMI-1" : "HDMI-2");
+    if (!output)
+	return;
+    intel_output = xnfcalloc(sizeof (I830OutputPrivateRec) +
+			     sizeof (struct i830_hdmi_priv), 1);
+    if (intel_output == NULL) {
+	xf86OutputDestroy(output);
+	return;
+    }
+    output->driver_private = intel_output;
+    output->interlaceAllowed = FALSE;
+    output->doubleScanAllowed = FALSE;
+
+    dev_priv = (struct i830_hdmi_priv *)(intel_output + 1);
+    dev_priv->output_reg = output_reg;
+
+    intel_output->dev_priv = dev_priv;
+    intel_output->type = I830_OUTPUT_HDMI;
+    intel_output->pipe_mask = ((1 << 0) | (1 << 1));
+    intel_output->clone_mask = (1 << I830_OUTPUT_HDMI);
+
+    /* Set up the DDC bus. */
+    if (output_reg == SDVOB)
+	I830I2CInit(pScrn, &intel_output->pDDCBus, GPIOE, "HDMIDDC_B");
+    else
+	I830I2CInit(pScrn, &intel_output->pDDCBus, GPIOE, "HDMIDDC_C");
+
+    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+	       "HDMI output %d detected\n",
+	       1 + (output_reg - SDVOB));
+}
commit da58dc3b02999f3244d0eaf77180b828d85bd609
Author: Eric Anholt <eric at anholt.net>
Date:   Thu Mar 6 14:57:57 2008 -0800

    Add DisplayPort registers.

diff --git a/src/i810_reg.h b/src/i810_reg.h
index dc4f5e8..dcf14bf 100644
--- a/src/i810_reg.h
+++ b/src/i810_reg.h
@@ -1451,6 +1451,30 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
 /** @} */
 
+#define DP_B			0x64100
+#define DPB_AUX_CH_CTL		0x64110
+#define DPB_AUX_CH_DATA1	0x64114
+#define DPB_AUX_CH_DATA2	0x64118
+#define DPB_AUX_CH_DATA3	0x6411c
+#define DPB_AUX_CH_DATA4	0x64120
+#define DPB_AUX_CH_DATA5	0x64124
+
+#define DP_C			0x64200
+#define DPC_AUX_CH_CTL		0x64210
+#define DPC_AUX_CH_DATA1	0x64214
+#define DPC_AUX_CH_DATA2	0x64218
+#define DPC_AUX_CH_DATA3	0x6421c
+#define DPC_AUX_CH_DATA4	0x64220
+#define DPC_AUX_CH_DATA5	0x64224
+
+#define DP_D			0x64300
+#define DPD_AUX_CH_CTL		0x64310
+#define DPD_AUX_CH_DATA1	0x64314
+#define DPD_AUX_CH_DATA2	0x64318
+#define DPD_AUX_CH_DATA3	0x6431c
+#define DPD_AUX_CH_DATA4	0x64320
+#define DPD_AUX_CH_DATA5	0x64324
+
 /*
  * Two channel clock control. Turn this on if you need clkb for two channel mode
  * Overridden by global LVDS power sequencing
diff --git a/src/i830_debug.c b/src/i830_debug.c
index 19cc661..2b5708e 100644
--- a/src/i830_debug.c
+++ b/src/i830_debug.c
@@ -628,6 +628,31 @@ static struct i830SnapshotRec {
     DEFINEREG(MI_ARB_STATE),
     DEFINEREG(MI_RDRET_STATE),
     DEFINEREG(ECOSKPD),
+
+    DEFINEREG(DP_B),
+    DEFINEREG(DPB_AUX_CH_CTL),
+    DEFINEREG(DPB_AUX_CH_DATA1),
+    DEFINEREG(DPB_AUX_CH_DATA2),
+    DEFINEREG(DPB_AUX_CH_DATA3),
+    DEFINEREG(DPB_AUX_CH_DATA4),
+    DEFINEREG(DPB_AUX_CH_DATA5),
+
+    DEFINEREG(DP_C),
+    DEFINEREG(DPC_AUX_CH_CTL),
+    DEFINEREG(DPC_AUX_CH_DATA1),
+    DEFINEREG(DPC_AUX_CH_DATA2),
+    DEFINEREG(DPC_AUX_CH_DATA3),
+    DEFINEREG(DPC_AUX_CH_DATA4),
+    DEFINEREG(DPC_AUX_CH_DATA5),
+
+    DEFINEREG(DP_D),
+    DEFINEREG(DPD_AUX_CH_CTL),
+    DEFINEREG(DPD_AUX_CH_DATA1),
+    DEFINEREG(DPD_AUX_CH_DATA2),
+    DEFINEREG(DPD_AUX_CH_DATA3),
+    DEFINEREG(DPD_AUX_CH_DATA4),
+    DEFINEREG(DPD_AUX_CH_DATA5),
+
 #if 0
     DEFINEREG2(FENCE_NEW + 0, i810_debug_fence_new),
     DEFINEREG2(FENCE_NEW + 8, i810_debug_fence_new),
commit 52a414d1158aa7512fb79560dc220e2a78456a2d
Author: Eric Anholt <eric at anholt.net>
Date:   Thu Mar 6 14:00:18 2008 -0800

    Remove VGA regs from debug output.

diff --git a/src/i830_debug.c b/src/i830_debug.c
index 074e8b9..19cc661 100644
--- a/src/i830_debug.c
+++ b/src/i830_debug.c
@@ -697,6 +697,7 @@ void i830CompareRegsToSnapshot(ScrnInfoPtr pScrn, char *where)
 }
 #endif /* !REG_DUMPER */
 
+#if 0
 static void i830DumpIndexed (ScrnInfoPtr pScrn, char *name, int id, int val, int min, int max)
 {
     I830Ptr pI830 = I830PTR(pScrn);
@@ -737,6 +738,7 @@ static void i830DumpAR(ScrnInfoPtr pScrn)
     OUTREG8(0x3c0, orig_arx);
     INREG8(st01); /* switch back to index mode */
 }
+#endif
 
 void i830DumpRegs (ScrnInfoPtr pScrn)
 {
@@ -748,8 +750,10 @@ void i830DumpRegs (ScrnInfoPtr pScrn)
     int ref;
     int	dot;
     int phase;
+#if 0
     int msr;
     int crt;
+#endif
 
     xf86DrvMsg (pScrn->scrnIndex, X_INFO, "DumpRegsBegin\n");
     for (i = 0; i < NUM_I830_SNAPSHOTREGS; i++) {
@@ -767,6 +771,7 @@ void i830DumpRegs (ScrnInfoPtr pScrn)
 			i830_snapshot[i].name, (unsigned int)val);
 	}
     }
+#if 0
     i830DumpIndexed (pScrn, "SR", 0x3c4, 0x3c5, 0, 7);
     msr = INREG8(0x3cc);
     xf86DrvMsg (pScrn->scrnIndex, X_INFO, "%20.20s: 0x%02x\n",
@@ -778,6 +783,7 @@ void i830DumpRegs (ScrnInfoPtr pScrn)
     else
 	crt = 0x3b0;
     i830DumpIndexed (pScrn, "CR", crt + 4, crt + 5, 0, 0x24);
+#endif
     for (pipe = 0; pipe <= 1; pipe++)
     {
 	fp = INREG(pipe == 0 ? FPA0 : FPB0);
diff --git a/src/reg_dumper/.gitignore b/src/reg_dumper/.gitignore
index f72a165..b0f9b6f 100644
--- a/src/reg_dumper/.gitignore
+++ b/src/reg_dumper/.gitignore
@@ -1,3 +1,4 @@
+intel_hotplug
 intel_idle
 intel_reg_dumper
 intel_stepping
diff --git a/src/reg_dumper/Makefile.am b/src/reg_dumper/Makefile.am
index b840b24..d49a59b 100644
--- a/src/reg_dumper/Makefile.am
+++ b/src/reg_dumper/Makefile.am
@@ -1,4 +1,4 @@
-noinst_PROGRAMS = intel_reg_dumper intel_idle intel_stepping
+noinst_PROGRAMS = intel_reg_dumper intel_idle intel_stepping intel_hotplug
 
 intel_reg_dumper_SOURCES = \
 	main.c \
@@ -12,9 +12,16 @@ intel_idle_SOURCES = \
 	xprintf.c \
 	../i830_debug.c
 
+intel_hotplug_SOURCES = \
+	hotplug.c \
+	reg_dumper.h \
+	xprintf.c \
+	../i830_debug.c
+
 intel_stepping_SOURCES = \
 	stepping.c
 
+intel_hotplug_LDADD = $(PCIACCESS_LIBS)
 intel_reg_dumper_LDADD = $(PCIACCESS_LIBS)
 intel_idle_LDADD = $(PCIACCESS_LIBS)
 intel_stepping_LDADD = $(PCIACCESS_LIBS)
commit b60bbbfd7b7dcf31726ad615a493f34f17cc6309
Author: Eric Anholt <eric at anholt.net>
Date:   Thu Mar 6 13:59:06 2008 -0800

    Add little hotplug detector app.

diff --git a/src/reg_dumper/hotplug.c b/src/reg_dumper/hotplug.c
new file mode 100644
index 0000000..68fe584
--- /dev/null
+++ b/src/reg_dumper/hotplug.c
@@ -0,0 +1,151 @@
+/*
+ * 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:
+ *    Eric Anholt <eric at anholt.net>
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <pciaccess.h>
+#include <err.h>
+#include <unistd.h>
+
+#include "reg_dumper.h"
+#include "../i810_reg.h"
+
+struct idle_flags {
+    uint32_t instdone_flag;
+    char *name;
+    unsigned int count;
+};
+
+int main(int argc, char **argv)
+{
+    struct pci_device *dev;
+    I830Rec i830;
+    I830Ptr pI830 = &i830;
+    ScrnInfoRec scrn;
+    int err, mmio_bar;
+    void *mmio;
+    int i;
+
+    err = pci_system_init();
+    if (err != 0) {
+	fprintf(stderr, "Couldn't initialize PCI system: %s\n", strerror(err));
+	exit(1);
+    }
+
+    /* Grab the graphics card */
+    dev = pci_device_find_by_slot(0, 0, 2, 0);
+    if (dev == NULL)
+	errx(1, "Couldn't find graphics card");
+
+    err = pci_device_probe(dev);
+    if (err != 0) {
+	fprintf(stderr, "Couldn't probe graphics card: %s\n", strerror(err));
+	exit(1);
+    }
+
+    if (dev->vendor_id != 0x8086)
+	errx(1, "Graphics card is non-intel");
+
+    i830.PciInfo = &i830.pci_info_rec;
+    i830.PciInfo->chipType = dev->device_id;
+
+    i830.pci_dev = dev;
+
+    mmio_bar = IS_I9XX((&i830)) ? 0 : 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 = mmio;
+
+    scrn.scrnIndex = 0;
+    scrn.pI830 = &i830;
+
+    OUTREG(SDVOB, (0x0 << 10));
+    OUTREG(SDVOC, (0x0 << 10));
+
+    OUTREG(PORT_HOTPLUG_EN,
+	   (1 << 29) |
+	   (1 << 28) |
+	   (1 << 27) |
+	   SDVOB_HOTPLUG_INT_EN |
+	   SDVOC_HOTPLUG_INT_EN |
+	   (1 << 24) |
+	   CRT_HOTPLUG_INT_EN |
+	   TV_HOTPLUG_INT_EN |
+	   CRT_HOTPLUG_INT_EN);
+
+    for (i = 0;; i++) {
+	OUTREG(PORT_HOTPLUG_STAT,
+	       (1 << 20) |
+	       (1 << 19) |
+	       (1 << 18) |
+	       (1 << 17) |
+	       CRT_HOTPLUG_INT_STATUS |
+	       TV_HOTPLUG_INT_STATUS |
+	       SDVOC_HOTPLUG_INT_STATUS |
+	       SDVOB_HOTPLUG_INT_STATUS);
+	INREG(PORT_HOTPLUG_STAT);
+
+	usleep(500 * 1000);
+
+	printf("%5d: 0x%08x\n", i, INREG(PORT_HOTPLUG_STAT));
+	sleep(1);
+    }
+
+    return 0;
+}
+
+void xf86DrvMsg(int scrnIndex, int severity, const char *format, ...)
+{
+    va_list va;
+
+    switch (severity) {
+    case X_INFO:
+	printf("(II): ");
+	break;
+    case X_WARNING:
+	printf("(WW): ");
+	break;
+    case X_ERROR:
+	printf("(EE): ");
+	break;
+    }
+
+    va_start(va, format);
+    vprintf(format, va);
+    va_end(va);
+}
commit 64fa32e2eba21cb94aa0f8d87a6ee6b7c178a7a5
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Thu Jun 19 11:02:29 2008 +0800

    Add backlight kernel method support on Asus and Eeepc
    
    Noted and tested by Evgeniy Manachkin <sfstudio at mail.ru>
    for asus-laptop support, also add eeepc support.

diff --git a/src/i830_lvds.c b/src/i830_lvds.c
index 4f62a2b..af82ee7 100644
--- a/src/i830_lvds.c
+++ b/src/i830_lvds.c
@@ -87,6 +87,8 @@ static char *backlight_interfaces[] = {
     "acpi_video1",
     "acpi_video0",
     "fujitsu-laptop",
+    "asus-laptop",
+    "eeepc",
     NULL,
 };
 
commit 1cfe769c74d1a3a392bf1aaaf5c2dcc8273daf66
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Tue Jun 17 12:39:28 2008 -0700

    Add support for Intel 4 series chipsets.

diff --git a/src/common.h b/src/common.h
index 9a3e0ac..5efdc0c 100644
--- a/src/common.h
+++ b/src/common.h
@@ -308,6 +308,21 @@ extern int I810_DEBUG;
 #define PCI_CHIP_IGD_GM_BRIDGE  0x2A40
 #endif
 
+#ifndef PCI_CHIP_IGD_E_G
+#define PCI_CHIP_IGD_E_G	0x2E02
+#define PCI_CHIP_IGD_E_G_BRIDGE 0x2E00
+#endif
+
+#ifndef PCI_CHIP_G45_G
+#define PCI_CHIP_G45_G		0x2E22
+#define PCI_CHIP_G45_G_BRIDGE	0x2E20
+#endif
+
+#ifndef PCI_CHIP_Q45_G
+#define PCI_CHIP_Q45_G		0x2E12
+#define PCI_CHIP_Q45_G_BRIDGE	0x2E10
+#endif
+
 #if XSERVER_LIBPCIACCESS
 #define I810_MEMBASE(p,n) (p)->regions[(n)].base_addr
 #define VENDOR_ID(p)      (p)->vendor_id
@@ -340,8 +355,9 @@ extern int I810_DEBUG;
 #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_IGD_GM(pI810) (DEVICE_ID(pI810->PciInfo) == PCI_CHIP_IGD_GM)
+#define IS_G4X(pI810) (DEVICE_ID(pI810->PciInfo) == PCI_CHIP_IGD_E_G || DEVICE_ID(pI810->PciInfo) == PCI_CHIP_G45_G || DEVICE_ID(pI810->PciInfo) == PCI_CHIP_Q45_G)
 #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_G35_G || 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 || IS_IGD_GM(pI810))
+#define IS_I965G(pI810) (DEVICE_ID(pI810->PciInfo) == PCI_CHIP_I965_G || DEVICE_ID(pI810->PciInfo) == PCI_CHIP_G35_G || 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 || IS_IGD_GM(pI810) || IS_G4X(pI810))
 #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)
@@ -350,8 +366,12 @@ extern int I810_DEBUG;
 #define IS_MOBILE(pI810) (IS_I830(pI810) || IS_I85X(pI810) || IS_I915GM(pI810) || IS_I945GM(pI810) || IS_I965GM(pI810) || IS_IGD_GM(pI810))
 /* mark chipsets for using gfx VM offset for overlay */
 #define OVERLAY_NOPHYSICAL(pI810) (IS_G33CLASS(pI810) || IS_I965G(pI810))
+/* mark chipsets without overlay hw */
+#define OVERLAY_NOEXIST(pI810) (IS_IGD_GM(pI810) || IS_G4X(pI810))
 /* chipsets require graphics mem for hardware status page */
-#define HWS_NEED_GFX(pI810) (IS_G33CLASS(pI810) || IS_IGD_GM(pI810))
+#define HWS_NEED_GFX(pI810) (IS_G33CLASS(pI810) || IS_IGD_GM(pI810) || IS_G4X(pI810))
+/* chipsets require status page in non stolen memory */
+#define HWS_NEED_NONSTOLEN(pI810) (IS_IGD_GM(pI810) || IS_G4X(pI810))
 
 #define GTT_PAGE_SIZE			KB(4)
 #define ROUND_TO(x, y)			(((x) + (y) - 1) / (y) * (y))
diff --git a/src/i810_driver.c b/src/i810_driver.c
index 4b71660..de4f3cb 100644
--- a/src/i810_driver.c
+++ b/src/i810_driver.c
@@ -153,6 +153,9 @@ static const struct pci_id_match intel_device_match[] = {
    INTEL_DEVICE_MATCH (PCI_CHIP_Q35_G, 0 ),
    INTEL_DEVICE_MATCH (PCI_CHIP_Q33_G, 0 ),
    INTEL_DEVICE_MATCH (PCI_CHIP_IGD_GM, 0 ),
+   INTEL_DEVICE_MATCH (PCI_CHIP_IGD_E_G, 0 ),
+   INTEL_DEVICE_MATCH (PCI_CHIP_G45_G, 0 ),
+   INTEL_DEVICE_MATCH (PCI_CHIP_Q45_G, 0 ),
     { 0, 0, 0 },
 };
 
@@ -206,6 +209,9 @@ static SymTabRec I810Chipsets[] = {
    {PCI_CHIP_Q35_G,		"Q35"},
    {PCI_CHIP_Q33_G,		"Q33"},
    {PCI_CHIP_IGD_GM,		"Intel Integrated Graphics Device"},
+   {PCI_CHIP_IGD_E_G,		"Intel Integrated Graphics Device"},
+   {PCI_CHIP_G45_G,		"G45/G43"},
+   {PCI_CHIP_Q45_G,		"Q45/Q43"},
    {-1,				NULL}
 };
 
@@ -236,6 +242,9 @@ static PciChipsets I810PciChipsets[] = {
    {PCI_CHIP_Q35_G,		PCI_CHIP_Q35_G,		RES_SHARED_VGA},
    {PCI_CHIP_Q33_G,		PCI_CHIP_Q33_G,		RES_SHARED_VGA},
    {PCI_CHIP_IGD_GM,		PCI_CHIP_IGD_GM,	RES_SHARED_VGA},
+   {PCI_CHIP_IGD_E_G,		PCI_CHIP_IGD_E_G,	RES_SHARED_VGA},
+   {PCI_CHIP_G45_G,		PCI_CHIP_G45_G,		RES_SHARED_VGA},
+   {PCI_CHIP_Q45_G,		PCI_CHIP_Q45_G,		RES_SHARED_VGA},
    {-1,				-1, RES_UNDEFINED }
 };
 
@@ -800,6 +809,9 @@ I810Probe(DriverPtr drv, int flags)
  	    case PCI_CHIP_Q35_G:
  	    case PCI_CHIP_Q33_G:
  	    case PCI_CHIP_IGD_GM:
+	    case PCI_CHIP_IGD_E_G:
+	    case PCI_CHIP_G45_G:
+	    case PCI_CHIP_Q45_G:
     	       xf86SetEntitySharable(usedChips[i]);
 
     	       /* Allocate an entity private if necessary */		
diff --git a/src/i810_reg.h b/src/i810_reg.h
index e0b0c27..dc4f5e8 100644
--- a/src/i810_reg.h
+++ b/src/i810_reg.h
@@ -2270,6 +2270,11 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #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 INTEL_GMCH_GMS_STOLEN_96M		(0xa << 4)
+#define INTEL_GMCH_GMS_STOLEN_160M		(0xb << 4)
+#define INTEL_GMCH_GMS_STOLEN_224M		(0xc << 4)
+#define INTEL_GMCH_GMS_STOLEN_352M		(0xd << 4)
+
 
 #define I85X_CAPID			0x44
 #define I85X_VARIANT_MASK			0x7
diff --git a/src/i830_driver.c b/src/i830_driver.c
index 091b5ca..604665e 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -252,6 +252,9 @@ static SymTabRec I830Chipsets[] = {
    {PCI_CHIP_Q35_G,		"Q35"},
    {PCI_CHIP_Q33_G,		"Q33"},
    {PCI_CHIP_IGD_GM,		"Intel Integrated Graphics Device"},
+   {PCI_CHIP_IGD_E_G,		"Intel Integrated Graphics Device"},
+   {PCI_CHIP_G45_G,		"G45/G43"},
+   {PCI_CHIP_Q45_G,		"Q45/Q43"},
    {-1,				NULL}
 };
 
@@ -276,6 +279,9 @@ static PciChipsets I830PciChipsets[] = {
    {PCI_CHIP_Q35_G,		PCI_CHIP_Q35_G,		RES_SHARED_VGA},
    {PCI_CHIP_Q33_G,		PCI_CHIP_Q33_G,		RES_SHARED_VGA},
    {PCI_CHIP_IGD_GM,		PCI_CHIP_IGD_GM,	RES_SHARED_VGA},
+   {PCI_CHIP_IGD_E_G,		PCI_CHIP_IGD_E_G,	RES_SHARED_VGA},
+   {PCI_CHIP_G45_G,		PCI_CHIP_G45_G,		RES_SHARED_VGA},
+   {PCI_CHIP_Q45_G,		PCI_CHIP_Q45_G,		RES_SHARED_VGA},
    {-1,				-1,			RES_UNDEFINED}
 };
 
@@ -511,6 +517,10 @@ I830DetectMemory(ScrnInfoPtr pScrn)
     */
    range = gtt_size + 4;
 
+   /* new 4 series hardware has seperate GTT stolen with GFX stolen */
+   if (IS_G4X(pI830))
+       range = 0;
+
    if (IS_I85X(pI830) || IS_I865G(pI830) || IS_I9XX(pI830)) {
       switch (gmch_ctrl & I855_GMCH_GMS_MASK) {
       case I855_GMCH_GMS_STOLEN_1M:
@@ -544,6 +554,22 @@ I830DetectMemory(ScrnInfoPtr pScrn)
 	 if (IS_I9XX(pI830))
 	     memsize = MB(256) - KB(range);
 	 break;
+      case INTEL_GMCH_GMS_STOLEN_96M:
+	 if (IS_I9XX(pI830))
+	     memsize = MB(96) - KB(range);
+	 break;
+      case INTEL_GMCH_GMS_STOLEN_160M:
+	 if (IS_I9XX(pI830))
+	     memsize = MB(160) - KB(range);
+	 break;
+      case INTEL_GMCH_GMS_STOLEN_224M:
+	 if (IS_I9XX(pI830))
+	     memsize = MB(224) - KB(range);
+	 break;
+      case INTEL_GMCH_GMS_STOLEN_352M:
+	 if (IS_I9XX(pI830))
+	     memsize = MB(352) - KB(range);
+	 break;
       }
    } else {
       switch (gmch_ctrl & I830_GMCH_GMS_MASK) {
@@ -627,7 +653,7 @@ I830MapMMIO(ScrnInfoPtr pScrn)
 
       if (IS_I965G(pI830)) 
       {
-	 if (IS_IGD_GM(pI830)) {
+	 if (IS_IGD_GM(pI830) || IS_G4X(pI830)) {
 	     gttaddr = pI830->MMIOAddr + MB(2);
 	     pI830->GTTMapSize = MB(2);
 	 } else {
@@ -1182,8 +1208,15 @@ i830_detect_chipset(ScrnInfoPtr pScrn)
 	chipname = "Q33";
 	break;
     case PCI_CHIP_IGD_GM:
+    case PCI_CHIP_IGD_E_G:
 	chipname = "Intel Integrated Graphics Device";
 	break;
+    case PCI_CHIP_G45_G:
+	chipname = "G45/G43";
+	break;
+    case PCI_CHIP_Q45_G:
+	chipname = "Q45/Q43";
+	break;
    default:
 	chipname = "unknown chipset";
 	break;
@@ -2952,7 +2985,7 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
 		    "needs 2D acceleration.\n");
 	 pI830->XvEnabled = FALSE;
       }
-      if (!IS_IGD_GM(pI830) && pI830->overlay_regs == NULL) {
+      if (!OVERLAY_NOEXIST(pI830) && pI830->overlay_regs == NULL) {
 	  xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
 		     "Disabling Xv because the overlay register buffer "
 		      "allocation failed.\n");
diff --git a/src/i830_memory.c b/src/i830_memory.c
index 6f7d7cc..6e7a838 100644
--- a/src/i830_memory.c
+++ b/src/i830_memory.c
@@ -447,7 +447,7 @@ i830_allocator_init(ScrnInfoPtr pScrn, unsigned long offset, unsigned long size)
 	/* Overlay and cursors, if physical, need to be allocated outside
 	 * of the kernel memory manager.
 	 */
-	if (!OVERLAY_NOPHYSICAL(pI830) && !IS_IGD_GM(pI830)) {
+	if (!OVERLAY_NOPHYSICAL(pI830) && !OVERLAY_NOEXIST(pI830)) {
 	    mmsize -= ROUND_TO(OVERLAY_SIZE, GTT_PAGE_SIZE);
 	}
 	if (pI830->CursorNeedsPhysical) {
@@ -459,7 +459,8 @@ i830_allocator_init(ScrnInfoPtr pScrn, unsigned long offset, unsigned long size)
 	/* Can't do TTM on stolen memory */
 	mmsize -= pI830->stolen_size;
 
-	if (HWS_NEED_GFX(pI830) && IS_IGD_GM(pI830))
+	/* new chipsets need non-stolen status page */
+	if (HWS_NEED_GFX(pI830) && HWS_NEED_NONSTOLEN(pI830))
 	    mmsize -= HWSTATUS_PAGE_SIZE;
 
 	/* Create the aperture allocation */
@@ -1027,7 +1028,7 @@ i830_allocate_overlay(ScrnInfoPtr pScrn)
     if (!pI830->XvEnabled)
 	return TRUE;
 
-    if (IS_IGD_GM(pI830))
+    if (OVERLAY_NOEXIST(pI830))
 	return TRUE;
 
     if (!OVERLAY_NOPHYSICAL(pI830))
@@ -1646,7 +1647,7 @@ i830_allocate_hwstatus(ScrnInfoPtr pScrn)
      * (i.e. not through buffer objects).
      */
     flags = NEED_LIFETIME_FIXED;
-    if (IS_IGD_GM(pI830))
+    if (HWS_NEED_NONSTOLEN(pI830))
 	    flags |= NEED_NON_STOLEN;
     pI830->hw_status = i830_allocate_memory(pScrn, "HW status",
 	    HWSTATUS_PAGE_SIZE, GTT_PAGE_SIZE, flags);
diff --git a/src/i830_video.c b/src/i830_video.c
index e109578..7b81b04 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -620,7 +620,7 @@ I830InitVideo(ScreenPtr pScreen)
     }
 
     /* Set up overlay video if we can do it at this depth. */
-    if (!IS_IGD_GM(pI830) && pScrn->bitsPerPixel != 8 &&
+    if (!OVERLAY_NOEXIST(pI830) && pScrn->bitsPerPixel != 8 &&
 	    pI830->overlay_regs != NULL)
     {
 	overlayAdaptor = I830SetupImageVideoOverlay(pScreen);
diff --git a/src/i965_render.c b/src/i965_render.c
index 4a8f9b8..a3c7f49 100644
--- a/src/i965_render.c
+++ b/src/i965_render.c
@@ -1035,7 +1035,7 @@ i965_prepare_composite(int op, PicturePtr pSrcPicture,
         BEGIN_BATCH(12);
 
         /* Match Mesa driver setup */
-	if (IS_IGD_GM(pI830))
+	if (IS_IGD_GM(pI830) || IS_G4X(pI830))
 	    OUT_BATCH(NEW_PIPELINE_SELECT | PIPELINE_SELECT_3D);
 	else
 	    OUT_BATCH(BRW_PIPELINE_SELECT | PIPELINE_SELECT_3D);
diff --git a/src/i965_video.c b/src/i965_video.c
index 485c89a..4572e13 100644
--- a/src/i965_video.c
+++ b/src/i965_video.c
@@ -584,7 +584,7 @@ I965DisplayVideoTextured(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv, int id,
     {
 	BEGIN_BATCH(12);
 	/* Match Mesa driver setup */
-	if (IS_IGD_GM(pI830))
+	if (IS_IGD_GM(pI830) || IS_G4X(pI830))
 	    OUT_BATCH(NEW_PIPELINE_SELECT | PIPELINE_SELECT_3D);
 	else
 	    OUT_BATCH(BRW_PIPELINE_SELECT | PIPELINE_SELECT_3D);
commit 289790c0467d27e96b537598a6589fc6a36da8b8
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Tue Jun 17 09:46:12 2008 +0800

    Fix compiling with server master in LVDS backlight patch

diff --git a/src/i830_lvds.c b/src/i830_lvds.c
index ecb41c9..4f62a2b 100644
--- a/src/i830_lvds.c
+++ b/src/i830_lvds.c
@@ -1145,6 +1145,8 @@ i830_lvds_set_property(xf86OutputPtr output, Atom property,
 static Bool
 i830_lvds_get_property(xf86OutputPtr output, Atom property)
 {
+    ScrnInfoPtr		    pScrn = output->scrn;
+    I830Ptr		    pI830 = I830PTR(pScrn);
     I830OutputPrivatePtr    intel_output = output->driver_private;
     struct i830_lvds_priv   *dev_priv = intel_output->dev_priv;
     int ret;
commit 66418cc99cfd360e303efcdf74a9ee31d435ff15
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Thu Jun 12 14:04:41 2008 +0800

    Fix compiler warning when disable xvmc config
    (cherry picked from commit df0bbdc7cbb6ff357a81ed28d12e56c9c7d643f7)

diff --git a/src/i830_memory.c b/src/i830_memory.c
index 02b1679..6f7d7cc 100644
--- a/src/i830_memory.c
+++ b/src/i830_memory.c
@@ -2023,6 +2023,7 @@ I830CheckAvailableMemory(ScrnInfoPtr pScrn)
     return maxPages * 4;
 }
 
+#ifdef INTEL_XVMC
 /*
  * Allocate memory for MC compensation
  */
@@ -2044,3 +2045,4 @@ Bool i830_allocate_xvmc_buffer(ScrnInfoPtr pScrn, const char *name,
 
     return TRUE;
 }
+#endif
commit 078d05865884ca5784b532c0a79c8440632002ac
Author: Shuang He <shuang.he at intel.com>
Date:   Mon May 26 09:20:53 2008 +0800

    Fix typo in xvmc block destroy
    (cherry picked from commit 87ace420a34df7425641d089f71830e44fced098)

diff --git a/src/xvmc/intel_xvmc.c b/src/xvmc/intel_xvmc.c
index ae357aa..0db3ca6 100644
--- a/src/xvmc/intel_xvmc.c
+++ b/src/xvmc/intel_xvmc.c
@@ -588,7 +588,7 @@ Status XvMCCreateBlocks(Display *display, XvMCContext *context,
  */
 Status XvMCDestroyBlocks(Display *display, XvMCBlockArray *block)
 {
-    if (!display || block)
+    if (!display || !block)
         return BadValue;
 
     if (block->blocks)
commit 4c4ef27779aebf4df90b6233de05be2bb972de4c
Author: Lukas Hejtmanek <xhejtman at ics.muni.cz>
Date:   Mon Jun 16 02:49:41 2008 +0800

    Fix maximum backlight issue

diff --git a/src/i830_lvds.c b/src/i830_lvds.c
index 899c6cb..ecb41c9 100644
--- a/src/i830_lvds.c
+++ b/src/i830_lvds.c
@@ -63,6 +63,9 @@ struct i830_lvds_priv {
     /* The panel needs dithering enabled */
     Bool	    panel_wants_dither;
 
+    /* The panel is in DPMS off */
+    Bool           dpmsoff;
+
     /* restore backlight to this value */
     int		    backlight_duty_cycle;
 
@@ -334,6 +337,7 @@ i830_lvds_get_backlight_kernel(xf86OutputPtr output)
 	return 0;
     }
 
+    memset(val, 0, sizeof(val));
     if (read(fd, val, BACKLIGHT_VALUE_LEN) == -1)
 	goto out_err;
 
@@ -388,6 +392,10 @@ i830SetLVDSPanelPower(xf86OutputPtr output, Bool on)
     uint32_t		    pp_status;
 
     if (on) {
+	/* if we're going from on->on, be aware to current level. */
+	if ((INREG(PP_CONTROL) & POWER_TARGET_ON) && !dev_priv->dpmsoff) 
+	    dev_priv->backlight_duty_cycle = dev_priv->get_backlight(output);
+
 	/*
 	 * If we're going from off->on we may need to turn on the backlight.
 	 * We should use the saved value whenever possible, but on some
@@ -405,12 +413,13 @@ i830SetLVDSPanelPower(xf86OutputPtr output, Bool on)
 	} while ((pp_status & PP_ON) == 0);
 
 	dev_priv->set_backlight(output, dev_priv->backlight_duty_cycle);
+	dev_priv->dpmsoff = FALSE;
     } else {
 	/*
 	 * Only save the current backlight value if we're going from
 	 * on to off.
 	 */
-	if (INREG(PP_CONTROL) & POWER_TARGET_ON)
+	if ((INREG(PP_CONTROL) & POWER_TARGET_ON) && !dev_priv->dpmsoff)
 	    dev_priv->backlight_duty_cycle = dev_priv->get_backlight(output);
 	dev_priv->set_backlight(output, 0);
 
@@ -418,6 +427,8 @@ i830SetLVDSPanelPower(xf86OutputPtr output, Bool on)
 	do {
 	    pp_status = INREG(PP_STATUS);
 	} while (pp_status & PP_ON);
+
+	dev_priv->dpmsoff = TRUE;
     }
 }
 
@@ -447,7 +458,8 @@ 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 = dev_priv->get_backlight(output);
+    if ((INREG(PP_CONTROL) & POWER_TARGET_ON) && !dev_priv->dpmsoff) 
+	dev_priv->backlight_duty_cycle = dev_priv->get_backlight(output);
 }
 
 static void
@@ -1081,7 +1093,10 @@ i830_lvds_set_property(xf86OutputPtr output, Atom property,
 		       "RRConfigureOutputProperty error, %d\n", ret);
 	}
 	/* Set the current value of the backlight property */
-	data = dev_priv->get_backlight(output);
+	if ((INREG(PP_CONTROL) & POWER_TARGET_ON) && !dev_priv->dpmsoff) 
+	    data = dev_priv->get_backlight(output);
+	else
+	    data = dev_priv->backlight_duty_cycle;
 	ret = RRChangeOutputProperty(output->randr_output, backlight_atom,
 				     XA_INTEGER, 32, PropModeReplace, 1, &data,
 				     FALSE, TRUE);
@@ -1140,8 +1155,11 @@ i830_lvds_get_property(xf86OutputPtr output, Atom property)
      */
     if (property == backlight_atom) {
 	int val;
-	val = dev_priv->get_backlight(output);
-	dev_priv->backlight_duty_cycle = val;
+	if ((INREG(PP_CONTROL) & POWER_TARGET_ON) && !dev_priv->dpmsoff) {
+	    val = dev_priv->get_backlight(output);
+	    dev_priv->backlight_duty_cycle = val;
+	} else
+	    val = dev_priv->backlight_duty_cycle;
 	ret = RRChangeOutputProperty(output->randr_output, backlight_atom,
 				     XA_INTEGER, 32, PropModeReplace, 1, &val,
 				     FALSE, TRUE);


More information about the xorg-commit mailing list