diff options
| author | Aravind Venkateswaran <aravindh@codeaurora.org> | 2016-12-09 16:17:02 -0800 |
|---|---|---|
| committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2017-01-17 23:24:21 -0800 |
| commit | ff59333bdd9572a20eed86de0f568e263314ffaf (patch) | |
| tree | 1abd1ad57122cf55e3f8433ab3803bef5d4e1b7b /drivers/video/fbdev/msm | |
| parent | f03a0910178da306211df851876391f0b8679f5f (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.c | 19 |
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); |
