LCOV - code coverage report
Current view: top level - drivers/gpu/drm - drm_edid.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 1715 0.0 %
Date: 2022-12-09 01:23:36 Functions: 0 109 0.0 %

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

Generated by: LCOV version 1.14