]> CyberLeo.Net >> Repos - FreeBSD/releng/10.2.git/blob - sys/dev/drm2/i915/intel_tv.c
- Copy stable/10@285827 to releng/10.2 in preparation for 10.2-RC1
[FreeBSD/releng/10.2.git] / sys / dev / drm2 / 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 <sys/cdefs.h>
34 __FBSDID("$FreeBSD$");
35
36 #include <dev/drm2/drmP.h>
37 #include <dev/drm2/drm.h>
38 #include <dev/drm2/drm_crtc.h>
39 #include <dev/drm2/drm_edid.h>
40 #include <dev/drm2/i915/i915_drm.h>
41 #include <dev/drm2/i915/i915_drv.h>
42 #include <dev/drm2/i915/intel_drv.h>
43
44 enum tv_margin {
45         TV_MARGIN_LEFT, TV_MARGIN_TOP,
46         TV_MARGIN_RIGHT, TV_MARGIN_BOTTOM
47 };
48
49 /** Private structure for the integrated TV support */
50 struct intel_tv {
51         struct intel_encoder base;
52
53         int type;
54         const char *tv_format;
55         int margin[4];
56         u32 save_TV_H_CTL_1;
57         u32 save_TV_H_CTL_2;
58         u32 save_TV_H_CTL_3;
59         u32 save_TV_V_CTL_1;
60         u32 save_TV_V_CTL_2;
61         u32 save_TV_V_CTL_3;
62         u32 save_TV_V_CTL_4;
63         u32 save_TV_V_CTL_5;
64         u32 save_TV_V_CTL_6;
65         u32 save_TV_V_CTL_7;
66         u32 save_TV_SC_CTL_1, save_TV_SC_CTL_2, save_TV_SC_CTL_3;
67
68         u32 save_TV_CSC_Y;
69         u32 save_TV_CSC_Y2;
70         u32 save_TV_CSC_U;
71         u32 save_TV_CSC_U2;
72         u32 save_TV_CSC_V;
73         u32 save_TV_CSC_V2;
74         u32 save_TV_CLR_KNOBS;
75         u32 save_TV_CLR_LEVEL;
76         u32 save_TV_WIN_POS;
77         u32 save_TV_WIN_SIZE;
78         u32 save_TV_FILTER_CTL_1;
79         u32 save_TV_FILTER_CTL_2;
80         u32 save_TV_FILTER_CTL_3;
81
82         u32 save_TV_H_LUMA[60];
83         u32 save_TV_H_CHROMA[60];
84         u32 save_TV_V_LUMA[43];
85         u32 save_TV_V_CHROMA[43];
86
87         u32 save_TV_DAC;
88         u32 save_TV_CTL;
89 };
90
91 struct video_levels {
92         int blank, black, burst;
93 };
94
95 struct color_conversion {
96         u16 ry, gy, by, ay;
97         u16 ru, gu, bu, au;
98         u16 rv, gv, bv, av;
99 };
100
101 static const u32 filter_table[] = {
102         0xB1403000, 0x2E203500, 0x35002E20, 0x3000B140,
103         0x35A0B160, 0x2DC02E80, 0xB1403480, 0xB1603000,
104         0x2EA03640, 0x34002D80, 0x3000B120, 0x36E0B160,
105         0x2D202EF0, 0xB1203380, 0xB1603000, 0x2F303780,
106         0x33002CC0, 0x3000B100, 0x3820B160, 0x2C802F50,
107         0xB10032A0, 0xB1603000, 0x2F9038C0, 0x32202C20,
108         0x3000B0E0, 0x3980B160, 0x2BC02FC0, 0xB0E031C0,
109         0xB1603000, 0x2FF03A20, 0x31602B60, 0xB020B0C0,
110         0x3AE0B160, 0x2B001810, 0xB0C03120, 0xB140B020,
111         0x18283BA0, 0x30C02A80, 0xB020B0A0, 0x3C60B140,
112         0x2A201838, 0xB0A03080, 0xB120B020, 0x18383D20,
113         0x304029C0, 0xB040B080, 0x3DE0B100, 0x29601848,
114         0xB0803000, 0xB100B040, 0x18483EC0, 0xB0402900,
115         0xB040B060, 0x3F80B0C0, 0x28801858, 0xB060B080,
116         0xB0A0B060, 0x18602820, 0xB0A02820, 0x0000B060,
117         0xB1403000, 0x2E203500, 0x35002E20, 0x3000B140,
118         0x35A0B160, 0x2DC02E80, 0xB1403480, 0xB1603000,
119         0x2EA03640, 0x34002D80, 0x3000B120, 0x36E0B160,
120         0x2D202EF0, 0xB1203380, 0xB1603000, 0x2F303780,
121         0x33002CC0, 0x3000B100, 0x3820B160, 0x2C802F50,
122         0xB10032A0, 0xB1603000, 0x2F9038C0, 0x32202C20,
123         0x3000B0E0, 0x3980B160, 0x2BC02FC0, 0xB0E031C0,
124         0xB1603000, 0x2FF03A20, 0x31602B60, 0xB020B0C0,
125         0x3AE0B160, 0x2B001810, 0xB0C03120, 0xB140B020,
126         0x18283BA0, 0x30C02A80, 0xB020B0A0, 0x3C60B140,
127         0x2A201838, 0xB0A03080, 0xB120B020, 0x18383D20,
128         0x304029C0, 0xB040B080, 0x3DE0B100, 0x29601848,
129         0xB0803000, 0xB100B040, 0x18483EC0, 0xB0402900,
130         0xB040B060, 0x3F80B0C0, 0x28801858, 0xB060B080,
131         0xB0A0B060, 0x18602820, 0xB0A02820, 0x0000B060,
132         0x36403000, 0x2D002CC0, 0x30003640, 0x2D0036C0,
133         0x35C02CC0, 0x37403000, 0x2C802D40, 0x30003540,
134         0x2D8037C0, 0x34C02C40, 0x38403000, 0x2BC02E00,
135         0x30003440, 0x2E2038C0, 0x34002B80, 0x39803000,
136         0x2B402E40, 0x30003380, 0x2E603A00, 0x33402B00,
137         0x3A803040, 0x2A802EA0, 0x30403300, 0x2EC03B40,
138         0x32802A40, 0x3C003040, 0x2A002EC0, 0x30803240,
139         0x2EC03C80, 0x320029C0, 0x3D403080, 0x29402F00,
140         0x308031C0, 0x2F203DC0, 0x31802900, 0x3E8030C0,
141         0x28802F40, 0x30C03140, 0x2F203F40, 0x31402840,
142         0x28003100, 0x28002F00, 0x00003100, 0x36403000,
143         0x2D002CC0, 0x30003640, 0x2D0036C0,
144         0x35C02CC0, 0x37403000, 0x2C802D40, 0x30003540,
145         0x2D8037C0, 0x34C02C40, 0x38403000, 0x2BC02E00,
146         0x30003440, 0x2E2038C0, 0x34002B80, 0x39803000,
147         0x2B402E40, 0x30003380, 0x2E603A00, 0x33402B00,
148         0x3A803040, 0x2A802EA0, 0x30403300, 0x2EC03B40,
149         0x32802A40, 0x3C003040, 0x2A002EC0, 0x30803240,
150         0x2EC03C80, 0x320029C0, 0x3D403080, 0x29402F00,
151         0x308031C0, 0x2F203DC0, 0x31802900, 0x3E8030C0,
152         0x28802F40, 0x30C03140, 0x2F203F40, 0x31402840,
153         0x28003100, 0x28002F00, 0x00003100,
154 };
155
156 /*
157  * Color conversion values have 3 separate fixed point formats:
158  *
159  * 10 bit fields (ay, au)
160  *   1.9 fixed point (b.bbbbbbbbb)
161  * 11 bit fields (ry, by, ru, gu, gv)
162  *   exp.mantissa (ee.mmmmmmmmm)
163  *   ee = 00 = 10^-1 (0.mmmmmmmmm)
164  *   ee = 01 = 10^-2 (0.0mmmmmmmmm)
165  *   ee = 10 = 10^-3 (0.00mmmmmmmmm)
166  *   ee = 11 = 10^-4 (0.000mmmmmmmmm)
167  * 12 bit fields (gy, rv, bu)
168  *   exp.mantissa (eee.mmmmmmmmm)
169  *   eee = 000 = 10^-1 (0.mmmmmmmmm)
170  *   eee = 001 = 10^-2 (0.0mmmmmmmmm)
171  *   eee = 010 = 10^-3 (0.00mmmmmmmmm)
172  *   eee = 011 = 10^-4 (0.000mmmmmmmmm)
173  *   eee = 100 = reserved
174  *   eee = 101 = reserved
175  *   eee = 110 = reserved
176  *   eee = 111 = 10^0 (m.mmmmmmmm) (only usable for 1.0 representation)
177  *
178  * Saturation and contrast are 8 bits, with their own representation:
179  * 8 bit field (saturation, contrast)
180  *   exp.mantissa (ee.mmmmmm)
181  *   ee = 00 = 10^-1 (0.mmmmmm)
182  *   ee = 01 = 10^0 (m.mmmmm)
183  *   ee = 10 = 10^1 (mm.mmmm)
184  *   ee = 11 = 10^2 (mmm.mmm)
185  *
186  * Simple conversion function:
187  *
188  * static u32
189  * float_to_csc_11(float f)
190  * {
191  *     u32 exp;
192  *     u32 mant;
193  *     u32 ret;
194  *
195  *     if (f < 0)
196  *         f = -f;
197  *
198  *     if (f >= 1) {
199  *         exp = 0x7;
200  *         mant = 1 << 8;
201  *     } else {
202  *         for (exp = 0; exp < 3 && f < 0.5; exp++)
203  *         f *= 2.0;
204  *         mant = (f * (1 << 9) + 0.5);
205  *         if (mant >= (1 << 9))
206  *             mant = (1 << 9) - 1;
207  *     }
208  *     ret = (exp << 9) | mant;
209  *     return ret;
210  * }
211  */
212
213 /*
214  * Behold, magic numbers!  If we plant them they might grow a big
215  * s-video cable to the sky... or something.
216  *
217  * Pre-converted to appropriate hex value.
218  */
219
220 /*
221  * PAL & NTSC values for composite & s-video connections
222  */
223 static const struct color_conversion ntsc_m_csc_composite = {
224         .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0104,
225         .ru = 0x0733, .gu = 0x052d, .bu = 0x05c7, .au = 0x0200,
226         .rv = 0x0340, .gv = 0x030c, .bv = 0x06d0, .av = 0x0200,
227 };
228
229 static const struct video_levels ntsc_m_levels_composite = {
230         .blank = 225, .black = 267, .burst = 113,
231 };
232
233 static const struct color_conversion ntsc_m_csc_svideo = {
234         .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0133,
235         .ru = 0x076a, .gu = 0x0564, .bu = 0x030d, .au = 0x0200,
236         .rv = 0x037a, .gv = 0x033d, .bv = 0x06f6, .av = 0x0200,
237 };
238
239 static const struct video_levels ntsc_m_levels_svideo = {
240         .blank = 266, .black = 316, .burst = 133,
241 };
242
243 static const struct color_conversion ntsc_j_csc_composite = {
244         .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0119,
245         .ru = 0x074c, .gu = 0x0546, .bu = 0x05ec, .au = 0x0200,
246         .rv = 0x035a, .gv = 0x0322, .bv = 0x06e1, .av = 0x0200,
247 };
248
249 static const struct video_levels ntsc_j_levels_composite = {
250         .blank = 225, .black = 225, .burst = 113,
251 };
252
253 static const struct color_conversion ntsc_j_csc_svideo = {
254         .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x014c,
255         .ru = 0x0788, .gu = 0x0581, .bu = 0x0322, .au = 0x0200,
256         .rv = 0x0399, .gv = 0x0356, .bv = 0x070a, .av = 0x0200,
257 };
258
259 static const struct video_levels ntsc_j_levels_svideo = {
260         .blank = 266, .black = 266, .burst = 133,
261 };
262
263 static const struct color_conversion pal_csc_composite = {
264         .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0113,
265         .ru = 0x0745, .gu = 0x053f, .bu = 0x05e1, .au = 0x0200,
266         .rv = 0x0353, .gv = 0x031c, .bv = 0x06dc, .av = 0x0200,
267 };
268
269 static const struct video_levels pal_levels_composite = {
270         .blank = 237, .black = 237, .burst = 118,
271 };
272
273 static const struct color_conversion pal_csc_svideo = {
274         .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0145,
275         .ru = 0x0780, .gu = 0x0579, .bu = 0x031c, .au = 0x0200,
276         .rv = 0x0390, .gv = 0x034f, .bv = 0x0705, .av = 0x0200,
277 };
278
279 static const struct video_levels pal_levels_svideo = {
280         .blank = 280, .black = 280, .burst = 139,
281 };
282
283 static const struct color_conversion pal_m_csc_composite = {
284         .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0104,
285         .ru = 0x0733, .gu = 0x052d, .bu = 0x05c7, .au = 0x0200,
286         .rv = 0x0340, .gv = 0x030c, .bv = 0x06d0, .av = 0x0200,
287 };
288
289 static const struct video_levels pal_m_levels_composite = {
290         .blank = 225, .black = 267, .burst = 113,
291 };
292
293 static const struct color_conversion pal_m_csc_svideo = {
294         .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0133,
295         .ru = 0x076a, .gu = 0x0564, .bu = 0x030d, .au = 0x0200,
296         .rv = 0x037a, .gv = 0x033d, .bv = 0x06f6, .av = 0x0200,
297 };
298
299 static const struct video_levels pal_m_levels_svideo = {
300         .blank = 266, .black = 316, .burst = 133,
301 };
302
303 static const struct color_conversion pal_n_csc_composite = {
304         .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0104,
305         .ru = 0x0733, .gu = 0x052d, .bu = 0x05c7, .au = 0x0200,
306         .rv = 0x0340, .gv = 0x030c, .bv = 0x06d0, .av = 0x0200,
307 };
308
309 static const struct video_levels pal_n_levels_composite = {
310         .blank = 225, .black = 267, .burst = 118,
311 };
312
313 static const struct color_conversion pal_n_csc_svideo = {
314         .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0133,
315         .ru = 0x076a, .gu = 0x0564, .bu = 0x030d, .au = 0x0200,
316         .rv = 0x037a, .gv = 0x033d, .bv = 0x06f6, .av = 0x0200,
317 };
318
319 static const struct video_levels pal_n_levels_svideo = {
320         .blank = 266, .black = 316, .burst = 139,
321 };
322
323 /*
324  * Component connections
325  */
326 static const struct color_conversion sdtv_csc_yprpb = {
327         .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0145,
328         .ru = 0x0559, .gu = 0x0353, .bu = 0x0100, .au = 0x0200,
329         .rv = 0x0100, .gv = 0x03ad, .bv = 0x074d, .av = 0x0200,
330 };
331
332 static const struct color_conversion sdtv_csc_rgb = {
333         .ry = 0x0000, .gy = 0x0f00, .by = 0x0000, .ay = 0x0166,
334         .ru = 0x0000, .gu = 0x0000, .bu = 0x0f00, .au = 0x0166,
335         .rv = 0x0f00, .gv = 0x0000, .bv = 0x0000, .av = 0x0166,
336 };
337
338 static const struct color_conversion hdtv_csc_yprpb = {
339         .ry = 0x05b3, .gy = 0x016e, .by = 0x0728, .ay = 0x0145,
340         .ru = 0x07d5, .gu = 0x038b, .bu = 0x0100, .au = 0x0200,
341         .rv = 0x0100, .gv = 0x03d1, .bv = 0x06bc, .av = 0x0200,
342 };
343
344 static const struct color_conversion hdtv_csc_rgb = {
345         .ry = 0x0000, .gy = 0x0f00, .by = 0x0000, .ay = 0x0166,
346         .ru = 0x0000, .gu = 0x0000, .bu = 0x0f00, .au = 0x0166,
347         .rv = 0x0f00, .gv = 0x0000, .bv = 0x0000, .av = 0x0166,
348 };
349
350 static const struct video_levels component_levels = {
351         .blank = 279, .black = 279, .burst = 0,
352 };
353
354
355 struct tv_mode {
356         const char *name;
357         int clock;
358         int refresh; /* in millihertz (for precision) */
359         u32 oversample;
360         int hsync_end, hblank_start, hblank_end, htotal;
361         bool progressive, trilevel_sync, component_only;
362         int vsync_start_f1, vsync_start_f2, vsync_len;
363         bool veq_ena;
364         int veq_start_f1, veq_start_f2, veq_len;
365         int vi_end_f1, vi_end_f2, nbr_end;
366         bool burst_ena;
367         int hburst_start, hburst_len;
368         int vburst_start_f1, vburst_end_f1;
369         int vburst_start_f2, vburst_end_f2;
370         int vburst_start_f3, vburst_end_f3;
371         int vburst_start_f4, vburst_end_f4;
372         /*
373          * subcarrier programming
374          */
375         int dda2_size, dda3_size, dda1_inc, dda2_inc, dda3_inc;
376         u32 sc_reset;
377         bool pal_burst;
378         /*
379          * blank/black levels
380          */
381         const struct video_levels *composite_levels, *svideo_levels;
382         const struct color_conversion *composite_color, *svideo_color;
383         const u32 *filter_table;
384         int max_srcw;
385 };
386
387
388 /*
389  * Sub carrier DDA
390  *
391  *  I think this works as follows:
392  *
393  *  subcarrier freq = pixel_clock * (dda1_inc + dda2_inc / dda2_size) / 4096
394  *
395  * Presumably, when dda3 is added in, it gets to adjust the dda2_inc value
396  *
397  * So,
398  *  dda1_ideal = subcarrier/pixel * 4096
399  *  dda1_inc = floor (dda1_ideal)
400  *  dda2 = dda1_ideal - dda1_inc
401  *
402  *  then pick a ratio for dda2 that gives the closest approximation. If
403  *  you can't get close enough, you can play with dda3 as well. This
404  *  seems likely to happen when dda2 is small as the jumps would be larger
405  *
406  * To invert this,
407  *
408  *  pixel_clock = subcarrier * 4096 / (dda1_inc + dda2_inc / dda2_size)
409  *
410  * The constants below were all computed using a 107.520MHz clock
411  */
412
413 /**
414  * Register programming values for TV modes.
415  *
416  * These values account for -1s required.
417  */
418
419 static const struct tv_mode tv_modes[] = {
420         {
421                 .name           = "NTSC-M",
422                 .clock          = 108000,
423                 .refresh        = 59940,
424                 .oversample     = TV_OVERSAMPLE_8X,
425                 .component_only = 0,
426                 /* 525 Lines, 60 Fields, 15.734KHz line, Sub-Carrier 3.580MHz */
427
428                 .hsync_end      = 64,               .hblank_end         = 124,
429                 .hblank_start   = 836,              .htotal             = 857,
430
431                 .progressive    = false,            .trilevel_sync = false,
432
433                 .vsync_start_f1 = 6,                .vsync_start_f2     = 7,
434                 .vsync_len      = 6,
435
436                 .veq_ena        = true,             .veq_start_f1       = 0,
437                 .veq_start_f2   = 1,                .veq_len            = 18,
438
439                 .vi_end_f1      = 20,               .vi_end_f2          = 21,
440                 .nbr_end        = 240,
441
442                 .burst_ena      = true,
443                 .hburst_start   = 72,               .hburst_len         = 34,
444                 .vburst_start_f1 = 9,               .vburst_end_f1      = 240,
445                 .vburst_start_f2 = 10,              .vburst_end_f2      = 240,
446                 .vburst_start_f3 = 9,               .vburst_end_f3      = 240,
447                 .vburst_start_f4 = 10,              .vburst_end_f4      = 240,
448
449                 /* desired 3.5800000 actual 3.5800000 clock 107.52 */
450                 .dda1_inc       =    135,
451                 .dda2_inc       =  20800,           .dda2_size          =  27456,
452                 .dda3_inc       =      0,           .dda3_size          =      0,
453                 .sc_reset       = TV_SC_RESET_EVERY_4,
454                 .pal_burst      = false,
455
456                 .composite_levels = &ntsc_m_levels_composite,
457                 .composite_color = &ntsc_m_csc_composite,
458                 .svideo_levels  = &ntsc_m_levels_svideo,
459                 .svideo_color = &ntsc_m_csc_svideo,
460
461                 .filter_table = filter_table,
462         },
463         {
464                 .name           = "NTSC-443",
465                 .clock          = 108000,
466                 .refresh        = 59940,
467                 .oversample     = TV_OVERSAMPLE_8X,
468                 .component_only = 0,
469                 /* 525 Lines, 60 Fields, 15.734KHz line, Sub-Carrier 4.43MHz */
470                 .hsync_end      = 64,               .hblank_end         = 124,
471                 .hblank_start   = 836,              .htotal             = 857,
472
473                 .progressive    = false,            .trilevel_sync = false,
474
475                 .vsync_start_f1 = 6,                .vsync_start_f2     = 7,
476                 .vsync_len      = 6,
477
478                 .veq_ena        = true,             .veq_start_f1       = 0,
479                 .veq_start_f2   = 1,                .veq_len            = 18,
480
481                 .vi_end_f1      = 20,               .vi_end_f2          = 21,
482                 .nbr_end        = 240,
483
484                 .burst_ena      = true,
485                 .hburst_start   = 72,               .hburst_len         = 34,
486                 .vburst_start_f1 = 9,               .vburst_end_f1      = 240,
487                 .vburst_start_f2 = 10,              .vburst_end_f2      = 240,
488                 .vburst_start_f3 = 9,               .vburst_end_f3      = 240,
489                 .vburst_start_f4 = 10,              .vburst_end_f4      = 240,
490
491                 /* desired 4.4336180 actual 4.4336180 clock 107.52 */
492                 .dda1_inc       =    168,
493                 .dda2_inc       =   4093,       .dda2_size      =  27456,
494                 .dda3_inc       =    310,       .dda3_size      =    525,
495                 .sc_reset   = TV_SC_RESET_NEVER,
496                 .pal_burst  = false,
497
498                 .composite_levels = &ntsc_m_levels_composite,
499                 .composite_color = &ntsc_m_csc_composite,
500                 .svideo_levels  = &ntsc_m_levels_svideo,
501                 .svideo_color = &ntsc_m_csc_svideo,
502
503                 .filter_table = filter_table,
504         },
505         {
506                 .name           = "NTSC-J",
507                 .clock          = 108000,
508                 .refresh        = 59940,
509                 .oversample     = TV_OVERSAMPLE_8X,
510                 .component_only = 0,
511
512                 /* 525 Lines, 60 Fields, 15.734KHz line, Sub-Carrier 3.580MHz */
513                 .hsync_end      = 64,               .hblank_end         = 124,
514                 .hblank_start = 836,        .htotal             = 857,
515
516                 .progressive    = false,    .trilevel_sync = false,
517
518                 .vsync_start_f1 = 6,        .vsync_start_f2     = 7,
519                 .vsync_len      = 6,
520
521                 .veq_ena      = true,       .veq_start_f1       = 0,
522                 .veq_start_f2 = 1,          .veq_len            = 18,
523
524                 .vi_end_f1      = 20,               .vi_end_f2          = 21,
525                 .nbr_end        = 240,
526
527                 .burst_ena      = true,
528                 .hburst_start   = 72,               .hburst_len         = 34,
529                 .vburst_start_f1 = 9,               .vburst_end_f1      = 240,
530                 .vburst_start_f2 = 10,              .vburst_end_f2      = 240,
531                 .vburst_start_f3 = 9,               .vburst_end_f3      = 240,
532                 .vburst_start_f4 = 10,              .vburst_end_f4      = 240,
533
534                 /* desired 3.5800000 actual 3.5800000 clock 107.52 */
535                 .dda1_inc       =    135,
536                 .dda2_inc       =  20800,           .dda2_size          =  27456,
537                 .dda3_inc       =      0,           .dda3_size          =      0,
538                 .sc_reset       = TV_SC_RESET_EVERY_4,
539                 .pal_burst      = false,
540
541                 .composite_levels = &ntsc_j_levels_composite,
542                 .composite_color = &ntsc_j_csc_composite,
543                 .svideo_levels  = &ntsc_j_levels_svideo,
544                 .svideo_color = &ntsc_j_csc_svideo,
545
546                 .filter_table = filter_table,
547         },
548         {
549                 .name           = "PAL-M",
550                 .clock          = 108000,
551                 .refresh        = 59940,
552                 .oversample     = TV_OVERSAMPLE_8X,
553                 .component_only = 0,
554
555                 /* 525 Lines, 60 Fields, 15.734KHz line, Sub-Carrier 3.580MHz */
556                 .hsync_end      = 64,             .hblank_end           = 124,
557                 .hblank_start = 836,      .htotal               = 857,
558
559                 .progressive    = false,            .trilevel_sync = false,
560
561                 .vsync_start_f1 = 6,                .vsync_start_f2     = 7,
562                 .vsync_len      = 6,
563
564                 .veq_ena        = true,             .veq_start_f1       = 0,
565                 .veq_start_f2   = 1,                .veq_len            = 18,
566
567                 .vi_end_f1      = 20,               .vi_end_f2          = 21,
568                 .nbr_end        = 240,
569
570                 .burst_ena      = true,
571                 .hburst_start   = 72,               .hburst_len         = 34,
572                 .vburst_start_f1 = 9,               .vburst_end_f1      = 240,
573                 .vburst_start_f2 = 10,              .vburst_end_f2      = 240,
574                 .vburst_start_f3 = 9,               .vburst_end_f3      = 240,
575                 .vburst_start_f4 = 10,              .vburst_end_f4      = 240,
576
577                 /* desired 3.5800000 actual 3.5800000 clock 107.52 */
578                 .dda1_inc       =    135,
579                 .dda2_inc       =  16704,           .dda2_size          =  27456,
580                 .dda3_inc       =      0,           .dda3_size          =      0,
581                 .sc_reset       = TV_SC_RESET_EVERY_8,
582                 .pal_burst  = true,
583
584                 .composite_levels = &pal_m_levels_composite,
585                 .composite_color = &pal_m_csc_composite,
586                 .svideo_levels  = &pal_m_levels_svideo,
587                 .svideo_color = &pal_m_csc_svideo,
588
589                 .filter_table = filter_table,
590         },
591         {
592                 /* 625 Lines, 50 Fields, 15.625KHz line, Sub-Carrier 4.434MHz */
593                 .name       = "PAL-N",
594                 .clock          = 108000,
595                 .refresh        = 50000,
596                 .oversample     = TV_OVERSAMPLE_8X,
597                 .component_only = 0,
598
599                 .hsync_end      = 64,               .hblank_end         = 128,
600                 .hblank_start = 844,        .htotal             = 863,
601
602                 .progressive  = false,    .trilevel_sync = false,
603
604
605                 .vsync_start_f1 = 6,       .vsync_start_f2      = 7,
606                 .vsync_len      = 6,
607
608                 .veq_ena        = true,             .veq_start_f1       = 0,
609                 .veq_start_f2   = 1,                .veq_len            = 18,
610
611                 .vi_end_f1      = 24,               .vi_end_f2          = 25,
612                 .nbr_end        = 286,
613
614                 .burst_ena      = true,
615                 .hburst_start = 73,         .hburst_len         = 34,
616                 .vburst_start_f1 = 8,       .vburst_end_f1      = 285,
617                 .vburst_start_f2 = 8,       .vburst_end_f2      = 286,
618                 .vburst_start_f3 = 9,       .vburst_end_f3      = 286,
619                 .vburst_start_f4 = 9,       .vburst_end_f4      = 285,
620
621
622                 /* desired 4.4336180 actual 4.4336180 clock 107.52 */
623                 .dda1_inc       =    135,
624                 .dda2_inc       =  23578,       .dda2_size      =  27648,
625                 .dda3_inc       =    134,       .dda3_size      =    625,
626                 .sc_reset   = TV_SC_RESET_EVERY_8,
627                 .pal_burst  = true,
628
629                 .composite_levels = &pal_n_levels_composite,
630                 .composite_color = &pal_n_csc_composite,
631                 .svideo_levels  = &pal_n_levels_svideo,
632                 .svideo_color = &pal_n_csc_svideo,
633
634                 .filter_table = filter_table,
635         },
636         {
637                 /* 625 Lines, 50 Fields, 15.625KHz line, Sub-Carrier 4.434MHz */
638                 .name       = "PAL",
639                 .clock          = 108000,
640                 .refresh        = 50000,
641                 .oversample     = TV_OVERSAMPLE_8X,
642                 .component_only = 0,
643
644                 .hsync_end      = 64,               .hblank_end         = 142,
645                 .hblank_start   = 844,      .htotal             = 863,
646
647                 .progressive    = false,    .trilevel_sync = false,
648
649                 .vsync_start_f1 = 5,        .vsync_start_f2     = 6,
650                 .vsync_len      = 5,
651
652                 .veq_ena        = true,     .veq_start_f1       = 0,
653                 .veq_start_f2   = 1,        .veq_len            = 15,
654
655                 .vi_end_f1      = 24,               .vi_end_f2          = 25,
656                 .nbr_end        = 286,
657
658                 .burst_ena      = true,
659                 .hburst_start   = 73,               .hburst_len         = 32,
660                 .vburst_start_f1 = 8,               .vburst_end_f1      = 285,
661                 .vburst_start_f2 = 8,               .vburst_end_f2      = 286,
662                 .vburst_start_f3 = 9,               .vburst_end_f3      = 286,
663                 .vburst_start_f4 = 9,               .vburst_end_f4      = 285,
664
665                 /* desired 4.4336180 actual 4.4336180 clock 107.52 */
666                 .dda1_inc       =    168,
667                 .dda2_inc       =   4122,       .dda2_size      =  27648,
668                 .dda3_inc       =     67,       .dda3_size      =    625,
669                 .sc_reset   = TV_SC_RESET_EVERY_8,
670                 .pal_burst  = true,
671
672                 .composite_levels = &pal_levels_composite,
673                 .composite_color = &pal_csc_composite,
674                 .svideo_levels  = &pal_levels_svideo,
675                 .svideo_color = &pal_csc_svideo,
676
677                 .filter_table = filter_table,
678         },
679         {
680                 .name       = "720p@60Hz",
681                 .clock          = 148800,
682                 .refresh        = 60000,
683                 .oversample     = TV_OVERSAMPLE_2X,
684                 .component_only = 1,
685
686                 .hsync_end      = 80,               .hblank_end         = 300,
687                 .hblank_start   = 1580,             .htotal             = 1649,
688
689                 .progressive    = true,             .trilevel_sync = true,
690
691                 .vsync_start_f1 = 10,               .vsync_start_f2     = 10,
692                 .vsync_len      = 10,
693
694                 .veq_ena        = false,
695
696                 .vi_end_f1      = 29,               .vi_end_f2          = 29,
697                 .nbr_end        = 719,
698
699                 .burst_ena      = false,
700
701                 .filter_table = filter_table,
702         },
703         {
704                 .name       = "720p@50Hz",
705                 .clock          = 148800,
706                 .refresh        = 50000,
707                 .oversample     = TV_OVERSAMPLE_2X,
708                 .component_only = 1,
709
710                 .hsync_end      = 80,               .hblank_end         = 300,
711                 .hblank_start   = 1580,             .htotal             = 1979,
712
713                 .progressive    = true,             .trilevel_sync = true,
714
715                 .vsync_start_f1 = 10,               .vsync_start_f2     = 10,
716                 .vsync_len      = 10,
717
718                 .veq_ena        = false,
719
720                 .vi_end_f1      = 29,               .vi_end_f2          = 29,
721                 .nbr_end        = 719,
722
723                 .burst_ena      = false,
724
725                 .filter_table = filter_table,
726                 .max_srcw = 800
727         },
728         {
729                 .name       = "1080i@50Hz",
730                 .clock          = 148800,
731                 .refresh        = 50000,
732                 .oversample     = TV_OVERSAMPLE_2X,
733                 .component_only = 1,
734
735                 .hsync_end      = 88,               .hblank_end         = 235,
736                 .hblank_start   = 2155,             .htotal             = 2639,
737
738                 .progressive    = false,          .trilevel_sync = true,
739
740                 .vsync_start_f1 = 4,              .vsync_start_f2     = 5,
741                 .vsync_len      = 10,
742
743                 .veq_ena        = true,     .veq_start_f1       = 4,
744                 .veq_start_f2   = 4,        .veq_len            = 10,
745
746
747                 .vi_end_f1      = 21,           .vi_end_f2          = 22,
748                 .nbr_end        = 539,
749
750                 .burst_ena      = false,
751
752                 .filter_table = filter_table,
753         },
754         {
755                 .name       = "1080i@60Hz",
756                 .clock          = 148800,
757                 .refresh        = 60000,
758                 .oversample     = TV_OVERSAMPLE_2X,
759                 .component_only = 1,
760
761                 .hsync_end      = 88,               .hblank_end         = 235,
762                 .hblank_start   = 2155,             .htotal             = 2199,
763
764                 .progressive    = false,            .trilevel_sync = true,
765
766                 .vsync_start_f1 = 4,               .vsync_start_f2     = 5,
767                 .vsync_len      = 10,
768
769                 .veq_ena        = true,             .veq_start_f1       = 4,
770                 .veq_start_f2   = 4,                .veq_len            = 10,
771
772
773                 .vi_end_f1      = 21,               .vi_end_f2          = 22,
774                 .nbr_end        = 539,
775
776                 .burst_ena      = false,
777
778                 .filter_table = filter_table,
779         },
780 };
781
782 static struct intel_tv *enc_to_intel_tv(struct drm_encoder *encoder)
783 {
784         return container_of(encoder, struct intel_tv, base.base);
785 }
786
787 static struct intel_tv *intel_attached_tv(struct drm_connector *connector)
788 {
789         return container_of(intel_attached_encoder(connector),
790                             struct intel_tv,
791                             base);
792 }
793
794 static void
795 intel_tv_dpms(struct drm_encoder *encoder, int mode)
796 {
797         struct drm_device *dev = encoder->dev;
798         struct drm_i915_private *dev_priv = dev->dev_private;
799
800         switch (mode) {
801         case DRM_MODE_DPMS_ON:
802                 I915_WRITE(TV_CTL, I915_READ(TV_CTL) | TV_ENC_ENABLE);
803                 break;
804         case DRM_MODE_DPMS_STANDBY:
805         case DRM_MODE_DPMS_SUSPEND:
806         case DRM_MODE_DPMS_OFF:
807                 I915_WRITE(TV_CTL, I915_READ(TV_CTL) & ~TV_ENC_ENABLE);
808                 break;
809         }
810 }
811
812 static const struct tv_mode *
813 intel_tv_mode_lookup(const char *tv_format)
814 {
815         int i;
816
817         for (i = 0; i < DRM_ARRAY_SIZE(tv_modes); i++) {
818                 const struct tv_mode *tv_mode = &tv_modes[i];
819
820                 if (!strcmp(tv_format, tv_mode->name))
821                         return tv_mode;
822         }
823         return NULL;
824 }
825
826 static const struct tv_mode *
827 intel_tv_mode_find(struct intel_tv *intel_tv)
828 {
829         return intel_tv_mode_lookup(intel_tv->tv_format);
830 }
831
832 static enum drm_mode_status
833 intel_tv_mode_valid(struct drm_connector *connector,
834                     struct drm_display_mode *mode)
835 {
836         struct intel_tv *intel_tv = intel_attached_tv(connector);
837         const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv);
838
839         /* Ensure TV refresh is close to desired refresh */
840         if (tv_mode && abs(tv_mode->refresh - drm_mode_vrefresh(mode) * 1000)
841                                 < 1000)
842                 return MODE_OK;
843
844         return MODE_CLOCK_RANGE;
845 }
846
847
848 static bool
849 intel_tv_mode_fixup(struct drm_encoder *encoder, const struct drm_display_mode *mode,
850                     struct drm_display_mode *adjusted_mode)
851 {
852         struct drm_device *dev = encoder->dev;
853         struct drm_mode_config *drm_config = &dev->mode_config;
854         struct intel_tv *intel_tv = enc_to_intel_tv(encoder);
855         const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv);
856         struct drm_encoder *other_encoder;
857
858         if (!tv_mode)
859                 return false;
860
861         /* FIXME: lock encoder list */
862         list_for_each_entry(other_encoder, &drm_config->encoder_list, head) {
863                 if (other_encoder != encoder &&
864                     other_encoder->crtc == encoder->crtc)
865                         return false;
866         }
867
868         adjusted_mode->clock = tv_mode->clock;
869         return true;
870 }
871
872 static void
873 intel_tv_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,
874                   struct drm_display_mode *adjusted_mode)
875 {
876         struct drm_device *dev = encoder->dev;
877         struct drm_i915_private *dev_priv = dev->dev_private;
878         struct drm_crtc *crtc = encoder->crtc;
879         struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
880         struct intel_tv *intel_tv = enc_to_intel_tv(encoder);
881         const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv);
882         u32 tv_ctl;
883         u32 hctl1, hctl2, hctl3;
884         u32 vctl1, vctl2, vctl3, vctl4, vctl5, vctl6, vctl7;
885         u32 scctl1, scctl2, scctl3;
886         int i, j;
887         const struct video_levels *video_levels;
888         const struct color_conversion *color_conversion;
889         bool burst_ena;
890         int pipe = intel_crtc->pipe;
891
892         if (!tv_mode)
893                 return; /* can't happen (mode_prepare prevents this) */
894
895         tv_ctl = I915_READ(TV_CTL);
896         tv_ctl &= TV_CTL_SAVE;
897
898         switch (intel_tv->type) {
899         default:
900         case DRM_MODE_CONNECTOR_Unknown:
901         case DRM_MODE_CONNECTOR_Composite:
902                 tv_ctl |= TV_ENC_OUTPUT_COMPOSITE;
903                 video_levels = tv_mode->composite_levels;
904                 color_conversion = tv_mode->composite_color;
905                 burst_ena = tv_mode->burst_ena;
906                 break;
907         case DRM_MODE_CONNECTOR_Component:
908                 tv_ctl |= TV_ENC_OUTPUT_COMPONENT;
909                 video_levels = &component_levels;
910                 if (tv_mode->burst_ena)
911                         color_conversion = &sdtv_csc_yprpb;
912                 else
913                         color_conversion = &hdtv_csc_yprpb;
914                 burst_ena = false;
915                 break;
916         case DRM_MODE_CONNECTOR_SVIDEO:
917                 tv_ctl |= TV_ENC_OUTPUT_SVIDEO;
918                 video_levels = tv_mode->svideo_levels;
919                 color_conversion = tv_mode->svideo_color;
920                 burst_ena = tv_mode->burst_ena;
921                 break;
922         }
923         hctl1 = (tv_mode->hsync_end << TV_HSYNC_END_SHIFT) |
924                 (tv_mode->htotal << TV_HTOTAL_SHIFT);
925
926         hctl2 = (tv_mode->hburst_start << 16) |
927                 (tv_mode->hburst_len << TV_HBURST_LEN_SHIFT);
928
929         if (burst_ena)
930                 hctl2 |= TV_BURST_ENA;
931
932         hctl3 = (tv_mode->hblank_start << TV_HBLANK_START_SHIFT) |
933                 (tv_mode->hblank_end << TV_HBLANK_END_SHIFT);
934
935         vctl1 = (tv_mode->nbr_end << TV_NBR_END_SHIFT) |
936                 (tv_mode->vi_end_f1 << TV_VI_END_F1_SHIFT) |
937                 (tv_mode->vi_end_f2 << TV_VI_END_F2_SHIFT);
938
939         vctl2 = (tv_mode->vsync_len << TV_VSYNC_LEN_SHIFT) |
940                 (tv_mode->vsync_start_f1 << TV_VSYNC_START_F1_SHIFT) |
941                 (tv_mode->vsync_start_f2 << TV_VSYNC_START_F2_SHIFT);
942
943         vctl3 = (tv_mode->veq_len << TV_VEQ_LEN_SHIFT) |
944                 (tv_mode->veq_start_f1 << TV_VEQ_START_F1_SHIFT) |
945                 (tv_mode->veq_start_f2 << TV_VEQ_START_F2_SHIFT);
946
947         if (tv_mode->veq_ena)
948                 vctl3 |= TV_EQUAL_ENA;
949
950         vctl4 = (tv_mode->vburst_start_f1 << TV_VBURST_START_F1_SHIFT) |
951                 (tv_mode->vburst_end_f1 << TV_VBURST_END_F1_SHIFT);
952
953         vctl5 = (tv_mode->vburst_start_f2 << TV_VBURST_START_F2_SHIFT) |
954                 (tv_mode->vburst_end_f2 << TV_VBURST_END_F2_SHIFT);
955
956         vctl6 = (tv_mode->vburst_start_f3 << TV_VBURST_START_F3_SHIFT) |
957                 (tv_mode->vburst_end_f3 << TV_VBURST_END_F3_SHIFT);
958
959         vctl7 = (tv_mode->vburst_start_f4 << TV_VBURST_START_F4_SHIFT) |
960                 (tv_mode->vburst_end_f4 << TV_VBURST_END_F4_SHIFT);
961
962         if (intel_crtc->pipe == 1)
963                 tv_ctl |= TV_ENC_PIPEB_SELECT;
964         tv_ctl |= tv_mode->oversample;
965
966         if (tv_mode->progressive)
967                 tv_ctl |= TV_PROGRESSIVE;
968         if (tv_mode->trilevel_sync)
969                 tv_ctl |= TV_TRILEVEL_SYNC;
970         if (tv_mode->pal_burst)
971                 tv_ctl |= TV_PAL_BURST;
972
973         scctl1 = 0;
974         if (tv_mode->dda1_inc)
975                 scctl1 |= TV_SC_DDA1_EN;
976         if (tv_mode->dda2_inc)
977                 scctl1 |= TV_SC_DDA2_EN;
978         if (tv_mode->dda3_inc)
979                 scctl1 |= TV_SC_DDA3_EN;
980         scctl1 |= tv_mode->sc_reset;
981         if (video_levels)
982                 scctl1 |= video_levels->burst << TV_BURST_LEVEL_SHIFT;
983         scctl1 |= tv_mode->dda1_inc << TV_SCDDA1_INC_SHIFT;
984
985         scctl2 = tv_mode->dda2_size << TV_SCDDA2_SIZE_SHIFT |
986                 tv_mode->dda2_inc << TV_SCDDA2_INC_SHIFT;
987
988         scctl3 = tv_mode->dda3_size << TV_SCDDA3_SIZE_SHIFT |
989                 tv_mode->dda3_inc << TV_SCDDA3_INC_SHIFT;
990
991         /* Enable two fixes for the chips that need them. */
992         if (dev->pci_device < 0x2772)
993                 tv_ctl |= TV_ENC_C0_FIX | TV_ENC_SDP_FIX;
994
995         I915_WRITE(TV_H_CTL_1, hctl1);
996         I915_WRITE(TV_H_CTL_2, hctl2);
997         I915_WRITE(TV_H_CTL_3, hctl3);
998         I915_WRITE(TV_V_CTL_1, vctl1);
999         I915_WRITE(TV_V_CTL_2, vctl2);
1000         I915_WRITE(TV_V_CTL_3, vctl3);
1001         I915_WRITE(TV_V_CTL_4, vctl4);
1002         I915_WRITE(TV_V_CTL_5, vctl5);
1003         I915_WRITE(TV_V_CTL_6, vctl6);
1004         I915_WRITE(TV_V_CTL_7, vctl7);
1005         I915_WRITE(TV_SC_CTL_1, scctl1);
1006         I915_WRITE(TV_SC_CTL_2, scctl2);
1007         I915_WRITE(TV_SC_CTL_3, scctl3);
1008
1009         if (color_conversion) {
1010                 I915_WRITE(TV_CSC_Y, (color_conversion->ry << 16) |
1011                            color_conversion->gy);
1012                 I915_WRITE(TV_CSC_Y2, (color_conversion->by << 16) |
1013                            color_conversion->ay);
1014                 I915_WRITE(TV_CSC_U, (color_conversion->ru << 16) |
1015                            color_conversion->gu);
1016                 I915_WRITE(TV_CSC_U2, (color_conversion->bu << 16) |
1017                            color_conversion->au);
1018                 I915_WRITE(TV_CSC_V, (color_conversion->rv << 16) |
1019                            color_conversion->gv);
1020                 I915_WRITE(TV_CSC_V2, (color_conversion->bv << 16) |
1021                            color_conversion->av);
1022         }
1023
1024         if (INTEL_INFO(dev)->gen >= 4)
1025                 I915_WRITE(TV_CLR_KNOBS, 0x00404000);
1026         else
1027                 I915_WRITE(TV_CLR_KNOBS, 0x00606000);
1028
1029         if (video_levels)
1030                 I915_WRITE(TV_CLR_LEVEL,
1031                            ((video_levels->black << TV_BLACK_LEVEL_SHIFT) |
1032                             (video_levels->blank << TV_BLANK_LEVEL_SHIFT)));
1033         {
1034                 int pipeconf_reg = PIPECONF(pipe);
1035                 int dspcntr_reg = DSPCNTR(intel_crtc->plane);
1036                 int pipeconf = I915_READ(pipeconf_reg);
1037                 int dspcntr = I915_READ(dspcntr_reg);
1038                 int dspbase_reg = DSPADDR(intel_crtc->plane);
1039                 int xpos = 0x0, ypos = 0x0;
1040                 unsigned int xsize, ysize;
1041                 /* Pipe must be off here */
1042                 I915_WRITE(dspcntr_reg, dspcntr & ~DISPLAY_PLANE_ENABLE);
1043                 /* Flush the plane changes */
1044                 I915_WRITE(dspbase_reg, I915_READ(dspbase_reg));
1045
1046                 /* Wait for vblank for the disable to take effect */
1047                 if (IS_GEN2(dev))
1048                         intel_wait_for_vblank(dev, intel_crtc->pipe);
1049
1050                 I915_WRITE(pipeconf_reg, pipeconf & ~PIPECONF_ENABLE);
1051                 /* Wait for vblank for the disable to take effect. */
1052                 intel_wait_for_pipe_off(dev, intel_crtc->pipe);
1053
1054                 /* Filter ctl must be set before TV_WIN_SIZE */
1055                 I915_WRITE(TV_FILTER_CTL_1, TV_AUTO_SCALE);
1056                 xsize = tv_mode->hblank_start - tv_mode->hblank_end;
1057                 if (tv_mode->progressive)
1058                         ysize = tv_mode->nbr_end + 1;
1059                 else
1060                         ysize = 2*tv_mode->nbr_end + 1;
1061
1062                 xpos += intel_tv->margin[TV_MARGIN_LEFT];
1063                 ypos += intel_tv->margin[TV_MARGIN_TOP];
1064                 xsize -= (intel_tv->margin[TV_MARGIN_LEFT] +
1065                           intel_tv->margin[TV_MARGIN_RIGHT]);
1066                 ysize -= (intel_tv->margin[TV_MARGIN_TOP] +
1067                           intel_tv->margin[TV_MARGIN_BOTTOM]);
1068                 I915_WRITE(TV_WIN_POS, (xpos<<16)|ypos);
1069                 I915_WRITE(TV_WIN_SIZE, (xsize<<16)|ysize);
1070
1071                 I915_WRITE(pipeconf_reg, pipeconf);
1072                 I915_WRITE(dspcntr_reg, dspcntr);
1073                 /* Flush the plane changes */
1074                 I915_WRITE(dspbase_reg, I915_READ(dspbase_reg));
1075         }
1076
1077         j = 0;
1078         for (i = 0; i < 60; i++)
1079                 I915_WRITE(TV_H_LUMA_0 + (i<<2), tv_mode->filter_table[j++]);
1080         for (i = 0; i < 60; i++)
1081                 I915_WRITE(TV_H_CHROMA_0 + (i<<2), tv_mode->filter_table[j++]);
1082         for (i = 0; i < 43; i++)
1083                 I915_WRITE(TV_V_LUMA_0 + (i<<2), tv_mode->filter_table[j++]);
1084         for (i = 0; i < 43; i++)
1085                 I915_WRITE(TV_V_CHROMA_0 + (i<<2), tv_mode->filter_table[j++]);
1086         I915_WRITE(TV_DAC, I915_READ(TV_DAC) & TV_DAC_SAVE);
1087         I915_WRITE(TV_CTL, tv_ctl);
1088 }
1089
1090 static const struct drm_display_mode reported_modes[] = {
1091         {
1092                 .name = "NTSC 480i",
1093                 .clock = 107520,
1094                 .hdisplay = 1280,
1095                 .hsync_start = 1368,
1096                 .hsync_end = 1496,
1097                 .htotal = 1712,
1098
1099                 .vdisplay = 1024,
1100                 .vsync_start = 1027,
1101                 .vsync_end = 1034,
1102                 .vtotal = 1104,
1103                 .type = DRM_MODE_TYPE_DRIVER,
1104         },
1105 };
1106
1107 /**
1108  * Detects TV presence by checking for load.
1109  *
1110  * Requires that the current pipe's DPLL is active.
1111
1112  * \return true if TV is connected.
1113  * \return false if TV is disconnected.
1114  */
1115 static int
1116 intel_tv_detect_type(struct intel_tv *intel_tv,
1117                       struct drm_connector *connector)
1118 {
1119         struct drm_encoder *encoder = &intel_tv->base.base;
1120         struct drm_crtc *crtc = encoder->crtc;
1121         struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
1122         struct drm_device *dev = encoder->dev;
1123         struct drm_i915_private *dev_priv = dev->dev_private;
1124         u32 tv_ctl, save_tv_ctl;
1125         u32 tv_dac, save_tv_dac;
1126         int type;
1127
1128         /* Disable TV interrupts around load detect or we'll recurse */
1129         if (connector->polled & DRM_CONNECTOR_POLL_HPD) {
1130                 mtx_lock(&dev_priv->irq_lock);
1131                 i915_disable_pipestat(dev_priv, 0,
1132                                       PIPE_HOTPLUG_INTERRUPT_ENABLE |
1133                                       PIPE_HOTPLUG_TV_INTERRUPT_ENABLE);
1134                 mtx_unlock(&dev_priv->irq_lock);
1135         }
1136
1137         save_tv_dac = tv_dac = I915_READ(TV_DAC);
1138         save_tv_ctl = tv_ctl = I915_READ(TV_CTL);
1139
1140         /* Poll for TV detection */
1141         tv_ctl &= ~(TV_ENC_ENABLE | TV_TEST_MODE_MASK);
1142         tv_ctl |= TV_TEST_MODE_MONITOR_DETECT;
1143         if (intel_crtc->pipe == 1)
1144                 tv_ctl |= TV_ENC_PIPEB_SELECT;
1145         else
1146                 tv_ctl &= ~TV_ENC_PIPEB_SELECT;
1147
1148         tv_dac &= ~(TVDAC_SENSE_MASK | DAC_A_MASK | DAC_B_MASK | DAC_C_MASK);
1149         tv_dac |= (TVDAC_STATE_CHG_EN |
1150                    TVDAC_A_SENSE_CTL |
1151                    TVDAC_B_SENSE_CTL |
1152                    TVDAC_C_SENSE_CTL |
1153                    DAC_CTL_OVERRIDE |
1154                    DAC_A_0_7_V |
1155                    DAC_B_0_7_V |
1156                    DAC_C_0_7_V);
1157
1158
1159         /*
1160          * The TV sense state should be cleared to zero on cantiga platform. Otherwise
1161          * the TV is misdetected. This is hardware requirement.
1162          */
1163         if (IS_GM45(dev))
1164                 tv_dac &= ~(TVDAC_STATE_CHG_EN | TVDAC_A_SENSE_CTL |
1165                             TVDAC_B_SENSE_CTL | TVDAC_C_SENSE_CTL);
1166
1167         I915_WRITE(TV_CTL, tv_ctl);
1168         I915_WRITE(TV_DAC, tv_dac);
1169         POSTING_READ(TV_DAC);
1170
1171         intel_wait_for_vblank(intel_tv->base.base.dev,
1172                               to_intel_crtc(intel_tv->base.base.crtc)->pipe);
1173
1174         type = -1;
1175         tv_dac = I915_READ(TV_DAC);
1176         DRM_DEBUG_KMS("TV detected: %x, %x\n", tv_ctl, tv_dac);
1177         /*
1178          *  A B C
1179          *  0 1 1 Composite
1180          *  1 0 X svideo
1181          *  0 0 0 Component
1182          */
1183         if ((tv_dac & TVDAC_SENSE_MASK) == (TVDAC_B_SENSE | TVDAC_C_SENSE)) {
1184                 DRM_DEBUG_KMS("Detected Composite TV connection\n");
1185                 type = DRM_MODE_CONNECTOR_Composite;
1186         } else if ((tv_dac & (TVDAC_A_SENSE|TVDAC_B_SENSE)) == TVDAC_A_SENSE) {
1187                 DRM_DEBUG_KMS("Detected S-Video TV connection\n");
1188                 type = DRM_MODE_CONNECTOR_SVIDEO;
1189         } else if ((tv_dac & TVDAC_SENSE_MASK) == 0) {
1190                 DRM_DEBUG_KMS("Detected Component TV connection\n");
1191                 type = DRM_MODE_CONNECTOR_Component;
1192         } else {
1193                 DRM_DEBUG_KMS("Unrecognised TV connection\n");
1194                 type = -1;
1195         }
1196
1197         I915_WRITE(TV_DAC, save_tv_dac & ~TVDAC_STATE_CHG_EN);
1198         I915_WRITE(TV_CTL, save_tv_ctl);
1199
1200         /* Restore interrupt config */
1201         if (connector->polled & DRM_CONNECTOR_POLL_HPD) {
1202                 mtx_lock(&dev_priv->irq_lock);
1203                 i915_enable_pipestat(dev_priv, 0,
1204                                      PIPE_HOTPLUG_INTERRUPT_ENABLE |
1205                                      PIPE_HOTPLUG_TV_INTERRUPT_ENABLE);
1206                 mtx_unlock(&dev_priv->irq_lock);
1207         }
1208
1209         return type;
1210 }
1211
1212 /*
1213  * Here we set accurate tv format according to connector type
1214  * i.e Component TV should not be assigned by NTSC or PAL
1215  */
1216 static void intel_tv_find_better_format(struct drm_connector *connector)
1217 {
1218         struct intel_tv *intel_tv = intel_attached_tv(connector);
1219         const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv);
1220         int i;
1221
1222         if ((intel_tv->type == DRM_MODE_CONNECTOR_Component) ==
1223                 tv_mode->component_only)
1224                 return;
1225
1226
1227         for (i = 0; i < sizeof(tv_modes) / sizeof(*tv_modes); i++) {
1228                 tv_mode = tv_modes + i;
1229
1230                 if ((intel_tv->type == DRM_MODE_CONNECTOR_Component) ==
1231                         tv_mode->component_only)
1232                         break;
1233         }
1234
1235         intel_tv->tv_format = tv_mode->name;
1236         drm_object_property_set_value(&connector->base,
1237                 connector->dev->mode_config.tv_mode_property, i);
1238 }
1239
1240 /**
1241  * Detect the TV connection.
1242  *
1243  * Currently this always returns CONNECTOR_STATUS_UNKNOWN, as we need to be sure
1244  * we have a pipe programmed in order to probe the TV.
1245  */
1246 static enum drm_connector_status
1247 intel_tv_detect(struct drm_connector *connector, bool force)
1248 {
1249         struct drm_display_mode mode;
1250         struct intel_tv *intel_tv = intel_attached_tv(connector);
1251         int type;
1252
1253         mode = reported_modes[0];
1254         drm_mode_set_crtcinfo(&mode, 0);
1255
1256         if (force) {
1257                 struct intel_load_detect_pipe tmp;
1258
1259                 if (intel_get_load_detect_pipe(&intel_tv->base, connector,
1260                                                &mode, &tmp)) {
1261                         type = intel_tv_detect_type(intel_tv, connector);
1262                         intel_release_load_detect_pipe(&intel_tv->base,
1263                                                        connector,
1264                                                        &tmp);
1265                 } else
1266                         return connector_status_unknown;
1267         } else
1268                 return connector->status;
1269
1270         if (type < 0)
1271                 return connector_status_disconnected;
1272
1273         intel_tv->type = type;
1274         intel_tv_find_better_format(connector);
1275
1276         return connector_status_connected;
1277 }
1278
1279 static const struct input_res {
1280         const char *name;
1281         int w, h;
1282 } input_res_table[] = {
1283         {"640x480", 640, 480},
1284         {"800x600", 800, 600},
1285         {"1024x768", 1024, 768},
1286         {"1280x1024", 1280, 1024},
1287         {"848x480", 848, 480},
1288         {"1280x720", 1280, 720},
1289         {"1920x1080", 1920, 1080},
1290 };
1291
1292 /*
1293  * Chose preferred mode  according to line number of TV format
1294  */
1295 static void
1296 intel_tv_chose_preferred_modes(struct drm_connector *connector,
1297                                struct drm_display_mode *mode_ptr)
1298 {
1299         struct intel_tv *intel_tv = intel_attached_tv(connector);
1300         const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv);
1301
1302         if (tv_mode->nbr_end < 480 && mode_ptr->vdisplay == 480)
1303                 mode_ptr->type |= DRM_MODE_TYPE_PREFERRED;
1304         else if (tv_mode->nbr_end > 480) {
1305                 if (tv_mode->progressive == true && tv_mode->nbr_end < 720) {
1306                         if (mode_ptr->vdisplay == 720)
1307                                 mode_ptr->type |= DRM_MODE_TYPE_PREFERRED;
1308                 } else if (mode_ptr->vdisplay == 1080)
1309                                 mode_ptr->type |= DRM_MODE_TYPE_PREFERRED;
1310         }
1311 }
1312
1313 /**
1314  * Stub get_modes function.
1315  *
1316  * This should probably return a set of fixed modes, unless we can figure out
1317  * how to probe modes off of TV connections.
1318  */
1319
1320 static int
1321 intel_tv_get_modes(struct drm_connector *connector)
1322 {
1323         struct drm_display_mode *mode_ptr;
1324         struct intel_tv *intel_tv = intel_attached_tv(connector);
1325         const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv);
1326         int j, count = 0;
1327         u64 tmp;
1328
1329         for (j = 0; j < ARRAY_SIZE(input_res_table);
1330              j++) {
1331                 const struct input_res *input = &input_res_table[j];
1332                 unsigned int hactive_s = input->w;
1333                 unsigned int vactive_s = input->h;
1334
1335                 if (tv_mode->max_srcw && input->w > tv_mode->max_srcw)
1336                         continue;
1337
1338                 if (input->w > 1024 && (!tv_mode->progressive
1339                                         && !tv_mode->component_only))
1340                         continue;
1341
1342                 mode_ptr = drm_mode_create(connector->dev);
1343                 if (!mode_ptr)
1344                         continue;
1345                 strncpy(mode_ptr->name, input->name, DRM_DISPLAY_MODE_LEN);
1346
1347                 mode_ptr->hdisplay = hactive_s;
1348                 mode_ptr->hsync_start = hactive_s + 1;
1349                 mode_ptr->hsync_end = hactive_s + 64;
1350                 if (mode_ptr->hsync_end <= mode_ptr->hsync_start)
1351                         mode_ptr->hsync_end = mode_ptr->hsync_start + 1;
1352                 mode_ptr->htotal = hactive_s + 96;
1353
1354                 mode_ptr->vdisplay = vactive_s;
1355                 mode_ptr->vsync_start = vactive_s + 1;
1356                 mode_ptr->vsync_end = vactive_s + 32;
1357                 if (mode_ptr->vsync_end <= mode_ptr->vsync_start)
1358                         mode_ptr->vsync_end = mode_ptr->vsync_start  + 1;
1359                 mode_ptr->vtotal = vactive_s + 33;
1360
1361                 tmp = (u64) tv_mode->refresh * mode_ptr->vtotal;
1362                 tmp *= mode_ptr->htotal;
1363                 tmp = tmp / 1000000;
1364                 mode_ptr->clock = (int) tmp;
1365
1366                 mode_ptr->type = DRM_MODE_TYPE_DRIVER;
1367                 intel_tv_chose_preferred_modes(connector, mode_ptr);
1368                 drm_mode_probed_add(connector, mode_ptr);
1369                 count++;
1370         }
1371
1372         return count;
1373 }
1374
1375 static void
1376 intel_tv_destroy(struct drm_connector *connector)
1377 {
1378 #if 0
1379         drm_sysfs_connector_remove(connector);
1380 #endif
1381         drm_connector_cleanup(connector);
1382         free(connector, DRM_MEM_KMS);
1383 }
1384
1385
1386 static int
1387 intel_tv_set_property(struct drm_connector *connector, struct drm_property *property,
1388                       uint64_t val)
1389 {
1390         struct drm_device *dev = connector->dev;
1391         struct intel_tv *intel_tv = intel_attached_tv(connector);
1392         struct drm_crtc *crtc = intel_tv->base.base.crtc;
1393         int ret = 0;
1394         bool changed = false;
1395
1396         ret = drm_object_property_set_value(&connector->base, property, val);
1397         if (ret < 0)
1398                 goto out;
1399
1400         if (property == dev->mode_config.tv_left_margin_property &&
1401                 intel_tv->margin[TV_MARGIN_LEFT] != val) {
1402                 intel_tv->margin[TV_MARGIN_LEFT] = val;
1403                 changed = true;
1404         } else if (property == dev->mode_config.tv_right_margin_property &&
1405                 intel_tv->margin[TV_MARGIN_RIGHT] != val) {
1406                 intel_tv->margin[TV_MARGIN_RIGHT] = val;
1407                 changed = true;
1408         } else if (property == dev->mode_config.tv_top_margin_property &&
1409                 intel_tv->margin[TV_MARGIN_TOP] != val) {
1410                 intel_tv->margin[TV_MARGIN_TOP] = val;
1411                 changed = true;
1412         } else if (property == dev->mode_config.tv_bottom_margin_property &&
1413                 intel_tv->margin[TV_MARGIN_BOTTOM] != val) {
1414                 intel_tv->margin[TV_MARGIN_BOTTOM] = val;
1415                 changed = true;
1416         } else if (property == dev->mode_config.tv_mode_property) {
1417                 if (val >= ARRAY_SIZE(tv_modes)) {
1418                         ret = -EINVAL;
1419                         goto out;
1420                 }
1421                 if (!strcmp(intel_tv->tv_format, tv_modes[val].name))
1422                         goto out;
1423
1424                 intel_tv->tv_format = tv_modes[val].name;
1425                 changed = true;
1426         } else {
1427                 ret = -EINVAL;
1428                 goto out;
1429         }
1430
1431         if (changed && crtc)
1432                 drm_crtc_helper_set_mode(crtc, &crtc->mode, crtc->x,
1433                                 crtc->y, crtc->fb);
1434 out:
1435         return ret;
1436 }
1437
1438 static const struct drm_encoder_helper_funcs intel_tv_helper_funcs = {
1439         .dpms = intel_tv_dpms,
1440         .mode_fixup = intel_tv_mode_fixup,
1441         .prepare = intel_encoder_prepare,
1442         .mode_set = intel_tv_mode_set,
1443         .commit = intel_encoder_commit,
1444 };
1445
1446 static const struct drm_connector_funcs intel_tv_connector_funcs = {
1447         .dpms = drm_helper_connector_dpms,
1448         .detect = intel_tv_detect,
1449         .destroy = intel_tv_destroy,
1450         .set_property = intel_tv_set_property,
1451         .fill_modes = drm_helper_probe_single_connector_modes,
1452 };
1453
1454 static const struct drm_connector_helper_funcs intel_tv_connector_helper_funcs = {
1455         .mode_valid = intel_tv_mode_valid,
1456         .get_modes = intel_tv_get_modes,
1457         .best_encoder = intel_best_encoder,
1458 };
1459
1460 static const struct drm_encoder_funcs intel_tv_enc_funcs = {
1461         .destroy = intel_encoder_destroy,
1462 };
1463
1464 /*
1465  * Enumerate the child dev array parsed from VBT to check whether
1466  * the integrated TV is present.
1467  * If it is present, return 1.
1468  * If it is not present, return false.
1469  * If no child dev is parsed from VBT, it assumes that the TV is present.
1470  */
1471 static int tv_is_present_in_vbt(struct drm_device *dev)
1472 {
1473         struct drm_i915_private *dev_priv = dev->dev_private;
1474         struct child_device_config *p_child;
1475         int i, ret;
1476
1477         if (!dev_priv->child_dev_num)
1478                 return 1;
1479
1480         ret = 0;
1481         for (i = 0; i < dev_priv->child_dev_num; i++) {
1482                 p_child = dev_priv->child_dev + i;
1483                 /*
1484                  * If the device type is not TV, continue.
1485                  */
1486                 if (p_child->device_type != DEVICE_TYPE_INT_TV &&
1487                         p_child->device_type != DEVICE_TYPE_TV)
1488                         continue;
1489                 /* Only when the addin_offset is non-zero, it is regarded
1490                  * as present.
1491                  */
1492                 if (p_child->addin_offset) {
1493                         ret = 1;
1494                         break;
1495                 }
1496         }
1497         return ret;
1498 }
1499
1500 void
1501 intel_tv_init(struct drm_device *dev)
1502 {
1503         struct drm_i915_private *dev_priv = dev->dev_private;
1504         struct drm_connector *connector;
1505         struct intel_tv *intel_tv;
1506         struct intel_encoder *intel_encoder;
1507         struct intel_connector *intel_connector;
1508         u32 tv_dac_on, tv_dac_off, save_tv_dac;
1509         char *tv_format_names[ARRAY_SIZE(tv_modes)];
1510         int i, initial_mode = 0;
1511
1512         if ((I915_READ(TV_CTL) & TV_FUSE_STATE_MASK) == TV_FUSE_STATE_DISABLED)
1513                 return;
1514
1515         if (!tv_is_present_in_vbt(dev)) {
1516                 DRM_DEBUG_KMS("Integrated TV is not present.\n");
1517                 return;
1518         }
1519         /* Even if we have an encoder we may not have a connector */
1520         if (!dev_priv->int_tv_support)
1521                 return;
1522
1523         /*
1524          * Sanity check the TV output by checking to see if the
1525          * DAC register holds a value
1526          */
1527         save_tv_dac = I915_READ(TV_DAC);
1528
1529         I915_WRITE(TV_DAC, save_tv_dac | TVDAC_STATE_CHG_EN);
1530         tv_dac_on = I915_READ(TV_DAC);
1531
1532         I915_WRITE(TV_DAC, save_tv_dac & ~TVDAC_STATE_CHG_EN);
1533         tv_dac_off = I915_READ(TV_DAC);
1534
1535         I915_WRITE(TV_DAC, save_tv_dac);
1536
1537         /*
1538          * If the register does not hold the state change enable
1539          * bit, (either as a 0 or a 1), assume it doesn't really
1540          * exist
1541          */
1542         if ((tv_dac_on & TVDAC_STATE_CHG_EN) == 0 ||
1543             (tv_dac_off & TVDAC_STATE_CHG_EN) != 0)
1544                 return;
1545
1546         intel_tv = malloc(sizeof(struct intel_tv), DRM_MEM_KMS,
1547             M_WAITOK | M_ZERO);
1548         intel_connector = malloc(sizeof(struct intel_connector), DRM_MEM_KMS,
1549             M_WAITOK | M_ZERO);
1550
1551         intel_encoder = &intel_tv->base;
1552         connector = &intel_connector->base;
1553
1554         /* The documentation, for the older chipsets at least, recommend
1555          * using a polling method rather than hotplug detection for TVs.
1556          * This is because in order to perform the hotplug detection, the PLLs
1557          * for the TV must be kept alive increasing power drain and starving
1558          * bandwidth from other encoders. Notably for instance, it causes
1559          * pipe underruns on Crestline when this encoder is supposedly idle.
1560          *
1561          * More recent chipsets favour HDMI rather than integrated S-Video.
1562          */
1563         connector->polled = DRM_CONNECTOR_POLL_CONNECT;
1564
1565         drm_connector_init(dev, connector, &intel_tv_connector_funcs,
1566                            DRM_MODE_CONNECTOR_SVIDEO);
1567
1568         drm_encoder_init(dev, &intel_encoder->base, &intel_tv_enc_funcs,
1569                          DRM_MODE_ENCODER_TVDAC);
1570
1571         intel_connector_attach_encoder(intel_connector, intel_encoder);
1572         intel_encoder->type = INTEL_OUTPUT_TVOUT;
1573         intel_encoder->crtc_mask = (1 << 0) | (1 << 1);
1574         intel_encoder->clone_mask = (1 << INTEL_TV_CLONE_BIT);
1575         intel_encoder->base.possible_crtcs = ((1 << 0) | (1 << 1));
1576         intel_encoder->base.possible_clones = (1 << INTEL_OUTPUT_TVOUT);
1577         intel_tv->type = DRM_MODE_CONNECTOR_Unknown;
1578
1579         /* BIOS margin values */
1580         intel_tv->margin[TV_MARGIN_LEFT] = 54;
1581         intel_tv->margin[TV_MARGIN_TOP] = 36;
1582         intel_tv->margin[TV_MARGIN_RIGHT] = 46;
1583         intel_tv->margin[TV_MARGIN_BOTTOM] = 37;
1584
1585         intel_tv->tv_format = tv_modes[initial_mode].name;
1586
1587         drm_encoder_helper_add(&intel_encoder->base, &intel_tv_helper_funcs);
1588         drm_connector_helper_add(connector, &intel_tv_connector_helper_funcs);
1589         connector->interlace_allowed = false;
1590         connector->doublescan_allowed = false;
1591
1592         /* Create TV properties then attach current values */
1593         for (i = 0; i < ARRAY_SIZE(tv_modes); i++)
1594                 tv_format_names[i] = __DECONST(char *, tv_modes[i].name);
1595         drm_mode_create_tv_properties(dev,
1596                                       ARRAY_SIZE(tv_modes),
1597                                       tv_format_names);
1598
1599         drm_object_attach_property(&connector->base, dev->mode_config.tv_mode_property,
1600                                    initial_mode);
1601         drm_object_attach_property(&connector->base,
1602                                    dev->mode_config.tv_left_margin_property,
1603                                    intel_tv->margin[TV_MARGIN_LEFT]);
1604         drm_object_attach_property(&connector->base,
1605                                    dev->mode_config.tv_top_margin_property,
1606                                    intel_tv->margin[TV_MARGIN_TOP]);
1607         drm_object_attach_property(&connector->base,
1608                                    dev->mode_config.tv_right_margin_property,
1609                                    intel_tv->margin[TV_MARGIN_RIGHT]);
1610         drm_object_attach_property(&connector->base,
1611                                    dev->mode_config.tv_bottom_margin_property,
1612                                    intel_tv->margin[TV_MARGIN_BOTTOM]);
1613 #if 0
1614         drm_sysfs_connector_add(connector);
1615 #endif
1616 }