drm/i915: extract intel_ddi.h from intel_drv.h
[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;
addc80f0
VS
1153 if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE)
1154 adjusted_mode->crtc_clock /= 2;
8a920e24
VS
1155
1156 /* pixel counter doesn't work on i965gm TV output */
1157 if (IS_I965GM(dev_priv))
1158 adjusted_mode->private_flags |=
1159 I915_MODE_FLAG_USE_SCANLINE_COUNTER;
7a495cfd
DV
1160}
1161
68e94f62
VS
1162static bool intel_tv_source_too_wide(struct drm_i915_private *dev_priv,
1163 int hdisplay)
1164{
1165 return IS_GEN(dev_priv, 3) && hdisplay > 1024;
1166}
1167
1168static bool intel_tv_vert_scaling(const struct drm_display_mode *tv_mode,
1169 const struct drm_connector_state *conn_state,
1170 int vdisplay)
1171{
1172 return tv_mode->crtc_vdisplay -
1173 conn_state->tv.margins.top -
1174 conn_state->tv.margins.bottom !=
1175 vdisplay;
1176}
1177
204474a6 1178static int
5d2d38dd 1179intel_tv_compute_config(struct intel_encoder *encoder,
0a478c27
ML
1180 struct intel_crtc_state *pipe_config,
1181 struct drm_connector_state *conn_state)
79e53945 1182{
690157f0
VS
1183 struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
1184 struct intel_tv_connector_state *tv_conn_state =
1185 to_intel_tv_connector_state(conn_state);
0e891b3f 1186 const struct tv_mode *tv_mode = intel_tv_mode_find(conn_state);
e4dd27aa
VS
1187 struct drm_display_mode *adjusted_mode =
1188 &pipe_config->base.adjusted_mode;
e3bb355c
VS
1189 int hdisplay = adjusted_mode->crtc_hdisplay;
1190 int vdisplay = adjusted_mode->crtc_vdisplay;
79e53945
JB
1191
1192 if (!tv_mode)
204474a6 1193 return -EINVAL;
79e53945 1194
e4dd27aa 1195 if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN)
204474a6 1196 return -EINVAL;
e4dd27aa 1197
d9facae6 1198 pipe_config->output_format = INTEL_OUTPUT_FORMAT_RGB;
e3bb355c 1199
5d2d38dd
DV
1200 DRM_DEBUG_KMS("forcing bpc to 8 for TV\n");
1201 pipe_config->pipe_bpp = 8*3;
1202
e3bb355c
VS
1203 pipe_config->port_clock = tv_mode->clock;
1204
1205 intel_tv_mode_to_mode(adjusted_mode, tv_mode);
690157f0
VS
1206 drm_mode_set_crtcinfo(adjusted_mode, 0);
1207
68e94f62
VS
1208 if (intel_tv_source_too_wide(dev_priv, hdisplay) ||
1209 !intel_tv_vert_scaling(adjusted_mode, conn_state, vdisplay)) {
690157f0
VS
1210 int extra, top, bottom;
1211
1212 extra = adjusted_mode->crtc_vdisplay - vdisplay;
1213
1214 if (extra < 0) {
1215 DRM_DEBUG_KMS("No vertical scaling for >1024 pixel wide modes\n");
6a2a9404 1216 return -EINVAL;
690157f0
VS
1217 }
1218
1219 /* Need to turn off the vertical filter and center the image */
1220
1221 /* Attempt to maintain the relative sizes of the margins */
1222 top = conn_state->tv.margins.top;
1223 bottom = conn_state->tv.margins.bottom;
1224
1225 if (top + bottom)
1226 top = extra * top / (top + bottom);
1227 else
1228 top = extra / 2;
1229 bottom = extra - top;
1230
1231 tv_conn_state->margins.top = top;
1232 tv_conn_state->margins.bottom = bottom;
1233
1234 tv_conn_state->bypass_vfilter = true;
1235
addc80f0
VS
1236 if (!tv_mode->progressive) {
1237 adjusted_mode->clock /= 2;
1238 adjusted_mode->crtc_clock /= 2;
690157f0 1239 adjusted_mode->flags |= DRM_MODE_FLAG_INTERLACE;
addc80f0 1240 }
690157f0
VS
1241 } else {
1242 tv_conn_state->margins.top = conn_state->tv.margins.top;
1243 tv_conn_state->margins.bottom = conn_state->tv.margins.bottom;
1244
1245 tv_conn_state->bypass_vfilter = false;
1246 }
e3bb355c
VS
1247
1248 DRM_DEBUG_KMS("TV mode:\n");
1249 drm_mode_debug_printmodeline(adjusted_mode);
1062b815
DV
1250
1251 /*
e3bb355c
VS
1252 * The pipe scanline counter behaviour looks as follows when
1253 * using the TV encoder:
1254 *
1255 * time ->
1256 *
1257 * dsl=vtotal-1 | |
1258 * || ||
1259 * ___| | ___| |
1260 * / | / |
1261 * / | / |
1262 * dsl=0 ___/ |_____/ |
1263 * | | | | | |
1264 * ^ ^ ^ ^ ^
1265 * | | | | pipe vblank/first part of tv vblank
1266 * | | | bottom margin
1267 * | | active
1268 * | top margin
1269 * remainder of tv vblank
1270 *
1271 * When the TV encoder is used the pipe wants to run faster
1272 * than expected rate. During the active portion the TV
1273 * encoder stalls the pipe every few lines to keep it in
1274 * check. When the TV encoder reaches the bottom margin the
1275 * pipe simply stops. Once we reach the TV vblank the pipe is
1276 * no longer stalled and it runs at the max rate (apparently
1277 * oversample clock on gen3, cdclk on gen4). Once the pipe
1278 * reaches the pipe vtotal the pipe stops for the remainder
1279 * of the TV vblank/top margin. The pipe starts up again when
1280 * the TV encoder exits the top margin.
1281 *
1282 * To avoid huge hassles for vblank timestamping we scale
1283 * the pipe timings as if the pipe always runs at the average
1284 * rate it maintains during the active period. This also
1285 * gives us a reasonable guesstimate as to the pixel rate.
1286 * Due to the variation in the actual pipe speed the scanline
1287 * counter will give us slightly erroneous results during the
1288 * TV vblank/margins. But since vtotal was selected such that
1289 * it matches the average rate of the pipe during the active
1290 * portion the error shouldn't cause any serious grief to
1291 * vblank timestamps.
1292 *
1293 * For posterity here is the empirically derived formula
1294 * that gives us the maximum length of the pipe vblank
1295 * we can use without causing display corruption. Following
1296 * this would allow us to have a ticking scanline counter
1297 * everywhere except during the bottom margin (there the
1298 * pipe always stops). Ie. this would eliminate the second
1299 * flat portion of the above graph. However this would also
1300 * complicate vblank timestamping as the pipe vtotal would
1301 * no longer match the average rate the pipe runs at during
1302 * the active portion. Hence following this formula seems
1303 * more trouble that it's worth.
1304 *
1305 * if (IS_GEN(dev_priv, 4)) {
1306 * num = cdclk * (tv_mode->oversample >> !tv_mode->progressive);
1307 * den = tv_mode->clock;
1308 * } else {
1309 * num = tv_mode->oversample >> !tv_mode->progressive;
1310 * den = 1;
1311 * }
1312 * max_pipe_vblank_len ~=
1313 * (num * tv_htotal * (tv_vblank_len + top_margin)) /
1314 * (den * pipe_htotal);
1062b815 1315 */
e3bb355c
VS
1316 intel_tv_scale_mode_horiz(adjusted_mode, hdisplay,
1317 conn_state->tv.margins.left,
1318 conn_state->tv.margins.right);
1319 intel_tv_scale_mode_vert(adjusted_mode, vdisplay,
690157f0
VS
1320 tv_conn_state->margins.top,
1321 tv_conn_state->margins.bottom);
e3bb355c
VS
1322 drm_mode_set_crtcinfo(adjusted_mode, 0);
1323 adjusted_mode->name[0] = '\0';
1062b815 1324
8a920e24
VS
1325 /* pixel counter doesn't work on i965gm TV output */
1326 if (IS_I965GM(dev_priv))
1327 adjusted_mode->private_flags |=
1328 I915_MODE_FLAG_USE_SCANLINE_COUNTER;
1329
204474a6 1330 return 0;
79e53945
JB
1331}
1332
8cb92203
DV
1333static void
1334set_tv_mode_timings(struct drm_i915_private *dev_priv,
1335 const struct tv_mode *tv_mode,
1336 bool burst_ena)
1337{
1338 u32 hctl1, hctl2, hctl3;
1339 u32 vctl1, vctl2, vctl3, vctl4, vctl5, vctl6, vctl7;
1340
1341 hctl1 = (tv_mode->hsync_end << TV_HSYNC_END_SHIFT) |
1342 (tv_mode->htotal << TV_HTOTAL_SHIFT);
1343
1344 hctl2 = (tv_mode->hburst_start << 16) |
1345 (tv_mode->hburst_len << TV_HBURST_LEN_SHIFT);
1346
1347 if (burst_ena)
1348 hctl2 |= TV_BURST_ENA;
1349
1350 hctl3 = (tv_mode->hblank_start << TV_HBLANK_START_SHIFT) |
1351 (tv_mode->hblank_end << TV_HBLANK_END_SHIFT);
1352
1353 vctl1 = (tv_mode->nbr_end << TV_NBR_END_SHIFT) |
1354 (tv_mode->vi_end_f1 << TV_VI_END_F1_SHIFT) |
1355 (tv_mode->vi_end_f2 << TV_VI_END_F2_SHIFT);
1356
1357 vctl2 = (tv_mode->vsync_len << TV_VSYNC_LEN_SHIFT) |
1358 (tv_mode->vsync_start_f1 << TV_VSYNC_START_F1_SHIFT) |
1359 (tv_mode->vsync_start_f2 << TV_VSYNC_START_F2_SHIFT);
1360
1361 vctl3 = (tv_mode->veq_len << TV_VEQ_LEN_SHIFT) |
1362 (tv_mode->veq_start_f1 << TV_VEQ_START_F1_SHIFT) |
1363 (tv_mode->veq_start_f2 << TV_VEQ_START_F2_SHIFT);
1364
1365 if (tv_mode->veq_ena)
1366 vctl3 |= TV_EQUAL_ENA;
1367
1368 vctl4 = (tv_mode->vburst_start_f1 << TV_VBURST_START_F1_SHIFT) |
1369 (tv_mode->vburst_end_f1 << TV_VBURST_END_F1_SHIFT);
1370
1371 vctl5 = (tv_mode->vburst_start_f2 << TV_VBURST_START_F2_SHIFT) |
1372 (tv_mode->vburst_end_f2 << TV_VBURST_END_F2_SHIFT);
1373
1374 vctl6 = (tv_mode->vburst_start_f3 << TV_VBURST_START_F3_SHIFT) |
1375 (tv_mode->vburst_end_f3 << TV_VBURST_END_F3_SHIFT);
1376
1377 vctl7 = (tv_mode->vburst_start_f4 << TV_VBURST_START_F4_SHIFT) |
1378 (tv_mode->vburst_end_f4 << TV_VBURST_END_F4_SHIFT);
1379
1380 I915_WRITE(TV_H_CTL_1, hctl1);
1381 I915_WRITE(TV_H_CTL_2, hctl2);
1382 I915_WRITE(TV_H_CTL_3, hctl3);
1383 I915_WRITE(TV_V_CTL_1, vctl1);
1384 I915_WRITE(TV_V_CTL_2, vctl2);
1385 I915_WRITE(TV_V_CTL_3, vctl3);
1386 I915_WRITE(TV_V_CTL_4, vctl4);
1387 I915_WRITE(TV_V_CTL_5, vctl5);
1388 I915_WRITE(TV_V_CTL_6, vctl6);
1389 I915_WRITE(TV_V_CTL_7, vctl7);
1390}
1391
b8866ef8
DV
1392static void set_color_conversion(struct drm_i915_private *dev_priv,
1393 const struct color_conversion *color_conversion)
1394{
1395 if (!color_conversion)
1396 return;
1397
1398 I915_WRITE(TV_CSC_Y, (color_conversion->ry << 16) |
1399 color_conversion->gy);
1400 I915_WRITE(TV_CSC_Y2, (color_conversion->by << 16) |
1401 color_conversion->ay);
1402 I915_WRITE(TV_CSC_U, (color_conversion->ru << 16) |
1403 color_conversion->gu);
1404 I915_WRITE(TV_CSC_U2, (color_conversion->bu << 16) |
1405 color_conversion->au);
1406 I915_WRITE(TV_CSC_V, (color_conversion->rv << 16) |
1407 color_conversion->gv);
1408 I915_WRITE(TV_CSC_V2, (color_conversion->bv << 16) |
1409 color_conversion->av);
1410}
1411
fd6bbda9 1412static void intel_tv_pre_enable(struct intel_encoder *encoder,
5f88a9c6
VS
1413 const struct intel_crtc_state *pipe_config,
1414 const struct drm_connector_state *conn_state)
79e53945 1415{
66478475 1416 struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
a7f519ba 1417 struct intel_crtc *intel_crtc = to_intel_crtc(pipe_config->base.crtc);
cd91ef23 1418 struct intel_tv *intel_tv = enc_to_tv(encoder);
690157f0
VS
1419 const struct intel_tv_connector_state *tv_conn_state =
1420 to_intel_tv_connector_state(conn_state);
0e891b3f 1421 const struct tv_mode *tv_mode = intel_tv_mode_find(conn_state);
690157f0 1422 u32 tv_ctl, tv_filter_ctl;
79e53945
JB
1423 u32 scctl1, scctl2, scctl3;
1424 int i, j;
1425 const struct video_levels *video_levels;
1426 const struct color_conversion *color_conversion;
1427 bool burst_ena;
bda5f532 1428 int xpos, ypos;
3fa2dd14 1429 unsigned int xsize, ysize;
79e53945
JB
1430
1431 if (!tv_mode)
1432 return; /* can't happen (mode_prepare prevents this) */
1433
d2d9f232
ZW
1434 tv_ctl = I915_READ(TV_CTL);
1435 tv_ctl &= TV_CTL_SAVE;
79e53945 1436
ea5b213a 1437 switch (intel_tv->type) {
79e53945
JB
1438 default:
1439 case DRM_MODE_CONNECTOR_Unknown:
1440 case DRM_MODE_CONNECTOR_Composite:
1441 tv_ctl |= TV_ENC_OUTPUT_COMPOSITE;
1442 video_levels = tv_mode->composite_levels;
1443 color_conversion = tv_mode->composite_color;
1444 burst_ena = tv_mode->burst_ena;
1445 break;
1446 case DRM_MODE_CONNECTOR_Component:
1447 tv_ctl |= TV_ENC_OUTPUT_COMPONENT;
1448 video_levels = &component_levels;
1449 if (tv_mode->burst_ena)
1450 color_conversion = &sdtv_csc_yprpb;
1451 else
1452 color_conversion = &hdtv_csc_yprpb;
1453 burst_ena = false;
1454 break;
1455 case DRM_MODE_CONNECTOR_SVIDEO:
1456 tv_ctl |= TV_ENC_OUTPUT_SVIDEO;
1457 video_levels = tv_mode->svideo_levels;
1458 color_conversion = tv_mode->svideo_color;
1459 burst_ena = tv_mode->burst_ena;
1460 break;
1461 }
79e53945 1462
4add0f6b 1463 tv_ctl |= TV_ENC_PIPE_SEL(intel_crtc->pipe);
4f503798
VS
1464
1465 switch (tv_mode->oversample) {
1466 case 8:
1467 tv_ctl |= TV_OVERSAMPLE_8X;
1468 break;
1469 case 4:
1470 tv_ctl |= TV_OVERSAMPLE_4X;
1471 break;
1472 case 2:
1473 tv_ctl |= TV_OVERSAMPLE_2X;
1474 break;
1475 default:
1476 tv_ctl |= TV_OVERSAMPLE_NONE;
1477 break;
1478 }
79e53945
JB
1479
1480 if (tv_mode->progressive)
1481 tv_ctl |= TV_PROGRESSIVE;
1482 if (tv_mode->trilevel_sync)
1483 tv_ctl |= TV_TRILEVEL_SYNC;
1484 if (tv_mode->pal_burst)
1485 tv_ctl |= TV_PAL_BURST;
d271817b 1486
79e53945 1487 scctl1 = 0;
d271817b 1488 if (tv_mode->dda1_inc)
79e53945 1489 scctl1 |= TV_SC_DDA1_EN;
79e53945
JB
1490 if (tv_mode->dda2_inc)
1491 scctl1 |= TV_SC_DDA2_EN;
79e53945
JB
1492 if (tv_mode->dda3_inc)
1493 scctl1 |= TV_SC_DDA3_EN;
79e53945 1494 scctl1 |= tv_mode->sc_reset;
d271817b
CW
1495 if (video_levels)
1496 scctl1 |= video_levels->burst << TV_BURST_LEVEL_SHIFT;
79e53945
JB
1497 scctl1 |= tv_mode->dda1_inc << TV_SCDDA1_INC_SHIFT;
1498
1499 scctl2 = tv_mode->dda2_size << TV_SCDDA2_SIZE_SHIFT |
1500 tv_mode->dda2_inc << TV_SCDDA2_INC_SHIFT;
1501
1502 scctl3 = tv_mode->dda3_size << TV_SCDDA3_SIZE_SHIFT |
1503 tv_mode->dda3_inc << TV_SCDDA3_INC_SHIFT;
1504
1505 /* Enable two fixes for the chips that need them. */
50a0bc90 1506 if (IS_I915GM(dev_priv))
79e53945
JB
1507 tv_ctl |= TV_ENC_C0_FIX | TV_ENC_SDP_FIX;
1508
8cb92203
DV
1509 set_tv_mode_timings(dev_priv, tv_mode, burst_ena);
1510
79e53945
JB
1511 I915_WRITE(TV_SC_CTL_1, scctl1);
1512 I915_WRITE(TV_SC_CTL_2, scctl2);
1513 I915_WRITE(TV_SC_CTL_3, scctl3);
1514
b8866ef8 1515 set_color_conversion(dev_priv, color_conversion);
79e53945 1516
66478475 1517 if (INTEL_GEN(dev_priv) >= 4)
d2d9f232
ZW
1518 I915_WRITE(TV_CLR_KNOBS, 0x00404000);
1519 else
1520 I915_WRITE(TV_CLR_KNOBS, 0x00606000);
1521
79e53945
JB
1522 if (video_levels)
1523 I915_WRITE(TV_CLR_LEVEL,
1524 ((video_levels->black << TV_BLACK_LEVEL_SHIFT) |
1525 (video_levels->blank << TV_BLANK_LEVEL_SHIFT)));
3fa2dd14
DV
1526
1527 assert_pipe_disabled(dev_priv, intel_crtc->pipe);
1528
1529 /* Filter ctl must be set before TV_WIN_SIZE */
690157f0
VS
1530 tv_filter_ctl = TV_AUTO_SCALE;
1531 if (tv_conn_state->bypass_vfilter)
1532 tv_filter_ctl |= TV_V_FILTER_BYPASS;
1533 I915_WRITE(TV_FILTER_CTL_1, tv_filter_ctl);
1534
3fa2dd14 1535 xsize = tv_mode->hblank_start - tv_mode->hblank_end;
65ddf7f9 1536 ysize = intel_tv_mode_vdisplay(tv_mode);
3fa2dd14 1537
bda5f532 1538 xpos = conn_state->tv.margins.left;
690157f0 1539 ypos = tv_conn_state->margins.top;
0e891b3f
ML
1540 xsize -= (conn_state->tv.margins.left +
1541 conn_state->tv.margins.right);
690157f0
VS
1542 ysize -= (tv_conn_state->margins.top +
1543 tv_conn_state->margins.bottom);
3fa2dd14
DV
1544 I915_WRITE(TV_WIN_POS, (xpos<<16)|ypos);
1545 I915_WRITE(TV_WIN_SIZE, (xsize<<16)|ysize);
79e53945
JB
1546
1547 j = 0;
1548 for (i = 0; i < 60; i++)
184d7c06 1549 I915_WRITE(TV_H_LUMA(i), tv_mode->filter_table[j++]);
79e53945 1550 for (i = 0; i < 60; i++)
184d7c06 1551 I915_WRITE(TV_H_CHROMA(i), tv_mode->filter_table[j++]);
79e53945 1552 for (i = 0; i < 43; i++)
184d7c06 1553 I915_WRITE(TV_V_LUMA(i), tv_mode->filter_table[j++]);
79e53945 1554 for (i = 0; i < 43; i++)
184d7c06 1555 I915_WRITE(TV_V_CHROMA(i), tv_mode->filter_table[j++]);
b8ed2a4f 1556 I915_WRITE(TV_DAC, I915_READ(TV_DAC) & TV_DAC_SAVE);
79e53945
JB
1557 I915_WRITE(TV_CTL, tv_ctl);
1558}
1559
79e53945 1560static int
0206e353 1561intel_tv_detect_type(struct intel_tv *intel_tv,
8102e126 1562 struct drm_connector *connector)
79e53945 1563{
0eadc624 1564 struct drm_crtc *crtc = connector->state->crtc;
835bff7e 1565 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
0eadc624 1566 struct drm_device *dev = connector->dev;
fac5e23e 1567 struct drm_i915_private *dev_priv = to_i915(dev);
79e53945
JB
1568 u32 tv_ctl, save_tv_ctl;
1569 u32 tv_dac, save_tv_dac;
974b9331 1570 int type;
79e53945
JB
1571
1572 /* Disable TV interrupts around load detect or we'll recurse */
8102e126 1573 if (connector->polled & DRM_CONNECTOR_POLL_HPD) {
2795aa48 1574 spin_lock_irq(&dev_priv->irq_lock);
8102e126 1575 i915_disable_pipestat(dev_priv, 0,
755e9019
ID
1576 PIPE_HOTPLUG_INTERRUPT_STATUS |
1577 PIPE_HOTPLUG_TV_INTERRUPT_STATUS);
2795aa48 1578 spin_unlock_irq(&dev_priv->irq_lock);
8102e126 1579 }
79e53945 1580
974b9331
CW
1581 save_tv_dac = tv_dac = I915_READ(TV_DAC);
1582 save_tv_ctl = tv_ctl = I915_READ(TV_CTL);
1583
1584 /* Poll for TV detection */
4add0f6b 1585 tv_ctl &= ~(TV_ENC_ENABLE | TV_ENC_PIPE_SEL_MASK | TV_TEST_MODE_MASK);
8ed9a5bc 1586 tv_ctl |= TV_TEST_MODE_MONITOR_DETECT;
4add0f6b 1587 tv_ctl |= TV_ENC_PIPE_SEL(intel_crtc->pipe);
974b9331
CW
1588
1589 tv_dac &= ~(TVDAC_SENSE_MASK | DAC_A_MASK | DAC_B_MASK | DAC_C_MASK);
8ed9a5bc 1590 tv_dac |= (TVDAC_STATE_CHG_EN |
1591 TVDAC_A_SENSE_CTL |
1592 TVDAC_B_SENSE_CTL |
1593 TVDAC_C_SENSE_CTL |
1594 DAC_CTL_OVERRIDE |
1595 DAC_A_0_7_V |
1596 DAC_B_0_7_V |
1597 DAC_C_0_7_V);
974b9331 1598
d42c9e2c
DV
1599
1600 /*
1601 * The TV sense state should be cleared to zero on cantiga platform. Otherwise
1602 * the TV is misdetected. This is hardware requirement.
1603 */
50a0bc90 1604 if (IS_GM45(dev_priv))
d42c9e2c
DV
1605 tv_dac &= ~(TVDAC_STATE_CHG_EN | TVDAC_A_SENSE_CTL |
1606 TVDAC_B_SENSE_CTL | TVDAC_C_SENSE_CTL);
1607
8ed9a5bc 1608 I915_WRITE(TV_CTL, tv_ctl);
1609 I915_WRITE(TV_DAC, tv_dac);
4f233eff 1610 POSTING_READ(TV_DAC);
4f233eff 1611
0f0f74bc 1612 intel_wait_for_vblank(dev_priv, intel_crtc->pipe);
29e1316a 1613
974b9331 1614 type = -1;
2bf71160
KP
1615 tv_dac = I915_READ(TV_DAC);
1616 DRM_DEBUG_KMS("TV detected: %x, %x\n", tv_ctl, tv_dac);
1617 /*
1618 * A B C
1619 * 0 1 1 Composite
1620 * 1 0 X svideo
1621 * 0 0 0 Component
1622 */
1623 if ((tv_dac & TVDAC_SENSE_MASK) == (TVDAC_B_SENSE | TVDAC_C_SENSE)) {
1624 DRM_DEBUG_KMS("Detected Composite TV connection\n");
1625 type = DRM_MODE_CONNECTOR_Composite;
1626 } else if ((tv_dac & (TVDAC_A_SENSE|TVDAC_B_SENSE)) == TVDAC_A_SENSE) {
1627 DRM_DEBUG_KMS("Detected S-Video TV connection\n");
1628 type = DRM_MODE_CONNECTOR_SVIDEO;
1629 } else if ((tv_dac & TVDAC_SENSE_MASK) == 0) {
1630 DRM_DEBUG_KMS("Detected Component TV connection\n");
1631 type = DRM_MODE_CONNECTOR_Component;
1632 } else {
1633 DRM_DEBUG_KMS("Unrecognised TV connection\n");
1634 type = -1;
79e53945
JB
1635 }
1636
974b9331
CW
1637 I915_WRITE(TV_DAC, save_tv_dac & ~TVDAC_STATE_CHG_EN);
1638 I915_WRITE(TV_CTL, save_tv_ctl);
bf2125e2
DV
1639 POSTING_READ(TV_CTL);
1640
1641 /* For unknown reasons the hw barfs if we don't do this vblank wait. */
0f0f74bc 1642 intel_wait_for_vblank(dev_priv, intel_crtc->pipe);
974b9331 1643
79e53945 1644 /* Restore interrupt config */
8102e126 1645 if (connector->polled & DRM_CONNECTOR_POLL_HPD) {
2795aa48 1646 spin_lock_irq(&dev_priv->irq_lock);
8102e126 1647 i915_enable_pipestat(dev_priv, 0,
755e9019
ID
1648 PIPE_HOTPLUG_INTERRUPT_STATUS |
1649 PIPE_HOTPLUG_TV_INTERRUPT_STATUS);
2795aa48 1650 spin_unlock_irq(&dev_priv->irq_lock);
8102e126 1651 }
79e53945
JB
1652
1653 return type;
1654}
1655
213c2e64
ML
1656/*
1657 * Here we set accurate tv format according to connector type
1658 * i.e Component TV should not be assigned by NTSC or PAL
1659 */
1660static void intel_tv_find_better_format(struct drm_connector *connector)
1661{
df0e9248 1662 struct intel_tv *intel_tv = intel_attached_tv(connector);
0e891b3f 1663 const struct tv_mode *tv_mode = intel_tv_mode_find(connector->state);
213c2e64
ML
1664 int i;
1665
e94390aa
VS
1666 /* Component supports everything so we can keep the current mode */
1667 if (intel_tv->type == DRM_MODE_CONNECTOR_Component)
213c2e64
ML
1668 return;
1669
e94390aa
VS
1670 /* If the current mode is fine don't change it */
1671 if (!tv_mode->component_only)
1672 return;
213c2e64 1673
53abb679 1674 for (i = 0; i < ARRAY_SIZE(tv_modes); i++) {
e94390aa 1675 tv_mode = &tv_modes[i];
213c2e64 1676
e94390aa 1677 if (!tv_mode->component_only)
213c2e64
ML
1678 break;
1679 }
1680
0e891b3f 1681 connector->state->tv.mode = i;
213c2e64
ML
1682}
1683
6c5ed5ae
ML
1684static int
1685intel_tv_detect(struct drm_connector *connector,
1686 struct drm_modeset_acquire_ctx *ctx,
1687 bool force)
79e53945 1688{
df0e9248 1689 struct intel_tv *intel_tv = intel_attached_tv(connector);
bbfb44e8 1690 enum drm_connector_status status;
ea5b213a 1691 int type;
79e53945 1692
164c8598 1693 DRM_DEBUG_KMS("[CONNECTOR:%d:%s] force=%d\n",
c23cc417 1694 connector->base.id, connector->name,
164c8598
CW
1695 force);
1696
38de45c5 1697 if (force) {
8261b191 1698 struct intel_load_detect_pipe tmp;
6c5ed5ae 1699 int ret;
ea5b213a 1700
528132a3 1701 ret = intel_get_load_detect_pipe(connector, NULL, &tmp, ctx);
6c5ed5ae
ML
1702 if (ret < 0)
1703 return ret;
208bf9fd 1704
6c5ed5ae 1705 if (ret > 0) {
8102e126 1706 type = intel_tv_detect_type(intel_tv, connector);
6c5ed5ae 1707 intel_release_load_detect_pipe(connector, &tmp, ctx);
bbfb44e8
VS
1708 status = type < 0 ?
1709 connector_status_disconnected :
1710 connector_status_connected;
79e53945 1711 } else
bbfb44e8 1712 status = connector_status_unknown;
bf5a269a 1713
0e891b3f
ML
1714 if (status == connector_status_connected) {
1715 intel_tv->type = type;
1716 intel_tv_find_better_format(connector);
1717 }
d5627663 1718
0e891b3f
ML
1719 return status;
1720 } else
1721 return connector->status;
79e53945
JB
1722}
1723
763a4a01 1724static const struct input_res {
5023520f 1725 u16 w, h;
763a4a01 1726} input_res_table[] = {
5023520f
VS
1727 { 640, 480 },
1728 { 800, 600 },
1729 { 1024, 768 },
1730 { 1280, 1024 },
1731 { 848, 480 },
1732 { 1280, 720 },
1733 { 1920, 1080 },
79e53945
JB
1734};
1735
65ddf7f9
VS
1736/* Choose preferred mode according to line number of TV format */
1737static bool
1738intel_tv_is_preferred_mode(const struct drm_display_mode *mode,
1739 const struct tv_mode *tv_mode)
1740{
1741 int vdisplay = intel_tv_mode_vdisplay(tv_mode);
1742
1743 /* prefer 480 line modes for all SD TV modes */
1744 if (vdisplay <= 576)
1745 vdisplay = 480;
1746
1747 return vdisplay == mode->vdisplay;
1748}
1749
bcae2ca8 1750static void
65ddf7f9
VS
1751intel_tv_set_mode_type(struct drm_display_mode *mode,
1752 const struct tv_mode *tv_mode)
bcae2ca8 1753{
65ddf7f9
VS
1754 mode->type = DRM_MODE_TYPE_DRIVER;
1755
1756 if (intel_tv_is_preferred_mode(mode, tv_mode))
1757 mode->type |= DRM_MODE_TYPE_PREFERRED;
bcae2ca8 1758}
1759
79e53945
JB
1760static int
1761intel_tv_get_modes(struct drm_connector *connector)
1762{
0bb1ffe4 1763 struct drm_i915_private *dev_priv = to_i915(connector->dev);
0e891b3f 1764 const struct tv_mode *tv_mode = intel_tv_mode_find(connector->state);
e3bb355c 1765 int i, count = 0;
79e53945 1766
e3bb355c
VS
1767 for (i = 0; i < ARRAY_SIZE(input_res_table); i++) {
1768 const struct input_res *input = &input_res_table[i];
1769 struct drm_display_mode *mode;
79e53945 1770
e3bb355c
VS
1771 if (input->w > 1024 &&
1772 !tv_mode->progressive &&
1773 !tv_mode->component_only)
79e53945
JB
1774 continue;
1775
0bb1ffe4
VS
1776 /* no vertical scaling with wide sources on gen3 */
1777 if (IS_GEN(dev_priv, 3) && input->w > 1024 &&
1778 input->h > intel_tv_mode_vdisplay(tv_mode))
1779 continue;
1780
e3bb355c
VS
1781 mode = drm_mode_create(connector->dev);
1782 if (!mode)
02c5dd98 1783 continue;
79e53945 1784
e3bb355c
VS
1785 /*
1786 * We take the TV mode and scale it to look
1787 * like it had the expected h/vdisplay. This
1788 * provides the most information to userspace
1789 * about the actual timings of the mode. We
1790 * do ignore the margins though.
1791 */
1792 intel_tv_mode_to_mode(mode, tv_mode);
1793 if (count == 0) {
1794 DRM_DEBUG_KMS("TV mode:\n");
1795 drm_mode_debug_printmodeline(mode);
1796 }
1797 intel_tv_scale_mode_horiz(mode, input->w, 0, 0);
1798 intel_tv_scale_mode_vert(mode, input->h, 0, 0);
1799 intel_tv_set_mode_type(mode, tv_mode);
5023520f 1800
e3bb355c 1801 drm_mode_set_name(mode);
5023520f 1802
e3bb355c 1803 drm_mode_probed_add(connector, mode);
02c5dd98 1804 count++;
79e53945
JB
1805 }
1806
02c5dd98 1807 return count;
79e53945
JB
1808}
1809
79e53945 1810static const struct drm_connector_funcs intel_tv_connector_funcs = {
1ebaa0b9 1811 .late_register = intel_connector_register,
c191eca1 1812 .early_unregister = intel_connector_unregister,
d4b26e4f 1813 .destroy = intel_connector_destroy,
79e53945 1814 .fill_modes = drm_helper_probe_single_connector_modes,
c6f95f27 1815 .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
690157f0 1816 .atomic_duplicate_state = intel_tv_connector_duplicate_state,
79e53945
JB
1817};
1818
0e891b3f
ML
1819static int intel_tv_atomic_check(struct drm_connector *connector,
1820 struct drm_connector_state *new_state)
1821{
1822 struct drm_crtc_state *new_crtc_state;
1823 struct drm_connector_state *old_state;
1824
1825 if (!new_state->crtc)
1826 return 0;
1827
1828 old_state = drm_atomic_get_old_connector_state(new_state->state, connector);
1829 new_crtc_state = drm_atomic_get_new_crtc_state(new_state->state, new_state->crtc);
1830
1831 if (old_state->tv.mode != new_state->tv.mode ||
1832 old_state->tv.margins.left != new_state->tv.margins.left ||
1833 old_state->tv.margins.right != new_state->tv.margins.right ||
1834 old_state->tv.margins.top != new_state->tv.margins.top ||
1835 old_state->tv.margins.bottom != new_state->tv.margins.bottom) {
1836 /* Force a modeset. */
1837
1838 new_crtc_state->connectors_changed = true;
1839 }
1840
1841 return 0;
1842}
1843
79e53945 1844static const struct drm_connector_helper_funcs intel_tv_connector_helper_funcs = {
6c5ed5ae 1845 .detect_ctx = intel_tv_detect,
79e53945
JB
1846 .mode_valid = intel_tv_mode_valid,
1847 .get_modes = intel_tv_get_modes,
0e891b3f 1848 .atomic_check = intel_tv_atomic_check,
79e53945
JB
1849};
1850
79e53945 1851static const struct drm_encoder_funcs intel_tv_enc_funcs = {
ea5b213a 1852 .destroy = intel_encoder_destroy,
79e53945
JB
1853};
1854
79e53945 1855void
c39055b0 1856intel_tv_init(struct drm_i915_private *dev_priv)
79e53945 1857{
c39055b0 1858 struct drm_device *dev = &dev_priv->drm;
79e53945 1859 struct drm_connector *connector;
ea5b213a 1860 struct intel_tv *intel_tv;
21d40d37 1861 struct intel_encoder *intel_encoder;
0c41ee2b 1862 struct intel_connector *intel_connector;
79e53945 1863 u32 tv_dac_on, tv_dac_off, save_tv_dac;
b7c914b3 1864 const char *tv_format_names[ARRAY_SIZE(tv_modes)];
79e53945 1865 int i, initial_mode = 0;
0e891b3f 1866 struct drm_connector_state *state;
79e53945
JB
1867
1868 if ((I915_READ(TV_CTL) & TV_FUSE_STATE_MASK) == TV_FUSE_STATE_DISABLED)
1869 return;
1870
3bdd14d5 1871 if (!intel_bios_is_tv_present(dev_priv)) {
c3561438
ZY
1872 DRM_DEBUG_KMS("Integrated TV is not present.\n");
1873 return;
1874 }
79e53945
JB
1875
1876 /*
1877 * Sanity check the TV output by checking to see if the
1878 * DAC register holds a value
1879 */
1880 save_tv_dac = I915_READ(TV_DAC);
1881
1882 I915_WRITE(TV_DAC, save_tv_dac | TVDAC_STATE_CHG_EN);
1883 tv_dac_on = I915_READ(TV_DAC);
1884
1885 I915_WRITE(TV_DAC, save_tv_dac & ~TVDAC_STATE_CHG_EN);
1886 tv_dac_off = I915_READ(TV_DAC);
1887
1888 I915_WRITE(TV_DAC, save_tv_dac);
1889
1890 /*
1891 * If the register does not hold the state change enable
1892 * bit, (either as a 0 or a 1), assume it doesn't really
1893 * exist
1894 */
1895 if ((tv_dac_on & TVDAC_STATE_CHG_EN) == 0 ||
1896 (tv_dac_off & TVDAC_STATE_CHG_EN) != 0)
1897 return;
1898
b14c5679 1899 intel_tv = kzalloc(sizeof(*intel_tv), GFP_KERNEL);
ea5b213a 1900 if (!intel_tv) {
79e53945
JB
1901 return;
1902 }
f8aed700 1903
08d9bc92 1904 intel_connector = intel_connector_alloc();
0c41ee2b 1905 if (!intel_connector) {
ea5b213a 1906 kfree(intel_tv);
0c41ee2b
ZW
1907 return;
1908 }
1909
ea5b213a 1910 intel_encoder = &intel_tv->base;
0c41ee2b 1911 connector = &intel_connector->base;
0e891b3f 1912 state = connector->state;
79e53945 1913
3930f18a
CW
1914 /*
1915 * The documentation, for the older chipsets at least, recommend
8102e126
CW
1916 * using a polling method rather than hotplug detection for TVs.
1917 * This is because in order to perform the hotplug detection, the PLLs
1918 * for the TV must be kept alive increasing power drain and starving
1919 * bandwidth from other encoders. Notably for instance, it causes
1920 * pipe underruns on Crestline when this encoder is supposedly idle.
1921 *
1922 * More recent chipsets favour HDMI rather than integrated S-Video.
1923 */
821450c6 1924 intel_connector->polled = DRM_CONNECTOR_POLL_CONNECT;
8102e126 1925
79e53945
JB
1926 drm_connector_init(dev, connector, &intel_tv_connector_funcs,
1927 DRM_MODE_CONNECTOR_SVIDEO);
1928
4ef69c7a 1929 drm_encoder_init(dev, &intel_encoder->base, &intel_tv_enc_funcs,
580d8ed5 1930 DRM_MODE_ENCODER_TVDAC, "TV");
79e53945 1931
5d2d38dd 1932 intel_encoder->compute_config = intel_tv_compute_config;
7a495cfd 1933 intel_encoder->get_config = intel_tv_get_config;
809a2a8b 1934 intel_encoder->pre_enable = intel_tv_pre_enable;
6b5756a0
DV
1935 intel_encoder->enable = intel_enable_tv;
1936 intel_encoder->disable = intel_disable_tv;
9a8ee983
DV
1937 intel_encoder->get_hw_state = intel_tv_get_hw_state;
1938 intel_connector->get_hw_state = intel_connector_get_hw_state;
6b5756a0 1939
df0e9248 1940 intel_connector_attach_encoder(intel_connector, intel_encoder);
03cdc1d4 1941
21d40d37 1942 intel_encoder->type = INTEL_OUTPUT_TVOUT;
79f255a0 1943 intel_encoder->power_domain = POWER_DOMAIN_PORT_OTHER;
03cdc1d4 1944 intel_encoder->port = PORT_NONE;
21d40d37 1945 intel_encoder->crtc_mask = (1 << 0) | (1 << 1);
bc079e8b 1946 intel_encoder->cloneable = 0;
4ef69c7a 1947 intel_encoder->base.possible_crtcs = ((1 << 0) | (1 << 1));
ea5b213a 1948 intel_tv->type = DRM_MODE_CONNECTOR_Unknown;
79e53945
JB
1949
1950 /* BIOS margin values */
0e891b3f
ML
1951 state->tv.margins.left = 54;
1952 state->tv.margins.top = 36;
1953 state->tv.margins.right = 46;
1954 state->tv.margins.bottom = 37;
79e53945 1955
0e891b3f 1956 state->tv.mode = initial_mode;
79e53945 1957
79e53945
JB
1958 drm_connector_helper_add(connector, &intel_tv_connector_helper_funcs);
1959 connector->interlace_allowed = false;
1960 connector->doublescan_allowed = false;
1961
1962 /* Create TV properties then attach current values */
a0ff6779
VS
1963 for (i = 0; i < ARRAY_SIZE(tv_modes); i++) {
1964 /* 1080p50/1080p60 not supported on gen3 */
1965 if (IS_GEN(dev_priv, 3) &&
1966 tv_modes[i].oversample == 1)
1967 break;
1968
b7c914b3 1969 tv_format_names[i] = tv_modes[i].name;
a0ff6779
VS
1970 }
1971 drm_mode_create_tv_properties(dev, i, tv_format_names);
79e53945 1972
662595df 1973 drm_object_attach_property(&connector->base, dev->mode_config.tv_mode_property,
0e891b3f 1974 state->tv.mode);
662595df 1975 drm_object_attach_property(&connector->base,
79e53945 1976 dev->mode_config.tv_left_margin_property,
0e891b3f 1977 state->tv.margins.left);
662595df 1978 drm_object_attach_property(&connector->base,
79e53945 1979 dev->mode_config.tv_top_margin_property,
0e891b3f 1980 state->tv.margins.top);
662595df 1981 drm_object_attach_property(&connector->base,
79e53945 1982 dev->mode_config.tv_right_margin_property,
0e891b3f 1983 state->tv.margins.right);
662595df 1984 drm_object_attach_property(&connector->base,
79e53945 1985 dev->mode_config.tv_bottom_margin_property,
0e891b3f 1986 state->tv.margins.bottom);
79e53945 1987}