xref: /dragonfly/sys/dev/drm/i915/intel_tv.c (revision 59b0b316)
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 hdtv_csc_yprpb = {
330 	.ry = 0x05b3, .gy = 0x016e, .by = 0x0728, .ay = 0x0145,
331 	.ru = 0x07d5, .gu = 0x038b, .bu = 0x0100, .au = 0x0200,
332 	.rv = 0x0100, .gv = 0x03d1, .bv = 0x06bc, .av = 0x0200,
333 };
334 
335 static const struct video_levels component_levels = {
336 	.blank = 279, .black = 279, .burst = 0,
337 };
338 
339 
340 struct tv_mode {
341 	const char *name;
342 	int clock;
343 	int refresh; /* in millihertz (for precision) */
344 	u32 oversample;
345 	int hsync_end, hblank_start, hblank_end, htotal;
346 	bool progressive, trilevel_sync, component_only;
347 	int vsync_start_f1, vsync_start_f2, vsync_len;
348 	bool veq_ena;
349 	int veq_start_f1, veq_start_f2, veq_len;
350 	int vi_end_f1, vi_end_f2, nbr_end;
351 	bool burst_ena;
352 	int hburst_start, hburst_len;
353 	int vburst_start_f1, vburst_end_f1;
354 	int vburst_start_f2, vburst_end_f2;
355 	int vburst_start_f3, vburst_end_f3;
356 	int vburst_start_f4, vburst_end_f4;
357 	/*
358 	 * subcarrier programming
359 	 */
360 	int dda2_size, dda3_size, dda1_inc, dda2_inc, dda3_inc;
361 	u32 sc_reset;
362 	bool pal_burst;
363 	/*
364 	 * blank/black levels
365 	 */
366 	const struct video_levels *composite_levels, *svideo_levels;
367 	const struct color_conversion *composite_color, *svideo_color;
368 	const u32 *filter_table;
369 	int max_srcw;
370 };
371 
372 
373 /*
374  * Sub carrier DDA
375  *
376  *  I think this works as follows:
377  *
378  *  subcarrier freq = pixel_clock * (dda1_inc + dda2_inc / dda2_size) / 4096
379  *
380  * Presumably, when dda3 is added in, it gets to adjust the dda2_inc value
381  *
382  * So,
383  *  dda1_ideal = subcarrier/pixel * 4096
384  *  dda1_inc = floor (dda1_ideal)
385  *  dda2 = dda1_ideal - dda1_inc
386  *
387  *  then pick a ratio for dda2 that gives the closest approximation. If
388  *  you can't get close enough, you can play with dda3 as well. This
389  *  seems likely to happen when dda2 is small as the jumps would be larger
390  *
391  * To invert this,
392  *
393  *  pixel_clock = subcarrier * 4096 / (dda1_inc + dda2_inc / dda2_size)
394  *
395  * The constants below were all computed using a 107.520MHz clock
396  */
397 
398 /**
399  * Register programming values for TV modes.
400  *
401  * These values account for -1s required.
402  */
403 
404 static const struct tv_mode tv_modes[] = {
405 	{
406 		.name		= "NTSC-M",
407 		.clock		= 108000,
408 		.refresh	= 59940,
409 		.oversample	= TV_OVERSAMPLE_8X,
410 		.component_only = 0,
411 		/* 525 Lines, 60 Fields, 15.734KHz line, Sub-Carrier 3.580MHz */
412 
413 		.hsync_end	= 64,		    .hblank_end		= 124,
414 		.hblank_start	= 836,		    .htotal		= 857,
415 
416 		.progressive	= false,	    .trilevel_sync = false,
417 
418 		.vsync_start_f1	= 6,		    .vsync_start_f2	= 7,
419 		.vsync_len	= 6,
420 
421 		.veq_ena	= true,		    .veq_start_f1	= 0,
422 		.veq_start_f2	= 1,		    .veq_len		= 18,
423 
424 		.vi_end_f1	= 20,		    .vi_end_f2		= 21,
425 		.nbr_end	= 240,
426 
427 		.burst_ena	= true,
428 		.hburst_start	= 72,		    .hburst_len		= 34,
429 		.vburst_start_f1 = 9,		    .vburst_end_f1	= 240,
430 		.vburst_start_f2 = 10,		    .vburst_end_f2	= 240,
431 		.vburst_start_f3 = 9,		    .vburst_end_f3	= 240,
432 		.vburst_start_f4 = 10,		    .vburst_end_f4	= 240,
433 
434 		/* desired 3.5800000 actual 3.5800000 clock 107.52 */
435 		.dda1_inc	=    135,
436 		.dda2_inc	=  20800,	    .dda2_size		=  27456,
437 		.dda3_inc	=      0,	    .dda3_size		=      0,
438 		.sc_reset	= TV_SC_RESET_EVERY_4,
439 		.pal_burst	= false,
440 
441 		.composite_levels = &ntsc_m_levels_composite,
442 		.composite_color = &ntsc_m_csc_composite,
443 		.svideo_levels  = &ntsc_m_levels_svideo,
444 		.svideo_color = &ntsc_m_csc_svideo,
445 
446 		.filter_table = filter_table,
447 	},
448 	{
449 		.name		= "NTSC-443",
450 		.clock		= 108000,
451 		.refresh	= 59940,
452 		.oversample	= TV_OVERSAMPLE_8X,
453 		.component_only = 0,
454 		/* 525 Lines, 60 Fields, 15.734KHz line, Sub-Carrier 4.43MHz */
455 		.hsync_end	= 64,		    .hblank_end		= 124,
456 		.hblank_start	= 836,		    .htotal		= 857,
457 
458 		.progressive	= false,	    .trilevel_sync = false,
459 
460 		.vsync_start_f1 = 6,		    .vsync_start_f2	= 7,
461 		.vsync_len	= 6,
462 
463 		.veq_ena	= true,		    .veq_start_f1	= 0,
464 		.veq_start_f2	= 1,		    .veq_len		= 18,
465 
466 		.vi_end_f1	= 20,		    .vi_end_f2		= 21,
467 		.nbr_end	= 240,
468 
469 		.burst_ena	= true,
470 		.hburst_start	= 72,		    .hburst_len		= 34,
471 		.vburst_start_f1 = 9,		    .vburst_end_f1	= 240,
472 		.vburst_start_f2 = 10,		    .vburst_end_f2	= 240,
473 		.vburst_start_f3 = 9,		    .vburst_end_f3	= 240,
474 		.vburst_start_f4 = 10,		    .vburst_end_f4	= 240,
475 
476 		/* desired 4.4336180 actual 4.4336180 clock 107.52 */
477 		.dda1_inc       =    168,
478 		.dda2_inc       =   4093,       .dda2_size      =  27456,
479 		.dda3_inc       =    310,       .dda3_size      =    525,
480 		.sc_reset   = TV_SC_RESET_NEVER,
481 		.pal_burst  = false,
482 
483 		.composite_levels = &ntsc_m_levels_composite,
484 		.composite_color = &ntsc_m_csc_composite,
485 		.svideo_levels  = &ntsc_m_levels_svideo,
486 		.svideo_color = &ntsc_m_csc_svideo,
487 
488 		.filter_table = filter_table,
489 	},
490 	{
491 		.name		= "NTSC-J",
492 		.clock		= 108000,
493 		.refresh	= 59940,
494 		.oversample	= TV_OVERSAMPLE_8X,
495 		.component_only = 0,
496 
497 		/* 525 Lines, 60 Fields, 15.734KHz line, Sub-Carrier 3.580MHz */
498 		.hsync_end	= 64,		    .hblank_end		= 124,
499 		.hblank_start = 836,	    .htotal		= 857,
500 
501 		.progressive	= false,    .trilevel_sync = false,
502 
503 		.vsync_start_f1	= 6,	    .vsync_start_f2	= 7,
504 		.vsync_len	= 6,
505 
506 		.veq_ena      = true,	    .veq_start_f1	= 0,
507 		.veq_start_f2 = 1,	    .veq_len		= 18,
508 
509 		.vi_end_f1	= 20,		    .vi_end_f2		= 21,
510 		.nbr_end	= 240,
511 
512 		.burst_ena	= true,
513 		.hburst_start	= 72,		    .hburst_len		= 34,
514 		.vburst_start_f1 = 9,		    .vburst_end_f1	= 240,
515 		.vburst_start_f2 = 10,		    .vburst_end_f2	= 240,
516 		.vburst_start_f3 = 9,		    .vburst_end_f3	= 240,
517 		.vburst_start_f4 = 10,		    .vburst_end_f4	= 240,
518 
519 		/* desired 3.5800000 actual 3.5800000 clock 107.52 */
520 		.dda1_inc	=    135,
521 		.dda2_inc	=  20800,	    .dda2_size		=  27456,
522 		.dda3_inc	=      0,	    .dda3_size		=      0,
523 		.sc_reset	= TV_SC_RESET_EVERY_4,
524 		.pal_burst	= false,
525 
526 		.composite_levels = &ntsc_j_levels_composite,
527 		.composite_color = &ntsc_j_csc_composite,
528 		.svideo_levels  = &ntsc_j_levels_svideo,
529 		.svideo_color = &ntsc_j_csc_svideo,
530 
531 		.filter_table = filter_table,
532 	},
533 	{
534 		.name		= "PAL-M",
535 		.clock		= 108000,
536 		.refresh	= 59940,
537 		.oversample	= TV_OVERSAMPLE_8X,
538 		.component_only = 0,
539 
540 		/* 525 Lines, 60 Fields, 15.734KHz line, Sub-Carrier 3.580MHz */
541 		.hsync_end	= 64,		  .hblank_end		= 124,
542 		.hblank_start = 836,	  .htotal		= 857,
543 
544 		.progressive	= false,	    .trilevel_sync = false,
545 
546 		.vsync_start_f1	= 6,		    .vsync_start_f2	= 7,
547 		.vsync_len	= 6,
548 
549 		.veq_ena	= true,		    .veq_start_f1	= 0,
550 		.veq_start_f2	= 1,		    .veq_len		= 18,
551 
552 		.vi_end_f1	= 20,		    .vi_end_f2		= 21,
553 		.nbr_end	= 240,
554 
555 		.burst_ena	= true,
556 		.hburst_start	= 72,		    .hburst_len		= 34,
557 		.vburst_start_f1 = 9,		    .vburst_end_f1	= 240,
558 		.vburst_start_f2 = 10,		    .vburst_end_f2	= 240,
559 		.vburst_start_f3 = 9,		    .vburst_end_f3	= 240,
560 		.vburst_start_f4 = 10,		    .vburst_end_f4	= 240,
561 
562 		/* desired 3.5800000 actual 3.5800000 clock 107.52 */
563 		.dda1_inc	=    135,
564 		.dda2_inc	=  16704,	    .dda2_size		=  27456,
565 		.dda3_inc	=      0,	    .dda3_size		=      0,
566 		.sc_reset	= TV_SC_RESET_EVERY_8,
567 		.pal_burst  = true,
568 
569 		.composite_levels = &pal_m_levels_composite,
570 		.composite_color = &pal_m_csc_composite,
571 		.svideo_levels  = &pal_m_levels_svideo,
572 		.svideo_color = &pal_m_csc_svideo,
573 
574 		.filter_table = filter_table,
575 	},
576 	{
577 		/* 625 Lines, 50 Fields, 15.625KHz line, Sub-Carrier 4.434MHz */
578 		.name	    = "PAL-N",
579 		.clock		= 108000,
580 		.refresh	= 50000,
581 		.oversample	= TV_OVERSAMPLE_8X,
582 		.component_only = 0,
583 
584 		.hsync_end	= 64,		    .hblank_end		= 128,
585 		.hblank_start = 844,	    .htotal		= 863,
586 
587 		.progressive  = false,    .trilevel_sync = false,
588 
589 
590 		.vsync_start_f1	= 6,	   .vsync_start_f2	= 7,
591 		.vsync_len	= 6,
592 
593 		.veq_ena	= true,		    .veq_start_f1	= 0,
594 		.veq_start_f2	= 1,		    .veq_len		= 18,
595 
596 		.vi_end_f1	= 24,		    .vi_end_f2		= 25,
597 		.nbr_end	= 286,
598 
599 		.burst_ena	= true,
600 		.hburst_start = 73,	    .hburst_len		= 34,
601 		.vburst_start_f1 = 8,	    .vburst_end_f1	= 285,
602 		.vburst_start_f2 = 8,	    .vburst_end_f2	= 286,
603 		.vburst_start_f3 = 9,	    .vburst_end_f3	= 286,
604 		.vburst_start_f4 = 9,	    .vburst_end_f4	= 285,
605 
606 
607 		/* desired 4.4336180 actual 4.4336180 clock 107.52 */
608 		.dda1_inc       =    135,
609 		.dda2_inc       =  23578,       .dda2_size      =  27648,
610 		.dda3_inc       =    134,       .dda3_size      =    625,
611 		.sc_reset   = TV_SC_RESET_EVERY_8,
612 		.pal_burst  = true,
613 
614 		.composite_levels = &pal_n_levels_composite,
615 		.composite_color = &pal_n_csc_composite,
616 		.svideo_levels  = &pal_n_levels_svideo,
617 		.svideo_color = &pal_n_csc_svideo,
618 
619 		.filter_table = filter_table,
620 	},
621 	{
622 		/* 625 Lines, 50 Fields, 15.625KHz line, Sub-Carrier 4.434MHz */
623 		.name	    = "PAL",
624 		.clock		= 108000,
625 		.refresh	= 50000,
626 		.oversample	= TV_OVERSAMPLE_8X,
627 		.component_only = 0,
628 
629 		.hsync_end	= 64,		    .hblank_end		= 142,
630 		.hblank_start	= 844,	    .htotal		= 863,
631 
632 		.progressive	= false,    .trilevel_sync = false,
633 
634 		.vsync_start_f1	= 5,	    .vsync_start_f2	= 6,
635 		.vsync_len	= 5,
636 
637 		.veq_ena	= true,	    .veq_start_f1	= 0,
638 		.veq_start_f2	= 1,	    .veq_len		= 15,
639 
640 		.vi_end_f1	= 24,		    .vi_end_f2		= 25,
641 		.nbr_end	= 286,
642 
643 		.burst_ena	= true,
644 		.hburst_start	= 73,		    .hburst_len		= 32,
645 		.vburst_start_f1 = 8,		    .vburst_end_f1	= 285,
646 		.vburst_start_f2 = 8,		    .vburst_end_f2	= 286,
647 		.vburst_start_f3 = 9,		    .vburst_end_f3	= 286,
648 		.vburst_start_f4 = 9,		    .vburst_end_f4	= 285,
649 
650 		/* desired 4.4336180 actual 4.4336180 clock 107.52 */
651 		.dda1_inc       =    168,
652 		.dda2_inc       =   4122,       .dda2_size      =  27648,
653 		.dda3_inc       =     67,       .dda3_size      =    625,
654 		.sc_reset   = TV_SC_RESET_EVERY_8,
655 		.pal_burst  = true,
656 
657 		.composite_levels = &pal_levels_composite,
658 		.composite_color = &pal_csc_composite,
659 		.svideo_levels  = &pal_levels_svideo,
660 		.svideo_color = &pal_csc_svideo,
661 
662 		.filter_table = filter_table,
663 	},
664 	{
665 		.name       = "480p",
666 		.clock		= 107520,
667 		.refresh	= 59940,
668 		.oversample     = TV_OVERSAMPLE_4X,
669 		.component_only = 1,
670 
671 		.hsync_end      = 64,               .hblank_end         = 122,
672 		.hblank_start   = 842,              .htotal             = 857,
673 
674 		.progressive    = true,		    .trilevel_sync = false,
675 
676 		.vsync_start_f1 = 12,               .vsync_start_f2     = 12,
677 		.vsync_len      = 12,
678 
679 		.veq_ena        = false,
680 
681 		.vi_end_f1      = 44,               .vi_end_f2          = 44,
682 		.nbr_end        = 479,
683 
684 		.burst_ena      = false,
685 
686 		.filter_table = filter_table,
687 	},
688 	{
689 		.name       = "576p",
690 		.clock		= 107520,
691 		.refresh	= 50000,
692 		.oversample     = TV_OVERSAMPLE_4X,
693 		.component_only = 1,
694 
695 		.hsync_end      = 64,               .hblank_end         = 139,
696 		.hblank_start   = 859,              .htotal             = 863,
697 
698 		.progressive    = true,		    .trilevel_sync = false,
699 
700 		.vsync_start_f1 = 10,               .vsync_start_f2     = 10,
701 		.vsync_len      = 10,
702 
703 		.veq_ena        = false,
704 
705 		.vi_end_f1      = 48,               .vi_end_f2          = 48,
706 		.nbr_end        = 575,
707 
708 		.burst_ena      = false,
709 
710 		.filter_table = filter_table,
711 	},
712 	{
713 		.name       = "720p@60Hz",
714 		.clock		= 148800,
715 		.refresh	= 60000,
716 		.oversample     = TV_OVERSAMPLE_2X,
717 		.component_only = 1,
718 
719 		.hsync_end      = 80,               .hblank_end         = 300,
720 		.hblank_start   = 1580,             .htotal             = 1649,
721 
722 		.progressive	= true,		    .trilevel_sync = true,
723 
724 		.vsync_start_f1 = 10,               .vsync_start_f2     = 10,
725 		.vsync_len      = 10,
726 
727 		.veq_ena        = false,
728 
729 		.vi_end_f1      = 29,               .vi_end_f2          = 29,
730 		.nbr_end        = 719,
731 
732 		.burst_ena      = false,
733 
734 		.filter_table = filter_table,
735 	},
736 	{
737 		.name       = "720p@50Hz",
738 		.clock		= 148800,
739 		.refresh	= 50000,
740 		.oversample     = TV_OVERSAMPLE_2X,
741 		.component_only = 1,
742 
743 		.hsync_end      = 80,               .hblank_end         = 300,
744 		.hblank_start   = 1580,             .htotal             = 1979,
745 
746 		.progressive	= true,		    .trilevel_sync = true,
747 
748 		.vsync_start_f1 = 10,               .vsync_start_f2     = 10,
749 		.vsync_len      = 10,
750 
751 		.veq_ena        = false,
752 
753 		.vi_end_f1      = 29,               .vi_end_f2          = 29,
754 		.nbr_end        = 719,
755 
756 		.burst_ena      = false,
757 
758 		.filter_table = filter_table,
759 		.max_srcw = 800
760 	},
761 	{
762 		.name       = "1080i@50Hz",
763 		.clock		= 148800,
764 		.refresh	= 50000,
765 		.oversample     = TV_OVERSAMPLE_2X,
766 		.component_only = 1,
767 
768 		.hsync_end      = 88,               .hblank_end         = 235,
769 		.hblank_start   = 2155,             .htotal             = 2639,
770 
771 		.progressive	= false,	  .trilevel_sync = true,
772 
773 		.vsync_start_f1 = 4,              .vsync_start_f2     = 5,
774 		.vsync_len      = 10,
775 
776 		.veq_ena	= true,	    .veq_start_f1	= 4,
777 		.veq_start_f2   = 4,	    .veq_len		= 10,
778 
779 
780 		.vi_end_f1      = 21,           .vi_end_f2          = 22,
781 		.nbr_end        = 539,
782 
783 		.burst_ena      = false,
784 
785 		.filter_table = filter_table,
786 	},
787 	{
788 		.name       = "1080i@60Hz",
789 		.clock		= 148800,
790 		.refresh	= 60000,
791 		.oversample     = TV_OVERSAMPLE_2X,
792 		.component_only = 1,
793 
794 		.hsync_end      = 88,               .hblank_end         = 235,
795 		.hblank_start   = 2155,             .htotal             = 2199,
796 
797 		.progressive	= false,	    .trilevel_sync = true,
798 
799 		.vsync_start_f1 = 4,               .vsync_start_f2     = 5,
800 		.vsync_len      = 10,
801 
802 		.veq_ena	= true,		    .veq_start_f1	= 4,
803 		.veq_start_f2	= 4,		    .veq_len		= 10,
804 
805 
806 		.vi_end_f1      = 21,               .vi_end_f2          = 22,
807 		.nbr_end        = 539,
808 
809 		.burst_ena      = false,
810 
811 		.filter_table = filter_table,
812 	},
813 };
814 
815 static struct intel_tv *enc_to_tv(struct intel_encoder *encoder)
816 {
817 	return container_of(encoder, struct intel_tv, base);
818 }
819 
820 static struct intel_tv *intel_attached_tv(struct drm_connector *connector)
821 {
822 	return enc_to_tv(intel_attached_encoder(connector));
823 }
824 
825 static bool
826 intel_tv_get_hw_state(struct intel_encoder *encoder, enum i915_pipe *pipe)
827 {
828 	struct drm_device *dev = encoder->base.dev;
829 	struct drm_i915_private *dev_priv = dev->dev_private;
830 	u32 tmp = I915_READ(TV_CTL);
831 
832 	if (!(tmp & TV_ENC_ENABLE))
833 		return false;
834 
835 	*pipe = PORT_TO_PIPE(tmp);
836 
837 	return true;
838 }
839 
840 static void
841 intel_enable_tv(struct intel_encoder *encoder)
842 {
843 	struct drm_device *dev = encoder->base.dev;
844 	struct drm_i915_private *dev_priv = dev->dev_private;
845 
846 	/* Prevents vblank waits from timing out in intel_tv_detect_type() */
847 	intel_wait_for_vblank(encoder->base.dev,
848 			      to_intel_crtc(encoder->base.crtc)->pipe);
849 
850 	I915_WRITE(TV_CTL, I915_READ(TV_CTL) | TV_ENC_ENABLE);
851 }
852 
853 static void
854 intel_disable_tv(struct intel_encoder *encoder)
855 {
856 	struct drm_device *dev = encoder->base.dev;
857 	struct drm_i915_private *dev_priv = dev->dev_private;
858 
859 	I915_WRITE(TV_CTL, I915_READ(TV_CTL) & ~TV_ENC_ENABLE);
860 }
861 
862 static const struct tv_mode *
863 intel_tv_mode_lookup(const char *tv_format)
864 {
865 	int i;
866 
867 	for (i = 0; i < ARRAY_SIZE(tv_modes); i++) {
868 		const struct tv_mode *tv_mode = &tv_modes[i];
869 
870 		if (!strcmp(tv_format, tv_mode->name))
871 			return tv_mode;
872 	}
873 	return NULL;
874 }
875 
876 static const struct tv_mode *
877 intel_tv_mode_find(struct intel_tv *intel_tv)
878 {
879 	return intel_tv_mode_lookup(intel_tv->tv_format);
880 }
881 
882 static enum drm_mode_status
883 intel_tv_mode_valid(struct drm_connector *connector,
884 		    struct drm_display_mode *mode)
885 {
886 	struct intel_tv *intel_tv = intel_attached_tv(connector);
887 	const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv);
888 	int max_dotclk = to_i915(connector->dev)->max_dotclk_freq;
889 
890 	if (mode->clock > max_dotclk)
891 		return MODE_CLOCK_HIGH;
892 
893 	/* Ensure TV refresh is close to desired refresh */
894 	if (tv_mode && abs(tv_mode->refresh - drm_mode_vrefresh(mode) * 1000)
895 				< 1000)
896 		return MODE_OK;
897 
898 	return MODE_CLOCK_RANGE;
899 }
900 
901 
902 static void
903 intel_tv_get_config(struct intel_encoder *encoder,
904 		    struct intel_crtc_state *pipe_config)
905 {
906 	pipe_config->base.adjusted_mode.crtc_clock = pipe_config->port_clock;
907 }
908 
909 static bool
910 intel_tv_compute_config(struct intel_encoder *encoder,
911 			struct intel_crtc_state *pipe_config)
912 {
913 	struct intel_tv *intel_tv = enc_to_tv(encoder);
914 	const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv);
915 
916 	if (!tv_mode)
917 		return false;
918 
919 	pipe_config->base.adjusted_mode.crtc_clock = tv_mode->clock;
920 	DRM_DEBUG_KMS("forcing bpc to 8 for TV\n");
921 	pipe_config->pipe_bpp = 8*3;
922 
923 	/* TV has it's own notion of sync and other mode flags, so clear them. */
924 	pipe_config->base.adjusted_mode.flags = 0;
925 
926 	/*
927 	 * FIXME: We don't check whether the input mode is actually what we want
928 	 * or whether userspace is doing something stupid.
929 	 */
930 
931 	return true;
932 }
933 
934 static void
935 set_tv_mode_timings(struct drm_i915_private *dev_priv,
936 		    const struct tv_mode *tv_mode,
937 		    bool burst_ena)
938 {
939 	u32 hctl1, hctl2, hctl3;
940 	u32 vctl1, vctl2, vctl3, vctl4, vctl5, vctl6, vctl7;
941 
942 	hctl1 = (tv_mode->hsync_end << TV_HSYNC_END_SHIFT) |
943 		(tv_mode->htotal << TV_HTOTAL_SHIFT);
944 
945 	hctl2 = (tv_mode->hburst_start << 16) |
946 		(tv_mode->hburst_len << TV_HBURST_LEN_SHIFT);
947 
948 	if (burst_ena)
949 		hctl2 |= TV_BURST_ENA;
950 
951 	hctl3 = (tv_mode->hblank_start << TV_HBLANK_START_SHIFT) |
952 		(tv_mode->hblank_end << TV_HBLANK_END_SHIFT);
953 
954 	vctl1 = (tv_mode->nbr_end << TV_NBR_END_SHIFT) |
955 		(tv_mode->vi_end_f1 << TV_VI_END_F1_SHIFT) |
956 		(tv_mode->vi_end_f2 << TV_VI_END_F2_SHIFT);
957 
958 	vctl2 = (tv_mode->vsync_len << TV_VSYNC_LEN_SHIFT) |
959 		(tv_mode->vsync_start_f1 << TV_VSYNC_START_F1_SHIFT) |
960 		(tv_mode->vsync_start_f2 << TV_VSYNC_START_F2_SHIFT);
961 
962 	vctl3 = (tv_mode->veq_len << TV_VEQ_LEN_SHIFT) |
963 		(tv_mode->veq_start_f1 << TV_VEQ_START_F1_SHIFT) |
964 		(tv_mode->veq_start_f2 << TV_VEQ_START_F2_SHIFT);
965 
966 	if (tv_mode->veq_ena)
967 		vctl3 |= TV_EQUAL_ENA;
968 
969 	vctl4 = (tv_mode->vburst_start_f1 << TV_VBURST_START_F1_SHIFT) |
970 		(tv_mode->vburst_end_f1 << TV_VBURST_END_F1_SHIFT);
971 
972 	vctl5 = (tv_mode->vburst_start_f2 << TV_VBURST_START_F2_SHIFT) |
973 		(tv_mode->vburst_end_f2 << TV_VBURST_END_F2_SHIFT);
974 
975 	vctl6 = (tv_mode->vburst_start_f3 << TV_VBURST_START_F3_SHIFT) |
976 		(tv_mode->vburst_end_f3 << TV_VBURST_END_F3_SHIFT);
977 
978 	vctl7 = (tv_mode->vburst_start_f4 << TV_VBURST_START_F4_SHIFT) |
979 		(tv_mode->vburst_end_f4 << TV_VBURST_END_F4_SHIFT);
980 
981 	I915_WRITE(TV_H_CTL_1, hctl1);
982 	I915_WRITE(TV_H_CTL_2, hctl2);
983 	I915_WRITE(TV_H_CTL_3, hctl3);
984 	I915_WRITE(TV_V_CTL_1, vctl1);
985 	I915_WRITE(TV_V_CTL_2, vctl2);
986 	I915_WRITE(TV_V_CTL_3, vctl3);
987 	I915_WRITE(TV_V_CTL_4, vctl4);
988 	I915_WRITE(TV_V_CTL_5, vctl5);
989 	I915_WRITE(TV_V_CTL_6, vctl6);
990 	I915_WRITE(TV_V_CTL_7, vctl7);
991 }
992 
993 static void set_color_conversion(struct drm_i915_private *dev_priv,
994 				 const struct color_conversion *color_conversion)
995 {
996 	if (!color_conversion)
997 		return;
998 
999 	I915_WRITE(TV_CSC_Y, (color_conversion->ry << 16) |
1000 		   color_conversion->gy);
1001 	I915_WRITE(TV_CSC_Y2, (color_conversion->by << 16) |
1002 		   color_conversion->ay);
1003 	I915_WRITE(TV_CSC_U, (color_conversion->ru << 16) |
1004 		   color_conversion->gu);
1005 	I915_WRITE(TV_CSC_U2, (color_conversion->bu << 16) |
1006 		   color_conversion->au);
1007 	I915_WRITE(TV_CSC_V, (color_conversion->rv << 16) |
1008 		   color_conversion->gv);
1009 	I915_WRITE(TV_CSC_V2, (color_conversion->bv << 16) |
1010 		   color_conversion->av);
1011 }
1012 
1013 static void intel_tv_pre_enable(struct intel_encoder *encoder)
1014 {
1015 	struct drm_device *dev = encoder->base.dev;
1016 	struct drm_i915_private *dev_priv = dev->dev_private;
1017 	struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc);
1018 	struct intel_tv *intel_tv = enc_to_tv(encoder);
1019 	const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv);
1020 	u32 tv_ctl;
1021 	u32 scctl1, scctl2, scctl3;
1022 	int i, j;
1023 	const struct video_levels *video_levels;
1024 	const struct color_conversion *color_conversion;
1025 	bool burst_ena;
1026 	int xpos = 0x0, ypos = 0x0;
1027 	unsigned int xsize, ysize;
1028 
1029 	if (!tv_mode)
1030 		return;	/* can't happen (mode_prepare prevents this) */
1031 
1032 	tv_ctl = I915_READ(TV_CTL);
1033 	tv_ctl &= TV_CTL_SAVE;
1034 
1035 	switch (intel_tv->type) {
1036 	default:
1037 	case DRM_MODE_CONNECTOR_Unknown:
1038 	case DRM_MODE_CONNECTOR_Composite:
1039 		tv_ctl |= TV_ENC_OUTPUT_COMPOSITE;
1040 		video_levels = tv_mode->composite_levels;
1041 		color_conversion = tv_mode->composite_color;
1042 		burst_ena = tv_mode->burst_ena;
1043 		break;
1044 	case DRM_MODE_CONNECTOR_Component:
1045 		tv_ctl |= TV_ENC_OUTPUT_COMPONENT;
1046 		video_levels = &component_levels;
1047 		if (tv_mode->burst_ena)
1048 			color_conversion = &sdtv_csc_yprpb;
1049 		else
1050 			color_conversion = &hdtv_csc_yprpb;
1051 		burst_ena = false;
1052 		break;
1053 	case DRM_MODE_CONNECTOR_SVIDEO:
1054 		tv_ctl |= TV_ENC_OUTPUT_SVIDEO;
1055 		video_levels = tv_mode->svideo_levels;
1056 		color_conversion = tv_mode->svideo_color;
1057 		burst_ena = tv_mode->burst_ena;
1058 		break;
1059 	}
1060 
1061 	if (intel_crtc->pipe == 1)
1062 		tv_ctl |= TV_ENC_PIPEB_SELECT;
1063 	tv_ctl |= tv_mode->oversample;
1064 
1065 	if (tv_mode->progressive)
1066 		tv_ctl |= TV_PROGRESSIVE;
1067 	if (tv_mode->trilevel_sync)
1068 		tv_ctl |= TV_TRILEVEL_SYNC;
1069 	if (tv_mode->pal_burst)
1070 		tv_ctl |= TV_PAL_BURST;
1071 
1072 	scctl1 = 0;
1073 	if (tv_mode->dda1_inc)
1074 		scctl1 |= TV_SC_DDA1_EN;
1075 	if (tv_mode->dda2_inc)
1076 		scctl1 |= TV_SC_DDA2_EN;
1077 	if (tv_mode->dda3_inc)
1078 		scctl1 |= TV_SC_DDA3_EN;
1079 	scctl1 |= tv_mode->sc_reset;
1080 	if (video_levels)
1081 		scctl1 |= video_levels->burst << TV_BURST_LEVEL_SHIFT;
1082 	scctl1 |= tv_mode->dda1_inc << TV_SCDDA1_INC_SHIFT;
1083 
1084 	scctl2 = tv_mode->dda2_size << TV_SCDDA2_SIZE_SHIFT |
1085 		tv_mode->dda2_inc << TV_SCDDA2_INC_SHIFT;
1086 
1087 	scctl3 = tv_mode->dda3_size << TV_SCDDA3_SIZE_SHIFT |
1088 		tv_mode->dda3_inc << TV_SCDDA3_INC_SHIFT;
1089 
1090 	/* Enable two fixes for the chips that need them. */
1091 	if (IS_I915GM(dev))
1092 		tv_ctl |= TV_ENC_C0_FIX | TV_ENC_SDP_FIX;
1093 
1094 	set_tv_mode_timings(dev_priv, tv_mode, burst_ena);
1095 
1096 	I915_WRITE(TV_SC_CTL_1, scctl1);
1097 	I915_WRITE(TV_SC_CTL_2, scctl2);
1098 	I915_WRITE(TV_SC_CTL_3, scctl3);
1099 
1100 	set_color_conversion(dev_priv, color_conversion);
1101 
1102 	if (INTEL_INFO(dev)->gen >= 4)
1103 		I915_WRITE(TV_CLR_KNOBS, 0x00404000);
1104 	else
1105 		I915_WRITE(TV_CLR_KNOBS, 0x00606000);
1106 
1107 	if (video_levels)
1108 		I915_WRITE(TV_CLR_LEVEL,
1109 			   ((video_levels->black << TV_BLACK_LEVEL_SHIFT) |
1110 			    (video_levels->blank << TV_BLANK_LEVEL_SHIFT)));
1111 
1112 	assert_pipe_disabled(dev_priv, intel_crtc->pipe);
1113 
1114 	/* Filter ctl must be set before TV_WIN_SIZE */
1115 	I915_WRITE(TV_FILTER_CTL_1, TV_AUTO_SCALE);
1116 	xsize = tv_mode->hblank_start - tv_mode->hblank_end;
1117 	if (tv_mode->progressive)
1118 		ysize = tv_mode->nbr_end + 1;
1119 	else
1120 		ysize = 2*tv_mode->nbr_end + 1;
1121 
1122 	xpos += intel_tv->margin[TV_MARGIN_LEFT];
1123 	ypos += intel_tv->margin[TV_MARGIN_TOP];
1124 	xsize -= (intel_tv->margin[TV_MARGIN_LEFT] +
1125 		  intel_tv->margin[TV_MARGIN_RIGHT]);
1126 	ysize -= (intel_tv->margin[TV_MARGIN_TOP] +
1127 		  intel_tv->margin[TV_MARGIN_BOTTOM]);
1128 	I915_WRITE(TV_WIN_POS, (xpos<<16)|ypos);
1129 	I915_WRITE(TV_WIN_SIZE, (xsize<<16)|ysize);
1130 
1131 	j = 0;
1132 	for (i = 0; i < 60; i++)
1133 		I915_WRITE(TV_H_LUMA(i), tv_mode->filter_table[j++]);
1134 	for (i = 0; i < 60; i++)
1135 		I915_WRITE(TV_H_CHROMA(i), tv_mode->filter_table[j++]);
1136 	for (i = 0; i < 43; i++)
1137 		I915_WRITE(TV_V_LUMA(i), tv_mode->filter_table[j++]);
1138 	for (i = 0; i < 43; i++)
1139 		I915_WRITE(TV_V_CHROMA(i), tv_mode->filter_table[j++]);
1140 	I915_WRITE(TV_DAC, I915_READ(TV_DAC) & TV_DAC_SAVE);
1141 	I915_WRITE(TV_CTL, tv_ctl);
1142 }
1143 
1144 static const struct drm_display_mode reported_modes[] = {
1145 	{
1146 		.name = "NTSC 480i",
1147 		.clock = 107520,
1148 		.hdisplay = 1280,
1149 		.hsync_start = 1368,
1150 		.hsync_end = 1496,
1151 		.htotal = 1712,
1152 
1153 		.vdisplay = 1024,
1154 		.vsync_start = 1027,
1155 		.vsync_end = 1034,
1156 		.vtotal = 1104,
1157 		.type = DRM_MODE_TYPE_DRIVER,
1158 	},
1159 };
1160 
1161 /**
1162  * Detects TV presence by checking for load.
1163  *
1164  * Requires that the current pipe's DPLL is active.
1165 
1166  * \return true if TV is connected.
1167  * \return false if TV is disconnected.
1168  */
1169 static int
1170 intel_tv_detect_type(struct intel_tv *intel_tv,
1171 		      struct drm_connector *connector)
1172 {
1173 	struct drm_crtc *crtc = connector->state->crtc;
1174 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
1175 	struct drm_device *dev = connector->dev;
1176 	struct drm_i915_private *dev_priv = dev->dev_private;
1177 	u32 tv_ctl, save_tv_ctl;
1178 	u32 tv_dac, save_tv_dac;
1179 	int type;
1180 
1181 	/* Disable TV interrupts around load detect or we'll recurse */
1182 	if (connector->polled & DRM_CONNECTOR_POLL_HPD) {
1183 		spin_lock_irq(&dev_priv->irq_lock);
1184 		i915_disable_pipestat(dev_priv, 0,
1185 				      PIPE_HOTPLUG_INTERRUPT_STATUS |
1186 				      PIPE_HOTPLUG_TV_INTERRUPT_STATUS);
1187 		spin_unlock_irq(&dev_priv->irq_lock);
1188 	}
1189 
1190 	save_tv_dac = tv_dac = I915_READ(TV_DAC);
1191 	save_tv_ctl = tv_ctl = I915_READ(TV_CTL);
1192 
1193 	/* Poll for TV detection */
1194 	tv_ctl &= ~(TV_ENC_ENABLE | TV_TEST_MODE_MASK);
1195 	tv_ctl |= TV_TEST_MODE_MONITOR_DETECT;
1196 	if (intel_crtc->pipe == 1)
1197 		tv_ctl |= TV_ENC_PIPEB_SELECT;
1198 	else
1199 		tv_ctl &= ~TV_ENC_PIPEB_SELECT;
1200 
1201 	tv_dac &= ~(TVDAC_SENSE_MASK | DAC_A_MASK | DAC_B_MASK | DAC_C_MASK);
1202 	tv_dac |= (TVDAC_STATE_CHG_EN |
1203 		   TVDAC_A_SENSE_CTL |
1204 		   TVDAC_B_SENSE_CTL |
1205 		   TVDAC_C_SENSE_CTL |
1206 		   DAC_CTL_OVERRIDE |
1207 		   DAC_A_0_7_V |
1208 		   DAC_B_0_7_V |
1209 		   DAC_C_0_7_V);
1210 
1211 
1212 	/*
1213 	 * The TV sense state should be cleared to zero on cantiga platform. Otherwise
1214 	 * the TV is misdetected. This is hardware requirement.
1215 	 */
1216 	if (IS_GM45(dev))
1217 		tv_dac &= ~(TVDAC_STATE_CHG_EN | TVDAC_A_SENSE_CTL |
1218 			    TVDAC_B_SENSE_CTL | TVDAC_C_SENSE_CTL);
1219 
1220 	I915_WRITE(TV_CTL, tv_ctl);
1221 	I915_WRITE(TV_DAC, tv_dac);
1222 	POSTING_READ(TV_DAC);
1223 
1224 	intel_wait_for_vblank(dev, intel_crtc->pipe);
1225 
1226 	type = -1;
1227 	tv_dac = I915_READ(TV_DAC);
1228 	DRM_DEBUG_KMS("TV detected: %x, %x\n", tv_ctl, tv_dac);
1229 	/*
1230 	 *  A B C
1231 	 *  0 1 1 Composite
1232 	 *  1 0 X svideo
1233 	 *  0 0 0 Component
1234 	 */
1235 	if ((tv_dac & TVDAC_SENSE_MASK) == (TVDAC_B_SENSE | TVDAC_C_SENSE)) {
1236 		DRM_DEBUG_KMS("Detected Composite TV connection\n");
1237 		type = DRM_MODE_CONNECTOR_Composite;
1238 	} else if ((tv_dac & (TVDAC_A_SENSE|TVDAC_B_SENSE)) == TVDAC_A_SENSE) {
1239 		DRM_DEBUG_KMS("Detected S-Video TV connection\n");
1240 		type = DRM_MODE_CONNECTOR_SVIDEO;
1241 	} else if ((tv_dac & TVDAC_SENSE_MASK) == 0) {
1242 		DRM_DEBUG_KMS("Detected Component TV connection\n");
1243 		type = DRM_MODE_CONNECTOR_Component;
1244 	} else {
1245 		DRM_DEBUG_KMS("Unrecognised TV connection\n");
1246 		type = -1;
1247 	}
1248 
1249 	I915_WRITE(TV_DAC, save_tv_dac & ~TVDAC_STATE_CHG_EN);
1250 	I915_WRITE(TV_CTL, save_tv_ctl);
1251 	POSTING_READ(TV_CTL);
1252 
1253 	/* For unknown reasons the hw barfs if we don't do this vblank wait. */
1254 	intel_wait_for_vblank(dev, intel_crtc->pipe);
1255 
1256 	/* Restore interrupt config */
1257 	if (connector->polled & DRM_CONNECTOR_POLL_HPD) {
1258 		spin_lock_irq(&dev_priv->irq_lock);
1259 		i915_enable_pipestat(dev_priv, 0,
1260 				     PIPE_HOTPLUG_INTERRUPT_STATUS |
1261 				     PIPE_HOTPLUG_TV_INTERRUPT_STATUS);
1262 		spin_unlock_irq(&dev_priv->irq_lock);
1263 	}
1264 
1265 	return type;
1266 }
1267 
1268 /*
1269  * Here we set accurate tv format according to connector type
1270  * i.e Component TV should not be assigned by NTSC or PAL
1271  */
1272 static void intel_tv_find_better_format(struct drm_connector *connector)
1273 {
1274 	struct intel_tv *intel_tv = intel_attached_tv(connector);
1275 	const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv);
1276 	int i;
1277 
1278 	if ((intel_tv->type == DRM_MODE_CONNECTOR_Component) ==
1279 		tv_mode->component_only)
1280 		return;
1281 
1282 
1283 	for (i = 0; i < ARRAY_SIZE(tv_modes); i++) {
1284 		tv_mode = tv_modes + i;
1285 
1286 		if ((intel_tv->type == DRM_MODE_CONNECTOR_Component) ==
1287 			tv_mode->component_only)
1288 			break;
1289 	}
1290 
1291 	intel_tv->tv_format = tv_mode->name;
1292 	drm_object_property_set_value(&connector->base,
1293 		connector->dev->mode_config.tv_mode_property, i);
1294 }
1295 
1296 /**
1297  * Detect the TV connection.
1298  *
1299  * Currently this always returns CONNECTOR_STATUS_UNKNOWN, as we need to be sure
1300  * we have a pipe programmed in order to probe the TV.
1301  */
1302 static enum drm_connector_status
1303 intel_tv_detect(struct drm_connector *connector, bool force)
1304 {
1305 	struct drm_display_mode mode;
1306 	struct intel_tv *intel_tv = intel_attached_tv(connector);
1307 	enum drm_connector_status status;
1308 	int type;
1309 
1310 	DRM_DEBUG_KMS("[CONNECTOR:%d:%s] force=%d\n",
1311 		      connector->base.id, connector->name,
1312 		      force);
1313 
1314 	mode = reported_modes[0];
1315 
1316 	if (force) {
1317 		struct intel_load_detect_pipe tmp;
1318 		struct drm_modeset_acquire_ctx ctx;
1319 
1320 		drm_modeset_acquire_init(&ctx, 0);
1321 
1322 		if (intel_get_load_detect_pipe(connector, &mode, &tmp, &ctx)) {
1323 			type = intel_tv_detect_type(intel_tv, connector);
1324 			intel_release_load_detect_pipe(connector, &tmp, &ctx);
1325 			status = type < 0 ?
1326 				connector_status_disconnected :
1327 				connector_status_connected;
1328 		} else
1329 			status = connector_status_unknown;
1330 
1331 		drm_modeset_drop_locks(&ctx);
1332 		drm_modeset_acquire_fini(&ctx);
1333 	} else
1334 		return connector->status;
1335 
1336 	if (status != connector_status_connected)
1337 		return status;
1338 
1339 	intel_tv->type = type;
1340 	intel_tv_find_better_format(connector);
1341 
1342 	return connector_status_connected;
1343 }
1344 
1345 static const struct input_res {
1346 	const char *name;
1347 	int w, h;
1348 } input_res_table[] = {
1349 	{"640x480", 640, 480},
1350 	{"800x600", 800, 600},
1351 	{"1024x768", 1024, 768},
1352 	{"1280x1024", 1280, 1024},
1353 	{"848x480", 848, 480},
1354 	{"1280x720", 1280, 720},
1355 	{"1920x1080", 1920, 1080},
1356 };
1357 
1358 /*
1359  * Chose preferred mode  according to line number of TV format
1360  */
1361 static void
1362 intel_tv_chose_preferred_modes(struct drm_connector *connector,
1363 			       struct drm_display_mode *mode_ptr)
1364 {
1365 	struct intel_tv *intel_tv = intel_attached_tv(connector);
1366 	const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv);
1367 
1368 	if (tv_mode->nbr_end < 480 && mode_ptr->vdisplay == 480)
1369 		mode_ptr->type |= DRM_MODE_TYPE_PREFERRED;
1370 	else if (tv_mode->nbr_end > 480) {
1371 		if (tv_mode->progressive == true && tv_mode->nbr_end < 720) {
1372 			if (mode_ptr->vdisplay == 720)
1373 				mode_ptr->type |= DRM_MODE_TYPE_PREFERRED;
1374 		} else if (mode_ptr->vdisplay == 1080)
1375 				mode_ptr->type |= DRM_MODE_TYPE_PREFERRED;
1376 	}
1377 }
1378 
1379 /**
1380  * Stub get_modes function.
1381  *
1382  * This should probably return a set of fixed modes, unless we can figure out
1383  * how to probe modes off of TV connections.
1384  */
1385 
1386 static int
1387 intel_tv_get_modes(struct drm_connector *connector)
1388 {
1389 	struct drm_display_mode *mode_ptr;
1390 	struct intel_tv *intel_tv = intel_attached_tv(connector);
1391 	const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv);
1392 	int j, count = 0;
1393 	u64 tmp;
1394 
1395 	for (j = 0; j < ARRAY_SIZE(input_res_table);
1396 	     j++) {
1397 		const struct input_res *input = &input_res_table[j];
1398 		unsigned int hactive_s = input->w;
1399 		unsigned int vactive_s = input->h;
1400 
1401 		if (tv_mode->max_srcw && input->w > tv_mode->max_srcw)
1402 			continue;
1403 
1404 		if (input->w > 1024 && (!tv_mode->progressive
1405 					&& !tv_mode->component_only))
1406 			continue;
1407 
1408 		mode_ptr = drm_mode_create(connector->dev);
1409 		if (!mode_ptr)
1410 			continue;
1411 		strncpy(mode_ptr->name, input->name, DRM_DISPLAY_MODE_LEN);
1412 		mode_ptr->name[DRM_DISPLAY_MODE_LEN - 1] = '\0';
1413 
1414 		mode_ptr->hdisplay = hactive_s;
1415 		mode_ptr->hsync_start = hactive_s + 1;
1416 		mode_ptr->hsync_end = hactive_s + 64;
1417 		if (mode_ptr->hsync_end <= mode_ptr->hsync_start)
1418 			mode_ptr->hsync_end = mode_ptr->hsync_start + 1;
1419 		mode_ptr->htotal = hactive_s + 96;
1420 
1421 		mode_ptr->vdisplay = vactive_s;
1422 		mode_ptr->vsync_start = vactive_s + 1;
1423 		mode_ptr->vsync_end = vactive_s + 32;
1424 		if (mode_ptr->vsync_end <= mode_ptr->vsync_start)
1425 			mode_ptr->vsync_end = mode_ptr->vsync_start  + 1;
1426 		mode_ptr->vtotal = vactive_s + 33;
1427 
1428 		tmp = (u64) tv_mode->refresh * mode_ptr->vtotal;
1429 		tmp *= mode_ptr->htotal;
1430 		tmp = div_u64(tmp, 1000000);
1431 		mode_ptr->clock = (int) tmp;
1432 
1433 		mode_ptr->type = DRM_MODE_TYPE_DRIVER;
1434 		intel_tv_chose_preferred_modes(connector, mode_ptr);
1435 		drm_mode_probed_add(connector, mode_ptr);
1436 		count++;
1437 	}
1438 
1439 	return count;
1440 }
1441 
1442 static void
1443 intel_tv_destroy(struct drm_connector *connector)
1444 {
1445 	drm_connector_cleanup(connector);
1446 	kfree(connector);
1447 }
1448 
1449 
1450 static int
1451 intel_tv_set_property(struct drm_connector *connector, struct drm_property *property,
1452 		      uint64_t val)
1453 {
1454 	struct drm_device *dev = connector->dev;
1455 	struct intel_tv *intel_tv = intel_attached_tv(connector);
1456 	struct drm_crtc *crtc = intel_tv->base.base.crtc;
1457 	int ret = 0;
1458 	bool changed = false;
1459 
1460 	ret = drm_object_property_set_value(&connector->base, property, val);
1461 	if (ret < 0)
1462 		goto out;
1463 
1464 	if (property == dev->mode_config.tv_left_margin_property &&
1465 		intel_tv->margin[TV_MARGIN_LEFT] != val) {
1466 		intel_tv->margin[TV_MARGIN_LEFT] = val;
1467 		changed = true;
1468 	} else if (property == dev->mode_config.tv_right_margin_property &&
1469 		intel_tv->margin[TV_MARGIN_RIGHT] != val) {
1470 		intel_tv->margin[TV_MARGIN_RIGHT] = val;
1471 		changed = true;
1472 	} else if (property == dev->mode_config.tv_top_margin_property &&
1473 		intel_tv->margin[TV_MARGIN_TOP] != val) {
1474 		intel_tv->margin[TV_MARGIN_TOP] = val;
1475 		changed = true;
1476 	} else if (property == dev->mode_config.tv_bottom_margin_property &&
1477 		intel_tv->margin[TV_MARGIN_BOTTOM] != val) {
1478 		intel_tv->margin[TV_MARGIN_BOTTOM] = val;
1479 		changed = true;
1480 	} else if (property == dev->mode_config.tv_mode_property) {
1481 		if (val >= ARRAY_SIZE(tv_modes)) {
1482 			ret = -EINVAL;
1483 			goto out;
1484 		}
1485 		if (!strcmp(intel_tv->tv_format, tv_modes[val].name))
1486 			goto out;
1487 
1488 		intel_tv->tv_format = tv_modes[val].name;
1489 		changed = true;
1490 	} else {
1491 		ret = -EINVAL;
1492 		goto out;
1493 	}
1494 
1495 	if (changed && crtc)
1496 		intel_crtc_restore_mode(crtc);
1497 out:
1498 	return ret;
1499 }
1500 
1501 static const struct drm_connector_funcs intel_tv_connector_funcs = {
1502 	.dpms = drm_atomic_helper_connector_dpms,
1503 	.detect = intel_tv_detect,
1504 	.destroy = intel_tv_destroy,
1505 	.set_property = intel_tv_set_property,
1506 	.atomic_get_property = intel_connector_atomic_get_property,
1507 	.fill_modes = drm_helper_probe_single_connector_modes,
1508 	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
1509 	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
1510 };
1511 
1512 static const struct drm_connector_helper_funcs intel_tv_connector_helper_funcs = {
1513 	.mode_valid = intel_tv_mode_valid,
1514 	.get_modes = intel_tv_get_modes,
1515 	.best_encoder = intel_best_encoder,
1516 };
1517 
1518 static const struct drm_encoder_funcs intel_tv_enc_funcs = {
1519 	.destroy = intel_encoder_destroy,
1520 };
1521 
1522 void
1523 intel_tv_init(struct drm_device *dev)
1524 {
1525 	struct drm_i915_private *dev_priv = dev->dev_private;
1526 	struct drm_connector *connector;
1527 	struct intel_tv *intel_tv;
1528 	struct intel_encoder *intel_encoder;
1529 	struct intel_connector *intel_connector;
1530 	u32 tv_dac_on, tv_dac_off, save_tv_dac;
1531 	const char *tv_format_names[ARRAY_SIZE(tv_modes)];
1532 	int i, initial_mode = 0;
1533 
1534 	if ((I915_READ(TV_CTL) & TV_FUSE_STATE_MASK) == TV_FUSE_STATE_DISABLED)
1535 		return;
1536 
1537 	if (!intel_bios_is_tv_present(dev_priv)) {
1538 		DRM_DEBUG_KMS("Integrated TV is not present.\n");
1539 		return;
1540 	}
1541 
1542 	/*
1543 	 * Sanity check the TV output by checking to see if the
1544 	 * DAC register holds a value
1545 	 */
1546 	save_tv_dac = I915_READ(TV_DAC);
1547 
1548 	I915_WRITE(TV_DAC, save_tv_dac | TVDAC_STATE_CHG_EN);
1549 	tv_dac_on = I915_READ(TV_DAC);
1550 
1551 	I915_WRITE(TV_DAC, save_tv_dac & ~TVDAC_STATE_CHG_EN);
1552 	tv_dac_off = I915_READ(TV_DAC);
1553 
1554 	I915_WRITE(TV_DAC, save_tv_dac);
1555 
1556 	/*
1557 	 * If the register does not hold the state change enable
1558 	 * bit, (either as a 0 or a 1), assume it doesn't really
1559 	 * exist
1560 	 */
1561 	if ((tv_dac_on & TVDAC_STATE_CHG_EN) == 0 ||
1562 	    (tv_dac_off & TVDAC_STATE_CHG_EN) != 0)
1563 		return;
1564 
1565 	intel_tv = kzalloc(sizeof(*intel_tv), GFP_KERNEL);
1566 	if (!intel_tv) {
1567 		return;
1568 	}
1569 
1570 	intel_connector = intel_connector_alloc();
1571 	if (!intel_connector) {
1572 		kfree(intel_tv);
1573 		return;
1574 	}
1575 
1576 	intel_encoder = &intel_tv->base;
1577 	connector = &intel_connector->base;
1578 
1579 	/* The documentation, for the older chipsets at least, recommend
1580 	 * using a polling method rather than hotplug detection for TVs.
1581 	 * This is because in order to perform the hotplug detection, the PLLs
1582 	 * for the TV must be kept alive increasing power drain and starving
1583 	 * bandwidth from other encoders. Notably for instance, it causes
1584 	 * pipe underruns on Crestline when this encoder is supposedly idle.
1585 	 *
1586 	 * More recent chipsets favour HDMI rather than integrated S-Video.
1587 	 */
1588 	intel_connector->polled = DRM_CONNECTOR_POLL_CONNECT;
1589 
1590 	drm_connector_init(dev, connector, &intel_tv_connector_funcs,
1591 			   DRM_MODE_CONNECTOR_SVIDEO);
1592 
1593 	drm_encoder_init(dev, &intel_encoder->base, &intel_tv_enc_funcs,
1594 			 DRM_MODE_ENCODER_TVDAC, NULL);
1595 
1596 	intel_encoder->compute_config = intel_tv_compute_config;
1597 	intel_encoder->get_config = intel_tv_get_config;
1598 	intel_encoder->pre_enable = intel_tv_pre_enable;
1599 	intel_encoder->enable = intel_enable_tv;
1600 	intel_encoder->disable = intel_disable_tv;
1601 	intel_encoder->get_hw_state = intel_tv_get_hw_state;
1602 	intel_connector->get_hw_state = intel_connector_get_hw_state;
1603 	intel_connector->unregister = intel_connector_unregister;
1604 
1605 	intel_connector_attach_encoder(intel_connector, intel_encoder);
1606 	intel_encoder->type = INTEL_OUTPUT_TVOUT;
1607 	intel_encoder->crtc_mask = (1 << 0) | (1 << 1);
1608 	intel_encoder->cloneable = 0;
1609 	intel_encoder->base.possible_crtcs = ((1 << 0) | (1 << 1));
1610 	intel_tv->type = DRM_MODE_CONNECTOR_Unknown;
1611 
1612 	/* BIOS margin values */
1613 	intel_tv->margin[TV_MARGIN_LEFT] = 54;
1614 	intel_tv->margin[TV_MARGIN_TOP] = 36;
1615 	intel_tv->margin[TV_MARGIN_RIGHT] = 46;
1616 	intel_tv->margin[TV_MARGIN_BOTTOM] = 37;
1617 
1618 	intel_tv->tv_format = tv_modes[initial_mode].name;
1619 
1620 	drm_connector_helper_add(connector, &intel_tv_connector_helper_funcs);
1621 	connector->interlace_allowed = false;
1622 	connector->doublescan_allowed = false;
1623 
1624 	/* Create TV properties then attach current values */
1625 	for (i = 0; i < ARRAY_SIZE(tv_modes); i++)
1626 		tv_format_names[i] = tv_modes[i].name;
1627 	drm_mode_create_tv_properties(dev,
1628 				      ARRAY_SIZE(tv_modes),
1629 				      tv_format_names);
1630 
1631 	drm_object_attach_property(&connector->base, dev->mode_config.tv_mode_property,
1632 				   initial_mode);
1633 	drm_object_attach_property(&connector->base,
1634 				   dev->mode_config.tv_left_margin_property,
1635 				   intel_tv->margin[TV_MARGIN_LEFT]);
1636 	drm_object_attach_property(&connector->base,
1637 				   dev->mode_config.tv_top_margin_property,
1638 				   intel_tv->margin[TV_MARGIN_TOP]);
1639 	drm_object_attach_property(&connector->base,
1640 				   dev->mode_config.tv_right_margin_property,
1641 				   intel_tv->margin[TV_MARGIN_RIGHT]);
1642 	drm_object_attach_property(&connector->base,
1643 				   dev->mode_config.tv_bottom_margin_property,
1644 				   intel_tv->margin[TV_MARGIN_BOTTOM]);
1645 	drm_connector_register(connector);
1646 }
1647