LCOV - code coverage report
Current view: top level - drivers/gpu/drm - drm_edid.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 66 2053 3.2 %
Date: 2023-03-27 20:00:47 Functions: 5 153 3.3 %

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

Generated by: LCOV version 1.14