drm/i915: Update to Linux 4.7.10
[dragonfly.git] / sys / dev / drm / i915 / intel_tv.c
blobd8a0d8b2ddad55bfea9416f856008c37f4e98ddf
1 /*
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
14 * Software.
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.
24 * Authors:
25 * Eric Anholt <eric@anholt.net>
29 /** @file
30 * Integrated TV-out support for the 915GM and 945GM.
33 #include <drm/drmP.h>
34 #include <drm/drm_atomic_helper.h>
35 #include <drm/drm_crtc.h>
36 #include <drm/drm_edid.h>
37 #include "intel_drv.h"
38 #include <drm/i915_drm.h>
39 #include "i915_drv.h"
41 enum tv_margin {
42 TV_MARGIN_LEFT, TV_MARGIN_TOP,
43 TV_MARGIN_RIGHT, TV_MARGIN_BOTTOM
46 /** Private structure for the integrated TV support */
47 struct intel_tv {
48 struct intel_encoder base;
50 int type;
51 const char *tv_format;
52 int margin[4];
53 u32 save_TV_H_CTL_1;
54 u32 save_TV_H_CTL_2;
55 u32 save_TV_H_CTL_3;
56 u32 save_TV_V_CTL_1;
57 u32 save_TV_V_CTL_2;
58 u32 save_TV_V_CTL_3;
59 u32 save_TV_V_CTL_4;
60 u32 save_TV_V_CTL_5;
61 u32 save_TV_V_CTL_6;
62 u32 save_TV_V_CTL_7;
63 u32 save_TV_SC_CTL_1, save_TV_SC_CTL_2, save_TV_SC_CTL_3;
65 u32 save_TV_CSC_Y;
66 u32 save_TV_CSC_Y2;
67 u32 save_TV_CSC_U;
68 u32 save_TV_CSC_U2;
69 u32 save_TV_CSC_V;
70 u32 save_TV_CSC_V2;
71 u32 save_TV_CLR_KNOBS;
72 u32 save_TV_CLR_LEVEL;
73 u32 save_TV_WIN_POS;
74 u32 save_TV_WIN_SIZE;
75 u32 save_TV_FILTER_CTL_1;
76 u32 save_TV_FILTER_CTL_2;
77 u32 save_TV_FILTER_CTL_3;
79 u32 save_TV_H_LUMA[60];
80 u32 save_TV_H_CHROMA[60];
81 u32 save_TV_V_LUMA[43];
82 u32 save_TV_V_CHROMA[43];
84 u32 save_TV_DAC;
85 u32 save_TV_CTL;
88 struct video_levels {
89 int blank, black, burst;
92 struct color_conversion {
93 u16 ry, gy, by, ay;
94 u16 ru, gu, bu, au;
95 u16 rv, gv, bv, av;
98 static const u32 filter_table[] = {
99 0xB1403000, 0x2E203500, 0x35002E20, 0x3000B140,
100 0x35A0B160, 0x2DC02E80, 0xB1403480, 0xB1603000,
101 0x2EA03640, 0x34002D80, 0x3000B120, 0x36E0B160,
102 0x2D202EF0, 0xB1203380, 0xB1603000, 0x2F303780,
103 0x33002CC0, 0x3000B100, 0x3820B160, 0x2C802F50,
104 0xB10032A0, 0xB1603000, 0x2F9038C0, 0x32202C20,
105 0x3000B0E0, 0x3980B160, 0x2BC02FC0, 0xB0E031C0,
106 0xB1603000, 0x2FF03A20, 0x31602B60, 0xB020B0C0,
107 0x3AE0B160, 0x2B001810, 0xB0C03120, 0xB140B020,
108 0x18283BA0, 0x30C02A80, 0xB020B0A0, 0x3C60B140,
109 0x2A201838, 0xB0A03080, 0xB120B020, 0x18383D20,
110 0x304029C0, 0xB040B080, 0x3DE0B100, 0x29601848,
111 0xB0803000, 0xB100B040, 0x18483EC0, 0xB0402900,
112 0xB040B060, 0x3F80B0C0, 0x28801858, 0xB060B080,
113 0xB0A0B060, 0x18602820, 0xB0A02820, 0x0000B060,
114 0xB1403000, 0x2E203500, 0x35002E20, 0x3000B140,
115 0x35A0B160, 0x2DC02E80, 0xB1403480, 0xB1603000,
116 0x2EA03640, 0x34002D80, 0x3000B120, 0x36E0B160,
117 0x2D202EF0, 0xB1203380, 0xB1603000, 0x2F303780,
118 0x33002CC0, 0x3000B100, 0x3820B160, 0x2C802F50,
119 0xB10032A0, 0xB1603000, 0x2F9038C0, 0x32202C20,
120 0x3000B0E0, 0x3980B160, 0x2BC02FC0, 0xB0E031C0,
121 0xB1603000, 0x2FF03A20, 0x31602B60, 0xB020B0C0,
122 0x3AE0B160, 0x2B001810, 0xB0C03120, 0xB140B020,
123 0x18283BA0, 0x30C02A80, 0xB020B0A0, 0x3C60B140,
124 0x2A201838, 0xB0A03080, 0xB120B020, 0x18383D20,
125 0x304029C0, 0xB040B080, 0x3DE0B100, 0x29601848,
126 0xB0803000, 0xB100B040, 0x18483EC0, 0xB0402900,
127 0xB040B060, 0x3F80B0C0, 0x28801858, 0xB060B080,
128 0xB0A0B060, 0x18602820, 0xB0A02820, 0x0000B060,
129 0x36403000, 0x2D002CC0, 0x30003640, 0x2D0036C0,
130 0x35C02CC0, 0x37403000, 0x2C802D40, 0x30003540,
131 0x2D8037C0, 0x34C02C40, 0x38403000, 0x2BC02E00,
132 0x30003440, 0x2E2038C0, 0x34002B80, 0x39803000,
133 0x2B402E40, 0x30003380, 0x2E603A00, 0x33402B00,
134 0x3A803040, 0x2A802EA0, 0x30403300, 0x2EC03B40,
135 0x32802A40, 0x3C003040, 0x2A002EC0, 0x30803240,
136 0x2EC03C80, 0x320029C0, 0x3D403080, 0x29402F00,
137 0x308031C0, 0x2F203DC0, 0x31802900, 0x3E8030C0,
138 0x28802F40, 0x30C03140, 0x2F203F40, 0x31402840,
139 0x28003100, 0x28002F00, 0x00003100, 0x36403000,
140 0x2D002CC0, 0x30003640, 0x2D0036C0,
141 0x35C02CC0, 0x37403000, 0x2C802D40, 0x30003540,
142 0x2D8037C0, 0x34C02C40, 0x38403000, 0x2BC02E00,
143 0x30003440, 0x2E2038C0, 0x34002B80, 0x39803000,
144 0x2B402E40, 0x30003380, 0x2E603A00, 0x33402B00,
145 0x3A803040, 0x2A802EA0, 0x30403300, 0x2EC03B40,
146 0x32802A40, 0x3C003040, 0x2A002EC0, 0x30803240,
147 0x2EC03C80, 0x320029C0, 0x3D403080, 0x29402F00,
148 0x308031C0, 0x2F203DC0, 0x31802900, 0x3E8030C0,
149 0x28802F40, 0x30C03140, 0x2F203F40, 0x31402840,
150 0x28003100, 0x28002F00, 0x00003100,
154 * Color conversion values have 3 separate fixed point formats:
156 * 10 bit fields (ay, au)
157 * 1.9 fixed point (b.bbbbbbbbb)
158 * 11 bit fields (ry, by, ru, gu, gv)
159 * exp.mantissa (ee.mmmmmmmmm)
160 * ee = 00 = 10^-1 (0.mmmmmmmmm)
161 * ee = 01 = 10^-2 (0.0mmmmmmmmm)
162 * ee = 10 = 10^-3 (0.00mmmmmmmmm)
163 * ee = 11 = 10^-4 (0.000mmmmmmmmm)
164 * 12 bit fields (gy, rv, bu)
165 * exp.mantissa (eee.mmmmmmmmm)
166 * eee = 000 = 10^-1 (0.mmmmmmmmm)
167 * eee = 001 = 10^-2 (0.0mmmmmmmmm)
168 * eee = 010 = 10^-3 (0.00mmmmmmmmm)
169 * eee = 011 = 10^-4 (0.000mmmmmmmmm)
170 * eee = 100 = reserved
171 * eee = 101 = reserved
172 * eee = 110 = reserved
173 * eee = 111 = 10^0 (m.mmmmmmmm) (only usable for 1.0 representation)
175 * Saturation and contrast are 8 bits, with their own representation:
176 * 8 bit field (saturation, contrast)
177 * exp.mantissa (ee.mmmmmm)
178 * ee = 00 = 10^-1 (0.mmmmmm)
179 * ee = 01 = 10^0 (m.mmmmm)
180 * ee = 10 = 10^1 (mm.mmmm)
181 * ee = 11 = 10^2 (mmm.mmm)
183 * Simple conversion function:
185 * static u32
186 * float_to_csc_11(float f)
188 * u32 exp;
189 * u32 mant;
190 * u32 ret;
192 * if (f < 0)
193 * f = -f;
195 * if (f >= 1) {
196 * exp = 0x7;
197 * mant = 1 << 8;
198 * } else {
199 * for (exp = 0; exp < 3 && f < 0.5; exp++)
200 * f *= 2.0;
201 * mant = (f * (1 << 9) + 0.5);
202 * if (mant >= (1 << 9))
203 * mant = (1 << 9) - 1;
205 * ret = (exp << 9) | mant;
206 * return ret;
211 * Behold, magic numbers! If we plant them they might grow a big
212 * s-video cable to the sky... or something.
214 * Pre-converted to appropriate hex value.
218 * PAL & NTSC values for composite & s-video connections
220 static const struct color_conversion ntsc_m_csc_composite = {
221 .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0104,
222 .ru = 0x0733, .gu = 0x052d, .bu = 0x05c7, .au = 0x0200,
223 .rv = 0x0340, .gv = 0x030c, .bv = 0x06d0, .av = 0x0200,
226 static const struct video_levels ntsc_m_levels_composite = {
227 .blank = 225, .black = 267, .burst = 113,
230 static const struct color_conversion ntsc_m_csc_svideo = {
231 .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0133,
232 .ru = 0x076a, .gu = 0x0564, .bu = 0x030d, .au = 0x0200,
233 .rv = 0x037a, .gv = 0x033d, .bv = 0x06f6, .av = 0x0200,
236 static const struct video_levels ntsc_m_levels_svideo = {
237 .blank = 266, .black = 316, .burst = 133,
240 static const struct color_conversion ntsc_j_csc_composite = {
241 .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0119,
242 .ru = 0x074c, .gu = 0x0546, .bu = 0x05ec, .au = 0x0200,
243 .rv = 0x035a, .gv = 0x0322, .bv = 0x06e1, .av = 0x0200,
246 static const struct video_levels ntsc_j_levels_composite = {
247 .blank = 225, .black = 225, .burst = 113,
250 static const struct color_conversion ntsc_j_csc_svideo = {
251 .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x014c,
252 .ru = 0x0788, .gu = 0x0581, .bu = 0x0322, .au = 0x0200,
253 .rv = 0x0399, .gv = 0x0356, .bv = 0x070a, .av = 0x0200,
256 static const struct video_levels ntsc_j_levels_svideo = {
257 .blank = 266, .black = 266, .burst = 133,
260 static const struct color_conversion pal_csc_composite = {
261 .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0113,
262 .ru = 0x0745, .gu = 0x053f, .bu = 0x05e1, .au = 0x0200,
263 .rv = 0x0353, .gv = 0x031c, .bv = 0x06dc, .av = 0x0200,
266 static const struct video_levels pal_levels_composite = {
267 .blank = 237, .black = 237, .burst = 118,
270 static const struct color_conversion pal_csc_svideo = {
271 .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0145,
272 .ru = 0x0780, .gu = 0x0579, .bu = 0x031c, .au = 0x0200,
273 .rv = 0x0390, .gv = 0x034f, .bv = 0x0705, .av = 0x0200,
276 static const struct video_levels pal_levels_svideo = {
277 .blank = 280, .black = 280, .burst = 139,
280 static const struct color_conversion pal_m_csc_composite = {
281 .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0104,
282 .ru = 0x0733, .gu = 0x052d, .bu = 0x05c7, .au = 0x0200,
283 .rv = 0x0340, .gv = 0x030c, .bv = 0x06d0, .av = 0x0200,
286 static const struct video_levels pal_m_levels_composite = {
287 .blank = 225, .black = 267, .burst = 113,
290 static const struct color_conversion pal_m_csc_svideo = {
291 .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0133,
292 .ru = 0x076a, .gu = 0x0564, .bu = 0x030d, .au = 0x0200,
293 .rv = 0x037a, .gv = 0x033d, .bv = 0x06f6, .av = 0x0200,
296 static const struct video_levels pal_m_levels_svideo = {
297 .blank = 266, .black = 316, .burst = 133,
300 static const struct color_conversion pal_n_csc_composite = {
301 .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0104,
302 .ru = 0x0733, .gu = 0x052d, .bu = 0x05c7, .au = 0x0200,
303 .rv = 0x0340, .gv = 0x030c, .bv = 0x06d0, .av = 0x0200,
306 static const struct video_levels pal_n_levels_composite = {
307 .blank = 225, .black = 267, .burst = 118,
310 static const struct color_conversion pal_n_csc_svideo = {
311 .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0133,
312 .ru = 0x076a, .gu = 0x0564, .bu = 0x030d, .au = 0x0200,
313 .rv = 0x037a, .gv = 0x033d, .bv = 0x06f6, .av = 0x0200,
316 static const struct video_levels pal_n_levels_svideo = {
317 .blank = 266, .black = 316, .burst = 139,
321 * Component connections
323 static const struct color_conversion sdtv_csc_yprpb = {
324 .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0145,
325 .ru = 0x0559, .gu = 0x0353, .bu = 0x0100, .au = 0x0200,
326 .rv = 0x0100, .gv = 0x03ad, .bv = 0x074d, .av = 0x0200,
329 static const struct color_conversion hdtv_csc_yprpb = {
330 .ry = 0x05b3, .gy = 0x016e, .by = 0x0728, .ay = 0x0145,
331 .ru = 0x07d5, .gu = 0x038b, .bu = 0x0100, .au = 0x0200,
332 .rv = 0x0100, .gv = 0x03d1, .bv = 0x06bc, .av = 0x0200,
335 static const struct video_levels component_levels = {
336 .blank = 279, .black = 279, .burst = 0,
340 struct tv_mode {
341 const char *name;
342 int clock;
343 int refresh; /* in millihertz (for precision) */
344 u32 oversample;
345 int hsync_end, hblank_start, hblank_end, htotal;
346 bool progressive, trilevel_sync, component_only;
347 int vsync_start_f1, vsync_start_f2, vsync_len;
348 bool veq_ena;
349 int veq_start_f1, veq_start_f2, veq_len;
350 int vi_end_f1, vi_end_f2, nbr_end;
351 bool burst_ena;
352 int hburst_start, hburst_len;
353 int vburst_start_f1, vburst_end_f1;
354 int vburst_start_f2, vburst_end_f2;
355 int vburst_start_f3, vburst_end_f3;
356 int vburst_start_f4, vburst_end_f4;
358 * subcarrier programming
360 int dda2_size, dda3_size, dda1_inc, dda2_inc, dda3_inc;
361 u32 sc_reset;
362 bool pal_burst;
364 * blank/black levels
366 const struct video_levels *composite_levels, *svideo_levels;
367 const struct color_conversion *composite_color, *svideo_color;
368 const u32 *filter_table;
369 int max_srcw;
374 * Sub carrier DDA
376 * I think this works as follows:
378 * subcarrier freq = pixel_clock * (dda1_inc + dda2_inc / dda2_size) / 4096
380 * Presumably, when dda3 is added in, it gets to adjust the dda2_inc value
382 * So,
383 * dda1_ideal = subcarrier/pixel * 4096
384 * dda1_inc = floor (dda1_ideal)
385 * dda2 = dda1_ideal - dda1_inc
387 * then pick a ratio for dda2 that gives the closest approximation. If
388 * you can't get close enough, you can play with dda3 as well. This
389 * seems likely to happen when dda2 is small as the jumps would be larger
391 * To invert this,
393 * pixel_clock = subcarrier * 4096 / (dda1_inc + dda2_inc / dda2_size)
395 * The constants below were all computed using a 107.520MHz clock
399 * Register programming values for TV modes.
401 * These values account for -1s required.
404 static const struct tv_mode tv_modes[] = {
406 .name = "NTSC-M",
407 .clock = 108000,
408 .refresh = 59940,
409 .oversample = TV_OVERSAMPLE_8X,
410 .component_only = 0,
411 /* 525 Lines, 60 Fields, 15.734KHz line, Sub-Carrier 3.580MHz */
413 .hsync_end = 64, .hblank_end = 124,
414 .hblank_start = 836, .htotal = 857,
416 .progressive = false, .trilevel_sync = false,
418 .vsync_start_f1 = 6, .vsync_start_f2 = 7,
419 .vsync_len = 6,
421 .veq_ena = true, .veq_start_f1 = 0,
422 .veq_start_f2 = 1, .veq_len = 18,
424 .vi_end_f1 = 20, .vi_end_f2 = 21,
425 .nbr_end = 240,
427 .burst_ena = true,
428 .hburst_start = 72, .hburst_len = 34,
429 .vburst_start_f1 = 9, .vburst_end_f1 = 240,
430 .vburst_start_f2 = 10, .vburst_end_f2 = 240,
431 .vburst_start_f3 = 9, .vburst_end_f3 = 240,
432 .vburst_start_f4 = 10, .vburst_end_f4 = 240,
434 /* desired 3.5800000 actual 3.5800000 clock 107.52 */
435 .dda1_inc = 135,
436 .dda2_inc = 20800, .dda2_size = 27456,
437 .dda3_inc = 0, .dda3_size = 0,
438 .sc_reset = TV_SC_RESET_EVERY_4,
439 .pal_burst = false,
441 .composite_levels = &ntsc_m_levels_composite,
442 .composite_color = &ntsc_m_csc_composite,
443 .svideo_levels = &ntsc_m_levels_svideo,
444 .svideo_color = &ntsc_m_csc_svideo,
446 .filter_table = filter_table,
449 .name = "NTSC-443",
450 .clock = 108000,
451 .refresh = 59940,
452 .oversample = TV_OVERSAMPLE_8X,
453 .component_only = 0,
454 /* 525 Lines, 60 Fields, 15.734KHz line, Sub-Carrier 4.43MHz */
455 .hsync_end = 64, .hblank_end = 124,
456 .hblank_start = 836, .htotal = 857,
458 .progressive = false, .trilevel_sync = false,
460 .vsync_start_f1 = 6, .vsync_start_f2 = 7,
461 .vsync_len = 6,
463 .veq_ena = true, .veq_start_f1 = 0,
464 .veq_start_f2 = 1, .veq_len = 18,
466 .vi_end_f1 = 20, .vi_end_f2 = 21,
467 .nbr_end = 240,
469 .burst_ena = true,
470 .hburst_start = 72, .hburst_len = 34,
471 .vburst_start_f1 = 9, .vburst_end_f1 = 240,
472 .vburst_start_f2 = 10, .vburst_end_f2 = 240,
473 .vburst_start_f3 = 9, .vburst_end_f3 = 240,
474 .vburst_start_f4 = 10, .vburst_end_f4 = 240,
476 /* desired 4.4336180 actual 4.4336180 clock 107.52 */
477 .dda1_inc = 168,
478 .dda2_inc = 4093, .dda2_size = 27456,
479 .dda3_inc = 310, .dda3_size = 525,
480 .sc_reset = TV_SC_RESET_NEVER,
481 .pal_burst = false,
483 .composite_levels = &ntsc_m_levels_composite,
484 .composite_color = &ntsc_m_csc_composite,
485 .svideo_levels = &ntsc_m_levels_svideo,
486 .svideo_color = &ntsc_m_csc_svideo,
488 .filter_table = filter_table,
491 .name = "NTSC-J",
492 .clock = 108000,
493 .refresh = 59940,
494 .oversample = TV_OVERSAMPLE_8X,
495 .component_only = 0,
497 /* 525 Lines, 60 Fields, 15.734KHz line, Sub-Carrier 3.580MHz */
498 .hsync_end = 64, .hblank_end = 124,
499 .hblank_start = 836, .htotal = 857,
501 .progressive = false, .trilevel_sync = false,
503 .vsync_start_f1 = 6, .vsync_start_f2 = 7,
504 .vsync_len = 6,
506 .veq_ena = true, .veq_start_f1 = 0,
507 .veq_start_f2 = 1, .veq_len = 18,
509 .vi_end_f1 = 20, .vi_end_f2 = 21,
510 .nbr_end = 240,
512 .burst_ena = true,
513 .hburst_start = 72, .hburst_len = 34,
514 .vburst_start_f1 = 9, .vburst_end_f1 = 240,
515 .vburst_start_f2 = 10, .vburst_end_f2 = 240,
516 .vburst_start_f3 = 9, .vburst_end_f3 = 240,
517 .vburst_start_f4 = 10, .vburst_end_f4 = 240,
519 /* desired 3.5800000 actual 3.5800000 clock 107.52 */
520 .dda1_inc = 135,
521 .dda2_inc = 20800, .dda2_size = 27456,
522 .dda3_inc = 0, .dda3_size = 0,
523 .sc_reset = TV_SC_RESET_EVERY_4,
524 .pal_burst = false,
526 .composite_levels = &ntsc_j_levels_composite,
527 .composite_color = &ntsc_j_csc_composite,
528 .svideo_levels = &ntsc_j_levels_svideo,
529 .svideo_color = &ntsc_j_csc_svideo,
531 .filter_table = filter_table,
534 .name = "PAL-M",
535 .clock = 108000,
536 .refresh = 59940,
537 .oversample = TV_OVERSAMPLE_8X,
538 .component_only = 0,
540 /* 525 Lines, 60 Fields, 15.734KHz line, Sub-Carrier 3.580MHz */
541 .hsync_end = 64, .hblank_end = 124,
542 .hblank_start = 836, .htotal = 857,
544 .progressive = false, .trilevel_sync = false,
546 .vsync_start_f1 = 6, .vsync_start_f2 = 7,
547 .vsync_len = 6,
549 .veq_ena = true, .veq_start_f1 = 0,
550 .veq_start_f2 = 1, .veq_len = 18,
552 .vi_end_f1 = 20, .vi_end_f2 = 21,
553 .nbr_end = 240,
555 .burst_ena = true,
556 .hburst_start = 72, .hburst_len = 34,
557 .vburst_start_f1 = 9, .vburst_end_f1 = 240,
558 .vburst_start_f2 = 10, .vburst_end_f2 = 240,
559 .vburst_start_f3 = 9, .vburst_end_f3 = 240,
560 .vburst_start_f4 = 10, .vburst_end_f4 = 240,
562 /* desired 3.5800000 actual 3.5800000 clock 107.52 */
563 .dda1_inc = 135,
564 .dda2_inc = 16704, .dda2_size = 27456,
565 .dda3_inc = 0, .dda3_size = 0,
566 .sc_reset = TV_SC_RESET_EVERY_8,
567 .pal_burst = true,
569 .composite_levels = &pal_m_levels_composite,
570 .composite_color = &pal_m_csc_composite,
571 .svideo_levels = &pal_m_levels_svideo,
572 .svideo_color = &pal_m_csc_svideo,
574 .filter_table = filter_table,
577 /* 625 Lines, 50 Fields, 15.625KHz line, Sub-Carrier 4.434MHz */
578 .name = "PAL-N",
579 .clock = 108000,
580 .refresh = 50000,
581 .oversample = TV_OVERSAMPLE_8X,
582 .component_only = 0,
584 .hsync_end = 64, .hblank_end = 128,
585 .hblank_start = 844, .htotal = 863,
587 .progressive = false, .trilevel_sync = false,
590 .vsync_start_f1 = 6, .vsync_start_f2 = 7,
591 .vsync_len = 6,
593 .veq_ena = true, .veq_start_f1 = 0,
594 .veq_start_f2 = 1, .veq_len = 18,
596 .vi_end_f1 = 24, .vi_end_f2 = 25,
597 .nbr_end = 286,
599 .burst_ena = true,
600 .hburst_start = 73, .hburst_len = 34,
601 .vburst_start_f1 = 8, .vburst_end_f1 = 285,
602 .vburst_start_f2 = 8, .vburst_end_f2 = 286,
603 .vburst_start_f3 = 9, .vburst_end_f3 = 286,
604 .vburst_start_f4 = 9, .vburst_end_f4 = 285,
607 /* desired 4.4336180 actual 4.4336180 clock 107.52 */
608 .dda1_inc = 135,
609 .dda2_inc = 23578, .dda2_size = 27648,
610 .dda3_inc = 134, .dda3_size = 625,
611 .sc_reset = TV_SC_RESET_EVERY_8,
612 .pal_burst = true,
614 .composite_levels = &pal_n_levels_composite,
615 .composite_color = &pal_n_csc_composite,
616 .svideo_levels = &pal_n_levels_svideo,
617 .svideo_color = &pal_n_csc_svideo,
619 .filter_table = filter_table,
622 /* 625 Lines, 50 Fields, 15.625KHz line, Sub-Carrier 4.434MHz */
623 .name = "PAL",
624 .clock = 108000,
625 .refresh = 50000,
626 .oversample = TV_OVERSAMPLE_8X,
627 .component_only = 0,
629 .hsync_end = 64, .hblank_end = 142,
630 .hblank_start = 844, .htotal = 863,
632 .progressive = false, .trilevel_sync = false,
634 .vsync_start_f1 = 5, .vsync_start_f2 = 6,
635 .vsync_len = 5,
637 .veq_ena = true, .veq_start_f1 = 0,
638 .veq_start_f2 = 1, .veq_len = 15,
640 .vi_end_f1 = 24, .vi_end_f2 = 25,
641 .nbr_end = 286,
643 .burst_ena = true,
644 .hburst_start = 73, .hburst_len = 32,
645 .vburst_start_f1 = 8, .vburst_end_f1 = 285,
646 .vburst_start_f2 = 8, .vburst_end_f2 = 286,
647 .vburst_start_f3 = 9, .vburst_end_f3 = 286,
648 .vburst_start_f4 = 9, .vburst_end_f4 = 285,
650 /* desired 4.4336180 actual 4.4336180 clock 107.52 */
651 .dda1_inc = 168,
652 .dda2_inc = 4122, .dda2_size = 27648,
653 .dda3_inc = 67, .dda3_size = 625,
654 .sc_reset = TV_SC_RESET_EVERY_8,
655 .pal_burst = true,
657 .composite_levels = &pal_levels_composite,
658 .composite_color = &pal_csc_composite,
659 .svideo_levels = &pal_levels_svideo,
660 .svideo_color = &pal_csc_svideo,
662 .filter_table = filter_table,
665 .name = "480p",
666 .clock = 107520,
667 .refresh = 59940,
668 .oversample = TV_OVERSAMPLE_4X,
669 .component_only = 1,
671 .hsync_end = 64, .hblank_end = 122,
672 .hblank_start = 842, .htotal = 857,
674 .progressive = true, .trilevel_sync = false,
676 .vsync_start_f1 = 12, .vsync_start_f2 = 12,
677 .vsync_len = 12,
679 .veq_ena = false,
681 .vi_end_f1 = 44, .vi_end_f2 = 44,
682 .nbr_end = 479,
684 .burst_ena = false,
686 .filter_table = filter_table,
689 .name = "576p",
690 .clock = 107520,
691 .refresh = 50000,
692 .oversample = TV_OVERSAMPLE_4X,
693 .component_only = 1,
695 .hsync_end = 64, .hblank_end = 139,
696 .hblank_start = 859, .htotal = 863,
698 .progressive = true, .trilevel_sync = false,
700 .vsync_start_f1 = 10, .vsync_start_f2 = 10,
701 .vsync_len = 10,
703 .veq_ena = false,
705 .vi_end_f1 = 48, .vi_end_f2 = 48,
706 .nbr_end = 575,
708 .burst_ena = false,
710 .filter_table = filter_table,
713 .name = "720p@60Hz",
714 .clock = 148800,
715 .refresh = 60000,
716 .oversample = TV_OVERSAMPLE_2X,
717 .component_only = 1,
719 .hsync_end = 80, .hblank_end = 300,
720 .hblank_start = 1580, .htotal = 1649,
722 .progressive = true, .trilevel_sync = true,
724 .vsync_start_f1 = 10, .vsync_start_f2 = 10,
725 .vsync_len = 10,
727 .veq_ena = false,
729 .vi_end_f1 = 29, .vi_end_f2 = 29,
730 .nbr_end = 719,
732 .burst_ena = false,
734 .filter_table = filter_table,
737 .name = "720p@50Hz",
738 .clock = 148800,
739 .refresh = 50000,
740 .oversample = TV_OVERSAMPLE_2X,
741 .component_only = 1,
743 .hsync_end = 80, .hblank_end = 300,
744 .hblank_start = 1580, .htotal = 1979,
746 .progressive = true, .trilevel_sync = true,
748 .vsync_start_f1 = 10, .vsync_start_f2 = 10,
749 .vsync_len = 10,
751 .veq_ena = false,
753 .vi_end_f1 = 29, .vi_end_f2 = 29,
754 .nbr_end = 719,
756 .burst_ena = false,
758 .filter_table = filter_table,
759 .max_srcw = 800
762 .name = "1080i@50Hz",
763 .clock = 148800,
764 .refresh = 50000,
765 .oversample = TV_OVERSAMPLE_2X,
766 .component_only = 1,
768 .hsync_end = 88, .hblank_end = 235,
769 .hblank_start = 2155, .htotal = 2639,
771 .progressive = false, .trilevel_sync = true,
773 .vsync_start_f1 = 4, .vsync_start_f2 = 5,
774 .vsync_len = 10,
776 .veq_ena = true, .veq_start_f1 = 4,
777 .veq_start_f2 = 4, .veq_len = 10,
780 .vi_end_f1 = 21, .vi_end_f2 = 22,
781 .nbr_end = 539,
783 .burst_ena = false,
785 .filter_table = filter_table,
788 .name = "1080i@60Hz",
789 .clock = 148800,
790 .refresh = 60000,
791 .oversample = TV_OVERSAMPLE_2X,
792 .component_only = 1,
794 .hsync_end = 88, .hblank_end = 235,
795 .hblank_start = 2155, .htotal = 2199,
797 .progressive = false, .trilevel_sync = true,
799 .vsync_start_f1 = 4, .vsync_start_f2 = 5,
800 .vsync_len = 10,
802 .veq_ena = true, .veq_start_f1 = 4,
803 .veq_start_f2 = 4, .veq_len = 10,
806 .vi_end_f1 = 21, .vi_end_f2 = 22,
807 .nbr_end = 539,
809 .burst_ena = false,
811 .filter_table = filter_table,
815 static struct intel_tv *enc_to_tv(struct intel_encoder *encoder)
817 return container_of(encoder, struct intel_tv, base);
820 static struct intel_tv *intel_attached_tv(struct drm_connector *connector)
822 return enc_to_tv(intel_attached_encoder(connector));
825 static bool
826 intel_tv_get_hw_state(struct intel_encoder *encoder, enum i915_pipe *pipe)
828 struct drm_device *dev = encoder->base.dev;
829 struct drm_i915_private *dev_priv = dev->dev_private;
830 u32 tmp = I915_READ(TV_CTL);
832 if (!(tmp & TV_ENC_ENABLE))
833 return false;
835 *pipe = PORT_TO_PIPE(tmp);
837 return true;
840 static void
841 intel_enable_tv(struct intel_encoder *encoder)
843 struct drm_device *dev = encoder->base.dev;
844 struct drm_i915_private *dev_priv = dev->dev_private;
846 /* Prevents vblank waits from timing out in intel_tv_detect_type() */
847 intel_wait_for_vblank(encoder->base.dev,
848 to_intel_crtc(encoder->base.crtc)->pipe);
850 I915_WRITE(TV_CTL, I915_READ(TV_CTL) | TV_ENC_ENABLE);
853 static void
854 intel_disable_tv(struct intel_encoder *encoder)
856 struct drm_device *dev = encoder->base.dev;
857 struct drm_i915_private *dev_priv = dev->dev_private;
859 I915_WRITE(TV_CTL, I915_READ(TV_CTL) & ~TV_ENC_ENABLE);
862 static const struct tv_mode *
863 intel_tv_mode_lookup(const char *tv_format)
865 int i;
867 for (i = 0; i < ARRAY_SIZE(tv_modes); i++) {
868 const struct tv_mode *tv_mode = &tv_modes[i];
870 if (!strcmp(tv_format, tv_mode->name))
871 return tv_mode;
873 return NULL;
876 static const struct tv_mode *
877 intel_tv_mode_find(struct intel_tv *intel_tv)
879 return intel_tv_mode_lookup(intel_tv->tv_format);
882 static enum drm_mode_status
883 intel_tv_mode_valid(struct drm_connector *connector,
884 struct drm_display_mode *mode)
886 struct intel_tv *intel_tv = intel_attached_tv(connector);
887 const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv);
888 int max_dotclk = to_i915(connector->dev)->max_dotclk_freq;
890 if (mode->clock > max_dotclk)
891 return MODE_CLOCK_HIGH;
893 /* Ensure TV refresh is close to desired refresh */
894 if (tv_mode && abs(tv_mode->refresh - drm_mode_vrefresh(mode) * 1000)
895 < 1000)
896 return MODE_OK;
898 return MODE_CLOCK_RANGE;
902 static void
903 intel_tv_get_config(struct intel_encoder *encoder,
904 struct intel_crtc_state *pipe_config)
906 pipe_config->base.adjusted_mode.crtc_clock = pipe_config->port_clock;
909 static bool
910 intel_tv_compute_config(struct intel_encoder *encoder,
911 struct intel_crtc_state *pipe_config)
913 struct intel_tv *intel_tv = enc_to_tv(encoder);
914 const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv);
916 if (!tv_mode)
917 return false;
919 pipe_config->base.adjusted_mode.crtc_clock = tv_mode->clock;
920 DRM_DEBUG_KMS("forcing bpc to 8 for TV\n");
921 pipe_config->pipe_bpp = 8*3;
923 /* TV has it's own notion of sync and other mode flags, so clear them. */
924 pipe_config->base.adjusted_mode.flags = 0;
927 * FIXME: We don't check whether the input mode is actually what we want
928 * or whether userspace is doing something stupid.
931 return true;
934 static void
935 set_tv_mode_timings(struct drm_i915_private *dev_priv,
936 const struct tv_mode *tv_mode,
937 bool burst_ena)
939 u32 hctl1, hctl2, hctl3;
940 u32 vctl1, vctl2, vctl3, vctl4, vctl5, vctl6, vctl7;
942 hctl1 = (tv_mode->hsync_end << TV_HSYNC_END_SHIFT) |
943 (tv_mode->htotal << TV_HTOTAL_SHIFT);
945 hctl2 = (tv_mode->hburst_start << 16) |
946 (tv_mode->hburst_len << TV_HBURST_LEN_SHIFT);
948 if (burst_ena)
949 hctl2 |= TV_BURST_ENA;
951 hctl3 = (tv_mode->hblank_start << TV_HBLANK_START_SHIFT) |
952 (tv_mode->hblank_end << TV_HBLANK_END_SHIFT);
954 vctl1 = (tv_mode->nbr_end << TV_NBR_END_SHIFT) |
955 (tv_mode->vi_end_f1 << TV_VI_END_F1_SHIFT) |
956 (tv_mode->vi_end_f2 << TV_VI_END_F2_SHIFT);
958 vctl2 = (tv_mode->vsync_len << TV_VSYNC_LEN_SHIFT) |
959 (tv_mode->vsync_start_f1 << TV_VSYNC_START_F1_SHIFT) |
960 (tv_mode->vsync_start_f2 << TV_VSYNC_START_F2_SHIFT);
962 vctl3 = (tv_mode->veq_len << TV_VEQ_LEN_SHIFT) |
963 (tv_mode->veq_start_f1 << TV_VEQ_START_F1_SHIFT) |
964 (tv_mode->veq_start_f2 << TV_VEQ_START_F2_SHIFT);
966 if (tv_mode->veq_ena)
967 vctl3 |= TV_EQUAL_ENA;
969 vctl4 = (tv_mode->vburst_start_f1 << TV_VBURST_START_F1_SHIFT) |
970 (tv_mode->vburst_end_f1 << TV_VBURST_END_F1_SHIFT);
972 vctl5 = (tv_mode->vburst_start_f2 << TV_VBURST_START_F2_SHIFT) |
973 (tv_mode->vburst_end_f2 << TV_VBURST_END_F2_SHIFT);
975 vctl6 = (tv_mode->vburst_start_f3 << TV_VBURST_START_F3_SHIFT) |
976 (tv_mode->vburst_end_f3 << TV_VBURST_END_F3_SHIFT);
978 vctl7 = (tv_mode->vburst_start_f4 << TV_VBURST_START_F4_SHIFT) |
979 (tv_mode->vburst_end_f4 << TV_VBURST_END_F4_SHIFT);
981 I915_WRITE(TV_H_CTL_1, hctl1);
982 I915_WRITE(TV_H_CTL_2, hctl2);
983 I915_WRITE(TV_H_CTL_3, hctl3);
984 I915_WRITE(TV_V_CTL_1, vctl1);
985 I915_WRITE(TV_V_CTL_2, vctl2);
986 I915_WRITE(TV_V_CTL_3, vctl3);
987 I915_WRITE(TV_V_CTL_4, vctl4);
988 I915_WRITE(TV_V_CTL_5, vctl5);
989 I915_WRITE(TV_V_CTL_6, vctl6);
990 I915_WRITE(TV_V_CTL_7, vctl7);
993 static void set_color_conversion(struct drm_i915_private *dev_priv,
994 const struct color_conversion *color_conversion)
996 if (!color_conversion)
997 return;
999 I915_WRITE(TV_CSC_Y, (color_conversion->ry << 16) |
1000 color_conversion->gy);
1001 I915_WRITE(TV_CSC_Y2, (color_conversion->by << 16) |
1002 color_conversion->ay);
1003 I915_WRITE(TV_CSC_U, (color_conversion->ru << 16) |
1004 color_conversion->gu);
1005 I915_WRITE(TV_CSC_U2, (color_conversion->bu << 16) |
1006 color_conversion->au);
1007 I915_WRITE(TV_CSC_V, (color_conversion->rv << 16) |
1008 color_conversion->gv);
1009 I915_WRITE(TV_CSC_V2, (color_conversion->bv << 16) |
1010 color_conversion->av);
1013 static void intel_tv_pre_enable(struct intel_encoder *encoder)
1015 struct drm_device *dev = encoder->base.dev;
1016 struct drm_i915_private *dev_priv = dev->dev_private;
1017 struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc);
1018 struct intel_tv *intel_tv = enc_to_tv(encoder);
1019 const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv);
1020 u32 tv_ctl;
1021 u32 scctl1, scctl2, scctl3;
1022 int i, j;
1023 const struct video_levels *video_levels;
1024 const struct color_conversion *color_conversion;
1025 bool burst_ena;
1026 int xpos = 0x0, ypos = 0x0;
1027 unsigned int xsize, ysize;
1029 if (!tv_mode)
1030 return; /* can't happen (mode_prepare prevents this) */
1032 tv_ctl = I915_READ(TV_CTL);
1033 tv_ctl &= TV_CTL_SAVE;
1035 switch (intel_tv->type) {
1036 default:
1037 case DRM_MODE_CONNECTOR_Unknown:
1038 case DRM_MODE_CONNECTOR_Composite:
1039 tv_ctl |= TV_ENC_OUTPUT_COMPOSITE;
1040 video_levels = tv_mode->composite_levels;
1041 color_conversion = tv_mode->composite_color;
1042 burst_ena = tv_mode->burst_ena;
1043 break;
1044 case DRM_MODE_CONNECTOR_Component:
1045 tv_ctl |= TV_ENC_OUTPUT_COMPONENT;
1046 video_levels = &component_levels;
1047 if (tv_mode->burst_ena)
1048 color_conversion = &sdtv_csc_yprpb;
1049 else
1050 color_conversion = &hdtv_csc_yprpb;
1051 burst_ena = false;
1052 break;
1053 case DRM_MODE_CONNECTOR_SVIDEO:
1054 tv_ctl |= TV_ENC_OUTPUT_SVIDEO;
1055 video_levels = tv_mode->svideo_levels;
1056 color_conversion = tv_mode->svideo_color;
1057 burst_ena = tv_mode->burst_ena;
1058 break;
1061 if (intel_crtc->pipe == 1)
1062 tv_ctl |= TV_ENC_PIPEB_SELECT;
1063 tv_ctl |= tv_mode->oversample;
1065 if (tv_mode->progressive)
1066 tv_ctl |= TV_PROGRESSIVE;
1067 if (tv_mode->trilevel_sync)
1068 tv_ctl |= TV_TRILEVEL_SYNC;
1069 if (tv_mode->pal_burst)
1070 tv_ctl |= TV_PAL_BURST;
1072 scctl1 = 0;
1073 if (tv_mode->dda1_inc)
1074 scctl1 |= TV_SC_DDA1_EN;
1075 if (tv_mode->dda2_inc)
1076 scctl1 |= TV_SC_DDA2_EN;
1077 if (tv_mode->dda3_inc)
1078 scctl1 |= TV_SC_DDA3_EN;
1079 scctl1 |= tv_mode->sc_reset;
1080 if (video_levels)
1081 scctl1 |= video_levels->burst << TV_BURST_LEVEL_SHIFT;
1082 scctl1 |= tv_mode->dda1_inc << TV_SCDDA1_INC_SHIFT;
1084 scctl2 = tv_mode->dda2_size << TV_SCDDA2_SIZE_SHIFT |
1085 tv_mode->dda2_inc << TV_SCDDA2_INC_SHIFT;
1087 scctl3 = tv_mode->dda3_size << TV_SCDDA3_SIZE_SHIFT |
1088 tv_mode->dda3_inc << TV_SCDDA3_INC_SHIFT;
1090 /* Enable two fixes for the chips that need them. */
1091 if (IS_I915GM(dev))
1092 tv_ctl |= TV_ENC_C0_FIX | TV_ENC_SDP_FIX;
1094 set_tv_mode_timings(dev_priv, tv_mode, burst_ena);
1096 I915_WRITE(TV_SC_CTL_1, scctl1);
1097 I915_WRITE(TV_SC_CTL_2, scctl2);
1098 I915_WRITE(TV_SC_CTL_3, scctl3);
1100 set_color_conversion(dev_priv, color_conversion);
1102 if (INTEL_INFO(dev)->gen >= 4)
1103 I915_WRITE(TV_CLR_KNOBS, 0x00404000);
1104 else
1105 I915_WRITE(TV_CLR_KNOBS, 0x00606000);
1107 if (video_levels)
1108 I915_WRITE(TV_CLR_LEVEL,
1109 ((video_levels->black << TV_BLACK_LEVEL_SHIFT) |
1110 (video_levels->blank << TV_BLANK_LEVEL_SHIFT)));
1112 assert_pipe_disabled(dev_priv, intel_crtc->pipe);
1114 /* Filter ctl must be set before TV_WIN_SIZE */
1115 I915_WRITE(TV_FILTER_CTL_1, TV_AUTO_SCALE);
1116 xsize = tv_mode->hblank_start - tv_mode->hblank_end;
1117 if (tv_mode->progressive)
1118 ysize = tv_mode->nbr_end + 1;
1119 else
1120 ysize = 2*tv_mode->nbr_end + 1;
1122 xpos += intel_tv->margin[TV_MARGIN_LEFT];
1123 ypos += intel_tv->margin[TV_MARGIN_TOP];
1124 xsize -= (intel_tv->margin[TV_MARGIN_LEFT] +
1125 intel_tv->margin[TV_MARGIN_RIGHT]);
1126 ysize -= (intel_tv->margin[TV_MARGIN_TOP] +
1127 intel_tv->margin[TV_MARGIN_BOTTOM]);
1128 I915_WRITE(TV_WIN_POS, (xpos<<16)|ypos);
1129 I915_WRITE(TV_WIN_SIZE, (xsize<<16)|ysize);
1131 j = 0;
1132 for (i = 0; i < 60; i++)
1133 I915_WRITE(TV_H_LUMA(i), tv_mode->filter_table[j++]);
1134 for (i = 0; i < 60; i++)
1135 I915_WRITE(TV_H_CHROMA(i), tv_mode->filter_table[j++]);
1136 for (i = 0; i < 43; i++)
1137 I915_WRITE(TV_V_LUMA(i), tv_mode->filter_table[j++]);
1138 for (i = 0; i < 43; i++)
1139 I915_WRITE(TV_V_CHROMA(i), tv_mode->filter_table[j++]);
1140 I915_WRITE(TV_DAC, I915_READ(TV_DAC) & TV_DAC_SAVE);
1141 I915_WRITE(TV_CTL, tv_ctl);
1144 static const struct drm_display_mode reported_modes[] = {
1146 .name = "NTSC 480i",
1147 .clock = 107520,
1148 .hdisplay = 1280,
1149 .hsync_start = 1368,
1150 .hsync_end = 1496,
1151 .htotal = 1712,
1153 .vdisplay = 1024,
1154 .vsync_start = 1027,
1155 .vsync_end = 1034,
1156 .vtotal = 1104,
1157 .type = DRM_MODE_TYPE_DRIVER,
1162 * Detects TV presence by checking for load.
1164 * Requires that the current pipe's DPLL is active.
1166 * \return true if TV is connected.
1167 * \return false if TV is disconnected.
1169 static int
1170 intel_tv_detect_type(struct intel_tv *intel_tv,
1171 struct drm_connector *connector)
1173 struct drm_crtc *crtc = connector->state->crtc;
1174 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
1175 struct drm_device *dev = connector->dev;
1176 struct drm_i915_private *dev_priv = dev->dev_private;
1177 u32 tv_ctl, save_tv_ctl;
1178 u32 tv_dac, save_tv_dac;
1179 int type;
1181 /* Disable TV interrupts around load detect or we'll recurse */
1182 if (connector->polled & DRM_CONNECTOR_POLL_HPD) {
1183 spin_lock_irq(&dev_priv->irq_lock);
1184 i915_disable_pipestat(dev_priv, 0,
1185 PIPE_HOTPLUG_INTERRUPT_STATUS |
1186 PIPE_HOTPLUG_TV_INTERRUPT_STATUS);
1187 spin_unlock_irq(&dev_priv->irq_lock);
1190 save_tv_dac = tv_dac = I915_READ(TV_DAC);
1191 save_tv_ctl = tv_ctl = I915_READ(TV_CTL);
1193 /* Poll for TV detection */
1194 tv_ctl &= ~(TV_ENC_ENABLE | TV_TEST_MODE_MASK);
1195 tv_ctl |= TV_TEST_MODE_MONITOR_DETECT;
1196 if (intel_crtc->pipe == 1)
1197 tv_ctl |= TV_ENC_PIPEB_SELECT;
1198 else
1199 tv_ctl &= ~TV_ENC_PIPEB_SELECT;
1201 tv_dac &= ~(TVDAC_SENSE_MASK | DAC_A_MASK | DAC_B_MASK | DAC_C_MASK);
1202 tv_dac |= (TVDAC_STATE_CHG_EN |
1203 TVDAC_A_SENSE_CTL |
1204 TVDAC_B_SENSE_CTL |
1205 TVDAC_C_SENSE_CTL |
1206 DAC_CTL_OVERRIDE |
1207 DAC_A_0_7_V |
1208 DAC_B_0_7_V |
1209 DAC_C_0_7_V);
1213 * The TV sense state should be cleared to zero on cantiga platform. Otherwise
1214 * the TV is misdetected. This is hardware requirement.
1216 if (IS_GM45(dev))
1217 tv_dac &= ~(TVDAC_STATE_CHG_EN | TVDAC_A_SENSE_CTL |
1218 TVDAC_B_SENSE_CTL | TVDAC_C_SENSE_CTL);
1220 I915_WRITE(TV_CTL, tv_ctl);
1221 I915_WRITE(TV_DAC, tv_dac);
1222 POSTING_READ(TV_DAC);
1224 intel_wait_for_vblank(dev, intel_crtc->pipe);
1226 type = -1;
1227 tv_dac = I915_READ(TV_DAC);
1228 DRM_DEBUG_KMS("TV detected: %x, %x\n", tv_ctl, tv_dac);
1230 * A B C
1231 * 0 1 1 Composite
1232 * 1 0 X svideo
1233 * 0 0 0 Component
1235 if ((tv_dac & TVDAC_SENSE_MASK) == (TVDAC_B_SENSE | TVDAC_C_SENSE)) {
1236 DRM_DEBUG_KMS("Detected Composite TV connection\n");
1237 type = DRM_MODE_CONNECTOR_Composite;
1238 } else if ((tv_dac & (TVDAC_A_SENSE|TVDAC_B_SENSE)) == TVDAC_A_SENSE) {
1239 DRM_DEBUG_KMS("Detected S-Video TV connection\n");
1240 type = DRM_MODE_CONNECTOR_SVIDEO;
1241 } else if ((tv_dac & TVDAC_SENSE_MASK) == 0) {
1242 DRM_DEBUG_KMS("Detected Component TV connection\n");
1243 type = DRM_MODE_CONNECTOR_Component;
1244 } else {
1245 DRM_DEBUG_KMS("Unrecognised TV connection\n");
1246 type = -1;
1249 I915_WRITE(TV_DAC, save_tv_dac & ~TVDAC_STATE_CHG_EN);
1250 I915_WRITE(TV_CTL, save_tv_ctl);
1251 POSTING_READ(TV_CTL);
1253 /* For unknown reasons the hw barfs if we don't do this vblank wait. */
1254 intel_wait_for_vblank(dev, intel_crtc->pipe);
1256 /* Restore interrupt config */
1257 if (connector->polled & DRM_CONNECTOR_POLL_HPD) {
1258 spin_lock_irq(&dev_priv->irq_lock);
1259 i915_enable_pipestat(dev_priv, 0,
1260 PIPE_HOTPLUG_INTERRUPT_STATUS |
1261 PIPE_HOTPLUG_TV_INTERRUPT_STATUS);
1262 spin_unlock_irq(&dev_priv->irq_lock);
1265 return type;
1269 * Here we set accurate tv format according to connector type
1270 * i.e Component TV should not be assigned by NTSC or PAL
1272 static void intel_tv_find_better_format(struct drm_connector *connector)
1274 struct intel_tv *intel_tv = intel_attached_tv(connector);
1275 const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv);
1276 int i;
1278 if ((intel_tv->type == DRM_MODE_CONNECTOR_Component) ==
1279 tv_mode->component_only)
1280 return;
1283 for (i = 0; i < ARRAY_SIZE(tv_modes); i++) {
1284 tv_mode = tv_modes + i;
1286 if ((intel_tv->type == DRM_MODE_CONNECTOR_Component) ==
1287 tv_mode->component_only)
1288 break;
1291 intel_tv->tv_format = tv_mode->name;
1292 drm_object_property_set_value(&connector->base,
1293 connector->dev->mode_config.tv_mode_property, i);
1297 * Detect the TV connection.
1299 * Currently this always returns CONNECTOR_STATUS_UNKNOWN, as we need to be sure
1300 * we have a pipe programmed in order to probe the TV.
1302 static enum drm_connector_status
1303 intel_tv_detect(struct drm_connector *connector, bool force)
1305 struct drm_display_mode mode;
1306 struct intel_tv *intel_tv = intel_attached_tv(connector);
1307 enum drm_connector_status status;
1308 int type;
1310 DRM_DEBUG_KMS("[CONNECTOR:%d:%s] force=%d\n",
1311 connector->base.id, connector->name,
1312 force);
1314 mode = reported_modes[0];
1316 if (force) {
1317 struct intel_load_detect_pipe tmp;
1318 struct drm_modeset_acquire_ctx ctx;
1320 drm_modeset_acquire_init(&ctx, 0);
1322 if (intel_get_load_detect_pipe(connector, &mode, &tmp, &ctx)) {
1323 type = intel_tv_detect_type(intel_tv, connector);
1324 intel_release_load_detect_pipe(connector, &tmp, &ctx);
1325 status = type < 0 ?
1326 connector_status_disconnected :
1327 connector_status_connected;
1328 } else
1329 status = connector_status_unknown;
1331 drm_modeset_drop_locks(&ctx);
1332 drm_modeset_acquire_fini(&ctx);
1333 } else
1334 return connector->status;
1336 if (status != connector_status_connected)
1337 return status;
1339 intel_tv->type = type;
1340 intel_tv_find_better_format(connector);
1342 return connector_status_connected;
1345 static const struct input_res {
1346 const char *name;
1347 int w, h;
1348 } input_res_table[] = {
1349 {"640x480", 640, 480},
1350 {"800x600", 800, 600},
1351 {"1024x768", 1024, 768},
1352 {"1280x1024", 1280, 1024},
1353 {"848x480", 848, 480},
1354 {"1280x720", 1280, 720},
1355 {"1920x1080", 1920, 1080},
1359 * Chose preferred mode according to line number of TV format
1361 static void
1362 intel_tv_chose_preferred_modes(struct drm_connector *connector,
1363 struct drm_display_mode *mode_ptr)
1365 struct intel_tv *intel_tv = intel_attached_tv(connector);
1366 const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv);
1368 if (tv_mode->nbr_end < 480 && mode_ptr->vdisplay == 480)
1369 mode_ptr->type |= DRM_MODE_TYPE_PREFERRED;
1370 else if (tv_mode->nbr_end > 480) {
1371 if (tv_mode->progressive == true && tv_mode->nbr_end < 720) {
1372 if (mode_ptr->vdisplay == 720)
1373 mode_ptr->type |= DRM_MODE_TYPE_PREFERRED;
1374 } else if (mode_ptr->vdisplay == 1080)
1375 mode_ptr->type |= DRM_MODE_TYPE_PREFERRED;
1380 * Stub get_modes function.
1382 * This should probably return a set of fixed modes, unless we can figure out
1383 * how to probe modes off of TV connections.
1386 static int
1387 intel_tv_get_modes(struct drm_connector *connector)
1389 struct drm_display_mode *mode_ptr;
1390 struct intel_tv *intel_tv = intel_attached_tv(connector);
1391 const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv);
1392 int j, count = 0;
1393 u64 tmp;
1395 for (j = 0; j < ARRAY_SIZE(input_res_table);
1396 j++) {
1397 const struct input_res *input = &input_res_table[j];
1398 unsigned int hactive_s = input->w;
1399 unsigned int vactive_s = input->h;
1401 if (tv_mode->max_srcw && input->w > tv_mode->max_srcw)
1402 continue;
1404 if (input->w > 1024 && (!tv_mode->progressive
1405 && !tv_mode->component_only))
1406 continue;
1408 mode_ptr = drm_mode_create(connector->dev);
1409 if (!mode_ptr)
1410 continue;
1411 strncpy(mode_ptr->name, input->name, DRM_DISPLAY_MODE_LEN);
1412 mode_ptr->name[DRM_DISPLAY_MODE_LEN - 1] = '\0';
1414 mode_ptr->hdisplay = hactive_s;
1415 mode_ptr->hsync_start = hactive_s + 1;
1416 mode_ptr->hsync_end = hactive_s + 64;
1417 if (mode_ptr->hsync_end <= mode_ptr->hsync_start)
1418 mode_ptr->hsync_end = mode_ptr->hsync_start + 1;
1419 mode_ptr->htotal = hactive_s + 96;
1421 mode_ptr->vdisplay = vactive_s;
1422 mode_ptr->vsync_start = vactive_s + 1;
1423 mode_ptr->vsync_end = vactive_s + 32;
1424 if (mode_ptr->vsync_end <= mode_ptr->vsync_start)
1425 mode_ptr->vsync_end = mode_ptr->vsync_start + 1;
1426 mode_ptr->vtotal = vactive_s + 33;
1428 tmp = (u64) tv_mode->refresh * mode_ptr->vtotal;
1429 tmp *= mode_ptr->htotal;
1430 tmp = div_u64(tmp, 1000000);
1431 mode_ptr->clock = (int) tmp;
1433 mode_ptr->type = DRM_MODE_TYPE_DRIVER;
1434 intel_tv_chose_preferred_modes(connector, mode_ptr);
1435 drm_mode_probed_add(connector, mode_ptr);
1436 count++;
1439 return count;
1442 static void
1443 intel_tv_destroy(struct drm_connector *connector)
1445 drm_connector_cleanup(connector);
1446 kfree(connector);
1450 static int
1451 intel_tv_set_property(struct drm_connector *connector, struct drm_property *property,
1452 uint64_t val)
1454 struct drm_device *dev = connector->dev;
1455 struct intel_tv *intel_tv = intel_attached_tv(connector);
1456 struct drm_crtc *crtc = intel_tv->base.base.crtc;
1457 int ret = 0;
1458 bool changed = false;
1460 ret = drm_object_property_set_value(&connector->base, property, val);
1461 if (ret < 0)
1462 goto out;
1464 if (property == dev->mode_config.tv_left_margin_property &&
1465 intel_tv->margin[TV_MARGIN_LEFT] != val) {
1466 intel_tv->margin[TV_MARGIN_LEFT] = val;
1467 changed = true;
1468 } else if (property == dev->mode_config.tv_right_margin_property &&
1469 intel_tv->margin[TV_MARGIN_RIGHT] != val) {
1470 intel_tv->margin[TV_MARGIN_RIGHT] = val;
1471 changed = true;
1472 } else if (property == dev->mode_config.tv_top_margin_property &&
1473 intel_tv->margin[TV_MARGIN_TOP] != val) {
1474 intel_tv->margin[TV_MARGIN_TOP] = val;
1475 changed = true;
1476 } else if (property == dev->mode_config.tv_bottom_margin_property &&
1477 intel_tv->margin[TV_MARGIN_BOTTOM] != val) {
1478 intel_tv->margin[TV_MARGIN_BOTTOM] = val;
1479 changed = true;
1480 } else if (property == dev->mode_config.tv_mode_property) {
1481 if (val >= ARRAY_SIZE(tv_modes)) {
1482 ret = -EINVAL;
1483 goto out;
1485 if (!strcmp(intel_tv->tv_format, tv_modes[val].name))
1486 goto out;
1488 intel_tv->tv_format = tv_modes[val].name;
1489 changed = true;
1490 } else {
1491 ret = -EINVAL;
1492 goto out;
1495 if (changed && crtc)
1496 intel_crtc_restore_mode(crtc);
1497 out:
1498 return ret;
1501 static const struct drm_connector_funcs intel_tv_connector_funcs = {
1502 .dpms = drm_atomic_helper_connector_dpms,
1503 .detect = intel_tv_detect,
1504 .destroy = intel_tv_destroy,
1505 .set_property = intel_tv_set_property,
1506 .atomic_get_property = intel_connector_atomic_get_property,
1507 .fill_modes = drm_helper_probe_single_connector_modes,
1508 .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
1509 .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
1512 static const struct drm_connector_helper_funcs intel_tv_connector_helper_funcs = {
1513 .mode_valid = intel_tv_mode_valid,
1514 .get_modes = intel_tv_get_modes,
1515 .best_encoder = intel_best_encoder,
1518 static const struct drm_encoder_funcs intel_tv_enc_funcs = {
1519 .destroy = intel_encoder_destroy,
1522 void
1523 intel_tv_init(struct drm_device *dev)
1525 struct drm_i915_private *dev_priv = dev->dev_private;
1526 struct drm_connector *connector;
1527 struct intel_tv *intel_tv;
1528 struct intel_encoder *intel_encoder;
1529 struct intel_connector *intel_connector;
1530 u32 tv_dac_on, tv_dac_off, save_tv_dac;
1531 const char *tv_format_names[ARRAY_SIZE(tv_modes)];
1532 int i, initial_mode = 0;
1534 if ((I915_READ(TV_CTL) & TV_FUSE_STATE_MASK) == TV_FUSE_STATE_DISABLED)
1535 return;
1537 if (!intel_bios_is_tv_present(dev_priv)) {
1538 DRM_DEBUG_KMS("Integrated TV is not present.\n");
1539 return;
1543 * Sanity check the TV output by checking to see if the
1544 * DAC register holds a value
1546 save_tv_dac = I915_READ(TV_DAC);
1548 I915_WRITE(TV_DAC, save_tv_dac | TVDAC_STATE_CHG_EN);
1549 tv_dac_on = I915_READ(TV_DAC);
1551 I915_WRITE(TV_DAC, save_tv_dac & ~TVDAC_STATE_CHG_EN);
1552 tv_dac_off = I915_READ(TV_DAC);
1554 I915_WRITE(TV_DAC, save_tv_dac);
1557 * If the register does not hold the state change enable
1558 * bit, (either as a 0 or a 1), assume it doesn't really
1559 * exist
1561 if ((tv_dac_on & TVDAC_STATE_CHG_EN) == 0 ||
1562 (tv_dac_off & TVDAC_STATE_CHG_EN) != 0)
1563 return;
1565 intel_tv = kzalloc(sizeof(*intel_tv), GFP_KERNEL);
1566 if (!intel_tv) {
1567 return;
1570 intel_connector = intel_connector_alloc();
1571 if (!intel_connector) {
1572 kfree(intel_tv);
1573 return;
1576 intel_encoder = &intel_tv->base;
1577 connector = &intel_connector->base;
1579 /* The documentation, for the older chipsets at least, recommend
1580 * using a polling method rather than hotplug detection for TVs.
1581 * This is because in order to perform the hotplug detection, the PLLs
1582 * for the TV must be kept alive increasing power drain and starving
1583 * bandwidth from other encoders. Notably for instance, it causes
1584 * pipe underruns on Crestline when this encoder is supposedly idle.
1586 * More recent chipsets favour HDMI rather than integrated S-Video.
1588 intel_connector->polled = DRM_CONNECTOR_POLL_CONNECT;
1590 drm_connector_init(dev, connector, &intel_tv_connector_funcs,
1591 DRM_MODE_CONNECTOR_SVIDEO);
1593 drm_encoder_init(dev, &intel_encoder->base, &intel_tv_enc_funcs,
1594 DRM_MODE_ENCODER_TVDAC, NULL);
1596 intel_encoder->compute_config = intel_tv_compute_config;
1597 intel_encoder->get_config = intel_tv_get_config;
1598 intel_encoder->pre_enable = intel_tv_pre_enable;
1599 intel_encoder->enable = intel_enable_tv;
1600 intel_encoder->disable = intel_disable_tv;
1601 intel_encoder->get_hw_state = intel_tv_get_hw_state;
1602 intel_connector->get_hw_state = intel_connector_get_hw_state;
1603 intel_connector->unregister = intel_connector_unregister;
1605 intel_connector_attach_encoder(intel_connector, intel_encoder);
1606 intel_encoder->type = INTEL_OUTPUT_TVOUT;
1607 intel_encoder->crtc_mask = (1 << 0) | (1 << 1);
1608 intel_encoder->cloneable = 0;
1609 intel_encoder->base.possible_crtcs = ((1 << 0) | (1 << 1));
1610 intel_tv->type = DRM_MODE_CONNECTOR_Unknown;
1612 /* BIOS margin values */
1613 intel_tv->margin[TV_MARGIN_LEFT] = 54;
1614 intel_tv->margin[TV_MARGIN_TOP] = 36;
1615 intel_tv->margin[TV_MARGIN_RIGHT] = 46;
1616 intel_tv->margin[TV_MARGIN_BOTTOM] = 37;
1618 intel_tv->tv_format = tv_modes[initial_mode].name;
1620 drm_connector_helper_add(connector, &intel_tv_connector_helper_funcs);
1621 connector->interlace_allowed = false;
1622 connector->doublescan_allowed = false;
1624 /* Create TV properties then attach current values */
1625 for (i = 0; i < ARRAY_SIZE(tv_modes); i++)
1626 tv_format_names[i] = tv_modes[i].name;
1627 drm_mode_create_tv_properties(dev,
1628 ARRAY_SIZE(tv_modes),
1629 tv_format_names);
1631 drm_object_attach_property(&connector->base, dev->mode_config.tv_mode_property,
1632 initial_mode);
1633 drm_object_attach_property(&connector->base,
1634 dev->mode_config.tv_left_margin_property,
1635 intel_tv->margin[TV_MARGIN_LEFT]);
1636 drm_object_attach_property(&connector->base,
1637 dev->mode_config.tv_top_margin_property,
1638 intel_tv->margin[TV_MARGIN_TOP]);
1639 drm_object_attach_property(&connector->base,
1640 dev->mode_config.tv_right_margin_property,
1641 intel_tv->margin[TV_MARGIN_RIGHT]);
1642 drm_object_attach_property(&connector->base,
1643 dev->mode_config.tv_bottom_margin_property,
1644 intel_tv->margin[TV_MARGIN_BOTTOM]);
1645 drm_connector_register(connector);