Blame SOURCES/0001-xfree86-add-drm-modes-on-non-GTF-panels.patch

315c3e
From 139868f3e82a3e7b7b17f3a5a2e07c4b04d81728 Mon Sep 17 00:00:00 2001
315c3e
From: Aaron Ma <aaron.ma@canonical.com>
315c3e
Date: Thu, 30 Jul 2020 11:02:39 +0200
315c3e
Subject: [PATCH xserver] xfree86: add drm modes on non-GTF panels
315c3e
MIME-Version: 1.0
315c3e
Content-Type: text/plain; charset=UTF-8
315c3e
Content-Transfer-Encoding: 8bit
315c3e
315c3e
EDID1.4 replaced GTF Bit with Continuous or Non-Continuous Frequency Display.
315c3e
315c3e
Check the "Display Range Limits Descriptor" for GTF support.
315c3e
If panel doesn't support GTF, then add gtf modes.
315c3e
315c3e
Otherwise X will only show the modes in "Detailed Timing Descriptor".
315c3e
315c3e
V2: Coding style changes.
315c3e
V3: Coding style changes, remove unused variate.
315c3e
V4: remove unused variate.
315c3e
315c3e
BugLink: https://gitlab.freedesktop.org/drm/intel/issues/313
315c3e
Signed-off-by: Aaron Ma <aaron.ma@canonical.com>
315c3e
Reviewed-by: Adam Jackson <ajax@redhat.com>
315c3e
(cherry picked from commit 6a79a737e2c0bc730ee693b4ea4a1530c108be4e)
315c3e
Signed-off-by: Michel Dänzer <mdaenzer@redhat.com>
315c3e
---
315c3e
 hw/xfree86/ddc/edid.h                         | 17 +++++++++++-
315c3e
 hw/xfree86/ddc/interpret_edid.c               | 27 +++++++++++++++++++
315c3e
 hw/xfree86/ddc/xf86DDC.h                      |  3 +++
315c3e
 .../drivers/modesetting/drmmode_display.c     |  2 +-
315c3e
 hw/xfree86/modes/xf86Crtc.c                   |  3 +--
315c3e
 5 files changed, 48 insertions(+), 4 deletions(-)
315c3e
315c3e
diff --git a/hw/xfree86/ddc/edid.h b/hw/xfree86/ddc/edid.h
315c3e
index 750e4270b..b884d8212 100644
315c3e
--- a/hw/xfree86/ddc/edid.h
315c3e
+++ b/hw/xfree86/ddc/edid.h
315c3e
@@ -262,6 +262,10 @@
315c3e
 #define MAX_H (_MAX_H(c) + _MAX_H_OFFSET(c))
315c3e
 #define _MAX_CLOCK(x) x[9]
315c3e
 #define MAX_CLOCK _MAX_CLOCK(c)
315c3e
+#define _DEFAULT_GTF(x) (x[10] == 0x00)
315c3e
+#define DEFAULT_GTF _DEFAULT_GTF(c)
315c3e
+#define _RANGE_LIMITS_ONLY(x) (x[10] == 0x01)
315c3e
+#define RANGE_LIMITS_ONLY _RANGE_LIMITS_ONLY(c)
315c3e
 #define _HAVE_2ND_GTF(x) (x[10] == 0x02)
315c3e
 #define HAVE_2ND_GTF _HAVE_2ND_GTF(c)
315c3e
 #define _F_2ND_GTF(x) (x[12] * 2)
315c3e
@@ -477,6 +481,16 @@ struct detailed_timings {
315c3e
 #define DS_VENDOR 0x101
315c3e
 #define DS_VENDOR_MAX 0x110
315c3e
 
315c3e
+/*
315c3e
+ * Display range limit Descriptor of EDID version1, reversion 4
315c3e
+ */
315c3e
+typedef enum {
315c3e
+	DR_DEFAULT_GTF,
315c3e
+	DR_LIMITS_ONLY,
315c3e
+	DR_SECONDARY_GTF,
315c3e
+	DR_CVT_SUPPORTED = 4,
315c3e
+} DR_timing_flags;
315c3e
+
315c3e
 struct monitor_ranges {
315c3e
     int min_v;
315c3e
     int max_v;
315c3e
@@ -495,6 +509,7 @@ struct monitor_ranges {
315c3e
     char supported_blanking;
315c3e
     char supported_scaling;
315c3e
     int preferred_refresh;      /* in hz */
315c3e
+    DR_timing_flags display_range_timing_flags;
315c3e
 };
315c3e
 
315c3e
 struct whitePoints {
315c3e
@@ -524,7 +539,7 @@ struct detailed_monitor_section {
315c3e
         Uchar serial[13];
315c3e
         Uchar ascii_data[13];
315c3e
         Uchar name[13];
315c3e
-        struct monitor_ranges ranges;   /* 56 */
315c3e
+        struct monitor_ranges ranges;   /* 60 */
315c3e
         struct std_timings std_t[5];    /* 80 */
315c3e
         struct whitePoints wp[2];       /* 32 */
315c3e
         /* color management data */
315c3e
diff --git a/hw/xfree86/ddc/interpret_edid.c b/hw/xfree86/ddc/interpret_edid.c
315c3e
index 17a8f81c0..19630471c 100644
315c3e
--- a/hw/xfree86/ddc/interpret_edid.c
315c3e
+++ b/hw/xfree86/ddc/interpret_edid.c
315c3e
@@ -672,6 +672,9 @@ get_monitor_ranges(Uchar * c, struct monitor_ranges *r)
315c3e
     r->max_clock = 0;
315c3e
     if (MAX_CLOCK != 0xff)      /* is specified? */
315c3e
         r->max_clock = MAX_CLOCK * 10 + 5;
315c3e
+
315c3e
+    r->display_range_timing_flags = c[10];
315c3e
+
315c3e
     if (HAVE_2ND_GTF) {
315c3e
         r->gtf_2nd_f = F_2ND_GTF;
315c3e
         r->gtf_2nd_c = C_2ND_GTF;
315c3e
@@ -751,6 +754,30 @@ validate_version(int scrnIndex, struct edid_version *r)
315c3e
     return TRUE;
315c3e
 }
315c3e
 
315c3e
+Bool
315c3e
+gtf_supported(xf86MonPtr mon)
315c3e
+{
315c3e
+    int i;
315c3e
+
315c3e
+    if (!mon)
315c3e
+        return FALSE;
315c3e
+
315c3e
+    if ((mon->ver.version == 1) && (mon->ver.revision < 4)) {
315c3e
+        if (mon->features.msc & 0x1)
315c3e
+	    return TRUE;
315c3e
+    } else {
315c3e
+        for (i = 0; i < DET_TIMINGS; i++) {
315c3e
+            struct detailed_monitor_section *det_timing_des = &(mon->det_mon[i]);
315c3e
+            if (det_timing_des && (det_timing_des->type == DS_RANGES) &&
315c3e
+                (det_timing_des->section.ranges.display_range_timing_flags == DR_DEFAULT_GTF
315c3e
+		|| det_timing_des->section.ranges.display_range_timing_flags == DR_SECONDARY_GTF))
315c3e
+		    return TRUE;
315c3e
+	}
315c3e
+    }
315c3e
+
315c3e
+    return FALSE;
315c3e
+}
315c3e
+
315c3e
 /*
315c3e
  * Returns true if HDMI, false if definitely not or unknown.
315c3e
  */
315c3e
diff --git a/hw/xfree86/ddc/xf86DDC.h b/hw/xfree86/ddc/xf86DDC.h
315c3e
index 7d81ab911..6eb2f0ba2 100644
315c3e
--- a/hw/xfree86/ddc/xf86DDC.h
315c3e
+++ b/hw/xfree86/ddc/xf86DDC.h
315c3e
@@ -48,6 +48,9 @@ extern _X_EXPORT Bool xf86SetDDCproperties(ScrnInfoPtr pScreen, xf86MonPtr DDC);
315c3e
 extern _X_EXPORT Bool
315c3e
  xf86MonitorIsHDMI(xf86MonPtr mon);
315c3e
 
315c3e
+extern _X_EXPORT Bool
315c3e
+gtf_supported(xf86MonPtr mon);
315c3e
+
315c3e
 extern _X_EXPORT DisplayModePtr
315c3e
 FindDMTMode(int hsize, int vsize, int refresh, Bool rb);
315c3e
 
315c3e
diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.c b/hw/xfree86/drivers/modesetting/drmmode_display.c
315c3e
index 59abb6cc7..9dd8c5573 100644
315c3e
--- a/hw/xfree86/drivers/modesetting/drmmode_display.c
315c3e
+++ b/hw/xfree86/drivers/modesetting/drmmode_display.c
315c3e
@@ -2439,7 +2439,7 @@ drmmode_output_add_gtf_modes(xf86OutputPtr output, DisplayModePtr Modes)
315c3e
     int max_x = 0, max_y = 0;
315c3e
     float max_vrefresh = 0.0;
315c3e
 
315c3e
-    if (mon && GTF_SUPPORTED(mon->features.msc))
315c3e
+    if (mon && gtf_supported(mon))
315c3e
         return Modes;
315c3e
 
315c3e
     if (!has_panel_fitter(output))
315c3e
diff --git a/hw/xfree86/modes/xf86Crtc.c b/hw/xfree86/modes/xf86Crtc.c
315c3e
index 37a45bb3a..17d4ef103 100644
315c3e
--- a/hw/xfree86/modes/xf86Crtc.c
315c3e
+++ b/hw/xfree86/modes/xf86Crtc.c
315c3e
@@ -1719,11 +1719,10 @@ xf86ProbeOutputModes(ScrnInfoPtr scrn, int maxX, int maxY)
315c3e
 
315c3e
         if (edid_monitor) {
315c3e
             struct det_monrec_parameter p;
315c3e
-            struct disp_features *features = &edid_monitor->features;
315c3e
             struct cea_data_block *hdmi_db;
315c3e
 
315c3e
             /* if display is not continuous-frequency, don't add default modes */
315c3e
-            if (!GTF_SUPPORTED(features->msc))
315c3e
+            if (!gtf_supported(edid_monitor))
315c3e
                 add_default_modes = FALSE;
315c3e
 
315c3e
             p.mon_rec = &mon_rec;
315c3e
-- 
315c3e
2.26.2
315c3e