|
@@ -1041,13 +1041,15 @@ static bool drm_edid_is_zero(const u8 *in_edid, int length)
|
|
|
* @raw_edid: pointer to raw EDID block
|
|
|
* @block: type of block to validate (0 for base, extension otherwise)
|
|
|
* @print_bad_edid: if true, dump bad EDID blocks to the console
|
|
|
+ * @edid_corrupt: if true, the header or checksum is invalid
|
|
|
*
|
|
|
* Validate a base or extension EDID block and optionally dump bad blocks to
|
|
|
* the console.
|
|
|
*
|
|
|
* Return: True if the block is valid, false otherwise.
|
|
|
*/
|
|
|
-bool drm_edid_block_valid(u8 *raw_edid, int block, bool print_bad_edid)
|
|
|
+bool drm_edid_block_valid(u8 *raw_edid, int block, bool print_bad_edid,
|
|
|
+ bool *edid_corrupt)
|
|
|
{
|
|
|
u8 csum;
|
|
|
struct edid *edid = (struct edid *)raw_edid;
|
|
@@ -1060,11 +1062,22 @@ bool drm_edid_block_valid(u8 *raw_edid, int block, bool print_bad_edid)
|
|
|
|
|
|
if (block == 0) {
|
|
|
int score = drm_edid_header_is_valid(raw_edid);
|
|
|
- if (score == 8) ;
|
|
|
- else if (score >= edid_fixup) {
|
|
|
+ if (score == 8) {
|
|
|
+ if (edid_corrupt)
|
|
|
+ *edid_corrupt = 0;
|
|
|
+ } else if (score >= edid_fixup) {
|
|
|
+ /* Displayport Link CTS Core 1.2 rev1.1 test 4.2.2.6
|
|
|
+ * The corrupt flag needs to be set here otherwise, the
|
|
|
+ * fix-up code here will correct the problem, the
|
|
|
+ * checksum is correct and the test fails
|
|
|
+ */
|
|
|
+ if (edid_corrupt)
|
|
|
+ *edid_corrupt = 1;
|
|
|
DRM_DEBUG("Fixing EDID header, your hardware may be failing\n");
|
|
|
memcpy(raw_edid, edid_header, sizeof(edid_header));
|
|
|
} else {
|
|
|
+ if (edid_corrupt)
|
|
|
+ *edid_corrupt = 1;
|
|
|
goto bad;
|
|
|
}
|
|
|
}
|
|
@@ -1075,6 +1088,9 @@ bool drm_edid_block_valid(u8 *raw_edid, int block, bool print_bad_edid)
|
|
|
DRM_ERROR("EDID checksum is invalid, remainder is %d\n", csum);
|
|
|
}
|
|
|
|
|
|
+ if (edid_corrupt)
|
|
|
+ *edid_corrupt = 1;
|
|
|
+
|
|
|
/* allow CEA to slide through, switches mangle this */
|
|
|
if (raw_edid[0] != 0x02)
|
|
|
goto bad;
|
|
@@ -1129,7 +1145,7 @@ bool drm_edid_is_valid(struct edid *edid)
|
|
|
return false;
|
|
|
|
|
|
for (i = 0; i <= edid->extensions; i++)
|
|
|
- if (!drm_edid_block_valid(raw + i * EDID_LENGTH, i, true))
|
|
|
+ if (!drm_edid_block_valid(raw + i * EDID_LENGTH, i, true, NULL))
|
|
|
return false;
|
|
|
|
|
|
return true;
|
|
@@ -1232,7 +1248,8 @@ struct edid *drm_do_get_edid(struct drm_connector *connector,
|
|
|
for (i = 0; i < 4; i++) {
|
|
|
if (get_edid_block(data, block, 0, EDID_LENGTH))
|
|
|
goto out;
|
|
|
- if (drm_edid_block_valid(block, 0, print_bad_edid))
|
|
|
+ if (drm_edid_block_valid(block, 0, print_bad_edid,
|
|
|
+ &connector->edid_corrupt))
|
|
|
break;
|
|
|
if (i == 0 && drm_edid_is_zero(block, EDID_LENGTH)) {
|
|
|
connector->null_edid_counter++;
|
|
@@ -1257,7 +1274,10 @@ struct edid *drm_do_get_edid(struct drm_connector *connector,
|
|
|
block + (valid_extensions + 1) * EDID_LENGTH,
|
|
|
j, EDID_LENGTH))
|
|
|
goto out;
|
|
|
- if (drm_edid_block_valid(block + (valid_extensions + 1) * EDID_LENGTH, j, print_bad_edid)) {
|
|
|
+ if (drm_edid_block_valid(block + (valid_extensions + 1)
|
|
|
+ * EDID_LENGTH, j,
|
|
|
+ print_bad_edid,
|
|
|
+ NULL)) {
|
|
|
valid_extensions++;
|
|
|
break;
|
|
|
}
|