2 * Copyright © 2006-2008 Intel Corporation
3 * Jesse Barnes <jesse.barnes@intel.com>
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:
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
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.
25 * Eric Anholt <eric@anholt.net>
30 * Integrated TV-out support for the 915GM and 945GM.
33 #include <drm/drm_atomic_helper.h>
34 #include <drm/drm_crtc.h>
35 #include <drm/drm_edid.h>
38 #include "intel_connector.h"
39 #include "intel_display_types.h"
40 #include "intel_hotplug.h"
44 TV_MARGIN_LEFT, TV_MARGIN_TOP,
45 TV_MARGIN_RIGHT, TV_MARGIN_BOTTOM
49 struct intel_encoder base;
59 struct color_conversion {
65 static const u32 filter_table[] = {
66 0xB1403000, 0x2E203500, 0x35002E20, 0x3000B140,
67 0x35A0B160, 0x2DC02E80, 0xB1403480, 0xB1603000,
68 0x2EA03640, 0x34002D80, 0x3000B120, 0x36E0B160,
69 0x2D202EF0, 0xB1203380, 0xB1603000, 0x2F303780,
70 0x33002CC0, 0x3000B100, 0x3820B160, 0x2C802F50,
71 0xB10032A0, 0xB1603000, 0x2F9038C0, 0x32202C20,
72 0x3000B0E0, 0x3980B160, 0x2BC02FC0, 0xB0E031C0,
73 0xB1603000, 0x2FF03A20, 0x31602B60, 0xB020B0C0,
74 0x3AE0B160, 0x2B001810, 0xB0C03120, 0xB140B020,
75 0x18283BA0, 0x30C02A80, 0xB020B0A0, 0x3C60B140,
76 0x2A201838, 0xB0A03080, 0xB120B020, 0x18383D20,
77 0x304029C0, 0xB040B080, 0x3DE0B100, 0x29601848,
78 0xB0803000, 0xB100B040, 0x18483EC0, 0xB0402900,
79 0xB040B060, 0x3F80B0C0, 0x28801858, 0xB060B080,
80 0xB0A0B060, 0x18602820, 0xB0A02820, 0x0000B060,
81 0xB1403000, 0x2E203500, 0x35002E20, 0x3000B140,
82 0x35A0B160, 0x2DC02E80, 0xB1403480, 0xB1603000,
83 0x2EA03640, 0x34002D80, 0x3000B120, 0x36E0B160,
84 0x2D202EF0, 0xB1203380, 0xB1603000, 0x2F303780,
85 0x33002CC0, 0x3000B100, 0x3820B160, 0x2C802F50,
86 0xB10032A0, 0xB1603000, 0x2F9038C0, 0x32202C20,
87 0x3000B0E0, 0x3980B160, 0x2BC02FC0, 0xB0E031C0,
88 0xB1603000, 0x2FF03A20, 0x31602B60, 0xB020B0C0,
89 0x3AE0B160, 0x2B001810, 0xB0C03120, 0xB140B020,
90 0x18283BA0, 0x30C02A80, 0xB020B0A0, 0x3C60B140,
91 0x2A201838, 0xB0A03080, 0xB120B020, 0x18383D20,
92 0x304029C0, 0xB040B080, 0x3DE0B100, 0x29601848,
93 0xB0803000, 0xB100B040, 0x18483EC0, 0xB0402900,
94 0xB040B060, 0x3F80B0C0, 0x28801858, 0xB060B080,
95 0xB0A0B060, 0x18602820, 0xB0A02820, 0x0000B060,
96 0x36403000, 0x2D002CC0, 0x30003640, 0x2D0036C0,
97 0x35C02CC0, 0x37403000, 0x2C802D40, 0x30003540,
98 0x2D8037C0, 0x34C02C40, 0x38403000, 0x2BC02E00,
99 0x30003440, 0x2E2038C0, 0x34002B80, 0x39803000,
100 0x2B402E40, 0x30003380, 0x2E603A00, 0x33402B00,
101 0x3A803040, 0x2A802EA0, 0x30403300, 0x2EC03B40,
102 0x32802A40, 0x3C003040, 0x2A002EC0, 0x30803240,
103 0x2EC03C80, 0x320029C0, 0x3D403080, 0x29402F00,
104 0x308031C0, 0x2F203DC0, 0x31802900, 0x3E8030C0,
105 0x28802F40, 0x30C03140, 0x2F203F40, 0x31402840,
106 0x28003100, 0x28002F00, 0x00003100, 0x36403000,
107 0x2D002CC0, 0x30003640, 0x2D0036C0,
108 0x35C02CC0, 0x37403000, 0x2C802D40, 0x30003540,
109 0x2D8037C0, 0x34C02C40, 0x38403000, 0x2BC02E00,
110 0x30003440, 0x2E2038C0, 0x34002B80, 0x39803000,
111 0x2B402E40, 0x30003380, 0x2E603A00, 0x33402B00,
112 0x3A803040, 0x2A802EA0, 0x30403300, 0x2EC03B40,
113 0x32802A40, 0x3C003040, 0x2A002EC0, 0x30803240,
114 0x2EC03C80, 0x320029C0, 0x3D403080, 0x29402F00,
115 0x308031C0, 0x2F203DC0, 0x31802900, 0x3E8030C0,
116 0x28802F40, 0x30C03140, 0x2F203F40, 0x31402840,
117 0x28003100, 0x28002F00, 0x00003100,
121 * Color conversion values have 3 separate fixed point formats:
123 * 10 bit fields (ay, au)
124 * 1.9 fixed point (b.bbbbbbbbb)
125 * 11 bit fields (ry, by, ru, gu, gv)
126 * exp.mantissa (ee.mmmmmmmmm)
127 * ee = 00 = 10^-1 (0.mmmmmmmmm)
128 * ee = 01 = 10^-2 (0.0mmmmmmmmm)
129 * ee = 10 = 10^-3 (0.00mmmmmmmmm)
130 * ee = 11 = 10^-4 (0.000mmmmmmmmm)
131 * 12 bit fields (gy, rv, bu)
132 * exp.mantissa (eee.mmmmmmmmm)
133 * eee = 000 = 10^-1 (0.mmmmmmmmm)
134 * eee = 001 = 10^-2 (0.0mmmmmmmmm)
135 * eee = 010 = 10^-3 (0.00mmmmmmmmm)
136 * eee = 011 = 10^-4 (0.000mmmmmmmmm)
137 * eee = 100 = reserved
138 * eee = 101 = reserved
139 * eee = 110 = reserved
140 * eee = 111 = 10^0 (m.mmmmmmmm) (only usable for 1.0 representation)
142 * Saturation and contrast are 8 bits, with their own representation:
143 * 8 bit field (saturation, contrast)
144 * exp.mantissa (ee.mmmmmm)
145 * ee = 00 = 10^-1 (0.mmmmmm)
146 * ee = 01 = 10^0 (m.mmmmm)
147 * ee = 10 = 10^1 (mm.mmmm)
148 * ee = 11 = 10^2 (mmm.mmm)
150 * Simple conversion function:
153 * float_to_csc_11(float f)
166 * for (exp = 0; exp < 3 && f < 0.5; exp++)
168 * mant = (f * (1 << 9) + 0.5);
169 * if (mant >= (1 << 9))
170 * mant = (1 << 9) - 1;
172 * ret = (exp << 9) | mant;
178 * Behold, magic numbers! If we plant them they might grow a big
179 * s-video cable to the sky... or something.
181 * Pre-converted to appropriate hex value.
185 * PAL & NTSC values for composite & s-video connections
187 static const struct color_conversion ntsc_m_csc_composite = {
188 .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0104,
189 .ru = 0x0733, .gu = 0x052d, .bu = 0x05c7, .au = 0x0200,
190 .rv = 0x0340, .gv = 0x030c, .bv = 0x06d0, .av = 0x0200,
193 static const struct video_levels ntsc_m_levels_composite = {
194 .blank = 225, .black = 267, .burst = 113,
197 static const struct color_conversion ntsc_m_csc_svideo = {
198 .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0133,
199 .ru = 0x076a, .gu = 0x0564, .bu = 0x030d, .au = 0x0200,
200 .rv = 0x037a, .gv = 0x033d, .bv = 0x06f6, .av = 0x0200,
203 static const struct video_levels ntsc_m_levels_svideo = {
204 .blank = 266, .black = 316, .burst = 133,
207 static const struct color_conversion ntsc_j_csc_composite = {
208 .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0119,
209 .ru = 0x074c, .gu = 0x0546, .bu = 0x05ec, .au = 0x0200,
210 .rv = 0x035a, .gv = 0x0322, .bv = 0x06e1, .av = 0x0200,
213 static const struct video_levels ntsc_j_levels_composite = {
214 .blank = 225, .black = 225, .burst = 113,
217 static const struct color_conversion ntsc_j_csc_svideo = {
218 .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x014c,
219 .ru = 0x0788, .gu = 0x0581, .bu = 0x0322, .au = 0x0200,
220 .rv = 0x0399, .gv = 0x0356, .bv = 0x070a, .av = 0x0200,
223 static const struct video_levels ntsc_j_levels_svideo = {
224 .blank = 266, .black = 266, .burst = 133,
227 static const struct color_conversion pal_csc_composite = {
228 .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0113,
229 .ru = 0x0745, .gu = 0x053f, .bu = 0x05e1, .au = 0x0200,
230 .rv = 0x0353, .gv = 0x031c, .bv = 0x06dc, .av = 0x0200,
233 static const struct video_levels pal_levels_composite = {
234 .blank = 237, .black = 237, .burst = 118,
237 static const struct color_conversion pal_csc_svideo = {
238 .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0145,
239 .ru = 0x0780, .gu = 0x0579, .bu = 0x031c, .au = 0x0200,
240 .rv = 0x0390, .gv = 0x034f, .bv = 0x0705, .av = 0x0200,
243 static const struct video_levels pal_levels_svideo = {
244 .blank = 280, .black = 280, .burst = 139,
247 static const struct color_conversion pal_m_csc_composite = {
248 .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0104,
249 .ru = 0x0733, .gu = 0x052d, .bu = 0x05c7, .au = 0x0200,
250 .rv = 0x0340, .gv = 0x030c, .bv = 0x06d0, .av = 0x0200,
253 static const struct video_levels pal_m_levels_composite = {
254 .blank = 225, .black = 267, .burst = 113,
257 static const struct color_conversion pal_m_csc_svideo = {
258 .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0133,
259 .ru = 0x076a, .gu = 0x0564, .bu = 0x030d, .au = 0x0200,
260 .rv = 0x037a, .gv = 0x033d, .bv = 0x06f6, .av = 0x0200,
263 static const struct video_levels pal_m_levels_svideo = {
264 .blank = 266, .black = 316, .burst = 133,
267 static const struct color_conversion pal_n_csc_composite = {
268 .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0104,
269 .ru = 0x0733, .gu = 0x052d, .bu = 0x05c7, .au = 0x0200,
270 .rv = 0x0340, .gv = 0x030c, .bv = 0x06d0, .av = 0x0200,
273 static const struct video_levels pal_n_levels_composite = {
274 .blank = 225, .black = 267, .burst = 118,
277 static const struct color_conversion pal_n_csc_svideo = {
278 .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0133,
279 .ru = 0x076a, .gu = 0x0564, .bu = 0x030d, .au = 0x0200,
280 .rv = 0x037a, .gv = 0x033d, .bv = 0x06f6, .av = 0x0200,
283 static const struct video_levels pal_n_levels_svideo = {
284 .blank = 266, .black = 316, .burst = 139,
288 * Component connections
290 static const struct color_conversion sdtv_csc_yprpb = {
291 .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0145,
292 .ru = 0x0559, .gu = 0x0353, .bu = 0x0100, .au = 0x0200,
293 .rv = 0x0100, .gv = 0x03ad, .bv = 0x074d, .av = 0x0200,
296 static const struct color_conversion hdtv_csc_yprpb = {
297 .ry = 0x05b3, .gy = 0x016e, .by = 0x0728, .ay = 0x0145,
298 .ru = 0x07d5, .gu = 0x038b, .bu = 0x0100, .au = 0x0200,
299 .rv = 0x0100, .gv = 0x03d1, .bv = 0x06bc, .av = 0x0200,
302 static const struct video_levels component_levels = {
303 .blank = 279, .black = 279, .burst = 0,
311 u16 refresh; /* in millihertz (for precision) */
314 u16 hblank_start, hblank_end, htotal;
315 bool progressive : 1, trilevel_sync : 1, component_only : 1;
316 u8 vsync_start_f1, vsync_start_f2, vsync_len;
318 u8 veq_start_f1, veq_start_f2, veq_len;
319 u8 vi_end_f1, vi_end_f2;
322 u8 hburst_start, hburst_len;
332 * subcarrier programming
334 u16 dda2_size, dda3_size;
336 u16 dda2_inc, dda3_inc;
342 const struct video_levels *composite_levels, *svideo_levels;
343 const struct color_conversion *composite_color, *svideo_color;
344 const u32 *filter_table;
351 * I think this works as follows:
353 * subcarrier freq = pixel_clock * (dda1_inc + dda2_inc / dda2_size) / 4096
355 * Presumably, when dda3 is added in, it gets to adjust the dda2_inc value
358 * dda1_ideal = subcarrier/pixel * 4096
359 * dda1_inc = floor (dda1_ideal)
360 * dda2 = dda1_ideal - dda1_inc
362 * then pick a ratio for dda2 that gives the closest approximation. If
363 * you can't get close enough, you can play with dda3 as well. This
364 * seems likely to happen when dda2 is small as the jumps would be larger
368 * pixel_clock = subcarrier * 4096 / (dda1_inc + dda2_inc / dda2_size)
370 * The constants below were all computed using a 107.520MHz clock
374 * Register programming values for TV modes.
376 * These values account for -1s required.
378 static const struct tv_mode tv_modes[] = {
384 .component_only = false,
385 /* 525 Lines, 60 Fields, 15.734KHz line, Sub-Carrier 3.580MHz */
387 .hsync_end = 64, .hblank_end = 124,
388 .hblank_start = 836, .htotal = 857,
390 .progressive = false, .trilevel_sync = false,
392 .vsync_start_f1 = 6, .vsync_start_f2 = 7,
395 .veq_ena = true, .veq_start_f1 = 0,
396 .veq_start_f2 = 1, .veq_len = 18,
398 .vi_end_f1 = 20, .vi_end_f2 = 21,
402 .hburst_start = 72, .hburst_len = 34,
403 .vburst_start_f1 = 9, .vburst_end_f1 = 240,
404 .vburst_start_f2 = 10, .vburst_end_f2 = 240,
405 .vburst_start_f3 = 9, .vburst_end_f3 = 240,
406 .vburst_start_f4 = 10, .vburst_end_f4 = 240,
408 /* desired 3.5800000 actual 3.5800000 clock 107.52 */
410 .dda2_inc = 20800, .dda2_size = 27456,
411 .dda3_inc = 0, .dda3_size = 0,
412 .sc_reset = TV_SC_RESET_EVERY_4,
415 .composite_levels = &ntsc_m_levels_composite,
416 .composite_color = &ntsc_m_csc_composite,
417 .svideo_levels = &ntsc_m_levels_svideo,
418 .svideo_color = &ntsc_m_csc_svideo,
420 .filter_table = filter_table,
427 .component_only = false,
428 /* 525 Lines, 60 Fields, 15.734KHz line, Sub-Carrier 4.43MHz */
429 .hsync_end = 64, .hblank_end = 124,
430 .hblank_start = 836, .htotal = 857,
432 .progressive = false, .trilevel_sync = false,
434 .vsync_start_f1 = 6, .vsync_start_f2 = 7,
437 .veq_ena = true, .veq_start_f1 = 0,
438 .veq_start_f2 = 1, .veq_len = 18,
440 .vi_end_f1 = 20, .vi_end_f2 = 21,
444 .hburst_start = 72, .hburst_len = 34,
445 .vburst_start_f1 = 9, .vburst_end_f1 = 240,
446 .vburst_start_f2 = 10, .vburst_end_f2 = 240,
447 .vburst_start_f3 = 9, .vburst_end_f3 = 240,
448 .vburst_start_f4 = 10, .vburst_end_f4 = 240,
450 /* desired 4.4336180 actual 4.4336180 clock 107.52 */
452 .dda2_inc = 4093, .dda2_size = 27456,
453 .dda3_inc = 310, .dda3_size = 525,
454 .sc_reset = TV_SC_RESET_NEVER,
457 .composite_levels = &ntsc_m_levels_composite,
458 .composite_color = &ntsc_m_csc_composite,
459 .svideo_levels = &ntsc_m_levels_svideo,
460 .svideo_color = &ntsc_m_csc_svideo,
462 .filter_table = filter_table,
469 .component_only = false,
471 /* 525 Lines, 60 Fields, 15.734KHz line, Sub-Carrier 3.580MHz */
472 .hsync_end = 64, .hblank_end = 124,
473 .hblank_start = 836, .htotal = 857,
475 .progressive = false, .trilevel_sync = false,
477 .vsync_start_f1 = 6, .vsync_start_f2 = 7,
480 .veq_ena = true, .veq_start_f1 = 0,
481 .veq_start_f2 = 1, .veq_len = 18,
483 .vi_end_f1 = 20, .vi_end_f2 = 21,
487 .hburst_start = 72, .hburst_len = 34,
488 .vburst_start_f1 = 9, .vburst_end_f1 = 240,
489 .vburst_start_f2 = 10, .vburst_end_f2 = 240,
490 .vburst_start_f3 = 9, .vburst_end_f3 = 240,
491 .vburst_start_f4 = 10, .vburst_end_f4 = 240,
493 /* desired 3.5800000 actual 3.5800000 clock 107.52 */
495 .dda2_inc = 20800, .dda2_size = 27456,
496 .dda3_inc = 0, .dda3_size = 0,
497 .sc_reset = TV_SC_RESET_EVERY_4,
500 .composite_levels = &ntsc_j_levels_composite,
501 .composite_color = &ntsc_j_csc_composite,
502 .svideo_levels = &ntsc_j_levels_svideo,
503 .svideo_color = &ntsc_j_csc_svideo,
505 .filter_table = filter_table,
512 .component_only = false,
514 /* 525 Lines, 60 Fields, 15.734KHz line, Sub-Carrier 3.580MHz */
515 .hsync_end = 64, .hblank_end = 124,
516 .hblank_start = 836, .htotal = 857,
518 .progressive = false, .trilevel_sync = false,
520 .vsync_start_f1 = 6, .vsync_start_f2 = 7,
523 .veq_ena = true, .veq_start_f1 = 0,
524 .veq_start_f2 = 1, .veq_len = 18,
526 .vi_end_f1 = 20, .vi_end_f2 = 21,
530 .hburst_start = 72, .hburst_len = 34,
531 .vburst_start_f1 = 9, .vburst_end_f1 = 240,
532 .vburst_start_f2 = 10, .vburst_end_f2 = 240,
533 .vburst_start_f3 = 9, .vburst_end_f3 = 240,
534 .vburst_start_f4 = 10, .vburst_end_f4 = 240,
536 /* desired 3.5800000 actual 3.5800000 clock 107.52 */
538 .dda2_inc = 16704, .dda2_size = 27456,
539 .dda3_inc = 0, .dda3_size = 0,
540 .sc_reset = TV_SC_RESET_EVERY_8,
543 .composite_levels = &pal_m_levels_composite,
544 .composite_color = &pal_m_csc_composite,
545 .svideo_levels = &pal_m_levels_svideo,
546 .svideo_color = &pal_m_csc_svideo,
548 .filter_table = filter_table,
551 /* 625 Lines, 50 Fields, 15.625KHz line, Sub-Carrier 4.434MHz */
556 .component_only = false,
558 .hsync_end = 64, .hblank_end = 128,
559 .hblank_start = 844, .htotal = 863,
561 .progressive = false, .trilevel_sync = false,
564 .vsync_start_f1 = 6, .vsync_start_f2 = 7,
567 .veq_ena = true, .veq_start_f1 = 0,
568 .veq_start_f2 = 1, .veq_len = 18,
570 .vi_end_f1 = 24, .vi_end_f2 = 25,
574 .hburst_start = 73, .hburst_len = 34,
575 .vburst_start_f1 = 8, .vburst_end_f1 = 285,
576 .vburst_start_f2 = 8, .vburst_end_f2 = 286,
577 .vburst_start_f3 = 9, .vburst_end_f3 = 286,
578 .vburst_start_f4 = 9, .vburst_end_f4 = 285,
581 /* desired 4.4336180 actual 4.4336180 clock 107.52 */
583 .dda2_inc = 23578, .dda2_size = 27648,
584 .dda3_inc = 134, .dda3_size = 625,
585 .sc_reset = TV_SC_RESET_EVERY_8,
588 .composite_levels = &pal_n_levels_composite,
589 .composite_color = &pal_n_csc_composite,
590 .svideo_levels = &pal_n_levels_svideo,
591 .svideo_color = &pal_n_csc_svideo,
593 .filter_table = filter_table,
596 /* 625 Lines, 50 Fields, 15.625KHz line, Sub-Carrier 4.434MHz */
601 .component_only = false,
603 .hsync_end = 64, .hblank_end = 142,
604 .hblank_start = 844, .htotal = 863,
606 .progressive = false, .trilevel_sync = false,
608 .vsync_start_f1 = 5, .vsync_start_f2 = 6,
611 .veq_ena = true, .veq_start_f1 = 0,
612 .veq_start_f2 = 1, .veq_len = 15,
614 .vi_end_f1 = 24, .vi_end_f2 = 25,
618 .hburst_start = 73, .hburst_len = 32,
619 .vburst_start_f1 = 8, .vburst_end_f1 = 285,
620 .vburst_start_f2 = 8, .vburst_end_f2 = 286,
621 .vburst_start_f3 = 9, .vburst_end_f3 = 286,
622 .vburst_start_f4 = 9, .vburst_end_f4 = 285,
624 /* desired 4.4336180 actual 4.4336180 clock 107.52 */
626 .dda2_inc = 4122, .dda2_size = 27648,
627 .dda3_inc = 67, .dda3_size = 625,
628 .sc_reset = TV_SC_RESET_EVERY_8,
631 .composite_levels = &pal_levels_composite,
632 .composite_color = &pal_csc_composite,
633 .svideo_levels = &pal_levels_svideo,
634 .svideo_color = &pal_csc_svideo,
636 .filter_table = filter_table,
643 .component_only = true,
645 .hsync_end = 64, .hblank_end = 122,
646 .hblank_start = 842, .htotal = 857,
648 .progressive = true, .trilevel_sync = false,
650 .vsync_start_f1 = 12, .vsync_start_f2 = 12,
655 .vi_end_f1 = 44, .vi_end_f2 = 44,
660 .filter_table = filter_table,
667 .component_only = true,
669 .hsync_end = 64, .hblank_end = 139,
670 .hblank_start = 859, .htotal = 863,
672 .progressive = true, .trilevel_sync = false,
674 .vsync_start_f1 = 10, .vsync_start_f2 = 10,
679 .vi_end_f1 = 48, .vi_end_f2 = 48,
684 .filter_table = filter_table,
691 .component_only = true,
693 .hsync_end = 80, .hblank_end = 300,
694 .hblank_start = 1580, .htotal = 1649,
696 .progressive = true, .trilevel_sync = true,
698 .vsync_start_f1 = 10, .vsync_start_f2 = 10,
703 .vi_end_f1 = 29, .vi_end_f2 = 29,
708 .filter_table = filter_table,
715 .component_only = true,
717 .hsync_end = 80, .hblank_end = 300,
718 .hblank_start = 1580, .htotal = 1979,
720 .progressive = true, .trilevel_sync = true,
722 .vsync_start_f1 = 10, .vsync_start_f2 = 10,
727 .vi_end_f1 = 29, .vi_end_f2 = 29,
732 .filter_table = filter_table,
735 .name = "1080i@50Hz",
739 .component_only = true,
741 .hsync_end = 88, .hblank_end = 235,
742 .hblank_start = 2155, .htotal = 2639,
744 .progressive = false, .trilevel_sync = true,
746 .vsync_start_f1 = 4, .vsync_start_f2 = 5,
749 .veq_ena = true, .veq_start_f1 = 4,
750 .veq_start_f2 = 4, .veq_len = 10,
753 .vi_end_f1 = 21, .vi_end_f2 = 22,
758 .filter_table = filter_table,
761 .name = "1080i@60Hz",
765 .component_only = true,
767 .hsync_end = 88, .hblank_end = 235,
768 .hblank_start = 2155, .htotal = 2199,
770 .progressive = false, .trilevel_sync = true,
772 .vsync_start_f1 = 4, .vsync_start_f2 = 5,
775 .veq_ena = true, .veq_start_f1 = 4,
776 .veq_start_f2 = 4, .veq_len = 10,
779 .vi_end_f1 = 21, .vi_end_f2 = 22,
784 .filter_table = filter_table,
788 .name = "1080p@30Hz",
792 .component_only = true,
794 .hsync_end = 88, .hblank_end = 235,
795 .hblank_start = 2155, .htotal = 2199,
797 .progressive = true, .trilevel_sync = true,
799 .vsync_start_f1 = 8, .vsync_start_f2 = 8,
802 .veq_ena = false, .veq_start_f1 = 0,
803 .veq_start_f2 = 0, .veq_len = 0,
805 .vi_end_f1 = 44, .vi_end_f2 = 44,
810 .filter_table = filter_table,
814 .name = "1080p@50Hz",
818 .component_only = true,
820 .hsync_end = 88, .hblank_end = 235,
821 .hblank_start = 2155, .htotal = 2639,
823 .progressive = true, .trilevel_sync = true,
825 .vsync_start_f1 = 8, .vsync_start_f2 = 8,
828 .veq_ena = false, .veq_start_f1 = 0,
829 .veq_start_f2 = 0, .veq_len = 0,
831 .vi_end_f1 = 44, .vi_end_f2 = 44,
836 .filter_table = filter_table,
840 .name = "1080p@60Hz",
844 .component_only = true,
846 .hsync_end = 88, .hblank_end = 235,
847 .hblank_start = 2155, .htotal = 2199,
849 .progressive = true, .trilevel_sync = true,
851 .vsync_start_f1 = 8, .vsync_start_f2 = 8,
854 .veq_ena = false, .veq_start_f1 = 0,
855 .veq_start_f2 = 0, .veq_len = 0,
857 .vi_end_f1 = 44, .vi_end_f2 = 44,
862 .filter_table = filter_table,
866 struct intel_tv_connector_state {
867 struct drm_connector_state base;
870 * May need to override the user margins for
871 * gen3 >1024 wide source vertical centering.
880 #define to_intel_tv_connector_state(x) container_of(x, struct intel_tv_connector_state, base)
882 static struct drm_connector_state *
883 intel_tv_connector_duplicate_state(struct drm_connector *connector)
885 struct intel_tv_connector_state *state;
887 state = kmemdup(connector->state, sizeof(*state), GFP_KERNEL);
891 __drm_atomic_helper_connector_duplicate_state(connector, &state->base);
895 static struct intel_tv *enc_to_tv(struct intel_encoder *encoder)
897 return container_of(encoder, struct intel_tv, base);
900 static struct intel_tv *intel_attached_tv(struct intel_connector *connector)
902 return enc_to_tv(intel_attached_encoder(connector));
906 intel_tv_get_hw_state(struct intel_encoder *encoder, enum pipe *pipe)
908 struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
909 u32 tmp = intel_de_read(dev_priv, TV_CTL);
911 *pipe = (tmp & TV_ENC_PIPE_SEL_MASK) >> TV_ENC_PIPE_SEL_SHIFT;
913 return tmp & TV_ENC_ENABLE;
917 intel_enable_tv(struct intel_encoder *encoder,
918 const struct intel_crtc_state *pipe_config,
919 const struct drm_connector_state *conn_state)
921 struct drm_device *dev = encoder->base.dev;
922 struct drm_i915_private *dev_priv = to_i915(dev);
924 /* Prevents vblank waits from timing out in intel_tv_detect_type() */
925 intel_wait_for_vblank(dev_priv,
926 to_intel_crtc(pipe_config->uapi.crtc)->pipe);
928 intel_de_write(dev_priv, TV_CTL,
929 intel_de_read(dev_priv, TV_CTL) | TV_ENC_ENABLE);
933 intel_disable_tv(struct intel_encoder *encoder,
934 const struct intel_crtc_state *old_crtc_state,
935 const struct drm_connector_state *old_conn_state)
937 struct drm_device *dev = encoder->base.dev;
938 struct drm_i915_private *dev_priv = to_i915(dev);
940 intel_de_write(dev_priv, TV_CTL,
941 intel_de_read(dev_priv, TV_CTL) & ~TV_ENC_ENABLE);
944 static const struct tv_mode *intel_tv_mode_find(const struct drm_connector_state *conn_state)
946 int format = conn_state->tv.mode;
948 return &tv_modes[format];
951 static enum drm_mode_status
952 intel_tv_mode_valid(struct drm_connector *connector,
953 struct drm_display_mode *mode)
955 const struct tv_mode *tv_mode = intel_tv_mode_find(connector->state);
956 int max_dotclk = to_i915(connector->dev)->max_dotclk_freq;
958 if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
959 return MODE_NO_DBLESCAN;
961 if (mode->clock > max_dotclk)
962 return MODE_CLOCK_HIGH;
964 /* Ensure TV refresh is close to desired refresh */
965 if (abs(tv_mode->refresh - drm_mode_vrefresh(mode) * 1000) >= 1000)
966 return MODE_CLOCK_RANGE;
972 intel_tv_mode_vdisplay(const struct tv_mode *tv_mode)
974 if (tv_mode->progressive)
975 return tv_mode->nbr_end + 1;
977 return 2 * (tv_mode->nbr_end + 1);
981 intel_tv_mode_to_mode(struct drm_display_mode *mode,
982 const struct tv_mode *tv_mode)
984 mode->clock = tv_mode->clock /
985 (tv_mode->oversample >> !tv_mode->progressive);
988 * tv_mode horizontal timings:
999 tv_mode->hblank_start - tv_mode->hblank_end;
1000 mode->hsync_start = mode->hdisplay +
1001 tv_mode->htotal - tv_mode->hblank_start;
1002 mode->hsync_end = mode->hsync_start +
1004 mode->htotal = tv_mode->htotal + 1;
1007 * tv_mode vertical timings:
1011 * | | vi_end nbr_end
1017 mode->vdisplay = intel_tv_mode_vdisplay(tv_mode);
1018 if (tv_mode->progressive) {
1019 mode->vsync_start = mode->vdisplay +
1020 tv_mode->vsync_start_f1 + 1;
1021 mode->vsync_end = mode->vsync_start +
1023 mode->vtotal = mode->vdisplay +
1024 tv_mode->vi_end_f1 + 1;
1026 mode->vsync_start = mode->vdisplay +
1027 tv_mode->vsync_start_f1 + 1 +
1028 tv_mode->vsync_start_f2 + 1;
1029 mode->vsync_end = mode->vsync_start +
1030 2 * tv_mode->vsync_len;
1031 mode->vtotal = mode->vdisplay +
1032 tv_mode->vi_end_f1 + 1 +
1033 tv_mode->vi_end_f2 + 1;
1036 /* TV has it's own notion of sync and other mode flags, so clear them. */
1039 snprintf(mode->name, sizeof(mode->name),
1041 mode->hdisplay, mode->vdisplay,
1042 tv_mode->progressive ? 'p' : 'i',
1046 static void intel_tv_scale_mode_horiz(struct drm_display_mode *mode,
1047 int hdisplay, int left_margin,
1050 int hsync_start = mode->hsync_start - mode->hdisplay + right_margin;
1051 int hsync_end = mode->hsync_end - mode->hdisplay + right_margin;
1052 int new_htotal = mode->htotal * hdisplay /
1053 (mode->hdisplay - left_margin - right_margin);
1055 mode->clock = mode->clock * new_htotal / mode->htotal;
1057 mode->hdisplay = hdisplay;
1058 mode->hsync_start = hdisplay + hsync_start * new_htotal / mode->htotal;
1059 mode->hsync_end = hdisplay + hsync_end * new_htotal / mode->htotal;
1060 mode->htotal = new_htotal;
1063 static void intel_tv_scale_mode_vert(struct drm_display_mode *mode,
1064 int vdisplay, int top_margin,
1067 int vsync_start = mode->vsync_start - mode->vdisplay + bottom_margin;
1068 int vsync_end = mode->vsync_end - mode->vdisplay + bottom_margin;
1069 int new_vtotal = mode->vtotal * vdisplay /
1070 (mode->vdisplay - top_margin - bottom_margin);
1072 mode->clock = mode->clock * new_vtotal / mode->vtotal;
1074 mode->vdisplay = vdisplay;
1075 mode->vsync_start = vdisplay + vsync_start * new_vtotal / mode->vtotal;
1076 mode->vsync_end = vdisplay + vsync_end * new_vtotal / mode->vtotal;
1077 mode->vtotal = new_vtotal;
1081 intel_tv_get_config(struct intel_encoder *encoder,
1082 struct intel_crtc_state *pipe_config)
1084 struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
1085 struct drm_display_mode *adjusted_mode =
1086 &pipe_config->hw.adjusted_mode;
1087 struct drm_display_mode mode = {};
1088 u32 tv_ctl, hctl1, hctl3, vctl1, vctl2, tmp;
1089 struct tv_mode tv_mode = {};
1090 int hdisplay = adjusted_mode->crtc_hdisplay;
1091 int vdisplay = adjusted_mode->crtc_vdisplay;
1092 int xsize, ysize, xpos, ypos;
1094 pipe_config->output_types |= BIT(INTEL_OUTPUT_TVOUT);
1096 tv_ctl = intel_de_read(dev_priv, TV_CTL);
1097 hctl1 = intel_de_read(dev_priv, TV_H_CTL_1);
1098 hctl3 = intel_de_read(dev_priv, TV_H_CTL_3);
1099 vctl1 = intel_de_read(dev_priv, TV_V_CTL_1);
1100 vctl2 = intel_de_read(dev_priv, TV_V_CTL_2);
1102 tv_mode.htotal = (hctl1 & TV_HTOTAL_MASK) >> TV_HTOTAL_SHIFT;
1103 tv_mode.hsync_end = (hctl1 & TV_HSYNC_END_MASK) >> TV_HSYNC_END_SHIFT;
1105 tv_mode.hblank_start = (hctl3 & TV_HBLANK_START_MASK) >> TV_HBLANK_START_SHIFT;
1106 tv_mode.hblank_end = (hctl3 & TV_HSYNC_END_MASK) >> TV_HBLANK_END_SHIFT;
1108 tv_mode.nbr_end = (vctl1 & TV_NBR_END_MASK) >> TV_NBR_END_SHIFT;
1109 tv_mode.vi_end_f1 = (vctl1 & TV_VI_END_F1_MASK) >> TV_VI_END_F1_SHIFT;
1110 tv_mode.vi_end_f2 = (vctl1 & TV_VI_END_F2_MASK) >> TV_VI_END_F2_SHIFT;
1112 tv_mode.vsync_len = (vctl2 & TV_VSYNC_LEN_MASK) >> TV_VSYNC_LEN_SHIFT;
1113 tv_mode.vsync_start_f1 = (vctl2 & TV_VSYNC_START_F1_MASK) >> TV_VSYNC_START_F1_SHIFT;
1114 tv_mode.vsync_start_f2 = (vctl2 & TV_VSYNC_START_F2_MASK) >> TV_VSYNC_START_F2_SHIFT;
1116 tv_mode.clock = pipe_config->port_clock;
1118 tv_mode.progressive = tv_ctl & TV_PROGRESSIVE;
1120 switch (tv_ctl & TV_OVERSAMPLE_MASK) {
1121 case TV_OVERSAMPLE_8X:
1122 tv_mode.oversample = 8;
1124 case TV_OVERSAMPLE_4X:
1125 tv_mode.oversample = 4;
1127 case TV_OVERSAMPLE_2X:
1128 tv_mode.oversample = 2;
1131 tv_mode.oversample = 1;
1135 tmp = intel_de_read(dev_priv, TV_WIN_POS);
1137 ypos = tmp & 0xffff;
1139 tmp = intel_de_read(dev_priv, TV_WIN_SIZE);
1141 ysize = tmp & 0xffff;
1143 intel_tv_mode_to_mode(&mode, &tv_mode);
1145 drm_dbg_kms(&dev_priv->drm, "TV mode:\n");
1146 drm_mode_debug_printmodeline(&mode);
1148 intel_tv_scale_mode_horiz(&mode, hdisplay,
1149 xpos, mode.hdisplay - xsize - xpos);
1150 intel_tv_scale_mode_vert(&mode, vdisplay,
1151 ypos, mode.vdisplay - ysize - ypos);
1153 adjusted_mode->crtc_clock = mode.clock;
1154 if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE)
1155 adjusted_mode->crtc_clock /= 2;
1157 /* pixel counter doesn't work on i965gm TV output */
1158 if (IS_I965GM(dev_priv))
1159 adjusted_mode->private_flags |=
1160 I915_MODE_FLAG_USE_SCANLINE_COUNTER;
1163 static bool intel_tv_source_too_wide(struct drm_i915_private *dev_priv,
1166 return IS_GEN(dev_priv, 3) && hdisplay > 1024;
1169 static bool intel_tv_vert_scaling(const struct drm_display_mode *tv_mode,
1170 const struct drm_connector_state *conn_state,
1173 return tv_mode->crtc_vdisplay -
1174 conn_state->tv.margins.top -
1175 conn_state->tv.margins.bottom !=
1180 intel_tv_compute_config(struct intel_encoder *encoder,
1181 struct intel_crtc_state *pipe_config,
1182 struct drm_connector_state *conn_state)
1184 struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
1185 struct intel_tv_connector_state *tv_conn_state =
1186 to_intel_tv_connector_state(conn_state);
1187 const struct tv_mode *tv_mode = intel_tv_mode_find(conn_state);
1188 struct drm_display_mode *adjusted_mode =
1189 &pipe_config->hw.adjusted_mode;
1190 int hdisplay = adjusted_mode->crtc_hdisplay;
1191 int vdisplay = adjusted_mode->crtc_vdisplay;
1196 if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN)
1199 pipe_config->output_format = INTEL_OUTPUT_FORMAT_RGB;
1201 drm_dbg_kms(&dev_priv->drm, "forcing bpc to 8 for TV\n");
1202 pipe_config->pipe_bpp = 8*3;
1204 pipe_config->port_clock = tv_mode->clock;
1206 intel_tv_mode_to_mode(adjusted_mode, tv_mode);
1207 drm_mode_set_crtcinfo(adjusted_mode, 0);
1209 if (intel_tv_source_too_wide(dev_priv, hdisplay) ||
1210 !intel_tv_vert_scaling(adjusted_mode, conn_state, vdisplay)) {
1211 int extra, top, bottom;
1213 extra = adjusted_mode->crtc_vdisplay - vdisplay;
1216 drm_dbg_kms(&dev_priv->drm,
1217 "No vertical scaling for >1024 pixel wide modes\n");
1221 /* Need to turn off the vertical filter and center the image */
1223 /* Attempt to maintain the relative sizes of the margins */
1224 top = conn_state->tv.margins.top;
1225 bottom = conn_state->tv.margins.bottom;
1228 top = extra * top / (top + bottom);
1231 bottom = extra - top;
1233 tv_conn_state->margins.top = top;
1234 tv_conn_state->margins.bottom = bottom;
1236 tv_conn_state->bypass_vfilter = true;
1238 if (!tv_mode->progressive) {
1239 adjusted_mode->clock /= 2;
1240 adjusted_mode->crtc_clock /= 2;
1241 adjusted_mode->flags |= DRM_MODE_FLAG_INTERLACE;
1244 tv_conn_state->margins.top = conn_state->tv.margins.top;
1245 tv_conn_state->margins.bottom = conn_state->tv.margins.bottom;
1247 tv_conn_state->bypass_vfilter = false;
1250 drm_dbg_kms(&dev_priv->drm, "TV mode:\n");
1251 drm_mode_debug_printmodeline(adjusted_mode);
1254 * The pipe scanline counter behaviour looks as follows when
1255 * using the TV encoder:
1264 * dsl=0 ___/ |_____/ |
1267 * | | | | pipe vblank/first part of tv vblank
1268 * | | | bottom margin
1271 * remainder of tv vblank
1273 * When the TV encoder is used the pipe wants to run faster
1274 * than expected rate. During the active portion the TV
1275 * encoder stalls the pipe every few lines to keep it in
1276 * check. When the TV encoder reaches the bottom margin the
1277 * pipe simply stops. Once we reach the TV vblank the pipe is
1278 * no longer stalled and it runs at the max rate (apparently
1279 * oversample clock on gen3, cdclk on gen4). Once the pipe
1280 * reaches the pipe vtotal the pipe stops for the remainder
1281 * of the TV vblank/top margin. The pipe starts up again when
1282 * the TV encoder exits the top margin.
1284 * To avoid huge hassles for vblank timestamping we scale
1285 * the pipe timings as if the pipe always runs at the average
1286 * rate it maintains during the active period. This also
1287 * gives us a reasonable guesstimate as to the pixel rate.
1288 * Due to the variation in the actual pipe speed the scanline
1289 * counter will give us slightly erroneous results during the
1290 * TV vblank/margins. But since vtotal was selected such that
1291 * it matches the average rate of the pipe during the active
1292 * portion the error shouldn't cause any serious grief to
1293 * vblank timestamps.
1295 * For posterity here is the empirically derived formula
1296 * that gives us the maximum length of the pipe vblank
1297 * we can use without causing display corruption. Following
1298 * this would allow us to have a ticking scanline counter
1299 * everywhere except during the bottom margin (there the
1300 * pipe always stops). Ie. this would eliminate the second
1301 * flat portion of the above graph. However this would also
1302 * complicate vblank timestamping as the pipe vtotal would
1303 * no longer match the average rate the pipe runs at during
1304 * the active portion. Hence following this formula seems
1305 * more trouble that it's worth.
1307 * if (IS_GEN(dev_priv, 4)) {
1308 * num = cdclk * (tv_mode->oversample >> !tv_mode->progressive);
1309 * den = tv_mode->clock;
1311 * num = tv_mode->oversample >> !tv_mode->progressive;
1314 * max_pipe_vblank_len ~=
1315 * (num * tv_htotal * (tv_vblank_len + top_margin)) /
1316 * (den * pipe_htotal);
1318 intel_tv_scale_mode_horiz(adjusted_mode, hdisplay,
1319 conn_state->tv.margins.left,
1320 conn_state->tv.margins.right);
1321 intel_tv_scale_mode_vert(adjusted_mode, vdisplay,
1322 tv_conn_state->margins.top,
1323 tv_conn_state->margins.bottom);
1324 drm_mode_set_crtcinfo(adjusted_mode, 0);
1325 adjusted_mode->name[0] = '\0';
1327 /* pixel counter doesn't work on i965gm TV output */
1328 if (IS_I965GM(dev_priv))
1329 adjusted_mode->private_flags |=
1330 I915_MODE_FLAG_USE_SCANLINE_COUNTER;
1336 set_tv_mode_timings(struct drm_i915_private *dev_priv,
1337 const struct tv_mode *tv_mode,
1340 u32 hctl1, hctl2, hctl3;
1341 u32 vctl1, vctl2, vctl3, vctl4, vctl5, vctl6, vctl7;
1343 hctl1 = (tv_mode->hsync_end << TV_HSYNC_END_SHIFT) |
1344 (tv_mode->htotal << TV_HTOTAL_SHIFT);
1346 hctl2 = (tv_mode->hburst_start << 16) |
1347 (tv_mode->hburst_len << TV_HBURST_LEN_SHIFT);
1350 hctl2 |= TV_BURST_ENA;
1352 hctl3 = (tv_mode->hblank_start << TV_HBLANK_START_SHIFT) |
1353 (tv_mode->hblank_end << TV_HBLANK_END_SHIFT);
1355 vctl1 = (tv_mode->nbr_end << TV_NBR_END_SHIFT) |
1356 (tv_mode->vi_end_f1 << TV_VI_END_F1_SHIFT) |
1357 (tv_mode->vi_end_f2 << TV_VI_END_F2_SHIFT);
1359 vctl2 = (tv_mode->vsync_len << TV_VSYNC_LEN_SHIFT) |
1360 (tv_mode->vsync_start_f1 << TV_VSYNC_START_F1_SHIFT) |
1361 (tv_mode->vsync_start_f2 << TV_VSYNC_START_F2_SHIFT);
1363 vctl3 = (tv_mode->veq_len << TV_VEQ_LEN_SHIFT) |
1364 (tv_mode->veq_start_f1 << TV_VEQ_START_F1_SHIFT) |
1365 (tv_mode->veq_start_f2 << TV_VEQ_START_F2_SHIFT);
1367 if (tv_mode->veq_ena)
1368 vctl3 |= TV_EQUAL_ENA;
1370 vctl4 = (tv_mode->vburst_start_f1 << TV_VBURST_START_F1_SHIFT) |
1371 (tv_mode->vburst_end_f1 << TV_VBURST_END_F1_SHIFT);
1373 vctl5 = (tv_mode->vburst_start_f2 << TV_VBURST_START_F2_SHIFT) |
1374 (tv_mode->vburst_end_f2 << TV_VBURST_END_F2_SHIFT);
1376 vctl6 = (tv_mode->vburst_start_f3 << TV_VBURST_START_F3_SHIFT) |
1377 (tv_mode->vburst_end_f3 << TV_VBURST_END_F3_SHIFT);
1379 vctl7 = (tv_mode->vburst_start_f4 << TV_VBURST_START_F4_SHIFT) |
1380 (tv_mode->vburst_end_f4 << TV_VBURST_END_F4_SHIFT);
1382 intel_de_write(dev_priv, TV_H_CTL_1, hctl1);
1383 intel_de_write(dev_priv, TV_H_CTL_2, hctl2);
1384 intel_de_write(dev_priv, TV_H_CTL_3, hctl3);
1385 intel_de_write(dev_priv, TV_V_CTL_1, vctl1);
1386 intel_de_write(dev_priv, TV_V_CTL_2, vctl2);
1387 intel_de_write(dev_priv, TV_V_CTL_3, vctl3);
1388 intel_de_write(dev_priv, TV_V_CTL_4, vctl4);
1389 intel_de_write(dev_priv, TV_V_CTL_5, vctl5);
1390 intel_de_write(dev_priv, TV_V_CTL_6, vctl6);
1391 intel_de_write(dev_priv, TV_V_CTL_7, vctl7);
1394 static void set_color_conversion(struct drm_i915_private *dev_priv,
1395 const struct color_conversion *color_conversion)
1397 if (!color_conversion)
1400 intel_de_write(dev_priv, TV_CSC_Y,
1401 (color_conversion->ry << 16) | color_conversion->gy);
1402 intel_de_write(dev_priv, TV_CSC_Y2,
1403 (color_conversion->by << 16) | color_conversion->ay);
1404 intel_de_write(dev_priv, TV_CSC_U,
1405 (color_conversion->ru << 16) | color_conversion->gu);
1406 intel_de_write(dev_priv, TV_CSC_U2,
1407 (color_conversion->bu << 16) | color_conversion->au);
1408 intel_de_write(dev_priv, TV_CSC_V,
1409 (color_conversion->rv << 16) | color_conversion->gv);
1410 intel_de_write(dev_priv, TV_CSC_V2,
1411 (color_conversion->bv << 16) | color_conversion->av);
1414 static void intel_tv_pre_enable(struct intel_encoder *encoder,
1415 const struct intel_crtc_state *pipe_config,
1416 const struct drm_connector_state *conn_state)
1418 struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
1419 struct intel_crtc *intel_crtc = to_intel_crtc(pipe_config->uapi.crtc);
1420 struct intel_tv *intel_tv = enc_to_tv(encoder);
1421 const struct intel_tv_connector_state *tv_conn_state =
1422 to_intel_tv_connector_state(conn_state);
1423 const struct tv_mode *tv_mode = intel_tv_mode_find(conn_state);
1424 u32 tv_ctl, tv_filter_ctl;
1425 u32 scctl1, scctl2, scctl3;
1427 const struct video_levels *video_levels;
1428 const struct color_conversion *color_conversion;
1431 unsigned int xsize, ysize;
1434 return; /* can't happen (mode_prepare prevents this) */
1436 tv_ctl = intel_de_read(dev_priv, TV_CTL);
1437 tv_ctl &= TV_CTL_SAVE;
1439 switch (intel_tv->type) {
1441 case DRM_MODE_CONNECTOR_Unknown:
1442 case DRM_MODE_CONNECTOR_Composite:
1443 tv_ctl |= TV_ENC_OUTPUT_COMPOSITE;
1444 video_levels = tv_mode->composite_levels;
1445 color_conversion = tv_mode->composite_color;
1446 burst_ena = tv_mode->burst_ena;
1448 case DRM_MODE_CONNECTOR_Component:
1449 tv_ctl |= TV_ENC_OUTPUT_COMPONENT;
1450 video_levels = &component_levels;
1451 if (tv_mode->burst_ena)
1452 color_conversion = &sdtv_csc_yprpb;
1454 color_conversion = &hdtv_csc_yprpb;
1457 case DRM_MODE_CONNECTOR_SVIDEO:
1458 tv_ctl |= TV_ENC_OUTPUT_SVIDEO;
1459 video_levels = tv_mode->svideo_levels;
1460 color_conversion = tv_mode->svideo_color;
1461 burst_ena = tv_mode->burst_ena;
1465 tv_ctl |= TV_ENC_PIPE_SEL(intel_crtc->pipe);
1467 switch (tv_mode->oversample) {
1469 tv_ctl |= TV_OVERSAMPLE_8X;
1472 tv_ctl |= TV_OVERSAMPLE_4X;
1475 tv_ctl |= TV_OVERSAMPLE_2X;
1478 tv_ctl |= TV_OVERSAMPLE_NONE;
1482 if (tv_mode->progressive)
1483 tv_ctl |= TV_PROGRESSIVE;
1484 if (tv_mode->trilevel_sync)
1485 tv_ctl |= TV_TRILEVEL_SYNC;
1486 if (tv_mode->pal_burst)
1487 tv_ctl |= TV_PAL_BURST;
1490 if (tv_mode->dda1_inc)
1491 scctl1 |= TV_SC_DDA1_EN;
1492 if (tv_mode->dda2_inc)
1493 scctl1 |= TV_SC_DDA2_EN;
1494 if (tv_mode->dda3_inc)
1495 scctl1 |= TV_SC_DDA3_EN;
1496 scctl1 |= tv_mode->sc_reset;
1498 scctl1 |= video_levels->burst << TV_BURST_LEVEL_SHIFT;
1499 scctl1 |= tv_mode->dda1_inc << TV_SCDDA1_INC_SHIFT;
1501 scctl2 = tv_mode->dda2_size << TV_SCDDA2_SIZE_SHIFT |
1502 tv_mode->dda2_inc << TV_SCDDA2_INC_SHIFT;
1504 scctl3 = tv_mode->dda3_size << TV_SCDDA3_SIZE_SHIFT |
1505 tv_mode->dda3_inc << TV_SCDDA3_INC_SHIFT;
1507 /* Enable two fixes for the chips that need them. */
1508 if (IS_I915GM(dev_priv))
1509 tv_ctl |= TV_ENC_C0_FIX | TV_ENC_SDP_FIX;
1511 set_tv_mode_timings(dev_priv, tv_mode, burst_ena);
1513 intel_de_write(dev_priv, TV_SC_CTL_1, scctl1);
1514 intel_de_write(dev_priv, TV_SC_CTL_2, scctl2);
1515 intel_de_write(dev_priv, TV_SC_CTL_3, scctl3);
1517 set_color_conversion(dev_priv, color_conversion);
1519 if (INTEL_GEN(dev_priv) >= 4)
1520 intel_de_write(dev_priv, TV_CLR_KNOBS, 0x00404000);
1522 intel_de_write(dev_priv, TV_CLR_KNOBS, 0x00606000);
1525 intel_de_write(dev_priv, TV_CLR_LEVEL,
1526 ((video_levels->black << TV_BLACK_LEVEL_SHIFT) | (video_levels->blank << TV_BLANK_LEVEL_SHIFT)));
1528 assert_pipe_disabled(dev_priv, pipe_config->cpu_transcoder);
1530 /* Filter ctl must be set before TV_WIN_SIZE */
1531 tv_filter_ctl = TV_AUTO_SCALE;
1532 if (tv_conn_state->bypass_vfilter)
1533 tv_filter_ctl |= TV_V_FILTER_BYPASS;
1534 intel_de_write(dev_priv, TV_FILTER_CTL_1, tv_filter_ctl);
1536 xsize = tv_mode->hblank_start - tv_mode->hblank_end;
1537 ysize = intel_tv_mode_vdisplay(tv_mode);
1539 xpos = conn_state->tv.margins.left;
1540 ypos = tv_conn_state->margins.top;
1541 xsize -= (conn_state->tv.margins.left +
1542 conn_state->tv.margins.right);
1543 ysize -= (tv_conn_state->margins.top +
1544 tv_conn_state->margins.bottom);
1545 intel_de_write(dev_priv, TV_WIN_POS, (xpos << 16) | ypos);
1546 intel_de_write(dev_priv, TV_WIN_SIZE, (xsize << 16) | ysize);
1549 for (i = 0; i < 60; i++)
1550 intel_de_write(dev_priv, TV_H_LUMA(i),
1551 tv_mode->filter_table[j++]);
1552 for (i = 0; i < 60; i++)
1553 intel_de_write(dev_priv, TV_H_CHROMA(i),
1554 tv_mode->filter_table[j++]);
1555 for (i = 0; i < 43; i++)
1556 intel_de_write(dev_priv, TV_V_LUMA(i),
1557 tv_mode->filter_table[j++]);
1558 for (i = 0; i < 43; i++)
1559 intel_de_write(dev_priv, TV_V_CHROMA(i),
1560 tv_mode->filter_table[j++]);
1561 intel_de_write(dev_priv, TV_DAC,
1562 intel_de_read(dev_priv, TV_DAC) & TV_DAC_SAVE);
1563 intel_de_write(dev_priv, TV_CTL, tv_ctl);
1567 intel_tv_detect_type(struct intel_tv *intel_tv,
1568 struct drm_connector *connector)
1570 struct drm_crtc *crtc = connector->state->crtc;
1571 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
1572 struct drm_device *dev = connector->dev;
1573 struct drm_i915_private *dev_priv = to_i915(dev);
1574 u32 tv_ctl, save_tv_ctl;
1575 u32 tv_dac, save_tv_dac;
1578 /* Disable TV interrupts around load detect or we'll recurse */
1579 if (connector->polled & DRM_CONNECTOR_POLL_HPD) {
1580 spin_lock_irq(&dev_priv->irq_lock);
1581 i915_disable_pipestat(dev_priv, 0,
1582 PIPE_HOTPLUG_INTERRUPT_STATUS |
1583 PIPE_HOTPLUG_TV_INTERRUPT_STATUS);
1584 spin_unlock_irq(&dev_priv->irq_lock);
1587 save_tv_dac = tv_dac = intel_de_read(dev_priv, TV_DAC);
1588 save_tv_ctl = tv_ctl = intel_de_read(dev_priv, TV_CTL);
1590 /* Poll for TV detection */
1591 tv_ctl &= ~(TV_ENC_ENABLE | TV_ENC_PIPE_SEL_MASK | TV_TEST_MODE_MASK);
1592 tv_ctl |= TV_TEST_MODE_MONITOR_DETECT;
1593 tv_ctl |= TV_ENC_PIPE_SEL(intel_crtc->pipe);
1595 tv_dac &= ~(TVDAC_SENSE_MASK | DAC_A_MASK | DAC_B_MASK | DAC_C_MASK);
1596 tv_dac |= (TVDAC_STATE_CHG_EN |
1607 * The TV sense state should be cleared to zero on cantiga platform. Otherwise
1608 * the TV is misdetected. This is hardware requirement.
1610 if (IS_GM45(dev_priv))
1611 tv_dac &= ~(TVDAC_STATE_CHG_EN | TVDAC_A_SENSE_CTL |
1612 TVDAC_B_SENSE_CTL | TVDAC_C_SENSE_CTL);
1614 intel_de_write(dev_priv, TV_CTL, tv_ctl);
1615 intel_de_write(dev_priv, TV_DAC, tv_dac);
1616 intel_de_posting_read(dev_priv, TV_DAC);
1618 intel_wait_for_vblank(dev_priv, intel_crtc->pipe);
1621 tv_dac = intel_de_read(dev_priv, TV_DAC);
1622 drm_dbg_kms(&dev_priv->drm, "TV detected: %x, %x\n", tv_ctl, tv_dac);
1629 if ((tv_dac & TVDAC_SENSE_MASK) == (TVDAC_B_SENSE | TVDAC_C_SENSE)) {
1630 drm_dbg_kms(&dev_priv->drm,
1631 "Detected Composite TV connection\n");
1632 type = DRM_MODE_CONNECTOR_Composite;
1633 } else if ((tv_dac & (TVDAC_A_SENSE|TVDAC_B_SENSE)) == TVDAC_A_SENSE) {
1634 drm_dbg_kms(&dev_priv->drm,
1635 "Detected S-Video TV connection\n");
1636 type = DRM_MODE_CONNECTOR_SVIDEO;
1637 } else if ((tv_dac & TVDAC_SENSE_MASK) == 0) {
1638 drm_dbg_kms(&dev_priv->drm,
1639 "Detected Component TV connection\n");
1640 type = DRM_MODE_CONNECTOR_Component;
1642 drm_dbg_kms(&dev_priv->drm, "Unrecognised TV connection\n");
1646 intel_de_write(dev_priv, TV_DAC, save_tv_dac & ~TVDAC_STATE_CHG_EN);
1647 intel_de_write(dev_priv, TV_CTL, save_tv_ctl);
1648 intel_de_posting_read(dev_priv, TV_CTL);
1650 /* For unknown reasons the hw barfs if we don't do this vblank wait. */
1651 intel_wait_for_vblank(dev_priv, intel_crtc->pipe);
1653 /* Restore interrupt config */
1654 if (connector->polled & DRM_CONNECTOR_POLL_HPD) {
1655 spin_lock_irq(&dev_priv->irq_lock);
1656 i915_enable_pipestat(dev_priv, 0,
1657 PIPE_HOTPLUG_INTERRUPT_STATUS |
1658 PIPE_HOTPLUG_TV_INTERRUPT_STATUS);
1659 spin_unlock_irq(&dev_priv->irq_lock);
1666 * Here we set accurate tv format according to connector type
1667 * i.e Component TV should not be assigned by NTSC or PAL
1669 static void intel_tv_find_better_format(struct drm_connector *connector)
1671 struct intel_tv *intel_tv = intel_attached_tv(to_intel_connector(connector));
1672 const struct tv_mode *tv_mode = intel_tv_mode_find(connector->state);
1675 /* Component supports everything so we can keep the current mode */
1676 if (intel_tv->type == DRM_MODE_CONNECTOR_Component)
1679 /* If the current mode is fine don't change it */
1680 if (!tv_mode->component_only)
1683 for (i = 0; i < ARRAY_SIZE(tv_modes); i++) {
1684 tv_mode = &tv_modes[i];
1686 if (!tv_mode->component_only)
1690 connector->state->tv.mode = i;
1694 intel_tv_detect(struct drm_connector *connector,
1695 struct drm_modeset_acquire_ctx *ctx,
1698 struct intel_tv *intel_tv = intel_attached_tv(to_intel_connector(connector));
1699 enum drm_connector_status status;
1702 DRM_DEBUG_KMS("[CONNECTOR:%d:%s] force=%d\n",
1703 connector->base.id, connector->name,
1707 struct intel_load_detect_pipe tmp;
1710 ret = intel_get_load_detect_pipe(connector, &tmp, ctx);
1715 type = intel_tv_detect_type(intel_tv, connector);
1716 intel_release_load_detect_pipe(connector, &tmp, ctx);
1718 connector_status_disconnected :
1719 connector_status_connected;
1721 status = connector_status_unknown;
1723 if (status == connector_status_connected) {
1724 intel_tv->type = type;
1725 intel_tv_find_better_format(connector);
1730 return connector->status;
1733 static const struct input_res {
1735 } input_res_table[] = {
1745 /* Choose preferred mode according to line number of TV format */
1747 intel_tv_is_preferred_mode(const struct drm_display_mode *mode,
1748 const struct tv_mode *tv_mode)
1750 int vdisplay = intel_tv_mode_vdisplay(tv_mode);
1752 /* prefer 480 line modes for all SD TV modes */
1753 if (vdisplay <= 576)
1756 return vdisplay == mode->vdisplay;
1760 intel_tv_set_mode_type(struct drm_display_mode *mode,
1761 const struct tv_mode *tv_mode)
1763 mode->type = DRM_MODE_TYPE_DRIVER;
1765 if (intel_tv_is_preferred_mode(mode, tv_mode))
1766 mode->type |= DRM_MODE_TYPE_PREFERRED;
1770 intel_tv_get_modes(struct drm_connector *connector)
1772 struct drm_i915_private *dev_priv = to_i915(connector->dev);
1773 const struct tv_mode *tv_mode = intel_tv_mode_find(connector->state);
1776 for (i = 0; i < ARRAY_SIZE(input_res_table); i++) {
1777 const struct input_res *input = &input_res_table[i];
1778 struct drm_display_mode *mode;
1780 if (input->w > 1024 &&
1781 !tv_mode->progressive &&
1782 !tv_mode->component_only)
1785 /* no vertical scaling with wide sources on gen3 */
1786 if (IS_GEN(dev_priv, 3) && input->w > 1024 &&
1787 input->h > intel_tv_mode_vdisplay(tv_mode))
1790 mode = drm_mode_create(connector->dev);
1795 * We take the TV mode and scale it to look
1796 * like it had the expected h/vdisplay. This
1797 * provides the most information to userspace
1798 * about the actual timings of the mode. We
1799 * do ignore the margins though.
1801 intel_tv_mode_to_mode(mode, tv_mode);
1803 drm_dbg_kms(&dev_priv->drm, "TV mode:\n");
1804 drm_mode_debug_printmodeline(mode);
1806 intel_tv_scale_mode_horiz(mode, input->w, 0, 0);
1807 intel_tv_scale_mode_vert(mode, input->h, 0, 0);
1808 intel_tv_set_mode_type(mode, tv_mode);
1810 drm_mode_set_name(mode);
1812 drm_mode_probed_add(connector, mode);
1819 static const struct drm_connector_funcs intel_tv_connector_funcs = {
1820 .late_register = intel_connector_register,
1821 .early_unregister = intel_connector_unregister,
1822 .destroy = intel_connector_destroy,
1823 .fill_modes = drm_helper_probe_single_connector_modes,
1824 .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
1825 .atomic_duplicate_state = intel_tv_connector_duplicate_state,
1828 static int intel_tv_atomic_check(struct drm_connector *connector,
1829 struct drm_atomic_state *state)
1831 struct drm_connector_state *new_state;
1832 struct drm_crtc_state *new_crtc_state;
1833 struct drm_connector_state *old_state;
1835 new_state = drm_atomic_get_new_connector_state(state, connector);
1836 if (!new_state->crtc)
1839 old_state = drm_atomic_get_old_connector_state(state, connector);
1840 new_crtc_state = drm_atomic_get_new_crtc_state(state, new_state->crtc);
1842 if (old_state->tv.mode != new_state->tv.mode ||
1843 old_state->tv.margins.left != new_state->tv.margins.left ||
1844 old_state->tv.margins.right != new_state->tv.margins.right ||
1845 old_state->tv.margins.top != new_state->tv.margins.top ||
1846 old_state->tv.margins.bottom != new_state->tv.margins.bottom) {
1847 /* Force a modeset. */
1849 new_crtc_state->connectors_changed = true;
1855 static const struct drm_connector_helper_funcs intel_tv_connector_helper_funcs = {
1856 .detect_ctx = intel_tv_detect,
1857 .mode_valid = intel_tv_mode_valid,
1858 .get_modes = intel_tv_get_modes,
1859 .atomic_check = intel_tv_atomic_check,
1862 static const struct drm_encoder_funcs intel_tv_enc_funcs = {
1863 .destroy = intel_encoder_destroy,
1867 intel_tv_init(struct drm_i915_private *dev_priv)
1869 struct drm_device *dev = &dev_priv->drm;
1870 struct drm_connector *connector;
1871 struct intel_tv *intel_tv;
1872 struct intel_encoder *intel_encoder;
1873 struct intel_connector *intel_connector;
1874 u32 tv_dac_on, tv_dac_off, save_tv_dac;
1875 const char *tv_format_names[ARRAY_SIZE(tv_modes)];
1876 int i, initial_mode = 0;
1877 struct drm_connector_state *state;
1879 if ((intel_de_read(dev_priv, TV_CTL) & TV_FUSE_STATE_MASK) == TV_FUSE_STATE_DISABLED)
1882 if (!intel_bios_is_tv_present(dev_priv)) {
1883 drm_dbg_kms(&dev_priv->drm, "Integrated TV is not present.\n");
1888 * Sanity check the TV output by checking to see if the
1889 * DAC register holds a value
1891 save_tv_dac = intel_de_read(dev_priv, TV_DAC);
1893 intel_de_write(dev_priv, TV_DAC, save_tv_dac | TVDAC_STATE_CHG_EN);
1894 tv_dac_on = intel_de_read(dev_priv, TV_DAC);
1896 intel_de_write(dev_priv, TV_DAC, save_tv_dac & ~TVDAC_STATE_CHG_EN);
1897 tv_dac_off = intel_de_read(dev_priv, TV_DAC);
1899 intel_de_write(dev_priv, TV_DAC, save_tv_dac);
1902 * If the register does not hold the state change enable
1903 * bit, (either as a 0 or a 1), assume it doesn't really
1906 if ((tv_dac_on & TVDAC_STATE_CHG_EN) == 0 ||
1907 (tv_dac_off & TVDAC_STATE_CHG_EN) != 0)
1910 intel_tv = kzalloc(sizeof(*intel_tv), GFP_KERNEL);
1915 intel_connector = intel_connector_alloc();
1916 if (!intel_connector) {
1921 intel_encoder = &intel_tv->base;
1922 connector = &intel_connector->base;
1923 state = connector->state;
1926 * The documentation, for the older chipsets at least, recommend
1927 * using a polling method rather than hotplug detection for TVs.
1928 * This is because in order to perform the hotplug detection, the PLLs
1929 * for the TV must be kept alive increasing power drain and starving
1930 * bandwidth from other encoders. Notably for instance, it causes
1931 * pipe underruns on Crestline when this encoder is supposedly idle.
1933 * More recent chipsets favour HDMI rather than integrated S-Video.
1935 intel_connector->polled = DRM_CONNECTOR_POLL_CONNECT;
1937 drm_connector_init(dev, connector, &intel_tv_connector_funcs,
1938 DRM_MODE_CONNECTOR_SVIDEO);
1940 drm_encoder_init(dev, &intel_encoder->base, &intel_tv_enc_funcs,
1941 DRM_MODE_ENCODER_TVDAC, "TV");
1943 intel_encoder->compute_config = intel_tv_compute_config;
1944 intel_encoder->get_config = intel_tv_get_config;
1945 intel_encoder->pre_enable = intel_tv_pre_enable;
1946 intel_encoder->enable = intel_enable_tv;
1947 intel_encoder->disable = intel_disable_tv;
1948 intel_encoder->get_hw_state = intel_tv_get_hw_state;
1949 intel_connector->get_hw_state = intel_connector_get_hw_state;
1951 intel_connector_attach_encoder(intel_connector, intel_encoder);
1953 intel_encoder->type = INTEL_OUTPUT_TVOUT;
1954 intel_encoder->power_domain = POWER_DOMAIN_PORT_OTHER;
1955 intel_encoder->port = PORT_NONE;
1956 intel_encoder->pipe_mask = ~0;
1957 intel_encoder->cloneable = 0;
1958 intel_tv->type = DRM_MODE_CONNECTOR_Unknown;
1960 /* BIOS margin values */
1961 state->tv.margins.left = 54;
1962 state->tv.margins.top = 36;
1963 state->tv.margins.right = 46;
1964 state->tv.margins.bottom = 37;
1966 state->tv.mode = initial_mode;
1968 drm_connector_helper_add(connector, &intel_tv_connector_helper_funcs);
1969 connector->interlace_allowed = false;
1970 connector->doublescan_allowed = false;
1972 /* Create TV properties then attach current values */
1973 for (i = 0; i < ARRAY_SIZE(tv_modes); i++) {
1974 /* 1080p50/1080p60 not supported on gen3 */
1975 if (IS_GEN(dev_priv, 3) &&
1976 tv_modes[i].oversample == 1)
1979 tv_format_names[i] = tv_modes[i].name;
1981 drm_mode_create_tv_properties(dev, i, tv_format_names);
1983 drm_object_attach_property(&connector->base, dev->mode_config.tv_mode_property,
1985 drm_object_attach_property(&connector->base,
1986 dev->mode_config.tv_left_margin_property,
1987 state->tv.margins.left);
1988 drm_object_attach_property(&connector->base,
1989 dev->mode_config.tv_top_margin_property,
1990 state->tv.margins.top);
1991 drm_object_attach_property(&connector->base,
1992 dev->mode_config.tv_right_margin_property,
1993 state->tv.margins.right);
1994 drm_object_attach_property(&connector->base,
1995 dev->mode_config.tv_bottom_margin_property,
1996 state->tv.margins.bottom);