summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/msm/dba_bridge.c6
-rw-r--r--drivers/video/fbdev/msm/msm_dba/adv7533.c174
2 files changed, 100 insertions, 80 deletions
diff --git a/drivers/gpu/drm/msm/dba_bridge.c b/drivers/gpu/drm/msm/dba_bridge.c
index 49999ba468e5..9144dfdf30c9 100644
--- a/drivers/gpu/drm/msm/dba_bridge.c
+++ b/drivers/gpu/drm/msm/dba_bridge.c
@@ -123,10 +123,16 @@ error:
static void _dba_bridge_pre_enable(struct drm_bridge *bridge)
{
+ struct dba_bridge *d_bridge;
+
if (!bridge) {
SDE_ERROR("Invalid params\n");
return;
}
+
+ d_bridge = to_dba_bridge(bridge);
+ if (d_bridge->ops.power_on)
+ d_bridge->ops.power_on(d_bridge->dba_ctx, true, 0);
}
static void _dba_bridge_enable(struct drm_bridge *bridge)
diff --git a/drivers/video/fbdev/msm/msm_dba/adv7533.c b/drivers/video/fbdev/msm/msm_dba/adv7533.c
index 8802b58116fb..bb3a5518d309 100644
--- a/drivers/video/fbdev/msm/msm_dba/adv7533.c
+++ b/drivers/video/fbdev/msm/msm_dba/adv7533.c
@@ -129,6 +129,7 @@ struct adv7533 {
bool hdcp_enabled;
bool cec_enabled;
bool is_power_on;
+ bool is_vreg_on;
void *edid_data;
u8 edid_buf[EDID_SEG_SIZE];
u8 audio_spkr_data[AUDIO_DATA_SIZE];
@@ -1375,6 +1376,85 @@ static int adv7533_check_hpd(void *client, u32 flags)
return connected;
}
+static int adv7533_enable_vreg(struct adv7533 *pdata, int enable)
+{
+ int rc = 0;
+ struct dss_module_power *power_data = NULL;
+
+ if (!pdata) {
+ pr_err("invalid input\n");
+ rc = -EINVAL;
+ goto exit;
+ }
+
+ power_data = &pdata->power_data;
+ if (!power_data || !power_data->num_vreg) {
+ pr_warn("%s: Error: invalid power data\n", __func__);
+ return 0;
+ }
+
+ if (enable) {
+ rc = msm_dss_enable_vreg(power_data->vreg_config,
+ power_data->num_vreg, 1);
+ if (rc) {
+ pr_err("%s: Failed to enable vreg. Err=%d\n",
+ __func__, rc);
+ goto exit;
+ }
+ pdata->is_vreg_on = true;
+ } else {
+ rc = msm_dss_enable_vreg(power_data->vreg_config,
+ power_data->num_vreg, 0);
+ if (rc) {
+ pr_err("%s: Failed to disable vreg. Err=%d\n",
+ __func__, rc);
+ goto exit;
+ }
+ pdata->is_vreg_on = false;
+ }
+exit:
+ return rc;
+}
+
+static int adv7533_config_vreg(struct adv7533 *pdata, int enable)
+{
+ int rc = 0;
+ struct dss_module_power *power_data = NULL;
+
+ if (!pdata) {
+ pr_err("invalid input\n");
+ rc = -EINVAL;
+ goto exit;
+ }
+ power_data = &pdata->power_data;
+ if (!power_data || !power_data->num_vreg) {
+ pr_warn("%s: Error: invalid power data\n", __func__);
+ return 0;
+ }
+
+ if (enable) {
+ rc = msm_dss_config_vreg(&pdata->i2c_client->dev,
+ power_data->vreg_config,
+ power_data->num_vreg, 1);
+ if (rc) {
+ pr_err("%s: Failed to config vreg. Err=%d\n",
+ __func__, rc);
+ goto exit;
+ }
+ } else {
+ rc = msm_dss_config_vreg(&pdata->i2c_client->dev,
+ power_data->vreg_config,
+ power_data->num_vreg, 0);
+ if (rc) {
+ pr_err("%s: Failed to deconfig vreg. Err=%d\n",
+ __func__, rc);
+ goto exit;
+ }
+ }
+exit:
+ return rc;
+}
+
/* Device Operations */
static int adv7533_power_on(void *client, bool on, u32 flags)
{
@@ -1390,6 +1470,16 @@ static int adv7533_power_on(void *client, bool on, u32 flags)
mutex_lock(&pdata->ops_mutex);
if (on && !pdata->is_power_on) {
+ if (!pdata->is_vreg_on) {
+ ret = adv7533_config_vreg(pdata, 1);
+ if (!ret) {
+ adv7533_enable_vreg(pdata, 1);
+ } else {
+ pr_err("%s: Failed to config vreg\n", __func__);
+ goto end;
+ }
+ }
+
if (gpio_is_valid(pdata->switch_gpio)) {
gpio_set_value(pdata->switch_gpio,
pdata->switch_flags);
@@ -1419,6 +1509,10 @@ static int adv7533_power_on(void *client, bool on, u32 flags)
ret = 0;
adv7533_notify_clients(&pdata->dev_info,
MSM_DBA_CB_HPD_DISCONNECT);
+ if (pdata->is_vreg_on) {
+ adv7533_enable_vreg(pdata, 0);
+ adv7533_config_vreg(pdata, 0);
+ }
}
end:
mutex_unlock(&pdata->ops_mutex);
@@ -1491,86 +1585,6 @@ static void adv7533_video_setup(struct adv7533 *pdata,
adv7533_write(pdata, I2C_ADDR_CEC_DSI, 0x37, ((vbp & 0xF) << 4));
}
-static int adv7533_config_vreg(struct adv7533 *pdata, int enable)
-{
- int rc = 0;
- struct dss_module_power *power_data = NULL;
-
- if (!pdata) {
- pr_err("invalid input\n");
- rc = -EINVAL;
- goto exit;
- }
-
- power_data = &pdata->power_data;
- if (!power_data || !power_data->num_vreg) {
- pr_warn("%s: Error: invalid power data\n", __func__);
- return 0;
- }
-
- if (enable) {
- rc = msm_dss_config_vreg(&pdata->i2c_client->dev,
- power_data->vreg_config,
- power_data->num_vreg, 1);
- if (rc) {
- pr_err("%s: Failed to config vreg. Err=%d\n",
- __func__, rc);
- goto exit;
- }
- } else {
- rc = msm_dss_config_vreg(&pdata->i2c_client->dev,
- power_data->vreg_config,
- power_data->num_vreg, 0);
- if (rc) {
- pr_err("%s: Failed to deconfig vreg. Err=%d\n",
- __func__, rc);
- goto exit;
- }
- }
-exit:
- return rc;
-
-}
-
-static int adv7533_enable_vreg(struct adv7533 *pdata, int enable)
-{
- int rc = 0;
- struct dss_module_power *power_data = NULL;
-
- if (!pdata) {
- pr_err("invalid input\n");
- rc = -EINVAL;
- goto exit;
- }
-
- power_data = &pdata->power_data;
- if (!power_data || !power_data->num_vreg) {
- pr_warn("%s: Error: invalid power data\n", __func__);
- return 0;
- }
-
- if (enable) {
- rc = msm_dss_enable_vreg(power_data->vreg_config,
- power_data->num_vreg, 1);
- if (rc) {
- pr_err("%s: Failed to enable vreg. Err=%d\n",
- __func__, rc);
- goto exit;
- }
- } else {
- rc = msm_dss_enable_vreg(power_data->vreg_config,
- power_data->num_vreg, 0);
- if (rc) {
- pr_err("%s: Failed to disable vreg. Err=%d\n",
- __func__, rc);
- goto exit;
- }
- }
-exit:
- return rc;
-
-}
-
static int adv7533_video_on(void *client, bool on,
struct msm_dba_video_cfg *cfg, u32 flags)
{