File Index
Files and directories
Sign in
FILE

intel_tv.c

File preview with syntax highlighting.

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