vt: vt_ioctl: fix VT_DISALLOCATE freeing in-use virtual console
[linux/fpc-iii.git] / drivers / gpu / drm / i915 / intel_tv.c
blobb5b04cb892e945b747f20702b5740b4af572644f
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 struct intel_tv {
47 struct intel_encoder base;
49 int type;
52 struct video_levels {
53 u16 blank, black;
54 u8 burst;
57 struct color_conversion {
58 u16 ry, gy, by, ay;
59 u16 ru, gu, bu, au;
60 u16 rv, gv, bv, av;
63 static const u32 filter_table[] = {
64 0xB1403000, 0x2E203500, 0x35002E20, 0x3000B140,
65 0x35A0B160, 0x2DC02E80, 0xB1403480, 0xB1603000,
66 0x2EA03640, 0x34002D80, 0x3000B120, 0x36E0B160,
67 0x2D202EF0, 0xB1203380, 0xB1603000, 0x2F303780,
68 0x33002CC0, 0x3000B100, 0x3820B160, 0x2C802F50,
69 0xB10032A0, 0xB1603000, 0x2F9038C0, 0x32202C20,
70 0x3000B0E0, 0x3980B160, 0x2BC02FC0, 0xB0E031C0,
71 0xB1603000, 0x2FF03A20, 0x31602B60, 0xB020B0C0,
72 0x3AE0B160, 0x2B001810, 0xB0C03120, 0xB140B020,
73 0x18283BA0, 0x30C02A80, 0xB020B0A0, 0x3C60B140,
74 0x2A201838, 0xB0A03080, 0xB120B020, 0x18383D20,
75 0x304029C0, 0xB040B080, 0x3DE0B100, 0x29601848,
76 0xB0803000, 0xB100B040, 0x18483EC0, 0xB0402900,
77 0xB040B060, 0x3F80B0C0, 0x28801858, 0xB060B080,
78 0xB0A0B060, 0x18602820, 0xB0A02820, 0x0000B060,
79 0xB1403000, 0x2E203500, 0x35002E20, 0x3000B140,
80 0x35A0B160, 0x2DC02E80, 0xB1403480, 0xB1603000,
81 0x2EA03640, 0x34002D80, 0x3000B120, 0x36E0B160,
82 0x2D202EF0, 0xB1203380, 0xB1603000, 0x2F303780,
83 0x33002CC0, 0x3000B100, 0x3820B160, 0x2C802F50,
84 0xB10032A0, 0xB1603000, 0x2F9038C0, 0x32202C20,
85 0x3000B0E0, 0x3980B160, 0x2BC02FC0, 0xB0E031C0,
86 0xB1603000, 0x2FF03A20, 0x31602B60, 0xB020B0C0,
87 0x3AE0B160, 0x2B001810, 0xB0C03120, 0xB140B020,
88 0x18283BA0, 0x30C02A80, 0xB020B0A0, 0x3C60B140,
89 0x2A201838, 0xB0A03080, 0xB120B020, 0x18383D20,
90 0x304029C0, 0xB040B080, 0x3DE0B100, 0x29601848,
91 0xB0803000, 0xB100B040, 0x18483EC0, 0xB0402900,
92 0xB040B060, 0x3F80B0C0, 0x28801858, 0xB060B080,
93 0xB0A0B060, 0x18602820, 0xB0A02820, 0x0000B060,
94 0x36403000, 0x2D002CC0, 0x30003640, 0x2D0036C0,
95 0x35C02CC0, 0x37403000, 0x2C802D40, 0x30003540,
96 0x2D8037C0, 0x34C02C40, 0x38403000, 0x2BC02E00,
97 0x30003440, 0x2E2038C0, 0x34002B80, 0x39803000,
98 0x2B402E40, 0x30003380, 0x2E603A00, 0x33402B00,
99 0x3A803040, 0x2A802EA0, 0x30403300, 0x2EC03B40,
100 0x32802A40, 0x3C003040, 0x2A002EC0, 0x30803240,
101 0x2EC03C80, 0x320029C0, 0x3D403080, 0x29402F00,
102 0x308031C0, 0x2F203DC0, 0x31802900, 0x3E8030C0,
103 0x28802F40, 0x30C03140, 0x2F203F40, 0x31402840,
104 0x28003100, 0x28002F00, 0x00003100, 0x36403000,
105 0x2D002CC0, 0x30003640, 0x2D0036C0,
106 0x35C02CC0, 0x37403000, 0x2C802D40, 0x30003540,
107 0x2D8037C0, 0x34C02C40, 0x38403000, 0x2BC02E00,
108 0x30003440, 0x2E2038C0, 0x34002B80, 0x39803000,
109 0x2B402E40, 0x30003380, 0x2E603A00, 0x33402B00,
110 0x3A803040, 0x2A802EA0, 0x30403300, 0x2EC03B40,
111 0x32802A40, 0x3C003040, 0x2A002EC0, 0x30803240,
112 0x2EC03C80, 0x320029C0, 0x3D403080, 0x29402F00,
113 0x308031C0, 0x2F203DC0, 0x31802900, 0x3E8030C0,
114 0x28802F40, 0x30C03140, 0x2F203F40, 0x31402840,
115 0x28003100, 0x28002F00, 0x00003100,
119 * Color conversion values have 3 separate fixed point formats:
121 * 10 bit fields (ay, au)
122 * 1.9 fixed point (b.bbbbbbbbb)
123 * 11 bit fields (ry, by, ru, gu, gv)
124 * exp.mantissa (ee.mmmmmmmmm)
125 * ee = 00 = 10^-1 (0.mmmmmmmmm)
126 * ee = 01 = 10^-2 (0.0mmmmmmmmm)
127 * ee = 10 = 10^-3 (0.00mmmmmmmmm)
128 * ee = 11 = 10^-4 (0.000mmmmmmmmm)
129 * 12 bit fields (gy, rv, bu)
130 * exp.mantissa (eee.mmmmmmmmm)
131 * eee = 000 = 10^-1 (0.mmmmmmmmm)
132 * eee = 001 = 10^-2 (0.0mmmmmmmmm)
133 * eee = 010 = 10^-3 (0.00mmmmmmmmm)
134 * eee = 011 = 10^-4 (0.000mmmmmmmmm)
135 * eee = 100 = reserved
136 * eee = 101 = reserved
137 * eee = 110 = reserved
138 * eee = 111 = 10^0 (m.mmmmmmmm) (only usable for 1.0 representation)
140 * Saturation and contrast are 8 bits, with their own representation:
141 * 8 bit field (saturation, contrast)
142 * exp.mantissa (ee.mmmmmm)
143 * ee = 00 = 10^-1 (0.mmmmmm)
144 * ee = 01 = 10^0 (m.mmmmm)
145 * ee = 10 = 10^1 (mm.mmmm)
146 * ee = 11 = 10^2 (mmm.mmm)
148 * Simple conversion function:
150 * static u32
151 * float_to_csc_11(float f)
153 * u32 exp;
154 * u32 mant;
155 * u32 ret;
157 * if (f < 0)
158 * f = -f;
160 * if (f >= 1) {
161 * exp = 0x7;
162 * mant = 1 << 8;
163 * } else {
164 * for (exp = 0; exp < 3 && f < 0.5; exp++)
165 * f *= 2.0;
166 * mant = (f * (1 << 9) + 0.5);
167 * if (mant >= (1 << 9))
168 * mant = (1 << 9) - 1;
170 * ret = (exp << 9) | mant;
171 * return ret;
176 * Behold, magic numbers! If we plant them they might grow a big
177 * s-video cable to the sky... or something.
179 * Pre-converted to appropriate hex value.
183 * PAL & NTSC values for composite & s-video connections
185 static const struct color_conversion ntsc_m_csc_composite = {
186 .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0104,
187 .ru = 0x0733, .gu = 0x052d, .bu = 0x05c7, .au = 0x0200,
188 .rv = 0x0340, .gv = 0x030c, .bv = 0x06d0, .av = 0x0200,
191 static const struct video_levels ntsc_m_levels_composite = {
192 .blank = 225, .black = 267, .burst = 113,
195 static const struct color_conversion ntsc_m_csc_svideo = {
196 .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0133,
197 .ru = 0x076a, .gu = 0x0564, .bu = 0x030d, .au = 0x0200,
198 .rv = 0x037a, .gv = 0x033d, .bv = 0x06f6, .av = 0x0200,
201 static const struct video_levels ntsc_m_levels_svideo = {
202 .blank = 266, .black = 316, .burst = 133,
205 static const struct color_conversion ntsc_j_csc_composite = {
206 .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0119,
207 .ru = 0x074c, .gu = 0x0546, .bu = 0x05ec, .au = 0x0200,
208 .rv = 0x035a, .gv = 0x0322, .bv = 0x06e1, .av = 0x0200,
211 static const struct video_levels ntsc_j_levels_composite = {
212 .blank = 225, .black = 225, .burst = 113,
215 static const struct color_conversion ntsc_j_csc_svideo = {
216 .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x014c,
217 .ru = 0x0788, .gu = 0x0581, .bu = 0x0322, .au = 0x0200,
218 .rv = 0x0399, .gv = 0x0356, .bv = 0x070a, .av = 0x0200,
221 static const struct video_levels ntsc_j_levels_svideo = {
222 .blank = 266, .black = 266, .burst = 133,
225 static const struct color_conversion pal_csc_composite = {
226 .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0113,
227 .ru = 0x0745, .gu = 0x053f, .bu = 0x05e1, .au = 0x0200,
228 .rv = 0x0353, .gv = 0x031c, .bv = 0x06dc, .av = 0x0200,
231 static const struct video_levels pal_levels_composite = {
232 .blank = 237, .black = 237, .burst = 118,
235 static const struct color_conversion pal_csc_svideo = {
236 .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0145,
237 .ru = 0x0780, .gu = 0x0579, .bu = 0x031c, .au = 0x0200,
238 .rv = 0x0390, .gv = 0x034f, .bv = 0x0705, .av = 0x0200,
241 static const struct video_levels pal_levels_svideo = {
242 .blank = 280, .black = 280, .burst = 139,
245 static const struct color_conversion pal_m_csc_composite = {
246 .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0104,
247 .ru = 0x0733, .gu = 0x052d, .bu = 0x05c7, .au = 0x0200,
248 .rv = 0x0340, .gv = 0x030c, .bv = 0x06d0, .av = 0x0200,
251 static const struct video_levels pal_m_levels_composite = {
252 .blank = 225, .black = 267, .burst = 113,
255 static const struct color_conversion pal_m_csc_svideo = {
256 .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0133,
257 .ru = 0x076a, .gu = 0x0564, .bu = 0x030d, .au = 0x0200,
258 .rv = 0x037a, .gv = 0x033d, .bv = 0x06f6, .av = 0x0200,
261 static const struct video_levels pal_m_levels_svideo = {
262 .blank = 266, .black = 316, .burst = 133,
265 static const struct color_conversion pal_n_csc_composite = {
266 .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0104,
267 .ru = 0x0733, .gu = 0x052d, .bu = 0x05c7, .au = 0x0200,
268 .rv = 0x0340, .gv = 0x030c, .bv = 0x06d0, .av = 0x0200,
271 static const struct video_levels pal_n_levels_composite = {
272 .blank = 225, .black = 267, .burst = 118,
275 static const struct color_conversion pal_n_csc_svideo = {
276 .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0133,
277 .ru = 0x076a, .gu = 0x0564, .bu = 0x030d, .au = 0x0200,
278 .rv = 0x037a, .gv = 0x033d, .bv = 0x06f6, .av = 0x0200,
281 static const struct video_levels pal_n_levels_svideo = {
282 .blank = 266, .black = 316, .burst = 139,
286 * Component connections
288 static const struct color_conversion sdtv_csc_yprpb = {
289 .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0145,
290 .ru = 0x0559, .gu = 0x0353, .bu = 0x0100, .au = 0x0200,
291 .rv = 0x0100, .gv = 0x03ad, .bv = 0x074d, .av = 0x0200,
294 static const struct color_conversion hdtv_csc_yprpb = {
295 .ry = 0x05b3, .gy = 0x016e, .by = 0x0728, .ay = 0x0145,
296 .ru = 0x07d5, .gu = 0x038b, .bu = 0x0100, .au = 0x0200,
297 .rv = 0x0100, .gv = 0x03d1, .bv = 0x06bc, .av = 0x0200,
300 static const struct video_levels component_levels = {
301 .blank = 279, .black = 279, .burst = 0,
305 struct tv_mode {
306 const char *name;
308 u32 clock;
309 u16 refresh; /* in millihertz (for precision) */
310 u32 oversample;
311 u8 hsync_end;
312 u16 hblank_start, hblank_end, htotal;
313 bool progressive : 1, trilevel_sync : 1, component_only : 1;
314 u8 vsync_start_f1, vsync_start_f2, vsync_len;
315 bool veq_ena : 1;
316 u8 veq_start_f1, veq_start_f2, veq_len;
317 u8 vi_end_f1, vi_end_f2;
318 u16 nbr_end;
319 bool burst_ena : 1;
320 u8 hburst_start, hburst_len;
321 u8 vburst_start_f1;
322 u16 vburst_end_f1;
323 u8 vburst_start_f2;
324 u16 vburst_end_f2;
325 u8 vburst_start_f3;
326 u16 vburst_end_f3;
327 u8 vburst_start_f4;
328 u16 vburst_end_f4;
330 * subcarrier programming
332 u16 dda2_size, dda3_size;
333 u8 dda1_inc;
334 u16 dda2_inc, dda3_inc;
335 u32 sc_reset;
336 bool pal_burst : 1;
338 * blank/black levels
340 const struct video_levels *composite_levels, *svideo_levels;
341 const struct color_conversion *composite_color, *svideo_color;
342 const u32 *filter_table;
343 u16 max_srcw;
348 * Sub carrier DDA
350 * I think this works as follows:
352 * subcarrier freq = pixel_clock * (dda1_inc + dda2_inc / dda2_size) / 4096
354 * Presumably, when dda3 is added in, it gets to adjust the dda2_inc value
356 * So,
357 * dda1_ideal = subcarrier/pixel * 4096
358 * dda1_inc = floor (dda1_ideal)
359 * dda2 = dda1_ideal - dda1_inc
361 * then pick a ratio for dda2 that gives the closest approximation. If
362 * you can't get close enough, you can play with dda3 as well. This
363 * seems likely to happen when dda2 is small as the jumps would be larger
365 * To invert this,
367 * pixel_clock = subcarrier * 4096 / (dda1_inc + dda2_inc / dda2_size)
369 * The constants below were all computed using a 107.520MHz clock
373 * Register programming values for TV modes.
375 * These values account for -1s required.
377 static const struct tv_mode tv_modes[] = {
379 .name = "NTSC-M",
380 .clock = 108000,
381 .refresh = 59940,
382 .oversample = TV_OVERSAMPLE_8X,
383 .component_only = 0,
384 /* 525 Lines, 60 Fields, 15.734KHz line, Sub-Carrier 3.580MHz */
386 .hsync_end = 64, .hblank_end = 124,
387 .hblank_start = 836, .htotal = 857,
389 .progressive = false, .trilevel_sync = false,
391 .vsync_start_f1 = 6, .vsync_start_f2 = 7,
392 .vsync_len = 6,
394 .veq_ena = true, .veq_start_f1 = 0,
395 .veq_start_f2 = 1, .veq_len = 18,
397 .vi_end_f1 = 20, .vi_end_f2 = 21,
398 .nbr_end = 240,
400 .burst_ena = true,
401 .hburst_start = 72, .hburst_len = 34,
402 .vburst_start_f1 = 9, .vburst_end_f1 = 240,
403 .vburst_start_f2 = 10, .vburst_end_f2 = 240,
404 .vburst_start_f3 = 9, .vburst_end_f3 = 240,
405 .vburst_start_f4 = 10, .vburst_end_f4 = 240,
407 /* desired 3.5800000 actual 3.5800000 clock 107.52 */
408 .dda1_inc = 135,
409 .dda2_inc = 20800, .dda2_size = 27456,
410 .dda3_inc = 0, .dda3_size = 0,
411 .sc_reset = TV_SC_RESET_EVERY_4,
412 .pal_burst = false,
414 .composite_levels = &ntsc_m_levels_composite,
415 .composite_color = &ntsc_m_csc_composite,
416 .svideo_levels = &ntsc_m_levels_svideo,
417 .svideo_color = &ntsc_m_csc_svideo,
419 .filter_table = filter_table,
422 .name = "NTSC-443",
423 .clock = 108000,
424 .refresh = 59940,
425 .oversample = TV_OVERSAMPLE_8X,
426 .component_only = 0,
427 /* 525 Lines, 60 Fields, 15.734KHz line, Sub-Carrier 4.43MHz */
428 .hsync_end = 64, .hblank_end = 124,
429 .hblank_start = 836, .htotal = 857,
431 .progressive = false, .trilevel_sync = false,
433 .vsync_start_f1 = 6, .vsync_start_f2 = 7,
434 .vsync_len = 6,
436 .veq_ena = true, .veq_start_f1 = 0,
437 .veq_start_f2 = 1, .veq_len = 18,
439 .vi_end_f1 = 20, .vi_end_f2 = 21,
440 .nbr_end = 240,
442 .burst_ena = true,
443 .hburst_start = 72, .hburst_len = 34,
444 .vburst_start_f1 = 9, .vburst_end_f1 = 240,
445 .vburst_start_f2 = 10, .vburst_end_f2 = 240,
446 .vburst_start_f3 = 9, .vburst_end_f3 = 240,
447 .vburst_start_f4 = 10, .vburst_end_f4 = 240,
449 /* desired 4.4336180 actual 4.4336180 clock 107.52 */
450 .dda1_inc = 168,
451 .dda2_inc = 4093, .dda2_size = 27456,
452 .dda3_inc = 310, .dda3_size = 525,
453 .sc_reset = TV_SC_RESET_NEVER,
454 .pal_burst = false,
456 .composite_levels = &ntsc_m_levels_composite,
457 .composite_color = &ntsc_m_csc_composite,
458 .svideo_levels = &ntsc_m_levels_svideo,
459 .svideo_color = &ntsc_m_csc_svideo,
461 .filter_table = filter_table,
464 .name = "NTSC-J",
465 .clock = 108000,
466 .refresh = 59940,
467 .oversample = TV_OVERSAMPLE_8X,
468 .component_only = 0,
470 /* 525 Lines, 60 Fields, 15.734KHz line, Sub-Carrier 3.580MHz */
471 .hsync_end = 64, .hblank_end = 124,
472 .hblank_start = 836, .htotal = 857,
474 .progressive = false, .trilevel_sync = false,
476 .vsync_start_f1 = 6, .vsync_start_f2 = 7,
477 .vsync_len = 6,
479 .veq_ena = true, .veq_start_f1 = 0,
480 .veq_start_f2 = 1, .veq_len = 18,
482 .vi_end_f1 = 20, .vi_end_f2 = 21,
483 .nbr_end = 240,
485 .burst_ena = true,
486 .hburst_start = 72, .hburst_len = 34,
487 .vburst_start_f1 = 9, .vburst_end_f1 = 240,
488 .vburst_start_f2 = 10, .vburst_end_f2 = 240,
489 .vburst_start_f3 = 9, .vburst_end_f3 = 240,
490 .vburst_start_f4 = 10, .vburst_end_f4 = 240,
492 /* desired 3.5800000 actual 3.5800000 clock 107.52 */
493 .dda1_inc = 135,
494 .dda2_inc = 20800, .dda2_size = 27456,
495 .dda3_inc = 0, .dda3_size = 0,
496 .sc_reset = TV_SC_RESET_EVERY_4,
497 .pal_burst = false,
499 .composite_levels = &ntsc_j_levels_composite,
500 .composite_color = &ntsc_j_csc_composite,
501 .svideo_levels = &ntsc_j_levels_svideo,
502 .svideo_color = &ntsc_j_csc_svideo,
504 .filter_table = filter_table,
507 .name = "PAL-M",
508 .clock = 108000,
509 .refresh = 59940,
510 .oversample = TV_OVERSAMPLE_8X,
511 .component_only = 0,
513 /* 525 Lines, 60 Fields, 15.734KHz line, Sub-Carrier 3.580MHz */
514 .hsync_end = 64, .hblank_end = 124,
515 .hblank_start = 836, .htotal = 857,
517 .progressive = false, .trilevel_sync = false,
519 .vsync_start_f1 = 6, .vsync_start_f2 = 7,
520 .vsync_len = 6,
522 .veq_ena = true, .veq_start_f1 = 0,
523 .veq_start_f2 = 1, .veq_len = 18,
525 .vi_end_f1 = 20, .vi_end_f2 = 21,
526 .nbr_end = 240,
528 .burst_ena = true,
529 .hburst_start = 72, .hburst_len = 34,
530 .vburst_start_f1 = 9, .vburst_end_f1 = 240,
531 .vburst_start_f2 = 10, .vburst_end_f2 = 240,
532 .vburst_start_f3 = 9, .vburst_end_f3 = 240,
533 .vburst_start_f4 = 10, .vburst_end_f4 = 240,
535 /* desired 3.5800000 actual 3.5800000 clock 107.52 */
536 .dda1_inc = 135,
537 .dda2_inc = 16704, .dda2_size = 27456,
538 .dda3_inc = 0, .dda3_size = 0,
539 .sc_reset = TV_SC_RESET_EVERY_8,
540 .pal_burst = true,
542 .composite_levels = &pal_m_levels_composite,
543 .composite_color = &pal_m_csc_composite,
544 .svideo_levels = &pal_m_levels_svideo,
545 .svideo_color = &pal_m_csc_svideo,
547 .filter_table = filter_table,
550 /* 625 Lines, 50 Fields, 15.625KHz line, Sub-Carrier 4.434MHz */
551 .name = "PAL-N",
552 .clock = 108000,
553 .refresh = 50000,
554 .oversample = TV_OVERSAMPLE_8X,
555 .component_only = 0,
557 .hsync_end = 64, .hblank_end = 128,
558 .hblank_start = 844, .htotal = 863,
560 .progressive = false, .trilevel_sync = false,
563 .vsync_start_f1 = 6, .vsync_start_f2 = 7,
564 .vsync_len = 6,
566 .veq_ena = true, .veq_start_f1 = 0,
567 .veq_start_f2 = 1, .veq_len = 18,
569 .vi_end_f1 = 24, .vi_end_f2 = 25,
570 .nbr_end = 286,
572 .burst_ena = true,
573 .hburst_start = 73, .hburst_len = 34,
574 .vburst_start_f1 = 8, .vburst_end_f1 = 285,
575 .vburst_start_f2 = 8, .vburst_end_f2 = 286,
576 .vburst_start_f3 = 9, .vburst_end_f3 = 286,
577 .vburst_start_f4 = 9, .vburst_end_f4 = 285,
580 /* desired 4.4336180 actual 4.4336180 clock 107.52 */
581 .dda1_inc = 135,
582 .dda2_inc = 23578, .dda2_size = 27648,
583 .dda3_inc = 134, .dda3_size = 625,
584 .sc_reset = TV_SC_RESET_EVERY_8,
585 .pal_burst = true,
587 .composite_levels = &pal_n_levels_composite,
588 .composite_color = &pal_n_csc_composite,
589 .svideo_levels = &pal_n_levels_svideo,
590 .svideo_color = &pal_n_csc_svideo,
592 .filter_table = filter_table,
595 /* 625 Lines, 50 Fields, 15.625KHz line, Sub-Carrier 4.434MHz */
596 .name = "PAL",
597 .clock = 108000,
598 .refresh = 50000,
599 .oversample = TV_OVERSAMPLE_8X,
600 .component_only = 0,
602 .hsync_end = 64, .hblank_end = 142,
603 .hblank_start = 844, .htotal = 863,
605 .progressive = false, .trilevel_sync = false,
607 .vsync_start_f1 = 5, .vsync_start_f2 = 6,
608 .vsync_len = 5,
610 .veq_ena = true, .veq_start_f1 = 0,
611 .veq_start_f2 = 1, .veq_len = 15,
613 .vi_end_f1 = 24, .vi_end_f2 = 25,
614 .nbr_end = 286,
616 .burst_ena = true,
617 .hburst_start = 73, .hburst_len = 32,
618 .vburst_start_f1 = 8, .vburst_end_f1 = 285,
619 .vburst_start_f2 = 8, .vburst_end_f2 = 286,
620 .vburst_start_f3 = 9, .vburst_end_f3 = 286,
621 .vburst_start_f4 = 9, .vburst_end_f4 = 285,
623 /* desired 4.4336180 actual 4.4336180 clock 107.52 */
624 .dda1_inc = 168,
625 .dda2_inc = 4122, .dda2_size = 27648,
626 .dda3_inc = 67, .dda3_size = 625,
627 .sc_reset = TV_SC_RESET_EVERY_8,
628 .pal_burst = true,
630 .composite_levels = &pal_levels_composite,
631 .composite_color = &pal_csc_composite,
632 .svideo_levels = &pal_levels_svideo,
633 .svideo_color = &pal_csc_svideo,
635 .filter_table = filter_table,
638 .name = "480p",
639 .clock = 107520,
640 .refresh = 59940,
641 .oversample = TV_OVERSAMPLE_4X,
642 .component_only = 1,
644 .hsync_end = 64, .hblank_end = 122,
645 .hblank_start = 842, .htotal = 857,
647 .progressive = true, .trilevel_sync = false,
649 .vsync_start_f1 = 12, .vsync_start_f2 = 12,
650 .vsync_len = 12,
652 .veq_ena = false,
654 .vi_end_f1 = 44, .vi_end_f2 = 44,
655 .nbr_end = 479,
657 .burst_ena = false,
659 .filter_table = filter_table,
662 .name = "576p",
663 .clock = 107520,
664 .refresh = 50000,
665 .oversample = TV_OVERSAMPLE_4X,
666 .component_only = 1,
668 .hsync_end = 64, .hblank_end = 139,
669 .hblank_start = 859, .htotal = 863,
671 .progressive = true, .trilevel_sync = false,
673 .vsync_start_f1 = 10, .vsync_start_f2 = 10,
674 .vsync_len = 10,
676 .veq_ena = false,
678 .vi_end_f1 = 48, .vi_end_f2 = 48,
679 .nbr_end = 575,
681 .burst_ena = false,
683 .filter_table = filter_table,
686 .name = "720p@60Hz",
687 .clock = 148800,
688 .refresh = 60000,
689 .oversample = TV_OVERSAMPLE_2X,
690 .component_only = 1,
692 .hsync_end = 80, .hblank_end = 300,
693 .hblank_start = 1580, .htotal = 1649,
695 .progressive = true, .trilevel_sync = true,
697 .vsync_start_f1 = 10, .vsync_start_f2 = 10,
698 .vsync_len = 10,
700 .veq_ena = false,
702 .vi_end_f1 = 29, .vi_end_f2 = 29,
703 .nbr_end = 719,
705 .burst_ena = false,
707 .filter_table = filter_table,
710 .name = "720p@50Hz",
711 .clock = 148800,
712 .refresh = 50000,
713 .oversample = TV_OVERSAMPLE_2X,
714 .component_only = 1,
716 .hsync_end = 80, .hblank_end = 300,
717 .hblank_start = 1580, .htotal = 1979,
719 .progressive = true, .trilevel_sync = true,
721 .vsync_start_f1 = 10, .vsync_start_f2 = 10,
722 .vsync_len = 10,
724 .veq_ena = false,
726 .vi_end_f1 = 29, .vi_end_f2 = 29,
727 .nbr_end = 719,
729 .burst_ena = false,
731 .filter_table = filter_table,
732 .max_srcw = 800
735 .name = "1080i@50Hz",
736 .clock = 148800,
737 .refresh = 50000,
738 .oversample = TV_OVERSAMPLE_2X,
739 .component_only = 1,
741 .hsync_end = 88, .hblank_end = 235,
742 .hblank_start = 2155, .htotal = 2639,
744 .progressive = false, .trilevel_sync = true,
746 .vsync_start_f1 = 4, .vsync_start_f2 = 5,
747 .vsync_len = 10,
749 .veq_ena = true, .veq_start_f1 = 4,
750 .veq_start_f2 = 4, .veq_len = 10,
753 .vi_end_f1 = 21, .vi_end_f2 = 22,
754 .nbr_end = 539,
756 .burst_ena = false,
758 .filter_table = filter_table,
761 .name = "1080i@60Hz",
762 .clock = 148800,
763 .refresh = 60000,
764 .oversample = TV_OVERSAMPLE_2X,
765 .component_only = 1,
767 .hsync_end = 88, .hblank_end = 235,
768 .hblank_start = 2155, .htotal = 2199,
770 .progressive = false, .trilevel_sync = true,
772 .vsync_start_f1 = 4, .vsync_start_f2 = 5,
773 .vsync_len = 10,
775 .veq_ena = true, .veq_start_f1 = 4,
776 .veq_start_f2 = 4, .veq_len = 10,
779 .vi_end_f1 = 21, .vi_end_f2 = 22,
780 .nbr_end = 539,
782 .burst_ena = false,
784 .filter_table = filter_table,
788 static struct intel_tv *enc_to_tv(struct intel_encoder *encoder)
790 return container_of(encoder, struct intel_tv, base);
793 static struct intel_tv *intel_attached_tv(struct drm_connector *connector)
795 return enc_to_tv(intel_attached_encoder(connector));
798 static bool
799 intel_tv_get_hw_state(struct intel_encoder *encoder, enum pipe *pipe)
801 struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
802 u32 tmp = I915_READ(TV_CTL);
804 *pipe = (tmp & TV_ENC_PIPE_SEL_MASK) >> TV_ENC_PIPE_SEL_SHIFT;
806 return tmp & TV_ENC_ENABLE;
809 static void
810 intel_enable_tv(struct intel_encoder *encoder,
811 const struct intel_crtc_state *pipe_config,
812 const struct drm_connector_state *conn_state)
814 struct drm_device *dev = encoder->base.dev;
815 struct drm_i915_private *dev_priv = to_i915(dev);
817 /* Prevents vblank waits from timing out in intel_tv_detect_type() */
818 intel_wait_for_vblank(dev_priv,
819 to_intel_crtc(pipe_config->base.crtc)->pipe);
821 I915_WRITE(TV_CTL, I915_READ(TV_CTL) | TV_ENC_ENABLE);
824 static void
825 intel_disable_tv(struct intel_encoder *encoder,
826 const struct intel_crtc_state *old_crtc_state,
827 const struct drm_connector_state *old_conn_state)
829 struct drm_device *dev = encoder->base.dev;
830 struct drm_i915_private *dev_priv = to_i915(dev);
832 I915_WRITE(TV_CTL, I915_READ(TV_CTL) & ~TV_ENC_ENABLE);
835 static const struct tv_mode *intel_tv_mode_find(const struct drm_connector_state *conn_state)
837 int format = conn_state->tv.mode;
839 return &tv_modes[format];
842 static enum drm_mode_status
843 intel_tv_mode_valid(struct drm_connector *connector,
844 struct drm_display_mode *mode)
846 const struct tv_mode *tv_mode = intel_tv_mode_find(connector->state);
847 int max_dotclk = to_i915(connector->dev)->max_dotclk_freq;
849 if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
850 return MODE_NO_DBLESCAN;
852 if (mode->clock > max_dotclk)
853 return MODE_CLOCK_HIGH;
855 /* Ensure TV refresh is close to desired refresh */
856 if (tv_mode && abs(tv_mode->refresh - drm_mode_vrefresh(mode) * 1000)
857 < 1000)
858 return MODE_OK;
860 return MODE_CLOCK_RANGE;
864 static void
865 intel_tv_get_config(struct intel_encoder *encoder,
866 struct intel_crtc_state *pipe_config)
868 pipe_config->output_types |= BIT(INTEL_OUTPUT_TVOUT);
870 pipe_config->base.adjusted_mode.crtc_clock = pipe_config->port_clock;
873 static bool
874 intel_tv_compute_config(struct intel_encoder *encoder,
875 struct intel_crtc_state *pipe_config,
876 struct drm_connector_state *conn_state)
878 const struct tv_mode *tv_mode = intel_tv_mode_find(conn_state);
879 struct drm_display_mode *adjusted_mode =
880 &pipe_config->base.adjusted_mode;
882 if (!tv_mode)
883 return false;
885 if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN)
886 return false;
888 adjusted_mode->crtc_clock = tv_mode->clock;
889 DRM_DEBUG_KMS("forcing bpc to 8 for TV\n");
890 pipe_config->pipe_bpp = 8*3;
892 /* TV has it's own notion of sync and other mode flags, so clear them. */
893 adjusted_mode->flags = 0;
896 * FIXME: We don't check whether the input mode is actually what we want
897 * or whether userspace is doing something stupid.
900 return true;
903 static void
904 set_tv_mode_timings(struct drm_i915_private *dev_priv,
905 const struct tv_mode *tv_mode,
906 bool burst_ena)
908 u32 hctl1, hctl2, hctl3;
909 u32 vctl1, vctl2, vctl3, vctl4, vctl5, vctl6, vctl7;
911 hctl1 = (tv_mode->hsync_end << TV_HSYNC_END_SHIFT) |
912 (tv_mode->htotal << TV_HTOTAL_SHIFT);
914 hctl2 = (tv_mode->hburst_start << 16) |
915 (tv_mode->hburst_len << TV_HBURST_LEN_SHIFT);
917 if (burst_ena)
918 hctl2 |= TV_BURST_ENA;
920 hctl3 = (tv_mode->hblank_start << TV_HBLANK_START_SHIFT) |
921 (tv_mode->hblank_end << TV_HBLANK_END_SHIFT);
923 vctl1 = (tv_mode->nbr_end << TV_NBR_END_SHIFT) |
924 (tv_mode->vi_end_f1 << TV_VI_END_F1_SHIFT) |
925 (tv_mode->vi_end_f2 << TV_VI_END_F2_SHIFT);
927 vctl2 = (tv_mode->vsync_len << TV_VSYNC_LEN_SHIFT) |
928 (tv_mode->vsync_start_f1 << TV_VSYNC_START_F1_SHIFT) |
929 (tv_mode->vsync_start_f2 << TV_VSYNC_START_F2_SHIFT);
931 vctl3 = (tv_mode->veq_len << TV_VEQ_LEN_SHIFT) |
932 (tv_mode->veq_start_f1 << TV_VEQ_START_F1_SHIFT) |
933 (tv_mode->veq_start_f2 << TV_VEQ_START_F2_SHIFT);
935 if (tv_mode->veq_ena)
936 vctl3 |= TV_EQUAL_ENA;
938 vctl4 = (tv_mode->vburst_start_f1 << TV_VBURST_START_F1_SHIFT) |
939 (tv_mode->vburst_end_f1 << TV_VBURST_END_F1_SHIFT);
941 vctl5 = (tv_mode->vburst_start_f2 << TV_VBURST_START_F2_SHIFT) |
942 (tv_mode->vburst_end_f2 << TV_VBURST_END_F2_SHIFT);
944 vctl6 = (tv_mode->vburst_start_f3 << TV_VBURST_START_F3_SHIFT) |
945 (tv_mode->vburst_end_f3 << TV_VBURST_END_F3_SHIFT);
947 vctl7 = (tv_mode->vburst_start_f4 << TV_VBURST_START_F4_SHIFT) |
948 (tv_mode->vburst_end_f4 << TV_VBURST_END_F4_SHIFT);
950 I915_WRITE(TV_H_CTL_1, hctl1);
951 I915_WRITE(TV_H_CTL_2, hctl2);
952 I915_WRITE(TV_H_CTL_3, hctl3);
953 I915_WRITE(TV_V_CTL_1, vctl1);
954 I915_WRITE(TV_V_CTL_2, vctl2);
955 I915_WRITE(TV_V_CTL_3, vctl3);
956 I915_WRITE(TV_V_CTL_4, vctl4);
957 I915_WRITE(TV_V_CTL_5, vctl5);
958 I915_WRITE(TV_V_CTL_6, vctl6);
959 I915_WRITE(TV_V_CTL_7, vctl7);
962 static void set_color_conversion(struct drm_i915_private *dev_priv,
963 const struct color_conversion *color_conversion)
965 if (!color_conversion)
966 return;
968 I915_WRITE(TV_CSC_Y, (color_conversion->ry << 16) |
969 color_conversion->gy);
970 I915_WRITE(TV_CSC_Y2, (color_conversion->by << 16) |
971 color_conversion->ay);
972 I915_WRITE(TV_CSC_U, (color_conversion->ru << 16) |
973 color_conversion->gu);
974 I915_WRITE(TV_CSC_U2, (color_conversion->bu << 16) |
975 color_conversion->au);
976 I915_WRITE(TV_CSC_V, (color_conversion->rv << 16) |
977 color_conversion->gv);
978 I915_WRITE(TV_CSC_V2, (color_conversion->bv << 16) |
979 color_conversion->av);
982 static void intel_tv_pre_enable(struct intel_encoder *encoder,
983 const struct intel_crtc_state *pipe_config,
984 const struct drm_connector_state *conn_state)
986 struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
987 struct intel_crtc *intel_crtc = to_intel_crtc(pipe_config->base.crtc);
988 struct intel_tv *intel_tv = enc_to_tv(encoder);
989 const struct tv_mode *tv_mode = intel_tv_mode_find(conn_state);
990 u32 tv_ctl;
991 u32 scctl1, scctl2, scctl3;
992 int i, j;
993 const struct video_levels *video_levels;
994 const struct color_conversion *color_conversion;
995 bool burst_ena;
996 int xpos = 0x0, ypos = 0x0;
997 unsigned int xsize, ysize;
999 if (!tv_mode)
1000 return; /* can't happen (mode_prepare prevents this) */
1002 tv_ctl = I915_READ(TV_CTL);
1003 tv_ctl &= TV_CTL_SAVE;
1005 switch (intel_tv->type) {
1006 default:
1007 case DRM_MODE_CONNECTOR_Unknown:
1008 case DRM_MODE_CONNECTOR_Composite:
1009 tv_ctl |= TV_ENC_OUTPUT_COMPOSITE;
1010 video_levels = tv_mode->composite_levels;
1011 color_conversion = tv_mode->composite_color;
1012 burst_ena = tv_mode->burst_ena;
1013 break;
1014 case DRM_MODE_CONNECTOR_Component:
1015 tv_ctl |= TV_ENC_OUTPUT_COMPONENT;
1016 video_levels = &component_levels;
1017 if (tv_mode->burst_ena)
1018 color_conversion = &sdtv_csc_yprpb;
1019 else
1020 color_conversion = &hdtv_csc_yprpb;
1021 burst_ena = false;
1022 break;
1023 case DRM_MODE_CONNECTOR_SVIDEO:
1024 tv_ctl |= TV_ENC_OUTPUT_SVIDEO;
1025 video_levels = tv_mode->svideo_levels;
1026 color_conversion = tv_mode->svideo_color;
1027 burst_ena = tv_mode->burst_ena;
1028 break;
1031 tv_ctl |= TV_ENC_PIPE_SEL(intel_crtc->pipe);
1032 tv_ctl |= tv_mode->oversample;
1034 if (tv_mode->progressive)
1035 tv_ctl |= TV_PROGRESSIVE;
1036 if (tv_mode->trilevel_sync)
1037 tv_ctl |= TV_TRILEVEL_SYNC;
1038 if (tv_mode->pal_burst)
1039 tv_ctl |= TV_PAL_BURST;
1041 scctl1 = 0;
1042 if (tv_mode->dda1_inc)
1043 scctl1 |= TV_SC_DDA1_EN;
1044 if (tv_mode->dda2_inc)
1045 scctl1 |= TV_SC_DDA2_EN;
1046 if (tv_mode->dda3_inc)
1047 scctl1 |= TV_SC_DDA3_EN;
1048 scctl1 |= tv_mode->sc_reset;
1049 if (video_levels)
1050 scctl1 |= video_levels->burst << TV_BURST_LEVEL_SHIFT;
1051 scctl1 |= tv_mode->dda1_inc << TV_SCDDA1_INC_SHIFT;
1053 scctl2 = tv_mode->dda2_size << TV_SCDDA2_SIZE_SHIFT |
1054 tv_mode->dda2_inc << TV_SCDDA2_INC_SHIFT;
1056 scctl3 = tv_mode->dda3_size << TV_SCDDA3_SIZE_SHIFT |
1057 tv_mode->dda3_inc << TV_SCDDA3_INC_SHIFT;
1059 /* Enable two fixes for the chips that need them. */
1060 if (IS_I915GM(dev_priv))
1061 tv_ctl |= TV_ENC_C0_FIX | TV_ENC_SDP_FIX;
1063 set_tv_mode_timings(dev_priv, tv_mode, burst_ena);
1065 I915_WRITE(TV_SC_CTL_1, scctl1);
1066 I915_WRITE(TV_SC_CTL_2, scctl2);
1067 I915_WRITE(TV_SC_CTL_3, scctl3);
1069 set_color_conversion(dev_priv, color_conversion);
1071 if (INTEL_GEN(dev_priv) >= 4)
1072 I915_WRITE(TV_CLR_KNOBS, 0x00404000);
1073 else
1074 I915_WRITE(TV_CLR_KNOBS, 0x00606000);
1076 if (video_levels)
1077 I915_WRITE(TV_CLR_LEVEL,
1078 ((video_levels->black << TV_BLACK_LEVEL_SHIFT) |
1079 (video_levels->blank << TV_BLANK_LEVEL_SHIFT)));
1081 assert_pipe_disabled(dev_priv, intel_crtc->pipe);
1083 /* Filter ctl must be set before TV_WIN_SIZE */
1084 I915_WRITE(TV_FILTER_CTL_1, TV_AUTO_SCALE);
1085 xsize = tv_mode->hblank_start - tv_mode->hblank_end;
1086 if (tv_mode->progressive)
1087 ysize = tv_mode->nbr_end + 1;
1088 else
1089 ysize = 2*tv_mode->nbr_end + 1;
1091 xpos += conn_state->tv.margins.left;
1092 ypos += conn_state->tv.margins.top;
1093 xsize -= (conn_state->tv.margins.left +
1094 conn_state->tv.margins.right);
1095 ysize -= (conn_state->tv.margins.top +
1096 conn_state->tv.margins.bottom);
1097 I915_WRITE(TV_WIN_POS, (xpos<<16)|ypos);
1098 I915_WRITE(TV_WIN_SIZE, (xsize<<16)|ysize);
1100 j = 0;
1101 for (i = 0; i < 60; i++)
1102 I915_WRITE(TV_H_LUMA(i), tv_mode->filter_table[j++]);
1103 for (i = 0; i < 60; i++)
1104 I915_WRITE(TV_H_CHROMA(i), tv_mode->filter_table[j++]);
1105 for (i = 0; i < 43; i++)
1106 I915_WRITE(TV_V_LUMA(i), tv_mode->filter_table[j++]);
1107 for (i = 0; i < 43; i++)
1108 I915_WRITE(TV_V_CHROMA(i), tv_mode->filter_table[j++]);
1109 I915_WRITE(TV_DAC, I915_READ(TV_DAC) & TV_DAC_SAVE);
1110 I915_WRITE(TV_CTL, tv_ctl);
1113 static const struct drm_display_mode reported_modes[] = {
1115 .name = "NTSC 480i",
1116 .clock = 107520,
1117 .hdisplay = 1280,
1118 .hsync_start = 1368,
1119 .hsync_end = 1496,
1120 .htotal = 1712,
1122 .vdisplay = 1024,
1123 .vsync_start = 1027,
1124 .vsync_end = 1034,
1125 .vtotal = 1104,
1126 .type = DRM_MODE_TYPE_DRIVER,
1130 static int
1131 intel_tv_detect_type(struct intel_tv *intel_tv,
1132 struct drm_connector *connector)
1134 struct drm_crtc *crtc = connector->state->crtc;
1135 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
1136 struct drm_device *dev = connector->dev;
1137 struct drm_i915_private *dev_priv = to_i915(dev);
1138 u32 tv_ctl, save_tv_ctl;
1139 u32 tv_dac, save_tv_dac;
1140 int type;
1142 /* Disable TV interrupts around load detect or we'll recurse */
1143 if (connector->polled & DRM_CONNECTOR_POLL_HPD) {
1144 spin_lock_irq(&dev_priv->irq_lock);
1145 i915_disable_pipestat(dev_priv, 0,
1146 PIPE_HOTPLUG_INTERRUPT_STATUS |
1147 PIPE_HOTPLUG_TV_INTERRUPT_STATUS);
1148 spin_unlock_irq(&dev_priv->irq_lock);
1151 save_tv_dac = tv_dac = I915_READ(TV_DAC);
1152 save_tv_ctl = tv_ctl = I915_READ(TV_CTL);
1154 /* Poll for TV detection */
1155 tv_ctl &= ~(TV_ENC_ENABLE | TV_ENC_PIPE_SEL_MASK | TV_TEST_MODE_MASK);
1156 tv_ctl |= TV_TEST_MODE_MONITOR_DETECT;
1157 tv_ctl |= TV_ENC_PIPE_SEL(intel_crtc->pipe);
1159 tv_dac &= ~(TVDAC_SENSE_MASK | DAC_A_MASK | DAC_B_MASK | DAC_C_MASK);
1160 tv_dac |= (TVDAC_STATE_CHG_EN |
1161 TVDAC_A_SENSE_CTL |
1162 TVDAC_B_SENSE_CTL |
1163 TVDAC_C_SENSE_CTL |
1164 DAC_CTL_OVERRIDE |
1165 DAC_A_0_7_V |
1166 DAC_B_0_7_V |
1167 DAC_C_0_7_V);
1171 * The TV sense state should be cleared to zero on cantiga platform. Otherwise
1172 * the TV is misdetected. This is hardware requirement.
1174 if (IS_GM45(dev_priv))
1175 tv_dac &= ~(TVDAC_STATE_CHG_EN | TVDAC_A_SENSE_CTL |
1176 TVDAC_B_SENSE_CTL | TVDAC_C_SENSE_CTL);
1178 I915_WRITE(TV_CTL, tv_ctl);
1179 I915_WRITE(TV_DAC, tv_dac);
1180 POSTING_READ(TV_DAC);
1182 intel_wait_for_vblank(dev_priv, intel_crtc->pipe);
1184 type = -1;
1185 tv_dac = I915_READ(TV_DAC);
1186 DRM_DEBUG_KMS("TV detected: %x, %x\n", tv_ctl, tv_dac);
1188 * A B C
1189 * 0 1 1 Composite
1190 * 1 0 X svideo
1191 * 0 0 0 Component
1193 if ((tv_dac & TVDAC_SENSE_MASK) == (TVDAC_B_SENSE | TVDAC_C_SENSE)) {
1194 DRM_DEBUG_KMS("Detected Composite TV connection\n");
1195 type = DRM_MODE_CONNECTOR_Composite;
1196 } else if ((tv_dac & (TVDAC_A_SENSE|TVDAC_B_SENSE)) == TVDAC_A_SENSE) {
1197 DRM_DEBUG_KMS("Detected S-Video TV connection\n");
1198 type = DRM_MODE_CONNECTOR_SVIDEO;
1199 } else if ((tv_dac & TVDAC_SENSE_MASK) == 0) {
1200 DRM_DEBUG_KMS("Detected Component TV connection\n");
1201 type = DRM_MODE_CONNECTOR_Component;
1202 } else {
1203 DRM_DEBUG_KMS("Unrecognised TV connection\n");
1204 type = -1;
1207 I915_WRITE(TV_DAC, save_tv_dac & ~TVDAC_STATE_CHG_EN);
1208 I915_WRITE(TV_CTL, save_tv_ctl);
1209 POSTING_READ(TV_CTL);
1211 /* For unknown reasons the hw barfs if we don't do this vblank wait. */
1212 intel_wait_for_vblank(dev_priv, intel_crtc->pipe);
1214 /* Restore interrupt config */
1215 if (connector->polled & DRM_CONNECTOR_POLL_HPD) {
1216 spin_lock_irq(&dev_priv->irq_lock);
1217 i915_enable_pipestat(dev_priv, 0,
1218 PIPE_HOTPLUG_INTERRUPT_STATUS |
1219 PIPE_HOTPLUG_TV_INTERRUPT_STATUS);
1220 spin_unlock_irq(&dev_priv->irq_lock);
1223 return type;
1227 * Here we set accurate tv format according to connector type
1228 * i.e Component TV should not be assigned by NTSC or PAL
1230 static void intel_tv_find_better_format(struct drm_connector *connector)
1232 struct intel_tv *intel_tv = intel_attached_tv(connector);
1233 const struct tv_mode *tv_mode = intel_tv_mode_find(connector->state);
1234 int i;
1236 if ((intel_tv->type == DRM_MODE_CONNECTOR_Component) ==
1237 tv_mode->component_only)
1238 return;
1241 for (i = 0; i < ARRAY_SIZE(tv_modes); i++) {
1242 tv_mode = tv_modes + i;
1244 if ((intel_tv->type == DRM_MODE_CONNECTOR_Component) ==
1245 tv_mode->component_only)
1246 break;
1249 connector->state->tv.mode = i;
1252 static int
1253 intel_tv_detect(struct drm_connector *connector,
1254 struct drm_modeset_acquire_ctx *ctx,
1255 bool force)
1257 struct drm_display_mode mode;
1258 struct intel_tv *intel_tv = intel_attached_tv(connector);
1259 enum drm_connector_status status;
1260 int type;
1262 DRM_DEBUG_KMS("[CONNECTOR:%d:%s] force=%d\n",
1263 connector->base.id, connector->name,
1264 force);
1266 mode = reported_modes[0];
1268 if (force) {
1269 struct intel_load_detect_pipe tmp;
1270 int ret;
1272 ret = intel_get_load_detect_pipe(connector, &mode, &tmp, ctx);
1273 if (ret < 0)
1274 return ret;
1276 if (ret > 0) {
1277 type = intel_tv_detect_type(intel_tv, connector);
1278 intel_release_load_detect_pipe(connector, &tmp, ctx);
1279 status = type < 0 ?
1280 connector_status_disconnected :
1281 connector_status_connected;
1282 } else
1283 status = connector_status_unknown;
1285 if (status == connector_status_connected) {
1286 intel_tv->type = type;
1287 intel_tv_find_better_format(connector);
1290 return status;
1291 } else
1292 return connector->status;
1295 static const struct input_res {
1296 const char *name;
1297 int w, h;
1298 } input_res_table[] = {
1299 {"640x480", 640, 480},
1300 {"800x600", 800, 600},
1301 {"1024x768", 1024, 768},
1302 {"1280x1024", 1280, 1024},
1303 {"848x480", 848, 480},
1304 {"1280x720", 1280, 720},
1305 {"1920x1080", 1920, 1080},
1309 * Chose preferred mode according to line number of TV format
1311 static void
1312 intel_tv_choose_preferred_modes(const struct tv_mode *tv_mode,
1313 struct drm_display_mode *mode_ptr)
1315 if (tv_mode->nbr_end < 480 && mode_ptr->vdisplay == 480)
1316 mode_ptr->type |= DRM_MODE_TYPE_PREFERRED;
1317 else if (tv_mode->nbr_end > 480) {
1318 if (tv_mode->progressive == true && tv_mode->nbr_end < 720) {
1319 if (mode_ptr->vdisplay == 720)
1320 mode_ptr->type |= DRM_MODE_TYPE_PREFERRED;
1321 } else if (mode_ptr->vdisplay == 1080)
1322 mode_ptr->type |= DRM_MODE_TYPE_PREFERRED;
1326 static int
1327 intel_tv_get_modes(struct drm_connector *connector)
1329 struct drm_display_mode *mode_ptr;
1330 const struct tv_mode *tv_mode = intel_tv_mode_find(connector->state);
1331 int j, count = 0;
1332 u64 tmp;
1334 for (j = 0; j < ARRAY_SIZE(input_res_table);
1335 j++) {
1336 const struct input_res *input = &input_res_table[j];
1337 unsigned int hactive_s = input->w;
1338 unsigned int vactive_s = input->h;
1340 if (tv_mode->max_srcw && input->w > tv_mode->max_srcw)
1341 continue;
1343 if (input->w > 1024 && (!tv_mode->progressive
1344 && !tv_mode->component_only))
1345 continue;
1347 mode_ptr = drm_mode_create(connector->dev);
1348 if (!mode_ptr)
1349 continue;
1350 strlcpy(mode_ptr->name, input->name, DRM_DISPLAY_MODE_LEN);
1352 mode_ptr->hdisplay = hactive_s;
1353 mode_ptr->hsync_start = hactive_s + 1;
1354 mode_ptr->hsync_end = hactive_s + 64;
1355 if (mode_ptr->hsync_end <= mode_ptr->hsync_start)
1356 mode_ptr->hsync_end = mode_ptr->hsync_start + 1;
1357 mode_ptr->htotal = hactive_s + 96;
1359 mode_ptr->vdisplay = vactive_s;
1360 mode_ptr->vsync_start = vactive_s + 1;
1361 mode_ptr->vsync_end = vactive_s + 32;
1362 if (mode_ptr->vsync_end <= mode_ptr->vsync_start)
1363 mode_ptr->vsync_end = mode_ptr->vsync_start + 1;
1364 mode_ptr->vtotal = vactive_s + 33;
1366 tmp = mul_u32_u32(tv_mode->refresh, mode_ptr->vtotal);
1367 tmp *= mode_ptr->htotal;
1368 tmp = div_u64(tmp, 1000000);
1369 mode_ptr->clock = (int) tmp;
1371 mode_ptr->type = DRM_MODE_TYPE_DRIVER;
1372 intel_tv_choose_preferred_modes(tv_mode, mode_ptr);
1373 drm_mode_probed_add(connector, mode_ptr);
1374 count++;
1377 return count;
1380 static void
1381 intel_tv_destroy(struct drm_connector *connector)
1383 drm_connector_cleanup(connector);
1384 kfree(connector);
1387 static const struct drm_connector_funcs intel_tv_connector_funcs = {
1388 .late_register = intel_connector_register,
1389 .early_unregister = intel_connector_unregister,
1390 .destroy = intel_tv_destroy,
1391 .fill_modes = drm_helper_probe_single_connector_modes,
1392 .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
1393 .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
1396 static int intel_tv_atomic_check(struct drm_connector *connector,
1397 struct drm_connector_state *new_state)
1399 struct drm_crtc_state *new_crtc_state;
1400 struct drm_connector_state *old_state;
1402 if (!new_state->crtc)
1403 return 0;
1405 old_state = drm_atomic_get_old_connector_state(new_state->state, connector);
1406 new_crtc_state = drm_atomic_get_new_crtc_state(new_state->state, new_state->crtc);
1408 if (old_state->tv.mode != new_state->tv.mode ||
1409 old_state->tv.margins.left != new_state->tv.margins.left ||
1410 old_state->tv.margins.right != new_state->tv.margins.right ||
1411 old_state->tv.margins.top != new_state->tv.margins.top ||
1412 old_state->tv.margins.bottom != new_state->tv.margins.bottom) {
1413 /* Force a modeset. */
1415 new_crtc_state->connectors_changed = true;
1418 return 0;
1421 static const struct drm_connector_helper_funcs intel_tv_connector_helper_funcs = {
1422 .detect_ctx = intel_tv_detect,
1423 .mode_valid = intel_tv_mode_valid,
1424 .get_modes = intel_tv_get_modes,
1425 .atomic_check = intel_tv_atomic_check,
1428 static const struct drm_encoder_funcs intel_tv_enc_funcs = {
1429 .destroy = intel_encoder_destroy,
1432 void
1433 intel_tv_init(struct drm_i915_private *dev_priv)
1435 struct drm_device *dev = &dev_priv->drm;
1436 struct drm_connector *connector;
1437 struct intel_tv *intel_tv;
1438 struct intel_encoder *intel_encoder;
1439 struct intel_connector *intel_connector;
1440 u32 tv_dac_on, tv_dac_off, save_tv_dac;
1441 const char *tv_format_names[ARRAY_SIZE(tv_modes)];
1442 int i, initial_mode = 0;
1443 struct drm_connector_state *state;
1445 if ((I915_READ(TV_CTL) & TV_FUSE_STATE_MASK) == TV_FUSE_STATE_DISABLED)
1446 return;
1448 if (!intel_bios_is_tv_present(dev_priv)) {
1449 DRM_DEBUG_KMS("Integrated TV is not present.\n");
1450 return;
1454 * Sanity check the TV output by checking to see if the
1455 * DAC register holds a value
1457 save_tv_dac = I915_READ(TV_DAC);
1459 I915_WRITE(TV_DAC, save_tv_dac | TVDAC_STATE_CHG_EN);
1460 tv_dac_on = I915_READ(TV_DAC);
1462 I915_WRITE(TV_DAC, save_tv_dac & ~TVDAC_STATE_CHG_EN);
1463 tv_dac_off = I915_READ(TV_DAC);
1465 I915_WRITE(TV_DAC, save_tv_dac);
1468 * If the register does not hold the state change enable
1469 * bit, (either as a 0 or a 1), assume it doesn't really
1470 * exist
1472 if ((tv_dac_on & TVDAC_STATE_CHG_EN) == 0 ||
1473 (tv_dac_off & TVDAC_STATE_CHG_EN) != 0)
1474 return;
1476 intel_tv = kzalloc(sizeof(*intel_tv), GFP_KERNEL);
1477 if (!intel_tv) {
1478 return;
1481 intel_connector = intel_connector_alloc();
1482 if (!intel_connector) {
1483 kfree(intel_tv);
1484 return;
1487 intel_encoder = &intel_tv->base;
1488 connector = &intel_connector->base;
1489 state = connector->state;
1492 * The documentation, for the older chipsets at least, recommend
1493 * using a polling method rather than hotplug detection for TVs.
1494 * This is because in order to perform the hotplug detection, the PLLs
1495 * for the TV must be kept alive increasing power drain and starving
1496 * bandwidth from other encoders. Notably for instance, it causes
1497 * pipe underruns on Crestline when this encoder is supposedly idle.
1499 * More recent chipsets favour HDMI rather than integrated S-Video.
1501 intel_connector->polled = DRM_CONNECTOR_POLL_CONNECT;
1503 drm_connector_init(dev, connector, &intel_tv_connector_funcs,
1504 DRM_MODE_CONNECTOR_SVIDEO);
1506 drm_encoder_init(dev, &intel_encoder->base, &intel_tv_enc_funcs,
1507 DRM_MODE_ENCODER_TVDAC, "TV");
1509 intel_encoder->compute_config = intel_tv_compute_config;
1510 intel_encoder->get_config = intel_tv_get_config;
1511 intel_encoder->pre_enable = intel_tv_pre_enable;
1512 intel_encoder->enable = intel_enable_tv;
1513 intel_encoder->disable = intel_disable_tv;
1514 intel_encoder->get_hw_state = intel_tv_get_hw_state;
1515 intel_connector->get_hw_state = intel_connector_get_hw_state;
1517 intel_connector_attach_encoder(intel_connector, intel_encoder);
1519 intel_encoder->type = INTEL_OUTPUT_TVOUT;
1520 intel_encoder->power_domain = POWER_DOMAIN_PORT_OTHER;
1521 intel_encoder->port = PORT_NONE;
1522 intel_encoder->crtc_mask = (1 << 0) | (1 << 1);
1523 intel_encoder->cloneable = 0;
1524 intel_encoder->base.possible_crtcs = ((1 << 0) | (1 << 1));
1525 intel_tv->type = DRM_MODE_CONNECTOR_Unknown;
1527 /* BIOS margin values */
1528 state->tv.margins.left = 54;
1529 state->tv.margins.top = 36;
1530 state->tv.margins.right = 46;
1531 state->tv.margins.bottom = 37;
1533 state->tv.mode = initial_mode;
1535 drm_connector_helper_add(connector, &intel_tv_connector_helper_funcs);
1536 connector->interlace_allowed = false;
1537 connector->doublescan_allowed = false;
1539 /* Create TV properties then attach current values */
1540 for (i = 0; i < ARRAY_SIZE(tv_modes); i++)
1541 tv_format_names[i] = tv_modes[i].name;
1542 drm_mode_create_tv_properties(dev,
1543 ARRAY_SIZE(tv_modes),
1544 tv_format_names);
1546 drm_object_attach_property(&connector->base, dev->mode_config.tv_mode_property,
1547 state->tv.mode);
1548 drm_object_attach_property(&connector->base,
1549 dev->mode_config.tv_left_margin_property,
1550 state->tv.margins.left);
1551 drm_object_attach_property(&connector->base,
1552 dev->mode_config.tv_top_margin_property,
1553 state->tv.margins.top);
1554 drm_object_attach_property(&connector->base,
1555 dev->mode_config.tv_right_margin_property,
1556 state->tv.margins.right);
1557 drm_object_attach_property(&connector->base,
1558 dev->mode_config.tv_bottom_margin_property,
1559 state->tv.margins.bottom);