/* tcx.c: TCX frame buffer driver
 *
 * Copyright (C) 2003, 2006 David S. Miller (davem@davemloft.net)
 * Copyright (C) 1996,1998 Jakub Jelinek (jj@ultra.linux.cz)
 * Copyright (C) 1996 Miguel de Icaza (miguel@nuclecu.unam.mx)
 * Copyright (C) 1996 Eddie C. Dost (ecd@skynet.be)
 *
 * Driver layout based loosely on tgafb.c, see that file for credits.
 */

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

#include <asm/io.h>
#include <asm/fbio.h>

#include "sbuslib.h"

/*
 * Local functions.
 */

static int tcx_setcolreg(unsigned, unsigned, unsigned, unsigned,
			 unsigned, struct fb_info *);
static int tcx_blank(int, struct fb_info *);

static int tcx_mmap(struct fb_info *, struct vm_area_struct *);
static int tcx_ioctl(struct fb_info *, unsigned int, unsigned long);
static int tcx_pan_display(struct fb_var_screeninfo *, struct fb_info *);

/*
 *  Frame buffer operations
 */

static struct fb_ops tcx_ops = {
	.owner			= THIS_MODULE,
	.fb_setcolreg		= tcx_setcolreg,
	.fb_blank		= tcx_blank,
	.fb_pan_display		= tcx_pan_display,
	.fb_fillrect		= cfb_fillrect,
	.fb_copyarea		= cfb_copyarea,
	.fb_imageblit		= cfb_imageblit,
	.fb_mmap		= tcx_mmap,
	.fb_ioctl		= tcx_ioctl,
#ifdef CONFIG_COMPAT
	.fb_compat_ioctl	= sbusfb_compat_ioctl,
#endif
};

/* THC definitions */
#define TCX_THC_MISC_REV_SHIFT       16
#define TCX_THC_MISC_REV_MASK        15
#define TCX_THC_MISC_VSYNC_DIS       (1 << 25)
#define TCX_THC_MISC_HSYNC_DIS       (1 << 24)
#define TCX_THC_MISC_RESET           (1 << 12)
#define TCX_THC_MISC_VIDEO           (1 << 10)
#define TCX_THC_MISC_SYNC            (1 << 9)
#define TCX_THC_MISC_VSYNC           (1 << 8)
#define TCX_THC_MISC_SYNC_ENAB       (1 << 7)
#define TCX_THC_MISC_CURS_RES        (1 << 6)
#define TCX_THC_MISC_INT_ENAB        (1 << 5)
#define TCX_THC_MISC_INT             (1 << 4)
#define TCX_THC_MISC_INIT            0x9f
#define TCX_THC_REV_REV_SHIFT        20
#define TCX_THC_REV_REV_MASK         15
#define TCX_THC_REV_MINREV_SHIFT     28
#define TCX_THC_REV_MINREV_MASK      15

/* The contents are unknown */
struct tcx_tec {
	u32 tec_matrix;
	u32 tec_clip;
	u32 tec_vdc;
};

struct tcx_thc {
	u32 thc_rev;
	u32 thc_pad0[511];
	u32 thc_hs;		/* hsync timing */
	u32 thc_hsdvs;
	u32 thc_hd;
	u32 thc_vs;		/* vsync timing */
	u32 thc_vd;
	u32 thc_refresh;
	u32 thc_misc;
	u32 thc_pad1[56];
	u32 thc_cursxy;	/* cursor x,y position (16 bits each) */
	u32 thc_cursmask[32];	/* cursor mask bits */
	u32 thc_cursbits[32];	/* what to show where mask enabled */
};

struct bt_regs {
	u32 addr;
	u32 color_map;
	u32 control;
	u32 cursor;
};

#define TCX_MMAP_ENTRIES 14

struct tcx_par {
	spinlock_t		lock;
	struct bt_regs		__iomem *bt;
	struct tcx_thc		__iomem *thc;
	struct tcx_tec		__iomem *tec;
	u32			__iomem *cplane;

	u32			flags;
#define TCX_FLAG_BLANKED	0x00000001

	unsigned long		physbase;
	unsigned long		which_io;
	unsigned long		fbsize;

	struct sbus_mmap_map	mmap_map[TCX_MMAP_ENTRIES];
	int			lowdepth;
};

/* Reset control plane so that WID is 8-bit plane. */
static void __tcx_set_control_plane(struct tcx_par *par)
{
	u32 __iomem *p, *pend;

	if (par->lowdepth)
		return;

	p = par->cplane;
	if (p == NULL)
		return;
	for (pend = p + par->fbsize; p < pend; p++) {
		u32 tmp = sbus_readl(p);

		tmp &= 0xffffff;
		sbus_writel(tmp, p);
	}
}

static void tcx_reset(struct fb_info *info)
{
	struct tcx_par *par = (struct tcx_par *) info->par;
	unsigned long flags;

	spin_lock_irqsave(&par->lock, flags);
	__tcx_set_control_plane(par);
	spin_unlock_irqrestore(&par->lock, flags);
}

static int tcx_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
{
	tcx_reset(info);
	return 0;
}

/**
 *      tcx_setcolreg - Optional function. Sets a color register.
 *      @regno: boolean, 0 copy local, 1 get_user() function
 *      @red: frame buffer colormap structure
 *      @green: The green value which can be up to 16 bits wide
 *      @blue:  The blue value which can be up to 16 bits wide.
 *      @transp: If supported the alpha value which can be up to 16 bits wide.
 *      @info: frame buffer info structure
 */
static int tcx_setcolreg(unsigned regno,
			 unsigned red, unsigned green, unsigned blue,
			 unsigned transp, struct fb_info *info)
{
	struct tcx_par *par = (struct tcx_par *) info->par;
	struct bt_regs __iomem *bt = par->bt;
	unsigned long flags;

	if (regno >= 256)
		return 1;

	red >>= 8;
	green >>= 8;
	blue >>= 8;

	spin_lock_irqsave(&par->lock, flags);

	sbus_writel(regno << 24, &bt->addr);
	sbus_writel(red << 24, &bt->color_map);
	sbus_writel(green << 24, &bt->color_map);
	sbus_writel(blue << 24, &bt->color_map);

	spin_unlock_irqrestore(&par->lock, flags);

	return 0;
}

/**
 *      tcx_blank - Optional function.  Blanks the display.
 *      @blank_mode: the blank mode we want.
 *      @info: frame buffer structure that represents a single frame buffer
 */
static int
tcx_blank(int blank, struct fb_info *info)
{
	struct tcx_par *par = (struct tcx_par *) info->par;
	struct tcx_thc __iomem *thc = par->thc;
	unsigned long flags;
	u32 val;

	spin_lock_irqsave(&par->lock, flags);

	val = sbus_readl(&thc->thc_misc);

	switch (blank) {
	case FB_BLANK_UNBLANK: /* Unblanking */
		val &= ~(TCX_THC_MISC_VSYNC_DIS |
			 TCX_THC_MISC_HSYNC_DIS);
		val |= TCX_THC_MISC_VIDEO;
		par->flags &= ~TCX_FLAG_BLANKED;
		break;

	case FB_BLANK_NORMAL: /* Normal blanking */
		val &= ~TCX_THC_MISC_VIDEO;
		par->flags |= TCX_FLAG_BLANKED;
		break;

	case FB_BLANK_VSYNC_SUSPEND: /* VESA blank (vsync off) */
		val |= TCX_THC_MISC_VSYNC_DIS;
		break;
	case FB_BLANK_HSYNC_SUSPEND: /* VESA blank (hsync off) */
		val |= TCX_THC_MISC_HSYNC_DIS;
		break;

	case FB_BLANK_POWERDOWN: /* Poweroff */
		break;
	};

	sbus_writel(val, &thc->thc_misc);

	spin_unlock_irqrestore(&par->lock, flags);

	return 0;
}

static struct sbus_mmap_map __tcx_mmap_map[TCX_MMAP_ENTRIES] = {
	{
		.voff	= TCX_RAM8BIT,
		.size	= SBUS_MMAP_FBSIZE(1)
	},
	{
		.voff	= TCX_RAM24BIT,
		.size	= SBUS_MMAP_FBSIZE(4)
	},
	{
		.voff	= TCX_UNK3,
		.size	= SBUS_MMAP_FBSIZE(8)
	},
	{
		.voff	= TCX_UNK4,
		.size	= SBUS_MMAP_FBSIZE(8)
	},
	{
		.voff	= TCX_CONTROLPLANE,
		.size	= SBUS_MMAP_FBSIZE(4)
	},
	{
		.voff	= TCX_UNK6,
		.size	= SBUS_MMAP_FBSIZE(8)
	},
	{
		.voff	= TCX_UNK7,
		.size	= SBUS_MMAP_FBSIZE(8)
	},
	{
		.voff	= TCX_TEC,
		.size	= PAGE_SIZE
	},
	{
		.voff	= TCX_BTREGS,
		.size	= PAGE_SIZE
	},
	{
		.voff	= TCX_THC,
		.size	= PAGE_SIZE
	},
	{
		.voff	= TCX_DHC,
		.size	= PAGE_SIZE
	},
	{
		.voff	= TCX_ALT,
		.size	= PAGE_SIZE
	},
	{
		.voff	= TCX_UNK2,
		.size	= 0x20000
	},
	{ .size = 0 }
};

static int tcx_mmap(struct fb_info *info, struct vm_area_struct *vma)
{
	struct tcx_par *par = (struct tcx_par *)info->par;

	return sbusfb_mmap_helper(par->mmap_map,
				  par->physbase, par->fbsize,
				  par->which_io, vma);
}

static int tcx_ioctl(struct fb_info *info, unsigned int cmd,
		     unsigned long arg)
{
	struct tcx_par *par = (struct tcx_par *) info->par;

	return sbusfb_ioctl_helper(cmd, arg, info,
				   FBTYPE_TCXCOLOR,
				   (par->lowdepth ? 8 : 24),
				   par->fbsize);
}

/*
 *  Initialisation
 */

static void
tcx_init_fix(struct fb_info *info, int linebytes)
{
	struct tcx_par *par = (struct tcx_par *)info->par;
	const char *tcx_name;

	if (par->lowdepth)
		tcx_name = "TCX8";
	else
		tcx_name = "TCX24";

	strlcpy(info->fix.id, tcx_name, sizeof(info->fix.id));

	info->fix.type = FB_TYPE_PACKED_PIXELS;
	info->fix.visual = FB_VISUAL_PSEUDOCOLOR;

	info->fix.line_length = linebytes;

	info->fix.accel = FB_ACCEL_SUN_TCX;
}

static void tcx_unmap_regs(struct of_device *op, struct fb_info *info,
			   struct tcx_par *par)
{
	if (par->tec)
		of_iounmap(&op->resource[7],
			   par->tec, sizeof(struct tcx_tec));
	if (par->thc)
		of_iounmap(&op->resource[9],
			   par->thc, sizeof(struct tcx_thc));
	if (par->bt)
		of_iounmap(&op->resource[8],
			   par->bt, sizeof(struct bt_regs));
	if (par->cplane)
		of_iounmap(&op->resource[4],
			   par->cplane, par->fbsize * sizeof(u32));
	if (info->screen_base)
		of_iounmap(&op->resource[0],
			   info->screen_base, par->fbsize);
}

static int __devinit tcx_probe(struct of_device *op,
			       const struct of_device_id *match)
{
	struct device_node *dp = op->node;
	struct fb_info *info;
	struct tcx_par *par;
	int linebytes, i, err;

	info = framebuffer_alloc(sizeof(struct tcx_par), &op->dev);

	err = -ENOMEM;
	if (!info)
		goto out_err;
	par = info->par;

	spin_lock_init(&par->lock);

	par->lowdepth =
		(of_find_property(dp, "tcx-8-bit", NULL) != NULL);

	sbusfb_fill_var(&info->var, dp, 8);
	info->var.red.length = 8;
	info->var.green.length = 8;
	info->var.blue.length = 8;

	linebytes = of_getintprop_default(dp, "linebytes",
					  info->var.xres);
	par->fbsize = PAGE_ALIGN(linebytes * info->var.yres);

	par->tec = of_ioremap(&op->resource[7], 0,
				  sizeof(struct tcx_tec), "tcx tec");
	par->thc = of_ioremap(&op->resource[9], 0,
				  sizeof(struct tcx_thc), "tcx thc");
	par->bt = of_ioremap(&op->resource[8], 0,
				 sizeof(struct bt_regs), "tcx dac");
	info->screen_base = of_ioremap(&op->resource[0], 0,
					   par->fbsize, "tcx ram");
	if (!par->tec || !par->thc ||
	    !par->bt || !info->screen_base)
		goto out_unmap_regs;

	memcpy(&par->mmap_map, &__tcx_mmap_map, sizeof(par->mmap_map));
	if (!par->lowdepth) {
		par->cplane = of_ioremap(&op->resource[4], 0,
					     par->fbsize * sizeof(u32),
					     "tcx cplane");
		if (!par->cplane)
			goto out_unmap_regs;
	} else {
		par->mmap_map[1].size = SBUS_MMAP_EMPTY;
		par->mmap_map[4].size = SBUS_MMAP_EMPTY;
		par->mmap_map[5].size = SBUS_MMAP_EMPTY;
		par->mmap_map[6].size = SBUS_MMAP_EMPTY;
	}

	par->physbase = op->resource[0].start;
	par->which_io = op->resource[0].flags & IORESOURCE_BITS;

	for (i = 0; i < TCX_MMAP_ENTRIES; i++) {
		int j;

		switch (i) {
		case 10:
			j = 12;
			break;

		case 11: case 12:
			j = i - 1;
			break;

		default:
			j = i;
			break;
		};
		par->mmap_map[i].poff = op->resource[j].start;
	}

	info->flags = FBINFO_DEFAULT;
	info->fbops = &tcx_ops;

	/* Initialize brooktree DAC. */
	sbus_writel(0x04 << 24, &par->bt->addr);         /* color planes */
	sbus_writel(0xff << 24, &par->bt->control);
	sbus_writel(0x05 << 24, &par->bt->addr);
	sbus_writel(0x00 << 24, &par->bt->control);
	sbus_writel(0x06 << 24, &par->bt->addr);         /* overlay plane */
	sbus_writel(0x73 << 24, &par->bt->control);
	sbus_writel(0x07 << 24, &par->bt->addr);
	sbus_writel(0x00 << 24, &par->bt->control);

	tcx_reset(info);

	tcx_blank(FB_BLANK_UNBLANK, info);

	if (fb_alloc_cmap(&info->cmap, 256, 0))
		goto out_unmap_regs;

	fb_set_cmap(&info->cmap, info);
	tcx_init_fix(info, linebytes);

	err = register_framebuffer(info);
	if (err < 0)
		goto out_dealloc_cmap;

	dev_set_drvdata(&op->dev, info);

	printk(KERN_INFO "%s: TCX at %lx:%lx, %s\n",
	       dp->full_name,
	       par->which_io,
	       par->physbase,
	       par->lowdepth ? "8-bit only" : "24-bit depth");

	return 0;

out_dealloc_cmap:
	fb_dealloc_cmap(&info->cmap);

out_unmap_regs:
	tcx_unmap_regs(op, info, par);

out_err:
	return err;
}

static int __devexit tcx_remove(struct of_device *op)
{
	struct fb_info *info = dev_get_drvdata(&op->dev);
	struct tcx_par *par = info->par;

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

	tcx_unmap_regs(op, info, par);

	framebuffer_release(info);

	dev_set_drvdata(&op->dev, NULL);

	return 0;
}

static struct of_device_id tcx_match[] = {
	{
		.name = "SUNW,tcx",
	},
	{},
};
MODULE_DEVICE_TABLE(of, tcx_match);

static struct of_platform_driver tcx_driver = {
	.name		= "tcx",
	.match_table	= tcx_match,
	.probe		= tcx_probe,
	.remove		= __devexit_p(tcx_remove),
};

static int __init tcx_init(void)
{
	if (fb_get_options("tcxfb", NULL))
		return -ENODEV;

	return of_register_driver(&tcx_driver, &of_bus_type);
}

static void __exit tcx_exit(void)
{
	of_unregister_driver(&tcx_driver);
}

module_init(tcx_init);
module_exit(tcx_exit);

MODULE_DESCRIPTION("framebuffer driver for TCX chipsets");
MODULE_AUTHOR("David S. Miller <davem@davemloft.net>");
MODULE_VERSION("2.0");
MODULE_LICENSE("GPL");
