LCOV - code coverage report
Current view: top level - drivers/gpu/drm - drm_edid.c (source / functions) Hit Total Coverage
Test: combined.info Lines: 0 1633 0.0 %
Date: 2022-03-28 16:04:14 Functions: 0 90 0.0 %
Branches: 0 1223 0.0 %

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

Generated by: LCOV version 1.14