/*
 *  linux/drivers/video/68328fb.c -- Low level implementation of the
 *                                   mc68x328 LCD frame buffer device
 *
 *	Copyright (C) 2003 Georges Menie
 *
 *  This driver assumes an already configured controller (e.g. from config.c)
 *  Keep the code clean of board specific initialization.
 *
 *  This code has not been tested with colors, colormap management functions
 *  are minimal (no colormap data written to the 68328 registers...)
 *
 *  initial version of this driver:
 *    Copyright (C) 1998,1999 Kenneth Albanowski <kjahds@kjahds.com>,
 *                            The Silver Hammer Group, Ltd.
 *
 *  this version is based on :
 *
 *  linux/drivers/video/vfb.c -- Virtual frame buffer device
 *
 *      Copyright (C) 2002 James Simmons
 *
 *	Copyright (C) 1997 Geert Uytterhoeven
 *
 *  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/vmalloc.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/uaccess.h>
#include <linux/fb.h>
#include <linux/init.h>

#if defined(CONFIG_M68VZ328)
#include <asm/MC68VZ328.h>
#elif defined(CONFIG_M68EZ328)
#include <asm/MC68EZ328.h>
#elif defined(CONFIG_M68328)
#include <asm/MC68328.h>
#else
#error wrong architecture for the MC68x328 frame buffer device
#endif

static u_long videomemory;
static u_long videomemorysize;

static struct fb_info fb_info;
static u32 mc68x328fb_pseudo_palette[16];

static struct fb_var_screeninfo mc68x328fb_default __initdata = {
	.red =		{ 0, 8, 0 },
      	.green =	{ 0, 8, 0 },
      	.blue =		{ 0, 8, 0 },
      	.activate =	FB_ACTIVATE_TEST,
      	.height =	-1,
      	.width =	-1,
      	.pixclock =	20000,
      	.left_margin =	64,
      	.right_margin =	64,
      	.upper_margin =	32,
      	.lower_margin =	32,
      	.hsync_len =	64,
      	.vsync_len =	2,
      	.vmode =	FB_VMODE_NONINTERLACED,
};

static const struct fb_fix_screeninfo mc68x328fb_fix __initconst = {
	.id =		"68328fb",
	.type =		FB_TYPE_PACKED_PIXELS,
	.xpanstep =	1,
	.ypanstep =	1,
	.ywrapstep =	1,
	.accel =	FB_ACCEL_NONE,
};

    /*
     *  Interface used by the world
     */
static int mc68x328fb_check_var(struct fb_var_screeninfo *var,
			 struct fb_info *info);
static int mc68x328fb_set_par(struct fb_info *info);
static int mc68x328fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
			 u_int transp, struct fb_info *info);
static int mc68x328fb_pan_display(struct fb_var_screeninfo *var,
			   struct fb_info *info);
static int mc68x328fb_mmap(struct fb_info *info, struct vm_area_struct *vma);

static const struct fb_ops mc68x328fb_ops = {
	.owner		= THIS_MODULE,
	__FB_DEFAULT_IOMEM_OPS_RDWR,
	.fb_check_var	= mc68x328fb_check_var,
	.fb_set_par	= mc68x328fb_set_par,
	.fb_setcolreg	= mc68x328fb_setcolreg,
	.fb_pan_display	= mc68x328fb_pan_display,
	__FB_DEFAULT_IOMEM_OPS_DRAW,
	.fb_mmap	= mc68x328fb_mmap,
};

    /*
     *  Internal routines
     */

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 mc68x328fb_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 > videomemorysize)
		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:
		var->red.offset = 0;
		var->red.length = 1;
		var->green.offset = 0;
		var->green.length = 1;
		var->blue.offset = 0;
		var->blue.length = 1;
		var->transp.offset = 0;
		var->transp.length = 0;
		break;
	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 = 0;
			var->red.length = 5;
			var->green.offset = 5;
			var->green.length = 6;
			var->blue.offset = 11;
			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 = 0;
		var->red.length = 8;
		var->green.offset = 8;
		var->green.length = 8;
		var->blue.offset = 16;
		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 mc68x328fb_set_par(struct fb_info *info)
{
	info->fix.line_length = get_line_length(info->var.xres_virtual,
						info->var.bits_per_pixel);
	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 mc68x328fb_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;
	/*
	 * Program hardware... do anything you want with transp
	 */

	/* 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;
	}

	/* Directcolor:
	 *   var->{color}.offset contains start of bitfield
	 *   var->{color}.length contains length of bitfield
	 *   {hardwarespecific} contains width of RAMDAC
	 *   cmap[X] is programmed to (X << red.offset) | (X << green.offset) | (X << blue.offset)
	 *   RAMDAC[X] is programmed to (red, green, blue)
	 *
	 * Pseudocolor:
	 *    uses offset = 0 && length = RAMDAC register width.
	 *    var->{color}.offset is 0
	 *    var->{color}.length contains width of DAC
	 *    cmap is not used
	 *    RAMDAC[X] is programmed to (red, green, blue)
	 * Truecolor:
	 *    does not use DAC. Usually 3 are present.
	 *    var->{color}.offset contains start of bitfield
	 *    var->{color}.length contains length of bitfield
	 *    cmap is programmed to (red << red.offset) | (green << green.offset) |
	 *                      (blue << blue.offset) | (transp << transp.offset)
	 *    RAMDAC does not exist
	 */
#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:
			((u32 *) (info->pseudo_palette))[regno] = v;
			break;
		case 24:
		case 32:
			((u32 *) (info->pseudo_palette))[regno] = v;
			break;
		}
		return 0;
	}
	return 0;
}

    /*
     *  Pan or Wrap the Display
     *
     *  This call looks only at xoffset, yoffset and the FB_VMODE_YWRAP flag
     */

static int mc68x328fb_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;
}

    /*
     *  Most drivers don't need their own mmap function
     */

static int mc68x328fb_mmap(struct fb_info *info, struct vm_area_struct *vma)
{
#ifndef MMU
	/* this is uClinux (no MMU) specific code */

	vm_flags_set(vma, VM_DONTEXPAND | VM_DONTDUMP);
	vma->vm_start = videomemory;

	return 0;
#else
	return -EINVAL;
#endif
}

static int __init mc68x328fb_setup(char *options)
{
	if (!options || !*options)
		return 1;
	return 1;
}

    /*
     *  Initialisation
     */

static int __init mc68x328fb_init(void)
{
#ifndef MODULE
	char *option = NULL;

	if (fb_get_options("68328fb", &option))
		return -ENODEV;
	mc68x328fb_setup(option);
#endif
	/*
	 *  initialize the default mode from the LCD controller registers
	 */
	mc68x328fb_default.xres = LXMAX;
	mc68x328fb_default.yres = LYMAX+1;
	mc68x328fb_default.xres_virtual = mc68x328fb_default.xres;
	mc68x328fb_default.yres_virtual = mc68x328fb_default.yres;
	mc68x328fb_default.bits_per_pixel = 1 + (LPICF & 0x01);
	videomemory = LSSA;
	videomemorysize = (mc68x328fb_default.xres_virtual+7) / 8 *
		mc68x328fb_default.yres_virtual * mc68x328fb_default.bits_per_pixel;

	fb_info.screen_base = (void *)videomemory;
	fb_info.fbops = &mc68x328fb_ops;
	fb_info.var = mc68x328fb_default;
	fb_info.fix = mc68x328fb_fix;
	fb_info.fix.smem_start = videomemory;
	fb_info.fix.smem_len = videomemorysize;
	fb_info.fix.line_length =
		get_line_length(mc68x328fb_default.xres_virtual, mc68x328fb_default.bits_per_pixel);
	fb_info.fix.visual = (mc68x328fb_default.bits_per_pixel) == 1 ?
		FB_VISUAL_MONO10 : FB_VISUAL_PSEUDOCOLOR;
	if (fb_info.var.bits_per_pixel == 1) {
		fb_info.var.red.length = fb_info.var.green.length = fb_info.var.blue.length = 1;
		fb_info.var.red.offset = fb_info.var.green.offset = fb_info.var.blue.offset = 0;
	}
	fb_info.pseudo_palette = &mc68x328fb_pseudo_palette;
	fb_info.flags = FBINFO_HWACCEL_YPAN;

	if (fb_alloc_cmap(&fb_info.cmap, 256, 0))
		return -ENOMEM;

	if (register_framebuffer(&fb_info) < 0) {
		fb_dealloc_cmap(&fb_info.cmap);
		return -EINVAL;
	}

	fb_info(&fb_info, "%s frame buffer device\n", fb_info.fix.id);
	fb_info(&fb_info, "%dx%dx%d at 0x%08lx\n",
		mc68x328fb_default.xres_virtual,
		mc68x328fb_default.yres_virtual,
		1 << mc68x328fb_default.bits_per_pixel, videomemory);

	return 0;
}

module_init(mc68x328fb_init);

#ifdef MODULE

static void __exit mc68x328fb_cleanup(void)
{
	unregister_framebuffer(&fb_info);
	fb_dealloc_cmap(&fb_info.cmap);
}

module_exit(mc68x328fb_cleanup);

MODULE_LICENSE("GPL");
#endif				/* MODULE */
