/* 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();
}