2 * Copyright © 2006-2008 Intel Corporation
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.
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>
39 #include "intel_connector.h"
40 #include "intel_crtc.h"
42 #include "intel_display_irq.h"
43 #include "intel_display_driver.h"
44 #include "intel_display_types.h"
45 #include "intel_dpll.h"
46 #include "intel_hotplug.h"
47 #include "intel_load_detect.h"
49 #include "intel_tv_regs.h"
52 TV_MARGIN_LEFT, TV_MARGIN_TOP,
53 TV_MARGIN_RIGHT, TV_MARGIN_BOTTOM
57 struct intel_encoder base;
67 struct color_conversion {
73 static const u32 filter_table[] = {
74 0xB1403000, 0x2E203500, 0x35002E20, 0x3000B140,
75 0x35A0B160, 0x2DC02E80, 0xB1403480, 0xB1603000,
76 0x2EA03640, 0x34002D80, 0x3000B120, 0x36E0B160,
77 0x2D202EF0, 0xB1203380, 0xB1603000, 0x2F303780,
78 0x33002CC0, 0x3000B100, 0x3820B160, 0x2C802F50,
79 0xB10032A0, 0xB1603000, 0x2F9038C0, 0x32202C20,
80 0x3000B0E0, 0x3980B160, 0x2BC02FC0, 0xB0E031C0,
81 0xB1603000, 0x2FF03A20, 0x31602B60, 0xB020B0C0,
82 0x3AE0B160, 0x2B001810, 0xB0C03120, 0xB140B020,
83 0x18283BA0, 0x30C02A80, 0xB020B0A0, 0x3C60B140,
84 0x2A201838, 0xB0A03080, 0xB120B020, 0x18383D20,
85 0x304029C0, 0xB040B080, 0x3DE0B100, 0x29601848,
86 0xB0803000, 0xB100B040, 0x18483EC0, 0xB0402900,
87 0xB040B060, 0x3F80B0C0, 0x28801858, 0xB060B080,
88 0xB0A0B060, 0x18602820, 0xB0A02820, 0x0000B060,
89 0xB1403000, 0x2E203500, 0x35002E20, 0x3000B140,
90 0x35A0B160, 0x2DC02E80, 0xB1403480, 0xB1603000,
91 0x2EA03640, 0x34002D80, 0x3000B120, 0x36E0B160,
92 0x2D202EF0, 0xB1203380, 0xB1603000, 0x2F303780,
93 0x33002CC0, 0x3000B100, 0x3820B160, 0x2C802F50,
94 0xB10032A0, 0xB1603000, 0x2F9038C0, 0x32202C20,
95 0x3000B0E0, 0x3980B160, 0x2BC02FC0, 0xB0E031C0,
96 0xB1603000, 0x2FF03A20, 0x31602B60, 0xB020B0C0,
97 0x3AE0B160, 0x2B001810, 0xB0C03120, 0xB140B020,
98 0x18283BA0, 0x30C02A80, 0xB020B0A0, 0x3C60B140,
99 0x2A201838, 0xB0A03080, 0xB120B020, 0x18383D20,
100 0x304029C0, 0xB040B080, 0x3DE0B100, 0x29601848,
101 0xB0803000, 0xB100B040, 0x18483EC0, 0xB0402900,
102 0xB040B060, 0x3F80B0C0, 0x28801858, 0xB060B080,
103 0xB0A0B060, 0x18602820, 0xB0A02820, 0x0000B060,
104 0x36403000, 0x2D002CC0, 0x30003640, 0x2D0036C0,
105 0x35C02CC0, 0x37403000, 0x2C802D40, 0x30003540,
106 0x2D8037C0, 0x34C02C40, 0x38403000, 0x2BC02E00,
107 0x30003440, 0x2E2038C0, 0x34002B80, 0x39803000,
108 0x2B402E40, 0x30003380, 0x2E603A00, 0x33402B00,
109 0x3A803040, 0x2A802EA0, 0x30403300, 0x2EC03B40,
110 0x32802A40, 0x3C003040, 0x2A002EC0, 0x30803240,
111 0x2EC03C80, 0x320029C0, 0x3D403080, 0x29402F00,
112 0x308031C0, 0x2F203DC0, 0x31802900, 0x3E8030C0,
113 0x28802F40, 0x30C03140, 0x2F203F40, 0x31402840,
114 0x28003100, 0x28002F00, 0x00003100, 0x36403000,
115 0x2D002CC0, 0x30003640, 0x2D0036C0,
116 0x35C02CC0, 0x37403000, 0x2C802D40, 0x30003540,
117 0x2D8037C0, 0x34C02C40, 0x38403000, 0x2BC02E00,
118 0x30003440, 0x2E2038C0, 0x34002B80, 0x39803000,
119 0x2B402E40, 0x30003380, 0x2E603A00, 0x33402B00,
120 0x3A803040, 0x2A802EA0, 0x30403300, 0x2EC03B40,
121 0x32802A40, 0x3C003040, 0x2A002EC0, 0x30803240,
122 0x2EC03C80, 0x320029C0, 0x3D403080, 0x29402F00,
123 0x308031C0, 0x2F203DC0, 0x31802900, 0x3E8030C0,
124 0x28802F40, 0x30C03140, 0x2F203F40, 0x31402840,
125 0x28003100, 0x28002F00, 0x00003100,
129 * Color conversion values have 3 separate fixed point formats:
131 * 10 bit fields (ay, au)
132 * 1.9 fixed point (b.bbbbbbbbb)
133 * 11 bit fields (ry, by, ru, gu, gv)
134 * exp.mantissa (ee.mmmmmmmmm)
135 * ee = 00 = 10^-1 (0.mmmmmmmmm)
136 * ee = 01 = 10^-2 (0.0mmmmmmmmm)
137 * ee = 10 = 10^-3 (0.00mmmmmmmmm)
138 * ee = 11 = 10^-4 (0.000mmmmmmmmm)
139 * 12 bit fields (gy, rv, bu)
140 * exp.mantissa (eee.mmmmmmmmm)
141 * eee = 000 = 10^-1 (0.mmmmmmmmm)
142 * eee = 001 = 10^-2 (0.0mmmmmmmmm)
143 * eee = 010 = 10^-3 (0.00mmmmmmmmm)
144 * eee = 011 = 10^-4 (0.000mmmmmmmmm)
145 * eee = 100 = reserved
146 * eee = 101 = reserved
147 * eee = 110 = reserved
148 * eee = 111 = 10^0 (m.mmmmmmmm) (only usable for 1.0 representation)
150 * Saturation and contrast are 8 bits, with their own representation:
151 * 8 bit field (saturation, contrast)
152 * exp.mantissa (ee.mmmmmm)
153 * ee = 00 = 10^-1 (0.mmmmmm)
154 * ee = 01 = 10^0 (m.mmmmm)
155 * ee = 10 = 10^1 (mm.mmmm)
156 * ee = 11 = 10^2 (mmm.mmm)
158 * Simple conversion function:
161 * float_to_csc_11(float f)
174 * for (exp = 0; exp < 3 && f < 0.5; exp++)
176 * mant = (f * (1 << 9) + 0.5);
177 * if (mant >= (1 << 9))
178 * mant = (1 << 9) - 1;
180 * ret = (exp << 9) | mant;
186 * Behold, magic numbers! If we plant them they might grow a big
187 * s-video cable to the sky... or something.
189 * Pre-converted to appropriate hex value.
193 * PAL & NTSC values for composite & s-video connections
195 static const struct color_conversion ntsc_m_csc_composite = {
196 .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0104,
197 .ru = 0x0733, .gu = 0x052d, .bu = 0x05c7, .au = 0x0200,
198 .rv = 0x0340, .gv = 0x030c, .bv = 0x06d0, .av = 0x0200,
201 static const struct video_levels ntsc_m_levels_composite = {
202 .blank = 225, .black = 267, .burst = 113,
205 static const struct color_conversion ntsc_m_csc_svideo = {
206 .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0133,
207 .ru = 0x076a, .gu = 0x0564, .bu = 0x030d, .au = 0x0200,
208 .rv = 0x037a, .gv = 0x033d, .bv = 0x06f6, .av = 0x0200,
211 static const struct video_levels ntsc_m_levels_svideo = {
212 .blank = 266, .black = 316, .burst = 133,
215 static const struct color_conversion ntsc_j_csc_composite = {
216 .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0119,
217 .ru = 0x074c, .gu = 0x0546, .bu = 0x05ec, .au = 0x0200,
218 .rv = 0x035a, .gv = 0x0322, .bv = 0x06e1, .av = 0x0200,
221 static const struct video_levels ntsc_j_levels_composite = {
222 .blank = 225, .black = 225, .burst = 113,
225 static const struct color_conversion ntsc_j_csc_svideo = {
226 .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x014c,
227 .ru = 0x0788, .gu = 0x0581, .bu = 0x0322, .au = 0x0200,
228 .rv = 0x0399, .gv = 0x0356, .bv = 0x070a, .av = 0x0200,
231 static const struct video_levels ntsc_j_levels_svideo = {
232 .blank = 266, .black = 266, .burst = 133,
235 static const struct color_conversion pal_csc_composite = {
236 .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0113,
237 .ru = 0x0745, .gu = 0x053f, .bu = 0x05e1, .au = 0x0200,
238 .rv = 0x0353, .gv = 0x031c, .bv = 0x06dc, .av = 0x0200,
241 static const struct video_levels pal_levels_composite = {
242 .blank = 237, .black = 237, .burst = 118,
245 static const struct color_conversion pal_csc_svideo = {
246 .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0145,
247 .ru = 0x0780, .gu = 0x0579, .bu = 0x031c, .au = 0x0200,
248 .rv = 0x0390, .gv = 0x034f, .bv = 0x0705, .av = 0x0200,
251 static const struct video_levels pal_levels_svideo = {
252 .blank = 280, .black = 280, .burst = 139,
255 static const struct color_conversion pal_m_csc_composite = {
256 .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0104,
257 .ru = 0x0733, .gu = 0x052d, .bu = 0x05c7, .au = 0x0200,
258 .rv = 0x0340, .gv = 0x030c, .bv = 0x06d0, .av = 0x0200,
261 static const struct video_levels pal_m_levels_composite = {
262 .blank = 225, .black = 267, .burst = 113,
265 static const struct color_conversion pal_m_csc_svideo = {
266 .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0133,
267 .ru = 0x076a, .gu = 0x0564, .bu = 0x030d, .au = 0x0200,
268 .rv = 0x037a, .gv = 0x033d, .bv = 0x06f6, .av = 0x0200,
271 static const struct video_levels pal_m_levels_svideo = {
272 .blank = 266, .black = 316, .burst = 133,
275 static const struct color_conversion pal_n_csc_composite = {
276 .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0104,
277 .ru = 0x0733, .gu = 0x052d, .bu = 0x05c7, .au = 0x0200,
278 .rv = 0x0340, .gv = 0x030c, .bv = 0x06d0, .av = 0x0200,
281 static const struct video_levels pal_n_levels_composite = {
282 .blank = 225, .black = 267, .burst = 118,
285 static const struct color_conversion pal_n_csc_svideo = {
286 .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0133,
287 .ru = 0x076a, .gu = 0x0564, .bu = 0x030d, .au = 0x0200,
288 .rv = 0x037a, .gv = 0x033d, .bv = 0x06f6, .av = 0x0200,
291 static const struct video_levels pal_n_levels_svideo = {
292 .blank = 266, .black = 316, .burst = 139,
296 * Component connections
298 static const struct color_conversion sdtv_csc_yprpb = {
299 .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0145,
300 .ru = 0x0559, .gu = 0x0353, .bu = 0x0100, .au = 0x0200,
301 .rv = 0x0100, .gv = 0x03ad, .bv = 0x074d, .av = 0x0200,
304 static const struct color_conversion hdtv_csc_yprpb = {
305 .ry = 0x05b3, .gy = 0x016e, .by = 0x0728, .ay = 0x0145,
306 .ru = 0x07d5, .gu = 0x038b, .bu = 0x0100, .au = 0x0200,
307 .rv = 0x0100, .gv = 0x03d1, .bv = 0x06bc, .av = 0x0200,
310 static const struct video_levels component_levels = {
311 .blank = 279, .black = 279, .burst = 0,
319 u16 refresh; /* in millihertz (for precision) */
322 u16 hblank_start, hblank_end, htotal;
323 bool progressive : 1, trilevel_sync : 1, component_only : 1;
324 u8 vsync_start_f1, vsync_start_f2, vsync_len;
326 u8 veq_start_f1, veq_start_f2, veq_len;
327 u8 vi_end_f1, vi_end_f2;
330 u8 hburst_start, hburst_len;
340 * subcarrier programming
342 u16 dda2_size, dda3_size;
344 u16 dda2_inc, dda3_inc;
350 const struct video_levels *composite_levels, *svideo_levels;
351 const struct color_conversion *composite_color, *svideo_color;
352 const u32 *filter_table;
359 * I think this works as follows:
361 * subcarrier freq = pixel_clock * (dda1_inc + dda2_inc / dda2_size) / 4096
363 * Presumably, when dda3 is added in, it gets to adjust the dda2_inc value
366 * dda1_ideal = subcarrier/pixel * 4096
367 * dda1_inc = floor (dda1_ideal)
368 * dda2 = dda1_ideal - dda1_inc
370 * then pick a ratio for dda2 that gives the closest approximation. If
371 * you can't get close enough, you can play with dda3 as well. This
372 * seems likely to happen when dda2 is small as the jumps would be larger
376 * pixel_clock = subcarrier * 4096 / (dda1_inc + dda2_inc / dda2_size)
378 * The constants below were all computed using a 107.520MHz clock
382 * Register programming values for TV modes.
384 * These values account for -1s required.
386 static const struct tv_mode tv_modes[] = {
392 .component_only = false,
393 /* 525 Lines, 60 Fields, 15.734KHz line, Sub-Carrier 3.580MHz */
395 .hsync_end = 64, .hblank_end = 124,
396 .hblank_start = 836, .htotal = 857,
398 .progressive = false, .trilevel_sync = false,
400 .vsync_start_f1 = 6, .vsync_start_f2 = 7,
403 .veq_ena = true, .veq_start_f1 = 0,
404 .veq_start_f2 = 1, .veq_len = 18,
406 .vi_end_f1 = 20, .vi_end_f2 = 21,
410 .hburst_start = 72, .hburst_len = 34,
411 .vburst_start_f1 = 9, .vburst_end_f1 = 240,
412 .vburst_start_f2 = 10, .vburst_end_f2 = 240,
413 .vburst_start_f3 = 9, .vburst_end_f3 = 240,
414 .vburst_start_f4 = 10, .vburst_end_f4 = 240,
416 /* desired 3.5800000 actual 3.5800000 clock 107.52 */
418 .dda2_inc = 20800, .dda2_size = 27456,
419 .dda3_inc = 0, .dda3_size = 0,
420 .sc_reset = TV_SC_RESET_EVERY_4,
423 .composite_levels = &ntsc_m_levels_composite,
424 .composite_color = &ntsc_m_csc_composite,
425 .svideo_levels = &ntsc_m_levels_svideo,
426 .svideo_color = &ntsc_m_csc_svideo,
428 .filter_table = filter_table,
435 .component_only = false,
436 /* 525 Lines, 60 Fields, 15.734KHz line, Sub-Carrier 4.43MHz */
437 .hsync_end = 64, .hblank_end = 124,
438 .hblank_start = 836, .htotal = 857,
440 .progressive = false, .trilevel_sync = false,
442 .vsync_start_f1 = 6, .vsync_start_f2 = 7,
445 .veq_ena = true, .veq_start_f1 = 0,
446 .veq_start_f2 = 1, .veq_len = 18,
448 .vi_end_f1 = 20, .vi_end_f2 = 21,
452 .hburst_start = 72, .hburst_len = 34,
453 .vburst_start_f1 = 9, .vburst_end_f1 = 240,
454 .vburst_start_f2 = 10, .vburst_end_f2 = 240,
455 .vburst_start_f3 = 9, .vburst_end_f3 = 240,
456 .vburst_start_f4 = 10, .vburst_end_f4 = 240,
458 /* desired 4.4336180 actual 4.4336180 clock 107.52 */
460 .dda2_inc = 4093, .dda2_size = 27456,
461 .dda3_inc = 310, .dda3_size = 525,
462 .sc_reset = TV_SC_RESET_NEVER,
465 .composite_levels = &ntsc_m_levels_composite,
466 .composite_color = &ntsc_m_csc_composite,
467 .svideo_levels = &ntsc_m_levels_svideo,
468 .svideo_color = &ntsc_m_csc_svideo,
470 .filter_table = filter_table,
477 .component_only = false,
479 /* 525 Lines, 60 Fields, 15.734KHz line, Sub-Carrier 3.580MHz */
480 .hsync_end = 64, .hblank_end = 124,
481 .hblank_start = 836, .htotal = 857,
483 .progressive = false, .trilevel_sync = false,
485 .vsync_start_f1 = 6, .vsync_start_f2 = 7,
488 .veq_ena = true, .veq_start_f1 = 0,
489 .veq_start_f2 = 1, .veq_len = 18,
491 .vi_end_f1 = 20, .vi_end_f2 = 21,
495 .hburst_start = 72, .hburst_len = 34,
496 .vburst_start_f1 = 9, .vburst_end_f1 = 240,
497 .vburst_start_f2 = 10, .vburst_end_f2 = 240,
498 .vburst_start_f3 = 9, .vburst_end_f3 = 240,
499 .vburst_start_f4 = 10, .vburst_end_f4 = 240,
501 /* desired 3.5800000 actual 3.5800000 clock 107.52 */
503 .dda2_inc = 20800, .dda2_size = 27456,
504 .dda3_inc = 0, .dda3_size = 0,
505 .sc_reset = TV_SC_RESET_EVERY_4,
508 .composite_levels = &ntsc_j_levels_composite,
509 .composite_color = &ntsc_j_csc_composite,
510 .svideo_levels = &ntsc_j_levels_svideo,
511 .svideo_color = &ntsc_j_csc_svideo,
513 .filter_table = filter_table,
520 .component_only = false,
522 /* 525 Lines, 60 Fields, 15.734KHz line, Sub-Carrier 3.580MHz */
523 .hsync_end = 64, .hblank_end = 124,
524 .hblank_start = 836, .htotal = 857,
526 .progressive = false, .trilevel_sync = false,
528 .vsync_start_f1 = 6, .vsync_start_f2 = 7,
531 .veq_ena = true, .veq_start_f1 = 0,
532 .veq_start_f2 = 1, .veq_len = 18,
534 .vi_end_f1 = 20, .vi_end_f2 = 21,
538 .hburst_start = 72, .hburst_len = 34,
539 .vburst_start_f1 = 9, .vburst_end_f1 = 240,
540 .vburst_start_f2 = 10, .vburst_end_f2 = 240,
541 .vburst_start_f3 = 9, .vburst_end_f3 = 240,
542 .vburst_start_f4 = 10, .vburst_end_f4 = 240,
544 /* desired 3.5800000 actual 3.5800000 clock 107.52 */
546 .dda2_inc = 16704, .dda2_size = 27456,
547 .dda3_inc = 0, .dda3_size = 0,
548 .sc_reset = TV_SC_RESET_EVERY_8,
551 .composite_levels = &pal_m_levels_composite,
552 .composite_color = &pal_m_csc_composite,
553 .svideo_levels = &pal_m_levels_svideo,
554 .svideo_color = &pal_m_csc_svideo,
556 .filter_table = filter_table,
559 /* 625 Lines, 50 Fields, 15.625KHz line, Sub-Carrier 4.434MHz */
564 .component_only = false,
566 .hsync_end = 64, .hblank_end = 128,
567 .hblank_start = 844, .htotal = 863,
569 .progressive = false, .trilevel_sync = false,
572 .vsync_start_f1 = 6, .vsync_start_f2 = 7,
575 .veq_ena = true, .veq_start_f1 = 0,
576 .veq_start_f2 = 1, .veq_len = 18,
578 .vi_end_f1 = 24, .vi_end_f2 = 25,
582 .hburst_start = 73, .hburst_len = 34,
583 .vburst_start_f1 = 8, .vburst_end_f1 = 285,
584 .vburst_start_f2 = 8, .vburst_end_f2 = 286,
585 .vburst_start_f3 = 9, .vburst_end_f3 = 286,
586 .vburst_start_f4 = 9, .vburst_end_f4 = 285,
589 /* desired 4.4336180 actual 4.4336180 clock 107.52 */
591 .dda2_inc = 23578, .dda2_size = 27648,
592 .dda3_inc = 134, .dda3_size = 625,
593 .sc_reset = TV_SC_RESET_EVERY_8,
596 .composite_levels = &pal_n_levels_composite,
597 .composite_color = &pal_n_csc_composite,
598 .svideo_levels = &pal_n_levels_svideo,
599 .svideo_color = &pal_n_csc_svideo,
601 .filter_table = filter_table,
604 /* 625 Lines, 50 Fields, 15.625KHz line, Sub-Carrier 4.434MHz */
609 .component_only = false,
611 .hsync_end = 64, .hblank_end = 142,
612 .hblank_start = 844, .htotal = 863,
614 .progressive = false, .trilevel_sync = false,
616 .vsync_start_f1 = 5, .vsync_start_f2 = 6,
619 .veq_ena = true, .veq_start_f1 = 0,
620 .veq_start_f2 = 1, .veq_len = 15,
622 .vi_end_f1 = 24, .vi_end_f2 = 25,
626 .hburst_start = 73, .hburst_len = 32,
627 .vburst_start_f1 = 8, .vburst_end_f1 = 285,
628 .vburst_start_f2 = 8, .vburst_end_f2 = 286,
629 .vburst_start_f3 = 9, .vburst_end_f3 = 286,
630 .vburst_start_f4 = 9, .vburst_end_f4 = 285,
632 /* desired 4.4336180 actual 4.4336180 clock 107.52 */
634 .dda2_inc = 4122, .dda2_size = 27648,
635 .dda3_inc = 67, .dda3_size = 625,
636 .sc_reset = TV_SC_RESET_EVERY_8,
639 .composite_levels = &pal_levels_composite,
640 .composite_color = &pal_csc_composite,
641 .svideo_levels = &pal_levels_svideo,
642 .svideo_color = &pal_csc_svideo,
644 .filter_table = filter_table,
651 .component_only = true,
653 .hsync_end = 64, .hblank_end = 122,
654 .hblank_start = 842, .htotal = 857,
656 .progressive = true, .trilevel_sync = false,
658 .vsync_start_f1 = 12, .vsync_start_f2 = 12,
663 .vi_end_f1 = 44, .vi_end_f2 = 44,
668 .filter_table = filter_table,
675 .component_only = true,
677 .hsync_end = 64, .hblank_end = 139,
678 .hblank_start = 859, .htotal = 863,
680 .progressive = true, .trilevel_sync = false,
682 .vsync_start_f1 = 10, .vsync_start_f2 = 10,
687 .vi_end_f1 = 48, .vi_end_f2 = 48,
692 .filter_table = filter_table,
699 .component_only = true,
701 .hsync_end = 80, .hblank_end = 300,
702 .hblank_start = 1580, .htotal = 1649,
704 .progressive = true, .trilevel_sync = true,
706 .vsync_start_f1 = 10, .vsync_start_f2 = 10,
711 .vi_end_f1 = 29, .vi_end_f2 = 29,
716 .filter_table = filter_table,
723 .component_only = true,
725 .hsync_end = 80, .hblank_end = 300,
726 .hblank_start = 1580, .htotal = 1979,
728 .progressive = true, .trilevel_sync = true,
730 .vsync_start_f1 = 10, .vsync_start_f2 = 10,
735 .vi_end_f1 = 29, .vi_end_f2 = 29,
740 .filter_table = filter_table,
743 .name = "1080i@50Hz",
747 .component_only = true,
749 .hsync_end = 88, .hblank_end = 235,
750 .hblank_start = 2155, .htotal = 2639,
752 .progressive = false, .trilevel_sync = true,
754 .vsync_start_f1 = 4, .vsync_start_f2 = 5,
757 .veq_ena = true, .veq_start_f1 = 4,
758 .veq_start_f2 = 4, .veq_len = 10,
761 .vi_end_f1 = 21, .vi_end_f2 = 22,
766 .filter_table = filter_table,
769 .name = "1080i@60Hz",
773 .component_only = true,
775 .hsync_end = 88, .hblank_end = 235,
776 .hblank_start = 2155, .htotal = 2199,
778 .progressive = false, .trilevel_sync = true,
780 .vsync_start_f1 = 4, .vsync_start_f2 = 5,
783 .veq_ena = true, .veq_start_f1 = 4,
784 .veq_start_f2 = 4, .veq_len = 10,
787 .vi_end_f1 = 21, .vi_end_f2 = 22,
792 .filter_table = filter_table,
796 .name = "1080p@30Hz",
800 .component_only = true,
802 .hsync_end = 88, .hblank_end = 235,
803 .hblank_start = 2155, .htotal = 2199,
805 .progressive = true, .trilevel_sync = true,
807 .vsync_start_f1 = 8, .vsync_start_f2 = 8,
810 .veq_ena = false, .veq_start_f1 = 0,
811 .veq_start_f2 = 0, .veq_len = 0,
813 .vi_end_f1 = 44, .vi_end_f2 = 44,
818 .filter_table = filter_table,
822 .name = "1080p@50Hz",
826 .component_only = true,
828 .hsync_end = 88, .hblank_end = 235,
829 .hblank_start = 2155, .htotal = 2639,
831 .progressive = true, .trilevel_sync = true,
833 .vsync_start_f1 = 8, .vsync_start_f2 = 8,
836 .veq_ena = false, .veq_start_f1 = 0,
837 .veq_start_f2 = 0, .veq_len = 0,
839 .vi_end_f1 = 44, .vi_end_f2 = 44,
844 .filter_table = filter_table,
848 .name = "1080p@60Hz",
852 .component_only = true,
854 .hsync_end = 88, .hblank_end = 235,
855 .hblank_start = 2155, .htotal = 2199,
857 .progressive = true, .trilevel_sync = true,
859 .vsync_start_f1 = 8, .vsync_start_f2 = 8,
862 .veq_ena = false, .veq_start_f1 = 0,
863 .veq_start_f2 = 0, .veq_len = 0,
865 .vi_end_f1 = 44, .vi_end_f2 = 44,
870 .filter_table = filter_table,
874 struct intel_tv_connector_state {
875 struct drm_connector_state base;
878 * May need to override the user margins for
879 * gen3 >1024 wide source vertical centering.
888 #define to_intel_tv_connector_state(conn_state) \
889 container_of_const((conn_state), struct intel_tv_connector_state, base)
891 static struct drm_connector_state *
892 intel_tv_connector_duplicate_state(struct drm_connector *connector)
894 struct intel_tv_connector_state *state;
896 state = kmemdup(connector->state, sizeof(*state), GFP_KERNEL);
900 __drm_atomic_helper_connector_duplicate_state(connector, &state->base);
904 static struct intel_tv *enc_to_tv(struct intel_encoder *encoder)
906 return container_of(encoder, struct intel_tv, base);
909 static struct intel_tv *intel_attached_tv(struct intel_connector *connector)
911 return enc_to_tv(intel_attached_encoder(connector));
915 intel_tv_get_hw_state(struct intel_encoder *encoder, enum pipe *pipe)
917 struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
918 u32 tmp = intel_de_read(dev_priv, TV_CTL);
920 *pipe = (tmp & TV_ENC_PIPE_SEL_MASK) >> TV_ENC_PIPE_SEL_SHIFT;
922 return tmp & TV_ENC_ENABLE;
926 intel_enable_tv(struct intel_atomic_state *state,
927 struct intel_encoder *encoder,
928 const struct intel_crtc_state *pipe_config,
929 const struct drm_connector_state *conn_state)
931 struct drm_device *dev = encoder->base.dev;
932 struct drm_i915_private *dev_priv = to_i915(dev);
934 /* Prevents vblank waits from timing out in intel_tv_detect_type() */
935 intel_crtc_wait_for_next_vblank(to_intel_crtc(pipe_config->uapi.crtc));
937 intel_de_rmw(dev_priv, TV_CTL, 0, TV_ENC_ENABLE);
941 intel_disable_tv(struct intel_atomic_state *state,
942 struct intel_encoder *encoder,
943 const struct intel_crtc_state *old_crtc_state,
944 const struct drm_connector_state *old_conn_state)
946 struct drm_device *dev = encoder->base.dev;
947 struct drm_i915_private *dev_priv = to_i915(dev);
949 intel_de_rmw(dev_priv, TV_CTL, TV_ENC_ENABLE, 0);
952 static const struct tv_mode *intel_tv_mode_find(const struct drm_connector_state *conn_state)
954 int format = conn_state->tv.legacy_mode;
956 return &tv_modes[format];
959 static enum drm_mode_status
960 intel_tv_mode_valid(struct drm_connector *connector,
961 struct drm_display_mode *mode)
963 struct drm_i915_private *i915 = to_i915(connector->dev);
964 const struct tv_mode *tv_mode = intel_tv_mode_find(connector->state);
965 int max_dotclk = i915->display.cdclk.max_dotclk_freq;
966 enum drm_mode_status status;
968 status = intel_cpu_transcoder_mode_valid(i915, mode);
969 if (status != MODE_OK)
972 if (mode->clock > max_dotclk)
973 return MODE_CLOCK_HIGH;
975 /* Ensure TV refresh is close to desired refresh */
976 if (abs(tv_mode->refresh - drm_mode_vrefresh(mode) * 1000) >= 1000)
977 return MODE_CLOCK_RANGE;
983 intel_tv_mode_vdisplay(const struct tv_mode *tv_mode)
985 if (tv_mode->progressive)
986 return tv_mode->nbr_end + 1;
988 return 2 * (tv_mode->nbr_end + 1);
992 intel_tv_mode_to_mode(struct drm_display_mode *mode,
993 const struct tv_mode *tv_mode,
996 mode->clock = clock / (tv_mode->oversample >> !tv_mode->progressive);
999 * tv_mode horizontal timings:
1010 tv_mode->hblank_start - tv_mode->hblank_end;
1011 mode->hsync_start = mode->hdisplay +
1012 tv_mode->htotal - tv_mode->hblank_start;
1013 mode->hsync_end = mode->hsync_start +
1015 mode->htotal = tv_mode->htotal + 1;
1018 * tv_mode vertical timings:
1022 * | | vi_end nbr_end
1028 mode->vdisplay = intel_tv_mode_vdisplay(tv_mode);
1029 if (tv_mode->progressive) {
1030 mode->vsync_start = mode->vdisplay +
1031 tv_mode->vsync_start_f1 + 1;
1032 mode->vsync_end = mode->vsync_start +
1034 mode->vtotal = mode->vdisplay +
1035 tv_mode->vi_end_f1 + 1;
1037 mode->vsync_start = mode->vdisplay +
1038 tv_mode->vsync_start_f1 + 1 +
1039 tv_mode->vsync_start_f2 + 1;
1040 mode->vsync_end = mode->vsync_start +
1041 2 * tv_mode->vsync_len;
1042 mode->vtotal = mode->vdisplay +
1043 tv_mode->vi_end_f1 + 1 +
1044 tv_mode->vi_end_f2 + 1;
1047 /* TV has it's own notion of sync and other mode flags, so clear them. */
1050 snprintf(mode->name, sizeof(mode->name),
1052 mode->hdisplay, mode->vdisplay,
1053 tv_mode->progressive ? 'p' : 'i',
1057 static void intel_tv_scale_mode_horiz(struct drm_display_mode *mode,
1058 int hdisplay, int left_margin,
1061 int hsync_start = mode->hsync_start - mode->hdisplay + right_margin;
1062 int hsync_end = mode->hsync_end - mode->hdisplay + right_margin;
1063 int new_htotal = mode->htotal * hdisplay /
1064 (mode->hdisplay - left_margin - right_margin);
1066 mode->clock = mode->clock * new_htotal / mode->htotal;
1068 mode->hdisplay = hdisplay;
1069 mode->hsync_start = hdisplay + hsync_start * new_htotal / mode->htotal;
1070 mode->hsync_end = hdisplay + hsync_end * new_htotal / mode->htotal;
1071 mode->htotal = new_htotal;
1074 static void intel_tv_scale_mode_vert(struct drm_display_mode *mode,
1075 int vdisplay, int top_margin,
1078 int vsync_start = mode->vsync_start - mode->vdisplay + bottom_margin;
1079 int vsync_end = mode->vsync_end - mode->vdisplay + bottom_margin;
1080 int new_vtotal = mode->vtotal * vdisplay /
1081 (mode->vdisplay - top_margin - bottom_margin);
1083 mode->clock = mode->clock * new_vtotal / mode->vtotal;
1085 mode->vdisplay = vdisplay;
1086 mode->vsync_start = vdisplay + vsync_start * new_vtotal / mode->vtotal;
1087 mode->vsync_end = vdisplay + vsync_end * new_vtotal / mode->vtotal;
1088 mode->vtotal = new_vtotal;
1092 intel_tv_get_config(struct intel_encoder *encoder,
1093 struct intel_crtc_state *pipe_config)
1095 struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
1096 struct drm_display_mode *adjusted_mode =
1097 &pipe_config->hw.adjusted_mode;
1098 struct drm_display_mode mode = {};
1099 u32 tv_ctl, hctl1, hctl3, vctl1, vctl2, tmp;
1100 struct tv_mode tv_mode = {};
1101 int hdisplay = adjusted_mode->crtc_hdisplay;
1102 int vdisplay = adjusted_mode->crtc_vdisplay;
1103 int xsize, ysize, xpos, ypos;
1105 pipe_config->output_types |= BIT(INTEL_OUTPUT_TVOUT);
1107 tv_ctl = intel_de_read(dev_priv, TV_CTL);
1108 hctl1 = intel_de_read(dev_priv, TV_H_CTL_1);
1109 hctl3 = intel_de_read(dev_priv, TV_H_CTL_3);
1110 vctl1 = intel_de_read(dev_priv, TV_V_CTL_1);
1111 vctl2 = intel_de_read(dev_priv, TV_V_CTL_2);
1113 tv_mode.htotal = (hctl1 & TV_HTOTAL_MASK) >> TV_HTOTAL_SHIFT;
1114 tv_mode.hsync_end = (hctl1 & TV_HSYNC_END_MASK) >> TV_HSYNC_END_SHIFT;
1116 tv_mode.hblank_start = (hctl3 & TV_HBLANK_START_MASK) >> TV_HBLANK_START_SHIFT;
1117 tv_mode.hblank_end = (hctl3 & TV_HSYNC_END_MASK) >> TV_HBLANK_END_SHIFT;
1119 tv_mode.nbr_end = (vctl1 & TV_NBR_END_MASK) >> TV_NBR_END_SHIFT;
1120 tv_mode.vi_end_f1 = (vctl1 & TV_VI_END_F1_MASK) >> TV_VI_END_F1_SHIFT;
1121 tv_mode.vi_end_f2 = (vctl1 & TV_VI_END_F2_MASK) >> TV_VI_END_F2_SHIFT;
1123 tv_mode.vsync_len = (vctl2 & TV_VSYNC_LEN_MASK) >> TV_VSYNC_LEN_SHIFT;
1124 tv_mode.vsync_start_f1 = (vctl2 & TV_VSYNC_START_F1_MASK) >> TV_VSYNC_START_F1_SHIFT;
1125 tv_mode.vsync_start_f2 = (vctl2 & TV_VSYNC_START_F2_MASK) >> TV_VSYNC_START_F2_SHIFT;
1127 tv_mode.clock = pipe_config->port_clock;
1129 tv_mode.progressive = tv_ctl & TV_PROGRESSIVE;
1131 switch (tv_ctl & TV_OVERSAMPLE_MASK) {
1132 case TV_OVERSAMPLE_8X:
1133 tv_mode.oversample = 8;
1135 case TV_OVERSAMPLE_4X:
1136 tv_mode.oversample = 4;
1138 case TV_OVERSAMPLE_2X:
1139 tv_mode.oversample = 2;
1142 tv_mode.oversample = 1;
1146 tmp = intel_de_read(dev_priv, TV_WIN_POS);
1148 ypos = tmp & 0xffff;
1150 tmp = intel_de_read(dev_priv, TV_WIN_SIZE);
1152 ysize = tmp & 0xffff;
1154 intel_tv_mode_to_mode(&mode, &tv_mode, pipe_config->port_clock);
1156 drm_dbg_kms(&dev_priv->drm, "TV mode: " DRM_MODE_FMT "\n",
1157 DRM_MODE_ARG(&mode));
1159 intel_tv_scale_mode_horiz(&mode, hdisplay,
1160 xpos, mode.hdisplay - xsize - xpos);
1161 intel_tv_scale_mode_vert(&mode, vdisplay,
1162 ypos, mode.vdisplay - ysize - ypos);
1164 adjusted_mode->crtc_clock = mode.clock;
1165 if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE)
1166 adjusted_mode->crtc_clock /= 2;
1168 /* pixel counter doesn't work on i965gm TV output */
1169 if (IS_I965GM(dev_priv))
1170 pipe_config->mode_flags |=
1171 I915_MODE_FLAG_USE_SCANLINE_COUNTER;
1174 static bool intel_tv_source_too_wide(struct drm_i915_private *dev_priv,
1177 return DISPLAY_VER(dev_priv) == 3 && hdisplay > 1024;
1180 static bool intel_tv_vert_scaling(const struct drm_display_mode *tv_mode,
1181 const struct drm_connector_state *conn_state,
1184 return tv_mode->crtc_vdisplay -
1185 conn_state->tv.margins.top -
1186 conn_state->tv.margins.bottom !=
1191 intel_tv_compute_config(struct intel_encoder *encoder,
1192 struct intel_crtc_state *pipe_config,
1193 struct drm_connector_state *conn_state)
1195 struct intel_atomic_state *state =
1196 to_intel_atomic_state(pipe_config->uapi.state);
1197 struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc);
1198 struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
1199 struct intel_tv_connector_state *tv_conn_state =
1200 to_intel_tv_connector_state(conn_state);
1201 const struct tv_mode *tv_mode = intel_tv_mode_find(conn_state);
1202 struct drm_display_mode *adjusted_mode =
1203 &pipe_config->hw.adjusted_mode;
1204 int hdisplay = adjusted_mode->crtc_hdisplay;
1205 int vdisplay = adjusted_mode->crtc_vdisplay;
1211 if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN)
1214 pipe_config->sink_format = INTEL_OUTPUT_FORMAT_RGB;
1215 pipe_config->output_format = INTEL_OUTPUT_FORMAT_RGB;
1217 drm_dbg_kms(&dev_priv->drm, "forcing bpc to 8 for TV\n");
1218 pipe_config->pipe_bpp = 8*3;
1220 pipe_config->port_clock = tv_mode->clock;
1222 ret = intel_dpll_crtc_compute_clock(state, crtc);
1226 pipe_config->clock_set = true;
1228 intel_tv_mode_to_mode(adjusted_mode, tv_mode, pipe_config->port_clock);
1229 drm_mode_set_crtcinfo(adjusted_mode, 0);
1231 if (intel_tv_source_too_wide(dev_priv, hdisplay) ||
1232 !intel_tv_vert_scaling(adjusted_mode, conn_state, vdisplay)) {
1233 int extra, top, bottom;
1235 extra = adjusted_mode->crtc_vdisplay - vdisplay;
1238 drm_dbg_kms(&dev_priv->drm,
1239 "No vertical scaling for >1024 pixel wide modes\n");
1243 /* Need to turn off the vertical filter and center the image */
1245 /* Attempt to maintain the relative sizes of the margins */
1246 top = conn_state->tv.margins.top;
1247 bottom = conn_state->tv.margins.bottom;
1250 top = extra * top / (top + bottom);
1253 bottom = extra - top;
1255 tv_conn_state->margins.top = top;
1256 tv_conn_state->margins.bottom = bottom;
1258 tv_conn_state->bypass_vfilter = true;
1260 if (!tv_mode->progressive) {
1261 adjusted_mode->clock /= 2;
1262 adjusted_mode->crtc_clock /= 2;
1263 adjusted_mode->flags |= DRM_MODE_FLAG_INTERLACE;
1266 tv_conn_state->margins.top = conn_state->tv.margins.top;
1267 tv_conn_state->margins.bottom = conn_state->tv.margins.bottom;
1269 tv_conn_state->bypass_vfilter = false;
1272 drm_dbg_kms(&dev_priv->drm, "TV mode: " DRM_MODE_FMT "\n",
1273 DRM_MODE_ARG(adjusted_mode));
1276 * The pipe scanline counter behaviour looks as follows when
1277 * using the TV encoder:
1286 * dsl=0 ___/ |_____/ |
1289 * | | | | pipe vblank/first part of tv vblank
1290 * | | | bottom margin
1293 * remainder of tv vblank
1295 * When the TV encoder is used the pipe wants to run faster
1296 * than expected rate. During the active portion the TV
1297 * encoder stalls the pipe every few lines to keep it in
1298 * check. When the TV encoder reaches the bottom margin the
1299 * pipe simply stops. Once we reach the TV vblank the pipe is
1300 * no longer stalled and it runs at the max rate (apparently
1301 * oversample clock on gen3, cdclk on gen4). Once the pipe
1302 * reaches the pipe vtotal the pipe stops for the remainder
1303 * of the TV vblank/top margin. The pipe starts up again when
1304 * the TV encoder exits the top margin.
1306 * To avoid huge hassles for vblank timestamping we scale
1307 * the pipe timings as if the pipe always runs at the average
1308 * rate it maintains during the active period. This also
1309 * gives us a reasonable guesstimate as to the pixel rate.
1310 * Due to the variation in the actual pipe speed the scanline
1311 * counter will give us slightly erroneous results during the
1312 * TV vblank/margins. But since vtotal was selected such that
1313 * it matches the average rate of the pipe during the active
1314 * portion the error shouldn't cause any serious grief to
1315 * vblank timestamps.
1317 * For posterity here is the empirically derived formula
1318 * that gives us the maximum length of the pipe vblank
1319 * we can use without causing display corruption. Following
1320 * this would allow us to have a ticking scanline counter
1321 * everywhere except during the bottom margin (there the
1322 * pipe always stops). Ie. this would eliminate the second
1323 * flat portion of the above graph. However this would also
1324 * complicate vblank timestamping as the pipe vtotal would
1325 * no longer match the average rate the pipe runs at during
1326 * the active portion. Hence following this formula seems
1327 * more trouble that it's worth.
1329 * if (DISPLAY_VER(dev_priv) == 4) {
1330 * num = cdclk * (tv_mode->oversample >> !tv_mode->progressive);
1331 * den = tv_mode->clock;
1333 * num = tv_mode->oversample >> !tv_mode->progressive;
1336 * max_pipe_vblank_len ~=
1337 * (num * tv_htotal * (tv_vblank_len + top_margin)) /
1338 * (den * pipe_htotal);
1340 intel_tv_scale_mode_horiz(adjusted_mode, hdisplay,
1341 conn_state->tv.margins.left,
1342 conn_state->tv.margins.right);
1343 intel_tv_scale_mode_vert(adjusted_mode, vdisplay,
1344 tv_conn_state->margins.top,
1345 tv_conn_state->margins.bottom);
1346 drm_mode_set_crtcinfo(adjusted_mode, 0);
1347 adjusted_mode->name[0] = '\0';
1349 /* pixel counter doesn't work on i965gm TV output */
1350 if (IS_I965GM(dev_priv))
1351 pipe_config->mode_flags |=
1352 I915_MODE_FLAG_USE_SCANLINE_COUNTER;
1358 set_tv_mode_timings(struct drm_i915_private *dev_priv,
1359 const struct tv_mode *tv_mode,
1362 u32 hctl1, hctl2, hctl3;
1363 u32 vctl1, vctl2, vctl3, vctl4, vctl5, vctl6, vctl7;
1365 hctl1 = (tv_mode->hsync_end << TV_HSYNC_END_SHIFT) |
1366 (tv_mode->htotal << TV_HTOTAL_SHIFT);
1368 hctl2 = (tv_mode->hburst_start << 16) |
1369 (tv_mode->hburst_len << TV_HBURST_LEN_SHIFT);
1372 hctl2 |= TV_BURST_ENA;
1374 hctl3 = (tv_mode->hblank_start << TV_HBLANK_START_SHIFT) |
1375 (tv_mode->hblank_end << TV_HBLANK_END_SHIFT);
1377 vctl1 = (tv_mode->nbr_end << TV_NBR_END_SHIFT) |
1378 (tv_mode->vi_end_f1 << TV_VI_END_F1_SHIFT) |
1379 (tv_mode->vi_end_f2 << TV_VI_END_F2_SHIFT);
1381 vctl2 = (tv_mode->vsync_len << TV_VSYNC_LEN_SHIFT) |
1382 (tv_mode->vsync_start_f1 << TV_VSYNC_START_F1_SHIFT) |
1383 (tv_mode->vsync_start_f2 << TV_VSYNC_START_F2_SHIFT);
1385 vctl3 = (tv_mode->veq_len << TV_VEQ_LEN_SHIFT) |
1386 (tv_mode->veq_start_f1 << TV_VEQ_START_F1_SHIFT) |
1387 (tv_mode->veq_start_f2 << TV_VEQ_START_F2_SHIFT);
1389 if (tv_mode->veq_ena)
1390 vctl3 |= TV_EQUAL_ENA;
1392 vctl4 = (tv_mode->vburst_start_f1 << TV_VBURST_START_F1_SHIFT) |
1393 (tv_mode->vburst_end_f1 << TV_VBURST_END_F1_SHIFT);
1395 vctl5 = (tv_mode->vburst_start_f2 << TV_VBURST_START_F2_SHIFT) |
1396 (tv_mode->vburst_end_f2 << TV_VBURST_END_F2_SHIFT);
1398 vctl6 = (tv_mode->vburst_start_f3 << TV_VBURST_START_F3_SHIFT) |
1399 (tv_mode->vburst_end_f3 << TV_VBURST_END_F3_SHIFT);
1401 vctl7 = (tv_mode->vburst_start_f4 << TV_VBURST_START_F4_SHIFT) |
1402 (tv_mode->vburst_end_f4 << TV_VBURST_END_F4_SHIFT);
1404 intel_de_write(dev_priv, TV_H_CTL_1, hctl1);
1405 intel_de_write(dev_priv, TV_H_CTL_2, hctl2);
1406 intel_de_write(dev_priv, TV_H_CTL_3, hctl3);
1407 intel_de_write(dev_priv, TV_V_CTL_1, vctl1);
1408 intel_de_write(dev_priv, TV_V_CTL_2, vctl2);
1409 intel_de_write(dev_priv, TV_V_CTL_3, vctl3);
1410 intel_de_write(dev_priv, TV_V_CTL_4, vctl4);
1411 intel_de_write(dev_priv, TV_V_CTL_5, vctl5);
1412 intel_de_write(dev_priv, TV_V_CTL_6, vctl6);
1413 intel_de_write(dev_priv, TV_V_CTL_7, vctl7);
1416 static void set_color_conversion(struct drm_i915_private *dev_priv,
1417 const struct color_conversion *color_conversion)
1419 intel_de_write(dev_priv, TV_CSC_Y,
1420 (color_conversion->ry << 16) | color_conversion->gy);
1421 intel_de_write(dev_priv, TV_CSC_Y2,
1422 (color_conversion->by << 16) | color_conversion->ay);
1423 intel_de_write(dev_priv, TV_CSC_U,
1424 (color_conversion->ru << 16) | color_conversion->gu);
1425 intel_de_write(dev_priv, TV_CSC_U2,
1426 (color_conversion->bu << 16) | color_conversion->au);
1427 intel_de_write(dev_priv, TV_CSC_V,
1428 (color_conversion->rv << 16) | color_conversion->gv);
1429 intel_de_write(dev_priv, TV_CSC_V2,
1430 (color_conversion->bv << 16) | color_conversion->av);
1433 static void intel_tv_pre_enable(struct intel_atomic_state *state,
1434 struct intel_encoder *encoder,
1435 const struct intel_crtc_state *pipe_config,
1436 const struct drm_connector_state *conn_state)
1438 struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
1439 struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc);
1440 struct intel_tv *intel_tv = enc_to_tv(encoder);
1441 const struct intel_tv_connector_state *tv_conn_state =
1442 to_intel_tv_connector_state(conn_state);
1443 const struct tv_mode *tv_mode = intel_tv_mode_find(conn_state);
1444 u32 tv_ctl, tv_filter_ctl;
1445 u32 scctl1, scctl2, scctl3;
1447 const struct video_levels *video_levels;
1448 const struct color_conversion *color_conversion;
1451 unsigned int xsize, ysize;
1453 tv_ctl = intel_de_read(dev_priv, TV_CTL);
1454 tv_ctl &= TV_CTL_SAVE;
1456 switch (intel_tv->type) {
1458 case DRM_MODE_CONNECTOR_Unknown:
1459 case DRM_MODE_CONNECTOR_Composite:
1460 tv_ctl |= TV_ENC_OUTPUT_COMPOSITE;
1461 video_levels = tv_mode->composite_levels;
1462 color_conversion = tv_mode->composite_color;
1463 burst_ena = tv_mode->burst_ena;
1465 case DRM_MODE_CONNECTOR_Component:
1466 tv_ctl |= TV_ENC_OUTPUT_COMPONENT;
1467 video_levels = &component_levels;
1468 if (tv_mode->burst_ena)
1469 color_conversion = &sdtv_csc_yprpb;
1471 color_conversion = &hdtv_csc_yprpb;
1474 case DRM_MODE_CONNECTOR_SVIDEO:
1475 tv_ctl |= TV_ENC_OUTPUT_SVIDEO;
1476 video_levels = tv_mode->svideo_levels;
1477 color_conversion = tv_mode->svideo_color;
1478 burst_ena = tv_mode->burst_ena;
1482 tv_ctl |= TV_ENC_PIPE_SEL(crtc->pipe);
1484 switch (tv_mode->oversample) {
1486 tv_ctl |= TV_OVERSAMPLE_8X;
1489 tv_ctl |= TV_OVERSAMPLE_4X;
1492 tv_ctl |= TV_OVERSAMPLE_2X;
1495 tv_ctl |= TV_OVERSAMPLE_NONE;
1499 if (tv_mode->progressive)
1500 tv_ctl |= TV_PROGRESSIVE;
1501 if (tv_mode->trilevel_sync)
1502 tv_ctl |= TV_TRILEVEL_SYNC;
1503 if (tv_mode->pal_burst)
1504 tv_ctl |= TV_PAL_BURST;
1507 if (tv_mode->dda1_inc)
1508 scctl1 |= TV_SC_DDA1_EN;
1509 if (tv_mode->dda2_inc)
1510 scctl1 |= TV_SC_DDA2_EN;
1511 if (tv_mode->dda3_inc)
1512 scctl1 |= TV_SC_DDA3_EN;
1513 scctl1 |= tv_mode->sc_reset;
1515 scctl1 |= video_levels->burst << TV_BURST_LEVEL_SHIFT;
1516 scctl1 |= tv_mode->dda1_inc << TV_SCDDA1_INC_SHIFT;
1518 scctl2 = tv_mode->dda2_size << TV_SCDDA2_SIZE_SHIFT |
1519 tv_mode->dda2_inc << TV_SCDDA2_INC_SHIFT;
1521 scctl3 = tv_mode->dda3_size << TV_SCDDA3_SIZE_SHIFT |
1522 tv_mode->dda3_inc << TV_SCDDA3_INC_SHIFT;
1524 /* Enable two fixes for the chips that need them. */
1525 if (IS_I915GM(dev_priv))
1526 tv_ctl |= TV_ENC_C0_FIX | TV_ENC_SDP_FIX;
1528 set_tv_mode_timings(dev_priv, tv_mode, burst_ena);
1530 intel_de_write(dev_priv, TV_SC_CTL_1, scctl1);
1531 intel_de_write(dev_priv, TV_SC_CTL_2, scctl2);
1532 intel_de_write(dev_priv, TV_SC_CTL_3, scctl3);
1534 set_color_conversion(dev_priv, color_conversion);
1536 if (DISPLAY_VER(dev_priv) >= 4)
1537 intel_de_write(dev_priv, TV_CLR_KNOBS, 0x00404000);
1539 intel_de_write(dev_priv, TV_CLR_KNOBS, 0x00606000);
1542 intel_de_write(dev_priv, TV_CLR_LEVEL,
1543 ((video_levels->black << TV_BLACK_LEVEL_SHIFT) | (video_levels->blank << TV_BLANK_LEVEL_SHIFT)));
1545 assert_transcoder_disabled(dev_priv, pipe_config->cpu_transcoder);
1547 /* Filter ctl must be set before TV_WIN_SIZE */
1548 tv_filter_ctl = TV_AUTO_SCALE;
1549 if (tv_conn_state->bypass_vfilter)
1550 tv_filter_ctl |= TV_V_FILTER_BYPASS;
1551 intel_de_write(dev_priv, TV_FILTER_CTL_1, tv_filter_ctl);
1553 xsize = tv_mode->hblank_start - tv_mode->hblank_end;
1554 ysize = intel_tv_mode_vdisplay(tv_mode);
1556 xpos = conn_state->tv.margins.left;
1557 ypos = tv_conn_state->margins.top;
1558 xsize -= (conn_state->tv.margins.left +
1559 conn_state->tv.margins.right);
1560 ysize -= (tv_conn_state->margins.top +
1561 tv_conn_state->margins.bottom);
1562 intel_de_write(dev_priv, TV_WIN_POS, (xpos << 16) | ypos);
1563 intel_de_write(dev_priv, TV_WIN_SIZE, (xsize << 16) | ysize);
1566 for (i = 0; i < 60; i++)
1567 intel_de_write(dev_priv, TV_H_LUMA(i),
1568 tv_mode->filter_table[j++]);
1569 for (i = 0; i < 60; i++)
1570 intel_de_write(dev_priv, TV_H_CHROMA(i),
1571 tv_mode->filter_table[j++]);
1572 for (i = 0; i < 43; i++)
1573 intel_de_write(dev_priv, TV_V_LUMA(i),
1574 tv_mode->filter_table[j++]);
1575 for (i = 0; i < 43; i++)
1576 intel_de_write(dev_priv, TV_V_CHROMA(i),
1577 tv_mode->filter_table[j++]);
1578 intel_de_write(dev_priv, TV_DAC,
1579 intel_de_read(dev_priv, TV_DAC) & TV_DAC_SAVE);
1580 intel_de_write(dev_priv, TV_CTL, tv_ctl);
1584 intel_tv_detect_type(struct intel_tv *intel_tv,
1585 struct drm_connector *connector)
1587 struct intel_crtc *crtc = to_intel_crtc(connector->state->crtc);
1588 struct drm_device *dev = connector->dev;
1589 struct drm_i915_private *dev_priv = to_i915(dev);
1590 u32 tv_ctl, save_tv_ctl;
1591 u32 tv_dac, save_tv_dac;
1594 /* Disable TV interrupts around load detect or we'll recurse */
1595 if (connector->polled & DRM_CONNECTOR_POLL_HPD) {
1596 spin_lock_irq(&dev_priv->irq_lock);
1597 i915_disable_pipestat(dev_priv, 0,
1598 PIPE_HOTPLUG_INTERRUPT_STATUS |
1599 PIPE_HOTPLUG_TV_INTERRUPT_STATUS);
1600 spin_unlock_irq(&dev_priv->irq_lock);
1603 save_tv_dac = tv_dac = intel_de_read(dev_priv, TV_DAC);
1604 save_tv_ctl = tv_ctl = intel_de_read(dev_priv, TV_CTL);
1606 /* Poll for TV detection */
1607 tv_ctl &= ~(TV_ENC_ENABLE | TV_ENC_PIPE_SEL_MASK | TV_TEST_MODE_MASK);
1608 tv_ctl |= TV_TEST_MODE_MONITOR_DETECT;
1609 tv_ctl |= TV_ENC_PIPE_SEL(crtc->pipe);
1611 tv_dac &= ~(TVDAC_SENSE_MASK | DAC_A_MASK | DAC_B_MASK | DAC_C_MASK);
1612 tv_dac |= (TVDAC_STATE_CHG_EN |
1623 * The TV sense state should be cleared to zero on cantiga platform. Otherwise
1624 * the TV is misdetected. This is hardware requirement.
1626 if (IS_GM45(dev_priv))
1627 tv_dac &= ~(TVDAC_STATE_CHG_EN | TVDAC_A_SENSE_CTL |
1628 TVDAC_B_SENSE_CTL | TVDAC_C_SENSE_CTL);
1630 intel_de_write(dev_priv, TV_CTL, tv_ctl);
1631 intel_de_write(dev_priv, TV_DAC, tv_dac);
1632 intel_de_posting_read(dev_priv, TV_DAC);
1634 intel_crtc_wait_for_next_vblank(crtc);
1637 tv_dac = intel_de_read(dev_priv, TV_DAC);
1638 drm_dbg_kms(&dev_priv->drm, "TV detected: %x, %x\n", tv_ctl, tv_dac);
1645 if ((tv_dac & TVDAC_SENSE_MASK) == (TVDAC_B_SENSE | TVDAC_C_SENSE)) {
1646 drm_dbg_kms(&dev_priv->drm,
1647 "Detected Composite TV connection\n");
1648 type = DRM_MODE_CONNECTOR_Composite;
1649 } else if ((tv_dac & (TVDAC_A_SENSE|TVDAC_B_SENSE)) == TVDAC_A_SENSE) {
1650 drm_dbg_kms(&dev_priv->drm,
1651 "Detected S-Video TV connection\n");
1652 type = DRM_MODE_CONNECTOR_SVIDEO;
1653 } else if ((tv_dac & TVDAC_SENSE_MASK) == 0) {
1654 drm_dbg_kms(&dev_priv->drm,
1655 "Detected Component TV connection\n");
1656 type = DRM_MODE_CONNECTOR_Component;
1658 drm_dbg_kms(&dev_priv->drm, "Unrecognised TV connection\n");
1662 intel_de_write(dev_priv, TV_DAC, save_tv_dac & ~TVDAC_STATE_CHG_EN);
1663 intel_de_write(dev_priv, TV_CTL, save_tv_ctl);
1664 intel_de_posting_read(dev_priv, TV_CTL);
1666 /* For unknown reasons the hw barfs if we don't do this vblank wait. */
1667 intel_crtc_wait_for_next_vblank(crtc);
1669 /* Restore interrupt config */
1670 if (connector->polled & DRM_CONNECTOR_POLL_HPD) {
1671 spin_lock_irq(&dev_priv->irq_lock);
1672 i915_enable_pipestat(dev_priv, 0,
1673 PIPE_HOTPLUG_INTERRUPT_STATUS |
1674 PIPE_HOTPLUG_TV_INTERRUPT_STATUS);
1675 spin_unlock_irq(&dev_priv->irq_lock);
1682 * Here we set accurate tv format according to connector type
1683 * i.e Component TV should not be assigned by NTSC or PAL
1685 static void intel_tv_find_better_format(struct drm_connector *connector)
1687 struct intel_tv *intel_tv = intel_attached_tv(to_intel_connector(connector));
1688 const struct tv_mode *tv_mode = intel_tv_mode_find(connector->state);
1691 /* Component supports everything so we can keep the current mode */
1692 if (intel_tv->type == DRM_MODE_CONNECTOR_Component)
1695 /* If the current mode is fine don't change it */
1696 if (!tv_mode->component_only)
1699 for (i = 0; i < ARRAY_SIZE(tv_modes); i++) {
1700 tv_mode = &tv_modes[i];
1702 if (!tv_mode->component_only)
1706 connector->state->tv.legacy_mode = i;
1710 intel_tv_detect(struct drm_connector *connector,
1711 struct drm_modeset_acquire_ctx *ctx,
1714 struct drm_i915_private *i915 = to_i915(connector->dev);
1715 struct intel_tv *intel_tv = intel_attached_tv(to_intel_connector(connector));
1716 enum drm_connector_status status;
1719 drm_dbg_kms(&i915->drm, "[CONNECTOR:%d:%s] force=%d\n",
1720 connector->base.id, connector->name, force);
1722 if (!intel_display_device_enabled(i915))
1723 return connector_status_disconnected;
1725 if (!intel_display_driver_check_access(i915))
1726 return connector->status;
1729 struct drm_atomic_state *state;
1731 state = intel_load_detect_get_pipe(connector, ctx);
1733 return PTR_ERR(state);
1736 type = intel_tv_detect_type(intel_tv, connector);
1737 intel_load_detect_release_pipe(connector, state, ctx);
1739 connector_status_disconnected :
1740 connector_status_connected;
1742 status = connector_status_unknown;
1745 if (status == connector_status_connected) {
1746 intel_tv->type = type;
1747 intel_tv_find_better_format(connector);
1752 return connector->status;
1755 static const struct input_res {
1757 } input_res_table[] = {
1767 /* Choose preferred mode according to line number of TV format */
1769 intel_tv_is_preferred_mode(const struct drm_display_mode *mode,
1770 const struct tv_mode *tv_mode)
1772 int vdisplay = intel_tv_mode_vdisplay(tv_mode);
1774 /* prefer 480 line modes for all SD TV modes */
1775 if (vdisplay <= 576)
1778 return vdisplay == mode->vdisplay;
1782 intel_tv_set_mode_type(struct drm_display_mode *mode,
1783 const struct tv_mode *tv_mode)
1785 mode->type = DRM_MODE_TYPE_DRIVER;
1787 if (intel_tv_is_preferred_mode(mode, tv_mode))
1788 mode->type |= DRM_MODE_TYPE_PREFERRED;
1792 intel_tv_get_modes(struct drm_connector *connector)
1794 struct drm_i915_private *dev_priv = to_i915(connector->dev);
1795 const struct tv_mode *tv_mode = intel_tv_mode_find(connector->state);
1798 for (i = 0; i < ARRAY_SIZE(input_res_table); i++) {
1799 const struct input_res *input = &input_res_table[i];
1800 struct drm_display_mode *mode;
1802 if (input->w > 1024 &&
1803 !tv_mode->progressive &&
1804 !tv_mode->component_only)
1807 /* no vertical scaling with wide sources on gen3 */
1808 if (DISPLAY_VER(dev_priv) == 3 && input->w > 1024 &&
1809 input->h > intel_tv_mode_vdisplay(tv_mode))
1812 mode = drm_mode_create(connector->dev);
1817 * We take the TV mode and scale it to look
1818 * like it had the expected h/vdisplay. This
1819 * provides the most information to userspace
1820 * about the actual timings of the mode. We
1821 * do ignore the margins though.
1823 intel_tv_mode_to_mode(mode, tv_mode, tv_mode->clock);
1825 drm_dbg_kms(&dev_priv->drm, "TV mode: " DRM_MODE_FMT "\n",
1826 DRM_MODE_ARG(mode));
1828 intel_tv_scale_mode_horiz(mode, input->w, 0, 0);
1829 intel_tv_scale_mode_vert(mode, input->h, 0, 0);
1830 intel_tv_set_mode_type(mode, tv_mode);
1832 drm_mode_set_name(mode);
1834 drm_mode_probed_add(connector, mode);
1841 static const struct drm_connector_funcs intel_tv_connector_funcs = {
1842 .late_register = intel_connector_register,
1843 .early_unregister = intel_connector_unregister,
1844 .destroy = intel_connector_destroy,
1845 .fill_modes = drm_helper_probe_single_connector_modes,
1846 .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
1847 .atomic_duplicate_state = intel_tv_connector_duplicate_state,
1850 static int intel_tv_atomic_check(struct drm_connector *connector,
1851 struct drm_atomic_state *state)
1853 struct drm_connector_state *new_state;
1854 struct drm_crtc_state *new_crtc_state;
1855 struct drm_connector_state *old_state;
1857 new_state = drm_atomic_get_new_connector_state(state, connector);
1858 if (!new_state->crtc)
1861 old_state = drm_atomic_get_old_connector_state(state, connector);
1862 new_crtc_state = drm_atomic_get_new_crtc_state(state, new_state->crtc);
1864 if (old_state->tv.legacy_mode != new_state->tv.legacy_mode ||
1865 old_state->tv.margins.left != new_state->tv.margins.left ||
1866 old_state->tv.margins.right != new_state->tv.margins.right ||
1867 old_state->tv.margins.top != new_state->tv.margins.top ||
1868 old_state->tv.margins.bottom != new_state->tv.margins.bottom) {
1869 /* Force a modeset. */
1871 new_crtc_state->connectors_changed = true;
1877 static const struct drm_connector_helper_funcs intel_tv_connector_helper_funcs = {
1878 .detect_ctx = intel_tv_detect,
1879 .mode_valid = intel_tv_mode_valid,
1880 .get_modes = intel_tv_get_modes,
1881 .atomic_check = intel_tv_atomic_check,
1884 static const struct drm_encoder_funcs intel_tv_enc_funcs = {
1885 .destroy = intel_encoder_destroy,
1888 static void intel_tv_add_properties(struct drm_connector *connector)
1890 struct drm_i915_private *i915 = to_i915(connector->dev);
1891 struct drm_connector_state *conn_state = connector->state;
1892 const char *tv_format_names[ARRAY_SIZE(tv_modes)];
1895 /* BIOS margin values */
1896 conn_state->tv.margins.left = 54;
1897 conn_state->tv.margins.top = 36;
1898 conn_state->tv.margins.right = 46;
1899 conn_state->tv.margins.bottom = 37;
1901 conn_state->tv.legacy_mode = 0;
1903 /* Create TV properties then attach current values */
1904 for (i = 0; i < ARRAY_SIZE(tv_modes); i++) {
1905 /* 1080p50/1080p60 not supported on gen3 */
1906 if (DISPLAY_VER(i915) == 3 && tv_modes[i].oversample == 1)
1909 tv_format_names[i] = tv_modes[i].name;
1911 drm_mode_create_tv_properties_legacy(&i915->drm, i, tv_format_names);
1913 drm_object_attach_property(&connector->base,
1914 i915->drm.mode_config.legacy_tv_mode_property,
1915 conn_state->tv.legacy_mode);
1916 drm_object_attach_property(&connector->base,
1917 i915->drm.mode_config.tv_left_margin_property,
1918 conn_state->tv.margins.left);
1919 drm_object_attach_property(&connector->base,
1920 i915->drm.mode_config.tv_top_margin_property,
1921 conn_state->tv.margins.top);
1922 drm_object_attach_property(&connector->base,
1923 i915->drm.mode_config.tv_right_margin_property,
1924 conn_state->tv.margins.right);
1925 drm_object_attach_property(&connector->base,
1926 i915->drm.mode_config.tv_bottom_margin_property,
1927 conn_state->tv.margins.bottom);
1931 intel_tv_init(struct drm_i915_private *dev_priv)
1933 struct drm_connector *connector;
1934 struct intel_tv *intel_tv;
1935 struct intel_encoder *intel_encoder;
1936 struct intel_connector *intel_connector;
1937 u32 tv_dac_on, tv_dac_off, save_tv_dac;
1939 if ((intel_de_read(dev_priv, TV_CTL) & TV_FUSE_STATE_MASK) == TV_FUSE_STATE_DISABLED)
1942 if (!intel_bios_is_tv_present(dev_priv)) {
1943 drm_dbg_kms(&dev_priv->drm, "Integrated TV is not present.\n");
1948 * Sanity check the TV output by checking to see if the
1949 * DAC register holds a value
1951 save_tv_dac = intel_de_read(dev_priv, TV_DAC);
1953 intel_de_write(dev_priv, TV_DAC, save_tv_dac | TVDAC_STATE_CHG_EN);
1954 tv_dac_on = intel_de_read(dev_priv, TV_DAC);
1956 intel_de_write(dev_priv, TV_DAC, save_tv_dac & ~TVDAC_STATE_CHG_EN);
1957 tv_dac_off = intel_de_read(dev_priv, TV_DAC);
1959 intel_de_write(dev_priv, TV_DAC, save_tv_dac);
1962 * If the register does not hold the state change enable
1963 * bit, (either as a 0 or a 1), assume it doesn't really
1966 if ((tv_dac_on & TVDAC_STATE_CHG_EN) == 0 ||
1967 (tv_dac_off & TVDAC_STATE_CHG_EN) != 0)
1970 intel_tv = kzalloc(sizeof(*intel_tv), GFP_KERNEL);
1975 intel_connector = intel_connector_alloc();
1976 if (!intel_connector) {
1981 intel_encoder = &intel_tv->base;
1982 connector = &intel_connector->base;
1985 * The documentation, for the older chipsets at least, recommend
1986 * using a polling method rather than hotplug detection for TVs.
1987 * This is because in order to perform the hotplug detection, the PLLs
1988 * for the TV must be kept alive increasing power drain and starving
1989 * bandwidth from other encoders. Notably for instance, it causes
1990 * pipe underruns on Crestline when this encoder is supposedly idle.
1992 * More recent chipsets favour HDMI rather than integrated S-Video.
1994 intel_connector->polled = DRM_CONNECTOR_POLL_CONNECT;
1995 intel_connector->base.polled = intel_connector->polled;
1997 drm_connector_init(&dev_priv->drm, connector, &intel_tv_connector_funcs,
1998 DRM_MODE_CONNECTOR_SVIDEO);
2000 drm_encoder_init(&dev_priv->drm, &intel_encoder->base, &intel_tv_enc_funcs,
2001 DRM_MODE_ENCODER_TVDAC, "TV");
2003 intel_encoder->compute_config = intel_tv_compute_config;
2004 intel_encoder->get_config = intel_tv_get_config;
2005 intel_encoder->pre_enable = intel_tv_pre_enable;
2006 intel_encoder->enable = intel_enable_tv;
2007 intel_encoder->disable = intel_disable_tv;
2008 intel_encoder->get_hw_state = intel_tv_get_hw_state;
2009 intel_connector->get_hw_state = intel_connector_get_hw_state;
2011 intel_connector_attach_encoder(intel_connector, intel_encoder);
2013 intel_encoder->type = INTEL_OUTPUT_TVOUT;
2014 intel_encoder->power_domain = POWER_DOMAIN_PORT_OTHER;
2015 intel_encoder->port = PORT_NONE;
2016 intel_encoder->pipe_mask = ~0;
2017 intel_encoder->cloneable = 0;
2018 intel_tv->type = DRM_MODE_CONNECTOR_Unknown;
2020 drm_connector_helper_add(connector, &intel_tv_connector_helper_funcs);
2022 intel_tv_add_properties(connector);