/*
 * xilinxfb.c
 *
 * Xilinx TFT LCD frame buffer driver
 *
 * Author: MontaVista Software, Inc.
 *         source@mvista.com
 *
 * 2002-2007 (c) MontaVista Software, Inc.  This file is licensed under the
 * terms of the GNU General Public License version 2.  This program is licensed
 * "as is" without any warranty of any kind, whether express or implied.
 */

/*
 * This driver was based on au1100fb.c by MontaVista rewritten for 2.6
 * by Embedded Alley Solutions <source@embeddedalley.com>, which in turn
 * was based on skeletonfb.c, Skeleton for a frame buffer device by
 * Geert Uytterhoeven.
 */

#include <linux/device.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/version.h>
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h>
#include <linux/fb.h>
#include <linux/init.h>
#include <linux/dma-mapping.h>
#include <linux/platform_device.h>

#include <asm/io.h>
#include <linux/xilinxfb.h>

#define DRIVER_NAME		"xilinxfb"
#define DRIVER_DESCRIPTION	"Xilinx TFT LCD frame buffer driver"

/*
 * Xilinx calls it "PLB TFT LCD Controller" though it can also be used for
 * the VGA port on the Xilinx ML40x board. This is a hardware display controller
 * for a 640x480 resolution TFT or VGA screen.
 *
 * The interface to the framebuffer is nice and simple.  There are two
 * control registers.  The first tells the LCD interface where in memory
 * the frame buffer is (only the 11 most significant bits are used, so
 * don't start thinking about scrolling).  The second allows the LCD to
 * be turned on or off as well as rotated 180 degrees.
 */
#define NUM_REGS	2
#define REG_FB_ADDR	0
#define REG_CTRL	1
#define REG_CTRL_ENABLE	 0x0001
#define REG_CTRL_ROTATE	 0x0002

/*
 * The hardware only handles a single mode: 640x480 24 bit true
 * color. Each pixel gets a word (32 bits) of memory.  Within each word,
 * the 8 most significant bits are ignored, the next 8 bits are the red
 * level, the next 8 bits are the green level and the 8 least
 * significant bits are the blue level.  Each row of the LCD uses 1024
 * words, but only the first 640 pixels are displayed with the other 384
 * words being ignored.  There are 480 rows.
 */
#define BYTES_PER_PIXEL	4
#define BITS_PER_PIXEL	(BYTES_PER_PIXEL * 8)
#define XRES		640
#define YRES		480
#define XRES_VIRTUAL	1024
#define YRES_VIRTUAL	YRES
#define LINE_LENGTH	(XRES_VIRTUAL * BYTES_PER_PIXEL)
#define FB_SIZE		(YRES_VIRTUAL * LINE_LENGTH)

#define RED_SHIFT	16
#define GREEN_SHIFT	8
#define BLUE_SHIFT	0

#define PALETTE_ENTRIES_NO	16	/* passed to fb_alloc_cmap() */

/*
 * Here are the default fb_fix_screeninfo and fb_var_screeninfo structures
 */
static struct fb_fix_screeninfo xilinx_fb_fix = {
	.id =		"Xilinx",
	.type =		FB_TYPE_PACKED_PIXELS,
	.visual =	FB_VISUAL_TRUECOLOR,
	.smem_len =	FB_SIZE,
	.line_length =	LINE_LENGTH,
	.accel =	FB_ACCEL_NONE
};

static struct fb_var_screeninfo xilinx_fb_var = {
	.xres =			XRES,
	.yres =			YRES,
	.xres_virtual =		XRES_VIRTUAL,
	.yres_virtual =		YRES_VIRTUAL,

	.bits_per_pixel =	BITS_PER_PIXEL,

	.red =		{ RED_SHIFT, 8, 0 },
	.green =	{ GREEN_SHIFT, 8, 0 },
	.blue =		{ BLUE_SHIFT, 8, 0 },
	.transp =	{ 0, 0, 0 },

	.activate =	FB_ACTIVATE_NOW
};

struct xilinxfb_drvdata {

	struct fb_info	info;		/* FB driver info record */

	u32		regs_phys;	/* phys. address of the control registers */
	u32 __iomem	*regs;		/* virt. address of the control registers */

	unsigned char __iomem	*fb_virt;	/* virt. address of the frame buffer */
	dma_addr_t	fb_phys;	/* phys. address of the frame buffer */

	u32		reg_ctrl_default;

	u32		pseudo_palette[PALETTE_ENTRIES_NO];
					/* Fake palette of 16 colors */
};

#define to_xilinxfb_drvdata(_info) \
	container_of(_info, struct xilinxfb_drvdata, info)

/*
 * The LCD controller has DCR interface to its registers, but all
 * the boards and configurations the driver has been tested with
 * use opb2dcr bridge. So the registers are seen as memory mapped.
 * This macro is to make it simple to add the direct DCR access
 * when it's needed.
 */
#define xilinx_fb_out_be32(driverdata, offset, val) \
	out_be32(driverdata->regs + offset, val)

static int
xilinx_fb_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue,
	unsigned transp, struct fb_info *fbi)
{
	u32 *palette = fbi->pseudo_palette;

	if (regno >= PALETTE_ENTRIES_NO)
		return -EINVAL;

	if (fbi->var.grayscale) {
		/* Convert color to grayscale.
		 * grayscale = 0.30*R + 0.59*G + 0.11*B */
		red = green = blue =
			(red * 77 + green * 151 + blue * 28 + 127) >> 8;
	}

	/* fbi->fix.visual is always FB_VISUAL_TRUECOLOR */

	/* We only handle 8 bits of each color. */
	red >>= 8;
	green >>= 8;
	blue >>= 8;
	palette[regno] = (red << RED_SHIFT) | (green << GREEN_SHIFT) |
			 (blue << BLUE_SHIFT);

	return 0;
}

static int
xilinx_fb_blank(int blank_mode, struct fb_info *fbi)
{
	struct xilinxfb_drvdata *drvdata = to_xilinxfb_drvdata(fbi);

	switch (blank_mode) {
	case FB_BLANK_UNBLANK:
		/* turn on panel */
		xilinx_fb_out_be32(drvdata, REG_CTRL, drvdata->reg_ctrl_default);
		break;

	case FB_BLANK_NORMAL:
	case FB_BLANK_VSYNC_SUSPEND:
	case FB_BLANK_HSYNC_SUSPEND:
	case FB_BLANK_POWERDOWN:
		/* turn off panel */
		xilinx_fb_out_be32(drvdata, REG_CTRL, 0);
	default:
		break;

	}
	return 0; /* success */
}

static struct fb_ops xilinxfb_ops =
{
	.owner			= THIS_MODULE,
	.fb_setcolreg		= xilinx_fb_setcolreg,
	.fb_blank		= xilinx_fb_blank,
	.fb_fillrect		= cfb_fillrect,
	.fb_copyarea		= cfb_copyarea,
	.fb_imageblit		= cfb_imageblit,
};

/* === The device driver === */

static int
xilinxfb_drv_probe(struct device *dev)
{
	struct platform_device *pdev;
	struct xilinxfb_platform_data *pdata;
	struct xilinxfb_drvdata *drvdata;
	struct resource *regs_res;
	int retval;

	if (!dev)
		return -EINVAL;

	pdev = to_platform_device(dev);
	pdata = pdev->dev.platform_data;

	drvdata = kzalloc(sizeof(*drvdata), GFP_KERNEL);
	if (!drvdata) {
		dev_err(dev, "Couldn't allocate device private record\n");
		return -ENOMEM;
	}
	dev_set_drvdata(dev, drvdata);

	/* Map the control registers in */
	regs_res = platform_get_resource(pdev, IORESOURCE_IO, 0);
	if (!regs_res || (regs_res->end - regs_res->start + 1 < 8)) {
		dev_err(dev, "Couldn't get registers resource\n");
		retval = -EFAULT;
		goto err_region;
	}

	if (!request_mem_region(regs_res->start, 8, DRIVER_NAME)) {
		dev_err(dev, "Couldn't lock memory region at 0x%08X\n",
		       regs_res->start);
		retval = -EBUSY;
		goto err_region;
	}
	drvdata->regs = (u32 __iomem*) ioremap(regs_res->start, 8);
	drvdata->regs_phys = regs_res->start;

	/* Allocate the framebuffer memory */
	drvdata->fb_virt = dma_alloc_coherent(dev, PAGE_ALIGN(FB_SIZE),
				&drvdata->fb_phys, GFP_KERNEL);
	if (!drvdata->fb_virt) {
		dev_err(dev, "Could not allocate frame buffer memory\n");
		retval = -ENOMEM;
		goto err_fbmem;
	}

	/* Clear (turn to black) the framebuffer */
	memset_io((void *) drvdata->fb_virt, 0, FB_SIZE);

	/* Tell the hardware where the frame buffer is */
	xilinx_fb_out_be32(drvdata, REG_FB_ADDR, drvdata->fb_phys);

	/* Turn on the display */
	drvdata->reg_ctrl_default = REG_CTRL_ENABLE;
	if (pdata && pdata->rotate_screen)
		drvdata->reg_ctrl_default |= REG_CTRL_ROTATE;
	xilinx_fb_out_be32(drvdata, REG_CTRL, drvdata->reg_ctrl_default);

	/* Fill struct fb_info */
	drvdata->info.device = dev;
	drvdata->info.screen_base = drvdata->fb_virt;
	drvdata->info.fbops = &xilinxfb_ops;
	drvdata->info.fix = xilinx_fb_fix;
	drvdata->info.fix.smem_start = drvdata->fb_phys;
	drvdata->info.pseudo_palette = drvdata->pseudo_palette;

	if (fb_alloc_cmap(&drvdata->info.cmap, PALETTE_ENTRIES_NO, 0) < 0) {
		dev_err(dev, "Fail to allocate colormap (%d entries)\n",
			PALETTE_ENTRIES_NO);
		retval = -EFAULT;
		goto err_cmap;
	}

	drvdata->info.flags = FBINFO_DEFAULT;
	if (pdata) {
		xilinx_fb_var.height = pdata->screen_height_mm;
		xilinx_fb_var.width = pdata->screen_width_mm;
	}
	drvdata->info.var = xilinx_fb_var;

	/* Register new frame buffer */
	if (register_framebuffer(&drvdata->info) < 0) {
		dev_err(dev, "Could not register frame buffer\n");
		retval = -EINVAL;
		goto err_regfb;
	}

	/* Put a banner in the log (for DEBUG) */
	dev_dbg(dev, "regs: phys=%x, virt=%p\n",
		drvdata->regs_phys, drvdata->regs);
	dev_dbg(dev, "fb: phys=%p, virt=%p, size=%x\n",
		(void*)drvdata->fb_phys, drvdata->fb_virt, FB_SIZE);
	return 0;	/* success */

err_regfb:
	fb_dealloc_cmap(&drvdata->info.cmap);

err_cmap:
	dma_free_coherent(dev, PAGE_ALIGN(FB_SIZE), drvdata->fb_virt,
		drvdata->fb_phys);

	/* Turn off the display */
	xilinx_fb_out_be32(drvdata, REG_CTRL, 0);
	iounmap(drvdata->regs);

err_fbmem:
	release_mem_region(regs_res->start, 8);

err_region:
	kfree(drvdata);
	dev_set_drvdata(dev, NULL);

	return retval;
}

static int
xilinxfb_drv_remove(struct device *dev)
{
	struct xilinxfb_drvdata *drvdata;

	if (!dev)
		return -ENODEV;

	drvdata = (struct xilinxfb_drvdata *) dev_get_drvdata(dev);

#if !defined(CONFIG_FRAMEBUFFER_CONSOLE) && defined(CONFIG_LOGO)
	xilinx_fb_blank(VESA_POWERDOWN, &drvdata->info);
#endif

	unregister_framebuffer(&drvdata->info);

	fb_dealloc_cmap(&drvdata->info.cmap);

	dma_free_coherent(dev, PAGE_ALIGN(FB_SIZE), drvdata->fb_virt,
		drvdata->fb_phys);

	/* Turn off the display */
	xilinx_fb_out_be32(drvdata, REG_CTRL, 0);
	iounmap(drvdata->regs);

	release_mem_region(drvdata->regs_phys, 8);

	kfree(drvdata);
	dev_set_drvdata(dev, NULL);

	return 0;
}


static struct device_driver xilinxfb_driver = {
	.name		= DRIVER_NAME,
	.bus		= &platform_bus_type,

	.probe		= xilinxfb_drv_probe,
	.remove		= xilinxfb_drv_remove
};

static int __init
xilinxfb_init(void)
{
	/*
	 * No kernel boot options used,
	 * so we just need to register the driver
	 */
	return driver_register(&xilinxfb_driver);
}

static void __exit
xilinxfb_cleanup(void)
{
	driver_unregister(&xilinxfb_driver);
}

module_init(xilinxfb_init);
module_exit(xilinxfb_cleanup);

MODULE_AUTHOR("MontaVista Software, Inc. <source@mvista.com>");
MODULE_DESCRIPTION(DRIVER_DESCRIPTION);
MODULE_LICENSE("GPL");
