From: Ke Ai Date: Wed, 9 May 2012 09:53:07 +0000 (+0800) Subject: GFX-Display:FB update status check,re-enable dsr. X-Git-Tag: 2.1b_release~681 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=2228668ec4e44c6fb9578f6907427726e7618959;p=kernel%2Fkernel-mfld-blackbay.git GFX-Display:FB update status check,re-enable dsr. BZ: 35248 for Enzo bug 969 / 1056 /568 1.BZ 969 return result of mdfld_dsi_send_dcs. then user space will know retry to flip the surface 2.re-enable DSR feature to save power. 3.BZ 1056 clear some unused variable. 4.BZ 568wait for DBI FIFO empty befor send command,which fix enzo Change-Id: If1ce11ea7bda92f854f56151654eee11f3045d66 Signed-off-by: Ke Ai Signed-off-by: Patel Hitesh Signed-off-by: Tong, Bo Reviewed-on: http://android.intel.com:8080/47787 Reviewed-by: Zhang, Lei Reviewed-by: Xu, Randy Tested-by: Xu, Randy Reviewed-by: buildbot Tested-by: buildbot --- diff --git a/drivers/staging/mrst/drv/auo_sc1_cmd.c b/drivers/staging/mrst/drv/auo_sc1_cmd.c index ee455e8..4a64b2d 100644 --- a/drivers/staging/mrst/drv/auo_sc1_cmd.c +++ b/drivers/staging/mrst/drv/auo_sc1_cmd.c @@ -140,15 +140,6 @@ static struct drm_display_mode *auo_cmd_get_config_mode(struct drm_device* dev) ((ti->vblank_hi << 8) | ti->vblank_lo); mode->clock = ti->pixel_clock * 10; - PSB_DEBUG_ENTRY("hdisplay is %d\n", mode->hdisplay); - PSB_DEBUG_ENTRY("vdisplay is %d\n", mode->vdisplay); - PSB_DEBUG_ENTRY("HSS is %d\n", mode->hsync_start); - PSB_DEBUG_ENTRY("HSE is %d\n", mode->hsync_end); - PSB_DEBUG_ENTRY("htotal is %d\n", mode->htotal); - PSB_DEBUG_ENTRY("VSS is %d\n", mode->vsync_start); - PSB_DEBUG_ENTRY("VSE is %d\n", mode->vsync_end); - PSB_DEBUG_ENTRY("vtotal is %d\n", mode->vtotal); - PSB_DEBUG_ENTRY("clock is %d\n", mode->clock); } else { mode->hdisplay = 540; mode->vdisplay = 960; @@ -162,8 +153,18 @@ static struct drm_display_mode *auo_cmd_get_config_mode(struct drm_device* dev) mode->vtotal = mode->vsync_end + 4; mode->vrefresh = 60; mode->clock = mode->vrefresh * mode->vtotal * - mode->htotal / 1000; - } + mode->htotal / 1000; + } + + PSB_DEBUG_ENTRY("hdisplay is %d\n", mode->hdisplay); + PSB_DEBUG_ENTRY("vdisplay is %d\n", mode->vdisplay); + PSB_DEBUG_ENTRY("HSS is %d\n", mode->hsync_start); + PSB_DEBUG_ENTRY("HSE is %d\n", mode->hsync_end); + PSB_DEBUG_ENTRY("htotal is %d\n", mode->htotal); + PSB_DEBUG_ENTRY("VSS is %d\n", mode->vsync_start); + PSB_DEBUG_ENTRY("VSE is %d\n", mode->vsync_end); + PSB_DEBUG_ENTRY("vtotal is %d\n", mode->vtotal); + PSB_DEBUG_ENTRY("clock is %d\n", mode->clock); drm_mode_set_name(mode); drm_mode_set_crtcinfo(mode, 0); diff --git a/drivers/staging/mrst/drv/h8c7_cmd.c b/drivers/staging/mrst/drv/h8c7_cmd.c index 1102b95..cc49cc7 100644 --- a/drivers/staging/mrst/drv/h8c7_cmd.c +++ b/drivers/staging/mrst/drv/h8c7_cmd.c @@ -319,17 +319,6 @@ struct drm_display_mode *h8c7_cmd_get_config_mode(struct drm_device *dev) mode->vtotal = mode->vdisplay + \ ((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); - } else { mode->htotal = 920; mode->hdisplay = 720; @@ -340,11 +329,21 @@ struct drm_display_mode *h8c7_cmd_get_config_mode(struct drm_device *dev) mode->vsync_start = 1296; mode->vsync_end = 1298; - mode->vrefresh = 40; + mode->vrefresh = 60; mode->clock = mode->vrefresh * mode->vtotal * mode->htotal / 1000; } + PSB_DEBUG_ENTRY("hdisplay is %d\n", mode->hdisplay); + PSB_DEBUG_ENTRY("vdisplay is %d\n", mode->vdisplay); + PSB_DEBUG_ENTRY("HSS is %d\n", mode->hsync_start); + PSB_DEBUG_ENTRY("HSE is %d\n", mode->hsync_end); + PSB_DEBUG_ENTRY("htotal is %d\n", mode->htotal); + PSB_DEBUG_ENTRY("VSS is %d\n", mode->vsync_start); + PSB_DEBUG_ENTRY("VSE is %d\n", mode->vsync_end); + PSB_DEBUG_ENTRY("vtotal is %d\n", mode->vtotal); + PSB_DEBUG_ENTRY("clock is %d\n", mode->clock); + drm_mode_set_name(mode); drm_mode_set_crtcinfo(mode, 0); diff --git a/drivers/staging/mrst/drv/mdfld_dsi_dbi.c b/drivers/staging/mrst/drv/mdfld_dsi_dbi.c index 5708f62..f948faa 100644 --- a/drivers/staging/mrst/drv/mdfld_dsi_dbi.c +++ b/drivers/staging/mrst/drv/mdfld_dsi_dbi.c @@ -412,23 +412,43 @@ void mdfld_dsi_dbi_enter_dsr (struct mdfld_dsi_dbi_output * dbi_output, int pipe { u32 reg_val; struct drm_device * dev = dbi_output->dev; - struct drm_psb_private * dev_priv = dev->dev_private; + struct drm_psb_private *dev_priv = dev->dev_private; struct drm_crtc * crtc = dbi_output->base.base.crtc; struct psb_intel_crtc * psb_crtc = (crtc) ? to_psb_intel_crtc(crtc) : NULL; + struct mdfld_dsi_pkg_sender *sender = NULL; + struct panel_funcs *p_funcs = NULL; u32 dpll_reg = MRST_DPLL_A; u32 pipeconf_reg = PIPEACONF; u32 dspcntr_reg = DSPACNTR; + int retry; - PSB_DEBUG_ENTRY("\n"); + printk(KERN_INFO "\ncommand mode enter dsr\n"); if(!dbi_output) return; - + + spin_lock(&dev_priv->dsr_lock); + gdbi_output = dbi_output; - if((dbi_output->mode_flags & MODE_SETTING_ON_GOING) || + if ((dbi_output->mode_flags & MODE_SETTING_IN_DSR) || + (dbi_output->mode_flags & MODE_SETTING_ON_GOING) || (psb_crtc && psb_crtc->mode_flags & MODE_SETTING_ON_GOING)) - return; - + goto fun_exit; + + sender = mdfld_dsi_encoder_get_pkg_sender(&dbi_output->base); + + retry = 100; + while (retry && !(REG_READ(sender->mipi_gen_fifo_stat_reg) & BIT27)) { + udelay(500); + retry--; + } + + /*if DBI FIFO timeout, do not enter dsr*/ + if (!retry) { + printk(KERN_INFO "can not enter dsr currently\n"); + goto fun_exit ; + } + if(pipe == 2) { dpll_reg = MRST_DPLL_A; pipeconf_reg = PIPECCONF; @@ -437,9 +457,13 @@ void mdfld_dsi_dbi_enter_dsr (struct mdfld_dsi_dbi_output * dbi_output, int pipe if (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, OSPM_UHB_FORCE_POWER_ON)) { DRM_ERROR("hw begin failed\n"); - return; + goto fun_exit; } - + + p_funcs = dbi_output->p_funcs; + if (p_funcs && (p_funcs->esd_detection)) + mdfld_error_detect_correct_timer_end(dev); + mdfld_disable_te(dev, pipe); /*disable plane*/ @@ -478,6 +502,8 @@ void mdfld_dsi_dbi_enter_dsr (struct mdfld_dsi_dbi_output * dbi_output, int pipe enter_dsr = 1; //pm_schedule_suspend(&dev->pdev->dev, gfxrtdelay); } +fun_exit: + spin_unlock(&dev_priv->dsr_lock); } #ifndef CONFIG_MDFLD_DSI_DPU @@ -487,6 +513,7 @@ static void mdfld_dbi_output_exit_dsr (struct mdfld_dsi_dbi_output * dbi_output, struct drm_psb_private *dev_priv = dev->dev_private; struct drm_crtc * crtc = dbi_output->base.base.crtc; struct psb_intel_crtc * psb_crtc = (crtc) ? to_psb_intel_crtc(crtc) : NULL; + struct panel_funcs *p_funcs = NULL; u32 reg_val; u32 dpll_reg = MRST_DPLL_A; u32 pipeconf_reg = PIPEACONF; @@ -494,13 +521,16 @@ static void mdfld_dbi_output_exit_dsr (struct mdfld_dsi_dbi_output * dbi_output, u32 dspsurf_reg = DSPASURF; u32 reg_offset = 0; - PSB_DEBUG_ENTRY("\n"); + printk(KERN_INFO "\ncommand mode exit dsr\n"); + + spin_lock(&dev_priv->dsr_lock); /*if mode setting on-going, back off*/ - if((dbi_output->mode_flags & MODE_SETTING_ON_GOING) || + if (!(dbi_output->mode_flags & MODE_SETTING_IN_DSR) || + (dbi_output->mode_flags & MODE_SETTING_ON_GOING) || (psb_crtc && psb_crtc->mode_flags & MODE_SETTING_ON_GOING)) - return; - + goto fun_exit; + if(pipe == 2) { dpll_reg = MRST_DPLL_A; pipeconf_reg = PIPECCONF; @@ -512,11 +542,11 @@ static void mdfld_dbi_output_exit_dsr (struct mdfld_dsi_dbi_output * dbi_output, if (check_hw_on_only) { if (!ospm_power_is_hw_on(OSPM_DISPLAY_ISLAND)) { DRM_ERROR("hw begin failed\n"); - return; + goto fun_exit; } } else if (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, OSPM_UHB_FORCE_POWER_ON)) { DRM_ERROR("hw begin failed\n"); - return; + goto fun_exit; } /*enable DPLL*/ @@ -570,8 +600,17 @@ static void mdfld_dbi_output_exit_dsr (struct mdfld_dsi_dbi_output * dbi_output, mdfld_enable_te(dev, pipe); + dev_priv->dsr_idle_count = 0; + + p_funcs = dbi_output->p_funcs; + /*clean IN_DSR flag*/ dbi_output->mode_flags &= ~MODE_SETTING_IN_DSR; + + if (p_funcs && (p_funcs->esd_detection)) + mdfld_error_detect_correct_timer_start(dev); +fun_exit: + spin_unlock(&dev_priv->dsr_lock); } int mdfld_dsi_dbi_async_check_fifo_empty(struct drm_device *dev) { @@ -580,13 +619,12 @@ int mdfld_dsi_dbi_async_check_fifo_empty(struct drm_device *dev) struct mdfld_dsi_dbi_output **dbi_outputs = NULL; struct mdfld_dsi_dbi_output *dbi_output = NULL; struct mdfld_dsi_pkg_sender *sender = NULL; - u32 reg = 0; int err = 0; dbi_outputs = dsr_info->dbi_outputs; dbi_output = 0 ? dbi_outputs[1] : dbi_outputs[0]; if (!dbi_output) - return; + return 0; sender = mdfld_dsi_encoder_get_pkg_sender(&dbi_output->base); @@ -596,25 +634,33 @@ int mdfld_dsi_dbi_async_check_fifo_empty(struct drm_device *dev) /* * use hw te to update fb */ -void mdfld_dsi_dbi_async_flip_fb_update(struct drm_device *dev, int pipe) +int mdfld_dsi_dbi_async_flip_fb_update(struct drm_device *dev, int pipe) { struct drm_psb_private *dev_priv = dev->dev_private; struct mdfld_dbi_dsr_info *dsr_info = dev_priv->dbi_dsr_info; struct mdfld_dsi_dbi_output **dbi_outputs = NULL; struct mdfld_dsi_dbi_output *dbi_output = NULL; struct mdfld_dsi_pkg_sender *sender = NULL; - u32 reg = 0; + int ret = IMG_TRUE; + int err = 0; - u32 dpll_reg = MRST_DPLL_A; - u32 dspcntr_reg = DSPACNTR; - u32 pipeconf_reg = PIPEACONF; u32 dsplinoff_reg = DSPALINOFF; u32 dspsurf_reg = DSPASURF; dbi_outputs = dsr_info->dbi_outputs; dbi_output = pipe ? dbi_outputs[1] : dbi_outputs[0]; if (!dbi_output) - return; + return IMG_FALSE; + + if (!(spin_trylock(&dev_priv->dsr_lock))) { + printk(KERN_INFO "dsr lock busy\n"); + return IMG_TRUE; + } + + if (dbi_output->mode_flags & MODE_SETTING_IN_DSR) { + ret = IMG_FALSE; + goto fun_exit; + } sender = mdfld_dsi_encoder_get_pkg_sender(&dbi_output->base); @@ -623,15 +669,23 @@ void mdfld_dsi_dbi_async_flip_fb_update(struct drm_device *dev, int pipe) REG_WRITE(dspsurf_reg, REG_READ(dspsurf_reg)); REG_READ(dspsurf_reg); - mdfld_dsi_send_dcs(sender, + err = mdfld_dsi_send_dcs(sender, write_mem_start, NULL, 0, CMD_DATA_SRC_PIPE, MDFLD_DSI_SEND_PACKAGE); - mdfld_dsi_cmds_kick_out(sender); - return; + if (err) { + DRM_ERROR( + "Error returned from mdfld_dsi_send_dcs: %d\n", ret); + ret = IMG_FALSE; + goto fun_exit; + } + +fun_exit: + spin_unlock(&dev_priv->dsr_lock); + return ret; } /** @@ -643,8 +697,6 @@ void mdfld_dsi_dbi_exit_dsr (struct drm_device *dev, u32 update_src, void *p_sur struct mdfld_dbi_dsr_info * dsr_info = dev_priv->dbi_dsr_info; struct mdfld_dsi_dbi_output ** dbi_output; int i; - - PSB_DEBUG_ENTRY("\n"); dbi_output = dsr_info->dbi_outputs; @@ -667,7 +719,7 @@ void mdfld_dsi_dbi_exit_dsr (struct drm_device *dev, u32 update_src, void *p_sur } dev_priv->dsr_fb_update |= update_src; - + dev_priv->dsr_idle_count = 0; /*start timer if A0 board*/ if ((get_panel_type(dev, 0) == GI_SONY_CMD)||(get_panel_type(dev, 0) == H8C7_CMD)) ; /* mdfld_dbi_dsr_timer_start(dsr_info); */ @@ -728,7 +780,7 @@ void mdfld_dbi_update_panel (struct drm_device *dev, int pipe) } /*try to enter DSR*/ - if (dbi_outputs[0]->dsr_idle_count > 1) { + if (dbi_outputs[0]->dsr_idle_count > 50) { /* && dbi_outputs[1]->dsr_idle_count > 1) { */ for(i=0; idbi_output_num; i++) { if (!mdfld_dbi_is_in_dsr(dev) && dbi_outputs[i] && diff --git a/drivers/staging/mrst/drv/mdfld_dsi_pkg_sender.c b/drivers/staging/mrst/drv/mdfld_dsi_pkg_sender.c index 8adffbb..3f6db93 100644 --- a/drivers/staging/mrst/drv/mdfld_dsi_pkg_sender.c +++ b/drivers/staging/mrst/drv/mdfld_dsi_pkg_sender.c @@ -341,11 +341,13 @@ static int __send_short_pkg(struct mdfld_dsi_pkg_sender * sender, if(pkg->transmission_type == MDFLD_DSI_HS_TRANSMISSION) { /*wait for hs fifo empty*/ + wait_for_dbi_fifo_empty(sender); wait_for_hs_fifos_empty(sender); /*send pkg*/ REG_WRITE(hs_gen_ctrl_reg, gen_ctrl_val); } else if(pkg->transmission_type == MDFLD_DSI_LP_TRANSMISSION) { + wait_for_dbi_fifo_empty(sender); wait_for_lp_fifos_empty(sender); /*send pkg*/ @@ -389,6 +391,7 @@ static int __send_long_pkg(struct mdfld_dsi_pkg_sender * sender, if(pkg->transmission_type == MDFLD_DSI_HS_TRANSMISSION) { /*wait for hs ctrl and data fifos to be empty*/ + wait_for_dbi_fifo_empty(sender); wait_for_hs_fifos_empty(sender); dword_count = long_pkg->len / 4; @@ -415,6 +418,7 @@ static int __send_long_pkg(struct mdfld_dsi_pkg_sender * sender, REG_WRITE(hs_gen_ctrl_reg, gen_ctrl_val); } else if(pkg->transmission_type == MDFLD_DSI_LP_TRANSMISSION) { + wait_for_dbi_fifo_empty(sender); wait_for_lp_fifos_empty(sender); dword_count = long_pkg->len / 4; @@ -768,17 +772,23 @@ static inline void pkg_sender_queue_pkg(struct mdfld_dsi_pkg_sender * sender, spin_unlock_irqrestore(&sender->lock, flags); } -static inline void process_pkg_list(struct mdfld_dsi_pkg_sender * sender) +static inline int process_pkg_list(struct mdfld_dsi_pkg_sender *sender) { struct mdfld_dsi_pkg * pkg; unsigned long flags; + int ret = 0; spin_lock_irqsave(&sender->lock, flags); while(!list_empty(&sender->pkg_list)) { pkg = list_first_entry(&sender->pkg_list, struct mdfld_dsi_pkg, entry); - send_pkg(sender, pkg); + ret = send_pkg(sender, pkg); + + if (ret) { + DRM_INFO("Returning eror from process_pkg_lisgt"); + goto errorunlock; + } list_del_init(&pkg->entry); @@ -786,6 +796,11 @@ static inline void process_pkg_list(struct mdfld_dsi_pkg_sender * sender) } spin_unlock_irqrestore(&sender->lock, flags); + return 0; + +errorunlock: + spin_unlock_irqrestore(&sender->lock, flags); + return ret; } static int mdfld_dsi_send_mcs_long(struct mdfld_dsi_pkg_sender * sender, @@ -1274,23 +1289,14 @@ void dsi_controller_dpi_init(struct mdfld_dsi_config * dsi_config, int pipe) REG_WRITE((MIPIA_DEVICE_READY_REG + reg_offset), 0x00000001); } -void mdfld_dsi_cmds_kick_out(struct mdfld_dsi_pkg_sender * sender) +int mdfld_dsi_cmds_kick_out(struct mdfld_dsi_pkg_sender *sender) { - process_pkg_list(sender); + return process_pkg_list(sender); } int mdfld_dsi_check_fifo_empty(struct mdfld_dsi_pkg_sender *sender) { - struct mdfld_dsi_pkg dsi_pkg = { 0 }; - u32 cb_phy = sender->dbi_cb_phy; struct drm_device *dev = sender->dev; - u32 index = 0; - u8 *cb = (u8 *)sender->dbi_cb_addr; - unsigned long flags; - int retry; - u8 *dst = NULL; - u8 *pSendparam = NULL; - int err = 0; if (!sender) { DRM_ERROR("Invalid parameter\n"); @@ -1310,12 +1316,10 @@ int mdfld_dsi_send_dcs(struct mdfld_dsi_pkg_sender * sender, u8 dcs, u8 * param, u32 param_num, u8 data_src, int delay) { - struct mdfld_dsi_pkg dsi_pkg = { 0 }; u32 cb_phy = sender->dbi_cb_phy; struct drm_device *dev = sender->dev; u32 index = 0; u8 *cb = (u8 *)sender->dbi_cb_addr; - unsigned long flags; int retry; u8 *dst = NULL; u8 *pSendparam = NULL; @@ -1334,7 +1338,7 @@ int mdfld_dsi_send_dcs(struct mdfld_dsi_pkg_sender * sender, /*if dcs is write_mem_start, send it directly using DSI adapter interface*/ if (dcs == write_mem_start) { if (!spin_trylock(&sender->lock)) - return -EAGAIN; + return 0; /** * query whether DBI FIFO is empty, @@ -1349,6 +1353,7 @@ int mdfld_dsi_send_dcs(struct mdfld_dsi_pkg_sender * sender, /*if DBI FIFO timeout, drop this frame*/ if (!retry) { spin_unlock(&sender->lock); + printk(KERN_INFO "write mem start wait fifo full\n"); return 0; } diff --git a/drivers/staging/mrst/drv/mdfld_dsi_pkg_sender.h b/drivers/staging/mrst/drv/mdfld_dsi_pkg_sender.h index 316314f..5a6ba31 100644 --- a/drivers/staging/mrst/drv/mdfld_dsi_pkg_sender.h +++ b/drivers/staging/mrst/drv/mdfld_dsi_pkg_sender.h @@ -188,7 +188,7 @@ extern int mdfld_dsi_send_dpi_spk_pkg_hs(struct mdfld_dsi_pkg_sender *sender, u32 spk_pkg); extern int mdfld_dsi_send_dpi_spk_pkg_lp(struct mdfld_dsi_pkg_sender *sender, u32 spk_pkg); -extern void mdfld_dsi_cmds_kick_out(struct mdfld_dsi_pkg_sender * sender); +extern int mdfld_dsi_cmds_kick_out(struct mdfld_dsi_pkg_sender *sender); /*read interfaces*/ extern int mdfld_dsi_read_gen_hs(struct mdfld_dsi_pkg_sender *sender, diff --git a/drivers/staging/mrst/drv/psb_drv.c b/drivers/staging/mrst/drv/psb_drv.c index b0b4242..e0e4673 100644 --- a/drivers/staging/mrst/drv/psb_drv.c +++ b/drivers/staging/mrst/drv/psb_drv.c @@ -1801,6 +1801,7 @@ static int psb_driver_load(struct drm_device *dev, unsigned long chipset) mutex_init(&dev_priv->gamma_csc_lock); spin_lock_init(&dev_priv->reloc_lock); + spin_lock_init(&dev_priv->dsr_lock); DRM_INIT_WAITQUEUE(&dev_priv->rel_mapped_queue); diff --git a/drivers/staging/mrst/drv/psb_drv.h b/drivers/staging/mrst/drv/psb_drv.h index 06546f2..c209275 100644 --- a/drivers/staging/mrst/drv/psb_drv.h +++ b/drivers/staging/mrst/drv/psb_drv.h @@ -1036,7 +1036,7 @@ struct drm_psb_private { bool b_is_in_idle; void (*exit_idle)(struct drm_device *dev, u32 update_src, void *p_surfaceAddr, bool check_hw_on_only); bool b_vblank_enable; - void (*async_flip_update_fb)(struct drm_device *dev, int pipe); + int (*async_flip_update_fb)(struct drm_device *dev, int pipe); int (*async_check_fifo_empty)(struct drm_device *dev); /* diff --git a/drivers/staging/mrst/drv/psb_irq.c b/drivers/staging/mrst/drv/psb_irq.c index 958dc9f..43428c5 100644 --- a/drivers/staging/mrst/drv/psb_irq.c +++ b/drivers/staging/mrst/drv/psb_irq.c @@ -292,22 +292,60 @@ void psb_te_timer_func(unsigned long data) */ } +void mdfld_async_flip_te_handler(struct drm_device *dev, uint32_t pipe) +{ + struct drm_psb_private *dev_priv = + (struct drm_psb_private *) dev->dev_private; + struct mdfld_dbi_dsr_info *dsr_info = dev_priv->dbi_dsr_info; + struct mdfld_dsi_dbi_output **dbi_outputs; + struct mdfld_dsi_dbi_output *dbi_output; + static unsigned long cnt; + + int ret = 0; + + if ((dev_priv->psb_vsync_handler != NULL)) { + ret = (*dev_priv->psb_vsync_handler)(dev, pipe); + if (ret) { + if (dev_priv->b_dsr_enable) { + if (dev_priv->dsr_idle_count > 50) { + dev_priv->te_pipe = pipe; + schedule_work(&dev_priv->te_work); + } else + dev_priv->dsr_idle_count++; + } + } + } + +} void mdfld_te_handler_work(struct work_struct *work) { struct drm_psb_private *dev_priv = container_of(work, struct drm_psb_private, te_work); int pipe = dev_priv->te_pipe; struct drm_device *dev = dev_priv->dev; + struct mdfld_dbi_dsr_info *dsr_info = dev_priv->dbi_dsr_info; + struct mdfld_dsi_dbi_output **dbi_outputs; + struct mdfld_dsi_dbi_output *dbi_output; + dbi_outputs = dsr_info->dbi_outputs; + dbi_output = pipe ? dbi_outputs[1] : dbi_outputs[0]; + + if (!dbi_output) + return ; + + if (dev_priv->b_async_flip_enable) { + mdfld_dsi_dbi_enter_dsr(dbi_output, pipe); + } else { #ifdef CONFIG_MDFD_DSI_DPU - mdfld_dpu_update_panel(dev); + mdfld_dpu_update_panel(dev); #else - mdfld_dbi_update_panel(dev, pipe); + mdfld_dbi_update_panel(dev, pipe); #endif - drm_handle_vblank(dev, pipe); + drm_handle_vblank(dev, pipe); - if (dev_priv->psb_vsync_handler != NULL) - (*dev_priv->psb_vsync_handler)(dev, pipe); + if (dev_priv->psb_vsync_handler != NULL) + (*dev_priv->psb_vsync_handler)(dev, pipe); + } } /** * Display controller interrupt handler for pipe event. @@ -416,8 +454,7 @@ static void mid_pipe_event_handler(struct drm_device *dev, uint32_t pipe) if (pipe_stat_val & PIPE_TE_STATUS) { if (dev_priv->b_async_flip_enable) { - if (dev_priv->psb_vsync_handler != NULL) - (*dev_priv->psb_vsync_handler)(dev, pipe); + mdfld_async_flip_te_handler(dev, pipe); } else { dev_priv->te_pipe = pipe; schedule_work(&dev_priv->te_work); diff --git a/drivers/staging/mrst/pvr/services4/3rdparty/linux_framebuffer_drm/drmlfb.h b/drivers/staging/mrst/pvr/services4/3rdparty/linux_framebuffer_drm/drmlfb.h index fb280c4..97bdfb9 100644 --- a/drivers/staging/mrst/pvr/services4/3rdparty/linux_framebuffer_drm/drmlfb.h +++ b/drivers/staging/mrst/pvr/services4/3rdparty/linux_framebuffer_drm/drmlfb.h @@ -295,7 +295,8 @@ MRST_ERROR MRSTLFBUninstallVSyncISR(MRSTLFB_DEVINFO *psDevInfo); void MRSTLFBEnableVSyncInterrupt(MRSTLFB_DEVINFO *psDevInfo); void MRSTLFBDisableVSyncInterrupt(MRSTLFB_DEVINFO *psDevInfo); -void MRSTLFBFlipToSurface(MRSTLFB_DEVINFO *psDevInfo, unsigned long uiAddr); +IMG_BOOL MRSTLFBFlipToSurface(MRSTLFB_DEVINFO *psDevInfo, + unsigned long uiAddr); void MRSTLFBSavePlaneConfig(MRSTLFB_DEVINFO *psDevInfo); void MRSTLFBRestorePlaneConfig(MRSTLFB_DEVINFO *psDevInfo); diff --git a/drivers/staging/mrst/pvr/services4/3rdparty/linux_framebuffer_drm/drmlfb_displayclass.c b/drivers/staging/mrst/pvr/services4/3rdparty/linux_framebuffer_drm/drmlfb_displayclass.c index f143a53..cefdf28 100644 --- a/drivers/staging/mrst/pvr/services4/3rdparty/linux_framebuffer_drm/drmlfb_displayclass.c +++ b/drivers/staging/mrst/pvr/services4/3rdparty/linux_framebuffer_drm/drmlfb_displayclass.c @@ -64,7 +64,8 @@ static void SetAnchorPtr(MRSTLFB_DEVINFO *psDevInfo) gpvAnchor = (void*)psDevInfo; } -static void MRSTLFBFlip(MRSTLFB_DEVINFO *psDevInfo, MRSTLFB_BUFFER *psBuffer) +static IMG_BOOL MRSTLFBFlip(MRSTLFB_DEVINFO *psDevInfo, + MRSTLFB_BUFFER *psBuffer) { unsigned long ulAddr = (unsigned long)psBuffer->sDevVAddr.uiAddr; struct fb_info *psLINFBInfo; @@ -73,7 +74,10 @@ static void MRSTLFBFlip(MRSTLFB_DEVINFO *psDevInfo, MRSTLFB_BUFFER *psBuffer) if (!psDevInfo->bSuspended && !psDevInfo->bLeaveVT) { MRSTLFBRestorePlaneConfig(psDevInfo); - MRSTLFBFlipToSurface(psDevInfo, ulAddr); + if (MRSTLFBFlipToSurface(psDevInfo, ulAddr) == IMG_FALSE) { + DRM_INFO("returning false from MRSTLFBFlip"); + return IMG_FALSE; + } } psDevInfo->ulLastFlipAddr = ulAddr; @@ -86,6 +90,7 @@ static void MRSTLFBFlip(MRSTLFB_DEVINFO *psDevInfo, MRSTLFB_BUFFER *psBuffer) memset(psDevInfo->sSystemBuffer.sCPUVAddr, 0, psDevInfo->sSystemBuffer.ui32BufferSize); FirstCleanFlag = 0; } + return IMG_TRUE; } static void MRSTLFBFlipOverlay(MRSTLFB_DEVINFO *psDevInfo, @@ -151,7 +156,7 @@ static void MRSTLFBFlipSprite(MRSTLFB_DEVINFO *psDevInfo, } } -static void MRSTLFBFlipContexts(MRSTLFB_DEVINFO *psDevInfo, +static IMG_BOOL MRSTLFBFlipContexts(MRSTLFB_DEVINFO *psDevInfo, struct mdfld_plane_contexts *psContexts) { struct intel_sprite_context *psSpriteContext; @@ -161,7 +166,7 @@ static void MRSTLFBFlipContexts(MRSTLFB_DEVINFO *psDevInfo, int i; if (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, MRST_FALSE)) - return; + return IMG_FALSE; dev = psDevInfo->psDrmDevice; dev_priv = (struct drm_psb_private *)psDevInfo->psDrmDevice->dev_private; @@ -182,10 +187,13 @@ static void MRSTLFBFlipContexts(MRSTLFB_DEVINFO *psDevInfo, } } - if (dev_priv->b_async_flip_enable && dev_priv->async_flip_update_fb) - dev_priv->async_flip_update_fb(dev, 0); + if (dev_priv->b_async_flip_enable && dev_priv->async_flip_update_fb) { + if (dev_priv->async_flip_update_fb(dev, 0) == IMG_FALSE) + return IMG_FALSE; + } ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND); + return IMG_TRUE; } static void MRSTLFBRestoreLastFlip(MRSTLFB_DEVINFO *psDevInfo) @@ -205,12 +213,13 @@ static void MRSTLFBClearSavedFlip(MRSTLFB_DEVINFO *psDevInfo) } -static void FlushInternalVSyncQueue(MRSTLFB_SWAPCHAIN *psSwapChain, MRST_BOOL bFlip) +static IMG_BOOL FlushInternalVSyncQueue(MRSTLFB_SWAPCHAIN *psSwapChain, + MRST_BOOL bFlip) { MRSTLFB_VSYNC_FLIP_ITEM *psFlipItem; unsigned long ulMaxIndex; unsigned long i; - + IMG_BOOL ret = IMG_TRUE; psFlipItem = &psSwapChain->psVSyncFlips[psSwapChain->ulRemoveIndex]; ulMaxIndex = psSwapChain->ulSwapChainLength - 1; @@ -227,11 +236,20 @@ static void FlushInternalVSyncQueue(MRSTLFB_SWAPCHAIN *psSwapChain, MRST_BOOL bF if (psFlipItem->bFlipped == MRST_FALSE && bFlip) { if (psFlipItem->psBuffer) - MRSTLFBFlip(psSwapChain->psDevInfo, + ret = MRSTLFBFlip( + psSwapChain->psDevInfo, psFlipItem->psBuffer); else - MRSTLFBFlipContexts(psSwapChain->psDevInfo, + ret = MRSTLFBFlipContexts( + psSwapChain->psDevInfo, &psFlipItem->sPlaneContexts); + if (ret == IMG_FALSE) { + DRM_INFO( + "%s failed call to DRMLFBFlipBuffer2 - value %d", + __func__, ret); + return ret; + } + } if(psFlipItem->bCmdCompleted == MRST_FALSE) @@ -260,6 +278,8 @@ static void FlushInternalVSyncQueue(MRSTLFB_SWAPCHAIN *psSwapChain, MRST_BOOL bF psSwapChain->ulInsertIndex = 0; psSwapChain->ulRemoveIndex = 0; + + return IMG_TRUE; } static int DRMLFBFifoEmpty(MRSTLFB_DEVINFO *psDevInfo) @@ -271,27 +291,44 @@ static int DRMLFBFifoEmpty(MRSTLFB_DEVINFO *psDevInfo) return dev_priv->async_check_fifo_empty(dev); } -static void DRMLFBFlipBuffer(MRSTLFB_DEVINFO *psDevInfo, MRSTLFB_SWAPCHAIN *psSwapChain, MRSTLFB_BUFFER *psBuffer) +static IMG_BOOL DRMLFBFlipBuffer(MRSTLFB_DEVINFO *psDevInfo, + MRSTLFB_SWAPCHAIN *psSwapChain, + MRSTLFB_BUFFER *psBuffer) { + IMG_BOOL ret = IMG_TRUE; if(psSwapChain != NULL) { if(psDevInfo->psCurrentSwapChain != NULL) { - if(psDevInfo->psCurrentSwapChain != psSwapChain) - FlushInternalVSyncQueue(psDevInfo->psCurrentSwapChain, MRST_FALSE); + ret = FlushInternalVSyncQueue( + psDevInfo->psCurrentSwapChain, MRST_FALSE); + if (ret == IMG_FALSE) { + DRM_INFO( + "returning false in %s from " + "FlushInternalVSyncQueue in DRMLFBFlipBuffer"); + return ret; + } } psDevInfo->psCurrentSwapChain = psSwapChain; psDevInfo->psCurrentBuffer = psBuffer; } - MRSTLFBFlip(psDevInfo, psBuffer); + ret = MRSTLFBFlip(psDevInfo, psBuffer); + if (ret != IMG_TRUE) + DRM_INFO( + "returning %d from MRSTLFBFlip in DRMLFBFlipBuffer", ret); + + return ret; + } -static void DRMLFBFlipBuffer2(MRSTLFB_DEVINFO *psDevInfo, +static IMG_BOOL DRMLFBFlipBuffer2(MRSTLFB_DEVINFO *psDevInfo, MRSTLFB_SWAPCHAIN *psSwapChain, struct mdfld_plane_contexts *psContexts) { + IMG_BOOL ret = IMG_TRUE; + if (!psSwapChain) goto flip_out; @@ -301,11 +338,22 @@ static void DRMLFBFlipBuffer2(MRSTLFB_DEVINFO *psDevInfo, goto flip_out; } - if (psDevInfo->psCurrentSwapChain != psSwapChain) - FlushInternalVSyncQueue(psDevInfo->psCurrentSwapChain, + if (psDevInfo->psCurrentSwapChain != psSwapChain) { + ret = FlushInternalVSyncQueue(psDevInfo->psCurrentSwapChain, MRST_FALSE); + if (ret == IMG_FALSE) { + DRM_INFO("leaving with error from DRMLFBFlipBuffer2"); + return ret; + } + } + flip_out: - MRSTLFBFlipContexts(psDevInfo, psContexts); + ret = MRSTLFBFlipContexts(psDevInfo, psContexts); + if (ret != IMG_TRUE) + DRM_INFO( + "Returning %d from MRSTLFBFlipContexts in " + "DRMLFBFlipBuffer2", ret); + return ret; } static void SetFlushStateNoLock(MRSTLFB_DEVINFO* psDevInfo, @@ -1207,7 +1255,15 @@ static IMG_BOOL ProcessFlip2(IMG_HANDLE hCmdCookie, psDevInfo->bFlushCommands) { #endif /* update sprite plane context*/ - DRMLFBFlipBuffer2(psDevInfo, psSwapChain, psPlaneContexts); + if (DRMLFBFlipBuffer2( + psDevInfo, + psSwapChain, psPlaneContexts) == IMG_FALSE) { + DRM_ERROR("%s DRMLFBFlipBuffer2 failed", __func__); + psSwapChain->psPVRJTable->pfnPVRSRVCmdComplete( + hCmdCookie, + IMG_TRUE); + goto ExitErrorUnlock; + } psSwapChain->psPVRJTable->pfnPVRSRVCmdComplete(hCmdCookie, IMG_TRUE); #if defined(MRST_USING_INTERRUPTS) @@ -1248,8 +1304,15 @@ static IMG_BOOL ProcessFlip2(IMG_HANDLE hCmdCookie, if (psSwapChain->ulInsertIndex == psSwapChain->ulRemoveIndex) { /*update sprite plane context*/ - DRMLFBFlipBuffer2(psDevInfo, psSwapChain, - psPlaneContexts); + if (DRMLFBFlipBuffer2( + psDevInfo, + psSwapChain, psPlaneContexts) == IMG_FALSE) { + psFlipItem->bFlipped = MRST_FALSE; + psSwapChain->psPVRJTable->pfnPVRSRVCmdComplete( + hCmdCookie, + IMG_TRUE); + goto ExitErrorUnlock; + } psFlipItem->bFlipped = MRST_TRUE; } else { psFlipItem->bFlipped = MRST_FALSE; @@ -1270,7 +1333,7 @@ static IMG_BOOL ProcessFlip2(IMG_HANDLE hCmdCookie, goto ExitTrueUnlock; } - +ExitErrorUnlock: spin_unlock_irqrestore(&psDevInfo->sSwapChainLock, ulLockFlags); return IMG_FALSE; ExitTrueUnlock: @@ -1294,6 +1357,7 @@ static IMG_BOOL ProcessFlip(IMG_HANDLE hCmdCookie, unsigned long irqflags; struct drm_device *dev; struct drm_psb_private *dev_priv; + int retry = 1000; if(!hCmdCookie || !pvData) return IMG_FALSE; @@ -1313,8 +1377,14 @@ static IMG_BOOL ProcessFlip(IMG_HANDLE hCmdCookie, psSwapChain = (MRSTLFB_SWAPCHAIN*) psFlipCmd->hExtSwapChain; if (dev_priv->b_async_flip_enable && dev_priv->async_flip_update_fb) { - while (!DRMLFBFifoEmpty(psDevInfo)) + while (!DRMLFBFifoEmpty(psDevInfo) && retry) { usleep_range(500, 1000); + retry--; + } + if (!retry) { + DRM_ERROR("FIFO never emptied\n"); + return IMG_FALSE; + } } if (!psBuffer) @@ -1327,9 +1397,14 @@ static IMG_BOOL ProcessFlip(IMG_HANDLE hCmdCookie, if(!drm_psb_3D_vblank || psFlipCmd->ui32SwapInterval == 0 || psDevInfo->bFlushCommands) { #endif - DRMLFBFlipBuffer(psDevInfo, psSwapChain, psBuffer); - - + if (DRMLFBFlipBuffer( + psDevInfo, psSwapChain, psBuffer) == IMG_FALSE) { + DRM_ERROR("%s failed call to DRMLFBFlipBuffer", + __func__); + psSwapChain->psPVRJTable->pfnPVRSRVCmdComplete( + hCmdCookie, IMG_TRUE); + goto ExitErrorUnlock; + } psSwapChain->psPVRJTable->pfnPVRSRVCmdComplete(hCmdCookie, IMG_TRUE); @@ -1367,8 +1442,15 @@ static IMG_BOOL ProcessFlip(IMG_HANDLE hCmdCookie, if(psSwapChain->ulInsertIndex == psSwapChain->ulRemoveIndex) { - - DRMLFBFlipBuffer(psDevInfo, psSwapChain, psBuffer); + if (DRMLFBFlipBuffer(psDevInfo, + psSwapChain, psBuffer) == IMG_FALSE) { + DRM_ERROR("%s DRMFLBFlipBuffer failed", + __func__); + psFlipItem->bFlipped = MRST_FALSE; + psSwapChain->psPVRJTable->pfnPVRSRVCmdComplete( + hCmdCookie, IMG_TRUE); + goto ExitErrorUnlock; + } psFlipItem->bFlipped = MRST_TRUE; } @@ -1390,7 +1472,7 @@ static IMG_BOOL ProcessFlip(IMG_HANDLE hCmdCookie, goto ExitTrueUnlock; } - +ExitErrorUnlock: spin_unlock_irqrestore(&psDevInfo->sSwapChainLock, ulLockFlags); return IMG_FALSE; diff --git a/drivers/staging/mrst/pvr/services4/3rdparty/linux_framebuffer_drm/drmlfb_linux.c b/drivers/staging/mrst/pvr/services4/3rdparty/linux_framebuffer_drm/drmlfb_linux.c index e1b7f33..3919913 100644 --- a/drivers/staging/mrst/pvr/services4/3rdparty/linux_framebuffer_drm/drmlfb_linux.c +++ b/drivers/staging/mrst/pvr/services4/3rdparty/linux_framebuffer_drm/drmlfb_linux.c @@ -133,7 +133,8 @@ MRST_ERROR MRSTLFBUninstallVSyncISR(MRSTLFB_DEVINFO *psDevInfo) #endif -void MRSTLFBFlipToSurface(MRSTLFB_DEVINFO *psDevInfo, unsigned long uiAddr) +IMG_BOOL MRSTLFBFlipToSurface(MRSTLFB_DEVINFO *psDevInfo, + unsigned long uiAddr) { int dspbase = (psDevInfo->ui32MainPipe == 0 ? DSPABASE : DSPBBASE); int dspsurf = (psDevInfo->ui32MainPipe == 0 ? DSPASURF : DSPBSURF); @@ -158,8 +159,10 @@ void MRSTLFBFlipToSurface(MRSTLFB_DEVINFO *psDevInfo, unsigned long uiAddr) dspsurf = DSPASURF; MRSTLFBVSyncWriteReg(psDevInfo, dspsurf, uiAddr); if (dev_priv->b_async_flip_enable && - dev_priv->async_flip_update_fb) - dev_priv->async_flip_update_fb(dev, 0); + dev_priv->async_flip_update_fb) + if (dev_priv->async_flip_update_fb( + dev, 0) == IMG_FALSE) + return IMG_FALSE; } #if defined(CONFIG_MDFD_DUAL_MIPI) if (psCurrentSwapChain->ui32SwapChainPropertyFlag @@ -168,7 +171,9 @@ void MRSTLFBFlipToSurface(MRSTLFB_DEVINFO *psDevInfo, unsigned long uiAddr) MRSTLFBVSyncWriteReg(psDevInfo, dspsurf, uiAddr); if (dev_priv->b_async_flip_enable && dev_priv->async_flip_update_fb) - dev_priv->async_flip_update_fb(dev, 2); + if (dev_priv->async_flip_update_fb( + dev, 2) == IMG_FALSE) + return IMG_FALSE; } #endif #ifdef CONFIG_MDFD_HDMI @@ -191,6 +196,7 @@ void MRSTLFBFlipToSurface(MRSTLFB_DEVINFO *psDevInfo, unsigned long uiAddr) } ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND); } + return IMG_TRUE; } void MRSTLFBSavePlaneConfig(MRSTLFB_DEVINFO *psDevInfo)