GFX-display: improve panel on/off path
authorKe Ai <ke.ai@intel.com>
Wed, 16 May 2012 03:26:12 +0000 (11:26 +0800)
committerbuildbot <buildbot@intel.com>
Mon, 21 May 2012 07:47:45 +0000 (00:47 -0700)
BZ: 24684

1. add recovery mechanism when dsi
controller abnormal, such as FIFO not empty.

2. avoid duplicate setting for DPI controll
let SHUT_DOWN and TURN_ON symmetrical.

3. move mipi port disable before panel power off.
which symmetrical with power on case

Change-Id: I2a6c5f0b0984fadeb96988589b6d0eb9a398be37
Signed-off-by: Ke Ai <ke.ai@intel.com>
Reviewed-on: http://android.intel.com:8080/48900
Reviewed-by: Pan, Zhenjie <zhenjie.pan@intel.com>
Reviewed-by: Xu, Randy <randy.xu@intel.com>
Reviewed-by: Geng, Xiujun <xiujun.geng@intel.com>
Tested-by: Tong, BoX <box.tong@intel.com>
Reviewed-by: buildbot <buildbot@intel.com>
Tested-by: buildbot <buildbot@intel.com>
drivers/staging/mrst/drv/mdfld_dsi_dpi.c
drivers/staging/mrst/drv/mdfld_dsi_pkg_sender.c
drivers/staging/mrst/drv/mdfld_dsi_pkg_sender.h
drivers/staging/mrst/drv/mdfld_output.h
drivers/staging/mrst/drv/tmd_6x10_vid.c

index 128d138..e68db08 100644 (file)
@@ -1510,7 +1510,7 @@ static int __dpi_panel_power_on(struct mdfld_dsi_config *dsi_config,
        struct mdfld_dsi_hw_context *ctx;
        struct drm_psb_private *dev_priv;
        struct drm_device *dev;
-       int retry;
+       int retry, reset_count = 10;
        int i;
        int err = 0;
 
@@ -1525,7 +1525,8 @@ static int __dpi_panel_power_on(struct mdfld_dsi_config *dsi_config,
        if (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND,
                                        OSPM_UHB_FORCE_POWER_ON))
                return -EAGAIN;
-
+reset_recovery:
+       --reset_count;
        /*HW-Reset*/
        if (p_funcs && p_funcs->reset)
                p_funcs->reset(dsi_config, RESET_FROM_OSPM_RESUME);
@@ -1649,15 +1650,26 @@ static int __dpi_panel_power_on(struct mdfld_dsi_config *dsi_config,
        /*set low power output hold*/
        REG_WRITE(regs->mipi_reg, (ctx->mipi | BIT16));
 
-/* FIXME JLIU7 */
-#if 1
        /**
         * Different panel may have different ways to have
         * drvIC initialized. Support it!
         */
-       if (p_funcs && p_funcs->drv_ic_init)
-               p_funcs->drv_ic_init(dsi_config, 0);
-#endif
+       if (p_funcs && p_funcs->drv_ic_init) {
+               if (p_funcs->drv_ic_init(dsi_config, 0)) {
+                       if (!reset_count) {
+                               err = -EAGAIN;
+                               goto power_on_err;
+                       }
+                       pmu_nc_set_power_state(OSPM_MIPI_ISLAND,
+                                       OSPM_ISLAND_DOWN, OSPM_REG_TYPE);
+
+                       pmu_nc_set_power_state(OSPM_MIPI_ISLAND,
+                                       OSPM_ISLAND_UP, OSPM_REG_TYPE);
+
+                       DRM_ERROR("Failed to init dsi controller, reset it!\n");
+                       goto reset_recovery;
+               }
+       }
 
        /**
         * Different panel may have different ways to have
@@ -1687,17 +1699,19 @@ static int __dpi_panel_power_on(struct mdfld_dsi_config *dsi_config,
        REG_WRITE(regs->pipestat_reg, ctx->pipestat |
                        PIPE_VBLANK_INTERRUPT_ENABLE);
 
-       /*Wait for pipe enabling*/
-       retry = 10000;
-       while (--retry && !(REG_READ(regs->pipeconf_reg) & BIT30))
-               udelay(3);
+       /*Wait for pipe enabling,when timing generator
+       is wroking */
+       if (REG_READ(regs->mipi_reg) & BIT31) {
+               retry = 10000;
+               while (--retry && !(REG_READ(regs->pipeconf_reg) & BIT30))
+                       udelay(3);
 
-       if (!retry) {
-               DRM_ERROR("Failed to enable pipe\n");
-               err = -EAGAIN;
-               goto power_on_err;
+               if (!retry) {
+                       DRM_ERROR("Failed to enable pipe\n");
+                       err = -EAGAIN;
+                       goto power_on_err;
+               }
        }
-
        /*enable plane*/
        val = ctx->dspcntr | BIT31;
 
@@ -1733,7 +1747,6 @@ static int __dpi_panel_power_off(struct mdfld_dsi_config *dsi_config,
        int pipe0_enabled;
        int pipe2_enabled;
        int err = 0;
-
        if (!dsi_config)
                return -EINVAL;
 
@@ -1780,16 +1793,22 @@ static int __dpi_panel_power_off(struct mdfld_dsi_config *dsi_config,
        ctx->pipeconf = val;
        REG_WRITE(regs->pipeconf_reg, (val & ~BIT31));
 
-       /*wait for pipe disabling*/
-       retry = 100000;
-       while (--retry && (REG_READ(regs->pipeconf_reg) & BIT30))
-               udelay(5);
+       /*wait for pipe disabling,
+       pipe synchronization plus , only avaiable when
+       timer generator is working*/
+       if (REG_READ(regs->mipi_reg) & BIT31) {
+               retry = 100000;
+               while (--retry && (REG_READ(regs->pipeconf_reg) & BIT30))
+                       udelay(5);
 
-       if (!retry) {
-               DRM_ERROR("Failed to disable pipe\n");
-               err = -EAGAIN;
-               goto power_off_err;
+               if (!retry) {
+                       DRM_ERROR("Failed to disable pipe\n");
+                       err = -EAGAIN;
+                       goto power_off_err;
+               }
        }
+       /*Disable MIPI port*/
+       REG_WRITE(regs->mipi_reg, (REG_READ(regs->mipi_reg) & ~BIT31));
 
        /**
         * Different panel may have different ways to have
@@ -1803,9 +1822,6 @@ static int __dpi_panel_power_off(struct mdfld_dsi_config *dsi_config,
                }
        }
 
-       /*Disable MIPI port*/
-       REG_WRITE(regs->mipi_reg, (REG_READ(regs->mipi_reg) & ~BIT31));
-
        /*clear Low power output hold*/
        REG_WRITE(regs->mipi_reg, (REG_READ(regs->mipi_reg) & ~BIT16));
 
index b5eea9e..8adffbb 100644 (file)
@@ -85,6 +85,7 @@ static inline int wait_for_gen_fifo_empty(struct mdfld_dsi_pkg_sender * sender,
        }
 
        DRM_ERROR("fifo is NOT empty 0x%08x\n", REG_READ(gen_fifo_stat_reg));
+       sender->status = MDFLD_DSI_CONTROL_ABNORMAL;
        return -EIO;
 }
 
@@ -485,6 +486,7 @@ static int send_dpi_spk_pkg(struct mdfld_dsi_pkg_sender *sender,
        u32 dpi_control_reg = sender->mipi_dpi_control_reg;
        u32 intr_stat_reg = sender->mipi_intr_stat_reg;
        u32 dpi_control_val = 0;
+       u32 dpi_control_current_setting = 0;
        struct mdfld_dsi_dpi_spk_pkg *spk_pkg = &pkg->pkg.spk_pkg;
        int retry = 10000;
 
@@ -498,19 +500,26 @@ static int send_dpi_spk_pkg(struct mdfld_dsi_pkg_sender *sender,
 
        /*clean spk packet sent interrupt*/
        REG_WRITE(intr_stat_reg, BIT30);
+       dpi_control_current_setting =
+               REG_READ(dpi_control_reg);
 
        /*send out spk packet*/
-       REG_WRITE(dpi_control_reg, dpi_control_val);
+       if (dpi_control_current_setting != dpi_control_val) {
+               REG_WRITE(dpi_control_reg, dpi_control_val);
 
-       /*wait for spk packet sent interrupt*/
-       while (--retry && !(REG_READ(intr_stat_reg) & BIT30))
-               udelay(3);
-
-       if (!retry) {
-               DRM_ERROR("Fail to send SPK Packet 0x%x\n", spk_pkg->cmd);
-               return -EINVAL;
-       }
+               /*wait for spk packet sent interrupt*/
+               while (--retry && !(REG_READ(intr_stat_reg) & BIT30))
+                       udelay(3);
 
+               if (!retry) {
+                       DRM_ERROR("Fail to send SPK Packet 0x%x\n",
+                                spk_pkg->cmd);
+                       return -EINVAL;
+               }
+       } else
+               /*For SHUT_DOWN and TURN_ON, it is better called by
+               symmetrical. so skip duplicate called*/
+               printk(KERN_WARNING "skip duplicate setting of DPI control\n");
        return 0;
 }
 
@@ -575,7 +584,8 @@ static int send_pkg_done(struct mdfld_dsi_pkg_sender * sender,
        else if (unlikely(cmd == exit_sleep_mode))
                sender->panel_mode &= ~MDFLD_DSI_PANEL_MODE_SLEEP;
 
-       sender->status = MDFLD_DSI_PKG_SENDER_FREE;
+       if (sender->status != MDFLD_DSI_CONTROL_ABNORMAL)
+               sender->status = MDFLD_DSI_PKG_SENDER_FREE;
 
        /*after sending pkg done, free the data buffer for mcs long pkg*/
        if (pkg->pkg_type == MDFLD_DSI_PKG_MCS_LONG_WRITE ||
index 264a30c..316314f 100644 (file)
@@ -68,8 +68,9 @@ enum {
 };
 
 enum {
-       MDFLD_DSI_PKG_SENDER_FREE = 0x0,
-       MDFLD_DSI_PKG_SENDER_BUSY = 0x1,
+       MDFLD_DSI_PKG_SENDER_FREE  = 0x0,
+       MDFLD_DSI_PKG_SENDER_BUSY  = 0x1,
+       MDFLD_DSI_CONTROL_ABNORMAL = 0x2,
 };
 
 enum {
index e4a7013..25b59b9 100644 (file)
@@ -98,7 +98,7 @@ struct panel_funcs {
        void (*update_fb)(struct mdfld_dsi_dbi_output*, int);
        int (*get_panel_info)(struct drm_device *, int, struct panel_info *);
        int (*reset)(struct mdfld_dsi_config *dsi_config, int reset_from);
-       void (*drv_ic_init)(struct mdfld_dsi_config *dsi_config, int pipe);
+       int (*drv_ic_init)(struct mdfld_dsi_config *dsi_config, int pipe);
        int (*detect)(struct mdfld_dsi_config *dsi_config, int pipe);
        void (*dsi_controller_init)(struct mdfld_dsi_config *dsi_config,
                                int pipe, int update);
index 96a1ba8..13e02d2 100755 (executable)
@@ -81,7 +81,7 @@ static u32 pr2_backlight_control_1[] = {0x0f0f01b8, 0xc8c8ffff, 0x18180f0f,
                                        0x02009090, 0x5A371D0c, 0x00FFBE87};
 static u32 pr2_backlight_control_2[] = {0x00cc01b9, 0x00000018};
 
-void mdfld_dsi_pr2_ic_init(struct mdfld_dsi_config *dsi_config, int pipe)
+int mdfld_dsi_pr2_ic_init(struct mdfld_dsi_config *dsi_config, int pipe)
 {
        struct mdfld_dsi_pkg_sender *sender
                        = mdfld_dsi_get_pkg_sender(dsi_config);
@@ -89,10 +89,11 @@ void mdfld_dsi_pr2_ic_init(struct mdfld_dsi_config *dsi_config, int pipe)
 
        if (!sender) {
                DRM_ERROR("Cannot get sender\n");
-               return;
+               return -EINVAL;
        }
 
        printk(KERN_ALERT "[DISPLAY TRK] Enter %s\n", __func__);
+       sender->status = MDFLD_DSI_PKG_SENDER_FREE;
 
        /*wait for 5ms*/
        wait_timeout = jiffies + (HZ / 200);
@@ -100,35 +101,118 @@ void mdfld_dsi_pr2_ic_init(struct mdfld_dsi_config *dsi_config, int pipe)
                cpu_relax();
 
        mdfld_dsi_send_gen_long_lp(sender, pr2_mcs_protect_off, 4, 0);
+       if (sender->status == MDFLD_DSI_CONTROL_ABNORMAL)
+               return -EIO;
+
        mdfld_dsi_send_gen_long_lp(sender, pr2_pixel_format, 4, 0);
+       if (sender->status == MDFLD_DSI_CONTROL_ABNORMAL)
+               return -EIO;
+
        mdfld_dsi_send_gen_long_lp(sender, pr2_dsi_control, 4, 0);
+       if (sender->status == MDFLD_DSI_CONTROL_ABNORMAL)
+               return -EIO;
+
        mdfld_dsi_send_gen_long_lp(sender, pr2_panel_driving, 8, 0);
+       if (sender->status == MDFLD_DSI_CONTROL_ABNORMAL)
+               return -EIO;
+
        mdfld_dsi_send_gen_long_lp(sender, pr2_v_timing, 8, 0);
+       if (sender->status == MDFLD_DSI_CONTROL_ABNORMAL)
+               return -EIO;
+
        mdfld_dsi_send_gen_long_lp(sender, pr2_control, 4, 0);
+       if (sender->status == MDFLD_DSI_CONTROL_ABNORMAL)
+               return -EIO;
+
        mdfld_dsi_send_gen_long_lp(sender, pr2_test_mode_0, 4, 0);
+       if (sender->status == MDFLD_DSI_CONTROL_ABNORMAL)
+               return -EIO;
+
        mdfld_dsi_send_gen_long_lp(sender, pr2_h_timing, 16, 0);
+       if (sender->status == MDFLD_DSI_CONTROL_ABNORMAL)
+               return -EIO;
+
        mdfld_dsi_send_gen_long_lp(sender, pr2_can_skip, 4, 0);
+       if (sender->status == MDFLD_DSI_CONTROL_ABNORMAL)
+               return -EIO;
+
        mdfld_dsi_send_gen_long_lp(sender, pr2_gamma_set_a, 16, 0);
+       if (sender->status == MDFLD_DSI_CONTROL_ABNORMAL)
+               return -EIO;
+
        mdfld_dsi_send_gen_long_lp(sender, pr2_gamma_set_b, 16, 0);
+       if (sender->status == MDFLD_DSI_CONTROL_ABNORMAL)
+               return -EIO;
+
        mdfld_dsi_send_gen_long_lp(sender, pr2_gamma_set_c, 16, 0);
+       if (sender->status == MDFLD_DSI_CONTROL_ABNORMAL)
+               return -EIO;
+
        mdfld_dsi_send_gen_long_lp(sender, pr2_charge_pump_setting, 8, 0);
+       if (sender->status == MDFLD_DSI_CONTROL_ABNORMAL)
+               return -EIO;
+
        mdfld_dsi_send_gen_long_lp(sender, pr2_test_mode_1, 8, 0);
+       if (sender->status == MDFLD_DSI_CONTROL_ABNORMAL)
+               return -EIO;
+
        mdfld_dsi_send_gen_long_lp(sender, pr2_source_amplifiers, 4, 0);
+       if (sender->status == MDFLD_DSI_CONTROL_ABNORMAL)
+               return -EIO;
+
        mdfld_dsi_send_gen_long_lp(sender, pr2_power_supply_circuit, 4, 0);
+       if (sender->status == MDFLD_DSI_CONTROL_ABNORMAL)
+               return -EIO;
+
        mdfld_dsi_send_gen_long_lp(sender, pr2_vreg_setting, 4, 0);
+       if (sender->status == MDFLD_DSI_CONTROL_ABNORMAL)
+               return -EIO;
+
        mdfld_dsi_send_gen_long_lp(sender, pr2_test_mode_2, 4, 0);
+       if (sender->status == MDFLD_DSI_CONTROL_ABNORMAL)
+               return -EIO;
+
        mdfld_dsi_send_gen_long_lp(sender, pr2_timing_control_0, 12, 0);
+       if (sender->status == MDFLD_DSI_CONTROL_ABNORMAL)
+               return -EIO;
+
        mdfld_dsi_send_gen_long_lp(sender, pr2_timing_control_1, 8, 0);
+       if (sender->status == MDFLD_DSI_CONTROL_ABNORMAL)
+               return -EIO;
+
        mdfld_dsi_send_gen_long_lp(sender, pr2_timing_control_2, 4, 0);
+       if (sender->status == MDFLD_DSI_CONTROL_ABNORMAL)
+               return -EIO;
+
        mdfld_dsi_send_gen_long_lp(sender, pr2_white_balance, 8, 0);
+       if (sender->status == MDFLD_DSI_CONTROL_ABNORMAL)
+               return -EIO;
+
        mdfld_dsi_send_gen_long_lp(sender, pr2_vcs_setting, 4, 0);
+       if (sender->status == MDFLD_DSI_CONTROL_ABNORMAL)
+               return -EIO;
+
        mdfld_dsi_send_gen_long_lp(sender, pr2_vcom_dc_setting, 4, 0);
+       if (sender->status == MDFLD_DSI_CONTROL_ABNORMAL)
+               return -EIO;
+
        mdfld_dsi_send_gen_long_lp(sender, pr2_test_mode_3, 8, 0);
+       if (sender->status == MDFLD_DSI_CONTROL_ABNORMAL)
+               return -EIO;
+
        mdfld_dsi_send_gen_long_lp(sender, pr2_mcs_protect_on, 4, 0);
+       if (sender->status == MDFLD_DSI_CONTROL_ABNORMAL)
+               return -EIO;
+
        mdfld_dsi_send_mcs_long_lp(sender, pr2_set_address_mode, 4, 0);
+       if (sender->status == MDFLD_DSI_CONTROL_ABNORMAL)
+               return -EIO;
+
        mdfld_dsi_send_mcs_long_lp(sender, pr2_set_pixel_format, 4, 0);
+       if (sender->status == MDFLD_DSI_CONTROL_ABNORMAL)
+               return -EIO;
 
-       /* Now In Sleep Mode */
+       return 0;
 }
 
 static void