diff options
| author | Ajay Singh Parmar <aparmar@codeaurora.org> | 2017-01-15 20:35:55 -0800 |
|---|---|---|
| committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2017-01-19 17:00:20 -0800 |
| commit | eae1dd350900c960511c33f8bc16cdc29fed6fef (patch) | |
| tree | 21272a6806868b1b9b94f5326ac1492505244f70 /drivers/video/fbdev | |
| parent | bb91430ca920d79785c074327a7542d587f38063 (diff) | |
msm: ext_disp: allow multiple requests per client
Allow each display client to issue multiple requests for audio only,
video only or both to address different use cases for the display
clients.
CRs-Fixed: 1109812
Change-Id: I38518cebb37da0a48ffd817af9246a7c9682b494
Signed-off-by: Ajay Singh Parmar <aparmar@codeaurora.org>
Signed-off-by: Tatenda Chipeperekwa <tatendac@codeaurora.org>
Diffstat (limited to 'drivers/video/fbdev')
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_dp.c | 8 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_hdmi_tx.c | 8 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/msm_ext_display.c | 87 |
3 files changed, 72 insertions, 31 deletions
diff --git a/drivers/video/fbdev/msm/mdss_dp.c b/drivers/video/fbdev/msm/mdss_dp.c index 419510fbe999..9553b7a5cefc 100644 --- a/drivers/video/fbdev/msm/mdss_dp.c +++ b/drivers/video/fbdev/msm/mdss_dp.c @@ -926,9 +926,7 @@ static int dp_get_cable_status(struct platform_device *pdev, u32 vote) return -ENODEV; } - mutex_lock(&dp_ctrl->pd_msg_mutex); hpd = dp_ctrl->cable_connected; - mutex_unlock(&dp_ctrl->pd_msg_mutex); return hpd; } @@ -1574,8 +1572,10 @@ static int mdss_dp_send_cable_notification( goto end; } - if (mdss_dp_is_dvi_mode(dp)) - flags |= MSM_EXT_DISP_HPD_NO_AUDIO; + flags |= MSM_EXT_DISP_HPD_VIDEO; + + if (!mdss_dp_is_dvi_mode(dp)) + flags |= MSM_EXT_DISP_HPD_AUDIO; if (dp->ext_audio_data.intf_ops.hpd) ret = dp->ext_audio_data.intf_ops.hpd(dp->ext_pdev, diff --git a/drivers/video/fbdev/msm/mdss_hdmi_tx.c b/drivers/video/fbdev/msm/mdss_hdmi_tx.c index ae6246f2ca27..e7a79ce83168 100644 --- a/drivers/video/fbdev/msm/mdss_hdmi_tx.c +++ b/drivers/video/fbdev/msm/mdss_hdmi_tx.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2010-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -421,8 +421,10 @@ static inline void hdmi_tx_send_cable_notification( if (hdmi_ctrl && hdmi_ctrl->ext_audio_data.intf_ops.hpd) { u32 flags = 0; - if (hdmi_tx_is_dvi_mode(hdmi_ctrl)) - flags |= MSM_EXT_DISP_HPD_NO_AUDIO; + flags |= MSM_EXT_DISP_HPD_VIDEO; + + if (!hdmi_tx_is_dvi_mode(hdmi_ctrl)) + flags |= MSM_EXT_DISP_HPD_AUDIO; hdmi_ctrl->ext_audio_data.intf_ops.hpd(hdmi_ctrl->ext_pdev, hdmi_ctrl->ext_audio_data.type, val, flags); diff --git a/drivers/video/fbdev/msm/msm_ext_display.c b/drivers/video/fbdev/msm/msm_ext_display.c index 4fccf1178dac..30f8ca0487a7 100644 --- a/drivers/video/fbdev/msm/msm_ext_display.c +++ b/drivers/video/fbdev/msm/msm_ext_display.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -42,6 +42,7 @@ struct msm_ext_disp { struct list_head display_list; struct mutex lock; struct completion hpd_comp; + u32 flags; }; static int msm_ext_disp_get_intf_data(struct msm_ext_disp *ext_disp, @@ -365,7 +366,7 @@ static int msm_ext_disp_process_display(struct msm_ext_disp *ext_disp, { int ret = 0; - if (flags & MSM_EXT_DISP_HPD_NO_VIDEO) { + if (!(flags & MSM_EXT_DISP_HPD_VIDEO)) { pr_debug("skipping video setup for display (%s)\n", msm_ext_disp_name(type)); goto end; @@ -398,7 +399,7 @@ static int msm_ext_disp_process_audio(struct msm_ext_disp *ext_disp, { int ret = 0; - if (flags & MSM_EXT_DISP_HPD_NO_AUDIO) { + if (!(flags & MSM_EXT_DISP_HPD_AUDIO)) { pr_debug("skipping audio setup for display (%s)\n", msm_ext_disp_name(type)); goto end; @@ -425,6 +426,47 @@ end: return ret; } +static bool msm_ext_disp_validate_connect(struct msm_ext_disp *ext_disp, + enum msm_ext_disp_type type, u32 flags) +{ + /* allow new connections */ + if (ext_disp->current_disp == EXT_DISPLAY_TYPE_MAX) + goto end; + + /* if already connected, block a new connection */ + if (ext_disp->current_disp != type) + return false; + + /* if same display connected, block same connection type */ + if (ext_disp->flags & flags) + return false; + +end: + ext_disp->flags |= flags; + ext_disp->current_disp = type; + return true; +} + +static bool msm_ext_disp_validate_disconnect(struct msm_ext_disp *ext_disp, + enum msm_ext_disp_type type, u32 flags) +{ + /* check if nothing connected */ + if (ext_disp->current_disp == EXT_DISPLAY_TYPE_MAX) + return false; + + /* check if a different display's request */ + if (ext_disp->current_disp != type) + return false; + + /* allow only an already connected type */ + if (ext_disp->flags & flags) { + ext_disp->flags &= ~flags; + return true; + } + + return false; +} + static int msm_ext_disp_hpd(struct platform_device *pdev, enum msm_ext_disp_type type, enum msm_ext_disp_cable_state state, @@ -446,8 +488,8 @@ static int msm_ext_disp_hpd(struct platform_device *pdev, mutex_lock(&ext_disp->lock); - pr_debug("HPD for display (%s), NEW STATE = %d\n", - msm_ext_disp_name(type), state); + pr_debug("HPD for display (%s), NEW STATE = %d, flags = %d\n", + msm_ext_disp_name(type), state, flags); if (state < EXT_DISPLAY_CABLE_DISCONNECT || state >= EXT_DISPLAY_CABLE_STATE_MAX) { @@ -456,24 +498,13 @@ static int msm_ext_disp_hpd(struct platform_device *pdev, goto end; } - if ((state == EXT_DISPLAY_CABLE_CONNECT) && - (ext_disp->current_disp != EXT_DISPLAY_TYPE_MAX)) { - pr_err("Display interface (%s) already connected\n", - msm_ext_disp_name(ext_disp->current_disp)); - ret = -EINVAL; - goto end; - } - - if ((state == EXT_DISPLAY_CABLE_DISCONNECT) && - (ext_disp->current_disp != type)) { - pr_err("Display interface (%s) is not connected\n", - msm_ext_disp_name(type)); - ret = -EINVAL; - goto end; - } - if (state == EXT_DISPLAY_CABLE_CONNECT) { - ext_disp->current_disp = type; + if (!msm_ext_disp_validate_connect(ext_disp, type, flags)) { + pr_err("Display interface (%s) already connected\n", + msm_ext_disp_name(ext_disp->current_disp)); + ret = -EINVAL; + goto end; + } ret = msm_ext_disp_process_display(ext_disp, type, state, flags); @@ -490,11 +521,19 @@ static int msm_ext_disp_hpd(struct platform_device *pdev, if (ret) goto end; } else { + if (!msm_ext_disp_validate_disconnect(ext_disp, type, flags)) { + pr_err("Display interface (%s) not connected\n", + msm_ext_disp_name(type)); + ret = -EINVAL; + goto end; + } + msm_ext_disp_process_audio(ext_disp, type, state, flags); msm_ext_disp_update_audio_ops(ext_disp, type, state, flags); msm_ext_disp_process_display(ext_disp, type, state, flags); - ext_disp->current_disp = EXT_DISPLAY_TYPE_MAX; + if (!ext_disp->flags) + ext_disp->current_disp = EXT_DISPLAY_TYPE_MAX; } pr_debug("Hpd (%d) for display (%s)\n", state, @@ -653,7 +692,7 @@ static int msm_ext_disp_update_audio_ops(struct msm_ext_disp *ext_disp, int ret = 0; struct msm_ext_disp_audio_codec_ops *ops = ext_disp->ops; - if (flags & MSM_EXT_DISP_HPD_NO_AUDIO) { + if (!(flags & MSM_EXT_DISP_HPD_AUDIO)) { pr_debug("skipping audio ops setup for display (%s)\n", msm_ext_disp_name(type)); goto end; |
