summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/drm_edid.c
diff options
context:
space:
mode:
authorJerry (Fangzhi) Zuo <Jerry.Zuo@amd.com>2020-02-11 11:08:32 -0500
committerRodrigo Siqueira <rodrigosiqueiramelo@gmail.com>2020-02-13 18:33:58 -0500
commite11f5bd8228fc3760c221f940b9f6365dbf3e7ed (patch)
treebc5aeb67afdb3efbadaaf17819c228e5c2c9efd4 /drivers/gpu/drm/drm_edid.c
parent48e678076e58341a70369d2db67770272181aa41 (diff)
drm: Add support for DP 1.4 Compliance edid corruption test
Unlike DP 1.2 edid corruption test, DP 1.4 requires to calculate real CRC value of the last edid data block, and write it back. Current edid CRC calculates routine adds the last CRC byte, and check if non-zero. This behavior is not accurate; actually, we need to return the actual CRC value when corruption is detected. This commit changes this issue by returning the calculated CRC, and initiate the required sequence. Change since v7 - Fix for CI.CHECKPATCH Change since v6 - Add return check Change since v5 - Obtain real CRC value before dumping bad edid Change since v4 - Fix for CI.CHECKPATCH Change since v3 - Fix a minor typo. Change since v2 - Rewrite checksum computation routine to avoid duplicated code. - Rename to avoid confusion. Change since v1 - Have separate routine for returning real CRC. Signed-off-by: Jerry (Fangzhi) Zuo <Jerry.Zuo@amd.com> Reviewed-by: Harry Wentland <harry.wentland@amd.com> Reviewed-by: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com> Signed-off-by: Rodrigo Siqueira <rodrigosiqueiramelo@gmail.com> Link: https://patchwork.freedesktop.org/patch/msgid/20200211160832.24259-1-Jerry.Zuo@amd.com
Diffstat (limited to 'drivers/gpu/drm/drm_edid.c')
-rw-r--r--drivers/gpu/drm/drm_edid.c24
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;