summaryrefslogtreecommitdiff
path: root/drivers/video/tegra/dc/dsi.c
diff options
context:
space:
mode:
authorKevin Huang <kevinh@nvidia.com>2012-06-06 10:48:18 -0700
committerSimone Willett <swillett@nvidia.com>2012-06-11 17:31:24 -0700
commitb901b56e0c0573ce30393836e4078ca78beffca0 (patch)
tree6941d2d4cbd9719d26f2d3840735cca6c31bec4d /drivers/video/tegra/dc/dsi.c
parentb08927a712005ae3f6941e59f530b7896ac5f407 (diff)
video: tegra: dc: Clock-gate display modules dynamically.
Bug 936337 Bug 899053 Change-Id: I2b3d8cfc8a00881338c1e17d03f2844d15ba7d3e Signed-off-by: Kevin Huang <kevinh@nvidia.com> Reviewed-on: http://git-master/r/106313 Reviewed-by: Simone Willett <swillett@nvidia.com> Tested-by: Simone Willett <swillett@nvidia.com>
Diffstat (limited to 'drivers/video/tegra/dc/dsi.c')
-rw-r--r--drivers/video/tegra/dc/dsi.c53
1 files changed, 44 insertions, 9 deletions
diff --git a/drivers/video/tegra/dc/dsi.c b/drivers/video/tegra/dc/dsi.c
index 6624a8e8f52c..0ea3947176fe 100644
--- a/drivers/video/tegra/dc/dsi.c
+++ b/drivers/video/tegra/dc/dsi.c
@@ -416,6 +416,22 @@ static inline void tegra_dc_dsi_debug_create(struct tegra_dc_dsi_data *dsi)
{ }
#endif
+static inline void tegra_dsi_clk_enable(struct tegra_dc_dsi_data *dsi)
+{
+ if (!tegra_is_clk_enabled(dsi->dsi_clk)) {
+ clk_enable(dsi->dsi_clk);
+ clk_enable(dsi->dsi_fixed_clk);
+ }
+}
+
+static inline void tegra_dsi_clk_disable(struct tegra_dc_dsi_data *dsi)
+{
+ if (tegra_is_clk_enabled(dsi->dsi_clk)) {
+ clk_disable(dsi->dsi_clk);
+ clk_disable(dsi->dsi_fixed_clk);
+ }
+}
+
static int tegra_dsi_syncpt(struct tegra_dc_dsi_data *dsi)
{
u32 val;
@@ -1455,12 +1471,9 @@ static void tegra_dsi_set_dsi_clk(struct tegra_dc *dc,
/* Enable DSI clock */
tegra_dc_setup_clk(dc, dsi->dsi_clk);
- if (!dsi->clk_ref) {
- dsi->clk_ref = true;
- clk_enable(dsi->dsi_clk);
- clk_enable(dsi->dsi_fixed_clk);
- tegra_periph_reset_deassert(dsi->dsi_clk);
- }
+ tegra_dsi_clk_enable(dsi);
+ tegra_periph_reset_deassert(dsi->dsi_clk);
+
dsi->current_dsi_clk_khz = clk_get_rate(dsi->dsi_clk) / 1000;
dsi->current_bit_clk_ns = 1000*1000 / (dsi->current_dsi_clk_khz * 2);
}
@@ -2193,6 +2206,9 @@ int tegra_dsi_send_panel_short_cmd(struct tegra_dc *dc, u8 *pdata, u8 data_len)
int err = 0, count = 0;
struct tegra_dc_dsi_data *dsi = tegra_dc_get_outdata(dc);
+ if (dc->out->flags & TEGRA_DC_OUT_ONE_SHOT_LP_MODE)
+ tegra_dc_host_resume(dc);
+
data_len_orig = data_len;
if (pdata != NULL) {
while (data_len) {
@@ -2610,6 +2626,8 @@ static void tegra_dc_dsi_enable(struct tegra_dc *dc)
tegra_dc_io_start(dc);
mutex_lock(&dsi->lock);
+ if (dc->out->flags & TEGRA_DC_OUT_ONE_SHOT_LP_MODE)
+ tegra_dc_host_resume(dc);
/* Stop DC stream before configuring DSI registers
* to avoid visible glitches on panel during transition
* from bootloader to kernel driver
@@ -3072,10 +3090,8 @@ static int tegra_dsi_deep_sleep(struct tegra_dc *dc,
0);
/* Disable dsi source clock */
- clk_disable(dsi->dsi_clk);
- clk_disable(dsi->dsi_fixed_clk);
+ tegra_dsi_clk_disable(dsi);
- dsi->clk_ref = false;
dsi->enabled = false;
return 0;
@@ -3083,6 +3099,25 @@ fail:
return err;
}
+
+int tegra_dsi_host_suspend(struct tegra_dc *dc)
+{
+ struct tegra_dc_dsi_data *dsi = tegra_dc_get_outdata(dc);
+
+ tegra_dsi_stop_dc_stream(dc, dsi);
+
+ tegra_dsi_clk_disable(dsi);
+}
+
+void tegra_dsi_host_resume(struct tegra_dc *dc)
+{
+ struct tegra_dc_dsi_data *dsi = tegra_dc_get_outdata(dc);
+
+ tegra_dsi_clk_enable(dsi);
+
+ tegra_dsi_start_dc_stream(dc, dsi);
+}
+
static void tegra_dc_dsi_disable(struct tegra_dc *dc)
{
int err;