1/*	$NetBSD: intel_tv.c,v 1.3 2021/12/19 11:49:11 riastradh Exp $	*/
2
3/*
4 * Copyright �� 2006-2008 Intel Corporation
5 *   Jesse Barnes <jesse.barnes@intel.com>
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the next
15 * paragraph) shall be included in all copies or substantial portions of the
16 * Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
21 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24 * DEALINGS IN THE SOFTWARE.
25 *
26 * Authors:
27 *    Eric Anholt <eric@anholt.net>
28 *
29 */
30
31/** @file
32 * Integrated TV-out support for the 915GM and 945GM.
33 */
34
35#include <sys/cdefs.h>
36__KERNEL_RCSID(0, "$NetBSD: intel_tv.c,v 1.3 2021/12/19 11:49:11 riastradh Exp $");
37
38#include <drm/drm_atomic_helper.h>
39#include <drm/drm_crtc.h>
40#include <drm/drm_edid.h>
41#include <drm/i915_drm.h>
42
43#include "i915_drv.h"
44#include "intel_connector.h"
45#include "intel_display_types.h"
46#include "intel_hotplug.h"
47#include "intel_tv.h"
48
49enum tv_margin {
50	TV_MARGIN_LEFT, TV_MARGIN_TOP,
51	TV_MARGIN_RIGHT, TV_MARGIN_BOTTOM
52};
53
54struct intel_tv {
55	struct intel_encoder base;
56
57	int type;
58};
59
60struct video_levels {
61	u16 blank, black;
62	u8 burst;
63};
64
65struct color_conversion {
66	u16 ry, gy, by, ay;
67	u16 ru, gu, bu, au;
68	u16 rv, gv, bv, av;
69};
70
71static const u32 filter_table[] = {
72	0xB1403000, 0x2E203500, 0x35002E20, 0x3000B140,
73	0x35A0B160, 0x2DC02E80, 0xB1403480, 0xB1603000,
74	0x2EA03640, 0x34002D80, 0x3000B120, 0x36E0B160,
75	0x2D202EF0, 0xB1203380, 0xB1603000, 0x2F303780,
76	0x33002CC0, 0x3000B100, 0x3820B160, 0x2C802F50,
77	0xB10032A0, 0xB1603000, 0x2F9038C0, 0x32202C20,
78	0x3000B0E0, 0x3980B160, 0x2BC02FC0, 0xB0E031C0,
79	0xB1603000, 0x2FF03A20, 0x31602B60, 0xB020B0C0,
80	0x3AE0B160, 0x2B001810, 0xB0C03120, 0xB140B020,
81	0x18283BA0, 0x30C02A80, 0xB020B0A0, 0x3C60B140,
82	0x2A201838, 0xB0A03080, 0xB120B020, 0x18383D20,
83	0x304029C0, 0xB040B080, 0x3DE0B100, 0x29601848,
84	0xB0803000, 0xB100B040, 0x18483EC0, 0xB0402900,
85	0xB040B060, 0x3F80B0C0, 0x28801858, 0xB060B080,
86	0xB0A0B060, 0x18602820, 0xB0A02820, 0x0000B060,
87	0xB1403000, 0x2E203500, 0x35002E20, 0x3000B140,
88	0x35A0B160, 0x2DC02E80, 0xB1403480, 0xB1603000,
89	0x2EA03640, 0x34002D80, 0x3000B120, 0x36E0B160,
90	0x2D202EF0, 0xB1203380, 0xB1603000, 0x2F303780,
91	0x33002CC0, 0x3000B100, 0x3820B160, 0x2C802F50,
92	0xB10032A0, 0xB1603000, 0x2F9038C0, 0x32202C20,
93	0x3000B0E0, 0x3980B160, 0x2BC02FC0, 0xB0E031C0,
94	0xB1603000, 0x2FF03A20, 0x31602B60, 0xB020B0C0,
95	0x3AE0B160, 0x2B001810, 0xB0C03120, 0xB140B020,
96	0x18283BA0, 0x30C02A80, 0xB020B0A0, 0x3C60B140,
97	0x2A201838, 0xB0A03080, 0xB120B020, 0x18383D20,
98	0x304029C0, 0xB040B080, 0x3DE0B100, 0x29601848,
99	0xB0803000, 0xB100B040, 0x18483EC0, 0xB0402900,
100	0xB040B060, 0x3F80B0C0, 0x28801858, 0xB060B080,
101	0xB0A0B060, 0x18602820, 0xB0A02820, 0x0000B060,
102	0x36403000, 0x2D002CC0, 0x30003640, 0x2D0036C0,
103	0x35C02CC0, 0x37403000, 0x2C802D40, 0x30003540,
104	0x2D8037C0, 0x34C02C40, 0x38403000, 0x2BC02E00,
105	0x30003440, 0x2E2038C0, 0x34002B80, 0x39803000,
106	0x2B402E40, 0x30003380, 0x2E603A00, 0x33402B00,
107	0x3A803040, 0x2A802EA0, 0x30403300, 0x2EC03B40,
108	0x32802A40, 0x3C003040, 0x2A002EC0, 0x30803240,
109	0x2EC03C80, 0x320029C0, 0x3D403080, 0x29402F00,
110	0x308031C0, 0x2F203DC0, 0x31802900, 0x3E8030C0,
111	0x28802F40, 0x30C03140, 0x2F203F40, 0x31402840,
112	0x28003100, 0x28002F00, 0x00003100, 0x36403000,
113	0x2D002CC0, 0x30003640, 0x2D0036C0,
114	0x35C02CC0, 0x37403000, 0x2C802D40, 0x30003540,
115	0x2D8037C0, 0x34C02C40, 0x38403000, 0x2BC02E00,
116	0x30003440, 0x2E2038C0, 0x34002B80, 0x39803000,
117	0x2B402E40, 0x30003380, 0x2E603A00, 0x33402B00,
118	0x3A803040, 0x2A802EA0, 0x30403300, 0x2EC03B40,
119	0x32802A40, 0x3C003040, 0x2A002EC0, 0x30803240,
120	0x2EC03C80, 0x320029C0, 0x3D403080, 0x29402F00,
121	0x308031C0, 0x2F203DC0, 0x31802900, 0x3E8030C0,
122	0x28802F40, 0x30C03140, 0x2F203F40, 0x31402840,
123	0x28003100, 0x28002F00, 0x00003100,
124};
125
126/*
127 * Color conversion values have 3 separate fixed point formats:
128 *
129 * 10 bit fields (ay, au)
130 *   1.9 fixed point (b.bbbbbbbbb)
131 * 11 bit fields (ry, by, ru, gu, gv)
132 *   exp.mantissa (ee.mmmmmmmmm)
133 *   ee = 00 = 10^-1 (0.mmmmmmmmm)
134 *   ee = 01 = 10^-2 (0.0mmmmmmmmm)
135 *   ee = 10 = 10^-3 (0.00mmmmmmmmm)
136 *   ee = 11 = 10^-4 (0.000mmmmmmmmm)
137 * 12 bit fields (gy, rv, bu)
138 *   exp.mantissa (eee.mmmmmmmmm)
139 *   eee = 000 = 10^-1 (0.mmmmmmmmm)
140 *   eee = 001 = 10^-2 (0.0mmmmmmmmm)
141 *   eee = 010 = 10^-3 (0.00mmmmmmmmm)
142 *   eee = 011 = 10^-4 (0.000mmmmmmmmm)
143 *   eee = 100 = reserved
144 *   eee = 101 = reserved
145 *   eee = 110 = reserved
146 *   eee = 111 = 10^0 (m.mmmmmmmm) (only usable for 1.0 representation)
147 *
148 * Saturation and contrast are 8 bits, with their own representation:
149 * 8 bit field (saturation, contrast)
150 *   exp.mantissa (ee.mmmmmm)
151 *   ee = 00 = 10^-1 (0.mmmmmm)
152 *   ee = 01 = 10^0 (m.mmmmm)
153 *   ee = 10 = 10^1 (mm.mmmm)
154 *   ee = 11 = 10^2 (mmm.mmm)
155 *
156 * Simple conversion function:
157 *
158 * static u32
159 * float_to_csc_11(float f)
160 * {
161 *     u32 exp;
162 *     u32 mant;
163 *     u32 ret;
164 *
165 *     if (f < 0)
166 *         f = -f;
167 *
168 *     if (f >= 1) {
169 *         exp = 0x7;
170 *	   mant = 1 << 8;
171 *     } else {
172 *         for (exp = 0; exp < 3 && f < 0.5; exp++)
173 *	   f *= 2.0;
174 *         mant = (f * (1 << 9) + 0.5);
175 *         if (mant >= (1 << 9))
176 *             mant = (1 << 9) - 1;
177 *     }
178 *     ret = (exp << 9) | mant;
179 *     return ret;
180 * }
181 */
182
183/*
184 * Behold, magic numbers!  If we plant them they might grow a big
185 * s-video cable to the sky... or something.
186 *
187 * Pre-converted to appropriate hex value.
188 */
189
190/*
191 * PAL & NTSC values for composite & s-video connections
192 */
193static const struct color_conversion ntsc_m_csc_composite = {
194	.ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0104,
195	.ru = 0x0733, .gu = 0x052d, .bu = 0x05c7, .au = 0x0200,
196	.rv = 0x0340, .gv = 0x030c, .bv = 0x06d0, .av = 0x0200,
197};
198
199static const struct video_levels ntsc_m_levels_composite = {
200	.blank = 225, .black = 267, .burst = 113,
201};
202
203static const struct color_conversion ntsc_m_csc_svideo = {
204	.ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0133,
205	.ru = 0x076a, .gu = 0x0564, .bu = 0x030d, .au = 0x0200,
206	.rv = 0x037a, .gv = 0x033d, .bv = 0x06f6, .av = 0x0200,
207};
208
209static const struct video_levels ntsc_m_levels_svideo = {
210	.blank = 266, .black = 316, .burst = 133,
211};
212
213static const struct color_conversion ntsc_j_csc_composite = {
214	.ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0119,
215	.ru = 0x074c, .gu = 0x0546, .bu = 0x05ec, .au = 0x0200,
216	.rv = 0x035a, .gv = 0x0322, .bv = 0x06e1, .av = 0x0200,
217};
218
219static const struct video_levels ntsc_j_levels_composite = {
220	.blank = 225, .black = 225, .burst = 113,
221};
222
223static const struct color_conversion ntsc_j_csc_svideo = {
224	.ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x014c,
225	.ru = 0x0788, .gu = 0x0581, .bu = 0x0322, .au = 0x0200,
226	.rv = 0x0399, .gv = 0x0356, .bv = 0x070a, .av = 0x0200,
227};
228
229static const struct video_levels ntsc_j_levels_svideo = {
230	.blank = 266, .black = 266, .burst = 133,
231};
232
233static const struct color_conversion pal_csc_composite = {
234	.ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0113,
235	.ru = 0x0745, .gu = 0x053f, .bu = 0x05e1, .au = 0x0200,
236	.rv = 0x0353, .gv = 0x031c, .bv = 0x06dc, .av = 0x0200,
237};
238
239static const struct video_levels pal_levels_composite = {
240	.blank = 237, .black = 237, .burst = 118,
241};
242
243static const struct color_conversion pal_csc_svideo = {
244	.ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0145,
245	.ru = 0x0780, .gu = 0x0579, .bu = 0x031c, .au = 0x0200,
246	.rv = 0x0390, .gv = 0x034f, .bv = 0x0705, .av = 0x0200,
247};
248
249static const struct video_levels pal_levels_svideo = {
250	.blank = 280, .black = 280, .burst = 139,
251};
252
253static const struct color_conversion pal_m_csc_composite = {
254	.ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0104,
255	.ru = 0x0733, .gu = 0x052d, .bu = 0x05c7, .au = 0x0200,
256	.rv = 0x0340, .gv = 0x030c, .bv = 0x06d0, .av = 0x0200,
257};
258
259static const struct video_levels pal_m_levels_composite = {
260	.blank = 225, .black = 267, .burst = 113,
261};
262
263static const struct color_conversion pal_m_csc_svideo = {
264	.ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0133,
265	.ru = 0x076a, .gu = 0x0564, .bu = 0x030d, .au = 0x0200,
266	.rv = 0x037a, .gv = 0x033d, .bv = 0x06f6, .av = 0x0200,
267};
268
269static const struct video_levels pal_m_levels_svideo = {
270	.blank = 266, .black = 316, .burst = 133,
271};
272
273static const struct color_conversion pal_n_csc_composite = {
274	.ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0104,
275	.ru = 0x0733, .gu = 0x052d, .bu = 0x05c7, .au = 0x0200,
276	.rv = 0x0340, .gv = 0x030c, .bv = 0x06d0, .av = 0x0200,
277};
278
279static const struct video_levels pal_n_levels_composite = {
280	.blank = 225, .black = 267, .burst = 118,
281};
282
283static const struct color_conversion pal_n_csc_svideo = {
284	.ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0133,
285	.ru = 0x076a, .gu = 0x0564, .bu = 0x030d, .au = 0x0200,
286	.rv = 0x037a, .gv = 0x033d, .bv = 0x06f6, .av = 0x0200,
287};
288
289static const struct video_levels pal_n_levels_svideo = {
290	.blank = 266, .black = 316, .burst = 139,
291};
292
293/*
294 * Component connections
295 */
296static const struct color_conversion sdtv_csc_yprpb = {
297	.ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0145,
298	.ru = 0x0559, .gu = 0x0353, .bu = 0x0100, .au = 0x0200,
299	.rv = 0x0100, .gv = 0x03ad, .bv = 0x074d, .av = 0x0200,
300};
301
302static const struct color_conversion hdtv_csc_yprpb = {
303	.ry = 0x05b3, .gy = 0x016e, .by = 0x0728, .ay = 0x0145,
304	.ru = 0x07d5, .gu = 0x038b, .bu = 0x0100, .au = 0x0200,
305	.rv = 0x0100, .gv = 0x03d1, .bv = 0x06bc, .av = 0x0200,
306};
307
308static const struct video_levels component_levels = {
309	.blank = 279, .black = 279, .burst = 0,
310};
311
312
313struct tv_mode {
314	const char *name;
315
316	u32 clock;
317	u16 refresh; /* in millihertz (for precision) */
318	u8 oversample;
319	u8 hsync_end;
320	u16 hblank_start, hblank_end, htotal;
321	bool progressive : 1, trilevel_sync : 1, component_only : 1;
322	u8 vsync_start_f1, vsync_start_f2, vsync_len;
323	bool veq_ena : 1;
324	u8 veq_start_f1, veq_start_f2, veq_len;
325	u8 vi_end_f1, vi_end_f2;
326	u16 nbr_end;
327	bool burst_ena : 1;
328	u8 hburst_start, hburst_len;
329	u8 vburst_start_f1;
330	u16 vburst_end_f1;
331	u8 vburst_start_f2;
332	u16 vburst_end_f2;
333	u8 vburst_start_f3;
334	u16 vburst_end_f3;
335	u8 vburst_start_f4;
336	u16 vburst_end_f4;
337	/*
338	 * subcarrier programming
339	 */
340	u16 dda2_size, dda3_size;
341	u8 dda1_inc;
342	u16 dda2_inc, dda3_inc;
343	u32 sc_reset;
344	bool pal_burst : 1;
345	/*
346	 * blank/black levels
347	 */
348	const struct video_levels *composite_levels, *svideo_levels;
349	const struct color_conversion *composite_color, *svideo_color;
350	const u32 *filter_table;
351};
352
353
354/*
355 * Sub carrier DDA
356 *
357 *  I think this works as follows:
358 *
359 *  subcarrier freq = pixel_clock * (dda1_inc + dda2_inc / dda2_size) / 4096
360 *
361 * Presumably, when dda3 is added in, it gets to adjust the dda2_inc value
362 *
363 * So,
364 *  dda1_ideal = subcarrier/pixel * 4096
365 *  dda1_inc = floor (dda1_ideal)
366 *  dda2 = dda1_ideal - dda1_inc
367 *
368 *  then pick a ratio for dda2 that gives the closest approximation. If
369 *  you can't get close enough, you can play with dda3 as well. This
370 *  seems likely to happen when dda2 is small as the jumps would be larger
371 *
372 * To invert this,
373 *
374 *  pixel_clock = subcarrier * 4096 / (dda1_inc + dda2_inc / dda2_size)
375 *
376 * The constants below were all computed using a 107.520MHz clock
377 */
378
379/*
380 * Register programming values for TV modes.
381 *
382 * These values account for -1s required.
383 */
384static const struct tv_mode tv_modes[] = {
385	{
386		.name		= "NTSC-M",
387		.clock		= 108000,
388		.refresh	= 59940,
389		.oversample	= 8,
390		.component_only = false,
391		/* 525 Lines, 60 Fields, 15.734KHz line, Sub-Carrier 3.580MHz */
392
393		.hsync_end	= 64,		    .hblank_end		= 124,
394		.hblank_start	= 836,		    .htotal		= 857,
395
396		.progressive	= false,	    .trilevel_sync = false,
397
398		.vsync_start_f1	= 6,		    .vsync_start_f2	= 7,
399		.vsync_len	= 6,
400
401		.veq_ena	= true,		    .veq_start_f1	= 0,
402		.veq_start_f2	= 1,		    .veq_len		= 18,
403
404		.vi_end_f1	= 20,		    .vi_end_f2		= 21,
405		.nbr_end	= 240,
406
407		.burst_ena	= true,
408		.hburst_start	= 72,		    .hburst_len		= 34,
409		.vburst_start_f1 = 9,		    .vburst_end_f1	= 240,
410		.vburst_start_f2 = 10,		    .vburst_end_f2	= 240,
411		.vburst_start_f3 = 9,		    .vburst_end_f3	= 240,
412		.vburst_start_f4 = 10,		    .vburst_end_f4	= 240,
413
414		/* desired 3.5800000 actual 3.5800000 clock 107.52 */
415		.dda1_inc	=    135,
416		.dda2_inc	=  20800,	    .dda2_size		=  27456,
417		.dda3_inc	=      0,	    .dda3_size		=      0,
418		.sc_reset	= TV_SC_RESET_EVERY_4,
419		.pal_burst	= false,
420
421		.composite_levels = &ntsc_m_levels_composite,
422		.composite_color = &ntsc_m_csc_composite,
423		.svideo_levels  = &ntsc_m_levels_svideo,
424		.svideo_color = &ntsc_m_csc_svideo,
425
426		.filter_table = filter_table,
427	},
428	{
429		.name		= "NTSC-443",
430		.clock		= 108000,
431		.refresh	= 59940,
432		.oversample	= 8,
433		.component_only = false,
434		/* 525 Lines, 60 Fields, 15.734KHz line, Sub-Carrier 4.43MHz */
435		.hsync_end	= 64,		    .hblank_end		= 124,
436		.hblank_start	= 836,		    .htotal		= 857,
437
438		.progressive	= false,	    .trilevel_sync = false,
439
440		.vsync_start_f1 = 6,		    .vsync_start_f2	= 7,
441		.vsync_len	= 6,
442
443		.veq_ena	= true,		    .veq_start_f1	= 0,
444		.veq_start_f2	= 1,		    .veq_len		= 18,
445
446		.vi_end_f1	= 20,		    .vi_end_f2		= 21,
447		.nbr_end	= 240,
448
449		.burst_ena	= true,
450		.hburst_start	= 72,		    .hburst_len		= 34,
451		.vburst_start_f1 = 9,		    .vburst_end_f1	= 240,
452		.vburst_start_f2 = 10,		    .vburst_end_f2	= 240,
453		.vburst_start_f3 = 9,		    .vburst_end_f3	= 240,
454		.vburst_start_f4 = 10,		    .vburst_end_f4	= 240,
455
456		/* desired 4.4336180 actual 4.4336180 clock 107.52 */
457		.dda1_inc       =    168,
458		.dda2_inc       =   4093,       .dda2_size      =  27456,
459		.dda3_inc       =    310,       .dda3_size      =    525,
460		.sc_reset   = TV_SC_RESET_NEVER,
461		.pal_burst  = false,
462
463		.composite_levels = &ntsc_m_levels_composite,
464		.composite_color = &ntsc_m_csc_composite,
465		.svideo_levels  = &ntsc_m_levels_svideo,
466		.svideo_color = &ntsc_m_csc_svideo,
467
468		.filter_table = filter_table,
469	},
470	{
471		.name		= "NTSC-J",
472		.clock		= 108000,
473		.refresh	= 59940,
474		.oversample	= 8,
475		.component_only = false,
476
477		/* 525 Lines, 60 Fields, 15.734KHz line, Sub-Carrier 3.580MHz */
478		.hsync_end	= 64,		    .hblank_end		= 124,
479		.hblank_start = 836,	    .htotal		= 857,
480
481		.progressive	= false,    .trilevel_sync = false,
482
483		.vsync_start_f1	= 6,	    .vsync_start_f2	= 7,
484		.vsync_len	= 6,
485
486		.veq_ena      = true,	    .veq_start_f1	= 0,
487		.veq_start_f2 = 1,	    .veq_len		= 18,
488
489		.vi_end_f1	= 20,		    .vi_end_f2		= 21,
490		.nbr_end	= 240,
491
492		.burst_ena	= true,
493		.hburst_start	= 72,		    .hburst_len		= 34,
494		.vburst_start_f1 = 9,		    .vburst_end_f1	= 240,
495		.vburst_start_f2 = 10,		    .vburst_end_f2	= 240,
496		.vburst_start_f3 = 9,		    .vburst_end_f3	= 240,
497		.vburst_start_f4 = 10,		    .vburst_end_f4	= 240,
498
499		/* desired 3.5800000 actual 3.5800000 clock 107.52 */
500		.dda1_inc	=    135,
501		.dda2_inc	=  20800,	    .dda2_size		=  27456,
502		.dda3_inc	=      0,	    .dda3_size		=      0,
503		.sc_reset	= TV_SC_RESET_EVERY_4,
504		.pal_burst	= false,
505
506		.composite_levels = &ntsc_j_levels_composite,
507		.composite_color = &ntsc_j_csc_composite,
508		.svideo_levels  = &ntsc_j_levels_svideo,
509		.svideo_color = &ntsc_j_csc_svideo,
510
511		.filter_table = filter_table,
512	},
513	{
514		.name		= "PAL-M",
515		.clock		= 108000,
516		.refresh	= 59940,
517		.oversample	= 8,
518		.component_only = false,
519
520		/* 525 Lines, 60 Fields, 15.734KHz line, Sub-Carrier 3.580MHz */
521		.hsync_end	= 64,		  .hblank_end		= 124,
522		.hblank_start = 836,	  .htotal		= 857,
523
524		.progressive	= false,	    .trilevel_sync = false,
525
526		.vsync_start_f1	= 6,		    .vsync_start_f2	= 7,
527		.vsync_len	= 6,
528
529		.veq_ena	= true,		    .veq_start_f1	= 0,
530		.veq_start_f2	= 1,		    .veq_len		= 18,
531
532		.vi_end_f1	= 20,		    .vi_end_f2		= 21,
533		.nbr_end	= 240,
534
535		.burst_ena	= true,
536		.hburst_start	= 72,		    .hburst_len		= 34,
537		.vburst_start_f1 = 9,		    .vburst_end_f1	= 240,
538		.vburst_start_f2 = 10,		    .vburst_end_f2	= 240,
539		.vburst_start_f3 = 9,		    .vburst_end_f3	= 240,
540		.vburst_start_f4 = 10,		    .vburst_end_f4	= 240,
541
542		/* desired 3.5800000 actual 3.5800000 clock 107.52 */
543		.dda1_inc	=    135,
544		.dda2_inc	=  16704,	    .dda2_size		=  27456,
545		.dda3_inc	=      0,	    .dda3_size		=      0,
546		.sc_reset	= TV_SC_RESET_EVERY_8,
547		.pal_burst  = true,
548
549		.composite_levels = &pal_m_levels_composite,
550		.composite_color = &pal_m_csc_composite,
551		.svideo_levels  = &pal_m_levels_svideo,
552		.svideo_color = &pal_m_csc_svideo,
553
554		.filter_table = filter_table,
555	},
556	{
557		/* 625 Lines, 50 Fields, 15.625KHz line, Sub-Carrier 4.434MHz */
558		.name	    = "PAL-N",
559		.clock		= 108000,
560		.refresh	= 50000,
561		.oversample	= 8,
562		.component_only = false,
563
564		.hsync_end	= 64,		    .hblank_end		= 128,
565		.hblank_start = 844,	    .htotal		= 863,
566
567		.progressive  = false,    .trilevel_sync = false,
568
569
570		.vsync_start_f1	= 6,	   .vsync_start_f2	= 7,
571		.vsync_len	= 6,
572
573		.veq_ena	= true,		    .veq_start_f1	= 0,
574		.veq_start_f2	= 1,		    .veq_len		= 18,
575
576		.vi_end_f1	= 24,		    .vi_end_f2		= 25,
577		.nbr_end	= 286,
578
579		.burst_ena	= true,
580		.hburst_start = 73,	    .hburst_len		= 34,
581		.vburst_start_f1 = 8,	    .vburst_end_f1	= 285,
582		.vburst_start_f2 = 8,	    .vburst_end_f2	= 286,
583		.vburst_start_f3 = 9,	    .vburst_end_f3	= 286,
584		.vburst_start_f4 = 9,	    .vburst_end_f4	= 285,
585
586
587		/* desired 4.4336180 actual 4.4336180 clock 107.52 */
588		.dda1_inc       =    135,
589		.dda2_inc       =  23578,       .dda2_size      =  27648,
590		.dda3_inc       =    134,       .dda3_size      =    625,
591		.sc_reset   = TV_SC_RESET_EVERY_8,
592		.pal_burst  = true,
593
594		.composite_levels = &pal_n_levels_composite,
595		.composite_color = &pal_n_csc_composite,
596		.svideo_levels  = &pal_n_levels_svideo,
597		.svideo_color = &pal_n_csc_svideo,
598
599		.filter_table = filter_table,
600	},
601	{
602		/* 625 Lines, 50 Fields, 15.625KHz line, Sub-Carrier 4.434MHz */
603		.name	    = "PAL",
604		.clock		= 108000,
605		.refresh	= 50000,
606		.oversample	= 8,
607		.component_only = false,
608
609		.hsync_end	= 64,		    .hblank_end		= 142,
610		.hblank_start	= 844,	    .htotal		= 863,
611
612		.progressive	= false,    .trilevel_sync = false,
613
614		.vsync_start_f1	= 5,	    .vsync_start_f2	= 6,
615		.vsync_len	= 5,
616
617		.veq_ena	= true,	    .veq_start_f1	= 0,
618		.veq_start_f2	= 1,	    .veq_len		= 15,
619
620		.vi_end_f1	= 24,		    .vi_end_f2		= 25,
621		.nbr_end	= 286,
622
623		.burst_ena	= true,
624		.hburst_start	= 73,		    .hburst_len		= 32,
625		.vburst_start_f1 = 8,		    .vburst_end_f1	= 285,
626		.vburst_start_f2 = 8,		    .vburst_end_f2	= 286,
627		.vburst_start_f3 = 9,		    .vburst_end_f3	= 286,
628		.vburst_start_f4 = 9,		    .vburst_end_f4	= 285,
629
630		/* desired 4.4336180 actual 4.4336180 clock 107.52 */
631		.dda1_inc       =    168,
632		.dda2_inc       =   4122,       .dda2_size      =  27648,
633		.dda3_inc       =     67,       .dda3_size      =    625,
634		.sc_reset   = TV_SC_RESET_EVERY_8,
635		.pal_burst  = true,
636
637		.composite_levels = &pal_levels_composite,
638		.composite_color = &pal_csc_composite,
639		.svideo_levels  = &pal_levels_svideo,
640		.svideo_color = &pal_csc_svideo,
641
642		.filter_table = filter_table,
643	},
644	{
645		.name       = "480p",
646		.clock		= 108000,
647		.refresh	= 59940,
648		.oversample     = 4,
649		.component_only = true,
650
651		.hsync_end      = 64,               .hblank_end         = 122,
652		.hblank_start   = 842,              .htotal             = 857,
653
654		.progressive    = true,		    .trilevel_sync = false,
655
656		.vsync_start_f1 = 12,               .vsync_start_f2     = 12,
657		.vsync_len      = 12,
658
659		.veq_ena        = false,
660
661		.vi_end_f1      = 44,               .vi_end_f2          = 44,
662		.nbr_end        = 479,
663
664		.burst_ena      = false,
665
666		.filter_table = filter_table,
667	},
668	{
669		.name       = "576p",
670		.clock		= 108000,
671		.refresh	= 50000,
672		.oversample     = 4,
673		.component_only = true,
674
675		.hsync_end      = 64,               .hblank_end         = 139,
676		.hblank_start   = 859,              .htotal             = 863,
677
678		.progressive    = true,		    .trilevel_sync = false,
679
680		.vsync_start_f1 = 10,               .vsync_start_f2     = 10,
681		.vsync_len      = 10,
682
683		.veq_ena        = false,
684
685		.vi_end_f1      = 48,               .vi_end_f2          = 48,
686		.nbr_end        = 575,
687
688		.burst_ena      = false,
689
690		.filter_table = filter_table,
691	},
692	{
693		.name       = "720p@60Hz",
694		.clock		= 148500,
695		.refresh	= 60000,
696		.oversample     = 2,
697		.component_only = true,
698
699		.hsync_end      = 80,               .hblank_end         = 300,
700		.hblank_start   = 1580,             .htotal             = 1649,
701
702		.progressive	= true,		    .trilevel_sync = true,
703
704		.vsync_start_f1 = 10,               .vsync_start_f2     = 10,
705		.vsync_len      = 10,
706
707		.veq_ena        = false,
708
709		.vi_end_f1      = 29,               .vi_end_f2          = 29,
710		.nbr_end        = 719,
711
712		.burst_ena      = false,
713
714		.filter_table = filter_table,
715	},
716	{
717		.name       = "720p@50Hz",
718		.clock		= 148500,
719		.refresh	= 50000,
720		.oversample     = 2,
721		.component_only = true,
722
723		.hsync_end      = 80,               .hblank_end         = 300,
724		.hblank_start   = 1580,             .htotal             = 1979,
725
726		.progressive	= true,		    .trilevel_sync = true,
727
728		.vsync_start_f1 = 10,               .vsync_start_f2     = 10,
729		.vsync_len      = 10,
730
731		.veq_ena        = false,
732
733		.vi_end_f1      = 29,               .vi_end_f2          = 29,
734		.nbr_end        = 719,
735
736		.burst_ena      = false,
737
738		.filter_table = filter_table,
739	},
740	{
741		.name       = "1080i@50Hz",
742		.clock		= 148500,
743		.refresh	= 50000,
744		.oversample     = 2,
745		.component_only = true,
746
747		.hsync_end      = 88,               .hblank_end         = 235,
748		.hblank_start   = 2155,             .htotal             = 2639,
749
750		.progressive	= false,	  .trilevel_sync = true,
751
752		.vsync_start_f1 = 4,              .vsync_start_f2     = 5,
753		.vsync_len      = 10,
754
755		.veq_ena	= true,	    .veq_start_f1	= 4,
756		.veq_start_f2   = 4,	    .veq_len		= 10,
757
758
759		.vi_end_f1      = 21,           .vi_end_f2          = 22,
760		.nbr_end        = 539,
761
762		.burst_ena      = false,
763
764		.filter_table = filter_table,
765	},
766	{
767		.name       = "1080i@60Hz",
768		.clock		= 148500,
769		.refresh	= 60000,
770		.oversample     = 2,
771		.component_only = true,
772
773		.hsync_end      = 88,               .hblank_end         = 235,
774		.hblank_start   = 2155,             .htotal             = 2199,
775
776		.progressive	= false,	    .trilevel_sync = true,
777
778		.vsync_start_f1 = 4,               .vsync_start_f2     = 5,
779		.vsync_len      = 10,
780
781		.veq_ena	= true,		    .veq_start_f1	= 4,
782		.veq_start_f2	= 4,		    .veq_len		= 10,
783
784
785		.vi_end_f1      = 21,               .vi_end_f2          = 22,
786		.nbr_end        = 539,
787
788		.burst_ena      = false,
789
790		.filter_table = filter_table,
791	},
792
793	{
794		.name       = "1080p@30Hz",
795		.clock		= 148500,
796		.refresh	= 30000,
797		.oversample     = 2,
798		.component_only = true,
799
800		.hsync_end      = 88,               .hblank_end         = 235,
801		.hblank_start   = 2155,             .htotal             = 2199,
802
803		.progressive	= true,		    .trilevel_sync = true,
804
805		.vsync_start_f1 = 8,               .vsync_start_f2     = 8,
806		.vsync_len      = 10,
807
808		.veq_ena	= false,	.veq_start_f1	= 0,
809		.veq_start_f2	= 0,		    .veq_len		= 0,
810
811		.vi_end_f1      = 44,               .vi_end_f2          = 44,
812		.nbr_end        = 1079,
813
814		.burst_ena      = false,
815
816		.filter_table = filter_table,
817	},
818
819	{
820		.name       = "1080p@50Hz",
821		.clock		= 148500,
822		.refresh	= 50000,
823		.oversample     = 1,
824		.component_only = true,
825
826		.hsync_end      = 88,               .hblank_end         = 235,
827		.hblank_start   = 2155,             .htotal             = 2639,
828
829		.progressive	= true,		    .trilevel_sync = true,
830
831		.vsync_start_f1 = 8,               .vsync_start_f2     = 8,
832		.vsync_len      = 10,
833
834		.veq_ena	= false,	.veq_start_f1	= 0,
835		.veq_start_f2	= 0,		    .veq_len		= 0,
836
837		.vi_end_f1      = 44,               .vi_end_f2          = 44,
838		.nbr_end        = 1079,
839
840		.burst_ena      = false,
841
842		.filter_table = filter_table,
843	},
844
845	{
846		.name       = "1080p@60Hz",
847		.clock		= 148500,
848		.refresh	= 60000,
849		.oversample     = 1,
850		.component_only = true,
851
852		.hsync_end      = 88,               .hblank_end         = 235,
853		.hblank_start   = 2155,             .htotal             = 2199,
854
855		.progressive	= true,		    .trilevel_sync = true,
856
857		.vsync_start_f1 = 8,               .vsync_start_f2     = 8,
858		.vsync_len      = 10,
859
860		.veq_ena	= false,		    .veq_start_f1	= 0,
861		.veq_start_f2	= 0,		    .veq_len		= 0,
862
863		.vi_end_f1      = 44,               .vi_end_f2          = 44,
864		.nbr_end        = 1079,
865
866		.burst_ena      = false,
867
868		.filter_table = filter_table,
869	},
870};
871
872struct intel_tv_connector_state {
873	struct drm_connector_state base;
874
875	/*
876	 * May need to override the user margins for
877	 * gen3 >1024 wide source vertical centering.
878	 */
879	struct {
880		u16 top, bottom;
881	} margins;
882
883	bool bypass_vfilter;
884};
885
886#define to_intel_tv_connector_state(x) container_of(x, struct intel_tv_connector_state, base)
887
888static struct drm_connector_state *
889intel_tv_connector_duplicate_state(struct drm_connector *connector)
890{
891	struct intel_tv_connector_state *state;
892
893	state = kmemdup(connector->state, sizeof(*state), GFP_KERNEL);
894	if (!state)
895		return NULL;
896
897	__drm_atomic_helper_connector_duplicate_state(connector, &state->base);
898	return &state->base;
899}
900
901static struct intel_tv *enc_to_tv(struct intel_encoder *encoder)
902{
903	return container_of(encoder, struct intel_tv, base);
904}
905
906static struct intel_tv *intel_attached_tv(struct intel_connector *connector)
907{
908	return enc_to_tv(intel_attached_encoder(connector));
909}
910
911static bool
912intel_tv_get_hw_state(struct intel_encoder *encoder, enum pipe *pipe)
913{
914	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
915	u32 tmp = I915_READ(TV_CTL);
916
917	*pipe = (tmp & TV_ENC_PIPE_SEL_MASK) >> TV_ENC_PIPE_SEL_SHIFT;
918
919	return tmp & TV_ENC_ENABLE;
920}
921
922static void
923intel_enable_tv(struct intel_encoder *encoder,
924		const struct intel_crtc_state *pipe_config,
925		const struct drm_connector_state *conn_state)
926{
927	struct drm_device *dev = encoder->base.dev;
928	struct drm_i915_private *dev_priv = to_i915(dev);
929
930	/* Prevents vblank waits from timing out in intel_tv_detect_type() */
931	intel_wait_for_vblank(dev_priv,
932			      to_intel_crtc(pipe_config->uapi.crtc)->pipe);
933
934	I915_WRITE(TV_CTL, I915_READ(TV_CTL) | TV_ENC_ENABLE);
935}
936
937static void
938intel_disable_tv(struct intel_encoder *encoder,
939		 const struct intel_crtc_state *old_crtc_state,
940		 const struct drm_connector_state *old_conn_state)
941{
942	struct drm_device *dev = encoder->base.dev;
943	struct drm_i915_private *dev_priv = to_i915(dev);
944
945	I915_WRITE(TV_CTL, I915_READ(TV_CTL) & ~TV_ENC_ENABLE);
946}
947
948static const struct tv_mode *intel_tv_mode_find(const struct drm_connector_state *conn_state)
949{
950	int format = conn_state->tv.mode;
951
952	return &tv_modes[format];
953}
954
955static enum drm_mode_status
956intel_tv_mode_valid(struct drm_connector *connector,
957		    struct drm_display_mode *mode)
958{
959	const struct tv_mode *tv_mode = intel_tv_mode_find(connector->state);
960	int max_dotclk = to_i915(connector->dev)->max_dotclk_freq;
961
962	if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
963		return MODE_NO_DBLESCAN;
964
965	if (mode->clock > max_dotclk)
966		return MODE_CLOCK_HIGH;
967
968	/* Ensure TV refresh is close to desired refresh */
969	if (abs(tv_mode->refresh - drm_mode_vrefresh(mode) * 1000) >= 1000)
970		return MODE_CLOCK_RANGE;
971
972	return MODE_OK;
973}
974
975static int
976intel_tv_mode_vdisplay(const struct tv_mode *tv_mode)
977{
978	if (tv_mode->progressive)
979		return tv_mode->nbr_end + 1;
980	else
981		return 2 * (tv_mode->nbr_end + 1);
982}
983
984static void
985intel_tv_mode_to_mode(struct drm_display_mode *mode,
986		      const struct tv_mode *tv_mode)
987{
988	mode->clock = tv_mode->clock /
989		(tv_mode->oversample >> !tv_mode->progressive);
990
991	/*
992	 * tv_mode horizontal timings:
993	 *
994	 * hsync_end
995	 *    | hblank_end
996	 *    |    | hblank_start
997	 *    |    |       | htotal
998	 *    |     _______    |
999	 *     ____/       \___
1000	 * \__/                \
1001	 */
1002	mode->hdisplay =
1003		tv_mode->hblank_start - tv_mode->hblank_end;
1004	mode->hsync_start = mode->hdisplay +
1005		tv_mode->htotal - tv_mode->hblank_start;
1006	mode->hsync_end = mode->hsync_start +
1007		tv_mode->hsync_end;
1008	mode->htotal = tv_mode->htotal + 1;
1009
1010	/*
1011	 * tv_mode vertical timings:
1012	 *
1013	 * vsync_start
1014	 *    | vsync_end
1015	 *    |  | vi_end nbr_end
1016	 *    |  |    |       |
1017	 *    |  |     _______
1018	 * \__    ____/       \
1019	 *    \__/
1020	 */
1021	mode->vdisplay = intel_tv_mode_vdisplay(tv_mode);
1022	if (tv_mode->progressive) {
1023		mode->vsync_start = mode->vdisplay +
1024			tv_mode->vsync_start_f1 + 1;
1025		mode->vsync_end = mode->vsync_start +
1026			tv_mode->vsync_len;
1027		mode->vtotal = mode->vdisplay +
1028			tv_mode->vi_end_f1 + 1;
1029	} else {
1030		mode->vsync_start = mode->vdisplay +
1031			tv_mode->vsync_start_f1 + 1 +
1032			tv_mode->vsync_start_f2 + 1;
1033		mode->vsync_end = mode->vsync_start +
1034			2 * tv_mode->vsync_len;
1035		mode->vtotal = mode->vdisplay +
1036			tv_mode->vi_end_f1 + 1 +
1037			tv_mode->vi_end_f2 + 1;
1038	}
1039
1040	/* TV has it's own notion of sync and other mode flags, so clear them. */
1041	mode->flags = 0;
1042
1043	mode->vrefresh = 0;
1044	mode->vrefresh = drm_mode_vrefresh(mode);
1045
1046	snprintf(mode->name, sizeof(mode->name),
1047		 "%dx%d%c (%s)",
1048		 mode->hdisplay, mode->vdisplay,
1049		 tv_mode->progressive ? 'p' : 'i',
1050		 tv_mode->name);
1051}
1052
1053static void intel_tv_scale_mode_horiz(struct drm_display_mode *mode,
1054				      int hdisplay, int left_margin,
1055				      int right_margin)
1056{
1057	int hsync_start = mode->hsync_start - mode->hdisplay + right_margin;
1058	int hsync_end = mode->hsync_end - mode->hdisplay + right_margin;
1059	int new_htotal = mode->htotal * hdisplay /
1060		(mode->hdisplay - left_margin - right_margin);
1061
1062	mode->clock = mode->clock * new_htotal / mode->htotal;
1063
1064	mode->hdisplay = hdisplay;
1065	mode->hsync_start = hdisplay + hsync_start * new_htotal / mode->htotal;
1066	mode->hsync_end = hdisplay + hsync_end * new_htotal / mode->htotal;
1067	mode->htotal = new_htotal;
1068}
1069
1070static void intel_tv_scale_mode_vert(struct drm_display_mode *mode,
1071				     int vdisplay, int top_margin,
1072				     int bottom_margin)
1073{
1074	int vsync_start = mode->vsync_start - mode->vdisplay + bottom_margin;
1075	int vsync_end = mode->vsync_end - mode->vdisplay + bottom_margin;
1076	int new_vtotal = mode->vtotal * vdisplay /
1077		(mode->vdisplay - top_margin - bottom_margin);
1078
1079	mode->clock = mode->clock * new_vtotal / mode->vtotal;
1080
1081	mode->vdisplay = vdisplay;
1082	mode->vsync_start = vdisplay + vsync_start * new_vtotal / mode->vtotal;
1083	mode->vsync_end = vdisplay + vsync_end * new_vtotal / mode->vtotal;
1084	mode->vtotal = new_vtotal;
1085}
1086
1087static void
1088intel_tv_get_config(struct intel_encoder *encoder,
1089		    struct intel_crtc_state *pipe_config)
1090{
1091	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
1092	struct drm_display_mode *adjusted_mode =
1093		&pipe_config->hw.adjusted_mode;
1094	struct drm_display_mode mode = {};
1095	u32 tv_ctl, hctl1, hctl3, vctl1, vctl2, tmp;
1096	struct tv_mode tv_mode = {};
1097	int hdisplay = adjusted_mode->crtc_hdisplay;
1098	int vdisplay = adjusted_mode->crtc_vdisplay;
1099	int xsize, ysize, xpos, ypos;
1100
1101	pipe_config->output_types |= BIT(INTEL_OUTPUT_TVOUT);
1102
1103	tv_ctl = I915_READ(TV_CTL);
1104	hctl1 = I915_READ(TV_H_CTL_1);
1105	hctl3 = I915_READ(TV_H_CTL_3);
1106	vctl1 = I915_READ(TV_V_CTL_1);
1107	vctl2 = I915_READ(TV_V_CTL_2);
1108
1109	tv_mode.htotal = (hctl1 & TV_HTOTAL_MASK) >> TV_HTOTAL_SHIFT;
1110	tv_mode.hsync_end = (hctl1 & TV_HSYNC_END_MASK) >> TV_HSYNC_END_SHIFT;
1111
1112	tv_mode.hblank_start = (hctl3 & TV_HBLANK_START_MASK) >> TV_HBLANK_START_SHIFT;
1113	tv_mode.hblank_end = (hctl3 & TV_HSYNC_END_MASK) >> TV_HBLANK_END_SHIFT;
1114
1115	tv_mode.nbr_end = (vctl1 & TV_NBR_END_MASK) >> TV_NBR_END_SHIFT;
1116	tv_mode.vi_end_f1 = (vctl1 & TV_VI_END_F1_MASK) >> TV_VI_END_F1_SHIFT;
1117	tv_mode.vi_end_f2 = (vctl1 & TV_VI_END_F2_MASK) >> TV_VI_END_F2_SHIFT;
1118
1119	tv_mode.vsync_len = (vctl2 & TV_VSYNC_LEN_MASK) >> TV_VSYNC_LEN_SHIFT;
1120	tv_mode.vsync_start_f1 = (vctl2 & TV_VSYNC_START_F1_MASK) >> TV_VSYNC_START_F1_SHIFT;
1121	tv_mode.vsync_start_f2 = (vctl2 & TV_VSYNC_START_F2_MASK) >> TV_VSYNC_START_F2_SHIFT;
1122
1123	tv_mode.clock = pipe_config->port_clock;
1124
1125	tv_mode.progressive = tv_ctl & TV_PROGRESSIVE;
1126
1127	switch (tv_ctl & TV_OVERSAMPLE_MASK) {
1128	case TV_OVERSAMPLE_8X:
1129		tv_mode.oversample = 8;
1130		break;
1131	case TV_OVERSAMPLE_4X:
1132		tv_mode.oversample = 4;
1133		break;
1134	case TV_OVERSAMPLE_2X:
1135		tv_mode.oversample = 2;
1136		break;
1137	default:
1138		tv_mode.oversample = 1;
1139		break;
1140	}
1141
1142	tmp = I915_READ(TV_WIN_POS);
1143	xpos = tmp >> 16;
1144	ypos = tmp & 0xffff;
1145
1146	tmp = I915_READ(TV_WIN_SIZE);
1147	xsize = tmp >> 16;
1148	ysize = tmp & 0xffff;
1149
1150	intel_tv_mode_to_mode(&mode, &tv_mode);
1151
1152	DRM_DEBUG_KMS("TV mode:\n");
1153	drm_mode_debug_printmodeline(&mode);
1154
1155	intel_tv_scale_mode_horiz(&mode, hdisplay,
1156				  xpos, mode.hdisplay - xsize - xpos);
1157	intel_tv_scale_mode_vert(&mode, vdisplay,
1158				 ypos, mode.vdisplay - ysize - ypos);
1159
1160	adjusted_mode->crtc_clock = mode.clock;
1161	if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE)
1162		adjusted_mode->crtc_clock /= 2;
1163
1164	/* pixel counter doesn't work on i965gm TV output */
1165	if (IS_I965GM(dev_priv))
1166		adjusted_mode->private_flags |=
1167			I915_MODE_FLAG_USE_SCANLINE_COUNTER;
1168}
1169
1170static bool intel_tv_source_too_wide(struct drm_i915_private *dev_priv,
1171				     int hdisplay)
1172{
1173	return IS_GEN(dev_priv, 3) && hdisplay > 1024;
1174}
1175
1176static bool intel_tv_vert_scaling(const struct drm_display_mode *tv_mode,
1177				  const struct drm_connector_state *conn_state,
1178				  int vdisplay)
1179{
1180	return tv_mode->crtc_vdisplay -
1181		conn_state->tv.margins.top -
1182		conn_state->tv.margins.bottom !=
1183		vdisplay;
1184}
1185
1186static int
1187intel_tv_compute_config(struct intel_encoder *encoder,
1188			struct intel_crtc_state *pipe_config,
1189			struct drm_connector_state *conn_state)
1190{
1191	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
1192	struct intel_tv_connector_state *tv_conn_state =
1193		to_intel_tv_connector_state(conn_state);
1194	const struct tv_mode *tv_mode = intel_tv_mode_find(conn_state);
1195	struct drm_display_mode *adjusted_mode =
1196		&pipe_config->hw.adjusted_mode;
1197	int hdisplay = adjusted_mode->crtc_hdisplay;
1198	int vdisplay = adjusted_mode->crtc_vdisplay;
1199
1200	if (!tv_mode)
1201		return -EINVAL;
1202
1203	if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN)
1204		return -EINVAL;
1205
1206	pipe_config->output_format = INTEL_OUTPUT_FORMAT_RGB;
1207
1208	DRM_DEBUG_KMS("forcing bpc to 8 for TV\n");
1209	pipe_config->pipe_bpp = 8*3;
1210
1211	pipe_config->port_clock = tv_mode->clock;
1212
1213	intel_tv_mode_to_mode(adjusted_mode, tv_mode);
1214	drm_mode_set_crtcinfo(adjusted_mode, 0);
1215
1216	if (intel_tv_source_too_wide(dev_priv, hdisplay) ||
1217	    !intel_tv_vert_scaling(adjusted_mode, conn_state, vdisplay)) {
1218		int extra, top, bottom;
1219
1220		extra = adjusted_mode->crtc_vdisplay - vdisplay;
1221
1222		if (extra < 0) {
1223			DRM_DEBUG_KMS("No vertical scaling for >1024 pixel wide modes\n");
1224			return -EINVAL;
1225		}
1226
1227		/* Need to turn off the vertical filter and center the image */
1228
1229		/* Attempt to maintain the relative sizes of the margins */
1230		top = conn_state->tv.margins.top;
1231		bottom = conn_state->tv.margins.bottom;
1232
1233		if (top + bottom)
1234			top = extra * top / (top + bottom);
1235		else
1236			top = extra / 2;
1237		bottom = extra - top;
1238
1239		tv_conn_state->margins.top = top;
1240		tv_conn_state->margins.bottom = bottom;
1241
1242		tv_conn_state->bypass_vfilter = true;
1243
1244		if (!tv_mode->progressive) {
1245			adjusted_mode->clock /= 2;
1246			adjusted_mode->crtc_clock /= 2;
1247			adjusted_mode->flags |= DRM_MODE_FLAG_INTERLACE;
1248		}
1249	} else {
1250		tv_conn_state->margins.top = conn_state->tv.margins.top;
1251		tv_conn_state->margins.bottom = conn_state->tv.margins.bottom;
1252
1253		tv_conn_state->bypass_vfilter = false;
1254	}
1255
1256	DRM_DEBUG_KMS("TV mode:\n");
1257	drm_mode_debug_printmodeline(adjusted_mode);
1258
1259	/*
1260	 * The pipe scanline counter behaviour looks as follows when
1261	 * using the TV encoder:
1262	 *
1263	 * time ->
1264	 *
1265	 * dsl=vtotal-1       |             |
1266	 *                   ||            ||
1267	 *               ___| |        ___| |
1268	 *              /     |       /     |
1269	 *             /      |      /      |
1270	 * dsl=0   ___/       |_____/       |
1271	 *        | | |  |  | |
1272	 *         ^ ^ ^   ^ ^
1273	 *         | | |   | pipe vblank/first part of tv vblank
1274	 *         | | |   bottom margin
1275	 *         | | active
1276	 *         | top margin
1277	 *         remainder of tv vblank
1278	 *
1279	 * When the TV encoder is used the pipe wants to run faster
1280	 * than expected rate. During the active portion the TV
1281	 * encoder stalls the pipe every few lines to keep it in
1282	 * check. When the TV encoder reaches the bottom margin the
1283	 * pipe simply stops. Once we reach the TV vblank the pipe is
1284	 * no longer stalled and it runs at the max rate (apparently
1285	 * oversample clock on gen3, cdclk on gen4). Once the pipe
1286	 * reaches the pipe vtotal the pipe stops for the remainder
1287	 * of the TV vblank/top margin. The pipe starts up again when
1288	 * the TV encoder exits the top margin.
1289	 *
1290	 * To avoid huge hassles for vblank timestamping we scale
1291	 * the pipe timings as if the pipe always runs at the average
1292	 * rate it maintains during the active period. This also
1293	 * gives us a reasonable guesstimate as to the pixel rate.
1294	 * Due to the variation in the actual pipe speed the scanline
1295	 * counter will give us slightly erroneous results during the
1296	 * TV vblank/margins. But since vtotal was selected such that
1297	 * it matches the average rate of the pipe during the active
1298	 * portion the error shouldn't cause any serious grief to
1299	 * vblank timestamps.
1300	 *
1301	 * For posterity here is the empirically derived formula
1302	 * that gives us the maximum length of the pipe vblank
1303	 * we can use without causing display corruption. Following
1304	 * this would allow us to have a ticking scanline counter
1305	 * everywhere except during the bottom margin (there the
1306	 * pipe always stops). Ie. this would eliminate the second
1307	 * flat portion of the above graph. However this would also
1308	 * complicate vblank timestamping as the pipe vtotal would
1309	 * no longer match the average rate the pipe runs at during
1310	 * the active portion. Hence following this formula seems
1311	 * more trouble that it's worth.
1312	 *
1313	 * if (IS_GEN(dev_priv, 4)) {
1314	 *	num = cdclk * (tv_mode->oversample >> !tv_mode->progressive);
1315	 *	den = tv_mode->clock;
1316	 * } else {
1317	 *	num = tv_mode->oversample >> !tv_mode->progressive;
1318	 *	den = 1;
1319	 * }
1320	 * max_pipe_vblank_len ~=
1321	 *	(num * tv_htotal * (tv_vblank_len + top_margin)) /
1322	 *	(den * pipe_htotal);
1323	 */
1324	intel_tv_scale_mode_horiz(adjusted_mode, hdisplay,
1325				  conn_state->tv.margins.left,
1326				  conn_state->tv.margins.right);
1327	intel_tv_scale_mode_vert(adjusted_mode, vdisplay,
1328				 tv_conn_state->margins.top,
1329				 tv_conn_state->margins.bottom);
1330	drm_mode_set_crtcinfo(adjusted_mode, 0);
1331	adjusted_mode->name[0] = '\0';
1332
1333	/* pixel counter doesn't work on i965gm TV output */
1334	if (IS_I965GM(dev_priv))
1335		adjusted_mode->private_flags |=
1336			I915_MODE_FLAG_USE_SCANLINE_COUNTER;
1337
1338	return 0;
1339}
1340
1341static void
1342set_tv_mode_timings(struct drm_i915_private *dev_priv,
1343		    const struct tv_mode *tv_mode,
1344		    bool burst_ena)
1345{
1346	u32 hctl1, hctl2, hctl3;
1347	u32 vctl1, vctl2, vctl3, vctl4, vctl5, vctl6, vctl7;
1348
1349	hctl1 = (tv_mode->hsync_end << TV_HSYNC_END_SHIFT) |
1350		(tv_mode->htotal << TV_HTOTAL_SHIFT);
1351
1352	hctl2 = (tv_mode->hburst_start << 16) |
1353		(tv_mode->hburst_len << TV_HBURST_LEN_SHIFT);
1354
1355	if (burst_ena)
1356		hctl2 |= TV_BURST_ENA;
1357
1358	hctl3 = (tv_mode->hblank_start << TV_HBLANK_START_SHIFT) |
1359		(tv_mode->hblank_end << TV_HBLANK_END_SHIFT);
1360
1361	vctl1 = (tv_mode->nbr_end << TV_NBR_END_SHIFT) |
1362		(tv_mode->vi_end_f1 << TV_VI_END_F1_SHIFT) |
1363		(tv_mode->vi_end_f2 << TV_VI_END_F2_SHIFT);
1364
1365	vctl2 = (tv_mode->vsync_len << TV_VSYNC_LEN_SHIFT) |
1366		(tv_mode->vsync_start_f1 << TV_VSYNC_START_F1_SHIFT) |
1367		(tv_mode->vsync_start_f2 << TV_VSYNC_START_F2_SHIFT);
1368
1369	vctl3 = (tv_mode->veq_len << TV_VEQ_LEN_SHIFT) |
1370		(tv_mode->veq_start_f1 << TV_VEQ_START_F1_SHIFT) |
1371		(tv_mode->veq_start_f2 << TV_VEQ_START_F2_SHIFT);
1372
1373	if (tv_mode->veq_ena)
1374		vctl3 |= TV_EQUAL_ENA;
1375
1376	vctl4 = (tv_mode->vburst_start_f1 << TV_VBURST_START_F1_SHIFT) |
1377		(tv_mode->vburst_end_f1 << TV_VBURST_END_F1_SHIFT);
1378
1379	vctl5 = (tv_mode->vburst_start_f2 << TV_VBURST_START_F2_SHIFT) |
1380		(tv_mode->vburst_end_f2 << TV_VBURST_END_F2_SHIFT);
1381
1382	vctl6 = (tv_mode->vburst_start_f3 << TV_VBURST_START_F3_SHIFT) |
1383		(tv_mode->vburst_end_f3 << TV_VBURST_END_F3_SHIFT);
1384
1385	vctl7 = (tv_mode->vburst_start_f4 << TV_VBURST_START_F4_SHIFT) |
1386		(tv_mode->vburst_end_f4 << TV_VBURST_END_F4_SHIFT);
1387
1388	I915_WRITE(TV_H_CTL_1, hctl1);
1389	I915_WRITE(TV_H_CTL_2, hctl2);
1390	I915_WRITE(TV_H_CTL_3, hctl3);
1391	I915_WRITE(TV_V_CTL_1, vctl1);
1392	I915_WRITE(TV_V_CTL_2, vctl2);
1393	I915_WRITE(TV_V_CTL_3, vctl3);
1394	I915_WRITE(TV_V_CTL_4, vctl4);
1395	I915_WRITE(TV_V_CTL_5, vctl5);
1396	I915_WRITE(TV_V_CTL_6, vctl6);
1397	I915_WRITE(TV_V_CTL_7, vctl7);
1398}
1399
1400static void set_color_conversion(struct drm_i915_private *dev_priv,
1401				 const struct color_conversion *color_conversion)
1402{
1403	if (!color_conversion)
1404		return;
1405
1406	I915_WRITE(TV_CSC_Y, (color_conversion->ry << 16) |
1407		   color_conversion->gy);
1408	I915_WRITE(TV_CSC_Y2, (color_conversion->by << 16) |
1409		   color_conversion->ay);
1410	I915_WRITE(TV_CSC_U, (color_conversion->ru << 16) |
1411		   color_conversion->gu);
1412	I915_WRITE(TV_CSC_U2, (color_conversion->bu << 16) |
1413		   color_conversion->au);
1414	I915_WRITE(TV_CSC_V, (color_conversion->rv << 16) |
1415		   color_conversion->gv);
1416	I915_WRITE(TV_CSC_V2, (color_conversion->bv << 16) |
1417		   color_conversion->av);
1418}
1419
1420static void intel_tv_pre_enable(struct intel_encoder *encoder,
1421				const struct intel_crtc_state *pipe_config,
1422				const struct drm_connector_state *conn_state)
1423{
1424	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
1425	struct intel_crtc *intel_crtc = to_intel_crtc(pipe_config->uapi.crtc);
1426	struct intel_tv *intel_tv = enc_to_tv(encoder);
1427	const struct intel_tv_connector_state *tv_conn_state =
1428		const_container_of(conn_state, struct intel_tv_connector_state, base);
1429	const struct tv_mode *tv_mode = intel_tv_mode_find(conn_state);
1430	u32 tv_ctl, tv_filter_ctl;
1431	u32 scctl1, scctl2, scctl3;
1432	int i, j;
1433	const struct video_levels *video_levels;
1434	const struct color_conversion *color_conversion;
1435	bool burst_ena;
1436	int xpos, ypos;
1437	unsigned int xsize, ysize;
1438
1439	if (!tv_mode)
1440		return;	/* can't happen (mode_prepare prevents this) */
1441
1442	tv_ctl = I915_READ(TV_CTL);
1443	tv_ctl &= TV_CTL_SAVE;
1444
1445	switch (intel_tv->type) {
1446	default:
1447	case DRM_MODE_CONNECTOR_Unknown:
1448	case DRM_MODE_CONNECTOR_Composite:
1449		tv_ctl |= TV_ENC_OUTPUT_COMPOSITE;
1450		video_levels = tv_mode->composite_levels;
1451		color_conversion = tv_mode->composite_color;
1452		burst_ena = tv_mode->burst_ena;
1453		break;
1454	case DRM_MODE_CONNECTOR_Component:
1455		tv_ctl |= TV_ENC_OUTPUT_COMPONENT;
1456		video_levels = &component_levels;
1457		if (tv_mode->burst_ena)
1458			color_conversion = &sdtv_csc_yprpb;
1459		else
1460			color_conversion = &hdtv_csc_yprpb;
1461		burst_ena = false;
1462		break;
1463	case DRM_MODE_CONNECTOR_SVIDEO:
1464		tv_ctl |= TV_ENC_OUTPUT_SVIDEO;
1465		video_levels = tv_mode->svideo_levels;
1466		color_conversion = tv_mode->svideo_color;
1467		burst_ena = tv_mode->burst_ena;
1468		break;
1469	}
1470
1471	tv_ctl |= TV_ENC_PIPE_SEL(intel_crtc->pipe);
1472
1473	switch (tv_mode->oversample) {
1474	case 8:
1475		tv_ctl |= TV_OVERSAMPLE_8X;
1476		break;
1477	case 4:
1478		tv_ctl |= TV_OVERSAMPLE_4X;
1479		break;
1480	case 2:
1481		tv_ctl |= TV_OVERSAMPLE_2X;
1482		break;
1483	default:
1484		tv_ctl |= TV_OVERSAMPLE_NONE;
1485		break;
1486	}
1487
1488	if (tv_mode->progressive)
1489		tv_ctl |= TV_PROGRESSIVE;
1490	if (tv_mode->trilevel_sync)
1491		tv_ctl |= TV_TRILEVEL_SYNC;
1492	if (tv_mode->pal_burst)
1493		tv_ctl |= TV_PAL_BURST;
1494
1495	scctl1 = 0;
1496	if (tv_mode->dda1_inc)
1497		scctl1 |= TV_SC_DDA1_EN;
1498	if (tv_mode->dda2_inc)
1499		scctl1 |= TV_SC_DDA2_EN;
1500	if (tv_mode->dda3_inc)
1501		scctl1 |= TV_SC_DDA3_EN;
1502	scctl1 |= tv_mode->sc_reset;
1503	if (video_levels)
1504		scctl1 |= video_levels->burst << TV_BURST_LEVEL_SHIFT;
1505	scctl1 |= tv_mode->dda1_inc << TV_SCDDA1_INC_SHIFT;
1506
1507	scctl2 = tv_mode->dda2_size << TV_SCDDA2_SIZE_SHIFT |
1508		tv_mode->dda2_inc << TV_SCDDA2_INC_SHIFT;
1509
1510	scctl3 = tv_mode->dda3_size << TV_SCDDA3_SIZE_SHIFT |
1511		tv_mode->dda3_inc << TV_SCDDA3_INC_SHIFT;
1512
1513	/* Enable two fixes for the chips that need them. */
1514	if (IS_I915GM(dev_priv))
1515		tv_ctl |= TV_ENC_C0_FIX | TV_ENC_SDP_FIX;
1516
1517	set_tv_mode_timings(dev_priv, tv_mode, burst_ena);
1518
1519	I915_WRITE(TV_SC_CTL_1, scctl1);
1520	I915_WRITE(TV_SC_CTL_2, scctl2);
1521	I915_WRITE(TV_SC_CTL_3, scctl3);
1522
1523	set_color_conversion(dev_priv, color_conversion);
1524
1525	if (INTEL_GEN(dev_priv) >= 4)
1526		I915_WRITE(TV_CLR_KNOBS, 0x00404000);
1527	else
1528		I915_WRITE(TV_CLR_KNOBS, 0x00606000);
1529
1530	if (video_levels)
1531		I915_WRITE(TV_CLR_LEVEL,
1532			   ((video_levels->black << TV_BLACK_LEVEL_SHIFT) |
1533			    (video_levels->blank << TV_BLANK_LEVEL_SHIFT)));
1534
1535	assert_pipe_disabled(dev_priv, pipe_config->cpu_transcoder);
1536
1537	/* Filter ctl must be set before TV_WIN_SIZE */
1538	tv_filter_ctl = TV_AUTO_SCALE;
1539	if (tv_conn_state->bypass_vfilter)
1540		tv_filter_ctl |= TV_V_FILTER_BYPASS;
1541	I915_WRITE(TV_FILTER_CTL_1, tv_filter_ctl);
1542
1543	xsize = tv_mode->hblank_start - tv_mode->hblank_end;
1544	ysize = intel_tv_mode_vdisplay(tv_mode);
1545
1546	xpos = conn_state->tv.margins.left;
1547	ypos = tv_conn_state->margins.top;
1548	xsize -= (conn_state->tv.margins.left +
1549		  conn_state->tv.margins.right);
1550	ysize -= (tv_conn_state->margins.top +
1551		  tv_conn_state->margins.bottom);
1552	I915_WRITE(TV_WIN_POS, (xpos<<16)|ypos);
1553	I915_WRITE(TV_WIN_SIZE, (xsize<<16)|ysize);
1554
1555	j = 0;
1556	for (i = 0; i < 60; i++)
1557		I915_WRITE(TV_H_LUMA(i), tv_mode->filter_table[j++]);
1558	for (i = 0; i < 60; i++)
1559		I915_WRITE(TV_H_CHROMA(i), tv_mode->filter_table[j++]);
1560	for (i = 0; i < 43; i++)
1561		I915_WRITE(TV_V_LUMA(i), tv_mode->filter_table[j++]);
1562	for (i = 0; i < 43; i++)
1563		I915_WRITE(TV_V_CHROMA(i), tv_mode->filter_table[j++]);
1564	I915_WRITE(TV_DAC, I915_READ(TV_DAC) & TV_DAC_SAVE);
1565	I915_WRITE(TV_CTL, tv_ctl);
1566}
1567
1568static int
1569intel_tv_detect_type(struct intel_tv *intel_tv,
1570		      struct drm_connector *connector)
1571{
1572	struct drm_crtc *crtc = connector->state->crtc;
1573	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
1574	struct drm_device *dev = connector->dev;
1575	struct drm_i915_private *dev_priv = to_i915(dev);
1576	u32 tv_ctl, save_tv_ctl;
1577	u32 tv_dac, save_tv_dac;
1578	int type;
1579
1580	/* Disable TV interrupts around load detect or we'll recurse */
1581	if (connector->polled & DRM_CONNECTOR_POLL_HPD) {
1582		spin_lock_irq(&dev_priv->irq_lock);
1583		i915_disable_pipestat(dev_priv, 0,
1584				      PIPE_HOTPLUG_INTERRUPT_STATUS |
1585				      PIPE_HOTPLUG_TV_INTERRUPT_STATUS);
1586		spin_unlock_irq(&dev_priv->irq_lock);
1587	}
1588
1589	save_tv_dac = tv_dac = I915_READ(TV_DAC);
1590	save_tv_ctl = tv_ctl = I915_READ(TV_CTL);
1591
1592	/* Poll for TV detection */
1593	tv_ctl &= ~(TV_ENC_ENABLE | TV_ENC_PIPE_SEL_MASK | TV_TEST_MODE_MASK);
1594	tv_ctl |= TV_TEST_MODE_MONITOR_DETECT;
1595	tv_ctl |= TV_ENC_PIPE_SEL(intel_crtc->pipe);
1596
1597	tv_dac &= ~(TVDAC_SENSE_MASK | DAC_A_MASK | DAC_B_MASK | DAC_C_MASK);
1598	tv_dac |= (TVDAC_STATE_CHG_EN |
1599		   TVDAC_A_SENSE_CTL |
1600		   TVDAC_B_SENSE_CTL |
1601		   TVDAC_C_SENSE_CTL |
1602		   DAC_CTL_OVERRIDE |
1603		   DAC_A_0_7_V |
1604		   DAC_B_0_7_V |
1605		   DAC_C_0_7_V);
1606
1607
1608	/*
1609	 * The TV sense state should be cleared to zero on cantiga platform. Otherwise
1610	 * the TV is misdetected. This is hardware requirement.
1611	 */
1612	if (IS_GM45(dev_priv))
1613		tv_dac &= ~(TVDAC_STATE_CHG_EN | TVDAC_A_SENSE_CTL |
1614			    TVDAC_B_SENSE_CTL | TVDAC_C_SENSE_CTL);
1615
1616	I915_WRITE(TV_CTL, tv_ctl);
1617	I915_WRITE(TV_DAC, tv_dac);
1618	POSTING_READ(TV_DAC);
1619
1620	intel_wait_for_vblank(dev_priv, intel_crtc->pipe);
1621
1622	type = -1;
1623	tv_dac = I915_READ(TV_DAC);
1624	DRM_DEBUG_KMS("TV detected: %x, %x\n", tv_ctl, tv_dac);
1625	/*
1626	 *  A B C
1627	 *  0 1 1 Composite
1628	 *  1 0 X svideo
1629	 *  0 0 0 Component
1630	 */
1631	if ((tv_dac & TVDAC_SENSE_MASK) == (TVDAC_B_SENSE | TVDAC_C_SENSE)) {
1632		DRM_DEBUG_KMS("Detected Composite TV connection\n");
1633		type = DRM_MODE_CONNECTOR_Composite;
1634	} else if ((tv_dac & (TVDAC_A_SENSE|TVDAC_B_SENSE)) == TVDAC_A_SENSE) {
1635		DRM_DEBUG_KMS("Detected S-Video TV connection\n");
1636		type = DRM_MODE_CONNECTOR_SVIDEO;
1637	} else if ((tv_dac & TVDAC_SENSE_MASK) == 0) {
1638		DRM_DEBUG_KMS("Detected Component TV connection\n");
1639		type = DRM_MODE_CONNECTOR_Component;
1640	} else {
1641		DRM_DEBUG_KMS("Unrecognised TV connection\n");
1642		type = -1;
1643	}
1644
1645	I915_WRITE(TV_DAC, save_tv_dac & ~TVDAC_STATE_CHG_EN);
1646	I915_WRITE(TV_CTL, save_tv_ctl);
1647	POSTING_READ(TV_CTL);
1648
1649	/* For unknown reasons the hw barfs if we don't do this vblank wait. */
1650	intel_wait_for_vblank(dev_priv, intel_crtc->pipe);
1651
1652	/* Restore interrupt config */
1653	if (connector->polled & DRM_CONNECTOR_POLL_HPD) {
1654		spin_lock_irq(&dev_priv->irq_lock);
1655		i915_enable_pipestat(dev_priv, 0,
1656				     PIPE_HOTPLUG_INTERRUPT_STATUS |
1657				     PIPE_HOTPLUG_TV_INTERRUPT_STATUS);
1658		spin_unlock_irq(&dev_priv->irq_lock);
1659	}
1660
1661	return type;
1662}
1663
1664/*
1665 * Here we set accurate tv format according to connector type
1666 * i.e Component TV should not be assigned by NTSC or PAL
1667 */
1668static void intel_tv_find_better_format(struct drm_connector *connector)
1669{
1670	struct intel_tv *intel_tv = intel_attached_tv(to_intel_connector(connector));
1671	const struct tv_mode *tv_mode = intel_tv_mode_find(connector->state);
1672	int i;
1673
1674	/* Component supports everything so we can keep the current mode */
1675	if (intel_tv->type == DRM_MODE_CONNECTOR_Component)
1676		return;
1677
1678	/* If the current mode is fine don't change it */
1679	if (!tv_mode->component_only)
1680		return;
1681
1682	for (i = 0; i < ARRAY_SIZE(tv_modes); i++) {
1683		tv_mode = &tv_modes[i];
1684
1685		if (!tv_mode->component_only)
1686			break;
1687	}
1688
1689	connector->state->tv.mode = i;
1690}
1691
1692static int
1693intel_tv_detect(struct drm_connector *connector,
1694		struct drm_modeset_acquire_ctx *ctx,
1695		bool force)
1696{
1697	struct intel_tv *intel_tv = intel_attached_tv(to_intel_connector(connector));
1698	enum drm_connector_status status;
1699	int type;
1700
1701	DRM_DEBUG_KMS("[CONNECTOR:%d:%s] force=%d\n",
1702		      connector->base.id, connector->name,
1703		      force);
1704
1705	if (force) {
1706		struct intel_load_detect_pipe tmp;
1707		int ret;
1708
1709		ret = intel_get_load_detect_pipe(connector, &tmp, ctx);
1710		if (ret < 0)
1711			return ret;
1712
1713		if (ret > 0) {
1714			type = intel_tv_detect_type(intel_tv, connector);
1715			intel_release_load_detect_pipe(connector, &tmp, ctx);
1716			status = type < 0 ?
1717				connector_status_disconnected :
1718				connector_status_connected;
1719		} else
1720			status = connector_status_unknown;
1721
1722		if (status == connector_status_connected) {
1723			intel_tv->type = type;
1724			intel_tv_find_better_format(connector);
1725		}
1726
1727		return status;
1728	} else
1729		return connector->status;
1730}
1731
1732static const struct input_res {
1733	u16 w, h;
1734} input_res_table[] = {
1735	{ 640, 480 },
1736	{ 800, 600 },
1737	{ 1024, 768 },
1738	{ 1280, 1024 },
1739	{ 848, 480 },
1740	{ 1280, 720 },
1741	{ 1920, 1080 },
1742};
1743
1744/* Choose preferred mode according to line number of TV format */
1745static bool
1746intel_tv_is_preferred_mode(const struct drm_display_mode *mode,
1747			   const struct tv_mode *tv_mode)
1748{
1749	int vdisplay = intel_tv_mode_vdisplay(tv_mode);
1750
1751	/* prefer 480 line modes for all SD TV modes */
1752	if (vdisplay <= 576)
1753		vdisplay = 480;
1754
1755	return vdisplay == mode->vdisplay;
1756}
1757
1758static void
1759intel_tv_set_mode_type(struct drm_display_mode *mode,
1760		       const struct tv_mode *tv_mode)
1761{
1762	mode->type = DRM_MODE_TYPE_DRIVER;
1763
1764	if (intel_tv_is_preferred_mode(mode, tv_mode))
1765		mode->type |= DRM_MODE_TYPE_PREFERRED;
1766}
1767
1768static int
1769intel_tv_get_modes(struct drm_connector *connector)
1770{
1771	struct drm_i915_private *dev_priv = to_i915(connector->dev);
1772	const struct tv_mode *tv_mode = intel_tv_mode_find(connector->state);
1773	int i, count = 0;
1774
1775	for (i = 0; i < ARRAY_SIZE(input_res_table); i++) {
1776		const struct input_res *input = &input_res_table[i];
1777		struct drm_display_mode *mode;
1778
1779		if (input->w > 1024 &&
1780		    !tv_mode->progressive &&
1781		    !tv_mode->component_only)
1782			continue;
1783
1784		/* no vertical scaling with wide sources on gen3 */
1785		if (IS_GEN(dev_priv, 3) && input->w > 1024 &&
1786		    input->h > intel_tv_mode_vdisplay(tv_mode))
1787			continue;
1788
1789		mode = drm_mode_create(connector->dev);
1790		if (!mode)
1791			continue;
1792
1793		/*
1794		 * We take the TV mode and scale it to look
1795		 * like it had the expected h/vdisplay. This
1796		 * provides the most information to userspace
1797		 * about the actual timings of the mode. We
1798		 * do ignore the margins though.
1799		 */
1800		intel_tv_mode_to_mode(mode, tv_mode);
1801		if (count == 0) {
1802			DRM_DEBUG_KMS("TV mode:\n");
1803			drm_mode_debug_printmodeline(mode);
1804		}
1805		intel_tv_scale_mode_horiz(mode, input->w, 0, 0);
1806		intel_tv_scale_mode_vert(mode, input->h, 0, 0);
1807		intel_tv_set_mode_type(mode, tv_mode);
1808
1809		drm_mode_set_name(mode);
1810
1811		drm_mode_probed_add(connector, mode);
1812		count++;
1813	}
1814
1815	return count;
1816}
1817
1818static const struct drm_connector_funcs intel_tv_connector_funcs = {
1819	.late_register = intel_connector_register,
1820	.early_unregister = intel_connector_unregister,
1821	.destroy = intel_connector_destroy,
1822	.fill_modes = drm_helper_probe_single_connector_modes,
1823	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
1824	.atomic_duplicate_state = intel_tv_connector_duplicate_state,
1825};
1826
1827static int intel_tv_atomic_check(struct drm_connector *connector,
1828				 struct drm_atomic_state *state)
1829{
1830	struct drm_connector_state *new_state;
1831	struct drm_crtc_state *new_crtc_state;
1832	struct drm_connector_state *old_state;
1833
1834	new_state = drm_atomic_get_new_connector_state(state, connector);
1835	if (!new_state->crtc)
1836		return 0;
1837
1838	old_state = drm_atomic_get_old_connector_state(state, connector);
1839	new_crtc_state = drm_atomic_get_new_crtc_state(state, new_state->crtc);
1840
1841	if (old_state->tv.mode != new_state->tv.mode ||
1842	    old_state->tv.margins.left != new_state->tv.margins.left ||
1843	    old_state->tv.margins.right != new_state->tv.margins.right ||
1844	    old_state->tv.margins.top != new_state->tv.margins.top ||
1845	    old_state->tv.margins.bottom != new_state->tv.margins.bottom) {
1846		/* Force a modeset. */
1847
1848		new_crtc_state->connectors_changed = true;
1849	}
1850
1851	return 0;
1852}
1853
1854static const struct drm_connector_helper_funcs intel_tv_connector_helper_funcs = {
1855	.detect_ctx = intel_tv_detect,
1856	.mode_valid = intel_tv_mode_valid,
1857	.get_modes = intel_tv_get_modes,
1858	.atomic_check = intel_tv_atomic_check,
1859};
1860
1861static const struct drm_encoder_funcs intel_tv_enc_funcs = {
1862	.destroy = intel_encoder_destroy,
1863};
1864
1865void
1866intel_tv_init(struct drm_i915_private *dev_priv)
1867{
1868	struct drm_device *dev = &dev_priv->drm;
1869	struct drm_connector *connector;
1870	struct intel_tv *intel_tv;
1871	struct intel_encoder *intel_encoder;
1872	struct intel_connector *intel_connector;
1873	u32 tv_dac_on, tv_dac_off, save_tv_dac;
1874	const char *tv_format_names[ARRAY_SIZE(tv_modes)];
1875	int i, initial_mode = 0;
1876	struct drm_connector_state *state;
1877
1878	if ((I915_READ(TV_CTL) & TV_FUSE_STATE_MASK) == TV_FUSE_STATE_DISABLED)
1879		return;
1880
1881	if (!intel_bios_is_tv_present(dev_priv)) {
1882		DRM_DEBUG_KMS("Integrated TV is not present.\n");
1883		return;
1884	}
1885
1886	/*
1887	 * Sanity check the TV output by checking to see if the
1888	 * DAC register holds a value
1889	 */
1890	save_tv_dac = I915_READ(TV_DAC);
1891
1892	I915_WRITE(TV_DAC, save_tv_dac | TVDAC_STATE_CHG_EN);
1893	tv_dac_on = I915_READ(TV_DAC);
1894
1895	I915_WRITE(TV_DAC, save_tv_dac & ~TVDAC_STATE_CHG_EN);
1896	tv_dac_off = I915_READ(TV_DAC);
1897
1898	I915_WRITE(TV_DAC, save_tv_dac);
1899
1900	/*
1901	 * If the register does not hold the state change enable
1902	 * bit, (either as a 0 or a 1), assume it doesn't really
1903	 * exist
1904	 */
1905	if ((tv_dac_on & TVDAC_STATE_CHG_EN) == 0 ||
1906	    (tv_dac_off & TVDAC_STATE_CHG_EN) != 0)
1907		return;
1908
1909	intel_tv = kzalloc(sizeof(*intel_tv), GFP_KERNEL);
1910	if (!intel_tv) {
1911		return;
1912	}
1913
1914	intel_connector = intel_connector_alloc();
1915	if (!intel_connector) {
1916		kfree(intel_tv);
1917		return;
1918	}
1919
1920	intel_encoder = &intel_tv->base;
1921	connector = &intel_connector->base;
1922	state = connector->state;
1923
1924	/*
1925	 * The documentation, for the older chipsets at least, recommend
1926	 * using a polling method rather than hotplug detection for TVs.
1927	 * This is because in order to perform the hotplug detection, the PLLs
1928	 * for the TV must be kept alive increasing power drain and starving
1929	 * bandwidth from other encoders. Notably for instance, it causes
1930	 * pipe underruns on Crestline when this encoder is supposedly idle.
1931	 *
1932	 * More recent chipsets favour HDMI rather than integrated S-Video.
1933	 */
1934	intel_connector->polled = DRM_CONNECTOR_POLL_CONNECT;
1935
1936	drm_connector_init(dev, connector, &intel_tv_connector_funcs,
1937			   DRM_MODE_CONNECTOR_SVIDEO);
1938
1939	drm_encoder_init(dev, &intel_encoder->base, &intel_tv_enc_funcs,
1940			 DRM_MODE_ENCODER_TVDAC, "TV");
1941
1942	intel_encoder->compute_config = intel_tv_compute_config;
1943	intel_encoder->get_config = intel_tv_get_config;
1944	intel_encoder->pre_enable = intel_tv_pre_enable;
1945	intel_encoder->enable = intel_enable_tv;
1946	intel_encoder->disable = intel_disable_tv;
1947	intel_encoder->get_hw_state = intel_tv_get_hw_state;
1948	intel_connector->get_hw_state = intel_connector_get_hw_state;
1949
1950	intel_connector_attach_encoder(intel_connector, intel_encoder);
1951
1952	intel_encoder->type = INTEL_OUTPUT_TVOUT;
1953	intel_encoder->power_domain = POWER_DOMAIN_PORT_OTHER;
1954	intel_encoder->port = PORT_NONE;
1955	intel_encoder->pipe_mask = ~0;
1956	intel_encoder->cloneable = 0;
1957	intel_tv->type = DRM_MODE_CONNECTOR_Unknown;
1958
1959	/* BIOS margin values */
1960	state->tv.margins.left = 54;
1961	state->tv.margins.top = 36;
1962	state->tv.margins.right = 46;
1963	state->tv.margins.bottom = 37;
1964
1965	state->tv.mode = initial_mode;
1966
1967	drm_connector_helper_add(connector, &intel_tv_connector_helper_funcs);
1968	connector->interlace_allowed = false;
1969	connector->doublescan_allowed = false;
1970
1971	/* Create TV properties then attach current values */
1972	for (i = 0; i < ARRAY_SIZE(tv_modes); i++) {
1973		/* 1080p50/1080p60 not supported on gen3 */
1974		if (IS_GEN(dev_priv, 3) &&
1975		    tv_modes[i].oversample == 1)
1976			break;
1977
1978		tv_format_names[i] = tv_modes[i].name;
1979	}
1980	drm_mode_create_tv_properties(dev, i, tv_format_names);
1981
1982	drm_object_attach_property(&connector->base, dev->mode_config.tv_mode_property,
1983				   state->tv.mode);
1984	drm_object_attach_property(&connector->base,
1985				   dev->mode_config.tv_left_margin_property,
1986				   state->tv.margins.left);
1987	drm_object_attach_property(&connector->base,
1988				   dev->mode_config.tv_top_margin_property,
1989				   state->tv.margins.top);
1990	drm_object_attach_property(&connector->base,
1991				   dev->mode_config.tv_right_margin_property,
1992				   state->tv.margins.right);
1993	drm_object_attach_property(&connector->base,
1994				   dev->mode_config.tv_bottom_margin_property,
1995				   state->tv.margins.bottom);
1996}
1997