xf86-video-intel: Branch 'modesetting' - src/i830_tv.c

Zhenyu Wang zhen at kemper.freedesktop.org
Fri Feb 9 05:31:26 EET 2007


 src/i830_tv.c | 1184 +++++++++++++++++++++++++++++++++++-----------------------
 1 files changed, 733 insertions(+), 451 deletions(-)

New commits:
diff-tree fce4390c4f1a76c65423114bb479814787612cd7 (from 10712c7a781e50475ee7e8ccd5bfd2d820f863e2)
Author: Zou Nan hai <zhenyu.z.wang at intel.com>
Date:   Fri Feb 9 11:32:22 2007 +0800

     TV Enable

diff --git a/src/i830_tv.c b/src/i830_tv.c
index 79b6ae8..5ee8866 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,
@@ -94,11 +93,67 @@ typedef struct {
     float   rv, gv, bv, av;
 } color_conversion_t;
 
+static const CARD32 filter_table[] = {
+    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,
+};
+
 typedef struct {
     char *name;
+    int	clock;
     CARD32 oversample;
     int hsync_end, hblank_start, hblank_end, htotal;
-    Bool progressive;
+    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 +175,10 @@ 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;
 
-#define TV_PLL_CLOCK	107520
 
 /*
  * Sub carrier DDA
@@ -157,25 +213,26 @@ 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,
 	.hblank_start	= 836,		    .htotal		= 857,
-	
-	.progressive	= FALSE,
-	
+
+	.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,
@@ -203,26 +260,78 @@ 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,
     },
     {
-	.name		= "NTSC-Japan 480i",
+	.name		= "NTSC-443",
+	.clock		= 107520,	
 	.oversample	= TV_OVERSAMPLE_8X,
-	
-	/* 525 Lines, 60 Fields, 15.734KHz line, Sub-Carrier 3.580MHz */
+	.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,
-	
-	.vsync_start_f1	= 6,		    .vsync_start_f2	= 7,
+
+	.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,
@@ -250,20 +359,74 @@ const static 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,
 	},
+	.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	=    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 576i",
+	.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,
-	
-	.vsync_start_f1	= 6,		    .vsync_start_f2	= 7,
+	.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,
 
@@ -271,44 +434,70 @@ const static tv_mode_t tv_modes[] = {
 	.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,
+	.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,
+	.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_levels = { .blank = 225, .black = 267, .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,
+	    .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 = 280, .black = 280, .burst = 139 },
+	.svideo_levels    = { .blank = 266, .black = 316, .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,
+	    .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,
 	},
-    }
-#if 0
+	.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	= 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,
+	.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
-	
+	.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,
@@ -322,84 +511,226 @@ 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,
     },
     {
-	/* 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,
-	},
+	.name       = "480p at 59.94Hz",
+	.clock 	= 107520,	
+	.oversample     = TV_OVERSAMPLE_4X,
+	.component_only = 1,
 
-	.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,
-	},
+	.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,
     },
     {
-	/* 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,
-	},
+	.name       = "480p at 60Hz",
+	.clock 	= 107520,	
+	.oversample     = TV_OVERSAMPLE_4X,
+	.component_only = 1,
 
-	.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,
-	},
+	.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,
     },
     {
-	/* 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       = "576p",
+	.clock 	= 107520,	
+	.oversample     = TV_OVERSAMPLE_4X,
+	.component_only = 1,
 
-	.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      = 64,               .hblank_end         = 139,
+	.hblank_start   = 859,              .htotal             = 863,
 
-	.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    = 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,
+
+	.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,
+
+	.filter_table = filter_table,
+    },
+    {
+	.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,
+
+	.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,
+    },
+    {
+	.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,
+
+	.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,
+
+	.filter_table = filter_table,
+    },
+    {
+	.name       = "1080i at 60Hz",
+	.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,
+
+	.filter_table = filter_table,
+    },
+    {
+	.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,
+
+	.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,
+
+	.filter_table = filter_table,
     },
-#endif
 };
 
 static const video_levels_t component_level = {
-    .blank = 279, .black = 279 
+	.blank = 279, .black = 279 
 };
 
 static const color_conversion_t sdtv_component_color = {
@@ -407,13 +738,13 @@ static const color_conversion_t sdtv_com
     .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,
 };
-    
+
 static void
 i830_tv_dpms(xf86OutputPtr output, int mode)
 {
@@ -421,14 +752,14 @@ i830_tv_dpms(xf86OutputPtr output, int m
     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;
+	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;
     }
 }
 
@@ -491,6 +822,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);
@@ -513,11 +849,38 @@ i830_tv_restore(xf86OutputPtr output)
     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);
+
+    {
+	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 */
+	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]);
@@ -535,95 +898,32 @@ i830_tv_restore(xf86OutputPtr output)
 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
@@ -633,10 +933,10 @@ i830_float_to_csc (float fin)
     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;
@@ -665,7 +965,7 @@ i830_float_to_luma (float f)
 
 static void
 i830_tv_mode_set(xf86OutputPtr output, DisplayModePtr mode,
-		 DisplayModePtr adjusted_mode)
+		DisplayModePtr adjusted_mode)
 {
     ScrnInfoPtr		    pScrn = output->scrn;
     I830Ptr		    pI830 = I830PTR(pScrn);
@@ -674,53 +974,52 @@ 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;
-    int			    i;
+    int			    i, j;
     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.
-     */
-    tv_mode = &tv_modes[0];
-    
+    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;
+	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);
 
     hctl2 = (tv_mode->hburst_start << 16) |
 	(tv_mode->hburst_len << TV_HBURST_LEN_SHIFT);
+
     if (burst_ena)
 	hctl2 |= TV_BURST_ENA;
 
@@ -738,6 +1037,7 @@ i830_tv_mode_set(xf86OutputPtr output, D
     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;
 
@@ -755,21 +1055,24 @@ 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;
+    scctl1 = 0;
+    if (tv_mode->dda1_inc)
+	scctl1 |= TV_SC_DDA1_EN;
 
-    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;
@@ -784,10 +1087,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);
     OUTREG(TV_H_CTL_3, hctl3);
@@ -801,183 +1100,113 @@ i830_tv_mode_set(xf86OutputPtr output, D
     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)));
+	    (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)));
+	    (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)));
+	    (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_KNOBS, 0x10606000);
     OUTREG(TV_CLR_LEVEL, ((video_levels->black << TV_BLACK_LEVEL_SHIFT) |
-			  (video_levels->blank << TV_BLANK_LEVEL_SHIFT)));
-    
-    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);
+		(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)
+	    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), h_luma[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), h_chroma[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), v_luma[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), v_chroma[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,
-		.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
-	},
-	{
-		.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
-	},
+    {
+	.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
+    },
 };
 
 /**
  * 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);
@@ -1002,13 +1231,13 @@ i830_tv_detect_type (xf86CrtcPtr    crtc
 	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);
+		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);
@@ -1024,22 +1253,22 @@ i830_tv_detect_type (xf86CrtcPtr    crtc
      */
     if ((tv_dac & TVDAC_SENSE_MASK) == (TVDAC_B_SENSE | TVDAC_C_SENSE)) {
 	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-		   "Detected Composite TV connection\n");
+		"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");
+		"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");
+		"Detected Component TV connection\n");
 	type = TV_TYPE_COMPONENT;
     } else {
 	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-		   "No TV connection detected\n");
+		"No TV connection detected\n");
 	type = TV_TYPE_NONE;
     }
-    
+
     dev_priv->type = type;
 }
 
@@ -1060,55 +1289,108 @@ i830_tv_detect(xf86OutputPtr 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);
+	    crtc->funcs->mode_set(crtc, &mode, &mode, 0, 0);
+        }
+        i830_tv_detect_type (crtc, output);
+        i830ReleaseLoadDetectPipe (output);
     }
-    
+
     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.
  *
  * 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++)
-    {
-	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;
+    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 first;
+    return ret;
 }
 
 static void
@@ -1138,7 +1420,7 @@ i830_tv_init(ScrnInfoPtr pScrn)
     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;
 
@@ -1147,31 +1429,31 @@ i830_tv_init(ScrnInfoPtr pScrn)
      * 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);
@@ -1181,7 +1463,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;



More information about the xorg-commit mailing list