Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Copyright © 2006-2008 Intel Corporation
0003  *   Jesse Barnes <jesse.barnes@intel.com>
0004  *
0005  * Permission is hereby granted, free of charge, to any person obtaining a
0006  * copy of this software and associated documentation files (the "Software"),
0007  * to deal in the Software without restriction, including without limitation
0008  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
0009  * and/or sell copies of the Software, and to permit persons to whom the
0010  * Software is furnished to do so, subject to the following conditions:
0011  *
0012  * The above copyright notice and this permission notice (including the next
0013  * paragraph) shall be included in all copies or substantial portions of the
0014  * Software.
0015  *
0016  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
0017  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
0018  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
0019  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
0020  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
0021  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
0022  * DEALINGS IN THE SOFTWARE.
0023  *
0024  * Authors:
0025  *    Eric Anholt <eric@anholt.net>
0026  *
0027  */
0028 
0029 /** @file
0030  * Integrated TV-out support for the 915GM and 945GM.
0031  */
0032 
0033 #include <drm/drm_atomic_helper.h>
0034 #include <drm/drm_crtc.h>
0035 #include <drm/drm_edid.h>
0036 
0037 #include "i915_drv.h"
0038 #include "intel_connector.h"
0039 #include "intel_crtc.h"
0040 #include "intel_de.h"
0041 #include "intel_display_types.h"
0042 #include "intel_hotplug.h"
0043 #include "intel_tv.h"
0044 
0045 enum tv_margin {
0046     TV_MARGIN_LEFT, TV_MARGIN_TOP,
0047     TV_MARGIN_RIGHT, TV_MARGIN_BOTTOM
0048 };
0049 
0050 struct intel_tv {
0051     struct intel_encoder base;
0052 
0053     int type;
0054 };
0055 
0056 struct video_levels {
0057     u16 blank, black;
0058     u8 burst;
0059 };
0060 
0061 struct color_conversion {
0062     u16 ry, gy, by, ay;
0063     u16 ru, gu, bu, au;
0064     u16 rv, gv, bv, av;
0065 };
0066 
0067 static const u32 filter_table[] = {
0068     0xB1403000, 0x2E203500, 0x35002E20, 0x3000B140,
0069     0x35A0B160, 0x2DC02E80, 0xB1403480, 0xB1603000,
0070     0x2EA03640, 0x34002D80, 0x3000B120, 0x36E0B160,
0071     0x2D202EF0, 0xB1203380, 0xB1603000, 0x2F303780,
0072     0x33002CC0, 0x3000B100, 0x3820B160, 0x2C802F50,
0073     0xB10032A0, 0xB1603000, 0x2F9038C0, 0x32202C20,
0074     0x3000B0E0, 0x3980B160, 0x2BC02FC0, 0xB0E031C0,
0075     0xB1603000, 0x2FF03A20, 0x31602B60, 0xB020B0C0,
0076     0x3AE0B160, 0x2B001810, 0xB0C03120, 0xB140B020,
0077     0x18283BA0, 0x30C02A80, 0xB020B0A0, 0x3C60B140,
0078     0x2A201838, 0xB0A03080, 0xB120B020, 0x18383D20,
0079     0x304029C0, 0xB040B080, 0x3DE0B100, 0x29601848,
0080     0xB0803000, 0xB100B040, 0x18483EC0, 0xB0402900,
0081     0xB040B060, 0x3F80B0C0, 0x28801858, 0xB060B080,
0082     0xB0A0B060, 0x18602820, 0xB0A02820, 0x0000B060,
0083     0xB1403000, 0x2E203500, 0x35002E20, 0x3000B140,
0084     0x35A0B160, 0x2DC02E80, 0xB1403480, 0xB1603000,
0085     0x2EA03640, 0x34002D80, 0x3000B120, 0x36E0B160,
0086     0x2D202EF0, 0xB1203380, 0xB1603000, 0x2F303780,
0087     0x33002CC0, 0x3000B100, 0x3820B160, 0x2C802F50,
0088     0xB10032A0, 0xB1603000, 0x2F9038C0, 0x32202C20,
0089     0x3000B0E0, 0x3980B160, 0x2BC02FC0, 0xB0E031C0,
0090     0xB1603000, 0x2FF03A20, 0x31602B60, 0xB020B0C0,
0091     0x3AE0B160, 0x2B001810, 0xB0C03120, 0xB140B020,
0092     0x18283BA0, 0x30C02A80, 0xB020B0A0, 0x3C60B140,
0093     0x2A201838, 0xB0A03080, 0xB120B020, 0x18383D20,
0094     0x304029C0, 0xB040B080, 0x3DE0B100, 0x29601848,
0095     0xB0803000, 0xB100B040, 0x18483EC0, 0xB0402900,
0096     0xB040B060, 0x3F80B0C0, 0x28801858, 0xB060B080,
0097     0xB0A0B060, 0x18602820, 0xB0A02820, 0x0000B060,
0098     0x36403000, 0x2D002CC0, 0x30003640, 0x2D0036C0,
0099     0x35C02CC0, 0x37403000, 0x2C802D40, 0x30003540,
0100     0x2D8037C0, 0x34C02C40, 0x38403000, 0x2BC02E00,
0101     0x30003440, 0x2E2038C0, 0x34002B80, 0x39803000,
0102     0x2B402E40, 0x30003380, 0x2E603A00, 0x33402B00,
0103     0x3A803040, 0x2A802EA0, 0x30403300, 0x2EC03B40,
0104     0x32802A40, 0x3C003040, 0x2A002EC0, 0x30803240,
0105     0x2EC03C80, 0x320029C0, 0x3D403080, 0x29402F00,
0106     0x308031C0, 0x2F203DC0, 0x31802900, 0x3E8030C0,
0107     0x28802F40, 0x30C03140, 0x2F203F40, 0x31402840,
0108     0x28003100, 0x28002F00, 0x00003100, 0x36403000,
0109     0x2D002CC0, 0x30003640, 0x2D0036C0,
0110     0x35C02CC0, 0x37403000, 0x2C802D40, 0x30003540,
0111     0x2D8037C0, 0x34C02C40, 0x38403000, 0x2BC02E00,
0112     0x30003440, 0x2E2038C0, 0x34002B80, 0x39803000,
0113     0x2B402E40, 0x30003380, 0x2E603A00, 0x33402B00,
0114     0x3A803040, 0x2A802EA0, 0x30403300, 0x2EC03B40,
0115     0x32802A40, 0x3C003040, 0x2A002EC0, 0x30803240,
0116     0x2EC03C80, 0x320029C0, 0x3D403080, 0x29402F00,
0117     0x308031C0, 0x2F203DC0, 0x31802900, 0x3E8030C0,
0118     0x28802F40, 0x30C03140, 0x2F203F40, 0x31402840,
0119     0x28003100, 0x28002F00, 0x00003100,
0120 };
0121 
0122 /*
0123  * Color conversion values have 3 separate fixed point formats:
0124  *
0125  * 10 bit fields (ay, au)
0126  *   1.9 fixed point (b.bbbbbbbbb)
0127  * 11 bit fields (ry, by, ru, gu, gv)
0128  *   exp.mantissa (ee.mmmmmmmmm)
0129  *   ee = 00 = 10^-1 (0.mmmmmmmmm)
0130  *   ee = 01 = 10^-2 (0.0mmmmmmmmm)
0131  *   ee = 10 = 10^-3 (0.00mmmmmmmmm)
0132  *   ee = 11 = 10^-4 (0.000mmmmmmmmm)
0133  * 12 bit fields (gy, rv, bu)
0134  *   exp.mantissa (eee.mmmmmmmmm)
0135  *   eee = 000 = 10^-1 (0.mmmmmmmmm)
0136  *   eee = 001 = 10^-2 (0.0mmmmmmmmm)
0137  *   eee = 010 = 10^-3 (0.00mmmmmmmmm)
0138  *   eee = 011 = 10^-4 (0.000mmmmmmmmm)
0139  *   eee = 100 = reserved
0140  *   eee = 101 = reserved
0141  *   eee = 110 = reserved
0142  *   eee = 111 = 10^0 (m.mmmmmmmm) (only usable for 1.0 representation)
0143  *
0144  * Saturation and contrast are 8 bits, with their own representation:
0145  * 8 bit field (saturation, contrast)
0146  *   exp.mantissa (ee.mmmmmm)
0147  *   ee = 00 = 10^-1 (0.mmmmmm)
0148  *   ee = 01 = 10^0 (m.mmmmm)
0149  *   ee = 10 = 10^1 (mm.mmmm)
0150  *   ee = 11 = 10^2 (mmm.mmm)
0151  *
0152  * Simple conversion function:
0153  *
0154  * static u32
0155  * float_to_csc_11(float f)
0156  * {
0157  *     u32 exp;
0158  *     u32 mant;
0159  *     u32 ret;
0160  *
0161  *     if (f < 0)
0162  *         f = -f;
0163  *
0164  *     if (f >= 1) {
0165  *         exp = 0x7;
0166  *     mant = 1 << 8;
0167  *     } else {
0168  *         for (exp = 0; exp < 3 && f < 0.5; exp++)
0169  *     f *= 2.0;
0170  *         mant = (f * (1 << 9) + 0.5);
0171  *         if (mant >= (1 << 9))
0172  *             mant = (1 << 9) - 1;
0173  *     }
0174  *     ret = (exp << 9) | mant;
0175  *     return ret;
0176  * }
0177  */
0178 
0179 /*
0180  * Behold, magic numbers!  If we plant them they might grow a big
0181  * s-video cable to the sky... or something.
0182  *
0183  * Pre-converted to appropriate hex value.
0184  */
0185 
0186 /*
0187  * PAL & NTSC values for composite & s-video connections
0188  */
0189 static const struct color_conversion ntsc_m_csc_composite = {
0190     .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0104,
0191     .ru = 0x0733, .gu = 0x052d, .bu = 0x05c7, .au = 0x0200,
0192     .rv = 0x0340, .gv = 0x030c, .bv = 0x06d0, .av = 0x0200,
0193 };
0194 
0195 static const struct video_levels ntsc_m_levels_composite = {
0196     .blank = 225, .black = 267, .burst = 113,
0197 };
0198 
0199 static const struct color_conversion ntsc_m_csc_svideo = {
0200     .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0133,
0201     .ru = 0x076a, .gu = 0x0564, .bu = 0x030d, .au = 0x0200,
0202     .rv = 0x037a, .gv = 0x033d, .bv = 0x06f6, .av = 0x0200,
0203 };
0204 
0205 static const struct video_levels ntsc_m_levels_svideo = {
0206     .blank = 266, .black = 316, .burst = 133,
0207 };
0208 
0209 static const struct color_conversion ntsc_j_csc_composite = {
0210     .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0119,
0211     .ru = 0x074c, .gu = 0x0546, .bu = 0x05ec, .au = 0x0200,
0212     .rv = 0x035a, .gv = 0x0322, .bv = 0x06e1, .av = 0x0200,
0213 };
0214 
0215 static const struct video_levels ntsc_j_levels_composite = {
0216     .blank = 225, .black = 225, .burst = 113,
0217 };
0218 
0219 static const struct color_conversion ntsc_j_csc_svideo = {
0220     .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x014c,
0221     .ru = 0x0788, .gu = 0x0581, .bu = 0x0322, .au = 0x0200,
0222     .rv = 0x0399, .gv = 0x0356, .bv = 0x070a, .av = 0x0200,
0223 };
0224 
0225 static const struct video_levels ntsc_j_levels_svideo = {
0226     .blank = 266, .black = 266, .burst = 133,
0227 };
0228 
0229 static const struct color_conversion pal_csc_composite = {
0230     .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0113,
0231     .ru = 0x0745, .gu = 0x053f, .bu = 0x05e1, .au = 0x0200,
0232     .rv = 0x0353, .gv = 0x031c, .bv = 0x06dc, .av = 0x0200,
0233 };
0234 
0235 static const struct video_levels pal_levels_composite = {
0236     .blank = 237, .black = 237, .burst = 118,
0237 };
0238 
0239 static const struct color_conversion pal_csc_svideo = {
0240     .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0145,
0241     .ru = 0x0780, .gu = 0x0579, .bu = 0x031c, .au = 0x0200,
0242     .rv = 0x0390, .gv = 0x034f, .bv = 0x0705, .av = 0x0200,
0243 };
0244 
0245 static const struct video_levels pal_levels_svideo = {
0246     .blank = 280, .black = 280, .burst = 139,
0247 };
0248 
0249 static const struct color_conversion pal_m_csc_composite = {
0250     .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0104,
0251     .ru = 0x0733, .gu = 0x052d, .bu = 0x05c7, .au = 0x0200,
0252     .rv = 0x0340, .gv = 0x030c, .bv = 0x06d0, .av = 0x0200,
0253 };
0254 
0255 static const struct video_levels pal_m_levels_composite = {
0256     .blank = 225, .black = 267, .burst = 113,
0257 };
0258 
0259 static const struct color_conversion pal_m_csc_svideo = {
0260     .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0133,
0261     .ru = 0x076a, .gu = 0x0564, .bu = 0x030d, .au = 0x0200,
0262     .rv = 0x037a, .gv = 0x033d, .bv = 0x06f6, .av = 0x0200,
0263 };
0264 
0265 static const struct video_levels pal_m_levels_svideo = {
0266     .blank = 266, .black = 316, .burst = 133,
0267 };
0268 
0269 static const struct color_conversion pal_n_csc_composite = {
0270     .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0104,
0271     .ru = 0x0733, .gu = 0x052d, .bu = 0x05c7, .au = 0x0200,
0272     .rv = 0x0340, .gv = 0x030c, .bv = 0x06d0, .av = 0x0200,
0273 };
0274 
0275 static const struct video_levels pal_n_levels_composite = {
0276     .blank = 225, .black = 267, .burst = 118,
0277 };
0278 
0279 static const struct color_conversion pal_n_csc_svideo = {
0280     .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0133,
0281     .ru = 0x076a, .gu = 0x0564, .bu = 0x030d, .au = 0x0200,
0282     .rv = 0x037a, .gv = 0x033d, .bv = 0x06f6, .av = 0x0200,
0283 };
0284 
0285 static const struct video_levels pal_n_levels_svideo = {
0286     .blank = 266, .black = 316, .burst = 139,
0287 };
0288 
0289 /*
0290  * Component connections
0291  */
0292 static const struct color_conversion sdtv_csc_yprpb = {
0293     .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0145,
0294     .ru = 0x0559, .gu = 0x0353, .bu = 0x0100, .au = 0x0200,
0295     .rv = 0x0100, .gv = 0x03ad, .bv = 0x074d, .av = 0x0200,
0296 };
0297 
0298 static const struct color_conversion hdtv_csc_yprpb = {
0299     .ry = 0x05b3, .gy = 0x016e, .by = 0x0728, .ay = 0x0145,
0300     .ru = 0x07d5, .gu = 0x038b, .bu = 0x0100, .au = 0x0200,
0301     .rv = 0x0100, .gv = 0x03d1, .bv = 0x06bc, .av = 0x0200,
0302 };
0303 
0304 static const struct video_levels component_levels = {
0305     .blank = 279, .black = 279, .burst = 0,
0306 };
0307 
0308 
0309 struct tv_mode {
0310     const char *name;
0311 
0312     u32 clock;
0313     u16 refresh; /* in millihertz (for precision) */
0314     u8 oversample;
0315     u8 hsync_end;
0316     u16 hblank_start, hblank_end, htotal;
0317     bool progressive : 1, trilevel_sync : 1, component_only : 1;
0318     u8 vsync_start_f1, vsync_start_f2, vsync_len;
0319     bool veq_ena : 1;
0320     u8 veq_start_f1, veq_start_f2, veq_len;
0321     u8 vi_end_f1, vi_end_f2;
0322     u16 nbr_end;
0323     bool burst_ena : 1;
0324     u8 hburst_start, hburst_len;
0325     u8 vburst_start_f1;
0326     u16 vburst_end_f1;
0327     u8 vburst_start_f2;
0328     u16 vburst_end_f2;
0329     u8 vburst_start_f3;
0330     u16 vburst_end_f3;
0331     u8 vburst_start_f4;
0332     u16 vburst_end_f4;
0333     /*
0334      * subcarrier programming
0335      */
0336     u16 dda2_size, dda3_size;
0337     u8 dda1_inc;
0338     u16 dda2_inc, dda3_inc;
0339     u32 sc_reset;
0340     bool pal_burst : 1;
0341     /*
0342      * blank/black levels
0343      */
0344     const struct video_levels *composite_levels, *svideo_levels;
0345     const struct color_conversion *composite_color, *svideo_color;
0346     const u32 *filter_table;
0347 };
0348 
0349 
0350 /*
0351  * Sub carrier DDA
0352  *
0353  *  I think this works as follows:
0354  *
0355  *  subcarrier freq = pixel_clock * (dda1_inc + dda2_inc / dda2_size) / 4096
0356  *
0357  * Presumably, when dda3 is added in, it gets to adjust the dda2_inc value
0358  *
0359  * So,
0360  *  dda1_ideal = subcarrier/pixel * 4096
0361  *  dda1_inc = floor (dda1_ideal)
0362  *  dda2 = dda1_ideal - dda1_inc
0363  *
0364  *  then pick a ratio for dda2 that gives the closest approximation. If
0365  *  you can't get close enough, you can play with dda3 as well. This
0366  *  seems likely to happen when dda2 is small as the jumps would be larger
0367  *
0368  * To invert this,
0369  *
0370  *  pixel_clock = subcarrier * 4096 / (dda1_inc + dda2_inc / dda2_size)
0371  *
0372  * The constants below were all computed using a 107.520MHz clock
0373  */
0374 
0375 /*
0376  * Register programming values for TV modes.
0377  *
0378  * These values account for -1s required.
0379  */
0380 static const struct tv_mode tv_modes[] = {
0381     {
0382         .name       = "NTSC-M",
0383         .clock      = 108000,
0384         .refresh    = 59940,
0385         .oversample = 8,
0386         .component_only = false,
0387         /* 525 Lines, 60 Fields, 15.734KHz line, Sub-Carrier 3.580MHz */
0388 
0389         .hsync_end  = 64,           .hblank_end     = 124,
0390         .hblank_start   = 836,          .htotal     = 857,
0391 
0392         .progressive    = false,        .trilevel_sync = false,
0393 
0394         .vsync_start_f1 = 6,            .vsync_start_f2 = 7,
0395         .vsync_len  = 6,
0396 
0397         .veq_ena    = true,         .veq_start_f1   = 0,
0398         .veq_start_f2   = 1,            .veq_len        = 18,
0399 
0400         .vi_end_f1  = 20,           .vi_end_f2      = 21,
0401         .nbr_end    = 240,
0402 
0403         .burst_ena  = true,
0404         .hburst_start   = 72,           .hburst_len     = 34,
0405         .vburst_start_f1 = 9,           .vburst_end_f1  = 240,
0406         .vburst_start_f2 = 10,          .vburst_end_f2  = 240,
0407         .vburst_start_f3 = 9,           .vburst_end_f3  = 240,
0408         .vburst_start_f4 = 10,          .vburst_end_f4  = 240,
0409 
0410         /* desired 3.5800000 actual 3.5800000 clock 107.52 */
0411         .dda1_inc   =    135,
0412         .dda2_inc   =  20800,       .dda2_size      =  27456,
0413         .dda3_inc   =      0,       .dda3_size      =      0,
0414         .sc_reset   = TV_SC_RESET_EVERY_4,
0415         .pal_burst  = false,
0416 
0417         .composite_levels = &ntsc_m_levels_composite,
0418         .composite_color = &ntsc_m_csc_composite,
0419         .svideo_levels  = &ntsc_m_levels_svideo,
0420         .svideo_color = &ntsc_m_csc_svideo,
0421 
0422         .filter_table = filter_table,
0423     },
0424     {
0425         .name       = "NTSC-443",
0426         .clock      = 108000,
0427         .refresh    = 59940,
0428         .oversample = 8,
0429         .component_only = false,
0430         /* 525 Lines, 60 Fields, 15.734KHz line, Sub-Carrier 4.43MHz */
0431         .hsync_end  = 64,           .hblank_end     = 124,
0432         .hblank_start   = 836,          .htotal     = 857,
0433 
0434         .progressive    = false,        .trilevel_sync = false,
0435 
0436         .vsync_start_f1 = 6,            .vsync_start_f2 = 7,
0437         .vsync_len  = 6,
0438 
0439         .veq_ena    = true,         .veq_start_f1   = 0,
0440         .veq_start_f2   = 1,            .veq_len        = 18,
0441 
0442         .vi_end_f1  = 20,           .vi_end_f2      = 21,
0443         .nbr_end    = 240,
0444 
0445         .burst_ena  = true,
0446         .hburst_start   = 72,           .hburst_len     = 34,
0447         .vburst_start_f1 = 9,           .vburst_end_f1  = 240,
0448         .vburst_start_f2 = 10,          .vburst_end_f2  = 240,
0449         .vburst_start_f3 = 9,           .vburst_end_f3  = 240,
0450         .vburst_start_f4 = 10,          .vburst_end_f4  = 240,
0451 
0452         /* desired 4.4336180 actual 4.4336180 clock 107.52 */
0453         .dda1_inc       =    168,
0454         .dda2_inc       =   4093,       .dda2_size      =  27456,
0455         .dda3_inc       =    310,       .dda3_size      =    525,
0456         .sc_reset   = TV_SC_RESET_NEVER,
0457         .pal_burst  = false,
0458 
0459         .composite_levels = &ntsc_m_levels_composite,
0460         .composite_color = &ntsc_m_csc_composite,
0461         .svideo_levels  = &ntsc_m_levels_svideo,
0462         .svideo_color = &ntsc_m_csc_svideo,
0463 
0464         .filter_table = filter_table,
0465     },
0466     {
0467         .name       = "NTSC-J",
0468         .clock      = 108000,
0469         .refresh    = 59940,
0470         .oversample = 8,
0471         .component_only = false,
0472 
0473         /* 525 Lines, 60 Fields, 15.734KHz line, Sub-Carrier 3.580MHz */
0474         .hsync_end  = 64,           .hblank_end     = 124,
0475         .hblank_start = 836,        .htotal     = 857,
0476 
0477         .progressive    = false,    .trilevel_sync = false,
0478 
0479         .vsync_start_f1 = 6,        .vsync_start_f2 = 7,
0480         .vsync_len  = 6,
0481 
0482         .veq_ena      = true,       .veq_start_f1   = 0,
0483         .veq_start_f2 = 1,      .veq_len        = 18,
0484 
0485         .vi_end_f1  = 20,           .vi_end_f2      = 21,
0486         .nbr_end    = 240,
0487 
0488         .burst_ena  = true,
0489         .hburst_start   = 72,           .hburst_len     = 34,
0490         .vburst_start_f1 = 9,           .vburst_end_f1  = 240,
0491         .vburst_start_f2 = 10,          .vburst_end_f2  = 240,
0492         .vburst_start_f3 = 9,           .vburst_end_f3  = 240,
0493         .vburst_start_f4 = 10,          .vburst_end_f4  = 240,
0494 
0495         /* desired 3.5800000 actual 3.5800000 clock 107.52 */
0496         .dda1_inc   =    135,
0497         .dda2_inc   =  20800,       .dda2_size      =  27456,
0498         .dda3_inc   =      0,       .dda3_size      =      0,
0499         .sc_reset   = TV_SC_RESET_EVERY_4,
0500         .pal_burst  = false,
0501 
0502         .composite_levels = &ntsc_j_levels_composite,
0503         .composite_color = &ntsc_j_csc_composite,
0504         .svideo_levels  = &ntsc_j_levels_svideo,
0505         .svideo_color = &ntsc_j_csc_svideo,
0506 
0507         .filter_table = filter_table,
0508     },
0509     {
0510         .name       = "PAL-M",
0511         .clock      = 108000,
0512         .refresh    = 59940,
0513         .oversample = 8,
0514         .component_only = false,
0515 
0516         /* 525 Lines, 60 Fields, 15.734KHz line, Sub-Carrier 3.580MHz */
0517         .hsync_end  = 64,         .hblank_end       = 124,
0518         .hblank_start = 836,      .htotal       = 857,
0519 
0520         .progressive    = false,        .trilevel_sync = false,
0521 
0522         .vsync_start_f1 = 6,            .vsync_start_f2 = 7,
0523         .vsync_len  = 6,
0524 
0525         .veq_ena    = true,         .veq_start_f1   = 0,
0526         .veq_start_f2   = 1,            .veq_len        = 18,
0527 
0528         .vi_end_f1  = 20,           .vi_end_f2      = 21,
0529         .nbr_end    = 240,
0530 
0531         .burst_ena  = true,
0532         .hburst_start   = 72,           .hburst_len     = 34,
0533         .vburst_start_f1 = 9,           .vburst_end_f1  = 240,
0534         .vburst_start_f2 = 10,          .vburst_end_f2  = 240,
0535         .vburst_start_f3 = 9,           .vburst_end_f3  = 240,
0536         .vburst_start_f4 = 10,          .vburst_end_f4  = 240,
0537 
0538         /* desired 3.5800000 actual 3.5800000 clock 107.52 */
0539         .dda1_inc   =    135,
0540         .dda2_inc   =  16704,       .dda2_size      =  27456,
0541         .dda3_inc   =      0,       .dda3_size      =      0,
0542         .sc_reset   = TV_SC_RESET_EVERY_8,
0543         .pal_burst  = true,
0544 
0545         .composite_levels = &pal_m_levels_composite,
0546         .composite_color = &pal_m_csc_composite,
0547         .svideo_levels  = &pal_m_levels_svideo,
0548         .svideo_color = &pal_m_csc_svideo,
0549 
0550         .filter_table = filter_table,
0551     },
0552     {
0553         /* 625 Lines, 50 Fields, 15.625KHz line, Sub-Carrier 4.434MHz */
0554         .name       = "PAL-N",
0555         .clock      = 108000,
0556         .refresh    = 50000,
0557         .oversample = 8,
0558         .component_only = false,
0559 
0560         .hsync_end  = 64,           .hblank_end     = 128,
0561         .hblank_start = 844,        .htotal     = 863,
0562 
0563         .progressive  = false,    .trilevel_sync = false,
0564 
0565 
0566         .vsync_start_f1 = 6,       .vsync_start_f2  = 7,
0567         .vsync_len  = 6,
0568 
0569         .veq_ena    = true,         .veq_start_f1   = 0,
0570         .veq_start_f2   = 1,            .veq_len        = 18,
0571 
0572         .vi_end_f1  = 24,           .vi_end_f2      = 25,
0573         .nbr_end    = 286,
0574 
0575         .burst_ena  = true,
0576         .hburst_start = 73,     .hburst_len     = 34,
0577         .vburst_start_f1 = 8,       .vburst_end_f1  = 285,
0578         .vburst_start_f2 = 8,       .vburst_end_f2  = 286,
0579         .vburst_start_f3 = 9,       .vburst_end_f3  = 286,
0580         .vburst_start_f4 = 9,       .vburst_end_f4  = 285,
0581 
0582 
0583         /* desired 4.4336180 actual 4.4336180 clock 107.52 */
0584         .dda1_inc       =    135,
0585         .dda2_inc       =  23578,       .dda2_size      =  27648,
0586         .dda3_inc       =    134,       .dda3_size      =    625,
0587         .sc_reset   = TV_SC_RESET_EVERY_8,
0588         .pal_burst  = true,
0589 
0590         .composite_levels = &pal_n_levels_composite,
0591         .composite_color = &pal_n_csc_composite,
0592         .svideo_levels  = &pal_n_levels_svideo,
0593         .svideo_color = &pal_n_csc_svideo,
0594 
0595         .filter_table = filter_table,
0596     },
0597     {
0598         /* 625 Lines, 50 Fields, 15.625KHz line, Sub-Carrier 4.434MHz */
0599         .name       = "PAL",
0600         .clock      = 108000,
0601         .refresh    = 50000,
0602         .oversample = 8,
0603         .component_only = false,
0604 
0605         .hsync_end  = 64,           .hblank_end     = 142,
0606         .hblank_start   = 844,      .htotal     = 863,
0607 
0608         .progressive    = false,    .trilevel_sync = false,
0609 
0610         .vsync_start_f1 = 5,        .vsync_start_f2 = 6,
0611         .vsync_len  = 5,
0612 
0613         .veq_ena    = true,     .veq_start_f1   = 0,
0614         .veq_start_f2   = 1,        .veq_len        = 15,
0615 
0616         .vi_end_f1  = 24,           .vi_end_f2      = 25,
0617         .nbr_end    = 286,
0618 
0619         .burst_ena  = true,
0620         .hburst_start   = 73,           .hburst_len     = 32,
0621         .vburst_start_f1 = 8,           .vburst_end_f1  = 285,
0622         .vburst_start_f2 = 8,           .vburst_end_f2  = 286,
0623         .vburst_start_f3 = 9,           .vburst_end_f3  = 286,
0624         .vburst_start_f4 = 9,           .vburst_end_f4  = 285,
0625 
0626         /* desired 4.4336180 actual 4.4336180 clock 107.52 */
0627         .dda1_inc       =    168,
0628         .dda2_inc       =   4122,       .dda2_size      =  27648,
0629         .dda3_inc       =     67,       .dda3_size      =    625,
0630         .sc_reset   = TV_SC_RESET_EVERY_8,
0631         .pal_burst  = true,
0632 
0633         .composite_levels = &pal_levels_composite,
0634         .composite_color = &pal_csc_composite,
0635         .svideo_levels  = &pal_levels_svideo,
0636         .svideo_color = &pal_csc_svideo,
0637 
0638         .filter_table = filter_table,
0639     },
0640     {
0641         .name       = "480p",
0642         .clock      = 108000,
0643         .refresh    = 59940,
0644         .oversample     = 4,
0645         .component_only = true,
0646 
0647         .hsync_end      = 64,               .hblank_end         = 122,
0648         .hblank_start   = 842,              .htotal             = 857,
0649 
0650         .progressive    = true,         .trilevel_sync = false,
0651 
0652         .vsync_start_f1 = 12,               .vsync_start_f2     = 12,
0653         .vsync_len      = 12,
0654 
0655         .veq_ena        = false,
0656 
0657         .vi_end_f1      = 44,               .vi_end_f2          = 44,
0658         .nbr_end        = 479,
0659 
0660         .burst_ena      = false,
0661 
0662         .filter_table = filter_table,
0663     },
0664     {
0665         .name       = "576p",
0666         .clock      = 108000,
0667         .refresh    = 50000,
0668         .oversample     = 4,
0669         .component_only = true,
0670 
0671         .hsync_end      = 64,               .hblank_end         = 139,
0672         .hblank_start   = 859,              .htotal             = 863,
0673 
0674         .progressive    = true,         .trilevel_sync = false,
0675 
0676         .vsync_start_f1 = 10,               .vsync_start_f2     = 10,
0677         .vsync_len      = 10,
0678 
0679         .veq_ena        = false,
0680 
0681         .vi_end_f1      = 48,               .vi_end_f2          = 48,
0682         .nbr_end        = 575,
0683 
0684         .burst_ena      = false,
0685 
0686         .filter_table = filter_table,
0687     },
0688     {
0689         .name       = "720p@60Hz",
0690         .clock      = 148500,
0691         .refresh    = 60000,
0692         .oversample     = 2,
0693         .component_only = true,
0694 
0695         .hsync_end      = 80,               .hblank_end         = 300,
0696         .hblank_start   = 1580,             .htotal             = 1649,
0697 
0698         .progressive    = true,         .trilevel_sync = true,
0699 
0700         .vsync_start_f1 = 10,               .vsync_start_f2     = 10,
0701         .vsync_len      = 10,
0702 
0703         .veq_ena        = false,
0704 
0705         .vi_end_f1      = 29,               .vi_end_f2          = 29,
0706         .nbr_end        = 719,
0707 
0708         .burst_ena      = false,
0709 
0710         .filter_table = filter_table,
0711     },
0712     {
0713         .name       = "720p@50Hz",
0714         .clock      = 148500,
0715         .refresh    = 50000,
0716         .oversample     = 2,
0717         .component_only = true,
0718 
0719         .hsync_end      = 80,               .hblank_end         = 300,
0720         .hblank_start   = 1580,             .htotal             = 1979,
0721 
0722         .progressive    = true,         .trilevel_sync = true,
0723 
0724         .vsync_start_f1 = 10,               .vsync_start_f2     = 10,
0725         .vsync_len      = 10,
0726 
0727         .veq_ena        = false,
0728 
0729         .vi_end_f1      = 29,               .vi_end_f2          = 29,
0730         .nbr_end        = 719,
0731 
0732         .burst_ena      = false,
0733 
0734         .filter_table = filter_table,
0735     },
0736     {
0737         .name       = "1080i@50Hz",
0738         .clock      = 148500,
0739         .refresh    = 50000,
0740         .oversample     = 2,
0741         .component_only = true,
0742 
0743         .hsync_end      = 88,               .hblank_end         = 235,
0744         .hblank_start   = 2155,             .htotal             = 2639,
0745 
0746         .progressive    = false,      .trilevel_sync = true,
0747 
0748         .vsync_start_f1 = 4,              .vsync_start_f2     = 5,
0749         .vsync_len      = 10,
0750 
0751         .veq_ena    = true,     .veq_start_f1   = 4,
0752         .veq_start_f2   = 4,        .veq_len        = 10,
0753 
0754 
0755         .vi_end_f1      = 21,           .vi_end_f2          = 22,
0756         .nbr_end        = 539,
0757 
0758         .burst_ena      = false,
0759 
0760         .filter_table = filter_table,
0761     },
0762     {
0763         .name       = "1080i@60Hz",
0764         .clock      = 148500,
0765         .refresh    = 60000,
0766         .oversample     = 2,
0767         .component_only = true,
0768 
0769         .hsync_end      = 88,               .hblank_end         = 235,
0770         .hblank_start   = 2155,             .htotal             = 2199,
0771 
0772         .progressive    = false,        .trilevel_sync = true,
0773 
0774         .vsync_start_f1 = 4,               .vsync_start_f2     = 5,
0775         .vsync_len      = 10,
0776 
0777         .veq_ena    = true,         .veq_start_f1   = 4,
0778         .veq_start_f2   = 4,            .veq_len        = 10,
0779 
0780 
0781         .vi_end_f1      = 21,               .vi_end_f2          = 22,
0782         .nbr_end        = 539,
0783 
0784         .burst_ena      = false,
0785 
0786         .filter_table = filter_table,
0787     },
0788 
0789     {
0790         .name       = "1080p@30Hz",
0791         .clock      = 148500,
0792         .refresh    = 30000,
0793         .oversample     = 2,
0794         .component_only = true,
0795 
0796         .hsync_end      = 88,               .hblank_end         = 235,
0797         .hblank_start   = 2155,             .htotal             = 2199,
0798 
0799         .progressive    = true,         .trilevel_sync = true,
0800 
0801         .vsync_start_f1 = 8,               .vsync_start_f2     = 8,
0802         .vsync_len      = 10,
0803 
0804         .veq_ena    = false,    .veq_start_f1   = 0,
0805         .veq_start_f2   = 0,            .veq_len        = 0,
0806 
0807         .vi_end_f1      = 44,               .vi_end_f2          = 44,
0808         .nbr_end        = 1079,
0809 
0810         .burst_ena      = false,
0811 
0812         .filter_table = filter_table,
0813     },
0814 
0815     {
0816         .name       = "1080p@50Hz",
0817         .clock      = 148500,
0818         .refresh    = 50000,
0819         .oversample     = 1,
0820         .component_only = true,
0821 
0822         .hsync_end      = 88,               .hblank_end         = 235,
0823         .hblank_start   = 2155,             .htotal             = 2639,
0824 
0825         .progressive    = true,         .trilevel_sync = true,
0826 
0827         .vsync_start_f1 = 8,               .vsync_start_f2     = 8,
0828         .vsync_len      = 10,
0829 
0830         .veq_ena    = false,    .veq_start_f1   = 0,
0831         .veq_start_f2   = 0,            .veq_len        = 0,
0832 
0833         .vi_end_f1      = 44,               .vi_end_f2          = 44,
0834         .nbr_end        = 1079,
0835 
0836         .burst_ena      = false,
0837 
0838         .filter_table = filter_table,
0839     },
0840 
0841     {
0842         .name       = "1080p@60Hz",
0843         .clock      = 148500,
0844         .refresh    = 60000,
0845         .oversample     = 1,
0846         .component_only = true,
0847 
0848         .hsync_end      = 88,               .hblank_end         = 235,
0849         .hblank_start   = 2155,             .htotal             = 2199,
0850 
0851         .progressive    = true,         .trilevel_sync = true,
0852 
0853         .vsync_start_f1 = 8,               .vsync_start_f2     = 8,
0854         .vsync_len      = 10,
0855 
0856         .veq_ena    = false,            .veq_start_f1   = 0,
0857         .veq_start_f2   = 0,            .veq_len        = 0,
0858 
0859         .vi_end_f1      = 44,               .vi_end_f2          = 44,
0860         .nbr_end        = 1079,
0861 
0862         .burst_ena      = false,
0863 
0864         .filter_table = filter_table,
0865     },
0866 };
0867 
0868 struct intel_tv_connector_state {
0869     struct drm_connector_state base;
0870 
0871     /*
0872      * May need to override the user margins for
0873      * gen3 >1024 wide source vertical centering.
0874      */
0875     struct {
0876         u16 top, bottom;
0877     } margins;
0878 
0879     bool bypass_vfilter;
0880 };
0881 
0882 #define to_intel_tv_connector_state(x) container_of(x, struct intel_tv_connector_state, base)
0883 
0884 static struct drm_connector_state *
0885 intel_tv_connector_duplicate_state(struct drm_connector *connector)
0886 {
0887     struct intel_tv_connector_state *state;
0888 
0889     state = kmemdup(connector->state, sizeof(*state), GFP_KERNEL);
0890     if (!state)
0891         return NULL;
0892 
0893     __drm_atomic_helper_connector_duplicate_state(connector, &state->base);
0894     return &state->base;
0895 }
0896 
0897 static struct intel_tv *enc_to_tv(struct intel_encoder *encoder)
0898 {
0899     return container_of(encoder, struct intel_tv, base);
0900 }
0901 
0902 static struct intel_tv *intel_attached_tv(struct intel_connector *connector)
0903 {
0904     return enc_to_tv(intel_attached_encoder(connector));
0905 }
0906 
0907 static bool
0908 intel_tv_get_hw_state(struct intel_encoder *encoder, enum pipe *pipe)
0909 {
0910     struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
0911     u32 tmp = intel_de_read(dev_priv, TV_CTL);
0912 
0913     *pipe = (tmp & TV_ENC_PIPE_SEL_MASK) >> TV_ENC_PIPE_SEL_SHIFT;
0914 
0915     return tmp & TV_ENC_ENABLE;
0916 }
0917 
0918 static void
0919 intel_enable_tv(struct intel_atomic_state *state,
0920         struct intel_encoder *encoder,
0921         const struct intel_crtc_state *pipe_config,
0922         const struct drm_connector_state *conn_state)
0923 {
0924     struct drm_device *dev = encoder->base.dev;
0925     struct drm_i915_private *dev_priv = to_i915(dev);
0926 
0927     /* Prevents vblank waits from timing out in intel_tv_detect_type() */
0928     intel_crtc_wait_for_next_vblank(to_intel_crtc(pipe_config->uapi.crtc));
0929 
0930     intel_de_write(dev_priv, TV_CTL,
0931                intel_de_read(dev_priv, TV_CTL) | TV_ENC_ENABLE);
0932 }
0933 
0934 static void
0935 intel_disable_tv(struct intel_atomic_state *state,
0936          struct intel_encoder *encoder,
0937          const struct intel_crtc_state *old_crtc_state,
0938          const struct drm_connector_state *old_conn_state)
0939 {
0940     struct drm_device *dev = encoder->base.dev;
0941     struct drm_i915_private *dev_priv = to_i915(dev);
0942 
0943     intel_de_write(dev_priv, TV_CTL,
0944                intel_de_read(dev_priv, TV_CTL) & ~TV_ENC_ENABLE);
0945 }
0946 
0947 static const struct tv_mode *intel_tv_mode_find(const struct drm_connector_state *conn_state)
0948 {
0949     int format = conn_state->tv.mode;
0950 
0951     return &tv_modes[format];
0952 }
0953 
0954 static enum drm_mode_status
0955 intel_tv_mode_valid(struct drm_connector *connector,
0956             struct drm_display_mode *mode)
0957 {
0958     const struct tv_mode *tv_mode = intel_tv_mode_find(connector->state);
0959     int max_dotclk = to_i915(connector->dev)->max_dotclk_freq;
0960 
0961     if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
0962         return MODE_NO_DBLESCAN;
0963 
0964     if (mode->clock > max_dotclk)
0965         return MODE_CLOCK_HIGH;
0966 
0967     /* Ensure TV refresh is close to desired refresh */
0968     if (abs(tv_mode->refresh - drm_mode_vrefresh(mode) * 1000) >= 1000)
0969         return MODE_CLOCK_RANGE;
0970 
0971     return MODE_OK;
0972 }
0973 
0974 static int
0975 intel_tv_mode_vdisplay(const struct tv_mode *tv_mode)
0976 {
0977     if (tv_mode->progressive)
0978         return tv_mode->nbr_end + 1;
0979     else
0980         return 2 * (tv_mode->nbr_end + 1);
0981 }
0982 
0983 static void
0984 intel_tv_mode_to_mode(struct drm_display_mode *mode,
0985               const struct tv_mode *tv_mode)
0986 {
0987     mode->clock = tv_mode->clock /
0988         (tv_mode->oversample >> !tv_mode->progressive);
0989 
0990     /*
0991      * tv_mode horizontal timings:
0992      *
0993      * hsync_end
0994      *    | hblank_end
0995      *    |    | hblank_start
0996      *    |    |       | htotal
0997      *    |     _______    |
0998      *     ____/       \___
0999      * \__/                \
1000      */
1001     mode->hdisplay =
1002         tv_mode->hblank_start - tv_mode->hblank_end;
1003     mode->hsync_start = mode->hdisplay +
1004         tv_mode->htotal - tv_mode->hblank_start;
1005     mode->hsync_end = mode->hsync_start +
1006         tv_mode->hsync_end;
1007     mode->htotal = tv_mode->htotal + 1;
1008 
1009     /*
1010      * tv_mode vertical timings:
1011      *
1012      * vsync_start
1013      *    | vsync_end
1014      *    |  | vi_end nbr_end
1015      *    |  |    |       |
1016      *    |  |     _______
1017      * \__    ____/       \
1018      *    \__/
1019      */
1020     mode->vdisplay = intel_tv_mode_vdisplay(tv_mode);
1021     if (tv_mode->progressive) {
1022         mode->vsync_start = mode->vdisplay +
1023             tv_mode->vsync_start_f1 + 1;
1024         mode->vsync_end = mode->vsync_start +
1025             tv_mode->vsync_len;
1026         mode->vtotal = mode->vdisplay +
1027             tv_mode->vi_end_f1 + 1;
1028     } else {
1029         mode->vsync_start = mode->vdisplay +
1030             tv_mode->vsync_start_f1 + 1 +
1031             tv_mode->vsync_start_f2 + 1;
1032         mode->vsync_end = mode->vsync_start +
1033             2 * tv_mode->vsync_len;
1034         mode->vtotal = mode->vdisplay +
1035             tv_mode->vi_end_f1 + 1 +
1036             tv_mode->vi_end_f2 + 1;
1037     }
1038 
1039     /* TV has it's own notion of sync and other mode flags, so clear them. */
1040     mode->flags = 0;
1041 
1042     snprintf(mode->name, sizeof(mode->name),
1043          "%dx%d%c (%s)",
1044          mode->hdisplay, mode->vdisplay,
1045          tv_mode->progressive ? 'p' : 'i',
1046          tv_mode->name);
1047 }
1048 
1049 static void intel_tv_scale_mode_horiz(struct drm_display_mode *mode,
1050                       int hdisplay, int left_margin,
1051                       int right_margin)
1052 {
1053     int hsync_start = mode->hsync_start - mode->hdisplay + right_margin;
1054     int hsync_end = mode->hsync_end - mode->hdisplay + right_margin;
1055     int new_htotal = mode->htotal * hdisplay /
1056         (mode->hdisplay - left_margin - right_margin);
1057 
1058     mode->clock = mode->clock * new_htotal / mode->htotal;
1059 
1060     mode->hdisplay = hdisplay;
1061     mode->hsync_start = hdisplay + hsync_start * new_htotal / mode->htotal;
1062     mode->hsync_end = hdisplay + hsync_end * new_htotal / mode->htotal;
1063     mode->htotal = new_htotal;
1064 }
1065 
1066 static void intel_tv_scale_mode_vert(struct drm_display_mode *mode,
1067                      int vdisplay, int top_margin,
1068                      int bottom_margin)
1069 {
1070     int vsync_start = mode->vsync_start - mode->vdisplay + bottom_margin;
1071     int vsync_end = mode->vsync_end - mode->vdisplay + bottom_margin;
1072     int new_vtotal = mode->vtotal * vdisplay /
1073         (mode->vdisplay - top_margin - bottom_margin);
1074 
1075     mode->clock = mode->clock * new_vtotal / mode->vtotal;
1076 
1077     mode->vdisplay = vdisplay;
1078     mode->vsync_start = vdisplay + vsync_start * new_vtotal / mode->vtotal;
1079     mode->vsync_end = vdisplay + vsync_end * new_vtotal / mode->vtotal;
1080     mode->vtotal = new_vtotal;
1081 }
1082 
1083 static void
1084 intel_tv_get_config(struct intel_encoder *encoder,
1085             struct intel_crtc_state *pipe_config)
1086 {
1087     struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
1088     struct drm_display_mode *adjusted_mode =
1089         &pipe_config->hw.adjusted_mode;
1090     struct drm_display_mode mode = {};
1091     u32 tv_ctl, hctl1, hctl3, vctl1, vctl2, tmp;
1092     struct tv_mode tv_mode = {};
1093     int hdisplay = adjusted_mode->crtc_hdisplay;
1094     int vdisplay = adjusted_mode->crtc_vdisplay;
1095     int xsize, ysize, xpos, ypos;
1096 
1097     pipe_config->output_types |= BIT(INTEL_OUTPUT_TVOUT);
1098 
1099     tv_ctl = intel_de_read(dev_priv, TV_CTL);
1100     hctl1 = intel_de_read(dev_priv, TV_H_CTL_1);
1101     hctl3 = intel_de_read(dev_priv, TV_H_CTL_3);
1102     vctl1 = intel_de_read(dev_priv, TV_V_CTL_1);
1103     vctl2 = intel_de_read(dev_priv, TV_V_CTL_2);
1104 
1105     tv_mode.htotal = (hctl1 & TV_HTOTAL_MASK) >> TV_HTOTAL_SHIFT;
1106     tv_mode.hsync_end = (hctl1 & TV_HSYNC_END_MASK) >> TV_HSYNC_END_SHIFT;
1107 
1108     tv_mode.hblank_start = (hctl3 & TV_HBLANK_START_MASK) >> TV_HBLANK_START_SHIFT;
1109     tv_mode.hblank_end = (hctl3 & TV_HSYNC_END_MASK) >> TV_HBLANK_END_SHIFT;
1110 
1111     tv_mode.nbr_end = (vctl1 & TV_NBR_END_MASK) >> TV_NBR_END_SHIFT;
1112     tv_mode.vi_end_f1 = (vctl1 & TV_VI_END_F1_MASK) >> TV_VI_END_F1_SHIFT;
1113     tv_mode.vi_end_f2 = (vctl1 & TV_VI_END_F2_MASK) >> TV_VI_END_F2_SHIFT;
1114 
1115     tv_mode.vsync_len = (vctl2 & TV_VSYNC_LEN_MASK) >> TV_VSYNC_LEN_SHIFT;
1116     tv_mode.vsync_start_f1 = (vctl2 & TV_VSYNC_START_F1_MASK) >> TV_VSYNC_START_F1_SHIFT;
1117     tv_mode.vsync_start_f2 = (vctl2 & TV_VSYNC_START_F2_MASK) >> TV_VSYNC_START_F2_SHIFT;
1118 
1119     tv_mode.clock = pipe_config->port_clock;
1120 
1121     tv_mode.progressive = tv_ctl & TV_PROGRESSIVE;
1122 
1123     switch (tv_ctl & TV_OVERSAMPLE_MASK) {
1124     case TV_OVERSAMPLE_8X:
1125         tv_mode.oversample = 8;
1126         break;
1127     case TV_OVERSAMPLE_4X:
1128         tv_mode.oversample = 4;
1129         break;
1130     case TV_OVERSAMPLE_2X:
1131         tv_mode.oversample = 2;
1132         break;
1133     default:
1134         tv_mode.oversample = 1;
1135         break;
1136     }
1137 
1138     tmp = intel_de_read(dev_priv, TV_WIN_POS);
1139     xpos = tmp >> 16;
1140     ypos = tmp & 0xffff;
1141 
1142     tmp = intel_de_read(dev_priv, TV_WIN_SIZE);
1143     xsize = tmp >> 16;
1144     ysize = tmp & 0xffff;
1145 
1146     intel_tv_mode_to_mode(&mode, &tv_mode);
1147 
1148     drm_dbg_kms(&dev_priv->drm, "TV mode: " DRM_MODE_FMT "\n",
1149             DRM_MODE_ARG(&mode));
1150 
1151     intel_tv_scale_mode_horiz(&mode, hdisplay,
1152                   xpos, mode.hdisplay - xsize - xpos);
1153     intel_tv_scale_mode_vert(&mode, vdisplay,
1154                  ypos, mode.vdisplay - ysize - ypos);
1155 
1156     adjusted_mode->crtc_clock = mode.clock;
1157     if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE)
1158         adjusted_mode->crtc_clock /= 2;
1159 
1160     /* pixel counter doesn't work on i965gm TV output */
1161     if (IS_I965GM(dev_priv))
1162         pipe_config->mode_flags |=
1163             I915_MODE_FLAG_USE_SCANLINE_COUNTER;
1164 }
1165 
1166 static bool intel_tv_source_too_wide(struct drm_i915_private *dev_priv,
1167                      int hdisplay)
1168 {
1169     return DISPLAY_VER(dev_priv) == 3 && hdisplay > 1024;
1170 }
1171 
1172 static bool intel_tv_vert_scaling(const struct drm_display_mode *tv_mode,
1173                   const struct drm_connector_state *conn_state,
1174                   int vdisplay)
1175 {
1176     return tv_mode->crtc_vdisplay -
1177         conn_state->tv.margins.top -
1178         conn_state->tv.margins.bottom !=
1179         vdisplay;
1180 }
1181 
1182 static int
1183 intel_tv_compute_config(struct intel_encoder *encoder,
1184             struct intel_crtc_state *pipe_config,
1185             struct drm_connector_state *conn_state)
1186 {
1187     struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
1188     struct intel_tv_connector_state *tv_conn_state =
1189         to_intel_tv_connector_state(conn_state);
1190     const struct tv_mode *tv_mode = intel_tv_mode_find(conn_state);
1191     struct drm_display_mode *adjusted_mode =
1192         &pipe_config->hw.adjusted_mode;
1193     int hdisplay = adjusted_mode->crtc_hdisplay;
1194     int vdisplay = adjusted_mode->crtc_vdisplay;
1195 
1196     if (!tv_mode)
1197         return -EINVAL;
1198 
1199     if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN)
1200         return -EINVAL;
1201 
1202     pipe_config->output_format = INTEL_OUTPUT_FORMAT_RGB;
1203 
1204     drm_dbg_kms(&dev_priv->drm, "forcing bpc to 8 for TV\n");
1205     pipe_config->pipe_bpp = 8*3;
1206 
1207     pipe_config->port_clock = tv_mode->clock;
1208 
1209     intel_tv_mode_to_mode(adjusted_mode, tv_mode);
1210     drm_mode_set_crtcinfo(adjusted_mode, 0);
1211 
1212     if (intel_tv_source_too_wide(dev_priv, hdisplay) ||
1213         !intel_tv_vert_scaling(adjusted_mode, conn_state, vdisplay)) {
1214         int extra, top, bottom;
1215 
1216         extra = adjusted_mode->crtc_vdisplay - vdisplay;
1217 
1218         if (extra < 0) {
1219             drm_dbg_kms(&dev_priv->drm,
1220                     "No vertical scaling for >1024 pixel wide modes\n");
1221             return -EINVAL;
1222         }
1223 
1224         /* Need to turn off the vertical filter and center the image */
1225 
1226         /* Attempt to maintain the relative sizes of the margins */
1227         top = conn_state->tv.margins.top;
1228         bottom = conn_state->tv.margins.bottom;
1229 
1230         if (top + bottom)
1231             top = extra * top / (top + bottom);
1232         else
1233             top = extra / 2;
1234         bottom = extra - top;
1235 
1236         tv_conn_state->margins.top = top;
1237         tv_conn_state->margins.bottom = bottom;
1238 
1239         tv_conn_state->bypass_vfilter = true;
1240 
1241         if (!tv_mode->progressive) {
1242             adjusted_mode->clock /= 2;
1243             adjusted_mode->crtc_clock /= 2;
1244             adjusted_mode->flags |= DRM_MODE_FLAG_INTERLACE;
1245         }
1246     } else {
1247         tv_conn_state->margins.top = conn_state->tv.margins.top;
1248         tv_conn_state->margins.bottom = conn_state->tv.margins.bottom;
1249 
1250         tv_conn_state->bypass_vfilter = false;
1251     }
1252 
1253     drm_dbg_kms(&dev_priv->drm, "TV mode: " DRM_MODE_FMT "\n",
1254             DRM_MODE_ARG(adjusted_mode));
1255 
1256     /*
1257      * The pipe scanline counter behaviour looks as follows when
1258      * using the TV encoder:
1259      *
1260      * time ->
1261      *
1262      * dsl=vtotal-1       |             |
1263      *                   ||            ||
1264      *               ___| |        ___| |
1265      *              /     |       /     |
1266      *             /      |      /      |
1267      * dsl=0   ___/       |_____/       |
1268      *        | | |  |  | |
1269      *         ^ ^ ^   ^ ^
1270      *         | | |   | pipe vblank/first part of tv vblank
1271      *         | | |   bottom margin
1272      *         | | active
1273      *         | top margin
1274      *         remainder of tv vblank
1275      *
1276      * When the TV encoder is used the pipe wants to run faster
1277      * than expected rate. During the active portion the TV
1278      * encoder stalls the pipe every few lines to keep it in
1279      * check. When the TV encoder reaches the bottom margin the
1280      * pipe simply stops. Once we reach the TV vblank the pipe is
1281      * no longer stalled and it runs at the max rate (apparently
1282      * oversample clock on gen3, cdclk on gen4). Once the pipe
1283      * reaches the pipe vtotal the pipe stops for the remainder
1284      * of the TV vblank/top margin. The pipe starts up again when
1285      * the TV encoder exits the top margin.
1286      *
1287      * To avoid huge hassles for vblank timestamping we scale
1288      * the pipe timings as if the pipe always runs at the average
1289      * rate it maintains during the active period. This also
1290      * gives us a reasonable guesstimate as to the pixel rate.
1291      * Due to the variation in the actual pipe speed the scanline
1292      * counter will give us slightly erroneous results during the
1293      * TV vblank/margins. But since vtotal was selected such that
1294      * it matches the average rate of the pipe during the active
1295      * portion the error shouldn't cause any serious grief to
1296      * vblank timestamps.
1297      *
1298      * For posterity here is the empirically derived formula
1299      * that gives us the maximum length of the pipe vblank
1300      * we can use without causing display corruption. Following
1301      * this would allow us to have a ticking scanline counter
1302      * everywhere except during the bottom margin (there the
1303      * pipe always stops). Ie. this would eliminate the second
1304      * flat portion of the above graph. However this would also
1305      * complicate vblank timestamping as the pipe vtotal would
1306      * no longer match the average rate the pipe runs at during
1307      * the active portion. Hence following this formula seems
1308      * more trouble that it's worth.
1309      *
1310      * if (GRAPHICS_VER(dev_priv) == 4) {
1311      *  num = cdclk * (tv_mode->oversample >> !tv_mode->progressive);
1312      *  den = tv_mode->clock;
1313      * } else {
1314      *  num = tv_mode->oversample >> !tv_mode->progressive;
1315      *  den = 1;
1316      * }
1317      * max_pipe_vblank_len ~=
1318      *  (num * tv_htotal * (tv_vblank_len + top_margin)) /
1319      *  (den * pipe_htotal);
1320      */
1321     intel_tv_scale_mode_horiz(adjusted_mode, hdisplay,
1322                   conn_state->tv.margins.left,
1323                   conn_state->tv.margins.right);
1324     intel_tv_scale_mode_vert(adjusted_mode, vdisplay,
1325                  tv_conn_state->margins.top,
1326                  tv_conn_state->margins.bottom);
1327     drm_mode_set_crtcinfo(adjusted_mode, 0);
1328     adjusted_mode->name[0] = '\0';
1329 
1330     /* pixel counter doesn't work on i965gm TV output */
1331     if (IS_I965GM(dev_priv))
1332         pipe_config->mode_flags |=
1333             I915_MODE_FLAG_USE_SCANLINE_COUNTER;
1334 
1335     return 0;
1336 }
1337 
1338 static void
1339 set_tv_mode_timings(struct drm_i915_private *dev_priv,
1340             const struct tv_mode *tv_mode,
1341             bool burst_ena)
1342 {
1343     u32 hctl1, hctl2, hctl3;
1344     u32 vctl1, vctl2, vctl3, vctl4, vctl5, vctl6, vctl7;
1345 
1346     hctl1 = (tv_mode->hsync_end << TV_HSYNC_END_SHIFT) |
1347         (tv_mode->htotal << TV_HTOTAL_SHIFT);
1348 
1349     hctl2 = (tv_mode->hburst_start << 16) |
1350         (tv_mode->hburst_len << TV_HBURST_LEN_SHIFT);
1351 
1352     if (burst_ena)
1353         hctl2 |= TV_BURST_ENA;
1354 
1355     hctl3 = (tv_mode->hblank_start << TV_HBLANK_START_SHIFT) |
1356         (tv_mode->hblank_end << TV_HBLANK_END_SHIFT);
1357 
1358     vctl1 = (tv_mode->nbr_end << TV_NBR_END_SHIFT) |
1359         (tv_mode->vi_end_f1 << TV_VI_END_F1_SHIFT) |
1360         (tv_mode->vi_end_f2 << TV_VI_END_F2_SHIFT);
1361 
1362     vctl2 = (tv_mode->vsync_len << TV_VSYNC_LEN_SHIFT) |
1363         (tv_mode->vsync_start_f1 << TV_VSYNC_START_F1_SHIFT) |
1364         (tv_mode->vsync_start_f2 << TV_VSYNC_START_F2_SHIFT);
1365 
1366     vctl3 = (tv_mode->veq_len << TV_VEQ_LEN_SHIFT) |
1367         (tv_mode->veq_start_f1 << TV_VEQ_START_F1_SHIFT) |
1368         (tv_mode->veq_start_f2 << TV_VEQ_START_F2_SHIFT);
1369 
1370     if (tv_mode->veq_ena)
1371         vctl3 |= TV_EQUAL_ENA;
1372 
1373     vctl4 = (tv_mode->vburst_start_f1 << TV_VBURST_START_F1_SHIFT) |
1374         (tv_mode->vburst_end_f1 << TV_VBURST_END_F1_SHIFT);
1375 
1376     vctl5 = (tv_mode->vburst_start_f2 << TV_VBURST_START_F2_SHIFT) |
1377         (tv_mode->vburst_end_f2 << TV_VBURST_END_F2_SHIFT);
1378 
1379     vctl6 = (tv_mode->vburst_start_f3 << TV_VBURST_START_F3_SHIFT) |
1380         (tv_mode->vburst_end_f3 << TV_VBURST_END_F3_SHIFT);
1381 
1382     vctl7 = (tv_mode->vburst_start_f4 << TV_VBURST_START_F4_SHIFT) |
1383         (tv_mode->vburst_end_f4 << TV_VBURST_END_F4_SHIFT);
1384 
1385     intel_de_write(dev_priv, TV_H_CTL_1, hctl1);
1386     intel_de_write(dev_priv, TV_H_CTL_2, hctl2);
1387     intel_de_write(dev_priv, TV_H_CTL_3, hctl3);
1388     intel_de_write(dev_priv, TV_V_CTL_1, vctl1);
1389     intel_de_write(dev_priv, TV_V_CTL_2, vctl2);
1390     intel_de_write(dev_priv, TV_V_CTL_3, vctl3);
1391     intel_de_write(dev_priv, TV_V_CTL_4, vctl4);
1392     intel_de_write(dev_priv, TV_V_CTL_5, vctl5);
1393     intel_de_write(dev_priv, TV_V_CTL_6, vctl6);
1394     intel_de_write(dev_priv, TV_V_CTL_7, vctl7);
1395 }
1396 
1397 static void set_color_conversion(struct drm_i915_private *dev_priv,
1398                  const struct color_conversion *color_conversion)
1399 {
1400     if (!color_conversion)
1401         return;
1402 
1403     intel_de_write(dev_priv, TV_CSC_Y,
1404                (color_conversion->ry << 16) | color_conversion->gy);
1405     intel_de_write(dev_priv, TV_CSC_Y2,
1406                (color_conversion->by << 16) | color_conversion->ay);
1407     intel_de_write(dev_priv, TV_CSC_U,
1408                (color_conversion->ru << 16) | color_conversion->gu);
1409     intel_de_write(dev_priv, TV_CSC_U2,
1410                (color_conversion->bu << 16) | color_conversion->au);
1411     intel_de_write(dev_priv, TV_CSC_V,
1412                (color_conversion->rv << 16) | color_conversion->gv);
1413     intel_de_write(dev_priv, TV_CSC_V2,
1414                (color_conversion->bv << 16) | color_conversion->av);
1415 }
1416 
1417 static void intel_tv_pre_enable(struct intel_atomic_state *state,
1418                 struct intel_encoder *encoder,
1419                 const struct intel_crtc_state *pipe_config,
1420                 const struct drm_connector_state *conn_state)
1421 {
1422     struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
1423     struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc);
1424     struct intel_tv *intel_tv = enc_to_tv(encoder);
1425     const struct intel_tv_connector_state *tv_conn_state =
1426         to_intel_tv_connector_state(conn_state);
1427     const struct tv_mode *tv_mode = intel_tv_mode_find(conn_state);
1428     u32 tv_ctl, tv_filter_ctl;
1429     u32 scctl1, scctl2, scctl3;
1430     int i, j;
1431     const struct video_levels *video_levels;
1432     const struct color_conversion *color_conversion;
1433     bool burst_ena;
1434     int xpos, ypos;
1435     unsigned int xsize, ysize;
1436 
1437     if (!tv_mode)
1438         return; /* can't happen (mode_prepare prevents this) */
1439 
1440     tv_ctl = intel_de_read(dev_priv, TV_CTL);
1441     tv_ctl &= TV_CTL_SAVE;
1442 
1443     switch (intel_tv->type) {
1444     default:
1445     case DRM_MODE_CONNECTOR_Unknown:
1446     case DRM_MODE_CONNECTOR_Composite:
1447         tv_ctl |= TV_ENC_OUTPUT_COMPOSITE;
1448         video_levels = tv_mode->composite_levels;
1449         color_conversion = tv_mode->composite_color;
1450         burst_ena = tv_mode->burst_ena;
1451         break;
1452     case DRM_MODE_CONNECTOR_Component:
1453         tv_ctl |= TV_ENC_OUTPUT_COMPONENT;
1454         video_levels = &component_levels;
1455         if (tv_mode->burst_ena)
1456             color_conversion = &sdtv_csc_yprpb;
1457         else
1458             color_conversion = &hdtv_csc_yprpb;
1459         burst_ena = false;
1460         break;
1461     case DRM_MODE_CONNECTOR_SVIDEO:
1462         tv_ctl |= TV_ENC_OUTPUT_SVIDEO;
1463         video_levels = tv_mode->svideo_levels;
1464         color_conversion = tv_mode->svideo_color;
1465         burst_ena = tv_mode->burst_ena;
1466         break;
1467     }
1468 
1469     tv_ctl |= TV_ENC_PIPE_SEL(crtc->pipe);
1470 
1471     switch (tv_mode->oversample) {
1472     case 8:
1473         tv_ctl |= TV_OVERSAMPLE_8X;
1474         break;
1475     case 4:
1476         tv_ctl |= TV_OVERSAMPLE_4X;
1477         break;
1478     case 2:
1479         tv_ctl |= TV_OVERSAMPLE_2X;
1480         break;
1481     default:
1482         tv_ctl |= TV_OVERSAMPLE_NONE;
1483         break;
1484     }
1485 
1486     if (tv_mode->progressive)
1487         tv_ctl |= TV_PROGRESSIVE;
1488     if (tv_mode->trilevel_sync)
1489         tv_ctl |= TV_TRILEVEL_SYNC;
1490     if (tv_mode->pal_burst)
1491         tv_ctl |= TV_PAL_BURST;
1492 
1493     scctl1 = 0;
1494     if (tv_mode->dda1_inc)
1495         scctl1 |= TV_SC_DDA1_EN;
1496     if (tv_mode->dda2_inc)
1497         scctl1 |= TV_SC_DDA2_EN;
1498     if (tv_mode->dda3_inc)
1499         scctl1 |= TV_SC_DDA3_EN;
1500     scctl1 |= tv_mode->sc_reset;
1501     if (video_levels)
1502         scctl1 |= video_levels->burst << TV_BURST_LEVEL_SHIFT;
1503     scctl1 |= tv_mode->dda1_inc << TV_SCDDA1_INC_SHIFT;
1504 
1505     scctl2 = tv_mode->dda2_size << TV_SCDDA2_SIZE_SHIFT |
1506         tv_mode->dda2_inc << TV_SCDDA2_INC_SHIFT;
1507 
1508     scctl3 = tv_mode->dda3_size << TV_SCDDA3_SIZE_SHIFT |
1509         tv_mode->dda3_inc << TV_SCDDA3_INC_SHIFT;
1510 
1511     /* Enable two fixes for the chips that need them. */
1512     if (IS_I915GM(dev_priv))
1513         tv_ctl |= TV_ENC_C0_FIX | TV_ENC_SDP_FIX;
1514 
1515     set_tv_mode_timings(dev_priv, tv_mode, burst_ena);
1516 
1517     intel_de_write(dev_priv, TV_SC_CTL_1, scctl1);
1518     intel_de_write(dev_priv, TV_SC_CTL_2, scctl2);
1519     intel_de_write(dev_priv, TV_SC_CTL_3, scctl3);
1520 
1521     set_color_conversion(dev_priv, color_conversion);
1522 
1523     if (DISPLAY_VER(dev_priv) >= 4)
1524         intel_de_write(dev_priv, TV_CLR_KNOBS, 0x00404000);
1525     else
1526         intel_de_write(dev_priv, TV_CLR_KNOBS, 0x00606000);
1527 
1528     if (video_levels)
1529         intel_de_write(dev_priv, TV_CLR_LEVEL,
1530                    ((video_levels->black << TV_BLACK_LEVEL_SHIFT) | (video_levels->blank << TV_BLANK_LEVEL_SHIFT)));
1531 
1532     assert_transcoder_disabled(dev_priv, pipe_config->cpu_transcoder);
1533 
1534     /* Filter ctl must be set before TV_WIN_SIZE */
1535     tv_filter_ctl = TV_AUTO_SCALE;
1536     if (tv_conn_state->bypass_vfilter)
1537         tv_filter_ctl |= TV_V_FILTER_BYPASS;
1538     intel_de_write(dev_priv, TV_FILTER_CTL_1, tv_filter_ctl);
1539 
1540     xsize = tv_mode->hblank_start - tv_mode->hblank_end;
1541     ysize = intel_tv_mode_vdisplay(tv_mode);
1542 
1543     xpos = conn_state->tv.margins.left;
1544     ypos = tv_conn_state->margins.top;
1545     xsize -= (conn_state->tv.margins.left +
1546           conn_state->tv.margins.right);
1547     ysize -= (tv_conn_state->margins.top +
1548           tv_conn_state->margins.bottom);
1549     intel_de_write(dev_priv, TV_WIN_POS, (xpos << 16) | ypos);
1550     intel_de_write(dev_priv, TV_WIN_SIZE, (xsize << 16) | ysize);
1551 
1552     j = 0;
1553     for (i = 0; i < 60; i++)
1554         intel_de_write(dev_priv, TV_H_LUMA(i),
1555                    tv_mode->filter_table[j++]);
1556     for (i = 0; i < 60; i++)
1557         intel_de_write(dev_priv, TV_H_CHROMA(i),
1558                    tv_mode->filter_table[j++]);
1559     for (i = 0; i < 43; i++)
1560         intel_de_write(dev_priv, TV_V_LUMA(i),
1561                    tv_mode->filter_table[j++]);
1562     for (i = 0; i < 43; i++)
1563         intel_de_write(dev_priv, TV_V_CHROMA(i),
1564                    tv_mode->filter_table[j++]);
1565     intel_de_write(dev_priv, TV_DAC,
1566                intel_de_read(dev_priv, TV_DAC) & TV_DAC_SAVE);
1567     intel_de_write(dev_priv, TV_CTL, tv_ctl);
1568 }
1569 
1570 static int
1571 intel_tv_detect_type(struct intel_tv *intel_tv,
1572               struct drm_connector *connector)
1573 {
1574     struct intel_crtc *crtc = to_intel_crtc(connector->state->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(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_crtc_wait_for_next_vblank(crtc);
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_crtc_wait_for_next_vblank(crtc);
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  */
1672 static 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 
1696 static int
1697 intel_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 (!INTEL_DISPLAY_ENABLED(i915))
1710         return connector_status_disconnected;
1711 
1712     if (force) {
1713         struct intel_load_detect_pipe tmp;
1714         int ret;
1715 
1716         ret = intel_get_load_detect_pipe(connector, &tmp, ctx);
1717         if (ret < 0)
1718             return ret;
1719 
1720         if (ret > 0) {
1721             type = intel_tv_detect_type(intel_tv, connector);
1722             intel_release_load_detect_pipe(connector, &tmp, ctx);
1723             status = type < 0 ?
1724                 connector_status_disconnected :
1725                 connector_status_connected;
1726         } else
1727             status = connector_status_unknown;
1728 
1729         if (status == connector_status_connected) {
1730             intel_tv->type = type;
1731             intel_tv_find_better_format(connector);
1732         }
1733 
1734         return status;
1735     } else
1736         return connector->status;
1737 }
1738 
1739 static const struct input_res {
1740     u16 w, h;
1741 } input_res_table[] = {
1742     { 640, 480 },
1743     { 800, 600 },
1744     { 1024, 768 },
1745     { 1280, 1024 },
1746     { 848, 480 },
1747     { 1280, 720 },
1748     { 1920, 1080 },
1749 };
1750 
1751 /* Choose preferred mode according to line number of TV format */
1752 static bool
1753 intel_tv_is_preferred_mode(const struct drm_display_mode *mode,
1754                const struct tv_mode *tv_mode)
1755 {
1756     int vdisplay = intel_tv_mode_vdisplay(tv_mode);
1757 
1758     /* prefer 480 line modes for all SD TV modes */
1759     if (vdisplay <= 576)
1760         vdisplay = 480;
1761 
1762     return vdisplay == mode->vdisplay;
1763 }
1764 
1765 static void
1766 intel_tv_set_mode_type(struct drm_display_mode *mode,
1767                const struct tv_mode *tv_mode)
1768 {
1769     mode->type = DRM_MODE_TYPE_DRIVER;
1770 
1771     if (intel_tv_is_preferred_mode(mode, tv_mode))
1772         mode->type |= DRM_MODE_TYPE_PREFERRED;
1773 }
1774 
1775 static int
1776 intel_tv_get_modes(struct drm_connector *connector)
1777 {
1778     struct drm_i915_private *dev_priv = to_i915(connector->dev);
1779     const struct tv_mode *tv_mode = intel_tv_mode_find(connector->state);
1780     int i, count = 0;
1781 
1782     for (i = 0; i < ARRAY_SIZE(input_res_table); i++) {
1783         const struct input_res *input = &input_res_table[i];
1784         struct drm_display_mode *mode;
1785 
1786         if (input->w > 1024 &&
1787             !tv_mode->progressive &&
1788             !tv_mode->component_only)
1789             continue;
1790 
1791         /* no vertical scaling with wide sources on gen3 */
1792         if (DISPLAY_VER(dev_priv) == 3 && input->w > 1024 &&
1793             input->h > intel_tv_mode_vdisplay(tv_mode))
1794             continue;
1795 
1796         mode = drm_mode_create(connector->dev);
1797         if (!mode)
1798             continue;
1799 
1800         /*
1801          * We take the TV mode and scale it to look
1802          * like it had the expected h/vdisplay. This
1803          * provides the most information to userspace
1804          * about the actual timings of the mode. We
1805          * do ignore the margins though.
1806          */
1807         intel_tv_mode_to_mode(mode, tv_mode);
1808         if (count == 0) {
1809             drm_dbg_kms(&dev_priv->drm, "TV mode: " DRM_MODE_FMT "\n",
1810                     DRM_MODE_ARG(mode));
1811         }
1812         intel_tv_scale_mode_horiz(mode, input->w, 0, 0);
1813         intel_tv_scale_mode_vert(mode, input->h, 0, 0);
1814         intel_tv_set_mode_type(mode, tv_mode);
1815 
1816         drm_mode_set_name(mode);
1817 
1818         drm_mode_probed_add(connector, mode);
1819         count++;
1820     }
1821 
1822     return count;
1823 }
1824 
1825 static const struct drm_connector_funcs intel_tv_connector_funcs = {
1826     .late_register = intel_connector_register,
1827     .early_unregister = intel_connector_unregister,
1828     .destroy = intel_connector_destroy,
1829     .fill_modes = drm_helper_probe_single_connector_modes,
1830     .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
1831     .atomic_duplicate_state = intel_tv_connector_duplicate_state,
1832 };
1833 
1834 static int intel_tv_atomic_check(struct drm_connector *connector,
1835                  struct drm_atomic_state *state)
1836 {
1837     struct drm_connector_state *new_state;
1838     struct drm_crtc_state *new_crtc_state;
1839     struct drm_connector_state *old_state;
1840 
1841     new_state = drm_atomic_get_new_connector_state(state, connector);
1842     if (!new_state->crtc)
1843         return 0;
1844 
1845     old_state = drm_atomic_get_old_connector_state(state, connector);
1846     new_crtc_state = drm_atomic_get_new_crtc_state(state, new_state->crtc);
1847 
1848     if (old_state->tv.mode != new_state->tv.mode ||
1849         old_state->tv.margins.left != new_state->tv.margins.left ||
1850         old_state->tv.margins.right != new_state->tv.margins.right ||
1851         old_state->tv.margins.top != new_state->tv.margins.top ||
1852         old_state->tv.margins.bottom != new_state->tv.margins.bottom) {
1853         /* Force a modeset. */
1854 
1855         new_crtc_state->connectors_changed = true;
1856     }
1857 
1858     return 0;
1859 }
1860 
1861 static const struct drm_connector_helper_funcs intel_tv_connector_helper_funcs = {
1862     .detect_ctx = intel_tv_detect,
1863     .mode_valid = intel_tv_mode_valid,
1864     .get_modes = intel_tv_get_modes,
1865     .atomic_check = intel_tv_atomic_check,
1866 };
1867 
1868 static const struct drm_encoder_funcs intel_tv_enc_funcs = {
1869     .destroy = intel_encoder_destroy,
1870 };
1871 
1872 void
1873 intel_tv_init(struct drm_i915_private *dev_priv)
1874 {
1875     struct drm_device *dev = &dev_priv->drm;
1876     struct drm_connector *connector;
1877     struct intel_tv *intel_tv;
1878     struct intel_encoder *intel_encoder;
1879     struct intel_connector *intel_connector;
1880     u32 tv_dac_on, tv_dac_off, save_tv_dac;
1881     const char *tv_format_names[ARRAY_SIZE(tv_modes)];
1882     int i, initial_mode = 0;
1883     struct drm_connector_state *state;
1884 
1885     if ((intel_de_read(dev_priv, TV_CTL) & TV_FUSE_STATE_MASK) == TV_FUSE_STATE_DISABLED)
1886         return;
1887 
1888     if (!intel_bios_is_tv_present(dev_priv)) {
1889         drm_dbg_kms(&dev_priv->drm, "Integrated TV is not present.\n");
1890         return;
1891     }
1892 
1893     /*
1894      * Sanity check the TV output by checking to see if the
1895      * DAC register holds a value
1896      */
1897     save_tv_dac = 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_on = intel_de_read(dev_priv, TV_DAC);
1901 
1902     intel_de_write(dev_priv, TV_DAC, save_tv_dac & ~TVDAC_STATE_CHG_EN);
1903     tv_dac_off = intel_de_read(dev_priv, TV_DAC);
1904 
1905     intel_de_write(dev_priv, TV_DAC, save_tv_dac);
1906 
1907     /*
1908      * If the register does not hold the state change enable
1909      * bit, (either as a 0 or a 1), assume it doesn't really
1910      * exist
1911      */
1912     if ((tv_dac_on & TVDAC_STATE_CHG_EN) == 0 ||
1913         (tv_dac_off & TVDAC_STATE_CHG_EN) != 0)
1914         return;
1915 
1916     intel_tv = kzalloc(sizeof(*intel_tv), GFP_KERNEL);
1917     if (!intel_tv) {
1918         return;
1919     }
1920 
1921     intel_connector = intel_connector_alloc();
1922     if (!intel_connector) {
1923         kfree(intel_tv);
1924         return;
1925     }
1926 
1927     intel_encoder = &intel_tv->base;
1928     connector = &intel_connector->base;
1929     state = connector->state;
1930 
1931     /*
1932      * The documentation, for the older chipsets at least, recommend
1933      * using a polling method rather than hotplug detection for TVs.
1934      * This is because in order to perform the hotplug detection, the PLLs
1935      * for the TV must be kept alive increasing power drain and starving
1936      * bandwidth from other encoders. Notably for instance, it causes
1937      * pipe underruns on Crestline when this encoder is supposedly idle.
1938      *
1939      * More recent chipsets favour HDMI rather than integrated S-Video.
1940      */
1941     intel_connector->polled = DRM_CONNECTOR_POLL_CONNECT;
1942 
1943     drm_connector_init(dev, connector, &intel_tv_connector_funcs,
1944                DRM_MODE_CONNECTOR_SVIDEO);
1945 
1946     drm_encoder_init(dev, &intel_encoder->base, &intel_tv_enc_funcs,
1947              DRM_MODE_ENCODER_TVDAC, "TV");
1948 
1949     intel_encoder->compute_config = intel_tv_compute_config;
1950     intel_encoder->get_config = intel_tv_get_config;
1951     intel_encoder->pre_enable = intel_tv_pre_enable;
1952     intel_encoder->enable = intel_enable_tv;
1953     intel_encoder->disable = intel_disable_tv;
1954     intel_encoder->get_hw_state = intel_tv_get_hw_state;
1955     intel_connector->get_hw_state = intel_connector_get_hw_state;
1956 
1957     intel_connector_attach_encoder(intel_connector, intel_encoder);
1958 
1959     intel_encoder->type = INTEL_OUTPUT_TVOUT;
1960     intel_encoder->power_domain = POWER_DOMAIN_PORT_OTHER;
1961     intel_encoder->port = PORT_NONE;
1962     intel_encoder->pipe_mask = ~0;
1963     intel_encoder->cloneable = 0;
1964     intel_tv->type = DRM_MODE_CONNECTOR_Unknown;
1965 
1966     /* BIOS margin values */
1967     state->tv.margins.left = 54;
1968     state->tv.margins.top = 36;
1969     state->tv.margins.right = 46;
1970     state->tv.margins.bottom = 37;
1971 
1972     state->tv.mode = initial_mode;
1973 
1974     drm_connector_helper_add(connector, &intel_tv_connector_helper_funcs);
1975     connector->interlace_allowed = false;
1976     connector->doublescan_allowed = false;
1977 
1978     /* Create TV properties then attach current values */
1979     for (i = 0; i < ARRAY_SIZE(tv_modes); i++) {
1980         /* 1080p50/1080p60 not supported on gen3 */
1981         if (DISPLAY_VER(dev_priv) == 3 &&
1982             tv_modes[i].oversample == 1)
1983             break;
1984 
1985         tv_format_names[i] = tv_modes[i].name;
1986     }
1987     drm_mode_create_tv_properties(dev, i, tv_format_names);
1988 
1989     drm_object_attach_property(&connector->base, dev->mode_config.tv_mode_property,
1990                    state->tv.mode);
1991     drm_object_attach_property(&connector->base,
1992                    dev->mode_config.tv_left_margin_property,
1993                    state->tv.margins.left);
1994     drm_object_attach_property(&connector->base,
1995                    dev->mode_config.tv_top_margin_property,
1996                    state->tv.margins.top);
1997     drm_object_attach_property(&connector->base,
1998                    dev->mode_config.tv_right_margin_property,
1999                    state->tv.margins.right);
2000     drm_object_attach_property(&connector->base,
2001                    dev->mode_config.tv_bottom_margin_property,
2002                    state->tv.margins.bottom);
2003 }