summaryrefslogtreecommitdiff
path: root/drivers/video/tegra/dc/dsi.c
diff options
context:
space:
mode:
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;