xref: /dragonfly/sys/dev/drm/i915/intel_tv.c (revision b29f78b5)
1 /*
2  * Copyright © 2006-2008 Intel Corporation
3  *   Jesse Barnes <jesse.barnes@intel.com>
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a
6  * copy of this software and associated documentation files (the "Software"),
7  * to deal in the Software without restriction, including without limitation
8  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9  * and/or sell copies of the Software, and to permit persons to whom the
10  * Software is furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice (including the next
13  * paragraph) shall be included in all copies or substantial portions of the
14  * Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22  * DEALINGS IN THE SOFTWARE.
23  *
24  * Authors:
25  *    Eric Anholt <eric@anholt.net>
26  *
27  */
28 
29 /** @file
30  * Integrated TV-out support for the 915GM and 945GM.
31  */
32 
33 #include <drm/drmP.h>
34 #include <drm/drm_crtc.h>
35 #include <drm/drm_edid.h>
36 #include "intel_drv.h"
37 #include <drm/i915_drm.h>
38 #include "i915_drv.h"
39 
40 enum tv_margin {
41 	TV_MARGIN_LEFT, TV_MARGIN_TOP,
42 	TV_MARGIN_RIGHT, TV_MARGIN_BOTTOM
43 };
44 
45 /** Private structure for the integrated TV support */
46 struct intel_tv {
47 	struct intel_encoder base;
48 
49 	int type;
50 	const char *tv_format;
51 	int margin[4];
52 	u32 save_TV_H_CTL_1;
53 	u32 save_TV_H_CTL_2;
54 	u32 save_TV_H_CTL_3;
55 	u32 save_TV_V_CTL_1;
56 	u32 save_TV_V_CTL_2;
57 	u32 save_TV_V_CTL_3;
58 	u32 save_TV_V_CTL_4;
59 	u32 save_TV_V_CTL_5;
60 	u32 save_TV_V_CTL_6;
61 	u32 save_TV_V_CTL_7;
62 	u32 save_TV_SC_CTL_1, save_TV_SC_CTL_2, save_TV_SC_CTL_3;
63 
64 	u32 save_TV_CSC_Y;
65 	u32 save_TV_CSC_Y2;
66 	u32 save_TV_CSC_U;
67 	u32 save_TV_CSC_U2;
68 	u32 save_TV_CSC_V;
69 	u32 save_TV_CSC_V2;
70 	u32 save_TV_CLR_KNOBS;
71 	u32 save_TV_CLR_LEVEL;
72 	u32 save_TV_WIN_POS;
73 	u32 save_TV_WIN_SIZE;
74 	u32 save_TV_FILTER_CTL_1;
75 	u32 save_TV_FILTER_CTL_2;
76 	u32 save_TV_FILTER_CTL_3;
77 
78 	u32 save_TV_H_LUMA[60];
79 	u32 save_TV_H_CHROMA[60];
80 	u32 save_TV_V_LUMA[43];
81 	u32 save_TV_V_CHROMA[43];
82 
83 	u32 save_TV_DAC;
84 	u32 save_TV_CTL;
85 };
86 
87 struct video_levels {
88 	int blank, black, burst;
89 };
90 
91 struct color_conversion {
92 	u16 ry, gy, by, ay;
93 	u16 ru, gu, bu, au;
94 	u16 rv, gv, bv, av;
95 };
96 
97 static const u32 filter_table[] = {
98 	0xB1403000, 0x2E203500, 0x35002E20, 0x3000B140,
99 	0x35A0B160, 0x2DC02E80, 0xB1403480, 0xB1603000,
100 	0x2EA03640, 0x34002D80, 0x3000B120, 0x36E0B160,
101 	0x2D202EF0, 0xB1203380, 0xB1603000, 0x2F303780,
102 	0x33002CC0, 0x3000B100, 0x3820B160, 0x2C802F50,
103 	0xB10032A0, 0xB1603000, 0x2F9038C0, 0x32202C20,
104 	0x3000B0E0, 0x3980B160, 0x2BC02FC0, 0xB0E031C0,
105 	0xB1603000, 0x2FF03A20, 0x31602B60, 0xB020B0C0,
106 	0x3AE0B160, 0x2B001810, 0xB0C03120, 0xB140B020,
107 	0x18283BA0, 0x30C02A80, 0xB020B0A0, 0x3C60B140,
108 	0x2A201838, 0xB0A03080, 0xB120B020, 0x18383D20,
109 	0x304029C0, 0xB040B080, 0x3DE0B100, 0x29601848,
110 	0xB0803000, 0xB100B040, 0x18483EC0, 0xB0402900,
111 	0xB040B060, 0x3F80B0C0, 0x28801858, 0xB060B080,
112 	0xB0A0B060, 0x18602820, 0xB0A02820, 0x0000B060,
113 	0xB1403000, 0x2E203500, 0x35002E20, 0x3000B140,
114 	0x35A0B160, 0x2DC02E80, 0xB1403480, 0xB1603000,
115 	0x2EA03640, 0x34002D80, 0x3000B120, 0x36E0B160,
116 	0x2D202EF0, 0xB1203380, 0xB1603000, 0x2F303780,
117 	0x33002CC0, 0x3000B100, 0x3820B160, 0x2C802F50,
118 	0xB10032A0, 0xB1603000, 0x2F9038C0, 0x32202C20,
119 	0x3000B0E0, 0x3980B160, 0x2BC02FC0, 0xB0E031C0,
120 	0xB1603000, 0x2FF03A20, 0x31602B60, 0xB020B0C0,
121 	0x3AE0B160, 0x2B001810, 0xB0C03120, 0xB140B020,
122 	0x18283BA0, 0x30C02A80, 0xB020B0A0, 0x3C60B140,
123 	0x2A201838, 0xB0A03080, 0xB120B020, 0x18383D20,
124 	0x304029C0, 0xB040B080, 0x3DE0B100, 0x29601848,
125 	0xB0803000, 0xB100B040, 0x18483EC0, 0xB0402900,
126 	0xB040B060, 0x3F80B0C0, 0x28801858, 0xB060B080,
127 	0xB0A0B060, 0x18602820, 0xB0A02820, 0x0000B060,
128 	0x36403000, 0x2D002CC0, 0x30003640, 0x2D0036C0,
129 	0x35C02CC0, 0x37403000, 0x2C802D40, 0x30003540,
130 	0x2D8037C0, 0x34C02C40, 0x38403000, 0x2BC02E00,
131 	0x30003440, 0x2E2038C0, 0x34002B80, 0x39803000,
132 	0x2B402E40, 0x30003380, 0x2E603A00, 0x33402B00,
133 	0x3A803040, 0x2A802EA0, 0x30403300, 0x2EC03B40,
134 	0x32802A40, 0x3C003040, 0x2A002EC0, 0x30803240,
135 	0x2EC03C80, 0x320029C0, 0x3D403080, 0x29402F00,
136 	0x308031C0, 0x2F203DC0, 0x31802900, 0x3E8030C0,
137 	0x28802F40, 0x30C03140, 0x2F203F40, 0x31402840,
138 	0x28003100, 0x28002F00, 0x00003100, 0x36403000,
139 	0x2D002CC0, 0x30003640, 0x2D0036C0,
140 	0x35C02CC0, 0x37403000, 0x2C802D40, 0x30003540,
141 	0x2D8037C0, 0x34C02C40, 0x38403000, 0x2BC02E00,
142 	0x30003440, 0x2E2038C0, 0x34002B80, 0x39803000,
143 	0x2B402E40, 0x30003380, 0x2E603A00, 0x33402B00,
144 	0x3A803040, 0x2A802EA0, 0x30403300, 0x2EC03B40,
145 	0x32802A40, 0x3C003040, 0x2A002EC0, 0x30803240,
146 	0x2EC03C80, 0x320029C0, 0x3D403080, 0x29402F00,
147 	0x308031C0, 0x2F203DC0, 0x31802900, 0x3E8030C0,
148 	0x28802F40, 0x30C03140, 0x2F203F40, 0x31402840,
149 	0x28003100, 0x28002F00, 0x00003100,
150 };
151 
152 /*
153  * Color conversion values have 3 separate fixed point formats:
154  *
155  * 10 bit fields (ay, au)
156  *   1.9 fixed point (b.bbbbbbbbb)
157  * 11 bit fields (ry, by, ru, gu, gv)
158  *   exp.mantissa (ee.mmmmmmmmm)
159  *   ee = 00 = 10^-1 (0.mmmmmmmmm)
160  *   ee = 01 = 10^-2 (0.0mmmmmmmmm)
161  *   ee = 10 = 10^-3 (0.00mmmmmmmmm)
162  *   ee = 11 = 10^-4 (0.000mmmmmmmmm)
163  * 12 bit fields (gy, rv, bu)
164  *   exp.mantissa (eee.mmmmmmmmm)
165  *   eee = 000 = 10^-1 (0.mmmmmmmmm)
166  *   eee = 001 = 10^-2 (0.0mmmmmmmmm)
167  *   eee = 010 = 10^-3 (0.00mmmmmmmmm)
168  *   eee = 011 = 10^-4 (0.000mmmmmmmmm)
169  *   eee = 100 = reserved
170  *   eee = 101 = reserved
171  *   eee = 110 = reserved
172  *   eee = 111 = 10^0 (m.mmmmmmmm) (only usable for 1.0 representation)
173  *
174  * Saturation and contrast are 8 bits, with their own representation:
175  * 8 bit field (saturation, contrast)
176  *   exp.mantissa (ee.mmmmmm)
177  *   ee = 00 = 10^-1 (0.mmmmmm)
178  *   ee = 01 = 10^0 (m.mmmmm)
179  *   ee = 10 = 10^1 (mm.mmmm)
180  *   ee = 11 = 10^2 (mmm.mmm)
181  *
182  * Simple conversion function:
183  *
184  * static u32
185  * float_to_csc_11(float f)
186  * {
187  *     u32 exp;
188  *     u32 mant;
189  *     u32 ret;
190  *
191  *     if (f < 0)
192  *         f = -f;
193  *
194  *     if (f >= 1) {
195  *         exp = 0x7;
196  *	   mant = 1 << 8;
197  *     } else {
198  *         for (exp = 0; exp < 3 && f < 0.5; exp++)
199  *	   f *= 2.0;
200  *         mant = (f * (1 << 9) + 0.5);
201  *         if (mant >= (1 << 9))
202  *             mant = (1 << 9) - 1;
203  *     }
204  *     ret = (exp << 9) | mant;
205  *     return ret;
206  * }
207  */
208 
209 /*
210  * Behold, magic numbers!  If we plant them they might grow a big
211  * s-video cable to the sky... or something.
212  *
213  * Pre-converted to appropriate hex value.
214  */
215 
216 /*
217  * PAL & NTSC values for composite & s-video connections
218  */
219 static const struct color_conversion ntsc_m_csc_composite = {
220 	.ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0104,
221 	.ru = 0x0733, .gu = 0x052d, .bu = 0x05c7, .au = 0x0200,
222 	.rv = 0x0340, .gv = 0x030c, .bv = 0x06d0, .av = 0x0200,
223 };
224 
225 static const struct video_levels ntsc_m_levels_composite = {
226 	.blank = 225, .black = 267, .burst = 113,
227 };
228 
229 static const struct color_conversion ntsc_m_csc_svideo = {
230 	.ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0133,
231 	.ru = 0x076a, .gu = 0x0564, .bu = 0x030d, .au = 0x0200,
232 	.rv = 0x037a, .gv = 0x033d, .bv = 0x06f6, .av = 0x0200,
233 };
234 
235 static const struct video_levels ntsc_m_levels_svideo = {
236 	.blank = 266, .black = 316, .burst = 133,
237 };
238 
239 static const struct color_conversion ntsc_j_csc_composite = {
240 	.ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0119,
241 	.ru = 0x074c, .gu = 0x0546, .bu = 0x05ec, .au = 0x0200,
242 	.rv = 0x035a, .gv = 0x0322, .bv = 0x06e1, .av = 0x0200,
243 };
244 
245 static const struct video_levels ntsc_j_levels_composite = {
246 	.blank = 225, .black = 225, .burst = 113,
247 };
248 
249 static const struct color_conversion ntsc_j_csc_svideo = {
250 	.ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x014c,
251 	.ru = 0x0788, .gu = 0x0581, .bu = 0x0322, .au = 0x0200,
252 	.rv = 0x0399, .gv = 0x0356, .bv = 0x070a, .av = 0x0200,
253 };
254 
255 static const struct video_levels ntsc_j_levels_svideo = {
256 	.blank = 266, .black = 266, .burst = 133,
257 };
258 
259 static const struct color_conversion pal_csc_composite = {
260 	.ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0113,
261 	.ru = 0x0745, .gu = 0x053f, .bu = 0x05e1, .au = 0x0200,
262 	.rv = 0x0353, .gv = 0x031c, .bv = 0x06dc, .av = 0x0200,
263 };
264 
265 static const struct video_levels pal_levels_composite = {
266 	.blank = 237, .black = 237, .burst = 118,
267 };
268 
269 static const struct color_conversion pal_csc_svideo = {
270 	.ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0145,
271 	.ru = 0x0780, .gu = 0x0579, .bu = 0x031c, .au = 0x0200,
272 	.rv = 0x0390, .gv = 0x034f, .bv = 0x0705, .av = 0x0200,
273 };
274 
275 static const struct video_levels pal_levels_svideo = {
276 	.blank = 280, .black = 280, .burst = 139,
277 };
278 
279 static const struct color_conversion pal_m_csc_composite = {
280 	.ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0104,
281 	.ru = 0x0733, .gu = 0x052d, .bu = 0x05c7, .au = 0x0200,
282 	.rv = 0x0340, .gv = 0x030c, .bv = 0x06d0, .av = 0x0200,
283 };
284 
285 static const struct video_levels pal_m_levels_composite = {
286 	.blank = 225, .black = 267, .burst = 113,
287 };
288 
289 static const struct color_conversion pal_m_csc_svideo = {
290 	.ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0133,
291 	.ru = 0x076a, .gu = 0x0564, .bu = 0x030d, .au = 0x0200,
292 	.rv = 0x037a, .gv = 0x033d, .bv = 0x06f6, .av = 0x0200,
293 };
294 
295 static const struct video_levels pal_m_levels_svideo = {
296 	.blank = 266, .black = 316, .burst = 133,
297 };
298 
299 static const struct color_conversion pal_n_csc_composite = {
300 	.ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0104,
301 	.ru = 0x0733, .gu = 0x052d, .bu = 0x05c7, .au = 0x0200,
302 	.rv = 0x0340, .gv = 0x030c, .bv = 0x06d0, .av = 0x0200,
303 };
304 
305 static const struct video_levels pal_n_levels_composite = {
306 	.blank = 225, .black = 267, .burst = 118,
307 };
308 
309 static const struct color_conversion pal_n_csc_svideo = {
310 	.ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0133,
311 	.ru = 0x076a, .gu = 0x0564, .bu = 0x030d, .au = 0x0200,
312 	.rv = 0x037a, .gv = 0x033d, .bv = 0x06f6, .av = 0x0200,
313 };
314 
315 static const struct video_levels pal_n_levels_svideo = {
316 	.blank = 266, .black = 316, .burst = 139,
317 };
318 
319 /*
320  * Component connections
321  */
322 static const struct color_conversion sdtv_csc_yprpb = {
323 	.ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0145,
324 	.ru = 0x0559, .gu = 0x0353, .bu = 0x0100, .au = 0x0200,
325 	.rv = 0x0100, .gv = 0x03ad, .bv = 0x074d, .av = 0x0200,
326 };
327 
328 static const struct color_conversion sdtv_csc_rgb = {
329 	.ry = 0x0000, .gy = 0x0f00, .by = 0x0000, .ay = 0x0166,
330 	.ru = 0x0000, .gu = 0x0000, .bu = 0x0f00, .au = 0x0166,
331 	.rv = 0x0f00, .gv = 0x0000, .bv = 0x0000, .av = 0x0166,
332 };
333 
334 static const struct color_conversion hdtv_csc_yprpb = {
335 	.ry = 0x05b3, .gy = 0x016e, .by = 0x0728, .ay = 0x0145,
336 	.ru = 0x07d5, .gu = 0x038b, .bu = 0x0100, .au = 0x0200,
337 	.rv = 0x0100, .gv = 0x03d1, .bv = 0x06bc, .av = 0x0200,
338 };
339 
340 static const struct color_conversion hdtv_csc_rgb = {
341 	.ry = 0x0000, .gy = 0x0f00, .by = 0x0000, .ay = 0x0166,
342 	.ru = 0x0000, .gu = 0x0000, .bu = 0x0f00, .au = 0x0166,
343 	.rv = 0x0f00, .gv = 0x0000, .bv = 0x0000, .av = 0x0166,
344 };
345 
346 static const struct video_levels component_levels = {
347 	.blank = 279, .black = 279, .burst = 0,
348 };
349 
350 
351 struct tv_mode {
352 	const char *name;
353 	int clock;
354 	int refresh; /* in millihertz (for precision) */
355 	u32 oversample;
356 	int hsync_end, hblank_start, hblank_end, htotal;
357 	bool progressive, trilevel_sync, component_only;
358 	int vsync_start_f1, vsync_start_f2, vsync_len;
359 	bool veq_ena;
360 	int veq_start_f1, veq_start_f2, veq_len;
361 	int vi_end_f1, vi_end_f2, nbr_end;
362 	bool burst_ena;
363 	int hburst_start, hburst_len;
364 	int vburst_start_f1, vburst_end_f1;
365 	int vburst_start_f2, vburst_end_f2;
366 	int vburst_start_f3, vburst_end_f3;
367 	int vburst_start_f4, vburst_end_f4;
368 	/*
369 	 * subcarrier programming
370 	 */
371 	int dda2_size, dda3_size, dda1_inc, dda2_inc, dda3_inc;
372 	u32 sc_reset;
373 	bool pal_burst;
374 	/*
375 	 * blank/black levels
376 	 */
377 	const struct video_levels *composite_levels, *svideo_levels;
378 	const struct color_conversion *composite_color, *svideo_color;
379 	const u32 *filter_table;
380 	int max_srcw;
381 };
382 
383 
384 /*
385  * Sub carrier DDA
386  *
387  *  I think this works as follows:
388  *
389  *  subcarrier freq = pixel_clock * (dda1_inc + dda2_inc / dda2_size) / 4096
390  *
391  * Presumably, when dda3 is added in, it gets to adjust the dda2_inc value
392  *
393  * So,
394  *  dda1_ideal = subcarrier/pixel * 4096
395  *  dda1_inc = floor (dda1_ideal)
396  *  dda2 = dda1_ideal - dda1_inc
397  *
398  *  then pick a ratio for dda2 that gives the closest approximation. If
399  *  you can't get close enough, you can play with dda3 as well. This
400  *  seems likely to happen when dda2 is small as the jumps would be larger
401  *
402  * To invert this,
403  *
404  *  pixel_clock = subcarrier * 4096 / (dda1_inc + dda2_inc / dda2_size)
405  *
406  * The constants below were all computed using a 107.520MHz clock
407  */
408 
409 /**
410  * Register programming values for TV modes.
411  *
412  * These values account for -1s required.
413  */
414 
415 static const struct tv_mode tv_modes[] = {
416 	{
417 		.name		= "NTSC-M",
418 		.clock		= 108000,
419 		.refresh	= 59940,
420 		.oversample	= TV_OVERSAMPLE_8X,
421 		.component_only = 0,
422 		/* 525 Lines, 60 Fields, 15.734KHz line, Sub-Carrier 3.580MHz */
423 
424 		.hsync_end	= 64,		    .hblank_end		= 124,
425 		.hblank_start	= 836,		    .htotal		= 857,
426 
427 		.progressive	= false,	    .trilevel_sync = false,
428 
429 		.vsync_start_f1	= 6,		    .vsync_start_f2	= 7,
430 		.vsync_len	= 6,
431 
432 		.veq_ena	= true,		    .veq_start_f1	= 0,
433 		.veq_start_f2	= 1,		    .veq_len		= 18,
434 
435 		.vi_end_f1	= 20,		    .vi_end_f2		= 21,
436 		.nbr_end	= 240,
437 
438 		.burst_ena	= true,
439 		.hburst_start	= 72,		    .hburst_len		= 34,
440 		.vburst_start_f1 = 9,		    .vburst_end_f1	= 240,
441 		.vburst_start_f2 = 10,		    .vburst_end_f2	= 240,
442 		.vburst_start_f3 = 9,		    .vburst_end_f3	= 240,
443 		.vburst_start_f4 = 10,		    .vburst_end_f4	= 240,
444 
445 		/* desired 3.5800000 actual 3.5800000 clock 107.52 */
446 		.dda1_inc	=    135,
447 		.dda2_inc	=  20800,	    .dda2_size		=  27456,
448 		.dda3_inc	=      0,	    .dda3_size		=      0,
449 		.sc_reset	= TV_SC_RESET_EVERY_4,
450 		.pal_burst	= false,
451 
452 		.composite_levels = &ntsc_m_levels_composite,
453 		.composite_color = &ntsc_m_csc_composite,
454 		.svideo_levels  = &ntsc_m_levels_svideo,
455 		.svideo_color = &ntsc_m_csc_svideo,
456 
457 		.filter_table = filter_table,
458 	},
459 	{
460 		.name		= "NTSC-443",
461 		.clock		= 108000,
462 		.refresh	= 59940,
463 		.oversample	= TV_OVERSAMPLE_8X,
464 		.component_only = 0,
465 		/* 525 Lines, 60 Fields, 15.734KHz line, Sub-Carrier 4.43MHz */
466 		.hsync_end	= 64,		    .hblank_end		= 124,
467 		.hblank_start	= 836,		    .htotal		= 857,
468 
469 		.progressive	= false,	    .trilevel_sync = false,
470 
471 		.vsync_start_f1 = 6,		    .vsync_start_f2	= 7,
472 		.vsync_len	= 6,
473 
474 		.veq_ena	= true,		    .veq_start_f1	= 0,
475 		.veq_start_f2	= 1,		    .veq_len		= 18,
476 
477 		.vi_end_f1	= 20,		    .vi_end_f2		= 21,
478 		.nbr_end	= 240,
479 
480 		.burst_ena	= true,
481 		.hburst_start	= 72,		    .hburst_len		= 34,
482 		.vburst_start_f1 = 9,		    .vburst_end_f1	= 240,
483 		.vburst_start_f2 = 10,		    .vburst_end_f2	= 240,
484 		.vburst_start_f3 = 9,		    .vburst_end_f3	= 240,
485 		.vburst_start_f4 = 10,		    .vburst_end_f4	= 240,
486 
487 		/* desired 4.4336180 actual 4.4336180 clock 107.52 */
488 		.dda1_inc       =    168,
489 		.dda2_inc       =   4093,       .dda2_size      =  27456,
490 		.dda3_inc       =    310,       .dda3_size      =    525,
491 		.sc_reset   = TV_SC_RESET_NEVER,
492 		.pal_burst  = false,
493 
494 		.composite_levels = &ntsc_m_levels_composite,
495 		.composite_color = &ntsc_m_csc_composite,
496 		.svideo_levels  = &ntsc_m_levels_svideo,
497 		.svideo_color = &ntsc_m_csc_svideo,
498 
499 		.filter_table = filter_table,
500 	},
501 	{
502 		.name		= "NTSC-J",
503 		.clock		= 108000,
504 		.refresh	= 59940,
505 		.oversample	= TV_OVERSAMPLE_8X,
506 		.component_only = 0,
507 
508 		/* 525 Lines, 60 Fields, 15.734KHz line, Sub-Carrier 3.580MHz */
509 		.hsync_end	= 64,		    .hblank_end		= 124,
510 		.hblank_start = 836,	    .htotal		= 857,
511 
512 		.progressive	= false,    .trilevel_sync = false,
513 
514 		.vsync_start_f1	= 6,	    .vsync_start_f2	= 7,
515 		.vsync_len	= 6,
516 
517 		.veq_ena      = true,	    .veq_start_f1	= 0,
518 		.veq_start_f2 = 1,	    .veq_len		= 18,
519 
520 		.vi_end_f1	= 20,		    .vi_end_f2		= 21,
521 		.nbr_end	= 240,
522 
523 		.burst_ena	= true,
524 		.hburst_start	= 72,		    .hburst_len		= 34,
525 		.vburst_start_f1 = 9,		    .vburst_end_f1	= 240,
526 		.vburst_start_f2 = 10,		    .vburst_end_f2	= 240,
527 		.vburst_start_f3 = 9,		    .vburst_end_f3	= 240,
528 		.vburst_start_f4 = 10,		    .vburst_end_f4	= 240,
529 
530 		/* desired 3.5800000 actual 3.5800000 clock 107.52 */
531 		.dda1_inc	=    135,
532 		.dda2_inc	=  20800,	    .dda2_size		=  27456,
533 		.dda3_inc	=      0,	    .dda3_size		=      0,
534 		.sc_reset	= TV_SC_RESET_EVERY_4,
535 		.pal_burst	= false,
536 
537 		.composite_levels = &ntsc_j_levels_composite,
538 		.composite_color = &ntsc_j_csc_composite,
539 		.svideo_levels  = &ntsc_j_levels_svideo,
540 		.svideo_color = &ntsc_j_csc_svideo,
541 
542 		.filter_table = filter_table,
543 	},
544 	{
545 		.name		= "PAL-M",
546 		.clock		= 108000,
547 		.refresh	= 59940,
548 		.oversample	= TV_OVERSAMPLE_8X,
549 		.component_only = 0,
550 
551 		/* 525 Lines, 60 Fields, 15.734KHz line, Sub-Carrier 3.580MHz */
552 		.hsync_end	= 64,		  .hblank_end		= 124,
553 		.hblank_start = 836,	  .htotal		= 857,
554 
555 		.progressive	= false,	    .trilevel_sync = false,
556 
557 		.vsync_start_f1	= 6,		    .vsync_start_f2	= 7,
558 		.vsync_len	= 6,
559 
560 		.veq_ena	= true,		    .veq_start_f1	= 0,
561 		.veq_start_f2	= 1,		    .veq_len		= 18,
562 
563 		.vi_end_f1	= 20,		    .vi_end_f2		= 21,
564 		.nbr_end	= 240,
565 
566 		.burst_ena	= true,
567 		.hburst_start	= 72,		    .hburst_len		= 34,
568 		.vburst_start_f1 = 9,		    .vburst_end_f1	= 240,
569 		.vburst_start_f2 = 10,		    .vburst_end_f2	= 240,
570 		.vburst_start_f3 = 9,		    .vburst_end_f3	= 240,
571 		.vburst_start_f4 = 10,		    .vburst_end_f4	= 240,
572 
573 		/* desired 3.5800000 actual 3.5800000 clock 107.52 */
574 		.dda1_inc	=    135,
575 		.dda2_inc	=  16704,	    .dda2_size		=  27456,
576 		.dda3_inc	=      0,	    .dda3_size		=      0,
577 		.sc_reset	= TV_SC_RESET_EVERY_8,
578 		.pal_burst  = true,
579 
580 		.composite_levels = &pal_m_levels_composite,
581 		.composite_color = &pal_m_csc_composite,
582 		.svideo_levels  = &pal_m_levels_svideo,
583 		.svideo_color = &pal_m_csc_svideo,
584 
585 		.filter_table = filter_table,
586 	},
587 	{
588 		/* 625 Lines, 50 Fields, 15.625KHz line, Sub-Carrier 4.434MHz */
589 		.name	    = "PAL-N",
590 		.clock		= 108000,
591 		.refresh	= 50000,
592 		.oversample	= TV_OVERSAMPLE_8X,
593 		.component_only = 0,
594 
595 		.hsync_end	= 64,		    .hblank_end		= 128,
596 		.hblank_start = 844,	    .htotal		= 863,
597 
598 		.progressive  = false,    .trilevel_sync = false,
599 
600 
601 		.vsync_start_f1	= 6,	   .vsync_start_f2	= 7,
602 		.vsync_len	= 6,
603 
604 		.veq_ena	= true,		    .veq_start_f1	= 0,
605 		.veq_start_f2	= 1,		    .veq_len		= 18,
606 
607 		.vi_end_f1	= 24,		    .vi_end_f2		= 25,
608 		.nbr_end	= 286,
609 
610 		.burst_ena	= true,
611 		.hburst_start = 73,	    .hburst_len		= 34,
612 		.vburst_start_f1 = 8,	    .vburst_end_f1	= 285,
613 		.vburst_start_f2 = 8,	    .vburst_end_f2	= 286,
614 		.vburst_start_f3 = 9,	    .vburst_end_f3	= 286,
615 		.vburst_start_f4 = 9,	    .vburst_end_f4	= 285,
616 
617 
618 		/* desired 4.4336180 actual 4.4336180 clock 107.52 */
619 		.dda1_inc       =    135,
620 		.dda2_inc       =  23578,       .dda2_size      =  27648,
621 		.dda3_inc       =    134,       .dda3_size      =    625,
622 		.sc_reset   = TV_SC_RESET_EVERY_8,
623 		.pal_burst  = true,
624 
625 		.composite_levels = &pal_n_levels_composite,
626 		.composite_color = &pal_n_csc_composite,
627 		.svideo_levels  = &pal_n_levels_svideo,
628 		.svideo_color = &pal_n_csc_svideo,
629 
630 		.filter_table = filter_table,
631 	},
632 	{
633 		/* 625 Lines, 50 Fields, 15.625KHz line, Sub-Carrier 4.434MHz */
634 		.name	    = "PAL",
635 		.clock		= 108000,
636 		.refresh	= 50000,
637 		.oversample	= TV_OVERSAMPLE_8X,
638 		.component_only = 0,
639 
640 		.hsync_end	= 64,		    .hblank_end		= 142,
641 		.hblank_start	= 844,	    .htotal		= 863,
642 
643 		.progressive	= false,    .trilevel_sync = false,
644 
645 		.vsync_start_f1	= 5,	    .vsync_start_f2	= 6,
646 		.vsync_len	= 5,
647 
648 		.veq_ena	= true,	    .veq_start_f1	= 0,
649 		.veq_start_f2	= 1,	    .veq_len		= 15,
650 
651 		.vi_end_f1	= 24,		    .vi_end_f2		= 25,
652 		.nbr_end	= 286,
653 
654 		.burst_ena	= true,
655 		.hburst_start	= 73,		    .hburst_len		= 32,
656 		.vburst_start_f1 = 8,		    .vburst_end_f1	= 285,
657 		.vburst_start_f2 = 8,		    .vburst_end_f2	= 286,
658 		.vburst_start_f3 = 9,		    .vburst_end_f3	= 286,
659 		.vburst_start_f4 = 9,		    .vburst_end_f4	= 285,
660 
661 		/* desired 4.4336180 actual 4.4336180 clock 107.52 */
662 		.dda1_inc       =    168,
663 		.dda2_inc       =   4122,       .dda2_size      =  27648,
664 		.dda3_inc       =     67,       .dda3_size      =    625,
665 		.sc_reset   = TV_SC_RESET_EVERY_8,
666 		.pal_burst  = true,
667 
668 		.composite_levels = &pal_levels_composite,
669 		.composite_color = &pal_csc_composite,
670 		.svideo_levels  = &pal_levels_svideo,
671 		.svideo_color = &pal_csc_svideo,
672 
673 		.filter_table = filter_table,
674 	},
675 	{
676 		.name       = "480p",
677 		.clock		= 107520,
678 		.refresh	= 59940,
679 		.oversample     = TV_OVERSAMPLE_4X,
680 		.component_only = 1,
681 
682 		.hsync_end      = 64,               .hblank_end         = 122,
683 		.hblank_start   = 842,              .htotal             = 857,
684 
685 		.progressive    = true,		    .trilevel_sync = false,
686 
687 		.vsync_start_f1 = 12,               .vsync_start_f2     = 12,
688 		.vsync_len      = 12,
689 
690 		.veq_ena        = false,
691 
692 		.vi_end_f1      = 44,               .vi_end_f2          = 44,
693 		.nbr_end        = 479,
694 
695 		.burst_ena      = false,
696 
697 		.filter_table = filter_table,
698 	},
699 	{
700 		.name       = "576p",
701 		.clock		= 107520,
702 		.refresh	= 50000,
703 		.oversample     = TV_OVERSAMPLE_4X,
704 		.component_only = 1,
705 
706 		.hsync_end      = 64,               .hblank_end         = 139,
707 		.hblank_start   = 859,              .htotal             = 863,
708 
709 		.progressive    = true,		    .trilevel_sync = false,
710 
711 		.vsync_start_f1 = 10,               .vsync_start_f2     = 10,
712 		.vsync_len      = 10,
713 
714 		.veq_ena        = false,
715 
716 		.vi_end_f1      = 48,               .vi_end_f2          = 48,
717 		.nbr_end        = 575,
718 
719 		.burst_ena      = false,
720 
721 		.filter_table = filter_table,
722 	},
723 	{
724 		.name       = "720p@60Hz",
725 		.clock		= 148800,
726 		.refresh	= 60000,
727 		.oversample     = TV_OVERSAMPLE_2X,
728 		.component_only = 1,
729 
730 		.hsync_end      = 80,               .hblank_end         = 300,
731 		.hblank_start   = 1580,             .htotal             = 1649,
732 
733 		.progressive	= true,		    .trilevel_sync = true,
734 
735 		.vsync_start_f1 = 10,               .vsync_start_f2     = 10,
736 		.vsync_len      = 10,
737 
738 		.veq_ena        = false,
739 
740 		.vi_end_f1      = 29,               .vi_end_f2          = 29,
741 		.nbr_end        = 719,
742 
743 		.burst_ena      = false,
744 
745 		.filter_table = filter_table,
746 	},
747 	{
748 		.name       = "720p@50Hz",
749 		.clock		= 148800,
750 		.refresh	= 50000,
751 		.oversample     = TV_OVERSAMPLE_2X,
752 		.component_only = 1,
753 
754 		.hsync_end      = 80,               .hblank_end         = 300,
755 		.hblank_start   = 1580,             .htotal             = 1979,
756 
757 		.progressive	= true,		    .trilevel_sync = true,
758 
759 		.vsync_start_f1 = 10,               .vsync_start_f2     = 10,
760 		.vsync_len      = 10,
761 
762 		.veq_ena        = false,
763 
764 		.vi_end_f1      = 29,               .vi_end_f2          = 29,
765 		.nbr_end        = 719,
766 
767 		.burst_ena      = false,
768 
769 		.filter_table = filter_table,
770 		.max_srcw = 800
771 	},
772 	{
773 		.name       = "1080i@50Hz",
774 		.clock		= 148800,
775 		.refresh	= 50000,
776 		.oversample     = TV_OVERSAMPLE_2X,
777 		.component_only = 1,
778 
779 		.hsync_end      = 88,               .hblank_end         = 235,
780 		.hblank_start   = 2155,             .htotal             = 2639,
781 
782 		.progressive	= false,	  .trilevel_sync = true,
783 
784 		.vsync_start_f1 = 4,              .vsync_start_f2     = 5,
785 		.vsync_len      = 10,
786 
787 		.veq_ena	= true,	    .veq_start_f1	= 4,
788 		.veq_start_f2   = 4,	    .veq_len		= 10,
789 
790 
791 		.vi_end_f1      = 21,           .vi_end_f2          = 22,
792 		.nbr_end        = 539,
793 
794 		.burst_ena      = false,
795 
796 		.filter_table = filter_table,
797 	},
798 	{
799 		.name       = "1080i@60Hz",
800 		.clock		= 148800,
801 		.refresh	= 60000,
802 		.oversample     = TV_OVERSAMPLE_2X,
803 		.component_only = 1,
804 
805 		.hsync_end      = 88,               .hblank_end         = 235,
806 		.hblank_start   = 2155,             .htotal             = 2199,
807 
808 		.progressive	= false,	    .trilevel_sync = true,
809 
810 		.vsync_start_f1 = 4,               .vsync_start_f2     = 5,
811 		.vsync_len      = 10,
812 
813 		.veq_ena	= true,		    .veq_start_f1	= 4,
814 		.veq_start_f2	= 4,		    .veq_len		= 10,
815 
816 
817 		.vi_end_f1      = 21,               .vi_end_f2          = 22,
818 		.nbr_end        = 539,
819 
820 		.burst_ena      = false,
821 
822 		.filter_table = filter_table,
823 	},
824 };
825 
826 static struct intel_tv *enc_to_intel_tv(struct drm_encoder *encoder)
827 {
828 	return container_of(encoder, struct intel_tv, base.base);
829 }
830 
831 static struct intel_tv *intel_attached_tv(struct drm_connector *connector)
832 {
833 	return container_of(intel_attached_encoder(connector),
834 			    struct intel_tv,
835 			    base);
836 }
837 
838 static bool
839 intel_tv_get_hw_state(struct intel_encoder *encoder, enum i915_pipe *pipe)
840 {
841 	struct drm_device *dev = encoder->base.dev;
842 	struct drm_i915_private *dev_priv = dev->dev_private;
843 	u32 tmp = I915_READ(TV_CTL);
844 
845 	if (!(tmp & TV_ENC_ENABLE))
846 		return false;
847 
848 	*pipe = PORT_TO_PIPE(tmp);
849 
850 	return true;
851 }
852 
853 static void
854 intel_enable_tv(struct intel_encoder *encoder)
855 {
856 	struct drm_device *dev = encoder->base.dev;
857 	struct drm_i915_private *dev_priv = dev->dev_private;
858 
859 	I915_WRITE(TV_CTL, I915_READ(TV_CTL) | TV_ENC_ENABLE);
860 }
861 
862 static void
863 intel_disable_tv(struct intel_encoder *encoder)
864 {
865 	struct drm_device *dev = encoder->base.dev;
866 	struct drm_i915_private *dev_priv = dev->dev_private;
867 
868 	I915_WRITE(TV_CTL, I915_READ(TV_CTL) & ~TV_ENC_ENABLE);
869 }
870 
871 static const struct tv_mode *
872 intel_tv_mode_lookup(const char *tv_format)
873 {
874 	int i;
875 
876 	for (i = 0; i < ARRAY_SIZE(tv_modes); i++) {
877 		const struct tv_mode *tv_mode = &tv_modes[i];
878 
879 		if (!strcmp(tv_format, tv_mode->name))
880 			return tv_mode;
881 	}
882 	return NULL;
883 }
884 
885 static const struct tv_mode *
886 intel_tv_mode_find(struct intel_tv *intel_tv)
887 {
888 	return intel_tv_mode_lookup(intel_tv->tv_format);
889 }
890 
891 static enum drm_mode_status
892 intel_tv_mode_valid(struct drm_connector *connector,
893 		    struct drm_display_mode *mode)
894 {
895 	struct intel_tv *intel_tv = intel_attached_tv(connector);
896 	const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv);
897 
898 	/* Ensure TV refresh is close to desired refresh */
899 	if (tv_mode && abs(tv_mode->refresh - drm_mode_vrefresh(mode) * 1000)
900 				< 1000)
901 		return MODE_OK;
902 
903 	return MODE_CLOCK_RANGE;
904 }
905 
906 
907 static bool
908 intel_tv_compute_config(struct intel_encoder *encoder,
909 			struct intel_crtc_config *pipe_config)
910 {
911 	struct intel_tv *intel_tv = enc_to_intel_tv(&encoder->base);
912 	const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv);
913 
914 	if (!tv_mode)
915 		return false;
916 
917 	pipe_config->adjusted_mode.clock = tv_mode->clock;
918 	DRM_DEBUG_KMS("forcing bpc to 8 for TV\n");
919 	pipe_config->pipe_bpp = 8*3;
920 
921 	return true;
922 }
923 
924 static void
925 intel_tv_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,
926 		  struct drm_display_mode *adjusted_mode)
927 {
928 	struct drm_device *dev = encoder->dev;
929 	struct drm_i915_private *dev_priv = dev->dev_private;
930 	struct drm_crtc *crtc = encoder->crtc;
931 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
932 	struct intel_tv *intel_tv = enc_to_intel_tv(encoder);
933 	const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv);
934 	u32 tv_ctl;
935 	u32 hctl1, hctl2, hctl3;
936 	u32 vctl1, vctl2, vctl3, vctl4, vctl5, vctl6, vctl7;
937 	u32 scctl1, scctl2, scctl3;
938 	int i, j;
939 	const struct video_levels *video_levels;
940 	const struct color_conversion *color_conversion;
941 	bool burst_ena;
942 	int pipe = intel_crtc->pipe;
943 
944 	if (!tv_mode)
945 		return;	/* can't happen (mode_prepare prevents this) */
946 
947 	tv_ctl = I915_READ(TV_CTL);
948 	tv_ctl &= TV_CTL_SAVE;
949 
950 	switch (intel_tv->type) {
951 	default:
952 	case DRM_MODE_CONNECTOR_Unknown:
953 	case DRM_MODE_CONNECTOR_Composite:
954 		tv_ctl |= TV_ENC_OUTPUT_COMPOSITE;
955 		video_levels = tv_mode->composite_levels;
956 		color_conversion = tv_mode->composite_color;
957 		burst_ena = tv_mode->burst_ena;
958 		break;
959 	case DRM_MODE_CONNECTOR_Component:
960 		tv_ctl |= TV_ENC_OUTPUT_COMPONENT;
961 		video_levels = &component_levels;
962 		if (tv_mode->burst_ena)
963 			color_conversion = &sdtv_csc_yprpb;
964 		else
965 			color_conversion = &hdtv_csc_yprpb;
966 		burst_ena = false;
967 		break;
968 	case DRM_MODE_CONNECTOR_SVIDEO:
969 		tv_ctl |= TV_ENC_OUTPUT_SVIDEO;
970 		video_levels = tv_mode->svideo_levels;
971 		color_conversion = tv_mode->svideo_color;
972 		burst_ena = tv_mode->burst_ena;
973 		break;
974 	}
975 	hctl1 = (tv_mode->hsync_end << TV_HSYNC_END_SHIFT) |
976 		(tv_mode->htotal << TV_HTOTAL_SHIFT);
977 
978 	hctl2 = (tv_mode->hburst_start << 16) |
979 		(tv_mode->hburst_len << TV_HBURST_LEN_SHIFT);
980 
981 	if (burst_ena)
982 		hctl2 |= TV_BURST_ENA;
983 
984 	hctl3 = (tv_mode->hblank_start << TV_HBLANK_START_SHIFT) |
985 		(tv_mode->hblank_end << TV_HBLANK_END_SHIFT);
986 
987 	vctl1 = (tv_mode->nbr_end << TV_NBR_END_SHIFT) |
988 		(tv_mode->vi_end_f1 << TV_VI_END_F1_SHIFT) |
989 		(tv_mode->vi_end_f2 << TV_VI_END_F2_SHIFT);
990 
991 	vctl2 = (tv_mode->vsync_len << TV_VSYNC_LEN_SHIFT) |
992 		(tv_mode->vsync_start_f1 << TV_VSYNC_START_F1_SHIFT) |
993 		(tv_mode->vsync_start_f2 << TV_VSYNC_START_F2_SHIFT);
994 
995 	vctl3 = (tv_mode->veq_len << TV_VEQ_LEN_SHIFT) |
996 		(tv_mode->veq_start_f1 << TV_VEQ_START_F1_SHIFT) |
997 		(tv_mode->veq_start_f2 << TV_VEQ_START_F2_SHIFT);
998 
999 	if (tv_mode->veq_ena)
1000 		vctl3 |= TV_EQUAL_ENA;
1001 
1002 	vctl4 = (tv_mode->vburst_start_f1 << TV_VBURST_START_F1_SHIFT) |
1003 		(tv_mode->vburst_end_f1 << TV_VBURST_END_F1_SHIFT);
1004 
1005 	vctl5 = (tv_mode->vburst_start_f2 << TV_VBURST_START_F2_SHIFT) |
1006 		(tv_mode->vburst_end_f2 << TV_VBURST_END_F2_SHIFT);
1007 
1008 	vctl6 = (tv_mode->vburst_start_f3 << TV_VBURST_START_F3_SHIFT) |
1009 		(tv_mode->vburst_end_f3 << TV_VBURST_END_F3_SHIFT);
1010 
1011 	vctl7 = (tv_mode->vburst_start_f4 << TV_VBURST_START_F4_SHIFT) |
1012 		(tv_mode->vburst_end_f4 << TV_VBURST_END_F4_SHIFT);
1013 
1014 	if (intel_crtc->pipe == 1)
1015 		tv_ctl |= TV_ENC_PIPEB_SELECT;
1016 	tv_ctl |= tv_mode->oversample;
1017 
1018 	if (tv_mode->progressive)
1019 		tv_ctl |= TV_PROGRESSIVE;
1020 	if (tv_mode->trilevel_sync)
1021 		tv_ctl |= TV_TRILEVEL_SYNC;
1022 	if (tv_mode->pal_burst)
1023 		tv_ctl |= TV_PAL_BURST;
1024 
1025 	scctl1 = 0;
1026 	if (tv_mode->dda1_inc)
1027 		scctl1 |= TV_SC_DDA1_EN;
1028 	if (tv_mode->dda2_inc)
1029 		scctl1 |= TV_SC_DDA2_EN;
1030 	if (tv_mode->dda3_inc)
1031 		scctl1 |= TV_SC_DDA3_EN;
1032 	scctl1 |= tv_mode->sc_reset;
1033 	if (video_levels)
1034 		scctl1 |= video_levels->burst << TV_BURST_LEVEL_SHIFT;
1035 	scctl1 |= tv_mode->dda1_inc << TV_SCDDA1_INC_SHIFT;
1036 
1037 	scctl2 = tv_mode->dda2_size << TV_SCDDA2_SIZE_SHIFT |
1038 		tv_mode->dda2_inc << TV_SCDDA2_INC_SHIFT;
1039 
1040 	scctl3 = tv_mode->dda3_size << TV_SCDDA3_SIZE_SHIFT |
1041 		tv_mode->dda3_inc << TV_SCDDA3_INC_SHIFT;
1042 
1043 	/* Enable two fixes for the chips that need them. */
1044 	if (dev->pci_device < 0x2772)
1045 		tv_ctl |= TV_ENC_C0_FIX | TV_ENC_SDP_FIX;
1046 
1047 	I915_WRITE(TV_H_CTL_1, hctl1);
1048 	I915_WRITE(TV_H_CTL_2, hctl2);
1049 	I915_WRITE(TV_H_CTL_3, hctl3);
1050 	I915_WRITE(TV_V_CTL_1, vctl1);
1051 	I915_WRITE(TV_V_CTL_2, vctl2);
1052 	I915_WRITE(TV_V_CTL_3, vctl3);
1053 	I915_WRITE(TV_V_CTL_4, vctl4);
1054 	I915_WRITE(TV_V_CTL_5, vctl5);
1055 	I915_WRITE(TV_V_CTL_6, vctl6);
1056 	I915_WRITE(TV_V_CTL_7, vctl7);
1057 	I915_WRITE(TV_SC_CTL_1, scctl1);
1058 	I915_WRITE(TV_SC_CTL_2, scctl2);
1059 	I915_WRITE(TV_SC_CTL_3, scctl3);
1060 
1061 	if (color_conversion) {
1062 		I915_WRITE(TV_CSC_Y, (color_conversion->ry << 16) |
1063 			   color_conversion->gy);
1064 		I915_WRITE(TV_CSC_Y2, (color_conversion->by << 16) |
1065 			   color_conversion->ay);
1066 		I915_WRITE(TV_CSC_U, (color_conversion->ru << 16) |
1067 			   color_conversion->gu);
1068 		I915_WRITE(TV_CSC_U2, (color_conversion->bu << 16) |
1069 			   color_conversion->au);
1070 		I915_WRITE(TV_CSC_V, (color_conversion->rv << 16) |
1071 			   color_conversion->gv);
1072 		I915_WRITE(TV_CSC_V2, (color_conversion->bv << 16) |
1073 			   color_conversion->av);
1074 	}
1075 
1076 	if (INTEL_INFO(dev)->gen >= 4)
1077 		I915_WRITE(TV_CLR_KNOBS, 0x00404000);
1078 	else
1079 		I915_WRITE(TV_CLR_KNOBS, 0x00606000);
1080 
1081 	if (video_levels)
1082 		I915_WRITE(TV_CLR_LEVEL,
1083 			   ((video_levels->black << TV_BLACK_LEVEL_SHIFT) |
1084 			    (video_levels->blank << TV_BLANK_LEVEL_SHIFT)));
1085 	{
1086 		int pipeconf_reg = PIPECONF(pipe);
1087 		int dspcntr_reg = DSPCNTR(intel_crtc->plane);
1088 		int pipeconf = I915_READ(pipeconf_reg);
1089 		int dspcntr = I915_READ(dspcntr_reg);
1090 		int xpos = 0x0, ypos = 0x0;
1091 		unsigned int xsize, ysize;
1092 		/* Pipe must be off here */
1093 		I915_WRITE(dspcntr_reg, dspcntr & ~DISPLAY_PLANE_ENABLE);
1094 		intel_flush_display_plane(dev_priv, intel_crtc->plane);
1095 
1096 		/* Wait for vblank for the disable to take effect */
1097 		if (IS_GEN2(dev))
1098 			intel_wait_for_vblank(dev, intel_crtc->pipe);
1099 
1100 		I915_WRITE(pipeconf_reg, pipeconf & ~PIPECONF_ENABLE);
1101 		/* Wait for vblank for the disable to take effect. */
1102 		intel_wait_for_pipe_off(dev, intel_crtc->pipe);
1103 
1104 		/* Filter ctl must be set before TV_WIN_SIZE */
1105 		I915_WRITE(TV_FILTER_CTL_1, TV_AUTO_SCALE);
1106 		xsize = tv_mode->hblank_start - tv_mode->hblank_end;
1107 		if (tv_mode->progressive)
1108 			ysize = tv_mode->nbr_end + 1;
1109 		else
1110 			ysize = 2*tv_mode->nbr_end + 1;
1111 
1112 		xpos += intel_tv->margin[TV_MARGIN_LEFT];
1113 		ypos += intel_tv->margin[TV_MARGIN_TOP];
1114 		xsize -= (intel_tv->margin[TV_MARGIN_LEFT] +
1115 			  intel_tv->margin[TV_MARGIN_RIGHT]);
1116 		ysize -= (intel_tv->margin[TV_MARGIN_TOP] +
1117 			  intel_tv->margin[TV_MARGIN_BOTTOM]);
1118 		I915_WRITE(TV_WIN_POS, (xpos<<16)|ypos);
1119 		I915_WRITE(TV_WIN_SIZE, (xsize<<16)|ysize);
1120 
1121 		I915_WRITE(pipeconf_reg, pipeconf);
1122 		I915_WRITE(dspcntr_reg, dspcntr);
1123 		intel_flush_display_plane(dev_priv, intel_crtc->plane);
1124 	}
1125 
1126 	j = 0;
1127 	for (i = 0; i < 60; i++)
1128 		I915_WRITE(TV_H_LUMA_0 + (i<<2), tv_mode->filter_table[j++]);
1129 	for (i = 0; i < 60; i++)
1130 		I915_WRITE(TV_H_CHROMA_0 + (i<<2), tv_mode->filter_table[j++]);
1131 	for (i = 0; i < 43; i++)
1132 		I915_WRITE(TV_V_LUMA_0 + (i<<2), tv_mode->filter_table[j++]);
1133 	for (i = 0; i < 43; i++)
1134 		I915_WRITE(TV_V_CHROMA_0 + (i<<2), tv_mode->filter_table[j++]);
1135 	I915_WRITE(TV_DAC, I915_READ(TV_DAC) & TV_DAC_SAVE);
1136 	I915_WRITE(TV_CTL, tv_ctl);
1137 }
1138 
1139 static const struct drm_display_mode reported_modes[] = {
1140 	{
1141 		.name = "NTSC 480i",
1142 		.clock = 107520,
1143 		.hdisplay = 1280,
1144 		.hsync_start = 1368,
1145 		.hsync_end = 1496,
1146 		.htotal = 1712,
1147 
1148 		.vdisplay = 1024,
1149 		.vsync_start = 1027,
1150 		.vsync_end = 1034,
1151 		.vtotal = 1104,
1152 		.type = DRM_MODE_TYPE_DRIVER,
1153 	},
1154 };
1155 
1156 /**
1157  * Detects TV presence by checking for load.
1158  *
1159  * Requires that the current pipe's DPLL is active.
1160 
1161  * \return true if TV is connected.
1162  * \return false if TV is disconnected.
1163  */
1164 static int
1165 intel_tv_detect_type(struct intel_tv *intel_tv,
1166 		      struct drm_connector *connector)
1167 {
1168 	struct drm_encoder *encoder = &intel_tv->base.base;
1169 	struct drm_crtc *crtc = encoder->crtc;
1170 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
1171 	struct drm_device *dev = encoder->dev;
1172 	struct drm_i915_private *dev_priv = dev->dev_private;
1173 	u32 tv_ctl, save_tv_ctl;
1174 	u32 tv_dac, save_tv_dac;
1175 	int type;
1176 
1177 	/* Disable TV interrupts around load detect or we'll recurse */
1178 	if (connector->polled & DRM_CONNECTOR_POLL_HPD) {
1179 		lockmgr(&dev_priv->irq_lock, LK_EXCLUSIVE);
1180 		i915_disable_pipestat(dev_priv, 0,
1181 				      PIPE_HOTPLUG_INTERRUPT_ENABLE |
1182 				      PIPE_HOTPLUG_TV_INTERRUPT_ENABLE);
1183 		lockmgr(&dev_priv->irq_lock, LK_RELEASE);
1184 	}
1185 
1186 	save_tv_dac = tv_dac = I915_READ(TV_DAC);
1187 	save_tv_ctl = tv_ctl = I915_READ(TV_CTL);
1188 
1189 	/* Poll for TV detection */
1190 	tv_ctl &= ~(TV_ENC_ENABLE | TV_TEST_MODE_MASK);
1191 	tv_ctl |= TV_TEST_MODE_MONITOR_DETECT;
1192 	if (intel_crtc->pipe == 1)
1193 		tv_ctl |= TV_ENC_PIPEB_SELECT;
1194 	else
1195 		tv_ctl &= ~TV_ENC_PIPEB_SELECT;
1196 
1197 	tv_dac &= ~(TVDAC_SENSE_MASK | DAC_A_MASK | DAC_B_MASK | DAC_C_MASK);
1198 	tv_dac |= (TVDAC_STATE_CHG_EN |
1199 		   TVDAC_A_SENSE_CTL |
1200 		   TVDAC_B_SENSE_CTL |
1201 		   TVDAC_C_SENSE_CTL |
1202 		   DAC_CTL_OVERRIDE |
1203 		   DAC_A_0_7_V |
1204 		   DAC_B_0_7_V |
1205 		   DAC_C_0_7_V);
1206 
1207 
1208 	/*
1209 	 * The TV sense state should be cleared to zero on cantiga platform. Otherwise
1210 	 * the TV is misdetected. This is hardware requirement.
1211 	 */
1212 	if (IS_GM45(dev))
1213 		tv_dac &= ~(TVDAC_STATE_CHG_EN | TVDAC_A_SENSE_CTL |
1214 			    TVDAC_B_SENSE_CTL | TVDAC_C_SENSE_CTL);
1215 
1216 	I915_WRITE(TV_CTL, tv_ctl);
1217 	I915_WRITE(TV_DAC, tv_dac);
1218 	POSTING_READ(TV_DAC);
1219 
1220 	intel_wait_for_vblank(intel_tv->base.base.dev,
1221 			      to_intel_crtc(intel_tv->base.base.crtc)->pipe);
1222 
1223 	type = -1;
1224 	tv_dac = I915_READ(TV_DAC);
1225 	DRM_DEBUG_KMS("TV detected: %x, %x\n", tv_ctl, tv_dac);
1226 	/*
1227 	 *  A B C
1228 	 *  0 1 1 Composite
1229 	 *  1 0 X svideo
1230 	 *  0 0 0 Component
1231 	 */
1232 	if ((tv_dac & TVDAC_SENSE_MASK) == (TVDAC_B_SENSE | TVDAC_C_SENSE)) {
1233 		DRM_DEBUG_KMS("Detected Composite TV connection\n");
1234 		type = DRM_MODE_CONNECTOR_Composite;
1235 	} else if ((tv_dac & (TVDAC_A_SENSE|TVDAC_B_SENSE)) == TVDAC_A_SENSE) {
1236 		DRM_DEBUG_KMS("Detected S-Video TV connection\n");
1237 		type = DRM_MODE_CONNECTOR_SVIDEO;
1238 	} else if ((tv_dac & TVDAC_SENSE_MASK) == 0) {
1239 		DRM_DEBUG_KMS("Detected Component TV connection\n");
1240 		type = DRM_MODE_CONNECTOR_Component;
1241 	} else {
1242 		DRM_DEBUG_KMS("Unrecognised TV connection\n");
1243 		type = -1;
1244 	}
1245 
1246 	I915_WRITE(TV_DAC, save_tv_dac & ~TVDAC_STATE_CHG_EN);
1247 	I915_WRITE(TV_CTL, save_tv_ctl);
1248 	POSTING_READ(TV_CTL);
1249 
1250 	/* For unknown reasons the hw barfs if we don't do this vblank wait. */
1251 	intel_wait_for_vblank(intel_tv->base.base.dev,
1252 			      to_intel_crtc(intel_tv->base.base.crtc)->pipe);
1253 
1254 	/* Restore interrupt config */
1255 	if (connector->polled & DRM_CONNECTOR_POLL_HPD) {
1256 		lockmgr(&dev_priv->irq_lock, LK_EXCLUSIVE);
1257 		i915_enable_pipestat(dev_priv, 0,
1258 				     PIPE_HOTPLUG_INTERRUPT_ENABLE |
1259 				     PIPE_HOTPLUG_TV_INTERRUPT_ENABLE);
1260 		lockmgr(&dev_priv->irq_lock, LK_RELEASE);
1261 	}
1262 
1263 	return type;
1264 }
1265 
1266 /*
1267  * Here we set accurate tv format according to connector type
1268  * i.e Component TV should not be assigned by NTSC or PAL
1269  */
1270 static void intel_tv_find_better_format(struct drm_connector *connector)
1271 {
1272 	struct intel_tv *intel_tv = intel_attached_tv(connector);
1273 	const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv);
1274 	int i;
1275 
1276 	if ((intel_tv->type == DRM_MODE_CONNECTOR_Component) ==
1277 		tv_mode->component_only)
1278 		return;
1279 
1280 
1281 	for (i = 0; i < sizeof(tv_modes) / sizeof(*tv_modes); i++) {
1282 		tv_mode = tv_modes + i;
1283 
1284 		if ((intel_tv->type == DRM_MODE_CONNECTOR_Component) ==
1285 			tv_mode->component_only)
1286 			break;
1287 	}
1288 
1289 	intel_tv->tv_format = tv_mode->name;
1290 	drm_object_property_set_value(&connector->base,
1291 		connector->dev->mode_config.tv_mode_property, i);
1292 }
1293 
1294 /**
1295  * Detect the TV connection.
1296  *
1297  * Currently this always returns CONNECTOR_STATUS_UNKNOWN, as we need to be sure
1298  * we have a pipe programmed in order to probe the TV.
1299  */
1300 static enum drm_connector_status
1301 intel_tv_detect(struct drm_connector *connector, bool force)
1302 {
1303 	struct drm_display_mode mode;
1304 	struct intel_tv *intel_tv = intel_attached_tv(connector);
1305 	int type;
1306 
1307 	mode = reported_modes[0];
1308 
1309 	if (force) {
1310 		struct intel_load_detect_pipe tmp;
1311 
1312 		if (intel_get_load_detect_pipe(connector, &mode, &tmp)) {
1313 			type = intel_tv_detect_type(intel_tv, connector);
1314 			intel_release_load_detect_pipe(connector, &tmp);
1315 		} else
1316 			return connector_status_unknown;
1317 	} else
1318 		return connector->status;
1319 
1320 	if (type < 0)
1321 		return connector_status_disconnected;
1322 
1323 	intel_tv->type = type;
1324 	intel_tv_find_better_format(connector);
1325 
1326 	return connector_status_connected;
1327 }
1328 
1329 static const struct input_res {
1330 	const char *name;
1331 	int w, h;
1332 } input_res_table[] = {
1333 	{"640x480", 640, 480},
1334 	{"800x600", 800, 600},
1335 	{"1024x768", 1024, 768},
1336 	{"1280x1024", 1280, 1024},
1337 	{"848x480", 848, 480},
1338 	{"1280x720", 1280, 720},
1339 	{"1920x1080", 1920, 1080},
1340 };
1341 
1342 /*
1343  * Chose preferred mode  according to line number of TV format
1344  */
1345 static void
1346 intel_tv_chose_preferred_modes(struct drm_connector *connector,
1347 			       struct drm_display_mode *mode_ptr)
1348 {
1349 	struct intel_tv *intel_tv = intel_attached_tv(connector);
1350 	const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv);
1351 
1352 	if (tv_mode->nbr_end < 480 && mode_ptr->vdisplay == 480)
1353 		mode_ptr->type |= DRM_MODE_TYPE_PREFERRED;
1354 	else if (tv_mode->nbr_end > 480) {
1355 		if (tv_mode->progressive == true && tv_mode->nbr_end < 720) {
1356 			if (mode_ptr->vdisplay == 720)
1357 				mode_ptr->type |= DRM_MODE_TYPE_PREFERRED;
1358 		} else if (mode_ptr->vdisplay == 1080)
1359 				mode_ptr->type |= DRM_MODE_TYPE_PREFERRED;
1360 	}
1361 }
1362 
1363 /**
1364  * Stub get_modes function.
1365  *
1366  * This should probably return a set of fixed modes, unless we can figure out
1367  * how to probe modes off of TV connections.
1368  */
1369 
1370 static int
1371 intel_tv_get_modes(struct drm_connector *connector)
1372 {
1373 	struct drm_display_mode *mode_ptr;
1374 	struct intel_tv *intel_tv = intel_attached_tv(connector);
1375 	const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv);
1376 	int j, count = 0;
1377 	u64 tmp;
1378 
1379 	for (j = 0; j < ARRAY_SIZE(input_res_table);
1380 	     j++) {
1381 		const struct input_res *input = &input_res_table[j];
1382 		unsigned int hactive_s = input->w;
1383 		unsigned int vactive_s = input->h;
1384 
1385 		if (tv_mode->max_srcw && input->w > tv_mode->max_srcw)
1386 			continue;
1387 
1388 		if (input->w > 1024 && (!tv_mode->progressive
1389 					&& !tv_mode->component_only))
1390 			continue;
1391 
1392 		mode_ptr = drm_mode_create(connector->dev);
1393 		if (!mode_ptr)
1394 			continue;
1395 		strncpy(mode_ptr->name, input->name, DRM_DISPLAY_MODE_LEN);
1396 
1397 		mode_ptr->hdisplay = hactive_s;
1398 		mode_ptr->hsync_start = hactive_s + 1;
1399 		mode_ptr->hsync_end = hactive_s + 64;
1400 		if (mode_ptr->hsync_end <= mode_ptr->hsync_start)
1401 			mode_ptr->hsync_end = mode_ptr->hsync_start + 1;
1402 		mode_ptr->htotal = hactive_s + 96;
1403 
1404 		mode_ptr->vdisplay = vactive_s;
1405 		mode_ptr->vsync_start = vactive_s + 1;
1406 		mode_ptr->vsync_end = vactive_s + 32;
1407 		if (mode_ptr->vsync_end <= mode_ptr->vsync_start)
1408 			mode_ptr->vsync_end = mode_ptr->vsync_start  + 1;
1409 		mode_ptr->vtotal = vactive_s + 33;
1410 
1411 		tmp = (u64) tv_mode->refresh * mode_ptr->vtotal;
1412 		tmp *= mode_ptr->htotal;
1413 		tmp = div_u64(tmp, 1000000);
1414 		mode_ptr->clock = (int) tmp;
1415 
1416 		mode_ptr->type = DRM_MODE_TYPE_DRIVER;
1417 		intel_tv_chose_preferred_modes(connector, mode_ptr);
1418 		drm_mode_probed_add(connector, mode_ptr);
1419 		count++;
1420 	}
1421 
1422 	return count;
1423 }
1424 
1425 static void
1426 intel_tv_destroy(struct drm_connector *connector)
1427 {
1428 	drm_sysfs_connector_remove(connector);
1429 	drm_connector_cleanup(connector);
1430 	kfree(connector);
1431 }
1432 
1433 
1434 static int
1435 intel_tv_set_property(struct drm_connector *connector, struct drm_property *property,
1436 		      uint64_t val)
1437 {
1438 	struct drm_device *dev = connector->dev;
1439 	struct intel_tv *intel_tv = intel_attached_tv(connector);
1440 	struct drm_crtc *crtc = intel_tv->base.base.crtc;
1441 	int ret = 0;
1442 	bool changed = false;
1443 
1444 	ret = drm_object_property_set_value(&connector->base, property, val);
1445 	if (ret < 0)
1446 		goto out;
1447 
1448 	if (property == dev->mode_config.tv_left_margin_property &&
1449 		intel_tv->margin[TV_MARGIN_LEFT] != val) {
1450 		intel_tv->margin[TV_MARGIN_LEFT] = val;
1451 		changed = true;
1452 	} else if (property == dev->mode_config.tv_right_margin_property &&
1453 		intel_tv->margin[TV_MARGIN_RIGHT] != val) {
1454 		intel_tv->margin[TV_MARGIN_RIGHT] = val;
1455 		changed = true;
1456 	} else if (property == dev->mode_config.tv_top_margin_property &&
1457 		intel_tv->margin[TV_MARGIN_TOP] != val) {
1458 		intel_tv->margin[TV_MARGIN_TOP] = val;
1459 		changed = true;
1460 	} else if (property == dev->mode_config.tv_bottom_margin_property &&
1461 		intel_tv->margin[TV_MARGIN_BOTTOM] != val) {
1462 		intel_tv->margin[TV_MARGIN_BOTTOM] = val;
1463 		changed = true;
1464 	} else if (property == dev->mode_config.tv_mode_property) {
1465 		if (val >= ARRAY_SIZE(tv_modes)) {
1466 			ret = -EINVAL;
1467 			goto out;
1468 		}
1469 		if (!strcmp(intel_tv->tv_format, tv_modes[val].name))
1470 			goto out;
1471 
1472 		intel_tv->tv_format = tv_modes[val].name;
1473 		changed = true;
1474 	} else {
1475 		ret = -EINVAL;
1476 		goto out;
1477 	}
1478 
1479 	if (changed && crtc)
1480 		intel_crtc_restore_mode(crtc);
1481 out:
1482 	return ret;
1483 }
1484 
1485 static const struct drm_encoder_helper_funcs intel_tv_helper_funcs = {
1486 	.mode_set = intel_tv_mode_set,
1487 };
1488 
1489 static const struct drm_connector_funcs intel_tv_connector_funcs = {
1490 	.dpms = intel_connector_dpms,
1491 	.detect = intel_tv_detect,
1492 	.destroy = intel_tv_destroy,
1493 	.set_property = intel_tv_set_property,
1494 	.fill_modes = drm_helper_probe_single_connector_modes,
1495 };
1496 
1497 static const struct drm_connector_helper_funcs intel_tv_connector_helper_funcs = {
1498 	.mode_valid = intel_tv_mode_valid,
1499 	.get_modes = intel_tv_get_modes,
1500 	.best_encoder = intel_best_encoder,
1501 };
1502 
1503 static const struct drm_encoder_funcs intel_tv_enc_funcs = {
1504 	.destroy = intel_encoder_destroy,
1505 };
1506 
1507 /*
1508  * Enumerate the child dev array parsed from VBT to check whether
1509  * the integrated TV is present.
1510  * If it is present, return 1.
1511  * If it is not present, return false.
1512  * If no child dev is parsed from VBT, it assumes that the TV is present.
1513  */
1514 static int tv_is_present_in_vbt(struct drm_device *dev)
1515 {
1516 	struct drm_i915_private *dev_priv = dev->dev_private;
1517 	struct child_device_config *p_child;
1518 	int i, ret;
1519 
1520 	if (!dev_priv->vbt.child_dev_num)
1521 		return 1;
1522 
1523 	ret = 0;
1524 	for (i = 0; i < dev_priv->vbt.child_dev_num; i++) {
1525 		p_child = dev_priv->vbt.child_dev + i;
1526 		/*
1527 		 * If the device type is not TV, continue.
1528 		 */
1529 		if (p_child->device_type != DEVICE_TYPE_INT_TV &&
1530 			p_child->device_type != DEVICE_TYPE_TV)
1531 			continue;
1532 		/* Only when the addin_offset is non-zero, it is regarded
1533 		 * as present.
1534 		 */
1535 		if (p_child->addin_offset) {
1536 			ret = 1;
1537 			break;
1538 		}
1539 	}
1540 	return ret;
1541 }
1542 
1543 void
1544 intel_tv_init(struct drm_device *dev)
1545 {
1546 	struct drm_i915_private *dev_priv = dev->dev_private;
1547 	struct drm_connector *connector;
1548 	struct intel_tv *intel_tv;
1549 	struct intel_encoder *intel_encoder;
1550 	struct intel_connector *intel_connector;
1551 	u32 tv_dac_on, tv_dac_off, save_tv_dac;
1552 	char *tv_format_names[ARRAY_SIZE(tv_modes)];
1553 	int i, initial_mode = 0;
1554 
1555 	if ((I915_READ(TV_CTL) & TV_FUSE_STATE_MASK) == TV_FUSE_STATE_DISABLED)
1556 		return;
1557 
1558 	if (!tv_is_present_in_vbt(dev)) {
1559 		DRM_DEBUG_KMS("Integrated TV is not present.\n");
1560 		return;
1561 	}
1562 	/* Even if we have an encoder we may not have a connector */
1563 	if (!dev_priv->vbt.int_tv_support)
1564 		return;
1565 
1566 	/*
1567 	 * Sanity check the TV output by checking to see if the
1568 	 * DAC register holds a value
1569 	 */
1570 	save_tv_dac = I915_READ(TV_DAC);
1571 
1572 	I915_WRITE(TV_DAC, save_tv_dac | TVDAC_STATE_CHG_EN);
1573 	tv_dac_on = I915_READ(TV_DAC);
1574 
1575 	I915_WRITE(TV_DAC, save_tv_dac & ~TVDAC_STATE_CHG_EN);
1576 	tv_dac_off = I915_READ(TV_DAC);
1577 
1578 	I915_WRITE(TV_DAC, save_tv_dac);
1579 
1580 	/*
1581 	 * If the register does not hold the state change enable
1582 	 * bit, (either as a 0 or a 1), assume it doesn't really
1583 	 * exist
1584 	 */
1585 	if ((tv_dac_on & TVDAC_STATE_CHG_EN) == 0 ||
1586 	    (tv_dac_off & TVDAC_STATE_CHG_EN) != 0)
1587 		return;
1588 
1589 	intel_tv = kzalloc(sizeof(struct intel_tv), GFP_KERNEL);
1590 	if (!intel_tv) {
1591 		return;
1592 	}
1593 
1594 	intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL);
1595 	if (!intel_connector) {
1596 		kfree(intel_tv);
1597 		return;
1598 	}
1599 
1600 	intel_encoder = &intel_tv->base;
1601 	connector = &intel_connector->base;
1602 
1603 	/* The documentation, for the older chipsets at least, recommend
1604 	 * using a polling method rather than hotplug detection for TVs.
1605 	 * This is because in order to perform the hotplug detection, the PLLs
1606 	 * for the TV must be kept alive increasing power drain and starving
1607 	 * bandwidth from other encoders. Notably for instance, it causes
1608 	 * pipe underruns on Crestline when this encoder is supposedly idle.
1609 	 *
1610 	 * More recent chipsets favour HDMI rather than integrated S-Video.
1611 	 */
1612 	intel_connector->polled = DRM_CONNECTOR_POLL_CONNECT;
1613 
1614 	drm_connector_init(dev, connector, &intel_tv_connector_funcs,
1615 			   DRM_MODE_CONNECTOR_SVIDEO);
1616 
1617 	drm_encoder_init(dev, &intel_encoder->base, &intel_tv_enc_funcs,
1618 			 DRM_MODE_ENCODER_TVDAC);
1619 
1620 	intel_encoder->compute_config = intel_tv_compute_config;
1621 	intel_encoder->enable = intel_enable_tv;
1622 	intel_encoder->disable = intel_disable_tv;
1623 	intel_encoder->get_hw_state = intel_tv_get_hw_state;
1624 	intel_connector->get_hw_state = intel_connector_get_hw_state;
1625 
1626 	intel_connector_attach_encoder(intel_connector, intel_encoder);
1627 	intel_encoder->type = INTEL_OUTPUT_TVOUT;
1628 	intel_encoder->crtc_mask = (1 << 0) | (1 << 1);
1629 	intel_encoder->cloneable = false;
1630 	intel_encoder->base.possible_crtcs = ((1 << 0) | (1 << 1));
1631 	intel_encoder->base.possible_clones = (1 << INTEL_OUTPUT_TVOUT);
1632 	intel_tv->type = DRM_MODE_CONNECTOR_Unknown;
1633 
1634 	/* BIOS margin values */
1635 	intel_tv->margin[TV_MARGIN_LEFT] = 54;
1636 	intel_tv->margin[TV_MARGIN_TOP] = 36;
1637 	intel_tv->margin[TV_MARGIN_RIGHT] = 46;
1638 	intel_tv->margin[TV_MARGIN_BOTTOM] = 37;
1639 
1640 	intel_tv->tv_format = tv_modes[initial_mode].name;
1641 
1642 	drm_encoder_helper_add(&intel_encoder->base, &intel_tv_helper_funcs);
1643 	drm_connector_helper_add(connector, &intel_tv_connector_helper_funcs);
1644 	connector->interlace_allowed = false;
1645 	connector->doublescan_allowed = false;
1646 
1647 	/* Create TV properties then attach current values */
1648 	for (i = 0; i < ARRAY_SIZE(tv_modes); i++)
1649 		tv_format_names[i] = __DECONST(char *, tv_modes[i].name);
1650 	drm_mode_create_tv_properties(dev,
1651 				      ARRAY_SIZE(tv_modes),
1652 				      tv_format_names);
1653 
1654 	drm_object_attach_property(&connector->base, dev->mode_config.tv_mode_property,
1655 				   initial_mode);
1656 	drm_object_attach_property(&connector->base,
1657 				   dev->mode_config.tv_left_margin_property,
1658 				   intel_tv->margin[TV_MARGIN_LEFT]);
1659 	drm_object_attach_property(&connector->base,
1660 				   dev->mode_config.tv_top_margin_property,
1661 				   intel_tv->margin[TV_MARGIN_TOP]);
1662 	drm_object_attach_property(&connector->base,
1663 				   dev->mode_config.tv_right_margin_property,
1664 				   intel_tv->margin[TV_MARGIN_RIGHT]);
1665 	drm_object_attach_property(&connector->base,
1666 				   dev->mode_config.tv_bottom_margin_property,
1667 				   intel_tv->margin[TV_MARGIN_BOTTOM]);
1668 	drm_sysfs_connector_add(connector);
1669 }
1670