diff options
| author | Gustavo Diaz Prado <x0083741@ti.com> | 2011-05-31 09:25:05 +0100 |
|---|---|---|
| committer | Andy Green <andy.green@linaro.org> | 2011-05-31 11:06:36 +0100 |
| commit | 06eac788a455158c045087e6881ce59f93611386 (patch) | |
| tree | b07fdd2afbab68a413e03f8fcf869335d5bde683 /drivers | |
| parent | 6e3fb218036c1d9535fe11ba537118303e8ef3db (diff) | |
SGX: UDD: Support for flipping with multiple display types
This patch enables the SGX display driver to support flipping
with multiple display types and configurations including
DSI auto and manual update modes. Code is compatible with DPI
interface panels and HDMI.
Change-Id: Iab57b495d29bb406f748a6e5b56612713789b7bb
Signed-off-by: Gustavo Diaz Prado <x0083741@ti.com>
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/gpu/pvr/omaplfb/omaplfb_displayclass.c | 97 | ||||
| -rw-r--r-- | drivers/gpu/pvr/omaplfb/omaplfb_linux.c | 63 |
2 files changed, 75 insertions, 85 deletions
diff --git a/drivers/gpu/pvr/omaplfb/omaplfb_displayclass.c b/drivers/gpu/pvr/omaplfb/omaplfb_displayclass.c index a2ad4e6e5d6..082e2d13f91 100644 --- a/drivers/gpu/pvr/omaplfb/omaplfb_displayclass.c +++ b/drivers/gpu/pvr/omaplfb/omaplfb_displayclass.c @@ -1038,62 +1038,47 @@ static void OMAPLFBSyncIHandler(struct work_struct *work) psFlipItem = &psSwapChain->psFlipItems[psSwapChain->ulRemoveIndex]; ulMaxIndex = psSwapChain->ulBufferCount - 1; - /* Synchronize with the display */ - OMAPLFBWaitForSync(psDevInfo); - /* Iterate through the flip items and flip them if necessary */ while(psFlipItem->bValid) { - if(psFlipItem->bFlipped) - { - if(!psFlipItem->bCmdCompleted) - { - psSwapChain->psPVRJTable->pfnPVRSRVCmdComplete( - (IMG_HANDLE)psFlipItem->hCmdComplete, - IMG_TRUE); - psFlipItem->bCmdCompleted = OMAP_TRUE; - } - psFlipItem->ulSwapInterval--; - - if(psFlipItem->ulSwapInterval == 0) - { - psSwapChain->ulRemoveIndex++; - if(psSwapChain->ulRemoveIndex > ulMaxIndex) - psSwapChain->ulRemoveIndex = 0; - psFlipItem->bCmdCompleted = OMAP_FALSE; - psFlipItem->bFlipped = OMAP_FALSE; - psFlipItem->bValid = OMAP_FALSE; - } - else - { - /* - * Here the swap interval is not zero yet - * we need to schedule another work until - * it reaches zero - */ - queue_work(psDevInfo->sync_display_wq, - &psDevInfo->sync_display_work); - goto ExitUnlock; - } - } - else - { - OMAPLFBFlip(psSwapChain, - (unsigned long)psFlipItem->sSysAddr); - psFlipItem->bFlipped = OMAP_TRUE; + /* Synchronize with the display */ + OMAPLFBWaitForSync(psDevInfo); + /* Update display */ + OMAPLFBFlip(psSwapChain, + (unsigned long)psFlipItem->sSysAddr->uiAddr); + + psFlipItem->ulSwapInterval--; + psFlipItem->bFlipped = OMAP_TRUE; + + if (psFlipItem->ulSwapInterval == 0) { + + /* Mark the flip item as completed to reuse it */ + psSwapChain->ulRemoveIndex++; + if (psSwapChain->ulRemoveIndex > ulMaxIndex) + psSwapChain->ulRemoveIndex = 0; + psFlipItem->bCmdCompleted = OMAP_FALSE; + psFlipItem->bFlipped = OMAP_FALSE; + psFlipItem->bValid = OMAP_FALSE; + + psSwapChain->psPVRJTable->pfnPVRSRVCmdComplete( + (IMG_HANDLE)psFlipItem->hCmdComplete, + IMG_TRUE); + psFlipItem->bCmdCompleted = OMAP_TRUE; + } else { /* - * If the flip has been presented here then we need - * in the next sync execute the command complete, - * schedule another work + * Here the swap interval is not zero yet + * we need to schedule another work until + * it reaches zero */ queue_work(psDevInfo->sync_display_wq, &psDevInfo->sync_display_work); - goto ExitUnlock; + break; } + psFlipItem = &psSwapChain->psFlipItems[psSwapChain->ulRemoveIndex]; } - + ExitUnlock: mutex_unlock(&psDevInfo->sSwapChainLockMutex); } @@ -1113,6 +1098,7 @@ static IMG_BOOL ProcessFlip(IMG_HANDLE hCmdCookie, OMAPLFB_SWAPCHAIN *psSwapChain; #if defined(SYS_USING_INTERRUPTS) OMAPLFB_FLIP_ITEM* psFlipItem; + unsigned long ulMaxIndex; #endif if(!hCmdCookie || !pvData) @@ -1163,20 +1149,9 @@ static IMG_BOOL ProcessFlip(IMG_HANDLE hCmdCookie, if(psFlipItem->bValid == OMAP_FALSE) { - unsigned long ulMaxIndex = psSwapChain->ulBufferCount - 1; - - /* - * If both indexes are equal the queue is empty, - * present immediatly - */ - if(psSwapChain->ulInsertIndex == psSwapChain->ulRemoveIndex) - { - OMAPLFBFlip(psSwapChain, - (unsigned long)psBuffer->sSysAddr.uiAddr); - psFlipItem->bFlipped = OMAP_TRUE; - } - else - psFlipItem->bFlipped = OMAP_FALSE; + /* Mark the flip item as not flipped */ + ulMaxIndex = psSwapChain->ulBufferCount - 1; + psFlipItem->bFlipped = OMAP_FALSE; /* * The buffer is queued here, must be consumed by the workqueue @@ -1195,7 +1170,9 @@ static IMG_BOOL ProcessFlip(IMG_HANDLE hCmdCookie, queue_work(psDevInfo->sync_display_wq, &psDevInfo->sync_display_work); goto ExitTrueUnlock; - } + } else + WARNING_PRINTK("Dropping frame! %p index %lu is the flip " + "queue full?", psFlipItem, psSwapChain->ulInsertIndex); mutex_unlock(&psDevInfo->sSwapChainLockMutex); return IMG_FALSE; diff --git a/drivers/gpu/pvr/omaplfb/omaplfb_linux.c b/drivers/gpu/pvr/omaplfb/omaplfb_linux.c index 5fe7c3b8563..90951f4f439 100644 --- a/drivers/gpu/pvr/omaplfb/omaplfb_linux.c +++ b/drivers/gpu/pvr/omaplfb/omaplfb_linux.c @@ -183,10 +183,7 @@ void OMAPLFBFlip(OMAPLFB_SWAPCHAIN *psSwapChain, unsigned long aPhyAddr) struct fb_info * framebuffer = psDevInfo->psLINFBInfo; struct omapfb_info *ofbi = FB2OFB(framebuffer); struct omapfb2_device *fbdev = ofbi->fbdev; - unsigned long fb_offset = - aPhyAddr - psDevInfo->sSystemBuffer.sSysAddr.uiAddr; - struct omap_overlay* overlay; - struct omap_overlay_info overlay_info; + unsigned long fb_offset; int i; fb_offset = aPhyAddr - psDevInfo->sSystemBuffer.sSysAddr.uiAddr; @@ -195,31 +192,31 @@ void OMAPLFBFlip(OMAPLFB_SWAPCHAIN *psSwapChain, unsigned long aPhyAddr) for(i = 0; i < ofbi->num_overlays ; i++) { + struct omap_dss_device *display = NULL; + struct omap_dss_driver *driver = NULL; + struct omap_overlay_manager *manager; + struct omap_overlay *overlay; + struct omap_overlay_info overlay_info; + overlay = ofbi->overlays[i]; + manager = overlay->manager; overlay->get_overlay_info( overlay, &overlay_info ); - /* If the overlay is not enabled don't update it */ - if(!overlay_info.enabled) - continue; - overlay_info.paddr = framebuffer->fix.smem_start + fb_offset; overlay_info.vaddr = framebuffer->screen_base + fb_offset; overlay->set_overlay_info(overlay, &overlay_info); - overlay->manager->apply(overlay->manager); -#if 0 - /* FIXME: Update call takes a long time in 2.6.35. - * Needs to be resolved in the display driver - * before we can enable this. - */ - if(overlay->manager->device->driver->update) - { - overlay->manager->device->driver->update( - overlay->manager->device, 0, 0, - overlay_info.width, - overlay_info.height); + if (manager) { + manager->apply(manager); + display = manager->device; + driver = display ? display->driver : NULL; } -#endif + + if (driver && driver->update && + driver->get_update_mode(display) == + OMAP_DSS_UPDATE_MANUAL) + driver->update(display, 0, 0, overlay_info.width, + overlay_info.height); } @@ -241,10 +238,26 @@ void OMAPLFBWaitForSync(OMAPLFB_DEVINFO *psDevInfo) { struct fb_info * framebuffer = psDevInfo->psLINFBInfo; struct omap_dss_device *display = fb2display(framebuffer); - if (display) - { - display->manager->wait_for_vsync(display->manager); - } + struct omap_dss_driver *driver; + struct omap_overlay_manager *manager; + int err = 1; + + if (!display) + WARNING_PRINTK("No DSS device to sync with display %u!", + psDevInfo->uDeviceID); + + driver = display->driver; + manager = display->manager; + + if (driver && driver->sync && + driver->get_update_mode(display) == OMAP_DSS_UPDATE_MANUAL) + err = driver->sync(display); + else if (manager && manager->wait_for_vsync) + err = manager->wait_for_vsync(manager); + + if (err) + WARNING_PRINTK("Unable to sync with display %u!", + psDevInfo->uDeviceID); } #if defined(LDM_PLATFORM) |
