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>
diff --git a/src/drivers/parade/ps8640/ps8640.c b/src/drivers/parade/ps8640/ps8640.c
index 9596560..62bbf63 100644
--- a/src/drivers/parade/ps8640/ps8640.c
+++ b/src/drivers/parade/ps8640/ps8640.c
@@ -47,7 +47,7 @@
 		}
 	}
 
-	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 cf81258..100dbe9 100644
--- a/src/include/edid.h
+++ b/src/include/edid.h
@@ -91,6 +91,12 @@
 	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 58dd813..7b7098a 100644
--- a/src/lib/edid.c
+++ b/src/lib/edid.c
@@ -66,7 +66,7 @@
 	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 @@
 	    .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 @@
 
 	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 @@
 		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 @@
 		    !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 @@
 		 * 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 @@
 			   "\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 @@
 			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 @@
 	    !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 @@
 	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 a308f68..0132369 100644
--- a/src/soc/nvidia/tegra124/dp.c
+++ b/src/soc/nvidia/tegra124/dp.c
@@ -1322,7 +1322,7 @@
 		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 e047584..350eb82 100644
--- a/src/soc/nvidia/tegra210/dp.c
+++ b/src/soc/nvidia/tegra210/dp.c
@@ -1361,7 +1361,7 @@
 		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 5723ccf..2594005 100644
--- a/src/soc/rockchip/common/edp.c
+++ b/src/soc/rockchip/common/edp.c
@@ -778,7 +778,7 @@
 		}
 	}
 
-	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 4966293..5e74423 100644
--- a/src/soc/rockchip/rk3288/hdmi.c
+++ b/src/soc/rockchip/rk3288/hdmi.c
@@ -814,7 +814,7 @@
 
 	/* 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. */