From 53863e53970ab9bfef1f085e3fad7bc5311cb1bd Mon Sep 17 00:00:00 2001
From: Tatenda Chipeperekwa <tatendac@codeaurora.org>
Date: Tue, 15 Nov 2016 14:34:42 -0800
Subject: [PATCH] msm: mdss: dp: enter failsafe mode on EDID read failure

Add support to enter failsafe mode on EDID read failures
that might be caused by corrupt EDID blocks or AUX
transaction failures. The failsafe mode for this driver
is 640x480 at 60fps, in accordance with the Display Port
v1.3 specification.

CRs-Fixed: 1076516
Change-Id: Ia3895fb0e860991173ffcde604c165d007cfa972
Signed-off-by: Tatenda Chipeperekwa <tatendac@codeaurora.org>
---
 drivers/video/fbdev/msm/mdss_dp.c     | 16 +++++++++++++---
 drivers/video/fbdev/msm/mdss_dp_aux.c |  9 ++++++---
 2 files changed, 19 insertions(+), 6 deletions(-)

diff --git a/drivers/video/fbdev/msm/mdss_dp.c b/drivers/video/fbdev/msm/mdss_dp.c
index ee0f43573c56..59c660002759 100644
--- a/drivers/video/fbdev/msm/mdss_dp.c
+++ b/drivers/video/fbdev/msm/mdss_dp.c
@@ -1450,6 +1450,12 @@ static int mdss_dp_notify_clients(struct mdss_dp_drv_pdata *dp, bool enable)
 	return mdss_dp_send_cable_notification(dp, enable);
 }
 
+static void mdss_dp_set_default_resolution(struct mdss_dp_drv_pdata *dp)
+{
+	hdmi_edid_set_video_resolution(dp->panel_data.panel_info.edid_data,
+			DEFAULT_VIDEO_RESOLUTION, true);
+}
+
 static int mdss_dp_edid_init(struct mdss_panel_data *pdata)
 {
 	struct mdss_dp_drv_pdata *dp_drv = NULL;
@@ -1484,6 +1490,8 @@ static int mdss_dp_edid_init(struct mdss_panel_data *pdata)
 	dp_drv->edid_buf = edid_init_data.buf;
 	dp_drv->edid_buf_size = edid_init_data.buf_size;
 
+	mdss_dp_set_default_resolution(dp_drv);
+
 	return 0;
 }
 
@@ -1548,8 +1556,11 @@ static int mdss_dp_host_init(struct mdss_panel_data *pdata)
 	mdss_dp_dpcd_cap_read(dp_drv);
 
 	ret = mdss_dp_edid_read(dp_drv);
-	if (ret)
+	if (ret) {
+		pr_info("edid read error, setting default resolution\n");
+		mdss_dp_set_default_resolution(dp_drv);
 		goto edid_error;
+	}
 
 	pr_debug("edid_read success. buf_size=%d\n",
 				dp_drv->edid_buf_size);
@@ -1560,14 +1571,13 @@ static int mdss_dp_host_init(struct mdss_panel_data *pdata)
 		goto edid_error;
 	}
 
+edid_error:
 	mdss_dp_update_cable_status(dp_drv, true);
 	mdss_dp_notify_clients(dp_drv, true);
 	dp_drv->dp_initialized = true;
 
 	return ret;
 
-edid_error:
-	mdss_dp_clk_ctrl(dp_drv, DP_CORE_PM, false);
 clk_error:
 	mdss_dp_regulator_ctrl(dp_drv, false);
 	mdss_dp_config_gpios(dp_drv, false);
diff --git a/drivers/video/fbdev/msm/mdss_dp_aux.c b/drivers/video/fbdev/msm/mdss_dp_aux.c
index 90afae40faa1..173851071b7a 100644
--- a/drivers/video/fbdev/msm/mdss_dp_aux.c
+++ b/drivers/video/fbdev/msm/mdss_dp_aux.c
@@ -770,8 +770,11 @@ int mdss_dp_edid_read(struct mdss_dp_drv_pdata *dp)
 		pr_debug("blk_num=%d, rlen=%d\n", blk_num, rlen);
 
 		if (dp_edid_is_valid_header(rp->data)) {
-			if (dp_edid_buf_error(rp->data, rp->len))
-				continue;
+			ret = dp_edid_buf_error(rp->data, rp->len);
+			if (ret) {
+				pr_err("corrupt edid block detected\n");
+				goto end;
+			}
 
 			if (edid_parsing_done) {
 				blk_num++;
@@ -817,7 +820,7 @@ end:
 		dp->test_data = (const struct dpcd_test_request){ 0 };
 	}
 
-	return 0;
+	return ret;
 }
 
 static void dp_sink_capability_read(struct mdss_dp_drv_pdata *ep,