[coreboot-gerrit] New patch to review for coreboot: edid: Make framebuffer row alignment configurable

Julius Werner (jwerner@chromium.org) gerrit at coreboot.org
Wed Apr 6 22:02:24 CEST 2016


Julius Werner (jwerner at chromium.org) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/14267

-gerrit

commit bb85653f808c6edb9373d945fe338065536f2d5a
Author: Julius Werner <jwerner at chromium.org>
Date:   Wed Apr 6 12:50:40 2016 -0700

    edid: Make framebuffer row alignment configurable
    
    Our EDID code had always been aligning the framebuffer's
    bytes_per_line (and x_resolution dependent on that) to 64. It turns out
    that this is a controller-dependent parameter that seems to only really
    be necessary for Intel chipsets, and commit 6911219cc (edid: Add helper
    function to calculate bits-per-pixel dependent values) probably actually
    broke this for some other controllers by applying the alignment too
    widely.
    
    This patch makes it explicitly configurable and depends the default on
    ARCH_X86 (which seems to be the simplest and least intrusive way to make
    it fit most cases for now... boards where this doesn't apply can still
    override it manually by calling edid_set_framebuffer_bits_per_pixel()
    again).
    
    Change-Id: I1c565a72826fc5ddfbb1ae4a5db5e9063b761455
    Signed-off-by: Julius Werner <jwerner at chromium.org>
---
 src/drivers/emulation/qemu/bochs.c  |  2 +-
 src/drivers/emulation/qemu/cirrus.c |  2 +-
 src/include/edid.h                  |  3 ++-
 src/lib/edid.c                      | 16 +++++++++++-----
 src/soc/nvidia/tegra124/display.c   |  2 +-
 src/soc/nvidia/tegra132/dc.c        |  2 +-
 src/soc/nvidia/tegra210/dc.c        |  2 +-
 src/soc/rockchip/rk3288/display.c   |  2 +-
 8 files changed, 19 insertions(+), 12 deletions(-)

diff --git a/src/drivers/emulation/qemu/bochs.c b/src/drivers/emulation/qemu/bochs.c
index f32fee0..74a7247 100644
--- a/src/drivers/emulation/qemu/bochs.c
+++ b/src/drivers/emulation/qemu/bochs.c
@@ -113,7 +113,7 @@ static void bochs_init(struct device *dev)
 	edid.mode.va = height;
 	edid.panel_bits_per_color = 8;
 	edid.panel_bits_per_pixel = 24;
-	edid_set_framebuffer_bits_per_pixel(&edid, 32);
+	edid_set_framebuffer_bits_per_pixel(&edid, 32, 0);
 	set_vbe_mode_info_valid(&edid, addr);
 #else
 	vga_misc_write(0x1);
diff --git a/src/drivers/emulation/qemu/cirrus.c b/src/drivers/emulation/qemu/cirrus.c
index 84c2958..dc20f54 100644
--- a/src/drivers/emulation/qemu/cirrus.c
+++ b/src/drivers/emulation/qemu/cirrus.c
@@ -332,7 +332,7 @@ static void cirrus_init(struct device *dev)
 	edid.mode.va = height;
 	edid.panel_bits_per_color = 8;
 	edid.panel_bits_per_pixel = 24;
-	edid_set_framebuffer_bits_per_pixel(&edid, 32);
+	edid_set_framebuffer_bits_per_pixel(&edid, 32, 0);
 	set_vbe_mode_info_valid(&edid, addr);
 #else
 	vga_misc_write(0x1);
diff --git a/src/include/edid.h b/src/include/edid.h
index f46c761..73412a3 100644
--- a/src/include/edid.h
+++ b/src/include/edid.h
@@ -93,7 +93,8 @@ struct edid {
 
 /* Defined in src/lib/edid.c */
 int decode_edid(unsigned char *edid, int size, struct edid *out);
-void edid_set_framebuffer_bits_per_pixel(struct edid *edid, int fb_bpp);
+void edid_set_framebuffer_bits_per_pixel(struct edid *edid, int fb_bpp,
+					 int row_byte_alignment);
 void set_vbe_mode_info_valid(struct edid *edid, uintptr_t fb_addr);
 int set_display_mode(struct edid *edid, enum edid_modes mode);
 
diff --git a/src/lib/edid.c b/src/lib/edid.c
index 52898fb..0381735 100644
--- a/src/lib/edid.c
+++ b/src/lib/edid.c
@@ -481,9 +481,14 @@ detailed_block(struct edid *result_edid, unsigned char *x, int in_extension,
 	out->mode.vborder = x[16];
 
 	/* We assume rgb888 (32 bits per pixel) framebuffers by default.
-	 * Chipsets that want something else will need to override this
-	 * with another call to edid_set_framebuffer_bits_per_pixel(). */
-	edid_set_framebuffer_bits_per_pixel(out, 32);
+	 * Chipsets that want something else will need to override this with
+	 * another call to edid_set_framebuffer_bits_per_pixel(). As a cheap
+	 * heuristic, assume that X86 systems require a 64-byte row alignment
+	 * (since that seems to be true for most Intel chipsets). */
+	if (IS_ENABLED(CONFIG_ARCH_X86))
+		edid_set_framebuffer_bits_per_pixel(out, 32, 64);
+	else
+		edid_set_framebuffer_bits_per_pixel(out, 32, 0);
 
 	switch ((x[17] & 0x18) >> 3) {
 	case 0x00:
@@ -1524,14 +1529,15 @@ int decode_edid(unsigned char *edid, int size, struct edid *out)
  */
 
 /* Set the framebuffer bits-per-pixel, recalculating all dependent values. */
-void edid_set_framebuffer_bits_per_pixel(struct edid *edid, int fb_bpp)
+void edid_set_framebuffer_bits_per_pixel(struct edid *edid, int fb_bpp,
+					 int row_byte_alignment)
 {
 	/* Caller should pass a supported value, everything else is BUG(). */
 	assert(fb_bpp == 32 || fb_bpp == 24 || fb_bpp == 16);
 
 	edid->framebuffer_bits_per_pixel = fb_bpp;
 	edid->bytes_per_line = ALIGN_UP(edid->mode.ha *
-					div_round_up(fb_bpp, 8), 64);
+		div_round_up(fb_bpp, 8), row_byte_alignment);
 	edid->x_resolution = edid->bytes_per_line / (fb_bpp / 8);
 	edid->y_resolution = edid->mode.va;
 }
diff --git a/src/soc/nvidia/tegra124/display.c b/src/soc/nvidia/tegra124/display.c
index 74202ba..bb96831 100644
--- a/src/soc/nvidia/tegra124/display.c
+++ b/src/soc/nvidia/tegra124/display.c
@@ -334,6 +334,6 @@ void display_startup(device_t dev)
 	edid.mode.va = config->yres;
 	edid.mode.ha = config->xres;
 	edid_set_framebuffer_bits_per_pixel(&edid,
-					    config->framebuffer_bits_per_pixel);
+		config->framebuffer_bits_per_pixel, 0);
 	set_vbe_mode_info_valid(&edid, (uintptr_t)(framebuffer_base_mb*MiB));
 }
diff --git a/src/soc/nvidia/tegra132/dc.c b/src/soc/nvidia/tegra132/dc.c
index 562061a..3ae25bc 100644
--- a/src/soc/nvidia/tegra132/dc.c
+++ b/src/soc/nvidia/tegra132/dc.c
@@ -230,7 +230,7 @@ void pass_mode_info_to_payload(
 	edid.mode.va = config->display_yres;
 	edid.mode.ha = config->display_xres;
 	edid_set_framebuffer_bits_per_pixel(&edid,
-					    config->framebuffer_bits_per_pixel);
+		config->framebuffer_bits_per_pixel, 0);
 
 	printk(BIOS_INFO, "%s: bytes_per_line: %d, bits_per_pixel: %d\n "
 			"               x_res x y_res: %d x %d, size: %d\n",
diff --git a/src/soc/nvidia/tegra210/dc.c b/src/soc/nvidia/tegra210/dc.c
index 72f1bcb..88e599d 100644
--- a/src/soc/nvidia/tegra210/dc.c
+++ b/src/soc/nvidia/tegra210/dc.c
@@ -230,7 +230,7 @@ void pass_mode_info_to_payload(
 	edid.mode.va = config->display_yres;
 	edid.mode.ha = config->display_xres;
 	edid_set_framebuffer_bits_per_pixel(&edid,
-					    config->framebuffer_bits_per_pixel);
+		config->framebuffer_bits_per_pixel, 0);
 
 	printk(BIOS_INFO, "%s: bytes_per_line: %d, bits_per_pixel: %d\n "
 			"               x_res x y_res: %d x %d, size: %d\n",
diff --git a/src/soc/rockchip/rk3288/display.c b/src/soc/rockchip/rk3288/display.c
index 66b2edc..306baad 100644
--- a/src/soc/rockchip/rk3288/display.c
+++ b/src/soc/rockchip/rk3288/display.c
@@ -95,7 +95,7 @@ void rk_display_init(device_t dev, u32 lcdbase,
 	}
 
 	edid_set_framebuffer_bits_per_pixel(&edid,
-					    conf->framebuffer_bits_per_pixel);
+		conf->framebuffer_bits_per_pixel, 0);
 	rkvop_mode_set(conf->vop_id, &edid, detected_mode);
 
 	rkvop_enable(conf->vop_id, lcdbase, &edid);



More information about the coreboot-gerrit mailing list