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