diff options
| author | Ujwal Patel <ujwalp@codeaurora.org> | 2013-03-14 17:05:40 -0700 |
|---|---|---|
| committer | David Keitel <dkeitel@codeaurora.org> | 2016-03-23 20:15:24 -0700 |
| commit | 8ee7156cf1dd855aa8dd759bf3ec5220c81fd3cf (patch) | |
| tree | 7e0065f434ffe5229a2ce3cb4a7ab37f11a6c6a4 /drivers | |
| parent | 7b8cbc68c0d70dd60cf74e199d5e203a3d997e2e (diff) | |
msm: mdss: enable support for hdmi as primary
When HDMI is configured as primary display, enable hpd circuit
as soon as frame buffer is registered.
Change-Id: I4bcc796ea6310416077b09858a272b2622c62709
Signed-off-by: Ujwal Patel <ujwalp@codeaurora.org>
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_hdmi_tx.c | 56 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_hdmi_tx.h | 3 |
2 files changed, 51 insertions, 8 deletions
diff --git a/drivers/video/fbdev/msm/mdss_hdmi_tx.c b/drivers/video/fbdev/msm/mdss_hdmi_tx.c index caa24f6ef470..300671711982 100644 --- a/drivers/video/fbdev/msm/mdss_hdmi_tx.c +++ b/drivers/video/fbdev/msm/mdss_hdmi_tx.c @@ -449,6 +449,18 @@ static inline u32 hdmi_tx_is_dvi_mode(struct hdmi_tx_ctrl *hdmi_ctrl) hdmi_ctrl->feature_data[HDMI_TX_FEAT_EDID]) ? 0 : 1; } /* hdmi_tx_is_dvi_mode */ +static inline void hdmi_tx_send_cable_notification( + struct hdmi_tx_ctrl *hdmi_ctrl, int val) +{ + if (!hdmi_ctrl) { + DEV_ERR("%s: invalid input\n", __func__); + return; + } + + if (!hdmi_ctrl->pdata.primary && (hdmi_ctrl->sdev.state != val)) + switch_set_state(&hdmi_ctrl->sdev, val); +} /* hdmi_tx_send_cable_notification */ + static inline void hdmi_tx_set_audio_switch_node(struct hdmi_tx_ctrl *hdmi_ctrl, int val, bool force) { @@ -695,11 +707,11 @@ static void hdmi_tx_hpd_int_work(struct work_struct *work) if (hdmi_ctrl->hpd_state) { hdmi_tx_read_sink_info(hdmi_ctrl); - switch_set_state(&hdmi_ctrl->sdev, 1); + hdmi_tx_send_cable_notification(hdmi_ctrl, 1); DEV_INFO("%s: sense cable CONNECTED: state switch to %d\n", __func__, hdmi_ctrl->sdev.state); } else { - switch_set_state(&hdmi_ctrl->sdev, 0); + hdmi_tx_send_cable_notification(hdmi_ctrl, 0); DEV_INFO("%s: sense cable DISCONNECTED: state switch to %d\n", __func__, hdmi_ctrl->sdev.state); } @@ -2097,6 +2109,7 @@ static int hdmi_tx_power_off(struct mdss_panel_data *panel_data) static int hdmi_tx_power_on(struct mdss_panel_data *panel_data) { + u32 timeout; int rc = 0; struct dss_io_data *io = NULL; struct hdmi_tx_ctrl *hdmi_ctrl = @@ -2121,6 +2134,16 @@ static int hdmi_tx_power_on(struct mdss_panel_data *panel_data) /* If a power down is already underway, wait for it to finish */ flush_work(&hdmi_ctrl->power_off_work); + if (hdmi_ctrl->pdata.primary) { + timeout = wait_for_completion_interruptible_timeout( + &hdmi_ctrl->hpd_done, HZ); + if (!timeout) { + DEV_ERR("%s: cable connection hasn't happened yet\n", + __func__); + return -ETIMEDOUT; + } + } + rc = hdmi_tx_set_video_fmt(hdmi_ctrl, &panel_data->panel_info); if (rc) { DEV_ERR("%s: cannot set video_fmt.rc=%d\n", __func__, rc); @@ -2265,7 +2288,7 @@ static int hdmi_tx_sysfs_enable_hpd(struct hdmi_tx_ctrl *hdmi_ctrl, int on) } else { hdmi_ctrl->hpd_off_pending = true; - switch_set_state(&hdmi_ctrl->sdev, 0); + hdmi_tx_send_cable_notification(hdmi_ctrl, 0); DEV_DBG("%s: Hdmi state switch to %d\n", __func__, hdmi_ctrl->sdev.state); } @@ -2441,6 +2464,20 @@ static int hdmi_tx_panel_event_handler(struct mdss_panel_data *panel_data, hdmi_tx_sysfs_remove(hdmi_ctrl); return rc; } + + if (hdmi_ctrl->pdata.primary) { + INIT_COMPLETION(hdmi_ctrl->hpd_done); + rc = hdmi_tx_sysfs_enable_hpd(hdmi_ctrl, true); + if (rc) { + DEV_ERR("%s: hpd_enable failed. rc=%d\n", + __func__, rc); + hdmi_tx_sysfs_remove(hdmi_ctrl); + return rc; + } else { + hdmi_ctrl->hpd_feature_on = true; + } + } + break; case MDSS_EVENT_CHECK_PARAMS: @@ -2487,7 +2524,7 @@ static int hdmi_tx_panel_event_handler(struct mdss_panel_data *panel_data, if (!timeout & !hdmi_ctrl->hpd_state) { DEV_INFO("%s: cable removed during suspend\n", __func__); - switch_set_state(&hdmi_ctrl->sdev, 0); + hdmi_tx_send_cable_notification(hdmi_ctrl, 0); rc = -EPERM; } else { DEV_DBG("%s: cable present after resume\n", @@ -3116,6 +3153,13 @@ static int hdmi_tx_get_dt_data(struct platform_device *pdev, } } + if (of_find_property(pdev->dev.of_node, "qcom,primary_panel", NULL)) { + u32 tmp; + of_property_read_u32(pdev->dev.of_node, "qcom,primary_panel", + &tmp); + pdata->primary = tmp ? true : false; + } + return rc; error: @@ -3175,7 +3219,7 @@ static int hdmi_tx_probe(struct platform_device *pdev) if (rc) { DEV_ERR("%s: Failed to add child devices. rc=%d\n", __func__, rc); - goto failed_init_features; + goto failed_reg_panel; } else { DEV_DBG("%s: Add child devices.\n", __func__); } @@ -3187,8 +3231,6 @@ static int hdmi_tx_probe(struct platform_device *pdev) return rc; -failed_init_features: - hdmi_tx_sysfs_remove(hdmi_ctrl); failed_reg_panel: hdmi_tx_dev_deinit(hdmi_ctrl); failed_dev_init: diff --git a/drivers/video/fbdev/msm/mdss_hdmi_tx.h b/drivers/video/fbdev/msm/mdss_hdmi_tx.h index 06ae42766593..8d9a477a979a 100644 --- a/drivers/video/fbdev/msm/mdss_hdmi_tx.h +++ b/drivers/video/fbdev/msm/mdss_hdmi_tx.h @@ -30,8 +30,9 @@ enum hdmi_tx_power_module_type { HDMI_TX_MAX_PM }; +/* Data filled from device tree */ struct hdmi_tx_platform_data { - /* Data filled from device tree nodes */ + bool primary; struct dss_io_data io[HDMI_TX_MAX_IO]; struct dss_module_power power_data[HDMI_TX_MAX_PM]; }; |
