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