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