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