Merge branch 'for-airlied' of git://people.freedesktop.org/~danvet/drm-intel into...
[deliverable/linux.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 "drmP.h"
34 #include "drm.h"
35 #include "drm_crtc.h"
36 #include "drm_edid.h"
37 #include "intel_drv.h"
38 #include "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 sdtv_csc_rgb = {
330 .ry = 0x0000, .gy = 0x0f00, .by = 0x0000, .ay = 0x0166,
331 .ru = 0x0000, .gu = 0x0000, .bu = 0x0f00, .au = 0x0166,
332 .rv = 0x0f00, .gv = 0x0000, .bv = 0x0000, .av = 0x0166,
333 };
334
335 static const struct color_conversion hdtv_csc_yprpb = {
336 .ry = 0x05b3, .gy = 0x016e, .by = 0x0728, .ay = 0x0145,
337 .ru = 0x07d5, .gu = 0x038b, .bu = 0x0100, .au = 0x0200,
338 .rv = 0x0100, .gv = 0x03d1, .bv = 0x06bc, .av = 0x0200,
339 };
340
341 static const struct color_conversion hdtv_csc_rgb = {
342 .ry = 0x0000, .gy = 0x0f00, .by = 0x0000, .ay = 0x0166,
343 .ru = 0x0000, .gu = 0x0000, .bu = 0x0f00, .au = 0x0166,
344 .rv = 0x0f00, .gv = 0x0000, .bv = 0x0000, .av = 0x0166,
345 };
346
347 static const struct video_levels component_levels = {
348 .blank = 279, .black = 279, .burst = 0,
349 };
350
351
352 struct tv_mode {
353 const char *name;
354 int clock;
355 int refresh; /* in millihertz (for precision) */
356 u32 oversample;
357 int hsync_end, hblank_start, hblank_end, htotal;
358 bool progressive, trilevel_sync, component_only;
359 int vsync_start_f1, vsync_start_f2, vsync_len;
360 bool veq_ena;
361 int veq_start_f1, veq_start_f2, veq_len;
362 int vi_end_f1, vi_end_f2, nbr_end;
363 bool burst_ena;
364 int hburst_start, hburst_len;
365 int vburst_start_f1, vburst_end_f1;
366 int vburst_start_f2, vburst_end_f2;
367 int vburst_start_f3, vburst_end_f3;
368 int vburst_start_f4, vburst_end_f4;
369 /*
370 * subcarrier programming
371 */
372 int dda2_size, dda3_size, dda1_inc, dda2_inc, dda3_inc;
373 u32 sc_reset;
374 bool pal_burst;
375 /*
376 * blank/black levels
377 */
378 const struct video_levels *composite_levels, *svideo_levels;
379 const struct color_conversion *composite_color, *svideo_color;
380 const u32 *filter_table;
381 int max_srcw;
382 };
383
384
385 /*
386 * Sub carrier DDA
387 *
388 * I think this works as follows:
389 *
390 * subcarrier freq = pixel_clock * (dda1_inc + dda2_inc / dda2_size) / 4096
391 *
392 * Presumably, when dda3 is added in, it gets to adjust the dda2_inc value
393 *
394 * So,
395 * dda1_ideal = subcarrier/pixel * 4096
396 * dda1_inc = floor (dda1_ideal)
397 * dda2 = dda1_ideal - dda1_inc
398 *
399 * then pick a ratio for dda2 that gives the closest approximation. If
400 * you can't get close enough, you can play with dda3 as well. This
401 * seems likely to happen when dda2 is small as the jumps would be larger
402 *
403 * To invert this,
404 *
405 * pixel_clock = subcarrier * 4096 / (dda1_inc + dda2_inc / dda2_size)
406 *
407 * The constants below were all computed using a 107.520MHz clock
408 */
409
410 /**
411 * Register programming values for TV modes.
412 *
413 * These values account for -1s required.
414 */
415
416 static const struct tv_mode tv_modes[] = {
417 {
418 .name = "NTSC-M",
419 .clock = 108000,
420 .refresh = 59940,
421 .oversample = TV_OVERSAMPLE_8X,
422 .component_only = 0,
423 /* 525 Lines, 60 Fields, 15.734KHz line, Sub-Carrier 3.580MHz */
424
425 .hsync_end = 64, .hblank_end = 124,
426 .hblank_start = 836, .htotal = 857,
427
428 .progressive = false, .trilevel_sync = false,
429
430 .vsync_start_f1 = 6, .vsync_start_f2 = 7,
431 .vsync_len = 6,
432
433 .veq_ena = true, .veq_start_f1 = 0,
434 .veq_start_f2 = 1, .veq_len = 18,
435
436 .vi_end_f1 = 20, .vi_end_f2 = 21,
437 .nbr_end = 240,
438
439 .burst_ena = true,
440 .hburst_start = 72, .hburst_len = 34,
441 .vburst_start_f1 = 9, .vburst_end_f1 = 240,
442 .vburst_start_f2 = 10, .vburst_end_f2 = 240,
443 .vburst_start_f3 = 9, .vburst_end_f3 = 240,
444 .vburst_start_f4 = 10, .vburst_end_f4 = 240,
445
446 /* desired 3.5800000 actual 3.5800000 clock 107.52 */
447 .dda1_inc = 135,
448 .dda2_inc = 20800, .dda2_size = 27456,
449 .dda3_inc = 0, .dda3_size = 0,
450 .sc_reset = TV_SC_RESET_EVERY_4,
451 .pal_burst = false,
452
453 .composite_levels = &ntsc_m_levels_composite,
454 .composite_color = &ntsc_m_csc_composite,
455 .svideo_levels = &ntsc_m_levels_svideo,
456 .svideo_color = &ntsc_m_csc_svideo,
457
458 .filter_table = filter_table,
459 },
460 {
461 .name = "NTSC-443",
462 .clock = 108000,
463 .refresh = 59940,
464 .oversample = TV_OVERSAMPLE_8X,
465 .component_only = 0,
466 /* 525 Lines, 60 Fields, 15.734KHz line, Sub-Carrier 4.43MHz */
467 .hsync_end = 64, .hblank_end = 124,
468 .hblank_start = 836, .htotal = 857,
469
470 .progressive = false, .trilevel_sync = false,
471
472 .vsync_start_f1 = 6, .vsync_start_f2 = 7,
473 .vsync_len = 6,
474
475 .veq_ena = true, .veq_start_f1 = 0,
476 .veq_start_f2 = 1, .veq_len = 18,
477
478 .vi_end_f1 = 20, .vi_end_f2 = 21,
479 .nbr_end = 240,
480
481 .burst_ena = true,
482 .hburst_start = 72, .hburst_len = 34,
483 .vburst_start_f1 = 9, .vburst_end_f1 = 240,
484 .vburst_start_f2 = 10, .vburst_end_f2 = 240,
485 .vburst_start_f3 = 9, .vburst_end_f3 = 240,
486 .vburst_start_f4 = 10, .vburst_end_f4 = 240,
487
488 /* desired 4.4336180 actual 4.4336180 clock 107.52 */
489 .dda1_inc = 168,
490 .dda2_inc = 4093, .dda2_size = 27456,
491 .dda3_inc = 310, .dda3_size = 525,
492 .sc_reset = TV_SC_RESET_NEVER,
493 .pal_burst = false,
494
495 .composite_levels = &ntsc_m_levels_composite,
496 .composite_color = &ntsc_m_csc_composite,
497 .svideo_levels = &ntsc_m_levels_svideo,
498 .svideo_color = &ntsc_m_csc_svideo,
499
500 .filter_table = filter_table,
501 },
502 {
503 .name = "NTSC-J",
504 .clock = 108000,
505 .refresh = 59940,
506 .oversample = TV_OVERSAMPLE_8X,
507 .component_only = 0,
508
509 /* 525 Lines, 60 Fields, 15.734KHz line, Sub-Carrier 3.580MHz */
510 .hsync_end = 64, .hblank_end = 124,
511 .hblank_start = 836, .htotal = 857,
512
513 .progressive = false, .trilevel_sync = false,
514
515 .vsync_start_f1 = 6, .vsync_start_f2 = 7,
516 .vsync_len = 6,
517
518 .veq_ena = true, .veq_start_f1 = 0,
519 .veq_start_f2 = 1, .veq_len = 18,
520
521 .vi_end_f1 = 20, .vi_end_f2 = 21,
522 .nbr_end = 240,
523
524 .burst_ena = true,
525 .hburst_start = 72, .hburst_len = 34,
526 .vburst_start_f1 = 9, .vburst_end_f1 = 240,
527 .vburst_start_f2 = 10, .vburst_end_f2 = 240,
528 .vburst_start_f3 = 9, .vburst_end_f3 = 240,
529 .vburst_start_f4 = 10, .vburst_end_f4 = 240,
530
531 /* desired 3.5800000 actual 3.5800000 clock 107.52 */
532 .dda1_inc = 135,
533 .dda2_inc = 20800, .dda2_size = 27456,
534 .dda3_inc = 0, .dda3_size = 0,
535 .sc_reset = TV_SC_RESET_EVERY_4,
536 .pal_burst = false,
537
538 .composite_levels = &ntsc_j_levels_composite,
539 .composite_color = &ntsc_j_csc_composite,
540 .svideo_levels = &ntsc_j_levels_svideo,
541 .svideo_color = &ntsc_j_csc_svideo,
542
543 .filter_table = filter_table,
544 },
545 {
546 .name = "PAL-M",
547 .clock = 108000,
548 .refresh = 59940,
549 .oversample = TV_OVERSAMPLE_8X,
550 .component_only = 0,
551
552 /* 525 Lines, 60 Fields, 15.734KHz line, Sub-Carrier 3.580MHz */
553 .hsync_end = 64, .hblank_end = 124,
554 .hblank_start = 836, .htotal = 857,
555
556 .progressive = false, .trilevel_sync = false,
557
558 .vsync_start_f1 = 6, .vsync_start_f2 = 7,
559 .vsync_len = 6,
560
561 .veq_ena = true, .veq_start_f1 = 0,
562 .veq_start_f2 = 1, .veq_len = 18,
563
564 .vi_end_f1 = 20, .vi_end_f2 = 21,
565 .nbr_end = 240,
566
567 .burst_ena = true,
568 .hburst_start = 72, .hburst_len = 34,
569 .vburst_start_f1 = 9, .vburst_end_f1 = 240,
570 .vburst_start_f2 = 10, .vburst_end_f2 = 240,
571 .vburst_start_f3 = 9, .vburst_end_f3 = 240,
572 .vburst_start_f4 = 10, .vburst_end_f4 = 240,
573
574 /* desired 3.5800000 actual 3.5800000 clock 107.52 */
575 .dda1_inc = 135,
576 .dda2_inc = 16704, .dda2_size = 27456,
577 .dda3_inc = 0, .dda3_size = 0,
578 .sc_reset = TV_SC_RESET_EVERY_8,
579 .pal_burst = true,
580
581 .composite_levels = &pal_m_levels_composite,
582 .composite_color = &pal_m_csc_composite,
583 .svideo_levels = &pal_m_levels_svideo,
584 .svideo_color = &pal_m_csc_svideo,
585
586 .filter_table = filter_table,
587 },
588 {
589 /* 625 Lines, 50 Fields, 15.625KHz line, Sub-Carrier 4.434MHz */
590 .name = "PAL-N",
591 .clock = 108000,
592 .refresh = 50000,
593 .oversample = TV_OVERSAMPLE_8X,
594 .component_only = 0,
595
596 .hsync_end = 64, .hblank_end = 128,
597 .hblank_start = 844, .htotal = 863,
598
599 .progressive = false, .trilevel_sync = false,
600
601
602 .vsync_start_f1 = 6, .vsync_start_f2 = 7,
603 .vsync_len = 6,
604
605 .veq_ena = true, .veq_start_f1 = 0,
606 .veq_start_f2 = 1, .veq_len = 18,
607
608 .vi_end_f1 = 24, .vi_end_f2 = 25,
609 .nbr_end = 286,
610
611 .burst_ena = true,
612 .hburst_start = 73, .hburst_len = 34,
613 .vburst_start_f1 = 8, .vburst_end_f1 = 285,
614 .vburst_start_f2 = 8, .vburst_end_f2 = 286,
615 .vburst_start_f3 = 9, .vburst_end_f3 = 286,
616 .vburst_start_f4 = 9, .vburst_end_f4 = 285,
617
618
619 /* desired 4.4336180 actual 4.4336180 clock 107.52 */
620 .dda1_inc = 135,
621 .dda2_inc = 23578, .dda2_size = 27648,
622 .dda3_inc = 134, .dda3_size = 625,
623 .sc_reset = TV_SC_RESET_EVERY_8,
624 .pal_burst = true,
625
626 .composite_levels = &pal_n_levels_composite,
627 .composite_color = &pal_n_csc_composite,
628 .svideo_levels = &pal_n_levels_svideo,
629 .svideo_color = &pal_n_csc_svideo,
630
631 .filter_table = filter_table,
632 },
633 {
634 /* 625 Lines, 50 Fields, 15.625KHz line, Sub-Carrier 4.434MHz */
635 .name = "PAL",
636 .clock = 108000,
637 .refresh = 50000,
638 .oversample = TV_OVERSAMPLE_8X,
639 .component_only = 0,
640
641 .hsync_end = 64, .hblank_end = 142,
642 .hblank_start = 844, .htotal = 863,
643
644 .progressive = false, .trilevel_sync = false,
645
646 .vsync_start_f1 = 5, .vsync_start_f2 = 6,
647 .vsync_len = 5,
648
649 .veq_ena = true, .veq_start_f1 = 0,
650 .veq_start_f2 = 1, .veq_len = 15,
651
652 .vi_end_f1 = 24, .vi_end_f2 = 25,
653 .nbr_end = 286,
654
655 .burst_ena = true,
656 .hburst_start = 73, .hburst_len = 32,
657 .vburst_start_f1 = 8, .vburst_end_f1 = 285,
658 .vburst_start_f2 = 8, .vburst_end_f2 = 286,
659 .vburst_start_f3 = 9, .vburst_end_f3 = 286,
660 .vburst_start_f4 = 9, .vburst_end_f4 = 285,
661
662 /* desired 4.4336180 actual 4.4336180 clock 107.52 */
663 .dda1_inc = 168,
664 .dda2_inc = 4122, .dda2_size = 27648,
665 .dda3_inc = 67, .dda3_size = 625,
666 .sc_reset = TV_SC_RESET_EVERY_8,
667 .pal_burst = true,
668
669 .composite_levels = &pal_levels_composite,
670 .composite_color = &pal_csc_composite,
671 .svideo_levels = &pal_levels_svideo,
672 .svideo_color = &pal_csc_svideo,
673
674 .filter_table = filter_table,
675 },
676 {
677 .name = "480p",
678 .clock = 107520,
679 .refresh = 59940,
680 .oversample = TV_OVERSAMPLE_4X,
681 .component_only = 1,
682
683 .hsync_end = 64, .hblank_end = 122,
684 .hblank_start = 842, .htotal = 857,
685
686 .progressive = true, .trilevel_sync = false,
687
688 .vsync_start_f1 = 12, .vsync_start_f2 = 12,
689 .vsync_len = 12,
690
691 .veq_ena = false,
692
693 .vi_end_f1 = 44, .vi_end_f2 = 44,
694 .nbr_end = 479,
695
696 .burst_ena = false,
697
698 .filter_table = filter_table,
699 },
700 {
701 .name = "576p",
702 .clock = 107520,
703 .refresh = 50000,
704 .oversample = TV_OVERSAMPLE_4X,
705 .component_only = 1,
706
707 .hsync_end = 64, .hblank_end = 139,
708 .hblank_start = 859, .htotal = 863,
709
710 .progressive = true, .trilevel_sync = false,
711
712 .vsync_start_f1 = 10, .vsync_start_f2 = 10,
713 .vsync_len = 10,
714
715 .veq_ena = false,
716
717 .vi_end_f1 = 48, .vi_end_f2 = 48,
718 .nbr_end = 575,
719
720 .burst_ena = false,
721
722 .filter_table = filter_table,
723 },
724 {
725 .name = "720p@60Hz",
726 .clock = 148800,
727 .refresh = 60000,
728 .oversample = TV_OVERSAMPLE_2X,
729 .component_only = 1,
730
731 .hsync_end = 80, .hblank_end = 300,
732 .hblank_start = 1580, .htotal = 1649,
733
734 .progressive = true, .trilevel_sync = true,
735
736 .vsync_start_f1 = 10, .vsync_start_f2 = 10,
737 .vsync_len = 10,
738
739 .veq_ena = false,
740
741 .vi_end_f1 = 29, .vi_end_f2 = 29,
742 .nbr_end = 719,
743
744 .burst_ena = false,
745
746 .filter_table = filter_table,
747 },
748 {
749 .name = "720p@50Hz",
750 .clock = 148800,
751 .refresh = 50000,
752 .oversample = TV_OVERSAMPLE_2X,
753 .component_only = 1,
754
755 .hsync_end = 80, .hblank_end = 300,
756 .hblank_start = 1580, .htotal = 1979,
757
758 .progressive = true, .trilevel_sync = true,
759
760 .vsync_start_f1 = 10, .vsync_start_f2 = 10,
761 .vsync_len = 10,
762
763 .veq_ena = false,
764
765 .vi_end_f1 = 29, .vi_end_f2 = 29,
766 .nbr_end = 719,
767
768 .burst_ena = false,
769
770 .filter_table = filter_table,
771 .max_srcw = 800
772 },
773 {
774 .name = "1080i@50Hz",
775 .clock = 148800,
776 .refresh = 50000,
777 .oversample = TV_OVERSAMPLE_2X,
778 .component_only = 1,
779
780 .hsync_end = 88, .hblank_end = 235,
781 .hblank_start = 2155, .htotal = 2639,
782
783 .progressive = false, .trilevel_sync = true,
784
785 .vsync_start_f1 = 4, .vsync_start_f2 = 5,
786 .vsync_len = 10,
787
788 .veq_ena = true, .veq_start_f1 = 4,
789 .veq_start_f2 = 4, .veq_len = 10,
790
791
792 .vi_end_f1 = 21, .vi_end_f2 = 22,
793 .nbr_end = 539,
794
795 .burst_ena = false,
796
797 .filter_table = filter_table,
798 },
799 {
800 .name = "1080i@60Hz",
801 .clock = 148800,
802 .refresh = 60000,
803 .oversample = TV_OVERSAMPLE_2X,
804 .component_only = 1,
805
806 .hsync_end = 88, .hblank_end = 235,
807 .hblank_start = 2155, .htotal = 2199,
808
809 .progressive = false, .trilevel_sync = true,
810
811 .vsync_start_f1 = 4, .vsync_start_f2 = 5,
812 .vsync_len = 10,
813
814 .veq_ena = true, .veq_start_f1 = 4,
815 .veq_start_f2 = 4, .veq_len = 10,
816
817
818 .vi_end_f1 = 21, .vi_end_f2 = 22,
819 .nbr_end = 539,
820
821 .burst_ena = false,
822
823 .filter_table = filter_table,
824 },
825 };
826
827 static struct intel_tv *enc_to_intel_tv(struct drm_encoder *encoder)
828 {
829 return container_of(encoder, struct intel_tv, base.base);
830 }
831
832 static struct intel_tv *intel_attached_tv(struct drm_connector *connector)
833 {
834 return container_of(intel_attached_encoder(connector),
835 struct intel_tv,
836 base);
837 }
838
839 static bool
840 intel_tv_get_hw_state(struct intel_encoder *encoder, enum pipe *pipe)
841 {
842 struct drm_device *dev = encoder->base.dev;
843 struct drm_i915_private *dev_priv = dev->dev_private;
844 u32 tmp = I915_READ(TV_CTL);
845
846 if (!(tmp & TV_ENC_ENABLE))
847 return false;
848
849 *pipe = PORT_TO_PIPE(tmp);
850
851 return true;
852 }
853
854 static void
855 intel_enable_tv(struct intel_encoder *encoder)
856 {
857 struct drm_device *dev = encoder->base.dev;
858 struct drm_i915_private *dev_priv = dev->dev_private;
859
860 I915_WRITE(TV_CTL, I915_READ(TV_CTL) | TV_ENC_ENABLE);
861 }
862
863 static void
864 intel_disable_tv(struct intel_encoder *encoder)
865 {
866 struct drm_device *dev = encoder->base.dev;
867 struct drm_i915_private *dev_priv = dev->dev_private;
868
869 I915_WRITE(TV_CTL, I915_READ(TV_CTL) & ~TV_ENC_ENABLE);
870 }
871
872 static const struct tv_mode *
873 intel_tv_mode_lookup(const char *tv_format)
874 {
875 int i;
876
877 for (i = 0; i < ARRAY_SIZE(tv_modes); i++) {
878 const struct tv_mode *tv_mode = &tv_modes[i];
879
880 if (!strcmp(tv_format, tv_mode->name))
881 return tv_mode;
882 }
883 return NULL;
884 }
885
886 static const struct tv_mode *
887 intel_tv_mode_find(struct intel_tv *intel_tv)
888 {
889 return intel_tv_mode_lookup(intel_tv->tv_format);
890 }
891
892 static enum drm_mode_status
893 intel_tv_mode_valid(struct drm_connector *connector,
894 struct drm_display_mode *mode)
895 {
896 struct intel_tv *intel_tv = intel_attached_tv(connector);
897 const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv);
898
899 /* Ensure TV refresh is close to desired refresh */
900 if (tv_mode && abs(tv_mode->refresh - drm_mode_vrefresh(mode) * 1000)
901 < 1000)
902 return MODE_OK;
903
904 return MODE_CLOCK_RANGE;
905 }
906
907
908 static bool
909 intel_tv_mode_fixup(struct drm_encoder *encoder,
910 const struct drm_display_mode *mode,
911 struct drm_display_mode *adjusted_mode)
912 {
913 struct intel_tv *intel_tv = enc_to_intel_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 if (intel_encoder_check_is_cloned(&intel_tv->base))
920 return false;
921
922 adjusted_mode->clock = tv_mode->clock;
923 return true;
924 }
925
926 static void
927 intel_tv_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,
928 struct drm_display_mode *adjusted_mode)
929 {
930 struct drm_device *dev = encoder->dev;
931 struct drm_i915_private *dev_priv = dev->dev_private;
932 struct drm_crtc *crtc = encoder->crtc;
933 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
934 struct intel_tv *intel_tv = enc_to_intel_tv(encoder);
935 const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv);
936 u32 tv_ctl;
937 u32 hctl1, hctl2, hctl3;
938 u32 vctl1, vctl2, vctl3, vctl4, vctl5, vctl6, vctl7;
939 u32 scctl1, scctl2, scctl3;
940 int i, j;
941 const struct video_levels *video_levels;
942 const struct color_conversion *color_conversion;
943 bool burst_ena;
944 int pipe = intel_crtc->pipe;
945
946 if (!tv_mode)
947 return; /* can't happen (mode_prepare prevents this) */
948
949 tv_ctl = I915_READ(TV_CTL);
950 tv_ctl &= TV_CTL_SAVE;
951
952 switch (intel_tv->type) {
953 default:
954 case DRM_MODE_CONNECTOR_Unknown:
955 case DRM_MODE_CONNECTOR_Composite:
956 tv_ctl |= TV_ENC_OUTPUT_COMPOSITE;
957 video_levels = tv_mode->composite_levels;
958 color_conversion = tv_mode->composite_color;
959 burst_ena = tv_mode->burst_ena;
960 break;
961 case DRM_MODE_CONNECTOR_Component:
962 tv_ctl |= TV_ENC_OUTPUT_COMPONENT;
963 video_levels = &component_levels;
964 if (tv_mode->burst_ena)
965 color_conversion = &sdtv_csc_yprpb;
966 else
967 color_conversion = &hdtv_csc_yprpb;
968 burst_ena = false;
969 break;
970 case DRM_MODE_CONNECTOR_SVIDEO:
971 tv_ctl |= TV_ENC_OUTPUT_SVIDEO;
972 video_levels = tv_mode->svideo_levels;
973 color_conversion = tv_mode->svideo_color;
974 burst_ena = tv_mode->burst_ena;
975 break;
976 }
977 hctl1 = (tv_mode->hsync_end << TV_HSYNC_END_SHIFT) |
978 (tv_mode->htotal << TV_HTOTAL_SHIFT);
979
980 hctl2 = (tv_mode->hburst_start << 16) |
981 (tv_mode->hburst_len << TV_HBURST_LEN_SHIFT);
982
983 if (burst_ena)
984 hctl2 |= TV_BURST_ENA;
985
986 hctl3 = (tv_mode->hblank_start << TV_HBLANK_START_SHIFT) |
987 (tv_mode->hblank_end << TV_HBLANK_END_SHIFT);
988
989 vctl1 = (tv_mode->nbr_end << TV_NBR_END_SHIFT) |
990 (tv_mode->vi_end_f1 << TV_VI_END_F1_SHIFT) |
991 (tv_mode->vi_end_f2 << TV_VI_END_F2_SHIFT);
992
993 vctl2 = (tv_mode->vsync_len << TV_VSYNC_LEN_SHIFT) |
994 (tv_mode->vsync_start_f1 << TV_VSYNC_START_F1_SHIFT) |
995 (tv_mode->vsync_start_f2 << TV_VSYNC_START_F2_SHIFT);
996
997 vctl3 = (tv_mode->veq_len << TV_VEQ_LEN_SHIFT) |
998 (tv_mode->veq_start_f1 << TV_VEQ_START_F1_SHIFT) |
999 (tv_mode->veq_start_f2 << TV_VEQ_START_F2_SHIFT);
1000
1001 if (tv_mode->veq_ena)
1002 vctl3 |= TV_EQUAL_ENA;
1003
1004 vctl4 = (tv_mode->vburst_start_f1 << TV_VBURST_START_F1_SHIFT) |
1005 (tv_mode->vburst_end_f1 << TV_VBURST_END_F1_SHIFT);
1006
1007 vctl5 = (tv_mode->vburst_start_f2 << TV_VBURST_START_F2_SHIFT) |
1008 (tv_mode->vburst_end_f2 << TV_VBURST_END_F2_SHIFT);
1009
1010 vctl6 = (tv_mode->vburst_start_f3 << TV_VBURST_START_F3_SHIFT) |
1011 (tv_mode->vburst_end_f3 << TV_VBURST_END_F3_SHIFT);
1012
1013 vctl7 = (tv_mode->vburst_start_f4 << TV_VBURST_START_F4_SHIFT) |
1014 (tv_mode->vburst_end_f4 << TV_VBURST_END_F4_SHIFT);
1015
1016 if (intel_crtc->pipe == 1)
1017 tv_ctl |= TV_ENC_PIPEB_SELECT;
1018 tv_ctl |= tv_mode->oversample;
1019
1020 if (tv_mode->progressive)
1021 tv_ctl |= TV_PROGRESSIVE;
1022 if (tv_mode->trilevel_sync)
1023 tv_ctl |= TV_TRILEVEL_SYNC;
1024 if (tv_mode->pal_burst)
1025 tv_ctl |= TV_PAL_BURST;
1026
1027 scctl1 = 0;
1028 if (tv_mode->dda1_inc)
1029 scctl1 |= TV_SC_DDA1_EN;
1030 if (tv_mode->dda2_inc)
1031 scctl1 |= TV_SC_DDA2_EN;
1032 if (tv_mode->dda3_inc)
1033 scctl1 |= TV_SC_DDA3_EN;
1034 scctl1 |= tv_mode->sc_reset;
1035 if (video_levels)
1036 scctl1 |= video_levels->burst << TV_BURST_LEVEL_SHIFT;
1037 scctl1 |= tv_mode->dda1_inc << TV_SCDDA1_INC_SHIFT;
1038
1039 scctl2 = tv_mode->dda2_size << TV_SCDDA2_SIZE_SHIFT |
1040 tv_mode->dda2_inc << TV_SCDDA2_INC_SHIFT;
1041
1042 scctl3 = tv_mode->dda3_size << TV_SCDDA3_SIZE_SHIFT |
1043 tv_mode->dda3_inc << TV_SCDDA3_INC_SHIFT;
1044
1045 /* Enable two fixes for the chips that need them. */
1046 if (dev->pci_device < 0x2772)
1047 tv_ctl |= TV_ENC_C0_FIX | TV_ENC_SDP_FIX;
1048
1049 I915_WRITE(TV_H_CTL_1, hctl1);
1050 I915_WRITE(TV_H_CTL_2, hctl2);
1051 I915_WRITE(TV_H_CTL_3, hctl3);
1052 I915_WRITE(TV_V_CTL_1, vctl1);
1053 I915_WRITE(TV_V_CTL_2, vctl2);
1054 I915_WRITE(TV_V_CTL_3, vctl3);
1055 I915_WRITE(TV_V_CTL_4, vctl4);
1056 I915_WRITE(TV_V_CTL_5, vctl5);
1057 I915_WRITE(TV_V_CTL_6, vctl6);
1058 I915_WRITE(TV_V_CTL_7, vctl7);
1059 I915_WRITE(TV_SC_CTL_1, scctl1);
1060 I915_WRITE(TV_SC_CTL_2, scctl2);
1061 I915_WRITE(TV_SC_CTL_3, scctl3);
1062
1063 if (color_conversion) {
1064 I915_WRITE(TV_CSC_Y, (color_conversion->ry << 16) |
1065 color_conversion->gy);
1066 I915_WRITE(TV_CSC_Y2, (color_conversion->by << 16) |
1067 color_conversion->ay);
1068 I915_WRITE(TV_CSC_U, (color_conversion->ru << 16) |
1069 color_conversion->gu);
1070 I915_WRITE(TV_CSC_U2, (color_conversion->bu << 16) |
1071 color_conversion->au);
1072 I915_WRITE(TV_CSC_V, (color_conversion->rv << 16) |
1073 color_conversion->gv);
1074 I915_WRITE(TV_CSC_V2, (color_conversion->bv << 16) |
1075 color_conversion->av);
1076 }
1077
1078 if (INTEL_INFO(dev)->gen >= 4)
1079 I915_WRITE(TV_CLR_KNOBS, 0x00404000);
1080 else
1081 I915_WRITE(TV_CLR_KNOBS, 0x00606000);
1082
1083 if (video_levels)
1084 I915_WRITE(TV_CLR_LEVEL,
1085 ((video_levels->black << TV_BLACK_LEVEL_SHIFT) |
1086 (video_levels->blank << TV_BLANK_LEVEL_SHIFT)));
1087 {
1088 int pipeconf_reg = PIPECONF(pipe);
1089 int dspcntr_reg = DSPCNTR(intel_crtc->plane);
1090 int pipeconf = I915_READ(pipeconf_reg);
1091 int dspcntr = I915_READ(dspcntr_reg);
1092 int dspbase_reg = DSPADDR(intel_crtc->plane);
1093 int xpos = 0x0, ypos = 0x0;
1094 unsigned int xsize, ysize;
1095 /* Pipe must be off here */
1096 I915_WRITE(dspcntr_reg, dspcntr & ~DISPLAY_PLANE_ENABLE);
1097 /* Flush the plane changes */
1098 I915_WRITE(dspbase_reg, I915_READ(dspbase_reg));
1099
1100 /* Wait for vblank for the disable to take effect */
1101 if (IS_GEN2(dev))
1102 intel_wait_for_vblank(dev, intel_crtc->pipe);
1103
1104 I915_WRITE(pipeconf_reg, pipeconf & ~PIPECONF_ENABLE);
1105 /* Wait for vblank for the disable to take effect. */
1106 intel_wait_for_pipe_off(dev, intel_crtc->pipe);
1107
1108 /* Filter ctl must be set before TV_WIN_SIZE */
1109 I915_WRITE(TV_FILTER_CTL_1, TV_AUTO_SCALE);
1110 xsize = tv_mode->hblank_start - tv_mode->hblank_end;
1111 if (tv_mode->progressive)
1112 ysize = tv_mode->nbr_end + 1;
1113 else
1114 ysize = 2*tv_mode->nbr_end + 1;
1115
1116 xpos += intel_tv->margin[TV_MARGIN_LEFT];
1117 ypos += intel_tv->margin[TV_MARGIN_TOP];
1118 xsize -= (intel_tv->margin[TV_MARGIN_LEFT] +
1119 intel_tv->margin[TV_MARGIN_RIGHT]);
1120 ysize -= (intel_tv->margin[TV_MARGIN_TOP] +
1121 intel_tv->margin[TV_MARGIN_BOTTOM]);
1122 I915_WRITE(TV_WIN_POS, (xpos<<16)|ypos);
1123 I915_WRITE(TV_WIN_SIZE, (xsize<<16)|ysize);
1124
1125 I915_WRITE(pipeconf_reg, pipeconf);
1126 I915_WRITE(dspcntr_reg, dspcntr);
1127 /* Flush the plane changes */
1128 I915_WRITE(dspbase_reg, I915_READ(dspbase_reg));
1129 }
1130
1131 j = 0;
1132 for (i = 0; i < 60; i++)
1133 I915_WRITE(TV_H_LUMA_0 + (i<<2), tv_mode->filter_table[j++]);
1134 for (i = 0; i < 60; i++)
1135 I915_WRITE(TV_H_CHROMA_0 + (i<<2), tv_mode->filter_table[j++]);
1136 for (i = 0; i < 43; i++)
1137 I915_WRITE(TV_V_LUMA_0 + (i<<2), tv_mode->filter_table[j++]);
1138 for (i = 0; i < 43; i++)
1139 I915_WRITE(TV_V_CHROMA_0 + (i<<2), 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_encoder *encoder = &intel_tv->base.base;
1174 struct drm_crtc *crtc = encoder->crtc;
1175 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
1176 struct drm_device *dev = encoder->dev;
1177 struct drm_i915_private *dev_priv = dev->dev_private;
1178 unsigned long irqflags;
1179 u32 tv_ctl, save_tv_ctl;
1180 u32 tv_dac, save_tv_dac;
1181 int type;
1182
1183 /* Disable TV interrupts around load detect or we'll recurse */
1184 if (connector->polled & DRM_CONNECTOR_POLL_HPD) {
1185 spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
1186 i915_disable_pipestat(dev_priv, 0,
1187 PIPE_HOTPLUG_INTERRUPT_ENABLE |
1188 PIPE_HOTPLUG_TV_INTERRUPT_ENABLE);
1189 spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
1190 }
1191
1192 save_tv_dac = tv_dac = I915_READ(TV_DAC);
1193 save_tv_ctl = tv_ctl = I915_READ(TV_CTL);
1194
1195 /* Poll for TV detection */
1196 tv_ctl &= ~(TV_ENC_ENABLE | TV_TEST_MODE_MASK);
1197 tv_ctl |= TV_TEST_MODE_MONITOR_DETECT;
1198 if (intel_crtc->pipe == 1)
1199 tv_ctl |= TV_ENC_PIPEB_SELECT;
1200 else
1201 tv_ctl &= ~TV_ENC_PIPEB_SELECT;
1202
1203 tv_dac &= ~(TVDAC_SENSE_MASK | DAC_A_MASK | DAC_B_MASK | DAC_C_MASK);
1204 tv_dac |= (TVDAC_STATE_CHG_EN |
1205 TVDAC_A_SENSE_CTL |
1206 TVDAC_B_SENSE_CTL |
1207 TVDAC_C_SENSE_CTL |
1208 DAC_CTL_OVERRIDE |
1209 DAC_A_0_7_V |
1210 DAC_B_0_7_V |
1211 DAC_C_0_7_V);
1212
1213
1214 /*
1215 * The TV sense state should be cleared to zero on cantiga platform. Otherwise
1216 * the TV is misdetected. This is hardware requirement.
1217 */
1218 if (IS_GM45(dev))
1219 tv_dac &= ~(TVDAC_STATE_CHG_EN | TVDAC_A_SENSE_CTL |
1220 TVDAC_B_SENSE_CTL | TVDAC_C_SENSE_CTL);
1221
1222 I915_WRITE(TV_CTL, tv_ctl);
1223 I915_WRITE(TV_DAC, tv_dac);
1224 POSTING_READ(TV_DAC);
1225
1226 intel_wait_for_vblank(intel_tv->base.base.dev,
1227 to_intel_crtc(intel_tv->base.base.crtc)->pipe);
1228
1229 type = -1;
1230 tv_dac = I915_READ(TV_DAC);
1231 DRM_DEBUG_KMS("TV detected: %x, %x\n", tv_ctl, tv_dac);
1232 /*
1233 * A B C
1234 * 0 1 1 Composite
1235 * 1 0 X svideo
1236 * 0 0 0 Component
1237 */
1238 if ((tv_dac & TVDAC_SENSE_MASK) == (TVDAC_B_SENSE | TVDAC_C_SENSE)) {
1239 DRM_DEBUG_KMS("Detected Composite TV connection\n");
1240 type = DRM_MODE_CONNECTOR_Composite;
1241 } else if ((tv_dac & (TVDAC_A_SENSE|TVDAC_B_SENSE)) == TVDAC_A_SENSE) {
1242 DRM_DEBUG_KMS("Detected S-Video TV connection\n");
1243 type = DRM_MODE_CONNECTOR_SVIDEO;
1244 } else if ((tv_dac & TVDAC_SENSE_MASK) == 0) {
1245 DRM_DEBUG_KMS("Detected Component TV connection\n");
1246 type = DRM_MODE_CONNECTOR_Component;
1247 } else {
1248 DRM_DEBUG_KMS("Unrecognised TV connection\n");
1249 type = -1;
1250 }
1251
1252 I915_WRITE(TV_DAC, save_tv_dac & ~TVDAC_STATE_CHG_EN);
1253 I915_WRITE(TV_CTL, save_tv_ctl);
1254 POSTING_READ(TV_CTL);
1255
1256 /* For unknown reasons the hw barfs if we don't do this vblank wait. */
1257 intel_wait_for_vblank(intel_tv->base.base.dev,
1258 to_intel_crtc(intel_tv->base.base.crtc)->pipe);
1259
1260 /* Restore interrupt config */
1261 if (connector->polled & DRM_CONNECTOR_POLL_HPD) {
1262 spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
1263 i915_enable_pipestat(dev_priv, 0,
1264 PIPE_HOTPLUG_INTERRUPT_ENABLE |
1265 PIPE_HOTPLUG_TV_INTERRUPT_ENABLE);
1266 spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
1267 }
1268
1269 return type;
1270 }
1271
1272 /*
1273 * Here we set accurate tv format according to connector type
1274 * i.e Component TV should not be assigned by NTSC or PAL
1275 */
1276 static void intel_tv_find_better_format(struct drm_connector *connector)
1277 {
1278 struct intel_tv *intel_tv = intel_attached_tv(connector);
1279 const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv);
1280 int i;
1281
1282 if ((intel_tv->type == DRM_MODE_CONNECTOR_Component) ==
1283 tv_mode->component_only)
1284 return;
1285
1286
1287 for (i = 0; i < sizeof(tv_modes) / sizeof(*tv_modes); i++) {
1288 tv_mode = tv_modes + i;
1289
1290 if ((intel_tv->type == DRM_MODE_CONNECTOR_Component) ==
1291 tv_mode->component_only)
1292 break;
1293 }
1294
1295 intel_tv->tv_format = tv_mode->name;
1296 drm_connector_property_set_value(connector,
1297 connector->dev->mode_config.tv_mode_property, i);
1298 }
1299
1300 /**
1301 * Detect the TV connection.
1302 *
1303 * Currently this always returns CONNECTOR_STATUS_UNKNOWN, as we need to be sure
1304 * we have a pipe programmed in order to probe the TV.
1305 */
1306 static enum drm_connector_status
1307 intel_tv_detect(struct drm_connector *connector, bool force)
1308 {
1309 struct drm_display_mode mode;
1310 struct intel_tv *intel_tv = intel_attached_tv(connector);
1311 int type;
1312
1313 mode = reported_modes[0];
1314
1315 if (force) {
1316 struct intel_load_detect_pipe tmp;
1317
1318 if (intel_get_load_detect_pipe(connector, &mode, &tmp)) {
1319 type = intel_tv_detect_type(intel_tv, connector);
1320 intel_release_load_detect_pipe(connector, &tmp);
1321 } else
1322 return connector_status_unknown;
1323 } else
1324 return connector->status;
1325
1326 if (type < 0)
1327 return connector_status_disconnected;
1328
1329 intel_tv->type = type;
1330 intel_tv_find_better_format(connector);
1331
1332 return connector_status_connected;
1333 }
1334
1335 static const struct input_res {
1336 const char *name;
1337 int w, h;
1338 } input_res_table[] = {
1339 {"640x480", 640, 480},
1340 {"800x600", 800, 600},
1341 {"1024x768", 1024, 768},
1342 {"1280x1024", 1280, 1024},
1343 {"848x480", 848, 480},
1344 {"1280x720", 1280, 720},
1345 {"1920x1080", 1920, 1080},
1346 };
1347
1348 /*
1349 * Chose preferred mode according to line number of TV format
1350 */
1351 static void
1352 intel_tv_chose_preferred_modes(struct drm_connector *connector,
1353 struct drm_display_mode *mode_ptr)
1354 {
1355 struct intel_tv *intel_tv = intel_attached_tv(connector);
1356 const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv);
1357
1358 if (tv_mode->nbr_end < 480 && mode_ptr->vdisplay == 480)
1359 mode_ptr->type |= DRM_MODE_TYPE_PREFERRED;
1360 else if (tv_mode->nbr_end > 480) {
1361 if (tv_mode->progressive == true && tv_mode->nbr_end < 720) {
1362 if (mode_ptr->vdisplay == 720)
1363 mode_ptr->type |= DRM_MODE_TYPE_PREFERRED;
1364 } else if (mode_ptr->vdisplay == 1080)
1365 mode_ptr->type |= DRM_MODE_TYPE_PREFERRED;
1366 }
1367 }
1368
1369 /**
1370 * Stub get_modes function.
1371 *
1372 * This should probably return a set of fixed modes, unless we can figure out
1373 * how to probe modes off of TV connections.
1374 */
1375
1376 static int
1377 intel_tv_get_modes(struct drm_connector *connector)
1378 {
1379 struct drm_display_mode *mode_ptr;
1380 struct intel_tv *intel_tv = intel_attached_tv(connector);
1381 const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv);
1382 int j, count = 0;
1383 u64 tmp;
1384
1385 for (j = 0; j < ARRAY_SIZE(input_res_table);
1386 j++) {
1387 const struct input_res *input = &input_res_table[j];
1388 unsigned int hactive_s = input->w;
1389 unsigned int vactive_s = input->h;
1390
1391 if (tv_mode->max_srcw && input->w > tv_mode->max_srcw)
1392 continue;
1393
1394 if (input->w > 1024 && (!tv_mode->progressive
1395 && !tv_mode->component_only))
1396 continue;
1397
1398 mode_ptr = drm_mode_create(connector->dev);
1399 if (!mode_ptr)
1400 continue;
1401 strncpy(mode_ptr->name, input->name, DRM_DISPLAY_MODE_LEN);
1402
1403 mode_ptr->hdisplay = hactive_s;
1404 mode_ptr->hsync_start = hactive_s + 1;
1405 mode_ptr->hsync_end = hactive_s + 64;
1406 if (mode_ptr->hsync_end <= mode_ptr->hsync_start)
1407 mode_ptr->hsync_end = mode_ptr->hsync_start + 1;
1408 mode_ptr->htotal = hactive_s + 96;
1409
1410 mode_ptr->vdisplay = vactive_s;
1411 mode_ptr->vsync_start = vactive_s + 1;
1412 mode_ptr->vsync_end = vactive_s + 32;
1413 if (mode_ptr->vsync_end <= mode_ptr->vsync_start)
1414 mode_ptr->vsync_end = mode_ptr->vsync_start + 1;
1415 mode_ptr->vtotal = vactive_s + 33;
1416
1417 tmp = (u64) tv_mode->refresh * mode_ptr->vtotal;
1418 tmp *= mode_ptr->htotal;
1419 tmp = div_u64(tmp, 1000000);
1420 mode_ptr->clock = (int) tmp;
1421
1422 mode_ptr->type = DRM_MODE_TYPE_DRIVER;
1423 intel_tv_chose_preferred_modes(connector, mode_ptr);
1424 drm_mode_probed_add(connector, mode_ptr);
1425 count++;
1426 }
1427
1428 return count;
1429 }
1430
1431 static void
1432 intel_tv_destroy(struct drm_connector *connector)
1433 {
1434 drm_sysfs_connector_remove(connector);
1435 drm_connector_cleanup(connector);
1436 kfree(connector);
1437 }
1438
1439
1440 static int
1441 intel_tv_set_property(struct drm_connector *connector, struct drm_property *property,
1442 uint64_t val)
1443 {
1444 struct drm_device *dev = connector->dev;
1445 struct intel_tv *intel_tv = intel_attached_tv(connector);
1446 struct drm_crtc *crtc = intel_tv->base.base.crtc;
1447 int ret = 0;
1448 bool changed = false;
1449
1450 ret = drm_connector_property_set_value(connector, property, val);
1451 if (ret < 0)
1452 goto out;
1453
1454 if (property == dev->mode_config.tv_left_margin_property &&
1455 intel_tv->margin[TV_MARGIN_LEFT] != val) {
1456 intel_tv->margin[TV_MARGIN_LEFT] = val;
1457 changed = true;
1458 } else if (property == dev->mode_config.tv_right_margin_property &&
1459 intel_tv->margin[TV_MARGIN_RIGHT] != val) {
1460 intel_tv->margin[TV_MARGIN_RIGHT] = val;
1461 changed = true;
1462 } else if (property == dev->mode_config.tv_top_margin_property &&
1463 intel_tv->margin[TV_MARGIN_TOP] != val) {
1464 intel_tv->margin[TV_MARGIN_TOP] = val;
1465 changed = true;
1466 } else if (property == dev->mode_config.tv_bottom_margin_property &&
1467 intel_tv->margin[TV_MARGIN_BOTTOM] != val) {
1468 intel_tv->margin[TV_MARGIN_BOTTOM] = val;
1469 changed = true;
1470 } else if (property == dev->mode_config.tv_mode_property) {
1471 if (val >= ARRAY_SIZE(tv_modes)) {
1472 ret = -EINVAL;
1473 goto out;
1474 }
1475 if (!strcmp(intel_tv->tv_format, tv_modes[val].name))
1476 goto out;
1477
1478 intel_tv->tv_format = tv_modes[val].name;
1479 changed = true;
1480 } else {
1481 ret = -EINVAL;
1482 goto out;
1483 }
1484
1485 if (changed && crtc)
1486 intel_set_mode(crtc, &crtc->mode,
1487 crtc->x, crtc->y, crtc->fb);
1488 out:
1489 return ret;
1490 }
1491
1492 static const struct drm_encoder_helper_funcs intel_tv_helper_funcs = {
1493 .mode_fixup = intel_tv_mode_fixup,
1494 .mode_set = intel_tv_mode_set,
1495 .disable = intel_encoder_noop,
1496 };
1497
1498 static const struct drm_connector_funcs intel_tv_connector_funcs = {
1499 .dpms = intel_connector_dpms,
1500 .detect = intel_tv_detect,
1501 .destroy = intel_tv_destroy,
1502 .set_property = intel_tv_set_property,
1503 .fill_modes = drm_helper_probe_single_connector_modes,
1504 };
1505
1506 static const struct drm_connector_helper_funcs intel_tv_connector_helper_funcs = {
1507 .mode_valid = intel_tv_mode_valid,
1508 .get_modes = intel_tv_get_modes,
1509 .best_encoder = intel_best_encoder,
1510 };
1511
1512 static const struct drm_encoder_funcs intel_tv_enc_funcs = {
1513 .destroy = intel_encoder_destroy,
1514 };
1515
1516 /*
1517 * Enumerate the child dev array parsed from VBT to check whether
1518 * the integrated TV is present.
1519 * If it is present, return 1.
1520 * If it is not present, return false.
1521 * If no child dev is parsed from VBT, it assumes that the TV is present.
1522 */
1523 static int tv_is_present_in_vbt(struct drm_device *dev)
1524 {
1525 struct drm_i915_private *dev_priv = dev->dev_private;
1526 struct child_device_config *p_child;
1527 int i, ret;
1528
1529 if (!dev_priv->child_dev_num)
1530 return 1;
1531
1532 ret = 0;
1533 for (i = 0; i < dev_priv->child_dev_num; i++) {
1534 p_child = dev_priv->child_dev + i;
1535 /*
1536 * If the device type is not TV, continue.
1537 */
1538 if (p_child->device_type != DEVICE_TYPE_INT_TV &&
1539 p_child->device_type != DEVICE_TYPE_TV)
1540 continue;
1541 /* Only when the addin_offset is non-zero, it is regarded
1542 * as present.
1543 */
1544 if (p_child->addin_offset) {
1545 ret = 1;
1546 break;
1547 }
1548 }
1549 return ret;
1550 }
1551
1552 void
1553 intel_tv_init(struct drm_device *dev)
1554 {
1555 struct drm_i915_private *dev_priv = dev->dev_private;
1556 struct drm_connector *connector;
1557 struct intel_tv *intel_tv;
1558 struct intel_encoder *intel_encoder;
1559 struct intel_connector *intel_connector;
1560 u32 tv_dac_on, tv_dac_off, save_tv_dac;
1561 char *tv_format_names[ARRAY_SIZE(tv_modes)];
1562 int i, initial_mode = 0;
1563
1564 if ((I915_READ(TV_CTL) & TV_FUSE_STATE_MASK) == TV_FUSE_STATE_DISABLED)
1565 return;
1566
1567 if (!tv_is_present_in_vbt(dev)) {
1568 DRM_DEBUG_KMS("Integrated TV is not present.\n");
1569 return;
1570 }
1571 /* Even if we have an encoder we may not have a connector */
1572 if (!dev_priv->int_tv_support)
1573 return;
1574
1575 /*
1576 * Sanity check the TV output by checking to see if the
1577 * DAC register holds a value
1578 */
1579 save_tv_dac = I915_READ(TV_DAC);
1580
1581 I915_WRITE(TV_DAC, save_tv_dac | TVDAC_STATE_CHG_EN);
1582 tv_dac_on = I915_READ(TV_DAC);
1583
1584 I915_WRITE(TV_DAC, save_tv_dac & ~TVDAC_STATE_CHG_EN);
1585 tv_dac_off = I915_READ(TV_DAC);
1586
1587 I915_WRITE(TV_DAC, save_tv_dac);
1588
1589 /*
1590 * If the register does not hold the state change enable
1591 * bit, (either as a 0 or a 1), assume it doesn't really
1592 * exist
1593 */
1594 if ((tv_dac_on & TVDAC_STATE_CHG_EN) == 0 ||
1595 (tv_dac_off & TVDAC_STATE_CHG_EN) != 0)
1596 return;
1597
1598 intel_tv = kzalloc(sizeof(struct intel_tv), GFP_KERNEL);
1599 if (!intel_tv) {
1600 return;
1601 }
1602
1603 intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL);
1604 if (!intel_connector) {
1605 kfree(intel_tv);
1606 return;
1607 }
1608
1609 intel_encoder = &intel_tv->base;
1610 connector = &intel_connector->base;
1611
1612 /* The documentation, for the older chipsets at least, recommend
1613 * using a polling method rather than hotplug detection for TVs.
1614 * This is because in order to perform the hotplug detection, the PLLs
1615 * for the TV must be kept alive increasing power drain and starving
1616 * bandwidth from other encoders. Notably for instance, it causes
1617 * pipe underruns on Crestline when this encoder is supposedly idle.
1618 *
1619 * More recent chipsets favour HDMI rather than integrated S-Video.
1620 */
1621 connector->polled = DRM_CONNECTOR_POLL_CONNECT;
1622
1623 drm_connector_init(dev, connector, &intel_tv_connector_funcs,
1624 DRM_MODE_CONNECTOR_SVIDEO);
1625
1626 drm_encoder_init(dev, &intel_encoder->base, &intel_tv_enc_funcs,
1627 DRM_MODE_ENCODER_TVDAC);
1628
1629 intel_encoder->enable = intel_enable_tv;
1630 intel_encoder->disable = intel_disable_tv;
1631 intel_encoder->get_hw_state = intel_tv_get_hw_state;
1632 intel_connector->get_hw_state = intel_connector_get_hw_state;
1633
1634 intel_connector_attach_encoder(intel_connector, intel_encoder);
1635 intel_encoder->type = INTEL_OUTPUT_TVOUT;
1636 intel_encoder->crtc_mask = (1 << 0) | (1 << 1);
1637 intel_encoder->cloneable = false;
1638 intel_encoder->base.possible_crtcs = ((1 << 0) | (1 << 1));
1639 intel_encoder->base.possible_clones = (1 << INTEL_OUTPUT_TVOUT);
1640 intel_tv->type = DRM_MODE_CONNECTOR_Unknown;
1641
1642 /* BIOS margin values */
1643 intel_tv->margin[TV_MARGIN_LEFT] = 54;
1644 intel_tv->margin[TV_MARGIN_TOP] = 36;
1645 intel_tv->margin[TV_MARGIN_RIGHT] = 46;
1646 intel_tv->margin[TV_MARGIN_BOTTOM] = 37;
1647
1648 intel_tv->tv_format = tv_modes[initial_mode].name;
1649
1650 drm_encoder_helper_add(&intel_encoder->base, &intel_tv_helper_funcs);
1651 drm_connector_helper_add(connector, &intel_tv_connector_helper_funcs);
1652 connector->interlace_allowed = false;
1653 connector->doublescan_allowed = false;
1654
1655 /* Create TV properties then attach current values */
1656 for (i = 0; i < ARRAY_SIZE(tv_modes); i++)
1657 tv_format_names[i] = (char *)tv_modes[i].name;
1658 drm_mode_create_tv_properties(dev,
1659 ARRAY_SIZE(tv_modes),
1660 tv_format_names);
1661
1662 drm_connector_attach_property(connector, dev->mode_config.tv_mode_property,
1663 initial_mode);
1664 drm_connector_attach_property(connector,
1665 dev->mode_config.tv_left_margin_property,
1666 intel_tv->margin[TV_MARGIN_LEFT]);
1667 drm_connector_attach_property(connector,
1668 dev->mode_config.tv_top_margin_property,
1669 intel_tv->margin[TV_MARGIN_TOP]);
1670 drm_connector_attach_property(connector,
1671 dev->mode_config.tv_right_margin_property,
1672 intel_tv->margin[TV_MARGIN_RIGHT]);
1673 drm_connector_attach_property(connector,
1674 dev->mode_config.tv_bottom_margin_property,
1675 intel_tv->margin[TV_MARGIN_BOTTOM]);
1676 drm_sysfs_connector_add(connector);
1677 }
This page took 0.093081 seconds and 5 git commands to generate.