// SPDX-License-Identifier: GPL-2.0-only
/*
 * 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
 */

#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 <linux/sizes.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 const 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");
