summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCamus Wong <camusw@codeaurora.org>2018-02-05 17:14:44 -0500
committerCamus Wong <camusw@codeaurora.org>2018-02-12 19:36:58 -0500
commitdef1bee62a0a653ae4a7824a17ddec1b182c98dd (patch)
tree7eccdaaa6d32f96aa3d4109c4400a6548f0c40f7
parenta15bce8f33bccaa3b83b40024620fd36533685c2 (diff)
DRM: DBA: Adding hardware power sequence to DBA power off code
Adding power off register sequence to reduce power in power off. Adding switch GPIO sequence in power on/off call. Change-Id: Ifbe57852a43e1b1d0f05594a84a10540cfeb6be7 Signed-off-by: Camus Wong <camusw@codeaurora.org>
-rw-r--r--drivers/gpu/drm/msm/dba_bridge.c14
-rw-r--r--drivers/video/fbdev/msm/msm_dba/adv7533.c93
2 files changed, 74 insertions, 33 deletions
diff --git a/drivers/gpu/drm/msm/dba_bridge.c b/drivers/gpu/drm/msm/dba_bridge.c
index f933a7f3dcfb..49999ba468e5 100644
--- a/drivers/gpu/drm/msm/dba_bridge.c
+++ b/drivers/gpu/drm/msm/dba_bridge.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -205,7 +205,8 @@ static void _dba_bridge_disable(struct drm_bridge *bridge)
}
if (d_bridge->ops.video_on) {
- rc = d_bridge->ops.video_on(d_bridge->dba_ctx, false, NULL, 0);
+ rc = d_bridge->ops.video_on(d_bridge->dba_ctx,
+ false, NULL, 0);
if (rc)
SDE_ERROR("video off failed ret=%d\n", rc);
}
@@ -213,10 +214,19 @@ static void _dba_bridge_disable(struct drm_bridge *bridge)
static void _dba_bridge_post_disable(struct drm_bridge *bridge)
{
+ int rc = 0;
+ struct dba_bridge *d_bridge = to_dba_bridge(bridge);
+
if (!bridge) {
SDE_ERROR("Invalid params\n");
return;
}
+
+ if (d_bridge->ops.power_on) {
+ rc = d_bridge->ops.power_on(d_bridge->dba_ctx, false, 0);
+ if (rc)
+ SDE_ERROR("power off failed ret=%d\n", rc);
+ }
}
static void _dba_bridge_mode_set(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 09632b49d33b..8802b58116fb 100644
--- a/drivers/video/fbdev/msm/msm_dba/adv7533.c
+++ b/drivers/video/fbdev/msm/msm_dba/adv7533.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -188,6 +188,17 @@ static struct adv7533_reg_cfg adv7533_video_en[] = {
{I2C_ADDR_MAIN, 0x40, 0x80, 0},
};
+static struct adv7533_reg_cfg adv7533_video_disable[] = {
+ /* Timing Generator Disable */
+ {I2C_ADDR_CEC_DSI, 0x27, 0x4B, 0},
+ /* SPDIF disable */
+ {I2C_ADDR_MAIN, 0x0B, 0x00, 0},
+ /* Gate CEC Clock */
+ {I2C_ADDR_CEC_DSI, 0x05, 0xF8, 0},
+ /* power down */
+ {I2C_ADDR_MAIN, 0x41, 0x50, 0},
+};
+
static struct adv7533_reg_cfg adv7533_cec_en[] = {
/* Fixed, clock gate disable */
{I2C_ADDR_CEC_DSI, 0x05, 0xC8, 0},
@@ -1379,6 +1390,12 @@ static int adv7533_power_on(void *client, bool on, u32 flags)
mutex_lock(&pdata->ops_mutex);
if (on && !pdata->is_power_on) {
+ if (gpio_is_valid(pdata->switch_gpio)) {
+ gpio_set_value(pdata->switch_gpio,
+ pdata->switch_flags);
+ msleep(ADV7533_RESET_DELAY);
+ }
+
adv7533_write_array(pdata, adv7533_init_setup,
sizeof(adv7533_init_setup));
@@ -1394,6 +1411,12 @@ static int adv7533_power_on(void *client, bool on, u32 flags)
adv7533_write(pdata, I2C_ADDR_MAIN, 0x41, 0x50);
pdata->is_power_on = false;
+ if (gpio_is_valid(pdata->switch_gpio)) {
+ gpio_set_value(pdata->switch_gpio,
+ !pdata->switch_flags);
+ msleep(ADV7533_RESET_DELAY);
+ }
+ ret = 0;
adv7533_notify_clients(&pdata->dev_info,
MSM_DBA_CB_HPD_DISCONNECT);
}
@@ -1556,49 +1579,57 @@ static int adv7533_video_on(void *client, bool on,
u8 reg_val = 0;
struct adv7533 *pdata = adv7533_get_platform_data(client);
- if (!pdata || !cfg) {
+ if (!pdata) {
pr_err("%s: invalid platform data\n", __func__);
return -EINVAL;
+ } else if (on && !cfg) {
+ pr_err("%s: invalid cfg data for power on\n", __func__);
+ return -EINVAL;
}
mutex_lock(&pdata->ops_mutex);
- /* DSI lane configuration */
- lanes = (cfg->num_of_input_lanes << 4);
- adv7533_write(pdata, I2C_ADDR_CEC_DSI, 0x1C, lanes);
+ if (on) {
+ /* DSI lane configuration */
+ lanes = (cfg->num_of_input_lanes << 4);
+ adv7533_write(pdata, I2C_ADDR_CEC_DSI, 0x1C, lanes);
- adv7533_video_setup(pdata, cfg);
+ adv7533_video_setup(pdata, cfg);
- /* hdmi/dvi mode */
- if (cfg->hdmi_mode)
- adv7533_write(pdata, I2C_ADDR_MAIN, 0xAF, 0x06);
- else
- adv7533_write(pdata, I2C_ADDR_MAIN, 0xAF, 0x04);
+ /* hdmi/dvi mode */
+ if (cfg->hdmi_mode)
+ adv7533_write(pdata, I2C_ADDR_MAIN, 0xAF, 0x06);
+ else
+ adv7533_write(pdata, I2C_ADDR_MAIN, 0xAF, 0x04);
- /* set scan info for AVI Infoframe*/
- if (cfg->scaninfo) {
- adv7533_read(pdata, I2C_ADDR_MAIN, 0x55, &reg_val, 1);
- reg_val |= cfg->scaninfo & (BIT(1) | BIT(0));
- adv7533_write(pdata, I2C_ADDR_MAIN, 0x55, reg_val);
- }
+ /* set scan info for AVI Infoframe*/
+ if (cfg->scaninfo) {
+ adv7533_read(pdata, I2C_ADDR_MAIN, 0x55, &reg_val, 1);
+ reg_val |= cfg->scaninfo & (BIT(1) | BIT(0));
+ adv7533_write(pdata, I2C_ADDR_MAIN, 0x55, reg_val);
+ }
- /*
- * aspect ratio and sync polarity set up.
- * Currently adv only supports 16:9 or 4:3 aspect ratio
- * configuration.
- */
- if (cfg->h_active * 3 - cfg->v_active * 4) {
- adv7533_write(pdata, I2C_ADDR_MAIN, 0x17, 0x02);
- adv7533_write(pdata, I2C_ADDR_MAIN, 0x56, 0x28);
+ /*
+ * aspect ratio and sync polarity set up.
+ * Currently adv only supports 16:9 or 4:3 aspect ratio
+ * configuration.
+ */
+ if (cfg->h_active * 3 - cfg->v_active * 4) {
+ adv7533_write(pdata, I2C_ADDR_MAIN, 0x17, 0x02);
+ adv7533_write(pdata, I2C_ADDR_MAIN, 0x56, 0x28);
+ } else {
+ /* 4:3 aspect ratio */
+ adv7533_write(pdata, I2C_ADDR_MAIN, 0x17, 0x00);
+ adv7533_write(pdata, I2C_ADDR_MAIN, 0x56, 0x18);
+ }
+
+ adv7533_write_array(pdata, adv7533_video_en,
+ sizeof(adv7533_video_en));
} else {
- /* 4:3 aspect ratio */
- adv7533_write(pdata, I2C_ADDR_MAIN, 0x17, 0x00);
- adv7533_write(pdata, I2C_ADDR_MAIN, 0x56, 0x18);
+ adv7533_write_array(pdata, adv7533_video_disable,
+ sizeof(adv7533_video_disable));
}
- adv7533_write_array(pdata, adv7533_video_en,
- sizeof(adv7533_video_en));
-
mutex_unlock(&pdata->ops_mutex);
return ret;
}