Merge git://git.kernel.org/pub/scm/linux/kernel/git/steve/gfs2-2.6-fixes
[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         I915_WRITE(TV_CTL, tv_ctl);
1267         I915_WRITE(TV_DAC, tv_dac);
1268         intel_wait_for_vblank(dev);
1269         tv_dac = I915_READ(TV_DAC);
1270         I915_WRITE(TV_DAC, save_tv_dac);
1271         I915_WRITE(TV_CTL, save_tv_ctl);
1272         intel_wait_for_vblank(dev);
1273         /*
1274          *  A B C
1275          *  0 1 1 Composite
1276          *  1 0 X svideo
1277          *  0 0 0 Component
1278          */
1279         if ((tv_dac & TVDAC_SENSE_MASK) == (TVDAC_B_SENSE | TVDAC_C_SENSE)) {
1280                 DRM_DEBUG_KMS("Detected Composite TV connection\n");
1281                 type = DRM_MODE_CONNECTOR_Composite;
1282         } else if ((tv_dac & (TVDAC_A_SENSE|TVDAC_B_SENSE)) == TVDAC_A_SENSE) {
1283                 DRM_DEBUG_KMS("Detected S-Video TV connection\n");
1284                 type = DRM_MODE_CONNECTOR_SVIDEO;
1285         } else if ((tv_dac & TVDAC_SENSE_MASK) == 0) {
1286                 DRM_DEBUG_KMS("Detected Component TV connection\n");
1287                 type = DRM_MODE_CONNECTOR_Component;
1288         } else {
1289                 DRM_DEBUG_KMS("No TV connection detected\n");
1290                 type = -1;
1291         }
1292
1293         /* Restore interrupt config */
1294         spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags);
1295         i915_enable_pipestat(dev_priv, 0, PIPE_HOTPLUG_INTERRUPT_ENABLE |
1296                              PIPE_HOTPLUG_TV_INTERRUPT_ENABLE);
1297         spin_unlock_irqrestore(&dev_priv->user_irq_lock, irqflags);
1298
1299         return type;
1300 }
1301
1302 /*
1303  * Here we set accurate tv format according to connector type
1304  * i.e Component TV should not be assigned by NTSC or PAL
1305  */
1306 static void intel_tv_find_better_format(struct drm_connector *connector)
1307 {
1308         struct drm_encoder *encoder = intel_attached_encoder(connector);
1309         struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
1310         struct intel_tv_priv *tv_priv = intel_encoder->dev_priv;
1311         const struct tv_mode *tv_mode = intel_tv_mode_find(intel_encoder);
1312         int i;
1313
1314         if ((tv_priv->type == DRM_MODE_CONNECTOR_Component) ==
1315                 tv_mode->component_only)
1316                 return;
1317
1318
1319         for (i = 0; i < sizeof(tv_modes) / sizeof(*tv_modes); i++) {
1320                 tv_mode = tv_modes + i;
1321
1322                 if ((tv_priv->type == DRM_MODE_CONNECTOR_Component) ==
1323                         tv_mode->component_only)
1324                         break;
1325         }
1326
1327         tv_priv->tv_format = tv_mode->name;
1328         drm_connector_property_set_value(connector,
1329                 connector->dev->mode_config.tv_mode_property, i);
1330 }
1331
1332 /**
1333  * Detect the TV connection.
1334  *
1335  * Currently this always returns CONNECTOR_STATUS_UNKNOWN, as we need to be sure
1336  * we have a pipe programmed in order to probe the TV.
1337  */
1338 static enum drm_connector_status
1339 intel_tv_detect(struct drm_connector *connector)
1340 {
1341         struct drm_crtc *crtc;
1342         struct drm_display_mode mode;
1343         struct drm_encoder *encoder = intel_attached_encoder(connector);
1344         struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
1345         struct intel_tv_priv *tv_priv = intel_encoder->dev_priv;
1346         int dpms_mode;
1347         int type = tv_priv->type;
1348
1349         mode = reported_modes[0];
1350         drm_mode_set_crtcinfo(&mode, CRTC_INTERLACE_HALVE_V);
1351
1352         if (encoder->crtc && encoder->crtc->enabled) {
1353                 type = intel_tv_detect_type(encoder->crtc, intel_encoder);
1354         } else {
1355                 crtc = intel_get_load_detect_pipe(intel_encoder, connector,
1356                                                   &mode, &dpms_mode);
1357                 if (crtc) {
1358                         type = intel_tv_detect_type(crtc, intel_encoder);
1359                         intel_release_load_detect_pipe(intel_encoder, connector,
1360                                                        dpms_mode);
1361                 } else
1362                         type = -1;
1363         }
1364
1365         tv_priv->type = type;
1366
1367         if (type < 0)
1368                 return connector_status_disconnected;
1369
1370         intel_tv_find_better_format(connector);
1371         return connector_status_connected;
1372 }
1373
1374 static struct input_res {
1375         char *name;
1376         int w, h;
1377 } input_res_table[] =
1378 {
1379         {"640x480", 640, 480},
1380         {"800x600", 800, 600},
1381         {"1024x768", 1024, 768},
1382         {"1280x1024", 1280, 1024},
1383         {"848x480", 848, 480},
1384         {"1280x720", 1280, 720},
1385         {"1920x1080", 1920, 1080},
1386 };
1387
1388 /*
1389  * Chose preferred mode  according to line number of TV format
1390  */
1391 static void
1392 intel_tv_chose_preferred_modes(struct drm_connector *connector,
1393                                struct drm_display_mode *mode_ptr)
1394 {
1395         struct drm_encoder *encoder = intel_attached_encoder(connector);
1396         struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
1397         const struct tv_mode *tv_mode = intel_tv_mode_find(intel_encoder);
1398
1399         if (tv_mode->nbr_end < 480 && mode_ptr->vdisplay == 480)
1400                 mode_ptr->type |= DRM_MODE_TYPE_PREFERRED;
1401         else if (tv_mode->nbr_end > 480) {
1402                 if (tv_mode->progressive == true && tv_mode->nbr_end < 720) {
1403                         if (mode_ptr->vdisplay == 720)
1404                                 mode_ptr->type |= DRM_MODE_TYPE_PREFERRED;
1405                 } else if (mode_ptr->vdisplay == 1080)
1406                                 mode_ptr->type |= DRM_MODE_TYPE_PREFERRED;
1407         }
1408 }
1409
1410 /**
1411  * Stub get_modes function.
1412  *
1413  * This should probably return a set of fixed modes, unless we can figure out
1414  * how to probe modes off of TV connections.
1415  */
1416
1417 static int
1418 intel_tv_get_modes(struct drm_connector *connector)
1419 {
1420         struct drm_display_mode *mode_ptr;
1421         struct drm_encoder *encoder = intel_attached_encoder(connector);
1422         struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
1423         const struct tv_mode *tv_mode = intel_tv_mode_find(intel_encoder);
1424         int j, count = 0;
1425         u64 tmp;
1426
1427         for (j = 0; j < sizeof(input_res_table) / sizeof(input_res_table[0]);
1428              j++) {
1429                 struct input_res *input = &input_res_table[j];
1430                 unsigned int hactive_s = input->w;
1431                 unsigned int vactive_s = input->h;
1432
1433                 if (tv_mode->max_srcw && input->w > tv_mode->max_srcw)
1434                         continue;
1435
1436                 if (input->w > 1024 && (!tv_mode->progressive
1437                                         && !tv_mode->component_only))
1438                         continue;
1439
1440                 mode_ptr = drm_mode_create(connector->dev);
1441                 if (!mode_ptr)
1442                         continue;
1443                 strncpy(mode_ptr->name, input->name, DRM_DISPLAY_MODE_LEN);
1444
1445                 mode_ptr->hdisplay = hactive_s;
1446                 mode_ptr->hsync_start = hactive_s + 1;
1447                 mode_ptr->hsync_end = hactive_s + 64;
1448                 if (mode_ptr->hsync_end <= mode_ptr->hsync_start)
1449                         mode_ptr->hsync_end = mode_ptr->hsync_start + 1;
1450                 mode_ptr->htotal = hactive_s + 96;
1451
1452                 mode_ptr->vdisplay = vactive_s;
1453                 mode_ptr->vsync_start = vactive_s + 1;
1454                 mode_ptr->vsync_end = vactive_s + 32;
1455                 if (mode_ptr->vsync_end <= mode_ptr->vsync_start)
1456                         mode_ptr->vsync_end = mode_ptr->vsync_start  + 1;
1457                 mode_ptr->vtotal = vactive_s + 33;
1458
1459                 tmp = (u64) tv_mode->refresh * mode_ptr->vtotal;
1460                 tmp *= mode_ptr->htotal;
1461                 tmp = div_u64(tmp, 1000000);
1462                 mode_ptr->clock = (int) tmp;
1463
1464                 mode_ptr->type = DRM_MODE_TYPE_DRIVER;
1465                 intel_tv_chose_preferred_modes(connector, mode_ptr);
1466                 drm_mode_probed_add(connector, mode_ptr);
1467                 count++;
1468         }
1469
1470         return count;
1471 }
1472
1473 static void
1474 intel_tv_destroy (struct drm_connector *connector)
1475 {
1476         drm_sysfs_connector_remove(connector);
1477         drm_connector_cleanup(connector);
1478         kfree(connector);
1479 }
1480
1481
1482 static int
1483 intel_tv_set_property(struct drm_connector *connector, struct drm_property *property,
1484                       uint64_t val)
1485 {
1486         struct drm_device *dev = connector->dev;
1487         struct drm_encoder *encoder = intel_attached_encoder(connector);
1488         struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
1489         struct intel_tv_priv *tv_priv = intel_encoder->dev_priv;
1490         struct drm_crtc *crtc = encoder->crtc;
1491         int ret = 0;
1492         bool changed = false;
1493
1494         ret = drm_connector_property_set_value(connector, property, val);
1495         if (ret < 0)
1496                 goto out;
1497
1498         if (property == dev->mode_config.tv_left_margin_property &&
1499                 tv_priv->margin[TV_MARGIN_LEFT] != val) {
1500                 tv_priv->margin[TV_MARGIN_LEFT] = val;
1501                 changed = true;
1502         } else if (property == dev->mode_config.tv_right_margin_property &&
1503                 tv_priv->margin[TV_MARGIN_RIGHT] != val) {
1504                 tv_priv->margin[TV_MARGIN_RIGHT] = val;
1505                 changed = true;
1506         } else if (property == dev->mode_config.tv_top_margin_property &&
1507                 tv_priv->margin[TV_MARGIN_TOP] != val) {
1508                 tv_priv->margin[TV_MARGIN_TOP] = val;
1509                 changed = true;
1510         } else if (property == dev->mode_config.tv_bottom_margin_property &&
1511                 tv_priv->margin[TV_MARGIN_BOTTOM] != val) {
1512                 tv_priv->margin[TV_MARGIN_BOTTOM] = val;
1513                 changed = true;
1514         } else if (property == dev->mode_config.tv_mode_property) {
1515                 if (val >= NUM_TV_MODES) {
1516                         ret = -EINVAL;
1517                         goto out;
1518                 }
1519                 if (!strcmp(tv_priv->tv_format, tv_modes[val].name))
1520                         goto out;
1521
1522                 tv_priv->tv_format = tv_modes[val].name;
1523                 changed = true;
1524         } else {
1525                 ret = -EINVAL;
1526                 goto out;
1527         }
1528
1529         if (changed && crtc)
1530                 drm_crtc_helper_set_mode(crtc, &crtc->mode, crtc->x,
1531                                 crtc->y, crtc->fb);
1532 out:
1533         return ret;
1534 }
1535
1536 static const struct drm_encoder_helper_funcs intel_tv_helper_funcs = {
1537         .dpms = intel_tv_dpms,
1538         .mode_fixup = intel_tv_mode_fixup,
1539         .prepare = intel_encoder_prepare,
1540         .mode_set = intel_tv_mode_set,
1541         .commit = intel_encoder_commit,
1542 };
1543
1544 static const struct drm_connector_funcs intel_tv_connector_funcs = {
1545         .dpms = drm_helper_connector_dpms,
1546         .detect = intel_tv_detect,
1547         .destroy = intel_tv_destroy,
1548         .set_property = intel_tv_set_property,
1549         .fill_modes = drm_helper_probe_single_connector_modes,
1550 };
1551
1552 static const struct drm_connector_helper_funcs intel_tv_connector_helper_funcs = {
1553         .mode_valid = intel_tv_mode_valid,
1554         .get_modes = intel_tv_get_modes,
1555         .best_encoder = intel_attached_encoder,
1556 };
1557
1558 static void intel_tv_enc_destroy(struct drm_encoder *encoder)
1559 {
1560         struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
1561
1562         drm_encoder_cleanup(encoder);
1563         kfree(intel_encoder);
1564 }
1565
1566 static const struct drm_encoder_funcs intel_tv_enc_funcs = {
1567         .destroy = intel_tv_enc_destroy,
1568 };
1569
1570 /*
1571  * Enumerate the child dev array parsed from VBT to check whether
1572  * the integrated TV is present.
1573  * If it is present, return 1.
1574  * If it is not present, return false.
1575  * If no child dev is parsed from VBT, it assumes that the TV is present.
1576  */
1577 static int tv_is_present_in_vbt(struct drm_device *dev)
1578 {
1579         struct drm_i915_private *dev_priv = dev->dev_private;
1580         struct child_device_config *p_child;
1581         int i, ret;
1582
1583         if (!dev_priv->child_dev_num)
1584                 return 1;
1585
1586         ret = 0;
1587         for (i = 0; i < dev_priv->child_dev_num; i++) {
1588                 p_child = dev_priv->child_dev + i;
1589                 /*
1590                  * If the device type is not TV, continue.
1591                  */
1592                 if (p_child->device_type != DEVICE_TYPE_INT_TV &&
1593                         p_child->device_type != DEVICE_TYPE_TV)
1594                         continue;
1595                 /* Only when the addin_offset is non-zero, it is regarded
1596                  * as present.
1597                  */
1598                 if (p_child->addin_offset) {
1599                         ret = 1;
1600                         break;
1601                 }
1602         }
1603         return ret;
1604 }
1605
1606 void
1607 intel_tv_init(struct drm_device *dev)
1608 {
1609         struct drm_i915_private *dev_priv = dev->dev_private;
1610         struct drm_connector *connector;
1611         struct intel_encoder *intel_encoder;
1612         struct intel_connector *intel_connector;
1613         struct intel_tv_priv *tv_priv;
1614         u32 tv_dac_on, tv_dac_off, save_tv_dac;
1615         char **tv_format_names;
1616         int i, initial_mode = 0;
1617
1618         if ((I915_READ(TV_CTL) & TV_FUSE_STATE_MASK) == TV_FUSE_STATE_DISABLED)
1619                 return;
1620
1621         if (!tv_is_present_in_vbt(dev)) {
1622                 DRM_DEBUG_KMS("Integrated TV is not present.\n");
1623                 return;
1624         }
1625         /* Even if we have an encoder we may not have a connector */
1626         if (!dev_priv->int_tv_support)
1627                 return;
1628
1629         /*
1630          * Sanity check the TV output by checking to see if the
1631          * DAC register holds a value
1632          */
1633         save_tv_dac = I915_READ(TV_DAC);
1634
1635         I915_WRITE(TV_DAC, save_tv_dac | TVDAC_STATE_CHG_EN);
1636         tv_dac_on = I915_READ(TV_DAC);
1637
1638         I915_WRITE(TV_DAC, save_tv_dac & ~TVDAC_STATE_CHG_EN);
1639         tv_dac_off = I915_READ(TV_DAC);
1640
1641         I915_WRITE(TV_DAC, save_tv_dac);
1642
1643         /*
1644          * If the register does not hold the state change enable
1645          * bit, (either as a 0 or a 1), assume it doesn't really
1646          * exist
1647          */
1648         if ((tv_dac_on & TVDAC_STATE_CHG_EN) == 0 ||
1649             (tv_dac_off & TVDAC_STATE_CHG_EN) != 0)
1650                 return;
1651
1652         intel_encoder = kzalloc(sizeof(struct intel_encoder) +
1653                                sizeof(struct intel_tv_priv), GFP_KERNEL);
1654         if (!intel_encoder) {
1655                 return;
1656         }
1657
1658         intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL);
1659         if (!intel_connector) {
1660                 kfree(intel_encoder);
1661                 return;
1662         }
1663
1664         connector = &intel_connector->base;
1665
1666         drm_connector_init(dev, connector, &intel_tv_connector_funcs,
1667                            DRM_MODE_CONNECTOR_SVIDEO);
1668
1669         drm_encoder_init(dev, &intel_encoder->enc, &intel_tv_enc_funcs,
1670                          DRM_MODE_ENCODER_TVDAC);
1671
1672         drm_mode_connector_attach_encoder(&intel_connector->base, &intel_encoder->enc);
1673         tv_priv = (struct intel_tv_priv *)(intel_encoder + 1);
1674         intel_encoder->type = INTEL_OUTPUT_TVOUT;
1675         intel_encoder->crtc_mask = (1 << 0) | (1 << 1);
1676         intel_encoder->clone_mask = (1 << INTEL_TV_CLONE_BIT);
1677         intel_encoder->enc.possible_crtcs = ((1 << 0) | (1 << 1));
1678         intel_encoder->enc.possible_clones = (1 << INTEL_OUTPUT_TVOUT);
1679         intel_encoder->dev_priv = tv_priv;
1680         tv_priv->type = DRM_MODE_CONNECTOR_Unknown;
1681
1682         /* BIOS margin values */
1683         tv_priv->margin[TV_MARGIN_LEFT] = 54;
1684         tv_priv->margin[TV_MARGIN_TOP] = 36;
1685         tv_priv->margin[TV_MARGIN_RIGHT] = 46;
1686         tv_priv->margin[TV_MARGIN_BOTTOM] = 37;
1687
1688         tv_priv->tv_format = kstrdup(tv_modes[initial_mode].name, GFP_KERNEL);
1689
1690         drm_encoder_helper_add(&intel_encoder->enc, &intel_tv_helper_funcs);
1691         drm_connector_helper_add(connector, &intel_tv_connector_helper_funcs);
1692         connector->interlace_allowed = false;
1693         connector->doublescan_allowed = false;
1694
1695         /* Create TV properties then attach current values */
1696         tv_format_names = kmalloc(sizeof(char *) * NUM_TV_MODES,
1697                                   GFP_KERNEL);
1698         if (!tv_format_names)
1699                 goto out;
1700         for (i = 0; i < NUM_TV_MODES; i++)
1701                 tv_format_names[i] = tv_modes[i].name;
1702         drm_mode_create_tv_properties(dev, NUM_TV_MODES, tv_format_names);
1703
1704         drm_connector_attach_property(connector, dev->mode_config.tv_mode_property,
1705                                    initial_mode);
1706         drm_connector_attach_property(connector,
1707                                    dev->mode_config.tv_left_margin_property,
1708                                    tv_priv->margin[TV_MARGIN_LEFT]);
1709         drm_connector_attach_property(connector,
1710                                    dev->mode_config.tv_top_margin_property,
1711                                    tv_priv->margin[TV_MARGIN_TOP]);
1712         drm_connector_attach_property(connector,
1713                                    dev->mode_config.tv_right_margin_property,
1714                                    tv_priv->margin[TV_MARGIN_RIGHT]);
1715         drm_connector_attach_property(connector,
1716                                    dev->mode_config.tv_bottom_margin_property,
1717                                    tv_priv->margin[TV_MARGIN_BOTTOM]);
1718 out:
1719         drm_sysfs_connector_add(connector);
1720 }