/*
 *	linux/drivers/video/pmag-aa-fb.c
 *	Copyright 2002 Karsten Merker <merker@debian.org>
 *
 *	PMAG-AA TurboChannel framebuffer card support ... derived from
 *	pmag-ba-fb.c, which is Copyright (C) 1999, 2000, 2001 by
 *	Michael Engel <engel@unix-ag.org>, Karsten Merker <merker@debian.org>
 *	and Harald Koerfgen <hkoerfg@web.de>, which itself is derived from
 *	"HP300 Topcat framebuffer support (derived from macfb of all things)
 *	Phil Blundell <philb@gnu.org> 1998"
 *	Copyright (c) 2016  Maciej W. Rozycki
 *
 *	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.
 *
 *	2002-09-28  Karsten Merker <merker@linuxtag.org>
 *		Version 0.01: First try to get a PMAG-AA running.
 *
 *	2003-02-24  Thiemo Seufer  <seufer@csv.ica.uni-stuttgart.de>
 *		Version 0.02: Major code cleanup.
 *
 *	2003-09-21  Thiemo Seufer  <seufer@csv.ica.uni-stuttgart.de>
 *		Hardware cursor support.
 *
 *	2016-02-21  Maciej W. Rozycki  <macro@linux-mips.org>
 *		Version 0.03: Rewritten for the new FB and TC APIs.
 */

#include <linux/compiler.h>
#include <linux/errno.h>
#include <linux/fb.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/tc.h>
#include <linux/timer.h>

#include "bt455.h"
#include "bt431.h"

/* Version information */
#define DRIVER_VERSION "0.03"
#define DRIVER_AUTHOR "Karsten Merker <merker@linuxtag.org>"
#define DRIVER_DESCRIPTION "PMAG-AA Framebuffer Driver"

/*
 * Bt455 RAM DAC register base offset (rel. to TC slot base address).
 */
#define PMAG_AA_BT455_OFFSET		0x100000

/*
 * Bt431 cursor generator offset (rel. to TC slot base address).
 */
#define PMAG_AA_BT431_OFFSET		0x180000

/*
 * Begin of PMAG-AA framebuffer memory relative to TC slot address,
 * resolution is 1280x1024x1 (8 bits deep, but only LSB is used).
 */
#define PMAG_AA_ONBOARD_FBMEM_OFFSET	0x200000

struct aafb_par {
	void __iomem *mmio;
	struct bt455_regs __iomem *bt455;
	struct bt431_regs __iomem *bt431;
};

static struct fb_var_screeninfo aafb_defined = {
	.xres		= 1280,
	.yres		= 1024,
	.xres_virtual	= 2048,
	.yres_virtual	= 1024,
	.bits_per_pixel	= 8,
	.grayscale	= 1,
	.red.length	= 0,
	.green.length	= 1,
	.blue.length	= 0,
	.activate	= FB_ACTIVATE_NOW,
	.accel_flags	= FB_ACCEL_NONE,
	.pixclock	= 7645,
	.left_margin	= 224,
	.right_margin	= 32,
	.upper_margin	= 33,
	.lower_margin	= 3,
	.hsync_len	= 160,
	.vsync_len	= 3,
	.sync		= FB_SYNC_ON_GREEN,
	.vmode		= FB_VMODE_NONINTERLACED,
};

static struct fb_fix_screeninfo aafb_fix = {
	.id		= "PMAG-AA",
	.smem_len	= (2048 * 1024),
	.type		= FB_TYPE_PACKED_PIXELS,
	.visual		= FB_VISUAL_MONO10,
	.ypanstep	= 1,
	.ywrapstep	= 1,
	.line_length	= 2048,
	.mmio_len	= PMAG_AA_ONBOARD_FBMEM_OFFSET - PMAG_AA_BT455_OFFSET,
};

static int aafb_cursor(struct fb_info *info, struct fb_cursor *cursor)
{
	struct aafb_par *par = info->par;

	if (cursor->image.height > BT431_CURSOR_SIZE ||
	    cursor->image.width > BT431_CURSOR_SIZE) {
		bt431_erase_cursor(par->bt431);
		return -EINVAL;
	}

	if (!cursor->enable)
		bt431_erase_cursor(par->bt431);

	if (cursor->set & FB_CUR_SETPOS)
		bt431_position_cursor(par->bt431,
				      cursor->image.dx, cursor->image.dy);
	if (cursor->set & FB_CUR_SETCMAP) {
		u8 fg = cursor->image.fg_color ? 0xf : 0x0;
		u8 bg = cursor->image.bg_color ? 0xf : 0x0;

		bt455_write_cmap_entry(par->bt455, 8, bg);
		bt455_write_cmap_next(par->bt455, bg);
		bt455_write_ovly_next(par->bt455, fg);
	}
	if (cursor->set & (FB_CUR_SETSIZE | FB_CUR_SETSHAPE | FB_CUR_SETIMAGE))
		bt431_set_cursor(par->bt431,
				 cursor->image.data, cursor->mask, cursor->rop,
				 cursor->image.width, cursor->image.height);

	if (cursor->enable)
		bt431_enable_cursor(par->bt431);

	return 0;
}

/* 0 unblanks, any other blanks. */

static int aafb_blank(int blank, struct fb_info *info)
{
	struct aafb_par *par = info->par;
	u8 val = blank ? 0x00 : 0x0f;

	bt455_write_cmap_entry(par->bt455, 1, val);
	return 0;
}

static struct fb_ops aafb_ops = {
	.owner		= THIS_MODULE,
	.fb_blank	= aafb_blank,
	.fb_fillrect	= cfb_fillrect,
	.fb_copyarea	= cfb_copyarea,
	.fb_imageblit	= cfb_imageblit,
	.fb_cursor	= aafb_cursor,
};

static int pmagaafb_probe(struct device *dev)
{
	struct tc_dev *tdev = to_tc_dev(dev);
	resource_size_t start, len;
	struct fb_info *info;
	struct aafb_par *par;
	int err;

	info = framebuffer_alloc(sizeof(struct aafb_par), dev);
	if (!info) {
		printk(KERN_ERR "%s: Cannot allocate memory\n", dev_name(dev));
		return -ENOMEM;
	}

	par = info->par;
	dev_set_drvdata(dev, info);

	info->fbops = &aafb_ops;
	info->fix = aafb_fix;
	info->var = aafb_defined;
	info->flags = FBINFO_DEFAULT;

	/* Request the I/O MEM resource. */
	start = tdev->resource.start;
	len = tdev->resource.end - start + 1;
	if (!request_mem_region(start, len, dev_name(dev))) {
		printk(KERN_ERR "%s: Cannot reserve FB region\n",
		       dev_name(dev));
		err = -EBUSY;
		goto err_alloc;
	}

	/* MMIO mapping setup. */
	info->fix.mmio_start = start + PMAG_AA_BT455_OFFSET;
	par->mmio = ioremap_nocache(info->fix.mmio_start, info->fix.mmio_len);
	if (!par->mmio) {
		printk(KERN_ERR "%s: Cannot map MMIO\n", dev_name(dev));
		err = -ENOMEM;
		goto err_resource;
	}
	par->bt455 = par->mmio - PMAG_AA_BT455_OFFSET + PMAG_AA_BT455_OFFSET;
	par->bt431 = par->mmio - PMAG_AA_BT455_OFFSET + PMAG_AA_BT431_OFFSET;

	/* Frame buffer mapping setup. */
	info->fix.smem_start = start + PMAG_AA_ONBOARD_FBMEM_OFFSET;
	info->screen_base = ioremap_nocache(info->fix.smem_start,
					    info->fix.smem_len);
	if (!info->screen_base) {
		printk(KERN_ERR "%s: Cannot map FB\n", dev_name(dev));
		err = -ENOMEM;
		goto err_mmio_map;
	}
	info->screen_size = info->fix.smem_len;

	/* Init colormap. */
	bt455_write_cmap_entry(par->bt455, 0, 0x0);
	bt455_write_cmap_next(par->bt455, 0xf);

	/* Init hardware cursor. */
	bt431_erase_cursor(par->bt431);
	bt431_init_cursor(par->bt431);

	err = register_framebuffer(info);
	if (err < 0) {
		printk(KERN_ERR "%s: Cannot register framebuffer\n",
		       dev_name(dev));
		goto err_smem_map;
	}

	get_device(dev);

	pr_info("fb%d: %s frame buffer device at %s\n",
		info->node, info->fix.id, dev_name(dev));

	return 0;


err_smem_map:
	iounmap(info->screen_base);

err_mmio_map:
	iounmap(par->mmio);

err_resource:
	release_mem_region(start, len);

err_alloc:
	framebuffer_release(info);
	return err;
}

static int pmagaafb_remove(struct device *dev)
{
	struct tc_dev *tdev = to_tc_dev(dev);
	struct fb_info *info = dev_get_drvdata(dev);
	struct aafb_par *par = info->par;
	resource_size_t start, len;

	put_device(dev);
	unregister_framebuffer(info);
	iounmap(info->screen_base);
	iounmap(par->mmio);
	start = tdev->resource.start;
	len = tdev->resource.end - start + 1;
	release_mem_region(start, len);
	framebuffer_release(info);
	return 0;
}

/*
 * Initialise the framebuffer.
 */
static const struct tc_device_id pmagaafb_tc_table[] = {
	{ "DEC     ", "PMAG-AA " },
	{ }
};
MODULE_DEVICE_TABLE(tc, pmagaafb_tc_table);

static struct tc_driver pmagaafb_driver = {
	.id_table	= pmagaafb_tc_table,
	.driver		= {
		.name	= "pmagaafb",
		.bus	= &tc_bus_type,
		.probe	= pmagaafb_probe,
		.remove	= pmagaafb_remove,
	},
};

static int __init pmagaafb_init(void)
{
#ifndef MODULE
	if (fb_get_options("pmagaafb", NULL))
		return -ENXIO;
#endif
	return tc_register_driver(&pmagaafb_driver);
}

static void __exit pmagaafb_exit(void)
{
	tc_unregister_driver(&pmagaafb_driver);
}

module_init(pmagaafb_init);
module_exit(pmagaafb_exit);

MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESCRIPTION);
MODULE_LICENSE("GPL");
