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