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