summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/drivers/emulation/qemu/bochs.c2
-rw-r--r--src/drivers/emulation/qemu/cirrus.c2
-rw-r--r--src/include/edid.h3
-rw-r--r--src/lib/edid.c17
-rw-r--r--src/soc/nvidia/tegra124/display.c2
-rw-r--r--src/soc/nvidia/tegra132/dc.c2
-rw-r--r--src/soc/nvidia/tegra210/dc.c2
-rw-r--r--src/soc/rockchip/rk3288/display.c2
8 files changed, 20 insertions, 12 deletions
diff --git a/src/drivers/emulation/qemu/bochs.c b/src/drivers/emulation/qemu/bochs.c
index f32fee008c..74a72471a7 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 84c2958031..dc20f540ae 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 f46c761935..73412a3304 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 52898fbfa6..8bcb95630f 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,16 @@ 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);
+ row_byte_alignment = max(row_byte_alignment, 1);
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 74202bad23..bb96831514 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 562061a1d3..3ae25bc2f5 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 72f1bcb3fa..88e599defd 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 66b2edc5b8..306baad3b6 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);