edid: Clean-up the edid struct
There are serveral members of the edid struct which are never used outside of the EDID parsing code itself. This patch moves them to a struct in edid.c. They might be useful some day but until then we can just pretty print them and not pollute the more general API. BUG=none BRANCH=firmware-veyron TEST=compiled for veyron_mickey, peppy, link, nyan_big, rush, smaug Signed-off-by: David Hendricks <dhendrix@chromium.org> Change-Id: I660f28c850163e89fe1f59d6c5cfd6e63a56dda0 Signed-off-by: Patrick Georgi <patrick@georgi-clan.de> Original-Commit-Id: ee8ea314a0d8f5993508f560fc24ab17604049df Original-Change-Id: I7fb8674619c0b780cc64f3ab786286225a3fe0e2 Original-Reviewed-on: https://chromium-review.googlesource.com/290333 Original-Reviewed-by: Yakir Yang <ykk@rock-chips.com> Original-Reviewed-by: Julius Werner <jwerner@chromium.org> Original-Commit-Queue: David Hendricks <dhendrix@chromium.org> Original-Tested-by: David Hendricks <dhendrix@chromium.org> Reviewed-on: http://review.coreboot.org/11387 Tested-by: build bot (Jenkins) Reviewed-by: Stefan Reinauer <stefan.reinauer@coreboot.org>
This commit is contained in:
parent
ffe63e2796
commit
a3b898aaf0
|
@ -27,14 +27,6 @@
|
|||
*/
|
||||
|
||||
struct edid {
|
||||
char manuf_name[4];
|
||||
unsigned int model;
|
||||
unsigned int serial;
|
||||
unsigned int year;
|
||||
unsigned int week;
|
||||
unsigned int version[2];
|
||||
unsigned int nonconformant;
|
||||
unsigned int type;
|
||||
/* These next three things used to all be called bpp.
|
||||
* Merriment ensued. The identifier
|
||||
* 'bpp' is herewith banished from our
|
||||
|
@ -56,17 +48,9 @@ struct edid {
|
|||
* all over the place.
|
||||
*/
|
||||
unsigned int panel_bits_per_pixel;
|
||||
unsigned int xres;
|
||||
unsigned int yres;
|
||||
unsigned int voltage;
|
||||
unsigned int sync;
|
||||
unsigned int xsize_cm;
|
||||
unsigned int ysize_cm;
|
||||
/* used to compute timing for graphics chips. */
|
||||
unsigned char phsync;
|
||||
unsigned char pvsync;
|
||||
unsigned int x_mm;
|
||||
unsigned int y_mm;
|
||||
unsigned int pixel_clock;
|
||||
unsigned int link_clock;
|
||||
unsigned int ha;
|
||||
|
@ -87,14 +71,6 @@ struct edid {
|
|||
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. */
|
||||
/* they're aspect * 10 to provide some additional resolution */
|
||||
unsigned int aspect_landscape;
|
||||
unsigned int aspect_portrait;
|
||||
const char *range_class;
|
||||
const char *syncmethod;
|
||||
const char *stereo;
|
||||
};
|
||||
|
||||
/* Defined in src/lib/edid.c */
|
||||
|
|
121
src/lib/edid.c
121
src/lib/edid.c
|
@ -68,20 +68,43 @@ struct edid_context {
|
|||
int conformant;
|
||||
};
|
||||
|
||||
/* Stuff that isn't used anywhere but is nice to pretty-print while
|
||||
we're decoding everything else. */
|
||||
static struct {
|
||||
char manuf_name[4];
|
||||
unsigned int model;
|
||||
unsigned int serial;
|
||||
unsigned int year;
|
||||
unsigned int week;
|
||||
unsigned int version[2];
|
||||
unsigned int nonconformant;
|
||||
unsigned int type;
|
||||
|
||||
unsigned int x_mm;
|
||||
unsigned int y_mm;
|
||||
|
||||
unsigned int voltage;
|
||||
unsigned int sync;
|
||||
|
||||
const char *syncmethod;
|
||||
const char *range_class;
|
||||
const char *stereo;
|
||||
} extra_info;
|
||||
|
||||
static int vbe_valid;
|
||||
static struct lb_framebuffer edid_fb;
|
||||
|
||||
static char *manufacturer_name(struct edid *out, unsigned char *x)
|
||||
static char *manufacturer_name(unsigned char *x)
|
||||
{
|
||||
out->manuf_name[0] = ((x[0] & 0x7C) >> 2) + '@';
|
||||
out->manuf_name[1] = ((x[0] & 0x03) << 3) + ((x[1] & 0xE0) >> 5) + '@';
|
||||
out->manuf_name[2] = (x[1] & 0x1F) + '@';
|
||||
out->manuf_name[3] = 0;
|
||||
extra_info.manuf_name[0] = ((x[0] & 0x7C) >> 2) + '@';
|
||||
extra_info.manuf_name[1] = ((x[0] & 0x03) << 3) + ((x[1] & 0xE0) >> 5) + '@';
|
||||
extra_info.manuf_name[2] = (x[1] & 0x1F) + '@';
|
||||
extra_info.manuf_name[3] = 0;
|
||||
|
||||
if (isupper(out->manuf_name[0]) &&
|
||||
isupper(out->manuf_name[1]) &&
|
||||
isupper(out->manuf_name[2]))
|
||||
return out->manuf_name;
|
||||
if (isupper(extra_info.manuf_name[0]) &&
|
||||
isupper(extra_info.manuf_name[1]) &&
|
||||
isupper(extra_info.manuf_name[2]))
|
||||
return extra_info.manuf_name;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
@ -258,7 +281,7 @@ detailed_block(struct edid *out, unsigned char *x, int in_extension,
|
|||
int v_max_offset = 0, v_min_offset = 0;
|
||||
int is_cvt = 0;
|
||||
c->has_range_descriptor = 1;
|
||||
out->range_class = "";
|
||||
extra_info.range_class = "";
|
||||
/*
|
||||
* XXX todo: implement feature flags, vtd blocks
|
||||
* XXX check: ranges are well-formed; block termination if no vtd
|
||||
|
@ -285,25 +308,25 @@ detailed_block(struct edid *out, unsigned char *x, int in_extension,
|
|||
*/
|
||||
switch (x[10]) {
|
||||
case 0x00: /* default gtf */
|
||||
out->range_class = "GTF";
|
||||
extra_info.range_class = "GTF";
|
||||
break;
|
||||
case 0x01: /* range limits only */
|
||||
out->range_class = "bare limits";
|
||||
extra_info.range_class = "bare limits";
|
||||
if (!c->claims_one_point_four)
|
||||
c->has_valid_range_descriptor = 0;
|
||||
break;
|
||||
case 0x02: /* secondary gtf curve */
|
||||
out->range_class = "GTF with icing";
|
||||
extra_info.range_class = "GTF with icing";
|
||||
break;
|
||||
case 0x04: /* cvt */
|
||||
out->range_class = "CVT";
|
||||
extra_info.range_class = "CVT";
|
||||
is_cvt = 1;
|
||||
if (!c->claims_one_point_four)
|
||||
c->has_valid_range_descriptor = 0;
|
||||
break;
|
||||
default: /* invalid */
|
||||
c->has_valid_range_descriptor = 0;
|
||||
out->range_class = "invalid";
|
||||
extra_info.range_class = "invalid";
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -312,7 +335,7 @@ detailed_block(struct edid *out, unsigned char *x, int in_extension,
|
|||
if (x[7] + h_min_offset > x[8] + h_max_offset)
|
||||
c->has_valid_range_descriptor = 0;
|
||||
printk(BIOS_SPEW, "Monitor ranges (%s): %d-%dHz V, %d-%dkHz H",
|
||||
out->range_class,
|
||||
extra_info.range_class,
|
||||
x[5] + v_min_offset, x[6] + v_max_offset,
|
||||
x[7] + h_min_offset, x[8] + h_max_offset);
|
||||
if (x[9])
|
||||
|
@ -423,8 +446,8 @@ detailed_block(struct edid *out, unsigned char *x, int in_extension,
|
|||
if (! c->did_detailed_timing){
|
||||
/* Edid contains pixel clock in terms of 10KHz */
|
||||
out->pixel_clock = (x[0] + (x[1] << 8)) * 10;
|
||||
out->x_mm = (x[12] + ((x[14] & 0xF0) << 4));
|
||||
out->y_mm = (x[13] + ((x[14] & 0x0F) << 8));
|
||||
extra_info.x_mm = (x[12] + ((x[14] & 0xF0) << 4));
|
||||
extra_info.y_mm = (x[13] + ((x[14] & 0x0F) << 8));
|
||||
out->ha = (x[2] + ((x[4] & 0xF0) << 4));
|
||||
out->hbl = (x[3] + ((x[4] & 0x0F) << 8));
|
||||
out->hso = (x[8] + ((x[11] & 0xC0) << 2));
|
||||
|
@ -464,41 +487,41 @@ detailed_block(struct edid *out, unsigned char *x, int in_extension,
|
|||
c->did_detailed_timing = 1;
|
||||
switch ((x[17] & 0x18) >> 3) {
|
||||
case 0x00:
|
||||
out->syncmethod = " analog composite";
|
||||
extra_info.syncmethod = " analog composite";
|
||||
break;
|
||||
case 0x01:
|
||||
out->syncmethod = " bipolar analog composite";
|
||||
extra_info.syncmethod = " bipolar analog composite";
|
||||
break;
|
||||
case 0x02:
|
||||
out->syncmethod = " digital composite";
|
||||
extra_info.syncmethod = " digital composite";
|
||||
break;
|
||||
case 0x03:
|
||||
out->syncmethod = "";
|
||||
extra_info.syncmethod = "";
|
||||
break;
|
||||
}
|
||||
out->pvsync = (x[17] & (1 << 2)) ? '+' : '-';
|
||||
out->phsync = (x[17] & (1 << 1)) ? '+' : '-';
|
||||
switch (x[17] & 0x61) {
|
||||
case 0x20:
|
||||
out->stereo = "field sequential L/R";
|
||||
extra_info.stereo = "field sequential L/R";
|
||||
break;
|
||||
case 0x40:
|
||||
out->stereo = "field sequential R/L";
|
||||
extra_info.stereo = "field sequential R/L";
|
||||
break;
|
||||
case 0x21:
|
||||
out->stereo = "interleaved right even";
|
||||
extra_info.stereo = "interleaved right even";
|
||||
break;
|
||||
case 0x41:
|
||||
out->stereo = "interleaved left even";
|
||||
extra_info.stereo = "interleaved left even";
|
||||
break;
|
||||
case 0x60:
|
||||
out->stereo = "four way interleaved";
|
||||
extra_info.stereo = "four way interleaved";
|
||||
break;
|
||||
case 0x61:
|
||||
out->stereo = "side by side interleaved";
|
||||
extra_info.stereo = "side by side interleaved";
|
||||
break;
|
||||
default:
|
||||
out->stereo = "";
|
||||
extra_info.stereo = "";
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -507,15 +530,15 @@ detailed_block(struct edid *out, unsigned char *x, int in_extension,
|
|||
" %04x %04x %04x %04x vborder %x\n"
|
||||
" %chsync %cvsync%s%s %s\n",
|
||||
out->pixel_clock,
|
||||
out->x_mm,
|
||||
out->y_mm,
|
||||
extra_info.x_mm,
|
||||
extra_info.y_mm,
|
||||
out->ha, out->ha + out->hso, out->ha + out->hso + out->hspw,
|
||||
out->ha + out->hbl, out->hborder,
|
||||
out->va, out->va + out->vso, out->va + out->vso + out->vspw,
|
||||
out->va + out->vbl, out->vborder,
|
||||
out->phsync, out->pvsync,
|
||||
out->syncmethod, x[17] & 0x80 ?" interlaced" : "",
|
||||
out->stereo
|
||||
extra_info.syncmethod, x[17] & 0x80 ?" interlaced" : "",
|
||||
extra_info.stereo
|
||||
);
|
||||
return 1;
|
||||
}
|
||||
|
@ -983,15 +1006,15 @@ int decode_edid(unsigned char *edid, int size, struct edid *out)
|
|||
}
|
||||
|
||||
memset(out, 0, sizeof(*out));
|
||||
if (manufacturer_name(out, edid + 0x08))
|
||||
if (manufacturer_name(edid + 0x08))
|
||||
c.manufacturer_name_well_formed = 1;
|
||||
|
||||
out->model = (unsigned short)(edid[0x0A] + (edid[0x0B] << 8));
|
||||
out->serial = (unsigned int)(edid[0x0C] + (edid[0x0D] << 8)
|
||||
extra_info.model = (unsigned short)(edid[0x0A] + (edid[0x0B] << 8));
|
||||
extra_info.serial = (unsigned int)(edid[0x0C] + (edid[0x0D] << 8)
|
||||
+ (edid[0x0E] << 16) + (edid[0x0F] << 24));
|
||||
|
||||
printk(BIOS_SPEW, "Manufacturer: %s Model %x Serial Number %u\n",
|
||||
out->manuf_name,
|
||||
extra_info.manuf_name,
|
||||
(unsigned short)(edid[0x0A] + (edid[0x0B] << 8)),
|
||||
(unsigned int)(edid[0x0C] + (edid[0x0D] << 8)
|
||||
+ (edid[0x0E] << 16) + (edid[0x0F] << 24)));
|
||||
|
@ -1004,24 +1027,24 @@ int decode_edid(unsigned char *edid, int size, struct edid *out)
|
|||
c.has_valid_year = 1;
|
||||
printk(BIOS_SPEW, "Made week %hhd of model year %hhd\n", edid[0x10],
|
||||
edid[0x11]);
|
||||
out->week = edid[0x10];
|
||||
out->year = edid[0x11];
|
||||
extra_info.week = edid[0x10];
|
||||
extra_info.year = edid[0x11];
|
||||
} else {
|
||||
/* we know it's at least 2013, when this code was written */
|
||||
if (edid[0x11] + 90 <= 2013) {
|
||||
c.has_valid_year = 1;
|
||||
printk(BIOS_SPEW, "Made week %hhd of %d\n",
|
||||
edid[0x10], edid[0x11] + 1990);
|
||||
out->week = edid[0x10];
|
||||
out->year = edid[0x11] + 1990;
|
||||
extra_info.week = edid[0x10];
|
||||
extra_info.year = edid[0x11] + 1990;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
printk(BIOS_SPEW, "EDID version: %hhd.%hhd\n", edid[0x12], edid[0x13]);
|
||||
out->version[0] = edid[0x12];
|
||||
out->version[1] = edid[0x13];
|
||||
extra_info.version[0] = edid[0x12];
|
||||
extra_info.version[1] = edid[0x13];
|
||||
|
||||
if (edid[0x12] == 1) {
|
||||
if (edid[0x13] > 4) {
|
||||
|
@ -1068,7 +1091,7 @@ int decode_edid(unsigned char *edid, int size, struct edid *out)
|
|||
default:
|
||||
c.nonconformant_digital_display = 1;
|
||||
}
|
||||
out->type = edid[0x14] & 0x0f;
|
||||
extra_info.type = edid[0x14] & 0x0f;
|
||||
} else if (c.claims_one_point_two) {
|
||||
conformance_mask = 0x7E;
|
||||
if (edid[0x14] & 0x01) {
|
||||
|
@ -1079,13 +1102,13 @@ int decode_edid(unsigned char *edid, int size, struct edid *out)
|
|||
|
||||
if (!c.nonconformant_digital_display)
|
||||
c.nonconformant_digital_display = edid[0x14] & conformance_mask;
|
||||
out->nonconformant = c.nonconformant_digital_display;
|
||||
extra_info.nonconformant = c.nonconformant_digital_display;
|
||||
} else {
|
||||
analog = 1;
|
||||
int voltage = (edid[0x14] & 0x60) >> 5;
|
||||
int sync = (edid[0x14] & 0x0F);
|
||||
out->voltage = voltage;
|
||||
out->sync = sync;
|
||||
extra_info.voltage = voltage;
|
||||
extra_info.sync = sync;
|
||||
|
||||
printk(BIOS_SPEW, "Analog display, Input voltage level: %s V\n",
|
||||
voltage == 3 ? "0.7/0.7" :
|
||||
|
@ -1117,19 +1140,15 @@ int decode_edid(unsigned char *edid, int size, struct edid *out)
|
|||
if (edid[0x15] && edid[0x16]) {
|
||||
printk(BIOS_SPEW, "Maximum image size: %d cm x %d cm\n",
|
||||
edid[0x15], edid[0x16]);
|
||||
out->xsize_cm = edid[0x15];
|
||||
out->ysize_cm = edid[0x16];
|
||||
} else if (c.claims_one_point_four && (edid[0x15] || edid[0x16])) {
|
||||
if (edid[0x15]) { /* edid[0x15] != 0 && edid[0x16] == 0 */
|
||||
unsigned int ratio = 100000/(edid[0x15] + 99);
|
||||
printk(BIOS_SPEW, "Aspect ratio is %u.%03u (landscape)\n",
|
||||
ratio / 1000, ratio % 1000);
|
||||
out->aspect_landscape = ratio / 100;
|
||||
} else { /* edid[0x15] == 0 && edid[0x16] != 0 */
|
||||
unsigned int ratio = 100000/(edid[0x16] + 99);
|
||||
printk(BIOS_SPEW, "Aspect ratio is %u.%03u (portrait)\n",
|
||||
ratio / 1000, ratio % 1000);
|
||||
out->aspect_portrait = ratio / 100;
|
||||
}
|
||||
} else {
|
||||
/* Either or both can be zero for 1.3 and before */
|
||||
|
|
Loading…
Reference in New Issue