Merge master.kernel.org:/pub/scm/linux/kernel/git/lethal/genesis-2.6 into devel-stable
[sfrench/cifs-2.6.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      = true,
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 static void
900 intel_tv_dpms(struct drm_encoder *encoder, int mode)
901 {
902         struct drm_device *dev = encoder->dev;
903         struct drm_i915_private *dev_priv = dev->dev_private;
904
905         switch(mode) {
906         case DRM_MODE_DPMS_ON:
907                 I915_WRITE(TV_CTL, I915_READ(TV_CTL) | TV_ENC_ENABLE);
908                 break;
909         case DRM_MODE_DPMS_STANDBY:
910         case DRM_MODE_DPMS_SUSPEND:
911         case DRM_MODE_DPMS_OFF:
912                 I915_WRITE(TV_CTL, I915_READ(TV_CTL) & ~TV_ENC_ENABLE);
913                 break;
914         }
915 }
916
917 static const struct tv_mode *
918 intel_tv_mode_lookup (char *tv_format)
919 {
920         int i;
921
922         for (i = 0; i < sizeof(tv_modes) / sizeof (tv_modes[0]); i++) {
923                 const struct tv_mode *tv_mode = &tv_modes[i];
924
925                 if (!strcmp(tv_format, tv_mode->name))
926                         return tv_mode;
927         }
928         return NULL;
929 }
930
931 static const struct tv_mode *
932 intel_tv_mode_find (struct intel_encoder *intel_encoder)
933 {
934         struct intel_tv_priv *tv_priv = intel_encoder->dev_priv;
935
936         return intel_tv_mode_lookup(tv_priv->tv_format);
937 }
938
939 static enum drm_mode_status
940 intel_tv_mode_valid(struct drm_connector *connector, struct drm_display_mode *mode)
941 {
942         struct drm_encoder *encoder = intel_attached_encoder(connector);
943         struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
944         const struct tv_mode *tv_mode = intel_tv_mode_find(intel_encoder);
945
946         /* Ensure TV refresh is close to desired refresh */
947         if (tv_mode && abs(tv_mode->refresh - drm_mode_vrefresh(mode) * 1000)
948                                 < 1000)
949                 return MODE_OK;
950         return MODE_CLOCK_RANGE;
951 }
952
953
954 static bool
955 intel_tv_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode,
956                     struct drm_display_mode *adjusted_mode)
957 {
958         struct drm_device *dev = encoder->dev;
959         struct drm_mode_config *drm_config = &dev->mode_config;
960         struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
961         const struct tv_mode *tv_mode = intel_tv_mode_find (intel_encoder);
962         struct drm_encoder *other_encoder;
963
964         if (!tv_mode)
965                 return false;
966
967         /* FIXME: lock encoder list */
968         list_for_each_entry(other_encoder, &drm_config->encoder_list, head) {
969                 if (other_encoder != encoder &&
970                     other_encoder->crtc == encoder->crtc)
971                         return false;
972         }
973
974         adjusted_mode->clock = tv_mode->clock;
975         return true;
976 }
977
978 static void
979 intel_tv_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,
980                   struct drm_display_mode *adjusted_mode)
981 {
982         struct drm_device *dev = encoder->dev;
983         struct drm_i915_private *dev_priv = dev->dev_private;
984         struct drm_crtc *crtc = encoder->crtc;
985         struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
986         struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
987         struct intel_tv_priv *tv_priv = intel_encoder->dev_priv;
988         const struct tv_mode *tv_mode = intel_tv_mode_find(intel_encoder);
989         u32 tv_ctl;
990         u32 hctl1, hctl2, hctl3;
991         u32 vctl1, vctl2, vctl3, vctl4, vctl5, vctl6, vctl7;
992         u32 scctl1, scctl2, scctl3;
993         int i, j;
994         const struct video_levels *video_levels;
995         const struct color_conversion *color_conversion;
996         bool burst_ena;
997
998         if (!tv_mode)
999                 return; /* can't happen (mode_prepare prevents this) */
1000
1001         tv_ctl = I915_READ(TV_CTL);
1002         tv_ctl &= TV_CTL_SAVE;
1003
1004         switch (tv_priv->type) {
1005         default:
1006         case DRM_MODE_CONNECTOR_Unknown:
1007         case DRM_MODE_CONNECTOR_Composite:
1008                 tv_ctl |= TV_ENC_OUTPUT_COMPOSITE;
1009                 video_levels = tv_mode->composite_levels;
1010                 color_conversion = tv_mode->composite_color;
1011                 burst_ena = tv_mode->burst_ena;
1012                 break;
1013         case DRM_MODE_CONNECTOR_Component:
1014                 tv_ctl |= TV_ENC_OUTPUT_COMPONENT;
1015                 video_levels = &component_levels;
1016                 if (tv_mode->burst_ena)
1017                         color_conversion = &sdtv_csc_yprpb;
1018                 else
1019                         color_conversion = &hdtv_csc_yprpb;
1020                 burst_ena = false;
1021                 break;
1022         case DRM_MODE_CONNECTOR_SVIDEO:
1023                 tv_ctl |= TV_ENC_OUTPUT_SVIDEO;
1024                 video_levels = tv_mode->svideo_levels;
1025                 color_conversion = tv_mode->svideo_color;
1026                 burst_ena = tv_mode->burst_ena;
1027                 break;
1028         }
1029         hctl1 = (tv_mode->hsync_end << TV_HSYNC_END_SHIFT) |
1030                 (tv_mode->htotal << TV_HTOTAL_SHIFT);
1031
1032         hctl2 = (tv_mode->hburst_start << 16) |
1033                 (tv_mode->hburst_len << TV_HBURST_LEN_SHIFT);
1034
1035         if (burst_ena)
1036                 hctl2 |= TV_BURST_ENA;
1037
1038         hctl3 = (tv_mode->hblank_start << TV_HBLANK_START_SHIFT) |
1039                 (tv_mode->hblank_end << TV_HBLANK_END_SHIFT);
1040
1041         vctl1 = (tv_mode->nbr_end << TV_NBR_END_SHIFT) |
1042                 (tv_mode->vi_end_f1 << TV_VI_END_F1_SHIFT) |
1043                 (tv_mode->vi_end_f2 << TV_VI_END_F2_SHIFT);
1044
1045         vctl2 = (tv_mode->vsync_len << TV_VSYNC_LEN_SHIFT) |
1046                 (tv_mode->vsync_start_f1 << TV_VSYNC_START_F1_SHIFT) |
1047                 (tv_mode->vsync_start_f2 << TV_VSYNC_START_F2_SHIFT);
1048
1049         vctl3 = (tv_mode->veq_len << TV_VEQ_LEN_SHIFT) |
1050                 (tv_mode->veq_start_f1 << TV_VEQ_START_F1_SHIFT) |
1051                 (tv_mode->veq_start_f2 << TV_VEQ_START_F2_SHIFT);
1052
1053         if (tv_mode->veq_ena)
1054                 vctl3 |= TV_EQUAL_ENA;
1055
1056         vctl4 = (tv_mode->vburst_start_f1 << TV_VBURST_START_F1_SHIFT) |
1057                 (tv_mode->vburst_end_f1 << TV_VBURST_END_F1_SHIFT);
1058
1059         vctl5 = (tv_mode->vburst_start_f2 << TV_VBURST_START_F2_SHIFT) |
1060                 (tv_mode->vburst_end_f2 << TV_VBURST_END_F2_SHIFT);
1061
1062         vctl6 = (tv_mode->vburst_start_f3 << TV_VBURST_START_F3_SHIFT) |
1063                 (tv_mode->vburst_end_f3 << TV_VBURST_END_F3_SHIFT);
1064
1065         vctl7 = (tv_mode->vburst_start_f4 << TV_VBURST_START_F4_SHIFT) |
1066                 (tv_mode->vburst_end_f4 << TV_VBURST_END_F4_SHIFT);
1067
1068         if (intel_crtc->pipe == 1)
1069                 tv_ctl |= TV_ENC_PIPEB_SELECT;
1070         tv_ctl |= tv_mode->oversample;
1071
1072         if (tv_mode->progressive)
1073                 tv_ctl |= TV_PROGRESSIVE;
1074         if (tv_mode->trilevel_sync)
1075                 tv_ctl |= TV_TRILEVEL_SYNC;
1076         if (tv_mode->pal_burst)
1077                 tv_ctl |= TV_PAL_BURST;
1078
1079         scctl1 = 0;
1080         if (tv_mode->dda1_inc)
1081                 scctl1 |= TV_SC_DDA1_EN;
1082         if (tv_mode->dda2_inc)
1083                 scctl1 |= TV_SC_DDA2_EN;
1084         if (tv_mode->dda3_inc)
1085                 scctl1 |= TV_SC_DDA3_EN;
1086         scctl1 |= tv_mode->sc_reset;
1087         if (video_levels)
1088                 scctl1 |= video_levels->burst << TV_BURST_LEVEL_SHIFT;
1089         scctl1 |= tv_mode->dda1_inc << TV_SCDDA1_INC_SHIFT;
1090
1091         scctl2 = tv_mode->dda2_size << TV_SCDDA2_SIZE_SHIFT |
1092                 tv_mode->dda2_inc << TV_SCDDA2_INC_SHIFT;
1093
1094         scctl3 = tv_mode->dda3_size << TV_SCDDA3_SIZE_SHIFT |
1095                 tv_mode->dda3_inc << TV_SCDDA3_INC_SHIFT;
1096
1097         /* Enable two fixes for the chips that need them. */
1098         if (dev->pci_device < 0x2772)
1099                 tv_ctl |= TV_ENC_C0_FIX | TV_ENC_SDP_FIX;
1100
1101         I915_WRITE(TV_H_CTL_1, hctl1);
1102         I915_WRITE(TV_H_CTL_2, hctl2);
1103         I915_WRITE(TV_H_CTL_3, hctl3);
1104         I915_WRITE(TV_V_CTL_1, vctl1);
1105         I915_WRITE(TV_V_CTL_2, vctl2);
1106         I915_WRITE(TV_V_CTL_3, vctl3);
1107         I915_WRITE(TV_V_CTL_4, vctl4);
1108         I915_WRITE(TV_V_CTL_5, vctl5);
1109         I915_WRITE(TV_V_CTL_6, vctl6);
1110         I915_WRITE(TV_V_CTL_7, vctl7);
1111         I915_WRITE(TV_SC_CTL_1, scctl1);
1112         I915_WRITE(TV_SC_CTL_2, scctl2);
1113         I915_WRITE(TV_SC_CTL_3, scctl3);
1114
1115         if (color_conversion) {
1116                 I915_WRITE(TV_CSC_Y, (color_conversion->ry << 16) |
1117                            color_conversion->gy);
1118                 I915_WRITE(TV_CSC_Y2,(color_conversion->by << 16) |
1119                            color_conversion->ay);
1120                 I915_WRITE(TV_CSC_U, (color_conversion->ru << 16) |
1121                            color_conversion->gu);
1122                 I915_WRITE(TV_CSC_U2, (color_conversion->bu << 16) |
1123                            color_conversion->au);
1124                 I915_WRITE(TV_CSC_V, (color_conversion->rv << 16) |
1125                            color_conversion->gv);
1126                 I915_WRITE(TV_CSC_V2, (color_conversion->bv << 16) |
1127                            color_conversion->av);
1128         }
1129
1130         if (IS_I965G(dev))
1131                 I915_WRITE(TV_CLR_KNOBS, 0x00404000);
1132         else
1133                 I915_WRITE(TV_CLR_KNOBS, 0x00606000);
1134
1135         if (video_levels)
1136                 I915_WRITE(TV_CLR_LEVEL,
1137                            ((video_levels->black << TV_BLACK_LEVEL_SHIFT) |
1138                             (video_levels->blank << TV_BLANK_LEVEL_SHIFT)));
1139         {
1140                 int pipeconf_reg = (intel_crtc->pipe == 0) ?
1141                         PIPEACONF : PIPEBCONF;
1142                 int dspcntr_reg = (intel_crtc->plane == 0) ?
1143                         DSPACNTR : DSPBCNTR;
1144                 int pipeconf = I915_READ(pipeconf_reg);
1145                 int dspcntr = I915_READ(dspcntr_reg);
1146                 int dspbase_reg = (intel_crtc->plane == 0) ?
1147                         DSPAADDR : DSPBADDR;
1148                 int xpos = 0x0, ypos = 0x0;
1149                 unsigned int xsize, ysize;
1150                 /* Pipe must be off here */
1151                 I915_WRITE(dspcntr_reg, dspcntr & ~DISPLAY_PLANE_ENABLE);
1152                 /* Flush the plane changes */
1153                 I915_WRITE(dspbase_reg, I915_READ(dspbase_reg));
1154
1155                 /* Wait for vblank for the disable to take effect */
1156                 if (!IS_I9XX(dev))
1157                         intel_wait_for_vblank(dev);
1158
1159                 I915_WRITE(pipeconf_reg, pipeconf & ~PIPEACONF_ENABLE);
1160                 /* Wait for vblank for the disable to take effect. */
1161                 intel_wait_for_vblank(dev);
1162
1163                 /* Filter ctl must be set before TV_WIN_SIZE */
1164                 I915_WRITE(TV_FILTER_CTL_1, TV_AUTO_SCALE);
1165                 xsize = tv_mode->hblank_start - tv_mode->hblank_end;
1166                 if (tv_mode->progressive)
1167                         ysize = tv_mode->nbr_end + 1;
1168                 else
1169                         ysize = 2*tv_mode->nbr_end + 1;
1170
1171                 xpos += tv_priv->margin[TV_MARGIN_LEFT];
1172                 ypos += tv_priv->margin[TV_MARGIN_TOP];
1173                 xsize -= (tv_priv->margin[TV_MARGIN_LEFT] +
1174                           tv_priv->margin[TV_MARGIN_RIGHT]);
1175                 ysize -= (tv_priv->margin[TV_MARGIN_TOP] +
1176                           tv_priv->margin[TV_MARGIN_BOTTOM]);
1177                 I915_WRITE(TV_WIN_POS, (xpos<<16)|ypos);
1178                 I915_WRITE(TV_WIN_SIZE, (xsize<<16)|ysize);
1179
1180                 I915_WRITE(pipeconf_reg, pipeconf);
1181                 I915_WRITE(dspcntr_reg, dspcntr);
1182                 /* Flush the plane changes */
1183                 I915_WRITE(dspbase_reg, I915_READ(dspbase_reg));
1184         }
1185
1186         j = 0;
1187         for (i = 0; i < 60; i++)
1188                 I915_WRITE(TV_H_LUMA_0 + (i<<2), tv_mode->filter_table[j++]);
1189         for (i = 0; i < 60; i++)
1190                 I915_WRITE(TV_H_CHROMA_0 + (i<<2), tv_mode->filter_table[j++]);
1191         for (i = 0; i < 43; i++)
1192                 I915_WRITE(TV_V_LUMA_0 + (i<<2), tv_mode->filter_table[j++]);
1193         for (i = 0; i < 43; i++)
1194                 I915_WRITE(TV_V_CHROMA_0 + (i<<2), tv_mode->filter_table[j++]);
1195         I915_WRITE(TV_DAC, 0);
1196         I915_WRITE(TV_CTL, tv_ctl);
1197 }
1198
1199 static const struct drm_display_mode reported_modes[] = {
1200         {
1201                 .name = "NTSC 480i",
1202                 .clock = 107520,
1203                 .hdisplay = 1280,
1204                 .hsync_start = 1368,
1205                 .hsync_end = 1496,
1206                 .htotal = 1712,
1207
1208                 .vdisplay = 1024,
1209                 .vsync_start = 1027,
1210                 .vsync_end = 1034,
1211                 .vtotal = 1104,
1212                 .type = DRM_MODE_TYPE_DRIVER,
1213         },
1214 };
1215
1216 /**
1217  * Detects TV presence by checking for load.
1218  *
1219  * Requires that the current pipe's DPLL is active.
1220
1221  * \return true if TV is connected.
1222  * \return false if TV is disconnected.
1223  */
1224 static int
1225 intel_tv_detect_type (struct drm_crtc *crtc, struct intel_encoder *intel_encoder)
1226 {
1227         struct drm_encoder *encoder = &intel_encoder->enc;
1228         struct drm_device *dev = encoder->dev;
1229         struct drm_i915_private *dev_priv = dev->dev_private;
1230         unsigned long irqflags;
1231         u32 tv_ctl, save_tv_ctl;
1232         u32 tv_dac, save_tv_dac;
1233         int type = DRM_MODE_CONNECTOR_Unknown;
1234
1235         tv_dac = I915_READ(TV_DAC);
1236
1237         /* Disable TV interrupts around load detect or we'll recurse */
1238         spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags);
1239         i915_disable_pipestat(dev_priv, 0, PIPE_HOTPLUG_INTERRUPT_ENABLE |
1240                               PIPE_HOTPLUG_TV_INTERRUPT_ENABLE);
1241         spin_unlock_irqrestore(&dev_priv->user_irq_lock, irqflags);
1242
1243         /*
1244          * Detect TV by polling)
1245          */
1246         save_tv_dac = tv_dac;
1247         tv_ctl = I915_READ(TV_CTL);
1248         save_tv_ctl = tv_ctl;
1249         tv_ctl &= ~TV_ENC_ENABLE;
1250         tv_ctl &= ~TV_TEST_MODE_MASK;
1251         tv_ctl |= TV_TEST_MODE_MONITOR_DETECT;
1252         tv_dac &= ~TVDAC_SENSE_MASK;
1253         tv_dac &= ~DAC_A_MASK;
1254         tv_dac &= ~DAC_B_MASK;
1255         tv_dac &= ~DAC_C_MASK;
1256         tv_dac |= (TVDAC_STATE_CHG_EN |
1257                    TVDAC_A_SENSE_CTL |
1258                    TVDAC_B_SENSE_CTL |
1259                    TVDAC_C_SENSE_CTL |
1260                    DAC_CTL_OVERRIDE |
1261                    DAC_A_0_7_V |
1262                    DAC_B_0_7_V |
1263                    DAC_C_0_7_V);
1264         I915_WRITE(TV_CTL, tv_ctl);
1265         I915_WRITE(TV_DAC, tv_dac);
1266         intel_wait_for_vblank(dev);
1267         tv_dac = I915_READ(TV_DAC);
1268         I915_WRITE(TV_DAC, save_tv_dac);
1269         I915_WRITE(TV_CTL, save_tv_ctl);
1270         intel_wait_for_vblank(dev);
1271         /*
1272          *  A B C
1273          *  0 1 1 Composite
1274          *  1 0 X svideo
1275          *  0 0 0 Component
1276          */
1277         if ((tv_dac & TVDAC_SENSE_MASK) == (TVDAC_B_SENSE | TVDAC_C_SENSE)) {
1278                 DRM_DEBUG_KMS("Detected Composite TV connection\n");
1279                 type = DRM_MODE_CONNECTOR_Composite;
1280         } else if ((tv_dac & (TVDAC_A_SENSE|TVDAC_B_SENSE)) == TVDAC_A_SENSE) {
1281                 DRM_DEBUG_KMS("Detected S-Video TV connection\n");
1282                 type = DRM_MODE_CONNECTOR_SVIDEO;
1283         } else if ((tv_dac & TVDAC_SENSE_MASK) == 0) {
1284                 DRM_DEBUG_KMS("Detected Component TV connection\n");
1285                 type = DRM_MODE_CONNECTOR_Component;
1286         } else {
1287                 DRM_DEBUG_KMS("No TV connection detected\n");
1288                 type = -1;
1289         }
1290
1291         /* Restore interrupt config */
1292         spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags);
1293         i915_enable_pipestat(dev_priv, 0, PIPE_HOTPLUG_INTERRUPT_ENABLE |
1294                              PIPE_HOTPLUG_TV_INTERRUPT_ENABLE);
1295         spin_unlock_irqrestore(&dev_priv->user_irq_lock, irqflags);
1296
1297         return type;
1298 }
1299
1300 /*
1301  * Here we set accurate tv format according to connector type
1302  * i.e Component TV should not be assigned by NTSC or PAL
1303  */
1304 static void intel_tv_find_better_format(struct drm_connector *connector)
1305 {
1306         struct drm_encoder *encoder = intel_attached_encoder(connector);
1307         struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
1308         struct intel_tv_priv *tv_priv = intel_encoder->dev_priv;
1309         const struct tv_mode *tv_mode = intel_tv_mode_find(intel_encoder);
1310         int i;
1311
1312         if ((tv_priv->type == DRM_MODE_CONNECTOR_Component) ==
1313                 tv_mode->component_only)
1314                 return;
1315
1316
1317         for (i = 0; i < sizeof(tv_modes) / sizeof(*tv_modes); i++) {
1318                 tv_mode = tv_modes + i;
1319
1320                 if ((tv_priv->type == DRM_MODE_CONNECTOR_Component) ==
1321                         tv_mode->component_only)
1322                         break;
1323         }
1324
1325         tv_priv->tv_format = tv_mode->name;
1326         drm_connector_property_set_value(connector,
1327                 connector->dev->mode_config.tv_mode_property, i);
1328 }
1329
1330 /**
1331  * Detect the TV connection.
1332  *
1333  * Currently this always returns CONNECTOR_STATUS_UNKNOWN, as we need to be sure
1334  * we have a pipe programmed in order to probe the TV.
1335  */
1336 static enum drm_connector_status
1337 intel_tv_detect(struct drm_connector *connector)
1338 {
1339         struct drm_crtc *crtc;
1340         struct drm_display_mode mode;
1341         struct drm_encoder *encoder = intel_attached_encoder(connector);
1342         struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
1343         struct intel_tv_priv *tv_priv = intel_encoder->dev_priv;
1344         int dpms_mode;
1345         int type = tv_priv->type;
1346
1347         mode = reported_modes[0];
1348         drm_mode_set_crtcinfo(&mode, CRTC_INTERLACE_HALVE_V);
1349
1350         if (encoder->crtc && encoder->crtc->enabled) {
1351                 type = intel_tv_detect_type(encoder->crtc, intel_encoder);
1352         } else {
1353                 crtc = intel_get_load_detect_pipe(intel_encoder, connector,
1354                                                   &mode, &dpms_mode);
1355                 if (crtc) {
1356                         type = intel_tv_detect_type(crtc, intel_encoder);
1357                         intel_release_load_detect_pipe(intel_encoder, connector,
1358                                                        dpms_mode);
1359                 } else
1360                         type = -1;
1361         }
1362
1363         tv_priv->type = type;
1364
1365         if (type < 0)
1366                 return connector_status_disconnected;
1367
1368         intel_tv_find_better_format(connector);
1369         return connector_status_connected;
1370 }
1371
1372 static struct input_res {
1373         char *name;
1374         int w, h;
1375 } input_res_table[] =
1376 {
1377         {"640x480", 640, 480},
1378         {"800x600", 800, 600},
1379         {"1024x768", 1024, 768},
1380         {"1280x1024", 1280, 1024},
1381         {"848x480", 848, 480},
1382         {"1280x720", 1280, 720},
1383         {"1920x1080", 1920, 1080},
1384 };
1385
1386 /*
1387  * Chose preferred mode  according to line number of TV format
1388  */
1389 static void
1390 intel_tv_chose_preferred_modes(struct drm_connector *connector,
1391                                struct drm_display_mode *mode_ptr)
1392 {
1393         struct drm_encoder *encoder = intel_attached_encoder(connector);
1394         struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
1395         const struct tv_mode *tv_mode = intel_tv_mode_find(intel_encoder);
1396
1397         if (tv_mode->nbr_end < 480 && mode_ptr->vdisplay == 480)
1398                 mode_ptr->type |= DRM_MODE_TYPE_PREFERRED;
1399         else if (tv_mode->nbr_end > 480) {
1400                 if (tv_mode->progressive == true && tv_mode->nbr_end < 720) {
1401                         if (mode_ptr->vdisplay == 720)
1402                                 mode_ptr->type |= DRM_MODE_TYPE_PREFERRED;
1403                 } else if (mode_ptr->vdisplay == 1080)
1404                                 mode_ptr->type |= DRM_MODE_TYPE_PREFERRED;
1405         }
1406 }
1407
1408 /**
1409  * Stub get_modes function.
1410  *
1411  * This should probably return a set of fixed modes, unless we can figure out
1412  * how to probe modes off of TV connections.
1413  */
1414
1415 static int
1416 intel_tv_get_modes(struct drm_connector *connector)
1417 {
1418         struct drm_display_mode *mode_ptr;
1419         struct drm_encoder *encoder = intel_attached_encoder(connector);
1420         struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
1421         const struct tv_mode *tv_mode = intel_tv_mode_find(intel_encoder);
1422         int j, count = 0;
1423         u64 tmp;
1424
1425         for (j = 0; j < ARRAY_SIZE(input_res_table);
1426              j++) {
1427                 struct input_res *input = &input_res_table[j];
1428                 unsigned int hactive_s = input->w;
1429                 unsigned int vactive_s = input->h;
1430
1431                 if (tv_mode->max_srcw && input->w > tv_mode->max_srcw)
1432                         continue;
1433
1434                 if (input->w > 1024 && (!tv_mode->progressive
1435                                         && !tv_mode->component_only))
1436                         continue;
1437
1438                 mode_ptr = drm_mode_create(connector->dev);
1439                 if (!mode_ptr)
1440                         continue;
1441                 strncpy(mode_ptr->name, input->name, DRM_DISPLAY_MODE_LEN);
1442
1443                 mode_ptr->hdisplay = hactive_s;
1444                 mode_ptr->hsync_start = hactive_s + 1;
1445                 mode_ptr->hsync_end = hactive_s + 64;
1446                 if (mode_ptr->hsync_end <= mode_ptr->hsync_start)
1447                         mode_ptr->hsync_end = mode_ptr->hsync_start + 1;
1448                 mode_ptr->htotal = hactive_s + 96;
1449
1450                 mode_ptr->vdisplay = vactive_s;
1451                 mode_ptr->vsync_start = vactive_s + 1;
1452                 mode_ptr->vsync_end = vactive_s + 32;
1453                 if (mode_ptr->vsync_end <= mode_ptr->vsync_start)
1454                         mode_ptr->vsync_end = mode_ptr->vsync_start  + 1;
1455                 mode_ptr->vtotal = vactive_s + 33;
1456
1457                 tmp = (u64) tv_mode->refresh * mode_ptr->vtotal;
1458                 tmp *= mode_ptr->htotal;
1459                 tmp = div_u64(tmp, 1000000);
1460                 mode_ptr->clock = (int) tmp;
1461
1462                 mode_ptr->type = DRM_MODE_TYPE_DRIVER;
1463                 intel_tv_chose_preferred_modes(connector, mode_ptr);
1464                 drm_mode_probed_add(connector, mode_ptr);
1465                 count++;
1466         }
1467
1468         return count;
1469 }
1470
1471 static void
1472 intel_tv_destroy (struct drm_connector *connector)
1473 {
1474         drm_sysfs_connector_remove(connector);
1475         drm_connector_cleanup(connector);
1476         kfree(connector);
1477 }
1478
1479
1480 static int
1481 intel_tv_set_property(struct drm_connector *connector, struct drm_property *property,
1482                       uint64_t val)
1483 {
1484         struct drm_device *dev = connector->dev;
1485         struct drm_encoder *encoder = intel_attached_encoder(connector);
1486         struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
1487         struct intel_tv_priv *tv_priv = intel_encoder->dev_priv;
1488         struct drm_crtc *crtc = encoder->crtc;
1489         int ret = 0;
1490         bool changed = false;
1491
1492         ret = drm_connector_property_set_value(connector, property, val);
1493         if (ret < 0)
1494                 goto out;
1495
1496         if (property == dev->mode_config.tv_left_margin_property &&
1497                 tv_priv->margin[TV_MARGIN_LEFT] != val) {
1498                 tv_priv->margin[TV_MARGIN_LEFT] = val;
1499                 changed = true;
1500         } else if (property == dev->mode_config.tv_right_margin_property &&
1501                 tv_priv->margin[TV_MARGIN_RIGHT] != val) {
1502                 tv_priv->margin[TV_MARGIN_RIGHT] = val;
1503                 changed = true;
1504         } else if (property == dev->mode_config.tv_top_margin_property &&
1505                 tv_priv->margin[TV_MARGIN_TOP] != val) {
1506                 tv_priv->margin[TV_MARGIN_TOP] = val;
1507                 changed = true;
1508         } else if (property == dev->mode_config.tv_bottom_margin_property &&
1509                 tv_priv->margin[TV_MARGIN_BOTTOM] != val) {
1510                 tv_priv->margin[TV_MARGIN_BOTTOM] = val;
1511                 changed = true;
1512         } else if (property == dev->mode_config.tv_mode_property) {
1513                 if (val >= ARRAY_SIZE(tv_modes)) {
1514                         ret = -EINVAL;
1515                         goto out;
1516                 }
1517                 if (!strcmp(tv_priv->tv_format, tv_modes[val].name))
1518                         goto out;
1519
1520                 tv_priv->tv_format = tv_modes[val].name;
1521                 changed = true;
1522         } else {
1523                 ret = -EINVAL;
1524                 goto out;
1525         }
1526
1527         if (changed && crtc)
1528                 drm_crtc_helper_set_mode(crtc, &crtc->mode, crtc->x,
1529                                 crtc->y, crtc->fb);
1530 out:
1531         return ret;
1532 }
1533
1534 static const struct drm_encoder_helper_funcs intel_tv_helper_funcs = {
1535         .dpms = intel_tv_dpms,
1536         .mode_fixup = intel_tv_mode_fixup,
1537         .prepare = intel_encoder_prepare,
1538         .mode_set = intel_tv_mode_set,
1539         .commit = intel_encoder_commit,
1540 };
1541
1542 static const struct drm_connector_funcs intel_tv_connector_funcs = {
1543         .dpms = drm_helper_connector_dpms,
1544         .detect = intel_tv_detect,
1545         .destroy = intel_tv_destroy,
1546         .set_property = intel_tv_set_property,
1547         .fill_modes = drm_helper_probe_single_connector_modes,
1548 };
1549
1550 static const struct drm_connector_helper_funcs intel_tv_connector_helper_funcs = {
1551         .mode_valid = intel_tv_mode_valid,
1552         .get_modes = intel_tv_get_modes,
1553         .best_encoder = intel_attached_encoder,
1554 };
1555
1556 static void intel_tv_enc_destroy(struct drm_encoder *encoder)
1557 {
1558         struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
1559
1560         drm_encoder_cleanup(encoder);
1561         kfree(intel_encoder);
1562 }
1563
1564 static const struct drm_encoder_funcs intel_tv_enc_funcs = {
1565         .destroy = intel_tv_enc_destroy,
1566 };
1567
1568 /*
1569  * Enumerate the child dev array parsed from VBT to check whether
1570  * the integrated TV is present.
1571  * If it is present, return 1.
1572  * If it is not present, return false.
1573  * If no child dev is parsed from VBT, it assumes that the TV is present.
1574  */
1575 static int tv_is_present_in_vbt(struct drm_device *dev)
1576 {
1577         struct drm_i915_private *dev_priv = dev->dev_private;
1578         struct child_device_config *p_child;
1579         int i, ret;
1580
1581         if (!dev_priv->child_dev_num)
1582                 return 1;
1583
1584         ret = 0;
1585         for (i = 0; i < dev_priv->child_dev_num; i++) {
1586                 p_child = dev_priv->child_dev + i;
1587                 /*
1588                  * If the device type is not TV, continue.
1589                  */
1590                 if (p_child->device_type != DEVICE_TYPE_INT_TV &&
1591                         p_child->device_type != DEVICE_TYPE_TV)
1592                         continue;
1593                 /* Only when the addin_offset is non-zero, it is regarded
1594                  * as present.
1595                  */
1596                 if (p_child->addin_offset) {
1597                         ret = 1;
1598                         break;
1599                 }
1600         }
1601         return ret;
1602 }
1603
1604 void
1605 intel_tv_init(struct drm_device *dev)
1606 {
1607         struct drm_i915_private *dev_priv = dev->dev_private;
1608         struct drm_connector *connector;
1609         struct intel_encoder *intel_encoder;
1610         struct intel_connector *intel_connector;
1611         struct intel_tv_priv *tv_priv;
1612         u32 tv_dac_on, tv_dac_off, save_tv_dac;
1613         char **tv_format_names;
1614         int i, initial_mode = 0;
1615
1616         if ((I915_READ(TV_CTL) & TV_FUSE_STATE_MASK) == TV_FUSE_STATE_DISABLED)
1617                 return;
1618
1619         if (!tv_is_present_in_vbt(dev)) {
1620                 DRM_DEBUG_KMS("Integrated TV is not present.\n");
1621                 return;
1622         }
1623         /* Even if we have an encoder we may not have a connector */
1624         if (!dev_priv->int_tv_support)
1625                 return;
1626
1627         /*
1628          * Sanity check the TV output by checking to see if the
1629          * DAC register holds a value
1630          */
1631         save_tv_dac = I915_READ(TV_DAC);
1632
1633         I915_WRITE(TV_DAC, save_tv_dac | TVDAC_STATE_CHG_EN);
1634         tv_dac_on = I915_READ(TV_DAC);
1635
1636         I915_WRITE(TV_DAC, save_tv_dac & ~TVDAC_STATE_CHG_EN);
1637         tv_dac_off = I915_READ(TV_DAC);
1638
1639         I915_WRITE(TV_DAC, save_tv_dac);
1640
1641         /*
1642          * If the register does not hold the state change enable
1643          * bit, (either as a 0 or a 1), assume it doesn't really
1644          * exist
1645          */
1646         if ((tv_dac_on & TVDAC_STATE_CHG_EN) == 0 ||
1647             (tv_dac_off & TVDAC_STATE_CHG_EN) != 0)
1648                 return;
1649
1650         intel_encoder = kzalloc(sizeof(struct intel_encoder) +
1651                                sizeof(struct intel_tv_priv), GFP_KERNEL);
1652         if (!intel_encoder) {
1653                 return;
1654         }
1655
1656         intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL);
1657         if (!intel_connector) {
1658                 kfree(intel_encoder);
1659                 return;
1660         }
1661
1662         connector = &intel_connector->base;
1663
1664         drm_connector_init(dev, connector, &intel_tv_connector_funcs,
1665                            DRM_MODE_CONNECTOR_SVIDEO);
1666
1667         drm_encoder_init(dev, &intel_encoder->enc, &intel_tv_enc_funcs,
1668                          DRM_MODE_ENCODER_TVDAC);
1669
1670         drm_mode_connector_attach_encoder(&intel_connector->base, &intel_encoder->enc);
1671         tv_priv = (struct intel_tv_priv *)(intel_encoder + 1);
1672         intel_encoder->type = INTEL_OUTPUT_TVOUT;
1673         intel_encoder->crtc_mask = (1 << 0) | (1 << 1);
1674         intel_encoder->clone_mask = (1 << INTEL_TV_CLONE_BIT);
1675         intel_encoder->enc.possible_crtcs = ((1 << 0) | (1 << 1));
1676         intel_encoder->enc.possible_clones = (1 << INTEL_OUTPUT_TVOUT);
1677         intel_encoder->dev_priv = tv_priv;
1678         tv_priv->type = DRM_MODE_CONNECTOR_Unknown;
1679
1680         /* BIOS margin values */
1681         tv_priv->margin[TV_MARGIN_LEFT] = 54;
1682         tv_priv->margin[TV_MARGIN_TOP] = 36;
1683         tv_priv->margin[TV_MARGIN_RIGHT] = 46;
1684         tv_priv->margin[TV_MARGIN_BOTTOM] = 37;
1685
1686         tv_priv->tv_format = kstrdup(tv_modes[initial_mode].name, GFP_KERNEL);
1687
1688         drm_encoder_helper_add(&intel_encoder->enc, &intel_tv_helper_funcs);
1689         drm_connector_helper_add(connector, &intel_tv_connector_helper_funcs);
1690         connector->interlace_allowed = false;
1691         connector->doublescan_allowed = false;
1692
1693         /* Create TV properties then attach current values */
1694         tv_format_names = kmalloc(sizeof(char *) * ARRAY_SIZE(tv_modes),
1695                                   GFP_KERNEL);
1696         if (!tv_format_names)
1697                 goto out;
1698         for (i = 0; i < ARRAY_SIZE(tv_modes); i++)
1699                 tv_format_names[i] = tv_modes[i].name;
1700         drm_mode_create_tv_properties(dev, ARRAY_SIZE(tv_modes), tv_format_names);
1701
1702         drm_connector_attach_property(connector, dev->mode_config.tv_mode_property,
1703                                    initial_mode);
1704         drm_connector_attach_property(connector,
1705                                    dev->mode_config.tv_left_margin_property,
1706                                    tv_priv->margin[TV_MARGIN_LEFT]);
1707         drm_connector_attach_property(connector,
1708                                    dev->mode_config.tv_top_margin_property,
1709                                    tv_priv->margin[TV_MARGIN_TOP]);
1710         drm_connector_attach_property(connector,
1711                                    dev->mode_config.tv_right_margin_property,
1712                                    tv_priv->margin[TV_MARGIN_RIGHT]);
1713         drm_connector_attach_property(connector,
1714                                    dev->mode_config.tv_bottom_margin_property,
1715                                    tv_priv->margin[TV_MARGIN_BOTTOM]);
1716 out:
1717         drm_sysfs_connector_add(connector);
1718 }