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