summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKevin Huang <kevinh@nvidia.com>2011-07-26 17:49:43 -0700
committerRyan Wong <ryanw@nvidia.com>2011-07-28 17:44:23 -0700
commit617434cebb5f6b7b6b6b72dea3df22ae92a897eb (patch)
tree97cb2179ffbe8d7e696144ea28643bfdecc7e7a0
parent0810893fefc4c80e721b88259b9c8db582aa0248 (diff)
ARM: tegra: clock: Optimize power consumption of DSI module DO NOT MERGE
- Disable phy clock at early suspend. - Set DSI to LP mode at early suspend Bug 847254 Bug 848069 Change-Id: Ia3199b1848075e7adfc3b8c686d93d4d5655aca5 Reviewed-on: http://git-master/r/43800 Reviewed-by: Chih-Lung Huang <lhuang@nvidia.com> Tested-by: Chih-Lung Huang <lhuang@nvidia.com> Reviewed-by: Ryan Wong <ryanw@nvidia.com>
-rw-r--r--arch/arm/mach-tegra/board-enterprise-panel.c2
-rw-r--r--arch/arm/mach-tegra/tegra3_clocks.c11
-rw-r--r--drivers/video/tegra/dc/dc.c2
-rw-r--r--drivers/video/tegra/dc/dsi.c31
4 files changed, 33 insertions, 13 deletions
diff --git a/arch/arm/mach-tegra/board-enterprise-panel.c b/arch/arm/mach-tegra/board-enterprise-panel.c
index dd2c1e296993..bdba10c33d0b 100644
--- a/arch/arm/mach-tegra/board-enterprise-panel.c
+++ b/arch/arm/mach-tegra/board-enterprise-panel.c
@@ -459,7 +459,7 @@ struct tegra_dsi_out enterprise_dsi = {
.n_suspend_cmd = ARRAY_SIZE(dsi_suspend_cmd),
.dsi_suspend_cmd = dsi_suspend_cmd,
.video_data_type = TEGRA_DSI_VIDEO_TYPE_COMMAND_MODE,
- .lp_cmd_mode_freq_khz = 430000,
+ .lp_cmd_mode_freq_khz = 20000,
};
static struct tegra_stereo_out enterprise_stereo = {
diff --git a/arch/arm/mach-tegra/tegra3_clocks.c b/arch/arm/mach-tegra/tegra3_clocks.c
index 00469a555fb9..05cbaa4148de 100644
--- a/arch/arm/mach-tegra/tegra3_clocks.c
+++ b/arch/arm/mach-tegra/tegra3_clocks.c
@@ -1348,12 +1348,6 @@ static int tegra3_pll_clk_enable(struct clk *c)
val |= PLL_BASE_ENABLE;
clk_writel(val, c->reg + PLL_BASE);
- if (c->flags & PLLD) {
- val = clk_readl(c->reg + PLL_MISC(c) + PLL_BASE);
- val |= PLLD_MISC_CLKENABLE;
- clk_writel(val, c->reg + PLL_MISC(c) + PLL_BASE);
- }
-
if (c->flags & PLLM) {
val = pmc_readl(PMC_PLLP_WB0_OVERRIDE_0);
val |= PMC_PLLP_WB0_OVERRIDE_0_PLLM_ENABLE;
@@ -1374,11 +1368,6 @@ static void tegra3_pll_clk_disable(struct clk *c)
val &= ~(PLL_BASE_BYPASS | PLL_BASE_ENABLE);
clk_writel(val, c->reg);
- if (c->flags & PLLD) {
- val = clk_readl(c->reg + PLL_MISC(c) + PLL_BASE);
- val &= ~PLLD_MISC_CLKENABLE;
- clk_writel(val, c->reg + PLL_MISC(c) + PLL_BASE);
- }
if (c->flags & PLLM) {
val = pmc_readl(PMC_PLLP_WB0_OVERRIDE_0);
val &= ~PMC_PLLP_WB0_OVERRIDE_0_PLLM_ENABLE;
diff --git a/drivers/video/tegra/dc/dc.c b/drivers/video/tegra/dc/dc.c
index 132ec05022ed..973be578297b 100644
--- a/drivers/video/tegra/dc/dc.c
+++ b/drivers/video/tegra/dc/dc.c
@@ -1108,6 +1108,8 @@ void tegra_dc_setup_clk(struct tegra_dc *dc, struct clk *clk)
parent_clk = clk_get_sys(NULL,
dc->out->parent_clk ? : "pll_d_out0");
base_clk = clk_get_parent(parent_clk);
+ tegra_clk_cfg_ex(base_clk,
+ TEGRA_CLK_PLLD_DSI_OUT_ENB, 1);
} else {
if (dc->pdata->default_out->dsi->dsi_instance) {
parent_clk = clk_get_sys(NULL,
diff --git a/drivers/video/tegra/dc/dsi.c b/drivers/video/tegra/dc/dsi.c
index 85473db12429..dedbd7d55f81 100644
--- a/drivers/video/tegra/dc/dsi.c
+++ b/drivers/video/tegra/dc/dsi.c
@@ -935,6 +935,13 @@ static void tegra_dsi_set_dsi_clk(struct tegra_dc *dc,
static void tegra_dsi_hs_clk_out_enable(struct tegra_dc_dsi_data *dsi)
{
u32 val;
+ struct clk *base_clk;
+
+ /* Enable PHY clock */
+ base_clk = clk_get_parent(dsi->dsi_clk);
+ tegra_clk_cfg_ex(base_clk, TEGRA_CLK_PLLD_DSI_OUT_ENB, 1);
+ if (dsi->info.dsi_instance)
+ tegra_clk_cfg_ex(base_clk, TEGRA_CLK_PLLD_CSI_OUT_ENB, 1);
val = tegra_dsi_readl(dsi, DSI_CONTROL);
val &= ~DSI_CONTROL_HS_CLK_CTRL(1);
@@ -971,6 +978,7 @@ static void tegra_dsi_hs_clk_out_disable(struct tegra_dc *dc,
struct tegra_dc_dsi_data *dsi)
{
u32 val;
+ struct clk *base_clk;
if (dsi->status.dc_stream == DSI_DC_STREAM_ENABLE)
tegra_dsi_stop_dc_stream(dc, dsi);
@@ -987,6 +995,12 @@ static void tegra_dsi_hs_clk_out_disable(struct tegra_dc *dc,
val |= DSI_HOST_DSI_CONTROL_HIGH_SPEED_TRANS(TEGRA_DSI_LOW);
tegra_dsi_writel(dsi, val, DSI_HOST_DSI_CONTROL);
+ /* Disable PHY clock */
+ base_clk = clk_get_parent(dsi->dsi_clk);
+ tegra_clk_cfg_ex(base_clk, TEGRA_CLK_PLLD_DSI_OUT_ENB, 0);
+ if (dsi->info.dsi_instance)
+ tegra_clk_cfg_ex(base_clk, TEGRA_CLK_PLLD_CSI_OUT_ENB, 0);
+
dsi->status.clk_mode = DSI_PHYCLK_NOT_INIT;
dsi->status.clk_out = DSI_PHYCLK_OUT_DIS;
}
@@ -1690,6 +1704,7 @@ static void tegra_dc_dsi_enable(struct tegra_dc *dc)
goto fail;
}
}
+
if (dsi->info.panel_reset) {
err = tegra_dsi_send_panel_cmd(dc, dsi,
dsi->info.dsi_init_cmd,
@@ -1709,6 +1724,13 @@ static void tegra_dc_dsi_enable(struct tegra_dc *dc)
goto fail;
}
}
+
+ err = tegra_dsi_set_to_hs_mode(dc, dsi);
+ if (err < 0) {
+ dev_err(&dc->ndev->dev,
+ "dsi: not able to set to hs mode\n");
+ goto fail;
+ }
} else {
err = tegra_dsi_init_hw(dc, dsi);
if (err < 0) {
@@ -2047,8 +2069,8 @@ static void tegra_dc_dsi_destroy(struct tegra_dc *dc)
static void tegra_dc_dsi_disable(struct tegra_dc *dc)
{
- struct tegra_dc_dsi_data *dsi = tegra_dc_get_outdata(dc);
int err;
+ struct tegra_dc_dsi_data *dsi = tegra_dc_get_outdata(dc);
tegra_dc_io_start(dc);
mutex_lock(&dsi->lock);
@@ -2067,6 +2089,13 @@ static void tegra_dc_dsi_disable(struct tegra_dc *dc)
}
}
+ err = tegra_dsi_set_to_lp_mode(dc, dsi);
+ if (err < 0) {
+ dev_err(&dc->ndev->dev,
+ "dsi: not able to set to lp mode\n");
+ goto fail;
+ }
+
if (!dsi->ulpm) {
if (tegra_dsi_enter_ulpm(dsi) < 0)
printk(KERN_ERR "DSI failed to enter ulpm\n");