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

Generated by: LCOV version 1.14