cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

tdfxfb.c (43021B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 *
      4 * tdfxfb.c
      5 *
      6 * Author: Hannu Mallat <hmallat@cc.hut.fi>
      7 *
      8 * Copyright © 1999 Hannu Mallat
      9 * All rights reserved
     10 *
     11 * Created      : Thu Sep 23 18:17:43 1999, hmallat
     12 * Last modified: Tue Nov  2 21:19:47 1999, hmallat
     13 *
     14 * I2C part copied from the i2c-voodoo3.c driver by:
     15 * Frodo Looijaard <frodol@dds.nl>,
     16 * Philip Edelbrock <phil@netroedge.com>,
     17 * Ralph Metzler <rjkm@thp.uni-koeln.de>, and
     18 * Mark D. Studebaker <mdsxyz123@yahoo.com>
     19 *
     20 * Lots of the information here comes from the Daryll Strauss' Banshee
     21 * patches to the XF86 server, and the rest comes from the 3dfx
     22 * Banshee specification. I'm very much indebted to Daryll for his
     23 * work on the X server.
     24 *
     25 * Voodoo3 support was contributed Harold Oga. Lots of additions
     26 * (proper acceleration, 24 bpp, hardware cursor) and bug fixes by Attila
     27 * Kesmarki. Thanks guys!
     28 *
     29 * Voodoo1 and Voodoo2 support aren't relevant to this driver as they
     30 * behave very differently from the Voodoo3/4/5. For anyone wanting to
     31 * use frame buffer on the Voodoo1/2, see the sstfb driver (which is
     32 * located at http://www.sourceforge.net/projects/sstfb).
     33 *
     34 * While I _am_ grateful to 3Dfx for releasing the specs for Banshee,
     35 * I do wish the next version is a bit more complete. Without the XF86
     36 * patches I couldn't have gotten even this far... for instance, the
     37 * extensions to the VGA register set go completely unmentioned in the
     38 * spec! Also, lots of references are made to the 'SST core', but no
     39 * spec is publicly available, AFAIK.
     40 *
     41 * The structure of this driver comes pretty much from the Permedia
     42 * driver by Ilario Nardinocchi, which in turn is based on skeletonfb.
     43 *
     44 * TODO:
     45 * - multihead support (basically need to support an array of fb_infos)
     46 * - support other architectures (PPC, Alpha); does the fact that the VGA
     47 *   core can be accessed only thru I/O (not memory mapped) complicate
     48 *   things?
     49 *
     50 * Version history:
     51 *
     52 * 0.1.4 (released 2002-05-28)	ported over to new fbdev api by James Simmons
     53 *
     54 * 0.1.3 (released 1999-11-02)	added Attila's panning support, code
     55 *				reorg, hwcursor address page size alignment
     56 *				(for mmapping both frame buffer and regs),
     57 *				and my changes to get rid of hardcoded
     58 *				VGA i/o register locations (uses PCI
     59 *				configuration info now)
     60 * 0.1.2 (released 1999-10-19)	added Attila Kesmarki's bug fixes and
     61 *				improvements
     62 * 0.1.1 (released 1999-10-07)	added Voodoo3 support by Harold Oga.
     63 * 0.1.0 (released 1999-10-06)	initial version
     64 *
     65 */
     66
     67#include <linux/module.h>
     68#include <linux/kernel.h>
     69#include <linux/errno.h>
     70#include <linux/string.h>
     71#include <linux/mm.h>
     72#include <linux/slab.h>
     73#include <linux/fb.h>
     74#include <linux/init.h>
     75#include <linux/pci.h>
     76#include <asm/io.h>
     77
     78#include <video/tdfx.h>
     79
     80#define DPRINTK(a, b...) pr_debug("fb: %s: " a, __func__ , ## b)
     81
     82#define BANSHEE_MAX_PIXCLOCK 270000
     83#define VOODOO3_MAX_PIXCLOCK 300000
     84#define VOODOO5_MAX_PIXCLOCK 350000
     85
     86static const struct fb_fix_screeninfo tdfx_fix = {
     87	.type =		FB_TYPE_PACKED_PIXELS,
     88	.visual =	FB_VISUAL_PSEUDOCOLOR,
     89	.ypanstep =	1,
     90	.ywrapstep =	1,
     91	.accel =	FB_ACCEL_3DFX_BANSHEE
     92};
     93
     94static const struct fb_var_screeninfo tdfx_var = {
     95	/* "640x480, 8 bpp @ 60 Hz */
     96	.xres =		640,
     97	.yres =		480,
     98	.xres_virtual =	640,
     99	.yres_virtual =	1024,
    100	.bits_per_pixel = 8,
    101	.red =		{0, 8, 0},
    102	.blue =		{0, 8, 0},
    103	.green =	{0, 8, 0},
    104	.activate =	FB_ACTIVATE_NOW,
    105	.height =	-1,
    106	.width =	-1,
    107	.accel_flags =	FB_ACCELF_TEXT,
    108	.pixclock =	39722,
    109	.left_margin =	40,
    110	.right_margin =	24,
    111	.upper_margin =	32,
    112	.lower_margin =	11,
    113	.hsync_len =	96,
    114	.vsync_len =	2,
    115	.vmode =	FB_VMODE_NONINTERLACED
    116};
    117
    118/*
    119 * PCI driver prototypes
    120 */
    121static int tdfxfb_probe(struct pci_dev *pdev, const struct pci_device_id *id);
    122static void tdfxfb_remove(struct pci_dev *pdev);
    123
    124static const struct pci_device_id tdfxfb_id_table[] = {
    125	{ PCI_VENDOR_ID_3DFX, PCI_DEVICE_ID_3DFX_BANSHEE,
    126	  PCI_ANY_ID, PCI_ANY_ID, PCI_BASE_CLASS_DISPLAY << 16,
    127	  0xff0000, 0 },
    128	{ PCI_VENDOR_ID_3DFX, PCI_DEVICE_ID_3DFX_VOODOO3,
    129	  PCI_ANY_ID, PCI_ANY_ID, PCI_BASE_CLASS_DISPLAY << 16,
    130	  0xff0000, 0 },
    131	{ PCI_VENDOR_ID_3DFX, PCI_DEVICE_ID_3DFX_VOODOO5,
    132	  PCI_ANY_ID, PCI_ANY_ID, PCI_BASE_CLASS_DISPLAY << 16,
    133	  0xff0000, 0 },
    134	{ 0, }
    135};
    136
    137static struct pci_driver tdfxfb_driver = {
    138	.name		= "tdfxfb",
    139	.id_table	= tdfxfb_id_table,
    140	.probe		= tdfxfb_probe,
    141	.remove		= tdfxfb_remove,
    142};
    143
    144MODULE_DEVICE_TABLE(pci, tdfxfb_id_table);
    145
    146/*
    147 * Driver data
    148 */
    149static int nopan;
    150static int nowrap = 1;      /* not implemented (yet) */
    151static int hwcursor = 1;
    152static char *mode_option;
    153static bool nomtrr;
    154
    155/* -------------------------------------------------------------------------
    156 *			Hardware-specific funcions
    157 * ------------------------------------------------------------------------- */
    158
    159static inline u8 vga_inb(struct tdfx_par *par, u32 reg)
    160{
    161	return inb(par->iobase + reg - 0x300);
    162}
    163
    164static inline void vga_outb(struct tdfx_par *par, u32 reg, u8 val)
    165{
    166	outb(val, par->iobase + reg - 0x300);
    167}
    168
    169static inline void gra_outb(struct tdfx_par *par, u32 idx, u8 val)
    170{
    171	vga_outb(par, GRA_I, idx);
    172	wmb();
    173	vga_outb(par, GRA_D, val);
    174	wmb();
    175}
    176
    177static inline void seq_outb(struct tdfx_par *par, u32 idx, u8 val)
    178{
    179	vga_outb(par, SEQ_I, idx);
    180	wmb();
    181	vga_outb(par, SEQ_D, val);
    182	wmb();
    183}
    184
    185static inline u8 seq_inb(struct tdfx_par *par, u32 idx)
    186{
    187	vga_outb(par, SEQ_I, idx);
    188	mb();
    189	return vga_inb(par, SEQ_D);
    190}
    191
    192static inline void crt_outb(struct tdfx_par *par, u32 idx, u8 val)
    193{
    194	vga_outb(par, CRT_I, idx);
    195	wmb();
    196	vga_outb(par, CRT_D, val);
    197	wmb();
    198}
    199
    200static inline u8 crt_inb(struct tdfx_par *par, u32 idx)
    201{
    202	vga_outb(par, CRT_I, idx);
    203	mb();
    204	return vga_inb(par, CRT_D);
    205}
    206
    207static inline void att_outb(struct tdfx_par *par, u32 idx, u8 val)
    208{
    209	vga_inb(par, IS1_R);
    210	vga_outb(par, ATT_IW, idx);
    211	vga_outb(par, ATT_IW, val);
    212}
    213
    214static inline void vga_disable_video(struct tdfx_par *par)
    215{
    216	unsigned char s;
    217
    218	s = seq_inb(par, 0x01) | 0x20;
    219	seq_outb(par, 0x00, 0x01);
    220	seq_outb(par, 0x01, s);
    221	seq_outb(par, 0x00, 0x03);
    222}
    223
    224static inline void vga_enable_video(struct tdfx_par *par)
    225{
    226	unsigned char s;
    227
    228	s = seq_inb(par, 0x01) & 0xdf;
    229	seq_outb(par, 0x00, 0x01);
    230	seq_outb(par, 0x01, s);
    231	seq_outb(par, 0x00, 0x03);
    232}
    233
    234static inline void vga_enable_palette(struct tdfx_par *par)
    235{
    236	vga_inb(par, IS1_R);
    237	mb();
    238	vga_outb(par, ATT_IW, 0x20);
    239}
    240
    241static inline u32 tdfx_inl(struct tdfx_par *par, unsigned int reg)
    242{
    243	return readl(par->regbase_virt + reg);
    244}
    245
    246static inline void tdfx_outl(struct tdfx_par *par, unsigned int reg, u32 val)
    247{
    248	writel(val, par->regbase_virt + reg);
    249}
    250
    251static inline void banshee_make_room(struct tdfx_par *par, int size)
    252{
    253	/* Note: The Voodoo3's onboard FIFO has 32 slots. This loop
    254	 * won't quit if you ask for more. */
    255	while ((tdfx_inl(par, STATUS) & 0x1f) < size - 1)
    256		cpu_relax();
    257}
    258
    259static int banshee_wait_idle(struct fb_info *info)
    260{
    261	struct tdfx_par *par = info->par;
    262	int i = 0;
    263
    264	banshee_make_room(par, 1);
    265	tdfx_outl(par, COMMAND_3D, COMMAND_3D_NOP);
    266
    267	do {
    268		if ((tdfx_inl(par, STATUS) & STATUS_BUSY) == 0)
    269			i++;
    270	} while (i < 3);
    271
    272	return 0;
    273}
    274
    275/*
    276 * Set the color of a palette entry in 8bpp mode
    277 */
    278static inline void do_setpalentry(struct tdfx_par *par, unsigned regno, u32 c)
    279{
    280	banshee_make_room(par, 2);
    281	tdfx_outl(par, DACADDR, regno);
    282	/* read after write makes it working */
    283	tdfx_inl(par, DACADDR);
    284	tdfx_outl(par, DACDATA, c);
    285}
    286
    287static u32 do_calc_pll(int freq, int *freq_out)
    288{
    289	int m, n, k, best_m, best_n, best_k, best_error;
    290	int fref = 14318;
    291
    292	best_error = freq;
    293	best_n = best_m = best_k = 0;
    294
    295	for (k = 3; k >= 0; k--) {
    296		for (m = 63; m >= 0; m--) {
    297			/*
    298			 * Estimate value of n that produces target frequency
    299			 * with current m and k
    300			 */
    301			int n_estimated = ((freq * (m + 2) << k) / fref) - 2;
    302
    303			/* Search neighborhood of estimated n */
    304			for (n = max(0, n_estimated);
    305				n <= min(255, n_estimated + 1);
    306				n++) {
    307				/*
    308				 * Calculate PLL freqency with current m, k and
    309				 * estimated n
    310				 */
    311				int f = (fref * (n + 2) / (m + 2)) >> k;
    312				int error = abs(f - freq);
    313
    314				/*
    315				 * If this is the closest we've come to the
    316				 * target frequency then remember n, m and k
    317				 */
    318				if (error < best_error) {
    319					best_error = error;
    320					best_n = n;
    321					best_m = m;
    322					best_k = k;
    323				}
    324			}
    325		}
    326	}
    327
    328	n = best_n;
    329	m = best_m;
    330	k = best_k;
    331	*freq_out = (fref * (n + 2) / (m + 2)) >> k;
    332
    333	return (n << 8) | (m << 2) | k;
    334}
    335
    336static void do_write_regs(struct fb_info *info, struct banshee_reg *reg)
    337{
    338	struct tdfx_par *par = info->par;
    339	int i;
    340
    341	banshee_wait_idle(info);
    342
    343	tdfx_outl(par, MISCINIT1, tdfx_inl(par, MISCINIT1) | 0x01);
    344
    345	crt_outb(par, 0x11, crt_inb(par, 0x11) & 0x7f); /* CRT unprotect */
    346
    347	banshee_make_room(par, 3);
    348	tdfx_outl(par, VGAINIT1, reg->vgainit1 & 0x001FFFFF);
    349	tdfx_outl(par, VIDPROCCFG, reg->vidcfg & ~0x00000001);
    350#if 0
    351	tdfx_outl(par, PLLCTRL1, reg->mempll);
    352	tdfx_outl(par, PLLCTRL2, reg->gfxpll);
    353#endif
    354	tdfx_outl(par, PLLCTRL0, reg->vidpll);
    355
    356	vga_outb(par, MISC_W, reg->misc[0x00] | 0x01);
    357
    358	for (i = 0; i < 5; i++)
    359		seq_outb(par, i, reg->seq[i]);
    360
    361	for (i = 0; i < 25; i++)
    362		crt_outb(par, i, reg->crt[i]);
    363
    364	for (i = 0; i < 9; i++)
    365		gra_outb(par, i, reg->gra[i]);
    366
    367	for (i = 0; i < 21; i++)
    368		att_outb(par, i, reg->att[i]);
    369
    370	crt_outb(par, 0x1a, reg->ext[0]);
    371	crt_outb(par, 0x1b, reg->ext[1]);
    372
    373	vga_enable_palette(par);
    374	vga_enable_video(par);
    375
    376	banshee_make_room(par, 9);
    377	tdfx_outl(par, VGAINIT0, reg->vgainit0);
    378	tdfx_outl(par, DACMODE, reg->dacmode);
    379	tdfx_outl(par, VIDDESKSTRIDE, reg->stride);
    380	tdfx_outl(par, HWCURPATADDR, reg->curspataddr);
    381
    382	tdfx_outl(par, VIDSCREENSIZE, reg->screensize);
    383	tdfx_outl(par, VIDDESKSTART, reg->startaddr);
    384	tdfx_outl(par, VIDPROCCFG, reg->vidcfg);
    385	tdfx_outl(par, VGAINIT1, reg->vgainit1);
    386	tdfx_outl(par, MISCINIT0, reg->miscinit0);
    387
    388	banshee_make_room(par, 8);
    389	tdfx_outl(par, SRCBASE, reg->startaddr);
    390	tdfx_outl(par, DSTBASE, reg->startaddr);
    391	tdfx_outl(par, COMMANDEXTRA_2D, 0);
    392	tdfx_outl(par, CLIP0MIN, 0);
    393	tdfx_outl(par, CLIP0MAX, 0x0fff0fff);
    394	tdfx_outl(par, CLIP1MIN, 0);
    395	tdfx_outl(par, CLIP1MAX, 0x0fff0fff);
    396	tdfx_outl(par, SRCXY, 0);
    397
    398	banshee_wait_idle(info);
    399}
    400
    401static unsigned long do_lfb_size(struct tdfx_par *par, unsigned short dev_id)
    402{
    403	u32 draminit0 = tdfx_inl(par, DRAMINIT0);
    404	u32 draminit1 = tdfx_inl(par, DRAMINIT1);
    405	u32 miscinit1;
    406	int num_chips = (draminit0 & DRAMINIT0_SGRAM_NUM) ? 8 : 4;
    407	int chip_size; /* in MB */
    408	int has_sgram = draminit1 & DRAMINIT1_MEM_SDRAM;
    409
    410	if (dev_id < PCI_DEVICE_ID_3DFX_VOODOO5) {
    411		/* Banshee/Voodoo3 */
    412		chip_size = 2;
    413		if (has_sgram && !(draminit0 & DRAMINIT0_SGRAM_TYPE))
    414			chip_size = 1;
    415	} else {
    416		/* Voodoo4/5 */
    417		has_sgram = 0;
    418		chip_size = draminit0 & DRAMINIT0_SGRAM_TYPE_MASK;
    419		chip_size = 1 << (chip_size >> DRAMINIT0_SGRAM_TYPE_SHIFT);
    420	}
    421
    422	/* disable block writes for SDRAM */
    423	miscinit1 = tdfx_inl(par, MISCINIT1);
    424	miscinit1 |= has_sgram ? 0 : MISCINIT1_2DBLOCK_DIS;
    425	miscinit1 |= MISCINIT1_CLUT_INV;
    426
    427	banshee_make_room(par, 1);
    428	tdfx_outl(par, MISCINIT1, miscinit1);
    429	return num_chips * chip_size * 1024l * 1024;
    430}
    431
    432/* ------------------------------------------------------------------------- */
    433
    434static int tdfxfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
    435{
    436	struct tdfx_par *par = info->par;
    437	u32 lpitch;
    438
    439	if (var->bits_per_pixel != 8  && var->bits_per_pixel != 16 &&
    440	    var->bits_per_pixel != 24 && var->bits_per_pixel != 32) {
    441		DPRINTK("depth not supported: %u\n", var->bits_per_pixel);
    442		return -EINVAL;
    443	}
    444
    445	if (var->xres != var->xres_virtual)
    446		var->xres_virtual = var->xres;
    447
    448	if (var->yres > var->yres_virtual)
    449		var->yres_virtual = var->yres;
    450
    451	if (var->xoffset) {
    452		DPRINTK("xoffset not supported\n");
    453		return -EINVAL;
    454	}
    455	var->yoffset = 0;
    456
    457	/*
    458	 * Banshee doesn't support interlace, but Voodoo4/5 and probably
    459	 * Voodoo3 do.
    460	 * no direct information about device id now?
    461	 *  use max_pixclock for this...
    462	 */
    463	if (((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) &&
    464	    (par->max_pixclock < VOODOO3_MAX_PIXCLOCK)) {
    465		DPRINTK("interlace not supported\n");
    466		return -EINVAL;
    467	}
    468
    469	if (info->monspecs.hfmax && info->monspecs.vfmax &&
    470	    info->monspecs.dclkmax && fb_validate_mode(var, info) < 0) {
    471		DPRINTK("mode outside monitor's specs\n");
    472		return -EINVAL;
    473	}
    474
    475	var->xres = (var->xres + 15) & ~15; /* could sometimes be 8 */
    476	lpitch = var->xres * ((var->bits_per_pixel + 7) >> 3);
    477
    478	if (var->xres < 320 || var->xres > 2048) {
    479		DPRINTK("width not supported: %u\n", var->xres);
    480		return -EINVAL;
    481	}
    482
    483	if (var->yres < 200 || var->yres > 2048) {
    484		DPRINTK("height not supported: %u\n", var->yres);
    485		return -EINVAL;
    486	}
    487
    488	if (lpitch * var->yres_virtual > info->fix.smem_len) {
    489		var->yres_virtual = info->fix.smem_len / lpitch;
    490		if (var->yres_virtual < var->yres) {
    491			DPRINTK("no memory for screen (%ux%ux%u)\n",
    492				var->xres, var->yres_virtual,
    493				var->bits_per_pixel);
    494			return -EINVAL;
    495		}
    496	}
    497
    498	if (PICOS2KHZ(var->pixclock) > par->max_pixclock) {
    499		DPRINTK("pixclock too high (%ldKHz)\n",
    500			PICOS2KHZ(var->pixclock));
    501		return -EINVAL;
    502	}
    503
    504	var->transp.offset = 0;
    505	var->transp.length = 0;
    506	switch (var->bits_per_pixel) {
    507	case 8:
    508		var->red.length = 8;
    509		var->red.offset = 0;
    510		var->green = var->red;
    511		var->blue = var->red;
    512		break;
    513	case 16:
    514		var->red.offset   = 11;
    515		var->red.length   = 5;
    516		var->green.offset = 5;
    517		var->green.length = 6;
    518		var->blue.offset  = 0;
    519		var->blue.length  = 5;
    520		break;
    521	case 32:
    522		var->transp.offset = 24;
    523		var->transp.length = 8;
    524		fallthrough;
    525	case 24:
    526		var->red.offset = 16;
    527		var->green.offset = 8;
    528		var->blue.offset = 0;
    529		var->red.length = var->green.length = var->blue.length = 8;
    530		break;
    531	}
    532	var->width = -1;
    533	var->height = -1;
    534
    535	var->accel_flags = FB_ACCELF_TEXT;
    536
    537	DPRINTK("Checking graphics mode at %dx%d depth %d\n",
    538		var->xres, var->yres, var->bits_per_pixel);
    539	return 0;
    540}
    541
    542static int tdfxfb_set_par(struct fb_info *info)
    543{
    544	struct tdfx_par *par = info->par;
    545	u32 hdispend = info->var.xres;
    546	u32 hsyncsta = hdispend + info->var.right_margin;
    547	u32 hsyncend = hsyncsta + info->var.hsync_len;
    548	u32 htotal   = hsyncend + info->var.left_margin;
    549	u32 hd, hs, he, ht, hbs, hbe;
    550	u32 vd, vs, ve, vt, vbs, vbe;
    551	struct banshee_reg reg;
    552	int fout, freq;
    553	u32 wd;
    554	u32 cpp = (info->var.bits_per_pixel + 7) >> 3;
    555
    556	memset(&reg, 0, sizeof(reg));
    557
    558	reg.vidcfg = VIDCFG_VIDPROC_ENABLE | VIDCFG_DESK_ENABLE |
    559		     VIDCFG_CURS_X11 |
    560		     ((cpp - 1) << VIDCFG_PIXFMT_SHIFT) |
    561		     (cpp != 1 ? VIDCFG_CLUT_BYPASS : 0);
    562
    563	/* PLL settings */
    564	freq = PICOS2KHZ(info->var.pixclock);
    565
    566	reg.vidcfg &= ~VIDCFG_2X;
    567
    568	if (freq > par->max_pixclock / 2) {
    569		freq = freq > par->max_pixclock ? par->max_pixclock : freq;
    570		reg.dacmode |= DACMODE_2X;
    571		reg.vidcfg  |= VIDCFG_2X;
    572		hdispend >>= 1;
    573		hsyncsta >>= 1;
    574		hsyncend >>= 1;
    575		htotal   >>= 1;
    576	}
    577
    578	wd = (hdispend >> 3) - 1;
    579	hd  = wd;
    580	hs  = (hsyncsta >> 3) - 1;
    581	he  = (hsyncend >> 3) - 1;
    582	ht  = (htotal >> 3) - 1;
    583	hbs = hd;
    584	hbe = ht;
    585
    586	if ((info->var.vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
    587		vd = (info->var.yres << 1) - 1;
    588		vs  = vd + (info->var.lower_margin << 1);
    589		ve  = vs + (info->var.vsync_len << 1);
    590		vt = ve + (info->var.upper_margin << 1) - 1;
    591		reg.screensize = info->var.xres | (info->var.yres << 13);
    592		reg.vidcfg |= VIDCFG_HALF_MODE;
    593		reg.crt[0x09] = 0x80;
    594	} else {
    595		vd = info->var.yres - 1;
    596		vs  = vd + info->var.lower_margin;
    597		ve  = vs + info->var.vsync_len;
    598		vt = ve + info->var.upper_margin - 1;
    599		reg.screensize = info->var.xres | (info->var.yres << 12);
    600		reg.vidcfg &= ~VIDCFG_HALF_MODE;
    601	}
    602	vbs = vd;
    603	vbe = vt;
    604
    605	/* this is all pretty standard VGA register stuffing */
    606	reg.misc[0x00] = 0x0f |
    607			(info->var.xres < 400 ? 0xa0 :
    608			 info->var.xres < 480 ? 0x60 :
    609			 info->var.xres < 768 ? 0xe0 : 0x20);
    610
    611	reg.gra[0x05] = 0x40;
    612	reg.gra[0x06] = 0x05;
    613	reg.gra[0x07] = 0x0f;
    614	reg.gra[0x08] = 0xff;
    615
    616	reg.att[0x00] = 0x00;
    617	reg.att[0x01] = 0x01;
    618	reg.att[0x02] = 0x02;
    619	reg.att[0x03] = 0x03;
    620	reg.att[0x04] = 0x04;
    621	reg.att[0x05] = 0x05;
    622	reg.att[0x06] = 0x06;
    623	reg.att[0x07] = 0x07;
    624	reg.att[0x08] = 0x08;
    625	reg.att[0x09] = 0x09;
    626	reg.att[0x0a] = 0x0a;
    627	reg.att[0x0b] = 0x0b;
    628	reg.att[0x0c] = 0x0c;
    629	reg.att[0x0d] = 0x0d;
    630	reg.att[0x0e] = 0x0e;
    631	reg.att[0x0f] = 0x0f;
    632	reg.att[0x10] = 0x41;
    633	reg.att[0x12] = 0x0f;
    634
    635	reg.seq[0x00] = 0x03;
    636	reg.seq[0x01] = 0x01; /* fixme: clkdiv2? */
    637	reg.seq[0x02] = 0x0f;
    638	reg.seq[0x03] = 0x00;
    639	reg.seq[0x04] = 0x0e;
    640
    641	reg.crt[0x00] = ht - 4;
    642	reg.crt[0x01] = hd;
    643	reg.crt[0x02] = hbs;
    644	reg.crt[0x03] = 0x80 | (hbe & 0x1f);
    645	reg.crt[0x04] = hs;
    646	reg.crt[0x05] = ((hbe & 0x20) << 2) | (he & 0x1f);
    647	reg.crt[0x06] = vt;
    648	reg.crt[0x07] = ((vs & 0x200) >> 2) |
    649			((vd & 0x200) >> 3) |
    650			((vt & 0x200) >> 4) | 0x10 |
    651			((vbs & 0x100) >> 5) |
    652			((vs & 0x100) >> 6) |
    653			((vd & 0x100) >> 7) |
    654			((vt & 0x100) >> 8);
    655	reg.crt[0x09] |= 0x40 | ((vbs & 0x200) >> 4);
    656	reg.crt[0x10] = vs;
    657	reg.crt[0x11] = (ve & 0x0f) | 0x20;
    658	reg.crt[0x12] = vd;
    659	reg.crt[0x13] = wd;
    660	reg.crt[0x15] = vbs;
    661	reg.crt[0x16] = vbe + 1;
    662	reg.crt[0x17] = 0xc3;
    663	reg.crt[0x18] = 0xff;
    664
    665	/* Banshee's nonvga stuff */
    666	reg.ext[0x00] = (((ht & 0x100) >> 8) |
    667			((hd & 0x100) >> 6) |
    668			((hbs & 0x100) >> 4) |
    669			((hbe & 0x40) >> 1) |
    670			((hs & 0x100) >> 2) |
    671			((he & 0x20) << 2));
    672	reg.ext[0x01] = (((vt & 0x400) >> 10) |
    673			((vd & 0x400) >> 8) |
    674			((vbs & 0x400) >> 6) |
    675			((vbe & 0x400) >> 4));
    676
    677	reg.vgainit0 =	VGAINIT0_8BIT_DAC     |
    678			VGAINIT0_EXT_ENABLE   |
    679			VGAINIT0_WAKEUP_3C3   |
    680			VGAINIT0_ALT_READBACK |
    681			VGAINIT0_EXTSHIFTOUT;
    682	reg.vgainit1 = tdfx_inl(par, VGAINIT1) & 0x1fffff;
    683
    684	if (hwcursor)
    685		reg.curspataddr = info->fix.smem_len;
    686
    687	reg.cursloc   = 0;
    688
    689	reg.cursc0    = 0;
    690	reg.cursc1    = 0xffffff;
    691
    692	reg.stride    = info->var.xres * cpp;
    693	reg.startaddr = info->var.yoffset * reg.stride
    694			+ info->var.xoffset * cpp;
    695
    696	reg.vidpll = do_calc_pll(freq, &fout);
    697#if 0
    698	reg.mempll = do_calc_pll(..., &fout);
    699	reg.gfxpll = do_calc_pll(..., &fout);
    700#endif
    701
    702	if ((info->var.vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED)
    703		reg.vidcfg |= VIDCFG_INTERLACE;
    704	reg.miscinit0 = tdfx_inl(par, MISCINIT0);
    705
    706#if defined(__BIG_ENDIAN)
    707	switch (info->var.bits_per_pixel) {
    708	case 8:
    709	case 24:
    710		reg.miscinit0 &= ~(1 << 30);
    711		reg.miscinit0 &= ~(1 << 31);
    712		break;
    713	case 16:
    714		reg.miscinit0 |= (1 << 30);
    715		reg.miscinit0 |= (1 << 31);
    716		break;
    717	case 32:
    718		reg.miscinit0 |= (1 << 30);
    719		reg.miscinit0 &= ~(1 << 31);
    720		break;
    721	}
    722#endif
    723	do_write_regs(info, &reg);
    724
    725	/* Now change fb_fix_screeninfo according to changes in par */
    726	info->fix.line_length = reg.stride;
    727	info->fix.visual = (info->var.bits_per_pixel == 8)
    728				? FB_VISUAL_PSEUDOCOLOR
    729				: FB_VISUAL_TRUECOLOR;
    730	DPRINTK("Graphics mode is now set at %dx%d depth %d\n",
    731		info->var.xres, info->var.yres, info->var.bits_per_pixel);
    732	return 0;
    733}
    734
    735/* A handy macro shamelessly pinched from matroxfb */
    736#define CNVT_TOHW(val, width) ((((val) << (width)) + 0x7FFF - (val)) >> 16)
    737
    738static int tdfxfb_setcolreg(unsigned regno, unsigned red, unsigned green,
    739			    unsigned blue, unsigned transp,
    740			    struct fb_info *info)
    741{
    742	struct tdfx_par *par = info->par;
    743	u32 rgbcol;
    744
    745	if (regno >= info->cmap.len || regno > 255)
    746		return 1;
    747
    748	/* grayscale works only partially under directcolor */
    749	if (info->var.grayscale) {
    750		/* grayscale = 0.30*R + 0.59*G + 0.11*B */
    751		blue = (red * 77 + green * 151 + blue * 28) >> 8;
    752		green = blue;
    753		red = blue;
    754	}
    755
    756	switch (info->fix.visual) {
    757	case FB_VISUAL_PSEUDOCOLOR:
    758		rgbcol = (((u32)red   & 0xff00) << 8) |
    759			 (((u32)green & 0xff00) << 0) |
    760			 (((u32)blue  & 0xff00) >> 8);
    761		do_setpalentry(par, regno, rgbcol);
    762		break;
    763	/* Truecolor has no hardware color palettes. */
    764	case FB_VISUAL_TRUECOLOR:
    765		if (regno < 16) {
    766			rgbcol = (CNVT_TOHW(red, info->var.red.length) <<
    767				  info->var.red.offset) |
    768				(CNVT_TOHW(green, info->var.green.length) <<
    769				 info->var.green.offset) |
    770				(CNVT_TOHW(blue, info->var.blue.length) <<
    771				 info->var.blue.offset) |
    772				(CNVT_TOHW(transp, info->var.transp.length) <<
    773				 info->var.transp.offset);
    774			par->palette[regno] = rgbcol;
    775		}
    776
    777		break;
    778	default:
    779		DPRINTK("bad depth %u\n", info->var.bits_per_pixel);
    780		break;
    781	}
    782
    783	return 0;
    784}
    785
    786/* 0 unblank, 1 blank, 2 no vsync, 3 no hsync, 4 off */
    787static int tdfxfb_blank(int blank, struct fb_info *info)
    788{
    789	struct tdfx_par *par = info->par;
    790	int vgablank = 1;
    791	u32 dacmode = tdfx_inl(par, DACMODE);
    792
    793	dacmode &= ~(BIT(1) | BIT(3));
    794
    795	switch (blank) {
    796	case FB_BLANK_UNBLANK: /* Screen: On; HSync: On, VSync: On */
    797		vgablank = 0;
    798		break;
    799	case FB_BLANK_NORMAL: /* Screen: Off; HSync: On, VSync: On */
    800		break;
    801	case FB_BLANK_VSYNC_SUSPEND: /* Screen: Off; HSync: On, VSync: Off */
    802		dacmode |= BIT(3);
    803		break;
    804	case FB_BLANK_HSYNC_SUSPEND: /* Screen: Off; HSync: Off, VSync: On */
    805		dacmode |= BIT(1);
    806		break;
    807	case FB_BLANK_POWERDOWN: /* Screen: Off; HSync: Off, VSync: Off */
    808		dacmode |= BIT(1) | BIT(3);
    809		break;
    810	}
    811
    812	banshee_make_room(par, 1);
    813	tdfx_outl(par, DACMODE, dacmode);
    814	if (vgablank)
    815		vga_disable_video(par);
    816	else
    817		vga_enable_video(par);
    818	return 0;
    819}
    820
    821/*
    822 * Set the starting position of the visible screen to var->yoffset
    823 */
    824static int tdfxfb_pan_display(struct fb_var_screeninfo *var,
    825			      struct fb_info *info)
    826{
    827	struct tdfx_par *par = info->par;
    828	u32 addr = var->yoffset * info->fix.line_length;
    829
    830	if (nopan || var->xoffset)
    831		return -EINVAL;
    832
    833	banshee_make_room(par, 1);
    834	tdfx_outl(par, VIDDESKSTART, addr);
    835
    836	return 0;
    837}
    838
    839#ifdef CONFIG_FB_3DFX_ACCEL
    840/*
    841 * FillRect 2D command (solidfill or invert (via ROP_XOR))
    842 */
    843static void tdfxfb_fillrect(struct fb_info *info,
    844			    const struct fb_fillrect *rect)
    845{
    846	struct tdfx_par *par = info->par;
    847	u32 bpp = info->var.bits_per_pixel;
    848	u32 stride = info->fix.line_length;
    849	u32 fmt = stride | ((bpp + ((bpp == 8) ? 0 : 8)) << 13);
    850	int tdfx_rop;
    851	u32 dx = rect->dx;
    852	u32 dy = rect->dy;
    853	u32 dstbase = 0;
    854
    855	if (rect->rop == ROP_COPY)
    856		tdfx_rop = TDFX_ROP_COPY;
    857	else
    858		tdfx_rop = TDFX_ROP_XOR;
    859
    860	/* assume always rect->height < 4096 */
    861	if (dy + rect->height > 4095) {
    862		dstbase = stride * dy;
    863		dy = 0;
    864	}
    865	/* assume always rect->width < 4096 */
    866	if (dx + rect->width > 4095) {
    867		dstbase += dx * bpp >> 3;
    868		dx = 0;
    869	}
    870	banshee_make_room(par, 6);
    871	tdfx_outl(par, DSTFORMAT, fmt);
    872	if (info->fix.visual == FB_VISUAL_PSEUDOCOLOR) {
    873		tdfx_outl(par, COLORFORE, rect->color);
    874	} else { /* FB_VISUAL_TRUECOLOR */
    875		tdfx_outl(par, COLORFORE, par->palette[rect->color]);
    876	}
    877	tdfx_outl(par, COMMAND_2D, COMMAND_2D_FILLRECT | (tdfx_rop << 24));
    878	tdfx_outl(par, DSTBASE, dstbase);
    879	tdfx_outl(par, DSTSIZE, rect->width | (rect->height << 16));
    880	tdfx_outl(par, LAUNCH_2D, dx | (dy << 16));
    881}
    882
    883/*
    884 * Screen-to-Screen BitBlt 2D command (for the bmove fb op.)
    885 */
    886static void tdfxfb_copyarea(struct fb_info *info,
    887			    const struct fb_copyarea *area)
    888{
    889	struct tdfx_par *par = info->par;
    890	u32 sx = area->sx, sy = area->sy, dx = area->dx, dy = area->dy;
    891	u32 bpp = info->var.bits_per_pixel;
    892	u32 stride = info->fix.line_length;
    893	u32 blitcmd = COMMAND_2D_S2S_BITBLT | (TDFX_ROP_COPY << 24);
    894	u32 fmt = stride | ((bpp + ((bpp == 8) ? 0 : 8)) << 13);
    895	u32 dstbase = 0;
    896	u32 srcbase = 0;
    897
    898	/* assume always area->height < 4096 */
    899	if (sy + area->height > 4095) {
    900		srcbase = stride * sy;
    901		sy = 0;
    902	}
    903	/* assume always area->width < 4096 */
    904	if (sx + area->width > 4095) {
    905		srcbase += sx * bpp >> 3;
    906		sx = 0;
    907	}
    908	/* assume always area->height < 4096 */
    909	if (dy + area->height > 4095) {
    910		dstbase = stride * dy;
    911		dy = 0;
    912	}
    913	/* assume always area->width < 4096 */
    914	if (dx + area->width > 4095) {
    915		dstbase += dx * bpp >> 3;
    916		dx = 0;
    917	}
    918
    919	if (area->sx <= area->dx) {
    920		/* -X */
    921		blitcmd |= BIT(14);
    922		sx += area->width - 1;
    923		dx += area->width - 1;
    924	}
    925	if (area->sy <= area->dy) {
    926		/* -Y */
    927		blitcmd |= BIT(15);
    928		sy += area->height - 1;
    929		dy += area->height - 1;
    930	}
    931
    932	banshee_make_room(par, 8);
    933
    934	tdfx_outl(par, SRCFORMAT, fmt);
    935	tdfx_outl(par, DSTFORMAT, fmt);
    936	tdfx_outl(par, COMMAND_2D, blitcmd);
    937	tdfx_outl(par, DSTSIZE, area->width | (area->height << 16));
    938	tdfx_outl(par, DSTXY, dx | (dy << 16));
    939	tdfx_outl(par, SRCBASE, srcbase);
    940	tdfx_outl(par, DSTBASE, dstbase);
    941	tdfx_outl(par, LAUNCH_2D, sx | (sy << 16));
    942}
    943
    944static void tdfxfb_imageblit(struct fb_info *info, const struct fb_image *image)
    945{
    946	struct tdfx_par *par = info->par;
    947	int size = image->height * ((image->width * image->depth + 7) >> 3);
    948	int fifo_free;
    949	int i, stride = info->fix.line_length;
    950	u32 bpp = info->var.bits_per_pixel;
    951	u32 dstfmt = stride | ((bpp + ((bpp == 8) ? 0 : 8)) << 13);
    952	u8 *chardata = (u8 *) image->data;
    953	u32 srcfmt;
    954	u32 dx = image->dx;
    955	u32 dy = image->dy;
    956	u32 dstbase = 0;
    957
    958	if (image->depth != 1) {
    959#ifdef BROKEN_CODE
    960		banshee_make_room(par, 6 + ((size + 3) >> 2));
    961		srcfmt = stride | ((bpp + ((bpp == 8) ? 0 : 8)) << 13) |
    962			0x400000;
    963#else
    964		cfb_imageblit(info, image);
    965#endif
    966		return;
    967	}
    968	banshee_make_room(par, 9);
    969	switch (info->fix.visual) {
    970	case FB_VISUAL_PSEUDOCOLOR:
    971		tdfx_outl(par, COLORFORE, image->fg_color);
    972		tdfx_outl(par, COLORBACK, image->bg_color);
    973		break;
    974	case FB_VISUAL_TRUECOLOR:
    975	default:
    976		tdfx_outl(par, COLORFORE,
    977			  par->palette[image->fg_color]);
    978		tdfx_outl(par, COLORBACK,
    979			  par->palette[image->bg_color]);
    980	}
    981#ifdef __BIG_ENDIAN
    982	srcfmt = 0x400000 | BIT(20);
    983#else
    984	srcfmt = 0x400000;
    985#endif
    986	/* assume always image->height < 4096 */
    987	if (dy + image->height > 4095) {
    988		dstbase = stride * dy;
    989		dy = 0;
    990	}
    991	/* assume always image->width < 4096 */
    992	if (dx + image->width > 4095) {
    993		dstbase += dx * bpp >> 3;
    994		dx = 0;
    995	}
    996
    997	tdfx_outl(par, DSTBASE, dstbase);
    998	tdfx_outl(par, SRCXY, 0);
    999	tdfx_outl(par, DSTXY, dx | (dy << 16));
   1000	tdfx_outl(par, COMMAND_2D,
   1001		  COMMAND_2D_H2S_BITBLT | (TDFX_ROP_COPY << 24));
   1002	tdfx_outl(par, SRCFORMAT, srcfmt);
   1003	tdfx_outl(par, DSTFORMAT, dstfmt);
   1004	tdfx_outl(par, DSTSIZE, image->width | (image->height << 16));
   1005
   1006	/* A count of how many free FIFO entries we've requested.
   1007	 * When this goes negative, we need to request more. */
   1008	fifo_free = 0;
   1009
   1010	/* Send four bytes at a time of data */
   1011	for (i = (size >> 2); i > 0; i--) {
   1012		if (--fifo_free < 0) {
   1013			fifo_free = 31;
   1014			banshee_make_room(par, fifo_free);
   1015		}
   1016		tdfx_outl(par, LAUNCH_2D, *(u32 *)chardata);
   1017		chardata += 4;
   1018	}
   1019
   1020	/* Send the leftovers now */
   1021	banshee_make_room(par, 3);
   1022	switch (size % 4) {
   1023	case 0:
   1024		break;
   1025	case 1:
   1026		tdfx_outl(par, LAUNCH_2D, *chardata);
   1027		break;
   1028	case 2:
   1029		tdfx_outl(par, LAUNCH_2D, *(u16 *)chardata);
   1030		break;
   1031	case 3:
   1032		tdfx_outl(par, LAUNCH_2D,
   1033			*(u16 *)chardata | (chardata[3] << 24));
   1034		break;
   1035	}
   1036}
   1037#endif /* CONFIG_FB_3DFX_ACCEL */
   1038
   1039static int tdfxfb_cursor(struct fb_info *info, struct fb_cursor *cursor)
   1040{
   1041	struct tdfx_par *par = info->par;
   1042	u32 vidcfg;
   1043
   1044	if (!hwcursor)
   1045		return -EINVAL;	/* just to force soft_cursor() call */
   1046
   1047	/* Too large of a cursor or wrong bpp :-( */
   1048	if (cursor->image.width > 64 ||
   1049	    cursor->image.height > 64 ||
   1050	    cursor->image.depth > 1)
   1051		return -EINVAL;
   1052
   1053	vidcfg = tdfx_inl(par, VIDPROCCFG);
   1054	if (cursor->enable)
   1055		tdfx_outl(par, VIDPROCCFG, vidcfg | VIDCFG_HWCURSOR_ENABLE);
   1056	else
   1057		tdfx_outl(par, VIDPROCCFG, vidcfg & ~VIDCFG_HWCURSOR_ENABLE);
   1058
   1059	/*
   1060	 * If the cursor is not be changed this means either we want the
   1061	 * current cursor state (if enable is set) or we want to query what
   1062	 * we can do with the cursor (if enable is not set)
   1063	 */
   1064	if (!cursor->set)
   1065		return 0;
   1066
   1067	/* fix cursor color - XFree86 forgets to restore it properly */
   1068	if (cursor->set & FB_CUR_SETCMAP) {
   1069		struct fb_cmap cmap = info->cmap;
   1070		u32 bg_idx = cursor->image.bg_color;
   1071		u32 fg_idx = cursor->image.fg_color;
   1072		unsigned long bg_color, fg_color;
   1073
   1074		fg_color = (((u32)cmap.red[fg_idx]   & 0xff00) << 8) |
   1075			   (((u32)cmap.green[fg_idx] & 0xff00) << 0) |
   1076			   (((u32)cmap.blue[fg_idx]  & 0xff00) >> 8);
   1077		bg_color = (((u32)cmap.red[bg_idx]   & 0xff00) << 8) |
   1078			   (((u32)cmap.green[bg_idx] & 0xff00) << 0) |
   1079			   (((u32)cmap.blue[bg_idx]  & 0xff00) >> 8);
   1080		banshee_make_room(par, 2);
   1081		tdfx_outl(par, HWCURC0, bg_color);
   1082		tdfx_outl(par, HWCURC1, fg_color);
   1083	}
   1084
   1085	if (cursor->set & FB_CUR_SETPOS) {
   1086		int x = cursor->image.dx;
   1087		int y = cursor->image.dy - info->var.yoffset;
   1088
   1089		x += 63;
   1090		y += 63;
   1091		banshee_make_room(par, 1);
   1092		tdfx_outl(par, HWCURLOC, (y << 16) + x);
   1093	}
   1094	if (cursor->set & (FB_CUR_SETIMAGE | FB_CUR_SETSHAPE)) {
   1095		/*
   1096		 * Voodoo 3 and above cards use 2 monochrome cursor patterns.
   1097		 *    The reason is so the card can fetch 8 words at a time
   1098		 * and are stored on chip for use for the next 8 scanlines.
   1099		 * This reduces the number of times for access to draw the
   1100		 * cursor for each screen refresh.
   1101		 *    Each pattern is a bitmap of 64 bit wide and 64 bit high
   1102		 * (total of 8192 bits or 1024 bytes). The two patterns are
   1103		 * stored in such a way that pattern 0 always resides in the
   1104		 * lower half (least significant 64 bits) of a 128 bit word
   1105		 * and pattern 1 the upper half. If you examine the data of
   1106		 * the cursor image the graphics card uses then from the
   1107		 * beginning you see line one of pattern 0, line one of
   1108		 * pattern 1, line two of pattern 0, line two of pattern 1,
   1109		 * etc etc. The linear stride for the cursor is always 16 bytes
   1110		 * (128 bits) which is the maximum cursor width times two for
   1111		 * the two monochrome patterns.
   1112		 */
   1113		u8 __iomem *cursorbase = info->screen_base + info->fix.smem_len;
   1114		u8 *bitmap = (u8 *)cursor->image.data;
   1115		u8 *mask = (u8 *)cursor->mask;
   1116		int i;
   1117
   1118		fb_memset(cursorbase, 0, 1024);
   1119
   1120		for (i = 0; i < cursor->image.height; i++) {
   1121			int h = 0;
   1122			int j = (cursor->image.width + 7) >> 3;
   1123
   1124			for (; j > 0; j--) {
   1125				u8 data = *mask ^ *bitmap;
   1126				if (cursor->rop == ROP_COPY)
   1127					data = *mask & *bitmap;
   1128				/* Pattern 0. Copy the cursor mask to it */
   1129				fb_writeb(*mask, cursorbase + h);
   1130				mask++;
   1131				/* Pattern 1. Copy the cursor bitmap to it */
   1132				fb_writeb(data, cursorbase + h + 8);
   1133				bitmap++;
   1134				h++;
   1135			}
   1136			cursorbase += 16;
   1137		}
   1138	}
   1139	return 0;
   1140}
   1141
   1142static const struct fb_ops tdfxfb_ops = {
   1143	.owner		= THIS_MODULE,
   1144	.fb_check_var	= tdfxfb_check_var,
   1145	.fb_set_par	= tdfxfb_set_par,
   1146	.fb_setcolreg	= tdfxfb_setcolreg,
   1147	.fb_blank	= tdfxfb_blank,
   1148	.fb_pan_display	= tdfxfb_pan_display,
   1149	.fb_sync	= banshee_wait_idle,
   1150	.fb_cursor	= tdfxfb_cursor,
   1151#ifdef CONFIG_FB_3DFX_ACCEL
   1152	.fb_fillrect	= tdfxfb_fillrect,
   1153	.fb_copyarea	= tdfxfb_copyarea,
   1154	.fb_imageblit	= tdfxfb_imageblit,
   1155#else
   1156	.fb_fillrect	= cfb_fillrect,
   1157	.fb_copyarea	= cfb_copyarea,
   1158	.fb_imageblit	= cfb_imageblit,
   1159#endif
   1160};
   1161
   1162#ifdef CONFIG_FB_3DFX_I2C
   1163/* The voo GPIO registers don't have individual masks for each bit
   1164   so we always have to read before writing. */
   1165
   1166static void tdfxfb_i2c_setscl(void *data, int val)
   1167{
   1168	struct tdfxfb_i2c_chan 	*chan = data;
   1169	struct tdfx_par 	*par = chan->par;
   1170	unsigned int r;
   1171
   1172	r = tdfx_inl(par, VIDSERPARPORT);
   1173	if (val)
   1174		r |= I2C_SCL_OUT;
   1175	else
   1176		r &= ~I2C_SCL_OUT;
   1177	tdfx_outl(par, VIDSERPARPORT, r);
   1178	tdfx_inl(par, VIDSERPARPORT);	/* flush posted write */
   1179}
   1180
   1181static void tdfxfb_i2c_setsda(void *data, int val)
   1182{
   1183	struct tdfxfb_i2c_chan 	*chan = data;
   1184	struct tdfx_par 	*par = chan->par;
   1185	unsigned int r;
   1186
   1187	r = tdfx_inl(par, VIDSERPARPORT);
   1188	if (val)
   1189		r |= I2C_SDA_OUT;
   1190	else
   1191		r &= ~I2C_SDA_OUT;
   1192	tdfx_outl(par, VIDSERPARPORT, r);
   1193	tdfx_inl(par, VIDSERPARPORT);	/* flush posted write */
   1194}
   1195
   1196/* The GPIO pins are open drain, so the pins always remain outputs.
   1197   We rely on the i2c-algo-bit routines to set the pins high before
   1198   reading the input from other chips. */
   1199
   1200static int tdfxfb_i2c_getscl(void *data)
   1201{
   1202	struct tdfxfb_i2c_chan 	*chan = data;
   1203	struct tdfx_par 	*par = chan->par;
   1204
   1205	return (0 != (tdfx_inl(par, VIDSERPARPORT) & I2C_SCL_IN));
   1206}
   1207
   1208static int tdfxfb_i2c_getsda(void *data)
   1209{
   1210	struct tdfxfb_i2c_chan 	*chan = data;
   1211	struct tdfx_par 	*par = chan->par;
   1212
   1213	return (0 != (tdfx_inl(par, VIDSERPARPORT) & I2C_SDA_IN));
   1214}
   1215
   1216static void tdfxfb_ddc_setscl(void *data, int val)
   1217{
   1218	struct tdfxfb_i2c_chan 	*chan = data;
   1219	struct tdfx_par 	*par = chan->par;
   1220	unsigned int r;
   1221
   1222	r = tdfx_inl(par, VIDSERPARPORT);
   1223	if (val)
   1224		r |= DDC_SCL_OUT;
   1225	else
   1226		r &= ~DDC_SCL_OUT;
   1227	tdfx_outl(par, VIDSERPARPORT, r);
   1228	tdfx_inl(par, VIDSERPARPORT);	/* flush posted write */
   1229}
   1230
   1231static void tdfxfb_ddc_setsda(void *data, int val)
   1232{
   1233	struct tdfxfb_i2c_chan 	*chan = data;
   1234	struct tdfx_par 	*par = chan->par;
   1235	unsigned int r;
   1236
   1237	r = tdfx_inl(par, VIDSERPARPORT);
   1238	if (val)
   1239		r |= DDC_SDA_OUT;
   1240	else
   1241		r &= ~DDC_SDA_OUT;
   1242	tdfx_outl(par, VIDSERPARPORT, r);
   1243	tdfx_inl(par, VIDSERPARPORT);	/* flush posted write */
   1244}
   1245
   1246static int tdfxfb_ddc_getscl(void *data)
   1247{
   1248	struct tdfxfb_i2c_chan 	*chan = data;
   1249	struct tdfx_par 	*par = chan->par;
   1250
   1251	return (0 != (tdfx_inl(par, VIDSERPARPORT) & DDC_SCL_IN));
   1252}
   1253
   1254static int tdfxfb_ddc_getsda(void *data)
   1255{
   1256	struct tdfxfb_i2c_chan 	*chan = data;
   1257	struct tdfx_par 	*par = chan->par;
   1258
   1259	return (0 != (tdfx_inl(par, VIDSERPARPORT) & DDC_SDA_IN));
   1260}
   1261
   1262static int tdfxfb_setup_ddc_bus(struct tdfxfb_i2c_chan *chan, const char *name,
   1263				struct device *dev)
   1264{
   1265	int rc;
   1266
   1267	strlcpy(chan->adapter.name, name, sizeof(chan->adapter.name));
   1268	chan->adapter.owner		= THIS_MODULE;
   1269	chan->adapter.class		= I2C_CLASS_DDC;
   1270	chan->adapter.algo_data		= &chan->algo;
   1271	chan->adapter.dev.parent	= dev;
   1272	chan->algo.setsda		= tdfxfb_ddc_setsda;
   1273	chan->algo.setscl		= tdfxfb_ddc_setscl;
   1274	chan->algo.getsda		= tdfxfb_ddc_getsda;
   1275	chan->algo.getscl		= tdfxfb_ddc_getscl;
   1276	chan->algo.udelay		= 10;
   1277	chan->algo.timeout		= msecs_to_jiffies(500);
   1278	chan->algo.data 		= chan;
   1279
   1280	i2c_set_adapdata(&chan->adapter, chan);
   1281
   1282	rc = i2c_bit_add_bus(&chan->adapter);
   1283	if (rc == 0)
   1284		DPRINTK("I2C bus %s registered.\n", name);
   1285	else
   1286		chan->par = NULL;
   1287
   1288	return rc;
   1289}
   1290
   1291static int tdfxfb_setup_i2c_bus(struct tdfxfb_i2c_chan *chan, const char *name,
   1292				struct device *dev)
   1293{
   1294	int rc;
   1295
   1296	strlcpy(chan->adapter.name, name, sizeof(chan->adapter.name));
   1297	chan->adapter.owner		= THIS_MODULE;
   1298	chan->adapter.algo_data		= &chan->algo;
   1299	chan->adapter.dev.parent	= dev;
   1300	chan->algo.setsda		= tdfxfb_i2c_setsda;
   1301	chan->algo.setscl		= tdfxfb_i2c_setscl;
   1302	chan->algo.getsda		= tdfxfb_i2c_getsda;
   1303	chan->algo.getscl		= tdfxfb_i2c_getscl;
   1304	chan->algo.udelay		= 10;
   1305	chan->algo.timeout		= msecs_to_jiffies(500);
   1306	chan->algo.data 		= chan;
   1307
   1308	i2c_set_adapdata(&chan->adapter, chan);
   1309
   1310	rc = i2c_bit_add_bus(&chan->adapter);
   1311	if (rc == 0)
   1312		DPRINTK("I2C bus %s registered.\n", name);
   1313	else
   1314		chan->par = NULL;
   1315
   1316	return rc;
   1317}
   1318
   1319static void tdfxfb_create_i2c_busses(struct fb_info *info)
   1320{
   1321	struct tdfx_par *par = info->par;
   1322
   1323	tdfx_outl(par, VIDINFORMAT, 0x8160);
   1324	tdfx_outl(par, VIDSERPARPORT, 0xcffc0020);
   1325
   1326	par->chan[0].par = par;
   1327	par->chan[1].par = par;
   1328
   1329	tdfxfb_setup_ddc_bus(&par->chan[0], "Voodoo3-DDC", info->dev);
   1330	tdfxfb_setup_i2c_bus(&par->chan[1], "Voodoo3-I2C", info->dev);
   1331}
   1332
   1333static void tdfxfb_delete_i2c_busses(struct tdfx_par *par)
   1334{
   1335	if (par->chan[0].par)
   1336		i2c_del_adapter(&par->chan[0].adapter);
   1337	par->chan[0].par = NULL;
   1338
   1339	if (par->chan[1].par)
   1340		i2c_del_adapter(&par->chan[1].adapter);
   1341	par->chan[1].par = NULL;
   1342}
   1343
   1344static int tdfxfb_probe_i2c_connector(struct tdfx_par *par,
   1345				      struct fb_monspecs *specs)
   1346{
   1347	u8 *edid = NULL;
   1348
   1349	DPRINTK("Probe DDC Bus\n");
   1350	if (par->chan[0].par)
   1351		edid = fb_ddc_read(&par->chan[0].adapter);
   1352
   1353	if (edid) {
   1354		fb_edid_to_monspecs(edid, specs);
   1355		kfree(edid);
   1356		return 0;
   1357	}
   1358	return 1;
   1359}
   1360#endif /* CONFIG_FB_3DFX_I2C */
   1361
   1362/**
   1363 *      tdfxfb_probe - Device Initializiation
   1364 *
   1365 *      @pdev:  PCI Device to initialize
   1366 *      @id:    PCI Device ID
   1367 *
   1368 *      Initializes and allocates resources for PCI device @pdev.
   1369 *
   1370 */
   1371static int tdfxfb_probe(struct pci_dev *pdev, const struct pci_device_id *id)
   1372{
   1373	struct tdfx_par *default_par;
   1374	struct fb_info *info;
   1375	int err, lpitch;
   1376	struct fb_monspecs *specs;
   1377	bool found;
   1378
   1379	err = pci_enable_device(pdev);
   1380	if (err) {
   1381		printk(KERN_ERR "tdfxfb: Can't enable pdev: %d\n", err);
   1382		return err;
   1383	}
   1384
   1385	info = framebuffer_alloc(sizeof(struct tdfx_par), &pdev->dev);
   1386
   1387	if (!info)
   1388		return -ENOMEM;
   1389
   1390	default_par = info->par;
   1391	info->fix = tdfx_fix;
   1392
   1393	/* Configure the default fb_fix_screeninfo first */
   1394	switch (pdev->device) {
   1395	case PCI_DEVICE_ID_3DFX_BANSHEE:
   1396		strcpy(info->fix.id, "3Dfx Banshee");
   1397		default_par->max_pixclock = BANSHEE_MAX_PIXCLOCK;
   1398		break;
   1399	case PCI_DEVICE_ID_3DFX_VOODOO3:
   1400		strcpy(info->fix.id, "3Dfx Voodoo3");
   1401		default_par->max_pixclock = VOODOO3_MAX_PIXCLOCK;
   1402		break;
   1403	case PCI_DEVICE_ID_3DFX_VOODOO5:
   1404		strcpy(info->fix.id, "3Dfx Voodoo5");
   1405		default_par->max_pixclock = VOODOO5_MAX_PIXCLOCK;
   1406		break;
   1407	}
   1408
   1409	info->fix.mmio_start = pci_resource_start(pdev, 0);
   1410	info->fix.mmio_len = pci_resource_len(pdev, 0);
   1411	if (!request_mem_region(info->fix.mmio_start, info->fix.mmio_len,
   1412				"tdfx regbase")) {
   1413		printk(KERN_ERR "tdfxfb: Can't reserve regbase\n");
   1414		goto out_err;
   1415	}
   1416
   1417	default_par->regbase_virt =
   1418		ioremap(info->fix.mmio_start, info->fix.mmio_len);
   1419	if (!default_par->regbase_virt) {
   1420		printk(KERN_ERR "fb: Can't remap %s register area.\n",
   1421				info->fix.id);
   1422		goto out_err_regbase;
   1423	}
   1424
   1425	info->fix.smem_start = pci_resource_start(pdev, 1);
   1426	info->fix.smem_len = do_lfb_size(default_par, pdev->device);
   1427	if (!info->fix.smem_len) {
   1428		printk(KERN_ERR "fb: Can't count %s memory.\n", info->fix.id);
   1429		goto out_err_regbase;
   1430	}
   1431
   1432	if (!request_mem_region(info->fix.smem_start,
   1433				pci_resource_len(pdev, 1), "tdfx smem")) {
   1434		printk(KERN_ERR "tdfxfb: Can't reserve smem\n");
   1435		goto out_err_regbase;
   1436	}
   1437
   1438	info->screen_base = ioremap_wc(info->fix.smem_start,
   1439				       info->fix.smem_len);
   1440	if (!info->screen_base) {
   1441		printk(KERN_ERR "fb: Can't remap %s framebuffer.\n",
   1442				info->fix.id);
   1443		goto out_err_screenbase;
   1444	}
   1445
   1446	default_par->iobase = pci_resource_start(pdev, 2);
   1447
   1448	if (!request_region(pci_resource_start(pdev, 2),
   1449			    pci_resource_len(pdev, 2), "tdfx iobase")) {
   1450		printk(KERN_ERR "tdfxfb: Can't reserve iobase\n");
   1451		goto out_err_screenbase;
   1452	}
   1453
   1454	printk(KERN_INFO "fb: %s memory = %dK\n", info->fix.id,
   1455			info->fix.smem_len >> 10);
   1456
   1457	if (!nomtrr)
   1458		default_par->wc_cookie= arch_phys_wc_add(info->fix.smem_start,
   1459							 info->fix.smem_len);
   1460
   1461	info->fix.ypanstep	= nopan ? 0 : 1;
   1462	info->fix.ywrapstep	= nowrap ? 0 : 1;
   1463
   1464	info->fbops		= &tdfxfb_ops;
   1465	info->pseudo_palette	= default_par->palette;
   1466	info->flags		= FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN;
   1467#ifdef CONFIG_FB_3DFX_ACCEL
   1468	info->flags		|= FBINFO_HWACCEL_FILLRECT |
   1469				   FBINFO_HWACCEL_COPYAREA |
   1470				   FBINFO_HWACCEL_IMAGEBLIT |
   1471				   FBINFO_READS_FAST;
   1472#endif
   1473	/* reserve 8192 bits for cursor */
   1474	/* the 2.4 driver says PAGE_MASK boundary is not enough for Voodoo4 */
   1475	if (hwcursor)
   1476		info->fix.smem_len = (info->fix.smem_len - 1024) &
   1477					(PAGE_MASK << 1);
   1478	specs = &info->monspecs;
   1479	found = false;
   1480	info->var.bits_per_pixel = 8;
   1481#ifdef CONFIG_FB_3DFX_I2C
   1482	tdfxfb_create_i2c_busses(info);
   1483	err = tdfxfb_probe_i2c_connector(default_par, specs);
   1484
   1485	if (!err) {
   1486		if (specs->modedb == NULL)
   1487			DPRINTK("Unable to get Mode Database\n");
   1488		else {
   1489			const struct fb_videomode *m;
   1490
   1491			fb_videomode_to_modelist(specs->modedb,
   1492						 specs->modedb_len,
   1493						 &info->modelist);
   1494			m = fb_find_best_display(specs, &info->modelist);
   1495			if (m) {
   1496				fb_videomode_to_var(&info->var, m);
   1497				/* fill all other info->var's fields */
   1498				if (tdfxfb_check_var(&info->var, info) < 0)
   1499					info->var = tdfx_var;
   1500				else
   1501					found = true;
   1502			}
   1503		}
   1504	}
   1505#endif
   1506	if (!mode_option && !found)
   1507		mode_option = "640x480@60";
   1508
   1509	if (mode_option) {
   1510		err = fb_find_mode(&info->var, info, mode_option,
   1511				   specs->modedb, specs->modedb_len,
   1512				   NULL, info->var.bits_per_pixel);
   1513		if (!err || err == 4)
   1514			info->var = tdfx_var;
   1515	}
   1516
   1517	if (found) {
   1518		fb_destroy_modedb(specs->modedb);
   1519		specs->modedb = NULL;
   1520	}
   1521
   1522	/* maximize virtual vertical length */
   1523	lpitch = info->var.xres_virtual * ((info->var.bits_per_pixel + 7) >> 3);
   1524	info->var.yres_virtual = info->fix.smem_len / lpitch;
   1525	if (info->var.yres_virtual < info->var.yres)
   1526		goto out_err_iobase;
   1527
   1528	if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) {
   1529		printk(KERN_ERR "tdfxfb: Can't allocate color map\n");
   1530		goto out_err_iobase;
   1531	}
   1532
   1533	if (register_framebuffer(info) < 0) {
   1534		printk(KERN_ERR "tdfxfb: can't register framebuffer\n");
   1535		fb_dealloc_cmap(&info->cmap);
   1536		goto out_err_iobase;
   1537	}
   1538	/*
   1539	 * Our driver data
   1540	 */
   1541	pci_set_drvdata(pdev, info);
   1542	return 0;
   1543
   1544out_err_iobase:
   1545#ifdef CONFIG_FB_3DFX_I2C
   1546	tdfxfb_delete_i2c_busses(default_par);
   1547#endif
   1548	arch_phys_wc_del(default_par->wc_cookie);
   1549	release_region(pci_resource_start(pdev, 2),
   1550		       pci_resource_len(pdev, 2));
   1551out_err_screenbase:
   1552	if (info->screen_base)
   1553		iounmap(info->screen_base);
   1554	release_mem_region(info->fix.smem_start, pci_resource_len(pdev, 1));
   1555out_err_regbase:
   1556	/*
   1557	 * Cleanup after anything that was remapped/allocated.
   1558	 */
   1559	if (default_par->regbase_virt)
   1560		iounmap(default_par->regbase_virt);
   1561	release_mem_region(info->fix.mmio_start, info->fix.mmio_len);
   1562out_err:
   1563	framebuffer_release(info);
   1564	return -ENXIO;
   1565}
   1566
   1567#ifndef MODULE
   1568static void __init tdfxfb_setup(char *options)
   1569{
   1570	char *this_opt;
   1571
   1572	if (!options || !*options)
   1573		return;
   1574
   1575	while ((this_opt = strsep(&options, ",")) != NULL) {
   1576		if (!*this_opt)
   1577			continue;
   1578		if (!strcmp(this_opt, "nopan")) {
   1579			nopan = 1;
   1580		} else if (!strcmp(this_opt, "nowrap")) {
   1581			nowrap = 1;
   1582		} else if (!strncmp(this_opt, "hwcursor=", 9)) {
   1583			hwcursor = simple_strtoul(this_opt + 9, NULL, 0);
   1584		} else if (!strncmp(this_opt, "nomtrr", 6)) {
   1585			nomtrr = 1;
   1586		} else {
   1587			mode_option = this_opt;
   1588		}
   1589	}
   1590}
   1591#endif
   1592
   1593/**
   1594 *      tdfxfb_remove - Device removal
   1595 *
   1596 *      @pdev:  PCI Device to cleanup
   1597 *
   1598 *      Releases all resources allocated during the course of the driver's
   1599 *      lifetime for the PCI device @pdev.
   1600 *
   1601 */
   1602static void tdfxfb_remove(struct pci_dev *pdev)
   1603{
   1604	struct fb_info *info = pci_get_drvdata(pdev);
   1605	struct tdfx_par *par = info->par;
   1606
   1607	unregister_framebuffer(info);
   1608#ifdef CONFIG_FB_3DFX_I2C
   1609	tdfxfb_delete_i2c_busses(par);
   1610#endif
   1611	arch_phys_wc_del(par->wc_cookie);
   1612	iounmap(par->regbase_virt);
   1613	iounmap(info->screen_base);
   1614
   1615	/* Clean up after reserved regions */
   1616	release_region(pci_resource_start(pdev, 2),
   1617		       pci_resource_len(pdev, 2));
   1618	release_mem_region(pci_resource_start(pdev, 1),
   1619			   pci_resource_len(pdev, 1));
   1620	release_mem_region(pci_resource_start(pdev, 0),
   1621			   pci_resource_len(pdev, 0));
   1622	fb_dealloc_cmap(&info->cmap);
   1623	framebuffer_release(info);
   1624}
   1625
   1626static int __init tdfxfb_init(void)
   1627{
   1628#ifndef MODULE
   1629	char *option = NULL;
   1630
   1631	if (fb_get_options("tdfxfb", &option))
   1632		return -ENODEV;
   1633
   1634	tdfxfb_setup(option);
   1635#endif
   1636	return pci_register_driver(&tdfxfb_driver);
   1637}
   1638
   1639static void __exit tdfxfb_exit(void)
   1640{
   1641	pci_unregister_driver(&tdfxfb_driver);
   1642}
   1643
   1644MODULE_AUTHOR("Hannu Mallat <hmallat@cc.hut.fi>");
   1645MODULE_DESCRIPTION("3Dfx framebuffer device driver");
   1646MODULE_LICENSE("GPL");
   1647
   1648module_param(hwcursor, int, 0644);
   1649MODULE_PARM_DESC(hwcursor, "Enable hardware cursor "
   1650			"(1=enable, 0=disable, default=1)");
   1651module_param(mode_option, charp, 0);
   1652MODULE_PARM_DESC(mode_option, "Initial video mode e.g. '648x480-8@60'");
   1653module_param(nomtrr, bool, 0);
   1654MODULE_PARM_DESC(nomtrr, "Disable MTRR support (default: enabled)");
   1655
   1656module_init(tdfxfb_init);
   1657module_exit(tdfxfb_exit);