hwc: added a wait for vblank flag to sprite operations
authorJackie Li <yaodong.li@intel.com>
Mon, 12 Dec 2011 14:14:09 +0000 (22:14 +0800)
committerbuildbot <buildbot@intel.com>
Fri, 23 Dec 2011 16:45:15 +0000 (08:45 -0800)
BZ: 17189

we need wait for vblank start when doing sprite plane flip to
avoid tearing issues.

Change-Id: I786827f8a5ec80bfec94babb6bf84b65e5264f7c
Signed-off-by: Jackie Li <yaodong.li@intel.com>
Signed-off-by: Tong Bo <box.tong@intel.com>
Reviewed-on: http://android.intel.com:8080/27728
Reviewed-by: Xu, Randy <randy.xu@intel.com>
Tested-by: Xu, Randy <randy.xu@intel.com>
Reviewed-by: buildbot <buildbot@intel.com>
Tested-by: buildbot <buildbot@intel.com>
drivers/staging/mrst/drv/psb_drm.h
drivers/staging/mrst/drv/psb_drv.c

index 370a69f..937da2d 100644 (file)
@@ -562,11 +562,12 @@ struct drm_psb_stolen_memory_arg {
 #define OVC_REGRWBITS_OVADD                    (1 << 2)
 #define OVC_REGRWBITS_OGAM_ALL                 (1 << 3)
 /*sprite update fields*/
-#define SPRITE_UPDATE_SURFACE                  (0x00000001UL)
-#define SPRITE_UPDATE_CONTROL                  (0x00000002UL)
-#define SPRITE_UPDATE_POSITION                 (0x00000004UL)
-#define SPRITE_UPDATE_SIZE                     (0x00000008UL)
-#define SPRITE_UPDATE_ALL                      (0x0000000fUL)
+#define SPRITE_UPDATE_SURFACE                  (0x00000001UL)
+#define SPRITE_UPDATE_CONTROL                  (0x00000002UL)
+#define SPRITE_UPDATE_POSITION                 (0x00000004UL)
+#define SPRITE_UPDATE_SIZE                     (0x00000008UL)
+#define SPRITE_UPDATE_WAIT_VBLANK              (0X00000010UL)
+#define SPRITE_UPDATE_ALL                      (0x0000001fUL)
 
 struct intel_sprite_context {
        uint32_t update_mask;
index db7341f..120276a 100755 (executable)
@@ -2798,6 +2798,7 @@ static int psb_register_rw_ioctl(struct drm_device *dev, void *data,
        UHBUsage usage =
                arg->b_force_hw_on ? OSPM_UHB_FORCE_POWER_ON : OSPM_UHB_ONLY_IF_ON;
        uint32_t ovadd;
+       int retry;
 
        if (arg->sprite_context_mask & REGRWBITS_SPRITE_UPDATE) {
                if (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, usage))
@@ -2812,6 +2813,20 @@ static int psb_register_rw_ioctl(struct drm_device *dev, void *data,
                else
                        return -EINVAL;
 
+               if ((arg->sprite_context.update_mask &
+                       SPRITE_UPDATE_WAIT_VBLANK)) {
+                       /**
+                        * wait for vblank upto 30ms,the period of vblank is 22ms.
+                        */
+                       retry = 3000;
+                       while (--retry) {
+                               if ((PSB_RVDC32(PIPEASTAT + reg_offset) &
+                                       PIPE_VBLANK_STATUS))
+                                       break;
+                               udelay(10);
+                       }
+               }
+
                if ((arg->sprite_context.update_mask & SPRITE_UPDATE_POSITION))
                        PSB_WVDC32(arg->sprite_context.pos,
                                DSPAPOS + reg_offset);
@@ -2823,6 +2838,11 @@ static int psb_register_rw_ioctl(struct drm_device *dev, void *data,
                                DSPASTRIDE + reg_offset);
                }
 
+               if ((arg->sprite_context.update_mask & SPRITE_UPDATE_CONTROL)) {
+                       PSB_WVDC32(arg->sprite_context.cntr,
+                               DSPACNTR + reg_offset);
+               }
+
                if ((arg->sprite_context.update_mask & SPRITE_UPDATE_SURFACE)) {
                        PSB_WVDC32(arg->sprite_context.linoff,
                                DSPALINOFF + reg_offset);
@@ -2830,12 +2850,6 @@ static int psb_register_rw_ioctl(struct drm_device *dev, void *data,
                                DSPASURF + reg_offset);
                }
 
-               if ((arg->sprite_context.update_mask & SPRITE_UPDATE_CONTROL)) {
-                       PSB_WVDC32(arg->sprite_context.cntr,
-                               DSPACNTR + reg_offset);
-                       PSB_WVDC32(PSB_RVDC32(DSPASURF + reg_offset),
-                               DSPASURF + reg_offset);
-               }
                ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
        }