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