/* Wait for VSync */ OMAPLFB_BOOL OMAPLFBWaitForVSync(OMAPLFB_DEVINFO *psDevInfo) { #if defined(PVR_OMAPLFB_DRM_FB) struct drm_connector *psConnector; for (psConnector = NULL; (psConnector = omap_fbdev_get_next_connector(psDevInfo->psLINFBInfo, psConnector)) != NULL;) { (void) omap_encoder_wait_for_vsync(psConnector->encoder); } return OMAPLFB_TRUE; #else /* defined(PVR_OMAPLFB_DRM_FB) */ #if FBDEV_PRESENT struct omap_dss_device *psDSSDev = fb2display(psDevInfo->psLINFBInfo); OMAP_DSS_MANAGER(psDSSMan, psDSSDev); if (psDSSMan != NULL && WAIT_FOR_VSYNC(psDSSMan) != NULL) { int res = WAIT_FOR_VSYNC(psDSSMan)(psDSSMan); if (res != 0) { DEBUG_PRINTK((KERN_WARNING DRIVER_PREFIX ": %s: Device %u: Wait for vsync failed (%d)\n", __FUNCTION__, psDevInfo->uiFBDevID, res)); return OMAPLFB_FALSE; } } #endif return OMAPLFB_TRUE; #endif /* defined(PVR_OMAPLFB_DRM_FB) */ }
OMAPLFB_BOOL OMAPLFBWaitForVSync(OMAPLFB_DEVINFO *psDevInfo) { #if 0 struct omap_dss_device *psDSSDev = fb2display(psDevInfo->psLINFBInfo); OMAP_DSS_MANAGER(psDSSMan, psDSSDev); if (psDSSMan != NULL && WAIT_FOR_VSYNC(psDSSMan) != NULL) { int res = WAIT_FOR_VSYNC(psDSSMan)(psDSSMan); if (res != 0) { DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX ": %s: Device %u: Wait for vsync failed (%d)\n", __FUNCTION__, psDevInfo->uiFBDevID, res)); return OMAPLFB_FALSE; } } #endif #if 0 struct vps_grpx_ctrl *gctrl; int r; gctrl = vps_grpx_get_ctrl(psDevInfo->uiFBDevID); printk (" BVSYNC \n"); r = gctrl->wait_for_vsync(gctrl); printk (" AVSYNC: %d\n", vsync_num++); return OMAPLFB_TRUE; #endif // unsigned long timeout = msecs_to_jiffies(500); #if FBDEV_PRESENT int r; void grpx_irq_wait_handler(void *data) { complete((struct completion *)data); }
/* Flip display to given buffer */ void OMAPLFBFlip(OMAPLFB_DEVINFO *psDevInfo, OMAPLFB_BUFFER *psBuffer) { struct fb_var_screeninfo sFBVar; int res; OMAPLFB_CONSOLE_LOCK(); sFBVar = psDevInfo->psLINFBInfo->var; sFBVar.xoffset = 0; sFBVar.yoffset = psBuffer->ulYOffset; #if defined(CONFIG_DSSCOMP) /* * If flipping to a NULL buffer, blank the screen to prevent * warnings/errors from the display subsystem. */ if (psBuffer->sSysAddr.uiAddr == 0) { struct omap_dss_device *psDSSDev = fb2display(psDevInfo->psLINFBInfo); OMAP_DSS_MANAGER(psDSSMan, psDSSDev); if (psDSSMan != NULL && psDSSMan->blank != NULL) { res = psDSSMan->blank(psDSSMan, false); if (res != 0) { DEBUG_PRINTK((KERN_WARNING DRIVER_PREFIX ": %s: Device %u: DSS manager blank call failed (Y Offset: %lu, Error: %d)\n", __FUNCTION__, psDevInfo->uiFBDevID, psBuffer->ulYOffset, res)); } } } { /* * If using DSSCOMP, we need to use dsscomp queuing for normal * framebuffer updates, so that previously used overlays get * automatically disabled, and manager gets dirtied. We can * do that because DSSCOMP takes ownership of all pipelines on * a manager. */ struct fb_fix_screeninfo sFBFix = psDevInfo->psLINFBInfo->fix; struct dsscomp_setup_dispc_data d = { .num_ovls = 1, .num_mgrs = 1, .mgrs[0].alpha_blending = 1, .ovls[0] = { .cfg = { .win.w = sFBVar.xres, .win.h = sFBVar.yres, .crop.x = sFBVar.xoffset, .crop.y = sFBVar.yoffset, .crop.w = sFBVar.xres, .crop.h = sFBVar.yres, .width = sFBVar.xres_virtual, .height = sFBVar.yres_virtual, .stride = sFBFix.line_length, .enabled = (psBuffer->sSysAddr.uiAddr != 0), .global_alpha = 255, }, }, }; /* do not map buffer into TILER1D as it is contiguous */ struct tiler_pa_info *pas[] = { NULL }; d.ovls[0].ba = (u32) psBuffer->sSysAddr.uiAddr; omapfb_mode_to_dss_mode(&sFBVar, &d.ovls[0].cfg.color_mode); res = dsscomp_gralloc_queue(&d, pas, true, NULL, NULL); if (res != 0) { DEBUG_PRINTK((KERN_WARNING DRIVER_PREFIX ": %s: Device %u: dsscomp_gralloc_queue failed (Y Offset: %lu, Error: %d)\n", __FUNCTION__, psDevInfo->uiFBDevID, psBuffer->ulYOffset, res)); } } #else /* defined(CONFIG_DSSCOMP) */ { unsigned long ulYResVirtual = psBuffer->ulYOffset + sFBVar.yres; /* * PVR_OMAPLFB_DONT_USE_FB_PAN_DISPLAY should be defined to * work around flipping problems seen with the Taal LCDs on * Blaze. * The work around is safe to use with other types of screen * on Blaze (e.g. HDMI) and on other platforms (e.g. Panda * board). */ #if !defined(PVR_OMAPLFB_DONT_USE_FB_PAN_DISPLAY) /* * Attempt to change the virtual screen resolution if it is too * small. Note that fb_set_var also pans the display. */ if (sFBVar.xres_virtual != sFBVar.xres || sFBVar.yres_virtual < ulYResVirtual) #endif /* !defined(PVR_OMAPLFB_DONT_USE_FB_PAN_DISPLAY) */ { sFBVar.xres_virtual = sFBVar.xres; sFBVar.yres_virtual = ulYResVirtual; sFBVar.activate = FB_ACTIVATE_NOW | FB_ACTIVATE_FORCE; res = fb_set_var(psDevInfo->psLINFBInfo, &sFBVar); if (res != 0) { printk(KERN_ERR DRIVER_PREFIX ": %s: Device %u: fb_set_var failed (Y Offset: %lu, Error: %d)\n", __FUNCTION__, psDevInfo->uiFBDevID, psBuffer->ulYOffset, res); } } #if !defined(PVR_OMAPLFB_DONT_USE_FB_PAN_DISPLAY) else { res = fb_pan_display(psDevInfo->psLINFBInfo, &sFBVar); if (res != 0) { printk(KERN_ERR DRIVER_PREFIX ": %s: Device %u: fb_pan_display failed (Y Offset: %lu, Error: %d)\n", __FUNCTION__, psDevInfo->uiFBDevID, psBuffer->ulYOffset, res); } } #endif /* !defined(PVR_OMAPLFB_DONT_USE_FB_PAN_DISPLAY) */ } #endif /* defined(CONFIG_DSSCOMP) */ OMAPLFB_CONSOLE_UNLOCK(); }