LCOV - code coverage report
Current view: top level - dev/pci/drm - drm_edid.c (source / functions) Hit Total Coverage
Test: 6.4 Lines: 0 1385 0.0 %
Date: 2018-10-19 03:25:38 Functions: 0 95 0.0 %
Legend: Lines: hit not hit

          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             : #ifdef __linux__
      31             : #include <linux/kernel.h>
      32             : #include <linux/slab.h>
      33             : #include <linux/hdmi.h>
      34             : #include <linux/i2c.h>
      35             : #include <linux/module.h>
      36             : #endif
      37             : #include <dev/pci/drm/drmP.h>
      38             : #include <dev/pci/drm/drm_edid.h>
      39             : #include <dev/pci/drm/drm_displayid.h>
      40             : 
      41             : #define version_greater(edid, maj, min) \
      42             :         (((edid)->version > (maj)) || \
      43             :          ((edid)->version == (maj) && (edid)->revision > (min)))
      44             : 
      45             : #define EDID_EST_TIMINGS 16
      46             : #define EDID_STD_TIMINGS 8
      47             : #define EDID_DETAILED_TIMINGS 4
      48             : 
      49             : /*
      50             :  * EDID blocks out in the wild have a variety of bugs, try to collect
      51             :  * them here (note that userspace may work around broken monitors first,
      52             :  * but fixes should make their way here so that the kernel "just works"
      53             :  * on as many displays as possible).
      54             :  */
      55             : 
      56             : /* First detailed mode wrong, use largest 60Hz mode */
      57             : #define EDID_QUIRK_PREFER_LARGE_60              (1 << 0)
      58             : /* Reported 135MHz pixel clock is too high, needs adjustment */
      59             : #define EDID_QUIRK_135_CLOCK_TOO_HIGH           (1 << 1)
      60             : /* Prefer the largest mode at 75 Hz */
      61             : #define EDID_QUIRK_PREFER_LARGE_75              (1 << 2)
      62             : /* Detail timing is in cm not mm */
      63             : #define EDID_QUIRK_DETAILED_IN_CM               (1 << 3)
      64             : /* Detailed timing descriptors have bogus size values, so just take the
      65             :  * maximum size and use that.
      66             :  */
      67             : #define EDID_QUIRK_DETAILED_USE_MAXIMUM_SIZE    (1 << 4)
      68             : /* Monitor forgot to set the first detailed is preferred bit. */
      69             : #define EDID_QUIRK_FIRST_DETAILED_PREFERRED     (1 << 5)
      70             : /* use +hsync +vsync for detailed mode */
      71             : #define EDID_QUIRK_DETAILED_SYNC_PP             (1 << 6)
      72             : /* Force reduced-blanking timings for detailed modes */
      73             : #define EDID_QUIRK_FORCE_REDUCED_BLANKING       (1 << 7)
      74             : /* Force 8bpc */
      75             : #define EDID_QUIRK_FORCE_8BPC                   (1 << 8)
      76             : /* Force 12bpc */
      77             : #define EDID_QUIRK_FORCE_12BPC                  (1 << 9)
      78             : /* Force 6bpc */
      79             : #define EDID_QUIRK_FORCE_6BPC                   (1 << 10)
      80             : /* Force 10bpc */
      81             : #define EDID_QUIRK_FORCE_10BPC                  (1 << 11)
      82             : 
      83             : struct detailed_mode_closure {
      84             :         struct drm_connector *connector;
      85             :         struct edid *edid;
      86             :         bool preferred;
      87             :         u32 quirks;
      88             :         int modes;
      89             : };
      90             : 
      91             : #define LEVEL_DMT       0
      92             : #define LEVEL_GTF       1
      93             : #define LEVEL_GTF2      2
      94             : #define LEVEL_CVT       3
      95             : 
      96             : static struct edid_quirk {
      97             :         char vendor[4];
      98             :         int product_id;
      99             :         u32 quirks;
     100             : } edid_quirk_list[] = {
     101             :         /* Acer AL1706 */
     102             :         { "ACR", 44358, EDID_QUIRK_PREFER_LARGE_60 },
     103             :         /* Acer F51 */
     104             :         { "API", 0x7602, EDID_QUIRK_PREFER_LARGE_60 },
     105             :         /* Unknown Acer */
     106             :         { "ACR", 2423, EDID_QUIRK_FIRST_DETAILED_PREFERRED },
     107             : 
     108             :         /* AEO model 0 reports 8 bpc, but is a 6 bpc panel */
     109             :         { "AEO", 0, EDID_QUIRK_FORCE_6BPC },
     110             : 
     111             :         /* CPT panel of Asus UX303LA reports 8 bpc, but is a 6 bpc panel */
     112             :         { "CPT", 0x17df, EDID_QUIRK_FORCE_6BPC },
     113             : 
     114             :         /* Belinea 10 15 55 */
     115             :         { "MAX", 1516, EDID_QUIRK_PREFER_LARGE_60 },
     116             :         { "MAX", 0x77e, EDID_QUIRK_PREFER_LARGE_60 },
     117             : 
     118             :         /* Envision Peripherals, Inc. EN-7100e */
     119             :         { "EPI", 59264, EDID_QUIRK_135_CLOCK_TOO_HIGH },
     120             :         /* Envision EN2028 */
     121             :         { "EPI", 8232, EDID_QUIRK_PREFER_LARGE_60 },
     122             : 
     123             :         /* Funai Electronics PM36B */
     124             :         { "FCM", 13600, EDID_QUIRK_PREFER_LARGE_75 |
     125             :           EDID_QUIRK_DETAILED_IN_CM },
     126             : 
     127             :         /* LGD panel of HP zBook 17 G2, eDP 10 bpc, but reports unknown bpc */
     128             :         { "LGD", 764, EDID_QUIRK_FORCE_10BPC },
     129             : 
     130             :         /* LG Philips LCD LP154W01-A5 */
     131             :         { "LPL", 0, EDID_QUIRK_DETAILED_USE_MAXIMUM_SIZE },
     132             :         { "LPL", 0x2a00, EDID_QUIRK_DETAILED_USE_MAXIMUM_SIZE },
     133             : 
     134             :         /* Philips 107p5 CRT */
     135             :         { "PHL", 57364, EDID_QUIRK_FIRST_DETAILED_PREFERRED },
     136             : 
     137             :         /* Proview AY765C */
     138             :         { "PTS", 765, EDID_QUIRK_FIRST_DETAILED_PREFERRED },
     139             : 
     140             :         /* Samsung SyncMaster 205BW.  Note: irony */
     141             :         { "SAM", 541, EDID_QUIRK_DETAILED_SYNC_PP },
     142             :         /* Samsung SyncMaster 22[5-6]BW */
     143             :         { "SAM", 596, EDID_QUIRK_PREFER_LARGE_60 },
     144             :         { "SAM", 638, EDID_QUIRK_PREFER_LARGE_60 },
     145             : 
     146             :         /* Sony PVM-2541A does up to 12 bpc, but only reports max 8 bpc */
     147             :         { "SNY", 0x2541, EDID_QUIRK_FORCE_12BPC },
     148             : 
     149             :         /* ViewSonic VA2026w */
     150             :         { "VSC", 5020, EDID_QUIRK_FORCE_REDUCED_BLANKING },
     151             : 
     152             :         /* Medion MD 30217 PG */
     153             :         { "MED", 0x7b8, EDID_QUIRK_PREFER_LARGE_75 },
     154             : 
     155             :         /* Panel in Samsung NP700G7A-S01PL notebook reports 6bpc */
     156             :         { "SEC", 0xd033, EDID_QUIRK_FORCE_8BPC },
     157             : 
     158             :         /* Rotel RSX-1058 forwards sink's EDID but only does HDMI 1.1*/
     159             :         { "ETR", 13896, EDID_QUIRK_FORCE_8BPC },
     160             : };
     161             : 
     162             : /*
     163             :  * Autogenerated from the DMT spec.
     164             :  * This table is copied from xfree86/modes/xf86EdidModes.c.
     165             :  */
     166             : static const struct drm_display_mode drm_dmt_modes[] = {
     167             :         /* 0x01 - 640x350@85Hz */
     168             :         { DRM_MODE("640x350", DRM_MODE_TYPE_DRIVER, 31500, 640, 672,
     169             :                    736, 832, 0, 350, 382, 385, 445, 0,
     170             :                    DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
     171             :         /* 0x02 - 640x400@85Hz */
     172             :         { DRM_MODE("640x400", DRM_MODE_TYPE_DRIVER, 31500, 640, 672,
     173             :                    736, 832, 0, 400, 401, 404, 445, 0,
     174             :                    DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
     175             :         /* 0x03 - 720x400@85Hz */
     176             :         { DRM_MODE("720x400", DRM_MODE_TYPE_DRIVER, 35500, 720, 756,
     177             :                    828, 936, 0, 400, 401, 404, 446, 0,
     178             :                    DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
     179             :         /* 0x04 - 640x480@60Hz */
     180             :         { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 25175, 640, 656,
     181             :                    752, 800, 0, 480, 490, 492, 525, 0,
     182             :                    DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
     183             :         /* 0x05 - 640x480@72Hz */
     184             :         { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 31500, 640, 664,
     185             :                    704, 832, 0, 480, 489, 492, 520, 0,
     186             :                    DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
     187             :         /* 0x06 - 640x480@75Hz */
     188             :         { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 31500, 640, 656,
     189             :                    720, 840, 0, 480, 481, 484, 500, 0,
     190             :                    DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
     191             :         /* 0x07 - 640x480@85Hz */
     192             :         { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 36000, 640, 696,
     193             :                    752, 832, 0, 480, 481, 484, 509, 0,
     194             :                    DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
     195             :         /* 0x08 - 800x600@56Hz */
     196             :         { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 36000, 800, 824,
     197             :                    896, 1024, 0, 600, 601, 603, 625, 0,
     198             :                    DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
     199             :         /* 0x09 - 800x600@60Hz */
     200             :         { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 40000, 800, 840,
     201             :                    968, 1056, 0, 600, 601, 605, 628, 0,
     202             :                    DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
     203             :         /* 0x0a - 800x600@72Hz */
     204             :         { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 50000, 800, 856,
     205             :                    976, 1040, 0, 600, 637, 643, 666, 0,
     206             :                    DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
     207             :         /* 0x0b - 800x600@75Hz */
     208             :         { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 49500, 800, 816,
     209             :                    896, 1056, 0, 600, 601, 604, 625, 0,
     210             :                    DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
     211             :         /* 0x0c - 800x600@85Hz */
     212             :         { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 56250, 800, 832,
     213             :                    896, 1048, 0, 600, 601, 604, 631, 0,
     214             :                    DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
     215             :         /* 0x0d - 800x600@120Hz RB */
     216             :         { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 73250, 800, 848,
     217             :                    880, 960, 0, 600, 603, 607, 636, 0,
     218             :                    DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
     219             :         /* 0x0e - 848x480@60Hz */
     220             :         { DRM_MODE("848x480", DRM_MODE_TYPE_DRIVER, 33750, 848, 864,
     221             :                    976, 1088, 0, 480, 486, 494, 517, 0,
     222             :                    DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
     223             :         /* 0x0f - 1024x768@43Hz, interlace */
     224             :         { DRM_MODE("1024x768i", DRM_MODE_TYPE_DRIVER, 44900, 1024, 1032,
     225             :                    1208, 1264, 0, 768, 768, 772, 817, 0,
     226             :                    DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC |
     227             :                    DRM_MODE_FLAG_INTERLACE) },
     228             :         /* 0x10 - 1024x768@60Hz */
     229             :         { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 65000, 1024, 1048,
     230             :                    1184, 1344, 0, 768, 771, 777, 806, 0,
     231             :                    DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
     232             :         /* 0x11 - 1024x768@70Hz */
     233             :         { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 75000, 1024, 1048,
     234             :                    1184, 1328, 0, 768, 771, 777, 806, 0,
     235             :                    DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
     236             :         /* 0x12 - 1024x768@75Hz */
     237             :         { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 78750, 1024, 1040,
     238             :                    1136, 1312, 0, 768, 769, 772, 800, 0,
     239             :                    DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
     240             :         /* 0x13 - 1024x768@85Hz */
     241             :         { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 94500, 1024, 1072,
     242             :                    1168, 1376, 0, 768, 769, 772, 808, 0,
     243             :                    DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
     244             :         /* 0x14 - 1024x768@120Hz RB */
     245             :         { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 115500, 1024, 1072,
     246             :                    1104, 1184, 0, 768, 771, 775, 813, 0,
     247             :                    DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
     248             :         /* 0x15 - 1152x864@75Hz */
     249             :         { DRM_MODE("1152x864", DRM_MODE_TYPE_DRIVER, 108000, 1152, 1216,
     250             :                    1344, 1600, 0, 864, 865, 868, 900, 0,
     251             :                    DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
     252             :         /* 0x55 - 1280x720@60Hz */
     253             :         { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 74250, 1280, 1390,
     254             :                    1430, 1650, 0, 720, 725, 730, 750, 0,
     255             :                    DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
     256             :         /* 0x16 - 1280x768@60Hz RB */
     257             :         { DRM_MODE("1280x768", DRM_MODE_TYPE_DRIVER, 68250, 1280, 1328,
     258             :                    1360, 1440, 0, 768, 771, 778, 790, 0,
     259             :                    DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
     260             :         /* 0x17 - 1280x768@60Hz */
     261             :         { DRM_MODE("1280x768", DRM_MODE_TYPE_DRIVER, 79500, 1280, 1344,
     262             :                    1472, 1664, 0, 768, 771, 778, 798, 0,
     263             :                    DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
     264             :         /* 0x18 - 1280x768@75Hz */
     265             :         { DRM_MODE("1280x768", DRM_MODE_TYPE_DRIVER, 102250, 1280, 1360,
     266             :                    1488, 1696, 0, 768, 771, 778, 805, 0,
     267             :                    DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
     268             :         /* 0x19 - 1280x768@85Hz */
     269             :         { DRM_MODE("1280x768", DRM_MODE_TYPE_DRIVER, 117500, 1280, 1360,
     270             :                    1496, 1712, 0, 768, 771, 778, 809, 0,
     271             :                    DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
     272             :         /* 0x1a - 1280x768@120Hz RB */
     273             :         { DRM_MODE("1280x768", DRM_MODE_TYPE_DRIVER, 140250, 1280, 1328,
     274             :                    1360, 1440, 0, 768, 771, 778, 813, 0,
     275             :                    DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
     276             :         /* 0x1b - 1280x800@60Hz RB */
     277             :         { DRM_MODE("1280x800", DRM_MODE_TYPE_DRIVER, 71000, 1280, 1328,
     278             :                    1360, 1440, 0, 800, 803, 809, 823, 0,
     279             :                    DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
     280             :         /* 0x1c - 1280x800@60Hz */
     281             :         { DRM_MODE("1280x800", DRM_MODE_TYPE_DRIVER, 83500, 1280, 1352,
     282             :                    1480, 1680, 0, 800, 803, 809, 831, 0,
     283             :                    DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
     284             :         /* 0x1d - 1280x800@75Hz */
     285             :         { DRM_MODE("1280x800", DRM_MODE_TYPE_DRIVER, 106500, 1280, 1360,
     286             :                    1488, 1696, 0, 800, 803, 809, 838, 0,
     287             :                    DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
     288             :         /* 0x1e - 1280x800@85Hz */
     289             :         { DRM_MODE("1280x800", DRM_MODE_TYPE_DRIVER, 122500, 1280, 1360,
     290             :                    1496, 1712, 0, 800, 803, 809, 843, 0,
     291             :                    DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
     292             :         /* 0x1f - 1280x800@120Hz RB */
     293             :         { DRM_MODE("1280x800", DRM_MODE_TYPE_DRIVER, 146250, 1280, 1328,
     294             :                    1360, 1440, 0, 800, 803, 809, 847, 0,
     295             :                    DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
     296             :         /* 0x20 - 1280x960@60Hz */
     297             :         { DRM_MODE("1280x960", DRM_MODE_TYPE_DRIVER, 108000, 1280, 1376,
     298             :                    1488, 1800, 0, 960, 961, 964, 1000, 0,
     299             :                    DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
     300             :         /* 0x21 - 1280x960@85Hz */
     301             :         { DRM_MODE("1280x960", DRM_MODE_TYPE_DRIVER, 148500, 1280, 1344,
     302             :                    1504, 1728, 0, 960, 961, 964, 1011, 0,
     303             :                    DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
     304             :         /* 0x22 - 1280x960@120Hz RB */
     305             :         { DRM_MODE("1280x960", DRM_MODE_TYPE_DRIVER, 175500, 1280, 1328,
     306             :                    1360, 1440, 0, 960, 963, 967, 1017, 0,
     307             :                    DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
     308             :         /* 0x23 - 1280x1024@60Hz */
     309             :         { DRM_MODE("1280x1024", DRM_MODE_TYPE_DRIVER, 108000, 1280, 1328,
     310             :                    1440, 1688, 0, 1024, 1025, 1028, 1066, 0,
     311             :                    DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
     312             :         /* 0x24 - 1280x1024@75Hz */
     313             :         { DRM_MODE("1280x1024", DRM_MODE_TYPE_DRIVER, 135000, 1280, 1296,
     314             :                    1440, 1688, 0, 1024, 1025, 1028, 1066, 0,
     315             :                    DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
     316             :         /* 0x25 - 1280x1024@85Hz */
     317             :         { DRM_MODE("1280x1024", DRM_MODE_TYPE_DRIVER, 157500, 1280, 1344,
     318             :                    1504, 1728, 0, 1024, 1025, 1028, 1072, 0,
     319             :                    DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
     320             :         /* 0x26 - 1280x1024@120Hz RB */
     321             :         { DRM_MODE("1280x1024", DRM_MODE_TYPE_DRIVER, 187250, 1280, 1328,
     322             :                    1360, 1440, 0, 1024, 1027, 1034, 1084, 0,
     323             :                    DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
     324             :         /* 0x27 - 1360x768@60Hz */
     325             :         { DRM_MODE("1360x768", DRM_MODE_TYPE_DRIVER, 85500, 1360, 1424,
     326             :                    1536, 1792, 0, 768, 771, 777, 795, 0,
     327             :                    DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
     328             :         /* 0x28 - 1360x768@120Hz RB */
     329             :         { DRM_MODE("1360x768", DRM_MODE_TYPE_DRIVER, 148250, 1360, 1408,
     330             :                    1440, 1520, 0, 768, 771, 776, 813, 0,
     331             :                    DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
     332             :         /* 0x51 - 1366x768@60Hz */
     333             :         { DRM_MODE("1366x768", DRM_MODE_TYPE_DRIVER, 85500, 1366, 1436,
     334             :                    1579, 1792, 0, 768, 771, 774, 798, 0,
     335             :                    DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
     336             :         /* 0x56 - 1366x768@60Hz */
     337             :         { DRM_MODE("1366x768", DRM_MODE_TYPE_DRIVER, 72000, 1366, 1380,
     338             :                    1436, 1500, 0, 768, 769, 772, 800, 0,
     339             :                    DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
     340             :         /* 0x29 - 1400x1050@60Hz RB */
     341             :         { DRM_MODE("1400x1050", DRM_MODE_TYPE_DRIVER, 101000, 1400, 1448,
     342             :                    1480, 1560, 0, 1050, 1053, 1057, 1080, 0,
     343             :                    DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
     344             :         /* 0x2a - 1400x1050@60Hz */
     345             :         { DRM_MODE("1400x1050", DRM_MODE_TYPE_DRIVER, 121750, 1400, 1488,
     346             :                    1632, 1864, 0, 1050, 1053, 1057, 1089, 0,
     347             :                    DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
     348             :         /* 0x2b - 1400x1050@75Hz */
     349             :         { DRM_MODE("1400x1050", DRM_MODE_TYPE_DRIVER, 156000, 1400, 1504,
     350             :                    1648, 1896, 0, 1050, 1053, 1057, 1099, 0,
     351             :                    DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
     352             :         /* 0x2c - 1400x1050@85Hz */
     353             :         { DRM_MODE("1400x1050", DRM_MODE_TYPE_DRIVER, 179500, 1400, 1504,
     354             :                    1656, 1912, 0, 1050, 1053, 1057, 1105, 0,
     355             :                    DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
     356             :         /* 0x2d - 1400x1050@120Hz RB */
     357             :         { DRM_MODE("1400x1050", DRM_MODE_TYPE_DRIVER, 208000, 1400, 1448,
     358             :                    1480, 1560, 0, 1050, 1053, 1057, 1112, 0,
     359             :                    DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
     360             :         /* 0x2e - 1440x900@60Hz RB */
     361             :         { DRM_MODE("1440x900", DRM_MODE_TYPE_DRIVER, 88750, 1440, 1488,
     362             :                    1520, 1600, 0, 900, 903, 909, 926, 0,
     363             :                    DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
     364             :         /* 0x2f - 1440x900@60Hz */
     365             :         { DRM_MODE("1440x900", DRM_MODE_TYPE_DRIVER, 106500, 1440, 1520,
     366             :                    1672, 1904, 0, 900, 903, 909, 934, 0,
     367             :                    DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
     368             :         /* 0x30 - 1440x900@75Hz */
     369             :         { DRM_MODE("1440x900", DRM_MODE_TYPE_DRIVER, 136750, 1440, 1536,
     370             :                    1688, 1936, 0, 900, 903, 909, 942, 0,
     371             :                    DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
     372             :         /* 0x31 - 1440x900@85Hz */
     373             :         { DRM_MODE("1440x900", DRM_MODE_TYPE_DRIVER, 157000, 1440, 1544,
     374             :                    1696, 1952, 0, 900, 903, 909, 948, 0,
     375             :                    DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
     376             :         /* 0x32 - 1440x900@120Hz RB */
     377             :         { DRM_MODE("1440x900", DRM_MODE_TYPE_DRIVER, 182750, 1440, 1488,
     378             :                    1520, 1600, 0, 900, 903, 909, 953, 0,
     379             :                    DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
     380             :         /* 0x53 - 1600x900@60Hz */
     381             :         { DRM_MODE("1600x900", DRM_MODE_TYPE_DRIVER, 108000, 1600, 1624,
     382             :                    1704, 1800, 0, 900, 901, 904, 1000, 0,
     383             :                    DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
     384             :         /* 0x33 - 1600x1200@60Hz */
     385             :         { DRM_MODE("1600x1200", DRM_MODE_TYPE_DRIVER, 162000, 1600, 1664,
     386             :                    1856, 2160, 0, 1200, 1201, 1204, 1250, 0,
     387             :                    DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
     388             :         /* 0x34 - 1600x1200@65Hz */
     389             :         { DRM_MODE("1600x1200", DRM_MODE_TYPE_DRIVER, 175500, 1600, 1664,
     390             :                    1856, 2160, 0, 1200, 1201, 1204, 1250, 0,
     391             :                    DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
     392             :         /* 0x35 - 1600x1200@70Hz */
     393             :         { DRM_MODE("1600x1200", DRM_MODE_TYPE_DRIVER, 189000, 1600, 1664,
     394             :                    1856, 2160, 0, 1200, 1201, 1204, 1250, 0,
     395             :                    DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
     396             :         /* 0x36 - 1600x1200@75Hz */
     397             :         { DRM_MODE("1600x1200", DRM_MODE_TYPE_DRIVER, 202500, 1600, 1664,
     398             :                    1856, 2160, 0, 1200, 1201, 1204, 1250, 0,
     399             :                    DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
     400             :         /* 0x37 - 1600x1200@85Hz */
     401             :         { DRM_MODE("1600x1200", DRM_MODE_TYPE_DRIVER, 229500, 1600, 1664,
     402             :                    1856, 2160, 0, 1200, 1201, 1204, 1250, 0,
     403             :                    DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
     404             :         /* 0x38 - 1600x1200@120Hz RB */
     405             :         { DRM_MODE("1600x1200", DRM_MODE_TYPE_DRIVER, 268250, 1600, 1648,
     406             :                    1680, 1760, 0, 1200, 1203, 1207, 1271, 0,
     407             :                    DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
     408             :         /* 0x39 - 1680x1050@60Hz RB */
     409             :         { DRM_MODE("1680x1050", DRM_MODE_TYPE_DRIVER, 119000, 1680, 1728,
     410             :                    1760, 1840, 0, 1050, 1053, 1059, 1080, 0,
     411             :                    DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
     412             :         /* 0x3a - 1680x1050@60Hz */
     413             :         { DRM_MODE("1680x1050", DRM_MODE_TYPE_DRIVER, 146250, 1680, 1784,
     414             :                    1960, 2240, 0, 1050, 1053, 1059, 1089, 0,
     415             :                    DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
     416             :         /* 0x3b - 1680x1050@75Hz */
     417             :         { DRM_MODE("1680x1050", DRM_MODE_TYPE_DRIVER, 187000, 1680, 1800,
     418             :                    1976, 2272, 0, 1050, 1053, 1059, 1099, 0,
     419             :                    DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
     420             :         /* 0x3c - 1680x1050@85Hz */
     421             :         { DRM_MODE("1680x1050", DRM_MODE_TYPE_DRIVER, 214750, 1680, 1808,
     422             :                    1984, 2288, 0, 1050, 1053, 1059, 1105, 0,
     423             :                    DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
     424             :         /* 0x3d - 1680x1050@120Hz RB */
     425             :         { DRM_MODE("1680x1050", DRM_MODE_TYPE_DRIVER, 245500, 1680, 1728,
     426             :                    1760, 1840, 0, 1050, 1053, 1059, 1112, 0,
     427             :                    DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
     428             :         /* 0x3e - 1792x1344@60Hz */
     429             :         { DRM_MODE("1792x1344", DRM_MODE_TYPE_DRIVER, 204750, 1792, 1920,
     430             :                    2120, 2448, 0, 1344, 1345, 1348, 1394, 0,
     431             :                    DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
     432             :         /* 0x3f - 1792x1344@75Hz */
     433             :         { DRM_MODE("1792x1344", DRM_MODE_TYPE_DRIVER, 261000, 1792, 1888,
     434             :                    2104, 2456, 0, 1344, 1345, 1348, 1417, 0,
     435             :                    DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
     436             :         /* 0x40 - 1792x1344@120Hz RB */
     437             :         { DRM_MODE("1792x1344", DRM_MODE_TYPE_DRIVER, 333250, 1792, 1840,
     438             :                    1872, 1952, 0, 1344, 1347, 1351, 1423, 0,
     439             :                    DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
     440             :         /* 0x41 - 1856x1392@60Hz */
     441             :         { DRM_MODE("1856x1392", DRM_MODE_TYPE_DRIVER, 218250, 1856, 1952,
     442             :                    2176, 2528, 0, 1392, 1393, 1396, 1439, 0,
     443             :                    DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
     444             :         /* 0x42 - 1856x1392@75Hz */
     445             :         { DRM_MODE("1856x1392", DRM_MODE_TYPE_DRIVER, 288000, 1856, 1984,
     446             :                    2208, 2560, 0, 1392, 1393, 1396, 1500, 0,
     447             :                    DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
     448             :         /* 0x43 - 1856x1392@120Hz RB */
     449             :         { DRM_MODE("1856x1392", DRM_MODE_TYPE_DRIVER, 356500, 1856, 1904,
     450             :                    1936, 2016, 0, 1392, 1395, 1399, 1474, 0,
     451             :                    DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
     452             :         /* 0x52 - 1920x1080@60Hz */
     453             :         { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 148500, 1920, 2008,
     454             :                    2052, 2200, 0, 1080, 1084, 1089, 1125, 0,
     455             :                    DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
     456             :         /* 0x44 - 1920x1200@60Hz RB */
     457             :         { DRM_MODE("1920x1200", DRM_MODE_TYPE_DRIVER, 154000, 1920, 1968,
     458             :                    2000, 2080, 0, 1200, 1203, 1209, 1235, 0,
     459             :                    DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
     460             :         /* 0x45 - 1920x1200@60Hz */
     461             :         { DRM_MODE("1920x1200", DRM_MODE_TYPE_DRIVER, 193250, 1920, 2056,
     462             :                    2256, 2592, 0, 1200, 1203, 1209, 1245, 0,
     463             :                    DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
     464             :         /* 0x46 - 1920x1200@75Hz */
     465             :         { DRM_MODE("1920x1200", DRM_MODE_TYPE_DRIVER, 245250, 1920, 2056,
     466             :                    2264, 2608, 0, 1200, 1203, 1209, 1255, 0,
     467             :                    DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
     468             :         /* 0x47 - 1920x1200@85Hz */
     469             :         { DRM_MODE("1920x1200", DRM_MODE_TYPE_DRIVER, 281250, 1920, 2064,
     470             :                    2272, 2624, 0, 1200, 1203, 1209, 1262, 0,
     471             :                    DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
     472             :         /* 0x48 - 1920x1200@120Hz RB */
     473             :         { DRM_MODE("1920x1200", DRM_MODE_TYPE_DRIVER, 317000, 1920, 1968,
     474             :                    2000, 2080, 0, 1200, 1203, 1209, 1271, 0,
     475             :                    DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
     476             :         /* 0x49 - 1920x1440@60Hz */
     477             :         { DRM_MODE("1920x1440", DRM_MODE_TYPE_DRIVER, 234000, 1920, 2048,
     478             :                    2256, 2600, 0, 1440, 1441, 1444, 1500, 0,
     479             :                    DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
     480             :         /* 0x4a - 1920x1440@75Hz */
     481             :         { DRM_MODE("1920x1440", DRM_MODE_TYPE_DRIVER, 297000, 1920, 2064,
     482             :                    2288, 2640, 0, 1440, 1441, 1444, 1500, 0,
     483             :                    DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
     484             :         /* 0x4b - 1920x1440@120Hz RB */
     485             :         { DRM_MODE("1920x1440", DRM_MODE_TYPE_DRIVER, 380500, 1920, 1968,
     486             :                    2000, 2080, 0, 1440, 1443, 1447, 1525, 0,
     487             :                    DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
     488             :         /* 0x54 - 2048x1152@60Hz */
     489             :         { DRM_MODE("2048x1152", DRM_MODE_TYPE_DRIVER, 162000, 2048, 2074,
     490             :                    2154, 2250, 0, 1152, 1153, 1156, 1200, 0,
     491             :                    DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
     492             :         /* 0x4c - 2560x1600@60Hz RB */
     493             :         { DRM_MODE("2560x1600", DRM_MODE_TYPE_DRIVER, 268500, 2560, 2608,
     494             :                    2640, 2720, 0, 1600, 1603, 1609, 1646, 0,
     495             :                    DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
     496             :         /* 0x4d - 2560x1600@60Hz */
     497             :         { DRM_MODE("2560x1600", DRM_MODE_TYPE_DRIVER, 348500, 2560, 2752,
     498             :                    3032, 3504, 0, 1600, 1603, 1609, 1658, 0,
     499             :                    DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
     500             :         /* 0x4e - 2560x1600@75Hz */
     501             :         { DRM_MODE("2560x1600", DRM_MODE_TYPE_DRIVER, 443250, 2560, 2768,
     502             :                    3048, 3536, 0, 1600, 1603, 1609, 1672, 0,
     503             :                    DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
     504             :         /* 0x4f - 2560x1600@85Hz */
     505             :         { DRM_MODE("2560x1600", DRM_MODE_TYPE_DRIVER, 505250, 2560, 2768,
     506             :                    3048, 3536, 0, 1600, 1603, 1609, 1682, 0,
     507             :                    DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
     508             :         /* 0x50 - 2560x1600@120Hz RB */
     509             :         { DRM_MODE("2560x1600", DRM_MODE_TYPE_DRIVER, 552750, 2560, 2608,
     510             :                    2640, 2720, 0, 1600, 1603, 1609, 1694, 0,
     511             :                    DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
     512             :         /* 0x57 - 4096x2160@60Hz RB */
     513             :         { DRM_MODE("4096x2160", DRM_MODE_TYPE_DRIVER, 556744, 4096, 4104,
     514             :                    4136, 4176, 0, 2160, 2208, 2216, 2222, 0,
     515             :                    DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
     516             :         /* 0x58 - 4096x2160@59.94Hz RB */
     517             :         { DRM_MODE("4096x2160", DRM_MODE_TYPE_DRIVER, 556188, 4096, 4104,
     518             :                    4136, 4176, 0, 2160, 2208, 2216, 2222, 0,
     519             :                    DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
     520             : };
     521             : 
     522             : /*
     523             :  * These more or less come from the DMT spec.  The 720x400 modes are
     524             :  * inferred from historical 80x25 practice.  The 640x480@67 and 832x624@75
     525             :  * modes are old-school Mac modes.  The EDID spec says the 1152x864@75 mode
     526             :  * should be 1152x870, again for the Mac, but instead we use the x864 DMT
     527             :  * mode.
     528             :  *
     529             :  * The DMT modes have been fact-checked; the rest are mild guesses.
     530             :  */
     531             : static const struct drm_display_mode edid_est_modes[] = {
     532             :         { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 40000, 800, 840,
     533             :                    968, 1056, 0, 600, 601, 605, 628, 0,
     534             :                    DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, /* 800x600@60Hz */
     535             :         { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 36000, 800, 824,
     536             :                    896, 1024, 0, 600, 601, 603,  625, 0,
     537             :                    DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, /* 800x600@56Hz */
     538             :         { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 31500, 640, 656,
     539             :                    720, 840, 0, 480, 481, 484, 500, 0,
     540             :                    DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, /* 640x480@75Hz */
     541             :         { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 31500, 640, 664,
     542             :                    704,  832, 0, 480, 489, 491, 520, 0,
     543             :                    DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, /* 640x480@72Hz */
     544             :         { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 30240, 640, 704,
     545             :                    768,  864, 0, 480, 483, 486, 525, 0,
     546             :                    DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, /* 640x480@67Hz */
     547             :         { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 25200, 640, 656,
     548             :                    752, 800, 0, 480, 490, 492, 525, 0,
     549             :                    DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, /* 640x480@60Hz */
     550             :         { DRM_MODE("720x400", DRM_MODE_TYPE_DRIVER, 35500, 720, 738,
     551             :                    846, 900, 0, 400, 421, 423,  449, 0,
     552             :                    DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, /* 720x400@88Hz */
     553             :         { DRM_MODE("720x400", DRM_MODE_TYPE_DRIVER, 28320, 720, 738,
     554             :                    846,  900, 0, 400, 412, 414, 449, 0,
     555             :                    DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, /* 720x400@70Hz */
     556             :         { DRM_MODE("1280x1024", DRM_MODE_TYPE_DRIVER, 135000, 1280, 1296,
     557             :                    1440, 1688, 0, 1024, 1025, 1028, 1066, 0,
     558             :                    DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, /* 1280x1024@75Hz */
     559             :         { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 78800, 1024, 1040,
     560             :                    1136, 1312, 0,  768, 769, 772, 800, 0,
     561             :                    DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, /* 1024x768@75Hz */
     562             :         { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 75000, 1024, 1048,
     563             :                    1184, 1328, 0,  768, 771, 777, 806, 0,
     564             :                    DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, /* 1024x768@70Hz */
     565             :         { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 65000, 1024, 1048,
     566             :                    1184, 1344, 0,  768, 771, 777, 806, 0,
     567             :                    DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, /* 1024x768@60Hz */
     568             :         { DRM_MODE("1024x768i", DRM_MODE_TYPE_DRIVER,44900, 1024, 1032,
     569             :                    1208, 1264, 0, 768, 768, 776, 817, 0,
     570             :                    DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC | DRM_MODE_FLAG_INTERLACE) }, /* 1024x768@43Hz */
     571             :         { DRM_MODE("832x624", DRM_MODE_TYPE_DRIVER, 57284, 832, 864,
     572             :                    928, 1152, 0, 624, 625, 628, 667, 0,
     573             :                    DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, /* 832x624@75Hz */
     574             :         { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 49500, 800, 816,
     575             :                    896, 1056, 0, 600, 601, 604,  625, 0,
     576             :                    DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, /* 800x600@75Hz */
     577             :         { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 50000, 800, 856,
     578             :                    976, 1040, 0, 600, 637, 643, 666, 0,
     579             :                    DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, /* 800x600@72Hz */
     580             :         { DRM_MODE("1152x864", DRM_MODE_TYPE_DRIVER, 108000, 1152, 1216,
     581             :                    1344, 1600, 0,  864, 865, 868, 900, 0,
     582             :                    DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, /* 1152x864@75Hz */
     583             : };
     584             : 
     585             : struct minimode {
     586             :         short w;
     587             :         short h;
     588             :         short r;
     589             :         short rb;
     590             : };
     591             : 
     592             : static const struct minimode est3_modes[] = {
     593             :         /* byte 6 */
     594             :         { 640, 350, 85, 0 },
     595             :         { 640, 400, 85, 0 },
     596             :         { 720, 400, 85, 0 },
     597             :         { 640, 480, 85, 0 },
     598             :         { 848, 480, 60, 0 },
     599             :         { 800, 600, 85, 0 },
     600             :         { 1024, 768, 85, 0 },
     601             :         { 1152, 864, 75, 0 },
     602             :         /* byte 7 */
     603             :         { 1280, 768, 60, 1 },
     604             :         { 1280, 768, 60, 0 },
     605             :         { 1280, 768, 75, 0 },
     606             :         { 1280, 768, 85, 0 },
     607             :         { 1280, 960, 60, 0 },
     608             :         { 1280, 960, 85, 0 },
     609             :         { 1280, 1024, 60, 0 },
     610             :         { 1280, 1024, 85, 0 },
     611             :         /* byte 8 */
     612             :         { 1360, 768, 60, 0 },
     613             :         { 1440, 900, 60, 1 },
     614             :         { 1440, 900, 60, 0 },
     615             :         { 1440, 900, 75, 0 },
     616             :         { 1440, 900, 85, 0 },
     617             :         { 1400, 1050, 60, 1 },
     618             :         { 1400, 1050, 60, 0 },
     619             :         { 1400, 1050, 75, 0 },
     620             :         /* byte 9 */
     621             :         { 1400, 1050, 85, 0 },
     622             :         { 1680, 1050, 60, 1 },
     623             :         { 1680, 1050, 60, 0 },
     624             :         { 1680, 1050, 75, 0 },
     625             :         { 1680, 1050, 85, 0 },
     626             :         { 1600, 1200, 60, 0 },
     627             :         { 1600, 1200, 65, 0 },
     628             :         { 1600, 1200, 70, 0 },
     629             :         /* byte 10 */
     630             :         { 1600, 1200, 75, 0 },
     631             :         { 1600, 1200, 85, 0 },
     632             :         { 1792, 1344, 60, 0 },
     633             :         { 1792, 1344, 75, 0 },
     634             :         { 1856, 1392, 60, 0 },
     635             :         { 1856, 1392, 75, 0 },
     636             :         { 1920, 1200, 60, 1 },
     637             :         { 1920, 1200, 60, 0 },
     638             :         /* byte 11 */
     639             :         { 1920, 1200, 75, 0 },
     640             :         { 1920, 1200, 85, 0 },
     641             :         { 1920, 1440, 60, 0 },
     642             :         { 1920, 1440, 75, 0 },
     643             : };
     644             : 
     645             : static const struct minimode extra_modes[] = {
     646             :         { 1024, 576,  60, 0 },
     647             :         { 1366, 768,  60, 0 },
     648             :         { 1600, 900,  60, 0 },
     649             :         { 1680, 945,  60, 0 },
     650             :         { 1920, 1080, 60, 0 },
     651             :         { 2048, 1152, 60, 0 },
     652             :         { 2048, 1536, 60, 0 },
     653             : };
     654             : 
     655             : /*
     656             :  * Probably taken from CEA-861 spec.
     657             :  * This table is converted from xorg's hw/xfree86/modes/xf86EdidModes.c.
     658             :  */
     659             : static const struct drm_display_mode edid_cea_modes[] = {
     660             :         /* 1 - 640x480@60Hz */
     661             :         { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 25175, 640, 656,
     662             :                    752, 800, 0, 480, 490, 492, 525, 0,
     663             :                    DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
     664             :           .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, },
     665             :         /* 2 - 720x480@60Hz */
     666             :         { DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 27000, 720, 736,
     667             :                    798, 858, 0, 480, 489, 495, 525, 0,
     668             :                    DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
     669             :           .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, },
     670             :         /* 3 - 720x480@60Hz */
     671             :         { DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 27000, 720, 736,
     672             :                    798, 858, 0, 480, 489, 495, 525, 0,
     673             :                    DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
     674             :           .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
     675             :         /* 4 - 1280x720@60Hz */
     676             :         { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 74250, 1280, 1390,
     677             :                    1430, 1650, 0, 720, 725, 730, 750, 0,
     678             :                    DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
     679             :           .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
     680             :         /* 5 - 1920x1080i@60Hz */
     681             :         { DRM_MODE("1920x1080i", DRM_MODE_TYPE_DRIVER, 74250, 1920, 2008,
     682             :                    2052, 2200, 0, 1080, 1084, 1094, 1125, 0,
     683             :                    DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC |
     684             :                         DRM_MODE_FLAG_INTERLACE),
     685             :           .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
     686             :         /* 6 - 720(1440)x480i@60Hz */
     687             :         { DRM_MODE("720x480i", DRM_MODE_TYPE_DRIVER, 13500, 720, 739,
     688             :                    801, 858, 0, 480, 488, 494, 525, 0,
     689             :                    DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
     690             :                         DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK),
     691             :           .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, },
     692             :         /* 7 - 720(1440)x480i@60Hz */
     693             :         { DRM_MODE("720x480i", DRM_MODE_TYPE_DRIVER, 13500, 720, 739,
     694             :                    801, 858, 0, 480, 488, 494, 525, 0,
     695             :                    DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
     696             :                         DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK),
     697             :           .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
     698             :         /* 8 - 720(1440)x240@60Hz */
     699             :         { DRM_MODE("720x240", DRM_MODE_TYPE_DRIVER, 13500, 720, 739,
     700             :                    801, 858, 0, 240, 244, 247, 262, 0,
     701             :                    DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
     702             :                         DRM_MODE_FLAG_DBLCLK),
     703             :           .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, },
     704             :         /* 9 - 720(1440)x240@60Hz */
     705             :         { DRM_MODE("720x240", DRM_MODE_TYPE_DRIVER, 13500, 720, 739,
     706             :                    801, 858, 0, 240, 244, 247, 262, 0,
     707             :                    DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
     708             :                         DRM_MODE_FLAG_DBLCLK),
     709             :           .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
     710             :         /* 10 - 2880x480i@60Hz */
     711             :         { DRM_MODE("2880x480i", DRM_MODE_TYPE_DRIVER, 54000, 2880, 2956,
     712             :                    3204, 3432, 0, 480, 488, 494, 525, 0,
     713             :                    DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
     714             :                         DRM_MODE_FLAG_INTERLACE),
     715             :           .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, },
     716             :         /* 11 - 2880x480i@60Hz */
     717             :         { DRM_MODE("2880x480i", DRM_MODE_TYPE_DRIVER, 54000, 2880, 2956,
     718             :                    3204, 3432, 0, 480, 488, 494, 525, 0,
     719             :                    DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
     720             :                         DRM_MODE_FLAG_INTERLACE),
     721             :           .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
     722             :         /* 12 - 2880x240@60Hz */
     723             :         { DRM_MODE("2880x240", DRM_MODE_TYPE_DRIVER, 54000, 2880, 2956,
     724             :                    3204, 3432, 0, 240, 244, 247, 262, 0,
     725             :                    DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
     726             :           .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, },
     727             :         /* 13 - 2880x240@60Hz */
     728             :         { DRM_MODE("2880x240", DRM_MODE_TYPE_DRIVER, 54000, 2880, 2956,
     729             :                    3204, 3432, 0, 240, 244, 247, 262, 0,
     730             :                    DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
     731             :           .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
     732             :         /* 14 - 1440x480@60Hz */
     733             :         { DRM_MODE("1440x480", DRM_MODE_TYPE_DRIVER, 54000, 1440, 1472,
     734             :                    1596, 1716, 0, 480, 489, 495, 525, 0,
     735             :                    DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
     736             :           .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, },
     737             :         /* 15 - 1440x480@60Hz */
     738             :         { DRM_MODE("1440x480", DRM_MODE_TYPE_DRIVER, 54000, 1440, 1472,
     739             :                    1596, 1716, 0, 480, 489, 495, 525, 0,
     740             :                    DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
     741             :           .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
     742             :         /* 16 - 1920x1080@60Hz */
     743             :         { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 148500, 1920, 2008,
     744             :                    2052, 2200, 0, 1080, 1084, 1089, 1125, 0,
     745             :                    DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
     746             :           .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
     747             :         /* 17 - 720x576@50Hz */
     748             :         { DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 27000, 720, 732,
     749             :                    796, 864, 0, 576, 581, 586, 625, 0,
     750             :                    DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
     751             :           .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, },
     752             :         /* 18 - 720x576@50Hz */
     753             :         { DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 27000, 720, 732,
     754             :                    796, 864, 0, 576, 581, 586, 625, 0,
     755             :                    DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
     756             :           .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
     757             :         /* 19 - 1280x720@50Hz */
     758             :         { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 74250, 1280, 1720,
     759             :                    1760, 1980, 0, 720, 725, 730, 750, 0,
     760             :                    DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
     761             :           .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
     762             :         /* 20 - 1920x1080i@50Hz */
     763             :         { DRM_MODE("1920x1080i", DRM_MODE_TYPE_DRIVER, 74250, 1920, 2448,
     764             :                    2492, 2640, 0, 1080, 1084, 1094, 1125, 0,
     765             :                    DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC |
     766             :                         DRM_MODE_FLAG_INTERLACE),
     767             :           .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
     768             :         /* 21 - 720(1440)x576i@50Hz */
     769             :         { DRM_MODE("720x576i", DRM_MODE_TYPE_DRIVER, 13500, 720, 732,
     770             :                    795, 864, 0, 576, 580, 586, 625, 0,
     771             :                    DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
     772             :                         DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK),
     773             :           .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, },
     774             :         /* 22 - 720(1440)x576i@50Hz */
     775             :         { DRM_MODE("720x576i", DRM_MODE_TYPE_DRIVER, 13500, 720, 732,
     776             :                    795, 864, 0, 576, 580, 586, 625, 0,
     777             :                    DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
     778             :                         DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK),
     779             :           .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
     780             :         /* 23 - 720(1440)x288@50Hz */
     781             :         { DRM_MODE("720x288", DRM_MODE_TYPE_DRIVER, 13500, 720, 732,
     782             :                    795, 864, 0, 288, 290, 293, 312, 0,
     783             :                    DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
     784             :                         DRM_MODE_FLAG_DBLCLK),
     785             :           .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, },
     786             :         /* 24 - 720(1440)x288@50Hz */
     787             :         { DRM_MODE("720x288", DRM_MODE_TYPE_DRIVER, 13500, 720, 732,
     788             :                    795, 864, 0, 288, 290, 293, 312, 0,
     789             :                    DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
     790             :                         DRM_MODE_FLAG_DBLCLK),
     791             :           .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
     792             :         /* 25 - 2880x576i@50Hz */
     793             :         { DRM_MODE("2880x576i", DRM_MODE_TYPE_DRIVER, 54000, 2880, 2928,
     794             :                    3180, 3456, 0, 576, 580, 586, 625, 0,
     795             :                    DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
     796             :                         DRM_MODE_FLAG_INTERLACE),
     797             :           .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, },
     798             :         /* 26 - 2880x576i@50Hz */
     799             :         { DRM_MODE("2880x576i", DRM_MODE_TYPE_DRIVER, 54000, 2880, 2928,
     800             :                    3180, 3456, 0, 576, 580, 586, 625, 0,
     801             :                    DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
     802             :                         DRM_MODE_FLAG_INTERLACE),
     803             :           .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
     804             :         /* 27 - 2880x288@50Hz */
     805             :         { DRM_MODE("2880x288", DRM_MODE_TYPE_DRIVER, 54000, 2880, 2928,
     806             :                    3180, 3456, 0, 288, 290, 293, 312, 0,
     807             :                    DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
     808             :           .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, },
     809             :         /* 28 - 2880x288@50Hz */
     810             :         { DRM_MODE("2880x288", DRM_MODE_TYPE_DRIVER, 54000, 2880, 2928,
     811             :                    3180, 3456, 0, 288, 290, 293, 312, 0,
     812             :                    DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
     813             :           .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
     814             :         /* 29 - 1440x576@50Hz */
     815             :         { DRM_MODE("1440x576", DRM_MODE_TYPE_DRIVER, 54000, 1440, 1464,
     816             :                    1592, 1728, 0, 576, 581, 586, 625, 0,
     817             :                    DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
     818             :           .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, },
     819             :         /* 30 - 1440x576@50Hz */
     820             :         { DRM_MODE("1440x576", DRM_MODE_TYPE_DRIVER, 54000, 1440, 1464,
     821             :                    1592, 1728, 0, 576, 581, 586, 625, 0,
     822             :                    DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
     823             :           .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
     824             :         /* 31 - 1920x1080@50Hz */
     825             :         { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 148500, 1920, 2448,
     826             :                    2492, 2640, 0, 1080, 1084, 1089, 1125, 0,
     827             :                    DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
     828             :           .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
     829             :         /* 32 - 1920x1080@24Hz */
     830             :         { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 74250, 1920, 2558,
     831             :                    2602, 2750, 0, 1080, 1084, 1089, 1125, 0,
     832             :                    DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
     833             :           .vrefresh = 24, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
     834             :         /* 33 - 1920x1080@25Hz */
     835             :         { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 74250, 1920, 2448,
     836             :                    2492, 2640, 0, 1080, 1084, 1089, 1125, 0,
     837             :                    DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
     838             :           .vrefresh = 25, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
     839             :         /* 34 - 1920x1080@30Hz */
     840             :         { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 74250, 1920, 2008,
     841             :                    2052, 2200, 0, 1080, 1084, 1089, 1125, 0,
     842             :                    DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
     843             :           .vrefresh = 30, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
     844             :         /* 35 - 2880x480@60Hz */
     845             :         { DRM_MODE("2880x480", DRM_MODE_TYPE_DRIVER, 108000, 2880, 2944,
     846             :                    3192, 3432, 0, 480, 489, 495, 525, 0,
     847             :                    DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
     848             :           .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, },
     849             :         /* 36 - 2880x480@60Hz */
     850             :         { DRM_MODE("2880x480", DRM_MODE_TYPE_DRIVER, 108000, 2880, 2944,
     851             :                    3192, 3432, 0, 480, 489, 495, 525, 0,
     852             :                    DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
     853             :           .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
     854             :         /* 37 - 2880x576@50Hz */
     855             :         { DRM_MODE("2880x576", DRM_MODE_TYPE_DRIVER, 108000, 2880, 2928,
     856             :                    3184, 3456, 0, 576, 581, 586, 625, 0,
     857             :                    DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
     858             :           .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, },
     859             :         /* 38 - 2880x576@50Hz */
     860             :         { DRM_MODE("2880x576", DRM_MODE_TYPE_DRIVER, 108000, 2880, 2928,
     861             :                    3184, 3456, 0, 576, 581, 586, 625, 0,
     862             :                    DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
     863             :           .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
     864             :         /* 39 - 1920x1080i@50Hz */
     865             :         { DRM_MODE("1920x1080i", DRM_MODE_TYPE_DRIVER, 72000, 1920, 1952,
     866             :                    2120, 2304, 0, 1080, 1126, 1136, 1250, 0,
     867             :                    DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC |
     868             :                         DRM_MODE_FLAG_INTERLACE),
     869             :           .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
     870             :         /* 40 - 1920x1080i@100Hz */
     871             :         { DRM_MODE("1920x1080i", DRM_MODE_TYPE_DRIVER, 148500, 1920, 2448,
     872             :                    2492, 2640, 0, 1080, 1084, 1094, 1125, 0,
     873             :                    DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC |
     874             :                         DRM_MODE_FLAG_INTERLACE),
     875             :           .vrefresh = 100, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
     876             :         /* 41 - 1280x720@100Hz */
     877             :         { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 148500, 1280, 1720,
     878             :                    1760, 1980, 0, 720, 725, 730, 750, 0,
     879             :                    DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
     880             :           .vrefresh = 100, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
     881             :         /* 42 - 720x576@100Hz */
     882             :         { DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 54000, 720, 732,
     883             :                    796, 864, 0, 576, 581, 586, 625, 0,
     884             :                    DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
     885             :           .vrefresh = 100, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, },
     886             :         /* 43 - 720x576@100Hz */
     887             :         { DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 54000, 720, 732,
     888             :                    796, 864, 0, 576, 581, 586, 625, 0,
     889             :                    DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
     890             :           .vrefresh = 100, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
     891             :         /* 44 - 720(1440)x576i@100Hz */
     892             :         { DRM_MODE("720x576i", DRM_MODE_TYPE_DRIVER, 27000, 720, 732,
     893             :                    795, 864, 0, 576, 580, 586, 625, 0,
     894             :                    DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
     895             :                         DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK),
     896             :           .vrefresh = 100, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, },
     897             :         /* 45 - 720(1440)x576i@100Hz */
     898             :         { DRM_MODE("720x576i", DRM_MODE_TYPE_DRIVER, 27000, 720, 732,
     899             :                    795, 864, 0, 576, 580, 586, 625, 0,
     900             :                    DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
     901             :                         DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK),
     902             :           .vrefresh = 100, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
     903             :         /* 46 - 1920x1080i@120Hz */
     904             :         { DRM_MODE("1920x1080i", DRM_MODE_TYPE_DRIVER, 148500, 1920, 2008,
     905             :                    2052, 2200, 0, 1080, 1084, 1094, 1125, 0,
     906             :                    DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC |
     907             :                         DRM_MODE_FLAG_INTERLACE),
     908             :           .vrefresh = 120, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
     909             :         /* 47 - 1280x720@120Hz */
     910             :         { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 148500, 1280, 1390,
     911             :                    1430, 1650, 0, 720, 725, 730, 750, 0,
     912             :                    DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
     913             :           .vrefresh = 120, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
     914             :         /* 48 - 720x480@120Hz */
     915             :         { DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 54000, 720, 736,
     916             :                    798, 858, 0, 480, 489, 495, 525, 0,
     917             :                    DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
     918             :           .vrefresh = 120, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, },
     919             :         /* 49 - 720x480@120Hz */
     920             :         { DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 54000, 720, 736,
     921             :                    798, 858, 0, 480, 489, 495, 525, 0,
     922             :                    DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
     923             :           .vrefresh = 120, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
     924             :         /* 50 - 720(1440)x480i@120Hz */
     925             :         { DRM_MODE("720x480i", DRM_MODE_TYPE_DRIVER, 27000, 720, 739,
     926             :                    801, 858, 0, 480, 488, 494, 525, 0,
     927             :                    DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
     928             :                         DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK),
     929             :           .vrefresh = 120, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, },
     930             :         /* 51 - 720(1440)x480i@120Hz */
     931             :         { DRM_MODE("720x480i", DRM_MODE_TYPE_DRIVER, 27000, 720, 739,
     932             :                    801, 858, 0, 480, 488, 494, 525, 0,
     933             :                    DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
     934             :                         DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK),
     935             :           .vrefresh = 120, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
     936             :         /* 52 - 720x576@200Hz */
     937             :         { DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 108000, 720, 732,
     938             :                    796, 864, 0, 576, 581, 586, 625, 0,
     939             :                    DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
     940             :           .vrefresh = 200, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, },
     941             :         /* 53 - 720x576@200Hz */
     942             :         { DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 108000, 720, 732,
     943             :                    796, 864, 0, 576, 581, 586, 625, 0,
     944             :                    DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
     945             :           .vrefresh = 200, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
     946             :         /* 54 - 720(1440)x576i@200Hz */
     947             :         { DRM_MODE("720x576i", DRM_MODE_TYPE_DRIVER, 54000, 720, 732,
     948             :                    795, 864, 0, 576, 580, 586, 625, 0,
     949             :                    DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
     950             :                         DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK),
     951             :           .vrefresh = 200, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, },
     952             :         /* 55 - 720(1440)x576i@200Hz */
     953             :         { DRM_MODE("720x576i", DRM_MODE_TYPE_DRIVER, 54000, 720, 732,
     954             :                    795, 864, 0, 576, 580, 586, 625, 0,
     955             :                    DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
     956             :                         DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK),
     957             :           .vrefresh = 200, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
     958             :         /* 56 - 720x480@240Hz */
     959             :         { DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 108000, 720, 736,
     960             :                    798, 858, 0, 480, 489, 495, 525, 0,
     961             :                    DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
     962             :           .vrefresh = 240, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, },
     963             :         /* 57 - 720x480@240Hz */
     964             :         { DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 108000, 720, 736,
     965             :                    798, 858, 0, 480, 489, 495, 525, 0,
     966             :                    DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
     967             :           .vrefresh = 240, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
     968             :         /* 58 - 720(1440)x480i@240 */
     969             :         { DRM_MODE("720x480i", DRM_MODE_TYPE_DRIVER, 54000, 720, 739,
     970             :                    801, 858, 0, 480, 488, 494, 525, 0,
     971             :                    DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
     972             :                         DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK),
     973             :           .vrefresh = 240, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, },
     974             :         /* 59 - 720(1440)x480i@240 */
     975             :         { DRM_MODE("720x480i", DRM_MODE_TYPE_DRIVER, 54000, 720, 739,
     976             :                    801, 858, 0, 480, 488, 494, 525, 0,
     977             :                    DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
     978             :                         DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK),
     979             :           .vrefresh = 240, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
     980             :         /* 60 - 1280x720@24Hz */
     981             :         { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 59400, 1280, 3040,
     982             :                    3080, 3300, 0, 720, 725, 730, 750, 0,
     983             :                    DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
     984             :           .vrefresh = 24, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
     985             :         /* 61 - 1280x720@25Hz */
     986             :         { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 74250, 1280, 3700,
     987             :                    3740, 3960, 0, 720, 725, 730, 750, 0,
     988             :                    DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
     989             :           .vrefresh = 25, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
     990             :         /* 62 - 1280x720@30Hz */
     991             :         { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 74250, 1280, 3040,
     992             :                    3080, 3300, 0, 720, 725, 730, 750, 0,
     993             :                    DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
     994             :           .vrefresh = 30, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
     995             :         /* 63 - 1920x1080@120Hz */
     996             :         { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 297000, 1920, 2008,
     997             :                    2052, 2200, 0, 1080, 1084, 1089, 1125, 0,
     998             :                    DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
     999             :          .vrefresh = 120, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
    1000             :         /* 64 - 1920x1080@100Hz */
    1001             :         { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 297000, 1920, 2448,
    1002             :                    2492, 2640, 0, 1080, 1084, 1094, 1125, 0,
    1003             :                    DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
    1004             :          .vrefresh = 100, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
    1005             : };
    1006             : 
    1007             : /*
    1008             :  * HDMI 1.4 4k modes.
    1009             :  */
    1010             : static const struct drm_display_mode edid_4k_modes[] = {
    1011             :         /* 1 - 3840x2160@30Hz */
    1012             :         { DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 297000,
    1013             :                    3840, 4016, 4104, 4400, 0,
    1014             :                    2160, 2168, 2178, 2250, 0,
    1015             :                    DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
    1016             :           .vrefresh = 30, },
    1017             :         /* 2 - 3840x2160@25Hz */
    1018             :         { DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 297000,
    1019             :                    3840, 4896, 4984, 5280, 0,
    1020             :                    2160, 2168, 2178, 2250, 0,
    1021             :                    DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
    1022             :           .vrefresh = 25, },
    1023             :         /* 3 - 3840x2160@24Hz */
    1024             :         { DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 297000,
    1025             :                    3840, 5116, 5204, 5500, 0,
    1026             :                    2160, 2168, 2178, 2250, 0,
    1027             :                    DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
    1028             :           .vrefresh = 24, },
    1029             :         /* 4 - 4096x2160@24Hz (SMPTE) */
    1030             :         { DRM_MODE("4096x2160", DRM_MODE_TYPE_DRIVER, 297000,
    1031             :                    4096, 5116, 5204, 5500, 0,
    1032             :                    2160, 2168, 2178, 2250, 0,
    1033             :                    DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
    1034             :           .vrefresh = 24, },
    1035             : };
    1036             : 
    1037             : /*** DDC fetch and block validation ***/
    1038             : 
    1039             : static const u8 edid_header[] = {
    1040             :         0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00
    1041             : };
    1042             : 
    1043             : /**
    1044             :  * drm_edid_header_is_valid - sanity check the header of the base EDID block
    1045             :  * @raw_edid: pointer to raw base EDID block
    1046             :  *
    1047             :  * Sanity check the header of the base EDID block.
    1048             :  *
    1049             :  * Return: 8 if the header is perfect, down to 0 if it's totally wrong.
    1050             :  */
    1051           0 : int drm_edid_header_is_valid(const u8 *raw_edid)
    1052             : {
    1053             :         int i, score = 0;
    1054             : 
    1055           0 :         for (i = 0; i < sizeof(edid_header); i++)
    1056           0 :                 if (raw_edid[i] == edid_header[i])
    1057           0 :                         score++;
    1058             : 
    1059           0 :         return score;
    1060             : }
    1061             : EXPORT_SYMBOL(drm_edid_header_is_valid);
    1062             : 
    1063             : static int edid_fixup __read_mostly = 6;
    1064             : module_param_named(edid_fixup, edid_fixup, int, 0400);
    1065             : MODULE_PARM_DESC(edid_fixup,
    1066             :                  "Minimum number of valid EDID header bytes (0-8, default 6)");
    1067             : 
    1068             : static void drm_get_displayid(struct drm_connector *connector,
    1069             :                               struct edid *edid);
    1070             : 
    1071           0 : static int drm_edid_block_checksum(const u8 *raw_edid)
    1072             : {
    1073             :         int i;
    1074             :         u8 csum = 0;
    1075           0 :         for (i = 0; i < EDID_LENGTH; i++)
    1076           0 :                 csum += raw_edid[i];
    1077             : 
    1078           0 :         return csum;
    1079             : }
    1080             : 
    1081           0 : static bool drm_edid_is_zero(const u8 *in_edid, int length)
    1082             : {
    1083           0 :         if (memchr_inv(in_edid, 0, length))
    1084           0 :                 return false;
    1085             : 
    1086           0 :         return true;
    1087           0 : }
    1088             : 
    1089             : /**
    1090             :  * drm_edid_block_valid - Sanity check the EDID block (base or extension)
    1091             :  * @raw_edid: pointer to raw EDID block
    1092             :  * @block: type of block to validate (0 for base, extension otherwise)
    1093             :  * @print_bad_edid: if true, dump bad EDID blocks to the console
    1094             :  * @edid_corrupt: if true, the header or checksum is invalid
    1095             :  *
    1096             :  * Validate a base or extension EDID block and optionally dump bad blocks to
    1097             :  * the console.
    1098             :  *
    1099             :  * Return: True if the block is valid, false otherwise.
    1100             :  */
    1101           0 : bool drm_edid_block_valid(u8 *raw_edid, int block, bool print_bad_edid,
    1102             :                           bool *edid_corrupt)
    1103             : {
    1104             :         u8 csum;
    1105           0 :         struct edid *edid = (struct edid *)raw_edid;
    1106             : 
    1107           0 :         if (WARN_ON(!raw_edid))
    1108           0 :                 return false;
    1109             : 
    1110           0 :         if (edid_fixup > 8 || edid_fixup < 0)
    1111           0 :                 edid_fixup = 6;
    1112             : 
    1113           0 :         if (block == 0) {
    1114           0 :                 int score = drm_edid_header_is_valid(raw_edid);
    1115           0 :                 if (score == 8) {
    1116           0 :                         if (edid_corrupt)
    1117           0 :                                 *edid_corrupt = false;
    1118           0 :                 } else if (score >= edid_fixup) {
    1119             :                         /* Displayport Link CTS Core 1.2 rev1.1 test 4.2.2.6
    1120             :                          * The corrupt flag needs to be set here otherwise, the
    1121             :                          * fix-up code here will correct the problem, the
    1122             :                          * checksum is correct and the test fails
    1123             :                          */
    1124           0 :                         if (edid_corrupt)
    1125           0 :                                 *edid_corrupt = true;
    1126             :                         DRM_DEBUG("Fixing EDID header, your hardware may be failing\n");
    1127           0 :                         memcpy(raw_edid, edid_header, sizeof(edid_header));
    1128             :                 } else {
    1129           0 :                         if (edid_corrupt)
    1130           0 :                                 *edid_corrupt = true;
    1131           0 :                         goto bad;
    1132             :                 }
    1133           0 :         }
    1134             : 
    1135           0 :         csum = drm_edid_block_checksum(raw_edid);
    1136           0 :         if (csum) {
    1137           0 :                 if (print_bad_edid) {
    1138           0 :                         DRM_ERROR("EDID checksum is invalid, remainder is %d\n", csum);
    1139           0 :                 }
    1140             : 
    1141           0 :                 if (edid_corrupt)
    1142           0 :                         *edid_corrupt = true;
    1143             : 
    1144             :                 /* allow CEA to slide through, switches mangle this */
    1145           0 :                 if (raw_edid[0] != 0x02)
    1146             :                         goto bad;
    1147             :         }
    1148             : 
    1149             :         /* per-block-type checks */
    1150           0 :         switch (raw_edid[0]) {
    1151             :         case 0: /* base */
    1152           0 :                 if (edid->version != 1) {
    1153           0 :                         DRM_ERROR("EDID has major version %d, instead of 1\n", edid->version);
    1154           0 :                         goto bad;
    1155             :                 }
    1156             : 
    1157           0 :                 if (edid->revision > 4)
    1158             :                         DRM_DEBUG("EDID minor > 4, assuming backward compatibility\n");
    1159           0 :                 break;
    1160             : 
    1161             :         default:
    1162             :                 break;
    1163             :         }
    1164             : 
    1165           0 :         return true;
    1166             : 
    1167             : bad:
    1168           0 :         if (print_bad_edid) {
    1169           0 :                 if (drm_edid_is_zero(raw_edid, EDID_LENGTH)) {
    1170           0 :                         printk(KERN_ERR "EDID block is all zeroes\n");
    1171           0 :                 } else {
    1172           0 :                         printk(KERN_ERR "Raw EDID:\n");
    1173           0 :                         print_hex_dump(KERN_ERR, " \t", DUMP_PREFIX_NONE, 16, 1,
    1174             :                                raw_edid, EDID_LENGTH, false);
    1175             :                 }
    1176             :         }
    1177           0 :         return false;
    1178           0 : }
    1179             : EXPORT_SYMBOL(drm_edid_block_valid);
    1180             : 
    1181             : /**
    1182             :  * drm_edid_is_valid - sanity check EDID data
    1183             :  * @edid: EDID data
    1184             :  *
    1185             :  * Sanity-check an entire EDID record (including extensions)
    1186             :  *
    1187             :  * Return: True if the EDID data is valid, false otherwise.
    1188             :  */
    1189           0 : bool drm_edid_is_valid(struct edid *edid)
    1190             : {
    1191             :         int i;
    1192           0 :         u8 *raw = (u8 *)edid;
    1193             : 
    1194           0 :         if (!edid)
    1195           0 :                 return false;
    1196             : 
    1197           0 :         for (i = 0; i <= edid->extensions; i++)
    1198           0 :                 if (!drm_edid_block_valid(raw + i * EDID_LENGTH, i, true, NULL))
    1199           0 :                         return false;
    1200             : 
    1201           0 :         return true;
    1202           0 : }
    1203             : EXPORT_SYMBOL(drm_edid_is_valid);
    1204             : 
    1205             : #define DDC_SEGMENT_ADDR 0x30
    1206             : /**
    1207             :  * drm_do_probe_ddc_edid() - get EDID information via I2C
    1208             :  * @data: I2C device adapter
    1209             :  * @buf: EDID data buffer to be filled
    1210             :  * @block: 128 byte EDID block to start fetching from
    1211             :  * @len: EDID data buffer length to fetch
    1212             :  *
    1213             :  * Try to fetch EDID information by calling I2C driver functions.
    1214             :  *
    1215             :  * Return: 0 on success or -1 on failure.
    1216             :  */
    1217             : static int
    1218           0 : drm_do_probe_ddc_edid(void *data, u8 *buf, unsigned int block, size_t len)
    1219             : {
    1220           0 :         struct i2c_adapter *adapter = data;
    1221           0 :         unsigned char start = block * EDID_LENGTH;
    1222           0 :         unsigned char segment = block >> 1;
    1223           0 :         unsigned char xfers = segment ? 3 : 2;
    1224             :         int ret, retries = 5;
    1225             : 
    1226             :         /*
    1227             :          * The core I2C driver will automatically retry the transfer if the
    1228             :          * adapter reports EAGAIN. However, we find that bit-banging transfers
    1229             :          * are susceptible to errors under a heavily loaded machine and
    1230             :          * generate spurious NAKs and timeouts. Retrying the transfer
    1231             :          * of the individual block a few times seems to overcome this.
    1232             :          */
    1233           0 :         do {
    1234           0 :                 struct i2c_msg msgs[] = {
    1235           0 :                         {
    1236             :                                 .addr   = DDC_SEGMENT_ADDR,
    1237             :                                 .flags  = 0,
    1238             :                                 .len    = 1,
    1239             :                                 .buf    = &segment,
    1240           0 :                         }, {
    1241             :                                 .addr   = DDC_ADDR,
    1242             :                                 .flags  = 0,
    1243             :                                 .len    = 1,
    1244             :                                 .buf    = &start,
    1245           0 :                         }, {
    1246             :                                 .addr   = DDC_ADDR,
    1247             :                                 .flags  = I2C_M_RD,
    1248           0 :                                 .len    = len,
    1249             :                                 .buf    = buf,
    1250             :                         }
    1251             :                 };
    1252             : 
    1253             :                 /*
    1254             :                  * Avoid sending the segment addr to not upset non-compliant
    1255             :                  * DDC monitors.
    1256             :                  */
    1257           0 :                 ret = i2c_transfer(adapter, &msgs[3 - xfers], xfers);
    1258             : 
    1259           0 :                 if (ret == -ENXIO) {
    1260             :                         DRM_DEBUG_KMS("drm: skipping non-existent adapter %s\n",
    1261             :                                         adapter->name);
    1262           0 :                         break;
    1263             :                 }
    1264           0 :         } while (ret != xfers && --retries);
    1265             : 
    1266           0 :         return ret == xfers ? 0 : -1;
    1267           0 : }
    1268             : 
    1269             : /**
    1270             :  * drm_do_get_edid - get EDID data using a custom EDID block read function
    1271             :  * @connector: connector we're probing
    1272             :  * @get_edid_block: EDID block read function
    1273             :  * @data: private data passed to the block read function
    1274             :  *
    1275             :  * When the I2C adapter connected to the DDC bus is hidden behind a device that
    1276             :  * exposes a different interface to read EDID blocks this function can be used
    1277             :  * to get EDID data using a custom block read function.
    1278             :  *
    1279             :  * As in the general case the DDC bus is accessible by the kernel at the I2C
    1280             :  * level, drivers must make all reasonable efforts to expose it as an I2C
    1281             :  * adapter and use drm_get_edid() instead of abusing this function.
    1282             :  *
    1283             :  * Return: Pointer to valid EDID or NULL if we couldn't find any.
    1284             :  */
    1285           0 : struct edid *drm_do_get_edid(struct drm_connector *connector,
    1286             :         int (*get_edid_block)(void *data, u8 *buf, unsigned int block,
    1287             :                               size_t len),
    1288             :         void *data)
    1289             : {
    1290             :         int i, j = 0, valid_extensions = 0;
    1291             :         u8 *block, *new;
    1292           0 :         bool print_bad_edid = !connector->bad_edid_counter || (drm_debug & DRM_UT_KMS);
    1293             : 
    1294           0 :         if ((block = kmalloc(EDID_LENGTH, GFP_KERNEL)) == NULL)
    1295           0 :                 return NULL;
    1296             : 
    1297             :         /* base block fetch */
    1298           0 :         for (i = 0; i < 4; i++) {
    1299           0 :                 if (get_edid_block(data, block, 0, EDID_LENGTH))
    1300             :                         goto out;
    1301           0 :                 if (drm_edid_block_valid(block, 0, print_bad_edid,
    1302           0 :                                          &connector->edid_corrupt))
    1303             :                         break;
    1304           0 :                 if (i == 0 && drm_edid_is_zero(block, EDID_LENGTH)) {
    1305           0 :                         connector->null_edid_counter++;
    1306           0 :                         goto carp;
    1307             :                 }
    1308             :         }
    1309           0 :         if (i == 4)
    1310             :                 goto carp;
    1311             : 
    1312             :         /* if there's no extensions, we're done */
    1313           0 :         if (block[0x7e] == 0)
    1314           0 :                 return (struct edid *)block;
    1315             : 
    1316           0 :         new = kmalloc((block[0x7e] + 1) * EDID_LENGTH, GFP_KERNEL);
    1317           0 :         if (!new)
    1318             :                 goto out;
    1319           0 :         memcpy(new, block, EDID_LENGTH);
    1320           0 :         kfree(block);
    1321             :         block = new;
    1322             : 
    1323           0 :         for (j = 1; j <= block[0x7e]; j++) {
    1324           0 :                 for (i = 0; i < 4; i++) {
    1325           0 :                         if (get_edid_block(data,
    1326           0 :                                   block + (valid_extensions + 1) * EDID_LENGTH,
    1327             :                                   j, EDID_LENGTH))
    1328             :                                 goto out;
    1329           0 :                         if (drm_edid_block_valid(block + (valid_extensions + 1)
    1330             :                                                  * EDID_LENGTH, j,
    1331             :                                                  print_bad_edid,
    1332             :                                                  NULL)) {
    1333             :                                 valid_extensions++;
    1334           0 :                                 break;
    1335             :                         }
    1336             :                 }
    1337             : 
    1338           0 :                 if (i == 4 && print_bad_edid) {
    1339           0 :                         dev_warn(connector->dev->dev,
    1340             :                          "%s: Ignoring invalid EDID block %d.\n",
    1341             :                          connector->name, j);
    1342             : 
    1343           0 :                         connector->bad_edid_counter++;
    1344           0 :                 }
    1345             :         }
    1346             : 
    1347           0 :         if (valid_extensions != block[0x7e]) {
    1348           0 :                 block[EDID_LENGTH-1] += block[0x7e] - valid_extensions;
    1349           0 :                 block[0x7e] = valid_extensions;
    1350           0 :                 new = kmalloc((valid_extensions + 1) * EDID_LENGTH, GFP_KERNEL);
    1351           0 :                 if (!new)
    1352             :                         goto out;
    1353           0 :                 memcpy(new, block, (valid_extensions + 1) * EDID_LENGTH);
    1354           0 :                 kfree(block);
    1355             :                 block = new;
    1356           0 :         }
    1357             : 
    1358           0 :         return (struct edid *)block;
    1359             : 
    1360             : carp:
    1361           0 :         if (print_bad_edid) {
    1362           0 :                 dev_warn(connector->dev->dev, "%s: EDID block %d invalid.\n",
    1363             :                          connector->name, j);
    1364           0 :         }
    1365           0 :         connector->bad_edid_counter++;
    1366             : 
    1367             : out:
    1368           0 :         kfree(block);
    1369           0 :         return NULL;
    1370           0 : }
    1371             : 
    1372             : /**
    1373             :  * drm_probe_ddc() - probe DDC presence
    1374             :  * @adapter: I2C adapter to probe
    1375             :  *
    1376             :  * Return: True on success, false on failure.
    1377             :  */
    1378             : bool
    1379           0 : drm_probe_ddc(struct i2c_adapter *adapter)
    1380             : {
    1381           0 :         unsigned char out;
    1382             : 
    1383           0 :         return (drm_do_probe_ddc_edid(adapter, &out, 0, 1) == 0);
    1384           0 : }
    1385             : EXPORT_SYMBOL(drm_probe_ddc);
    1386             : 
    1387             : /**
    1388             :  * drm_get_edid - get EDID data, if available
    1389             :  * @connector: connector we're probing
    1390             :  * @adapter: I2C adapter to use for DDC
    1391             :  *
    1392             :  * Poke the given I2C channel to grab EDID data if possible.  If found,
    1393             :  * attach it to the connector.
    1394             :  *
    1395             :  * Return: Pointer to valid EDID or NULL if we couldn't find any.
    1396             :  */
    1397           0 : struct edid *drm_get_edid(struct drm_connector *connector,
    1398             :                           struct i2c_adapter *adapter)
    1399             : {
    1400             :         struct edid *edid;
    1401             : 
    1402           0 :         if (!drm_probe_ddc(adapter))
    1403           0 :                 return NULL;
    1404             : 
    1405           0 :         edid = drm_do_get_edid(connector, drm_do_probe_ddc_edid, adapter);
    1406           0 :         if (edid)
    1407           0 :                 drm_get_displayid(connector, edid);
    1408           0 :         return edid;
    1409           0 : }
    1410             : EXPORT_SYMBOL(drm_get_edid);
    1411             : 
    1412             : /**
    1413             :  * drm_edid_duplicate - duplicate an EDID and the extensions
    1414             :  * @edid: EDID to duplicate
    1415             :  *
    1416             :  * Return: Pointer to duplicated EDID or NULL on allocation failure.
    1417             :  */
    1418           0 : struct edid *drm_edid_duplicate(const struct edid *edid)
    1419             : {
    1420           0 :         return kmemdup(edid, (edid->extensions + 1) * EDID_LENGTH, GFP_KERNEL);
    1421             : }
    1422             : EXPORT_SYMBOL(drm_edid_duplicate);
    1423             : 
    1424             : /*** EDID parsing ***/
    1425             : 
    1426             : /**
    1427             :  * edid_vendor - match a string against EDID's obfuscated vendor field
    1428             :  * @edid: EDID to match
    1429             :  * @vendor: vendor string
    1430             :  *
    1431             :  * Returns true if @vendor is in @edid, false otherwise
    1432             :  */
    1433           0 : static bool edid_vendor(struct edid *edid, char *vendor)
    1434             : {
    1435           0 :         char edid_vendor[3];
    1436             : 
    1437           0 :         edid_vendor[0] = ((edid->mfg_id[0] & 0x7c) >> 2) + '@';
    1438           0 :         edid_vendor[1] = (((edid->mfg_id[0] & 0x3) << 3) |
    1439           0 :                           ((edid->mfg_id[1] & 0xe0) >> 5)) + '@';
    1440           0 :         edid_vendor[2] = (edid->mfg_id[1] & 0x1f) + '@';
    1441             : 
    1442           0 :         return !strncmp(edid_vendor, vendor, 3);
    1443           0 : }
    1444             : 
    1445             : /**
    1446             :  * edid_get_quirks - return quirk flags for a given EDID
    1447             :  * @edid: EDID to process
    1448             :  *
    1449             :  * This tells subsequent routines what fixes they need to apply.
    1450             :  */
    1451           0 : static u32 edid_get_quirks(struct edid *edid)
    1452             : {
    1453             :         struct edid_quirk *quirk;
    1454             :         int i;
    1455             : 
    1456           0 :         for (i = 0; i < ARRAY_SIZE(edid_quirk_list); i++) {
    1457           0 :                 quirk = &edid_quirk_list[i];
    1458             : 
    1459           0 :                 if (edid_vendor(edid, quirk->vendor) &&
    1460           0 :                     (EDID_PRODUCT_ID(edid) == quirk->product_id))
    1461           0 :                         return quirk->quirks;
    1462             :         }
    1463             : 
    1464           0 :         return 0;
    1465           0 : }
    1466             : 
    1467             : #define MODE_SIZE(m) ((m)->hdisplay * (m)->vdisplay)
    1468             : #define MODE_REFRESH_DIFF(c,t) (abs((c) - (t)))
    1469             : 
    1470             : /**
    1471             :  * edid_fixup_preferred - set preferred modes based on quirk list
    1472             :  * @connector: has mode list to fix up
    1473             :  * @quirks: quirks list
    1474             :  *
    1475             :  * Walk the mode list for @connector, clearing the preferred status
    1476             :  * on existing modes and setting it anew for the right mode ala @quirks.
    1477             :  */
    1478           0 : static void edid_fixup_preferred(struct drm_connector *connector,
    1479             :                                  u32 quirks)
    1480             : {
    1481             :         struct drm_display_mode *t, *cur_mode, *preferred_mode;
    1482             :         int target_refresh = 0;
    1483             :         int cur_vrefresh, preferred_vrefresh;
    1484             : 
    1485           0 :         if (list_empty(&connector->probed_modes))
    1486           0 :                 return;
    1487             : 
    1488           0 :         if (quirks & EDID_QUIRK_PREFER_LARGE_60)
    1489           0 :                 target_refresh = 60;
    1490           0 :         if (quirks & EDID_QUIRK_PREFER_LARGE_75)
    1491           0 :                 target_refresh = 75;
    1492             : 
    1493           0 :         preferred_mode = list_first_entry(&connector->probed_modes,
    1494             :                                           struct drm_display_mode, head);
    1495             : 
    1496           0 :         list_for_each_entry_safe(cur_mode, t, &connector->probed_modes, head) {
    1497           0 :                 cur_mode->type &= ~DRM_MODE_TYPE_PREFERRED;
    1498             : 
    1499           0 :                 if (cur_mode == preferred_mode)
    1500             :                         continue;
    1501             : 
    1502             :                 /* Largest mode is preferred */
    1503           0 :                 if (MODE_SIZE(cur_mode) > MODE_SIZE(preferred_mode))
    1504           0 :                         preferred_mode = cur_mode;
    1505             : 
    1506           0 :                 cur_vrefresh = cur_mode->vrefresh ?
    1507           0 :                         cur_mode->vrefresh : drm_mode_vrefresh(cur_mode);
    1508           0 :                 preferred_vrefresh = preferred_mode->vrefresh ?
    1509           0 :                         preferred_mode->vrefresh : drm_mode_vrefresh(preferred_mode);
    1510             :                 /* At a given size, try to get closest to target refresh */
    1511           0 :                 if ((MODE_SIZE(cur_mode) == MODE_SIZE(preferred_mode)) &&
    1512           0 :                     MODE_REFRESH_DIFF(cur_vrefresh, target_refresh) <
    1513           0 :                     MODE_REFRESH_DIFF(preferred_vrefresh, target_refresh)) {
    1514             :                         preferred_mode = cur_mode;
    1515           0 :                 }
    1516             :         }
    1517             : 
    1518           0 :         preferred_mode->type |= DRM_MODE_TYPE_PREFERRED;
    1519           0 : }
    1520             : 
    1521             : static bool
    1522           0 : mode_is_rb(const struct drm_display_mode *mode)
    1523             : {
    1524           0 :         return (mode->htotal - mode->hdisplay == 160) &&
    1525           0 :                (mode->hsync_end - mode->hdisplay == 80) &&
    1526           0 :                (mode->hsync_end - mode->hsync_start == 32) &&
    1527           0 :                (mode->vsync_start - mode->vdisplay == 3);
    1528             : }
    1529             : 
    1530             : /*
    1531             :  * drm_mode_find_dmt - Create a copy of a mode if present in DMT
    1532             :  * @dev: Device to duplicate against
    1533             :  * @hsize: Mode width
    1534             :  * @vsize: Mode height
    1535             :  * @fresh: Mode refresh rate
    1536             :  * @rb: Mode reduced-blanking-ness
    1537             :  *
    1538             :  * Walk the DMT mode list looking for a match for the given parameters.
    1539             :  *
    1540             :  * Return: A newly allocated copy of the mode, or NULL if not found.
    1541             :  */
    1542           0 : struct drm_display_mode *drm_mode_find_dmt(struct drm_device *dev,
    1543             :                                            int hsize, int vsize, int fresh,
    1544             :                                            bool rb)
    1545             : {
    1546             :         int i;
    1547             : 
    1548           0 :         for (i = 0; i < ARRAY_SIZE(drm_dmt_modes); i++) {
    1549           0 :                 const struct drm_display_mode *ptr = &drm_dmt_modes[i];
    1550           0 :                 if (hsize != ptr->hdisplay)
    1551           0 :                         continue;
    1552           0 :                 if (vsize != ptr->vdisplay)
    1553           0 :                         continue;
    1554           0 :                 if (fresh != drm_mode_vrefresh(ptr))
    1555           0 :                         continue;
    1556           0 :                 if (rb != mode_is_rb(ptr))
    1557           0 :                         continue;
    1558             : 
    1559           0 :                 return drm_mode_duplicate(dev, ptr);
    1560             :         }
    1561             : 
    1562           0 :         return NULL;
    1563           0 : }
    1564             : EXPORT_SYMBOL(drm_mode_find_dmt);
    1565             : 
    1566             : typedef void detailed_cb(struct detailed_timing *timing, void *closure);
    1567             : 
    1568             : static void
    1569           0 : cea_for_each_detailed_block(u8 *ext, detailed_cb *cb, void *closure)
    1570             : {
    1571             :         int i, n = 0;
    1572           0 :         u8 d = ext[0x02];
    1573           0 :         u8 *det_base = ext + d;
    1574             : 
    1575           0 :         n = (127 - d) / 18;
    1576           0 :         for (i = 0; i < n; i++)
    1577           0 :                 cb((struct detailed_timing *)(det_base + 18 * i), closure);
    1578           0 : }
    1579             : 
    1580             : static void
    1581           0 : vtb_for_each_detailed_block(u8 *ext, detailed_cb *cb, void *closure)
    1582             : {
    1583           0 :         unsigned int i, n = min((int)ext[0x02], 6);
    1584           0 :         u8 *det_base = ext + 5;
    1585             : 
    1586           0 :         if (ext[0x01] != 1)
    1587           0 :                 return; /* unknown version */
    1588             : 
    1589           0 :         for (i = 0; i < n; i++)
    1590           0 :                 cb((struct detailed_timing *)(det_base + 18 * i), closure);
    1591           0 : }
    1592             : 
    1593             : static void
    1594           0 : drm_for_each_detailed_block(u8 *raw_edid, detailed_cb *cb, void *closure)
    1595             : {
    1596             :         int i;
    1597           0 :         struct edid *edid = (struct edid *)raw_edid;
    1598             : 
    1599           0 :         if (edid == NULL)
    1600           0 :                 return;
    1601             : 
    1602           0 :         for (i = 0; i < EDID_DETAILED_TIMINGS; i++)
    1603           0 :                 cb(&(edid->detailed_timings[i]), closure);
    1604             : 
    1605           0 :         for (i = 1; i <= raw_edid[0x7e]; i++) {
    1606           0 :                 u8 *ext = raw_edid + (i * EDID_LENGTH);
    1607           0 :                 switch (*ext) {
    1608             :                 case CEA_EXT:
    1609           0 :                         cea_for_each_detailed_block(ext, cb, closure);
    1610           0 :                         break;
    1611             :                 case VTB_EXT:
    1612           0 :                         vtb_for_each_detailed_block(ext, cb, closure);
    1613           0 :                         break;
    1614             :                 default:
    1615             :                         break;
    1616             :                 }
    1617             :         }
    1618           0 : }
    1619             : 
    1620             : static void
    1621           0 : is_rb(struct detailed_timing *t, void *data)
    1622             : {
    1623           0 :         u8 *r = (u8 *)t;
    1624           0 :         if (r[3] == EDID_DETAIL_MONITOR_RANGE)
    1625           0 :                 if (r[15] & 0x10)
    1626           0 :                         *(bool *)data = true;
    1627           0 : }
    1628             : 
    1629             : /* EDID 1.4 defines this explicitly.  For EDID 1.3, we guess, badly. */
    1630             : static bool
    1631           0 : drm_monitor_supports_rb(struct edid *edid)
    1632             : {
    1633           0 :         if (edid->revision >= 4) {
    1634           0 :                 bool ret = false;
    1635           0 :                 drm_for_each_detailed_block((u8 *)edid, is_rb, &ret);
    1636           0 :                 return ret;
    1637           0 :         }
    1638             : 
    1639           0 :         return ((edid->input & DRM_EDID_INPUT_DIGITAL) != 0);
    1640           0 : }
    1641             : 
    1642             : static void
    1643           0 : find_gtf2(struct detailed_timing *t, void *data)
    1644             : {
    1645           0 :         u8 *r = (u8 *)t;
    1646           0 :         if (r[3] == EDID_DETAIL_MONITOR_RANGE && r[10] == 0x02)
    1647           0 :                 *(u8 **)data = r;
    1648           0 : }
    1649             : 
    1650             : /* Secondary GTF curve kicks in above some break frequency */
    1651             : static int
    1652           0 : drm_gtf2_hbreak(struct edid *edid)
    1653             : {
    1654           0 :         u8 *r = NULL;
    1655           0 :         drm_for_each_detailed_block((u8 *)edid, find_gtf2, &r);
    1656           0 :         return r ? (r[12] * 2) : 0;
    1657           0 : }
    1658             : 
    1659             : static int
    1660           0 : drm_gtf2_2c(struct edid *edid)
    1661             : {
    1662           0 :         u8 *r = NULL;
    1663           0 :         drm_for_each_detailed_block((u8 *)edid, find_gtf2, &r);
    1664           0 :         return r ? r[13] : 0;
    1665           0 : }
    1666             : 
    1667             : static int
    1668           0 : drm_gtf2_m(struct edid *edid)
    1669             : {
    1670           0 :         u8 *r = NULL;
    1671           0 :         drm_for_each_detailed_block((u8 *)edid, find_gtf2, &r);
    1672           0 :         return r ? (r[15] << 8) + r[14] : 0;
    1673           0 : }
    1674             : 
    1675             : static int
    1676           0 : drm_gtf2_k(struct edid *edid)
    1677             : {
    1678           0 :         u8 *r = NULL;
    1679           0 :         drm_for_each_detailed_block((u8 *)edid, find_gtf2, &r);
    1680           0 :         return r ? r[16] : 0;
    1681           0 : }
    1682             : 
    1683             : static int
    1684           0 : drm_gtf2_2j(struct edid *edid)
    1685             : {
    1686           0 :         u8 *r = NULL;
    1687           0 :         drm_for_each_detailed_block((u8 *)edid, find_gtf2, &r);
    1688           0 :         return r ? r[17] : 0;
    1689           0 : }
    1690             : 
    1691             : /**
    1692             :  * standard_timing_level - get std. timing level(CVT/GTF/DMT)
    1693             :  * @edid: EDID block to scan
    1694             :  */
    1695           0 : static int standard_timing_level(struct edid *edid)
    1696             : {
    1697           0 :         if (edid->revision >= 2) {
    1698           0 :                 if (edid->revision >= 4 && (edid->features & DRM_EDID_FEATURE_DEFAULT_GTF))
    1699           0 :                         return LEVEL_CVT;
    1700           0 :                 if (drm_gtf2_hbreak(edid))
    1701           0 :                         return LEVEL_GTF2;
    1702           0 :                 return LEVEL_GTF;
    1703             :         }
    1704           0 :         return LEVEL_DMT;
    1705           0 : }
    1706             : 
    1707             : /*
    1708             :  * 0 is reserved.  The spec says 0x01 fill for unused timings.  Some old
    1709             :  * monitors fill with ascii space (0x20) instead.
    1710             :  */
    1711             : static int
    1712           0 : bad_std_timing(u8 a, u8 b)
    1713             : {
    1714           0 :         return (a == 0x00 && b == 0x00) ||
    1715           0 :                (a == 0x01 && b == 0x01) ||
    1716           0 :                (a == 0x20 && b == 0x20);
    1717             : }
    1718             : 
    1719             : /**
    1720             :  * drm_mode_std - convert standard mode info (width, height, refresh) into mode
    1721             :  * @connector: connector of for the EDID block
    1722             :  * @edid: EDID block to scan
    1723             :  * @t: standard timing params
    1724             :  *
    1725             :  * Take the standard timing params (in this case width, aspect, and refresh)
    1726             :  * and convert them into a real mode using CVT/GTF/DMT.
    1727             :  */
    1728             : static struct drm_display_mode *
    1729           0 : drm_mode_std(struct drm_connector *connector, struct edid *edid,
    1730             :              struct std_timing *t)
    1731             : {
    1732           0 :         struct drm_device *dev = connector->dev;
    1733             :         struct drm_display_mode *m, *mode = NULL;
    1734             :         int hsize, vsize;
    1735             :         int vrefresh_rate;
    1736           0 :         unsigned aspect_ratio = (t->vfreq_aspect & EDID_TIMING_ASPECT_MASK)
    1737           0 :                 >> EDID_TIMING_ASPECT_SHIFT;
    1738           0 :         unsigned vfreq = (t->vfreq_aspect & EDID_TIMING_VFREQ_MASK)
    1739             :                 >> EDID_TIMING_VFREQ_SHIFT;
    1740           0 :         int timing_level = standard_timing_level(edid);
    1741             : 
    1742           0 :         if (bad_std_timing(t->hsize, t->vfreq_aspect))
    1743           0 :                 return NULL;
    1744             : 
    1745             :         /* According to the EDID spec, the hdisplay = hsize * 8 + 248 */
    1746           0 :         hsize = t->hsize * 8 + 248;
    1747             :         /* vrefresh_rate = vfreq + 60 */
    1748           0 :         vrefresh_rate = vfreq + 60;
    1749             :         /* the vdisplay is calculated based on the aspect ratio */
    1750           0 :         if (aspect_ratio == 0) {
    1751           0 :                 if (edid->revision < 3)
    1752           0 :                         vsize = hsize;
    1753             :                 else
    1754           0 :                         vsize = (hsize * 10) / 16;
    1755           0 :         } else if (aspect_ratio == 1)
    1756           0 :                 vsize = (hsize * 3) / 4;
    1757           0 :         else if (aspect_ratio == 2)
    1758           0 :                 vsize = (hsize * 4) / 5;
    1759             :         else
    1760           0 :                 vsize = (hsize * 9) / 16;
    1761             : 
    1762             :         /* HDTV hack, part 1 */
    1763           0 :         if (vrefresh_rate == 60 &&
    1764           0 :             ((hsize == 1360 && vsize == 765) ||
    1765           0 :              (hsize == 1368 && vsize == 769))) {
    1766             :                 hsize = 1366;
    1767             :                 vsize = 768;
    1768           0 :         }
    1769             : 
    1770             :         /*
    1771             :          * If this connector already has a mode for this size and refresh
    1772             :          * rate (because it came from detailed or CVT info), use that
    1773             :          * instead.  This way we don't have to guess at interlace or
    1774             :          * reduced blanking.
    1775             :          */
    1776           0 :         list_for_each_entry(m, &connector->probed_modes, head)
    1777           0 :                 if (m->hdisplay == hsize && m->vdisplay == vsize &&
    1778           0 :                     drm_mode_vrefresh(m) == vrefresh_rate)
    1779           0 :                         return NULL;
    1780             : 
    1781             :         /* HDTV hack, part 2 */
    1782           0 :         if (hsize == 1366 && vsize == 768 && vrefresh_rate == 60) {
    1783           0 :                 mode = drm_cvt_mode(dev, 1366, 768, vrefresh_rate, 0, 0,
    1784             :                                     false);
    1785           0 :                 mode->hdisplay = 1366;
    1786           0 :                 mode->hsync_start = mode->hsync_start - 1;
    1787           0 :                 mode->hsync_end = mode->hsync_end - 1;
    1788           0 :                 return mode;
    1789             :         }
    1790             : 
    1791             :         /* check whether it can be found in default mode table */
    1792           0 :         if (drm_monitor_supports_rb(edid)) {
    1793           0 :                 mode = drm_mode_find_dmt(dev, hsize, vsize, vrefresh_rate,
    1794             :                                          true);
    1795           0 :                 if (mode)
    1796           0 :                         return mode;
    1797             :         }
    1798           0 :         mode = drm_mode_find_dmt(dev, hsize, vsize, vrefresh_rate, false);
    1799           0 :         if (mode)
    1800           0 :                 return mode;
    1801             : 
    1802             :         /* okay, generate it */
    1803           0 :         switch (timing_level) {
    1804             :         case LEVEL_DMT:
    1805             :                 break;
    1806             :         case LEVEL_GTF:
    1807           0 :                 mode = drm_gtf_mode(dev, hsize, vsize, vrefresh_rate, 0, 0);
    1808           0 :                 break;
    1809             :         case LEVEL_GTF2:
    1810             :                 /*
    1811             :                  * This is potentially wrong if there's ever a monitor with
    1812             :                  * more than one ranges section, each claiming a different
    1813             :                  * secondary GTF curve.  Please don't do that.
    1814             :                  */
    1815           0 :                 mode = drm_gtf_mode(dev, hsize, vsize, vrefresh_rate, 0, 0);
    1816           0 :                 if (!mode)
    1817           0 :                         return NULL;
    1818           0 :                 if (drm_mode_hsync(mode) > drm_gtf2_hbreak(edid)) {
    1819           0 :                         drm_mode_destroy(dev, mode);
    1820           0 :                         mode = drm_gtf_mode_complex(dev, hsize, vsize,
    1821             :                                                     vrefresh_rate, 0, 0,
    1822           0 :                                                     drm_gtf2_m(edid),
    1823           0 :                                                     drm_gtf2_2c(edid),
    1824           0 :                                                     drm_gtf2_k(edid),
    1825           0 :                                                     drm_gtf2_2j(edid));
    1826           0 :                 }
    1827             :                 break;
    1828             :         case LEVEL_CVT:
    1829           0 :                 mode = drm_cvt_mode(dev, hsize, vsize, vrefresh_rate, 0, 0,
    1830             :                                     false);
    1831           0 :                 break;
    1832             :         }
    1833           0 :         return mode;
    1834           0 : }
    1835             : 
    1836             : /*
    1837             :  * EDID is delightfully ambiguous about how interlaced modes are to be
    1838             :  * encoded.  Our internal representation is of frame height, but some
    1839             :  * HDTV detailed timings are encoded as field height.
    1840             :  *
    1841             :  * The format list here is from CEA, in frame size.  Technically we
    1842             :  * should be checking refresh rate too.  Whatever.
    1843             :  */
    1844             : static void
    1845           0 : drm_mode_do_interlace_quirk(struct drm_display_mode *mode,
    1846             :                             struct detailed_pixel_timing *pt)
    1847             : {
    1848             :         int i;
    1849             :         static const struct {
    1850             :                 int w, h;
    1851             :         } cea_interlaced[] = {
    1852             :                 { 1920, 1080 },
    1853             :                 {  720,  480 },
    1854             :                 { 1440,  480 },
    1855             :                 { 2880,  480 },
    1856             :                 {  720,  576 },
    1857             :                 { 1440,  576 },
    1858             :                 { 2880,  576 },
    1859             :         };
    1860             : 
    1861           0 :         if (!(pt->misc & DRM_EDID_PT_INTERLACED))
    1862           0 :                 return;
    1863             : 
    1864           0 :         for (i = 0; i < ARRAY_SIZE(cea_interlaced); i++) {
    1865           0 :                 if ((mode->hdisplay == cea_interlaced[i].w) &&
    1866           0 :                     (mode->vdisplay == cea_interlaced[i].h / 2)) {
    1867           0 :                         mode->vdisplay *= 2;
    1868           0 :                         mode->vsync_start *= 2;
    1869           0 :                         mode->vsync_end *= 2;
    1870           0 :                         mode->vtotal *= 2;
    1871           0 :                         mode->vtotal |= 1;
    1872           0 :                 }
    1873             :         }
    1874             : 
    1875           0 :         mode->flags |= DRM_MODE_FLAG_INTERLACE;
    1876           0 : }
    1877             : 
    1878             : /**
    1879             :  * drm_mode_detailed - create a new mode from an EDID detailed timing section
    1880             :  * @dev: DRM device (needed to create new mode)
    1881             :  * @edid: EDID block
    1882             :  * @timing: EDID detailed timing info
    1883             :  * @quirks: quirks to apply
    1884             :  *
    1885             :  * An EDID detailed timing block contains enough info for us to create and
    1886             :  * return a new struct drm_display_mode.
    1887             :  */
    1888           0 : static struct drm_display_mode *drm_mode_detailed(struct drm_device *dev,
    1889             :                                                   struct edid *edid,
    1890             :                                                   struct detailed_timing *timing,
    1891             :                                                   u32 quirks)
    1892             : {
    1893             :         struct drm_display_mode *mode;
    1894           0 :         struct detailed_pixel_timing *pt = &timing->data.pixel_data;
    1895           0 :         unsigned hactive = (pt->hactive_hblank_hi & 0xf0) << 4 | pt->hactive_lo;
    1896           0 :         unsigned vactive = (pt->vactive_vblank_hi & 0xf0) << 4 | pt->vactive_lo;
    1897           0 :         unsigned hblank = (pt->hactive_hblank_hi & 0xf) << 8 | pt->hblank_lo;
    1898           0 :         unsigned vblank = (pt->vactive_vblank_hi & 0xf) << 8 | pt->vblank_lo;
    1899           0 :         unsigned hsync_offset = (pt->hsync_vsync_offset_pulse_width_hi & 0xc0) << 2 | pt->hsync_offset_lo;
    1900           0 :         unsigned hsync_pulse_width = (pt->hsync_vsync_offset_pulse_width_hi & 0x30) << 4 | pt->hsync_pulse_width_lo;
    1901           0 :         unsigned vsync_offset = (pt->hsync_vsync_offset_pulse_width_hi & 0xc) << 2 | pt->vsync_offset_pulse_width_lo >> 4;
    1902           0 :         unsigned vsync_pulse_width = (pt->hsync_vsync_offset_pulse_width_hi & 0x3) << 4 | (pt->vsync_offset_pulse_width_lo & 0xf);
    1903             : 
    1904             :         /* ignore tiny modes */
    1905           0 :         if (hactive < 64 || vactive < 64)
    1906           0 :                 return NULL;
    1907             : 
    1908           0 :         if (pt->misc & DRM_EDID_PT_STEREO) {
    1909             :                 DRM_DEBUG_KMS("stereo mode not supported\n");
    1910           0 :                 return NULL;
    1911             :         }
    1912           0 :         if (!(pt->misc & DRM_EDID_PT_SEPARATE_SYNC)) {
    1913             :                 DRM_DEBUG_KMS("composite sync not supported\n");
    1914             :         }
    1915             : 
    1916             :         /* it is incorrect if hsync/vsync width is zero */
    1917           0 :         if (!hsync_pulse_width || !vsync_pulse_width) {
    1918             :                 DRM_DEBUG_KMS("Incorrect Detailed timing. "
    1919             :                                 "Wrong Hsync/Vsync pulse width\n");
    1920           0 :                 return NULL;
    1921             :         }
    1922             : 
    1923           0 :         if (quirks & EDID_QUIRK_FORCE_REDUCED_BLANKING) {
    1924           0 :                 mode = drm_cvt_mode(dev, hactive, vactive, 60, true, false, false);
    1925           0 :                 if (!mode)
    1926           0 :                         return NULL;
    1927             : 
    1928             :                 goto set_size;
    1929             :         }
    1930             : 
    1931           0 :         mode = drm_mode_create(dev);
    1932           0 :         if (!mode)
    1933           0 :                 return NULL;
    1934             : 
    1935           0 :         if (quirks & EDID_QUIRK_135_CLOCK_TOO_HIGH)
    1936           0 :                 timing->pixel_clock = cpu_to_le16(1088);
    1937             : 
    1938           0 :         mode->clock = le16_to_cpu(timing->pixel_clock) * 10;
    1939             : 
    1940           0 :         mode->hdisplay = hactive;
    1941           0 :         mode->hsync_start = mode->hdisplay + hsync_offset;
    1942           0 :         mode->hsync_end = mode->hsync_start + hsync_pulse_width;
    1943           0 :         mode->htotal = mode->hdisplay + hblank;
    1944             : 
    1945           0 :         mode->vdisplay = vactive;
    1946           0 :         mode->vsync_start = mode->vdisplay + vsync_offset;
    1947           0 :         mode->vsync_end = mode->vsync_start + vsync_pulse_width;
    1948           0 :         mode->vtotal = mode->vdisplay + vblank;
    1949             : 
    1950             :         /* Some EDIDs have bogus h/vtotal values */
    1951           0 :         if (mode->hsync_end > mode->htotal)
    1952           0 :                 mode->htotal = mode->hsync_end + 1;
    1953           0 :         if (mode->vsync_end > mode->vtotal)
    1954           0 :                 mode->vtotal = mode->vsync_end + 1;
    1955             : 
    1956           0 :         drm_mode_do_interlace_quirk(mode, pt);
    1957             : 
    1958           0 :         if (quirks & EDID_QUIRK_DETAILED_SYNC_PP) {
    1959           0 :                 pt->misc |= DRM_EDID_PT_HSYNC_POSITIVE | DRM_EDID_PT_VSYNC_POSITIVE;
    1960           0 :         }
    1961             : 
    1962           0 :         mode->flags |= (pt->misc & DRM_EDID_PT_HSYNC_POSITIVE) ?
    1963             :                 DRM_MODE_FLAG_PHSYNC : DRM_MODE_FLAG_NHSYNC;
    1964           0 :         mode->flags |= (pt->misc & DRM_EDID_PT_VSYNC_POSITIVE) ?
    1965             :                 DRM_MODE_FLAG_PVSYNC : DRM_MODE_FLAG_NVSYNC;
    1966             : 
    1967             : set_size:
    1968           0 :         mode->width_mm = pt->width_mm_lo | (pt->width_height_mm_hi & 0xf0) << 4;
    1969           0 :         mode->height_mm = pt->height_mm_lo | (pt->width_height_mm_hi & 0xf) << 8;
    1970             : 
    1971           0 :         if (quirks & EDID_QUIRK_DETAILED_IN_CM) {
    1972           0 :                 mode->width_mm *= 10;
    1973           0 :                 mode->height_mm *= 10;
    1974           0 :         }
    1975             : 
    1976           0 :         if (quirks & EDID_QUIRK_DETAILED_USE_MAXIMUM_SIZE) {
    1977           0 :                 mode->width_mm = edid->width_cm * 10;
    1978           0 :                 mode->height_mm = edid->height_cm * 10;
    1979           0 :         }
    1980             : 
    1981           0 :         mode->type = DRM_MODE_TYPE_DRIVER;
    1982           0 :         mode->vrefresh = drm_mode_vrefresh(mode);
    1983           0 :         drm_mode_set_name(mode);
    1984             : 
    1985           0 :         return mode;
    1986           0 : }
    1987             : 
    1988             : static bool
    1989           0 : mode_in_hsync_range(const struct drm_display_mode *mode,
    1990             :                     struct edid *edid, u8 *t)
    1991             : {
    1992             :         int hsync, hmin, hmax;
    1993             : 
    1994           0 :         hmin = t[7];
    1995           0 :         if (edid->revision >= 4)
    1996           0 :             hmin += ((t[4] & 0x04) ? 255 : 0);
    1997           0 :         hmax = t[8];
    1998           0 :         if (edid->revision >= 4)
    1999           0 :             hmax += ((t[4] & 0x08) ? 255 : 0);
    2000           0 :         hsync = drm_mode_hsync(mode);
    2001             : 
    2002           0 :         return (hsync <= hmax && hsync >= hmin);
    2003             : }
    2004             : 
    2005             : static bool
    2006           0 : mode_in_vsync_range(const struct drm_display_mode *mode,
    2007             :                     struct edid *edid, u8 *t)
    2008             : {
    2009             :         int vsync, vmin, vmax;
    2010             : 
    2011           0 :         vmin = t[5];
    2012           0 :         if (edid->revision >= 4)
    2013           0 :             vmin += ((t[4] & 0x01) ? 255 : 0);
    2014           0 :         vmax = t[6];
    2015           0 :         if (edid->revision >= 4)
    2016           0 :             vmax += ((t[4] & 0x02) ? 255 : 0);
    2017           0 :         vsync = drm_mode_vrefresh(mode);
    2018             : 
    2019           0 :         return (vsync <= vmax && vsync >= vmin);
    2020             : }
    2021             : 
    2022             : static u32
    2023           0 : range_pixel_clock(struct edid *edid, u8 *t)
    2024             : {
    2025             :         /* unspecified */
    2026           0 :         if (t[9] == 0 || t[9] == 255)
    2027           0 :                 return 0;
    2028             : 
    2029             :         /* 1.4 with CVT support gives us real precision, yay */
    2030           0 :         if (edid->revision >= 4 && t[10] == 0x04)
    2031           0 :                 return (t[9] * 10000) - ((t[12] >> 2) * 250);
    2032             : 
    2033             :         /* 1.3 is pathetic, so fuzz up a bit */
    2034           0 :         return t[9] * 10000 + 5001;
    2035           0 : }
    2036             : 
    2037             : static bool
    2038           0 : mode_in_range(const struct drm_display_mode *mode, struct edid *edid,
    2039             :               struct detailed_timing *timing)
    2040             : {
    2041             :         u32 max_clock;
    2042           0 :         u8 *t = (u8 *)timing;
    2043             : 
    2044           0 :         if (!mode_in_hsync_range(mode, edid, t))
    2045           0 :                 return false;
    2046             : 
    2047           0 :         if (!mode_in_vsync_range(mode, edid, t))
    2048           0 :                 return false;
    2049             : 
    2050           0 :         if ((max_clock = range_pixel_clock(edid, t)))
    2051           0 :                 if (mode->clock > max_clock)
    2052           0 :                         return false;
    2053             : 
    2054             :         /* 1.4 max horizontal check */
    2055           0 :         if (edid->revision >= 4 && t[10] == 0x04)
    2056           0 :                 if (t[13] && mode->hdisplay > 8 * (t[13] + (256 * (t[12]&0x3))))
    2057           0 :                         return false;
    2058             : 
    2059           0 :         if (mode_is_rb(mode) && !drm_monitor_supports_rb(edid))
    2060           0 :                 return false;
    2061             : 
    2062           0 :         return true;
    2063           0 : }
    2064             : 
    2065           0 : static bool valid_inferred_mode(const struct drm_connector *connector,
    2066             :                                 const struct drm_display_mode *mode)
    2067             : {
    2068             :         const struct drm_display_mode *m;
    2069             :         bool ok = false;
    2070             : 
    2071           0 :         list_for_each_entry(m, &connector->probed_modes, head) {
    2072           0 :                 if (mode->hdisplay == m->hdisplay &&
    2073           0 :                     mode->vdisplay == m->vdisplay &&
    2074           0 :                     drm_mode_vrefresh(mode) == drm_mode_vrefresh(m))
    2075           0 :                         return false; /* duplicated */
    2076           0 :                 if (mode->hdisplay <= m->hdisplay &&
    2077           0 :                     mode->vdisplay <= m->vdisplay)
    2078           0 :                         ok = true;
    2079             :         }
    2080           0 :         return ok;
    2081           0 : }
    2082             : 
    2083             : static int
    2084           0 : drm_dmt_modes_for_range(struct drm_connector *connector, struct edid *edid,
    2085             :                         struct detailed_timing *timing)
    2086             : {
    2087             :         int i, modes = 0;
    2088             :         struct drm_display_mode *newmode;
    2089           0 :         struct drm_device *dev = connector->dev;
    2090             : 
    2091           0 :         for (i = 0; i < ARRAY_SIZE(drm_dmt_modes); i++) {
    2092           0 :                 if (mode_in_range(drm_dmt_modes + i, edid, timing) &&
    2093           0 :                     valid_inferred_mode(connector, drm_dmt_modes + i)) {
    2094           0 :                         newmode = drm_mode_duplicate(dev, &drm_dmt_modes[i]);
    2095           0 :                         if (newmode) {
    2096           0 :                                 drm_mode_probed_add(connector, newmode);
    2097           0 :                                 modes++;
    2098           0 :                         }
    2099             :                 }
    2100             :         }
    2101             : 
    2102           0 :         return modes;
    2103             : }
    2104             : 
    2105             : /* fix up 1366x768 mode from 1368x768;
    2106             :  * GFT/CVT can't express 1366 width which isn't dividable by 8
    2107             :  */
    2108           0 : static void fixup_mode_1366x768(struct drm_display_mode *mode)
    2109             : {
    2110           0 :         if (mode->hdisplay == 1368 && mode->vdisplay == 768) {
    2111           0 :                 mode->hdisplay = 1366;
    2112           0 :                 mode->hsync_start--;
    2113           0 :                 mode->hsync_end--;
    2114           0 :                 drm_mode_set_name(mode);
    2115           0 :         }
    2116           0 : }
    2117             : 
    2118             : static int
    2119           0 : drm_gtf_modes_for_range(struct drm_connector *connector, struct edid *edid,
    2120             :                         struct detailed_timing *timing)
    2121             : {
    2122             :         int i, modes = 0;
    2123             :         struct drm_display_mode *newmode;
    2124           0 :         struct drm_device *dev = connector->dev;
    2125             : 
    2126           0 :         for (i = 0; i < ARRAY_SIZE(extra_modes); i++) {
    2127           0 :                 const struct minimode *m = &extra_modes[i];
    2128           0 :                 newmode = drm_gtf_mode(dev, m->w, m->h, m->r, 0, 0);
    2129           0 :                 if (!newmode)
    2130           0 :                         return modes;
    2131             : 
    2132           0 :                 fixup_mode_1366x768(newmode);
    2133           0 :                 if (!mode_in_range(newmode, edid, timing) ||
    2134           0 :                     !valid_inferred_mode(connector, newmode)) {
    2135           0 :                         drm_mode_destroy(dev, newmode);
    2136           0 :                         continue;
    2137             :                 }
    2138             : 
    2139           0 :                 drm_mode_probed_add(connector, newmode);
    2140           0 :                 modes++;
    2141           0 :         }
    2142             : 
    2143           0 :         return modes;
    2144           0 : }
    2145             : 
    2146             : static int
    2147           0 : drm_cvt_modes_for_range(struct drm_connector *connector, struct edid *edid,
    2148             :                         struct detailed_timing *timing)
    2149             : {
    2150             :         int i, modes = 0;
    2151             :         struct drm_display_mode *newmode;
    2152           0 :         struct drm_device *dev = connector->dev;
    2153           0 :         bool rb = drm_monitor_supports_rb(edid);
    2154             : 
    2155           0 :         for (i = 0; i < ARRAY_SIZE(extra_modes); i++) {
    2156           0 :                 const struct minimode *m = &extra_modes[i];
    2157           0 :                 newmode = drm_cvt_mode(dev, m->w, m->h, m->r, rb, 0, 0);
    2158           0 :                 if (!newmode)
    2159           0 :                         return modes;
    2160             : 
    2161           0 :                 fixup_mode_1366x768(newmode);
    2162           0 :                 if (!mode_in_range(newmode, edid, timing) ||
    2163           0 :                     !valid_inferred_mode(connector, newmode)) {
    2164           0 :                         drm_mode_destroy(dev, newmode);
    2165           0 :                         continue;
    2166             :                 }
    2167             : 
    2168           0 :                 drm_mode_probed_add(connector, newmode);
    2169           0 :                 modes++;
    2170           0 :         }
    2171             : 
    2172           0 :         return modes;
    2173           0 : }
    2174             : 
    2175             : static void
    2176           0 : do_inferred_modes(struct detailed_timing *timing, void *c)
    2177             : {
    2178           0 :         struct detailed_mode_closure *closure = c;
    2179           0 :         struct detailed_non_pixel *data = &timing->data.other_data;
    2180           0 :         struct detailed_data_monitor_range *range = &data->data.range;
    2181             : 
    2182           0 :         if (data->type != EDID_DETAIL_MONITOR_RANGE)
    2183           0 :                 return;
    2184             : 
    2185           0 :         closure->modes += drm_dmt_modes_for_range(closure->connector,
    2186           0 :                                                   closure->edid,
    2187             :                                                   timing);
    2188             :         
    2189           0 :         if (!version_greater(closure->edid, 1, 1))
    2190           0 :                 return; /* GTF not defined yet */
    2191             : 
    2192           0 :         switch (range->flags) {
    2193             :         case 0x02: /* secondary gtf, XXX could do more */
    2194             :         case 0x00: /* default gtf */
    2195           0 :                 closure->modes += drm_gtf_modes_for_range(closure->connector,
    2196           0 :                                                           closure->edid,
    2197             :                                                           timing);
    2198           0 :                 break;
    2199             :         case 0x04: /* cvt, only in 1.4+ */
    2200           0 :                 if (!version_greater(closure->edid, 1, 3))
    2201             :                         break;
    2202             : 
    2203           0 :                 closure->modes += drm_cvt_modes_for_range(closure->connector,
    2204           0 :                                                           closure->edid,
    2205             :                                                           timing);
    2206           0 :                 break;
    2207             :         case 0x01: /* just the ranges, no formula */
    2208             :         default:
    2209             :                 break;
    2210             :         }
    2211           0 : }
    2212             : 
    2213             : static int
    2214           0 : add_inferred_modes(struct drm_connector *connector, struct edid *edid)
    2215             : {
    2216           0 :         struct detailed_mode_closure closure = {
    2217             :                 .connector = connector,
    2218             :                 .edid = edid,
    2219             :         };
    2220             : 
    2221           0 :         if (version_greater(edid, 1, 0))
    2222           0 :                 drm_for_each_detailed_block((u8 *)edid, do_inferred_modes,
    2223             :                                             &closure);
    2224             : 
    2225           0 :         return closure.modes;
    2226           0 : }
    2227             : 
    2228             : static int
    2229           0 : drm_est3_modes(struct drm_connector *connector, struct detailed_timing *timing)
    2230             : {
    2231             :         int i, j, m, modes = 0;
    2232             :         struct drm_display_mode *mode;
    2233           0 :         u8 *est = ((u8 *)timing) + 5;
    2234             : 
    2235           0 :         for (i = 0; i < 6; i++) {
    2236           0 :                 for (j = 7; j >= 0; j--) {
    2237           0 :                         m = (i * 8) + (7 - j);
    2238           0 :                         if (m >= ARRAY_SIZE(est3_modes))
    2239             :                                 break;
    2240           0 :                         if (est[i] & (1 << j)) {
    2241           0 :                                 mode = drm_mode_find_dmt(connector->dev,
    2242           0 :                                                          est3_modes[m].w,
    2243           0 :                                                          est3_modes[m].h,
    2244           0 :                                                          est3_modes[m].r,
    2245           0 :                                                          est3_modes[m].rb);
    2246           0 :                                 if (mode) {
    2247           0 :                                         drm_mode_probed_add(connector, mode);
    2248           0 :                                         modes++;
    2249           0 :                                 }
    2250             :                         }
    2251             :                 }
    2252             :         }
    2253             : 
    2254           0 :         return modes;
    2255             : }
    2256             : 
    2257             : static void
    2258           0 : do_established_modes(struct detailed_timing *timing, void *c)
    2259             : {
    2260           0 :         struct detailed_mode_closure *closure = c;
    2261           0 :         struct detailed_non_pixel *data = &timing->data.other_data;
    2262             : 
    2263           0 :         if (data->type == EDID_DETAIL_EST_TIMINGS)
    2264           0 :                 closure->modes += drm_est3_modes(closure->connector, timing);
    2265           0 : }
    2266             : 
    2267             : /**
    2268             :  * add_established_modes - get est. modes from EDID and add them
    2269             :  * @connector: connector to add mode(s) to
    2270             :  * @edid: EDID block to scan
    2271             :  *
    2272             :  * Each EDID block contains a bitmap of the supported "established modes" list
    2273             :  * (defined above).  Tease them out and add them to the global modes list.
    2274             :  */
    2275             : static int
    2276           0 : add_established_modes(struct drm_connector *connector, struct edid *edid)
    2277             : {
    2278           0 :         struct drm_device *dev = connector->dev;
    2279           0 :         unsigned long est_bits = edid->established_timings.t1 |
    2280           0 :                 (edid->established_timings.t2 << 8) |
    2281           0 :                 ((edid->established_timings.mfg_rsvd & 0x80) << 9);
    2282             :         int i, modes = 0;
    2283           0 :         struct detailed_mode_closure closure = {
    2284             :                 .connector = connector,
    2285             :                 .edid = edid,
    2286             :         };
    2287             : 
    2288           0 :         for (i = 0; i <= EDID_EST_TIMINGS; i++) {
    2289           0 :                 if (est_bits & (1<<i)) {
    2290             :                         struct drm_display_mode *newmode;
    2291           0 :                         newmode = drm_mode_duplicate(dev, &edid_est_modes[i]);
    2292           0 :                         if (newmode) {
    2293           0 :                                 drm_mode_probed_add(connector, newmode);
    2294           0 :                                 modes++;
    2295           0 :                         }
    2296           0 :                 }
    2297             :         }
    2298             : 
    2299           0 :         if (version_greater(edid, 1, 0))
    2300           0 :                     drm_for_each_detailed_block((u8 *)edid,
    2301             :                                                 do_established_modes, &closure);
    2302             : 
    2303           0 :         return modes + closure.modes;
    2304           0 : }
    2305             : 
    2306             : static void
    2307           0 : do_standard_modes(struct detailed_timing *timing, void *c)
    2308             : {
    2309           0 :         struct detailed_mode_closure *closure = c;
    2310           0 :         struct detailed_non_pixel *data = &timing->data.other_data;
    2311           0 :         struct drm_connector *connector = closure->connector;
    2312           0 :         struct edid *edid = closure->edid;
    2313             : 
    2314           0 :         if (data->type == EDID_DETAIL_STD_MODES) {
    2315             :                 int i;
    2316           0 :                 for (i = 0; i < 6; i++) {
    2317             :                         struct std_timing *std;
    2318             :                         struct drm_display_mode *newmode;
    2319             : 
    2320           0 :                         std = &data->data.timings[i];
    2321           0 :                         newmode = drm_mode_std(connector, edid, std);
    2322           0 :                         if (newmode) {
    2323           0 :                                 drm_mode_probed_add(connector, newmode);
    2324           0 :                                 closure->modes++;
    2325           0 :                         }
    2326             :                 }
    2327           0 :         }
    2328           0 : }
    2329             : 
    2330             : /**
    2331             :  * add_standard_modes - get std. modes from EDID and add them
    2332             :  * @connector: connector to add mode(s) to
    2333             :  * @edid: EDID block to scan
    2334             :  *
    2335             :  * Standard modes can be calculated using the appropriate standard (DMT,
    2336             :  * GTF or CVT. Grab them from @edid and add them to the list.
    2337             :  */
    2338             : static int
    2339           0 : add_standard_modes(struct drm_connector *connector, struct edid *edid)
    2340             : {
    2341             :         int i, modes = 0;
    2342           0 :         struct detailed_mode_closure closure = {
    2343             :                 .connector = connector,
    2344             :                 .edid = edid,
    2345             :         };
    2346             : 
    2347           0 :         for (i = 0; i < EDID_STD_TIMINGS; i++) {
    2348             :                 struct drm_display_mode *newmode;
    2349             : 
    2350           0 :                 newmode = drm_mode_std(connector, edid,
    2351           0 :                                        &edid->standard_timings[i]);
    2352           0 :                 if (newmode) {
    2353           0 :                         drm_mode_probed_add(connector, newmode);
    2354           0 :                         modes++;
    2355           0 :                 }
    2356             :         }
    2357             : 
    2358           0 :         if (version_greater(edid, 1, 0))
    2359           0 :                 drm_for_each_detailed_block((u8 *)edid, do_standard_modes,
    2360             :                                             &closure);
    2361             : 
    2362             :         /* XXX should also look for standard codes in VTB blocks */
    2363             : 
    2364           0 :         return modes + closure.modes;
    2365           0 : }
    2366             : 
    2367           0 : static int drm_cvt_modes(struct drm_connector *connector,
    2368             :                          struct detailed_timing *timing)
    2369             : {
    2370             :         int i, j, modes = 0;
    2371             :         struct drm_display_mode *newmode;
    2372           0 :         struct drm_device *dev = connector->dev;
    2373             :         struct cvt_timing *cvt;
    2374             :         const int rates[] = { 60, 85, 75, 60, 50 };
    2375             :         const u8 empty[3] = { 0, 0, 0 };
    2376             : 
    2377           0 :         for (i = 0; i < 4; i++) {
    2378             :                 int uninitialized_var(width), height;
    2379           0 :                 cvt = &(timing->data.other_data.data.cvt[i]);
    2380             : 
    2381           0 :                 if (!memcmp(cvt->code, empty, 3))
    2382           0 :                         continue;
    2383             : 
    2384           0 :                 height = (cvt->code[0] + ((cvt->code[1] & 0xf0) << 4) + 1) * 2;
    2385           0 :                 switch (cvt->code[1] & 0x0c) {
    2386             :                 case 0x00:
    2387           0 :                         width = height * 4 / 3;
    2388           0 :                         break;
    2389             :                 case 0x04:
    2390           0 :                         width = height * 16 / 9;
    2391           0 :                         break;
    2392             :                 case 0x08:
    2393           0 :                         width = height * 16 / 10;
    2394           0 :                         break;
    2395             :                 case 0x0c:
    2396           0 :                         width = height * 15 / 9;
    2397           0 :                         break;
    2398             :                 }
    2399             : 
    2400           0 :                 for (j = 1; j < 5; j++) {
    2401           0 :                         if (cvt->code[2] & (1 << j)) {
    2402           0 :                                 newmode = drm_cvt_mode(dev, width, height,
    2403           0 :                                                        rates[j], j == 0,
    2404             :                                                        false, false);
    2405           0 :                                 if (newmode) {
    2406           0 :                                         drm_mode_probed_add(connector, newmode);
    2407           0 :                                         modes++;
    2408           0 :                                 }
    2409             :                         }
    2410             :                 }
    2411           0 :         }
    2412             : 
    2413           0 :         return modes;
    2414             : }
    2415             : 
    2416             : static void
    2417           0 : do_cvt_mode(struct detailed_timing *timing, void *c)
    2418             : {
    2419           0 :         struct detailed_mode_closure *closure = c;
    2420           0 :         struct detailed_non_pixel *data = &timing->data.other_data;
    2421             : 
    2422           0 :         if (data->type == EDID_DETAIL_CVT_3BYTE)
    2423           0 :                 closure->modes += drm_cvt_modes(closure->connector, timing);
    2424           0 : }
    2425             : 
    2426             : static int
    2427           0 : add_cvt_modes(struct drm_connector *connector, struct edid *edid)
    2428             : {       
    2429           0 :         struct detailed_mode_closure closure = {
    2430             :                 .connector = connector,
    2431             :                 .edid = edid,
    2432             :         };
    2433             : 
    2434           0 :         if (version_greater(edid, 1, 2))
    2435           0 :                 drm_for_each_detailed_block((u8 *)edid, do_cvt_mode, &closure);
    2436             : 
    2437             :         /* XXX should also look for CVT codes in VTB blocks */
    2438             : 
    2439           0 :         return closure.modes;
    2440           0 : }
    2441             : 
    2442             : static void fixup_detailed_cea_mode_clock(struct drm_display_mode *mode);
    2443             : 
    2444             : static void
    2445           0 : do_detailed_mode(struct detailed_timing *timing, void *c)
    2446             : {
    2447           0 :         struct detailed_mode_closure *closure = c;
    2448             :         struct drm_display_mode *newmode;
    2449             : 
    2450           0 :         if (timing->pixel_clock) {
    2451           0 :                 newmode = drm_mode_detailed(closure->connector->dev,
    2452           0 :                                             closure->edid, timing,
    2453           0 :                                             closure->quirks);
    2454           0 :                 if (!newmode)
    2455           0 :                         return;
    2456             : 
    2457           0 :                 if (closure->preferred)
    2458           0 :                         newmode->type |= DRM_MODE_TYPE_PREFERRED;
    2459             : 
    2460             :                 /*
    2461             :                  * Detailed modes are limited to 10kHz pixel clock resolution,
    2462             :                  * so fix up anything that looks like CEA/HDMI mode, but the clock
    2463             :                  * is just slightly off.
    2464             :                  */
    2465           0 :                 fixup_detailed_cea_mode_clock(newmode);
    2466             : 
    2467           0 :                 drm_mode_probed_add(closure->connector, newmode);
    2468           0 :                 closure->modes++;
    2469           0 :                 closure->preferred = 0;
    2470           0 :         }
    2471           0 : }
    2472             : 
    2473             : /*
    2474             :  * add_detailed_modes - Add modes from detailed timings
    2475             :  * @connector: attached connector
    2476             :  * @edid: EDID block to scan
    2477             :  * @quirks: quirks to apply
    2478             :  */
    2479             : static int
    2480           0 : add_detailed_modes(struct drm_connector *connector, struct edid *edid,
    2481             :                    u32 quirks)
    2482             : {
    2483           0 :         struct detailed_mode_closure closure = {
    2484             :                 .connector = connector,
    2485             :                 .edid = edid,
    2486             :                 .preferred = 1,
    2487             :                 .quirks = quirks,
    2488             :         };
    2489             : 
    2490           0 :         if (closure.preferred && !version_greater(edid, 1, 3))
    2491           0 :                 closure.preferred =
    2492           0 :                     (edid->features & DRM_EDID_FEATURE_PREFERRED_TIMING);
    2493             : 
    2494           0 :         drm_for_each_detailed_block((u8 *)edid, do_detailed_mode, &closure);
    2495             : 
    2496           0 :         return closure.modes;
    2497           0 : }
    2498             : 
    2499             : #define AUDIO_BLOCK     0x01
    2500             : #define VIDEO_BLOCK     0x02
    2501             : #define VENDOR_BLOCK    0x03
    2502             : #define SPEAKER_BLOCK   0x04
    2503             : #define VIDEO_CAPABILITY_BLOCK  0x07
    2504             : #define EDID_BASIC_AUDIO        (1 << 6)
    2505             : #define EDID_CEA_YCRCB444       (1 << 5)
    2506             : #define EDID_CEA_YCRCB422       (1 << 4)
    2507             : #define EDID_CEA_VCDB_QS        (1 << 6)
    2508             : 
    2509             : /*
    2510             :  * Search EDID for CEA extension block.
    2511             :  */
    2512           0 : static u8 *drm_find_edid_extension(struct edid *edid, int ext_id)
    2513             : {
    2514             :         u8 *edid_ext = NULL;
    2515             :         int i;
    2516             : 
    2517             :         /* No EDID or EDID extensions */
    2518           0 :         if (edid == NULL || edid->extensions == 0)
    2519           0 :                 return NULL;
    2520             : 
    2521             :         /* Find CEA extension */
    2522           0 :         for (i = 0; i < edid->extensions; i++) {
    2523           0 :                 edid_ext = (u8 *)edid + EDID_LENGTH * (i + 1);
    2524           0 :                 if (edid_ext[0] == ext_id)
    2525             :                         break;
    2526             :         }
    2527             : 
    2528           0 :         if (i == edid->extensions)
    2529           0 :                 return NULL;
    2530             : 
    2531           0 :         return edid_ext;
    2532           0 : }
    2533             : 
    2534           0 : static u8 *drm_find_cea_extension(struct edid *edid)
    2535             : {
    2536           0 :         return drm_find_edid_extension(edid, CEA_EXT);
    2537             : }
    2538             : 
    2539           0 : static u8 *drm_find_displayid_extension(struct edid *edid)
    2540             : {
    2541           0 :         return drm_find_edid_extension(edid, DISPLAYID_EXT);
    2542             : }
    2543             : 
    2544             : /*
    2545             :  * Calculate the alternate clock for the CEA mode
    2546             :  * (60Hz vs. 59.94Hz etc.)
    2547             :  */
    2548             : static unsigned int
    2549           0 : cea_mode_alternate_clock(const struct drm_display_mode *cea_mode)
    2550             : {
    2551           0 :         unsigned int clock = cea_mode->clock;
    2552             : 
    2553           0 :         if (cea_mode->vrefresh % 6 != 0)
    2554           0 :                 return clock;
    2555             : 
    2556             :         /*
    2557             :          * edid_cea_modes contains the 59.94Hz
    2558             :          * variant for 240 and 480 line modes,
    2559             :          * and the 60Hz variant otherwise.
    2560             :          */
    2561           0 :         if (cea_mode->vdisplay == 240 || cea_mode->vdisplay == 480)
    2562           0 :                 clock = DIV_ROUND_CLOSEST(clock * 1001, 1000);
    2563             :         else
    2564           0 :                 clock = DIV_ROUND_CLOSEST(clock * 1000, 1001);
    2565             : 
    2566           0 :         return clock;
    2567           0 : }
    2568             : 
    2569             : /**
    2570             :  * drm_match_cea_mode - look for a CEA mode matching given mode
    2571             :  * @to_match: display mode
    2572             :  *
    2573             :  * Return: The CEA Video ID (VIC) of the mode or 0 if it isn't a CEA-861
    2574             :  * mode.
    2575             :  */
    2576           0 : u8 drm_match_cea_mode(const struct drm_display_mode *to_match)
    2577             : {
    2578             :         u8 mode;
    2579             : 
    2580           0 :         if (!to_match->clock)
    2581           0 :                 return 0;
    2582             : 
    2583           0 :         for (mode = 0; mode < ARRAY_SIZE(edid_cea_modes); mode++) {
    2584           0 :                 const struct drm_display_mode *cea_mode = &edid_cea_modes[mode];
    2585             :                 unsigned int clock1, clock2;
    2586             : 
    2587             :                 /* Check both 60Hz and 59.94Hz */
    2588           0 :                 clock1 = cea_mode->clock;
    2589           0 :                 clock2 = cea_mode_alternate_clock(cea_mode);
    2590             : 
    2591           0 :                 if ((KHZ2PICOS(to_match->clock) == KHZ2PICOS(clock1) ||
    2592           0 :                      KHZ2PICOS(to_match->clock) == KHZ2PICOS(clock2)) &&
    2593           0 :                     drm_mode_equal_no_clocks_no_stereo(to_match, cea_mode))
    2594           0 :                         return mode + 1;
    2595           0 :         }
    2596           0 :         return 0;
    2597           0 : }
    2598             : EXPORT_SYMBOL(drm_match_cea_mode);
    2599             : 
    2600             : /**
    2601             :  * drm_get_cea_aspect_ratio - get the picture aspect ratio corresponding to
    2602             :  * the input VIC from the CEA mode list
    2603             :  * @video_code: ID given to each of the CEA modes
    2604             :  *
    2605             :  * Returns picture aspect ratio
    2606             :  */
    2607           0 : enum hdmi_picture_aspect drm_get_cea_aspect_ratio(const u8 video_code)
    2608             : {
    2609             :         /* return picture aspect ratio for video_code - 1 to access the
    2610             :          * right array element
    2611             :         */
    2612           0 :         return edid_cea_modes[video_code-1].picture_aspect_ratio;
    2613             : }
    2614             : EXPORT_SYMBOL(drm_get_cea_aspect_ratio);
    2615             : 
    2616             : /*
    2617             :  * Calculate the alternate clock for HDMI modes (those from the HDMI vendor
    2618             :  * specific block).
    2619             :  *
    2620             :  * It's almost like cea_mode_alternate_clock(), we just need to add an
    2621             :  * exception for the VIC 4 mode (4096x2160@24Hz): no alternate clock for this
    2622             :  * one.
    2623             :  */
    2624             : static unsigned int
    2625           0 : hdmi_mode_alternate_clock(const struct drm_display_mode *hdmi_mode)
    2626             : {
    2627           0 :         if (hdmi_mode->vdisplay == 4096 && hdmi_mode->hdisplay == 2160)
    2628           0 :                 return hdmi_mode->clock;
    2629             : 
    2630           0 :         return cea_mode_alternate_clock(hdmi_mode);
    2631           0 : }
    2632             : 
    2633             : /*
    2634             :  * drm_match_hdmi_mode - look for a HDMI mode matching given mode
    2635             :  * @to_match: display mode
    2636             :  *
    2637             :  * An HDMI mode is one defined in the HDMI vendor specific block.
    2638             :  *
    2639             :  * Returns the HDMI Video ID (VIC) of the mode or 0 if it isn't one.
    2640             :  */
    2641           0 : static u8 drm_match_hdmi_mode(const struct drm_display_mode *to_match)
    2642             : {
    2643             :         u8 mode;
    2644             : 
    2645           0 :         if (!to_match->clock)
    2646           0 :                 return 0;
    2647             : 
    2648           0 :         for (mode = 0; mode < ARRAY_SIZE(edid_4k_modes); mode++) {
    2649           0 :                 const struct drm_display_mode *hdmi_mode = &edid_4k_modes[mode];
    2650             :                 unsigned int clock1, clock2;
    2651             : 
    2652             :                 /* Make sure to also match alternate clocks */
    2653           0 :                 clock1 = hdmi_mode->clock;
    2654           0 :                 clock2 = hdmi_mode_alternate_clock(hdmi_mode);
    2655             : 
    2656           0 :                 if ((KHZ2PICOS(to_match->clock) == KHZ2PICOS(clock1) ||
    2657           0 :                      KHZ2PICOS(to_match->clock) == KHZ2PICOS(clock2)) &&
    2658           0 :                     drm_mode_equal_no_clocks_no_stereo(to_match, hdmi_mode))
    2659           0 :                         return mode + 1;
    2660           0 :         }
    2661           0 :         return 0;
    2662           0 : }
    2663             : 
    2664             : static int
    2665           0 : add_alternate_cea_modes(struct drm_connector *connector, struct edid *edid)
    2666             : {
    2667           0 :         struct drm_device *dev = connector->dev;
    2668             :         struct drm_display_mode *mode, *tmp;
    2669           0 :         DRM_LIST_HEAD(list);
    2670             :         int modes = 0;
    2671             : 
    2672             :         /* Don't add CEA modes if the CEA extension block is missing */
    2673           0 :         if (!drm_find_cea_extension(edid))
    2674           0 :                 return 0;
    2675             : 
    2676             :         /*
    2677             :          * Go through all probed modes and create a new mode
    2678             :          * with the alternate clock for certain CEA modes.
    2679             :          */
    2680           0 :         list_for_each_entry(mode, &connector->probed_modes, head) {
    2681             :                 const struct drm_display_mode *cea_mode = NULL;
    2682             :                 struct drm_display_mode *newmode;
    2683           0 :                 u8 mode_idx = drm_match_cea_mode(mode) - 1;
    2684             :                 unsigned int clock1, clock2;
    2685             : 
    2686           0 :                 if (mode_idx < ARRAY_SIZE(edid_cea_modes)) {
    2687           0 :                         cea_mode = &edid_cea_modes[mode_idx];
    2688           0 :                         clock2 = cea_mode_alternate_clock(cea_mode);
    2689           0 :                 } else {
    2690           0 :                         mode_idx = drm_match_hdmi_mode(mode) - 1;
    2691           0 :                         if (mode_idx < ARRAY_SIZE(edid_4k_modes)) {
    2692           0 :                                 cea_mode = &edid_4k_modes[mode_idx];
    2693           0 :                                 clock2 = hdmi_mode_alternate_clock(cea_mode);
    2694           0 :                         }
    2695             :                 }
    2696             : 
    2697           0 :                 if (!cea_mode)
    2698           0 :                         continue;
    2699             : 
    2700           0 :                 clock1 = cea_mode->clock;
    2701             : 
    2702           0 :                 if (clock1 == clock2)
    2703           0 :                         continue;
    2704             : 
    2705           0 :                 if (mode->clock != clock1 && mode->clock != clock2)
    2706           0 :                         continue;
    2707             : 
    2708           0 :                 newmode = drm_mode_duplicate(dev, cea_mode);
    2709           0 :                 if (!newmode)
    2710           0 :                         continue;
    2711             : 
    2712             :                 /* Carry over the stereo flags */
    2713           0 :                 newmode->flags |= mode->flags & DRM_MODE_FLAG_3D_MASK;
    2714             : 
    2715             :                 /*
    2716             :                  * The current mode could be either variant. Make
    2717             :                  * sure to pick the "other" clock for the new mode.
    2718             :                  */
    2719           0 :                 if (mode->clock != clock1)
    2720           0 :                         newmode->clock = clock1;
    2721             :                 else
    2722           0 :                         newmode->clock = clock2;
    2723             : 
    2724           0 :                 list_add_tail(&newmode->head, &list);
    2725           0 :         }
    2726             : 
    2727           0 :         list_for_each_entry_safe(mode, tmp, &list, head) {
    2728           0 :                 list_del(&mode->head);
    2729           0 :                 drm_mode_probed_add(connector, mode);
    2730           0 :                 modes++;
    2731             :         }
    2732             : 
    2733           0 :         return modes;
    2734           0 : }
    2735             : 
    2736             : static struct drm_display_mode *
    2737           0 : drm_display_mode_from_vic_index(struct drm_connector *connector,
    2738             :                                 const u8 *video_db, u8 video_len,
    2739             :                                 u8 video_index)
    2740             : {
    2741           0 :         struct drm_device *dev = connector->dev;
    2742             :         struct drm_display_mode *newmode;
    2743             :         u8 cea_mode;
    2744             : 
    2745           0 :         if (video_db == NULL || video_index >= video_len)
    2746           0 :                 return NULL;
    2747             : 
    2748             :         /* CEA modes are numbered 1..127 */
    2749           0 :         cea_mode = (video_db[video_index] & 127) - 1;
    2750           0 :         if (cea_mode >= ARRAY_SIZE(edid_cea_modes))
    2751           0 :                 return NULL;
    2752             : 
    2753           0 :         newmode = drm_mode_duplicate(dev, &edid_cea_modes[cea_mode]);
    2754           0 :         if (!newmode)
    2755           0 :                 return NULL;
    2756             : 
    2757           0 :         newmode->vrefresh = 0;
    2758             : 
    2759           0 :         return newmode;
    2760           0 : }
    2761             : 
    2762             : static int
    2763           0 : do_cea_modes(struct drm_connector *connector, const u8 *db, u8 len)
    2764             : {
    2765             :         int i, modes = 0;
    2766             : 
    2767           0 :         for (i = 0; i < len; i++) {
    2768             :                 struct drm_display_mode *mode;
    2769           0 :                 mode = drm_display_mode_from_vic_index(connector, db, len, i);
    2770           0 :                 if (mode) {
    2771           0 :                         drm_mode_probed_add(connector, mode);
    2772           0 :                         modes++;
    2773           0 :                 }
    2774             :         }
    2775             : 
    2776           0 :         return modes;
    2777             : }
    2778             : 
    2779             : struct stereo_mandatory_mode {
    2780             :         int width, height, vrefresh;
    2781             :         unsigned int flags;
    2782             : };
    2783             : 
    2784             : static const struct stereo_mandatory_mode stereo_mandatory_modes[] = {
    2785             :         { 1920, 1080, 24, DRM_MODE_FLAG_3D_TOP_AND_BOTTOM },
    2786             :         { 1920, 1080, 24, DRM_MODE_FLAG_3D_FRAME_PACKING },
    2787             :         { 1920, 1080, 50,
    2788             :           DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_3D_SIDE_BY_SIDE_HALF },
    2789             :         { 1920, 1080, 60,
    2790             :           DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_3D_SIDE_BY_SIDE_HALF },
    2791             :         { 1280, 720,  50, DRM_MODE_FLAG_3D_TOP_AND_BOTTOM },
    2792             :         { 1280, 720,  50, DRM_MODE_FLAG_3D_FRAME_PACKING },
    2793             :         { 1280, 720,  60, DRM_MODE_FLAG_3D_TOP_AND_BOTTOM },
    2794             :         { 1280, 720,  60, DRM_MODE_FLAG_3D_FRAME_PACKING }
    2795             : };
    2796             : 
    2797             : static bool
    2798           0 : stereo_match_mandatory(const struct drm_display_mode *mode,
    2799             :                        const struct stereo_mandatory_mode *stereo_mode)
    2800             : {
    2801           0 :         unsigned int interlaced = mode->flags & DRM_MODE_FLAG_INTERLACE;
    2802             : 
    2803           0 :         return mode->hdisplay == stereo_mode->width &&
    2804           0 :                mode->vdisplay == stereo_mode->height &&
    2805           0 :                interlaced == (stereo_mode->flags & DRM_MODE_FLAG_INTERLACE) &&
    2806           0 :                drm_mode_vrefresh(mode) == stereo_mode->vrefresh;
    2807             : }
    2808             : 
    2809           0 : static int add_hdmi_mandatory_stereo_modes(struct drm_connector *connector)
    2810             : {
    2811           0 :         struct drm_device *dev = connector->dev;
    2812             :         const struct drm_display_mode *mode;
    2813           0 :         struct list_head stereo_modes;
    2814             :         int modes = 0, i;
    2815             : 
    2816           0 :         INIT_LIST_HEAD(&stereo_modes);
    2817             : 
    2818           0 :         list_for_each_entry(mode, &connector->probed_modes, head) {
    2819           0 :                 for (i = 0; i < ARRAY_SIZE(stereo_mandatory_modes); i++) {
    2820             :                         const struct stereo_mandatory_mode *mandatory;
    2821             :                         struct drm_display_mode *new_mode;
    2822             : 
    2823           0 :                         if (!stereo_match_mandatory(mode,
    2824           0 :                                                     &stereo_mandatory_modes[i]))
    2825           0 :                                 continue;
    2826             : 
    2827             :                         mandatory = &stereo_mandatory_modes[i];
    2828           0 :                         new_mode = drm_mode_duplicate(dev, mode);
    2829           0 :                         if (!new_mode)
    2830           0 :                                 continue;
    2831             : 
    2832           0 :                         new_mode->flags |= mandatory->flags;
    2833           0 :                         list_add_tail(&new_mode->head, &stereo_modes);
    2834           0 :                         modes++;
    2835           0 :                 }
    2836             :         }
    2837             : 
    2838           0 :         list_splice_tail(&stereo_modes, &connector->probed_modes);
    2839             : 
    2840           0 :         return modes;
    2841           0 : }
    2842             : 
    2843           0 : static int add_hdmi_mode(struct drm_connector *connector, u8 vic)
    2844             : {
    2845           0 :         struct drm_device *dev = connector->dev;
    2846             :         struct drm_display_mode *newmode;
    2847             : 
    2848           0 :         vic--; /* VICs start at 1 */
    2849           0 :         if (vic >= ARRAY_SIZE(edid_4k_modes)) {
    2850           0 :                 DRM_ERROR("Unknown HDMI VIC: %d\n", vic);
    2851           0 :                 return 0;
    2852             :         }
    2853             : 
    2854           0 :         newmode = drm_mode_duplicate(dev, &edid_4k_modes[vic]);
    2855           0 :         if (!newmode)
    2856           0 :                 return 0;
    2857             : 
    2858           0 :         drm_mode_probed_add(connector, newmode);
    2859             : 
    2860           0 :         return 1;
    2861           0 : }
    2862             : 
    2863           0 : static int add_3d_struct_modes(struct drm_connector *connector, u16 structure,
    2864             :                                const u8 *video_db, u8 video_len, u8 video_index)
    2865             : {
    2866             :         struct drm_display_mode *newmode;
    2867             :         int modes = 0;
    2868             : 
    2869           0 :         if (structure & (1 << 0)) {
    2870           0 :                 newmode = drm_display_mode_from_vic_index(connector, video_db,
    2871             :                                                           video_len,
    2872             :                                                           video_index);
    2873           0 :                 if (newmode) {
    2874           0 :                         newmode->flags |= DRM_MODE_FLAG_3D_FRAME_PACKING;
    2875           0 :                         drm_mode_probed_add(connector, newmode);
    2876             :                         modes++;
    2877           0 :                 }
    2878             :         }
    2879           0 :         if (structure & (1 << 6)) {
    2880           0 :                 newmode = drm_display_mode_from_vic_index(connector, video_db,
    2881             :                                                           video_len,
    2882             :                                                           video_index);
    2883           0 :                 if (newmode) {
    2884           0 :                         newmode->flags |= DRM_MODE_FLAG_3D_TOP_AND_BOTTOM;
    2885           0 :                         drm_mode_probed_add(connector, newmode);
    2886           0 :                         modes++;
    2887           0 :                 }
    2888             :         }
    2889           0 :         if (structure & (1 << 8)) {
    2890           0 :                 newmode = drm_display_mode_from_vic_index(connector, video_db,
    2891             :                                                           video_len,
    2892             :                                                           video_index);
    2893           0 :                 if (newmode) {
    2894           0 :                         newmode->flags |= DRM_MODE_FLAG_3D_SIDE_BY_SIDE_HALF;
    2895           0 :                         drm_mode_probed_add(connector, newmode);
    2896           0 :                         modes++;
    2897           0 :                 }
    2898             :         }
    2899             : 
    2900           0 :         return modes;
    2901             : }
    2902             : 
    2903             : /*
    2904             :  * do_hdmi_vsdb_modes - Parse the HDMI Vendor Specific data block
    2905             :  * @connector: connector corresponding to the HDMI sink
    2906             :  * @db: start of the CEA vendor specific block
    2907             :  * @len: length of the CEA block payload, ie. one can access up to db[len]
    2908             :  *
    2909             :  * Parses the HDMI VSDB looking for modes to add to @connector. This function
    2910             :  * also adds the stereo 3d modes when applicable.
    2911             :  */
    2912             : static int
    2913           0 : do_hdmi_vsdb_modes(struct drm_connector *connector, const u8 *db, u8 len,
    2914             :                    const u8 *video_db, u8 video_len)
    2915             : {
    2916             :         int modes = 0, offset = 0, i, multi_present = 0, multi_len;
    2917             :         u8 vic_len, hdmi_3d_len = 0;
    2918             :         u16 mask;
    2919             :         u16 structure_all;
    2920             : 
    2921           0 :         if (len < 8)
    2922             :                 goto out;
    2923             : 
    2924             :         /* no HDMI_Video_Present */
    2925           0 :         if (!(db[8] & (1 << 5)))
    2926             :                 goto out;
    2927             : 
    2928             :         /* Latency_Fields_Present */
    2929           0 :         if (db[8] & (1 << 7))
    2930           0 :                 offset += 2;
    2931             : 
    2932             :         /* I_Latency_Fields_Present */
    2933           0 :         if (db[8] & (1 << 6))
    2934           0 :                 offset += 2;
    2935             : 
    2936             :         /* the declared length is not long enough for the 2 first bytes
    2937             :          * of additional video format capabilities */
    2938           0 :         if (len < (8 + offset + 2))
    2939             :                 goto out;
    2940             : 
    2941             :         /* 3D_Present */
    2942           0 :         offset++;
    2943           0 :         if (db[8 + offset] & (1 << 7)) {
    2944           0 :                 modes += add_hdmi_mandatory_stereo_modes(connector);
    2945             : 
    2946             :                 /* 3D_Multi_present */
    2947           0 :                 multi_present = (db[8 + offset] & 0x60) >> 5;
    2948           0 :         }
    2949             : 
    2950           0 :         offset++;
    2951           0 :         vic_len = db[8 + offset] >> 5;
    2952           0 :         hdmi_3d_len = db[8 + offset] & 0x1f;
    2953             : 
    2954           0 :         for (i = 0; i < vic_len && len >= (9 + offset + i); i++) {
    2955             :                 u8 vic;
    2956             : 
    2957           0 :                 vic = db[9 + offset + i];
    2958           0 :                 modes += add_hdmi_mode(connector, vic);
    2959             :         }
    2960           0 :         offset += 1 + vic_len;
    2961             : 
    2962           0 :         if (multi_present == 1)
    2963           0 :                 multi_len = 2;
    2964           0 :         else if (multi_present == 2)
    2965           0 :                 multi_len = 4;
    2966             :         else
    2967             :                 multi_len = 0;
    2968             : 
    2969           0 :         if (len < (8 + offset + hdmi_3d_len - 1))
    2970             :                 goto out;
    2971             : 
    2972           0 :         if (hdmi_3d_len < multi_len)
    2973             :                 goto out;
    2974             : 
    2975           0 :         if (multi_present == 1 || multi_present == 2) {
    2976             :                 /* 3D_Structure_ALL */
    2977           0 :                 structure_all = (db[8 + offset] << 8) | db[9 + offset];
    2978             : 
    2979             :                 /* check if 3D_MASK is present */
    2980           0 :                 if (multi_present == 2)
    2981           0 :                         mask = (db[10 + offset] << 8) | db[11 + offset];
    2982             :                 else
    2983             :                         mask = 0xffff;
    2984             : 
    2985           0 :                 for (i = 0; i < 16; i++) {
    2986           0 :                         if (mask & (1 << i))
    2987           0 :                                 modes += add_3d_struct_modes(connector,
    2988             :                                                 structure_all,
    2989             :                                                 video_db,
    2990           0 :                                                 video_len, i);
    2991             :                 }
    2992             :         }
    2993             : 
    2994           0 :         offset += multi_len;
    2995             : 
    2996           0 :         for (i = 0; i < (hdmi_3d_len - multi_len); i++) {
    2997             :                 int vic_index;
    2998             :                 struct drm_display_mode *newmode = NULL;
    2999             :                 unsigned int newflag = 0;
    3000             :                 bool detail_present;
    3001             : 
    3002           0 :                 detail_present = ((db[8 + offset + i] & 0x0f) > 7);
    3003             : 
    3004           0 :                 if (detail_present && (i + 1 == hdmi_3d_len - multi_len))
    3005           0 :                         break;
    3006             : 
    3007             :                 /* 2D_VIC_order_X */
    3008           0 :                 vic_index = db[8 + offset + i] >> 4;
    3009             : 
    3010             :                 /* 3D_Structure_X */
    3011           0 :                 switch (db[8 + offset + i] & 0x0f) {
    3012             :                 case 0:
    3013             :                         newflag = DRM_MODE_FLAG_3D_FRAME_PACKING;
    3014           0 :                         break;
    3015             :                 case 6:
    3016             :                         newflag = DRM_MODE_FLAG_3D_TOP_AND_BOTTOM;
    3017           0 :                         break;
    3018             :                 case 8:
    3019             :                         /* 3D_Detail_X */
    3020           0 :                         if ((db[9 + offset + i] >> 4) == 1)
    3021           0 :                                 newflag = DRM_MODE_FLAG_3D_SIDE_BY_SIDE_HALF;
    3022             :                         break;
    3023             :                 }
    3024             : 
    3025           0 :                 if (newflag != 0) {
    3026           0 :                         newmode = drm_display_mode_from_vic_index(connector,
    3027             :                                                                   video_db,
    3028             :                                                                   video_len,
    3029           0 :                                                                   vic_index);
    3030             : 
    3031           0 :                         if (newmode) {
    3032           0 :                                 newmode->flags |= newflag;
    3033           0 :                                 drm_mode_probed_add(connector, newmode);
    3034           0 :                                 modes++;
    3035           0 :                         }
    3036             :                 }
    3037             : 
    3038           0 :                 if (detail_present)
    3039           0 :                         i++;
    3040           0 :         }
    3041             : 
    3042             : out:
    3043           0 :         return modes;
    3044             : }
    3045             : 
    3046             : static int
    3047           0 : cea_db_payload_len(const u8 *db)
    3048             : {
    3049           0 :         return db[0] & 0x1f;
    3050             : }
    3051             : 
    3052             : static int
    3053           0 : cea_db_tag(const u8 *db)
    3054             : {
    3055           0 :         return db[0] >> 5;
    3056             : }
    3057             : 
    3058             : static int
    3059           0 : cea_revision(const u8 *cea)
    3060             : {
    3061           0 :         return cea[1];
    3062             : }
    3063             : 
    3064             : static int
    3065           0 : cea_db_offsets(const u8 *cea, int *start, int *end)
    3066             : {
    3067             :         /* Data block offset in CEA extension block */
    3068           0 :         *start = 4;
    3069           0 :         *end = cea[2];
    3070           0 :         if (*end == 0)
    3071           0 :                 *end = 127;
    3072           0 :         if (*end < 4 || *end > 127)
    3073           0 :                 return -ERANGE;
    3074           0 :         return 0;
    3075           0 : }
    3076             : 
    3077           0 : static bool cea_db_is_hdmi_vsdb(const u8 *db)
    3078             : {
    3079             :         int hdmi_id;
    3080             : 
    3081           0 :         if (cea_db_tag(db) != VENDOR_BLOCK)
    3082           0 :                 return false;
    3083             : 
    3084           0 :         if (cea_db_payload_len(db) < 5)
    3085           0 :                 return false;
    3086             : 
    3087           0 :         hdmi_id = db[1] | (db[2] << 8) | (db[3] << 16);
    3088             : 
    3089           0 :         return hdmi_id == HDMI_IEEE_OUI;
    3090           0 : }
    3091             : 
    3092             : #define for_each_cea_db(cea, i, start, end) \
    3093             :         for ((i) = (start); (i) < (end) && (i) + cea_db_payload_len(&(cea)[(i)]) < (end); (i) += cea_db_payload_len(&(cea)[(i)]) + 1)
    3094             : 
    3095             : static int
    3096           0 : add_cea_modes(struct drm_connector *connector, struct edid *edid)
    3097             : {
    3098           0 :         const u8 *cea = drm_find_cea_extension(edid);
    3099             :         const u8 *db, *hdmi = NULL, *video = NULL;
    3100             :         u8 dbl, hdmi_len, video_len = 0;
    3101             :         int modes = 0;
    3102             : 
    3103           0 :         if (cea && cea_revision(cea) >= 3) {
    3104           0 :                 int i, start, end;
    3105             : 
    3106           0 :                 if (cea_db_offsets(cea, &start, &end))
    3107           0 :                         return 0;
    3108             : 
    3109           0 :                 for_each_cea_db(cea, i, start, end) {
    3110             :                         db = &cea[i];
    3111           0 :                         dbl = cea_db_payload_len(db);
    3112             : 
    3113           0 :                         if (cea_db_tag(db) == VIDEO_BLOCK) {
    3114           0 :                                 video = db + 1;
    3115             :                                 video_len = dbl;
    3116           0 :                                 modes += do_cea_modes(connector, video, dbl);
    3117           0 :                         }
    3118           0 :                         else if (cea_db_is_hdmi_vsdb(db)) {
    3119             :                                 hdmi = db;
    3120             :                                 hdmi_len = dbl;
    3121           0 :                         }
    3122             :                 }
    3123           0 :         }
    3124             : 
    3125             :         /*
    3126             :          * We parse the HDMI VSDB after having added the cea modes as we will
    3127             :          * be patching their flags when the sink supports stereo 3D.
    3128             :          */
    3129           0 :         if (hdmi)
    3130           0 :                 modes += do_hdmi_vsdb_modes(connector, hdmi, hdmi_len, video,
    3131             :                                             video_len);
    3132             : 
    3133           0 :         return modes;
    3134           0 : }
    3135             : 
    3136           0 : static void fixup_detailed_cea_mode_clock(struct drm_display_mode *mode)
    3137             : {
    3138             :         const struct drm_display_mode *cea_mode;
    3139             :         int clock1, clock2, clock;
    3140             :         u8 mode_idx;
    3141             :         const char *type;
    3142             : 
    3143           0 :         mode_idx = drm_match_cea_mode(mode) - 1;
    3144           0 :         if (mode_idx < ARRAY_SIZE(edid_cea_modes)) {
    3145             :                 type = "CEA";
    3146           0 :                 cea_mode = &edid_cea_modes[mode_idx];
    3147           0 :                 clock1 = cea_mode->clock;
    3148           0 :                 clock2 = cea_mode_alternate_clock(cea_mode);
    3149           0 :         } else {
    3150           0 :                 mode_idx = drm_match_hdmi_mode(mode) - 1;
    3151           0 :                 if (mode_idx < ARRAY_SIZE(edid_4k_modes)) {
    3152             :                         type = "HDMI";
    3153           0 :                         cea_mode = &edid_4k_modes[mode_idx];
    3154           0 :                         clock1 = cea_mode->clock;
    3155           0 :                         clock2 = hdmi_mode_alternate_clock(cea_mode);
    3156             :                 } else {
    3157           0 :                         return;
    3158             :                 }
    3159             :         }
    3160             : 
    3161             :         /* pick whichever is closest */
    3162           0 :         if (abs(mode->clock - clock1) < abs(mode->clock - clock2))
    3163           0 :                 clock = clock1;
    3164             :         else
    3165             :                 clock = clock2;
    3166             : 
    3167           0 :         if (mode->clock == clock)
    3168           0 :                 return;
    3169             : 
    3170             :         DRM_DEBUG("detailed mode matches %s VIC %d, adjusting clock %d -> %d\n",
    3171             :                   type, mode_idx + 1, mode->clock, clock);
    3172           0 :         mode->clock = clock;
    3173           0 : }
    3174             : 
    3175             : static void
    3176           0 : parse_hdmi_vsdb(struct drm_connector *connector, const u8 *db)
    3177             : {
    3178           0 :         u8 len = cea_db_payload_len(db);
    3179             : 
    3180           0 :         if (len >= 6) {
    3181           0 :                 connector->eld[5] |= (db[6] >> 7) << 1;  /* Supports_AI */
    3182           0 :                 connector->dvi_dual = db[6] & 1;
    3183           0 :         }
    3184           0 :         if (len >= 7)
    3185           0 :                 connector->max_tmds_clock = db[7] * 5;
    3186           0 :         if (len >= 8) {
    3187           0 :                 connector->latency_present[0] = db[8] >> 7;
    3188           0 :                 connector->latency_present[1] = (db[8] >> 6) & 1;
    3189           0 :         }
    3190           0 :         if (len >= 9)
    3191           0 :                 connector->video_latency[0] = db[9];
    3192           0 :         if (len >= 10)
    3193           0 :                 connector->audio_latency[0] = db[10];
    3194           0 :         if (len >= 11)
    3195           0 :                 connector->video_latency[1] = db[11];
    3196           0 :         if (len >= 12)
    3197           0 :                 connector->audio_latency[1] = db[12];
    3198             : 
    3199             :         DRM_DEBUG_KMS("HDMI: DVI dual %d, "
    3200             :                     "max TMDS clock %d, "
    3201             :                     "latency present %d %d, "
    3202             :                     "video latency %d %d, "
    3203             :                     "audio latency %d %d\n",
    3204             :                     connector->dvi_dual,
    3205             :                     connector->max_tmds_clock,
    3206             :               (int) connector->latency_present[0],
    3207             :               (int) connector->latency_present[1],
    3208             :                     connector->video_latency[0],
    3209             :                     connector->video_latency[1],
    3210             :                     connector->audio_latency[0],
    3211             :                     connector->audio_latency[1]);
    3212           0 : }
    3213             : 
    3214             : static void
    3215           0 : monitor_name(struct detailed_timing *t, void *data)
    3216             : {
    3217           0 :         if (t->data.other_data.type == EDID_DETAIL_MONITOR_NAME)
    3218           0 :                 *(u8 **)data = t->data.other_data.data.str.str;
    3219           0 : }
    3220             : 
    3221             : /**
    3222             :  * drm_edid_to_eld - build ELD from EDID
    3223             :  * @connector: connector corresponding to the HDMI/DP sink
    3224             :  * @edid: EDID to parse
    3225             :  *
    3226             :  * Fill the ELD (EDID-Like Data) buffer for passing to the audio driver. The
    3227             :  * HDCP and Port_ID ELD fields are left for the graphics driver to fill in.
    3228             :  */
    3229           0 : void drm_edid_to_eld(struct drm_connector *connector, struct edid *edid)
    3230             : {
    3231           0 :         uint8_t *eld = connector->eld;
    3232             :         u8 *cea;
    3233           0 :         u8 *name;
    3234             :         u8 *db;
    3235             :         int sad_count = 0;
    3236             :         int mnl;
    3237             :         int dbl;
    3238             : 
    3239           0 :         memset(eld, 0, sizeof(connector->eld));
    3240             : 
    3241           0 :         cea = drm_find_cea_extension(edid);
    3242           0 :         if (!cea) {
    3243             :                 DRM_DEBUG_KMS("ELD: no CEA Extension found\n");
    3244           0 :                 return;
    3245             :         }
    3246             : 
    3247           0 :         name = NULL;
    3248           0 :         drm_for_each_detailed_block((u8 *)edid, monitor_name, &name);
    3249           0 :         for (mnl = 0; name && mnl < 13; mnl++) {
    3250           0 :                 if (name[mnl] == 0x0a)
    3251             :                         break;
    3252           0 :                 eld[20 + mnl] = name[mnl];
    3253             :         }
    3254           0 :         eld[4] = (cea[1] << 5) | mnl;
    3255             :         DRM_DEBUG_KMS("ELD monitor %s\n", eld + 20);
    3256             : 
    3257           0 :         eld[0] = 2 << 3;          /* ELD version: 2 */
    3258             : 
    3259           0 :         eld[16] = edid->mfg_id[0];
    3260           0 :         eld[17] = edid->mfg_id[1];
    3261           0 :         eld[18] = edid->prod_code[0];
    3262           0 :         eld[19] = edid->prod_code[1];
    3263             : 
    3264           0 :         if (cea_revision(cea) >= 3) {
    3265           0 :                 int i, start, end;
    3266             : 
    3267           0 :                 if (cea_db_offsets(cea, &start, &end)) {
    3268           0 :                         start = 0;
    3269           0 :                         end = 0;
    3270           0 :                 }
    3271             : 
    3272           0 :                 for_each_cea_db(cea, i, start, end) {
    3273             :                         db = &cea[i];
    3274           0 :                         dbl = cea_db_payload_len(db);
    3275             : 
    3276           0 :                         switch (cea_db_tag(db)) {
    3277             :                         case AUDIO_BLOCK:
    3278             :                                 /* Audio Data Block, contains SADs */
    3279           0 :                                 sad_count = dbl / 3;
    3280           0 :                                 if (dbl >= 1)
    3281           0 :                                         memcpy(eld + 20 + mnl, &db[1], dbl);
    3282             :                                 break;
    3283             :                         case SPEAKER_BLOCK:
    3284             :                                 /* Speaker Allocation Data Block */
    3285           0 :                                 if (dbl >= 1)
    3286           0 :                                         eld[7] = db[1];
    3287             :                                 break;
    3288             :                         case VENDOR_BLOCK:
    3289             :                                 /* HDMI Vendor-Specific Data Block */
    3290           0 :                                 if (cea_db_is_hdmi_vsdb(db))
    3291           0 :                                         parse_hdmi_vsdb(connector, db);
    3292             :                                 break;
    3293             :                         default:
    3294             :                                 break;
    3295             :                         }
    3296             :                 }
    3297           0 :         }
    3298           0 :         eld[5] |= sad_count << 4;
    3299             : 
    3300           0 :         if (connector->connector_type == DRM_MODE_CONNECTOR_DisplayPort ||
    3301           0 :             connector->connector_type == DRM_MODE_CONNECTOR_eDP)
    3302           0 :                 eld[DRM_ELD_SAD_COUNT_CONN_TYPE] |= DRM_ELD_CONN_TYPE_DP;
    3303             :         else
    3304           0 :                 eld[DRM_ELD_SAD_COUNT_CONN_TYPE] |= DRM_ELD_CONN_TYPE_HDMI;
    3305             : 
    3306           0 :         eld[DRM_ELD_BASELINE_ELD_LEN] =
    3307           0 :                 DIV_ROUND_UP(drm_eld_calc_baseline_block_size(eld), 4);
    3308             : 
    3309             :         DRM_DEBUG_KMS("ELD size %d, SAD count %d\n",
    3310             :                       drm_eld_size(eld), sad_count);
    3311           0 : }
    3312             : EXPORT_SYMBOL(drm_edid_to_eld);
    3313             : 
    3314             : /**
    3315             :  * drm_edid_to_sad - extracts SADs from EDID
    3316             :  * @edid: EDID to parse
    3317             :  * @sads: pointer that will be set to the extracted SADs
    3318             :  *
    3319             :  * Looks for CEA EDID block and extracts SADs (Short Audio Descriptors) from it.
    3320             :  *
    3321             :  * Note: The returned pointer needs to be freed using kfree().
    3322             :  *
    3323             :  * Return: The number of found SADs or negative number on error.
    3324             :  */
    3325           0 : int drm_edid_to_sad(struct edid *edid, struct cea_sad **sads)
    3326             : {
    3327             :         int count = 0;
    3328           0 :         int i, start, end, dbl;
    3329             :         u8 *cea;
    3330             : 
    3331           0 :         cea = drm_find_cea_extension(edid);
    3332           0 :         if (!cea) {
    3333             :                 DRM_DEBUG_KMS("SAD: no CEA Extension found\n");
    3334           0 :                 return -ENOENT;
    3335             :         }
    3336             : 
    3337           0 :         if (cea_revision(cea) < 3) {
    3338             :                 DRM_DEBUG_KMS("SAD: wrong CEA revision\n");
    3339           0 :                 return -ENOTSUPP;
    3340             :         }
    3341             : 
    3342           0 :         if (cea_db_offsets(cea, &start, &end)) {
    3343             :                 DRM_DEBUG_KMS("SAD: invalid data block offsets\n");
    3344           0 :                 return -EPROTO;
    3345             :         }
    3346             : 
    3347           0 :         for_each_cea_db(cea, i, start, end) {
    3348             :                 u8 *db = &cea[i];
    3349             : 
    3350           0 :                 if (cea_db_tag(db) == AUDIO_BLOCK) {
    3351             :                         int j;
    3352           0 :                         dbl = cea_db_payload_len(db);
    3353             : 
    3354           0 :                         count = dbl / 3; /* SAD is 3B */
    3355           0 :                         *sads = kcalloc(count, sizeof(**sads), GFP_KERNEL);
    3356           0 :                         if (!*sads)
    3357           0 :                                 return -ENOMEM;
    3358           0 :                         for (j = 0; j < count; j++) {
    3359           0 :                                 u8 *sad = &db[1 + j * 3];
    3360             : 
    3361           0 :                                 (*sads)[j].format = (sad[0] & 0x78) >> 3;
    3362           0 :                                 (*sads)[j].channels = sad[0] & 0x7;
    3363           0 :                                 (*sads)[j].freq = sad[1] & 0x7F;
    3364           0 :                                 (*sads)[j].byte2 = sad[2];
    3365             :                         }
    3366           0 :                         break;
    3367             :                 }
    3368           0 :         }
    3369             : 
    3370           0 :         return count;
    3371           0 : }
    3372             : EXPORT_SYMBOL(drm_edid_to_sad);
    3373             : 
    3374             : /**
    3375             :  * drm_edid_to_speaker_allocation - extracts Speaker Allocation Data Blocks from EDID
    3376             :  * @edid: EDID to parse
    3377             :  * @sadb: pointer to the speaker block
    3378             :  *
    3379             :  * Looks for CEA EDID block and extracts the Speaker Allocation Data Block from it.
    3380             :  *
    3381             :  * Note: The returned pointer needs to be freed using kfree().
    3382             :  *
    3383             :  * Return: The number of found Speaker Allocation Blocks or negative number on
    3384             :  * error.
    3385             :  */
    3386           0 : int drm_edid_to_speaker_allocation(struct edid *edid, u8 **sadb)
    3387             : {
    3388             :         int count = 0;
    3389           0 :         int i, start, end, dbl;
    3390             :         const u8 *cea;
    3391             : 
    3392           0 :         cea = drm_find_cea_extension(edid);
    3393           0 :         if (!cea) {
    3394             :                 DRM_DEBUG_KMS("SAD: no CEA Extension found\n");
    3395           0 :                 return -ENOENT;
    3396             :         }
    3397             : 
    3398           0 :         if (cea_revision(cea) < 3) {
    3399             :                 DRM_DEBUG_KMS("SAD: wrong CEA revision\n");
    3400           0 :                 return -ENOTSUPP;
    3401             :         }
    3402             : 
    3403           0 :         if (cea_db_offsets(cea, &start, &end)) {
    3404             :                 DRM_DEBUG_KMS("SAD: invalid data block offsets\n");
    3405           0 :                 return -EPROTO;
    3406             :         }
    3407             : 
    3408           0 :         for_each_cea_db(cea, i, start, end) {
    3409             :                 const u8 *db = &cea[i];
    3410             : 
    3411           0 :                 if (cea_db_tag(db) == SPEAKER_BLOCK) {
    3412           0 :                         dbl = cea_db_payload_len(db);
    3413             : 
    3414             :                         /* Speaker Allocation Data Block */
    3415           0 :                         if (dbl == 3) {
    3416           0 :                                 *sadb = kmemdup(&db[1], dbl, GFP_KERNEL);
    3417           0 :                                 if (!*sadb)
    3418           0 :                                         return -ENOMEM;
    3419             :                                 count = dbl;
    3420           0 :                                 break;
    3421             :                         }
    3422             :                 }
    3423           0 :         }
    3424             : 
    3425           0 :         return count;
    3426           0 : }
    3427             : EXPORT_SYMBOL(drm_edid_to_speaker_allocation);
    3428             : 
    3429             : /**
    3430             :  * drm_av_sync_delay - compute the HDMI/DP sink audio-video sync delay
    3431             :  * @connector: connector associated with the HDMI/DP sink
    3432             :  * @mode: the display mode
    3433             :  *
    3434             :  * Return: The HDMI/DP sink's audio-video sync delay in milliseconds or 0 if
    3435             :  * the sink doesn't support audio or video.
    3436             :  */
    3437           0 : int drm_av_sync_delay(struct drm_connector *connector,
    3438             :                       const struct drm_display_mode *mode)
    3439             : {
    3440           0 :         int i = !!(mode->flags & DRM_MODE_FLAG_INTERLACE);
    3441             :         int a, v;
    3442             : 
    3443           0 :         if (!connector->latency_present[0])
    3444           0 :                 return 0;
    3445           0 :         if (!connector->latency_present[1])
    3446           0 :                 i = 0;
    3447             : 
    3448           0 :         a = connector->audio_latency[i];
    3449           0 :         v = connector->video_latency[i];
    3450             : 
    3451             :         /*
    3452             :          * HDMI/DP sink doesn't support audio or video?
    3453             :          */
    3454           0 :         if (a == 255 || v == 255)
    3455           0 :                 return 0;
    3456             : 
    3457             :         /*
    3458             :          * Convert raw EDID values to millisecond.
    3459             :          * Treat unknown latency as 0ms.
    3460             :          */
    3461           0 :         if (a)
    3462           0 :                 a = min(2 * (a - 1), 500);
    3463           0 :         if (v)
    3464           0 :                 v = min(2 * (v - 1), 500);
    3465             : 
    3466           0 :         return max(v - a, 0);
    3467           0 : }
    3468             : EXPORT_SYMBOL(drm_av_sync_delay);
    3469             : 
    3470             : /**
    3471             :  * drm_select_eld - select one ELD from multiple HDMI/DP sinks
    3472             :  * @encoder: the encoder just changed display mode
    3473             :  *
    3474             :  * It's possible for one encoder to be associated with multiple HDMI/DP sinks.
    3475             :  * The policy is now hard coded to simply use the first HDMI/DP sink's ELD.
    3476             :  *
    3477             :  * Return: The connector associated with the first HDMI/DP sink that has ELD
    3478             :  * attached to it.
    3479             :  */
    3480           0 : struct drm_connector *drm_select_eld(struct drm_encoder *encoder)
    3481             : {
    3482             :         struct drm_connector *connector;
    3483           0 :         struct drm_device *dev = encoder->dev;
    3484             : 
    3485           0 :         WARN_ON(!mutex_is_locked(&dev->mode_config.mutex));
    3486           0 :         WARN_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex));
    3487             : 
    3488           0 :         drm_for_each_connector(connector, dev)
    3489           0 :                 if (connector->encoder == encoder && connector->eld[0])
    3490           0 :                         return connector;
    3491             : 
    3492           0 :         return NULL;
    3493           0 : }
    3494             : EXPORT_SYMBOL(drm_select_eld);
    3495             : 
    3496             : /**
    3497             :  * drm_detect_hdmi_monitor - detect whether monitor is HDMI
    3498             :  * @edid: monitor EDID information
    3499             :  *
    3500             :  * Parse the CEA extension according to CEA-861-B.
    3501             :  *
    3502             :  * Return: True if the monitor is HDMI, false if not or unknown.
    3503             :  */
    3504           0 : bool drm_detect_hdmi_monitor(struct edid *edid)
    3505             : {
    3506             :         u8 *edid_ext;
    3507             :         int i;
    3508           0 :         int start_offset, end_offset;
    3509             : 
    3510           0 :         edid_ext = drm_find_cea_extension(edid);
    3511           0 :         if (!edid_ext)
    3512           0 :                 return false;
    3513             : 
    3514           0 :         if (cea_db_offsets(edid_ext, &start_offset, &end_offset))
    3515           0 :                 return false;
    3516             : 
    3517             :         /*
    3518             :          * Because HDMI identifier is in Vendor Specific Block,
    3519             :          * search it from all data blocks of CEA extension.
    3520             :          */
    3521           0 :         for_each_cea_db(edid_ext, i, start_offset, end_offset) {
    3522           0 :                 if (cea_db_is_hdmi_vsdb(&edid_ext[i]))
    3523           0 :                         return true;
    3524             :         }
    3525             : 
    3526           0 :         return false;
    3527           0 : }
    3528             : EXPORT_SYMBOL(drm_detect_hdmi_monitor);
    3529             : 
    3530             : /**
    3531             :  * drm_detect_monitor_audio - check monitor audio capability
    3532             :  * @edid: EDID block to scan
    3533             :  *
    3534             :  * Monitor should have CEA extension block.
    3535             :  * If monitor has 'basic audio', but no CEA audio blocks, it's 'basic
    3536             :  * audio' only. If there is any audio extension block and supported
    3537             :  * audio format, assume at least 'basic audio' support, even if 'basic
    3538             :  * audio' is not defined in EDID.
    3539             :  *
    3540             :  * Return: True if the monitor supports audio, false otherwise.
    3541             :  */
    3542           0 : bool drm_detect_monitor_audio(struct edid *edid)
    3543             : {
    3544             :         u8 *edid_ext;
    3545             :         int i, j;
    3546             :         bool has_audio = false;
    3547           0 :         int start_offset, end_offset;
    3548             : 
    3549           0 :         edid_ext = drm_find_cea_extension(edid);
    3550           0 :         if (!edid_ext)
    3551             :                 goto end;
    3552             : 
    3553           0 :         has_audio = ((edid_ext[3] & EDID_BASIC_AUDIO) != 0);
    3554             : 
    3555           0 :         if (has_audio) {
    3556             :                 DRM_DEBUG_KMS("Monitor has basic audio support\n");
    3557             :                 goto end;
    3558             :         }
    3559             : 
    3560           0 :         if (cea_db_offsets(edid_ext, &start_offset, &end_offset))
    3561             :                 goto end;
    3562             : 
    3563           0 :         for_each_cea_db(edid_ext, i, start_offset, end_offset) {
    3564           0 :                 if (cea_db_tag(&edid_ext[i]) == AUDIO_BLOCK) {
    3565             :                         has_audio = true;
    3566           0 :                         for (j = 1; j < cea_db_payload_len(&edid_ext[i]) + 1; j += 3)
    3567             :                                 DRM_DEBUG_KMS("CEA audio format %d\n",
    3568             :                                               (edid_ext[i + j] >> 3) & 0xf);
    3569             :                         goto end;
    3570             :                 }
    3571             :         }
    3572             : end:
    3573           0 :         return has_audio;
    3574           0 : }
    3575             : EXPORT_SYMBOL(drm_detect_monitor_audio);
    3576             : 
    3577             : /**
    3578             :  * drm_rgb_quant_range_selectable - is RGB quantization range selectable?
    3579             :  * @edid: EDID block to scan
    3580             :  *
    3581             :  * Check whether the monitor reports the RGB quantization range selection
    3582             :  * as supported. The AVI infoframe can then be used to inform the monitor
    3583             :  * which quantization range (full or limited) is used.
    3584             :  *
    3585             :  * Return: True if the RGB quantization range is selectable, false otherwise.
    3586             :  */
    3587           0 : bool drm_rgb_quant_range_selectable(struct edid *edid)
    3588             : {
    3589             :         u8 *edid_ext;
    3590           0 :         int i, start, end;
    3591             : 
    3592           0 :         edid_ext = drm_find_cea_extension(edid);
    3593           0 :         if (!edid_ext)
    3594           0 :                 return false;
    3595             : 
    3596           0 :         if (cea_db_offsets(edid_ext, &start, &end))
    3597           0 :                 return false;
    3598             : 
    3599           0 :         for_each_cea_db(edid_ext, i, start, end) {
    3600           0 :                 if (cea_db_tag(&edid_ext[i]) == VIDEO_CAPABILITY_BLOCK &&
    3601           0 :                     cea_db_payload_len(&edid_ext[i]) == 2) {
    3602             :                         DRM_DEBUG_KMS("CEA VCDB 0x%02x\n", edid_ext[i + 2]);
    3603           0 :                         return edid_ext[i + 2] & EDID_CEA_VCDB_QS;
    3604             :                 }
    3605             :         }
    3606             : 
    3607           0 :         return false;
    3608           0 : }
    3609             : EXPORT_SYMBOL(drm_rgb_quant_range_selectable);
    3610             : 
    3611             : /**
    3612             :  * drm_assign_hdmi_deep_color_info - detect whether monitor supports
    3613             :  * hdmi deep color modes and update drm_display_info if so.
    3614             :  * @edid: monitor EDID information
    3615             :  * @info: Updated with maximum supported deep color bpc and color format
    3616             :  *        if deep color supported.
    3617             :  * @connector: DRM connector, used only for debug output
    3618             :  *
    3619             :  * Parse the CEA extension according to CEA-861-B.
    3620             :  * Return true if HDMI deep color supported, false if not or unknown.
    3621             :  */
    3622           0 : static bool drm_assign_hdmi_deep_color_info(struct edid *edid,
    3623             :                                             struct drm_display_info *info,
    3624             :                                             struct drm_connector *connector)
    3625             : {
    3626             :         u8 *edid_ext, *hdmi;
    3627             :         int i;
    3628           0 :         int start_offset, end_offset;
    3629             :         unsigned int dc_bpc = 0;
    3630             : 
    3631           0 :         edid_ext = drm_find_cea_extension(edid);
    3632           0 :         if (!edid_ext)
    3633           0 :                 return false;
    3634             : 
    3635           0 :         if (cea_db_offsets(edid_ext, &start_offset, &end_offset))
    3636           0 :                 return false;
    3637             : 
    3638             :         /*
    3639             :          * Because HDMI identifier is in Vendor Specific Block,
    3640             :          * search it from all data blocks of CEA extension.
    3641             :          */
    3642           0 :         for_each_cea_db(edid_ext, i, start_offset, end_offset) {
    3643           0 :                 if (cea_db_is_hdmi_vsdb(&edid_ext[i])) {
    3644             :                         /* HDMI supports at least 8 bpc */
    3645           0 :                         info->bpc = 8;
    3646             : 
    3647             :                         hdmi = &edid_ext[i];
    3648           0 :                         if (cea_db_payload_len(hdmi) < 6)
    3649           0 :                                 return false;
    3650             : 
    3651           0 :                         if (hdmi[6] & DRM_EDID_HDMI_DC_30) {
    3652             :                                 dc_bpc = 10;
    3653           0 :                                 info->edid_hdmi_dc_modes |= DRM_EDID_HDMI_DC_30;
    3654             :                                 DRM_DEBUG("%s: HDMI sink does deep color 30.\n",
    3655             :                                                   connector->name);
    3656           0 :                         }
    3657             : 
    3658           0 :                         if (hdmi[6] & DRM_EDID_HDMI_DC_36) {
    3659             :                                 dc_bpc = 12;
    3660           0 :                                 info->edid_hdmi_dc_modes |= DRM_EDID_HDMI_DC_36;
    3661             :                                 DRM_DEBUG("%s: HDMI sink does deep color 36.\n",
    3662             :                                                   connector->name);
    3663           0 :                         }
    3664             : 
    3665           0 :                         if (hdmi[6] & DRM_EDID_HDMI_DC_48) {
    3666             :                                 dc_bpc = 16;
    3667           0 :                                 info->edid_hdmi_dc_modes |= DRM_EDID_HDMI_DC_48;
    3668             :                                 DRM_DEBUG("%s: HDMI sink does deep color 48.\n",
    3669             :                                                   connector->name);
    3670           0 :                         }
    3671             : 
    3672           0 :                         if (dc_bpc > 0) {
    3673             :                                 DRM_DEBUG("%s: Assigning HDMI sink color depth as %d bpc.\n",
    3674             :                                                   connector->name, dc_bpc);
    3675           0 :                                 info->bpc = dc_bpc;
    3676             : 
    3677             :                                 /*
    3678             :                                  * Deep color support mandates RGB444 support for all video
    3679             :                                  * modes and forbids YCRCB422 support for all video modes per
    3680             :                                  * HDMI 1.3 spec.
    3681             :                                  */
    3682           0 :                                 info->color_formats = DRM_COLOR_FORMAT_RGB444;
    3683             : 
    3684             :                                 /* YCRCB444 is optional according to spec. */
    3685           0 :                                 if (hdmi[6] & DRM_EDID_HDMI_DC_Y444) {
    3686           0 :                                         info->color_formats |= DRM_COLOR_FORMAT_YCRCB444;
    3687             :                                         DRM_DEBUG("%s: HDMI sink does YCRCB444 in deep color.\n",
    3688             :                                                           connector->name);
    3689           0 :                                 }
    3690             : 
    3691             :                                 /*
    3692             :                                  * Spec says that if any deep color mode is supported at all,
    3693             :                                  * then deep color 36 bit must be supported.
    3694             :                                  */
    3695           0 :                                 if (!(hdmi[6] & DRM_EDID_HDMI_DC_36)) {
    3696             :                                         DRM_DEBUG("%s: HDMI sink should do DC_36, but does not!\n",
    3697             :                                                           connector->name);
    3698             :                                 }
    3699             : 
    3700           0 :                                 return true;
    3701             :                         }
    3702             :                         else {
    3703             :                                 DRM_DEBUG("%s: No deep color support on this HDMI sink.\n",
    3704             :                                                   connector->name);
    3705             :                         }
    3706             :                 }
    3707             :         }
    3708             : 
    3709           0 :         return false;
    3710           0 : }
    3711             : 
    3712             : /**
    3713             :  * drm_add_display_info - pull display info out if present
    3714             :  * @edid: EDID data
    3715             :  * @info: display info (attached to connector)
    3716             :  * @connector: connector whose edid is used to build display info
    3717             :  *
    3718             :  * Grab any available display info and stuff it into the drm_display_info
    3719             :  * structure that's part of the connector.  Useful for tracking bpp and
    3720             :  * color spaces.
    3721             :  */
    3722           0 : static void drm_add_display_info(struct edid *edid,
    3723             :                                  struct drm_display_info *info,
    3724             :                                  struct drm_connector *connector)
    3725             : {
    3726             :         u8 *edid_ext;
    3727             : 
    3728           0 :         info->width_mm = edid->width_cm * 10;
    3729           0 :         info->height_mm = edid->height_cm * 10;
    3730             : 
    3731             :         /* driver figures it out in this case */
    3732           0 :         info->bpc = 0;
    3733           0 :         info->color_formats = 0;
    3734             : 
    3735           0 :         if (edid->revision < 3)
    3736           0 :                 return;
    3737             : 
    3738           0 :         if (!(edid->input & DRM_EDID_INPUT_DIGITAL))
    3739           0 :                 return;
    3740             : 
    3741             :         /* Get data from CEA blocks if present */
    3742           0 :         edid_ext = drm_find_cea_extension(edid);
    3743           0 :         if (edid_ext) {
    3744           0 :                 info->cea_rev = edid_ext[1];
    3745             : 
    3746             :                 /* The existence of a CEA block should imply RGB support */
    3747           0 :                 info->color_formats = DRM_COLOR_FORMAT_RGB444;
    3748           0 :                 if (edid_ext[3] & EDID_CEA_YCRCB444)
    3749           0 :                         info->color_formats |= DRM_COLOR_FORMAT_YCRCB444;
    3750           0 :                 if (edid_ext[3] & EDID_CEA_YCRCB422)
    3751           0 :                         info->color_formats |= DRM_COLOR_FORMAT_YCRCB422;
    3752             :         }
    3753             : 
    3754             :         /* HDMI deep color modes supported? Assign to info, if so */
    3755           0 :         drm_assign_hdmi_deep_color_info(edid, info, connector);
    3756             : 
    3757             :         /* Only defined for 1.4 with digital displays */
    3758           0 :         if (edid->revision < 4)
    3759           0 :                 return;
    3760             : 
    3761           0 :         switch (edid->input & DRM_EDID_DIGITAL_DEPTH_MASK) {
    3762             :         case DRM_EDID_DIGITAL_DEPTH_6:
    3763           0 :                 info->bpc = 6;
    3764           0 :                 break;
    3765             :         case DRM_EDID_DIGITAL_DEPTH_8:
    3766           0 :                 info->bpc = 8;
    3767           0 :                 break;
    3768             :         case DRM_EDID_DIGITAL_DEPTH_10:
    3769           0 :                 info->bpc = 10;
    3770           0 :                 break;
    3771             :         case DRM_EDID_DIGITAL_DEPTH_12:
    3772           0 :                 info->bpc = 12;
    3773           0 :                 break;
    3774             :         case DRM_EDID_DIGITAL_DEPTH_14:
    3775           0 :                 info->bpc = 14;
    3776           0 :                 break;
    3777             :         case DRM_EDID_DIGITAL_DEPTH_16:
    3778           0 :                 info->bpc = 16;
    3779           0 :                 break;
    3780             :         case DRM_EDID_DIGITAL_DEPTH_UNDEF:
    3781             :         default:
    3782           0 :                 info->bpc = 0;
    3783           0 :                 break;
    3784             :         }
    3785             : 
    3786             :         DRM_DEBUG("%s: Assigning EDID-1.4 digital sink color depth as %d bpc.\n",
    3787             :                           connector->name, info->bpc);
    3788             : 
    3789           0 :         info->color_formats |= DRM_COLOR_FORMAT_RGB444;
    3790           0 :         if (edid->features & DRM_EDID_FEATURE_RGB_YCRCB444)
    3791           0 :                 info->color_formats |= DRM_COLOR_FORMAT_YCRCB444;
    3792           0 :         if (edid->features & DRM_EDID_FEATURE_RGB_YCRCB422)
    3793           0 :                 info->color_formats |= DRM_COLOR_FORMAT_YCRCB422;
    3794           0 : }
    3795             : 
    3796             : /**
    3797             :  * drm_add_edid_modes - add modes from EDID data, if available
    3798             :  * @connector: connector we're probing
    3799             :  * @edid: EDID data
    3800             :  *
    3801             :  * Add the specified modes to the connector's mode list.
    3802             :  *
    3803             :  * Return: The number of modes added or 0 if we couldn't find any.
    3804             :  */
    3805           0 : int drm_add_edid_modes(struct drm_connector *connector, struct edid *edid)
    3806             : {
    3807             :         int num_modes = 0;
    3808             :         u32 quirks;
    3809             : 
    3810           0 :         if (edid == NULL) {
    3811           0 :                 return 0;
    3812             :         }
    3813           0 :         if (!drm_edid_is_valid(edid)) {
    3814           0 :                 dev_warn(connector->dev->dev, "%s: EDID invalid.\n",
    3815             :                          connector->name);
    3816           0 :                 return 0;
    3817             :         }
    3818             : 
    3819           0 :         quirks = edid_get_quirks(edid);
    3820             : 
    3821             :         /*
    3822             :          * EDID spec says modes should be preferred in this order:
    3823             :          * - preferred detailed mode
    3824             :          * - other detailed modes from base block
    3825             :          * - detailed modes from extension blocks
    3826             :          * - CVT 3-byte code modes
    3827             :          * - standard timing codes
    3828             :          * - established timing codes
    3829             :          * - modes inferred from GTF or CVT range information
    3830             :          *
    3831             :          * We get this pretty much right.
    3832             :          *
    3833             :          * XXX order for additional mode types in extension blocks?
    3834             :          */
    3835           0 :         num_modes += add_detailed_modes(connector, edid, quirks);
    3836           0 :         num_modes += add_cvt_modes(connector, edid);
    3837           0 :         num_modes += add_standard_modes(connector, edid);
    3838           0 :         num_modes += add_established_modes(connector, edid);
    3839           0 :         num_modes += add_cea_modes(connector, edid);
    3840           0 :         num_modes += add_alternate_cea_modes(connector, edid);
    3841           0 :         if (edid->features & DRM_EDID_FEATURE_DEFAULT_GTF)
    3842           0 :                 num_modes += add_inferred_modes(connector, edid);
    3843             : 
    3844           0 :         if (quirks & (EDID_QUIRK_PREFER_LARGE_60 | EDID_QUIRK_PREFER_LARGE_75))
    3845           0 :                 edid_fixup_preferred(connector, quirks);
    3846             : 
    3847           0 :         drm_add_display_info(edid, &connector->display_info, connector);
    3848             : 
    3849           0 :         if (quirks & EDID_QUIRK_FORCE_6BPC)
    3850           0 :                 connector->display_info.bpc = 6;
    3851             : 
    3852           0 :         if (quirks & EDID_QUIRK_FORCE_8BPC)
    3853           0 :                 connector->display_info.bpc = 8;
    3854             : 
    3855           0 :         if (quirks & EDID_QUIRK_FORCE_10BPC)
    3856           0 :                 connector->display_info.bpc = 10;
    3857             : 
    3858           0 :         if (quirks & EDID_QUIRK_FORCE_12BPC)
    3859           0 :                 connector->display_info.bpc = 12;
    3860             : 
    3861           0 :         return num_modes;
    3862           0 : }
    3863             : EXPORT_SYMBOL(drm_add_edid_modes);
    3864             : 
    3865             : /**
    3866             :  * drm_add_modes_noedid - add modes for the connectors without EDID
    3867             :  * @connector: connector we're probing
    3868             :  * @hdisplay: the horizontal display limit
    3869             :  * @vdisplay: the vertical display limit
    3870             :  *
    3871             :  * Add the specified modes to the connector's mode list. Only when the
    3872             :  * hdisplay/vdisplay is not beyond the given limit, it will be added.
    3873             :  *
    3874             :  * Return: The number of modes added or 0 if we couldn't find any.
    3875             :  */
    3876           0 : int drm_add_modes_noedid(struct drm_connector *connector,
    3877             :                         int hdisplay, int vdisplay)
    3878             : {
    3879             :         int i, count, num_modes = 0;
    3880             :         struct drm_display_mode *mode;
    3881           0 :         struct drm_device *dev = connector->dev;
    3882             : 
    3883             :         count = ARRAY_SIZE(drm_dmt_modes);
    3884           0 :         if (hdisplay < 0)
    3885           0 :                 hdisplay = 0;
    3886           0 :         if (vdisplay < 0)
    3887           0 :                 vdisplay = 0;
    3888             : 
    3889           0 :         for (i = 0; i < count; i++) {
    3890           0 :                 const struct drm_display_mode *ptr = &drm_dmt_modes[i];
    3891           0 :                 if (hdisplay && vdisplay) {
    3892             :                         /*
    3893             :                          * Only when two are valid, they will be used to check
    3894             :                          * whether the mode should be added to the mode list of
    3895             :                          * the connector.
    3896             :                          */
    3897           0 :                         if (ptr->hdisplay > hdisplay ||
    3898           0 :                                         ptr->vdisplay > vdisplay)
    3899           0 :                                 continue;
    3900             :                 }
    3901           0 :                 if (drm_mode_vrefresh(ptr) > 61)
    3902           0 :                         continue;
    3903           0 :                 mode = drm_mode_duplicate(dev, ptr);
    3904           0 :                 if (mode) {
    3905           0 :                         drm_mode_probed_add(connector, mode);
    3906           0 :                         num_modes++;
    3907           0 :                 }
    3908           0 :         }
    3909           0 :         return num_modes;
    3910             : }
    3911             : EXPORT_SYMBOL(drm_add_modes_noedid);
    3912             : 
    3913             : /**
    3914             :  * drm_set_preferred_mode - Sets the preferred mode of a connector
    3915             :  * @connector: connector whose mode list should be processed
    3916             :  * @hpref: horizontal resolution of preferred mode
    3917             :  * @vpref: vertical resolution of preferred mode
    3918             :  *
    3919             :  * Marks a mode as preferred if it matches the resolution specified by @hpref
    3920             :  * and @vpref.
    3921             :  */
    3922           0 : void drm_set_preferred_mode(struct drm_connector *connector,
    3923             :                            int hpref, int vpref)
    3924             : {
    3925             :         struct drm_display_mode *mode;
    3926             : 
    3927           0 :         list_for_each_entry(mode, &connector->probed_modes, head) {
    3928           0 :                 if (mode->hdisplay == hpref &&
    3929           0 :                     mode->vdisplay == vpref)
    3930           0 :                         mode->type |= DRM_MODE_TYPE_PREFERRED;
    3931             :         }
    3932           0 : }
    3933             : EXPORT_SYMBOL(drm_set_preferred_mode);
    3934             : 
    3935             : /**
    3936             :  * drm_hdmi_avi_infoframe_from_display_mode() - fill an HDMI AVI infoframe with
    3937             :  *                                              data from a DRM display mode
    3938             :  * @frame: HDMI AVI infoframe
    3939             :  * @mode: DRM display mode
    3940             :  *
    3941             :  * Return: 0 on success or a negative error code on failure.
    3942             :  */
    3943             : int
    3944           0 : drm_hdmi_avi_infoframe_from_display_mode(struct hdmi_avi_infoframe *frame,
    3945             :                                          const struct drm_display_mode *mode)
    3946             : {
    3947             :         int err;
    3948             : 
    3949           0 :         if (!frame || !mode)
    3950           0 :                 return -EINVAL;
    3951             : 
    3952           0 :         err = hdmi_avi_infoframe_init(frame);
    3953           0 :         if (err < 0)
    3954           0 :                 return err;
    3955             : 
    3956           0 :         if (mode->flags & DRM_MODE_FLAG_DBLCLK)
    3957           0 :                 frame->pixel_repeat = 1;
    3958             : 
    3959           0 :         frame->video_code = drm_match_cea_mode(mode);
    3960             : 
    3961           0 :         frame->picture_aspect = HDMI_PICTURE_ASPECT_NONE;
    3962             : 
    3963             :         /*
    3964             :          * Populate picture aspect ratio from either
    3965             :          * user input (if specified) or from the CEA mode list.
    3966             :          */
    3967           0 :         if (mode->picture_aspect_ratio == HDMI_PICTURE_ASPECT_4_3 ||
    3968           0 :                 mode->picture_aspect_ratio == HDMI_PICTURE_ASPECT_16_9)
    3969           0 :                 frame->picture_aspect = mode->picture_aspect_ratio;
    3970           0 :         else if (frame->video_code > 0)
    3971           0 :                 frame->picture_aspect = drm_get_cea_aspect_ratio(
    3972             :                                                 frame->video_code);
    3973             : 
    3974           0 :         frame->active_aspect = HDMI_ACTIVE_ASPECT_PICTURE;
    3975           0 :         frame->scan_mode = HDMI_SCAN_MODE_UNDERSCAN;
    3976             : 
    3977           0 :         return 0;
    3978           0 : }
    3979             : EXPORT_SYMBOL(drm_hdmi_avi_infoframe_from_display_mode);
    3980             : 
    3981             : static enum hdmi_3d_structure
    3982           0 : s3d_structure_from_display_mode(const struct drm_display_mode *mode)
    3983             : {
    3984           0 :         u32 layout = mode->flags & DRM_MODE_FLAG_3D_MASK;
    3985             : 
    3986           0 :         switch (layout) {
    3987             :         case DRM_MODE_FLAG_3D_FRAME_PACKING:
    3988           0 :                 return HDMI_3D_STRUCTURE_FRAME_PACKING;
    3989             :         case DRM_MODE_FLAG_3D_FIELD_ALTERNATIVE:
    3990           0 :                 return HDMI_3D_STRUCTURE_FIELD_ALTERNATIVE;
    3991             :         case DRM_MODE_FLAG_3D_LINE_ALTERNATIVE:
    3992           0 :                 return HDMI_3D_STRUCTURE_LINE_ALTERNATIVE;
    3993             :         case DRM_MODE_FLAG_3D_SIDE_BY_SIDE_FULL:
    3994           0 :                 return HDMI_3D_STRUCTURE_SIDE_BY_SIDE_FULL;
    3995             :         case DRM_MODE_FLAG_3D_L_DEPTH:
    3996           0 :                 return HDMI_3D_STRUCTURE_L_DEPTH;
    3997             :         case DRM_MODE_FLAG_3D_L_DEPTH_GFX_GFX_DEPTH:
    3998           0 :                 return HDMI_3D_STRUCTURE_L_DEPTH_GFX_GFX_DEPTH;
    3999             :         case DRM_MODE_FLAG_3D_TOP_AND_BOTTOM:
    4000           0 :                 return HDMI_3D_STRUCTURE_TOP_AND_BOTTOM;
    4001             :         case DRM_MODE_FLAG_3D_SIDE_BY_SIDE_HALF:
    4002           0 :                 return HDMI_3D_STRUCTURE_SIDE_BY_SIDE_HALF;
    4003             :         default:
    4004           0 :                 return HDMI_3D_STRUCTURE_INVALID;
    4005             :         }
    4006           0 : }
    4007             : 
    4008             : /**
    4009             :  * drm_hdmi_vendor_infoframe_from_display_mode() - fill an HDMI infoframe with
    4010             :  * data from a DRM display mode
    4011             :  * @frame: HDMI vendor infoframe
    4012             :  * @mode: DRM display mode
    4013             :  *
    4014             :  * Note that there's is a need to send HDMI vendor infoframes only when using a
    4015             :  * 4k or stereoscopic 3D mode. So when giving any other mode as input this
    4016             :  * function will return -EINVAL, error that can be safely ignored.
    4017             :  *
    4018             :  * Return: 0 on success or a negative error code on failure.
    4019             :  */
    4020             : int
    4021           0 : drm_hdmi_vendor_infoframe_from_display_mode(struct hdmi_vendor_infoframe *frame,
    4022             :                                             const struct drm_display_mode *mode)
    4023             : {
    4024             :         int err;
    4025             :         u32 s3d_flags;
    4026             :         u8 vic;
    4027             : 
    4028           0 :         if (!frame || !mode)
    4029           0 :                 return -EINVAL;
    4030             : 
    4031           0 :         vic = drm_match_hdmi_mode(mode);
    4032           0 :         s3d_flags = mode->flags & DRM_MODE_FLAG_3D_MASK;
    4033             : 
    4034           0 :         if (!vic && !s3d_flags)
    4035           0 :                 return -EINVAL;
    4036             : 
    4037           0 :         if (vic && s3d_flags)
    4038           0 :                 return -EINVAL;
    4039             : 
    4040           0 :         err = hdmi_vendor_infoframe_init(frame);
    4041           0 :         if (err < 0)
    4042           0 :                 return err;
    4043             : 
    4044           0 :         if (vic)
    4045           0 :                 frame->vic = vic;
    4046             :         else
    4047           0 :                 frame->s3d_struct = s3d_structure_from_display_mode(mode);
    4048             : 
    4049           0 :         return 0;
    4050           0 : }
    4051             : EXPORT_SYMBOL(drm_hdmi_vendor_infoframe_from_display_mode);
    4052             : 
    4053           0 : static int drm_parse_display_id(struct drm_connector *connector,
    4054             :                                 u8 *displayid, int length,
    4055             :                                 bool is_edid_extension)
    4056             : {
    4057             :         /* if this is an EDID extension the first byte will be 0x70 */
    4058             :         int idx = 0;
    4059             :         struct displayid_hdr *base;
    4060             :         struct displayid_block *block;
    4061             :         u8 csum = 0;
    4062             :         int i;
    4063             : 
    4064           0 :         if (is_edid_extension)
    4065           0 :                 idx = 1;
    4066             : 
    4067           0 :         base = (struct displayid_hdr *)&displayid[idx];
    4068             : 
    4069             :         DRM_DEBUG_KMS("base revision 0x%x, length %d, %d %d\n",
    4070             :                       base->rev, base->bytes, base->prod_id, base->ext_count);
    4071             : 
    4072           0 :         if (base->bytes + 5 > length - idx)
    4073           0 :                 return -EINVAL;
    4074             : 
    4075           0 :         for (i = idx; i <= base->bytes + 5; i++) {
    4076           0 :                 csum += displayid[i];
    4077             :         }
    4078           0 :         if (csum) {
    4079           0 :                 DRM_ERROR("DisplayID checksum invalid, remainder is %d\n", csum);
    4080           0 :                 return -EINVAL;
    4081             :         }
    4082             : 
    4083           0 :         block = (struct displayid_block *)&displayid[idx + 4];
    4084             :         DRM_DEBUG_KMS("block id %d, rev %d, len %d\n",
    4085             :                       block->tag, block->rev, block->num_bytes);
    4086             : 
    4087           0 :         switch (block->tag) {
    4088             :         case DATA_BLOCK_TILED_DISPLAY: {
    4089           0 :                 struct displayid_tiled_block *tile = (struct displayid_tiled_block *)block;
    4090             : 
    4091             :                 u16 w, h;
    4092             :                 u8 tile_v_loc, tile_h_loc;
    4093             :                 u8 num_v_tile, num_h_tile;
    4094             :                 struct drm_tile_group *tg;
    4095             : 
    4096           0 :                 w = tile->tile_size[0] | tile->tile_size[1] << 8;
    4097           0 :                 h = tile->tile_size[2] | tile->tile_size[3] << 8;
    4098             : 
    4099           0 :                 num_v_tile = (tile->topo[0] & 0xf) | (tile->topo[2] & 0x30);
    4100           0 :                 num_h_tile = (tile->topo[0] >> 4) | ((tile->topo[2] >> 2) & 0x30);
    4101           0 :                 tile_v_loc = (tile->topo[1] & 0xf) | ((tile->topo[2] & 0x3) << 4);
    4102           0 :                 tile_h_loc = (tile->topo[1] >> 4) | (((tile->topo[2] >> 2) & 0x3) << 4);
    4103             : 
    4104           0 :                 connector->has_tile = true;
    4105           0 :                 if (tile->tile_cap & 0x80)
    4106           0 :                         connector->tile_is_single_monitor = true;
    4107             : 
    4108           0 :                 connector->num_h_tile = num_h_tile + 1;
    4109           0 :                 connector->num_v_tile = num_v_tile + 1;
    4110           0 :                 connector->tile_h_loc = tile_h_loc;
    4111           0 :                 connector->tile_v_loc = tile_v_loc;
    4112           0 :                 connector->tile_h_size = w + 1;
    4113           0 :                 connector->tile_v_size = h + 1;
    4114             : 
    4115             :                 DRM_DEBUG_KMS("tile cap 0x%x\n", tile->tile_cap);
    4116             :                 DRM_DEBUG_KMS("tile_size %d x %d\n", w + 1, h + 1);
    4117             :                 DRM_DEBUG_KMS("topo num tiles %dx%d, location %dx%d\n",
    4118             :                        num_h_tile + 1, num_v_tile + 1, tile_h_loc, tile_v_loc);
    4119             :                 DRM_DEBUG_KMS("vend %c%c%c\n", tile->topology_id[0], tile->topology_id[1], tile->topology_id[2]);
    4120             : 
    4121           0 :                 tg = drm_mode_get_tile_group(connector->dev, tile->topology_id);
    4122           0 :                 if (!tg) {
    4123           0 :                         tg = drm_mode_create_tile_group(connector->dev, tile->topology_id);
    4124           0 :                 }
    4125           0 :                 if (!tg)
    4126           0 :                         return -ENOMEM;
    4127             : 
    4128           0 :                 if (connector->tile_group != tg) {
    4129             :                         /* if we haven't got a pointer,
    4130             :                            take the reference, drop ref to old tile group */
    4131           0 :                         if (connector->tile_group) {
    4132           0 :                                 drm_mode_put_tile_group(connector->dev, connector->tile_group);
    4133           0 :                         }
    4134           0 :                         connector->tile_group = tg;
    4135           0 :                 } else
    4136             :                         /* if same tile group, then release the ref we just took. */
    4137           0 :                         drm_mode_put_tile_group(connector->dev, tg);
    4138           0 :         }
    4139             :                 break;
    4140             :         default:
    4141           0 :                 printk("unknown displayid tag %d\n", block->tag);
    4142           0 :                 break;
    4143             :         }
    4144           0 :         return 0;
    4145           0 : }
    4146             : 
    4147           0 : static void drm_get_displayid(struct drm_connector *connector,
    4148             :                               struct edid *edid)
    4149             : {
    4150             :         void *displayid = NULL;
    4151             :         int ret;
    4152           0 :         connector->has_tile = false;
    4153           0 :         displayid = drm_find_displayid_extension(edid);
    4154           0 :         if (!displayid) {
    4155             :                 /* drop reference to any tile group we had */
    4156             :                 goto out_drop_ref;
    4157             :         }
    4158             : 
    4159           0 :         ret = drm_parse_display_id(connector, displayid, EDID_LENGTH, true);
    4160           0 :         if (ret < 0)
    4161             :                 goto out_drop_ref;
    4162           0 :         if (!connector->has_tile)
    4163             :                 goto out_drop_ref;
    4164           0 :         return;
    4165             : out_drop_ref:
    4166           0 :         if (connector->tile_group) {
    4167           0 :                 drm_mode_put_tile_group(connector->dev, connector->tile_group);
    4168           0 :                 connector->tile_group = NULL;
    4169           0 :         }
    4170           0 :         return;
    4171           0 : }

Generated by: LCOV version 1.13