summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/video/fbdev/msm/mdss_dp.h16
-rw-r--r--drivers/video/fbdev/msm/mdss_dp_aux.c36
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);
}
/**