/*
 *	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 const 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 const 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 const struct fb_ops aafb_ops = {
	.owner		= THIS_MODULE,
	FB_DEFAULT_IOMEM_OPS,
	.fb_blank	= aafb_blank,
	.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)
		return -ENOMEM;

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

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

	/* 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(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(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");
