/*
 * linux/drivers/video/hitfb.c -- Hitachi LCD frame buffer device
 *
 * (C) 1999 Mihai Spatar
 * (C) 2000 YAEGASHI Takeshi
 * (C) 2003, 2004 Paul Mundt
 * (C) 2003, 2004, 2006 Andriy Skulysh
 *
 *  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.
 */

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h>
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/fb.h>

#include <asm/machvec.h>
#include <linux/uaccess.h>
#include <asm/io.h>
#include <asm/hd64461.h>
#include <cpu/dac.h>

#define	WIDTH 640

static struct fb_var_screeninfo hitfb_var = {
	.activate	= FB_ACTIVATE_NOW,
	.height		= -1,
	.width		= -1,
	.vmode		= FB_VMODE_NONINTERLACED,
};

static struct fb_fix_screeninfo hitfb_fix = {
	.id		= "Hitachi HD64461",
	.type		= FB_TYPE_PACKED_PIXELS,
	.accel		= FB_ACCEL_NONE,
};

static volatile void __iomem *hitfb_offset_to_addr(unsigned int offset)
{
	return (__force volatile void __iomem *)(uintptr_t)offset;
}

static u16 hitfb_readw(unsigned int offset)
{
	return fb_readw(hitfb_offset_to_addr(offset));
}

static void hitfb_writew(u16 value, unsigned int offset)
{
	fb_writew(value, hitfb_offset_to_addr(offset));
}

static inline void hitfb_accel_wait(void)
{
	while (hitfb_readw(HD64461_GRCFGR) & HD64461_GRCFGR_ACCSTATUS)
		;
}

static inline void hitfb_accel_start(int truecolor)
{
	if (truecolor) {
		hitfb_writew(6, HD64461_GRCFGR);
	} else {
		hitfb_writew(7, HD64461_GRCFGR);
	}
}

static inline void hitfb_accel_set_dest(int truecolor, u16 dx, u16 dy,
					u16 width, u16 height)
{
	u32 saddr = WIDTH * dy + dx;
	if (truecolor)
		saddr <<= 1;

	hitfb_writew(width-1, HD64461_BBTDWR);
	hitfb_writew(height-1, HD64461_BBTDHR);

	hitfb_writew(saddr & 0xffff, HD64461_BBTDSARL);
	hitfb_writew(saddr >> 16, HD64461_BBTDSARH);

}

static inline void hitfb_accel_bitblt(int truecolor, u16 sx, u16 sy, u16 dx,
				      u16 dy, u16 width, u16 height, u16 rop,
				      u32 mask_addr)
{
	u32 saddr, daddr;
	u32 maddr = 0;

	height--;
	width--;
	hitfb_writew(rop, HD64461_BBTROPR);
	if ((sy < dy) || ((sy == dy) && (sx <= dx))) {
		saddr = WIDTH * (sy + height) + sx + width;
		daddr = WIDTH * (dy + height) + dx + width;
		if (mask_addr) {
			if (truecolor)
				maddr = ((width >> 3) + 1) * (height + 1) - 1;
			else
				maddr =
				    (((width >> 4) + 1) * (height + 1) - 1) * 2;

			hitfb_writew((1 << 5) | 1, HD64461_BBTMDR);
		} else
			hitfb_writew(1, HD64461_BBTMDR);
	} else {
		saddr = WIDTH * sy + sx;
		daddr = WIDTH * dy + dx;
		if (mask_addr) {
			hitfb_writew((1 << 5), HD64461_BBTMDR);
		} else {
			hitfb_writew(0, HD64461_BBTMDR);
		}
	}
	if (truecolor) {
		saddr <<= 1;
		daddr <<= 1;
	}
	hitfb_writew(width, HD64461_BBTDWR);
	hitfb_writew(height, HD64461_BBTDHR);
	hitfb_writew(saddr & 0xffff, HD64461_BBTSSARL);
	hitfb_writew(saddr >> 16, HD64461_BBTSSARH);
	hitfb_writew(daddr & 0xffff, HD64461_BBTDSARL);
	hitfb_writew(daddr >> 16, HD64461_BBTDSARH);
	if (mask_addr) {
		maddr += mask_addr;
		hitfb_writew(maddr & 0xffff, HD64461_BBTMARL);
		hitfb_writew(maddr >> 16, HD64461_BBTMARH);
	}
	hitfb_accel_start(truecolor);
}

static void hitfb_fillrect(struct fb_info *p, const struct fb_fillrect *rect)
{
	if (rect->rop != ROP_COPY)
		cfb_fillrect(p, rect);
	else {
		hitfb_accel_wait();
		hitfb_writew(0x00f0, HD64461_BBTROPR);
		hitfb_writew(16, HD64461_BBTMDR);

		if (p->var.bits_per_pixel == 16) {
			hitfb_writew(((u32 *) (p->pseudo_palette))[rect->color],
				  HD64461_GRSCR);
			hitfb_accel_set_dest(1, rect->dx, rect->dy, rect->width,
					     rect->height);
			hitfb_accel_start(1);
		} else {
			hitfb_writew(rect->color, HD64461_GRSCR);
			hitfb_accel_set_dest(0, rect->dx, rect->dy, rect->width,
					     rect->height);
			hitfb_accel_start(0);
		}
	}
}

static void hitfb_copyarea(struct fb_info *p, const struct fb_copyarea *area)
{
	hitfb_accel_wait();
	hitfb_accel_bitblt(p->var.bits_per_pixel == 16, area->sx, area->sy,
			   area->dx, area->dy, area->width, area->height,
			   0x00cc, 0);
}

static int hitfb_pan_display(struct fb_var_screeninfo *var,
			     struct fb_info *info)
{
	int xoffset = var->xoffset;
	int yoffset = var->yoffset;

	if (xoffset != 0)
		return -EINVAL;

	hitfb_writew((yoffset*info->fix.line_length)>>10, HD64461_LCDCBAR);

	return 0;
}

static int hitfb_blank(int blank_mode, struct fb_info *info)
{
	unsigned short v;

	if (blank_mode) {
		v = hitfb_readw(HD64461_LDR1);
		v &= ~HD64461_LDR1_DON;
		hitfb_writew(v, HD64461_LDR1);

		v = hitfb_readw(HD64461_LCDCCR);
		v |= HD64461_LCDCCR_MOFF;
		hitfb_writew(v, HD64461_LCDCCR);

		v = hitfb_readw(HD64461_STBCR);
		v |= HD64461_STBCR_SLCDST;
		hitfb_writew(v, HD64461_STBCR);
	} else {
		v = hitfb_readw(HD64461_STBCR);
		v &= ~HD64461_STBCR_SLCDST;
		hitfb_writew(v, HD64461_STBCR);

		v = hitfb_readw(HD64461_LCDCCR);
		v &= ~(HD64461_LCDCCR_MOFF | HD64461_LCDCCR_STREQ);
		hitfb_writew(v, HD64461_LCDCCR);

		do {
		    v = hitfb_readw(HD64461_LCDCCR);
		} while(v&HD64461_LCDCCR_STBACK);

		v = hitfb_readw(HD64461_LDR1);
		v |= HD64461_LDR1_DON;
		hitfb_writew(v, HD64461_LDR1);
	}
	return 0;
}

static int hitfb_setcolreg(unsigned regno, unsigned red, unsigned green,
			   unsigned blue, unsigned transp, struct fb_info *info)
{
	if (regno >= 256)
		return 1;

	switch (info->var.bits_per_pixel) {
	case 8:
		hitfb_writew(regno << 8, HD64461_CPTWAR);
		hitfb_writew(red >> 10, HD64461_CPTWDR);
		hitfb_writew(green >> 10, HD64461_CPTWDR);
		hitfb_writew(blue >> 10, HD64461_CPTWDR);
		break;
	case 16:
		if (regno >= 16)
			return 1;
		((u32 *) (info->pseudo_palette))[regno] =
		    ((red & 0xf800)) |
		    ((green & 0xfc00) >> 5) | ((blue & 0xf800) >> 11);
		break;
	}
	return 0;
}

static int hitfb_sync(struct fb_info *info)
{
	hitfb_accel_wait();

	return 0;
}

static int hitfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
{
	int maxy;

	var->xres = info->var.xres;
	var->xres_virtual = info->var.xres;
	var->yres = info->var.yres;

	if ((var->bits_per_pixel != 8) && (var->bits_per_pixel != 16))
		var->bits_per_pixel = info->var.bits_per_pixel;

	if (var->yres_virtual < var->yres)
		var->yres_virtual = var->yres;

	maxy = info->fix.smem_len / var->xres;

	if (var->bits_per_pixel == 16)
		maxy /= 2;

	if (var->yres_virtual > maxy)
		var->yres_virtual = maxy;

	var->xoffset = 0;
	var->yoffset = 0;

	switch (var->bits_per_pixel) {
	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:		/* 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;
	}

	return 0;
}

static int hitfb_set_par(struct fb_info *info)
{
	unsigned short ldr3;

	switch (info->var.bits_per_pixel) {
	case 8:
		info->fix.line_length = info->var.xres;
		info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
		info->fix.ypanstep = 16;
		break;
	case 16:
		info->fix.line_length = info->var.xres*2;
		info->fix.visual = FB_VISUAL_TRUECOLOR;
		info->fix.ypanstep = 8;
		break;
	}

	hitfb_writew(info->fix.line_length, HD64461_LCDCLOR);
	ldr3 = hitfb_readw(HD64461_LDR3);
	ldr3 &= ~15;
	ldr3 |= (info->var.bits_per_pixel == 8) ? 4 : 8;
	hitfb_writew(ldr3, HD64461_LDR3);
	return 0;
}

static const struct fb_ops hitfb_ops = {
	.owner		= THIS_MODULE,
	.fb_check_var	= hitfb_check_var,
	.fb_set_par		= hitfb_set_par,
	.fb_setcolreg	= hitfb_setcolreg,
	.fb_blank	= hitfb_blank,
	.fb_sync	= hitfb_sync,
	.fb_pan_display = hitfb_pan_display,
	.fb_fillrect	= hitfb_fillrect,
	.fb_copyarea	= hitfb_copyarea,
	.fb_imageblit	= cfb_imageblit,
};

static int hitfb_probe(struct platform_device *dev)
{
	unsigned short lcdclor, ldr3, ldvndr;
	struct fb_info *info;
	int ret;

	if (fb_get_options("hitfb", NULL))
		return -ENODEV;

	hitfb_fix.mmio_start = HD64461_IO_OFFSET(0x1000);
	hitfb_fix.mmio_len = 0x1000;
	hitfb_fix.smem_start = HD64461_IO_OFFSET(0x02000000);
	hitfb_fix.smem_len = 512 * 1024;

	lcdclor = hitfb_readw(HD64461_LCDCLOR);
	ldvndr = hitfb_readw(HD64461_LDVNDR);
	ldr3 = hitfb_readw(HD64461_LDR3);

	switch (ldr3 & 15) {
	default:
	case 4:
		hitfb_var.bits_per_pixel = 8;
		hitfb_var.xres = lcdclor;
		break;
	case 8:
		hitfb_var.bits_per_pixel = 16;
		hitfb_var.xres = lcdclor / 2;
		break;
	}
	hitfb_fix.line_length = lcdclor;
	hitfb_fix.visual = (hitfb_var.bits_per_pixel == 8) ?
	    FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR;
	hitfb_var.yres = ldvndr + 1;
	hitfb_var.xres_virtual = hitfb_var.xres;
	hitfb_var.yres_virtual = hitfb_fix.smem_len / lcdclor;
	switch (hitfb_var.bits_per_pixel) {
	case 8:
		hitfb_var.red.offset = 0;
		hitfb_var.red.length = 8;
		hitfb_var.green.offset = 0;
		hitfb_var.green.length = 8;
		hitfb_var.blue.offset = 0;
		hitfb_var.blue.length = 8;
		hitfb_var.transp.offset = 0;
		hitfb_var.transp.length = 0;
		break;
	case 16:		/* RGB 565 */
		hitfb_var.red.offset = 11;
		hitfb_var.red.length = 5;
		hitfb_var.green.offset = 5;
		hitfb_var.green.length = 6;
		hitfb_var.blue.offset = 0;
		hitfb_var.blue.length = 5;
		hitfb_var.transp.offset = 0;
		hitfb_var.transp.length = 0;
		break;
	}

	info = framebuffer_alloc(sizeof(u32) * 16, &dev->dev);
	if (unlikely(!info))
		return -ENOMEM;

	info->fbops = &hitfb_ops;
	info->var = hitfb_var;
	info->fix = hitfb_fix;
	info->pseudo_palette = info->par;
	info->flags = FBINFO_HWACCEL_YPAN |
		FBINFO_HWACCEL_FILLRECT | FBINFO_HWACCEL_COPYAREA;

	info->screen_base = (char __iomem *)(uintptr_t)hitfb_fix.smem_start;

	ret = fb_alloc_cmap(&info->cmap, 256, 0);
	if (unlikely(ret < 0))
		goto err_fb;

	ret = register_framebuffer(info);
	if (unlikely(ret < 0))
		goto err;

	platform_set_drvdata(dev, info);

	fb_info(info, "%s frame buffer device\n", info->fix.id);

	return 0;

err:
	fb_dealloc_cmap(&info->cmap);
err_fb:
	framebuffer_release(info);
	return ret;
}

static void hitfb_remove(struct platform_device *dev)
{
	struct fb_info *info = platform_get_drvdata(dev);

	unregister_framebuffer(info);
	fb_dealloc_cmap(&info->cmap);
	framebuffer_release(info);
}

static int hitfb_suspend(struct device *dev)
{
	u16 v;

	hitfb_blank(1, NULL);
	v = hitfb_readw(HD64461_STBCR);
	v |= HD64461_STBCR_SLCKE_IST;
	hitfb_writew(v, HD64461_STBCR);

	return 0;
}

static int hitfb_resume(struct device *dev)
{
	u16 v;

	v = hitfb_readw(HD64461_STBCR);
	v &= ~HD64461_STBCR_SLCKE_OST;
	msleep(100);
	v = hitfb_readw(HD64461_STBCR);
	v &= ~HD64461_STBCR_SLCKE_IST;
	hitfb_writew(v, HD64461_STBCR);
	hitfb_blank(0, NULL);

	return 0;
}

static const struct dev_pm_ops hitfb_dev_pm_ops = {
	.suspend	= hitfb_suspend,
	.resume		= hitfb_resume,
};

static struct platform_driver hitfb_driver = {
	.probe		= hitfb_probe,
	.remove_new	= hitfb_remove,
	.driver		= {
		.name	= "hitfb",
		.pm	= &hitfb_dev_pm_ops,
	},
};

static struct platform_device hitfb_device = {
	.name	= "hitfb",
	.id	= -1,
};

static int __init hitfb_init(void)
{
	int ret;

	ret = platform_driver_register(&hitfb_driver);
	if (!ret) {
		ret = platform_device_register(&hitfb_device);
		if (ret)
			platform_driver_unregister(&hitfb_driver);
	}
	return ret;
}


static void __exit hitfb_exit(void)
{
	platform_device_unregister(&hitfb_device);
	platform_driver_unregister(&hitfb_driver);
}

module_init(hitfb_init);
module_exit(hitfb_exit);

MODULE_LICENSE("GPL");
