Merge "msm: mdss: enable support for hdmi as primary"
diff --git a/drivers/video/msm/mdss/mdss_hdmi_tx.c b/drivers/video/msm/mdss/mdss_hdmi_tx.c
index cdb7048..e8a3795 100644
--- a/drivers/video/msm/mdss/mdss_hdmi_tx.c
+++ b/drivers/video/msm/mdss/mdss_hdmi_tx.c
@@ -449,6 +449,18 @@
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 @@
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_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 @@
/* If a power down is already underway, wait for it to finish */
flush_work_sync(&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 @@
} 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 @@
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 @@
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 @@
}
}
+ 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 @@
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 @@
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/msm/mdss/mdss_hdmi_tx.h b/drivers/video/msm/mdss/mdss_hdmi_tx.h
index 06ae427..8d9a477 100644
--- a/drivers/video/msm/mdss/mdss_hdmi_tx.h
+++ b/drivers/video/msm/mdss/mdss_hdmi_tx.h
@@ -30,8 +30,9 @@
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];
};