Home | History | Annotate | Line # | Download | only in drm
      1  1.15  riastrad /*	$NetBSD: drm_edid.c,v 1.15 2021/12/19 12:44:04 riastradh Exp $	*/
      2   1.6  riastrad 
      3   1.1  riastrad /*
      4   1.1  riastrad  * Copyright (c) 2006 Luc Verhaegen (quirks list)
      5   1.1  riastrad  * Copyright (c) 2007-2008 Intel Corporation
      6   1.1  riastrad  *   Jesse Barnes <jesse.barnes (at) intel.com>
      7   1.1  riastrad  * Copyright 2010 Red Hat, Inc.
      8   1.1  riastrad  *
      9   1.1  riastrad  * DDC probing routines (drm_ddc_read & drm_do_probe_ddc_edid) originally from
     10   1.1  riastrad  * FB layer.
     11   1.1  riastrad  *   Copyright (C) 2006 Dennis Munsie <dmunsie (at) cecropia.com>
     12   1.1  riastrad  *
     13   1.1  riastrad  * Permission is hereby granted, free of charge, to any person obtaining a
     14   1.1  riastrad  * copy of this software and associated documentation files (the "Software"),
     15   1.1  riastrad  * to deal in the Software without restriction, including without limitation
     16   1.1  riastrad  * the rights to use, copy, modify, merge, publish, distribute, sub license,
     17   1.1  riastrad  * and/or sell copies of the Software, and to permit persons to whom the
     18   1.1  riastrad  * Software is furnished to do so, subject to the following conditions:
     19   1.1  riastrad  *
     20   1.1  riastrad  * The above copyright notice and this permission notice (including the
     21   1.1  riastrad  * next paragraph) shall be included in all copies or substantial portions
     22   1.1  riastrad  * of the Software.
     23   1.1  riastrad  *
     24   1.1  riastrad  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     25   1.1  riastrad  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     26   1.1  riastrad  * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
     27   1.1  riastrad  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     28   1.1  riastrad  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
     29   1.1  riastrad  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
     30   1.1  riastrad  * DEALINGS IN THE SOFTWARE.
     31   1.1  riastrad  */
     32   1.9  riastrad 
     33   1.6  riastrad #include <sys/cdefs.h>
     34  1.15  riastrad __KERNEL_RCSID(0, "$NetBSD: drm_edid.c,v 1.15 2021/12/19 12:44:04 riastradh Exp $");
     35   1.6  riastrad 
     36   1.3  riastrad #include <linux/hdmi.h>
     37   1.1  riastrad #include <linux/i2c.h>
     38   1.9  riastrad #include <linux/kernel.h>
     39   1.1  riastrad #include <linux/module.h>
     40   1.9  riastrad #include <linux/slab.h>
     41   1.9  riastrad #include <linux/vga_switcheroo.h>
     42   1.9  riastrad 
     43   1.9  riastrad #include <drm/drm_displayid.h>
     44   1.9  riastrad #include <drm/drm_drv.h>
     45  1.10  riastrad #include <linux/bitmap.h>
     46   1.1  riastrad #include <drm/drm_edid.h>
     47   1.9  riastrad #include <drm/drm_encoder.h>
     48   1.9  riastrad #include <drm/drm_print.h>
     49   1.9  riastrad #include <drm/drm_scdc_helper.h>
     50   1.9  riastrad 
     51   1.9  riastrad #include "drm_crtc_internal.h"
     52   1.1  riastrad 
     53   1.7  riastrad #include <linux/nbsd-namespace.h>
     54   1.7  riastrad 
     55   1.1  riastrad #define version_greater(edid, maj, min) \
     56   1.1  riastrad 	(((edid)->version > (maj)) || \
     57   1.1  riastrad 	 ((edid)->version == (maj) && (edid)->revision > (min)))
     58   1.1  riastrad 
     59   1.1  riastrad #define EDID_EST_TIMINGS 16
     60   1.1  riastrad #define EDID_STD_TIMINGS 8
     61   1.1  riastrad #define EDID_DETAILED_TIMINGS 4
     62   1.1  riastrad 
     63   1.1  riastrad /*
     64   1.1  riastrad  * EDID blocks out in the wild have a variety of bugs, try to collect
     65   1.1  riastrad  * them here (note that userspace may work around broken monitors first,
     66   1.1  riastrad  * but fixes should make their way here so that the kernel "just works"
     67   1.1  riastrad  * on as many displays as possible).
     68   1.1  riastrad  */
     69   1.1  riastrad 
     70   1.1  riastrad /* First detailed mode wrong, use largest 60Hz mode */
     71   1.1  riastrad #define EDID_QUIRK_PREFER_LARGE_60		(1 << 0)
     72   1.1  riastrad /* Reported 135MHz pixel clock is too high, needs adjustment */
     73   1.1  riastrad #define EDID_QUIRK_135_CLOCK_TOO_HIGH		(1 << 1)
     74   1.1  riastrad /* Prefer the largest mode at 75 Hz */
     75   1.1  riastrad #define EDID_QUIRK_PREFER_LARGE_75		(1 << 2)
     76   1.1  riastrad /* Detail timing is in cm not mm */
     77   1.1  riastrad #define EDID_QUIRK_DETAILED_IN_CM		(1 << 3)
     78   1.1  riastrad /* Detailed timing descriptors have bogus size values, so just take the
     79   1.1  riastrad  * maximum size and use that.
     80   1.1  riastrad  */
     81   1.1  riastrad #define EDID_QUIRK_DETAILED_USE_MAXIMUM_SIZE	(1 << 4)
     82   1.1  riastrad /* use +hsync +vsync for detailed mode */
     83   1.1  riastrad #define EDID_QUIRK_DETAILED_SYNC_PP		(1 << 6)
     84   1.1  riastrad /* Force reduced-blanking timings for detailed modes */
     85   1.1  riastrad #define EDID_QUIRK_FORCE_REDUCED_BLANKING	(1 << 7)
     86   1.3  riastrad /* Force 8bpc */
     87   1.3  riastrad #define EDID_QUIRK_FORCE_8BPC			(1 << 8)
     88   1.6  riastrad /* Force 12bpc */
     89   1.6  riastrad #define EDID_QUIRK_FORCE_12BPC			(1 << 9)
     90   1.6  riastrad /* Force 6bpc */
     91   1.6  riastrad #define EDID_QUIRK_FORCE_6BPC			(1 << 10)
     92   1.6  riastrad /* Force 10bpc */
     93   1.6  riastrad #define EDID_QUIRK_FORCE_10BPC			(1 << 11)
     94   1.9  riastrad /* Non desktop display (i.e. HMD) */
     95   1.9  riastrad #define EDID_QUIRK_NON_DESKTOP			(1 << 12)
     96   1.1  riastrad 
     97   1.1  riastrad struct detailed_mode_closure {
     98   1.1  riastrad 	struct drm_connector *connector;
     99   1.1  riastrad 	struct edid *edid;
    100   1.1  riastrad 	bool preferred;
    101   1.1  riastrad 	u32 quirks;
    102   1.1  riastrad 	int modes;
    103   1.1  riastrad };
    104   1.1  riastrad 
    105   1.1  riastrad #define LEVEL_DMT	0
    106   1.1  riastrad #define LEVEL_GTF	1
    107   1.1  riastrad #define LEVEL_GTF2	2
    108   1.1  riastrad #define LEVEL_CVT	3
    109   1.1  riastrad 
    110   1.9  riastrad static const struct edid_quirk {
    111   1.1  riastrad 	char vendor[4];
    112   1.1  riastrad 	int product_id;
    113   1.1  riastrad 	u32 quirks;
    114   1.1  riastrad } edid_quirk_list[] = {
    115   1.1  riastrad 	/* Acer AL1706 */
    116   1.1  riastrad 	{ "ACR", 44358, EDID_QUIRK_PREFER_LARGE_60 },
    117   1.1  riastrad 	/* Acer F51 */
    118   1.1  riastrad 	{ "API", 0x7602, EDID_QUIRK_PREFER_LARGE_60 },
    119   1.1  riastrad 
    120   1.6  riastrad 	/* AEO model 0 reports 8 bpc, but is a 6 bpc panel */
    121   1.6  riastrad 	{ "AEO", 0, EDID_QUIRK_FORCE_6BPC },
    122   1.6  riastrad 
    123   1.9  riastrad 	/* BOE model on HP Pavilion 15-n233sl reports 8 bpc, but is a 6 bpc panel */
    124   1.9  riastrad 	{ "BOE", 0x78b, EDID_QUIRK_FORCE_6BPC },
    125   1.9  riastrad 
    126   1.6  riastrad 	/* CPT panel of Asus UX303LA reports 8 bpc, but is a 6 bpc panel */
    127   1.6  riastrad 	{ "CPT", 0x17df, EDID_QUIRK_FORCE_6BPC },
    128   1.6  riastrad 
    129   1.9  riastrad 	/* SDC panel of Lenovo B50-80 reports 8 bpc, but is a 6 bpc panel */
    130   1.9  riastrad 	{ "SDC", 0x3652, EDID_QUIRK_FORCE_6BPC },
    131   1.9  riastrad 
    132   1.9  riastrad 	/* BOE model 0x0771 reports 8 bpc, but is a 6 bpc panel */
    133   1.9  riastrad 	{ "BOE", 0x0771, EDID_QUIRK_FORCE_6BPC },
    134   1.9  riastrad 
    135   1.1  riastrad 	/* Belinea 10 15 55 */
    136   1.1  riastrad 	{ "MAX", 1516, EDID_QUIRK_PREFER_LARGE_60 },
    137   1.1  riastrad 	{ "MAX", 0x77e, EDID_QUIRK_PREFER_LARGE_60 },
    138   1.1  riastrad 
    139   1.1  riastrad 	/* Envision Peripherals, Inc. EN-7100e */
    140   1.1  riastrad 	{ "EPI", 59264, EDID_QUIRK_135_CLOCK_TOO_HIGH },
    141   1.1  riastrad 	/* Envision EN2028 */
    142   1.1  riastrad 	{ "EPI", 8232, EDID_QUIRK_PREFER_LARGE_60 },
    143   1.1  riastrad 
    144   1.1  riastrad 	/* Funai Electronics PM36B */
    145   1.1  riastrad 	{ "FCM", 13600, EDID_QUIRK_PREFER_LARGE_75 |
    146   1.1  riastrad 	  EDID_QUIRK_DETAILED_IN_CM },
    147   1.1  riastrad 
    148   1.6  riastrad 	/* LGD panel of HP zBook 17 G2, eDP 10 bpc, but reports unknown bpc */
    149   1.6  riastrad 	{ "LGD", 764, EDID_QUIRK_FORCE_10BPC },
    150   1.6  riastrad 
    151   1.1  riastrad 	/* LG Philips LCD LP154W01-A5 */
    152   1.1  riastrad 	{ "LPL", 0, EDID_QUIRK_DETAILED_USE_MAXIMUM_SIZE },
    153   1.1  riastrad 	{ "LPL", 0x2a00, EDID_QUIRK_DETAILED_USE_MAXIMUM_SIZE },
    154   1.1  riastrad 
    155   1.1  riastrad 	/* Samsung SyncMaster 205BW.  Note: irony */
    156   1.1  riastrad 	{ "SAM", 541, EDID_QUIRK_DETAILED_SYNC_PP },
    157   1.1  riastrad 	/* Samsung SyncMaster 22[5-6]BW */
    158   1.1  riastrad 	{ "SAM", 596, EDID_QUIRK_PREFER_LARGE_60 },
    159   1.1  riastrad 	{ "SAM", 638, EDID_QUIRK_PREFER_LARGE_60 },
    160   1.1  riastrad 
    161   1.6  riastrad 	/* Sony PVM-2541A does up to 12 bpc, but only reports max 8 bpc */
    162   1.6  riastrad 	{ "SNY", 0x2541, EDID_QUIRK_FORCE_12BPC },
    163   1.6  riastrad 
    164   1.1  riastrad 	/* ViewSonic VA2026w */
    165   1.1  riastrad 	{ "VSC", 5020, EDID_QUIRK_FORCE_REDUCED_BLANKING },
    166   1.3  riastrad 
    167   1.3  riastrad 	/* Medion MD 30217 PG */
    168   1.3  riastrad 	{ "MED", 0x7b8, EDID_QUIRK_PREFER_LARGE_75 },
    169   1.3  riastrad 
    170   1.9  riastrad 	/* Lenovo G50 */
    171   1.9  riastrad 	{ "SDC", 18514, EDID_QUIRK_FORCE_6BPC },
    172   1.9  riastrad 
    173   1.3  riastrad 	/* Panel in Samsung NP700G7A-S01PL notebook reports 6bpc */
    174   1.3  riastrad 	{ "SEC", 0xd033, EDID_QUIRK_FORCE_8BPC },
    175   1.6  riastrad 
    176   1.6  riastrad 	/* Rotel RSX-1058 forwards sink's EDID but only does HDMI 1.1*/
    177   1.6  riastrad 	{ "ETR", 13896, EDID_QUIRK_FORCE_8BPC },
    178   1.9  riastrad 
    179   1.9  riastrad 	/* Valve Index Headset */
    180   1.9  riastrad 	{ "VLV", 0x91a8, EDID_QUIRK_NON_DESKTOP },
    181   1.9  riastrad 	{ "VLV", 0x91b0, EDID_QUIRK_NON_DESKTOP },
    182   1.9  riastrad 	{ "VLV", 0x91b1, EDID_QUIRK_NON_DESKTOP },
    183   1.9  riastrad 	{ "VLV", 0x91b2, EDID_QUIRK_NON_DESKTOP },
    184   1.9  riastrad 	{ "VLV", 0x91b3, EDID_QUIRK_NON_DESKTOP },
    185   1.9  riastrad 	{ "VLV", 0x91b4, EDID_QUIRK_NON_DESKTOP },
    186   1.9  riastrad 	{ "VLV", 0x91b5, EDID_QUIRK_NON_DESKTOP },
    187   1.9  riastrad 	{ "VLV", 0x91b6, EDID_QUIRK_NON_DESKTOP },
    188   1.9  riastrad 	{ "VLV", 0x91b7, EDID_QUIRK_NON_DESKTOP },
    189   1.9  riastrad 	{ "VLV", 0x91b8, EDID_QUIRK_NON_DESKTOP },
    190   1.9  riastrad 	{ "VLV", 0x91b9, EDID_QUIRK_NON_DESKTOP },
    191   1.9  riastrad 	{ "VLV", 0x91ba, EDID_QUIRK_NON_DESKTOP },
    192   1.9  riastrad 	{ "VLV", 0x91bb, EDID_QUIRK_NON_DESKTOP },
    193   1.9  riastrad 	{ "VLV", 0x91bc, EDID_QUIRK_NON_DESKTOP },
    194   1.9  riastrad 	{ "VLV", 0x91bd, EDID_QUIRK_NON_DESKTOP },
    195   1.9  riastrad 	{ "VLV", 0x91be, EDID_QUIRK_NON_DESKTOP },
    196   1.9  riastrad 	{ "VLV", 0x91bf, EDID_QUIRK_NON_DESKTOP },
    197   1.9  riastrad 
    198   1.9  riastrad 	/* HTC Vive and Vive Pro VR Headsets */
    199   1.9  riastrad 	{ "HVR", 0xaa01, EDID_QUIRK_NON_DESKTOP },
    200   1.9  riastrad 	{ "HVR", 0xaa02, EDID_QUIRK_NON_DESKTOP },
    201   1.9  riastrad 
    202   1.9  riastrad 	/* Oculus Rift DK1, DK2, and CV1 VR Headsets */
    203   1.9  riastrad 	{ "OVR", 0x0001, EDID_QUIRK_NON_DESKTOP },
    204   1.9  riastrad 	{ "OVR", 0x0003, EDID_QUIRK_NON_DESKTOP },
    205   1.9  riastrad 	{ "OVR", 0x0004, EDID_QUIRK_NON_DESKTOP },
    206   1.9  riastrad 
    207   1.9  riastrad 	/* Windows Mixed Reality Headsets */
    208   1.9  riastrad 	{ "ACR", 0x7fce, EDID_QUIRK_NON_DESKTOP },
    209   1.9  riastrad 	{ "HPN", 0x3515, EDID_QUIRK_NON_DESKTOP },
    210   1.9  riastrad 	{ "LEN", 0x0408, EDID_QUIRK_NON_DESKTOP },
    211   1.9  riastrad 	{ "LEN", 0xb800, EDID_QUIRK_NON_DESKTOP },
    212   1.9  riastrad 	{ "FUJ", 0x1970, EDID_QUIRK_NON_DESKTOP },
    213   1.9  riastrad 	{ "DEL", 0x7fce, EDID_QUIRK_NON_DESKTOP },
    214   1.9  riastrad 	{ "SEC", 0x144a, EDID_QUIRK_NON_DESKTOP },
    215   1.9  riastrad 	{ "AUS", 0xc102, EDID_QUIRK_NON_DESKTOP },
    216   1.9  riastrad 
    217   1.9  riastrad 	/* Sony PlayStation VR Headset */
    218   1.9  riastrad 	{ "SNY", 0x0704, EDID_QUIRK_NON_DESKTOP },
    219   1.9  riastrad 
    220   1.9  riastrad 	/* Sensics VR Headsets */
    221   1.9  riastrad 	{ "SEN", 0x1019, EDID_QUIRK_NON_DESKTOP },
    222   1.9  riastrad 
    223   1.9  riastrad 	/* OSVR HDK and HDK2 VR Headsets */
    224   1.9  riastrad 	{ "SVR", 0x1019, EDID_QUIRK_NON_DESKTOP },
    225   1.3  riastrad };
    226   1.3  riastrad 
    227   1.3  riastrad /*
    228   1.3  riastrad  * Autogenerated from the DMT spec.
    229   1.3  riastrad  * This table is copied from xfree86/modes/xf86EdidModes.c.
    230   1.3  riastrad  */
    231   1.3  riastrad static const struct drm_display_mode drm_dmt_modes[] = {
    232   1.6  riastrad 	/* 0x01 - 640x350@85Hz */
    233   1.3  riastrad 	{ DRM_MODE("640x350", DRM_MODE_TYPE_DRIVER, 31500, 640, 672,
    234   1.3  riastrad 		   736, 832, 0, 350, 382, 385, 445, 0,
    235   1.3  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
    236   1.6  riastrad 	/* 0x02 - 640x400@85Hz */
    237   1.3  riastrad 	{ DRM_MODE("640x400", DRM_MODE_TYPE_DRIVER, 31500, 640, 672,
    238   1.3  riastrad 		   736, 832, 0, 400, 401, 404, 445, 0,
    239   1.3  riastrad 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
    240   1.6  riastrad 	/* 0x03 - 720x400@85Hz */
    241   1.3  riastrad 	{ DRM_MODE("720x400", DRM_MODE_TYPE_DRIVER, 35500, 720, 756,
    242   1.3  riastrad 		   828, 936, 0, 400, 401, 404, 446, 0,
    243   1.3  riastrad 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
    244   1.6  riastrad 	/* 0x04 - 640x480@60Hz */
    245   1.3  riastrad 	{ DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 25175, 640, 656,
    246   1.6  riastrad 		   752, 800, 0, 480, 490, 492, 525, 0,
    247   1.3  riastrad 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
    248   1.6  riastrad 	/* 0x05 - 640x480@72Hz */
    249   1.3  riastrad 	{ DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 31500, 640, 664,
    250   1.3  riastrad 		   704, 832, 0, 480, 489, 492, 520, 0,
    251   1.3  riastrad 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
    252   1.6  riastrad 	/* 0x06 - 640x480@75Hz */
    253   1.3  riastrad 	{ DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 31500, 640, 656,
    254   1.3  riastrad 		   720, 840, 0, 480, 481, 484, 500, 0,
    255   1.3  riastrad 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
    256   1.6  riastrad 	/* 0x07 - 640x480@85Hz */
    257   1.3  riastrad 	{ DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 36000, 640, 696,
    258   1.3  riastrad 		   752, 832, 0, 480, 481, 484, 509, 0,
    259   1.3  riastrad 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
    260   1.6  riastrad 	/* 0x08 - 800x600@56Hz */
    261   1.3  riastrad 	{ DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 36000, 800, 824,
    262   1.3  riastrad 		   896, 1024, 0, 600, 601, 603, 625, 0,
    263   1.3  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
    264   1.6  riastrad 	/* 0x09 - 800x600@60Hz */
    265   1.3  riastrad 	{ DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 40000, 800, 840,
    266   1.3  riastrad 		   968, 1056, 0, 600, 601, 605, 628, 0,
    267   1.3  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
    268   1.6  riastrad 	/* 0x0a - 800x600@72Hz */
    269   1.3  riastrad 	{ DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 50000, 800, 856,
    270   1.3  riastrad 		   976, 1040, 0, 600, 637, 643, 666, 0,
    271   1.3  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
    272   1.6  riastrad 	/* 0x0b - 800x600@75Hz */
    273   1.3  riastrad 	{ DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 49500, 800, 816,
    274   1.3  riastrad 		   896, 1056, 0, 600, 601, 604, 625, 0,
    275   1.3  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
    276   1.6  riastrad 	/* 0x0c - 800x600@85Hz */
    277   1.3  riastrad 	{ DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 56250, 800, 832,
    278   1.3  riastrad 		   896, 1048, 0, 600, 601, 604, 631, 0,
    279   1.3  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
    280   1.6  riastrad 	/* 0x0d - 800x600@120Hz RB */
    281   1.3  riastrad 	{ DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 73250, 800, 848,
    282   1.3  riastrad 		   880, 960, 0, 600, 603, 607, 636, 0,
    283   1.3  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
    284   1.6  riastrad 	/* 0x0e - 848x480@60Hz */
    285   1.3  riastrad 	{ DRM_MODE("848x480", DRM_MODE_TYPE_DRIVER, 33750, 848, 864,
    286   1.3  riastrad 		   976, 1088, 0, 480, 486, 494, 517, 0,
    287   1.3  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
    288   1.6  riastrad 	/* 0x0f - 1024x768@43Hz, interlace */
    289   1.3  riastrad 	{ DRM_MODE("1024x768i", DRM_MODE_TYPE_DRIVER, 44900, 1024, 1032,
    290   1.9  riastrad 		   1208, 1264, 0, 768, 768, 776, 817, 0,
    291   1.3  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC |
    292   1.6  riastrad 		   DRM_MODE_FLAG_INTERLACE) },
    293   1.6  riastrad 	/* 0x10 - 1024x768@60Hz */
    294   1.3  riastrad 	{ DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 65000, 1024, 1048,
    295   1.3  riastrad 		   1184, 1344, 0, 768, 771, 777, 806, 0,
    296   1.3  riastrad 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
    297   1.6  riastrad 	/* 0x11 - 1024x768@70Hz */
    298   1.3  riastrad 	{ DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 75000, 1024, 1048,
    299   1.3  riastrad 		   1184, 1328, 0, 768, 771, 777, 806, 0,
    300   1.3  riastrad 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
    301   1.6  riastrad 	/* 0x12 - 1024x768@75Hz */
    302   1.3  riastrad 	{ DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 78750, 1024, 1040,
    303   1.3  riastrad 		   1136, 1312, 0, 768, 769, 772, 800, 0,
    304   1.3  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
    305   1.6  riastrad 	/* 0x13 - 1024x768@85Hz */
    306   1.3  riastrad 	{ DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 94500, 1024, 1072,
    307   1.3  riastrad 		   1168, 1376, 0, 768, 769, 772, 808, 0,
    308   1.3  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
    309   1.6  riastrad 	/* 0x14 - 1024x768@120Hz RB */
    310   1.3  riastrad 	{ DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 115500, 1024, 1072,
    311   1.3  riastrad 		   1104, 1184, 0, 768, 771, 775, 813, 0,
    312   1.3  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
    313   1.6  riastrad 	/* 0x15 - 1152x864@75Hz */
    314   1.3  riastrad 	{ DRM_MODE("1152x864", DRM_MODE_TYPE_DRIVER, 108000, 1152, 1216,
    315   1.3  riastrad 		   1344, 1600, 0, 864, 865, 868, 900, 0,
    316   1.3  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
    317   1.6  riastrad 	/* 0x55 - 1280x720@60Hz */
    318   1.6  riastrad 	{ DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 74250, 1280, 1390,
    319   1.6  riastrad 		   1430, 1650, 0, 720, 725, 730, 750, 0,
    320   1.6  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
    321   1.6  riastrad 	/* 0x16 - 1280x768@60Hz RB */
    322   1.3  riastrad 	{ DRM_MODE("1280x768", DRM_MODE_TYPE_DRIVER, 68250, 1280, 1328,
    323   1.3  riastrad 		   1360, 1440, 0, 768, 771, 778, 790, 0,
    324   1.3  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
    325   1.6  riastrad 	/* 0x17 - 1280x768@60Hz */
    326   1.3  riastrad 	{ DRM_MODE("1280x768", DRM_MODE_TYPE_DRIVER, 79500, 1280, 1344,
    327   1.3  riastrad 		   1472, 1664, 0, 768, 771, 778, 798, 0,
    328   1.3  riastrad 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
    329   1.6  riastrad 	/* 0x18 - 1280x768@75Hz */
    330   1.3  riastrad 	{ DRM_MODE("1280x768", DRM_MODE_TYPE_DRIVER, 102250, 1280, 1360,
    331   1.3  riastrad 		   1488, 1696, 0, 768, 771, 778, 805, 0,
    332   1.6  riastrad 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
    333   1.6  riastrad 	/* 0x19 - 1280x768@85Hz */
    334   1.3  riastrad 	{ DRM_MODE("1280x768", DRM_MODE_TYPE_DRIVER, 117500, 1280, 1360,
    335   1.3  riastrad 		   1496, 1712, 0, 768, 771, 778, 809, 0,
    336   1.3  riastrad 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
    337   1.6  riastrad 	/* 0x1a - 1280x768@120Hz RB */
    338   1.3  riastrad 	{ DRM_MODE("1280x768", DRM_MODE_TYPE_DRIVER, 140250, 1280, 1328,
    339   1.3  riastrad 		   1360, 1440, 0, 768, 771, 778, 813, 0,
    340   1.3  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
    341   1.6  riastrad 	/* 0x1b - 1280x800@60Hz RB */
    342   1.3  riastrad 	{ DRM_MODE("1280x800", DRM_MODE_TYPE_DRIVER, 71000, 1280, 1328,
    343   1.3  riastrad 		   1360, 1440, 0, 800, 803, 809, 823, 0,
    344   1.3  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
    345   1.6  riastrad 	/* 0x1c - 1280x800@60Hz */
    346   1.3  riastrad 	{ DRM_MODE("1280x800", DRM_MODE_TYPE_DRIVER, 83500, 1280, 1352,
    347   1.3  riastrad 		   1480, 1680, 0, 800, 803, 809, 831, 0,
    348   1.6  riastrad 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
    349   1.6  riastrad 	/* 0x1d - 1280x800@75Hz */
    350   1.3  riastrad 	{ DRM_MODE("1280x800", DRM_MODE_TYPE_DRIVER, 106500, 1280, 1360,
    351   1.3  riastrad 		   1488, 1696, 0, 800, 803, 809, 838, 0,
    352   1.3  riastrad 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
    353   1.6  riastrad 	/* 0x1e - 1280x800@85Hz */
    354   1.3  riastrad 	{ DRM_MODE("1280x800", DRM_MODE_TYPE_DRIVER, 122500, 1280, 1360,
    355   1.3  riastrad 		   1496, 1712, 0, 800, 803, 809, 843, 0,
    356   1.3  riastrad 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
    357   1.6  riastrad 	/* 0x1f - 1280x800@120Hz RB */
    358   1.3  riastrad 	{ DRM_MODE("1280x800", DRM_MODE_TYPE_DRIVER, 146250, 1280, 1328,
    359   1.3  riastrad 		   1360, 1440, 0, 800, 803, 809, 847, 0,
    360   1.3  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
    361   1.6  riastrad 	/* 0x20 - 1280x960@60Hz */
    362   1.3  riastrad 	{ DRM_MODE("1280x960", DRM_MODE_TYPE_DRIVER, 108000, 1280, 1376,
    363   1.3  riastrad 		   1488, 1800, 0, 960, 961, 964, 1000, 0,
    364   1.3  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
    365   1.6  riastrad 	/* 0x21 - 1280x960@85Hz */
    366   1.3  riastrad 	{ DRM_MODE("1280x960", DRM_MODE_TYPE_DRIVER, 148500, 1280, 1344,
    367   1.3  riastrad 		   1504, 1728, 0, 960, 961, 964, 1011, 0,
    368   1.3  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
    369   1.6  riastrad 	/* 0x22 - 1280x960@120Hz RB */
    370   1.3  riastrad 	{ DRM_MODE("1280x960", DRM_MODE_TYPE_DRIVER, 175500, 1280, 1328,
    371   1.3  riastrad 		   1360, 1440, 0, 960, 963, 967, 1017, 0,
    372   1.3  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
    373   1.6  riastrad 	/* 0x23 - 1280x1024@60Hz */
    374   1.3  riastrad 	{ DRM_MODE("1280x1024", DRM_MODE_TYPE_DRIVER, 108000, 1280, 1328,
    375   1.3  riastrad 		   1440, 1688, 0, 1024, 1025, 1028, 1066, 0,
    376   1.3  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
    377   1.6  riastrad 	/* 0x24 - 1280x1024@75Hz */
    378   1.3  riastrad 	{ DRM_MODE("1280x1024", DRM_MODE_TYPE_DRIVER, 135000, 1280, 1296,
    379   1.3  riastrad 		   1440, 1688, 0, 1024, 1025, 1028, 1066, 0,
    380   1.3  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
    381   1.6  riastrad 	/* 0x25 - 1280x1024@85Hz */
    382   1.3  riastrad 	{ DRM_MODE("1280x1024", DRM_MODE_TYPE_DRIVER, 157500, 1280, 1344,
    383   1.3  riastrad 		   1504, 1728, 0, 1024, 1025, 1028, 1072, 0,
    384   1.3  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
    385   1.6  riastrad 	/* 0x26 - 1280x1024@120Hz RB */
    386   1.3  riastrad 	{ DRM_MODE("1280x1024", DRM_MODE_TYPE_DRIVER, 187250, 1280, 1328,
    387   1.3  riastrad 		   1360, 1440, 0, 1024, 1027, 1034, 1084, 0,
    388   1.3  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
    389   1.6  riastrad 	/* 0x27 - 1360x768@60Hz */
    390   1.3  riastrad 	{ DRM_MODE("1360x768", DRM_MODE_TYPE_DRIVER, 85500, 1360, 1424,
    391   1.3  riastrad 		   1536, 1792, 0, 768, 771, 777, 795, 0,
    392   1.3  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
    393   1.6  riastrad 	/* 0x28 - 1360x768@120Hz RB */
    394   1.3  riastrad 	{ DRM_MODE("1360x768", DRM_MODE_TYPE_DRIVER, 148250, 1360, 1408,
    395   1.3  riastrad 		   1440, 1520, 0, 768, 771, 776, 813, 0,
    396   1.3  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
    397   1.6  riastrad 	/* 0x51 - 1366x768@60Hz */
    398   1.6  riastrad 	{ DRM_MODE("1366x768", DRM_MODE_TYPE_DRIVER, 85500, 1366, 1436,
    399   1.6  riastrad 		   1579, 1792, 0, 768, 771, 774, 798, 0,
    400   1.6  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
    401   1.6  riastrad 	/* 0x56 - 1366x768@60Hz */
    402   1.6  riastrad 	{ DRM_MODE("1366x768", DRM_MODE_TYPE_DRIVER, 72000, 1366, 1380,
    403   1.6  riastrad 		   1436, 1500, 0, 768, 769, 772, 800, 0,
    404   1.6  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
    405   1.6  riastrad 	/* 0x29 - 1400x1050@60Hz RB */
    406   1.3  riastrad 	{ DRM_MODE("1400x1050", DRM_MODE_TYPE_DRIVER, 101000, 1400, 1448,
    407   1.3  riastrad 		   1480, 1560, 0, 1050, 1053, 1057, 1080, 0,
    408   1.3  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
    409   1.6  riastrad 	/* 0x2a - 1400x1050@60Hz */
    410   1.3  riastrad 	{ DRM_MODE("1400x1050", DRM_MODE_TYPE_DRIVER, 121750, 1400, 1488,
    411   1.3  riastrad 		   1632, 1864, 0, 1050, 1053, 1057, 1089, 0,
    412   1.3  riastrad 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
    413   1.6  riastrad 	/* 0x2b - 1400x1050@75Hz */
    414   1.3  riastrad 	{ DRM_MODE("1400x1050", DRM_MODE_TYPE_DRIVER, 156000, 1400, 1504,
    415   1.3  riastrad 		   1648, 1896, 0, 1050, 1053, 1057, 1099, 0,
    416   1.3  riastrad 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
    417   1.6  riastrad 	/* 0x2c - 1400x1050@85Hz */
    418   1.3  riastrad 	{ DRM_MODE("1400x1050", DRM_MODE_TYPE_DRIVER, 179500, 1400, 1504,
    419   1.3  riastrad 		   1656, 1912, 0, 1050, 1053, 1057, 1105, 0,
    420   1.3  riastrad 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
    421   1.6  riastrad 	/* 0x2d - 1400x1050@120Hz RB */
    422   1.3  riastrad 	{ DRM_MODE("1400x1050", DRM_MODE_TYPE_DRIVER, 208000, 1400, 1448,
    423   1.3  riastrad 		   1480, 1560, 0, 1050, 1053, 1057, 1112, 0,
    424   1.3  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
    425   1.6  riastrad 	/* 0x2e - 1440x900@60Hz RB */
    426   1.3  riastrad 	{ DRM_MODE("1440x900", DRM_MODE_TYPE_DRIVER, 88750, 1440, 1488,
    427   1.3  riastrad 		   1520, 1600, 0, 900, 903, 909, 926, 0,
    428   1.3  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
    429   1.6  riastrad 	/* 0x2f - 1440x900@60Hz */
    430   1.3  riastrad 	{ DRM_MODE("1440x900", DRM_MODE_TYPE_DRIVER, 106500, 1440, 1520,
    431   1.3  riastrad 		   1672, 1904, 0, 900, 903, 909, 934, 0,
    432   1.3  riastrad 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
    433   1.6  riastrad 	/* 0x30 - 1440x900@75Hz */
    434   1.3  riastrad 	{ DRM_MODE("1440x900", DRM_MODE_TYPE_DRIVER, 136750, 1440, 1536,
    435   1.3  riastrad 		   1688, 1936, 0, 900, 903, 909, 942, 0,
    436   1.3  riastrad 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
    437   1.6  riastrad 	/* 0x31 - 1440x900@85Hz */
    438   1.3  riastrad 	{ DRM_MODE("1440x900", DRM_MODE_TYPE_DRIVER, 157000, 1440, 1544,
    439   1.3  riastrad 		   1696, 1952, 0, 900, 903, 909, 948, 0,
    440   1.3  riastrad 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
    441   1.6  riastrad 	/* 0x32 - 1440x900@120Hz RB */
    442   1.3  riastrad 	{ DRM_MODE("1440x900", DRM_MODE_TYPE_DRIVER, 182750, 1440, 1488,
    443   1.3  riastrad 		   1520, 1600, 0, 900, 903, 909, 953, 0,
    444   1.3  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
    445   1.6  riastrad 	/* 0x53 - 1600x900@60Hz */
    446   1.6  riastrad 	{ DRM_MODE("1600x900", DRM_MODE_TYPE_DRIVER, 108000, 1600, 1624,
    447   1.6  riastrad 		   1704, 1800, 0, 900, 901, 904, 1000, 0,
    448   1.6  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
    449   1.6  riastrad 	/* 0x33 - 1600x1200@60Hz */
    450   1.3  riastrad 	{ DRM_MODE("1600x1200", DRM_MODE_TYPE_DRIVER, 162000, 1600, 1664,
    451   1.3  riastrad 		   1856, 2160, 0, 1200, 1201, 1204, 1250, 0,
    452   1.3  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
    453   1.6  riastrad 	/* 0x34 - 1600x1200@65Hz */
    454   1.3  riastrad 	{ DRM_MODE("1600x1200", DRM_MODE_TYPE_DRIVER, 175500, 1600, 1664,
    455   1.3  riastrad 		   1856, 2160, 0, 1200, 1201, 1204, 1250, 0,
    456   1.3  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
    457   1.6  riastrad 	/* 0x35 - 1600x1200@70Hz */
    458   1.3  riastrad 	{ DRM_MODE("1600x1200", DRM_MODE_TYPE_DRIVER, 189000, 1600, 1664,
    459   1.3  riastrad 		   1856, 2160, 0, 1200, 1201, 1204, 1250, 0,
    460   1.3  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
    461   1.6  riastrad 	/* 0x36 - 1600x1200@75Hz */
    462   1.3  riastrad 	{ DRM_MODE("1600x1200", DRM_MODE_TYPE_DRIVER, 202500, 1600, 1664,
    463   1.3  riastrad 		   1856, 2160, 0, 1200, 1201, 1204, 1250, 0,
    464   1.3  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
    465   1.6  riastrad 	/* 0x37 - 1600x1200@85Hz */
    466   1.3  riastrad 	{ DRM_MODE("1600x1200", DRM_MODE_TYPE_DRIVER, 229500, 1600, 1664,
    467   1.3  riastrad 		   1856, 2160, 0, 1200, 1201, 1204, 1250, 0,
    468   1.3  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
    469   1.6  riastrad 	/* 0x38 - 1600x1200@120Hz RB */
    470   1.3  riastrad 	{ DRM_MODE("1600x1200", DRM_MODE_TYPE_DRIVER, 268250, 1600, 1648,
    471   1.3  riastrad 		   1680, 1760, 0, 1200, 1203, 1207, 1271, 0,
    472   1.3  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
    473   1.6  riastrad 	/* 0x39 - 1680x1050@60Hz RB */
    474   1.3  riastrad 	{ DRM_MODE("1680x1050", DRM_MODE_TYPE_DRIVER, 119000, 1680, 1728,
    475   1.3  riastrad 		   1760, 1840, 0, 1050, 1053, 1059, 1080, 0,
    476   1.3  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
    477   1.6  riastrad 	/* 0x3a - 1680x1050@60Hz */
    478   1.3  riastrad 	{ DRM_MODE("1680x1050", DRM_MODE_TYPE_DRIVER, 146250, 1680, 1784,
    479   1.3  riastrad 		   1960, 2240, 0, 1050, 1053, 1059, 1089, 0,
    480   1.3  riastrad 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
    481   1.6  riastrad 	/* 0x3b - 1680x1050@75Hz */
    482   1.3  riastrad 	{ DRM_MODE("1680x1050", DRM_MODE_TYPE_DRIVER, 187000, 1680, 1800,
    483   1.3  riastrad 		   1976, 2272, 0, 1050, 1053, 1059, 1099, 0,
    484   1.3  riastrad 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
    485   1.6  riastrad 	/* 0x3c - 1680x1050@85Hz */
    486   1.3  riastrad 	{ DRM_MODE("1680x1050", DRM_MODE_TYPE_DRIVER, 214750, 1680, 1808,
    487   1.3  riastrad 		   1984, 2288, 0, 1050, 1053, 1059, 1105, 0,
    488   1.3  riastrad 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
    489   1.6  riastrad 	/* 0x3d - 1680x1050@120Hz RB */
    490   1.3  riastrad 	{ DRM_MODE("1680x1050", DRM_MODE_TYPE_DRIVER, 245500, 1680, 1728,
    491   1.3  riastrad 		   1760, 1840, 0, 1050, 1053, 1059, 1112, 0,
    492   1.3  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
    493   1.6  riastrad 	/* 0x3e - 1792x1344@60Hz */
    494   1.3  riastrad 	{ DRM_MODE("1792x1344", DRM_MODE_TYPE_DRIVER, 204750, 1792, 1920,
    495   1.3  riastrad 		   2120, 2448, 0, 1344, 1345, 1348, 1394, 0,
    496   1.3  riastrad 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
    497   1.6  riastrad 	/* 0x3f - 1792x1344@75Hz */
    498   1.3  riastrad 	{ DRM_MODE("1792x1344", DRM_MODE_TYPE_DRIVER, 261000, 1792, 1888,
    499   1.3  riastrad 		   2104, 2456, 0, 1344, 1345, 1348, 1417, 0,
    500   1.3  riastrad 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
    501   1.6  riastrad 	/* 0x40 - 1792x1344@120Hz RB */
    502   1.3  riastrad 	{ DRM_MODE("1792x1344", DRM_MODE_TYPE_DRIVER, 333250, 1792, 1840,
    503   1.3  riastrad 		   1872, 1952, 0, 1344, 1347, 1351, 1423, 0,
    504   1.3  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
    505   1.6  riastrad 	/* 0x41 - 1856x1392@60Hz */
    506   1.3  riastrad 	{ DRM_MODE("1856x1392", DRM_MODE_TYPE_DRIVER, 218250, 1856, 1952,
    507   1.3  riastrad 		   2176, 2528, 0, 1392, 1393, 1396, 1439, 0,
    508   1.3  riastrad 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
    509   1.6  riastrad 	/* 0x42 - 1856x1392@75Hz */
    510   1.3  riastrad 	{ DRM_MODE("1856x1392", DRM_MODE_TYPE_DRIVER, 288000, 1856, 1984,
    511   1.6  riastrad 		   2208, 2560, 0, 1392, 1393, 1396, 1500, 0,
    512   1.3  riastrad 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
    513   1.6  riastrad 	/* 0x43 - 1856x1392@120Hz RB */
    514   1.3  riastrad 	{ DRM_MODE("1856x1392", DRM_MODE_TYPE_DRIVER, 356500, 1856, 1904,
    515   1.3  riastrad 		   1936, 2016, 0, 1392, 1395, 1399, 1474, 0,
    516   1.3  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
    517   1.6  riastrad 	/* 0x52 - 1920x1080@60Hz */
    518   1.6  riastrad 	{ DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 148500, 1920, 2008,
    519   1.6  riastrad 		   2052, 2200, 0, 1080, 1084, 1089, 1125, 0,
    520   1.6  riastrad 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
    521   1.6  riastrad 	/* 0x44 - 1920x1200@60Hz RB */
    522   1.3  riastrad 	{ DRM_MODE("1920x1200", DRM_MODE_TYPE_DRIVER, 154000, 1920, 1968,
    523   1.3  riastrad 		   2000, 2080, 0, 1200, 1203, 1209, 1235, 0,
    524   1.3  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
    525   1.6  riastrad 	/* 0x45 - 1920x1200@60Hz */
    526   1.3  riastrad 	{ DRM_MODE("1920x1200", DRM_MODE_TYPE_DRIVER, 193250, 1920, 2056,
    527   1.3  riastrad 		   2256, 2592, 0, 1200, 1203, 1209, 1245, 0,
    528   1.3  riastrad 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
    529   1.6  riastrad 	/* 0x46 - 1920x1200@75Hz */
    530   1.3  riastrad 	{ DRM_MODE("1920x1200", DRM_MODE_TYPE_DRIVER, 245250, 1920, 2056,
    531   1.3  riastrad 		   2264, 2608, 0, 1200, 1203, 1209, 1255, 0,
    532   1.3  riastrad 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
    533   1.6  riastrad 	/* 0x47 - 1920x1200@85Hz */
    534   1.3  riastrad 	{ DRM_MODE("1920x1200", DRM_MODE_TYPE_DRIVER, 281250, 1920, 2064,
    535   1.3  riastrad 		   2272, 2624, 0, 1200, 1203, 1209, 1262, 0,
    536   1.3  riastrad 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
    537   1.6  riastrad 	/* 0x48 - 1920x1200@120Hz RB */
    538   1.3  riastrad 	{ DRM_MODE("1920x1200", DRM_MODE_TYPE_DRIVER, 317000, 1920, 1968,
    539   1.3  riastrad 		   2000, 2080, 0, 1200, 1203, 1209, 1271, 0,
    540   1.3  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
    541   1.6  riastrad 	/* 0x49 - 1920x1440@60Hz */
    542   1.3  riastrad 	{ DRM_MODE("1920x1440", DRM_MODE_TYPE_DRIVER, 234000, 1920, 2048,
    543   1.3  riastrad 		   2256, 2600, 0, 1440, 1441, 1444, 1500, 0,
    544   1.3  riastrad 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
    545   1.6  riastrad 	/* 0x4a - 1920x1440@75Hz */
    546   1.3  riastrad 	{ DRM_MODE("1920x1440", DRM_MODE_TYPE_DRIVER, 297000, 1920, 2064,
    547   1.3  riastrad 		   2288, 2640, 0, 1440, 1441, 1444, 1500, 0,
    548   1.3  riastrad 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
    549   1.6  riastrad 	/* 0x4b - 1920x1440@120Hz RB */
    550   1.3  riastrad 	{ DRM_MODE("1920x1440", DRM_MODE_TYPE_DRIVER, 380500, 1920, 1968,
    551   1.3  riastrad 		   2000, 2080, 0, 1440, 1443, 1447, 1525, 0,
    552   1.3  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
    553   1.6  riastrad 	/* 0x54 - 2048x1152@60Hz */
    554   1.6  riastrad 	{ DRM_MODE("2048x1152", DRM_MODE_TYPE_DRIVER, 162000, 2048, 2074,
    555   1.6  riastrad 		   2154, 2250, 0, 1152, 1153, 1156, 1200, 0,
    556   1.6  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
    557   1.6  riastrad 	/* 0x4c - 2560x1600@60Hz RB */
    558   1.3  riastrad 	{ DRM_MODE("2560x1600", DRM_MODE_TYPE_DRIVER, 268500, 2560, 2608,
    559   1.3  riastrad 		   2640, 2720, 0, 1600, 1603, 1609, 1646, 0,
    560   1.3  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
    561   1.6  riastrad 	/* 0x4d - 2560x1600@60Hz */
    562   1.3  riastrad 	{ DRM_MODE("2560x1600", DRM_MODE_TYPE_DRIVER, 348500, 2560, 2752,
    563   1.3  riastrad 		   3032, 3504, 0, 1600, 1603, 1609, 1658, 0,
    564   1.3  riastrad 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
    565   1.6  riastrad 	/* 0x4e - 2560x1600@75Hz */
    566   1.3  riastrad 	{ DRM_MODE("2560x1600", DRM_MODE_TYPE_DRIVER, 443250, 2560, 2768,
    567   1.3  riastrad 		   3048, 3536, 0, 1600, 1603, 1609, 1672, 0,
    568   1.3  riastrad 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
    569   1.6  riastrad 	/* 0x4f - 2560x1600@85Hz */
    570   1.3  riastrad 	{ DRM_MODE("2560x1600", DRM_MODE_TYPE_DRIVER, 505250, 2560, 2768,
    571   1.3  riastrad 		   3048, 3536, 0, 1600, 1603, 1609, 1682, 0,
    572   1.3  riastrad 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
    573   1.6  riastrad 	/* 0x50 - 2560x1600@120Hz RB */
    574   1.3  riastrad 	{ DRM_MODE("2560x1600", DRM_MODE_TYPE_DRIVER, 552750, 2560, 2608,
    575   1.3  riastrad 		   2640, 2720, 0, 1600, 1603, 1609, 1694, 0,
    576   1.3  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
    577   1.6  riastrad 	/* 0x57 - 4096x2160@60Hz RB */
    578   1.6  riastrad 	{ DRM_MODE("4096x2160", DRM_MODE_TYPE_DRIVER, 556744, 4096, 4104,
    579   1.6  riastrad 		   4136, 4176, 0, 2160, 2208, 2216, 2222, 0,
    580   1.6  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
    581   1.6  riastrad 	/* 0x58 - 4096x2160 (at) 59.94Hz RB */
    582   1.6  riastrad 	{ DRM_MODE("4096x2160", DRM_MODE_TYPE_DRIVER, 556188, 4096, 4104,
    583   1.6  riastrad 		   4136, 4176, 0, 2160, 2208, 2216, 2222, 0,
    584   1.6  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
    585   1.3  riastrad };
    586   1.3  riastrad 
    587   1.3  riastrad /*
    588   1.3  riastrad  * These more or less come from the DMT spec.  The 720x400 modes are
    589   1.3  riastrad  * inferred from historical 80x25 practice.  The 640x480@67 and 832x624@75
    590   1.3  riastrad  * modes are old-school Mac modes.  The EDID spec says the 1152x864@75 mode
    591   1.3  riastrad  * should be 1152x870, again for the Mac, but instead we use the x864 DMT
    592   1.3  riastrad  * mode.
    593   1.3  riastrad  *
    594   1.3  riastrad  * The DMT modes have been fact-checked; the rest are mild guesses.
    595   1.3  riastrad  */
    596   1.3  riastrad static const struct drm_display_mode edid_est_modes[] = {
    597   1.3  riastrad 	{ DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 40000, 800, 840,
    598   1.3  riastrad 		   968, 1056, 0, 600, 601, 605, 628, 0,
    599   1.3  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, /* 800x600@60Hz */
    600   1.3  riastrad 	{ DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 36000, 800, 824,
    601   1.3  riastrad 		   896, 1024, 0, 600, 601, 603,  625, 0,
    602   1.3  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, /* 800x600@56Hz */
    603   1.3  riastrad 	{ DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 31500, 640, 656,
    604   1.3  riastrad 		   720, 840, 0, 480, 481, 484, 500, 0,
    605   1.3  riastrad 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, /* 640x480@75Hz */
    606   1.3  riastrad 	{ DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 31500, 640, 664,
    607   1.9  riastrad 		   704,  832, 0, 480, 489, 492, 520, 0,
    608   1.3  riastrad 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, /* 640x480@72Hz */
    609   1.3  riastrad 	{ DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 30240, 640, 704,
    610   1.3  riastrad 		   768,  864, 0, 480, 483, 486, 525, 0,
    611   1.3  riastrad 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, /* 640x480@67Hz */
    612   1.9  riastrad 	{ DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 25175, 640, 656,
    613   1.3  riastrad 		   752, 800, 0, 480, 490, 492, 525, 0,
    614   1.3  riastrad 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, /* 640x480@60Hz */
    615   1.3  riastrad 	{ DRM_MODE("720x400", DRM_MODE_TYPE_DRIVER, 35500, 720, 738,
    616   1.3  riastrad 		   846, 900, 0, 400, 421, 423,  449, 0,
    617   1.3  riastrad 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, /* 720x400@88Hz */
    618   1.3  riastrad 	{ DRM_MODE("720x400", DRM_MODE_TYPE_DRIVER, 28320, 720, 738,
    619   1.3  riastrad 		   846,  900, 0, 400, 412, 414, 449, 0,
    620   1.3  riastrad 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, /* 720x400@70Hz */
    621   1.3  riastrad 	{ DRM_MODE("1280x1024", DRM_MODE_TYPE_DRIVER, 135000, 1280, 1296,
    622   1.3  riastrad 		   1440, 1688, 0, 1024, 1025, 1028, 1066, 0,
    623   1.3  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, /* 1280x1024@75Hz */
    624   1.9  riastrad 	{ DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 78750, 1024, 1040,
    625   1.3  riastrad 		   1136, 1312, 0,  768, 769, 772, 800, 0,
    626   1.3  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, /* 1024x768@75Hz */
    627   1.3  riastrad 	{ DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 75000, 1024, 1048,
    628   1.3  riastrad 		   1184, 1328, 0,  768, 771, 777, 806, 0,
    629   1.3  riastrad 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, /* 1024x768@70Hz */
    630   1.3  riastrad 	{ DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 65000, 1024, 1048,
    631   1.3  riastrad 		   1184, 1344, 0,  768, 771, 777, 806, 0,
    632   1.3  riastrad 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, /* 1024x768@60Hz */
    633   1.3  riastrad 	{ DRM_MODE("1024x768i", DRM_MODE_TYPE_DRIVER,44900, 1024, 1032,
    634   1.3  riastrad 		   1208, 1264, 0, 768, 768, 776, 817, 0,
    635   1.3  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC | DRM_MODE_FLAG_INTERLACE) }, /* 1024x768@43Hz */
    636   1.3  riastrad 	{ DRM_MODE("832x624", DRM_MODE_TYPE_DRIVER, 57284, 832, 864,
    637   1.3  riastrad 		   928, 1152, 0, 624, 625, 628, 667, 0,
    638   1.3  riastrad 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, /* 832x624@75Hz */
    639   1.3  riastrad 	{ DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 49500, 800, 816,
    640   1.3  riastrad 		   896, 1056, 0, 600, 601, 604,  625, 0,
    641   1.3  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, /* 800x600@75Hz */
    642   1.3  riastrad 	{ DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 50000, 800, 856,
    643   1.3  riastrad 		   976, 1040, 0, 600, 637, 643, 666, 0,
    644   1.3  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, /* 800x600@72Hz */
    645   1.3  riastrad 	{ DRM_MODE("1152x864", DRM_MODE_TYPE_DRIVER, 108000, 1152, 1216,
    646   1.3  riastrad 		   1344, 1600, 0,  864, 865, 868, 900, 0,
    647   1.3  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, /* 1152x864@75Hz */
    648   1.3  riastrad };
    649   1.3  riastrad 
    650   1.3  riastrad struct minimode {
    651   1.3  riastrad 	short w;
    652   1.3  riastrad 	short h;
    653   1.3  riastrad 	short r;
    654   1.3  riastrad 	short rb;
    655   1.3  riastrad };
    656   1.3  riastrad 
    657   1.3  riastrad static const struct minimode est3_modes[] = {
    658   1.3  riastrad 	/* byte 6 */
    659   1.3  riastrad 	{ 640, 350, 85, 0 },
    660   1.3  riastrad 	{ 640, 400, 85, 0 },
    661   1.3  riastrad 	{ 720, 400, 85, 0 },
    662   1.3  riastrad 	{ 640, 480, 85, 0 },
    663   1.3  riastrad 	{ 848, 480, 60, 0 },
    664   1.3  riastrad 	{ 800, 600, 85, 0 },
    665   1.3  riastrad 	{ 1024, 768, 85, 0 },
    666   1.3  riastrad 	{ 1152, 864, 75, 0 },
    667   1.3  riastrad 	/* byte 7 */
    668   1.3  riastrad 	{ 1280, 768, 60, 1 },
    669   1.3  riastrad 	{ 1280, 768, 60, 0 },
    670   1.3  riastrad 	{ 1280, 768, 75, 0 },
    671   1.3  riastrad 	{ 1280, 768, 85, 0 },
    672   1.3  riastrad 	{ 1280, 960, 60, 0 },
    673   1.3  riastrad 	{ 1280, 960, 85, 0 },
    674   1.3  riastrad 	{ 1280, 1024, 60, 0 },
    675   1.3  riastrad 	{ 1280, 1024, 85, 0 },
    676   1.3  riastrad 	/* byte 8 */
    677   1.3  riastrad 	{ 1360, 768, 60, 0 },
    678   1.3  riastrad 	{ 1440, 900, 60, 1 },
    679   1.3  riastrad 	{ 1440, 900, 60, 0 },
    680   1.3  riastrad 	{ 1440, 900, 75, 0 },
    681   1.3  riastrad 	{ 1440, 900, 85, 0 },
    682   1.3  riastrad 	{ 1400, 1050, 60, 1 },
    683   1.3  riastrad 	{ 1400, 1050, 60, 0 },
    684   1.3  riastrad 	{ 1400, 1050, 75, 0 },
    685   1.3  riastrad 	/* byte 9 */
    686   1.3  riastrad 	{ 1400, 1050, 85, 0 },
    687   1.3  riastrad 	{ 1680, 1050, 60, 1 },
    688   1.3  riastrad 	{ 1680, 1050, 60, 0 },
    689   1.3  riastrad 	{ 1680, 1050, 75, 0 },
    690   1.3  riastrad 	{ 1680, 1050, 85, 0 },
    691   1.3  riastrad 	{ 1600, 1200, 60, 0 },
    692   1.3  riastrad 	{ 1600, 1200, 65, 0 },
    693   1.3  riastrad 	{ 1600, 1200, 70, 0 },
    694   1.3  riastrad 	/* byte 10 */
    695   1.3  riastrad 	{ 1600, 1200, 75, 0 },
    696   1.3  riastrad 	{ 1600, 1200, 85, 0 },
    697   1.3  riastrad 	{ 1792, 1344, 60, 0 },
    698   1.3  riastrad 	{ 1792, 1344, 75, 0 },
    699   1.3  riastrad 	{ 1856, 1392, 60, 0 },
    700   1.3  riastrad 	{ 1856, 1392, 75, 0 },
    701   1.3  riastrad 	{ 1920, 1200, 60, 1 },
    702   1.3  riastrad 	{ 1920, 1200, 60, 0 },
    703   1.3  riastrad 	/* byte 11 */
    704   1.3  riastrad 	{ 1920, 1200, 75, 0 },
    705   1.3  riastrad 	{ 1920, 1200, 85, 0 },
    706   1.3  riastrad 	{ 1920, 1440, 60, 0 },
    707   1.3  riastrad 	{ 1920, 1440, 75, 0 },
    708   1.3  riastrad };
    709   1.3  riastrad 
    710   1.3  riastrad static const struct minimode extra_modes[] = {
    711   1.3  riastrad 	{ 1024, 576,  60, 0 },
    712   1.3  riastrad 	{ 1366, 768,  60, 0 },
    713   1.3  riastrad 	{ 1600, 900,  60, 0 },
    714   1.3  riastrad 	{ 1680, 945,  60, 0 },
    715   1.3  riastrad 	{ 1920, 1080, 60, 0 },
    716   1.3  riastrad 	{ 2048, 1152, 60, 0 },
    717   1.3  riastrad 	{ 2048, 1536, 60, 0 },
    718   1.3  riastrad };
    719   1.3  riastrad 
    720   1.3  riastrad /*
    721   1.9  riastrad  * From CEA/CTA-861 spec.
    722   1.9  riastrad  *
    723   1.9  riastrad  * Do not access directly, instead always use cea_mode_for_vic().
    724   1.3  riastrad  */
    725   1.9  riastrad static const struct drm_display_mode edid_cea_modes_1[] = {
    726   1.9  riastrad 	/* 1 - 640x480@60Hz 4:3 */
    727   1.3  riastrad 	{ DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 25175, 640, 656,
    728   1.3  riastrad 		   752, 800, 0, 480, 490, 492, 525, 0,
    729   1.3  riastrad 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
    730   1.3  riastrad 	  .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, },
    731   1.9  riastrad 	/* 2 - 720x480@60Hz 4:3 */
    732   1.3  riastrad 	{ DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 27000, 720, 736,
    733   1.3  riastrad 		   798, 858, 0, 480, 489, 495, 525, 0,
    734   1.3  riastrad 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
    735   1.3  riastrad 	  .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, },
    736   1.9  riastrad 	/* 3 - 720x480@60Hz 16:9 */
    737   1.3  riastrad 	{ DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 27000, 720, 736,
    738   1.3  riastrad 		   798, 858, 0, 480, 489, 495, 525, 0,
    739   1.3  riastrad 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
    740   1.3  riastrad 	  .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
    741   1.9  riastrad 	/* 4 - 1280x720@60Hz 16:9 */
    742   1.3  riastrad 	{ DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 74250, 1280, 1390,
    743   1.3  riastrad 		   1430, 1650, 0, 720, 725, 730, 750, 0,
    744   1.3  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
    745   1.3  riastrad 	  .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
    746   1.9  riastrad 	/* 5 - 1920x1080i@60Hz 16:9 */
    747   1.3  riastrad 	{ DRM_MODE("1920x1080i", DRM_MODE_TYPE_DRIVER, 74250, 1920, 2008,
    748   1.3  riastrad 		   2052, 2200, 0, 1080, 1084, 1094, 1125, 0,
    749   1.3  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC |
    750   1.9  riastrad 		   DRM_MODE_FLAG_INTERLACE),
    751   1.3  riastrad 	  .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
    752   1.9  riastrad 	/* 6 - 720(1440)x480i@60Hz 4:3 */
    753   1.6  riastrad 	{ DRM_MODE("720x480i", DRM_MODE_TYPE_DRIVER, 13500, 720, 739,
    754   1.6  riastrad 		   801, 858, 0, 480, 488, 494, 525, 0,
    755   1.3  riastrad 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
    756   1.9  riastrad 		   DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK),
    757   1.3  riastrad 	  .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, },
    758   1.9  riastrad 	/* 7 - 720(1440)x480i@60Hz 16:9 */
    759   1.6  riastrad 	{ DRM_MODE("720x480i", DRM_MODE_TYPE_DRIVER, 13500, 720, 739,
    760   1.6  riastrad 		   801, 858, 0, 480, 488, 494, 525, 0,
    761   1.3  riastrad 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
    762   1.9  riastrad 		   DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK),
    763   1.3  riastrad 	  .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
    764   1.9  riastrad 	/* 8 - 720(1440)x240@60Hz 4:3 */
    765   1.6  riastrad 	{ DRM_MODE("720x240", DRM_MODE_TYPE_DRIVER, 13500, 720, 739,
    766   1.6  riastrad 		   801, 858, 0, 240, 244, 247, 262, 0,
    767   1.3  riastrad 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
    768   1.9  riastrad 		   DRM_MODE_FLAG_DBLCLK),
    769   1.3  riastrad 	  .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, },
    770   1.9  riastrad 	/* 9 - 720(1440)x240@60Hz 16:9 */
    771   1.6  riastrad 	{ DRM_MODE("720x240", DRM_MODE_TYPE_DRIVER, 13500, 720, 739,
    772   1.6  riastrad 		   801, 858, 0, 240, 244, 247, 262, 0,
    773   1.3  riastrad 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
    774   1.9  riastrad 		   DRM_MODE_FLAG_DBLCLK),
    775   1.3  riastrad 	  .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
    776   1.9  riastrad 	/* 10 - 2880x480i@60Hz 4:3 */
    777   1.3  riastrad 	{ DRM_MODE("2880x480i", DRM_MODE_TYPE_DRIVER, 54000, 2880, 2956,
    778   1.3  riastrad 		   3204, 3432, 0, 480, 488, 494, 525, 0,
    779   1.3  riastrad 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
    780   1.9  riastrad 		   DRM_MODE_FLAG_INTERLACE),
    781   1.3  riastrad 	  .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, },
    782   1.9  riastrad 	/* 11 - 2880x480i@60Hz 16:9 */
    783   1.3  riastrad 	{ DRM_MODE("2880x480i", DRM_MODE_TYPE_DRIVER, 54000, 2880, 2956,
    784   1.3  riastrad 		   3204, 3432, 0, 480, 488, 494, 525, 0,
    785   1.3  riastrad 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
    786   1.9  riastrad 		   DRM_MODE_FLAG_INTERLACE),
    787   1.3  riastrad 	  .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
    788   1.9  riastrad 	/* 12 - 2880x240@60Hz 4:3 */
    789   1.3  riastrad 	{ DRM_MODE("2880x240", DRM_MODE_TYPE_DRIVER, 54000, 2880, 2956,
    790   1.3  riastrad 		   3204, 3432, 0, 240, 244, 247, 262, 0,
    791   1.3  riastrad 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
    792   1.3  riastrad 	  .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, },
    793   1.9  riastrad 	/* 13 - 2880x240@60Hz 16:9 */
    794   1.3  riastrad 	{ DRM_MODE("2880x240", DRM_MODE_TYPE_DRIVER, 54000, 2880, 2956,
    795   1.3  riastrad 		   3204, 3432, 0, 240, 244, 247, 262, 0,
    796   1.3  riastrad 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
    797   1.3  riastrad 	  .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
    798   1.9  riastrad 	/* 14 - 1440x480@60Hz 4:3 */
    799   1.3  riastrad 	{ DRM_MODE("1440x480", DRM_MODE_TYPE_DRIVER, 54000, 1440, 1472,
    800   1.3  riastrad 		   1596, 1716, 0, 480, 489, 495, 525, 0,
    801   1.3  riastrad 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
    802   1.3  riastrad 	  .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, },
    803   1.9  riastrad 	/* 15 - 1440x480@60Hz 16:9 */
    804   1.3  riastrad 	{ DRM_MODE("1440x480", DRM_MODE_TYPE_DRIVER, 54000, 1440, 1472,
    805   1.3  riastrad 		   1596, 1716, 0, 480, 489, 495, 525, 0,
    806   1.3  riastrad 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
    807   1.3  riastrad 	  .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
    808   1.9  riastrad 	/* 16 - 1920x1080@60Hz 16:9 */
    809   1.3  riastrad 	{ DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 148500, 1920, 2008,
    810   1.3  riastrad 		   2052, 2200, 0, 1080, 1084, 1089, 1125, 0,
    811   1.3  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
    812   1.3  riastrad 	  .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
    813   1.9  riastrad 	/* 17 - 720x576@50Hz 4:3 */
    814   1.3  riastrad 	{ DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 27000, 720, 732,
    815   1.3  riastrad 		   796, 864, 0, 576, 581, 586, 625, 0,
    816   1.3  riastrad 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
    817   1.3  riastrad 	  .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, },
    818   1.9  riastrad 	/* 18 - 720x576@50Hz 16:9 */
    819   1.3  riastrad 	{ DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 27000, 720, 732,
    820   1.3  riastrad 		   796, 864, 0, 576, 581, 586, 625, 0,
    821   1.3  riastrad 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
    822   1.3  riastrad 	  .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
    823   1.9  riastrad 	/* 19 - 1280x720@50Hz 16:9 */
    824   1.3  riastrad 	{ DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 74250, 1280, 1720,
    825   1.3  riastrad 		   1760, 1980, 0, 720, 725, 730, 750, 0,
    826   1.3  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
    827   1.3  riastrad 	  .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
    828   1.9  riastrad 	/* 20 - 1920x1080i@50Hz 16:9 */
    829   1.3  riastrad 	{ DRM_MODE("1920x1080i", DRM_MODE_TYPE_DRIVER, 74250, 1920, 2448,
    830   1.3  riastrad 		   2492, 2640, 0, 1080, 1084, 1094, 1125, 0,
    831   1.3  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC |
    832   1.9  riastrad 		   DRM_MODE_FLAG_INTERLACE),
    833   1.3  riastrad 	  .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
    834   1.9  riastrad 	/* 21 - 720(1440)x576i@50Hz 4:3 */
    835   1.6  riastrad 	{ DRM_MODE("720x576i", DRM_MODE_TYPE_DRIVER, 13500, 720, 732,
    836   1.6  riastrad 		   795, 864, 0, 576, 580, 586, 625, 0,
    837   1.3  riastrad 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
    838   1.9  riastrad 		   DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK),
    839   1.3  riastrad 	  .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, },
    840   1.9  riastrad 	/* 22 - 720(1440)x576i@50Hz 16:9 */
    841   1.6  riastrad 	{ DRM_MODE("720x576i", DRM_MODE_TYPE_DRIVER, 13500, 720, 732,
    842   1.6  riastrad 		   795, 864, 0, 576, 580, 586, 625, 0,
    843   1.3  riastrad 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
    844   1.9  riastrad 		   DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK),
    845   1.3  riastrad 	  .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
    846   1.9  riastrad 	/* 23 - 720(1440)x288@50Hz 4:3 */
    847   1.6  riastrad 	{ DRM_MODE("720x288", DRM_MODE_TYPE_DRIVER, 13500, 720, 732,
    848   1.6  riastrad 		   795, 864, 0, 288, 290, 293, 312, 0,
    849   1.3  riastrad 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
    850   1.9  riastrad 		   DRM_MODE_FLAG_DBLCLK),
    851   1.3  riastrad 	  .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, },
    852   1.9  riastrad 	/* 24 - 720(1440)x288@50Hz 16:9 */
    853   1.6  riastrad 	{ DRM_MODE("720x288", DRM_MODE_TYPE_DRIVER, 13500, 720, 732,
    854   1.6  riastrad 		   795, 864, 0, 288, 290, 293, 312, 0,
    855   1.3  riastrad 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
    856   1.9  riastrad 		   DRM_MODE_FLAG_DBLCLK),
    857   1.3  riastrad 	  .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
    858   1.9  riastrad 	/* 25 - 2880x576i@50Hz 4:3 */
    859   1.3  riastrad 	{ DRM_MODE("2880x576i", DRM_MODE_TYPE_DRIVER, 54000, 2880, 2928,
    860   1.3  riastrad 		   3180, 3456, 0, 576, 580, 586, 625, 0,
    861   1.3  riastrad 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
    862   1.9  riastrad 		   DRM_MODE_FLAG_INTERLACE),
    863   1.3  riastrad 	  .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, },
    864   1.9  riastrad 	/* 26 - 2880x576i@50Hz 16:9 */
    865   1.3  riastrad 	{ DRM_MODE("2880x576i", DRM_MODE_TYPE_DRIVER, 54000, 2880, 2928,
    866   1.3  riastrad 		   3180, 3456, 0, 576, 580, 586, 625, 0,
    867   1.3  riastrad 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
    868   1.9  riastrad 		   DRM_MODE_FLAG_INTERLACE),
    869   1.3  riastrad 	  .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
    870   1.9  riastrad 	/* 27 - 2880x288@50Hz 4:3 */
    871   1.3  riastrad 	{ DRM_MODE("2880x288", DRM_MODE_TYPE_DRIVER, 54000, 2880, 2928,
    872   1.3  riastrad 		   3180, 3456, 0, 288, 290, 293, 312, 0,
    873   1.3  riastrad 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
    874   1.3  riastrad 	  .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, },
    875   1.9  riastrad 	/* 28 - 2880x288@50Hz 16:9 */
    876   1.3  riastrad 	{ DRM_MODE("2880x288", DRM_MODE_TYPE_DRIVER, 54000, 2880, 2928,
    877   1.3  riastrad 		   3180, 3456, 0, 288, 290, 293, 312, 0,
    878   1.3  riastrad 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
    879   1.3  riastrad 	  .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
    880   1.9  riastrad 	/* 29 - 1440x576@50Hz 4:3 */
    881   1.3  riastrad 	{ DRM_MODE("1440x576", DRM_MODE_TYPE_DRIVER, 54000, 1440, 1464,
    882   1.3  riastrad 		   1592, 1728, 0, 576, 581, 586, 625, 0,
    883   1.3  riastrad 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
    884   1.3  riastrad 	  .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, },
    885   1.9  riastrad 	/* 30 - 1440x576@50Hz 16:9 */
    886   1.3  riastrad 	{ DRM_MODE("1440x576", DRM_MODE_TYPE_DRIVER, 54000, 1440, 1464,
    887   1.3  riastrad 		   1592, 1728, 0, 576, 581, 586, 625, 0,
    888   1.3  riastrad 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
    889   1.3  riastrad 	  .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
    890   1.9  riastrad 	/* 31 - 1920x1080@50Hz 16:9 */
    891   1.3  riastrad 	{ DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 148500, 1920, 2448,
    892   1.3  riastrad 		   2492, 2640, 0, 1080, 1084, 1089, 1125, 0,
    893   1.3  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
    894   1.3  riastrad 	  .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
    895   1.9  riastrad 	/* 32 - 1920x1080@24Hz 16:9 */
    896   1.3  riastrad 	{ DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 74250, 1920, 2558,
    897   1.3  riastrad 		   2602, 2750, 0, 1080, 1084, 1089, 1125, 0,
    898   1.3  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
    899   1.3  riastrad 	  .vrefresh = 24, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
    900   1.9  riastrad 	/* 33 - 1920x1080@25Hz 16:9 */
    901   1.3  riastrad 	{ DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 74250, 1920, 2448,
    902   1.3  riastrad 		   2492, 2640, 0, 1080, 1084, 1089, 1125, 0,
    903   1.3  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
    904   1.3  riastrad 	  .vrefresh = 25, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
    905   1.9  riastrad 	/* 34 - 1920x1080@30Hz 16:9 */
    906   1.3  riastrad 	{ DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 74250, 1920, 2008,
    907   1.3  riastrad 		   2052, 2200, 0, 1080, 1084, 1089, 1125, 0,
    908   1.3  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
    909   1.3  riastrad 	  .vrefresh = 30, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
    910   1.9  riastrad 	/* 35 - 2880x480@60Hz 4:3 */
    911   1.3  riastrad 	{ DRM_MODE("2880x480", DRM_MODE_TYPE_DRIVER, 108000, 2880, 2944,
    912   1.3  riastrad 		   3192, 3432, 0, 480, 489, 495, 525, 0,
    913   1.3  riastrad 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
    914   1.3  riastrad 	  .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, },
    915   1.9  riastrad 	/* 36 - 2880x480@60Hz 16:9 */
    916   1.3  riastrad 	{ DRM_MODE("2880x480", DRM_MODE_TYPE_DRIVER, 108000, 2880, 2944,
    917   1.3  riastrad 		   3192, 3432, 0, 480, 489, 495, 525, 0,
    918   1.3  riastrad 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
    919   1.3  riastrad 	  .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
    920   1.9  riastrad 	/* 37 - 2880x576@50Hz 4:3 */
    921   1.3  riastrad 	{ DRM_MODE("2880x576", DRM_MODE_TYPE_DRIVER, 108000, 2880, 2928,
    922   1.3  riastrad 		   3184, 3456, 0, 576, 581, 586, 625, 0,
    923   1.3  riastrad 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
    924   1.3  riastrad 	  .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, },
    925   1.9  riastrad 	/* 38 - 2880x576@50Hz 16:9 */
    926   1.3  riastrad 	{ DRM_MODE("2880x576", DRM_MODE_TYPE_DRIVER, 108000, 2880, 2928,
    927   1.3  riastrad 		   3184, 3456, 0, 576, 581, 586, 625, 0,
    928   1.3  riastrad 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
    929   1.3  riastrad 	  .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
    930   1.9  riastrad 	/* 39 - 1920x1080i@50Hz 16:9 */
    931   1.3  riastrad 	{ DRM_MODE("1920x1080i", DRM_MODE_TYPE_DRIVER, 72000, 1920, 1952,
    932   1.3  riastrad 		   2120, 2304, 0, 1080, 1126, 1136, 1250, 0,
    933   1.3  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC |
    934   1.9  riastrad 		   DRM_MODE_FLAG_INTERLACE),
    935   1.3  riastrad 	  .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
    936   1.9  riastrad 	/* 40 - 1920x1080i@100Hz 16:9 */
    937   1.3  riastrad 	{ DRM_MODE("1920x1080i", DRM_MODE_TYPE_DRIVER, 148500, 1920, 2448,
    938   1.3  riastrad 		   2492, 2640, 0, 1080, 1084, 1094, 1125, 0,
    939   1.3  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC |
    940   1.9  riastrad 		   DRM_MODE_FLAG_INTERLACE),
    941   1.3  riastrad 	  .vrefresh = 100, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
    942   1.9  riastrad 	/* 41 - 1280x720@100Hz 16:9 */
    943   1.3  riastrad 	{ DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 148500, 1280, 1720,
    944   1.3  riastrad 		   1760, 1980, 0, 720, 725, 730, 750, 0,
    945   1.3  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
    946   1.3  riastrad 	  .vrefresh = 100, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
    947   1.9  riastrad 	/* 42 - 720x576@100Hz 4:3 */
    948   1.3  riastrad 	{ DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 54000, 720, 732,
    949   1.3  riastrad 		   796, 864, 0, 576, 581, 586, 625, 0,
    950   1.3  riastrad 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
    951   1.3  riastrad 	  .vrefresh = 100, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, },
    952   1.9  riastrad 	/* 43 - 720x576@100Hz 16:9 */
    953   1.3  riastrad 	{ DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 54000, 720, 732,
    954   1.3  riastrad 		   796, 864, 0, 576, 581, 586, 625, 0,
    955   1.3  riastrad 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
    956   1.3  riastrad 	  .vrefresh = 100, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
    957   1.9  riastrad 	/* 44 - 720(1440)x576i@100Hz 4:3 */
    958   1.6  riastrad 	{ DRM_MODE("720x576i", DRM_MODE_TYPE_DRIVER, 27000, 720, 732,
    959   1.6  riastrad 		   795, 864, 0, 576, 580, 586, 625, 0,
    960   1.3  riastrad 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
    961   1.9  riastrad 		   DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK),
    962   1.3  riastrad 	  .vrefresh = 100, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, },
    963   1.9  riastrad 	/* 45 - 720(1440)x576i@100Hz 16:9 */
    964   1.6  riastrad 	{ DRM_MODE("720x576i", DRM_MODE_TYPE_DRIVER, 27000, 720, 732,
    965   1.6  riastrad 		   795, 864, 0, 576, 580, 586, 625, 0,
    966   1.3  riastrad 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
    967   1.9  riastrad 		   DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK),
    968   1.3  riastrad 	  .vrefresh = 100, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
    969   1.9  riastrad 	/* 46 - 1920x1080i@120Hz 16:9 */
    970   1.3  riastrad 	{ DRM_MODE("1920x1080i", DRM_MODE_TYPE_DRIVER, 148500, 1920, 2008,
    971   1.3  riastrad 		   2052, 2200, 0, 1080, 1084, 1094, 1125, 0,
    972   1.3  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC |
    973   1.9  riastrad 		   DRM_MODE_FLAG_INTERLACE),
    974   1.3  riastrad 	  .vrefresh = 120, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
    975   1.9  riastrad 	/* 47 - 1280x720@120Hz 16:9 */
    976   1.3  riastrad 	{ DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 148500, 1280, 1390,
    977   1.3  riastrad 		   1430, 1650, 0, 720, 725, 730, 750, 0,
    978   1.3  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
    979   1.3  riastrad 	  .vrefresh = 120, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
    980   1.9  riastrad 	/* 48 - 720x480@120Hz 4:3 */
    981   1.3  riastrad 	{ DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 54000, 720, 736,
    982   1.3  riastrad 		   798, 858, 0, 480, 489, 495, 525, 0,
    983   1.3  riastrad 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
    984   1.3  riastrad 	  .vrefresh = 120, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, },
    985   1.9  riastrad 	/* 49 - 720x480@120Hz 16:9 */
    986   1.3  riastrad 	{ DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 54000, 720, 736,
    987   1.3  riastrad 		   798, 858, 0, 480, 489, 495, 525, 0,
    988   1.3  riastrad 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
    989   1.3  riastrad 	  .vrefresh = 120, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
    990   1.9  riastrad 	/* 50 - 720(1440)x480i@120Hz 4:3 */
    991   1.6  riastrad 	{ DRM_MODE("720x480i", DRM_MODE_TYPE_DRIVER, 27000, 720, 739,
    992   1.6  riastrad 		   801, 858, 0, 480, 488, 494, 525, 0,
    993   1.3  riastrad 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
    994   1.9  riastrad 		   DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK),
    995   1.3  riastrad 	  .vrefresh = 120, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, },
    996   1.9  riastrad 	/* 51 - 720(1440)x480i@120Hz 16:9 */
    997   1.6  riastrad 	{ DRM_MODE("720x480i", DRM_MODE_TYPE_DRIVER, 27000, 720, 739,
    998   1.6  riastrad 		   801, 858, 0, 480, 488, 494, 525, 0,
    999   1.3  riastrad 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
   1000   1.9  riastrad 		   DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK),
   1001   1.3  riastrad 	  .vrefresh = 120, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
   1002   1.9  riastrad 	/* 52 - 720x576@200Hz 4:3 */
   1003   1.3  riastrad 	{ DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 108000, 720, 732,
   1004   1.3  riastrad 		   796, 864, 0, 576, 581, 586, 625, 0,
   1005   1.3  riastrad 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
   1006   1.3  riastrad 	  .vrefresh = 200, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, },
   1007   1.9  riastrad 	/* 53 - 720x576@200Hz 16:9 */
   1008   1.3  riastrad 	{ DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 108000, 720, 732,
   1009   1.3  riastrad 		   796, 864, 0, 576, 581, 586, 625, 0,
   1010   1.3  riastrad 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
   1011   1.3  riastrad 	  .vrefresh = 200, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
   1012   1.9  riastrad 	/* 54 - 720(1440)x576i@200Hz 4:3 */
   1013   1.6  riastrad 	{ DRM_MODE("720x576i", DRM_MODE_TYPE_DRIVER, 54000, 720, 732,
   1014   1.6  riastrad 		   795, 864, 0, 576, 580, 586, 625, 0,
   1015   1.3  riastrad 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
   1016   1.9  riastrad 		   DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK),
   1017   1.3  riastrad 	  .vrefresh = 200, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, },
   1018   1.9  riastrad 	/* 55 - 720(1440)x576i@200Hz 16:9 */
   1019   1.6  riastrad 	{ DRM_MODE("720x576i", DRM_MODE_TYPE_DRIVER, 54000, 720, 732,
   1020   1.6  riastrad 		   795, 864, 0, 576, 580, 586, 625, 0,
   1021   1.3  riastrad 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
   1022   1.9  riastrad 		   DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK),
   1023   1.3  riastrad 	  .vrefresh = 200, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
   1024   1.9  riastrad 	/* 56 - 720x480@240Hz 4:3 */
   1025   1.3  riastrad 	{ DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 108000, 720, 736,
   1026   1.3  riastrad 		   798, 858, 0, 480, 489, 495, 525, 0,
   1027   1.3  riastrad 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
   1028   1.3  riastrad 	  .vrefresh = 240, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, },
   1029   1.9  riastrad 	/* 57 - 720x480@240Hz 16:9 */
   1030   1.3  riastrad 	{ DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 108000, 720, 736,
   1031   1.3  riastrad 		   798, 858, 0, 480, 489, 495, 525, 0,
   1032   1.3  riastrad 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
   1033   1.3  riastrad 	  .vrefresh = 240, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
   1034   1.9  riastrad 	/* 58 - 720(1440)x480i@240Hz 4:3 */
   1035   1.6  riastrad 	{ DRM_MODE("720x480i", DRM_MODE_TYPE_DRIVER, 54000, 720, 739,
   1036   1.6  riastrad 		   801, 858, 0, 480, 488, 494, 525, 0,
   1037   1.3  riastrad 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
   1038   1.9  riastrad 		   DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK),
   1039   1.3  riastrad 	  .vrefresh = 240, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, },
   1040   1.9  riastrad 	/* 59 - 720(1440)x480i@240Hz 16:9 */
   1041   1.6  riastrad 	{ DRM_MODE("720x480i", DRM_MODE_TYPE_DRIVER, 54000, 720, 739,
   1042   1.6  riastrad 		   801, 858, 0, 480, 488, 494, 525, 0,
   1043   1.3  riastrad 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
   1044   1.9  riastrad 		   DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK),
   1045   1.3  riastrad 	  .vrefresh = 240, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
   1046   1.9  riastrad 	/* 60 - 1280x720@24Hz 16:9 */
   1047   1.3  riastrad 	{ DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 59400, 1280, 3040,
   1048   1.3  riastrad 		   3080, 3300, 0, 720, 725, 730, 750, 0,
   1049   1.3  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
   1050   1.3  riastrad 	  .vrefresh = 24, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
   1051   1.9  riastrad 	/* 61 - 1280x720@25Hz 16:9 */
   1052   1.3  riastrad 	{ DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 74250, 1280, 3700,
   1053   1.3  riastrad 		   3740, 3960, 0, 720, 725, 730, 750, 0,
   1054   1.3  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
   1055   1.3  riastrad 	  .vrefresh = 25, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
   1056   1.9  riastrad 	/* 62 - 1280x720@30Hz 16:9 */
   1057   1.3  riastrad 	{ DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 74250, 1280, 3040,
   1058   1.3  riastrad 		   3080, 3300, 0, 720, 725, 730, 750, 0,
   1059   1.3  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
   1060   1.3  riastrad 	  .vrefresh = 30, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
   1061   1.9  riastrad 	/* 63 - 1920x1080@120Hz 16:9 */
   1062   1.3  riastrad 	{ DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 297000, 1920, 2008,
   1063   1.3  riastrad 		   2052, 2200, 0, 1080, 1084, 1089, 1125, 0,
   1064   1.3  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
   1065   1.9  riastrad 	  .vrefresh = 120, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
   1066   1.9  riastrad 	/* 64 - 1920x1080@100Hz 16:9 */
   1067   1.9  riastrad 	{ DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 297000, 1920, 2448,
   1068   1.9  riastrad 		   2492, 2640, 0, 1080, 1084, 1089, 1125, 0,
   1069   1.9  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
   1070   1.9  riastrad 	  .vrefresh = 100, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
   1071   1.9  riastrad 	/* 65 - 1280x720@24Hz 64:27 */
   1072   1.9  riastrad 	{ DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 59400, 1280, 3040,
   1073   1.9  riastrad 		   3080, 3300, 0, 720, 725, 730, 750, 0,
   1074   1.9  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
   1075   1.9  riastrad 	  .vrefresh = 24, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
   1076   1.9  riastrad 	/* 66 - 1280x720@25Hz 64:27 */
   1077   1.9  riastrad 	{ DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 74250, 1280, 3700,
   1078   1.9  riastrad 		   3740, 3960, 0, 720, 725, 730, 750, 0,
   1079   1.9  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
   1080   1.9  riastrad 	  .vrefresh = 25, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
   1081   1.9  riastrad 	/* 67 - 1280x720@30Hz 64:27 */
   1082   1.9  riastrad 	{ DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 74250, 1280, 3040,
   1083   1.9  riastrad 		   3080, 3300, 0, 720, 725, 730, 750, 0,
   1084   1.9  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
   1085   1.9  riastrad 	  .vrefresh = 30, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
   1086   1.9  riastrad 	/* 68 - 1280x720@50Hz 64:27 */
   1087   1.9  riastrad 	{ DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 74250, 1280, 1720,
   1088   1.9  riastrad 		   1760, 1980, 0, 720, 725, 730, 750, 0,
   1089   1.9  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
   1090   1.9  riastrad 	  .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
   1091   1.9  riastrad 	/* 69 - 1280x720@60Hz 64:27 */
   1092   1.9  riastrad 	{ DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 74250, 1280, 1390,
   1093   1.9  riastrad 		   1430, 1650, 0, 720, 725, 730, 750, 0,
   1094   1.9  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
   1095   1.9  riastrad 	  .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
   1096   1.9  riastrad 	/* 70 - 1280x720@100Hz 64:27 */
   1097   1.9  riastrad 	{ DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 148500, 1280, 1720,
   1098   1.9  riastrad 		   1760, 1980, 0, 720, 725, 730, 750, 0,
   1099   1.9  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
   1100   1.9  riastrad 	  .vrefresh = 100, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
   1101   1.9  riastrad 	/* 71 - 1280x720@120Hz 64:27 */
   1102   1.9  riastrad 	{ DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 148500, 1280, 1390,
   1103   1.9  riastrad 		   1430, 1650, 0, 720, 725, 730, 750, 0,
   1104   1.9  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
   1105   1.9  riastrad 	  .vrefresh = 120, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
   1106   1.9  riastrad 	/* 72 - 1920x1080@24Hz 64:27 */
   1107   1.9  riastrad 	{ DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 74250, 1920, 2558,
   1108   1.9  riastrad 		   2602, 2750, 0, 1080, 1084, 1089, 1125, 0,
   1109   1.9  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
   1110   1.9  riastrad 	  .vrefresh = 24, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
   1111   1.9  riastrad 	/* 73 - 1920x1080@25Hz 64:27 */
   1112   1.9  riastrad 	{ DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 74250, 1920, 2448,
   1113   1.9  riastrad 		   2492, 2640, 0, 1080, 1084, 1089, 1125, 0,
   1114   1.9  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
   1115   1.9  riastrad 	  .vrefresh = 25, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
   1116   1.9  riastrad 	/* 74 - 1920x1080@30Hz 64:27 */
   1117   1.9  riastrad 	{ DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 74250, 1920, 2008,
   1118   1.9  riastrad 		   2052, 2200, 0, 1080, 1084, 1089, 1125, 0,
   1119   1.9  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
   1120   1.9  riastrad 	  .vrefresh = 30, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
   1121   1.9  riastrad 	/* 75 - 1920x1080@50Hz 64:27 */
   1122   1.9  riastrad 	{ DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 148500, 1920, 2448,
   1123   1.9  riastrad 		   2492, 2640, 0, 1080, 1084, 1089, 1125, 0,
   1124   1.9  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
   1125   1.9  riastrad 	  .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
   1126   1.9  riastrad 	/* 76 - 1920x1080@60Hz 64:27 */
   1127   1.9  riastrad 	{ DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 148500, 1920, 2008,
   1128   1.9  riastrad 		   2052, 2200, 0, 1080, 1084, 1089, 1125, 0,
   1129   1.9  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
   1130   1.9  riastrad 	  .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
   1131   1.9  riastrad 	/* 77 - 1920x1080@100Hz 64:27 */
   1132   1.3  riastrad 	{ DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 297000, 1920, 2448,
   1133   1.9  riastrad 		   2492, 2640, 0, 1080, 1084, 1089, 1125, 0,
   1134   1.9  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
   1135   1.9  riastrad 	  .vrefresh = 100, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
   1136   1.9  riastrad 	/* 78 - 1920x1080@120Hz 64:27 */
   1137   1.9  riastrad 	{ DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 297000, 1920, 2008,
   1138   1.9  riastrad 		   2052, 2200, 0, 1080, 1084, 1089, 1125, 0,
   1139   1.9  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
   1140   1.9  riastrad 	  .vrefresh = 120, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
   1141   1.9  riastrad 	/* 79 - 1680x720@24Hz 64:27 */
   1142   1.9  riastrad 	{ DRM_MODE("1680x720", DRM_MODE_TYPE_DRIVER, 59400, 1680, 3040,
   1143   1.9  riastrad 		   3080, 3300, 0, 720, 725, 730, 750, 0,
   1144   1.9  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
   1145   1.9  riastrad 	  .vrefresh = 24, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
   1146   1.9  riastrad 	/* 80 - 1680x720@25Hz 64:27 */
   1147   1.9  riastrad 	{ DRM_MODE("1680x720", DRM_MODE_TYPE_DRIVER, 59400, 1680, 2908,
   1148   1.9  riastrad 		   2948, 3168, 0, 720, 725, 730, 750, 0,
   1149   1.9  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
   1150   1.9  riastrad 	  .vrefresh = 25, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
   1151   1.9  riastrad 	/* 81 - 1680x720@30Hz 64:27 */
   1152   1.9  riastrad 	{ DRM_MODE("1680x720", DRM_MODE_TYPE_DRIVER, 59400, 1680, 2380,
   1153   1.9  riastrad 		   2420, 2640, 0, 720, 725, 730, 750, 0,
   1154   1.9  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
   1155   1.9  riastrad 	  .vrefresh = 30, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
   1156   1.9  riastrad 	/* 82 - 1680x720@50Hz 64:27 */
   1157   1.9  riastrad 	{ DRM_MODE("1680x720", DRM_MODE_TYPE_DRIVER, 82500, 1680, 1940,
   1158   1.9  riastrad 		   1980, 2200, 0, 720, 725, 730, 750, 0,
   1159   1.9  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
   1160   1.9  riastrad 	  .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
   1161   1.9  riastrad 	/* 83 - 1680x720@60Hz 64:27 */
   1162   1.9  riastrad 	{ DRM_MODE("1680x720", DRM_MODE_TYPE_DRIVER, 99000, 1680, 1940,
   1163   1.9  riastrad 		   1980, 2200, 0, 720, 725, 730, 750, 0,
   1164   1.9  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
   1165   1.9  riastrad 	  .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
   1166   1.9  riastrad 	/* 84 - 1680x720@100Hz 64:27 */
   1167   1.9  riastrad 	{ DRM_MODE("1680x720", DRM_MODE_TYPE_DRIVER, 165000, 1680, 1740,
   1168   1.9  riastrad 		   1780, 2000, 0, 720, 725, 730, 825, 0,
   1169   1.9  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
   1170   1.9  riastrad 	  .vrefresh = 100, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
   1171   1.9  riastrad 	/* 85 - 1680x720@120Hz 64:27 */
   1172   1.9  riastrad 	{ DRM_MODE("1680x720", DRM_MODE_TYPE_DRIVER, 198000, 1680, 1740,
   1173   1.9  riastrad 		   1780, 2000, 0, 720, 725, 730, 825, 0,
   1174   1.9  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
   1175   1.9  riastrad 	  .vrefresh = 120, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
   1176   1.9  riastrad 	/* 86 - 2560x1080@24Hz 64:27 */
   1177   1.9  riastrad 	{ DRM_MODE("2560x1080", DRM_MODE_TYPE_DRIVER, 99000, 2560, 3558,
   1178   1.9  riastrad 		   3602, 3750, 0, 1080, 1084, 1089, 1100, 0,
   1179   1.9  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
   1180   1.9  riastrad 	  .vrefresh = 24, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
   1181   1.9  riastrad 	/* 87 - 2560x1080@25Hz 64:27 */
   1182   1.9  riastrad 	{ DRM_MODE("2560x1080", DRM_MODE_TYPE_DRIVER, 90000, 2560, 3008,
   1183   1.9  riastrad 		   3052, 3200, 0, 1080, 1084, 1089, 1125, 0,
   1184   1.9  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
   1185   1.9  riastrad 	  .vrefresh = 25, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
   1186   1.9  riastrad 	/* 88 - 2560x1080@30Hz 64:27 */
   1187   1.9  riastrad 	{ DRM_MODE("2560x1080", DRM_MODE_TYPE_DRIVER, 118800, 2560, 3328,
   1188   1.9  riastrad 		   3372, 3520, 0, 1080, 1084, 1089, 1125, 0,
   1189   1.9  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
   1190   1.9  riastrad 	  .vrefresh = 30, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
   1191   1.9  riastrad 	/* 89 - 2560x1080@50Hz 64:27 */
   1192   1.9  riastrad 	{ DRM_MODE("2560x1080", DRM_MODE_TYPE_DRIVER, 185625, 2560, 3108,
   1193   1.9  riastrad 		   3152, 3300, 0, 1080, 1084, 1089, 1125, 0,
   1194   1.9  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
   1195   1.9  riastrad 	  .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
   1196   1.9  riastrad 	/* 90 - 2560x1080@60Hz 64:27 */
   1197   1.9  riastrad 	{ DRM_MODE("2560x1080", DRM_MODE_TYPE_DRIVER, 198000, 2560, 2808,
   1198   1.9  riastrad 		   2852, 3000, 0, 1080, 1084, 1089, 1100, 0,
   1199   1.9  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
   1200   1.9  riastrad 	  .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
   1201   1.9  riastrad 	/* 91 - 2560x1080@100Hz 64:27 */
   1202   1.9  riastrad 	{ DRM_MODE("2560x1080", DRM_MODE_TYPE_DRIVER, 371250, 2560, 2778,
   1203   1.9  riastrad 		   2822, 2970, 0, 1080, 1084, 1089, 1250, 0,
   1204   1.9  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
   1205   1.9  riastrad 	  .vrefresh = 100, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
   1206   1.9  riastrad 	/* 92 - 2560x1080@120Hz 64:27 */
   1207   1.9  riastrad 	{ DRM_MODE("2560x1080", DRM_MODE_TYPE_DRIVER, 495000, 2560, 3108,
   1208   1.9  riastrad 		   3152, 3300, 0, 1080, 1084, 1089, 1250, 0,
   1209   1.9  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
   1210   1.9  riastrad 	  .vrefresh = 120, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
   1211   1.9  riastrad 	/* 93 - 3840x2160@24Hz 16:9 */
   1212   1.9  riastrad 	{ DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 297000, 3840, 5116,
   1213   1.9  riastrad 		   5204, 5500, 0, 2160, 2168, 2178, 2250, 0,
   1214   1.9  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
   1215   1.9  riastrad 	  .vrefresh = 24, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
   1216   1.9  riastrad 	/* 94 - 3840x2160@25Hz 16:9 */
   1217   1.9  riastrad 	{ DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 297000, 3840, 4896,
   1218   1.9  riastrad 		   4984, 5280, 0, 2160, 2168, 2178, 2250, 0,
   1219   1.9  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
   1220   1.9  riastrad 	  .vrefresh = 25, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
   1221   1.9  riastrad 	/* 95 - 3840x2160@30Hz 16:9 */
   1222   1.9  riastrad 	{ DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 297000, 3840, 4016,
   1223   1.9  riastrad 		   4104, 4400, 0, 2160, 2168, 2178, 2250, 0,
   1224   1.9  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
   1225   1.9  riastrad 	  .vrefresh = 30, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
   1226   1.9  riastrad 	/* 96 - 3840x2160@50Hz 16:9 */
   1227   1.9  riastrad 	{ DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 594000, 3840, 4896,
   1228   1.9  riastrad 		   4984, 5280, 0, 2160, 2168, 2178, 2250, 0,
   1229   1.9  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
   1230   1.9  riastrad 	  .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
   1231   1.9  riastrad 	/* 97 - 3840x2160@60Hz 16:9 */
   1232   1.9  riastrad 	{ DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 594000, 3840, 4016,
   1233   1.9  riastrad 		   4104, 4400, 0, 2160, 2168, 2178, 2250, 0,
   1234   1.9  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
   1235   1.9  riastrad 	  .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
   1236   1.9  riastrad 	/* 98 - 4096x2160@24Hz 256:135 */
   1237   1.9  riastrad 	{ DRM_MODE("4096x2160", DRM_MODE_TYPE_DRIVER, 297000, 4096, 5116,
   1238   1.9  riastrad 		   5204, 5500, 0, 2160, 2168, 2178, 2250, 0,
   1239   1.9  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
   1240   1.9  riastrad 	  .vrefresh = 24, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_256_135, },
   1241   1.9  riastrad 	/* 99 - 4096x2160@25Hz 256:135 */
   1242   1.9  riastrad 	{ DRM_MODE("4096x2160", DRM_MODE_TYPE_DRIVER, 297000, 4096, 5064,
   1243   1.9  riastrad 		   5152, 5280, 0, 2160, 2168, 2178, 2250, 0,
   1244   1.9  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
   1245   1.9  riastrad 	  .vrefresh = 25, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_256_135, },
   1246   1.9  riastrad 	/* 100 - 4096x2160@30Hz 256:135 */
   1247   1.9  riastrad 	{ DRM_MODE("4096x2160", DRM_MODE_TYPE_DRIVER, 297000, 4096, 4184,
   1248   1.9  riastrad 		   4272, 4400, 0, 2160, 2168, 2178, 2250, 0,
   1249   1.9  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
   1250   1.9  riastrad 	  .vrefresh = 30, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_256_135, },
   1251   1.9  riastrad 	/* 101 - 4096x2160@50Hz 256:135 */
   1252   1.9  riastrad 	{ DRM_MODE("4096x2160", DRM_MODE_TYPE_DRIVER, 594000, 4096, 5064,
   1253   1.9  riastrad 		   5152, 5280, 0, 2160, 2168, 2178, 2250, 0,
   1254   1.9  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
   1255   1.9  riastrad 	  .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_256_135, },
   1256   1.9  riastrad 	/* 102 - 4096x2160@60Hz 256:135 */
   1257   1.9  riastrad 	{ DRM_MODE("4096x2160", DRM_MODE_TYPE_DRIVER, 594000, 4096, 4184,
   1258   1.9  riastrad 		   4272, 4400, 0, 2160, 2168, 2178, 2250, 0,
   1259   1.9  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
   1260   1.9  riastrad 	  .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_256_135, },
   1261   1.9  riastrad 	/* 103 - 3840x2160@24Hz 64:27 */
   1262   1.9  riastrad 	{ DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 297000, 3840, 5116,
   1263   1.9  riastrad 		   5204, 5500, 0, 2160, 2168, 2178, 2250, 0,
   1264   1.9  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
   1265   1.9  riastrad 	  .vrefresh = 24, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
   1266   1.9  riastrad 	/* 104 - 3840x2160@25Hz 64:27 */
   1267   1.9  riastrad 	{ DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 297000, 3840, 4896,
   1268   1.9  riastrad 		   4984, 5280, 0, 2160, 2168, 2178, 2250, 0,
   1269   1.9  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
   1270   1.9  riastrad 	  .vrefresh = 25, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
   1271   1.9  riastrad 	/* 105 - 3840x2160@30Hz 64:27 */
   1272   1.9  riastrad 	{ DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 297000, 3840, 4016,
   1273   1.9  riastrad 		   4104, 4400, 0, 2160, 2168, 2178, 2250, 0,
   1274   1.9  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
   1275   1.9  riastrad 	  .vrefresh = 30, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
   1276   1.9  riastrad 	/* 106 - 3840x2160@50Hz 64:27 */
   1277   1.9  riastrad 	{ DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 594000, 3840, 4896,
   1278   1.9  riastrad 		   4984, 5280, 0, 2160, 2168, 2178, 2250, 0,
   1279   1.9  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
   1280   1.9  riastrad 	  .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
   1281   1.9  riastrad 	/* 107 - 3840x2160@60Hz 64:27 */
   1282   1.9  riastrad 	{ DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 594000, 3840, 4016,
   1283   1.9  riastrad 		   4104, 4400, 0, 2160, 2168, 2178, 2250, 0,
   1284   1.9  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
   1285   1.9  riastrad 	  .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
   1286   1.9  riastrad 	/* 108 - 1280x720@48Hz 16:9 */
   1287   1.9  riastrad 	{ DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 90000, 1280, 2240,
   1288   1.9  riastrad 		   2280, 2500, 0, 720, 725, 730, 750, 0,
   1289   1.9  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
   1290   1.9  riastrad 	  .vrefresh = 48, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
   1291   1.9  riastrad 	/* 109 - 1280x720@48Hz 64:27 */
   1292   1.9  riastrad 	{ DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 90000, 1280, 2240,
   1293   1.9  riastrad 		   2280, 2500, 0, 720, 725, 730, 750, 0,
   1294   1.9  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
   1295   1.9  riastrad 	  .vrefresh = 48, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
   1296   1.9  riastrad 	/* 110 - 1680x720@48Hz 64:27 */
   1297   1.9  riastrad 	{ DRM_MODE("1680x720", DRM_MODE_TYPE_DRIVER, 99000, 1680, 2490,
   1298   1.9  riastrad 		   2530, 2750, 0, 720, 725, 730, 750, 0,
   1299   1.9  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
   1300   1.9  riastrad 	  .vrefresh = 48, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
   1301   1.9  riastrad 	/* 111 - 1920x1080@48Hz 16:9 */
   1302   1.9  riastrad 	{ DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 148500, 1920, 2558,
   1303   1.9  riastrad 		   2602, 2750, 0, 1080, 1084, 1089, 1125, 0,
   1304   1.9  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
   1305   1.9  riastrad 	  .vrefresh = 48, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
   1306   1.9  riastrad 	/* 112 - 1920x1080@48Hz 64:27 */
   1307   1.9  riastrad 	{ DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 148500, 1920, 2558,
   1308   1.9  riastrad 		   2602, 2750, 0, 1080, 1084, 1089, 1125, 0,
   1309   1.9  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
   1310   1.9  riastrad 	  .vrefresh = 48, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
   1311   1.9  riastrad 	/* 113 - 2560x1080@48Hz 64:27 */
   1312   1.9  riastrad 	{ DRM_MODE("2560x1080", DRM_MODE_TYPE_DRIVER, 198000, 2560, 3558,
   1313   1.9  riastrad 		   3602, 3750, 0, 1080, 1084, 1089, 1100, 0,
   1314   1.9  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
   1315   1.9  riastrad 	  .vrefresh = 48, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
   1316   1.9  riastrad 	/* 114 - 3840x2160@48Hz 16:9 */
   1317   1.9  riastrad 	{ DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 594000, 3840, 5116,
   1318   1.9  riastrad 		   5204, 5500, 0, 2160, 2168, 2178, 2250, 0,
   1319   1.9  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
   1320   1.9  riastrad 	  .vrefresh = 48, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
   1321   1.9  riastrad 	/* 115 - 4096x2160@48Hz 256:135 */
   1322   1.9  riastrad 	{ DRM_MODE("4096x2160", DRM_MODE_TYPE_DRIVER, 594000, 4096, 5116,
   1323   1.9  riastrad 		   5204, 5500, 0, 2160, 2168, 2178, 2250, 0,
   1324   1.9  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
   1325   1.9  riastrad 	  .vrefresh = 48, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_256_135, },
   1326   1.9  riastrad 	/* 116 - 3840x2160@48Hz 64:27 */
   1327   1.9  riastrad 	{ DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 594000, 3840, 5116,
   1328   1.9  riastrad 		   5204, 5500, 0, 2160, 2168, 2178, 2250, 0,
   1329   1.9  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
   1330   1.9  riastrad 	  .vrefresh = 48, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
   1331   1.9  riastrad 	/* 117 - 3840x2160@100Hz 16:9 */
   1332   1.9  riastrad 	{ DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 1188000, 3840, 4896,
   1333   1.9  riastrad 		   4984, 5280, 0, 2160, 2168, 2178, 2250, 0,
   1334   1.9  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
   1335   1.9  riastrad 	  .vrefresh = 100, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
   1336   1.9  riastrad 	/* 118 - 3840x2160@120Hz 16:9 */
   1337   1.9  riastrad 	{ DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 1188000, 3840, 4016,
   1338   1.9  riastrad 		   4104, 4400, 0, 2160, 2168, 2178, 2250, 0,
   1339   1.9  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
   1340   1.9  riastrad 	  .vrefresh = 120, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
   1341   1.9  riastrad 	/* 119 - 3840x2160@100Hz 64:27 */
   1342   1.9  riastrad 	{ DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 1188000, 3840, 4896,
   1343   1.9  riastrad 		   4984, 5280, 0, 2160, 2168, 2178, 2250, 0,
   1344   1.9  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
   1345   1.9  riastrad 	  .vrefresh = 100, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
   1346   1.9  riastrad 	/* 120 - 3840x2160@120Hz 64:27 */
   1347   1.9  riastrad 	{ DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 1188000, 3840, 4016,
   1348   1.9  riastrad 		   4104, 4400, 0, 2160, 2168, 2178, 2250, 0,
   1349   1.9  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
   1350   1.9  riastrad 	  .vrefresh = 120, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
   1351   1.9  riastrad 	/* 121 - 5120x2160@24Hz 64:27 */
   1352   1.9  riastrad 	{ DRM_MODE("5120x2160", DRM_MODE_TYPE_DRIVER, 396000, 5120, 7116,
   1353   1.9  riastrad 		   7204, 7500, 0, 2160, 2168, 2178, 2200, 0,
   1354   1.9  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
   1355   1.9  riastrad 	  .vrefresh = 24, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
   1356   1.9  riastrad 	/* 122 - 5120x2160@25Hz 64:27 */
   1357   1.9  riastrad 	{ DRM_MODE("5120x2160", DRM_MODE_TYPE_DRIVER, 396000, 5120, 6816,
   1358   1.9  riastrad 		   6904, 7200, 0, 2160, 2168, 2178, 2200, 0,
   1359   1.9  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
   1360   1.9  riastrad 	  .vrefresh = 25, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
   1361   1.9  riastrad 	/* 123 - 5120x2160@30Hz 64:27 */
   1362   1.9  riastrad 	{ DRM_MODE("5120x2160", DRM_MODE_TYPE_DRIVER, 396000, 5120, 5784,
   1363   1.9  riastrad 		   5872, 6000, 0, 2160, 2168, 2178, 2200, 0,
   1364   1.9  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
   1365   1.9  riastrad 	  .vrefresh = 30, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
   1366   1.9  riastrad 	/* 124 - 5120x2160@48Hz 64:27 */
   1367   1.9  riastrad 	{ DRM_MODE("5120x2160", DRM_MODE_TYPE_DRIVER, 742500, 5120, 5866,
   1368   1.9  riastrad 		   5954, 6250, 0, 2160, 2168, 2178, 2475, 0,
   1369   1.9  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
   1370   1.9  riastrad 	  .vrefresh = 48, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
   1371   1.9  riastrad 	/* 125 - 5120x2160@50Hz 64:27 */
   1372   1.9  riastrad 	{ DRM_MODE("5120x2160", DRM_MODE_TYPE_DRIVER, 742500, 5120, 6216,
   1373   1.9  riastrad 		   6304, 6600, 0, 2160, 2168, 2178, 2250, 0,
   1374   1.9  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
   1375   1.9  riastrad 	  .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
   1376   1.9  riastrad 	/* 126 - 5120x2160@60Hz 64:27 */
   1377   1.9  riastrad 	{ DRM_MODE("5120x2160", DRM_MODE_TYPE_DRIVER, 742500, 5120, 5284,
   1378   1.9  riastrad 		   5372, 5500, 0, 2160, 2168, 2178, 2250, 0,
   1379   1.9  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
   1380   1.9  riastrad 	  .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
   1381   1.9  riastrad 	/* 127 - 5120x2160@100Hz 64:27 */
   1382   1.9  riastrad 	{ DRM_MODE("5120x2160", DRM_MODE_TYPE_DRIVER, 1485000, 5120, 6216,
   1383   1.9  riastrad 		   6304, 6600, 0, 2160, 2168, 2178, 2250, 0,
   1384   1.9  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
   1385   1.9  riastrad 	  .vrefresh = 100, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
   1386   1.9  riastrad };
   1387   1.9  riastrad 
   1388   1.9  riastrad /*
   1389   1.9  riastrad  * From CEA/CTA-861 spec.
   1390   1.9  riastrad  *
   1391   1.9  riastrad  * Do not access directly, instead always use cea_mode_for_vic().
   1392   1.9  riastrad  */
   1393   1.9  riastrad static const struct drm_display_mode edid_cea_modes_193[] = {
   1394   1.9  riastrad 	/* 193 - 5120x2160@120Hz 64:27 */
   1395   1.9  riastrad 	{ DRM_MODE("5120x2160", DRM_MODE_TYPE_DRIVER, 1485000, 5120, 5284,
   1396   1.9  riastrad 		   5372, 5500, 0, 2160, 2168, 2178, 2250, 0,
   1397   1.9  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
   1398   1.9  riastrad 	  .vrefresh = 120, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
   1399   1.9  riastrad 	/* 194 - 7680x4320@24Hz 16:9 */
   1400   1.9  riastrad 	{ DRM_MODE("7680x4320", DRM_MODE_TYPE_DRIVER, 1188000, 7680, 10232,
   1401   1.9  riastrad 		   10408, 11000, 0, 4320, 4336, 4356, 4500, 0,
   1402   1.9  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
   1403   1.9  riastrad 	  .vrefresh = 24, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
   1404   1.9  riastrad 	/* 195 - 7680x4320@25Hz 16:9 */
   1405   1.9  riastrad 	{ DRM_MODE("7680x4320", DRM_MODE_TYPE_DRIVER, 1188000, 7680, 10032,
   1406   1.9  riastrad 		   10208, 10800, 0, 4320, 4336, 4356, 4400, 0,
   1407   1.9  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
   1408   1.9  riastrad 	  .vrefresh = 25, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
   1409   1.9  riastrad 	/* 196 - 7680x4320@30Hz 16:9 */
   1410   1.9  riastrad 	{ DRM_MODE("7680x4320", DRM_MODE_TYPE_DRIVER, 1188000, 7680, 8232,
   1411   1.9  riastrad 		   8408, 9000, 0, 4320, 4336, 4356, 4400, 0,
   1412   1.9  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
   1413   1.9  riastrad 	  .vrefresh = 30, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
   1414   1.9  riastrad 	/* 197 - 7680x4320@48Hz 16:9 */
   1415   1.9  riastrad 	{ DRM_MODE("7680x4320", DRM_MODE_TYPE_DRIVER, 2376000, 7680, 10232,
   1416   1.9  riastrad 		   10408, 11000, 0, 4320, 4336, 4356, 4500, 0,
   1417   1.9  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
   1418   1.9  riastrad 	  .vrefresh = 48, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
   1419   1.9  riastrad 	/* 198 - 7680x4320@50Hz 16:9 */
   1420   1.9  riastrad 	{ DRM_MODE("7680x4320", DRM_MODE_TYPE_DRIVER, 2376000, 7680, 10032,
   1421   1.9  riastrad 		   10208, 10800, 0, 4320, 4336, 4356, 4400, 0,
   1422   1.9  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
   1423   1.9  riastrad 	  .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
   1424   1.9  riastrad 	/* 199 - 7680x4320@60Hz 16:9 */
   1425   1.9  riastrad 	{ DRM_MODE("7680x4320", DRM_MODE_TYPE_DRIVER, 2376000, 7680, 8232,
   1426   1.9  riastrad 		   8408, 9000, 0, 4320, 4336, 4356, 4400, 0,
   1427   1.9  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
   1428   1.9  riastrad 	  .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
   1429   1.9  riastrad 	/* 200 - 7680x4320@100Hz 16:9 */
   1430   1.9  riastrad 	{ DRM_MODE("7680x4320", DRM_MODE_TYPE_DRIVER, 4752000, 7680, 9792,
   1431   1.9  riastrad 		   9968, 10560, 0, 4320, 4336, 4356, 4500, 0,
   1432   1.9  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
   1433   1.9  riastrad 	  .vrefresh = 100, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
   1434   1.9  riastrad 	/* 201 - 7680x4320@120Hz 16:9 */
   1435   1.9  riastrad 	{ DRM_MODE("7680x4320", DRM_MODE_TYPE_DRIVER, 4752000, 7680, 8032,
   1436   1.9  riastrad 		   8208, 8800, 0, 4320, 4336, 4356, 4500, 0,
   1437   1.9  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
   1438   1.9  riastrad 	  .vrefresh = 120, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
   1439   1.9  riastrad 	/* 202 - 7680x4320@24Hz 64:27 */
   1440   1.9  riastrad 	{ DRM_MODE("7680x4320", DRM_MODE_TYPE_DRIVER, 1188000, 7680, 10232,
   1441   1.9  riastrad 		   10408, 11000, 0, 4320, 4336, 4356, 4500, 0,
   1442   1.9  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
   1443   1.9  riastrad 	  .vrefresh = 24, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
   1444   1.9  riastrad 	/* 203 - 7680x4320@25Hz 64:27 */
   1445   1.9  riastrad 	{ DRM_MODE("7680x4320", DRM_MODE_TYPE_DRIVER, 1188000, 7680, 10032,
   1446   1.9  riastrad 		   10208, 10800, 0, 4320, 4336, 4356, 4400, 0,
   1447   1.9  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
   1448   1.9  riastrad 	  .vrefresh = 25, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
   1449   1.9  riastrad 	/* 204 - 7680x4320@30Hz 64:27 */
   1450   1.9  riastrad 	{ DRM_MODE("7680x4320", DRM_MODE_TYPE_DRIVER, 1188000, 7680, 8232,
   1451   1.9  riastrad 		   8408, 9000, 0, 4320, 4336, 4356, 4400, 0,
   1452   1.9  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
   1453   1.9  riastrad 	  .vrefresh = 30, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
   1454   1.9  riastrad 	/* 205 - 7680x4320@48Hz 64:27 */
   1455   1.9  riastrad 	{ DRM_MODE("7680x4320", DRM_MODE_TYPE_DRIVER, 2376000, 7680, 10232,
   1456   1.9  riastrad 		   10408, 11000, 0, 4320, 4336, 4356, 4500, 0,
   1457   1.9  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
   1458   1.9  riastrad 	  .vrefresh = 48, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
   1459   1.9  riastrad 	/* 206 - 7680x4320@50Hz 64:27 */
   1460   1.9  riastrad 	{ DRM_MODE("7680x4320", DRM_MODE_TYPE_DRIVER, 2376000, 7680, 10032,
   1461   1.9  riastrad 		   10208, 10800, 0, 4320, 4336, 4356, 4400, 0,
   1462   1.9  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
   1463   1.9  riastrad 	  .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
   1464   1.9  riastrad 	/* 207 - 7680x4320@60Hz 64:27 */
   1465   1.9  riastrad 	{ DRM_MODE("7680x4320", DRM_MODE_TYPE_DRIVER, 2376000, 7680, 8232,
   1466   1.9  riastrad 		   8408, 9000, 0, 4320, 4336, 4356, 4400, 0,
   1467   1.9  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
   1468   1.9  riastrad 	  .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
   1469   1.9  riastrad 	/* 208 - 7680x4320@100Hz 64:27 */
   1470   1.9  riastrad 	{ DRM_MODE("7680x4320", DRM_MODE_TYPE_DRIVER, 4752000, 7680, 9792,
   1471   1.9  riastrad 		   9968, 10560, 0, 4320, 4336, 4356, 4500, 0,
   1472   1.9  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
   1473   1.9  riastrad 	  .vrefresh = 100, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
   1474   1.9  riastrad 	/* 209 - 7680x4320@120Hz 64:27 */
   1475   1.9  riastrad 	{ DRM_MODE("7680x4320", DRM_MODE_TYPE_DRIVER, 4752000, 7680, 8032,
   1476   1.9  riastrad 		   8208, 8800, 0, 4320, 4336, 4356, 4500, 0,
   1477   1.9  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
   1478   1.9  riastrad 	  .vrefresh = 120, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
   1479   1.9  riastrad 	/* 210 - 10240x4320@24Hz 64:27 */
   1480   1.9  riastrad 	{ DRM_MODE("10240x4320", DRM_MODE_TYPE_DRIVER, 1485000, 10240, 11732,
   1481   1.9  riastrad 		   11908, 12500, 0, 4320, 4336, 4356, 4950, 0,
   1482   1.9  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
   1483   1.9  riastrad 	  .vrefresh = 24, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
   1484   1.9  riastrad 	/* 211 - 10240x4320@25Hz 64:27 */
   1485   1.9  riastrad 	{ DRM_MODE("10240x4320", DRM_MODE_TYPE_DRIVER, 1485000, 10240, 12732,
   1486   1.9  riastrad 		   12908, 13500, 0, 4320, 4336, 4356, 4400, 0,
   1487   1.9  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
   1488   1.9  riastrad 	  .vrefresh = 25, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
   1489   1.9  riastrad 	/* 212 - 10240x4320@30Hz 64:27 */
   1490   1.9  riastrad 	{ DRM_MODE("10240x4320", DRM_MODE_TYPE_DRIVER, 1485000, 10240, 10528,
   1491   1.9  riastrad 		   10704, 11000, 0, 4320, 4336, 4356, 4500, 0,
   1492   1.9  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
   1493   1.9  riastrad 	  .vrefresh = 30, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
   1494   1.9  riastrad 	/* 213 - 10240x4320@48Hz 64:27 */
   1495   1.9  riastrad 	{ DRM_MODE("10240x4320", DRM_MODE_TYPE_DRIVER, 2970000, 10240, 11732,
   1496   1.9  riastrad 		   11908, 12500, 0, 4320, 4336, 4356, 4950, 0,
   1497   1.9  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
   1498   1.9  riastrad 	  .vrefresh = 48, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
   1499   1.9  riastrad 	/* 214 - 10240x4320@50Hz 64:27 */
   1500   1.9  riastrad 	{ DRM_MODE("10240x4320", DRM_MODE_TYPE_DRIVER, 2970000, 10240, 12732,
   1501   1.9  riastrad 		   12908, 13500, 0, 4320, 4336, 4356, 4400, 0,
   1502   1.9  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
   1503   1.9  riastrad 	  .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
   1504   1.9  riastrad 	/* 215 - 10240x4320@60Hz 64:27 */
   1505   1.9  riastrad 	{ DRM_MODE("10240x4320", DRM_MODE_TYPE_DRIVER, 2970000, 10240, 10528,
   1506   1.9  riastrad 		   10704, 11000, 0, 4320, 4336, 4356, 4500, 0,
   1507   1.9  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
   1508   1.9  riastrad 	  .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
   1509   1.9  riastrad 	/* 216 - 10240x4320@100Hz 64:27 */
   1510   1.9  riastrad 	{ DRM_MODE("10240x4320", DRM_MODE_TYPE_DRIVER, 5940000, 10240, 12432,
   1511   1.9  riastrad 		   12608, 13200, 0, 4320, 4336, 4356, 4500, 0,
   1512   1.9  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
   1513   1.9  riastrad 	  .vrefresh = 100, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
   1514   1.9  riastrad 	/* 217 - 10240x4320@120Hz 64:27 */
   1515   1.9  riastrad 	{ DRM_MODE("10240x4320", DRM_MODE_TYPE_DRIVER, 5940000, 10240, 10528,
   1516   1.9  riastrad 		   10704, 11000, 0, 4320, 4336, 4356, 4500, 0,
   1517   1.9  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
   1518   1.9  riastrad 	  .vrefresh = 120, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
   1519   1.9  riastrad 	/* 218 - 4096x2160@100Hz 256:135 */
   1520   1.9  riastrad 	{ DRM_MODE("4096x2160", DRM_MODE_TYPE_DRIVER, 1188000, 4096, 4896,
   1521   1.9  riastrad 		   4984, 5280, 0, 2160, 2168, 2178, 2250, 0,
   1522   1.9  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
   1523   1.9  riastrad 	  .vrefresh = 100, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_256_135, },
   1524   1.9  riastrad 	/* 219 - 4096x2160@120Hz 256:135 */
   1525   1.9  riastrad 	{ DRM_MODE("4096x2160", DRM_MODE_TYPE_DRIVER, 1188000, 4096, 4184,
   1526   1.9  riastrad 		   4272, 4400, 0, 2160, 2168, 2178, 2250, 0,
   1527   1.3  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
   1528   1.9  riastrad 	  .vrefresh = 120, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_256_135, },
   1529   1.3  riastrad };
   1530   1.3  riastrad 
   1531   1.3  riastrad /*
   1532   1.9  riastrad  * HDMI 1.4 4k modes. Index using the VIC.
   1533   1.3  riastrad  */
   1534   1.3  riastrad static const struct drm_display_mode edid_4k_modes[] = {
   1535   1.9  riastrad 	/* 0 - dummy, VICs start at 1 */
   1536   1.9  riastrad 	{ },
   1537   1.3  riastrad 	/* 1 - 3840x2160@30Hz */
   1538   1.3  riastrad 	{ DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 297000,
   1539   1.3  riastrad 		   3840, 4016, 4104, 4400, 0,
   1540   1.3  riastrad 		   2160, 2168, 2178, 2250, 0,
   1541   1.3  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
   1542   1.9  riastrad 	  .vrefresh = 30, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
   1543   1.3  riastrad 	/* 2 - 3840x2160@25Hz */
   1544   1.3  riastrad 	{ DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 297000,
   1545   1.3  riastrad 		   3840, 4896, 4984, 5280, 0,
   1546   1.3  riastrad 		   2160, 2168, 2178, 2250, 0,
   1547   1.3  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
   1548   1.9  riastrad 	  .vrefresh = 25, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
   1549   1.3  riastrad 	/* 3 - 3840x2160@24Hz */
   1550   1.3  riastrad 	{ DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 297000,
   1551   1.3  riastrad 		   3840, 5116, 5204, 5500, 0,
   1552   1.3  riastrad 		   2160, 2168, 2178, 2250, 0,
   1553   1.3  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
   1554   1.9  riastrad 	  .vrefresh = 24, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
   1555   1.3  riastrad 	/* 4 - 4096x2160@24Hz (SMPTE) */
   1556   1.3  riastrad 	{ DRM_MODE("4096x2160", DRM_MODE_TYPE_DRIVER, 297000,
   1557   1.3  riastrad 		   4096, 5116, 5204, 5500, 0,
   1558   1.3  riastrad 		   2160, 2168, 2178, 2250, 0,
   1559   1.3  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
   1560   1.9  riastrad 	  .vrefresh = 24, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_256_135, },
   1561   1.1  riastrad };
   1562   1.1  riastrad 
   1563   1.1  riastrad /*** DDC fetch and block validation ***/
   1564   1.1  riastrad 
   1565   1.1  riastrad static const u8 edid_header[] = {
   1566   1.1  riastrad 	0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00
   1567   1.1  riastrad };
   1568   1.1  riastrad 
   1569   1.6  riastrad /**
   1570   1.6  riastrad  * drm_edid_header_is_valid - sanity check the header of the base EDID block
   1571   1.6  riastrad  * @raw_edid: pointer to raw base EDID block
   1572   1.6  riastrad  *
   1573   1.6  riastrad  * Sanity check the header of the base EDID block.
   1574   1.6  riastrad  *
   1575   1.6  riastrad  * Return: 8 if the header is perfect, down to 0 if it's totally wrong.
   1576   1.1  riastrad  */
   1577   1.1  riastrad int drm_edid_header_is_valid(const u8 *raw_edid)
   1578   1.1  riastrad {
   1579   1.1  riastrad 	int i, score = 0;
   1580   1.1  riastrad 
   1581   1.1  riastrad 	for (i = 0; i < sizeof(edid_header); i++)
   1582   1.1  riastrad 		if (raw_edid[i] == edid_header[i])
   1583   1.1  riastrad 			score++;
   1584   1.1  riastrad 
   1585   1.1  riastrad 	return score;
   1586   1.1  riastrad }
   1587   1.1  riastrad EXPORT_SYMBOL(drm_edid_header_is_valid);
   1588   1.1  riastrad 
   1589   1.1  riastrad static int edid_fixup __read_mostly = 6;
   1590   1.1  riastrad module_param_named(edid_fixup, edid_fixup, int, 0400);
   1591   1.1  riastrad MODULE_PARM_DESC(edid_fixup,
   1592   1.1  riastrad 		 "Minimum number of valid EDID header bytes (0-8, default 6)");
   1593   1.1  riastrad 
   1594   1.6  riastrad static void drm_get_displayid(struct drm_connector *connector,
   1595   1.6  riastrad 			      struct edid *edid);
   1596  1.14  riastrad static int validate_displayid(const u8 *displayid, int length, int idx);
   1597   1.6  riastrad 
   1598   1.6  riastrad static int drm_edid_block_checksum(const u8 *raw_edid)
   1599   1.1  riastrad {
   1600   1.1  riastrad 	int i;
   1601   1.1  riastrad 	u8 csum = 0;
   1602   1.6  riastrad 	for (i = 0; i < EDID_LENGTH; i++)
   1603   1.6  riastrad 		csum += raw_edid[i];
   1604   1.6  riastrad 
   1605   1.6  riastrad 	return csum;
   1606   1.6  riastrad }
   1607   1.6  riastrad 
   1608   1.6  riastrad static bool drm_edid_is_zero(const u8 *in_edid, int length)
   1609   1.6  riastrad {
   1610   1.6  riastrad 	if (memchr_inv(in_edid, 0, length))
   1611   1.6  riastrad 		return false;
   1612   1.6  riastrad 
   1613   1.6  riastrad 	return true;
   1614   1.6  riastrad }
   1615   1.6  riastrad 
   1616   1.6  riastrad /**
   1617   1.6  riastrad  * drm_edid_block_valid - Sanity check the EDID block (base or extension)
   1618   1.6  riastrad  * @raw_edid: pointer to raw EDID block
   1619   1.6  riastrad  * @block: type of block to validate (0 for base, extension otherwise)
   1620   1.6  riastrad  * @print_bad_edid: if true, dump bad EDID blocks to the console
   1621   1.6  riastrad  * @edid_corrupt: if true, the header or checksum is invalid
   1622   1.6  riastrad  *
   1623   1.6  riastrad  * Validate a base or extension EDID block and optionally dump bad blocks to
   1624   1.6  riastrad  * the console.
   1625   1.6  riastrad  *
   1626   1.6  riastrad  * Return: True if the block is valid, false otherwise.
   1627   1.6  riastrad  */
   1628   1.6  riastrad bool drm_edid_block_valid(u8 *raw_edid, int block, bool print_bad_edid,
   1629   1.6  riastrad 			  bool *edid_corrupt)
   1630   1.6  riastrad {
   1631   1.6  riastrad 	u8 csum;
   1632   1.1  riastrad 	struct edid *edid = (struct edid *)raw_edid;
   1633   1.1  riastrad 
   1634   1.3  riastrad 	if (WARN_ON(!raw_edid))
   1635   1.3  riastrad 		return false;
   1636   1.3  riastrad 
   1637   1.1  riastrad 	if (edid_fixup > 8 || edid_fixup < 0)
   1638   1.1  riastrad 		edid_fixup = 6;
   1639   1.1  riastrad 
   1640   1.1  riastrad 	if (block == 0) {
   1641   1.1  riastrad 		int score = drm_edid_header_is_valid(raw_edid);
   1642   1.6  riastrad 		if (score == 8) {
   1643   1.6  riastrad 			if (edid_corrupt)
   1644   1.6  riastrad 				*edid_corrupt = false;
   1645   1.6  riastrad 		} else if (score >= edid_fixup) {
   1646   1.6  riastrad 			/* Displayport Link CTS Core 1.2 rev1.1 test 4.2.2.6
   1647   1.6  riastrad 			 * The corrupt flag needs to be set here otherwise, the
   1648   1.6  riastrad 			 * fix-up code here will correct the problem, the
   1649   1.6  riastrad 			 * checksum is correct and the test fails
   1650   1.6  riastrad 			 */
   1651   1.6  riastrad 			if (edid_corrupt)
   1652   1.6  riastrad 				*edid_corrupt = true;
   1653   1.1  riastrad 			DRM_DEBUG("Fixing EDID header, your hardware may be failing\n");
   1654   1.1  riastrad 			memcpy(raw_edid, edid_header, sizeof(edid_header));
   1655   1.1  riastrad 		} else {
   1656   1.6  riastrad 			if (edid_corrupt)
   1657   1.6  riastrad 				*edid_corrupt = true;
   1658   1.1  riastrad 			goto bad;
   1659   1.1  riastrad 		}
   1660   1.1  riastrad 	}
   1661   1.1  riastrad 
   1662   1.6  riastrad 	csum = drm_edid_block_checksum(raw_edid);
   1663   1.1  riastrad 	if (csum) {
   1664   1.6  riastrad 		if (edid_corrupt)
   1665   1.6  riastrad 			*edid_corrupt = true;
   1666   1.6  riastrad 
   1667   1.1  riastrad 		/* allow CEA to slide through, switches mangle this */
   1668   1.9  riastrad 		if (raw_edid[0] == CEA_EXT) {
   1669   1.9  riastrad 			DRM_DEBUG("EDID checksum is invalid, remainder is %d\n", csum);
   1670   1.9  riastrad 			DRM_DEBUG("Assuming a KVM switch modified the CEA block but left the original checksum\n");
   1671   1.9  riastrad 		} else {
   1672   1.9  riastrad 			if (print_bad_edid)
   1673   1.9  riastrad 				DRM_NOTE("EDID checksum is invalid, remainder is %d\n", csum);
   1674   1.9  riastrad 
   1675   1.1  riastrad 			goto bad;
   1676   1.9  riastrad 		}
   1677   1.1  riastrad 	}
   1678   1.1  riastrad 
   1679   1.1  riastrad 	/* per-block-type checks */
   1680   1.1  riastrad 	switch (raw_edid[0]) {
   1681   1.1  riastrad 	case 0: /* base */
   1682   1.1  riastrad 		if (edid->version != 1) {
   1683   1.9  riastrad 			DRM_NOTE("EDID has major version %d, instead of 1\n", edid->version);
   1684   1.1  riastrad 			goto bad;
   1685   1.1  riastrad 		}
   1686   1.1  riastrad 
   1687   1.1  riastrad 		if (edid->revision > 4)
   1688   1.1  riastrad 			DRM_DEBUG("EDID minor > 4, assuming backward compatibility\n");
   1689   1.1  riastrad 		break;
   1690   1.1  riastrad 
   1691   1.1  riastrad 	default:
   1692   1.1  riastrad 		break;
   1693   1.1  riastrad 	}
   1694   1.1  riastrad 
   1695   1.3  riastrad 	return true;
   1696   1.1  riastrad 
   1697   1.1  riastrad bad:
   1698   1.3  riastrad 	if (print_bad_edid) {
   1699   1.6  riastrad 		if (drm_edid_is_zero(raw_edid, EDID_LENGTH)) {
   1700   1.9  riastrad 			pr_notice("EDID block is all zeroes\n");
   1701   1.6  riastrad 		} else {
   1702   1.9  riastrad 			pr_notice("Raw EDID:\n");
   1703   1.9  riastrad 			print_hex_dump(KERN_NOTICE,
   1704   1.9  riastrad 				       " \t", DUMP_PREFIX_NONE, 16, 1,
   1705   1.9  riastrad 				       raw_edid, EDID_LENGTH, false);
   1706   1.6  riastrad 		}
   1707   1.1  riastrad 	}
   1708   1.3  riastrad 	return false;
   1709   1.1  riastrad }
   1710   1.1  riastrad EXPORT_SYMBOL(drm_edid_block_valid);
   1711   1.1  riastrad 
   1712   1.1  riastrad /**
   1713   1.1  riastrad  * drm_edid_is_valid - sanity check EDID data
   1714   1.1  riastrad  * @edid: EDID data
   1715   1.1  riastrad  *
   1716   1.1  riastrad  * Sanity-check an entire EDID record (including extensions)
   1717   1.6  riastrad  *
   1718   1.6  riastrad  * Return: True if the EDID data is valid, false otherwise.
   1719   1.1  riastrad  */
   1720   1.1  riastrad bool drm_edid_is_valid(struct edid *edid)
   1721   1.1  riastrad {
   1722   1.1  riastrad 	int i;
   1723   1.1  riastrad 	u8 *raw = (u8 *)edid;
   1724   1.1  riastrad 
   1725   1.1  riastrad 	if (!edid)
   1726   1.1  riastrad 		return false;
   1727   1.1  riastrad 
   1728   1.1  riastrad 	for (i = 0; i <= edid->extensions; i++)
   1729   1.6  riastrad 		if (!drm_edid_block_valid(raw + i * EDID_LENGTH, i, true, NULL))
   1730   1.1  riastrad 			return false;
   1731   1.1  riastrad 
   1732   1.1  riastrad 	return true;
   1733   1.1  riastrad }
   1734   1.1  riastrad EXPORT_SYMBOL(drm_edid_is_valid);
   1735   1.1  riastrad 
   1736   1.1  riastrad #define DDC_SEGMENT_ADDR 0x30
   1737   1.1  riastrad /**
   1738   1.6  riastrad  * drm_do_probe_ddc_edid() - get EDID information via I2C
   1739   1.6  riastrad  * @data: I2C device adapter
   1740   1.3  riastrad  * @buf: EDID data buffer to be filled
   1741   1.3  riastrad  * @block: 128 byte EDID block to start fetching from
   1742   1.3  riastrad  * @len: EDID data buffer length to fetch
   1743   1.3  riastrad  *
   1744   1.6  riastrad  * Try to fetch EDID information by calling I2C driver functions.
   1745   1.1  riastrad  *
   1746   1.6  riastrad  * Return: 0 on success or -1 on failure.
   1747   1.1  riastrad  */
   1748   1.1  riastrad static int
   1749   1.6  riastrad drm_do_probe_ddc_edid(void *data, u8 *buf, unsigned int block, size_t len)
   1750   1.1  riastrad {
   1751   1.6  riastrad 	struct i2c_adapter *adapter = data;
   1752   1.1  riastrad 	unsigned char start = block * EDID_LENGTH;
   1753   1.1  riastrad 	unsigned char segment = block >> 1;
   1754   1.1  riastrad 	unsigned char xfers = segment ? 3 : 2;
   1755   1.1  riastrad 	int ret, retries = 5;
   1756   1.1  riastrad 
   1757   1.6  riastrad 	/*
   1758   1.6  riastrad 	 * The core I2C driver will automatically retry the transfer if the
   1759   1.1  riastrad 	 * adapter reports EAGAIN. However, we find that bit-banging transfers
   1760   1.1  riastrad 	 * are susceptible to errors under a heavily loaded machine and
   1761   1.1  riastrad 	 * generate spurious NAKs and timeouts. Retrying the transfer
   1762   1.1  riastrad 	 * of the individual block a few times seems to overcome this.
   1763   1.1  riastrad 	 */
   1764   1.1  riastrad 	do {
   1765   1.1  riastrad 		struct i2c_msg msgs[] = {
   1766   1.1  riastrad 			{
   1767   1.1  riastrad 				.addr	= DDC_SEGMENT_ADDR,
   1768   1.1  riastrad 				.flags	= 0,
   1769   1.1  riastrad 				.len	= 1,
   1770   1.1  riastrad 				.buf	= &segment,
   1771   1.1  riastrad 			}, {
   1772   1.1  riastrad 				.addr	= DDC_ADDR,
   1773   1.1  riastrad 				.flags	= 0,
   1774   1.1  riastrad 				.len	= 1,
   1775   1.1  riastrad 				.buf	= &start,
   1776   1.1  riastrad 			}, {
   1777   1.1  riastrad 				.addr	= DDC_ADDR,
   1778   1.1  riastrad 				.flags	= I2C_M_RD,
   1779   1.1  riastrad 				.len	= len,
   1780   1.1  riastrad 				.buf	= buf,
   1781   1.1  riastrad 			}
   1782   1.1  riastrad 		};
   1783   1.1  riastrad 
   1784   1.6  riastrad 		/*
   1785   1.6  riastrad 		 * Avoid sending the segment addr to not upset non-compliant
   1786   1.6  riastrad 		 * DDC monitors.
   1787   1.6  riastrad 		 */
   1788   1.1  riastrad 		ret = i2c_transfer(adapter, &msgs[3 - xfers], xfers);
   1789   1.1  riastrad 
   1790   1.1  riastrad 		if (ret == -ENXIO) {
   1791   1.1  riastrad 			DRM_DEBUG_KMS("drm: skipping non-existent adapter %s\n",
   1792   1.1  riastrad 					adapter->name);
   1793   1.1  riastrad 			break;
   1794   1.1  riastrad 		}
   1795   1.1  riastrad 	} while (ret != xfers && --retries);
   1796   1.1  riastrad 
   1797   1.1  riastrad 	return ret == xfers ? 0 : -1;
   1798   1.1  riastrad }
   1799   1.1  riastrad 
   1800   1.9  riastrad static void connector_bad_edid(struct drm_connector *connector,
   1801   1.9  riastrad 			       u8 *edid, int num_blocks)
   1802   1.9  riastrad {
   1803   1.9  riastrad 	int i;
   1804   1.9  riastrad 
   1805   1.9  riastrad 	if (connector->bad_edid_counter++ && !drm_debug_enabled(DRM_UT_KMS))
   1806   1.9  riastrad 		return;
   1807   1.9  riastrad 
   1808   1.9  riastrad 	dev_warn(connector->dev->dev,
   1809   1.9  riastrad 		 "%s: EDID is invalid:\n",
   1810   1.9  riastrad 		 connector->name);
   1811   1.9  riastrad 	for (i = 0; i < num_blocks; i++) {
   1812   1.9  riastrad 		u8 *block = edid + i * EDID_LENGTH;
   1813   1.9  riastrad 		char prefix[20];
   1814   1.9  riastrad 
   1815   1.9  riastrad 		if (drm_edid_is_zero(block, EDID_LENGTH))
   1816  1.10  riastrad 			snprintf(prefix, sizeof prefix, "\t[%02x] ZERO ", i);
   1817   1.9  riastrad 		else if (!drm_edid_block_valid(block, i, false, NULL))
   1818  1.10  riastrad 			snprintf(prefix, sizeof prefix, "\t[%02x] BAD  ", i);
   1819   1.9  riastrad 		else
   1820  1.10  riastrad 			snprintf(prefix, sizeof prefix, "\t[%02x] GOOD ", i);
   1821   1.9  riastrad 
   1822   1.9  riastrad 		print_hex_dump(KERN_WARNING,
   1823   1.9  riastrad 			       prefix, DUMP_PREFIX_NONE, 16, 1,
   1824   1.9  riastrad 			       block, EDID_LENGTH, false);
   1825   1.9  riastrad 	}
   1826   1.9  riastrad }
   1827   1.9  riastrad 
   1828   1.9  riastrad /* Get override or firmware EDID */
   1829   1.9  riastrad static struct edid *drm_get_override_edid(struct drm_connector *connector)
   1830   1.9  riastrad {
   1831   1.9  riastrad 	struct edid *override = NULL;
   1832   1.9  riastrad 
   1833   1.9  riastrad 	if (connector->override_edid)
   1834   1.9  riastrad 		override = drm_edid_duplicate(connector->edid_blob_ptr->data);
   1835   1.9  riastrad 
   1836   1.9  riastrad 	if (!override)
   1837   1.9  riastrad 		override = drm_load_edid_firmware(connector);
   1838   1.9  riastrad 
   1839   1.9  riastrad 	return IS_ERR(override) ? NULL : override;
   1840   1.9  riastrad }
   1841   1.9  riastrad 
   1842   1.9  riastrad /**
   1843   1.9  riastrad  * drm_add_override_edid_modes - add modes from override/firmware EDID
   1844   1.9  riastrad  * @connector: connector we're probing
   1845   1.9  riastrad  *
   1846   1.9  riastrad  * Add modes from the override/firmware EDID, if available. Only to be used from
   1847   1.9  riastrad  * drm_helper_probe_single_connector_modes() as a fallback for when DDC probe
   1848   1.9  riastrad  * failed during drm_get_edid() and caused the override/firmware EDID to be
   1849   1.9  riastrad  * skipped.
   1850   1.9  riastrad  *
   1851   1.9  riastrad  * Return: The number of modes added or 0 if we couldn't find any.
   1852   1.9  riastrad  */
   1853   1.9  riastrad int drm_add_override_edid_modes(struct drm_connector *connector)
   1854   1.9  riastrad {
   1855   1.9  riastrad 	struct edid *override;
   1856   1.9  riastrad 	int num_modes = 0;
   1857   1.9  riastrad 
   1858   1.9  riastrad 	override = drm_get_override_edid(connector);
   1859   1.9  riastrad 	if (override) {
   1860   1.9  riastrad 		drm_connector_update_edid_property(connector, override);
   1861   1.9  riastrad 		num_modes = drm_add_edid_modes(connector, override);
   1862   1.9  riastrad 		kfree(override);
   1863   1.9  riastrad 
   1864   1.9  riastrad 		DRM_DEBUG_KMS("[CONNECTOR:%d:%s] adding %d modes via fallback override/firmware EDID\n",
   1865   1.9  riastrad 			      connector->base.id, connector->name, num_modes);
   1866   1.9  riastrad 	}
   1867   1.9  riastrad 
   1868   1.9  riastrad 	return num_modes;
   1869   1.9  riastrad }
   1870   1.9  riastrad EXPORT_SYMBOL(drm_add_override_edid_modes);
   1871   1.9  riastrad 
   1872   1.6  riastrad /**
   1873   1.6  riastrad  * drm_do_get_edid - get EDID data using a custom EDID block read function
   1874   1.6  riastrad  * @connector: connector we're probing
   1875   1.6  riastrad  * @get_edid_block: EDID block read function
   1876   1.6  riastrad  * @data: private data passed to the block read function
   1877   1.6  riastrad  *
   1878   1.6  riastrad  * When the I2C adapter connected to the DDC bus is hidden behind a device that
   1879   1.6  riastrad  * exposes a different interface to read EDID blocks this function can be used
   1880   1.6  riastrad  * to get EDID data using a custom block read function.
   1881   1.6  riastrad  *
   1882   1.6  riastrad  * As in the general case the DDC bus is accessible by the kernel at the I2C
   1883   1.6  riastrad  * level, drivers must make all reasonable efforts to expose it as an I2C
   1884   1.6  riastrad  * adapter and use drm_get_edid() instead of abusing this function.
   1885   1.6  riastrad  *
   1886   1.9  riastrad  * The EDID may be overridden using debugfs override_edid or firmare EDID
   1887   1.9  riastrad  * (drm_load_edid_firmware() and drm.edid_firmware parameter), in this priority
   1888   1.9  riastrad  * order. Having either of them bypasses actual EDID reads.
   1889   1.9  riastrad  *
   1890   1.6  riastrad  * Return: Pointer to valid EDID or NULL if we couldn't find any.
   1891   1.6  riastrad  */
   1892   1.6  riastrad struct edid *drm_do_get_edid(struct drm_connector *connector,
   1893   1.6  riastrad 	int (*get_edid_block)(void *data, u8 *buf, unsigned int block,
   1894   1.6  riastrad 			      size_t len),
   1895   1.6  riastrad 	void *data)
   1896   1.1  riastrad {
   1897   1.1  riastrad 	int i, j = 0, valid_extensions = 0;
   1898   1.9  riastrad 	u8 *edid, *new;
   1899   1.9  riastrad 	struct edid *override;
   1900   1.9  riastrad 
   1901   1.9  riastrad 	override = drm_get_override_edid(connector);
   1902   1.9  riastrad 	if (override)
   1903   1.9  riastrad 		return override;
   1904   1.1  riastrad 
   1905   1.9  riastrad 	if ((edid = kmalloc(EDID_LENGTH, GFP_KERNEL)) == NULL)
   1906   1.1  riastrad 		return NULL;
   1907   1.1  riastrad 
   1908   1.1  riastrad 	/* base block fetch */
   1909   1.1  riastrad 	for (i = 0; i < 4; i++) {
   1910   1.9  riastrad 		if (get_edid_block(data, edid, 0, EDID_LENGTH))
   1911   1.1  riastrad 			goto out;
   1912   1.9  riastrad 		if (drm_edid_block_valid(edid, 0, false,
   1913   1.6  riastrad 					 &connector->edid_corrupt))
   1914   1.1  riastrad 			break;
   1915   1.9  riastrad 		if (i == 0 && drm_edid_is_zero(edid, EDID_LENGTH)) {
   1916   1.1  riastrad 			connector->null_edid_counter++;
   1917   1.1  riastrad 			goto carp;
   1918   1.1  riastrad 		}
   1919   1.1  riastrad 	}
   1920   1.1  riastrad 	if (i == 4)
   1921   1.1  riastrad 		goto carp;
   1922   1.1  riastrad 
   1923   1.1  riastrad 	/* if there's no extensions, we're done */
   1924   1.9  riastrad 	valid_extensions = edid[0x7e];
   1925   1.9  riastrad 	if (valid_extensions == 0)
   1926   1.9  riastrad 		return (struct edid *)edid;
   1927   1.1  riastrad 
   1928   1.9  riastrad 	new = krealloc(edid, (valid_extensions + 1) * EDID_LENGTH, GFP_KERNEL);
   1929   1.1  riastrad 	if (!new)
   1930   1.1  riastrad 		goto out;
   1931   1.9  riastrad 	edid = new;
   1932   1.9  riastrad 
   1933   1.9  riastrad 	for (j = 1; j <= edid[0x7e]; j++) {
   1934   1.9  riastrad 		u8 *block = edid + j * EDID_LENGTH;
   1935   1.1  riastrad 
   1936   1.1  riastrad 		for (i = 0; i < 4; i++) {
   1937   1.9  riastrad 			if (get_edid_block(data, block, j, EDID_LENGTH))
   1938   1.1  riastrad 				goto out;
   1939   1.9  riastrad 			if (drm_edid_block_valid(block, j, false, NULL))
   1940   1.1  riastrad 				break;
   1941   1.1  riastrad 		}
   1942   1.3  riastrad 
   1943   1.9  riastrad 		if (i == 4)
   1944   1.9  riastrad 			valid_extensions--;
   1945   1.9  riastrad 	}
   1946   1.9  riastrad 
   1947   1.9  riastrad 	if (valid_extensions != edid[0x7e]) {
   1948   1.9  riastrad 		u8 *base;
   1949   1.3  riastrad 
   1950   1.9  riastrad 		connector_bad_edid(connector, edid, edid[0x7e] + 1);
   1951   1.9  riastrad 
   1952   1.9  riastrad 		edid[EDID_LENGTH-1] += edid[0x7e] - valid_extensions;
   1953   1.9  riastrad 		edid[0x7e] = valid_extensions;
   1954   1.1  riastrad 
   1955   1.9  riastrad 		new = kmalloc_array(valid_extensions + 1, EDID_LENGTH,
   1956   1.9  riastrad 				    GFP_KERNEL);
   1957   1.1  riastrad 		if (!new)
   1958   1.1  riastrad 			goto out;
   1959   1.9  riastrad 
   1960   1.9  riastrad 		base = new;
   1961   1.9  riastrad 		for (i = 0; i <= edid[0x7e]; i++) {
   1962   1.9  riastrad 			u8 *block = edid + i * EDID_LENGTH;
   1963   1.9  riastrad 
   1964   1.9  riastrad 			if (!drm_edid_block_valid(block, i, false, NULL))
   1965   1.9  riastrad 				continue;
   1966   1.9  riastrad 
   1967   1.9  riastrad 			memcpy(base, block, EDID_LENGTH);
   1968   1.9  riastrad 			base += EDID_LENGTH;
   1969   1.9  riastrad 		}
   1970   1.9  riastrad 
   1971   1.9  riastrad 		kfree(edid);
   1972   1.9  riastrad 		edid = new;
   1973   1.1  riastrad 	}
   1974   1.1  riastrad 
   1975   1.9  riastrad 	return (struct edid *)edid;
   1976   1.1  riastrad 
   1977   1.1  riastrad carp:
   1978   1.9  riastrad 	connector_bad_edid(connector, edid, 1);
   1979   1.1  riastrad out:
   1980   1.9  riastrad 	kfree(edid);
   1981   1.1  riastrad 	return NULL;
   1982   1.1  riastrad }
   1983   1.6  riastrad EXPORT_SYMBOL_GPL(drm_do_get_edid);
   1984   1.1  riastrad 
   1985   1.1  riastrad /**
   1986   1.6  riastrad  * drm_probe_ddc() - probe DDC presence
   1987   1.6  riastrad  * @adapter: I2C adapter to probe
   1988   1.3  riastrad  *
   1989   1.6  riastrad  * Return: True on success, false on failure.
   1990   1.1  riastrad  */
   1991   1.1  riastrad bool
   1992   1.1  riastrad drm_probe_ddc(struct i2c_adapter *adapter)
   1993   1.1  riastrad {
   1994   1.1  riastrad 	unsigned char out;
   1995   1.1  riastrad 
   1996   1.1  riastrad 	return (drm_do_probe_ddc_edid(adapter, &out, 0, 1) == 0);
   1997   1.1  riastrad }
   1998   1.1  riastrad EXPORT_SYMBOL(drm_probe_ddc);
   1999   1.1  riastrad 
   2000   1.1  riastrad /**
   2001   1.1  riastrad  * drm_get_edid - get EDID data, if available
   2002   1.1  riastrad  * @connector: connector we're probing
   2003   1.6  riastrad  * @adapter: I2C adapter to use for DDC
   2004   1.1  riastrad  *
   2005   1.6  riastrad  * Poke the given I2C channel to grab EDID data if possible.  If found,
   2006   1.1  riastrad  * attach it to the connector.
   2007   1.1  riastrad  *
   2008   1.6  riastrad  * Return: Pointer to valid EDID or NULL if we couldn't find any.
   2009   1.1  riastrad  */
   2010   1.1  riastrad struct edid *drm_get_edid(struct drm_connector *connector,
   2011   1.1  riastrad 			  struct i2c_adapter *adapter)
   2012   1.1  riastrad {
   2013   1.6  riastrad 	struct edid *edid;
   2014   1.1  riastrad 
   2015   1.9  riastrad 	if (connector->force == DRM_FORCE_OFF)
   2016   1.9  riastrad 		return NULL;
   2017   1.9  riastrad 
   2018   1.9  riastrad 	if (connector->force == DRM_FORCE_UNSPECIFIED && !drm_probe_ddc(adapter))
   2019   1.6  riastrad 		return NULL;
   2020   1.1  riastrad 
   2021   1.6  riastrad 	edid = drm_do_get_edid(connector, drm_do_probe_ddc_edid, adapter);
   2022   1.6  riastrad 	if (edid)
   2023   1.6  riastrad 		drm_get_displayid(connector, edid);
   2024   1.1  riastrad 	return edid;
   2025   1.1  riastrad }
   2026   1.1  riastrad EXPORT_SYMBOL(drm_get_edid);
   2027   1.1  riastrad 
   2028   1.3  riastrad /**
   2029   1.9  riastrad  * drm_get_edid_switcheroo - get EDID data for a vga_switcheroo output
   2030   1.9  riastrad  * @connector: connector we're probing
   2031   1.9  riastrad  * @adapter: I2C adapter to use for DDC
   2032   1.9  riastrad  *
   2033   1.9  riastrad  * Wrapper around drm_get_edid() for laptops with dual GPUs using one set of
   2034   1.9  riastrad  * outputs. The wrapper adds the requisite vga_switcheroo calls to temporarily
   2035   1.9  riastrad  * switch DDC to the GPU which is retrieving EDID.
   2036   1.9  riastrad  *
   2037   1.9  riastrad  * Return: Pointer to valid EDID or %NULL if we couldn't find any.
   2038   1.9  riastrad  */
   2039   1.9  riastrad struct edid *drm_get_edid_switcheroo(struct drm_connector *connector,
   2040   1.9  riastrad 				     struct i2c_adapter *adapter)
   2041   1.9  riastrad {
   2042  1.11  riastrad #ifndef __NetBSD__		/* XXX vga switcheroo */
   2043   1.9  riastrad 	struct pci_dev *pdev = connector->dev->pdev;
   2044  1.11  riastrad #endif
   2045   1.9  riastrad 	struct edid *edid;
   2046   1.9  riastrad 
   2047  1.11  riastrad #ifndef __NetBSD__		/* XXX vga switcheroo */
   2048   1.9  riastrad 	vga_switcheroo_lock_ddc(pdev);
   2049  1.11  riastrad #endif
   2050   1.9  riastrad 	edid = drm_get_edid(connector, adapter);
   2051  1.11  riastrad #ifndef __NetBSD__		/* XXX vga switcheroo */
   2052   1.9  riastrad 	vga_switcheroo_unlock_ddc(pdev);
   2053  1.11  riastrad #endif
   2054   1.9  riastrad 
   2055   1.9  riastrad 	return edid;
   2056   1.9  riastrad }
   2057   1.9  riastrad EXPORT_SYMBOL(drm_get_edid_switcheroo);
   2058   1.9  riastrad 
   2059   1.9  riastrad /**
   2060   1.3  riastrad  * drm_edid_duplicate - duplicate an EDID and the extensions
   2061   1.3  riastrad  * @edid: EDID to duplicate
   2062   1.3  riastrad  *
   2063   1.6  riastrad  * Return: Pointer to duplicated EDID or NULL on allocation failure.
   2064   1.3  riastrad  */
   2065   1.3  riastrad struct edid *drm_edid_duplicate(const struct edid *edid)
   2066   1.3  riastrad {
   2067   1.3  riastrad 	return kmemdup(edid, (edid->extensions + 1) * EDID_LENGTH, GFP_KERNEL);
   2068   1.3  riastrad }
   2069   1.3  riastrad EXPORT_SYMBOL(drm_edid_duplicate);
   2070   1.3  riastrad 
   2071   1.1  riastrad /*** EDID parsing ***/
   2072   1.1  riastrad 
   2073   1.1  riastrad /**
   2074   1.1  riastrad  * edid_vendor - match a string against EDID's obfuscated vendor field
   2075   1.1  riastrad  * @edid: EDID to match
   2076   1.1  riastrad  * @vendor: vendor string
   2077   1.1  riastrad  *
   2078   1.1  riastrad  * Returns true if @vendor is in @edid, false otherwise
   2079   1.1  riastrad  */
   2080   1.9  riastrad static bool edid_vendor(const struct edid *edid, const char *vendor)
   2081   1.1  riastrad {
   2082   1.1  riastrad 	char edid_vendor[3];
   2083   1.1  riastrad 
   2084   1.1  riastrad 	edid_vendor[0] = ((edid->mfg_id[0] & 0x7c) >> 2) + '@';
   2085   1.1  riastrad 	edid_vendor[1] = (((edid->mfg_id[0] & 0x3) << 3) |
   2086   1.1  riastrad 			  ((edid->mfg_id[1] & 0xe0) >> 5)) + '@';
   2087   1.1  riastrad 	edid_vendor[2] = (edid->mfg_id[1] & 0x1f) + '@';
   2088   1.1  riastrad 
   2089   1.1  riastrad 	return !strncmp(edid_vendor, vendor, 3);
   2090   1.1  riastrad }
   2091   1.1  riastrad 
   2092   1.1  riastrad /**
   2093   1.1  riastrad  * edid_get_quirks - return quirk flags for a given EDID
   2094   1.1  riastrad  * @edid: EDID to process
   2095   1.1  riastrad  *
   2096   1.1  riastrad  * This tells subsequent routines what fixes they need to apply.
   2097   1.1  riastrad  */
   2098   1.9  riastrad static u32 edid_get_quirks(const struct edid *edid)
   2099   1.1  riastrad {
   2100   1.9  riastrad 	const struct edid_quirk *quirk;
   2101   1.1  riastrad 	int i;
   2102   1.1  riastrad 
   2103   1.1  riastrad 	for (i = 0; i < ARRAY_SIZE(edid_quirk_list); i++) {
   2104   1.1  riastrad 		quirk = &edid_quirk_list[i];
   2105   1.1  riastrad 
   2106   1.1  riastrad 		if (edid_vendor(edid, quirk->vendor) &&
   2107   1.1  riastrad 		    (EDID_PRODUCT_ID(edid) == quirk->product_id))
   2108   1.1  riastrad 			return quirk->quirks;
   2109   1.1  riastrad 	}
   2110   1.1  riastrad 
   2111   1.1  riastrad 	return 0;
   2112   1.1  riastrad }
   2113   1.1  riastrad 
   2114   1.1  riastrad #define MODE_SIZE(m) ((m)->hdisplay * (m)->vdisplay)
   2115   1.3  riastrad #define MODE_REFRESH_DIFF(c,t) (abs((c) - (t)))
   2116   1.1  riastrad 
   2117   1.1  riastrad /**
   2118   1.1  riastrad  * edid_fixup_preferred - set preferred modes based on quirk list
   2119   1.1  riastrad  * @connector: has mode list to fix up
   2120   1.1  riastrad  * @quirks: quirks list
   2121   1.1  riastrad  *
   2122   1.1  riastrad  * Walk the mode list for @connector, clearing the preferred status
   2123   1.1  riastrad  * on existing modes and setting it anew for the right mode ala @quirks.
   2124   1.1  riastrad  */
   2125   1.1  riastrad static void edid_fixup_preferred(struct drm_connector *connector,
   2126   1.1  riastrad 				 u32 quirks)
   2127   1.1  riastrad {
   2128   1.1  riastrad 	struct drm_display_mode *t, *cur_mode, *preferred_mode;
   2129   1.1  riastrad 	int target_refresh = 0;
   2130   1.3  riastrad 	int cur_vrefresh, preferred_vrefresh;
   2131   1.1  riastrad 
   2132   1.1  riastrad 	if (list_empty(&connector->probed_modes))
   2133   1.1  riastrad 		return;
   2134   1.1  riastrad 
   2135   1.1  riastrad 	if (quirks & EDID_QUIRK_PREFER_LARGE_60)
   2136   1.1  riastrad 		target_refresh = 60;
   2137   1.1  riastrad 	if (quirks & EDID_QUIRK_PREFER_LARGE_75)
   2138   1.1  riastrad 		target_refresh = 75;
   2139   1.1  riastrad 
   2140   1.1  riastrad 	preferred_mode = list_first_entry(&connector->probed_modes,
   2141   1.1  riastrad 					  struct drm_display_mode, head);
   2142   1.1  riastrad 
   2143   1.1  riastrad 	list_for_each_entry_safe(cur_mode, t, &connector->probed_modes, head) {
   2144   1.1  riastrad 		cur_mode->type &= ~DRM_MODE_TYPE_PREFERRED;
   2145   1.1  riastrad 
   2146   1.1  riastrad 		if (cur_mode == preferred_mode)
   2147   1.1  riastrad 			continue;
   2148   1.1  riastrad 
   2149   1.1  riastrad 		/* Largest mode is preferred */
   2150   1.1  riastrad 		if (MODE_SIZE(cur_mode) > MODE_SIZE(preferred_mode))
   2151   1.1  riastrad 			preferred_mode = cur_mode;
   2152   1.1  riastrad 
   2153   1.3  riastrad 		cur_vrefresh = cur_mode->vrefresh ?
   2154   1.3  riastrad 			cur_mode->vrefresh : drm_mode_vrefresh(cur_mode);
   2155   1.3  riastrad 		preferred_vrefresh = preferred_mode->vrefresh ?
   2156   1.3  riastrad 			preferred_mode->vrefresh : drm_mode_vrefresh(preferred_mode);
   2157   1.1  riastrad 		/* At a given size, try to get closest to target refresh */
   2158   1.1  riastrad 		if ((MODE_SIZE(cur_mode) == MODE_SIZE(preferred_mode)) &&
   2159   1.3  riastrad 		    MODE_REFRESH_DIFF(cur_vrefresh, target_refresh) <
   2160   1.3  riastrad 		    MODE_REFRESH_DIFF(preferred_vrefresh, target_refresh)) {
   2161   1.1  riastrad 			preferred_mode = cur_mode;
   2162   1.1  riastrad 		}
   2163   1.1  riastrad 	}
   2164   1.1  riastrad 
   2165   1.1  riastrad 	preferred_mode->type |= DRM_MODE_TYPE_PREFERRED;
   2166   1.1  riastrad }
   2167   1.1  riastrad 
   2168   1.1  riastrad static bool
   2169   1.1  riastrad mode_is_rb(const struct drm_display_mode *mode)
   2170   1.1  riastrad {
   2171   1.1  riastrad 	return (mode->htotal - mode->hdisplay == 160) &&
   2172   1.1  riastrad 	       (mode->hsync_end - mode->hdisplay == 80) &&
   2173   1.1  riastrad 	       (mode->hsync_end - mode->hsync_start == 32) &&
   2174   1.1  riastrad 	       (mode->vsync_start - mode->vdisplay == 3);
   2175   1.1  riastrad }
   2176   1.1  riastrad 
   2177   1.1  riastrad /*
   2178   1.1  riastrad  * drm_mode_find_dmt - Create a copy of a mode if present in DMT
   2179   1.1  riastrad  * @dev: Device to duplicate against
   2180   1.1  riastrad  * @hsize: Mode width
   2181   1.1  riastrad  * @vsize: Mode height
   2182   1.1  riastrad  * @fresh: Mode refresh rate
   2183   1.1  riastrad  * @rb: Mode reduced-blanking-ness
   2184   1.1  riastrad  *
   2185   1.1  riastrad  * Walk the DMT mode list looking for a match for the given parameters.
   2186   1.6  riastrad  *
   2187   1.6  riastrad  * Return: A newly allocated copy of the mode, or NULL if not found.
   2188   1.1  riastrad  */
   2189   1.1  riastrad struct drm_display_mode *drm_mode_find_dmt(struct drm_device *dev,
   2190   1.1  riastrad 					   int hsize, int vsize, int fresh,
   2191   1.1  riastrad 					   bool rb)
   2192   1.1  riastrad {
   2193   1.1  riastrad 	int i;
   2194   1.1  riastrad 
   2195   1.3  riastrad 	for (i = 0; i < ARRAY_SIZE(drm_dmt_modes); i++) {
   2196   1.1  riastrad 		const struct drm_display_mode *ptr = &drm_dmt_modes[i];
   2197   1.1  riastrad 		if (hsize != ptr->hdisplay)
   2198   1.1  riastrad 			continue;
   2199   1.1  riastrad 		if (vsize != ptr->vdisplay)
   2200   1.1  riastrad 			continue;
   2201   1.1  riastrad 		if (fresh != drm_mode_vrefresh(ptr))
   2202   1.1  riastrad 			continue;
   2203   1.1  riastrad 		if (rb != mode_is_rb(ptr))
   2204   1.1  riastrad 			continue;
   2205   1.1  riastrad 
   2206   1.1  riastrad 		return drm_mode_duplicate(dev, ptr);
   2207   1.1  riastrad 	}
   2208   1.1  riastrad 
   2209   1.1  riastrad 	return NULL;
   2210   1.1  riastrad }
   2211   1.1  riastrad EXPORT_SYMBOL(drm_mode_find_dmt);
   2212   1.1  riastrad 
   2213   1.1  riastrad typedef void detailed_cb(struct detailed_timing *timing, void *closure);
   2214   1.1  riastrad 
   2215   1.1  riastrad static void
   2216   1.1  riastrad cea_for_each_detailed_block(u8 *ext, detailed_cb *cb, void *closure)
   2217   1.1  riastrad {
   2218   1.1  riastrad 	int i, n = 0;
   2219   1.1  riastrad 	u8 d = ext[0x02];
   2220   1.1  riastrad 	u8 *det_base = ext + d;
   2221   1.1  riastrad 
   2222   1.1  riastrad 	n = (127 - d) / 18;
   2223   1.1  riastrad 	for (i = 0; i < n; i++)
   2224   1.1  riastrad 		cb((struct detailed_timing *)(det_base + 18 * i), closure);
   2225   1.1  riastrad }
   2226   1.1  riastrad 
   2227   1.1  riastrad static void
   2228   1.1  riastrad vtb_for_each_detailed_block(u8 *ext, detailed_cb *cb, void *closure)
   2229   1.1  riastrad {
   2230   1.1  riastrad 	unsigned int i, n = min((int)ext[0x02], 6);
   2231   1.1  riastrad 	u8 *det_base = ext + 5;
   2232   1.1  riastrad 
   2233   1.1  riastrad 	if (ext[0x01] != 1)
   2234   1.1  riastrad 		return; /* unknown version */
   2235   1.1  riastrad 
   2236   1.1  riastrad 	for (i = 0; i < n; i++)
   2237   1.1  riastrad 		cb((struct detailed_timing *)(det_base + 18 * i), closure);
   2238   1.1  riastrad }
   2239   1.1  riastrad 
   2240   1.1  riastrad static void
   2241   1.1  riastrad drm_for_each_detailed_block(u8 *raw_edid, detailed_cb *cb, void *closure)
   2242   1.1  riastrad {
   2243   1.1  riastrad 	int i;
   2244   1.1  riastrad 	struct edid *edid = (struct edid *)raw_edid;
   2245   1.1  riastrad 
   2246   1.1  riastrad 	if (edid == NULL)
   2247   1.1  riastrad 		return;
   2248   1.1  riastrad 
   2249   1.1  riastrad 	for (i = 0; i < EDID_DETAILED_TIMINGS; i++)
   2250   1.1  riastrad 		cb(&(edid->detailed_timings[i]), closure);
   2251   1.1  riastrad 
   2252   1.1  riastrad 	for (i = 1; i <= raw_edid[0x7e]; i++) {
   2253   1.1  riastrad 		u8 *ext = raw_edid + (i * EDID_LENGTH);
   2254   1.1  riastrad 		switch (*ext) {
   2255   1.1  riastrad 		case CEA_EXT:
   2256   1.1  riastrad 			cea_for_each_detailed_block(ext, cb, closure);
   2257   1.1  riastrad 			break;
   2258   1.1  riastrad 		case VTB_EXT:
   2259   1.1  riastrad 			vtb_for_each_detailed_block(ext, cb, closure);
   2260   1.1  riastrad 			break;
   2261   1.1  riastrad 		default:
   2262   1.1  riastrad 			break;
   2263   1.1  riastrad 		}
   2264   1.1  riastrad 	}
   2265   1.1  riastrad }
   2266   1.1  riastrad 
   2267   1.1  riastrad static void
   2268   1.1  riastrad is_rb(struct detailed_timing *t, void *data)
   2269   1.1  riastrad {
   2270   1.1  riastrad 	u8 *r = (u8 *)t;
   2271   1.1  riastrad 	if (r[3] == EDID_DETAIL_MONITOR_RANGE)
   2272   1.1  riastrad 		if (r[15] & 0x10)
   2273   1.1  riastrad 			*(bool *)data = true;
   2274   1.1  riastrad }
   2275   1.1  riastrad 
   2276   1.1  riastrad /* EDID 1.4 defines this explicitly.  For EDID 1.3, we guess, badly. */
   2277   1.1  riastrad static bool
   2278   1.1  riastrad drm_monitor_supports_rb(struct edid *edid)
   2279   1.1  riastrad {
   2280   1.1  riastrad 	if (edid->revision >= 4) {
   2281   1.1  riastrad 		bool ret = false;
   2282   1.1  riastrad 		drm_for_each_detailed_block((u8 *)edid, is_rb, &ret);
   2283   1.1  riastrad 		return ret;
   2284   1.1  riastrad 	}
   2285   1.1  riastrad 
   2286   1.1  riastrad 	return ((edid->input & DRM_EDID_INPUT_DIGITAL) != 0);
   2287   1.1  riastrad }
   2288   1.1  riastrad 
   2289   1.1  riastrad static void
   2290   1.1  riastrad find_gtf2(struct detailed_timing *t, void *data)
   2291   1.1  riastrad {
   2292   1.1  riastrad 	u8 *r = (u8 *)t;
   2293   1.1  riastrad 	if (r[3] == EDID_DETAIL_MONITOR_RANGE && r[10] == 0x02)
   2294   1.1  riastrad 		*(u8 **)data = r;
   2295   1.1  riastrad }
   2296   1.1  riastrad 
   2297   1.1  riastrad /* Secondary GTF curve kicks in above some break frequency */
   2298   1.1  riastrad static int
   2299   1.1  riastrad drm_gtf2_hbreak(struct edid *edid)
   2300   1.1  riastrad {
   2301   1.1  riastrad 	u8 *r = NULL;
   2302   1.1  riastrad 	drm_for_each_detailed_block((u8 *)edid, find_gtf2, &r);
   2303   1.1  riastrad 	return r ? (r[12] * 2) : 0;
   2304   1.1  riastrad }
   2305   1.1  riastrad 
   2306   1.1  riastrad static int
   2307   1.1  riastrad drm_gtf2_2c(struct edid *edid)
   2308   1.1  riastrad {
   2309   1.1  riastrad 	u8 *r = NULL;
   2310   1.1  riastrad 	drm_for_each_detailed_block((u8 *)edid, find_gtf2, &r);
   2311   1.1  riastrad 	return r ? r[13] : 0;
   2312   1.1  riastrad }
   2313   1.1  riastrad 
   2314   1.1  riastrad static int
   2315   1.1  riastrad drm_gtf2_m(struct edid *edid)
   2316   1.1  riastrad {
   2317   1.1  riastrad 	u8 *r = NULL;
   2318   1.1  riastrad 	drm_for_each_detailed_block((u8 *)edid, find_gtf2, &r);
   2319   1.1  riastrad 	return r ? (r[15] << 8) + r[14] : 0;
   2320   1.1  riastrad }
   2321   1.1  riastrad 
   2322   1.1  riastrad static int
   2323   1.1  riastrad drm_gtf2_k(struct edid *edid)
   2324   1.1  riastrad {
   2325   1.1  riastrad 	u8 *r = NULL;
   2326   1.1  riastrad 	drm_for_each_detailed_block((u8 *)edid, find_gtf2, &r);
   2327   1.1  riastrad 	return r ? r[16] : 0;
   2328   1.1  riastrad }
   2329   1.1  riastrad 
   2330   1.1  riastrad static int
   2331   1.1  riastrad drm_gtf2_2j(struct edid *edid)
   2332   1.1  riastrad {
   2333   1.1  riastrad 	u8 *r = NULL;
   2334   1.1  riastrad 	drm_for_each_detailed_block((u8 *)edid, find_gtf2, &r);
   2335   1.1  riastrad 	return r ? r[17] : 0;
   2336   1.1  riastrad }
   2337   1.1  riastrad 
   2338   1.1  riastrad /**
   2339   1.1  riastrad  * standard_timing_level - get std. timing level(CVT/GTF/DMT)
   2340   1.1  riastrad  * @edid: EDID block to scan
   2341   1.1  riastrad  */
   2342   1.1  riastrad static int standard_timing_level(struct edid *edid)
   2343   1.1  riastrad {
   2344   1.1  riastrad 	if (edid->revision >= 2) {
   2345   1.1  riastrad 		if (edid->revision >= 4 && (edid->features & DRM_EDID_FEATURE_DEFAULT_GTF))
   2346   1.1  riastrad 			return LEVEL_CVT;
   2347   1.1  riastrad 		if (drm_gtf2_hbreak(edid))
   2348   1.1  riastrad 			return LEVEL_GTF2;
   2349   1.9  riastrad 		if (edid->features & DRM_EDID_FEATURE_DEFAULT_GTF)
   2350   1.9  riastrad 			return LEVEL_GTF;
   2351   1.1  riastrad 	}
   2352   1.1  riastrad 	return LEVEL_DMT;
   2353   1.1  riastrad }
   2354   1.1  riastrad 
   2355   1.1  riastrad /*
   2356   1.1  riastrad  * 0 is reserved.  The spec says 0x01 fill for unused timings.  Some old
   2357   1.1  riastrad  * monitors fill with ascii space (0x20) instead.
   2358   1.1  riastrad  */
   2359   1.1  riastrad static int
   2360   1.1  riastrad bad_std_timing(u8 a, u8 b)
   2361   1.1  riastrad {
   2362   1.1  riastrad 	return (a == 0x00 && b == 0x00) ||
   2363   1.1  riastrad 	       (a == 0x01 && b == 0x01) ||
   2364   1.1  riastrad 	       (a == 0x20 && b == 0x20);
   2365   1.1  riastrad }
   2366   1.1  riastrad 
   2367   1.1  riastrad /**
   2368   1.1  riastrad  * drm_mode_std - convert standard mode info (width, height, refresh) into mode
   2369   1.3  riastrad  * @connector: connector of for the EDID block
   2370   1.3  riastrad  * @edid: EDID block to scan
   2371   1.1  riastrad  * @t: standard timing params
   2372   1.1  riastrad  *
   2373   1.1  riastrad  * Take the standard timing params (in this case width, aspect, and refresh)
   2374   1.1  riastrad  * and convert them into a real mode using CVT/GTF/DMT.
   2375   1.1  riastrad  */
   2376   1.1  riastrad static struct drm_display_mode *
   2377   1.1  riastrad drm_mode_std(struct drm_connector *connector, struct edid *edid,
   2378   1.6  riastrad 	     struct std_timing *t)
   2379   1.1  riastrad {
   2380   1.1  riastrad 	struct drm_device *dev = connector->dev;
   2381   1.1  riastrad 	struct drm_display_mode *m, *mode = NULL;
   2382   1.1  riastrad 	int hsize, vsize;
   2383   1.1  riastrad 	int vrefresh_rate;
   2384   1.1  riastrad 	unsigned aspect_ratio = (t->vfreq_aspect & EDID_TIMING_ASPECT_MASK)
   2385   1.1  riastrad 		>> EDID_TIMING_ASPECT_SHIFT;
   2386   1.1  riastrad 	unsigned vfreq = (t->vfreq_aspect & EDID_TIMING_VFREQ_MASK)
   2387   1.1  riastrad 		>> EDID_TIMING_VFREQ_SHIFT;
   2388   1.1  riastrad 	int timing_level = standard_timing_level(edid);
   2389   1.1  riastrad 
   2390   1.1  riastrad 	if (bad_std_timing(t->hsize, t->vfreq_aspect))
   2391   1.1  riastrad 		return NULL;
   2392   1.1  riastrad 
   2393   1.1  riastrad 	/* According to the EDID spec, the hdisplay = hsize * 8 + 248 */
   2394   1.1  riastrad 	hsize = t->hsize * 8 + 248;
   2395   1.1  riastrad 	/* vrefresh_rate = vfreq + 60 */
   2396   1.1  riastrad 	vrefresh_rate = vfreq + 60;
   2397   1.1  riastrad 	/* the vdisplay is calculated based on the aspect ratio */
   2398   1.1  riastrad 	if (aspect_ratio == 0) {
   2399   1.6  riastrad 		if (edid->revision < 3)
   2400   1.1  riastrad 			vsize = hsize;
   2401   1.1  riastrad 		else
   2402   1.1  riastrad 			vsize = (hsize * 10) / 16;
   2403   1.1  riastrad 	} else if (aspect_ratio == 1)
   2404   1.1  riastrad 		vsize = (hsize * 3) / 4;
   2405   1.1  riastrad 	else if (aspect_ratio == 2)
   2406   1.1  riastrad 		vsize = (hsize * 4) / 5;
   2407   1.1  riastrad 	else
   2408   1.1  riastrad 		vsize = (hsize * 9) / 16;
   2409   1.1  riastrad 
   2410   1.1  riastrad 	/* HDTV hack, part 1 */
   2411   1.1  riastrad 	if (vrefresh_rate == 60 &&
   2412   1.1  riastrad 	    ((hsize == 1360 && vsize == 765) ||
   2413   1.1  riastrad 	     (hsize == 1368 && vsize == 769))) {
   2414   1.1  riastrad 		hsize = 1366;
   2415   1.1  riastrad 		vsize = 768;
   2416   1.1  riastrad 	}
   2417   1.1  riastrad 
   2418   1.1  riastrad 	/*
   2419   1.1  riastrad 	 * If this connector already has a mode for this size and refresh
   2420   1.1  riastrad 	 * rate (because it came from detailed or CVT info), use that
   2421   1.1  riastrad 	 * instead.  This way we don't have to guess at interlace or
   2422   1.1  riastrad 	 * reduced blanking.
   2423   1.1  riastrad 	 */
   2424   1.1  riastrad 	list_for_each_entry(m, &connector->probed_modes, head)
   2425   1.1  riastrad 		if (m->hdisplay == hsize && m->vdisplay == vsize &&
   2426   1.1  riastrad 		    drm_mode_vrefresh(m) == vrefresh_rate)
   2427   1.1  riastrad 			return NULL;
   2428   1.1  riastrad 
   2429   1.1  riastrad 	/* HDTV hack, part 2 */
   2430   1.1  riastrad 	if (hsize == 1366 && vsize == 768 && vrefresh_rate == 60) {
   2431   1.1  riastrad 		mode = drm_cvt_mode(dev, 1366, 768, vrefresh_rate, 0, 0,
   2432   1.1  riastrad 				    false);
   2433   1.9  riastrad 		if (!mode)
   2434   1.9  riastrad 			return NULL;
   2435   1.1  riastrad 		mode->hdisplay = 1366;
   2436   1.1  riastrad 		mode->hsync_start = mode->hsync_start - 1;
   2437   1.1  riastrad 		mode->hsync_end = mode->hsync_end - 1;
   2438   1.1  riastrad 		return mode;
   2439   1.1  riastrad 	}
   2440   1.1  riastrad 
   2441   1.1  riastrad 	/* check whether it can be found in default mode table */
   2442   1.1  riastrad 	if (drm_monitor_supports_rb(edid)) {
   2443   1.1  riastrad 		mode = drm_mode_find_dmt(dev, hsize, vsize, vrefresh_rate,
   2444   1.1  riastrad 					 true);
   2445   1.1  riastrad 		if (mode)
   2446   1.1  riastrad 			return mode;
   2447   1.1  riastrad 	}
   2448   1.1  riastrad 	mode = drm_mode_find_dmt(dev, hsize, vsize, vrefresh_rate, false);
   2449   1.1  riastrad 	if (mode)
   2450   1.1  riastrad 		return mode;
   2451   1.1  riastrad 
   2452   1.1  riastrad 	/* okay, generate it */
   2453   1.1  riastrad 	switch (timing_level) {
   2454   1.1  riastrad 	case LEVEL_DMT:
   2455   1.1  riastrad 		break;
   2456   1.1  riastrad 	case LEVEL_GTF:
   2457   1.1  riastrad 		mode = drm_gtf_mode(dev, hsize, vsize, vrefresh_rate, 0, 0);
   2458   1.1  riastrad 		break;
   2459   1.1  riastrad 	case LEVEL_GTF2:
   2460   1.1  riastrad 		/*
   2461   1.1  riastrad 		 * This is potentially wrong if there's ever a monitor with
   2462   1.1  riastrad 		 * more than one ranges section, each claiming a different
   2463   1.1  riastrad 		 * secondary GTF curve.  Please don't do that.
   2464   1.1  riastrad 		 */
   2465   1.1  riastrad 		mode = drm_gtf_mode(dev, hsize, vsize, vrefresh_rate, 0, 0);
   2466   1.1  riastrad 		if (!mode)
   2467   1.1  riastrad 			return NULL;
   2468   1.1  riastrad 		if (drm_mode_hsync(mode) > drm_gtf2_hbreak(edid)) {
   2469   1.1  riastrad 			drm_mode_destroy(dev, mode);
   2470   1.1  riastrad 			mode = drm_gtf_mode_complex(dev, hsize, vsize,
   2471   1.1  riastrad 						    vrefresh_rate, 0, 0,
   2472   1.1  riastrad 						    drm_gtf2_m(edid),
   2473   1.1  riastrad 						    drm_gtf2_2c(edid),
   2474   1.1  riastrad 						    drm_gtf2_k(edid),
   2475   1.1  riastrad 						    drm_gtf2_2j(edid));
   2476   1.1  riastrad 		}
   2477   1.1  riastrad 		break;
   2478   1.1  riastrad 	case LEVEL_CVT:
   2479   1.1  riastrad 		mode = drm_cvt_mode(dev, hsize, vsize, vrefresh_rate, 0, 0,
   2480   1.1  riastrad 				    false);
   2481   1.1  riastrad 		break;
   2482   1.1  riastrad 	}
   2483   1.1  riastrad 	return mode;
   2484   1.1  riastrad }
   2485   1.1  riastrad 
   2486   1.1  riastrad /*
   2487   1.1  riastrad  * EDID is delightfully ambiguous about how interlaced modes are to be
   2488   1.1  riastrad  * encoded.  Our internal representation is of frame height, but some
   2489   1.1  riastrad  * HDTV detailed timings are encoded as field height.
   2490   1.1  riastrad  *
   2491   1.1  riastrad  * The format list here is from CEA, in frame size.  Technically we
   2492   1.1  riastrad  * should be checking refresh rate too.  Whatever.
   2493   1.1  riastrad  */
   2494   1.1  riastrad static void
   2495   1.1  riastrad drm_mode_do_interlace_quirk(struct drm_display_mode *mode,
   2496   1.1  riastrad 			    struct detailed_pixel_timing *pt)
   2497   1.1  riastrad {
   2498   1.1  riastrad 	int i;
   2499   1.1  riastrad 	static const struct {
   2500   1.1  riastrad 		int w, h;
   2501   1.1  riastrad 	} cea_interlaced[] = {
   2502   1.1  riastrad 		{ 1920, 1080 },
   2503   1.1  riastrad 		{  720,  480 },
   2504   1.1  riastrad 		{ 1440,  480 },
   2505   1.1  riastrad 		{ 2880,  480 },
   2506   1.1  riastrad 		{  720,  576 },
   2507   1.1  riastrad 		{ 1440,  576 },
   2508   1.1  riastrad 		{ 2880,  576 },
   2509   1.1  riastrad 	};
   2510   1.1  riastrad 
   2511   1.1  riastrad 	if (!(pt->misc & DRM_EDID_PT_INTERLACED))
   2512   1.1  riastrad 		return;
   2513   1.1  riastrad 
   2514   1.1  riastrad 	for (i = 0; i < ARRAY_SIZE(cea_interlaced); i++) {
   2515   1.1  riastrad 		if ((mode->hdisplay == cea_interlaced[i].w) &&
   2516   1.1  riastrad 		    (mode->vdisplay == cea_interlaced[i].h / 2)) {
   2517   1.1  riastrad 			mode->vdisplay *= 2;
   2518   1.1  riastrad 			mode->vsync_start *= 2;
   2519   1.1  riastrad 			mode->vsync_end *= 2;
   2520   1.1  riastrad 			mode->vtotal *= 2;
   2521   1.1  riastrad 			mode->vtotal |= 1;
   2522   1.1  riastrad 		}
   2523   1.1  riastrad 	}
   2524   1.1  riastrad 
   2525   1.1  riastrad 	mode->flags |= DRM_MODE_FLAG_INTERLACE;
   2526   1.1  riastrad }
   2527   1.1  riastrad 
   2528   1.1  riastrad /**
   2529   1.1  riastrad  * drm_mode_detailed - create a new mode from an EDID detailed timing section
   2530   1.1  riastrad  * @dev: DRM device (needed to create new mode)
   2531   1.1  riastrad  * @edid: EDID block
   2532   1.1  riastrad  * @timing: EDID detailed timing info
   2533   1.1  riastrad  * @quirks: quirks to apply
   2534   1.1  riastrad  *
   2535   1.1  riastrad  * An EDID detailed timing block contains enough info for us to create and
   2536   1.1  riastrad  * return a new struct drm_display_mode.
   2537   1.1  riastrad  */
   2538   1.1  riastrad static struct drm_display_mode *drm_mode_detailed(struct drm_device *dev,
   2539   1.1  riastrad 						  struct edid *edid,
   2540   1.1  riastrad 						  struct detailed_timing *timing,
   2541   1.1  riastrad 						  u32 quirks)
   2542   1.1  riastrad {
   2543   1.1  riastrad 	struct drm_display_mode *mode;
   2544   1.1  riastrad 	struct detailed_pixel_timing *pt = &timing->data.pixel_data;
   2545   1.1  riastrad 	unsigned hactive = (pt->hactive_hblank_hi & 0xf0) << 4 | pt->hactive_lo;
   2546   1.1  riastrad 	unsigned vactive = (pt->vactive_vblank_hi & 0xf0) << 4 | pt->vactive_lo;
   2547   1.1  riastrad 	unsigned hblank = (pt->hactive_hblank_hi & 0xf) << 8 | pt->hblank_lo;
   2548   1.1  riastrad 	unsigned vblank = (pt->vactive_vblank_hi & 0xf) << 8 | pt->vblank_lo;
   2549   1.1  riastrad 	unsigned hsync_offset = (pt->hsync_vsync_offset_pulse_width_hi & 0xc0) << 2 | pt->hsync_offset_lo;
   2550   1.1  riastrad 	unsigned hsync_pulse_width = (pt->hsync_vsync_offset_pulse_width_hi & 0x30) << 4 | pt->hsync_pulse_width_lo;
   2551   1.3  riastrad 	unsigned vsync_offset = (pt->hsync_vsync_offset_pulse_width_hi & 0xc) << 2 | pt->vsync_offset_pulse_width_lo >> 4;
   2552   1.1  riastrad 	unsigned vsync_pulse_width = (pt->hsync_vsync_offset_pulse_width_hi & 0x3) << 4 | (pt->vsync_offset_pulse_width_lo & 0xf);
   2553   1.1  riastrad 
   2554   1.1  riastrad 	/* ignore tiny modes */
   2555   1.1  riastrad 	if (hactive < 64 || vactive < 64)
   2556   1.1  riastrad 		return NULL;
   2557   1.1  riastrad 
   2558   1.1  riastrad 	if (pt->misc & DRM_EDID_PT_STEREO) {
   2559   1.3  riastrad 		DRM_DEBUG_KMS("stereo mode not supported\n");
   2560   1.1  riastrad 		return NULL;
   2561   1.1  riastrad 	}
   2562   1.1  riastrad 	if (!(pt->misc & DRM_EDID_PT_SEPARATE_SYNC)) {
   2563   1.3  riastrad 		DRM_DEBUG_KMS("composite sync not supported\n");
   2564   1.1  riastrad 	}
   2565   1.1  riastrad 
   2566   1.1  riastrad 	/* it is incorrect if hsync/vsync width is zero */
   2567   1.1  riastrad 	if (!hsync_pulse_width || !vsync_pulse_width) {
   2568   1.1  riastrad 		DRM_DEBUG_KMS("Incorrect Detailed timing. "
   2569   1.1  riastrad 				"Wrong Hsync/Vsync pulse width\n");
   2570   1.1  riastrad 		return NULL;
   2571   1.1  riastrad 	}
   2572   1.1  riastrad 
   2573   1.1  riastrad 	if (quirks & EDID_QUIRK_FORCE_REDUCED_BLANKING) {
   2574   1.1  riastrad 		mode = drm_cvt_mode(dev, hactive, vactive, 60, true, false, false);
   2575   1.1  riastrad 		if (!mode)
   2576   1.1  riastrad 			return NULL;
   2577   1.1  riastrad 
   2578   1.1  riastrad 		goto set_size;
   2579   1.1  riastrad 	}
   2580   1.1  riastrad 
   2581   1.1  riastrad 	mode = drm_mode_create(dev);
   2582   1.1  riastrad 	if (!mode)
   2583   1.1  riastrad 		return NULL;
   2584   1.1  riastrad 
   2585   1.1  riastrad 	if (quirks & EDID_QUIRK_135_CLOCK_TOO_HIGH)
   2586   1.1  riastrad 		timing->pixel_clock = cpu_to_le16(1088);
   2587   1.1  riastrad 
   2588   1.1  riastrad 	mode->clock = le16_to_cpu(timing->pixel_clock) * 10;
   2589   1.1  riastrad 
   2590   1.1  riastrad 	mode->hdisplay = hactive;
   2591   1.1  riastrad 	mode->hsync_start = mode->hdisplay + hsync_offset;
   2592   1.1  riastrad 	mode->hsync_end = mode->hsync_start + hsync_pulse_width;
   2593   1.1  riastrad 	mode->htotal = mode->hdisplay + hblank;
   2594   1.1  riastrad 
   2595   1.1  riastrad 	mode->vdisplay = vactive;
   2596   1.1  riastrad 	mode->vsync_start = mode->vdisplay + vsync_offset;
   2597   1.1  riastrad 	mode->vsync_end = mode->vsync_start + vsync_pulse_width;
   2598   1.1  riastrad 	mode->vtotal = mode->vdisplay + vblank;
   2599   1.1  riastrad 
   2600   1.1  riastrad 	/* Some EDIDs have bogus h/vtotal values */
   2601   1.1  riastrad 	if (mode->hsync_end > mode->htotal)
   2602   1.1  riastrad 		mode->htotal = mode->hsync_end + 1;
   2603   1.1  riastrad 	if (mode->vsync_end > mode->vtotal)
   2604   1.1  riastrad 		mode->vtotal = mode->vsync_end + 1;
   2605   1.1  riastrad 
   2606   1.1  riastrad 	drm_mode_do_interlace_quirk(mode, pt);
   2607   1.1  riastrad 
   2608   1.1  riastrad 	if (quirks & EDID_QUIRK_DETAILED_SYNC_PP) {
   2609   1.1  riastrad 		pt->misc |= DRM_EDID_PT_HSYNC_POSITIVE | DRM_EDID_PT_VSYNC_POSITIVE;
   2610   1.1  riastrad 	}
   2611   1.1  riastrad 
   2612   1.1  riastrad 	mode->flags |= (pt->misc & DRM_EDID_PT_HSYNC_POSITIVE) ?
   2613   1.1  riastrad 		DRM_MODE_FLAG_PHSYNC : DRM_MODE_FLAG_NHSYNC;
   2614   1.1  riastrad 	mode->flags |= (pt->misc & DRM_EDID_PT_VSYNC_POSITIVE) ?
   2615   1.1  riastrad 		DRM_MODE_FLAG_PVSYNC : DRM_MODE_FLAG_NVSYNC;
   2616   1.1  riastrad 
   2617   1.1  riastrad set_size:
   2618   1.1  riastrad 	mode->width_mm = pt->width_mm_lo | (pt->width_height_mm_hi & 0xf0) << 4;
   2619   1.1  riastrad 	mode->height_mm = pt->height_mm_lo | (pt->width_height_mm_hi & 0xf) << 8;
   2620   1.1  riastrad 
   2621   1.1  riastrad 	if (quirks & EDID_QUIRK_DETAILED_IN_CM) {
   2622   1.1  riastrad 		mode->width_mm *= 10;
   2623   1.1  riastrad 		mode->height_mm *= 10;
   2624   1.1  riastrad 	}
   2625   1.1  riastrad 
   2626   1.1  riastrad 	if (quirks & EDID_QUIRK_DETAILED_USE_MAXIMUM_SIZE) {
   2627   1.1  riastrad 		mode->width_mm = edid->width_cm * 10;
   2628   1.1  riastrad 		mode->height_mm = edid->height_cm * 10;
   2629   1.1  riastrad 	}
   2630   1.1  riastrad 
   2631   1.1  riastrad 	mode->type = DRM_MODE_TYPE_DRIVER;
   2632   1.3  riastrad 	mode->vrefresh = drm_mode_vrefresh(mode);
   2633   1.1  riastrad 	drm_mode_set_name(mode);
   2634   1.1  riastrad 
   2635   1.1  riastrad 	return mode;
   2636   1.1  riastrad }
   2637   1.1  riastrad 
   2638   1.1  riastrad static bool
   2639   1.1  riastrad mode_in_hsync_range(const struct drm_display_mode *mode,
   2640   1.1  riastrad 		    struct edid *edid, u8 *t)
   2641   1.1  riastrad {
   2642   1.1  riastrad 	int hsync, hmin, hmax;
   2643   1.1  riastrad 
   2644   1.1  riastrad 	hmin = t[7];
   2645   1.1  riastrad 	if (edid->revision >= 4)
   2646   1.1  riastrad 	    hmin += ((t[4] & 0x04) ? 255 : 0);
   2647   1.1  riastrad 	hmax = t[8];
   2648   1.1  riastrad 	if (edid->revision >= 4)
   2649   1.1  riastrad 	    hmax += ((t[4] & 0x08) ? 255 : 0);
   2650   1.1  riastrad 	hsync = drm_mode_hsync(mode);
   2651   1.1  riastrad 
   2652   1.1  riastrad 	return (hsync <= hmax && hsync >= hmin);
   2653   1.1  riastrad }
   2654   1.1  riastrad 
   2655   1.1  riastrad static bool
   2656   1.1  riastrad mode_in_vsync_range(const struct drm_display_mode *mode,
   2657   1.1  riastrad 		    struct edid *edid, u8 *t)
   2658   1.1  riastrad {
   2659   1.1  riastrad 	int vsync, vmin, vmax;
   2660   1.1  riastrad 
   2661   1.1  riastrad 	vmin = t[5];
   2662   1.1  riastrad 	if (edid->revision >= 4)
   2663   1.1  riastrad 	    vmin += ((t[4] & 0x01) ? 255 : 0);
   2664   1.1  riastrad 	vmax = t[6];
   2665   1.1  riastrad 	if (edid->revision >= 4)
   2666   1.1  riastrad 	    vmax += ((t[4] & 0x02) ? 255 : 0);
   2667   1.1  riastrad 	vsync = drm_mode_vrefresh(mode);
   2668   1.1  riastrad 
   2669   1.1  riastrad 	return (vsync <= vmax && vsync >= vmin);
   2670   1.1  riastrad }
   2671   1.1  riastrad 
   2672   1.1  riastrad static u32
   2673   1.1  riastrad range_pixel_clock(struct edid *edid, u8 *t)
   2674   1.1  riastrad {
   2675   1.1  riastrad 	/* unspecified */
   2676   1.1  riastrad 	if (t[9] == 0 || t[9] == 255)
   2677   1.1  riastrad 		return 0;
   2678   1.1  riastrad 
   2679   1.1  riastrad 	/* 1.4 with CVT support gives us real precision, yay */
   2680   1.1  riastrad 	if (edid->revision >= 4 && t[10] == 0x04)
   2681   1.1  riastrad 		return (t[9] * 10000) - ((t[12] >> 2) * 250);
   2682   1.1  riastrad 
   2683   1.1  riastrad 	/* 1.3 is pathetic, so fuzz up a bit */
   2684   1.1  riastrad 	return t[9] * 10000 + 5001;
   2685   1.1  riastrad }
   2686   1.1  riastrad 
   2687   1.1  riastrad static bool
   2688   1.1  riastrad mode_in_range(const struct drm_display_mode *mode, struct edid *edid,
   2689   1.1  riastrad 	      struct detailed_timing *timing)
   2690   1.1  riastrad {
   2691   1.1  riastrad 	u32 max_clock;
   2692   1.1  riastrad 	u8 *t = (u8 *)timing;
   2693   1.1  riastrad 
   2694   1.1  riastrad 	if (!mode_in_hsync_range(mode, edid, t))
   2695   1.1  riastrad 		return false;
   2696   1.1  riastrad 
   2697   1.1  riastrad 	if (!mode_in_vsync_range(mode, edid, t))
   2698   1.1  riastrad 		return false;
   2699   1.1  riastrad 
   2700   1.1  riastrad 	if ((max_clock = range_pixel_clock(edid, t)))
   2701   1.1  riastrad 		if (mode->clock > max_clock)
   2702   1.1  riastrad 			return false;
   2703   1.1  riastrad 
   2704   1.1  riastrad 	/* 1.4 max horizontal check */
   2705   1.1  riastrad 	if (edid->revision >= 4 && t[10] == 0x04)
   2706   1.1  riastrad 		if (t[13] && mode->hdisplay > 8 * (t[13] + (256 * (t[12]&0x3))))
   2707   1.1  riastrad 			return false;
   2708   1.1  riastrad 
   2709   1.1  riastrad 	if (mode_is_rb(mode) && !drm_monitor_supports_rb(edid))
   2710   1.1  riastrad 		return false;
   2711   1.1  riastrad 
   2712   1.1  riastrad 	return true;
   2713   1.1  riastrad }
   2714   1.1  riastrad 
   2715   1.1  riastrad static bool valid_inferred_mode(const struct drm_connector *connector,
   2716   1.1  riastrad 				const struct drm_display_mode *mode)
   2717   1.1  riastrad {
   2718   1.6  riastrad 	const struct drm_display_mode *m;
   2719   1.1  riastrad 	bool ok = false;
   2720   1.1  riastrad 
   2721   1.1  riastrad 	list_for_each_entry(m, &connector->probed_modes, head) {
   2722   1.1  riastrad 		if (mode->hdisplay == m->hdisplay &&
   2723   1.1  riastrad 		    mode->vdisplay == m->vdisplay &&
   2724   1.1  riastrad 		    drm_mode_vrefresh(mode) == drm_mode_vrefresh(m))
   2725   1.1  riastrad 			return false; /* duplicated */
   2726   1.1  riastrad 		if (mode->hdisplay <= m->hdisplay &&
   2727   1.1  riastrad 		    mode->vdisplay <= m->vdisplay)
   2728   1.1  riastrad 			ok = true;
   2729   1.1  riastrad 	}
   2730   1.1  riastrad 	return ok;
   2731   1.1  riastrad }
   2732   1.1  riastrad 
   2733   1.1  riastrad static int
   2734   1.1  riastrad drm_dmt_modes_for_range(struct drm_connector *connector, struct edid *edid,
   2735   1.1  riastrad 			struct detailed_timing *timing)
   2736   1.1  riastrad {
   2737   1.1  riastrad 	int i, modes = 0;
   2738   1.1  riastrad 	struct drm_display_mode *newmode;
   2739   1.1  riastrad 	struct drm_device *dev = connector->dev;
   2740   1.1  riastrad 
   2741   1.3  riastrad 	for (i = 0; i < ARRAY_SIZE(drm_dmt_modes); i++) {
   2742   1.1  riastrad 		if (mode_in_range(drm_dmt_modes + i, edid, timing) &&
   2743   1.1  riastrad 		    valid_inferred_mode(connector, drm_dmt_modes + i)) {
   2744   1.1  riastrad 			newmode = drm_mode_duplicate(dev, &drm_dmt_modes[i]);
   2745   1.1  riastrad 			if (newmode) {
   2746   1.1  riastrad 				drm_mode_probed_add(connector, newmode);
   2747   1.1  riastrad 				modes++;
   2748   1.1  riastrad 			}
   2749   1.1  riastrad 		}
   2750   1.1  riastrad 	}
   2751   1.1  riastrad 
   2752   1.1  riastrad 	return modes;
   2753   1.1  riastrad }
   2754   1.1  riastrad 
   2755   1.1  riastrad /* fix up 1366x768 mode from 1368x768;
   2756   1.1  riastrad  * GFT/CVT can't express 1366 width which isn't dividable by 8
   2757   1.1  riastrad  */
   2758   1.9  riastrad void drm_mode_fixup_1366x768(struct drm_display_mode *mode)
   2759   1.1  riastrad {
   2760   1.1  riastrad 	if (mode->hdisplay == 1368 && mode->vdisplay == 768) {
   2761   1.1  riastrad 		mode->hdisplay = 1366;
   2762   1.1  riastrad 		mode->hsync_start--;
   2763   1.1  riastrad 		mode->hsync_end--;
   2764   1.1  riastrad 		drm_mode_set_name(mode);
   2765   1.1  riastrad 	}
   2766   1.1  riastrad }
   2767   1.1  riastrad 
   2768   1.1  riastrad static int
   2769   1.1  riastrad drm_gtf_modes_for_range(struct drm_connector *connector, struct edid *edid,
   2770   1.1  riastrad 			struct detailed_timing *timing)
   2771   1.1  riastrad {
   2772   1.1  riastrad 	int i, modes = 0;
   2773   1.1  riastrad 	struct drm_display_mode *newmode;
   2774   1.1  riastrad 	struct drm_device *dev = connector->dev;
   2775   1.1  riastrad 
   2776   1.3  riastrad 	for (i = 0; i < ARRAY_SIZE(extra_modes); i++) {
   2777   1.1  riastrad 		const struct minimode *m = &extra_modes[i];
   2778   1.1  riastrad 		newmode = drm_gtf_mode(dev, m->w, m->h, m->r, 0, 0);
   2779   1.1  riastrad 		if (!newmode)
   2780   1.1  riastrad 			return modes;
   2781   1.1  riastrad 
   2782   1.9  riastrad 		drm_mode_fixup_1366x768(newmode);
   2783   1.1  riastrad 		if (!mode_in_range(newmode, edid, timing) ||
   2784   1.1  riastrad 		    !valid_inferred_mode(connector, newmode)) {
   2785   1.1  riastrad 			drm_mode_destroy(dev, newmode);
   2786   1.1  riastrad 			continue;
   2787   1.1  riastrad 		}
   2788   1.1  riastrad 
   2789   1.1  riastrad 		drm_mode_probed_add(connector, newmode);
   2790   1.1  riastrad 		modes++;
   2791   1.1  riastrad 	}
   2792   1.1  riastrad 
   2793   1.1  riastrad 	return modes;
   2794   1.1  riastrad }
   2795   1.1  riastrad 
   2796   1.1  riastrad static int
   2797   1.1  riastrad drm_cvt_modes_for_range(struct drm_connector *connector, struct edid *edid,
   2798   1.1  riastrad 			struct detailed_timing *timing)
   2799   1.1  riastrad {
   2800   1.1  riastrad 	int i, modes = 0;
   2801   1.1  riastrad 	struct drm_display_mode *newmode;
   2802   1.1  riastrad 	struct drm_device *dev = connector->dev;
   2803   1.1  riastrad 	bool rb = drm_monitor_supports_rb(edid);
   2804   1.1  riastrad 
   2805   1.3  riastrad 	for (i = 0; i < ARRAY_SIZE(extra_modes); i++) {
   2806   1.1  riastrad 		const struct minimode *m = &extra_modes[i];
   2807   1.1  riastrad 		newmode = drm_cvt_mode(dev, m->w, m->h, m->r, rb, 0, 0);
   2808   1.1  riastrad 		if (!newmode)
   2809   1.1  riastrad 			return modes;
   2810   1.1  riastrad 
   2811   1.9  riastrad 		drm_mode_fixup_1366x768(newmode);
   2812   1.1  riastrad 		if (!mode_in_range(newmode, edid, timing) ||
   2813   1.1  riastrad 		    !valid_inferred_mode(connector, newmode)) {
   2814   1.1  riastrad 			drm_mode_destroy(dev, newmode);
   2815   1.1  riastrad 			continue;
   2816   1.1  riastrad 		}
   2817   1.1  riastrad 
   2818   1.1  riastrad 		drm_mode_probed_add(connector, newmode);
   2819   1.1  riastrad 		modes++;
   2820   1.1  riastrad 	}
   2821   1.1  riastrad 
   2822   1.1  riastrad 	return modes;
   2823   1.1  riastrad }
   2824   1.1  riastrad 
   2825   1.1  riastrad static void
   2826   1.1  riastrad do_inferred_modes(struct detailed_timing *timing, void *c)
   2827   1.1  riastrad {
   2828   1.1  riastrad 	struct detailed_mode_closure *closure = c;
   2829   1.1  riastrad 	struct detailed_non_pixel *data = &timing->data.other_data;
   2830   1.1  riastrad 	struct detailed_data_monitor_range *range = &data->data.range;
   2831   1.1  riastrad 
   2832   1.1  riastrad 	if (data->type != EDID_DETAIL_MONITOR_RANGE)
   2833   1.1  riastrad 		return;
   2834   1.1  riastrad 
   2835   1.1  riastrad 	closure->modes += drm_dmt_modes_for_range(closure->connector,
   2836   1.1  riastrad 						  closure->edid,
   2837   1.1  riastrad 						  timing);
   2838   1.1  riastrad 
   2839   1.1  riastrad 	if (!version_greater(closure->edid, 1, 1))
   2840   1.1  riastrad 		return; /* GTF not defined yet */
   2841   1.1  riastrad 
   2842   1.1  riastrad 	switch (range->flags) {
   2843   1.1  riastrad 	case 0x02: /* secondary gtf, XXX could do more */
   2844   1.1  riastrad 	case 0x00: /* default gtf */
   2845   1.1  riastrad 		closure->modes += drm_gtf_modes_for_range(closure->connector,
   2846   1.1  riastrad 							  closure->edid,
   2847   1.1  riastrad 							  timing);
   2848   1.1  riastrad 		break;
   2849   1.1  riastrad 	case 0x04: /* cvt, only in 1.4+ */
   2850   1.1  riastrad 		if (!version_greater(closure->edid, 1, 3))
   2851   1.1  riastrad 			break;
   2852   1.1  riastrad 
   2853   1.1  riastrad 		closure->modes += drm_cvt_modes_for_range(closure->connector,
   2854   1.1  riastrad 							  closure->edid,
   2855   1.1  riastrad 							  timing);
   2856   1.1  riastrad 		break;
   2857   1.1  riastrad 	case 0x01: /* just the ranges, no formula */
   2858   1.1  riastrad 	default:
   2859   1.1  riastrad 		break;
   2860   1.1  riastrad 	}
   2861   1.1  riastrad }
   2862   1.1  riastrad 
   2863   1.1  riastrad static int
   2864   1.1  riastrad add_inferred_modes(struct drm_connector *connector, struct edid *edid)
   2865   1.1  riastrad {
   2866   1.1  riastrad 	struct detailed_mode_closure closure = {
   2867   1.6  riastrad 		.connector = connector,
   2868   1.6  riastrad 		.edid = edid,
   2869   1.1  riastrad 	};
   2870   1.1  riastrad 
   2871   1.1  riastrad 	if (version_greater(edid, 1, 0))
   2872   1.1  riastrad 		drm_for_each_detailed_block((u8 *)edid, do_inferred_modes,
   2873   1.1  riastrad 					    &closure);
   2874   1.1  riastrad 
   2875   1.1  riastrad 	return closure.modes;
   2876   1.1  riastrad }
   2877   1.1  riastrad 
   2878   1.1  riastrad static int
   2879   1.1  riastrad drm_est3_modes(struct drm_connector *connector, struct detailed_timing *timing)
   2880   1.1  riastrad {
   2881   1.1  riastrad 	int i, j, m, modes = 0;
   2882   1.1  riastrad 	struct drm_display_mode *mode;
   2883   1.9  riastrad 	u8 *est = ((u8 *)timing) + 6;
   2884   1.1  riastrad 
   2885   1.1  riastrad 	for (i = 0; i < 6; i++) {
   2886   1.3  riastrad 		for (j = 7; j >= 0; j--) {
   2887   1.1  riastrad 			m = (i * 8) + (7 - j);
   2888   1.1  riastrad 			if (m >= ARRAY_SIZE(est3_modes))
   2889   1.1  riastrad 				break;
   2890   1.1  riastrad 			if (est[i] & (1 << j)) {
   2891   1.1  riastrad 				mode = drm_mode_find_dmt(connector->dev,
   2892   1.1  riastrad 							 est3_modes[m].w,
   2893   1.1  riastrad 							 est3_modes[m].h,
   2894   1.1  riastrad 							 est3_modes[m].r,
   2895   1.1  riastrad 							 est3_modes[m].rb);
   2896   1.1  riastrad 				if (mode) {
   2897   1.1  riastrad 					drm_mode_probed_add(connector, mode);
   2898   1.1  riastrad 					modes++;
   2899   1.1  riastrad 				}
   2900   1.1  riastrad 			}
   2901   1.1  riastrad 		}
   2902   1.1  riastrad 	}
   2903   1.1  riastrad 
   2904   1.1  riastrad 	return modes;
   2905   1.1  riastrad }
   2906   1.1  riastrad 
   2907   1.1  riastrad static void
   2908   1.1  riastrad do_established_modes(struct detailed_timing *timing, void *c)
   2909   1.1  riastrad {
   2910   1.1  riastrad 	struct detailed_mode_closure *closure = c;
   2911   1.1  riastrad 	struct detailed_non_pixel *data = &timing->data.other_data;
   2912   1.1  riastrad 
   2913   1.1  riastrad 	if (data->type == EDID_DETAIL_EST_TIMINGS)
   2914   1.1  riastrad 		closure->modes += drm_est3_modes(closure->connector, timing);
   2915   1.1  riastrad }
   2916   1.1  riastrad 
   2917   1.1  riastrad /**
   2918   1.1  riastrad  * add_established_modes - get est. modes from EDID and add them
   2919   1.6  riastrad  * @connector: connector to add mode(s) to
   2920   1.1  riastrad  * @edid: EDID block to scan
   2921   1.1  riastrad  *
   2922   1.1  riastrad  * Each EDID block contains a bitmap of the supported "established modes" list
   2923   1.1  riastrad  * (defined above).  Tease them out and add them to the global modes list.
   2924   1.1  riastrad  */
   2925   1.1  riastrad static int
   2926   1.1  riastrad add_established_modes(struct drm_connector *connector, struct edid *edid)
   2927   1.1  riastrad {
   2928   1.1  riastrad 	struct drm_device *dev = connector->dev;
   2929   1.1  riastrad 	unsigned long est_bits = edid->established_timings.t1 |
   2930   1.1  riastrad 		(edid->established_timings.t2 << 8) |
   2931   1.1  riastrad 		((edid->established_timings.mfg_rsvd & 0x80) << 9);
   2932   1.1  riastrad 	int i, modes = 0;
   2933   1.1  riastrad 	struct detailed_mode_closure closure = {
   2934   1.6  riastrad 		.connector = connector,
   2935   1.6  riastrad 		.edid = edid,
   2936   1.1  riastrad 	};
   2937   1.1  riastrad 
   2938   1.1  riastrad 	for (i = 0; i <= EDID_EST_TIMINGS; i++) {
   2939   1.1  riastrad 		if (est_bits & (1<<i)) {
   2940   1.1  riastrad 			struct drm_display_mode *newmode;
   2941   1.1  riastrad 			newmode = drm_mode_duplicate(dev, &edid_est_modes[i]);
   2942   1.1  riastrad 			if (newmode) {
   2943   1.1  riastrad 				drm_mode_probed_add(connector, newmode);
   2944   1.1  riastrad 				modes++;
   2945   1.1  riastrad 			}
   2946   1.1  riastrad 		}
   2947   1.1  riastrad 	}
   2948   1.1  riastrad 
   2949   1.1  riastrad 	if (version_greater(edid, 1, 0))
   2950   1.1  riastrad 		    drm_for_each_detailed_block((u8 *)edid,
   2951   1.1  riastrad 						do_established_modes, &closure);
   2952   1.1  riastrad 
   2953   1.1  riastrad 	return modes + closure.modes;
   2954   1.1  riastrad }
   2955   1.1  riastrad 
   2956   1.1  riastrad static void
   2957   1.1  riastrad do_standard_modes(struct detailed_timing *timing, void *c)
   2958   1.1  riastrad {
   2959   1.1  riastrad 	struct detailed_mode_closure *closure = c;
   2960   1.1  riastrad 	struct detailed_non_pixel *data = &timing->data.other_data;
   2961   1.1  riastrad 	struct drm_connector *connector = closure->connector;
   2962   1.1  riastrad 	struct edid *edid = closure->edid;
   2963   1.1  riastrad 
   2964   1.1  riastrad 	if (data->type == EDID_DETAIL_STD_MODES) {
   2965   1.1  riastrad 		int i;
   2966   1.1  riastrad 		for (i = 0; i < 6; i++) {
   2967   1.1  riastrad 			struct std_timing *std;
   2968   1.1  riastrad 			struct drm_display_mode *newmode;
   2969   1.1  riastrad 
   2970   1.1  riastrad 			std = &data->data.timings[i];
   2971   1.6  riastrad 			newmode = drm_mode_std(connector, edid, std);
   2972   1.1  riastrad 			if (newmode) {
   2973   1.1  riastrad 				drm_mode_probed_add(connector, newmode);
   2974   1.1  riastrad 				closure->modes++;
   2975   1.1  riastrad 			}
   2976   1.1  riastrad 		}
   2977   1.1  riastrad 	}
   2978   1.1  riastrad }
   2979   1.1  riastrad 
   2980   1.1  riastrad /**
   2981   1.1  riastrad  * add_standard_modes - get std. modes from EDID and add them
   2982   1.6  riastrad  * @connector: connector to add mode(s) to
   2983   1.1  riastrad  * @edid: EDID block to scan
   2984   1.1  riastrad  *
   2985   1.1  riastrad  * Standard modes can be calculated using the appropriate standard (DMT,
   2986   1.1  riastrad  * GTF or CVT. Grab them from @edid and add them to the list.
   2987   1.1  riastrad  */
   2988   1.1  riastrad static int
   2989   1.1  riastrad add_standard_modes(struct drm_connector *connector, struct edid *edid)
   2990   1.1  riastrad {
   2991   1.1  riastrad 	int i, modes = 0;
   2992   1.1  riastrad 	struct detailed_mode_closure closure = {
   2993   1.6  riastrad 		.connector = connector,
   2994   1.6  riastrad 		.edid = edid,
   2995   1.1  riastrad 	};
   2996   1.1  riastrad 
   2997   1.1  riastrad 	for (i = 0; i < EDID_STD_TIMINGS; i++) {
   2998   1.1  riastrad 		struct drm_display_mode *newmode;
   2999   1.1  riastrad 
   3000   1.1  riastrad 		newmode = drm_mode_std(connector, edid,
   3001   1.6  riastrad 				       &edid->standard_timings[i]);
   3002   1.1  riastrad 		if (newmode) {
   3003   1.1  riastrad 			drm_mode_probed_add(connector, newmode);
   3004   1.1  riastrad 			modes++;
   3005   1.1  riastrad 		}
   3006   1.1  riastrad 	}
   3007   1.1  riastrad 
   3008   1.1  riastrad 	if (version_greater(edid, 1, 0))
   3009   1.1  riastrad 		drm_for_each_detailed_block((u8 *)edid, do_standard_modes,
   3010   1.1  riastrad 					    &closure);
   3011   1.1  riastrad 
   3012   1.1  riastrad 	/* XXX should also look for standard codes in VTB blocks */
   3013   1.1  riastrad 
   3014   1.1  riastrad 	return modes + closure.modes;
   3015   1.1  riastrad }
   3016   1.1  riastrad 
   3017   1.1  riastrad static int drm_cvt_modes(struct drm_connector *connector,
   3018   1.1  riastrad 			 struct detailed_timing *timing)
   3019   1.1  riastrad {
   3020   1.1  riastrad 	int i, j, modes = 0;
   3021   1.1  riastrad 	struct drm_display_mode *newmode;
   3022   1.1  riastrad 	struct drm_device *dev = connector->dev;
   3023   1.1  riastrad 	struct cvt_timing *cvt;
   3024   1.1  riastrad 	const int rates[] = { 60, 85, 75, 60, 50 };
   3025   1.1  riastrad 	const u8 empty[3] = { 0, 0, 0 };
   3026   1.1  riastrad 
   3027   1.1  riastrad 	for (i = 0; i < 4; i++) {
   3028   1.1  riastrad 		int uninitialized_var(width), height;
   3029   1.1  riastrad 		cvt = &(timing->data.other_data.data.cvt[i]);
   3030   1.1  riastrad 
   3031   1.1  riastrad 		if (!memcmp(cvt->code, empty, 3))
   3032   1.1  riastrad 			continue;
   3033   1.1  riastrad 
   3034   1.1  riastrad 		height = (cvt->code[0] + ((cvt->code[1] & 0xf0) << 4) + 1) * 2;
   3035   1.1  riastrad 		switch (cvt->code[1] & 0x0c) {
   3036   1.1  riastrad 		case 0x00:
   3037   1.1  riastrad 			width = height * 4 / 3;
   3038   1.1  riastrad 			break;
   3039   1.1  riastrad 		case 0x04:
   3040   1.1  riastrad 			width = height * 16 / 9;
   3041   1.1  riastrad 			break;
   3042   1.1  riastrad 		case 0x08:
   3043   1.1  riastrad 			width = height * 16 / 10;
   3044   1.1  riastrad 			break;
   3045   1.1  riastrad 		case 0x0c:
   3046   1.1  riastrad 			width = height * 15 / 9;
   3047   1.1  riastrad 			break;
   3048   1.1  riastrad 		}
   3049   1.1  riastrad 
   3050   1.1  riastrad 		for (j = 1; j < 5; j++) {
   3051   1.1  riastrad 			if (cvt->code[2] & (1 << j)) {
   3052   1.1  riastrad 				newmode = drm_cvt_mode(dev, width, height,
   3053   1.1  riastrad 						       rates[j], j == 0,
   3054   1.1  riastrad 						       false, false);
   3055   1.1  riastrad 				if (newmode) {
   3056   1.1  riastrad 					drm_mode_probed_add(connector, newmode);
   3057   1.1  riastrad 					modes++;
   3058   1.1  riastrad 				}
   3059   1.1  riastrad 			}
   3060   1.1  riastrad 		}
   3061   1.1  riastrad 	}
   3062   1.1  riastrad 
   3063   1.1  riastrad 	return modes;
   3064   1.1  riastrad }
   3065   1.1  riastrad 
   3066   1.1  riastrad static void
   3067   1.1  riastrad do_cvt_mode(struct detailed_timing *timing, void *c)
   3068   1.1  riastrad {
   3069   1.1  riastrad 	struct detailed_mode_closure *closure = c;
   3070   1.1  riastrad 	struct detailed_non_pixel *data = &timing->data.other_data;
   3071   1.1  riastrad 
   3072   1.1  riastrad 	if (data->type == EDID_DETAIL_CVT_3BYTE)
   3073   1.1  riastrad 		closure->modes += drm_cvt_modes(closure->connector, timing);
   3074   1.1  riastrad }
   3075   1.1  riastrad 
   3076   1.1  riastrad static int
   3077   1.1  riastrad add_cvt_modes(struct drm_connector *connector, struct edid *edid)
   3078   1.1  riastrad {
   3079   1.1  riastrad 	struct detailed_mode_closure closure = {
   3080   1.6  riastrad 		.connector = connector,
   3081   1.6  riastrad 		.edid = edid,
   3082   1.1  riastrad 	};
   3083   1.1  riastrad 
   3084   1.1  riastrad 	if (version_greater(edid, 1, 2))
   3085   1.1  riastrad 		drm_for_each_detailed_block((u8 *)edid, do_cvt_mode, &closure);
   3086   1.1  riastrad 
   3087   1.1  riastrad 	/* XXX should also look for CVT codes in VTB blocks */
   3088   1.1  riastrad 
   3089   1.1  riastrad 	return closure.modes;
   3090   1.1  riastrad }
   3091   1.1  riastrad 
   3092   1.6  riastrad static void fixup_detailed_cea_mode_clock(struct drm_display_mode *mode);
   3093   1.6  riastrad 
   3094   1.1  riastrad static void
   3095   1.1  riastrad do_detailed_mode(struct detailed_timing *timing, void *c)
   3096   1.1  riastrad {
   3097   1.1  riastrad 	struct detailed_mode_closure *closure = c;
   3098   1.1  riastrad 	struct drm_display_mode *newmode;
   3099   1.1  riastrad 
   3100   1.1  riastrad 	if (timing->pixel_clock) {
   3101   1.1  riastrad 		newmode = drm_mode_detailed(closure->connector->dev,
   3102   1.1  riastrad 					    closure->edid, timing,
   3103   1.1  riastrad 					    closure->quirks);
   3104   1.1  riastrad 		if (!newmode)
   3105   1.1  riastrad 			return;
   3106   1.1  riastrad 
   3107   1.1  riastrad 		if (closure->preferred)
   3108   1.1  riastrad 			newmode->type |= DRM_MODE_TYPE_PREFERRED;
   3109   1.1  riastrad 
   3110   1.6  riastrad 		/*
   3111   1.6  riastrad 		 * Detailed modes are limited to 10kHz pixel clock resolution,
   3112   1.6  riastrad 		 * so fix up anything that looks like CEA/HDMI mode, but the clock
   3113   1.6  riastrad 		 * is just slightly off.
   3114   1.6  riastrad 		 */
   3115   1.6  riastrad 		fixup_detailed_cea_mode_clock(newmode);
   3116   1.6  riastrad 
   3117   1.1  riastrad 		drm_mode_probed_add(closure->connector, newmode);
   3118   1.1  riastrad 		closure->modes++;
   3119   1.9  riastrad 		closure->preferred = false;
   3120   1.1  riastrad 	}
   3121   1.1  riastrad }
   3122   1.1  riastrad 
   3123   1.1  riastrad /*
   3124   1.1  riastrad  * add_detailed_modes - Add modes from detailed timings
   3125   1.1  riastrad  * @connector: attached connector
   3126   1.1  riastrad  * @edid: EDID block to scan
   3127   1.1  riastrad  * @quirks: quirks to apply
   3128   1.1  riastrad  */
   3129   1.1  riastrad static int
   3130   1.1  riastrad add_detailed_modes(struct drm_connector *connector, struct edid *edid,
   3131   1.1  riastrad 		   u32 quirks)
   3132   1.1  riastrad {
   3133   1.1  riastrad 	struct detailed_mode_closure closure = {
   3134   1.6  riastrad 		.connector = connector,
   3135   1.6  riastrad 		.edid = edid,
   3136   1.9  riastrad 		.preferred = true,
   3137   1.6  riastrad 		.quirks = quirks,
   3138   1.1  riastrad 	};
   3139   1.1  riastrad 
   3140   1.1  riastrad 	if (closure.preferred && !version_greater(edid, 1, 3))
   3141   1.1  riastrad 		closure.preferred =
   3142   1.1  riastrad 		    (edid->features & DRM_EDID_FEATURE_PREFERRED_TIMING);
   3143   1.1  riastrad 
   3144   1.1  riastrad 	drm_for_each_detailed_block((u8 *)edid, do_detailed_mode, &closure);
   3145   1.1  riastrad 
   3146   1.1  riastrad 	return closure.modes;
   3147   1.1  riastrad }
   3148   1.1  riastrad 
   3149   1.1  riastrad #define AUDIO_BLOCK	0x01
   3150   1.1  riastrad #define VIDEO_BLOCK     0x02
   3151   1.1  riastrad #define VENDOR_BLOCK    0x03
   3152   1.1  riastrad #define SPEAKER_BLOCK	0x04
   3153   1.9  riastrad #define HDR_STATIC_METADATA_BLOCK	0x6
   3154   1.9  riastrad #define USE_EXTENDED_TAG 0x07
   3155   1.9  riastrad #define EXT_VIDEO_CAPABILITY_BLOCK 0x00
   3156   1.9  riastrad #define EXT_VIDEO_DATA_BLOCK_420	0x0E
   3157   1.9  riastrad #define EXT_VIDEO_CAP_BLOCK_Y420CMDB 0x0F
   3158   1.1  riastrad #define EDID_BASIC_AUDIO	(1 << 6)
   3159   1.1  riastrad #define EDID_CEA_YCRCB444	(1 << 5)
   3160   1.1  riastrad #define EDID_CEA_YCRCB422	(1 << 4)
   3161   1.3  riastrad #define EDID_CEA_VCDB_QS	(1 << 6)
   3162   1.1  riastrad 
   3163   1.3  riastrad /*
   3164   1.1  riastrad  * Search EDID for CEA extension block.
   3165   1.1  riastrad  */
   3166  1.13  riastrad static const u8 *drm_find_edid_extension(const struct edid *edid, int ext_id)
   3167   1.1  riastrad {
   3168  1.12  riastrad 	const u8 *edid_ext = NULL;
   3169   1.1  riastrad 	int i;
   3170   1.1  riastrad 
   3171   1.1  riastrad 	/* No EDID or EDID extensions */
   3172   1.1  riastrad 	if (edid == NULL || edid->extensions == 0)
   3173   1.1  riastrad 		return NULL;
   3174   1.1  riastrad 
   3175   1.1  riastrad 	/* Find CEA extension */
   3176   1.1  riastrad 	for (i = 0; i < edid->extensions; i++) {
   3177  1.10  riastrad 		edid_ext = (const u8 *)edid + EDID_LENGTH * (i + 1);
   3178   1.6  riastrad 		if (edid_ext[0] == ext_id)
   3179   1.1  riastrad 			break;
   3180   1.1  riastrad 	}
   3181   1.1  riastrad 
   3182   1.1  riastrad 	if (i == edid->extensions)
   3183   1.1  riastrad 		return NULL;
   3184   1.1  riastrad 
   3185   1.1  riastrad 	return edid_ext;
   3186   1.1  riastrad }
   3187   1.1  riastrad 
   3188   1.6  riastrad 
   3189  1.14  riastrad static const u8 *drm_find_displayid_extension(const struct edid *edid)
   3190   1.6  riastrad {
   3191   1.6  riastrad 	return drm_find_edid_extension(edid, DISPLAYID_EXT);
   3192   1.6  riastrad }
   3193   1.6  riastrad 
   3194  1.13  riastrad static const u8 *drm_find_cea_extension(const struct edid *edid)
   3195   1.3  riastrad {
   3196   1.9  riastrad 	int ret;
   3197   1.9  riastrad 	int idx = 1;
   3198   1.9  riastrad 	int length = EDID_LENGTH;
   3199  1.14  riastrad 	const struct displayid_block *block;
   3200  1.14  riastrad 	const u8 *cea;
   3201  1.14  riastrad 	const u8 *displayid;
   3202   1.3  riastrad 
   3203   1.9  riastrad 	/* Look for a top level CEA extension block */
   3204   1.9  riastrad 	cea = drm_find_edid_extension(edid, CEA_EXT);
   3205   1.9  riastrad 	if (cea)
   3206   1.9  riastrad 		return cea;
   3207   1.9  riastrad 
   3208   1.9  riastrad 	/* CEA blocks can also be found embedded in a DisplayID block */
   3209   1.9  riastrad 	displayid = drm_find_displayid_extension(edid);
   3210   1.9  riastrad 	if (!displayid)
   3211   1.9  riastrad 		return NULL;
   3212   1.9  riastrad 
   3213   1.9  riastrad 	ret = validate_displayid(displayid, length, idx);
   3214   1.9  riastrad 	if (ret)
   3215   1.9  riastrad 		return NULL;
   3216   1.9  riastrad 
   3217   1.9  riastrad 	idx += sizeof(struct displayid_hdr);
   3218   1.9  riastrad 	for_each_displayid_db(displayid, block, idx, length) {
   3219   1.9  riastrad 		if (block->tag == DATA_BLOCK_CTA) {
   3220  1.14  riastrad 			cea = (const u8 *)block;
   3221   1.9  riastrad 			break;
   3222   1.9  riastrad 		}
   3223   1.9  riastrad 	}
   3224   1.9  riastrad 
   3225   1.9  riastrad 	return cea;
   3226   1.9  riastrad }
   3227   1.9  riastrad 
   3228   1.9  riastrad static __always_inline const struct drm_display_mode *cea_mode_for_vic(u8 vic)
   3229   1.9  riastrad {
   3230   1.9  riastrad 	BUILD_BUG_ON(1 + ARRAY_SIZE(edid_cea_modes_1) - 1 != 127);
   3231   1.9  riastrad 	BUILD_BUG_ON(193 + ARRAY_SIZE(edid_cea_modes_193) - 1 != 219);
   3232   1.9  riastrad 
   3233   1.9  riastrad 	if (vic >= 1 && vic < 1 + ARRAY_SIZE(edid_cea_modes_1))
   3234   1.9  riastrad 		return &edid_cea_modes_1[vic - 1];
   3235   1.9  riastrad 	if (vic >= 193 && vic < 193 + ARRAY_SIZE(edid_cea_modes_193))
   3236   1.9  riastrad 		return &edid_cea_modes_193[vic - 193];
   3237   1.9  riastrad 	return NULL;
   3238   1.9  riastrad }
   3239   1.9  riastrad 
   3240   1.9  riastrad static u8 cea_num_vics(void)
   3241   1.9  riastrad {
   3242   1.9  riastrad 	return 193 + ARRAY_SIZE(edid_cea_modes_193);
   3243   1.9  riastrad }
   3244   1.9  riastrad 
   3245   1.9  riastrad static u8 cea_next_vic(u8 vic)
   3246   1.9  riastrad {
   3247   1.9  riastrad 	if (++vic == 1 + ARRAY_SIZE(edid_cea_modes_1))
   3248   1.9  riastrad 		vic = 193;
   3249   1.9  riastrad 	return vic;
   3250   1.9  riastrad }
   3251   1.9  riastrad 
   3252   1.9  riastrad /*
   3253   1.9  riastrad  * Calculate the alternate clock for the CEA mode
   3254   1.9  riastrad  * (60Hz vs. 59.94Hz etc.)
   3255   1.9  riastrad  */
   3256   1.9  riastrad static unsigned int
   3257   1.9  riastrad cea_mode_alternate_clock(const struct drm_display_mode *cea_mode)
   3258   1.9  riastrad {
   3259   1.9  riastrad 	unsigned int clock = cea_mode->clock;
   3260   1.9  riastrad 
   3261   1.9  riastrad 	if (cea_mode->vrefresh % 6 != 0)
   3262   1.9  riastrad 		return clock;
   3263   1.3  riastrad 
   3264   1.3  riastrad 	/*
   3265   1.3  riastrad 	 * edid_cea_modes contains the 59.94Hz
   3266   1.3  riastrad 	 * variant for 240 and 480 line modes,
   3267   1.3  riastrad 	 * and the 60Hz variant otherwise.
   3268   1.3  riastrad 	 */
   3269   1.3  riastrad 	if (cea_mode->vdisplay == 240 || cea_mode->vdisplay == 480)
   3270   1.6  riastrad 		clock = DIV_ROUND_CLOSEST(clock * 1001, 1000);
   3271   1.3  riastrad 	else
   3272   1.6  riastrad 		clock = DIV_ROUND_CLOSEST(clock * 1000, 1001);
   3273   1.3  riastrad 
   3274   1.3  riastrad 	return clock;
   3275   1.3  riastrad }
   3276   1.3  riastrad 
   3277   1.9  riastrad static bool
   3278   1.9  riastrad cea_mode_alternate_timings(u8 vic, struct drm_display_mode *mode)
   3279   1.9  riastrad {
   3280   1.9  riastrad 	/*
   3281   1.9  riastrad 	 * For certain VICs the spec allows the vertical
   3282   1.9  riastrad 	 * front porch to vary by one or two lines.
   3283   1.9  riastrad 	 *
   3284   1.9  riastrad 	 * cea_modes[] stores the variant with the shortest
   3285   1.9  riastrad 	 * vertical front porch. We can adjust the mode to
   3286   1.9  riastrad 	 * get the other variants by simply increasing the
   3287   1.9  riastrad 	 * vertical front porch length.
   3288   1.9  riastrad 	 */
   3289   1.9  riastrad 	BUILD_BUG_ON(cea_mode_for_vic(8)->vtotal != 262 ||
   3290   1.9  riastrad 		     cea_mode_for_vic(9)->vtotal != 262 ||
   3291   1.9  riastrad 		     cea_mode_for_vic(12)->vtotal != 262 ||
   3292   1.9  riastrad 		     cea_mode_for_vic(13)->vtotal != 262 ||
   3293   1.9  riastrad 		     cea_mode_for_vic(23)->vtotal != 312 ||
   3294   1.9  riastrad 		     cea_mode_for_vic(24)->vtotal != 312 ||
   3295   1.9  riastrad 		     cea_mode_for_vic(27)->vtotal != 312 ||
   3296   1.9  riastrad 		     cea_mode_for_vic(28)->vtotal != 312);
   3297   1.9  riastrad 
   3298   1.9  riastrad 	if (((vic == 8 || vic == 9 ||
   3299   1.9  riastrad 	      vic == 12 || vic == 13) && mode->vtotal < 263) ||
   3300   1.9  riastrad 	    ((vic == 23 || vic == 24 ||
   3301   1.9  riastrad 	      vic == 27 || vic == 28) && mode->vtotal < 314)) {
   3302   1.9  riastrad 		mode->vsync_start++;
   3303   1.9  riastrad 		mode->vsync_end++;
   3304   1.9  riastrad 		mode->vtotal++;
   3305   1.9  riastrad 
   3306   1.9  riastrad 		return true;
   3307   1.9  riastrad 	}
   3308   1.9  riastrad 
   3309   1.9  riastrad 	return false;
   3310   1.9  riastrad }
   3311   1.9  riastrad 
   3312   1.9  riastrad static u8 drm_match_cea_mode_clock_tolerance(const struct drm_display_mode *to_match,
   3313   1.9  riastrad 					     unsigned int clock_tolerance)
   3314   1.9  riastrad {
   3315   1.9  riastrad 	unsigned int match_flags = DRM_MODE_MATCH_TIMINGS | DRM_MODE_MATCH_FLAGS;
   3316   1.9  riastrad 	u8 vic;
   3317   1.9  riastrad 
   3318   1.9  riastrad 	if (!to_match->clock)
   3319   1.9  riastrad 		return 0;
   3320   1.9  riastrad 
   3321   1.9  riastrad 	if (to_match->picture_aspect_ratio)
   3322   1.9  riastrad 		match_flags |= DRM_MODE_MATCH_ASPECT_RATIO;
   3323   1.9  riastrad 
   3324   1.9  riastrad 	for (vic = 1; vic < cea_num_vics(); vic = cea_next_vic(vic)) {
   3325   1.9  riastrad 		struct drm_display_mode cea_mode = *cea_mode_for_vic(vic);
   3326   1.9  riastrad 		unsigned int clock1, clock2;
   3327   1.9  riastrad 
   3328   1.9  riastrad 		/* Check both 60Hz and 59.94Hz */
   3329   1.9  riastrad 		clock1 = cea_mode.clock;
   3330   1.9  riastrad 		clock2 = cea_mode_alternate_clock(&cea_mode);
   3331   1.9  riastrad 
   3332   1.9  riastrad 		if (abs(to_match->clock - clock1) > clock_tolerance &&
   3333   1.9  riastrad 		    abs(to_match->clock - clock2) > clock_tolerance)
   3334   1.9  riastrad 			continue;
   3335   1.9  riastrad 
   3336   1.9  riastrad 		do {
   3337   1.9  riastrad 			if (drm_mode_match(to_match, &cea_mode, match_flags))
   3338   1.9  riastrad 				return vic;
   3339   1.9  riastrad 		} while (cea_mode_alternate_timings(vic, &cea_mode));
   3340   1.9  riastrad 	}
   3341   1.9  riastrad 
   3342   1.9  riastrad 	return 0;
   3343   1.9  riastrad }
   3344   1.9  riastrad 
   3345   1.3  riastrad /**
   3346   1.3  riastrad  * drm_match_cea_mode - look for a CEA mode matching given mode
   3347   1.3  riastrad  * @to_match: display mode
   3348   1.3  riastrad  *
   3349   1.6  riastrad  * Return: The CEA Video ID (VIC) of the mode or 0 if it isn't a CEA-861
   3350   1.3  riastrad  * mode.
   3351   1.1  riastrad  */
   3352   1.3  riastrad u8 drm_match_cea_mode(const struct drm_display_mode *to_match)
   3353   1.1  riastrad {
   3354   1.9  riastrad 	unsigned int match_flags = DRM_MODE_MATCH_TIMINGS | DRM_MODE_MATCH_FLAGS;
   3355   1.9  riastrad 	u8 vic;
   3356   1.1  riastrad 
   3357   1.3  riastrad 	if (!to_match->clock)
   3358   1.3  riastrad 		return 0;
   3359   1.1  riastrad 
   3360   1.9  riastrad 	if (to_match->picture_aspect_ratio)
   3361   1.9  riastrad 		match_flags |= DRM_MODE_MATCH_ASPECT_RATIO;
   3362   1.9  riastrad 
   3363   1.9  riastrad 	for (vic = 1; vic < cea_num_vics(); vic = cea_next_vic(vic)) {
   3364   1.9  riastrad 		struct drm_display_mode cea_mode = *cea_mode_for_vic(vic);
   3365   1.3  riastrad 		unsigned int clock1, clock2;
   3366   1.3  riastrad 
   3367   1.3  riastrad 		/* Check both 60Hz and 59.94Hz */
   3368   1.9  riastrad 		clock1 = cea_mode.clock;
   3369   1.9  riastrad 		clock2 = cea_mode_alternate_clock(&cea_mode);
   3370   1.9  riastrad 
   3371   1.9  riastrad 		if (KHZ2PICOS(to_match->clock) != KHZ2PICOS(clock1) &&
   3372   1.9  riastrad 		    KHZ2PICOS(to_match->clock) != KHZ2PICOS(clock2))
   3373   1.9  riastrad 			continue;
   3374   1.3  riastrad 
   3375   1.9  riastrad 		do {
   3376   1.9  riastrad 			if (drm_mode_match(to_match, &cea_mode, match_flags))
   3377   1.9  riastrad 				return vic;
   3378   1.9  riastrad 		} while (cea_mode_alternate_timings(vic, &cea_mode));
   3379   1.1  riastrad 	}
   3380   1.9  riastrad 
   3381   1.1  riastrad 	return 0;
   3382   1.1  riastrad }
   3383   1.1  riastrad EXPORT_SYMBOL(drm_match_cea_mode);
   3384   1.1  riastrad 
   3385   1.9  riastrad static bool drm_valid_cea_vic(u8 vic)
   3386   1.9  riastrad {
   3387   1.9  riastrad 	return cea_mode_for_vic(vic) != NULL;
   3388   1.9  riastrad }
   3389   1.9  riastrad 
   3390   1.9  riastrad static enum hdmi_picture_aspect drm_get_cea_aspect_ratio(const u8 video_code)
   3391   1.9  riastrad {
   3392   1.9  riastrad 	const struct drm_display_mode *mode = cea_mode_for_vic(video_code);
   3393   1.9  riastrad 
   3394   1.9  riastrad 	if (mode)
   3395   1.9  riastrad 		return mode->picture_aspect_ratio;
   3396   1.9  riastrad 
   3397   1.9  riastrad 	return HDMI_PICTURE_ASPECT_NONE;
   3398   1.9  riastrad }
   3399   1.9  riastrad 
   3400   1.9  riastrad static enum hdmi_picture_aspect drm_get_hdmi_aspect_ratio(const u8 video_code)
   3401   1.6  riastrad {
   3402   1.9  riastrad 	return edid_4k_modes[video_code].picture_aspect_ratio;
   3403   1.6  riastrad }
   3404   1.6  riastrad 
   3405   1.3  riastrad /*
   3406   1.3  riastrad  * Calculate the alternate clock for HDMI modes (those from the HDMI vendor
   3407   1.3  riastrad  * specific block).
   3408   1.3  riastrad  */
   3409   1.3  riastrad static unsigned int
   3410   1.3  riastrad hdmi_mode_alternate_clock(const struct drm_display_mode *hdmi_mode)
   3411   1.3  riastrad {
   3412   1.9  riastrad 	return cea_mode_alternate_clock(hdmi_mode);
   3413   1.9  riastrad }
   3414   1.9  riastrad 
   3415   1.9  riastrad static u8 drm_match_hdmi_mode_clock_tolerance(const struct drm_display_mode *to_match,
   3416   1.9  riastrad 					      unsigned int clock_tolerance)
   3417   1.9  riastrad {
   3418   1.9  riastrad 	unsigned int match_flags = DRM_MODE_MATCH_TIMINGS | DRM_MODE_MATCH_FLAGS;
   3419   1.9  riastrad 	u8 vic;
   3420   1.9  riastrad 
   3421   1.9  riastrad 	if (!to_match->clock)
   3422   1.9  riastrad 		return 0;
   3423   1.9  riastrad 
   3424   1.9  riastrad 	if (to_match->picture_aspect_ratio)
   3425   1.9  riastrad 		match_flags |= DRM_MODE_MATCH_ASPECT_RATIO;
   3426   1.9  riastrad 
   3427   1.9  riastrad 	for (vic = 1; vic < ARRAY_SIZE(edid_4k_modes); vic++) {
   3428   1.9  riastrad 		const struct drm_display_mode *hdmi_mode = &edid_4k_modes[vic];
   3429   1.9  riastrad 		unsigned int clock1, clock2;
   3430   1.9  riastrad 
   3431   1.9  riastrad 		/* Make sure to also match alternate clocks */
   3432   1.9  riastrad 		clock1 = hdmi_mode->clock;
   3433   1.9  riastrad 		clock2 = hdmi_mode_alternate_clock(hdmi_mode);
   3434   1.9  riastrad 
   3435   1.9  riastrad 		if (abs(to_match->clock - clock1) > clock_tolerance &&
   3436   1.9  riastrad 		    abs(to_match->clock - clock2) > clock_tolerance)
   3437   1.9  riastrad 			continue;
   3438   1.9  riastrad 
   3439   1.9  riastrad 		if (drm_mode_match(to_match, hdmi_mode, match_flags))
   3440   1.9  riastrad 			return vic;
   3441   1.9  riastrad 	}
   3442   1.3  riastrad 
   3443   1.9  riastrad 	return 0;
   3444   1.3  riastrad }
   3445   1.3  riastrad 
   3446   1.3  riastrad /*
   3447   1.3  riastrad  * drm_match_hdmi_mode - look for a HDMI mode matching given mode
   3448   1.3  riastrad  * @to_match: display mode
   3449   1.3  riastrad  *
   3450   1.3  riastrad  * An HDMI mode is one defined in the HDMI vendor specific block.
   3451   1.3  riastrad  *
   3452   1.3  riastrad  * Returns the HDMI Video ID (VIC) of the mode or 0 if it isn't one.
   3453   1.3  riastrad  */
   3454   1.3  riastrad static u8 drm_match_hdmi_mode(const struct drm_display_mode *to_match)
   3455   1.3  riastrad {
   3456   1.9  riastrad 	unsigned int match_flags = DRM_MODE_MATCH_TIMINGS | DRM_MODE_MATCH_FLAGS;
   3457   1.9  riastrad 	u8 vic;
   3458   1.3  riastrad 
   3459   1.3  riastrad 	if (!to_match->clock)
   3460   1.3  riastrad 		return 0;
   3461   1.3  riastrad 
   3462   1.9  riastrad 	if (to_match->picture_aspect_ratio)
   3463   1.9  riastrad 		match_flags |= DRM_MODE_MATCH_ASPECT_RATIO;
   3464   1.9  riastrad 
   3465   1.9  riastrad 	for (vic = 1; vic < ARRAY_SIZE(edid_4k_modes); vic++) {
   3466   1.9  riastrad 		const struct drm_display_mode *hdmi_mode = &edid_4k_modes[vic];
   3467   1.3  riastrad 		unsigned int clock1, clock2;
   3468   1.3  riastrad 
   3469   1.3  riastrad 		/* Make sure to also match alternate clocks */
   3470   1.3  riastrad 		clock1 = hdmi_mode->clock;
   3471   1.3  riastrad 		clock2 = hdmi_mode_alternate_clock(hdmi_mode);
   3472   1.3  riastrad 
   3473   1.3  riastrad 		if ((KHZ2PICOS(to_match->clock) == KHZ2PICOS(clock1) ||
   3474   1.3  riastrad 		     KHZ2PICOS(to_match->clock) == KHZ2PICOS(clock2)) &&
   3475   1.9  riastrad 		    drm_mode_match(to_match, hdmi_mode, match_flags))
   3476   1.9  riastrad 			return vic;
   3477   1.3  riastrad 	}
   3478   1.3  riastrad 	return 0;
   3479   1.3  riastrad }
   3480   1.1  riastrad 
   3481   1.9  riastrad static bool drm_valid_hdmi_vic(u8 vic)
   3482   1.9  riastrad {
   3483   1.9  riastrad 	return vic > 0 && vic < ARRAY_SIZE(edid_4k_modes);
   3484   1.9  riastrad }
   3485   1.9  riastrad 
   3486   1.1  riastrad static int
   3487   1.3  riastrad add_alternate_cea_modes(struct drm_connector *connector, struct edid *edid)
   3488   1.1  riastrad {
   3489   1.1  riastrad 	struct drm_device *dev = connector->dev;
   3490   1.3  riastrad 	struct drm_display_mode *mode, *tmp;
   3491   1.7  riastrad 	LIST_HEAD(list);
   3492   1.1  riastrad 	int modes = 0;
   3493   1.1  riastrad 
   3494   1.3  riastrad 	/* Don't add CEA modes if the CEA extension block is missing */
   3495   1.3  riastrad 	if (!drm_find_cea_extension(edid))
   3496   1.3  riastrad 		return 0;
   3497   1.3  riastrad 
   3498   1.3  riastrad 	/*
   3499   1.3  riastrad 	 * Go through all probed modes and create a new mode
   3500   1.3  riastrad 	 * with the alternate clock for certain CEA modes.
   3501   1.3  riastrad 	 */
   3502   1.3  riastrad 	list_for_each_entry(mode, &connector->probed_modes, head) {
   3503   1.3  riastrad 		const struct drm_display_mode *cea_mode = NULL;
   3504   1.3  riastrad 		struct drm_display_mode *newmode;
   3505   1.9  riastrad 		u8 vic = drm_match_cea_mode(mode);
   3506   1.3  riastrad 		unsigned int clock1, clock2;
   3507   1.3  riastrad 
   3508   1.9  riastrad 		if (drm_valid_cea_vic(vic)) {
   3509   1.9  riastrad 			cea_mode = cea_mode_for_vic(vic);
   3510   1.3  riastrad 			clock2 = cea_mode_alternate_clock(cea_mode);
   3511   1.3  riastrad 		} else {
   3512   1.9  riastrad 			vic = drm_match_hdmi_mode(mode);
   3513   1.9  riastrad 			if (drm_valid_hdmi_vic(vic)) {
   3514   1.9  riastrad 				cea_mode = &edid_4k_modes[vic];
   3515   1.3  riastrad 				clock2 = hdmi_mode_alternate_clock(cea_mode);
   3516   1.3  riastrad 			}
   3517   1.3  riastrad 		}
   3518   1.3  riastrad 
   3519   1.3  riastrad 		if (!cea_mode)
   3520   1.3  riastrad 			continue;
   3521   1.3  riastrad 
   3522   1.3  riastrad 		clock1 = cea_mode->clock;
   3523   1.3  riastrad 
   3524   1.3  riastrad 		if (clock1 == clock2)
   3525   1.3  riastrad 			continue;
   3526   1.3  riastrad 
   3527   1.3  riastrad 		if (mode->clock != clock1 && mode->clock != clock2)
   3528   1.3  riastrad 			continue;
   3529   1.3  riastrad 
   3530   1.3  riastrad 		newmode = drm_mode_duplicate(dev, cea_mode);
   3531   1.3  riastrad 		if (!newmode)
   3532   1.3  riastrad 			continue;
   3533   1.3  riastrad 
   3534   1.3  riastrad 		/* Carry over the stereo flags */
   3535   1.3  riastrad 		newmode->flags |= mode->flags & DRM_MODE_FLAG_3D_MASK;
   3536   1.3  riastrad 
   3537   1.3  riastrad 		/*
   3538   1.3  riastrad 		 * The current mode could be either variant. Make
   3539   1.3  riastrad 		 * sure to pick the "other" clock for the new mode.
   3540   1.3  riastrad 		 */
   3541   1.3  riastrad 		if (mode->clock != clock1)
   3542   1.3  riastrad 			newmode->clock = clock1;
   3543   1.3  riastrad 		else
   3544   1.3  riastrad 			newmode->clock = clock2;
   3545   1.3  riastrad 
   3546   1.3  riastrad 		list_add_tail(&newmode->head, &list);
   3547   1.3  riastrad 	}
   3548   1.3  riastrad 
   3549   1.3  riastrad 	list_for_each_entry_safe(mode, tmp, &list, head) {
   3550   1.3  riastrad 		list_del(&mode->head);
   3551   1.3  riastrad 		drm_mode_probed_add(connector, mode);
   3552   1.3  riastrad 		modes++;
   3553   1.3  riastrad 	}
   3554   1.3  riastrad 
   3555   1.3  riastrad 	return modes;
   3556   1.3  riastrad }
   3557   1.3  riastrad 
   3558   1.9  riastrad static u8 svd_to_vic(u8 svd)
   3559   1.9  riastrad {
   3560   1.9  riastrad 	/* 0-6 bit vic, 7th bit native mode indicator */
   3561   1.9  riastrad 	if ((svd >= 1 &&  svd <= 64) || (svd >= 129 && svd <= 192))
   3562   1.9  riastrad 		return svd & 127;
   3563   1.9  riastrad 
   3564   1.9  riastrad 	return svd;
   3565   1.9  riastrad }
   3566   1.9  riastrad 
   3567   1.3  riastrad static struct drm_display_mode *
   3568   1.3  riastrad drm_display_mode_from_vic_index(struct drm_connector *connector,
   3569   1.3  riastrad 				const u8 *video_db, u8 video_len,
   3570   1.3  riastrad 				u8 video_index)
   3571   1.3  riastrad {
   3572   1.3  riastrad 	struct drm_device *dev = connector->dev;
   3573   1.3  riastrad 	struct drm_display_mode *newmode;
   3574   1.9  riastrad 	u8 vic;
   3575   1.3  riastrad 
   3576   1.3  riastrad 	if (video_db == NULL || video_index >= video_len)
   3577   1.3  riastrad 		return NULL;
   3578   1.3  riastrad 
   3579   1.3  riastrad 	/* CEA modes are numbered 1..127 */
   3580   1.9  riastrad 	vic = svd_to_vic(video_db[video_index]);
   3581   1.9  riastrad 	if (!drm_valid_cea_vic(vic))
   3582   1.3  riastrad 		return NULL;
   3583   1.3  riastrad 
   3584   1.9  riastrad 	newmode = drm_mode_duplicate(dev, cea_mode_for_vic(vic));
   3585   1.3  riastrad 	if (!newmode)
   3586   1.3  riastrad 		return NULL;
   3587   1.3  riastrad 
   3588   1.3  riastrad 	newmode->vrefresh = 0;
   3589   1.3  riastrad 
   3590   1.3  riastrad 	return newmode;
   3591   1.3  riastrad }
   3592   1.3  riastrad 
   3593   1.9  riastrad /*
   3594   1.9  riastrad  * do_y420vdb_modes - Parse YCBCR 420 only modes
   3595   1.9  riastrad  * @connector: connector corresponding to the HDMI sink
   3596   1.9  riastrad  * @svds: start of the data block of CEA YCBCR 420 VDB
   3597   1.9  riastrad  * @len: length of the CEA YCBCR 420 VDB
   3598   1.9  riastrad  *
   3599   1.9  riastrad  * Parse the CEA-861-F YCBCR 420 Video Data Block (Y420VDB)
   3600   1.9  riastrad  * which contains modes which can be supported in YCBCR 420
   3601   1.9  riastrad  * output format only.
   3602   1.9  riastrad  */
   3603   1.9  riastrad static int do_y420vdb_modes(struct drm_connector *connector,
   3604   1.9  riastrad 			    const u8 *svds, u8 svds_len)
   3605   1.9  riastrad {
   3606   1.9  riastrad 	int modes = 0, i;
   3607   1.9  riastrad 	struct drm_device *dev = connector->dev;
   3608   1.9  riastrad 	struct drm_display_info *info = &connector->display_info;
   3609   1.9  riastrad 	struct drm_hdmi_info *hdmi = &info->hdmi;
   3610   1.9  riastrad 
   3611   1.9  riastrad 	for (i = 0; i < svds_len; i++) {
   3612   1.9  riastrad 		u8 vic = svd_to_vic(svds[i]);
   3613   1.9  riastrad 		struct drm_display_mode *newmode;
   3614   1.9  riastrad 
   3615   1.9  riastrad 		if (!drm_valid_cea_vic(vic))
   3616   1.9  riastrad 			continue;
   3617   1.9  riastrad 
   3618   1.9  riastrad 		newmode = drm_mode_duplicate(dev, cea_mode_for_vic(vic));
   3619   1.9  riastrad 		if (!newmode)
   3620   1.9  riastrad 			break;
   3621   1.9  riastrad 		bitmap_set(hdmi->y420_vdb_modes, vic, 1);
   3622   1.9  riastrad 		drm_mode_probed_add(connector, newmode);
   3623   1.9  riastrad 		modes++;
   3624   1.9  riastrad 	}
   3625   1.9  riastrad 
   3626   1.9  riastrad 	if (modes > 0)
   3627   1.9  riastrad 		info->color_formats |= DRM_COLOR_FORMAT_YCRCB420;
   3628   1.9  riastrad 	return modes;
   3629   1.9  riastrad }
   3630   1.9  riastrad 
   3631   1.9  riastrad /*
   3632   1.9  riastrad  * drm_add_cmdb_modes - Add a YCBCR 420 mode into bitmap
   3633   1.9  riastrad  * @connector: connector corresponding to the HDMI sink
   3634   1.9  riastrad  * @vic: CEA vic for the video mode to be added in the map
   3635   1.9  riastrad  *
   3636   1.9  riastrad  * Makes an entry for a videomode in the YCBCR 420 bitmap
   3637   1.9  riastrad  */
   3638   1.9  riastrad static void
   3639   1.9  riastrad drm_add_cmdb_modes(struct drm_connector *connector, u8 svd)
   3640   1.9  riastrad {
   3641   1.9  riastrad 	u8 vic = svd_to_vic(svd);
   3642   1.9  riastrad 	struct drm_hdmi_info *hdmi = &connector->display_info.hdmi;
   3643   1.9  riastrad 
   3644   1.9  riastrad 	if (!drm_valid_cea_vic(vic))
   3645   1.9  riastrad 		return;
   3646   1.9  riastrad 
   3647   1.9  riastrad 	bitmap_set(hdmi->y420_cmdb_modes, vic, 1);
   3648   1.9  riastrad }
   3649   1.9  riastrad 
   3650   1.3  riastrad static int
   3651   1.3  riastrad do_cea_modes(struct drm_connector *connector, const u8 *db, u8 len)
   3652   1.3  riastrad {
   3653   1.3  riastrad 	int i, modes = 0;
   3654   1.9  riastrad 	struct drm_hdmi_info *hdmi = &connector->display_info.hdmi;
   3655   1.3  riastrad 
   3656   1.3  riastrad 	for (i = 0; i < len; i++) {
   3657   1.3  riastrad 		struct drm_display_mode *mode;
   3658   1.3  riastrad 		mode = drm_display_mode_from_vic_index(connector, db, len, i);
   3659   1.3  riastrad 		if (mode) {
   3660   1.9  riastrad 			/*
   3661   1.9  riastrad 			 * YCBCR420 capability block contains a bitmap which
   3662   1.9  riastrad 			 * gives the index of CEA modes from CEA VDB, which
   3663   1.9  riastrad 			 * can support YCBCR 420 sampling output also (apart
   3664   1.9  riastrad 			 * from RGB/YCBCR444 etc).
   3665   1.9  riastrad 			 * For example, if the bit 0 in bitmap is set,
   3666   1.9  riastrad 			 * first mode in VDB can support YCBCR420 output too.
   3667   1.9  riastrad 			 * Add YCBCR420 modes only if sink is HDMI 2.0 capable.
   3668   1.9  riastrad 			 */
   3669   1.9  riastrad 			if (i < 64 && hdmi->y420_cmdb_map & (1ULL << i))
   3670   1.9  riastrad 				drm_add_cmdb_modes(connector, db[i]);
   3671   1.9  riastrad 
   3672   1.3  riastrad 			drm_mode_probed_add(connector, mode);
   3673   1.3  riastrad 			modes++;
   3674   1.3  riastrad 		}
   3675   1.3  riastrad 	}
   3676   1.3  riastrad 
   3677   1.3  riastrad 	return modes;
   3678   1.3  riastrad }
   3679   1.3  riastrad 
   3680   1.3  riastrad struct stereo_mandatory_mode {
   3681   1.3  riastrad 	int width, height, vrefresh;
   3682   1.3  riastrad 	unsigned int flags;
   3683   1.3  riastrad };
   3684   1.3  riastrad 
   3685   1.3  riastrad static const struct stereo_mandatory_mode stereo_mandatory_modes[] = {
   3686   1.3  riastrad 	{ 1920, 1080, 24, DRM_MODE_FLAG_3D_TOP_AND_BOTTOM },
   3687   1.3  riastrad 	{ 1920, 1080, 24, DRM_MODE_FLAG_3D_FRAME_PACKING },
   3688   1.3  riastrad 	{ 1920, 1080, 50,
   3689   1.3  riastrad 	  DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_3D_SIDE_BY_SIDE_HALF },
   3690   1.3  riastrad 	{ 1920, 1080, 60,
   3691   1.3  riastrad 	  DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_3D_SIDE_BY_SIDE_HALF },
   3692   1.3  riastrad 	{ 1280, 720,  50, DRM_MODE_FLAG_3D_TOP_AND_BOTTOM },
   3693   1.3  riastrad 	{ 1280, 720,  50, DRM_MODE_FLAG_3D_FRAME_PACKING },
   3694   1.3  riastrad 	{ 1280, 720,  60, DRM_MODE_FLAG_3D_TOP_AND_BOTTOM },
   3695   1.3  riastrad 	{ 1280, 720,  60, DRM_MODE_FLAG_3D_FRAME_PACKING }
   3696   1.3  riastrad };
   3697   1.3  riastrad 
   3698   1.3  riastrad static bool
   3699   1.3  riastrad stereo_match_mandatory(const struct drm_display_mode *mode,
   3700   1.3  riastrad 		       const struct stereo_mandatory_mode *stereo_mode)
   3701   1.3  riastrad {
   3702   1.3  riastrad 	unsigned int interlaced = mode->flags & DRM_MODE_FLAG_INTERLACE;
   3703   1.3  riastrad 
   3704   1.3  riastrad 	return mode->hdisplay == stereo_mode->width &&
   3705   1.3  riastrad 	       mode->vdisplay == stereo_mode->height &&
   3706   1.3  riastrad 	       interlaced == (stereo_mode->flags & DRM_MODE_FLAG_INTERLACE) &&
   3707   1.3  riastrad 	       drm_mode_vrefresh(mode) == stereo_mode->vrefresh;
   3708   1.3  riastrad }
   3709   1.3  riastrad 
   3710   1.3  riastrad static int add_hdmi_mandatory_stereo_modes(struct drm_connector *connector)
   3711   1.3  riastrad {
   3712   1.3  riastrad 	struct drm_device *dev = connector->dev;
   3713   1.3  riastrad 	const struct drm_display_mode *mode;
   3714   1.3  riastrad 	struct list_head stereo_modes;
   3715   1.3  riastrad 	int modes = 0, i;
   3716   1.3  riastrad 
   3717   1.3  riastrad 	INIT_LIST_HEAD(&stereo_modes);
   3718   1.3  riastrad 
   3719   1.3  riastrad 	list_for_each_entry(mode, &connector->probed_modes, head) {
   3720   1.3  riastrad 		for (i = 0; i < ARRAY_SIZE(stereo_mandatory_modes); i++) {
   3721   1.3  riastrad 			const struct stereo_mandatory_mode *mandatory;
   3722   1.3  riastrad 			struct drm_display_mode *new_mode;
   3723   1.3  riastrad 
   3724   1.3  riastrad 			if (!stereo_match_mandatory(mode,
   3725   1.3  riastrad 						    &stereo_mandatory_modes[i]))
   3726   1.3  riastrad 				continue;
   3727   1.3  riastrad 
   3728   1.3  riastrad 			mandatory = &stereo_mandatory_modes[i];
   3729   1.3  riastrad 			new_mode = drm_mode_duplicate(dev, mode);
   3730   1.3  riastrad 			if (!new_mode)
   3731   1.3  riastrad 				continue;
   3732   1.3  riastrad 
   3733   1.3  riastrad 			new_mode->flags |= mandatory->flags;
   3734   1.3  riastrad 			list_add_tail(&new_mode->head, &stereo_modes);
   3735   1.3  riastrad 			modes++;
   3736   1.3  riastrad 		}
   3737   1.3  riastrad 	}
   3738   1.3  riastrad 
   3739   1.3  riastrad 	list_splice_tail(&stereo_modes, &connector->probed_modes);
   3740   1.3  riastrad 
   3741   1.3  riastrad 	return modes;
   3742   1.3  riastrad }
   3743   1.3  riastrad 
   3744   1.3  riastrad static int add_hdmi_mode(struct drm_connector *connector, u8 vic)
   3745   1.3  riastrad {
   3746   1.3  riastrad 	struct drm_device *dev = connector->dev;
   3747   1.3  riastrad 	struct drm_display_mode *newmode;
   3748   1.3  riastrad 
   3749   1.9  riastrad 	if (!drm_valid_hdmi_vic(vic)) {
   3750   1.3  riastrad 		DRM_ERROR("Unknown HDMI VIC: %d\n", vic);
   3751   1.3  riastrad 		return 0;
   3752   1.3  riastrad 	}
   3753   1.3  riastrad 
   3754   1.3  riastrad 	newmode = drm_mode_duplicate(dev, &edid_4k_modes[vic]);
   3755   1.3  riastrad 	if (!newmode)
   3756   1.3  riastrad 		return 0;
   3757   1.3  riastrad 
   3758   1.3  riastrad 	drm_mode_probed_add(connector, newmode);
   3759   1.3  riastrad 
   3760   1.3  riastrad 	return 1;
   3761   1.3  riastrad }
   3762   1.3  riastrad 
   3763   1.3  riastrad static int add_3d_struct_modes(struct drm_connector *connector, u16 structure,
   3764   1.3  riastrad 			       const u8 *video_db, u8 video_len, u8 video_index)
   3765   1.3  riastrad {
   3766   1.3  riastrad 	struct drm_display_mode *newmode;
   3767   1.3  riastrad 	int modes = 0;
   3768   1.3  riastrad 
   3769   1.3  riastrad 	if (structure & (1 << 0)) {
   3770   1.3  riastrad 		newmode = drm_display_mode_from_vic_index(connector, video_db,
   3771   1.3  riastrad 							  video_len,
   3772   1.3  riastrad 							  video_index);
   3773   1.3  riastrad 		if (newmode) {
   3774   1.3  riastrad 			newmode->flags |= DRM_MODE_FLAG_3D_FRAME_PACKING;
   3775   1.3  riastrad 			drm_mode_probed_add(connector, newmode);
   3776   1.3  riastrad 			modes++;
   3777   1.3  riastrad 		}
   3778   1.3  riastrad 	}
   3779   1.3  riastrad 	if (structure & (1 << 6)) {
   3780   1.3  riastrad 		newmode = drm_display_mode_from_vic_index(connector, video_db,
   3781   1.3  riastrad 							  video_len,
   3782   1.3  riastrad 							  video_index);
   3783   1.3  riastrad 		if (newmode) {
   3784   1.3  riastrad 			newmode->flags |= DRM_MODE_FLAG_3D_TOP_AND_BOTTOM;
   3785   1.3  riastrad 			drm_mode_probed_add(connector, newmode);
   3786   1.3  riastrad 			modes++;
   3787   1.3  riastrad 		}
   3788   1.3  riastrad 	}
   3789   1.3  riastrad 	if (structure & (1 << 8)) {
   3790   1.3  riastrad 		newmode = drm_display_mode_from_vic_index(connector, video_db,
   3791   1.3  riastrad 							  video_len,
   3792   1.3  riastrad 							  video_index);
   3793   1.3  riastrad 		if (newmode) {
   3794   1.3  riastrad 			newmode->flags |= DRM_MODE_FLAG_3D_SIDE_BY_SIDE_HALF;
   3795   1.3  riastrad 			drm_mode_probed_add(connector, newmode);
   3796   1.3  riastrad 			modes++;
   3797   1.3  riastrad 		}
   3798   1.3  riastrad 	}
   3799   1.3  riastrad 
   3800   1.3  riastrad 	return modes;
   3801   1.3  riastrad }
   3802   1.3  riastrad 
   3803   1.3  riastrad /*
   3804   1.3  riastrad  * do_hdmi_vsdb_modes - Parse the HDMI Vendor Specific data block
   3805   1.3  riastrad  * @connector: connector corresponding to the HDMI sink
   3806   1.3  riastrad  * @db: start of the CEA vendor specific block
   3807   1.3  riastrad  * @len: length of the CEA block payload, ie. one can access up to db[len]
   3808   1.3  riastrad  *
   3809   1.3  riastrad  * Parses the HDMI VSDB looking for modes to add to @connector. This function
   3810   1.3  riastrad  * also adds the stereo 3d modes when applicable.
   3811   1.3  riastrad  */
   3812   1.3  riastrad static int
   3813   1.3  riastrad do_hdmi_vsdb_modes(struct drm_connector *connector, const u8 *db, u8 len,
   3814   1.3  riastrad 		   const u8 *video_db, u8 video_len)
   3815   1.3  riastrad {
   3816   1.9  riastrad 	struct drm_display_info *info = &connector->display_info;
   3817   1.3  riastrad 	int modes = 0, offset = 0, i, multi_present = 0, multi_len;
   3818   1.3  riastrad 	u8 vic_len, hdmi_3d_len = 0;
   3819   1.3  riastrad 	u16 mask;
   3820   1.3  riastrad 	u16 structure_all;
   3821   1.3  riastrad 
   3822   1.3  riastrad 	if (len < 8)
   3823   1.3  riastrad 		goto out;
   3824   1.3  riastrad 
   3825   1.3  riastrad 	/* no HDMI_Video_Present */
   3826   1.3  riastrad 	if (!(db[8] & (1 << 5)))
   3827   1.3  riastrad 		goto out;
   3828   1.3  riastrad 
   3829   1.3  riastrad 	/* Latency_Fields_Present */
   3830   1.3  riastrad 	if (db[8] & (1 << 7))
   3831   1.3  riastrad 		offset += 2;
   3832   1.3  riastrad 
   3833   1.3  riastrad 	/* I_Latency_Fields_Present */
   3834   1.3  riastrad 	if (db[8] & (1 << 6))
   3835   1.3  riastrad 		offset += 2;
   3836   1.3  riastrad 
   3837   1.3  riastrad 	/* the declared length is not long enough for the 2 first bytes
   3838   1.3  riastrad 	 * of additional video format capabilities */
   3839   1.3  riastrad 	if (len < (8 + offset + 2))
   3840   1.3  riastrad 		goto out;
   3841   1.3  riastrad 
   3842   1.3  riastrad 	/* 3D_Present */
   3843   1.3  riastrad 	offset++;
   3844   1.3  riastrad 	if (db[8 + offset] & (1 << 7)) {
   3845   1.3  riastrad 		modes += add_hdmi_mandatory_stereo_modes(connector);
   3846   1.3  riastrad 
   3847   1.3  riastrad 		/* 3D_Multi_present */
   3848   1.3  riastrad 		multi_present = (db[8 + offset] & 0x60) >> 5;
   3849   1.3  riastrad 	}
   3850   1.3  riastrad 
   3851   1.3  riastrad 	offset++;
   3852   1.3  riastrad 	vic_len = db[8 + offset] >> 5;
   3853   1.3  riastrad 	hdmi_3d_len = db[8 + offset] & 0x1f;
   3854   1.3  riastrad 
   3855   1.3  riastrad 	for (i = 0; i < vic_len && len >= (9 + offset + i); i++) {
   3856   1.3  riastrad 		u8 vic;
   3857   1.3  riastrad 
   3858   1.3  riastrad 		vic = db[9 + offset + i];
   3859   1.3  riastrad 		modes += add_hdmi_mode(connector, vic);
   3860   1.3  riastrad 	}
   3861   1.3  riastrad 	offset += 1 + vic_len;
   3862   1.3  riastrad 
   3863   1.3  riastrad 	if (multi_present == 1)
   3864   1.3  riastrad 		multi_len = 2;
   3865   1.3  riastrad 	else if (multi_present == 2)
   3866   1.3  riastrad 		multi_len = 4;
   3867   1.3  riastrad 	else
   3868   1.3  riastrad 		multi_len = 0;
   3869   1.3  riastrad 
   3870   1.3  riastrad 	if (len < (8 + offset + hdmi_3d_len - 1))
   3871   1.3  riastrad 		goto out;
   3872   1.3  riastrad 
   3873   1.3  riastrad 	if (hdmi_3d_len < multi_len)
   3874   1.3  riastrad 		goto out;
   3875   1.3  riastrad 
   3876   1.3  riastrad 	if (multi_present == 1 || multi_present == 2) {
   3877   1.3  riastrad 		/* 3D_Structure_ALL */
   3878   1.3  riastrad 		structure_all = (db[8 + offset] << 8) | db[9 + offset];
   3879   1.3  riastrad 
   3880   1.3  riastrad 		/* check if 3D_MASK is present */
   3881   1.3  riastrad 		if (multi_present == 2)
   3882   1.3  riastrad 			mask = (db[10 + offset] << 8) | db[11 + offset];
   3883   1.3  riastrad 		else
   3884   1.3  riastrad 			mask = 0xffff;
   3885   1.3  riastrad 
   3886   1.3  riastrad 		for (i = 0; i < 16; i++) {
   3887   1.3  riastrad 			if (mask & (1 << i))
   3888   1.3  riastrad 				modes += add_3d_struct_modes(connector,
   3889   1.3  riastrad 						structure_all,
   3890   1.3  riastrad 						video_db,
   3891   1.3  riastrad 						video_len, i);
   3892   1.3  riastrad 		}
   3893   1.3  riastrad 	}
   3894   1.3  riastrad 
   3895   1.3  riastrad 	offset += multi_len;
   3896   1.3  riastrad 
   3897   1.3  riastrad 	for (i = 0; i < (hdmi_3d_len - multi_len); i++) {
   3898   1.3  riastrad 		int vic_index;
   3899   1.3  riastrad 		struct drm_display_mode *newmode = NULL;
   3900   1.3  riastrad 		unsigned int newflag = 0;
   3901   1.3  riastrad 		bool detail_present;
   3902   1.3  riastrad 
   3903   1.3  riastrad 		detail_present = ((db[8 + offset + i] & 0x0f) > 7);
   3904   1.3  riastrad 
   3905   1.3  riastrad 		if (detail_present && (i + 1 == hdmi_3d_len - multi_len))
   3906   1.3  riastrad 			break;
   3907   1.3  riastrad 
   3908   1.3  riastrad 		/* 2D_VIC_order_X */
   3909   1.3  riastrad 		vic_index = db[8 + offset + i] >> 4;
   3910   1.3  riastrad 
   3911   1.3  riastrad 		/* 3D_Structure_X */
   3912   1.3  riastrad 		switch (db[8 + offset + i] & 0x0f) {
   3913   1.3  riastrad 		case 0:
   3914   1.3  riastrad 			newflag = DRM_MODE_FLAG_3D_FRAME_PACKING;
   3915   1.3  riastrad 			break;
   3916   1.3  riastrad 		case 6:
   3917   1.3  riastrad 			newflag = DRM_MODE_FLAG_3D_TOP_AND_BOTTOM;
   3918   1.3  riastrad 			break;
   3919   1.3  riastrad 		case 8:
   3920   1.3  riastrad 			/* 3D_Detail_X */
   3921   1.3  riastrad 			if ((db[9 + offset + i] >> 4) == 1)
   3922   1.3  riastrad 				newflag = DRM_MODE_FLAG_3D_SIDE_BY_SIDE_HALF;
   3923   1.3  riastrad 			break;
   3924   1.3  riastrad 		}
   3925   1.3  riastrad 
   3926   1.3  riastrad 		if (newflag != 0) {
   3927   1.3  riastrad 			newmode = drm_display_mode_from_vic_index(connector,
   3928   1.3  riastrad 								  video_db,
   3929   1.3  riastrad 								  video_len,
   3930   1.3  riastrad 								  vic_index);
   3931   1.3  riastrad 
   3932   1.1  riastrad 			if (newmode) {
   3933   1.3  riastrad 				newmode->flags |= newflag;
   3934   1.1  riastrad 				drm_mode_probed_add(connector, newmode);
   3935   1.1  riastrad 				modes++;
   3936   1.1  riastrad 			}
   3937   1.1  riastrad 		}
   3938   1.3  riastrad 
   3939   1.3  riastrad 		if (detail_present)
   3940   1.3  riastrad 			i++;
   3941   1.1  riastrad 	}
   3942   1.1  riastrad 
   3943   1.3  riastrad out:
   3944   1.9  riastrad 	if (modes > 0)
   3945   1.9  riastrad 		info->has_hdmi_infoframe = true;
   3946   1.1  riastrad 	return modes;
   3947   1.1  riastrad }
   3948   1.1  riastrad 
   3949   1.1  riastrad static int
   3950   1.1  riastrad cea_db_payload_len(const u8 *db)
   3951   1.1  riastrad {
   3952   1.1  riastrad 	return db[0] & 0x1f;
   3953   1.1  riastrad }
   3954   1.1  riastrad 
   3955   1.1  riastrad static int
   3956   1.9  riastrad cea_db_extended_tag(const u8 *db)
   3957   1.9  riastrad {
   3958   1.9  riastrad 	return db[1];
   3959   1.9  riastrad }
   3960   1.9  riastrad 
   3961   1.9  riastrad static int
   3962   1.1  riastrad cea_db_tag(const u8 *db)
   3963   1.1  riastrad {
   3964   1.1  riastrad 	return db[0] >> 5;
   3965   1.1  riastrad }
   3966   1.1  riastrad 
   3967   1.1  riastrad static int
   3968   1.1  riastrad cea_revision(const u8 *cea)
   3969   1.1  riastrad {
   3970   1.1  riastrad 	return cea[1];
   3971   1.1  riastrad }
   3972   1.1  riastrad 
   3973   1.1  riastrad static int
   3974   1.1  riastrad cea_db_offsets(const u8 *cea, int *start, int *end)
   3975   1.1  riastrad {
   3976   1.9  riastrad 	/* DisplayID CTA extension blocks and top-level CEA EDID
   3977   1.9  riastrad 	 * block header definitions differ in the following bytes:
   3978   1.9  riastrad 	 *   1) Byte 2 of the header specifies length differently,
   3979   1.9  riastrad 	 *   2) Byte 3 is only present in the CEA top level block.
   3980   1.9  riastrad 	 *
   3981   1.9  riastrad 	 * The different definitions for byte 2 follow.
   3982   1.9  riastrad 	 *
   3983   1.9  riastrad 	 * DisplayID CTA extension block defines byte 2 as:
   3984   1.9  riastrad 	 *   Number of payload bytes
   3985   1.9  riastrad 	 *
   3986   1.9  riastrad 	 * CEA EDID block defines byte 2 as:
   3987   1.9  riastrad 	 *   Byte number (decimal) within this block where the 18-byte
   3988   1.9  riastrad 	 *   DTDs begin. If no non-DTD data is present in this extension
   3989   1.9  riastrad 	 *   block, the value should be set to 04h (the byte after next).
   3990   1.9  riastrad 	 *   If set to 00h, there are no DTDs present in this block and
   3991   1.9  riastrad 	 *   no non-DTD data.
   3992   1.9  riastrad 	 */
   3993   1.9  riastrad 	if (cea[0] == DATA_BLOCK_CTA) {
   3994   1.9  riastrad 		*start = 3;
   3995   1.9  riastrad 		*end = *start + cea[2];
   3996   1.9  riastrad 	} else if (cea[0] == CEA_EXT) {
   3997   1.9  riastrad 		/* Data block offset in CEA extension block */
   3998   1.9  riastrad 		*start = 4;
   3999   1.9  riastrad 		*end = cea[2];
   4000   1.9  riastrad 		if (*end == 0)
   4001   1.9  riastrad 			*end = 127;
   4002   1.9  riastrad 		if (*end < 4 || *end > 127)
   4003   1.9  riastrad 			return -ERANGE;
   4004   1.9  riastrad 	} else {
   4005   1.9  riastrad 		return -EOPNOTSUPP;
   4006   1.9  riastrad 	}
   4007   1.9  riastrad 
   4008   1.1  riastrad 	return 0;
   4009   1.1  riastrad }
   4010   1.1  riastrad 
   4011   1.3  riastrad static bool cea_db_is_hdmi_vsdb(const u8 *db)
   4012   1.3  riastrad {
   4013   1.3  riastrad 	int hdmi_id;
   4014   1.3  riastrad 
   4015   1.3  riastrad 	if (cea_db_tag(db) != VENDOR_BLOCK)
   4016   1.3  riastrad 		return false;
   4017   1.3  riastrad 
   4018   1.3  riastrad 	if (cea_db_payload_len(db) < 5)
   4019   1.3  riastrad 		return false;
   4020   1.3  riastrad 
   4021   1.3  riastrad 	hdmi_id = db[1] | (db[2] << 8) | (db[3] << 16);
   4022   1.3  riastrad 
   4023   1.3  riastrad 	return hdmi_id == HDMI_IEEE_OUI;
   4024   1.3  riastrad }
   4025   1.3  riastrad 
   4026   1.9  riastrad static bool cea_db_is_hdmi_forum_vsdb(const u8 *db)
   4027   1.9  riastrad {
   4028   1.9  riastrad 	unsigned int oui;
   4029   1.9  riastrad 
   4030   1.9  riastrad 	if (cea_db_tag(db) != VENDOR_BLOCK)
   4031   1.9  riastrad 		return false;
   4032   1.9  riastrad 
   4033   1.9  riastrad 	if (cea_db_payload_len(db) < 7)
   4034   1.9  riastrad 		return false;
   4035   1.9  riastrad 
   4036   1.9  riastrad 	oui = db[3] << 16 | db[2] << 8 | db[1];
   4037   1.9  riastrad 
   4038   1.9  riastrad 	return oui == HDMI_FORUM_IEEE_OUI;
   4039   1.9  riastrad }
   4040   1.9  riastrad 
   4041   1.9  riastrad static bool cea_db_is_vcdb(const u8 *db)
   4042   1.9  riastrad {
   4043   1.9  riastrad 	if (cea_db_tag(db) != USE_EXTENDED_TAG)
   4044   1.9  riastrad 		return false;
   4045   1.9  riastrad 
   4046   1.9  riastrad 	if (cea_db_payload_len(db) != 2)
   4047   1.9  riastrad 		return false;
   4048   1.9  riastrad 
   4049   1.9  riastrad 	if (cea_db_extended_tag(db) != EXT_VIDEO_CAPABILITY_BLOCK)
   4050   1.9  riastrad 		return false;
   4051   1.9  riastrad 
   4052   1.9  riastrad 	return true;
   4053   1.9  riastrad }
   4054   1.9  riastrad 
   4055   1.9  riastrad static bool cea_db_is_y420cmdb(const u8 *db)
   4056   1.9  riastrad {
   4057   1.9  riastrad 	if (cea_db_tag(db) != USE_EXTENDED_TAG)
   4058   1.9  riastrad 		return false;
   4059   1.9  riastrad 
   4060   1.9  riastrad 	if (!cea_db_payload_len(db))
   4061   1.9  riastrad 		return false;
   4062   1.9  riastrad 
   4063   1.9  riastrad 	if (cea_db_extended_tag(db) != EXT_VIDEO_CAP_BLOCK_Y420CMDB)
   4064   1.9  riastrad 		return false;
   4065   1.9  riastrad 
   4066   1.9  riastrad 	return true;
   4067   1.9  riastrad }
   4068   1.9  riastrad 
   4069   1.9  riastrad static bool cea_db_is_y420vdb(const u8 *db)
   4070   1.9  riastrad {
   4071   1.9  riastrad 	if (cea_db_tag(db) != USE_EXTENDED_TAG)
   4072   1.9  riastrad 		return false;
   4073   1.9  riastrad 
   4074   1.9  riastrad 	if (!cea_db_payload_len(db))
   4075   1.9  riastrad 		return false;
   4076   1.9  riastrad 
   4077   1.9  riastrad 	if (cea_db_extended_tag(db) != EXT_VIDEO_DATA_BLOCK_420)
   4078   1.9  riastrad 		return false;
   4079   1.9  riastrad 
   4080   1.9  riastrad 	return true;
   4081   1.9  riastrad }
   4082   1.9  riastrad 
   4083   1.1  riastrad #define for_each_cea_db(cea, i, start, end) \
   4084   1.1  riastrad 	for ((i) = (start); (i) < (end) && (i) + cea_db_payload_len(&(cea)[(i)]) < (end); (i) += cea_db_payload_len(&(cea)[(i)]) + 1)
   4085   1.1  riastrad 
   4086   1.9  riastrad static void drm_parse_y420cmdb_bitmap(struct drm_connector *connector,
   4087   1.9  riastrad 				      const u8 *db)
   4088   1.9  riastrad {
   4089   1.9  riastrad 	struct drm_display_info *info = &connector->display_info;
   4090   1.9  riastrad 	struct drm_hdmi_info *hdmi = &info->hdmi;
   4091   1.9  riastrad 	u8 map_len = cea_db_payload_len(db) - 1;
   4092   1.9  riastrad 	u8 count;
   4093   1.9  riastrad 	u64 map = 0;
   4094   1.9  riastrad 
   4095   1.9  riastrad 	if (map_len == 0) {
   4096   1.9  riastrad 		/* All CEA modes support ycbcr420 sampling also.*/
   4097   1.9  riastrad 		hdmi->y420_cmdb_map = U64_MAX;
   4098   1.9  riastrad 		info->color_formats |= DRM_COLOR_FORMAT_YCRCB420;
   4099   1.9  riastrad 		return;
   4100   1.9  riastrad 	}
   4101   1.9  riastrad 
   4102   1.9  riastrad 	/*
   4103   1.9  riastrad 	 * This map indicates which of the existing CEA block modes
   4104   1.9  riastrad 	 * from VDB can support YCBCR420 output too. So if bit=0 is
   4105   1.9  riastrad 	 * set, first mode from VDB can support YCBCR420 output too.
   4106   1.9  riastrad 	 * We will parse and keep this map, before parsing VDB itself
   4107   1.9  riastrad 	 * to avoid going through the same block again and again.
   4108   1.9  riastrad 	 *
   4109   1.9  riastrad 	 * Spec is not clear about max possible size of this block.
   4110   1.9  riastrad 	 * Clamping max bitmap block size at 8 bytes. Every byte can
   4111   1.9  riastrad 	 * address 8 CEA modes, in this way this map can address
   4112   1.9  riastrad 	 * 8*8 = first 64 SVDs.
   4113   1.9  riastrad 	 */
   4114   1.9  riastrad 	if (WARN_ON_ONCE(map_len > 8))
   4115   1.9  riastrad 		map_len = 8;
   4116   1.9  riastrad 
   4117   1.9  riastrad 	for (count = 0; count < map_len; count++)
   4118   1.9  riastrad 		map |= (u64)db[2 + count] << (8 * count);
   4119   1.9  riastrad 
   4120   1.9  riastrad 	if (map)
   4121   1.9  riastrad 		info->color_formats |= DRM_COLOR_FORMAT_YCRCB420;
   4122   1.9  riastrad 
   4123   1.9  riastrad 	hdmi->y420_cmdb_map = map;
   4124   1.9  riastrad }
   4125   1.9  riastrad 
   4126   1.1  riastrad static int
   4127   1.1  riastrad add_cea_modes(struct drm_connector *connector, struct edid *edid)
   4128   1.1  riastrad {
   4129   1.3  riastrad 	const u8 *cea = drm_find_cea_extension(edid);
   4130   1.3  riastrad 	const u8 *db, *hdmi = NULL, *video = NULL;
   4131   1.3  riastrad 	u8 dbl, hdmi_len, video_len = 0;
   4132   1.1  riastrad 	int modes = 0;
   4133   1.1  riastrad 
   4134   1.1  riastrad 	if (cea && cea_revision(cea) >= 3) {
   4135   1.1  riastrad 		int i, start, end;
   4136   1.1  riastrad 
   4137   1.1  riastrad 		if (cea_db_offsets(cea, &start, &end))
   4138   1.1  riastrad 			return 0;
   4139   1.1  riastrad 
   4140   1.1  riastrad 		for_each_cea_db(cea, i, start, end) {
   4141   1.1  riastrad 			db = &cea[i];
   4142   1.1  riastrad 			dbl = cea_db_payload_len(db);
   4143   1.1  riastrad 
   4144   1.3  riastrad 			if (cea_db_tag(db) == VIDEO_BLOCK) {
   4145   1.3  riastrad 				video = db + 1;
   4146   1.3  riastrad 				video_len = dbl;
   4147   1.3  riastrad 				modes += do_cea_modes(connector, video, dbl);
   4148   1.9  riastrad 			} else if (cea_db_is_hdmi_vsdb(db)) {
   4149   1.3  riastrad 				hdmi = db;
   4150   1.3  riastrad 				hdmi_len = dbl;
   4151   1.9  riastrad 			} else if (cea_db_is_y420vdb(db)) {
   4152   1.9  riastrad 				const u8 *vdb420 = &db[2];
   4153   1.9  riastrad 
   4154   1.9  riastrad 				/* Add 4:2:0(only) modes present in EDID */
   4155   1.9  riastrad 				modes += do_y420vdb_modes(connector,
   4156   1.9  riastrad 							  vdb420,
   4157   1.9  riastrad 							  dbl - 1);
   4158   1.3  riastrad 			}
   4159   1.1  riastrad 		}
   4160   1.1  riastrad 	}
   4161   1.1  riastrad 
   4162   1.3  riastrad 	/*
   4163   1.3  riastrad 	 * We parse the HDMI VSDB after having added the cea modes as we will
   4164   1.3  riastrad 	 * be patching their flags when the sink supports stereo 3D.
   4165   1.3  riastrad 	 */
   4166   1.3  riastrad 	if (hdmi)
   4167   1.3  riastrad 		modes += do_hdmi_vsdb_modes(connector, hdmi, hdmi_len, video,
   4168   1.3  riastrad 					    video_len);
   4169   1.3  riastrad 
   4170   1.1  riastrad 	return modes;
   4171   1.1  riastrad }
   4172   1.1  riastrad 
   4173   1.6  riastrad static void fixup_detailed_cea_mode_clock(struct drm_display_mode *mode)
   4174   1.6  riastrad {
   4175   1.6  riastrad 	const struct drm_display_mode *cea_mode;
   4176   1.6  riastrad 	int clock1, clock2, clock;
   4177   1.9  riastrad 	u8 vic;
   4178   1.6  riastrad 	const char *type;
   4179   1.6  riastrad 
   4180   1.9  riastrad 	/*
   4181   1.9  riastrad 	 * allow 5kHz clock difference either way to account for
   4182   1.9  riastrad 	 * the 10kHz clock resolution limit of detailed timings.
   4183   1.9  riastrad 	 */
   4184   1.9  riastrad 	vic = drm_match_cea_mode_clock_tolerance(mode, 5);
   4185   1.9  riastrad 	if (drm_valid_cea_vic(vic)) {
   4186   1.6  riastrad 		type = "CEA";
   4187   1.9  riastrad 		cea_mode = cea_mode_for_vic(vic);
   4188   1.6  riastrad 		clock1 = cea_mode->clock;
   4189   1.6  riastrad 		clock2 = cea_mode_alternate_clock(cea_mode);
   4190   1.6  riastrad 	} else {
   4191   1.9  riastrad 		vic = drm_match_hdmi_mode_clock_tolerance(mode, 5);
   4192   1.9  riastrad 		if (drm_valid_hdmi_vic(vic)) {
   4193   1.6  riastrad 			type = "HDMI";
   4194   1.9  riastrad 			cea_mode = &edid_4k_modes[vic];
   4195   1.6  riastrad 			clock1 = cea_mode->clock;
   4196   1.6  riastrad 			clock2 = hdmi_mode_alternate_clock(cea_mode);
   4197   1.6  riastrad 		} else {
   4198   1.6  riastrad 			return;
   4199   1.6  riastrad 		}
   4200   1.6  riastrad 	}
   4201   1.6  riastrad 
   4202   1.6  riastrad 	/* pick whichever is closest */
   4203   1.6  riastrad 	if (abs(mode->clock - clock1) < abs(mode->clock - clock2))
   4204   1.6  riastrad 		clock = clock1;
   4205   1.6  riastrad 	else
   4206   1.6  riastrad 		clock = clock2;
   4207   1.6  riastrad 
   4208   1.6  riastrad 	if (mode->clock == clock)
   4209   1.6  riastrad 		return;
   4210   1.6  riastrad 
   4211   1.6  riastrad 	DRM_DEBUG("detailed mode matches %s VIC %d, adjusting clock %d -> %d\n",
   4212   1.9  riastrad 		  type, vic, mode->clock, clock);
   4213   1.6  riastrad 	mode->clock = clock;
   4214   1.6  riastrad }
   4215   1.6  riastrad 
   4216   1.9  riastrad static bool cea_db_is_hdmi_hdr_metadata_block(const u8 *db)
   4217   1.9  riastrad {
   4218   1.9  riastrad 	if (cea_db_tag(db) != USE_EXTENDED_TAG)
   4219   1.9  riastrad 		return false;
   4220   1.9  riastrad 
   4221   1.9  riastrad 	if (db[1] != HDR_STATIC_METADATA_BLOCK)
   4222   1.9  riastrad 		return false;
   4223   1.9  riastrad 
   4224   1.9  riastrad 	if (cea_db_payload_len(db) < 3)
   4225   1.9  riastrad 		return false;
   4226   1.9  riastrad 
   4227   1.9  riastrad 	return true;
   4228   1.9  riastrad }
   4229   1.9  riastrad 
   4230   1.9  riastrad static uint8_t eotf_supported(const u8 *edid_ext)
   4231   1.9  riastrad {
   4232   1.9  riastrad 	return edid_ext[2] &
   4233   1.9  riastrad 		(BIT(HDMI_EOTF_TRADITIONAL_GAMMA_SDR) |
   4234   1.9  riastrad 		 BIT(HDMI_EOTF_TRADITIONAL_GAMMA_HDR) |
   4235   1.9  riastrad 		 BIT(HDMI_EOTF_SMPTE_ST2084) |
   4236   1.9  riastrad 		 BIT(HDMI_EOTF_BT_2100_HLG));
   4237   1.9  riastrad }
   4238   1.9  riastrad 
   4239   1.9  riastrad static uint8_t hdr_metadata_type(const u8 *edid_ext)
   4240   1.9  riastrad {
   4241   1.9  riastrad 	return edid_ext[3] &
   4242   1.9  riastrad 		BIT(HDMI_STATIC_METADATA_TYPE1);
   4243   1.9  riastrad }
   4244   1.9  riastrad 
   4245   1.9  riastrad static void
   4246   1.9  riastrad drm_parse_hdr_metadata_block(struct drm_connector *connector, const u8 *db)
   4247   1.9  riastrad {
   4248   1.9  riastrad 	u16 len;
   4249   1.9  riastrad 
   4250   1.9  riastrad 	len = cea_db_payload_len(db);
   4251   1.9  riastrad 
   4252   1.9  riastrad 	connector->hdr_sink_metadata.hdmi_type1.eotf =
   4253   1.9  riastrad 						eotf_supported(db);
   4254   1.9  riastrad 	connector->hdr_sink_metadata.hdmi_type1.metadata_type =
   4255   1.9  riastrad 						hdr_metadata_type(db);
   4256   1.9  riastrad 
   4257   1.9  riastrad 	if (len >= 4)
   4258   1.9  riastrad 		connector->hdr_sink_metadata.hdmi_type1.max_cll = db[4];
   4259   1.9  riastrad 	if (len >= 5)
   4260   1.9  riastrad 		connector->hdr_sink_metadata.hdmi_type1.max_fall = db[5];
   4261   1.9  riastrad 	if (len >= 6)
   4262   1.9  riastrad 		connector->hdr_sink_metadata.hdmi_type1.min_cll = db[6];
   4263   1.9  riastrad }
   4264   1.9  riastrad 
   4265   1.1  riastrad static void
   4266   1.9  riastrad drm_parse_hdmi_vsdb_audio(struct drm_connector *connector, const u8 *db)
   4267   1.1  riastrad {
   4268   1.1  riastrad 	u8 len = cea_db_payload_len(db);
   4269   1.1  riastrad 
   4270  1.15  riastrad 	if (len >= 5) {
   4271  1.15  riastrad 		connector->physical_address = (db[4] << 8) | db[5];
   4272  1.15  riastrad 	}
   4273   1.9  riastrad 	if (len >= 6 && (db[6] & (1 << 7)))
   4274   1.9  riastrad 		connector->eld[DRM_ELD_SAD_COUNT_CONN_TYPE] |= DRM_ELD_SUPPORTS_AI;
   4275   1.1  riastrad 	if (len >= 8) {
   4276   1.1  riastrad 		connector->latency_present[0] = db[8] >> 7;
   4277   1.1  riastrad 		connector->latency_present[1] = (db[8] >> 6) & 1;
   4278   1.1  riastrad 	}
   4279   1.1  riastrad 	if (len >= 9)
   4280   1.1  riastrad 		connector->video_latency[0] = db[9];
   4281   1.1  riastrad 	if (len >= 10)
   4282   1.1  riastrad 		connector->audio_latency[0] = db[10];
   4283   1.1  riastrad 	if (len >= 11)
   4284   1.1  riastrad 		connector->video_latency[1] = db[11];
   4285   1.1  riastrad 	if (len >= 12)
   4286   1.1  riastrad 		connector->audio_latency[1] = db[12];
   4287   1.1  riastrad 
   4288   1.9  riastrad 	DRM_DEBUG_KMS("HDMI: latency present %d %d, "
   4289   1.9  riastrad 		      "video latency %d %d, "
   4290   1.9  riastrad 		      "audio latency %d %d\n",
   4291   1.9  riastrad 		      connector->latency_present[0],
   4292   1.9  riastrad 		      connector->latency_present[1],
   4293   1.9  riastrad 		      connector->video_latency[0],
   4294   1.9  riastrad 		      connector->video_latency[1],
   4295   1.9  riastrad 		      connector->audio_latency[0],
   4296   1.9  riastrad 		      connector->audio_latency[1]);
   4297   1.1  riastrad }
   4298   1.1  riastrad 
   4299   1.1  riastrad static void
   4300   1.1  riastrad monitor_name(struct detailed_timing *t, void *data)
   4301   1.1  riastrad {
   4302   1.1  riastrad 	if (t->data.other_data.type == EDID_DETAIL_MONITOR_NAME)
   4303   1.1  riastrad 		*(u8 **)data = t->data.other_data.data.str.str;
   4304   1.1  riastrad }
   4305   1.1  riastrad 
   4306   1.9  riastrad static int get_monitor_name(struct edid *edid, char name[13])
   4307   1.1  riastrad {
   4308   1.9  riastrad 	char *edid_name = NULL;
   4309   1.1  riastrad 	int mnl;
   4310   1.1  riastrad 
   4311   1.9  riastrad 	if (!edid || !name)
   4312   1.9  riastrad 		return 0;
   4313   1.9  riastrad 
   4314   1.9  riastrad 	drm_for_each_detailed_block((u8 *)edid, monitor_name, &edid_name);
   4315   1.9  riastrad 	for (mnl = 0; edid_name && mnl < 13; mnl++) {
   4316   1.9  riastrad 		if (edid_name[mnl] == 0x0a)
   4317   1.9  riastrad 			break;
   4318   1.9  riastrad 
   4319   1.9  riastrad 		name[mnl] = edid_name[mnl];
   4320   1.9  riastrad 	}
   4321   1.9  riastrad 
   4322   1.9  riastrad 	return mnl;
   4323   1.9  riastrad }
   4324   1.9  riastrad 
   4325   1.9  riastrad /**
   4326   1.9  riastrad  * drm_edid_get_monitor_name - fetch the monitor name from the edid
   4327   1.9  riastrad  * @edid: monitor EDID information
   4328   1.9  riastrad  * @name: pointer to a character array to hold the name of the monitor
   4329   1.9  riastrad  * @bufsize: The size of the name buffer (should be at least 14 chars.)
   4330   1.9  riastrad  *
   4331   1.9  riastrad  */
   4332   1.9  riastrad void drm_edid_get_monitor_name(struct edid *edid, char *name, int bufsize)
   4333   1.9  riastrad {
   4334   1.9  riastrad 	int name_length;
   4335   1.9  riastrad 	char buf[13];
   4336   1.9  riastrad 
   4337   1.9  riastrad 	if (bufsize <= 0)
   4338   1.9  riastrad 		return;
   4339   1.9  riastrad 
   4340   1.9  riastrad 	name_length = min(get_monitor_name(edid, buf), bufsize - 1);
   4341   1.9  riastrad 	memcpy(name, buf, name_length);
   4342   1.9  riastrad 	name[name_length] = '\0';
   4343   1.9  riastrad }
   4344   1.9  riastrad EXPORT_SYMBOL(drm_edid_get_monitor_name);
   4345   1.9  riastrad 
   4346   1.9  riastrad static void clear_eld(struct drm_connector *connector)
   4347   1.9  riastrad {
   4348   1.9  riastrad 	memset(connector->eld, 0, sizeof(connector->eld));
   4349   1.9  riastrad 
   4350   1.9  riastrad 	connector->latency_present[0] = false;
   4351   1.9  riastrad 	connector->latency_present[1] = false;
   4352   1.9  riastrad 	connector->video_latency[0] = 0;
   4353   1.9  riastrad 	connector->audio_latency[0] = 0;
   4354   1.9  riastrad 	connector->video_latency[1] = 0;
   4355   1.9  riastrad 	connector->audio_latency[1] = 0;
   4356   1.9  riastrad }
   4357   1.9  riastrad 
   4358   1.9  riastrad /*
   4359   1.9  riastrad  * drm_edid_to_eld - build ELD from EDID
   4360   1.9  riastrad  * @connector: connector corresponding to the HDMI/DP sink
   4361   1.9  riastrad  * @edid: EDID to parse
   4362   1.9  riastrad  *
   4363   1.9  riastrad  * Fill the ELD (EDID-Like Data) buffer for passing to the audio driver. The
   4364   1.9  riastrad  * HDCP and Port_ID ELD fields are left for the graphics driver to fill in.
   4365   1.9  riastrad  */
   4366   1.9  riastrad static void drm_edid_to_eld(struct drm_connector *connector, struct edid *edid)
   4367   1.9  riastrad {
   4368   1.9  riastrad 	uint8_t *eld = connector->eld;
   4369  1.13  riastrad 	const u8 *cea;
   4370  1.13  riastrad 	const u8 *db;
   4371   1.9  riastrad 	int total_sad_count = 0;
   4372   1.9  riastrad 	int mnl;
   4373   1.9  riastrad 	int dbl;
   4374   1.9  riastrad 
   4375   1.9  riastrad 	clear_eld(connector);
   4376   1.9  riastrad 
   4377   1.9  riastrad 	if (!edid)
   4378   1.9  riastrad 		return;
   4379   1.1  riastrad 
   4380   1.1  riastrad 	cea = drm_find_cea_extension(edid);
   4381   1.1  riastrad 	if (!cea) {
   4382   1.1  riastrad 		DRM_DEBUG_KMS("ELD: no CEA Extension found\n");
   4383   1.1  riastrad 		return;
   4384   1.1  riastrad 	}
   4385   1.1  riastrad 
   4386   1.9  riastrad 	mnl = get_monitor_name(edid, &eld[DRM_ELD_MONITOR_NAME_STRING]);
   4387   1.9  riastrad 	DRM_DEBUG_KMS("ELD monitor %s\n", &eld[DRM_ELD_MONITOR_NAME_STRING]);
   4388   1.9  riastrad 
   4389   1.9  riastrad 	eld[DRM_ELD_CEA_EDID_VER_MNL] = cea[1] << DRM_ELD_CEA_EDID_VER_SHIFT;
   4390   1.9  riastrad 	eld[DRM_ELD_CEA_EDID_VER_MNL] |= mnl;
   4391   1.1  riastrad 
   4392   1.9  riastrad 	eld[DRM_ELD_VER] = DRM_ELD_VER_CEA861D;
   4393   1.1  riastrad 
   4394   1.9  riastrad 	eld[DRM_ELD_MANUFACTURER_NAME0] = edid->mfg_id[0];
   4395   1.9  riastrad 	eld[DRM_ELD_MANUFACTURER_NAME1] = edid->mfg_id[1];
   4396   1.9  riastrad 	eld[DRM_ELD_PRODUCT_CODE0] = edid->prod_code[0];
   4397   1.9  riastrad 	eld[DRM_ELD_PRODUCT_CODE1] = edid->prod_code[1];
   4398   1.1  riastrad 
   4399   1.1  riastrad 	if (cea_revision(cea) >= 3) {
   4400   1.1  riastrad 		int i, start, end;
   4401   1.1  riastrad 
   4402   1.1  riastrad 		if (cea_db_offsets(cea, &start, &end)) {
   4403   1.1  riastrad 			start = 0;
   4404   1.1  riastrad 			end = 0;
   4405   1.1  riastrad 		}
   4406   1.1  riastrad 
   4407   1.1  riastrad 		for_each_cea_db(cea, i, start, end) {
   4408   1.1  riastrad 			db = &cea[i];
   4409   1.1  riastrad 			dbl = cea_db_payload_len(db);
   4410   1.1  riastrad 
   4411   1.1  riastrad 			switch (cea_db_tag(db)) {
   4412   1.9  riastrad 				int sad_count;
   4413   1.9  riastrad 
   4414   1.1  riastrad 			case AUDIO_BLOCK:
   4415   1.1  riastrad 				/* Audio Data Block, contains SADs */
   4416   1.9  riastrad 				sad_count = min(dbl / 3, 15 - total_sad_count);
   4417   1.9  riastrad 				if (sad_count >= 1)
   4418   1.9  riastrad 					memcpy(&eld[DRM_ELD_CEA_SAD(mnl, total_sad_count)],
   4419   1.9  riastrad 					       &db[1], sad_count * 3);
   4420   1.9  riastrad 				total_sad_count += sad_count;
   4421   1.1  riastrad 				break;
   4422   1.1  riastrad 			case SPEAKER_BLOCK:
   4423   1.1  riastrad 				/* Speaker Allocation Data Block */
   4424   1.1  riastrad 				if (dbl >= 1)
   4425   1.9  riastrad 					eld[DRM_ELD_SPEAKER] = db[1];
   4426   1.1  riastrad 				break;
   4427   1.1  riastrad 			case VENDOR_BLOCK:
   4428   1.1  riastrad 				/* HDMI Vendor-Specific Data Block */
   4429   1.1  riastrad 				if (cea_db_is_hdmi_vsdb(db))
   4430   1.9  riastrad 					drm_parse_hdmi_vsdb_audio(connector, db);
   4431   1.1  riastrad 				break;
   4432   1.1  riastrad 			default:
   4433   1.1  riastrad 				break;
   4434   1.1  riastrad 			}
   4435   1.1  riastrad 		}
   4436   1.1  riastrad 	}
   4437   1.9  riastrad 	eld[DRM_ELD_SAD_COUNT_CONN_TYPE] |= total_sad_count << DRM_ELD_SAD_COUNT_SHIFT;
   4438   1.1  riastrad 
   4439   1.6  riastrad 	if (connector->connector_type == DRM_MODE_CONNECTOR_DisplayPort ||
   4440   1.6  riastrad 	    connector->connector_type == DRM_MODE_CONNECTOR_eDP)
   4441   1.6  riastrad 		eld[DRM_ELD_SAD_COUNT_CONN_TYPE] |= DRM_ELD_CONN_TYPE_DP;
   4442   1.6  riastrad 	else
   4443   1.6  riastrad 		eld[DRM_ELD_SAD_COUNT_CONN_TYPE] |= DRM_ELD_CONN_TYPE_HDMI;
   4444   1.6  riastrad 
   4445   1.6  riastrad 	eld[DRM_ELD_BASELINE_ELD_LEN] =
   4446   1.6  riastrad 		DIV_ROUND_UP(drm_eld_calc_baseline_block_size(eld), 4);
   4447   1.6  riastrad 
   4448   1.6  riastrad 	DRM_DEBUG_KMS("ELD size %d, SAD count %d\n",
   4449   1.9  riastrad 		      drm_eld_size(eld), total_sad_count);
   4450   1.1  riastrad }
   4451   1.1  riastrad 
   4452   1.1  riastrad /**
   4453   1.3  riastrad  * drm_edid_to_sad - extracts SADs from EDID
   4454   1.3  riastrad  * @edid: EDID to parse
   4455   1.3  riastrad  * @sads: pointer that will be set to the extracted SADs
   4456   1.3  riastrad  *
   4457   1.3  riastrad  * Looks for CEA EDID block and extracts SADs (Short Audio Descriptors) from it.
   4458   1.3  riastrad  *
   4459   1.6  riastrad  * Note: The returned pointer needs to be freed using kfree().
   4460   1.6  riastrad  *
   4461   1.6  riastrad  * Return: The number of found SADs or negative number on error.
   4462   1.3  riastrad  */
   4463   1.3  riastrad int drm_edid_to_sad(struct edid *edid, struct cea_sad **sads)
   4464   1.3  riastrad {
   4465   1.3  riastrad 	int count = 0;
   4466   1.3  riastrad 	int i, start, end, dbl;
   4467  1.13  riastrad 	const u8 *cea;
   4468   1.3  riastrad 
   4469   1.3  riastrad 	cea = drm_find_cea_extension(edid);
   4470   1.3  riastrad 	if (!cea) {
   4471   1.3  riastrad 		DRM_DEBUG_KMS("SAD: no CEA Extension found\n");
   4472   1.9  riastrad 		return 0;
   4473   1.3  riastrad 	}
   4474   1.3  riastrad 
   4475   1.3  riastrad 	if (cea_revision(cea) < 3) {
   4476   1.3  riastrad 		DRM_DEBUG_KMS("SAD: wrong CEA revision\n");
   4477   1.9  riastrad 		return 0;
   4478   1.3  riastrad 	}
   4479   1.3  riastrad 
   4480   1.3  riastrad 	if (cea_db_offsets(cea, &start, &end)) {
   4481   1.3  riastrad 		DRM_DEBUG_KMS("SAD: invalid data block offsets\n");
   4482   1.3  riastrad 		return -EPROTO;
   4483   1.3  riastrad 	}
   4484   1.3  riastrad 
   4485   1.3  riastrad 	for_each_cea_db(cea, i, start, end) {
   4486  1.13  riastrad 		const u8 *db = &cea[i];
   4487   1.3  riastrad 
   4488   1.3  riastrad 		if (cea_db_tag(db) == AUDIO_BLOCK) {
   4489   1.3  riastrad 			int j;
   4490   1.3  riastrad 			dbl = cea_db_payload_len(db);
   4491   1.3  riastrad 
   4492   1.3  riastrad 			count = dbl / 3; /* SAD is 3B */
   4493   1.3  riastrad 			*sads = kcalloc(count, sizeof(**sads), GFP_KERNEL);
   4494   1.3  riastrad 			if (!*sads)
   4495   1.3  riastrad 				return -ENOMEM;
   4496   1.3  riastrad 			for (j = 0; j < count; j++) {
   4497  1.13  riastrad 				const u8 *sad = &db[1 + j * 3];
   4498   1.3  riastrad 
   4499   1.3  riastrad 				(*sads)[j].format = (sad[0] & 0x78) >> 3;
   4500   1.3  riastrad 				(*sads)[j].channels = sad[0] & 0x7;
   4501   1.3  riastrad 				(*sads)[j].freq = sad[1] & 0x7F;
   4502   1.3  riastrad 				(*sads)[j].byte2 = sad[2];
   4503   1.3  riastrad 			}
   4504   1.3  riastrad 			break;
   4505   1.3  riastrad 		}
   4506   1.3  riastrad 	}
   4507   1.3  riastrad 
   4508   1.3  riastrad 	return count;
   4509   1.3  riastrad }
   4510   1.3  riastrad EXPORT_SYMBOL(drm_edid_to_sad);
   4511   1.3  riastrad 
   4512   1.3  riastrad /**
   4513   1.3  riastrad  * drm_edid_to_speaker_allocation - extracts Speaker Allocation Data Blocks from EDID
   4514   1.3  riastrad  * @edid: EDID to parse
   4515   1.3  riastrad  * @sadb: pointer to the speaker block
   4516   1.3  riastrad  *
   4517   1.3  riastrad  * Looks for CEA EDID block and extracts the Speaker Allocation Data Block from it.
   4518   1.3  riastrad  *
   4519   1.6  riastrad  * Note: The returned pointer needs to be freed using kfree().
   4520   1.6  riastrad  *
   4521   1.6  riastrad  * Return: The number of found Speaker Allocation Blocks or negative number on
   4522   1.6  riastrad  * error.
   4523   1.3  riastrad  */
   4524   1.3  riastrad int drm_edid_to_speaker_allocation(struct edid *edid, u8 **sadb)
   4525   1.3  riastrad {
   4526   1.3  riastrad 	int count = 0;
   4527   1.3  riastrad 	int i, start, end, dbl;
   4528   1.3  riastrad 	const u8 *cea;
   4529   1.3  riastrad 
   4530   1.3  riastrad 	cea = drm_find_cea_extension(edid);
   4531   1.3  riastrad 	if (!cea) {
   4532   1.3  riastrad 		DRM_DEBUG_KMS("SAD: no CEA Extension found\n");
   4533   1.9  riastrad 		return 0;
   4534   1.3  riastrad 	}
   4535   1.3  riastrad 
   4536   1.3  riastrad 	if (cea_revision(cea) < 3) {
   4537   1.3  riastrad 		DRM_DEBUG_KMS("SAD: wrong CEA revision\n");
   4538   1.9  riastrad 		return 0;
   4539   1.3  riastrad 	}
   4540   1.3  riastrad 
   4541   1.3  riastrad 	if (cea_db_offsets(cea, &start, &end)) {
   4542   1.3  riastrad 		DRM_DEBUG_KMS("SAD: invalid data block offsets\n");
   4543   1.3  riastrad 		return -EPROTO;
   4544   1.3  riastrad 	}
   4545   1.3  riastrad 
   4546   1.3  riastrad 	for_each_cea_db(cea, i, start, end) {
   4547   1.3  riastrad 		const u8 *db = &cea[i];
   4548   1.3  riastrad 
   4549   1.3  riastrad 		if (cea_db_tag(db) == SPEAKER_BLOCK) {
   4550   1.3  riastrad 			dbl = cea_db_payload_len(db);
   4551   1.3  riastrad 
   4552   1.3  riastrad 			/* Speaker Allocation Data Block */
   4553   1.3  riastrad 			if (dbl == 3) {
   4554   1.6  riastrad 				*sadb = kmemdup(&db[1], dbl, GFP_KERNEL);
   4555   1.3  riastrad 				if (!*sadb)
   4556   1.3  riastrad 					return -ENOMEM;
   4557   1.3  riastrad 				count = dbl;
   4558   1.3  riastrad 				break;
   4559   1.3  riastrad 			}
   4560   1.3  riastrad 		}
   4561   1.3  riastrad 	}
   4562   1.3  riastrad 
   4563   1.3  riastrad 	return count;
   4564   1.3  riastrad }
   4565   1.3  riastrad EXPORT_SYMBOL(drm_edid_to_speaker_allocation);
   4566   1.3  riastrad 
   4567   1.3  riastrad /**
   4568   1.6  riastrad  * drm_av_sync_delay - compute the HDMI/DP sink audio-video sync delay
   4569   1.1  riastrad  * @connector: connector associated with the HDMI/DP sink
   4570   1.1  riastrad  * @mode: the display mode
   4571   1.6  riastrad  *
   4572   1.6  riastrad  * Return: The HDMI/DP sink's audio-video sync delay in milliseconds or 0 if
   4573   1.6  riastrad  * the sink doesn't support audio or video.
   4574   1.1  riastrad  */
   4575   1.1  riastrad int drm_av_sync_delay(struct drm_connector *connector,
   4576   1.6  riastrad 		      const struct drm_display_mode *mode)
   4577   1.1  riastrad {
   4578   1.1  riastrad 	int i = !!(mode->flags & DRM_MODE_FLAG_INTERLACE);
   4579   1.1  riastrad 	int a, v;
   4580   1.1  riastrad 
   4581   1.1  riastrad 	if (!connector->latency_present[0])
   4582   1.1  riastrad 		return 0;
   4583   1.1  riastrad 	if (!connector->latency_present[1])
   4584   1.1  riastrad 		i = 0;
   4585   1.1  riastrad 
   4586   1.1  riastrad 	a = connector->audio_latency[i];
   4587   1.1  riastrad 	v = connector->video_latency[i];
   4588   1.1  riastrad 
   4589   1.1  riastrad 	/*
   4590   1.1  riastrad 	 * HDMI/DP sink doesn't support audio or video?
   4591   1.1  riastrad 	 */
   4592   1.1  riastrad 	if (a == 255 || v == 255)
   4593   1.1  riastrad 		return 0;
   4594   1.1  riastrad 
   4595   1.1  riastrad 	/*
   4596   1.1  riastrad 	 * Convert raw EDID values to millisecond.
   4597   1.1  riastrad 	 * Treat unknown latency as 0ms.
   4598   1.1  riastrad 	 */
   4599   1.1  riastrad 	if (a)
   4600   1.1  riastrad 		a = min(2 * (a - 1), 500);
   4601   1.1  riastrad 	if (v)
   4602   1.1  riastrad 		v = min(2 * (v - 1), 500);
   4603   1.1  riastrad 
   4604   1.1  riastrad 	return max(v - a, 0);
   4605   1.1  riastrad }
   4606   1.1  riastrad EXPORT_SYMBOL(drm_av_sync_delay);
   4607   1.1  riastrad 
   4608   1.1  riastrad /**
   4609   1.6  riastrad  * drm_detect_hdmi_monitor - detect whether monitor is HDMI
   4610   1.1  riastrad  * @edid: monitor EDID information
   4611   1.1  riastrad  *
   4612   1.1  riastrad  * Parse the CEA extension according to CEA-861-B.
   4613   1.6  riastrad  *
   4614   1.6  riastrad  * Return: True if the monitor is HDMI, false if not or unknown.
   4615   1.1  riastrad  */
   4616   1.1  riastrad bool drm_detect_hdmi_monitor(struct edid *edid)
   4617   1.1  riastrad {
   4618  1.13  riastrad 	const u8 *edid_ext;
   4619   1.1  riastrad 	int i;
   4620   1.1  riastrad 	int start_offset, end_offset;
   4621   1.1  riastrad 
   4622   1.1  riastrad 	edid_ext = drm_find_cea_extension(edid);
   4623   1.1  riastrad 	if (!edid_ext)
   4624   1.1  riastrad 		return false;
   4625   1.1  riastrad 
   4626   1.1  riastrad 	if (cea_db_offsets(edid_ext, &start_offset, &end_offset))
   4627   1.1  riastrad 		return false;
   4628   1.1  riastrad 
   4629   1.1  riastrad 	/*
   4630   1.1  riastrad 	 * Because HDMI identifier is in Vendor Specific Block,
   4631   1.1  riastrad 	 * search it from all data blocks of CEA extension.
   4632   1.1  riastrad 	 */
   4633   1.1  riastrad 	for_each_cea_db(edid_ext, i, start_offset, end_offset) {
   4634   1.1  riastrad 		if (cea_db_is_hdmi_vsdb(&edid_ext[i]))
   4635   1.1  riastrad 			return true;
   4636   1.1  riastrad 	}
   4637   1.1  riastrad 
   4638   1.1  riastrad 	return false;
   4639   1.1  riastrad }
   4640   1.1  riastrad EXPORT_SYMBOL(drm_detect_hdmi_monitor);
   4641   1.1  riastrad 
   4642   1.1  riastrad /**
   4643   1.1  riastrad  * drm_detect_monitor_audio - check monitor audio capability
   4644   1.3  riastrad  * @edid: EDID block to scan
   4645   1.1  riastrad  *
   4646   1.1  riastrad  * Monitor should have CEA extension block.
   4647   1.1  riastrad  * If monitor has 'basic audio', but no CEA audio blocks, it's 'basic
   4648   1.1  riastrad  * audio' only. If there is any audio extension block and supported
   4649   1.1  riastrad  * audio format, assume at least 'basic audio' support, even if 'basic
   4650   1.1  riastrad  * audio' is not defined in EDID.
   4651   1.1  riastrad  *
   4652   1.6  riastrad  * Return: True if the monitor supports audio, false otherwise.
   4653   1.1  riastrad  */
   4654   1.1  riastrad bool drm_detect_monitor_audio(struct edid *edid)
   4655   1.1  riastrad {
   4656  1.13  riastrad 	const u8 *edid_ext;
   4657   1.1  riastrad 	int i, j;
   4658   1.1  riastrad 	bool has_audio = false;
   4659   1.1  riastrad 	int start_offset, end_offset;
   4660   1.1  riastrad 
   4661   1.1  riastrad 	edid_ext = drm_find_cea_extension(edid);
   4662   1.1  riastrad 	if (!edid_ext)
   4663   1.1  riastrad 		goto end;
   4664   1.1  riastrad 
   4665   1.1  riastrad 	has_audio = ((edid_ext[3] & EDID_BASIC_AUDIO) != 0);
   4666   1.1  riastrad 
   4667   1.1  riastrad 	if (has_audio) {
   4668   1.1  riastrad 		DRM_DEBUG_KMS("Monitor has basic audio support\n");
   4669   1.1  riastrad 		goto end;
   4670   1.1  riastrad 	}
   4671   1.1  riastrad 
   4672   1.1  riastrad 	if (cea_db_offsets(edid_ext, &start_offset, &end_offset))
   4673   1.1  riastrad 		goto end;
   4674   1.1  riastrad 
   4675   1.1  riastrad 	for_each_cea_db(edid_ext, i, start_offset, end_offset) {
   4676   1.1  riastrad 		if (cea_db_tag(&edid_ext[i]) == AUDIO_BLOCK) {
   4677   1.1  riastrad 			has_audio = true;
   4678   1.1  riastrad 			for (j = 1; j < cea_db_payload_len(&edid_ext[i]) + 1; j += 3)
   4679   1.1  riastrad 				DRM_DEBUG_KMS("CEA audio format %d\n",
   4680   1.1  riastrad 					      (edid_ext[i + j] >> 3) & 0xf);
   4681   1.1  riastrad 			goto end;
   4682   1.1  riastrad 		}
   4683   1.1  riastrad 	}
   4684   1.1  riastrad end:
   4685   1.1  riastrad 	return has_audio;
   4686   1.1  riastrad }
   4687   1.1  riastrad EXPORT_SYMBOL(drm_detect_monitor_audio);
   4688   1.1  riastrad 
   4689   1.9  riastrad 
   4690   1.1  riastrad /**
   4691   1.9  riastrad  * drm_default_rgb_quant_range - default RGB quantization range
   4692   1.9  riastrad  * @mode: display mode
   4693   1.3  riastrad  *
   4694   1.9  riastrad  * Determine the default RGB quantization range for the mode,
   4695   1.9  riastrad  * as specified in CEA-861.
   4696   1.6  riastrad  *
   4697   1.9  riastrad  * Return: The default RGB quantization range for the mode
   4698   1.3  riastrad  */
   4699   1.9  riastrad enum hdmi_quantization_range
   4700   1.9  riastrad drm_default_rgb_quant_range(const struct drm_display_mode *mode)
   4701   1.9  riastrad {
   4702   1.9  riastrad 	/* All CEA modes other than VIC 1 use limited quantization range. */
   4703   1.9  riastrad 	return drm_match_cea_mode(mode) > 1 ?
   4704   1.9  riastrad 		HDMI_QUANTIZATION_RANGE_LIMITED :
   4705   1.9  riastrad 		HDMI_QUANTIZATION_RANGE_FULL;
   4706   1.9  riastrad }
   4707   1.9  riastrad EXPORT_SYMBOL(drm_default_rgb_quant_range);
   4708   1.9  riastrad 
   4709   1.9  riastrad static void drm_parse_vcdb(struct drm_connector *connector, const u8 *db)
   4710   1.3  riastrad {
   4711   1.9  riastrad 	struct drm_display_info *info = &connector->display_info;
   4712   1.9  riastrad 
   4713   1.9  riastrad 	DRM_DEBUG_KMS("CEA VCDB 0x%02x\n", db[2]);
   4714   1.9  riastrad 
   4715   1.9  riastrad 	if (db[2] & EDID_CEA_VCDB_QS)
   4716   1.9  riastrad 		info->rgb_quant_range_selectable = true;
   4717   1.9  riastrad }
   4718   1.9  riastrad 
   4719   1.9  riastrad static void drm_parse_ycbcr420_deep_color_info(struct drm_connector *connector,
   4720   1.9  riastrad 					       const u8 *db)
   4721   1.9  riastrad {
   4722   1.9  riastrad 	u8 dc_mask;
   4723   1.9  riastrad 	struct drm_hdmi_info *hdmi = &connector->display_info.hdmi;
   4724   1.9  riastrad 
   4725   1.9  riastrad 	dc_mask = db[7] & DRM_EDID_YCBCR420_DC_MASK;
   4726   1.9  riastrad 	hdmi->y420_dc_modes = dc_mask;
   4727   1.9  riastrad }
   4728   1.9  riastrad 
   4729   1.9  riastrad static void drm_parse_hdmi_forum_vsdb(struct drm_connector *connector,
   4730   1.9  riastrad 				 const u8 *hf_vsdb)
   4731   1.9  riastrad {
   4732   1.9  riastrad 	struct drm_display_info *display = &connector->display_info;
   4733   1.9  riastrad 	struct drm_hdmi_info *hdmi = &display->hdmi;
   4734   1.9  riastrad 
   4735   1.9  riastrad 	display->has_hdmi_infoframe = true;
   4736   1.9  riastrad 
   4737   1.9  riastrad 	if (hf_vsdb[6] & 0x80) {
   4738   1.9  riastrad 		hdmi->scdc.supported = true;
   4739   1.9  riastrad 		if (hf_vsdb[6] & 0x40)
   4740   1.9  riastrad 			hdmi->scdc.read_request = true;
   4741   1.9  riastrad 	}
   4742   1.9  riastrad 
   4743   1.9  riastrad 	/*
   4744   1.9  riastrad 	 * All HDMI 2.0 monitors must support scrambling at rates > 340 MHz.
   4745   1.9  riastrad 	 * And as per the spec, three factors confirm this:
   4746   1.9  riastrad 	 * * Availability of a HF-VSDB block in EDID (check)
   4747   1.9  riastrad 	 * * Non zero Max_TMDS_Char_Rate filed in HF-VSDB (let's check)
   4748   1.9  riastrad 	 * * SCDC support available (let's check)
   4749   1.9  riastrad 	 * Lets check it out.
   4750   1.9  riastrad 	 */
   4751   1.9  riastrad 
   4752   1.9  riastrad 	if (hf_vsdb[5]) {
   4753   1.9  riastrad 		/* max clock is 5000 KHz times block value */
   4754   1.9  riastrad 		u32 max_tmds_clock = hf_vsdb[5] * 5000;
   4755   1.9  riastrad 		struct drm_scdc *scdc = &hdmi->scdc;
   4756   1.3  riastrad 
   4757   1.9  riastrad 		if (max_tmds_clock > 340000) {
   4758   1.9  riastrad 			display->max_tmds_clock = max_tmds_clock;
   4759   1.9  riastrad 			DRM_DEBUG_KMS("HF-VSDB: max TMDS clock %d kHz\n",
   4760   1.9  riastrad 				display->max_tmds_clock);
   4761   1.9  riastrad 		}
   4762   1.3  riastrad 
   4763   1.9  riastrad 		if (scdc->supported) {
   4764   1.9  riastrad 			scdc->scrambling.supported = true;
   4765   1.3  riastrad 
   4766   1.9  riastrad 			/* Few sinks support scrambling for clocks < 340M */
   4767   1.9  riastrad 			if ((hf_vsdb[6] & 0x8))
   4768   1.9  riastrad 				scdc->scrambling.low_rates = true;
   4769   1.3  riastrad 		}
   4770   1.3  riastrad 	}
   4771   1.3  riastrad 
   4772   1.9  riastrad 	drm_parse_ycbcr420_deep_color_info(connector, hf_vsdb);
   4773   1.3  riastrad }
   4774   1.3  riastrad 
   4775   1.9  riastrad static void drm_parse_hdmi_deep_color_info(struct drm_connector *connector,
   4776   1.9  riastrad 					   const u8 *hdmi)
   4777   1.6  riastrad {
   4778   1.9  riastrad 	struct drm_display_info *info = &connector->display_info;
   4779   1.6  riastrad 	unsigned int dc_bpc = 0;
   4780   1.6  riastrad 
   4781   1.9  riastrad 	/* HDMI supports at least 8 bpc */
   4782   1.9  riastrad 	info->bpc = 8;
   4783   1.9  riastrad 
   4784   1.9  riastrad 	if (cea_db_payload_len(hdmi) < 6)
   4785   1.9  riastrad 		return;
   4786   1.9  riastrad 
   4787   1.9  riastrad 	if (hdmi[6] & DRM_EDID_HDMI_DC_30) {
   4788   1.9  riastrad 		dc_bpc = 10;
   4789   1.9  riastrad 		info->edid_hdmi_dc_modes |= DRM_EDID_HDMI_DC_30;
   4790   1.9  riastrad 		DRM_DEBUG("%s: HDMI sink does deep color 30.\n",
   4791   1.9  riastrad 			  connector->name);
   4792   1.9  riastrad 	}
   4793   1.9  riastrad 
   4794   1.9  riastrad 	if (hdmi[6] & DRM_EDID_HDMI_DC_36) {
   4795   1.9  riastrad 		dc_bpc = 12;
   4796   1.9  riastrad 		info->edid_hdmi_dc_modes |= DRM_EDID_HDMI_DC_36;
   4797   1.9  riastrad 		DRM_DEBUG("%s: HDMI sink does deep color 36.\n",
   4798   1.9  riastrad 			  connector->name);
   4799   1.9  riastrad 	}
   4800   1.9  riastrad 
   4801   1.9  riastrad 	if (hdmi[6] & DRM_EDID_HDMI_DC_48) {
   4802   1.9  riastrad 		dc_bpc = 16;
   4803   1.9  riastrad 		info->edid_hdmi_dc_modes |= DRM_EDID_HDMI_DC_48;
   4804   1.9  riastrad 		DRM_DEBUG("%s: HDMI sink does deep color 48.\n",
   4805   1.9  riastrad 			  connector->name);
   4806   1.9  riastrad 	}
   4807   1.9  riastrad 
   4808   1.9  riastrad 	if (dc_bpc == 0) {
   4809   1.9  riastrad 		DRM_DEBUG("%s: No deep color support on this HDMI sink.\n",
   4810   1.9  riastrad 			  connector->name);
   4811   1.9  riastrad 		return;
   4812   1.9  riastrad 	}
   4813   1.9  riastrad 
   4814   1.9  riastrad 	DRM_DEBUG("%s: Assigning HDMI sink color depth as %d bpc.\n",
   4815   1.9  riastrad 		  connector->name, dc_bpc);
   4816   1.9  riastrad 	info->bpc = dc_bpc;
   4817   1.9  riastrad 
   4818   1.9  riastrad 	/*
   4819   1.9  riastrad 	 * Deep color support mandates RGB444 support for all video
   4820   1.9  riastrad 	 * modes and forbids YCRCB422 support for all video modes per
   4821   1.9  riastrad 	 * HDMI 1.3 spec.
   4822   1.9  riastrad 	 */
   4823   1.9  riastrad 	info->color_formats = DRM_COLOR_FORMAT_RGB444;
   4824   1.6  riastrad 
   4825   1.9  riastrad 	/* YCRCB444 is optional according to spec. */
   4826   1.9  riastrad 	if (hdmi[6] & DRM_EDID_HDMI_DC_Y444) {
   4827   1.9  riastrad 		info->color_formats |= DRM_COLOR_FORMAT_YCRCB444;
   4828   1.9  riastrad 		DRM_DEBUG("%s: HDMI sink does YCRCB444 in deep color.\n",
   4829   1.9  riastrad 			  connector->name);
   4830   1.9  riastrad 	}
   4831   1.6  riastrad 
   4832   1.6  riastrad 	/*
   4833   1.9  riastrad 	 * Spec says that if any deep color mode is supported at all,
   4834   1.9  riastrad 	 * then deep color 36 bit must be supported.
   4835   1.6  riastrad 	 */
   4836   1.9  riastrad 	if (!(hdmi[6] & DRM_EDID_HDMI_DC_36)) {
   4837   1.9  riastrad 		DRM_DEBUG("%s: HDMI sink should do DC_36, but does not!\n",
   4838   1.9  riastrad 			  connector->name);
   4839   1.9  riastrad 	}
   4840   1.9  riastrad }
   4841   1.9  riastrad 
   4842   1.9  riastrad static void
   4843   1.9  riastrad drm_parse_hdmi_vsdb_video(struct drm_connector *connector, const u8 *db)
   4844   1.9  riastrad {
   4845   1.9  riastrad 	struct drm_display_info *info = &connector->display_info;
   4846   1.9  riastrad 	u8 len = cea_db_payload_len(db);
   4847   1.9  riastrad 
   4848   1.9  riastrad 	if (len >= 6)
   4849   1.9  riastrad 		info->dvi_dual = db[6] & 1;
   4850   1.9  riastrad 	if (len >= 7)
   4851   1.9  riastrad 		info->max_tmds_clock = db[7] * 5000;
   4852   1.9  riastrad 
   4853   1.9  riastrad 	DRM_DEBUG_KMS("HDMI: DVI dual %d, "
   4854   1.9  riastrad 		      "max TMDS clock %d kHz\n",
   4855   1.9  riastrad 		      info->dvi_dual,
   4856   1.9  riastrad 		      info->max_tmds_clock);
   4857   1.9  riastrad 
   4858   1.9  riastrad 	drm_parse_hdmi_deep_color_info(connector, db);
   4859   1.9  riastrad }
   4860   1.9  riastrad 
   4861   1.9  riastrad static void drm_parse_cea_ext(struct drm_connector *connector,
   4862   1.9  riastrad 			      const struct edid *edid)
   4863   1.9  riastrad {
   4864   1.9  riastrad 	struct drm_display_info *info = &connector->display_info;
   4865   1.9  riastrad 	const u8 *edid_ext;
   4866   1.9  riastrad 	int i, start, end;
   4867   1.9  riastrad 
   4868   1.9  riastrad 	edid_ext = drm_find_cea_extension(edid);
   4869   1.9  riastrad 	if (!edid_ext)
   4870   1.9  riastrad 		return;
   4871   1.6  riastrad 
   4872   1.9  riastrad 	info->cea_rev = edid_ext[1];
   4873   1.6  riastrad 
   4874   1.9  riastrad 	/* The existence of a CEA block should imply RGB support */
   4875   1.9  riastrad 	info->color_formats = DRM_COLOR_FORMAT_RGB444;
   4876   1.9  riastrad 	if (edid_ext[3] & EDID_CEA_YCRCB444)
   4877   1.9  riastrad 		info->color_formats |= DRM_COLOR_FORMAT_YCRCB444;
   4878   1.9  riastrad 	if (edid_ext[3] & EDID_CEA_YCRCB422)
   4879   1.9  riastrad 		info->color_formats |= DRM_COLOR_FORMAT_YCRCB422;
   4880   1.6  riastrad 
   4881   1.9  riastrad 	if (cea_db_offsets(edid_ext, &start, &end))
   4882   1.9  riastrad 		return;
   4883   1.6  riastrad 
   4884   1.9  riastrad 	for_each_cea_db(edid_ext, i, start, end) {
   4885   1.9  riastrad 		const u8 *db = &edid_ext[i];
   4886   1.6  riastrad 
   4887   1.9  riastrad 		if (cea_db_is_hdmi_vsdb(db))
   4888   1.9  riastrad 			drm_parse_hdmi_vsdb_video(connector, db);
   4889   1.9  riastrad 		if (cea_db_is_hdmi_forum_vsdb(db))
   4890   1.9  riastrad 			drm_parse_hdmi_forum_vsdb(connector, db);
   4891   1.9  riastrad 		if (cea_db_is_y420cmdb(db))
   4892   1.9  riastrad 			drm_parse_y420cmdb_bitmap(connector, db);
   4893   1.9  riastrad 		if (cea_db_is_vcdb(db))
   4894   1.9  riastrad 			drm_parse_vcdb(connector, db);
   4895   1.9  riastrad 		if (cea_db_is_hdmi_hdr_metadata_block(db))
   4896   1.9  riastrad 			drm_parse_hdr_metadata_block(connector, db);
   4897   1.6  riastrad 	}
   4898   1.9  riastrad }
   4899   1.9  riastrad 
   4900   1.9  riastrad /* A connector has no EDID information, so we've got no EDID to compute quirks from. Reset
   4901   1.9  riastrad  * all of the values which would have been set from EDID
   4902   1.9  riastrad  */
   4903   1.9  riastrad void
   4904   1.9  riastrad drm_reset_display_info(struct drm_connector *connector)
   4905   1.9  riastrad {
   4906   1.9  riastrad 	struct drm_display_info *info = &connector->display_info;
   4907   1.6  riastrad 
   4908   1.9  riastrad 	info->width_mm = 0;
   4909   1.9  riastrad 	info->height_mm = 0;
   4910   1.9  riastrad 
   4911   1.9  riastrad 	info->bpc = 0;
   4912   1.9  riastrad 	info->color_formats = 0;
   4913   1.9  riastrad 	info->cea_rev = 0;
   4914   1.9  riastrad 	info->max_tmds_clock = 0;
   4915   1.9  riastrad 	info->dvi_dual = false;
   4916   1.9  riastrad 	info->has_hdmi_infoframe = false;
   4917   1.9  riastrad 	info->rgb_quant_range_selectable = false;
   4918   1.9  riastrad 	memset(&info->hdmi, 0, sizeof(info->hdmi));
   4919   1.9  riastrad 
   4920   1.9  riastrad 	info->non_desktop = 0;
   4921   1.6  riastrad }
   4922   1.6  riastrad 
   4923   1.9  riastrad u32 drm_add_display_info(struct drm_connector *connector, const struct edid *edid)
   4924   1.1  riastrad {
   4925   1.9  riastrad 	struct drm_display_info *info = &connector->display_info;
   4926   1.9  riastrad 
   4927   1.9  riastrad 	u32 quirks = edid_get_quirks(edid);
   4928   1.9  riastrad 
   4929   1.9  riastrad 	drm_reset_display_info(connector);
   4930   1.1  riastrad 
   4931   1.1  riastrad 	info->width_mm = edid->width_cm * 10;
   4932   1.1  riastrad 	info->height_mm = edid->height_cm * 10;
   4933   1.1  riastrad 
   4934   1.9  riastrad 	info->non_desktop = !!(quirks & EDID_QUIRK_NON_DESKTOP);
   4935   1.9  riastrad 
   4936   1.9  riastrad 	DRM_DEBUG_KMS("non_desktop set to %d\n", info->non_desktop);
   4937   1.1  riastrad 
   4938   1.1  riastrad 	if (edid->revision < 3)
   4939   1.9  riastrad 		return quirks;
   4940   1.1  riastrad 
   4941   1.1  riastrad 	if (!(edid->input & DRM_EDID_INPUT_DIGITAL))
   4942   1.9  riastrad 		return quirks;
   4943   1.1  riastrad 
   4944   1.9  riastrad 	drm_parse_cea_ext(connector, edid);
   4945   1.1  riastrad 
   4946   1.9  riastrad 	/*
   4947   1.9  riastrad 	 * Digital sink with "DFP 1.x compliant TMDS" according to EDID 1.3?
   4948   1.9  riastrad 	 *
   4949   1.9  riastrad 	 * For such displays, the DFP spec 1.0, section 3.10 "EDID support"
   4950   1.9  riastrad 	 * tells us to assume 8 bpc color depth if the EDID doesn't have
   4951   1.9  riastrad 	 * extensions which tell otherwise.
   4952   1.9  riastrad 	 */
   4953   1.9  riastrad 	if (info->bpc == 0 && edid->revision == 3 &&
   4954   1.9  riastrad 	    edid->input & DRM_EDID_DIGITAL_DFP_1_X) {
   4955   1.9  riastrad 		info->bpc = 8;
   4956   1.9  riastrad 		DRM_DEBUG("%s: Assigning DFP sink color depth as %d bpc.\n",
   4957   1.9  riastrad 			  connector->name, info->bpc);
   4958   1.1  riastrad 	}
   4959   1.1  riastrad 
   4960   1.1  riastrad 	/* Only defined for 1.4 with digital displays */
   4961   1.1  riastrad 	if (edid->revision < 4)
   4962   1.9  riastrad 		return quirks;
   4963   1.1  riastrad 
   4964   1.1  riastrad 	switch (edid->input & DRM_EDID_DIGITAL_DEPTH_MASK) {
   4965   1.1  riastrad 	case DRM_EDID_DIGITAL_DEPTH_6:
   4966   1.1  riastrad 		info->bpc = 6;
   4967   1.1  riastrad 		break;
   4968   1.1  riastrad 	case DRM_EDID_DIGITAL_DEPTH_8:
   4969   1.1  riastrad 		info->bpc = 8;
   4970   1.1  riastrad 		break;
   4971   1.1  riastrad 	case DRM_EDID_DIGITAL_DEPTH_10:
   4972   1.1  riastrad 		info->bpc = 10;
   4973   1.1  riastrad 		break;
   4974   1.1  riastrad 	case DRM_EDID_DIGITAL_DEPTH_12:
   4975   1.1  riastrad 		info->bpc = 12;
   4976   1.1  riastrad 		break;
   4977   1.1  riastrad 	case DRM_EDID_DIGITAL_DEPTH_14:
   4978   1.1  riastrad 		info->bpc = 14;
   4979   1.1  riastrad 		break;
   4980   1.1  riastrad 	case DRM_EDID_DIGITAL_DEPTH_16:
   4981   1.1  riastrad 		info->bpc = 16;
   4982   1.1  riastrad 		break;
   4983   1.1  riastrad 	case DRM_EDID_DIGITAL_DEPTH_UNDEF:
   4984   1.1  riastrad 	default:
   4985   1.1  riastrad 		info->bpc = 0;
   4986   1.1  riastrad 		break;
   4987   1.1  riastrad 	}
   4988   1.1  riastrad 
   4989   1.6  riastrad 	DRM_DEBUG("%s: Assigning EDID-1.4 digital sink color depth as %d bpc.\n",
   4990   1.6  riastrad 			  connector->name, info->bpc);
   4991   1.6  riastrad 
   4992   1.1  riastrad 	info->color_formats |= DRM_COLOR_FORMAT_RGB444;
   4993   1.1  riastrad 	if (edid->features & DRM_EDID_FEATURE_RGB_YCRCB444)
   4994   1.1  riastrad 		info->color_formats |= DRM_COLOR_FORMAT_YCRCB444;
   4995   1.1  riastrad 	if (edid->features & DRM_EDID_FEATURE_RGB_YCRCB422)
   4996   1.1  riastrad 		info->color_formats |= DRM_COLOR_FORMAT_YCRCB422;
   4997   1.9  riastrad 	return quirks;
   4998   1.9  riastrad }
   4999   1.9  riastrad 
   5000  1.13  riastrad static int validate_displayid(const u8 *displayid, int length, int idx)
   5001   1.9  riastrad {
   5002   1.9  riastrad 	int i;
   5003   1.9  riastrad 	u8 csum = 0;
   5004  1.13  riastrad 	const struct displayid_hdr *base;
   5005   1.9  riastrad 
   5006  1.13  riastrad 	base = (const struct displayid_hdr *)&displayid[idx];
   5007   1.9  riastrad 
   5008   1.9  riastrad 	DRM_DEBUG_KMS("base revision 0x%x, length %d, %d %d\n",
   5009   1.9  riastrad 		      base->rev, base->bytes, base->prod_id, base->ext_count);
   5010   1.9  riastrad 
   5011   1.9  riastrad 	if (base->bytes + 5 > length - idx)
   5012   1.9  riastrad 		return -EINVAL;
   5013   1.9  riastrad 	for (i = idx; i <= base->bytes + 5; i++) {
   5014   1.9  riastrad 		csum += displayid[i];
   5015   1.9  riastrad 	}
   5016   1.9  riastrad 	if (csum) {
   5017   1.9  riastrad 		DRM_NOTE("DisplayID checksum invalid, remainder is %d\n", csum);
   5018   1.9  riastrad 		return -EINVAL;
   5019   1.9  riastrad 	}
   5020   1.9  riastrad 	return 0;
   5021   1.9  riastrad }
   5022   1.9  riastrad 
   5023   1.9  riastrad static struct drm_display_mode *drm_mode_displayid_detailed(struct drm_device *dev,
   5024  1.13  riastrad 							    const struct displayid_detailed_timings_1 *timings)
   5025   1.9  riastrad {
   5026   1.9  riastrad 	struct drm_display_mode *mode;
   5027   1.9  riastrad 	unsigned pixel_clock = (timings->pixel_clock[0] |
   5028   1.9  riastrad 				(timings->pixel_clock[1] << 8) |
   5029   1.9  riastrad 				(timings->pixel_clock[2] << 16));
   5030   1.9  riastrad 	unsigned hactive = (timings->hactive[0] | timings->hactive[1] << 8) + 1;
   5031   1.9  riastrad 	unsigned hblank = (timings->hblank[0] | timings->hblank[1] << 8) + 1;
   5032   1.9  riastrad 	unsigned hsync = (timings->hsync[0] | (timings->hsync[1] & 0x7f) << 8) + 1;
   5033   1.9  riastrad 	unsigned hsync_width = (timings->hsw[0] | timings->hsw[1] << 8) + 1;
   5034   1.9  riastrad 	unsigned vactive = (timings->vactive[0] | timings->vactive[1] << 8) + 1;
   5035   1.9  riastrad 	unsigned vblank = (timings->vblank[0] | timings->vblank[1] << 8) + 1;
   5036   1.9  riastrad 	unsigned vsync = (timings->vsync[0] | (timings->vsync[1] & 0x7f) << 8) + 1;
   5037   1.9  riastrad 	unsigned vsync_width = (timings->vsw[0] | timings->vsw[1] << 8) + 1;
   5038   1.9  riastrad 	bool hsync_positive = (timings->hsync[1] >> 7) & 0x1;
   5039   1.9  riastrad 	bool vsync_positive = (timings->vsync[1] >> 7) & 0x1;
   5040   1.9  riastrad 	mode = drm_mode_create(dev);
   5041   1.9  riastrad 	if (!mode)
   5042   1.9  riastrad 		return NULL;
   5043   1.9  riastrad 
   5044   1.9  riastrad 	mode->clock = pixel_clock * 10;
   5045   1.9  riastrad 	mode->hdisplay = hactive;
   5046   1.9  riastrad 	mode->hsync_start = mode->hdisplay + hsync;
   5047   1.9  riastrad 	mode->hsync_end = mode->hsync_start + hsync_width;
   5048   1.9  riastrad 	mode->htotal = mode->hdisplay + hblank;
   5049   1.9  riastrad 
   5050   1.9  riastrad 	mode->vdisplay = vactive;
   5051   1.9  riastrad 	mode->vsync_start = mode->vdisplay + vsync;
   5052   1.9  riastrad 	mode->vsync_end = mode->vsync_start + vsync_width;
   5053   1.9  riastrad 	mode->vtotal = mode->vdisplay + vblank;
   5054   1.9  riastrad 
   5055   1.9  riastrad 	mode->flags = 0;
   5056   1.9  riastrad 	mode->flags |= hsync_positive ? DRM_MODE_FLAG_PHSYNC : DRM_MODE_FLAG_NHSYNC;
   5057   1.9  riastrad 	mode->flags |= vsync_positive ? DRM_MODE_FLAG_PVSYNC : DRM_MODE_FLAG_NVSYNC;
   5058   1.9  riastrad 	mode->type = DRM_MODE_TYPE_DRIVER;
   5059   1.9  riastrad 
   5060   1.9  riastrad 	if (timings->flags & 0x80)
   5061   1.9  riastrad 		mode->type |= DRM_MODE_TYPE_PREFERRED;
   5062   1.9  riastrad 	mode->vrefresh = drm_mode_vrefresh(mode);
   5063   1.9  riastrad 	drm_mode_set_name(mode);
   5064   1.9  riastrad 
   5065   1.9  riastrad 	return mode;
   5066   1.9  riastrad }
   5067   1.9  riastrad 
   5068   1.9  riastrad static int add_displayid_detailed_1_modes(struct drm_connector *connector,
   5069  1.13  riastrad 					  const struct displayid_block *block)
   5070   1.9  riastrad {
   5071  1.13  riastrad 	const struct displayid_detailed_timing_block *det = (const struct displayid_detailed_timing_block *)block;
   5072   1.9  riastrad 	int i;
   5073   1.9  riastrad 	int num_timings;
   5074   1.9  riastrad 	struct drm_display_mode *newmode;
   5075   1.9  riastrad 	int num_modes = 0;
   5076   1.9  riastrad 	/* blocks must be multiple of 20 bytes length */
   5077   1.9  riastrad 	if (block->num_bytes % 20)
   5078   1.9  riastrad 		return 0;
   5079   1.9  riastrad 
   5080   1.9  riastrad 	num_timings = block->num_bytes / 20;
   5081   1.9  riastrad 	for (i = 0; i < num_timings; i++) {
   5082  1.13  riastrad 		const struct displayid_detailed_timings_1 *timings = &det->timings[i];
   5083   1.9  riastrad 
   5084   1.9  riastrad 		newmode = drm_mode_displayid_detailed(connector->dev, timings);
   5085   1.9  riastrad 		if (!newmode)
   5086   1.9  riastrad 			continue;
   5087   1.9  riastrad 
   5088   1.9  riastrad 		drm_mode_probed_add(connector, newmode);
   5089   1.9  riastrad 		num_modes++;
   5090   1.9  riastrad 	}
   5091   1.9  riastrad 	return num_modes;
   5092   1.9  riastrad }
   5093   1.9  riastrad 
   5094   1.9  riastrad static int add_displayid_detailed_modes(struct drm_connector *connector,
   5095   1.9  riastrad 					struct edid *edid)
   5096   1.9  riastrad {
   5097  1.13  riastrad 	const u8 *displayid;
   5098   1.9  riastrad 	int ret;
   5099   1.9  riastrad 	int idx = 1;
   5100   1.9  riastrad 	int length = EDID_LENGTH;
   5101  1.13  riastrad 	const struct displayid_block *block;
   5102   1.9  riastrad 	int num_modes = 0;
   5103   1.9  riastrad 
   5104   1.9  riastrad 	displayid = drm_find_displayid_extension(edid);
   5105   1.9  riastrad 	if (!displayid)
   5106   1.9  riastrad 		return 0;
   5107   1.9  riastrad 
   5108   1.9  riastrad 	ret = validate_displayid(displayid, length, idx);
   5109   1.9  riastrad 	if (ret)
   5110   1.9  riastrad 		return 0;
   5111   1.9  riastrad 
   5112   1.9  riastrad 	idx += sizeof(struct displayid_hdr);
   5113   1.9  riastrad 	for_each_displayid_db(displayid, block, idx, length) {
   5114   1.9  riastrad 		switch (block->tag) {
   5115   1.9  riastrad 		case DATA_BLOCK_TYPE_1_DETAILED_TIMING:
   5116   1.9  riastrad 			num_modes += add_displayid_detailed_1_modes(connector, block);
   5117   1.9  riastrad 			break;
   5118   1.9  riastrad 		}
   5119   1.9  riastrad 	}
   5120   1.9  riastrad 	return num_modes;
   5121   1.1  riastrad }
   5122   1.1  riastrad 
   5123   1.1  riastrad /**
   5124   1.1  riastrad  * drm_add_edid_modes - add modes from EDID data, if available
   5125   1.1  riastrad  * @connector: connector we're probing
   5126   1.6  riastrad  * @edid: EDID data
   5127   1.1  riastrad  *
   5128   1.9  riastrad  * Add the specified modes to the connector's mode list. Also fills out the
   5129   1.9  riastrad  * &drm_display_info structure and ELD in @connector with any information which
   5130   1.9  riastrad  * can be derived from the edid.
   5131   1.1  riastrad  *
   5132   1.6  riastrad  * Return: The number of modes added or 0 if we couldn't find any.
   5133   1.1  riastrad  */
   5134   1.1  riastrad int drm_add_edid_modes(struct drm_connector *connector, struct edid *edid)
   5135   1.1  riastrad {
   5136   1.1  riastrad 	int num_modes = 0;
   5137   1.1  riastrad 	u32 quirks;
   5138   1.1  riastrad 
   5139   1.1  riastrad 	if (edid == NULL) {
   5140   1.9  riastrad 		clear_eld(connector);
   5141   1.1  riastrad 		return 0;
   5142   1.1  riastrad 	}
   5143   1.1  riastrad 	if (!drm_edid_is_valid(edid)) {
   5144   1.9  riastrad 		clear_eld(connector);
   5145   1.1  riastrad 		dev_warn(connector->dev->dev, "%s: EDID invalid.\n",
   5146   1.6  riastrad 			 connector->name);
   5147   1.1  riastrad 		return 0;
   5148   1.1  riastrad 	}
   5149   1.1  riastrad 
   5150   1.9  riastrad 	drm_edid_to_eld(connector, edid);
   5151   1.9  riastrad 
   5152   1.9  riastrad 	/*
   5153   1.9  riastrad 	 * CEA-861-F adds ycbcr capability map block, for HDMI 2.0 sinks.
   5154   1.9  riastrad 	 * To avoid multiple parsing of same block, lets parse that map
   5155   1.9  riastrad 	 * from sink info, before parsing CEA modes.
   5156   1.9  riastrad 	 */
   5157   1.9  riastrad 	quirks = drm_add_display_info(connector, edid);
   5158   1.1  riastrad 
   5159   1.1  riastrad 	/*
   5160   1.1  riastrad 	 * EDID spec says modes should be preferred in this order:
   5161   1.1  riastrad 	 * - preferred detailed mode
   5162   1.1  riastrad 	 * - other detailed modes from base block
   5163   1.1  riastrad 	 * - detailed modes from extension blocks
   5164   1.1  riastrad 	 * - CVT 3-byte code modes
   5165   1.1  riastrad 	 * - standard timing codes
   5166   1.1  riastrad 	 * - established timing codes
   5167   1.1  riastrad 	 * - modes inferred from GTF or CVT range information
   5168   1.1  riastrad 	 *
   5169   1.1  riastrad 	 * We get this pretty much right.
   5170   1.1  riastrad 	 *
   5171   1.1  riastrad 	 * XXX order for additional mode types in extension blocks?
   5172   1.1  riastrad 	 */
   5173   1.1  riastrad 	num_modes += add_detailed_modes(connector, edid, quirks);
   5174   1.1  riastrad 	num_modes += add_cvt_modes(connector, edid);
   5175   1.1  riastrad 	num_modes += add_standard_modes(connector, edid);
   5176   1.1  riastrad 	num_modes += add_established_modes(connector, edid);
   5177   1.6  riastrad 	num_modes += add_cea_modes(connector, edid);
   5178   1.6  riastrad 	num_modes += add_alternate_cea_modes(connector, edid);
   5179   1.9  riastrad 	num_modes += add_displayid_detailed_modes(connector, edid);
   5180   1.3  riastrad 	if (edid->features & DRM_EDID_FEATURE_DEFAULT_GTF)
   5181   1.3  riastrad 		num_modes += add_inferred_modes(connector, edid);
   5182   1.1  riastrad 
   5183   1.1  riastrad 	if (quirks & (EDID_QUIRK_PREFER_LARGE_60 | EDID_QUIRK_PREFER_LARGE_75))
   5184   1.1  riastrad 		edid_fixup_preferred(connector, quirks);
   5185   1.1  riastrad 
   5186   1.6  riastrad 	if (quirks & EDID_QUIRK_FORCE_6BPC)
   5187   1.6  riastrad 		connector->display_info.bpc = 6;
   5188   1.1  riastrad 
   5189   1.3  riastrad 	if (quirks & EDID_QUIRK_FORCE_8BPC)
   5190   1.3  riastrad 		connector->display_info.bpc = 8;
   5191   1.3  riastrad 
   5192   1.6  riastrad 	if (quirks & EDID_QUIRK_FORCE_10BPC)
   5193   1.6  riastrad 		connector->display_info.bpc = 10;
   5194   1.6  riastrad 
   5195   1.6  riastrad 	if (quirks & EDID_QUIRK_FORCE_12BPC)
   5196   1.6  riastrad 		connector->display_info.bpc = 12;
   5197   1.6  riastrad 
   5198   1.1  riastrad 	return num_modes;
   5199   1.1  riastrad }
   5200   1.1  riastrad EXPORT_SYMBOL(drm_add_edid_modes);
   5201   1.1  riastrad 
   5202   1.1  riastrad /**
   5203   1.1  riastrad  * drm_add_modes_noedid - add modes for the connectors without EDID
   5204   1.1  riastrad  * @connector: connector we're probing
   5205   1.1  riastrad  * @hdisplay: the horizontal display limit
   5206   1.1  riastrad  * @vdisplay: the vertical display limit
   5207   1.1  riastrad  *
   5208   1.1  riastrad  * Add the specified modes to the connector's mode list. Only when the
   5209   1.1  riastrad  * hdisplay/vdisplay is not beyond the given limit, it will be added.
   5210   1.1  riastrad  *
   5211   1.6  riastrad  * Return: The number of modes added or 0 if we couldn't find any.
   5212   1.1  riastrad  */
   5213   1.1  riastrad int drm_add_modes_noedid(struct drm_connector *connector,
   5214   1.1  riastrad 			int hdisplay, int vdisplay)
   5215   1.1  riastrad {
   5216   1.1  riastrad 	int i, count, num_modes = 0;
   5217   1.1  riastrad 	struct drm_display_mode *mode;
   5218   1.1  riastrad 	struct drm_device *dev = connector->dev;
   5219   1.1  riastrad 
   5220   1.6  riastrad 	count = ARRAY_SIZE(drm_dmt_modes);
   5221   1.1  riastrad 	if (hdisplay < 0)
   5222   1.1  riastrad 		hdisplay = 0;
   5223   1.1  riastrad 	if (vdisplay < 0)
   5224   1.1  riastrad 		vdisplay = 0;
   5225   1.1  riastrad 
   5226   1.1  riastrad 	for (i = 0; i < count; i++) {
   5227   1.1  riastrad 		const struct drm_display_mode *ptr = &drm_dmt_modes[i];
   5228   1.1  riastrad 		if (hdisplay && vdisplay) {
   5229   1.1  riastrad 			/*
   5230   1.1  riastrad 			 * Only when two are valid, they will be used to check
   5231   1.1  riastrad 			 * whether the mode should be added to the mode list of
   5232   1.1  riastrad 			 * the connector.
   5233   1.1  riastrad 			 */
   5234   1.1  riastrad 			if (ptr->hdisplay > hdisplay ||
   5235   1.1  riastrad 					ptr->vdisplay > vdisplay)
   5236   1.1  riastrad 				continue;
   5237   1.1  riastrad 		}
   5238   1.1  riastrad 		if (drm_mode_vrefresh(ptr) > 61)
   5239   1.1  riastrad 			continue;
   5240   1.1  riastrad 		mode = drm_mode_duplicate(dev, ptr);
   5241   1.1  riastrad 		if (mode) {
   5242   1.1  riastrad 			drm_mode_probed_add(connector, mode);
   5243   1.1  riastrad 			num_modes++;
   5244   1.1  riastrad 		}
   5245   1.1  riastrad 	}
   5246   1.1  riastrad 	return num_modes;
   5247   1.1  riastrad }
   5248   1.1  riastrad EXPORT_SYMBOL(drm_add_modes_noedid);
   5249   1.1  riastrad 
   5250   1.6  riastrad /**
   5251   1.6  riastrad  * drm_set_preferred_mode - Sets the preferred mode of a connector
   5252   1.6  riastrad  * @connector: connector whose mode list should be processed
   5253   1.6  riastrad  * @hpref: horizontal resolution of preferred mode
   5254   1.6  riastrad  * @vpref: vertical resolution of preferred mode
   5255   1.6  riastrad  *
   5256   1.6  riastrad  * Marks a mode as preferred if it matches the resolution specified by @hpref
   5257   1.6  riastrad  * and @vpref.
   5258   1.6  riastrad  */
   5259   1.3  riastrad void drm_set_preferred_mode(struct drm_connector *connector,
   5260   1.3  riastrad 			   int hpref, int vpref)
   5261   1.3  riastrad {
   5262   1.3  riastrad 	struct drm_display_mode *mode;
   5263   1.3  riastrad 
   5264   1.3  riastrad 	list_for_each_entry(mode, &connector->probed_modes, head) {
   5265   1.6  riastrad 		if (mode->hdisplay == hpref &&
   5266   1.3  riastrad 		    mode->vdisplay == vpref)
   5267   1.3  riastrad 			mode->type |= DRM_MODE_TYPE_PREFERRED;
   5268   1.3  riastrad 	}
   5269   1.3  riastrad }
   5270   1.3  riastrad EXPORT_SYMBOL(drm_set_preferred_mode);
   5271   1.3  riastrad 
   5272   1.9  riastrad static bool is_hdmi2_sink(struct drm_connector *connector)
   5273   1.9  riastrad {
   5274   1.9  riastrad 	/*
   5275   1.9  riastrad 	 * FIXME: sil-sii8620 doesn't have a connector around when
   5276   1.9  riastrad 	 * we need one, so we have to be prepared for a NULL connector.
   5277   1.9  riastrad 	 */
   5278   1.9  riastrad 	if (!connector)
   5279   1.9  riastrad 		return true;
   5280   1.9  riastrad 
   5281   1.9  riastrad 	return connector->display_info.hdmi.scdc.supported ||
   5282   1.9  riastrad 		connector->display_info.color_formats & DRM_COLOR_FORMAT_YCRCB420;
   5283   1.9  riastrad }
   5284   1.9  riastrad 
   5285   1.9  riastrad static inline bool is_eotf_supported(u8 output_eotf, u8 sink_eotf)
   5286   1.9  riastrad {
   5287   1.9  riastrad 	return sink_eotf & BIT(output_eotf);
   5288   1.9  riastrad }
   5289   1.9  riastrad 
   5290   1.9  riastrad /**
   5291   1.9  riastrad  * drm_hdmi_infoframe_set_hdr_metadata() - fill an HDMI DRM infoframe with
   5292   1.9  riastrad  *                                         HDR metadata from userspace
   5293   1.9  riastrad  * @frame: HDMI DRM infoframe
   5294   1.9  riastrad  * @conn_state: Connector state containing HDR metadata
   5295   1.9  riastrad  *
   5296   1.9  riastrad  * Return: 0 on success or a negative error code on failure.
   5297   1.9  riastrad  */
   5298   1.9  riastrad int
   5299   1.9  riastrad drm_hdmi_infoframe_set_hdr_metadata(struct hdmi_drm_infoframe *frame,
   5300   1.9  riastrad 				    const struct drm_connector_state *conn_state)
   5301   1.9  riastrad {
   5302   1.9  riastrad 	struct drm_connector *connector;
   5303   1.9  riastrad 	struct hdr_output_metadata *hdr_metadata;
   5304   1.9  riastrad 	int err;
   5305   1.9  riastrad 
   5306   1.9  riastrad 	if (!frame || !conn_state)
   5307   1.9  riastrad 		return -EINVAL;
   5308   1.9  riastrad 
   5309   1.9  riastrad 	connector = conn_state->connector;
   5310   1.9  riastrad 
   5311   1.9  riastrad 	if (!conn_state->hdr_output_metadata)
   5312   1.9  riastrad 		return -EINVAL;
   5313   1.9  riastrad 
   5314   1.9  riastrad 	hdr_metadata = conn_state->hdr_output_metadata->data;
   5315   1.9  riastrad 
   5316   1.9  riastrad 	if (!hdr_metadata || !connector)
   5317   1.9  riastrad 		return -EINVAL;
   5318   1.9  riastrad 
   5319   1.9  riastrad 	/* Sink EOTF is Bit map while infoframe is absolute values */
   5320   1.9  riastrad 	if (!is_eotf_supported(hdr_metadata->hdmi_metadata_type1.eotf,
   5321   1.9  riastrad 	    connector->hdr_sink_metadata.hdmi_type1.eotf)) {
   5322   1.9  riastrad 		DRM_DEBUG_KMS("EOTF Not Supported\n");
   5323   1.9  riastrad 		return -EINVAL;
   5324   1.9  riastrad 	}
   5325   1.9  riastrad 
   5326   1.9  riastrad 	err = hdmi_drm_infoframe_init(frame);
   5327   1.9  riastrad 	if (err < 0)
   5328   1.9  riastrad 		return err;
   5329   1.9  riastrad 
   5330   1.9  riastrad 	frame->eotf = hdr_metadata->hdmi_metadata_type1.eotf;
   5331   1.9  riastrad 	frame->metadata_type = hdr_metadata->hdmi_metadata_type1.metadata_type;
   5332   1.9  riastrad 
   5333   1.9  riastrad 	BUILD_BUG_ON(sizeof(frame->display_primaries) !=
   5334   1.9  riastrad 		     sizeof(hdr_metadata->hdmi_metadata_type1.display_primaries));
   5335   1.9  riastrad 	BUILD_BUG_ON(sizeof(frame->white_point) !=
   5336   1.9  riastrad 		     sizeof(hdr_metadata->hdmi_metadata_type1.white_point));
   5337   1.9  riastrad 
   5338   1.9  riastrad 	memcpy(&frame->display_primaries,
   5339   1.9  riastrad 	       &hdr_metadata->hdmi_metadata_type1.display_primaries,
   5340   1.9  riastrad 	       sizeof(frame->display_primaries));
   5341   1.9  riastrad 
   5342   1.9  riastrad 	memcpy(&frame->white_point,
   5343   1.9  riastrad 	       &hdr_metadata->hdmi_metadata_type1.white_point,
   5344   1.9  riastrad 	       sizeof(frame->white_point));
   5345   1.9  riastrad 
   5346   1.9  riastrad 	frame->max_display_mastering_luminance =
   5347   1.9  riastrad 		hdr_metadata->hdmi_metadata_type1.max_display_mastering_luminance;
   5348   1.9  riastrad 	frame->min_display_mastering_luminance =
   5349   1.9  riastrad 		hdr_metadata->hdmi_metadata_type1.min_display_mastering_luminance;
   5350   1.9  riastrad 	frame->max_fall = hdr_metadata->hdmi_metadata_type1.max_fall;
   5351   1.9  riastrad 	frame->max_cll = hdr_metadata->hdmi_metadata_type1.max_cll;
   5352   1.9  riastrad 
   5353   1.9  riastrad 	return 0;
   5354   1.9  riastrad }
   5355   1.9  riastrad EXPORT_SYMBOL(drm_hdmi_infoframe_set_hdr_metadata);
   5356   1.9  riastrad 
   5357   1.9  riastrad static u8 drm_mode_hdmi_vic(struct drm_connector *connector,
   5358   1.9  riastrad 			    const struct drm_display_mode *mode)
   5359   1.9  riastrad {
   5360   1.9  riastrad 	bool has_hdmi_infoframe = connector ?
   5361   1.9  riastrad 		connector->display_info.has_hdmi_infoframe : false;
   5362   1.9  riastrad 
   5363   1.9  riastrad 	if (!has_hdmi_infoframe)
   5364   1.9  riastrad 		return 0;
   5365   1.9  riastrad 
   5366   1.9  riastrad 	/* No HDMI VIC when signalling 3D video format */
   5367   1.9  riastrad 	if (mode->flags & DRM_MODE_FLAG_3D_MASK)
   5368   1.9  riastrad 		return 0;
   5369   1.9  riastrad 
   5370   1.9  riastrad 	return drm_match_hdmi_mode(mode);
   5371   1.9  riastrad }
   5372   1.9  riastrad 
   5373   1.9  riastrad static u8 drm_mode_cea_vic(struct drm_connector *connector,
   5374   1.9  riastrad 			   const struct drm_display_mode *mode)
   5375   1.9  riastrad {
   5376   1.9  riastrad 	u8 vic;
   5377   1.9  riastrad 
   5378   1.9  riastrad 	/*
   5379   1.9  riastrad 	 * HDMI spec says if a mode is found in HDMI 1.4b 4K modes
   5380   1.9  riastrad 	 * we should send its VIC in vendor infoframes, else send the
   5381   1.9  riastrad 	 * VIC in AVI infoframes. Lets check if this mode is present in
   5382   1.9  riastrad 	 * HDMI 1.4b 4K modes
   5383   1.9  riastrad 	 */
   5384   1.9  riastrad 	if (drm_mode_hdmi_vic(connector, mode))
   5385   1.9  riastrad 		return 0;
   5386   1.9  riastrad 
   5387   1.9  riastrad 	vic = drm_match_cea_mode(mode);
   5388   1.9  riastrad 
   5389   1.9  riastrad 	/*
   5390   1.9  riastrad 	 * HDMI 1.4 VIC range: 1 <= VIC <= 64 (CEA-861-D) but
   5391   1.9  riastrad 	 * HDMI 2.0 VIC range: 1 <= VIC <= 107 (CEA-861-F). So we
   5392   1.9  riastrad 	 * have to make sure we dont break HDMI 1.4 sinks.
   5393   1.9  riastrad 	 */
   5394   1.9  riastrad 	if (!is_hdmi2_sink(connector) && vic > 64)
   5395   1.9  riastrad 		return 0;
   5396   1.9  riastrad 
   5397   1.9  riastrad 	return vic;
   5398   1.9  riastrad }
   5399   1.9  riastrad 
   5400   1.1  riastrad /**
   5401   1.3  riastrad  * drm_hdmi_avi_infoframe_from_display_mode() - fill an HDMI AVI infoframe with
   5402   1.3  riastrad  *                                              data from a DRM display mode
   5403   1.3  riastrad  * @frame: HDMI AVI infoframe
   5404   1.9  riastrad  * @connector: the connector
   5405   1.3  riastrad  * @mode: DRM display mode
   5406   1.1  riastrad  *
   5407   1.6  riastrad  * Return: 0 on success or a negative error code on failure.
   5408   1.1  riastrad  */
   5409   1.3  riastrad int
   5410   1.3  riastrad drm_hdmi_avi_infoframe_from_display_mode(struct hdmi_avi_infoframe *frame,
   5411   1.9  riastrad 					 struct drm_connector *connector,
   5412   1.3  riastrad 					 const struct drm_display_mode *mode)
   5413   1.1  riastrad {
   5414   1.9  riastrad 	enum hdmi_picture_aspect picture_aspect;
   5415   1.9  riastrad 	u8 vic, hdmi_vic;
   5416   1.3  riastrad 	int err;
   5417   1.3  riastrad 
   5418   1.3  riastrad 	if (!frame || !mode)
   5419   1.3  riastrad 		return -EINVAL;
   5420   1.3  riastrad 
   5421   1.3  riastrad 	err = hdmi_avi_infoframe_init(frame);
   5422   1.3  riastrad 	if (err < 0)
   5423   1.3  riastrad 		return err;
   5424   1.3  riastrad 
   5425   1.3  riastrad 	if (mode->flags & DRM_MODE_FLAG_DBLCLK)
   5426   1.3  riastrad 		frame->pixel_repeat = 1;
   5427   1.1  riastrad 
   5428   1.9  riastrad 	vic = drm_mode_cea_vic(connector, mode);
   5429   1.9  riastrad 	hdmi_vic = drm_mode_hdmi_vic(connector, mode);
   5430   1.3  riastrad 
   5431   1.3  riastrad 	frame->picture_aspect = HDMI_PICTURE_ASPECT_NONE;
   5432   1.6  riastrad 
   5433   1.6  riastrad 	/*
   5434   1.9  riastrad 	 * As some drivers don't support atomic, we can't use connector state.
   5435   1.9  riastrad 	 * So just initialize the frame with default values, just the same way
   5436   1.9  riastrad 	 * as it's done with other properties here.
   5437   1.9  riastrad 	 */
   5438   1.9  riastrad 	frame->content_type = HDMI_CONTENT_TYPE_GRAPHICS;
   5439   1.9  riastrad 	frame->itc = 0;
   5440   1.9  riastrad 
   5441   1.9  riastrad 	/*
   5442   1.6  riastrad 	 * Populate picture aspect ratio from either
   5443   1.9  riastrad 	 * user input (if specified) or from the CEA/HDMI mode lists.
   5444   1.6  riastrad 	 */
   5445   1.9  riastrad 	picture_aspect = mode->picture_aspect_ratio;
   5446   1.9  riastrad 	if (picture_aspect == HDMI_PICTURE_ASPECT_NONE) {
   5447   1.9  riastrad 		if (vic)
   5448   1.9  riastrad 			picture_aspect = drm_get_cea_aspect_ratio(vic);
   5449   1.9  riastrad 		else if (hdmi_vic)
   5450   1.9  riastrad 			picture_aspect = drm_get_hdmi_aspect_ratio(hdmi_vic);
   5451   1.9  riastrad 	}
   5452   1.6  riastrad 
   5453   1.9  riastrad 	/*
   5454   1.9  riastrad 	 * The infoframe can't convey anything but none, 4:3
   5455   1.9  riastrad 	 * and 16:9, so if the user has asked for anything else
   5456   1.9  riastrad 	 * we can only satisfy it by specifying the right VIC.
   5457   1.9  riastrad 	 */
   5458   1.9  riastrad 	if (picture_aspect > HDMI_PICTURE_ASPECT_16_9) {
   5459   1.9  riastrad 		if (vic) {
   5460   1.9  riastrad 			if (picture_aspect != drm_get_cea_aspect_ratio(vic))
   5461   1.9  riastrad 				return -EINVAL;
   5462   1.9  riastrad 		} else if (hdmi_vic) {
   5463   1.9  riastrad 			if (picture_aspect != drm_get_hdmi_aspect_ratio(hdmi_vic))
   5464   1.9  riastrad 				return -EINVAL;
   5465   1.9  riastrad 		} else {
   5466   1.9  riastrad 			return -EINVAL;
   5467   1.9  riastrad 		}
   5468   1.9  riastrad 
   5469   1.9  riastrad 		picture_aspect = HDMI_PICTURE_ASPECT_NONE;
   5470   1.9  riastrad 	}
   5471   1.9  riastrad 
   5472   1.9  riastrad 	frame->video_code = vic;
   5473   1.9  riastrad 	frame->picture_aspect = picture_aspect;
   5474   1.3  riastrad 	frame->active_aspect = HDMI_ACTIVE_ASPECT_PICTURE;
   5475   1.3  riastrad 	frame->scan_mode = HDMI_SCAN_MODE_UNDERSCAN;
   5476   1.3  riastrad 
   5477   1.3  riastrad 	return 0;
   5478   1.3  riastrad }
   5479   1.3  riastrad EXPORT_SYMBOL(drm_hdmi_avi_infoframe_from_display_mode);
   5480   1.3  riastrad 
   5481   1.9  riastrad /* HDMI Colorspace Spec Definitions */
   5482   1.9  riastrad #define FULL_COLORIMETRY_MASK		0x1FF
   5483   1.9  riastrad #define NORMAL_COLORIMETRY_MASK		0x3
   5484   1.9  riastrad #define EXTENDED_COLORIMETRY_MASK	0x7
   5485   1.9  riastrad #define EXTENDED_ACE_COLORIMETRY_MASK	0xF
   5486   1.9  riastrad 
   5487   1.9  riastrad #define C(x) ((x) << 0)
   5488   1.9  riastrad #define EC(x) ((x) << 2)
   5489   1.9  riastrad #define ACE(x) ((x) << 5)
   5490   1.9  riastrad 
   5491   1.9  riastrad #define HDMI_COLORIMETRY_NO_DATA		0x0
   5492   1.9  riastrad #define HDMI_COLORIMETRY_SMPTE_170M_YCC		(C(1) | EC(0) | ACE(0))
   5493   1.9  riastrad #define HDMI_COLORIMETRY_BT709_YCC		(C(2) | EC(0) | ACE(0))
   5494   1.9  riastrad #define HDMI_COLORIMETRY_XVYCC_601		(C(3) | EC(0) | ACE(0))
   5495   1.9  riastrad #define HDMI_COLORIMETRY_XVYCC_709		(C(3) | EC(1) | ACE(0))
   5496   1.9  riastrad #define HDMI_COLORIMETRY_SYCC_601		(C(3) | EC(2) | ACE(0))
   5497   1.9  riastrad #define HDMI_COLORIMETRY_OPYCC_601		(C(3) | EC(3) | ACE(0))
   5498   1.9  riastrad #define HDMI_COLORIMETRY_OPRGB			(C(3) | EC(4) | ACE(0))
   5499   1.9  riastrad #define HDMI_COLORIMETRY_BT2020_CYCC		(C(3) | EC(5) | ACE(0))
   5500   1.9  riastrad #define HDMI_COLORIMETRY_BT2020_RGB		(C(3) | EC(6) | ACE(0))
   5501   1.9  riastrad #define HDMI_COLORIMETRY_BT2020_YCC		(C(3) | EC(6) | ACE(0))
   5502   1.9  riastrad #define HDMI_COLORIMETRY_DCI_P3_RGB_D65		(C(3) | EC(7) | ACE(0))
   5503   1.9  riastrad #define HDMI_COLORIMETRY_DCI_P3_RGB_THEATER	(C(3) | EC(7) | ACE(1))
   5504   1.9  riastrad 
   5505   1.9  riastrad static const u32 hdmi_colorimetry_val[] = {
   5506   1.9  riastrad 	[DRM_MODE_COLORIMETRY_NO_DATA] = HDMI_COLORIMETRY_NO_DATA,
   5507   1.9  riastrad 	[DRM_MODE_COLORIMETRY_SMPTE_170M_YCC] = HDMI_COLORIMETRY_SMPTE_170M_YCC,
   5508   1.9  riastrad 	[DRM_MODE_COLORIMETRY_BT709_YCC] = HDMI_COLORIMETRY_BT709_YCC,
   5509   1.9  riastrad 	[DRM_MODE_COLORIMETRY_XVYCC_601] = HDMI_COLORIMETRY_XVYCC_601,
   5510   1.9  riastrad 	[DRM_MODE_COLORIMETRY_XVYCC_709] = HDMI_COLORIMETRY_XVYCC_709,
   5511   1.9  riastrad 	[DRM_MODE_COLORIMETRY_SYCC_601] = HDMI_COLORIMETRY_SYCC_601,
   5512   1.9  riastrad 	[DRM_MODE_COLORIMETRY_OPYCC_601] = HDMI_COLORIMETRY_OPYCC_601,
   5513   1.9  riastrad 	[DRM_MODE_COLORIMETRY_OPRGB] = HDMI_COLORIMETRY_OPRGB,
   5514   1.9  riastrad 	[DRM_MODE_COLORIMETRY_BT2020_CYCC] = HDMI_COLORIMETRY_BT2020_CYCC,
   5515   1.9  riastrad 	[DRM_MODE_COLORIMETRY_BT2020_RGB] = HDMI_COLORIMETRY_BT2020_RGB,
   5516   1.9  riastrad 	[DRM_MODE_COLORIMETRY_BT2020_YCC] = HDMI_COLORIMETRY_BT2020_YCC,
   5517   1.9  riastrad };
   5518   1.9  riastrad 
   5519   1.9  riastrad #undef C
   5520   1.9  riastrad #undef EC
   5521   1.9  riastrad #undef ACE
   5522   1.9  riastrad 
   5523   1.9  riastrad /**
   5524   1.9  riastrad  * drm_hdmi_avi_infoframe_colorspace() - fill the HDMI AVI infoframe
   5525   1.9  riastrad  *                                       colorspace information
   5526   1.9  riastrad  * @frame: HDMI AVI infoframe
   5527   1.9  riastrad  * @conn_state: connector state
   5528   1.9  riastrad  */
   5529   1.9  riastrad void
   5530   1.9  riastrad drm_hdmi_avi_infoframe_colorspace(struct hdmi_avi_infoframe *frame,
   5531   1.9  riastrad 				  const struct drm_connector_state *conn_state)
   5532   1.9  riastrad {
   5533   1.9  riastrad 	u32 colorimetry_val;
   5534   1.9  riastrad 	u32 colorimetry_index = conn_state->colorspace & FULL_COLORIMETRY_MASK;
   5535   1.9  riastrad 
   5536   1.9  riastrad 	if (colorimetry_index >= ARRAY_SIZE(hdmi_colorimetry_val))
   5537   1.9  riastrad 		colorimetry_val = HDMI_COLORIMETRY_NO_DATA;
   5538   1.9  riastrad 	else
   5539   1.9  riastrad 		colorimetry_val = hdmi_colorimetry_val[colorimetry_index];
   5540   1.9  riastrad 
   5541   1.9  riastrad 	frame->colorimetry = colorimetry_val & NORMAL_COLORIMETRY_MASK;
   5542   1.9  riastrad 	/*
   5543   1.9  riastrad 	 * ToDo: Extend it for ACE formats as well. Modify the infoframe
   5544   1.9  riastrad 	 * structure and extend it in drivers/video/hdmi
   5545   1.9  riastrad 	 */
   5546   1.9  riastrad 	frame->extended_colorimetry = (colorimetry_val >> 2) &
   5547   1.9  riastrad 					EXTENDED_COLORIMETRY_MASK;
   5548   1.9  riastrad }
   5549   1.9  riastrad EXPORT_SYMBOL(drm_hdmi_avi_infoframe_colorspace);
   5550   1.9  riastrad 
   5551   1.9  riastrad /**
   5552   1.9  riastrad  * drm_hdmi_avi_infoframe_quant_range() - fill the HDMI AVI infoframe
   5553   1.9  riastrad  *                                        quantization range information
   5554   1.9  riastrad  * @frame: HDMI AVI infoframe
   5555   1.9  riastrad  * @connector: the connector
   5556   1.9  riastrad  * @mode: DRM display mode
   5557   1.9  riastrad  * @rgb_quant_range: RGB quantization range (Q)
   5558   1.9  riastrad  */
   5559   1.9  riastrad void
   5560   1.9  riastrad drm_hdmi_avi_infoframe_quant_range(struct hdmi_avi_infoframe *frame,
   5561   1.9  riastrad 				   struct drm_connector *connector,
   5562   1.9  riastrad 				   const struct drm_display_mode *mode,
   5563   1.9  riastrad 				   enum hdmi_quantization_range rgb_quant_range)
   5564   1.9  riastrad {
   5565   1.9  riastrad 	const struct drm_display_info *info = &connector->display_info;
   5566   1.9  riastrad 
   5567   1.9  riastrad 	/*
   5568   1.9  riastrad 	 * CEA-861:
   5569   1.9  riastrad 	 * "A Source shall not send a non-zero Q value that does not correspond
   5570   1.9  riastrad 	 *  to the default RGB Quantization Range for the transmitted Picture
   5571   1.9  riastrad 	 *  unless the Sink indicates support for the Q bit in a Video
   5572   1.9  riastrad 	 *  Capabilities Data Block."
   5573   1.9  riastrad 	 *
   5574   1.9  riastrad 	 * HDMI 2.0 recommends sending non-zero Q when it does match the
   5575   1.9  riastrad 	 * default RGB quantization range for the mode, even when QS=0.
   5576   1.9  riastrad 	 */
   5577   1.9  riastrad 	if (info->rgb_quant_range_selectable ||
   5578   1.9  riastrad 	    rgb_quant_range == drm_default_rgb_quant_range(mode))
   5579   1.9  riastrad 		frame->quantization_range = rgb_quant_range;
   5580   1.9  riastrad 	else
   5581   1.9  riastrad 		frame->quantization_range = HDMI_QUANTIZATION_RANGE_DEFAULT;
   5582   1.9  riastrad 
   5583   1.9  riastrad 	/*
   5584   1.9  riastrad 	 * CEA-861-F:
   5585   1.9  riastrad 	 * "When transmitting any RGB colorimetry, the Source should set the
   5586   1.9  riastrad 	 *  YQ-field to match the RGB Quantization Range being transmitted
   5587   1.9  riastrad 	 *  (e.g., when Limited Range RGB, set YQ=0 or when Full Range RGB,
   5588   1.9  riastrad 	 *  set YQ=1) and the Sink shall ignore the YQ-field."
   5589   1.9  riastrad 	 *
   5590   1.9  riastrad 	 * Unfortunate certain sinks (eg. VIZ Model 67/E261VA) get confused
   5591   1.9  riastrad 	 * by non-zero YQ when receiving RGB. There doesn't seem to be any
   5592   1.9  riastrad 	 * good way to tell which version of CEA-861 the sink supports, so
   5593   1.9  riastrad 	 * we limit non-zero YQ to HDMI 2.0 sinks only as HDMI 2.0 is based
   5594   1.9  riastrad 	 * on on CEA-861-F.
   5595   1.9  riastrad 	 */
   5596   1.9  riastrad 	if (!is_hdmi2_sink(connector) ||
   5597   1.9  riastrad 	    rgb_quant_range == HDMI_QUANTIZATION_RANGE_LIMITED)
   5598   1.9  riastrad 		frame->ycc_quantization_range =
   5599   1.9  riastrad 			HDMI_YCC_QUANTIZATION_RANGE_LIMITED;
   5600   1.9  riastrad 	else
   5601   1.9  riastrad 		frame->ycc_quantization_range =
   5602   1.9  riastrad 			HDMI_YCC_QUANTIZATION_RANGE_FULL;
   5603   1.9  riastrad }
   5604   1.9  riastrad EXPORT_SYMBOL(drm_hdmi_avi_infoframe_quant_range);
   5605   1.9  riastrad 
   5606   1.9  riastrad /**
   5607   1.9  riastrad  * drm_hdmi_avi_infoframe_bars() - fill the HDMI AVI infoframe
   5608   1.9  riastrad  *                                 bar information
   5609   1.9  riastrad  * @frame: HDMI AVI infoframe
   5610   1.9  riastrad  * @conn_state: connector state
   5611   1.9  riastrad  */
   5612   1.9  riastrad void
   5613   1.9  riastrad drm_hdmi_avi_infoframe_bars(struct hdmi_avi_infoframe *frame,
   5614   1.9  riastrad 			    const struct drm_connector_state *conn_state)
   5615   1.9  riastrad {
   5616   1.9  riastrad 	frame->right_bar = conn_state->tv.margins.right;
   5617   1.9  riastrad 	frame->left_bar = conn_state->tv.margins.left;
   5618   1.9  riastrad 	frame->top_bar = conn_state->tv.margins.top;
   5619   1.9  riastrad 	frame->bottom_bar = conn_state->tv.margins.bottom;
   5620   1.9  riastrad }
   5621   1.9  riastrad EXPORT_SYMBOL(drm_hdmi_avi_infoframe_bars);
   5622   1.9  riastrad 
   5623   1.3  riastrad static enum hdmi_3d_structure
   5624   1.3  riastrad s3d_structure_from_display_mode(const struct drm_display_mode *mode)
   5625   1.3  riastrad {
   5626   1.3  riastrad 	u32 layout = mode->flags & DRM_MODE_FLAG_3D_MASK;
   5627   1.3  riastrad 
   5628   1.3  riastrad 	switch (layout) {
   5629   1.3  riastrad 	case DRM_MODE_FLAG_3D_FRAME_PACKING:
   5630   1.3  riastrad 		return HDMI_3D_STRUCTURE_FRAME_PACKING;
   5631   1.3  riastrad 	case DRM_MODE_FLAG_3D_FIELD_ALTERNATIVE:
   5632   1.3  riastrad 		return HDMI_3D_STRUCTURE_FIELD_ALTERNATIVE;
   5633   1.3  riastrad 	case DRM_MODE_FLAG_3D_LINE_ALTERNATIVE:
   5634   1.3  riastrad 		return HDMI_3D_STRUCTURE_LINE_ALTERNATIVE;
   5635   1.3  riastrad 	case DRM_MODE_FLAG_3D_SIDE_BY_SIDE_FULL:
   5636   1.3  riastrad 		return HDMI_3D_STRUCTURE_SIDE_BY_SIDE_FULL;
   5637   1.3  riastrad 	case DRM_MODE_FLAG_3D_L_DEPTH:
   5638   1.3  riastrad 		return HDMI_3D_STRUCTURE_L_DEPTH;
   5639   1.3  riastrad 	case DRM_MODE_FLAG_3D_L_DEPTH_GFX_GFX_DEPTH:
   5640   1.3  riastrad 		return HDMI_3D_STRUCTURE_L_DEPTH_GFX_GFX_DEPTH;
   5641   1.3  riastrad 	case DRM_MODE_FLAG_3D_TOP_AND_BOTTOM:
   5642   1.3  riastrad 		return HDMI_3D_STRUCTURE_TOP_AND_BOTTOM;
   5643   1.3  riastrad 	case DRM_MODE_FLAG_3D_SIDE_BY_SIDE_HALF:
   5644   1.3  riastrad 		return HDMI_3D_STRUCTURE_SIDE_BY_SIDE_HALF;
   5645   1.3  riastrad 	default:
   5646   1.3  riastrad 		return HDMI_3D_STRUCTURE_INVALID;
   5647   1.3  riastrad 	}
   5648   1.3  riastrad }
   5649   1.3  riastrad 
   5650   1.3  riastrad /**
   5651   1.3  riastrad  * drm_hdmi_vendor_infoframe_from_display_mode() - fill an HDMI infoframe with
   5652   1.3  riastrad  * data from a DRM display mode
   5653   1.3  riastrad  * @frame: HDMI vendor infoframe
   5654   1.9  riastrad  * @connector: the connector
   5655   1.3  riastrad  * @mode: DRM display mode
   5656   1.3  riastrad  *
   5657   1.3  riastrad  * Note that there's is a need to send HDMI vendor infoframes only when using a
   5658   1.3  riastrad  * 4k or stereoscopic 3D mode. So when giving any other mode as input this
   5659   1.3  riastrad  * function will return -EINVAL, error that can be safely ignored.
   5660   1.3  riastrad  *
   5661   1.6  riastrad  * Return: 0 on success or a negative error code on failure.
   5662   1.3  riastrad  */
   5663   1.3  riastrad int
   5664   1.3  riastrad drm_hdmi_vendor_infoframe_from_display_mode(struct hdmi_vendor_infoframe *frame,
   5665   1.9  riastrad 					    struct drm_connector *connector,
   5666   1.3  riastrad 					    const struct drm_display_mode *mode)
   5667   1.3  riastrad {
   5668   1.9  riastrad 	/*
   5669   1.9  riastrad 	 * FIXME: sil-sii8620 doesn't have a connector around when
   5670   1.9  riastrad 	 * we need one, so we have to be prepared for a NULL connector.
   5671   1.9  riastrad 	 */
   5672   1.9  riastrad 	bool has_hdmi_infoframe = connector ?
   5673   1.9  riastrad 		connector->display_info.has_hdmi_infoframe : false;
   5674   1.3  riastrad 	int err;
   5675   1.3  riastrad 
   5676   1.3  riastrad 	if (!frame || !mode)
   5677   1.3  riastrad 		return -EINVAL;
   5678   1.3  riastrad 
   5679   1.9  riastrad 	if (!has_hdmi_infoframe)
   5680   1.3  riastrad 		return -EINVAL;
   5681   1.3  riastrad 
   5682   1.3  riastrad 	err = hdmi_vendor_infoframe_init(frame);
   5683   1.3  riastrad 	if (err < 0)
   5684   1.3  riastrad 		return err;
   5685   1.3  riastrad 
   5686   1.9  riastrad 	/*
   5687   1.9  riastrad 	 * Even if it's not absolutely necessary to send the infoframe
   5688   1.9  riastrad 	 * (ie.vic==0 and s3d_struct==0) we will still send it if we
   5689   1.9  riastrad 	 * know that the sink can handle it. This is based on a
   5690   1.9  riastrad 	 * suggestion in HDMI 2.0 Appendix F. Apparently some sinks
   5691   1.9  riastrad 	 * have trouble realizing that they shuld switch from 3D to 2D
   5692   1.9  riastrad 	 * mode if the source simply stops sending the infoframe when
   5693   1.9  riastrad 	 * it wants to switch from 3D to 2D.
   5694   1.9  riastrad 	 */
   5695   1.9  riastrad 	frame->vic = drm_mode_hdmi_vic(connector, mode);
   5696   1.9  riastrad 	frame->s3d_struct = s3d_structure_from_display_mode(mode);
   5697   1.1  riastrad 
   5698   1.1  riastrad 	return 0;
   5699   1.1  riastrad }
   5700   1.3  riastrad EXPORT_SYMBOL(drm_hdmi_vendor_infoframe_from_display_mode);
   5701   1.6  riastrad 
   5702   1.9  riastrad static int drm_parse_tiled_block(struct drm_connector *connector,
   5703  1.13  riastrad 				 const struct displayid_block *block)
   5704   1.9  riastrad {
   5705  1.13  riastrad 	const struct displayid_tiled_block *tile = (const struct displayid_tiled_block *)block;
   5706   1.9  riastrad 	u16 w, h;
   5707   1.9  riastrad 	u8 tile_v_loc, tile_h_loc;
   5708   1.9  riastrad 	u8 num_v_tile, num_h_tile;
   5709   1.9  riastrad 	struct drm_tile_group *tg;
   5710   1.9  riastrad 
   5711   1.9  riastrad 	w = tile->tile_size[0] | tile->tile_size[1] << 8;
   5712   1.9  riastrad 	h = tile->tile_size[2] | tile->tile_size[3] << 8;
   5713   1.9  riastrad 
   5714   1.9  riastrad 	num_v_tile = (tile->topo[0] & 0xf) | (tile->topo[2] & 0x30);
   5715   1.9  riastrad 	num_h_tile = (tile->topo[0] >> 4) | ((tile->topo[2] >> 2) & 0x30);
   5716   1.9  riastrad 	tile_v_loc = (tile->topo[1] & 0xf) | ((tile->topo[2] & 0x3) << 4);
   5717   1.9  riastrad 	tile_h_loc = (tile->topo[1] >> 4) | (((tile->topo[2] >> 2) & 0x3) << 4);
   5718   1.9  riastrad 
   5719   1.9  riastrad 	connector->has_tile = true;
   5720   1.9  riastrad 	if (tile->tile_cap & 0x80)
   5721   1.9  riastrad 		connector->tile_is_single_monitor = true;
   5722   1.9  riastrad 
   5723   1.9  riastrad 	connector->num_h_tile = num_h_tile + 1;
   5724   1.9  riastrad 	connector->num_v_tile = num_v_tile + 1;
   5725   1.9  riastrad 	connector->tile_h_loc = tile_h_loc;
   5726   1.9  riastrad 	connector->tile_v_loc = tile_v_loc;
   5727   1.9  riastrad 	connector->tile_h_size = w + 1;
   5728   1.9  riastrad 	connector->tile_v_size = h + 1;
   5729   1.9  riastrad 
   5730   1.9  riastrad 	DRM_DEBUG_KMS("tile cap 0x%x\n", tile->tile_cap);
   5731   1.9  riastrad 	DRM_DEBUG_KMS("tile_size %d x %d\n", w + 1, h + 1);
   5732   1.9  riastrad 	DRM_DEBUG_KMS("topo num tiles %dx%d, location %dx%d\n",
   5733   1.9  riastrad 		      num_h_tile + 1, num_v_tile + 1, tile_h_loc, tile_v_loc);
   5734   1.9  riastrad 	DRM_DEBUG_KMS("vend %c%c%c\n", tile->topology_id[0], tile->topology_id[1], tile->topology_id[2]);
   5735   1.9  riastrad 
   5736   1.9  riastrad 	tg = drm_mode_get_tile_group(connector->dev, tile->topology_id);
   5737   1.9  riastrad 	if (!tg) {
   5738   1.9  riastrad 		tg = drm_mode_create_tile_group(connector->dev, tile->topology_id);
   5739   1.9  riastrad 	}
   5740   1.9  riastrad 	if (!tg)
   5741   1.9  riastrad 		return -ENOMEM;
   5742   1.9  riastrad 
   5743   1.9  riastrad 	if (connector->tile_group != tg) {
   5744   1.9  riastrad 		/* if we haven't got a pointer,
   5745   1.9  riastrad 		   take the reference, drop ref to old tile group */
   5746   1.9  riastrad 		if (connector->tile_group) {
   5747   1.9  riastrad 			drm_mode_put_tile_group(connector->dev, connector->tile_group);
   5748   1.9  riastrad 		}
   5749   1.9  riastrad 		connector->tile_group = tg;
   5750   1.9  riastrad 	} else
   5751   1.9  riastrad 		/* if same tile group, then release the ref we just took. */
   5752   1.9  riastrad 		drm_mode_put_tile_group(connector->dev, tg);
   5753   1.9  riastrad 	return 0;
   5754   1.9  riastrad }
   5755   1.9  riastrad 
   5756   1.6  riastrad static int drm_parse_display_id(struct drm_connector *connector,
   5757  1.13  riastrad 				const u8 *displayid, int length,
   5758   1.6  riastrad 				bool is_edid_extension)
   5759   1.6  riastrad {
   5760   1.6  riastrad 	/* if this is an EDID extension the first byte will be 0x70 */
   5761   1.6  riastrad 	int idx = 0;
   5762  1.13  riastrad 	const struct displayid_block *block;
   5763   1.9  riastrad 	int ret;
   5764   1.6  riastrad 
   5765   1.6  riastrad 	if (is_edid_extension)
   5766   1.6  riastrad 		idx = 1;
   5767   1.6  riastrad 
   5768   1.9  riastrad 	ret = validate_displayid(displayid, length, idx);
   5769   1.9  riastrad 	if (ret)
   5770   1.9  riastrad 		return ret;
   5771   1.6  riastrad 
   5772   1.9  riastrad 	idx += sizeof(struct displayid_hdr);
   5773   1.9  riastrad 	for_each_displayid_db(displayid, block, idx, length) {
   5774   1.9  riastrad 		DRM_DEBUG_KMS("block id 0x%x, rev %d, len %d\n",
   5775   1.9  riastrad 			      block->tag, block->rev, block->num_bytes);
   5776   1.9  riastrad 
   5777   1.9  riastrad 		switch (block->tag) {
   5778   1.9  riastrad 		case DATA_BLOCK_TILED_DISPLAY:
   5779   1.9  riastrad 			ret = drm_parse_tiled_block(connector, block);
   5780   1.9  riastrad 			if (ret)
   5781   1.9  riastrad 				return ret;
   5782   1.9  riastrad 			break;
   5783   1.9  riastrad 		case DATA_BLOCK_TYPE_1_DETAILED_TIMING:
   5784   1.9  riastrad 			/* handled in mode gathering code. */
   5785   1.9  riastrad 			break;
   5786   1.9  riastrad 		case DATA_BLOCK_CTA:
   5787   1.9  riastrad 			/* handled in the cea parser code. */
   5788   1.9  riastrad 			break;
   5789   1.9  riastrad 		default:
   5790   1.9  riastrad 			DRM_DEBUG_KMS("found DisplayID tag 0x%x, unhandled\n", block->tag);
   5791   1.9  riastrad 			break;
   5792   1.9  riastrad 		}
   5793   1.6  riastrad 	}
   5794   1.6  riastrad 	return 0;
   5795   1.6  riastrad }
   5796   1.6  riastrad 
   5797   1.6  riastrad static void drm_get_displayid(struct drm_connector *connector,
   5798   1.6  riastrad 			      struct edid *edid)
   5799   1.6  riastrad {
   5800  1.13  riastrad 	const void *displayid = NULL;
   5801   1.6  riastrad 	int ret;
   5802   1.6  riastrad 	connector->has_tile = false;
   5803   1.6  riastrad 	displayid = drm_find_displayid_extension(edid);
   5804   1.6  riastrad 	if (!displayid) {
   5805   1.6  riastrad 		/* drop reference to any tile group we had */
   5806   1.6  riastrad 		goto out_drop_ref;
   5807   1.6  riastrad 	}
   5808   1.6  riastrad 
   5809   1.6  riastrad 	ret = drm_parse_display_id(connector, displayid, EDID_LENGTH, true);
   5810   1.6  riastrad 	if (ret < 0)
   5811   1.6  riastrad 		goto out_drop_ref;
   5812   1.6  riastrad 	if (!connector->has_tile)
   5813   1.6  riastrad 		goto out_drop_ref;
   5814   1.6  riastrad 	return;
   5815   1.6  riastrad out_drop_ref:
   5816   1.6  riastrad 	if (connector->tile_group) {
   5817   1.6  riastrad 		drm_mode_put_tile_group(connector->dev, connector->tile_group);
   5818   1.6  riastrad 		connector->tile_group = NULL;
   5819   1.6  riastrad 	}
   5820   1.6  riastrad 	return;
   5821   1.6  riastrad }
   5822