]> git.proxmox.com Git - mirror_ubuntu-zesty-kernel.git/blob - drivers/gpu/drm/i915/intel_tv.c
drm: i915: Rely on the default ->best_encoder() behavior where appropriate
[mirror_ubuntu-zesty-kernel.git] / drivers / gpu / drm / i915 / intel_tv.c
1 /*
2 * Copyright © 2006-2008 Intel Corporation
3 * Jesse Barnes <jesse.barnes@intel.com>
4 *
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:
11 *
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.
15 *
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.
23 *
24 * Authors:
25 * Eric Anholt <eric@anholt.net>
26 *
27 */
28
29 /** @file
30 * Integrated TV-out support for the 915GM and 945GM.
31 */
32
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"
40
41 enum tv_margin {
42 TV_MARGIN_LEFT, TV_MARGIN_TOP,
43 TV_MARGIN_RIGHT, TV_MARGIN_BOTTOM
44 };
45
46 /** Private structure for the integrated TV support */
47 struct intel_tv {
48 struct intel_encoder base;
49
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;
64
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;
78
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];
83
84 u32 save_TV_DAC;
85 u32 save_TV_CTL;
86 };
87
88 struct video_levels {
89 int blank, black, burst;
90 };
91
92 struct color_conversion {
93 u16 ry, gy, by, ay;
94 u16 ru, gu, bu, au;
95 u16 rv, gv, bv, av;
96 };
97
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,
151 };
152
153 /*
154 * Color conversion values have 3 separate fixed point formats:
155 *
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)
174 *
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)
182 *
183 * Simple conversion function:
184 *
185 * static u32
186 * float_to_csc_11(float f)
187 * {
188 * u32 exp;
189 * u32 mant;
190 * u32 ret;
191 *
192 * if (f < 0)
193 * f = -f;
194 *
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;
204 * }
205 * ret = (exp << 9) | mant;
206 * return ret;
207 * }
208 */
209
210 /*
211 * Behold, magic numbers! If we plant them they might grow a big
212 * s-video cable to the sky... or something.
213 *
214 * Pre-converted to appropriate hex value.
215 */
216
217 /*
218 * PAL & NTSC values for composite & s-video connections
219 */
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,
224 };
225
226 static const struct video_levels ntsc_m_levels_composite = {
227 .blank = 225, .black = 267, .burst = 113,
228 };
229
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,
234 };
235
236 static const struct video_levels ntsc_m_levels_svideo = {
237 .blank = 266, .black = 316, .burst = 133,
238 };
239
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,
244 };
245
246 static const struct video_levels ntsc_j_levels_composite = {
247 .blank = 225, .black = 225, .burst = 113,
248 };
249
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,
254 };
255
256 static const struct video_levels ntsc_j_levels_svideo = {
257 .blank = 266, .black = 266, .burst = 133,
258 };
259
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,
264 };
265
266 static const struct video_levels pal_levels_composite = {
267 .blank = 237, .black = 237, .burst = 118,
268 };
269
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,
274 };
275
276 static const struct video_levels pal_levels_svideo = {
277 .blank = 280, .black = 280, .burst = 139,
278 };
279
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,
284 };
285
286 static const struct video_levels pal_m_levels_composite = {
287 .blank = 225, .black = 267, .burst = 113,
288 };
289
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,
294 };
295
296 static const struct video_levels pal_m_levels_svideo = {
297 .blank = 266, .black = 316, .burst = 133,
298 };
299
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,
304 };
305
306 static const struct video_levels pal_n_levels_composite = {
307 .blank = 225, .black = 267, .burst = 118,
308 };
309
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,
314 };
315
316 static const struct video_levels pal_n_levels_svideo = {
317 .blank = 266, .black = 316, .burst = 139,
318 };
319
320 /*
321 * Component connections
322 */
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,
327 };
328
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,
333 };
334
335 static const struct video_levels component_levels = {
336 .blank = 279, .black = 279, .burst = 0,
337 };
338
339
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;
357 /*
358 * subcarrier programming
359 */
360 int dda2_size, dda3_size, dda1_inc, dda2_inc, dda3_inc;
361 u32 sc_reset;
362 bool pal_burst;
363 /*
364 * blank/black levels
365 */
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;
370 };
371
372
373 /*
374 * Sub carrier DDA
375 *
376 * I think this works as follows:
377 *
378 * subcarrier freq = pixel_clock * (dda1_inc + dda2_inc / dda2_size) / 4096
379 *
380 * Presumably, when dda3 is added in, it gets to adjust the dda2_inc value
381 *
382 * So,
383 * dda1_ideal = subcarrier/pixel * 4096
384 * dda1_inc = floor (dda1_ideal)
385 * dda2 = dda1_ideal - dda1_inc
386 *
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
390 *
391 * To invert this,
392 *
393 * pixel_clock = subcarrier * 4096 / (dda1_inc + dda2_inc / dda2_size)
394 *
395 * The constants below were all computed using a 107.520MHz clock
396 */
397
398 /**
399 * Register programming values for TV modes.
400 *
401 * These values account for -1s required.
402 */
403
404 static const struct tv_mode tv_modes[] = {
405 {
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 */
412
413 .hsync_end = 64, .hblank_end = 124,
414 .hblank_start = 836, .htotal = 857,
415
416 .progressive = false, .trilevel_sync = false,
417
418 .vsync_start_f1 = 6, .vsync_start_f2 = 7,
419 .vsync_len = 6,
420
421 .veq_ena = true, .veq_start_f1 = 0,
422 .veq_start_f2 = 1, .veq_len = 18,
423
424 .vi_end_f1 = 20, .vi_end_f2 = 21,
425 .nbr_end = 240,
426
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,
433
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,
440
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,
445
446 .filter_table = filter_table,
447 },
448 {
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,
457
458 .progressive = false, .trilevel_sync = false,
459
460 .vsync_start_f1 = 6, .vsync_start_f2 = 7,
461 .vsync_len = 6,
462
463 .veq_ena = true, .veq_start_f1 = 0,
464 .veq_start_f2 = 1, .veq_len = 18,
465
466 .vi_end_f1 = 20, .vi_end_f2 = 21,
467 .nbr_end = 240,
468
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,
475
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,
482
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,
487
488 .filter_table = filter_table,
489 },
490 {
491 .name = "NTSC-J",
492 .clock = 108000,
493 .refresh = 59940,
494 .oversample = TV_OVERSAMPLE_8X,
495 .component_only = 0,
496
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,
500
501 .progressive = false, .trilevel_sync = false,
502
503 .vsync_start_f1 = 6, .vsync_start_f2 = 7,
504 .vsync_len = 6,
505
506 .veq_ena = true, .veq_start_f1 = 0,
507 .veq_start_f2 = 1, .veq_len = 18,
508
509 .vi_end_f1 = 20, .vi_end_f2 = 21,
510 .nbr_end = 240,
511
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,
518
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,
525
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,
530
531 .filter_table = filter_table,
532 },
533 {
534 .name = "PAL-M",
535 .clock = 108000,
536 .refresh = 59940,
537 .oversample = TV_OVERSAMPLE_8X,
538 .component_only = 0,
539
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,
543
544 .progressive = false, .trilevel_sync = false,
545
546 .vsync_start_f1 = 6, .vsync_start_f2 = 7,
547 .vsync_len = 6,
548
549 .veq_ena = true, .veq_start_f1 = 0,
550 .veq_start_f2 = 1, .veq_len = 18,
551
552 .vi_end_f1 = 20, .vi_end_f2 = 21,
553 .nbr_end = 240,
554
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,
561
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,
568
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,
573
574 .filter_table = filter_table,
575 },
576 {
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,
583
584 .hsync_end = 64, .hblank_end = 128,
585 .hblank_start = 844, .htotal = 863,
586
587 .progressive = false, .trilevel_sync = false,
588
589
590 .vsync_start_f1 = 6, .vsync_start_f2 = 7,
591 .vsync_len = 6,
592
593 .veq_ena = true, .veq_start_f1 = 0,
594 .veq_start_f2 = 1, .veq_len = 18,
595
596 .vi_end_f1 = 24, .vi_end_f2 = 25,
597 .nbr_end = 286,
598
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,
605
606
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,
613
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,
618
619 .filter_table = filter_table,
620 },
621 {
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,
628
629 .hsync_end = 64, .hblank_end = 142,
630 .hblank_start = 844, .htotal = 863,
631
632 .progressive = false, .trilevel_sync = false,
633
634 .vsync_start_f1 = 5, .vsync_start_f2 = 6,
635 .vsync_len = 5,
636
637 .veq_ena = true, .veq_start_f1 = 0,
638 .veq_start_f2 = 1, .veq_len = 15,
639
640 .vi_end_f1 = 24, .vi_end_f2 = 25,
641 .nbr_end = 286,
642
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,
649
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,
656
657 .composite_levels = &pal_levels_composite,
658 .composite_color = &pal_csc_composite,
659 .svideo_levels = &pal_levels_svideo,
660 .svideo_color = &pal_csc_svideo,
661
662 .filter_table = filter_table,
663 },
664 {
665 .name = "480p",
666 .clock = 107520,
667 .refresh = 59940,
668 .oversample = TV_OVERSAMPLE_4X,
669 .component_only = 1,
670
671 .hsync_end = 64, .hblank_end = 122,
672 .hblank_start = 842, .htotal = 857,
673
674 .progressive = true, .trilevel_sync = false,
675
676 .vsync_start_f1 = 12, .vsync_start_f2 = 12,
677 .vsync_len = 12,
678
679 .veq_ena = false,
680
681 .vi_end_f1 = 44, .vi_end_f2 = 44,
682 .nbr_end = 479,
683
684 .burst_ena = false,
685
686 .filter_table = filter_table,
687 },
688 {
689 .name = "576p",
690 .clock = 107520,
691 .refresh = 50000,
692 .oversample = TV_OVERSAMPLE_4X,
693 .component_only = 1,
694
695 .hsync_end = 64, .hblank_end = 139,
696 .hblank_start = 859, .htotal = 863,
697
698 .progressive = true, .trilevel_sync = false,
699
700 .vsync_start_f1 = 10, .vsync_start_f2 = 10,
701 .vsync_len = 10,
702
703 .veq_ena = false,
704
705 .vi_end_f1 = 48, .vi_end_f2 = 48,
706 .nbr_end = 575,
707
708 .burst_ena = false,
709
710 .filter_table = filter_table,
711 },
712 {
713 .name = "720p@60Hz",
714 .clock = 148800,
715 .refresh = 60000,
716 .oversample = TV_OVERSAMPLE_2X,
717 .component_only = 1,
718
719 .hsync_end = 80, .hblank_end = 300,
720 .hblank_start = 1580, .htotal = 1649,
721
722 .progressive = true, .trilevel_sync = true,
723
724 .vsync_start_f1 = 10, .vsync_start_f2 = 10,
725 .vsync_len = 10,
726
727 .veq_ena = false,
728
729 .vi_end_f1 = 29, .vi_end_f2 = 29,
730 .nbr_end = 719,
731
732 .burst_ena = false,
733
734 .filter_table = filter_table,
735 },
736 {
737 .name = "720p@50Hz",
738 .clock = 148800,
739 .refresh = 50000,
740 .oversample = TV_OVERSAMPLE_2X,
741 .component_only = 1,
742
743 .hsync_end = 80, .hblank_end = 300,
744 .hblank_start = 1580, .htotal = 1979,
745
746 .progressive = true, .trilevel_sync = true,
747
748 .vsync_start_f1 = 10, .vsync_start_f2 = 10,
749 .vsync_len = 10,
750
751 .veq_ena = false,
752
753 .vi_end_f1 = 29, .vi_end_f2 = 29,
754 .nbr_end = 719,
755
756 .burst_ena = false,
757
758 .filter_table = filter_table,
759 .max_srcw = 800
760 },
761 {
762 .name = "1080i@50Hz",
763 .clock = 148800,
764 .refresh = 50000,
765 .oversample = TV_OVERSAMPLE_2X,
766 .component_only = 1,
767
768 .hsync_end = 88, .hblank_end = 235,
769 .hblank_start = 2155, .htotal = 2639,
770
771 .progressive = false, .trilevel_sync = true,
772
773 .vsync_start_f1 = 4, .vsync_start_f2 = 5,
774 .vsync_len = 10,
775
776 .veq_ena = true, .veq_start_f1 = 4,
777 .veq_start_f2 = 4, .veq_len = 10,
778
779
780 .vi_end_f1 = 21, .vi_end_f2 = 22,
781 .nbr_end = 539,
782
783 .burst_ena = false,
784
785 .filter_table = filter_table,
786 },
787 {
788 .name = "1080i@60Hz",
789 .clock = 148800,
790 .refresh = 60000,
791 .oversample = TV_OVERSAMPLE_2X,
792 .component_only = 1,
793
794 .hsync_end = 88, .hblank_end = 235,
795 .hblank_start = 2155, .htotal = 2199,
796
797 .progressive = false, .trilevel_sync = true,
798
799 .vsync_start_f1 = 4, .vsync_start_f2 = 5,
800 .vsync_len = 10,
801
802 .veq_ena = true, .veq_start_f1 = 4,
803 .veq_start_f2 = 4, .veq_len = 10,
804
805
806 .vi_end_f1 = 21, .vi_end_f2 = 22,
807 .nbr_end = 539,
808
809 .burst_ena = false,
810
811 .filter_table = filter_table,
812 },
813 };
814
815 static struct intel_tv *enc_to_tv(struct intel_encoder *encoder)
816 {
817 return container_of(encoder, struct intel_tv, base);
818 }
819
820 static struct intel_tv *intel_attached_tv(struct drm_connector *connector)
821 {
822 return enc_to_tv(intel_attached_encoder(connector));
823 }
824
825 static bool
826 intel_tv_get_hw_state(struct intel_encoder *encoder, enum pipe *pipe)
827 {
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);
831
832 if (!(tmp & TV_ENC_ENABLE))
833 return false;
834
835 *pipe = PORT_TO_PIPE(tmp);
836
837 return true;
838 }
839
840 static void
841 intel_enable_tv(struct intel_encoder *encoder)
842 {
843 struct drm_device *dev = encoder->base.dev;
844 struct drm_i915_private *dev_priv = dev->dev_private;
845
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);
849
850 I915_WRITE(TV_CTL, I915_READ(TV_CTL) | TV_ENC_ENABLE);
851 }
852
853 static void
854 intel_disable_tv(struct intel_encoder *encoder)
855 {
856 struct drm_device *dev = encoder->base.dev;
857 struct drm_i915_private *dev_priv = dev->dev_private;
858
859 I915_WRITE(TV_CTL, I915_READ(TV_CTL) & ~TV_ENC_ENABLE);
860 }
861
862 static const struct tv_mode *
863 intel_tv_mode_lookup(const char *tv_format)
864 {
865 int i;
866
867 for (i = 0; i < ARRAY_SIZE(tv_modes); i++) {
868 const struct tv_mode *tv_mode = &tv_modes[i];
869
870 if (!strcmp(tv_format, tv_mode->name))
871 return tv_mode;
872 }
873 return NULL;
874 }
875
876 static const struct tv_mode *
877 intel_tv_mode_find(struct intel_tv *intel_tv)
878 {
879 return intel_tv_mode_lookup(intel_tv->tv_format);
880 }
881
882 static enum drm_mode_status
883 intel_tv_mode_valid(struct drm_connector *connector,
884 struct drm_display_mode *mode)
885 {
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;
889
890 if (mode->clock > max_dotclk)
891 return MODE_CLOCK_HIGH;
892
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;
897
898 return MODE_CLOCK_RANGE;
899 }
900
901
902 static void
903 intel_tv_get_config(struct intel_encoder *encoder,
904 struct intel_crtc_state *pipe_config)
905 {
906 pipe_config->base.adjusted_mode.crtc_clock = pipe_config->port_clock;
907 }
908
909 static bool
910 intel_tv_compute_config(struct intel_encoder *encoder,
911 struct intel_crtc_state *pipe_config)
912 {
913 struct intel_tv *intel_tv = enc_to_tv(encoder);
914 const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv);
915
916 if (!tv_mode)
917 return false;
918
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;
922
923 /* TV has it's own notion of sync and other mode flags, so clear them. */
924 pipe_config->base.adjusted_mode.flags = 0;
925
926 /*
927 * FIXME: We don't check whether the input mode is actually what we want
928 * or whether userspace is doing something stupid.
929 */
930
931 return true;
932 }
933
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)
938 {
939 u32 hctl1, hctl2, hctl3;
940 u32 vctl1, vctl2, vctl3, vctl4, vctl5, vctl6, vctl7;
941
942 hctl1 = (tv_mode->hsync_end << TV_HSYNC_END_SHIFT) |
943 (tv_mode->htotal << TV_HTOTAL_SHIFT);
944
945 hctl2 = (tv_mode->hburst_start << 16) |
946 (tv_mode->hburst_len << TV_HBURST_LEN_SHIFT);
947
948 if (burst_ena)
949 hctl2 |= TV_BURST_ENA;
950
951 hctl3 = (tv_mode->hblank_start << TV_HBLANK_START_SHIFT) |
952 (tv_mode->hblank_end << TV_HBLANK_END_SHIFT);
953
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);
957
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);
961
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);
965
966 if (tv_mode->veq_ena)
967 vctl3 |= TV_EQUAL_ENA;
968
969 vctl4 = (tv_mode->vburst_start_f1 << TV_VBURST_START_F1_SHIFT) |
970 (tv_mode->vburst_end_f1 << TV_VBURST_END_F1_SHIFT);
971
972 vctl5 = (tv_mode->vburst_start_f2 << TV_VBURST_START_F2_SHIFT) |
973 (tv_mode->vburst_end_f2 << TV_VBURST_END_F2_SHIFT);
974
975 vctl6 = (tv_mode->vburst_start_f3 << TV_VBURST_START_F3_SHIFT) |
976 (tv_mode->vburst_end_f3 << TV_VBURST_END_F3_SHIFT);
977
978 vctl7 = (tv_mode->vburst_start_f4 << TV_VBURST_START_F4_SHIFT) |
979 (tv_mode->vburst_end_f4 << TV_VBURST_END_F4_SHIFT);
980
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);
991 }
992
993 static void set_color_conversion(struct drm_i915_private *dev_priv,
994 const struct color_conversion *color_conversion)
995 {
996 if (!color_conversion)
997 return;
998
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);
1011 }
1012
1013 static void intel_tv_pre_enable(struct intel_encoder *encoder)
1014 {
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;
1028
1029 if (!tv_mode)
1030 return; /* can't happen (mode_prepare prevents this) */
1031
1032 tv_ctl = I915_READ(TV_CTL);
1033 tv_ctl &= TV_CTL_SAVE;
1034
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;
1059 }
1060
1061 if (intel_crtc->pipe == 1)
1062 tv_ctl |= TV_ENC_PIPEB_SELECT;
1063 tv_ctl |= tv_mode->oversample;
1064
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;
1071
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;
1083
1084 scctl2 = tv_mode->dda2_size << TV_SCDDA2_SIZE_SHIFT |
1085 tv_mode->dda2_inc << TV_SCDDA2_INC_SHIFT;
1086
1087 scctl3 = tv_mode->dda3_size << TV_SCDDA3_SIZE_SHIFT |
1088 tv_mode->dda3_inc << TV_SCDDA3_INC_SHIFT;
1089
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;
1093
1094 set_tv_mode_timings(dev_priv, tv_mode, burst_ena);
1095
1096 I915_WRITE(TV_SC_CTL_1, scctl1);
1097 I915_WRITE(TV_SC_CTL_2, scctl2);
1098 I915_WRITE(TV_SC_CTL_3, scctl3);
1099
1100 set_color_conversion(dev_priv, color_conversion);
1101
1102 if (INTEL_INFO(dev)->gen >= 4)
1103 I915_WRITE(TV_CLR_KNOBS, 0x00404000);
1104 else
1105 I915_WRITE(TV_CLR_KNOBS, 0x00606000);
1106
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)));
1111
1112 assert_pipe_disabled(dev_priv, intel_crtc->pipe);
1113
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;
1121
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);
1130
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);
1142 }
1143
1144 static const struct drm_display_mode reported_modes[] = {
1145 {
1146 .name = "NTSC 480i",
1147 .clock = 107520,
1148 .hdisplay = 1280,
1149 .hsync_start = 1368,
1150 .hsync_end = 1496,
1151 .htotal = 1712,
1152
1153 .vdisplay = 1024,
1154 .vsync_start = 1027,
1155 .vsync_end = 1034,
1156 .vtotal = 1104,
1157 .type = DRM_MODE_TYPE_DRIVER,
1158 },
1159 };
1160
1161 /**
1162 * Detects TV presence by checking for load.
1163 *
1164 * Requires that the current pipe's DPLL is active.
1165
1166 * \return true if TV is connected.
1167 * \return false if TV is disconnected.
1168 */
1169 static int
1170 intel_tv_detect_type(struct intel_tv *intel_tv,
1171 struct drm_connector *connector)
1172 {
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;
1180
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);
1188 }
1189
1190 save_tv_dac = tv_dac = I915_READ(TV_DAC);
1191 save_tv_ctl = tv_ctl = I915_READ(TV_CTL);
1192
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;
1200
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);
1210
1211
1212 /*
1213 * The TV sense state should be cleared to zero on cantiga platform. Otherwise
1214 * the TV is misdetected. This is hardware requirement.
1215 */
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);
1219
1220 I915_WRITE(TV_CTL, tv_ctl);
1221 I915_WRITE(TV_DAC, tv_dac);
1222 POSTING_READ(TV_DAC);
1223
1224 intel_wait_for_vblank(dev, intel_crtc->pipe);
1225
1226 type = -1;
1227 tv_dac = I915_READ(TV_DAC);
1228 DRM_DEBUG_KMS("TV detected: %x, %x\n", tv_ctl, tv_dac);
1229 /*
1230 * A B C
1231 * 0 1 1 Composite
1232 * 1 0 X svideo
1233 * 0 0 0 Component
1234 */
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;
1247 }
1248
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);
1252
1253 /* For unknown reasons the hw barfs if we don't do this vblank wait. */
1254 intel_wait_for_vblank(dev, intel_crtc->pipe);
1255
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);
1263 }
1264
1265 return type;
1266 }
1267
1268 /*
1269 * Here we set accurate tv format according to connector type
1270 * i.e Component TV should not be assigned by NTSC or PAL
1271 */
1272 static void intel_tv_find_better_format(struct drm_connector *connector)
1273 {
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;
1277
1278 if ((intel_tv->type == DRM_MODE_CONNECTOR_Component) ==
1279 tv_mode->component_only)
1280 return;
1281
1282
1283 for (i = 0; i < ARRAY_SIZE(tv_modes); i++) {
1284 tv_mode = tv_modes + i;
1285
1286 if ((intel_tv->type == DRM_MODE_CONNECTOR_Component) ==
1287 tv_mode->component_only)
1288 break;
1289 }
1290
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);
1294 }
1295
1296 /**
1297 * Detect the TV connection.
1298 *
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.
1301 */
1302 static enum drm_connector_status
1303 intel_tv_detect(struct drm_connector *connector, bool force)
1304 {
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;
1309
1310 DRM_DEBUG_KMS("[CONNECTOR:%d:%s] force=%d\n",
1311 connector->base.id, connector->name,
1312 force);
1313
1314 mode = reported_modes[0];
1315
1316 if (force) {
1317 struct intel_load_detect_pipe tmp;
1318 struct drm_modeset_acquire_ctx ctx;
1319
1320 drm_modeset_acquire_init(&ctx, 0);
1321
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;
1330
1331 drm_modeset_drop_locks(&ctx);
1332 drm_modeset_acquire_fini(&ctx);
1333 } else
1334 return connector->status;
1335
1336 if (status != connector_status_connected)
1337 return status;
1338
1339 intel_tv->type = type;
1340 intel_tv_find_better_format(connector);
1341
1342 return connector_status_connected;
1343 }
1344
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},
1356 };
1357
1358 /*
1359 * Chose preferred mode according to line number of TV format
1360 */
1361 static void
1362 intel_tv_chose_preferred_modes(struct drm_connector *connector,
1363 struct drm_display_mode *mode_ptr)
1364 {
1365 struct intel_tv *intel_tv = intel_attached_tv(connector);
1366 const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv);
1367
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;
1376 }
1377 }
1378
1379 /**
1380 * Stub get_modes function.
1381 *
1382 * This should probably return a set of fixed modes, unless we can figure out
1383 * how to probe modes off of TV connections.
1384 */
1385
1386 static int
1387 intel_tv_get_modes(struct drm_connector *connector)
1388 {
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;
1394
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;
1400
1401 if (tv_mode->max_srcw && input->w > tv_mode->max_srcw)
1402 continue;
1403
1404 if (input->w > 1024 && (!tv_mode->progressive
1405 && !tv_mode->component_only))
1406 continue;
1407
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';
1413
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;
1420
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;
1427
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;
1432
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++;
1437 }
1438
1439 return count;
1440 }
1441
1442 static void
1443 intel_tv_destroy(struct drm_connector *connector)
1444 {
1445 drm_connector_cleanup(connector);
1446 kfree(connector);
1447 }
1448
1449
1450 static int
1451 intel_tv_set_property(struct drm_connector *connector, struct drm_property *property,
1452 uint64_t val)
1453 {
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;
1459
1460 ret = drm_object_property_set_value(&connector->base, property, val);
1461 if (ret < 0)
1462 goto out;
1463
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;
1484 }
1485 if (!strcmp(intel_tv->tv_format, tv_modes[val].name))
1486 goto out;
1487
1488 intel_tv->tv_format = tv_modes[val].name;
1489 changed = true;
1490 } else {
1491 ret = -EINVAL;
1492 goto out;
1493 }
1494
1495 if (changed && crtc)
1496 intel_crtc_restore_mode(crtc);
1497 out:
1498 return ret;
1499 }
1500
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,
1510 };
1511
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 };
1516
1517 static const struct drm_encoder_funcs intel_tv_enc_funcs = {
1518 .destroy = intel_encoder_destroy,
1519 };
1520
1521 void
1522 intel_tv_init(struct drm_device *dev)
1523 {
1524 struct drm_i915_private *dev_priv = dev->dev_private;
1525 struct drm_connector *connector;
1526 struct intel_tv *intel_tv;
1527 struct intel_encoder *intel_encoder;
1528 struct intel_connector *intel_connector;
1529 u32 tv_dac_on, tv_dac_off, save_tv_dac;
1530 const char *tv_format_names[ARRAY_SIZE(tv_modes)];
1531 int i, initial_mode = 0;
1532
1533 if ((I915_READ(TV_CTL) & TV_FUSE_STATE_MASK) == TV_FUSE_STATE_DISABLED)
1534 return;
1535
1536 if (!intel_bios_is_tv_present(dev_priv)) {
1537 DRM_DEBUG_KMS("Integrated TV is not present.\n");
1538 return;
1539 }
1540
1541 /*
1542 * Sanity check the TV output by checking to see if the
1543 * DAC register holds a value
1544 */
1545 save_tv_dac = I915_READ(TV_DAC);
1546
1547 I915_WRITE(TV_DAC, save_tv_dac | TVDAC_STATE_CHG_EN);
1548 tv_dac_on = I915_READ(TV_DAC);
1549
1550 I915_WRITE(TV_DAC, save_tv_dac & ~TVDAC_STATE_CHG_EN);
1551 tv_dac_off = I915_READ(TV_DAC);
1552
1553 I915_WRITE(TV_DAC, save_tv_dac);
1554
1555 /*
1556 * If the register does not hold the state change enable
1557 * bit, (either as a 0 or a 1), assume it doesn't really
1558 * exist
1559 */
1560 if ((tv_dac_on & TVDAC_STATE_CHG_EN) == 0 ||
1561 (tv_dac_off & TVDAC_STATE_CHG_EN) != 0)
1562 return;
1563
1564 intel_tv = kzalloc(sizeof(*intel_tv), GFP_KERNEL);
1565 if (!intel_tv) {
1566 return;
1567 }
1568
1569 intel_connector = intel_connector_alloc();
1570 if (!intel_connector) {
1571 kfree(intel_tv);
1572 return;
1573 }
1574
1575 intel_encoder = &intel_tv->base;
1576 connector = &intel_connector->base;
1577
1578 /* The documentation, for the older chipsets at least, recommend
1579 * using a polling method rather than hotplug detection for TVs.
1580 * This is because in order to perform the hotplug detection, the PLLs
1581 * for the TV must be kept alive increasing power drain and starving
1582 * bandwidth from other encoders. Notably for instance, it causes
1583 * pipe underruns on Crestline when this encoder is supposedly idle.
1584 *
1585 * More recent chipsets favour HDMI rather than integrated S-Video.
1586 */
1587 intel_connector->polled = DRM_CONNECTOR_POLL_CONNECT;
1588
1589 drm_connector_init(dev, connector, &intel_tv_connector_funcs,
1590 DRM_MODE_CONNECTOR_SVIDEO);
1591
1592 drm_encoder_init(dev, &intel_encoder->base, &intel_tv_enc_funcs,
1593 DRM_MODE_ENCODER_TVDAC, "TV");
1594
1595 intel_encoder->compute_config = intel_tv_compute_config;
1596 intel_encoder->get_config = intel_tv_get_config;
1597 intel_encoder->pre_enable = intel_tv_pre_enable;
1598 intel_encoder->enable = intel_enable_tv;
1599 intel_encoder->disable = intel_disable_tv;
1600 intel_encoder->get_hw_state = intel_tv_get_hw_state;
1601 intel_connector->get_hw_state = intel_connector_get_hw_state;
1602 intel_connector->unregister = intel_connector_unregister;
1603
1604 intel_connector_attach_encoder(intel_connector, intel_encoder);
1605 intel_encoder->type = INTEL_OUTPUT_TVOUT;
1606 intel_encoder->crtc_mask = (1 << 0) | (1 << 1);
1607 intel_encoder->cloneable = 0;
1608 intel_encoder->base.possible_crtcs = ((1 << 0) | (1 << 1));
1609 intel_tv->type = DRM_MODE_CONNECTOR_Unknown;
1610
1611 /* BIOS margin values */
1612 intel_tv->margin[TV_MARGIN_LEFT] = 54;
1613 intel_tv->margin[TV_MARGIN_TOP] = 36;
1614 intel_tv->margin[TV_MARGIN_RIGHT] = 46;
1615 intel_tv->margin[TV_MARGIN_BOTTOM] = 37;
1616
1617 intel_tv->tv_format = tv_modes[initial_mode].name;
1618
1619 drm_connector_helper_add(connector, &intel_tv_connector_helper_funcs);
1620 connector->interlace_allowed = false;
1621 connector->doublescan_allowed = false;
1622
1623 /* Create TV properties then attach current values */
1624 for (i = 0; i < ARRAY_SIZE(tv_modes); i++)
1625 tv_format_names[i] = tv_modes[i].name;
1626 drm_mode_create_tv_properties(dev,
1627 ARRAY_SIZE(tv_modes),
1628 tv_format_names);
1629
1630 drm_object_attach_property(&connector->base, dev->mode_config.tv_mode_property,
1631 initial_mode);
1632 drm_object_attach_property(&connector->base,
1633 dev->mode_config.tv_left_margin_property,
1634 intel_tv->margin[TV_MARGIN_LEFT]);
1635 drm_object_attach_property(&connector->base,
1636 dev->mode_config.tv_top_margin_property,
1637 intel_tv->margin[TV_MARGIN_TOP]);
1638 drm_object_attach_property(&connector->base,
1639 dev->mode_config.tv_right_margin_property,
1640 intel_tv->margin[TV_MARGIN_RIGHT]);
1641 drm_object_attach_property(&connector->base,
1642 dev->mode_config.tv_bottom_margin_property,
1643 intel_tv->margin[TV_MARGIN_BOTTOM]);
1644 drm_connector_register(connector);
1645 }