1/* $NetBSD: intel_tv.c,v 1.3 2021/12/19 11:49:11 riastradh Exp $ */ 2 3/* 4 * Copyright �� 2006-2008 Intel Corporation 5 * Jesse Barnes <jesse.barnes@intel.com> 6 * 7 * Permission is hereby granted, free of charge, to any person obtaining a 8 * copy of this software and associated documentation files (the "Software"), 9 * to deal in the Software without restriction, including without limitation 10 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 11 * and/or sell copies of the Software, and to permit persons to whom the 12 * Software is furnished to do so, subject to the following conditions: 13 * 14 * The above copyright notice and this permission notice (including the next 15 * paragraph) shall be included in all copies or substantial portions of the 16 * Software. 17 * 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 23 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 24 * DEALINGS IN THE SOFTWARE. 25 * 26 * Authors: 27 * Eric Anholt <eric@anholt.net> 28 * 29 */ 30 31/** @file 32 * Integrated TV-out support for the 915GM and 945GM. 33 */ 34 35#include <sys/cdefs.h> 36__KERNEL_RCSID(0, "$NetBSD: intel_tv.c,v 1.3 2021/12/19 11:49:11 riastradh Exp $"); 37 38#include <drm/drm_atomic_helper.h> 39#include <drm/drm_crtc.h> 40#include <drm/drm_edid.h> 41#include <drm/i915_drm.h> 42 43#include "i915_drv.h" 44#include "intel_connector.h" 45#include "intel_display_types.h" 46#include "intel_hotplug.h" 47#include "intel_tv.h" 48 49enum tv_margin { 50 TV_MARGIN_LEFT, TV_MARGIN_TOP, 51 TV_MARGIN_RIGHT, TV_MARGIN_BOTTOM 52}; 53 54struct intel_tv { 55 struct intel_encoder base; 56 57 int type; 58}; 59 60struct video_levels { 61 u16 blank, black; 62 u8 burst; 63}; 64 65struct color_conversion { 66 u16 ry, gy, by, ay; 67 u16 ru, gu, bu, au; 68 u16 rv, gv, bv, av; 69}; 70 71static const u32 filter_table[] = { 72 0xB1403000, 0x2E203500, 0x35002E20, 0x3000B140, 73 0x35A0B160, 0x2DC02E80, 0xB1403480, 0xB1603000, 74 0x2EA03640, 0x34002D80, 0x3000B120, 0x36E0B160, 75 0x2D202EF0, 0xB1203380, 0xB1603000, 0x2F303780, 76 0x33002CC0, 0x3000B100, 0x3820B160, 0x2C802F50, 77 0xB10032A0, 0xB1603000, 0x2F9038C0, 0x32202C20, 78 0x3000B0E0, 0x3980B160, 0x2BC02FC0, 0xB0E031C0, 79 0xB1603000, 0x2FF03A20, 0x31602B60, 0xB020B0C0, 80 0x3AE0B160, 0x2B001810, 0xB0C03120, 0xB140B020, 81 0x18283BA0, 0x30C02A80, 0xB020B0A0, 0x3C60B140, 82 0x2A201838, 0xB0A03080, 0xB120B020, 0x18383D20, 83 0x304029C0, 0xB040B080, 0x3DE0B100, 0x29601848, 84 0xB0803000, 0xB100B040, 0x18483EC0, 0xB0402900, 85 0xB040B060, 0x3F80B0C0, 0x28801858, 0xB060B080, 86 0xB0A0B060, 0x18602820, 0xB0A02820, 0x0000B060, 87 0xB1403000, 0x2E203500, 0x35002E20, 0x3000B140, 88 0x35A0B160, 0x2DC02E80, 0xB1403480, 0xB1603000, 89 0x2EA03640, 0x34002D80, 0x3000B120, 0x36E0B160, 90 0x2D202EF0, 0xB1203380, 0xB1603000, 0x2F303780, 91 0x33002CC0, 0x3000B100, 0x3820B160, 0x2C802F50, 92 0xB10032A0, 0xB1603000, 0x2F9038C0, 0x32202C20, 93 0x3000B0E0, 0x3980B160, 0x2BC02FC0, 0xB0E031C0, 94 0xB1603000, 0x2FF03A20, 0x31602B60, 0xB020B0C0, 95 0x3AE0B160, 0x2B001810, 0xB0C03120, 0xB140B020, 96 0x18283BA0, 0x30C02A80, 0xB020B0A0, 0x3C60B140, 97 0x2A201838, 0xB0A03080, 0xB120B020, 0x18383D20, 98 0x304029C0, 0xB040B080, 0x3DE0B100, 0x29601848, 99 0xB0803000, 0xB100B040, 0x18483EC0, 0xB0402900, 100 0xB040B060, 0x3F80B0C0, 0x28801858, 0xB060B080, 101 0xB0A0B060, 0x18602820, 0xB0A02820, 0x0000B060, 102 0x36403000, 0x2D002CC0, 0x30003640, 0x2D0036C0, 103 0x35C02CC0, 0x37403000, 0x2C802D40, 0x30003540, 104 0x2D8037C0, 0x34C02C40, 0x38403000, 0x2BC02E00, 105 0x30003440, 0x2E2038C0, 0x34002B80, 0x39803000, 106 0x2B402E40, 0x30003380, 0x2E603A00, 0x33402B00, 107 0x3A803040, 0x2A802EA0, 0x30403300, 0x2EC03B40, 108 0x32802A40, 0x3C003040, 0x2A002EC0, 0x30803240, 109 0x2EC03C80, 0x320029C0, 0x3D403080, 0x29402F00, 110 0x308031C0, 0x2F203DC0, 0x31802900, 0x3E8030C0, 111 0x28802F40, 0x30C03140, 0x2F203F40, 0x31402840, 112 0x28003100, 0x28002F00, 0x00003100, 0x36403000, 113 0x2D002CC0, 0x30003640, 0x2D0036C0, 114 0x35C02CC0, 0x37403000, 0x2C802D40, 0x30003540, 115 0x2D8037C0, 0x34C02C40, 0x38403000, 0x2BC02E00, 116 0x30003440, 0x2E2038C0, 0x34002B80, 0x39803000, 117 0x2B402E40, 0x30003380, 0x2E603A00, 0x33402B00, 118 0x3A803040, 0x2A802EA0, 0x30403300, 0x2EC03B40, 119 0x32802A40, 0x3C003040, 0x2A002EC0, 0x30803240, 120 0x2EC03C80, 0x320029C0, 0x3D403080, 0x29402F00, 121 0x308031C0, 0x2F203DC0, 0x31802900, 0x3E8030C0, 122 0x28802F40, 0x30C03140, 0x2F203F40, 0x31402840, 123 0x28003100, 0x28002F00, 0x00003100, 124}; 125 126/* 127 * Color conversion values have 3 separate fixed point formats: 128 * 129 * 10 bit fields (ay, au) 130 * 1.9 fixed point (b.bbbbbbbbb) 131 * 11 bit fields (ry, by, ru, gu, gv) 132 * exp.mantissa (ee.mmmmmmmmm) 133 * ee = 00 = 10^-1 (0.mmmmmmmmm) 134 * ee = 01 = 10^-2 (0.0mmmmmmmmm) 135 * ee = 10 = 10^-3 (0.00mmmmmmmmm) 136 * ee = 11 = 10^-4 (0.000mmmmmmmmm) 137 * 12 bit fields (gy, rv, bu) 138 * exp.mantissa (eee.mmmmmmmmm) 139 * eee = 000 = 10^-1 (0.mmmmmmmmm) 140 * eee = 001 = 10^-2 (0.0mmmmmmmmm) 141 * eee = 010 = 10^-3 (0.00mmmmmmmmm) 142 * eee = 011 = 10^-4 (0.000mmmmmmmmm) 143 * eee = 100 = reserved 144 * eee = 101 = reserved 145 * eee = 110 = reserved 146 * eee = 111 = 10^0 (m.mmmmmmmm) (only usable for 1.0 representation) 147 * 148 * Saturation and contrast are 8 bits, with their own representation: 149 * 8 bit field (saturation, contrast) 150 * exp.mantissa (ee.mmmmmm) 151 * ee = 00 = 10^-1 (0.mmmmmm) 152 * ee = 01 = 10^0 (m.mmmmm) 153 * ee = 10 = 10^1 (mm.mmmm) 154 * ee = 11 = 10^2 (mmm.mmm) 155 * 156 * Simple conversion function: 157 * 158 * static u32 159 * float_to_csc_11(float f) 160 * { 161 * u32 exp; 162 * u32 mant; 163 * u32 ret; 164 * 165 * if (f < 0) 166 * f = -f; 167 * 168 * if (f >= 1) { 169 * exp = 0x7; 170 * mant = 1 << 8; 171 * } else { 172 * for (exp = 0; exp < 3 && f < 0.5; exp++) 173 * f *= 2.0; 174 * mant = (f * (1 << 9) + 0.5); 175 * if (mant >= (1 << 9)) 176 * mant = (1 << 9) - 1; 177 * } 178 * ret = (exp << 9) | mant; 179 * return ret; 180 * } 181 */ 182 183/* 184 * Behold, magic numbers! If we plant them they might grow a big 185 * s-video cable to the sky... or something. 186 * 187 * Pre-converted to appropriate hex value. 188 */ 189 190/* 191 * PAL & NTSC values for composite & s-video connections 192 */ 193static const struct color_conversion ntsc_m_csc_composite = { 194 .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0104, 195 .ru = 0x0733, .gu = 0x052d, .bu = 0x05c7, .au = 0x0200, 196 .rv = 0x0340, .gv = 0x030c, .bv = 0x06d0, .av = 0x0200, 197}; 198 199static const struct video_levels ntsc_m_levels_composite = { 200 .blank = 225, .black = 267, .burst = 113, 201}; 202 203static const struct color_conversion ntsc_m_csc_svideo = { 204 .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0133, 205 .ru = 0x076a, .gu = 0x0564, .bu = 0x030d, .au = 0x0200, 206 .rv = 0x037a, .gv = 0x033d, .bv = 0x06f6, .av = 0x0200, 207}; 208 209static const struct video_levels ntsc_m_levels_svideo = { 210 .blank = 266, .black = 316, .burst = 133, 211}; 212 213static const struct color_conversion ntsc_j_csc_composite = { 214 .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0119, 215 .ru = 0x074c, .gu = 0x0546, .bu = 0x05ec, .au = 0x0200, 216 .rv = 0x035a, .gv = 0x0322, .bv = 0x06e1, .av = 0x0200, 217}; 218 219static const struct video_levels ntsc_j_levels_composite = { 220 .blank = 225, .black = 225, .burst = 113, 221}; 222 223static const struct color_conversion ntsc_j_csc_svideo = { 224 .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x014c, 225 .ru = 0x0788, .gu = 0x0581, .bu = 0x0322, .au = 0x0200, 226 .rv = 0x0399, .gv = 0x0356, .bv = 0x070a, .av = 0x0200, 227}; 228 229static const struct video_levels ntsc_j_levels_svideo = { 230 .blank = 266, .black = 266, .burst = 133, 231}; 232 233static const struct color_conversion pal_csc_composite = { 234 .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0113, 235 .ru = 0x0745, .gu = 0x053f, .bu = 0x05e1, .au = 0x0200, 236 .rv = 0x0353, .gv = 0x031c, .bv = 0x06dc, .av = 0x0200, 237}; 238 239static const struct video_levels pal_levels_composite = { 240 .blank = 237, .black = 237, .burst = 118, 241}; 242 243static const struct color_conversion pal_csc_svideo = { 244 .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0145, 245 .ru = 0x0780, .gu = 0x0579, .bu = 0x031c, .au = 0x0200, 246 .rv = 0x0390, .gv = 0x034f, .bv = 0x0705, .av = 0x0200, 247}; 248 249static const struct video_levels pal_levels_svideo = { 250 .blank = 280, .black = 280, .burst = 139, 251}; 252 253static const struct color_conversion pal_m_csc_composite = { 254 .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0104, 255 .ru = 0x0733, .gu = 0x052d, .bu = 0x05c7, .au = 0x0200, 256 .rv = 0x0340, .gv = 0x030c, .bv = 0x06d0, .av = 0x0200, 257}; 258 259static const struct video_levels pal_m_levels_composite = { 260 .blank = 225, .black = 267, .burst = 113, 261}; 262 263static const struct color_conversion pal_m_csc_svideo = { 264 .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0133, 265 .ru = 0x076a, .gu = 0x0564, .bu = 0x030d, .au = 0x0200, 266 .rv = 0x037a, .gv = 0x033d, .bv = 0x06f6, .av = 0x0200, 267}; 268 269static const struct video_levels pal_m_levels_svideo = { 270 .blank = 266, .black = 316, .burst = 133, 271}; 272 273static const struct color_conversion pal_n_csc_composite = { 274 .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0104, 275 .ru = 0x0733, .gu = 0x052d, .bu = 0x05c7, .au = 0x0200, 276 .rv = 0x0340, .gv = 0x030c, .bv = 0x06d0, .av = 0x0200, 277}; 278 279static const struct video_levels pal_n_levels_composite = { 280 .blank = 225, .black = 267, .burst = 118, 281}; 282 283static const struct color_conversion pal_n_csc_svideo = { 284 .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0133, 285 .ru = 0x076a, .gu = 0x0564, .bu = 0x030d, .au = 0x0200, 286 .rv = 0x037a, .gv = 0x033d, .bv = 0x06f6, .av = 0x0200, 287}; 288 289static const struct video_levels pal_n_levels_svideo = { 290 .blank = 266, .black = 316, .burst = 139, 291}; 292 293/* 294 * Component connections 295 */ 296static const struct color_conversion sdtv_csc_yprpb = { 297 .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0145, 298 .ru = 0x0559, .gu = 0x0353, .bu = 0x0100, .au = 0x0200, 299 .rv = 0x0100, .gv = 0x03ad, .bv = 0x074d, .av = 0x0200, 300}; 301 302static const struct color_conversion hdtv_csc_yprpb = { 303 .ry = 0x05b3, .gy = 0x016e, .by = 0x0728, .ay = 0x0145, 304 .ru = 0x07d5, .gu = 0x038b, .bu = 0x0100, .au = 0x0200, 305 .rv = 0x0100, .gv = 0x03d1, .bv = 0x06bc, .av = 0x0200, 306}; 307 308static const struct video_levels component_levels = { 309 .blank = 279, .black = 279, .burst = 0, 310}; 311 312 313struct tv_mode { 314 const char *name; 315 316 u32 clock; 317 u16 refresh; /* in millihertz (for precision) */ 318 u8 oversample; 319 u8 hsync_end; 320 u16 hblank_start, hblank_end, htotal; 321 bool progressive : 1, trilevel_sync : 1, component_only : 1; 322 u8 vsync_start_f1, vsync_start_f2, vsync_len; 323 bool veq_ena : 1; 324 u8 veq_start_f1, veq_start_f2, veq_len; 325 u8 vi_end_f1, vi_end_f2; 326 u16 nbr_end; 327 bool burst_ena : 1; 328 u8 hburst_start, hburst_len; 329 u8 vburst_start_f1; 330 u16 vburst_end_f1; 331 u8 vburst_start_f2; 332 u16 vburst_end_f2; 333 u8 vburst_start_f3; 334 u16 vburst_end_f3; 335 u8 vburst_start_f4; 336 u16 vburst_end_f4; 337 /* 338 * subcarrier programming 339 */ 340 u16 dda2_size, dda3_size; 341 u8 dda1_inc; 342 u16 dda2_inc, dda3_inc; 343 u32 sc_reset; 344 bool pal_burst : 1; 345 /* 346 * blank/black levels 347 */ 348 const struct video_levels *composite_levels, *svideo_levels; 349 const struct color_conversion *composite_color, *svideo_color; 350 const u32 *filter_table; 351}; 352 353 354/* 355 * Sub carrier DDA 356 * 357 * I think this works as follows: 358 * 359 * subcarrier freq = pixel_clock * (dda1_inc + dda2_inc / dda2_size) / 4096 360 * 361 * Presumably, when dda3 is added in, it gets to adjust the dda2_inc value 362 * 363 * So, 364 * dda1_ideal = subcarrier/pixel * 4096 365 * dda1_inc = floor (dda1_ideal) 366 * dda2 = dda1_ideal - dda1_inc 367 * 368 * then pick a ratio for dda2 that gives the closest approximation. If 369 * you can't get close enough, you can play with dda3 as well. This 370 * seems likely to happen when dda2 is small as the jumps would be larger 371 * 372 * To invert this, 373 * 374 * pixel_clock = subcarrier * 4096 / (dda1_inc + dda2_inc / dda2_size) 375 * 376 * The constants below were all computed using a 107.520MHz clock 377 */ 378 379/* 380 * Register programming values for TV modes. 381 * 382 * These values account for -1s required. 383 */ 384static const struct tv_mode tv_modes[] = { 385 { 386 .name = "NTSC-M", 387 .clock = 108000, 388 .refresh = 59940, 389 .oversample = 8, 390 .component_only = false, 391 /* 525 Lines, 60 Fields, 15.734KHz line, Sub-Carrier 3.580MHz */ 392 393 .hsync_end = 64, .hblank_end = 124, 394 .hblank_start = 836, .htotal = 857, 395 396 .progressive = false, .trilevel_sync = false, 397 398 .vsync_start_f1 = 6, .vsync_start_f2 = 7, 399 .vsync_len = 6, 400 401 .veq_ena = true, .veq_start_f1 = 0, 402 .veq_start_f2 = 1, .veq_len = 18, 403 404 .vi_end_f1 = 20, .vi_end_f2 = 21, 405 .nbr_end = 240, 406 407 .burst_ena = true, 408 .hburst_start = 72, .hburst_len = 34, 409 .vburst_start_f1 = 9, .vburst_end_f1 = 240, 410 .vburst_start_f2 = 10, .vburst_end_f2 = 240, 411 .vburst_start_f3 = 9, .vburst_end_f3 = 240, 412 .vburst_start_f4 = 10, .vburst_end_f4 = 240, 413 414 /* desired 3.5800000 actual 3.5800000 clock 107.52 */ 415 .dda1_inc = 135, 416 .dda2_inc = 20800, .dda2_size = 27456, 417 .dda3_inc = 0, .dda3_size = 0, 418 .sc_reset = TV_SC_RESET_EVERY_4, 419 .pal_burst = false, 420 421 .composite_levels = &ntsc_m_levels_composite, 422 .composite_color = &ntsc_m_csc_composite, 423 .svideo_levels = &ntsc_m_levels_svideo, 424 .svideo_color = &ntsc_m_csc_svideo, 425 426 .filter_table = filter_table, 427 }, 428 { 429 .name = "NTSC-443", 430 .clock = 108000, 431 .refresh = 59940, 432 .oversample = 8, 433 .component_only = false, 434 /* 525 Lines, 60 Fields, 15.734KHz line, Sub-Carrier 4.43MHz */ 435 .hsync_end = 64, .hblank_end = 124, 436 .hblank_start = 836, .htotal = 857, 437 438 .progressive = false, .trilevel_sync = false, 439 440 .vsync_start_f1 = 6, .vsync_start_f2 = 7, 441 .vsync_len = 6, 442 443 .veq_ena = true, .veq_start_f1 = 0, 444 .veq_start_f2 = 1, .veq_len = 18, 445 446 .vi_end_f1 = 20, .vi_end_f2 = 21, 447 .nbr_end = 240, 448 449 .burst_ena = true, 450 .hburst_start = 72, .hburst_len = 34, 451 .vburst_start_f1 = 9, .vburst_end_f1 = 240, 452 .vburst_start_f2 = 10, .vburst_end_f2 = 240, 453 .vburst_start_f3 = 9, .vburst_end_f3 = 240, 454 .vburst_start_f4 = 10, .vburst_end_f4 = 240, 455 456 /* desired 4.4336180 actual 4.4336180 clock 107.52 */ 457 .dda1_inc = 168, 458 .dda2_inc = 4093, .dda2_size = 27456, 459 .dda3_inc = 310, .dda3_size = 525, 460 .sc_reset = TV_SC_RESET_NEVER, 461 .pal_burst = false, 462 463 .composite_levels = &ntsc_m_levels_composite, 464 .composite_color = &ntsc_m_csc_composite, 465 .svideo_levels = &ntsc_m_levels_svideo, 466 .svideo_color = &ntsc_m_csc_svideo, 467 468 .filter_table = filter_table, 469 }, 470 { 471 .name = "NTSC-J", 472 .clock = 108000, 473 .refresh = 59940, 474 .oversample = 8, 475 .component_only = false, 476 477 /* 525 Lines, 60 Fields, 15.734KHz line, Sub-Carrier 3.580MHz */ 478 .hsync_end = 64, .hblank_end = 124, 479 .hblank_start = 836, .htotal = 857, 480 481 .progressive = false, .trilevel_sync = false, 482 483 .vsync_start_f1 = 6, .vsync_start_f2 = 7, 484 .vsync_len = 6, 485 486 .veq_ena = true, .veq_start_f1 = 0, 487 .veq_start_f2 = 1, .veq_len = 18, 488 489 .vi_end_f1 = 20, .vi_end_f2 = 21, 490 .nbr_end = 240, 491 492 .burst_ena = true, 493 .hburst_start = 72, .hburst_len = 34, 494 .vburst_start_f1 = 9, .vburst_end_f1 = 240, 495 .vburst_start_f2 = 10, .vburst_end_f2 = 240, 496 .vburst_start_f3 = 9, .vburst_end_f3 = 240, 497 .vburst_start_f4 = 10, .vburst_end_f4 = 240, 498 499 /* desired 3.5800000 actual 3.5800000 clock 107.52 */ 500 .dda1_inc = 135, 501 .dda2_inc = 20800, .dda2_size = 27456, 502 .dda3_inc = 0, .dda3_size = 0, 503 .sc_reset = TV_SC_RESET_EVERY_4, 504 .pal_burst = false, 505 506 .composite_levels = &ntsc_j_levels_composite, 507 .composite_color = &ntsc_j_csc_composite, 508 .svideo_levels = &ntsc_j_levels_svideo, 509 .svideo_color = &ntsc_j_csc_svideo, 510 511 .filter_table = filter_table, 512 }, 513 { 514 .name = "PAL-M", 515 .clock = 108000, 516 .refresh = 59940, 517 .oversample = 8, 518 .component_only = false, 519 520 /* 525 Lines, 60 Fields, 15.734KHz line, Sub-Carrier 3.580MHz */ 521 .hsync_end = 64, .hblank_end = 124, 522 .hblank_start = 836, .htotal = 857, 523 524 .progressive = false, .trilevel_sync = false, 525 526 .vsync_start_f1 = 6, .vsync_start_f2 = 7, 527 .vsync_len = 6, 528 529 .veq_ena = true, .veq_start_f1 = 0, 530 .veq_start_f2 = 1, .veq_len = 18, 531 532 .vi_end_f1 = 20, .vi_end_f2 = 21, 533 .nbr_end = 240, 534 535 .burst_ena = true, 536 .hburst_start = 72, .hburst_len = 34, 537 .vburst_start_f1 = 9, .vburst_end_f1 = 240, 538 .vburst_start_f2 = 10, .vburst_end_f2 = 240, 539 .vburst_start_f3 = 9, .vburst_end_f3 = 240, 540 .vburst_start_f4 = 10, .vburst_end_f4 = 240, 541 542 /* desired 3.5800000 actual 3.5800000 clock 107.52 */ 543 .dda1_inc = 135, 544 .dda2_inc = 16704, .dda2_size = 27456, 545 .dda3_inc = 0, .dda3_size = 0, 546 .sc_reset = TV_SC_RESET_EVERY_8, 547 .pal_burst = true, 548 549 .composite_levels = &pal_m_levels_composite, 550 .composite_color = &pal_m_csc_composite, 551 .svideo_levels = &pal_m_levels_svideo, 552 .svideo_color = &pal_m_csc_svideo, 553 554 .filter_table = filter_table, 555 }, 556 { 557 /* 625 Lines, 50 Fields, 15.625KHz line, Sub-Carrier 4.434MHz */ 558 .name = "PAL-N", 559 .clock = 108000, 560 .refresh = 50000, 561 .oversample = 8, 562 .component_only = false, 563 564 .hsync_end = 64, .hblank_end = 128, 565 .hblank_start = 844, .htotal = 863, 566 567 .progressive = false, .trilevel_sync = false, 568 569 570 .vsync_start_f1 = 6, .vsync_start_f2 = 7, 571 .vsync_len = 6, 572 573 .veq_ena = true, .veq_start_f1 = 0, 574 .veq_start_f2 = 1, .veq_len = 18, 575 576 .vi_end_f1 = 24, .vi_end_f2 = 25, 577 .nbr_end = 286, 578 579 .burst_ena = true, 580 .hburst_start = 73, .hburst_len = 34, 581 .vburst_start_f1 = 8, .vburst_end_f1 = 285, 582 .vburst_start_f2 = 8, .vburst_end_f2 = 286, 583 .vburst_start_f3 = 9, .vburst_end_f3 = 286, 584 .vburst_start_f4 = 9, .vburst_end_f4 = 285, 585 586 587 /* desired 4.4336180 actual 4.4336180 clock 107.52 */ 588 .dda1_inc = 135, 589 .dda2_inc = 23578, .dda2_size = 27648, 590 .dda3_inc = 134, .dda3_size = 625, 591 .sc_reset = TV_SC_RESET_EVERY_8, 592 .pal_burst = true, 593 594 .composite_levels = &pal_n_levels_composite, 595 .composite_color = &pal_n_csc_composite, 596 .svideo_levels = &pal_n_levels_svideo, 597 .svideo_color = &pal_n_csc_svideo, 598 599 .filter_table = filter_table, 600 }, 601 { 602 /* 625 Lines, 50 Fields, 15.625KHz line, Sub-Carrier 4.434MHz */ 603 .name = "PAL", 604 .clock = 108000, 605 .refresh = 50000, 606 .oversample = 8, 607 .component_only = false, 608 609 .hsync_end = 64, .hblank_end = 142, 610 .hblank_start = 844, .htotal = 863, 611 612 .progressive = false, .trilevel_sync = false, 613 614 .vsync_start_f1 = 5, .vsync_start_f2 = 6, 615 .vsync_len = 5, 616 617 .veq_ena = true, .veq_start_f1 = 0, 618 .veq_start_f2 = 1, .veq_len = 15, 619 620 .vi_end_f1 = 24, .vi_end_f2 = 25, 621 .nbr_end = 286, 622 623 .burst_ena = true, 624 .hburst_start = 73, .hburst_len = 32, 625 .vburst_start_f1 = 8, .vburst_end_f1 = 285, 626 .vburst_start_f2 = 8, .vburst_end_f2 = 286, 627 .vburst_start_f3 = 9, .vburst_end_f3 = 286, 628 .vburst_start_f4 = 9, .vburst_end_f4 = 285, 629 630 /* desired 4.4336180 actual 4.4336180 clock 107.52 */ 631 .dda1_inc = 168, 632 .dda2_inc = 4122, .dda2_size = 27648, 633 .dda3_inc = 67, .dda3_size = 625, 634 .sc_reset = TV_SC_RESET_EVERY_8, 635 .pal_burst = true, 636 637 .composite_levels = &pal_levels_composite, 638 .composite_color = &pal_csc_composite, 639 .svideo_levels = &pal_levels_svideo, 640 .svideo_color = &pal_csc_svideo, 641 642 .filter_table = filter_table, 643 }, 644 { 645 .name = "480p", 646 .clock = 108000, 647 .refresh = 59940, 648 .oversample = 4, 649 .component_only = true, 650 651 .hsync_end = 64, .hblank_end = 122, 652 .hblank_start = 842, .htotal = 857, 653 654 .progressive = true, .trilevel_sync = false, 655 656 .vsync_start_f1 = 12, .vsync_start_f2 = 12, 657 .vsync_len = 12, 658 659 .veq_ena = false, 660 661 .vi_end_f1 = 44, .vi_end_f2 = 44, 662 .nbr_end = 479, 663 664 .burst_ena = false, 665 666 .filter_table = filter_table, 667 }, 668 { 669 .name = "576p", 670 .clock = 108000, 671 .refresh = 50000, 672 .oversample = 4, 673 .component_only = true, 674 675 .hsync_end = 64, .hblank_end = 139, 676 .hblank_start = 859, .htotal = 863, 677 678 .progressive = true, .trilevel_sync = false, 679 680 .vsync_start_f1 = 10, .vsync_start_f2 = 10, 681 .vsync_len = 10, 682 683 .veq_ena = false, 684 685 .vi_end_f1 = 48, .vi_end_f2 = 48, 686 .nbr_end = 575, 687 688 .burst_ena = false, 689 690 .filter_table = filter_table, 691 }, 692 { 693 .name = "720p@60Hz", 694 .clock = 148500, 695 .refresh = 60000, 696 .oversample = 2, 697 .component_only = true, 698 699 .hsync_end = 80, .hblank_end = 300, 700 .hblank_start = 1580, .htotal = 1649, 701 702 .progressive = true, .trilevel_sync = true, 703 704 .vsync_start_f1 = 10, .vsync_start_f2 = 10, 705 .vsync_len = 10, 706 707 .veq_ena = false, 708 709 .vi_end_f1 = 29, .vi_end_f2 = 29, 710 .nbr_end = 719, 711 712 .burst_ena = false, 713 714 .filter_table = filter_table, 715 }, 716 { 717 .name = "720p@50Hz", 718 .clock = 148500, 719 .refresh = 50000, 720 .oversample = 2, 721 .component_only = true, 722 723 .hsync_end = 80, .hblank_end = 300, 724 .hblank_start = 1580, .htotal = 1979, 725 726 .progressive = true, .trilevel_sync = true, 727 728 .vsync_start_f1 = 10, .vsync_start_f2 = 10, 729 .vsync_len = 10, 730 731 .veq_ena = false, 732 733 .vi_end_f1 = 29, .vi_end_f2 = 29, 734 .nbr_end = 719, 735 736 .burst_ena = false, 737 738 .filter_table = filter_table, 739 }, 740 { 741 .name = "1080i@50Hz", 742 .clock = 148500, 743 .refresh = 50000, 744 .oversample = 2, 745 .component_only = true, 746 747 .hsync_end = 88, .hblank_end = 235, 748 .hblank_start = 2155, .htotal = 2639, 749 750 .progressive = false, .trilevel_sync = true, 751 752 .vsync_start_f1 = 4, .vsync_start_f2 = 5, 753 .vsync_len = 10, 754 755 .veq_ena = true, .veq_start_f1 = 4, 756 .veq_start_f2 = 4, .veq_len = 10, 757 758 759 .vi_end_f1 = 21, .vi_end_f2 = 22, 760 .nbr_end = 539, 761 762 .burst_ena = false, 763 764 .filter_table = filter_table, 765 }, 766 { 767 .name = "1080i@60Hz", 768 .clock = 148500, 769 .refresh = 60000, 770 .oversample = 2, 771 .component_only = true, 772 773 .hsync_end = 88, .hblank_end = 235, 774 .hblank_start = 2155, .htotal = 2199, 775 776 .progressive = false, .trilevel_sync = true, 777 778 .vsync_start_f1 = 4, .vsync_start_f2 = 5, 779 .vsync_len = 10, 780 781 .veq_ena = true, .veq_start_f1 = 4, 782 .veq_start_f2 = 4, .veq_len = 10, 783 784 785 .vi_end_f1 = 21, .vi_end_f2 = 22, 786 .nbr_end = 539, 787 788 .burst_ena = false, 789 790 .filter_table = filter_table, 791 }, 792 793 { 794 .name = "1080p@30Hz", 795 .clock = 148500, 796 .refresh = 30000, 797 .oversample = 2, 798 .component_only = true, 799 800 .hsync_end = 88, .hblank_end = 235, 801 .hblank_start = 2155, .htotal = 2199, 802 803 .progressive = true, .trilevel_sync = true, 804 805 .vsync_start_f1 = 8, .vsync_start_f2 = 8, 806 .vsync_len = 10, 807 808 .veq_ena = false, .veq_start_f1 = 0, 809 .veq_start_f2 = 0, .veq_len = 0, 810 811 .vi_end_f1 = 44, .vi_end_f2 = 44, 812 .nbr_end = 1079, 813 814 .burst_ena = false, 815 816 .filter_table = filter_table, 817 }, 818 819 { 820 .name = "1080p@50Hz", 821 .clock = 148500, 822 .refresh = 50000, 823 .oversample = 1, 824 .component_only = true, 825 826 .hsync_end = 88, .hblank_end = 235, 827 .hblank_start = 2155, .htotal = 2639, 828 829 .progressive = true, .trilevel_sync = true, 830 831 .vsync_start_f1 = 8, .vsync_start_f2 = 8, 832 .vsync_len = 10, 833 834 .veq_ena = false, .veq_start_f1 = 0, 835 .veq_start_f2 = 0, .veq_len = 0, 836 837 .vi_end_f1 = 44, .vi_end_f2 = 44, 838 .nbr_end = 1079, 839 840 .burst_ena = false, 841 842 .filter_table = filter_table, 843 }, 844 845 { 846 .name = "1080p@60Hz", 847 .clock = 148500, 848 .refresh = 60000, 849 .oversample = 1, 850 .component_only = true, 851 852 .hsync_end = 88, .hblank_end = 235, 853 .hblank_start = 2155, .htotal = 2199, 854 855 .progressive = true, .trilevel_sync = true, 856 857 .vsync_start_f1 = 8, .vsync_start_f2 = 8, 858 .vsync_len = 10, 859 860 .veq_ena = false, .veq_start_f1 = 0, 861 .veq_start_f2 = 0, .veq_len = 0, 862 863 .vi_end_f1 = 44, .vi_end_f2 = 44, 864 .nbr_end = 1079, 865 866 .burst_ena = false, 867 868 .filter_table = filter_table, 869 }, 870}; 871 872struct intel_tv_connector_state { 873 struct drm_connector_state base; 874 875 /* 876 * May need to override the user margins for 877 * gen3 >1024 wide source vertical centering. 878 */ 879 struct { 880 u16 top, bottom; 881 } margins; 882 883 bool bypass_vfilter; 884}; 885 886#define to_intel_tv_connector_state(x) container_of(x, struct intel_tv_connector_state, base) 887 888static struct drm_connector_state * 889intel_tv_connector_duplicate_state(struct drm_connector *connector) 890{ 891 struct intel_tv_connector_state *state; 892 893 state = kmemdup(connector->state, sizeof(*state), GFP_KERNEL); 894 if (!state) 895 return NULL; 896 897 __drm_atomic_helper_connector_duplicate_state(connector, &state->base); 898 return &state->base; 899} 900 901static struct intel_tv *enc_to_tv(struct intel_encoder *encoder) 902{ 903 return container_of(encoder, struct intel_tv, base); 904} 905 906static struct intel_tv *intel_attached_tv(struct intel_connector *connector) 907{ 908 return enc_to_tv(intel_attached_encoder(connector)); 909} 910 911static bool 912intel_tv_get_hw_state(struct intel_encoder *encoder, enum pipe *pipe) 913{ 914 struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); 915 u32 tmp = I915_READ(TV_CTL); 916 917 *pipe = (tmp & TV_ENC_PIPE_SEL_MASK) >> TV_ENC_PIPE_SEL_SHIFT; 918 919 return tmp & TV_ENC_ENABLE; 920} 921 922static void 923intel_enable_tv(struct intel_encoder *encoder, 924 const struct intel_crtc_state *pipe_config, 925 const struct drm_connector_state *conn_state) 926{ 927 struct drm_device *dev = encoder->base.dev; 928 struct drm_i915_private *dev_priv = to_i915(dev); 929 930 /* Prevents vblank waits from timing out in intel_tv_detect_type() */ 931 intel_wait_for_vblank(dev_priv, 932 to_intel_crtc(pipe_config->uapi.crtc)->pipe); 933 934 I915_WRITE(TV_CTL, I915_READ(TV_CTL) | TV_ENC_ENABLE); 935} 936 937static void 938intel_disable_tv(struct intel_encoder *encoder, 939 const struct intel_crtc_state *old_crtc_state, 940 const struct drm_connector_state *old_conn_state) 941{ 942 struct drm_device *dev = encoder->base.dev; 943 struct drm_i915_private *dev_priv = to_i915(dev); 944 945 I915_WRITE(TV_CTL, I915_READ(TV_CTL) & ~TV_ENC_ENABLE); 946} 947 948static const struct tv_mode *intel_tv_mode_find(const struct drm_connector_state *conn_state) 949{ 950 int format = conn_state->tv.mode; 951 952 return &tv_modes[format]; 953} 954 955static enum drm_mode_status 956intel_tv_mode_valid(struct drm_connector *connector, 957 struct drm_display_mode *mode) 958{ 959 const struct tv_mode *tv_mode = intel_tv_mode_find(connector->state); 960 int max_dotclk = to_i915(connector->dev)->max_dotclk_freq; 961 962 if (mode->flags & DRM_MODE_FLAG_DBLSCAN) 963 return MODE_NO_DBLESCAN; 964 965 if (mode->clock > max_dotclk) 966 return MODE_CLOCK_HIGH; 967 968 /* Ensure TV refresh is close to desired refresh */ 969 if (abs(tv_mode->refresh - drm_mode_vrefresh(mode) * 1000) >= 1000) 970 return MODE_CLOCK_RANGE; 971 972 return MODE_OK; 973} 974 975static int 976intel_tv_mode_vdisplay(const struct tv_mode *tv_mode) 977{ 978 if (tv_mode->progressive) 979 return tv_mode->nbr_end + 1; 980 else 981 return 2 * (tv_mode->nbr_end + 1); 982} 983 984static void 985intel_tv_mode_to_mode(struct drm_display_mode *mode, 986 const struct tv_mode *tv_mode) 987{ 988 mode->clock = tv_mode->clock / 989 (tv_mode->oversample >> !tv_mode->progressive); 990 991 /* 992 * tv_mode horizontal timings: 993 * 994 * hsync_end 995 * | hblank_end 996 * | | hblank_start 997 * | | | htotal 998 * | _______ | 999 * ____/ \___ 1000 * \__/ \ 1001 */ 1002 mode->hdisplay = 1003 tv_mode->hblank_start - tv_mode->hblank_end; 1004 mode->hsync_start = mode->hdisplay + 1005 tv_mode->htotal - tv_mode->hblank_start; 1006 mode->hsync_end = mode->hsync_start + 1007 tv_mode->hsync_end; 1008 mode->htotal = tv_mode->htotal + 1; 1009 1010 /* 1011 * tv_mode vertical timings: 1012 * 1013 * vsync_start 1014 * | vsync_end 1015 * | | vi_end nbr_end 1016 * | | | | 1017 * | | _______ 1018 * \__ ____/ \ 1019 * \__/ 1020 */ 1021 mode->vdisplay = intel_tv_mode_vdisplay(tv_mode); 1022 if (tv_mode->progressive) { 1023 mode->vsync_start = mode->vdisplay + 1024 tv_mode->vsync_start_f1 + 1; 1025 mode->vsync_end = mode->vsync_start + 1026 tv_mode->vsync_len; 1027 mode->vtotal = mode->vdisplay + 1028 tv_mode->vi_end_f1 + 1; 1029 } else { 1030 mode->vsync_start = mode->vdisplay + 1031 tv_mode->vsync_start_f1 + 1 + 1032 tv_mode->vsync_start_f2 + 1; 1033 mode->vsync_end = mode->vsync_start + 1034 2 * tv_mode->vsync_len; 1035 mode->vtotal = mode->vdisplay + 1036 tv_mode->vi_end_f1 + 1 + 1037 tv_mode->vi_end_f2 + 1; 1038 } 1039 1040 /* TV has it's own notion of sync and other mode flags, so clear them. */ 1041 mode->flags = 0; 1042 1043 mode->vrefresh = 0; 1044 mode->vrefresh = drm_mode_vrefresh(mode); 1045 1046 snprintf(mode->name, sizeof(mode->name), 1047 "%dx%d%c (%s)", 1048 mode->hdisplay, mode->vdisplay, 1049 tv_mode->progressive ? 'p' : 'i', 1050 tv_mode->name); 1051} 1052 1053static void intel_tv_scale_mode_horiz(struct drm_display_mode *mode, 1054 int hdisplay, int left_margin, 1055 int right_margin) 1056{ 1057 int hsync_start = mode->hsync_start - mode->hdisplay + right_margin; 1058 int hsync_end = mode->hsync_end - mode->hdisplay + right_margin; 1059 int new_htotal = mode->htotal * hdisplay / 1060 (mode->hdisplay - left_margin - right_margin); 1061 1062 mode->clock = mode->clock * new_htotal / mode->htotal; 1063 1064 mode->hdisplay = hdisplay; 1065 mode->hsync_start = hdisplay + hsync_start * new_htotal / mode->htotal; 1066 mode->hsync_end = hdisplay + hsync_end * new_htotal / mode->htotal; 1067 mode->htotal = new_htotal; 1068} 1069 1070static void intel_tv_scale_mode_vert(struct drm_display_mode *mode, 1071 int vdisplay, int top_margin, 1072 int bottom_margin) 1073{ 1074 int vsync_start = mode->vsync_start - mode->vdisplay + bottom_margin; 1075 int vsync_end = mode->vsync_end - mode->vdisplay + bottom_margin; 1076 int new_vtotal = mode->vtotal * vdisplay / 1077 (mode->vdisplay - top_margin - bottom_margin); 1078 1079 mode->clock = mode->clock * new_vtotal / mode->vtotal; 1080 1081 mode->vdisplay = vdisplay; 1082 mode->vsync_start = vdisplay + vsync_start * new_vtotal / mode->vtotal; 1083 mode->vsync_end = vdisplay + vsync_end * new_vtotal / mode->vtotal; 1084 mode->vtotal = new_vtotal; 1085} 1086 1087static void 1088intel_tv_get_config(struct intel_encoder *encoder, 1089 struct intel_crtc_state *pipe_config) 1090{ 1091 struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); 1092 struct drm_display_mode *adjusted_mode = 1093 &pipe_config->hw.adjusted_mode; 1094 struct drm_display_mode mode = {}; 1095 u32 tv_ctl, hctl1, hctl3, vctl1, vctl2, tmp; 1096 struct tv_mode tv_mode = {}; 1097 int hdisplay = adjusted_mode->crtc_hdisplay; 1098 int vdisplay = adjusted_mode->crtc_vdisplay; 1099 int xsize, ysize, xpos, ypos; 1100 1101 pipe_config->output_types |= BIT(INTEL_OUTPUT_TVOUT); 1102 1103 tv_ctl = I915_READ(TV_CTL); 1104 hctl1 = I915_READ(TV_H_CTL_1); 1105 hctl3 = I915_READ(TV_H_CTL_3); 1106 vctl1 = I915_READ(TV_V_CTL_1); 1107 vctl2 = I915_READ(TV_V_CTL_2); 1108 1109 tv_mode.htotal = (hctl1 & TV_HTOTAL_MASK) >> TV_HTOTAL_SHIFT; 1110 tv_mode.hsync_end = (hctl1 & TV_HSYNC_END_MASK) >> TV_HSYNC_END_SHIFT; 1111 1112 tv_mode.hblank_start = (hctl3 & TV_HBLANK_START_MASK) >> TV_HBLANK_START_SHIFT; 1113 tv_mode.hblank_end = (hctl3 & TV_HSYNC_END_MASK) >> TV_HBLANK_END_SHIFT; 1114 1115 tv_mode.nbr_end = (vctl1 & TV_NBR_END_MASK) >> TV_NBR_END_SHIFT; 1116 tv_mode.vi_end_f1 = (vctl1 & TV_VI_END_F1_MASK) >> TV_VI_END_F1_SHIFT; 1117 tv_mode.vi_end_f2 = (vctl1 & TV_VI_END_F2_MASK) >> TV_VI_END_F2_SHIFT; 1118 1119 tv_mode.vsync_len = (vctl2 & TV_VSYNC_LEN_MASK) >> TV_VSYNC_LEN_SHIFT; 1120 tv_mode.vsync_start_f1 = (vctl2 & TV_VSYNC_START_F1_MASK) >> TV_VSYNC_START_F1_SHIFT; 1121 tv_mode.vsync_start_f2 = (vctl2 & TV_VSYNC_START_F2_MASK) >> TV_VSYNC_START_F2_SHIFT; 1122 1123 tv_mode.clock = pipe_config->port_clock; 1124 1125 tv_mode.progressive = tv_ctl & TV_PROGRESSIVE; 1126 1127 switch (tv_ctl & TV_OVERSAMPLE_MASK) { 1128 case TV_OVERSAMPLE_8X: 1129 tv_mode.oversample = 8; 1130 break; 1131 case TV_OVERSAMPLE_4X: 1132 tv_mode.oversample = 4; 1133 break; 1134 case TV_OVERSAMPLE_2X: 1135 tv_mode.oversample = 2; 1136 break; 1137 default: 1138 tv_mode.oversample = 1; 1139 break; 1140 } 1141 1142 tmp = I915_READ(TV_WIN_POS); 1143 xpos = tmp >> 16; 1144 ypos = tmp & 0xffff; 1145 1146 tmp = I915_READ(TV_WIN_SIZE); 1147 xsize = tmp >> 16; 1148 ysize = tmp & 0xffff; 1149 1150 intel_tv_mode_to_mode(&mode, &tv_mode); 1151 1152 DRM_DEBUG_KMS("TV mode:\n"); 1153 drm_mode_debug_printmodeline(&mode); 1154 1155 intel_tv_scale_mode_horiz(&mode, hdisplay, 1156 xpos, mode.hdisplay - xsize - xpos); 1157 intel_tv_scale_mode_vert(&mode, vdisplay, 1158 ypos, mode.vdisplay - ysize - ypos); 1159 1160 adjusted_mode->crtc_clock = mode.clock; 1161 if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) 1162 adjusted_mode->crtc_clock /= 2; 1163 1164 /* pixel counter doesn't work on i965gm TV output */ 1165 if (IS_I965GM(dev_priv)) 1166 adjusted_mode->private_flags |= 1167 I915_MODE_FLAG_USE_SCANLINE_COUNTER; 1168} 1169 1170static bool intel_tv_source_too_wide(struct drm_i915_private *dev_priv, 1171 int hdisplay) 1172{ 1173 return IS_GEN(dev_priv, 3) && hdisplay > 1024; 1174} 1175 1176static bool intel_tv_vert_scaling(const struct drm_display_mode *tv_mode, 1177 const struct drm_connector_state *conn_state, 1178 int vdisplay) 1179{ 1180 return tv_mode->crtc_vdisplay - 1181 conn_state->tv.margins.top - 1182 conn_state->tv.margins.bottom != 1183 vdisplay; 1184} 1185 1186static int 1187intel_tv_compute_config(struct intel_encoder *encoder, 1188 struct intel_crtc_state *pipe_config, 1189 struct drm_connector_state *conn_state) 1190{ 1191 struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); 1192 struct intel_tv_connector_state *tv_conn_state = 1193 to_intel_tv_connector_state(conn_state); 1194 const struct tv_mode *tv_mode = intel_tv_mode_find(conn_state); 1195 struct drm_display_mode *adjusted_mode = 1196 &pipe_config->hw.adjusted_mode; 1197 int hdisplay = adjusted_mode->crtc_hdisplay; 1198 int vdisplay = adjusted_mode->crtc_vdisplay; 1199 1200 if (!tv_mode) 1201 return -EINVAL; 1202 1203 if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN) 1204 return -EINVAL; 1205 1206 pipe_config->output_format = INTEL_OUTPUT_FORMAT_RGB; 1207 1208 DRM_DEBUG_KMS("forcing bpc to 8 for TV\n"); 1209 pipe_config->pipe_bpp = 8*3; 1210 1211 pipe_config->port_clock = tv_mode->clock; 1212 1213 intel_tv_mode_to_mode(adjusted_mode, tv_mode); 1214 drm_mode_set_crtcinfo(adjusted_mode, 0); 1215 1216 if (intel_tv_source_too_wide(dev_priv, hdisplay) || 1217 !intel_tv_vert_scaling(adjusted_mode, conn_state, vdisplay)) { 1218 int extra, top, bottom; 1219 1220 extra = adjusted_mode->crtc_vdisplay - vdisplay; 1221 1222 if (extra < 0) { 1223 DRM_DEBUG_KMS("No vertical scaling for >1024 pixel wide modes\n"); 1224 return -EINVAL; 1225 } 1226 1227 /* Need to turn off the vertical filter and center the image */ 1228 1229 /* Attempt to maintain the relative sizes of the margins */ 1230 top = conn_state->tv.margins.top; 1231 bottom = conn_state->tv.margins.bottom; 1232 1233 if (top + bottom) 1234 top = extra * top / (top + bottom); 1235 else 1236 top = extra / 2; 1237 bottom = extra - top; 1238 1239 tv_conn_state->margins.top = top; 1240 tv_conn_state->margins.bottom = bottom; 1241 1242 tv_conn_state->bypass_vfilter = true; 1243 1244 if (!tv_mode->progressive) { 1245 adjusted_mode->clock /= 2; 1246 adjusted_mode->crtc_clock /= 2; 1247 adjusted_mode->flags |= DRM_MODE_FLAG_INTERLACE; 1248 } 1249 } else { 1250 tv_conn_state->margins.top = conn_state->tv.margins.top; 1251 tv_conn_state->margins.bottom = conn_state->tv.margins.bottom; 1252 1253 tv_conn_state->bypass_vfilter = false; 1254 } 1255 1256 DRM_DEBUG_KMS("TV mode:\n"); 1257 drm_mode_debug_printmodeline(adjusted_mode); 1258 1259 /* 1260 * The pipe scanline counter behaviour looks as follows when 1261 * using the TV encoder: 1262 * 1263 * time -> 1264 * 1265 * dsl=vtotal-1 | | 1266 * || || 1267 * ___| | ___| | 1268 * / | / | 1269 * / | / | 1270 * dsl=0 ___/ |_____/ | 1271 * | | | | | | 1272 * ^ ^ ^ ^ ^ 1273 * | | | | pipe vblank/first part of tv vblank 1274 * | | | bottom margin 1275 * | | active 1276 * | top margin 1277 * remainder of tv vblank 1278 * 1279 * When the TV encoder is used the pipe wants to run faster 1280 * than expected rate. During the active portion the TV 1281 * encoder stalls the pipe every few lines to keep it in 1282 * check. When the TV encoder reaches the bottom margin the 1283 * pipe simply stops. Once we reach the TV vblank the pipe is 1284 * no longer stalled and it runs at the max rate (apparently 1285 * oversample clock on gen3, cdclk on gen4). Once the pipe 1286 * reaches the pipe vtotal the pipe stops for the remainder 1287 * of the TV vblank/top margin. The pipe starts up again when 1288 * the TV encoder exits the top margin. 1289 * 1290 * To avoid huge hassles for vblank timestamping we scale 1291 * the pipe timings as if the pipe always runs at the average 1292 * rate it maintains during the active period. This also 1293 * gives us a reasonable guesstimate as to the pixel rate. 1294 * Due to the variation in the actual pipe speed the scanline 1295 * counter will give us slightly erroneous results during the 1296 * TV vblank/margins. But since vtotal was selected such that 1297 * it matches the average rate of the pipe during the active 1298 * portion the error shouldn't cause any serious grief to 1299 * vblank timestamps. 1300 * 1301 * For posterity here is the empirically derived formula 1302 * that gives us the maximum length of the pipe vblank 1303 * we can use without causing display corruption. Following 1304 * this would allow us to have a ticking scanline counter 1305 * everywhere except during the bottom margin (there the 1306 * pipe always stops). Ie. this would eliminate the second 1307 * flat portion of the above graph. However this would also 1308 * complicate vblank timestamping as the pipe vtotal would 1309 * no longer match the average rate the pipe runs at during 1310 * the active portion. Hence following this formula seems 1311 * more trouble that it's worth. 1312 * 1313 * if (IS_GEN(dev_priv, 4)) { 1314 * num = cdclk * (tv_mode->oversample >> !tv_mode->progressive); 1315 * den = tv_mode->clock; 1316 * } else { 1317 * num = tv_mode->oversample >> !tv_mode->progressive; 1318 * den = 1; 1319 * } 1320 * max_pipe_vblank_len ~= 1321 * (num * tv_htotal * (tv_vblank_len + top_margin)) / 1322 * (den * pipe_htotal); 1323 */ 1324 intel_tv_scale_mode_horiz(adjusted_mode, hdisplay, 1325 conn_state->tv.margins.left, 1326 conn_state->tv.margins.right); 1327 intel_tv_scale_mode_vert(adjusted_mode, vdisplay, 1328 tv_conn_state->margins.top, 1329 tv_conn_state->margins.bottom); 1330 drm_mode_set_crtcinfo(adjusted_mode, 0); 1331 adjusted_mode->name[0] = '\0'; 1332 1333 /* pixel counter doesn't work on i965gm TV output */ 1334 if (IS_I965GM(dev_priv)) 1335 adjusted_mode->private_flags |= 1336 I915_MODE_FLAG_USE_SCANLINE_COUNTER; 1337 1338 return 0; 1339} 1340 1341static void 1342set_tv_mode_timings(struct drm_i915_private *dev_priv, 1343 const struct tv_mode *tv_mode, 1344 bool burst_ena) 1345{ 1346 u32 hctl1, hctl2, hctl3; 1347 u32 vctl1, vctl2, vctl3, vctl4, vctl5, vctl6, vctl7; 1348 1349 hctl1 = (tv_mode->hsync_end << TV_HSYNC_END_SHIFT) | 1350 (tv_mode->htotal << TV_HTOTAL_SHIFT); 1351 1352 hctl2 = (tv_mode->hburst_start << 16) | 1353 (tv_mode->hburst_len << TV_HBURST_LEN_SHIFT); 1354 1355 if (burst_ena) 1356 hctl2 |= TV_BURST_ENA; 1357 1358 hctl3 = (tv_mode->hblank_start << TV_HBLANK_START_SHIFT) | 1359 (tv_mode->hblank_end << TV_HBLANK_END_SHIFT); 1360 1361 vctl1 = (tv_mode->nbr_end << TV_NBR_END_SHIFT) | 1362 (tv_mode->vi_end_f1 << TV_VI_END_F1_SHIFT) | 1363 (tv_mode->vi_end_f2 << TV_VI_END_F2_SHIFT); 1364 1365 vctl2 = (tv_mode->vsync_len << TV_VSYNC_LEN_SHIFT) | 1366 (tv_mode->vsync_start_f1 << TV_VSYNC_START_F1_SHIFT) | 1367 (tv_mode->vsync_start_f2 << TV_VSYNC_START_F2_SHIFT); 1368 1369 vctl3 = (tv_mode->veq_len << TV_VEQ_LEN_SHIFT) | 1370 (tv_mode->veq_start_f1 << TV_VEQ_START_F1_SHIFT) | 1371 (tv_mode->veq_start_f2 << TV_VEQ_START_F2_SHIFT); 1372 1373 if (tv_mode->veq_ena) 1374 vctl3 |= TV_EQUAL_ENA; 1375 1376 vctl4 = (tv_mode->vburst_start_f1 << TV_VBURST_START_F1_SHIFT) | 1377 (tv_mode->vburst_end_f1 << TV_VBURST_END_F1_SHIFT); 1378 1379 vctl5 = (tv_mode->vburst_start_f2 << TV_VBURST_START_F2_SHIFT) | 1380 (tv_mode->vburst_end_f2 << TV_VBURST_END_F2_SHIFT); 1381 1382 vctl6 = (tv_mode->vburst_start_f3 << TV_VBURST_START_F3_SHIFT) | 1383 (tv_mode->vburst_end_f3 << TV_VBURST_END_F3_SHIFT); 1384 1385 vctl7 = (tv_mode->vburst_start_f4 << TV_VBURST_START_F4_SHIFT) | 1386 (tv_mode->vburst_end_f4 << TV_VBURST_END_F4_SHIFT); 1387 1388 I915_WRITE(TV_H_CTL_1, hctl1); 1389 I915_WRITE(TV_H_CTL_2, hctl2); 1390 I915_WRITE(TV_H_CTL_3, hctl3); 1391 I915_WRITE(TV_V_CTL_1, vctl1); 1392 I915_WRITE(TV_V_CTL_2, vctl2); 1393 I915_WRITE(TV_V_CTL_3, vctl3); 1394 I915_WRITE(TV_V_CTL_4, vctl4); 1395 I915_WRITE(TV_V_CTL_5, vctl5); 1396 I915_WRITE(TV_V_CTL_6, vctl6); 1397 I915_WRITE(TV_V_CTL_7, vctl7); 1398} 1399 1400static void set_color_conversion(struct drm_i915_private *dev_priv, 1401 const struct color_conversion *color_conversion) 1402{ 1403 if (!color_conversion) 1404 return; 1405 1406 I915_WRITE(TV_CSC_Y, (color_conversion->ry << 16) | 1407 color_conversion->gy); 1408 I915_WRITE(TV_CSC_Y2, (color_conversion->by << 16) | 1409 color_conversion->ay); 1410 I915_WRITE(TV_CSC_U, (color_conversion->ru << 16) | 1411 color_conversion->gu); 1412 I915_WRITE(TV_CSC_U2, (color_conversion->bu << 16) | 1413 color_conversion->au); 1414 I915_WRITE(TV_CSC_V, (color_conversion->rv << 16) | 1415 color_conversion->gv); 1416 I915_WRITE(TV_CSC_V2, (color_conversion->bv << 16) | 1417 color_conversion->av); 1418} 1419 1420static void intel_tv_pre_enable(struct intel_encoder *encoder, 1421 const struct intel_crtc_state *pipe_config, 1422 const struct drm_connector_state *conn_state) 1423{ 1424 struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); 1425 struct intel_crtc *intel_crtc = to_intel_crtc(pipe_config->uapi.crtc); 1426 struct intel_tv *intel_tv = enc_to_tv(encoder); 1427 const struct intel_tv_connector_state *tv_conn_state = 1428 const_container_of(conn_state, struct intel_tv_connector_state, base); 1429 const struct tv_mode *tv_mode = intel_tv_mode_find(conn_state); 1430 u32 tv_ctl, tv_filter_ctl; 1431 u32 scctl1, scctl2, scctl3; 1432 int i, j; 1433 const struct video_levels *video_levels; 1434 const struct color_conversion *color_conversion; 1435 bool burst_ena; 1436 int xpos, ypos; 1437 unsigned int xsize, ysize; 1438 1439 if (!tv_mode) 1440 return; /* can't happen (mode_prepare prevents this) */ 1441 1442 tv_ctl = I915_READ(TV_CTL); 1443 tv_ctl &= TV_CTL_SAVE; 1444 1445 switch (intel_tv->type) { 1446 default: 1447 case DRM_MODE_CONNECTOR_Unknown: 1448 case DRM_MODE_CONNECTOR_Composite: 1449 tv_ctl |= TV_ENC_OUTPUT_COMPOSITE; 1450 video_levels = tv_mode->composite_levels; 1451 color_conversion = tv_mode->composite_color; 1452 burst_ena = tv_mode->burst_ena; 1453 break; 1454 case DRM_MODE_CONNECTOR_Component: 1455 tv_ctl |= TV_ENC_OUTPUT_COMPONENT; 1456 video_levels = &component_levels; 1457 if (tv_mode->burst_ena) 1458 color_conversion = &sdtv_csc_yprpb; 1459 else 1460 color_conversion = &hdtv_csc_yprpb; 1461 burst_ena = false; 1462 break; 1463 case DRM_MODE_CONNECTOR_SVIDEO: 1464 tv_ctl |= TV_ENC_OUTPUT_SVIDEO; 1465 video_levels = tv_mode->svideo_levels; 1466 color_conversion = tv_mode->svideo_color; 1467 burst_ena = tv_mode->burst_ena; 1468 break; 1469 } 1470 1471 tv_ctl |= TV_ENC_PIPE_SEL(intel_crtc->pipe); 1472 1473 switch (tv_mode->oversample) { 1474 case 8: 1475 tv_ctl |= TV_OVERSAMPLE_8X; 1476 break; 1477 case 4: 1478 tv_ctl |= TV_OVERSAMPLE_4X; 1479 break; 1480 case 2: 1481 tv_ctl |= TV_OVERSAMPLE_2X; 1482 break; 1483 default: 1484 tv_ctl |= TV_OVERSAMPLE_NONE; 1485 break; 1486 } 1487 1488 if (tv_mode->progressive) 1489 tv_ctl |= TV_PROGRESSIVE; 1490 if (tv_mode->trilevel_sync) 1491 tv_ctl |= TV_TRILEVEL_SYNC; 1492 if (tv_mode->pal_burst) 1493 tv_ctl |= TV_PAL_BURST; 1494 1495 scctl1 = 0; 1496 if (tv_mode->dda1_inc) 1497 scctl1 |= TV_SC_DDA1_EN; 1498 if (tv_mode->dda2_inc) 1499 scctl1 |= TV_SC_DDA2_EN; 1500 if (tv_mode->dda3_inc) 1501 scctl1 |= TV_SC_DDA3_EN; 1502 scctl1 |= tv_mode->sc_reset; 1503 if (video_levels) 1504 scctl1 |= video_levels->burst << TV_BURST_LEVEL_SHIFT; 1505 scctl1 |= tv_mode->dda1_inc << TV_SCDDA1_INC_SHIFT; 1506 1507 scctl2 = tv_mode->dda2_size << TV_SCDDA2_SIZE_SHIFT | 1508 tv_mode->dda2_inc << TV_SCDDA2_INC_SHIFT; 1509 1510 scctl3 = tv_mode->dda3_size << TV_SCDDA3_SIZE_SHIFT | 1511 tv_mode->dda3_inc << TV_SCDDA3_INC_SHIFT; 1512 1513 /* Enable two fixes for the chips that need them. */ 1514 if (IS_I915GM(dev_priv)) 1515 tv_ctl |= TV_ENC_C0_FIX | TV_ENC_SDP_FIX; 1516 1517 set_tv_mode_timings(dev_priv, tv_mode, burst_ena); 1518 1519 I915_WRITE(TV_SC_CTL_1, scctl1); 1520 I915_WRITE(TV_SC_CTL_2, scctl2); 1521 I915_WRITE(TV_SC_CTL_3, scctl3); 1522 1523 set_color_conversion(dev_priv, color_conversion); 1524 1525 if (INTEL_GEN(dev_priv) >= 4) 1526 I915_WRITE(TV_CLR_KNOBS, 0x00404000); 1527 else 1528 I915_WRITE(TV_CLR_KNOBS, 0x00606000); 1529 1530 if (video_levels) 1531 I915_WRITE(TV_CLR_LEVEL, 1532 ((video_levels->black << TV_BLACK_LEVEL_SHIFT) | 1533 (video_levels->blank << TV_BLANK_LEVEL_SHIFT))); 1534 1535 assert_pipe_disabled(dev_priv, pipe_config->cpu_transcoder); 1536 1537 /* Filter ctl must be set before TV_WIN_SIZE */ 1538 tv_filter_ctl = TV_AUTO_SCALE; 1539 if (tv_conn_state->bypass_vfilter) 1540 tv_filter_ctl |= TV_V_FILTER_BYPASS; 1541 I915_WRITE(TV_FILTER_CTL_1, tv_filter_ctl); 1542 1543 xsize = tv_mode->hblank_start - tv_mode->hblank_end; 1544 ysize = intel_tv_mode_vdisplay(tv_mode); 1545 1546 xpos = conn_state->tv.margins.left; 1547 ypos = tv_conn_state->margins.top; 1548 xsize -= (conn_state->tv.margins.left + 1549 conn_state->tv.margins.right); 1550 ysize -= (tv_conn_state->margins.top + 1551 tv_conn_state->margins.bottom); 1552 I915_WRITE(TV_WIN_POS, (xpos<<16)|ypos); 1553 I915_WRITE(TV_WIN_SIZE, (xsize<<16)|ysize); 1554 1555 j = 0; 1556 for (i = 0; i < 60; i++) 1557 I915_WRITE(TV_H_LUMA(i), tv_mode->filter_table[j++]); 1558 for (i = 0; i < 60; i++) 1559 I915_WRITE(TV_H_CHROMA(i), tv_mode->filter_table[j++]); 1560 for (i = 0; i < 43; i++) 1561 I915_WRITE(TV_V_LUMA(i), tv_mode->filter_table[j++]); 1562 for (i = 0; i < 43; i++) 1563 I915_WRITE(TV_V_CHROMA(i), tv_mode->filter_table[j++]); 1564 I915_WRITE(TV_DAC, I915_READ(TV_DAC) & TV_DAC_SAVE); 1565 I915_WRITE(TV_CTL, tv_ctl); 1566} 1567 1568static int 1569intel_tv_detect_type(struct intel_tv *intel_tv, 1570 struct drm_connector *connector) 1571{ 1572 struct drm_crtc *crtc = connector->state->crtc; 1573 struct intel_crtc *intel_crtc = to_intel_crtc(crtc); 1574 struct drm_device *dev = connector->dev; 1575 struct drm_i915_private *dev_priv = to_i915(dev); 1576 u32 tv_ctl, save_tv_ctl; 1577 u32 tv_dac, save_tv_dac; 1578 int type; 1579 1580 /* Disable TV interrupts around load detect or we'll recurse */ 1581 if (connector->polled & DRM_CONNECTOR_POLL_HPD) { 1582 spin_lock_irq(&dev_priv->irq_lock); 1583 i915_disable_pipestat(dev_priv, 0, 1584 PIPE_HOTPLUG_INTERRUPT_STATUS | 1585 PIPE_HOTPLUG_TV_INTERRUPT_STATUS); 1586 spin_unlock_irq(&dev_priv->irq_lock); 1587 } 1588 1589 save_tv_dac = tv_dac = I915_READ(TV_DAC); 1590 save_tv_ctl = tv_ctl = I915_READ(TV_CTL); 1591 1592 /* Poll for TV detection */ 1593 tv_ctl &= ~(TV_ENC_ENABLE | TV_ENC_PIPE_SEL_MASK | TV_TEST_MODE_MASK); 1594 tv_ctl |= TV_TEST_MODE_MONITOR_DETECT; 1595 tv_ctl |= TV_ENC_PIPE_SEL(intel_crtc->pipe); 1596 1597 tv_dac &= ~(TVDAC_SENSE_MASK | DAC_A_MASK | DAC_B_MASK | DAC_C_MASK); 1598 tv_dac |= (TVDAC_STATE_CHG_EN | 1599 TVDAC_A_SENSE_CTL | 1600 TVDAC_B_SENSE_CTL | 1601 TVDAC_C_SENSE_CTL | 1602 DAC_CTL_OVERRIDE | 1603 DAC_A_0_7_V | 1604 DAC_B_0_7_V | 1605 DAC_C_0_7_V); 1606 1607 1608 /* 1609 * The TV sense state should be cleared to zero on cantiga platform. Otherwise 1610 * the TV is misdetected. This is hardware requirement. 1611 */ 1612 if (IS_GM45(dev_priv)) 1613 tv_dac &= ~(TVDAC_STATE_CHG_EN | TVDAC_A_SENSE_CTL | 1614 TVDAC_B_SENSE_CTL | TVDAC_C_SENSE_CTL); 1615 1616 I915_WRITE(TV_CTL, tv_ctl); 1617 I915_WRITE(TV_DAC, tv_dac); 1618 POSTING_READ(TV_DAC); 1619 1620 intel_wait_for_vblank(dev_priv, intel_crtc->pipe); 1621 1622 type = -1; 1623 tv_dac = I915_READ(TV_DAC); 1624 DRM_DEBUG_KMS("TV detected: %x, %x\n", tv_ctl, tv_dac); 1625 /* 1626 * A B C 1627 * 0 1 1 Composite 1628 * 1 0 X svideo 1629 * 0 0 0 Component 1630 */ 1631 if ((tv_dac & TVDAC_SENSE_MASK) == (TVDAC_B_SENSE | TVDAC_C_SENSE)) { 1632 DRM_DEBUG_KMS("Detected Composite TV connection\n"); 1633 type = DRM_MODE_CONNECTOR_Composite; 1634 } else if ((tv_dac & (TVDAC_A_SENSE|TVDAC_B_SENSE)) == TVDAC_A_SENSE) { 1635 DRM_DEBUG_KMS("Detected S-Video TV connection\n"); 1636 type = DRM_MODE_CONNECTOR_SVIDEO; 1637 } else if ((tv_dac & TVDAC_SENSE_MASK) == 0) { 1638 DRM_DEBUG_KMS("Detected Component TV connection\n"); 1639 type = DRM_MODE_CONNECTOR_Component; 1640 } else { 1641 DRM_DEBUG_KMS("Unrecognised TV connection\n"); 1642 type = -1; 1643 } 1644 1645 I915_WRITE(TV_DAC, save_tv_dac & ~TVDAC_STATE_CHG_EN); 1646 I915_WRITE(TV_CTL, save_tv_ctl); 1647 POSTING_READ(TV_CTL); 1648 1649 /* For unknown reasons the hw barfs if we don't do this vblank wait. */ 1650 intel_wait_for_vblank(dev_priv, intel_crtc->pipe); 1651 1652 /* Restore interrupt config */ 1653 if (connector->polled & DRM_CONNECTOR_POLL_HPD) { 1654 spin_lock_irq(&dev_priv->irq_lock); 1655 i915_enable_pipestat(dev_priv, 0, 1656 PIPE_HOTPLUG_INTERRUPT_STATUS | 1657 PIPE_HOTPLUG_TV_INTERRUPT_STATUS); 1658 spin_unlock_irq(&dev_priv->irq_lock); 1659 } 1660 1661 return type; 1662} 1663 1664/* 1665 * Here we set accurate tv format according to connector type 1666 * i.e Component TV should not be assigned by NTSC or PAL 1667 */ 1668static void intel_tv_find_better_format(struct drm_connector *connector) 1669{ 1670 struct intel_tv *intel_tv = intel_attached_tv(to_intel_connector(connector)); 1671 const struct tv_mode *tv_mode = intel_tv_mode_find(connector->state); 1672 int i; 1673 1674 /* Component supports everything so we can keep the current mode */ 1675 if (intel_tv->type == DRM_MODE_CONNECTOR_Component) 1676 return; 1677 1678 /* If the current mode is fine don't change it */ 1679 if (!tv_mode->component_only) 1680 return; 1681 1682 for (i = 0; i < ARRAY_SIZE(tv_modes); i++) { 1683 tv_mode = &tv_modes[i]; 1684 1685 if (!tv_mode->component_only) 1686 break; 1687 } 1688 1689 connector->state->tv.mode = i; 1690} 1691 1692static int 1693intel_tv_detect(struct drm_connector *connector, 1694 struct drm_modeset_acquire_ctx *ctx, 1695 bool force) 1696{ 1697 struct intel_tv *intel_tv = intel_attached_tv(to_intel_connector(connector)); 1698 enum drm_connector_status status; 1699 int type; 1700 1701 DRM_DEBUG_KMS("[CONNECTOR:%d:%s] force=%d\n", 1702 connector->base.id, connector->name, 1703 force); 1704 1705 if (force) { 1706 struct intel_load_detect_pipe tmp; 1707 int ret; 1708 1709 ret = intel_get_load_detect_pipe(connector, &tmp, ctx); 1710 if (ret < 0) 1711 return ret; 1712 1713 if (ret > 0) { 1714 type = intel_tv_detect_type(intel_tv, connector); 1715 intel_release_load_detect_pipe(connector, &tmp, ctx); 1716 status = type < 0 ? 1717 connector_status_disconnected : 1718 connector_status_connected; 1719 } else 1720 status = connector_status_unknown; 1721 1722 if (status == connector_status_connected) { 1723 intel_tv->type = type; 1724 intel_tv_find_better_format(connector); 1725 } 1726 1727 return status; 1728 } else 1729 return connector->status; 1730} 1731 1732static const struct input_res { 1733 u16 w, h; 1734} input_res_table[] = { 1735 { 640, 480 }, 1736 { 800, 600 }, 1737 { 1024, 768 }, 1738 { 1280, 1024 }, 1739 { 848, 480 }, 1740 { 1280, 720 }, 1741 { 1920, 1080 }, 1742}; 1743 1744/* Choose preferred mode according to line number of TV format */ 1745static bool 1746intel_tv_is_preferred_mode(const struct drm_display_mode *mode, 1747 const struct tv_mode *tv_mode) 1748{ 1749 int vdisplay = intel_tv_mode_vdisplay(tv_mode); 1750 1751 /* prefer 480 line modes for all SD TV modes */ 1752 if (vdisplay <= 576) 1753 vdisplay = 480; 1754 1755 return vdisplay == mode->vdisplay; 1756} 1757 1758static void 1759intel_tv_set_mode_type(struct drm_display_mode *mode, 1760 const struct tv_mode *tv_mode) 1761{ 1762 mode->type = DRM_MODE_TYPE_DRIVER; 1763 1764 if (intel_tv_is_preferred_mode(mode, tv_mode)) 1765 mode->type |= DRM_MODE_TYPE_PREFERRED; 1766} 1767 1768static int 1769intel_tv_get_modes(struct drm_connector *connector) 1770{ 1771 struct drm_i915_private *dev_priv = to_i915(connector->dev); 1772 const struct tv_mode *tv_mode = intel_tv_mode_find(connector->state); 1773 int i, count = 0; 1774 1775 for (i = 0; i < ARRAY_SIZE(input_res_table); i++) { 1776 const struct input_res *input = &input_res_table[i]; 1777 struct drm_display_mode *mode; 1778 1779 if (input->w > 1024 && 1780 !tv_mode->progressive && 1781 !tv_mode->component_only) 1782 continue; 1783 1784 /* no vertical scaling with wide sources on gen3 */ 1785 if (IS_GEN(dev_priv, 3) && input->w > 1024 && 1786 input->h > intel_tv_mode_vdisplay(tv_mode)) 1787 continue; 1788 1789 mode = drm_mode_create(connector->dev); 1790 if (!mode) 1791 continue; 1792 1793 /* 1794 * We take the TV mode and scale it to look 1795 * like it had the expected h/vdisplay. This 1796 * provides the most information to userspace 1797 * about the actual timings of the mode. We 1798 * do ignore the margins though. 1799 */ 1800 intel_tv_mode_to_mode(mode, tv_mode); 1801 if (count == 0) { 1802 DRM_DEBUG_KMS("TV mode:\n"); 1803 drm_mode_debug_printmodeline(mode); 1804 } 1805 intel_tv_scale_mode_horiz(mode, input->w, 0, 0); 1806 intel_tv_scale_mode_vert(mode, input->h, 0, 0); 1807 intel_tv_set_mode_type(mode, tv_mode); 1808 1809 drm_mode_set_name(mode); 1810 1811 drm_mode_probed_add(connector, mode); 1812 count++; 1813 } 1814 1815 return count; 1816} 1817 1818static const struct drm_connector_funcs intel_tv_connector_funcs = { 1819 .late_register = intel_connector_register, 1820 .early_unregister = intel_connector_unregister, 1821 .destroy = intel_connector_destroy, 1822 .fill_modes = drm_helper_probe_single_connector_modes, 1823 .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, 1824 .atomic_duplicate_state = intel_tv_connector_duplicate_state, 1825}; 1826 1827static int intel_tv_atomic_check(struct drm_connector *connector, 1828 struct drm_atomic_state *state) 1829{ 1830 struct drm_connector_state *new_state; 1831 struct drm_crtc_state *new_crtc_state; 1832 struct drm_connector_state *old_state; 1833 1834 new_state = drm_atomic_get_new_connector_state(state, connector); 1835 if (!new_state->crtc) 1836 return 0; 1837 1838 old_state = drm_atomic_get_old_connector_state(state, connector); 1839 new_crtc_state = drm_atomic_get_new_crtc_state(state, new_state->crtc); 1840 1841 if (old_state->tv.mode != new_state->tv.mode || 1842 old_state->tv.margins.left != new_state->tv.margins.left || 1843 old_state->tv.margins.right != new_state->tv.margins.right || 1844 old_state->tv.margins.top != new_state->tv.margins.top || 1845 old_state->tv.margins.bottom != new_state->tv.margins.bottom) { 1846 /* Force a modeset. */ 1847 1848 new_crtc_state->connectors_changed = true; 1849 } 1850 1851 return 0; 1852} 1853 1854static const struct drm_connector_helper_funcs intel_tv_connector_helper_funcs = { 1855 .detect_ctx = intel_tv_detect, 1856 .mode_valid = intel_tv_mode_valid, 1857 .get_modes = intel_tv_get_modes, 1858 .atomic_check = intel_tv_atomic_check, 1859}; 1860 1861static const struct drm_encoder_funcs intel_tv_enc_funcs = { 1862 .destroy = intel_encoder_destroy, 1863}; 1864 1865void 1866intel_tv_init(struct drm_i915_private *dev_priv) 1867{ 1868 struct drm_device *dev = &dev_priv->drm; 1869 struct drm_connector *connector; 1870 struct intel_tv *intel_tv; 1871 struct intel_encoder *intel_encoder; 1872 struct intel_connector *intel_connector; 1873 u32 tv_dac_on, tv_dac_off, save_tv_dac; 1874 const char *tv_format_names[ARRAY_SIZE(tv_modes)]; 1875 int i, initial_mode = 0; 1876 struct drm_connector_state *state; 1877 1878 if ((I915_READ(TV_CTL) & TV_FUSE_STATE_MASK) == TV_FUSE_STATE_DISABLED) 1879 return; 1880 1881 if (!intel_bios_is_tv_present(dev_priv)) { 1882 DRM_DEBUG_KMS("Integrated TV is not present.\n"); 1883 return; 1884 } 1885 1886 /* 1887 * Sanity check the TV output by checking to see if the 1888 * DAC register holds a value 1889 */ 1890 save_tv_dac = I915_READ(TV_DAC); 1891 1892 I915_WRITE(TV_DAC, save_tv_dac | TVDAC_STATE_CHG_EN); 1893 tv_dac_on = I915_READ(TV_DAC); 1894 1895 I915_WRITE(TV_DAC, save_tv_dac & ~TVDAC_STATE_CHG_EN); 1896 tv_dac_off = I915_READ(TV_DAC); 1897 1898 I915_WRITE(TV_DAC, save_tv_dac); 1899 1900 /* 1901 * If the register does not hold the state change enable 1902 * bit, (either as a 0 or a 1), assume it doesn't really 1903 * exist 1904 */ 1905 if ((tv_dac_on & TVDAC_STATE_CHG_EN) == 0 || 1906 (tv_dac_off & TVDAC_STATE_CHG_EN) != 0) 1907 return; 1908 1909 intel_tv = kzalloc(sizeof(*intel_tv), GFP_KERNEL); 1910 if (!intel_tv) { 1911 return; 1912 } 1913 1914 intel_connector = intel_connector_alloc(); 1915 if (!intel_connector) { 1916 kfree(intel_tv); 1917 return; 1918 } 1919 1920 intel_encoder = &intel_tv->base; 1921 connector = &intel_connector->base; 1922 state = connector->state; 1923 1924 /* 1925 * The documentation, for the older chipsets at least, recommend 1926 * using a polling method rather than hotplug detection for TVs. 1927 * This is because in order to perform the hotplug detection, the PLLs 1928 * for the TV must be kept alive increasing power drain and starving 1929 * bandwidth from other encoders. Notably for instance, it causes 1930 * pipe underruns on Crestline when this encoder is supposedly idle. 1931 * 1932 * More recent chipsets favour HDMI rather than integrated S-Video. 1933 */ 1934 intel_connector->polled = DRM_CONNECTOR_POLL_CONNECT; 1935 1936 drm_connector_init(dev, connector, &intel_tv_connector_funcs, 1937 DRM_MODE_CONNECTOR_SVIDEO); 1938 1939 drm_encoder_init(dev, &intel_encoder->base, &intel_tv_enc_funcs, 1940 DRM_MODE_ENCODER_TVDAC, "TV"); 1941 1942 intel_encoder->compute_config = intel_tv_compute_config; 1943 intel_encoder->get_config = intel_tv_get_config; 1944 intel_encoder->pre_enable = intel_tv_pre_enable; 1945 intel_encoder->enable = intel_enable_tv; 1946 intel_encoder->disable = intel_disable_tv; 1947 intel_encoder->get_hw_state = intel_tv_get_hw_state; 1948 intel_connector->get_hw_state = intel_connector_get_hw_state; 1949 1950 intel_connector_attach_encoder(intel_connector, intel_encoder); 1951 1952 intel_encoder->type = INTEL_OUTPUT_TVOUT; 1953 intel_encoder->power_domain = POWER_DOMAIN_PORT_OTHER; 1954 intel_encoder->port = PORT_NONE; 1955 intel_encoder->pipe_mask = ~0; 1956 intel_encoder->cloneable = 0; 1957 intel_tv->type = DRM_MODE_CONNECTOR_Unknown; 1958 1959 /* BIOS margin values */ 1960 state->tv.margins.left = 54; 1961 state->tv.margins.top = 36; 1962 state->tv.margins.right = 46; 1963 state->tv.margins.bottom = 37; 1964 1965 state->tv.mode = initial_mode; 1966 1967 drm_connector_helper_add(connector, &intel_tv_connector_helper_funcs); 1968 connector->interlace_allowed = false; 1969 connector->doublescan_allowed = false; 1970 1971 /* Create TV properties then attach current values */ 1972 for (i = 0; i < ARRAY_SIZE(tv_modes); i++) { 1973 /* 1080p50/1080p60 not supported on gen3 */ 1974 if (IS_GEN(dev_priv, 3) && 1975 tv_modes[i].oversample == 1) 1976 break; 1977 1978 tv_format_names[i] = tv_modes[i].name; 1979 } 1980 drm_mode_create_tv_properties(dev, i, tv_format_names); 1981 1982 drm_object_attach_property(&connector->base, dev->mode_config.tv_mode_property, 1983 state->tv.mode); 1984 drm_object_attach_property(&connector->base, 1985 dev->mode_config.tv_left_margin_property, 1986 state->tv.margins.left); 1987 drm_object_attach_property(&connector->base, 1988 dev->mode_config.tv_top_margin_property, 1989 state->tv.margins.top); 1990 drm_object_attach_property(&connector->base, 1991 dev->mode_config.tv_right_margin_property, 1992 state->tv.margins.right); 1993 drm_object_attach_property(&connector->base, 1994 dev->mode_config.tv_bottom_margin_property, 1995 state->tv.margins.bottom); 1996} 1997