Merge "msm: mdss: fix handling of audio for DVI sinks"

This commit is contained in:
Linux Build Service Account 2016-12-21 07:30:07 -08:00 committed by Gerrit - the friendly Code Review server
commit b728b32df3
7 changed files with 95 additions and 24 deletions

View file

@ -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;

View file

@ -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;

View file

@ -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;
@ -2407,6 +2408,22 @@ u32 hdmi_edid_get_sink_mode(void *input)
return sink_mode;
} /* 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

View file

@ -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);

View file

@ -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 */
/*

View file

@ -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;

View file

@ -21,6 +21,15 @@
#define AUDIO_ACK_ENABLE BIT(4)
#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
@ -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,