summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAravind Venkateswaran <aravindh@codeaurora.org>2017-02-03 16:28:27 -0800
committerGerrit - the friendly Code Review server <code-review@localhost>2017-04-13 18:19:49 -0700
commitfe847c64b01b335e5a93345471f914ac69b5b082 (patch)
treea06d1c0aeabdbed48d86393b225ae573fc86bebd
parentf5e769987f71a70c0b623a35438432b0b287d79c (diff)
msm: mdss: dp: fix EDID read sequence
Update the EDID read sequence to first write the offset to request the appropriate EDID block prior to reading the EDID block data. In addition, write the correct segment address when reading more than two extension blocks. CRs-Fixed: 2006096 Change-Id: Ic4b2bd4d4cf9da5e247c5735b4e768b9e2b87b27 Signed-off-by: Aravind Venkateswaran <aravindh@codeaurora.org> Signed-off-by: Tatenda Chipeperekwa <tatendac@codeaurora.org>
-rw-r--r--drivers/video/fbdev/msm/mdss_dp_aux.c58
1 files changed, 45 insertions, 13 deletions
diff --git a/drivers/video/fbdev/msm/mdss_dp_aux.c b/drivers/video/fbdev/msm/mdss_dp_aux.c
index 671ca8270e4c..eb1cb8785621 100644
--- a/drivers/video/fbdev/msm/mdss_dp_aux.c
+++ b/drivers/video/fbdev/msm/mdss_dp_aux.c
@@ -876,10 +876,10 @@ int mdss_dp_edid_read(struct mdss_dp_drv_pdata *dp)
int rlen, ret = 0;
int edid_blk = 0, blk_num = 0, retries = 10;
bool edid_parsing_done = false;
- const u8 cea_tag = 0x02, start_ext_blk = 0x1;
+ const u8 cea_tag = 0x02;
u32 const segment_addr = 0x30;
u32 checksum = 0;
- char segment = 0x1;
+ u8 offset[] = {0x0, 0x80};
ret = dp_aux_chan_ready(dp);
if (ret) {
@@ -895,26 +895,56 @@ int mdss_dp_edid_read(struct mdss_dp_drv_pdata *dp)
*/
dp_sink_parse_test_request(dp);
- do {
- rlen = dp_aux_read_buf_retry(dp, EDID_START_ADDRESS +
- (blk_num * EDID_BLOCK_SIZE),
+ while (retries) {
+ u8 *offset_p;
+ u8 segment;
+
+ /*
+ * Write the segment first.
+ * Segment = 0, for blocks 0 and 1
+ * Segment = 1, for blocks 2 and 3
+ * Segment = 2, for blocks 3 and 4
+ * and so on ...
+ */
+ segment = blk_num >> 1;
+ dp_aux_write_buf_retry(dp, segment_addr, &segment, 1, 1, false);
+
+ /*
+ * Write the offset of the desired EDID block to be read.
+ * For even blocks, offset = 0x0
+ * For odd blocks, offset = 0x80
+ */
+ if (blk_num % 2)
+ offset_p = &offset[1];
+ else
+ offset_p = &offset[0];
+ dp_aux_write_buf_retry(dp, EDID_START_ADDRESS, offset_p, 1, 1,
+ false);
+
+ rlen = dp_aux_read_buf_retry(dp, EDID_START_ADDRESS,
EDID_BLOCK_SIZE, 1, false);
if (rlen != EDID_BLOCK_SIZE) {
- pr_err("Read failed. rlen=%d\n", rlen);
+ pr_err("Read failed. rlen=%s\n",
+ mdss_dp_get_aux_error(rlen));
+ mdss_dp_phy_aux_update_config(dp, PHY_AUX_CFG1);
+ retries--;
continue;
}
-
pr_debug("blk_num=%d, rlen=%d\n", blk_num, rlen);
if (dp_edid_is_valid_header(rp->data)) {
ret = dp_edid_buf_error(rp->data, rp->len);
if (ret) {
pr_err("corrupt edid block detected\n");
+ mdss_dp_phy_aux_update_config(dp, PHY_AUX_CFG1);
+ retries--;
continue;
}
if (edid_parsing_done) {
+ pr_debug("block 0 parsed already\n");
blk_num++;
+ retries--;
continue;
}
@@ -928,6 +958,12 @@ int mdss_dp_edid_read(struct mdss_dp_drv_pdata *dp)
rp->data);
edid_parsing_done = true;
+ } else if (!edid_parsing_done) {
+ pr_debug("Invalid edid block 0 header\n");
+ /* Retry block 0 with adjusted phy aux settings */
+ mdss_dp_phy_aux_update_config(dp, PHY_AUX_CFG1);
+ retries--;
+ continue;
} else {
edid_blk++;
blk_num++;
@@ -948,13 +984,9 @@ int mdss_dp_edid_read(struct mdss_dp_drv_pdata *dp)
checksum = rp->data[rp->len - 1];
/* break if no more extension blocks present */
- if (edid_blk == dp->edid.ext_block_cnt)
+ if (edid_blk >= dp->edid.ext_block_cnt)
break;
-
- /* write segment number to read block 3 onwards */
- if (edid_blk == start_ext_blk)
- dp_aux_write_buf(dp, segment_addr, &segment, 1, 1);
- } while (retries--);
+ }
if (dp->test_data.test_requested == TEST_EDID_READ) {
pr_debug("sending checksum %d\n", checksum);