xf86-video-intel: 112 commits - src/common.h src/i810_driver.c src/i810_reg.h src/i830_display.c src/i830_driver.c src/i830_lvds.c src/i830_sdvo.c

Keith Packard keithp at kemper.freedesktop.org
Fri Mar 30 22:11:36 EEST 2007


 src/common.h       |   10 ++++-
 src/i810_driver.c  |    3 +
 src/i810_reg.h     |   89 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/i830_display.c |   21 ++++++++----
 src/i830_driver.c  |    5 ++
 src/i830_lvds.c    |    9 ++++-
 src/i830_sdvo.c    |   22 +++++++------
 7 files changed, 140 insertions(+), 19 deletions(-)

New commits:
diff-tree aa6a9abb34e93780c07563ab5b21d8c064ea0a1c (from parents)
Merge: 670c8521f18f01b9ea899ceb68d2a3dbb884b199 107ac12867eda6b86212159db15c640d3490f2da
Author: Keith Packard <keithp at neko.keithp.com>
Date:   Fri Mar 30 12:10:17 2007 -0700

    Merge branch 'crestline-qa'

diff-tree 107ac12867eda6b86212159db15c640d3490f2da (from parents)
Merge: 654881794ae1ad7214e85091b9015ae0fbdc5ddc 2191634dd67b3219bb88f365bcf951d5a58140e8
Author: Nian Wu <nian.wu at intel.com>
Date:   Tue Mar 27 12:51:45 2007 +0800

    Merge git://proxy01.pd.intel.com:9419/git/xorg/driver/xf86-video-intel into crestline

diff-tree 654881794ae1ad7214e85091b9015ae0fbdc5ddc (from parents)
Merge: 6de3edcb52e6258f1af75e4f4bef73de1698445d d5727717c9141be28a69b1154ccd23c23207f8f6
Author: Nian Wu <nian.wu at intel.com>
Date:   Mon Mar 26 17:00:11 2007 +0800

    Merge git://proxy01.pd.intel.com:9419/git/xorg/driver/xf86-video-intel into crestline

diff-tree 6de3edcb52e6258f1af75e4f4bef73de1698445d (from parents)
Merge: d874aa31599da4777438cc51469afe9b66601f55 1e6e675524461ef0eb1983de89e2877426571a55
Author: Nian Wu <nian.wu at intel.com>
Date:   Sat Mar 24 17:00:13 2007 +0800

    Merge git://proxy01.pd.intel.com:9419/git/xorg/driver/xf86-video-intel into crestline

diff-tree d874aa31599da4777438cc51469afe9b66601f55 (from parents)
Merge: 94dbc3725358d63fe0ac8e6749489c993d24ede2 26f32ef680a19e63af4b7c8c84141fe32263f298
Author: Nian Wu <nian.wu at intel.com>
Date:   Fri Mar 23 17:00:12 2007 +0800

    Merge git://proxy01.pd.intel.com:9419/git/xorg/driver/xf86-video-intel into crestline

diff-tree 94dbc3725358d63fe0ac8e6749489c993d24ede2 (from parents)
Merge: 28af380ab133eb14d21dc650c77bdbab66576255 20b26854abdacb6dc45cba2d81d515b2e47e25f1
Author: Nian Wu <nian.wu at intel.com>
Date:   Thu Mar 22 17:00:15 2007 +0800

    Merge git://proxy01.pd.intel.com:9419/git/xorg/driver/xf86-video-intel into crestline

diff-tree 28af380ab133eb14d21dc650c77bdbab66576255 (from parents)
Merge: 300e893cec19dca48e00ee25014b8714dc13b278 e06c5f727fb2e2de111ac9e691a877c56d2ca1b4
Author: Nian Wu <nian.wu at intel.com>
Date:   Wed Mar 21 17:00:04 2007 +0800

    Merge branch 'crestline' of git://otc-graphics.jf.intel.com/git/xorg/driver/xf86-video-intel into crestline

diff-tree e06c5f727fb2e2de111ac9e691a877c56d2ca1b4 (from parents)
Merge: 02023998663cc7f0735fadfb1719d93dc2e5a112 3025fa0fb2bf5ace7076796e45e2560fe8410e8d
Author: Wang Zhenyu <zhenyu.z.wang at intel.com>
Date:   Wed Mar 21 15:04:21 2007 +0800

    Merge branch 'master' into crestline

diff-tree 02023998663cc7f0735fadfb1719d93dc2e5a112 (from 3e9ec78b4f54defb9986e11e6f2ac3475755849d)
Author: Eric Anholt <eric at anholt.net>
Date:   Wed Mar 21 00:00:56 2007 -0700

    Whitespace and symbolic reg names cleanup in i830_panel_fitter_pipe().

diff --git a/src/i830_display.c b/src/i830_display.c
index 5cedd77..0d0cdf0 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -673,23 +673,23 @@ i830_get_core_clock_speed(ScrnInfoPtr pS
  * or -1 if the panel fitter is not present or not in use
  */
 static int
-i830_panel_fitter_pipe (I830Ptr	pI830)
+i830_panel_fitter_pipe(I830Ptr pI830)
 {
     CARD32  pfit_control;
-    
+
     /* i830 doesn't have a panel fitter */
     if (IS_I830(pI830))
 	return -1;
-    
+
     pfit_control = INREG(PFIT_CONTROL);
-    
+
     /* See if the panel fitter is in use */
     if ((pfit_control & PFIT_ENABLE) == 0)
 	return -1;
-    
+
     /* 965 can place panel fitter on either pipe */
     if (IS_I965G(pI830))
-	return (pfit_control >> 29) & 0x3;
+	return (pfit_control & PFIT_PIPE_MASK) >> PFIT_PIPE_SHIFT;
 
     /* older chips can only use pipe 1 */
     return 1;
diff-tree 3e9ec78b4f54defb9986e11e6f2ac3475755849d (from a50009604152bf9237c40bd098b3b1da3d018929)
Author: Eric Anholt <eric at anholt.net>
Date:   Tue Mar 20 23:58:48 2007 -0700

    Set the panel fitter to the right pipe on Crestline.

diff --git a/src/i810_reg.h b/src/i810_reg.h
index e4bebaf..eaa8bb5 100644
--- a/src/i810_reg.h
+++ b/src/i810_reg.h
@@ -830,6 +830,8 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN
 
 #define PFIT_CONTROL	0x61230
 # define PFIT_ENABLE				(1 << 31)
+# define PFIT_PIPE_MASK				(3 << 29)
+# define PFIT_PIPE_SHIFT			29
 # define VERT_INTERP_DISABLE			(0 << 10)
 # define VERT_INTERP_BILINEAR			(1 << 10)
 # define VERT_INTERP_MASK			(3 << 10)
diff --git a/src/i830_lvds.c b/src/i830_lvds.c
index 7e5ce67..2ad52a7 100644
--- a/src/i830_lvds.c
+++ b/src/i830_lvds.c
@@ -216,6 +216,7 @@ i830_lvds_mode_set(xf86OutputPtr output,
 {
     ScrnInfoPtr pScrn = output->scrn;
     I830Ptr pI830 = I830PTR(pScrn);
+    I830CrtcPrivatePtr intel_crtc = output->crtc->driver_private;
     CARD32 pfit_control;
 
     /* The LVDS pin pair will already have been turned on in the
@@ -230,9 +231,12 @@ i830_lvds_mode_set(xf86OutputPtr output,
 		    VERT_AUTO_SCALE | HORIZ_AUTO_SCALE |
 		    VERT_INTERP_BILINEAR | HORIZ_INTERP_BILINEAR);
 
-    if (!IS_I965G(pI830))
+    if (!IS_I965G(pI830)) {
 	if (pI830->panel_wants_dither)
 	    pfit_control |= PANEL_8TO6_DITHER_ENABLE;
+    } else {
+	pfit_control |= intel_crtc->pipe << PFIT_PIPE_SHIFT;
+    }
 
     OUTREG(PFIT_CONTROL, pfit_control);
 }
diff-tree a50009604152bf9237c40bd098b3b1da3d018929 (from parents)
Merge: 0a612e7115ff993bb8e9a00df13c0b0d20122fd6 223944878cf38f86580df5a7d3102d86cfc061b9
Author: Eric Anholt <eric at anholt.net>
Date:   Tue Mar 20 23:32:19 2007 -0700

    Merge branch 'master' into crestline
    
    Conflicts:
    
    	src/i810_reg.h
    	src/i830_display.c

diff --cc src/i810_reg.h
index f50646b,4c6e582..e4bebaf
@@@ -1128,110 -1128,58 +1128,145 @@@
  #define DVO_SRCDIM_HORIZONTAL_SHIFT	12
  #define DVO_SRCDIM_VERTICAL_SHIFT	0
  
+ /** @defgroup LVDS
+  * @{
+  */
+ /**
+  * This register controls the LVDS output enable, pipe selection, and data
+  * format selection.
+  *
+  * All of the clock/data pairs are force powered down by power sequencing.
+  */
  #define LVDS			0x61180
+ /**
+  * Enables the LVDS port.  This bit must be set before DPLLs are enabled, as
+  * the DPLL semantics change when the LVDS is assigned to that pipe.
+  */
  # define LVDS_PORT_EN			(1 << 31)
+ /** Selects pipe B for LVDS data.  Must be set on pre-965. */
  # define LVDS_PIPEB_SELECT		(1 << 30)
  
 +/* on 965, dithering is enabled in this register, not PFIT_CONTROL */
 +# define LVDS_DITHER_ENABLE		(1 << 25)
 +
 +/*
 + * Selects between .0 and .1 formats:
 + *
 + * 0 = 1x18.0, 2x18.0, 1x24.0 or 2x24.0
 + * 1 = 1x24.1 or 2x24.1
 + */
 +# define LVDS_DATA_FORMAT_DOT_ONE	(1 << 24)
 +
 +/* Using LE instead of HS on second channel control signal */
 +# define LVDS_LE_CONTROL_ENABLE		(1 << 23)
 +
 +/* Using LF instead of VS on second channel control signal */
 +# define LVDS_LF_CONTROL_ENABLE		(1 << 22)
 +
 +/* invert vsync signal polarity */
 +# define LVDS_VSYNC_POLARITY_INVERT	(1 << 21)
 +
 +/* invert hsync signal polarity */
 +# define LVDS_HSYNC_POLARITY_INVERT	(1 << 20)
 +
 +/* invert display enable signal polarity */
 +# define LVDS_DE_POLARITY_INVERT	(1 << 19)
 +
 +/*
 + * Control signals for second channel, ignored in single channel modes
 + */
 +
 +/* send DE, HS, VS on second channel */
 +# define LVDS_SECOND_CHANNEL_DE_HS_VS	(0 << 17)
 +
 +# define LVDS_SECOND_CHANNEL_RESERVED	(1 << 17)
 +
 +/* Send zeros instead of DE, HS, VS on second channel */
 +# define LVDS_SECOND_CHANNEL_ZEROS	(2 << 17)
 +
 +/* Set DE=0, HS=LE, VS=LF on second channel */
 +# define LVDS_SECOND_CHANNEL_HS_VS	(3 << 17)
 +
 +/*
 + * Send duplicate data for channel reserved bits, otherwise send zeros
 + */
 +# define LVDS_CHANNEL_DUP_RESERVED	(1 << 16)
 +
 +/*
 + * Enable border for unscaled (or aspect-scaled) display
 + */
 +# define LVDS_BORDER_ENABLE		(1 << 15)
 +
 +/*
 + * Tri-state the LVDS buffers when powered down, otherwise
 + * they are set to 0V
 + */
 +# define LVDS_POWER_DOWN_TRI_STATE	(1 << 10)
 +
- /*
-  * Clock A control; overridden by LVDS power sequencing
+ /**
+  * Enables the A0-A2 data pairs and CLKA, containing 18 bits of color data per
+  * pixel.
   */
+ # define LVDS_A0A2_CLKA_POWER_MASK	(3 << 8)
+ # define LVDS_A0A2_CLKA_POWER_DOWN	(0 << 8)
+ # define LVDS_A0A2_CLKA_POWER_UP	(3 << 8)
+ /**
+  * Controls the A3 data pair, which contains the additional LSBs for 24 bit
+  * mode.  Only enabled if LVDS_A0A2_CLKA_POWER_UP also indicates it should be
+  * on.
+  */
+ # define LVDS_A3_POWER_MASK		(3 << 6)
+ # define LVDS_A3_POWER_DOWN		(0 << 6)
+ # define LVDS_A3_POWER_UP		(3 << 6)
+ /**
+  * Controls the CLKB pair.  This should only be set when LVDS_B0B3_POWER_UP
+  * is set.
+  */
+ # define LVDS_CLKB_POWER_MASK		(3 << 4)
+ # define LVDS_CLKB_POWER_DOWN		(0 << 4)
+ # define LVDS_CLKB_POWER_UP		(3 << 4)
  
- /* power down everything including A3 (0V) */
- # define LVDS_CLKA_POWER_DOWN		(0 << 8)
- 
- /* Partially active. A0, A1, A2 set to 0, timing active, clock active */
- # define LVDS_CLKA_POWER_PARTIAL	(1 << 8)
+ /**
+  * Controls the B0-B3 data pairs.  This must be set to match the DPLL p2
+  * setting for whether we are in dual-channel mode.  The B3 pair will
+  * additionally only be powered up when LVDS_A3_POWER_UP is set.
+  */
+ # define LVDS_B0B3_POWER_MASK		(3 << 2)
+ # define LVDS_B0B3_POWER_DOWN		(0 << 2)
+ # define LVDS_B0B3_POWER_UP		(3 << 2)
  
- /* running, data and clock active */
- # define LVDS_CLKA_POWER_UP		(3 << 8)
+ /** @} */
  
 +/*
 + * Two channel clock control. Turn this on if you need clkb for two channel mode
 + * Overridden by global LVDS power sequencing
 + */
 +
 +/* clkb off */
 +# define LVDS_CLKB_POWER_DOWN		(0 << 4)
 +
 +/* powered up, but clkb forced to 0 */
 +# define LVDS_CLKB_POWER_PARTIAL	(1 << 4)
 +
 +/* clock B running */
 +# define LVDS_CLKB_POWER_UP		(3 << 4)
 +
 +/*
 + * Two channel mode B0-B2 control. Sets state when power is on.
 + * Set to POWER_DOWN in single channel mode, other settings enable
 + * two channel mode. The CLKB power control controls whether that clock
 + * is enabled during two channel mode.
 + *
 + */
 +/* Everything is off, including B3 and CLKB */
 +# define LVDS_B_POWER_DOWN		(0 << 2)
 +
 +/* B0, B1, B2 and data lines forced to 0. timing is active */
 +# define LVDS_B_POWER_PARTIAL		(1 << 2)
 +
 +/* data lines active (both timing and colour) */
 +# define LVDS_B_POWER_UP		(3 << 2)
 +
  /** @defgroup TV_CTL
   * @{
   */
diff --cc src/i830_display.c
index 2810a8b,d55e0a6..5cedd77
@@@ -890,22 -904,28 +904,37 @@@
  	usleep(150);
      }
  
+     /* The LVDS pin pair needs to be on before the DPLLs are enabled.
+      * This is an exception to the general rule that mode_set doesn't turn
+      * things on.
+      */
      if (is_lvds)
      {
- 	CARD32	lvds = INREG(LVDS);
+ 	CARD32 lvds = INREG(LVDS);
+ 
+ 	lvds |= LVDS_PORT_EN | LVDS_A0A2_CLKA_POWER_UP | LVDS_PIPEB_SELECT;
+ 	/* Set the B0-B3 data pairs corresponding to whether we're going to
+ 	 * set the DPLLs for dual-channel mode or not.
+ 	 */
+ 	if (adjusted_mode->Clock >= I9XX_P2_LVDS_SLOW_LIMIT)
+ 	    lvds |= LVDS_B0B3_POWER_UP | LVDS_CLKB_POWER_UP;
+ 	else
+ 	    lvds &= ~(LVDS_B0B3_POWER_UP | LVDS_CLKB_POWER_UP);
  
- 	/* The LVDS pin pair needs to be on before the DPLLs are enabled.
- 	 * This is an exception to the general rule that mode_set doesn't turn
- 	 * things on.
+ 	/* It would be nice to set 24 vs 18-bit mode (LVDS_A3_POWER_UP)
+ 	 * appropriately here, but we need to look more thoroughly into how
+ 	 * panels behave in the two modes.
  	 */
- 	lvds |= LVDS_PORT_EN | LVDS_PIPEB_SELECT;
+ 
++	/* Enable dithering if we're in 18-bit mode. */
 +	if (IS_I965G(pI830))
 +	{
- 	    if (pI830->panel_wants_dither)
++	    if ((lvds & LVDS_A3_POWER_MASK) == LVDS_A3_POWER_UP)
 +		lvds |= LVDS_DITHER_ENABLE;
 +	    else
 +		lvds &= ~LVDS_DITHER_ENABLE;
 +	}
++
  	OUTREG(LVDS, lvds);
  	POSTING_READ(LVDS);
      }
diff-tree 300e893cec19dca48e00ee25014b8714dc13b278 (from parents)
Merge: 96e86994f3d1b4938e99a751454ee99bebfe40d3 02023998663cc7f0735fadfb1719d93dc2e5a112
Author: Nian Wu <nian.wu at intel.com>
Date:   Wed Mar 21 08:55:50 2007 +0800

    Merge branch 'crestline' of git://otc-graphics.jf.intel.com/git/xorg/driver/xf86-video-intel into crestline

diff-tree 96e86994f3d1b4938e99a751454ee99bebfe40d3 (from parents)
Merge: f465c23750adf908c0ea874f95aad98ebd2f1015 0a612e7115ff993bb8e9a00df13c0b0d20122fd6
Author: Nian Wu <nian.wu at intel.com>
Date:   Tue Mar 20 13:11:09 2007 +0800

    Merge branch 'crestline' of git://otc-graphics.jf.intel.com/git/xorg/driver/xf86-video-intel into crestline

diff-tree 0a612e7115ff993bb8e9a00df13c0b0d20122fd6 (from parents)
Merge: 8bb677889d3f71cde671f17a3589939acad2c3b3 4c4faf260eb4dad1b1919c6168fa9ef477b98a39
Author: Wang Zhenyu <zhenyu.z.wang at intel.com>
Date:   Tue Mar 20 11:34:40 2007 +0800

    Merge branch 'master' of git://proxy.ims.intel.com:9419/git/xorg/driver/xf86-video-intel into crestline
    
    Conflicts:
    
    	src/i830_display.c
    
    Change LVDS output and postread like upstream. This might
    need to be retested on 965GM LVDS.

diff --cc src/i830_display.c
index 784dce7,faa3781..2810a8b
@@@ -917,32 -896,13 +898,21 @@@
  	 * This is an exception to the general rule that mode_set doesn't turn
  	 * things on.
  	 */
 -	OUTREG(LVDS, INREG(LVDS) | LVDS_PORT_EN | LVDS_PIPEB_SELECT);
 +	lvds |= LVDS_PORT_EN | LVDS_PIPEB_SELECT;
 +	if (IS_I965G(pI830))
 +	{
 +	    if (pI830->panel_wants_dither)
 +		lvds |= LVDS_DITHER_ENABLE;
 +	    else
 +		lvds &= ~LVDS_DITHER_ENABLE;
 +	}
 +	OUTREG(LVDS, lvds);
+ 	POSTING_READ(LVDS);
      }
-     
-     /* Disable the panel fitter if it was on our pipe */
-     if (i830_panel_fitter_pipe (pI830) == pipe)
- 	OUTREG(PFIT_CONTROL, 0);
  
-     i830PrintPll("chosen", &clock);
-     ErrorF("clock regs: 0x%08x, 0x%08x\n", (int)dpll, (int)fp);
- 
-     if (dpll & DPLL_VCO_ENABLE)
-     {
- 	OUTREG(fp_reg, fp);
- 	OUTREG(dpll_reg, dpll & ~DPLL_VCO_ENABLE);
- 	usleep(150);
-     }
      OUTREG(fp_reg, fp);
      OUTREG(dpll_reg, dpll);
+     POSTING_READ(dpll_reg);
      /* Wait for the clocks to stabilize. */
      usleep(150);
      
diff-tree f465c23750adf908c0ea874f95aad98ebd2f1015 (from parents)
Merge: d33e8daa6874ced978d2a1f687c48922555f2524 1ed3843f73a0d8efa405daff3483ebe70bf6134f
Author: Nian Wu <nian.wu at intel.com>
Date:   Tue Mar 13 17:00:44 2007 +0800

    Merge git://proxy01.pd.intel.com:9419/git/xorg/driver/xf86-video-intel into crestline

diff-tree d33e8daa6874ced978d2a1f687c48922555f2524 (from parents)
Merge: 58aeb87f2e335d15eba73ce9dd1982e867c52403 797aa6fcb1231587bde1efb47bc8430c4c8d8110
Author: Nian Wu <nian.wu at intel.com>
Date:   Mon Mar 12 09:03:52 2007 +0800

    Merge git://proxy01.pd.intel.com:9419/git/xorg/driver/xf86-video-intel into crestline

diff-tree 58aeb87f2e335d15eba73ce9dd1982e867c52403 (from parents)
Merge: a4e7e814a24dbe30a33e6ad45baeb41d190a2724 81722a21d232fa6cfb11fbe3d984abab50e89bcc
Author: Nian Wu <nian.wu at intel.com>
Date:   Wed Mar 7 16:02:03 2007 -0500

    Merge git://proxy01.pd.intel.com:9419/git/xorg/driver/xf86-video-intel into crestline

diff-tree a4e7e814a24dbe30a33e6ad45baeb41d190a2724 (from parents)
Merge: 862088ba6a91d3e7cf8d37126b1d9f4ee03a1f73 4042b27f01fdb94e7fc0d4e991e054fff88479ea
Author: Nian Wu <nian.wu at intel.com>
Date:   Tue Mar 6 16:01:40 2007 -0500

    Merge git://proxy01.pd.intel.com:9419/git/xorg/driver/xf86-video-intel into crestline

diff-tree 862088ba6a91d3e7cf8d37126b1d9f4ee03a1f73 (from parents)
Merge: 11e91586169b4f4bf2b41c0e0e620a69670c2f07 d717d9d566fe3c0866b06840114e1c1990bd7be0
Author: Nian Wu <nian.wu at intel.com>
Date:   Tue Mar 6 07:43:16 2007 -0500

    Merge git://proxy01.pd.intel.com:9419/git/xorg/driver/xf86-video-intel into crestline

diff-tree 11e91586169b4f4bf2b41c0e0e620a69670c2f07 (from parents)
Merge: a24962af9ed39fabca0152cae1265a29fe6237d3 015027034e970f1e3bb6ab239f7e0119235e404f
Author: Nian Wu <nian.wu at intel.com>
Date:   Mon Mar 5 16:00:20 2007 -0500

    Merge git://proxy01.pd.intel.com:9419/git/xorg/driver/xf86-video-intel into crestline

diff-tree a24962af9ed39fabca0152cae1265a29fe6237d3 (from parents)
Merge: 35e9310ef59873877422dcaf9a65b38789fc8ad6 8bb677889d3f71cde671f17a3589939acad2c3b3
Author: Nian Wu <nian.wu at intel.com>
Date:   Mon Mar 5 16:00:11 2007 -0500

    Merge branch 'crestline' of git://otc-graphics.jf.intel.com/git/xorg/driver/xf86-video-intel into crestline

diff-tree 35e9310ef59873877422dcaf9a65b38789fc8ad6 (from parents)
Merge: c8e6f0bac13e0e407f9771b1bbf126f023c1511b b27fa2c257ccc49c6f29a20a3e672ebaaf58e7aa
Author: Nian Wu <nian.wu at intel.com>
Date:   Mon Mar 5 09:01:55 2007 -0500

    Merge branch 'modesetting' of git://proxy01.pd.intel.com:9419/git/xorg/driver/xf86-video-intel into crestline

diff-tree 8bb677889d3f71cde671f17a3589939acad2c3b3 (from a0c83af3430b6705ab2ecae59085d1c74e890c19)
Author: Eric Anholt <eric at anholt.net>
Date:   Mon Mar 5 05:08:51 2007 -0800

    Fix 965GM SDVO by not setting fields in SDVO[BC] which have new meanings.

diff --git a/src/i830_sdvo.c b/src/i830_sdvo.c
index b7cf843..ab01028 100644
--- a/src/i830_sdvo.c
+++ b/src/i830_sdvo.c
@@ -647,16 +647,20 @@ i830_sdvo_mode_set(xf86OutputPtr output,
     }
 
     /* Set the SDVO control regs. */
-    sdvox = INREG(dev_priv->output_device);
-    switch (dev_priv->output_device) {
-    case SDVOB:
-	sdvox &= SDVOB_PRESERVE_MASK;
-	break;
-    case SDVOC:
-	sdvox &= SDVOC_PRESERVE_MASK;
-	break;
+    if (IS_I965GM(pI830)) {
+	sdvox = SDVO_BORDER_ENABLE;
+    } else {
+	sdvox = INREG(dev_priv->output_device);
+	switch (dev_priv->output_device) {
+	case SDVOB:
+	    sdvox &= SDVOB_PRESERVE_MASK;
+	    break;
+	case SDVOC:
+	    sdvox &= SDVOC_PRESERVE_MASK;
+	    break;
+	}
+	sdvox |= (9 << 19) | SDVO_BORDER_ENABLE;
     }
-    sdvox |= (9 << 19) | SDVO_BORDER_ENABLE;
     if (intel_crtc->pipe == 1)
 	sdvox |= SDVO_PIPE_B_SELECT;
 
diff-tree a0c83af3430b6705ab2ecae59085d1c74e890c19 (from parents)
Merge: c0f99b4962553e560a5cb882a5060d95db5477a4 bc20b54c34088356a277beaebcc90bb4a7063e19
Author: Eric Anholt <eric at anholt.net>
Date:   Mon Mar 5 03:37:53 2007 -0800

    Merge branch 'modesetting' into crestline

diff-tree c8e6f0bac13e0e407f9771b1bbf126f023c1511b (from parents)
Merge: 0ed5a2fdcfe9674175aa9af155c20695ef41cadc c0f99b4962553e560a5cb882a5060d95db5477a4
Author: Nian Wu <nian.wu at intel.com>
Date:   Sun Mar 4 09:00:12 2007 -0500

    Merge branch 'crestline' of git://otc-graphics.jf.intel.com/git/xorg/driver/xf86-video-intel into crestline

diff-tree c0f99b4962553e560a5cb882a5060d95db5477a4 (from 0fa3d4f51b5ee0dba3882fd74b6ac4e7da708f8f)
Author: Keith Packard <keithp at gamba.jf.intel.com>
Date:   Sat Mar 3 22:36:46 2007 -0800

    LVDS dither control moved from PFIT to LVDS register for Crestline
    
    The LVDS register now contains lots of new controls for dual-channel LVDS control
    along with dither enabling. The PFIT register has a lot fewer controls as a result.

diff --git a/src/i810_reg.h b/src/i810_reg.h
index d63be02..f50646b 100644
--- a/src/i810_reg.h
+++ b/src/i810_reg.h
@@ -1131,9 +1131,107 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN
 #define LVDS			0x61180
 # define LVDS_PORT_EN			(1 << 31)
 # define LVDS_PIPEB_SELECT		(1 << 30)
+
+/* on 965, dithering is enabled in this register, not PFIT_CONTROL */
+# define LVDS_DITHER_ENABLE		(1 << 25)
+
+/*
+ * Selects between .0 and .1 formats:
+ *
+ * 0 = 1x18.0, 2x18.0, 1x24.0 or 2x24.0
+ * 1 = 1x24.1 or 2x24.1
+ */
+# define LVDS_DATA_FORMAT_DOT_ONE	(1 << 24)
+
+/* Using LE instead of HS on second channel control signal */
+# define LVDS_LE_CONTROL_ENABLE		(1 << 23)
+
+/* Using LF instead of VS on second channel control signal */
+# define LVDS_LF_CONTROL_ENABLE		(1 << 22)
+
+/* invert vsync signal polarity */
+# define LVDS_VSYNC_POLARITY_INVERT	(1 << 21)
+
+/* invert hsync signal polarity */
+# define LVDS_HSYNC_POLARITY_INVERT	(1 << 20)
+
+/* invert display enable signal polarity */
+# define LVDS_DE_POLARITY_INVERT	(1 << 19)
+
+/*
+ * Control signals for second channel, ignored in single channel modes
+ */
+
+/* send DE, HS, VS on second channel */
+# define LVDS_SECOND_CHANNEL_DE_HS_VS	(0 << 17)
+
+# define LVDS_SECOND_CHANNEL_RESERVED	(1 << 17)
+
+/* Send zeros instead of DE, HS, VS on second channel */
+# define LVDS_SECOND_CHANNEL_ZEROS	(2 << 17)
+
+/* Set DE=0, HS=LE, VS=LF on second channel */
+# define LVDS_SECOND_CHANNEL_HS_VS	(3 << 17)
+
+/*
+ * Send duplicate data for channel reserved bits, otherwise send zeros
+ */
+# define LVDS_CHANNEL_DUP_RESERVED	(1 << 16)
+
+/*
+ * Enable border for unscaled (or aspect-scaled) display
+ */
+# define LVDS_BORDER_ENABLE		(1 << 15)
+
+/*
+ * Tri-state the LVDS buffers when powered down, otherwise
+ * they are set to 0V
+ */
+# define LVDS_POWER_DOWN_TRI_STATE	(1 << 10)
+
+/*
+ * Clock A control; overridden by LVDS power sequencing
+ */
+
+/* power down everything including A3 (0V) */
 # define LVDS_CLKA_POWER_DOWN		(0 << 8)
+
+/* Partially active. A0, A1, A2 set to 0, timing active, clock active */
+# define LVDS_CLKA_POWER_PARTIAL	(1 << 8)
+
+/* running, data and clock active */
 # define LVDS_CLKA_POWER_UP		(3 << 8)
 
+/*
+ * Two channel clock control. Turn this on if you need clkb for two channel mode
+ * Overridden by global LVDS power sequencing
+ */
+
+/* clkb off */
+# define LVDS_CLKB_POWER_DOWN		(0 << 4)
+
+/* powered up, but clkb forced to 0 */
+# define LVDS_CLKB_POWER_PARTIAL	(1 << 4)
+
+/* clock B running */
+# define LVDS_CLKB_POWER_UP		(3 << 4)
+
+/*
+ * Two channel mode B0-B2 control. Sets state when power is on.
+ * Set to POWER_DOWN in single channel mode, other settings enable
+ * two channel mode. The CLKB power control controls whether that clock
+ * is enabled during two channel mode.
+ *
+ */
+/* Everything is off, including B3 and CLKB */
+# define LVDS_B_POWER_DOWN		(0 << 2)
+
+/* B0, B1, B2 and data lines forced to 0. timing is active */
+# define LVDS_B_POWER_PARTIAL		(1 << 2)
+
+/* data lines active (both timing and colour) */
+# define LVDS_B_POWER_UP		(3 << 2)
+
 /** @defgroup TV_CTL
  * @{
  */
diff --git a/src/i830_display.c b/src/i830_display.c
index e9666de..97d2660 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -884,11 +884,21 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, Dis
 
     if (is_lvds)
     {
+	CARD32	lvds = INREG(LVDS);
+
 	/* The LVDS pin pair needs to be on before the DPLLs are enabled.
 	 * This is an exception to the general rule that mode_set doesn't turn
 	 * things on.
 	 */
-	OUTREG(LVDS, INREG(LVDS) | LVDS_PORT_EN | LVDS_PIPEB_SELECT);
+	lvds |= LVDS_PORT_EN | LVDS_PIPEB_SELECT;
+	if (IS_I965G(pI830))
+	{
+	    if (pI830->panel_wants_dither)
+		lvds |= LVDS_DITHER_ENABLE;
+	    else
+		lvds &= ~LVDS_DITHER_ENABLE;
+	}
+	OUTREG(LVDS, lvds);
     }
     
     /* Disable the panel fitter if it was on our pipe */
diff --git a/src/i830_lvds.c b/src/i830_lvds.c
index 642dd8a..1df8a92 100644
--- a/src/i830_lvds.c
+++ b/src/i830_lvds.c
@@ -241,8 +241,9 @@ i830_lvds_mode_set(xf86OutputPtr output,
 		    VERT_AUTO_SCALE | HORIZ_AUTO_SCALE |
 		    VERT_INTERP_BILINEAR | HORIZ_INTERP_BILINEAR);
 
-    if (pI830->panel_wants_dither)
-	pfit_control |= PANEL_8TO6_DITHER_ENABLE;
+    if (!IS_I965G(pI830))
+	if (pI830->panel_wants_dither)
+	    pfit_control |= PANEL_8TO6_DITHER_ENABLE;
 
     OUTREG(PFIT_CONTROL, pfit_control);
 }
diff-tree 0fa3d4f51b5ee0dba3882fd74b6ac4e7da708f8f (from parents)
Merge: 10655c4674cdac8a231c50dd9afc5d43fe43b4bd fd52d635603b7093c5a2b7fa9c987cf59f9be27c
Author: Keith Packard <keithp at gamba.jf.intel.com>
Date:   Sat Mar 3 21:02:17 2007 -0800

    Merge branch 'modesetting' into crestline

diff-tree 0ed5a2fdcfe9674175aa9af155c20695ef41cadc (from parents)
Merge: 7ba80cc3a5e0f469e3ee55c7537fdc952cd85911 fd52d635603b7093c5a2b7fa9c987cf59f9be27c
Author: Nian Wu <nian.wu at intel.com>
Date:   Sat Mar 3 09:00:20 2007 -0500

    Merge branch 'modesetting' of git://proxy01.pd.intel.com:9419/git/xorg/driver/xf86-video-intel into crestline

diff-tree 7ba80cc3a5e0f469e3ee55c7537fdc952cd85911 (from parents)
Merge: 9796cb7ac4bd74d5336986bb194ff5875b028121 d5df52be59a7dd950e73336ce5698e73480108b0
Author: Nian Wu <nian.wu at intel.com>
Date:   Fri Mar 2 09:01:46 2007 -0500

    Merge branch 'modesetting' of git://proxy01.pd.intel.com:9419/git/xorg/driver/xf86-video-intel into crestline

diff-tree 9796cb7ac4bd74d5336986bb194ff5875b028121 (from parents)
Merge: 42deb1e10fc445d152b74e2b225daeaee2abb3d1 1f5d1666c8386ca4597c6f2c1ec239f9d821da4c
Author: Nian Wu <nian.wu at intel.com>
Date:   Thu Mar 1 09:02:22 2007 -0500

    Merge branch 'modesetting' of git://proxy01.pd.intel.com:9419/git/xorg/driver/xf86-video-intel into crestline

diff-tree 42deb1e10fc445d152b74e2b225daeaee2abb3d1 (from parents)
Merge: 76aac382659bc1dab7dca078f703b9cf48b4ad74 3e8e75e5d83a2fa7e9fc6e9a3fbb07dac548ea5a
Author: Nian Wu <nian.wu at intel.com>
Date:   Wed Feb 28 09:00:24 2007 -0500

    Merge branch 'modesetting' of git://proxy01.pd.intel.com:9419/git/xorg/driver/xf86-video-intel into crestline

diff-tree 76aac382659bc1dab7dca078f703b9cf48b4ad74 (from parents)
Merge: 42fc06c85a0c487cfa26b9d4aa396402dbc4c2fe 1ac83f51ee46d65237eae1b5c767e106ac9e29bc
Author: Nian Wu <nian at tinderbox.sh.intel.com>
Date:   Tue Feb 27 14:42:42 2007 -0500

    Merge branch 'modesetting' of git://proxy01.pd.intel.com:9419/git/xorg/driver/xf86-video-intel into crestline

diff-tree 10655c4674cdac8a231c50dd9afc5d43fe43b4bd (from 9417af8630fce0476273b693ebac12129415e0cf)
Author: Zou Nan hai <nanhai.zou at intel.com>
Date:   Mon Feb 26 09:23:14 2007 +0800

      for merge with external tree

diff --git a/src/i830_xf86Crtc.c b/src/i830_xf86Crtc.c
deleted file mode 100644
index da25577..0000000
--- a/src/i830_xf86Crtc.c
+++ /dev/null
@@ -1,1559 +0,0 @@
-/*
- * Copyright © 2006 Keith Packard
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that copyright
- * notice and this permission notice appear in supporting documentation, and
- * that the name of the copyright holders not be used in advertising or
- * publicity pertaining to distribution of the software without specific,
- * written prior permission.  The copyright holders make no representations
- * about the suitability of this software for any purpose.  It is provided "as
- * is" without express or implied warranty.
- *
- * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
- * OF THIS SOFTWARE.
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <stddef.h>
-#include <string.h>
-#include <stdio.h>
-
-#include "xf86.h"
-#include "xf86DDC.h"
-#include "i830.h"
-#include "i830_xf86Crtc.h"
-#include "i830_xf86Modes.h"
-#include "i830_randr.h"
-#include "X11/extensions/render.h"
-#define DPMS_SERVER
-#include "X11/extensions/dpms.h"
-#include "X11/Xatom.h"
-
-/*
- * Initialize xf86CrtcConfig structure
- */
-
-int xf86CrtcConfigPrivateIndex = -1;
-
-void
-xf86CrtcConfigInit (ScrnInfoPtr scrn)
-{
-    xf86CrtcConfigPtr	config;
-    
-    if (xf86CrtcConfigPrivateIndex == -1)
-	xf86CrtcConfigPrivateIndex = xf86AllocateScrnInfoPrivateIndex();
-    config = xnfcalloc (1, sizeof (xf86CrtcConfigRec));
-    scrn->privates[xf86CrtcConfigPrivateIndex].ptr = config;
-}
- 
-void
-xf86CrtcSetSizeRange (ScrnInfoPtr scrn,
-		      int minWidth, int minHeight,
-		      int maxWidth, int maxHeight)
-{
-    xf86CrtcConfigPtr	config = XF86_CRTC_CONFIG_PTR(scrn);
-
-    config->minWidth = minWidth;
-    config->minHeight = minHeight;
-    config->maxWidth = maxWidth;
-    config->maxHeight = maxHeight;
-}
-
-/*
- * Crtc functions
- */
-xf86CrtcPtr
-xf86CrtcCreate (ScrnInfoPtr		scrn,
-		const xf86CrtcFuncsRec	*funcs)
-{
-    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
-    xf86CrtcPtr		crtc, *crtcs;
-
-    crtc = xcalloc (sizeof (xf86CrtcRec), 1);
-    if (!crtc)
-	return NULL;
-    crtc->scrn = scrn;
-    crtc->funcs = funcs;
-#ifdef RANDR_12_INTERFACE
-    crtc->randr_crtc = NULL;
-#endif
-    crtc->rotation = RR_Rotate_0;
-    crtc->desiredRotation = RR_Rotate_0;
-    if (xf86_config->crtc)
-	crtcs = xrealloc (xf86_config->crtc,
-			  (xf86_config->num_crtc + 1) * sizeof (xf86CrtcPtr));
-    else
-	crtcs = xalloc ((xf86_config->num_crtc + 1) * sizeof (xf86CrtcPtr));
-    if (!crtcs)
-    {
-	xfree (crtc);
-	return NULL;
-    }
-    xf86_config->crtc = crtcs;
-    xf86_config->crtc[xf86_config->num_crtc++] = crtc;
-    return crtc;
-}
-
-void
-xf86CrtcDestroy (xf86CrtcPtr crtc)
-{
-    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn);
-    int			c;
-    
-    (*crtc->funcs->destroy) (crtc);
-    for (c = 0; c < xf86_config->num_crtc; c++)
-	if (xf86_config->crtc[c] == crtc)
-	{
-	    memmove (&xf86_config->crtc[c],
-		     &xf86_config->crtc[c+1],
-		     xf86_config->num_crtc - (c + 1));
-	    xf86_config->num_crtc--;
-	    break;
-	}
-    xfree (crtc);
-}
-
-
-/**
- * Return whether any outputs are connected to the specified pipe
- */
-
-Bool
-xf86CrtcInUse (xf86CrtcPtr crtc)
-{
-    ScrnInfoPtr		pScrn = crtc->scrn;
-    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
-    int			o;
-    
-    for (o = 0; o < xf86_config->num_output; o++)
-	if (xf86_config->output[o]->crtc == crtc)
-	    return TRUE;
-    return FALSE;
-}
-
-/**
- * Sets the given video mode on the given crtc
- */
-Bool
-xf86CrtcSetMode (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation,
-		 int x, int y)
-{
-    ScrnInfoPtr		scrn = crtc->scrn;
-    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
-    int			i;
-    Bool		ret = FALSE;
-    Bool		didLock = FALSE;
-    DisplayModePtr	adjusted_mode;
-    DisplayModeRec	saved_mode;
-    int			saved_x, saved_y;
-    Rotation		saved_rotation;
-
-    adjusted_mode = xf86DuplicateMode(mode);
-
-    crtc->enabled = xf86CrtcInUse (crtc);
-    
-    if (!crtc->enabled)
-    {
-	/* XXX disable crtc? */
-	return TRUE;
-    }
-
-    didLock = crtc->funcs->lock (crtc);
-
-    saved_mode = crtc->mode;
-    saved_x = crtc->x;
-    saved_y = crtc->y;
-    saved_rotation = crtc->rotation;
-    /* Update crtc values up front so the driver can rely on them for mode
-     * setting.
-     */
-    crtc->mode = *mode;
-    crtc->x = x;
-    crtc->y = y;
-    crtc->rotation = rotation;
-
-    /* XXX short-circuit changes to base location only */
-    
-    /* Pass our mode to the outputs and the CRTC to give them a chance to
-     * adjust it according to limitations or output properties, and also
-     * a chance to reject the mode entirely.
-     */
-    for (i = 0; i < xf86_config->num_output; i++) {
-	xf86OutputPtr output = xf86_config->output[i];
-
-	if (output->crtc != crtc)
-	    continue;
-
-	if (!output->funcs->mode_fixup(output, mode, adjusted_mode)) {
-	    goto done;
-	}
-    }
-
-    if (!crtc->funcs->mode_fixup(crtc, mode, adjusted_mode)) {
-	goto done;
-    }
-
-    if (!xf86CrtcRotate (crtc, mode, rotation)) {
-	goto done;
-    }
-
-    /* Disable the outputs and CRTCs before setting the mode. */
-    for (i = 0; i < xf86_config->num_output; i++) {
-	xf86OutputPtr output = xf86_config->output[i];
-
-	if (output->crtc != crtc)
-	    continue;
-
-	/* Disable the output as the first thing we do. */
-	output->funcs->dpms(output, DPMSModeOff);
-    }
-
-    crtc->funcs->dpms(crtc, DPMSModeOff);
-
-    /* Set up the DPLL and any output state that needs to adjust or depend
-     * on the DPLL.
-     */
-    crtc->funcs->mode_set(crtc, mode, adjusted_mode, x, y);
-    for (i = 0; i < xf86_config->num_output; i++) 
-    {
-	xf86OutputPtr output = xf86_config->output[i];
-	if (output->crtc == crtc)
-	    output->funcs->mode_set(output, mode, adjusted_mode);
-    }
-
-    /* Now, enable the clocks, plane, pipe, and outputs that we set up. */
-    crtc->funcs->dpms(crtc, DPMSModeOn);
-    for (i = 0; i < xf86_config->num_output; i++) 
-    {
-	xf86OutputPtr output = xf86_config->output[i];
-	if (output->crtc == crtc)
-	    output->funcs->dpms(output, DPMSModeOn);
-    }
-
-    /* XXX free adjustedmode */
-    ret = TRUE;
-done:
-    if (!ret) {
-	crtc->x = saved_x;
-	crtc->y = saved_y;
-	crtc->rotation = saved_rotation;
-	crtc->mode = saved_mode;
-    }
-
-    if (didLock)
-	crtc->funcs->unlock (crtc);
-
-    return ret;
-}
-
-/*
- * Output functions
- */
-
-extern XF86ConfigPtr xf86configptr;
-
-typedef enum {
-    OPTION_PREFERRED_MODE,
-    OPTION_POSITION,
-    OPTION_BELOW,
-    OPTION_RIGHT_OF,
-    OPTION_ABOVE,
-    OPTION_LEFT_OF,
-    OPTION_ENABLE,
-    OPTION_DISABLE,
-    OPTION_MIN_CLOCK,
-    OPTION_MAX_CLOCK,
-} OutputOpts;
-
-static OptionInfoRec xf86OutputOptions[] = {
-    {OPTION_PREFERRED_MODE, "PreferredMode",	OPTV_STRING,  {0}, FALSE },
-    {OPTION_POSITION,	    "Position",		OPTV_STRING,  {0}, FALSE },
-    {OPTION_BELOW,	    "Below",		OPTV_STRING,  {0}, FALSE },
-    {OPTION_RIGHT_OF,	    "RightOf",		OPTV_STRING,  {0}, FALSE },
-    {OPTION_ABOVE,	    "Above",		OPTV_STRING,  {0}, FALSE },
-    {OPTION_LEFT_OF,	    "LeftOf",		OPTV_STRING,  {0}, FALSE },
-    {OPTION_ENABLE,	    "Enable",		OPTV_BOOLEAN, {0}, FALSE },
-    {OPTION_DISABLE,	    "Disable",		OPTV_BOOLEAN, {0}, FALSE },
-    {OPTION_MIN_CLOCK,	    "MinClock",		OPTV_FREQ,    {0}, FALSE },
-    {OPTION_MAX_CLOCK,	    "MaxClock",		OPTV_FREQ,    {0}, FALSE },
-    {-1,		    NULL,		OPTV_NONE,    {0}, FALSE },
-};
-
-static void
-xf86OutputSetMonitor (xf86OutputPtr output)
-{
-    char    *option_name;
-    static const char monitor_prefix[] = "monitor-";
-    char    *monitor;
-
-    if (output->options)
-	xfree (output->options);
-
-    output->options = xnfalloc (sizeof (xf86OutputOptions));
-    memcpy (output->options, xf86OutputOptions, sizeof (xf86OutputOptions));
-    
-    option_name = xnfalloc (strlen (monitor_prefix) +
-			    strlen (output->name) + 1);
-    strcpy (option_name, monitor_prefix);
-    strcat (option_name, output->name);
-    monitor = xf86findOptionValue (output->scrn->options, option_name);
-    if (!monitor)
-	monitor = output->name;
-    else
-	xf86MarkOptionUsedByName (output->scrn->options, option_name);
-    xfree (option_name);
-    output->conf_monitor = xf86findMonitor (monitor,
-					    xf86configptr->conf_monitor_lst);
-    if (output->conf_monitor)
-	xf86ProcessOptions (output->scrn->scrnIndex,
-			    output->conf_monitor->mon_option_lst,
-			    output->options);
-}
-
-static Bool
-xf86OutputEnabled (xf86OutputPtr    output)
-{
-    /* Check to see if this output was disabled in the config file */
-    if (xf86ReturnOptValBool (output->options, OPTION_ENABLE, TRUE) == FALSE ||
-	xf86ReturnOptValBool (output->options, OPTION_DISABLE, FALSE) == TRUE)
-    {
-	return FALSE;
-    }
-    return TRUE;
-}
-
-xf86OutputPtr
-xf86OutputCreate (ScrnInfoPtr		    scrn,
-		  const xf86OutputFuncsRec *funcs,
-		  const char		    *name)
-{
-    xf86OutputPtr	output, *outputs;
-    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
-    int			len = strlen (name);
-
-    output = xcalloc (sizeof (xf86OutputRec) + len + 1, 1);
-    if (!output)
-	return NULL;
-    output->scrn = scrn;
-    output->funcs = funcs;
-    output->name = (char *) (output + 1);
-    output->subpixel_order = SubPixelUnknown;
-    strcpy (output->name, name);
-#ifdef RANDR_12_INTERFACE
-    output->randr_output = NULL;
-#endif
-    xf86OutputSetMonitor (output);
-    
-    if (xf86_config->output)
-	outputs = xrealloc (xf86_config->output,
-			  (xf86_config->num_output + 1) * sizeof (xf86OutputPtr));
-    else
-	outputs = xalloc ((xf86_config->num_output + 1) * sizeof (xf86OutputPtr));
-    if (!outputs)
-    {
-	xfree (output);
-	return NULL;
-    }
-    
-    xf86_config->output = outputs;
-    xf86_config->output[xf86_config->num_output++] = output;
-    
-    return output;
-}
-
-Bool
-xf86OutputRename (xf86OutputPtr output, const char *name)
-{
-    int	    len = strlen(name);
-    char    *newname = xalloc (len + 1);
-    
-    if (!newname)
-	return FALSE;	/* so sorry... */
-    
-    strcpy (newname, name);
-    if (output->name != (char *) (output + 1))
-	xfree (output->name);
-    output->name = newname;
-    xf86OutputSetMonitor (output);
-    return TRUE;
-}
-
-void
-xf86OutputDestroy (xf86OutputPtr output)
-{
-    ScrnInfoPtr		scrn = output->scrn;
-    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
-    int			o;
-    
-    (*output->funcs->destroy) (output);
-    while (output->probed_modes)
-	xf86DeleteMode (&output->probed_modes, output->probed_modes);
-    for (o = 0; o < xf86_config->num_output; o++)
-	if (xf86_config->output[o] == output)
-	{
-	    memmove (&xf86_config->output[o],
-		     &xf86_config->output[o+1],
-		     xf86_config->num_output - (o + 1));
-	    xf86_config->num_output--;
-	    break;
-	}
-    if (output->name != (char *) (output + 1))
-	xfree (output->name);
-    xfree (output);
-}
-
-static DisplayModePtr
-xf86DefaultMode (xf86OutputPtr output, int width, int height)
-{
-    DisplayModePtr  target_mode = NULL;
-    DisplayModePtr  mode;
-    int		    target_diff = 0;
-    int		    target_preferred = 0;
-    int		    mm_height;
-    
-    mm_height = output->mm_height;
-    if (!mm_height)
-	mm_height = 203;	/* 768 pixels at 96dpi */
-    /*
-     * Pick a mode closest to 96dpi 
-     */
-    for (mode = output->probed_modes; mode; mode = mode->next)
-    {
-	int	    dpi;
-	int	    preferred = (mode->type & M_T_PREFERRED) != 0;
-	int	    diff;
-
-	if (mode->HDisplay > width || mode->VDisplay > height) continue;
-	dpi = (mode->HDisplay * 254) / (mm_height * 10);
-	diff = dpi - 96;
-	diff = diff < 0 ? -diff : diff;
-	if (target_mode == NULL || (preferred > target_preferred) ||
-	    (preferred == target_preferred && diff < target_diff))
-	{
-	    target_mode = mode;
-	    target_diff = diff;
-	    target_preferred = preferred;
-	}
-    }
-    return target_mode;
-}
-
-static DisplayModePtr
-xf86ClosestMode (xf86OutputPtr output, DisplayModePtr match,
-		 int width, int height)
-{
-    DisplayModePtr  target_mode = NULL;
-    DisplayModePtr  mode;
-    int		    target_diff = 0;
-    
-    /*
-     * Pick a mode closest to the specified mode
-     */
-    for (mode = output->probed_modes; mode; mode = mode->next)
-    {
-	int	    dx, dy;
-	int	    diff;
-
-	if (mode->HDisplay > width || mode->VDisplay > height) continue;
-	
-	/* exact matches are preferred */
-	if (xf86ModesEqual (mode, match))
-	    return mode;
-	
-	dx = match->HDisplay - mode->HDisplay;
-	dy = match->VDisplay - mode->VDisplay;
-	diff = dx * dx + dy * dy;
-	if (target_mode == NULL || diff < target_diff)
-	{
-	    target_mode = mode;
-	    target_diff = diff;
-	}
-    }
-    return target_mode;
-}
-
-static Bool
-xf86OutputHasPreferredMode (xf86OutputPtr output, int width, int height)
-{
-    DisplayModePtr  mode;
-
-    for (mode = output->probed_modes; mode; mode = mode->next)
-    {
-	if (mode->HDisplay > width || mode->VDisplay > height) continue;
-	if (mode->type & M_T_PREFERRED)
-	    return TRUE;
-    }
-    return FALSE;
-}
-
-static int
-xf86PickCrtcs (ScrnInfoPtr	scrn,
-	       xf86CrtcPtr	*best_crtcs,
-	       DisplayModePtr	*modes,
-	       int		n,
-	       int		width,
-	       int		height)
-{
-    xf86CrtcConfigPtr	config = XF86_CRTC_CONFIG_PTR(scrn);
-    int		    c, o, l;
-    xf86OutputPtr   output;
-    xf86CrtcPtr	    crtc;
-    xf86CrtcPtr	    *crtcs;
-    xf86CrtcPtr	    best_crtc;
-    int		    best_score;
-    int		    score;
-    int		    my_score;
-    
-    if (n == config->num_output)
-	return 0;
-    output = config->output[n];
-    
-    /*
-     * Compute score with this output disabled
-     */
-    best_crtcs[n] = NULL;
-    best_crtc = NULL;
-    best_score = xf86PickCrtcs (scrn, best_crtcs, modes, n+1, width, height);
-    if (modes[n] == NULL)
-	return best_score;
-    
-    crtcs = xalloc (config->num_output * sizeof (xf86CrtcPtr));
-    if (!crtcs)
-	return best_score;
-
-    my_score = 1;
-    /* Score outputs that are known to be connected higher */
-    if (output->status == XF86OutputStatusConnected)
-	my_score++;
-    /* Score outputs with preferred modes higher */
-    if (xf86OutputHasPreferredMode (output, width, height))
-	my_score++;
-    /*
-     * Select a crtc for this output and
-     * then attempt to configure the remaining
-     * outputs
-     */
-    for (c = 0; c < config->num_crtc; c++)
-    {
-	if ((output->possible_crtcs & (1 << c)) == 0)
-	    continue;
-	
-	crtc = config->crtc[c];
-	/*
-	 * Check to see if some other output is
-	 * using this crtc
-	 */
-	for (o = 0; o < n; o++)
-	    if (best_crtcs[o] == crtc)
-		break;
-	if (o < n)
-	{
-	    /*
-	     * If the two outputs desire the same mode,
-	     * see if they can be cloned
-	     */
-	    if (xf86ModesEqual (modes[o], modes[n]) &&
-		config->output[o]->initial_x == config->output[n]->initial_x &&
-		config->output[o]->initial_y == config->output[n]->initial_y)
-	    {
-		for (l = 0; l < config->num_output; l++)
-		    if (output->possible_clones & (1 << l))
-			break;
-		if (l == config->num_output)
-		    continue;		/* nope, try next CRTC */
-	    }
-	    else
-		continue;		/* different modes, can't clone */
-	}
-	crtcs[n] = crtc;
-	memcpy (crtcs, best_crtcs, n * sizeof (xf86CrtcPtr));
-	score = my_score + xf86PickCrtcs (scrn, crtcs, modes, n+1, width, height);
-	if (score > best_score)
-	{
-	    best_crtc = crtc;
-	    best_score = score;
-	    memcpy (best_crtcs, crtcs, config->num_output * sizeof (xf86CrtcPtr));
-	}
-    }
-    xfree (crtcs);
-    return best_score;
-}
-
-
-/*
- * Compute the virtual size necessary to place all of the available
- * crtcs in the specified configuration and also large enough to
- * resize any crtc to the largest available mode
- */
-
-static void
-xf86DefaultScreenLimits (ScrnInfoPtr scrn, int *widthp, int *heightp)
-{
-    xf86CrtcConfigPtr	config = XF86_CRTC_CONFIG_PTR(scrn);
-    int	    width = 0, height = 0;
-    int	    o;
-    int	    c;
-    int	    s;
-
-    for (c = 0; c < config->num_crtc; c++)
-    {
-	int	    crtc_width = 0, crtc_height = 0;
-	xf86CrtcPtr crtc = config->crtc[c];
-
-	if (crtc->enabled)
-	{
-	    crtc_width = crtc->x + crtc->desiredMode.HDisplay;
-	    crtc_height = crtc->y + crtc->desiredMode.VDisplay;
-	}
-	for (o = 0; o < config->num_output; o++) 
-	{
-	    xf86OutputPtr   output = config->output[o];
-
-	    for (s = 0; s < config->num_crtc; s++)
-		if (output->possible_crtcs & (1 << s))
-		{
-		    DisplayModePtr  mode;
-		    for (mode = output->probed_modes; mode; mode = mode->next)
-		    {
-			if (mode->HDisplay > crtc_width)
-			    crtc_width = mode->HDisplay;
-			if (mode->VDisplay > crtc_height)
-			    crtc_height = mode->VDisplay;
-		    }
-		}
-	}
-	if (crtc_width > width)
-	    width = crtc_width;
-	if (crtc_height > height)
-	    height = crtc_height;
-    }
-    if (config->maxWidth && width > config->maxWidth) width = config->maxWidth;
-    if (config->maxHeight && height > config->maxHeight) height = config->maxHeight;
-    if (config->minWidth && width < config->minWidth) width = config->minWidth;
-    if (config->minHeight && height < config->minHeight) height = config->minHeight;
-    *widthp = width;
-    *heightp = height;
-}
-
-#define POSITION_UNSET	-100000
-
-static Bool
-xf86InitialOutputPositions (ScrnInfoPtr scrn, DisplayModePtr *modes)
-{
-    xf86CrtcConfigPtr	config = XF86_CRTC_CONFIG_PTR(scrn);
-    int			o;
-    int			min_x, min_y;
-    
-    for (o = 0; o < config->num_output; o++)
-    {
-	xf86OutputPtr	output = config->output[o];
-
-	output->initial_x = output->initial_y = POSITION_UNSET;
-    }
-    
-    /*
-     * Loop until all outputs are set
-     */
-    for (;;)
-    {
-	Bool	any_set = FALSE;
-	Bool	keep_going = FALSE;
-
-	for (o = 0; o < config->num_output; o++)	
-	{
-	    static const OutputOpts	relations[] = {
-		OPTION_BELOW, OPTION_RIGHT_OF, OPTION_ABOVE, OPTION_LEFT_OF
-	    };
-	    xf86OutputPtr   output = config->output[o];
-	    xf86OutputPtr   relative;
-	    char	    *relative_name;
-	    char	    *position;
-	    OutputOpts	    relation;
-	    int		    r;
-
-	    if (output->initial_x != POSITION_UNSET)
-		continue;
-	    position = xf86GetOptValString (output->options,
-					    OPTION_POSITION);
-	    /*
-	     * Absolute position wins
-	     */
-	    if (position)
-	    {
-		int		    x, y;
-		if (sscanf (position, "%d %d", &x, &y) == 2)
-		{
-		    output->initial_x = x;
-		    output->initial_y = y;
-		}
-		else
-		{
-		    xf86DrvMsg (scrn->scrnIndex, X_ERROR,
-				"Output %s position not of form \"x y\"\n",
-				output->name);
-		    output->initial_x = output->initial_y = 0;
-		}
-		any_set = TRUE;
-		continue;
-	    }
-	    /*
-	     * Next comes relative positions
-	     */
-	    relation = 0;
-	    relative_name = NULL;
-	    for (r = 0; r < 4; r++)
-	    {
-		relation = relations[r];
-		relative_name = xf86GetOptValString (output->options,
-						     relation);
-		if (relative_name)
-		    break;
-	    }
-	    if (relative_name)
-	    {
-		int or;
-		relative = NULL;
-		for (or = 0; or < config->num_output; or++)
-		{
-		    xf86OutputPtr	out_rel = config->output[or];
-		    XF86ConfMonitorPtr	rel_mon = out_rel->conf_monitor;
-		    char		*name;
-
-		    if (rel_mon)
-			name = rel_mon->mon_identifier;
-		    else
-			name = out_rel->name;
-		    if (!strcmp (relative_name, name))
-		    {
-			relative = config->output[or];
-			break;
-		    }
-		}
-		if (!relative)
-		{
-		    xf86DrvMsg (scrn->scrnIndex, X_ERROR,
-				"Cannot position output %s relative to unknown output %s\n",
-				output->name, relative_name);
-		    output->initial_x = 0;
-		    output->initial_y = 0;
-		    any_set = TRUE;
-		    continue;
-		}
-		if (relative->initial_x == POSITION_UNSET)
-		{
-		    keep_going = TRUE;
-		    continue;
-		}
-		output->initial_x = relative->initial_x;
-		output->initial_y = relative->initial_y;
-		switch (relation) {
-		case OPTION_BELOW:
-		    output->initial_y += modes[or]->VDisplay;
-		    break;
-		case OPTION_RIGHT_OF:
-		    output->initial_x += modes[or]->HDisplay;
-		    break;
-		case OPTION_ABOVE:
-		    output->initial_y -= modes[o]->VDisplay;
-		    break;
-		case OPTION_LEFT_OF:
-		    output->initial_x -= modes[o]->HDisplay;
-		    break;
-		default:
-		    break;
-		}
-		any_set = TRUE;
-		continue;
-	    }
-	    
-	    /* Nothing set, just stick them at 0,0 */
-	    output->initial_x = 0;
-	    output->initial_y = 0;
-	    any_set = TRUE;
-	}
-	if (!keep_going)
-	    break;
-	if (!any_set) 
-	{
-	    for (o = 0; o < config->num_output; o++)
-	    {
-		xf86OutputPtr   output = config->output[o];
-		if (output->initial_x == POSITION_UNSET)
-		{
-		    xf86DrvMsg (scrn->scrnIndex, X_ERROR,
-				"Output position loop. Moving %s to 0,0\n",
-				output->name);
-		    output->initial_x = output->initial_y = 0;
-		    break;
-		}
-	    }
-	}
-    }
-
-    /*
-     * normalize positions
-     */
-    min_x = 1000000;
-    min_y = 1000000;
-    for (o = 0; o < config->num_output; o++)
-    {
-	xf86OutputPtr	output = config->output[o];
-
-	if (output->initial_x < min_x)
-	    min_x = output->initial_x;
-	if (output->initial_y < min_y)
-	    min_y = output->initial_y;
-    }
-    
-    for (o = 0; o < config->num_output; o++)
-    {
-	xf86OutputPtr	output = config->output[o];
-
-	output->initial_x -= min_x;
-	output->initial_y -= min_y;
-    }
-    return TRUE;
-}
-
-/*
- * XXX walk the monitor mode list and prune out duplicates that
- * are inserted by xf86DDCMonitorSet. In an ideal world, that
- * function would do this work by itself.
- */
-
-static void
-xf86PruneDuplicateMonitorModes (MonPtr Monitor)
-{
-    DisplayModePtr  master, clone, next;
-
-    for (master = Monitor->Modes; 
-	 master && master != Monitor->Last; 
-	 master = master->next)
-    {
-	for (clone = master->next; clone && clone != Monitor->Modes; clone = next)
-	{
-	    next = clone->next;
-	    if (xf86ModesEqual (master, clone))
-	    {
-		if (Monitor->Last == clone)
-		    Monitor->Last = clone->prev;
-		xf86DeleteMode (&Monitor->Modes, clone);
-	    }
-	}
-    }
-}
-
-/** Return - 0 + if a should be earlier, same or later than b in list
- */
-static int
-i830xf86ModeCompare (DisplayModePtr a, DisplayModePtr b)
-{
-    int	diff;
-
-    diff = ((b->type & M_T_PREFERRED) != 0) - ((a->type & M_T_PREFERRED) != 0);
-    if (diff)
-	return diff;
-    diff = b->HDisplay * b->VDisplay - a->HDisplay * a->VDisplay;
-    if (diff)
-	return diff;
-    diff = b->Clock - a->Clock;
-    return diff;
-}
-
-/**
- * Insertion sort input in-place and return the resulting head
- */
-static DisplayModePtr
-i830xf86SortModes (DisplayModePtr input)
-{
-    DisplayModePtr  output = NULL, i, o, n, *op, prev;
-
-    /* sort by preferred status and pixel area */
-    while (input)
-    {
-	i = input;
-	input = input->next;
-	for (op = &output; (o = *op); op = &o->next)
-	    if (i830xf86ModeCompare (o, i) > 0)
-		break;
-	i->next = *op;
-	*op = i;
-    }
-    /* prune identical modes */
-    for (o = output; o && (n = o->next); o = n)
-    {
-	if (!strcmp (o->name, n->name) && xf86ModesEqual (o, n))
-	{
-	    o->next = n->next;
-	    xfree (n->name);
-	    xfree (n);
-	    n = o;
-	}
-    }
-    /* hook up backward links */
-    prev = NULL;
-    for (o = output; o; o = o->next)
-    {
-	o->prev = prev;
-	prev = o;
-    }
-    return output;
-}
-
-#define DEBUG_REPROBE 1
-
-void
-xf86ProbeOutputModes (ScrnInfoPtr scrn, int maxX, int maxY)
-{
-    xf86CrtcConfigPtr	config = XF86_CRTC_CONFIG_PTR(scrn);
-    int			o;
-
-    if (maxX == 0 || maxY == 0)
-	xf86RandR12GetOriginalVirtualSize (scrn, &maxX, &maxY);
-
-    /* Elide duplicate modes before defaulting code uses them */
-    xf86PruneDuplicateMonitorModes (scrn->monitor);
-    
-    /* Probe the list of modes for each output. */
-    for (o = 0; o < config->num_output; o++) 
-    {
-	xf86OutputPtr	    output = config->output[o];
-	I830OutputPrivatePtr intel_output = output->driver_private;
-	DisplayModePtr	    mode;
-	DisplayModePtr	    config_modes = NULL, output_modes, default_modes;
-	char		    *preferred_mode;
-	xf86MonPtr	    edid_monitor;
-	XF86ConfMonitorPtr  conf_monitor;
-	MonRec		    mon_rec;
-	int		    min_clock = 0;
-	int		    max_clock = 0;
-	double		    clock;
-	enum { sync_config, sync_edid, sync_default } sync_source = sync_default;
-	while (output->probed_modes != NULL)
-	    xf86DeleteMode(&output->probed_modes, output->probed_modes);
-
-	/*
-	 * Check connection status
-	 */
-	output->status = (*output->funcs->detect)(output);
-
-	if (output->status == XF86OutputStatusDisconnected)
-	    continue;
-
-	memset (&mon_rec, '\0', sizeof (mon_rec));
-	
-	conf_monitor = output->conf_monitor;
-	
-	if (conf_monitor)
-	{
-	    int	i;
-	    
-	    for (i = 0; i < conf_monitor->mon_n_hsync; i++)
-	    {
-		mon_rec.hsync[mon_rec.nHsync].lo = conf_monitor->mon_hsync[i].lo;
-		mon_rec.hsync[mon_rec.nHsync].hi = conf_monitor->mon_hsync[i].hi;
-		mon_rec.nHsync++;
-		sync_source = sync_config;
-	    }
-	    for (i = 0; i < conf_monitor->mon_n_vrefresh; i++)
-	    {
-		mon_rec.vrefresh[mon_rec.nVrefresh].lo = conf_monitor->mon_vrefresh[i].lo;
-		mon_rec.vrefresh[mon_rec.nVrefresh].hi = conf_monitor->mon_vrefresh[i].hi;
-		mon_rec.nVrefresh++;
-		sync_source = sync_config;
-	    }
-	    config_modes = xf86GetMonitorModes (scrn, conf_monitor);
-	}
-	
-	output_modes = (*output->funcs->get_modes) (output);
-	
-	edid_monitor = output->MonInfo;
-	
-	if (edid_monitor)
-	{
-	    int			    i;
-	    Bool		    set_hsync = mon_rec.nHsync == 0;
-	    Bool		    set_vrefresh = mon_rec.nVrefresh == 0;
-
-	    for (i = 0; i < sizeof (edid_monitor->det_mon) / sizeof (edid_monitor->det_mon[0]); i++)
-	    {
-		if (edid_monitor->det_mon[i].type == DS_RANGES)
-		{
-		    struct monitor_ranges   *ranges = &edid_monitor->det_mon[i].section.ranges;
-		    if (set_hsync && ranges->max_h)
-		    {
-			mon_rec.hsync[mon_rec.nHsync].lo = ranges->min_h;
-			mon_rec.hsync[mon_rec.nHsync].hi = ranges->max_h;
-			mon_rec.nHsync++;
-			if (sync_source == sync_default)
-			    sync_source = sync_edid;
-		    }
-		    if (set_vrefresh && ranges->max_v)
-		    {
-			mon_rec.vrefresh[mon_rec.nVrefresh].lo = ranges->min_v;
-			mon_rec.vrefresh[mon_rec.nVrefresh].hi = ranges->max_v;
-			mon_rec.nVrefresh++;
-			if (sync_source == sync_default)
-			    sync_source = sync_edid;
-		    }
-		    if (ranges->max_clock > max_clock)
-			max_clock = ranges->max_clock;
-		}
-	    }
-	}
-
-	if (xf86GetOptValFreq (output->options, OPTION_MIN_CLOCK,
-			       OPTUNITS_KHZ, &clock))
-	    min_clock = (int) clock;
-	if (xf86GetOptValFreq (output->options, OPTION_MAX_CLOCK,
-			       OPTUNITS_KHZ, &clock))
-	    max_clock = (int) clock;
-
-	/*
-	 * These limits will end up setting a 1024x768 at 60Hz mode by default,
-	 * which seems like a fairly good mode to use when nothing else is
-	 * specified
-	 */
-	if (mon_rec.nHsync == 0)
-	{
-	    mon_rec.hsync[0].lo = 31.0;
-	    mon_rec.hsync[0].hi = 55.0;
-	    mon_rec.nHsync = 1;
-	}
-	if (mon_rec.nVrefresh == 0)
-	{
-	    mon_rec.vrefresh[0].lo = 58.0;
-	    mon_rec.vrefresh[0].hi = 62.0;
-	    mon_rec.nVrefresh = 1;
-	}
-	default_modes = xf86GetDefaultModes (output->interlaceAllowed,
-					     output->doubleScanAllowed);
-	
-	if (sync_source == sync_config)
-	{
-	    /* 
-	     * Check output and config modes against sync range from config file
-	     */
-	    xf86ValidateModesSync (scrn, output_modes, &mon_rec);
-	    xf86ValidateModesSync (scrn, config_modes, &mon_rec);
-	}
-	/*
-	 * Check default modes against sync range
-	 */
-        xf86ValidateModesSync (scrn, default_modes, &mon_rec);
-	/*
-	 * Check default modes against monitor max clock
-	 */
-	if (max_clock)
-	    xf86ValidateModesClocks(scrn, default_modes,
-				    &min_clock, &max_clock, 1);
-	
-	output->probed_modes = NULL;
-	output->probed_modes = xf86ModesAdd (output->probed_modes, config_modes);
-	output->probed_modes = xf86ModesAdd (output->probed_modes, output_modes);
-	if (intel_output->type != I830_OUTPUT_TVOUT)	
-		output->probed_modes = xf86ModesAdd (output->probed_modes, default_modes);
-
-	/*
-	 * Check all modes against max size
-	 */
-	if (maxX && maxY)
-	    xf86ValidateModesSize (scrn, output->probed_modes,
-				       maxX, maxY, 0);
-	 
-	/*
-	 * Check all modes against output
-	 */
-	for (mode = output->probed_modes; mode != NULL; mode = mode->next) 
-	    if (mode->status == MODE_OK)
-		mode->status = (*output->funcs->mode_valid)(output, mode);
-	
-	xf86PruneInvalidModes(scrn, &output->probed_modes, TRUE);
-	
-	output->probed_modes = i830xf86SortModes (output->probed_modes);
-	
-	/* Check for a configured preference for a particular mode */
-	preferred_mode = xf86GetOptValString (output->options,
-					      OPTION_PREFERRED_MODE);
-
-	if (preferred_mode)
-	{
-	    for (mode = output->probed_modes; mode; mode = mode->next)
-	    {
-		if (!strcmp (preferred_mode, mode->name))
-		{
-		    if (mode != output->probed_modes)
-		    {
-			if (mode->prev)
-			    mode->prev->next = mode->next;
-			if (mode->next)
-			    mode->next->prev = mode->prev;
-			mode->next = output->probed_modes;
-			output->probed_modes->prev = mode;
-			mode->prev = NULL;
-			output->probed_modes = mode;
-		    }
-		    mode->type |= M_T_PREFERRED;
-		    break;
-		}
-	    }
-	}
-	
-#ifdef DEBUG_REPROBE
-	if (output->probed_modes != NULL) {
-	    xf86DrvMsg(scrn->scrnIndex, X_INFO,
-		       "Printing probed modes for output %s\n",
-		       output->name);
-	} else {
-	    xf86DrvMsg(scrn->scrnIndex, X_INFO,
-		       "No remaining probed modes for output %s\n",
-		       output->name);
-	}
-#endif
-	for (mode = output->probed_modes; mode != NULL; mode = mode->next)
-	{
-	    /* The code to choose the best mode per pipe later on will require
-	     * VRefresh to be set.
-	     */
-	    mode->VRefresh = xf86ModeVRefresh(mode);
-	    xf86SetModeCrtc(mode, INTERLACE_HALVE_V);
-
-#ifdef DEBUG_REPROBE
-	    xf86PrintModeline(scrn->scrnIndex, mode);
-#endif
-	}
-    }
-}
-
-
-/**
- * Copy one of the output mode lists to the ScrnInfo record
- */
-
-/* XXX where does this function belong? Here? */
-void
-xf86RandR12GetOriginalVirtualSize(ScrnInfoPtr scrn, int *x, int *y);
-
-void
-xf86SetScrnInfoModes (ScrnInfoPtr scrn)
-{
-    xf86CrtcConfigPtr	config = XF86_CRTC_CONFIG_PTR(scrn);
-    xf86OutputPtr	output;
-    xf86CrtcPtr		crtc;
-    DisplayModePtr	last, mode;
-
-    output = config->output[config->compat_output];
-    if (!output->crtc)
-    {
-	int o;
-
-	output = NULL;
-	for (o = 0; o < config->num_output; o++)
-	    if (config->output[o]->crtc)
-	    {
-		config->compat_output = o;
-		output = config->output[o];
-		break;
-	    }
-	/* no outputs are active, punt and leave things as they are */
-	if (!output)
-	    return;
-    }
-    crtc = output->crtc;
-
-    /* Clear any existing modes from scrn->modes */
-    while (scrn->modes != NULL)
-	xf86DeleteMode(&scrn->modes, scrn->modes);
-
-    /* Set scrn->modes to the mode list for the 'compat' output */
-    scrn->modes = xf86DuplicateModes(scrn, output->probed_modes);
-
-    for (mode = scrn->modes; mode; mode = mode->next)
-	if (xf86ModesEqual (mode, &crtc->desiredMode))
-	    break;
-
-    if (scrn->modes != NULL) {
-	/* For some reason, scrn->modes is circular, unlike the other mode
-	 * lists.  How great is that?
-	 */
-	for (last = scrn->modes; last && last->next; last = last->next)
-	    ;
-	last->next = scrn->modes;
-	scrn->modes->prev = last;
-	if (mode) {
-	    while (scrn->modes != mode)
-		scrn->modes = scrn->modes->next;
-	}
-    }
-    scrn->currentMode = scrn->modes;
-}
-
-/**
- * Construct default screen configuration
- *
- * Given auto-detected (and, eventually, configured) values,
- * construct a usable configuration for the system
- */
-
-Bool
-xf86InitialConfiguration (ScrnInfoPtr	    scrn)
-{
-    xf86CrtcConfigPtr	config = XF86_CRTC_CONFIG_PTR(scrn);
-    int			o, c;
-    DisplayModePtr	target_mode = NULL;
-    xf86CrtcPtr		*crtcs;
-    DisplayModePtr	*modes;
-    Bool		*enabled;
-    int			width;
-    int			height;
-
-    if (scrn->display->virtualX)
-	width = scrn->display->virtualX;
-    else
-	width = config->maxWidth;
-    if (scrn->display->virtualY)
-	height = scrn->display->virtualY;
-    else
-	height = config->maxHeight;
-
-    xf86ProbeOutputModes (scrn, width, height);
-
-    crtcs = xnfcalloc (config->num_output, sizeof (xf86CrtcPtr));
-    modes = xnfcalloc (config->num_output, sizeof (DisplayModePtr));
-    enabled = xnfcalloc (config->num_output, sizeof (Bool));
-    
-    for (o = 0; o < config->num_output; o++)
-    {
-	xf86OutputPtr output = config->output[o];
-	
-	modes[o] = NULL;
-	enabled[o] = (xf86OutputEnabled (output) &&
-		      output->status != XF86OutputStatusDisconnected);
-    }
-    
-    /*
-     * Let outputs with preferred modes drive screen size
-     */
-    for (o = 0; o < config->num_output; o++)
-    {
-	xf86OutputPtr output = config->output[o];
-
-	if (enabled[o] &&
-	    xf86OutputHasPreferredMode (output, width, height))
-	{
-	    target_mode = xf86DefaultMode (output, width, height);
-	    if (target_mode)
-	    {
-		modes[o] = target_mode;
-		config->compat_output = o;
-		break;
-	    }
-	}
-    }
-    if (!target_mode)
-    {
-	for (o = 0; o < config->num_output; o++)
-	{
-	    xf86OutputPtr output = config->output[o];
-	    if (enabled[o])
-	    {
-		target_mode = xf86DefaultMode (output, width, height);
-		if (target_mode)
-		{
-		    modes[o] = target_mode;
-		    config->compat_output = o;
-		    break;
-		}
-	    }
-	}
-    }
-    for (o = 0; o < config->num_output; o++)
-    {
-	xf86OutputPtr output = config->output[o];
-	
-	if (enabled[o] && !modes[o])
-	    modes[o] = xf86ClosestMode (output, target_mode, width, height);
-    }
-
-    /*
-     * Set the position of each output
-     */
-    if (!xf86InitialOutputPositions (scrn, modes))
-    {
-	xfree (crtcs);
-	xfree (modes);
-	return FALSE;
-    }
-	
-    /*
-     * Assign CRTCs to fit output configuration
-     */
-    if (!xf86PickCrtcs (scrn, crtcs, modes, 0, width, height))
-    {
-	xfree (crtcs);
-	xfree (modes);
-	return FALSE;
-    }
-    
-    /* XXX override xf86 common frame computation code */
-    
-    scrn->display->frameX0 = 0;
-    scrn->display->frameY0 = 0;
-    
-    for (c = 0; c < config->num_crtc; c++)
-    {
-	xf86CrtcPtr	crtc = config->crtc[c];
-
-	crtc->enabled = FALSE;
-	memset (&crtc->desiredMode, '\0', sizeof (crtc->desiredMode));
-    }
-    
-    /*
-     * Set initial configuration
-     */
-    for (o = 0; o < config->num_output; o++)
-    {
-	xf86OutputPtr	output = config->output[o];
-	DisplayModePtr	mode = modes[o];
-        xf86CrtcPtr	crtc = crtcs[o];
-
-	if (mode && crtc)
-	{
-	    crtc->desiredMode = *mode;
-	    crtc->enabled = TRUE;
-	    crtc->x = output->initial_x;
-	    crtc->y = output->initial_y;
-	    output->crtc = crtc;
-	}
-    }
-    
-    if (scrn->display->virtualX == 0)
-    {
-	/*
-	 * Expand virtual size to cover potential mode switches
-	 */
-	xf86DefaultScreenLimits (scrn, &width, &height);
-    
-	scrn->display->virtualX = width;
-	scrn->display->virtualY = height;
-    }
-
-    if (width > scrn->virtualX)
-	scrn->virtualX = width;
-    if (height > scrn->virtualY)
-	scrn->virtualY = height;
-    
-    /* Mirror output modes to scrn mode list */
-    xf86SetScrnInfoModes (scrn);
-    
-    xfree (crtcs);
-    xfree (modes);
-    return TRUE;
-}
-
-/**
- * Set the DPMS power mode of all outputs and CRTCs.
- *
- * If the new mode is off, it will turn off outputs and then CRTCs.
- * Otherwise, it will affect CRTCs before outputs.
- */
-void
-xf86DPMSSet(ScrnInfoPtr scrn, int mode, int flags)
-{
-    xf86CrtcConfigPtr	config = XF86_CRTC_CONFIG_PTR(scrn);
-    int			i;
-
-    if (!scrn->vtSema)
-	return;
-
-    if (mode == DPMSModeOff) {
-	for (i = 0; i < config->num_output; i++) {
-	    xf86OutputPtr output = config->output[i];
-	    if (output->crtc != NULL)
-		(*output->funcs->dpms) (output, mode);
-	}
-    }
-
-    for (i = 0; i < config->num_crtc; i++) {
-	xf86CrtcPtr crtc = config->crtc[i];
-	if (crtc->enabled)
-	    (*crtc->funcs->dpms) (crtc, mode);
-    }
-
-    if (mode != DPMSModeOff) {
-	for (i = 0; i < config->num_output; i++) {
-	    xf86OutputPtr output = config->output[i];
-	    if (output->crtc != NULL)
-		(*output->funcs->dpms) (output, mode);
-	}
-    }
-}
-
-/**
- * Implement the screensaver by just calling down into the driver DPMS hooks.
- *
- * Even for monitors with no DPMS support, by the definition of our DPMS hooks,
- * the outputs will still get disabled (blanked).
- */
-Bool
-xf86SaveScreen(ScreenPtr pScreen, int mode)
-{
-    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
-
-    if (xf86IsUnblank(mode))
-	xf86DPMSSet(pScrn, DPMSModeOn, 0);
-    else
-	xf86DPMSSet(pScrn, DPMSModeOff, 0);
-
-    return TRUE;
-}
-
-/**
- * Disable all inactive crtcs and outputs
- */
-void
-xf86DisableUnusedFunctions(ScrnInfoPtr pScrn)
-{
-    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
-    int			o, c;
-
-    for (o = 0; o < xf86_config->num_output; o++) 
-    {
-	xf86OutputPtr  output = xf86_config->output[o];
-	if (!output->crtc) 
-	    (*output->funcs->dpms)(output, DPMSModeOff);
-    }
-
-    for (c = 0; c < xf86_config->num_crtc; c++) 
-    {
-	xf86CrtcPtr crtc = xf86_config->crtc[c];
-
-	if (!crtc->enabled) 
-	{
-	    crtc->funcs->dpms(crtc, DPMSModeOff);
-	    memset(&crtc->mode, 0, sizeof(crtc->mode));
-	}
-    }
-}
-
-#ifdef RANDR_12_INTERFACE
-
-#define EDID_ATOM_NAME		"EDID_DATA"
-
-/**
- * Set the RandR EDID property
- */
-static void
-xf86OutputSetEDIDProperty (xf86OutputPtr output, void *data, int data_len)
-{
-    Atom edid_atom = MakeAtom(EDID_ATOM_NAME, sizeof(EDID_ATOM_NAME), TRUE);
-
-    /* This may get called before the RandR resources have been created */
-    if (output->randr_output == NULL)
-	return;
-
-    if (data_len != 0) {
-	RRChangeOutputProperty(output->randr_output, edid_atom, XA_INTEGER, 8,
-			       PropModeReplace, data_len, data, FALSE);
-    } else {
-	RRDeleteOutputProperty(output->randr_output, edid_atom);
-    }
-}
-
-#endif
-
-/**
- * Set the EDID information for the specified output
- */
-void
-xf86OutputSetEDID (xf86OutputPtr output, xf86MonPtr edid_mon)
-{
-    ScrnInfoPtr		scrn = output->scrn;
-    xf86CrtcConfigPtr	config = XF86_CRTC_CONFIG_PTR(scrn);
-    int			i;
-#ifdef RANDR_12_INTERFACE
-    int			size;
-#endif
-    
-    if (output->MonInfo != NULL)
-	xfree(output->MonInfo);
-    
-    output->MonInfo = edid_mon;
-
-    /* Debug info for now, at least */
-    xf86DrvMsg(scrn->scrnIndex, X_INFO, "EDID for output %s\n", output->name);
-    xf86PrintEDID(edid_mon);
-    
-    /* Set the DDC properties for the 'compat' output */
-    if (output == config->output[config->compat_output])
-        xf86SetDDCproperties(scrn, edid_mon);
-
-#ifdef RANDR_12_INTERFACE
-    /* Set the RandR output properties */
-    size = 0;
-    if (edid_mon)
-    {
-	if (edid_mon->ver.version == 1)
-	    size = 128;
-	else if (edid_mon->ver.version == 2)
-	    size = 256;
-    }
-    xf86OutputSetEDIDProperty (output, edid_mon ? edid_mon->rawData : NULL, size);
-#endif
-
-    if (edid_mon)
-    {
-	/* Pull out a phyiscal size from a detailed timing if available. */
-	for (i = 0; i < 4; i++) {
-	    if (edid_mon->det_mon[i].type == DT &&
-		edid_mon->det_mon[i].section.d_timings.h_size != 0 &&
-		edid_mon->det_mon[i].section.d_timings.v_size != 0)
-	    {
-		output->mm_width = edid_mon->det_mon[i].section.d_timings.h_size;
-		output->mm_height = edid_mon->det_mon[i].section.d_timings.v_size;
-		break;
-	    }
-	}
-    
-	/* if no mm size is available from a detailed timing, check the max size field */
-	if ((!output->mm_width || !output->mm_height) &&
-	    (edid_mon->features.hsize && edid_mon->features.vsize))
-	{
-	    output->mm_width = edid_mon->features.hsize * 10;
-	    output->mm_height = edid_mon->features.vsize * 10;
-	}
-    }
-}
-
-/**
- * Return the list of modes supported by the EDID information
- * stored in 'output'
- */
-DisplayModePtr
-xf86OutputGetEDIDModes (xf86OutputPtr output)
-{
-    ScrnInfoPtr	scrn = output->scrn;
-    xf86MonPtr	edid_mon = output->MonInfo;
-
-    if (!edid_mon)
-	return NULL;
-    return xf86DDCGetModes(scrn->scrnIndex, edid_mon);
-}
-
-xf86MonPtr
-xf86OutputGetEDID (xf86OutputPtr output, I2CBusPtr pDDCBus)
-{
-    ScrnInfoPtr	scrn = output->scrn;
-
-    return xf86DoEDID_DDC2 (scrn->scrnIndex, pDDCBus);
-}
diff-tree 9417af8630fce0476273b693ebac12129415e0cf (from 00dadaa115951c36de9caf2a9d78909811ef34bc)
Author: Zou Nan hai <nanhai.zou at intel.com>
Date:   Mon Feb 26 08:02:50 2007 +0800

      fix conflict with external branch

diff --git a/src/i830_tv.c b/src/i830_tv.c
index 5ee8866..95612e4 100644
--- a/src/i830_tv.c
+++ b/src/i830_tv.c
@@ -1310,7 +1310,7 @@ i830_tv_detect(xf86OutputPtr output)
     }
 }
 
-struct input_res {
+static struct input_res {
     char *name;
     int w, h;	
 } input_res_table[] = 
diff-tree 42fc06c85a0c487cfa26b9d4aa396402dbc4c2fe (from parents)
Merge: 10655c4674cdac8a231c50dd9afc5d43fe43b4bd 3bce8bf0e95e5842399959a5d6f6413e96f03adb
Author: Nian Wu <nian at graphics.(none)>
Date:   Sun Feb 25 12:53:47 2007 -0800

    Merge branch 'modesetting' of git://proxy01.pd.intel.com:9419/git/xorg/driver/xf86-video-intel into crestline

diff-tree 00dadaa115951c36de9caf2a9d78909811ef34bc (from 920aeaf8478f706ab3b1de4f20f5d351e64a0197)
Author: Zou Nan hai <nanhai.zou at intel.com>
Date:   Fri Feb 9 11:14:50 2007 +0800

      set DPLL before detect

diff --git a/src/i830_tv.c b/src/i830_tv.c
index 9e62c46..5ee8866 100644
--- a/src/i830_tv.c
+++ b/src/i830_tv.c
@@ -1294,6 +1294,7 @@ i830_tv_detect(xf86OutputPtr output)
             /* we only need the pixel clock set correctly here */
             mode = reported_modes[0];
             xf86SetModeCrtc (&mode, INTERLACE_HALVE_V);
+	    crtc->funcs->mode_set(crtc, &mode, &mode, 0, 0);
         }
         i830_tv_detect_type (crtc, output);
         i830ReleaseLoadDetectPipe (output);
diff-tree 920aeaf8478f706ab3b1de4f20f5d351e64a0197 (from 6d9757e466863594300c83f3806fd4376bea0504)
Author: Zou Nan hai <nanhai.zou at intel.com>
Date:   Wed Feb 7 13:15:52 2007 +0800

      Make TV code same with external tree.
      Fallback to old filter table.
      4 spaces indent reformat.
      Auto scaling seem to not work well on some low res interlace mode when input width > 1024, filter those modes.
      Fix some subcarriar number

diff --git a/src/i830_tv.c b/src/i830_tv.c
index 6131b28..9e62c46 100644
--- a/src/i830_tv.c
+++ b/src/i830_tv.c
@@ -93,7 +93,7 @@ typedef struct {
     float   rv, gv, bv, av;
 } color_conversion_t;
 
-static const CARD32 filter_table_hres[] = {
+static const CARD32 filter_table[] = {
     0xB1403000, 0x2E203500, 0x35002E20, 0x3000B140,
     0x35A0B160, 0x2DC02E80, 0xB1403480, 0xB1603000,
     0x2EA03640, 0x34002D80, 0x3000B120, 0x36E0B160,
@@ -148,51 +148,6 @@ static const CARD32 filter_table_hres[] 
     0x28003100, 0x28002F00, 0x00003100,
 };
 
-static const CARD32 filter_table_ntsc[] = {
-	0xB0603000, 0x1920B3E0, 0xB3E01900, 0x3000B060, 0xB380B080,
-	0x18A01980, 0xB040B440, 0xB0A03000, 0x19D0B300, 0xB4801840,
-	0x3000B020, 0xB260B0E0, 0x2FE01A10, 0x3000B4C0, 0xB1003000,
-	0x1A60B1C0, 0xB4E02F00, 0x30003020, 0xB120B140, 0x2E401AB0,
-	0x3020B500, 0xB1803000, 0x1B00B060, 0xB5202D60, 0x30003040,
-	0x3080B1A0, 0x2CA01B30, 0x3040B520, 0xB1E03020, 0x1B703160,
-	0xB5202BC0, 0x30203040, 0x3260B220, 0x2B001B98, 0x3060B520,
-	0xB2603020, 0x1BD03360, 0xB5002A20, 0x30203060, 0x3480B2A0,
-	0x29601BF0, 0x3060B4E0, 0xB2E03020, 0x1C1835C0, 0xB4C02880,
-	0x30403060, 0x3700B340, 0x3F801C30, 0x3060B4A0, 0xB3803040,
-	0x1C403840, 0xB4603E00, 0x30403060, 0x39A0B3C0, 0x3C801C50,
-	0x3040B420, 0xB4003040, 0x1C603B00, 0xB4003B00, 0x00003040,
-	0x38A03000, 0x3C803AE0, 0x3AE03C80, 0x300038A0, 0x3B0038E0,
-	0x3C803C80, 0x38403AE0, 0x39203000, 0x3C803B00, 0x3AE03C80,
-	0x30203800, 0x3B003960, 0x3C803C80, 0x37A03AE0, 0x39803040,
-	0x3C603B20, 0x3AE03C80, 0x30403760, 0x3B2039C0, 0x3C803C80,
-	0x37003AE0, 0x39E03080, 0x3C603B40, 0x3AE03C80, 0x30A036A0,
-	0x3B603A20, 0x3C803C40, 0x36403AE0, 0x3A4030C0, 0x3C403B60,
-	0x3AE03C80, 0x31003600, 0x3B803A60, 0x3C603C40, 0x35A03AE0,
-	0x3A803140, 0x3C403B80, 0x3AE03C60, 0x31803540, 0x3BA03A80,
-	0x3C603C40, 0x34E03AE0, 0x3AA031C0, 0x3C403BC0, 0x3AE03C40,
-	0x32003480, 0x3BC03AC0, 0x3C403C40, 0x34203AE0, 0x3AC03260,
-	0x3C403BE0, 0x3AE03C20, 0x32A033C0, 0x3C003AC0, 0x3C203C40,
-	0x33603AE0, 0x3AE03300, 0x3C403C00, 0x3AE03C00, 0x00003300,
-	0x38C030C0, 0x2B802B60, 0x30C038C0, 0x2BA03940, 0x38402B40,
-	0x39C030C0, 0x2B402BA0, 0x30C037C0, 0x2BC03A40, 0x37802B00,
-	0x3AC03100, 0x2AC02BE0, 0x31003700, 0x2BE03B40, 0x36802AC0,
-	0x3BC03100, 0x2A802C20, 0x31403600, 0x2C203C40, 0x35C02A40,
-	0x3CC03140, 0x2A402C20, 0x31803540, 0x2C203D40, 0x35002A00,
-	0x3DC03180, 0x29C02C60, 0x31C03480, 0x2C603E40, 0x34402980,
-	0x3F003200, 0x29402C40, 0x32003400, 0x2C803F80, 0x33802900,
-	0x3FC03240, 0x29002C60, 0x32803340, 0x2C402840, 0x330028C0,
-	0x288032C0, 0x28802C40, 0x000032C0, 0x38C030C0, 0x2B802B60,
-	0x30C038C0, 0x2BA03940, 0x38402B40, 0x39C030C0, 0x2B402BA0,
-	0x30C037C0, 0x2BC03A40, 0x37802B00, 0x3AC03100, 0x2AC02BE0,
-	0x31003700, 0x2BE03B40, 0x36802AC0, 0x3BC03100, 0x2A802C20,
-	0x31403600, 0x2C203C40, 0x35C02A40, 0x3CC03140, 0x2A402C20,
-	0x31803540, 0x2C203D40, 0x35002A00, 0x3DC03180, 0x29C02C60,
-	0x31C03480, 0x2C603E40, 0x34402980, 0x3F003200, 0x29402C40,
-	0x32003400, 0x2C803F80, 0x33802900, 0x3FC03240, 0x29002C60,
-	0x32803340, 0x2C402840, 0x330028C0, 0x288032C0, 0x28802C40,
-	0x000032C0,
-};
-
 typedef struct {
     char *name;
     int	clock;
@@ -266,18 +221,18 @@ const static tv_mode_t tv_modes[] = {
 
 	.hsync_end	= 64,		    .hblank_end		= 124,
 	.hblank_start	= 836,		    .htotal		= 857,
-	
+
 	.progressive	= FALSE,	    .trilevel_sync = FALSE,
 
 	.vsync_start_f1	= 6,		    .vsync_start_f2	= 7,
 	.vsync_len	= 6,
-	
+
 	.veq_ena	= TRUE,		    .veq_start_f1    	= 0,
 	.veq_start_f2	= 1,		    .veq_len		= 18,
-	
+
 	.vi_end_f1	= 20,		    .vi_end_f2		= 21,
 	.nbr_end	= 240,
-	
+
 	.burst_ena	= TRUE,
 	.hburst_start	= 72,		    .hburst_len		= 34,
 	.vburst_start_f1 = 9,		    .vburst_end_f1	= 240,
@@ -305,548 +260,472 @@ const static tv_mode_t tv_modes[] = {
 	    .ru =-0.0885, .gu =-0.1738, .bu = 0.2624, .au = 1.0000,
 	    .rv = 0.3693, .gv =-0.3092, .bv =-0.0601, .av = 1.0000,
 	},
-	.filter_table = filter_table_ntsc,
+	.filter_table = filter_table,
     },
     {
-         .name		= "NTSC-443",
-	 .clock		= 107520,	
-	 .oversample	= TV_OVERSAMPLE_8X,
-	 .component_only = 0,
-	 /* 525 Lines, 60 Fields, 15.734KHz line, Sub-Carrier 4.43MHz */
-	 .hsync_end	= 64,		    .hblank_end		= 124,
-	 .hblank_start	= 836,		    .htotal		= 857,
-
-	 .progressive	= FALSE,	    .trilevel_sync = FALSE,
-
-	 .vsync_start_f1 = 6,		    .vsync_start_f2	= 7,
-	 .vsync_len	= 6,
-
-	 .veq_ena	= TRUE,		    .veq_start_f1    	= 0,
-	 .veq_start_f2	= 1,		    .veq_len		= 18,
-
-	 .vi_end_f1	= 20,		    .vi_end_f2		= 21,
-	 .nbr_end	= 240,
-
-	 .burst_ena	= TRUE,
-	 .hburst_start	= 72,		    .hburst_len		= 34,
-	 .vburst_start_f1 = 9,		    .vburst_end_f1	= 240,
-	 .vburst_start_f2 = 10,		    .vburst_end_f2	= 240,
-	 .vburst_start_f3 = 9,		    .vburst_end_f3	= 240, 
-	 .vburst_start_f4 = 10,		    .vburst_end_f4	= 240,
-
-	 /* desired 4.4336180 actual 4.4336180 clock 107.52 */
-	 .dda1_inc	=   168,
-	 .dda2_inc	=   4093,	    .dda2_size		=  27456,
-	 .dda3_inc	=   525,	    .dda3_size		=  310,
-	 .sc_reset	= TV_SC_RESET_NEVER,
-	 .pal_burst	= FALSE,
-
-	 .composite_levels = { .blank = 225, .black = 267, .burst = 113 },
-	 .composite_color = {
-		 .ry = 0.2990, .gy = 0.5870, .by = 0.1140, .ay = 0.5082,
-		 .ru =-0.0749, .gu =-0.1471, .bu = 0.2220, .au = 1.0000,
-		 .rv = 0.3125, .gv =-0.2616, .bv =-0.0508, .av = 1.0000,
-	 },
-
-	 .svideo_levels    = { .blank = 266, .black = 316, .burst = 133 },
-	 .svideo_color = {
-		 .ry = 0.2990, .gy = 0.5870, .by = 0.1140, .ay = 0.6006,
-		 .ru =-0.0885, .gu =-0.1738, .bu = 0.2624, .au = 1.0000,
-		 .rv = 0.3693, .gv =-0.3092, .bv =-0.0601, .av = 1.0000,
-	 },
-	.filter_table = filter_table_ntsc,
+	.name		= "NTSC-443",
+	.clock		= 107520,	
+	.oversample	= TV_OVERSAMPLE_8X,
+	.component_only = 0,
+	/* 525 Lines, 60 Fields, 15.734KHz line, Sub-Carrier 4.43MHz */
+	.hsync_end	= 64,		    .hblank_end		= 124,
+	.hblank_start	= 836,		    .htotal		= 857,
+
+	.progressive	= FALSE,	    .trilevel_sync = FALSE,
+
+	.vsync_start_f1 = 6,		    .vsync_start_f2	= 7,
+	.vsync_len	= 6,
+
+	.veq_ena	= TRUE,		    .veq_start_f1    	= 0,
+	.veq_start_f2	= 1,		    .veq_len		= 18,
+
+	.vi_end_f1	= 20,		    .vi_end_f2		= 21,
+	.nbr_end	= 240,
+
+	.burst_ena	= 8,
+	.hburst_start	= 72,		    .hburst_len		= 34,
+	.vburst_start_f1 = 9,		    .vburst_end_f1	= 240,
+	.vburst_start_f2 = 10,		    .vburst_end_f2	= 240,
+	.vburst_start_f3 = 9,		    .vburst_end_f3	= 240, 
+	.vburst_start_f4 = 10,		    .vburst_end_f4	= 240,
+
+	/* desired 4.4336180 actual 4.4336180 clock 107.52 */
+	.dda1_inc       =    168,
+	.dda2_inc       =  18557,       .dda2_size      =  20625,
+	.dda3_inc       =      0,       .dda3_size      =      0,
+	.sc_reset   = TV_SC_RESET_EVERY_8,
+	.pal_burst  = TRUE,
+
+	.composite_levels = { .blank = 225, .black = 267, .burst = 113 },
+	.composite_color = {
+	    .ry = 0.2990, .gy = 0.5870, .by = 0.1140, .ay = 0.5082,
+	    .ru =-0.0749, .gu =-0.1471, .bu = 0.2220, .au = 1.0000,
+	    .rv = 0.3125, .gv =-0.2616, .bv =-0.0508, .av = 1.0000,
+	},
+
+	.svideo_levels    = { .blank = 266, .black = 316, .burst = 133 },
+	.svideo_color = {
+	    .ry = 0.2990, .gy = 0.5870, .by = 0.1140, .ay = 0.6006,
+	    .ru =-0.0885, .gu =-0.1738, .bu = 0.2624, .au = 1.0000,
+	    .rv = 0.3693, .gv =-0.3092, .bv =-0.0601, .av = 1.0000,
+	},
+	.filter_table = filter_table,
     },
     {
-	    .name		= "NTSC-J",
-	    .clock		= 107520,	
-	    .oversample	= TV_OVERSAMPLE_8X,
-	    .component_only = 0,
-
-	    /* 525 Lines, 60 Fields, 15.734KHz line, Sub-Carrier 3.580MHz */
-	    .hsync_end	= 64,		    .hblank_end		= 124,
-	    .hblank_start = 836,	    .htotal		= 857,
-
-	    .progressive	= FALSE,    .trilevel_sync = FALSE,
-
-	    .vsync_start_f1	= 6,	    .vsync_start_f2	= 7,
-	    .vsync_len	= 6,
-
-	    .veq_ena	= TRUE,		    .veq_start_f1    	= 0,
-	    .veq_start_f2 = 1,	    .veq_len		= 18,
-
-	    .vi_end_f1	= 20,		    .vi_end_f2		= 21,
-	    .nbr_end	= 240,
-
-	    .burst_ena	= TRUE,
-	    .hburst_start	= 72,		    .hburst_len		= 34,
-	    .vburst_start_f1 = 9,		    .vburst_end_f1	= 240,
-	    .vburst_start_f2 = 10,		    .vburst_end_f2	= 240,
-	    .vburst_start_f3 = 9,		    .vburst_end_f3	= 240, 
-	    .vburst_start_f4 = 10,		    .vburst_end_f4	= 240,
-
-	    /* desired 3.5800000 actual 3.5800000 clock 107.52 */
-	    .dda1_inc	=    136,
-	    .dda2_inc	=   7624,	    .dda2_size		=  20013,
-	    .dda3_inc	=      0,	    .dda3_size		=      0,
-	    .sc_reset	= TV_SC_RESET_EVERY_4,
-	    .pal_burst	= FALSE,
-
-	    .composite_levels = { .blank = 225, .black = 225, .burst = 113 },
-	    .composite_color = {
-		    .ry = 0.2990, .gy = 0.5870, .by = 0.1140, .ay = 0.5495,
-		    .ru =-0.0810, .gu =-0.1590, .bu = 0.2400, .au = 1.0000,
-		    .rv = 0.3378, .gv =-0.2829, .bv =-0.0549, .av = 1.0000,
-	    },
-
-	    .svideo_levels    = { .blank = 266, .black = 266, .burst = 133 },
-	    .svideo_color = {
-		    .ry = 0.2990, .gy = 0.5870, .by = 0.1140, .ay = 0.6494,
-		    .ru =-0.0957, .gu =-0.1879, .bu = 0.2836, .au = 1.0000,
-		    .rv = 0.3992, .gv =-0.3343, .bv =-0.0649, .av = 1.0000,
-	    },
-	    .filter_table = filter_table_ntsc,
+	.name		= "NTSC-J",
+	.clock		= 107520,	
+	.oversample	= TV_OVERSAMPLE_8X,
+	.component_only = 0,
+
+	/* 525 Lines, 60 Fields, 15.734KHz line, Sub-Carrier 3.580MHz */
+	.hsync_end	= 64,		    .hblank_end		= 124,
+	.hblank_start = 836,	    .htotal		= 857,
+
+	.progressive	= FALSE,    .trilevel_sync = FALSE,
+
+	.vsync_start_f1	= 6,	    .vsync_start_f2	= 7,
+	.vsync_len	= 6,
+
+	.veq_ena	= TRUE,		    .veq_start_f1    	= 0,
+	.veq_start_f2 = 1,	    .veq_len		= 18,
+
+	.vi_end_f1	= 20,		    .vi_end_f2		= 21,
+	.nbr_end	= 240,
+
+	.burst_ena	= TRUE,
+	.hburst_start	= 72,		    .hburst_len		= 34,
+	.vburst_start_f1 = 9,		    .vburst_end_f1	= 240,
+	.vburst_start_f2 = 10,		    .vburst_end_f2	= 240,
+	.vburst_start_f3 = 9,		    .vburst_end_f3	= 240, 
+	.vburst_start_f4 = 10,		    .vburst_end_f4	= 240,
+
+	/* desired 3.5800000 actual 3.5800000 clock 107.52 */
+	.dda1_inc	=    136,
+	.dda2_inc	=   7624,	    .dda2_size		=  20013,
+	.dda3_inc	=      0,	    .dda3_size		=      0,
+	.sc_reset	= TV_SC_RESET_EVERY_4,
+	.pal_burst	= FALSE,
+
+	.composite_levels = { .blank = 225, .black = 225, .burst = 113 },
+	.composite_color = {
+	    .ry = 0.2990, .gy = 0.5870, .by = 0.1140, .ay = 0.5495,
+	    .ru =-0.0810, .gu =-0.1590, .bu = 0.2400, .au = 1.0000,
+	    .rv = 0.3378, .gv =-0.2829, .bv =-0.0549, .av = 1.0000,
+	},
+
+	.svideo_levels    = { .blank = 266, .black = 266, .burst = 133 },
+	.svideo_color = {
+	    .ry = 0.2990, .gy = 0.5870, .by = 0.1140, .ay = 0.6494,
+	    .ru =-0.0957, .gu =-0.1879, .bu = 0.2836, .au = 1.0000,
+	    .rv = 0.3992, .gv =-0.3343, .bv =-0.0649, .av = 1.0000,
+	},
+	.filter_table = filter_table,
     },
     {
-	    .name		= "PAL-M",
-	    .clock		= 107520,	
-	    .oversample	= TV_OVERSAMPLE_8X,
-	    .component_only = 0,
-
-	    /* 525 Lines, 60 Fields, 15.734KHz line, Sub-Carrier 3.580MHz */
-	    .hsync_end	= 64,		  .hblank_end		= 124,
-	    .hblank_start = 836,	  .htotal		= 857,
-
-	    .progressive	= FALSE,	    .trilevel_sync = FALSE,
-
-	    .vsync_start_f1	= 6,		    .vsync_start_f2	= 7,
-	    .vsync_len	= 6,
-
-	    .veq_ena	= TRUE,		    .veq_start_f1    	= 0,
-	    .veq_start_f2	= 1,		    .veq_len		= 18,
-
-	    .vi_end_f1	= 20,		    .vi_end_f2		= 21,
-	    .nbr_end	= 240,
-
-	    .burst_ena	= TRUE,
-	    .hburst_start	= 72,		    .hburst_len		= 34,
-	    .vburst_start_f1 = 9,		    .vburst_end_f1	= 240,
-	    .vburst_start_f2 = 10,		    .vburst_end_f2	= 240,
-	    .vburst_start_f3 = 9,		    .vburst_end_f3	= 240, 
-	    .vburst_start_f4 = 10,		    .vburst_end_f4	= 240,
-
-	    /* desired 3.5800000 actual 3.5800000 clock 107.52 */
-	    .dda1_inc	=    135,
-	    .dda2_inc	=    16704,	    .dda2_size		=  27456,
-	    .dda3_inc	=      0,	    .dda3_size		=      0,
-	    .sc_reset	= TV_SC_RESET_EVERY_8,
-	    .pal_burst  = TRUE,
-
-	    .composite_levels = { .blank = 225, .black = 267, .burst = 113 },
-	    .composite_color = {
-		    .ry = 0.2990, .gy = 0.5870, .by = 0.1140, .ay = 0.5082,
-		    .ru =-0.0749, .gu =-0.1471, .bu = 0.2220, .au = 1.0000,
-		    .rv = 0.3125, .gv =-0.2616, .bv =-0.0508, .av = 1.0000,
-	    },
-
-	    .svideo_levels    = { .blank = 266, .black = 316, .burst = 133 },
-	    .svideo_color = {
-		    .ry = 0.2990, .gy = 0.5870, .by = 0.1140, .ay = 0.6006,
-		    .ru =-0.0885, .gu =-0.1738, .bu = 0.2624, .au = 1.0000,
-		    .rv = 0.3693, .gv =-0.3092, .bv =-0.0601, .av = 1.0000,
-	    },
-	    .filter_table = filter_table_ntsc,
+	.name		= "PAL-M",
+	.clock		= 107520,	
+	.oversample	= TV_OVERSAMPLE_8X,
+	.component_only = 0,
+
+	/* 525 Lines, 60 Fields, 15.734KHz line, Sub-Carrier 3.580MHz */
+	.hsync_end	= 64,		  .hblank_end		= 124,
+	.hblank_start = 836,	  .htotal		= 857,
+
+	.progressive	= FALSE,	    .trilevel_sync = FALSE,
+
+	.vsync_start_f1	= 6,		    .vsync_start_f2	= 7,
+	.vsync_len	= 6,
+
+	.veq_ena	= TRUE,		    .veq_start_f1    	= 0,
+	.veq_start_f2	= 1,		    .veq_len		= 18,
+
+	.vi_end_f1	= 20,		    .vi_end_f2		= 21,
+	.nbr_end	= 240,
+
+	.burst_ena	= TRUE,
+	.hburst_start	= 72,		    .hburst_len		= 34,
+	.vburst_start_f1 = 9,		    .vburst_end_f1	= 240,
+	.vburst_start_f2 = 10,		    .vburst_end_f2	= 240,
+	.vburst_start_f3 = 9,		    .vburst_end_f3	= 240, 
+	.vburst_start_f4 = 10,		    .vburst_end_f4	= 240,
+
+	/* desired 3.5800000 actual 3.5800000 clock 107.52 */
+	.dda1_inc	=    136,
+	.dda2_inc	=    7624,	    .dda2_size		=  20013,
+	.dda3_inc	=      0,	    .dda3_size		=      0,
+	.sc_reset	= TV_SC_RESET_EVERY_4,
+	.pal_burst  = FALSE,
+
+	.composite_levels = { .blank = 225, .black = 267, .burst = 113 },
+	.composite_color = {
+	    .ry = 0.2990, .gy = 0.5870, .by = 0.1140, .ay = 0.5082,
+	    .ru =-0.0749, .gu =-0.1471, .bu = 0.2220, .au = 1.0000,
+	    .rv = 0.3125, .gv =-0.2616, .bv =-0.0508, .av = 1.0000,
+	},
+
+	.svideo_levels    = { .blank = 266, .black = 316, .burst = 133 },
+	.svideo_color = {
+	    .ry = 0.2990, .gy = 0.5870, .by = 0.1140, .ay = 0.6006,
+	    .ru =-0.0885, .gu =-0.1738, .bu = 0.2624, .au = 1.0000,
+	    .rv = 0.3693, .gv =-0.3092, .bv =-0.0601, .av = 1.0000,
+	},
+	.filter_table = filter_table,
     },
     {
-	    /* 625 Lines, 50 Fields, 15.625KHz line, Sub-Carrier 4.434MHz */
-	    .name	    = "PAL-N",
-	    .clock		= 107520,	
-	    .oversample	= TV_OVERSAMPLE_8X,
-	    .component_only = 0,
-
-	    .hsync_end	= 64,		    .hblank_end		= 128,
-	    .hblank_start = 844,	    .htotal		= 863,
-
-	    .progressive  = FALSE,    .trilevel_sync = FALSE,
-
-
-	    .vsync_start_f1	= 6,	   .vsync_start_f2	= 7,
-	    .vsync_len	= 6,
-
-	    .veq_ena	= TRUE,		    .veq_start_f1    	= 0,
-	    .veq_start_f2	= 1,		    .veq_len		= 18,
-
-	    .vi_end_f1	= 24,		    .vi_end_f2		= 25,
-	    .nbr_end	= 286,
-
-	    .burst_ena	= TRUE,
-	    .hburst_start = 73,	    .hburst_len		= 34,
-	    .vburst_start_f1 = 8,	    .vburst_end_f1	= 285,
-	    .vburst_start_f2 = 8,	    .vburst_end_f2	= 286,
-	    .vburst_start_f3 = 9,	    .vburst_end_f3	= 286, 
-	    .vburst_start_f4 = 9,	    .vburst_end_f4	= 285,
-
-	    /* desired 4.4336180 actual 4.4336180 clock 107.52 */
-	    .dda1_inc	=    135,
-	    .dda2_inc	=  23578,	.dda2_size	=  27648,
-	    .dda3_inc	=     134,	.dda3_size	=  625,
-	    .sc_reset   = TV_SC_RESET_EVERY_8,
-	    .pal_burst  = TRUE,
-
-	    .composite_levels = { .blank = 225, .black = 267, .burst = 118 },
-	    .composite_color = {
-		    .ry = 0.2990, .gy = 0.5870, .by = 0.1140, .ay = 0.5082,
-		    .ru =-0.0749, .gu =-0.1471, .bu = 0.2220, .au = 1.0000,
-		    .rv = 0.3125, .gv =-0.2616, .bv =-0.0508, .av = 1.0000,
-	    },
-
-	    .svideo_levels    = { .blank = 266, .black = 316, .burst = 139 },
-	    .svideo_color = {
-		    .ry = 0.2990, .gy = 0.5870, .by = 0.1140, .ay = 0.6006,
-		    .ru =-0.0885, .gu =-0.1738, .bu = 0.2624, .au = 1.0000,
-		    .rv = 0.3693, .gv =-0.3092, .bv =-0.0601, .av = 1.0000,
-	    },
-	    .filter_table = filter_table_ntsc,
+	/* 625 Lines, 50 Fields, 15.625KHz line, Sub-Carrier 4.434MHz */
+	.name	    = "PAL-N",
+	.clock		= 107520,	
+	.oversample	= TV_OVERSAMPLE_8X,
+	.component_only = 0,
+
+	.hsync_end	= 64,		    .hblank_end		= 128,
+	.hblank_start = 844,	    .htotal		= 863,
+
+	.progressive  = FALSE,    .trilevel_sync = FALSE,
+
+
+	.vsync_start_f1	= 6,	   .vsync_start_f2	= 7,
+	.vsync_len	= 6,
+
+	.veq_ena	= TRUE,		    .veq_start_f1    	= 0,
+	.veq_start_f2	= 1,		    .veq_len		= 18,
+
+	.vi_end_f1	= 24,		    .vi_end_f2		= 25,
+	.nbr_end	= 286,
+
+	.burst_ena	= TRUE,
+	.hburst_start = 73,	    	    .hburst_len		= 34,
+	.vburst_start_f1 = 8,	    .vburst_end_f1	= 285,
+	.vburst_start_f2 = 8,	    .vburst_end_f2	= 286,
+	.vburst_start_f3 = 9,	    .vburst_end_f3	= 286, 
+	.vburst_start_f4 = 9,	    .vburst_end_f4	= 285,
+
+
+	/* desired 4.4336180 actual 4.4336180 clock 107.52 */
+	.dda1_inc       =    168,
+	.dda2_inc       =  18557,       .dda2_size      =  20625,
+	.dda3_inc       =      0,       .dda3_size      =      0,
+	.sc_reset   = TV_SC_RESET_EVERY_8,
+	.pal_burst  = TRUE,
+
+	.composite_levels = { .blank = 225, .black = 267, .burst = 118 },
+	.composite_color = {
+	    .ry = 0.2990, .gy = 0.5870, .by = 0.1140, .ay = 0.5082,
+	    .ru =-0.0749, .gu =-0.1471, .bu = 0.2220, .au = 1.0000,
+	    .rv = 0.3125, .gv =-0.2616, .bv =-0.0508, .av = 1.0000,
+	},
+
+	.svideo_levels    = { .blank = 266, .black = 316, .burst = 139 },
+	.svideo_color = {
+	    .ry = 0.2990, .gy = 0.5870, .by = 0.1140, .ay = 0.6006,
+	    .ru =-0.0885, .gu =-0.1738, .bu = 0.2624, .au = 1.0000,
+	    .rv = 0.3693, .gv =-0.3092, .bv =-0.0601, .av = 1.0000,
+	},
+	.filter_table = filter_table,
     },
     {
-	    /* 625 Lines, 50 Fields, 15.625KHz line, Sub-Carrier 4.434MHz */
-	    .name	    = "PAL",
-	    .clock		= 107520,	
-	    .oversample	= TV_OVERSAMPLE_8X,
-	    .component_only = 0,
-
-	    .hsync_end	= 64,		    .hblank_end		= 128,
-	    .hblank_start	= 844,		    .htotal		= 863,
-
-	    .progressive	= FALSE,	   .trilevel_sync = FALSE,
-
-
-	    .vsync_start_f1	= 6,		    .vsync_start_f2	= 7,
-	    .vsync_len	= 6,
-
-	    .veq_ena	= TRUE,		    .veq_start_f1    	= 0,
-	    .veq_start_f2	= 1,		    .veq_len		= 18,
-
-	    .vi_end_f1	= 24,		    .vi_end_f2		= 25,
-	    .nbr_end	= 286,
-
-	    .burst_ena	= TRUE,
-	    .hburst_start	= 73,		    .hburst_len		= 34,
-	    .vburst_start_f1 = 8,		    .vburst_end_f1	= 285,
-	    .vburst_start_f2 = 8,		    .vburst_end_f2	= 286,
-	    .vburst_start_f3 = 9,		    .vburst_end_f3	= 286, 
-	    .vburst_start_f4 = 9,		    .vburst_end_f4	= 285,
-
-	    /* desired 4.4336180 actual 4.4336180 clock 107.52 */
-	    .dda1_inc	=    168,
-	    .dda2_inc	=   4122,	.dda2_size	=  27648,
-	    .dda3_inc	=     67,	.dda3_size	=  625,
-	    .sc_reset   = TV_SC_RESET_EVERY_8,
-	    .pal_burst  = TRUE,
-
-	    .composite_levels = { .blank = 237, .black = 237, .burst = 118 },
-	    .composite_color = {
-		    .ry = 0.2990, .gy = 0.5870, .by = 0.1140, .ay = 0.5379,
-		    .ru =-0.0793, .gu =-0.1557, .bu = 0.2350, .au = 1.0000,
-		    .rv = 0.3307, .gv =-0.2769, .bv =-0.0538, .av = 1.0000,
-	    },
-
-	    .svideo_levels    = { .blank = 280, .black = 280, .burst = 139 },
-	    .svideo_color = {
-		    .ry = 0.2990, .gy = 0.5870, .by = 0.1140, .ay = 0.6357,
-		    .ru =-0.0937, .gu =-0.1840, .bu = 0.2777, .au = 1.0000,
-		    .rv = 0.3908, .gv =-0.3273, .bv =-0.0636, .av = 1.0000,
-	    },
-	    .filter_table = filter_table_ntsc,
+	/* 625 Lines, 50 Fields, 15.625KHz line, Sub-Carrier 4.434MHz */
+	.name	    = "PAL",
+	.clock		= 107520,	
+	.oversample	= TV_OVERSAMPLE_8X,
+	.component_only = 0,
+
+	.hsync_end	= 64,		    .hblank_end		= 128,
+	.hblank_start	= 844,	    .htotal		= 863,
+
+	.progressive	= FALSE,    .trilevel_sync = FALSE,
+
+	.vsync_start_f1	= 5,	    .vsync_start_f2	= 6,
+	.vsync_len	= 5,
+
+	.veq_ena	= TRUE,		    .veq_start_f1    	= 0,
+	.veq_start_f2	= 1,	    .veq_len		= 15,
+
+	.vi_end_f1	= 24,		    .vi_end_f2		= 25,
+	.nbr_end	= 286,
+
+	.burst_ena	= TRUE,
+	.hburst_start	= 73,		    .hburst_len		= 32,
+	.vburst_start_f1 = 8,		    .vburst_end_f1	= 285,
+	.vburst_start_f2 = 8,		    .vburst_end_f2	= 286,
+	.vburst_start_f3 = 9,		    .vburst_end_f3	= 286, 
+	.vburst_start_f4 = 9,		    .vburst_end_f4	= 285,
+
+	/* desired 4.4336180 actual 4.4336180 clock 107.52 */
+	.dda1_inc       =    168,
+	.dda2_inc       =  18557,       .dda2_size      =  20625,
+	.dda3_inc       =      0,       .dda3_size      =      0,
+	.sc_reset   = TV_SC_RESET_EVERY_8,
+	.pal_burst  = TRUE,
+
+	.composite_levels = { .blank = 237, .black = 237, .burst = 118 },
+	.composite_color = {
+	    .ry = 0.2990, .gy = 0.5870, .by = 0.1140, .ay = 0.5379,
+	    .ru =-0.0793, .gu =-0.1557, .bu = 0.2350, .au = 1.0000,
+	    .rv = 0.3307, .gv =-0.2769, .bv =-0.0538, .av = 1.0000,
+	},
+
+	.svideo_levels    = { .blank = 280, .black = 280, .burst = 139 },
+	.svideo_color = {
+	    .ry = 0.2990, .gy = 0.5870, .by = 0.1140, .ay = 0.6357,
+	    .ru =-0.0937, .gu =-0.1840, .bu = 0.2777, .au = 1.0000,
+	    .rv = 0.3908, .gv =-0.3273, .bv =-0.0636, .av = 1.0000,
+	},
+	.filter_table = filter_table,
     },
     {
-	    .name       = "480p at 59.94Hz",
-	    .clock 	= 107520,	
-	    .oversample     = TV_OVERSAMPLE_4X,
-	    .component_only = 1,
-
-	    .hsync_end      = 64,               .hblank_end         = 122,
-	    .hblank_start   = 842,              .htotal             = 857,
-
-	    .progressive    = TRUE,.trilevel_sync = FALSE,
-
-	    .vsync_start_f1 = 12,               .vsync_start_f2     = 12,
-	    .vsync_len      = 12,
-
-	    .veq_ena        = FALSE,
-
-	    .vi_end_f1      = 44,               .vi_end_f2          = 44,
-	    .nbr_end        = 496,
-
-	    .burst_ena      = FALSE,
-
-	    .composite_levels = { .blank = 237, .black = 237, .burst = 118 },
-	    .composite_color = {
-		    .ry = 0.2990, .gy = 0.5870, .by = 0.1140, .ay = 0.5379,
-		    .ru =-0.0793, .gu =-0.1557, .bu = 0.2350, .au = 1.0000,
-		    .rv = 0.3307, .gv =-0.2769, .bv =-0.0538, .av = 1.0000,
-	    },
-
-	    .svideo_levels    = { .blank = 280, .black = 280, .burst = 139 },
-	    .svideo_color = {
-		    .ry = 0.2990, .gy = 0.5870, .by = 0.1140, .ay = 0.6357,
-		    .ru =-0.0937, .gu =-0.1840, .bu = 0.2777, .au = 1.0000,
-		    .rv = 0.3908, .gv =-0.3273, .bv =-0.0636, .av = 1.0000,
-	    },
-	    .filter_table = filter_table_hres,
+	.name       = "480p at 59.94Hz",
+	.clock 	= 107520,	
+	.oversample     = TV_OVERSAMPLE_4X,
+	.component_only = 1,
+
+	.hsync_end      = 64,               .hblank_end         = 122,
+	.hblank_start   = 842,              .htotal             = 857,
+
+	.progressive    = TRUE,.trilevel_sync = FALSE,
+
+	.vsync_start_f1 = 12,               .vsync_start_f2     = 12,
+	.vsync_len      = 12,
+
+	.veq_ena        = FALSE,
+
+	.vi_end_f1      = 44,               .vi_end_f2          = 44,
+	.nbr_end        = 496,
+
+	.burst_ena      = FALSE,
+
+	.filter_table = filter_table,
     },
     {
-	    .name       = "480p at 60Hz",
-	    .clock 	= 107520,	
-	    .oversample     = TV_OVERSAMPLE_4X,
-	    .component_only = 1,
-
-	    .hsync_end      = 64,               .hblank_end         = 122,
-	    .hblank_start   = 842,              .htotal             = 856,
-
-	    .progressive    = TRUE,.trilevel_sync = FALSE,
-
-	    .vsync_start_f1 = 12,               .vsync_start_f2     = 12,
-	    .vsync_len      = 12,
-
-	    .veq_ena        = FALSE,
-
-	    .vi_end_f1      = 44,               .vi_end_f2          = 44,
-	    .nbr_end        = 496,
-
-	    .burst_ena      = FALSE,
-
-	    .composite_levels = { .blank = 237, .black = 237, .burst = 118 },
-	    .composite_color = {
-		    .ry = 0.2990, .gy = 0.5870, .by = 0.1140, .ay = 0.5379,
-		    .ru =-0.0793, .gu =-0.1557, .bu = 0.2350, .au = 1.0000,
-		    .rv = 0.3307, .gv =-0.2769, .bv =-0.0538, .av = 1.0000,
-	    },
-
-	    .svideo_levels    = { .blank = 280, .black = 280, .burst = 139 },
-	    .svideo_color = {
-		    .ry = 0.2990, .gy = 0.5870, .by = 0.1140, .ay = 0.6357,
-		    .ru =-0.0937, .gu =-0.1840, .bu = 0.2777, .au = 1.0000,
-		    .rv = 0.3908, .gv =-0.3273, .bv =-0.0636, .av = 1.0000,
-	    },
-	    .filter_table = filter_table_hres,
+	.name       = "480p at 60Hz",
+	.clock 	= 107520,	
+	.oversample     = TV_OVERSAMPLE_4X,
+	.component_only = 1,
+
+	.hsync_end      = 64,               .hblank_end         = 122,
+	.hblank_start   = 842,              .htotal             = 856,
+
+	.progressive    = TRUE,.trilevel_sync = FALSE,
+
+	.vsync_start_f1 = 12,               .vsync_start_f2     = 12,
+	.vsync_len      = 12,
+
+	.veq_ena        = FALSE,
+
+	.vi_end_f1      = 44,               .vi_end_f2          = 44,
+	.nbr_end        = 496,
+
+	.burst_ena      = FALSE,
+
+	.filter_table = filter_table,
     },
     {
-	    .name       = "576p",
-	    .clock 	= 107520,	
-	    .oversample     = TV_OVERSAMPLE_4X,
-	    .component_only = 1,
-
-	    .hsync_end      = 64,               .hblank_end         = 139,
-	    .hblank_start   = 859,              .htotal             = 863,
-
-	    .progressive    = TRUE,		.trilevel_sync = FALSE,
-
-	    .vsync_start_f1 = 10,               .vsync_start_f2     = 10,
-	    .vsync_len      = 10,
-
-	    .veq_ena        = FALSE,
-
-	    .vi_end_f1      = 48,               .vi_end_f2          = 48,
-	    .nbr_end        = 575,
-
-	    .burst_ena      = FALSE,
-
-	    .composite_levels = { .blank = 237, .black = 237, .burst = 118 },
-	    .composite_color = {
-		    .ry = 0.2990, .gy = 0.5870, .by = 0.1140, .ay = 0.5379,
-		    .ru =-0.0793, .gu =-0.1557, .bu = 0.2350, .au = 1.0000,
-		    .rv = 0.3307, .gv =-0.2769, .bv =-0.0538, .av = 1.0000,
-	    },
-
-	    .svideo_levels    = { .blank = 280, .black = 280, .burst = 139 },
-	    .svideo_color = {
-		    .ry = 0.2990, .gy = 0.5870, .by = 0.1140, .ay = 0.6357,
-		    .ru =-0.0937, .gu =-0.1840, .bu = 0.2777, .au = 1.0000,
-		    .rv = 0.3908, .gv =-0.3273, .bv =-0.0636, .av = 1.0000,
-	    },
-	    .filter_table = filter_table_hres,
+	.name       = "576p",
+	.clock 	= 107520,	
+	.oversample     = TV_OVERSAMPLE_4X,
+	.component_only = 1,
+
+	.hsync_end      = 64,               .hblank_end         = 139,
+	.hblank_start   = 859,              .htotal             = 863,
+
+	.progressive    = TRUE,		.trilevel_sync = FALSE,
+
+	.vsync_start_f1 = 10,               .vsync_start_f2     = 10,
+	.vsync_len      = 10,
+
+	.veq_ena        = FALSE,
+
+	.vi_end_f1      = 48,               .vi_end_f2          = 48,
+	.nbr_end        = 575,
+
+	.burst_ena      = FALSE,
+
+	.filter_table = filter_table,
     },
     {
-	    .name       = "720p at 60Hz",
-	    .clock		= 148800,	
-	    .oversample     = TV_OVERSAMPLE_2X,
-	    .component_only = 1,
+	.name       = "720p at 60Hz",
+	.clock		= 148800,	
+	.oversample     = TV_OVERSAMPLE_2X,
+	.component_only = 1,
 
-	    .hsync_end      = 80,               .hblank_end         = 300,
-	    .hblank_start   = 1580,             .htotal             = 1649,
+	.hsync_end      = 80,               .hblank_end         = 300,
+	.hblank_start   = 1580,             .htotal             = 1649,
 
-	    .progressive    = TRUE, 	    .trilevel_sync = TRUE,
+	.progressive    = TRUE, 	    .trilevel_sync = TRUE,
 
-	    .vsync_start_f1 = 10,               .vsync_start_f2     = 10,
-	    .vsync_len      = 10,
+	.vsync_start_f1 = 10,               .vsync_start_f2     = 10,
+	.vsync_len      = 10,
 
-	    .veq_ena        = FALSE,
+	.veq_ena        = FALSE,
 
-	    .vi_end_f1      = 29,               .vi_end_f2          = 29,
-	    .nbr_end        = 719,
+	.vi_end_f1      = 29,               .vi_end_f2          = 29,
+	.nbr_end        = 719,
 
-	    .burst_ena      = FALSE,
+	.burst_ena      = FALSE,
 
-	    .composite_levels = { .blank = 237, .black = 237, .burst = 118 },
-	    .composite_color = {
-		    .ry = 0.2990, .gy = 0.5870, .by = 0.1140, .ay = 0.5379,
-		    .ru =-0.0793, .gu =-0.1557, .bu = 0.2350, .au = 1.0000,
-		    .rv = 0.3307, .gv =-0.2769, .bv =-0.0538, .av = 1.0000,
-	    },
-	    .filter_table = filter_table_hres,
+	.filter_table = filter_table,
     },
     {
-	    .name       = "720p at 59.94Hz",
-	    .clock		= 148800,	
-	    .oversample     = TV_OVERSAMPLE_2X,
-	    .component_only = 1,
+	.name       = "720p at 59.94Hz",
+	.clock		= 148800,	
+	.oversample     = TV_OVERSAMPLE_2X,
+	.component_only = 1,
 
-	    .hsync_end      = 80,               .hblank_end         = 300,
-	    .hblank_start   = 1580,             .htotal             = 1651,
+	.hsync_end      = 80,               .hblank_end         = 300,
+	.hblank_start   = 1580,             .htotal             = 1651,
 
-	    .progressive    = TRUE, 	    .trilevel_sync = TRUE,
+	.progressive    = TRUE, 	    .trilevel_sync = TRUE,
 
-	    .vsync_start_f1 = 10,               .vsync_start_f2     = 10,
-	    .vsync_len      = 10,
+	.vsync_start_f1 = 10,               .vsync_start_f2     = 10,
+	.vsync_len      = 10,
 
-	    .veq_ena        = FALSE,
+	.veq_ena        = FALSE,
 
-	    .vi_end_f1      = 29,               .vi_end_f2          = 29,
-	    .nbr_end        = 719,
+	.vi_end_f1      = 29,               .vi_end_f2          = 29,
+	.nbr_end        = 719,
 
-	    .burst_ena      = FALSE,
+	.burst_ena      = FALSE,
 
-	    .composite_levels = { .blank = 237, .black = 237, .burst = 118 },
-	    .composite_color = {
-		    .ry = 0.2990, .gy = 0.5870, .by = 0.1140, .ay = 0.5379,
-		    .ru =-0.0793, .gu =-0.1557, .bu = 0.2350, .au = 1.0000,
-		    .rv = 0.3307, .gv =-0.2769, .bv =-0.0538, .av = 1.0000,
-	    },
-	    .filter_table = filter_table_hres,
+	.filter_table = filter_table,
     },
     {
-	    .name       = "720p at 50Hz",
-	    .clock		= 148800,	
-	    .oversample     = TV_OVERSAMPLE_2X,
-	    .component_only = 1,
-
-	    .hsync_end      = 80,               .hblank_end         = 300,
-	    .hblank_start   = 1580,             .htotal             = 1979,
-
-	    .progressive    = TRUE, 	        .trilevel_sync = TRUE,
-
-	    .vsync_start_f1 = 10,               .vsync_start_f2     = 10,
-	    .vsync_len      = 10,
-
-	    .veq_ena        = FALSE,
-
-	    .vi_end_f1      = 29,               .vi_end_f2          = 29,
-	    .nbr_end        = 719,
-
-	    .burst_ena      = FALSE,
-
-	    .pal_burst  = TRUE,
-	    .composite_levels = { .blank = 237, .black = 237, .burst = 118 },
-	    .composite_color = {
-		    .ry = 0.2990, .gy = 0.5870, .by = 0.1140, .ay = 0.5379,
-		    .ru =-0.0793, .gu =-0.1557, .bu = 0.2350, .au = 1.0000,
-		    .rv = 0.3307, .gv =-0.2769, .bv =-0.0538, .av = 1.0000,
-	    },
-	    .filter_table = filter_table_hres,
-	    .max_srcw = 800
+	.name       = "720p at 50Hz",
+	.clock		= 148800,	
+	.oversample     = TV_OVERSAMPLE_2X,
+	.component_only = 1,
+
+	.hsync_end      = 80,               .hblank_end         = 300,
+	.hblank_start   = 1580,             .htotal             = 1979,
+
+	.progressive    = TRUE, 	        .trilevel_sync = TRUE,
+
+	.vsync_start_f1 = 10,               .vsync_start_f2     = 10,
+	.vsync_len      = 10,
+
+	.veq_ena        = FALSE,
+
+	.vi_end_f1      = 29,               .vi_end_f2          = 29,
+	.nbr_end        = 719,
+
+	.burst_ena      = FALSE,
+
+	.filter_table = filter_table,
+	.max_srcw = 800
     },
     {
-	    .name       = "1080i at 50Hz",
-	    .clock		= 148800,	
-	    .oversample     = TV_OVERSAMPLE_2X,
-	    .component_only = 1,
+	.name       = "1080i at 50Hz",
+	.clock		= 148800,	
+	.oversample     = TV_OVERSAMPLE_2X,
+	.component_only = 1,
 
-	    .hsync_end      = 88,               .hblank_end         = 235,
-	    .hblank_start   = 2155,             .htotal             = 2639,
+	.hsync_end      = 88,               .hblank_end         = 235,
+	.hblank_start   = 2155,             .htotal             = 2639,
 
-	    .progressive    = FALSE, 	    .trilevel_sync = TRUE,
+	.progressive    = FALSE, 	    .trilevel_sync = TRUE,
 
-	    .vsync_start_f1 = 4,              .vsync_start_f2     = 5,
-	    .vsync_len      = 10,
+	.vsync_start_f1 = 4,              .vsync_start_f2     = 5,
+	.vsync_len      = 10,
 
-	    .veq_ena	= TRUE,		    .veq_start_f1    	= 4,
-	    .veq_start_f2   = 4,	    .veq_len		= 10,
+	.veq_ena	= TRUE,		    .veq_start_f1    	= 4,
+	.veq_start_f2   = 4,	    .veq_len		= 10,
 
 
-	    .vi_end_f1      = 21,           .vi_end_f2          = 22,
-	    .nbr_end        = 539,
+	.vi_end_f1      = 21,           .vi_end_f2          = 22,
+	.nbr_end        = 539,
 
-	    .burst_ena      = FALSE,
+	.burst_ena      = FALSE,
 
-	    .composite_levels = { .blank = 237, .black = 237, .burst = 118 },
-	    .composite_color = {
-		    .ry = 0.2990, .gy = 0.5870, .by = 0.1140, .ay = 0.5379,
-		    .ru =-0.0793, .gu =-0.1557, .bu = 0.2350, .au = 1.0000,
-		    .rv = 0.3307, .gv =-0.2769, .bv =-0.0538, .av = 1.0000,
-	    },
-	    .filter_table = filter_table_hres,
+	.filter_table = filter_table,
     },
     {
-	    .name       = "1080i at 60Hz",
-	    .clock		= 148800,	
-	    .oversample     = TV_OVERSAMPLE_2X,
-	    .component_only = 1,
+	.name       = "1080i at 60Hz",
+	.clock		= 148800,	
+	.oversample     = TV_OVERSAMPLE_2X,
+	.component_only = 1,
 
-	    .hsync_end      = 88,               .hblank_end         = 235,
-	    .hblank_start   = 2155,             .htotal             = 2199,
+	.hsync_end      = 88,               .hblank_end         = 235,
+	.hblank_start   = 2155,             .htotal             = 2199,
 
-	    .progressive    = FALSE, 	    .trilevel_sync = TRUE,
+	.progressive    = FALSE, 	    .trilevel_sync = TRUE,
 
-	    .vsync_start_f1 = 4,               .vsync_start_f2     = 5,
-	    .vsync_len      = 10,
+	.vsync_start_f1 = 4,               .vsync_start_f2     = 5,
+	.vsync_len      = 10,
 
-	    .veq_ena	= TRUE,		    .veq_start_f1    	= 4,
-	    .veq_start_f2	= 4,		    .veq_len		= 10,
+	.veq_ena	= TRUE,		    .veq_start_f1    	= 4,
+	.veq_start_f2	= 4,		    .veq_len		= 10,
 
 
-	    .vi_end_f1      = 21,               .vi_end_f2          = 22,
-	    .nbr_end        = 539,
+	.vi_end_f1      = 21,               .vi_end_f2          = 22,
+	.nbr_end        = 539,
 
-	    .burst_ena      = FALSE,
+	.burst_ena      = FALSE,
 
-	    .composite_levels = { .blank = 237, .black = 237, .burst = 118 },
-	    .composite_color = {
-		    .ry = 0.2990, .gy = 0.5870, .by = 0.1140, .ay = 0.5379,
-		    .ru =-0.0793, .gu =-0.1557, .bu = 0.2350, .au = 1.0000,
-		    .rv = 0.3307, .gv =-0.2769, .bv =-0.0538, .av = 1.0000,
-	    },
-	    .filter_table = filter_table_hres,
+	.filter_table = filter_table,
     },
     {
-	    .name       = "1080i at 59.94Hz",
-	    .clock		= 148800,	
-	    .oversample     = TV_OVERSAMPLE_2X,
-	    .component_only = 1,
+	.name       = "1080i at 59.94Hz",
+	.clock		= 148800,	
+	.oversample     = TV_OVERSAMPLE_2X,
+	.component_only = 1,
 
-	    .hsync_end      = 88,               .hblank_end         = 235,
-	    .hblank_start   = 2155,             .htotal             = 2200,
+	.hsync_end      = 88,               .hblank_end         = 235,
+	.hblank_start   = 2155,             .htotal             = 2200,
 
-	    .progressive    = FALSE, 	    .trilevel_sync = TRUE,
+	.progressive    = FALSE, 	    .trilevel_sync = TRUE,
 
-	    .vsync_start_f1 = 4,            .vsync_start_f2    = 5,
-	    .vsync_len      = 10,
+	.vsync_start_f1 = 4,            .vsync_start_f2    = 5,
+	.vsync_len      = 10,
 
-	    .veq_ena	= TRUE,		    .veq_start_f1	= 4,
-	    .veq_start_f2 = 4,	    	    .veq_len = 10,
+	.veq_ena	= TRUE,		    .veq_start_f1	= 4,
+	.veq_start_f2 = 4,	    	    .veq_len = 10,
 
 
-	    .vi_end_f1      = 21,           .vi_end_f2         	= 22,
-	    .nbr_end        = 539,
+	.vi_end_f1      = 21,           .vi_end_f2         	= 22,
+	.nbr_end        = 539,
 
-	    .burst_ena      = FALSE,
+	.burst_ena      = FALSE,
 
-	    .composite_levels = { .blank = 237, .black = 237, .burst = 118 },
-	    .composite_color = {
-		    .ry = 0.2990, .gy = 0.5870, .by = 0.1140, .ay = 0.5379,
-		    .ru =-0.0793, .gu =-0.1557, .bu = 0.2350, .au = 1.0000,
-		    .rv = 0.3307, .gv =-0.2769, .bv =-0.0538, .av = 1.0000,
-	    },
-	    .filter_table = filter_table_hres,
+	.filter_table = filter_table,
     },
 };
 
@@ -855,165 +734,165 @@ static const video_levels_t component_le
 };
 
 static const color_conversion_t sdtv_component_color = {
-	.ry = 0.2990, .gy = 0.5870, .by = 0.1140, .ay = 0.6364,
-	.ru =-0.1687, .gu =-0.3313, .bu = 0.5000, .au = 1.0000,
-	.rv = 0.5000, .gv =-0.4187, .bv =-0.0813, .av = 1.0000,
+    .ry = 0.2990, .gy = 0.5870, .by = 0.1140, .ay = 0.6364,
+    .ru =-0.1687, .gu =-0.3313, .bu = 0.5000, .au = 1.0000,
+    .rv = 0.5000, .gv =-0.4187, .bv =-0.0813, .av = 1.0000,
 };
 
 static const color_conversion_t hdtv_component_color = {
-	.ry = 0.2126, .gy = 0.7152, .by = 0.0722, .ay = 0.6364,
-	.ru =-0.1146, .gu =-0.3854, .bu = 0.5000, .au = 1.0000,
-	.rv = 0.5000, .gv =-0.4542, .bv =-0.0458, .av = 1.0000,
+    .ry = 0.2126, .gy = 0.7152, .by = 0.0722, .ay = 0.6364,
+    .ru =-0.1146, .gu =-0.3854, .bu = 0.5000, .au = 1.0000,
+    .rv = 0.5000, .gv =-0.4542, .bv =-0.0458, .av = 1.0000,
 };
 
 static void
 i830_tv_dpms(xf86OutputPtr output, int mode)
 {
-	ScrnInfoPtr pScrn = output->scrn;
-	I830Ptr pI830 = I830PTR(pScrn);
+    ScrnInfoPtr pScrn = output->scrn;
+    I830Ptr pI830 = I830PTR(pScrn);
 
-	switch(mode) {
-		case DPMSModeOn:
-			OUTREG(TV_CTL, INREG(TV_CTL) | TV_ENC_ENABLE);
-			break;
-		case DPMSModeStandby:
-		case DPMSModeSuspend:
-		case DPMSModeOff:
-			OUTREG(TV_CTL, INREG(TV_CTL) & ~TV_ENC_ENABLE);
-			break;
-	}
+    switch(mode) {
+	case DPMSModeOn:
+	    OUTREG(TV_CTL, INREG(TV_CTL) | TV_ENC_ENABLE);
+	    break;
+	case DPMSModeStandby:
+	case DPMSModeSuspend:
+	case DPMSModeOff:
+	    OUTREG(TV_CTL, INREG(TV_CTL) & ~TV_ENC_ENABLE);
+	    break;
+    }
 }
 
 static void
 i830_tv_save(xf86OutputPtr output)
 {
-	ScrnInfoPtr		    pScrn = output->scrn;
-	I830Ptr		    pI830 = I830PTR(pScrn);
-	I830OutputPrivatePtr    intel_output = output->driver_private;
-	struct i830_tv_priv	    *dev_priv = intel_output->dev_priv;
-	int			    i;
-
-	dev_priv->save_TV_H_CTL_1 = INREG(TV_H_CTL_1);
-	dev_priv->save_TV_H_CTL_2 = INREG(TV_H_CTL_2);
-	dev_priv->save_TV_H_CTL_3 = INREG(TV_H_CTL_3);
-	dev_priv->save_TV_V_CTL_1 = INREG(TV_V_CTL_1);
-	dev_priv->save_TV_V_CTL_2 = INREG(TV_V_CTL_2);
-	dev_priv->save_TV_V_CTL_3 = INREG(TV_V_CTL_3);
-	dev_priv->save_TV_V_CTL_4 = INREG(TV_V_CTL_4);
-	dev_priv->save_TV_V_CTL_5 = INREG(TV_V_CTL_5);
-	dev_priv->save_TV_V_CTL_6 = INREG(TV_V_CTL_6);
-	dev_priv->save_TV_V_CTL_7 = INREG(TV_V_CTL_7);
-	dev_priv->save_TV_SC_CTL_1 = INREG(TV_SC_CTL_1);
-	dev_priv->save_TV_SC_CTL_2 = INREG(TV_SC_CTL_2);
-	dev_priv->save_TV_SC_CTL_3 = INREG(TV_SC_CTL_3);
-
-	dev_priv->save_TV_CSC_Y = INREG(TV_CSC_Y);
-	dev_priv->save_TV_CSC_Y2 = INREG(TV_CSC_Y2);
-	dev_priv->save_TV_CSC_U = INREG(TV_CSC_U);
-	dev_priv->save_TV_CSC_U2 = INREG(TV_CSC_U2);
-	dev_priv->save_TV_CSC_V = INREG(TV_CSC_V);
-	dev_priv->save_TV_CSC_V2 = INREG(TV_CSC_V2);
-	dev_priv->save_TV_CLR_KNOBS = INREG(TV_CLR_KNOBS);
-	dev_priv->save_TV_CLR_LEVEL = INREG(TV_CLR_LEVEL);
-	dev_priv->save_TV_WIN_POS = INREG(TV_WIN_POS);
-	dev_priv->save_TV_WIN_SIZE = INREG(TV_WIN_SIZE);
-	dev_priv->save_TV_FILTER_CTL_1 = INREG(TV_FILTER_CTL_1);
-	dev_priv->save_TV_FILTER_CTL_2 = INREG(TV_FILTER_CTL_2);
-	dev_priv->save_TV_FILTER_CTL_3 = INREG(TV_FILTER_CTL_3);
-
-	for (i = 0; i < 60; i++)
-		dev_priv->save_TV_H_LUMA[i] = INREG(TV_H_LUMA_0 + (i <<2));
-	for (i = 0; i < 60; i++)
-		dev_priv->save_TV_H_CHROMA[i] = INREG(TV_H_CHROMA_0 + (i <<2));
-	for (i = 0; i < 43; i++)
-		dev_priv->save_TV_V_LUMA[i] = INREG(TV_V_LUMA_0 + (i <<2));
-	for (i = 0; i < 43; i++)
-		dev_priv->save_TV_V_CHROMA[i] = INREG(TV_V_CHROMA_0 + (i <<2));
+    ScrnInfoPtr		    pScrn = output->scrn;
+    I830Ptr		    pI830 = I830PTR(pScrn);
+    I830OutputPrivatePtr    intel_output = output->driver_private;
+    struct i830_tv_priv	    *dev_priv = intel_output->dev_priv;
+    int			    i;
 
-	dev_priv->save_TV_DAC = INREG(TV_DAC);
-	dev_priv->save_TV_CTL = INREG(TV_CTL);
+    dev_priv->save_TV_H_CTL_1 = INREG(TV_H_CTL_1);
+    dev_priv->save_TV_H_CTL_2 = INREG(TV_H_CTL_2);
+    dev_priv->save_TV_H_CTL_3 = INREG(TV_H_CTL_3);
+    dev_priv->save_TV_V_CTL_1 = INREG(TV_V_CTL_1);
+    dev_priv->save_TV_V_CTL_2 = INREG(TV_V_CTL_2);
+    dev_priv->save_TV_V_CTL_3 = INREG(TV_V_CTL_3);
+    dev_priv->save_TV_V_CTL_4 = INREG(TV_V_CTL_4);
+    dev_priv->save_TV_V_CTL_5 = INREG(TV_V_CTL_5);
+    dev_priv->save_TV_V_CTL_6 = INREG(TV_V_CTL_6);
+    dev_priv->save_TV_V_CTL_7 = INREG(TV_V_CTL_7);
+    dev_priv->save_TV_SC_CTL_1 = INREG(TV_SC_CTL_1);
+    dev_priv->save_TV_SC_CTL_2 = INREG(TV_SC_CTL_2);
+    dev_priv->save_TV_SC_CTL_3 = INREG(TV_SC_CTL_3);
+
+    dev_priv->save_TV_CSC_Y = INREG(TV_CSC_Y);
+    dev_priv->save_TV_CSC_Y2 = INREG(TV_CSC_Y2);
+    dev_priv->save_TV_CSC_U = INREG(TV_CSC_U);
+    dev_priv->save_TV_CSC_U2 = INREG(TV_CSC_U2);
+    dev_priv->save_TV_CSC_V = INREG(TV_CSC_V);
+    dev_priv->save_TV_CSC_V2 = INREG(TV_CSC_V2);
+    dev_priv->save_TV_CLR_KNOBS = INREG(TV_CLR_KNOBS);
+    dev_priv->save_TV_CLR_LEVEL = INREG(TV_CLR_LEVEL);
+    dev_priv->save_TV_WIN_POS = INREG(TV_WIN_POS);
+    dev_priv->save_TV_WIN_SIZE = INREG(TV_WIN_SIZE);
+    dev_priv->save_TV_FILTER_CTL_1 = INREG(TV_FILTER_CTL_1);
+    dev_priv->save_TV_FILTER_CTL_2 = INREG(TV_FILTER_CTL_2);
+    dev_priv->save_TV_FILTER_CTL_3 = INREG(TV_FILTER_CTL_3);
+
+    for (i = 0; i < 60; i++)
+	dev_priv->save_TV_H_LUMA[i] = INREG(TV_H_LUMA_0 + (i <<2));
+    for (i = 0; i < 60; i++)
+	dev_priv->save_TV_H_CHROMA[i] = INREG(TV_H_CHROMA_0 + (i <<2));
+    for (i = 0; i < 43; i++)
+	dev_priv->save_TV_V_LUMA[i] = INREG(TV_V_LUMA_0 + (i <<2));
+    for (i = 0; i < 43; i++)
+	dev_priv->save_TV_V_CHROMA[i] = INREG(TV_V_CHROMA_0 + (i <<2));
+
+    dev_priv->save_TV_DAC = INREG(TV_DAC);
+    dev_priv->save_TV_CTL = INREG(TV_CTL);
 }
 
 static void
 i830_tv_restore(xf86OutputPtr output)
 {
-	ScrnInfoPtr		    pScrn = output->scrn;
-	I830Ptr		    pI830 = I830PTR(pScrn);
-	I830OutputPrivatePtr    intel_output = output->driver_private;
-	struct i830_tv_priv	    *dev_priv = intel_output->dev_priv;
-	int			    i;
-
-	xf86CrtcPtr	    crtc = output->crtc;
-	I830CrtcPrivatePtr  intel_crtc;
-	if (!crtc)
-		return;
-	intel_crtc = crtc->driver_private;
-	OUTREG(TV_H_CTL_1, dev_priv->save_TV_H_CTL_1);
-	OUTREG(TV_H_CTL_2, dev_priv->save_TV_H_CTL_2);
-	OUTREG(TV_H_CTL_3, dev_priv->save_TV_H_CTL_3);
-	OUTREG(TV_V_CTL_1, dev_priv->save_TV_V_CTL_1);
-	OUTREG(TV_V_CTL_2, dev_priv->save_TV_V_CTL_2);
-	OUTREG(TV_V_CTL_3, dev_priv->save_TV_V_CTL_3);
-	OUTREG(TV_V_CTL_4, dev_priv->save_TV_V_CTL_4);
-	OUTREG(TV_V_CTL_5, dev_priv->save_TV_V_CTL_5);
-	OUTREG(TV_V_CTL_6, dev_priv->save_TV_V_CTL_6);
-	OUTREG(TV_V_CTL_7, dev_priv->save_TV_V_CTL_7);
-	OUTREG(TV_SC_CTL_1, dev_priv->save_TV_SC_CTL_1);
-	OUTREG(TV_SC_CTL_2, dev_priv->save_TV_SC_CTL_2);
-	OUTREG(TV_SC_CTL_3, dev_priv->save_TV_SC_CTL_3);
-
-	OUTREG(TV_CSC_Y, dev_priv->save_TV_CSC_Y);
-	OUTREG(TV_CSC_Y2, dev_priv->save_TV_CSC_Y2);
-	OUTREG(TV_CSC_U, dev_priv->save_TV_CSC_U);
-	OUTREG(TV_CSC_U2, dev_priv->save_TV_CSC_U2);
-	OUTREG(TV_CSC_V, dev_priv->save_TV_CSC_V);
-	OUTREG(TV_CSC_V2, dev_priv->save_TV_CSC_V2);
-	OUTREG(TV_CLR_KNOBS, dev_priv->save_TV_CLR_KNOBS);
-	OUTREG(TV_CLR_LEVEL, dev_priv->save_TV_CLR_LEVEL);
-
-	{
-		int pipeconf_reg = (intel_crtc->pipe == 0)?PIPEACONF:PIPEBCONF;
-		int dspcntr_reg = (intel_crtc->pipe == 0)?DSPACNTR : DSPBCNTR;
-		int pipeconf = INREG(pipeconf_reg);
-		int dspcntr = INREG(dspcntr_reg);
-		int dspbase_reg = (intel_crtc->pipe == 0) ? DSPABASE : DSPBBASE;
-		/* Pipe must be off here */
-		OUTREG(dspcntr_reg, dspcntr & ~DISPLAY_PLANE_ENABLE);
-		/* Flush the plane changes */
-		OUTREG(dspbase_reg, INREG(dspbase_reg));
-
-		if (!IS_I9XX(pI830)) {
-			/* Wait for vblank for the disable to take effect */
-			i830WaitForVblank(pScrn);
-		}
+    ScrnInfoPtr		    pScrn = output->scrn;
+    I830Ptr		    pI830 = I830PTR(pScrn);
+    I830OutputPrivatePtr    intel_output = output->driver_private;
+    struct i830_tv_priv	    *dev_priv = intel_output->dev_priv;
+    int			    i;
 
-		OUTREG(pipeconf_reg, pipeconf & ~PIPEACONF_ENABLE);
-		/* Wait for vblank for the disable to take effect. */
-		i830WaitForVblank(pScrn);
-
-		/* Filter ctl must be set before TV_WIN_SIZE and TV_WIN_POS */
-		OUTREG(TV_FILTER_CTL_1, dev_priv->save_TV_FILTER_CTL_1);
-		OUTREG(TV_FILTER_CTL_2, dev_priv->save_TV_FILTER_CTL_2);
-		OUTREG(TV_FILTER_CTL_3, dev_priv->save_TV_FILTER_CTL_3);
-		OUTREG(TV_WIN_POS, dev_priv->save_TV_WIN_POS);
-		OUTREG(TV_WIN_SIZE, dev_priv->save_TV_WIN_SIZE);
-		OUTREG(pipeconf_reg, pipeconf);
-		OUTREG(dspcntr_reg, dspcntr);
-		/* Flush the plane changes */
-		OUTREG(dspbase_reg, INREG(dspbase_reg));
+    xf86CrtcPtr	    crtc = output->crtc;
+    I830CrtcPrivatePtr  intel_crtc;
+    if (!crtc)
+	return;
+    intel_crtc = crtc->driver_private;
+    OUTREG(TV_H_CTL_1, dev_priv->save_TV_H_CTL_1);
+    OUTREG(TV_H_CTL_2, dev_priv->save_TV_H_CTL_2);
+    OUTREG(TV_H_CTL_3, dev_priv->save_TV_H_CTL_3);
+    OUTREG(TV_V_CTL_1, dev_priv->save_TV_V_CTL_1);
+    OUTREG(TV_V_CTL_2, dev_priv->save_TV_V_CTL_2);
+    OUTREG(TV_V_CTL_3, dev_priv->save_TV_V_CTL_3);
+    OUTREG(TV_V_CTL_4, dev_priv->save_TV_V_CTL_4);
+    OUTREG(TV_V_CTL_5, dev_priv->save_TV_V_CTL_5);
+    OUTREG(TV_V_CTL_6, dev_priv->save_TV_V_CTL_6);
+    OUTREG(TV_V_CTL_7, dev_priv->save_TV_V_CTL_7);
+    OUTREG(TV_SC_CTL_1, dev_priv->save_TV_SC_CTL_1);
+    OUTREG(TV_SC_CTL_2, dev_priv->save_TV_SC_CTL_2);
+    OUTREG(TV_SC_CTL_3, dev_priv->save_TV_SC_CTL_3);
+
+    OUTREG(TV_CSC_Y, dev_priv->save_TV_CSC_Y);
+    OUTREG(TV_CSC_Y2, dev_priv->save_TV_CSC_Y2);
+    OUTREG(TV_CSC_U, dev_priv->save_TV_CSC_U);
+    OUTREG(TV_CSC_U2, dev_priv->save_TV_CSC_U2);
+    OUTREG(TV_CSC_V, dev_priv->save_TV_CSC_V);
+    OUTREG(TV_CSC_V2, dev_priv->save_TV_CSC_V2);
+    OUTREG(TV_CLR_KNOBS, dev_priv->save_TV_CLR_KNOBS);
+    OUTREG(TV_CLR_LEVEL, dev_priv->save_TV_CLR_LEVEL);
+
+    {
+	int pipeconf_reg = (intel_crtc->pipe == 0)?PIPEACONF:PIPEBCONF;
+	int dspcntr_reg = (intel_crtc->pipe == 0)?DSPACNTR : DSPBCNTR;
+	int pipeconf = INREG(pipeconf_reg);
+	int dspcntr = INREG(dspcntr_reg);
+	int dspbase_reg = (intel_crtc->pipe == 0) ? DSPABASE : DSPBBASE;
+	/* Pipe must be off here */
+	OUTREG(dspcntr_reg, dspcntr & ~DISPLAY_PLANE_ENABLE);
+	/* Flush the plane changes */
+	OUTREG(dspbase_reg, INREG(dspbase_reg));
+
+	if (!IS_I9XX(pI830)) {
+	    /* Wait for vblank for the disable to take effect */
+	    i830WaitForVblank(pScrn);
 	}
 
-	for (i = 0; i < 60; i++)
-		OUTREG(TV_H_LUMA_0 + (i <<2), dev_priv->save_TV_H_LUMA[i]);
-	for (i = 0; i < 60; i++)
-		OUTREG(TV_H_CHROMA_0 + (i <<2), dev_priv->save_TV_H_CHROMA[i]);
-	for (i = 0; i < 43; i++)
-		OUTREG(TV_V_LUMA_0 + (i <<2), dev_priv->save_TV_V_LUMA[i]);
-	for (i = 0; i < 43; i++)
-		OUTREG(TV_V_CHROMA_0 + (i <<2), dev_priv->save_TV_V_CHROMA[i]);
+	OUTREG(pipeconf_reg, pipeconf & ~PIPEACONF_ENABLE);
+	/* Wait for vblank for the disable to take effect. */
+	i830WaitForVblank(pScrn);
+
+	/* Filter ctl must be set before TV_WIN_SIZE */
+	OUTREG(TV_FILTER_CTL_1, dev_priv->save_TV_FILTER_CTL_1);
+	OUTREG(TV_FILTER_CTL_2, dev_priv->save_TV_FILTER_CTL_2);
+	OUTREG(TV_FILTER_CTL_3, dev_priv->save_TV_FILTER_CTL_3);
+	OUTREG(TV_WIN_POS, dev_priv->save_TV_WIN_POS);
+	OUTREG(TV_WIN_SIZE, dev_priv->save_TV_WIN_SIZE);
+	OUTREG(pipeconf_reg, pipeconf);
+	OUTREG(dspcntr_reg, dspcntr);
+	/* Flush the plane changes */
+	OUTREG(dspbase_reg, INREG(dspbase_reg));
+    }
+
+    for (i = 0; i < 60; i++)
+	OUTREG(TV_H_LUMA_0 + (i <<2), dev_priv->save_TV_H_LUMA[i]);
+    for (i = 0; i < 60; i++)
+	OUTREG(TV_H_CHROMA_0 + (i <<2), dev_priv->save_TV_H_CHROMA[i]);
+    for (i = 0; i < 43; i++)
+	OUTREG(TV_V_LUMA_0 + (i <<2), dev_priv->save_TV_V_LUMA[i]);
+    for (i = 0; i < 43; i++)
+	OUTREG(TV_V_CHROMA_0 + (i <<2), dev_priv->save_TV_V_CHROMA[i]);
 
-	OUTREG(TV_DAC, dev_priv->save_TV_DAC);
-	OUTREG(TV_CTL, dev_priv->save_TV_CTL);
+    OUTREG(TV_DAC, dev_priv->save_TV_DAC);
+    OUTREG(TV_CTL, dev_priv->save_TV_CTL);
 }
 
 static int
@@ -1050,271 +929,271 @@ i830_tv_mode_fixup(xf86OutputPtr output,
 static CARD32
 i830_float_to_csc (float fin)
 {
-	CARD32  exp;
-	CARD32  mant;
-	CARD32  ret;
-	float   f = fin;
-
-	/* somehow the color conversion knows the signs of all the values */
-	if (f < 0) f = -f;
-
-	if (f >= 1)
-	{
-		exp = 0x7;
-		mant = 1 << 8;
-	}
-	else
-	{
-		for (exp = 0; exp < 3 && f < 0.5; exp++)
-			f *= 2.0;
-		mant = (f * (1 << 9) + 0.5);
-		if (mant >= (1 << 9))
-			mant = (1 << 9) - 1;
-	}
-	ret = (exp << 9) | mant;
-	return ret;
+    CARD32  exp;
+    CARD32  mant;
+    CARD32  ret;
+    float   f = fin;
+
+    /* somehow the color conversion knows the signs of all the values */
+    if (f < 0) f = -f;
+
+    if (f >= 1)
+    {
+	exp = 0x7;
+	mant = 1 << 8;
+    }
+    else
+    {
+	for (exp = 0; exp < 3 && f < 0.5; exp++)
+	    f *= 2.0;
+	mant = (f * (1 << 9) + 0.5);
+	if (mant >= (1 << 9))
+	    mant = (1 << 9) - 1;
+    }
+    ret = (exp << 9) | mant;
+    return ret;
 }
 
 static CARD16
 i830_float_to_luma (float f)
 {
-	CARD16  ret;
+    CARD16  ret;
 
-	ret = (f * (1 << 9));
-	return ret;
+    ret = (f * (1 << 9));
+    return ret;
 }
 
 static void
 i830_tv_mode_set(xf86OutputPtr output, DisplayModePtr mode,
 		DisplayModePtr adjusted_mode)
 {
-	ScrnInfoPtr		    pScrn = output->scrn;
-	I830Ptr		    pI830 = I830PTR(pScrn);
-	xf86CrtcPtr	    crtc = output->crtc;
-	I830OutputPrivatePtr    intel_output = output->driver_private;
-	I830CrtcPrivatePtr	    intel_crtc = crtc->driver_private;
-	struct i830_tv_priv	    *dev_priv = intel_output->dev_priv;
-	const tv_mode_t	    *tv_mode;
-	CARD32		    tv_ctl;
-	CARD32		    hctl1, hctl2, hctl3;
-	CARD32		    vctl1, vctl2, vctl3, vctl4, vctl5, vctl6, vctl7;
-	CARD32		    scctl1, scctl2, scctl3;
-	int			    i, j;
-	const video_levels_t	*video_levels;
-	const color_conversion_t	*color_conversion;
-	Bool		    burst_ena;
-
-	for (i = 0; i < sizeof(tv_modes) / sizeof (tv_modes[0]); i++) {
-		tv_mode = &tv_modes[i];
-		if (strstr(mode->name, tv_mode->name)) 
-			break;	
-	}
+    ScrnInfoPtr		    pScrn = output->scrn;
+    I830Ptr		    pI830 = I830PTR(pScrn);
+    xf86CrtcPtr	    crtc = output->crtc;
+    I830OutputPrivatePtr    intel_output = output->driver_private;
+    I830CrtcPrivatePtr	    intel_crtc = crtc->driver_private;
+    struct i830_tv_priv	    *dev_priv = intel_output->dev_priv;
+    const tv_mode_t	    *tv_mode;
+    CARD32		    tv_ctl;
+    CARD32		    hctl1, hctl2, hctl3;
+    CARD32		    vctl1, vctl2, vctl3, vctl4, vctl5, vctl6, vctl7;
+    CARD32		    scctl1, scctl2, scctl3;
+    int			    i, j;
+    const video_levels_t	*video_levels;
+    const color_conversion_t	*color_conversion;
+    Bool burst_ena;
+    for (i = 0; i < sizeof(tv_modes) / sizeof (tv_modes[0]); i++) {
+	tv_mode = &tv_modes[i];
+	if (strstr(mode->name, tv_mode->name))
+	    break;	
+    }
+    tv_ctl = 0;
+
+    switch (dev_priv->type) {
+	default:
+	case TV_TYPE_UNKNOWN:
+	case TV_TYPE_COMPOSITE:
+	    tv_ctl |= TV_ENC_OUTPUT_COMPOSITE;
+	    video_levels = &tv_mode->composite_levels;
+	    color_conversion = &tv_mode->composite_color;
+	    burst_ena = tv_mode->burst_ena;
+	    break;
+	case TV_TYPE_COMPONENT:
+	    tv_ctl |= TV_ENC_OUTPUT_COMPONENT;
+	    video_levels = &component_level;
+	    if (tv_mode->burst_ena)
+		color_conversion = &sdtv_component_color;
+	    else
+		color_conversion = &hdtv_component_color;
+	    burst_ena = FALSE;
+	    break;
+	case TV_TYPE_SVIDEO:
+	    tv_ctl |= TV_ENC_OUTPUT_SVIDEO;
+	    video_levels = &tv_mode->svideo_levels;
+	    color_conversion = &tv_mode->svideo_color;
+	    burst_ena = tv_mode->burst_ena;
+	    break;
+    }
+    hctl1 = (tv_mode->hsync_end << TV_HSYNC_END_SHIFT) |
+	(tv_mode->htotal << TV_HTOTAL_SHIFT);
 
-	tv_ctl = 0;
+    hctl2 = (tv_mode->hburst_start << 16) |
+	(tv_mode->hburst_len << TV_HBURST_LEN_SHIFT);
 
-	switch (dev_priv->type) {
-		default:
-		case TV_TYPE_UNKNOWN:
-		case TV_TYPE_COMPOSITE:
-			tv_ctl |= TV_ENC_OUTPUT_COMPOSITE;
-			video_levels = &tv_mode->composite_levels;
-			color_conversion = &tv_mode->composite_color;
-			burst_ena = tv_mode->burst_ena;
-			break;
-		case TV_TYPE_COMPONENT:
-			tv_ctl |= TV_ENC_OUTPUT_COMPONENT;
-			video_levels = &component_level;
-			if (tv_mode->burst_ena)
-				color_conversion = &sdtv_component_color;
-			else
-				color_conversion = &hdtv_component_color;
-			burst_ena = FALSE;
-			break;
-		case TV_TYPE_SVIDEO:
-			tv_ctl |= TV_ENC_OUTPUT_SVIDEO;
-			video_levels = &tv_mode->svideo_levels;
-			color_conversion = &tv_mode->svideo_color;
-			burst_ena = tv_mode->burst_ena;
-			break;
-	}
-	hctl1 = (tv_mode->hsync_end << TV_HSYNC_END_SHIFT) |
-		(tv_mode->htotal << TV_HTOTAL_SHIFT);
+    if (burst_ena)
+	hctl2 |= TV_BURST_ENA;
 
-	hctl2 = (tv_mode->hburst_start << 16) |
-		(tv_mode->hburst_len << TV_HBURST_LEN_SHIFT);
-	if (burst_ena)
-		hctl2 |= TV_BURST_ENA;
-
-	hctl3 = (tv_mode->hblank_start << TV_HBLANK_START_SHIFT) |
-		(tv_mode->hblank_end << TV_HBLANK_END_SHIFT);
-
-	vctl1 = (tv_mode->nbr_end << TV_NBR_END_SHIFT) |
-		(tv_mode->vi_end_f1 << TV_VI_END_F1_SHIFT) |
-		(tv_mode->vi_end_f2 << TV_VI_END_F2_SHIFT);
-
-	vctl2 = (tv_mode->vsync_len << TV_VSYNC_LEN_SHIFT) |
-		(tv_mode->vsync_start_f1 << TV_VSYNC_START_F1_SHIFT) |
-		(tv_mode->vsync_start_f2 << TV_VSYNC_START_F2_SHIFT);
-
-	vctl3 = (tv_mode->veq_len << TV_VEQ_LEN_SHIFT) |
-		(tv_mode->veq_start_f1 << TV_VEQ_START_F1_SHIFT) |
-		(tv_mode->veq_start_f2 << TV_VEQ_START_F2_SHIFT);
-	if (tv_mode->veq_ena)
-		vctl3 |= TV_EQUAL_ENA;
-
-	vctl4 = (tv_mode->vburst_start_f1 << TV_VBURST_START_F1_SHIFT) |
-		(tv_mode->vburst_end_f1 << TV_VBURST_END_F1_SHIFT);
-
-	vctl5 = (tv_mode->vburst_start_f2 << TV_VBURST_START_F2_SHIFT) |
-		(tv_mode->vburst_end_f2 << TV_VBURST_END_F2_SHIFT);
-
-	vctl6 = (tv_mode->vburst_start_f3 << TV_VBURST_START_F3_SHIFT) |
-		(tv_mode->vburst_end_f3 << TV_VBURST_END_F3_SHIFT);
-
-	vctl7 = (tv_mode->vburst_start_f4 << TV_VBURST_START_F4_SHIFT) |
-		(tv_mode->vburst_end_f4 << TV_VBURST_END_F4_SHIFT);
-
-	if (intel_crtc->pipe == 1)
-		tv_ctl |= TV_ENC_PIPEB_SELECT;
-	tv_ctl |= tv_mode->oversample;
+    hctl3 = (tv_mode->hblank_start << TV_HBLANK_START_SHIFT) |
+	(tv_mode->hblank_end << TV_HBLANK_END_SHIFT);
+
+    vctl1 = (tv_mode->nbr_end << TV_NBR_END_SHIFT) |
+	(tv_mode->vi_end_f1 << TV_VI_END_F1_SHIFT) |
+	(tv_mode->vi_end_f2 << TV_VI_END_F2_SHIFT);
+
+    vctl2 = (tv_mode->vsync_len << TV_VSYNC_LEN_SHIFT) |
+	(tv_mode->vsync_start_f1 << TV_VSYNC_START_F1_SHIFT) |
+	(tv_mode->vsync_start_f2 << TV_VSYNC_START_F2_SHIFT);
+
+    vctl3 = (tv_mode->veq_len << TV_VEQ_LEN_SHIFT) |
+	(tv_mode->veq_start_f1 << TV_VEQ_START_F1_SHIFT) |
+	(tv_mode->veq_start_f2 << TV_VEQ_START_F2_SHIFT);
+
+    if (tv_mode->veq_ena)
+	vctl3 |= TV_EQUAL_ENA;
+
+    vctl4 = (tv_mode->vburst_start_f1 << TV_VBURST_START_F1_SHIFT) |
+	(tv_mode->vburst_end_f1 << TV_VBURST_END_F1_SHIFT);
+
+    vctl5 = (tv_mode->vburst_start_f2 << TV_VBURST_START_F2_SHIFT) |
+	(tv_mode->vburst_end_f2 << TV_VBURST_END_F2_SHIFT);
+
+    vctl6 = (tv_mode->vburst_start_f3 << TV_VBURST_START_F3_SHIFT) |
+	(tv_mode->vburst_end_f3 << TV_VBURST_END_F3_SHIFT);
+
+    vctl7 = (tv_mode->vburst_start_f4 << TV_VBURST_START_F4_SHIFT) |
+	(tv_mode->vburst_end_f4 << TV_VBURST_END_F4_SHIFT);
+
+    if (intel_crtc->pipe == 1)
+	tv_ctl |= TV_ENC_PIPEB_SELECT;
+    tv_ctl |= tv_mode->oversample;
+
+    if (tv_mode->progressive)
+	tv_ctl |= TV_PROGRESSIVE;
+    if (tv_mode->trilevel_sync)
+	tv_ctl |= TV_TRILEVEL_SYNC;
+    if (tv_mode->pal_burst)
+	tv_ctl |= TV_PAL_BURST;
+    scctl1 = 0;
+    if (tv_mode->dda1_inc)
+	scctl1 |= TV_SC_DDA1_EN;
+
+    if (tv_mode->dda2_inc)
+	scctl1 |= TV_SC_DDA2_EN;
+
+    if (tv_mode->dda3_inc)
+	scctl1 |= TV_SC_DDA3_EN;
+
+    scctl1 |= tv_mode->sc_reset;
+    scctl1 |= video_levels->burst << TV_BURST_LEVEL_SHIFT;
+    scctl1 |= tv_mode->dda1_inc << TV_SCDDA1_INC_SHIFT;
+
+    scctl2 = tv_mode->dda2_size << TV_SCDDA2_SIZE_SHIFT |
+	tv_mode->dda2_inc << TV_SCDDA2_INC_SHIFT;
+
+    scctl3 = tv_mode->dda3_size << TV_SCDDA3_SIZE_SHIFT |
+	tv_mode->dda3_inc << TV_SCDDA3_INC_SHIFT;
+
+    /* Enable two fixes for the chips that need them. */
+    if (pI830->PciInfo->chipType < PCI_CHIP_I945_G)
+	tv_ctl |= TV_ENC_C0_FIX | TV_ENC_SDP_FIX;
+
+    OUTREG(TV_H_CTL_1, hctl1);
+    OUTREG(TV_H_CTL_2, hctl2);
+    OUTREG(TV_H_CTL_3, hctl3);
+    OUTREG(TV_V_CTL_1, vctl1);
+    OUTREG(TV_V_CTL_2, vctl2);
+    OUTREG(TV_V_CTL_3, vctl3);
+    OUTREG(TV_V_CTL_4, vctl4);
+    OUTREG(TV_V_CTL_5, vctl5);
+    OUTREG(TV_V_CTL_6, vctl6);
+    OUTREG(TV_V_CTL_7, vctl7);
+    OUTREG(TV_SC_CTL_1, scctl1);
+    OUTREG(TV_SC_CTL_2, scctl2);
+    OUTREG(TV_SC_CTL_3, scctl3);
+
+    OUTREG(TV_CSC_Y,
+	    (i830_float_to_csc(color_conversion->ry) << 16) |
+	    (i830_float_to_csc(color_conversion->gy)));
+    OUTREG(TV_CSC_Y2,
+	    (i830_float_to_csc(color_conversion->by) << 16) |
+	    (i830_float_to_luma(color_conversion->ay)));
+
+    OUTREG(TV_CSC_U,
+	    (i830_float_to_csc(color_conversion->ru) << 16) |
+	    (i830_float_to_csc(color_conversion->gu)));
+
+    OUTREG(TV_CSC_U2,
+	    (i830_float_to_csc(color_conversion->bu) << 16) |
+	    (i830_float_to_luma(color_conversion->au)));
+
+    OUTREG(TV_CSC_V,
+	    (i830_float_to_csc(color_conversion->rv) << 16) |
+	    (i830_float_to_csc(color_conversion->gv)));
+
+    OUTREG(TV_CSC_V2,
+	    (i830_float_to_csc(color_conversion->bv) << 16) |
+	    (i830_float_to_luma(color_conversion->av)));
+
+    OUTREG(TV_CLR_KNOBS, 0x10606000);
+    OUTREG(TV_CLR_LEVEL, ((video_levels->black << TV_BLACK_LEVEL_SHIFT) |
+		(video_levels->blank << TV_BLANK_LEVEL_SHIFT)));
+    {
+	int pipeconf_reg = (intel_crtc->pipe == 0)?PIPEACONF:PIPEBCONF;
+	int dspcntr_reg = (intel_crtc->pipe == 0)?DSPACNTR : DSPBCNTR;
+	int pipeconf = INREG(pipeconf_reg);
+	int dspcntr = INREG(dspcntr_reg);
+	int dspbase_reg = (intel_crtc->pipe == 0) ? DSPABASE : DSPBBASE;
+	int xpos = 0x0, ypos = 0x0;
+	unsigned int xsize, ysize;
+	/* Pipe must be off here */
+	OUTREG(dspcntr_reg, dspcntr & ~DISPLAY_PLANE_ENABLE);
+	/* Flush the plane changes */
+	OUTREG(dspbase_reg, INREG(dspbase_reg));
+
+	if (!IS_I9XX(pI830)) {
+	    /* Wait for vblank for the disable to take effect */
+	    i830WaitForVblank(pScrn);
+	}
 
+	OUTREG(pipeconf_reg, pipeconf & ~PIPEACONF_ENABLE);
+	/* Wait for vblank for the disable to take effect. */
+	i830WaitForVblank(pScrn);
+
+	/* Filter ctl must be set before TV_WIN_SIZE */
+	OUTREG(TV_FILTER_CTL_1, TV_AUTO_SCALE); 
+	xsize = tv_mode->hblank_start - tv_mode->hblank_end;
 	if (tv_mode->progressive)
-		tv_ctl |= TV_PROGRESSIVE;
-	if (tv_mode->trilevel_sync)
-		tv_ctl |= TV_TRILEVEL_SYNC;
-	if (tv_mode->pal_burst)
-		tv_ctl |= TV_PAL_BURST;
-	if (tv_mode->oversample == TV_OVERSAMPLE_8X)
-		scctl1 = TV_SC_DDA1_EN;
-
-	if (tv_mode->dda2_inc)
-		scctl1 |= TV_SC_DDA2_EN;
-
-	if (tv_mode->dda3_inc)
-		scctl1 |= TV_SC_DDA3_EN;
-
-	scctl1 |= tv_mode->sc_reset;
-	scctl1 |= video_levels->burst << TV_BURST_LEVEL_SHIFT;
-	scctl1 |= tv_mode->dda1_inc << TV_SCDDA1_INC_SHIFT;
-
-	scctl2 = tv_mode->dda2_size << TV_SCDDA2_SIZE_SHIFT |
-		tv_mode->dda2_inc << TV_SCDDA2_INC_SHIFT;
-
-	scctl3 = tv_mode->dda3_size << TV_SCDDA3_SIZE_SHIFT |
-		tv_mode->dda3_inc << TV_SCDDA3_INC_SHIFT;
-
-	/* Enable two fixes for the chips that need them. */
-	if (pI830->PciInfo->chipType < PCI_CHIP_I945_G)
-		tv_ctl |= TV_ENC_C0_FIX | TV_ENC_SDP_FIX;
-
-
-	OUTREG(TV_H_CTL_1, hctl1);
-	OUTREG(TV_H_CTL_2, hctl2);
-	OUTREG(TV_H_CTL_3, hctl3);
-	OUTREG(TV_V_CTL_1, vctl1);
-	OUTREG(TV_V_CTL_2, vctl2);
-	OUTREG(TV_V_CTL_3, vctl3);
-	OUTREG(TV_V_CTL_4, vctl4);
-	OUTREG(TV_V_CTL_5, vctl5);
-	OUTREG(TV_V_CTL_6, vctl6);
-	OUTREG(TV_V_CTL_7, vctl7);
-	OUTREG(TV_SC_CTL_1, scctl1);
-	OUTREG(TV_SC_CTL_2, scctl2);
-	OUTREG(TV_SC_CTL_3, scctl3);
-
-	OUTREG(TV_CSC_Y,
-			(i830_float_to_csc(color_conversion->ry) << 16) |
-			(i830_float_to_csc(color_conversion->gy)));
-	OUTREG(TV_CSC_Y2,
-			(i830_float_to_csc(color_conversion->by) << 16) |
-			(i830_float_to_luma(color_conversion->ay)));
-
-	OUTREG(TV_CSC_U,
-			(i830_float_to_csc(color_conversion->ru) << 16) |
-			(i830_float_to_csc(color_conversion->gu)));
-
-	OUTREG(TV_CSC_U2,
-			(i830_float_to_csc(color_conversion->bu) << 16) |
-			(i830_float_to_luma(color_conversion->au)));
-
-	OUTREG(TV_CSC_V,
-			(i830_float_to_csc(color_conversion->rv) << 16) |
-			(i830_float_to_csc(color_conversion->gv)));
-
-	OUTREG(TV_CSC_V2,
-			(i830_float_to_csc(color_conversion->bv) << 16) |
-			(i830_float_to_luma(color_conversion->av)));
-
-	OUTREG(TV_CLR_KNOBS, 0x10606000);
-	OUTREG(TV_CLR_LEVEL, ((video_levels->black << TV_BLACK_LEVEL_SHIFT) |
-				(video_levels->blank << TV_BLANK_LEVEL_SHIFT)));
-	{
-		int pipeconf_reg = (intel_crtc->pipe == 0)?PIPEACONF:PIPEBCONF;
-		int dspcntr_reg = (intel_crtc->pipe == 0)?DSPACNTR : DSPBCNTR;
-		int pipeconf = INREG(pipeconf_reg);
-		int dspcntr = INREG(dspcntr_reg);
-		int dspbase_reg = (intel_crtc->pipe == 0) ? DSPABASE : DSPBBASE;
-		int xpos = 0x0, ypos = 0x0;
-		unsigned int xsize, ysize;
-		/* Pipe must be off here */
-		OUTREG(dspcntr_reg, dspcntr & ~DISPLAY_PLANE_ENABLE);
-		/* Flush the plane changes */
-		OUTREG(dspbase_reg, INREG(dspbase_reg));
-
-		if (!IS_I9XX(pI830)) {
-			/* Wait for vblank for the disable to take effect */
-			i830WaitForVblank(pScrn);
-		}
+	    ysize = tv_mode->nbr_end + 1;
+	else
+	    ysize = 2*tv_mode->nbr_end + 1;
 
-		OUTREG(pipeconf_reg, pipeconf & ~PIPEACONF_ENABLE);
-		/* Wait for vblank for the disable to take effect. */
-		i830WaitForVblank(pScrn);
-
-		/* Filter ctl must be set before TV_WIN_SIZE and TV_WIN_POS */
-		OUTREG(TV_FILTER_CTL_1, TV_AUTO_SCALE); 
-		xsize = tv_mode->hblank_start - tv_mode->hblank_end;
-		if (tv_mode->progressive)
-			ysize = tv_mode->nbr_end + 1;
-		else
-			ysize = 2*tv_mode->nbr_end + 1;
-
-		OUTREG(TV_WIN_POS, (xpos<<16)|ypos);
-		OUTREG(TV_WIN_SIZE, (xsize<<16)|ysize);
-
-		OUTREG(pipeconf_reg, pipeconf);
-		OUTREG(dspcntr_reg, dspcntr);
-		/* Flush the plane changes */
-		OUTREG(dspbase_reg, INREG(dspbase_reg));
-	} 	
-
-	j = 0;
-	for (i = 0; i < 60; i++)
-		OUTREG(TV_H_LUMA_0 + (i<<2), tv_mode->filter_table[j++]);
-	for (i = 0; i < 60; i++)
-		OUTREG(TV_H_CHROMA_0 + (i<<2), tv_mode->filter_table[j++]);
-	for (i = 0; i < 43; i++)
-		OUTREG(TV_V_LUMA_0 + (i<<2), tv_mode->filter_table[j++]);
-	for (i = 0; i < 43; i++)
-		OUTREG(TV_V_CHROMA_0 + (i<<2), tv_mode->filter_table[j++]);
-	OUTREG(TV_DAC, 0);
-	OUTREG(TV_CTL, tv_ctl);
+	OUTREG(TV_WIN_POS, (xpos<<16)|ypos);
+	OUTREG(TV_WIN_SIZE, (xsize<<16)|ysize);
+
+	OUTREG(pipeconf_reg, pipeconf);
+	OUTREG(dspcntr_reg, dspcntr);
+	/* Flush the plane changes */
+	OUTREG(dspbase_reg, INREG(dspbase_reg));
+    } 	
+
+    j = 0;
+    for (i = 0; i < 60; i++)
+	OUTREG(TV_H_LUMA_0 + (i<<2), tv_mode->filter_table[j++]);
+    for (i = 0; i < 60; i++)
+	OUTREG(TV_H_CHROMA_0 + (i<<2), tv_mode->filter_table[j++]);
+    for (i = 0; i < 43; i++)
+	OUTREG(TV_V_LUMA_0 + (i<<2), tv_mode->filter_table[j++]);
+    for (i = 0; i < 43; i++)
+	OUTREG(TV_V_CHROMA_0 + (i<<2), tv_mode->filter_table[j++]);
+    OUTREG(TV_DAC, 0);
+    OUTREG(TV_CTL, tv_ctl);
 }
 
 static const DisplayModeRec reported_modes[] = {
-	{
-		.name = "NTSC 480i",
-		.Clock = 107520,
-		.HDisplay   = 1280,
-		.HSyncStart = 1368,
-		.HSyncEnd   = 1496,
-		.HTotal     = 1712,
-
-		.VDisplay   = 1024,
-		.VSyncStart = 1027,
-		.VSyncEnd   = 1034,
-		.VTotal     = 1104,
-		.type       = M_T_DRIVER
-	},
+    {
+	.name = "NTSC 480i",
+	.Clock = 107520,
+	.HDisplay   = 1280,
+	.HSyncStart = 1368,
+	.HSyncEnd   = 1496,
+	.HTotal     = 1712,
+
+	.VDisplay   = 1024,
+	.VSyncStart = 1027,
+	.VSyncEnd   = 1034,
+	.VTotal     = 1104,
+	.type       = M_T_DRIVER
+    },
 };
 
 /**
@@ -1329,68 +1208,68 @@ static void
 i830_tv_detect_type (xf86CrtcPtr    crtc,
 		xf86OutputPtr  output)
 {
-	ScrnInfoPtr		    pScrn = output->scrn;
-	I830Ptr		    pI830 = I830PTR(pScrn);
-	I830OutputPrivatePtr    intel_output = output->driver_private;
-	struct i830_tv_priv	    *dev_priv = intel_output->dev_priv;
-	CARD32		    tv_ctl, save_tv_ctl;
-	CARD32		    tv_dac, save_tv_dac;
-	int			    type = TV_TYPE_UNKNOWN;
+    ScrnInfoPtr		    pScrn = output->scrn;
+    I830Ptr		    pI830 = I830PTR(pScrn);
+    I830OutputPrivatePtr    intel_output = output->driver_private;
+    struct i830_tv_priv	    *dev_priv = intel_output->dev_priv;
+    CARD32		    tv_ctl, save_tv_ctl;
+    CARD32		    tv_dac, save_tv_dac;
+    int			    type = TV_TYPE_UNKNOWN;
 
+    tv_dac = INREG(TV_DAC);
+    /*
+     * Detect TV by polling)
+     */
+    if (intel_output->load_detect_temp)
+    {
+	/* TV not currently running, prod it with destructive detect */
+	save_tv_dac = tv_dac;
+	tv_ctl = INREG(TV_CTL);
+	save_tv_ctl = tv_ctl;
+	tv_ctl &= ~TV_ENC_ENABLE;
+	tv_ctl &= ~TV_TEST_MODE_MASK;
+	tv_ctl |= TV_TEST_MODE_MONITOR_DETECT;
+	tv_dac &= ~TVDAC_SENSE_MASK;
+	tv_dac |= (TVDAC_STATE_CHG_EN |
+		TVDAC_A_SENSE_CTL |
+		TVDAC_B_SENSE_CTL |
+		TVDAC_C_SENSE_CTL |
+		DAC_CTL_OVERRIDE |
+		DAC_A_0_7_V |
+		DAC_B_0_7_V |
+		DAC_C_0_7_V);
+	OUTREG(TV_CTL, tv_ctl);
+	OUTREG(TV_DAC, tv_dac);
+	i830WaitForVblank(pScrn);
 	tv_dac = INREG(TV_DAC);
-	/*
-	 * Detect TV by polling)
-	 */
-	if (intel_output->load_detect_temp)
-	{
-		/* TV not currently running, prod it with destructive detect */
-		save_tv_dac = tv_dac;
-		tv_ctl = INREG(TV_CTL);
-		save_tv_ctl = tv_ctl;
-		tv_ctl &= ~TV_ENC_ENABLE;
-		tv_ctl &= ~TV_TEST_MODE_MASK;
-		tv_ctl |= TV_TEST_MODE_MONITOR_DETECT;
-		tv_dac &= ~TVDAC_SENSE_MASK;
-		tv_dac |= (TVDAC_STATE_CHG_EN |
-				TVDAC_A_SENSE_CTL |
-				TVDAC_B_SENSE_CTL |
-				TVDAC_C_SENSE_CTL |
-				DAC_CTL_OVERRIDE |
-				DAC_A_0_7_V |
-				DAC_B_0_7_V |
-				DAC_C_0_7_V);
-		OUTREG(TV_CTL, tv_ctl);
-		OUTREG(TV_DAC, tv_dac);
-		i830WaitForVblank(pScrn);
-		tv_dac = INREG(TV_DAC);
-		OUTREG(TV_DAC, save_tv_dac);
-		OUTREG(TV_CTL, save_tv_ctl);
-	}
-	/*
-	 *  A B C
-	 *  0 1 1 Composite
-	 *  1 0 X svideo
-	 *  0 0 0 Component
-	 */
-	if ((tv_dac & TVDAC_SENSE_MASK) == (TVDAC_B_SENSE | TVDAC_C_SENSE)) {
-		xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-				"Detected Composite TV connection\n");
-		type = TV_TYPE_COMPOSITE;
-	} else if ((tv_dac & (TVDAC_A_SENSE|TVDAC_B_SENSE)) == TVDAC_A_SENSE) {
-		xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-				"Detected S-Video TV connection\n");
-		type = TV_TYPE_SVIDEO;
-	} else if ((tv_dac & TVDAC_SENSE_MASK) == 0) {
-		xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-				"Detected Component TV connection\n");
-		type = TV_TYPE_COMPONENT;
-	} else {
-		xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-				"No TV connection detected\n");
-		type = TV_TYPE_NONE;
-	}
+	OUTREG(TV_DAC, save_tv_dac);
+	OUTREG(TV_CTL, save_tv_ctl);
+    }
+    /*
+     *  A B C
+     *  0 1 1 Composite
+     *  1 0 X svideo
+     *  0 0 0 Component
+     */
+    if ((tv_dac & TVDAC_SENSE_MASK) == (TVDAC_B_SENSE | TVDAC_C_SENSE)) {
+	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+		"Detected Composite TV connection\n");
+	type = TV_TYPE_COMPOSITE;
+    } else if ((tv_dac & (TVDAC_A_SENSE|TVDAC_B_SENSE)) == TVDAC_A_SENSE) {
+	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+		"Detected S-Video TV connection\n");
+	type = TV_TYPE_SVIDEO;
+    } else if ((tv_dac & TVDAC_SENSE_MASK) == 0) {
+	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+		"Detected Component TV connection\n");
+	type = TV_TYPE_COMPONENT;
+    } else {
+	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+		"No TV connection detected\n");
+	type = TV_TYPE_NONE;
+    }
 
-	dev_priv->type = type;
+    dev_priv->type = type;
 }
 
 /**
@@ -1415,7 +1294,6 @@ i830_tv_detect(xf86OutputPtr output)
             /* we only need the pixel clock set correctly here */
             mode = reported_modes[0];
             xf86SetModeCrtc (&mode, INTERLACE_HALVE_V);
-            xf86CrtcSetMode (crtc, &mode, RR_Rotate_0, 0, 0);
         }
         i830_tv_detect_type (crtc, output);
         i830ReleaseLoadDetectPipe (output);
@@ -1432,16 +1310,16 @@ i830_tv_detect(xf86OutputPtr output)
 }
 
 struct input_res {
-	char *name;
-	int w, h;	
-}input_res_table[] = 
+    char *name;
+    int w, h;	
+} input_res_table[] = 
 {
 	{"640x480", 640, 480},
 	{"800x600", 800, 600},
 	{"1024x768", 1024, 768},
 	{"1280x1024", 1280, 1024},
 	{"848x480", 848, 480},
-	{"1280x720", 1280, 720}
+	{"1280x720", 1280, 720},
 };
 
 /**
@@ -1454,124 +1332,127 @@ struct input_res {
 static DisplayModePtr
 i830_tv_get_modes(xf86OutputPtr output)
 {
-	DisplayModePtr  ret = NULL, mode_ptr;
-	int		    i, j;
-	I830OutputPrivatePtr    intel_output = output->driver_private;
-	struct i830_tv_priv	    *dev_priv = intel_output->dev_priv;
-
-	for (i = 0; i < sizeof(tv_modes) / sizeof (tv_modes[0]); i++) 
-	{
-		const tv_mode_t *tv_mode = &tv_modes[i];
-		unsigned int hactive = tv_mode->hblank_start - tv_mode->hblank_end;
-		unsigned int vactive = tv_mode->progressive
-			?tv_mode->nbr_end + 1: 2*(tv_mode->nbr_end + 1);
-		unsigned int htotal = tv_mode->htotal + 1;
-		unsigned int vtotal = tv_mode->progressive
-			?tv_mode->nbr_end + 1 + tv_mode->vi_end_f2:
-			2*(tv_mode->nbr_end+1) + 2*(tv_mode->vi_end_f2);
-
-		if (dev_priv->type != TV_TYPE_COMPONENT && tv_mode->component_only)
-			continue;
-
-		for (j = 0; j < sizeof(input_res_table)/sizeof(input_res_table[0]); j++)	{
-			struct input_res *input = &input_res_table[j];
-			unsigned int hactive_s = input->w;
-			unsigned int vactive_s = input->h;
-			unsigned int htotal_s = htotal*hactive_s/hactive;
-			unsigned int vtotal_s = vtotal*vactive_s/vactive;
-			if (tv_mode->max_srcw && input->w > tv_mode->max_srcw)
-				continue;
-			mode_ptr = xnfcalloc(1, sizeof(DisplayModeRec));
-			mode_ptr->name = xnfalloc(strlen(tv_mode->name) + 
-					strlen(input->name) + 4);
-			sprintf(mode_ptr->name, "%s %s", tv_mode->name, input->name);
-
-			mode_ptr->Clock = tv_mode->clock;
-
-			mode_ptr->HDisplay = hactive_s;
-			mode_ptr->HSyncStart = hactive_s + 1;
-			mode_ptr->HSyncEnd = htotal_s - 20;  
-			if ( mode_ptr->HSyncEnd <= mode_ptr->HSyncStart)
-				mode_ptr->HSyncEnd = mode_ptr->HSyncStart  + 1;
-			mode_ptr->HTotal = htotal_s;
-
-			mode_ptr->VDisplay = vactive_s;
-			mode_ptr->VSyncStart = vactive_s + 1;
-			mode_ptr->VSyncEnd = vtotal_s - 20;
-			if ( mode_ptr->VSyncEnd <= mode_ptr->VSyncStart)
-				mode_ptr->VSyncEnd = mode_ptr->VSyncStart  + 1;
-			mode_ptr->VTotal = vtotal_s;
-
-			mode_ptr->type = M_T_DRIVER;
-			mode_ptr->next = ret;
-			ret = mode_ptr;
-		} 
-	}
+    DisplayModePtr  ret = NULL, mode_ptr;
+    int		    i, j;
+    I830OutputPrivatePtr    intel_output = output->driver_private;
+    struct i830_tv_priv	    *dev_priv = intel_output->dev_priv;
+
+    for (i = 0; i < sizeof(tv_modes) / sizeof (tv_modes[0]); i++) 
+    {
+	const tv_mode_t *tv_mode = &tv_modes[i];
+	unsigned int hactive = tv_mode->hblank_start - tv_mode->hblank_end;
+	unsigned int vactive = tv_mode->progressive
+	    ?tv_mode->nbr_end + 1: 2*(tv_mode->nbr_end + 1);
+	unsigned int htotal = tv_mode->htotal + 1;
+	unsigned int vtotal = tv_mode->progressive
+	    ?tv_mode->nbr_end + 1 + tv_mode->vi_end_f2:
+	    2*(tv_mode->nbr_end+1) + 2*(tv_mode->vi_end_f2);
+
+	if (dev_priv->type != TV_TYPE_COMPONENT && tv_mode->component_only)
+	    continue;
+
+	for (j = 0; j < sizeof(input_res_table)/sizeof(input_res_table[0]); j++)	{
+	    struct input_res *input = &input_res_table[j];
+	    unsigned int hactive_s = input->w;
+	    unsigned int vactive_s = input->h;
+	    unsigned int htotal_s = htotal*hactive_s/hactive;
+	    unsigned int vtotal_s = vtotal*vactive_s/vactive;
+	    if (tv_mode->max_srcw && input->w > tv_mode->max_srcw)
+		continue;
+	    if (input->w > 1024 && (!tv_mode->progressive 
+			&& !tv_mode->component_only))
+		continue;
+	    mode_ptr = xnfcalloc(1, sizeof(DisplayModeRec));
+	    mode_ptr->name = xnfalloc(strlen(tv_mode->name) + 
+		    strlen(input->name) + 4);
+	    sprintf(mode_ptr->name, "%s %s", tv_mode->name, input->name);
+
+	    mode_ptr->Clock = tv_mode->clock;
+
+	    mode_ptr->HDisplay = hactive_s;
+	    mode_ptr->HSyncStart = hactive_s + 1;
+	    mode_ptr->HSyncEnd = htotal_s - 20;  
+	    if ( mode_ptr->HSyncEnd <= mode_ptr->HSyncStart)
+		mode_ptr->HSyncEnd = mode_ptr->HSyncStart  + 1;
+	    mode_ptr->HTotal = htotal_s;
+
+	    mode_ptr->VDisplay = vactive_s;
+	    mode_ptr->VSyncStart = vactive_s + 1;
+	    mode_ptr->VSyncEnd = vtotal_s - 20;
+	    if ( mode_ptr->VSyncEnd <= mode_ptr->VSyncStart)
+		mode_ptr->VSyncEnd = mode_ptr->VSyncStart  + 1;
+	    mode_ptr->VTotal = vtotal_s;
+
+	    mode_ptr->type = M_T_DRIVER;
+	    mode_ptr->next = ret;
+	    ret = mode_ptr;
+	} 
+    }
 
-	return ret;
+    return ret;
 }
 
 static void
 i830_tv_destroy (xf86OutputPtr output)
 {
-	if (output->driver_private)
-		xfree (output->driver_private);
+    if (output->driver_private)
+	xfree (output->driver_private);
 }
 
 static const xf86OutputFuncsRec i830_tv_output_funcs = {
-	.dpms = i830_tv_dpms,
-	.save = i830_tv_save,
-	.restore = i830_tv_restore,
-	.mode_valid = i830_tv_mode_valid,
-	.mode_fixup = i830_tv_mode_fixup,
-	.mode_set = i830_tv_mode_set,
-	.detect = i830_tv_detect,
-	.get_modes = i830_tv_get_modes,
-	.destroy = i830_tv_destroy
+    .dpms = i830_tv_dpms,
+    .save = i830_tv_save,
+    .restore = i830_tv_restore,
+    .mode_valid = i830_tv_mode_valid,
+    .mode_fixup = i830_tv_mode_fixup,
+    .mode_set = i830_tv_mode_set,
+    .detect = i830_tv_detect,
+    .get_modes = i830_tv_get_modes,
+    .destroy = i830_tv_destroy
 };
 
 void
 i830_tv_init(ScrnInfoPtr pScrn)
 {
-	I830Ptr		    pI830 = I830PTR(pScrn);
-	xf86OutputPtr	    output;
-	I830OutputPrivatePtr    intel_output;
-	struct i830_tv_priv	    *dev_priv;
-	CARD32		    tv_dac_on, tv_dac_off, save_tv_dac;
+    I830Ptr		    pI830 = I830PTR(pScrn);
+    xf86OutputPtr	    output;
+    I830OutputPrivatePtr    intel_output;
+    struct i830_tv_priv	    *dev_priv;
+    CARD32		    tv_dac_on, tv_dac_off, save_tv_dac;
 
-	if ((INREG(TV_CTL) & TV_FUSE_STATE_MASK) == TV_FUSE_STATE_DISABLED)
-		return;
+    if ((INREG(TV_CTL) & TV_FUSE_STATE_MASK) == TV_FUSE_STATE_DISABLED)
+	return;
 
-	/*
+    /*
      * Sanity check the TV output by checking to see if the
      * DAC register holds a value
      */
     save_tv_dac = INREG(TV_DAC);
-    
+
     OUTREG(TV_DAC, save_tv_dac | TVDAC_STATE_CHG_EN);
     tv_dac_on = INREG(TV_DAC);
-    
+
     OUTREG(TV_DAC, save_tv_dac & ~TVDAC_STATE_CHG_EN);
     tv_dac_off = INREG(TV_DAC);
-    
+
     OUTREG(TV_DAC, save_tv_dac);
-    
+
     /*
      * If the register does not hold the state change enable
      * bit, (either as a 0 or a 1), assume it doesn't really
      * exist
      */
     if ((tv_dac_on & TVDAC_STATE_CHG_EN) == 0 || 
-	(tv_dac_off & TVDAC_STATE_CHG_EN) != 0)
+	    (tv_dac_off & TVDAC_STATE_CHG_EN) != 0)
 	return;
-    
+
     output = xf86OutputCreate (pScrn, &i830_tv_output_funcs, "TV");
-    
+
     if (!output)
 	return;
-    
+
     intel_output = xnfcalloc (sizeof (I830OutputPrivateRec) +
-			      sizeof (struct i830_tv_priv), 1);
+	    sizeof (struct i830_tv_priv), 1);
     if (!intel_output)
     {
 	xf86OutputDestroy (output);
@@ -1581,7 +1462,7 @@ i830_tv_init(ScrnInfoPtr pScrn)
     intel_output->type = I830_OUTPUT_TVOUT;
     intel_output->dev_priv = dev_priv;
     dev_priv->type = TV_TYPE_UNKNOWN;
-    
+
     output->driver_private = intel_output;
     output->interlaceAllowed = FALSE;
     output->doubleScanAllowed = FALSE;
diff-tree 6d9757e466863594300c83f3806fd4376bea0504 (from b3633506dcd4fd58f0f9519cd67f6e75d6fb2042)
Author: Zou Nanhai <nanhai.zou at intel.com>
Date:   Mon Feb 5 14:59:53 2007 +0800

    Fix hang when TV is not connect.

diff --git a/src/i830_tv.c b/src/i830_tv.c
index 4c55b35..6131b28 100644
--- a/src/i830_tv.c
+++ b/src/i830_tv.c
@@ -943,6 +943,11 @@ i830_tv_restore(xf86OutputPtr output)
 	struct i830_tv_priv	    *dev_priv = intel_output->dev_priv;
 	int			    i;
 
+	xf86CrtcPtr	    crtc = output->crtc;
+	I830CrtcPrivatePtr  intel_crtc;
+	if (!crtc)
+		return;
+	intel_crtc = crtc->driver_private;
 	OUTREG(TV_H_CTL_1, dev_priv->save_TV_H_CTL_1);
 	OUTREG(TV_H_CTL_2, dev_priv->save_TV_H_CTL_2);
 	OUTREG(TV_H_CTL_3, dev_priv->save_TV_H_CTL_3);
@@ -967,8 +972,6 @@ i830_tv_restore(xf86OutputPtr output)
 	OUTREG(TV_CLR_LEVEL, dev_priv->save_TV_CLR_LEVEL);
 
 	{
-		xf86CrtcPtr	    crtc = output->crtc;
-		I830CrtcPrivatePtr	    intel_crtc = crtc->driver_private;
 		int pipeconf_reg = (intel_crtc->pipe == 0)?PIPEACONF:PIPEBCONF;
 		int dspcntr_reg = (intel_crtc->pipe == 0)?DSPACNTR : DSPBCNTR;
 		int pipeconf = INREG(pipeconf_reg);
diff-tree b3633506dcd4fd58f0f9519cd67f6e75d6fb2042 (from 380129a17c61c783d77a87685ad5333e8b1c253c)
Author: Wang Zhenyu <zhenyu.z.wang at intel.com>
Date:   Fri Feb 2 11:35:44 2007 +0800

    Add Intel 965GM chipset support

diff --git a/src/common.h b/src/common.h
index 91e31b5..cc68239 100644
--- a/src/common.h
+++ b/src/common.h
@@ -314,6 +314,11 @@ extern int I810_DEBUG;
 #define PCI_CHIP_I946_GZ_BRIDGE 	0x2970
 #endif
 
+#ifndef PCI_CHIP_I965_GM
+#define PCI_CHIP_I965_GM        0x2A02
+#define PCI_CHIP_I965_GM_BRIDGE 0x2A00
+#endif
+
 #define IS_I810(pI810) (pI810->PciInfo->chipType == PCI_CHIP_I810 ||	\
 			pI810->PciInfo->chipType == PCI_CHIP_I810_DC100 || \
 			pI810->PciInfo->chipType == PCI_CHIP_I810_E)
@@ -329,10 +334,11 @@ extern int I810_DEBUG;
 #define IS_I915GM(pI810) (pI810->PciInfo->chipType == PCI_CHIP_I915_GM)
 #define IS_I945G(pI810) (pI810->PciInfo->chipType == PCI_CHIP_I945_G)
 #define IS_I945GM(pI810) (pI810->PciInfo->chipType == PCI_CHIP_I945_GM)
-#define IS_I965G(pI810) (pI810->PciInfo->chipType == PCI_CHIP_I965_G || pI810->PciInfo->chipType == PCI_CHIP_I965_G_1 || pI810->PciInfo->chipType == PCI_CHIP_I965_Q || pI810->PciInfo->chipType == PCI_CHIP_I946_GZ)
+#define IS_I965GM(pI810) (pI810->PciInfo->chipType == PCI_CHIP_I965_GM)
+#define IS_I965G(pI810) (pI810->PciInfo->chipType == PCI_CHIP_I965_G || pI810->PciInfo->chipType == PCI_CHIP_I965_G_1 || pI810->PciInfo->chipType == PCI_CHIP_I965_Q || pI810->PciInfo->chipType == PCI_CHIP_I946_GZ || pI810->PciInfo->chipType == PCI_CHIP_I965_GM)
 #define IS_I9XX(pI810) (IS_I915G(pI810) || IS_I915GM(pI810) || IS_I945G(pI810) || IS_I945GM(pI810) || IS_I965G(pI810))
 
-#define IS_MOBILE(pI810) (IS_I830(pI810) || IS_I85X(pI810) || IS_I915GM(pI810) || IS_I945GM(pI810))
+#define IS_MOBILE(pI810) (IS_I830(pI810) || IS_I85X(pI810) || IS_I915GM(pI810) || IS_I945GM(pI810) || IS_I965GM(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 e7c8507..ab3a200 100644
--- a/src/i810_driver.c
+++ b/src/i810_driver.c
@@ -144,6 +144,7 @@ static SymTabRec I810Chipsets[] = {
    {PCI_CHIP_I965_G_1,		"965G"},
    {PCI_CHIP_I965_Q,		"965Q"},
    {PCI_CHIP_I946_GZ,		"946GZ"},
+   {PCI_CHIP_I965_GM,		"965GM"},
    {-1,				NULL}
 };
 
@@ -167,6 +168,7 @@ static PciChipsets I810PciChipsets[] = {
    {PCI_CHIP_I965_G_1,		PCI_CHIP_I965_G_1,	RES_SHARED_VGA},
    {PCI_CHIP_I965_Q,		PCI_CHIP_I965_Q,	RES_SHARED_VGA},
    {PCI_CHIP_I946_GZ,		PCI_CHIP_I946_GZ,	RES_SHARED_VGA},
+   {PCI_CHIP_I965_GM,		PCI_CHIP_I965_GM,	RES_SHARED_VGA},
    {-1,				-1, RES_UNDEFINED }
 };
 
@@ -601,6 +603,7 @@ I810Probe(DriverPtr drv, int flags)
 	    case PCI_CHIP_I965_G_1:
 	    case PCI_CHIP_I965_Q:
 	    case PCI_CHIP_I946_GZ:
+	    case PCI_CHIP_I965_GM:
     	       xf86SetEntitySharable(usedChips[i]);
 
     	       /* Allocate an entity private if necessary */		
diff --git a/src/i830_driver.c b/src/i830_driver.c
index 0f66311..701abd7 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -232,6 +232,7 @@ static SymTabRec I830Chipsets[] = {
    {PCI_CHIP_I965_G_1,		"965G"},
    {PCI_CHIP_I965_Q,		"965Q"},
    {PCI_CHIP_I946_GZ,		"946GZ"},
+   {PCI_CHIP_I965_GM,		"965GM"},
    {-1,				NULL}
 };
 
@@ -249,6 +250,7 @@ static PciChipsets I830PciChipsets[] = {
    {PCI_CHIP_I965_G_1,		PCI_CHIP_I965_G_1,	RES_SHARED_VGA},
    {PCI_CHIP_I965_Q,		PCI_CHIP_I965_Q,	RES_SHARED_VGA},
    {PCI_CHIP_I946_GZ,		PCI_CHIP_I946_GZ,	RES_SHARED_VGA},
+   {PCI_CHIP_I965_GM,		PCI_CHIP_I965_GM,	RES_SHARED_VGA},
    {-1,				-1,			RES_UNDEFINED}
 };
 
@@ -1045,6 +1047,9 @@ I830PreInit(ScrnInfoPtr pScrn, int flags
    case PCI_CHIP_I946_GZ:
       chipname = "946GZ";
       break;
+   case PCI_CHIP_I965_GM:
+      chipname = "965GM";
+      break;
    default:
       chipname = "unknown chipset";
       break;
diff-tree 380129a17c61c783d77a87685ad5333e8b1c253c (from f7489bbec150349bf03bea8d9d55451dbc92bfc2)
Author: Wang Zhenyu <zhenyu.z.wang at intel.com>
Date:   Fri Feb 2 11:33:46 2007 +0800

    Revert original crestline pci id patch

diff --git a/src/common.h b/src/common.h
index 92dc2cf..91e31b5 100644
--- a/src/common.h
+++ b/src/common.h
@@ -314,11 +314,6 @@ extern int I810_DEBUG;
 #define PCI_CHIP_I946_GZ_BRIDGE 	0x2970
 #endif
 
-#ifndef PCI_CHIP_CRESTLINE		//XXX: fix with official name
-#define PCI_CHIP_CRESTLINE		0x2A02
-#define PCI_CHIP_CRESTLINE_BRIDGE 	0x2A00
-#endif
-
 #define IS_I810(pI810) (pI810->PciInfo->chipType == PCI_CHIP_I810 ||	\
 			pI810->PciInfo->chipType == PCI_CHIP_I810_DC100 || \
 			pI810->PciInfo->chipType == PCI_CHIP_I810_E)
@@ -334,11 +329,10 @@ extern int I810_DEBUG;
 #define IS_I915GM(pI810) (pI810->PciInfo->chipType == PCI_CHIP_I915_GM)
 #define IS_I945G(pI810) (pI810->PciInfo->chipType == PCI_CHIP_I945_G)
 #define IS_I945GM(pI810) (pI810->PciInfo->chipType == PCI_CHIP_I945_GM)
-#define IS_I965G(pI810) (pI810->PciInfo->chipType == PCI_CHIP_I965_G || pI810->PciInfo->chipType == PCI_CHIP_I965_G_1 || pI810->PciInfo->chipType == PCI_CHIP_I965_Q || pI810->PciInfo->chipType == PCI_CHIP_I946_GZ || pI810->PciInfo->chipType == PCI_CHIP_CRESTLINE)
+#define IS_I965G(pI810) (pI810->PciInfo->chipType == PCI_CHIP_I965_G || pI810->PciInfo->chipType == PCI_CHIP_I965_G_1 || pI810->PciInfo->chipType == PCI_CHIP_I965_Q || pI810->PciInfo->chipType == PCI_CHIP_I946_GZ)
 #define IS_I9XX(pI810) (IS_I915G(pI810) || IS_I915GM(pI810) || IS_I945G(pI810) || IS_I945GM(pI810) || IS_I965G(pI810))
-#define IS_CRESTLINE(pI810) (pI810->PciInfo->chipType == PCI_CHIP_CRESTLINE) // XXX: IS_965GM ?
 
-#define IS_MOBILE(pI810) (IS_I830(pI810) || IS_I85X(pI810) || IS_I915GM(pI810) || IS_I945GM(pI810) || IS_CRESTLINE(pI810))
+#define IS_MOBILE(pI810) (IS_I830(pI810) || IS_I85X(pI810) || IS_I915GM(pI810) || IS_I945GM(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 74100cd..e7c8507 100644
--- a/src/i810_driver.c
+++ b/src/i810_driver.c
@@ -144,7 +144,6 @@ static SymTabRec I810Chipsets[] = {
    {PCI_CHIP_I965_G_1,		"965G"},
    {PCI_CHIP_I965_Q,		"965Q"},
    {PCI_CHIP_I946_GZ,		"946GZ"},
-   {PCI_CHIP_CRESTLINE,		"Crestline"},
    {-1,				NULL}
 };
 
@@ -168,7 +167,6 @@ static PciChipsets I810PciChipsets[] = {
    {PCI_CHIP_I965_G_1,		PCI_CHIP_I965_G_1,	RES_SHARED_VGA},
    {PCI_CHIP_I965_Q,		PCI_CHIP_I965_Q,	RES_SHARED_VGA},
    {PCI_CHIP_I946_GZ,		PCI_CHIP_I946_GZ,	RES_SHARED_VGA},
-   {PCI_CHIP_CRESTLINE,		PCI_CHIP_CRESTLINE,	RES_SHARED_VGA},
    {-1,				-1, RES_UNDEFINED }
 };
 
@@ -603,7 +601,6 @@ I810Probe(DriverPtr drv, int flags)
 	    case PCI_CHIP_I965_G_1:
 	    case PCI_CHIP_I965_Q:
 	    case PCI_CHIP_I946_GZ:
-	    case PCI_CHIP_CRESTLINE:
     	       xf86SetEntitySharable(usedChips[i]);
 
     	       /* Allocate an entity private if necessary */		
diff --git a/src/i830_driver.c b/src/i830_driver.c
index 12b72ac..0f66311 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -232,7 +232,6 @@ static SymTabRec I830Chipsets[] = {
    {PCI_CHIP_I965_G_1,		"965G"},
    {PCI_CHIP_I965_Q,		"965Q"},
    {PCI_CHIP_I946_GZ,		"946GZ"},
-   {PCI_CHIP_CRESTLINE,		"Crestline"},
    {-1,				NULL}
 };
 
@@ -250,7 +249,6 @@ static PciChipsets I830PciChipsets[] = {
    {PCI_CHIP_I965_G_1,		PCI_CHIP_I965_G_1,	RES_SHARED_VGA},
    {PCI_CHIP_I965_Q,		PCI_CHIP_I965_Q,	RES_SHARED_VGA},
    {PCI_CHIP_I946_GZ,		PCI_CHIP_I946_GZ,	RES_SHARED_VGA},
-   {PCI_CHIP_CRESTLINE,		PCI_CHIP_CRESTLINE,	RES_SHARED_VGA},
    {-1,				-1,			RES_UNDEFINED}
 };
 
@@ -1047,9 +1045,6 @@ I830PreInit(ScrnInfoPtr pScrn, int flags
    case PCI_CHIP_I946_GZ:
       chipname = "946GZ";
       break;
-   case PCI_CHIP_CRESTLINE:
-      chipname = "Crestline";
-      break;
    default:
       chipname = "unknown chipset";
       break;
diff-tree f7489bbec150349bf03bea8d9d55451dbc92bfc2 (from parents)
Merge: f1285ecb72e807ac10db398fa983bf69d4154d97 ae6d3585a4d96aa4dc05ca8563cebfa7796324ef
Author: Wang Zhenyu <zhenyu.z.wang at intel.com>
Date:   Fri Feb 2 11:26:57 2007 +0800

    Merge branch 'modesetting' into crestline
    
    Conflicts:
    
    	src/i830_display.c
    	src/i830_tv.c
    	src/i830_xf86Crtc.c

diff --cc src/i830_tv.c
index 48167f6,79b6ae8..4c55b35
@@@ -1399,48 -1052,35 +1399,48 @@@
  static xf86OutputStatus
  i830_tv_detect(xf86OutputPtr output)
  {
- 	xf86CrtcPtr		    crtc;
- 	DisplayModeRec	    mode;
- 	I830OutputPrivatePtr    intel_output = output->driver_private;
- 	struct i830_tv_priv	    *dev_priv = intel_output->dev_priv;
+     xf86CrtcPtr		    crtc;
+     DisplayModeRec	    mode;
+     I830OutputPrivatePtr    intel_output = output->driver_private;
+     struct i830_tv_priv	    *dev_priv = intel_output->dev_priv;
  
- 	crtc = i830GetLoadDetectPipe (output);
- 	if (crtc)
- 	{
- 		if (intel_output->load_detect_temp)
- 		{
- 			/* we only need the pixel clock set correctly here */
- 			mode = reported_modes[0];
- 			xf86SetModeCrtc (&mode, INTERLACE_HALVE_V);
- 			i830PipeSetMode (crtc, &mode, FALSE);
- 		}
- 		i830_tv_detect_type (crtc, output);
- 		i830ReleaseLoadDetectPipe (output);
- 	}
+     crtc = i830GetLoadDetectPipe (output);
+     if (crtc)
+     {
 -	if (intel_output->load_detect_temp)
 -	{
 -	    /* we only need the pixel clock set correctly here */
 -	    mode = reported_modes[0];
 -	    xf86SetModeCrtc (&mode, INTERLACE_HALVE_V);
 -	    xf86CrtcSetMode (crtc, &mode, RR_Rotate_0, 0, 0);
 -	}
 -	i830_tv_detect_type (crtc, output);
 -	i830ReleaseLoadDetectPipe (output);
++        if (intel_output->load_detect_temp)
++        {
++            /* we only need the pixel clock set correctly here */
++            mode = reported_modes[0];
++            xf86SetModeCrtc (&mode, INTERLACE_HALVE_V);
++            xf86CrtcSetMode (crtc, &mode, RR_Rotate_0, 0, 0);
++        }
++        i830_tv_detect_type (crtc, output);
++        i830ReleaseLoadDetectPipe (output);
+     }
 -    
 +
- 	switch (dev_priv->type) {
- 		case TV_TYPE_NONE:
- 			return XF86OutputStatusDisconnected;
- 		case TV_TYPE_UNKNOWN:
- 			return XF86OutputStatusUnknown;
- 		default:
- 			return XF86OutputStatusConnected;
- 	}
+     switch (dev_priv->type) {
+     case TV_TYPE_NONE:
 -	return XF86OutputStatusDisconnected;
++        return XF86OutputStatusDisconnected;
+     case TV_TYPE_UNKNOWN:
 -	return XF86OutputStatusUnknown;
++        return XF86OutputStatusUnknown;
+     default:
 -	return XF86OutputStatusConnected;
++        return XF86OutputStatusConnected;
+     }
  }
  
 +struct input_res {
 +	char *name;
 +	int w, h;	
 +}input_res_table[] = 
 +{
 +	{"640x480", 640, 480},
 +	{"800x600", 800, 600},
 +	{"1024x768", 1024, 768},
 +	{"1280x1024", 1280, 1024},
 +	{"848x480", 848, 480},
 +	{"1280x720", 1280, 720}
 +};
 +
  /**
   * Stub get_modes function.
   *
diff-tree ae6d3585a4d96aa4dc05ca8563cebfa7796324ef (from parents)
Merge: 6d549ed280d3fcf3fe611b095d9f8adc0196bfb6 1ba45a3fcd40aaf4d373447fb9f252ca053f9105
Author: Wang Zhenyu <zhenyu.z.wang at intel.com>
Date:   Fri Feb 2 11:21:59 2007 +0800

    Merge branch 'modesetting' of git://proxy.ims.intel.com:9419/git/xorg/driver/xf86-video-intel into modesetting

diff-tree f1285ecb72e807ac10db398fa983bf69d4154d97 (from 0620a7650f758652d05a0c25d159587f641aaf3e)
Author: Zou Nan hai <nanhai.zou at intel.com>
Date:   Wed Jan 31 14:58:08 2007 +0800

      tune

diff --git a/src/i830_tv.c b/src/i830_tv.c
index ccffe5b..48167f6 100644
--- a/src/i830_tv.c
+++ b/src/i830_tv.c
@@ -148,51 +148,6 @@ static const CARD32 filter_table_hres[] 
     0x28003100, 0x28002F00, 0x00003100,
 };
 
-static const CARD32 filter_table_pal[] = {
-	0xB0603000, 0x1920B3E0, 0xB3E01900, 0x3000B060, 0xB380B080,
-	0x18A01980, 0xB040B440, 0xB0A03000, 0x19D0B300, 0xB4801840,
-	0x3000B020, 0xB260B0E0, 0x2FE01A10, 0x3000B4C0, 0xB1003000,
-	0x1A60B1C0, 0xB4E02F00, 0x30003020, 0xB120B140, 0x2E401AB0,
-	0x3020B500, 0xB1803000, 0x1B00B060, 0xB5202D60, 0x30003040,
-	0x3080B1A0, 0x2CA01B30, 0x3040B520, 0xB1E03020, 0x1B703160,
-	0xB5202BC0, 0x30203040, 0x3260B220, 0x2B001B98, 0x3060B520,
-	0xB2603020, 0x1BD03360, 0xB5002A20, 0x30203060, 0x3480B2A0,
-	0x29601BF0, 0x3060B4E0, 0xB2E03020, 0x1C1835C0, 0xB4C02880,
-	0x30403060, 0x3700B340, 0x3F801C30, 0x3060B4A0, 0xB3803040,
-	0x1C403840, 0xB4603E00, 0x30403060, 0x39A0B3C0, 0x3C801C50,
-	0x3040B420, 0xB4003040, 0x1C603B00, 0xB4003B00, 0x00003040,
-	0x36E03640, 0x3CA03960, 0x39603CA0, 0x364036E0, 0x398036E0,
-	0x3C803CC0, 0x36E03940, 0x37003640, 0x3CC039A0, 0x39203C80,
-	0x364036C0, 0x39C03700, 0x3C603CC0, 0x36C03920, 0x37203640,
-	0x3CC039E0, 0x39003C40, 0x364036C0, 0x3A003720, 0x3C403CE0,
-	0x36A038E0, 0x37203640, 0x3D203A00, 0x38C03C20, 0x364036A0,
-	0x3A203740, 0x3C003D20, 0x36A038A0, 0x37403640, 0x3D003A40,
-	0x38A03C00, 0x364036A0, 0x3A603760, 0x3BE03D20, 0x36803880,
-	0x37603660, 0x3D203A80, 0x38603BC0, 0x36603680, 0x3AA03780,
-	0x3BA03D20, 0x36803840, 0x37803660, 0x3D003AC0, 0x38403BA0,
-	0x36603680, 0x3AE037A0, 0x3B803D00, 0x36803820, 0x37C03660,
-	0x3D203B00, 0x38003B60, 0x36603660, 0x3B0037C0, 0x3B403D40,
-	0x36603800, 0x37E03660, 0x3D403B20, 0x37E03B20, 0x00003660,
-	0x38C030C0, 0x2B802B60, 0x30C038C0, 0x2BA03940, 0x38402B40,
-	0x39C030C0, 0x2B402BA0, 0x30C037C0, 0x2BC03A40, 0x37802B00,
-	0x3AC03100, 0x2AC02BE0, 0x31003700, 0x2BE03B40, 0x36802AC0,
-	0x3BC03100, 0x2A802C20, 0x31403600, 0x2C203C40, 0x35C02A40,
-	0x3CC03140, 0x2A402C20, 0x31803540, 0x2C203D40, 0x35002A00,
-	0x3DC03180, 0x29C02C60, 0x31C03480, 0x2C603E40, 0x34402980,
-	0x3F003200, 0x29402C40, 0x32003400, 0x2C803F80, 0x33802900,
-	0x3FC03240, 0x29002C60, 0x32803340, 0x2C402840, 0x330028C0,
-	0x288032C0, 0x28802C40, 0x000032C0, 0x38C030C0, 0x2B802B60,
-	0x30C038C0, 0x2BA03940, 0x38402B40, 0x39C030C0, 0x2B402BA0,
-	0x30C037C0, 0x2BC03A40, 0x37802B00, 0x3AC03100, 0x2AC02BE0,
-	0x31003700, 0x2BE03B40, 0x36802AC0, 0x3BC03100, 0x2A802C20,
-	0x31403600, 0x2C203C40, 0x35C02A40, 0x3CC03140, 0x2A402C20,
-	0x31803540, 0x2C203D40, 0x35002A00, 0x3DC03180, 0x29C02C60,
-	0x31C03480, 0x2C603E40, 0x34402980, 0x3F003200, 0x29402C40,
-	0x32003400, 0x2C803F80, 0x33802900, 0x3FC03240, 0x29002C60,
-	0x32803340, 0x2C402840, 0x330028C0, 0x288032C0, 0x28802C40,
-	0x000032C0,
-};
-
 static const CARD32 filter_table_ntsc[] = {
 	0xB0603000, 0x1920B3E0, 0xB3E01900, 0x3000B060, 0xB380B080,
 	0x18A01980, 0xB040B440, 0xB0A03000, 0x19D0B300, 0xB4801840,
@@ -499,7 +454,7 @@ const static tv_mode_t tv_modes[] = {
 		    .ru =-0.0885, .gu =-0.1738, .bu = 0.2624, .au = 1.0000,
 		    .rv = 0.3693, .gv =-0.3092, .bv =-0.0601, .av = 1.0000,
 	    },
-	    .filter_table = filter_table_pal,
+	    .filter_table = filter_table_ntsc,
     },
     {
 	    /* 625 Lines, 50 Fields, 15.625KHz line, Sub-Carrier 4.434MHz */
@@ -550,7 +505,7 @@ const static tv_mode_t tv_modes[] = {
 		    .ru =-0.0885, .gu =-0.1738, .bu = 0.2624, .au = 1.0000,
 		    .rv = 0.3693, .gv =-0.3092, .bv =-0.0601, .av = 1.0000,
 	    },
-	    .filter_table = filter_table_pal,
+	    .filter_table = filter_table_ntsc,
     },
     {
 	    /* 625 Lines, 50 Fields, 15.625KHz line, Sub-Carrier 4.434MHz */
@@ -601,7 +556,7 @@ const static tv_mode_t tv_modes[] = {
 		    .ru =-0.0937, .gu =-0.1840, .bu = 0.2777, .au = 1.0000,
 		    .rv = 0.3908, .gv =-0.3273, .bv =-0.0636, .av = 1.0000,
 	    },
-	    .filter_table = filter_table_pal,
+	    .filter_table = filter_table_ntsc,
     },
     {
 	    .name       = "480p at 59.94Hz",
diff-tree 0620a7650f758652d05a0c25d159587f641aaf3e (from 12441e217a1968dea3a6b0646b6c5d0e2ede0e7e)
Author: Zou Nan hai <nanhai.zou at intel.com>
Date:   Wed Jan 31 11:21:11 2007 +0800

      fix

diff --git a/src/i830_tv.c b/src/i830_tv.c
index 56b5450..ccffe5b 100644
--- a/src/i830_tv.c
+++ b/src/i830_tv.c
@@ -800,7 +800,6 @@ const static tv_mode_t tv_modes[] = {
 	    .filter_table = filter_table_hres,
 	    .max_srcw = 800
     },
-/*
     {
 	    .name       = "1080i at 50Hz",
 	    .clock		= 148800,	
@@ -894,7 +893,6 @@ const static tv_mode_t tv_modes[] = {
 	    },
 	    .filter_table = filter_table_hres,
     },
-*/
 };
 
 static const video_levels_t component_level = {
diff-tree 12441e217a1968dea3a6b0646b6c5d0e2ede0e7e (from 726c7dd89627409820ee5cf9bf657d5a926b3648)
Author: Zou Nan hai <nanhai.zou at intel.com>
Date:   Wed Jan 31 11:20:23 2007 +0800

      add 720p at 50Hz,
      however 720p in this freq seems to not support src width,
      hactive > 800, so skip those inputs.

diff --git a/src/i830_tv.c b/src/i830_tv.c
index 1452c5c..56b5450 100644
--- a/src/i830_tv.c
+++ b/src/i830_tv.c
@@ -266,6 +266,7 @@ typedef struct {
     video_levels_t	composite_levels, svideo_levels;
     color_conversion_t	composite_color, svideo_color;
     const CARD32 *filter_table;
+    int max_srcw;
 } tv_mode_t;
 
 
@@ -769,6 +770,38 @@ const static tv_mode_t tv_modes[] = {
 	    .filter_table = filter_table_hres,
     },
     {
+	    .name       = "720p at 50Hz",
+	    .clock		= 148800,	
+	    .oversample     = TV_OVERSAMPLE_2X,
+	    .component_only = 1,
+
+	    .hsync_end      = 80,               .hblank_end         = 300,
+	    .hblank_start   = 1580,             .htotal             = 1979,
+
+	    .progressive    = TRUE, 	        .trilevel_sync = TRUE,
+
+	    .vsync_start_f1 = 10,               .vsync_start_f2     = 10,
+	    .vsync_len      = 10,
+
+	    .veq_ena        = FALSE,
+
+	    .vi_end_f1      = 29,               .vi_end_f2          = 29,
+	    .nbr_end        = 719,
+
+	    .burst_ena      = FALSE,
+
+	    .pal_burst  = TRUE,
+	    .composite_levels = { .blank = 237, .black = 237, .burst = 118 },
+	    .composite_color = {
+		    .ry = 0.2990, .gy = 0.5870, .by = 0.1140, .ay = 0.5379,
+		    .ru =-0.0793, .gu =-0.1557, .bu = 0.2350, .au = 1.0000,
+		    .rv = 0.3307, .gv =-0.2769, .bv =-0.0538, .av = 1.0000,
+	    },
+	    .filter_table = filter_table_hres,
+	    .max_srcw = 800
+    },
+/*
+    {
 	    .name       = "1080i at 50Hz",
 	    .clock		= 148800,	
 	    .oversample     = TV_OVERSAMPLE_2X,
@@ -800,7 +833,7 @@ const static tv_mode_t tv_modes[] = {
 	    .filter_table = filter_table_hres,
     },
     {
-	    .name       = "1080i at 30Hz",
+	    .name       = "1080i at 60Hz",
 	    .clock		= 148800,	
 	    .oversample     = TV_OVERSAMPLE_2X,
 	    .component_only = 1,
@@ -831,7 +864,7 @@ const static tv_mode_t tv_modes[] = {
 	    .filter_table = filter_table_hres,
     },
     {
-	    .name       = "1080i at 29.97Hz",
+	    .name       = "1080i at 59.94Hz",
 	    .clock		= 148800,	
 	    .oversample     = TV_OVERSAMPLE_2X,
 	    .component_only = 1,
@@ -861,6 +894,7 @@ const static tv_mode_t tv_modes[] = {
 	    },
 	    .filter_table = filter_table_hres,
     },
+*/
 };
 
 static const video_levels_t component_level = {
@@ -1281,8 +1315,7 @@ i830_tv_mode_set(xf86OutputPtr output, D
 		i830WaitForVblank(pScrn);
 
 		/* Filter ctl must be set before TV_WIN_SIZE and TV_WIN_POS */
-		OUTREG(TV_FILTER_CTL_1, TV_AUTO_SCALE);
-
+		OUTREG(TV_FILTER_CTL_1, TV_AUTO_SCALE); 
 		xsize = tv_mode->hblank_start - tv_mode->hblank_end;
 		if (tv_mode->progressive)
 			ysize = tv_mode->nbr_end + 1;
@@ -1490,7 +1523,8 @@ i830_tv_get_modes(xf86OutputPtr output)
 			unsigned int vactive_s = input->h;
 			unsigned int htotal_s = htotal*hactive_s/hactive;
 			unsigned int vtotal_s = vtotal*vactive_s/vactive;
-
+			if (tv_mode->max_srcw && input->w > tv_mode->max_srcw)
+				continue;
 			mode_ptr = xnfcalloc(1, sizeof(DisplayModeRec));
 			mode_ptr->name = xnfalloc(strlen(tv_mode->name) + 
 					strlen(input->name) + 4);
diff-tree 726c7dd89627409820ee5cf9bf657d5a926b3648 (from 5a67f3d3690903a181ca854d060cfa8b4c2aca26)
Author: Zou Nan hai <nanhai.zou at intel.com>
Date:   Wed Jan 31 10:34:39 2007 +0800

       TV fixes.

diff --git a/src/i830_tv.c b/src/i830_tv.c
index 1b75e87..1452c5c 100644
--- a/src/i830_tv.c
+++ b/src/i830_tv.c
@@ -93,12 +93,157 @@ typedef struct {
     float   rv, gv, bv, av;
 } color_conversion_t;
 
+static const CARD32 filter_table_hres[] = {
+    0xB1403000, 0x2E203500, 0x35002E20, 0x3000B140,
+    0x35A0B160, 0x2DC02E80, 0xB1403480, 0xB1603000,
+    0x2EA03640, 0x34002D80, 0x3000B120, 0x36E0B160,
+    0x2D202EF0, 0xB1203380, 0xB1603000, 0x2F303780,
+    0x33002CC0, 0x3000B100, 0x3820B160, 0x2C802F50,
+    0xB10032A0, 0xB1603000, 0x2F9038C0, 0x32202C20,
+    0x3000B0E0, 0x3980B160, 0x2BC02FC0, 0xB0E031C0,
+    0xB1603000, 0x2FF03A20, 0x31602B60, 0xB020B0C0,
+    0x3AE0B160, 0x2B001810, 0xB0C03120, 0xB140B020,
+    0x18283BA0, 0x30C02A80, 0xB020B0A0, 0x3C60B140,
+    0x2A201838, 0xB0A03080, 0xB120B020, 0x18383D20,
+    0x304029C0, 0xB040B080, 0x3DE0B100, 0x29601848,
+    0xB0803000, 0xB100B040, 0x18483EC0, 0xB0402900,
+    0xB040B060, 0x3F80B0C0, 0x28801858, 0xB060B080,
+    0xB0A0B060, 0x18602820, 0xB0A02820, 0x0000B060,
+    0xB1403000, 0x2E203500, 0x35002E20, 0x3000B140,
+    0x35A0B160, 0x2DC02E80, 0xB1403480, 0xB1603000,
+    0x2EA03640, 0x34002D80, 0x3000B120, 0x36E0B160,
+    0x2D202EF0, 0xB1203380, 0xB1603000, 0x2F303780,
+    0x33002CC0, 0x3000B100, 0x3820B160, 0x2C802F50,
+    0xB10032A0, 0xB1603000, 0x2F9038C0, 0x32202C20,
+    0x3000B0E0, 0x3980B160, 0x2BC02FC0, 0xB0E031C0,
+    0xB1603000, 0x2FF03A20, 0x31602B60, 0xB020B0C0,
+    0x3AE0B160, 0x2B001810, 0xB0C03120, 0xB140B020,
+    0x18283BA0, 0x30C02A80, 0xB020B0A0, 0x3C60B140,
+    0x2A201838, 0xB0A03080, 0xB120B020, 0x18383D20,
+    0x304029C0, 0xB040B080, 0x3DE0B100, 0x29601848,
+    0xB0803000, 0xB100B040, 0x18483EC0, 0xB0402900,
+    0xB040B060, 0x3F80B0C0, 0x28801858, 0xB060B080,
+    0xB0A0B060, 0x18602820, 0xB0A02820, 0x0000B060,
+    0x36403000, 0x2D002CC0, 0x30003640, 0x2D0036C0,
+    0x35C02CC0, 0x37403000, 0x2C802D40, 0x30003540,
+    0x2D8037C0, 0x34C02C40, 0x38403000, 0x2BC02E00,
+    0x30003440, 0x2E2038C0, 0x34002B80, 0x39803000,
+    0x2B402E40, 0x30003380, 0x2E603A00, 0x33402B00,
+    0x3A803040, 0x2A802EA0, 0x30403300, 0x2EC03B40,
+    0x32802A40, 0x3C003040, 0x2A002EC0, 0x30803240,
+    0x2EC03C80, 0x320029C0, 0x3D403080, 0x29402F00,
+    0x308031C0, 0x2F203DC0, 0x31802900, 0x3E8030C0,
+    0x28802F40, 0x30C03140, 0x2F203F40, 0x31402840,
+    0x28003100, 0x28002F00, 0x00003100, 0x36403000, 
+    0x2D002CC0, 0x30003640, 0x2D0036C0,
+    0x35C02CC0, 0x37403000, 0x2C802D40, 0x30003540,
+    0x2D8037C0, 0x34C02C40, 0x38403000, 0x2BC02E00,
+    0x30003440, 0x2E2038C0, 0x34002B80, 0x39803000,
+    0x2B402E40, 0x30003380, 0x2E603A00, 0x33402B00,
+    0x3A803040, 0x2A802EA0, 0x30403300, 0x2EC03B40,
+    0x32802A40, 0x3C003040, 0x2A002EC0, 0x30803240,
+    0x2EC03C80, 0x320029C0, 0x3D403080, 0x29402F00,
+    0x308031C0, 0x2F203DC0, 0x31802900, 0x3E8030C0,
+    0x28802F40, 0x30C03140, 0x2F203F40, 0x31402840,
+    0x28003100, 0x28002F00, 0x00003100,
+};
+
+static const CARD32 filter_table_pal[] = {
+	0xB0603000, 0x1920B3E0, 0xB3E01900, 0x3000B060, 0xB380B080,
+	0x18A01980, 0xB040B440, 0xB0A03000, 0x19D0B300, 0xB4801840,
+	0x3000B020, 0xB260B0E0, 0x2FE01A10, 0x3000B4C0, 0xB1003000,
+	0x1A60B1C0, 0xB4E02F00, 0x30003020, 0xB120B140, 0x2E401AB0,
+	0x3020B500, 0xB1803000, 0x1B00B060, 0xB5202D60, 0x30003040,
+	0x3080B1A0, 0x2CA01B30, 0x3040B520, 0xB1E03020, 0x1B703160,
+	0xB5202BC0, 0x30203040, 0x3260B220, 0x2B001B98, 0x3060B520,
+	0xB2603020, 0x1BD03360, 0xB5002A20, 0x30203060, 0x3480B2A0,
+	0x29601BF0, 0x3060B4E0, 0xB2E03020, 0x1C1835C0, 0xB4C02880,
+	0x30403060, 0x3700B340, 0x3F801C30, 0x3060B4A0, 0xB3803040,
+	0x1C403840, 0xB4603E00, 0x30403060, 0x39A0B3C0, 0x3C801C50,
+	0x3040B420, 0xB4003040, 0x1C603B00, 0xB4003B00, 0x00003040,
+	0x36E03640, 0x3CA03960, 0x39603CA0, 0x364036E0, 0x398036E0,
+	0x3C803CC0, 0x36E03940, 0x37003640, 0x3CC039A0, 0x39203C80,
+	0x364036C0, 0x39C03700, 0x3C603CC0, 0x36C03920, 0x37203640,
+	0x3CC039E0, 0x39003C40, 0x364036C0, 0x3A003720, 0x3C403CE0,
+	0x36A038E0, 0x37203640, 0x3D203A00, 0x38C03C20, 0x364036A0,
+	0x3A203740, 0x3C003D20, 0x36A038A0, 0x37403640, 0x3D003A40,
+	0x38A03C00, 0x364036A0, 0x3A603760, 0x3BE03D20, 0x36803880,
+	0x37603660, 0x3D203A80, 0x38603BC0, 0x36603680, 0x3AA03780,
+	0x3BA03D20, 0x36803840, 0x37803660, 0x3D003AC0, 0x38403BA0,
+	0x36603680, 0x3AE037A0, 0x3B803D00, 0x36803820, 0x37C03660,
+	0x3D203B00, 0x38003B60, 0x36603660, 0x3B0037C0, 0x3B403D40,
+	0x36603800, 0x37E03660, 0x3D403B20, 0x37E03B20, 0x00003660,
+	0x38C030C0, 0x2B802B60, 0x30C038C0, 0x2BA03940, 0x38402B40,
+	0x39C030C0, 0x2B402BA0, 0x30C037C0, 0x2BC03A40, 0x37802B00,
+	0x3AC03100, 0x2AC02BE0, 0x31003700, 0x2BE03B40, 0x36802AC0,
+	0x3BC03100, 0x2A802C20, 0x31403600, 0x2C203C40, 0x35C02A40,
+	0x3CC03140, 0x2A402C20, 0x31803540, 0x2C203D40, 0x35002A00,
+	0x3DC03180, 0x29C02C60, 0x31C03480, 0x2C603E40, 0x34402980,
+	0x3F003200, 0x29402C40, 0x32003400, 0x2C803F80, 0x33802900,
+	0x3FC03240, 0x29002C60, 0x32803340, 0x2C402840, 0x330028C0,
+	0x288032C0, 0x28802C40, 0x000032C0, 0x38C030C0, 0x2B802B60,
+	0x30C038C0, 0x2BA03940, 0x38402B40, 0x39C030C0, 0x2B402BA0,
+	0x30C037C0, 0x2BC03A40, 0x37802B00, 0x3AC03100, 0x2AC02BE0,
+	0x31003700, 0x2BE03B40, 0x36802AC0, 0x3BC03100, 0x2A802C20,
+	0x31403600, 0x2C203C40, 0x35C02A40, 0x3CC03140, 0x2A402C20,
+	0x31803540, 0x2C203D40, 0x35002A00, 0x3DC03180, 0x29C02C60,
+	0x31C03480, 0x2C603E40, 0x34402980, 0x3F003200, 0x29402C40,
+	0x32003400, 0x2C803F80, 0x33802900, 0x3FC03240, 0x29002C60,
+	0x32803340, 0x2C402840, 0x330028C0, 0x288032C0, 0x28802C40,
+	0x000032C0,
+};
+
+static const CARD32 filter_table_ntsc[] = {
+	0xB0603000, 0x1920B3E0, 0xB3E01900, 0x3000B060, 0xB380B080,
+	0x18A01980, 0xB040B440, 0xB0A03000, 0x19D0B300, 0xB4801840,
+	0x3000B020, 0xB260B0E0, 0x2FE01A10, 0x3000B4C0, 0xB1003000,
+	0x1A60B1C0, 0xB4E02F00, 0x30003020, 0xB120B140, 0x2E401AB0,
+	0x3020B500, 0xB1803000, 0x1B00B060, 0xB5202D60, 0x30003040,
+	0x3080B1A0, 0x2CA01B30, 0x3040B520, 0xB1E03020, 0x1B703160,
+	0xB5202BC0, 0x30203040, 0x3260B220, 0x2B001B98, 0x3060B520,
+	0xB2603020, 0x1BD03360, 0xB5002A20, 0x30203060, 0x3480B2A0,
+	0x29601BF0, 0x3060B4E0, 0xB2E03020, 0x1C1835C0, 0xB4C02880,
+	0x30403060, 0x3700B340, 0x3F801C30, 0x3060B4A0, 0xB3803040,
+	0x1C403840, 0xB4603E00, 0x30403060, 0x39A0B3C0, 0x3C801C50,
+	0x3040B420, 0xB4003040, 0x1C603B00, 0xB4003B00, 0x00003040,
+	0x38A03000, 0x3C803AE0, 0x3AE03C80, 0x300038A0, 0x3B0038E0,
+	0x3C803C80, 0x38403AE0, 0x39203000, 0x3C803B00, 0x3AE03C80,
+	0x30203800, 0x3B003960, 0x3C803C80, 0x37A03AE0, 0x39803040,
+	0x3C603B20, 0x3AE03C80, 0x30403760, 0x3B2039C0, 0x3C803C80,
+	0x37003AE0, 0x39E03080, 0x3C603B40, 0x3AE03C80, 0x30A036A0,
+	0x3B603A20, 0x3C803C40, 0x36403AE0, 0x3A4030C0, 0x3C403B60,
+	0x3AE03C80, 0x31003600, 0x3B803A60, 0x3C603C40, 0x35A03AE0,
+	0x3A803140, 0x3C403B80, 0x3AE03C60, 0x31803540, 0x3BA03A80,
+	0x3C603C40, 0x34E03AE0, 0x3AA031C0, 0x3C403BC0, 0x3AE03C40,
+	0x32003480, 0x3BC03AC0, 0x3C403C40, 0x34203AE0, 0x3AC03260,
+	0x3C403BE0, 0x3AE03C20, 0x32A033C0, 0x3C003AC0, 0x3C203C40,
+	0x33603AE0, 0x3AE03300, 0x3C403C00, 0x3AE03C00, 0x00003300,
+	0x38C030C0, 0x2B802B60, 0x30C038C0, 0x2BA03940, 0x38402B40,
+	0x39C030C0, 0x2B402BA0, 0x30C037C0, 0x2BC03A40, 0x37802B00,
+	0x3AC03100, 0x2AC02BE0, 0x31003700, 0x2BE03B40, 0x36802AC0,
+	0x3BC03100, 0x2A802C20, 0x31403600, 0x2C203C40, 0x35C02A40,
+	0x3CC03140, 0x2A402C20, 0x31803540, 0x2C203D40, 0x35002A00,
+	0x3DC03180, 0x29C02C60, 0x31C03480, 0x2C603E40, 0x34402980,
+	0x3F003200, 0x29402C40, 0x32003400, 0x2C803F80, 0x33802900,
+	0x3FC03240, 0x29002C60, 0x32803340, 0x2C402840, 0x330028C0,
+	0x288032C0, 0x28802C40, 0x000032C0, 0x38C030C0, 0x2B802B60,
+	0x30C038C0, 0x2BA03940, 0x38402B40, 0x39C030C0, 0x2B402BA0,
+	0x30C037C0, 0x2BC03A40, 0x37802B00, 0x3AC03100, 0x2AC02BE0,
+	0x31003700, 0x2BE03B40, 0x36802AC0, 0x3BC03100, 0x2A802C20,
+	0x31403600, 0x2C203C40, 0x35C02A40, 0x3CC03140, 0x2A402C20,
+	0x31803540, 0x2C203D40, 0x35002A00, 0x3DC03180, 0x29C02C60,
+	0x31C03480, 0x2C603E40, 0x34402980, 0x3F003200, 0x29402C40,
+	0x32003400, 0x2C803F80, 0x33802900, 0x3FC03240, 0x29002C60,
+	0x32803340, 0x2C402840, 0x330028C0, 0x288032C0, 0x28802C40,
+	0x000032C0,
+};
+
 typedef struct {
     char *name;
     int	clock;
     CARD32 oversample;
     int hsync_end, hblank_start, hblank_end, htotal;
-    Bool progressive, trilevel_sync;
+    Bool progressive, trilevel_sync, component_only;
     int vsync_start_f1, vsync_start_f2, vsync_len;
     Bool veq_ena;
     int veq_start_f1, veq_start_f2, veq_len;
@@ -120,9 +265,9 @@ typedef struct {
      */
     video_levels_t	composite_levels, svideo_levels;
     color_conversion_t	composite_color, svideo_color;
+    const CARD32 *filter_table;
 } tv_mode_t;
 
-#define TV_PLL_CLOCK	107520
 
 /*
  * Sub carrier DDA
@@ -157,9 +302,10 @@ typedef struct {
 
 const static tv_mode_t tv_modes[] = {
     {
-	.name		= "NTSC 480i",
+	.name		= "NTSC-M",
 	.clock		= 107520,	
 	.oversample	= TV_OVERSAMPLE_8X,
+	.component_only = 0,
 	/* 525 Lines, 60 Fields, 15.734KHz line, Sub-Carrier 3.580MHz */
 
 	.hsync_end	= 64,		    .hblank_end		= 124,
@@ -203,108 +349,264 @@ const static tv_mode_t tv_modes[] = {
 	    .ru =-0.0885, .gu =-0.1738, .bu = 0.2624, .au = 1.0000,
 	    .rv = 0.3693, .gv =-0.3092, .bv =-0.0601, .av = 1.0000,
 	},
+	.filter_table = filter_table_ntsc,
     },
     {
-	.name		= "NTSC-Japan 480i",
-	.clock		= 107520,	
-	.oversample	= TV_OVERSAMPLE_8X,
-	
-	/* 525 Lines, 60 Fields, 15.734KHz line, Sub-Carrier 3.580MHz */
-	.hsync_end	= 64,		    .hblank_end		= 124,
-	.hblank_start	= 836,		    .htotal		= 857,
-	
-	.progressive	= FALSE,	    .trilevel_sync = FALSE,
+         .name		= "NTSC-443",
+	 .clock		= 107520,	
+	 .oversample	= TV_OVERSAMPLE_8X,
+	 .component_only = 0,
+	 /* 525 Lines, 60 Fields, 15.734KHz line, Sub-Carrier 4.43MHz */
+	 .hsync_end	= 64,		    .hblank_end		= 124,
+	 .hblank_start	= 836,		    .htotal		= 857,
+
+	 .progressive	= FALSE,	    .trilevel_sync = FALSE,
+
+	 .vsync_start_f1 = 6,		    .vsync_start_f2	= 7,
+	 .vsync_len	= 6,
+
+	 .veq_ena	= TRUE,		    .veq_start_f1    	= 0,
+	 .veq_start_f2	= 1,		    .veq_len		= 18,
+
+	 .vi_end_f1	= 20,		    .vi_end_f2		= 21,
+	 .nbr_end	= 240,
+
+	 .burst_ena	= TRUE,
+	 .hburst_start	= 72,		    .hburst_len		= 34,
+	 .vburst_start_f1 = 9,		    .vburst_end_f1	= 240,
+	 .vburst_start_f2 = 10,		    .vburst_end_f2	= 240,
+	 .vburst_start_f3 = 9,		    .vburst_end_f3	= 240, 
+	 .vburst_start_f4 = 10,		    .vburst_end_f4	= 240,
+
+	 /* desired 4.4336180 actual 4.4336180 clock 107.52 */
+	 .dda1_inc	=   168,
+	 .dda2_inc	=   4093,	    .dda2_size		=  27456,
+	 .dda3_inc	=   525,	    .dda3_size		=  310,
+	 .sc_reset	= TV_SC_RESET_NEVER,
+	 .pal_burst	= FALSE,
+
+	 .composite_levels = { .blank = 225, .black = 267, .burst = 113 },
+	 .composite_color = {
+		 .ry = 0.2990, .gy = 0.5870, .by = 0.1140, .ay = 0.5082,
+		 .ru =-0.0749, .gu =-0.1471, .bu = 0.2220, .au = 1.0000,
+		 .rv = 0.3125, .gv =-0.2616, .bv =-0.0508, .av = 1.0000,
+	 },
+
+	 .svideo_levels    = { .blank = 266, .black = 316, .burst = 133 },
+	 .svideo_color = {
+		 .ry = 0.2990, .gy = 0.5870, .by = 0.1140, .ay = 0.6006,
+		 .ru =-0.0885, .gu =-0.1738, .bu = 0.2624, .au = 1.0000,
+		 .rv = 0.3693, .gv =-0.3092, .bv =-0.0601, .av = 1.0000,
+	 },
+	.filter_table = filter_table_ntsc,
+    },
+    {
+	    .name		= "NTSC-J",
+	    .clock		= 107520,	
+	    .oversample	= TV_OVERSAMPLE_8X,
+	    .component_only = 0,
+
+	    /* 525 Lines, 60 Fields, 15.734KHz line, Sub-Carrier 3.580MHz */
+	    .hsync_end	= 64,		    .hblank_end		= 124,
+	    .hblank_start = 836,	    .htotal		= 857,
+
+	    .progressive	= FALSE,    .trilevel_sync = FALSE,
+
+	    .vsync_start_f1	= 6,	    .vsync_start_f2	= 7,
+	    .vsync_len	= 6,
+
+	    .veq_ena	= TRUE,		    .veq_start_f1    	= 0,
+	    .veq_start_f2 = 1,	    .veq_len		= 18,
+
+	    .vi_end_f1	= 20,		    .vi_end_f2		= 21,
+	    .nbr_end	= 240,
+
+	    .burst_ena	= TRUE,
+	    .hburst_start	= 72,		    .hburst_len		= 34,
+	    .vburst_start_f1 = 9,		    .vburst_end_f1	= 240,
+	    .vburst_start_f2 = 10,		    .vburst_end_f2	= 240,
+	    .vburst_start_f3 = 9,		    .vburst_end_f3	= 240, 
+	    .vburst_start_f4 = 10,		    .vburst_end_f4	= 240,
+
+	    /* desired 3.5800000 actual 3.5800000 clock 107.52 */
+	    .dda1_inc	=    136,
+	    .dda2_inc	=   7624,	    .dda2_size		=  20013,
+	    .dda3_inc	=      0,	    .dda3_size		=      0,
+	    .sc_reset	= TV_SC_RESET_EVERY_4,
+	    .pal_burst	= FALSE,
 
-	.vsync_start_f1	= 6,		    .vsync_start_f2	= 7,
-	.vsync_len	= 6,
-	
-	.veq_ena	= TRUE,		    .veq_start_f1    	= 0,
-	.veq_start_f2	= 1,		    .veq_len		= 18,
-	
-	.vi_end_f1	= 20,		    .vi_end_f2		= 21,
-	.nbr_end	= 240,
-	
-	.burst_ena	= TRUE,
-	.hburst_start	= 72,		    .hburst_len		= 34,
-	.vburst_start_f1 = 9,		    .vburst_end_f1	= 240,
-	.vburst_start_f2 = 10,		    .vburst_end_f2	= 240,
-	.vburst_start_f3 = 9,		    .vburst_end_f3	= 240, 
-	.vburst_start_f4 = 10,		    .vburst_end_f4	= 240,
+	    .composite_levels = { .blank = 225, .black = 225, .burst = 113 },
+	    .composite_color = {
+		    .ry = 0.2990, .gy = 0.5870, .by = 0.1140, .ay = 0.5495,
+		    .ru =-0.0810, .gu =-0.1590, .bu = 0.2400, .au = 1.0000,
+		    .rv = 0.3378, .gv =-0.2829, .bv =-0.0549, .av = 1.0000,
+	    },
 
-	/* desired 3.5800000 actual 3.5800000 clock 107.52 */
-	.dda1_inc	=    136,
-	.dda2_inc	=   7624,	    .dda2_size		=  20013,
-	.dda3_inc	=      0,	    .dda3_size		=      0,
-	.sc_reset	= TV_SC_RESET_EVERY_4,
-	.pal_burst	= FALSE,
+	    .svideo_levels    = { .blank = 266, .black = 266, .burst = 133 },
+	    .svideo_color = {
+		    .ry = 0.2990, .gy = 0.5870, .by = 0.1140, .ay = 0.6494,
+		    .ru =-0.0957, .gu =-0.1879, .bu = 0.2836, .au = 1.0000,
+		    .rv = 0.3992, .gv =-0.3343, .bv =-0.0649, .av = 1.0000,
+	    },
+	    .filter_table = filter_table_ntsc,
+    },
+    {
+	    .name		= "PAL-M",
+	    .clock		= 107520,	
+	    .oversample	= TV_OVERSAMPLE_8X,
+	    .component_only = 0,
+
+	    /* 525 Lines, 60 Fields, 15.734KHz line, Sub-Carrier 3.580MHz */
+	    .hsync_end	= 64,		  .hblank_end		= 124,
+	    .hblank_start = 836,	  .htotal		= 857,
+
+	    .progressive	= FALSE,	    .trilevel_sync = FALSE,
+
+	    .vsync_start_f1	= 6,		    .vsync_start_f2	= 7,
+	    .vsync_len	= 6,
+
+	    .veq_ena	= TRUE,		    .veq_start_f1    	= 0,
+	    .veq_start_f2	= 1,		    .veq_len		= 18,
+
+	    .vi_end_f1	= 20,		    .vi_end_f2		= 21,
+	    .nbr_end	= 240,
+
+	    .burst_ena	= TRUE,
+	    .hburst_start	= 72,		    .hburst_len		= 34,
+	    .vburst_start_f1 = 9,		    .vburst_end_f1	= 240,
+	    .vburst_start_f2 = 10,		    .vburst_end_f2	= 240,
+	    .vburst_start_f3 = 9,		    .vburst_end_f3	= 240, 
+	    .vburst_start_f4 = 10,		    .vburst_end_f4	= 240,
+
+	    /* desired 3.5800000 actual 3.5800000 clock 107.52 */
+	    .dda1_inc	=    135,
+	    .dda2_inc	=    16704,	    .dda2_size		=  27456,
+	    .dda3_inc	=      0,	    .dda3_size		=      0,
+	    .sc_reset	= TV_SC_RESET_EVERY_8,
+	    .pal_burst  = TRUE,
 
-	.composite_levels = { .blank = 225, .black = 225, .burst = 113 },
-	.composite_color = {
-	    .ry = 0.2990, .gy = 0.5870, .by = 0.1140, .ay = 0.5495,
-	    .ru =-0.0810, .gu =-0.1590, .bu = 0.2400, .au = 1.0000,
-	    .rv = 0.3378, .gv =-0.2829, .bv =-0.0549, .av = 1.0000,
-	},
+	    .composite_levels = { .blank = 225, .black = 267, .burst = 113 },
+	    .composite_color = {
+		    .ry = 0.2990, .gy = 0.5870, .by = 0.1140, .ay = 0.5082,
+		    .ru =-0.0749, .gu =-0.1471, .bu = 0.2220, .au = 1.0000,
+		    .rv = 0.3125, .gv =-0.2616, .bv =-0.0508, .av = 1.0000,
+	    },
 
-	.svideo_levels    = { .blank = 266, .black = 266, .burst = 133 },
-	.svideo_color = {
-	    .ry = 0.2990, .gy = 0.5870, .by = 0.1140, .ay = 0.6494,
-	    .ru =-0.0957, .gu =-0.1879, .bu = 0.2836, .au = 1.0000,
-	    .rv = 0.3992, .gv =-0.3343, .bv =-0.0649, .av = 1.0000,
-	},
+	    .svideo_levels    = { .blank = 266, .black = 316, .burst = 133 },
+	    .svideo_color = {
+		    .ry = 0.2990, .gy = 0.5870, .by = 0.1140, .ay = 0.6006,
+		    .ru =-0.0885, .gu =-0.1738, .bu = 0.2624, .au = 1.0000,
+		    .rv = 0.3693, .gv =-0.3092, .bv =-0.0601, .av = 1.0000,
+	    },
+	    .filter_table = filter_table_pal,
     },
     {
-	/* 625 Lines, 50 Fields, 15.625KHz line, Sub-Carrier 4.434MHz */
-	.name	    = "PAL 576i",
-	.clock		= 107520,	
-	.oversample	= TV_OVERSAMPLE_8X,
+	    /* 625 Lines, 50 Fields, 15.625KHz line, Sub-Carrier 4.434MHz */
+	    .name	    = "PAL-N",
+	    .clock		= 107520,	
+	    .oversample	= TV_OVERSAMPLE_8X,
+	    .component_only = 0,
+
+	    .hsync_end	= 64,		    .hblank_end		= 128,
+	    .hblank_start = 844,	    .htotal		= 863,
+
+	    .progressive  = FALSE,    .trilevel_sync = FALSE,
+
+
+	    .vsync_start_f1	= 6,	   .vsync_start_f2	= 7,
+	    .vsync_len	= 6,
+
+	    .veq_ena	= TRUE,		    .veq_start_f1    	= 0,
+	    .veq_start_f2	= 1,		    .veq_len		= 18,
+
+	    .vi_end_f1	= 24,		    .vi_end_f2		= 25,
+	    .nbr_end	= 286,
+
+	    .burst_ena	= TRUE,
+	    .hburst_start = 73,	    .hburst_len		= 34,
+	    .vburst_start_f1 = 8,	    .vburst_end_f1	= 285,
+	    .vburst_start_f2 = 8,	    .vburst_end_f2	= 286,
+	    .vburst_start_f3 = 9,	    .vburst_end_f3	= 286, 
+	    .vburst_start_f4 = 9,	    .vburst_end_f4	= 285,
+
+	    /* desired 4.4336180 actual 4.4336180 clock 107.52 */
+	    .dda1_inc	=    135,
+	    .dda2_inc	=  23578,	.dda2_size	=  27648,
+	    .dda3_inc	=     134,	.dda3_size	=  625,
+	    .sc_reset   = TV_SC_RESET_EVERY_8,
+	    .pal_burst  = TRUE,
 
-	.hsync_end	= 64,		    .hblank_end		= 128,
-	.hblank_start	= 844,		    .htotal		= 863,
-	
-	.progressive	= FALSE,	   .trilevel_sync = FALSE,
-	
-	
-	.vsync_start_f1	= 6,		    .vsync_start_f2	= 7,
-	.vsync_len	= 6,
-	
-	.veq_ena	= TRUE,		    .veq_start_f1    	= 0,
-	.veq_start_f2	= 1,		    .veq_len		= 18,
+	    .composite_levels = { .blank = 225, .black = 267, .burst = 118 },
+	    .composite_color = {
+		    .ry = 0.2990, .gy = 0.5870, .by = 0.1140, .ay = 0.5082,
+		    .ru =-0.0749, .gu =-0.1471, .bu = 0.2220, .au = 1.0000,
+		    .rv = 0.3125, .gv =-0.2616, .bv =-0.0508, .av = 1.0000,
+	    },
 
-	.vi_end_f1	= 24,		    .vi_end_f2		= 25,
-	.nbr_end	= 286,
+	    .svideo_levels    = { .blank = 266, .black = 316, .burst = 139 },
+	    .svideo_color = {
+		    .ry = 0.2990, .gy = 0.5870, .by = 0.1140, .ay = 0.6006,
+		    .ru =-0.0885, .gu =-0.1738, .bu = 0.2624, .au = 1.0000,
+		    .rv = 0.3693, .gv =-0.3092, .bv =-0.0601, .av = 1.0000,
+	    },
+	    .filter_table = filter_table_pal,
+    },
+    {
+	    /* 625 Lines, 50 Fields, 15.625KHz line, Sub-Carrier 4.434MHz */
+	    .name	    = "PAL",
+	    .clock		= 107520,	
+	    .oversample	= TV_OVERSAMPLE_8X,
+	    .component_only = 0,
+
+	    .hsync_end	= 64,		    .hblank_end		= 128,
+	    .hblank_start	= 844,		    .htotal		= 863,
+
+	    .progressive	= FALSE,	   .trilevel_sync = FALSE,
+
+
+	    .vsync_start_f1	= 6,		    .vsync_start_f2	= 7,
+	    .vsync_len	= 6,
+
+	    .veq_ena	= TRUE,		    .veq_start_f1    	= 0,
+	    .veq_start_f2	= 1,		    .veq_len		= 18,
+
+	    .vi_end_f1	= 24,		    .vi_end_f2		= 25,
+	    .nbr_end	= 286,
+
+	    .burst_ena	= TRUE,
+	    .hburst_start	= 73,		    .hburst_len		= 34,
+	    .vburst_start_f1 = 8,		    .vburst_end_f1	= 285,
+	    .vburst_start_f2 = 8,		    .vburst_end_f2	= 286,
+	    .vburst_start_f3 = 9,		    .vburst_end_f3	= 286, 
+	    .vburst_start_f4 = 9,		    .vburst_end_f4	= 285,
+
+	    /* desired 4.4336180 actual 4.4336180 clock 107.52 */
+	    .dda1_inc	=    168,
+	    .dda2_inc	=   4122,	.dda2_size	=  27648,
+	    .dda3_inc	=     67,	.dda3_size	=  625,
+	    .sc_reset   = TV_SC_RESET_EVERY_8,
+	    .pal_burst  = TRUE,
 
-	.burst_ena	= TRUE,
-	.hburst_start	= 73,		    .hburst_len		= 34,
-	.vburst_start_f1 = 8,		    .vburst_end_f1	= 285,
-	.vburst_start_f2 = 8,		    .vburst_end_f2	= 286,
-	.vburst_start_f3 = 9,		    .vburst_end_f3	= 286, 
-	.vburst_start_f4 = 9,		    .vburst_end_f4	= 285,
-
-	/* desired 4.4336180 actual 4.4336180 clock 107.52 */
-	.dda1_inc	=    168,
-	.dda2_inc	=  18557,	.dda2_size	=  20625,
-	.dda3_inc	=      0,	.dda3_size	=      0,
-	.sc_reset   = TV_SC_RESET_EVERY_8,
-	.pal_burst  = TRUE,
-	
-	.composite_levels = { .blank = 237, .black = 237, .burst = 118 },
-	.composite_color = {
-	    .ry = 0.2990, .gy = 0.5870, .by = 0.1140, .ay = 0.5379,
-	    .ru =-0.0793, .gu =-0.1557, .bu = 0.2350, .au = 1.0000,
-	    .rv = 0.3307, .gv =-0.2769, .bv =-0.0538, .av = 1.0000,
-	},
+	    .composite_levels = { .blank = 237, .black = 237, .burst = 118 },
+	    .composite_color = {
+		    .ry = 0.2990, .gy = 0.5870, .by = 0.1140, .ay = 0.5379,
+		    .ru =-0.0793, .gu =-0.1557, .bu = 0.2350, .au = 1.0000,
+		    .rv = 0.3307, .gv =-0.2769, .bv =-0.0538, .av = 1.0000,
+	    },
 
-	.svideo_levels    = { .blank = 280, .black = 280, .burst = 139 },
-	.svideo_color = {
-	    .ry = 0.2990, .gy = 0.5870, .by = 0.1140, .ay = 0.6357,
-	    .ru =-0.0937, .gu =-0.1840, .bu = 0.2777, .au = 1.0000,
-	    .rv = 0.3908, .gv =-0.3273, .bv =-0.0636, .av = 1.0000,
-	},
+	    .svideo_levels    = { .blank = 280, .black = 280, .burst = 139 },
+	    .svideo_color = {
+		    .ry = 0.2990, .gy = 0.5870, .by = 0.1140, .ay = 0.6357,
+		    .ru =-0.0937, .gu =-0.1840, .bu = 0.2777, .au = 1.0000,
+		    .rv = 0.3908, .gv =-0.3273, .bv =-0.0636, .av = 1.0000,
+	    },
+	    .filter_table = filter_table_pal,
     },
     {
-	    .name       = "480p",
+	    .name       = "480p at 59.94Hz",
 	    .clock 	= 107520,	
 	    .oversample     = TV_OVERSAMPLE_4X,
+	    .component_only = 1,
 
 	    .hsync_end      = 64,               .hblank_end         = 122,
 	    .hblank_start   = 842,              .htotal             = 857,
@@ -334,11 +636,49 @@ const static tv_mode_t tv_modes[] = {
 		    .ru =-0.0937, .gu =-0.1840, .bu = 0.2777, .au = 1.0000,
 		    .rv = 0.3908, .gv =-0.3273, .bv =-0.0636, .av = 1.0000,
 	    },
+	    .filter_table = filter_table_hres,
+    },
+    {
+	    .name       = "480p at 60Hz",
+	    .clock 	= 107520,	
+	    .oversample     = TV_OVERSAMPLE_4X,
+	    .component_only = 1,
+
+	    .hsync_end      = 64,               .hblank_end         = 122,
+	    .hblank_start   = 842,              .htotal             = 856,
+
+	    .progressive    = TRUE,.trilevel_sync = FALSE,
+
+	    .vsync_start_f1 = 12,               .vsync_start_f2     = 12,
+	    .vsync_len      = 12,
+
+	    .veq_ena        = FALSE,
+
+	    .vi_end_f1      = 44,               .vi_end_f2          = 44,
+	    .nbr_end        = 496,
+
+	    .burst_ena      = FALSE,
+
+	    .composite_levels = { .blank = 237, .black = 237, .burst = 118 },
+	    .composite_color = {
+		    .ry = 0.2990, .gy = 0.5870, .by = 0.1140, .ay = 0.5379,
+		    .ru =-0.0793, .gu =-0.1557, .bu = 0.2350, .au = 1.0000,
+		    .rv = 0.3307, .gv =-0.2769, .bv =-0.0538, .av = 1.0000,
+	    },
+
+	    .svideo_levels    = { .blank = 280, .black = 280, .burst = 139 },
+	    .svideo_color = {
+		    .ry = 0.2990, .gy = 0.5870, .by = 0.1140, .ay = 0.6357,
+		    .ru =-0.0937, .gu =-0.1840, .bu = 0.2777, .au = 1.0000,
+		    .rv = 0.3908, .gv =-0.3273, .bv =-0.0636, .av = 1.0000,
+	    },
+	    .filter_table = filter_table_hres,
     },
     {
 	    .name       = "576p",
 	    .clock 	= 107520,	
 	    .oversample     = TV_OVERSAMPLE_4X,
+	    .component_only = 1,
 
 	    .hsync_end      = 64,               .hblank_end         = 139,
 	    .hblank_start   = 859,              .htotal             = 863,
@@ -368,571 +708,613 @@ const static tv_mode_t tv_modes[] = {
 		    .ru =-0.0937, .gu =-0.1840, .bu = 0.2777, .au = 1.0000,
 		    .rv = 0.3908, .gv =-0.3273, .bv =-0.0636, .av = 1.0000,
 	    },
+	    .filter_table = filter_table_hres,
     },
     {
-        .name       = "720p",
-	.clock		= 148800,	
-        .oversample     = TV_OVERSAMPLE_2X,
-
-        .hsync_end      = 80,               .hblank_end         = 300,
-        .hblank_start   = 1580,             .htotal             = 1649,
-
-        .progressive    = TRUE, 	    .trilevel_sync = TRUE,
-
-        .vsync_start_f1 = 10,               .vsync_start_f2     = 10,
-        .vsync_len      = 10,
-
-        .veq_ena        = FALSE,
-
-        .vi_end_f1      = 29,               .vi_end_f2          = 29,
-        .nbr_end        = 719,
-
-        .burst_ena      = FALSE,
-
-        .composite_levels = { .blank = 237, .black = 237, .burst = 118 },
-        .composite_color = {
-            .ry = 0.2990, .gy = 0.5870, .by = 0.1140, .ay = 0.5379,
-            .ru =-0.0793, .gu =-0.1557, .bu = 0.2350, .au = 1.0000,
-            .rv = 0.3307, .gv =-0.2769, .bv =-0.0538, .av = 1.0000,
-        },
-
-        .svideo_levels    = { .blank = 280, .black = 280, .burst = 139 },
-        .svideo_color = {
-            .ry = 0.2990, .gy = 0.5870, .by = 0.1140, .ay = 0.6357,
-            .ru =-0.0937, .gu =-0.1840, .bu = 0.2777, .au = 1.0000,
-            .rv = 0.3908, .gv =-0.3273, .bv =-0.0636, .av = 1.0000,
-        },
+	    .name       = "720p at 60Hz",
+	    .clock		= 148800,	
+	    .oversample     = TV_OVERSAMPLE_2X,
+	    .component_only = 1,
+
+	    .hsync_end      = 80,               .hblank_end         = 300,
+	    .hblank_start   = 1580,             .htotal             = 1649,
+
+	    .progressive    = TRUE, 	    .trilevel_sync = TRUE,
+
+	    .vsync_start_f1 = 10,               .vsync_start_f2     = 10,
+	    .vsync_len      = 10,
+
+	    .veq_ena        = FALSE,
+
+	    .vi_end_f1      = 29,               .vi_end_f2          = 29,
+	    .nbr_end        = 719,
+
+	    .burst_ena      = FALSE,
+
+	    .composite_levels = { .blank = 237, .black = 237, .burst = 118 },
+	    .composite_color = {
+		    .ry = 0.2990, .gy = 0.5870, .by = 0.1140, .ay = 0.5379,
+		    .ru =-0.0793, .gu =-0.1557, .bu = 0.2350, .au = 1.0000,
+		    .rv = 0.3307, .gv =-0.2769, .bv =-0.0538, .av = 1.0000,
+	    },
+	    .filter_table = filter_table_hres,
     },
     {
-        .name       = "1080i",
-	.clock		= 148800,	
-        .oversample     = TV_OVERSAMPLE_2X,
+	    .name       = "720p at 59.94Hz",
+	    .clock		= 148800,	
+	    .oversample     = TV_OVERSAMPLE_2X,
+	    .component_only = 1,
 
-        .hsync_end      = 88,               .hblank_end         = 235,
-        .hblank_start   = 2155,             .htotal             = 2639,
+	    .hsync_end      = 80,               .hblank_end         = 300,
+	    .hblank_start   = 1580,             .htotal             = 1651,
 
-        .progressive    = FALSE, 	    .trilevel_sync = TRUE,
+	    .progressive    = TRUE, 	    .trilevel_sync = TRUE,
 
-        .vsync_start_f1 = 4,               .vsync_start_f2     = 5,
-        .vsync_len      = 10,
+	    .vsync_start_f1 = 10,               .vsync_start_f2     = 10,
+	    .vsync_len      = 10,
 
-	.veq_ena	= TRUE,		    .veq_start_f1    	= 4,
-	.veq_start_f2	= 4,		    .veq_len		= 10,
-	
+	    .veq_ena        = FALSE,
 
-        .vi_end_f1      = 21,               .vi_end_f2          = 22,
-        .nbr_end        = 539,
+	    .vi_end_f1      = 29,               .vi_end_f2          = 29,
+	    .nbr_end        = 719,
 
-        .burst_ena      = FALSE,
+	    .burst_ena      = FALSE,
 
-        .composite_levels = { .blank = 237, .black = 237, .burst = 118 },
-        .composite_color = {
-            .ry = 0.2990, .gy = 0.5870, .by = 0.1140, .ay = 0.5379,
-            .ru =-0.0793, .gu =-0.1557, .bu = 0.2350, .au = 1.0000,
-            .rv = 0.3307, .gv =-0.2769, .bv =-0.0538, .av = 1.0000,
-        },
-
-        .svideo_levels    = { .blank = 280, .black = 280, .burst = 139 },
-        .svideo_color = {
-            .ry = 0.2990, .gy = 0.5870, .by = 0.1140, .ay = 0.6357,
-            .ru =-0.0937, .gu =-0.1840, .bu = 0.2777, .au = 1.0000,
-            .rv = 0.3908, .gv =-0.3273, .bv =-0.0636, .av = 1.0000,
-        },
+	    .composite_levels = { .blank = 237, .black = 237, .burst = 118 },
+	    .composite_color = {
+		    .ry = 0.2990, .gy = 0.5870, .by = 0.1140, .ay = 0.5379,
+		    .ru =-0.0793, .gu =-0.1557, .bu = 0.2350, .au = 1.0000,
+		    .rv = 0.3307, .gv =-0.2769, .bv =-0.0538, .av = 1.0000,
+	    },
+	    .filter_table = filter_table_hres,
+    },
+    {
+	    .name       = "1080i at 50Hz",
+	    .clock		= 148800,	
+	    .oversample     = TV_OVERSAMPLE_2X,
+	    .component_only = 1,
+
+	    .hsync_end      = 88,               .hblank_end         = 235,
+	    .hblank_start   = 2155,             .htotal             = 2639,
+
+	    .progressive    = FALSE, 	    .trilevel_sync = TRUE,
+
+	    .vsync_start_f1 = 4,              .vsync_start_f2     = 5,
+	    .vsync_len      = 10,
+
+	    .veq_ena	= TRUE,		    .veq_start_f1    	= 4,
+	    .veq_start_f2   = 4,	    .veq_len		= 10,
+
+
+	    .vi_end_f1      = 21,           .vi_end_f2          = 22,
+	    .nbr_end        = 539,
+
+	    .burst_ena      = FALSE,
+
+	    .composite_levels = { .blank = 237, .black = 237, .burst = 118 },
+	    .composite_color = {
+		    .ry = 0.2990, .gy = 0.5870, .by = 0.1140, .ay = 0.5379,
+		    .ru =-0.0793, .gu =-0.1557, .bu = 0.2350, .au = 1.0000,
+		    .rv = 0.3307, .gv =-0.2769, .bv =-0.0538, .av = 1.0000,
+	    },
+	    .filter_table = filter_table_hres,
+    },
+    {
+	    .name       = "1080i at 30Hz",
+	    .clock		= 148800,	
+	    .oversample     = TV_OVERSAMPLE_2X,
+	    .component_only = 1,
+
+	    .hsync_end      = 88,               .hblank_end         = 235,
+	    .hblank_start   = 2155,             .htotal             = 2199,
+
+	    .progressive    = FALSE, 	    .trilevel_sync = TRUE,
+
+	    .vsync_start_f1 = 4,               .vsync_start_f2     = 5,
+	    .vsync_len      = 10,
+
+	    .veq_ena	= TRUE,		    .veq_start_f1    	= 4,
+	    .veq_start_f2	= 4,		    .veq_len		= 10,
+
+
+	    .vi_end_f1      = 21,               .vi_end_f2          = 22,
+	    .nbr_end        = 539,
+
+	    .burst_ena      = FALSE,
+
+	    .composite_levels = { .blank = 237, .black = 237, .burst = 118 },
+	    .composite_color = {
+		    .ry = 0.2990, .gy = 0.5870, .by = 0.1140, .ay = 0.5379,
+		    .ru =-0.0793, .gu =-0.1557, .bu = 0.2350, .au = 1.0000,
+		    .rv = 0.3307, .gv =-0.2769, .bv =-0.0538, .av = 1.0000,
+	    },
+	    .filter_table = filter_table_hres,
+    },
+    {
+	    .name       = "1080i at 29.97Hz",
+	    .clock		= 148800,	
+	    .oversample     = TV_OVERSAMPLE_2X,
+	    .component_only = 1,
+
+	    .hsync_end      = 88,               .hblank_end         = 235,
+	    .hblank_start   = 2155,             .htotal             = 2200,
+
+	    .progressive    = FALSE, 	    .trilevel_sync = TRUE,
+
+	    .vsync_start_f1 = 4,            .vsync_start_f2    = 5,
+	    .vsync_len      = 10,
+
+	    .veq_ena	= TRUE,		    .veq_start_f1	= 4,
+	    .veq_start_f2 = 4,	    	    .veq_len = 10,
+
+
+	    .vi_end_f1      = 21,           .vi_end_f2         	= 22,
+	    .nbr_end        = 539,
+
+	    .burst_ena      = FALSE,
+
+	    .composite_levels = { .blank = 237, .black = 237, .burst = 118 },
+	    .composite_color = {
+		    .ry = 0.2990, .gy = 0.5870, .by = 0.1140, .ay = 0.5379,
+		    .ru =-0.0793, .gu =-0.1557, .bu = 0.2350, .au = 1.0000,
+		    .rv = 0.3307, .gv =-0.2769, .bv =-0.0538, .av = 1.0000,
+	    },
+	    .filter_table = filter_table_hres,
     },
 };
 
 static const video_levels_t component_level = {
-    .blank = 279, .black = 279 
+	.blank = 279, .black = 279 
 };
 
 static const color_conversion_t sdtv_component_color = {
-    .ry = 0.2990, .gy = 0.5870, .by = 0.1140, .ay = 0.6364,
-    .ru =-0.1687, .gu =-0.3313, .bu = 0.5000, .au = 1.0000,
-    .rv = 0.5000, .gv =-0.4187, .bv =-0.0813, .av = 1.0000,
+	.ry = 0.2990, .gy = 0.5870, .by = 0.1140, .ay = 0.6364,
+	.ru =-0.1687, .gu =-0.3313, .bu = 0.5000, .au = 1.0000,
+	.rv = 0.5000, .gv =-0.4187, .bv =-0.0813, .av = 1.0000,
 };
-    
+
 static const color_conversion_t hdtv_component_color = {
-    .ry = 0.2126, .gy = 0.7152, .by = 0.0722, .ay = 0.6364,
-    .ru =-0.1146, .gu =-0.3854, .bu = 0.5000, .au = 1.0000,
-    .rv = 0.5000, .gv =-0.4542, .bv =-0.0458, .av = 1.0000,
+	.ry = 0.2126, .gy = 0.7152, .by = 0.0722, .ay = 0.6364,
+	.ru =-0.1146, .gu =-0.3854, .bu = 0.5000, .au = 1.0000,
+	.rv = 0.5000, .gv =-0.4542, .bv =-0.0458, .av = 1.0000,
 };
-    
+
 static void
 i830_tv_dpms(xf86OutputPtr output, int mode)
 {
-    ScrnInfoPtr pScrn = output->scrn;
-    I830Ptr pI830 = I830PTR(pScrn);
+	ScrnInfoPtr pScrn = output->scrn;
+	I830Ptr pI830 = I830PTR(pScrn);
 
-    switch(mode) {
-    case DPMSModeOn:
-	OUTREG(TV_CTL, INREG(TV_CTL) | TV_ENC_ENABLE);
-	break;
-    case DPMSModeStandby:
-    case DPMSModeSuspend:
-    case DPMSModeOff:
-	OUTREG(TV_CTL, INREG(TV_CTL) & ~TV_ENC_ENABLE);
-	break;
-    }
+	switch(mode) {
+		case DPMSModeOn:
+			OUTREG(TV_CTL, INREG(TV_CTL) | TV_ENC_ENABLE);
+			break;
+		case DPMSModeStandby:
+		case DPMSModeSuspend:
+		case DPMSModeOff:
+			OUTREG(TV_CTL, INREG(TV_CTL) & ~TV_ENC_ENABLE);
+			break;
+	}
 }
 
 static void
 i830_tv_save(xf86OutputPtr output)
 {
-    ScrnInfoPtr		    pScrn = output->scrn;
-    I830Ptr		    pI830 = I830PTR(pScrn);
-    I830OutputPrivatePtr    intel_output = output->driver_private;
-    struct i830_tv_priv	    *dev_priv = intel_output->dev_priv;
-    int			    i;
-
-    dev_priv->save_TV_H_CTL_1 = INREG(TV_H_CTL_1);
-    dev_priv->save_TV_H_CTL_2 = INREG(TV_H_CTL_2);
-    dev_priv->save_TV_H_CTL_3 = INREG(TV_H_CTL_3);
-    dev_priv->save_TV_V_CTL_1 = INREG(TV_V_CTL_1);
-    dev_priv->save_TV_V_CTL_2 = INREG(TV_V_CTL_2);
-    dev_priv->save_TV_V_CTL_3 = INREG(TV_V_CTL_3);
-    dev_priv->save_TV_V_CTL_4 = INREG(TV_V_CTL_4);
-    dev_priv->save_TV_V_CTL_5 = INREG(TV_V_CTL_5);
-    dev_priv->save_TV_V_CTL_6 = INREG(TV_V_CTL_6);
-    dev_priv->save_TV_V_CTL_7 = INREG(TV_V_CTL_7);
-    dev_priv->save_TV_SC_CTL_1 = INREG(TV_SC_CTL_1);
-    dev_priv->save_TV_SC_CTL_2 = INREG(TV_SC_CTL_2);
-    dev_priv->save_TV_SC_CTL_3 = INREG(TV_SC_CTL_3);
-
-    dev_priv->save_TV_CSC_Y = INREG(TV_CSC_Y);
-    dev_priv->save_TV_CSC_Y2 = INREG(TV_CSC_Y2);
-    dev_priv->save_TV_CSC_U = INREG(TV_CSC_U);
-    dev_priv->save_TV_CSC_U2 = INREG(TV_CSC_U2);
-    dev_priv->save_TV_CSC_V = INREG(TV_CSC_V);
-    dev_priv->save_TV_CSC_V2 = INREG(TV_CSC_V2);
-    dev_priv->save_TV_CLR_KNOBS = INREG(TV_CLR_KNOBS);
-    dev_priv->save_TV_CLR_LEVEL = INREG(TV_CLR_LEVEL);
-    dev_priv->save_TV_WIN_POS = INREG(TV_WIN_POS);
-    dev_priv->save_TV_WIN_SIZE = INREG(TV_WIN_SIZE);
-    dev_priv->save_TV_FILTER_CTL_1 = INREG(TV_FILTER_CTL_1);
-    dev_priv->save_TV_FILTER_CTL_2 = INREG(TV_FILTER_CTL_2);
-    dev_priv->save_TV_FILTER_CTL_3 = INREG(TV_FILTER_CTL_3);
-
-    for (i = 0; i < 60; i++)
-	dev_priv->save_TV_H_LUMA[i] = INREG(TV_H_LUMA_0 + (i <<2));
-    for (i = 0; i < 60; i++)
-	dev_priv->save_TV_H_CHROMA[i] = INREG(TV_H_CHROMA_0 + (i <<2));
-    for (i = 0; i < 43; i++)
-	dev_priv->save_TV_V_LUMA[i] = INREG(TV_V_LUMA_0 + (i <<2));
-    for (i = 0; i < 43; i++)
-	dev_priv->save_TV_V_CHROMA[i] = INREG(TV_V_CHROMA_0 + (i <<2));
+	ScrnInfoPtr		    pScrn = output->scrn;
+	I830Ptr		    pI830 = I830PTR(pScrn);
+	I830OutputPrivatePtr    intel_output = output->driver_private;
+	struct i830_tv_priv	    *dev_priv = intel_output->dev_priv;
+	int			    i;
+
+	dev_priv->save_TV_H_CTL_1 = INREG(TV_H_CTL_1);
+	dev_priv->save_TV_H_CTL_2 = INREG(TV_H_CTL_2);
+	dev_priv->save_TV_H_CTL_3 = INREG(TV_H_CTL_3);
+	dev_priv->save_TV_V_CTL_1 = INREG(TV_V_CTL_1);
+	dev_priv->save_TV_V_CTL_2 = INREG(TV_V_CTL_2);
+	dev_priv->save_TV_V_CTL_3 = INREG(TV_V_CTL_3);
+	dev_priv->save_TV_V_CTL_4 = INREG(TV_V_CTL_4);
+	dev_priv->save_TV_V_CTL_5 = INREG(TV_V_CTL_5);
+	dev_priv->save_TV_V_CTL_6 = INREG(TV_V_CTL_6);
+	dev_priv->save_TV_V_CTL_7 = INREG(TV_V_CTL_7);
+	dev_priv->save_TV_SC_CTL_1 = INREG(TV_SC_CTL_1);
+	dev_priv->save_TV_SC_CTL_2 = INREG(TV_SC_CTL_2);
+	dev_priv->save_TV_SC_CTL_3 = INREG(TV_SC_CTL_3);
+
+	dev_priv->save_TV_CSC_Y = INREG(TV_CSC_Y);
+	dev_priv->save_TV_CSC_Y2 = INREG(TV_CSC_Y2);
+	dev_priv->save_TV_CSC_U = INREG(TV_CSC_U);
+	dev_priv->save_TV_CSC_U2 = INREG(TV_CSC_U2);
+	dev_priv->save_TV_CSC_V = INREG(TV_CSC_V);
+	dev_priv->save_TV_CSC_V2 = INREG(TV_CSC_V2);
+	dev_priv->save_TV_CLR_KNOBS = INREG(TV_CLR_KNOBS);
+	dev_priv->save_TV_CLR_LEVEL = INREG(TV_CLR_LEVEL);
+	dev_priv->save_TV_WIN_POS = INREG(TV_WIN_POS);
+	dev_priv->save_TV_WIN_SIZE = INREG(TV_WIN_SIZE);
+	dev_priv->save_TV_FILTER_CTL_1 = INREG(TV_FILTER_CTL_1);
+	dev_priv->save_TV_FILTER_CTL_2 = INREG(TV_FILTER_CTL_2);
+	dev_priv->save_TV_FILTER_CTL_3 = INREG(TV_FILTER_CTL_3);
+
+	for (i = 0; i < 60; i++)
+		dev_priv->save_TV_H_LUMA[i] = INREG(TV_H_LUMA_0 + (i <<2));
+	for (i = 0; i < 60; i++)
+		dev_priv->save_TV_H_CHROMA[i] = INREG(TV_H_CHROMA_0 + (i <<2));
+	for (i = 0; i < 43; i++)
+		dev_priv->save_TV_V_LUMA[i] = INREG(TV_V_LUMA_0 + (i <<2));
+	for (i = 0; i < 43; i++)
+		dev_priv->save_TV_V_CHROMA[i] = INREG(TV_V_CHROMA_0 + (i <<2));
 
-    dev_priv->save_TV_DAC = INREG(TV_DAC);
-    dev_priv->save_TV_CTL = INREG(TV_CTL);
+	dev_priv->save_TV_DAC = INREG(TV_DAC);
+	dev_priv->save_TV_CTL = INREG(TV_CTL);
 }
 
 static void
 i830_tv_restore(xf86OutputPtr output)
 {
-    ScrnInfoPtr		    pScrn = output->scrn;
-    I830Ptr		    pI830 = I830PTR(pScrn);
-    I830OutputPrivatePtr    intel_output = output->driver_private;
-    struct i830_tv_priv	    *dev_priv = intel_output->dev_priv;
-    int			    i;
-
-    OUTREG(TV_H_CTL_1, dev_priv->save_TV_H_CTL_1);
-    OUTREG(TV_H_CTL_2, dev_priv->save_TV_H_CTL_2);
-    OUTREG(TV_H_CTL_3, dev_priv->save_TV_H_CTL_3);
-    OUTREG(TV_V_CTL_1, dev_priv->save_TV_V_CTL_1);
-    OUTREG(TV_V_CTL_2, dev_priv->save_TV_V_CTL_2);
-    OUTREG(TV_V_CTL_3, dev_priv->save_TV_V_CTL_3);
-    OUTREG(TV_V_CTL_4, dev_priv->save_TV_V_CTL_4);
-    OUTREG(TV_V_CTL_5, dev_priv->save_TV_V_CTL_5);
-    OUTREG(TV_V_CTL_6, dev_priv->save_TV_V_CTL_6);
-    OUTREG(TV_V_CTL_7, dev_priv->save_TV_V_CTL_7);
-    OUTREG(TV_SC_CTL_1, dev_priv->save_TV_SC_CTL_1);
-    OUTREG(TV_SC_CTL_2, dev_priv->save_TV_SC_CTL_2);
-    OUTREG(TV_SC_CTL_3, dev_priv->save_TV_SC_CTL_3);
-
-    OUTREG(TV_CSC_Y, dev_priv->save_TV_CSC_Y);
-    OUTREG(TV_CSC_Y2, dev_priv->save_TV_CSC_Y2);
-    OUTREG(TV_CSC_U, dev_priv->save_TV_CSC_U);
-    OUTREG(TV_CSC_U2, dev_priv->save_TV_CSC_U2);
-    OUTREG(TV_CSC_V, dev_priv->save_TV_CSC_V);
-    OUTREG(TV_CSC_V2, dev_priv->save_TV_CSC_V2);
-    OUTREG(TV_CLR_KNOBS, dev_priv->save_TV_CLR_KNOBS);
-    OUTREG(TV_CLR_LEVEL, dev_priv->save_TV_CLR_LEVEL);
-    OUTREG(TV_WIN_POS, dev_priv->save_TV_WIN_POS);
-    OUTREG(TV_WIN_SIZE, dev_priv->save_TV_WIN_SIZE);
-    OUTREG(TV_FILTER_CTL_1, dev_priv->save_TV_FILTER_CTL_1);
-    OUTREG(TV_FILTER_CTL_2, dev_priv->save_TV_FILTER_CTL_2);
-    OUTREG(TV_FILTER_CTL_3, dev_priv->save_TV_FILTER_CTL_3);
-
-    for (i = 0; i < 60; i++)
-	OUTREG(TV_H_LUMA_0 + (i <<2), dev_priv->save_TV_H_LUMA[i]);
-    for (i = 0; i < 60; i++)
-	OUTREG(TV_H_CHROMA_0 + (i <<2), dev_priv->save_TV_H_CHROMA[i]);
-    for (i = 0; i < 43; i++)
-	OUTREG(TV_V_LUMA_0 + (i <<2), dev_priv->save_TV_V_LUMA[i]);
-    for (i = 0; i < 43; i++)
-	OUTREG(TV_V_CHROMA_0 + (i <<2), dev_priv->save_TV_V_CHROMA[i]);
+	ScrnInfoPtr		    pScrn = output->scrn;
+	I830Ptr		    pI830 = I830PTR(pScrn);
+	I830OutputPrivatePtr    intel_output = output->driver_private;
+	struct i830_tv_priv	    *dev_priv = intel_output->dev_priv;
+	int			    i;
+
+	OUTREG(TV_H_CTL_1, dev_priv->save_TV_H_CTL_1);
+	OUTREG(TV_H_CTL_2, dev_priv->save_TV_H_CTL_2);
+	OUTREG(TV_H_CTL_3, dev_priv->save_TV_H_CTL_3);
+	OUTREG(TV_V_CTL_1, dev_priv->save_TV_V_CTL_1);
+	OUTREG(TV_V_CTL_2, dev_priv->save_TV_V_CTL_2);
+	OUTREG(TV_V_CTL_3, dev_priv->save_TV_V_CTL_3);
+	OUTREG(TV_V_CTL_4, dev_priv->save_TV_V_CTL_4);
+	OUTREG(TV_V_CTL_5, dev_priv->save_TV_V_CTL_5);
+	OUTREG(TV_V_CTL_6, dev_priv->save_TV_V_CTL_6);
+	OUTREG(TV_V_CTL_7, dev_priv->save_TV_V_CTL_7);
+	OUTREG(TV_SC_CTL_1, dev_priv->save_TV_SC_CTL_1);
+	OUTREG(TV_SC_CTL_2, dev_priv->save_TV_SC_CTL_2);
+	OUTREG(TV_SC_CTL_3, dev_priv->save_TV_SC_CTL_3);
+
+	OUTREG(TV_CSC_Y, dev_priv->save_TV_CSC_Y);
+	OUTREG(TV_CSC_Y2, dev_priv->save_TV_CSC_Y2);
+	OUTREG(TV_CSC_U, dev_priv->save_TV_CSC_U);
+	OUTREG(TV_CSC_U2, dev_priv->save_TV_CSC_U2);
+	OUTREG(TV_CSC_V, dev_priv->save_TV_CSC_V);
+	OUTREG(TV_CSC_V2, dev_priv->save_TV_CSC_V2);
+	OUTREG(TV_CLR_KNOBS, dev_priv->save_TV_CLR_KNOBS);
+	OUTREG(TV_CLR_LEVEL, dev_priv->save_TV_CLR_LEVEL);
+
+	{
+		xf86CrtcPtr	    crtc = output->crtc;
+		I830CrtcPrivatePtr	    intel_crtc = crtc->driver_private;
+		int pipeconf_reg = (intel_crtc->pipe == 0)?PIPEACONF:PIPEBCONF;
+		int dspcntr_reg = (intel_crtc->pipe == 0)?DSPACNTR : DSPBCNTR;
+		int pipeconf = INREG(pipeconf_reg);
+		int dspcntr = INREG(dspcntr_reg);
+		int dspbase_reg = (intel_crtc->pipe == 0) ? DSPABASE : DSPBBASE;
+		/* Pipe must be off here */
+		OUTREG(dspcntr_reg, dspcntr & ~DISPLAY_PLANE_ENABLE);
+		/* Flush the plane changes */
+		OUTREG(dspbase_reg, INREG(dspbase_reg));
+
+		if (!IS_I9XX(pI830)) {
+			/* Wait for vblank for the disable to take effect */
+			i830WaitForVblank(pScrn);
+		}
+
+		OUTREG(pipeconf_reg, pipeconf & ~PIPEACONF_ENABLE);
+		/* Wait for vblank for the disable to take effect. */
+		i830WaitForVblank(pScrn);
+
+		/* Filter ctl must be set before TV_WIN_SIZE and TV_WIN_POS */
+		OUTREG(TV_FILTER_CTL_1, dev_priv->save_TV_FILTER_CTL_1);
+		OUTREG(TV_FILTER_CTL_2, dev_priv->save_TV_FILTER_CTL_2);
+		OUTREG(TV_FILTER_CTL_3, dev_priv->save_TV_FILTER_CTL_3);
+		OUTREG(TV_WIN_POS, dev_priv->save_TV_WIN_POS);
+		OUTREG(TV_WIN_SIZE, dev_priv->save_TV_WIN_SIZE);
+		OUTREG(pipeconf_reg, pipeconf);
+		OUTREG(dspcntr_reg, dspcntr);
+		/* Flush the plane changes */
+		OUTREG(dspbase_reg, INREG(dspbase_reg));
+	}
+
+	for (i = 0; i < 60; i++)
+		OUTREG(TV_H_LUMA_0 + (i <<2), dev_priv->save_TV_H_LUMA[i]);
+	for (i = 0; i < 60; i++)
+		OUTREG(TV_H_CHROMA_0 + (i <<2), dev_priv->save_TV_H_CHROMA[i]);
+	for (i = 0; i < 43; i++)
+		OUTREG(TV_V_LUMA_0 + (i <<2), dev_priv->save_TV_V_LUMA[i]);
+	for (i = 0; i < 43; i++)
+		OUTREG(TV_V_CHROMA_0 + (i <<2), dev_priv->save_TV_V_CHROMA[i]);
 
-    OUTREG(TV_DAC, dev_priv->save_TV_DAC);
-    OUTREG(TV_CTL, dev_priv->save_TV_CTL);
+	OUTREG(TV_DAC, dev_priv->save_TV_DAC);
+	OUTREG(TV_CTL, dev_priv->save_TV_CTL);
 }
 
 static int
 i830_tv_mode_valid(xf86OutputPtr output, DisplayModePtr pMode)
 {
-    return MODE_OK;
+	return MODE_OK;
 }
 
-static const CARD32 h_luma[60] = {
-    0xB1403000, 0x2E203500, 0x35002E20, 0x3000B140,
-    0x35A0B160, 0x2DC02E80, 0xB1403480, 0xB1603000,
-    0x2EA03640, 0x34002D80, 0x3000B120, 0x36E0B160,
-    0x2D202EF0, 0xB1203380, 0xB1603000, 0x2F303780,
-    0x33002CC0, 0x3000B100, 0x3820B160, 0x2C802F50,
-    0xB10032A0, 0xB1603000, 0x2F9038C0, 0x32202C20,
-    0x3000B0E0, 0x3980B160, 0x2BC02FC0, 0xB0E031C0,
-    0xB1603000, 0x2FF03A20, 0x31602B60, 0xB020B0C0,
-    0x3AE0B160, 0x2B001810, 0xB0C03120, 0xB140B020,
-    0x18283BA0, 0x30C02A80, 0xB020B0A0, 0x3C60B140,
-    0x2A201838, 0xB0A03080, 0xB120B020, 0x18383D20,
-    0x304029C0, 0xB040B080, 0x3DE0B100, 0x29601848,
-    0xB0803000, 0xB100B040, 0x18483EC0, 0xB0402900,
-    0xB040B060, 0x3F80B0C0, 0x28801858, 0xB060B080,
-    0xB0A0B060, 0x18602820, 0xB0A02820, 0x0000B060,
-};
-
-static const CARD32 h_chroma[60] = {
-    0xB1403000, 0x2E203500, 0x35002E20, 0x3000B140,
-    0x35A0B160, 0x2DC02E80, 0xB1403480, 0xB1603000,
-    0x2EA03640, 0x34002D80, 0x3000B120, 0x36E0B160,
-    0x2D202EF0, 0xB1203380, 0xB1603000, 0x2F303780,
-    0x33002CC0, 0x3000B100, 0x3820B160, 0x2C802F50,
-    0xB10032A0, 0xB1603000, 0x2F9038C0, 0x32202C20,
-    0x3000B0E0, 0x3980B160, 0x2BC02FC0, 0xB0E031C0,
-    0xB1603000, 0x2FF03A20, 0x31602B60, 0xB020B0C0,
-    0x3AE0B160, 0x2B001810, 0xB0C03120, 0xB140B020,
-    0x18283BA0, 0x30C02A80, 0xB020B0A0, 0x3C60B140,
-    0x2A201838, 0xB0A03080, 0xB120B020, 0x18383D20,
-    0x304029C0, 0xB040B080, 0x3DE0B100, 0x29601848,
-    0xB0803000, 0xB100B040, 0x18483EC0, 0xB0402900,
-    0xB040B060, 0x3F80B0C0, 0x28801858, 0xB060B080,
-    0xB0A0B060, 0x18602820, 0xB0A02820, 0x0000B060,
-};
-
-static const CARD32 v_luma[43] = {
-    0x36403000, 0x2D002CC0, 0x30003640, 0x2D0036C0,
-    0x35C02CC0, 0x37403000, 0x2C802D40, 0x30003540,
-    0x2D8037C0, 0x34C02C40, 0x38403000, 0x2BC02E00,
-    0x30003440, 0x2E2038C0, 0x34002B80, 0x39803000,
-    0x2B402E40, 0x30003380, 0x2E603A00, 0x33402B00,
-    0x3A803040, 0x2A802EA0, 0x30403300, 0x2EC03B40,
-    0x32802A40, 0x3C003040, 0x2A002EC0, 0x30803240,
-    0x2EC03C80, 0x320029C0, 0x3D403080, 0x29402F00,
-    0x308031C0, 0x2F203DC0, 0x31802900, 0x3E8030C0,
-    0x28802F40, 0x30C03140, 0x2F203F40, 0x31402840,
-    0x28003100, 0x28002F00, 0x00003100,
-};
-
-static const CARD32 v_chroma[43] = {
-    0x36403000, 0x2D002CC0, 0x30003640, 0x2D0036C0,
-    0x35C02CC0, 0x37403000, 0x2C802D40, 0x30003540,
-    0x2D8037C0, 0x34C02C40, 0x38403000, 0x2BC02E00,
-    0x30003440, 0x2E2038C0, 0x34002B80, 0x39803000,
-    0x2B402E40, 0x30003380, 0x2E603A00, 0x33402B00,
-    0x3A803040, 0x2A802EA0, 0x30403300, 0x2EC03B40,
-    0x32802A40, 0x3C003040, 0x2A002EC0, 0x30803240,
-    0x2EC03C80, 0x320029C0, 0x3D403080, 0x29402F00,
-    0x308031C0, 0x2F203DC0, 0x31802900, 0x3E8030C0,
-    0x28802F40, 0x30C03140, 0x2F203F40, 0x31402840,
-    0x28003100, 0x28002F00, 0x00003100,
-};
 
 static Bool
 i830_tv_mode_fixup(xf86OutputPtr output, DisplayModePtr mode,
-		 DisplayModePtr adjusted_mode)
+		DisplayModePtr adjusted_mode)
 {
-    ScrnInfoPtr pScrn = output->scrn;
-    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
-    int i;
-
-    for (i = 0; i < xf86_config->num_output; i++) {
-	xf86OutputPtr other_output = xf86_config->output[i];
-
-	if (other_output != output && other_output->crtc == output->crtc) {
-	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
-		       "Can't enable TV and another output on the same "
-		       "pipe\n");
-	    return FALSE;
+	ScrnInfoPtr pScrn = output->scrn;
+	xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+	int i;
+
+	for (i = 0; i < xf86_config->num_output; i++) {
+		xf86OutputPtr other_output = xf86_config->output[i];
+
+		if (other_output != output && other_output->crtc == output->crtc) {
+			xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+					"Can't enable TV and another output on the same "
+					"pipe\n");
+			return FALSE;
+		}
 	}
-    }
 
-    /* XXX: fill me in */
+	/* XXX: fill me in */
 
-    return TRUE;
+	return TRUE;
 }
 
 static CARD32
 i830_float_to_csc (float fin)
 {
-    CARD32  exp;
-    CARD32  mant;
-    CARD32  ret;
-    float   f = fin;
-    
-    /* somehow the color conversion knows the signs of all the values */
-    if (f < 0) f = -f;
-    
-    if (f >= 1)
-    {
-	exp = 0x7;
-	mant = 1 << 8;
-    }
-    else
-    {
-	for (exp = 0; exp < 3 && f < 0.5; exp++)
-	    f *= 2.0;
-	mant = (f * (1 << 9) + 0.5);
-	if (mant >= (1 << 9))
-	    mant = (1 << 9) - 1;
-    }
-    ret = (exp << 9) | mant;
-    return ret;
+	CARD32  exp;
+	CARD32  mant;
+	CARD32  ret;
+	float   f = fin;
+
+	/* somehow the color conversion knows the signs of all the values */
+	if (f < 0) f = -f;
+
+	if (f >= 1)
+	{
+		exp = 0x7;
+		mant = 1 << 8;
+	}
+	else
+	{
+		for (exp = 0; exp < 3 && f < 0.5; exp++)
+			f *= 2.0;
+		mant = (f * (1 << 9) + 0.5);
+		if (mant >= (1 << 9))
+			mant = (1 << 9) - 1;
+	}
+	ret = (exp << 9) | mant;
+	return ret;
 }
 
 static CARD16
 i830_float_to_luma (float f)
 {
-    CARD16  ret;
+	CARD16  ret;
 
-    ret = (f * (1 << 9));
-    return ret;
+	ret = (f * (1 << 9));
+	return ret;
 }
 
 static void
 i830_tv_mode_set(xf86OutputPtr output, DisplayModePtr mode,
-		 DisplayModePtr adjusted_mode)
+		DisplayModePtr adjusted_mode)
 {
-    ScrnInfoPtr		    pScrn = output->scrn;
-    I830Ptr		    pI830 = I830PTR(pScrn);
-    xf86CrtcPtr	    crtc = output->crtc;
-    I830OutputPrivatePtr    intel_output = output->driver_private;
-    I830CrtcPrivatePtr	    intel_crtc = crtc->driver_private;
-    struct i830_tv_priv	    *dev_priv = intel_output->dev_priv;
-    const tv_mode_t	    *tv_mode;
-    CARD32		    tv_ctl;
-    CARD32		    hctl1, hctl2, hctl3;
-    CARD32		    vctl1, vctl2, vctl3, vctl4, vctl5, vctl6, vctl7;
-    CARD32		    scctl1, scctl2, scctl3;
-    int			    i;
-    const video_levels_t	*video_levels;
-    const color_conversion_t	*color_conversion;
-    Bool		    burst_ena;
-
-    /* Need to actually choose or construct the appropriate
-     * mode.  For now, just set the first one in the list, with
-     * NTSC format.
-     */
-	
-    for (i = 0; i < sizeof(tv_modes) / sizeof (tv_modes[0]); i++) {
-	    tv_mode = &tv_modes[i];
-	    if (strstr(mode->name, tv_mode->name)) 
-		    break;	
-    }
-    
-    tv_ctl = 0;
-
-    switch (dev_priv->type) {
-    default:
-    case TV_TYPE_UNKNOWN:
-    case TV_TYPE_COMPOSITE:
-	tv_ctl |= TV_ENC_OUTPUT_COMPOSITE;
-	video_levels = &tv_mode->composite_levels;
-	color_conversion = &tv_mode->composite_color;
-	burst_ena = tv_mode->burst_ena;
-	break;
-    case TV_TYPE_COMPONENT:
-	tv_ctl |= TV_ENC_OUTPUT_COMPONENT;
-	video_levels = &component_level;
-	if (tv_mode->burst_ena)
-	    color_conversion = &sdtv_component_color;
-	else
-	    color_conversion = &hdtv_component_color;
-	burst_ena = FALSE;
-	break;
-    case TV_TYPE_SVIDEO:
-	tv_ctl |= TV_ENC_OUTPUT_SVIDEO;
-	video_levels = &tv_mode->svideo_levels;
-	color_conversion = &tv_mode->svideo_color;
-	burst_ena = tv_mode->burst_ena;
-	break;
-    }
-    hctl1 = (tv_mode->hsync_end << TV_HSYNC_END_SHIFT) |
-	(tv_mode->htotal << TV_HTOTAL_SHIFT);
+	ScrnInfoPtr		    pScrn = output->scrn;
+	I830Ptr		    pI830 = I830PTR(pScrn);
+	xf86CrtcPtr	    crtc = output->crtc;
+	I830OutputPrivatePtr    intel_output = output->driver_private;
+	I830CrtcPrivatePtr	    intel_crtc = crtc->driver_private;
+	struct i830_tv_priv	    *dev_priv = intel_output->dev_priv;
+	const tv_mode_t	    *tv_mode;
+	CARD32		    tv_ctl;
+	CARD32		    hctl1, hctl2, hctl3;
+	CARD32		    vctl1, vctl2, vctl3, vctl4, vctl5, vctl6, vctl7;
+	CARD32		    scctl1, scctl2, scctl3;
+	int			    i, j;
+	const video_levels_t	*video_levels;
+	const color_conversion_t	*color_conversion;
+	Bool		    burst_ena;
+
+	for (i = 0; i < sizeof(tv_modes) / sizeof (tv_modes[0]); i++) {
+		tv_mode = &tv_modes[i];
+		if (strstr(mode->name, tv_mode->name)) 
+			break;	
+	}
 
-    hctl2 = (tv_mode->hburst_start << 16) |
-	(tv_mode->hburst_len << TV_HBURST_LEN_SHIFT);
-    if (burst_ena)
-	hctl2 |= TV_BURST_ENA;
-
-    hctl3 = (tv_mode->hblank_start << TV_HBLANK_START_SHIFT) |
-	(tv_mode->hblank_end << TV_HBLANK_END_SHIFT);
-
-    vctl1 = (tv_mode->nbr_end << TV_NBR_END_SHIFT) |
-	(tv_mode->vi_end_f1 << TV_VI_END_F1_SHIFT) |
-	(tv_mode->vi_end_f2 << TV_VI_END_F2_SHIFT);
-
-    vctl2 = (tv_mode->vsync_len << TV_VSYNC_LEN_SHIFT) |
-	(tv_mode->vsync_start_f1 << TV_VSYNC_START_F1_SHIFT) |
-	(tv_mode->vsync_start_f2 << TV_VSYNC_START_F2_SHIFT);
-
-    vctl3 = (tv_mode->veq_len << TV_VEQ_LEN_SHIFT) |
-	(tv_mode->veq_start_f1 << TV_VEQ_START_F1_SHIFT) |
-	(tv_mode->veq_start_f2 << TV_VEQ_START_F2_SHIFT);
-    if (tv_mode->veq_ena)
-	vctl3 |= TV_EQUAL_ENA;
-
-    vctl4 = (tv_mode->vburst_start_f1 << TV_VBURST_START_F1_SHIFT) |
-	(tv_mode->vburst_end_f1 << TV_VBURST_END_F1_SHIFT);
-
-    vctl5 = (tv_mode->vburst_start_f2 << TV_VBURST_START_F2_SHIFT) |
-	(tv_mode->vburst_end_f2 << TV_VBURST_END_F2_SHIFT);
-
-    vctl6 = (tv_mode->vburst_start_f3 << TV_VBURST_START_F3_SHIFT) |
-	(tv_mode->vburst_end_f3 << TV_VBURST_END_F3_SHIFT);
-
-    vctl7 = (tv_mode->vburst_start_f4 << TV_VBURST_START_F4_SHIFT) |
-	(tv_mode->vburst_end_f4 << TV_VBURST_END_F4_SHIFT);
-
-    if (intel_crtc->pipe == 1)
-	tv_ctl |= TV_ENC_PIPEB_SELECT;
-    tv_ctl |= tv_mode->oversample;
-
-    if (tv_mode->progressive)
-	tv_ctl |= TV_PROGRESSIVE;
-    if (tv_mode->trilevel_sync)
-	tv_ctl |= TV_TRILEVEL_SYNC;
-    if (tv_mode->pal_burst)
-	tv_ctl |= TV_PAL_BURST;
-    if (tv_mode->oversample == TV_OVERSAMPLE_8X)
-	    scctl1 = TV_SC_DDA1_EN;
+	tv_ctl = 0;
 
-    if (tv_mode->dda2_inc)
-	scctl1 |= TV_SC_DDA2_EN;
-    
-    if (tv_mode->dda3_inc)
-	scctl1 |= TV_SC_DDA3_EN;
-    
-    scctl1 |= tv_mode->sc_reset;
-    scctl1 |= video_levels->burst << TV_BURST_LEVEL_SHIFT;
-    scctl1 |= tv_mode->dda1_inc << TV_SCDDA1_INC_SHIFT;
-
-    scctl2 = tv_mode->dda2_size << TV_SCDDA2_SIZE_SHIFT |
-	tv_mode->dda2_inc << TV_SCDDA2_INC_SHIFT;
-
-    scctl3 = tv_mode->dda3_size << TV_SCDDA3_SIZE_SHIFT |
-	tv_mode->dda3_inc << TV_SCDDA3_INC_SHIFT;
-
-    /* Enable two fixes for the chips that need them. */
-    if (pI830->PciInfo->chipType < PCI_CHIP_I945_G)
-	tv_ctl |= TV_ENC_C0_FIX | TV_ENC_SDP_FIX;
-
-
-    OUTREG(TV_H_CTL_1, hctl1);
-    OUTREG(TV_H_CTL_2, hctl2);
-    OUTREG(TV_H_CTL_3, hctl3);
-    OUTREG(TV_V_CTL_1, vctl1);
-    OUTREG(TV_V_CTL_2, vctl2);
-    OUTREG(TV_V_CTL_3, vctl3);
-    OUTREG(TV_V_CTL_4, vctl4);
-    OUTREG(TV_V_CTL_5, vctl5);
-    OUTREG(TV_V_CTL_6, vctl6);
-    OUTREG(TV_V_CTL_7, vctl7);
-    OUTREG(TV_SC_CTL_1, scctl1);
-    OUTREG(TV_SC_CTL_2, scctl2);
-    OUTREG(TV_SC_CTL_3, scctl3);
-    
-    OUTREG(TV_CSC_Y,
-	   (i830_float_to_csc(color_conversion->ry) << 16) |
-	   (i830_float_to_csc(color_conversion->gy)));
-    OUTREG(TV_CSC_Y2,
-	    (i830_float_to_csc(color_conversion->by) << 16) |
-	    (i830_float_to_luma(color_conversion->ay)));
-	   
-    OUTREG(TV_CSC_U,
-	   (i830_float_to_csc(color_conversion->ru) << 16) |
-	   (i830_float_to_csc(color_conversion->gu)));
-
-    OUTREG(TV_CSC_U2,
-	    (i830_float_to_csc(color_conversion->bu) << 16) |
-	    (i830_float_to_luma(color_conversion->au)));
-	   
-    OUTREG(TV_CSC_V,
-	   (i830_float_to_csc(color_conversion->rv) << 16) |
-	   (i830_float_to_csc(color_conversion->gv)));
-
-    OUTREG(TV_CSC_V2,
-	    (i830_float_to_csc(color_conversion->bv) << 16) |
-	    (i830_float_to_luma(color_conversion->av)));
-	   
-    OUTREG(TV_CLR_KNOBS, 0x00606000);
-    OUTREG(TV_CLR_LEVEL, ((video_levels->black << TV_BLACK_LEVEL_SHIFT) |
-			  (video_levels->blank << TV_BLANK_LEVEL_SHIFT)));
-    {
-	int pipeconf_reg = (intel_crtc->pipe == 0)?PIPEACONF:PIPEBCONF;
-        int dspcntr_reg = (intel_crtc->pipe == 0)?DSPACNTR : DSPBCNTR;
-	int pipeconf = INREG(pipeconf_reg);
-	int dspcntr = INREG(dspcntr_reg);
-	int dspbase_reg = (intel_crtc->pipe == 0) ? DSPABASE : DSPBBASE;
-	int xpos = 0x0, ypos = 0x0;
-	unsigned int xsize, ysize;
-	/* Pipe must be off here */
-	OUTREG(dspcntr_reg, dspcntr & ~DISPLAY_PLANE_ENABLE);
-	/* Flush the plane changes */
-	OUTREG(dspbase_reg, INREG(dspbase_reg));
-
-	if (!IS_I9XX(pI830)) {
-            /* Wait for vblank for the disable to take effect */
-            i830WaitForVblank(pScrn);
-        }
-
-	OUTREG(pipeconf_reg, pipeconf & ~PIPEACONF_ENABLE);
-	/* Wait for vblank for the disable to take effect. */
-        i830WaitForVblank(pScrn);
+	switch (dev_priv->type) {
+		default:
+		case TV_TYPE_UNKNOWN:
+		case TV_TYPE_COMPOSITE:
+			tv_ctl |= TV_ENC_OUTPUT_COMPOSITE;
+			video_levels = &tv_mode->composite_levels;
+			color_conversion = &tv_mode->composite_color;
+			burst_ena = tv_mode->burst_ena;
+			break;
+		case TV_TYPE_COMPONENT:
+			tv_ctl |= TV_ENC_OUTPUT_COMPONENT;
+			video_levels = &component_level;
+			if (tv_mode->burst_ena)
+				color_conversion = &sdtv_component_color;
+			else
+				color_conversion = &hdtv_component_color;
+			burst_ena = FALSE;
+			break;
+		case TV_TYPE_SVIDEO:
+			tv_ctl |= TV_ENC_OUTPUT_SVIDEO;
+			video_levels = &tv_mode->svideo_levels;
+			color_conversion = &tv_mode->svideo_color;
+			burst_ena = tv_mode->burst_ena;
+			break;
+	}
+	hctl1 = (tv_mode->hsync_end << TV_HSYNC_END_SHIFT) |
+		(tv_mode->htotal << TV_HTOTAL_SHIFT);
 
-	/* Filter ctl must be set before TV_WIN_SIZE and TV_WIN_POS */
-    	OUTREG(TV_FILTER_CTL_1, TV_AUTO_SCALE);
+	hctl2 = (tv_mode->hburst_start << 16) |
+		(tv_mode->hburst_len << TV_HBURST_LEN_SHIFT);
+	if (burst_ena)
+		hctl2 |= TV_BURST_ENA;
+
+	hctl3 = (tv_mode->hblank_start << TV_HBLANK_START_SHIFT) |
+		(tv_mode->hblank_end << TV_HBLANK_END_SHIFT);
+
+	vctl1 = (tv_mode->nbr_end << TV_NBR_END_SHIFT) |
+		(tv_mode->vi_end_f1 << TV_VI_END_F1_SHIFT) |
+		(tv_mode->vi_end_f2 << TV_VI_END_F2_SHIFT);
+
+	vctl2 = (tv_mode->vsync_len << TV_VSYNC_LEN_SHIFT) |
+		(tv_mode->vsync_start_f1 << TV_VSYNC_START_F1_SHIFT) |
+		(tv_mode->vsync_start_f2 << TV_VSYNC_START_F2_SHIFT);
+
+	vctl3 = (tv_mode->veq_len << TV_VEQ_LEN_SHIFT) |
+		(tv_mode->veq_start_f1 << TV_VEQ_START_F1_SHIFT) |
+		(tv_mode->veq_start_f2 << TV_VEQ_START_F2_SHIFT);
+	if (tv_mode->veq_ena)
+		vctl3 |= TV_EQUAL_ENA;
+
+	vctl4 = (tv_mode->vburst_start_f1 << TV_VBURST_START_F1_SHIFT) |
+		(tv_mode->vburst_end_f1 << TV_VBURST_END_F1_SHIFT);
+
+	vctl5 = (tv_mode->vburst_start_f2 << TV_VBURST_START_F2_SHIFT) |
+		(tv_mode->vburst_end_f2 << TV_VBURST_END_F2_SHIFT);
+
+	vctl6 = (tv_mode->vburst_start_f3 << TV_VBURST_START_F3_SHIFT) |
+		(tv_mode->vburst_end_f3 << TV_VBURST_END_F3_SHIFT);
+
+	vctl7 = (tv_mode->vburst_start_f4 << TV_VBURST_START_F4_SHIFT) |
+		(tv_mode->vburst_end_f4 << TV_VBURST_END_F4_SHIFT);
+
+	if (intel_crtc->pipe == 1)
+		tv_ctl |= TV_ENC_PIPEB_SELECT;
+	tv_ctl |= tv_mode->oversample;
 
-	xsize = tv_mode->hblank_start - tv_mode->hblank_end;
 	if (tv_mode->progressive)
-		ysize = tv_mode->nbr_end + 1;
-	else
-		ysize = 2*tv_mode->nbr_end + 1;
-
-	OUTREG(TV_WIN_POS, (xpos<<16)|ypos);
-	OUTREG(TV_WIN_SIZE, (xsize<<16)|ysize);
-
-	OUTREG(pipeconf_reg, pipeconf);
-	OUTREG(dspcntr_reg, dspcntr);
-        /* Flush the plane changes */
-        OUTREG(dspbase_reg, INREG(dspbase_reg));
-
-    } 	
-    
-    for (i = 0; i < 60; i++)
-	OUTREG(TV_H_LUMA_0 + (i <<2), h_luma[i]);
-    for (i = 0; i < 60; i++)
-	OUTREG(TV_H_CHROMA_0 + (i <<2), h_chroma[i]);
-    for (i = 0; i < 43; i++)
-	OUTREG(TV_V_LUMA_0 + (i <<2), v_luma[i]);
-    for (i = 0; i < 43; i++)
-	OUTREG(TV_V_CHROMA_0 + (i <<2), v_chroma[i]);
-
-    OUTREG(TV_DAC, 0);
-    OUTREG(TV_CTL, tv_ctl);
+		tv_ctl |= TV_PROGRESSIVE;
+	if (tv_mode->trilevel_sync)
+		tv_ctl |= TV_TRILEVEL_SYNC;
+	if (tv_mode->pal_burst)
+		tv_ctl |= TV_PAL_BURST;
+	if (tv_mode->oversample == TV_OVERSAMPLE_8X)
+		scctl1 = TV_SC_DDA1_EN;
+
+	if (tv_mode->dda2_inc)
+		scctl1 |= TV_SC_DDA2_EN;
+
+	if (tv_mode->dda3_inc)
+		scctl1 |= TV_SC_DDA3_EN;
+
+	scctl1 |= tv_mode->sc_reset;
+	scctl1 |= video_levels->burst << TV_BURST_LEVEL_SHIFT;
+	scctl1 |= tv_mode->dda1_inc << TV_SCDDA1_INC_SHIFT;
+
+	scctl2 = tv_mode->dda2_size << TV_SCDDA2_SIZE_SHIFT |
+		tv_mode->dda2_inc << TV_SCDDA2_INC_SHIFT;
+
+	scctl3 = tv_mode->dda3_size << TV_SCDDA3_SIZE_SHIFT |
+		tv_mode->dda3_inc << TV_SCDDA3_INC_SHIFT;
+
+	/* Enable two fixes for the chips that need them. */
+	if (pI830->PciInfo->chipType < PCI_CHIP_I945_G)
+		tv_ctl |= TV_ENC_C0_FIX | TV_ENC_SDP_FIX;
+
+
+	OUTREG(TV_H_CTL_1, hctl1);
+	OUTREG(TV_H_CTL_2, hctl2);
+	OUTREG(TV_H_CTL_3, hctl3);
+	OUTREG(TV_V_CTL_1, vctl1);
+	OUTREG(TV_V_CTL_2, vctl2);
+	OUTREG(TV_V_CTL_3, vctl3);
+	OUTREG(TV_V_CTL_4, vctl4);
+	OUTREG(TV_V_CTL_5, vctl5);
+	OUTREG(TV_V_CTL_6, vctl6);
+	OUTREG(TV_V_CTL_7, vctl7);
+	OUTREG(TV_SC_CTL_1, scctl1);
+	OUTREG(TV_SC_CTL_2, scctl2);
+	OUTREG(TV_SC_CTL_3, scctl3);
+
+	OUTREG(TV_CSC_Y,
+			(i830_float_to_csc(color_conversion->ry) << 16) |
+			(i830_float_to_csc(color_conversion->gy)));
+	OUTREG(TV_CSC_Y2,
+			(i830_float_to_csc(color_conversion->by) << 16) |
+			(i830_float_to_luma(color_conversion->ay)));
+
+	OUTREG(TV_CSC_U,
+			(i830_float_to_csc(color_conversion->ru) << 16) |
+			(i830_float_to_csc(color_conversion->gu)));
+
+	OUTREG(TV_CSC_U2,
+			(i830_float_to_csc(color_conversion->bu) << 16) |
+			(i830_float_to_luma(color_conversion->au)));
+
+	OUTREG(TV_CSC_V,
+			(i830_float_to_csc(color_conversion->rv) << 16) |
+			(i830_float_to_csc(color_conversion->gv)));
+
+	OUTREG(TV_CSC_V2,
+			(i830_float_to_csc(color_conversion->bv) << 16) |
+			(i830_float_to_luma(color_conversion->av)));
+
+	OUTREG(TV_CLR_KNOBS, 0x10606000);
+	OUTREG(TV_CLR_LEVEL, ((video_levels->black << TV_BLACK_LEVEL_SHIFT) |
+				(video_levels->blank << TV_BLANK_LEVEL_SHIFT)));
+	{
+		int pipeconf_reg = (intel_crtc->pipe == 0)?PIPEACONF:PIPEBCONF;
+		int dspcntr_reg = (intel_crtc->pipe == 0)?DSPACNTR : DSPBCNTR;
+		int pipeconf = INREG(pipeconf_reg);
+		int dspcntr = INREG(dspcntr_reg);
+		int dspbase_reg = (intel_crtc->pipe == 0) ? DSPABASE : DSPBBASE;
+		int xpos = 0x0, ypos = 0x0;
+		unsigned int xsize, ysize;
+		/* Pipe must be off here */
+		OUTREG(dspcntr_reg, dspcntr & ~DISPLAY_PLANE_ENABLE);
+		/* Flush the plane changes */
+		OUTREG(dspbase_reg, INREG(dspbase_reg));
+
+		if (!IS_I9XX(pI830)) {
+			/* Wait for vblank for the disable to take effect */
+			i830WaitForVblank(pScrn);
+		}
+
+		OUTREG(pipeconf_reg, pipeconf & ~PIPEACONF_ENABLE);
+		/* Wait for vblank for the disable to take effect. */
+		i830WaitForVblank(pScrn);
+
+		/* Filter ctl must be set before TV_WIN_SIZE and TV_WIN_POS */
+		OUTREG(TV_FILTER_CTL_1, TV_AUTO_SCALE);
+
+		xsize = tv_mode->hblank_start - tv_mode->hblank_end;
+		if (tv_mode->progressive)
+			ysize = tv_mode->nbr_end + 1;
+		else
+			ysize = 2*tv_mode->nbr_end + 1;
+
+		OUTREG(TV_WIN_POS, (xpos<<16)|ypos);
+		OUTREG(TV_WIN_SIZE, (xsize<<16)|ysize);
+
+		OUTREG(pipeconf_reg, pipeconf);
+		OUTREG(dspcntr_reg, dspcntr);
+		/* Flush the plane changes */
+		OUTREG(dspbase_reg, INREG(dspbase_reg));
+	} 	
+
+	j = 0;
+	for (i = 0; i < 60; i++)
+		OUTREG(TV_H_LUMA_0 + (i<<2), tv_mode->filter_table[j++]);
+	for (i = 0; i < 60; i++)
+		OUTREG(TV_H_CHROMA_0 + (i<<2), tv_mode->filter_table[j++]);
+	for (i = 0; i < 43; i++)
+		OUTREG(TV_V_LUMA_0 + (i<<2), tv_mode->filter_table[j++]);
+	for (i = 0; i < 43; i++)
+		OUTREG(TV_V_CHROMA_0 + (i<<2), tv_mode->filter_table[j++]);
+	OUTREG(TV_DAC, 0);
+	OUTREG(TV_CTL, tv_ctl);
 }
 
 static const DisplayModeRec reported_modes[] = {
 	{
 		.name = "NTSC 480i",
-		.Clock = TV_PLL_CLOCK,
+		.Clock = 107520,
 		.HDisplay   = 1280,
 		.HSyncStart = 1368,
 		.HSyncEnd   = 1496,
@@ -950,76 +1332,76 @@ static const DisplayModeRec reported_mod
  * Detects TV presence by checking for load.
  *
  * Requires that the current pipe's DPLL is active.
- 
+
  * \return TRUE if TV is connected.
  * \return FALSE if TV is disconnected.
  */
 static void
 i830_tv_detect_type (xf86CrtcPtr    crtc,
-		     xf86OutputPtr  output)
+		xf86OutputPtr  output)
 {
-    ScrnInfoPtr		    pScrn = output->scrn;
-    I830Ptr		    pI830 = I830PTR(pScrn);
-    I830OutputPrivatePtr    intel_output = output->driver_private;
-    struct i830_tv_priv	    *dev_priv = intel_output->dev_priv;
-    CARD32		    tv_ctl, save_tv_ctl;
-    CARD32		    tv_dac, save_tv_dac;
-    int			    type = TV_TYPE_UNKNOWN;
+	ScrnInfoPtr		    pScrn = output->scrn;
+	I830Ptr		    pI830 = I830PTR(pScrn);
+	I830OutputPrivatePtr    intel_output = output->driver_private;
+	struct i830_tv_priv	    *dev_priv = intel_output->dev_priv;
+	CARD32		    tv_ctl, save_tv_ctl;
+	CARD32		    tv_dac, save_tv_dac;
+	int			    type = TV_TYPE_UNKNOWN;
 
-    tv_dac = INREG(TV_DAC);
-    /*
-     * Detect TV by polling)
-     */
-    if (intel_output->load_detect_temp)
-    {
-	/* TV not currently running, prod it with destructive detect */
-	save_tv_dac = tv_dac;
-	tv_ctl = INREG(TV_CTL);
-	save_tv_ctl = tv_ctl;
-	tv_ctl &= ~TV_ENC_ENABLE;
-	tv_ctl &= ~TV_TEST_MODE_MASK;
-	tv_ctl |= TV_TEST_MODE_MONITOR_DETECT;
-	tv_dac &= ~TVDAC_SENSE_MASK;
-	tv_dac |= (TVDAC_STATE_CHG_EN |
-		   TVDAC_A_SENSE_CTL |
-		   TVDAC_B_SENSE_CTL |
-		   TVDAC_C_SENSE_CTL |
-		   DAC_CTL_OVERRIDE |
-		   DAC_A_0_7_V |
-		   DAC_B_0_7_V |
-		   DAC_C_0_7_V);
-	OUTREG(TV_CTL, tv_ctl);
-	OUTREG(TV_DAC, tv_dac);
-	i830WaitForVblank(pScrn);
 	tv_dac = INREG(TV_DAC);
-	OUTREG(TV_DAC, save_tv_dac);
-	OUTREG(TV_CTL, save_tv_ctl);
-    }
-    /*
-     *  A B C
-     *  0 1 1 Composite
-     *  1 0 X svideo
-     *  0 0 0 Component
-     */
-    if ((tv_dac & TVDAC_SENSE_MASK) == (TVDAC_B_SENSE | TVDAC_C_SENSE)) {
-	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-		   "Detected Composite TV connection\n");
-	type = TV_TYPE_COMPOSITE;
-    } else if ((tv_dac & (TVDAC_A_SENSE|TVDAC_B_SENSE)) == TVDAC_A_SENSE) {
-	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-		   "Detected S-Video TV connection\n");
-	type = TV_TYPE_SVIDEO;
-    } else if ((tv_dac & TVDAC_SENSE_MASK) == 0) {
-	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-		   "Detected Component TV connection\n");
-	type = TV_TYPE_COMPONENT;
-    } else {
-	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-		   "No TV connection detected\n");
-	type = TV_TYPE_NONE;
-    }
-    
-    dev_priv->type = type;
+	/*
+	 * Detect TV by polling)
+	 */
+	if (intel_output->load_detect_temp)
+	{
+		/* TV not currently running, prod it with destructive detect */
+		save_tv_dac = tv_dac;
+		tv_ctl = INREG(TV_CTL);
+		save_tv_ctl = tv_ctl;
+		tv_ctl &= ~TV_ENC_ENABLE;
+		tv_ctl &= ~TV_TEST_MODE_MASK;
+		tv_ctl |= TV_TEST_MODE_MONITOR_DETECT;
+		tv_dac &= ~TVDAC_SENSE_MASK;
+		tv_dac |= (TVDAC_STATE_CHG_EN |
+				TVDAC_A_SENSE_CTL |
+				TVDAC_B_SENSE_CTL |
+				TVDAC_C_SENSE_CTL |
+				DAC_CTL_OVERRIDE |
+				DAC_A_0_7_V |
+				DAC_B_0_7_V |
+				DAC_C_0_7_V);
+		OUTREG(TV_CTL, tv_ctl);
+		OUTREG(TV_DAC, tv_dac);
+		i830WaitForVblank(pScrn);
+		tv_dac = INREG(TV_DAC);
+		OUTREG(TV_DAC, save_tv_dac);
+		OUTREG(TV_CTL, save_tv_ctl);
+	}
+	/*
+	 *  A B C
+	 *  0 1 1 Composite
+	 *  1 0 X svideo
+	 *  0 0 0 Component
+	 */
+	if ((tv_dac & TVDAC_SENSE_MASK) == (TVDAC_B_SENSE | TVDAC_C_SENSE)) {
+		xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+				"Detected Composite TV connection\n");
+		type = TV_TYPE_COMPOSITE;
+	} else if ((tv_dac & (TVDAC_A_SENSE|TVDAC_B_SENSE)) == TVDAC_A_SENSE) {
+		xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+				"Detected S-Video TV connection\n");
+		type = TV_TYPE_SVIDEO;
+	} else if ((tv_dac & TVDAC_SENSE_MASK) == 0) {
+		xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+				"Detected Component TV connection\n");
+		type = TV_TYPE_COMPONENT;
+	} else {
+		xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+				"No TV connection detected\n");
+		type = TV_TYPE_NONE;
+	}
+
+	dev_priv->type = type;
 }
 
 /**
@@ -1031,33 +1413,33 @@ i830_tv_detect_type (xf86CrtcPtr    crtc
 static xf86OutputStatus
 i830_tv_detect(xf86OutputPtr output)
 {
-    xf86CrtcPtr		    crtc;
-    DisplayModeRec	    mode;
-    I830OutputPrivatePtr    intel_output = output->driver_private;
-    struct i830_tv_priv	    *dev_priv = intel_output->dev_priv;
+	xf86CrtcPtr		    crtc;
+	DisplayModeRec	    mode;
+	I830OutputPrivatePtr    intel_output = output->driver_private;
+	struct i830_tv_priv	    *dev_priv = intel_output->dev_priv;
 
-    crtc = i830GetLoadDetectPipe (output);
-    if (crtc)
-    {
-	if (intel_output->load_detect_temp)
+	crtc = i830GetLoadDetectPipe (output);
+	if (crtc)
 	{
-	    /* we only need the pixel clock set correctly here */
-	    mode = reported_modes[0];
-	    xf86SetModeCrtc (&mode, INTERLACE_HALVE_V);
-	    i830PipeSetMode (crtc, &mode, FALSE);
+		if (intel_output->load_detect_temp)
+		{
+			/* we only need the pixel clock set correctly here */
+			mode = reported_modes[0];
+			xf86SetModeCrtc (&mode, INTERLACE_HALVE_V);
+			i830PipeSetMode (crtc, &mode, FALSE);
+		}
+		i830_tv_detect_type (crtc, output);
+		i830ReleaseLoadDetectPipe (output);
+	}
+
+	switch (dev_priv->type) {
+		case TV_TYPE_NONE:
+			return XF86OutputStatusDisconnected;
+		case TV_TYPE_UNKNOWN:
+			return XF86OutputStatusUnknown;
+		default:
+			return XF86OutputStatusConnected;
 	}
-	i830_tv_detect_type (crtc, output);
-	i830ReleaseLoadDetectPipe (output);
-    }
-    
-    switch (dev_priv->type) {
-    case TV_TYPE_NONE:
-	return XF86OutputStatusDisconnected;
-    case TV_TYPE_UNKNOWN:
-	return XF86OutputStatusUnknown;
-    default:
-	return XF86OutputStatusConnected;
-    }
 }
 
 struct input_res {
@@ -1083,89 +1465,94 @@ struct input_res {
 static DisplayModePtr
 i830_tv_get_modes(xf86OutputPtr output)
 {
-    DisplayModePtr  ret = NULL, mode_ptr;
-    int		    i, j;
-    	
-    for (i = 0; i < sizeof(tv_modes) / sizeof (tv_modes[0]); i++) 
-    {
-	const tv_mode_t *tv_mode = &tv_modes[i];
-	unsigned int hactive = tv_mode->hblank_start - tv_mode->hblank_end;
-	unsigned int vactive = tv_mode->progressive
-		?tv_mode->nbr_end + 1: 2*(tv_mode->nbr_end + 1);
-	unsigned int htotal = tv_mode->htotal + 1;
-	unsigned int vtotal = tv_mode->progressive
-		?tv_mode->nbr_end + 1 + tv_mode->vi_end_f2:
+	DisplayModePtr  ret = NULL, mode_ptr;
+	int		    i, j;
+	I830OutputPrivatePtr    intel_output = output->driver_private;
+	struct i830_tv_priv	    *dev_priv = intel_output->dev_priv;
+
+	for (i = 0; i < sizeof(tv_modes) / sizeof (tv_modes[0]); i++) 
+	{
+		const tv_mode_t *tv_mode = &tv_modes[i];
+		unsigned int hactive = tv_mode->hblank_start - tv_mode->hblank_end;
+		unsigned int vactive = tv_mode->progressive
+			?tv_mode->nbr_end + 1: 2*(tv_mode->nbr_end + 1);
+		unsigned int htotal = tv_mode->htotal + 1;
+		unsigned int vtotal = tv_mode->progressive
+			?tv_mode->nbr_end + 1 + tv_mode->vi_end_f2:
 			2*(tv_mode->nbr_end+1) + 2*(tv_mode->vi_end_f2);
-	
-	for (j = 0; j < sizeof(input_res_table)/sizeof(input_res_table[0]); j++)	{
-	        struct input_res *input = &input_res_table[j];
-		unsigned int hactive_s = input->w;
-		unsigned int vactive_s = input->h;
-		unsigned int htotal_s = htotal*hactive_s/hactive;
-		unsigned int vtotal_s = vtotal*vactive_s/vactive;
-	
-		mode_ptr = xnfcalloc(1, sizeof(DisplayModeRec));
-		mode_ptr->name = xnfalloc(strlen(tv_mode->name) + 
-			strlen(input->name) + 4);
-		sprintf(mode_ptr->name, "%s %s", tv_mode->name, input->name);
-		
-		mode_ptr->Clock = tv_mode->clock;
-
-		mode_ptr->HDisplay = hactive_s;
-		mode_ptr->HSyncStart = hactive_s + 1;
-		mode_ptr->HSyncEnd = htotal_s - 20;  
-		if ( mode_ptr->HSyncEnd <= mode_ptr->HSyncStart)
-			mode_ptr->HSyncEnd = mode_ptr->HSyncStart  + 1;
-		mode_ptr->HTotal = htotal_s;
-
-		mode_ptr->VDisplay = vactive_s;
-		mode_ptr->VSyncStart = vactive_s + 1;
-		mode_ptr->VSyncEnd = vtotal_s - 20;
-		if ( mode_ptr->VSyncEnd <= mode_ptr->VSyncStart)
-			mode_ptr->VSyncEnd = mode_ptr->VSyncStart  + 1;
-		mode_ptr->VTotal = vtotal_s;
-
-		mode_ptr->type = M_T_DRIVER;
-		mode_ptr->next = ret;
-		ret = mode_ptr;
-	} 
-    }
 
-    return ret;
+		if (dev_priv->type != TV_TYPE_COMPONENT && tv_mode->component_only)
+			continue;
+
+		for (j = 0; j < sizeof(input_res_table)/sizeof(input_res_table[0]); j++)	{
+			struct input_res *input = &input_res_table[j];
+			unsigned int hactive_s = input->w;
+			unsigned int vactive_s = input->h;
+			unsigned int htotal_s = htotal*hactive_s/hactive;
+			unsigned int vtotal_s = vtotal*vactive_s/vactive;
+
+			mode_ptr = xnfcalloc(1, sizeof(DisplayModeRec));
+			mode_ptr->name = xnfalloc(strlen(tv_mode->name) + 
+					strlen(input->name) + 4);
+			sprintf(mode_ptr->name, "%s %s", tv_mode->name, input->name);
+
+			mode_ptr->Clock = tv_mode->clock;
+
+			mode_ptr->HDisplay = hactive_s;
+			mode_ptr->HSyncStart = hactive_s + 1;
+			mode_ptr->HSyncEnd = htotal_s - 20;  
+			if ( mode_ptr->HSyncEnd <= mode_ptr->HSyncStart)
+				mode_ptr->HSyncEnd = mode_ptr->HSyncStart  + 1;
+			mode_ptr->HTotal = htotal_s;
+
+			mode_ptr->VDisplay = vactive_s;
+			mode_ptr->VSyncStart = vactive_s + 1;
+			mode_ptr->VSyncEnd = vtotal_s - 20;
+			if ( mode_ptr->VSyncEnd <= mode_ptr->VSyncStart)
+				mode_ptr->VSyncEnd = mode_ptr->VSyncStart  + 1;
+			mode_ptr->VTotal = vtotal_s;
+
+			mode_ptr->type = M_T_DRIVER;
+			mode_ptr->next = ret;
+			ret = mode_ptr;
+		} 
+	}
+
+	return ret;
 }
 
 static void
 i830_tv_destroy (xf86OutputPtr output)
 {
-    if (output->driver_private)
-	xfree (output->driver_private);
+	if (output->driver_private)
+		xfree (output->driver_private);
 }
 
 static const xf86OutputFuncsRec i830_tv_output_funcs = {
-    .dpms = i830_tv_dpms,
-    .save = i830_tv_save,
-    .restore = i830_tv_restore,
-    .mode_valid = i830_tv_mode_valid,
-    .mode_fixup = i830_tv_mode_fixup,
-    .mode_set = i830_tv_mode_set,
-    .detect = i830_tv_detect,
-    .get_modes = i830_tv_get_modes,
-    .destroy = i830_tv_destroy
+	.dpms = i830_tv_dpms,
+	.save = i830_tv_save,
+	.restore = i830_tv_restore,
+	.mode_valid = i830_tv_mode_valid,
+	.mode_fixup = i830_tv_mode_fixup,
+	.mode_set = i830_tv_mode_set,
+	.detect = i830_tv_detect,
+	.get_modes = i830_tv_get_modes,
+	.destroy = i830_tv_destroy
 };
 
 void
 i830_tv_init(ScrnInfoPtr pScrn)
 {
-    I830Ptr		    pI830 = I830PTR(pScrn);
-    xf86OutputPtr	    output;
-    I830OutputPrivatePtr    intel_output;
-    struct i830_tv_priv	    *dev_priv;
-    CARD32		    tv_dac_on, tv_dac_off, save_tv_dac;
- 
-    if ((INREG(TV_CTL) & TV_FUSE_STATE_MASK) == TV_FUSE_STATE_DISABLED)
-	return;
+	I830Ptr		    pI830 = I830PTR(pScrn);
+	xf86OutputPtr	    output;
+	I830OutputPrivatePtr    intel_output;
+	struct i830_tv_priv	    *dev_priv;
+	CARD32		    tv_dac_on, tv_dac_off, save_tv_dac;
 
-    /*
+	if ((INREG(TV_CTL) & TV_FUSE_STATE_MASK) == TV_FUSE_STATE_DISABLED)
+		return;
+
+	/*
      * Sanity check the TV output by checking to see if the
      * DAC register holds a value
      */
diff-tree 5a67f3d3690903a181ca854d060cfa8b4c2aca26 (from parents)
Merge: 3cc583ec8e79ec65103308220dd6047a4a7acddf 98110591001dfaf2b8b5ac440bea0c38456da718
Author: Nian Wu <nian.wu at intel.com>
Date:   Thu Jan 25 13:40:50 2007 -0800

    Merge branch 'crestline' of /git/xorg/driver/xf86-video-intel into crestline

diff-tree 3cc583ec8e79ec65103308220dd6047a4a7acddf (from parents)
Merge: 566e1d397744d0b477de4da6a206919906176f49 effe579e691b044e3ce59b41b5c0eaaac4368dda
Author: Nian Wu <nian.wu at intel.com>
Date:   Thu Jan 25 13:37:05 2007 -0800

    Merge branch 'modesetting' of git://proxy01.pd.intel.com:9419/git/xorg/driver/xf86-video-intel into crestline

diff-tree 6d549ed280d3fcf3fe611b095d9f8adc0196bfb6 (from parents)
Merge: 75f4df278e9db360967d77cdba4756cbde622d56 effe579e691b044e3ce59b41b5c0eaaac4368dda
Author: Nian Wu <nian.wu at intel.com>
Date:   Thu Jan 25 13:36:33 2007 -0800

    Merge branch 'modesetting' of git://proxy01.pd.intel.com:9419/git/xorg/driver/xf86-video-intel into modesetting
    
    Conflicts:
    
    	src/i830_driver.c

diff-tree 98110591001dfaf2b8b5ac440bea0c38456da718 (from 566e1d397744d0b477de4da6a206919906176f49)
Author: Zou Nan hai <nanhai.zou at intel.com>
Date:   Wed Jan 17 10:45:59 2007 +0800

      enable all TV modes

diff --git a/src/i830_display.c b/src/i830_display.c
index f47a9db..553d2d2 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -960,13 +960,14 @@ i830PipeSetMode(xf86CrtcPtr crtc, Displa
 	if (output->crtc == crtc)
 	    output->funcs->mode_set(output, pMode, adjusted_mode);
     }
-
-    /* Now, enable the clocks, plane, pipe, and outputs that we set up. */
-    crtc->funcs->dpms(crtc, DPMSModeOn);
-    for (i = 0; i < xf86_config->num_output; i++) {
-	xf86OutputPtr output = xf86_config->output[i];
-	if (output->crtc == crtc)
-	    output->funcs->dpms(output, DPMSModeOn);
+    if (plane_enable) {
+	    /* Now, enable the clocks, plane, pipe, and outputs that we set up. */
+	    crtc->funcs->dpms(crtc, DPMSModeOn);
+	    for (i = 0; i < xf86_config->num_output; i++) {
+		    xf86OutputPtr output = xf86_config->output[i];
+		    if (output->crtc == crtc)
+			    output->funcs->dpms(output, DPMSModeOn);
+	    }
     }
 
 #if 0
diff --git a/src/i830_tv.c b/src/i830_tv.c
index 92e417e..1b75e87 100644
--- a/src/i830_tv.c
+++ b/src/i830_tv.c
@@ -37,7 +37,6 @@
 #include "i830.h"
 #include "i830_display.h"
 #include <string.h>
-
 enum tv_type {
     TV_TYPE_NONE,
     TV_TYPE_UNKNOWN,
@@ -96,9 +95,10 @@ typedef struct {
 
 typedef struct {
     char *name;
+    int	clock;
     CARD32 oversample;
     int hsync_end, hblank_start, hblank_end, htotal;
-    Bool progressive;
+    Bool progressive, trilevel_sync;
     int vsync_start_f1, vsync_start_f2, vsync_len;
     Bool veq_ena;
     int veq_start_f1, veq_start_f2, veq_len;
@@ -158,15 +158,15 @@ typedef struct {
 const static tv_mode_t tv_modes[] = {
     {
 	.name		= "NTSC 480i",
+	.clock		= 107520,	
 	.oversample	= TV_OVERSAMPLE_8X,
-	
 	/* 525 Lines, 60 Fields, 15.734KHz line, Sub-Carrier 3.580MHz */
 
 	.hsync_end	= 64,		    .hblank_end		= 124,
 	.hblank_start	= 836,		    .htotal		= 857,
 	
-	.progressive	= FALSE,
-	
+	.progressive	= FALSE,	    .trilevel_sync = FALSE,
+
 	.vsync_start_f1	= 6,		    .vsync_start_f2	= 7,
 	.vsync_len	= 6,
 	
@@ -206,14 +206,15 @@ const static tv_mode_t tv_modes[] = {
     },
     {
 	.name		= "NTSC-Japan 480i",
+	.clock		= 107520,	
 	.oversample	= TV_OVERSAMPLE_8X,
 	
 	/* 525 Lines, 60 Fields, 15.734KHz line, Sub-Carrier 3.580MHz */
 	.hsync_end	= 64,		    .hblank_end		= 124,
 	.hblank_start	= 836,		    .htotal		= 857,
 	
-	.progressive	= FALSE,
-	
+	.progressive	= FALSE,	    .trilevel_sync = FALSE,
+
 	.vsync_start_f1	= 6,		    .vsync_start_f2	= 7,
 	.vsync_len	= 6,
 	
@@ -254,12 +255,14 @@ const static tv_mode_t tv_modes[] = {
     {
 	/* 625 Lines, 50 Fields, 15.625KHz line, Sub-Carrier 4.434MHz */
 	.name	    = "PAL 576i",
+	.clock		= 107520,	
 	.oversample	= TV_OVERSAMPLE_8X,
 
 	.hsync_end	= 64,		    .hblank_end		= 128,
 	.hblank_start	= 844,		    .htotal		= 863,
 	
-	.progressive	= FALSE,
+	.progressive	= FALSE,	   .trilevel_sync = FALSE,
+	
 	
 	.vsync_start_f1	= 6,		    .vsync_start_f2	= 7,
 	.vsync_len	= 6,
@@ -297,105 +300,145 @@ const static tv_mode_t tv_modes[] = {
 	    .ru =-0.0937, .gu =-0.1840, .bu = 0.2777, .au = 1.0000,
 	    .rv = 0.3908, .gv =-0.3273, .bv =-0.0636, .av = 1.0000,
 	},
-    }
-#if 0
+    },
     {
-	/* 625 Lines, 50 Fields, 15.625KHz line, Sub-Carrier 4.434MHz */
-	.name	    = "PAL",
-	/* desired 4.4336180 actual 4.4336180 clock 107.52 */
-	.dda1_inc	=    168,
-	.dda2_inc	=  18557,	.dda2_size	=  20625,
-	.dda3_inc	=      0,	.dda3_size	=      0,
-	.sc_reset   = TV_SC_RESET_EVERY_8,
-	.pal_burst  = TRUE
-	
-	.composite_levels = { .blank = 237, .black = 237, .burst = 118 },
-	.composite_color = {
-	    .ry = 0.2990, .gy = 0.5870, .by = 0.1140, .ay = 0.5379,
-	    .ru =-0.0793, .gu =-0.1557, .bu = 0.2350, .au = 1.0000,
-	    .rv = 0.3307, .gv =-0.2769, .bv =-0.0538, .av = 1.0000,
-	},
-
-	.svideo_levels    = { .blank = 280, .black = 280, .burst = 139 },
-	.svideo_color = {
-	    .ry = 0.2990, .gy = 0.5870, .by = 0.1140, .ay = 0.6357,
-	    .ru =-0.0937, .gu =-0.1840, .bu = 0.2777, .au = 1.0000,
-	    .rv = 0.3908, .gv =-0.3273, .bv =-0.0636, .av = 1.0000,
-	},
+	    .name       = "480p",
+	    .clock 	= 107520,	
+	    .oversample     = TV_OVERSAMPLE_4X,
+
+	    .hsync_end      = 64,               .hblank_end         = 122,
+	    .hblank_start   = 842,              .htotal             = 857,
+
+	    .progressive    = TRUE,.trilevel_sync = FALSE,
+
+	    .vsync_start_f1 = 12,               .vsync_start_f2     = 12,
+	    .vsync_len      = 12,
+
+	    .veq_ena        = FALSE,
+
+	    .vi_end_f1      = 44,               .vi_end_f2          = 44,
+	    .nbr_end        = 496,
+
+	    .burst_ena      = FALSE,
+
+	    .composite_levels = { .blank = 237, .black = 237, .burst = 118 },
+	    .composite_color = {
+		    .ry = 0.2990, .gy = 0.5870, .by = 0.1140, .ay = 0.5379,
+		    .ru =-0.0793, .gu =-0.1557, .bu = 0.2350, .au = 1.0000,
+		    .rv = 0.3307, .gv =-0.2769, .bv =-0.0538, .av = 1.0000,
+	    },
+
+	    .svideo_levels    = { .blank = 280, .black = 280, .burst = 139 },
+	    .svideo_color = {
+		    .ry = 0.2990, .gy = 0.5870, .by = 0.1140, .ay = 0.6357,
+		    .ru =-0.0937, .gu =-0.1840, .bu = 0.2777, .au = 1.0000,
+		    .rv = 0.3908, .gv =-0.3273, .bv =-0.0636, .av = 1.0000,
+	    },
     },
     {
-	/* 525 Lines, 60 Fields, 15.734KHz line, Sub-Carrier 3.576MHz */
-	.name	    = "PAL M",
-	/* desired 3.5756110 actual 3.5756110 clock 107.52 */
-	.dda1_inc	=    136,
-	.dda2_inc	=   5611,	.dda2_size	=  26250,
-	.dda3_inc	=      0,	.dda3_size	=      0,
-	.sc_reset   = TV_SC_RESET_EVERY_8,
-	.pal_burst  = TRUE
-	
-	.composite_levels = { .blank = 225, .black = 267, .burst = 113 },
-	.composite_color = {
-	    .ry = 0.2990, .gy = 0.5870, .by = 0.1140, .ay = 0.5082,
-	    .ru =-0.0749, .gu =-0.1471, .bu = 0.2220, .au = 1.0000,
-	    .rv = 0.3125, .gv =-0.2616, .bv =-0.0508, .av = 1.0000,
-	},
-
-	.svideo_levels    = { .blank = 266, .black = 316, .burst = 133 },
-	.svideo_color = {
-	    .ry = 0.2990, .gy = 0.5870, .by = 0.1140, .ay = 0.6006,
-	    .ru =-0.0885, .gu =-0.1738, .bu = 0.2624, .au = 1.0000,
-	    .rv = 0.3693, .gv =-0.3092, .bv =-0.0601, .av = 1.0000,
-	},
+	    .name       = "576p",
+	    .clock 	= 107520,	
+	    .oversample     = TV_OVERSAMPLE_4X,
+
+	    .hsync_end      = 64,               .hblank_end         = 139,
+	    .hblank_start   = 859,              .htotal             = 863,
+
+	    .progressive    = TRUE,		.trilevel_sync = FALSE,
+
+	    .vsync_start_f1 = 10,               .vsync_start_f2     = 10,
+	    .vsync_len      = 10,
+
+	    .veq_ena        = FALSE,
+
+	    .vi_end_f1      = 48,               .vi_end_f2          = 48,
+	    .nbr_end        = 575,
+
+	    .burst_ena      = FALSE,
+
+	    .composite_levels = { .blank = 237, .black = 237, .burst = 118 },
+	    .composite_color = {
+		    .ry = 0.2990, .gy = 0.5870, .by = 0.1140, .ay = 0.5379,
+		    .ru =-0.0793, .gu =-0.1557, .bu = 0.2350, .au = 1.0000,
+		    .rv = 0.3307, .gv =-0.2769, .bv =-0.0538, .av = 1.0000,
+	    },
+
+	    .svideo_levels    = { .blank = 280, .black = 280, .burst = 139 },
+	    .svideo_color = {
+		    .ry = 0.2990, .gy = 0.5870, .by = 0.1140, .ay = 0.6357,
+		    .ru =-0.0937, .gu =-0.1840, .bu = 0.2777, .au = 1.0000,
+		    .rv = 0.3908, .gv =-0.3273, .bv =-0.0636, .av = 1.0000,
+	    },
     },
     {
-	/* 625 Lines, 50 Fields, 15.625KHz line, Sub-Carrier 3.582MHz */
-	.name	    = "PAL Nc",
-	/* desired 3.5820560 actual 3.5820560 clock 107.52 */
-	.dda1_inc	=    136,
-	.dda2_inc	=  12056,	.dda2_size	=  26250,
-	.dda3_inc	=      0,	.dda3_size	=      0,
-	.sc_reset   = TV_SC_RESET_EVERY_8,
-	.pal_burst  = TRUE
-	
-	.composite_levels = { .blank = 225, .black = 267, .burst = 113 },
-	.composite_color = {
-	    .ry = 0.2990, .gy = 0.5870, .by = 0.1140, .ay = 0.5082,
-	    .ru =-0.0749, .gu =-0.1471, .bu = 0.2220, .au = 1.0000,
-	    .rv = 0.3125, .gv =-0.2616, .bv =-0.0508, .av = 1.0000,
-	},
-
-	.svideo_levels    = { .blank = 266, .black = 316, .burst = 133 },
-	.svideo_color = {
-	    .ry = 0.2990, .gy = 0.5870, .by = 0.1140, .ay = 0.6006,
-	    .ru =-0.0885, .gu =-0.1738, .bu = 0.2624, .au = 1.0000,
-	    .rv = 0.3693, .gv =-0.3092, .bv =-0.0601, .av = 1.0000,
-	},
+        .name       = "720p",
+	.clock		= 148800,	
+        .oversample     = TV_OVERSAMPLE_2X,
+
+        .hsync_end      = 80,               .hblank_end         = 300,
+        .hblank_start   = 1580,             .htotal             = 1649,
+
+        .progressive    = TRUE, 	    .trilevel_sync = TRUE,
+
+        .vsync_start_f1 = 10,               .vsync_start_f2     = 10,
+        .vsync_len      = 10,
+
+        .veq_ena        = FALSE,
+
+        .vi_end_f1      = 29,               .vi_end_f2          = 29,
+        .nbr_end        = 719,
+
+        .burst_ena      = FALSE,
+
+        .composite_levels = { .blank = 237, .black = 237, .burst = 118 },
+        .composite_color = {
+            .ry = 0.2990, .gy = 0.5870, .by = 0.1140, .ay = 0.5379,
+            .ru =-0.0793, .gu =-0.1557, .bu = 0.2350, .au = 1.0000,
+            .rv = 0.3307, .gv =-0.2769, .bv =-0.0538, .av = 1.0000,
+        },
+
+        .svideo_levels    = { .blank = 280, .black = 280, .burst = 139 },
+        .svideo_color = {
+            .ry = 0.2990, .gy = 0.5870, .by = 0.1140, .ay = 0.6357,
+            .ru =-0.0937, .gu =-0.1840, .bu = 0.2777, .au = 1.0000,
+            .rv = 0.3908, .gv =-0.3273, .bv =-0.0636, .av = 1.0000,
+        },
     },
     {
-	/* 525 lines, 60 fields, 15.734KHz line, Sub-Carrier 4.43MHz */
-	.name	    = "NTSC-4.43(nonstandard)",
-	/* desired 4.4336180 actual 4.4336180 clock 107.52 */
-	.dda1_inc	=    168,
-	.dda2_inc	=  18557,	.dda2_size	=  20625,
-	.dda3_inc	=      0,	.dda3_size	=      0,
-	.sc_reset   = TV_SC_RESET_NEVER,
-	.pal_burst  = FALSE
+        .name       = "1080i",
+	.clock		= 148800,	
+        .oversample     = TV_OVERSAMPLE_2X,
 
-	.composite_levels = { .blank = 225, .black = 267, .burst = 113 },
-	.composite_color = {
-	    .ry = 0.2990, .gy = 0.5870, .by = 0.1140, .ay = 0.5082,
-	    .ru =-0.0749, .gu =-0.1471, .bu = 0.2220, .au = 1.0000,
-	    .rv = 0.3125, .gv =-0.2616, .bv =-0.0508, .av = 1.0000,
-	},
+        .hsync_end      = 88,               .hblank_end         = 235,
+        .hblank_start   = 2155,             .htotal             = 2639,
 
-	.svideo_levels    = { .blank = 266, .black = 316, .burst = 133 },
-	.svideo_color = {
-	    .ry = 0.2990, .gy = 0.5870, .by = 0.1140, .ay = 0.6006,
-	    .ru =-0.0885, .gu =-0.1738, .bu = 0.2624, .au = 1.0000,
-	    .rv = 0.3693, .gv =-0.3092, .bv =-0.0601, .av = 1.0000,
-	},
+        .progressive    = FALSE, 	    .trilevel_sync = TRUE,
+
+        .vsync_start_f1 = 4,               .vsync_start_f2     = 5,
+        .vsync_len      = 10,
+
+	.veq_ena	= TRUE,		    .veq_start_f1    	= 4,
+	.veq_start_f2	= 4,		    .veq_len		= 10,
+	
+
+        .vi_end_f1      = 21,               .vi_end_f2          = 22,
+        .nbr_end        = 539,
+
+        .burst_ena      = FALSE,
+
+        .composite_levels = { .blank = 237, .black = 237, .burst = 118 },
+        .composite_color = {
+            .ry = 0.2990, .gy = 0.5870, .by = 0.1140, .ay = 0.5379,
+            .ru =-0.0793, .gu =-0.1557, .bu = 0.2350, .au = 1.0000,
+            .rv = 0.3307, .gv =-0.2769, .bv =-0.0538, .av = 1.0000,
+        },
+
+        .svideo_levels    = { .blank = 280, .black = 280, .burst = 139 },
+        .svideo_color = {
+            .ry = 0.2990, .gy = 0.5870, .by = 0.1140, .ay = 0.6357,
+            .ru =-0.0937, .gu =-0.1840, .bu = 0.2777, .au = 1.0000,
+            .rv = 0.3908, .gv =-0.3273, .bv =-0.0636, .av = 1.0000,
+        },
     },
-#endif
 };
 
 static const video_levels_t component_level = {
@@ -674,7 +717,7 @@ i830_tv_mode_set(xf86OutputPtr output, D
     I830CrtcPrivatePtr	    intel_crtc = crtc->driver_private;
     struct i830_tv_priv	    *dev_priv = intel_output->dev_priv;
     const tv_mode_t	    *tv_mode;
-    CARD32		    tv_ctl, tv_filter_ctl;
+    CARD32		    tv_ctl;
     CARD32		    hctl1, hctl2, hctl3;
     CARD32		    vctl1, vctl2, vctl3, vctl4, vctl5, vctl6, vctl7;
     CARD32		    scctl1, scctl2, scctl3;
@@ -687,7 +730,12 @@ i830_tv_mode_set(xf86OutputPtr output, D
      * mode.  For now, just set the first one in the list, with
      * NTSC format.
      */
-    tv_mode = &tv_modes[0];
+	
+    for (i = 0; i < sizeof(tv_modes) / sizeof (tv_modes[0]); i++) {
+	    tv_mode = &tv_modes[i];
+	    if (strstr(mode->name, tv_mode->name)) 
+		    break;	
+    }
     
     tv_ctl = 0;
 
@@ -755,15 +803,17 @@ i830_tv_mode_set(xf86OutputPtr output, D
 
     if (intel_crtc->pipe == 1)
 	tv_ctl |= TV_ENC_PIPEB_SELECT;
-
     tv_ctl |= tv_mode->oversample;
+
     if (tv_mode->progressive)
 	tv_ctl |= TV_PROGRESSIVE;
+    if (tv_mode->trilevel_sync)
+	tv_ctl |= TV_TRILEVEL_SYNC;
     if (tv_mode->pal_burst)
 	tv_ctl |= TV_PAL_BURST;
+    if (tv_mode->oversample == TV_OVERSAMPLE_8X)
+	    scctl1 = TV_SC_DDA1_EN;
 
-    scctl1 = TV_SC_DDA1_EN;
-    
     if (tv_mode->dda2_inc)
 	scctl1 |= TV_SC_DDA2_EN;
     
@@ -784,9 +834,6 @@ i830_tv_mode_set(xf86OutputPtr output, D
     if (pI830->PciInfo->chipType < PCI_CHIP_I945_G)
 	tv_ctl |= TV_ENC_C0_FIX | TV_ENC_SDP_FIX;
 
-    tv_filter_ctl = TV_AUTO_SCALE;
-    if (mode->HDisplay > 1024)
-	tv_ctl |= TV_V_FILTER_BYPASS;
 
     OUTREG(TV_H_CTL_1, hctl1);
     OUTREG(TV_H_CTL_2, hctl2);
@@ -828,13 +875,47 @@ i830_tv_mode_set(xf86OutputPtr output, D
     OUTREG(TV_CLR_KNOBS, 0x00606000);
     OUTREG(TV_CLR_LEVEL, ((video_levels->black << TV_BLACK_LEVEL_SHIFT) |
 			  (video_levels->blank << TV_BLANK_LEVEL_SHIFT)));
+    {
+	int pipeconf_reg = (intel_crtc->pipe == 0)?PIPEACONF:PIPEBCONF;
+        int dspcntr_reg = (intel_crtc->pipe == 0)?DSPACNTR : DSPBCNTR;
+	int pipeconf = INREG(pipeconf_reg);
+	int dspcntr = INREG(dspcntr_reg);
+	int dspbase_reg = (intel_crtc->pipe == 0) ? DSPABASE : DSPBBASE;
+	int xpos = 0x0, ypos = 0x0;
+	unsigned int xsize, ysize;
+	/* Pipe must be off here */
+	OUTREG(dspcntr_reg, dspcntr & ~DISPLAY_PLANE_ENABLE);
+	/* Flush the plane changes */
+	OUTREG(dspbase_reg, INREG(dspbase_reg));
+
+	if (!IS_I9XX(pI830)) {
+            /* Wait for vblank for the disable to take effect */
+            i830WaitForVblank(pScrn);
+        }
+
+	OUTREG(pipeconf_reg, pipeconf & ~PIPEACONF_ENABLE);
+	/* Wait for vblank for the disable to take effect. */
+        i830WaitForVblank(pScrn);
+
+	/* Filter ctl must be set before TV_WIN_SIZE and TV_WIN_POS */
+    	OUTREG(TV_FILTER_CTL_1, TV_AUTO_SCALE);
+
+	xsize = tv_mode->hblank_start - tv_mode->hblank_end;
+	if (tv_mode->progressive)
+		ysize = tv_mode->nbr_end + 1;
+	else
+		ysize = 2*tv_mode->nbr_end + 1;
+
+	OUTREG(TV_WIN_POS, (xpos<<16)|ypos);
+	OUTREG(TV_WIN_SIZE, (xsize<<16)|ysize);
+
+	OUTREG(pipeconf_reg, pipeconf);
+	OUTREG(dspcntr_reg, dspcntr);
+        /* Flush the plane changes */
+        OUTREG(dspbase_reg, INREG(dspbase_reg));
+
+    } 	
     
-    OUTREG(TV_WIN_POS, 0x00360024);
-    OUTREG(TV_WIN_SIZE, 0x02640198);
-    
-    OUTREG(TV_FILTER_CTL_1, 0x8000085E);
-    OUTREG(TV_FILTER_CTL_2, 0x00017878);
-    OUTREG(TV_FILTER_CTL_3, 0x0000BC3C);
     for (i = 0; i < 60; i++)
 	OUTREG(TV_H_LUMA_0 + (i <<2), h_luma[i]);
     for (i = 0; i < 60; i++)
@@ -863,108 +944,6 @@ static const DisplayModeRec reported_mod
 		.VTotal     = 1104,
 		.type       = M_T_DRIVER
 	},
-	{
-		.name = "NTSC 480i",
-		.Clock = TV_PLL_CLOCK,
-		.HDisplay   = 1024,
-		.HSyncStart = 1080,
-		.HSyncEnd   = 1184,
-		.HTotal     = 1344,
-
-		.VDisplay   = 768,
-		.VSyncStart = 771,
-		.VSyncEnd   = 777,
-		.VTotal     = 806,
-		.type       = M_T_DRIVER
-	},
-	{
-		.name = "NTSC 480i",
-		.Clock = TV_PLL_CLOCK,
-		.HDisplay   = 800,
-		.HSyncStart = 832,
-		.HSyncEnd   = 912,
-		.HTotal     = 1024,
-
-		.VDisplay   = 600,
-		.VSyncStart = 603,
-		.VSyncEnd   = 607,
-		.VTotal     = 650,
-		.type       = M_T_DRIVER
-	},
-	{
-		.name = "NTSC 480i",
-		.Clock = TV_PLL_CLOCK,
-		.HDisplay   = 640,
-		.HSyncStart = 664,
-		.HSyncEnd   = 720,
-		.HTotal     = 800,
-
-		.VDisplay   = 480,
-		.VSyncStart = 483,
-		.VSyncEnd   = 487,
-		.VTotal     = 552,
-		.type       = M_T_DRIVER
-	},
-	{
-		.name = "PAL 576i",
-		.Clock = TV_PLL_CLOCK,
-		.HDisplay   = 1280,
-		.HSyncStart = 1352,
-		.HSyncEnd   = 1480,
-		.HTotal     = 1680,
-
-		.VDisplay   = 1024,
-		.VSyncStart = 1027,
-		.VSyncEnd   = 1034,
-		.VTotal     = 1092,
-
-		.type       = M_T_DRIVER
-	},
-	{
-		.name = "PAL 576i",
-		.Clock = TV_PLL_CLOCK,
-		.HDisplay   = 1024,
-		.HSyncStart = 1072,
-		.HSyncEnd   = 1168,
-		.HTotal     = 1312,
-		.VDisplay   = 768,
-		.VSyncStart = 771,
-		.VSyncEnd   = 775,
-		.VTotal     = 820,
-		.VRefresh   = 50.0f,
-
-		.type       = M_T_DRIVER
-	},
-	{
-		.name = "PAL 576i",
-		.Clock = TV_PLL_CLOCK,
-		.HDisplay   = 800,
-		.HSyncStart = 832,
-		.HSyncEnd   = 904,
-		.HTotal     = 1008,
-		.VDisplay   = 600,
-		.VSyncStart = 603,
-		.VSyncEnd   = 607,
-		.VTotal     = 642,
-		.VRefresh   = 50.0f,
-
-		.type       = M_T_DRIVER
-	},
-	{
-		.name = "PAL 576i",
-		.Clock = TV_PLL_CLOCK,
-		.HDisplay   = 640,
-		.HSyncStart = 664,
-		.HSyncEnd   = 720,
-		.HTotal     = 800,
-
-		.VDisplay   = 480,
-		.VSyncStart = 483,
-		.VSyncEnd   = 487,
-		.VTotal     = 516,
-		.VRefresh   = 50.0f,
-		.type       = M_T_DRIVER
-	},
 };
 
 /**
@@ -1081,34 +1060,78 @@ i830_tv_detect(xf86OutputPtr output)
     }
 }
 
+struct input_res {
+	char *name;
+	int w, h;	
+}input_res_table[] = 
+{
+	{"640x480", 640, 480},
+	{"800x600", 800, 600},
+	{"1024x768", 1024, 768},
+	{"1280x1024", 1280, 1024},
+	{"848x480", 848, 480},
+	{"1280x720", 1280, 720}
+};
+
 /**
  * Stub get_modes function.
  *
  * This should probably return a set of fixed modes, unless we can figure out
  * how to probe modes off of TV connections.
  */
+
 static DisplayModePtr
 i830_tv_get_modes(xf86OutputPtr output)
 {
-    ScrnInfoPtr	    pScrn = output->scrn;
-    I830Ptr	    pI830 = I830PTR(pScrn);
-    DisplayModePtr  new, first = NULL, *tail = &first;
-    int		    i;
-
-    (void) pI830;
-
-    for (i = 0; i < sizeof (reported_modes) / sizeof (reported_modes[0]); i++)
+    DisplayModePtr  ret = NULL, mode_ptr;
+    int		    i, j;
+    	
+    for (i = 0; i < sizeof(tv_modes) / sizeof (tv_modes[0]); i++) 
     {
-	new             = xnfcalloc(1, sizeof (DisplayModeRec));
-
-	*new = reported_modes[i];
-	new->name = xnfalloc(strlen(reported_modes[i].name) + 1);
-	strcpy(new->name, reported_modes[i].name);
-	*tail = new;
-	tail = &new->next;
+	const tv_mode_t *tv_mode = &tv_modes[i];
+	unsigned int hactive = tv_mode->hblank_start - tv_mode->hblank_end;
+	unsigned int vactive = tv_mode->progressive
+		?tv_mode->nbr_end + 1: 2*(tv_mode->nbr_end + 1);
+	unsigned int htotal = tv_mode->htotal + 1;
+	unsigned int vtotal = tv_mode->progressive
+		?tv_mode->nbr_end + 1 + tv_mode->vi_end_f2:
+			2*(tv_mode->nbr_end+1) + 2*(tv_mode->vi_end_f2);
+	
+	for (j = 0; j < sizeof(input_res_table)/sizeof(input_res_table[0]); j++)	{
+	        struct input_res *input = &input_res_table[j];
+		unsigned int hactive_s = input->w;
+		unsigned int vactive_s = input->h;
+		unsigned int htotal_s = htotal*hactive_s/hactive;
+		unsigned int vtotal_s = vtotal*vactive_s/vactive;
+	
+		mode_ptr = xnfcalloc(1, sizeof(DisplayModeRec));
+		mode_ptr->name = xnfalloc(strlen(tv_mode->name) + 
+			strlen(input->name) + 4);
+		sprintf(mode_ptr->name, "%s %s", tv_mode->name, input->name);
+		
+		mode_ptr->Clock = tv_mode->clock;
+
+		mode_ptr->HDisplay = hactive_s;
+		mode_ptr->HSyncStart = hactive_s + 1;
+		mode_ptr->HSyncEnd = htotal_s - 20;  
+		if ( mode_ptr->HSyncEnd <= mode_ptr->HSyncStart)
+			mode_ptr->HSyncEnd = mode_ptr->HSyncStart  + 1;
+		mode_ptr->HTotal = htotal_s;
+
+		mode_ptr->VDisplay = vactive_s;
+		mode_ptr->VSyncStart = vactive_s + 1;
+		mode_ptr->VSyncEnd = vtotal_s - 20;
+		if ( mode_ptr->VSyncEnd <= mode_ptr->VSyncStart)
+			mode_ptr->VSyncEnd = mode_ptr->VSyncStart  + 1;
+		mode_ptr->VTotal = vtotal_s;
+
+		mode_ptr->type = M_T_DRIVER;
+		mode_ptr->next = ret;
+		ret = mode_ptr;
+	} 
     }
 
-    return first;
+    return ret;
 }
 
 static void
diff --git a/src/i830_xf86Crtc.c b/src/i830_xf86Crtc.c
index ceb8f2e..1148c28 100644
--- a/src/i830_xf86Crtc.c
+++ b/src/i830_xf86Crtc.c
@@ -30,7 +30,7 @@
 
 #include "xf86.h"
 #include "xf86DDC.h"
-/*#include "i830.h" */
+#include "i830.h"
 #include "i830_xf86Crtc.h"
 #include "i830_xf86Modes.h"
 #include "i830_randr.h"
@@ -793,6 +793,7 @@ xf86ProbeOutputModes (ScrnInfoPtr pScrn,
     for (o = 0; o < config->num_output; o++) 
     {
 	xf86OutputPtr	    output = config->output[o];
+	I830OutputPrivatePtr intel_output = output->driver_private;
 	DisplayModePtr	    mode;
 	DisplayModePtr	    config_modes = NULL, output_modes, default_modes;
 	char		    *preferred_mode;
@@ -803,7 +804,6 @@ xf86ProbeOutputModes (ScrnInfoPtr pScrn,
 	int		    max_clock = 0;
 	double		    clock;
 	enum { sync_config, sync_edid, sync_default } sync_source = sync_default;
-	
 	while (output->probed_modes != NULL)
 	    xf86DeleteMode(&output->probed_modes, output->probed_modes);
 
@@ -902,8 +902,8 @@ xf86ProbeOutputModes (ScrnInfoPtr pScrn,
 	    mon_rec.nVrefresh = 1;
 	}
 	default_modes = i830xf86GetDefaultModes (output->interlaceAllowed,
-						 output->doubleScanAllowed);
-	
+			output->doubleScanAllowed);
+
 	if (sync_source == sync_config)
 	{
 	    /* 
@@ -926,8 +926,9 @@ xf86ProbeOutputModes (ScrnInfoPtr pScrn,
 	output->probed_modes = NULL;
 	output->probed_modes = xf86ModesAdd (output->probed_modes, config_modes);
 	output->probed_modes = xf86ModesAdd (output->probed_modes, output_modes);
-	output->probed_modes = xf86ModesAdd (output->probed_modes, default_modes);
-	
+	if (intel_output->type != I830_OUTPUT_TVOUT)	
+		output->probed_modes = xf86ModesAdd (output->probed_modes, default_modes);
+
 	/*
 	 * Check all modes against max size
 	 */
diff-tree 566e1d397744d0b477de4da6a206919906176f49 (from parents)
Merge: b13d6386dfb3a00bd9d21ac0695cdce9f812d1f3 da6a00f787e4d13e6b75768c1976f1c44ae5bf72
Author: Keith Packard <keithp at neko.keithp.com>
Date:   Mon Jan 8 12:37:49 2007 -0800

    Merge branch 'modesetting' into crestline

diff-tree b13d6386dfb3a00bd9d21ac0695cdce9f812d1f3 (from 7473e7d5297f94164e0f35822166713fb21a11bd)
Author: Keith Packard <keithp at neko.keithp.com>
Date:   Sun Jan 7 22:56:37 2007 -0800

    Back out rotation changes for RandR 1.2 which won't work.
    
    RandR 1.2 requires a new rotation structure for per-CRTC rotation.

diff --git a/src/i830.h b/src/i830.h
index a03f877..f89d022 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -195,8 +195,6 @@ extern const char *i830_output_type_name
 
 typedef struct _I830CrtcPrivateRec {
     int			    pipe;
-    Rotation 		    rotation;    /* current rotation, mirror from pI830->rotation */
-    Rotation		    rotations;  /* all */
     /* Lookup table values to be set when the CRTC is enabled */
     CARD8 lut_r[256], lut_g[256], lut_b[256];
 } I830CrtcPrivateRec, *I830CrtcPrivatePtr;
diff --git a/src/i830_display.c b/src/i830_display.c
index 3f9d882..f47a9db 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -821,9 +821,7 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, Dis
 	((adjusted_mode->CrtcVBlankEnd - 1) << 16));
     OUTREG(vsync_reg, (adjusted_mode->CrtcVSyncStart - 1) |
 	((adjusted_mode->CrtcVSyncEnd - 1) << 16));
-  /* XXX we might always set real line stride, rotation can change it */
-  //  OUTREG(dspstride_reg, pScrn->displayWidth * pI830->cpp);
-    OUTREG(dspstride_reg, pI830->displayWidth * pI830->cpp);
+    OUTREG(dspstride_reg, pScrn->displayWidth * pI830->cpp);
     /* pipesrc and dspsize control the size that is scaled from, which should
      * always be the user's requested size.
      */
diff --git a/src/i830_randr.c b/src/i830_randr.c
index 79b16e8..533322b 100644
--- a/src/i830_randr.c
+++ b/src/i830_randr.c
@@ -371,14 +371,6 @@ xf86RandR12GetRotation(ScreenPtr pScreen
     return randrp->rotation;
 }
 
-Rotation
-xf86RandR12GetRotation12(RRCrtcPtr randr_crtc)
-{
-    xf86CrtcPtr		crtc = randr_crtc->devPrivate;
-    I830CrtcPrivatePtr  intel_crtc = I830CrtcPrivate(crtc);
-    return intel_crtc->rotation;
-}
-
 Bool
 xf86RandR12CreateScreenResources (ScreenPtr pScreen)
 {
@@ -498,29 +490,12 @@ xf86RandR12Init (ScreenPtr pScreen)
     return TRUE;
 }
 
-/* RandR12 should have been initialized, so we might set rotations
-   to Crtc object. 
- */
 void
 xf86RandR12SetRotations (ScreenPtr pScreen, Rotation rotations)
 {
     XF86RandRInfoPtr	randrp = XF86RANDRINFO(pScreen);
-#if RANDR_12_INTERFACE
-    ScrnInfoPtr		pScrn = xf86Screens[pScreen->myNum];
-    xf86CrtcConfigPtr   config = XF86_CRTC_CONFIG_PTR(pScrn);
-    int c;
-#endif
 
     randrp->supported_rotations = rotations;
-#if RANDR_12_INTERFACE
-    for (c = 0; c < config->num_crtc ; c++) {
-	xf86CrtcPtr    crtc = config->crtc[c];
-	I830CrtcPrivatePtr intel_crtc = I830CrtcPrivate(crtc);
-	crtc->randr_crtc->rotations = rotations;
-	intel_crtc->rotations = rotations;
-	intel_crtc->rotation = RR_Rotate_0; /*XXX initial rotation fix */
-    }
-#endif
 }
 
 void
@@ -566,7 +541,7 @@ xf86RandR12CrtcNotify (RRCrtcPtr	randr_c
 	return FALSE;
     x = crtc->x;
     y = crtc->y;
-    rotation = xf86RandR12GetRotation12(randr_crtc);
+    rotation = RR_Rotate_0;
     numOutputs = 0;
     randr_mode = NULL;
     for (i = 0; i < config->num_output; i++)
@@ -597,9 +572,6 @@ xf86RandR12CrtcNotify (RRCrtcPtr	randr_c
     return ret;
 }
 
-extern Bool i830RandR12Rotate(ScreenPtr pScreen, RRCrtcPtr randr_crtc, 
-		DisplayModePtr mode, Rotation rotation);
-
 static Bool
 xf86RandR12CrtcSet (ScreenPtr	pScreen,
 		  RRCrtcPtr	randr_crtc,
@@ -616,8 +588,6 @@ xf86RandR12CrtcSet (ScreenPtr	pScreen,
     DisplayModePtr	mode = randr_mode ? randr_mode->devPrivate : NULL;
     Bool		changed = FALSE;
     Bool		pos_changed;
-    Bool		rotation_changed = FALSE;
-    Rotation 		old_rotation;
     int			o, ro;
     xf86CrtcPtr		*save_crtcs;
     Bool		save_enabled = crtc->enabled;
@@ -631,14 +601,6 @@ xf86RandR12CrtcSet (ScreenPtr	pScreen,
     pos_changed = changed;
     if (x != crtc->x || y != crtc->y)
 	pos_changed = TRUE;
-
-    old_rotation = xf86RandR12GetRotation12(randr_crtc);
-    if (rotation != old_rotation) {
-	changed = TRUE;
-	rotation_changed = TRUE;
-	pos_changed = TRUE;
-    }
-
     for (o = 0; o < config->num_output; o++) 
     {
 	xf86OutputPtr  output = config->output[o];
@@ -674,14 +636,6 @@ xf86RandR12CrtcSet (ScreenPtr	pScreen,
 	    pI830->AccelInfoRec->NeedToSync = FALSE;
 	}
 
-	/* rotation should take effect when crtc enabled*/
-	if (rotation_changed && crtc->enabled) {
-	    randr_crtc->rotation = rotation;
-	    if (!i830RandR12Rotate(pScreen, randr_crtc, mode, rotation)) {
-	        randr_crtc->rotation = old_rotation;
-  	    }
-        }
-
 	if (mode)
 	{
 	    if (!i830PipeSetMode (crtc, mode, TRUE))
diff --git a/src/i830_rotate.c b/src/i830_rotate.c
index 081690b..029f439 100644
--- a/src/i830_rotate.c
+++ b/src/i830_rotate.c
@@ -60,13 +60,9 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN
 #include "i830.h"
 #include "i915_reg.h"
 #include "i915_3d.h"
-#include "i830_xf86Crtc.h"
-#include "i830_randr.h"
 #include "brw_defines.h"
 #include "brw_structs.h"
 
-#include "brw_defines.h"
-#include "brw_structs.h"
 #ifdef XF86DRI
 #include "dri.h"
 #endif
@@ -1345,268 +1341,6 @@ I830UpdateRotate (ScreenPtr      pScreen
 #endif
 }
 
-static
-Bool i830_setup_shadowfb(ScrnInfoPtr pScrn, xf86CrtcPtr crtc)
-{
-    I830Ptr  		pI830 = I830PTR(pScrn);
-    I830CrtcPrivatePtr  intel_crtc = I830CrtcPrivate(crtc);
-    ShadowUpdateProc    func = NULL;
-
-    if (pI830->noAccel)
-        func = LoaderSymbol("shadowUpdateRotatePacked");
-    else {
-      if (IS_I9XX(pI830)) {
-	 if (IS_I965G(pI830))
-	     func = I965UpdateRotate;
-	 else 
-	     func = I915UpdateRotate;
-      } else
-	 func = I830UpdateRotate;
-    }
-
-    if (!func)
-	return FALSE;
-
-   shadowRemove (pScrn->pScreen, NULL);
-   if (intel_crtc->rotation != RR_Rotate_0) {
-      shadowAdd (pScrn->pScreen, 
-		 (*pScrn->pScreen->GetScreenPixmap) (pScrn->pScreen),
-		 func, I830WindowLinear, intel_crtc->rotation, 0);
-   }
-
-   if (intel_crtc->rotation != RR_Rotate_0)
-       pScrn->fbOffset = pI830->RotatedMem.Start;
-   else
-       pScrn->fbOffset = pI830->FrontBuffer.Start;
-
-   I830SelectBuffer(pScrn, I830_SELECT_FRONT);
-
-   pScrn->pScreen->ModifyPixmapHeader((*pScrn->pScreen->GetScreenPixmap)(pScrn->pScreen), 
-		    pScrn->pScreen->width,
-		    pScrn->pScreen->height, 
-		    pScrn->pScreen->rootDepth, pScrn->bitsPerPixel,
-		    PixmapBytePad(pScrn->displayWidth, pScrn->pScreen->rootDepth), 
-		    (pointer)(pI830->FbBase + pScrn->fbOffset));
-   (*pScrn->EnableDisableFBAccess) (pScrn->pScreen->myNum, FALSE);
-   (*pScrn->EnableDisableFBAccess) (pScrn->pScreen->myNum, TRUE);
-   
-   return TRUE;
-}
-
-static
-Bool i830_rotate_mem_realloc(ScrnInfoPtr pScrn, xf86CrtcPtr crtc)
-{
-   I830Ptr pI830 = I830PTR(pScrn);
-   I830CrtcPrivatePtr intel_crtc = I830CrtcPrivate(crtc);
-#ifdef XF86DRI
-    Bool 		didLock = FALSE;
-#endif
-    int i;
-
-#ifdef XF86DRI
-   if (pI830->directRenderingEnabled) {
-      didLock = I830DRILock(pScrn);
-      
-      /* Do heap teardown here
-       */
-      if (pI830->mmModeFlags & I830_KERNEL_TEX) {
-	 drmI830MemDestroyHeap destroy;
-	 destroy.region = I830_MEM_REGION_AGP;
-	 
-	 if (drmCommandWrite(pI830->drmSubFD, 
-			     DRM_I830_DESTROY_HEAP, 
-			     &destroy, sizeof(destroy))) {
-	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
-		       "[dri] I830 destroy heap failed\n");
-	 }
-      }
-      
-      if (pI830->mmModeFlags & I830_KERNEL_TEX) {
-	 if (pI830->TexMem.Key != -1)
-	    xf86UnbindGARTMemory(pScrn->scrnIndex, pI830->TexMem.Key);
-	 I830FreeVidMem(pScrn, &(pI830->TexMem));
-      }
-      if (pI830->StolenPool.Allocated.Key != -1) {
-         xf86UnbindGARTMemory(pScrn->scrnIndex, pI830->StolenPool.Allocated.Key);
-         xf86DeallocateGARTMemory(pScrn->scrnIndex, pI830->StolenPool.Allocated.Key);
-      }
-      if (pI830->DepthBuffer.Key != -1)
-         xf86UnbindGARTMemory(pScrn->scrnIndex, pI830->DepthBuffer.Key);
-      I830FreeVidMem(pScrn, &(pI830->DepthBuffer));
-      if (pI830->BackBuffer.Key != -1)
-         xf86UnbindGARTMemory(pScrn->scrnIndex, pI830->BackBuffer.Key);
-      I830FreeVidMem(pScrn, &(pI830->BackBuffer));
-   }
-#endif
-
-      if (pI830->RotatedMem.Key != -1)
-         xf86UnbindGARTMemory(pScrn->scrnIndex, pI830->RotatedMem.Key);
- 
-      I830FreeVidMem(pScrn, &(pI830->RotatedMem));
-      memset(&(pI830->RotatedMem), 0, sizeof(pI830->RotatedMem));
-      pI830->RotatedMem.Key = -1;
-
-      if (IS_I965G(pI830)) {
-         if (pI830->RotateStateMem.Key != -1)
-            xf86UnbindGARTMemory(pScrn->scrnIndex, pI830->RotateStateMem.Key);
- 
-         I830FreeVidMem(pScrn, &(pI830->RotateStateMem));
-         memset(&(pI830->RotateStateMem), 0, sizeof(pI830->RotateStateMem));
-      	 pI830->RotateStateMem.Key = -1;
-      }
-
-      if (intel_crtc->rotation != RR_Rotate_0) {
-         if (!I830AllocateRotatedBuffer(pScrn, pI830->disableTiling ? ALLOC_NO_TILING : 0))
-            goto BAIL1;
-
-         I830FixOffset(pScrn, &(pI830->RotatedMem));
-         if (pI830->RotatedMem.Key != -1)
-            xf86BindGARTMemory(pScrn->scrnIndex, pI830->RotatedMem.Key, pI830->RotatedMem.Offset);
-	 if (IS_I965G(pI830)) {
-            I830FixOffset(pScrn, &(pI830->RotateStateMem));
-            if (pI830->RotateStateMem.Key != -1)
-            	xf86BindGARTMemory(pScrn->scrnIndex, pI830->RotateStateMem.Key, 
-				   pI830->RotateStateMem.Offset);
-	 }
-      }
-  
-#ifdef XF86DRI
-   if (pI830->directRenderingEnabled) {
-      if (!I830AllocateBackBuffer(pScrn,
-			      pI830->disableTiling ? ALLOC_NO_TILING : 0))
-         goto BAIL2;
-
-      if (!I830AllocateDepthBuffer(pScrn,
-			      pI830->disableTiling ? ALLOC_NO_TILING : 0))
-         goto BAIL3;
-
-      if (pI830->mmModeFlags & I830_KERNEL_TEX) {
-	 if (!I830AllocateTextureMemory(pScrn,
-					pI830->disableTiling ? ALLOC_NO_TILING : 0))
-	    goto BAIL4;
-      }
-
-      I830DoPoolAllocation(pScrn, &(pI830->StolenPool));
-
-      I830FixOffset(pScrn, &(pI830->BackBuffer));
-      I830FixOffset(pScrn, &(pI830->DepthBuffer));
-
-      if (pI830->BackBuffer.Key != -1)
-         xf86BindGARTMemory(pScrn->scrnIndex, pI830->BackBuffer.Key, pI830->BackBuffer.Offset);
-      if (pI830->DepthBuffer.Key != -1)
-         xf86BindGARTMemory(pScrn->scrnIndex, pI830->DepthBuffer.Key, pI830->DepthBuffer.Offset);
-      if (pI830->StolenPool.Allocated.Key != -1)
-         xf86BindGARTMemory(pScrn->scrnIndex, pI830->StolenPool.Allocated.Key, pI830->StolenPool.Allocated.Offset);
-      if (pI830->mmModeFlags & I830_KERNEL_TEX) {
-	 if (pI830->TexMem.Key != -1)
-	    xf86BindGARTMemory(pScrn->scrnIndex, pI830->TexMem.Key, pI830->TexMem.Offset);
-      }
-      I830SetupMemoryTiling(pScrn);
-      /* update fence registers */
-      if (IS_I965G(pI830)) {
-         for (i = 0; i < FENCE_NEW_NR; i++) {
-            OUTREG(FENCE_NEW + i * 8, pI830->ModeReg.Fence[i]);
-            OUTREG(FENCE_NEW + 4 + i * 8, pI830->ModeReg.Fence[i+FENCE_NEW_NR]);
-         }
-      } else {
-         for (i = 0; i < 8; i++) 
-            OUTREG(FENCE + i * 4, pI830->ModeReg.Fence[i]);
-      }
-
-      {
-         drmI830Sarea *sarea = DRIGetSAREAPrivate(pScrn->pScreen);
-         I830UpdateDRIBuffers(pScrn, sarea );
-      }
-      
-      if (didLock)
-	 I830DRIUnlock(pScrn);
-   }
-#endif
-
-   return TRUE;
-BAIL1:
-BAIL2:
-BAIL3:
-BAIL4:
-   //XXX alloc failure
-   return FALSE;
-}
-
-Bool
-i830RandR12Rotate(ScreenPtr pScreen, RRCrtcPtr randr_crtc, 
-		DisplayModePtr mode, Rotation rotation)
-{
-    ScrnInfoPtr		pScrn = xf86Screens[pScreen->myNum];
-    I830Ptr  		pI830 = I830PTR(pScrn);
-    xf86CrtcPtr		crtc = randr_crtc->devPrivate;
-    I830CrtcPrivatePtr  intel_crtc = I830CrtcPrivate(crtc);
-    Rotation		old_rotation = intel_crtc->rotation;
-
-    if (old_rotation == rotation)
-	return TRUE;
-    intel_crtc->rotation = rotation;
-    pI830->rotation = rotation;
-
-   *pI830->used3D |= 1<<31; /* use high bit to denote new rotation occured */
-
-
-    /* user should have already changed screen size. */
-    /* pI830->displayWidth should always trigger current width in use, 
-       pScrn->displayWidth is current config in use. */
-   switch (intel_crtc->rotation) {
-      case RR_Rotate_0:
-	ErrorF("Rotating Screen to 0 degrees\n");
-         pScrn->displayWidth = pI830->displayWidth;
-         break;
-      case RR_Rotate_90:
-	ErrorF("Rotating Screen to 90 degrees\n");
-         pScrn->displayWidth = pScrn->pScreen->width;
-         break;
-      case RR_Rotate_180:
-	ErrorF("Rotating Screen to 180 degrees\n");
-         pScrn->displayWidth = pI830->displayWidth;
-         break;
-      case RR_Rotate_270:
-	ErrorF("Rotating Screen to 270 degrees\n");
-         pScrn->displayWidth = pScrn->pScreen->width;
-         break;
-   }
-   ErrorF("pScrn->displayWidth %d\n", pScrn->displayWidth);
-
-   if (!i830_rotate_mem_realloc(pScrn, crtc)) {
-	intel_crtc->rotation = old_rotation;
-	return FALSE;
-   }
-   
-   if (!i830_setup_shadowfb(pScrn, crtc)) {
-	intel_crtc->rotation = old_rotation;
-	return FALSE;
-   }
-
-
-#ifdef I830_USE_XAA
-   if (pI830->AccelInfoRec != NULL) {
-      /* Don't allow pixmap cache or offscreen pixmaps when rotated */
-      /* XAA needs some serious fixing for this to happen */
-      if (intel_crtc->rotation == RR_Rotate_0) {
-	 pI830->AccelInfoRec->Flags = LINEAR_FRAMEBUFFER | OFFSCREEN_PIXMAPS |
-				      PIXMAP_CACHE;
-	 pI830->AccelInfoRec->UsingPixmapCache = TRUE;
-	 /* funny as it seems this will enable XAA's createpixmap */
-	 pI830->AccelInfoRec->maxOffPixWidth = 0;
-	 pI830->AccelInfoRec->maxOffPixHeight = 0;
-      } else {
-	 pI830->AccelInfoRec->Flags = LINEAR_FRAMEBUFFER;
-	 pI830->AccelInfoRec->UsingPixmapCache = FALSE;
-	 /* funny as it seems this will disable XAA's createpixmap */
-	 pI830->AccelInfoRec->maxOffPixWidth = 1;
-	 pI830->AccelInfoRec->maxOffPixHeight = 1;
-      }
-   }
-#endif
-    return TRUE;
-}
-
 Bool
 I830Rotate(ScrnInfoPtr pScrn, DisplayModePtr mode)
 {
diff --git a/src/i830_sdvo.c b/src/i830_sdvo.c
index b66d226..ea62ad9 100644
--- a/src/i830_sdvo.c
+++ b/src/i830_sdvo.c
@@ -1095,6 +1095,7 @@ i830_sdvo_init(ScrnInfoPtr pScrn, int ou
     output->doubleScanAllowed = FALSE;
     
     dev_priv = (struct i830_sdvo_priv *) (intel_output + 1);
+    intel_output->type = I830_OUTPUT_SDVO;
 
     /* While it's the same bus, we just initialize a new copy to avoid trouble
      * with tracking refcounting ourselves, since the XFree86 DDX bits don't.
@@ -1218,7 +1219,7 @@ i830_sdvo_init(ScrnInfoPtr pScrn, int ou
 
     i830_sdvo_get_input_pixel_clock_range(output, &dev_priv->pixel_clock_min,
 					  &dev_priv->pixel_clock_max);
-    intel_output->type = I830_OUTPUT_SDVO;
+
     xf86DrvMsg(pScrn->scrnIndex, X_INFO,
 	       "%s device VID/DID: %02X:%02X.%02X, "
 	       "clock range %.1fMHz - %.1fMHz, "
diff --git a/src/i830_tv.c b/src/i830_tv.c
index 0ba2339..92e417e 100644
--- a/src/i830_tv.c
+++ b/src/i830_tv.c
@@ -422,15 +422,13 @@ i830_tv_dpms(xf86OutputPtr output, int m
 
     switch(mode) {
     case DPMSModeOn:
-            /* Wait for a Vblank when reenable TV encoder */
-	    i830WaitForVblank(pScrn);
-	    OUTREG(TV_CTL, INREG(TV_CTL) | TV_ENC_ENABLE);
-	    break;
+	OUTREG(TV_CTL, INREG(TV_CTL) | TV_ENC_ENABLE);
+	break;
     case DPMSModeStandby:
     case DPMSModeSuspend:
     case DPMSModeOff:
-	    /*OUTREG(TV_CTL, INREG(TV_CTL) & ~TV_ENC_ENABLE);*/
-	    break;
+	OUTREG(TV_CTL, INREG(TV_CTL) & ~TV_ENC_ENABLE);
+	break;
     }
 }
 
@@ -689,10 +687,10 @@ i830_tv_mode_set(xf86OutputPtr output, D
      * mode.  For now, just set the first one in the list, with
      * NTSC format.
      */
-    OUTREG(TV_CTL, INREG(TV_CTL) & ~TV_ENC_ENABLE);
     tv_mode = &tv_modes[0];
     
     tv_ctl = 0;
+
     switch (dev_priv->type) {
     default:
     case TV_TYPE_UNKNOWN:
@@ -783,8 +781,8 @@ i830_tv_mode_set(xf86OutputPtr output, D
 	tv_mode->dda3_inc << TV_SCDDA3_INC_SHIFT;
 
     /* Enable two fixes for the chips that need them. */
-    if (pI830->PciInfo->chipType < PCI_CHIP_I945_G) 
-	    tv_ctl |= TV_ENC_C0_FIX | TV_ENC_SDP_FIX;
+    if (pI830->PciInfo->chipType < PCI_CHIP_I945_G)
+	tv_ctl |= TV_ENC_C0_FIX | TV_ENC_SDP_FIX;
 
     tv_filter_ctl = TV_AUTO_SCALE;
     if (mode->HDisplay > 1024)
diff-tree 7473e7d5297f94164e0f35822166713fb21a11bd (from parents)
Merge: cdde9e7f4a0645ab1ee3e124de54433c1a250097 a87801f73a73e53524237be7835b8cd8b3eb282c
Author: Keith Packard <keithp at neko.keithp.com>
Date:   Sun Jan 7 22:50:27 2007 -0800

    Merge branch 'crestline-otc' into crestline

diff-tree cdde9e7f4a0645ab1ee3e124de54433c1a250097 (from parents)
Merge: 3110630e04f37e184609c91494fa7f9f4d59b93f 0fd2752f199928f846fe03c9087f7b6d48cc28d9
Author: Keith Packard <keithp at neko.keithp.com>
Date:   Sun Jan 7 22:50:12 2007 -0800

    Merge branch 'modesetting' into crestline

diff-tree 3110630e04f37e184609c91494fa7f9f4d59b93f (from parents)
Merge: be9b635b82c0c77ccc0555f178f94de6e5338e27 736d82a6b43f174cb95b425faacd4b0b889916fa
Author: Keith Packard <keithp at neko.keithp.com>
Date:   Sun Jan 7 22:44:36 2007 -0800

    Merge branch 'modesetting' into crestline
    
    Conflicts:
    
    	src/i830_rotate.c
    
    Pull in upstream changes to crestline branch leaving only
    the PCI-IDs as local changes.

diff --cc src/i830_rotate.c
index 1f1824b,029f439..081690b
@@@ -60,11 -60,9 +60,13 @@@
  #include "i830.h"
  #include "i915_reg.h"
  #include "i915_3d.h"
 +#include "i830_xf86Crtc.h"
 +#include "i830_randr.h"
+ #include "brw_defines.h"
+ #include "brw_structs.h"
  
 +#include "brw_defines.h"
 +#include "brw_structs.h"
  #ifdef XF86DRI
  #include "dri.h"
  #endif
diff-tree a87801f73a73e53524237be7835b8cd8b3eb282c (from 9cf759a2cb2580c4ac5f8cdc983389642f3cfce0)
Author: Wang Zhenyu <zhenyu.z.wang at intel.com>
Date:   Thu Jan 4 14:47:48 2007 +0800

    Fix TV load detect
    
    Actually load TV, otherwise we don't have expected
    reg state to probe.

diff --git a/src/i830_tv.c b/src/i830_tv.c
index 0580a95..5bd9eca 100644
--- a/src/i830_tv.c
+++ b/src/i830_tv.c
@@ -1067,6 +1067,7 @@ i830_tv_detect(xf86OutputPtr output)
 	    /* we only need the pixel clock set correctly here */
 	    mode = reported_modes[0];
 	    xf86SetModeCrtc (&mode, INTERLACE_HALVE_V);
+	    i830PipeSetMode (crtc, &mode, FALSE);
 	}
 	i830_tv_detect_type (crtc, output);
 	i830ReleaseLoadDetectPipe (output);
diff-tree 9cf759a2cb2580c4ac5f8cdc983389642f3cfce0 (from 9e48808fccf5b153c2fb4027f9a09944574fdace)
Author: Wang Zhenyu <zhenyu.z.wang at intel.com>
Date:   Thu Jan 4 14:35:55 2007 +0800

    minor fix on last exa mem binding commit

diff --git a/src/i830_memory.c b/src/i830_memory.c
index 3a3836c..af86688 100644
--- a/src/i830_memory.c
+++ b/src/i830_memory.c
@@ -2044,10 +2044,12 @@ I830UnbindAGPMemory(ScrnInfoPtr pScrn)
       }
 #endif
 #ifdef I830_USE_EXA
-     if (!UnbindMemRange(pScrn, &(pI830->Offscreen)))
-	return FALSE;
-     if (IS_I965G(pI830) && !UnbindMemRange(pScrn, &(pI830->EXAStateMem)))
-	return FALSE;
+     if (pI830->useEXA) {
+         if (!UnbindMemRange(pScrn, &(pI830->Offscreen)))
+	    return FALSE;
+         if (IS_I965G(pI830) && !UnbindMemRange(pScrn, &(pI830->EXAStateMem)))
+	    return FALSE;
+     }
 #endif
       if (!xf86ReleaseGART(pScrn->scrnIndex))
 	 return FALSE;
diff-tree be9b635b82c0c77ccc0555f178f94de6e5338e27 (from parents)
Merge: 9e48808fccf5b153c2fb4027f9a09944574fdace 5a793b0dcf2d5de408b55073858fcfba6d99f994
Author: Keith Packard <keithp at neko.keithp.com>
Date:   Wed Jan 3 22:15:53 2007 -0800

    Merge branch 'modesetting' into crestline

diff-tree 9e48808fccf5b153c2fb4027f9a09944574fdace (from ebd636dbd62cb69ed7defbd86f297c6bc7dac5dd)
Author: Wang Zhenyu <zhenyu.z.wang at intel.com>
Date:   Thu Jan 4 11:25:31 2007 +0800

    Fix EXA mem binding
    
    We should check if EXA is really enabled.

diff --git a/src/i830_memory.c b/src/i830_memory.c
index 29108c5..3a3836c 100644
--- a/src/i830_memory.c
+++ b/src/i830_memory.c
@@ -863,7 +863,7 @@ I830Allocate2DMemory(ScrnInfoPtr pScrn, 
 		       pI830->Offscreen.Start, pI830->Offscreen.Size/1024);
 	 }
       }
-      if (IS_I965G(pI830)) {
+      if (pI830->useEXA && IS_I965G(pI830)) {
           memset(&(pI830->EXAStateMem), 0, sizeof(I830MemRange));
           pI830->EXAStateMem.Key = -1;
           size = ROUND_TO_PAGE(EXA_LINEAR_EXTRA);
@@ -1535,9 +1535,11 @@ I830FixupOffsets(ScrnInfoPtr pScrn)
    }
 #endif
 #ifdef I830_USE_EXA
-   I830FixOffset(pScrn, &(pI830->Offscreen));
-   if (IS_I965G(pI830))
-       I830FixOffset(pScrn, &(pI830->EXAStateMem));
+   if (pI830->useEXA) {
+       I830FixOffset(pScrn, &(pI830->Offscreen));
+       if (IS_I965G(pI830))
+           I830FixOffset(pScrn, &(pI830->EXAStateMem));
+    }
 #endif
    return TRUE;
 }
@@ -1949,10 +1951,12 @@ I830BindAGPMemory(ScrnInfoPtr pScrn)
       }
 #endif
 #ifdef I830_USE_EXA
-     if (!BindMemRange(pScrn, &(pI830->Offscreen)))
-	return FALSE;
-     if (IS_I965G(pI830) && !BindMemRange(pScrn, &(pI830->EXAStateMem)))
-	return FALSE;
+     if (pI830->useEXA) {
+         if (!BindMemRange(pScrn, &(pI830->Offscreen)))
+	    return FALSE;
+         if (IS_I965G(pI830) && !BindMemRange(pScrn, &(pI830->EXAStateMem)))
+	    return FALSE;
+     }
 #endif
       pI830->GttBound = 1;
    }
diff-tree ebd636dbd62cb69ed7defbd86f297c6bc7dac5dd (from parents)
Merge: 75f0033ec41a34bbe695cfd4a9bc9aa60e919c99 3d9ea6f3c8a274f930d286fc15d3665dfaa8327a
Author: Wang Zhenyu <zhenyu.z.wang at intel.com>
Date:   Thu Jan 4 10:13:55 2007 +0800

    Merge branch 'modesetting' into crestline
    
    Conflicts:
    
    	src/i830.h
    	src/i830_randr.c

diff --cc src/i830.h
index 6c03a73,d5ca5d4..a03f877
@@@ -195,9 -194,8 +195,10 @@@
  
  typedef struct _I830CrtcPrivateRec {
      int			    pipe;
-     Bool		    gammaEnabled;
 +    Rotation 		    rotation;    /* current rotation, mirror from pI830->rotation */
 +    Rotation		    rotations;  /* all */
+     /* Lookup table values to be set when the CRTC is enabled */
+     CARD8 lut_r[256], lut_g[256], lut_b[256];
  } I830CrtcPrivateRec, *I830CrtcPrivatePtr;
  
  #define I830CrtcPrivate(c) ((I830CrtcPrivatePtr) (c)->driver_private)
diff --cc src/i830_memory.c
index 6944863,5bbf3e3..29108c5
@@@ -682,262 -801,46 +823,65 @@@
           I830EntPtr pI830Ent = pI830->entityPrivate;
           I830Ptr pI8302 = I830PTR(pI830Ent->pScrn_2);
  
-          /* Clear everything first. */
-          memset(&(pI830->FbMemBox2), 0, sizeof(pI830->FbMemBox2));
-          memset(&(pI830->FrontBuffer2), 0, sizeof(pI830->FrontBuffer2));
-          pI830->FrontBuffer2.Key = -1;
- 
- #if 1 /* ROTATION */
-          pI830->FbMemBox2.x1 = 0;
-          pI830->FbMemBox2.x2 = pI830Ent->pScrn_2->displayWidth;
-          pI830->FbMemBox2.y1 = 0;
-          if (pI830Ent->pScrn_2->virtualX > pI830Ent->pScrn_2->virtualY)
-             pI830->FbMemBox2.y2 = pI830Ent->pScrn_2->virtualX;
-          else
-             pI830->FbMemBox2.y2 = pI830Ent->pScrn_2->virtualY;
- #else
-          pI830->FbMemBox2.x1 = 0;
-          pI830->FbMemBox2.x2 = pI830Ent->pScrn_2->displayWidth;
-          pI830->FbMemBox2.y1 = 0;
-          pI830->FbMemBox2.y2 = pI830Ent->pScrn_2->virtualY;
- #endif
- 
-          /*
-           * Calculate how much framebuffer memory to allocate.  For the
-           * initial allocation, calculate a reasonable minimum.  This is
-           * enough for the virtual screen size, plus some pixmap cache
-           * space.
-           */
- 
-          lineSize = pI830Ent->pScrn_2->displayWidth * pI8302->cpp;
-          minspace = lineSize * pI830Ent->pScrn_2->virtualY;
-          avail = pI830Ent->pScrn_2->videoRam * 1024;
-          maxCacheLines = (avail - minspace) / lineSize;
-          /* This shouldn't happen. */
-          if (maxCacheLines < 0) {
- 	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- 		    "Internal Error: "
- 		    "maxCacheLines < 0 in I830Allocate2DMemory()\n");
- 	    maxCacheLines = 0;
-          }
-          if (maxCacheLines > (MAX_DISPLAY_HEIGHT - pI830Ent->pScrn_2->virtualY))
- 	    maxCacheLines = MAX_DISPLAY_HEIGHT - pI830Ent->pScrn_2->virtualY;
- 
-          if (pI8302->CacheLines >= 0) {
- 	    cacheLines = pI8302->CacheLines;
-          } else {
- #if 1
- 	    /* Make sure there is enough for two DVD sized YUV buffers */
- 	    cacheLines = (pI830Ent->pScrn_2->depth == 24) ? 256 : 384;
- 	    if (pI830Ent->pScrn_2->displayWidth <= 1024)
- 	       cacheLines *= 2;
- #else
- 	    /*
- 	     * Make sure there is enough for two DVD sized YUV buffers.
- 	     * Make that 1.5MB, which is around what was allocated with
- 	     * the old algorithm
- 	     */
- 	    cacheLines = (MB(1) + KB(512)) / pI8302->cpp / pI830Ent->pScrn_2->displayWidth;
- #endif
-          }
-          if (cacheLines > maxCacheLines)
- 	    cacheLines = maxCacheLines;
- 
-          pI830->FbMemBox2.y2 += cacheLines;
- 
-          xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
- 		     "%sAllocating at least %d scanlines for pixmap cache\n",
- 		     s, cacheLines);
- 
-          tileable = !(flags & ALLOC_NO_TILING) && pI8302->allowPageFlip &&
- 		 IsTileable(pI830Ent->pScrn_2->displayWidth * pI8302->cpp);
-          if (tileable) {
-             if (IS_I9XX(pI830))
-                align = MB(1);
-             else
- 	       align = KB(512);
- 	    alignflags = ALIGN_BOTH_ENDS;
-          } else {
- 	    align = KB(64);
- 	    alignflags = 0;
-          }
- 
- #if 1 /* ROTATION */
-          if (pI830Ent->pScrn_2->virtualX > pI830Ent->pScrn_2->virtualY)
-             size = lineSize * (pI830Ent->pScrn_2->virtualX + cacheLines);
-          else 
-             size = lineSize * (pI830Ent->pScrn_2->virtualY + cacheLines);
-          size = ROUND_TO_PAGE(size);
- #else
-          size = lineSize * (pI830Ent->pScrn_2->virtualY + cacheLines);
-          size = ROUND_TO_PAGE(size);
- #endif
-          xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
- 		     "%sSecondary framebuffer allocation size: %ld kByte\n", s,
- 		     size / 1024);
-          alloced = I830AllocVidMem(pScrn, &(pI830->FrontBuffer2),
- 				&(pI830->StolenPool), size, align,
- 				flags | alignflags |
- 				FROM_ANYWHERE | ALLOCATE_AT_BOTTOM);
-          if (alloced < size) {
- 	    if (!dryrun) {
- 	       xf86DrvMsg(pI830Ent->pScrn_2->scrnIndex, X_ERROR,
- 		       "Failed to allocate secondary framebuffer.\n");
- 	    }
-             return FALSE;
-          }
-       }
- 
-       /* Clear everything first. */
-       memset(&(pI830->FbMemBox), 0, sizeof(pI830->FbMemBox));
-       memset(&(pI830->FrontBuffer), 0, sizeof(pI830->FrontBuffer));
-       pI830->FrontBuffer.Key = -1;
- 
- #if 1 /* ROTATION */
-       pI830->FbMemBox.x1 = 0;
-       pI830->FbMemBox.x2 = pScrn->displayWidth;
-       pI830->FbMemBox.y1 = 0;
-       if (pScrn->virtualX > pScrn->virtualY)
-          pI830->FbMemBox.y2 = pScrn->virtualX;
-       else
-          pI830->FbMemBox.y2 = pScrn->virtualY;
- #else
-       pI830->FbMemBox.x1 = 0;
-       pI830->FbMemBox.x2 = pScrn->displayWidth;
-       pI830->FbMemBox.y1 = 0;
-       pI830->FbMemBox.y2 = pScrn->virtualY;
- #endif
- 
-       /*
-        * Calculate how much framebuffer memory to allocate.  For the
-        * initial allocation, calculate a reasonable minimum.  This is
-        * enough for the virtual screen size, plus some pixmap cache
-        * space.
-        */
- 
-       lineSize = pScrn->displayWidth * pI830->cpp;
-       minspace = lineSize * pScrn->virtualY;
-       avail = pScrn->videoRam * 1024;
-       maxCacheLines = (avail - minspace) / lineSize;
-       /* This shouldn't happen. */
-       if (maxCacheLines < 0) {
- 	 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- 		    "Internal Error: "
- 		    "maxCacheLines < 0 in I830Allocate2DMemory()\n");
- 	 maxCacheLines = 0;
-       }
-       if (maxCacheLines > (MAX_DISPLAY_HEIGHT - pScrn->virtualY))
- 	 maxCacheLines = MAX_DISPLAY_HEIGHT - pScrn->virtualY;
- 
-       if (pI830->CacheLines >= 0) {
- 	 cacheLines = pI830->CacheLines;
-       } else {
- #if 1
- 	 /* Make sure there is enough for two DVD sized YUV buffers */
- 	 cacheLines = (pScrn->depth == 24) ? 256 : 384;
- 	 if (pScrn->displayWidth <= 1024)
- 	    cacheLines *= 2;
- #else
- 	 /*
- 	  * Make sure there is enough for two DVD sized YUV buffers.
- 	  * Make that 1.5MB, which is around what was allocated with
- 	  * the old algorithm
- 	  */
- 	 cacheLines = (MB(1) + KB(512)) / pI830->cpp / pScrn->displayWidth;
- #endif
-       }
-       if (cacheLines > maxCacheLines)
- 	 cacheLines = maxCacheLines;
- 
-       pI830->FbMemBox.y2 += cacheLines;
- 
-       xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
- 		     "%sAllocating at least %d scanlines for pixmap cache\n",
- 		     s, cacheLines);
- 
-       tileable = !(flags & ALLOC_NO_TILING) && pI830->allowPageFlip &&
- 		 IsTileable(pScrn->displayWidth * pI830->cpp);
-       if (tileable) {
-          if (IS_I9XX(pI830))
-             align = MB(1);
-          else
- 	    align = KB(512);
- 	 alignflags = ALIGN_BOTH_ENDS;
-       } else {
- 	 align = KB(64);
- 	 alignflags = 0;
-       }
- 
- #if 1 /* ROTATION */
-       if (pScrn->virtualX > pScrn->virtualY)
-          size = lineSize * (pScrn->virtualX + cacheLines);
-       else 
-          size = lineSize * (pScrn->virtualY + cacheLines);
-       size = ROUND_TO_PAGE(size);
- #else
-       size = lineSize * (pScrn->virtualY + cacheLines);
-       size = ROUND_TO_PAGE(size);
- #endif
-       xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
- 		     "%sInitial framebuffer allocation size: %ld kByte\n", s,
- 		     size / 1024);
-       alloced = I830AllocVidMem(pScrn, &(pI830->FrontBuffer),
- 				&(pI830->StolenPool), size, align,
- 				flags | alignflags |
- 				FROM_ANYWHERE | ALLOCATE_AT_BOTTOM);
-       if (alloced < size) {
- 	 if (!dryrun) {
- 	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to allocate "
- 	    		"framebuffer. Is your VideoRAM set too low ??\n");
+ 	 if (!I830AllocateFramebuffer(pI830Ent->pScrn_2, pI8302,
+ 				      &pI830->FbMemBox2,
+ 				      &pI830->FrontBuffer2, &pI830->StolenPool,
+ 				      TRUE, flags))
+ 	 {
+ 	    return FALSE;
  	 }
- 	 return FALSE;
        }
- #ifdef I830_USE_EXA
-       size = lineSize * pScrn->virtualY;
-       size = ROUND_TO_PAGE(size);
- 
-       if (tileable) {
- 	 align = KB(512);
- 	 alignflags = ALIGN_BOTH_ENDS;
-       } else {
- 	 align = KB(64);
- 	 alignflags = 0;
+       if (!I830AllocateFramebuffer(pScrn, pI830, &pI830->FbMemBox,
+ 				   &pI830->FrontBuffer, &pI830->StolenPool,
+ 				   FALSE, flags))
+       {
+ 	 return FALSE;
        }
  
-       alloced = I830AllocVidMem(pScrn, &(pI830->Offscreen),
- 				&(pI830->StolenPool), size, align,
- 				flags | alignflags |
- 				FROM_ANYWHERE | ALLOCATE_AT_BOTTOM);
-       if (alloced < size) {
- 	 if (!dryrun) {
- 	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to allocate "
- 		       "offscreen memory.  Not enough VRAM?\n");
+ #ifdef I830_USE_EXA
+       if (pI830->useEXA) {
+ 	 /* Default EXA to having 3 screens worth of offscreen memory space
+ 	  * (for pixmaps), plus a double-buffered, 1920x1088 video's worth.
+ 	  */
+ 	 size = 3 * pScrn->displayWidth * pI830->cpp * pScrn->virtualY;
+ 	 size += 1920 * 1088 * 2 * 2;
+ 	 size = ROUND_TO_PAGE(size);
+ 
+ 	 alloced = I830AllocVidMem(pScrn, &(pI830->Offscreen),
+ 				   &(pI830->StolenPool), size, 1,
+ 				   flags |
+ 				   FROM_ANYWHERE | ALLOCATE_AT_BOTTOM);
+ 	 if (alloced < size) {
+ 	    if (!dryrun) {
+ 	       xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to allocate "
+ 			  "offscreen memory.  Not enough VRAM?\n");
+ 	    }
+ 	    return FALSE;
+ 	 } else {
+ 	    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Successful allocation of "
+ 		       "EXA offscreen memory at 0x%lx, size %ld KB\n",
+ 		       pI830->Offscreen.Start, pI830->Offscreen.Size/1024);
  	 }
- 	 return FALSE;
-       } else {
- 	    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Successful allocate "
- 		       "offscreen memory at 0x%lx, size %ld KB\n", 
- 			pI830->Offscreen.Start, pI830->Offscreen.Size/1024);
        }
 +      if (IS_I965G(pI830)) {
 +          memset(&(pI830->EXAStateMem), 0, sizeof(I830MemRange));
 +          pI830->EXAStateMem.Key = -1;
 +          size = ROUND_TO_PAGE(EXA_LINEAR_EXTRA);
 +          align = GTT_PAGE_SIZE;
 +          alloced = I830AllocVidMem(pScrn, &(pI830->EXAStateMem),
 +				&(pI830->StolenPool), size, align,
 +				flags | FROM_ANYWHERE | ALLOCATE_AT_TOP);
 +          if (alloced < size) {
 +             if (!dryrun) {
 +         	 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
 +		    "G965: Failed to allocate exa state buffer space.\n");
 +             }
 +             return FALSE;
 +          }
 +          xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
 + 		  "%sAllocated %ld kB for the G965 exa state buffer at 0x%lx - 0x%lx.\n", s, 
 + 		alloced / 1024, pI830->EXAStateMem.Start, pI830->EXAStateMem.End);
 +      }
  #endif
     } else {
        long lineSize;
diff --cc src/i830_sdvo.c
index 8e38779,19b4b93..4fc5921
@@@ -1091,8 -1091,11 +1091,10 @@@
  	return;
      }
      output->driver_private = intel_output;
+     output->interlaceAllowed = FALSE;
+     output->doubleScanAllowed = FALSE;
      
      dev_priv = (struct i830_sdvo_priv *) (intel_output + 1);
 -    intel_output->type = I830_OUTPUT_SDVO;
  
      /* While it's the same bus, we just initialize a new copy to avoid trouble
       * with tracking refcounting ourselves, since the XFree86 DDX bits don't.
diff-tree 3d9ea6f3c8a274f930d286fc15d3665dfaa8327a (from parents)
Merge: 75f4df278e9db360967d77cdba4756cbde622d56 394124ceaadb46d976ad5c3bdeb1b77d351c57f6
Author: Wang Zhenyu <zhenyu.z.wang at intel.com>
Date:   Thu Jan 4 10:12:50 2007 +0800

    Merge branch 'modesetting' of git+ssh://zhen@git.freedesktop.org/git/xorg/driver/xf86-video-intel into modesetting
    
    Conflicts:
    
    	src/i830_driver.c

diff-tree 75f0033ec41a34bbe695cfd4a9bc9aa60e919c99 (from fbd3f588f0d412c20cc3f86dfad73700734a9a76)
Author: Wang Zhenyu <zhenyu.z.wang at intel.com>
Date:   Sun Dec 31 15:16:59 2006 +0800

    Issue current virtual size to mode valid.
    
    Revert change in rotation patch.

diff --git a/src/i830_xf86Crtc.c b/src/i830_xf86Crtc.c
index 6e836bd..0c482a2 100644
--- a/src/i830_xf86Crtc.c
+++ b/src/i830_xf86Crtc.c
@@ -517,7 +517,6 @@ xf86SetScrnInfoModes (ScrnInfoPtr pScrn)
     xf86CrtcPtr		crtc;
     DisplayModePtr	last, mode;
     int			originalVirtualX, originalVirtualY;
-    I830Ptr		pI830 = I830PTR(pScrn);
 
     output = config->output[config->compat_output];
     if (!output->crtc)
@@ -550,10 +549,9 @@ xf86SetScrnInfoModes (ScrnInfoPtr pScrn)
     /* Disable modes in the XFree86 DDX list that are larger than the current
      * virtual size.
      */
-    /* pass real line pitch, rotation might change this */
     i830xf86ValidateModesSize(pScrn, pScrn->modes,
 			      originalVirtualX, originalVirtualY,
-			      pI830->displayWidth);
+			      pScrn->displayWidth);
 
     /* Strip out anything that we threw out for virtualX/Y. */
     i830xf86PruneInvalidModes(pScrn, &pScrn->modes, TRUE);
diff-tree fbd3f588f0d412c20cc3f86dfad73700734a9a76 (from a1796bfb51d90fd545973909404e1a77ad27c9cc)
Author: Wang Zhenyu <zhenyu.z.wang at intel.com>
Date:   Fri Dec 29 10:47:52 2006 +0800

    rotation support for randr-1.2
    
    This patch trys to resolve rotation regression with randr-1.2.
    Tested with Crestline VGA output. See bug 83.

diff --git a/src/i830.h b/src/i830.h
index 20bcde6..6c03a73 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -196,6 +196,8 @@ extern const char *i830_output_type_name
 typedef struct _I830CrtcPrivateRec {
     int			    pipe;
     Bool		    gammaEnabled;
+    Rotation 		    rotation;    /* current rotation, mirror from pI830->rotation */
+    Rotation		    rotations;  /* all */
 } I830CrtcPrivateRec, *I830CrtcPrivatePtr;
 
 #define I830CrtcPrivate(c) ((I830CrtcPrivatePtr) (c)->driver_private)
diff --git a/src/i830_display.c b/src/i830_display.c
index c5880d6..b70f1eb 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -821,7 +821,9 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, Dis
 	((adjusted_mode->CrtcVBlankEnd - 1) << 16));
     OUTREG(vsync_reg, (adjusted_mode->CrtcVSyncStart - 1) |
 	((adjusted_mode->CrtcVSyncEnd - 1) << 16));
-    OUTREG(dspstride_reg, pScrn->displayWidth * pI830->cpp);
+  /* XXX we might always set real line stride, rotation can change it */
+  //  OUTREG(dspstride_reg, pScrn->displayWidth * pI830->cpp);
+    OUTREG(dspstride_reg, pI830->displayWidth * pI830->cpp);
     /* pipesrc and dspsize control the size that is scaled from, which should
      * always be the user's requested size.
      */
diff --git a/src/i830_driver.c b/src/i830_driver.c
index 23729de..5e66038 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -2950,11 +2950,7 @@ I830ScreenInit(int scrnIndex, ScreenPtr 
       shadowSetup(pScreen);
       /* support all rotations */
       xf86RandR12Init (pScreen);
-      if (IS_I965G(pI830)) {
-	 xf86RandR12SetRotations (pScreen, RR_Rotate_0); /* only 0 degrees for I965G */
-      } else {
-	 xf86RandR12SetRotations (pScreen, RR_Rotate_0 | RR_Rotate_90 | RR_Rotate_180 | RR_Rotate_270);
-      }
+      xf86RandR12SetRotations (pScreen, RR_Rotate_0 | RR_Rotate_90 | RR_Rotate_180 | RR_Rotate_270);
       pI830->PointerMoved = pScrn->PointerMoved;
       pScrn->PointerMoved = I830PointerMoved;
       pI830->CreateScreenResources = pScreen->CreateScreenResources;
diff --git a/src/i830_randr.c b/src/i830_randr.c
index 3d6febc..019e71c 100644
--- a/src/i830_randr.c
+++ b/src/i830_randr.c
@@ -333,6 +333,14 @@ xf86RandR12GetRotation(ScreenPtr pScreen
     return randrp->rotation;
 }
 
+Rotation
+xf86RandR12GetRotation12(RRCrtcPtr randr_crtc)
+{
+    xf86CrtcPtr		crtc = randr_crtc->devPrivate;
+    I830CrtcPrivatePtr  intel_crtc = I830CrtcPrivate(crtc);
+    return intel_crtc->rotation;
+}
+
 Bool
 xf86RandR12CreateScreenResources (ScreenPtr pScreen)
 {
@@ -422,12 +430,29 @@ xf86RandR12Init (ScreenPtr pScreen)
     return TRUE;
 }
 
+/* RandR12 should have been initialized, so we might set rotations
+   to Crtc object. 
+ */
 void
 xf86RandR12SetRotations (ScreenPtr pScreen, Rotation rotations)
 {
     XF86RandRInfoPtr	randrp = XF86RANDRINFO(pScreen);
+#if RANDR_12_INTERFACE
+    ScrnInfoPtr		pScrn = xf86Screens[pScreen->myNum];
+    xf86CrtcConfigPtr   config = XF86_CRTC_CONFIG_PTR(pScrn);
+    int c;
+#endif
 
     randrp->supported_rotations = rotations;
+#if RANDR_12_INTERFACE
+    for (c = 0; c < config->num_crtc ; c++) {
+	xf86CrtcPtr    crtc = config->crtc[c];
+	I830CrtcPrivatePtr intel_crtc = I830CrtcPrivate(crtc);
+	crtc->randr_crtc->rotations = rotations;
+	intel_crtc->rotations = rotations;
+	intel_crtc->rotation = RR_Rotate_0; /*XXX initial rotation fix */
+    }
+#endif
 }
 
 void
@@ -468,11 +493,13 @@ xf86RandR12ScreenSetSize (ScreenPtr	pScr
     }
     if (pRoot)
 	(*pScrn->EnableDisableFBAccess) (pScreen->myNum, FALSE);
-    pScrn->virtualX = width;
-    pScrn->virtualY = height;
-
-    pScreen->width = pScrn->virtualX;
-    pScreen->height = pScrn->virtualY;
+    /* XXX don't change the actual draw window size */
+    /*pScrn->virtualX = width;
+     *pScrn->virtualY = height;
+     *pScreen->width = pScrn->virtualX;
+     *pScreen->height = pScrn->virtualY;*/
+    pScreen->width = width;
+    pScreen->height = height;
     pScreen->mmWidth = mmWidth;
     pScreen->mmHeight = mmHeight;
 
@@ -509,7 +536,7 @@ xf86RandR12CrtcNotify (RRCrtcPtr	randr_c
 	return FALSE;
     x = crtc->x;
     y = crtc->y;
-    rotation = RR_Rotate_0;
+    rotation = xf86RandR12GetRotation12(randr_crtc);
     numOutputs = 0;
     randr_mode = NULL;
     for (i = 0; i < config->num_output; i++)
@@ -540,6 +567,9 @@ xf86RandR12CrtcNotify (RRCrtcPtr	randr_c
     return ret;
 }
 
+extern Bool i830RandR12Rotate(ScreenPtr pScreen, RRCrtcPtr randr_crtc, 
+		DisplayModePtr mode, Rotation rotation);
+
 static Bool
 xf86RandR12CrtcSet (ScreenPtr	pScreen,
 		  RRCrtcPtr	randr_crtc,
@@ -556,6 +586,8 @@ xf86RandR12CrtcSet (ScreenPtr	pScreen,
     DisplayModePtr	mode = randr_mode ? randr_mode->devPrivate : NULL;
     Bool		changed = FALSE;
     Bool		pos_changed;
+    Bool		rotation_changed = FALSE;
+    Rotation 		old_rotation;
     int			o, ro;
     xf86CrtcPtr		*save_crtcs;
     Bool		save_enabled = crtc->enabled;
@@ -569,6 +601,14 @@ xf86RandR12CrtcSet (ScreenPtr	pScreen,
     pos_changed = changed;
     if (x != crtc->x || y != crtc->y)
 	pos_changed = TRUE;
+
+    old_rotation = xf86RandR12GetRotation12(randr_crtc);
+    if (rotation != old_rotation) {
+	changed = TRUE;
+	rotation_changed = TRUE;
+	pos_changed = TRUE;
+    }
+
     for (o = 0; o < config->num_output; o++) 
     {
 	xf86OutputPtr  output = config->output[o];
@@ -604,6 +644,14 @@ xf86RandR12CrtcSet (ScreenPtr	pScreen,
 	    pI830->AccelInfoRec->NeedToSync = FALSE;
 	}
 
+	/* rotation should take effect when crtc enabled*/
+	if (rotation_changed && crtc->enabled) {
+	    randr_crtc->rotation = rotation;
+	    if (!i830RandR12Rotate(pScreen, randr_crtc, mode, rotation)) {
+	        randr_crtc->rotation = old_rotation;
+  	    }
+        }
+
 	if (mode)
 	{
 	    if (!i830PipeSetMode (crtc, mode, TRUE))
diff --git a/src/i830_rotate.c b/src/i830_rotate.c
index b2587b2..1f1824b 100644
--- a/src/i830_rotate.c
+++ b/src/i830_rotate.c
@@ -60,9 +60,11 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN
 #include "i830.h"
 #include "i915_reg.h"
 #include "i915_3d.h"
+#include "i830_xf86Crtc.h"
+#include "i830_randr.h"
+
 #include "brw_defines.h"
 #include "brw_structs.h"
-
 #ifdef XF86DRI
 #include "dri.h"
 #endif
@@ -1341,6 +1343,268 @@ I830UpdateRotate (ScreenPtr      pScreen
 #endif
 }
 
+static
+Bool i830_setup_shadowfb(ScrnInfoPtr pScrn, xf86CrtcPtr crtc)
+{
+    I830Ptr  		pI830 = I830PTR(pScrn);
+    I830CrtcPrivatePtr  intel_crtc = I830CrtcPrivate(crtc);
+    ShadowUpdateProc    func = NULL;
+
+    if (pI830->noAccel)
+        func = LoaderSymbol("shadowUpdateRotatePacked");
+    else {
+      if (IS_I9XX(pI830)) {
+	 if (IS_I965G(pI830))
+	     func = I965UpdateRotate;
+	 else 
+	     func = I915UpdateRotate;
+      } else
+	 func = I830UpdateRotate;
+    }
+
+    if (!func)
+	return FALSE;
+
+   shadowRemove (pScrn->pScreen, NULL);
+   if (intel_crtc->rotation != RR_Rotate_0) {
+      shadowAdd (pScrn->pScreen, 
+		 (*pScrn->pScreen->GetScreenPixmap) (pScrn->pScreen),
+		 func, I830WindowLinear, intel_crtc->rotation, 0);
+   }
+
+   if (intel_crtc->rotation != RR_Rotate_0)
+       pScrn->fbOffset = pI830->RotatedMem.Start;
+   else
+       pScrn->fbOffset = pI830->FrontBuffer.Start;
+
+   I830SelectBuffer(pScrn, I830_SELECT_FRONT);
+
+   pScrn->pScreen->ModifyPixmapHeader((*pScrn->pScreen->GetScreenPixmap)(pScrn->pScreen), 
+		    pScrn->pScreen->width,
+		    pScrn->pScreen->height, 
+		    pScrn->pScreen->rootDepth, pScrn->bitsPerPixel,
+		    PixmapBytePad(pScrn->displayWidth, pScrn->pScreen->rootDepth), 
+		    (pointer)(pI830->FbBase + pScrn->fbOffset));
+   (*pScrn->EnableDisableFBAccess) (pScrn->pScreen->myNum, FALSE);
+   (*pScrn->EnableDisableFBAccess) (pScrn->pScreen->myNum, TRUE);
+   
+   return TRUE;
+}
+
+static
+Bool i830_rotate_mem_realloc(ScrnInfoPtr pScrn, xf86CrtcPtr crtc)
+{
+   I830Ptr pI830 = I830PTR(pScrn);
+   I830CrtcPrivatePtr intel_crtc = I830CrtcPrivate(crtc);
+#ifdef XF86DRI
+    Bool 		didLock = FALSE;
+#endif
+    int i;
+
+#ifdef XF86DRI
+   if (pI830->directRenderingEnabled) {
+      didLock = I830DRILock(pScrn);
+      
+      /* Do heap teardown here
+       */
+      if (pI830->mmModeFlags & I830_KERNEL_TEX) {
+	 drmI830MemDestroyHeap destroy;
+	 destroy.region = I830_MEM_REGION_AGP;
+	 
+	 if (drmCommandWrite(pI830->drmSubFD, 
+			     DRM_I830_DESTROY_HEAP, 
+			     &destroy, sizeof(destroy))) {
+	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+		       "[dri] I830 destroy heap failed\n");
+	 }
+      }
+      
+      if (pI830->mmModeFlags & I830_KERNEL_TEX) {
+	 if (pI830->TexMem.Key != -1)
+	    xf86UnbindGARTMemory(pScrn->scrnIndex, pI830->TexMem.Key);
+	 I830FreeVidMem(pScrn, &(pI830->TexMem));
+      }
+      if (pI830->StolenPool.Allocated.Key != -1) {
+         xf86UnbindGARTMemory(pScrn->scrnIndex, pI830->StolenPool.Allocated.Key);
+         xf86DeallocateGARTMemory(pScrn->scrnIndex, pI830->StolenPool.Allocated.Key);
+      }
+      if (pI830->DepthBuffer.Key != -1)
+         xf86UnbindGARTMemory(pScrn->scrnIndex, pI830->DepthBuffer.Key);
+      I830FreeVidMem(pScrn, &(pI830->DepthBuffer));
+      if (pI830->BackBuffer.Key != -1)
+         xf86UnbindGARTMemory(pScrn->scrnIndex, pI830->BackBuffer.Key);
+      I830FreeVidMem(pScrn, &(pI830->BackBuffer));
+   }
+#endif
+
+      if (pI830->RotatedMem.Key != -1)
+         xf86UnbindGARTMemory(pScrn->scrnIndex, pI830->RotatedMem.Key);
+ 
+      I830FreeVidMem(pScrn, &(pI830->RotatedMem));
+      memset(&(pI830->RotatedMem), 0, sizeof(pI830->RotatedMem));
+      pI830->RotatedMem.Key = -1;
+
+      if (IS_I965G(pI830)) {
+         if (pI830->RotateStateMem.Key != -1)
+            xf86UnbindGARTMemory(pScrn->scrnIndex, pI830->RotateStateMem.Key);
+ 
+         I830FreeVidMem(pScrn, &(pI830->RotateStateMem));
+         memset(&(pI830->RotateStateMem), 0, sizeof(pI830->RotateStateMem));
+      	 pI830->RotateStateMem.Key = -1;
+      }
+
+      if (intel_crtc->rotation != RR_Rotate_0) {
+         if (!I830AllocateRotatedBuffer(pScrn, pI830->disableTiling ? ALLOC_NO_TILING : 0))
+            goto BAIL1;
+
+         I830FixOffset(pScrn, &(pI830->RotatedMem));
+         if (pI830->RotatedMem.Key != -1)
+            xf86BindGARTMemory(pScrn->scrnIndex, pI830->RotatedMem.Key, pI830->RotatedMem.Offset);
+	 if (IS_I965G(pI830)) {
+            I830FixOffset(pScrn, &(pI830->RotateStateMem));
+            if (pI830->RotateStateMem.Key != -1)
+            	xf86BindGARTMemory(pScrn->scrnIndex, pI830->RotateStateMem.Key, 
+				   pI830->RotateStateMem.Offset);
+	 }
+      }
+  
+#ifdef XF86DRI
+   if (pI830->directRenderingEnabled) {
+      if (!I830AllocateBackBuffer(pScrn,
+			      pI830->disableTiling ? ALLOC_NO_TILING : 0))
+         goto BAIL2;
+
+      if (!I830AllocateDepthBuffer(pScrn,
+			      pI830->disableTiling ? ALLOC_NO_TILING : 0))
+         goto BAIL3;
+
+      if (pI830->mmModeFlags & I830_KERNEL_TEX) {
+	 if (!I830AllocateTextureMemory(pScrn,
+					pI830->disableTiling ? ALLOC_NO_TILING : 0))
+	    goto BAIL4;
+      }
+
+      I830DoPoolAllocation(pScrn, &(pI830->StolenPool));
+
+      I830FixOffset(pScrn, &(pI830->BackBuffer));
+      I830FixOffset(pScrn, &(pI830->DepthBuffer));
+
+      if (pI830->BackBuffer.Key != -1)
+         xf86BindGARTMemory(pScrn->scrnIndex, pI830->BackBuffer.Key, pI830->BackBuffer.Offset);
+      if (pI830->DepthBuffer.Key != -1)
+         xf86BindGARTMemory(pScrn->scrnIndex, pI830->DepthBuffer.Key, pI830->DepthBuffer.Offset);
+      if (pI830->StolenPool.Allocated.Key != -1)
+         xf86BindGARTMemory(pScrn->scrnIndex, pI830->StolenPool.Allocated.Key, pI830->StolenPool.Allocated.Offset);
+      if (pI830->mmModeFlags & I830_KERNEL_TEX) {
+	 if (pI830->TexMem.Key != -1)
+	    xf86BindGARTMemory(pScrn->scrnIndex, pI830->TexMem.Key, pI830->TexMem.Offset);
+      }
+      I830SetupMemoryTiling(pScrn);
+      /* update fence registers */
+      if (IS_I965G(pI830)) {
+         for (i = 0; i < FENCE_NEW_NR; i++) {
+            OUTREG(FENCE_NEW + i * 8, pI830->ModeReg.Fence[i]);
+            OUTREG(FENCE_NEW + 4 + i * 8, pI830->ModeReg.Fence[i+FENCE_NEW_NR]);
+         }
+      } else {
+         for (i = 0; i < 8; i++) 
+            OUTREG(FENCE + i * 4, pI830->ModeReg.Fence[i]);
+      }
+
+      {
+         drmI830Sarea *sarea = DRIGetSAREAPrivate(pScrn->pScreen);
+         I830UpdateDRIBuffers(pScrn, sarea );
+      }
+      
+      if (didLock)
+	 I830DRIUnlock(pScrn);
+   }
+#endif
+
+   return TRUE;
+BAIL1:
+BAIL2:
+BAIL3:
+BAIL4:
+   //XXX alloc failure
+   return FALSE;
+}
+
+Bool
+i830RandR12Rotate(ScreenPtr pScreen, RRCrtcPtr randr_crtc, 
+		DisplayModePtr mode, Rotation rotation)
+{
+    ScrnInfoPtr		pScrn = xf86Screens[pScreen->myNum];
+    I830Ptr  		pI830 = I830PTR(pScrn);
+    xf86CrtcPtr		crtc = randr_crtc->devPrivate;
+    I830CrtcPrivatePtr  intel_crtc = I830CrtcPrivate(crtc);
+    Rotation		old_rotation = intel_crtc->rotation;
+
+    if (old_rotation == rotation)
+	return TRUE;
+    intel_crtc->rotation = rotation;
+    pI830->rotation = rotation;
+
+   *pI830->used3D |= 1<<31; /* use high bit to denote new rotation occured */
+
+
+    /* user should have already changed screen size. */
+    /* pI830->displayWidth should always trigger current width in use, 
+       pScrn->displayWidth is current config in use. */
+   switch (intel_crtc->rotation) {
+      case RR_Rotate_0:
+	ErrorF("Rotating Screen to 0 degrees\n");
+         pScrn->displayWidth = pI830->displayWidth;
+         break;
+      case RR_Rotate_90:
+	ErrorF("Rotating Screen to 90 degrees\n");
+         pScrn->displayWidth = pScrn->pScreen->width;
+         break;
+      case RR_Rotate_180:
+	ErrorF("Rotating Screen to 180 degrees\n");
+         pScrn->displayWidth = pI830->displayWidth;
+         break;
+      case RR_Rotate_270:
+	ErrorF("Rotating Screen to 270 degrees\n");
+         pScrn->displayWidth = pScrn->pScreen->width;
+         break;
+   }
+   ErrorF("pScrn->displayWidth %d\n", pScrn->displayWidth);
+
+   if (!i830_rotate_mem_realloc(pScrn, crtc)) {
+	intel_crtc->rotation = old_rotation;
+	return FALSE;
+   }
+   
+   if (!i830_setup_shadowfb(pScrn, crtc)) {
+	intel_crtc->rotation = old_rotation;
+	return FALSE;
+   }
+
+
+#ifdef I830_USE_XAA
+   if (pI830->AccelInfoRec != NULL) {
+      /* Don't allow pixmap cache or offscreen pixmaps when rotated */
+      /* XAA needs some serious fixing for this to happen */
+      if (intel_crtc->rotation == RR_Rotate_0) {
+	 pI830->AccelInfoRec->Flags = LINEAR_FRAMEBUFFER | OFFSCREEN_PIXMAPS |
+				      PIXMAP_CACHE;
+	 pI830->AccelInfoRec->UsingPixmapCache = TRUE;
+	 /* funny as it seems this will enable XAA's createpixmap */
+	 pI830->AccelInfoRec->maxOffPixWidth = 0;
+	 pI830->AccelInfoRec->maxOffPixHeight = 0;
+      } else {
+	 pI830->AccelInfoRec->Flags = LINEAR_FRAMEBUFFER;
+	 pI830->AccelInfoRec->UsingPixmapCache = FALSE;
+	 /* funny as it seems this will disable XAA's createpixmap */
+	 pI830->AccelInfoRec->maxOffPixWidth = 1;
+	 pI830->AccelInfoRec->maxOffPixHeight = 1;
+      }
+   }
+#endif
+    return TRUE;
+}
+
 Bool
 I830Rotate(ScrnInfoPtr pScrn, DisplayModePtr mode)
 {
diff --git a/src/i830_xf86Crtc.c b/src/i830_xf86Crtc.c
index 0c482a2..6e836bd 100644
--- a/src/i830_xf86Crtc.c
+++ b/src/i830_xf86Crtc.c
@@ -517,6 +517,7 @@ xf86SetScrnInfoModes (ScrnInfoPtr pScrn)
     xf86CrtcPtr		crtc;
     DisplayModePtr	last, mode;
     int			originalVirtualX, originalVirtualY;
+    I830Ptr		pI830 = I830PTR(pScrn);
 
     output = config->output[config->compat_output];
     if (!output->crtc)
@@ -549,9 +550,10 @@ xf86SetScrnInfoModes (ScrnInfoPtr pScrn)
     /* Disable modes in the XFree86 DDX list that are larger than the current
      * virtual size.
      */
+    /* pass real line pitch, rotation might change this */
     i830xf86ValidateModesSize(pScrn, pScrn->modes,
 			      originalVirtualX, originalVirtualY,
-			      pScrn->displayWidth);
+			      pI830->displayWidth);
 
     /* Strip out anything that we threw out for virtualX/Y. */
     i830xf86PruneInvalidModes(pScrn, &pScrn->modes, TRUE);
diff-tree a1796bfb51d90fd545973909404e1a77ad27c9cc (from parents)
Merge: 84915ac8afeb4bbc03df8f94ab3ba351788d6501 fabfccd3d8a55a83138d361f66c53cb7e6d371a8
Author: Wang Zhenyu <zhenyu.z.wang at intel.com>
Date:   Fri Dec 29 10:10:26 2006 +0800

    Merge branch 'crestline' of git+ssh://zhen@otc-graphics.jf.intel.com/git/xorg/driver/xf86-video-intel into crestline

diff-tree fabfccd3d8a55a83138d361f66c53cb7e6d371a8 (from ddefce4f02eb3272ad37e890350f73f03eff73c9)
Author: Zou Nan hai <nanhai.zou at intel.com>
Date:   Thu Dec 28 14:48:54 2006 +0800

      Fix

diff --git a/src/i830_tv.c b/src/i830_tv.c
index 7e5daa6..9048d08 100644
--- a/src/i830_tv.c
+++ b/src/i830_tv.c
@@ -1064,7 +1064,7 @@ i830_tv_detect(xf86OutputPtr output)
 	if (intel_output->load_detect_temp)
 	{
 	    /* we only need the pixel clock set correctly here */
-	    mode = crtc->desiredMode;
+	    mode = reported_modes[0];
 	    xf86SetModeCrtc (&mode, INTERLACE_HALVE_V);
 	}
 	i830_tv_detect_type (crtc, output);
diff-tree ddefce4f02eb3272ad37e890350f73f03eff73c9 (from c5205595f2abacc9f736e1f53666302ec551cbc4)
Author: Zou Nan hai <nanhai.zou at intel.com>
Date:   Thu Dec 28 14:45:53 2006 +0800

     support NTSC 480i M-J 1280x1024 1024x768 800x600 640x480
     PAL 576i 1280x1024 1024x768 800x600 640x480
    
     I still have problem with non-interlace mode and Hi Res mode.
     also I don't know how to pickup those mode in xorg.conf

diff --git a/src/i830_tv.c b/src/i830_tv.c
index 0b43908..7e5daa6 100644
--- a/src/i830_tv.c
+++ b/src/i830_tv.c
@@ -249,6 +249,53 @@ const tv_mode_t tv_modes[] = {
 	    .ru =-0.0957, .gu =-0.1879, .bu = 0.2836, .au = 1.0000,
 	    .rv = 0.3992, .gv =-0.3343, .bv =-0.0649, .av = 1.0000,
 	},
+    },
+    {
+	/* 625 Lines, 50 Fields, 15.625KHz line, Sub-Carrier 4.434MHz */
+	.name	    = "PAL 576i",
+	.oversample	= TV_OVERSAMPLE_8X,
+
+	.hsync_end	= 64,		    .hblank_end		= 128,
+	.hblank_start	= 844,		    .htotal		= 863,
+	
+	.progressive	= FALSE,
+	
+	.vsync_start_f1	= 6,		    .vsync_start_f2	= 7,
+	.vsync_len	= 6,
+	
+	.veq_ena	= TRUE,		    .veq_start_f1    	= 0,
+	.veq_start_f2	= 1,		    .veq_len		= 18,
+
+	.vi_end_f1	= 24,		    .vi_end_f2		= 25,
+	.nbr_end	= 286,
+
+	.burst_ena	= TRUE,
+	.hburst_start	= 73,		    .hburst_len		= 34,
+	.vburst_start_f1 = 8,		    .vburst_end_f1	= 285,
+	.vburst_start_f2 = 8,		    .vburst_end_f2	= 286,
+	.vburst_start_f3 = 9,		    .vburst_end_f3	= 286, 
+	.vburst_start_f4 = 9,		    .vburst_end_f4	= 285,
+
+	/* desired 4.4336180 actual 4.4336180 clock 107.52 */
+	.dda1_inc	=    168,
+	.dda2_inc	=  18557,	.dda2_size	=  20625,
+	.dda3_inc	=      0,	.dda3_size	=      0,
+	.sc_reset   = TV_SC_RESET_EVERY_8,
+	.pal_burst  = TRUE,
+	
+	.composite_levels = { .blank = 237, .black = 237, .burst = 118 },
+	.composite_color = {
+	    .ry = 0.2990, .gy = 0.5870, .by = 0.1140, .ay = 0.5379,
+	    .ru =-0.0793, .gu =-0.1557, .bu = 0.2350, .au = 1.0000,
+	    .rv = 0.3307, .gv =-0.2769, .bv =-0.0538, .av = 1.0000,
+	},
+
+	.svideo_levels    = { .blank = 280, .black = 280, .burst = 139 },
+	.svideo_color = {
+	    .ry = 0.2990, .gy = 0.5870, .by = 0.1140, .ay = 0.6357,
+	    .ru =-0.0937, .gu =-0.1840, .bu = 0.2777, .au = 1.0000,
+	    .rv = 0.3908, .gv =-0.3273, .bv =-0.0636, .av = 1.0000,
+	},
     }
 #if 0
     {
@@ -645,7 +692,6 @@ i830_tv_mode_set(xf86OutputPtr output, D
     tv_mode = &tv_modes[0];
     
     tv_ctl = 0;
-
     switch (dev_priv->type) {
     default:
     case TV_TYPE_UNKNOWN:
@@ -804,22 +850,122 @@ i830_tv_mode_set(xf86OutputPtr output, D
 }
 
 static const DisplayModeRec reported_modes[] = {
-    {
-	.name = "NTSC 480i",
-	.Clock = TV_PLL_CLOCK,
-	
-	.HDisplay   = 1024,
-	.HSyncStart = 1048,
-	.HSyncEnd   = 1184,
-	.HTotal     = 1344,
-
-	.VDisplay   = 768,
-	.VSyncStart = 771,
-	.VSyncEnd   = 777,
-	.VTotal     = 806,
+	{
+		.name = "NTSC 480i",
+		.Clock = TV_PLL_CLOCK,
+		.HDisplay   = 1280,
+		.HSyncStart = 1368,
+		.HSyncEnd   = 1496,
+		.HTotal     = 1712,
+
+		.VDisplay   = 1024,
+		.VSyncStart = 1027,
+		.VSyncEnd   = 1034,
+		.VTotal     = 1104,
+		.type       = M_T_DRIVER
+	},
+	{
+		.name = "NTSC 480i",
+		.Clock = TV_PLL_CLOCK,
+		.HDisplay   = 1024,
+		.HSyncStart = 1080,
+		.HSyncEnd   = 1184,
+		.HTotal     = 1344,
+
+		.VDisplay   = 768,
+		.VSyncStart = 771,
+		.VSyncEnd   = 777,
+		.VTotal     = 806,
+		.type       = M_T_DRIVER
+	},
+	{
+		.name = "NTSC 480i",
+		.Clock = TV_PLL_CLOCK,
+		.HDisplay   = 800,
+		.HSyncStart = 832,
+		.HSyncEnd   = 912,
+		.HTotal     = 1024,
+
+		.VDisplay   = 600,
+		.VSyncStart = 603,
+		.VSyncEnd   = 607,
+		.VTotal     = 650,
+		.type       = M_T_DRIVER
+	},
+	{
+		.name = "NTSC 480i",
+		.Clock = TV_PLL_CLOCK,
+		.HDisplay   = 640,
+		.HSyncStart = 664,
+		.HSyncEnd   = 720,
+		.HTotal     = 800,
+
+		.VDisplay   = 480,
+		.VSyncStart = 483,
+		.VSyncEnd   = 487,
+		.VTotal     = 552,
+		.type       = M_T_DRIVER
+	},
+	{
+		.name = "PAL 576i",
+		.Clock = TV_PLL_CLOCK,
+		.HDisplay   = 1280,
+		.HSyncStart = 1352,
+		.HSyncEnd   = 1480,
+		.HTotal     = 1680,
+
+		.VDisplay   = 1024,
+		.VSyncStart = 1027,
+		.VSyncEnd   = 1034,
+		.VTotal     = 1092,
 
-	.type       = M_T_DRIVER
-    }
+		.type       = M_T_DRIVER
+	},
+	{
+		.name = "PAL 576i",
+		.Clock = TV_PLL_CLOCK,
+		.HDisplay   = 1024,
+		.HSyncStart = 1072,
+		.HSyncEnd   = 1168,
+		.HTotal     = 1312,
+		.VDisplay   = 768,
+		.VSyncStart = 771,
+		.VSyncEnd   = 775,
+		.VTotal     = 820,
+		.VRefresh   = 50.0f,
+
+		.type       = M_T_DRIVER
+	},
+	{
+		.name = "PAL 576i",
+		.Clock = TV_PLL_CLOCK,
+		.HDisplay   = 800,
+		.HSyncStart = 832,
+		.HSyncEnd   = 904,
+		.HTotal     = 1008,
+		.VDisplay   = 600,
+		.VSyncStart = 603,
+		.VSyncEnd   = 607,
+		.VTotal     = 642,
+		.VRefresh   = 50.0f,
+
+		.type       = M_T_DRIVER
+	},
+	{
+		.name = "PAL 576i",
+		.Clock = TV_PLL_CLOCK,
+		.HDisplay   = 640,
+		.HSyncStart = 664,
+		.HSyncEnd   = 720,
+		.HTotal     = 800,
+
+		.VDisplay   = 480,
+		.VSyncStart = 483,
+		.VSyncEnd   = 487,
+		.VTotal     = 516,
+		.VRefresh   = 50.0f,
+		.type       = M_T_DRIVER
+	},
 };
 
 /**
@@ -918,9 +1064,8 @@ i830_tv_detect(xf86OutputPtr output)
 	if (intel_output->load_detect_temp)
 	{
 	    /* we only need the pixel clock set correctly here */
-	    mode = reported_modes[0];
+	    mode = crtc->desiredMode;
 	    xf86SetModeCrtc (&mode, INTERLACE_HALVE_V);
-	    i830PipeSetMode (crtc, &mode, FALSE);
 	}
 	i830_tv_detect_type (crtc, output);
 	i830ReleaseLoadDetectPipe (output);
diff-tree c5205595f2abacc9f736e1f53666302ec551cbc4 (from parents)
Merge: b8f3ec77104882fc755ddc88f2583cd5d15387a4 4c0c1aa882cfec77b2183baec93cbc4cfaf4abe0
Author: Keith Packard <keithp at neko.keithp.com>
Date:   Thu Dec 21 02:51:33 2006 -0800

    Merge branch 'modesetting' into crestline

diff --cc src/i830_tv.c
index 05b6825,6231891..0b43908
@@@ -400,12 -639,35 +641,36 @@@
       * mode.  For now, just set the first one in the list, with
       * NTSC format.
       */
 +    OUTREG(TV_CTL, INREG(TV_CTL) & ~TV_ENC_ENABLE);
      tv_mode = &tv_modes[0];
-     sc_mode = &tv_sc_modes[TV_SC_NTSC_MJ];
- 
-     type = dev_priv->type;
+     
+     tv_ctl = 0;
  
+     switch (dev_priv->type) {
+     default:
+     case TV_TYPE_UNKNOWN:
+     case TV_TYPE_COMPOSITE:
+ 	tv_ctl |= TV_ENC_OUTPUT_COMPOSITE;
+ 	video_levels = &tv_mode->composite_levels;
+ 	color_conversion = &tv_mode->composite_color;
+ 	burst_ena = tv_mode->burst_ena;
+ 	break;
+     case TV_TYPE_COMPONENT:
+ 	tv_ctl |= TV_ENC_OUTPUT_COMPONENT;
+ 	video_levels = &component_level;
+ 	if (tv_mode->burst_ena)
+ 	    color_conversion = &sdtv_component_color;
+ 	else
+ 	    color_conversion = &hdtv_component_color;
+ 	burst_ena = FALSE;
+ 	break;
+     case TV_TYPE_SVIDEO:
+ 	tv_ctl |= TV_ENC_OUTPUT_SVIDEO;
+ 	video_levels = &tv_mode->svideo_levels;
+ 	color_conversion = &tv_mode->svideo_color;
+ 	burst_ena = tv_mode->burst_ena;
+ 	break;
+     }
      hctl1 = (tv_mode->hsync_end << TV_HSYNC_END_SHIFT) |
  	(tv_mode->htotal << TV_HTOTAL_SHIFT);
  
@@@ -450,41 -711,30 +714,30 @@@
-     switch (type) {
-     case TV_TYPE_COMPOSITE:
- 	tv_ctl |= TV_ENC_OUTPUT_COMPOSITE;
- 	break;
-     case TV_TYPE_COMPONENT:
- 	tv_ctl |= TV_ENC_OUTPUT_COMPONENT;
- 	break;
-     case TV_TYPE_SVIDEO:
- 	tv_ctl |= TV_ENC_OUTPUT_SVIDEO;
- 	break;
-     default:
-     case TV_TYPE_UNKNOWN:
- 	tv_ctl |= TV_ENC_OUTPUT_SVIDEO_COMPOSITE;
- 	break;
-     }
      tv_ctl |= tv_mode->oversample;
      if (tv_mode->progressive)
  	tv_ctl |= TV_PROGRESSIVE;
-     if (sc_mode->pal_burst)
+     if (tv_mode->pal_burst)
  	tv_ctl |= TV_PAL_BURST;
  
-     scctl1 = TV_SC_DDA1_EN | TV_SC_DDA2_EN;
-     if (sc_mode->dda3_size != 0)
+     scctl1 = TV_SC_DDA1_EN;
+     
+     if (tv_mode->dda2_inc)
+ 	scctl1 |= TV_SC_DDA2_EN;
+     
+     if (tv_mode->dda3_inc)
  	scctl1 |= TV_SC_DDA3_EN;
-     scctl1 |= sc_mode->sc_reset;
-     /* XXX: set the burst level */
-     scctl1 |= 113 << TV_BURST_LEVEL_SHIFT;    /* from BIOS */
-     scctl1 |= sc_mode->dda1_inc << TV_SCDDA1_INC_SHIFT;
+     
+     scctl1 |= tv_mode->sc_reset;
+     scctl1 |= video_levels->burst << TV_BURST_LEVEL_SHIFT;
+     scctl1 |= tv_mode->dda1_inc << TV_SCDDA1_INC_SHIFT;
  
-     scctl2 = sc_mode->dda2_size << TV_SCDDA2_SIZE_SHIFT |
- 	sc_mode->dda2_inc << TV_SCDDA2_INC_SHIFT;
+     scctl2 = tv_mode->dda2_size << TV_SCDDA2_SIZE_SHIFT |
+ 	tv_mode->dda2_inc << TV_SCDDA2_INC_SHIFT;
  
-     scctl3 = sc_mode->dda3_size << TV_SCDDA3_SIZE_SHIFT |
- 	sc_mode->dda3_inc << TV_SCDDA3_INC_SHIFT;
+     scctl3 = tv_mode->dda3_size << TV_SCDDA3_SIZE_SHIFT |
+ 	tv_mode->dda3_inc << TV_SCDDA3_INC_SHIFT;
  
      /* Enable two fixes for the chips that need them. */
 -    if (pI830->PciInfo->chipType < PCI_CHIP_I945_G)
 -	tv_ctl |= TV_ENC_C0_FIX | TV_ENC_SDP_FIX;
 +    if (pI830->PciInfo->chipType < PCI_CHIP_I945_G) 
 +	    tv_ctl |= TV_ENC_C0_FIX | TV_ENC_SDP_FIX;
  
      tv_filter_ctl = TV_AUTO_SCALE;
      if (mode->HDisplay > 1024)
diff-tree b8f3ec77104882fc755ddc88f2583cd5d15387a4 (from b83cbec34a8d1ff39bd303fcd27fc03dcdb1d6c3)
Author: Zou Nan hai <nanhai.zou at intel.com>
Date:   Thu Dec 21 10:46:17 2006 +0800

      This fix should be better, I830SetMode will call i830_sdvo_dump,
      if the sdvo is not initialized, X will crash. So any application which
      SetMode will crash X if there is no SDVO output.

diff --git a/src/i830_sdvo.c b/src/i830_sdvo.c
index df5f130..8e38779 100644
--- a/src/i830_sdvo.c
+++ b/src/i830_sdvo.c
@@ -981,7 +981,7 @@ i830_sdvo_dump(ScrnInfoPtr pScrn)
 	xf86OutputPtr	output = xf86_config->output[i];
 	I830OutputPrivatePtr	intel_output = output->driver_private;
 	
-	if (intel_output->type == I830_OUTPUT_SDVO && (intel_output->pI2CBus))
+	if (intel_output->type == I830_OUTPUT_SDVO)
 	    i830_sdvo_dump_device(output);
     }
 }
@@ -1093,7 +1093,6 @@ i830_sdvo_init(ScrnInfoPtr pScrn, int ou
     output->driver_private = intel_output;
     
     dev_priv = (struct i830_sdvo_priv *) (intel_output + 1);
-    intel_output->type = I830_OUTPUT_SDVO;
 
     /* While it's the same bus, we just initialize a new copy to avoid trouble
      * with tracking refcounting ourselves, since the XFree86 DDX bits don't.
@@ -1212,7 +1211,7 @@ i830_sdvo_init(ScrnInfoPtr pScrn, int ou
 
     i830_sdvo_get_input_pixel_clock_range(output, &dev_priv->pixel_clock_min,
 					  &dev_priv->pixel_clock_max);
-
+    intel_output->type = I830_OUTPUT_SDVO;
     xf86DrvMsg(pScrn->scrnIndex, X_INFO,
 	       "%s device VID/DID: %02X:%02X.%02X, "
 	       "clock range %.1fMHz - %.1fMHz, "
diff-tree b83cbec34a8d1ff39bd303fcd27fc03dcdb1d6c3 (from 07d3f141712e2abf704cb68a59cd5d5c3390e2ca)
Author: Zou Nan hai <nanhai.zou at intel.com>
Date:   Wed Dec 20 17:32:05 2006 +0800

    fix null pointer reference,
    I hit this when running doom3-demo

diff --git a/src/i830_sdvo.c b/src/i830_sdvo.c
index cb68802..df5f130 100644
--- a/src/i830_sdvo.c
+++ b/src/i830_sdvo.c
@@ -981,7 +981,7 @@ i830_sdvo_dump(ScrnInfoPtr pScrn)
 	xf86OutputPtr	output = xf86_config->output[i];
 	I830OutputPrivatePtr	intel_output = output->driver_private;
 	
-	if (intel_output->type == I830_OUTPUT_SDVO)
+	if (intel_output->type == I830_OUTPUT_SDVO && (intel_output->pI2CBus))
 	    i830_sdvo_dump_device(output);
     }
 }
diff-tree 07d3f141712e2abf704cb68a59cd5d5c3390e2ca (from parents)
Merge: 0cd1a11d4493ef4a2d05ccf8aadec743504dba5f c28075e1d70c98b39fc9829a6a01da171a9b9426
Author: Keith Packard <keithp at neko.keithp.com>
Date:   Tue Dec 19 22:01:02 2006 -0800

    Merge branch 'modesetting' into crestline

diff-tree 0cd1a11d4493ef4a2d05ccf8aadec743504dba5f (from 65cd18b97bc533b24031d6eb882fd3074779ceba)
Author: Zou Nan hai <nanhai.zou at intel.com>
Date:   Tue Dec 19 14:03:19 2006 +0800

      fix for bug #108

diff --git a/src/i830_tv.c b/src/i830_tv.c
index af9826b..46ce046 100644
--- a/src/i830_tv.c
+++ b/src/i830_tv.c
@@ -171,13 +171,15 @@ i830_tv_dpms(xf86OutputPtr output, int m
 
     switch(mode) {
     case DPMSModeOn:
-	OUTREG(TV_CTL, INREG(TV_CTL) | TV_ENC_ENABLE);
-	break;
+            /* Wait for a Vblank when reenable TV encoder */
+	    i830WaitForVblank(pScrn);
+	    OUTREG(TV_CTL, INREG(TV_CTL) | TV_ENC_ENABLE);
+	    break;
     case DPMSModeStandby:
     case DPMSModeSuspend:
     case DPMSModeOff:
-	OUTREG(TV_CTL, INREG(TV_CTL) & ~TV_ENC_ENABLE);
-	break;
+	    /*OUTREG(TV_CTL, INREG(TV_CTL) & ~TV_ENC_ENABLE);*/
+	    break;
     }
 }
 
@@ -398,6 +400,7 @@ i830_tv_mode_set(xf86OutputPtr output, D
      * mode.  For now, just set the first one in the list, with
      * NTSC format.
      */
+    OUTREG(TV_CTL, INREG(TV_CTL) & ~TV_ENC_ENABLE);
     tv_mode = &tv_modes[0];
     sc_mode = &tv_sc_modes[TV_SC_NTSC_MJ];
 
@@ -480,8 +483,8 @@ i830_tv_mode_set(xf86OutputPtr output, D
 	sc_mode->dda3_inc << TV_SCDDA3_INC_SHIFT;
 
     /* Enable two fixes for the chips that need them. */
-    if (pI830->PciInfo->chipType < PCI_CHIP_I945_G)
-	tv_ctl |= TV_ENC_C0_FIX | TV_ENC_SDP_FIX;
+    if (pI830->PciInfo->chipType < PCI_CHIP_I945_G) 
+	    tv_ctl |= TV_ENC_C0_FIX | TV_ENC_SDP_FIX;
 
     tv_filter_ctl = TV_AUTO_SCALE;
     if (mode->HDisplay > 1024)
diff-tree 65cd18b97bc533b24031d6eb882fd3074779ceba (from parents)
Merge: bf43f8ce736d91659c2757fb39b13e63bc5891a4 6823ca87f3b1ef3b28ed167254dcfce2a80467df
Author: Keith Packard <keithp at neko.keithp.com>
Date:   Sun Dec 17 17:32:24 2006 -0800

    Merge branch 'modesetting' into crestline

diff-tree bf43f8ce736d91659c2757fb39b13e63bc5891a4 (from parents)
Merge: 684ea26b740d07ec8f6b0d223c1171e70c073bfa 94523215127a3458a28d0f1217224a27c8870884
Author: Wang Zhenyu <zhenyu.z.wang at intel.com>
Date:   Fri Dec 8 14:17:43 2006 +0800

    Merge branch 'modesetting' into crestline

diff-tree 94523215127a3458a28d0f1217224a27c8870884 (from parents)
Merge: 75f4df278e9db360967d77cdba4756cbde622d56 fde52de870c84821ab457e17634c334a10cf71ab
Author: Wang Zhenyu <zhenyu.z.wang at intel.com>
Date:   Fri Dec 8 14:15:06 2006 +0800

    Merge branch 'modesetting' of git+ssh://zhen@git.freedesktop.org/git/xorg/driver/xf86-video-intel into modesetting

diff-tree 684ea26b740d07ec8f6b0d223c1171e70c073bfa (from parents)
Merge: 64269de3c34db047e78b788dc5681abdc009f8aa 6b977f0eca388a295ca7348f5960bd8e0192cf1d
Author: Wang Zhenyu <zhenyu.z.wang at intel.com>
Date:   Fri Dec 8 14:03:10 2006 +0800

    Merge branch 'exa-i965' of git+ssh://zhen@git.freedesktop.org/git/xorg/driver/xf86-video-intel into crestline

diff --cc src/i830_memory.c
index 43fde11,4a8d480..6944863
@@@ -1559,11 -1561,14 +1578,16 @@@
        I830FixOffset(pScrn, &(pI830->ContextMem));
        I830FixOffset(pScrn, &(pI830->BackBuffer));
        I830FixOffset(pScrn, &(pI830->DepthBuffer));
 -      I830FixOffset(pScrn, &(pI830->TexMem));
 +      if (pI830->mmModeFlags & I830_KERNEL_TEX) {
 +	 I830FixOffset(pScrn, &(pI830->TexMem));
 +      }
     }
  #endif
+ #ifdef I830_USE_EXA
+    I830FixOffset(pScrn, &(pI830->Offscreen));
+    if (IS_I965G(pI830))
+        I830FixOffset(pScrn, &(pI830->EXAStateMem));
+ #endif
     return TRUE;
  }
  
diff-tree 64269de3c34db047e78b788dc5681abdc009f8aa (from parents)
Merge: 8ddbc26b276016b922487f7b1e8997998b655a7d 182d2f503a7a1be90d93a4a15059585a564fd3ce
Author: Keith Packard <keithp at neko.keithp.com>
Date:   Wed Dec 6 18:09:28 2006 -0800

    Merge branch 'modesetting' into crestline

diff-tree 6b977f0eca388a295ca7348f5960bd8e0192cf1d (from 041f0029c78620ca1b50e7e5d11f5d022e189641)
Author: Wang Zhenyu <zhenyu.z.wang at intel.com>
Date:   Wed Dec 6 13:24:44 2006 +0800

    fix Makefile.am

diff --git a/src/Makefile.am b/src/Makefile.am
index 890e90f..d7da2c6 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -70,7 +70,6 @@ i810_drv_la_SOURCES = \
 	 i830_xaa.c \
 	 i830_exa_render.c \
 	 i915_exa_render.c \
-	 i965_composite_wm_nomask.h \
 	 i965_exa_render.c
 
 if HAVE_GEN4ASM
@@ -78,8 +77,14 @@ sf_prog.h: packed_yuv_sf.g4a
 	intel-gen4asm -o sf_prog.h packed_yuv_sf.g4a
 wm_prog.h: packed_yuv_wm.g4a
 	intel-gen4asm -o wm_prog.h packed_yuv_wm.g4a
+exa_sf_prog.h: exa_sf.g4a
+	intel-gen4asm -o exa_sf_prog.h exa_sf.g4a
+exa_sf_mask_prog.h: exa_sf_mask.g4a
+	intel-gen4asm -o exa_sf_mask_prog.h exa_sf_mask.g4a
 exa_wm_nomask_prog.h: exa_wm_nomask.g4a
 	intel-gen4asm -o exa_wm_nomask_prog.h exa_wm_nomask.g4a
+exa_wm_masknoca_prog.h: exa_wm_masknoca.g4a
+	intel-gen4asm -o exa_wm_masknoca_prog.h exa_wm_masknoca.g4a
 endif
 
 if DRI
diff-tree 041f0029c78620ca1b50e7e5d11f5d022e189641 (from 583619cdb2b6a469299dd5bf658bf5b51ee999fe)
Author: Wang Zhenyu <zhenyu.z.wang at intel.com>
Date:   Wed Dec 6 10:43:29 2006 +0800

    Formats fixes
    
    We should use card_fmt for src/mask picture, and use dest color
    buffer format helper. Also fix wrong name for G965 texture formats,
    and pict_x1r5g5b5 isn't supported by sampler engine.

diff --git a/src/i965_exa_render.c b/src/i965_exa_render.c
index 7e9c1e3..583bc26 100644
--- a/src/i965_exa_render.c
+++ b/src/i965_exa_render.c
@@ -121,13 +121,12 @@ static struct blendinfo I965BlendOp[] = 
 
 /* FIXME: surface format defined in brw_defines.h, shared Sampling engine 1.7.2*/
 static struct formatinfo I965TexFormats[] = {
-        {PICT_a8r8g8b8, BRW_SURFACEFORMAT_R8G8B8A8_UNORM },
-        {PICT_x8r8g8b8, BRW_SURFACEFORMAT_R8G8B8X8_UNORM },
-        {PICT_a8b8g8r8, BRW_SURFACEFORMAT_B8G8R8A8_UNORM },
-        {PICT_x8b8g8r8, BRW_SURFACEFORMAT_B8G8R8X8_UNORM },
+        {PICT_a8r8g8b8, BRW_SURFACEFORMAT_B8G8R8A8_UNORM },
+        {PICT_x8r8g8b8, BRW_SURFACEFORMAT_B8G8R8X8_UNORM },
+        {PICT_a8b8g8r8, BRW_SURFACEFORMAT_R8G8B8A8_UNORM },
+        {PICT_x8b8g8r8, BRW_SURFACEFORMAT_R8G8B8X8_UNORM },
         {PICT_r5g6b5,   BRW_SURFACEFORMAT_B5G6R5_UNORM   },
         {PICT_a1r5g5b5, BRW_SURFACEFORMAT_B5G5R5A1_UNORM },
-        {PICT_x1r5g5b5, BRW_SURFACEFORMAT_B5G5R5X1_UNORM },
         {PICT_a8,       BRW_SURFACEFORMAT_A8_UNORM	 },
 };
 
@@ -366,6 +365,16 @@ static const CARD32 ps_kernel_static_mas
 #include "exa_wm_masknoca_prog.h"
 };
 
+static CARD32 i965_get_card_format(PicturePtr pPict) 
+{
+	int i;
+        for (i = 0; i < sizeof(I965TexFormats) / sizeof(I965TexFormats[0]); i++) {
+            if (I965TexFormats[i].fmt == pPict->format)
+                break;
+        }
+	return I965TexFormats[i].card_fmt;
+}
+
 Bool
 I965EXAPrepareComposite(int op, PicturePtr pSrcPicture,
 			PicturePtr pMaskPicture, PicturePtr pDstPicture,
@@ -376,10 +385,7 @@ I965EXAPrepareComposite(int op, PictureP
     CARD32 src_offset, src_pitch;
     CARD32 mask_offset = 0, mask_pitch = 0;
     CARD32 dst_format, dst_offset, dst_pitch;
- 
-ErrorF("i965 prepareComposite\n");
 
-    I965GetDestFormat(pDstPicture, &dst_format);
     src_offset = exaGetPixmapOffset(pSrc);
     src_pitch = exaGetPixmapPitch(pSrc);
     dst_offset = exaGetPixmapOffset(pDst);
@@ -590,11 +596,9 @@ ErrorF("i965 prepareComposite\n");
    memset(dest_surf_state, 0, sizeof(*dest_surf_state));
    dest_surf_state->ss0.surface_type = BRW_SURFACE_2D;
    dest_surf_state->ss0.data_return_format = BRW_SURFACERETURNFORMAT_FLOAT32;
-   if (pDst->drawable.bitsPerPixel == 16) {
-      dest_surf_state->ss0.surface_format = BRW_SURFACEFORMAT_B5G6R5_UNORM;
-   } else {
-      dest_surf_state->ss0.surface_format = BRW_SURFACEFORMAT_B8G8R8A8_UNORM;
-   }
+   I965GetDestFormat(pDstPicture, &dst_format);
+   dest_surf_state->ss0.surface_format = dst_format;
+
    dest_surf_state->ss0.writedisable_alpha = 0;
    dest_surf_state->ss0.writedisable_red = 0;
    dest_surf_state->ss0.writedisable_green = 0;
@@ -615,12 +619,7 @@ ErrorF("i965 prepareComposite\n");
    /* Set up the source surface state buffer */
    memset(src_surf_state, 0, sizeof(*src_surf_state));
    src_surf_state->ss0.surface_type = BRW_SURFACE_2D;
-   if (pSrc->drawable.bitsPerPixel == 8)
-      src_surf_state->ss0.surface_format = BRW_SURFACEFORMAT_A8_UNORM; //XXX? 
-   else if (pSrc->drawable.bitsPerPixel == 16)
-      src_surf_state->ss0.surface_format = BRW_SURFACEFORMAT_B5G6R5_UNORM;
-   else 
-      src_surf_state->ss0.surface_format = BRW_SURFACEFORMAT_B8G8R8A8_UNORM;
+   src_surf_state->ss0.surface_format = i965_get_card_format(pSrcPicture);
 
    src_surf_state->ss0.writedisable_alpha = 0;
    src_surf_state->ss0.writedisable_red = 0;
@@ -643,12 +642,7 @@ ErrorF("i965 prepareComposite\n");
    if (pMask) {
    	memset(mask_surf_state, 0, sizeof(*mask_surf_state));
 	mask_surf_state->ss0.surface_type = BRW_SURFACE_2D;
-   	if (pMask->drawable.bitsPerPixel == 8)
-      	    mask_surf_state->ss0.surface_format = BRW_SURFACEFORMAT_A8_UNORM; //XXX? 
-   	else if (pMask->drawable.bitsPerPixel == 16)
-      	    mask_surf_state->ss0.surface_format = BRW_SURFACEFORMAT_B5G6R5_UNORM;
-   	else 
-      	    mask_surf_state->ss0.surface_format = BRW_SURFACEFORMAT_B8G8R8A8_UNORM;
+   	mask_surf_state->ss0.surface_format = i965_get_card_format(pMaskPicture);
 
    	mask_surf_state->ss0.writedisable_alpha = 0;
    	mask_surf_state->ss0.writedisable_red = 0;
diff-tree 583619cdb2b6a469299dd5bf658bf5b51ee999fe (from f28d5fc30ccf60d72d5832bb6542522dc7f1c463)
Author: Wang Zhenyu <zhenyu.z.wang at intel.com>
Date:   Mon Dec 4 15:48:04 2006 +0800

    set correct default border color

diff --git a/src/i965_exa_render.c b/src/i965_exa_render.c
index 2d1ce5f..7e9c1e3 100644
--- a/src/i965_exa_render.c
+++ b/src/i965_exa_render.c
@@ -691,10 +691,10 @@ ErrorF("i965 prepareComposite\n");
    }
 
    memset(default_color_state, 0, sizeof(*default_color_state));
-   default_color_state->color[0] = 1.0; /* RGBA format */
-   default_color_state->color[1] = 0.0; 
-   default_color_state->color[2] = 0.0; 
-   default_color_state->color[3] = 0.0; 
+   default_color_state->color[0] = 0.0; /* R */
+   default_color_state->color[1] = 0.0; /* G */
+   default_color_state->color[2] = 0.0; /* B */
+   default_color_state->color[3] = 1.0; /* A */
 
    src_sampler_state->ss0.default_color_mode = 0; /* GL mode */
 
diff-tree f28d5fc30ccf60d72d5832bb6542522dc7f1c463 (from db391e8e4c4d87bfe3ccad0de14dd5b47b69b8fe)
Author: Wang Zhenyu <zhenyu.z.wang at intel.com>
Date:   Mon Dec 4 15:47:31 2006 +0800

    fix typo in ps kernel
    
    fix corrupt in some subspans

diff --git a/src/exa_wm_masknoca.g4a b/src/exa_wm_masknoca.g4a
index 195203c..c2049fd 100644
--- a/src/exa_wm_masknoca.g4a
+++ b/src/exa_wm_masknoca.g4a
@@ -51,10 +51,10 @@ mov (1) g8.20<1>F g1.14<0,1,0>UW { align
 add (1) g8.24<1>F g1.14<0,1,0>UW 1UB { align1 };
 add (1) g8.28<1>F g1.14<0,1,0>UW 1UB { align1 };
     /* Set up ss2.x coordinates */
-mov (1) g9<1>F g1.16<0,1,0>UW { align1 };
-add (1) g9.4<1>F g1.16<0,1,0>UW 1UB { align1 };
-mov (1) g9.8<1>F g1.16<0,1,0>UW { align1 };
-add (1) g9.12<1>F g1.16<0,1,0>UW 1UB { align1 };
+mov (1) g7<1>F g1.16<0,1,0>UW { align1 };
+add (1) g7.4<1>F g1.16<0,1,0>UW 1UB { align1 };
+mov (1) g7.8<1>F g1.16<0,1,0>UW { align1 };
+add (1) g7.12<1>F g1.16<0,1,0>UW 1UB { align1 };
     /* Set up ss2.y coordinates */
 mov (1) g9<1>F g1.18<0,1,0>UW { align1 };
 mov (1) g9.4<1>F g1.18<0,1,0>UW { align1 };
diff --git a/src/exa_wm_masknoca_prog.h b/src/exa_wm_masknoca_prog.h
index 66eb960..5fcf3b5 100644
--- a/src/exa_wm_masknoca_prog.h
+++ b/src/exa_wm_masknoca_prog.h
@@ -14,10 +14,10 @@
    { 0x00000001, 0x2114013d, 0x0000002e, 0x00000000 },
    { 0x00000040, 0x21180d3d, 0x0000002e, 0x00000001 },
    { 0x00000040, 0x211c0d3d, 0x0000002e, 0x00000001 },
-   { 0x00000001, 0x2120013d, 0x00000030, 0x00000000 },
-   { 0x00000040, 0x21240d3d, 0x00000030, 0x00000001 },
-   { 0x00000001, 0x2128013d, 0x00000030, 0x00000000 },
-   { 0x00000040, 0x212c0d3d, 0x00000030, 0x00000001 },
+   { 0x00000001, 0x20e0013d, 0x00000030, 0x00000000 },
+   { 0x00000040, 0x20e40d3d, 0x00000030, 0x00000001 },
+   { 0x00000001, 0x20e8013d, 0x00000030, 0x00000000 },
+   { 0x00000040, 0x20ec0d3d, 0x00000030, 0x00000001 },
    { 0x00000001, 0x2120013d, 0x00000032, 0x00000000 },
    { 0x00000001, 0x2124013d, 0x00000032, 0x00000000 },
    { 0x00000040, 0x21280d3d, 0x00000032, 0x00000001 },
diff-tree 8ddbc26b276016b922487f7b1e8997998b655a7d (from parents)
Merge: 93975a526086432cdeb8d7ead721a862d632c1e7 16f9a56070a01c7ada8e566d9b73fcf7900136e0
Author: Keith Packard <keithp at neko.keithp.com>
Date:   Fri Dec 1 10:57:16 2006 -0800

    Merge branch 'modesetting' into crestline
    
    Use new TV output condition (all 9xx except 915g)

diff-tree 93975a526086432cdeb8d7ead721a862d632c1e7 (from parents)
Merge: 08b6569dc663ddf38cb36a6875de6d4ab55acac9 e603cd0c73344ef137d3276b5cfcbcf4df340778
Author: Keith Packard <keithp at neko.keithp.com>
Date:   Fri Dec 1 10:28:58 2006 -0800

    Merge branch 'modesetting' into crestline

diff --cc src/i830_driver.c
index 441eba4,3aafe3a..4cb854f
@@@ -669,12 -707,36 +709,36 @@@
     } else {
        i830_dvo_init(pScrn);
     }
- #if 1
 -   if (IS_I915GM(pI830) || IS_I945GM(pI830))
 +   if (IS_I915GM(pI830) || IS_I945GM(pI830) || IS_I965G(pI830))
        i830_tv_init(pScrn);
- #endif
  }
  
+ /**
+  * Setup the CRTCs
+  */
+ 
+ static const xf86CrtcFuncsRec i830_crtc_funcs = {
+ };
+ 
+ static void
+ I830SetupCrtcs(ScrnInfoPtr pScrn, int num_pipe)
+ {
+     int	    p;
+ 
+     for (p = 0; p < num_pipe; p++)
+     {
+ 	xf86CrtcPtr    crtc = xf86CrtcCreate (pScrn, &i830_crtc_funcs);
+ 	I830CrtcPrivatePtr  intel_crtc;
+ 	
+ 	if (!crtc)
+ 	    break;
+ 	intel_crtc = xnfcalloc (sizeof (I830CrtcPrivateRec), 1);
+ 	intel_crtc->pipe = p;
+ 	
+ 	crtc->driver_private = intel_crtc;
+     }
+ }
+     
  static void 
  I830PreInitDDC(ScrnInfoPtr pScrn)
  {
diff-tree db391e8e4c4d87bfe3ccad0de14dd5b47b69b8fe (from 290f15cd4cda97727ebcaadacbbbf7650278934b)
Author: Wang Zhenyu <zhenyu.z.wang at intel.com>
Date:   Wed Nov 29 17:16:46 2006 +0800

    shut up warning

diff --git a/src/i965_exa_render.c b/src/i965_exa_render.c
index 6f2bc84..2d1ce5f 100644
--- a/src/i965_exa_render.c
+++ b/src/i965_exa_render.c
@@ -1011,10 +1011,8 @@ I965EXAComposite(PixmapPtr pDst, int src
 
     srcXend = srcX + w;
     srcYend = srcY + h;
-    if (pMask) {
-        maskXend = maskX + w;
-        maskYend = maskY + h;
-    }
+    maskXend = maskX + w;
+    maskYend = maskY + h;
     if (is_transform[0]) {
         v.vector[0] = IntToxFixed(srcX);
         v.vector[1] = IntToxFixed(srcY);
diff-tree 290f15cd4cda97727ebcaadacbbbf7650278934b (from 3d4edd325f3859c749ee42df102bb4239eac5287)
Author: Wang Zhenyu <zhenyu.z.wang at intel.com>
Date:   Wed Nov 29 17:14:55 2006 +0800

    fix alpha blending state

diff --git a/src/i965_exa_render.c b/src/i965_exa_render.c
index c4a3f97..6f2bc84 100644
--- a/src/i965_exa_render.c
+++ b/src/i965_exa_render.c
@@ -562,21 +562,26 @@ ErrorF("i965 prepareComposite\n");
    cc_state->cc0.stencil_enable = 0;   /* disable stencil */
    cc_state->cc2.depth_test = 0;       /* disable depth test */
    cc_state->cc2.logicop_enable = 0;   /* disable logic op */
-   cc_state->cc3.ia_blend_enable = 0;  /* blend alpha just like colors */
+   cc_state->cc3.ia_blend_enable = 1;  /* blend alpha just like colors */
    cc_state->cc3.blend_enable = 1;     /* enable color blend */
    cc_state->cc3.alpha_test = 0;       /* disable alpha test */
    cc_state->cc4.cc_viewport_state_offset = (state_base_offset + cc_viewport_offset) >> 5;
    cc_state->cc5.dither_enable = 0;    /* disable dither */
-//   cc_state->cc5.logicop_func = 0xc;   /* COPY */
-//   cc_state->cc5.statistics_enable = 1;
-//   cc_state->cc5.ia_blend_function = BRW_BLENDFUNCTION_ADD;
-//   cc_state->cc5.ia_src_blend_factor = BRW_BLENDFACTOR_ONE;
-//   cc_state->cc5.ia_dest_blend_factor = BRW_BLENDFACTOR_ONE;
-   cc_state->cc6.blend_function = BRW_BLENDFUNCTION_ADD;
+   cc_state->cc5.logicop_func = 0xc;   /* COPY */
+   cc_state->cc5.statistics_enable = 1;
+   cc_state->cc5.ia_blend_function = BRW_BLENDFUNCTION_ADD;
    I965GetBlendCntl(op, pMaskPicture, pDstPicture->format, 
 		    &src_blend, &dst_blend);
+   /* XXX: alpha blend factor should be same as color, but check
+	   for CA case in future */
+   cc_state->cc5.ia_src_blend_factor = src_blend;
+   cc_state->cc5.ia_dest_blend_factor = dst_blend;
+   cc_state->cc6.blend_function = BRW_BLENDFUNCTION_ADD;
    cc_state->cc6.src_blend_factor = src_blend;
    cc_state->cc6.dest_blend_factor = dst_blend;
+   cc_state->cc6.clamp_post_alpha_blend = 1; 
+   cc_state->cc6.clamp_pre_alpha_blend = 1; 
+   cc_state->cc6.clamp_range = 0;  /* clamp range [0,1] */
 
    /* Upload system kernel */
    memcpy (sip_kernel, sip_kernel_static, sizeof (sip_kernel_static));
diff-tree 3d4edd325f3859c749ee42df102bb4239eac5287 (from a704120b15efae47344a90d972e7f3da64a202a6)
Author: Wang Zhenyu <zhenyu.z.wang at intel.com>
Date:   Wed Nov 29 17:05:32 2006 +0800

    Add in sf/wm program for mask picture without CA

diff --git a/src/exa_sf_mask.g4a b/src/exa_sf_mask.g4a
new file mode 100644
index 0000000..ab519ce
--- /dev/null
+++ b/src/exa_sf_mask.g4a
@@ -0,0 +1,53 @@
+
+/* FIXME how to setup second coeffient for mask tex coord */
+
+/* 
+   g3 (v0) { u0, v0, 1.0, 1.0 }  ==> {u0, v0, 1.0, 1.0, mu0, mv0, 1.0, 1.0}  Co[0](u0) Co[1](v0) Co[2](mu0) Co[3](mv0)
+   g4 (v1) { u1, v1, 1.0, 1.0 }  ==> {u1, v1, 1.0, 1.0, mu1, mv1, 1.0, 1.0}
+   g5 (v2) { u2, v2 }  ==> (u2, v2, mu2, mv2}
+   g6      { 1/(x1-x0), 1/(y1-y0) }
+   g7      { u1-u0, v1-v0, 0, 0}  ==>{u1-u0, v1-v0,0, 0, mu1-mu0, mv1-mv0, 0, 0}
+	   -> { (u1-u0)/(x1-x0), (v1-v0)/(y1-y0) }  ==>{(u1-u0)/(x1-x0), (v1-v0)/(y1-y0),(mu1-mu0)/(x1-x0), (mv1-mv0)/(y1-y0)
+		Cx,		 Cy 			Cx[0],		 Cy[0],		 Cx[1], 	    Cy[1]
+ */
+
+/* assign Cx[0], Cx[1] to src, same to Cy, Co 
+          Cx[2], Cx[3] to mask, same to Cy, Co */
+
+send (1) 0 g6<1>F g1.12<0,1,0>F math inv scalar mlen 1 rlen 1 { align1 };
+send (1) 0 g6.4<1>F g1.20<0,1,0>F math inv scalar mlen 1 rlen 1 { align1 };
+add (8) g7<1>F g4<8,8,1>F -g3<8,8,1>F { align1 };
+/* Cx[0] */
+mul (1) g7<1>F g7<0,1,0>F g6<0,1,0>F { align1 };
+/* Cy[0] */
+mul (1) g7.4<1>F g7.4<0,1,0>F g6.4<0,1,0>F { align1 };
+/* Cx[2] */
+mul (1) g7.16<1>F g7.16<0,1,0>F g6<0,1,0>F { align1 };
+/* Cy[2] */
+mul (1) g7.20<1>F g7.20<0,1,0>F g6.4<0,1,0>F { align1 };
+
+/* src Cx[0], Cx[1] */
+mov (8) m1<1>F g7<0,1,0>F { align1 };
+/* mask Cx[2], Cx[3] */
+mov (1) m1.8<1>F g7.16<0,1,0>F { align1 };
+mov (1) m1.12<1>F g7.16<0,1,0>F { align1 };
+/* src Cy[0], Cy[1] */
+mov (8) m2<1>F g7.4<0,1,0>F { align1 };
+/* mask Cy[2], Cy[3] */
+mov (1) m2.8<1>F g7.20<0,1,0>F { align1 };
+mov (1) m2.12<1>F g7.20<0,1,0>F { align1 };
+/* src Co[0], Co[1] */
+mov (8) m3<1>F g3<8,8,1>F { align1 };
+/* mask Co[2], Co[3] */
+mov (1) m3.8<1>F g3.16<0,1,0>F { align1 };
+mov (1) m3.12<1>F g3.20<0,1,0>F { align1 };
+
+send (8) 0 null g0<8,8,1>F urb 0 transpose used complete mlen 4 rlen 0 { align1 EOT };
+nop;
+nop;
+nop;
+nop;
+nop;
+nop;
+nop;
+nop;
diff --git a/src/exa_sf_mask_prog.h b/src/exa_sf_mask_prog.h
new file mode 100644
index 0000000..cd7f460
--- /dev/null
+++ b/src/exa_sf_mask_prog.h
@@ -0,0 +1,25 @@
+   { 0x00000031, 0x20c01fbd, 0x0000002c, 0x01110081 },
+   { 0x00000031, 0x20c41fbd, 0x00000034, 0x01110081 },
+   { 0x00600040, 0x20e077bd, 0x008d0080, 0x008d4060 },
+   { 0x00000041, 0x20e077bd, 0x000000e0, 0x000000c0 },
+   { 0x00000041, 0x20e477bd, 0x000000e4, 0x000000c4 },
+   { 0x00000041, 0x20f077bd, 0x000000f0, 0x000000c0 },
+   { 0x00000041, 0x20f477bd, 0x000000f4, 0x000000c4 },
+   { 0x00600001, 0x202003be, 0x000000e0, 0x00000000 },
+   { 0x00000001, 0x202803be, 0x000000f0, 0x00000000 },
+   { 0x00000001, 0x202c03be, 0x000000f0, 0x00000000 },
+   { 0x00600001, 0x204003be, 0x000000e4, 0x00000000 },
+   { 0x00000001, 0x204803be, 0x000000f4, 0x00000000 },
+   { 0x00000001, 0x204c03be, 0x000000f4, 0x00000000 },
+   { 0x00600001, 0x206003be, 0x008d0060, 0x00000000 },
+   { 0x00000001, 0x206803be, 0x00000070, 0x00000000 },
+   { 0x00000001, 0x206c03be, 0x00000074, 0x00000000 },
+   { 0x00600031, 0x20001fbc, 0x008d0000, 0x8640c800 },
+   { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
+   { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
+   { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
+   { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
+   { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
+   { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
+   { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
+   { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
diff --git a/src/exa_wm_masknoca.g4a b/src/exa_wm_masknoca.g4a
new file mode 100644
index 0000000..195203c
--- /dev/null
+++ b/src/exa_wm_masknoca.g4a
@@ -0,0 +1,202 @@
+/*
+ * This's for exa composite operation in no mask picture case.
+ * The simplest case is just sending what src picture has to dst picture.
+ * XXX: This is still experimental, and should be fixed to support multiple texture
+ * map, and conditional mul actions. 
+ */
+
+/* I think this should be same as in g4a program for texture video,
+   as we also use 16-pixel dispatch. and SF scale in g3 is useful for us. */
+
+/* The initial payload of the thread is always g0.
+ * WM_URB (incoming URB entries) is g3
+   As mask texture coeffient needs extra setup urb starting from g4, we should
+   shift this location. 
+
+ * X0_R is g4->g6
+ * X1_R is g5->g7
+ * Y0_R is g6->g8
+ * Y1_R is g7->g9
+
+     * X0: {ss0.x, ss0.x+1, ss0.x,   ss0.x+1, ss1.x, ss1.x+1, ss1.x,   ss1.x+y}
+     * Y0: {ss0.y, ss0.y,   ss0.y+1, ss0.y+1, ss1.y, ss1.y,   ss1.y+1, ss1.y+1}
+     * X1: {ss2.x, ss2.x+1, ss2.x,   ss2.x+1, ss3.x, ss3.x+1, ss3.x,   ss3.x+y}
+     * Y1: {ss2.y, ss2.y,   ss2.y+1, ss2.y+1, ss3.y, ss3.y,   ss3.y+1, ss3.y+1}
+ */
+
+/* multitexture program with src and mask texture */
+/* - load src texture */
+/* - load mask texture */
+/* - mul src.X with mask's alpha */
+/* - write out src.X */
+
+    /* Set up ss0.x coordinates*/
+mov (1) g6<1>F g1.8<0,1,0>UW { align1 };
+add (1) g6.4<1>F g1.8<0,1,0>UW 1UB { align1 };
+mov (1) g6.8<1>F g1.8<0,1,0>UW { align1 };
+add (1) g6.12<1>F g1.8<0,1,0>UW 1UB { align1 };
+    /* Set up ss0.y coordinates */
+mov (1) g8<1>F g1.10<0,1,0>UW { align1 };
+mov (1) g8.4<1>F g1.10<0,1,0>UW { align1 };
+add (1) g8.8<1>F g1.10<0,1,0>UW 1UB { align1 };
+add (1) g8.12<1>F g1.10<0,1,0>UW 1UB { align1 };
+    /* set up ss1.x coordinates */
+mov (1) g6.16<1>F g1.12<0,1,0>UW { align1 };
+add (1) g6.20<1>F g1.12<0,1,0>UW 1UB { align1 };
+mov (1) g6.24<1>F g1.12<0,1,0>UW { align1 };
+add (1) g6.28<1>F g1.12<0,1,0>UW 1UB { align1 };
+    /* set up ss1.y coordinates */
+mov (1) g8.16<1>F g1.14<0,1,0>UW { align1 };
+mov (1) g8.20<1>F g1.14<0,1,0>UW { align1 };
+add (1) g8.24<1>F g1.14<0,1,0>UW 1UB { align1 };
+add (1) g8.28<1>F g1.14<0,1,0>UW 1UB { align1 };
+    /* Set up ss2.x coordinates */
+mov (1) g9<1>F g1.16<0,1,0>UW { align1 };
+add (1) g9.4<1>F g1.16<0,1,0>UW 1UB { align1 };
+mov (1) g9.8<1>F g1.16<0,1,0>UW { align1 };
+add (1) g9.12<1>F g1.16<0,1,0>UW 1UB { align1 };
+    /* Set up ss2.y coordinates */
+mov (1) g9<1>F g1.18<0,1,0>UW { align1 };
+mov (1) g9.4<1>F g1.18<0,1,0>UW { align1 };
+add (1) g9.8<1>F g1.18<0,1,0>UW 1UB { align1 };
+add (1) g9.12<1>F g1.18<0,1,0>UW 1UB { align1 };
+    /* Set up ss3.x coordinates */
+mov (1) g7.16<1>F g1.20<0,1,0>UW { align1 };
+add (1) g7.20<1>F g1.20<0,1,0>UW 1UB { align1 };
+mov (1) g7.24<1>F g1.20<0,1,0>UW { align1 };
+add (1) g7.28<1>F g1.20<0,1,0>UW 1UB { align1 };
+    /* Set up ss3.y coordinates */
+mov (1) g9.16<1>F g1.22<0,1,0>UW { align1 };
+mov (1) g9.20<1>F g1.22<0,1,0>UW { align1 };
+add (1) g9.24<1>F g1.22<0,1,0>UW 1UB { align1 };
+add (1) g9.28<1>F g1.22<0,1,0>UW 1UB { align1 };
+
+    /* Now, map these screen space coordinates into texture coordinates. */
+/* This is for src texture */
+/* I don't want to change origin ssX coords, as it will be used later in mask */
+/* so store tex coords in g10, g11, g12, g13 */
+
+    /* subtract screen-space X origin of vertex 0. */
+add (8) g10<1>F g6<8,8,1>F -g1<0,1,0>F { align1 };
+add (8) g11<1>F g7<8,8,1>F -g1<0,1,0>F { align1 };
+    /* scale by texture X increment */
+/* Cx[0] */
+mul (8) g10<1>F g10<8,8,1>F g3<0,1,0>F { align1 };
+mul (8) g11<1>F g11<8,8,1>F g3<0,1,0>F { align1 };
+    /* add in texture X offset */
+/* Co[0] */
+add (8) g10<1>F g10<8,8,1>F g3.12<0,1,0>F { align1 };
+add (8) g11<1>F g11<8,8,1>F g3.12<0,1,0>F { align1 };
+    /* subtract screen-space Y origin of vertex 0. */
+add (8) g12<1>F g8<8,8,1>F -g1.4<0,1,0>F { align1 };
+add (8) g13<1>F g9<8,8,1>F -g1.4<0,1,0>F { align1 };
+    /* scale by texture Y increment */
+/* Cy[0] */
+mul (8) g12<1>F g12<8,8,1>F g3.4<0,1,0>F { align1 };
+mul (8) g13<1>F g13<8,8,1>F g3.4<0,1,0>F { align1 };
+    /* add in texture Y offset */
+/* Co[1] */
+add (8) g12<1>F g12<8,8,1>F g3.28<0,1,0>F { align1 };
+add (8) g13<1>F g13<8,8,1>F g3.28<0,1,0>F { align1 };
+
+/* prepare sampler read back gX register, which would be written back to output */
+
+/* use simd16 sampler, param 0 is u, param 1 is v. */
+/* 'payload' loading, assuming tex coord start from g4 */
+mov (8) m1<1>F g10<8,8,1>F { align1 };
+mov (8) m2<1>F g11<8,8,1>F { align1 }; /* param 0 u in m1, m2 */
+mov (8) m3<1>F g12<8,8,1>F { align1 };
+mov (8) m4<1>F g13<8,8,1>F { align1 }; /* param 1 v in m3, m4 */
+
+/* m0 will be copied with g0, as it contains send desc */
+/* emit sampler 'send' cmd */
+
+/* src texture readback: g14-g21 */
+send (16) 0 		/* msg reg index */
+	g14<1>UW 	/* readback */
+	g0<8,8,1>UW  	/* copy to msg start reg*/
+	sampler (1,0,F)  /* sampler message description, 
+				(binding_table,sampler_index,datatype). 
+			    here(src->dst) we should use src_sampler and 
+			    src_surface */
+	mlen 5 rlen 8 { align1 };   /* required message len 5, readback len 8 */
+
+mov (8) g21<1>UD g21<8,8,1>UD { align1 };  /* wait sampler return */
+
+/* sampler mask texture, use g10, g11, g12, g13 */
+    /* subtract screen-space X origin of vertex 0. */
+add (8) g10<1>F g6<8,8,1>F -g1<0,1,0>F { align1 };
+add (8) g11<1>F g7<8,8,1>F -g1<0,1,0>F { align1 };
+    /* scale by texture X increment */
+/* Cx[2] */
+mul (8) g10<1>F g10<8,8,1>F g4<0,1,0>F { align1 };
+mul (8) g11<1>F g11<8,8,1>F g4<0,1,0>F { align1 };
+    /* add in texture X offset */
+/* Co[2] */
+add (8) g10<1>F g10<8,8,1>F g4.12<0,1,0>F { align1 };
+add (8) g11<1>F g11<8,8,1>F g4.12<0,1,0>F { align1 };
+    /* subtract screen-space Y origin of vertex 0. */
+add (8) g12<1>F g8<8,8,1>F -g1.4<0,1,0>F { align1 };
+add (8) g13<1>F g9<8,8,1>F -g1.4<0,1,0>F { align1 };
+    /* scale by texture Y increment */
+/* Cy[2] */
+mul (8) g12<1>F g12<8,8,1>F g4.4<0,1,0>F { align1 };
+mul (8) g13<1>F g13<8,8,1>F g4.4<0,1,0>F { align1 };
+    /* add in texture Y offset */
+/* Co[3] */
+add (8) g12<1>F g12<8,8,1>F g4.28<0,1,0>F { align1 };
+add (8) g13<1>F g13<8,8,1>F g4.28<0,1,0>F { align1 };
+
+mov (8) m1<1>F g10<8,8,1>F { align1 };
+mov (8) m2<1>F g11<8,8,1>F { align1 }; 
+mov (8) m3<1>F g12<8,8,1>F { align1 };
+mov (8) m4<1>F g13<8,8,1>F { align1 };
+
+/* mask sampler g22-g29 */
+/* binding_table (2), sampler (1) */
+send (16) 0 g22<1>UW g0<8,8,1>UW sampler (2,1,F) mlen 5 rlen 8 { align1 };
+mov (8) g29<1>UD g29<8,8,1>UD { align1 };  /* wait sampler return */
+
+/* mul mask's alpha channel g28,g29 to src (g14-g21), then write out src */
+mul (8) g14<1>F g14<8,8,1>F g28<8,8,1>F { align1 };
+mul (8) g15<1>F g15<8,8,1>F g29<8,8,1>F { align1 };
+mul (8) g16<1>F g16<8,8,1>F g28<8,8,1>F { align1 };
+mul (8) g17<1>F g17<8,8,1>F g29<8,8,1>F { align1 };
+mul (8) g18<1>F g18<8,8,1>F g28<8,8,1>F { align1 };
+mul (8) g19<1>F g19<8,8,1>F g29<8,8,1>F { align1 };
+mul (8) g20<1>F g20<8,8,1>F g28<8,8,1>F { align1 };
+mul (8) g21<1>F g21<8,8,1>F g29<8,8,1>F { align1 };
+
+/* prepare data in m2-m5 for subspan(1,0), m6-m9 for subspan(3,2), then it's ready to write */
+mov (8) m2<1>F g14<8,8,1>F { align1 };
+mov (8) m3<1>F g16<8,8,1>F { align1 };
+mov (8) m4<1>F g18<8,8,1>F { align1 };
+mov (8) m5<1>F g20<8,8,1>F { align1 };
+mov (8) m6<1>F g15<8,8,1>F { align1 };
+mov (8) m7<1>F g17<8,8,1>F { align1 };
+mov (8) m8<1>F g19<8,8,1>F { align1 };
+mov (8) m9<1>F g21<8,8,1>F { align1 };
+
+/* m0, m1 are all direct passed by PS thread payload */
+mov (8) m1<1>UD g1<8,8,1>UD { align1 mask_disable };
+
+/* write */
+send (16) 0 acc0<1>UW g0<8,8,1>UW write (
+	0,  /* binding_table */
+	8,  /* pixel scordboard clear, msg type simd16 single source */
+	4,  /* render target write */
+	0   /* no write commit message */
+	) 
+	mlen 10
+	rlen 0
+	{ align1 EOT };
+
+nop;
+nop;
+nop;
+nop;
+nop;
+nop;
+nop;
+nop;
+nop;
diff --git a/src/exa_wm_masknoca_prog.h b/src/exa_wm_masknoca_prog.h
new file mode 100644
index 0000000..66eb960
--- /dev/null
+++ b/src/exa_wm_masknoca_prog.h
@@ -0,0 +1,95 @@
+   { 0x00000001, 0x20c0013d, 0x00000028, 0x00000000 },
+   { 0x00000040, 0x20c40d3d, 0x00000028, 0x00000001 },
+   { 0x00000001, 0x20c8013d, 0x00000028, 0x00000000 },
+   { 0x00000040, 0x20cc0d3d, 0x00000028, 0x00000001 },
+   { 0x00000001, 0x2100013d, 0x0000002a, 0x00000000 },
+   { 0x00000001, 0x2104013d, 0x0000002a, 0x00000000 },
+   { 0x00000040, 0x21080d3d, 0x0000002a, 0x00000001 },
+   { 0x00000040, 0x210c0d3d, 0x0000002a, 0x00000001 },
+   { 0x00000001, 0x20d0013d, 0x0000002c, 0x00000000 },
+   { 0x00000040, 0x20d40d3d, 0x0000002c, 0x00000001 },
+   { 0x00000001, 0x20d8013d, 0x0000002c, 0x00000000 },
+   { 0x00000040, 0x20dc0d3d, 0x0000002c, 0x00000001 },
+   { 0x00000001, 0x2110013d, 0x0000002e, 0x00000000 },
+   { 0x00000001, 0x2114013d, 0x0000002e, 0x00000000 },
+   { 0x00000040, 0x21180d3d, 0x0000002e, 0x00000001 },
+   { 0x00000040, 0x211c0d3d, 0x0000002e, 0x00000001 },
+   { 0x00000001, 0x2120013d, 0x00000030, 0x00000000 },
+   { 0x00000040, 0x21240d3d, 0x00000030, 0x00000001 },
+   { 0x00000001, 0x2128013d, 0x00000030, 0x00000000 },
+   { 0x00000040, 0x212c0d3d, 0x00000030, 0x00000001 },
+   { 0x00000001, 0x2120013d, 0x00000032, 0x00000000 },
+   { 0x00000001, 0x2124013d, 0x00000032, 0x00000000 },
+   { 0x00000040, 0x21280d3d, 0x00000032, 0x00000001 },
+   { 0x00000040, 0x212c0d3d, 0x00000032, 0x00000001 },
+   { 0x00000001, 0x20f0013d, 0x00000034, 0x00000000 },
+   { 0x00000040, 0x20f40d3d, 0x00000034, 0x00000001 },
+   { 0x00000001, 0x20f8013d, 0x00000034, 0x00000000 },
+   { 0x00000040, 0x20fc0d3d, 0x00000034, 0x00000001 },
+   { 0x00000001, 0x2130013d, 0x00000036, 0x00000000 },
+   { 0x00000001, 0x2134013d, 0x00000036, 0x00000000 },
+   { 0x00000040, 0x21380d3d, 0x00000036, 0x00000001 },
+   { 0x00000040, 0x213c0d3d, 0x00000036, 0x00000001 },
+   { 0x00600040, 0x214077bd, 0x008d00c0, 0x00004020 },
+   { 0x00600040, 0x216077bd, 0x008d00e0, 0x00004020 },
+   { 0x00600041, 0x214077bd, 0x008d0140, 0x00000060 },
+   { 0x00600041, 0x216077bd, 0x008d0160, 0x00000060 },
+   { 0x00600040, 0x214077bd, 0x008d0140, 0x0000006c },
+   { 0x00600040, 0x216077bd, 0x008d0160, 0x0000006c },
+   { 0x00600040, 0x218077bd, 0x008d0100, 0x00004024 },
+   { 0x00600040, 0x21a077bd, 0x008d0120, 0x00004024 },
+   { 0x00600041, 0x218077bd, 0x008d0180, 0x00000064 },
+   { 0x00600041, 0x21a077bd, 0x008d01a0, 0x00000064 },
+   { 0x00600040, 0x218077bd, 0x008d0180, 0x0000007c },
+   { 0x00600040, 0x21a077bd, 0x008d01a0, 0x0000007c },
+   { 0x00600001, 0x202003be, 0x008d0140, 0x00000000 },
+   { 0x00600001, 0x204003be, 0x008d0160, 0x00000000 },
+   { 0x00600001, 0x206003be, 0x008d0180, 0x00000000 },
+   { 0x00600001, 0x208003be, 0x008d01a0, 0x00000000 },
+   { 0x00800031, 0x21c01d29, 0x008d0000, 0x02580001 },
+   { 0x00600001, 0x22a00021, 0x008d02a0, 0x00000000 },
+   { 0x00600040, 0x214077bd, 0x008d00c0, 0x00004020 },
+   { 0x00600040, 0x216077bd, 0x008d00e0, 0x00004020 },
+   { 0x00600041, 0x214077bd, 0x008d0140, 0x00000080 },
+   { 0x00600041, 0x216077bd, 0x008d0160, 0x00000080 },
+   { 0x00600040, 0x214077bd, 0x008d0140, 0x0000008c },
+   { 0x00600040, 0x216077bd, 0x008d0160, 0x0000008c },
+   { 0x00600040, 0x218077bd, 0x008d0100, 0x00004024 },
+   { 0x00600040, 0x21a077bd, 0x008d0120, 0x00004024 },
+   { 0x00600041, 0x218077bd, 0x008d0180, 0x00000084 },
+   { 0x00600041, 0x21a077bd, 0x008d01a0, 0x00000084 },
+   { 0x00600040, 0x218077bd, 0x008d0180, 0x0000009c },
+   { 0x00600040, 0x21a077bd, 0x008d01a0, 0x0000009c },
+   { 0x00600001, 0x202003be, 0x008d0140, 0x00000000 },
+   { 0x00600001, 0x204003be, 0x008d0160, 0x00000000 },
+   { 0x00600001, 0x206003be, 0x008d0180, 0x00000000 },
+   { 0x00600001, 0x208003be, 0x008d01a0, 0x00000000 },
+   { 0x00800031, 0x22c01d29, 0x008d0000, 0x02580102 },
+   { 0x00600001, 0x23a00021, 0x008d03a0, 0x00000000 },
+   { 0x00600041, 0x21c077bd, 0x008d01c0, 0x008d0380 },
+   { 0x00600041, 0x21e077bd, 0x008d01e0, 0x008d03a0 },
+   { 0x00600041, 0x220077bd, 0x008d0200, 0x008d0380 },
+   { 0x00600041, 0x222077bd, 0x008d0220, 0x008d03a0 },
+   { 0x00600041, 0x224077bd, 0x008d0240, 0x008d0380 },
+   { 0x00600041, 0x226077bd, 0x008d0260, 0x008d03a0 },
+   { 0x00600041, 0x228077bd, 0x008d0280, 0x008d0380 },
+   { 0x00600041, 0x22a077bd, 0x008d02a0, 0x008d03a0 },
+   { 0x00600001, 0x204003be, 0x008d01c0, 0x00000000 },
+   { 0x00600001, 0x206003be, 0x008d0200, 0x00000000 },
+   { 0x00600001, 0x208003be, 0x008d0240, 0x00000000 },
+   { 0x00600001, 0x20a003be, 0x008d0280, 0x00000000 },
+   { 0x00600001, 0x20c003be, 0x008d01e0, 0x00000000 },
+   { 0x00600001, 0x20e003be, 0x008d0220, 0x00000000 },
+   { 0x00600001, 0x210003be, 0x008d0260, 0x00000000 },
+   { 0x00600001, 0x212003be, 0x008d02a0, 0x00000000 },
+   { 0x00600201, 0x20200022, 0x008d0020, 0x00000000 },
+   { 0x00800031, 0x24001d28, 0x008d0000, 0x85a04800 },
+   { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
+   { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
+   { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
+   { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
+   { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
+   { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
+   { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
+   { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
+   { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
diff --git a/src/i965_exa_render.c b/src/i965_exa_render.c
index 4bc90c1..c4a3f97 100644
--- a/src/i965_exa_render.c
+++ b/src/i965_exa_render.c
@@ -344,12 +344,16 @@ static const CARD32 sf_kernel_static[][4
 #include "exa_sf_prog.h"
 };
 
+static const CARD32 sf_kernel_static_mask[][4] = {
+#include "exa_sf_mask_prog.h"
+};
+
 /* ps kernels */
 #define PS_KERNEL_NUM_GRF   32
 #define PS_MAX_THREADS	   32
 /* 1: no mask */
 static const CARD32 ps_kernel_static_nomask [][4] = {
-	#include "exa_wm_nomask_prog.h"
+#include "exa_wm_nomask_prog.h"
 };
 
 /* 2: mask with componentAlpha, src * mask color, XXX: later */
@@ -359,7 +363,7 @@ static const CARD32 ps_kernel_static_mas
 
 /* 3: mask without componentAlpha, src * mask alpha */
 static const CARD32 ps_kernel_static_masknoca [][4] = {
-/*#include "i965_composite_wm_masknoca.h" */
+#include "exa_wm_masknoca_prog.h"
 };
 
 Bool
@@ -375,11 +379,6 @@ I965EXAPrepareComposite(int op, PictureP
  
 ErrorF("i965 prepareComposite\n");
 
-    /* FIXME: fallback in pMask for now, would be enable after finish
-	wm kernel program */
-    if (pMask)
-	I830FALLBACK("No mask support yet.\n");
-
     I965GetDestFormat(pDstPicture, &dst_format);
     src_offset = exaGetPixmapOffset(pSrc);
     src_pitch = exaGetPixmapPitch(pSrc);
@@ -436,7 +435,10 @@ ErrorF("i965 prepareComposite\n");
    /* keep current sf_kernel, which will send one setup urb entry to
 	PS kernel */
    sf_kernel_offset = ALIGN(next_offset, 64);
-   next_offset = sf_kernel_offset + sizeof (sf_kernel_static);
+   if (pMask) 
+       next_offset = sf_kernel_offset + sizeof (sf_kernel_static_mask);
+   else
+       next_offset = sf_kernel_offset + sizeof (sf_kernel_static);
 
    //XXX: ps_kernel may be seperated, fix with offset
    ps_kernel_offset = ALIGN(next_offset, 64);
@@ -746,7 +748,10 @@ ErrorF("i965 prepareComposite\n");
     * calculate dA/dx and dA/dy.  Hand these interpolation coefficients
     * back to SF which then hands pixels off to WM.
     */
-   memcpy (sf_kernel, sf_kernel_static, sizeof (sf_kernel_static));
+   if (pMask) 
+       memcpy (sf_kernel, sf_kernel_static_mask, sizeof (sf_kernel_static));
+   else
+       memcpy (sf_kernel, sf_kernel_static, sizeof (sf_kernel_static));
 
    memset(sf_state, 0, sizeof(*sf_state));
    sf_state->thread0.kernel_start_pointer = 
@@ -780,7 +785,6 @@ ErrorF("i965 prepareComposite\n");
    /* Set up the PS kernel (dispatched by WM) 
     */
     
-    // XXX: replace to texture blend shader, and different cases 
    if (pMask) {
 	if (pMaskPicture->componentAlpha)
    	    memcpy (ps_kernel, ps_kernel_static_maskca, sizeof (ps_kernel_static_maskca));
diff-tree a704120b15efae47344a90d972e7f3da64a202a6 (from e3c70c68e39183226e498271c44e98ef1b96a681)
Author: Wang Zhenyu <zhenyu.z.wang at intel.com>
Date:   Wed Nov 29 16:52:44 2006 +0800

    misc cleanup for G965 vs/sf/wm states

diff --git a/src/i965_exa_render.c b/src/i965_exa_render.c
index 51b2c60..4bc90c1 100644
--- a/src/i965_exa_render.c
+++ b/src/i965_exa_render.c
@@ -266,6 +266,7 @@ I965EXACheckComposite(int op, PicturePtr
 
 #define ALIGN(i,m)    (((i) + (m) - 1) & ~((m) - 1))
 #define MIN(a,b) ((a) < (b) ? (a) : (b))
+#define BRW_GRF_BLOCKS(nreg)    ((nreg + 15) / 16 - 1)
 
 int urb_vs_start, urb_vs_size;
 int urb_gs_start, urb_gs_size;
@@ -336,9 +337,8 @@ static const CARD32 sip_kernel_static[][
  * with the base texture coordinate. It was extracted from the Mesa driver
  */
 
-#define SF_KERNEL_NUM_GRF  10
-#define SF_KERNEL_NUM_URB  8
-#define SF_MAX_THREADS	   4
+#define SF_KERNEL_NUM_GRF  16
+#define SF_MAX_THREADS	   1
 
 static const CARD32 sf_kernel_static[][4] = {
 #include "exa_sf_prog.h"
@@ -468,7 +468,6 @@ ErrorF("i965 prepareComposite\n");
    next_offset = vb_offset + vb_size;
 
    /* And then the general state: */
-   //XXX: fix for texture map and target surface
    dest_surf_offset = ALIGN(next_offset, 32);
    next_offset = dest_surf_offset + sizeof(*dest_surf_state);
 
@@ -534,8 +533,8 @@ ErrorF("i965 prepareComposite\n");
 #define URB_CLIP_ENTRY_SIZE   0
 #define URB_CLIP_ENTRIES      0
    
-#define URB_SF_ENTRY_SIZE     4
-#define URB_SF_ENTRIES	      8
+#define URB_SF_ENTRY_SIZE     2
+#define URB_SF_ENTRIES	      1
 
    urb_vs_start = 0;
    urb_vs_size = URB_VS_ENTRIES * URB_VS_ENTRY_SIZE;
@@ -564,7 +563,6 @@ ErrorF("i965 prepareComposite\n");
    cc_state->cc3.ia_blend_enable = 0;  /* blend alpha just like colors */
    cc_state->cc3.blend_enable = 1;     /* enable color blend */
    cc_state->cc3.alpha_test = 0;       /* disable alpha test */
-   // XXX:cc_viewport needed? 
    cc_state->cc4.cc_viewport_state_offset = (state_base_offset + cc_viewport_offset) >> 5;
    cc_state->cc5.dither_enable = 0;    /* disable dither */
 //   cc_state->cc5.logicop_func = 0xc;   /* COPY */
@@ -585,7 +583,6 @@ ErrorF("i965 prepareComposite\n");
    memset(dest_surf_state, 0, sizeof(*dest_surf_state));
    dest_surf_state->ss0.surface_type = BRW_SURFACE_2D;
    dest_surf_state->ss0.data_return_format = BRW_SURFACERETURNFORMAT_FLOAT32;
-   // XXX: should compare with picture's cpp?...8 bit surf?
    if (pDst->drawable.bitsPerPixel == 16) {
       dest_surf_state->ss0.surface_format = BRW_SURFACEFORMAT_B5G6R5_UNORM;
    } else {
@@ -601,14 +598,12 @@ ErrorF("i965 prepareComposite\n");
    dest_surf_state->ss0.mipmap_layout_mode = 0;
    dest_surf_state->ss0.render_cache_read_mode = 0;
    
-   // XXX: fix to picture address & size
    dest_surf_state->ss1.base_addr = dst_offset;
    dest_surf_state->ss2.height = pDst->drawable.height - 1;
    dest_surf_state->ss2.width = pDst->drawable.width - 1;
    dest_surf_state->ss2.mip_count = 0;
    dest_surf_state->ss2.render_target_rotation = 0;
    dest_surf_state->ss3.pitch = dst_pitch - 1; 
-   // tiled surface?
 
    /* Set up the source surface state buffer */
    memset(src_surf_state, 0, sizeof(*src_surf_state));
@@ -741,8 +736,10 @@ ErrorF("i965 prepareComposite\n");
 
    /* Set up the vertex shader to be disabled (passthrough) */
    memset(vs_state, 0, sizeof(*vs_state));
-   // XXX: vs URB should be defined for VF vertex URB store. done already?
+   vs_state->thread4.nr_urb_entries = URB_VS_ENTRIES;
+   vs_state->thread4.urb_entry_allocation_size = URB_VS_ENTRY_SIZE - 1;
    vs_state->vs6.vs_enable = 0;
+   vs_state->vs6.vert_cache_disable = 1;
 
    // XXX: sf_kernel? keep it as now
    /* Set up the SF kernel to do coord interp: for each attribute,
@@ -754,7 +751,7 @@ ErrorF("i965 prepareComposite\n");
    memset(sf_state, 0, sizeof(*sf_state));
    sf_state->thread0.kernel_start_pointer = 
 	       (state_base_offset + sf_kernel_offset) >> 6;
-   sf_state->thread0.grf_reg_count = ((SF_KERNEL_NUM_GRF & ~15) / 16);
+   sf_state->thread0.grf_reg_count = BRW_GRF_BLOCKS(SF_KERNEL_NUM_GRF);
    sf_state->sf1.single_program_flow = 1;
    sf_state->sf1.binding_table_entry_count = 0;
    sf_state->sf1.thread_priority = 0;
@@ -795,7 +792,7 @@ ErrorF("i965 prepareComposite\n");
    memset (wm_state, 0, sizeof (*wm_state));
    wm_state->thread0.kernel_start_pointer = 
 	    (state_base_offset + ps_kernel_offset) >> 6;
-   wm_state->thread0.grf_reg_count = ((PS_KERNEL_NUM_GRF & ~15) / 16);
+   wm_state->thread0.grf_reg_count = BRW_GRF_BLOCKS(PS_KERNEL_NUM_GRF);
    wm_state->thread1.single_program_flow = 1;
    if (!pMask)
        wm_state->thread1.binding_table_entry_count = 2; /* 1 tex and fb */
@@ -808,7 +805,10 @@ ErrorF("i965 prepareComposite\n");
    // XXX: urb allocation
    wm_state->thread3.const_urb_entry_read_length = 0;
    wm_state->thread3.const_urb_entry_read_offset = 0;
-   wm_state->thread3.urb_entry_read_length = 1;  /* one per pair of attrib */
+   if (pMask)
+       wm_state->thread3.urb_entry_read_length = 2;  /* two per pair of attrib */
+   else 
+       wm_state->thread3.urb_entry_read_length = 1;  /* one per pair of attrib */
    wm_state->thread3.urb_entry_read_offset = 0;
    // wm kernel use urb from 3, see wm_program in compiler module
    wm_state->thread3.dispatch_grf_start_reg = 3; /* must match kernel */
diff-tree e3c70c68e39183226e498271c44e98ef1b96a681 (from aa515c54f0cfd9025fc38dc4b7938ff17a8a13fb)
Author: Wang Zhenyu <zhenyu.z.wang at intel.com>
Date:   Wed Nov 29 16:40:15 2006 +0800

    WM kernel needs scratch space

diff --git a/src/i965_exa_render.c b/src/i965_exa_render.c
index 51c2006..51b2c60 100644
--- a/src/i965_exa_render.c
+++ b/src/i965_exa_render.c
@@ -297,6 +297,7 @@ int dest_surf_offset, src_surf_offset, m
 int src_sampler_offset, mask_sampler_offset,vs_offset;
 int sf_offset, wm_offset, cc_offset, vb_offset, cc_viewport_offset;
 int sf_kernel_offset, ps_kernel_offset, sip_kernel_offset;
+int wm_scratch_offset;
 int binding_table_offset;
 int default_color_offset; 
 int next_offset, total_state_size;
@@ -426,6 +427,9 @@ ErrorF("i965 prepareComposite\n");
    wm_offset = ALIGN(next_offset, 32);
    next_offset = wm_offset + sizeof(*wm_state);
     
+   wm_scratch_offset = ALIGN(next_offset, 1024);
+   next_offset = wm_scratch_offset + 1024 * PS_MAX_THREADS;
+
    cc_offset = ALIGN(next_offset, 32);
    next_offset = cc_offset + sizeof(*cc_state);
 
@@ -798,7 +802,8 @@ ErrorF("i965 prepareComposite\n");
    else
        wm_state->thread1.binding_table_entry_count = 3; /* 2 tex and fb */
 
-   wm_state->thread2.scratch_space_base_pointer = 0;
+   wm_state->thread2.scratch_space_base_pointer = (state_base_offset + 
+						   wm_scratch_offset)>>10;
    wm_state->thread2.per_thread_scratch_space = 0;
    // XXX: urb allocation
    wm_state->thread3.const_urb_entry_read_length = 0;
diff-tree aa515c54f0cfd9025fc38dc4b7938ff17a8a13fb (from b6eba96584bcd2c024f6443d9f3728eb65b234fb)
Author: Wang Zhenyu <zhenyu.z.wang at intel.com>
Date:   Wed Nov 29 16:37:06 2006 +0800

    Setup default border color for our samplers

diff --git a/src/i965_exa_render.c b/src/i965_exa_render.c
index 94eabfb..51c2006 100644
--- a/src/i965_exa_render.c
+++ b/src/i965_exa_render.c
@@ -278,6 +278,7 @@ struct brw_surface_state *src_surf_state
 struct brw_surface_state *mask_surf_state;
 struct brw_sampler_state *src_sampler_state;
 struct brw_sampler_state *mask_sampler_state;  
+struct brw_sampler_default_color *default_color_state;
 
 struct brw_vs_unit_state *vs_state;
 struct brw_sf_unit_state *sf_state;
@@ -297,6 +298,7 @@ int src_sampler_offset, mask_sampler_off
 int sf_offset, wm_offset, cc_offset, vb_offset, cc_viewport_offset;
 int sf_kernel_offset, ps_kernel_offset, sip_kernel_offset;
 int binding_table_offset;
+int default_color_offset; 
 int next_offset, total_state_size;
 char *state_base;
 int state_base_offset;
@@ -478,6 +480,9 @@ ErrorF("i965 prepareComposite\n");
    binding_table_offset = ALIGN(next_offset, 32);
    next_offset = binding_table_offset + (binding_table_entries * 4);
 
+   default_color_offset = ALIGN(next_offset, 32);
+   next_offset = default_color_offset + sizeof(*default_color_state);
+
    total_state_size = next_offset;
    assert(total_state_size < EXA_LINEAR_EXTRA);
 
@@ -508,6 +513,8 @@ ErrorF("i965 prepareComposite\n");
 
    vb = (void *)(state_base + vb_offset);
 
+   default_color_state = (void*)(state_base + default_color_offset);
+
    /* Set up a default static partitioning of the URB, which is supposed to
     * allow anything we would want to do, at potentially lower performance.
     */
@@ -541,7 +548,6 @@ ErrorF("i965 prepareComposite\n");
     * here, but we should have synced the 3D engine already in I830PutImage.
     */
 
-// needed?
    memset (cc_viewport, 0, sizeof (*cc_viewport));
    cc_viewport->min_depth = -1.e35;
    cc_viewport->max_depth = 1.e35;
@@ -678,18 +684,25 @@ ErrorF("i965 prepareComposite\n");
 	I830FALLBACK("Bad filter 0x%x\n", pSrcPicture->filter);
    }
 
+   memset(default_color_state, 0, sizeof(*default_color_state));
+   default_color_state->color[0] = 1.0; /* RGBA format */
+   default_color_state->color[1] = 0.0; 
+   default_color_state->color[2] = 0.0; 
+   default_color_state->color[3] = 0.0; 
+
+   src_sampler_state->ss0.default_color_mode = 0; /* GL mode */
+
    if (!pSrcPicture->repeat) {
-	/* XXX: clamp_border and set border to 0 */
-   	src_sampler_state->ss1.r_wrap_mode = BRW_TEXCOORDMODE_CLAMP; 
-   	src_sampler_state->ss1.s_wrap_mode = BRW_TEXCOORDMODE_CLAMP;
-   	src_sampler_state->ss1.t_wrap_mode = BRW_TEXCOORDMODE_CLAMP;
+   	src_sampler_state->ss1.r_wrap_mode = BRW_TEXCOORDMODE_CLAMP_BORDER; 
+   	src_sampler_state->ss1.s_wrap_mode = BRW_TEXCOORDMODE_CLAMP_BORDER;
+   	src_sampler_state->ss1.t_wrap_mode = BRW_TEXCOORDMODE_CLAMP_BORDER;
+	src_sampler_state->ss2.default_color_pointer = 
+			(state_base_offset + default_color_offset) >> 5;
    } else {
    	src_sampler_state->ss1.r_wrap_mode = BRW_TEXCOORDMODE_WRAP; 
    	src_sampler_state->ss1.s_wrap_mode = BRW_TEXCOORDMODE_WRAP;
    	src_sampler_state->ss1.t_wrap_mode = BRW_TEXCOORDMODE_WRAP;
    }
-   /* XXX: ss2 has border color pointer, which should be in general state address,
-    	   and just a single texel tex map, with R32G32B32A32_FLOAT */
    src_sampler_state->ss3.chroma_key_enable = 0; /* disable chromakey */
 
    if (pMask) {
@@ -709,17 +722,16 @@ ErrorF("i965 prepareComposite\n");
    	}
 
    	if (!pMaskPicture->repeat) {
-	/* XXX: clamp_border and set border to 0 */
-   	    mask_sampler_state->ss1.r_wrap_mode = BRW_TEXCOORDMODE_CLAMP; 
-   	    mask_sampler_state->ss1.s_wrap_mode = BRW_TEXCOORDMODE_CLAMP;
-   	    mask_sampler_state->ss1.t_wrap_mode = BRW_TEXCOORDMODE_CLAMP;
+   	    mask_sampler_state->ss1.r_wrap_mode = BRW_TEXCOORDMODE_CLAMP_BORDER; 
+   	    mask_sampler_state->ss1.s_wrap_mode = BRW_TEXCOORDMODE_CLAMP_BORDER;
+   	    mask_sampler_state->ss1.t_wrap_mode = BRW_TEXCOORDMODE_CLAMP_BORDER;
+            mask_sampler_state->ss2.default_color_pointer = 
+				(state_base_offset + default_color_offset)>>5;
    	} else {
    	    mask_sampler_state->ss1.r_wrap_mode = BRW_TEXCOORDMODE_WRAP; 
    	    mask_sampler_state->ss1.s_wrap_mode = BRW_TEXCOORDMODE_WRAP;
    	    mask_sampler_state->ss1.t_wrap_mode = BRW_TEXCOORDMODE_WRAP;
     	}
-   /* XXX: ss2 has border color pointer, which should be in general state address,
-    	   and just a single texel tex map, with R32G32B32A32_FLOAT */
    	mask_sampler_state->ss3.chroma_key_enable = 0; /* disable chromakey */
    }
 
diff-tree b6eba96584bcd2c024f6443d9f3728eb65b234fb (from 453842c9ff733af45fa665d9db6a35164f45c60a)
Author: Wang Zhenyu <zhenyu.z.wang at intel.com>
Date:   Wed Nov 29 16:30:53 2006 +0800

    fix vertex buffer size

diff --git a/src/i965_exa_render.c b/src/i965_exa_render.c
index 9127d65..94eabfb 100644
--- a/src/i965_exa_render.c
+++ b/src/i965_exa_render.c
@@ -233,16 +233,12 @@ Bool
 I965EXACheckComposite(int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture,
 		      PicturePtr pDstPicture)
 {
-	/* check op*/
-	/* check op with mask's componentAlpha*/
-	/* check textures */
-	/* check dst buffer format */
     CARD32 tmp1;
     
     /* Check for unsupported compositing operations. */
     if (op >= sizeof(I965BlendOp) / sizeof(I965BlendOp[0]))
         I830FALLBACK("Unsupported Composite op 0x%x\n", op);
-                                                                                                                                                            
+
     if (pMaskPicture != NULL && pMaskPicture->componentAlpha) {
         /* Check if it's component alpha that relies on a source alpha and on
          * the source value.  We can only get one of those into the single
@@ -305,7 +301,7 @@ int next_offset, total_state_size;
 char *state_base;
 int state_base_offset;
 float *vb;
-int vb_size = 4 * 4 ; /* 4 DWORDS per vertex, 4 vertices for TRIFAN*/ 
+int vb_size = (4 * 4) * 4 ; /* 4 DWORDS per vertex*/ 
 
 CARD32 src_blend, dst_blend;
 
diff-tree 453842c9ff733af45fa665d9db6a35164f45c60a (from 18ad7d5cf04081d89a9f978ccc7794116f7c498b)
Author: Wang Zhenyu <zhenyu.z.wang at intel.com>
Date:   Wed Nov 29 16:24:24 2006 +0800

    clean up issue cmd to ring buffer
    
    Make it easy to track different part of ring state, and
    use rectlist primitive instead.

diff --git a/src/i965_exa_render.c b/src/i965_exa_render.c
index 2c3e43b..9127d65 100644
--- a/src/i965_exa_render.c
+++ b/src/i965_exa_render.c
@@ -376,11 +376,6 @@ I965EXAPrepareComposite(int op, PictureP
  
 ErrorF("i965 prepareComposite\n");
 
-//    i965_3d_pipeline_setup(pScrn);
-//    i965_surf_setup(pScrn, pSrcPicture, pMaskPicture, pDstPicture,
-//   			pSrc, pMask, pDst);
-    // then setup blend, and shader program 
-    
     /* FIXME: fallback in pMask for now, would be enable after finish
 	wm kernel program */
     if (pMask)
@@ -819,62 +814,65 @@ ErrorF("i965 prepareComposite\n");
     * rendering pipe
     */
    {
-   
-   BEGIN_LP_RING((pMask?48:46));
-   // MI_FLUSH prior to PIPELINE_SELECT
-   OUT_RING(MI_FLUSH | 
+	BEGIN_LP_RING(2);
+   	OUT_RING(MI_FLUSH | 
 	    MI_STATE_INSTRUCTION_CACHE_FLUSH |
 	    BRW_MI_GLOBAL_SNAPSHOT_RESET);
+	OUT_RING(MI_NOOP);
+	ADVANCE_LP_RING();
+   }
+   {
+        BEGIN_LP_RING(12);
    
-   /* Match Mesa driver setup */
-   OUT_RING(BRW_PIPELINE_SELECT | PIPELINE_SELECT_3D);
+        /* Match Mesa driver setup */
+        OUT_RING(BRW_PIPELINE_SELECT | PIPELINE_SELECT_3D);
    
+   	OUT_RING(BRW_CS_URB_STATE | 0);
+   	OUT_RING((0 << 4) |  /* URB Entry Allocation Size */
+            (0 << 0));  /* Number of URB Entries */
+
    /* Zero out the two base address registers so all offsets are absolute */
-   // XXX: zero out...
-   OUT_RING(BRW_STATE_BASE_ADDRESS | 4);
-   // why this's not state_base_offset? -> because later we'll always add on
-   // state_base_offset to offset params. see SIP
-   OUT_RING(0 | BASE_ADDRESS_MODIFY);  /* Generate state base address */
-   OUT_RING(0 | BASE_ADDRESS_MODIFY);  /* Surface state base address */
-   OUT_RING(0 | BASE_ADDRESS_MODIFY);  /* media base addr, don't care */
-   OUT_RING(0x10000000 | BASE_ADDRESS_MODIFY);  /* general state max addr, disabled */
-   OUT_RING(0x10000000 | BASE_ADDRESS_MODIFY);  /* media object state max addr, disabled */
+   	OUT_RING(BRW_STATE_BASE_ADDRESS | 4);
+   	OUT_RING(0 | BASE_ADDRESS_MODIFY);  /* Generate state base address */
+   	OUT_RING(0 | BASE_ADDRESS_MODIFY);  /* Surface state base address */
+   	OUT_RING(0 | BASE_ADDRESS_MODIFY);  /* media base addr, don't care */
+   	OUT_RING(0x10000000 | BASE_ADDRESS_MODIFY);  /* general state max addr, disabled */
+   	OUT_RING(0x10000000 | BASE_ADDRESS_MODIFY);  /* media object state max addr, disabled */
 
    /* Set system instruction pointer */
-   OUT_RING(BRW_STATE_SIP | 0);
-   OUT_RING(state_base_offset + sip_kernel_offset); /* system instruction pointer */
-      
+   	OUT_RING(BRW_STATE_SIP | 0);
+   	OUT_RING(state_base_offset + sip_kernel_offset); /* system instruction pointer */
+	OUT_RING(MI_NOOP);
+	ADVANCE_LP_RING();
+   }
+   {
+	BEGIN_LP_RING(26);
    /* Pipe control */
-   // XXX: pipe control write cache before enabling color blending
-   // vol2, geometry pipeline 1.8.4
-   OUT_RING(BRW_PIPE_CONTROL |
+   	OUT_RING(BRW_PIPE_CONTROL |
 	    BRW_PIPE_CONTROL_NOWRITE |
 	    BRW_PIPE_CONTROL_IS_FLUSH |
 	    2);
-   OUT_RING(0);			       /* Destination address */
-   OUT_RING(0);			       /* Immediate data low DW */
-   OUT_RING(0);			       /* Immediate data high DW */
+   	OUT_RING(0);			       /* Destination address */
+   	OUT_RING(0);			       /* Immediate data low DW */
+   	OUT_RING(0);			       /* Immediate data high DW */
 
    /* Binding table pointers */
-   OUT_RING(BRW_3DSTATE_BINDING_TABLE_POINTERS | 4);
-   OUT_RING(0); /* vs */
-   OUT_RING(0); /* gs */
-   OUT_RING(0); /* clip */
-   OUT_RING(0); /* sf */
+   	OUT_RING(BRW_3DSTATE_BINDING_TABLE_POINTERS | 4);
+   	OUT_RING(0); /* vs */
+   	OUT_RING(0); /* gs */
+   	OUT_RING(0); /* clip */
+   	OUT_RING(0); /* sf */
    /* Only the PS uses the binding table */
-   OUT_RING(state_base_offset + binding_table_offset); /* ps */
-
-   //ring 20
+   	OUT_RING(state_base_offset + binding_table_offset); /* ps */
 
    /* The drawing rectangle clipping is always on.  Set it to values that
     * shouldn't do any clipping.
     */
-    //XXX: fix for picture size
-   OUT_RING(BRW_3DSTATE_DRAWING_RECTANGLE | 2);	/* XXX 3 for BLC or CTG */
-   OUT_RING(0x00000000);	/* ymin, xmin */
-   OUT_RING((pScrn->virtualX - 1) |
-	    (pScrn->virtualY - 1) << 16); /* ymax, xmax */
-   OUT_RING(0x00000000);	/* yorigin, xorigin */
+   	OUT_RING(BRW_3DSTATE_DRAWING_RECTANGLE | 2);	/* XXX 3 for BLC or CTG */
+   	OUT_RING(0x00000000);	/* ymin, xmin */
+   	OUT_RING((pScrn->virtualX - 1) |
+ 	         (pScrn->virtualY - 1) << 16); /* ymax, xmax */
+   	OUT_RING(0x00000000);	/* yorigin, xorigin */
 
    /* skip the depth buffer */
    /* skip the polygon stipple */
@@ -882,90 +880,82 @@ ErrorF("i965 prepareComposite\n");
    /* skip the line stipple */
    
    /* Set the pointers to the 3d pipeline state */
-   OUT_RING(BRW_3DSTATE_PIPELINED_POINTERS | 5);
-   OUT_RING(state_base_offset + vs_offset);  /* 32 byte aligned */
-   OUT_RING(BRW_GS_DISABLE);		     /* disable GS, resulting in passthrough */
-   OUT_RING(BRW_CLIP_DISABLE);		     /* disable CLIP, resulting in passthrough */
-   OUT_RING(state_base_offset + sf_offset);  /* 32 byte aligned */
-   OUT_RING(state_base_offset + wm_offset);  /* 32 byte aligned */
-   OUT_RING(state_base_offset + cc_offset);  /* 64 byte aligned */
+   	OUT_RING(BRW_3DSTATE_PIPELINED_POINTERS | 5);
+   	OUT_RING(state_base_offset + vs_offset);  /* 32 byte aligned */
+   	OUT_RING(BRW_GS_DISABLE);		     /* disable GS, resulting in passthrough */
+   	OUT_RING(BRW_CLIP_DISABLE);		     /* disable CLIP, resulting in passthrough */
+   	OUT_RING(state_base_offset + sf_offset);  /* 32 byte aligned */
+   	OUT_RING(state_base_offset + wm_offset);  /* 32 byte aligned */
+   	OUT_RING(state_base_offset + cc_offset);  /* 64 byte aligned */
 
    /* URB fence */
-   // XXX: CS for const URB needed? if not, cs_fence should be equal to sf_fence
-   OUT_RING(BRW_URB_FENCE |
-	    UF0_CS_REALLOC |
-	    UF0_SF_REALLOC |
-	    UF0_CLIP_REALLOC |
-	    UF0_GS_REALLOC |
-	    UF0_VS_REALLOC |
-	    1);
-   OUT_RING(((urb_clip_start + urb_clip_size) << UF1_CLIP_FENCE_SHIFT) |
-	    ((urb_gs_start + urb_gs_size) << UF1_GS_FENCE_SHIFT) |
-	    ((urb_vs_start + urb_vs_size) << UF1_VS_FENCE_SHIFT));
-   OUT_RING(((urb_cs_start + urb_cs_size) << UF2_CS_FENCE_SHIFT) |
-	    ((urb_sf_start + urb_sf_size) << UF2_SF_FENCE_SHIFT));
+   	OUT_RING(BRW_URB_FENCE |
+        	 UF0_CS_REALLOC |
+	    	 UF0_SF_REALLOC |
+	    	 UF0_CLIP_REALLOC |
+	         UF0_GS_REALLOC |
+	         UF0_VS_REALLOC |
+	    	 1);
+   	OUT_RING(((urb_clip_start + urb_clip_size) << UF1_CLIP_FENCE_SHIFT) |
+	    	 ((urb_gs_start + urb_gs_size) << UF1_GS_FENCE_SHIFT) |
+	    	 ((urb_vs_start + urb_vs_size) << UF1_VS_FENCE_SHIFT));
+   	OUT_RING(((urb_cs_start + urb_cs_size) << UF2_CS_FENCE_SHIFT) |
+	     	 ((urb_sf_start + urb_sf_size) << UF2_SF_FENCE_SHIFT));
 
    /* Constant buffer state */
-   // XXX: needed? seems no usage, as we don't have CONSTANT_BUFFER definition
-   OUT_RING(BRW_CS_URB_STATE | 0);
-   OUT_RING(((URB_CS_ENTRY_SIZE - 1) << 4) | /* URB Entry Allocation Size */
-	    (URB_CS_ENTRIES << 0));	     /* Number of URB Entries */
-   
+   	OUT_RING(BRW_CS_URB_STATE | 0);
+   	OUT_RING(((URB_CS_ENTRY_SIZE - 1) << 4) | /* URB Entry Allocation Size */
+	    	 (URB_CS_ENTRIES << 0));	     /* Number of URB Entries */
+	ADVANCE_LP_RING();
+   }
+   {
+        int nelem = pMask ? 3: 2;
+   	BEGIN_LP_RING(pMask?12:10);
    /* Set up the pointer to our vertex buffer */
-   // XXX: double check
-  // int vb_pitch = 4 * 4;  // XXX: pitch should include mask's coords? possible
-  // all three coords on one row?
-   int nelem = pMask ? 3: 2;
-   OUT_RING(BRW_3DSTATE_VERTEX_BUFFERS | 3); //XXX: should be 4n-1 -> 3
-   OUT_RING((0 << VB0_BUFFER_INDEX_SHIFT) |
-	    VB0_VERTEXDATA |
-	    ((4 * 2 * nelem) << VB0_BUFFER_PITCH_SHIFT)); 
-   		// pitch includes all vertex data, 4bytes for 1 dword, each
-		// element has 2 coords (x,y)(s0,t0), nelem to reflect possible
-		// mask
-   OUT_RING(state_base_offset + vb_offset);
-   OUT_RING(4 * nelem); // max index, prim has 4 coords
-   OUT_RING(0); // ignore for VERTEXDATA, but still there
+   	OUT_RING(BRW_3DSTATE_VERTEX_BUFFERS | 3); 
+   	OUT_RING((0 << VB0_BUFFER_INDEX_SHIFT) |
+	    	 VB0_VERTEXDATA |
+	    	 ((4 * 2 * nelem) << VB0_BUFFER_PITCH_SHIFT)); 
+   	OUT_RING(state_base_offset + vb_offset);
+   	OUT_RING(2); // max index, prim has 4 coords
+   	OUT_RING(0); // ignore for VERTEXDATA, but still there
 
    /* Set up our vertex elements, sourced from the single vertex buffer. */
-   OUT_RING(BRW_3DSTATE_VERTEX_ELEMENTS | ((2 * nelem) - 1));  // XXX: 2n-1, (x,y) + (s0,t0) +
-						//   possible (s1, t1)
+   	OUT_RING(BRW_3DSTATE_VERTEX_ELEMENTS | ((2 * nelem) - 1));  
    /* offset 0: X,Y -> {X, Y, 1.0, 1.0} */
-   OUT_RING((0 << VE0_VERTEX_BUFFER_INDEX_SHIFT) |
-	    VE0_VALID |
-	    (BRW_SURFACEFORMAT_R32G32_FLOAT << VE0_FORMAT_SHIFT) |
-	    (0 << VE0_OFFSET_SHIFT));
-   OUT_RING((BRW_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT) |
-	    (BRW_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT) |
-	    (BRW_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_2_SHIFT) |
-	    (BRW_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_3_SHIFT) |
-	    (0 << VE1_DESTINATION_ELEMENT_OFFSET_SHIFT));
+   	OUT_RING((0 << VE0_VERTEX_BUFFER_INDEX_SHIFT) |
+	    	 VE0_VALID |
+	    	 (BRW_SURFACEFORMAT_R32G32_FLOAT << VE0_FORMAT_SHIFT) |
+	    	 (0 << VE0_OFFSET_SHIFT));
+   	OUT_RING((BRW_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT) |
+	    	 (BRW_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT) |
+	     	 (BRW_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_2_SHIFT) |
+	    	 (BRW_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_3_SHIFT) |
+	    	 (0 << VE1_DESTINATION_ELEMENT_OFFSET_SHIFT));
    /* offset 8: S0, T0 -> {S0, T0, 1.0, 1.0} */
-   OUT_RING((0 << VE0_VERTEX_BUFFER_INDEX_SHIFT) |
-	    VE0_VALID |
-	    (BRW_SURFACEFORMAT_R32G32_FLOAT << VE0_FORMAT_SHIFT) |
-	    (8 << VE0_OFFSET_SHIFT));
-   OUT_RING((BRW_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT) |
-	    (BRW_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT) |
-	    (BRW_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_2_SHIFT) |
-	    (BRW_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_3_SHIFT) |
-	    (4 << VE1_DESTINATION_ELEMENT_OFFSET_SHIFT));
-
-   if (pMask) {
    	OUT_RING((0 << VE0_VERTEX_BUFFER_INDEX_SHIFT) |
-	    VE0_VALID |
-	    (BRW_SURFACEFORMAT_R32G32_FLOAT << VE0_FORMAT_SHIFT) |
-	    (16 << VE0_OFFSET_SHIFT));
-	OUT_RING((BRW_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT) |
-	    (BRW_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT) |
-	    (BRW_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_2_SHIFT) |
-	    (BRW_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_3_SHIFT) |
-	    (8 << VE1_DESTINATION_ELEMENT_OFFSET_SHIFT)); 
-		//XXX: is this has alignment issue? and thread access problem?
-   }
+	    	 VE0_VALID |
+	    	 (BRW_SURFACEFORMAT_R32G32_FLOAT << VE0_FORMAT_SHIFT) |
+	    	 (8 << VE0_OFFSET_SHIFT));
+   	OUT_RING((BRW_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT) |
+	    	 (BRW_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT) |
+	    	 (BRW_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_2_SHIFT) |
+	     	 (BRW_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_3_SHIFT) |
+	    	 (4 << VE1_DESTINATION_ELEMENT_OFFSET_SHIFT));
+
+   	if (pMask) {
+   		OUT_RING((0 << VE0_VERTEX_BUFFER_INDEX_SHIFT) |
+	    		 VE0_VALID |
+	    		 (BRW_SURFACEFORMAT_R32G32_FLOAT << VE0_FORMAT_SHIFT) |
+	    		 (16 << VE0_OFFSET_SHIFT));
+		OUT_RING((BRW_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT) |
+	    		 (BRW_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT) |
+	    		 (BRW_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_2_SHIFT) |
+	    		 (BRW_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_3_SHIFT) |
+	    		 (8 << VE1_DESTINATION_ELEMENT_OFFSET_SHIFT)); 
+   	}
    
-   ADVANCE_LP_RING();
-    
+   	ADVANCE_LP_RING();
    }
 
 #ifdef I830DEBUG
@@ -983,7 +973,7 @@ I965EXAComposite(PixmapPtr pDst, int src
     I830Ptr pI830 = I830PTR(pScrn);
     int srcXend, srcYend, maskXend, maskYend;
     PictVector v;
-    int pMask = 1, i = 0;
+    int pMask = 1, i;
 
     DPRINTF(PFX, "Composite: srcX %d, srcY %d\n\t maskX %d, maskY %d\n\t"
 	    "dstX %d, dstY %d\n\twidth %d, height %d\n\t"
@@ -999,8 +989,10 @@ I965EXAComposite(PixmapPtr pDst, int src
 
     srcXend = srcX + w;
     srcYend = srcY + h;
-    maskXend = maskX + w;
-    maskYend = maskY + h;
+    if (pMask) {
+        maskXend = maskX + w;
+        maskYend = maskY + h;
+    }
     if (is_transform[0]) {
         v.vector[0] = IntToxFixed(srcX);
         v.vector[1] = IntToxFixed(srcY);
@@ -1035,51 +1027,45 @@ I965EXAComposite(PixmapPtr pDst, int src
 		"dstX %d, dstY %d\n", srcX, srcY, srcXend, srcYend,
 		maskX, maskY, maskXend, maskYend, dstX, dstY);
 
- 
-    vb[i++] = (float)dstX;
-    vb[i++] = (float)dstY;
-    vb[i++] = (float)srcX / scale_units[0][0];
-    vb[i++] = (float)srcY / scale_units[0][1];
-    if (pMask) {
-        vb[i++] = (float)maskX / scale_units[1][0];
-        vb[i++] = (float)maskY / scale_units[1][1];
-    }
-
-    vb[i++] = (float)dstX;
-    vb[i++] = (float)(dstY + h);
-    vb[i++] = (float)srcX / scale_units[0][0];
-    vb[i++] = (float)srcYend / scale_units[0][1];
+    i = 0;
+    /* rect (x2,y2) */
+    vb[i++] = (float)(srcXend) / scale_units[0][0];
+    vb[i++] = (float)(srcYend) / scale_units[0][1];
     if (pMask) {
-        vb[i++] = (float)maskX / scale_units[1][0];
+        vb[i++] = (float)maskXend / scale_units[1][0];
         vb[i++] = (float)maskYend / scale_units[1][1];
     }
-
     vb[i++] = (float)(dstX + w);
     vb[i++] = (float)(dstY + h);
-    vb[i++] = (float)srcXend / scale_units[0][0];
-    vb[i++] = (float)srcYend / scale_units[0][1];
+
+    /* rect (x1,y2) */
+    vb[i++] = (float)(srcX)/ scale_units[0][0];
+    vb[i++] = (float)(srcYend)/ scale_units[0][1];
     if (pMask) {
-        vb[i++] = (float)maskXend / scale_units[1][0];
+        vb[i++] = (float)maskX / scale_units[1][0];
         vb[i++] = (float)maskYend / scale_units[1][1];
     }
+    vb[i++] = (float)dstX;
+    vb[i++] = (float)(dstY + h);
 
-    vb[i++] = (float)(dstX + w);
-    vb[i++] = (float)dstY;
-    vb[i++] = (float)srcXend / scale_units[0][0];
-    vb[i++] = (float)srcY / scale_units[0][1];
+    /* rect (x1,y1) */
+    vb[i++] = (float)(srcX) / scale_units[0][0];
+    vb[i++] = (float)(srcY) / scale_units[0][1];
     if (pMask) {
-        vb[i++] = (float)maskXend / scale_units[1][0];
+        vb[i++] = (float)maskX / scale_units[1][0];
         vb[i++] = (float)maskY / scale_units[1][1];
     }
-
+    vb[i++] = (float)dstX;
+    vb[i++] = (float)dstY;
+   
     {
       BEGIN_LP_RING(6);
       OUT_RING(BRW_3DPRIMITIVE | 
 	       BRW_3DPRIMITIVE_VERTEX_SEQUENTIAL |
-	       (_3DPRIM_TRIFAN << BRW_3DPRIMITIVE_TOPOLOGY_SHIFT) | 
+	       (_3DPRIM_RECTLIST << BRW_3DPRIMITIVE_TOPOLOGY_SHIFT) | 
 	       (0 << 9) |  /* CTG - indirect vertex count */
 	       4);
-      OUT_RING(4);  /* vertex count per instance */
+      OUT_RING(3);  /* vertex count per instance */
       OUT_RING(0); /* start vertex offset */
       OUT_RING(1); /* single instance */
       OUT_RING(0); /* start instance location */
@@ -1090,4 +1076,19 @@ I965EXAComposite(PixmapPtr pDst, int src
     ErrorF("sync after 3dprimitive");
     I830Sync(pScrn);
 #endif
+    /* we must be sure that the pipeline is flushed before next exa draw,
+       because that will be new state, binding state and instructions*/
+    {
+	BEGIN_LP_RING(4);
+   	OUT_RING(BRW_PIPE_CONTROL |
+	    BRW_PIPE_CONTROL_NOWRITE |
+	    BRW_PIPE_CONTROL_WC_FLUSH |
+	    BRW_PIPE_CONTROL_IS_FLUSH |
+	    (1 << 10) |  /* XXX texture cache flush for BLC/CTG */
+	    2);
+   	OUT_RING(0); /* Destination address */
+   	OUT_RING(0); /* Immediate data low DW */
+   	OUT_RING(0); /* Immediate data high DW */
+	ADVANCE_LP_RING();
+    }
 }
diff-tree 18ad7d5cf04081d89a9f978ccc7794116f7c498b (from 3d5bd0c14eea7951540f7a12eee257428f78e2d1)
Author: Wang Zhenyu <zhenyu.z.wang at intel.com>
Date:   Wed Nov 29 16:04:16 2006 +0800

    remove wrong scale_units

diff --git a/src/i965_exa_render.c b/src/i965_exa_render.c
index 2751778..2c3e43b 100644
--- a/src/i965_exa_render.c
+++ b/src/i965_exa_render.c
@@ -397,8 +397,6 @@ ErrorF("i965 prepareComposite\n");
     }
     scale_units[0][0] = pSrc->drawable.width;
     scale_units[0][1] = pSrc->drawable.height;
-    scale_units[2][0] = pDst->drawable.width;
-    scale_units[2][1] = pDst->drawable.height;
 
     if (pSrcPicture->transform) {
 	is_transform[0] = TRUE;
diff-tree 3d5bd0c14eea7951540f7a12eee257428f78e2d1 (from a06beb5f80f097fac3b718e742742bb32f1c1194)
Author: Wang Zhenyu <zhenyu.z.wang at intel.com>
Date:   Wed Nov 29 16:02:16 2006 +0800

    Rename exa sf/wm program files
    
    Also fix some minors in wm program.

diff --git a/src/Makefile.am b/src/Makefile.am
index 494a921..890e90f 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -78,8 +78,8 @@ sf_prog.h: packed_yuv_sf.g4a
 	intel-gen4asm -o sf_prog.h packed_yuv_sf.g4a
 wm_prog.h: packed_yuv_wm.g4a
 	intel-gen4asm -o wm_prog.h packed_yuv_wm.g4a
-i965_composite_wm_nomask.h: i965_composite_wm_nomask.g4a
-	intel-gen4asm -o i965_composite_wm_nomask.h i965_composite_wm_nomask.g4a
+exa_wm_nomask_prog.h: exa_wm_nomask.g4a
+	intel-gen4asm -o exa_wm_nomask_prog.h exa_wm_nomask.g4a
 endif
 
 if DRI
diff --git a/src/exa_sf.g4a b/src/exa_sf.g4a
new file mode 100644
index 0000000..8c1398f
--- /dev/null
+++ b/src/exa_sf.g4a
@@ -0,0 +1,17 @@
+send (1) 0 g6<1>F g1.12<0,1,0>F math inv scalar mlen 1 rlen 1 { align1 };
+send (1) 0 g6.4<1>F g1.20<0,1,0>F math inv scalar mlen 1 rlen 1 { align1 };
+add (8) g7<1>F g4<8,8,1>F -g3<8,8,1>F { align1 };
+mul (1) g7<1>F g7<0,1,0>F g6<0,1,0>F { align1 };
+mul (1) g7.4<1>F g7.4<0,1,0>F g6.4<0,1,0>F { align1 };
+mov (8) m1<1>F g7<0,1,0>F { align1 };
+mov (8) m2<1>F g7.4<0,1,0>F { align1 };
+mov (8) m3<1>F g3<8,8,1>F { align1 };
+send (8) 0 null g0<8,8,1>F urb 0 transpose used complete mlen 4 rlen 0 { align1 EOT };
+nop;
+nop;
+nop;
+nop;
+nop;
+nop;
+nop;
+nop;
diff --git a/src/exa_sf_prog.h b/src/exa_sf_prog.h
new file mode 100644
index 0000000..830d176
--- /dev/null
+++ b/src/exa_sf_prog.h
@@ -0,0 +1,17 @@
+   { 0x00000031, 0x20c01fbd, 0x0000002c, 0x01110081 },
+   { 0x00000031, 0x20c41fbd, 0x00000034, 0x01110081 },
+   { 0x00600040, 0x20e077bd, 0x008d0080, 0x008d4060 },
+   { 0x00000041, 0x20e077bd, 0x000000e0, 0x000000c0 },
+   { 0x00000041, 0x20e477bd, 0x000000e4, 0x000000c4 },
+   { 0x00600001, 0x202003be, 0x000000e0, 0x00000000 },
+   { 0x00600001, 0x204003be, 0x000000e4, 0x00000000 },
+   { 0x00600001, 0x206003be, 0x008d0060, 0x00000000 },
+   { 0x00600031, 0x20001fbc, 0x008d0000, 0x8640c800 },
+   { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
+   { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
+   { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
+   { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
+   { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
+   { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
+   { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
+   { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
diff --git a/src/exa_wm_nomask.g4a b/src/exa_wm_nomask.g4a
new file mode 100644
index 0000000..8e851a3
--- /dev/null
+++ b/src/exa_wm_nomask.g4a
@@ -0,0 +1,143 @@
+/*
+ * This's for exa composite operation in no mask picture case.
+ * The simplest case is just sending what src picture has to dst picture.
+ */
+
+/* I think this should be same as in g4a program for texture video,
+   as we also use 16-pixel dispatch. and SF scale in g3 is useful for us. */
+
+/* The initial payload of the thread is always g0.
+ * WM_URB (incoming URB entries) is g3
+ * X0_R is g4
+ * X1_R is g5
+ * Y0_R is g6
+ * Y1_R is g7
+ */
+
+    /* Set up ss0.x coordinates*/
+mov (1) g4<1>F g1.8<0,1,0>UW { align1 };
+add (1) g4.4<1>F g1.8<0,1,0>UW 1UB { align1 };
+mov (1) g4.8<1>F g1.8<0,1,0>UW { align1 };
+add (1) g4.12<1>F g1.8<0,1,0>UW 1UB { align1 };
+    /* Set up ss0.y coordinates */
+mov (1) g6<1>F g1.10<0,1,0>UW { align1 };
+mov (1) g6.4<1>F g1.10<0,1,0>UW { align1 };
+add (1) g6.8<1>F g1.10<0,1,0>UW 1UB { align1 };
+add (1) g6.12<1>F g1.10<0,1,0>UW 1UB { align1 };
+    /* set up ss1.x coordinates */
+mov (1) g4.16<1>F g1.12<0,1,0>UW { align1 };
+add (1) g4.20<1>F g1.12<0,1,0>UW 1UB { align1 };
+mov (1) g4.24<1>F g1.12<0,1,0>UW { align1 };
+add (1) g4.28<1>F g1.12<0,1,0>UW 1UB { align1 };
+    /* set up ss1.y coordinates */
+mov (1) g6.16<1>F g1.14<0,1,0>UW { align1 };
+mov (1) g6.20<1>F g1.14<0,1,0>UW { align1 };
+add (1) g6.24<1>F g1.14<0,1,0>UW 1UB { align1 };
+add (1) g6.28<1>F g1.14<0,1,0>UW 1UB { align1 };
+    /* Set up ss2.x coordinates */
+mov (1) g5<1>F g1.16<0,1,0>UW { align1 };
+add (1) g5.4<1>F g1.16<0,1,0>UW 1UB { align1 };
+mov (1) g5.8<1>F g1.16<0,1,0>UW { align1 };
+add (1) g5.12<1>F g1.16<0,1,0>UW 1UB { align1 };
+    /* Set up ss2.y coordinates */
+mov (1) g7<1>F g1.18<0,1,0>UW { align1 };
+mov (1) g7.4<1>F g1.18<0,1,0>UW { align1 };
+add (1) g7.8<1>F g1.18<0,1,0>UW 1UB { align1 };
+add (1) g7.12<1>F g1.18<0,1,0>UW 1UB { align1 };
+    /* Set up ss3.x coordinates */
+mov (1) g5.16<1>F g1.20<0,1,0>UW { align1 };
+add (1) g5.20<1>F g1.20<0,1,0>UW 1UB { align1 };
+mov (1) g5.24<1>F g1.20<0,1,0>UW { align1 };
+add (1) g5.28<1>F g1.20<0,1,0>UW 1UB { align1 };
+    /* Set up ss3.y coordinates */
+mov (1) g7.16<1>F g1.22<0,1,0>UW { align1 };
+mov (1) g7.20<1>F g1.22<0,1,0>UW { align1 };
+add (1) g7.24<1>F g1.22<0,1,0>UW 1UB { align1 };
+add (1) g7.28<1>F g1.22<0,1,0>UW 1UB { align1 };
+
+    /* Now, map these screen space coordinates into texture coordinates. */
+    /* subtract screen-space X origin of vertex 0. */
+add (8) g4<1>F g4<8,8,1>F -g1<0,1,0>F { align1 };
+add (8) g5<1>F g5<8,8,1>F -g1<0,1,0>F { align1 };
+    /* scale by texture X increment */
+mul (8) g4<1>F g4<8,8,1>F g3<0,1,0>F { align1 };
+mul (8) g5<1>F g5<8,8,1>F g3<0,1,0>F { align1 };
+    /* add in texture X offset */
+add (8) g4<1>F g4<8,8,1>F g3.12<0,1,0>F { align1 };
+add (8) g5<1>F g5<8,8,1>F g3.12<0,1,0>F { align1 };
+    /* subtract screen-space Y origin of vertex 0. */
+add (8) g6<1>F g6<8,8,1>F -g1.4<0,1,0>F { align1 };
+add (8) g7<1>F g7<8,8,1>F -g1.4<0,1,0>F { align1 };
+    /* scale by texture Y increment */
+mul (8) g6<1>F g6<8,8,1>F g3.20<0,1,0>F { align1 };
+mul (8) g7<1>F g7<8,8,1>F g3.20<0,1,0>F { align1 };
+    /* add in texture Y offset */
+add (8) g6<1>F g6<8,8,1>F g3.28<0,1,0>F { align1 };
+add (8) g7<1>F g7<8,8,1>F g3.28<0,1,0>F { align1 };
+
+/* prepare sampler read back gX register, which would be written back to output */
+
+/* use simd16 sampler, param 0 is u, param 1 is v. */
+/* 'payload' loading, assuming tex coord start from g4 */
+mov (8) m1<1>F g4<8,8,1>F { align1 };
+mov (8) m2<1>F g5<8,8,1>F { align1 };  /* param 0 u in m1, m2 */
+mov (8) m3<1>F g6<8,8,1>F { align1 };
+mov (8) m4<1>F g7<8,8,1>F { align1 };  /* param 1 v in m3, m4 */
+
+/* m0 will be copied with g0, as it contains send desc */
+/* emit sampler 'send' cmd */
+send (16) 0 		/* msg reg index */
+	g12<1>UW 	/* readback */
+	g0<8,8,1>UW  	/* copy to msg start reg*/
+	sampler (1,0,F)  /* sampler message description, (binding_table,sampler_index,datatype)
+			 /* here(src->dst) we should use src_sampler and src_surface */
+	mlen 5 rlen 8 { align1 };   /* required message len 5, readback len 8 */
+
+mov (8) g19<1>UD g19<8,8,1>UD { align1 };  /* wait sampler return */
+/* if we set up read-back reg correctly, emit dataport write 'send' cmd with EOT */
+
+/* m0, m1 are all direct passed by PS thread payload */
+mov (8) m1<1>F g1<8,8,1>F { align1 };
+
+/* prepare data in m2-m5 for subspan(1,0), m6-m9 for subspan(3,2), then it's ready to write */
+/* g12 -> m2
+   g13 -> m6
+   g14 -> m3
+   g15 -> m7
+   g16 -> m4
+   g17 -> m8
+   g18 -> m5
+   g19 -> m9
+*/
+mov (8) m2<1>F g12<8,8,1>F { align1 };
+mov (8) m3<1>F g14<8,8,1>F { align1 };
+mov (8) m4<1>F g16<8,8,1>F { align1 };
+mov (8) m5<1>F g18<8,8,1>F { align1 };
+mov (8) m6<1>F g13<8,8,1>F { align1 };
+mov (8) m7<1>F g15<8,8,1>F { align1 };
+mov (8) m8<1>F g17<8,8,1>F { align1 };
+mov (8) m9<1>F g19<8,8,1>F { align1 };
+
+/* m0, m1 are all direct passed by PS thread payload */
+mov (8) m1<1>UD g1<8,8,1>UD { align1 mask_disable };
+
+/* write */
+send (16) 0 acc0<1>UW g0<8,8,1>UW write (
+	0,  /* binding_table */
+	8,  /* pixel scordboard clear, msg type simd16 single source */
+	4,  /* render target write */
+	0   /* no write commit message */
+	) 
+	mlen 10
+	rlen 0
+	{ align1 EOT };
+
+nop;
+nop;
+nop;
+nop;
+nop;
+nop;
+nop;
+nop;
+nop;
diff --git a/src/exa_wm_nomask_prog.h b/src/exa_wm_nomask_prog.h
new file mode 100644
index 0000000..7870b3b
--- /dev/null
+++ b/src/exa_wm_nomask_prog.h
@@ -0,0 +1,70 @@
+   { 0x00000001, 0x2080013d, 0x00000028, 0x00000000 },
+   { 0x00000040, 0x20840d3d, 0x00000028, 0x00000001 },
+   { 0x00000001, 0x2088013d, 0x00000028, 0x00000000 },
+   { 0x00000040, 0x208c0d3d, 0x00000028, 0x00000001 },
+   { 0x00000001, 0x20c0013d, 0x0000002a, 0x00000000 },
+   { 0x00000001, 0x20c4013d, 0x0000002a, 0x00000000 },
+   { 0x00000040, 0x20c80d3d, 0x0000002a, 0x00000001 },
+   { 0x00000040, 0x20cc0d3d, 0x0000002a, 0x00000001 },
+   { 0x00000001, 0x2090013d, 0x0000002c, 0x00000000 },
+   { 0x00000040, 0x20940d3d, 0x0000002c, 0x00000001 },
+   { 0x00000001, 0x2098013d, 0x0000002c, 0x00000000 },
+   { 0x00000040, 0x209c0d3d, 0x0000002c, 0x00000001 },
+   { 0x00000001, 0x20d0013d, 0x0000002e, 0x00000000 },
+   { 0x00000001, 0x20d4013d, 0x0000002e, 0x00000000 },
+   { 0x00000040, 0x20d80d3d, 0x0000002e, 0x00000001 },
+   { 0x00000040, 0x20dc0d3d, 0x0000002e, 0x00000001 },
+   { 0x00000001, 0x20a0013d, 0x00000030, 0x00000000 },
+   { 0x00000040, 0x20a40d3d, 0x00000030, 0x00000001 },
+   { 0x00000001, 0x20a8013d, 0x00000030, 0x00000000 },
+   { 0x00000040, 0x20ac0d3d, 0x00000030, 0x00000001 },
+   { 0x00000001, 0x20e0013d, 0x00000032, 0x00000000 },
+   { 0x00000001, 0x20e4013d, 0x00000032, 0x00000000 },
+   { 0x00000040, 0x20e80d3d, 0x00000032, 0x00000001 },
+   { 0x00000040, 0x20ec0d3d, 0x00000032, 0x00000001 },
+   { 0x00000001, 0x20b0013d, 0x00000034, 0x00000000 },
+   { 0x00000040, 0x20b40d3d, 0x00000034, 0x00000001 },
+   { 0x00000001, 0x20b8013d, 0x00000034, 0x00000000 },
+   { 0x00000040, 0x20bc0d3d, 0x00000034, 0x00000001 },
+   { 0x00000001, 0x20f0013d, 0x00000036, 0x00000000 },
+   { 0x00000001, 0x20f4013d, 0x00000036, 0x00000000 },
+   { 0x00000040, 0x20f80d3d, 0x00000036, 0x00000001 },
+   { 0x00000040, 0x20fc0d3d, 0x00000036, 0x00000001 },
+   { 0x00600040, 0x208077bd, 0x008d0080, 0x00004020 },
+   { 0x00600040, 0x20a077bd, 0x008d00a0, 0x00004020 },
+   { 0x00600041, 0x208077bd, 0x008d0080, 0x00000060 },
+   { 0x00600041, 0x20a077bd, 0x008d00a0, 0x00000060 },
+   { 0x00600040, 0x208077bd, 0x008d0080, 0x0000006c },
+   { 0x00600040, 0x20a077bd, 0x008d00a0, 0x0000006c },
+   { 0x00600040, 0x20c077bd, 0x008d00c0, 0x00004024 },
+   { 0x00600040, 0x20e077bd, 0x008d00e0, 0x00004024 },
+   { 0x00600041, 0x20c077bd, 0x008d00c0, 0x00000074 },
+   { 0x00600041, 0x20e077bd, 0x008d00e0, 0x00000074 },
+   { 0x00600040, 0x20c077bd, 0x008d00c0, 0x0000007c },
+   { 0x00600040, 0x20e077bd, 0x008d00e0, 0x0000007c },
+   { 0x00600001, 0x202003be, 0x008d0080, 0x00000000 },
+   { 0x00600001, 0x204003be, 0x008d00a0, 0x00000000 },
+   { 0x00600001, 0x206003be, 0x008d00c0, 0x00000000 },
+   { 0x00600001, 0x208003be, 0x008d00e0, 0x00000000 },
+   { 0x00800031, 0x21801d29, 0x008d0000, 0x02580001 },
+   { 0x00600001, 0x22600021, 0x008d0260, 0x00000000 },
+   { 0x00600001, 0x202003be, 0x008d0020, 0x00000000 },
+   { 0x00600001, 0x204003be, 0x008d0180, 0x00000000 },
+   { 0x00600001, 0x206003be, 0x008d01c0, 0x00000000 },
+   { 0x00600001, 0x208003be, 0x008d0200, 0x00000000 },
+   { 0x00600001, 0x20a003be, 0x008d0240, 0x00000000 },
+   { 0x00600001, 0x20c003be, 0x008d01a0, 0x00000000 },
+   { 0x00600001, 0x20e003be, 0x008d01e0, 0x00000000 },
+   { 0x00600001, 0x210003be, 0x008d0220, 0x00000000 },
+   { 0x00600001, 0x212003be, 0x008d0260, 0x00000000 },
+   { 0x00600201, 0x20200022, 0x008d0020, 0x00000000 },
+   { 0x00800031, 0x24001d28, 0x008d0000, 0x85a04800 },
+   { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
+   { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
+   { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
+   { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
+   { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
+   { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
+   { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
+   { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
+   { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
diff --git a/src/i965_composite_wm_nomask.g4a b/src/i965_composite_wm_nomask.g4a
deleted file mode 100644
index 927d86a..0000000
--- a/src/i965_composite_wm_nomask.g4a
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * This's for exa composite operation in no mask picture case.
- * The simplest case is just sending what src picture has to dst picture.
- * XXX: This is still experimental, and should be fixed to support multiple texture
- * map, and conditional mul actions. 
- */
-
-/* I think this should be same as in g4a program for texture video,
-   as we also use 16-pixel dispatch. and SF scale in g3 is useful for us. */
-
-/* The initial payload of the thread is always g0.
- * WM_URB (incoming URB entries) is g3
- * X0_R is g4
- * X1_R is g5
- * Y0_R is g6
- * Y1_R is g7
- */
-
-    /* Set up ss0.x coordinates*/
-mov (1) g4<1>F g1.8<0,1,0>UW { align1 };
-add (1) g4.4<1>F g1.8<0,1,0>UW 1UB { align1 };
-mov (1) g4.8<1>F g1.8<0,1,0>UW { align1 };
-add (1) g4.12<1>F g1.8<0,1,0>UW 1UB { align1 };
-    /* Set up ss0.y coordinates */
-mov (1) g6<1>F g1.10<0,1,0>UW { align1 };
-mov (1) g6.4<1>F g1.10<0,1,0>UW { align1 };
-add (1) g6.8<1>F g1.10<0,1,0>UW 1UB { align1 };
-add (1) g6.12<1>F g1.10<0,1,0>UW 1UB { align1 };
-    /* set up ss1.x coordinates */
-mov (1) g4.16<1>F g1.12<0,1,0>UW { align1 };
-add (1) g4.20<1>F g1.12<0,1,0>UW 1UB { align1 };
-mov (1) g4.24<1>F g1.12<0,1,0>UW { align1 };
-add (1) g4.28<1>F g1.12<0,1,0>UW 1UB { align1 };
-    /* set up ss1.y coordinates */
-mov (1) g6.16<1>F g1.14<0,1,0>UW { align1 };
-mov (1) g6.20<1>F g1.14<0,1,0>UW { align1 };
-add (1) g6.24<1>F g1.14<0,1,0>UW 1UB { align1 };
-add (1) g6.28<1>F g1.14<0,1,0>UW 1UB { align1 };
-    /* Set up ss2.x coordinates */
-mov (1) g5<1>F g1.16<0,1,0>UW { align1 };
-add (1) g5.4<1>F g1.16<0,1,0>UW 1UB { align1 };
-mov (1) g5.8<1>F g1.16<0,1,0>UW { align1 };
-add (1) g5.12<1>F g1.16<0,1,0>UW 1UB { align1 };
-    /* Set up ss2.y coordinates */
-mov (1) g7<1>F g1.18<0,1,0>UW { align1 };
-mov (1) g7.4<1>F g1.18<0,1,0>UW { align1 };
-add (1) g7.8<1>F g1.18<0,1,0>UW 1UB { align1 };
-add (1) g7.12<1>F g1.18<0,1,0>UW 1UB { align1 };
-    /* Set up ss3.x coordinates */
-mov (1) g5.16<1>F g1.20<0,1,0>UW { align1 };
-add (1) g5.20<1>F g1.20<0,1,0>UW 1UB { align1 };
-mov (1) g5.24<1>F g1.20<0,1,0>UW { align1 };
-add (1) g5.28<1>F g1.20<0,1,0>UW 1UB { align1 };
-    /* Set up ss3.y coordinates */
-mov (1) g7.16<1>F g1.22<0,1,0>UW { align1 };
-mov (1) g7.20<1>F g1.22<0,1,0>UW { align1 };
-add (1) g7.24<1>F g1.22<0,1,0>UW 1UB { align1 };
-add (1) g7.28<1>F g1.22<0,1,0>UW 1UB { align1 };
-
-    /* Now, map these screen space coordinates into texture coordinates. */
-    /* subtract screen-space X origin of vertex 0. */
-add (8) g4<1>F g4<8,8,1>F -g1<0,1,0>F { align1 };
-add (8) g5<1>F g5<8,8,1>F -g1<0,1,0>F { align1 };
-    /* scale by texture X increment */
-mul (8) g4<1>F g4<8,8,1>F g3<0,1,0>F { align1 };
-mul (8) g5<1>F g5<8,8,1>F g3<0,1,0>F { align1 };
-    /* add in texture X offset */
-add (8) g4<1>F g4<8,8,1>F g3.12<0,1,0>F { align1 };
-add (8) g5<1>F g5<8,8,1>F g3.12<0,1,0>F { align1 };
-    /* subtract screen-space Y origin of vertex 0. */
-add (8) g6<1>F g6<8,8,1>F -g1.4<0,1,0>F { align1 };
-add (8) g7<1>F g7<8,8,1>F -g1.4<0,1,0>F { align1 };
-    /* scale by texture Y increment */
-mul (8) g6<1>F g6<8,8,1>F g3.20<0,1,0>F { align1 };
-mul (8) g7<1>F g7<8,8,1>F g3.20<0,1,0>F { align1 };
-    /* add in texture Y offset */
-add (8) g6<1>F g6<8,8,1>F g3.28<0,1,0>F { align1 };
-add (8) g7<1>F g7<8,8,1>F g3.28<0,1,0>F { align1 };
-
-/* prepare sampler read back gX register, which would be written back to output */
-
-/* use simd16 sampler, param 0 is u, param 1 is v. */
-/* 'payload' loading, assuming tex coord start from g4 */
-mov (8) m1<1>F g4<8,8,1>F { align1 };
-mov (8) m2<1>F g5<8,8,1>F { align1 };  /* param 0 u in m1, m2 */
-mov (8) m3<1>F g6<8,8,1>F { align1 };
-mov (8) m4<1>F g7<8,8,1>F { align1 };  /* param 1 v in m3, m4 */
-
-/* m0 will be copied with g0, as it contains send desc */
-/* emit sampler 'send' cmd */
-send (16) 0 		/* msg reg index */
-	g12<1>UW 	/* readback */
-	g0<8,8,1>UW  	/* copy to msg start reg*/
-	sampler (1,0,F)  /* sampler message description, (binding_table,sampler_index,datatype)
-			 /* here(src->dst) we should use src_sampler and src_surface */
-	mlen 5 rlen 8 { align1 };   /* required message len 5, readback len 8 */
-
-/* if we set up read-back reg correctly, emit dataport write 'send' cmd with EOT */
-
-/* m0, m1 are all direct passed by PS thread payload */
-mov (8) m1<1>F g1<8,8,1>F { align1 };
-
-/* prepare data in m2-m5 for subspan(1,0), m6-m9 for subspan(3,2), then it's ready to write */
-/* g12 -> m2
-   g13 -> m6
-   g14 -> m3
-   g15 -> m7
-   g16 -> m4
-   g17 -> m8
-   g18 -> m5
-   g19 -> m9
-*/
-mov (8) m2<1>F g12<8,8,1>F { align1 };
-mov (8) m3<1>F g14<8,8,1>F { align1 };
-mov (8) m4<1>F g16<8,8,1>F { align1 };
-mov (8) m5<1>F g18<8,8,1>F { align1 };
-mov (8) m6<1>F g13<8,8,1>F { align1 };
-mov (8) m7<1>F g15<8,8,1>F { align1 };
-mov (8) m8<1>F g17<8,8,1>F { align1 };
-mov (8) m9<1>F g19<8,8,1>F { align1 };
-
-/* write */
-send (16) 0 null g0<8,8,1>UW write (
-	0,  /* binding_table */
-	8,  /* pixel scordboard clear, msg type simd16 single source */
-	4,  /* render target write */
-	0   /* no write commit message */
-	) 
-	mlen 10
-	rlen 0
-	{ align1 EOT };
-
-nop;
-nop;
-nop;
-nop;
-nop;
-nop;
-nop;
-nop;
-nop;
diff --git a/src/i965_composite_wm_nomask.h b/src/i965_composite_wm_nomask.h
deleted file mode 100644
index bd99dd9..0000000
--- a/src/i965_composite_wm_nomask.h
+++ /dev/null
@@ -1,68 +0,0 @@
-   { 0x00000001, 0x2080013d, 0x00000028, 0x00000000 },
-   { 0x00000040, 0x20840d3d, 0x00000028, 0x00000001 },
-   { 0x00000001, 0x2088013d, 0x00000028, 0x00000000 },
-   { 0x00000040, 0x208c0d3d, 0x00000028, 0x00000001 },
-   { 0x00000001, 0x20c0013d, 0x0000002a, 0x00000000 },
-   { 0x00000001, 0x20c4013d, 0x0000002a, 0x00000000 },
-   { 0x00000040, 0x20c80d3d, 0x0000002a, 0x00000001 },
-   { 0x00000040, 0x20cc0d3d, 0x0000002a, 0x00000001 },
-   { 0x00000001, 0x2090013d, 0x0000002c, 0x00000000 },
-   { 0x00000040, 0x20940d3d, 0x0000002c, 0x00000001 },
-   { 0x00000001, 0x2098013d, 0x0000002c, 0x00000000 },
-   { 0x00000040, 0x209c0d3d, 0x0000002c, 0x00000001 },
-   { 0x00000001, 0x20d0013d, 0x0000002e, 0x00000000 },
-   { 0x00000001, 0x20d4013d, 0x0000002e, 0x00000000 },
-   { 0x00000040, 0x20d80d3d, 0x0000002e, 0x00000001 },
-   { 0x00000040, 0x20dc0d3d, 0x0000002e, 0x00000001 },
-   { 0x00000001, 0x20a0013d, 0x00000030, 0x00000000 },
-   { 0x00000040, 0x20a40d3d, 0x00000030, 0x00000001 },
-   { 0x00000001, 0x20a8013d, 0x00000030, 0x00000000 },
-   { 0x00000040, 0x20ac0d3d, 0x00000030, 0x00000001 },
-   { 0x00000001, 0x20e0013d, 0x00000032, 0x00000000 },
-   { 0x00000001, 0x20e4013d, 0x00000032, 0x00000000 },
-   { 0x00000040, 0x20e80d3d, 0x00000032, 0x00000001 },
-   { 0x00000040, 0x20ec0d3d, 0x00000032, 0x00000001 },
-   { 0x00000001, 0x20b0013d, 0x00000034, 0x00000000 },
-   { 0x00000040, 0x20b40d3d, 0x00000034, 0x00000001 },
-   { 0x00000001, 0x20b8013d, 0x00000034, 0x00000000 },
-   { 0x00000040, 0x20bc0d3d, 0x00000034, 0x00000001 },
-   { 0x00000001, 0x20f0013d, 0x00000036, 0x00000000 },
-   { 0x00000001, 0x20f4013d, 0x00000036, 0x00000000 },
-   { 0x00000040, 0x20f80d3d, 0x00000036, 0x00000001 },
-   { 0x00000040, 0x20fc0d3d, 0x00000036, 0x00000001 },
-   { 0x00600040, 0x208077bd, 0x008d0080, 0x00004020 },
-   { 0x00600040, 0x20a077bd, 0x008d00a0, 0x00004020 },
-   { 0x00600041, 0x208077bd, 0x008d0080, 0x00000060 },
-   { 0x00600041, 0x20a077bd, 0x008d00a0, 0x00000060 },
-   { 0x00600040, 0x208077bd, 0x008d0080, 0x0000006c },
-   { 0x00600040, 0x20a077bd, 0x008d00a0, 0x0000006c },
-   { 0x00600040, 0x20c077bd, 0x008d00c0, 0x00004024 },
-   { 0x00600040, 0x20e077bd, 0x008d00e0, 0x00004024 },
-   { 0x00600041, 0x20c077bd, 0x008d00c0, 0x00000074 },
-   { 0x00600041, 0x20e077bd, 0x008d00e0, 0x00000074 },
-   { 0x00600040, 0x20c077bd, 0x008d00c0, 0x0000007c },
-   { 0x00600040, 0x20e077bd, 0x008d00e0, 0x0000007c },
-   { 0x00600001, 0x202003be, 0x008d0080, 0x00000000 },
-   { 0x00600001, 0x204003be, 0x008d00a0, 0x00000000 },
-   { 0x00600001, 0x206003be, 0x008d00c0, 0x00000000 },
-   { 0x00600001, 0x208003be, 0x008d00e0, 0x00000000 },
-   { 0x00800031, 0x21801d29, 0x008d0000, 0x02580001 },
-   { 0x00600001, 0x202003be, 0x008d0020, 0x00000000 },
-   { 0x00600001, 0x204003be, 0x008d0180, 0x00000000 },
-   { 0x00600001, 0x206003be, 0x008d01c0, 0x00000000 },
-   { 0x00600001, 0x208003be, 0x008d0200, 0x00000000 },
-   { 0x00600001, 0x20a003be, 0x008d0240, 0x00000000 },
-   { 0x00600001, 0x20c003be, 0x008d01a0, 0x00000000 },
-   { 0x00600001, 0x20e003be, 0x008d01e0, 0x00000000 },
-   { 0x00600001, 0x210003be, 0x008d0220, 0x00000000 },
-   { 0x00600001, 0x212003be, 0x008d0260, 0x00000000 },
-   { 0x00800031, 0x20001d3c, 0x008d0000, 0x85a04800 },
-   { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
-   { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
-   { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
-   { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
-   { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
-   { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
-   { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
-   { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
-   { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
diff --git a/src/i965_exa_render.c b/src/i965_exa_render.c
index fe3007b..2751778 100644
--- a/src/i965_exa_render.c
+++ b/src/i965_exa_render.c
@@ -342,7 +342,7 @@ static const CARD32 sip_kernel_static[][
 #define SF_MAX_THREADS	   4
 
 static const CARD32 sf_kernel_static[][4] = {
-#include "sf_prog.h"
+#include "exa_sf_prog.h"
 };
 
 /* ps kernels */
@@ -350,7 +350,7 @@ static const CARD32 sf_kernel_static[][4
 #define PS_MAX_THREADS	   32
 /* 1: no mask */
 static const CARD32 ps_kernel_static_nomask [][4] = {
-	#include "i965_composite_wm_nomask.h"
+	#include "exa_wm_nomask_prog.h"
 };
 
 /* 2: mask with componentAlpha, src * mask color, XXX: later */
diff-tree a06beb5f80f097fac3b718e742742bb32f1c1194 (from 4198f1216eb13b30d1e92d4395e98861f4324c38)
Author: Wang Zhenyu <zhenyu.z.wang at intel.com>
Date:   Wed Nov 29 15:47:19 2006 +0800

    EXA state mem for G965
    
    Not split offscreen mem for exa, but alloc a dedicated one
    for G965 states.

diff --git a/src/i830.h b/src/i830.h
index df1c171..2a68499 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -73,6 +73,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN
 #ifdef I830_USE_EXA
 #include "exa.h"
 Bool I830EXAInit(ScreenPtr pScreen);
+#define EXA_LINEAR_EXTRA	(64*1024)
 #endif
 
 #ifdef I830_USE_XAA
@@ -243,6 +244,7 @@ typedef struct _I830Rec {
    I830MemRange Scratch2;
 #ifdef I830_USE_EXA
    I830MemRange Offscreen;
+   I830MemRange EXAStateMem;  /* specific exa state for G965 */
 #endif
    /* Regions allocated either from the above pools, or from agpgart. */
    I830MemRange	*CursorMem;
diff --git a/src/i830_exa.c b/src/i830_exa.c
index 9b2e6b2..8b07ecb 100644
--- a/src/i830_exa.c
+++ b/src/i830_exa.c
@@ -424,7 +424,6 @@ IntelEXADoneComposite(PixmapPtr pDst)
 #endif
 }
 
-#define BRW_LINEAR_EXTRA (32*1024)
 /*
  * TODO:
  *   - Dual head?
@@ -447,11 +446,7 @@ I830EXAInit(ScreenPtr pScreen)
     pI830->EXADriverPtr->exa_minor = 0;
     pI830->EXADriverPtr->memoryBase = pI830->FbBase;
     pI830->EXADriverPtr->offScreenBase = pI830->Offscreen.Start;
-    if (IS_I965G(pI830))
-    	pI830->EXADriverPtr->memorySize = pI830->Offscreen.End -
-					BRW_LINEAR_EXTRA; /* BRW needs state buffer*/
-    else
-    	pI830->EXADriverPtr->memorySize = pI830->Offscreen.End;
+    pI830->EXADriverPtr->memorySize = pI830->Offscreen.End;
 	   
     DPRINTF(PFX, "EXA Mem: memoryBase 0x%x, end 0x%x, offscreen base 0x%x, memorySize 0x%x\n",
 		pI830->EXADriverPtr->memoryBase,
diff --git a/src/i830_memory.c b/src/i830_memory.c
index e3307d6..4a8d480 100644
--- a/src/i830_memory.c
+++ b/src/i830_memory.c
@@ -905,6 +905,25 @@ I830Allocate2DMemory(ScrnInfoPtr pScrn, 
 		       "offscreen memory at 0x%lx, size %ld KB\n", 
 			pI830->Offscreen.Start, pI830->Offscreen.Size/1024);
       }
+      if (IS_I965G(pI830)) {
+          memset(&(pI830->EXAStateMem), 0, sizeof(I830MemRange));
+          pI830->EXAStateMem.Key = -1;
+          size = ROUND_TO_PAGE(EXA_LINEAR_EXTRA);
+          align = GTT_PAGE_SIZE;
+          alloced = I830AllocVidMem(pScrn, &(pI830->EXAStateMem),
+				&(pI830->StolenPool), size, align,
+				flags | FROM_ANYWHERE | ALLOCATE_AT_TOP);
+          if (alloced < size) {
+             if (!dryrun) {
+         	 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+		    "G965: Failed to allocate exa state buffer space.\n");
+             }
+             return FALSE;
+          }
+          xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
+ 		  "%sAllocated %ld kB for the G965 exa state buffer at 0x%lx - 0x%lx.\n", s, 
+ 		alloced / 1024, pI830->EXAStateMem.Start, pI830->EXAStateMem.End);
+      }
 #endif
    } else {
       long lineSize;
@@ -1545,6 +1564,11 @@ I830FixupOffsets(ScrnInfoPtr pScrn)
       I830FixOffset(pScrn, &(pI830->TexMem));
    }
 #endif
+#ifdef I830_USE_EXA
+   I830FixOffset(pScrn, &(pI830->Offscreen));
+   if (IS_I965G(pI830))
+       I830FixOffset(pScrn, &(pI830->EXAStateMem));
+#endif
    return TRUE;
 }
 
@@ -1945,6 +1969,12 @@ I830BindAGPMemory(ScrnInfoPtr pScrn)
 	    return FALSE;
       }
 #endif
+#ifdef I830_USE_EXA
+     if (!BindMemRange(pScrn, &(pI830->Offscreen)))
+	return FALSE;
+     if (IS_I965G(pI830) && !BindMemRange(pScrn, &(pI830->EXAStateMem)))
+	return FALSE;
+#endif
       pI830->GttBound = 1;
    }
 
@@ -2029,6 +2059,12 @@ I830UnbindAGPMemory(ScrnInfoPtr pScrn)
 	    return FALSE;
       }
 #endif
+#ifdef I830_USE_EXA
+     if (!UnbindMemRange(pScrn, &(pI830->Offscreen)))
+	return FALSE;
+     if (IS_I965G(pI830) && !UnbindMemRange(pScrn, &(pI830->EXAStateMem)))
+	return FALSE;
+#endif
       if (!xf86ReleaseGART(pScrn->scrnIndex))
 	 return FALSE;
 
diff --git a/src/i965_exa_render.c b/src/i965_exa_render.c
index 7fbf99c..fe3007b 100644
--- a/src/i965_exa_render.c
+++ b/src/i965_exa_render.c
@@ -490,21 +490,12 @@ ErrorF("i965 prepareComposite\n");
    next_offset = binding_table_offset + (binding_table_entries * 4);
 
    total_state_size = next_offset;
+   assert(total_state_size < EXA_LINEAR_EXTRA);
 
-   /*
-    * XXX: Use the extra space allocated at the end of the exa offscreen buffer?
-    */
-#define BRW_LINEAR_EXTRA	(32*1024)
-
-   state_base_offset = (pI830->Offscreen.End -
-			BRW_LINEAR_EXTRA);
-   
+   state_base_offset = pI830->EXAStateMem.Start;
    state_base_offset = ALIGN(state_base_offset, 64);
    state_base = (char *)(pI830->FbBase + state_base_offset);
-   /* Set up our pointers to state structures in framebuffer.  It would probably
-    * be a good idea to fill these structures out in system memory and then dump
-    * them there, instead.
-    */
+
    vs_state = (void *)(state_base + vs_offset);
    sf_state = (void *)(state_base + sf_offset);
    wm_state = (void *)(state_base + wm_offset);
diff-tree 08b6569dc663ddf38cb36a6875de6d4ab55acac9 (from 05202cabbd23f15330b811ae6b8d708ad042bc40)
Author: Eric Anholt <eric at anholt.net>
Date:   Sun Nov 19 16:15:45 2006 -0800

    Enable TV output on Crestline (untested).

diff --git a/src/i830_driver.c b/src/i830_driver.c
index f61e0f0..441eba4 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -670,7 +670,7 @@ I830SetupOutputs(ScrnInfoPtr pScrn)
       i830_dvo_init(pScrn);
    }
 #if 1
-   if (IS_I915GM(pI830) || IS_I945GM(pI830))
+   if (IS_I915GM(pI830) || IS_I945GM(pI830) || IS_I965G(pI830))
       i830_tv_init(pScrn);
 #endif
 }
diff-tree 05202cabbd23f15330b811ae6b8d708ad042bc40 (from parents)
Merge: ee502dd92a3dfccdc2efcfb76fc652694bc89e3b b945a650e952f98c2d101b71bd3ec0f390478da5
Author: Eric Anholt <eric at anholt.net>
Date:   Sun Nov 19 16:14:18 2006 -0800

    Merge branch 'modesetting-origin' into crestline

diff-tree ee502dd92a3dfccdc2efcfb76fc652694bc89e3b (from parents)
Merge: 15ff17c756e42f392306820e3f7ffbdcc56b9892 2fe6107ac68e86ed183d8602436633348340678d
Author: Eric Anholt <eric at anholt.net>
Date:   Fri Nov 17 14:57:41 2006 -0800

    Merge branch 'crestline-origin' into crestline

diff-tree 15ff17c756e42f392306820e3f7ffbdcc56b9892 (from parents)
Merge: 9cc2f3313d77487dea372e6ab32d6d9c06617ae3 816fc1a76a5ac738e41b172ba8f43137c1521328
Author: Eric Anholt <eric at anholt.net>
Date:   Fri Nov 17 11:48:53 2006 -0800

    Merge branch 'modesetting' into crestline
    
    This works for analog, but SDVO output appears to not work yet.
    
    Conflicts:
    
    	src/i830_driver.c

diff-tree 2fe6107ac68e86ed183d8602436633348340678d (from 9cc2f3313d77487dea372e6ab32d6d9c06617ae3)
Author: Wang Zhenyu <zhenyu.z.wang at intel.com>
Date:   Fri Nov 17 13:11:36 2006 +0800

    Rotation support for 965GM

diff --git a/src/i830.h b/src/i830.h
index 0df41e3..5c7a488 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -277,6 +277,7 @@ typedef struct _I830Rec {
    XF86ModReqInfo shadowReq; /* to test for later libshadow */
    I830MemRange RotatedMem;
    I830MemRange RotatedMem2;
+   I830MemRange RotateStateMem; /* for G965 state buffer */
    Rotation rotation;
    int InitialRotation;
    int displayWidth;
diff --git a/src/i830_driver.c b/src/i830_driver.c
index 287217a..ef05dd0 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -7219,6 +7219,10 @@ I830BIOSScreenInit(int scrnIndex, Screen
       /* Rotated2 Buffer */
       memset(&(pI830->RotatedMem2), 0, sizeof(pI830->RotatedMem2));
       pI830->RotatedMem2.Key = -1;
+      if (IS_I965G(pI830)) {
+          memset(&(pI830->RotateStateMem), 0, sizeof(pI830->RotateStateMem));
+          pI830->RotateStateMem.Key = -1;
+      }
    }
 
 #ifdef HAS_MTRR_SUPPORT
@@ -7636,11 +7640,7 @@ I830BIOSScreenInit(int scrnIndex, Screen
       xf86DisableRandR(); /* Disable built-in RandR extension */
       shadowSetup(pScreen);
       /* support all rotations */
-      if (IS_I965G(pI830)) {
-	 I830RandRInit(pScreen, RR_Rotate_0); /* only 0 degrees for I965G */
-      } else {
-	 I830RandRInit(pScreen, RR_Rotate_0 | RR_Rotate_90 | RR_Rotate_180 | RR_Rotate_270);
-      }
+      I830RandRInit(pScreen, RR_Rotate_0 | RR_Rotate_90 | RR_Rotate_180 | RR_Rotate_270);
       pI830->PointerMoved = pScrn->PointerMoved;
       pScrn->PointerMoved = I830PointerMoved;
       pI830->CreateScreenResources = pScreen->CreateScreenResources;
@@ -8428,8 +8428,7 @@ I830BIOSSwitchMode(int scrnIndex, Displa
     * The extra WindowTable check detects a rotation at startup.
     */
    if ( (!WindowTable[pScrn->scrnIndex] || pspix->devPrivate.ptr == NULL) &&
-         !pI830->DGAactive && (pScrn->PointerMoved == I830PointerMoved) &&
-	 !IS_I965G(pI830)) {
+         !pI830->DGAactive && (pScrn->PointerMoved == I830PointerMoved)) {
       if (!I830Rotate(pScrn, mode))
          ret = FALSE;
    }
diff --git a/src/i830_memory.c b/src/i830_memory.c
index 09ef5be..96d6efc 100644
--- a/src/i830_memory.c
+++ b/src/i830_memory.c
@@ -526,6 +526,28 @@ I830AllocateRotatedBuffer(ScrnInfoPtr pS
    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
 		  "%sAllocated %ld kB for the rotated buffer at 0x%lx.\n", s,
 		  alloced / 1024, pI830->RotatedMem.Start);
+
+#define BRW_LINEAR_EXTRA (32*1024)
+   if (IS_I965G(pI830)) {
+       memset(&(pI830->RotateStateMem), 0, sizeof(I830MemRange));
+       pI830->RotateStateMem.Key = -1;
+       size = ROUND_TO_PAGE(BRW_LINEAR_EXTRA);
+       align = GTT_PAGE_SIZE;
+       alloced = I830AllocVidMem(pScrn, &(pI830->RotateStateMem),
+				&(pI830->StolenPool), size, align,
+				flags | FROM_ANYWHERE | ALLOCATE_AT_TOP);
+       if (alloced < size) {
+          if (!dryrun) {
+	     xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+		    "G965: Failed to allocate rotate state buffer space.\n");
+          }
+          return FALSE;
+       }
+       xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
+		  "%sAllocated %ld kB for the G965 rotate state buffer at 0x%lx - 0x%lx.\n", s, 
+		alloced / 1024, pI830->RotateStateMem.Start, pI830->RotateStateMem.End);
+   }
+  
    return TRUE;
 }
 
@@ -1753,8 +1775,13 @@ I830SetupMemoryTiling(ScrnInfoPtr pScrn)
    int i;
 
    /* Clear out */
-   for (i = 0; i < 8; i++)
-      pI830->ModeReg.Fence[i] = 0;
+   if (IS_I965G(pI830)) {
+      for (i = 0; i < FENCE_NEW_NR*2; i++)
+	 pI830->ModeReg.Fence[i] = 0;
+   } else {
+      for (i = 0; i < 8; i++)
+         pI830->ModeReg.Fence[i] = 0;
+   }
 
    nextTile = 0;
    tileGeneration = -1;
@@ -1824,6 +1851,9 @@ I830SetupMemoryTiling(ScrnInfoPtr pScrn)
       }
    }
 	
+/* XXX tiled rotate mem not ready on G965*/
+ 
+  if(!IS_I965G(pI830)) {
    if (pI830->RotatedMem.Alignment >= KB(512)) {
       if (MakeTiles(pScrn, &(pI830->RotatedMem), FENCE_XMAJOR)) {
 	 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
@@ -1834,7 +1864,7 @@ I830SetupMemoryTiling(ScrnInfoPtr pScrn)
 		    "MakeTiles failed for the rotated buffer.\n");
       }
    }
-
+  }
 #if 0
    if (pI830->RotatedMem2.Alignment >= KB(512)) {
       if (MakeTiles(pScrn, &(pI830->RotatedMem2), FENCE_XMAJOR)) {
diff --git a/src/i830_rotate.c b/src/i830_rotate.c
index 0471b55..ba41c0c 100644
--- a/src/i830_rotate.c
+++ b/src/i830_rotate.c
@@ -60,6 +60,8 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN
 #include "i830.h"
 #include "i915_reg.h"
 #include "i915_3d.h"
+#include "brw_defines.h"
+#include "brw_structs.h"
 
 #ifdef XF86DRI
 #include "dri.h"
@@ -194,6 +196,718 @@ static void draw_poly(CARD32 *vb,
    }
 }
 
+
+/* Our PS kernel uses less than 32 GRF registers (about 20) */
+#define PS_KERNEL_NUM_GRF   32
+#define PS_MAX_THREADS	   32
+
+#define BRW_GRF_BLOCKS(nreg)	((nreg + 15) / 16 - 1)
+
+static const CARD32 ps_kernel_static0[][4] = {
+#include "rotation_wm_prog0.h"
+};
+
+static const CARD32 ps_kernel_static90[][4] = {
+#include "rotation_wm_prog90.h"
+};
+
+#define ALIGN(i,m)    (((i) + (m) - 1) & ~((m) - 1))
+#define MIN(a,b) ((a) < (b) ? (a) : (b))
+#define BRW_LINEAR_EXTRA (32*1024)
+#define WM_BINDING_TABLE_ENTRIES    2
+
+static const CARD32 sip_kernel_static[][4] = {
+/*    wait (1) a0<1>UW a145<0,1,0>UW { align1 +  } */
+    { 0x00000030, 0x20000108, 0x00001220, 0x00000000 },
+/*    nop (4) g0<1>UD { align1 +  } */
+    { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
+/*    nop (4) g0<1>UD { align1 +  } */
+    { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
+/*    nop (4) g0<1>UD { align1 +  } */
+    { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
+/*    nop (4) g0<1>UD { align1 +  } */
+    { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
+/*    nop (4) g0<1>UD { align1 +  } */
+    { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
+/*    nop (4) g0<1>UD { align1 +  } */
+    { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
+/*    nop (4) g0<1>UD { align1 +  } */
+    { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
+/*    nop (4) g0<1>UD { align1 +  } */
+    { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
+/*    nop (4) g0<1>UD { align1 +  } */
+    { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
+};
+  
+#define SF_KERNEL_NUM_GRF  16
+#define SF_MAX_THREADS	   1
+
+static const CARD32 sf_kernel_static0[][4] = {
+#include "rotation_sf_prog0.h"
+};
+
+
+static const CARD32 sf_kernel_static90[][4] = {
+#include "rotation_sf_prog90.h"
+};
+
+static void
+I965UpdateRotate (ScreenPtr      pScreen,
+                 shadowBufPtr   pBuf)
+{
+   ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+   I830Ptr pI830 = I830PTR(pScrn);
+   ScrnInfoPtr pScrn1 = pScrn;
+   I830Ptr pI8301 = NULL;
+   RegionPtr	damage = shadowDamage(pBuf);
+   int		nbox = REGION_NUM_RECTS (damage);
+   BoxPtr	pbox = REGION_RECTS (damage);
+   int		box_x1, box_x2, box_y1, box_y2;
+   float verts[4][2];
+   struct matrix23 rotMatrix;
+   Bool updateInvarient = FALSE;
+#ifdef XF86DRI
+   drmI830Sarea *sarea = NULL;
+   drm_context_t myContext = 0;
+#endif
+   Bool didLock = FALSE;
+
+/* Gen4 states */
+   int urb_vs_start, urb_vs_size;
+   int urb_gs_start, urb_gs_size;
+   int urb_clip_start, urb_clip_size;
+   int urb_sf_start, urb_sf_size;
+   int urb_cs_start, urb_cs_size;
+   struct brw_surface_state *dest_surf_state;
+   struct brw_surface_state *src_surf_state;
+   struct brw_sampler_state *src_sampler_state;
+   struct brw_vs_unit_state *vs_state;
+   struct brw_sf_unit_state *sf_state;
+   struct brw_wm_unit_state *wm_state;
+   struct brw_cc_unit_state *cc_state;
+   struct brw_cc_viewport *cc_viewport;
+   struct brw_instruction *sf_kernel;
+   struct brw_instruction *ps_kernel;
+   struct brw_instruction *sip_kernel;
+   float *vb;  
+   BOOL first_output = TRUE;
+   CARD32 *binding_table;
+   int dest_surf_offset, src_surf_offset, src_sampler_offset, vs_offset;
+   int sf_offset, wm_offset, cc_offset, vb_offset, cc_viewport_offset;
+   int wm_scratch_offset;
+   int sf_kernel_offset, ps_kernel_offset, sip_kernel_offset;
+   int binding_table_offset;
+   int next_offset, total_state_size;
+   int vb_size = (4 * 4) * 4; /* 4 DWORDS per vertex */
+   char *state_base;
+   int state_base_offset;
+
+   DPRINTF(PFX, "I965UpdateRotate: from (%d x %d) -> (%d x %d)\n",	
+		pScrn->virtualX, pScrn->virtualY, pScreen->width, pScreen->height);
+
+   if (I830IsPrimary(pScrn)) {
+      pI8301 = pI830;
+   } else {
+      pI8301 = I830PTR(pI830->entityPrivate->pScrn_1);
+      pScrn1 = pI830->entityPrivate->pScrn_1;
+   }
+
+   switch (pI830->rotation) {
+      case RR_Rotate_90:
+         matrix23Rotate(&rotMatrix,
+                     pScreen->width, pScreen->height,
+                     90);
+	 break;
+      case RR_Rotate_180:
+         matrix23Rotate(&rotMatrix,
+                     pScreen->width, pScreen->height,
+                     180);
+	 break;
+      case RR_Rotate_270:
+         matrix23Rotate(&rotMatrix,
+                     pScreen->width, pScreen->height,
+                     270);
+	 break;
+      default:
+	 break;
+   }
+
+#ifdef XF86DRI
+   if (pI8301->directRenderingEnabled) {
+      sarea = DRIGetSAREAPrivate(pScrn1->pScreen);
+      myContext = DRIGetContext(pScrn1->pScreen);
+      didLock = I830DRILock(pScrn1);
+   }
+#endif
+
+   if (pScrn->scrnIndex != *pI830->used3D) 
+      updateInvarient = TRUE;
+ 
+#ifdef XF86DRI
+   if (sarea && sarea->ctxOwner != myContext)
+      updateInvarient = TRUE;
+#endif
+
+   /*XXX we'll always update state */
+   *pI830->used3D = pScrn->scrnIndex;
+#ifdef XF86DRI
+   if (sarea)
+      sarea->ctxOwner = myContext;
+#endif
+
+   /* this starts initialize 3D engine for rotation mapping*/
+   next_offset = 0;
+
+   /* Set up our layout of state in framebuffer.  First the general state: */
+   vs_offset = ALIGN(next_offset, 64);
+   next_offset = vs_offset + sizeof(*vs_state);
+   sf_offset = ALIGN(next_offset, 32);
+   next_offset = sf_offset + sizeof(*sf_state);
+   wm_offset = ALIGN(next_offset, 32);
+   next_offset = wm_offset + sizeof(*wm_state);
+   wm_scratch_offset = ALIGN(next_offset, 1024);
+   next_offset = wm_scratch_offset + 1024 * PS_MAX_THREADS;
+   cc_offset = ALIGN(next_offset, 32);
+   next_offset = cc_offset + sizeof(*cc_state);
+
+   sf_kernel_offset = ALIGN(next_offset, 64);
+      
+   switch (pI830->rotation) {
+       case RR_Rotate_90:
+       case RR_Rotate_270:
+      	    next_offset = sf_kernel_offset + sizeof (sf_kernel_static90);
+      	    ps_kernel_offset = ALIGN(next_offset, 64);
+      	    next_offset = ps_kernel_offset + sizeof (ps_kernel_static90);
+	    break;
+       case RR_Rotate_180:
+       default:
+      	    next_offset = sf_kernel_offset + sizeof (sf_kernel_static0);
+      	    ps_kernel_offset = ALIGN(next_offset, 64);
+      	    next_offset = ps_kernel_offset + sizeof (ps_kernel_static0);
+	    break;
+   }
+
+   sip_kernel_offset = ALIGN(next_offset, 64);
+   next_offset = sip_kernel_offset + sizeof (sip_kernel_static);
+   cc_viewport_offset = ALIGN(next_offset, 32);
+   next_offset = cc_viewport_offset + sizeof(*cc_viewport);
+
+   src_sampler_offset = ALIGN(next_offset, 32);
+   next_offset = src_sampler_offset + sizeof(*src_sampler_state);
+
+   /* Align VB to native size of elements, for safety */
+   vb_offset = ALIGN(next_offset, 8);
+   next_offset = vb_offset + vb_size;
+
+   dest_surf_offset = ALIGN(next_offset, 32);
+   next_offset = dest_surf_offset + sizeof(*dest_surf_state);
+   src_surf_offset = ALIGN(next_offset, 32);
+   next_offset = src_surf_offset + sizeof(*src_surf_state);
+   binding_table_offset = ALIGN(next_offset, 32);
+   next_offset = binding_table_offset + (WM_BINDING_TABLE_ENTRIES * 4);
+
+   total_state_size = next_offset;
+   assert (total_state_size < BRW_LINEAR_EXTRA);
+
+   state_base_offset = pI830->RotateStateMem.Start;
+   state_base_offset = ALIGN(state_base_offset, 64);
+   state_base = (char *)(pI830->FbBase + state_base_offset);
+   DPRINTF(PFX, "rotate state buffer start 0x%x, addr 0x%x, base 0x%x\n",
+			pI830->RotateStateMem.Start, state_base, pI830->FbBase);
+
+   vs_state = (void *)(state_base + vs_offset);
+   sf_state = (void *)(state_base + sf_offset);
+   wm_state = (void *)(state_base + wm_offset);
+   cc_state = (void *)(state_base + cc_offset);
+   sf_kernel = (void *)(state_base + sf_kernel_offset);
+   ps_kernel = (void *)(state_base + ps_kernel_offset);
+   sip_kernel = (void *)(state_base + sip_kernel_offset);
+   
+   cc_viewport = (void *)(state_base + cc_viewport_offset);
+   dest_surf_state = (void *)(state_base + dest_surf_offset);
+   src_surf_state = (void *)(state_base + src_surf_offset);
+   src_sampler_state = (void *)(state_base + src_sampler_offset);
+   binding_table = (void *)(state_base + binding_table_offset);
+   vb = (void *)(state_base + vb_offset);
+
+   /* For 3D, the VS must have 8, 12, 16, 24, or 32 VUEs allocated to it.
+    * A VUE consists of a 256-bit vertex header followed by the vertex data,
+    * which in our case is 4 floats (128 bits), thus a single 512-bit URB
+    * entry.
+    */
+#define URB_VS_ENTRIES	      8
+#define URB_VS_ENTRY_SIZE     1
+   
+#define URB_GS_ENTRIES	      0
+#define URB_GS_ENTRY_SIZE     0
+   
+#define URB_CLIP_ENTRIES      0
+#define URB_CLIP_ENTRY_SIZE   0
+   
+   /* The SF kernel we use outputs only 4 256-bit registers, leading to an
+    * entry size of 2 512-bit URBs.  We don't need to have many entries to
+    * output as we're generally working on large rectangles and don't care
+    * about having WM threads running on different rectangles simultaneously.
+    */
+#define URB_SF_ENTRIES	      1
+#define URB_SF_ENTRY_SIZE     2
+
+#define URB_CS_ENTRIES	      0
+#define URB_CS_ENTRY_SIZE     0
+   
+   urb_vs_start = 0;
+   urb_vs_size = URB_VS_ENTRIES * URB_VS_ENTRY_SIZE;
+   urb_gs_start = urb_vs_start + urb_vs_size;
+   urb_gs_size = URB_GS_ENTRIES * URB_GS_ENTRY_SIZE;
+   urb_clip_start = urb_gs_start + urb_gs_size;
+   urb_clip_size = URB_CLIP_ENTRIES * URB_CLIP_ENTRY_SIZE;
+   urb_sf_start = urb_clip_start + urb_clip_size;
+   urb_sf_size = URB_SF_ENTRIES * URB_SF_ENTRY_SIZE;
+   urb_cs_start = urb_sf_start + urb_sf_size;
+   urb_cs_size = URB_CS_ENTRIES * URB_CS_ENTRY_SIZE;
+
+   memset (cc_viewport, 0, sizeof (*cc_viewport));
+   cc_viewport->min_depth = -1.e35;
+   cc_viewport->max_depth = 1.e35;
+
+   memset(cc_state, 0, sizeof(*cc_state));
+   cc_state->cc0.stencil_enable = 0;   /* disable stencil */
+   cc_state->cc2.depth_test = 0;       /* disable depth test */
+   cc_state->cc2.logicop_enable = 1;   /* enable logic op */
+   cc_state->cc3.ia_blend_enable = 1;  /* blend alpha just like colors */
+   cc_state->cc3.blend_enable = 0;     /* disable color blend */
+   cc_state->cc3.alpha_test = 0;       /* disable alpha test */
+   cc_state->cc4.cc_viewport_state_offset = (state_base_offset + cc_viewport_offset) >> 5;
+   cc_state->cc5.dither_enable = 0;    /* disable dither */
+   cc_state->cc5.logicop_func = 0xc;   /* COPY S*/
+   cc_state->cc5.statistics_enable = 1;
+   cc_state->cc5.ia_blend_function = BRW_BLENDFUNCTION_ADD;
+   cc_state->cc5.ia_src_blend_factor = BRW_BLENDFACTOR_ONE;
+   cc_state->cc5.ia_dest_blend_factor = BRW_BLENDFACTOR_ZERO;
+
+   /* Upload system kernel */
+   memcpy (sip_kernel, sip_kernel_static, sizeof (sip_kernel_static));
+   
+   memset(dest_surf_state, 0, sizeof(*dest_surf_state));
+   dest_surf_state->ss0.surface_type = BRW_SURFACE_2D;
+   dest_surf_state->ss0.data_return_format = BRW_SURFACERETURNFORMAT_FLOAT32;
+   if (pI8301->cpp == 2)
+      dest_surf_state->ss0.surface_format = BRW_SURFACEFORMAT_B5G6R5_UNORM;
+   else
+      dest_surf_state->ss0.surface_format = BRW_SURFACEFORMAT_B8G8R8A8_UNORM;
+   dest_surf_state->ss0.writedisable_alpha = 0;
+   dest_surf_state->ss0.writedisable_red = 0;
+   dest_surf_state->ss0.writedisable_green = 0;
+   dest_surf_state->ss0.writedisable_blue = 0;
+   dest_surf_state->ss0.color_blend = 0;
+   dest_surf_state->ss0.vert_line_stride = 0;
+   dest_surf_state->ss0.vert_line_stride_ofs = 0;
+   dest_surf_state->ss0.mipmap_layout_mode = 0;
+   dest_surf_state->ss0.render_cache_read_mode = 0;
+   
+   if (I830IsPrimary(pScrn))
+      dest_surf_state->ss1.base_addr = pI830->FrontBuffer.Start;
+   else 
+      dest_surf_state->ss1.base_addr = pI8301->FrontBuffer2.Start;
+   dest_surf_state->ss2.width = pScrn->virtualX - 1;
+   dest_surf_state->ss2.height = pScrn->virtualY - 1; 
+   dest_surf_state->ss2.mip_count = 0;
+   dest_surf_state->ss2.render_target_rotation = 0; /*XXX how to use? */
+   dest_surf_state->ss3.pitch = (pI830->displayWidth * pI830->cpp) - 1;
+   if (pI830->front_tiled) {
+      dest_surf_state->ss3.tiled_surface = 1;
+      dest_surf_state->ss3.tile_walk = 0; /* X major */
+   }
+
+   memset(src_surf_state, 0, sizeof(*src_surf_state));
+   src_surf_state->ss0.surface_type = BRW_SURFACE_2D;
+/* src_surf_state->ss0.data_return_format = BRW_SURFACERETURNFORMAT_FLOAT32;*/
+   if (pI8301->cpp == 2) 
+      src_surf_state->ss0.surface_format = BRW_SURFACEFORMAT_B5G6R5_UNORM;
+   else 
+      src_surf_state->ss0.surface_format = BRW_SURFACEFORMAT_B8G8R8A8_UNORM;
+   src_surf_state->ss0.writedisable_alpha = 0;
+   src_surf_state->ss0.writedisable_red = 0;
+   src_surf_state->ss0.writedisable_green = 0;
+   src_surf_state->ss0.writedisable_blue = 0;
+   src_surf_state->ss0.color_blend = 0;
+   src_surf_state->ss0.vert_line_stride = 0;
+   src_surf_state->ss0.vert_line_stride_ofs = 0;
+   src_surf_state->ss0.mipmap_layout_mode = 0;
+   src_surf_state->ss0.render_cache_read_mode = 0;
+  
+   if (I830IsPrimary(pScrn)) 
+      src_surf_state->ss1.base_addr = pI830->RotatedMem.Start;
+   else 
+      src_surf_state->ss1.base_addr = pI8301->RotatedMem2.Start;
+   src_surf_state->ss2.width = pScreen->width - 1;
+   src_surf_state->ss2.height = pScreen->height - 1;
+   src_surf_state->ss2.mip_count = 0;
+   src_surf_state->ss2.render_target_rotation = 0;
+   src_surf_state->ss3.pitch = (pScrn->displayWidth * pI830->cpp) - 1;
+   if (pI830->rotated_tiled) {
+      src_surf_state->ss3.tiled_surface = 1;
+      src_surf_state->ss3.tile_walk = 0; /* X major */
+   }
+
+   binding_table[0] = state_base_offset + dest_surf_offset;
+   binding_table[1] = state_base_offset + src_surf_offset;
+
+   memset(src_sampler_state, 0, sizeof(*src_sampler_state));
+   src_sampler_state->ss0.min_filter = BRW_MAPFILTER_LINEAR;
+   src_sampler_state->ss0.mag_filter = BRW_MAPFILTER_LINEAR;
+   src_sampler_state->ss1.r_wrap_mode = BRW_TEXCOORDMODE_CLAMP;
+   src_sampler_state->ss1.s_wrap_mode = BRW_TEXCOORDMODE_CLAMP;
+   src_sampler_state->ss1.t_wrap_mode = BRW_TEXCOORDMODE_CLAMP;
+
+   /* Set up the vertex shader to be disabled (passthrough) */
+   memset(vs_state, 0, sizeof(*vs_state));
+   vs_state->thread4.nr_urb_entries = URB_VS_ENTRIES;
+   vs_state->thread4.urb_entry_allocation_size = URB_VS_ENTRY_SIZE - 1;
+   vs_state->vs6.vs_enable = 0;
+   vs_state->vs6.vert_cache_disable = 1;
+
+   /* Set up the SF kernel to do coord interp: for each attribute,
+    * calculate dA/dx and dA/dy.  Hand these interpolation coefficients
+    * back to SF which then hands pixels off to WM.
+    */
+
+   switch (pI830->rotation) {
+      case RR_Rotate_90:
+      case RR_Rotate_270:
+           memcpy (sf_kernel, sf_kernel_static90, sizeof (sf_kernel_static90));
+           memcpy (ps_kernel, ps_kernel_static90, sizeof (ps_kernel_static90));
+	   break;
+      case RR_Rotate_180:
+      default:
+           memcpy (sf_kernel, sf_kernel_static0, sizeof (sf_kernel_static0));
+           memcpy (ps_kernel, ps_kernel_static0, sizeof (ps_kernel_static0));
+	   break;
+   }
+
+   memset(sf_state, 0, sizeof(*sf_state));
+   sf_state->thread0.kernel_start_pointer = 
+	          (state_base_offset + sf_kernel_offset) >> 6;
+   sf_state->thread0.grf_reg_count = BRW_GRF_BLOCKS(SF_KERNEL_NUM_GRF);
+   sf_state->sf1.single_program_flow = 1; /* XXX */
+   sf_state->sf1.binding_table_entry_count = 0;
+   sf_state->sf1.thread_priority = 0;
+   sf_state->sf1.floating_point_mode = 0; 
+   sf_state->sf1.illegal_op_exception_enable = 1;
+   sf_state->sf1.mask_stack_exception_enable = 1;
+   sf_state->sf1.sw_exception_enable = 1;
+   sf_state->thread2.per_thread_scratch_space = 0;
+   sf_state->thread2.scratch_space_base_pointer = 0; /* not used in our kernel */
+   sf_state->thread3.const_urb_entry_read_length = 0; /* no const URBs */
+   sf_state->thread3.const_urb_entry_read_offset = 0; /* no const URBs */
+   sf_state->thread3.urb_entry_read_length = 1; /* 1 URB per vertex */
+   sf_state->thread3.urb_entry_read_offset = 0;
+   sf_state->thread3.dispatch_grf_start_reg = 3;
+   sf_state->thread4.max_threads = SF_MAX_THREADS - 1;
+   sf_state->thread4.urb_entry_allocation_size = URB_SF_ENTRY_SIZE - 1;
+   sf_state->thread4.nr_urb_entries = URB_SF_ENTRIES;
+   sf_state->thread4.stats_enable = 1;
+   sf_state->sf5.viewport_transform = FALSE; /* skip viewport */
+   sf_state->sf6.cull_mode = BRW_CULLMODE_NONE;
+   sf_state->sf6.scissor = 0;
+   sf_state->sf7.trifan_pv = 2;
+   sf_state->sf6.dest_org_vbias = 0x8;
+   sf_state->sf6.dest_org_hbias = 0x8;
+
+   memset (wm_state, 0, sizeof (*wm_state));
+   wm_state->thread0.kernel_start_pointer = 
+	       (state_base_offset + ps_kernel_offset) >> 6;
+   wm_state->thread0.grf_reg_count = BRW_GRF_BLOCKS(PS_KERNEL_NUM_GRF);
+   wm_state->thread1.single_program_flow = 1; /* XXX */
+   wm_state->thread1.binding_table_entry_count = 2;
+   /* Though we never use the scratch space in our WM kernel, it has to be
+    * set, and the minimum allocation is 1024 bytes.
+    */
+   wm_state->thread2.scratch_space_base_pointer = (state_base_offset +
+						   wm_scratch_offset) >> 10;
+   wm_state->thread2.per_thread_scratch_space = 0; /* 1024 bytes */
+   wm_state->thread3.dispatch_grf_start_reg = 3;
+   wm_state->thread3.const_urb_entry_read_length = 0;
+   wm_state->thread3.const_urb_entry_read_offset = 0;
+   wm_state->thread3.urb_entry_read_length = 1;
+   wm_state->thread3.urb_entry_read_offset = 0;
+   wm_state->wm4.stats_enable = 1;
+   wm_state->wm4.sampler_state_pointer = (state_base_offset + src_sampler_offset) >> 5;
+   wm_state->wm4.sampler_count = 1; /* 1-4 samplers used */
+   wm_state->wm5.max_threads = PS_MAX_THREADS - 1;
+   wm_state->wm5.thread_dispatch_enable = 1;
+   wm_state->wm5.enable_16_pix = 1;
+   wm_state->wm5.enable_8_pix = 0;
+   wm_state->wm5.early_depth_test = 1;
+
+   
+   {
+         BEGIN_LP_RING(2);
+         OUT_RING(MI_FLUSH | 
+	          MI_STATE_INSTRUCTION_CACHE_FLUSH |
+	          BRW_MI_GLOBAL_SNAPSHOT_RESET);
+         OUT_RING(MI_NOOP);
+         ADVANCE_LP_RING();
+    }
+
+    {
+         BEGIN_LP_RING(12);
+         OUT_RING(BRW_PIPELINE_SELECT | PIPELINE_SELECT_3D);
+
+   /* Mesa does this. Who knows... */
+         OUT_RING(BRW_CS_URB_STATE | 0);
+         OUT_RING((0 << 4) |	/* URB Entry Allocation Size */
+	          (0 << 0));	/* Number of URB Entries */
+   
+   /* Zero out the two base address registers so all offsets are absolute */
+         OUT_RING(BRW_STATE_BASE_ADDRESS | 4);
+         OUT_RING(0 | BASE_ADDRESS_MODIFY);  /* Generate state base address */
+         OUT_RING(0 | BASE_ADDRESS_MODIFY);  /* Surface state base address */
+         OUT_RING(0 | BASE_ADDRESS_MODIFY);  /* media base addr, don't care */
+         OUT_RING(0x10000000 | BASE_ADDRESS_MODIFY);  /* general state max addr, disabled */
+         OUT_RING(0x10000000 | BASE_ADDRESS_MODIFY);  /* media object state max addr, disabled */
+
+   /* Set system instruction pointer */
+         OUT_RING(BRW_STATE_SIP | 0);
+         OUT_RING(state_base_offset + sip_kernel_offset); /* system instruction pointer */
+      
+         OUT_RING(MI_NOOP);
+         ADVANCE_LP_RING(); 
+    }
+   
+
+    { 
+         BEGIN_LP_RING(36);
+   /* Enable VF statistics */
+         OUT_RING(BRW_3DSTATE_VF_STATISTICS | 1);
+   
+   /* Pipe control */
+         OUT_RING(BRW_PIPE_CONTROL |
+	          BRW_PIPE_CONTROL_NOWRITE |
+	          BRW_PIPE_CONTROL_IS_FLUSH |
+	          2);
+         OUT_RING(0);			       /* Destination address */
+         OUT_RING(0);			       /* Immediate data low DW */
+         OUT_RING(0);			       /* Immediate data high DW */
+
+   /* Binding table pointers */
+         OUT_RING(BRW_3DSTATE_BINDING_TABLE_POINTERS | 4);
+         OUT_RING(0); /* vs */
+         OUT_RING(0); /* gs */
+         OUT_RING(0); /* clip */
+         OUT_RING(0); /* sf */
+   /* Only the PS uses the binding table */
+         OUT_RING(state_base_offset + binding_table_offset); /* ps */
+   
+   /* XXX: Blend constant color (magenta is fun) */
+         //OUT_RING(BRW_3DSTATE_CONSTANT_COLOR | 3);
+         //OUT_RING(float_to_uint (1.0));
+         //OUT_RING(float_to_uint (0.0));
+         //OUT_RING(float_to_uint (1.0));
+         //OUT_RING(float_to_uint (1.0));
+   
+   /* The drawing rectangle clipping is always on.  Set it to values that
+    * shouldn't do any clipping.
+    */
+         OUT_RING(BRW_3DSTATE_DRAWING_RECTANGLE | 2);	/* XXX 3 for BLC or CTG */
+         OUT_RING(0x00000000);	/* ymin, xmin */
+         OUT_RING((pScrn->virtualX - 1) |
+	          (pScrn->virtualY - 1) << 16); /* ymax, xmax */
+         OUT_RING(0x00000000);	/* yorigin, xorigin */
+
+   /* skip the depth buffer */
+   /* skip the polygon stipple */
+   /* skip the polygon stipple offset */
+   /* skip the line stipple */
+   
+   /* Set the pointers to the 3d pipeline state */
+         OUT_RING(BRW_3DSTATE_PIPELINED_POINTERS | 5);
+         OUT_RING(state_base_offset + vs_offset);  /* 32 byte aligned */
+         OUT_RING(BRW_GS_DISABLE);		     /* disable GS, resulting in passthrough */
+         OUT_RING(BRW_CLIP_DISABLE);		     /* disable CLIP, resulting in passthrough */
+         OUT_RING(state_base_offset + sf_offset);  /* 32 byte aligned */
+         OUT_RING(state_base_offset + wm_offset);  /* 32 byte aligned */
+         OUT_RING(state_base_offset + cc_offset);  /* 64 byte aligned */
+
+   /* URB fence */
+         OUT_RING(BRW_URB_FENCE |
+	          UF0_CS_REALLOC |
+	          UF0_SF_REALLOC |
+	          UF0_CLIP_REALLOC |
+	          UF0_GS_REALLOC |
+	          UF0_VS_REALLOC |
+	    	  1);
+         OUT_RING(((urb_clip_start + urb_clip_size) << UF1_CLIP_FENCE_SHIFT) |
+	          ((urb_gs_start + urb_gs_size) << UF1_GS_FENCE_SHIFT) |
+	          ((urb_vs_start + urb_vs_size) << UF1_VS_FENCE_SHIFT));
+         OUT_RING(((urb_cs_start + urb_cs_size) << UF2_CS_FENCE_SHIFT) |
+	          ((urb_sf_start + urb_sf_size) << UF2_SF_FENCE_SHIFT));
+
+   /* Constant buffer state */
+         OUT_RING(BRW_CS_URB_STATE | 0);
+         OUT_RING(((URB_CS_ENTRY_SIZE - 1) << 4) | /* URB Entry Allocation Size */
+	          (URB_CS_ENTRIES << 0));	     /* Number of URB Entries */
+   
+   /* Set up the pointer to our vertex buffer */
+         OUT_RING(BRW_3DSTATE_VERTEX_BUFFERS | 2);
+         OUT_RING((0 << VB0_BUFFER_INDEX_SHIFT) |
+	          VB0_VERTEXDATA |
+	          ((4 * 4) << VB0_BUFFER_PITCH_SHIFT)); /* four 32-bit floats per vertex */
+         OUT_RING(state_base_offset + vb_offset);
+         OUT_RING(3); /* four corners to our rectangle */
+
+   /* Set up our vertex elements, sourced from the single vertex buffer. */
+         OUT_RING(BRW_3DSTATE_VERTEX_ELEMENTS | 3);
+   /* offset 0: X,Y -> {X, Y, 1.0, 1.0} */
+         OUT_RING((0 << VE0_VERTEX_BUFFER_INDEX_SHIFT) |
+	          VE0_VALID |
+	          (BRW_SURFACEFORMAT_R32G32_FLOAT << VE0_FORMAT_SHIFT) |
+	          (0 << VE0_OFFSET_SHIFT));
+         OUT_RING((BRW_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT) |
+	          (BRW_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT) |
+	          (BRW_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_2_SHIFT) |
+	          (BRW_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_3_SHIFT) |
+	          (0 << VE1_DESTINATION_ELEMENT_OFFSET_SHIFT));
+   /* offset 8: S0, T0 -> {S0, T0, 1.0, 1.0} */
+         OUT_RING((0 << VE0_VERTEX_BUFFER_INDEX_SHIFT) |
+	          VE0_VALID |
+	          (BRW_SURFACEFORMAT_R32G32_FLOAT << VE0_FORMAT_SHIFT) |
+	          (8 << VE0_OFFSET_SHIFT));
+         OUT_RING((BRW_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT) |
+	          (BRW_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT) |
+	          (BRW_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_2_SHIFT) |
+	          (BRW_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_3_SHIFT) |
+	          (4 << VE1_DESTINATION_ELEMENT_OFFSET_SHIFT));
+
+         //OUT_RING(MI_NOOP);			/* pad to quadword */
+         ADVANCE_LP_RING(); 
+   }
+
+   {
+      BEGIN_LP_RING(2);
+      OUT_RING(MI_FLUSH | 
+	       MI_STATE_INSTRUCTION_CACHE_FLUSH |
+	       BRW_MI_GLOBAL_SNAPSHOT_RESET);
+      OUT_RING(MI_NOOP);
+      ADVANCE_LP_RING();
+   }
+
+   while (nbox--)
+   {
+      float src_scale_x, src_scale_y;
+      int i;
+      box_x1 = pbox->x1;
+      box_y1 = pbox->y1;
+      box_x2 = pbox->x2;
+      box_y2 = pbox->y2;
+
+      if (!first_output) {
+	 /* Since we use the same little vertex buffer over and over, sync for
+	  * subsequent rectangles.
+	  */
+	 if (pI830->AccelInfoRec && pI830->AccelInfoRec->NeedToSync) {
+	    (*pI830->AccelInfoRec->Sync)(pScrn);
+	    pI830->AccelInfoRec->NeedToSync = FALSE;
+	 }
+      }
+
+      pbox++;
+
+      verts[0][0] = box_x1; verts[0][1] = box_y1;
+      verts[1][0] = box_x2; verts[1][1] = box_y1;
+      verts[2][0] = box_x2; verts[2][1] = box_y2;
+      verts[3][0] = box_x1; verts[3][1] = box_y2;
+
+      /* transform coordinates to rotated versions, but leave texcoords unchanged */
+      for (i = 0; i < 4; i++)
+         matrix23TransformCoordf(&rotMatrix, &verts[i][0], &verts[i][1]);
+
+      src_scale_x = (float)1.0 / (float)pScreen->width;
+      src_scale_y = (float)1.0 / (float)pScreen->height;
+      i = 0;
+
+      DPRINTF(PFX, "box size (%d, %d) -> (%d, %d)\n", 
+			box_x1, box_y1, box_x2, box_y2);
+
+      switch (pI830->rotation) {
+         case RR_Rotate_90:
+      	    vb[i++] = (float)box_x1 * src_scale_x;
+      	    vb[i++] = (float)box_y2 * src_scale_y;
+      	    vb[i++] = verts[3][0];
+      	    vb[i++] = verts[3][1];
+
+      	    vb[i++] = (float)box_x1 * src_scale_x;
+      	    vb[i++] = (float)box_y1 * src_scale_y;
+      	    vb[i++] = verts[0][0];
+      	    vb[i++] = verts[0][1];
+
+      	    vb[i++] = (float)box_x2 * src_scale_x;
+      	    vb[i++] = (float)box_y1 * src_scale_y;
+      	    vb[i++] = verts[1][0];
+      	    vb[i++] = verts[1][1];
+	    break;
+         case RR_Rotate_270:
+      	    vb[i++] = (float)box_x2 * src_scale_x;
+      	    vb[i++] = (float)box_y1 * src_scale_y;
+      	    vb[i++] = verts[1][0];
+      	    vb[i++] = verts[1][1];
+
+      	    vb[i++] = (float)box_x2 * src_scale_x;
+      	    vb[i++] = (float)box_y2 * src_scale_y;
+      	    vb[i++] = verts[2][0];
+      	    vb[i++] = verts[2][1];
+
+      	    vb[i++] = (float)box_x1 * src_scale_x;
+      	    vb[i++] = (float)box_y2 * src_scale_y;
+      	    vb[i++] = verts[3][0];
+      	    vb[i++] = verts[3][1];
+	    break;
+	 case RR_Rotate_180:
+       	 default:
+      	    vb[i++] = (float)box_x1 * src_scale_x;
+      	    vb[i++] = (float)box_y1 * src_scale_y;
+      	    vb[i++] = verts[0][0];
+      	    vb[i++] = verts[0][1];
+
+            vb[i++] = (float)box_x2 * src_scale_x;
+      	    vb[i++] = (float)box_y1 * src_scale_y;
+      	    vb[i++] = verts[1][0];
+      	    vb[i++] = verts[1][1];
+
+      	    vb[i++] = (float)box_x2 * src_scale_x;
+      	    vb[i++] = (float)box_y2 * src_scale_y;
+      	    vb[i++] = verts[2][0];
+      	    vb[i++] = verts[2][1];
+	    break;
+      }
+
+      BEGIN_LP_RING(6);
+      OUT_RING(BRW_3DPRIMITIVE | 
+	       BRW_3DPRIMITIVE_VERTEX_SEQUENTIAL |
+	       (_3DPRIM_RECTLIST << BRW_3DPRIMITIVE_TOPOLOGY_SHIFT) | 
+	       (0 << 9) |  /* CTG - indirect vertex count */
+	       4);
+      OUT_RING(3); /* vertex count per instance */
+      OUT_RING(0); /* start vertex offset */
+      OUT_RING(1); /* single instance */
+      OUT_RING(0); /* start instance location */
+      OUT_RING(0); /* index buffer offset, ignored */
+      ADVANCE_LP_RING();
+
+      first_output = FALSE;
+      if (pI830->AccelInfoRec)
+	 pI830->AccelInfoRec->NeedToSync = TRUE;
+   }
+
+   if (pI830->AccelInfoRec)
+      (*pI830->AccelInfoRec->Sync)(pScrn);
+#ifdef XF86DRI
+   if (didLock)
+      I830DRIUnlock(pScrn1);
+#endif
+}
+
+
 static void
 I915UpdateRotate (ScreenPtr      pScreen,
                  shadowBufPtr   pBuf)
@@ -737,11 +1451,15 @@ I830Rotate(ScrnInfoPtr pScrn, DisplayMod
 
    if (pI830->noAccel)
       func = LoaderSymbol("shadowUpdateRotatePacked");
-   else
-      if (IS_I9XX(pI830))
-	 func = I915UpdateRotate;
-      else
+   else {
+      if (IS_I9XX(pI830)) {
+	 if (IS_I965G(pI830))
+	     func = I965UpdateRotate;
+	 else 
+	     func = I915UpdateRotate;
+      } else
 	 func = I830UpdateRotate;
+   }
 
    if (I830IsPrimary(pScrn)) {
       pI8301 = pI830;
@@ -818,6 +1536,15 @@ I830Rotate(ScrnInfoPtr pScrn, DisplayMod
       memset(&(pI8301->RotatedMem), 0, sizeof(pI8301->RotatedMem));
       pI8301->RotatedMem.Key = -1;
 
+      if (IS_I965G(pI8301)) {
+         if (pI8301->RotateStateMem.Key != -1)
+            xf86UnbindGARTMemory(pScrn1->scrnIndex, pI8301->RotateStateMem.Key);
+ 
+         I830FreeVidMem(pScrn1, &(pI8301->RotateStateMem));
+         memset(&(pI8301->RotateStateMem), 0, sizeof(pI8301->RotateStateMem));
+      	 pI8301->RotateStateMem.Key = -1;
+      }
+
       if (pI830->entityPrivate) {
          if (pI8301->RotatedMem2.Key != -1)
             xf86UnbindGARTMemory(pScrn1->scrnIndex, pI8301->RotatedMem2.Key);
@@ -900,6 +1627,12 @@ I830Rotate(ScrnInfoPtr pScrn, DisplayMod
          I830FixOffset(pScrn1, &(pI8301->RotatedMem));
          if (pI8301->RotatedMem.Key != -1)
             xf86BindGARTMemory(pScrn1->scrnIndex, pI8301->RotatedMem.Key, pI8301->RotatedMem.Offset);
+	 if (IS_I965G(pI8301)) {
+            I830FixOffset(pScrn1, &(pI8301->RotateStateMem));
+            if (pI8301->RotateStateMem.Key != -1)
+            	xf86BindGARTMemory(pScrn1->scrnIndex, pI8301->RotateStateMem.Key, 
+				   pI8301->RotateStateMem.Offset);
+	 }
       }
    }
    
@@ -967,8 +1700,16 @@ I830Rotate(ScrnInfoPtr pScrn, DisplayMod
       }
       I830SetupMemoryTiling(pScrn1);
       /* update fence registers */
-      for (i = 0; i < 8; i++) 
-         OUTREG(FENCE + i * 4, pI8301->ModeReg.Fence[i]);
+      if (IS_I965G(pI830)) {
+         for (i = 0; i < FENCE_NEW_NR; i++) {
+            OUTREG(FENCE_NEW + i * 8, pI830->ModeReg.Fence[i]);
+            OUTREG(FENCE_NEW + 4 + i * 8, pI830->ModeReg.Fence[i+FENCE_NEW_NR]);
+         }
+      } else {
+         for (i = 0; i < 8; i++) 
+            OUTREG(FENCE + i * 4, pI8301->ModeReg.Fence[i]);
+      }
+
       {
          drmI830Sarea *sarea = DRIGetSAREAPrivate(pScrn1->pScreen);
          I830UpdateDRIBuffers(pScrn1, sarea );
diff --git a/src/rotation_sf0.g4a b/src/rotation_sf0.g4a
new file mode 100644
index 0000000..8c1398f
--- /dev/null
+++ b/src/rotation_sf0.g4a
@@ -0,0 +1,17 @@
+send (1) 0 g6<1>F g1.12<0,1,0>F math inv scalar mlen 1 rlen 1 { align1 };
+send (1) 0 g6.4<1>F g1.20<0,1,0>F math inv scalar mlen 1 rlen 1 { align1 };
+add (8) g7<1>F g4<8,8,1>F -g3<8,8,1>F { align1 };
+mul (1) g7<1>F g7<0,1,0>F g6<0,1,0>F { align1 };
+mul (1) g7.4<1>F g7.4<0,1,0>F g6.4<0,1,0>F { align1 };
+mov (8) m1<1>F g7<0,1,0>F { align1 };
+mov (8) m2<1>F g7.4<0,1,0>F { align1 };
+mov (8) m3<1>F g3<8,8,1>F { align1 };
+send (8) 0 null g0<8,8,1>F urb 0 transpose used complete mlen 4 rlen 0 { align1 EOT };
+nop;
+nop;
+nop;
+nop;
+nop;
+nop;
+nop;
+nop;
diff --git a/src/rotation_sf90.g4a b/src/rotation_sf90.g4a
new file mode 100644
index 0000000..2648dff
--- /dev/null
+++ b/src/rotation_sf90.g4a
@@ -0,0 +1,17 @@
+send (1) 0 g6<1>F g1.20<0,1,0>F math inv scalar mlen 1 rlen 1 { align1 };
+send (1) 0 g6.4<1>F g1.12<0,1,0>F math inv scalar mlen 1 rlen 1 { align1 };
+add (8) g7<1>F g4<8,8,1>F -g3<8,8,1>F { align1 };
+mul (1) g7<1>F g7<0,1,0>F g6<0,1,0>F { align1 };
+mul (1) g7.4<1>F g7.4<0,1,0>F g6.4<0,1,0>F { align1 };
+mov (8) m1<1>F g7<0,1,0>F { align1 };
+mov (8) m2<1>F g7.4<0,1,0>F { align1 };
+mov (8) m3<1>F g3<8,8,1>F { align1 };
+send (8) 0 null g0<8,8,1>F urb 0 transpose used complete mlen 4 rlen 0 { align1 EOT };
+nop;
+nop;
+nop;
+nop;
+nop;
+nop;
+nop;
+nop;
diff --git a/src/rotation_sf_prog0.h b/src/rotation_sf_prog0.h
new file mode 100644
index 0000000..830d176
--- /dev/null
+++ b/src/rotation_sf_prog0.h
@@ -0,0 +1,17 @@
+   { 0x00000031, 0x20c01fbd, 0x0000002c, 0x01110081 },
+   { 0x00000031, 0x20c41fbd, 0x00000034, 0x01110081 },
+   { 0x00600040, 0x20e077bd, 0x008d0080, 0x008d4060 },
+   { 0x00000041, 0x20e077bd, 0x000000e0, 0x000000c0 },
+   { 0x00000041, 0x20e477bd, 0x000000e4, 0x000000c4 },
+   { 0x00600001, 0x202003be, 0x000000e0, 0x00000000 },
+   { 0x00600001, 0x204003be, 0x000000e4, 0x00000000 },
+   { 0x00600001, 0x206003be, 0x008d0060, 0x00000000 },
+   { 0x00600031, 0x20001fbc, 0x008d0000, 0x8640c800 },
+   { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
+   { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
+   { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
+   { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
+   { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
+   { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
+   { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
+   { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
diff --git a/src/rotation_sf_prog90.h b/src/rotation_sf_prog90.h
new file mode 100644
index 0000000..2e94b8f
--- /dev/null
+++ b/src/rotation_sf_prog90.h
@@ -0,0 +1,17 @@
+   { 0x00000031, 0x20c01fbd, 0x00000034, 0x01110081 },
+   { 0x00000031, 0x20c41fbd, 0x0000002c, 0x01110081 },
+   { 0x00600040, 0x20e077bd, 0x008d0080, 0x008d4060 },
+   { 0x00000041, 0x20e077bd, 0x000000e0, 0x000000c0 },
+   { 0x00000041, 0x20e477bd, 0x000000e4, 0x000000c4 },
+   { 0x00600001, 0x202003be, 0x000000e0, 0x00000000 },
+   { 0x00600001, 0x204003be, 0x000000e4, 0x00000000 },
+   { 0x00600001, 0x206003be, 0x008d0060, 0x00000000 },
+   { 0x00600031, 0x20001fbc, 0x008d0000, 0x8640c800 },
+   { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
+   { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
+   { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
+   { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
+   { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
+   { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
+   { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
+   { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
diff --git a/src/rotation_wm0.g4a b/src/rotation_wm0.g4a
new file mode 100644
index 0000000..fe09734
--- /dev/null
+++ b/src/rotation_wm0.g4a
@@ -0,0 +1,123 @@
+/* The initial payload of the thread is always g0.
+ * WM_URB (incoming URB entries) is g3
+ * X0_R is g4
+ * X1_R is g5
+ * Y0_R is g6
+ * Y1_R is g7
+ */
+
+    /* Set up the X/Y screen coordinates of the pixels in our 4 subspans.  Each
+     * subspan is a 2x2 rectangle, and the screen x/y of the upper left of each
+     * subspan are given in GRF register 1.2 through 1.5 (which, with the word
+     * addressing below, are 1.4 through 1.11).
+     *
+     * The result is WM_X*_R and WM_Y*R being:
+     *
+     * X0: {ss0.x, ss0.x+1, ss0.x,   ss0.x+1, ss1.x, ss1.x+1, ss1.x,   ss1.x+y}
+     * Y0: {ss0.y, ss0.y,   ss0.y+1, ss0.y+1, ss1.y, ss1.y,   ss1.y+1, ss1.y+1}
+     * X1: {ss2.x, ss2.x+1, ss2.x,   ss2.x+1, ss3.x, ss3.x+1, ss3.x,   ss3.x+y}
+     * Y1: {ss2.y, ss2.y,   ss2.y+1, ss2.y+1, ss3.y, ss3.y,   ss3.y+1, ss3.y+1}
+     */
+
+    /* Set up ss0.x coordinates*/
+mov (1) g4<1>F g1.8<0,1,0>UW { align1 };
+add (1) g4.4<1>F g1.8<0,1,0>UW 1UB { align1 };
+mov (1) g4.8<1>F g1.8<0,1,0>UW { align1 };
+add (1) g4.12<1>F g1.8<0,1,0>UW 1UB { align1 };
+    /* Set up ss0.y coordinates */
+mov (1) g6<1>F g1.10<0,1,0>UW { align1 };
+mov (1) g6.4<1>F g1.10<0,1,0>UW { align1 };
+add (1) g6.8<1>F g1.10<0,1,0>UW 1UB { align1 };
+add (1) g6.12<1>F g1.10<0,1,0>UW 1UB { align1 };
+    /* set up ss1.x coordinates */
+mov (1) g4.16<1>F g1.12<0,1,0>UW { align1 };
+add (1) g4.20<1>F g1.12<0,1,0>UW 1UB { align1 };
+mov (1) g4.24<1>F g1.12<0,1,0>UW { align1 };
+add (1) g4.28<1>F g1.12<0,1,0>UW 1UB { align1 };
+    /* set up ss1.y coordinates */
+mov (1) g6.16<1>F g1.14<0,1,0>UW { align1 };
+mov (1) g6.20<1>F g1.14<0,1,0>UW { align1 };
+add (1) g6.24<1>F g1.14<0,1,0>UW 1UB { align1 };
+add (1) g6.28<1>F g1.14<0,1,0>UW 1UB { align1 };
+    /* Set up ss2.x coordinates */
+mov (1) g5<1>F g1.16<0,1,0>UW { align1 };
+add (1) g5.4<1>F g1.16<0,1,0>UW 1UB { align1 };
+mov (1) g5.8<1>F g1.16<0,1,0>UW { align1 };
+add (1) g5.12<1>F g1.16<0,1,0>UW 1UB { align1 };
+    /* Set up ss2.y coordinates */
+mov (1) g7<1>F g1.18<0,1,0>UW { align1 };
+mov (1) g7.4<1>F g1.18<0,1,0>UW { align1 };
+add (1) g7.8<1>F g1.18<0,1,0>UW 1UB { align1 };
+add (1) g7.12<1>F g1.18<0,1,0>UW 1UB { align1 };
+    /* Set up ss3.x coordinates */
+mov (1) g5.16<1>F g1.20<0,1,0>UW { align1 };
+add (1) g5.20<1>F g1.20<0,1,0>UW 1UB { align1 };
+mov (1) g5.24<1>F g1.20<0,1,0>UW { align1 };
+add (1) g5.28<1>F g1.20<0,1,0>UW 1UB { align1 };
+    /* Set up ss3.y coordinates */
+mov (1) g7.16<1>F g1.22<0,1,0>UW { align1 };
+mov (1) g7.20<1>F g1.22<0,1,0>UW { align1 };
+add (1) g7.24<1>F g1.22<0,1,0>UW 1UB { align1 };
+add (1) g7.28<1>F g1.22<0,1,0>UW 1UB { align1 };
+
+    /* Now, map these screen space coordinates into texture coordinates. */
+    /* subtract screen-space X origin of vertex 0. */
+add (8) g4<1>F g4<8,8,1>F -g1<0,1,0>F { align1 };
+add (8) g5<1>F g5<8,8,1>F -g1<0,1,0>F { align1 };
+    /* scale by texture X increment */
+mul (8) g4<1>F g4<8,8,1>F g3<0,1,0>F { align1 };
+mul (8) g5<1>F g5<8,8,1>F g3<0,1,0>F { align1 };
+    /* add in texture X offset */
+add (8) g4<1>F g4<8,8,1>F g3.12<0,1,0>F { align1 };
+add (8) g5<1>F g5<8,8,1>F g3.12<0,1,0>F { align1 };
+    /* subtract screen-space Y origin of vertex 0. */
+add (8) g6<1>F g6<8,8,1>F -g1.4<0,1,0>F { align1 };
+add (8) g7<1>F g7<8,8,1>F -g1.4<0,1,0>F { align1 };
+    /* scale by texture Y increment */
+    /* XXX: double check the fields in Cx,Cy,Co and attributes*/
+mul (8) g6<1>F g6<8,8,1>F g3.20<0,1,0>F { align1 };
+mul (8) g7<1>F g7<8,8,1>F g3.20<0,1,0>F { align1 };
+    /* add in texture Y offset */
+add (8) g6<1>F g6<8,8,1>F g3.28<0,1,0>F { align1 };
+add (8) g7<1>F g7<8,8,1>F g3.28<0,1,0>F { align1 };
+    /* sampler  */
+mov (8) m1<1>F g4<8,8,1>F { align1 };
+mov (8) m2<1>F g5<8,8,1>F { align1 };
+mov (8) m3<1>F g6<8,8,1>F { align1 };
+mov (8) m4<1>F g7<8,8,1>F { align1 };
+
+    /*
+     * g0 holds the PS thread payload, which (oddly) contains
+     * precisely what the sampler wants to see in m0
+     */
+send  (16) 0 g12<1>UW g0<8,8,1>UW sampler (1,0,F) mlen 5 rlen 8 { align1 };
+mov (8) g19<1>UD g19<8,8,1>UD { align1 };
+
+mov (8) m2<1>F g12<8,8,1>F { align1 };
+mov (8) m3<1>F g14<8,8,1>F { align1 };
+mov (8) m4<1>F g16<8,8,1>F { align1 };
+mov (8) m5<1>F g18<8,8,1>F { align1 };
+mov (8) m6<1>F g13<8,8,1>F { align1 };
+mov (8) m7<1>F g15<8,8,1>F { align1 };
+mov (8) m8<1>F g17<8,8,1>F { align1 };
+mov (8) m9<1>F g19<8,8,1>F { align1 };
+
+   /* Pass through control information:
+    */
+mov (8) m1<1>UD g1<8,8,1>UD { align1 mask_disable };
+   /* Send framebuffer write message: XXX: acc0? */
+send (16) 0 acc0<1>UW g0<8,8,1>UW write (
+	0, /* binding table index 0 */
+	8, /* pixel scoreboard clear */
+	4, /* render target write */
+	0 /* no write commit message */
+	) mlen 10 rlen 0 { align1 EOT };
+   /* padding */
+nop;
+nop;
+nop;
+nop;
+nop;
+nop;
+nop;
+nop;
diff --git a/src/rotation_wm90.g4a b/src/rotation_wm90.g4a
new file mode 100644
index 0000000..fd600bf
--- /dev/null
+++ b/src/rotation_wm90.g4a
@@ -0,0 +1,127 @@
+/* The initial payload of the thread is always g0.
+ * WM_URB (incoming URB entries) is g3
+ * X0_R is g4
+ * X1_R is g5
+ * Y0_R is g6
+ * Y1_R is g7
+ */
+
+    /* Set up the X/Y screen coordinates of the pixels in our 4 subspans.  Each
+     * subspan is a 2x2 rectangle, and the screen x/y of the upper left of each
+     * subspan are given in GRF register 1.2 through 1.5 (which, with the word
+     * addressing below, are 1.4 through 1.11).
+     *
+     * The result is WM_X*_R and WM_Y*R being:
+     *
+     * X0: {ss0.x, ss0.x+1, ss0.x,   ss0.x+1, ss1.x, ss1.x+1, ss1.x,   ss1.x+y}
+     * Y0: {ss0.y, ss0.y,   ss0.y+1, ss0.y+1, ss1.y, ss1.y,   ss1.y+1, ss1.y+1}
+     * X1: {ss2.x, ss2.x+1, ss2.x,   ss2.x+1, ss3.x, ss3.x+1, ss3.x,   ss3.x+y}
+     * Y1: {ss2.y, ss2.y,   ss2.y+1, ss2.y+1, ss3.y, ss3.y,   ss3.y+1, ss3.y+1}
+     */
+
+    /* Set up ss0.x coordinates*/
+mov (1) g4<1>F g1.8<0,1,0>UW { align1 };
+add (1) g4.4<1>F g1.8<0,1,0>UW 1UB { align1 };
+mov (1) g4.8<1>F g1.8<0,1,0>UW { align1 };
+add (1) g4.12<1>F g1.8<0,1,0>UW 1UB { align1 };
+    /* Set up ss0.y coordinates */
+mov (1) g6<1>F g1.10<0,1,0>UW { align1 };
+mov (1) g6.4<1>F g1.10<0,1,0>UW { align1 };
+add (1) g6.8<1>F g1.10<0,1,0>UW 1UB { align1 };
+add (1) g6.12<1>F g1.10<0,1,0>UW 1UB { align1 };
+    /* set up ss1.x coordinates */
+mov (1) g4.16<1>F g1.12<0,1,0>UW { align1 };
+add (1) g4.20<1>F g1.12<0,1,0>UW 1UB { align1 };
+mov (1) g4.24<1>F g1.12<0,1,0>UW { align1 };
+add (1) g4.28<1>F g1.12<0,1,0>UW 1UB { align1 };
+    /* set up ss1.y coordinates */
+mov (1) g6.16<1>F g1.14<0,1,0>UW { align1 };
+mov (1) g6.20<1>F g1.14<0,1,0>UW { align1 };
+add (1) g6.24<1>F g1.14<0,1,0>UW 1UB { align1 };
+add (1) g6.28<1>F g1.14<0,1,0>UW 1UB { align1 };
+    /* Set up ss2.x coordinates */
+mov (1) g5<1>F g1.16<0,1,0>UW { align1 };
+add (1) g5.4<1>F g1.16<0,1,0>UW 1UB { align1 };
+mov (1) g5.8<1>F g1.16<0,1,0>UW { align1 };
+add (1) g5.12<1>F g1.16<0,1,0>UW 1UB { align1 };
+    /* Set up ss2.y coordinates */
+mov (1) g7<1>F g1.18<0,1,0>UW { align1 };
+mov (1) g7.4<1>F g1.18<0,1,0>UW { align1 };
+add (1) g7.8<1>F g1.18<0,1,0>UW 1UB { align1 };
+add (1) g7.12<1>F g1.18<0,1,0>UW 1UB { align1 };
+    /* Set up ss3.x coordinates */
+mov (1) g5.16<1>F g1.20<0,1,0>UW { align1 };
+add (1) g5.20<1>F g1.20<0,1,0>UW 1UB { align1 };
+mov (1) g5.24<1>F g1.20<0,1,0>UW { align1 };
+add (1) g5.28<1>F g1.20<0,1,0>UW 1UB { align1 };
+    /* Set up ss3.y coordinates */
+mov (1) g7.16<1>F g1.22<0,1,0>UW { align1 };
+mov (1) g7.20<1>F g1.22<0,1,0>UW { align1 };
+add (1) g7.24<1>F g1.22<0,1,0>UW 1UB { align1 };
+add (1) g7.28<1>F g1.22<0,1,0>UW 1UB { align1 };
+
+    /* Now, map these screen space coordinates into texture coordinates. */
+/* XXX: convert it to calculate (u,v) in 90 and 270 case */
+    /* subtract screen-space Y origin of vertex 0. */
+add (8) g6<1>F g6<8,8,1>F -g1.4<0,1,0>F { align1 };
+add (8) g7<1>F g7<8,8,1>F -g1.4<0,1,0>F { align1 };
+
+/* (Yp - Ystart) * Cx */
+mul (8) g6<1>F g6<8,8,1>F g3<0,1,0>F { align1 };
+mul (8) g7<1>F g7<8,8,1>F g3<0,1,0>F { align1 };
+
+    /* scale by texture Y increment */
+add (8) g6<1>F g6<8,8,1>F g3.12<0,1,0>F { align1 };
+add (8) g7<1>F g7<8,8,1>F g3.12<0,1,0>F { align1 };
+
+    /* subtract screen-space X origin of vertex 0. */
+add (8) g4<1>F g4<8,8,1>F -g1<0,1,0>F { align1 };
+add (8) g5<1>F g5<8,8,1>F -g1<0,1,0>F { align1 };
+    /* scale by texture X increment */
+mul (8) g4<1>F g4<8,8,1>F g3.20<0,1,0>F { align1 };
+mul (8) g5<1>F g5<8,8,1>F g3.20<0,1,0>F { align1 };
+    /* add in texture X offset */
+add (8) g4<1>F g4<8,8,1>F g3.28<0,1,0>F { align1 };
+add (8) g5<1>F g5<8,8,1>F g3.28<0,1,0>F { align1 };
+
+    /* sampler  */
+mov (8) m1<1>F g6<8,8,1>F { align1 };
+mov (8) m2<1>F g7<8,8,1>F { align1 };
+mov (8) m3<1>F g4<8,8,1>F { align1 };
+mov (8) m4<1>F g5<8,8,1>F { align1 };
+
+    /*
+     * g0 holds the PS thread payload, which (oddly) contains
+     * precisely what the sampler wants to see in m0
+     */
+send  (16) 0 g12<1>UW g0<8,8,1>UW sampler (1,0,F) mlen 5 rlen 8 { align1 };
+mov (8) g19<1>UD g19<8,8,1>UD { align1 };
+
+mov (8) m2<1>F g12<8,8,1>F { align1 };
+mov (8) m3<1>F g14<8,8,1>F { align1 };
+mov (8) m4<1>F g16<8,8,1>F { align1 };
+mov (8) m5<1>F g18<8,8,1>F { align1 };
+mov (8) m6<1>F g13<8,8,1>F { align1 };
+mov (8) m7<1>F g15<8,8,1>F { align1 };
+mov (8) m8<1>F g17<8,8,1>F { align1 };
+mov (8) m9<1>F g19<8,8,1>F { align1 };
+
+   /* Pass through control information:
+    */
+mov (8) m1<1>UD g1<8,8,1>UD { align1 mask_disable };
+   /* Send framebuffer write message: XXX: acc0? */
+send (16) 0 acc0<1>UW g0<8,8,1>UW write (
+	0, /* binding table index 0 */
+	8, /* pixel scoreboard clear */
+	4, /* render target write */
+	0 /* no write commit message */
+	) mlen 10 rlen 0 { align1 EOT };
+   /* padding */
+nop;
+nop;
+nop;
+nop;
+nop;
+nop;
+nop;
+nop;
diff --git a/src/rotation_wm_prog0.h b/src/rotation_wm_prog0.h
new file mode 100644
index 0000000..08269b7
--- /dev/null
+++ b/src/rotation_wm_prog0.h
@@ -0,0 +1,68 @@
+   { 0x00000001, 0x2080013d, 0x00000028, 0x00000000 },
+   { 0x00000040, 0x20840d3d, 0x00000028, 0x00000001 },
+   { 0x00000001, 0x2088013d, 0x00000028, 0x00000000 },
+   { 0x00000040, 0x208c0d3d, 0x00000028, 0x00000001 },
+   { 0x00000001, 0x20c0013d, 0x0000002a, 0x00000000 },
+   { 0x00000001, 0x20c4013d, 0x0000002a, 0x00000000 },
+   { 0x00000040, 0x20c80d3d, 0x0000002a, 0x00000001 },
+   { 0x00000040, 0x20cc0d3d, 0x0000002a, 0x00000001 },
+   { 0x00000001, 0x2090013d, 0x0000002c, 0x00000000 },
+   { 0x00000040, 0x20940d3d, 0x0000002c, 0x00000001 },
+   { 0x00000001, 0x2098013d, 0x0000002c, 0x00000000 },
+   { 0x00000040, 0x209c0d3d, 0x0000002c, 0x00000001 },
+   { 0x00000001, 0x20d0013d, 0x0000002e, 0x00000000 },
+   { 0x00000001, 0x20d4013d, 0x0000002e, 0x00000000 },
+   { 0x00000040, 0x20d80d3d, 0x0000002e, 0x00000001 },
+   { 0x00000040, 0x20dc0d3d, 0x0000002e, 0x00000001 },
+   { 0x00000001, 0x20a0013d, 0x00000030, 0x00000000 },
+   { 0x00000040, 0x20a40d3d, 0x00000030, 0x00000001 },
+   { 0x00000001, 0x20a8013d, 0x00000030, 0x00000000 },
+   { 0x00000040, 0x20ac0d3d, 0x00000030, 0x00000001 },
+   { 0x00000001, 0x20e0013d, 0x00000032, 0x00000000 },
+   { 0x00000001, 0x20e4013d, 0x00000032, 0x00000000 },
+   { 0x00000040, 0x20e80d3d, 0x00000032, 0x00000001 },
+   { 0x00000040, 0x20ec0d3d, 0x00000032, 0x00000001 },
+   { 0x00000001, 0x20b0013d, 0x00000034, 0x00000000 },
+   { 0x00000040, 0x20b40d3d, 0x00000034, 0x00000001 },
+   { 0x00000001, 0x20b8013d, 0x00000034, 0x00000000 },
+   { 0x00000040, 0x20bc0d3d, 0x00000034, 0x00000001 },
+   { 0x00000001, 0x20f0013d, 0x00000036, 0x00000000 },
+   { 0x00000001, 0x20f4013d, 0x00000036, 0x00000000 },
+   { 0x00000040, 0x20f80d3d, 0x00000036, 0x00000001 },
+   { 0x00000040, 0x20fc0d3d, 0x00000036, 0x00000001 },
+   { 0x00600040, 0x208077bd, 0x008d0080, 0x00004020 },
+   { 0x00600040, 0x20a077bd, 0x008d00a0, 0x00004020 },
+   { 0x00600041, 0x208077bd, 0x008d0080, 0x00000060 },
+   { 0x00600041, 0x20a077bd, 0x008d00a0, 0x00000060 },
+   { 0x00600040, 0x208077bd, 0x008d0080, 0x0000006c },
+   { 0x00600040, 0x20a077bd, 0x008d00a0, 0x0000006c },
+   { 0x00600040, 0x20c077bd, 0x008d00c0, 0x00004024 },
+   { 0x00600040, 0x20e077bd, 0x008d00e0, 0x00004024 },
+   { 0x00600041, 0x20c077bd, 0x008d00c0, 0x00000074 },
+   { 0x00600041, 0x20e077bd, 0x008d00e0, 0x00000074 },
+   { 0x00600040, 0x20c077bd, 0x008d00c0, 0x0000007c },
+   { 0x00600040, 0x20e077bd, 0x008d00e0, 0x0000007c },
+   { 0x00600001, 0x202003be, 0x008d0080, 0x00000000 },
+   { 0x00600001, 0x204003be, 0x008d00a0, 0x00000000 },
+   { 0x00600001, 0x206003be, 0x008d00c0, 0x00000000 },
+   { 0x00600001, 0x208003be, 0x008d00e0, 0x00000000 },
+   { 0x00800031, 0x21801d29, 0x008d0000, 0x02580001 },
+   { 0x00600001, 0x22600021, 0x008d0260, 0x00000000 },
+   { 0x00600001, 0x204003be, 0x008d0180, 0x00000000 },
+   { 0x00600001, 0x206003be, 0x008d01c0, 0x00000000 },
+   { 0x00600001, 0x208003be, 0x008d0200, 0x00000000 },
+   { 0x00600001, 0x20a003be, 0x008d0240, 0x00000000 },
+   { 0x00600001, 0x20c003be, 0x008d01a0, 0x00000000 },
+   { 0x00600001, 0x20e003be, 0x008d01e0, 0x00000000 },
+   { 0x00600001, 0x210003be, 0x008d0220, 0x00000000 },
+   { 0x00600001, 0x212003be, 0x008d0260, 0x00000000 },
+   { 0x00600201, 0x20200022, 0x008d0020, 0x00000000 },
+   { 0x00800031, 0x24001d28, 0x008d0000, 0x85a04800 },
+   { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
+   { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
+   { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
+   { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
+   { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
+   { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
+   { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
+   { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
diff --git a/src/rotation_wm_prog90.h b/src/rotation_wm_prog90.h
new file mode 100644
index 0000000..9b87750
--- /dev/null
+++ b/src/rotation_wm_prog90.h
@@ -0,0 +1,68 @@
+   { 0x00000001, 0x2080013d, 0x00000028, 0x00000000 },
+   { 0x00000040, 0x20840d3d, 0x00000028, 0x00000001 },
+   { 0x00000001, 0x2088013d, 0x00000028, 0x00000000 },
+   { 0x00000040, 0x208c0d3d, 0x00000028, 0x00000001 },
+   { 0x00000001, 0x20c0013d, 0x0000002a, 0x00000000 },
+   { 0x00000001, 0x20c4013d, 0x0000002a, 0x00000000 },
+   { 0x00000040, 0x20c80d3d, 0x0000002a, 0x00000001 },
+   { 0x00000040, 0x20cc0d3d, 0x0000002a, 0x00000001 },
+   { 0x00000001, 0x2090013d, 0x0000002c, 0x00000000 },
+   { 0x00000040, 0x20940d3d, 0x0000002c, 0x00000001 },
+   { 0x00000001, 0x2098013d, 0x0000002c, 0x00000000 },
+   { 0x00000040, 0x209c0d3d, 0x0000002c, 0x00000001 },
+   { 0x00000001, 0x20d0013d, 0x0000002e, 0x00000000 },
+   { 0x00000001, 0x20d4013d, 0x0000002e, 0x00000000 },
+   { 0x00000040, 0x20d80d3d, 0x0000002e, 0x00000001 },
+   { 0x00000040, 0x20dc0d3d, 0x0000002e, 0x00000001 },
+   { 0x00000001, 0x20a0013d, 0x00000030, 0x00000000 },
+   { 0x00000040, 0x20a40d3d, 0x00000030, 0x00000001 },
+   { 0x00000001, 0x20a8013d, 0x00000030, 0x00000000 },
+   { 0x00000040, 0x20ac0d3d, 0x00000030, 0x00000001 },
+   { 0x00000001, 0x20e0013d, 0x00000032, 0x00000000 },
+   { 0x00000001, 0x20e4013d, 0x00000032, 0x00000000 },
+   { 0x00000040, 0x20e80d3d, 0x00000032, 0x00000001 },
+   { 0x00000040, 0x20ec0d3d, 0x00000032, 0x00000001 },
+   { 0x00000001, 0x20b0013d, 0x00000034, 0x00000000 },
+   { 0x00000040, 0x20b40d3d, 0x00000034, 0x00000001 },
+   { 0x00000001, 0x20b8013d, 0x00000034, 0x00000000 },
+   { 0x00000040, 0x20bc0d3d, 0x00000034, 0x00000001 },
+   { 0x00000001, 0x20f0013d, 0x00000036, 0x00000000 },
+   { 0x00000001, 0x20f4013d, 0x00000036, 0x00000000 },
+   { 0x00000040, 0x20f80d3d, 0x00000036, 0x00000001 },
+   { 0x00000040, 0x20fc0d3d, 0x00000036, 0x00000001 },
+   { 0x00600040, 0x20c077bd, 0x008d00c0, 0x00004024 },
+   { 0x00600040, 0x20e077bd, 0x008d00e0, 0x00004024 },
+   { 0x00600041, 0x20c077bd, 0x008d00c0, 0x00000060 },
+   { 0x00600041, 0x20e077bd, 0x008d00e0, 0x00000060 },
+   { 0x00600040, 0x20c077bd, 0x008d00c0, 0x0000006c },
+   { 0x00600040, 0x20e077bd, 0x008d00e0, 0x0000006c },
+   { 0x00600040, 0x208077bd, 0x008d0080, 0x00004020 },
+   { 0x00600040, 0x20a077bd, 0x008d00a0, 0x00004020 },
+   { 0x00600041, 0x208077bd, 0x008d0080, 0x00000074 },
+   { 0x00600041, 0x20a077bd, 0x008d00a0, 0x00000074 },
+   { 0x00600040, 0x208077bd, 0x008d0080, 0x0000007c },
+   { 0x00600040, 0x20a077bd, 0x008d00a0, 0x0000007c },
+   { 0x00600001, 0x202003be, 0x008d00c0, 0x00000000 },
+   { 0x00600001, 0x204003be, 0x008d00e0, 0x00000000 },
+   { 0x00600001, 0x206003be, 0x008d0080, 0x00000000 },
+   { 0x00600001, 0x208003be, 0x008d00a0, 0x00000000 },
+   { 0x00800031, 0x21801d29, 0x008d0000, 0x02580001 },
+   { 0x00600001, 0x22600021, 0x008d0260, 0x00000000 },
+   { 0x00600001, 0x204003be, 0x008d0180, 0x00000000 },
+   { 0x00600001, 0x206003be, 0x008d01c0, 0x00000000 },
+   { 0x00600001, 0x208003be, 0x008d0200, 0x00000000 },
+   { 0x00600001, 0x20a003be, 0x008d0240, 0x00000000 },
+   { 0x00600001, 0x20c003be, 0x008d01a0, 0x00000000 },
+   { 0x00600001, 0x20e003be, 0x008d01e0, 0x00000000 },
+   { 0x00600001, 0x210003be, 0x008d0220, 0x00000000 },
+   { 0x00600001, 0x212003be, 0x008d0260, 0x00000000 },
+   { 0x00600201, 0x20200022, 0x008d0020, 0x00000000 },
+   { 0x00800031, 0x24001d28, 0x008d0000, 0x85a04800 },
+   { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
+   { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
+   { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
+   { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
+   { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
+   { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
+   { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
+   { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
diff-tree 9cc2f3313d77487dea372e6ab32d6d9c06617ae3 (from 49a6bea7d969dbfd1dd542c0c3e02abc330d6850)
Author: Eric Anholt <eric at anholt.net>
Date:   Thu Nov 16 15:12:43 2006 -0800

    Replace broken PCI resource size detection with pciGetBaseSize() call.

diff --git a/src/i830_driver.c b/src/i830_driver.c
index c28b8b7..287217a 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -4192,16 +4192,12 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int f
       }
    } else {
       if (IS_I9XX(pI830)) {
-	 if (pI830->PciInfo->memBase[2] & 0x08000000)
-	    pI830->FbMapSize = 0x8000000;	/* 128MB aperture */
-	 else
-	    pI830->FbMapSize = 0x10000000;	/* 256MB aperture */
-
-   	 if (pI830->PciInfo->chipType == PCI_CHIP_E7221_G)
-	    pI830->FbMapSize = 0x8000000;	/* 128MB aperture */
-      } else
-	 /* 128MB aperture for later chips */
+	 pI830->FbMapSize = 1UL << pciGetBaseSize(pI830->PciTag, 2, TRUE,
+						  NULL);
+      } else {
+	 /* 128MB aperture for later i8xx series. */
 	 pI830->FbMapSize = 0x8000000;
+      }
    }
 
    if (pI830->PciInfo->chipType == PCI_CHIP_E7221_G)
diff-tree 75f4df278e9db360967d77cdba4756cbde622d56 (from e5c572f841b626b8b6f21a6966a33956d3b0b35b)
Author: root <root at localhost.localdomain>
Date:   Wed Nov 8 13:56:32 2006 +0800

    855 fix

diff --git a/src/i830_driver.c b/src/i830_driver.c
index 8464b39..ce3e442 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -2851,7 +2851,8 @@ RestoreHWState(ScrnInfoPtr pScrn)
 
    OUTREG(PIPEACONF, pI830->savePIPEACONF);
    OUTREG(PIPEBCONF, pI830->savePIPEBCONF);
-
+   if (IS_I855(pI830))
+	usleep(10);
    OUTREG(VGACNTRL, pI830->saveVGACNTRL);
    OUTREG(DSPACNTR, pI830->saveDSPACNTR);
    OUTREG(DSPBCNTR, pI830->saveDSPBCNTR);
diff-tree 49a6bea7d969dbfd1dd542c0c3e02abc330d6850 (from parents)
Merge: 64447c7a059775e7ea8649f4714df7565e932c60 fbb376bd1a4daad4c86e349df98438989ce173f1
Author: Wang Zhenyu <zhenyu.z.wang at intel.com>
Date:   Mon Nov 6 10:25:23 2006 +0800

    Merge branch 'master' into crestline

diff-tree 64447c7a059775e7ea8649f4714df7565e932c60 (from b7e57deebbda527e878326cf3e6358c0a48d7817)
Author: Zou Nanhai <nanhai.zou at intel.com>
Date:   Wed Nov 1 14:36:20 2006 +0800

    walk around to VBIOS bug in Crestline B0

diff --git a/src/i830_driver.c b/src/i830_driver.c
index cdf005a..ea6cd17 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -6514,7 +6514,7 @@ I830VESASetMode(ScrnInfoPtr pScrn, Displ
 
    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Mode bandwidth is %d Mpixel/s\n",
 	      pMode->HDisplay * pMode->VDisplay * refresh / 1000000);
-
+   if (0)
    {
       int maxBandwidth, bandwidthA, bandwidthB;
 
diff-tree 4198f1216eb13b30d1e92d4395e98861f4324c38 (from d485c1f2de11db92b515690fbe38b6aeb6207605)
Author: Wang Zhenyu <zhenyu.z.wang at intel.com>
Date:   Tue Oct 10 15:50:10 2006 +0800

    Mark current ps kernel is experimential with little test.

diff --git a/src/i965_composite_wm_nomask.g4a b/src/i965_composite_wm_nomask.g4a
index 8791631..927d86a 100644
--- a/src/i965_composite_wm_nomask.g4a
+++ b/src/i965_composite_wm_nomask.g4a
@@ -1,6 +1,8 @@
 /*
  * This's for exa composite operation in no mask picture case.
- * The simplest case is just sending what src picture has to dst picture
+ * The simplest case is just sending what src picture has to dst picture.
+ * XXX: This is still experimental, and should be fixed to support multiple texture
+ * map, and conditional mul actions. 
  */
 
 /* I think this should be same as in g4a program for texture video,
diff-tree d485c1f2de11db92b515690fbe38b6aeb6207605 (from 92c5020bbd31e02c7224798a8f094d237afa19a0)
Author: Wang Zhenyu <zhenyu.z.wang at intel.com>
Date:   Tue Oct 10 14:11:35 2006 +0800

    Use sf_prog.h instead

diff --git a/src/i965_exa_render.c b/src/i965_exa_render.c
index 5528388..7fbf99c 100644
--- a/src/i965_exa_render.c
+++ b/src/i965_exa_render.c
@@ -89,7 +89,6 @@ struct formatinfo {
 
 // refer vol2, 3d rasterization 3.8.1
 
-/* XXX: bad!bad! broadwater has different blend factor definition */
 /* defined in brw_defines.h */
 static struct blendinfo I965BlendOp[] = { 
     /* Clear */
@@ -163,8 +162,6 @@ static void I965GetBlendCntl(int op, Pic
 
 }
 
-
-/* FIXME */
 static Bool I965GetDestFormat(PicturePtr pDstPicture, CARD32 *dst_format)
 {
     switch (pDstPicture->format) {
@@ -221,7 +218,6 @@ static Bool I965CheckCompositeTexture(Pi
         I830FALLBACK("Unsupported picture format 0x%x\n",
                          (int)pPict->format);
 
-    /* XXX: fallback when repeat? */
     if (pPict->repeat && pPict->repeatType != RepeatNormal)
 	I830FALLBACK("extended repeat (%d) not supported\n",
 		     pPict->repeatType);
@@ -346,40 +342,7 @@ static const CARD32 sip_kernel_static[][
 #define SF_MAX_THREADS	   4
 
 static const CARD32 sf_kernel_static[][4] = {
-/*    send   0 (1) g6<1>F g1.12<0,1,0>F math mlen 1 rlen 1 { align1 +  } */
-   { 0x00000031, 0x20c01fbd, 0x0000002c, 0x01110081 },
-/*    send   0 (1) g6.4<1>F g1.20<0,1,0>F math mlen 1 rlen 1 { align1 +  } */
-   { 0x00000031, 0x20c41fbd, 0x00000034, 0x01110081 },
-/*    add (8) g7<1>F g4<8,8,1>F g3<8,8,1>F { align1 +  } */
-   { 0x00600040, 0x20e077bd, 0x008d0080, 0x008d4060 },
-/*    mul (1) g7<1>F g7<0,1,0>F g6<0,1,0>F { align1 +  } */
-   { 0x00000041, 0x20e077bd, 0x000000e0, 0x000000c0 },
-/*    mul (1) g7.4<1>F g7.4<0,1,0>F g6.4<0,1,0>F { align1 +  } */
-   { 0x00000041, 0x20e477bd, 0x000000e4, 0x000000c4 },
-/*    mov (8) m1<1>F g7<0,1,0>F { align1 +  } */
-   { 0x00600001, 0x202003be, 0x000000e0, 0x00000000 },
-/*    mov (8) m2<1>F g7.4<0,1,0>F { align1 +  } */
-   { 0x00600001, 0x204003be, 0x000000e4, 0x00000000 },
-/*    mov (8) m3<1>F g3<8,8,1>F { align1 +  } */
-   { 0x00600001, 0x206003be, 0x008d0060, 0x00000000 },
-/*    send   0 (8) a0<1>F g0<8,8,1>F urb mlen 4 rlen 0 write +0 transpose used complete EOT{ align1 +  } */
-   { 0x00600031, 0x20001fbc, 0x008d0000, 0x8640c800 },
-/*    nop (4) g0<1>UD { align1 +  } */
-   { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
-/*    nop (4) g0<1>UD { align1 +  } */
-   { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
-/*    nop (4) g0<1>UD { align1 +  } */
-   { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
-/*    nop (4) g0<1>UD { align1 +  } */
-   { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
-/*    nop (4) g0<1>UD { align1 +  } */
-   { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
-/*    nop (4) g0<1>UD { align1 +  } */
-   { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
-/*    nop (4) g0<1>UD { align1 +  } */
-   { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
-/*    nop (4) g0<1>UD { align1 +  } */
-   { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
+#include "sf_prog.h"
 };
 
 /* ps kernels */
@@ -475,9 +438,8 @@ ErrorF("i965 prepareComposite\n");
    cc_offset = ALIGN(next_offset, 32);
    next_offset = cc_offset + sizeof(*cc_state);
 
-// fixup sf_kernel_static, is sf_kernel needed? or not? why? 
-//	-> just keep current sf_kernel, which will send one setup urb entry to
-//	PS kernel
+   /* keep current sf_kernel, which will send one setup urb entry to
+	PS kernel */
    sf_kernel_offset = ALIGN(next_offset, 64);
    next_offset = sf_kernel_offset + sizeof (sf_kernel_static);
 
@@ -965,7 +927,7 @@ ErrorF("i965 prepareComposite\n");
   // int vb_pitch = 4 * 4;  // XXX: pitch should include mask's coords? possible
   // all three coords on one row?
    int nelem = pMask ? 3: 2;
-   OUT_RING(BRW_3DSTATE_VERTEX_BUFFERS | 3); //should be 4n-1 -> 3
+   OUT_RING(BRW_3DSTATE_VERTEX_BUFFERS | 3); //XXX: should be 4n-1 -> 3
    OUT_RING((0 << VB0_BUFFER_INDEX_SHIFT) |
 	    VB0_VERTEXDATA |
 	    ((4 * 2 * nelem) << VB0_BUFFER_PITCH_SHIFT)); 
diff-tree 92c5020bbd31e02c7224798a8f094d237afa19a0 (from 518802843284973f1f86132afd805c0e662e1ba6)
Author: Wang Zhenyu <zhenyu.z.wang at intel.com>
Date:   Thu Sep 28 13:55:52 2006 +0800

    Fix picture's transform checking

diff --git a/src/i965_exa_render.c b/src/i965_exa_render.c
index f7093f2..5528388 100644
--- a/src/i965_exa_render.c
+++ b/src/i965_exa_render.c
@@ -437,11 +437,22 @@ ErrorF("i965 prepareComposite\n");
     scale_units[2][0] = pDst->drawable.width;
     scale_units[2][1] = pDst->drawable.height;
 
+    if (pSrcPicture->transform) {
+	is_transform[0] = TRUE;
+	transform[0] = pSrcPicture->transform;
+    } else 
+	is_transform[0] = FALSE;
+
     if (!pMask) {
 	is_transform[1] = FALSE;
 	scale_units[1][0] = -1;
 	scale_units[1][1] = -1;
     } else {
+	if (pMaskPicture->transform) {
+	    is_transform[1] = TRUE;
+	    transform[1] = pMaskPicture->transform;
+	} else
+	    is_transform[1] = FALSE;
 	scale_units[1][0] = pMask->drawable.width;
 	scale_units[1][1] = pMask->drawable.height;
     }
diff-tree 518802843284973f1f86132afd805c0e662e1ba6 (from 25ff5baad95c205c7c690da72fc0f252b3ed9289)
Author: Wang Zhenyu <zhenyu.z.wang at intel.com>
Date:   Thu Sep 28 11:15:33 2006 +0800

    Fallback in mask picture for now
    
    Do it later after finish wm kernel program.

diff --git a/src/i965_exa_render.c b/src/i965_exa_render.c
index b56bf7f..f7093f2 100644
--- a/src/i965_exa_render.c
+++ b/src/i965_exa_render.c
@@ -417,6 +417,11 @@ ErrorF("i965 prepareComposite\n");
 //    i965_surf_setup(pScrn, pSrcPicture, pMaskPicture, pDstPicture,
 //   			pSrc, pMask, pDst);
     // then setup blend, and shader program 
+    
+    /* FIXME: fallback in pMask for now, would be enable after finish
+	wm kernel program */
+    if (pMask)
+	I830FALLBACK("No mask support yet.\n");
 
     I965GetDestFormat(pDstPicture, &dst_format);
     src_offset = exaGetPixmapOffset(pSrc);
@@ -995,68 +1000,12 @@ ErrorF("i965 prepareComposite\n");
 	    (BRW_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_3_SHIFT) |
 	    (8 << VE1_DESTINATION_ELEMENT_OFFSET_SHIFT)); 
 		//XXX: is this has alignment issue? and thread access problem?
-	    
    }
    
    ADVANCE_LP_RING();
     
    }
 
-    {
-	/* cc states */
-	/* dest buffer */
-	/* urbs */
-	/* binding tables */
-	/* clipping */
-	/* color blend (color calculator, dataport shared function)
-		COLOR_CALC_STATE/SURFACE_STATE(rendertarget's color blend enable
-		bit)
-		Errata!!!: brw-a/b, rendertarget 'local' color blending always
-		enabled! only control by global enable bit.
-	   surface format for blend, "Surface format table in Sampling Engine"
-	   XXX: if surface format not support, we should fallback.
-	*/
-	/* 
-	    render target should be defined in SURFACE_STATE
-	    	o render target SURFTYPE_BUFFER? 2D? Keith has 2D set.
-		o depth buffer SURFTYPE_NULL?
-	    color blend:
-	        o Errata!!: mush issue PIPE_CONTROL with Write Cache Flush
-		enable set, before transite to read-write color buffer. 
-	    	o disable pre/post-blending clamping
-		o enable color buffer blending enable in COLOR_CALC_STATE,(vol2, 3d rasterization 3.8) 
-		  enable color blending enable in SURFACE_STATE.(shared,
-		  sampling engine 1.7) 
-		  disable depth test
-		o (we don't use BLENDFACT_SRC_ALPHA_SATURATE, so don't care
-		the Errata for independent alpha blending, just use color
-		blending factor for all) disable independent alpha blending
-		in COLOR_CALC_STATE
-		o set src/dst blend factor in COLOR_CALC_STATE
-
-	*/
-    }
-
-	/* shader program 
-		o use sampler shared function for texture data
-		o submit result to dataport for later color blending */
-    {
-	 /* PS program:
-	 	o declare sampler and variables??
-		o 'send' cmd to Sampling Engine to load 'src' picture
-		o if (!pMask) then 'send' 'src' texture value to DataPort
-		target render cache
-		o else 
-		    - 'send' cmd to SE to load 'mask' picture
-		    - if no alpha, force to 1 (move 1 to W element of mask)
-		    - if (mask->componentAlpha) then mul 'src' & 'mask', 'send'
-		    	output to DataPort render cache
-		    - else mul 'src' & 'mask''s W element(alpha), 'send' output
-		    	to Dataport render cache
-	 */
-
-    }
-
 #ifdef I830DEBUG
     ErrorF("try to sync to show any errors...");
     I830Sync(pScrn);
diff-tree 25ff5baad95c205c7c690da72fc0f252b3ed9289 (from c3a49b5123d094280b5ff358ceef961958319ce4)
Author: Wang Zhenyu <zhenyu.z.wang at intel.com>
Date:   Thu Sep 28 11:09:52 2006 +0800

    Fix compile, add wm header file.

diff --git a/src/Makefile.am b/src/Makefile.am
index e7132bc..494a921 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -70,6 +70,7 @@ i810_drv_la_SOURCES = \
 	 i830_xaa.c \
 	 i830_exa_render.c \
 	 i915_exa_render.c \
+	 i965_composite_wm_nomask.h \
 	 i965_exa_render.c
 
 if HAVE_GEN4ASM
diff --git a/src/i965_composite_wm_nomask.h b/src/i965_composite_wm_nomask.h
new file mode 100644
index 0000000..bd99dd9
--- /dev/null
+++ b/src/i965_composite_wm_nomask.h
@@ -0,0 +1,68 @@
+   { 0x00000001, 0x2080013d, 0x00000028, 0x00000000 },
+   { 0x00000040, 0x20840d3d, 0x00000028, 0x00000001 },
+   { 0x00000001, 0x2088013d, 0x00000028, 0x00000000 },
+   { 0x00000040, 0x208c0d3d, 0x00000028, 0x00000001 },
+   { 0x00000001, 0x20c0013d, 0x0000002a, 0x00000000 },
+   { 0x00000001, 0x20c4013d, 0x0000002a, 0x00000000 },
+   { 0x00000040, 0x20c80d3d, 0x0000002a, 0x00000001 },
+   { 0x00000040, 0x20cc0d3d, 0x0000002a, 0x00000001 },
+   { 0x00000001, 0x2090013d, 0x0000002c, 0x00000000 },
+   { 0x00000040, 0x20940d3d, 0x0000002c, 0x00000001 },
+   { 0x00000001, 0x2098013d, 0x0000002c, 0x00000000 },
+   { 0x00000040, 0x209c0d3d, 0x0000002c, 0x00000001 },
+   { 0x00000001, 0x20d0013d, 0x0000002e, 0x00000000 },
+   { 0x00000001, 0x20d4013d, 0x0000002e, 0x00000000 },
+   { 0x00000040, 0x20d80d3d, 0x0000002e, 0x00000001 },
+   { 0x00000040, 0x20dc0d3d, 0x0000002e, 0x00000001 },
+   { 0x00000001, 0x20a0013d, 0x00000030, 0x00000000 },
+   { 0x00000040, 0x20a40d3d, 0x00000030, 0x00000001 },
+   { 0x00000001, 0x20a8013d, 0x00000030, 0x00000000 },
+   { 0x00000040, 0x20ac0d3d, 0x00000030, 0x00000001 },
+   { 0x00000001, 0x20e0013d, 0x00000032, 0x00000000 },
+   { 0x00000001, 0x20e4013d, 0x00000032, 0x00000000 },
+   { 0x00000040, 0x20e80d3d, 0x00000032, 0x00000001 },
+   { 0x00000040, 0x20ec0d3d, 0x00000032, 0x00000001 },
+   { 0x00000001, 0x20b0013d, 0x00000034, 0x00000000 },
+   { 0x00000040, 0x20b40d3d, 0x00000034, 0x00000001 },
+   { 0x00000001, 0x20b8013d, 0x00000034, 0x00000000 },
+   { 0x00000040, 0x20bc0d3d, 0x00000034, 0x00000001 },
+   { 0x00000001, 0x20f0013d, 0x00000036, 0x00000000 },
+   { 0x00000001, 0x20f4013d, 0x00000036, 0x00000000 },
+   { 0x00000040, 0x20f80d3d, 0x00000036, 0x00000001 },
+   { 0x00000040, 0x20fc0d3d, 0x00000036, 0x00000001 },
+   { 0x00600040, 0x208077bd, 0x008d0080, 0x00004020 },
+   { 0x00600040, 0x20a077bd, 0x008d00a0, 0x00004020 },
+   { 0x00600041, 0x208077bd, 0x008d0080, 0x00000060 },
+   { 0x00600041, 0x20a077bd, 0x008d00a0, 0x00000060 },
+   { 0x00600040, 0x208077bd, 0x008d0080, 0x0000006c },
+   { 0x00600040, 0x20a077bd, 0x008d00a0, 0x0000006c },
+   { 0x00600040, 0x20c077bd, 0x008d00c0, 0x00004024 },
+   { 0x00600040, 0x20e077bd, 0x008d00e0, 0x00004024 },
+   { 0x00600041, 0x20c077bd, 0x008d00c0, 0x00000074 },
+   { 0x00600041, 0x20e077bd, 0x008d00e0, 0x00000074 },
+   { 0x00600040, 0x20c077bd, 0x008d00c0, 0x0000007c },
+   { 0x00600040, 0x20e077bd, 0x008d00e0, 0x0000007c },
+   { 0x00600001, 0x202003be, 0x008d0080, 0x00000000 },
+   { 0x00600001, 0x204003be, 0x008d00a0, 0x00000000 },
+   { 0x00600001, 0x206003be, 0x008d00c0, 0x00000000 },
+   { 0x00600001, 0x208003be, 0x008d00e0, 0x00000000 },
+   { 0x00800031, 0x21801d29, 0x008d0000, 0x02580001 },
+   { 0x00600001, 0x202003be, 0x008d0020, 0x00000000 },
+   { 0x00600001, 0x204003be, 0x008d0180, 0x00000000 },
+   { 0x00600001, 0x206003be, 0x008d01c0, 0x00000000 },
+   { 0x00600001, 0x208003be, 0x008d0200, 0x00000000 },
+   { 0x00600001, 0x20a003be, 0x008d0240, 0x00000000 },
+   { 0x00600001, 0x20c003be, 0x008d01a0, 0x00000000 },
+   { 0x00600001, 0x20e003be, 0x008d01e0, 0x00000000 },
+   { 0x00600001, 0x210003be, 0x008d0220, 0x00000000 },
+   { 0x00600001, 0x212003be, 0x008d0260, 0x00000000 },
+   { 0x00800031, 0x20001d3c, 0x008d0000, 0x85a04800 },
+   { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
+   { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
+   { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
+   { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
+   { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
+   { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
+   { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
+   { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
+   { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
diff --git a/src/i965_exa_render.c b/src/i965_exa_render.c
index dfa9a04..b56bf7f 100644
--- a/src/i965_exa_render.c
+++ b/src/i965_exa_render.c
@@ -68,6 +68,9 @@ extern void
 I965EXAComposite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY,
 		int dstX, int dstY, int width, int height);
 
+static void I965GetBlendCntl(int op, PicturePtr pMask, CARD32 dst_format, 
+			     CARD32 *sblend, CARD32 *dblend);
+
 extern float scale_units[2][2];
 extern Bool is_transform[2];
 extern PictTransform *transform[2];
@@ -90,31 +93,31 @@ struct formatinfo {
 /* defined in brw_defines.h */
 static struct blendinfo I965BlendOp[] = { 
     /* Clear */
-    {0, 0, BRW_BLENDFACT_ZERO,          BRW_BLENDFACT_ZERO},
+    {0, 0, BRW_BLENDFACTOR_ZERO,          BRW_BLENDFACTOR_ZERO},
     /* Src */
-    {0, 0, BRW_BLENDFACT_ONE,           BRW_BLENDFACT_ZERO},
+    {0, 0, BRW_BLENDFACTOR_ONE,           BRW_BLENDFACTOR_ZERO},
     /* Dst */
-    {0, 0, BRW_BLENDFACT_ZERO,          BRW_BLENDFACT_ONE},
+    {0, 0, BRW_BLENDFACTOR_ZERO,          BRW_BLENDFACTOR_ONE},
     /* Over */
-    {0, 1, BRW_BLENDFACT_ONE,           BRW_BLENDFACT_INV_SRC_ALPHA},
+    {0, 1, BRW_BLENDFACTOR_ONE,           BRW_BLENDFACTOR_INV_SRC_ALPHA},
     /* OverReverse */
-    {1, 0, BRW_BLENDFACT_INV_DST_ALPHA, BRW_BLENDFACT_ONE},
+    {1, 0, BRW_BLENDFACTOR_INV_DST_ALPHA, BRW_BLENDFACTOR_ONE},
     /* In */
-    {1, 0, BRW_BLENDFACT_DST_ALPHA,     BRW_BLENDFACT_ZERO},
+    {1, 0, BRW_BLENDFACTOR_DST_ALPHA,     BRW_BLENDFACTOR_ZERO},
     /* InReverse */
-    {0, 1, BRW_BLENDFACT_ZERO,          BRW_BLENDFACT_SRC_ALPHA},
+    {0, 1, BRW_BLENDFACTOR_ZERO,          BRW_BLENDFACTOR_SRC_ALPHA},
     /* Out */
-    {1, 0, BRW_BLENDFACT_INV_DST_ALPHA, BRW_BLENDFACT_ZERO},
+    {1, 0, BRW_BLENDFACTOR_INV_DST_ALPHA, BRW_BLENDFACTOR_ZERO},
     /* OutReverse */
-    {0, 1, BRW_BLENDFACT_ZERO,          BRW_BLENDFACT_INV_SRC_ALPHA},
+    {0, 1, BRW_BLENDFACTOR_ZERO,          BRW_BLENDFACTOR_INV_SRC_ALPHA},
     /* Atop */
-    {1, 1, BRW_BLENDFACT_DST_ALPHA,     BRW_BLENDFACT_INV_SRC_ALPHA},
+    {1, 1, BRW_BLENDFACTOR_DST_ALPHA,     BRW_BLENDFACTOR_INV_SRC_ALPHA},
     /* AtopReverse */
-    {1, 1, BRW_BLENDFACT_INV_DST_ALPHA, BRW_BLENDFACT_SRC_ALPHA},
+    {1, 1, BRW_BLENDFACTOR_INV_DST_ALPHA, BRW_BLENDFACTOR_SRC_ALPHA},
     /* Xor */
-    {1, 1, BRW_BLENDFACT_INV_DST_ALPHA, BRW_BLENDFACT_INV_SRC_ALPHA},
+    {1, 1, BRW_BLENDFACTOR_INV_DST_ALPHA, BRW_BLENDFACTOR_INV_SRC_ALPHA},
     /* Add */
-    {0, 0, BRW_BLENDFACT_ONE,           BRW_BLENDFACT_ONE},
+    {0, 0, BRW_BLENDFACTOR_ONE,           BRW_BLENDFACTOR_ONE},
 };
 
 /* FIXME: surface format defined in brw_defines.h, shared Sampling engine 1.7.2*/
@@ -124,8 +127,8 @@ static struct formatinfo I965TexFormats[
         {PICT_a8b8g8r8, BRW_SURFACEFORMAT_B8G8R8A8_UNORM },
         {PICT_x8b8g8r8, BRW_SURFACEFORMAT_B8G8R8X8_UNORM },
         {PICT_r5g6b5,   BRW_SURFACEFORMAT_B5G6R5_UNORM   },
-        {PICT_a1r5g5b5, BRW_SURFACEFORMAT_B5G6R5A1_UNORM },
-        {PICT_x1r5g5b5, BRW_SURFACEFORMAT_B5G6R5X1_UNORM },
+        {PICT_a1r5g5b5, BRW_SURFACEFORMAT_B5G5R5A1_UNORM },
+        {PICT_x1r5g5b5, BRW_SURFACEFORMAT_B5G5R5X1_UNORM },
         {PICT_a8,       BRW_SURFACEFORMAT_A8_UNORM	 },
 };
 
@@ -140,10 +143,10 @@ static void I965GetBlendCntl(int op, Pic
      * it as always 1.
      */
     if (PICT_FORMAT_A(dst_format) == 0 && I965BlendOp[op].dst_alpha) {
-        if (*sblend == BRW_BLENDFACT_DST_ALPHA)
-            *sblend = BRW_BLENDFACT_ONE;
-        else if (*sblend == BRW_BLENDFACT_INV_DST_ALPHA)
-            *sblend = BRW_BLENDFACT_ZERO;
+        if (*sblend == BRW_BLENDFACTOR_DST_ALPHA)
+            *sblend = BRW_BLENDFACTOR_ONE;
+        else if (*sblend == BRW_BLENDFACTOR_INV_DST_ALPHA)
+            *sblend = BRW_BLENDFACTOR_ZERO;
     }
 
     /* If the source alpha is being used, then we should only be in a case where
@@ -151,10 +154,10 @@ static void I965GetBlendCntl(int op, Pic
      * channels multiplied by the source picture's alpha.
      */
     if (pMask && pMask->componentAlpha && I965BlendOp[op].src_alpha) {
-        if (*dblend == BRW_BLENDFACT_SRC_ALPHA) {
-	    *dblend = BRW_BLENDFACT_SRC_COLR;
-        } else if (*dblend == BRW_BLENDFACT_INV_SRC_ALPHA) {
-	    *dblend = BRW_BLENDFACT_INV_SRC_COLR;
+        if (*dblend == BRW_BLENDFACTOR_SRC_ALPHA) {
+	    *dblend = BRW_BLENDFACTOR_SRC_COLOR;
+        } else if (*dblend == BRW_BLENDFACTOR_INV_SRC_ALPHA) {
+	    *dblend = BRW_BLENDFACTOR_INV_SRC_COLOR;
         }
     }
 
@@ -173,10 +176,10 @@ static Bool I965GetDestFormat(PicturePtr
         *dst_format = BRW_SURFACEFORMAT_B5G6R5_UNORM;
         break;
     case PICT_a1r5g5b5:
-    	*dst_format = BRW_SURFACEFORMAT_B5G6R5A1_UNORM;
+    	*dst_format = BRW_SURFACEFORMAT_B5G5R5A1_UNORM;
 	break;
     case PICT_x1r5g5b5:
-        *dst_format = BRW_SURFACEFORMAT_B5G6R5X1_UNORM;
+        *dst_format = BRW_SURFACEFORMAT_B5G5R5X1_UNORM;
         break;
     /* COLR_BUF_8BIT is special for YUV surfaces.  While we may end up being
      * able to use it depending on how the hardware implements it, disable it
@@ -250,7 +253,7 @@ I965EXACheckComposite(int op, PicturePtr
          * source value that we get to blend with.
          */
         if (I965BlendOp[op].src_alpha &&
-            (I965BlendOp[op].src_blend != BRW_BLENDFACT_ZERO))
+            (I965BlendOp[op].src_blend != BRW_BLENDFACTOR_ZERO))
             	I830FALLBACK("Component alpha not supported with source "
                             "alpha and source value blending.\n");
 	/* XXX: fallback now for mask with componentAlpha */
@@ -297,7 +300,7 @@ struct brw_instruction *sip_kernel;
 CARD32 *binding_table;
 int binding_table_entries; 
 
-int dest_surf_offset, src_surf_offset;
+int dest_surf_offset, src_surf_offset, mask_surf_offset;
 int src_sampler_offset, mask_sampler_offset,vs_offset;
 int sf_offset, wm_offset, cc_offset, vb_offset, cc_viewport_offset;
 int sf_kernel_offset, ps_kernel_offset, sip_kernel_offset;
@@ -308,7 +311,7 @@ int state_base_offset;
 float *vb;
 int vb_size = 4 * 4 ; /* 4 DWORDS per vertex, 4 vertices for TRIFAN*/ 
 
-int src_blend, dst_blend;
+CARD32 src_blend, dst_blend;
 
 static const CARD32 sip_kernel_static[][4] = {
 /*    wait (1) a0<1>UW a145<0,1,0>UW { align1 +  } */
@@ -380,6 +383,8 @@ static const CARD32 sf_kernel_static[][4
 };
 
 /* ps kernels */
+#define PS_KERNEL_NUM_GRF   32
+#define PS_MAX_THREADS	   32
 /* 1: no mask */
 static const CARD32 ps_kernel_static_nomask [][4] = {
 	#include "i965_composite_wm_nomask.h"
@@ -387,12 +392,12 @@ static const CARD32 ps_kernel_static_nom
 
 /* 2: mask with componentAlpha, src * mask color, XXX: later */
 static const CARD32 ps_kernel_static_maskca [][4] = {
-	#include "i965_composite_wm_maskca.h"
+/*#include "i965_composite_wm_maskca.h" */
 };
 
 /* 3: mask without componentAlpha, src * mask alpha */
 static const CARD32 ps_kernel_static_masknoca [][4] = {
-	#include "i965_composite_wm_masknoca.h"
+/*#include "i965_composite_wm_masknoca.h" */
 };
 
 Bool
@@ -403,9 +408,8 @@ I965EXAPrepareComposite(int op, PictureP
     ScrnInfoPtr pScrn = xf86Screens[pSrcPicture->pDrawable->pScreen->myNum];
     I830Ptr pI830 = I830PTR(pScrn);
     CARD32 src_offset, src_pitch;
-    CARD32 mask_offset, mask_pitch;
+    CARD32 mask_offset = 0, mask_pitch = 0;
     CARD32 dst_format, dst_offset, dst_pitch;
-    CARD32 blendctl;
  
 ErrorF("i965 prepareComposite\n");
 
@@ -437,7 +441,6 @@ ErrorF("i965 prepareComposite\n");
 	scale_units[1][1] = pMask->drawable.height;
     }
 
-/* FIXME */
 	/* setup 3d pipeline state */
 
    binding_table_entries = 2; /* default no mask */
@@ -602,7 +605,7 @@ ErrorF("i965 prepareComposite\n");
 //   cc_state->cc5.ia_src_blend_factor = BRW_BLENDFACTOR_ONE;
 //   cc_state->cc5.ia_dest_blend_factor = BRW_BLENDFACTOR_ONE;
    cc_state->cc6.blend_function = BRW_BLENDFUNCTION_ADD;
-   I965GetBlendCntl(op, pMask, pDstPicture->format, 
+   I965GetBlendCntl(op, pMaskPicture, pDstPicture->format, 
 		    &src_blend, &dst_blend);
    cc_state->cc6.src_blend_factor = src_blend;
    cc_state->cc6.dest_blend_factor = dst_blend;
@@ -703,7 +706,7 @@ ErrorF("i965 prepareComposite\n");
 
    /* PS kernel use this sampler */
    memset(src_sampler_state, 0, sizeof(*src_sampler_state));
-   src_sampler_state->ss0.lod_peclamp = 1; /* GL mode */
+   src_sampler_state->ss0.lod_preclamp = 1; /* GL mode */
    switch(pSrcPicture->filter) {
    case PictFilterNearest:
    	src_sampler_state->ss0.min_filter = BRW_MAPFILTER_NEAREST; 
@@ -733,7 +736,7 @@ ErrorF("i965 prepareComposite\n");
 
    if (pMask) {
    	memset(mask_sampler_state, 0, sizeof(*mask_sampler_state));
-   	mask_sampler_state->ss0.lod_peclamp = 1; /* GL mode */
+   	mask_sampler_state->ss0.lod_preclamp = 1; /* GL mode */
    	switch(pMaskPicture->filter) {
    	case PictFilterNearest:
    	    mask_sampler_state->ss0.min_filter = BRW_MAPFILTER_NEAREST; 
@@ -1065,6 +1068,8 @@ void
 I965EXAComposite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY,
 		int dstX, int dstY, int w, int h)
 {
+    ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum];
+    I830Ptr pI830 = I830PTR(pScrn);
     int srcXend, srcYend, maskXend, maskYend;
     PictVector v;
     int pMask = 1, i = 0;
diff-tree c3a49b5123d094280b5ff358ceef961958319ce4 (from 185df8a18102eea79b8c8e11304dfee148ac2002)
Author: Wang Zhenyu <zhenyu.z.wang at intel.com>
Date:   Thu Sep 28 10:36:00 2006 +0800

    Add simplest wm kernel program for no mask picture composite
    
    This is a try to use new gen4asm language, and will finish
    composite program for mask picture with or without CA case later.

diff --git a/src/Makefile.am b/src/Makefile.am
index f08d9a7..e7132bc 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -77,6 +77,8 @@ sf_prog.h: packed_yuv_sf.g4a
 	intel-gen4asm -o sf_prog.h packed_yuv_sf.g4a
 wm_prog.h: packed_yuv_wm.g4a
 	intel-gen4asm -o wm_prog.h packed_yuv_wm.g4a
+i965_composite_wm_nomask.h: i965_composite_wm_nomask.g4a
+	intel-gen4asm -o i965_composite_wm_nomask.h i965_composite_wm_nomask.g4a
 endif
 
 if DRI
diff --git a/src/i965_composite_wm_nomask.g4a b/src/i965_composite_wm_nomask.g4a
new file mode 100644
index 0000000..8791631
--- /dev/null
+++ b/src/i965_composite_wm_nomask.g4a
@@ -0,0 +1,139 @@
+/*
+ * This's for exa composite operation in no mask picture case.
+ * The simplest case is just sending what src picture has to dst picture
+ */
+
+/* I think this should be same as in g4a program for texture video,
+   as we also use 16-pixel dispatch. and SF scale in g3 is useful for us. */
+
+/* The initial payload of the thread is always g0.
+ * WM_URB (incoming URB entries) is g3
+ * X0_R is g4
+ * X1_R is g5
+ * Y0_R is g6
+ * Y1_R is g7
+ */
+
+    /* Set up ss0.x coordinates*/
+mov (1) g4<1>F g1.8<0,1,0>UW { align1 };
+add (1) g4.4<1>F g1.8<0,1,0>UW 1UB { align1 };
+mov (1) g4.8<1>F g1.8<0,1,0>UW { align1 };
+add (1) g4.12<1>F g1.8<0,1,0>UW 1UB { align1 };
+    /* Set up ss0.y coordinates */
+mov (1) g6<1>F g1.10<0,1,0>UW { align1 };
+mov (1) g6.4<1>F g1.10<0,1,0>UW { align1 };
+add (1) g6.8<1>F g1.10<0,1,0>UW 1UB { align1 };
+add (1) g6.12<1>F g1.10<0,1,0>UW 1UB { align1 };
+    /* set up ss1.x coordinates */
+mov (1) g4.16<1>F g1.12<0,1,0>UW { align1 };
+add (1) g4.20<1>F g1.12<0,1,0>UW 1UB { align1 };
+mov (1) g4.24<1>F g1.12<0,1,0>UW { align1 };
+add (1) g4.28<1>F g1.12<0,1,0>UW 1UB { align1 };
+    /* set up ss1.y coordinates */
+mov (1) g6.16<1>F g1.14<0,1,0>UW { align1 };
+mov (1) g6.20<1>F g1.14<0,1,0>UW { align1 };
+add (1) g6.24<1>F g1.14<0,1,0>UW 1UB { align1 };
+add (1) g6.28<1>F g1.14<0,1,0>UW 1UB { align1 };
+    /* Set up ss2.x coordinates */
+mov (1) g5<1>F g1.16<0,1,0>UW { align1 };
+add (1) g5.4<1>F g1.16<0,1,0>UW 1UB { align1 };
+mov (1) g5.8<1>F g1.16<0,1,0>UW { align1 };
+add (1) g5.12<1>F g1.16<0,1,0>UW 1UB { align1 };
+    /* Set up ss2.y coordinates */
+mov (1) g7<1>F g1.18<0,1,0>UW { align1 };
+mov (1) g7.4<1>F g1.18<0,1,0>UW { align1 };
+add (1) g7.8<1>F g1.18<0,1,0>UW 1UB { align1 };
+add (1) g7.12<1>F g1.18<0,1,0>UW 1UB { align1 };
+    /* Set up ss3.x coordinates */
+mov (1) g5.16<1>F g1.20<0,1,0>UW { align1 };
+add (1) g5.20<1>F g1.20<0,1,0>UW 1UB { align1 };
+mov (1) g5.24<1>F g1.20<0,1,0>UW { align1 };
+add (1) g5.28<1>F g1.20<0,1,0>UW 1UB { align1 };
+    /* Set up ss3.y coordinates */
+mov (1) g7.16<1>F g1.22<0,1,0>UW { align1 };
+mov (1) g7.20<1>F g1.22<0,1,0>UW { align1 };
+add (1) g7.24<1>F g1.22<0,1,0>UW 1UB { align1 };
+add (1) g7.28<1>F g1.22<0,1,0>UW 1UB { align1 };
+
+    /* Now, map these screen space coordinates into texture coordinates. */
+    /* subtract screen-space X origin of vertex 0. */
+add (8) g4<1>F g4<8,8,1>F -g1<0,1,0>F { align1 };
+add (8) g5<1>F g5<8,8,1>F -g1<0,1,0>F { align1 };
+    /* scale by texture X increment */
+mul (8) g4<1>F g4<8,8,1>F g3<0,1,0>F { align1 };
+mul (8) g5<1>F g5<8,8,1>F g3<0,1,0>F { align1 };
+    /* add in texture X offset */
+add (8) g4<1>F g4<8,8,1>F g3.12<0,1,0>F { align1 };
+add (8) g5<1>F g5<8,8,1>F g3.12<0,1,0>F { align1 };
+    /* subtract screen-space Y origin of vertex 0. */
+add (8) g6<1>F g6<8,8,1>F -g1.4<0,1,0>F { align1 };
+add (8) g7<1>F g7<8,8,1>F -g1.4<0,1,0>F { align1 };
+    /* scale by texture Y increment */
+mul (8) g6<1>F g6<8,8,1>F g3.20<0,1,0>F { align1 };
+mul (8) g7<1>F g7<8,8,1>F g3.20<0,1,0>F { align1 };
+    /* add in texture Y offset */
+add (8) g6<1>F g6<8,8,1>F g3.28<0,1,0>F { align1 };
+add (8) g7<1>F g7<8,8,1>F g3.28<0,1,0>F { align1 };
+
+/* prepare sampler read back gX register, which would be written back to output */
+
+/* use simd16 sampler, param 0 is u, param 1 is v. */
+/* 'payload' loading, assuming tex coord start from g4 */
+mov (8) m1<1>F g4<8,8,1>F { align1 };
+mov (8) m2<1>F g5<8,8,1>F { align1 };  /* param 0 u in m1, m2 */
+mov (8) m3<1>F g6<8,8,1>F { align1 };
+mov (8) m4<1>F g7<8,8,1>F { align1 };  /* param 1 v in m3, m4 */
+
+/* m0 will be copied with g0, as it contains send desc */
+/* emit sampler 'send' cmd */
+send (16) 0 		/* msg reg index */
+	g12<1>UW 	/* readback */
+	g0<8,8,1>UW  	/* copy to msg start reg*/
+	sampler (1,0,F)  /* sampler message description, (binding_table,sampler_index,datatype)
+			 /* here(src->dst) we should use src_sampler and src_surface */
+	mlen 5 rlen 8 { align1 };   /* required message len 5, readback len 8 */
+
+/* if we set up read-back reg correctly, emit dataport write 'send' cmd with EOT */
+
+/* m0, m1 are all direct passed by PS thread payload */
+mov (8) m1<1>F g1<8,8,1>F { align1 };
+
+/* prepare data in m2-m5 for subspan(1,0), m6-m9 for subspan(3,2), then it's ready to write */
+/* g12 -> m2
+   g13 -> m6
+   g14 -> m3
+   g15 -> m7
+   g16 -> m4
+   g17 -> m8
+   g18 -> m5
+   g19 -> m9
+*/
+mov (8) m2<1>F g12<8,8,1>F { align1 };
+mov (8) m3<1>F g14<8,8,1>F { align1 };
+mov (8) m4<1>F g16<8,8,1>F { align1 };
+mov (8) m5<1>F g18<8,8,1>F { align1 };
+mov (8) m6<1>F g13<8,8,1>F { align1 };
+mov (8) m7<1>F g15<8,8,1>F { align1 };
+mov (8) m8<1>F g17<8,8,1>F { align1 };
+mov (8) m9<1>F g19<8,8,1>F { align1 };
+
+/* write */
+send (16) 0 null g0<8,8,1>UW write (
+	0,  /* binding_table */
+	8,  /* pixel scordboard clear, msg type simd16 single source */
+	4,  /* render target write */
+	0   /* no write commit message */
+	) 
+	mlen 10
+	rlen 0
+	{ align1 EOT };
+
+nop;
+nop;
+nop;
+nop;
+nop;
+nop;
+nop;
+nop;
+nop;
diff-tree 185df8a18102eea79b8c8e11304dfee148ac2002 (from 1422d4f04ac2d57899eee91f6522f8670f7263da)
Author: Wang Zhenyu <zhenyu.z.wang at intel.com>
Date:   Wed Sep 27 16:48:43 2006 +0800

    Add mask sampler state

diff --git a/src/i965_exa_render.c b/src/i965_exa_render.c
index 942f0eb..dfa9a04 100644
--- a/src/i965_exa_render.c
+++ b/src/i965_exa_render.c
@@ -282,7 +282,7 @@ struct brw_surface_state *dest_surf_stat
 struct brw_surface_state *src_surf_state;
 struct brw_surface_state *mask_surf_state;
 struct brw_sampler_state *src_sampler_state;
-struct brw_sampler_state *mask_sampler_state;  // could just use one sampler?
+struct brw_sampler_state *mask_sampler_state;  
 
 struct brw_vs_unit_state *vs_state;
 struct brw_sf_unit_state *sf_state;
@@ -297,7 +297,8 @@ struct brw_instruction *sip_kernel;
 CARD32 *binding_table;
 int binding_table_entries; 
 
-int dest_surf_offset, src_surf_offset, src_sampler_offset, vs_offset;
+int dest_surf_offset, src_surf_offset;
+int src_sampler_offset, mask_sampler_offset,vs_offset;
 int sf_offset, wm_offset, cc_offset, vb_offset, cc_viewport_offset;
 int sf_kernel_offset, ps_kernel_offset, sip_kernel_offset;
 int binding_table_offset;
@@ -381,17 +382,17 @@ static const CARD32 sf_kernel_static[][4
 /* ps kernels */
 /* 1: no mask */
 static const CARD32 ps_kernel_static_nomask [][4] = {
-	#include "i965_composite_ps_nomask.h"
+	#include "i965_composite_wm_nomask.h"
 };
 
 /* 2: mask with componentAlpha, src * mask color, XXX: later */
 static const CARD32 ps_kernel_static_maskca [][4] = {
-	#include "i965_composite_ps_maskca.h"
+	#include "i965_composite_wm_maskca.h"
 };
 
 /* 3: mask without componentAlpha, src * mask alpha */
 static const CARD32 ps_kernel_static_masknoca [][4] = {
-	#include "i965_composite_ps_masknoca.h"
+	#include "i965_composite_wm_masknoca.h"
 };
 
 Bool
@@ -478,11 +479,14 @@ ErrorF("i965 prepareComposite\n");
    cc_viewport_offset = ALIGN(next_offset, 32);
    next_offset = cc_viewport_offset + sizeof(*cc_viewport);
 
-   // : fix for texture sampler
-   // XXX: -> use only one sampler
+   // for texture sampler
    src_sampler_offset = ALIGN(next_offset, 32);
    next_offset = src_sampler_offset + sizeof(*src_sampler_state);
 
+   if (pMask) {
+   	mask_sampler_offset = ALIGN(next_offset, 32);
+   	next_offset = mask_sampler_offset + sizeof(*mask_sampler_state);
+   }
    /* Align VB to native size of elements, for safety */
    vb_offset = ALIGN(next_offset, 8);
    next_offset = vb_offset + vb_size;
@@ -536,6 +540,9 @@ ErrorF("i965 prepareComposite\n");
 	mask_surf_state = (void *)(state_base + mask_surf_offset);
 
    src_sampler_state = (void *)(state_base + src_sampler_offset);
+   if (pMask)
+	mask_sampler_state = (void *)(state_base + mask_sampler_offset);
+
    binding_table = (void *)(state_base + binding_table_offset);
 
    vb = (void *)(state_base + vb_offset);
@@ -724,6 +731,37 @@ ErrorF("i965 prepareComposite\n");
     	   and just a single texel tex map, with R32G32B32A32_FLOAT */
    src_sampler_state->ss3.chroma_key_enable = 0; /* disable chromakey */
 
+   if (pMask) {
+   	memset(mask_sampler_state, 0, sizeof(*mask_sampler_state));
+   	mask_sampler_state->ss0.lod_peclamp = 1; /* GL mode */
+   	switch(pMaskPicture->filter) {
+   	case PictFilterNearest:
+   	    mask_sampler_state->ss0.min_filter = BRW_MAPFILTER_NEAREST; 
+   	    mask_sampler_state->ss0.mag_filter = BRW_MAPFILTER_NEAREST;
+	    break;
+   	case PictFilterBilinear:
+   	    mask_sampler_state->ss0.min_filter = BRW_MAPFILTER_LINEAR; 
+   	    mask_sampler_state->ss0.mag_filter = BRW_MAPFILTER_LINEAR;
+	    break;
+   	default:
+	    I830FALLBACK("Bad filter 0x%x\n", pMaskPicture->filter);
+   	}
+
+   	if (!pMaskPicture->repeat) {
+	/* XXX: clamp_border and set border to 0 */
+   	    mask_sampler_state->ss1.r_wrap_mode = BRW_TEXCOORDMODE_CLAMP; 
+   	    mask_sampler_state->ss1.s_wrap_mode = BRW_TEXCOORDMODE_CLAMP;
+   	    mask_sampler_state->ss1.t_wrap_mode = BRW_TEXCOORDMODE_CLAMP;
+   	} else {
+   	    mask_sampler_state->ss1.r_wrap_mode = BRW_TEXCOORDMODE_WRAP; 
+   	    mask_sampler_state->ss1.s_wrap_mode = BRW_TEXCOORDMODE_WRAP;
+   	    mask_sampler_state->ss1.t_wrap_mode = BRW_TEXCOORDMODE_WRAP;
+    	}
+   /* XXX: ss2 has border color pointer, which should be in general state address,
+    	   and just a single texel tex map, with R32G32B32A32_FLOAT */
+   	mask_sampler_state->ss3.chroma_key_enable = 0; /* disable chromakey */
+   }
+
    /* Set up the vertex shader to be disabled (passthrough) */
    memset(vs_state, 0, sizeof(*vs_state));
    // XXX: vs URB should be defined for VF vertex URB store. done already?
@@ -783,26 +821,26 @@ ErrorF("i965 prepareComposite\n");
    wm_state->thread0.grf_reg_count = ((PS_KERNEL_NUM_GRF & ~15) / 16);
    wm_state->thread1.single_program_flow = 1;
    if (!pMask)
-       wm_state->thread1.binding_table_entry_count = 2; /* tex and fb */
+       wm_state->thread1.binding_table_entry_count = 2; /* 1 tex and fb */
    else
-       wm_state->thread1.binding_table_entry_count = 3; /* tex and fb */
+       wm_state->thread1.binding_table_entry_count = 3; /* 2 tex and fb */
 
    wm_state->thread2.scratch_space_base_pointer = 0;
    wm_state->thread2.per_thread_scratch_space = 0;
    // XXX: urb allocation
-   wm_state->thread3.dispatch_grf_start_reg = 3; /* must match kernel */
-   // wm kernel use urb from 3, see wm_program in compiler module
-   wm_state->thread3.urb_entry_read_length = 1;  /* one per pair of attrib */
    wm_state->thread3.const_urb_entry_read_length = 0;
    wm_state->thread3.const_urb_entry_read_offset = 0;
+   wm_state->thread3.urb_entry_read_length = 1;  /* one per pair of attrib */
    wm_state->thread3.urb_entry_read_offset = 0;
+   // wm kernel use urb from 3, see wm_program in compiler module
+   wm_state->thread3.dispatch_grf_start_reg = 3; /* must match kernel */
 
-   wm_state->wm4.stats_enable = 1;
-   wm_state->wm4.sampler_state_pointer = (state_base_offset + src_sampler_offset) >> 5;
+   wm_state->wm4.stats_enable = 1;  /* statistic */
+   wm_state->wm4.sampler_state_pointer = (state_base_offset + src_sampler_offset) >> 5; 
    wm_state->wm4.sampler_count = 1; /* 1-4 samplers used */
    wm_state->wm5.max_threads = PS_MAX_THREADS - 1;
    wm_state->wm5.thread_dispatch_enable = 1;
-   //just use 16-pixel dispatch, don't need to change kernel start point
+   //just use 16-pixel dispatch (4 subspans), don't need to change kernel start point
    wm_state->wm5.enable_16_pix = 1;
    wm_state->wm5.enable_8_pix = 0;
    wm_state->wm5.early_depth_test = 1;
diff-tree 1422d4f04ac2d57899eee91f6522f8670f7263da (from 52a4f2a02b8f38108bfa866bf74b1596b8125512)
Author: Wang Zhenyu <zhenyu.z.wang at intel.com>
Date:   Wed Sep 27 13:54:14 2006 +0800

    change some src sampler states
    
    sampler for mask should also be set up, and fix
    default border texel.

diff --git a/src/i965_exa_render.c b/src/i965_exa_render.c
index 24e0ba2..942f0eb 100644
--- a/src/i965_exa_render.c
+++ b/src/i965_exa_render.c
@@ -546,8 +546,8 @@ ErrorF("i965 prepareComposite\n");
 #define URB_CS_ENTRY_SIZE     0
 #define URB_CS_ENTRIES	      0
    
-#define URB_VS_ENTRY_SIZE     1	  // XXX: VUE row num? double check, 1 row is enough
-#define URB_VS_ENTRIES	      8
+#define URB_VS_ENTRY_SIZE     1	  // each 512-bit row
+#define URB_VS_ENTRIES	      8	  // we needs at least 8 entries
    
 #define URB_GS_ENTRY_SIZE     0
 #define URB_GS_ENTRIES	      0
@@ -630,6 +630,7 @@ ErrorF("i965 prepareComposite\n");
    dest_surf_state->ss2.mip_count = 0;
    dest_surf_state->ss2.render_target_rotation = 0;
    dest_surf_state->ss3.pitch = dst_pitch - 1; 
+   // tiled surface?
 
    /* Set up the source surface state buffer */
    memset(src_surf_state, 0, sizeof(*src_surf_state));
@@ -695,19 +696,33 @@ ErrorF("i965 prepareComposite\n");
 
    /* PS kernel use this sampler */
    memset(src_sampler_state, 0, sizeof(*src_sampler_state));
-   src_sampler_state->ss0.min_filter = BRW_MAPFILTER_LINEAR;
-   src_sampler_state->ss0.mag_filter = BRW_MAPFILTER_LINEAR;
+   src_sampler_state->ss0.lod_peclamp = 1; /* GL mode */
+   switch(pSrcPicture->filter) {
+   case PictFilterNearest:
+   	src_sampler_state->ss0.min_filter = BRW_MAPFILTER_NEAREST; 
+   	src_sampler_state->ss0.mag_filter = BRW_MAPFILTER_NEAREST;
+	break;
+   case PictFilterBilinear:
+   	src_sampler_state->ss0.min_filter = BRW_MAPFILTER_LINEAR; 
+   	src_sampler_state->ss0.mag_filter = BRW_MAPFILTER_LINEAR;
+	break;
+   default:
+	I830FALLBACK("Bad filter 0x%x\n", pSrcPicture->filter);
+   }
 
-   /* XXX: fix for repeat */
    if (!pSrcPicture->repeat) {
-   	src_sampler_state->ss1.r_wrap_mode = BRW_TEXCOORDMODE_CLAMP; // XXX: clamp_border and set border to 0?
+	/* XXX: clamp_border and set border to 0 */
+   	src_sampler_state->ss1.r_wrap_mode = BRW_TEXCOORDMODE_CLAMP; 
    	src_sampler_state->ss1.s_wrap_mode = BRW_TEXCOORDMODE_CLAMP;
    	src_sampler_state->ss1.t_wrap_mode = BRW_TEXCOORDMODE_CLAMP;
    } else {
-   	src_sampler_state->ss1.r_wrap_mode = BRW_TEXCOORDMODE_WRAP; // XXX: clamp_border and set border to 0?
+   	src_sampler_state->ss1.r_wrap_mode = BRW_TEXCOORDMODE_WRAP; 
    	src_sampler_state->ss1.s_wrap_mode = BRW_TEXCOORDMODE_WRAP;
    	src_sampler_state->ss1.t_wrap_mode = BRW_TEXCOORDMODE_WRAP;
    }
+   /* XXX: ss2 has border color pointer, which should be in general state address,
+    	   and just a single texel tex map, with R32G32B32A32_FLOAT */
+   src_sampler_state->ss3.chroma_key_enable = 0; /* disable chromakey */
 
    /* Set up the vertex shader to be disabled (passthrough) */
    memset(vs_state, 0, sizeof(*vs_state));
diff-tree 52a4f2a02b8f38108bfa866bf74b1596b8125512 (from f272f0d811f9ee059e8f8617a516e6c8bff917a1)
Author: Wang Zhenyu <zhenyu.z.wang at intel.com>
Date:   Mon Sep 25 14:35:51 2006 +0800

    Add file for i965 exa composite
    
    This does not include ps program, which will be added
    in g4a form.

diff --git a/src/Makefile.am b/src/Makefile.am
index 163cc3f..f08d9a7 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -69,7 +69,8 @@ i810_drv_la_SOURCES = \
 	 i830_exa.c \
 	 i830_xaa.c \
 	 i830_exa_render.c \
-	 i915_exa_render.c
+	 i915_exa_render.c \
+	 i965_exa_render.c
 
 if HAVE_GEN4ASM
 sf_prog.h: packed_yuv_sf.g4a
diff --git a/src/i830_exa.c b/src/i830_exa.c
index a1c7546..9b2e6b2 100644
--- a/src/i830_exa.c
+++ b/src/i830_exa.c
@@ -120,6 +120,11 @@ extern Bool I915EXACheckComposite(int, P
 extern Bool I915EXAPrepareComposite(int, PicturePtr, PicturePtr, PicturePtr, 
 				PixmapPtr, PixmapPtr, PixmapPtr);
 
+extern Bool I965EXACheckComposite(int, PicturePtr, PicturePtr, PicturePtr);
+extern Bool I965EXAPrepareComposite(int, PicturePtr, PicturePtr, PicturePtr, 
+				PixmapPtr, PixmapPtr, PixmapPtr);
+extern void I965EXAComposite(PixmapPtr pDst, int srcX, int srcY, int maskX, 
+			int maskY, int dstX, int dstY, int width, int height);
 /**
  * I830EXASync - wait for a command to finish
  * @pScreen: current screen
@@ -418,6 +423,8 @@ IntelEXADoneComposite(PixmapPtr pDst)
     I830Sync(pScrn);
 #endif
 }
+
+#define BRW_LINEAR_EXTRA (32*1024)
 /*
  * TODO:
  *   - Dual head?
@@ -440,7 +447,11 @@ I830EXAInit(ScreenPtr pScreen)
     pI830->EXADriverPtr->exa_minor = 0;
     pI830->EXADriverPtr->memoryBase = pI830->FbBase;
     pI830->EXADriverPtr->offScreenBase = pI830->Offscreen.Start;
-    pI830->EXADriverPtr->memorySize = pI830->Offscreen.End;
+    if (IS_I965G(pI830))
+    	pI830->EXADriverPtr->memorySize = pI830->Offscreen.End -
+					BRW_LINEAR_EXTRA; /* BRW needs state buffer*/
+    else
+    	pI830->EXADriverPtr->memorySize = pI830->Offscreen.End;
 	   
     DPRINTF(PFX, "EXA Mem: memoryBase 0x%x, end 0x%x, offscreen base 0x%x, memorySize 0x%x\n",
 		pI830->EXADriverPtr->memoryBase,
@@ -490,6 +501,11 @@ I830EXAInit(ScreenPtr pScreen)
     	pI830->EXADriverPtr->PrepareComposite = I830EXAPrepareComposite;
     	pI830->EXADriverPtr->Composite = IntelEXAComposite;
     	pI830->EXADriverPtr->DoneComposite = IntelEXADoneComposite;
+    } else if (IS_I965G(pI830)) {
+ 	pI830->EXADriverPtr->CheckComposite = I965EXACheckComposite;
+ 	pI830->EXADriverPtr->PrepareComposite = I965EXAPrepareComposite;
+ 	pI830->EXADriverPtr->Composite = I965EXAComposite;
+ 	pI830->EXADriverPtr->DoneComposite = IntelEXADoneComposite;
     }
 
     if(!exaDriverInit(pScreen, pI830->EXADriverPtr)) {
diff --git a/src/i965_exa_render.c b/src/i965_exa_render.c
new file mode 100644
index 0000000..24e0ba2
--- /dev/null
+++ b/src/i965_exa_render.c
@@ -0,0 +1,1124 @@
+/*
+ * Copyright © 2006 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ *    Wang Zhenyu <zhenyu.z.wang at intel.com>
+ *    Eric Anholt <eric at anholt.net>
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "xf86.h"
+#include "i830.h"
+#include "i915_reg.h"
+
+/* bring in brw structs */
+#include "brw_defines.h"
+#include "brw_structs.h"
+
+#ifdef I830DEBUG
+#define DEBUG_I830FALLBACK 1
+#endif
+
+#ifdef DEBUG_I830FALLBACK
+#define I830FALLBACK(s, arg...)				\
+do {							\
+	DPRINTF(PFX, "EXA fallback: " s "\n", ##arg); 	\
+	return FALSE;					\
+} while(0)
+#else
+#define I830FALLBACK(s, arg...) 			\
+do { 							\
+	return FALSE;					\
+} while(0) 
+#endif
+
+extern Bool
+I965EXACheckComposite(int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture,
+		      PicturePtr pDstPicture);
+
+extern Bool
+I965EXAPrepareComposite(int op, PicturePtr pSrcPicture,
+			PicturePtr pMaskPicture, PicturePtr pDstPicture,
+			PixmapPtr pSrc, PixmapPtr pMask, PixmapPtr pDst);
+
+extern void
+I965EXAComposite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY,
+		int dstX, int dstY, int width, int height);
+
+extern float scale_units[2][2];
+extern Bool is_transform[2];
+extern PictTransform *transform[2];
+
+struct blendinfo {
+    Bool dst_alpha;
+    Bool src_alpha;
+    CARD32 src_blend;
+    CARD32 dst_blend;
+};
+
+struct formatinfo {
+    int fmt;
+    CARD32 card_fmt;
+};
+
+// refer vol2, 3d rasterization 3.8.1
+
+/* XXX: bad!bad! broadwater has different blend factor definition */
+/* defined in brw_defines.h */
+static struct blendinfo I965BlendOp[] = { 
+    /* Clear */
+    {0, 0, BRW_BLENDFACT_ZERO,          BRW_BLENDFACT_ZERO},
+    /* Src */
+    {0, 0, BRW_BLENDFACT_ONE,           BRW_BLENDFACT_ZERO},
+    /* Dst */
+    {0, 0, BRW_BLENDFACT_ZERO,          BRW_BLENDFACT_ONE},
+    /* Over */
+    {0, 1, BRW_BLENDFACT_ONE,           BRW_BLENDFACT_INV_SRC_ALPHA},
+    /* OverReverse */
+    {1, 0, BRW_BLENDFACT_INV_DST_ALPHA, BRW_BLENDFACT_ONE},
+    /* In */
+    {1, 0, BRW_BLENDFACT_DST_ALPHA,     BRW_BLENDFACT_ZERO},
+    /* InReverse */
+    {0, 1, BRW_BLENDFACT_ZERO,          BRW_BLENDFACT_SRC_ALPHA},
+    /* Out */
+    {1, 0, BRW_BLENDFACT_INV_DST_ALPHA, BRW_BLENDFACT_ZERO},
+    /* OutReverse */
+    {0, 1, BRW_BLENDFACT_ZERO,          BRW_BLENDFACT_INV_SRC_ALPHA},
+    /* Atop */
+    {1, 1, BRW_BLENDFACT_DST_ALPHA,     BRW_BLENDFACT_INV_SRC_ALPHA},
+    /* AtopReverse */
+    {1, 1, BRW_BLENDFACT_INV_DST_ALPHA, BRW_BLENDFACT_SRC_ALPHA},
+    /* Xor */
+    {1, 1, BRW_BLENDFACT_INV_DST_ALPHA, BRW_BLENDFACT_INV_SRC_ALPHA},
+    /* Add */
+    {0, 0, BRW_BLENDFACT_ONE,           BRW_BLENDFACT_ONE},
+};
+
+/* FIXME: surface format defined in brw_defines.h, shared Sampling engine 1.7.2*/
+static struct formatinfo I965TexFormats[] = {
+        {PICT_a8r8g8b8, BRW_SURFACEFORMAT_R8G8B8A8_UNORM },
+        {PICT_x8r8g8b8, BRW_SURFACEFORMAT_R8G8B8X8_UNORM },
+        {PICT_a8b8g8r8, BRW_SURFACEFORMAT_B8G8R8A8_UNORM },
+        {PICT_x8b8g8r8, BRW_SURFACEFORMAT_B8G8R8X8_UNORM },
+        {PICT_r5g6b5,   BRW_SURFACEFORMAT_B5G6R5_UNORM   },
+        {PICT_a1r5g5b5, BRW_SURFACEFORMAT_B5G6R5A1_UNORM },
+        {PICT_x1r5g5b5, BRW_SURFACEFORMAT_B5G6R5X1_UNORM },
+        {PICT_a8,       BRW_SURFACEFORMAT_A8_UNORM	 },
+};
+
+static void I965GetBlendCntl(int op, PicturePtr pMask, CARD32 dst_format, 
+			     CARD32 *sblend, CARD32 *dblend)
+{
+
+    *sblend = I965BlendOp[op].src_blend;
+    *dblend = I965BlendOp[op].dst_blend;
+
+    /* If there's no dst alpha channel, adjust the blend op so that we'll treat
+     * it as always 1.
+     */
+    if (PICT_FORMAT_A(dst_format) == 0 && I965BlendOp[op].dst_alpha) {
+        if (*sblend == BRW_BLENDFACT_DST_ALPHA)
+            *sblend = BRW_BLENDFACT_ONE;
+        else if (*sblend == BRW_BLENDFACT_INV_DST_ALPHA)
+            *sblend = BRW_BLENDFACT_ZERO;
+    }
+
+    /* If the source alpha is being used, then we should only be in a case where
+     * the source blend factor is 0, and the source blend value is the mask
+     * channels multiplied by the source picture's alpha.
+     */
+    if (pMask && pMask->componentAlpha && I965BlendOp[op].src_alpha) {
+        if (*dblend == BRW_BLENDFACT_SRC_ALPHA) {
+	    *dblend = BRW_BLENDFACT_SRC_COLR;
+        } else if (*dblend == BRW_BLENDFACT_INV_SRC_ALPHA) {
+	    *dblend = BRW_BLENDFACT_INV_SRC_COLR;
+        }
+    }
+
+}
+
+
+/* FIXME */
+static Bool I965GetDestFormat(PicturePtr pDstPicture, CARD32 *dst_format)
+{
+    switch (pDstPicture->format) {
+    case PICT_a8r8g8b8:
+    case PICT_x8r8g8b8:
+        *dst_format = BRW_SURFACEFORMAT_B8G8R8A8_UNORM;
+        break;
+    case PICT_r5g6b5:
+        *dst_format = BRW_SURFACEFORMAT_B5G6R5_UNORM;
+        break;
+    case PICT_a1r5g5b5:
+    	*dst_format = BRW_SURFACEFORMAT_B5G6R5A1_UNORM;
+	break;
+    case PICT_x1r5g5b5:
+        *dst_format = BRW_SURFACEFORMAT_B5G6R5X1_UNORM;
+        break;
+    /* COLR_BUF_8BIT is special for YUV surfaces.  While we may end up being
+     * able to use it depending on how the hardware implements it, disable it
+     * for now while we don't know what exactly it does (what channel does it
+     * read from?
+     */
+    /*
+    case PICT_a8:
+        *dst_format = COLR_BUF_8BIT;
+        break;
+    */
+    case PICT_a4r4g4b4:
+    case PICT_x4r4g4b4:
+	*dst_format = BRW_SURFACEFORMAT_B4G4R4A4_UNORM; 
+	break;
+    default:
+        I830FALLBACK("Unsupported dest format 0x%x\n",
+                        (int)pDstPicture->format);
+    }
+
+    return TRUE;
+}
+
+static Bool I965CheckCompositeTexture(PicturePtr pPict, int unit)
+{
+    int w = pPict->pDrawable->width;
+    int h = pPict->pDrawable->height;
+    int i;
+                                                                                                                                                            
+    if ((w > 0x7ff) || (h > 0x7ff))
+        I830FALLBACK("Picture w/h too large (%dx%d)\n", w, h);
+
+    for (i = 0; i < sizeof(I965TexFormats) / sizeof(I965TexFormats[0]); i++)
+    {
+        if (I965TexFormats[i].fmt == pPict->format)
+            break;
+    }
+    if (i == sizeof(I965TexFormats) / sizeof(I965TexFormats[0]))
+        I830FALLBACK("Unsupported picture format 0x%x\n",
+                         (int)pPict->format);
+
+    /* XXX: fallback when repeat? */
+    if (pPict->repeat && pPict->repeatType != RepeatNormal)
+	I830FALLBACK("extended repeat (%d) not supported\n",
+		     pPict->repeatType);
+
+    if (pPict->filter != PictFilterNearest &&
+        pPict->filter != PictFilterBilinear)
+        I830FALLBACK("Unsupported filter 0x%x\n", pPict->filter);
+
+    return TRUE;
+}
+
+Bool
+I965EXACheckComposite(int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture,
+		      PicturePtr pDstPicture)
+{
+	/* check op*/
+	/* check op with mask's componentAlpha*/
+	/* check textures */
+	/* check dst buffer format */
+    CARD32 tmp1;
+    
+    /* Check for unsupported compositing operations. */
+    if (op >= sizeof(I965BlendOp) / sizeof(I965BlendOp[0]))
+        I830FALLBACK("Unsupported Composite op 0x%x\n", op);
+                                                                                                                                                            
+    if (pMaskPicture != NULL && pMaskPicture->componentAlpha) {
+        /* Check if it's component alpha that relies on a source alpha and on
+         * the source value.  We can only get one of those into the single
+         * source value that we get to blend with.
+         */
+        if (I965BlendOp[op].src_alpha &&
+            (I965BlendOp[op].src_blend != BRW_BLENDFACT_ZERO))
+            	I830FALLBACK("Component alpha not supported with source "
+                            "alpha and source value blending.\n");
+	/* XXX: fallback now for mask with componentAlpha */
+	I830FALLBACK("mask componentAlpha not ready.\n");
+    }
+
+    if (!I965CheckCompositeTexture(pSrcPicture, 0))
+        I830FALLBACK("Check Src picture texture\n");
+    if (pMaskPicture != NULL && !I965CheckCompositeTexture(pMaskPicture, 1))
+        I830FALLBACK("Check Mask picture texture\n");
+
+    if (!I965GetDestFormat(pDstPicture, &tmp1)) 
+	I830FALLBACK("Get Color buffer format\n");
+
+    return TRUE;
+
+}
+
+#define ALIGN(i,m)    (((i) + (m) - 1) & ~((m) - 1))
+#define MIN(a,b) ((a) < (b) ? (a) : (b))
+
+int urb_vs_start, urb_vs_size;
+int urb_gs_start, urb_gs_size;
+int urb_clip_start, urb_clip_size;
+int urb_sf_start, urb_sf_size;
+int urb_cs_start, urb_cs_size;
+
+struct brw_surface_state *dest_surf_state;
+struct brw_surface_state *src_surf_state;
+struct brw_surface_state *mask_surf_state;
+struct brw_sampler_state *src_sampler_state;
+struct brw_sampler_state *mask_sampler_state;  // could just use one sampler?
+
+struct brw_vs_unit_state *vs_state;
+struct brw_sf_unit_state *sf_state;
+struct brw_wm_unit_state *wm_state;
+struct brw_cc_unit_state *cc_state;
+struct brw_cc_viewport *cc_viewport;
+
+struct brw_instruction *sf_kernel;
+struct brw_instruction *ps_kernel;
+struct brw_instruction *sip_kernel;
+
+CARD32 *binding_table;
+int binding_table_entries; 
+
+int dest_surf_offset, src_surf_offset, src_sampler_offset, vs_offset;
+int sf_offset, wm_offset, cc_offset, vb_offset, cc_viewport_offset;
+int sf_kernel_offset, ps_kernel_offset, sip_kernel_offset;
+int binding_table_offset;
+int next_offset, total_state_size;
+char *state_base;
+int state_base_offset;
+float *vb;
+int vb_size = 4 * 4 ; /* 4 DWORDS per vertex, 4 vertices for TRIFAN*/ 
+
+int src_blend, dst_blend;
+
+static const CARD32 sip_kernel_static[][4] = {
+/*    wait (1) a0<1>UW a145<0,1,0>UW { align1 +  } */
+    { 0x00000030, 0x20000108, 0x00001220, 0x00000000 },
+/*    nop (4) g0<1>UD { align1 +  } */
+    { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
+/*    nop (4) g0<1>UD { align1 +  } */
+    { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
+/*    nop (4) g0<1>UD { align1 +  } */
+    { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
+/*    nop (4) g0<1>UD { align1 +  } */
+    { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
+/*    nop (4) g0<1>UD { align1 +  } */
+    { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
+/*    nop (4) g0<1>UD { align1 +  } */
+    { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
+/*    nop (4) g0<1>UD { align1 +  } */
+    { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
+/*    nop (4) g0<1>UD { align1 +  } */
+    { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
+/*    nop (4) g0<1>UD { align1 +  } */
+    { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
+};
+
+/*
+ * this program computes dA/dx and dA/dy for the texture coordinates along
+ * with the base texture coordinate. It was extracted from the Mesa driver
+ */
+
+#define SF_KERNEL_NUM_GRF  10
+#define SF_KERNEL_NUM_URB  8
+#define SF_MAX_THREADS	   4
+
+static const CARD32 sf_kernel_static[][4] = {
+/*    send   0 (1) g6<1>F g1.12<0,1,0>F math mlen 1 rlen 1 { align1 +  } */
+   { 0x00000031, 0x20c01fbd, 0x0000002c, 0x01110081 },
+/*    send   0 (1) g6.4<1>F g1.20<0,1,0>F math mlen 1 rlen 1 { align1 +  } */
+   { 0x00000031, 0x20c41fbd, 0x00000034, 0x01110081 },
+/*    add (8) g7<1>F g4<8,8,1>F g3<8,8,1>F { align1 +  } */
+   { 0x00600040, 0x20e077bd, 0x008d0080, 0x008d4060 },
+/*    mul (1) g7<1>F g7<0,1,0>F g6<0,1,0>F { align1 +  } */
+   { 0x00000041, 0x20e077bd, 0x000000e0, 0x000000c0 },
+/*    mul (1) g7.4<1>F g7.4<0,1,0>F g6.4<0,1,0>F { align1 +  } */
+   { 0x00000041, 0x20e477bd, 0x000000e4, 0x000000c4 },
+/*    mov (8) m1<1>F g7<0,1,0>F { align1 +  } */
+   { 0x00600001, 0x202003be, 0x000000e0, 0x00000000 },
+/*    mov (8) m2<1>F g7.4<0,1,0>F { align1 +  } */
+   { 0x00600001, 0x204003be, 0x000000e4, 0x00000000 },
+/*    mov (8) m3<1>F g3<8,8,1>F { align1 +  } */
+   { 0x00600001, 0x206003be, 0x008d0060, 0x00000000 },
+/*    send   0 (8) a0<1>F g0<8,8,1>F urb mlen 4 rlen 0 write +0 transpose used complete EOT{ align1 +  } */
+   { 0x00600031, 0x20001fbc, 0x008d0000, 0x8640c800 },
+/*    nop (4) g0<1>UD { align1 +  } */
+   { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
+/*    nop (4) g0<1>UD { align1 +  } */
+   { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
+/*    nop (4) g0<1>UD { align1 +  } */
+   { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
+/*    nop (4) g0<1>UD { align1 +  } */
+   { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
+/*    nop (4) g0<1>UD { align1 +  } */
+   { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
+/*    nop (4) g0<1>UD { align1 +  } */
+   { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
+/*    nop (4) g0<1>UD { align1 +  } */
+   { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
+/*    nop (4) g0<1>UD { align1 +  } */
+   { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
+};
+
+/* ps kernels */
+/* 1: no mask */
+static const CARD32 ps_kernel_static_nomask [][4] = {
+	#include "i965_composite_ps_nomask.h"
+};
+
+/* 2: mask with componentAlpha, src * mask color, XXX: later */
+static const CARD32 ps_kernel_static_maskca [][4] = {
+	#include "i965_composite_ps_maskca.h"
+};
+
+/* 3: mask without componentAlpha, src * mask alpha */
+static const CARD32 ps_kernel_static_masknoca [][4] = {
+	#include "i965_composite_ps_masknoca.h"
+};
+
+Bool
+I965EXAPrepareComposite(int op, PicturePtr pSrcPicture,
+			PicturePtr pMaskPicture, PicturePtr pDstPicture,
+			PixmapPtr pSrc, PixmapPtr pMask, PixmapPtr pDst)
+{
+    ScrnInfoPtr pScrn = xf86Screens[pSrcPicture->pDrawable->pScreen->myNum];
+    I830Ptr pI830 = I830PTR(pScrn);
+    CARD32 src_offset, src_pitch;
+    CARD32 mask_offset, mask_pitch;
+    CARD32 dst_format, dst_offset, dst_pitch;
+    CARD32 blendctl;
+ 
+ErrorF("i965 prepareComposite\n");
+
+//    i965_3d_pipeline_setup(pScrn);
+//    i965_surf_setup(pScrn, pSrcPicture, pMaskPicture, pDstPicture,
+//   			pSrc, pMask, pDst);
+    // then setup blend, and shader program 
+
+    I965GetDestFormat(pDstPicture, &dst_format);
+    src_offset = exaGetPixmapOffset(pSrc);
+    src_pitch = exaGetPixmapPitch(pSrc);
+    dst_offset = exaGetPixmapOffset(pDst);
+    dst_pitch = exaGetPixmapPitch(pDst);
+    if (pMask) {
+	mask_offset = exaGetPixmapOffset(pMask);
+	mask_pitch = exaGetPixmapPitch(pMask);
+    }
+    scale_units[0][0] = pSrc->drawable.width;
+    scale_units[0][1] = pSrc->drawable.height;
+    scale_units[2][0] = pDst->drawable.width;
+    scale_units[2][1] = pDst->drawable.height;
+
+    if (!pMask) {
+	is_transform[1] = FALSE;
+	scale_units[1][0] = -1;
+	scale_units[1][1] = -1;
+    } else {
+	scale_units[1][0] = pMask->drawable.width;
+	scale_units[1][1] = pMask->drawable.height;
+    }
+
+/* FIXME */
+	/* setup 3d pipeline state */
+
+   binding_table_entries = 2; /* default no mask */
+
+   /* Set up our layout of state in framebuffer.  First the general state: */
+   next_offset = 0;
+   vs_offset = ALIGN(next_offset, 64);
+   next_offset = vs_offset + sizeof(*vs_state);
+    
+   sf_offset = ALIGN(next_offset, 32);
+   next_offset = sf_offset + sizeof(*sf_state);
+    
+   wm_offset = ALIGN(next_offset, 32);
+   next_offset = wm_offset + sizeof(*wm_state);
+    
+   cc_offset = ALIGN(next_offset, 32);
+   next_offset = cc_offset + sizeof(*cc_state);
+
+// fixup sf_kernel_static, is sf_kernel needed? or not? why? 
+//	-> just keep current sf_kernel, which will send one setup urb entry to
+//	PS kernel
+   sf_kernel_offset = ALIGN(next_offset, 64);
+   next_offset = sf_kernel_offset + sizeof (sf_kernel_static);
+
+   //XXX: ps_kernel may be seperated, fix with offset
+   ps_kernel_offset = ALIGN(next_offset, 64);
+   if (pMask) {
+	if (pMaskPicture->componentAlpha)
+	    next_offset = ps_kernel_offset + sizeof(ps_kernel_static_maskca);
+	else 
+	    next_offset = ps_kernel_offset + sizeof(ps_kernel_static_masknoca);
+   } else 
+   	next_offset = ps_kernel_offset + sizeof (ps_kernel_static_nomask);
+    
+   sip_kernel_offset = ALIGN(next_offset, 64);
+   next_offset = sip_kernel_offset + sizeof (sip_kernel_static);
+   
+   // needed?
+   cc_viewport_offset = ALIGN(next_offset, 32);
+   next_offset = cc_viewport_offset + sizeof(*cc_viewport);
+
+   // : fix for texture sampler
+   // XXX: -> use only one sampler
+   src_sampler_offset = ALIGN(next_offset, 32);
+   next_offset = src_sampler_offset + sizeof(*src_sampler_state);
+
+   /* Align VB to native size of elements, for safety */
+   vb_offset = ALIGN(next_offset, 8);
+   next_offset = vb_offset + vb_size;
+
+   /* And then the general state: */
+   //XXX: fix for texture map and target surface
+   dest_surf_offset = ALIGN(next_offset, 32);
+   next_offset = dest_surf_offset + sizeof(*dest_surf_state);
+
+   src_surf_offset = ALIGN(next_offset, 32);
+   next_offset = src_surf_offset + sizeof(*src_surf_state);
+
+   if (pMask) {
+   	mask_surf_offset = ALIGN(next_offset, 32);
+   	next_offset = mask_surf_offset + sizeof(*mask_surf_state);
+	binding_table_entries = 3;
+   }
+
+   binding_table_offset = ALIGN(next_offset, 32);
+   next_offset = binding_table_offset + (binding_table_entries * 4);
+
+   total_state_size = next_offset;
+
+   /*
+    * XXX: Use the extra space allocated at the end of the exa offscreen buffer?
+    */
+#define BRW_LINEAR_EXTRA	(32*1024)
+
+   state_base_offset = (pI830->Offscreen.End -
+			BRW_LINEAR_EXTRA);
+   
+   state_base_offset = ALIGN(state_base_offset, 64);
+   state_base = (char *)(pI830->FbBase + state_base_offset);
+   /* Set up our pointers to state structures in framebuffer.  It would probably
+    * be a good idea to fill these structures out in system memory and then dump
+    * them there, instead.
+    */
+   vs_state = (void *)(state_base + vs_offset);
+   sf_state = (void *)(state_base + sf_offset);
+   wm_state = (void *)(state_base + wm_offset);
+   cc_state = (void *)(state_base + cc_offset);
+   sf_kernel = (void *)(state_base + sf_kernel_offset);
+   ps_kernel = (void *)(state_base + ps_kernel_offset);
+   sip_kernel = (void *)(state_base + sip_kernel_offset);
+   
+   cc_viewport = (void *)(state_base + cc_viewport_offset);
+   
+   dest_surf_state = (void *)(state_base + dest_surf_offset);
+   src_surf_state = (void *)(state_base + src_surf_offset);
+   if (pMask)
+	mask_surf_state = (void *)(state_base + mask_surf_offset);
+
+   src_sampler_state = (void *)(state_base + src_sampler_offset);
+   binding_table = (void *)(state_base + binding_table_offset);
+
+   vb = (void *)(state_base + vb_offset);
+
+   /* Set up a default static partitioning of the URB, which is supposed to
+    * allow anything we would want to do, at potentially lower performance.
+    */
+#define URB_CS_ENTRY_SIZE     0
+#define URB_CS_ENTRIES	      0
+   
+#define URB_VS_ENTRY_SIZE     1	  // XXX: VUE row num? double check, 1 row is enough
+#define URB_VS_ENTRIES	      8
+   
+#define URB_GS_ENTRY_SIZE     0
+#define URB_GS_ENTRIES	      0
+   
+#define URB_CLIP_ENTRY_SIZE   0
+#define URB_CLIP_ENTRIES      0
+   
+#define URB_SF_ENTRY_SIZE     4
+#define URB_SF_ENTRIES	      8
+
+   urb_vs_start = 0;
+   urb_vs_size = URB_VS_ENTRIES * URB_VS_ENTRY_SIZE;
+   urb_gs_start = urb_vs_start + urb_vs_size;
+   urb_gs_size = URB_GS_ENTRIES * URB_GS_ENTRY_SIZE;
+   urb_clip_start = urb_gs_start + urb_gs_size;
+   urb_clip_size = URB_CLIP_ENTRIES * URB_CLIP_ENTRY_SIZE;
+   urb_sf_start = urb_clip_start + urb_clip_size;
+   urb_sf_size = URB_SF_ENTRIES * URB_SF_ENTRY_SIZE;
+   urb_cs_start = urb_sf_start + urb_sf_size;
+   urb_cs_size = URB_CS_ENTRIES * URB_CS_ENTRY_SIZE;
+
+   /* We'll be poking the state buffers that could be in use by the 3d hardware
+    * here, but we should have synced the 3D engine already in I830PutImage.
+    */
+
+// needed?
+   memset (cc_viewport, 0, sizeof (*cc_viewport));
+   cc_viewport->min_depth = -1.e35;
+   cc_viewport->max_depth = 1.e35;
+
+   /* Color calculator state */
+   memset(cc_state, 0, sizeof(*cc_state));
+   cc_state->cc0.stencil_enable = 0;   /* disable stencil */
+   cc_state->cc2.depth_test = 0;       /* disable depth test */
+   cc_state->cc2.logicop_enable = 0;   /* disable logic op */
+   cc_state->cc3.ia_blend_enable = 0;  /* blend alpha just like colors */
+   cc_state->cc3.blend_enable = 1;     /* enable color blend */
+   cc_state->cc3.alpha_test = 0;       /* disable alpha test */
+   // XXX:cc_viewport needed? 
+   cc_state->cc4.cc_viewport_state_offset = (state_base_offset + cc_viewport_offset) >> 5;
+   cc_state->cc5.dither_enable = 0;    /* disable dither */
+//   cc_state->cc5.logicop_func = 0xc;   /* COPY */
+//   cc_state->cc5.statistics_enable = 1;
+//   cc_state->cc5.ia_blend_function = BRW_BLENDFUNCTION_ADD;
+//   cc_state->cc5.ia_src_blend_factor = BRW_BLENDFACTOR_ONE;
+//   cc_state->cc5.ia_dest_blend_factor = BRW_BLENDFACTOR_ONE;
+   cc_state->cc6.blend_function = BRW_BLENDFUNCTION_ADD;
+   I965GetBlendCntl(op, pMask, pDstPicture->format, 
+		    &src_blend, &dst_blend);
+   cc_state->cc6.src_blend_factor = src_blend;
+   cc_state->cc6.dest_blend_factor = dst_blend;
+
+   /* Upload system kernel */
+   memcpy (sip_kernel, sip_kernel_static, sizeof (sip_kernel_static));
+   
+   /* Set up the state buffer for the destination surface */
+   memset(dest_surf_state, 0, sizeof(*dest_surf_state));
+   dest_surf_state->ss0.surface_type = BRW_SURFACE_2D;
+   dest_surf_state->ss0.data_return_format = BRW_SURFACERETURNFORMAT_FLOAT32;
+   // XXX: should compare with picture's cpp?...8 bit surf?
+   if (pDst->drawable.bitsPerPixel == 16) {
+      dest_surf_state->ss0.surface_format = BRW_SURFACEFORMAT_B5G6R5_UNORM;
+   } else {
+      dest_surf_state->ss0.surface_format = BRW_SURFACEFORMAT_B8G8R8A8_UNORM;
+   }
+   dest_surf_state->ss0.writedisable_alpha = 0;
+   dest_surf_state->ss0.writedisable_red = 0;
+   dest_surf_state->ss0.writedisable_green = 0;
+   dest_surf_state->ss0.writedisable_blue = 0;
+   dest_surf_state->ss0.color_blend = 1;
+   dest_surf_state->ss0.vert_line_stride = 0;
+   dest_surf_state->ss0.vert_line_stride_ofs = 0;
+   dest_surf_state->ss0.mipmap_layout_mode = 0;
+   dest_surf_state->ss0.render_cache_read_mode = 0;
+   
+   // XXX: fix to picture address & size
+   dest_surf_state->ss1.base_addr = dst_offset;
+   dest_surf_state->ss2.height = pDst->drawable.height - 1;
+   dest_surf_state->ss2.width = pDst->drawable.width - 1;
+   dest_surf_state->ss2.mip_count = 0;
+   dest_surf_state->ss2.render_target_rotation = 0;
+   dest_surf_state->ss3.pitch = dst_pitch - 1; 
+
+   /* Set up the source surface state buffer */
+   memset(src_surf_state, 0, sizeof(*src_surf_state));
+   src_surf_state->ss0.surface_type = BRW_SURFACE_2D;
+   if (pSrc->drawable.bitsPerPixel == 8)
+      src_surf_state->ss0.surface_format = BRW_SURFACEFORMAT_A8_UNORM; //XXX? 
+   else if (pSrc->drawable.bitsPerPixel == 16)
+      src_surf_state->ss0.surface_format = BRW_SURFACEFORMAT_B5G6R5_UNORM;
+   else 
+      src_surf_state->ss0.surface_format = BRW_SURFACEFORMAT_B8G8R8A8_UNORM;
+
+   src_surf_state->ss0.writedisable_alpha = 0;
+   src_surf_state->ss0.writedisable_red = 0;
+   src_surf_state->ss0.writedisable_green = 0;
+   src_surf_state->ss0.writedisable_blue = 0;
+   src_surf_state->ss0.color_blend = 1;
+   src_surf_state->ss0.vert_line_stride = 0;
+   src_surf_state->ss0.vert_line_stride_ofs = 0;
+   src_surf_state->ss0.mipmap_layout_mode = 0;
+   src_surf_state->ss0.render_cache_read_mode = 0;
+   
+   src_surf_state->ss1.base_addr = src_offset;
+   src_surf_state->ss2.width = pSrc->drawable.width - 1;
+   src_surf_state->ss2.height = pSrc->drawable.height - 1;
+   src_surf_state->ss2.mip_count = 0;
+   src_surf_state->ss2.render_target_rotation = 0;
+   src_surf_state->ss3.pitch = src_pitch - 1; 
+
+   /* setup mask surface */
+   if (pMask) {
+   	memset(mask_surf_state, 0, sizeof(*mask_surf_state));
+	mask_surf_state->ss0.surface_type = BRW_SURFACE_2D;
+   	if (pMask->drawable.bitsPerPixel == 8)
+      	    mask_surf_state->ss0.surface_format = BRW_SURFACEFORMAT_A8_UNORM; //XXX? 
+   	else if (pMask->drawable.bitsPerPixel == 16)
+      	    mask_surf_state->ss0.surface_format = BRW_SURFACEFORMAT_B5G6R5_UNORM;
+   	else 
+      	    mask_surf_state->ss0.surface_format = BRW_SURFACEFORMAT_B8G8R8A8_UNORM;
+
+   	mask_surf_state->ss0.writedisable_alpha = 0;
+   	mask_surf_state->ss0.writedisable_red = 0;
+   	mask_surf_state->ss0.writedisable_green = 0;
+   	mask_surf_state->ss0.writedisable_blue = 0;
+   	mask_surf_state->ss0.color_blend = 1;
+   	mask_surf_state->ss0.vert_line_stride = 0;
+   	mask_surf_state->ss0.vert_line_stride_ofs = 0;
+   	mask_surf_state->ss0.mipmap_layout_mode = 0;
+   	mask_surf_state->ss0.render_cache_read_mode = 0;
+   
+   	mask_surf_state->ss1.base_addr = mask_offset;
+   	mask_surf_state->ss2.width = pMask->drawable.width - 1;
+   	mask_surf_state->ss2.height = pMask->drawable.height - 1;
+   	mask_surf_state->ss2.mip_count = 0;
+   	mask_surf_state->ss2.render_target_rotation = 0;
+   	mask_surf_state->ss3.pitch = mask_pitch - 1; 
+   }
+
+   /* Set up a binding table for our surfaces.  Only the PS will use it */
+   binding_table[0] = state_base_offset + dest_surf_offset;
+   binding_table[1] = state_base_offset + src_surf_offset;
+   if (pMask)
+   	binding_table[2] = state_base_offset + mask_surf_offset;
+
+   /* PS kernel use this sampler */
+   memset(src_sampler_state, 0, sizeof(*src_sampler_state));
+   src_sampler_state->ss0.min_filter = BRW_MAPFILTER_LINEAR;
+   src_sampler_state->ss0.mag_filter = BRW_MAPFILTER_LINEAR;
+
+   /* XXX: fix for repeat */
+   if (!pSrcPicture->repeat) {
+   	src_sampler_state->ss1.r_wrap_mode = BRW_TEXCOORDMODE_CLAMP; // XXX: clamp_border and set border to 0?
+   	src_sampler_state->ss1.s_wrap_mode = BRW_TEXCOORDMODE_CLAMP;
+   	src_sampler_state->ss1.t_wrap_mode = BRW_TEXCOORDMODE_CLAMP;
+   } else {
+   	src_sampler_state->ss1.r_wrap_mode = BRW_TEXCOORDMODE_WRAP; // XXX: clamp_border and set border to 0?
+   	src_sampler_state->ss1.s_wrap_mode = BRW_TEXCOORDMODE_WRAP;
+   	src_sampler_state->ss1.t_wrap_mode = BRW_TEXCOORDMODE_WRAP;
+   }
+
+   /* Set up the vertex shader to be disabled (passthrough) */
+   memset(vs_state, 0, sizeof(*vs_state));
+   // XXX: vs URB should be defined for VF vertex URB store. done already?
+   vs_state->vs6.vs_enable = 0;
+
+   // XXX: sf_kernel? keep it as now
+   /* Set up the SF kernel to do coord interp: for each attribute,
+    * calculate dA/dx and dA/dy.  Hand these interpolation coefficients
+    * back to SF which then hands pixels off to WM.
+    */
+   memcpy (sf_kernel, sf_kernel_static, sizeof (sf_kernel_static));
+
+   memset(sf_state, 0, sizeof(*sf_state));
+   sf_state->thread0.kernel_start_pointer = 
+	       (state_base_offset + sf_kernel_offset) >> 6;
+   sf_state->thread0.grf_reg_count = ((SF_KERNEL_NUM_GRF & ~15) / 16);
+   sf_state->sf1.single_program_flow = 1;
+   sf_state->sf1.binding_table_entry_count = 0;
+   sf_state->sf1.thread_priority = 0;
+   sf_state->sf1.floating_point_mode = 0; /* Mesa does this */
+   sf_state->sf1.illegal_op_exception_enable = 1;
+   sf_state->sf1.mask_stack_exception_enable = 1;
+   sf_state->sf1.sw_exception_enable = 1;
+   sf_state->thread2.per_thread_scratch_space = 0;
+   sf_state->thread2.scratch_space_base_pointer = 0; /* not used in our kernel */
+   sf_state->thread3.const_urb_entry_read_length = 0; /* no const URBs */
+   sf_state->thread3.const_urb_entry_read_offset = 0; /* no const URBs */
+   sf_state->thread3.urb_entry_read_length = 1; /* 1 URB per vertex */
+   sf_state->thread3.urb_entry_read_offset = 0;
+   sf_state->thread3.dispatch_grf_start_reg = 3;
+   sf_state->thread4.max_threads = SF_MAX_THREADS - 1;
+   sf_state->thread4.urb_entry_allocation_size = URB_SF_ENTRY_SIZE - 1;
+   sf_state->thread4.nr_urb_entries = URB_SF_ENTRIES;
+   sf_state->thread4.stats_enable = 1;
+   sf_state->sf5.viewport_transform = FALSE; /* skip viewport */
+   sf_state->sf6.cull_mode = BRW_CULLMODE_NONE;
+   sf_state->sf6.scissor = 0;
+   sf_state->sf7.trifan_pv = 2;
+   sf_state->sf6.dest_org_vbias = 0x8;
+   sf_state->sf6.dest_org_hbias = 0x8;
+
+   /* Set up the PS kernel (dispatched by WM) 
+    */
+    
+    // XXX: replace to texture blend shader, and different cases 
+   if (pMask) {
+	if (pMaskPicture->componentAlpha)
+   	    memcpy (ps_kernel, ps_kernel_static_maskca, sizeof (ps_kernel_static_maskca));
+	else
+   	    memcpy (ps_kernel, ps_kernel_static_masknoca, sizeof (ps_kernel_static_masknoca));
+   } else 
+   	memcpy (ps_kernel, ps_kernel_static_nomask, sizeof (ps_kernel_static_nomask));
+
+   memset (wm_state, 0, sizeof (*wm_state));
+   wm_state->thread0.kernel_start_pointer = 
+	    (state_base_offset + ps_kernel_offset) >> 6;
+   wm_state->thread0.grf_reg_count = ((PS_KERNEL_NUM_GRF & ~15) / 16);
+   wm_state->thread1.single_program_flow = 1;
+   if (!pMask)
+       wm_state->thread1.binding_table_entry_count = 2; /* tex and fb */
+   else
+       wm_state->thread1.binding_table_entry_count = 3; /* tex and fb */
+
+   wm_state->thread2.scratch_space_base_pointer = 0;
+   wm_state->thread2.per_thread_scratch_space = 0;
+   // XXX: urb allocation
+   wm_state->thread3.dispatch_grf_start_reg = 3; /* must match kernel */
+   // wm kernel use urb from 3, see wm_program in compiler module
+   wm_state->thread3.urb_entry_read_length = 1;  /* one per pair of attrib */
+   wm_state->thread3.const_urb_entry_read_length = 0;
+   wm_state->thread3.const_urb_entry_read_offset = 0;
+   wm_state->thread3.urb_entry_read_offset = 0;
+
+   wm_state->wm4.stats_enable = 1;
+   wm_state->wm4.sampler_state_pointer = (state_base_offset + src_sampler_offset) >> 5;
+   wm_state->wm4.sampler_count = 1; /* 1-4 samplers used */
+   wm_state->wm5.max_threads = PS_MAX_THREADS - 1;
+   wm_state->wm5.thread_dispatch_enable = 1;
+   //just use 16-pixel dispatch, don't need to change kernel start point
+   wm_state->wm5.enable_16_pix = 1;
+   wm_state->wm5.enable_8_pix = 0;
+   wm_state->wm5.early_depth_test = 1;
+
+   /* Begin the long sequence of commands needed to set up the 3D 
+    * rendering pipe
+    */
+   {
+   
+   BEGIN_LP_RING((pMask?48:46));
+   // MI_FLUSH prior to PIPELINE_SELECT
+   OUT_RING(MI_FLUSH | 
+	    MI_STATE_INSTRUCTION_CACHE_FLUSH |
+	    BRW_MI_GLOBAL_SNAPSHOT_RESET);
+   
+   /* Match Mesa driver setup */
+   OUT_RING(BRW_PIPELINE_SELECT | PIPELINE_SELECT_3D);
+   
+   /* Zero out the two base address registers so all offsets are absolute */
+   // XXX: zero out...
+   OUT_RING(BRW_STATE_BASE_ADDRESS | 4);
+   // why this's not state_base_offset? -> because later we'll always add on
+   // state_base_offset to offset params. see SIP
+   OUT_RING(0 | BASE_ADDRESS_MODIFY);  /* Generate state base address */
+   OUT_RING(0 | BASE_ADDRESS_MODIFY);  /* Surface state base address */
+   OUT_RING(0 | BASE_ADDRESS_MODIFY);  /* media base addr, don't care */
+   OUT_RING(0x10000000 | BASE_ADDRESS_MODIFY);  /* general state max addr, disabled */
+   OUT_RING(0x10000000 | BASE_ADDRESS_MODIFY);  /* media object state max addr, disabled */
+
+   /* Set system instruction pointer */
+   OUT_RING(BRW_STATE_SIP | 0);
+   OUT_RING(state_base_offset + sip_kernel_offset); /* system instruction pointer */
+      
+   /* Pipe control */
+   // XXX: pipe control write cache before enabling color blending
+   // vol2, geometry pipeline 1.8.4
+   OUT_RING(BRW_PIPE_CONTROL |
+	    BRW_PIPE_CONTROL_NOWRITE |
+	    BRW_PIPE_CONTROL_IS_FLUSH |
+	    2);
+   OUT_RING(0);			       /* Destination address */
+   OUT_RING(0);			       /* Immediate data low DW */
+   OUT_RING(0);			       /* Immediate data high DW */
+
+   /* Binding table pointers */
+   OUT_RING(BRW_3DSTATE_BINDING_TABLE_POINTERS | 4);
+   OUT_RING(0); /* vs */
+   OUT_RING(0); /* gs */
+   OUT_RING(0); /* clip */
+   OUT_RING(0); /* sf */
+   /* Only the PS uses the binding table */
+   OUT_RING(state_base_offset + binding_table_offset); /* ps */
+
+   //ring 20
+
+   /* The drawing rectangle clipping is always on.  Set it to values that
+    * shouldn't do any clipping.
+    */
+    //XXX: fix for picture size
+   OUT_RING(BRW_3DSTATE_DRAWING_RECTANGLE | 2);	/* XXX 3 for BLC or CTG */
+   OUT_RING(0x00000000);	/* ymin, xmin */
+   OUT_RING((pScrn->virtualX - 1) |
+	    (pScrn->virtualY - 1) << 16); /* ymax, xmax */
+   OUT_RING(0x00000000);	/* yorigin, xorigin */
+
+   /* skip the depth buffer */
+   /* skip the polygon stipple */
+   /* skip the polygon stipple offset */
+   /* skip the line stipple */
+   
+   /* Set the pointers to the 3d pipeline state */
+   OUT_RING(BRW_3DSTATE_PIPELINED_POINTERS | 5);
+   OUT_RING(state_base_offset + vs_offset);  /* 32 byte aligned */
+   OUT_RING(BRW_GS_DISABLE);		     /* disable GS, resulting in passthrough */
+   OUT_RING(BRW_CLIP_DISABLE);		     /* disable CLIP, resulting in passthrough */
+   OUT_RING(state_base_offset + sf_offset);  /* 32 byte aligned */
+   OUT_RING(state_base_offset + wm_offset);  /* 32 byte aligned */
+   OUT_RING(state_base_offset + cc_offset);  /* 64 byte aligned */
+
+   /* URB fence */
+   // XXX: CS for const URB needed? if not, cs_fence should be equal to sf_fence
+   OUT_RING(BRW_URB_FENCE |
+	    UF0_CS_REALLOC |
+	    UF0_SF_REALLOC |
+	    UF0_CLIP_REALLOC |
+	    UF0_GS_REALLOC |
+	    UF0_VS_REALLOC |
+	    1);
+   OUT_RING(((urb_clip_start + urb_clip_size) << UF1_CLIP_FENCE_SHIFT) |
+	    ((urb_gs_start + urb_gs_size) << UF1_GS_FENCE_SHIFT) |
+	    ((urb_vs_start + urb_vs_size) << UF1_VS_FENCE_SHIFT));
+   OUT_RING(((urb_cs_start + urb_cs_size) << UF2_CS_FENCE_SHIFT) |
+	    ((urb_sf_start + urb_sf_size) << UF2_SF_FENCE_SHIFT));
+
+   /* Constant buffer state */
+   // XXX: needed? seems no usage, as we don't have CONSTANT_BUFFER definition
+   OUT_RING(BRW_CS_URB_STATE | 0);
+   OUT_RING(((URB_CS_ENTRY_SIZE - 1) << 4) | /* URB Entry Allocation Size */
+	    (URB_CS_ENTRIES << 0));	     /* Number of URB Entries */
+   
+   /* Set up the pointer to our vertex buffer */
+   // XXX: double check
+  // int vb_pitch = 4 * 4;  // XXX: pitch should include mask's coords? possible
+  // all three coords on one row?
+   int nelem = pMask ? 3: 2;
+   OUT_RING(BRW_3DSTATE_VERTEX_BUFFERS | 3); //should be 4n-1 -> 3
+   OUT_RING((0 << VB0_BUFFER_INDEX_SHIFT) |
+	    VB0_VERTEXDATA |
+	    ((4 * 2 * nelem) << VB0_BUFFER_PITCH_SHIFT)); 
+   		// pitch includes all vertex data, 4bytes for 1 dword, each
+		// element has 2 coords (x,y)(s0,t0), nelem to reflect possible
+		// mask
+   OUT_RING(state_base_offset + vb_offset);
+   OUT_RING(4 * nelem); // max index, prim has 4 coords
+   OUT_RING(0); // ignore for VERTEXDATA, but still there
+
+   /* Set up our vertex elements, sourced from the single vertex buffer. */
+   OUT_RING(BRW_3DSTATE_VERTEX_ELEMENTS | ((2 * nelem) - 1));  // XXX: 2n-1, (x,y) + (s0,t0) +
+						//   possible (s1, t1)
+   /* offset 0: X,Y -> {X, Y, 1.0, 1.0} */
+   OUT_RING((0 << VE0_VERTEX_BUFFER_INDEX_SHIFT) |
+	    VE0_VALID |
+	    (BRW_SURFACEFORMAT_R32G32_FLOAT << VE0_FORMAT_SHIFT) |
+	    (0 << VE0_OFFSET_SHIFT));
+   OUT_RING((BRW_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT) |
+	    (BRW_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT) |
+	    (BRW_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_2_SHIFT) |
+	    (BRW_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_3_SHIFT) |
+	    (0 << VE1_DESTINATION_ELEMENT_OFFSET_SHIFT));
+   /* offset 8: S0, T0 -> {S0, T0, 1.0, 1.0} */
+   OUT_RING((0 << VE0_VERTEX_BUFFER_INDEX_SHIFT) |
+	    VE0_VALID |
+	    (BRW_SURFACEFORMAT_R32G32_FLOAT << VE0_FORMAT_SHIFT) |
+	    (8 << VE0_OFFSET_SHIFT));
+   OUT_RING((BRW_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT) |
+	    (BRW_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT) |
+	    (BRW_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_2_SHIFT) |
+	    (BRW_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_3_SHIFT) |
+	    (4 << VE1_DESTINATION_ELEMENT_OFFSET_SHIFT));
+
+   if (pMask) {
+   	OUT_RING((0 << VE0_VERTEX_BUFFER_INDEX_SHIFT) |
+	    VE0_VALID |
+	    (BRW_SURFACEFORMAT_R32G32_FLOAT << VE0_FORMAT_SHIFT) |
+	    (16 << VE0_OFFSET_SHIFT));
+	OUT_RING((BRW_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT) |
+	    (BRW_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT) |
+	    (BRW_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_2_SHIFT) |
+	    (BRW_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_3_SHIFT) |
+	    (8 << VE1_DESTINATION_ELEMENT_OFFSET_SHIFT)); 
+		//XXX: is this has alignment issue? and thread access problem?
+	    
+   }
+   
+   ADVANCE_LP_RING();
+    
+   }
+
+    {
+	/* cc states */
+	/* dest buffer */
+	/* urbs */
+	/* binding tables */
+	/* clipping */
+	/* color blend (color calculator, dataport shared function)
+		COLOR_CALC_STATE/SURFACE_STATE(rendertarget's color blend enable
+		bit)
+		Errata!!!: brw-a/b, rendertarget 'local' color blending always
+		enabled! only control by global enable bit.
+	   surface format for blend, "Surface format table in Sampling Engine"
+	   XXX: if surface format not support, we should fallback.
+	*/
+	/* 
+	    render target should be defined in SURFACE_STATE
+	    	o render target SURFTYPE_BUFFER? 2D? Keith has 2D set.
+		o depth buffer SURFTYPE_NULL?
+	    color blend:
+	        o Errata!!: mush issue PIPE_CONTROL with Write Cache Flush
+		enable set, before transite to read-write color buffer. 
+	    	o disable pre/post-blending clamping
+		o enable color buffer blending enable in COLOR_CALC_STATE,(vol2, 3d rasterization 3.8) 
+		  enable color blending enable in SURFACE_STATE.(shared,
+		  sampling engine 1.7) 
+		  disable depth test
+		o (we don't use BLENDFACT_SRC_ALPHA_SATURATE, so don't care
+		the Errata for independent alpha blending, just use color
+		blending factor for all) disable independent alpha blending
+		in COLOR_CALC_STATE
+		o set src/dst blend factor in COLOR_CALC_STATE
+
+	*/
+    }
+
+	/* shader program 
+		o use sampler shared function for texture data
+		o submit result to dataport for later color blending */
+    {
+	 /* PS program:
+	 	o declare sampler and variables??
+		o 'send' cmd to Sampling Engine to load 'src' picture
+		o if (!pMask) then 'send' 'src' texture value to DataPort
+		target render cache
+		o else 
+		    - 'send' cmd to SE to load 'mask' picture
+		    - if no alpha, force to 1 (move 1 to W element of mask)
+		    - if (mask->componentAlpha) then mul 'src' & 'mask', 'send'
+		    	output to DataPort render cache
+		    - else mul 'src' & 'mask''s W element(alpha), 'send' output
+		    	to Dataport render cache
+	 */
+
+    }
+
+#ifdef I830DEBUG
+    ErrorF("try to sync to show any errors...");
+    I830Sync(pScrn);
+#endif
+    return TRUE;
+}	
+
+void
+I965EXAComposite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY,
+		int dstX, int dstY, int w, int h)
+{
+    int srcXend, srcYend, maskXend, maskYend;
+    PictVector v;
+    int pMask = 1, i = 0;
+
+    DPRINTF(PFX, "Composite: srcX %d, srcY %d\n\t maskX %d, maskY %d\n\t"
+	    "dstX %d, dstY %d\n\twidth %d, height %d\n\t"
+	    "src_scale_x %f, src_scale_y %f, "
+	    "mask_scale_x %f, mask_scale_y %f\n",
+	    srcX, srcY, maskX, maskY, dstX, dstY, w, h,
+	    scale_units[0][0], scale_units[0][1],
+	    scale_units[1][0], scale_units[1][1]);
+
+    if (scale_units[1][0] == -1 || scale_units[1][1] == -1) {
+	pMask = 0;
+    }
+
+    srcXend = srcX + w;
+    srcYend = srcY + h;
+    maskXend = maskX + w;
+    maskYend = maskY + h;
+    if (is_transform[0]) {
+        v.vector[0] = IntToxFixed(srcX);
+        v.vector[1] = IntToxFixed(srcY);
+        v.vector[2] = xFixed1;
+        PictureTransformPoint(transform[0], &v);
+        srcX = xFixedToInt(v.vector[0]);
+        srcY = xFixedToInt(v.vector[1]);
+        v.vector[0] = IntToxFixed(srcXend);
+        v.vector[1] = IntToxFixed(srcYend);
+        v.vector[2] = xFixed1;
+        PictureTransformPoint(transform[0], &v);
+        srcXend = xFixedToInt(v.vector[0]);
+        srcYend = xFixedToInt(v.vector[1]);
+    }
+    if (is_transform[1]) {
+        v.vector[0] = IntToxFixed(maskX);
+        v.vector[1] = IntToxFixed(maskY);
+        v.vector[2] = xFixed1;
+        PictureTransformPoint(transform[1], &v);
+        maskX = xFixedToInt(v.vector[0]);
+        maskY = xFixedToInt(v.vector[1]);
+        v.vector[0] = IntToxFixed(maskXend);
+        v.vector[1] = IntToxFixed(maskYend);
+        v.vector[2] = xFixed1;
+        PictureTransformPoint(transform[1], &v);
+        maskXend = xFixedToInt(v.vector[0]);
+        maskYend = xFixedToInt(v.vector[1]);
+    }
+
+    DPRINTF(PFX, "After transform: srcX %d, srcY %d,srcXend %d, srcYend %d\n\t"
+		"maskX %d, maskY %d, maskXend %d, maskYend %d\n\t"
+		"dstX %d, dstY %d\n", srcX, srcY, srcXend, srcYend,
+		maskX, maskY, maskXend, maskYend, dstX, dstY);
+
+ 
+    vb[i++] = (float)dstX;
+    vb[i++] = (float)dstY;
+    vb[i++] = (float)srcX / scale_units[0][0];
+    vb[i++] = (float)srcY / scale_units[0][1];
+    if (pMask) {
+        vb[i++] = (float)maskX / scale_units[1][0];
+        vb[i++] = (float)maskY / scale_units[1][1];
+    }
+
+    vb[i++] = (float)dstX;
+    vb[i++] = (float)(dstY + h);
+    vb[i++] = (float)srcX / scale_units[0][0];
+    vb[i++] = (float)srcYend / scale_units[0][1];
+    if (pMask) {
+        vb[i++] = (float)maskX / scale_units[1][0];
+        vb[i++] = (float)maskYend / scale_units[1][1];
+    }
+
+    vb[i++] = (float)(dstX + w);
+    vb[i++] = (float)(dstY + h);
+    vb[i++] = (float)srcXend / scale_units[0][0];
+    vb[i++] = (float)srcYend / scale_units[0][1];
+    if (pMask) {
+        vb[i++] = (float)maskXend / scale_units[1][0];
+        vb[i++] = (float)maskYend / scale_units[1][1];
+    }
+
+    vb[i++] = (float)(dstX + w);
+    vb[i++] = (float)dstY;
+    vb[i++] = (float)srcXend / scale_units[0][0];
+    vb[i++] = (float)srcY / scale_units[0][1];
+    if (pMask) {
+        vb[i++] = (float)maskXend / scale_units[1][0];
+        vb[i++] = (float)maskY / scale_units[1][1];
+    }
+
+    {
+      BEGIN_LP_RING(6);
+      OUT_RING(BRW_3DPRIMITIVE | 
+	       BRW_3DPRIMITIVE_VERTEX_SEQUENTIAL |
+	       (_3DPRIM_TRIFAN << BRW_3DPRIMITIVE_TOPOLOGY_SHIFT) | 
+	       (0 << 9) |  /* CTG - indirect vertex count */
+	       4);
+      OUT_RING(4);  /* vertex count per instance */
+      OUT_RING(0); /* start vertex offset */
+      OUT_RING(1); /* single instance */
+      OUT_RING(0); /* start instance location */
+      OUT_RING(0); /* index buffer offset, ignored */
+      ADVANCE_LP_RING();
+    }
+#ifdef I830DEBUG
+    ErrorF("sync after 3dprimitive");
+    I830Sync(pScrn);
+#endif
+}
diff-tree b7e57deebbda527e878326cf3e6358c0a48d7817 (from 43daaec63929c1f0e54a5125375d8147629da4b9)
Author: Wang Zhenyu <zhenyu.z.wang at intel.com>
Date:   Tue Aug 22 19:38:13 2006 +0800

    pci id update for Crestline
    
    The "Crestline" banner should be replaced with official
    name later.

diff --git a/src/common.h b/src/common.h
index ad5ee1d..d808b21 100644
--- a/src/common.h
+++ b/src/common.h
@@ -301,6 +301,11 @@ extern int I810_DEBUG;
 #define PCI_CHIP_I946_GZ_BRIDGE 	0x2970
 #endif
 
+#ifndef PCI_CHIP_CRESTLINE		//XXX: fix with official name
+#define PCI_CHIP_CRESTLINE		0x2A02
+#define PCI_CHIP_CRESTLINE_BRIDGE 	0x2A00
+#endif
+
 #define IS_I810(pI810) (pI810->PciInfo->chipType == PCI_CHIP_I810 ||	\
 			pI810->PciInfo->chipType == PCI_CHIP_I810_DC100 || \
 			pI810->PciInfo->chipType == PCI_CHIP_I810_E)
@@ -316,10 +321,11 @@ extern int I810_DEBUG;
 #define IS_I915GM(pI810) (pI810->PciInfo->chipType == PCI_CHIP_I915_GM)
 #define IS_I945G(pI810) (pI810->PciInfo->chipType == PCI_CHIP_I945_G)
 #define IS_I945GM(pI810) (pI810->PciInfo->chipType == PCI_CHIP_I945_GM)
-#define IS_I965G(pI810) (pI810->PciInfo->chipType == PCI_CHIP_I965_G || pI810->PciInfo->chipType == PCI_CHIP_I965_G_1 || pI810->PciInfo->chipType == PCI_CHIP_I965_Q || pI810->PciInfo->chipType == PCI_CHIP_I946_GZ)
+#define IS_I965G(pI810) (pI810->PciInfo->chipType == PCI_CHIP_I965_G || pI810->PciInfo->chipType == PCI_CHIP_I965_G_1 || pI810->PciInfo->chipType == PCI_CHIP_I965_Q || pI810->PciInfo->chipType == PCI_CHIP_I946_GZ || pI810->PciInfo->chipType == PCI_CHIP_CRESTLINE)
 #define IS_I9XX(pI810) (IS_I915G(pI810) || IS_I915GM(pI810) || IS_I945G(pI810) || IS_I945GM(pI810) || IS_I965G(pI810))
+#define IS_CRESTLINE(pI810) (pI810->PciInfo->chipType == PCI_CHIP_CRESTLINE) // XXX: IS_965GM ?
 
-#define IS_MOBILE(pI810) (IS_I830(pI810) || IS_I85X(pI810) || IS_I915GM(pI810) || IS_I945GM(pI810))
+#define IS_MOBILE(pI810) (IS_I830(pI810) || IS_I85X(pI810) || IS_I915GM(pI810) || IS_I945GM(pI810) || IS_CRESTLINE(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 3481d0b..48e1463 100644
--- a/src/i810_driver.c
+++ b/src/i810_driver.c
@@ -144,6 +144,7 @@ static SymTabRec I810Chipsets[] = {
    {PCI_CHIP_I965_G_1,		"965G"},
    {PCI_CHIP_I965_Q,		"965Q"},
    {PCI_CHIP_I946_GZ,		"946GZ"},
+   {PCI_CHIP_CRESTLINE,		"Crestline"},
    {-1,				NULL}
 };
 
@@ -167,6 +168,7 @@ static PciChipsets I810PciChipsets[] = {
    {PCI_CHIP_I965_G_1,		PCI_CHIP_I965_G_1,	RES_SHARED_VGA},
    {PCI_CHIP_I965_Q,		PCI_CHIP_I965_Q,	RES_SHARED_VGA},
    {PCI_CHIP_I946_GZ,		PCI_CHIP_I946_GZ,	RES_SHARED_VGA},
+   {PCI_CHIP_CRESTLINE,		PCI_CHIP_CRESTLINE,	RES_SHARED_VGA},
    {-1,				-1, RES_UNDEFINED }
 };
 
@@ -589,6 +591,7 @@ I810Probe(DriverPtr drv, int flags)
 	    case PCI_CHIP_I965_G_1:
 	    case PCI_CHIP_I965_Q:
 	    case PCI_CHIP_I946_GZ:
+	    case PCI_CHIP_CRESTLINE:
     	       xf86SetEntitySharable(usedChips[i]);
 
     	       /* Allocate an entity private if necessary */		
diff --git a/src/i830_driver.c b/src/i830_driver.c
index c0d9672..cdf005a 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -218,6 +218,7 @@ static SymTabRec I830BIOSChipsets[] = {
    {PCI_CHIP_I965_G_1,		"965G"},
    {PCI_CHIP_I965_Q,		"965Q"},
    {PCI_CHIP_I946_GZ,		"946GZ"},
+   {PCI_CHIP_CRESTLINE,		"Crestline"},
    {-1,				NULL}
 };
 
@@ -235,6 +236,7 @@ static PciChipsets I830BIOSPciChipsets[]
    {PCI_CHIP_I965_G_1,		PCI_CHIP_I965_G_1,	RES_SHARED_VGA},
    {PCI_CHIP_I965_Q,		PCI_CHIP_I965_Q,	RES_SHARED_VGA},
    {PCI_CHIP_I946_GZ,		PCI_CHIP_I946_GZ,	RES_SHARED_VGA},
+   {PCI_CHIP_CRESTLINE,		PCI_CHIP_CRESTLINE,	RES_SHARED_VGA},
    {-1,				-1,			RES_UNDEFINED}
 };
 
@@ -4022,6 +4024,9 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int f
    case PCI_CHIP_I946_GZ:
       chipname = "946GZ";
       break;
+   case PCI_CHIP_CRESTLINE:
+      chipname = "Crestline";
+      break;
    default:
       chipname = "unknown chipset";
       break;



More information about the xorg-commit mailing list