xref: /dragonfly/sys/dev/drm/i915/intel_tv.c (revision b0d289c2)
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_tv(struct intel_encoder *encoder)
827 {
828 	return container_of(encoder, struct intel_tv, base);
829 }
830 
831 static struct intel_tv *intel_attached_tv(struct drm_connector *connector)
832 {
833 	return enc_to_tv(intel_attached_encoder(connector));
834 }
835 
836 static bool
837 intel_tv_get_hw_state(struct intel_encoder *encoder, enum i915_pipe *pipe)
838 {
839 	struct drm_device *dev = encoder->base.dev;
840 	struct drm_i915_private *dev_priv = dev->dev_private;
841 	u32 tmp = I915_READ(TV_CTL);
842 
843 	if (!(tmp & TV_ENC_ENABLE))
844 		return false;
845 
846 	*pipe = PORT_TO_PIPE(tmp);
847 
848 	return true;
849 }
850 
851 static void
852 intel_enable_tv(struct intel_encoder *encoder)
853 {
854 	struct drm_device *dev = encoder->base.dev;
855 	struct drm_i915_private *dev_priv = dev->dev_private;
856 
857 	I915_WRITE(TV_CTL, I915_READ(TV_CTL) | TV_ENC_ENABLE);
858 }
859 
860 static void
861 intel_disable_tv(struct intel_encoder *encoder)
862 {
863 	struct drm_device *dev = encoder->base.dev;
864 	struct drm_i915_private *dev_priv = dev->dev_private;
865 
866 	I915_WRITE(TV_CTL, I915_READ(TV_CTL) & ~TV_ENC_ENABLE);
867 }
868 
869 static const struct tv_mode *
870 intel_tv_mode_lookup(const char *tv_format)
871 {
872 	int i;
873 
874 	for (i = 0; i < ARRAY_SIZE(tv_modes); i++) {
875 		const struct tv_mode *tv_mode = &tv_modes[i];
876 
877 		if (!strcmp(tv_format, tv_mode->name))
878 			return tv_mode;
879 	}
880 	return NULL;
881 }
882 
883 static const struct tv_mode *
884 intel_tv_mode_find(struct intel_tv *intel_tv)
885 {
886 	return intel_tv_mode_lookup(intel_tv->tv_format);
887 }
888 
889 static enum drm_mode_status
890 intel_tv_mode_valid(struct drm_connector *connector,
891 		    struct drm_display_mode *mode)
892 {
893 	struct intel_tv *intel_tv = intel_attached_tv(connector);
894 	const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv);
895 
896 	/* Ensure TV refresh is close to desired refresh */
897 	if (tv_mode && abs(tv_mode->refresh - drm_mode_vrefresh(mode) * 1000)
898 				< 1000)
899 		return MODE_OK;
900 
901 	return MODE_CLOCK_RANGE;
902 }
903 
904 
905 static void
906 intel_tv_get_config(struct intel_encoder *encoder,
907 		    struct intel_crtc_config *pipe_config)
908 {
909 	pipe_config->adjusted_mode.crtc_clock = pipe_config->port_clock;
910 }
911 
912 static bool
913 intel_tv_compute_config(struct intel_encoder *encoder,
914 			struct intel_crtc_config *pipe_config)
915 {
916 	struct intel_tv *intel_tv = enc_to_tv(encoder);
917 	const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv);
918 
919 	if (!tv_mode)
920 		return false;
921 
922 	pipe_config->adjusted_mode.crtc_clock = tv_mode->clock;
923 	DRM_DEBUG_KMS("forcing bpc to 8 for TV\n");
924 	pipe_config->pipe_bpp = 8*3;
925 
926 	/* TV has it's own notion of sync and other mode flags, so clear them. */
927 	pipe_config->adjusted_mode.flags = 0;
928 
929 	/*
930 	 * FIXME: We don't check whether the input mode is actually what we want
931 	 * or whether userspace is doing something stupid.
932 	 */
933 
934 	return true;
935 }
936 
937 static void intel_tv_mode_set(struct intel_encoder *encoder)
938 {
939 	struct drm_device *dev = encoder->base.dev;
940 	struct drm_i915_private *dev_priv = dev->dev_private;
941 	struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc);
942 	struct intel_tv *intel_tv = enc_to_tv(encoder);
943 	const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv);
944 	u32 tv_ctl;
945 	u32 hctl1, hctl2, hctl3;
946 	u32 vctl1, vctl2, vctl3, vctl4, vctl5, vctl6, vctl7;
947 	u32 scctl1, scctl2, scctl3;
948 	int i, j;
949 	const struct video_levels *video_levels;
950 	const struct color_conversion *color_conversion;
951 	bool burst_ena;
952 	int pipe = intel_crtc->pipe;
953 
954 	if (!tv_mode)
955 		return;	/* can't happen (mode_prepare prevents this) */
956 
957 	tv_ctl = I915_READ(TV_CTL);
958 	tv_ctl &= TV_CTL_SAVE;
959 
960 	switch (intel_tv->type) {
961 	default:
962 	case DRM_MODE_CONNECTOR_Unknown:
963 	case DRM_MODE_CONNECTOR_Composite:
964 		tv_ctl |= TV_ENC_OUTPUT_COMPOSITE;
965 		video_levels = tv_mode->composite_levels;
966 		color_conversion = tv_mode->composite_color;
967 		burst_ena = tv_mode->burst_ena;
968 		break;
969 	case DRM_MODE_CONNECTOR_Component:
970 		tv_ctl |= TV_ENC_OUTPUT_COMPONENT;
971 		video_levels = &component_levels;
972 		if (tv_mode->burst_ena)
973 			color_conversion = &sdtv_csc_yprpb;
974 		else
975 			color_conversion = &hdtv_csc_yprpb;
976 		burst_ena = false;
977 		break;
978 	case DRM_MODE_CONNECTOR_SVIDEO:
979 		tv_ctl |= TV_ENC_OUTPUT_SVIDEO;
980 		video_levels = tv_mode->svideo_levels;
981 		color_conversion = tv_mode->svideo_color;
982 		burst_ena = tv_mode->burst_ena;
983 		break;
984 	}
985 	hctl1 = (tv_mode->hsync_end << TV_HSYNC_END_SHIFT) |
986 		(tv_mode->htotal << TV_HTOTAL_SHIFT);
987 
988 	hctl2 = (tv_mode->hburst_start << 16) |
989 		(tv_mode->hburst_len << TV_HBURST_LEN_SHIFT);
990 
991 	if (burst_ena)
992 		hctl2 |= TV_BURST_ENA;
993 
994 	hctl3 = (tv_mode->hblank_start << TV_HBLANK_START_SHIFT) |
995 		(tv_mode->hblank_end << TV_HBLANK_END_SHIFT);
996 
997 	vctl1 = (tv_mode->nbr_end << TV_NBR_END_SHIFT) |
998 		(tv_mode->vi_end_f1 << TV_VI_END_F1_SHIFT) |
999 		(tv_mode->vi_end_f2 << TV_VI_END_F2_SHIFT);
1000 
1001 	vctl2 = (tv_mode->vsync_len << TV_VSYNC_LEN_SHIFT) |
1002 		(tv_mode->vsync_start_f1 << TV_VSYNC_START_F1_SHIFT) |
1003 		(tv_mode->vsync_start_f2 << TV_VSYNC_START_F2_SHIFT);
1004 
1005 	vctl3 = (tv_mode->veq_len << TV_VEQ_LEN_SHIFT) |
1006 		(tv_mode->veq_start_f1 << TV_VEQ_START_F1_SHIFT) |
1007 		(tv_mode->veq_start_f2 << TV_VEQ_START_F2_SHIFT);
1008 
1009 	if (tv_mode->veq_ena)
1010 		vctl3 |= TV_EQUAL_ENA;
1011 
1012 	vctl4 = (tv_mode->vburst_start_f1 << TV_VBURST_START_F1_SHIFT) |
1013 		(tv_mode->vburst_end_f1 << TV_VBURST_END_F1_SHIFT);
1014 
1015 	vctl5 = (tv_mode->vburst_start_f2 << TV_VBURST_START_F2_SHIFT) |
1016 		(tv_mode->vburst_end_f2 << TV_VBURST_END_F2_SHIFT);
1017 
1018 	vctl6 = (tv_mode->vburst_start_f3 << TV_VBURST_START_F3_SHIFT) |
1019 		(tv_mode->vburst_end_f3 << TV_VBURST_END_F3_SHIFT);
1020 
1021 	vctl7 = (tv_mode->vburst_start_f4 << TV_VBURST_START_F4_SHIFT) |
1022 		(tv_mode->vburst_end_f4 << TV_VBURST_END_F4_SHIFT);
1023 
1024 	if (intel_crtc->pipe == 1)
1025 		tv_ctl |= TV_ENC_PIPEB_SELECT;
1026 	tv_ctl |= tv_mode->oversample;
1027 
1028 	if (tv_mode->progressive)
1029 		tv_ctl |= TV_PROGRESSIVE;
1030 	if (tv_mode->trilevel_sync)
1031 		tv_ctl |= TV_TRILEVEL_SYNC;
1032 	if (tv_mode->pal_burst)
1033 		tv_ctl |= TV_PAL_BURST;
1034 
1035 	scctl1 = 0;
1036 	if (tv_mode->dda1_inc)
1037 		scctl1 |= TV_SC_DDA1_EN;
1038 	if (tv_mode->dda2_inc)
1039 		scctl1 |= TV_SC_DDA2_EN;
1040 	if (tv_mode->dda3_inc)
1041 		scctl1 |= TV_SC_DDA3_EN;
1042 	scctl1 |= tv_mode->sc_reset;
1043 	if (video_levels)
1044 		scctl1 |= video_levels->burst << TV_BURST_LEVEL_SHIFT;
1045 	scctl1 |= tv_mode->dda1_inc << TV_SCDDA1_INC_SHIFT;
1046 
1047 	scctl2 = tv_mode->dda2_size << TV_SCDDA2_SIZE_SHIFT |
1048 		tv_mode->dda2_inc << TV_SCDDA2_INC_SHIFT;
1049 
1050 	scctl3 = tv_mode->dda3_size << TV_SCDDA3_SIZE_SHIFT |
1051 		tv_mode->dda3_inc << TV_SCDDA3_INC_SHIFT;
1052 
1053 	/* Enable two fixes for the chips that need them. */
1054 	if (dev->pdev->device < 0x2772)
1055 		tv_ctl |= TV_ENC_C0_FIX | TV_ENC_SDP_FIX;
1056 
1057 	I915_WRITE(TV_H_CTL_1, hctl1);
1058 	I915_WRITE(TV_H_CTL_2, hctl2);
1059 	I915_WRITE(TV_H_CTL_3, hctl3);
1060 	I915_WRITE(TV_V_CTL_1, vctl1);
1061 	I915_WRITE(TV_V_CTL_2, vctl2);
1062 	I915_WRITE(TV_V_CTL_3, vctl3);
1063 	I915_WRITE(TV_V_CTL_4, vctl4);
1064 	I915_WRITE(TV_V_CTL_5, vctl5);
1065 	I915_WRITE(TV_V_CTL_6, vctl6);
1066 	I915_WRITE(TV_V_CTL_7, vctl7);
1067 	I915_WRITE(TV_SC_CTL_1, scctl1);
1068 	I915_WRITE(TV_SC_CTL_2, scctl2);
1069 	I915_WRITE(TV_SC_CTL_3, scctl3);
1070 
1071 	if (color_conversion) {
1072 		I915_WRITE(TV_CSC_Y, (color_conversion->ry << 16) |
1073 			   color_conversion->gy);
1074 		I915_WRITE(TV_CSC_Y2, (color_conversion->by << 16) |
1075 			   color_conversion->ay);
1076 		I915_WRITE(TV_CSC_U, (color_conversion->ru << 16) |
1077 			   color_conversion->gu);
1078 		I915_WRITE(TV_CSC_U2, (color_conversion->bu << 16) |
1079 			   color_conversion->au);
1080 		I915_WRITE(TV_CSC_V, (color_conversion->rv << 16) |
1081 			   color_conversion->gv);
1082 		I915_WRITE(TV_CSC_V2, (color_conversion->bv << 16) |
1083 			   color_conversion->av);
1084 	}
1085 
1086 	if (INTEL_INFO(dev)->gen >= 4)
1087 		I915_WRITE(TV_CLR_KNOBS, 0x00404000);
1088 	else
1089 		I915_WRITE(TV_CLR_KNOBS, 0x00606000);
1090 
1091 	if (video_levels)
1092 		I915_WRITE(TV_CLR_LEVEL,
1093 			   ((video_levels->black << TV_BLACK_LEVEL_SHIFT) |
1094 			    (video_levels->blank << TV_BLANK_LEVEL_SHIFT)));
1095 	{
1096 		int pipeconf_reg = PIPECONF(pipe);
1097 		int dspcntr_reg = DSPCNTR(intel_crtc->plane);
1098 		int pipeconf = I915_READ(pipeconf_reg);
1099 		int dspcntr = I915_READ(dspcntr_reg);
1100 		int xpos = 0x0, ypos = 0x0;
1101 		unsigned int xsize, ysize;
1102 		/* Pipe must be off here */
1103 		I915_WRITE(dspcntr_reg, dspcntr & ~DISPLAY_PLANE_ENABLE);
1104 		intel_flush_primary_plane(dev_priv, intel_crtc->plane);
1105 
1106 		/* Wait for vblank for the disable to take effect */
1107 		if (IS_GEN2(dev))
1108 			intel_wait_for_vblank(dev, intel_crtc->pipe);
1109 
1110 		I915_WRITE(pipeconf_reg, pipeconf & ~PIPECONF_ENABLE);
1111 		/* Wait for vblank for the disable to take effect. */
1112 		intel_wait_for_pipe_off(dev, intel_crtc->pipe);
1113 
1114 		/* Filter ctl must be set before TV_WIN_SIZE */
1115 		I915_WRITE(TV_FILTER_CTL_1, TV_AUTO_SCALE);
1116 		xsize = tv_mode->hblank_start - tv_mode->hblank_end;
1117 		if (tv_mode->progressive)
1118 			ysize = tv_mode->nbr_end + 1;
1119 		else
1120 			ysize = 2*tv_mode->nbr_end + 1;
1121 
1122 		xpos += intel_tv->margin[TV_MARGIN_LEFT];
1123 		ypos += intel_tv->margin[TV_MARGIN_TOP];
1124 		xsize -= (intel_tv->margin[TV_MARGIN_LEFT] +
1125 			  intel_tv->margin[TV_MARGIN_RIGHT]);
1126 		ysize -= (intel_tv->margin[TV_MARGIN_TOP] +
1127 			  intel_tv->margin[TV_MARGIN_BOTTOM]);
1128 		I915_WRITE(TV_WIN_POS, (xpos<<16)|ypos);
1129 		I915_WRITE(TV_WIN_SIZE, (xsize<<16)|ysize);
1130 
1131 		I915_WRITE(pipeconf_reg, pipeconf);
1132 		I915_WRITE(dspcntr_reg, dspcntr);
1133 		intel_flush_primary_plane(dev_priv, intel_crtc->plane);
1134 	}
1135 
1136 	j = 0;
1137 	for (i = 0; i < 60; i++)
1138 		I915_WRITE(TV_H_LUMA_0 + (i<<2), tv_mode->filter_table[j++]);
1139 	for (i = 0; i < 60; i++)
1140 		I915_WRITE(TV_H_CHROMA_0 + (i<<2), tv_mode->filter_table[j++]);
1141 	for (i = 0; i < 43; i++)
1142 		I915_WRITE(TV_V_LUMA_0 + (i<<2), tv_mode->filter_table[j++]);
1143 	for (i = 0; i < 43; i++)
1144 		I915_WRITE(TV_V_CHROMA_0 + (i<<2), tv_mode->filter_table[j++]);
1145 	I915_WRITE(TV_DAC, I915_READ(TV_DAC) & TV_DAC_SAVE);
1146 	I915_WRITE(TV_CTL, tv_ctl);
1147 }
1148 
1149 static const struct drm_display_mode reported_modes[] = {
1150 	{
1151 		.name = "NTSC 480i",
1152 		.clock = 107520,
1153 		.hdisplay = 1280,
1154 		.hsync_start = 1368,
1155 		.hsync_end = 1496,
1156 		.htotal = 1712,
1157 
1158 		.vdisplay = 1024,
1159 		.vsync_start = 1027,
1160 		.vsync_end = 1034,
1161 		.vtotal = 1104,
1162 		.type = DRM_MODE_TYPE_DRIVER,
1163 	},
1164 };
1165 
1166 /**
1167  * Detects TV presence by checking for load.
1168  *
1169  * Requires that the current pipe's DPLL is active.
1170 
1171  * \return true if TV is connected.
1172  * \return false if TV is disconnected.
1173  */
1174 static int
1175 intel_tv_detect_type(struct intel_tv *intel_tv,
1176 		      struct drm_connector *connector)
1177 {
1178 	struct drm_encoder *encoder = &intel_tv->base.base;
1179 	struct drm_crtc *crtc = encoder->crtc;
1180 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
1181 	struct drm_device *dev = encoder->dev;
1182 	struct drm_i915_private *dev_priv = dev->dev_private;
1183 	u32 tv_ctl, save_tv_ctl;
1184 	u32 tv_dac, save_tv_dac;
1185 	int type;
1186 
1187 	/* Disable TV interrupts around load detect or we'll recurse */
1188 	if (connector->polled & DRM_CONNECTOR_POLL_HPD) {
1189 		lockmgr(&dev_priv->irq_lock, LK_EXCLUSIVE);
1190 		i915_disable_pipestat(dev_priv, 0,
1191 				      PIPE_HOTPLUG_INTERRUPT_ENABLE |
1192 				      PIPE_HOTPLUG_TV_INTERRUPT_ENABLE);
1193 		lockmgr(&dev_priv->irq_lock, LK_RELEASE);
1194 	}
1195 
1196 	save_tv_dac = tv_dac = I915_READ(TV_DAC);
1197 	save_tv_ctl = tv_ctl = I915_READ(TV_CTL);
1198 
1199 	/* Poll for TV detection */
1200 	tv_ctl &= ~(TV_ENC_ENABLE | TV_TEST_MODE_MASK);
1201 	tv_ctl |= TV_TEST_MODE_MONITOR_DETECT;
1202 	if (intel_crtc->pipe == 1)
1203 		tv_ctl |= TV_ENC_PIPEB_SELECT;
1204 	else
1205 		tv_ctl &= ~TV_ENC_PIPEB_SELECT;
1206 
1207 	tv_dac &= ~(TVDAC_SENSE_MASK | DAC_A_MASK | DAC_B_MASK | DAC_C_MASK);
1208 	tv_dac |= (TVDAC_STATE_CHG_EN |
1209 		   TVDAC_A_SENSE_CTL |
1210 		   TVDAC_B_SENSE_CTL |
1211 		   TVDAC_C_SENSE_CTL |
1212 		   DAC_CTL_OVERRIDE |
1213 		   DAC_A_0_7_V |
1214 		   DAC_B_0_7_V |
1215 		   DAC_C_0_7_V);
1216 
1217 
1218 	/*
1219 	 * The TV sense state should be cleared to zero on cantiga platform. Otherwise
1220 	 * the TV is misdetected. This is hardware requirement.
1221 	 */
1222 	if (IS_GM45(dev))
1223 		tv_dac &= ~(TVDAC_STATE_CHG_EN | TVDAC_A_SENSE_CTL |
1224 			    TVDAC_B_SENSE_CTL | TVDAC_C_SENSE_CTL);
1225 
1226 	I915_WRITE(TV_CTL, tv_ctl);
1227 	I915_WRITE(TV_DAC, tv_dac);
1228 	POSTING_READ(TV_DAC);
1229 
1230 	intel_wait_for_vblank(intel_tv->base.base.dev,
1231 			      to_intel_crtc(intel_tv->base.base.crtc)->pipe);
1232 
1233 	type = -1;
1234 	tv_dac = I915_READ(TV_DAC);
1235 	DRM_DEBUG_KMS("TV detected: %x, %x\n", tv_ctl, tv_dac);
1236 	/*
1237 	 *  A B C
1238 	 *  0 1 1 Composite
1239 	 *  1 0 X svideo
1240 	 *  0 0 0 Component
1241 	 */
1242 	if ((tv_dac & TVDAC_SENSE_MASK) == (TVDAC_B_SENSE | TVDAC_C_SENSE)) {
1243 		DRM_DEBUG_KMS("Detected Composite TV connection\n");
1244 		type = DRM_MODE_CONNECTOR_Composite;
1245 	} else if ((tv_dac & (TVDAC_A_SENSE|TVDAC_B_SENSE)) == TVDAC_A_SENSE) {
1246 		DRM_DEBUG_KMS("Detected S-Video TV connection\n");
1247 		type = DRM_MODE_CONNECTOR_SVIDEO;
1248 	} else if ((tv_dac & TVDAC_SENSE_MASK) == 0) {
1249 		DRM_DEBUG_KMS("Detected Component TV connection\n");
1250 		type = DRM_MODE_CONNECTOR_Component;
1251 	} else {
1252 		DRM_DEBUG_KMS("Unrecognised TV connection\n");
1253 		type = -1;
1254 	}
1255 
1256 	I915_WRITE(TV_DAC, save_tv_dac & ~TVDAC_STATE_CHG_EN);
1257 	I915_WRITE(TV_CTL, save_tv_ctl);
1258 	POSTING_READ(TV_CTL);
1259 
1260 	/* For unknown reasons the hw barfs if we don't do this vblank wait. */
1261 	intel_wait_for_vblank(intel_tv->base.base.dev,
1262 			      to_intel_crtc(intel_tv->base.base.crtc)->pipe);
1263 
1264 	/* Restore interrupt config */
1265 	if (connector->polled & DRM_CONNECTOR_POLL_HPD) {
1266 		lockmgr(&dev_priv->irq_lock, LK_EXCLUSIVE);
1267 		i915_enable_pipestat(dev_priv, 0,
1268 				     PIPE_HOTPLUG_INTERRUPT_ENABLE |
1269 				     PIPE_HOTPLUG_TV_INTERRUPT_ENABLE);
1270 		lockmgr(&dev_priv->irq_lock, LK_RELEASE);
1271 	}
1272 
1273 	return type;
1274 }
1275 
1276 /*
1277  * Here we set accurate tv format according to connector type
1278  * i.e Component TV should not be assigned by NTSC or PAL
1279  */
1280 static void intel_tv_find_better_format(struct drm_connector *connector)
1281 {
1282 	struct intel_tv *intel_tv = intel_attached_tv(connector);
1283 	const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv);
1284 	int i;
1285 
1286 	if ((intel_tv->type == DRM_MODE_CONNECTOR_Component) ==
1287 		tv_mode->component_only)
1288 		return;
1289 
1290 
1291 	for (i = 0; i < sizeof(tv_modes) / sizeof(*tv_modes); i++) {
1292 		tv_mode = tv_modes + i;
1293 
1294 		if ((intel_tv->type == DRM_MODE_CONNECTOR_Component) ==
1295 			tv_mode->component_only)
1296 			break;
1297 	}
1298 
1299 	intel_tv->tv_format = tv_mode->name;
1300 	drm_object_property_set_value(&connector->base,
1301 		connector->dev->mode_config.tv_mode_property, i);
1302 }
1303 
1304 /**
1305  * Detect the TV connection.
1306  *
1307  * Currently this always returns CONNECTOR_STATUS_UNKNOWN, as we need to be sure
1308  * we have a pipe programmed in order to probe the TV.
1309  */
1310 static enum drm_connector_status
1311 intel_tv_detect(struct drm_connector *connector, bool force)
1312 {
1313 	struct drm_display_mode mode;
1314 	struct intel_tv *intel_tv = intel_attached_tv(connector);
1315 	int type;
1316 
1317 	DRM_DEBUG_KMS("[CONNECTOR:%d:%s] force=%d\n",
1318 		      connector->base.id, drm_get_connector_name(connector),
1319 		      force);
1320 
1321 	mode = reported_modes[0];
1322 
1323 	if (force) {
1324 		struct intel_load_detect_pipe tmp;
1325 
1326 		if (intel_get_load_detect_pipe(connector, &mode, &tmp)) {
1327 			type = intel_tv_detect_type(intel_tv, connector);
1328 			intel_release_load_detect_pipe(connector, &tmp);
1329 		} else
1330 			return connector_status_unknown;
1331 	} else
1332 		return connector->status;
1333 
1334 	if (type < 0)
1335 		return connector_status_disconnected;
1336 
1337 	intel_tv->type = type;
1338 	intel_tv_find_better_format(connector);
1339 
1340 	return connector_status_connected;
1341 }
1342 
1343 static const struct input_res {
1344 	const char *name;
1345 	int w, h;
1346 } input_res_table[] = {
1347 	{"640x480", 640, 480},
1348 	{"800x600", 800, 600},
1349 	{"1024x768", 1024, 768},
1350 	{"1280x1024", 1280, 1024},
1351 	{"848x480", 848, 480},
1352 	{"1280x720", 1280, 720},
1353 	{"1920x1080", 1920, 1080},
1354 };
1355 
1356 /*
1357  * Chose preferred mode  according to line number of TV format
1358  */
1359 static void
1360 intel_tv_chose_preferred_modes(struct drm_connector *connector,
1361 			       struct drm_display_mode *mode_ptr)
1362 {
1363 	struct intel_tv *intel_tv = intel_attached_tv(connector);
1364 	const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv);
1365 
1366 	if (tv_mode->nbr_end < 480 && mode_ptr->vdisplay == 480)
1367 		mode_ptr->type |= DRM_MODE_TYPE_PREFERRED;
1368 	else if (tv_mode->nbr_end > 480) {
1369 		if (tv_mode->progressive == true && tv_mode->nbr_end < 720) {
1370 			if (mode_ptr->vdisplay == 720)
1371 				mode_ptr->type |= DRM_MODE_TYPE_PREFERRED;
1372 		} else if (mode_ptr->vdisplay == 1080)
1373 				mode_ptr->type |= DRM_MODE_TYPE_PREFERRED;
1374 	}
1375 }
1376 
1377 /**
1378  * Stub get_modes function.
1379  *
1380  * This should probably return a set of fixed modes, unless we can figure out
1381  * how to probe modes off of TV connections.
1382  */
1383 
1384 static int
1385 intel_tv_get_modes(struct drm_connector *connector)
1386 {
1387 	struct drm_display_mode *mode_ptr;
1388 	struct intel_tv *intel_tv = intel_attached_tv(connector);
1389 	const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv);
1390 	int j, count = 0;
1391 	u64 tmp;
1392 
1393 	for (j = 0; j < ARRAY_SIZE(input_res_table);
1394 	     j++) {
1395 		const struct input_res *input = &input_res_table[j];
1396 		unsigned int hactive_s = input->w;
1397 		unsigned int vactive_s = input->h;
1398 
1399 		if (tv_mode->max_srcw && input->w > tv_mode->max_srcw)
1400 			continue;
1401 
1402 		if (input->w > 1024 && (!tv_mode->progressive
1403 					&& !tv_mode->component_only))
1404 			continue;
1405 
1406 		mode_ptr = drm_mode_create(connector->dev);
1407 		if (!mode_ptr)
1408 			continue;
1409 		strncpy(mode_ptr->name, input->name, DRM_DISPLAY_MODE_LEN);
1410 
1411 		mode_ptr->hdisplay = hactive_s;
1412 		mode_ptr->hsync_start = hactive_s + 1;
1413 		mode_ptr->hsync_end = hactive_s + 64;
1414 		if (mode_ptr->hsync_end <= mode_ptr->hsync_start)
1415 			mode_ptr->hsync_end = mode_ptr->hsync_start + 1;
1416 		mode_ptr->htotal = hactive_s + 96;
1417 
1418 		mode_ptr->vdisplay = vactive_s;
1419 		mode_ptr->vsync_start = vactive_s + 1;
1420 		mode_ptr->vsync_end = vactive_s + 32;
1421 		if (mode_ptr->vsync_end <= mode_ptr->vsync_start)
1422 			mode_ptr->vsync_end = mode_ptr->vsync_start  + 1;
1423 		mode_ptr->vtotal = vactive_s + 33;
1424 
1425 		tmp = (u64) tv_mode->refresh * mode_ptr->vtotal;
1426 		tmp *= mode_ptr->htotal;
1427 		tmp = div_u64(tmp, 1000000);
1428 		mode_ptr->clock = (int) tmp;
1429 
1430 		mode_ptr->type = DRM_MODE_TYPE_DRIVER;
1431 		intel_tv_chose_preferred_modes(connector, mode_ptr);
1432 		drm_mode_probed_add(connector, mode_ptr);
1433 		count++;
1434 	}
1435 
1436 	return count;
1437 }
1438 
1439 static void
1440 intel_tv_destroy(struct drm_connector *connector)
1441 {
1442 	drm_connector_cleanup(connector);
1443 	kfree(connector);
1444 }
1445 
1446 
1447 static int
1448 intel_tv_set_property(struct drm_connector *connector, struct drm_property *property,
1449 		      uint64_t val)
1450 {
1451 	struct drm_device *dev = connector->dev;
1452 	struct intel_tv *intel_tv = intel_attached_tv(connector);
1453 	struct drm_crtc *crtc = intel_tv->base.base.crtc;
1454 	int ret = 0;
1455 	bool changed = false;
1456 
1457 	ret = drm_object_property_set_value(&connector->base, property, val);
1458 	if (ret < 0)
1459 		goto out;
1460 
1461 	if (property == dev->mode_config.tv_left_margin_property &&
1462 		intel_tv->margin[TV_MARGIN_LEFT] != val) {
1463 		intel_tv->margin[TV_MARGIN_LEFT] = val;
1464 		changed = true;
1465 	} else if (property == dev->mode_config.tv_right_margin_property &&
1466 		intel_tv->margin[TV_MARGIN_RIGHT] != val) {
1467 		intel_tv->margin[TV_MARGIN_RIGHT] = val;
1468 		changed = true;
1469 	} else if (property == dev->mode_config.tv_top_margin_property &&
1470 		intel_tv->margin[TV_MARGIN_TOP] != val) {
1471 		intel_tv->margin[TV_MARGIN_TOP] = val;
1472 		changed = true;
1473 	} else if (property == dev->mode_config.tv_bottom_margin_property &&
1474 		intel_tv->margin[TV_MARGIN_BOTTOM] != val) {
1475 		intel_tv->margin[TV_MARGIN_BOTTOM] = val;
1476 		changed = true;
1477 	} else if (property == dev->mode_config.tv_mode_property) {
1478 		if (val >= ARRAY_SIZE(tv_modes)) {
1479 			ret = -EINVAL;
1480 			goto out;
1481 		}
1482 		if (!strcmp(intel_tv->tv_format, tv_modes[val].name))
1483 			goto out;
1484 
1485 		intel_tv->tv_format = tv_modes[val].name;
1486 		changed = true;
1487 	} else {
1488 		ret = -EINVAL;
1489 		goto out;
1490 	}
1491 
1492 	if (changed && crtc)
1493 		intel_crtc_restore_mode(crtc);
1494 out:
1495 	return ret;
1496 }
1497 
1498 static const struct drm_connector_funcs intel_tv_connector_funcs = {
1499 	.dpms = intel_connector_dpms,
1500 	.detect = intel_tv_detect,
1501 	.destroy = intel_tv_destroy,
1502 	.set_property = intel_tv_set_property,
1503 	.fill_modes = drm_helper_probe_single_connector_modes,
1504 };
1505 
1506 static const struct drm_connector_helper_funcs intel_tv_connector_helper_funcs = {
1507 	.mode_valid = intel_tv_mode_valid,
1508 	.get_modes = intel_tv_get_modes,
1509 	.best_encoder = intel_best_encoder,
1510 };
1511 
1512 static const struct drm_encoder_funcs intel_tv_enc_funcs = {
1513 	.destroy = intel_encoder_destroy,
1514 };
1515 
1516 /*
1517  * Enumerate the child dev array parsed from VBT to check whether
1518  * the integrated TV is present.
1519  * If it is present, return 1.
1520  * If it is not present, return false.
1521  * If no child dev is parsed from VBT, it assumes that the TV is present.
1522  */
1523 static int tv_is_present_in_vbt(struct drm_device *dev)
1524 {
1525 	struct drm_i915_private *dev_priv = dev->dev_private;
1526 	union child_device_config *p_child;
1527 	int i, ret;
1528 
1529 	if (!dev_priv->vbt.child_dev_num)
1530 		return 1;
1531 
1532 	ret = 0;
1533 	for (i = 0; i < dev_priv->vbt.child_dev_num; i++) {
1534 		p_child = dev_priv->vbt.child_dev + i;
1535 		/*
1536 		 * If the device type is not TV, continue.
1537 		 */
1538 		if (p_child->old.device_type != DEVICE_TYPE_INT_TV &&
1539 			p_child->old.device_type != DEVICE_TYPE_TV)
1540 			continue;
1541 		/* Only when the addin_offset is non-zero, it is regarded
1542 		 * as present.
1543 		 */
1544 		if (p_child->old.addin_offset) {
1545 			ret = 1;
1546 			break;
1547 		}
1548 	}
1549 	return ret;
1550 }
1551 
1552 void
1553 intel_tv_init(struct drm_device *dev)
1554 {
1555 	struct drm_i915_private *dev_priv = dev->dev_private;
1556 	struct drm_connector *connector;
1557 	struct intel_tv *intel_tv;
1558 	struct intel_encoder *intel_encoder;
1559 	struct intel_connector *intel_connector;
1560 	u32 tv_dac_on, tv_dac_off, save_tv_dac;
1561 	char *tv_format_names[ARRAY_SIZE(tv_modes)];
1562 	int i, initial_mode = 0;
1563 
1564 	if ((I915_READ(TV_CTL) & TV_FUSE_STATE_MASK) == TV_FUSE_STATE_DISABLED)
1565 		return;
1566 
1567 	if (!tv_is_present_in_vbt(dev)) {
1568 		DRM_DEBUG_KMS("Integrated TV is not present.\n");
1569 		return;
1570 	}
1571 	/* Even if we have an encoder we may not have a connector */
1572 	if (!dev_priv->vbt.int_tv_support)
1573 		return;
1574 
1575 	/*
1576 	 * Sanity check the TV output by checking to see if the
1577 	 * DAC register holds a value
1578 	 */
1579 	save_tv_dac = I915_READ(TV_DAC);
1580 
1581 	I915_WRITE(TV_DAC, save_tv_dac | TVDAC_STATE_CHG_EN);
1582 	tv_dac_on = I915_READ(TV_DAC);
1583 
1584 	I915_WRITE(TV_DAC, save_tv_dac & ~TVDAC_STATE_CHG_EN);
1585 	tv_dac_off = I915_READ(TV_DAC);
1586 
1587 	I915_WRITE(TV_DAC, save_tv_dac);
1588 
1589 	/*
1590 	 * If the register does not hold the state change enable
1591 	 * bit, (either as a 0 or a 1), assume it doesn't really
1592 	 * exist
1593 	 */
1594 	if ((tv_dac_on & TVDAC_STATE_CHG_EN) == 0 ||
1595 	    (tv_dac_off & TVDAC_STATE_CHG_EN) != 0)
1596 		return;
1597 
1598 	intel_tv = kzalloc(sizeof(*intel_tv), GFP_KERNEL);
1599 	if (!intel_tv) {
1600 		return;
1601 	}
1602 
1603 	intel_connector = kzalloc(sizeof(*intel_connector), GFP_KERNEL);
1604 	if (!intel_connector) {
1605 		kfree(intel_tv);
1606 		return;
1607 	}
1608 
1609 	intel_encoder = &intel_tv->base;
1610 	connector = &intel_connector->base;
1611 
1612 	/* The documentation, for the older chipsets at least, recommend
1613 	 * using a polling method rather than hotplug detection for TVs.
1614 	 * This is because in order to perform the hotplug detection, the PLLs
1615 	 * for the TV must be kept alive increasing power drain and starving
1616 	 * bandwidth from other encoders. Notably for instance, it causes
1617 	 * pipe underruns on Crestline when this encoder is supposedly idle.
1618 	 *
1619 	 * More recent chipsets favour HDMI rather than integrated S-Video.
1620 	 */
1621 	intel_connector->polled = DRM_CONNECTOR_POLL_CONNECT;
1622 
1623 	drm_connector_init(dev, connector, &intel_tv_connector_funcs,
1624 			   DRM_MODE_CONNECTOR_SVIDEO);
1625 
1626 	drm_encoder_init(dev, &intel_encoder->base, &intel_tv_enc_funcs,
1627 			 DRM_MODE_ENCODER_TVDAC);
1628 
1629 	intel_encoder->compute_config = intel_tv_compute_config;
1630 	intel_encoder->get_config = intel_tv_get_config;
1631 	intel_encoder->mode_set = intel_tv_mode_set;
1632 	intel_encoder->enable = intel_enable_tv;
1633 	intel_encoder->disable = intel_disable_tv;
1634 	intel_encoder->get_hw_state = intel_tv_get_hw_state;
1635 	intel_connector->get_hw_state = intel_connector_get_hw_state;
1636 
1637 	intel_connector_attach_encoder(intel_connector, intel_encoder);
1638 	intel_encoder->type = INTEL_OUTPUT_TVOUT;
1639 	intel_encoder->crtc_mask = (1 << 0) | (1 << 1);
1640 	intel_encoder->cloneable = false;
1641 	intel_encoder->base.possible_crtcs = ((1 << 0) | (1 << 1));
1642 	intel_encoder->base.possible_clones = (1 << INTEL_OUTPUT_TVOUT);
1643 	intel_tv->type = DRM_MODE_CONNECTOR_Unknown;
1644 
1645 	/* BIOS margin values */
1646 	intel_tv->margin[TV_MARGIN_LEFT] = 54;
1647 	intel_tv->margin[TV_MARGIN_TOP] = 36;
1648 	intel_tv->margin[TV_MARGIN_RIGHT] = 46;
1649 	intel_tv->margin[TV_MARGIN_BOTTOM] = 37;
1650 
1651 	intel_tv->tv_format = tv_modes[initial_mode].name;
1652 
1653 	drm_connector_helper_add(connector, &intel_tv_connector_helper_funcs);
1654 	connector->interlace_allowed = false;
1655 	connector->doublescan_allowed = false;
1656 
1657 	/* Create TV properties then attach current values */
1658 	for (i = 0; i < ARRAY_SIZE(tv_modes); i++)
1659 		tv_format_names[i] = __DECONST(char *, tv_modes[i].name);
1660 	drm_mode_create_tv_properties(dev,
1661 				      ARRAY_SIZE(tv_modes),
1662 				      tv_format_names);
1663 
1664 	drm_object_attach_property(&connector->base, dev->mode_config.tv_mode_property,
1665 				   initial_mode);
1666 	drm_object_attach_property(&connector->base,
1667 				   dev->mode_config.tv_left_margin_property,
1668 				   intel_tv->margin[TV_MARGIN_LEFT]);
1669 	drm_object_attach_property(&connector->base,
1670 				   dev->mode_config.tv_top_margin_property,
1671 				   intel_tv->margin[TV_MARGIN_TOP]);
1672 	drm_object_attach_property(&connector->base,
1673 				   dev->mode_config.tv_right_margin_property,
1674 				   intel_tv->margin[TV_MARGIN_RIGHT]);
1675 	drm_object_attach_property(&connector->base,
1676 				   dev->mode_config.tv_bottom_margin_property,
1677 				   intel_tv->margin[TV_MARGIN_BOTTOM]);
1678 	drm_sysfs_connector_add(connector);
1679 }
1680