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