diff options
author | Kevin Huang <kevinh@nvidia.com> | 2011-07-26 17:49:43 -0700 |
---|---|---|
committer | Ryan Wong <ryanw@nvidia.com> | 2011-07-28 17:44:23 -0700 |
commit | 617434cebb5f6b7b6b6b72dea3df22ae92a897eb (patch) | |
tree | 97cb2179ffbe8d7e696144ea28643bfdecc7e7a0 | |
parent | 0810893fefc4c80e721b88259b9c8db582aa0248 (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.c | 2 | ||||
-rw-r--r-- | arch/arm/mach-tegra/tegra3_clocks.c | 11 | ||||
-rw-r--r-- | drivers/video/tegra/dc/dc.c | 2 | ||||
-rw-r--r-- | drivers/video/tegra/dc/dsi.c | 31 |
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"); |