ARM: tegra: clock: Optimize power consumption of DSI module.
Kevin Huang [Wed, 27 Jul 2011 00:49:43 +0000 (17:49 -0700)]
- 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 <kevinh@nvidia.com>
Tested-by: Kevin Huang <kevinh@nvidia.com>
Reviewed-by: Jonathan Mayo <jmayo@nvidia.com>

Rebase-Id: Ra178934e0a17a698d353ddbe7bbf4c5631972189

drivers/video/tegra/dc/dc.c
drivers/video/tegra/dc/dsi.c

index cde7507..d7d0c7c 100644 (file)
@@ -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,
index 79d6208..4b43d87 100644 (file)
@@ -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");