GFX-Display: Added Post2 support for frame buffer flipping.
authorLei Zhang <lei.zhang@intel.com>
Mon, 4 Jun 2012 01:41:27 +0000 (09:41 +0800)
committerbuildbot <buildbot@intel.com>
Mon, 25 Jun 2012 18:04:19 +0000 (11:04 -0700)
BZ: 33412

This is 1/3 patches to solve Bug 33412.

Since post() path only supports update display plane surface in
kernel driver, we cannot configure other display plane settings
dynamically from user space.

This patch eanbled frame buffer flipping in Post2() path, and it
enhanced kernel driver to be able to re-config all display plane
registers, so that HWC can adjust display plane configs such as
plane format, z order dynamically.

This patch also increased the number of buffer of display class
so that we can multiple buffers to kernel driver in one flip cmd.

Change-Id: Id9b6bfcd0c59a2fbcb6338dc20dbbfd219ce5e9a
Signed-off-by: Jackie Li <yaodong.li@intel.com>
Signed-off-by: Lei Zhang <lei.zhang@intel.com>
Reviewed-on: http://android.intel.com:8080/51149
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/pvr/services4/3rdparty/linux_framebuffer_drm/drmlfb.h
drivers/staging/mrst/pvr/services4/3rdparty/linux_framebuffer_drm/drmlfb_displayclass.c
drivers/staging/mrst/pvr/services4/3rdparty/linux_framebuffer_drm/drmlfb_linux.c

index 621a447..c097f4a 100644 (file)
@@ -601,8 +601,10 @@ struct intel_sprite_context {
 #define INTEL_DISPLAY_PLANE_NUM                5
 
 struct mdfld_plane_contexts {
+       uint32_t active_primaries;
        uint32_t active_sprites;
        uint32_t active_overlays;
+       struct intel_sprite_context primary_contexts[INTEL_SPRITE_PLANE_NUM];
        struct intel_sprite_context sprite_contexts[INTEL_SPRITE_PLANE_NUM];
        struct intel_overlay_context overlay_contexts[INTEL_OVERLAY_PLANE_NUM];
 };
index 851a3b9..aa8b6bf 100644 (file)
@@ -227,19 +227,8 @@ typedef struct MRSTLFB_DEVINFO_TAG
 
        MRST_BOOL bLastFlipAddrValid;
 
-       uint32_t uPlaneACntr;
-       uint32_t uPlaneAPos;
-       uint32_t uPlaneASize;
-       uint32_t uPlaneAStride;
-       uint32_t uPlaneBCntr;
-       uint32_t uPlaneBPos;
-       uint32_t uPlaneBSize;
-       uint32_t uPlaneBStride;
-       uint32_t uPlaneCCntr;
-       uint32_t uPlaneCPos;
-       uint32_t uPlaneCSize;
-       uint32_t uPlaneCStride;
-    MRST_BOOL bScreenState;
+       MRST_BOOL bScreenState;
+
        struct timer_list sFlipTimer;
 }  MRSTLFB_DEVINFO;
 
@@ -297,8 +286,6 @@ void MRSTLFBDisableVSyncInterrupt(MRSTLFB_DEVINFO *psDevInfo);
 
 IMG_BOOL MRSTLFBFlipToSurface(MRSTLFB_DEVINFO *psDevInfo,
                  unsigned long uiAddr);
-void MRSTLFBSavePlaneConfig(MRSTLFB_DEVINFO *psDevInfo);
-void MRSTLFBRestorePlaneConfig(MRSTLFB_DEVINFO *psDevInfo);
 
 void MRSTLFBSuspend(void);
 void MRSTLFBResume(void);
index 3219d41..e039bc2 100644 (file)
@@ -53,6 +53,7 @@ extern int drm_psb_3D_vblank;
 #define FLIP_TIMEOUT (HZ/4)
 
 static PFN_DC_GET_PVRJTABLE pfnGetPVRJTable = 0;
+static int FirstCleanFlag = 1;
 
 static MRSTLFB_DEVINFO * GetAnchorPtr(void)
 {
@@ -69,11 +70,9 @@ static IMG_BOOL MRSTLFBFlip(MRSTLFB_DEVINFO *psDevInfo,
 {
        unsigned long ulAddr = (unsigned long)psBuffer->sDevVAddr.uiAddr;
        struct fb_info *psLINFBInfo;
-       static int FirstCleanFlag = 1;
 
        if (!psDevInfo->bSuspended && !psDevInfo->bLeaveVT)
        {
-               MRSTLFBRestorePlaneConfig(psDevInfo);
                if (MRSTLFBFlipToSurface(psDevInfo, ulAddr) == IMG_FALSE) {
                        DRM_INFO("returning false from MRSTLFBFlip");
                        return IMG_FALSE;
@@ -178,9 +177,54 @@ static void MRSTLFBFlipSprite(MRSTLFB_DEVINFO *psDevInfo,
        }
 }
 
+static void MRSTLFBFlipPrimary(MRSTLFB_DEVINFO *psDevInfo,
+                       struct intel_sprite_context *psContext)
+{
+       struct drm_device *dev;
+       struct drm_psb_private *dev_priv;
+       u32 reg_offset;
+       int pipe;
+
+       dev = psDevInfo->psDrmDevice;
+       dev_priv =
+               (struct drm_psb_private *)psDevInfo->psDrmDevice->dev_private;
+
+       if (psContext->index == 0) {
+               reg_offset = 0;
+               pipe = 0;
+       } else if (psContext->index == 1) {
+               reg_offset = 0x1000;
+               pipe = 1;
+       } else if (psContext->index == 2) {
+               reg_offset = 0x2000;
+               pipe = 2;
+       } else
+               return;
+
+       /*for HDMI only flip the surface address*/
+       if (pipe == 1)
+               psContext->update_mask &= SPRITE_UPDATE_SURFACE;
+
+       if ((psContext->update_mask & SPRITE_UPDATE_POSITION))
+               PSB_WVDC32(psContext->pos, DSPAPOS + reg_offset);
+       if ((psContext->update_mask & SPRITE_UPDATE_SIZE)) {
+               PSB_WVDC32(psContext->size, DSPASIZE + reg_offset);
+               PSB_WVDC32(psContext->stride, DSPASTRIDE + reg_offset);
+       }
+
+       if ((psContext->update_mask & SPRITE_UPDATE_CONTROL))
+               PSB_WVDC32(psContext->cntr, DSPACNTR + reg_offset);
+
+       if ((psContext->update_mask & SPRITE_UPDATE_SURFACE)) {
+               PSB_WVDC32(psContext->linoff, DSPALINOFF + reg_offset);
+               PSB_WVDC32(psContext->surf, DSPASURF + reg_offset);
+       }
+}
+
 static IMG_BOOL MRSTLFBFlipContexts(MRSTLFB_DEVINFO *psDevInfo,
                        struct mdfld_plane_contexts *psContexts)
 {
+       struct intel_sprite_context *psPrimaryContext;
        struct intel_sprite_context *psSpriteContext;
        struct intel_overlay_context *psOverlayContext;
        struct drm_psb_private *dev_priv;
@@ -193,6 +237,14 @@ static IMG_BOOL MRSTLFBFlipContexts(MRSTLFB_DEVINFO *psDevInfo,
        dev_priv =
                (struct drm_psb_private *)psDevInfo->psDrmDevice->dev_private;
 
+       /*flip all active primary planes*/
+       for (i = 0; i < INTEL_SPRITE_PLANE_NUM; i++) {
+               if (psContexts->active_primaries & (1 << i)) {
+                       psPrimaryContext = &psContexts->primary_contexts[i];
+                       MRSTLFBFlipPrimary(psDevInfo, psPrimaryContext);
+               }
+       }
+
        /*flip all active sprite planes*/
        for (i = 0; i < INTEL_SPRITE_PLANE_NUM; i++) {
                if (psContexts->active_sprites & (1 << i)) {
@@ -1238,6 +1290,77 @@ MRSTLFBVSyncISR(struct drm_device *psDrmDevice, int iPipe)
 }
 #endif
 
+static IMG_BOOL updatePlaneContexts(MRSTLFB_SWAPCHAIN *psSwapChain,
+                               DISPLAYCLASS_FLIP_COMMAND2 *psFlipCmd,
+                               struct mdfld_plane_contexts *psPlaneContexts)
+{
+       int i;
+       PDC_MEM_INFO psMemInfo, psCurrentMemInfo;
+       MRSTLFB_BUFFER *psBuffer, *psCurrentBuffer;
+
+       if (!psSwapChain || !psFlipCmd || !psPlaneContexts) {
+               DRM_ERROR("Invalid parameters\n");
+               return IMG_FALSE;
+       }
+
+       if (!psPlaneContexts->active_primaries)
+               return IMG_TRUE;
+
+       /* if active_primaries, update plane surface address*/
+       psCurrentMemInfo = 0;
+
+       for (i = 0; i < psFlipCmd->ui32NumMemInfos; i++) {
+               psMemInfo = psFlipCmd->ppsMemInfos[i];
+
+               if (!psMemInfo)
+                       continue;
+
+               if (psMemInfo->memType == PVRSRV_MEMTYPE_DEVICECLASS) {
+                       psCurrentMemInfo = psMemInfo;
+                       break;
+               }
+       }
+
+       if (!psCurrentMemInfo) {
+               DRM_ERROR("Failed to get FB MemInfo\n");
+               return IMG_FALSE;
+       }
+
+       /*get mrstlfb_buffer*/
+       psCurrentBuffer = 0;
+       for (i = 0; i < psSwapChain->ulBufferCount; i++) {
+               psBuffer = psSwapChain->ppsBuffer[i];
+
+               if (!psBuffer)
+                       continue;
+
+               if (psBuffer->sCPUVAddr == psMemInfo->pvLinAddrKM) {
+                       psCurrentBuffer = psBuffer;
+                       break;
+               }
+       }
+
+       if (!psCurrentBuffer) {
+               DRM_ERROR("Failed to get FB Buffer\n");
+               return IMG_FALSE;
+       }
+
+       /*update primary context with fb surface address*/
+       for (i = 0; i < INTEL_SPRITE_PLANE_NUM; i++) {
+               if (!(psSwapChain->ui32SwapChainPropertyFlag & (1 << i))) {
+                       psPlaneContexts->active_primaries &= ~(1 << i);
+                       continue;
+               }
+
+               if (psPlaneContexts->active_primaries & (1 << i)) {
+                       psPlaneContexts->primary_contexts[i].surf =
+                               psCurrentBuffer->sDevVAddr.uiAddr;
+               }
+       }
+
+       return IMG_TRUE;
+}
+
 static IMG_BOOL ProcessFlip2(IMG_HANDLE hCmdCookie,
                        IMG_UINT32 ui32DataSize,
                        IMG_VOID *pvData)
@@ -1268,9 +1391,18 @@ static IMG_BOOL ProcessFlip2(IMG_HANDLE hCmdCookie,
                return IMG_FALSE;
        }
 
+       if (FirstCleanFlag == 1) {
+               memset(psDevInfo->sSystemBuffer.sCPUVAddr, 0, psDevInfo->sSystemBuffer.ui32BufferSize);
+               FirstCleanFlag = 0;
+       }
+
        psPlaneContexts = (struct mdfld_plane_contexts *)psFlipCmd->pvPrivData;
 
        spin_lock_irqsave(&psDevInfo->sSwapChainLock, ulLockFlags);
+
+       /*update context*/
+       updatePlaneContexts(psSwapChain, psFlipCmd, psPlaneContexts);
+
 #if defined(MRST_USING_INTERRUPTS)
        if (!drm_psb_3D_vblank || psFlipCmd->ui32SwapInterval == 0 ||
                psDevInfo->bFlushCommands) {
@@ -2008,9 +2140,6 @@ MRST_ERROR MRSTLFBInit(struct drm_device * dev)
                        return (MRST_ERROR_INIT_FAILURE);
                }
 
-               /*save default plane config*/
-               MRSTLFBSavePlaneConfig(psDevInfo);
-
                if(MRSTLFBGetLibFuncAddr ("PVRGetDisplayClassJTable", &pfnGetPVRJTable) != MRST_OK)
                {
                        return (MRST_ERROR_INIT_FAILURE);
@@ -2101,7 +2230,7 @@ MRST_ERROR MRSTLFBInit(struct drm_device * dev)
 
 
        aui32SyncCountList[DC_FLIP_COMMAND][0] = 0;
-       aui32SyncCountList[DC_FLIP_COMMAND][1] = 2;
+       aui32SyncCountList[DC_FLIP_COMMAND][1] = 10;
 
 
 
index 7306a87..9dd56ab 100644 (file)
@@ -200,80 +200,6 @@ IMG_BOOL  MRSTLFBFlipToSurface(MRSTLFB_DEVINFO *psDevInfo,
        return IMG_TRUE;
 }
 
-void MRSTLFBSavePlaneConfig(MRSTLFB_DEVINFO *psDevInfo)
-{
-       struct drm_psb_private *dev_priv =
-               (struct drm_psb_private *) psDevInfo->psDrmDevice->dev_private;
-       u32 uPlaneFormat = 0;
-
-       /*update format based on active display pixel format*/
-       switch (psDevInfo->sDisplayFormat.pixelformat) {
-       case PVRSRV_PIXEL_FORMAT_RGB565:
-               uPlaneFormat = DISPPLANE_16BPP;
-               break;
-       case PVRSRV_PIXEL_FORMAT_ARGB8888:
-       default:
-               uPlaneFormat = DISPPLANE_32BPP;
-               break;
-       }
-
-       if (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, false))
-               return;
-
-       psDevInfo->uPlaneACntr = uPlaneFormat;
-       psDevInfo->uPlaneAStride = PSB_RVDC32(DSPASTRIDE);
-       psDevInfo->uPlaneAPos = PSB_RVDC32(DSPAPOS);
-       psDevInfo->uPlaneASize = PSB_RVDC32(DSPASIZE);
-#ifdef CONFIG_MDFD_HDMI
-       /*TODO: fully support HDMI later*/
-       /*psDevInfo->uPlaneBCntr = PSB_RVDC32(DSPBCNTR);*/
-       /*psDevInfo->uPlaneBStride = PSB_RVDC32(DSPBSTRIDE);*/
-#endif
-
-#ifdef CONFIG_MDFD_DUAL_MIPI
-       psDevInfo->uPlaneCCntr = uPlaneFormat;
-       psDevInfo->uPlaneCStride = PSB_RVDC32(DSPCSTRIDE);
-       psDevInfo->uPlaneCPos = PSB_RVDC32(DSPCPOS);
-       psDevInfo->uPlaneCSize = PSB_RVDC32(DSPCSIZE);
-#endif
-       ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
-
-}
-
-void MRSTLFBRestorePlaneConfig(MRSTLFB_DEVINFO *psDevInfo)
-{
-       struct drm_psb_private *dev_priv =
-               (struct drm_psb_private *) psDevInfo->psDrmDevice->dev_private;
-       u32 uDspCntr = 0;
-
-       if (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, false))
-               return;
-       uDspCntr = PSB_RVDC32(DSPACNTR);
-       uDspCntr &= ~(0xf << 26);
-       uDspCntr |= psDevInfo->uPlaneACntr;
-       PSB_WVDC32(uDspCntr, DSPACNTR);
-       PSB_WVDC32(psDevInfo->uPlaneAStride, DSPASTRIDE);
-       PSB_WVDC32(psDevInfo->uPlaneAPos, DSPAPOS);
-       PSB_WVDC32(psDevInfo->uPlaneASize, DSPASIZE);
-#ifdef CONFIG_MDFD_HDMI
-       /*TODO: fully support HDMI later*/
-       /*PSB_WVDC32(psDevInfo->uPlaneBCntr, DSPBCNTR);*/
-       /*PSB_WVDC32(psDevInfo->uPlaneBStride, DSPBSTRIDE);*/
-#endif
-
-#ifdef CONFIG_MDFD_DUAL_MIPI
-       uDspCntr = PSB_RVDC32(DSPCCNTR);
-       uDspCntr &= ~(0xf << 26);
-       uDspCntr |= psDevInfo->uPlaneCCntr;
-       PSB_WVDC32(uDspCntr, DSPCCNTR);
-       PSB_WVDC32(psDevInfo->uPlaneCCntr, DSPCCNTR);
-       PSB_WVDC32(psDevInfo->uPlaneCStride, DSPCSTRIDE);
-       PSB_WVDC32(psDevInfo->uPlaneCPos, DSPCPOS);
-       PSB_WVDC32(psDevInfo->uPlaneCSize, DSPCSIZE);
-#endif
-       ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
-}
-
 int PVR_DRM_MAKENAME(DISPLAY_CONTROLLER, _Init)(struct drm_device unref__ *dev)
 {
        if(MRSTLFBInit(dev) != MRST_OK)