From 306732cd443da8774c229e48d19f0ad61d8da0ce Mon Sep 17 00:00:00 2001 From: Sandeep Panda Date: Wed, 8 Jun 2016 09:20:42 +0530 Subject: [PATCH 1/2] msm: mdss: try to read EDID again in case of read errors As per HDMI specification a source should try to re-read the EDID in case there is error during the EDID buffer read, like checksum mismatch or EDID header not correct. So retry for maximum allowed attempts when EDID read fails due to any reason. Change-Id: I04b222271cf22834dc0ea6355cd78a7492e24f27 Signed-off-by: Sandeep Panda --- drivers/video/fbdev/msm/mdss_hdmi_tx.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/video/fbdev/msm/mdss_hdmi_tx.c b/drivers/video/fbdev/msm/mdss_hdmi_tx.c index 66e7c749e595..4c303224ba95 100644 --- a/drivers/video/fbdev/msm/mdss_hdmi_tx.c +++ b/drivers/video/fbdev/msm/mdss_hdmi_tx.c @@ -1707,7 +1707,7 @@ static int hdmi_tx_read_edid(struct hdmi_tx_ctrl *hdmi_ctrl) check_sum += ebuf[ndx]; if (check_sum & 0xFF) { - DEV_ERR("%s: checksome mismatch\n", __func__); + DEV_ERR("%s: checksum mismatch\n", __func__); ret = -EINVAL; goto end; } @@ -2262,6 +2262,8 @@ static void hdmi_tx_update_deep_color(struct hdmi_tx_ctrl *hdmi_ctrl) static void hdmi_tx_hpd_int_work(struct work_struct *work) { struct hdmi_tx_ctrl *hdmi_ctrl = NULL; + int rc = -EINVAL; + int retry = MAX_EDID_READ_RETRY; hdmi_ctrl = container_of(work, struct hdmi_tx_ctrl, hpd_int_work); if (!hdmi_ctrl) { @@ -2280,7 +2282,10 @@ static void hdmi_tx_hpd_int_work(struct work_struct *work) hdmi_ctrl->hpd_state ? "CONNECT" : "DISCONNECT"); if (hdmi_ctrl->hpd_state) { - hdmi_tx_read_sink_info(hdmi_ctrl); + while (rc && retry--) + rc = hdmi_tx_read_sink_info(hdmi_ctrl); + if (!retry && rc) + pr_warn_ratelimited("%s: EDID read failed\n", __func__); hdmi_tx_update_deep_color(hdmi_ctrl); hdmi_tx_send_cable_notification(hdmi_ctrl, true); From 1a71e5ed0c887d12226d5f4557b4ad8c83b6f3a0 Mon Sep 17 00:00:00 2001 From: Ingrid Gallardo Date: Wed, 8 Jun 2016 10:51:09 -0700 Subject: [PATCH 2/2] msm: mdss: enable pll regulator during phy on sequence Make sure pll regulator is enabled as part of the phy on sequence. This fixes some corruption observed when pll is disabled as part of the phy shut-down sequence. Change-Id: I1ace97dbf5b8e5ed8fceedddf714758a5f708cfb Signed-off-by: Ingrid Gallardo --- drivers/video/fbdev/msm/msm_mdss_io_8974.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/drivers/video/fbdev/msm/msm_mdss_io_8974.c b/drivers/video/fbdev/msm/msm_mdss_io_8974.c index 3dc2e952b5dd..e6151b4c75a1 100644 --- a/drivers/video/fbdev/msm/msm_mdss_io_8974.c +++ b/drivers/video/fbdev/msm/msm_mdss_io_8974.c @@ -947,8 +947,11 @@ static void mdss_dsi_8996_phy_power_off( { int ln; void __iomem *base; + u32 data; - MIPI_OUTP(ctrl->phy_io.base + DSIPHY_CMN_CTRL_0, 0x7f); + /* Turn off PLL power */ + data = MIPI_INP(ctrl->phy_io.base + DSIPHY_CMN_CTRL_0); + MIPI_OUTP(ctrl->phy_io.base + DSIPHY_CMN_CTRL_0, data & ~BIT(7)); /* 4 lanes + clk lane configuration */ for (ln = 0; ln < 5; ln++) { @@ -1004,6 +1007,7 @@ static void mdss_dsi_8996_phy_power_on( void __iomem *base; struct mdss_dsi_phy_ctrl *pd; char *ip; + u32 data; pd = &(((ctrl->panel_data).panel_info.mipi).dsi_phy_db); @@ -1023,6 +1027,10 @@ static void mdss_dsi_8996_phy_power_on( } mdss_dsi_8996_phy_regulator_enable(ctrl); + + /* Turn on PLL power */ + data = MIPI_INP(ctrl->phy_io.base + DSIPHY_CMN_CTRL_0); + MIPI_OUTP(ctrl->phy_io.base + DSIPHY_CMN_CTRL_0, data | BIT(7)); } static void mdss_dsi_phy_power_on( @@ -1126,6 +1134,7 @@ static void mdss_dsi_8996_phy_config(struct mdss_dsi_ctrl_pdata *ctrl) mdss_dsi_8996_pll_source_standalone(ctrl); } + MIPI_OUTP(ctrl->phy_io.base + DSIPHY_CMN_CTRL_0, 0x7f); wmb(); /* make sure registers committed */ }