[coreboot-gerrit] Patch set updated for coreboot: edid: add function to manually specify mode

Patrick Georgi (pgeorgi@google.com) gerrit at coreboot.org
Thu Aug 27 17:28:30 CEST 2015


Patrick Georgi (pgeorgi at google.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/11390

-gerrit

commit 5c542869bd5fa642bfdc0e02e76529fa2a4aa748
Author: David Hendricks <dhendrix at chromium.org>
Date:   Fri Aug 7 18:41:37 2015 -0700

    edid: add function to manually specify mode
    
    This patch will let you to choose a favourite mode to
    display, while not just taking the edid detail timing.
    But not all modes are able to set, only modes that
    are in established or standard timing, and we only
    support a few common common resolutions for now.
    
    BUG=chrome-os-partner:42946
    BRANCH=firmware-veyron
    TEST=tested dev mode on Mickey at 640x480 at 60Hz
    
    Change-Id: I8a9dedfe08057d42d85b8ca129935a258cb26762
    Signed-off-by: Patrick Georgi <patrick at georgi-clan.de>
    Original-Commit-Id: 090583f90ff720d88e5cfe69fcb2d541c716f0e6
    Original-Change-Id: Iaa8c9a6fad106ee792f7cd1a0ac77e3dcbadf481
    Original-Signed-off-by: Yakir Yang <ykk at rock-chips.com>
    Original-Signed-off-by: David Hendricks <dhendrix at chromium.org>
    Original-Reviewed-on: https://chromium-review.googlesource.com/289671
    Original-Reviewed-by: Julius Werner <jwerner at chromium.org>
---
 src/include/edid.h |  9 +++++++-
 src/lib/edid.c     | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 68 insertions(+), 2 deletions(-)

diff --git a/src/include/edid.h b/src/include/edid.h
index 3de4dbc..72ae7f3 100644
--- a/src/include/edid.h
+++ b/src/include/edid.h
@@ -21,8 +21,13 @@
 #define EDID_H
 
 enum edid_modes {
-	EDID_MODE_AUTO = 0,
 	EDID_MODE_640x480_60Hz,
+	EDID_MODE_720x480_60Hz,
+	EDID_MODE_1280x720_60Hz,
+	EDID_MODE_1920x1080_60Hz,
+	NUM_KNOWN_MODES,
+
+	EDID_MODE_AUTO
 };
 
 struct edid_mode {
@@ -75,6 +80,7 @@ struct edid {
 	unsigned int panel_bits_per_pixel;
 	/* used to compute timing for graphics chips. */
 	struct edid_mode mode;
+	u8 mode_is_supported[NUM_KNOWN_MODES];
 	unsigned int link_clock;
 	/* 3 variables needed for coreboot framebuffer.
 	 * In most cases, they are the same as the ha
@@ -89,5 +95,6 @@ struct edid {
 /* Defined in src/lib/edid.c */
 int decode_edid(unsigned char *edid, int size, struct edid *out);
 void set_vbe_mode_info_valid(struct edid *edid, uintptr_t fb_addr);
+int set_display_mode(struct edid *edid, enum edid_modes mode);
 
 #endif /* EDID_H */
diff --git a/src/lib/edid.c b/src/lib/edid.c
index ed3565c..be3d906 100644
--- a/src/lib/edid.c
+++ b/src/lib/edid.c
@@ -977,6 +977,52 @@ static void dump_breakdown(unsigned char *edid)
 }
 
 /*
+ * Lookup table of some well-known modes that can be useful in case the
+ * auto-detected mode is unsuitable.
+ * ha = hdisplay;			va = vdisplay;
+ * hbl = htotal - hdisplay;		vbl = vtotal - vdisplay;
+ * hso = hsync_start - hdsiplay;	vso = vsync_start - vdisplay;
+ * hspw = hsync_end - hsync_start;	vspw = vsync_end - vsync_start;
+ */
+static struct edid_mode known_modes[NUM_KNOWN_MODES] = {
+	[EDID_MODE_640x480_60Hz] = {
+		.name = "640x480 at 60Hz", .pixel_clock = 25175, .refresh = 60,
+		.ha = 640, .hbl = 160, .hso = 16, .hborder = 96,
+		.va = 480, .vbl = 45, .vso = 10, .vspw = 2,
+		.phsync = '-', .pvsync = '-' },
+	[EDID_MODE_720x480_60Hz] = {
+		.name = "720x480 at 60Hz", .pixel_clock = 27000, .refresh = 60,
+		.ha = 720, .hbl = 78, .hso = 16, .hborder = 62,
+		.va = 480, .vbl = 45, .vso = 9, .vspw = 6,
+		.phsync = '-', .pvsync = '-' },
+	[EDID_MODE_1280x720_60Hz] = {
+		.name = "1280x720 at 60Hz", .pixel_clock = 74250, .refresh = 60,
+		.ha = 1280, .hbl = 370, .hso = 110, .hborder = 40,
+		.va = 720, .vbl = 30, .vso = 5, .vspw = 20,
+		.phsync = '+', .pvsync = '+' },
+	[EDID_MODE_1920x1080_60Hz] = {
+		.name = "1920x1080 at 60Hz", .pixel_clock = 148500, .refresh = 60,
+		.ha = 1920, .hbl = 280, .hso = 88, .hborder = 44,
+		.va = 1080, .vbl = 45, .vso = 4, .vspw = 5,
+		.phsync = '+', .pvsync = '+' },
+};
+
+int set_display_mode(struct edid *edid, enum edid_modes mode)
+{
+	if (mode == EDID_MODE_AUTO)
+		return 0;
+
+	if (edid->mode_is_supported[mode]) {
+		printk(BIOS_DEBUG, "Forcing mode %s\n", known_modes[mode].name);
+		edid->mode = known_modes[mode];
+		return 0;
+	}
+
+	printk(BIOS_ERR, "Requested display mode not supported.\n");
+	return -1;
+}
+
+/*
  * Given a raw edid bloc, decode it into a form
  * that other parts of coreboot can use -- mainly
  * graphics bringup functions. The raw block is
@@ -986,7 +1032,7 @@ static void dump_breakdown(unsigned char *edid)
  */
 int decode_edid(unsigned char *edid, int size, struct edid *out)
 {
-	int analog, i;
+	int analog, i, j;
 	struct edid_context c = {
 	    .has_valid_cvt = 1,
 	    .has_valid_dummy_block = 1,
@@ -1210,6 +1256,14 @@ int decode_edid(unsigned char *edid, int size, struct edid *out)
 			printk(BIOS_SPEW, "  %dx%d@%dHz\n", established_timings[i].x,
 			       established_timings[i].y, established_timings[i].refresh);
 		}
+
+		for (j = 0; j < NUM_KNOWN_MODES; j++) {
+			if (known_modes[j].ha == established_timings[i].x &&
+				known_modes[j].va == established_timings[i].y &&
+				known_modes[j].refresh ==  established_timings[i].refresh)
+					out->mode_is_supported[j] = 1;
+		}
+
 	}
 
 	printk(BIOS_SPEW, "Standard timings supported:\n");
@@ -1245,6 +1299,11 @@ int decode_edid(unsigned char *edid, int size, struct edid *out)
 		refresh = 60 + (b2 & 0x3f);
 
 		printk(BIOS_SPEW, "  %dx%d@%dHz\n", x, y, refresh);
+		for (j = 0; j < NUM_KNOWN_MODES; j++) {
+			if (known_modes[j].ha == x && known_modes[j].va == y &&
+					known_modes[j].refresh == refresh)
+				out->mode_is_supported[j] = 1;
+		}
 	}
 
 	/* detailed timings */



More information about the coreboot-gerrit mailing list