/*
 * Permedia2 framebuffer driver.
 *
 * 2.5/2.6 driver:
 * Copyright (c) 2003 Jim Hague (jim.hague@acm.org)
 *
 * based on 2.4 driver:
 * Copyright (c) 1998-2000 Ilario Nardinocchi (nardinoc@CS.UniBO.IT)
 * Copyright (c) 1999 Jakub Jelinek (jakub@redhat.com)
 *
 * and additional input from James Simmon's port of Hannu Mallat's tdfx
 * driver.
 *
 * I have a Creative Graphics Blaster Exxtreme card - pm2fb on x86.  I
 * have no access to other pm2fb implementations. Sparc (and thus
 * hopefully other big-endian) devices now work, thanks to a lot of
 * testing work by Ron Murray. I have no access to CVision hardware,
 * and therefore for now I am omitting the CVision code.
 *
 * Multiple boards support has been on the TODO list for ages.
 * Don't expect this to change.
 *
 * 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/moduleparam.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/fb.h>
#include <linux/init.h>
#include <linux/pci.h>

#include <video/permedia2.h>
#include <video/cvisionppc.h>

#if !defined(__LITTLE_ENDIAN) && !defined(__BIG_ENDIAN)
#error	"The endianness of the target host has not been defined."
#endif

#if !defined(CONFIG_PCI)
#error "Only generic PCI cards supported."
#endif

#undef PM2FB_MASTER_DEBUG
#ifdef PM2FB_MASTER_DEBUG
#define DPRINTK(a,b...)	printk(KERN_DEBUG "pm2fb: %s: " a, __FUNCTION__ , ## b)
#else
#define DPRINTK(a,b...)
#endif

/*
 * Driver data 
 */
static char *mode __devinitdata = NULL;

/*
 * The XFree GLINT driver will (I think to implement hardware cursor
 * support on TVP4010 and similar where there is no RAMDAC - see
 * comment in set_video) always request +ve sync regardless of what
 * the mode requires. This screws me because I have a Sun
 * fixed-frequency monitor which absolutely has to have -ve sync. So
 * these flags allow the user to specify that requests for +ve sync
 * should be silently turned in -ve sync.
 */
static int lowhsync;
static int lowvsync;

/*
 * The hardware state of the graphics card that isn't part of the
 * screeninfo.
 */
struct pm2fb_par
{
	pm2type_t	type;		/* Board type */
	unsigned char	__iomem *v_regs;/* virtual address of p_regs */
	u32 	   	memclock;	/* memclock */
	u32		video;		/* video flags before blanking */
	u32		mem_config;	/* MemConfig reg at probe */
	u32		mem_control;	/* MemControl reg at probe */
	u32		boot_address;	/* BootAddress reg at probe */
	u32             palette[16];
};

/*
 * Here we define the default structs fb_fix_screeninfo and fb_var_screeninfo
 * if we don't use modedb.
 */
static struct fb_fix_screeninfo pm2fb_fix __devinitdata = {
	.id =		"", 
	.type =		FB_TYPE_PACKED_PIXELS,
	.visual =	FB_VISUAL_PSEUDOCOLOR,
	.xpanstep =	1,
	.ypanstep =	1,
	.ywrapstep =	0, 
	.accel =	FB_ACCEL_3DLABS_PERMEDIA2,
};

/*
 * Default video mode. In case the modedb doesn't work.
 */
static struct fb_var_screeninfo pm2fb_var __devinitdata = {
	/* "640x480, 8 bpp @ 60 Hz */
	.xres =		640,
	.yres =		480,
	.xres_virtual =	640,
	.yres_virtual =	480,
	.bits_per_pixel =8,
	.red =		{0, 8, 0},
	.blue =		{0, 8, 0},
	.green =	{0, 8, 0},
	.activate =	FB_ACTIVATE_NOW,
	.height =	-1,
	.width =	-1,
	.accel_flags =	0,
	.pixclock =	39721,
	.left_margin =	40,
	.right_margin =	24,
	.upper_margin =	32,
	.lower_margin =	11,
	.hsync_len =	96,
	.vsync_len =	2,
	.vmode =	FB_VMODE_NONINTERLACED
};

/*
 * Utility functions
 */

static inline u32 RD32(unsigned char __iomem *base, s32 off)
{
	return fb_readl(base + off);
}

static inline void WR32(unsigned char __iomem *base, s32 off, u32 v)
{
	fb_writel(v, base + off);
}

static inline u32 pm2_RD(struct pm2fb_par* p, s32 off)
{
	return RD32(p->v_regs, off);
}

static inline void pm2_WR(struct pm2fb_par* p, s32 off, u32 v)
{
	WR32(p->v_regs, off, v);
}

static inline u32 pm2_RDAC_RD(struct pm2fb_par* p, s32 idx)
{
	int index = PM2R_RD_INDEXED_DATA;
	switch (p->type) {
	case PM2_TYPE_PERMEDIA2:
		pm2_WR(p, PM2R_RD_PALETTE_WRITE_ADDRESS, idx);
		break;
	case PM2_TYPE_PERMEDIA2V:
		pm2_WR(p, PM2VR_RD_INDEX_LOW, idx & 0xff);
		index = PM2VR_RD_INDEXED_DATA;
		break;
	}	
	mb();
	return pm2_RD(p, index);
}

static inline void pm2_RDAC_WR(struct pm2fb_par* p, s32 idx, u32 v)
{
	int index = PM2R_RD_INDEXED_DATA;
	switch (p->type) {
	case PM2_TYPE_PERMEDIA2:
		pm2_WR(p, PM2R_RD_PALETTE_WRITE_ADDRESS, idx);
		break;
	case PM2_TYPE_PERMEDIA2V:
		pm2_WR(p, PM2VR_RD_INDEX_LOW, idx & 0xff);
		index = PM2VR_RD_INDEXED_DATA;
		break;
	}	
	mb();
	pm2_WR(p, index, v);
}

static inline void pm2v_RDAC_WR(struct pm2fb_par* p, s32 idx, u32 v)
{
	pm2_WR(p, PM2VR_RD_INDEX_LOW, idx & 0xff);
	mb();
	pm2_WR(p, PM2VR_RD_INDEXED_DATA, v);
}

#ifdef CONFIG_FB_PM2_FIFO_DISCONNECT
#define WAIT_FIFO(p,a)
#else
static inline void WAIT_FIFO(struct pm2fb_par* p, u32 a)
{
	while( pm2_RD(p, PM2R_IN_FIFO_SPACE) < a );
	mb();
}
#endif

static void wait_pm2(struct pm2fb_par* par) {

	WAIT_FIFO(par, 1);
	pm2_WR(par, PM2R_SYNC, 0);
	mb();
	do {
		while (pm2_RD(par, PM2R_OUT_FIFO_WORDS) == 0);
		rmb();
	} while (pm2_RD(par, PM2R_OUT_FIFO) != PM2TAG(PM2R_SYNC));
}

/*
 * partial products for the supported horizontal resolutions.
 */
#define PACKPP(p0,p1,p2)	(((p2) << 6) | ((p1) << 3) | (p0))
static const struct {
	u16 width;
	u16 pp;
} pp_table[] = {
	{ 32,	PACKPP(1, 0, 0) }, { 64,	PACKPP(1, 1, 0) },
	{ 96,	PACKPP(1, 1, 1) }, { 128,	PACKPP(2, 1, 1) },
	{ 160,	PACKPP(2, 2, 1) }, { 192,	PACKPP(2, 2, 2) },
	{ 224,	PACKPP(3, 2, 1) }, { 256,	PACKPP(3, 2, 2) },
	{ 288,	PACKPP(3, 3, 1) }, { 320,	PACKPP(3, 3, 2) },
	{ 384,	PACKPP(3, 3, 3) }, { 416,	PACKPP(4, 3, 1) },
	{ 448,	PACKPP(4, 3, 2) }, { 512,	PACKPP(4, 3, 3) },
	{ 544,	PACKPP(4, 4, 1) }, { 576,	PACKPP(4, 4, 2) },
	{ 640,	PACKPP(4, 4, 3) }, { 768,	PACKPP(4, 4, 4) },
	{ 800,	PACKPP(5, 4, 1) }, { 832,	PACKPP(5, 4, 2) },
	{ 896,	PACKPP(5, 4, 3) }, { 1024,	PACKPP(5, 4, 4) },
	{ 1056,	PACKPP(5, 5, 1) }, { 1088,	PACKPP(5, 5, 2) },
	{ 1152,	PACKPP(5, 5, 3) }, { 1280,	PACKPP(5, 5, 4) },
	{ 1536,	PACKPP(5, 5, 5) }, { 1568,	PACKPP(6, 5, 1) },
	{ 1600,	PACKPP(6, 5, 2) }, { 1664,	PACKPP(6, 5, 3) },
	{ 1792,	PACKPP(6, 5, 4) }, { 2048,	PACKPP(6, 5, 5) },
	{ 0,	0 } };

static u32 partprod(u32 xres)
{
	int i;

	for (i = 0; pp_table[i].width && pp_table[i].width != xres; i++)
		;
	if ( pp_table[i].width == 0 )
		DPRINTK("invalid width %u\n", xres);
	return pp_table[i].pp;
}

static u32 to3264(u32 timing, int bpp, int is64)
{
	switch (bpp) {
	case 8:
		timing >>= 2 + is64;
		break;
	case 16:
		timing >>= 1 + is64;
		break;
	case 24:
		timing = (timing * 3) >> (2 + is64);
		break;
	case 32:
		if (is64)
			timing >>= 1;
		break;
	}
	return timing;
}

static void pm2_mnp(u32 clk, unsigned char* mm, unsigned char* nn,
		    unsigned char* pp)
{
	unsigned char m;
	unsigned char n;
	unsigned char p;
	u32 f;
	s32 curr;
	s32 delta = 100000;

	*mm = *nn = *pp = 0;
	for (n = 2; n < 15; n++) {
		for (m = 2; m; m++) {
			f = PM2_REFERENCE_CLOCK * m / n;
			if (f >= 150000 && f <= 300000) {
				for ( p = 0; p < 5; p++, f >>= 1) {
					curr = ( clk > f ) ? clk - f : f - clk;
					if ( curr < delta ) {
						delta=curr;
						*mm=m;
						*nn=n;
						*pp=p;
					}
				}
			}
		}
	}
}

static void pm2v_mnp(u32 clk, unsigned char* mm, unsigned char* nn,
		     unsigned char* pp)
{
	unsigned char m;
	unsigned char n;
	unsigned char p;
	u32 f;
	s32 delta = 1000;

	*mm = *nn = *pp = 0;
	for ( m = 1; m < 128; m++) {
		for (n = 2 * m + 1; n; n++) {
			for ( p = 0; p < 2; p++) {
				f = ( PM2_REFERENCE_CLOCK >> ( p + 1 )) * n / m;
				if ( clk > f - delta && clk < f + delta ) {
					delta = ( clk > f ) ? clk - f : f - clk;
					*mm=m;
					*nn=n;
					*pp=p;
				}
			}
		}
	}
}

static void clear_palette(struct pm2fb_par* p) {
	int i=256;

	WAIT_FIFO(p, 1);
	pm2_WR(p, PM2R_RD_PALETTE_WRITE_ADDRESS, 0);
	wmb();
	while (i--) {
		WAIT_FIFO(p, 3);
		pm2_WR(p, PM2R_RD_PALETTE_DATA, 0);
		pm2_WR(p, PM2R_RD_PALETTE_DATA, 0);
		pm2_WR(p, PM2R_RD_PALETTE_DATA, 0);
	}
}

static void reset_card(struct pm2fb_par* p)
{
	if (p->type == PM2_TYPE_PERMEDIA2V)
		pm2_WR(p, PM2VR_RD_INDEX_HIGH, 0);
	pm2_WR(p, PM2R_RESET_STATUS, 0);
	mb();
	while (pm2_RD(p, PM2R_RESET_STATUS) & PM2F_BEING_RESET)
		;
	mb();
#ifdef CONFIG_FB_PM2_FIFO_DISCONNECT
	DPRINTK("FIFO disconnect enabled\n");
	pm2_WR(p, PM2R_FIFO_DISCON, 1);
	mb();
#endif

	/* Restore stashed memory config information from probe */
	WAIT_FIFO(p, 3);
	pm2_WR(p, PM2R_MEM_CONTROL, p->mem_control);
	pm2_WR(p, PM2R_BOOT_ADDRESS, p->boot_address);
	wmb();
	pm2_WR(p, PM2R_MEM_CONFIG, p->mem_config);
}

static void reset_config(struct pm2fb_par* p)
{
	WAIT_FIFO(p, 52);
	pm2_WR(p, PM2R_CHIP_CONFIG, pm2_RD(p, PM2R_CHIP_CONFIG)&
	       ~(PM2F_VGA_ENABLE|PM2F_VGA_FIXED));
	pm2_WR(p, PM2R_BYPASS_WRITE_MASK, ~(0L));
	pm2_WR(p, PM2R_FRAMEBUFFER_WRITE_MASK, ~(0L));
	pm2_WR(p, PM2R_FIFO_CONTROL, 0);
	pm2_WR(p, PM2R_APERTURE_ONE, 0);
	pm2_WR(p, PM2R_APERTURE_TWO, 0);
	pm2_WR(p, PM2R_RASTERIZER_MODE, 0);
	pm2_WR(p, PM2R_DELTA_MODE, PM2F_DELTA_ORDER_RGB);
	pm2_WR(p, PM2R_LB_READ_FORMAT, 0);
	pm2_WR(p, PM2R_LB_WRITE_FORMAT, 0); 
	pm2_WR(p, PM2R_LB_READ_MODE, 0);
	pm2_WR(p, PM2R_LB_SOURCE_OFFSET, 0);
	pm2_WR(p, PM2R_FB_SOURCE_OFFSET, 0);
	pm2_WR(p, PM2R_FB_PIXEL_OFFSET, 0);
	pm2_WR(p, PM2R_FB_WINDOW_BASE, 0);
	pm2_WR(p, PM2R_LB_WINDOW_BASE, 0);
	pm2_WR(p, PM2R_FB_SOFT_WRITE_MASK, ~(0L));
	pm2_WR(p, PM2R_FB_HARD_WRITE_MASK, ~(0L));
	pm2_WR(p, PM2R_FB_READ_PIXEL, 0);
	pm2_WR(p, PM2R_DITHER_MODE, 0);
	pm2_WR(p, PM2R_AREA_STIPPLE_MODE, 0);
	pm2_WR(p, PM2R_DEPTH_MODE, 0);
	pm2_WR(p, PM2R_STENCIL_MODE, 0);
	pm2_WR(p, PM2R_TEXTURE_ADDRESS_MODE, 0);
	pm2_WR(p, PM2R_TEXTURE_READ_MODE, 0);
	pm2_WR(p, PM2R_TEXEL_LUT_MODE, 0);
	pm2_WR(p, PM2R_YUV_MODE, 0);
	pm2_WR(p, PM2R_COLOR_DDA_MODE, 0);
	pm2_WR(p, PM2R_TEXTURE_COLOR_MODE, 0);
	pm2_WR(p, PM2R_FOG_MODE, 0);
	pm2_WR(p, PM2R_ALPHA_BLEND_MODE, 0);
	pm2_WR(p, PM2R_LOGICAL_OP_MODE, 0);
	pm2_WR(p, PM2R_STATISTICS_MODE, 0);
	pm2_WR(p, PM2R_SCISSOR_MODE, 0);
	pm2_WR(p, PM2R_FILTER_MODE, PM2F_SYNCHRONIZATION);
	switch (p->type) {
	case PM2_TYPE_PERMEDIA2:
		pm2_RDAC_WR(p, PM2I_RD_MODE_CONTROL, 0); /* no overlay */
		pm2_RDAC_WR(p, PM2I_RD_CURSOR_CONTROL, 0);
		pm2_RDAC_WR(p, PM2I_RD_MISC_CONTROL, PM2F_RD_PALETTE_WIDTH_8);
		break;
	case PM2_TYPE_PERMEDIA2V:
		pm2v_RDAC_WR(p, PM2VI_RD_MISC_CONTROL, 1); /* 8bit */
		break;
	}
	pm2_RDAC_WR(p, PM2I_RD_COLOR_KEY_CONTROL, 0);
	pm2_RDAC_WR(p, PM2I_RD_OVERLAY_KEY, 0);
	pm2_RDAC_WR(p, PM2I_RD_RED_KEY, 0);
	pm2_RDAC_WR(p, PM2I_RD_GREEN_KEY, 0);
	pm2_RDAC_WR(p, PM2I_RD_BLUE_KEY, 0);
}

static void set_aperture(struct pm2fb_par* p, u32 depth)
{
	/*
	 * The hardware is little-endian. When used in big-endian
	 * hosts, the on-chip aperture settings are used where
	 * possible to translate from host to card byte order.
	 */
	WAIT_FIFO(p, 4);
#ifdef __LITTLE_ENDIAN
	pm2_WR(p, PM2R_APERTURE_ONE, PM2F_APERTURE_STANDARD);
#else
	switch (depth) {
	case 24:	/* RGB->BGR */
		/*
		 * We can't use the aperture to translate host to
		 * card byte order here, so we switch to BGR mode
		 * in pm2fb_set_par().
		 */
	case 8:		/* B->B */
		pm2_WR(p, PM2R_APERTURE_ONE, PM2F_APERTURE_STANDARD);
		break;
	case 16:	/* HL->LH */
		pm2_WR(p, PM2R_APERTURE_ONE, PM2F_APERTURE_HALFWORDSWAP);
		break;
	case 32:	/* RGBA->ABGR */
		pm2_WR(p, PM2R_APERTURE_ONE, PM2F_APERTURE_BYTESWAP);
		break;
	}
#endif

	// We don't use aperture two, so this may be superflous
	pm2_WR(p, PM2R_APERTURE_TWO, PM2F_APERTURE_STANDARD);
}

static void set_color(struct pm2fb_par* p, unsigned char regno,
		      unsigned char r, unsigned char g, unsigned char b)
{
	WAIT_FIFO(p, 4);
	pm2_WR(p, PM2R_RD_PALETTE_WRITE_ADDRESS, regno);
	wmb();
	pm2_WR(p, PM2R_RD_PALETTE_DATA, r);
	wmb();
	pm2_WR(p, PM2R_RD_PALETTE_DATA, g);
	wmb();
	pm2_WR(p, PM2R_RD_PALETTE_DATA, b);
}

static void set_memclock(struct pm2fb_par* par, u32 clk)
{
	int i;
	unsigned char m, n, p;

	switch (par->type) {
	case PM2_TYPE_PERMEDIA2V:
		pm2v_mnp(clk/2, &m, &n, &p);
		WAIT_FIFO(par, 8);
		pm2_WR(par, PM2VR_RD_INDEX_HIGH, PM2VI_RD_MCLK_CONTROL >> 8);
		pm2v_RDAC_WR(par, PM2VI_RD_MCLK_CONTROL, 0);
		wmb();
		pm2v_RDAC_WR(par, PM2VI_RD_MCLK_PRESCALE, m);
		pm2v_RDAC_WR(par, PM2VI_RD_MCLK_FEEDBACK, n);
		pm2v_RDAC_WR(par, PM2VI_RD_MCLK_POSTSCALE, p);
		wmb();
		pm2v_RDAC_WR(par, PM2VI_RD_MCLK_CONTROL, 1);
		rmb();
		for (i = 256;
		     i && !(pm2_RDAC_RD(par, PM2VI_RD_MCLK_CONTROL) & 2);
		     i--)
			;
		pm2_WR(par, PM2VR_RD_INDEX_HIGH, 0);
		break;
	case PM2_TYPE_PERMEDIA2:
		pm2_mnp(clk, &m, &n, &p);
		WAIT_FIFO(par, 10);
		pm2_RDAC_WR(par, PM2I_RD_MEMORY_CLOCK_3, 6);
		wmb();
		pm2_RDAC_WR(par, PM2I_RD_MEMORY_CLOCK_1, m);
		pm2_RDAC_WR(par, PM2I_RD_MEMORY_CLOCK_2, n);
		wmb();
		pm2_RDAC_WR(par, PM2I_RD_MEMORY_CLOCK_3, 8|p);
		wmb();
		pm2_RDAC_RD(par, PM2I_RD_MEMORY_CLOCK_STATUS);
		rmb();
		for (i = 256;
		     i && !(pm2_RD(par, PM2R_RD_INDEXED_DATA) & PM2F_PLL_LOCKED);
		     i--)
			;
		break;
	}
}

static void set_pixclock(struct pm2fb_par* par, u32 clk)
{
	int i;
	unsigned char m, n, p;

	switch (par->type) {
	case PM2_TYPE_PERMEDIA2:
		pm2_mnp(clk, &m, &n, &p);
		WAIT_FIFO(par, 8);
		pm2_RDAC_WR(par, PM2I_RD_PIXEL_CLOCK_A3, 0);
		wmb();
		pm2_RDAC_WR(par, PM2I_RD_PIXEL_CLOCK_A1, m);
		pm2_RDAC_WR(par, PM2I_RD_PIXEL_CLOCK_A2, n);
		wmb();
		pm2_RDAC_WR(par, PM2I_RD_PIXEL_CLOCK_A3, 8|p);
		wmb();
		pm2_RDAC_RD(par, PM2I_RD_PIXEL_CLOCK_STATUS);
		rmb();
		for (i = 256;
		     i && !(pm2_RD(par, PM2R_RD_INDEXED_DATA) & PM2F_PLL_LOCKED);
		     i--)
			;
		break;
	case PM2_TYPE_PERMEDIA2V:
		pm2v_mnp(clk/2, &m, &n, &p);
		WAIT_FIFO(par, 8);
		pm2_WR(par, PM2VR_RD_INDEX_HIGH, PM2VI_RD_CLK0_PRESCALE >> 8);
		pm2v_RDAC_WR(par, PM2VI_RD_CLK0_PRESCALE, m);
		pm2v_RDAC_WR(par, PM2VI_RD_CLK0_FEEDBACK, n);
		pm2v_RDAC_WR(par, PM2VI_RD_CLK0_POSTSCALE, p);
		pm2_WR(par, PM2VR_RD_INDEX_HIGH, 0);
		break;
	}
}

static void set_video(struct pm2fb_par* p, u32 video) {
	u32 tmp;
	u32 vsync;

	vsync = video;

	DPRINTK("video = 0x%x\n", video);
	
	/*
	 * The hardware cursor needs +vsync to recognise vert retrace.
	 * We may not be using the hardware cursor, but the X Glint
	 * driver may well. So always set +hsync/+vsync and then set
	 * the RAMDAC to invert the sync if necessary.
	 */
	vsync &= ~(PM2F_HSYNC_MASK|PM2F_VSYNC_MASK);
	vsync |= PM2F_HSYNC_ACT_HIGH|PM2F_VSYNC_ACT_HIGH;

	WAIT_FIFO(p, 5);
	pm2_WR(p, PM2R_VIDEO_CONTROL, vsync);

	switch (p->type) {
	case PM2_TYPE_PERMEDIA2:
		tmp = PM2F_RD_PALETTE_WIDTH_8;
		if ((video & PM2F_HSYNC_MASK) == PM2F_HSYNC_ACT_LOW)
			tmp |= 4; /* invert hsync */
		if ((video & PM2F_VSYNC_MASK) == PM2F_VSYNC_ACT_LOW)
			tmp |= 8; /* invert vsync */
		pm2_RDAC_WR(p, PM2I_RD_MISC_CONTROL, tmp);
		break;
	case PM2_TYPE_PERMEDIA2V:
		tmp = 0;
		if ((video & PM2F_HSYNC_MASK) == PM2F_HSYNC_ACT_LOW)
			tmp |= 1; /* invert hsync */
		if ((video & PM2F_VSYNC_MASK) == PM2F_VSYNC_ACT_LOW)
			tmp |= 4; /* invert vsync */
		pm2v_RDAC_WR(p, PM2VI_RD_SYNC_CONTROL, tmp);
		pm2v_RDAC_WR(p, PM2VI_RD_MISC_CONTROL, 1);
		break;
	}
}

/*
 *
 */

/**
 *      pm2fb_check_var - Optional function. Validates a var passed in. 
 *      @var: frame buffer variable screen structure
 *      @info: frame buffer structure that represents a single frame buffer 
 *
 *	Checks to see if the hardware supports the state requested by
 *	var passed in.
 *
 *	Returns negative errno on error, or zero on success.
 */
static int pm2fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
{
	u32 lpitch;

	if (var->bits_per_pixel != 8  && var->bits_per_pixel != 16 &&
	    var->bits_per_pixel != 24 && var->bits_per_pixel != 32) {
		DPRINTK("depth not supported: %u\n", var->bits_per_pixel);
		return -EINVAL;
	}

	if (var->xres != var->xres_virtual) {
		DPRINTK("virtual x resolution != physical x resolution not supported\n");
		return -EINVAL;
	}

	if (var->yres > var->yres_virtual) {
		DPRINTK("virtual y resolution < physical y resolution not possible\n");
		return -EINVAL;
	}

	if (var->xoffset) {
		DPRINTK("xoffset not supported\n");
		return -EINVAL;
	}

	if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
		DPRINTK("interlace not supported\n");
		return -EINVAL;
	}

	var->xres = (var->xres + 15) & ~15; /* could sometimes be 8 */
	lpitch = var->xres * ((var->bits_per_pixel + 7)>>3);
  
	if (var->xres < 320 || var->xres > 1600) {
		DPRINTK("width not supported: %u\n", var->xres);
		return -EINVAL;
	}
  
	if (var->yres < 200 || var->yres > 1200) {
		DPRINTK("height not supported: %u\n", var->yres);
		return -EINVAL;
	}
  
	if (lpitch * var->yres_virtual > info->fix.smem_len) {
		DPRINTK("no memory for screen (%ux%ux%u)\n",
			var->xres, var->yres_virtual, var->bits_per_pixel);
		return -EINVAL;
	}
  
	if (PICOS2KHZ(var->pixclock) > PM2_MAX_PIXCLOCK) {
		DPRINTK("pixclock too high (%ldKHz)\n", PICOS2KHZ(var->pixclock));
		return -EINVAL;
	}

	var->transp.offset = 0;
	var->transp.length = 0;
	switch(var->bits_per_pixel) {
	case 8:
		var->red.length = var->green.length = var->blue.length = 8;
		break;
	case 16:
		var->red.offset   = 11;
		var->red.length   = 5;
		var->green.offset = 5;
		var->green.length = 6;
		var->blue.offset  = 0;
		var->blue.length  = 5;
		break;
	case 32:
		var->transp.offset = 24;
		var->transp.length = 8;
		var->red.offset	  = 16;
		var->green.offset = 8;
		var->blue.offset  = 0;
		var->red.length = var->green.length = var->blue.length = 8;
		break;
	case 24:
#ifdef __BIG_ENDIAN
		var->red.offset   = 0;
		var->blue.offset  = 16;
#else
		var->red.offset   = 16;
		var->blue.offset  = 0;
#endif
		var->green.offset = 8;
		var->red.length = var->green.length = var->blue.length = 8;
		break;
	}
	var->height = var->width = -1;
  
	var->accel_flags = 0;	/* Can't mmap if this is on */
	
	DPRINTK("Checking graphics mode at %dx%d depth %d\n",
		var->xres, var->yres, var->bits_per_pixel);
	return 0;
}

/**
 *      pm2fb_set_par - Alters the hardware state.
 *      @info: frame buffer structure that represents a single frame buffer
 *
 *	Using the fb_var_screeninfo in fb_info we set the resolution of the
 *	this particular framebuffer.
 */
static int pm2fb_set_par(struct fb_info *info)
{
	struct pm2fb_par *par = info->par;
	u32 pixclock;
	u32 width, height, depth;
	u32 hsstart, hsend, hbend, htotal;
	u32 vsstart, vsend, vbend, vtotal;
	u32 stride;
	u32 base;
	u32 video = 0;
	u32 clrmode = PM2F_RD_COLOR_MODE_RGB | PM2F_RD_GUI_ACTIVE;
	u32 txtmap = 0;
	u32 pixsize = 0;
	u32 clrformat = 0;
	u32 xres;
	int data64;

	reset_card(par);
	reset_config(par);
	clear_palette(par);
	if ( par->memclock )
		set_memclock(par, par->memclock);
    
	width = (info->var.xres_virtual + 7) & ~7;
	height = info->var.yres_virtual;
	depth = (info->var.bits_per_pixel + 7) & ~7;
	depth = (depth > 32) ? 32 : depth;
	data64 = depth > 8 || par->type == PM2_TYPE_PERMEDIA2V;

	xres = (info->var.xres + 31) & ~31;
	pixclock = PICOS2KHZ(info->var.pixclock);
	if (pixclock > PM2_MAX_PIXCLOCK) {
		DPRINTK("pixclock too high (%uKHz)\n", pixclock);
		return -EINVAL;
	}
    
	hsstart = to3264(info->var.right_margin, depth, data64);
	hsend = hsstart + to3264(info->var.hsync_len, depth, data64);
	hbend = hsend + to3264(info->var.left_margin, depth, data64);
	htotal = to3264(xres, depth, data64) + hbend - 1;
	vsstart = (info->var.lower_margin)
		? info->var.lower_margin - 1
		: 0;	/* FIXME! */
	vsend = info->var.lower_margin + info->var.vsync_len - 1;
	vbend = info->var.lower_margin + info->var.vsync_len + info->var.upper_margin;
	vtotal = info->var.yres + vbend - 1;
	stride = to3264(width, depth, 1);
	base = to3264(info->var.yoffset * xres + info->var.xoffset, depth, 1);
	if (data64)
		video |= PM2F_DATA_64_ENABLE;
    
	if (info->var.sync & FB_SYNC_HOR_HIGH_ACT) {
		if (lowhsync) {
			DPRINTK("ignoring +hsync, using -hsync.\n");
			video |= PM2F_HSYNC_ACT_LOW;
		} else
			video |= PM2F_HSYNC_ACT_HIGH;
	}
	else
		video |= PM2F_HSYNC_ACT_LOW;
	if (info->var.sync & FB_SYNC_VERT_HIGH_ACT) {
		if (lowvsync) {
			DPRINTK("ignoring +vsync, using -vsync.\n");
			video |= PM2F_VSYNC_ACT_LOW;
		} else
			video |= PM2F_VSYNC_ACT_HIGH;
	}
	else
		video |= PM2F_VSYNC_ACT_LOW;
	if ((info->var.vmode & FB_VMODE_MASK)==FB_VMODE_INTERLACED) {
		DPRINTK("interlaced not supported\n");
		return -EINVAL;
	}
	if ((info->var.vmode & FB_VMODE_MASK)==FB_VMODE_DOUBLE)
		video |= PM2F_LINE_DOUBLE;
	if ((info->var.activate & FB_ACTIVATE_MASK)==FB_ACTIVATE_NOW)
		video |= PM2F_VIDEO_ENABLE;
	par->video = video;

	info->fix.visual =
		(depth == 8) ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR;
	info->fix.line_length = info->var.xres * depth / 8;
	info->cmap.len = 256;

	/*
	 * Settings calculated. Now write them out.
	 */
	if (par->type == PM2_TYPE_PERMEDIA2V) {
		WAIT_FIFO(par, 1);
		pm2_WR(par, PM2VR_RD_INDEX_HIGH, 0);
	}
    
	set_aperture(par, depth);
    
	mb();
	WAIT_FIFO(par, 19);
	pm2_RDAC_WR(par, PM2I_RD_COLOR_KEY_CONTROL,
		    ( depth == 8 ) ? 0 : PM2F_COLOR_KEY_TEST_OFF);
	switch (depth) {
	case 8:
		pm2_WR(par, PM2R_FB_READ_PIXEL, 0);
		clrformat = 0x0e;
		break;
	case 16:
		pm2_WR(par, PM2R_FB_READ_PIXEL, 1);
		clrmode |= PM2F_RD_TRUECOLOR | PM2F_RD_PIXELFORMAT_RGB565;
		txtmap = PM2F_TEXTEL_SIZE_16;
		pixsize = 1;
		clrformat = 0x70;
		break;
	case 32:
		pm2_WR(par, PM2R_FB_READ_PIXEL, 2);
		clrmode |= PM2F_RD_TRUECOLOR | PM2F_RD_PIXELFORMAT_RGBA8888;
		txtmap = PM2F_TEXTEL_SIZE_32;
		pixsize = 2;
		clrformat = 0x20;
		break;
	case 24:
		pm2_WR(par, PM2R_FB_READ_PIXEL, 4);
		clrmode |= PM2F_RD_TRUECOLOR | PM2F_RD_PIXELFORMAT_RGB888;
		txtmap = PM2F_TEXTEL_SIZE_24;
		pixsize = 4;
		clrformat = 0x20;
		break;
	}
	pm2_WR(par, PM2R_FB_WRITE_MODE, PM2F_FB_WRITE_ENABLE);
	pm2_WR(par, PM2R_FB_READ_MODE, partprod(xres));
	pm2_WR(par, PM2R_LB_READ_MODE, partprod(xres));
	pm2_WR(par, PM2R_TEXTURE_MAP_FORMAT, txtmap | partprod(xres));
	pm2_WR(par, PM2R_H_TOTAL, htotal);
	pm2_WR(par, PM2R_HS_START, hsstart);
	pm2_WR(par, PM2R_HS_END, hsend);
	pm2_WR(par, PM2R_HG_END, hbend);
	pm2_WR(par, PM2R_HB_END, hbend);
	pm2_WR(par, PM2R_V_TOTAL, vtotal);
	pm2_WR(par, PM2R_VS_START, vsstart);
	pm2_WR(par, PM2R_VS_END, vsend);
	pm2_WR(par, PM2R_VB_END, vbend);
	pm2_WR(par, PM2R_SCREEN_STRIDE, stride);
	wmb();
	pm2_WR(par, PM2R_WINDOW_ORIGIN, 0);
	pm2_WR(par, PM2R_SCREEN_SIZE, (height << 16) | width);
	pm2_WR(par, PM2R_SCISSOR_MODE, PM2F_SCREEN_SCISSOR_ENABLE);
	wmb();
	pm2_WR(par, PM2R_SCREEN_BASE, base);
	wmb();
	set_video(par, video);
	WAIT_FIFO(par, 4);
	switch (par->type) {
	case PM2_TYPE_PERMEDIA2:
		pm2_RDAC_WR(par, PM2I_RD_COLOR_MODE, clrmode);
		break;
	case PM2_TYPE_PERMEDIA2V:
		pm2v_RDAC_WR(par, PM2VI_RD_PIXEL_SIZE, pixsize);
		pm2v_RDAC_WR(par, PM2VI_RD_COLOR_FORMAT, clrformat);
		break;
	}
	set_pixclock(par, pixclock);
	DPRINTK("Setting graphics mode at %dx%d depth %d\n",
		info->var.xres, info->var.yres, info->var.bits_per_pixel);
	return 0;	
}

/**
 *  	pm2fb_setcolreg - 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
 * 
 *  	Set a single color register. The values supplied have a 16 bit
 *  	magnitude which needs to be scaled in this function for the hardware.
 *	Pretty much a direct lift from tdfxfb.c.
 * 
 *	Returns negative errno on error, or zero on success.
 */
static int pm2fb_setcolreg(unsigned regno, unsigned red, unsigned green,
			   unsigned blue, unsigned transp,
			   struct fb_info *info)
{
	struct pm2fb_par *par = info->par;

	if (regno >= info->cmap.len)  /* no. of hw registers */
		return 1;
	/*
	 * Program hardware... do anything you want with transp
	 */

	/* grayscale works only partially under directcolor */
	if (info->var.grayscale) {
		/* grayscale = 0.30*R + 0.59*G + 0.11*B */
		red = green = blue = (red * 77 + green * 151 + blue * 28) >> 8;
	}

	/* Directcolor:
	 *   var->{color}.offset contains start of bitfield
	 *   var->{color}.length contains length of bitfield
	 *   {hardwarespecific} contains width of DAC
	 *   cmap[X] is programmed to
	 *   (X << red.offset) | (X << green.offset) | (X << blue.offset)
	 *   RAMDAC[X] is programmed to (red, green, blue)
	 *
	 * Pseudocolor:
	 *    uses offset = 0 && length = DAC register width.
	 *    var->{color}.offset is 0
	 *    var->{color}.length contains widht of DAC
	 *    cmap is not used
	 *    DAC[X] is programmed to (red, green, blue)
	 * Truecolor:
	 *    does not use RAMDAC (usually has 3 of them).
	 *    var->{color}.offset contains start of bitfield
	 *    var->{color}.length contains length of bitfield
	 *    cmap is programmed to
	 *    (red << red.offset) | (green << green.offset) |
	 *    (blue << blue.offset) | (transp << transp.offset)
	 *    RAMDAC does not exist
	 */
#define CNVT_TOHW(val,width) ((((val)<<(width))+0x7FFF-(val))>>16)
	switch (info->fix.visual) {
	case FB_VISUAL_TRUECOLOR:
	case FB_VISUAL_PSEUDOCOLOR:
		red = CNVT_TOHW(red, info->var.red.length);
		green = CNVT_TOHW(green, info->var.green.length);
		blue = CNVT_TOHW(blue, info->var.blue.length);
		transp = CNVT_TOHW(transp, info->var.transp.length);
		break;
	case FB_VISUAL_DIRECTCOLOR:
		/* example here assumes 8 bit DAC. Might be different 
		 * for your hardware */	
		red = CNVT_TOHW(red, 8);       
		green = CNVT_TOHW(green, 8);
		blue = CNVT_TOHW(blue, 8);
		/* hey, there is bug in transp handling... */
		transp = CNVT_TOHW(transp, 8);
		break;
	}
#undef CNVT_TOHW
	/* Truecolor has hardware independent palette */
	if (info->fix.visual == FB_VISUAL_TRUECOLOR) {
		u32 v;

		if (regno >= 16)
			return 1;

		v = (red << info->var.red.offset) |
			(green << info->var.green.offset) |
			(blue << info->var.blue.offset) |
			(transp << info->var.transp.offset);

		switch (info->var.bits_per_pixel) {
		case 8:
			break;	
   		case 16:
		case 24:
		case 32:	
           		par->palette[regno] = v;
			break;
		}
		return 0;
	}
	else if (info->fix.visual == FB_VISUAL_PSEUDOCOLOR)
		set_color(par, regno, red, green, blue);

	return 0;
}

/**
 *      pm2fb_pan_display - Pans the display.
 *      @var: frame buffer variable screen structure
 *      @info: frame buffer structure that represents a single frame buffer
 *
 *	Pan (or wrap, depending on the `vmode' field) the display using the
 *  	`xoffset' and `yoffset' fields of the `var' structure.
 *  	If the values don't fit, return -EINVAL.
 *
 *      Returns negative errno on error, or zero on success.
 *
 */
static int pm2fb_pan_display(struct fb_var_screeninfo *var,
			     struct fb_info *info)
{
	struct pm2fb_par *p = info->par;
	u32 base;
	u32 depth;
	u32 xres;

	xres = (var->xres + 31) & ~31;
	depth = (var->bits_per_pixel + 7) & ~7;
	depth = (depth > 32) ? 32 : depth;
	base = to3264(var->yoffset * xres + var->xoffset, depth, 1);
	WAIT_FIFO(p, 1);
	pm2_WR(p, PM2R_SCREEN_BASE, base);    
	return 0;
}

/**
 *      pm2fb_blank - Blanks the display.
 *      @blank_mode: the blank mode we want. 
 *      @info: frame buffer structure that represents a single frame buffer
 *
 *      Blank the screen if blank_mode != 0, else unblank. Return 0 if
 *      blanking succeeded, != 0 if un-/blanking failed due to e.g. a 
 *      video mode which doesn't support it. Implements VESA suspend
 *      and powerdown modes on hardware that supports disabling hsync/vsync:
 *      blank_mode == 2: suspend vsync
 *      blank_mode == 3: suspend hsync
 *      blank_mode == 4: powerdown
 *
 *      Returns negative errno on error, or zero on success.
 *
 */
static int pm2fb_blank(int blank_mode, struct fb_info *info)
{
	struct pm2fb_par *par = info->par;
	u32 video = par->video;

	DPRINTK("blank_mode %d\n", blank_mode);

	switch (blank_mode) {
	case FB_BLANK_UNBLANK:
		/* Screen: On */
		video |= PM2F_VIDEO_ENABLE;
		break;
	case FB_BLANK_NORMAL:
		/* Screen: Off */
		video &= ~PM2F_VIDEO_ENABLE;
		break;
	case FB_BLANK_VSYNC_SUSPEND:
		/* VSync: Off */
		video &= ~(PM2F_VSYNC_MASK | PM2F_BLANK_LOW );
		break;
	case FB_BLANK_HSYNC_SUSPEND:
		/* HSync: Off */
		video &= ~(PM2F_HSYNC_MASK | PM2F_BLANK_LOW );
		break;
	case FB_BLANK_POWERDOWN:
		/* HSync: Off, VSync: Off */
		video &= ~(PM2F_VSYNC_MASK | PM2F_HSYNC_MASK| PM2F_BLANK_LOW);
		break;
	}
	set_video(par, video);
	return 0;
}

/*
 * block operation. copy=0: rectangle fill, copy=1: rectangle copy.
 */
static void pm2fb_block_op(struct pm2fb_par* par, int copy,
				s32 xsrc, s32 ysrc,
				s32 x, s32 y, s32 w, s32 h,
				u32 color) {

	if (!w || !h)
		return;
	WAIT_FIFO(par, 6);
	pm2_WR(par, PM2R_CONFIG, PM2F_CONFIG_FB_WRITE_ENABLE |
		PM2F_CONFIG_FB_READ_SOURCE_ENABLE);
	pm2_WR(par, PM2R_FB_PIXEL_OFFSET, 0);
	if (copy)
		pm2_WR(par, PM2R_FB_SOURCE_DELTA,
			((ysrc-y) & 0xfff) << 16 | ((xsrc-x) & 0xfff));
	else
		pm2_WR(par, PM2R_FB_BLOCK_COLOR, color);
	pm2_WR(par, PM2R_RECTANGLE_ORIGIN, (y << 16) | x);
	pm2_WR(par, PM2R_RECTANGLE_SIZE, (h << 16) | w);
	wmb();
	pm2_WR(par, PM2R_RENDER,PM2F_RENDER_RECTANGLE |
				(x<xsrc ? PM2F_INCREASE_X : 0) |
				(y<ysrc ? PM2F_INCREASE_Y : 0) |
				(copy ? 0 : PM2F_RENDER_FASTFILL));
	wait_pm2(par);
}

static void pm2fb_fillrect (struct fb_info *info,
				const struct fb_fillrect *region)
{
	struct pm2fb_par *par = info->par;
	struct fb_fillrect modded;
	int vxres, vyres;
	u32 color = (info->fix.visual == FB_VISUAL_TRUECOLOR) ?
		((u32*)info->pseudo_palette)[region->color] : region->color;

	if (info->state != FBINFO_STATE_RUNNING)
		return;
	if ((info->flags & FBINFO_HWACCEL_DISABLED) ||
		region->rop != ROP_COPY ) {
		cfb_fillrect(info, region);
		return;
	}

	vxres = info->var.xres_virtual;
	vyres = info->var.yres_virtual;

	memcpy(&modded, region, sizeof(struct fb_fillrect));

	if(!modded.width || !modded.height ||
	   modded.dx >= vxres || modded.dy >= vyres)
		return;

	if(modded.dx + modded.width  > vxres)
		modded.width  = vxres - modded.dx;
	if(modded.dy + modded.height > vyres)
		modded.height = vyres - modded.dy;

	if(info->var.bits_per_pixel == 8)
		color |= color << 8;
	if(info->var.bits_per_pixel <= 16)
		color |= color << 16;

	if(info->var.bits_per_pixel != 24)
		pm2fb_block_op(par, 0, 0, 0,
				modded.dx, modded.dy,
				modded.width, modded.height, color);
	else
		cfb_fillrect(info, region);
}

static void pm2fb_copyarea(struct fb_info *info,
				const struct fb_copyarea *area)
{
	struct pm2fb_par *par = info->par;
	struct fb_copyarea modded;
	u32 vxres, vyres;

	if (info->state != FBINFO_STATE_RUNNING)
		return;
	if (info->flags & FBINFO_HWACCEL_DISABLED) {
		cfb_copyarea(info, area);
		return;
	}

	memcpy(&modded, area, sizeof(struct fb_copyarea));

	vxres = info->var.xres_virtual;
	vyres = info->var.yres_virtual;

	if(!modded.width || !modded.height ||
	   modded.sx >= vxres || modded.sy >= vyres ||
	   modded.dx >= vxres || modded.dy >= vyres)
		return;

	if(modded.sx + modded.width > vxres)
		modded.width = vxres - modded.sx;
	if(modded.dx + modded.width > vxres)
		modded.width = vxres - modded.dx;
	if(modded.sy + modded.height > vyres)
		modded.height = vyres - modded.sy;
	if(modded.dy + modded.height > vyres)
		modded.height = vyres - modded.dy;

	pm2fb_block_op(par, 1, modded.sx, modded.sy,
			modded.dx, modded.dy,
			modded.width, modded.height, 0);
}

/* ------------ Hardware Independent Functions ------------ */

/*
 *  Frame buffer operations
 */

static struct fb_ops pm2fb_ops = {
	.owner		= THIS_MODULE,
	.fb_check_var	= pm2fb_check_var,
	.fb_set_par	= pm2fb_set_par,
	.fb_setcolreg	= pm2fb_setcolreg,
	.fb_blank	= pm2fb_blank,
	.fb_pan_display	= pm2fb_pan_display,
	.fb_fillrect	= pm2fb_fillrect,
	.fb_copyarea	= pm2fb_copyarea,
	.fb_imageblit	= cfb_imageblit,
};

/*
 * PCI stuff
 */


/**
 * Device initialisation
 *
 * Initialise and allocate resource for PCI device.
 *
 * @param	pdev	PCI device.
 * @param	id	PCI device ID.
 */
static int __devinit pm2fb_probe(struct pci_dev *pdev,
				 const struct pci_device_id *id)
{
	struct pm2fb_par *default_par;
	struct fb_info *info;
	int err, err_retval = -ENXIO;

	err = pci_enable_device(pdev);
	if ( err ) {
		printk(KERN_WARNING "pm2fb: Can't enable pdev: %d\n", err);
		return err;
	}

	info = framebuffer_alloc(sizeof(struct pm2fb_par), &pdev->dev);
	if ( !info )
		return -ENOMEM;
	default_par = info->par;

	switch (pdev->device) {
	case  PCI_DEVICE_ID_TI_TVP4020:
		strcpy(pm2fb_fix.id, "TVP4020");
		default_par->type = PM2_TYPE_PERMEDIA2;
		break;
	case  PCI_DEVICE_ID_3DLABS_PERMEDIA2:
		strcpy(pm2fb_fix.id, "Permedia2");
		default_par->type = PM2_TYPE_PERMEDIA2;
		break;
	case  PCI_DEVICE_ID_3DLABS_PERMEDIA2V:
		strcpy(pm2fb_fix.id, "Permedia2v");
		default_par->type = PM2_TYPE_PERMEDIA2V;
		break;
	}

	pm2fb_fix.mmio_start = pci_resource_start(pdev, 0);
	pm2fb_fix.mmio_len = PM2_REGS_SIZE;

#if defined(__BIG_ENDIAN)
	/*
	 * PM2 has a 64k register file, mapped twice in 128k. Lower
	 * map is little-endian, upper map is big-endian.
	 */
	pm2fb_fix.mmio_start += PM2_REGS_SIZE;
	DPRINTK("Adjusting register base for big-endian.\n");
#endif
	DPRINTK("Register base at 0x%lx\n", pm2fb_fix.mmio_start);
    
	/* Registers - request region and map it. */
	if ( !request_mem_region(pm2fb_fix.mmio_start, pm2fb_fix.mmio_len,
				 "pm2fb regbase") ) {
		printk(KERN_WARNING "pm2fb: Can't reserve regbase.\n");
		goto err_exit_neither;
	}
	default_par->v_regs =
		ioremap_nocache(pm2fb_fix.mmio_start, pm2fb_fix.mmio_len);
	if ( !default_par->v_regs ) {
		printk(KERN_WARNING "pm2fb: Can't remap %s register area.\n",
		       pm2fb_fix.id);
		release_mem_region(pm2fb_fix.mmio_start, pm2fb_fix.mmio_len);
		goto err_exit_neither;
	}

	/* Stash away memory register info for use when we reset the board */
	default_par->mem_control = pm2_RD(default_par, PM2R_MEM_CONTROL);
	default_par->boot_address = pm2_RD(default_par, PM2R_BOOT_ADDRESS);
	default_par->mem_config = pm2_RD(default_par, PM2R_MEM_CONFIG);
	DPRINTK("MemControl 0x%x BootAddress 0x%x MemConfig 0x%x\n",
		default_par->mem_control, default_par->boot_address,
		default_par->mem_config);

	if(default_par->mem_control == 0 &&
		default_par->boot_address == 0x31 &&
		default_par->mem_config == 0x259fffff) {
		default_par->memclock = CVPPC_MEMCLOCK;
		default_par->mem_control=0;
		default_par->boot_address=0x20;
		default_par->mem_config=0xe6002021;
		if (pdev->subsystem_vendor == 0x1048 &&
			pdev->subsystem_device == 0x0a31) {
			DPRINTK("subsystem_vendor: %04x, subsystem_device: %04x\n",
				pdev->subsystem_vendor, pdev->subsystem_device);
			DPRINTK("We have not been initialized by VGA BIOS "
				"and are running on an Elsa Winner 2000 Office\n");
			DPRINTK("Initializing card timings manually...\n");
			default_par->memclock=70000;
		}
		if (pdev->subsystem_vendor == 0x3d3d &&
			pdev->subsystem_device == 0x0100) {
			DPRINTK("subsystem_vendor: %04x, subsystem_device: %04x\n",
				pdev->subsystem_vendor, pdev->subsystem_device);
			DPRINTK("We have not been initialized by VGA BIOS "
				"and are running on an 3dlabs reference board\n");
			DPRINTK("Initializing card timings manually...\n");
			default_par->memclock=74894;
		}
	}

	/* Now work out how big lfb is going to be. */
	switch(default_par->mem_config & PM2F_MEM_CONFIG_RAM_MASK) {
	case PM2F_MEM_BANKS_1:
		pm2fb_fix.smem_len=0x200000;
		break;
	case PM2F_MEM_BANKS_2:
		pm2fb_fix.smem_len=0x400000;
		break;
	case PM2F_MEM_BANKS_3:
		pm2fb_fix.smem_len=0x600000;
		break;
	case PM2F_MEM_BANKS_4:
		pm2fb_fix.smem_len=0x800000;
		break;
	}
	pm2fb_fix.smem_start = pci_resource_start(pdev, 1);

	/* Linear frame buffer - request region and map it. */
	if ( !request_mem_region(pm2fb_fix.smem_start, pm2fb_fix.smem_len,
				 "pm2fb smem") ) {
		printk(KERN_WARNING "pm2fb: Can't reserve smem.\n");
		goto err_exit_mmio;
	}
	info->screen_base =
		ioremap_nocache(pm2fb_fix.smem_start, pm2fb_fix.smem_len);
	if ( !info->screen_base ) {
		printk(KERN_WARNING "pm2fb: Can't ioremap smem area.\n");
		release_mem_region(pm2fb_fix.smem_start, pm2fb_fix.smem_len);
		goto err_exit_mmio;
	}

	info->fbops		= &pm2fb_ops;
	info->fix		= pm2fb_fix; 	
	info->pseudo_palette	= default_par->palette;
	info->flags		= FBINFO_DEFAULT |
                                  FBINFO_HWACCEL_YPAN |
	                          FBINFO_HWACCEL_COPYAREA |
	                          FBINFO_HWACCEL_FILLRECT;

	if (!mode)
		mode = "640x480@60";
	 
	err = fb_find_mode(&info->var, info, mode, NULL, 0, NULL, 8); 
	if (!err || err == 4)
		info->var = pm2fb_var;

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

	if (register_framebuffer(info) < 0)
		goto err_exit_all;

	printk(KERN_INFO "fb%d: %s frame buffer device, memory = %dK.\n",
	       info->node, info->fix.id, pm2fb_fix.smem_len / 1024);

	/*
	 * Our driver data
	 */
	pci_set_drvdata(pdev, info);

	return 0;

 err_exit_all:
	fb_dealloc_cmap(&info->cmap);	
 err_exit_both:    
	iounmap(info->screen_base);
	release_mem_region(pm2fb_fix.smem_start, pm2fb_fix.smem_len);
 err_exit_mmio:
	iounmap(default_par->v_regs);
	release_mem_region(pm2fb_fix.mmio_start, pm2fb_fix.mmio_len);
 err_exit_neither:
	framebuffer_release(info);
	return err_retval;
}

/**
 * Device removal.
 *
 * Release all device resources.
 *
 * @param	pdev	PCI device to clean up.
 */
static void __devexit pm2fb_remove(struct pci_dev *pdev)
{
	struct fb_info* info = pci_get_drvdata(pdev);
	struct fb_fix_screeninfo* fix = &info->fix;
	struct pm2fb_par *par = info->par;

	unregister_framebuffer(info);
    
	iounmap(info->screen_base);
	release_mem_region(fix->smem_start, fix->smem_len);
	iounmap(par->v_regs);
	release_mem_region(fix->mmio_start, fix->mmio_len);

	pci_set_drvdata(pdev, NULL);
	kfree(info);
}

static struct pci_device_id pm2fb_id_table[] = {
	{ PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_TVP4020,
	  PCI_ANY_ID, PCI_ANY_ID, PCI_BASE_CLASS_DISPLAY << 16,
	  0xff0000, 0 },
	{ PCI_VENDOR_ID_3DLABS, PCI_DEVICE_ID_3DLABS_PERMEDIA2,
	  PCI_ANY_ID, PCI_ANY_ID, PCI_BASE_CLASS_DISPLAY << 16,
	  0xff0000, 0 },
	{ PCI_VENDOR_ID_3DLABS, PCI_DEVICE_ID_3DLABS_PERMEDIA2V,
	  PCI_ANY_ID, PCI_ANY_ID, PCI_BASE_CLASS_DISPLAY << 16,
	  0xff0000, 0 },
	{ PCI_VENDOR_ID_3DLABS, PCI_DEVICE_ID_3DLABS_PERMEDIA2V,
	  PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_NOT_DEFINED_VGA << 8,
	  0xff00, 0 },
	{ 0, }
};

static struct pci_driver pm2fb_driver = {
	.name		= "pm2fb",
	.id_table 	= pm2fb_id_table,
	.probe 		= pm2fb_probe,
	.remove 	= __devexit_p(pm2fb_remove),
};

MODULE_DEVICE_TABLE(pci, pm2fb_id_table);


#ifndef MODULE
/**
 * Parse user speficied options.
 *
 * This is, comma-separated options following `video=pm2fb:'.
 */
static int __init pm2fb_setup(char *options)
{
	char* this_opt;

	if (!options || !*options)
		return 0;

	while ((this_opt = strsep(&options, ",")) != NULL) {	
		if (!*this_opt)
			continue;
		if(!strcmp(this_opt, "lowhsync")) {
			lowhsync = 1;
		} else if(!strcmp(this_opt, "lowvsync")) {
			lowvsync = 1;
		} else {
			mode = this_opt;
		}
	}
	return 0;
}
#endif


static int __init pm2fb_init(void)
{
#ifndef MODULE
	char *option = NULL;

	if (fb_get_options("pm2fb", &option))
		return -ENODEV;
	pm2fb_setup(option);
#endif

	return pci_register_driver(&pm2fb_driver);
}

module_init(pm2fb_init);

#ifdef MODULE
/*
 *  Cleanup
 */

static void __exit pm2fb_exit(void)
{
	pci_unregister_driver(&pm2fb_driver);
}
#endif

#ifdef MODULE
module_exit(pm2fb_exit);

module_param(mode, charp, 0);
MODULE_PARM_DESC(mode, "Preferred video mode e.g. '648x480-8@60'");
module_param(lowhsync, bool, 0);
MODULE_PARM_DESC(lowhsync, "Force horizontal sync low regardless of mode");
module_param(lowvsync, bool, 0);
MODULE_PARM_DESC(lowvsync, "Force vertical sync low regardless of mode");

MODULE_AUTHOR("Jim Hague <jim.hague@acm.org>");
MODULE_DESCRIPTION("Permedia2 framebuffer device driver");
MODULE_LICENSE("GPL");
#endif
