summaryrefslogtreecommitdiff
path: root/drivers/video/tegra/dc/dsi.c
diff options
context:
space:
mode:
authorAnimesh Kishore <ankishore@nvidia.com>2011-08-27 00:52:41 +0530
committerDan Willemsen <dwillemsen@nvidia.com>2011-11-30 21:48:46 -0800
commit2f684e948e8811117e8fe50421393c8ae0973414 (patch)
treed5e4b42e6a6a32859d1dfc83145d41b756af6c64 /drivers/video/tegra/dc/dsi.c
parenta8553a4075782a7e23ca4f923039e413f51d209a (diff)
video: tegra: dsi: deep sleep
Aggregate code for dsi deep sleep Bug 862427 Original-Change-Id: I5296e6659112642f9fe0fb84bec1d5938014c33a Reviewed-on: http://git-master/r/49506 Reviewed-by: Animesh Kishore <ankishore@nvidia.com> Tested-by: Animesh Kishore <ankishore@nvidia.com> Reviewed-by: Kevin Huang <kevinh@nvidia.com> Reviewed-by: Bitan Biswas <bbiswas@nvidia.com> Rebase-Id: Ref7c30c407efe88481af5f2d23e5892bb0d05ef3
Diffstat (limited to 'drivers/video/tegra/dc/dsi.c')
-rw-r--r--drivers/video/tegra/dc/dsi.c160
1 files changed, 79 insertions, 81 deletions
diff --git a/drivers/video/tegra/dc/dsi.c b/drivers/video/tegra/dc/dsi.c
index 2cca8cc65462..cbe46f9b4f89 100644
--- a/drivers/video/tegra/dc/dsi.c
+++ b/drivers/video/tegra/dc/dsi.c
@@ -2068,70 +2068,95 @@ static void tegra_dc_dsi_destroy(struct tegra_dc *dc)
kfree(dsi);
}
-static void tegra_dc_dsi_disable(struct tegra_dc *dc)
+static int tegra_dsi_deep_sleep(struct tegra_dc *dc,
+ struct tegra_dc_dsi_data *dsi)
{
- int err;
- u32 val;
- struct clk *base_clk;
- struct tegra_dc_dsi_data *dsi = tegra_dc_get_outdata(dc);
+ int err = 0;
+ int val;
+ struct clk *parent_clk = NULL;
+ struct clk *base_clk = NULL;
- tegra_dc_io_start(dc);
- mutex_lock(&dsi->lock);
+ if (!dsi->enabled) {
+ err = -EPERM;
+ goto fail;
+ }
- if (dsi->status.dc_stream == DSI_DC_STREAM_ENABLE)
- tegra_dsi_stop_dc_stream_at_frame_end(dc, dsi);
+ err = tegra_dsi_set_to_lp_mode(dc, dsi);
+ if (err < 0) {
+ dev_err(&dc->ndev->dev,
+ "DSI failed to go to LP mode\n");
+ goto fail;
+ }
- if (dsi->info.power_saving_suspend) {
- if (!dsi->enabled)
- goto fail;
+ /* Suspend panel */
+ err = tegra_dsi_send_panel_cmd(dc, dsi,
+ dsi->info.dsi_suspend_cmd,
+ dsi->info.n_suspend_cmd);
+ if (err < 0) {
+ dev_err(&dc->ndev->dev,
+ "dsi: Error sending suspend cmd\n");
+ goto fail;
+ }
- err = tegra_dsi_set_to_lp_mode(dc, dsi);
+ if (!dsi->ulpm) {
+ err = tegra_dsi_enter_ulpm(dsi);
if (err < 0) {
dev_err(&dc->ndev->dev,
- "DSI failed to go to LP mode\n");
+ "DSI failed to enter ulpm\n");
goto fail;
}
+ }
- err = tegra_dsi_send_panel_cmd(dc, dsi,
- dsi->info.dsi_suspend_cmd,
- dsi->info.n_suspend_cmd);
- if (err < 0) {
- dev_err(&dc->ndev->dev,
- "dsi: Error sending suspend cmd\n");
- goto fail;
- }
+ /* Suspend pad */
+ val = tegra_dsi_readl(dsi, DSI_PAD_CONTROL);
+ val = DSI_PAD_CONTROL_PAD_PDIO(0x3) |
+ DSI_PAD_CONTROL_PAD_PDIO_CLK(0x1) |
+ DSI_PAD_CONTROL_PAD_PULLDN_ENAB(TEGRA_DSI_ENABLE);
+ tegra_dsi_writel(dsi, val, DSI_PAD_CONTROL);
- if (!dsi->ulpm) {
- if (tegra_dsi_enter_ulpm(dsi) < 0)
- printk(KERN_ERR "DSI failed to enter ulpm\n");
- }
+ /* Suspend core-logic */
+ val = DSI_POWER_CONTROL_LEG_DSI_ENABLE(TEGRA_DSI_DISABLE);
+ tegra_dsi_writel(dsi, val, DSI_POWER_CONTROL);
- /* Suspend pad */
- val = tegra_dsi_readl(dsi, DSI_PAD_CONTROL);
- val = DSI_PAD_CONTROL_PAD_PDIO(0x3) |
- DSI_PAD_CONTROL_PAD_PDIO_CLK(0x1) |
- DSI_PAD_CONTROL_PAD_PULLDN_ENAB(TEGRA_DSI_ENABLE);
- tegra_dsi_writel(dsi, val, DSI_PAD_CONTROL);
+ /* Disable dsi fast and slow clock */
+ parent_clk = clk_get_parent(dsi->dsi_clk);
+ base_clk = clk_get_parent(parent_clk);
+ if (dsi->info.dsi_instance)
+ tegra_clk_cfg_ex(base_clk,
+ TEGRA_CLK_PLLD_CSI_OUT_ENB,
+ 0);
+ else
+ tegra_clk_cfg_ex(base_clk,
+ TEGRA_CLK_PLLD_DSI_OUT_ENB,
+ 0);
- /* Suspend core-logic */
- val = DSI_POWER_CONTROL_LEG_DSI_ENABLE(TEGRA_DSI_DISABLE);
- tegra_dsi_writel(dsi, val, DSI_POWER_CONTROL);
+ /* Disable dsi source clock */
+ clk_disable(dsi->dsi_clk);
- /* Disable phy clock */
- base_clk = clk_get_parent(dsi->dsi_clk);
- if (dsi->info.dsi_instance)
- tegra_clk_cfg_ex(base_clk,
- TEGRA_CLK_PLLD_CSI_OUT_ENB,
- 0);
- else
- tegra_clk_cfg_ex(base_clk,
- TEGRA_CLK_PLLD_DSI_OUT_ENB,
- 0);
+ dsi->clk_ref = false;
+ dsi->enabled = false;
- /* Disable DSI source clock */
- clk_disable(dsi->dsi_clk);
- dsi->clk_ref = false;
- dsi->enabled = false;
+ return 0;
+fail:
+ return err;
+}
+
+static void tegra_dc_dsi_disable(struct tegra_dc *dc)
+{
+ int err;
+ struct tegra_dc_dsi_data *dsi = tegra_dc_get_outdata(dc);
+
+ tegra_dc_io_start(dc);
+ mutex_lock(&dsi->lock);
+
+ if (dsi->status.dc_stream == DSI_DC_STREAM_ENABLE)
+ tegra_dsi_stop_dc_stream_at_frame_end(dc, dsi);
+
+ if (dsi->info.power_saving_suspend) {
+ if (tegra_dsi_deep_sleep(dc, dsi) < 0) {
+ printk(KERN_ERR "DSI failed to enter deep sleep\n");
+ goto fail;
+ }
} else {
if (dsi->info.dsi_early_suspend_cmd) {
err = tegra_dsi_send_panel_cmd(dc, dsi,
@@ -2145,8 +2170,10 @@ static void tegra_dc_dsi_disable(struct tegra_dc *dc)
}
if (!dsi->ulpm) {
- if (tegra_dsi_enter_ulpm(dsi) < 0)
+ if (tegra_dsi_enter_ulpm(dsi) < 0) {
printk(KERN_ERR "DSI failed to enter ulpm\n");
+ goto fail;
+ }
}
}
@@ -2159,8 +2186,6 @@ fail:
static void tegra_dc_dsi_suspend(struct tegra_dc *dc)
{
struct tegra_dc_dsi_data *dsi;
- int err;
- u32 val;
dsi = tegra_dc_get_outdata(dc);
@@ -2178,37 +2203,10 @@ static void tegra_dc_dsi_suspend(struct tegra_dc *dc)
}
}
- /* Suspend Panel */
- err = tegra_dsi_send_panel_cmd(dc, dsi,
- dsi->info.dsi_suspend_cmd,
- dsi->info.n_suspend_cmd);
- if (err < 0) {
- dev_err(&dc->ndev->dev,
- "dsi: Error sending suspend cmd\n");
+ if (tegra_dsi_deep_sleep(dc, dsi) < 0) {
+ printk(KERN_ERR "DSI failed to enter deep sleep\n");
goto fail;
}
- if (!dsi->ulpm) {
- if (tegra_dsi_enter_ulpm(dsi) < 0) {
- printk(KERN_ERR "DSI failed to enter ulpm\n");
- goto fail;
- }
- }
-
- /* Suspend pad */
- val = tegra_dsi_readl(dsi, DSI_PAD_CONTROL);
- val = DSI_PAD_CONTROL_PAD_PDIO(0x3) |
- DSI_PAD_CONTROL_PAD_PDIO_CLK(0x1) |
- DSI_PAD_CONTROL_PAD_PULLDN_ENAB(TEGRA_DSI_ENABLE);
- tegra_dsi_writel(dsi, val, DSI_PAD_CONTROL);
-
- /* Suspend core-logic */
- val = DSI_POWER_CONTROL_LEG_DSI_ENABLE(TEGRA_DSI_DISABLE);
- tegra_dsi_writel(dsi, val, DSI_POWER_CONTROL);
-
- dsi->enabled = false;
-
- clk_disable(dsi->dsi_clk);
- dsi->clk_ref = false;
}
fail:
mutex_unlock(&dsi->lock);