diff options
Diffstat (limited to 'drivers/gpu/drm/drm_edid.c')
-rw-r--r-- | drivers/gpu/drm/drm_edid.c | 24 |
1 files changed, 20 insertions, 4 deletions
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index 99769d6c9f84..1fcec5f4c3ec 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c @@ -1590,11 +1590,22 @@ static int validate_displayid(u8 *displayid, int length, int idx); static int drm_edid_block_checksum(const u8 *raw_edid) { int i; - u8 csum = 0; - for (i = 0; i < EDID_LENGTH; i++) + u8 csum = 0, crc = 0; + + for (i = 0; i < EDID_LENGTH - 1; i++) csum += raw_edid[i]; - return csum; + crc = 0x100 - csum; + + return crc; +} + +static bool drm_edid_block_checksum_diff(const u8 *raw_edid, u8 real_checksum) +{ + if (raw_edid[EDID_LENGTH - 1] != real_checksum) + return true; + else + return false; } static bool drm_edid_is_zero(const u8 *in_edid, int length) @@ -1652,7 +1663,7 @@ bool drm_edid_block_valid(u8 *raw_edid, int block, bool print_bad_edid, } csum = drm_edid_block_checksum(raw_edid); - if (csum) { + if (drm_edid_block_checksum_diff(raw_edid, csum)) { if (edid_corrupt) *edid_corrupt = true; @@ -1793,6 +1804,11 @@ static void connector_bad_edid(struct drm_connector *connector, u8 *edid, int num_blocks) { int i; + u8 num_of_ext = edid[0x7e]; + + /* Calculate real checksum for the last edid extension block data */ + connector->real_edid_checksum = + drm_edid_block_checksum(edid + num_of_ext * EDID_LENGTH); if (connector->bad_edid_counter++ && !drm_debug_enabled(DRM_UT_KMS)) return; |