From a4f8cf546a9e760712a6deee584dea672b71a72f Mon Sep 17 00:00:00 2001 From: Kevin Huang Date: Tue, 26 Jul 2011 17:49:43 -0700 Subject: ARM: tegra: clock: Optimize power consumption of DSI module. - Disable phy clock at early suspend. - Set DSI to LP mode at early suspend Bug 847254 Bug 848069 Original-Change-Id: Ia53fa3be5280172bc5aede12cef3ca06e07ea7f5 Reviewed-on: http://git-master/r/39245 Reviewed-by: Kevin Huang Tested-by: Kevin Huang Reviewed-by: Jonathan Mayo Rebase-Id: Ra8be9383813904f9514cfca59455e40f5aa32346 --- drivers/video/tegra/dc/dc.c | 2 ++ drivers/video/tegra/dc/dsi.c | 31 ++++++++++++++++++++++++++++++- 2 files changed, 32 insertions(+), 1 deletion(-) (limited to 'drivers/video/tegra') diff --git a/drivers/video/tegra/dc/dc.c b/drivers/video/tegra/dc/dc.c index 3344246ed50a..50988a643615 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 f395c60af46d..970e7ce91bb2 100644 --- a/drivers/video/tegra/dc/dsi.c +++ b/drivers/video/tegra/dc/dsi.c @@ -933,6 +933,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); @@ -969,6 +976,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); @@ -985,6 +993,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; } @@ -1688,6 +1702,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, @@ -1707,6 +1722,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) { @@ -2045,8 +2067,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); @@ -2065,6 +2087,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"); -- cgit v1.2.3