summaryrefslogtreecommitdiff
path: root/drivers/video/fbdev
diff options
context:
space:
mode:
authorAjay Singh Parmar <aparmar@codeaurora.org>2017-01-15 20:35:55 -0800
committerGerrit - the friendly Code Review server <code-review@localhost>2017-01-19 17:00:20 -0800
commiteae1dd350900c960511c33f8bc16cdc29fed6fef (patch)
tree21272a6806868b1b9b94f5326ac1492505244f70 /drivers/video/fbdev
parentbb91430ca920d79785c074327a7542d587f38063 (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.c8
-rw-r--r--drivers/video/fbdev/msm/mdss_hdmi_tx.c8
-rw-r--r--drivers/video/fbdev/msm/msm_ext_display.c87
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;