/*
 * SH7760/SH7763 LCDC Framebuffer driver.
 *
 * (c) 2006-2008 MSC Vertriebsges.m.b.H.,
 *             Manuel Lauss <mano@roarinelk.homelinux.net>
 * (c) 2008 Nobuhiro Iwamatsu <iwamatsu.nobuhiro@renesas.com>
 *
 *  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.
 *
 * PLEASE HAVE A LOOK AT Documentation/fb/sh7760fb.txt!
 *
 * Thanks to Siegfried Schaefer <s.schaefer at schaefer-edv.de>
 *     for his original source and testing!
 */

#include <linux/completion.h>
#include <linux/delay.h>
#include <linux/dma-mapping.h>
#include <linux/fb.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/platform_device.h>

#include <asm/sh7760fb.h>

struct sh7760fb_par {
	void __iomem *base;
	int irq;

	struct sh7760fb_platdata *pd;	/* display information */

	dma_addr_t fbdma;	/* physical address */

	int rot;		/* rotation enabled? */

	u32 pseudo_palette[16];

	struct platform_device *dev;
	struct resource *ioarea;
	struct completion vsync;	/* vsync irq event */
};

static irqreturn_t sh7760fb_irq(int irq, void *data)
{
	struct completion *c = data;

	complete(c);

	return IRQ_HANDLED;
}

static void sh7760fb_wait_vsync(struct fb_info *info)
{
	struct sh7760fb_par *par = info->par;

	if (par->pd->novsync)
		return;

	iowrite16(ioread16(par->base + LDINTR) & ~VINT_CHECK,
		  par->base + LDINTR);

	if (par->irq < 0) {
		/* poll for vert. retrace: status bit is sticky */
		while (!(ioread16(par->base + LDINTR) & VINT_CHECK))
			cpu_relax();
	} else {
		/* a "wait_for_irq_event(par->irq)" would be extremely nice */
		init_completion(&par->vsync);
		enable_irq(par->irq);
		wait_for_completion(&par->vsync);
		disable_irq_nosync(par->irq);
	}
}

/* wait_for_lps - wait until power supply has reached a certain state. */
static int wait_for_lps(struct sh7760fb_par *par, int val)
{
	int i = 100;
	while (--i && ((ioread16(par->base + LDPMMR) & 3) != val))
		msleep(1);

	if (i <= 0)
		return -ETIMEDOUT;

	return 0;
}

/* en/disable the LCDC */
static int sh7760fb_blank(int blank, struct fb_info *info)
{
	struct sh7760fb_par *par = info->par;
	struct sh7760fb_platdata *pd = par->pd;
	unsigned short cntr = ioread16(par->base + LDCNTR);
	unsigned short intr = ioread16(par->base + LDINTR);
	int lps;

	if (blank == FB_BLANK_UNBLANK) {
		intr |= VINT_START;
		cntr = LDCNTR_DON2 | LDCNTR_DON;
		lps = 3;
	} else {
		intr &= ~VINT_START;
		cntr = LDCNTR_DON2;
		lps = 0;
	}

	if (pd->blank)
		pd->blank(blank);

	iowrite16(intr, par->base + LDINTR);
	iowrite16(cntr, par->base + LDCNTR);

	return wait_for_lps(par, lps);
}

/* set color registers */
static int sh7760fb_setcmap(struct fb_cmap *cmap, struct fb_info *info)
{
	struct sh7760fb_par *par = info->par;
	u32 s = cmap->start;
	u32 l = cmap->len;
	u16 *r = cmap->red;
	u16 *g = cmap->green;
	u16 *b = cmap->blue;
	u32 col, tmo;
	int ret;

	ret = 0;

	sh7760fb_wait_vsync(info);

	/* request palette access */
	iowrite16(LDPALCR_PALEN, par->base + LDPALCR);

	/* poll for access grant */
	tmo = 100;
	while (!(ioread16(par->base + LDPALCR) & LDPALCR_PALS) && (--tmo))
		cpu_relax();

	if (!tmo) {
		ret = 1;
		dev_dbg(info->dev, "no palette access!\n");
		goto out;
	}

	while (l && (s < 256)) {
		col = ((*r) & 0xff) << 16;
		col |= ((*g) & 0xff) << 8;
		col |= ((*b) & 0xff);
		col &= SH7760FB_PALETTE_MASK;
		iowrite32(col, par->base + LDPR(s));

		if (s < 16)
			((u32 *) (info->pseudo_palette))[s] = s;

		s++;
		l--;
		r++;
		g++;
		b++;
	}
out:
	iowrite16(0, par->base + LDPALCR);
	return ret;
}

static void encode_fix(struct fb_fix_screeninfo *fix, struct fb_info *info,
		       unsigned long stride)
{
	memset(fix, 0, sizeof(struct fb_fix_screeninfo));
	strcpy(fix->id, "sh7760-lcdc");

	fix->smem_start = (unsigned long)info->screen_base;
	fix->smem_len = info->screen_size;

	fix->line_length = stride;
}

static int sh7760fb_get_color_info(struct device *dev,
				   u16 lddfr, int *bpp, int *gray)
{
	int lbpp, lgray;

	lgray = lbpp = 0;

	switch (lddfr & LDDFR_COLOR_MASK) {
	case LDDFR_1BPP_MONO:
		lgray = 1;
		lbpp = 1;
		break;
	case LDDFR_2BPP_MONO:
		lgray = 1;
		lbpp = 2;
		break;
	case LDDFR_4BPP_MONO:
		lgray = 1;
	case LDDFR_4BPP:
		lbpp = 4;
		break;
	case LDDFR_6BPP_MONO:
		lgray = 1;
	case LDDFR_8BPP:
		lbpp = 8;
		break;
	case LDDFR_16BPP_RGB555:
	case LDDFR_16BPP_RGB565:
		lbpp = 16;
		lgray = 0;
		break;
	default:
		dev_dbg(dev, "unsupported LDDFR bit depth.\n");
		return -EINVAL;
	}

	if (bpp)
		*bpp = lbpp;
	if (gray)
		*gray = lgray;

	return 0;
}

static int sh7760fb_check_var(struct fb_var_screeninfo *var,
			      struct fb_info *info)
{
	struct fb_fix_screeninfo *fix = &info->fix;
	struct sh7760fb_par *par = info->par;
	int ret, bpp;

	/* get color info from register value */
	ret = sh7760fb_get_color_info(info->dev, par->pd->lddfr, &bpp, NULL);
	if (ret)
		return ret;

	var->bits_per_pixel = bpp;

	if ((var->grayscale) && (var->bits_per_pixel == 1))
		fix->visual = FB_VISUAL_MONO10;
	else if (var->bits_per_pixel >= 15)
		fix->visual = FB_VISUAL_TRUECOLOR;
	else
		fix->visual = FB_VISUAL_PSEUDOCOLOR;

	/* TODO: add some more validation here */
	return 0;
}

/*
 * sh7760fb_set_par - set videomode.
 *
 * NOTE: The rotation, grayscale and DSTN codepaths are
 *     totally untested!
 */
static int sh7760fb_set_par(struct fb_info *info)
{
	struct sh7760fb_par *par = info->par;
	struct fb_videomode *vm = par->pd->def_mode;
	unsigned long sbase, dstn_off, ldsarl, stride;
	unsigned short hsynp, hsynw, htcn, hdcn;
	unsigned short vsynp, vsynw, vtln, vdln;
	unsigned short lddfr, ldmtr;
	int ret, bpp, gray;

	par->rot = par->pd->rotate;

	/* rotate only works with xres <= 320 */
	if (par->rot && (vm->xres > 320)) {
		dev_dbg(info->dev, "rotation disabled due to display size\n");
		par->rot = 0;
	}

	/* calculate LCDC reg vals from display parameters */
	hsynp = vm->right_margin + vm->xres;
	hsynw = vm->hsync_len;
	htcn = vm->left_margin + hsynp + hsynw;
	hdcn = vm->xres;
	vsynp = vm->lower_margin + vm->yres;
	vsynw = vm->vsync_len;
	vtln = vm->upper_margin + vsynp + vsynw;
	vdln = vm->yres;

	/* get color info from register value */
	ret = sh7760fb_get_color_info(info->dev, par->pd->lddfr, &bpp, &gray);
	if (ret)
		return ret;

	dev_dbg(info->dev, "%dx%d %dbpp %s (orientation %s)\n", hdcn,
		vdln, bpp, gray ? "grayscale" : "color",
		par->rot ? "rotated" : "normal");

#ifdef CONFIG_CPU_LITTLE_ENDIAN
	lddfr = par->pd->lddfr | (1 << 8);
#else
	lddfr = par->pd->lddfr & ~(1 << 8);
#endif

	ldmtr = par->pd->ldmtr;

	if (!(vm->sync & FB_SYNC_HOR_HIGH_ACT))
		ldmtr |= LDMTR_CL1POL;
	if (!(vm->sync & FB_SYNC_VERT_HIGH_ACT))
		ldmtr |= LDMTR_FLMPOL;

	/* shut down LCDC before changing display parameters */
	sh7760fb_blank(FB_BLANK_POWERDOWN, info);

	iowrite16(par->pd->ldickr, par->base + LDICKR);	/* pixclock */
	iowrite16(ldmtr, par->base + LDMTR);	/* polarities */
	iowrite16(lddfr, par->base + LDDFR);	/* color/depth */
	iowrite16((par->rot ? 1 << 13 : 0), par->base + LDSMR);	/* rotate */
	iowrite16(par->pd->ldpmmr, par->base + LDPMMR);	/* Power Management */
	iowrite16(par->pd->ldpspr, par->base + LDPSPR);	/* Power Supply Ctrl */

	/* display resolution */
	iowrite16(((htcn >> 3) - 1) | (((hdcn >> 3) - 1) << 8),
		  par->base + LDHCNR);
	iowrite16(vdln - 1, par->base + LDVDLNR);
	iowrite16(vtln - 1, par->base + LDVTLNR);
	/* h/v sync signals */
	iowrite16((vsynp - 1) | ((vsynw - 1) << 12), par->base + LDVSYNR);
	iowrite16(((hsynp >> 3) - 1) | (((hsynw >> 3) - 1) << 12),
		  par->base + LDHSYNR);
	/* AC modulation sig */
	iowrite16(par->pd->ldaclnr, par->base + LDACLNR);

	stride = (par->rot) ? vtln : hdcn;
	if (!gray)
		stride *= (bpp + 7) >> 3;
	else {
		if (bpp == 1)
			stride >>= 3;
		else if (bpp == 2)
			stride >>= 2;
		else if (bpp == 4)
			stride >>= 1;
		/* 6 bpp == 8 bpp */
	}

	/* if rotated, stride must be power of 2 */
	if (par->rot) {
		unsigned long bit = 1 << 31;
		while (bit) {
			if (stride & bit)
				break;
			bit >>= 1;
		}
		if (stride & ~bit)
			stride = bit << 1;	/* not P-o-2, round up */
	}
	iowrite16(stride, par->base + LDLAOR);

	/* set display mem start address */
	sbase = (unsigned long)par->fbdma;
	if (par->rot)
		sbase += (hdcn - 1) * stride;

	iowrite32(sbase, par->base + LDSARU);

	/*
	 * for DSTN need to set address for lower half.
	 * I (mlau) don't know which address to set it to,
	 * so I guessed at (stride * yres/2).
	 */
	if (((ldmtr & 0x003f) >= LDMTR_DSTN_MONO_8) &&
	    ((ldmtr & 0x003f) <= LDMTR_DSTN_COLOR_16)) {

		dev_dbg(info->dev, " ***** DSTN untested! *****\n");

		dstn_off = stride;
		if (par->rot)
			dstn_off *= hdcn >> 1;
		else
			dstn_off *= vdln >> 1;

		ldsarl = sbase + dstn_off;
	} else
		ldsarl = 0;

	iowrite32(ldsarl, par->base + LDSARL);	/* mem for lower half of DSTN */

	encode_fix(&info->fix, info, stride);
	sh7760fb_check_var(&info->var, info);

	sh7760fb_blank(FB_BLANK_UNBLANK, info);	/* panel on! */

	dev_dbg(info->dev, "hdcn  : %6d htcn  : %6d\n", hdcn, htcn);
	dev_dbg(info->dev, "hsynw : %6d hsynp : %6d\n", hsynw, hsynp);
	dev_dbg(info->dev, "vdln  : %6d vtln  : %6d\n", vdln, vtln);
	dev_dbg(info->dev, "vsynw : %6d vsynp : %6d\n", vsynw, vsynp);
	dev_dbg(info->dev, "clksrc: %6d clkdiv: %6d\n",
		(par->pd->ldickr >> 12) & 3, par->pd->ldickr & 0x1f);
	dev_dbg(info->dev, "ldpmmr: 0x%04x ldpspr: 0x%04x\n", par->pd->ldpmmr,
		par->pd->ldpspr);
	dev_dbg(info->dev, "ldmtr : 0x%04x lddfr : 0x%04x\n", ldmtr, lddfr);
	dev_dbg(info->dev, "ldlaor: %ld\n", stride);
	dev_dbg(info->dev, "ldsaru: 0x%08lx ldsarl: 0x%08lx\n", sbase, ldsarl);

	return 0;
}

static struct fb_ops sh7760fb_ops = {
	.owner = THIS_MODULE,
	.fb_blank = sh7760fb_blank,
	.fb_check_var = sh7760fb_check_var,
	.fb_setcmap = sh7760fb_setcmap,
	.fb_set_par = sh7760fb_set_par,
	.fb_fillrect = cfb_fillrect,
	.fb_copyarea = cfb_copyarea,
	.fb_imageblit = cfb_imageblit,
};

static void sh7760fb_free_mem(struct fb_info *info)
{
	struct sh7760fb_par *par = info->par;

	if (!info->screen_base)
		return;

	dma_free_coherent(info->dev, info->screen_size,
			  info->screen_base, par->fbdma);

	par->fbdma = 0;
	info->screen_base = NULL;
	info->screen_size = 0;
}

/* allocate the framebuffer memory. This memory must be in Area3,
 * (dictated by the DMA engine) and contiguous, at a 512 byte boundary.
 */
static int sh7760fb_alloc_mem(struct fb_info *info)
{
	struct sh7760fb_par *par = info->par;
	void *fbmem;
	unsigned long vram;
	int ret, bpp;

	if (info->screen_base)
		return 0;

	/* get color info from register value */
	ret = sh7760fb_get_color_info(info->dev, par->pd->lddfr, &bpp, NULL);
	if (ret) {
		printk(KERN_ERR "colinfo\n");
		return ret;
	}

	/* min VRAM: xres_min = 16, yres_min = 1, bpp = 1: 2byte -> 1 page
	   max VRAM: xres_max = 1024, yres_max = 1024, bpp = 16: 2MB */

	vram = info->var.xres * info->var.yres;
	if (info->var.grayscale) {
		if (bpp == 1)
			vram >>= 3;
		else if (bpp == 2)
			vram >>= 2;
		else if (bpp == 4)
			vram >>= 1;
	} else if (bpp > 8)
		vram *= 2;
	if ((vram < 1) || (vram > 1024 * 2048)) {
		dev_dbg(info->dev, "too much VRAM required. Check settings\n");
		return -ENODEV;
	}

	if (vram < PAGE_SIZE)
		vram = PAGE_SIZE;

	fbmem = dma_alloc_coherent(info->dev, vram, &par->fbdma, GFP_KERNEL);

	if (!fbmem)
		return -ENOMEM;

	if ((par->fbdma & SH7760FB_DMA_MASK) != SH7760FB_DMA_MASK) {
		sh7760fb_free_mem(info);
		dev_err(info->dev, "kernel gave me memory at 0x%08lx, which is"
			"unusable for the LCDC\n", (unsigned long)par->fbdma);
		return -ENOMEM;
	}

	info->screen_base = fbmem;
	info->screen_size = vram;

	return 0;
}

static int __devinit sh7760fb_probe(struct platform_device *pdev)
{
	struct fb_info *info;
	struct resource *res;
	struct sh7760fb_par *par;
	int ret;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (unlikely(res == NULL)) {
		dev_err(&pdev->dev, "invalid resource\n");
		return -EINVAL;
	}

	info = framebuffer_alloc(sizeof(struct sh7760fb_par), &pdev->dev);
	if (!info)
		return -ENOMEM;

	par = info->par;
	par->dev = pdev;

	par->pd = pdev->dev.platform_data;
	if (!par->pd) {
		dev_dbg(info->dev, "no display setup data!\n");
		ret = -ENODEV;
		goto out_fb;
	}

	par->ioarea = request_mem_region(res->start,
					 (res->end - res->start), pdev->name);
	if (!par->ioarea) {
		dev_err(&pdev->dev, "mmio area busy\n");
		ret = -EBUSY;
		goto out_fb;
	}

	par->base = ioremap_nocache(res->start, res->end - res->start + 1);
	if (!par->base) {
		dev_err(&pdev->dev, "cannot remap\n");
		ret = -ENODEV;
		goto out_res;
	}

	iowrite16(0, par->base + LDINTR);	/* disable vsync irq */
	par->irq = platform_get_irq(pdev, 0);
	if (par->irq >= 0) {
		ret = request_irq(par->irq, sh7760fb_irq, 0,
				  "sh7760-lcdc", &par->vsync);
		if (ret) {
			dev_err(&pdev->dev, "cannot grab IRQ\n");
			par->irq = -ENXIO;
		} else
			disable_irq_nosync(par->irq);
	}

	fb_videomode_to_var(&info->var, par->pd->def_mode);

	ret = sh7760fb_alloc_mem(info);
	if (ret) {
		dev_dbg(info->dev, "framebuffer memory allocation failed!\n");
		goto out_unmap;
	}

	info->pseudo_palette = par->pseudo_palette;

	/* fixup color register bitpositions. These are fixed by hardware */
	info->var.red.offset = 11;
	info->var.red.length = 5;
	info->var.red.msb_right = 0;

	info->var.green.offset = 5;
	info->var.green.length = 6;
	info->var.green.msb_right = 0;

	info->var.blue.offset = 0;
	info->var.blue.length = 5;
	info->var.blue.msb_right = 0;

	info->var.transp.offset = 0;
	info->var.transp.length = 0;
	info->var.transp.msb_right = 0;

	/* set the DON2 bit now, before cmap allocation, as it will randomize
	 * palette memory.
	 */
	iowrite16(LDCNTR_DON2, par->base + LDCNTR);
	info->fbops = &sh7760fb_ops;

	ret = fb_alloc_cmap(&info->cmap, 256, 0);
	if (ret) {
		dev_dbg(info->dev, "Unable to allocate cmap memory\n");
		goto out_mem;
	}

	ret = register_framebuffer(info);
	if (ret < 0) {
		dev_dbg(info->dev, "cannot register fb!\n");
		goto out_cmap;
	}
	platform_set_drvdata(pdev, info);

	printk(KERN_INFO "%s: memory at phys 0x%08lx-0x%08lx, size %ld KiB\n",
	       pdev->name,
	       (unsigned long)par->fbdma,
	       (unsigned long)(par->fbdma + info->screen_size - 1),
	       info->screen_size >> 10);

	return 0;

out_cmap:
	sh7760fb_blank(FB_BLANK_POWERDOWN, info);
	fb_dealloc_cmap(&info->cmap);
out_mem:
	sh7760fb_free_mem(info);
out_unmap:
	if (par->irq >= 0)
		free_irq(par->irq, &par->vsync);
	iounmap(par->base);
out_res:
	release_resource(par->ioarea);
	kfree(par->ioarea);
out_fb:
	framebuffer_release(info);
	return ret;
}

static int __devexit sh7760fb_remove(struct platform_device *dev)
{
	struct fb_info *info = platform_get_drvdata(dev);
	struct sh7760fb_par *par = info->par;

	sh7760fb_blank(FB_BLANK_POWERDOWN, info);
	unregister_framebuffer(info);
	fb_dealloc_cmap(&info->cmap);
	sh7760fb_free_mem(info);
	if (par->irq >= 0)
		free_irq(par->irq, par);
	iounmap(par->base);
	release_resource(par->ioarea);
	kfree(par->ioarea);
	framebuffer_release(info);
	platform_set_drvdata(dev, NULL);

	return 0;
}

static struct platform_driver sh7760_lcdc_driver = {
	.driver = {
		   .name = "sh7760-lcdc",
		   .owner = THIS_MODULE,
		   },
	.probe = sh7760fb_probe,
	.remove = __devexit_p(sh7760fb_remove),
};

static int __init sh7760fb_init(void)
{
	return platform_driver_register(&sh7760_lcdc_driver);
}

static void __exit sh7760fb_exit(void)
{
	platform_driver_unregister(&sh7760_lcdc_driver);
}

module_init(sh7760fb_init);
module_exit(sh7760fb_exit);

MODULE_AUTHOR("Nobuhiro Iwamatsu, Manuel Lauss");
MODULE_DESCRIPTION("FBdev for SH7760/63 integrated LCD Controller");
MODULE_LICENSE("GPL");
