[GFX-Display] add a watch dog for flip chain
authorYun Tu(Mark Tu) <yun.tu@intel.com>
Thu, 23 Feb 2012 01:26:28 +0000 (09:26 +0800)
committerbuildbot <buildbot@intel.com>
Tue, 15 May 2012 12:18:41 +0000 (05:18 -0700)
BZ:32306

3D flip depends on vysnc interrupt by default, so 3D will get blocked if there are something
wrong on display vsync interrupt. Add this watch dog so we can flush flip queue once we detected
the missing of vsync interrupt and avoid ANR of appliaction

Change-Id: I91a85fea3fafdada124191ace73a967935cf295d
Signed-off-by: Yun Tu(Mark Tu) <yun.tu@intel.com>
Reviewed-on: http://android.intel.com:8080/48116
Reviewed-by: Wang, Gang A <gang.a.wang@intel.com>
Reviewed-by: He, Bo <bo.he@intel.com>
Reviewed-by: Xu, Randy <randy.xu@intel.com>
Reviewed-by: Ai, Ke <ke.ai@intel.com>
Reviewed-by: Zhang, Yanmin <yanmin.zhang@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/pvr/services4/3rdparty/linux_framebuffer_drm/drmlfb.h
drivers/staging/mrst/pvr/services4/3rdparty/linux_framebuffer_drm/drmlfb_displayclass.c

index dbb63af..fb280c4 100644 (file)
@@ -240,6 +240,7 @@ typedef struct MRSTLFB_DEVINFO_TAG
        uint32_t uPlaneCSize;
        uint32_t uPlaneCStride;
     MRST_BOOL bScreenState;
+       struct timer_list sFlipTimer;
 }  MRSTLFB_DEVINFO;
 
 #if 0
index 677ad95..27e2e13 100644 (file)
@@ -50,6 +50,8 @@ extern int drm_psb_3D_vblank;
 
 #define MRSTLFB_COMMAND_COUNT          1
 
+#define FLIP_TIMEOUT (HZ/4)
+
 static PFN_DC_GET_PVRJTABLE pfnGetPVRJTable = 0;
 
 static MRSTLFB_DEVINFO * GetAnchorPtr(void)
@@ -1033,6 +1035,33 @@ static PVRSRV_ERROR SwapToDCBuffer(IMG_HANDLE hDevice,
        return (PVRSRV_OK);
 }
 
+void MRSTLFBFlipTimerFn(unsigned long arg)
+{
+       MRSTLFB_DEVINFO *psDevInfo = (MRSTLFB_DEVINFO *)arg;
+       unsigned long ulLockFlags;
+       MRSTLFB_SWAPCHAIN *psSwapChain;
+       printk(KERN_WARNING "MRSTLFBFlipTimerFn trigered\n");
+
+       spin_lock_irqsave(&psDevInfo->sSwapChainLock, ulLockFlags);
+
+       psSwapChain = psDevInfo->psCurrentSwapChain;
+       if (psSwapChain == NULL)
+       {
+               printk(KERN_WARNING "MRSTLFBFlipTimerFn: Swapchain is null\n");
+               goto ExitUnlock;
+       }
+       if (psSwapChain->ulRemoveIndex == psSwapChain->ulInsertIndex)
+       {
+               printk(KERN_INFO "MRSTLFBFlipTimerFn: swapchain is empty\n");
+               goto ExitUnlock;
+       }
+       printk(KERN_WARNING "MRSTLFBFlipTimerFn: flush flip queue\n");
+       FlushInternalVSyncQueue(psSwapChain, MRST_TRUE);
+ExitUnlock:
+       spin_unlock_irqrestore(&psDevInfo->sSwapChainLock, ulLockFlags);
+}
+
+
 static PVRSRV_ERROR SwapToDCSystem(IMG_HANDLE hDevice,
                                    IMG_HANDLE hSwapChain)
 {
@@ -1118,7 +1147,12 @@ static MRST_BOOL MRSTLFBVSyncIHandler(MRSTLFB_DEVINFO *psDevInfo, int iPipe)
        }
 
        if (psSwapChain->ulRemoveIndex == psSwapChain->ulInsertIndex)
+       {
                bStatus = MRST_TRUE;
+               del_timer(&psDevInfo->sFlipTimer);
+       }
+       else
+               mod_timer(&psDevInfo->sFlipTimer, FLIP_TIMEOUT + jiffies);
 ExitUnlock:
        spin_unlock_irqrestore(&psDevInfo->sSwapChainLock, ulLockFlags);
 
@@ -1195,6 +1229,8 @@ static IMG_BOOL ProcessFlip2(IMG_HANDLE hCmdCookie,
        }
        if (dev_priv->b_dsr_enable)
                dev_priv->exit_idle(dev, MDFLD_DSR_2D_3D, NULL, true);
+       /*start Flip watch dog*/
+       mod_timer(&psDevInfo->sFlipTimer, FLIP_TIMEOUT + jiffies);
 
        if (hdmi_state) {
                /*
@@ -1311,6 +1347,9 @@ static IMG_BOOL ProcessFlip(IMG_HANDLE  hCmdCookie,
        if (dev_priv->b_dsr_enable)
                dev_priv->exit_idle(dev, MDFLD_DSR_2D_3D, NULL, true);
 
+       /*start Flip watch dog*/
+       mod_timer(&psDevInfo->sFlipTimer, FLIP_TIMEOUT + jiffies);
+
        if (hdmi_state) {
                /*
                 * Enable HDMI vblank interrupt, otherwise page flip would stuck
@@ -1976,7 +2015,9 @@ MRST_ERROR MRSTLFBInit(struct drm_device * dev)
 
        psDevInfo->ulRefCount++;
 
-
+       psDevInfo->sFlipTimer.data = (unsigned long)psDevInfo;
+       psDevInfo->sFlipTimer.function = MRSTLFBFlipTimerFn;
+       init_timer(&psDevInfo->sFlipTimer);
        return (MRST_OK);
 }