示例#1
0
static int tile_update_start(struct fb_info *info)
{
	struct fbcon_ops *ops = info->fbcon_par;
	int err;

	err = fb_pan_display(info, &ops->var);
	ops->var.xoffset = info->var.xoffset;
	ops->var.yoffset = info->var.yoffset;
	ops->var.vmode = info->var.vmode;
	return err;
}
示例#2
0
/* Flip display to given buffer */
void XBLFBFlip(XBLFB_DEVINFO *psDevInfo, XBLFB_BUFFER *psBuffer)
{
	struct fb_var_screeninfo sFBVar;
	int res;
	unsigned long ulYResVirtual;

	XBLFB_CONSOLE_LOCK();

	sFBVar = psDevInfo->psLINFBInfo->var;

	sFBVar.xoffset = 0;
	sFBVar.yoffset = psBuffer->ulYOffset;

	ulYResVirtual = psBuffer->ulYOffset + sFBVar.yres;

#if !defined(PVR_OMAPLFB_DONT_USE_FB_PAN_DISPLAY)
	
	if (sFBVar.xres_virtual != sFBVar.xres || sFBVar.yres_virtual < ulYResVirtual)
#endif 
	{
		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);
                //                printk("fb_pan_display-----------------------\n");
                
		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 

	XBLFB_CONSOLE_UNLOCK();
}
示例#3
0
static IMG_VOID S3C_Flip(S3C_LCD_DEVINFO  *psDevInfo,
					   S3C_FRAME_BUFFER *fb)
{
	struct fb_var_screeninfo sFBVar;
	int res;
	unsigned long ulYResVirtual;

	S3C_CONSOLE_LOCK();

	sFBVar = psDevInfo->psFBInfo->var;

	sFBVar.xoffset = 0;
	sFBVar.yoffset = fb->yoffset;

	ulYResVirtual = fb->yoffset + sFBVar.yres;

	if (sFBVar.xres_virtual != sFBVar.xres || sFBVar.yres_virtual < ulYResVirtual)
	{
		sFBVar.xres_virtual = sFBVar.xres;
		sFBVar.yres_virtual = ulYResVirtual;

		sFBVar.activate = FB_ACTIVATE_NOW | FB_ACTIVATE_FORCE;

		res = fb_set_var(psDevInfo->psFBInfo, &sFBVar);
		if (res != 0)
		{
			printk("%s: fb_set_var failed (Y Offset: %d, Error: %d)\n", __FUNCTION__, fb->yoffset, res);	}
	}
	else
	{
		res = fb_pan_display(psDevInfo->psFBInfo, &sFBVar);
		if (res != 0)
		{
			printk( "%s: fb_pan_display failed (Y Offset: %d, Error: %d)\n", __FUNCTION__, fb->yoffset, res);
		}
	}

	if (gPVRPanDisplaySignal) {
		psDevInfo->sPVRJTable.pfnPVRSRVOEMFunction(
			OEM_COMPLETE_PREPARE_DISPLAY,
			&(fb->yoffset), sizeof(int),
			IMG_NULL, 0);
	}

	S3C_CONSOLE_UNLOCK();
}
void OMAPLFBFlip(OMAPLFB_DEVINFO *psDevInfo, OMAPLFB_BUFFER *psBuffer)
{
	struct fb_var_screeninfo sFBVar;
	int res;
	unsigned long ulYResVirtual;

	acquire_console_sem();

	sFBVar = psDevInfo->psLINFBInfo->var;

	sFBVar.xoffset = 0;
	sFBVar.yoffset = psBuffer->ulYOffset;

	ulYResVirtual = psBuffer->ulYOffset + sFBVar.yres;

	
	if (sFBVar.xres_virtual != sFBVar.xres || sFBVar.yres_virtual < ulYResVirtual)
	{
		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_INFO DRIVER_PREFIX ": %s: Device %u: fb_set_var failed (Y Offset: %lu, Error: %d)\n", __FUNCTION__, psDevInfo->uiFBDevID, psBuffer->ulYOffset, res);
		}
	}
	else
	{
		res = fb_pan_display(psDevInfo->psLINFBInfo, &sFBVar);
		if (res != 0)
		{
                        printk (" fb_pan api failed \n");
			printk(KERN_INFO DRIVER_PREFIX ": %s: Device %u: fb_pan_display failed (Y Offset: %lu, Error: %d)\n", __FUNCTION__, psDevInfo->uiFBDevID, psBuffer->ulYOffset, res);
		}
	}

	release_console_sem();
}
示例#5
0
文件: stmfb.c 项目: Firmeware/driver
static int stmfb_resume(struct platform_device *pdev)
{
  struct stmfb_info *i = (struct stmfb_info *)platform_get_drvdata(pdev);

  DPRINTK("\n");

  if(!i)
    return 0;

  if(pdev->dev.power.power_state.event == PM_EVENT_ON)
    return 0;

  acquire_console_sem();

  if(down_interruptible(&i->framebufferLock))
  {
    release_console_sem();
    return -EINTR;
  }

  if(i->pFBMainOutput)
    stm_display_output_resume(i->pFBMainOutput);

  if(i->pFBDVO)
    stm_display_output_resume(i->pFBDVO);

  up(&i->framebufferLock);

  /*
   * Now the hardware is back, kick the framebuffer into life
   */
  fb_pan_display(&i->info, &i->info.var);
  fb_set_cmap(&i->info.cmap, &i->info);
  fb_set_suspend(&i->info, 0);

  release_console_sem();

  DPRINTK("resumed\n");

  return 0;
}
static IMG_VOID S3C_Flip(S3C_LCD_DEVINFO  *psDevInfo,
					   S3C_FRAME_BUFFER *fb)
{
	struct fb_var_screeninfo sFBVar;
	int res;
	unsigned long ulYResVirtual;

	acquire_console_sem();

	sFBVar = psDevInfo->psFBInfo->var;

	sFBVar.xoffset = 0;
	sFBVar.yoffset = fb->yoffset;

	ulYResVirtual = fb->yoffset + sFBVar.yres;

	if (sFBVar.xres_virtual != sFBVar.xres || sFBVar.yres_virtual < ulYResVirtual)
	{
		sFBVar.xres_virtual = sFBVar.xres;
		sFBVar.yres_virtual = ulYResVirtual;

		sFBVar.activate = FB_ACTIVATE_NOW | FB_ACTIVATE_FORCE;

		res = fb_set_var(psDevInfo->psFBInfo, &sFBVar);
		if (res != 0)
		{
			printk("%s: fb_set_var failed (Y Offset: %d, Error: %d)\n", __FUNCTION__, fb->yoffset, res);	}
	}
	else
	{
		res = fb_pan_display(psDevInfo->psFBInfo, &sFBVar);
		if (res != 0)
		{
			printk( "%s: fb_pan_display failed (Y Offset: %d, Error: %d)\n", __FUNCTION__, fb->yoffset, res);
		}
	}

	release_console_sem();
}
示例#7
0
int __init sky_display_loadingbar_increase(void)
{
	static int		g_nRatio = 0;
	int				err = 0;
	struct fb_info	*info = registered_fb[0];

	if(0 == g_nRatio)	// avoid first call...
	{
		g_nRatio = 1;
		return 0;
	}



	if(SKY_LOADBAR_KERNEL_MODULE_LOAD_MAX_RATIO < g_nRatio)	// 1 ~ 33%
	{
		printk(KERN_DEBUG "sky_display_loadingbar_increase() DROP COUNT: %d\n", g_nRatio - SKY_LOADBAR_KERNEL_MODULE_LOAD_MAX_RATIO);
		g_nRatio++;
		return 0;
	}

	if(0 > (err = sky_lcdc_display_loadingbar(g_nRatio)))
		return err;
	if(0 > (err = fb_pan_display(info, &info->var)))
		return err;

	printk(KERN_DEBUG "########## sky_display_loadingbar_increase(%d)\n", g_nRatio);

	++g_nRatio;

	if(SKY_LOADBAR_KERNEL_MODULE_LOAD_MAX_RATIO < g_nRatio)	// 1 ~ 33%
	{
		printk(KERN_DEBUG "sky_display_loadingbar_increase() Droped: %d\n", g_nRatio);
		g_nRatio = 0;
		return 99;
	}
	
	return err;
}
示例#8
0
文件: radeon_pm.c 项目: wxlong/Test
int radeonfb_pci_resume(struct pci_dev *pdev)
{
        struct fb_info *info = pci_get_drvdata(pdev);
        struct radeonfb_info *rinfo = info->par;

	if (pdev->dev.power_state == 0)
		return 0;

	acquire_console_sem();

	/* Wakeup chip */
#ifdef CONFIG_RADEON_HAS_D2
	if (radeon_suspend_to_d2(rinfo, 0))
		radeon_set_suspend(rinfo, 0);
#endif /* CONFIG_RADEON_HAS_D2 */

	rinfo->asleep = 0;

	/* Restore display & engine */
	radeonfb_set_par(info);
	fb_pan_display(info, &info->var);
	fb_set_cmap(&info->cmap, 1, info);

	/* Refresh */
	fb_set_suspend(info, 0);

	/* Unblank */
	rinfo->lock_blank = 0;
	radeonfb_blank(0, info);

	release_console_sem();

	pdev->dev.power_state = 0;

	printk(KERN_DEBUG "radeonfb: resumed !\n");

	return 0;
}
/* Flip display to given buffer */
static void DC_SUNXIFlip(DC_SUNXI_DEVINFO *psDevInfo, DC_SUNXI_BUFFER *psBuffer)
{
	struct fb_var_screeninfo sFBVar;
	unsigned long ulYResVirtual;
	int res;

	console_lock();

	sFBVar = psDevInfo->psLINFBInfo->var;

	sFBVar.xoffset = 0;
	sFBVar.yoffset = psBuffer->ulYOffset;

	ulYResVirtual = psBuffer->ulYOffset + sFBVar.yres;

	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);
	}

	console_unlock();
}
/* 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();
}
示例#11
0
/* 565RLE image format: [count(2 bytes), rle(2 bytes)] */
int load_565rle_image(char *filename, bool bf_supported)
{
	struct fb_info *info;
	int fd, count, err = 0;
	unsigned max;
	unsigned short *data, *bits, *ptr;
#ifndef CONFIG_FRAMEBUFFER_CONSOLE
	struct module *owner;
#endif
	int pad;

	info = registered_fb[0];
	if (!info) {
		printk(KERN_WARNING "%s: Can not access framebuffer\n",
			__func__);
		return -ENODEV;
	}
#ifndef CONFIG_FRAMEBUFFER_CONSOLE
	owner = info->fbops->owner;
	if (!try_module_get(owner))
		return -ENODEV;
	if (info->fbops->fb_open && info->fbops->fb_open(info, 0)) {
		module_put(owner);
		return -ENODEV;
	}
#endif

	fd = sys_open(filename, O_RDONLY, 0);
	if (fd < 0) {
		printk(KERN_WARNING "%s: Can not open %s\n",
			__func__, filename);
		return -ENOENT;
	}
	count = sys_lseek(fd, (off_t)0, 2);
	if (count <= 0) {
		err = -EIO;
		goto err_logo_close_file;
	}
	sys_lseek(fd, (off_t)0, 0);
	data = kmalloc(count, GFP_KERNEL);
	if (!data) {
		printk(KERN_WARNING "%s: Can not alloc data\n", __func__);
		err = -ENOMEM;
		goto err_logo_close_file;
	}
	if (sys_read(fd, (char *)data, count) != count) {
		err = -EIO;
		goto err_logo_free_data;
	}

	max = fb_width(info) * fb_height(info);
	ptr = data;
	if (bf_supported && (info->node == 1 || info->node == 2)) {
		err = -EPERM;
		pr_err("%s:%d no info->creen_base on fb%d!\n",
		       __func__, __LINE__, info->node);
		goto err_logo_free_data;
	}
	if (info->screen_base) {
		bits = (unsigned short *)(info->screen_base);
		while (count > 3) {
			unsigned n = ptr[0];
			if (n > max)
				break;
			if (info->var.bits_per_pixel >= 24) {
				pad = memset16_rgb8888(bits, ptr[1], n << 1, info);
				bits += n << 1;
				bits += pad;
			} else {
			memset16(bits, ptr[1], n << 1);
			bits += n;
			}
			max -= n;
			ptr += 2;
			count -= 4;
		}
	}
#ifndef CONFIG_FRAMEBUFFER_CONSOLE
	err = fb_pan_display(info, &info->var);
	if (err < 0) {
		printk(KERN_WARNING "%s: Can not update framebuffer\n",
		__func__);
		return -ENODEV;
	}
#endif

err_logo_free_data:
	kfree(data);
err_logo_close_file:
	sys_close(fd);
	return err;
}
示例#12
0
void OMAPLFBFlip(OMAPLFB_DEVINFO *psDevInfo, OMAPLFB_BUFFER *psBuffer)
{
	struct fb_var_screeninfo sFBVar;
	int res;
	unsigned long ulYResVirtual;

	OMAPLFB_CONSOLE_LOCK();

	sFBVar = psDevInfo->psLINFBInfo->var;

	sFBVar.xoffset = 0;
	sFBVar.yoffset = psBuffer->ulYOffset;

	ulYResVirtual = psBuffer->ulYOffset + sFBVar.yres;

#if defined(CONFIG_DSSCOMP)
	{
		
		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 = 1,
					.global_alpha = 255,
				},
			},
		};

		
		struct tiler_pa_info *pas[] = { NULL };

		d.ovls[0].ba = sFBFix.smem_start;
		omapfb_mode_to_dss_mode(&sFBVar, &d.ovls[0].cfg.color_mode);

		res = dsscomp_gralloc_queue(&d, pas, true, NULL, NULL);
	}
#else 
	
#if !defined(PVR_OMAPLFB_DONT_USE_FB_PAN_DISPLAY)
	
	if (sFBVar.xres_virtual != sFBVar.xres || sFBVar.yres_virtual < ulYResVirtual)
#endif 
	{
		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 
#endif 

	OMAPLFB_CONSOLE_UNLOCK();
}
示例#13
0
static unsigned char *fb_init_driver(unsigned char *param, unsigned char *ignore)
{
	unsigned char *e;
	struct stat st;
	int rs;
	unsigned long ul;

	TTY = 0;
	EINTRLOOP(rs, ioctl(TTY,VT_GETMODE, &vt_omode));
	if (rs == -1) {
		TTY = 1;
		EINTRLOOP(rs, ioctl(TTY,VT_GETMODE, &vt_omode));
		if (rs == -1) {
			TTY = 0;
		}
	}

	kbd_set_raw = 1;
	fb_old_vd = NULL;
	fb_driver_param=NULL;
	if(param != NULL)
		fb_driver_param=stracpy(param);

	border_left = border_right = border_top = border_bottom = 0;
	if (!param) param=cast_uchar "";
	if (*param) {
		if (*param < '0' || *param > '9') {
			bad_p:
			if(fb_driver_param) { mem_free(fb_driver_param); fb_driver_param=NULL; }
			return stracpy(cast_uchar "-mode syntax is left_border[,top_border[,right_border[,bottom_border]]]\n");
		}
		ul = strtoul(cast_const_char param, (char **)(void *)&param, 10);
		if (ul > MAXINT / 10) goto bad_p;
		border_left = (int)ul;
		if (*param == ',') param++;
	} else {
		border_left = 0;
	}
	if (*param) {
		if (*param < '0' || *param > '9') goto bad_p;
		ul = strtoul(cast_const_char param, (char **)(void *)&param, 10);
		if (ul > MAXINT / 10) goto bad_p;
		border_top = (int)ul;
		if (*param == ',') param++;
	} else {
		border_top = border_left;
	}
	if (*param) {
		if (*param < '0' || *param > '9') goto bad_p;
		ul = strtoul(cast_const_char param, (char **)(void *)&param, 10);
		if (ul > MAXINT / 10) goto bad_p;
		border_right = (int)ul;
		if (*param == ',') param++;
	} else {
		border_right = border_left;
	}
	if (*param) {
		if (*param < '0' || *param > '9') goto bad_p;
		ul = strtoul(cast_const_char param, (char **)(void *)&param, 10);
		if (ul > MAXINT / 10) goto bad_p;
		border_bottom = (int)ul;
		if (*param == ',') param++;
	} else {
		border_bottom = border_top;
	}
	if (*param) goto bad_p;

	EINTRLOOP(rs, fstat(TTY, &st));
	if (rs) {
		if(fb_driver_param) { mem_free(fb_driver_param); fb_driver_param=NULL; }
		return stracpy(cast_uchar "Cannon stat stdin.\n");
	}

	fb_console = (int)(st.st_rdev & 0xff);

	fb_hide_cursor();

	if ((e = fb_switch_init())) {
		if(fb_driver_param) { mem_free(fb_driver_param); fb_driver_param=NULL; }
		fb_show_cursor();
		return e;
	}

	EINTRLOOP(fb_handle, open("/dev/fb0", O_RDWR));
	if (fb_handle==-1) {
		fb_switch_shutdown();
		if(fb_driver_param) { mem_free(fb_driver_param); fb_driver_param=NULL; }
		fb_show_cursor();
		return stracpy(cast_uchar "Cannot open /dev/fb0.\n");
	}

	EINTRLOOP(rs, ioctl(fb_handle, FBIOGET_VSCREENINFO, &vi));
	if (rs==-1)
	{
		EINTRLOOP(rs, close(fb_handle));
		fb_switch_shutdown();
		if(fb_driver_param) { mem_free(fb_driver_param); fb_driver_param=NULL; }
		fb_show_cursor();
		return stracpy(cast_uchar "Cannot get FB VSCREENINFO.\n");
	}

	/*oldmode=vi;*/

	EINTRLOOP(rs, ioctl(fb_handle, FBIOGET_FSCREENINFO, &fi));
	if (rs==-1)
	{
		EINTRLOOP(rs, close(fb_handle));
		fb_switch_shutdown();
		if(fb_driver_param) { mem_free(fb_driver_param); fb_driver_param=NULL; }
		fb_show_cursor();
		return stracpy(cast_uchar "Cannot get FB FSCREENINFO.\n");
	}

	fb_xsize=vi.xres;
	fb_ysize=vi.yres;
	fb_bits_pp=vi.bits_per_pixel;
	if (fb_bits_pp == 16 && vi.green.length == 5) fb_bits_pp = 15;

	if (fb_xsize <= border_left + border_right) border_left = border_right = 0;
	fb_xsize -= border_left + border_right;
	if (fb_ysize <= border_top + border_bottom) border_top = border_bottom = 0;
	fb_ysize -= border_top + border_bottom;

	fb_driver.x=fb_xsize;
	fb_driver.y=fb_ysize;

	switch(fb_bits_pp)
	{
		case 4:
		fb_pixelsize=1;
		fb_palette_colors=16;
		break;

		case 8:
		fb_pixelsize=1;
		fb_palette_colors=256;
		break;

		case 15:
		case 16:
		fb_pixelsize=2;
		fb_palette_colors=64;
		break;

		case 24:
		fb_palette_colors=256;
		fb_pixelsize=3;
		break;

		case 32:
		fb_palette_colors=256;
		fb_pixelsize=4;
		fb_bits_pp=24;
		break;

		default:
		EINTRLOOP(rs, close(fb_handle));
		fb_switch_shutdown();
		if(fb_driver_param) { mem_free(fb_driver_param); fb_driver_param=NULL; }
		fb_show_cursor();
		return stracpy(cast_uchar "Unknown bit depth");
	}
	fb_colors=1<<fb_bits_pp;

	/* we must pan before setting palette */
	fb_pan_display();

	have_cmap = 0;
	if (fi.visual==FB_VISUAL_PSEUDOCOLOR && fb_colors <= 0x1000000) /* set palette */
	{
		have_cmap=1;
		fb_palette_colors=fb_colors;
		alloc_palette(&old_palette);
		get_palette(&old_palette);

		alloc_palette(&global_pal);
		generate_palette(&global_pal);
		set_palette(&global_pal);
	}
	if (fi.visual==FB_VISUAL_DIRECTCOLOR) /* set pseudo palette */
	{
		have_cmap=2;
		alloc_palette(&old_palette);
		get_palette(&old_palette);

		alloc_palette(&global_pal);
		generate_palette(&global_pal);
		set_palette(&global_pal);
	}

	fb_linesize=fi.line_length;
	fb_mem_size=fi.smem_len;

	if (init_virtual_devices(&fb_driver, NUMBER_OF_DEVICES)){
		fb_shutdown_palette();
		EINTRLOOP(rs, close(fb_handle));
		fb_switch_shutdown();
		if(fb_driver_param) { mem_free(fb_driver_param); fb_driver_param=NULL; }
		fb_show_cursor();
		return stracpy(cast_uchar "Allocation of virtual devices failed.\n");
	}
	fb_kbd = handle_svgalib_keyboard(fb_key_in);

	/* Mikulas: nechodi to na sparcu */
	if (fb_mem_size < (unsigned)((border_top + fb_ysize + border_bottom) * fb_linesize))
	{
		fb_shutdown_palette();
		svgalib_free_trm(fb_kbd);
		shutdown_virtual_devices();
		EINTRLOOP(rs, close(fb_handle));
		fb_switch_shutdown();
		if(fb_driver_param) { mem_free(fb_driver_param); fb_driver_param=NULL; }
		fb_show_cursor();
		return stracpy(cast_uchar "Nonlinear mapping of graphics memory not supported.\n");
	}

	if (vi.nonstd) {
		fb_shutdown_palette();
		svgalib_free_trm(fb_kbd);
		shutdown_virtual_devices();
		EINTRLOOP(rs, close(fb_handle));
		fb_switch_shutdown();
		if(fb_driver_param) { mem_free(fb_driver_param); fb_driver_param=NULL; }
		fb_show_cursor();
		return stracpy(cast_uchar "Non-standard pixel format.\n");
	}

	fb_driver.flags |= GD_DONT_USE_SCROLL;
#ifdef USE_FB_ACCEL
	need_accel_sync = 0;
	EINTRLOOP(rs, ioctl(fb_handle, FBIO_ACCEL_SUPPORT));
	if (rs < 0) {
		accel_flags = 0;
		/*debug("accel not supported");*/
	} else {
		accel_flags = rs;
		/*debug("accel supported, flags %x", accel_flags);*/
	}
	if (fb_bits_pp != 8)
		accel_flags &= ~(FB_ACCEL_FILLRECT_SUPPORTED | FB_ACCEL_FILLRECT_ACCELERATED);
	if (accel_flags & FB_ACCEL_COPYAREA_ACCELERATED)
		fb_driver.flags &= ~GD_DONT_USE_SCROLL;
#endif

	/*
	 * Some framebuffer implementations (for example Mach64) on Sparc64 hate
	 * partial framebuffer mappings.
	 *
	 * For others, we can save virtual memory space by doing a partial mmap.
	 */
	fb_mapped_size = (border_top + fb_ysize + border_bottom) * fb_linesize;
retry1:
	if ((fb_mem=mmap(0,fb_mapped_size,PROT_READ|PROT_WRITE,MAP_SHARED,fb_handle,0))==MAP_FAILED) {
		if (errno == EINTR) goto retry1;
		fb_mapped_size = fb_mem_size;
retry2:
		if ((fb_mem=mmap(0,fb_mapped_size,PROT_READ|PROT_WRITE,MAP_SHARED,fb_handle,0))==MAP_FAILED) {
			if (errno == EINTR) goto retry2;
			fb_shutdown_palette();
			svgalib_free_trm(fb_kbd);
			shutdown_virtual_devices();

			EINTRLOOP(rs, close(fb_handle));
			fb_switch_shutdown();
			if(fb_driver_param) { mem_free(fb_driver_param); fb_driver_param=NULL; }
			fb_show_cursor();
			return stracpy(cast_uchar "Cannot mmap graphics memory.\n");
		}
	}
	fb_vmem = fb_mem + border_left * fb_pixelsize + border_top * fb_linesize;
	fb_driver.depth=fb_pixelsize&7;
	fb_driver.depth|=(fb_bits_pp&31)<<3;
	if (htonl(0x12345678) == 0x12345678) {
		/* Big endian */
		if (fb_driver.depth == 130 || fb_driver.depth == 122) fb_driver.depth |= 1 << 8;
		else if (fb_driver.depth == 196) fb_driver.depth |= 1 << 9;
	}

	fb_driver.get_color=get_color_fn(fb_driver.depth);
	if (!fb_driver.get_color) {
		fb_shutdown_palette();
		svgalib_free_trm(fb_kbd);
		shutdown_virtual_devices();

		EINTRLOOP(rs, close(fb_handle));
		fb_switch_shutdown();
		if(fb_driver_param) { mem_free(fb_driver_param); fb_driver_param=NULL; }
		fb_show_cursor();
		return stracpy(cast_uchar "Unknown bit format.\n");
	}
	install_signal_handler(SIGINT, (void (*)(void *))fb_ctrl_c, fb_kbd, 0);

	/* mouse */
	mouse_buffer=mem_alloc(fb_pixelsize*arrow_area);
	background_buffer=mem_alloc(fb_pixelsize*arrow_area);
	new_background_buffer=mem_alloc(fb_pixelsize*arrow_area);
	background_x=mouse_x=fb_xsize>>1;
	background_y=mouse_y=fb_ysize>>1;
	mouse_black=fb_driver.get_color(0);
	mouse_white=fb_driver.get_color(0xffffff);
	mouse_graphics_device=fb_driver.init_device();
	virtual_devices[0] = NULL;
	global_mouse_hidden=1;
	last_mouse_buttons = B_MOVE;
	if (handle_fb_mouse()) {
		fb_driver.shutdown_device(mouse_graphics_device);
		mem_free(mouse_buffer);
		mem_free(background_buffer);
		mem_free(new_background_buffer);
		fb_shutdown_palette();
		svgalib_free_trm(fb_kbd);
		shutdown_virtual_devices();

		EINTRLOOP(rs, close(fb_handle));
		fb_switch_shutdown();
		if(fb_driver_param) { mem_free(fb_driver_param); fb_driver_param=NULL; }
		fb_show_cursor();
		return stracpy(cast_uchar "Cannot open GPM mouse.\n");
	}
	/* hide cursor */
	if (border_left | border_top | border_right | border_bottom) fb_clear_videoram();

	show_mouse();

	END_GR

	return NULL;
}
static
void DC_FBDEV_ContextConfigure(IMG_HANDLE hDisplayContext,
								   IMG_UINT32 ui32PipeCount,
								   PVRSRV_SURFACE_CONFIG_INFO *pasSurfAttrib,
								   IMG_HANDLE *ahBuffers,
								   IMG_UINT32 ui32DisplayPeriod,
								   IMG_HANDLE hConfigData)
{
	DC_FBDEV_CONTEXT *psDeviceContext = hDisplayContext;
	DC_FBDEV_DEVICE *psDeviceData = psDeviceContext->psDeviceData;
	struct fb_var_screeninfo sVar = psDeviceData->psLINFBInfo->var;
	int err;

	PVR_UNREFERENCED_PARAMETER(ui32PipeCount);
	PVR_UNREFERENCED_PARAMETER(pasSurfAttrib);
	PVR_UNREFERENCED_PARAMETER(ui32DisplayPeriod);

	if(psDeviceContext->hLastConfigData)
		DCDisplayConfigurationRetired(psDeviceContext->hLastConfigData);

	sVar.yoffset = 0;

	if(ui32PipeCount == 0)
	{
		/* If the pipe count is zero, we're tearing down. Don't record
		 * any new configurations, but still allow the display to pan
		 * back to buffer 0.
		 */
		psDeviceContext->hLastConfigData = IMG_NULL;

		/*
			We still need to "retire" this NULL flip as that signals back to
			the DC core that we've finished doing what we need to do
			and it can destroy the display context
		*/
		DCDisplayConfigurationRetired(hConfigData);
	}
	else
	{
		BUG_ON(ahBuffers == IMG_NULL);

		if(psDeviceData->bCanFlip)
		{
			DC_FBDEV_BUFFER *psBuffer = ahBuffers[0];
			sVar.yoffset = sVar.yres * psBuffer->ui32BufferID;
		}

		psDeviceContext->hLastConfigData = hConfigData;
	}

	/* MTK: set BGRA */
	sVar.bits_per_pixel = 32;
	sVar.transp.offset  = 24;
	sVar.transp.length  = 8;
	sVar.red.offset     = 16;
	sVar.red.length     = 8;
	sVar.green.offset   = 8;
	sVar.green.length   = 8;
	sVar.blue.offset    = 0;
	sVar.blue.length    = 8;

	if(lock_fb_info(psDeviceData->psLINFBInfo))
	{
		console_lock();

		/* If we're supposed to be able to flip, but the yres_virtual
		 * has been changed to an unsupported (smaller) value, we need
		 * to change it back (this is a workaround for some Linux fbdev
		 * drivers that seem to lose any modifications to yres_virtual
		 * after a blank.)
		 */
		if(psDeviceData->bCanFlip &&
		   sVar.yres_virtual < sVar.yres * NUM_PREFERRED_BUFFERS)
		{
			sVar.activate = FB_ACTIVATE_NOW;
			sVar.yres_virtual = sVar.yres * NUM_PREFERRED_BUFFERS;

			err = fb_set_var(psDeviceData->psLINFBInfo, &sVar);
			if(err)
				pr_err("fb_set_var failed (err=%d)\n", err);
		}
		else
		{
			err = fb_pan_display(psDeviceData->psLINFBInfo, &sVar);
			if(err)
				pr_err("fb_pan_display failed (err=%d)\n", err);
		}

		console_unlock();
		unlock_fb_info(psDeviceData->psLINFBInfo);
	}
}