Merge "msm: mdss: fix handling of audio for DVI sinks"
This commit is contained in:
commit
b728b32df3
7 changed files with 95 additions and 24 deletions
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 */
|
||||
|
||||
/*
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Add table
Reference in a new issue