Linux Audio

Check our new training course

Linux kernel drivers training

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