/*
 *  linux/drivers/video/sgivwfb.c -- SGI DBE frame buffer device
 *
 *	Copyright (C) 1999 Silicon Graphics, Inc.
 *      Jeffrey Newquist, newquist@engr.sgi.som
 *
 *  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/config.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/errno.h>
#include <linux/delay.h>
#include <linux/fb.h>
#include <linux/init.h>
#include <linux/ioport.h>
#include <asm/io.h>
#include <asm/mtrr.h>

#define INCLUDE_TIMING_TABLE_DATA
#define DBE_REG_BASE par->regs
#include <video/sgivw.h>

struct sgivw_par {
	struct asregs *regs;
	u32 cmap_fifo;
	u_long timing_num;
};

#define FLATPANEL_SGI_1600SW	5

/*
 *  RAM we reserve for the frame buffer. This defines the maximum screen
 *  size
 *
 *  The default can be overridden if the driver is compiled as a module
 */

/* set by arch/i386/kernel/setup.c */
extern unsigned long sgivwfb_mem_phys;
extern unsigned long sgivwfb_mem_size;

static int ypan = 0;
static int ywrap = 0;

static int flatpanel_id = -1;

static struct fb_fix_screeninfo sgivwfb_fix __initdata = {
	.id		= "SGI Vis WS FB",
	.type		= FB_TYPE_PACKED_PIXELS,
        .visual		= FB_VISUAL_PSEUDOCOLOR,
	.mmio_start	= DBE_REG_PHYS,
	.mmio_len	= DBE_REG_SIZE,
        .accel		= FB_ACCEL_NONE,
	.line_length	= 640,
};

static struct fb_var_screeninfo sgivwfb_var __initdata = {
	/* 640x480, 8 bpp */
	.xres		= 640,
	.yres		= 480,
	.xres_virtual	= 640,
	.yres_virtual	= 480,
	.bits_per_pixel	= 8,
	.red		= { 0, 8, 0 },
	.green		= { 0, 8, 0 },
	.blue		= { 0, 8, 0 },
	.height		= -1,
	.width		= -1,
	.pixclock	= 20000,
	.left_margin	= 64,
	.right_margin	= 64,
	.upper_margin	= 32,
	.lower_margin	= 32,
	.hsync_len	= 64,
	.vsync_len	= 2,
	.vmode		= FB_VMODE_NONINTERLACED
};

static struct fb_var_screeninfo sgivwfb_var1600sw __initdata = {
	/* 1600x1024, 8 bpp */
	.xres		= 1600,
	.yres		= 1024,
	.xres_virtual	= 1600,
	.yres_virtual	= 1024,
	.bits_per_pixel	= 8,
	.red		= { 0, 8, 0 },
	.green		= { 0, 8, 0 },
	.blue		= { 0, 8, 0 },
	.height		= -1,
	.width		= -1,
	.pixclock	= 9353,
	.left_margin	= 20,
	.right_margin	= 30,
	.upper_margin	= 37,
	.lower_margin	= 3,
	.hsync_len	= 20,
	.vsync_len	= 3,
	.vmode		= FB_VMODE_NONINTERLACED
};

/*
 *  Interface used by the world
 */
int sgivwfb_init(void);

static int sgivwfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info);
static int sgivwfb_set_par(struct fb_info *info);
static int sgivwfb_setcolreg(u_int regno, u_int red, u_int green,
			     u_int blue, u_int transp,
			     struct fb_info *info);
static int sgivwfb_mmap(struct fb_info *info, struct file *file,
			struct vm_area_struct *vma);

static struct fb_ops sgivwfb_ops = {
	.owner		= THIS_MODULE,
	.fb_check_var	= sgivwfb_check_var,
	.fb_set_par	= sgivwfb_set_par,
	.fb_setcolreg	= sgivwfb_setcolreg,
	.fb_fillrect	= cfb_fillrect,
	.fb_copyarea	= cfb_copyarea,
	.fb_imageblit	= cfb_imageblit,
	.fb_cursor	= soft_cursor,
	.fb_mmap	= sgivwfb_mmap,
};

/*
 *  Internal routines
 */
static unsigned long bytes_per_pixel(int bpp)
{
	switch (bpp) {
		case 8:
			return 1;
		case 16:
			return 2;
		case 32:
			return 4;
		default:
			printk(KERN_INFO "sgivwfb: unsupported bpp %d\n", bpp);
			return 0;
	}
}

static unsigned long get_line_length(int xres_virtual, int bpp)
{
	return (xres_virtual * bytes_per_pixel(bpp));
}

/*
 * Function:	dbe_TurnOffDma
 * Parameters:	(None)
 * Description:	This should turn off the monitor and dbe.  This is used
 *              when switching between the serial console and the graphics
 *              console.
 */

static void dbe_TurnOffDma(struct sgivw_par *par)
{
	unsigned int readVal;
	int i;

	// Check to see if things are already turned off:
	// 1) Check to see if dbe is not using the internal dotclock.
	// 2) Check to see if the xy counter in dbe is already off.

	DBE_GETREG(ctrlstat, readVal);
	if (GET_DBE_FIELD(CTRLSTAT, PCLKSEL, readVal) < 2)
		return;

	DBE_GETREG(vt_xy, readVal);
	if (GET_DBE_FIELD(VT_XY, VT_FREEZE, readVal) == 1)
		return;

	// Otherwise, turn off dbe

	DBE_GETREG(ovr_control, readVal);
	SET_DBE_FIELD(OVR_CONTROL, OVR_DMA_ENABLE, readVal, 0);
	DBE_SETREG(ovr_control, readVal);
	udelay(1000);
	DBE_GETREG(frm_control, readVal);
	SET_DBE_FIELD(FRM_CONTROL, FRM_DMA_ENABLE, readVal, 0);
	DBE_SETREG(frm_control, readVal);
	udelay(1000);
	DBE_GETREG(did_control, readVal);
	SET_DBE_FIELD(DID_CONTROL, DID_DMA_ENABLE, readVal, 0);
	DBE_SETREG(did_control, readVal);
	udelay(1000);

	// XXX HACK:
	//
	//    This was necessary for GBE--we had to wait through two
	//    vertical retrace periods before the pixel DMA was
	//    turned off for sure.  I've left this in for now, in
	//    case dbe needs it.

	for (i = 0; i < 10000; i++) {
		DBE_GETREG(frm_inhwctrl, readVal);
		if (GET_DBE_FIELD(FRM_INHWCTRL, FRM_DMA_ENABLE, readVal) ==
		    0)
			udelay(10);
		else {
			DBE_GETREG(ovr_inhwctrl, readVal);
			if (GET_DBE_FIELD
			    (OVR_INHWCTRL, OVR_DMA_ENABLE, readVal) == 0)
				udelay(10);
			else {
				DBE_GETREG(did_inhwctrl, readVal);
				if (GET_DBE_FIELD
				    (DID_INHWCTRL, DID_DMA_ENABLE,
				     readVal) == 0)
					udelay(10);
				else
					break;
			}
		}
	}
}

/*
 *  Set the User Defined Part of the Display. Again if par use it to get
 *  real video mode.
 */
static int sgivwfb_check_var(struct fb_var_screeninfo *var, 
			     struct fb_info *info)
{
	struct sgivw_par *par = (struct sgivw_par *)info->par;
	struct dbe_timing_info *timing;
	u_long line_length;
	u_long min_mode;
	int req_dot;
	int test_mode;

	/*
	 *  FB_VMODE_CONUPDATE and FB_VMODE_SMOOTH_XPAN are equal!
	 *  as FB_VMODE_SMOOTH_XPAN is only used internally
	 */

	if (var->vmode & FB_VMODE_CONUPDATE) {
		var->vmode |= FB_VMODE_YWRAP;
		var->xoffset = info->var.xoffset;
		var->yoffset = info->var.yoffset;
	}

	/* XXX FIXME - forcing var's */
	var->xoffset = 0;
	var->yoffset = 0;

	/* Limit bpp to 8, 16, and 32 */
	if (var->bits_per_pixel <= 8)
		var->bits_per_pixel = 8;
	else if (var->bits_per_pixel <= 16)
		var->bits_per_pixel = 16;
	else if (var->bits_per_pixel <= 32)
		var->bits_per_pixel = 32;
	else
		return -EINVAL;

	var->grayscale = 0;	/* No grayscale for now */

	/* determine valid resolution and timing */
	for (min_mode = 0; min_mode < DBE_VT_SIZE; min_mode++) {
		if (dbeVTimings[min_mode].width >= var->xres &&
		    dbeVTimings[min_mode].height >= var->yres)
			break;
	}

	if (min_mode == DBE_VT_SIZE)
		return -EINVAL;	/* Resolution to high */

	/* XXX FIXME - should try to pick best refresh rate */
	/* for now, pick closest dot-clock within 3MHz */
	req_dot = PICOS2KHZ(var->pixclock);
	printk(KERN_INFO "sgivwfb: requested pixclock=%d ps (%d KHz)\n",
	       var->pixclock, req_dot);
	test_mode = min_mode;
	while (dbeVTimings[min_mode].width == dbeVTimings[test_mode].width) {
		if (dbeVTimings[test_mode].cfreq + 3000 > req_dot)
			break;
		test_mode++;
	}
	if (dbeVTimings[min_mode].width != dbeVTimings[test_mode].width)
		test_mode--;
	min_mode = test_mode;
	timing = &dbeVTimings[min_mode];
	printk(KERN_INFO "sgivwfb: granted dot-clock=%d KHz\n", timing->cfreq);

	/* Adjust virtual resolution, if necessary */
	if (var->xres > var->xres_virtual || (!ywrap && !ypan))
		var->xres_virtual = var->xres;
	if (var->yres > var->yres_virtual || (!ywrap && !ypan))
		var->yres_virtual = var->yres;

	/*
	 *  Memory limit
	 */
	line_length = get_line_length(var->xres_virtual, var->bits_per_pixel);
	if (line_length * var->yres_virtual > sgivwfb_mem_size)
		return -ENOMEM;	/* Virtual resolution to high */

	info->fix.line_length = line_length;

	switch (var->bits_per_pixel) {
	case 8:
		var->red.offset = 0;
		var->red.length = 8;
		var->green.offset = 0;
		var->green.length = 8;
		var->blue.offset = 0;
		var->blue.length = 8;
		var->transp.offset = 0;
		var->transp.length = 0;
		break;
	case 16:		/* RGBA 5551 */
		var->red.offset = 11;
		var->red.length = 5;
		var->green.offset = 6;
		var->green.length = 5;
		var->blue.offset = 1;
		var->blue.length = 5;
		var->transp.offset = 0;
		var->transp.length = 0;
		break;
	case 32:		/* RGB 8888 */
		var->red.offset = 0;
		var->red.length = 8;
		var->green.offset = 8;
		var->green.length = 8;
		var->blue.offset = 16;
		var->blue.length = 8;
		var->transp.offset = 24;
		var->transp.length = 8;
		break;
	}
	var->red.msb_right = 0;
	var->green.msb_right = 0;
	var->blue.msb_right = 0;
	var->transp.msb_right = 0;

	/* set video timing information */
	var->pixclock = KHZ2PICOS(timing->cfreq);
	var->left_margin = timing->htotal - timing->hsync_end;
	var->right_margin = timing->hsync_start - timing->width;
	var->upper_margin = timing->vtotal - timing->vsync_end;
	var->lower_margin = timing->vsync_start - timing->height;
	var->hsync_len = timing->hsync_end - timing->hsync_start;
	var->vsync_len = timing->vsync_end - timing->vsync_start;

	/* Ouch. This breaks the rules but timing_num is only important if you
	* change a video mode */
	par->timing_num = min_mode;

	printk(KERN_INFO "sgivwfb: new video mode xres=%d yres=%d bpp=%d\n",
		var->xres, var->yres, var->bits_per_pixel);
	printk(KERN_INFO "         vxres=%d vyres=%d\n", var->xres_virtual,
		var->yres_virtual);
	return 0;
}

/*
 *  Setup flatpanel related registers.
 */
static void sgivwfb_setup_flatpanel(struct sgivw_par *par, struct dbe_timing_info *currentTiming)
{
	int fp_wid, fp_hgt, fp_vbs, fp_vbe;
	u32 outputVal = 0;

	SET_DBE_FIELD(VT_FLAGS, HDRV_INVERT, outputVal, 
		(currentTiming->flags & FB_SYNC_HOR_HIGH_ACT) ? 0 : 1);
	SET_DBE_FIELD(VT_FLAGS, VDRV_INVERT, outputVal, 
		(currentTiming->flags & FB_SYNC_VERT_HIGH_ACT) ? 0 : 1);
	DBE_SETREG(vt_flags, outputVal);

	/* Turn on the flat panel */
	switch (flatpanel_id) {
		case FLATPANEL_SGI_1600SW:
			fp_wid = 1600;
			fp_hgt = 1024;
			fp_vbs = 0;
			fp_vbe = 1600;
			currentTiming->pll_m = 4;
			currentTiming->pll_n = 1;
			currentTiming->pll_p = 0;
			break;
		default:
      			fp_wid = fp_hgt = fp_vbs = fp_vbe = 0xfff;
  	}

	outputVal = 0;
	SET_DBE_FIELD(FP_DE, FP_DE_ON, outputVal, fp_vbs);
	SET_DBE_FIELD(FP_DE, FP_DE_OFF, outputVal, fp_vbe);
	DBE_SETREG(fp_de, outputVal);
	outputVal = 0;
	SET_DBE_FIELD(FP_HDRV, FP_HDRV_OFF, outputVal, fp_wid);
	DBE_SETREG(fp_hdrv, outputVal);
	outputVal = 0;
	SET_DBE_FIELD(FP_VDRV, FP_VDRV_ON, outputVal, 1);
	SET_DBE_FIELD(FP_VDRV, FP_VDRV_OFF, outputVal, fp_hgt + 1);
	DBE_SETREG(fp_vdrv, outputVal);
}

/*
 *  Set the hardware according to 'par'.
 */
static int sgivwfb_set_par(struct fb_info *info)
{
	struct sgivw_par *par = info->par;
	int i, j, htmp, temp;
	u32 readVal, outputVal;
	int wholeTilesX, maxPixelsPerTileX;
	int frmWrite1, frmWrite2, frmWrite3b;
	struct dbe_timing_info *currentTiming; /* Current Video Timing */
	int xpmax, ypmax;	// Monitor resolution
	int bytesPerPixel;	// Bytes per pixel

	currentTiming = &dbeVTimings[par->timing_num];
	bytesPerPixel = bytes_per_pixel(info->var.bits_per_pixel);
	xpmax = currentTiming->width;
	ypmax = currentTiming->height;

	/* dbe_InitGraphicsBase(); */
	/* Turn on dotclock PLL */
	DBE_SETREG(ctrlstat, 0x20000000);

	dbe_TurnOffDma(par);

	/* dbe_CalculateScreenParams(); */
	maxPixelsPerTileX = 512 / bytesPerPixel;
	wholeTilesX = xpmax / maxPixelsPerTileX;
	if (wholeTilesX * maxPixelsPerTileX < xpmax)
		wholeTilesX++;

	printk(KERN_DEBUG "sgivwfb: pixPerTile=%d wholeTilesX=%d\n",
	       maxPixelsPerTileX, wholeTilesX);

	/* dbe_InitGammaMap(); */
	udelay(10);

	for (i = 0; i < 256; i++) {
		DBE_ISETREG(gmap, i, (i << 24) | (i << 16) | (i << 8));
	}

	/* dbe_TurnOn(); */
	DBE_GETREG(vt_xy, readVal);
	if (GET_DBE_FIELD(VT_XY, VT_FREEZE, readVal) == 1) {
		DBE_SETREG(vt_xy, 0x00000000);
		udelay(1);
	} else
		dbe_TurnOffDma(par);

	/* dbe_Initdbe(); */
	for (i = 0; i < 256; i++) {
		for (j = 0; j < 100; j++) {
			DBE_GETREG(cm_fifo, readVal);
			if (readVal != 0x00000000)
				break;
			else
				udelay(10);
		}

		// DBE_ISETREG(cmap, i, 0x00000000);
		DBE_ISETREG(cmap, i, (i << 8) | (i << 16) | (i << 24));
	}

	/* dbe_InitFramebuffer(); */
	frmWrite1 = 0;
	SET_DBE_FIELD(FRM_SIZE_TILE, FRM_WIDTH_TILE, frmWrite1,
		      wholeTilesX);
	SET_DBE_FIELD(FRM_SIZE_TILE, FRM_RHS, frmWrite1, 0);

	switch (bytesPerPixel) {
	case 1:
		SET_DBE_FIELD(FRM_SIZE_TILE, FRM_DEPTH, frmWrite1,
			      DBE_FRM_DEPTH_8);
		break;
	case 2:
		SET_DBE_FIELD(FRM_SIZE_TILE, FRM_DEPTH, frmWrite1,
			      DBE_FRM_DEPTH_16);
		break;
	case 4:
		SET_DBE_FIELD(FRM_SIZE_TILE, FRM_DEPTH, frmWrite1,
			      DBE_FRM_DEPTH_32);
		break;
	}

	frmWrite2 = 0;
	SET_DBE_FIELD(FRM_SIZE_PIXEL, FB_HEIGHT_PIX, frmWrite2, ypmax);

	// Tell dbe about the framebuffer location and type
	// XXX What format is the FRM_TILE_PTR??  64K aligned address?
	frmWrite3b = 0;
	SET_DBE_FIELD(FRM_CONTROL, FRM_TILE_PTR, frmWrite3b,
		      sgivwfb_mem_phys >> 9);
	SET_DBE_FIELD(FRM_CONTROL, FRM_DMA_ENABLE, frmWrite3b, 1);
	SET_DBE_FIELD(FRM_CONTROL, FRM_LINEAR, frmWrite3b, 1);

	/* Initialize DIDs */

	outputVal = 0;
	switch (bytesPerPixel) {
	case 1:
		SET_DBE_FIELD(WID, TYP, outputVal, DBE_CMODE_I8);
		break;
	case 2:
		SET_DBE_FIELD(WID, TYP, outputVal, DBE_CMODE_RGBA5);
		break;
	case 4:
		SET_DBE_FIELD(WID, TYP, outputVal, DBE_CMODE_RGB8);
		break;
	}
	SET_DBE_FIELD(WID, BUF, outputVal, DBE_BMODE_BOTH);

	for (i = 0; i < 32; i++) {
		DBE_ISETREG(mode_regs, i, outputVal);
	}

	/* dbe_InitTiming(); */
	DBE_SETREG(vt_intr01, 0xffffffff);
	DBE_SETREG(vt_intr23, 0xffffffff);

	DBE_GETREG(dotclock, readVal);
	DBE_SETREG(dotclock, readVal & 0xffff);

	DBE_SETREG(vt_xymax, 0x00000000);
	outputVal = 0;
	SET_DBE_FIELD(VT_VSYNC, VT_VSYNC_ON, outputVal,
		      currentTiming->vsync_start);
	SET_DBE_FIELD(VT_VSYNC, VT_VSYNC_OFF, outputVal,
		      currentTiming->vsync_end);
	DBE_SETREG(vt_vsync, outputVal);
	outputVal = 0;
	SET_DBE_FIELD(VT_HSYNC, VT_HSYNC_ON, outputVal,
		      currentTiming->hsync_start);
	SET_DBE_FIELD(VT_HSYNC, VT_HSYNC_OFF, outputVal,
		      currentTiming->hsync_end);
	DBE_SETREG(vt_hsync, outputVal);
	outputVal = 0;
	SET_DBE_FIELD(VT_VBLANK, VT_VBLANK_ON, outputVal,
		      currentTiming->vblank_start);
	SET_DBE_FIELD(VT_VBLANK, VT_VBLANK_OFF, outputVal,
		      currentTiming->vblank_end);
	DBE_SETREG(vt_vblank, outputVal);
	outputVal = 0;
	SET_DBE_FIELD(VT_HBLANK, VT_HBLANK_ON, outputVal,
		      currentTiming->hblank_start);
	SET_DBE_FIELD(VT_HBLANK, VT_HBLANK_OFF, outputVal,
		      currentTiming->hblank_end - 3);
	DBE_SETREG(vt_hblank, outputVal);
	outputVal = 0;
	SET_DBE_FIELD(VT_VCMAP, VT_VCMAP_ON, outputVal,
		      currentTiming->vblank_start);
	SET_DBE_FIELD(VT_VCMAP, VT_VCMAP_OFF, outputVal,
		      currentTiming->vblank_end);
	DBE_SETREG(vt_vcmap, outputVal);
	outputVal = 0;
	SET_DBE_FIELD(VT_HCMAP, VT_HCMAP_ON, outputVal,
		      currentTiming->hblank_start);
	SET_DBE_FIELD(VT_HCMAP, VT_HCMAP_OFF, outputVal,
		      currentTiming->hblank_end - 3);
	DBE_SETREG(vt_hcmap, outputVal);

	if (flatpanel_id != -1)
		sgivwfb_setup_flatpanel(par, currentTiming);

	outputVal = 0;
	temp = currentTiming->vblank_start - currentTiming->vblank_end - 1;
	if (temp > 0)
		temp = -temp;

	SET_DBE_FIELD(DID_START_XY, DID_STARTY, outputVal, (u32) temp);
	if (currentTiming->hblank_end >= 20)
		SET_DBE_FIELD(DID_START_XY, DID_STARTX, outputVal,
			      currentTiming->hblank_end - 20);
	else
		SET_DBE_FIELD(DID_START_XY, DID_STARTX, outputVal,
			      currentTiming->htotal - (20 -
						       currentTiming->
						       hblank_end));
	DBE_SETREG(did_start_xy, outputVal);

	outputVal = 0;
	SET_DBE_FIELD(CRS_START_XY, CRS_STARTY, outputVal,
		      (u32) (temp + 1));
	if (currentTiming->hblank_end >= DBE_CRS_MAGIC)
		SET_DBE_FIELD(CRS_START_XY, CRS_STARTX, outputVal,
			      currentTiming->hblank_end - DBE_CRS_MAGIC);
	else
		SET_DBE_FIELD(CRS_START_XY, CRS_STARTX, outputVal,
			      currentTiming->htotal - (DBE_CRS_MAGIC -
						       currentTiming->
						       hblank_end));
	DBE_SETREG(crs_start_xy, outputVal);

	outputVal = 0;
	SET_DBE_FIELD(VC_START_XY, VC_STARTY, outputVal, (u32) temp);
	SET_DBE_FIELD(VC_START_XY, VC_STARTX, outputVal,
		      currentTiming->hblank_end - 4);
	DBE_SETREG(vc_start_xy, outputVal);

	DBE_SETREG(frm_size_tile, frmWrite1);
	DBE_SETREG(frm_size_pixel, frmWrite2);

	outputVal = 0;
	SET_DBE_FIELD(DOTCLK, M, outputVal, currentTiming->pll_m - 1);
	SET_DBE_FIELD(DOTCLK, N, outputVal, currentTiming->pll_n - 1);
	SET_DBE_FIELD(DOTCLK, P, outputVal, currentTiming->pll_p);
	SET_DBE_FIELD(DOTCLK, RUN, outputVal, 1);
	DBE_SETREG(dotclock, outputVal);

	udelay(11 * 1000);

	DBE_SETREG(vt_vpixen, 0xffffff);
	DBE_SETREG(vt_hpixen, 0xffffff);

	outputVal = 0;
	SET_DBE_FIELD(VT_XYMAX, VT_MAXX, outputVal, currentTiming->htotal);
	SET_DBE_FIELD(VT_XYMAX, VT_MAXY, outputVal, currentTiming->vtotal);
	DBE_SETREG(vt_xymax, outputVal);

	outputVal = frmWrite1;
	SET_DBE_FIELD(FRM_SIZE_TILE, FRM_FIFO_RESET, outputVal, 1);
	DBE_SETREG(frm_size_tile, outputVal);
	DBE_SETREG(frm_size_tile, frmWrite1);

	outputVal = 0;
	SET_DBE_FIELD(OVR_WIDTH_TILE, OVR_FIFO_RESET, outputVal, 1);
	DBE_SETREG(ovr_width_tile, outputVal);
	DBE_SETREG(ovr_width_tile, 0);

	DBE_SETREG(frm_control, frmWrite3b);
	DBE_SETREG(did_control, 0);

	// Wait for dbe to take frame settings
	for (i = 0; i < 100000; i++) {
		DBE_GETREG(frm_inhwctrl, readVal);
		if (GET_DBE_FIELD(FRM_INHWCTRL, FRM_DMA_ENABLE, readVal) !=
		    0)
			break;
		else
			udelay(1);
	}

	if (i == 100000)
		printk(KERN_INFO
		       "sgivwfb: timeout waiting for frame DMA enable.\n");

	outputVal = 0;
	htmp = currentTiming->hblank_end - 19;
	if (htmp < 0)
		htmp += currentTiming->htotal;	/* allow blank to wrap around */
	SET_DBE_FIELD(VT_HPIXEN, VT_HPIXEN_ON, outputVal, htmp);
	SET_DBE_FIELD(VT_HPIXEN, VT_HPIXEN_OFF, outputVal,
		      ((htmp + currentTiming->width -
			2) % currentTiming->htotal));
	DBE_SETREG(vt_hpixen, outputVal);

	outputVal = 0;
	SET_DBE_FIELD(VT_VPIXEN, VT_VPIXEN_OFF, outputVal,
		      currentTiming->vblank_start);
	SET_DBE_FIELD(VT_VPIXEN, VT_VPIXEN_ON, outputVal,
		      currentTiming->vblank_end);
	DBE_SETREG(vt_vpixen, outputVal);

	// Turn off mouse cursor
	par->regs->crs_ctl = 0;

	// XXX What's this section for??
	DBE_GETREG(ctrlstat, readVal);
	readVal &= 0x02000000;

	if (readVal != 0) {
		DBE_SETREG(ctrlstat, 0x30000000);
	}
	return 0;
}

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

static int sgivwfb_setcolreg(u_int regno, u_int red, u_int green,
			     u_int blue, u_int transp,
			     struct fb_info *info)
{
	struct sgivw_par *par = (struct sgivw_par *) info->par;

	if (regno > 255)
		return 1;
	red >>= 8;
	green >>= 8;
	blue >>= 8;

	/* wait for the color map FIFO to have a free entry */
	while (par->cmap_fifo == 0)
		par->cmap_fifo = par->regs->cm_fifo;

	par->regs->cmap[regno] = (red << 24) | (green << 16) | (blue << 8);
	par->cmap_fifo--;	/* assume FIFO is filling up */
	return 0;
}

static int sgivwfb_mmap(struct fb_info *info, struct file *file,
			struct vm_area_struct *vma)
{
	unsigned long size = vma->vm_end - vma->vm_start;
	unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;

	if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT))
		return -EINVAL;
	if (offset + size > sgivwfb_mem_size)
		return -EINVAL;
	offset += sgivwfb_mem_phys;
	pgprot_val(vma->vm_page_prot) =
	    pgprot_val(vma->vm_page_prot) | _PAGE_PCD;
	vma->vm_flags |= VM_IO;
	if (remap_pfn_range(vma, vma->vm_start, offset >> PAGE_SHIFT,
						size, vma->vm_page_prot))
		return -EAGAIN;
	vma->vm_file = file;
	printk(KERN_DEBUG "sgivwfb: mmap framebuffer P(%lx)->V(%lx)\n",
	       offset, vma->vm_start);
	return 0;
}

int __init sgivwfb_setup(char *options)
{
	char *this_opt;

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

	while ((this_opt = strsep(&options, ",")) != NULL) {
		if (!strncmp(this_opt, "monitor:", 8)) {
			if (!strncmp(this_opt + 8, "crt", 3))
				flatpanel_id = -1;
			else if (!strncmp(this_opt + 8, "1600sw", 6))
				flatpanel_id = FLATPANEL_SGI_1600SW;
		}
	}
	return 0;
}

/*
 *  Initialisation
 */
static void sgivwfb_release(struct device *device)
{
}

static int __init sgivwfb_probe(struct device *device)
{
	struct platform_device *dev = to_platform_device(device);
	struct sgivw_par *par;
	struct fb_info *info;
	char *monitor;

	info = framebuffer_alloc(sizeof(struct sgivw_par) + sizeof(u32) * 256, &dev->dev);
	if (!info)
		return -ENOMEM;
	par = info->par;

	if (!request_mem_region(DBE_REG_PHYS, DBE_REG_SIZE, "sgivwfb")) {
		printk(KERN_ERR "sgivwfb: couldn't reserve mmio region\n");
		framebuffer_release(info);
		return -EBUSY;
	}

	par->regs = (struct asregs *) ioremap_nocache(DBE_REG_PHYS, DBE_REG_SIZE);
	if (!par->regs) {
		printk(KERN_ERR "sgivwfb: couldn't ioremap registers\n");
		goto fail_ioremap_regs;
	}

	mtrr_add(sgivwfb_mem_phys, sgivwfb_mem_size, MTRR_TYPE_WRCOMB, 1);

	sgivwfb_fix.smem_start = sgivwfb_mem_phys;
	sgivwfb_fix.smem_len = sgivwfb_mem_size;
	sgivwfb_fix.ywrapstep = ywrap;
	sgivwfb_fix.ypanstep = ypan;

	info->fix = sgivwfb_fix;

	switch (flatpanel_id) {
		case FLATPANEL_SGI_1600SW:
			info->var = sgivwfb_var1600sw;
			monitor = "SGI 1600SW flatpanel";
			break;
		default:
			info->var = sgivwfb_var;
			monitor = "CRT";
	}

	printk(KERN_INFO "sgivwfb: %s monitor selected\n", monitor);

	info->fbops = &sgivwfb_ops;
	info->pseudo_palette = (void *) (par + 1);
	info->flags = FBINFO_DEFAULT;

	info->screen_base = ioremap_nocache((unsigned long) sgivwfb_mem_phys, sgivwfb_mem_size);
	if (!info->screen_base) {
		printk(KERN_ERR "sgivwfb: couldn't ioremap screen_base\n");
		goto fail_ioremap_fbmem;
	}

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

	if (register_framebuffer(info) < 0) {
		printk(KERN_ERR "sgivwfb: couldn't register framebuffer\n");
		goto fail_register_framebuffer;
	}

	dev_set_drvdata(&dev->dev, info);

	printk(KERN_INFO "fb%d: SGI DBE frame buffer device, using %ldK of video memory at %#lx\n",      
		info->node, sgivwfb_mem_size >> 10, sgivwfb_mem_phys);
	return 0;

fail_register_framebuffer:
	fb_dealloc_cmap(&info->cmap);
fail_color_map:
	iounmap((char *) info->screen_base);
fail_ioremap_fbmem:
	iounmap(par->regs);
fail_ioremap_regs:
	release_mem_region(DBE_REG_PHYS, DBE_REG_SIZE);
	framebuffer_release(info);
	return -ENXIO;
}

static int sgivwfb_remove(struct device *device)
{
	struct fb_info *info = dev_get_drvdata(device);

	if (info) {
		struct sgivw_par *par = info->par;

		unregister_framebuffer(info);
		dbe_TurnOffDma(par);
		iounmap(par->regs);
		iounmap(info->screen_base);
		release_mem_region(DBE_REG_PHYS, DBE_REG_SIZE);
	}
	return 0;
}

static struct device_driver sgivwfb_driver = {
	.name	= "sgivwfb",
	.bus	= &platform_bus_type,
	.probe	= sgivwfb_probe,
	.remove	= sgivwfb_remove,
};

static struct platform_device sgivwfb_device = {
	.name	= "sgivwfb",
	.id	= 0,
	.dev	= {
		.release = sgivwfb_release,
	}
};

int __init sgivwfb_init(void)
{
	int ret;

#ifndef MODULE
	char *option = NULL;

	if (fb_get_options("sgivwfb", &option))
		return -ENODEV;
	sgivwfb_setup(option);
#endif
	ret = driver_register(&sgivwfb_driver);
	if (!ret) {
		ret = platform_device_register(&sgivwfb_device);
		if (ret)
			driver_unregister(&sgivwfb_driver);
	}
	return ret;
}

module_init(sgivwfb_init);

#ifdef MODULE
MODULE_LICENSE("GPL");

static void __exit sgivwfb_exit(void)
{
	platform_device_unregister(&sgivwfb_device);
	driver_unregister(&sgivwfb_driver);
}

module_exit(sgivwfb_exit);

#endif				/* MODULE */
