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.

Note for cherry-picking: There seem to be some formatting patches for
edid.c that never made it into the firmware branch, so for this patch
conflicts were resolved by just taking the newer (more correct)
version that was tested in ToT.

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: I7fb8674619c0b780cc64f3ab786286225a3fe0e2
Reviewed-on: https://chromium-review.googlesource.com/290333
Reviewed-by: Yakir Yang <ykk@rock-chips.com>
Reviewed-by: Julius Werner <jwerner@chromium.org>
Commit-Queue: David Hendricks <dhendrix@chromium.org>
Tested-by: David Hendricks <dhendrix@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/293604
Reviewed-by: David Hendricks <dhendrix@chromium.org>
This commit is contained in:
David Hendricks 2015-08-02 18:07:48 -07:00 committed by ChromeOS Commit Bot
commit d54ef1ca82
2 changed files with 80 additions and 83 deletions

View file

@ -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,13 +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. */
unsigned int aspect_landscape;
unsigned int aspect_portrait;
const char *range_class;
const char *syncmethod;
const char *stereo;
};
/* Defined in src/lib/edid.c */

View file

@ -69,20 +69,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;
}
@ -259,7 +282,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
@ -286,25 +309,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;
}
@ -313,7 +336,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])
@ -424,8 +447,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));
@ -465,41 +488,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;
}
@ -508,16 +531,16 @@ 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;
}
@ -984,15 +1007,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)));
@ -1005,24 +1028,24 @@ int decode_edid(unsigned char *edid, int size, struct edid *out)
c.has_valid_year = 1;
printk(BIOS_SPEW, "Made week %hd of model year %hd\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 %hd of %hd\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: %hd.%hd\n", edid[0x12], edid[0x13]);
out->version[0] = edid[0x12];
out->version[1] = edid[0x13];
printk(BIOS_SPEW, "EDID version: %hhd.%hhd\n", edid[0x12], edid[0x13]);
extra_info.version[0] = edid[0x12];
extra_info.version[1] = edid[0x13];
if (edid[0x12] == 1) {
if (edid[0x13] > 4) {
@ -1069,7 +1092,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) {
@ -1080,13 +1103,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" :
@ -1118,18 +1141,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]) {
printk(BIOS_SPEW, "Aspect ratio is %f (landscape)\n",
100.0/(edid[0x16] + 99));
/* truncated to integer %. We try to avoid floating point */
out->aspect_landscape = 10000 /(edid[0x16] + 99);
} else {
printk(BIOS_SPEW, "Aspect ratio is %f (portrait)\n",
100.0/(edid[0x15] + 99));
out->aspect_portrait = 10000 /(edid[0x16] + 99);
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);
} 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);
}
} else {
/* Either or both can be zero for 1.3 and before */