/*
 * Frame Buffer Driver for PKUnity-v3 Unigfx
 * Code specific to PKUnity SoC and UniCore ISA
 *
 *	Maintained by GUAN Xue-tao <gxt@mprc.pku.edu.cn>
 *	Copyright (C) 2001-2010 Guan Xuetao
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/platform_device.h>
#include <linux/clk.h>
#include <linux/fb.h>
#include <linux/init.h>
#include <linux/console.h>
#include <linux/mm.h>

#include <asm/sizes.h>
#include <asm/pgtable.h>
#include <mach/hardware.h>

/* Platform_data reserved for unifb registers. */
#define UNIFB_REGS_NUM		10
/* RAM reserved for the frame buffer. */
#define UNIFB_MEMSIZE		(SZ_4M)		/* 4 MB for 1024*768*32b */

/*
 * cause UNIGFX don not have EDID
 * all the modes are organized as follow
 */
static const struct fb_videomode unifb_modes[] = {
	/* 0 640x480-60 VESA */
	{ "640x480@60",  60,  640, 480,  25175000,  48, 16, 34, 10,  96, 1,
	  0, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
	/* 1 640x480-75 VESA */
	{ "640x480@75",  75,  640, 480,  31500000, 120, 16, 18,  1,  64, 1,
	  0, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
	/* 2 800x600-60 VESA */
	{ "800x600@60",  60,  800, 600,  40000000,  88, 40, 26,  1, 128, 1,
	  0, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
	/* 3 800x600-75 VESA */
	{ "800x600@75",  75,  800, 600,  49500000, 160, 16, 23,  1,  80, 1,
	  0, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
	/* 4 1024x768-60 VESA */
	{ "1024x768@60", 60, 1024, 768,  65000000, 160, 24, 34,  3, 136, 1,
	  0, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
	/* 5 1024x768-75 VESA */
	{ "1024x768@75", 75, 1024, 768,  78750000, 176, 16, 30,  1,  96, 1,
	  0, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
	/* 6 1280x960-60 VESA */
	{ "1280x960@60", 60, 1280, 960, 108000000, 312, 96, 38,  1, 112, 1,
	  0, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
	/* 7 1440x900-60 VESA */
	{ "1440x900@60", 60, 1440, 900, 106500000, 232, 80, 30,  3, 152, 1,
	  0, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
	/* 8 FIXME 9 1024x600-60 VESA UNTESTED */
	{ "1024x600@60", 60, 1024, 600,  50650000, 160, 24, 26,  1, 136, 1,
	  0, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
	/* 9 FIXME 10 1024x600-75 VESA UNTESTED */
	{ "1024x600@75", 75, 1024, 600,  61500000, 176, 16, 23,  1,  96, 1,
	  0, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
	/* 10 FIXME 11 1366x768-60 VESA UNTESTED */
	{ "1366x768@60", 60, 1366, 768,  85500000, 256, 58, 18,  1,  112, 3,
	  0, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
};

static const struct fb_var_screeninfo unifb_default = {
	.xres =		640,
	.yres =		480,
	.xres_virtual =	640,
	.yres_virtual =	480,
	.bits_per_pixel = 16,
	.red =		{ 11, 5, 0 },
	.green =	{ 5,  6, 0 },
	.blue =		{ 0,  5, 0 },
	.activate =	FB_ACTIVATE_NOW,
	.height =	-1,
	.width =	-1,
	.pixclock =	25175000,
	.left_margin =	48,
	.right_margin =	16,
	.upper_margin =	33,
	.lower_margin =	10,
	.hsync_len =	96,
	.vsync_len =	2,
	.vmode =	FB_VMODE_NONINTERLACED,
};

static struct fb_fix_screeninfo unifb_fix = {
	.id =		"UNIGFX FB",
	.type =		FB_TYPE_PACKED_PIXELS,
	.visual =	FB_VISUAL_TRUECOLOR,
	.xpanstep =	1,
	.ypanstep =	1,
	.ywrapstep =	1,
	.accel =	FB_ACCEL_NONE,
};

static void unifb_sync(struct fb_info *info)
{
	/* TODO: may, this can be replaced by interrupt */
	int cnt;

	for (cnt = 0; cnt < 0x10000000; cnt++) {
		if (readl(UGE_COMMAND) & 0x1000000)
			return;
	}

	if (cnt > 0x8000000)
		dev_warn(info->device, "Warning: UniGFX GE time out ...\n");
}

static void unifb_prim_fillrect(struct fb_info *info,
				const struct fb_fillrect *region)
{
	int awidth = region->width;
	int aheight = region->height;
	int m_iBpp = info->var.bits_per_pixel;
	int screen_width = info->var.xres;
	int src_sel = 1;	/* from fg_color */
	int pat_sel = 1;
	int src_x0 = 0;
	int dst_x0 = region->dx;
	int src_y0 = 0;
	int dst_y0 = region->dy;
	int rop_alpha_sel = 0;
	int rop_alpha_code = 0xCC;
	int x_dir = 1;
	int y_dir = 1;
	int alpha_r = 0;
	int alpha_sel = 0;
	int dst_pitch = screen_width * (m_iBpp / 8);
	int dst_offset = dst_y0 * dst_pitch + dst_x0 * (m_iBpp / 8);
	int src_pitch = screen_width * (m_iBpp / 8);
	int src_offset = src_y0 * src_pitch + src_x0 * (m_iBpp / 8);
	unsigned int command = 0;
	int clip_region = 0;
	int clip_en = 0;
	int tp_en = 0;
	int fg_color = 0;
	int bottom = info->var.yres - 1;
	int right = info->var.xres - 1;
	int top = 0;

	bottom = (bottom << 16) | right;
	command = (rop_alpha_sel << 26) | (pat_sel << 18) | (src_sel << 16)
		| (x_dir << 20) | (y_dir << 21) | (command << 24)
		| (clip_region << 23) | (clip_en << 22) | (tp_en << 27);
	src_pitch = (dst_pitch << 16) | src_pitch;
	awidth = awidth | (aheight << 16);
	alpha_r = ((rop_alpha_code & 0xff) << 8) | (alpha_r & 0xff)
		| (alpha_sel << 16);
	src_x0 = (src_x0 & 0x1fff) | ((src_y0 & 0x1fff) << 16);
	dst_x0 = (dst_x0 & 0x1fff) | ((dst_y0 & 0x1fff) << 16);
	fg_color = region->color;

	unifb_sync(info);

	writel(((u32 *)(info->pseudo_palette))[fg_color], UGE_FCOLOR);
	writel(0, UGE_BCOLOR);
	writel(src_pitch, UGE_PITCH);
	writel(src_offset, UGE_SRCSTART);
	writel(dst_offset, UGE_DSTSTART);
	writel(awidth, UGE_WIDHEIGHT);
	writel(top, UGE_CLIP0);
	writel(bottom, UGE_CLIP1);
	writel(alpha_r, UGE_ROPALPHA);
	writel(src_x0, UGE_SRCXY);
	writel(dst_x0, UGE_DSTXY);
	writel(command, UGE_COMMAND);
}

static void unifb_fillrect(struct fb_info *info,
		const struct fb_fillrect *region)
{
	struct fb_fillrect modded;
	int vxres, vyres;

	if (info->flags & FBINFO_HWACCEL_DISABLED) {
		sys_fillrect(info, region);
		return;
	}

	vxres = info->var.xres_virtual;
	vyres = info->var.yres_virtual;

	memcpy(&modded, region, sizeof(struct fb_fillrect));

	if (!modded.width || !modded.height ||
	    modded.dx >= vxres || modded.dy >= vyres)
		return;

	if (modded.dx + modded.width > vxres)
		modded.width = vxres - modded.dx;
	if (modded.dy + modded.height > vyres)
		modded.height = vyres - modded.dy;

	unifb_prim_fillrect(info, &modded);
}

static void unifb_prim_copyarea(struct fb_info *info,
				const struct fb_copyarea *area)
{
	int awidth = area->width;
	int aheight = area->height;
	int m_iBpp = info->var.bits_per_pixel;
	int screen_width = info->var.xres;
	int src_sel = 2;	/* from mem */
	int pat_sel = 0;
	int src_x0 = area->sx;
	int dst_x0 = area->dx;
	int src_y0 = area->sy;
	int dst_y0 = area->dy;

	int rop_alpha_sel = 0;
	int rop_alpha_code = 0xCC;
	int x_dir = 1;
	int y_dir = 1;

	int alpha_r = 0;
	int alpha_sel = 0;
	int dst_pitch = screen_width * (m_iBpp / 8);
	int dst_offset = dst_y0 * dst_pitch + dst_x0 * (m_iBpp / 8);
	int src_pitch = screen_width * (m_iBpp / 8);
	int src_offset = src_y0 * src_pitch + src_x0 * (m_iBpp / 8);
	unsigned int command = 0;
	int clip_region = 0;
	int clip_en = 1;
	int tp_en = 0;
	int top = 0;
	int bottom = info->var.yres;
	int right = info->var.xres;
	int fg_color = 0;
	int bg_color = 0;

	if (src_x0 < 0)
		src_x0 = 0;
	if (src_y0 < 0)
		src_y0 = 0;

	if (src_y0 - dst_y0 > 0) {
		y_dir = 1;
	} else {
		y_dir = 0;
		src_offset = (src_y0 + aheight) * src_pitch +
				src_x0 * (m_iBpp / 8);
		dst_offset = (dst_y0 + aheight) * dst_pitch +
				dst_x0 * (m_iBpp / 8);
		src_y0 += aheight;
		dst_y0 += aheight;
	}

	command = (rop_alpha_sel << 26) | (pat_sel << 18) | (src_sel << 16) |
		(x_dir << 20) | (y_dir << 21) | (command << 24) |
		(clip_region << 23) | (clip_en << 22) | (tp_en << 27);
	src_pitch = (dst_pitch << 16) | src_pitch;
	awidth = awidth | (aheight << 16);
	alpha_r = ((rop_alpha_code & 0xff) << 8) | (alpha_r & 0xff) |
		(alpha_sel << 16);
	src_x0 = (src_x0 & 0x1fff) | ((src_y0 & 0x1fff) << 16);
	dst_x0 = (dst_x0 & 0x1fff) | ((dst_y0 & 0x1fff) << 16);
	bottom = (bottom << 16) | right;

	unifb_sync(info);

	writel(src_pitch, UGE_PITCH);
	writel(src_offset, UGE_SRCSTART);
	writel(dst_offset, UGE_DSTSTART);
	writel(awidth, UGE_WIDHEIGHT);
	writel(top, UGE_CLIP0);
	writel(bottom, UGE_CLIP1);
	writel(bg_color, UGE_BCOLOR);
	writel(fg_color, UGE_FCOLOR);
	writel(alpha_r, UGE_ROPALPHA);
	writel(src_x0, UGE_SRCXY);
	writel(dst_x0, UGE_DSTXY);
	writel(command, UGE_COMMAND);
}

static void unifb_copyarea(struct fb_info *info, const struct fb_copyarea *area)
{
	struct fb_copyarea modded;
	u32 vxres, vyres;
	modded.sx = area->sx;
	modded.sy = area->sy;
	modded.dx = area->dx;
	modded.dy = area->dy;
	modded.width = area->width;
	modded.height = area->height;

	if (info->flags & FBINFO_HWACCEL_DISABLED) {
		sys_copyarea(info, area);
		return;
	}

	vxres = info->var.xres_virtual;
	vyres = info->var.yres_virtual;

	if (!modded.width || !modded.height ||
	    modded.sx >= vxres || modded.sy >= vyres ||
	    modded.dx >= vxres || modded.dy >= vyres)
		return;

	if (modded.sx + modded.width > vxres)
		modded.width = vxres - modded.sx;
	if (modded.dx + modded.width > vxres)
		modded.width = vxres - modded.dx;
	if (modded.sy + modded.height > vyres)
		modded.height = vyres - modded.sy;
	if (modded.dy + modded.height > vyres)
		modded.height = vyres - modded.dy;

	unifb_prim_copyarea(info, &modded);
}

static void unifb_imageblit(struct fb_info *info, const struct fb_image *image)
{
	sys_imageblit(info, image);
}

static u_long get_line_length(int xres_virtual, int bpp)
{
	u_long length;

	length = xres_virtual * bpp;
	length = (length + 31) & ~31;
	length >>= 3;
	return length;
}

/*
 *  Setting the video mode has been split into two parts.
 *  First part, xxxfb_check_var, must not write anything
 *  to hardware, it should only verify and adjust var.
 *  This means it doesn't alter par but it does use hardware
 *  data from it to check this var.
 */
static int unifb_check_var(struct fb_var_screeninfo *var,
			 struct fb_info *info)
{
	u_long line_length;

	/*
	 *  FB_VMODE_CONUPDATE and FB_VMODE_SMOOTH_XPAN are equal!
	 *  as FB_VMODE_SMOOTH_XPAN is only used internally
	 */

	if (var->vmode & FB_VMODE_CONUPDATE) {
		var->vmode |= FB_VMODE_YWRAP;
		var->xoffset = info->var.xoffset;
		var->yoffset = info->var.yoffset;
	}

	/*
	 *  Some very basic checks
	 */
	if (!var->xres)
		var->xres = 1;
	if (!var->yres)
		var->yres = 1;
	if (var->xres > var->xres_virtual)
		var->xres_virtual = var->xres;
	if (var->yres > var->yres_virtual)
		var->yres_virtual = var->yres;
	if (var->bits_per_pixel <= 1)
		var->bits_per_pixel = 1;
	else if (var->bits_per_pixel <= 8)
		var->bits_per_pixel = 8;
	else if (var->bits_per_pixel <= 16)
		var->bits_per_pixel = 16;
	else if (var->bits_per_pixel <= 24)
		var->bits_per_pixel = 24;
	else if (var->bits_per_pixel <= 32)
		var->bits_per_pixel = 32;
	else
		return -EINVAL;

	if (var->xres_virtual < var->xoffset + var->xres)
		var->xres_virtual = var->xoffset + var->xres;
	if (var->yres_virtual < var->yoffset + var->yres)
		var->yres_virtual = var->yoffset + var->yres;

	/*
	 *  Memory limit
	 */
	line_length =
	    get_line_length(var->xres_virtual, var->bits_per_pixel);
	if (line_length * var->yres_virtual > UNIFB_MEMSIZE)
		return -ENOMEM;

	/*
	 * Now that we checked it we alter var. The reason being is that the
	 * video mode passed in might not work but slight changes to it might
	 * make it work. This way we let the user know what is acceptable.
	 */
	switch (var->bits_per_pixel) {
	case 1:
	case 8:
		var->red.offset = 0;
		var->red.length = 8;
		var->green.offset = 0;
		var->green.length = 8;
		var->blue.offset = 0;
		var->blue.length = 8;
		var->transp.offset = 0;
		var->transp.length = 0;
		break;
	case 16:		/* RGBA 5551 */
		if (var->transp.length) {
			var->red.offset = 0;
			var->red.length = 5;
			var->green.offset = 5;
			var->green.length = 5;
			var->blue.offset = 10;
			var->blue.length = 5;
			var->transp.offset = 15;
			var->transp.length = 1;
		} else {	/* RGB 565 */
			var->red.offset = 11;
			var->red.length = 5;
			var->green.offset = 5;
			var->green.length = 6;
			var->blue.offset = 0;
			var->blue.length = 5;
			var->transp.offset = 0;
			var->transp.length = 0;
		}
		break;
	case 24:		/* RGB 888 */
		var->red.offset = 0;
		var->red.length = 8;
		var->green.offset = 8;
		var->green.length = 8;
		var->blue.offset = 16;
		var->blue.length = 8;
		var->transp.offset = 0;
		var->transp.length = 0;
		break;
	case 32:		/* RGBA 8888 */
		var->red.offset = 16;
		var->red.length = 8;
		var->green.offset = 8;
		var->green.length = 8;
		var->blue.offset = 0;
		var->blue.length = 8;
		var->transp.offset = 24;
		var->transp.length = 8;
		break;
	}
	var->red.msb_right = 0;
	var->green.msb_right = 0;
	var->blue.msb_right = 0;
	var->transp.msb_right = 0;

	return 0;
}

/*
 * This routine actually sets the video mode. It's in here where we
 * the hardware state info->par and fix which can be affected by the
 * change in par. For this driver it doesn't do much.
 */
static int unifb_set_par(struct fb_info *info)
{
	int hTotal, vTotal, hSyncStart, hSyncEnd, vSyncStart, vSyncEnd;
	int format;

#ifdef CONFIG_PUV3_PM
	struct clk *clk_vga;
	u32 pixclk = 0;
	int i;

	for (i = 0; i <= 10; i++) {
		if    (info->var.xres         == unifb_modes[i].xres
		    && info->var.yres         == unifb_modes[i].yres
		    && info->var.upper_margin == unifb_modes[i].upper_margin
		    && info->var.lower_margin == unifb_modes[i].lower_margin
		    && info->var.left_margin  == unifb_modes[i].left_margin
		    && info->var.right_margin == unifb_modes[i].right_margin
		    && info->var.hsync_len    == unifb_modes[i].hsync_len
		    && info->var.vsync_len    == unifb_modes[i].vsync_len) {
			pixclk = unifb_modes[i].pixclock;
			break;
		}
	}

	/* set clock rate */
	clk_vga = clk_get(info->device, "VGA_CLK");
	if (clk_vga == ERR_PTR(-ENOENT))
		return -ENOENT;

	if (pixclk != 0) {
		if (clk_set_rate(clk_vga, pixclk)) { /* set clock failed */
			info->fix = unifb_fix;
			info->var = unifb_default;
			if (clk_set_rate(clk_vga, unifb_default.pixclock))
				return -EINVAL;
		}
	}
#endif

	info->fix.line_length = get_line_length(info->var.xres_virtual,
						info->var.bits_per_pixel);

	hSyncStart = info->var.xres + info->var.right_margin;
	hSyncEnd = hSyncStart + info->var.hsync_len;
	hTotal = hSyncEnd + info->var.left_margin;

	vSyncStart = info->var.yres + info->var.lower_margin;
	vSyncEnd = vSyncStart + info->var.vsync_len;
	vTotal = vSyncEnd + info->var.upper_margin;

	switch (info->var.bits_per_pixel) {
	case 8:
		format = UDE_CFG_DST8;
		break;
	case 16:
		format = UDE_CFG_DST16;
		break;
	case 24:
		format = UDE_CFG_DST24;
		break;
	case 32:
		format = UDE_CFG_DST32;
		break;
	default:
		return -EINVAL;
	}

	writel(info->fix.smem_start, UDE_FSA);
	writel(info->var.yres, UDE_LS);
	writel(get_line_length(info->var.xres,
			info->var.bits_per_pixel) >> 3, UDE_PS);
			/* >> 3 for hardware required. */
	writel((hTotal << 16) | (info->var.xres), UDE_HAT);
	writel(((hTotal - 1) << 16) | (info->var.xres - 1), UDE_HBT);
	writel(((hSyncEnd - 1) << 16) | (hSyncStart - 1), UDE_HST);
	writel((vTotal << 16) | (info->var.yres), UDE_VAT);
	writel(((vTotal - 1) << 16) | (info->var.yres - 1), UDE_VBT);
	writel(((vSyncEnd - 1) << 16) | (vSyncStart - 1), UDE_VST);
	writel(UDE_CFG_GDEN_ENABLE | UDE_CFG_TIMEUP_ENABLE
			| format | 0xC0000001, UDE_CFG);

	return 0;
}

/*
 *  Set a single color register. The values supplied are already
 *  rounded down to the hardware's capabilities (according to the
 *  entries in the var structure). Return != 0 for invalid regno.
 */
static int unifb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
			 u_int transp, struct fb_info *info)
{
	if (regno >= 256)	/* no. of hw registers */
		return 1;

	/* grayscale works only partially under directcolor */
	if (info->var.grayscale) {
		/* grayscale = 0.30*R + 0.59*G + 0.11*B */
		red = green = blue =
		    (red * 77 + green * 151 + blue * 28) >> 8;
	}

#define CNVT_TOHW(val, width) ((((val)<<(width))+0x7FFF-(val))>>16)
	switch (info->fix.visual) {
	case FB_VISUAL_TRUECOLOR:
	case FB_VISUAL_PSEUDOCOLOR:
		red = CNVT_TOHW(red, info->var.red.length);
		green = CNVT_TOHW(green, info->var.green.length);
		blue = CNVT_TOHW(blue, info->var.blue.length);
		transp = CNVT_TOHW(transp, info->var.transp.length);
		break;
	case FB_VISUAL_DIRECTCOLOR:
		red = CNVT_TOHW(red, 8);	/* expect 8 bit DAC */
		green = CNVT_TOHW(green, 8);
		blue = CNVT_TOHW(blue, 8);
		/* hey, there is bug in transp handling... */
		transp = CNVT_TOHW(transp, 8);
		break;
	}
#undef CNVT_TOHW
	/* Truecolor has hardware independent palette */
	if (info->fix.visual == FB_VISUAL_TRUECOLOR) {
		u32 v;

		if (regno >= 16)
			return 1;

		v = (red << info->var.red.offset) |
		    (green << info->var.green.offset) |
		    (blue << info->var.blue.offset) |
		    (transp << info->var.transp.offset);
		switch (info->var.bits_per_pixel) {
		case 8:
			break;
		case 16:
		case 24:
		case 32:
			((u32 *) (info->pseudo_palette))[regno] = v;
			break;
		default:
			return 1;
		}
		return 0;
	}
	return 0;
}

/*
 *  Pan or Wrap the Display
 *
 *  This call looks only at xoffset, yoffset and the FB_VMODE_YWRAP flag
 */
static int unifb_pan_display(struct fb_var_screeninfo *var,
			   struct fb_info *info)
{
	if (var->vmode & FB_VMODE_YWRAP) {
		if (var->yoffset < 0
		    || var->yoffset >= info->var.yres_virtual
		    || var->xoffset)
			return -EINVAL;
	} else {
		if (var->xoffset + info->var.xres > info->var.xres_virtual ||
		    var->yoffset + info->var.yres > info->var.yres_virtual)
			return -EINVAL;
	}
	info->var.xoffset = var->xoffset;
	info->var.yoffset = var->yoffset;
	if (var->vmode & FB_VMODE_YWRAP)
		info->var.vmode |= FB_VMODE_YWRAP;
	else
		info->var.vmode &= ~FB_VMODE_YWRAP;
	return 0;
}

int unifb_mmap(struct fb_info *info,
		    struct vm_area_struct *vma)
{
	vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);

	return vm_iomap_memory(vma, info->fix.smem_start, info->fix.smem_len);
}

static struct fb_ops unifb_ops = {
	.fb_read        = fb_sys_read,
	.fb_write       = fb_sys_write,
	.fb_check_var	= unifb_check_var,
	.fb_set_par	= unifb_set_par,
	.fb_setcolreg	= unifb_setcolreg,
	.fb_pan_display	= unifb_pan_display,
	.fb_fillrect	= unifb_fillrect,
	.fb_copyarea	= unifb_copyarea,
	.fb_imageblit   = unifb_imageblit,
	.fb_mmap	= unifb_mmap,
};

/*
 *  Initialisation
 */
static int unifb_probe(struct platform_device *dev)
{
	struct fb_info *info;
	u32 unifb_regs[UNIFB_REGS_NUM];
	int retval = -ENOMEM;
	struct resource *iomem;
	void *videomemory;

	videomemory = (void *)__get_free_pages(GFP_KERNEL | __GFP_COMP,
				get_order(UNIFB_MEMSIZE));
	if (!videomemory)
		goto err;

	memset(videomemory, 0, UNIFB_MEMSIZE);

	unifb_fix.smem_start = virt_to_phys(videomemory);
	unifb_fix.smem_len = UNIFB_MEMSIZE;

	iomem = platform_get_resource(dev, IORESOURCE_MEM, 0);
	unifb_fix.mmio_start = iomem->start;

	info = framebuffer_alloc(sizeof(u32)*256, &dev->dev);
	if (!info)
		goto err;

	info->screen_base = (char __iomem *)videomemory;
	info->fbops = &unifb_ops;

	retval = fb_find_mode(&info->var, info, NULL,
			      unifb_modes, 10, &unifb_modes[0], 16);

	if (!retval || (retval == 4))
		info->var = unifb_default;

	info->fix = unifb_fix;
	info->pseudo_palette = info->par;
	info->par = NULL;
	info->flags = FBINFO_FLAG_DEFAULT;
#ifdef FB_ACCEL_PUV3_UNIGFX
	info->fix.accel = FB_ACCEL_PUV3_UNIGFX;
#endif

	retval = fb_alloc_cmap(&info->cmap, 256, 0);
	if (retval < 0)
		goto err1;

	retval = register_framebuffer(info);
	if (retval < 0)
		goto err2;
	platform_set_drvdata(dev, info);
	platform_device_add_data(dev, unifb_regs, sizeof(u32) * UNIFB_REGS_NUM);

	fb_info(info, "Virtual frame buffer device, using %dM of video memory\n",
		UNIFB_MEMSIZE >> 20);
	return 0;
err2:
	fb_dealloc_cmap(&info->cmap);
err1:
	framebuffer_release(info);
err:
	return retval;
}

static int unifb_remove(struct platform_device *dev)
{
	struct fb_info *info = platform_get_drvdata(dev);

	if (info) {
		unregister_framebuffer(info);
		fb_dealloc_cmap(&info->cmap);
		framebuffer_release(info);
	}
	return 0;
}

#ifdef CONFIG_PM
static int unifb_resume(struct platform_device *dev)
{
	int rc = 0;
	u32 *unifb_regs = dev->dev.platform_data;

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

	console_lock();

	if (dev->dev.power.power_state.event == PM_EVENT_SUSPEND) {
		writel(unifb_regs[0], UDE_FSA);
		writel(unifb_regs[1], UDE_LS);
		writel(unifb_regs[2], UDE_PS);
		writel(unifb_regs[3], UDE_HAT);
		writel(unifb_regs[4], UDE_HBT);
		writel(unifb_regs[5], UDE_HST);
		writel(unifb_regs[6], UDE_VAT);
		writel(unifb_regs[7], UDE_VBT);
		writel(unifb_regs[8], UDE_VST);
		writel(unifb_regs[9], UDE_CFG);
	}
	dev->dev.power.power_state = PMSG_ON;

	console_unlock();

	return rc;
}

static int unifb_suspend(struct platform_device *dev, pm_message_t mesg)
{
	u32 *unifb_regs = dev->dev.platform_data;

	unifb_regs[0] = readl(UDE_FSA);
	unifb_regs[1] = readl(UDE_LS);
	unifb_regs[2] = readl(UDE_PS);
	unifb_regs[3] = readl(UDE_HAT);
	unifb_regs[4] = readl(UDE_HBT);
	unifb_regs[5] = readl(UDE_HST);
	unifb_regs[6] = readl(UDE_VAT);
	unifb_regs[7] = readl(UDE_VBT);
	unifb_regs[8] = readl(UDE_VST);
	unifb_regs[9] = readl(UDE_CFG);

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

	switch (mesg.event) {
	case PM_EVENT_FREEZE:		/* about to take snapshot */
	case PM_EVENT_PRETHAW:		/* before restoring snapshot */
		goto done;
	}

	console_lock();

	/* do nothing... */

	console_unlock();

done:
	dev->dev.power.power_state = mesg;

	return 0;
}
#else
#define	unifb_resume	NULL
#define unifb_suspend	NULL
#endif

static struct platform_driver unifb_driver = {
	.probe	 = unifb_probe,
	.remove  = unifb_remove,
	.resume  = unifb_resume,
	.suspend = unifb_suspend,
	.driver  = {
		.name	= "PKUnity-v3-UNIGFX",
	},
};

static int __init unifb_init(void)
{
#ifndef MODULE
	if (fb_get_options("unifb", NULL))
		return -ENODEV;
#endif

	return platform_driver_register(&unifb_driver);
}

module_init(unifb_init);

static void __exit unifb_exit(void)
{
	platform_driver_unregister(&unifb_driver);
}

module_exit(unifb_exit);

MODULE_LICENSE("GPL v2");
