aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/include/edid.h8
-rw-r--r--src/lib/edid.c24
2 files changed, 28 insertions, 4 deletions
diff --git a/src/include/edid.h b/src/include/edid.h
index 7d4736dc33..ce1f615709 100644
--- a/src/include/edid.h
+++ b/src/include/edid.h
@@ -55,6 +55,14 @@ struct edid {
unsigned int vso;
unsigned int vspw;
unsigned int vborder;
+ /* 3 variables needed for coreboot framebuffer.
+ * In most cases, they are the same as the ha
+ * and va variables, but not always, as in the
+ * case of a 1366 wide display.
+ */
+ u32 x_resolution;
+ u32 y_resolution;
+ u32 bytes_per_line;
/* it is unlikely we need these things. */
/* if one of these is non-zero, use that one. */
unsigned int aspect_landscape;
diff --git a/src/lib/edid.c b/src/lib/edid.c
index d0e8b98b52..aa12596d89 100644
--- a/src/lib/edid.c
+++ b/src/lib/edid.c
@@ -457,6 +457,23 @@ detailed_block(struct edid *out, unsigned char *x, int in_extension)
out->vso = ((x[10] >> 4) + ((x[11] & 0x0C) << 2));
out->vspw = ((x[10] & 0x0F) + ((x[11] & 0x03) << 4));
out->vborder = x[16];
+ /* set up some reasonable defaults for payloads.
+ * We observe that most modern chipsets we work with
+ * tend to support rgb888 without regard to the
+ * panel bits per color or other settings. The rgb888
+ * is a convenient layout for software because
+ * it avoids the messy bit stuffing of rgb565 or rgb444.
+ * It makes a reasonable trade of memory for speed.
+ * So, set up the default for
+ * 32 bits per pixel
+ * rgb888 (i.e. no alpha, but pixels on 32-bit boundaries)
+ * The mainboard can modify these if needed, though
+ * we have yet to see a case where that will happen.
+ */
+ out->bpp = 32;
+ out->x_resolution = ALIGN(out->ha * ((out->bpp + 7) / 8),64) / (out->bpp/8);
+ out->y_resolution = out->va;
+ out->bytes_per_line = ALIGN(out->ha * ((out->bpp + 7) / 8),64);
printk(BIOS_SPEW, "Did detailed timing\n");
}
did_detailed_timing = 1;
@@ -1398,8 +1415,9 @@ int decode_edid(unsigned char *edid, int size, struct edid *out)
void set_vbe_mode_info_valid(struct edid *edid, uintptr_t fb_addr)
{
edid_fb.physical_address = fb_addr;
- edid_fb.x_resolution = edid->ha;
- edid_fb.y_resolution = edid->va;
+ edid_fb.x_resolution = edid->x_resolution;
+ edid_fb.y_resolution = edid->y_resolution;
+ edid_fb.bytes_per_line = edid->bytes_per_line;
/* In the case of (e.g.) 24bpp, the convention nowadays
* seems to be to round it up to the nearest reasonable
* boundary, because otherwise the byte-packing is hideous.
@@ -1416,7 +1434,6 @@ void set_vbe_mode_info_valid(struct edid *edid, uintptr_t fb_addr)
case 32:
case 24:
/* packed into 4-byte words */
- edid_fb.bytes_per_line = edid->ha * 4;
edid_fb.red_mask_pos = 16;
edid_fb.red_mask_size = 8;
edid_fb.green_mask_pos = 8;
@@ -1426,7 +1443,6 @@ void set_vbe_mode_info_valid(struct edid *edid, uintptr_t fb_addr)
break;
case 16:
/* packed into 2-byte words */
- edid_fb.bytes_per_line = edid->ha * 2;
edid_fb.red_mask_pos = 12;
edid_fb.red_mask_size = 4;
edid_fb.green_mask_pos = 8;