[PATCH v1 1/1] common: edid: update timing selection logic

Svyatoslav Ryhel clamor95 at gmail.com
Wed Mar 5 12:07:09 CET 2025


From: Jonas Schwöbel <jonasschwoebel at yahoo.de>

Older EDID timing algorithms relied solely on detailed timings, typically
optimized for a display's native resolution. This caused issues with newer
4K panels on older hardware, which couldn't handle those high resolutions.
To address this, the algorithm now also considers standard timings, offering
lower, compatible resolutions. Future improvements may include checking
established timings for even broader compatibility.

Signed-off-by: Jonas Schwöbel <jonasschwoebel at yahoo.de>
Signed-off-by: Svyatoslav Ryhel <clamor95 at gmail.com>
---
 common/edid.c | 233 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 233 insertions(+)

diff --git a/common/edid.c b/common/edid.c
index 48a737690db..dd52d8b8239 100644
--- a/common/edid.c
+++ b/common/edid.c
@@ -16,6 +16,191 @@
 #include <linux/ctype.h>
 #include <linux/string.h>
 
+#define TIMING(c, ha, hfp, hbp, hsl, va, vfp, vbp, vsl, f) \
+	.pixelclock.typ = (c), .hactive.typ = (ha), .hfront_porch.typ = (hfp), \
+	.hback_porch.typ = (hbp), .hsync_len.typ = (hsl), .vactive.typ = (va), \
+	.vfront_porch.typ = (vfp), .vback_porch.typ = (vbp), .hsync_len.typ = (vsl), \
+	.flags = (f)
+
+static const struct display_timing dmt_timings[] = {
+	{ TIMING(31500000, 640, 32, 64, 96, 350, 32, 3, 60,
+		 DISPLAY_FLAGS_HSYNC_HIGH | DISPLAY_FLAGS_VSYNC_LOW) },
+	{ TIMING(31500000, 640, 32, 64, 96, 400, 1, 3, 41,
+		 DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_HIGH) },
+	{ TIMING(35500000, 720, 36, 72, 108, 400, 1, 3, 42,
+		 DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_HIGH) },
+	{ TIMING(25175000, 640, 16, 96, 48, 480, 10, 2, 33,
+		 DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_LOW) },
+	{ TIMING(31500000, 640, 24, 40, 128, 480, 9, 3, 28,
+		 DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_LOW) },
+	{ TIMING(31500000, 640, 16, 64, 120, 480, 1, 3, 16,
+		 DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_LOW) },
+	{ TIMING(36000000, 640, 56, 56, 80, 480, 1, 3, 25,
+		 DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_LOW) },
+	{ TIMING(36000000, 800, 24, 72, 128, 600, 1, 2, 22,
+		 DISPLAY_FLAGS_HSYNC_HIGH | DISPLAY_FLAGS_VSYNC_HIGH) },
+	{ TIMING(40000000, 800, 40, 128, 88, 600, 1, 4, 23,
+		 DISPLAY_FLAGS_HSYNC_HIGH | DISPLAY_FLAGS_VSYNC_HIGH) },
+	{ TIMING(50000000, 800, 56, 120, 64, 600, 37, 6, 23,
+		 DISPLAY_FLAGS_HSYNC_HIGH | DISPLAY_FLAGS_VSYNC_HIGH) },
+	{ TIMING(49500000, 800, 16, 80, 160, 600, 1, 3, 21,
+		 DISPLAY_FLAGS_HSYNC_HIGH | DISPLAY_FLAGS_VSYNC_HIGH) },
+	{ TIMING(56250000, 800, 32, 64, 152, 600, 1, 3, 27,
+		 DISPLAY_FLAGS_HSYNC_HIGH | DISPLAY_FLAGS_VSYNC_HIGH) },
+	{ TIMING(73250000, 800, 48, 32, 80, 600, 3, 4, 29,
+		 DISPLAY_FLAGS_HSYNC_HIGH | DISPLAY_FLAGS_VSYNC_LOW) },
+	{ TIMING(33750000, 848, 16, 112, 112, 480, 6, 8, 23,
+		 DISPLAY_FLAGS_HSYNC_HIGH | DISPLAY_FLAGS_VSYNC_HIGH) },
+	{ TIMING(44900000, 1024, 8, 176, 56, 768, 0, 8, 41,
+		 DISPLAY_FLAGS_HSYNC_HIGH | DISPLAY_FLAGS_VSYNC_HIGH) },
+	{ TIMING(65000000, 1024, 24, 136, 160, 768, 3, 6, 29,
+		 DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_LOW) },
+	{ TIMING(75000000, 1024, 24, 136, 144, 768, 3, 6, 29,
+		 DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_LOW) },
+	{ TIMING(78750000, 1024, 16, 96, 176, 768, 1, 3, 28,
+		 DISPLAY_FLAGS_HSYNC_HIGH | DISPLAY_FLAGS_VSYNC_HIGH) },
+	{ TIMING(94500000, 1024, 48, 96, 208, 768, 1, 3, 36,
+		 DISPLAY_FLAGS_HSYNC_HIGH | DISPLAY_FLAGS_VSYNC_HIGH) },
+	{ TIMING(115500000, 1024, 48, 32, 80, 768, 3, 4, 38,
+		 DISPLAY_FLAGS_HSYNC_HIGH | DISPLAY_FLAGS_VSYNC_LOW) },
+	{ TIMING(108000000, 1152, 64, 128, 256, 864, 1, 3, 32,
+		 DISPLAY_FLAGS_HSYNC_HIGH | DISPLAY_FLAGS_VSYNC_HIGH) },
+	{ TIMING(74250000, 1280, 110, 40, 220, 720, 5, 5, 20,
+		 DISPLAY_FLAGS_HSYNC_HIGH | DISPLAY_FLAGS_VSYNC_HIGH) },
+	{ TIMING(68250000, 1280, 48, 32, 80, 768, 3, 7, 12,
+		 DISPLAY_FLAGS_HSYNC_HIGH | DISPLAY_FLAGS_VSYNC_LOW) },
+	{ TIMING(79500000, 1280, 64, 128, 192, 768, 3, 7, 20,
+		 DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_HIGH) },
+	{ TIMING(102250000, 1280, 80, 128, 208, 768, 3, 7, 27,
+		 DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_HIGH) },
+	{ TIMING(117500000, 1280, 80, 136, 216, 768, 3, 7, 31,
+		 DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_HIGH) },
+	{ TIMING(140250000, 1280, 48, 32, 80, 768, 3, 7, 35,
+		 DISPLAY_FLAGS_HSYNC_HIGH | DISPLAY_FLAGS_VSYNC_LOW) },
+	{ TIMING(71000000, 1280, 48, 32, 80, 800, 3, 6, 14,
+		 DISPLAY_FLAGS_HSYNC_HIGH | DISPLAY_FLAGS_VSYNC_LOW) },
+	{ TIMING(83500000, 1280, 72, 128, 200, 800, 3, 6, 22,
+		 DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_HIGH) },
+	{ TIMING(106500000, 1280, 80, 128, 208, 800, 3, 6, 29,
+		 DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_HIGH) },
+	{ TIMING(122500000, 1280, 80, 136, 216, 800, 3, 6, 34,
+		 DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_HIGH) },
+	{ TIMING(146250000, 1280, 48, 32, 80, 800, 3, 6, 38,
+		 DISPLAY_FLAGS_HSYNC_HIGH | DISPLAY_FLAGS_VSYNC_LOW) },
+	{ TIMING(108000000, 1280, 96, 112, 312, 960, 1, 3, 36,
+		 DISPLAY_FLAGS_HSYNC_HIGH | DISPLAY_FLAGS_VSYNC_HIGH) },
+	{ TIMING(148500000, 1280, 64, 160, 224, 960, 1, 3, 47,
+		 DISPLAY_FLAGS_HSYNC_HIGH | DISPLAY_FLAGS_VSYNC_HIGH) },
+	{ TIMING(175500000, 1280, 48, 32, 80, 960, 3, 4, 50,
+		 DISPLAY_FLAGS_HSYNC_HIGH | DISPLAY_FLAGS_VSYNC_LOW) },
+	{ TIMING(108000000, 1280, 48, 112, 248, 1024, 1, 3, 38,
+		 DISPLAY_FLAGS_HSYNC_HIGH | DISPLAY_FLAGS_VSYNC_HIGH) },
+	{ TIMING(135000000, 1280, 16, 144, 248, 1024, 1, 3, 38,
+		 DISPLAY_FLAGS_HSYNC_HIGH | DISPLAY_FLAGS_VSYNC_HIGH) },
+	{ TIMING(157500000, 1280, 64, 160, 224, 1024, 1, 3, 44,
+		 DISPLAY_FLAGS_HSYNC_HIGH | DISPLAY_FLAGS_VSYNC_HIGH) },
+	{ TIMING(187250000, 1280, 48, 32, 80, 1024, 3, 7, 50,
+		 DISPLAY_FLAGS_HSYNC_HIGH | DISPLAY_FLAGS_VSYNC_LOW) },
+	{ TIMING(85500000, 1360, 64, 112, 256, 768, 3, 6, 18,
+		 DISPLAY_FLAGS_HSYNC_HIGH | DISPLAY_FLAGS_VSYNC_HIGH) },
+	{ TIMING(148250000, 1360, 48, 32, 80, 768, 3, 5, 37,
+		 DISPLAY_FLAGS_HSYNC_HIGH | DISPLAY_FLAGS_VSYNC_LOW) },
+	{ TIMING(85500000, 1366, 70, 143, 213, 768, 3, 3, 24,
+		 DISPLAY_FLAGS_HSYNC_HIGH | DISPLAY_FLAGS_VSYNC_HIGH) },
+	{ TIMING(72000000, 1366, 14, 56, 64, 768, 1, 3, 28,
+		 DISPLAY_FLAGS_HSYNC_HIGH | DISPLAY_FLAGS_VSYNC_HIGH) },
+	{ TIMING(101000000, 1400, 48, 32, 80, 1050, 3, 4, 23,
+		 DISPLAY_FLAGS_HSYNC_HIGH | DISPLAY_FLAGS_VSYNC_LOW) },
+	{ TIMING(121750000, 1400, 88, 144, 232, 1050, 3, 4, 32,
+		 DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_HIGH) },
+	{ TIMING(156000000, 1400, 104, 144, 248, 1050, 3, 4, 42,
+		 DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_HIGH) },
+	{ TIMING(179500000, 1400, 104, 152, 256, 1050, 3, 4, 48,
+		 DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_HIGH) },
+	{ TIMING(208000000, 1400, 48, 32, 80, 1050, 3, 4, 55,
+		 DISPLAY_FLAGS_HSYNC_HIGH | DISPLAY_FLAGS_VSYNC_LOW) },
+	{ TIMING(88750000, 1440, 48, 32, 80, 900, 3, 6, 17,
+		 DISPLAY_FLAGS_HSYNC_HIGH | DISPLAY_FLAGS_VSYNC_LOW) },
+	{ TIMING(106500000, 1440, 80, 152, 232, 900, 3, 6, 25,
+		 DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_HIGH) },
+	{ TIMING(136750000, 1440, 96, 152, 248, 900, 3, 6, 33,
+		 DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_HIGH) },
+	{ TIMING(157000000, 1440, 104, 152, 256, 900, 3, 6, 39,
+		 DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_HIGH) },
+	{ TIMING(182750000, 1440, 48, 32, 80, 900, 3, 6, 44,
+		 DISPLAY_FLAGS_HSYNC_HIGH | DISPLAY_FLAGS_VSYNC_LOW) },
+	{ TIMING(108000000, 1600, 24, 80, 96, 900, 1, 3, 96,
+		 DISPLAY_FLAGS_HSYNC_HIGH | DISPLAY_FLAGS_VSYNC_HIGH) },
+	{ TIMING(162000000, 1600, 64, 192, 304, 1200, 1, 3, 46,
+		 DISPLAY_FLAGS_HSYNC_HIGH | DISPLAY_FLAGS_VSYNC_HIGH) },
+	{ TIMING(175500000, 1600, 64, 192, 304, 1200, 1, 3, 46,
+		 DISPLAY_FLAGS_HSYNC_HIGH | DISPLAY_FLAGS_VSYNC_HIGH) },
+	{ TIMING(189000000, 1600, 64, 192, 304, 1200, 1, 3, 46,
+		 DISPLAY_FLAGS_HSYNC_HIGH | DISPLAY_FLAGS_VSYNC_HIGH) },
+	{ TIMING(202500000, 1600, 64, 192, 304, 1200, 1, 3, 46,
+		 DISPLAY_FLAGS_HSYNC_HIGH | DISPLAY_FLAGS_VSYNC_HIGH) },
+	{ TIMING(229500000, 1600, 64, 192, 304, 1200, 1, 3, 46,
+		 DISPLAY_FLAGS_HSYNC_HIGH | DISPLAY_FLAGS_VSYNC_HIGH) },
+	{ TIMING(268250000, 1600, 48, 32, 80, 1200, 3, 4, 64,
+		 DISPLAY_FLAGS_HSYNC_HIGH | DISPLAY_FLAGS_VSYNC_LOW) },
+	{ TIMING(119000000, 1680, 48, 32, 80, 1050, 3, 6, 21,
+		 DISPLAY_FLAGS_HSYNC_HIGH | DISPLAY_FLAGS_VSYNC_LOW) },
+	{ TIMING(146250000, 1680, 104, 176, 280, 1050, 3, 6, 30,
+		 DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_HIGH) },
+	{ TIMING(187000000, 1680, 120, 176, 296, 1050, 3, 6, 40,
+		 DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_HIGH) },
+	{ TIMING(214750000, 1680, 128, 176, 304, 1050, 3, 6, 46,
+		 DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_HIGH) },
+	{ TIMING(245500000, 1680, 48, 32, 80, 1050, 3, 6, 53,
+		 DISPLAY_FLAGS_HSYNC_HIGH | DISPLAY_FLAGS_VSYNC_LOW) },
+	{ TIMING(204750000, 1792, 128, 200, 328, 1344, 1, 3, 46,
+		 DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_HIGH) },
+	{ TIMING(261000000, 1792, 96, 216, 352, 1344, 1, 3, 69,
+		 DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_HIGH) },
+	{ TIMING(333250000, 1792, 48, 32, 80, 1344, 3, 4, 72,
+		 DISPLAY_FLAGS_HSYNC_HIGH | DISPLAY_FLAGS_VSYNC_LOW) },
+	{ TIMING(218250000, 1856, 96, 224, 352, 1392, 1, 3, 43,
+		 DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_HIGH) },
+	{ TIMING(288000000, 1856, 128, 224, 352, 1392, 1, 3, 104,
+		 DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_HIGH) },
+	{ TIMING(356500000, 1856, 48, 32, 80, 1392, 3, 4, 75,
+		 DISPLAY_FLAGS_HSYNC_HIGH | DISPLAY_FLAGS_VSYNC_LOW) },
+	{ TIMING(148500000, 1920, 88, 44, 148, 1080, 4, 5, 36,
+		 DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_LOW) },
+	{ TIMING(154000000, 1920, 48, 32, 80, 1200, 3, 6, 26,
+		 DISPLAY_FLAGS_HSYNC_HIGH | DISPLAY_FLAGS_VSYNC_LOW) },
+	{ TIMING(193250000, 1920, 136, 200, 336, 1200, 3, 6, 36,
+		 DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_HIGH) },
+	{ TIMING(245250000, 1920, 136, 208, 344, 1200, 3, 6, 46,
+		 DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_HIGH) },
+	{ TIMING(281250000, 1920, 144, 208, 352, 1200, 3, 6, 53,
+		 DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_HIGH) },
+	{ TIMING(317000000, 1920, 48, 32, 80, 1200, 3, 6, 62,
+		 DISPLAY_FLAGS_HSYNC_HIGH | DISPLAY_FLAGS_VSYNC_LOW) },
+	{ TIMING(234000000, 1920, 128, 208, 344, 1440, 1, 3, 56,
+		 DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_HIGH) },
+	{ TIMING(297000000, 1920, 144, 224, 352, 1440, 1, 3, 56,
+		 DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_HIGH) },
+	{ TIMING(380500000, 1920, 48, 32, 80, 1440, 3, 4, 78,
+		 DISPLAY_FLAGS_HSYNC_HIGH | DISPLAY_FLAGS_VSYNC_LOW) },
+	{ TIMING(162000000, 2048, 26, 80, 96, 1152, 1, 3, 44,
+		 DISPLAY_FLAGS_HSYNC_HIGH | DISPLAY_FLAGS_VSYNC_HIGH) },
+	{ TIMING(268500000, 2560, 48, 32, 80, 1600, 3, 6, 37,
+		 DISPLAY_FLAGS_HSYNC_HIGH | DISPLAY_FLAGS_VSYNC_LOW) },
+	{ TIMING(348500000, 2560, 192, 280, 472, 1600, 3, 6, 49,
+		 DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_HIGH) },
+	{ TIMING(443250000, 2560, 208, 280, 488, 1600, 3, 6, 63,
+		 DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_HIGH) },
+	{ TIMING(505250000, 2560, 208, 280, 488, 1600, 3, 6, 73,
+		 DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_HIGH) },
+	{ TIMING(552750000, 2560, 48, 32, 80, 1600, 3, 6, 85,
+		 DISPLAY_FLAGS_HSYNC_HIGH | DISPLAY_FLAGS_VSYNC_LOW) },
+	{ TIMING(556744000, 4096, 8, 32, 40, 2160, 48, 8, 6,
+		 DISPLAY_FLAGS_HSYNC_HIGH | DISPLAY_FLAGS_VSYNC_LOW) },
+	{ TIMING(556188000, 4096, 8, 32, 40, 2160, 48, 8, 6,
+		 DISPLAY_FLAGS_HSYNC_HIGH | DISPLAY_FLAGS_VSYNC_LOW) },
+};
+
 int edid_check_info(struct edid1_info *edid_info)
 {
 	if ((edid_info == NULL) || (edid_info->version == 0))
@@ -200,6 +385,7 @@ int edid_get_timing_validate(u8 *buf, int buf_size,
 {
 	struct edid1_info *edid = (struct edid1_info *)buf;
 	bool found;
+	int i, k;
 
 	if (buf_size < sizeof(*edid) || edid_check_info(edid)) {
 		debug("%s: Invalid buffer\n", __func__);
@@ -237,6 +423,53 @@ int edid_get_timing_validate(u8 *buf, int buf_size,
 		}
 	}
 
+	/* Look for timing in Standard Timings */
+	if (!found) {
+		for (i = 0; i < ARRAY_SIZE(edid->standard_timings); i++) {
+			unsigned int aspect = 10000;
+			unsigned int x, y, freq;
+			unsigned char xres, vfreq;
+
+			xres = EDID1_INFO_STANDARD_TIMING_XRESOLUTION(*edid, i);
+			vfreq = EDID1_INFO_STANDARD_TIMING_VFREQ(*edid, i);
+			if (xres != vfreq || (xres != 0 && xres != 1) ||
+			    (vfreq != 0 && vfreq != 1)) {
+				switch (EDID1_INFO_STANDARD_TIMING_ASPECT(*edid, i)) {
+				case ASPECT_625: // 16:10
+					aspect = 6250;
+					break;
+				case ASPECT_75: // 4:3
+					aspect = 7500;
+					break;
+				case ASPECT_8: // 5:4
+					aspect = 8000;
+					break;
+				case ASPECT_5625: // 16:9
+					aspect = 5625;
+					break;
+				}
+				x = (xres + 31) * 8;
+				y = x * aspect / 10000;
+				freq = (vfreq & 0x3f) + 60;
+
+				for (k = 0; k < ARRAY_SIZE(dmt_timings); k++) {
+					const struct display_timing *dt = &dmt_timings[k];
+
+					if (dt->hactive.typ == x && dt->vactive.typ == y) {
+						found = mode_valid(mode_valid_priv, dt);
+						if (found) {
+							memcpy(timing, dt, sizeof(*timing));
+							break;
+						}
+					}
+				}
+
+				if (found)
+					break;
+			}
+		}
+	}
+
 	if (!found)
 		return -EINVAL;
 
-- 
2.43.0



More information about the U-Boot mailing list