/*
 *  linux/drivers/video/console/sticore.c -
 *	core code for console driver using HP's STI firmware
 *
 *	Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org>
 *	Copyright (C) 2001-2003 Helge Deller <deller@gmx.de>
 *	Copyright (C) 2001-2002 Thomas Bogendoerfer <tsbogend@alpha.franken.de>
 * 
 * TODO:
 * - call STI in virtual mode rather than in real mode
 * - screen blanking with state_mgmt() in text mode STI ? 
 * - try to make it work on m68k hp workstations ;)
 * 
 */

#include <linux/module.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/init.h>
#include <linux/pci.h>
#include <linux/font.h>

#include <asm/hardware.h>
#include <asm/page.h>
#include <asm/parisc-device.h>
#include <asm/pdc.h>
#include <asm/cacheflush.h>
#include <asm/grfioctl.h>

#include "../sticore.h"

#define STI_DRIVERVERSION "Version 0.9a"

static struct sti_struct *default_sti __read_mostly;

/* number of STI ROMS found and their ptrs to each struct */
static int num_sti_roms __read_mostly;
static struct sti_struct *sti_roms[MAX_STI_ROMS] __read_mostly;


/* The colour indices used by STI are
 *   0 - Black
 *   1 - White
 *   2 - Red
 *   3 - Yellow/Brown
 *   4 - Green
 *   5 - Cyan
 *   6 - Blue
 *   7 - Magenta
 *
 * So we have the same colours as VGA (basically one bit each for R, G, B),
 * but have to translate them, anyway. */

static const u8 col_trans[8] = {
        0, 6, 4, 5,
        2, 7, 3, 1
};

#define c_fg(sti, c) col_trans[((c>> 8) & 7)]
#define c_bg(sti, c) col_trans[((c>>11) & 7)]
#define c_index(sti, c) ((c) & 0xff)

static const struct sti_init_flags default_init_flags = {
	.wait	= STI_WAIT, 
	.reset	= 1,
	.text	= 1, 
	.nontext = 1,
	.no_chg_bet = 1, 
	.no_chg_bei = 1, 
	.init_cmap_tx = 1,
};

static int sti_init_graph(struct sti_struct *sti)
{
	struct sti_init_inptr_ext inptr_ext = { 0, };
	struct sti_init_inptr inptr = {
		.text_planes	= 3, /* # of text planes (max 3 for STI) */
		.ext_ptr	= STI_PTR(&inptr_ext)
	};
	struct sti_init_outptr outptr = { 0, };
	unsigned long flags;
	int ret;

	spin_lock_irqsave(&sti->lock, flags);

	ret = STI_CALL(sti->init_graph, &default_init_flags, &inptr,
		&outptr, sti->glob_cfg);

	spin_unlock_irqrestore(&sti->lock, flags);

	if (ret < 0) {
		printk(KERN_ERR "STI init_graph failed (ret %d, errno %d)\n",ret,outptr.errno);
		return -1;
	}
	
	sti->text_planes = outptr.text_planes;
	return 0;
}

static const struct sti_conf_flags default_conf_flags = {
	.wait	= STI_WAIT,
};

static void sti_inq_conf(struct sti_struct *sti)
{
	struct sti_conf_inptr inptr = { 0, };
	unsigned long flags;
	s32 ret;

	sti->outptr.ext_ptr = STI_PTR(&sti->outptr_ext);
	
	do {
		spin_lock_irqsave(&sti->lock, flags);
		ret = STI_CALL(sti->inq_conf, &default_conf_flags,
			&inptr, &sti->outptr, sti->glob_cfg);
		spin_unlock_irqrestore(&sti->lock, flags);
	} while (ret == 1);
}

static const struct sti_font_flags default_font_flags = {
	.wait		= STI_WAIT,
	.non_text	= 0,
};

void
sti_putc(struct sti_struct *sti, int c, int y, int x)
{
	struct sti_font_inptr inptr = {
		.font_start_addr= STI_PTR(sti->font->raw),
		.index		= c_index(sti, c),
		.fg_color	= c_fg(sti, c),
		.bg_color	= c_bg(sti, c),
		.dest_x		= x * sti->font_width,
		.dest_y		= y * sti->font_height,
	};
	struct sti_font_outptr outptr = { 0, };
	s32 ret;
	unsigned long flags;

	do {
		spin_lock_irqsave(&sti->lock, flags);
		ret = STI_CALL(sti->font_unpmv, &default_font_flags,
			&inptr, &outptr, sti->glob_cfg);
		spin_unlock_irqrestore(&sti->lock, flags);
	} while (ret == 1);
}

static const struct sti_blkmv_flags clear_blkmv_flags = {
	.wait	= STI_WAIT, 
	.color	= 1, 
	.clear	= 1, 
};

void
sti_set(struct sti_struct *sti, int src_y, int src_x,
	int height, int width, u8 color)
{
	struct sti_blkmv_inptr inptr = {
		.fg_color	= color,
		.bg_color	= color,
		.src_x		= src_x,
		.src_y		= src_y,
		.dest_x		= src_x,
		.dest_y		= src_y,
		.width		= width,
		.height		= height,
	};
	struct sti_blkmv_outptr outptr = { 0, };
	s32 ret;
	unsigned long flags;
	
	do {
		spin_lock_irqsave(&sti->lock, flags);
		ret = STI_CALL(sti->block_move, &clear_blkmv_flags,
			&inptr, &outptr, sti->glob_cfg);
		spin_unlock_irqrestore(&sti->lock, flags);
	} while (ret == 1);
}

void
sti_clear(struct sti_struct *sti, int src_y, int src_x,
	  int height, int width, int c)
{
	struct sti_blkmv_inptr inptr = {
		.fg_color	= c_fg(sti, c),
		.bg_color	= c_bg(sti, c),
		.src_x		= src_x * sti->font_width,
		.src_y		= src_y * sti->font_height,
		.dest_x		= src_x * sti->font_width,
		.dest_y		= src_y * sti->font_height,
		.width		= width * sti->font_width,
		.height		= height* sti->font_height,
	};
	struct sti_blkmv_outptr outptr = { 0, };
	s32 ret;
	unsigned long flags;

	do {
		spin_lock_irqsave(&sti->lock, flags);
		ret = STI_CALL(sti->block_move, &clear_blkmv_flags,
			&inptr, &outptr, sti->glob_cfg);
		spin_unlock_irqrestore(&sti->lock, flags);
	} while (ret == 1);
}

static const struct sti_blkmv_flags default_blkmv_flags = {
	.wait = STI_WAIT, 
};

void
sti_bmove(struct sti_struct *sti, int src_y, int src_x,
	  int dst_y, int dst_x, int height, int width)
{
	struct sti_blkmv_inptr inptr = {
		.src_x		= src_x * sti->font_width,
		.src_y		= src_y * sti->font_height,
		.dest_x		= dst_x * sti->font_width,
		.dest_y		= dst_y * sti->font_height,
		.width		= width * sti->font_width,
		.height		= height* sti->font_height,
	};
	struct sti_blkmv_outptr outptr = { 0, };
	s32 ret;
	unsigned long flags;

	do {
		spin_lock_irqsave(&sti->lock, flags);
		ret = STI_CALL(sti->block_move, &default_blkmv_flags,
			&inptr, &outptr, sti->glob_cfg);
		spin_unlock_irqrestore(&sti->lock, flags);
	} while (ret == 1);
}


static void sti_flush(unsigned long start, unsigned long end)
{
	flush_icache_range(start, end);
}

static void __devinit sti_rom_copy(unsigned long base, unsigned long count,
				   void *dest)
{
	unsigned long dest_start = (unsigned long) dest;

	/* this still needs to be revisited (see arch/parisc/mm/init.c:246) ! */
	while (count >= 4) {
		count -= 4;
		*(u32 *)dest = gsc_readl(base);
		base += 4;
		dest += 4;
	}
	while (count) {
		count--;
		*(u8 *)dest = gsc_readb(base);
		base++;
		dest++;
	}

	sti_flush(dest_start, (unsigned long)dest);
}




static char default_sti_path[21] __read_mostly;

#ifndef MODULE
static int __devinit sti_setup(char *str)
{
	if (str)
		strlcpy (default_sti_path, str, sizeof (default_sti_path));
	
	return 1;
}

/*	Assuming the machine has multiple STI consoles (=graphic cards) which
 *	all get detected by sticon, the user may define with the linux kernel
 *	parameter sti=<x> which of them will be the initial boot-console.
 *	<x> is a number between 0 and MAX_STI_ROMS, with 0 as the default 
 *	STI screen.
 */
__setup("sti=", sti_setup);
#endif



static char __devinitdata	*font_name[MAX_STI_ROMS] = { "VGA8x16", };
static int __devinitdata	font_index[MAX_STI_ROMS],
				font_height[MAX_STI_ROMS],
				font_width[MAX_STI_ROMS];
#ifndef MODULE
static int __devinit sti_font_setup(char *str)
{
	char *x;
	int i = 0;

	/* we accept sti_font=VGA8x16, sti_font=10x20, sti_font=10*20 
	 * or sti_font=7 style command lines. */

	while (i<MAX_STI_ROMS && str && *str) {
		if (*str>='0' && *str<='9') {
			if ((x = strchr(str, 'x')) || (x = strchr(str, '*'))) {
				font_height[i] = simple_strtoul(str, NULL, 0);
				font_width[i] = simple_strtoul(x+1, NULL, 0);
			} else {
				font_index[i] = simple_strtoul(str, NULL, 0);
			}
		} else {
			font_name[i] = str;	/* fb font name */
		}

		if ((x = strchr(str, ',')))
			*x++ = 0;
		str = x;

		i++;
	}

	return 1;
}

/*	The optional linux kernel parameter "sti_font" defines which font
 *	should be used by the sticon driver to draw characters to the screen.
 *	Possible values are:
 *	- sti_font=<fb_fontname>:
 *		<fb_fontname> is the name of one of the linux-kernel built-in 
 *		framebuffer font names (e.g. VGA8x16, SUN22x18). 
 *		This is only available if the fonts have been statically compiled 
 *		in with e.g. the CONFIG_FONT_8x16 or CONFIG_FONT_SUN12x22 options.
 *	- sti_font=<number>
 *		most STI ROMs have built-in HP specific fonts, which can be selected
 *		by giving the desired number to the sticon driver. 
 *		NOTE: This number is machine and STI ROM dependend.
 *	- sti_font=<height>x<width>  (e.g. sti_font=16x8)
 *		<height> and <width> gives hints to the height and width of the
 *		font which the user wants. The sticon driver will try to use
 *		a font with this height and width, but if no suitable font is
 *		found, sticon will use the default 8x8 font.
 */
__setup("sti_font=", sti_font_setup);
#endif


	
static void __devinit
sti_dump_globcfg(struct sti_glob_cfg *glob_cfg, unsigned int sti_mem_request)
{
	struct sti_glob_cfg_ext *cfg;
	
	DPRINTK((KERN_INFO
		"%d text planes\n"
		"%4d x %4d screen resolution\n"
		"%4d x %4d offscreen\n"
		"%4d x %4d layout\n"
		"regions at %08x %08x %08x %08x\n"
		"regions at %08x %08x %08x %08x\n"
		"reent_lvl %d\n"
		"save_addr %08x\n",
		glob_cfg->text_planes,
		glob_cfg->onscreen_x, glob_cfg->onscreen_y,
		glob_cfg->offscreen_x, glob_cfg->offscreen_y,
		glob_cfg->total_x, glob_cfg->total_y,
		glob_cfg->region_ptrs[0], glob_cfg->region_ptrs[1],
		glob_cfg->region_ptrs[2], glob_cfg->region_ptrs[3],
		glob_cfg->region_ptrs[4], glob_cfg->region_ptrs[5],
		glob_cfg->region_ptrs[6], glob_cfg->region_ptrs[7],
		glob_cfg->reent_lvl,
		glob_cfg->save_addr));

	/* dump extended cfg */ 
	cfg = PTR_STI((unsigned long)glob_cfg->ext_ptr);
	DPRINTK(( KERN_INFO
		"monitor %d\n"
		"in friendly mode: %d\n"
		"power consumption %d watts\n"
		"freq ref %d\n"
		"sti_mem_addr %08x (size=%d bytes)\n",
		cfg->curr_mon,
		cfg->friendly_boot,
		cfg->power,
		cfg->freq_ref,
		cfg->sti_mem_addr, sti_mem_request));
}

static void __devinit
sti_dump_outptr(struct sti_struct *sti)
{
	DPRINTK((KERN_INFO
		"%d bits per pixel\n"
		"%d used bits\n"
		"%d planes\n"
		"attributes %08x\n",
		 sti->outptr.bits_per_pixel,
		 sti->outptr.bits_used,
		 sti->outptr.planes,
		 sti->outptr.attributes));
}

static int __devinit
sti_init_glob_cfg(struct sti_struct *sti,
	    unsigned long rom_address, unsigned long hpa)
{
	struct sti_glob_cfg *glob_cfg;
	struct sti_glob_cfg_ext *glob_cfg_ext;
	void *save_addr;
	void *sti_mem_addr;
	const int save_addr_size = 1024;	/* XXX */
	int i;

	if (!sti->sti_mem_request)
		sti->sti_mem_request = 256; /* STI default */

	glob_cfg = kzalloc(sizeof(*sti->glob_cfg), GFP_KERNEL);
	glob_cfg_ext = kzalloc(sizeof(*glob_cfg_ext), GFP_KERNEL);
	save_addr = kzalloc(save_addr_size, GFP_KERNEL);
	sti_mem_addr = kzalloc(sti->sti_mem_request, GFP_KERNEL);

	if (!(glob_cfg && glob_cfg_ext && save_addr && sti_mem_addr)) {
		kfree(glob_cfg);
		kfree(glob_cfg_ext);
		kfree(save_addr);
		kfree(sti_mem_addr);
		return -ENOMEM;
	}

	glob_cfg->ext_ptr = STI_PTR(glob_cfg_ext);
	glob_cfg->save_addr = STI_PTR(save_addr);
	for (i=0; i<8; i++) {
		unsigned long newhpa, len;
	       
		if (sti->pd) {
			unsigned char offs = sti->rm_entry[i];
				
			if (offs == 0)
				continue;
			if (offs != PCI_ROM_ADDRESS &&
			    (offs < PCI_BASE_ADDRESS_0 ||
			     offs > PCI_BASE_ADDRESS_5)) {
				printk (KERN_WARNING
					"STI pci region mapping for region %d (%02x) can't be mapped\n",
					i,sti->rm_entry[i]);
				continue;
			}
			newhpa = pci_resource_start (sti->pd, (offs - PCI_BASE_ADDRESS_0) / 4);
		} else
			newhpa = (i == 0) ? rom_address : hpa;

		sti->regions_phys[i] =
			REGION_OFFSET_TO_PHYS(sti->regions[i], newhpa);
		
		len = sti->regions[i].region_desc.length * 4096;
		if (len)
			glob_cfg->region_ptrs[i] = sti->regions_phys[i];
		
		DPRINTK(("region #%d: phys %08lx, region_ptr %08x, len=%lukB, "
			 "btlb=%d, sysonly=%d, cache=%d, last=%d\n",
			i, sti->regions_phys[i], glob_cfg->region_ptrs[i],
			len/1024,
			sti->regions[i].region_desc.btlb,
			sti->regions[i].region_desc.sys_only,
			sti->regions[i].region_desc.cache, 
			sti->regions[i].region_desc.last));

		/* last entry reached ? */
		if (sti->regions[i].region_desc.last)
			break;
	}

	if (++i<8 && sti->regions[i].region)
		printk(KERN_WARNING "%s: *future ptr (0x%8x) not yet supported !\n",
				__FILE__, sti->regions[i].region);

	glob_cfg_ext->sti_mem_addr = STI_PTR(sti_mem_addr);

	sti->glob_cfg = glob_cfg;
	
	return 0;
}

#ifdef CONFIG_FB
static struct sti_cooked_font __devinit
*sti_select_fbfont(struct sti_cooked_rom *cooked_rom, const char *fbfont_name)
{
	const struct font_desc *fbfont;
	unsigned int size, bpc;
	void *dest;
	struct sti_rom_font *nf;
	struct sti_cooked_font *cooked_font;
	
	if (!fbfont_name || !strlen(fbfont_name))
		return NULL;
	fbfont = find_font(fbfont_name);
	if (!fbfont)
		fbfont = get_default_font(1024,768, ~(u32)0, ~(u32)0);
	if (!fbfont)
		return NULL;

	DPRINTK((KERN_DEBUG "selected %dx%d fb-font %s\n",
			fbfont->width, fbfont->height, fbfont->name));
			
	bpc = ((fbfont->width+7)/8) * fbfont->height; 
	size = bpc * 256;
	size += sizeof(struct sti_rom_font);

	nf = kzalloc(size, GFP_KERNEL);
	if (!nf)
		return NULL;

	nf->first_char = 0;
	nf->last_char = 255;
	nf->width = fbfont->width;
	nf->height = fbfont->height;
	nf->font_type = STI_FONT_HPROMAN8;
	nf->bytes_per_char = bpc;
	nf->next_font = 0;
	nf->underline_height = 1;
	nf->underline_pos = fbfont->height - nf->underline_height;

	dest = nf;
	dest += sizeof(struct sti_rom_font);
	memcpy(dest, fbfont->data, bpc*256);

	cooked_font = kzalloc(sizeof(*cooked_font), GFP_KERNEL);
	if (!cooked_font) {
		kfree(nf);
		return NULL;
	}
	
	cooked_font->raw = nf;
	cooked_font->next_font = NULL;

	cooked_rom->font_start = cooked_font;

	return cooked_font;
}
#else
static struct sti_cooked_font __devinit
*sti_select_fbfont(struct sti_cooked_rom *cooked_rom, const char *fbfont_name)
{
	return NULL;
}
#endif

static struct sti_cooked_font __devinit
*sti_select_font(struct sti_cooked_rom *rom,
		 int (*search_font_fnc)(struct sti_cooked_rom *, int, int))
{
	struct sti_cooked_font *font;
	int i;
	int index = num_sti_roms;

	/* check for framebuffer-font first */
	if ((font = sti_select_fbfont(rom, font_name[index])))
		return font;

	if (font_width[index] && font_height[index])
		font_index[index] = search_font_fnc(rom, 
				font_height[index], font_width[index]);

	for (font = rom->font_start, i = font_index[index];
	    font && (i > 0);
	    font = font->next_font, i--);

	if (font)
		return font;
	else
		return rom->font_start;
}


static void __devinit
sti_dump_rom(struct sti_rom *rom)
{
	printk(KERN_INFO "    id %04x-%04x, conforms to spec rev. %d.%02x\n",
		rom->graphics_id[0], 
		rom->graphics_id[1],
		rom->revno[0] >> 4, 
		rom->revno[0] & 0x0f);
	DPRINTK(("      supports %d monitors\n", rom->num_mons));
	DPRINTK(("      font start %08x\n", rom->font_start));
	DPRINTK(("      region list %08x\n", rom->region_list));
	DPRINTK(("      init_graph %08x\n", rom->init_graph));
	DPRINTK(("      bus support %02x\n", rom->bus_support));
	DPRINTK(("      ext bus support %02x\n", rom->ext_bus_support));
	DPRINTK(("      alternate code type %d\n", rom->alt_code_type));
}


static int __devinit
sti_cook_fonts(struct sti_cooked_rom *cooked_rom,
			struct sti_rom *raw_rom)
{
	struct sti_rom_font *raw_font, *font_start;
	struct sti_cooked_font *cooked_font;
	
	cooked_font = kzalloc(sizeof(*cooked_font), GFP_KERNEL);
	if (!cooked_font)
		return 0;

	cooked_rom->font_start = cooked_font;

	raw_font = ((void *)raw_rom) + (raw_rom->font_start);

	font_start = raw_font;
	cooked_font->raw = raw_font;

	while (raw_font->next_font) {
		raw_font = ((void *)font_start) + (raw_font->next_font);

		cooked_font->next_font = kzalloc(sizeof(*cooked_font), GFP_KERNEL);
		if (!cooked_font->next_font)
			return 1;

		cooked_font = cooked_font->next_font;

		cooked_font->raw = raw_font;
	}

	cooked_font->next_font = NULL;
	return 1;
}


static int __devinit
sti_search_font(struct sti_cooked_rom *rom, int height, int width)
{
	struct sti_cooked_font *font;
	int i = 0;
	
	for (font = rom->font_start; font; font = font->next_font, i++) {
		if ((font->raw->width == width) &&
		    (font->raw->height == height))
			return i;
	}
	return 0;
}

#define BMODE_RELOCATE(offset)		offset = (offset) / 4;
#define BMODE_LAST_ADDR_OFFS		0x50

static void * __devinit
sti_bmode_font_raw(struct sti_cooked_font *f)
{
	unsigned char *n, *p, *q;
	int size = f->raw->bytes_per_char*256+sizeof(struct sti_rom_font);
	
	n = kzalloc (4*size, GFP_KERNEL);
	if (!n)
		return NULL;
	p = n + 3;
	q = (unsigned char *)f->raw;
	while (size--) {
		*p = *q++;
		p+=4;
	}
	return n + 3;
}

static void __devinit
sti_bmode_rom_copy(unsigned long base, unsigned long count, void *dest)
{
	unsigned long dest_start = (unsigned long) dest;

	while (count) {
		count--;
		*(u8 *)dest = gsc_readl(base);
		base += 4;
		dest++;
	}

	sti_flush(dest_start, (unsigned long)dest);
}

static struct sti_rom * __devinit
sti_get_bmode_rom (unsigned long address)
{
	struct sti_rom *raw;
	u32 size;
	struct sti_rom_font *raw_font, *font_start;

	sti_bmode_rom_copy(address + BMODE_LAST_ADDR_OFFS, sizeof(size), &size);

	size = (size+3) / 4;
	raw = kmalloc(size, GFP_KERNEL);
	if (raw) {
		sti_bmode_rom_copy(address, size, raw);
		memmove (&raw->res004, &raw->type[0], 0x3c);
		raw->type[3] = raw->res004;

		BMODE_RELOCATE (raw->region_list);
		BMODE_RELOCATE (raw->font_start);

		BMODE_RELOCATE (raw->init_graph);
		BMODE_RELOCATE (raw->state_mgmt);
		BMODE_RELOCATE (raw->font_unpmv);
		BMODE_RELOCATE (raw->block_move);
		BMODE_RELOCATE (raw->inq_conf);

		raw_font = ((void *)raw) + raw->font_start;
		font_start = raw_font;
		
		while (raw_font->next_font) {
			BMODE_RELOCATE (raw_font->next_font);
			raw_font = ((void *)font_start) + raw_font->next_font;
		}
	}
	return raw;
}

static struct sti_rom __devinit *sti_get_wmode_rom(unsigned long address)
{
	struct sti_rom *raw;
	unsigned long size;

	/* read the ROM size directly from the struct in ROM */ 
	size = gsc_readl(address + offsetof(struct sti_rom,last_addr));

	raw = kmalloc(size, GFP_KERNEL);
	if (raw)
		sti_rom_copy(address, size, raw);

	return raw;
}

static int __devinit sti_read_rom(int wordmode, struct sti_struct *sti,
				  unsigned long address)
{
	struct sti_cooked_rom *cooked;
	struct sti_rom *raw = NULL;
	unsigned long revno;

	cooked = kmalloc(sizeof *cooked, GFP_KERNEL);
	if (!cooked)
		goto out_err;

	if (wordmode)
		raw = sti_get_wmode_rom (address);
	else
		raw = sti_get_bmode_rom (address);

	if (!raw)
		goto out_err;

	if (!sti_cook_fonts(cooked, raw)) {
		printk(KERN_ERR "No font found for STI at %08lx\n", address);
		goto out_err;
	}

	if (raw->region_list)
		memcpy(sti->regions, ((void *)raw)+raw->region_list, sizeof(sti->regions));

	address = (unsigned long) STI_PTR(raw);

	sti->font_unpmv = address + (raw->font_unpmv & 0x03ffffff);
	sti->block_move = address + (raw->block_move & 0x03ffffff);
	sti->init_graph = address + (raw->init_graph & 0x03ffffff);
	sti->inq_conf   = address + (raw->inq_conf   & 0x03ffffff);

	sti->rom = cooked;
	sti->rom->raw = raw;
	
	sti->font = sti_select_font(sti->rom, sti_search_font);
	sti->font_width = sti->font->raw->width;
	sti->font_height = sti->font->raw->height;
	if (!wordmode)
		sti->font->raw = sti_bmode_font_raw(sti->font);

	sti->sti_mem_request = raw->sti_mem_req;
	sti->graphics_id[0] = raw->graphics_id[0];
	sti->graphics_id[1] = raw->graphics_id[1];
	
	sti_dump_rom(raw);

	/* check if the ROM routines in this card are compatible */
	if (wordmode || sti->graphics_id[1] != 0x09A02587)
		goto ok;

	revno = (raw->revno[0] << 8) | raw->revno[1];

	switch (sti->graphics_id[0]) {
	case S9000_ID_HCRX:
		/* HyperA or HyperB ? */
		if (revno == 0x8408 || revno == 0x840b)
			goto msg_not_supported;
		break;
	case CRT_ID_THUNDER:
		if (revno == 0x8509)
			goto msg_not_supported;
		break;
	case CRT_ID_THUNDER2:
		if (revno == 0x850c)
			goto msg_not_supported;
	}
ok:
	return 1;

msg_not_supported:
	printk(KERN_ERR "Sorry, this GSC/STI card is not yet supported.\n");
	printk(KERN_ERR "Please see http://parisc-linux.org/faq/"
			"graphics-howto.html for more info.\n");
	/* fall through */
out_err:
	kfree(raw);
	kfree(cooked);
	return 0;
}

static struct sti_struct * __devinit
sti_try_rom_generic(unsigned long address, unsigned long hpa, struct pci_dev *pd)
{
	struct sti_struct *sti;
	int ok;
	u32 sig;

	if (num_sti_roms >= MAX_STI_ROMS) {
		printk(KERN_WARNING "maximum number of STI ROMS reached !\n");
		return NULL;
	}
	
	sti = kzalloc(sizeof(*sti), GFP_KERNEL);
	if (!sti) {
		printk(KERN_ERR "Not enough memory !\n");
		return NULL;
	}

	spin_lock_init(&sti->lock);

test_rom:
	/* if we can't read the ROM, bail out early.  Not being able
	 * to read the hpa is okay, for romless sti */
	if (pdc_add_valid(address))
		goto out_err;

	sig = gsc_readl(address);

	/* check for a PCI ROM structure */
	if ((le32_to_cpu(sig)==0xaa55)) {
		unsigned int i, rm_offset;
		u32 *rm;
		i = gsc_readl(address+0x04);
		if (i != 1) {
			/* The ROM could have multiple architecture 
			 * dependent images (e.g. i386, parisc,...) */
			printk(KERN_WARNING 
				"PCI ROM is not a STI ROM type image (0x%8x)\n", i);
			goto out_err;
		}
		
		sti->pd = pd;

		i = gsc_readl(address+0x0c);
		DPRINTK(("PCI ROM size (from header) = %d kB\n",
			le16_to_cpu(i>>16)*512/1024));
		rm_offset = le16_to_cpu(i & 0xffff);
		if (rm_offset) { 
			/* read 16 bytes from the pci region mapper array */
			rm = (u32*) &sti->rm_entry;
			*rm++ = gsc_readl(address+rm_offset+0x00);
			*rm++ = gsc_readl(address+rm_offset+0x04);
			*rm++ = gsc_readl(address+rm_offset+0x08);
			*rm++ = gsc_readl(address+rm_offset+0x0c);
			DPRINTK(("PCI region Mapper offset = %08x: ",
				rm_offset));
			for (i=0; i<16; i++)
				DPRINTK(("%02x ", sti->rm_entry[i]));
			DPRINTK(("\n"));
		}

		address += le32_to_cpu(gsc_readl(address+8));
		DPRINTK(("sig %04x, PCI STI ROM at %08lx\n", sig, address));
		goto test_rom;
	}
	
	ok = 0;
	
	if ((sig & 0xff) == 0x01) {
		DPRINTK(("    byte mode ROM at %08lx, hpa at %08lx\n",
		       address, hpa));
		ok = sti_read_rom(0, sti, address);
	}

	if ((sig & 0xffff) == 0x0303) {
		DPRINTK(("    word mode ROM at %08lx, hpa at %08lx\n",
		       address, hpa));
		ok = sti_read_rom(1, sti, address);
	}

	if (!ok)
		goto out_err;

	if (sti_init_glob_cfg(sti, address, hpa))
		goto out_err; /* not enough memory */

	/* disable STI PCI ROM. ROM and card RAM overlap and
	 * leaving it enabled would force HPMCs
	 */
	if (sti->pd) {
		unsigned long rom_base;
		rom_base = pci_resource_start(sti->pd, PCI_ROM_RESOURCE);	
		pci_write_config_dword(sti->pd, PCI_ROM_ADDRESS, rom_base & ~PCI_ROM_ADDRESS_ENABLE);
		DPRINTK((KERN_DEBUG "STI PCI ROM disabled\n"));
	}

	if (sti_init_graph(sti))
		goto out_err;

	sti_inq_conf(sti);
	sti_dump_globcfg(sti->glob_cfg, sti->sti_mem_request);
	sti_dump_outptr(sti);
	
	printk(KERN_INFO "    graphics card name: %s\n", sti->outptr.dev_name );

	sti_roms[num_sti_roms] = sti;
	num_sti_roms++;
	
	return sti;

out_err:
	kfree(sti);
	return NULL;
}

static void __devinit sticore_check_for_default_sti(struct sti_struct *sti, char *path)
{
	if (strcmp (path, default_sti_path) == 0)
		default_sti = sti;
}

/*
 * on newer systems PDC gives the address of the ROM 
 * in the additional address field addr[1] while on
 * older Systems the PDC stores it in page0->proc_sti 
 */
static int __devinit sticore_pa_init(struct parisc_device *dev)
{
	char pa_path[21];
	struct sti_struct *sti = NULL;
	int hpa = dev->hpa.start;

	if (dev->num_addrs && dev->addr[0])
		sti = sti_try_rom_generic(dev->addr[0], hpa, NULL);
	if (!sti)
		sti = sti_try_rom_generic(hpa, hpa, NULL);
	if (!sti)
		sti = sti_try_rom_generic(PAGE0->proc_sti, hpa, NULL);
	if (!sti)
		return 1;

	print_pa_hwpath(dev, pa_path);
	sticore_check_for_default_sti(sti, pa_path);
	return 0;
}


static int __devinit sticore_pci_init(struct pci_dev *pd,
		const struct pci_device_id *ent)
{
#ifdef CONFIG_PCI
	unsigned long fb_base, rom_base;
	unsigned int fb_len, rom_len;
	int err;
	struct sti_struct *sti;
	
	err = pci_enable_device(pd);
	if (err < 0) {
		dev_err(&pd->dev, "Cannot enable PCI device\n");
		return err;
	}

	fb_base = pci_resource_start(pd, 0);
	fb_len = pci_resource_len(pd, 0);
	rom_base = pci_resource_start(pd, PCI_ROM_RESOURCE);
	rom_len = pci_resource_len(pd, PCI_ROM_RESOURCE);
	if (rom_base) {
		pci_write_config_dword(pd, PCI_ROM_ADDRESS, rom_base | PCI_ROM_ADDRESS_ENABLE);
		DPRINTK((KERN_DEBUG "STI PCI ROM enabled at 0x%08lx\n", rom_base));
	}

	printk(KERN_INFO "STI PCI graphic ROM found at %08lx (%u kB), fb at %08lx (%u MB)\n",
		rom_base, rom_len/1024, fb_base, fb_len/1024/1024);

	DPRINTK((KERN_DEBUG "Trying PCI STI ROM at %08lx, PCI hpa at %08lx\n",
		    rom_base, fb_base));

	sti = sti_try_rom_generic(rom_base, fb_base, pd);
	if (sti) {
		char pa_path[30];
		print_pci_hwpath(pd, pa_path);
		sticore_check_for_default_sti(sti, pa_path);
	}
	
	if (!sti) {
		printk(KERN_WARNING "Unable to handle STI device '%s'\n",
			pci_name(pd));
		return -ENODEV;
	}
#endif /* CONFIG_PCI */

	return 0;
}


static void __devexit sticore_pci_remove(struct pci_dev *pd)
{
	BUG();
}


static struct pci_device_id sti_pci_tbl[] = {
	{ PCI_DEVICE(PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_VISUALIZE_EG) },
	{ PCI_DEVICE(PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_VISUALIZE_FX6) },
	{ PCI_DEVICE(PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_VISUALIZE_FX4) },
	{ PCI_DEVICE(PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_VISUALIZE_FX2) },
	{ PCI_DEVICE(PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_VISUALIZE_FXE) },
	{ 0, } /* terminate list */
};
MODULE_DEVICE_TABLE(pci, sti_pci_tbl);

static struct pci_driver pci_sti_driver = {
	.name		= "sti",
	.id_table	= sti_pci_tbl,
	.probe		= sticore_pci_init,
	.remove		= sticore_pci_remove,
};

static struct parisc_device_id sti_pa_tbl[] = {
	{ HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x00077 },
	{ HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x00085 },
	{ 0, }
};

static struct parisc_driver pa_sti_driver = {
	.name		= "sti",
	.id_table	= sti_pa_tbl,
	.probe		= sticore_pa_init,
};


/*
 * sti_init_roms() - detects all STI ROMs and stores them in sti_roms[]
 */

static int sticore_initialized __read_mostly;

static void __devinit sti_init_roms(void)
{
	if (sticore_initialized)
		return;

	sticore_initialized = 1;

	printk(KERN_INFO "STI GSC/PCI core graphics driver "
			STI_DRIVERVERSION "\n");

	/* Register drivers for native & PCI cards */
	register_parisc_driver(&pa_sti_driver);
	WARN_ON(pci_register_driver(&pci_sti_driver));

	/* if we didn't find the given default sti, take the first one */
	if (!default_sti)
		default_sti = sti_roms[0];

}

/*
 * index = 0 gives default sti
 * index > 0 gives other stis in detection order
 */
struct sti_struct * sti_get_rom(unsigned int index)
{
	if (!sticore_initialized)
		sti_init_roms();

	if (index == 0)
		return default_sti;

	if (index > num_sti_roms)
		return NULL;

	return sti_roms[index-1];
}
EXPORT_SYMBOL(sti_get_rom);

MODULE_AUTHOR("Philipp Rumpf, Helge Deller, Thomas Bogendoerfer");
MODULE_DESCRIPTION("Core STI driver for HP's NGLE series graphics cards in HP PARISC machines");
MODULE_LICENSE("GPL v2");

