summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinux Build Service Account <lnxbuild@localhost>2016-12-21 07:30:07 -0800
committerGerrit - the friendly Code Review server <code-review@localhost>2016-12-21 07:30:06 -0800
commitb728b32df366f512c7f7b87c8a75708d5902ac74 (patch)
tree4f0756cc746ab9cacedd3bf52409c80727636753
parent8d9d44abdd65eca8f9036a6c1a9cc8f3508faa7c (diff)
parent1bd7966d14bf125a8d53dd53229ed2c8dda174e5 (diff)
Merge "msm: mdss: fix handling of audio for DVI sinks"
-rw-r--r--drivers/video/fbdev/msm/mdss_dba_utils.c2
-rw-r--r--drivers/video/fbdev/msm/mdss_dp.c13
-rw-r--r--drivers/video/fbdev/msm/mdss_hdmi_edid.c19
-rw-r--r--drivers/video/fbdev/msm/mdss_hdmi_edid.h2
-rw-r--r--drivers/video/fbdev/msm/mdss_hdmi_tx.c15
-rw-r--r--drivers/video/fbdev/msm/msm_ext_display.c56
-rw-r--r--include/linux/msm_ext_display.h12
7 files changed, 95 insertions, 24 deletions
diff --git a/drivers/video/fbdev/msm/mdss_dba_utils.c b/drivers/video/fbdev/msm/mdss_dba_utils.c
index 76671b539aa7..0808a1a6e14b 100644
--- a/drivers/video/fbdev/msm/mdss_dba_utils.c
+++ b/drivers/video/fbdev/msm/mdss_dba_utils.c
@@ -542,7 +542,7 @@ int mdss_dba_utils_video_on(void *data, struct mdss_panel_info *pinfo)
video_cfg.h_pulse_width = pinfo->lcdc.h_pulse_width;
video_cfg.v_pulse_width = pinfo->lcdc.v_pulse_width;
video_cfg.pclk_khz = (unsigned long)pinfo->clk_rate / 1000;
- video_cfg.hdmi_mode = hdmi_edid_get_sink_mode(ud->edid_data);
+ video_cfg.hdmi_mode = !hdmi_edid_is_dvi_mode(ud->edid_data);
/* Calculate number of DSI lanes configured */
video_cfg.num_of_input_lanes = 0;
diff --git a/drivers/video/fbdev/msm/mdss_dp.c b/drivers/video/fbdev/msm/mdss_dp.c
index 2dc45d2b2b8e..da3c8ca23fb6 100644
--- a/drivers/video/fbdev/msm/mdss_dp.c
+++ b/drivers/video/fbdev/msm/mdss_dp.c
@@ -898,6 +898,11 @@ static int dp_get_cable_status(struct platform_device *pdev, u32 vote)
return hpd;
}
+static bool mdss_dp_is_dvi_mode(struct mdss_dp_drv_pdata *dp)
+{
+ return hdmi_edid_is_dvi_mode(dp->panel_data.panel_info.edid_data);
+}
+
static int dp_audio_info_setup(struct platform_device *pdev,
struct msm_ext_disp_audio_setup_params *params)
{
@@ -1447,6 +1452,7 @@ static int mdss_dp_send_cable_notification(
struct mdss_dp_drv_pdata *dp, int val)
{
int ret = 0;
+ u32 flags = 0;
if (!dp) {
DEV_ERR("%s: invalid input\n", __func__);
@@ -1454,9 +1460,12 @@ static int mdss_dp_send_cable_notification(
goto end;
}
- if (dp && dp->ext_audio_data.intf_ops.hpd)
+ if (mdss_dp_is_dvi_mode(dp))
+ flags |= MSM_EXT_DISP_HPD_NO_AUDIO;
+
+ if (dp->ext_audio_data.intf_ops.hpd)
ret = dp->ext_audio_data.intf_ops.hpd(dp->ext_pdev,
- dp->ext_audio_data.type, val);
+ dp->ext_audio_data.type, val, flags);
end:
return ret;
diff --git a/drivers/video/fbdev/msm/mdss_hdmi_edid.c b/drivers/video/fbdev/msm/mdss_hdmi_edid.c
index 0a316fa19909..3adf04214d87 100644
--- a/drivers/video/fbdev/msm/mdss_hdmi_edid.c
+++ b/drivers/video/fbdev/msm/mdss_hdmi_edid.c
@@ -2294,6 +2294,7 @@ int hdmi_edid_parser(void *input)
edid_buf += EDID_BLOCK_SIZE;
ieee_reg_id = hdmi_edid_extract_ieee_reg_id(edid_ctrl, edid_buf);
+ DEV_DBG("%s: ieee_reg_id = 0x%08x\n", __func__, ieee_reg_id);
if (ieee_reg_id == EDID_IEEE_REG_ID)
edid_ctrl->sink_mode = SINK_MODE_HDMI;
else
@@ -2388,7 +2389,7 @@ end:
return scaninfo;
} /* hdmi_edid_get_sink_scaninfo */
-u32 hdmi_edid_get_sink_mode(void *input)
+static u32 hdmi_edid_get_sink_mode(void *input)
{
struct hdmi_edid_ctrl *edid_ctrl = (struct hdmi_edid_ctrl *)input;
bool sink_mode;
@@ -2408,6 +2409,22 @@ u32 hdmi_edid_get_sink_mode(void *input)
} /* hdmi_edid_get_sink_mode */
/**
+ * hdmi_edid_is_dvi_mode() - check if the dvi mode is set in the EDID
+ * @input: edid parser data
+ *
+ * This API returns true is the DVI mode bit in the EDID is set. This
+ * API can be used to check if the sink associated with the EDID data
+ * is a DVI sink or not
+ */
+bool hdmi_edid_is_dvi_mode(void *input)
+{
+ if (hdmi_edid_get_sink_mode(input))
+ return false;
+ else
+ return true;
+}
+
+/**
* hdmi_edid_get_deep_color() - get deep color info supported by sink
* @input: edid parser data
*
diff --git a/drivers/video/fbdev/msm/mdss_hdmi_edid.h b/drivers/video/fbdev/msm/mdss_hdmi_edid.h
index 43e1adb1f139..5ee77fcf2066 100644
--- a/drivers/video/fbdev/msm/mdss_hdmi_edid.h
+++ b/drivers/video/fbdev/msm/mdss_hdmi_edid.h
@@ -47,7 +47,7 @@ struct hdmi_edid_hdr_data {
int hdmi_edid_parser(void *edid_ctrl);
u32 hdmi_edid_get_raw_data(void *edid_ctrl, u8 *buf, u32 size);
u8 hdmi_edid_get_sink_scaninfo(void *edid_ctrl, u32 resolution);
-u32 hdmi_edid_get_sink_mode(void *edid_ctrl);
+bool hdmi_edid_is_dvi_mode(void *input);
bool hdmi_edid_sink_scramble_override(void *input);
bool hdmi_edid_get_sink_scrambler_support(void *input);
bool hdmi_edid_get_scdc_support(void *input);
diff --git a/drivers/video/fbdev/msm/mdss_hdmi_tx.c b/drivers/video/fbdev/msm/mdss_hdmi_tx.c
index 92d2ffdd41cd..ae6246f2ca27 100644
--- a/drivers/video/fbdev/msm/mdss_hdmi_tx.c
+++ b/drivers/video/fbdev/msm/mdss_hdmi_tx.c
@@ -376,8 +376,7 @@ static void hdmi_tx_audio_setup(struct hdmi_tx_ctrl *hdmi_ctrl)
static inline u32 hdmi_tx_is_dvi_mode(struct hdmi_tx_ctrl *hdmi_ctrl)
{
- return hdmi_edid_get_sink_mode(
- hdmi_tx_get_fd(HDMI_TX_FEAT_EDID)) ? 0 : 1;
+ return hdmi_edid_is_dvi_mode(hdmi_tx_get_fd(HDMI_TX_FEAT_EDID));
} /* hdmi_tx_is_dvi_mode */
static inline bool hdmi_tx_is_panel_on(struct hdmi_tx_ctrl *hdmi_ctrl)
@@ -419,9 +418,15 @@ static inline void hdmi_tx_cec_device_suspend(struct hdmi_tx_ctrl *hdmi_ctrl)
static inline void hdmi_tx_send_cable_notification(
struct hdmi_tx_ctrl *hdmi_ctrl, int val)
{
- if (hdmi_ctrl && hdmi_ctrl->ext_audio_data.intf_ops.hpd)
+ 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;
+
hdmi_ctrl->ext_audio_data.intf_ops.hpd(hdmi_ctrl->ext_pdev,
- hdmi_ctrl->ext_audio_data.type, val);
+ hdmi_ctrl->ext_audio_data.type, val, flags);
+ }
}
static inline void hdmi_tx_set_audio_switch_node(
@@ -2452,7 +2457,7 @@ static void hdmi_tx_set_mode(struct hdmi_tx_ctrl *hdmi_ctrl, u32 power_on)
hdmi_ctrl_reg |= BIT(2);
/* Set transmission mode to DVI based in EDID info */
- if (!hdmi_edid_get_sink_mode(hdmi_tx_get_fd(HDMI_TX_FEAT_EDID)))
+ if (hdmi_edid_is_dvi_mode(hdmi_tx_get_fd(HDMI_TX_FEAT_EDID)))
hdmi_ctrl_reg &= ~BIT(1); /* DVI mode */
/*
diff --git a/drivers/video/fbdev/msm/msm_ext_display.c b/drivers/video/fbdev/msm/msm_ext_display.c
index ca01ee6345d2..4fccf1178dac 100644
--- a/drivers/video/fbdev/msm/msm_ext_display.c
+++ b/drivers/video/fbdev/msm/msm_ext_display.c
@@ -49,7 +49,8 @@ static int msm_ext_disp_get_intf_data(struct msm_ext_disp *ext_disp,
struct msm_ext_disp_init_data **data);
static int msm_ext_disp_audio_ack(struct platform_device *pdev, u32 ack);
static int msm_ext_disp_update_audio_ops(struct msm_ext_disp *ext_disp,
- enum msm_ext_disp_cable_state state);
+ enum msm_ext_disp_type type,
+ enum msm_ext_disp_cable_state state, u32 flags);
static int msm_ext_disp_switch_dev_register(struct msm_ext_disp *ext_disp)
{
@@ -359,9 +360,18 @@ static int msm_ext_disp_send_audio_notification(struct msm_ext_disp *ext_disp,
}
static int msm_ext_disp_process_display(struct msm_ext_disp *ext_disp,
- enum msm_ext_disp_cable_state state)
+ enum msm_ext_disp_type type,
+ enum msm_ext_disp_cable_state state, u32 flags)
{
- int ret = msm_ext_disp_send_cable_notification(ext_disp, state);
+ int ret = 0;
+
+ if (flags & MSM_EXT_DISP_HPD_NO_VIDEO) {
+ pr_debug("skipping video setup for display (%s)\n",
+ msm_ext_disp_name(type));
+ goto end;
+ }
+
+ ret = msm_ext_disp_send_cable_notification(ext_disp, state);
/* positive ret value means audio node was switched */
if (IS_ERR_VALUE(ret) || !ret) {
@@ -383,9 +393,18 @@ end:
}
static int msm_ext_disp_process_audio(struct msm_ext_disp *ext_disp,
- enum msm_ext_disp_cable_state state)
+ enum msm_ext_disp_type type,
+ enum msm_ext_disp_cable_state state, u32 flags)
{
- int ret = msm_ext_disp_send_audio_notification(ext_disp, state);
+ int ret = 0;
+
+ if (flags & MSM_EXT_DISP_HPD_NO_AUDIO) {
+ pr_debug("skipping audio setup for display (%s)\n",
+ msm_ext_disp_name(type));
+ goto end;
+ }
+
+ ret = msm_ext_disp_send_audio_notification(ext_disp, state);
/* positive ret value means audio node was switched */
if (IS_ERR_VALUE(ret) || !ret || !ext_disp->ack_enabled) {
@@ -408,7 +427,8 @@ end:
static int msm_ext_disp_hpd(struct platform_device *pdev,
enum msm_ext_disp_type type,
- enum msm_ext_disp_cable_state state)
+ enum msm_ext_disp_cable_state state,
+ u32 flags)
{
int ret = 0;
struct msm_ext_disp *ext_disp = NULL;
@@ -455,21 +475,24 @@ static int msm_ext_disp_hpd(struct platform_device *pdev,
if (state == EXT_DISPLAY_CABLE_CONNECT) {
ext_disp->current_disp = type;
- ret = msm_ext_disp_process_display(ext_disp, state);
+ ret = msm_ext_disp_process_display(ext_disp, type, state,
+ flags);
if (ret)
goto end;
- msm_ext_disp_update_audio_ops(ext_disp, state);
+ ret = msm_ext_disp_update_audio_ops(ext_disp, type, state,
+ flags);
if (ret)
goto end;
- ret = msm_ext_disp_process_audio(ext_disp, state);
+ ret = msm_ext_disp_process_audio(ext_disp, type, state,
+ flags);
if (ret)
goto end;
} else {
- msm_ext_disp_process_audio(ext_disp, state);
- msm_ext_disp_update_audio_ops(ext_disp, state);
- msm_ext_disp_process_display(ext_disp, state);
+ 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;
}
@@ -624,11 +647,18 @@ end:
}
static int msm_ext_disp_update_audio_ops(struct msm_ext_disp *ext_disp,
- enum msm_ext_disp_cable_state state)
+ enum msm_ext_disp_type type,
+ enum msm_ext_disp_cable_state state, u32 flags)
{
int ret = 0;
struct msm_ext_disp_audio_codec_ops *ops = ext_disp->ops;
+ if (flags & MSM_EXT_DISP_HPD_NO_AUDIO) {
+ pr_debug("skipping audio ops setup for display (%s)\n",
+ msm_ext_disp_name(type));
+ goto end;
+ }
+
if (!ops) {
pr_err("Invalid audio ops\n");
ret = -EINVAL;
diff --git a/include/linux/msm_ext_display.h b/include/linux/msm_ext_display.h
index 59ba776b5f9b..b3a7e4ad722a 100644
--- a/include/linux/msm_ext_display.h
+++ b/include/linux/msm_ext_display.h
@@ -22,6 +22,15 @@
#define AUDIO_ACK_CONNECT BIT(0)
/**
+ * Flags to be used with the HPD operation of the external display
+ * interface:
+ * MSM_EXT_DISP_HPD_NO_AUDIO: audio will not be routed to external display
+ * MSM_EXT_DISP_HPD_NO_VIDEO: video will not be routed to external display
+ */
+#define MSM_EXT_DISP_HPD_NO_AUDIO BIT(0)
+#define MSM_EXT_DISP_HPD_NO_VIDEO BIT(1)
+
+/**
* struct ext_disp_cable_notify - cable notify handler structure
* @link: a link for the linked list
* @status: current status of HDMI/DP cable connection
@@ -87,7 +96,8 @@ enum msm_ext_disp_power_state {
struct msm_ext_disp_intf_ops {
int (*hpd)(struct platform_device *pdev,
enum msm_ext_disp_type type,
- enum msm_ext_disp_cable_state state);
+ enum msm_ext_disp_cable_state state,
+ u32 flags);
int (*notify)(struct platform_device *pdev,
enum msm_ext_disp_cable_state state);
int (*ack)(struct platform_device *pdev,