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