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