summaryrefslogtreecommitdiff
path: root/drivers/video/fbdev/msm
diff options
context:
space:
mode:
authorAravind Venkateswaran <aravindh@codeaurora.org>2016-12-09 16:17:02 -0800
committerGerrit - the friendly Code Review server <code-review@localhost>2017-01-17 23:24:21 -0800
commitff59333bdd9572a20eed86de0f568e263314ffaf (patch)
tree1abd1ad57122cf55e3f8433ab3803bef5d4e1b7b /drivers/video/fbdev/msm
parentf03a0910178da306211df851876391f0b8679f5f (diff)
msm: mdss: dp: fix switching between non-standard resolutions
EDID parser assigns temporary Video Identification Codes (VIC) for all non-standard resolutions when parsing a sink's EDID. These VICs can be reused for a subsequent connection for different resolutions. In the current implementation of the Display Port (DP) driver, a resolution change is detected whenever a new VIC is used. However, when switching between two non-standard resolutions spanning connections to two different sinks, it is possible to have the same VIC assigned for the two resolutions. This can result in abnormal behavior. Fix this by resetting the video identification code and panel information to reset value every time we get an HPD for disconnect. CRs-Fixed: 1099532 Change-Id: I4bb5a6b4329f67368ebbdc7fe8d92c2ea4605082 Signed-off-by: Aravind Venkateswaran <aravindh@codeaurora.org>
Diffstat (limited to 'drivers/video/fbdev/msm')
-rw-r--r--drivers/video/fbdev/msm/mdss_dp.c19
1 files changed, 14 insertions, 5 deletions
diff --git a/drivers/video/fbdev/msm/mdss_dp.c b/drivers/video/fbdev/msm/mdss_dp.c
index 79ee9722117f..937c987b3066 100644
--- a/drivers/video/fbdev/msm/mdss_dp.c
+++ b/drivers/video/fbdev/msm/mdss_dp.c
@@ -993,13 +993,17 @@ static int dp_init_panel_info(struct mdss_dp_drv_pdata *dp_drv, u32 vic)
DEV_ERR("invalid input\n");
return -EINVAL;
}
-
- ret = hdmi_get_supported_mode(&timing, 0, vic);
pinfo = &dp_drv->panel_data.panel_info;
- if (ret || !timing.supported || !pinfo) {
- DEV_ERR("%s: invalid timing data\n", __func__);
- return -EINVAL;
+ if (vic != HDMI_VFRMT_UNKNOWN) {
+ ret = hdmi_get_supported_mode(&timing, 0, vic);
+
+ if (ret || !timing.supported || !pinfo) {
+ DEV_ERR("%s: invalid timing data\n", __func__);
+ return -EINVAL;
+ }
+ } else {
+ pr_debug("reset panel info to zeroes\n");
}
dp_drv->vic = vic;
@@ -1207,6 +1211,9 @@ static int mdss_dp_on_irq(struct mdss_dp_drv_pdata *dp_drv)
goto exit;
}
+ if (dp_drv->new_vic && (dp_drv->new_vic != dp_drv->vic))
+ dp_init_panel_info(dp_drv, dp_drv->new_vic);
+
mdss_dp_phy_share_lane_config(&dp_drv->phy_io,
dp_drv->orientation,
dp_drv->dpcd.max_lane_count);
@@ -1398,6 +1405,7 @@ static int mdss_dp_off_irq(struct mdss_dp_drv_pdata *dp_drv)
dp_drv->power_on = false;
dp_drv->sink_info_read = false;
+ dp_init_panel_info(dp_drv, HDMI_VFRMT_UNKNOWN);
mutex_unlock(&dp_drv->train_mutex);
complete_all(&dp_drv->irq_comp);
pr_debug("end\n");
@@ -1445,6 +1453,7 @@ static int mdss_dp_off_hpd(struct mdss_dp_drv_pdata *dp_drv)
dp_drv->power_on = false;
dp_drv->sink_info_read = false;
+ dp_init_panel_info(dp_drv, HDMI_VFRMT_UNKNOWN);
mdss_dp_ack_state(dp_drv, false);
mutex_unlock(&dp_drv->train_mutex);