video: tegra: dsi: Fix dsi resume
Animesh Kishore [Mon, 5 Aug 2013 10:44:29 +0000 (15:44 +0530)]
- Support lp-00/lp-11 before panel wakeup.
- Platform flag to enable/disable ulpm.

Bug 1341152

Change-Id: Icff3fe7caf52585374a4a9002f87700be5dfe330
Signed-off-by: Animesh Kishore <ankishore@nvidia.com>
Signed-off-by: Vineel Kumar Reddy Kovvuri <vineelkumarr@nvidia.com>
Reviewed-on: http://git-master/r/258165
(cherry picked from commit abbe8deae875b6c2ea59a2bdf639ef37507bae54)
Reviewed-on: http://git-master/r/265482
Reviewed-by: Automatic_Commit_Validation_User
Reviewed-by: Bitan Biswas <bbiswas@nvidia.com>
GVS: Gerrit_Virtual_Submit

arch/arm/mach-tegra/include/mach/dc.h
drivers/video/tegra/dc/dc.c
drivers/video/tegra/dc/dc_priv_defs.h
drivers/video/tegra/dc/dsi.c

index f274d24..3c498b1 100644 (file)
@@ -240,6 +240,8 @@ struct tegra_dsi_out {
        u8              controller_vs;
 
        bool            panel_has_frame_buffer; /* required*/
+
+       /* Deprecated. Use DSI_SEND_FRAME panel command instead. */
        bool            panel_send_dc_frames;
 
        struct tegra_dsi_cmd    *dsi_init_cmd;          /* required */
@@ -287,6 +289,9 @@ struct tegra_dsi_out {
        struct dsi_phy_timing_ns phy_timing;
 
        u8              *bl_name;
+
+       bool            lp00_pre_panel_wakeup;
+       bool            ulpm_not_supported;
 };
 
 enum {
@@ -504,7 +509,7 @@ struct tegra_dc_out {
        struct completion       user_vblank_comp;
 
        int     (*enable)(struct device *);
-       int     (*postpoweron)(void);
+       int     (*postpoweron)(struct device *);
        int     (*prepoweroff)(void);
        int     (*disable)(void);
 
index 87dfe7d..2831329 100644 (file)
@@ -1874,7 +1874,10 @@ static bool _tegra_dc_controller_enable(struct tegra_dc *dc)
        tegra_dc_writel(dc, GENERAL_ACT_REQ, DC_CMD_STATE_CONTROL);
 
        if (dc->out->postpoweron)
-               dc->out->postpoweron();
+               dc->out->postpoweron(&dc->ndev->dev);
+
+       if (dc->out_ops && dc->out_ops->postpoweron)
+               dc->out_ops->postpoweron(dc);
 
        tegra_log_resume_time();
 
index dadadb3..f078152 100644 (file)
@@ -69,6 +69,8 @@ struct tegra_dc_out_ops {
        bool (*detect)(struct tegra_dc *dc);
        /* enable output.  dc clocks are on at this point */
        void (*enable)(struct tegra_dc *dc);
+       /* enable dc client.  Panel is enable at this point */
+       void (*postpoweron)(struct tegra_dc *dc);
        /* disable output.  dc clocks are on at this point */
        void (*disable)(struct tegra_dc *dc);
        /* dc client is disabled.  dc clocks are on at this point */
index 6930ce8..191b30c 100644 (file)
@@ -2115,8 +2115,8 @@ static void tegra_dsi_pad_enable(struct tegra_dc_dsi_data *dsi)
        }
 }
 
-static void __maybe_unused tegra_dsi_mipi_calibration_status
-(struct tegra_dc_dsi_data *dsi)
+static void __maybe_unused
+tegra_dsi_mipi_calibration_status(struct tegra_dc_dsi_data *dsi)
 {
        u32 val = 0;
        u32 timeout = 0;
@@ -3389,8 +3389,13 @@ static int tegra_dsi_enter_ulpm(struct tegra_dc_dsi_data *dsi)
        u32 val;
        int ret = 0;
 
+       if (dsi->info.ulpm_not_supported)
+               return 0;
+
+#if DSI_USE_SYNC_POINTS
        if (atomic_read(&dsi_syncpt_rst))
                tegra_dsi_syncpt_reset(dsi);
+#endif
 
        val = tegra_dsi_readl(dsi, DSI_HOST_DSI_CONTROL);
        val &= ~DSI_HOST_DSI_CONTROL_ULTRA_LOW_POWER(3);
@@ -3628,8 +3633,40 @@ static void tegra_dc_dsi_enable(struct tegra_dc *dc)
                        goto fail;
                }
 
+               if (dsi->info.lp00_pre_panel_wakeup)
+                       tegra_dsi_pad_disable(dsi);
+
+               dsi->enabled = true;
+       }
+
+       if (dsi->out_ops && dsi->out_ops->enable)
+               dsi->out_ops->enable(dsi);
+fail:
+       tegra_dc_io_end(dc);
+       mutex_unlock(&dsi->lock);
+}
+
+static void tegra_dc_dsi_postpoweron(struct tegra_dc *dc)
+{
+       struct tegra_dc_dsi_data *dsi = tegra_dc_get_outdata(dc);
+       int err = 0;
+
+       /*
+        * Do not configure. Use bootloader configuration.
+        * This avoids periods of blanking during boot.
+        */
+       if (dc->out->flags & TEGRA_DC_OUT_INITIALIZED_MODE)
+               return;
+
+       mutex_lock(&dsi->lock);
+       tegra_dc_io_start(dc);
+
+       if (dsi->enabled) {
+               if (dsi->info.lp00_pre_panel_wakeup)
+                       tegra_dsi_pad_enable(dsi);
+
                err = tegra_dsi_send_panel_cmd(dc, dsi, dsi->info.dsi_init_cmd,
-                                               dsi->info.n_init_cmd);
+                                                       dsi->info.n_init_cmd);
                if (err < 0) {
                        dev_err(&dc->ndev->dev,
                                "dsi: error while sending dsi init cmd\n");
@@ -3644,17 +3681,12 @@ static void tegra_dc_dsi_enable(struct tegra_dc *dc)
                        goto fail;
                }
 
-               dsi->enabled = true;
-       }
-
-       if (dsi->out_ops && dsi->out_ops->enable)
-               dsi->out_ops->enable(dsi);
-
-       if (dsi->status.driven == DSI_DRIVEN_MODE_DC)
-               tegra_dsi_start_dc_stream(dc, dsi);
+               if (dsi->status.driven == DSI_DRIVEN_MODE_DC)
+                       tegra_dsi_start_dc_stream(dc, dsi);
 
-       dsi->host_suspended = false;
-       atomic_set(&display_ready, 1);
+               dsi->host_suspended = false;
+               atomic_set(&display_ready, 1);
+       }
 fail:
        tegra_dc_io_end(dc);
        mutex_unlock(&dsi->lock);
@@ -4454,6 +4486,7 @@ struct tegra_dc_out_ops tegra_dc_dsi_ops = {
        .init = tegra_dc_dsi_init,
        .destroy = tegra_dc_dsi_destroy,
        .enable = tegra_dc_dsi_enable,
+       .postpoweron = tegra_dc_dsi_postpoweron,
        .disable = tegra_dc_dsi_disable,
        .postpoweroff = tegra_dc_dsi_postpoweroff,
        .hold = tegra_dc_dsi_hold_host,