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