// SPDX-License-Identifier: GPL-2.0-only
/*
 *	HP300 Topcat framebuffer support (derived from macfb of all things)
 *	Phil Blundell <philb@gnu.org> 1998
 *	DIO-II, colour map and Catseye support by
 *	Kars de Jong <jongk@linux-m68k.org>, May 2004.
 */

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

#include <asm/io.h>
#include <linux/uaccess.h>

static struct fb_info fb_info = {
	.fix = {
		.id		= "HP300 ",
		.type		= FB_TYPE_PACKED_PIXELS,
		.visual		= FB_VISUAL_PSEUDOCOLOR,
		.accel		= FB_ACCEL_NONE,
	}
};

static unsigned long fb_regs;
static unsigned char fb_bitmask;

#define TC_NBLANK	0x4080
#define TC_WEN		0x4088
#define TC_REN		0x408c
#define TC_FBEN		0x4090
#define TC_PRR		0x40ea

/* These defines match the X window system */
#define RR_CLEAR	0x0
#define RR_COPY		0x3
#define RR_NOOP		0x5
#define RR_XOR		0x6
#define RR_INVERT	0xa
#define RR_COPYINVERTED 0xc
#define RR_SET		0xf

/* blitter regs */
#define BUSY		0x4044
#define WMRR		0x40ef
#define SOURCE_X	0x40f2
#define SOURCE_Y	0x40f6
#define DEST_X		0x40fa
#define DEST_Y		0x40fe
#define WHEIGHT		0x4106
#define WWIDTH		0x4102
#define WMOVE		0x409c

static struct fb_var_screeninfo hpfb_defined = {
	.red		= {
		.length = 8,
	},
	.green		= {
		.length = 8,
	},
	.blue		= {
		.length = 8,
	},
	.activate	= FB_ACTIVATE_NOW,
	.height		= -1,
	.width		= -1,
	.vmode		= FB_VMODE_NONINTERLACED,
};

static int hpfb_setcolreg(unsigned regno, unsigned red, unsigned green,
			  unsigned blue, unsigned transp,
			  struct fb_info *info)
{
	/* use MSBs */
	unsigned char _red  =red>>8;
	unsigned char _green=green>>8;
	unsigned char _blue =blue>>8;
	unsigned char _regno=regno;

	/*
	 *  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.
	 */

	if (regno >= info->cmap.len)
		return 1;

	while (in_be16(fb_regs + 0x6002) & 0x4) udelay(1);

	out_be16(fb_regs + 0x60ba, 0xff);

	out_be16(fb_regs + 0x60b2, _red);
	out_be16(fb_regs + 0x60b4, _green);
	out_be16(fb_regs + 0x60b6, _blue);
	out_be16(fb_regs + 0x60b8, ~_regno);
	out_be16(fb_regs + 0x60f0, 0xff);

	udelay(100);

	while (in_be16(fb_regs + 0x6002) & 0x4) udelay(1);
	out_be16(fb_regs + 0x60b2, 0);
	out_be16(fb_regs + 0x60b4, 0);
	out_be16(fb_regs + 0x60b6, 0);
	out_be16(fb_regs + 0x60b8, 0);

	return 0;
}

/* 0 unblank, 1 blank, 2 no vsync, 3 no hsync, 4 off */

static int hpfb_blank(int blank, struct fb_info *info)
{
	out_8(fb_regs + TC_NBLANK, (blank ? 0x00 : fb_bitmask));

	return 0;
}

static void topcat_blit(int x0, int y0, int x1, int y1, int w, int h, int rr)
{
	if (rr >= 0) {
		while (in_8(fb_regs + BUSY) & fb_bitmask)
			;
	}
	out_8(fb_regs + TC_FBEN, fb_bitmask);
	if (rr >= 0) {
		out_8(fb_regs + TC_WEN, fb_bitmask);
		out_8(fb_regs + WMRR, rr);
	}
	out_be16(fb_regs + SOURCE_X, x0);
	out_be16(fb_regs + SOURCE_Y, y0);
	out_be16(fb_regs + DEST_X, x1);
	out_be16(fb_regs + DEST_Y, y1);
	out_be16(fb_regs + WWIDTH, w);
	out_be16(fb_regs + WHEIGHT, h);
	out_8(fb_regs + WMOVE, fb_bitmask);
}

static void hpfb_copyarea(struct fb_info *info, const struct fb_copyarea *area)
{
	topcat_blit(area->sx, area->sy, area->dx, area->dy, area->width, area->height, RR_COPY);
}

static void hpfb_fillrect(struct fb_info *p, const struct fb_fillrect *region)
{
	u8 clr;

	clr = region->color & 0xff;

	while (in_8(fb_regs + BUSY) & fb_bitmask)
		;

	/* Foreground */
	out_8(fb_regs + TC_WEN, fb_bitmask & clr);
	out_8(fb_regs + WMRR, (region->rop == ROP_COPY ? RR_SET : RR_INVERT));

	/* Background */
	out_8(fb_regs + TC_WEN, fb_bitmask & ~clr);
	out_8(fb_regs + WMRR, (region->rop == ROP_COPY ? RR_CLEAR : RR_NOOP));

	topcat_blit(region->dx, region->dy, region->dx, region->dy, region->width, region->height, -1);
}

static int hpfb_sync(struct fb_info *info)
{
	/*
	 * Since we also access the framebuffer directly, we have to wait
	 * until the block mover is finished
	 */
	while (in_8(fb_regs + BUSY) & fb_bitmask)
		;

	out_8(fb_regs + TC_WEN, fb_bitmask);
	out_8(fb_regs + TC_PRR, RR_COPY);
	out_8(fb_regs + TC_FBEN, fb_bitmask);

	return 0;
}

static const struct fb_ops hpfb_ops = {
	.owner		= THIS_MODULE,
	__FB_DEFAULT_IOMEM_OPS_RDWR,
	.fb_setcolreg	= hpfb_setcolreg,
	.fb_blank	= hpfb_blank,
	.fb_fillrect	= hpfb_fillrect,
	.fb_copyarea	= hpfb_copyarea,
	.fb_imageblit	= cfb_imageblit,
	.fb_sync	= hpfb_sync,
	__FB_DEFAULT_IOMEM_OPS_MMAP,
};

/* Common to all HP framebuffers */
#define HPFB_FBWMSB	0x05	/* Frame buffer width 		*/
#define HPFB_FBWLSB	0x07
#define HPFB_FBHMSB	0x09	/* Frame buffer height		*/
#define HPFB_FBHLSB	0x0b
#define HPFB_DWMSB	0x0d	/* Display width		*/
#define HPFB_DWLSB	0x0f
#define HPFB_DHMSB	0x11	/* Display height		*/
#define HPFB_DHLSB	0x13
#define HPFB_NUMPLANES	0x5b	/* Number of colour planes	*/
#define HPFB_FBOMSB	0x5d	/* Frame buffer offset		*/
#define HPFB_FBOLSB	0x5f

static int hpfb_init_one(unsigned long phys_base, unsigned long virt_base)
{
	unsigned long fboff, fb_width, fb_height, fb_start;
	int ret;

	fb_regs = virt_base;
	fboff = (in_8(fb_regs + HPFB_FBOMSB) << 8) | in_8(fb_regs + HPFB_FBOLSB);

	fb_info.fix.smem_start = (in_8(fb_regs + fboff) << 16);

	if (phys_base >= DIOII_BASE) {
		fb_info.fix.smem_start += phys_base;
	}

	if (DIO_SECID(fb_regs) != DIO_ID2_TOPCAT) {
		/* This is the magic incantation the HP X server uses to make Catseye boards work. */
		while (in_be16(fb_regs+0x4800) & 1)
			;
		out_be16(fb_regs+0x4800, 0);	/* Catseye status */
		out_be16(fb_regs+0x4510, 0);	/* VB */
		out_be16(fb_regs+0x4512, 0);	/* TCNTRL */
		out_be16(fb_regs+0x4514, 0);	/* ACNTRL */
		out_be16(fb_regs+0x4516, 0);	/* PNCNTRL */
		out_be16(fb_regs+0x4206, 0x90);	/* RUG Command/Status */
		out_be16(fb_regs+0x60a2, 0);	/* Overlay Mask */
		out_be16(fb_regs+0x60bc, 0);	/* Ram Select */
	}

	/*
	 *	Fill in the available video resolution
	 */
	fb_width = (in_8(fb_regs + HPFB_FBWMSB) << 8) | in_8(fb_regs + HPFB_FBWLSB);
	fb_info.fix.line_length = fb_width;
	fb_height = (in_8(fb_regs + HPFB_FBHMSB) << 8) | in_8(fb_regs + HPFB_FBHLSB);
	fb_info.fix.smem_len = fb_width * fb_height;
	fb_start = (unsigned long)ioremap_wt(fb_info.fix.smem_start,
					     fb_info.fix.smem_len);
	hpfb_defined.xres = (in_8(fb_regs + HPFB_DWMSB) << 8) | in_8(fb_regs + HPFB_DWLSB);
	hpfb_defined.yres = (in_8(fb_regs + HPFB_DHMSB) << 8) | in_8(fb_regs + HPFB_DHLSB);
	hpfb_defined.xres_virtual = hpfb_defined.xres;
	hpfb_defined.yres_virtual = hpfb_defined.yres;
	hpfb_defined.bits_per_pixel = in_8(fb_regs + HPFB_NUMPLANES);

	printk(KERN_INFO "hpfb: framebuffer at 0x%lx, mapped to 0x%lx, size %dk\n",
	       fb_info.fix.smem_start, fb_start, fb_info.fix.smem_len/1024);
	printk(KERN_INFO "hpfb: mode is %dx%dx%d, linelength=%d\n",
	       hpfb_defined.xres, hpfb_defined.yres, hpfb_defined.bits_per_pixel, fb_info.fix.line_length);

	/*
	 *	Give the hardware a bit of a prod and work out how many bits per
	 *	pixel are supported.
	 */
	out_8(fb_regs + TC_WEN, 0xff);
	out_8(fb_regs + TC_PRR, RR_COPY);
	out_8(fb_regs + TC_FBEN, 0xff);
	out_8(fb_start, 0xff);
	fb_bitmask = in_8(fb_start);
	out_8(fb_start, 0);

	/*
	 *	Enable reading/writing of all the planes.
	 */
	out_8(fb_regs + TC_WEN, fb_bitmask);
	out_8(fb_regs + TC_PRR, RR_COPY);
	out_8(fb_regs + TC_REN, fb_bitmask);
	out_8(fb_regs + TC_FBEN, fb_bitmask);

	/*
	 *	Clear the screen.
	 */
	topcat_blit(0, 0, 0, 0, fb_width, fb_height, RR_CLEAR);

	/*
	 *	Let there be consoles..
	 */
	if (DIO_SECID(fb_regs) == DIO_ID2_TOPCAT)
		strcat(fb_info.fix.id, "Topcat");
	else
		strcat(fb_info.fix.id, "Catseye");
	fb_info.fbops = &hpfb_ops;
	fb_info.var   = hpfb_defined;
	fb_info.screen_base = (char *)fb_start;

	ret = fb_alloc_cmap(&fb_info.cmap, 1 << hpfb_defined.bits_per_pixel, 0);
	if (ret < 0)
		goto unmap_screen_base;

	ret = register_framebuffer(&fb_info);
	if (ret < 0)
		goto dealloc_cmap;

	fb_info(&fb_info, "%s frame buffer device\n", fb_info.fix.id);

	return 0;

dealloc_cmap:
	fb_dealloc_cmap(&fb_info.cmap);

unmap_screen_base:
	if (fb_info.screen_base) {
		iounmap(fb_info.screen_base);
		fb_info.screen_base = NULL;
	}

	return ret;
}

/*
 * Check that the secondary ID indicates that we have some hope of working with this
 * framebuffer.  The catseye boards are pretty much like topcats and we can muddle through.
 */

#define topcat_sid_ok(x)  (((x) == DIO_ID2_LRCATSEYE) || ((x) == DIO_ID2_HRCCATSEYE)    \
			   || ((x) == DIO_ID2_HRMCATSEYE) || ((x) == DIO_ID2_TOPCAT))

/*
 * Initialise the framebuffer
 */
static int hpfb_dio_probe(struct dio_dev *d, const struct dio_device_id *ent)
{
	unsigned long paddr, vaddr;

	paddr = d->resource.start;
	if (!request_mem_region(d->resource.start, resource_size(&d->resource), d->name))
                return -EBUSY;

	if (d->scode >= DIOII_SCBASE) {
		vaddr = (unsigned long)ioremap(paddr, resource_size(&d->resource));
	} else {
		vaddr = paddr + DIO_VIRADDRBASE;
	}
	printk(KERN_INFO "Topcat found at DIO select code %d "
	       "(secondary id %02x)\n", d->scode, (d->id >> 8) & 0xff);
	if (hpfb_init_one(paddr, vaddr)) {
		if (d->scode >= DIOII_SCBASE)
			iounmap((void *)vaddr);
		release_mem_region(d->resource.start, resource_size(&d->resource));
		return -ENOMEM;
	}
	return 0;
}

static void hpfb_remove_one(struct dio_dev *d)
{
	unregister_framebuffer(&fb_info);
	if (d->scode >= DIOII_SCBASE)
		iounmap((void *)fb_regs);
	release_mem_region(d->resource.start, resource_size(&d->resource));
	fb_dealloc_cmap(&fb_info.cmap);
	if (fb_info.screen_base)
		iounmap(fb_info.screen_base);
}

static struct dio_device_id hpfb_dio_tbl[] = {
    { DIO_ENCODE_ID(DIO_ID_FBUFFER, DIO_ID2_LRCATSEYE) },
    { DIO_ENCODE_ID(DIO_ID_FBUFFER, DIO_ID2_HRCCATSEYE) },
    { DIO_ENCODE_ID(DIO_ID_FBUFFER, DIO_ID2_HRMCATSEYE) },
    { DIO_ENCODE_ID(DIO_ID_FBUFFER, DIO_ID2_TOPCAT) },
    { 0 }
};

static struct dio_driver hpfb_driver = {
    .name      = "hpfb",
    .id_table  = hpfb_dio_tbl,
    .probe     = hpfb_dio_probe,
    .remove    = hpfb_remove_one,
};

static int __init hpfb_init(void)
{
	unsigned int sid;
	unsigned char i;
	int err;

	/* Topcats can be on the internal IO bus or real DIO devices.
	 * The internal variant sits at 0x560000; it has primary
	 * and secondary ID registers just like the DIO version.
	 * So we merge the two detection routines.
	 *
	 * Perhaps this #define should be in a global header file:
	 * I believe it's common to all internal fbs, not just topcat.
	 */
#define INTFBVADDR 0xf0560000
#define INTFBPADDR 0x560000

	if (!MACH_IS_HP300)
		return -ENODEV;

	if (fb_get_options("hpfb", NULL))
		return -ENODEV;

	err = dio_register_driver(&hpfb_driver);
	if (err)
		return err;

	err = copy_from_kernel_nofault(&i, (unsigned char *)INTFBVADDR + DIO_IDOFF, 1);

	if (!err && (i == DIO_ID_FBUFFER) && topcat_sid_ok(sid = DIO_SECID(INTFBVADDR))) {
		if (!request_mem_region(INTFBPADDR, DIO_DEVSIZE, "Internal Topcat"))
			return -EBUSY;
		printk(KERN_INFO "Internal Topcat found (secondary id %02x)\n", sid);
		if (hpfb_init_one(INTFBPADDR, INTFBVADDR)) {
			return -ENOMEM;
		}
	}
	return 0;
}

static void __exit hpfb_cleanup_module(void)
{
	dio_unregister_driver(&hpfb_driver);
}

module_init(hpfb_init);
module_exit(hpfb_cleanup_module);

MODULE_LICENSE("GPL");
