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