Linux Audio

Check our new training course

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