/*
 *  drivers/video/chipsfb.c -- frame buffer device for
 *  Chips & Technologies 65550 chip.
 *
 *  Copyright (C) 1998-2002 Paul Mackerras
 *
 *  This file is derived from the Powermac "chips" driver:
 *  Copyright (C) 1997 Fabio Riccardi.
 *  And from the frame buffer device for Open Firmware-initialized devices:
 *  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/fb.h>
#include <linux/pm.h>
#include <linux/init.h>
#include <linux/pci.h>
#include <linux/console.h>
#include <asm/io.h>

#ifdef CONFIG_PMAC_BACKLIGHT
#include <asm/backlight.h>
#endif

/*
 * Since we access the display with inb/outb to fixed port numbers,
 * we can only handle one 6555x chip.  -- paulus
 */
#define write_ind(num, val, ap, dp)	do { \
	outb((num), (ap)); outb((val), (dp)); \
} while (0)
#define read_ind(num, var, ap, dp)	do { \
	outb((num), (ap)); var = inb((dp)); \
} while (0)

/* extension registers */
#define write_xr(num, val)	write_ind(num, val, 0x3d6, 0x3d7)
#define read_xr(num, var)	read_ind(num, var, 0x3d6, 0x3d7)
/* flat panel registers */
#define write_fr(num, val)	write_ind(num, val, 0x3d0, 0x3d1)
#define read_fr(num, var)	read_ind(num, var, 0x3d0, 0x3d1)
/* CRTC registers */
#define write_cr(num, val)	write_ind(num, val, 0x3d4, 0x3d5)
#define read_cr(num, var)	read_ind(num, var, 0x3d4, 0x3d5)
/* graphics registers */
#define write_gr(num, val)	write_ind(num, val, 0x3ce, 0x3cf)
#define read_gr(num, var)	read_ind(num, var, 0x3ce, 0x3cf)
/* sequencer registers */
#define write_sr(num, val)	write_ind(num, val, 0x3c4, 0x3c5)
#define read_sr(num, var)	read_ind(num, var, 0x3c4, 0x3c5)
/* attribute registers - slightly strange */
#define write_ar(num, val)	do { \
	inb(0x3da); write_ind(num, val, 0x3c0, 0x3c0); \
} while (0)
#define read_ar(num, var)	do { \
	inb(0x3da); read_ind(num, var, 0x3c0, 0x3c1); \
} while (0)

/*
 * Exported functions
 */
int chips_init(void);

static int chipsfb_pci_init(struct pci_dev *dp, const struct pci_device_id *);
static int chipsfb_check_var(struct fb_var_screeninfo *var,
			     struct fb_info *info);
static int chipsfb_set_par(struct fb_info *info);
static int chipsfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
			     u_int transp, struct fb_info *info);
static int chipsfb_blank(int blank, struct fb_info *info);

static struct fb_ops chipsfb_ops = {
	.owner		= THIS_MODULE,
	.fb_check_var	= chipsfb_check_var,
	.fb_set_par	= chipsfb_set_par,
	.fb_setcolreg	= chipsfb_setcolreg,
	.fb_blank	= chipsfb_blank,
	.fb_fillrect	= cfb_fillrect,
	.fb_copyarea	= cfb_copyarea,
	.fb_imageblit	= cfb_imageblit,
};

static int chipsfb_check_var(struct fb_var_screeninfo *var,
			     struct fb_info *info)
{
	if (var->xres > 800 || var->yres > 600
	    || var->xres_virtual > 800 || var->yres_virtual > 600
	    || (var->bits_per_pixel != 8 && var->bits_per_pixel != 16)
	    || var->nonstd
	    || (var->vmode & FB_VMODE_MASK) != FB_VMODE_NONINTERLACED)
		return -EINVAL;

	var->xres = var->xres_virtual = 800;
	var->yres = var->yres_virtual = 600;

	return 0;
}

static int chipsfb_set_par(struct fb_info *info)
{
	if (info->var.bits_per_pixel == 16) {
		write_cr(0x13, 200);		// Set line length (doublewords)
		write_xr(0x81, 0x14);		// 15 bit (555) color mode
		write_xr(0x82, 0x00);		// Disable palettes
		write_xr(0x20, 0x10);		// 16 bit blitter mode

		info->fix.line_length = 800*2;
		info->fix.visual = FB_VISUAL_TRUECOLOR;

		info->var.red.offset = 10;
		info->var.green.offset = 5;
		info->var.blue.offset = 0;
		info->var.red.length = info->var.green.length =
			info->var.blue.length = 5;
		
	} else {
		/* p->var.bits_per_pixel == 8 */
		write_cr(0x13, 100);		// Set line length (doublewords)
		write_xr(0x81, 0x12);		// 8 bit color mode
		write_xr(0x82, 0x08);		// Graphics gamma enable
		write_xr(0x20, 0x00);		// 8 bit blitter mode

		info->fix.line_length = 800;
		info->fix.visual = FB_VISUAL_PSEUDOCOLOR;		

 		info->var.red.offset = info->var.green.offset =
			info->var.blue.offset = 0;
		info->var.red.length = info->var.green.length =
			info->var.blue.length = 8;
		
	}
	return 0;
}

static int chipsfb_blank(int blank, struct fb_info *info)
{
	return 1;	/* get fb_blank to set the colormap to all black */
}

static int chipsfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
			     u_int transp, struct fb_info *info)
{
	if (regno > 255)
		return 1;
	red >>= 8;
	green >>= 8;
	blue >>= 8;
	outb(regno, 0x3c8);
	udelay(1);
	outb(red, 0x3c9);
	outb(green, 0x3c9);
	outb(blue, 0x3c9);

	return 0;
}

struct chips_init_reg {
	unsigned char addr;
	unsigned char data;
};

static struct chips_init_reg chips_init_sr[] = {
	{ 0x00, 0x03 },
	{ 0x01, 0x01 },
	{ 0x02, 0x0f },
	{ 0x04, 0x0e }
};

static struct chips_init_reg chips_init_gr[] = {
	{ 0x05, 0x00 },
	{ 0x06, 0x0d },
	{ 0x08, 0xff }
};

static struct chips_init_reg chips_init_ar[] = {
	{ 0x10, 0x01 },
	{ 0x12, 0x0f },
	{ 0x13, 0x00 }
};

static struct chips_init_reg chips_init_cr[] = {
	{ 0x00, 0x7f },
	{ 0x01, 0x63 },
	{ 0x02, 0x63 },
	{ 0x03, 0x83 },
	{ 0x04, 0x66 },
	{ 0x05, 0x10 },
	{ 0x06, 0x72 },
	{ 0x07, 0x3e },
	{ 0x08, 0x00 },
	{ 0x09, 0x40 },
	{ 0x0c, 0x00 },
	{ 0x0d, 0x00 },
	{ 0x10, 0x59 },
	{ 0x11, 0x0d },
	{ 0x12, 0x57 },
	{ 0x13, 0x64 },
	{ 0x14, 0x00 },
	{ 0x15, 0x57 },
	{ 0x16, 0x73 },
	{ 0x17, 0xe3 },
	{ 0x18, 0xff },
	{ 0x30, 0x02 },
	{ 0x31, 0x02 },
	{ 0x32, 0x02 },
	{ 0x33, 0x02 },
	{ 0x40, 0x00 },
	{ 0x41, 0x00 },
	{ 0x40, 0x80 }
};

static struct chips_init_reg chips_init_fr[] = {
	{ 0x01, 0x02 },
	{ 0x03, 0x08 },
	{ 0x04, 0x81 },
	{ 0x05, 0x21 },
	{ 0x08, 0x0c },
	{ 0x0a, 0x74 },
	{ 0x0b, 0x11 },
	{ 0x10, 0x0c },
	{ 0x11, 0xe0 },
	/* { 0x12, 0x40 }, -- 3400 needs 40, 2400 needs 48, no way to tell */
	{ 0x20, 0x63 },
	{ 0x21, 0x68 },
	{ 0x22, 0x19 },
	{ 0x23, 0x7f },
	{ 0x24, 0x68 },
	{ 0x26, 0x00 },
	{ 0x27, 0x0f },
	{ 0x30, 0x57 },
	{ 0x31, 0x58 },
	{ 0x32, 0x0d },
	{ 0x33, 0x72 },
	{ 0x34, 0x02 },
	{ 0x35, 0x22 },
	{ 0x36, 0x02 },
	{ 0x37, 0x00 }
};

static struct chips_init_reg chips_init_xr[] = {
	{ 0xce, 0x00 },		/* set default memory clock */
	{ 0xcc, 0x43 },		/* memory clock ratio */
	{ 0xcd, 0x18 },
	{ 0xce, 0xa1 },
	{ 0xc8, 0x84 },
	{ 0xc9, 0x0a },
	{ 0xca, 0x00 },
	{ 0xcb, 0x20 },
	{ 0xcf, 0x06 },
	{ 0xd0, 0x0e },
	{ 0x09, 0x01 },
	{ 0x0a, 0x02 },
	{ 0x0b, 0x01 },
	{ 0x20, 0x00 },
	{ 0x40, 0x03 },
	{ 0x41, 0x01 },
	{ 0x42, 0x00 },
	{ 0x80, 0x82 },
	{ 0x81, 0x12 },
	{ 0x82, 0x08 },
	{ 0xa0, 0x00 },
	{ 0xa8, 0x00 }
};

static void __init chips_hw_init(void)
{
	int i;

	for (i = 0; i < ARRAY_SIZE(chips_init_xr); ++i)
		write_xr(chips_init_xr[i].addr, chips_init_xr[i].data);
	outb(0x29, 0x3c2); /* set misc output reg */
	for (i = 0; i < ARRAY_SIZE(chips_init_sr); ++i)
		write_sr(chips_init_sr[i].addr, chips_init_sr[i].data);
	for (i = 0; i < ARRAY_SIZE(chips_init_gr); ++i)
		write_gr(chips_init_gr[i].addr, chips_init_gr[i].data);
	for (i = 0; i < ARRAY_SIZE(chips_init_ar); ++i)
		write_ar(chips_init_ar[i].addr, chips_init_ar[i].data);
	for (i = 0; i < ARRAY_SIZE(chips_init_cr); ++i)
		write_cr(chips_init_cr[i].addr, chips_init_cr[i].data);
	for (i = 0; i < ARRAY_SIZE(chips_init_fr); ++i)
		write_fr(chips_init_fr[i].addr, chips_init_fr[i].data);
}

static struct fb_fix_screeninfo chipsfb_fix = {
	.id =		"C&T 65550",
	.type =		FB_TYPE_PACKED_PIXELS,
	.visual =	FB_VISUAL_PSEUDOCOLOR,
	.accel =	FB_ACCEL_NONE,
	.line_length =	800,

// FIXME: Assumes 1MB frame buffer, but 65550 supports 1MB or 2MB.
// * "3500" PowerBook G3 (the original PB G3) has 2MB.
// * 2400 has 1MB composed of 2 Mitsubishi M5M4V4265CTP DRAM chips.
//   Motherboard actually supports 2MB -- there are two blank locations
//   for a second pair of DRAMs.  (Thanks, Apple!)
// * 3400 has 1MB (I think).  Don't know if it's expandable.
// -- Tim Seufert
	.smem_len =	0x100000,	/* 1MB */
};

static struct fb_var_screeninfo chipsfb_var = {
	.xres = 800,
	.yres = 600,
	.xres_virtual = 800,
	.yres_virtual = 600,
	.bits_per_pixel = 8,
	.red = { .length = 8 },
	.green = { .length = 8 },
	.blue = { .length = 8 },
	.height = -1,
	.width = -1,
	.vmode = FB_VMODE_NONINTERLACED,
	.pixclock = 10000,
	.left_margin = 16,
	.right_margin = 16,
	.upper_margin = 16,
	.lower_margin = 16,
	.hsync_len = 8,
	.vsync_len = 8,
};

static void init_chips(struct fb_info *p, unsigned long addr)
{
	memset(p->screen_base, 0, 0x100000);

	p->fix = chipsfb_fix;
	p->fix.smem_start = addr;

	p->var = chipsfb_var;

	p->fbops = &chipsfb_ops;
	p->flags = FBINFO_DEFAULT;

	fb_alloc_cmap(&p->cmap, 256, 0);

	chips_hw_init();
}

static int chipsfb_pci_init(struct pci_dev *dp, const struct pci_device_id *ent)
{
	struct fb_info *p;
	unsigned long addr, size;
	unsigned short cmd;
	int rc = -ENODEV;

	if (pci_enable_device(dp) < 0) {
		dev_err(&dp->dev, "Cannot enable PCI device\n");
		goto err_out;
	}

	if ((dp->resource[0].flags & IORESOURCE_MEM) == 0)
		goto err_disable;
	addr = pci_resource_start(dp, 0);
	size = pci_resource_len(dp, 0);
	if (addr == 0)
		goto err_disable;

	p = framebuffer_alloc(0, &dp->dev);
	if (p == NULL) {
		dev_err(&dp->dev, "Cannot allocate framebuffer structure\n");
		rc = -ENOMEM;
		goto err_disable;
	}

	if (pci_request_region(dp, 0, "chipsfb") != 0) {
		dev_err(&dp->dev, "Cannot request framebuffer\n");
		rc = -EBUSY;
		goto err_release_fb;
	}

#ifdef __BIG_ENDIAN
	addr += 0x800000;	// Use big-endian aperture
#endif

	/* we should use pci_enable_device here, but,
	   the device doesn't declare its I/O ports in its BARs
	   so pci_enable_device won't turn on I/O responses */
	pci_read_config_word(dp, PCI_COMMAND, &cmd);
	cmd |= 3;	/* enable memory and IO space */
	pci_write_config_word(dp, PCI_COMMAND, cmd);

#ifdef CONFIG_PMAC_BACKLIGHT
	/* turn on the backlight */
	mutex_lock(&pmac_backlight_mutex);
	if (pmac_backlight) {
		pmac_backlight->props.power = FB_BLANK_UNBLANK;
		backlight_update_status(pmac_backlight);
	}
	mutex_unlock(&pmac_backlight_mutex);
#endif /* CONFIG_PMAC_BACKLIGHT */

#ifdef CONFIG_PPC
	p->screen_base = __ioremap(addr, 0x200000, _PAGE_NO_CACHE);
#else
	p->screen_base = ioremap(addr, 0x200000);
#endif
	if (p->screen_base == NULL) {
		dev_err(&dp->dev, "Cannot map framebuffer\n");
		rc = -ENOMEM;
		goto err_release_pci;
	}

	pci_set_drvdata(dp, p);

	init_chips(p, addr);

	if (register_framebuffer(p) < 0) {
		dev_err(&dp->dev,"C&T 65550 framebuffer failed to register\n");
		goto err_unmap;
	}

	dev_info(&dp->dev,"fb%d: Chips 65550 frame buffer"
		 " (%dK RAM detected)\n",
		 p->node, p->fix.smem_len / 1024);

	return 0;

 err_unmap:
	iounmap(p->screen_base);
 err_release_pci:
	pci_release_region(dp, 0);
 err_release_fb:
	framebuffer_release(p);
 err_disable:
 err_out:
	return rc;
}

static void chipsfb_remove(struct pci_dev *dp)
{
	struct fb_info *p = pci_get_drvdata(dp);

	if (p->screen_base == NULL)
		return;
	unregister_framebuffer(p);
	iounmap(p->screen_base);
	p->screen_base = NULL;
	pci_release_region(dp, 0);
}

#ifdef CONFIG_PM
static int chipsfb_pci_suspend(struct pci_dev *pdev, pm_message_t state)
{
        struct fb_info *p = pci_get_drvdata(pdev);

	if (state.event == pdev->dev.power.power_state.event)
		return 0;
	if (!(state.event & PM_EVENT_SLEEP))
		goto done;

	console_lock();
	chipsfb_blank(1, p);
	fb_set_suspend(p, 1);
	console_unlock();
 done:
	pdev->dev.power.power_state = state;
	return 0;
}

static int chipsfb_pci_resume(struct pci_dev *pdev)
{
        struct fb_info *p = pci_get_drvdata(pdev);

	console_lock();
	fb_set_suspend(p, 0);
	chipsfb_blank(0, p);
	console_unlock();

	pdev->dev.power.power_state = PMSG_ON;
	return 0;
}
#endif /* CONFIG_PM */


static struct pci_device_id chipsfb_pci_tbl[] = {
	{ PCI_VENDOR_ID_CT, PCI_DEVICE_ID_CT_65550, PCI_ANY_ID, PCI_ANY_ID },
	{ 0 }
};

MODULE_DEVICE_TABLE(pci, chipsfb_pci_tbl);

static struct pci_driver chipsfb_driver = {
	.name =		"chipsfb",
	.id_table =	chipsfb_pci_tbl,
	.probe =	chipsfb_pci_init,
	.remove =	chipsfb_remove,
#ifdef CONFIG_PM
	.suspend =	chipsfb_pci_suspend,
	.resume =	chipsfb_pci_resume,
#endif
};

int __init chips_init(void)
{
	if (fb_get_options("chipsfb", NULL))
		return -ENODEV;

	return pci_register_driver(&chipsfb_driver);
}

module_init(chips_init);

static void __exit chipsfb_exit(void)
{
	pci_unregister_driver(&chipsfb_driver);
}

MODULE_LICENSE("GPL");
