From 0178c6e499024f16f90cbe2e8b95a078b8a3a339 Mon Sep 17 00:00:00 2001 From: Tatenda Chipeperekwa Date: Mon, 14 Nov 2016 16:56:02 -0800 Subject: [PATCH] msm: mdss: dp: add support for automated EDID tests Add support to parse the test request vector to determine whether an automated EDID test has been requested. If requested, send the checksum found in the first EDID block back to the sink for validation. Change-Id: I40159e554c1be1972a7e2d91a9792aee89171ac3 Signed-off-by: Tatenda Chipeperekwa CRs-Fixed: 1076516 --- drivers/video/fbdev/msm/mdss_dp.h | 16 ++++++++---- drivers/video/fbdev/msm/mdss_dp_aux.c | 36 +++++++++++++++++++++++++-- 2 files changed, 45 insertions(+), 7 deletions(-) diff --git a/drivers/video/fbdev/msm/mdss_dp.h b/drivers/video/fbdev/msm/mdss_dp.h index da3fd3b9c133..068be4fdf602 100644 --- a/drivers/video/fbdev/msm/mdss_dp.h +++ b/drivers/video/fbdev/msm/mdss_dp.h @@ -513,16 +513,22 @@ enum dp_lane_count { }; enum test_response { - TEST_NACK = 0x0, - TEST_ACK = 0x1, + TEST_ACK = 0x1, + TEST_NACK = 0x2, + TEST_EDID_CHECKSUM_WRITE = 0x4, }; static inline char *mdss_dp_get_test_response(u32 test_response) { switch (test_response) { - case TEST_NACK: return DP_ENUM_STR(TEST_NACK); - case TEST_ACK: return DP_ENUM_STR(TEST_ACK); - default: return "unknown"; + case TEST_NACK: + return DP_ENUM_STR(TEST_NACK); + case TEST_ACK: + return DP_ENUM_STR(TEST_ACK); + case TEST_EDID_CHECKSUM_WRITE: + return DP_ENUM_STR(TEST_EDID_CHECKSUM_WRITE); + default: + return "unknown"; } } diff --git a/drivers/video/fbdev/msm/mdss_dp_aux.c b/drivers/video/fbdev/msm/mdss_dp_aux.c index b64518194926..90afae40faa1 100644 --- a/drivers/video/fbdev/msm/mdss_dp_aux.c +++ b/drivers/video/fbdev/msm/mdss_dp_aux.c @@ -34,6 +34,8 @@ #include "mdss_dp.h" #include "mdss_dp_util.h" +static void dp_sink_parse_test_request(struct mdss_dp_drv_pdata *ep); + /* * edp buffer operation */ @@ -721,6 +723,20 @@ static int dp_aux_chan_ready(struct mdss_dp_drv_pdata *ep) return 0; } +static void dp_aux_send_checksum(struct mdss_dp_drv_pdata *dp, u32 checksum) +{ + char data[4]; + + data[0] = checksum; + pr_debug("writing checksum %d\n", data[0]); + dp_aux_write_buf(dp, 0x261, data, 1, 0); + + data[0] = TEST_EDID_CHECKSUM_WRITE; + pr_debug("sending test response %s\n", + mdss_dp_get_test_response(data[0])); + dp_aux_write_buf(dp, 0x260, data, 1, 0); +} + int mdss_dp_edid_read(struct mdss_dp_drv_pdata *dp) { struct edp_buf *rp = &dp->rxp; @@ -728,6 +744,7 @@ int mdss_dp_edid_read(struct mdss_dp_drv_pdata *dp) int edid_blk = 0, blk_num = 0, retries = 10; bool edid_parsing_done = false; const u8 cea_tag = 0x02; + u32 checksum = 0; ret = dp_aux_chan_ready(dp); if (ret) { @@ -735,6 +752,12 @@ int mdss_dp_edid_read(struct mdss_dp_drv_pdata *dp) return ret; } + /** + * Parse the test request vector to see whether there is a + * TEST_EDID_READ test request. + */ + dp_sink_parse_test_request(dp); + do { rlen = dp_aux_read_buf(dp, EDID_START_ADDRESS + (blk_num * EDID_BLOCK_SIZE), @@ -765,6 +788,7 @@ int mdss_dp_edid_read(struct mdss_dp_drv_pdata *dp) rp->data); edid_parsing_done = true; + checksum = rp->data[rp->len - 1]; } else { edid_blk++; blk_num++; @@ -783,9 +807,16 @@ int mdss_dp_edid_read(struct mdss_dp_drv_pdata *dp) rp->data, EDID_BLOCK_SIZE); if (edid_blk == dp->edid.ext_block_cnt) - return 0; + goto end; } while (retries--); +end: + if (dp->test_data.test_requested == TEST_EDID_READ) { + pr_debug("sending checksum %d\n", checksum); + dp_aux_send_checksum(dp, checksum); + dp->test_data = (const struct dpcd_test_request){ 0 }; + } + return 0; } @@ -1141,7 +1172,8 @@ static void dp_sink_parse_sink_count(struct mdss_dp_drv_pdata *ep) */ static bool dp_is_test_supported(u32 test_requested) { - return test_requested == TEST_LINK_TRAINING; + return (test_requested == TEST_LINK_TRAINING) || + (test_requested == TEST_EDID_READ); } /**