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