GFX-Display: SW Method for ESD detection and recovery
authorfaxing <faxing.lu@intel.com>
Wed, 9 May 2012 17:20:48 +0000 (10:20 -0700)
committerbuildbot <buildbot@intel.com>
Fri, 18 May 2012 22:35:07 +0000 (15:35 -0700)
BZ: 31620

Enzo Bugs: 665, 602, 762

1. This patch created a timer to monitor ESD error. If an ESD is detected, the display panel will be reset. It had been verified in Enzo's phone and CMI panel in CLV+
2. Fixed format error/warning by checkpatch

Signed-off-by: faxing <faxing.lu@intel.com>
Change-Id: I10fe4354510d4e1eb2e93029b948416c84fc5097
Signed-off-by: faxing <faxing.lu@intel.com>
Reviewed-on: http://android.intel.com:8080/48072
Reviewed-by: Ai, Ke <ke.ai@intel.com>
Reviewed-by: Patel, Hitesh K <hitesh.k.patel@intel.com>
Reviewed-by: Tong, BoX <box.tong@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/auo_sc1_cmd.c
drivers/staging/mrst/drv/h8c7_cmd.c
drivers/staging/mrst/drv/mdfld_dsi_pkg_sender.c
drivers/staging/mrst/drv/mdfld_output.c
drivers/staging/mrst/drv/mdfld_output.h
drivers/staging/mrst/drv/psb_drv.c
drivers/staging/mrst/drv/psb_drv.h
drivers/staging/mrst/drv/psb_powermgmt.c

index 8b695a4..ee455e8 100644 (file)
@@ -570,6 +570,10 @@ static int mdfld_auo_dsi_dbi_set_power(struct drm_encoder *encoder, bool on)
                dsi_config->dsi_hw_context.panel_on = 0;
        }
 
+       if (dev_priv->dbi_panel_on)
+               mdfld_error_detect_correct_timer_start(dev);
+       else
+               mdfld_error_detect_correct_timer_end(dev);
 out_err:
        mutex_unlock(&dsi_config->context_lock);
        ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
@@ -595,6 +599,7 @@ static void mdfld_auo_dsi_dbi_mode_set(struct drm_encoder *encoder,
        struct mdfld_dsi_connector *dsi_connector = dsi_config->connector;
        int pipe = dsi_connector->pipe;
        int err = 0;
+       u32 reg_offset = pipe ? MIPIC_REG_OFFSET : 0;
 
        PSB_DEBUG_ENTRY("type %s\n", (pipe == 2) ? "MIPI2" : "MIPI");
        PSB_DEBUG_ENTRY("h %d v %d\n", mode->hdisplay, mode->vdisplay);
@@ -609,7 +614,7 @@ static void mdfld_auo_dsi_dbi_mode_set(struct drm_encoder *encoder,
                DRM_ERROR("mode set failed\n");
        else
                PSB_DEBUG_ENTRY("mode set done successfully\n");
-
+       REG_WRITE((MIPIA_EOT_DISABLE_REG+reg_offset), 0x00000008);/*0xB05C */
        return;
 }
 
@@ -931,6 +936,24 @@ err:
        return 0;
 }
 
+static bool mdfld_auo_esd_detection(struct mdfld_dsi_config *dsi_config)
+{
+       int ret;
+       u32 data = 0;
+       ret = mdfld_dsi_get_power_mode(dsi_config,
+                                &data,
+                                MDFLD_DSI_LP_TRANSMISSION);
+       if ((ret == 1) && ((data & 0x14) != 0x14))
+               return true;
+       return false;
+}
+static void mdfld_auo_get_reset_delay_time(
+               int *pdelay_between_dispaly_island_off_on,
+               int *pdelay_after_reset_gpio_toggle)
+{
+       *pdelay_between_dispaly_island_off_on = 20;
+       *pdelay_after_reset_gpio_toggle = 20;
+}
 /* TPO DBI encoder helper funcs */
 static const struct drm_encoder_helper_funcs auo_dsi_dbi_helper_funcs = {
        .save = mdfld_auo_dsi_dbi_save,
@@ -961,4 +984,6 @@ void auo_sc1_cmd_init(struct drm_device *dev, struct panel_funcs *p_funcs)
        p_funcs->set_brightness = mdfld_auo_dsi_cmd_set_brightness;
        p_funcs->power_on = __mdfld_auo_dsi_power_on;
        p_funcs->power_off = __mdfld_auo_dsi_power_off;
+       p_funcs->esd_detection = mdfld_auo_esd_detection;
+       p_funcs->get_reset_delay_time = mdfld_auo_get_reset_delay_time;
 }
index 1d5b54e..a51a73b 100644 (file)
@@ -71,8 +71,8 @@ static u32 h8c7_gamma_b[] = {0x070601e2, 0x1f322a2d, 0x0e0c0540, 0x13121411,
        0x0601180f, 0x322a2d07, 0x0c05401f, 0x1214110e, 0x00180f13};
 static u32 h8c7_enter_set_cabc[] = {0x1e001fc9, 0x0000001e, 0x00003e01};
 
-static u32 h8c7_mcs_clumn_addr[] = {0x0200002a,0xcf};
-static u32 h8c7_mcs_page_addr[] = {0x0400002b,0xff};
+static u32 h8c7_mcs_clumn_addr[] = {0x0200002a, 0xcf};
+static u32 h8c7_mcs_page_addr[] = {0x0400002b, 0xff};
 
 static u32 h8c7_mcs_protect_on[] = {0x000000b9};
 static u32 h8c7_set_address_mode[] = {0x00000036};
@@ -98,7 +98,8 @@ static int mdfld_mipi_panel_gpio_parse(struct sfi_table_header *table)
        return 0;
 }
 
-static void mdfld_h8c7_dci_ic_init(struct mdfld_dsi_config *dsi_config, int pipe)
+static void mdfld_h8c7_dci_ic_init(
+               struct mdfld_dsi_config *dsi_config, int pipe)
 {
 
        struct mdfld_dsi_pkg_sender *sender
@@ -246,7 +247,7 @@ static void mdfld_h8c7_dci_ic_init(struct mdfld_dsi_config *dsi_config, int pipe
 
 
 static void
-mdfld_h8c7_dci_controller_init(struct mdfld_dsi_config *dsi_config,
+mdfld_h8c7_dsi_controller_init(struct mdfld_dsi_config *dsi_config,
                                int pipe, int update)
 {
 
@@ -317,15 +318,15 @@ struct drm_display_mode *h8c7_cmd_get_config_mode(struct drm_device *dev)
                                ((ti->vblank_hi << 8) | ti->vblank_lo);
                mode->clock = ti->pixel_clock * 10;
 
-               printk(KERN_ALERT"===hdisplay is %d\n", mode->hdisplay);
-               printk(KERN_ALERT"===vdisplay is %d\n", mode->vdisplay);
-               printk(KERN_ALERT"===HSS is %d\n", mode->hsync_start);
-               printk(KERN_ALERT"===HSE is %d\n", mode->hsync_end);
-               printk(KERN_ALERT"===htotal is %d\n", mode->htotal);
-               printk(KERN_ALERT"===VSS is %d\n", mode->vsync_start);
-               printk(KERN_ALERT"===VSE is %d\n", mode->vsync_end);
-               printk(KERN_ALERT"===vtotal is %d\n", mode->vtotal);
-               printk(KERN_ALERT"===clock is %d\n", mode->clock);
+               printk(KERN_ALERT"hdisplay is %d\n", mode->hdisplay);
+               printk(KERN_ALERT"vdisplay is %d\n", mode->vdisplay);
+               printk(KERN_ALERT"HSS is %d\n", mode->hsync_start);
+               printk(KERN_ALERT"HSE is %d\n", mode->hsync_end);
+               printk(KERN_ALERT"htotal is %d\n", mode->htotal);
+               printk(KERN_ALERT"VSS is %d\n", mode->vsync_start);
+               printk(KERN_ALERT"VSE is %d\n", mode->vsync_end);
+               printk(KERN_ALERT"vtotal is %d\n", mode->vtotal);
+               printk(KERN_ALERT"clock is %d\n", mode->clock);
 
        } else {
                mode->htotal = 920;
@@ -411,7 +412,7 @@ int mdfld_dsi_h8c7_cmd_power_on(struct mdfld_dsi_config *dsi_config)
        msleep(120);
 
 
-       param[0] = 0x00; //0x03;
+       param[0] = 0x00;
        param[1] = 0x00;
        param[2] = 0x00;
        err = mdfld_dsi_send_dcs(sender,
@@ -425,7 +426,7 @@ int mdfld_dsi_h8c7_cmd_power_on(struct mdfld_dsi_config *dsi_config)
                goto power_err;
        }
 
-       param[0] = 0x24; //0x28;
+       param[0] = 0x24;
        param[1] = 0x00;
        param[2] = 0x00;
        err = mdfld_dsi_send_dcs(sender,
@@ -468,7 +469,7 @@ int mdfld_dsi_h8c7_cmd_power_on(struct mdfld_dsi_config *dsi_config)
        }
        msleep(21);
 
-       param[0] = 0x24;//0x2c;
+       param[0] = 0x24;
        param[1] = 0x00;
        param[2] = 0x00;
        err = mdfld_dsi_send_dcs(sender,
@@ -551,6 +552,74 @@ power_err:
        return err;
 }
 
+static void mdfld_h8c7_dsi_control_config(struct drm_device *dev)
+{
+       struct mdfld_dsi_hw_registers *regs = NULL;
+       struct mdfld_dsi_hw_context *ctx = NULL;
+       struct mdfld_dsi_config *dsi_config = NULL;
+       struct drm_psb_private *dev_priv = dev->dev_private;
+       int mipi_pipe = dev_priv->cur_pipe;
+       if (mipi_pipe)
+               dsi_config = dev_priv->dsi_configs[1];
+       else
+               dsi_config = dev_priv->dsi_configs[0];
+       regs = &dsi_config->regs;
+       ctx = &dsi_config->dsi_hw_context;
+       /* set low power output hold */
+       REG_WRITE(regs->mipi_reg, ctx->mipi);
+       msleep(30);
+       /* D-PHY parameter */
+       REG_WRITE(regs->dphy_param_reg, ctx->dphy_param);
+       /* Configure DSI controller */
+
+       REG_WRITE(regs->mipi_control_reg, ctx->mipi_control);
+       REG_WRITE(regs->intr_en_reg, ctx->intr_en);
+       REG_WRITE(regs->hs_tx_timeout_reg, ctx->hs_tx_timeout);
+       REG_WRITE(regs->lp_rx_timeout_reg, ctx->lp_rx_timeout);
+       REG_WRITE(regs->turn_around_timeout_reg, ctx->turn_around_timeout);
+       REG_WRITE(regs->device_reset_timer_reg, ctx->device_reset_timer);
+       REG_WRITE(regs->high_low_switch_count_reg, ctx->high_low_switch_count);
+       REG_WRITE(regs->init_count_reg, ctx->init_count);
+       REG_WRITE(regs->eot_disable_reg, ctx->eot_disable);
+       REG_WRITE(regs->lp_byteclk_reg, ctx->lp_byteclk);
+       REG_WRITE(regs->clk_lane_switch_time_cnt_reg,
+                       ctx->clk_lane_switch_time_cnt);
+       REG_WRITE(regs->dsi_func_prg_reg, ctx->dsi_func_prg);
+       REG_WRITE(regs->dbi_bw_ctrl_reg, ctx->dbi_bw_ctrl);
+
+}
+
+void mdfld_h8c7_disp_control_init(struct drm_device *dev)
+{
+       struct mdfld_dsi_hw_registers *regs = NULL;
+       struct mdfld_dsi_config *dsi_config = NULL;
+       struct drm_display_mode *fixed_mode =
+                       h8c7_cmd_get_config_mode(dev);
+       struct drm_psb_private *dev_priv = dev->dev_private;
+       int mipi_pipe = dev_priv->cur_pipe;
+       if (mipi_pipe)
+               dsi_config = dev_priv->dsi_configs[1];
+       else
+               dsi_config = dev_priv->dsi_configs[0];
+       regs = &dsi_config->regs;
+       mdfld_h8c7_dsi_control_config(dev);
+
+       REG_WRITE(0x70184, 0);
+       REG_WRITE(0x70188, fixed_mode->hdisplay*4);
+       REG_WRITE(0x7018c, 0);
+       REG_WRITE(0x70190,
+               ((fixed_mode->vdisplay - 1)<<16) | (fixed_mode->hdisplay - 1));
+       REG_WRITE(0x70180, 0x98000000);
+
+       REG_WRITE(0x71400, 0x80000000);
+       REG_WRITE(0x6001c,
+               ((fixed_mode->hdisplay - 1)<<16) | (fixed_mode->vdisplay - 1));
+       msleep(30);
+       /* Enable DSI Controller */
+       REG_WRITE(regs->device_ready_reg, BIT0);
+       msleep(30);
+}
+
 int mdfld_h8c7_dsi_dbi_power_on(struct drm_encoder *encoder)
 {
        struct mdfld_dsi_encoder *dsi_encoder = MDFLD_DSI_ENCODER(encoder);
@@ -576,28 +645,7 @@ int mdfld_h8c7_dsi_dbi_power_on(struct drm_encoder *encoder)
                                        OSPM_UHB_FORCE_POWER_ON))
                return -EAGAIN;
 
-       /* HW-Reset */
-
-       /* set low power output hold */
-       REG_WRITE(regs->mipi_reg, ctx->mipi);
-       /* D-PHY parameter */
-       REG_WRITE(regs->dphy_param_reg, ctx->dphy_param);
-
-       /* Configure DSI controller */
-       REG_WRITE(regs->mipi_control_reg, ctx->mipi_control);
-       REG_WRITE(regs->intr_en_reg, ctx->intr_en);
-       REG_WRITE(regs->hs_tx_timeout_reg, ctx->hs_tx_timeout);
-       REG_WRITE(regs->lp_rx_timeout_reg, ctx->lp_rx_timeout);
-       REG_WRITE(regs->turn_around_timeout_reg, ctx->turn_around_timeout);
-       REG_WRITE(regs->device_reset_timer_reg, ctx->device_reset_timer);
-       REG_WRITE(regs->high_low_switch_count_reg, ctx->high_low_switch_count);
-       REG_WRITE(regs->init_count_reg, ctx->init_count);
-       REG_WRITE(regs->eot_disable_reg, ctx->eot_disable);
-       REG_WRITE(regs->lp_byteclk_reg, ctx->lp_byteclk);
-       REG_WRITE(regs->clk_lane_switch_time_cnt_reg,
-                       ctx->clk_lane_switch_time_cnt);
-       REG_WRITE(regs->dsi_func_prg_reg, ctx->dsi_func_prg);
-       REG_WRITE(regs->dbi_bw_ctrl_reg, ctx->dbi_bw_ctrl);
+       mdfld_h8c7_dsi_control_config(dev);
 
        /* Enable DSI Controller */
        REG_WRITE(regs->device_ready_reg, BIT0);
@@ -619,7 +667,6 @@ power_on_err:
        ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
        return err;
 }
-//--------------------------------- add below
 /*
  * Power off sequence for video mode MIPI panel.
  * NOTE: do NOT modify this function
@@ -745,6 +792,10 @@ static int mdfld_h8c7_dsi_dbi_set_power(struct drm_encoder *encoder, bool on)
 
                dsi_config->dsi_hw_context.panel_on = 0;
        }
+       if (dev_priv->dbi_panel_on)
+               mdfld_error_detect_correct_timer_start(dev);
+       else
+               mdfld_error_detect_correct_timer_end(dev);
 
 out_err:
        mutex_unlock(&dsi_config->context_lock);
@@ -771,6 +822,7 @@ static void mdfld_h8c7_dsi_dbi_mode_set(struct drm_encoder *encoder,
                mdfld_dsi_encoder_get_config(dsi_encoder);
        struct mdfld_dsi_connector *dsi_connector = dsi_config->connector;
        int pipe = dsi_connector->pipe;
+       u32 reg_offset = pipe ? MIPIC_REG_OFFSET : 0;
        struct mdfld_dsi_pkg_sender *sender =
                mdfld_dsi_get_pkg_sender(dsi_config);
        u8 param[8];
@@ -836,7 +888,8 @@ static void mdfld_h8c7_dsi_dbi_mode_set(struct drm_encoder *encoder,
 
 out_err:
        ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
-
+       REG_WRITE((MIPIA_EOT_DISABLE_REG + reg_offset), 0x00000008);
+       /*0xB05C */
        if (err)
                DRM_ERROR("mode set failed\n");
        else
@@ -968,32 +1021,33 @@ void mdfld_h8c7_dsi_dbi_restore(struct drm_encoder *encoder)
 /*
  * Update the DBI MIPI Panel Frame Buffer.
  */
-void mdfld_dsi_dbi_CB_ready (struct drm_device *dev, u32 mipi_command_address_reg, u32 gen_fifo_stat_reg)
+void mdfld_dsi_dbi_CB_ready(struct drm_device *dev,
+               u32 mipi_command_address_reg, u32 gen_fifo_stat_reg)
 {
        u32 DBI_CB_time_out_count = 0;
 
        /* Check MIPI Adatper command registers */
-       for (DBI_CB_time_out_count = 0; DBI_CB_time_out_count < DBI_CB_TIME_OUT; DBI_CB_time_out_count++)
-       {
+       for (DBI_CB_time_out_count = 0; DBI_CB_time_out_count <
+               DBI_CB_TIME_OUT; DBI_CB_time_out_count++){
                if (!(REG_READ(mipi_command_address_reg) & BIT0))
                        break;
        }
 
        if (DBI_CB_time_out_count == DBI_CB_TIME_OUT)
-               DRM_ERROR("Timeout waiting for DBI COMMAND status\n");
+               DRM_ERROR("Timeout waiting for DBI COMMAND status\n");
 
        if (!gen_fifo_stat_reg)
                return;
 
        /* Check and make sure the MIPI DBI BUFFER is empty. */
-       for (DBI_CB_time_out_count = 0; DBI_CB_time_out_count < DBI_CB_TIME_OUT; DBI_CB_time_out_count++)
-       {
+       for (DBI_CB_time_out_count = 0; DBI_CB_time_out_count <
+               DBI_CB_TIME_OUT; DBI_CB_time_out_count++){
                if (REG_READ(gen_fifo_stat_reg) & DBI_FIFO_EMPTY)
                        break;
        }
 
        if (DBI_CB_time_out_count == DBI_CB_TIME_OUT)
-               DRM_ERROR("Timeout waiting for DBI FIFO empty\n");
+               DRM_ERROR("Timeout waiting for DBI FIFO empty\n");
 }
 
 static void h8c7_dsi_dbi_update_fb(struct mdfld_dsi_dbi_output *dbi_output,
@@ -1016,8 +1070,7 @@ static void h8c7_dsi_dbi_update_fb(struct mdfld_dsi_dbi_output *dbi_output,
        if ((dbi_output->mode_flags & MODE_SETTING_ON_GOING) ||
                        (psb_crtc &&
                         (psb_crtc->mode_flags & MODE_SETTING_ON_GOING)) ||
-                       !(dbi_output->mode_flags & MODE_SETTING_ENCODER_DONE))
-       {
+                       !(dbi_output->mode_flags & MODE_SETTING_ENCODER_DONE)) {
                return;
        }
 
@@ -1053,7 +1106,7 @@ static void h8c7_dsi_dbi_update_fb(struct mdfld_dsi_dbi_output *dbi_output,
                           0,
                           CMD_DATA_SRC_PIPE,
                           MDFLD_DSI_SEND_PACKAGE);
-//     mdfld_dsi_gen_fifo_ready(dev, GEN_FIFO_STAT_REG, DBI_FIFO_EMPTY);
+/*     mdfld_dsi_gen_fifo_ready(dev, GEN_FIFO_STAT_REG, DBI_FIFO_EMPTY);*/
        dbi_output->dsr_fb_update_done = true;
        mdfld_dsi_cmds_kick_out(sender);
 
@@ -1099,7 +1152,7 @@ int mdfld_dsi_h8c7_cmd_detect(struct mdfld_dsi_config *dsi_config,
 
 #ifndef CONFIG_DRM_DPMS
        PSB_DEBUG_ENTRY("ifndef CONFIG_DRM_DPMS....\n");
-               //if (ctx->pll_bypass_mode)
+               /*if (ctx->pll_bypass_mode)*/
             {
                        REG_WRITE(regs->dpll_reg, dpll);
                        if (ctx->cck_div)
@@ -1170,7 +1223,8 @@ int mdfld_dsi_h8c7_cmd_panel_reset(struct mdfld_dsi_config *dsi_config,
        dev = dsi_config->dev;
 
        if (IS_CTP(dev)) {
-               sfi_table_parse(SFI_SIG_GPIO, NULL, NULL, mdfld_mipi_panel_gpio_parse);
+               sfi_table_parse(SFI_SIG_GPIO,
+                               NULL, NULL, mdfld_mipi_panel_gpio_parse);
                gpio_mipi_panel_reset = mdfld_mipi_panel_gpio_reset;
        }
 
@@ -1243,9 +1297,8 @@ int mdfld_h8c7_cmd_power_on(struct drm_encoder *encoder)
                mdfld_dsi_get_pkg_sender(dsi_config);
        u8 param[4];
 
-       struct drm_display_mode *fixed_mode = h8c7_cmd_get_config_mode(dev);  //h8c7_cmd
+       struct drm_display_mode *fixed_mode = h8c7_cmd_get_config_mode(dev);
 
-       printk(KERN_ALERT"%s\n",__func__);
        PSB_DEBUG_ENTRY("\n");
 
        regs = &dsi_config->regs;
@@ -1287,14 +1340,15 @@ int mdfld_h8c7_cmd_power_on(struct drm_encoder *encoder)
        REG_WRITE(0x70184, 0);
        REG_WRITE(0x70188, fixed_mode->hdisplay*4);
        REG_WRITE(0x7018c, 0);
-       REG_WRITE(0x70190, ((fixed_mode->vdisplay - 1)<<16) | (fixed_mode->hdisplay - 1));  //h8c7_cmd
+       REG_WRITE(0x70190,
+               ((fixed_mode->vdisplay - 1)<<16) | (fixed_mode->hdisplay - 1));
        REG_WRITE(0x70180, 0x98000000);
 
        REG_WRITE(0x71400, 0x80000000);
 
        REG_WRITE(0x7019c, 0);
-       REG_WRITE(0x6001c, ((fixed_mode->hdisplay - 1)<<16) | (fixed_mode->vdisplay - 1));
-
+       REG_WRITE(0x6001c,
+               ((fixed_mode->hdisplay-1)<<16)|(fixed_mode->vdisplay-1));
        msleep(30);
        /* Enable DSI Controller */
        REG_WRITE(regs->device_ready_reg, BIT0);
@@ -1338,13 +1392,31 @@ int mdfld_h8c7_cmd_power_on(struct drm_encoder *encoder)
 
        msleep(50);
 
-       // mdfld_dbi_dsr_timer_start(dev_priv->dbi_dsr_info);   //h8c7_cmd disable timer
+       /* mdfld_dbi_dsr_timer_start(dev_priv->dbi_dsr_info);*/
 
 power_err:
        ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
        return err;
 }
 
+static bool mdfld_h8c7_cmd_esd_detection(struct mdfld_dsi_config *dsi_config)
+{
+       int ret;
+       u32 data = 0;
+       ret = mdfld_dsi_get_power_mode(dsi_config,
+                                &data,
+                                MDFLD_DSI_LP_TRANSMISSION);
+       if ((ret == 1) && ((data & 0x14) != 0x14))
+               return true;
+       return false;
+}
+static void mdfld_h8c7_cmd_get_reset_delay_time(
+               int *pdelay_between_dispaly_island_off_on,
+               int *pdelay_after_reset_gpio_toggle)
+{
+       *pdelay_between_dispaly_island_off_on = 1200;
+       *pdelay_after_reset_gpio_toggle = 300;
+}
 
 /* TPO DBI encoder helper funcs */
 static const struct drm_encoder_helper_funcs h8c7_dsi_dbi_helper_funcs = {
@@ -1378,11 +1450,14 @@ void h8c7_cmd_init(struct drm_device *dev, struct panel_funcs *p_funcs)
        p_funcs->get_panel_info = h8c7_cmd_get_panel_info;
        p_funcs->reset = mdfld_dsi_h8c7_cmd_panel_reset;
        p_funcs->drv_ic_init = mdfld_h8c7_dci_ic_init;
-       p_funcs->dsi_controller_init = mdfld_h8c7_dci_controller_init;
+       p_funcs->dsi_controller_init = mdfld_h8c7_dsi_controller_init;
        p_funcs->detect = mdfld_dsi_h8c7_cmd_detect;
-       //p_funcs->get_panel_power_state = mdfld_h8c7_cmd_get_power_state;
+       /*p_funcs->get_panel_power_state = mdfld_h8c7_cmd_get_power_state;*/
        p_funcs->power_on = mdfld_dsi_h8c7_cmd_power_on;
        p_funcs->power_off = mdfld_dsi_h8c7_cmd_power_off;
        p_funcs->set_brightness = mdfld_dsi_h8c7_cmd_set_brightness;
+       p_funcs->disp_control_init = mdfld_h8c7_disp_control_init;
+       p_funcs->esd_detection = mdfld_h8c7_cmd_esd_detection;
+       p_funcs->get_reset_delay_time = mdfld_h8c7_cmd_get_reset_delay_time;
 
 }
index 41d4846..b5eea9e 100644 (file)
@@ -54,6 +54,7 @@ const char * dsi_errors[] = {
        "TX Checksum Error",
        "TX DSI Data Type Not Recognised",
        "TX DSI VC ID invalid",
+
        "High Contention",
        "Low contention",
        "DPI FIFO Under run",
@@ -117,6 +118,7 @@ static int handle_dsi_error(struct mdfld_dsi_pkg_sender *sender, u32 mask)
 {
        u32 intr_stat_reg = sender->mipi_intr_stat_reg;
        struct drm_device *dev = sender->dev;
+       struct drm_psb_private *dev_priv = dev->dev_private;
 
        PSB_DEBUG_ENTRY("Handling error 0x%08x\n", mask);
 
@@ -133,7 +135,12 @@ static int handle_dsi_error(struct mdfld_dsi_pkg_sender *sender, u32 mask)
        case BIT9:
        case BIT10:
        case BIT11:
+               PSB_DEBUG_ENTRY("No Action required\n");
+               break;
        case BIT12:
+               PSB_DEBUG_ENTRY("TXFALSE control error\n");
+               REG_WRITE(0xb004, BIT12);
+               break;
        case BIT13:
                PSB_DEBUG_ENTRY("No Action required\n");
                break;
@@ -145,16 +152,44 @@ static int handle_dsi_error(struct mdfld_dsi_pkg_sender *sender, u32 mask)
                PSB_DEBUG_ENTRY("No Action required\n");
                break;
        case BIT16:
+               PSB_DEBUG_ENTRY("TX DSI data type not recognised error\n");
+               /*REG_WRITE(0xb05c, REG_READ(0xb05c) | 0x8);*/
+               REG_WRITE(0xb004, BIT16);
                break;
        case BIT17:
                break;
        case BIT18:
+               {
+                       int count = 0;
+                       PSB_DEBUG_ENTRY("single high contention event\n");
+                       REG_WRITE(0xb05c, REG_READ(0xb05c)|0x30);
+                       while ((REG_READ(0xb004)&0x40000) == 0x40000) {
+                               count++;
+                       if (count == 2)
+                               REG_WRITE(0xb004, BIT18);
+                       if (count == 3) {
+                               printk(KERN_ALERT
+                                               "persistent high contention error detected\n");
+                               if (dev_priv->dbi_panel_on) {
+                                       /*Enzo asked no to do panel
+                                        *  reset panel right now
+                                       */
+                                       /*schedule_work(
+                                        * &dev_priv->reset_panel_work);
+                                        * */
+                               }
+                               break;
+                       }
+                       }
+               }
+               break;
        case BIT19:
-               PSB_DEBUG_ENTRY("High/Low contention detected\n");
+               PSB_DEBUG_ENTRY("Low contention detected\n");
                /*wait for contention recovery time*/
                /*mdelay(10);*/
                /*wait for all fifo empty*/
-               if(0) wait_for_all_fifos_empty(sender);
+               if (0)
+                       wait_for_all_fifos_empty(sender);
                break;
        case BIT20:
                PSB_DEBUG_ENTRY("No Action required\n");
index f85bdd8..62c21a9 100644 (file)
@@ -114,6 +114,7 @@ void init_panel(struct drm_device* dev, int mipi_pipe, enum panel_type p_type)
        struct panel_funcs * p_vid_funcs = NULL;
        int ret = 0;
 
+       dev_priv->cur_pipe = mipi_pipe;
        p_cmd_funcs = kzalloc(sizeof(struct panel_funcs), GFP_KERNEL);
        p_vid_funcs = kzalloc(sizeof(struct panel_funcs), GFP_KERNEL);
        
index 1f3d4fc..e4a7013 100644 (file)
@@ -107,6 +107,10 @@ struct panel_funcs {
        int (*power_on)(struct mdfld_dsi_config *dsi_config);
        int (*power_off)(struct mdfld_dsi_config *dsi_config);
        int (*set_brightness)(struct mdfld_dsi_config *dsi_config, int level);
+       void (*disp_control_init)(struct drm_device *);
+       bool (*esd_detection)(struct mdfld_dsi_config *dsi_config);
+       void (*get_reset_delay_time)(int *pdelay_between_dispaly_island_off_on,
+                       int *pdelay_after_reset_gpio_toggle);
 };
 
 void mdfld_output_init(struct drm_device* dev);
index 801a720..751efcc 100644 (file)
@@ -102,6 +102,8 @@ extern u32 DISP_PLANEB_STATUS;
 
 static int psb_probe(struct pci_dev *pdev, const struct pci_device_id *ent);
 
+#define ERROR_DETECT_DELAY (DRM_HZ*8)  /*8 seconds*/
+
 MODULE_PARM_DESC(debug, "Enable debug output");
 MODULE_PARM_DESC(no_fb, "Disable FBdev");
 MODULE_PARM_DESC(trap_pagefaults, "Error and reset on MMU pagefaults");
@@ -615,6 +617,106 @@ static void get_ci_info(struct drm_psb_private *dev_priv)
        return;
 }
 
+static void mdfld_error_detect_correct_timer_func(unsigned long data)
+{
+       struct mdfld_dsi_dbi_output *dbi_output = NULL;
+       struct panel_funcs *p_funcs  = NULL;
+       struct mdfld_dsi_config *dsi_config;
+       struct drm_device *dev = (struct drm_device *)data;
+       struct drm_psb_private *dev_priv = dev->dev_private;
+
+       struct timer_list *error_handle_timer =
+                       &(dev_priv->error_detect_correct_timer);
+       unsigned long flags;
+       if (!dev_priv->dbi_panel_on)
+               return;
+       if (dev_priv->cur_pipe == 0) {
+               dbi_output = dev_priv->dbi_output;
+               dsi_config = dev_priv->dsi_configs[0];
+       } else {
+               dbi_output = dev_priv->dbi_output2;
+               dsi_config = dev_priv->dsi_configs[1];
+       }
+       if (dbi_output) {
+               p_funcs = dbi_output->p_funcs;
+               if (p_funcs && (p_funcs->esd_detection)
+                               && dev_priv->dbi_panel_on) {
+                       if (p_funcs->esd_detection(dsi_config)) {
+                               printk(KERN_ALERT"ESD\n");
+                               schedule_work(&dev_priv->reset_panel_work);
+                       }
+               }
+       }
+       spin_lock_irqsave(&(dev_priv->error_detect_correct_lock), flags);
+       if (!timer_pending(error_handle_timer)) {
+               error_handle_timer->expires = jiffies + ERROR_DETECT_DELAY;
+               add_timer(error_handle_timer);
+       }
+       spin_unlock_irqrestore(&(dev_priv->error_detect_correct_lock), flags);
+
+}
+
+static int mdfld_error_detect_correct_timer_init(struct drm_device *dev)
+{
+
+       struct drm_psb_private *dev_priv =
+               (struct drm_psb_private *) dev->dev_private;
+
+       struct timer_list *error_handle_timer =
+                       &(dev_priv->error_detect_correct_timer);
+       unsigned long flags;
+
+       PSB_DEBUG_ENTRY("\n");
+
+       spin_lock_init(&(dev_priv->error_detect_correct_lock));
+       spin_lock_irqsave(&(dev_priv->error_detect_correct_lock), flags);
+
+       init_timer(error_handle_timer);
+
+       error_handle_timer->data = (unsigned long)dev;
+       error_handle_timer->function = mdfld_error_detect_correct_timer_func;
+       error_handle_timer->expires = jiffies + ERROR_DETECT_DELAY;
+
+       spin_unlock_irqrestore(&(dev_priv->error_detect_correct_lock), flags);
+
+       PSB_DEBUG_ENTRY("successfully\n");
+
+       return 0;
+}
+
+
+void mdfld_error_detect_correct_timer_start(struct drm_device *dev)
+{
+       struct drm_psb_private *dev_priv =
+               (struct drm_psb_private *) dev->dev_private;
+
+       struct timer_list *error_handle_timer =
+                       &(dev_priv->error_detect_correct_timer);
+       unsigned long flags;
+       spin_lock_irqsave(&(dev_priv->error_detect_correct_lock), flags);
+       if (!timer_pending(error_handle_timer)) {
+               error_handle_timer->expires = jiffies + ERROR_DETECT_DELAY;
+               add_timer(error_handle_timer);
+       }
+       spin_unlock_irqrestore(&(dev_priv->error_detect_correct_lock), flags);
+}
+
+
+void mdfld_error_detect_correct_timer_end(struct drm_device *dev)
+{
+       struct drm_psb_private *dev_priv =
+               (struct drm_psb_private *) dev->dev_private;
+
+       struct timer_list *error_handle_timer =
+                       &(dev_priv->error_detect_correct_timer);
+       unsigned long flags;
+       spin_lock_irqsave(&(dev_priv->error_detect_correct_lock), flags);
+       if (timer_pending(error_handle_timer)) {
+               error_handle_timer->expires = jiffies + ERROR_DETECT_DELAY;
+               del_timer(error_handle_timer);
+       }
+       spin_unlock_irqrestore(&(dev_priv->error_detect_correct_lock), flags);
+}
 
 
 static void get_imr_info(struct drm_psb_private *dev_priv)
@@ -1202,7 +1304,7 @@ bool mrst_get_vbt_data(struct drm_psb_private *dev_priv)
        }
 
        PanelID = dev_priv->panel_id;
-
+       printk(KERN_ALERT"PanelID:%d\n", PanelID);
        return true;
 }
 
@@ -1847,6 +1949,7 @@ static int psb_driver_load(struct drm_device *dev, unsigned long chipset)
        if (ret)
                return ret;
 
+       mdfld_error_detect_correct_timer_init(dev);
        /**
         *  Init lid switch timer.
         *  NOTE: must do this after psb_intel_opregion_init
@@ -1899,6 +2002,8 @@ static int psb_driver_load(struct drm_device *dev, unsigned long chipset)
                mdfld_dbi_dsr_init(dev);
 #endif /*CONFIG_MDFLD_DSI_DPU*/
                INIT_WORK(&dev_priv->te_work, mdfld_te_handler_work);
+               INIT_WORK(&dev_priv->reset_panel_work,
+                               mdfld_reset_panel_handler_work);
        }
 
        if (drm_psb_no_fb == 0) {
index 12e02c0..e097dcb 100644 (file)
@@ -442,7 +442,8 @@ struct drm_psb_private {
 
        struct work_struct te_work;
        int te_pipe;
-
+       struct work_struct reset_panel_work;
+       bool is_in_panel_reset;
        /*
         *TTM Glue.
         */
@@ -1037,6 +1038,12 @@ struct drm_psb_private {
        int (*async_check_fifo_empty)(struct drm_device *dev);
 
        /*
+        * Error detect/correct TIMER
+        */
+       spinlock_t error_detect_correct_lock;
+       struct timer_list error_detect_correct_timer;
+
+       /*
         * DSR TIMER
         */
        spinlock_t dsr_lock;
@@ -1268,8 +1275,9 @@ extern int mdfld_irq_enable_hdmi_audio(struct drm_device *dev);
 extern int mdfld_irq_disable_hdmi_audio(struct drm_device *dev);
 extern void psb_te_timer_func(unsigned long data);
 extern void mdfld_te_handler_work(struct work_struct *te_work);
-extern void mdfld_display_setting__work(struct work_struct *te_work);
-
+extern void mdfld_reset_panel_handler_work(struct work_struct *work);
+extern void mdfld_error_detect_correct_timer_end(struct drm_device *dev);
+extern void mdfld_error_detect_correct_timer_start(struct drm_device *dev);
 /*
  *psb_fence.c
  */
index 3007660..c5b78d7 100644 (file)
@@ -1877,7 +1877,7 @@ static void gfx_redridge_late_resume(struct drm_device *dev)
 
 static void gfx_early_suspend(struct early_suspend *h)
 {
-       struct drm_psb_privatedev_priv = gpDrmDevice->dev_private;
+       struct drm_psb_private *dev_priv = gpDrmDevice->dev_private;
        struct drm_device *dev = dev_priv->dev;
        struct drm_encoder *encoder;
        struct drm_encoder_helper_funcs *enc_funcs;
@@ -1886,8 +1886,14 @@ static void gfx_early_suspend(struct early_suspend *h)
        printk(KERN_ALERT "\n   gfx_early_suspend\n");
 #endif
 
-    if (dev_priv->pvr_screen_event_handler)
-        dev_priv->pvr_screen_event_handler(dev, 0);
+       if (h) {
+               while (dev_priv->is_in_panel_reset) {
+                       mdelay(100);
+                       printk(KERN_ALERT "===power key wait\n");
+               }
+       }
+       if (dev_priv->pvr_screen_event_handler)
+               dev_priv->pvr_screen_event_handler(dev, 0);
        /*Display off*/
        if (IS_MDFLD(gpDrmDevice)) {
                if ((dev_priv->panel_id == TMD_VID) ||
@@ -1936,85 +1942,94 @@ static void gfx_early_suspend(struct early_suspend *h)
 #endif
 
 }
-
-static void gfx_late_resume(struct early_suspend *h)
+static void resume_data_back()
+{
+       pm_runtime_forbid(&gpDrmDevice->pdev->dev);
+       mutex_lock(&g_ospm_mutex);
+       ospm_resume_pci(gpDrmDevice->pdev);
+       ospm_resume_display(gpDrmDevice->pdev);
+       psb_irq_preinstall_islands(gpDrmDevice, OSPM_DISPLAY_ISLAND);
+       psb_irq_postinstall_islands(gpDrmDevice, OSPM_DISPLAY_ISLAND);
+       mutex_unlock(&g_ospm_mutex);
+}
+static void restore_panel_controll_back(struct drm_psb_private *dev_priv)
 {
-       struct drm_psb_private* dev_priv = gpDrmDevice->dev_private;
        struct drm_device *dev = dev_priv->dev;
        struct drm_encoder *encoder;
        struct drm_encoder_helper_funcs *enc_funcs;
        struct drm_crtc *crtc = NULL;
        u32 dspcntr_val;
 
-#ifdef OSPM_GFX_DPK
-       printk(KERN_ALERT "\ngfx_late_resume\n");
-#endif
-
-       if(IS_MDFLD(gpDrmDevice)){
-
-#ifdef CONFIG_GFX_RTPM
-               pm_runtime_forbid(&gpDrmDevice->pdev->dev);
-               mutex_lock(&g_ospm_mutex);
-               ospm_resume_pci(gpDrmDevice->pdev);
-               ospm_resume_display(gpDrmDevice->pdev);
-               psb_irq_preinstall_islands(gpDrmDevice, OSPM_DISPLAY_ISLAND);
-               psb_irq_postinstall_islands(gpDrmDevice, OSPM_DISPLAY_ISLAND);
-               mutex_unlock(&g_ospm_mutex);
-#endif
-               if (IS_MDFLD(gpDrmDevice)) {
-                       if ((dev_priv->panel_id == TMD_VID) ||
-                               (dev_priv->panel_id == H8C7_VID) ||
-                               (dev_priv->panel_id == TMD_6X10_VID) ||
-                               (dev_priv->panel_id == GI_SONY_VID) ||
-                               (dev_priv->panel_id == GI_SONY_CMD) ||
-                               (dev_priv->panel_id == H8C7_CMD) ||
-                               (dev_priv->panel_id == AUO_SC1_VID) ||
-                               /* SC1 setting */
-                               (dev_priv->panel_id == AUO_SC1_CMD)) {
+       if (IS_MDFLD(gpDrmDevice)) {
+               if ((dev_priv->panel_id == TMD_VID) ||
+                       (dev_priv->panel_id == H8C7_VID) ||
+                       (dev_priv->panel_id == TMD_6X10_VID) ||
+                       (dev_priv->panel_id == GI_SONY_VID) ||
+                       (dev_priv->panel_id == GI_SONY_CMD) ||
+                       (dev_priv->panel_id == H8C7_CMD) ||
+                       (dev_priv->panel_id == AUO_SC1_VID) ||
+                       /* SC1 setting */
+                       (dev_priv->panel_id == AUO_SC1_CMD)) {
 #if defined(CONFIG_SUPPORT_TOSHIBA_MIPI_DISPLAY) || \
-                               defined(CONFIG_SUPPORT_TOSHIBA_MIPI_LVDS_BRIDGE)
-                               gfx_redridge_late_resume(dev);
+                       defined(CONFIG_SUPPORT_TOSHIBA_MIPI_LVDS_BRIDGE)
+                       gfx_redridge_late_resume(dev);
 #else
-                               list_for_each_entry(encoder,
-                                               &dev->mode_config.encoder_list,
-                                               head) {
-                                       enc_funcs = encoder->helper_private;
-                                       if (!drm_helper_encoder_in_use(encoder))
-                                               continue;
-                                       if (enc_funcs && enc_funcs->restore)
-                                               enc_funcs->restore(encoder);
-                               }
-#endif
-                       } else if (dev_priv->panel_id == TPO_CMD) {
-                               if (dev_priv->encoder0 &&
-                                       (dev_priv->panel_desc & DISPLAY_A))
-                                       mdfld_dsi_dbi_set_power(
-                                               &dev_priv->encoder0->base, true);
-                               if (dev_priv->encoder2 &&
-                                       (dev_priv->panel_desc & DISPLAY_C))
-                                       mdfld_dsi_dbi_set_power(
-                                               &dev_priv->encoder2->base, true);
-                       } else {
-                               printk(KERN_ALERT "%s invalid panel\n",
-                                       __func__);
+                       list_for_each_entry(encoder,
+                                       &dev->mode_config.encoder_list,
+                                       head) {
+                               enc_funcs = encoder->helper_private;
+                               if (!drm_helper_encoder_in_use(encoder))
+                                       continue;
+                               if (enc_funcs && enc_funcs->restore)
+                                       enc_funcs->restore(encoder);
                        }
+#endif
+               } else if (dev_priv->panel_id == TPO_CMD) {
+                       if (dev_priv->encoder0 &&
+                               (dev_priv->panel_desc & DISPLAY_A))
+                               mdfld_dsi_dbi_set_power(
+                                       &dev_priv->encoder0->base, true);
+                       if (dev_priv->encoder2 &&
+                               (dev_priv->panel_desc & DISPLAY_C))
+                               mdfld_dsi_dbi_set_power(
+                                       &dev_priv->encoder2->base, true);
+               } else {
+                       printk(KERN_ALERT "%s invalid panel\n",
+                               __func__);
                }
 
                if (dev_priv->panel_desc & DISPLAY_B) {
                        dspcntr_val = PSB_RVDC32(DSPBCNTR);
                        /* comply the status with HDMI DPMS */
                        if (DISP_PLANEB_STATUS == DISPLAY_PLANE_DISABLE)
-                               PSB_WVDC32(dspcntr_val & ~DISPLAY_PLANE_ENABLE, DSPBCNTR);
+                               PSB_WVDC32(dspcntr_val
+                                       & ~DISPLAY_PLANE_ENABLE, DSPBCNTR);
                        else
-                               PSB_WVDC32(dspcntr_val | DISPLAY_PLANE_ENABLE, DSPBCNTR);
+                               PSB_WVDC32(dspcntr_val
+                                       | DISPLAY_PLANE_ENABLE, DSPBCNTR);
                }
-        if (dev_priv->pvr_screen_event_handler)
-            dev_priv->pvr_screen_event_handler(dev, 1);
+               if (dev_priv->pvr_screen_event_handler)
+                       dev_priv->pvr_screen_event_handler(dev, 1);
                gbdispstatus = true;
 
                if (lastFailedBrightness > 0)
                        psb_set_brightness(NULL);
        }
+
+}
+static void gfx_late_resume(struct early_suspend *h)
+{
+       struct drm_psb_private *dev_priv = gpDrmDevice->dev_private;
+#ifdef OSPM_GFX_DPK
+       printk(KERN_ALERT "\ngfx_late_resume\n");
+#endif
+
+       if (IS_MDFLD(gpDrmDevice)) {
+#ifdef CONFIG_GFX_RTPM
+               resume_data_back();
+#endif
+       }
+       restore_panel_controll_back(dev_priv);
 }
 
 /*
@@ -2025,11 +2040,11 @@ static void gfx_late_resume(struct early_suspend *h)
  */
 int ospm_power_suspend(struct pci_dev *pdev, pm_message_t state)
 {
-        int ret = 0;
-        int graphics_access_count;
-        int videoenc_access_count;
-        int videodec_access_count;
-        int display_access_count;
+       int ret = 0;
+       int graphics_access_count;
+       int videoenc_access_count;
+       int videodec_access_count;
+       int display_access_count;
        struct drm_psb_private *dev_priv = gpDrmDevice->dev_private;
 
 #ifdef CONFIG_SUPPORT_TOSHIBA_MIPI_LVDS_BRIDGE
@@ -2732,3 +2747,74 @@ unlock:
        mutex_unlock(&vadd_mutex);
 }
 #endif
+void mdfld_reset_panel_handler_work(struct work_struct *work)
+{
+       struct drm_psb_private *dev_priv =
+               container_of(work, struct drm_psb_private, reset_panel_work);
+       int mipi_pipe = dev_priv->cur_pipe;
+       struct drm_device *dev = dev_priv->dev;
+       struct mdfld_dsi_config *dsi_config = NULL;
+
+       struct mdfld_dsi_dbi_output *dbi_output = NULL;
+       struct panel_funcs *p_funcs  = NULL;
+       int delay_between_dispaly_island_off_on = 20;
+       int delay_after_reset_gpio_toggle = 20;
+
+       /*if (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND,
+       *                               OSPM_UHB_FORCE_POWER_ON))
+       *       return -EAGAIN;
+       */
+       dev_priv->is_in_panel_reset = true;
+       if (!dev_priv->is_mipi_on)
+               goto reset_error;
+
+       if (mipi_pipe == 0) {
+               dbi_output = dev_priv->dbi_output;
+               dsi_config = dev_priv->dsi_configs[0];
+       } else {
+               dbi_output = dev_priv->dbi_output2;
+               dsi_config = dev_priv->dsi_configs[1];
+       }
+       if (!dbi_output) {
+               printk(KERN_ALERT "%s invalid dbi_output\n",
+                                               __func__);
+               goto reset_error;
+       }
+       p_funcs = dbi_output->p_funcs;
+       if (p_funcs) {
+               gfx_early_suspend(NULL);
+               if (p_funcs->get_reset_delay_time)
+                       p_funcs->get_reset_delay_time(
+                                       &delay_between_dispaly_island_off_on,
+                                       &delay_after_reset_gpio_toggle);
+               mdelay(delay_between_dispaly_island_off_on);
+
+               if (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND,
+                                               OSPM_UHB_FORCE_POWER_ON))
+                       goto reset_error;
+
+               if (p_funcs->reset)
+                       p_funcs->reset(dsi_config, RESET_FROM_OSPM_RESUME);
+
+               mdelay(delay_after_reset_gpio_toggle);
+               if (p_funcs->disp_control_init)
+                       p_funcs->disp_control_init(dev);
+
+               if (IS_MDFLD(gpDrmDevice))
+                       resume_data_back();
+
+               if (p_funcs->drv_ic_init)
+                       p_funcs->drv_ic_init(dsi_config, mipi_pipe);
+
+               restore_panel_controll_back(dev_priv);
+               ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
+               printk(KERN_ALERT"End panel reset!!!\n");
+       } else {
+               printk(KERN_ALERT "%s invalid panel init\n",
+                                                               __func__);
+       }
+reset_error:
+       dev_priv->is_in_panel_reset = false;
+       /*ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);*/
+}
+