summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorArthur Heymans <arthur@aheymans.xyz>2017-04-30 08:28:05 +0200
committerNico Huber <nico.h@gmx.de>2017-05-03 16:16:43 +0200
commit8c5884e8d739ed0271da051034f5c4f475a00b55 (patch)
tree6b120a66bed866c6ba8cd0ad0d20e8e7cf2bb896 /src
parenta459a8a145be0413d540d6cb62f9a1b6ead3175a (diff)
lib/edid.c: Differentiate between absent and non-conformant EDID
Change-Id: Id90aa210ff72092c4ab638a7bafb82bd11889bdc Signed-off-by: Arthur Heymans <arthur@aheymans.xyz> Reviewed-on: https://review.coreboot.org/19502 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Nico Huber <nico.h@gmx.de>
Diffstat (limited to 'src')
-rw-r--r--src/drivers/parade/ps8640/ps8640.c2
-rw-r--r--src/include/edid.h6
-rw-r--r--src/lib/edid.c33
-rw-r--r--src/soc/nvidia/tegra124/dp.c2
-rw-r--r--src/soc/nvidia/tegra210/dp.c2
-rw-r--r--src/soc/rockchip/common/edp.c2
-rw-r--r--src/soc/rockchip/rk3288/hdmi.c2
7 files changed, 28 insertions, 21 deletions
diff --git a/src/drivers/parade/ps8640/ps8640.c b/src/drivers/parade/ps8640/ps8640.c
index 95965601ec..62bbf635b8 100644
--- a/src/drivers/parade/ps8640/ps8640.c
+++ b/src/drivers/parade/ps8640/ps8640.c
@@ -47,7 +47,7 @@ int ps8640_get_edid(uint8_t bus, uint8_t chip, struct edid *out)
}
}
- if (decode_edid(edid, edid_size, out)) {
+ if (decode_edid(edid, edid_size, out) != EDID_CONFORMANT) {
printk(BIOS_INFO, "Failed to decode EDID.\n");
return -1;
}
diff --git a/src/include/edid.h b/src/include/edid.h
index cf812583a5..100dbe9ba3 100644
--- a/src/include/edid.h
+++ b/src/include/edid.h
@@ -91,6 +91,12 @@ struct edid {
int hdmi_monitor_detected;
};
+enum edid_status {
+ EDID_CONFORMANT,
+ EDID_NOT_CONFORMANT,
+ EDID_ABSENT,
+};
+
/* 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,
diff --git a/src/lib/edid.c b/src/lib/edid.c
index 58dd813dd2..7b7098a0e8 100644
--- a/src/lib/edid.c
+++ b/src/lib/edid.c
@@ -66,7 +66,7 @@ struct edid_context {
int seen_non_detailed_descriptor;
int warning_excessive_dotclock_correction;
int warning_zero_preferred_refresh;
- int conformant;
+ enum edid_status conformant;
};
/* Stuff that isn't used anywhere but is nice to pretty-print while
@@ -1134,7 +1134,7 @@ int decode_edid(unsigned char *edid, int size, struct edid *out)
.has_valid_range_descriptor = 1,
.has_valid_max_dotclock = 1,
.has_valid_string_termination = 1,
- .conformant = 1,
+ .conformant = EDID_CONFORMANT,
};
dump_breakdown(edid);
@@ -1143,7 +1143,7 @@ int decode_edid(unsigned char *edid, int size, struct edid *out)
if (!edid || memcmp(edid, "\x00\xFF\xFF\xFF\xFF\xFF\xFF\x00", 8)) {
printk(BIOS_SPEW, "No header found\n");
- return 1;
+ return EDID_ABSENT;
}
if (manufacturer_name(edid + 0x08))
@@ -1485,11 +1485,12 @@ int decode_edid(unsigned char *edid, int size, struct edid *out)
if (c.nonconformant_digital_display ||
!c.has_valid_string_termination ||
!c.has_valid_descriptor_pad ||
- !c.has_preferred_timing)
- c.conformant = 0;
- if (!c.conformant)
+ !c.has_preferred_timing) {
+ c.conformant = EDID_NOT_CONFORMANT;
printk(BIOS_ERR,
"EDID block does NOT conform to EDID 1.4!\n");
+ }
+
if (c.nonconformant_digital_display)
printk(BIOS_ERR,
"\tDigital display field contains garbage: %x\n",
@@ -1507,7 +1508,7 @@ int decode_edid(unsigned char *edid, int size, struct edid *out)
!c.has_valid_string_termination ||
!c.has_valid_descriptor_pad ||
!c.has_preferred_timing) {
- c.conformant = 0;
+ c.conformant = EDID_NOT_CONFORMANT;
}
/**
* According to E-EDID (EDIDv1.3), has_name_descriptor and
@@ -1516,7 +1517,7 @@ int decode_edid(unsigned char *edid, int size, struct edid *out)
* don't have them. As a workaround, we only print warning
* messages.
*/
- if (!c.conformant)
+ if (c.conformant == EDID_NOT_CONFORMANT)
printk(BIOS_ERR,
"EDID block does NOT conform to EDID 1.3!\n");
else if (!c.has_name_descriptor || !c.has_range_descriptor)
@@ -1542,11 +1543,11 @@ int decode_edid(unsigned char *edid, int size, struct edid *out)
"\tDetailed block string not properly terminated\n");
} else if (c.claims_one_point_two) {
if (c.nonconformant_digital_display ||
- !c.has_valid_string_termination)
- c.conformant = 0;
- if (!c.conformant)
+ !c.has_valid_string_termination) {
+ c.conformant = EDID_NOT_CONFORMANT;
printk(BIOS_ERR,
"EDID block does NOT conform to EDID 1.2!\n");
+ }
if (c.nonconformant_digital_display)
printk(BIOS_ERR,
"\tDigital display field contains garbage: %x\n",
@@ -1555,11 +1556,11 @@ int decode_edid(unsigned char *edid, int size, struct edid *out)
printk(BIOS_ERR,
"\tDetailed block string not properly terminated\n");
} else if (c.claims_one_point_oh) {
- if (c.seen_non_detailed_descriptor)
- c.conformant = 0;
- if (!c.conformant)
+ if (c.seen_non_detailed_descriptor) {
+ c.conformant = EDID_NOT_CONFORMANT;
printk(BIOS_ERR,
"EDID block does NOT conform to EDID 1.0!\n");
+ }
if (c.seen_non_detailed_descriptor)
printk(BIOS_ERR,
"\tHas descriptor blocks other than detailed timings\n");
@@ -1576,7 +1577,7 @@ int decode_edid(unsigned char *edid, int size, struct edid *out)
!c.has_valid_descriptor_ordering ||
!c.has_valid_range_descriptor ||
!c.manufacturer_name_well_formed) {
- c.conformant = 0;
+ c.conformant = EDID_NOT_CONFORMANT;
printk(BIOS_ERR, "EDID block does not conform at all!\n");
if (c.nonconformant_extension)
printk(BIOS_ERR,
@@ -1618,7 +1619,7 @@ int decode_edid(unsigned char *edid, int size, struct edid *out)
if (c.warning_zero_preferred_refresh)
printk(BIOS_ERR,
"Warning: CVT block does not set preferred refresh rate\n");
- return !c.conformant;
+ return c.conformant;
}
/*
diff --git a/src/soc/nvidia/tegra124/dp.c b/src/soc/nvidia/tegra124/dp.c
index a308f68fe1..0132369073 100644
--- a/src/soc/nvidia/tegra124/dp.c
+++ b/src/soc/nvidia/tegra124/dp.c
@@ -1322,7 +1322,7 @@ static void tegra_dp_update_config(struct tegra_dc_dp_data *dp,
return;
}
- if (decode_edid(buf, sizeof(buf), &edid)) {
+ if (decode_edid(buf, sizeof(buf), &edid) != EDID_CONFORMANT) {
printk(BIOS_ERR, "%s: Failed to decode EDID. Use defaults.\n",
__func__);
return;
diff --git a/src/soc/nvidia/tegra210/dp.c b/src/soc/nvidia/tegra210/dp.c
index e0475842e3..350eb8254d 100644
--- a/src/soc/nvidia/tegra210/dp.c
+++ b/src/soc/nvidia/tegra210/dp.c
@@ -1361,7 +1361,7 @@ static void tegra_dp_update_config(struct tegra_dc_dp_data *dp,
return;
}
- if (decode_edid(buf, sizeof(buf), &edid)) {
+ if (decode_edid(buf, sizeof(buf), &edid) != EDID_CONFORMANT) {
printk(BIOS_ERR, "%s: Failed to decode EDID. Use defaults.\n",
__func__);
return;
diff --git a/src/soc/rockchip/common/edp.c b/src/soc/rockchip/common/edp.c
index 5723ccf660..259400530e 100644
--- a/src/soc/rockchip/common/edp.c
+++ b/src/soc/rockchip/common/edp.c
@@ -778,7 +778,7 @@ static int rk_edp_read_edid(struct rk_edp *edp, struct edid *edid)
}
}
- if (decode_edid(buf, edid_size, edid)) {
+ if (decode_edid(buf, edid_size, edid) != EDID_CONFORMANT) {
printk(BIOS_ERR, "%s: Failed to decode EDID.\n",
__func__);
return -1;
diff --git a/src/soc/rockchip/rk3288/hdmi.c b/src/soc/rockchip/rk3288/hdmi.c
index 496629316e..5e744236e7 100644
--- a/src/soc/rockchip/rk3288/hdmi.c
+++ b/src/soc/rockchip/rk3288/hdmi.c
@@ -814,7 +814,7 @@ int rk_hdmi_get_edid(struct edid *edid)
/* Assume usage of HDMI implies an external display in which case
* we should be lenient about errors that the EDID decoder finds. */
- if (decode_edid(edid_buf, edid_size, edid))
+ if (decode_edid(edid_buf, edid_size, edid) != EDID_CONFORMANT)
hdmi_debug("failed to decode edid.\n");
/* Try 480p for best compatibility. */