/*
 *  linux/drivers/video/mbx/mbxfb.c
 *
 *  Copyright (C) 2006 8D Technologies inc
 *  Raphael Assenat <raph@8d.com>
 *  	- Added video overlay support
 *  	- Various improvements
 *
 *  Copyright (C) 2006 Compulab, Ltd.
 *  Mike Rapoport <mike@compulab.co.il>
 *  	- Creation of driver
 *
 *   Based on pxafb.c
 *
 * This file is subject to the terms and conditions of the GNU General Public
 * License.  See the file COPYING in the main directory of this archive for
 * more details.
 *
 *   Intel 2700G (Marathon) Graphics Accelerator Frame Buffer Driver
 *
 */

#include <linux/delay.h>
#include <linux/fb.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/uaccess.h>

#include <asm/io.h>

#include <video/mbxfb.h>

#include "regs.h"
#include "reg_bits.h"

static unsigned long virt_base_2700;

#define write_reg(val, reg) do { writel((val), (reg)); } while(0)

/* Without this delay, the graphics appears somehow scaled and
 * there is a lot of jitter in scanlines. This delay is probably
 * needed only after setting some specific register(s) somewhere,
 * not all over the place... */
#define write_reg_dly(val, reg) do { writel((val), reg); udelay(1000); } while(0)

#define MIN_XRES	16
#define MIN_YRES	16
#define MAX_XRES	2048
#define MAX_YRES	2048

#define MAX_PALETTES	16

/* FIXME: take care of different chip revisions with different sizes
   of ODFB */
#define MEMORY_OFFSET	0x60000

struct mbxfb_info {
	struct device *dev;

	struct resource *fb_res;
	struct resource *fb_req;

	struct resource *reg_res;
	struct resource *reg_req;

	void __iomem *fb_virt_addr;
	unsigned long fb_phys_addr;

	void __iomem *reg_virt_addr;
	unsigned long reg_phys_addr;

	int (*platform_probe) (struct fb_info * fb);
	int (*platform_remove) (struct fb_info * fb);

	u32 pseudo_palette[MAX_PALETTES];
#ifdef CONFIG_FB_MBX_DEBUG
	void *debugfs_data;
#endif

};

static struct fb_var_screeninfo mbxfb_default __devinitdata = {
	.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_TEST,
	.height = -1,
	.width = -1,
	.pixclock = 40000,
	.left_margin = 48,
	.right_margin = 16,
	.upper_margin = 33,
	.lower_margin = 10,
	.hsync_len = 96,
	.vsync_len = 2,
	.vmode = FB_VMODE_NONINTERLACED,
	.sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
};

static struct fb_fix_screeninfo mbxfb_fix  __devinitdata = {
	.id = "MBX",
	.type = FB_TYPE_PACKED_PIXELS,
	.visual = FB_VISUAL_TRUECOLOR,
	.xpanstep = 0,
	.ypanstep = 0,
	.ywrapstep = 0,
	.accel = FB_ACCEL_NONE,
};

struct pixclock_div {
	u8 m;
	u8 n;
	u8 p;
};

static unsigned int mbxfb_get_pixclock(unsigned int pixclock_ps,
				       struct pixclock_div *div)
{
	u8 m, n, p;
	unsigned int err = 0;
	unsigned int min_err = ~0x0;
	unsigned int clk;
	unsigned int best_clk = 0;
	unsigned int ref_clk = 13000;	/* FIXME: take from platform data */
	unsigned int pixclock;

	/* convert pixclock to KHz */
	pixclock = PICOS2KHZ(pixclock_ps);

	/* PLL output freq = (ref_clk * M) / (N * 2^P)
	 *
	 * M: 1 to 63
	 * N: 1 to 7
	 * P: 0 to 7
	 */

	/* RAPH: When N==1, the resulting pixel clock appears to
	 * get divided by 2. Preventing N=1 by starting the following
	 * loop at 2 prevents this. Is this a bug with my chip
	 * revision or something I dont understand? */
	for (m = 1; m < 64; m++) {
		for (n = 2; n < 8; n++) {
			for (p = 0; p < 8; p++) {
				clk = (ref_clk * m) / (n * (1 << p));
				err = (clk > pixclock) ? (clk - pixclock) :
					(pixclock - clk);
				if (err < min_err) {
					min_err = err;
					best_clk = clk;
					div->m = m;
					div->n = n;
					div->p = p;
				}
			}
		}
	}
	return KHZ2PICOS(best_clk);
}

static int mbxfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
			   u_int trans, struct fb_info *info)
{
	u32 val, ret = 1;

	if (regno < MAX_PALETTES) {
		u32 *pal = info->pseudo_palette;

		val = (red & 0xf800) | ((green & 0xfc00) >> 5) |
			((blue & 0xf800) >> 11);
		pal[regno] = val;
		ret = 0;
	}

	return ret;
}

static int mbxfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
{
	struct pixclock_div div;

	var->pixclock = mbxfb_get_pixclock(var->pixclock, &div);

	if (var->xres < MIN_XRES)
		var->xres = MIN_XRES;
	if (var->yres < MIN_YRES)
		var->yres = MIN_YRES;
	if (var->xres > MAX_XRES)
		return -EINVAL;
	if (var->yres > MAX_YRES)
		return -EINVAL;
	var->xres_virtual = max(var->xres_virtual, var->xres);
	var->yres_virtual = max(var->yres_virtual, var->yres);

	switch (var->bits_per_pixel) {
		/* 8 bits-per-pixel is not supported yet */
	case 8:
		return -EINVAL;
	case 16:
		var->green.length = (var->green.length == 5) ? 5 : 6;
		var->red.length = 5;
		var->blue.length = 5;
		var->transp.length = 6 - var->green.length;
		var->blue.offset = 0;
		var->green.offset = 5;
		var->red.offset = 5 + var->green.length;
		var->transp.offset = (5 + var->red.offset) & 15;
		break;
	case 24:		/* RGB 888   */
	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.length = var->bits_per_pixel - 24;
		var->transp.offset = (var->transp.length) ? 24 : 0;
		break;
	}
	var->red.msb_right = 0;
	var->green.msb_right = 0;
	var->blue.msb_right = 0;
	var->transp.msb_right = 0;

	return 0;
}

static int mbxfb_set_par(struct fb_info *info)
{
	struct fb_var_screeninfo *var = &info->var;
	struct pixclock_div div;
	ushort hbps, ht, hfps, has;
	ushort vbps, vt, vfps, vas;
	u32 gsctrl = readl(GSCTRL);
	u32 gsadr = readl(GSADR);

	info->fix.line_length = var->xres_virtual * var->bits_per_pixel / 8;

	/* setup color mode */
	gsctrl &= ~(FMsk(GSCTRL_GPIXFMT));
	/* FIXME: add *WORKING* support for 8-bits per color */
	if (info->var.bits_per_pixel == 8) {
		return -EINVAL;
	} else {
		fb_dealloc_cmap(&info->cmap);
		gsctrl &= ~GSCTRL_LUT_EN;

		info->fix.visual = FB_VISUAL_TRUECOLOR;
		switch (info->var.bits_per_pixel) {
		case 16:
			if (info->var.green.length == 5)
				gsctrl |= GSCTRL_GPIXFMT_ARGB1555;
			else
				gsctrl |= GSCTRL_GPIXFMT_RGB565;
			break;
		case 24:
			gsctrl |= GSCTRL_GPIXFMT_RGB888;
			break;
		case 32:
			gsctrl |= GSCTRL_GPIXFMT_ARGB8888;
			break;
		}
	}

	/* setup resolution */
	gsctrl &= ~(FMsk(GSCTRL_GSWIDTH) | FMsk(GSCTRL_GSHEIGHT));
	gsctrl |= Gsctrl_Width(info->var.xres) |
		Gsctrl_Height(info->var.yres);
	write_reg_dly(gsctrl, GSCTRL);

	gsadr &= ~(FMsk(GSADR_SRCSTRIDE));
	gsadr |= Gsadr_Srcstride(info->var.xres * info->var.bits_per_pixel /
				 (8 * 16) - 1);
	write_reg_dly(gsadr, GSADR);

	/* setup timings */
	var->pixclock = mbxfb_get_pixclock(info->var.pixclock, &div);

	write_reg_dly((Disp_Pll_M(div.m) | Disp_Pll_N(div.n) |
		Disp_Pll_P(div.p) | DISP_PLL_EN), DISPPLL);

	hbps = var->hsync_len;
	has = hbps + var->left_margin;
	hfps = has + var->xres;
	ht = hfps + var->right_margin;

	vbps = var->vsync_len;
	vas = vbps + var->upper_margin;
	vfps = vas + var->yres;
	vt = vfps + var->lower_margin;

	write_reg_dly((Dht01_Hbps(hbps) | Dht01_Ht(ht)), DHT01);
	write_reg_dly((Dht02_Hlbs(has) | Dht02_Has(has)), DHT02);
	write_reg_dly((Dht03_Hfps(hfps) | Dht03_Hrbs(hfps)), DHT03);
	write_reg_dly((Dhdet_Hdes(has) | Dhdet_Hdef(hfps)), DHDET);

	write_reg_dly((Dvt01_Vbps(vbps) | Dvt01_Vt(vt)), DVT01);
	write_reg_dly((Dvt02_Vtbs(vas) | Dvt02_Vas(vas)), DVT02);
	write_reg_dly((Dvt03_Vfps(vfps) | Dvt03_Vbbs(vfps)), DVT03);
	write_reg_dly((Dvdet_Vdes(vas) | Dvdet_Vdef(vfps)), DVDET);
	write_reg_dly((Dvectrl_Vevent(vfps) | Dvectrl_Vfetch(vbps)), DVECTRL);

	write_reg_dly((readl(DSCTRL) | DSCTRL_SYNCGEN_EN), DSCTRL);

	write_reg_dly(DINTRE_VEVENT0_EN, DINTRE);

	return 0;
}

static int mbxfb_blank(int blank, struct fb_info *info)
{
	switch (blank) {
	case FB_BLANK_POWERDOWN:
	case FB_BLANK_VSYNC_SUSPEND:
	case FB_BLANK_HSYNC_SUSPEND:
	case FB_BLANK_NORMAL:
		write_reg_dly((readl(DSCTRL) & ~DSCTRL_SYNCGEN_EN), DSCTRL);
		write_reg_dly((readl(PIXCLK) & ~PIXCLK_EN), PIXCLK);
		write_reg_dly((readl(VOVRCLK) & ~VOVRCLK_EN), VOVRCLK);
		break;
	case FB_BLANK_UNBLANK:
		write_reg_dly((readl(DSCTRL) | DSCTRL_SYNCGEN_EN), DSCTRL);
		write_reg_dly((readl(PIXCLK) | PIXCLK_EN), PIXCLK);
		break;
	}
	return 0;
}

static int mbxfb_setupOverlay(struct mbxfb_overlaySetup *set)
{
	u32 vsctrl, vbbase, vscadr, vsadr;
	u32 sssize, spoctrl, svctrl, shctrl;
	u32 vubase, vvbase;
	u32 vovrclk;

	if (set->scaled_width==0 || set->scaled_height==0)
		return -EINVAL;

	/* read registers which have reserved bits
	 * so we can write them back as-is. */
	vovrclk = readl(VOVRCLK);
	vsctrl = readl(VSCTRL);
	vscadr = readl(VSCADR);
	vubase = readl(VUBASE);
	vvbase = readl(VVBASE);

	spoctrl = readl(SPOCTRL);
	sssize = readl(SSSIZE);


	vbbase = Vbbase_Glalpha(set->alpha);

	vsctrl &= ~(	FMsk(VSCTRL_VSWIDTH) |
					FMsk(VSCTRL_VSHEIGHT) |
					FMsk(VSCTRL_VPIXFMT) |
					VSCTRL_GAMMA_EN | VSCTRL_CSC_EN |
					VSCTRL_COSITED );
	vsctrl |= Vsctrl_Width(set->width) | Vsctrl_Height(set->height) |
				VSCTRL_CSC_EN;

	vscadr &= ~(VSCADR_STR_EN | VSCADR_COLKEY_EN | VSCADR_COLKEYSRC |
				FMsk(VSCADR_BLEND_M) | FMsk(VSCADR_BLEND_POS) |
				FMsk(VSCADR_VBASE_ADR) );
	vubase &= ~(VUBASE_UVHALFSTR | FMsk(VUBASE_UBASE_ADR));
	vvbase &= ~(FMsk(VVBASE_VBASE_ADR));

	switch (set->fmt)
	{
		case MBXFB_FMT_YUV12:
			vsctrl |= VSCTRL_VPIXFMT_YUV12;

			set->Y_stride = ((set->width) + 0xf ) & ~0xf;

			break;
		case MBXFB_FMT_UY0VY1:
			vsctrl |= VSCTRL_VPIXFMT_UY0VY1;
			set->Y_stride = (set->width*2 + 0xf ) & ~0xf;
			break;
		case MBXFB_FMT_VY0UY1:
			vsctrl |= VSCTRL_VPIXFMT_VY0UY1;
			set->Y_stride = (set->width*2 + 0xf ) & ~0xf;
			break;
		case MBXFB_FMT_Y0UY1V:
			vsctrl |= VSCTRL_VPIXFMT_Y0UY1V;
			set->Y_stride = (set->width*2 + 0xf ) & ~0xf;
			break;
		case MBXFB_FMT_Y0VY1U:
			vsctrl |= VSCTRL_VPIXFMT_Y0VY1U;
			set->Y_stride = (set->width*2 + 0xf ) & ~0xf;
			break;
		default:
			return -EINVAL;
	}

	/* VSCTRL has the bits which sets the Video Pixel Format.
	 * When passing from a packed to planar format,
	 * if we write VSCTRL first, VVBASE and VUBASE would
	 * be zero if we would not set them here. (And then,
	 * the chips hangs and only a reset seems to fix it).
	 *
	 * If course, the values calculated here have no meaning
	 * for packed formats.
	 */
	set->UV_stride = ((set->width/2) + 0x7 ) & ~0x7;
		set->U_offset = set->height * set->Y_stride;
		set->V_offset = set->U_offset +
						set->height * set->UV_stride;
	vubase |= Vubase_Ubase_Adr(
			(0x60000 + set->mem_offset + set->U_offset)>>3);
	vvbase |= Vvbase_Vbase_Adr(
			(0x60000 + set->mem_offset + set->V_offset)>>3);


	vscadr |= VSCADR_BLEND_VID | VSCADR_BLEND_GLOB |
		Vscadr_Vbase_Adr((0x60000 + set->mem_offset)>>4);

	if (set->enable)
		vscadr |= VSCADR_STR_EN;


	vsadr = Vsadr_Srcstride((set->Y_stride)/16-1) |
		Vsadr_Xstart(set->x) | Vsadr_Ystart(set->y);

	sssize &= ~(FMsk(SSSIZE_SC_WIDTH) | FMsk(SSSIZE_SC_HEIGHT));
	sssize = Sssize_Sc_Width(set->scaled_width-1) |
			Sssize_Sc_Height(set->scaled_height-1);

	spoctrl &= ~(SPOCTRL_H_SC_BP | SPOCTRL_V_SC_BP |
			SPOCTRL_HV_SC_OR | SPOCTRL_VS_UR_C |
			FMsk(SPOCTRL_VORDER) | FMsk(SPOCTRL_VPITCH));
	spoctrl = Spoctrl_Vpitch((set->height<<11)/set->scaled_height)
							| SPOCTRL_VORDER_2TAP;

	/* Bypass horiz/vert scaler when same size */
	if (set->scaled_width == set->width)
		spoctrl |= SPOCTRL_H_SC_BP;
	if (set->scaled_height == set->height)
		spoctrl |= SPOCTRL_V_SC_BP;

	svctrl = Svctrl_Initial1(1<<10) | Svctrl_Initial2(1<<10);

	shctrl = Shctrl_Hinitial(4<<11)
			| Shctrl_Hpitch((set->width<<11)/set->scaled_width);

	/* Video plane registers */
	write_reg(vsctrl, VSCTRL);
	write_reg(vbbase, VBBASE);
	write_reg(vscadr, VSCADR);
	write_reg(vubase, VUBASE);
	write_reg(vvbase, VVBASE);
	write_reg(vsadr, VSADR);

	/* Video scaler registers */
	write_reg(sssize, SSSIZE);
	write_reg(spoctrl, SPOCTRL);
	write_reg(svctrl, SVCTRL);
	write_reg(shctrl, SHCTRL);

	/* RAPH: Using those coefficients, the scaled
	 * image is quite blurry. I dont know how
	 * to improve them ; The chip documentation
	 * was not helpful.. */
	write_reg(0x21212121, VSCOEFF0);
	write_reg(0x21212121, VSCOEFF1);
	write_reg(0x21212121, VSCOEFF2);
	write_reg(0x21212121, VSCOEFF3);
	write_reg(0x21212121, VSCOEFF4);
	write_reg(0x00000000, HSCOEFF0);
	write_reg(0x00000000, HSCOEFF1);
	write_reg(0x00000000, HSCOEFF2);
	write_reg(0x03020201, HSCOEFF3);
	write_reg(0x09070604, HSCOEFF4);
	write_reg(0x0f0e0c0a, HSCOEFF5);
	write_reg(0x15141211, HSCOEFF6);
	write_reg(0x19181716, HSCOEFF7);
	write_reg(0x00000019, HSCOEFF8);

	/* Clock */
	if (set->enable)
		vovrclk |= 1;
	else
		vovrclk &= ~1;

	write_reg(vovrclk, VOVRCLK);

	return 0;
}

static int mbxfb_ioctl(struct fb_info *info, unsigned int cmd,
				unsigned long arg)
{
	struct mbxfb_overlaySetup setup;
	int res;

	if (cmd == MBXFB_IOCX_OVERLAY)
	{
		if (copy_from_user(&setup, (void __user*)arg,
					sizeof(struct mbxfb_overlaySetup)))
			return -EFAULT;

		res = mbxfb_setupOverlay(&setup);
		if (res)
			return res;

		if (copy_to_user((void __user*)arg, &setup,
					sizeof(struct mbxfb_overlaySetup)))
			return -EFAULT;

		return 0;
	}
	return -EINVAL;
}

static struct fb_ops mbxfb_ops = {
	.owner = THIS_MODULE,
	.fb_check_var = mbxfb_check_var,
	.fb_set_par = mbxfb_set_par,
	.fb_setcolreg = mbxfb_setcolreg,
	.fb_fillrect = cfb_fillrect,
	.fb_copyarea = cfb_copyarea,
	.fb_imageblit = cfb_imageblit,
	.fb_blank = mbxfb_blank,
	.fb_ioctl = mbxfb_ioctl,
};

/*
  Enable external SDRAM controller. Assume that all clocks are active
  by now.
*/
static void __devinit setup_memc(struct fb_info *fbi)
{
	unsigned long tmp;
	int i;

	/* FIXME: use platfrom specific parameters */
	/* setup SDRAM controller */
	write_reg_dly((LMCFG_LMC_DS | LMCFG_LMC_TS | LMCFG_LMD_TS |
		LMCFG_LMA_TS),
	       LMCFG);

	write_reg_dly(LMPWR_MC_PWR_ACT, LMPWR);

	/* setup SDRAM timings */
	write_reg_dly((Lmtim_Tras(7) | Lmtim_Trp(3) | Lmtim_Trcd(3) |
		Lmtim_Trc(9) | Lmtim_Tdpl(2)),
	       LMTIM);
	/* setup SDRAM refresh rate */
	write_reg_dly(0xc2b, LMREFRESH);
	/* setup SDRAM type parameters */
	write_reg_dly((LMTYPE_CASLAT_3 | LMTYPE_BKSZ_2 | LMTYPE_ROWSZ_11 |
		LMTYPE_COLSZ_8),
	       LMTYPE);
	/* enable memory controller */
	write_reg_dly(LMPWR_MC_PWR_ACT, LMPWR);

	/* perform dummy reads */
	for ( i = 0; i < 16; i++ ) {
		tmp = readl(fbi->screen_base);
	}
}

static void enable_clocks(struct fb_info *fbi)
{
	/* enable clocks */
	write_reg_dly(SYSCLKSRC_PLL_2, SYSCLKSRC);
	write_reg_dly(PIXCLKSRC_PLL_1, PIXCLKSRC);
	write_reg_dly(0x00000000, CLKSLEEP);

	/* PLL output = (Frefclk * M) / (N * 2^P )
	 *
	 * M: 0x17, N: 0x3, P: 0x0 == 100 Mhz!
	 * M: 0xb, N: 0x1, P: 0x1 == 71 Mhz
	 * */
	write_reg_dly((Core_Pll_M(0xb) | Core_Pll_N(0x1) | Core_Pll_P(0x1) |
		CORE_PLL_EN),
	       COREPLL);

	write_reg_dly((Disp_Pll_M(0x1b) | Disp_Pll_N(0x7) | Disp_Pll_P(0x1) |
		DISP_PLL_EN),
	       DISPPLL);

	write_reg_dly(0x00000000, VOVRCLK);
	write_reg_dly(PIXCLK_EN, PIXCLK);
	write_reg_dly(MEMCLK_EN, MEMCLK);
	write_reg_dly(0x00000006, M24CLK);
	write_reg_dly(0x00000006, MBXCLK);
	write_reg_dly(SDCLK_EN, SDCLK);
	write_reg_dly(0x00000001, PIXCLKDIV);
}

static void __devinit setup_graphics(struct fb_info *fbi)
{
	unsigned long gsctrl;

	gsctrl = GSCTRL_GAMMA_EN | Gsctrl_Width(fbi->var.xres) |
		Gsctrl_Height(fbi->var.yres);
	switch (fbi->var.bits_per_pixel) {
	case 16:
		if (fbi->var.green.length == 5)
			gsctrl |= GSCTRL_GPIXFMT_ARGB1555;
		else
			gsctrl |= GSCTRL_GPIXFMT_RGB565;
		break;
	case 24:
		gsctrl |= GSCTRL_GPIXFMT_RGB888;
		break;
	case 32:
		gsctrl |= GSCTRL_GPIXFMT_ARGB8888;
		break;
	}

	write_reg_dly(gsctrl, GSCTRL);
	write_reg_dly(0x00000000, GBBASE);
	write_reg_dly(0x00ffffff, GDRCTRL);
	write_reg_dly((GSCADR_STR_EN | Gscadr_Gbase_Adr(0x6000)), GSCADR);
	write_reg_dly(0x00000000, GPLUT);
}

static void __devinit setup_display(struct fb_info *fbi)
{
	unsigned long dsctrl = 0;

	dsctrl = DSCTRL_BLNK_POL;
	if (fbi->var.sync & FB_SYNC_HOR_HIGH_ACT)
		dsctrl |= DSCTRL_HS_POL;
	if (fbi->var.sync & FB_SYNC_VERT_HIGH_ACT)
		dsctrl |= DSCTRL_VS_POL;
	write_reg_dly(dsctrl, DSCTRL);
	write_reg_dly(0xd0303010, DMCTRL);
	write_reg_dly((readl(DSCTRL) | DSCTRL_SYNCGEN_EN), DSCTRL);
}

static void __devinit enable_controller(struct fb_info *fbi)
{
	write_reg_dly(SYSRST_RST, SYSRST);


	enable_clocks(fbi);
	setup_memc(fbi);
	setup_graphics(fbi);
	setup_display(fbi);
}

#ifdef CONFIG_PM
/*
 * Power management hooks.  Note that we won't be called from IRQ context,
 * unlike the blank functions above, so we may sleep.
 */
static int mbxfb_suspend(struct platform_device *dev, pm_message_t state)
{
	/* make frame buffer memory enter self-refresh mode */
	write_reg_dly(LMPWR_MC_PWR_SRM, LMPWR);
	while (LMPWRSTAT != LMPWRSTAT_MC_PWR_SRM)
		; /* empty statement */

	/* reset the device, since it's initial state is 'mostly sleeping' */
	write_reg_dly(SYSRST_RST, SYSRST);
	return 0;
}

static int mbxfb_resume(struct platform_device *dev)
{
	struct fb_info *fbi = platform_get_drvdata(dev);

	enable_clocks(fbi);
/* 	setup_graphics(fbi); */
/* 	setup_display(fbi); */

	write_reg_dly((readl(DSCTRL) | DSCTRL_SYNCGEN_EN), DSCTRL);
	return 0;
}
#else
#define mbxfb_suspend	NULL
#define mbxfb_resume	NULL
#endif

/* debugfs entries */
#ifndef CONFIG_FB_MBX_DEBUG
#define mbxfb_debugfs_init(x)	do {} while(0)
#define mbxfb_debugfs_remove(x)	do {} while(0)
#endif

#define res_size(_r) (((_r)->end - (_r)->start) + 1)

static int __devinit mbxfb_probe(struct platform_device *dev)
{
	int ret;
	struct fb_info *fbi;
	struct mbxfb_info *mfbi;
	struct mbxfb_platform_data *pdata;

	dev_dbg(dev, "mbxfb_probe\n");

	pdata = dev->dev.platform_data;
	if (!pdata) {
		dev_err(&dev->dev, "platform data is required\n");
		return -EINVAL;
	}

	fbi = framebuffer_alloc(sizeof(struct mbxfb_info), &dev->dev);
	if (fbi == NULL) {
		dev_err(&dev->dev, "framebuffer_alloc failed\n");
		return -ENOMEM;
	}

	mfbi = fbi->par;
	fbi->pseudo_palette = mfbi->pseudo_palette;


	if (pdata->probe)
		mfbi->platform_probe = pdata->probe;
	if (pdata->remove)
		mfbi->platform_remove = pdata->remove;

	mfbi->fb_res = platform_get_resource(dev, IORESOURCE_MEM, 0);
	mfbi->reg_res = platform_get_resource(dev, IORESOURCE_MEM, 1);

	if (!mfbi->fb_res || !mfbi->reg_res) {
		dev_err(&dev->dev, "no resources found\n");
		ret = -ENODEV;
		goto err1;
	}

	mfbi->fb_req = request_mem_region(mfbi->fb_res->start,
					  res_size(mfbi->fb_res), dev->name);
	if (mfbi->fb_req == NULL) {
		dev_err(&dev->dev, "failed to claim framebuffer memory\n");
		ret = -EINVAL;
		goto err1;
	}
	mfbi->fb_phys_addr = mfbi->fb_res->start;

	mfbi->reg_req = request_mem_region(mfbi->reg_res->start,
					   res_size(mfbi->reg_res), dev->name);
	if (mfbi->reg_req == NULL) {
		dev_err(&dev->dev, "failed to claim Marathon registers\n");
		ret = -EINVAL;
		goto err2;
	}
	mfbi->reg_phys_addr = mfbi->reg_res->start;

	mfbi->reg_virt_addr = ioremap_nocache(mfbi->reg_phys_addr,
					      res_size(mfbi->reg_req));
	if (!mfbi->reg_virt_addr) {
		dev_err(&dev->dev, "failed to ioremap Marathon registers\n");
		ret = -EINVAL;
		goto err3;
	}
	virt_base_2700 = (unsigned long)mfbi->reg_virt_addr;

	mfbi->fb_virt_addr = ioremap_nocache(mfbi->fb_phys_addr,
					     res_size(mfbi->fb_req));
	if (!mfbi->reg_virt_addr) {
		dev_err(&dev->dev, "failed to ioremap frame buffer\n");
		ret = -EINVAL;
		goto err4;
	}

	fbi->screen_base = (char __iomem *)(mfbi->fb_virt_addr + 0x60000);
	fbi->screen_size = pdata->memsize;
	fbi->fbops = &mbxfb_ops;

	fbi->var = mbxfb_default;
	fbi->fix = mbxfb_fix;
	fbi->fix.smem_start = mfbi->fb_phys_addr + 0x60000;
	fbi->fix.smem_len = pdata->memsize;
	fbi->fix.line_length = mbxfb_default.xres_virtual *
					mbxfb_default.bits_per_pixel / 8;

	ret = fb_alloc_cmap(&fbi->cmap, 256, 0);
	if (ret < 0) {
		dev_err(&dev->dev, "fb_alloc_cmap failed\n");
		ret = -EINVAL;
		goto err5;
	}

	platform_set_drvdata(dev, fbi);

	printk(KERN_INFO "fb%d: mbx frame buffer device\n", fbi->node);

	if (mfbi->platform_probe)
		mfbi->platform_probe(fbi);

	enable_controller(fbi);

	mbxfb_debugfs_init(fbi);

	ret = register_framebuffer(fbi);
	if (ret < 0) {
		dev_err(&dev->dev, "register_framebuffer failed\n");
		ret = -EINVAL;
		goto err6;
	}

	return 0;

err6:
	fb_dealloc_cmap(&fbi->cmap);
err5:
	iounmap(mfbi->fb_virt_addr);
err4:
	iounmap(mfbi->reg_virt_addr);
err3:
	release_mem_region(mfbi->reg_res->start, res_size(mfbi->reg_res));
err2:
	release_mem_region(mfbi->fb_res->start, res_size(mfbi->fb_res));
err1:
	framebuffer_release(fbi);

	return ret;
}

static int __devexit mbxfb_remove(struct platform_device *dev)
{
	struct fb_info *fbi = platform_get_drvdata(dev);

	write_reg_dly(SYSRST_RST, SYSRST);

	mbxfb_debugfs_remove(fbi);

	if (fbi) {
		struct mbxfb_info *mfbi = fbi->par;

		unregister_framebuffer(fbi);
		if (mfbi) {
			if (mfbi->platform_remove)
				mfbi->platform_remove(fbi);

			if (mfbi->fb_virt_addr)
				iounmap(mfbi->fb_virt_addr);
			if (mfbi->reg_virt_addr)
				iounmap(mfbi->reg_virt_addr);
			if (mfbi->reg_req)
				release_mem_region(mfbi->reg_req->start,
						   res_size(mfbi->reg_req));
			if (mfbi->fb_req)
				release_mem_region(mfbi->fb_req->start,
						   res_size(mfbi->fb_req));
		}
		framebuffer_release(fbi);
	}

	return 0;
}

static struct platform_driver mbxfb_driver = {
	.probe = mbxfb_probe,
	.remove = mbxfb_remove,
	.suspend = mbxfb_suspend,
	.resume = mbxfb_resume,
	.driver = {
		.name = "mbx-fb",
	},
};

int __devinit mbxfb_init(void)
{
	return platform_driver_register(&mbxfb_driver);
}

static void __devexit mbxfb_exit(void)
{
	platform_driver_unregister(&mbxfb_driver);
}

module_init(mbxfb_init);
module_exit(mbxfb_exit);

MODULE_DESCRIPTION("loadable framebuffer driver for Marathon device");
MODULE_AUTHOR("Mike Rapoport, Compulab");
MODULE_LICENSE("GPL");
