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