66 #include <linux/module.h>
67 #include <linux/kernel.h>
68 #include <linux/errno.h>
69 #include <linux/string.h>
71 #include <linux/slab.h>
74 #include <linux/pci.h>
79 #define DPRINTK(a, b...) pr_debug("fb: %s: " a, __func__ , ## b)
85 #define MTRR_TYPE_WRCOMB 1
87 static inline int mtrr_add(
unsigned long base,
unsigned long size,
88 unsigned int type,
char increment)
92 static inline int mtrr_del(
int reg,
unsigned long base,
99 #define BANSHEE_MAX_PIXCLOCK 270000
100 #define VOODOO3_MAX_PIXCLOCK 300000
101 #define VOODOO5_MAX_PIXCLOCK 350000
116 .yres_virtual = 1024,
157 .id_table = tdfxfb_id_table,
158 .probe = tdfxfb_probe,
168 static int nowrap = 1;
169 static int hwcursor = 1;
178 static inline u8 vga_inb(
struct tdfx_par *par,
u32 reg)
180 return inb(par->iobase + reg - 0x300);
183 static inline void vga_outb(
struct tdfx_par *par,
u32 reg,
u8 val)
185 outb(val, par->iobase + reg - 0x300);
188 static inline void gra_outb(
struct tdfx_par *par,
u32 idx,
u8 val)
190 vga_outb(par,
GRA_I, idx);
192 vga_outb(par,
GRA_D, val);
196 static inline void seq_outb(
struct tdfx_par *par,
u32 idx,
u8 val)
198 vga_outb(par,
SEQ_I, idx);
200 vga_outb(par,
SEQ_D, val);
204 static inline u8 seq_inb(
struct tdfx_par *par,
u32 idx)
206 vga_outb(par,
SEQ_I, idx);
208 return vga_inb(par,
SEQ_D);
211 static inline void crt_outb(
struct tdfx_par *par,
u32 idx,
u8 val)
213 vga_outb(par,
CRT_I, idx);
215 vga_outb(par,
CRT_D, val);
219 static inline u8 crt_inb(
struct tdfx_par *par,
u32 idx)
221 vga_outb(par,
CRT_I, idx);
223 return vga_inb(par,
CRT_D);
226 static inline void att_outb(
struct tdfx_par *par,
u32 idx,
u8 val)
230 tmp = vga_inb(par,
IS1_R);
231 vga_outb(par,
ATT_IW, idx);
232 vga_outb(par,
ATT_IW, val);
235 static inline void vga_disable_video(
struct tdfx_par *par)
239 s = seq_inb(par, 0x01) | 0x20;
240 seq_outb(par, 0x00, 0x01);
241 seq_outb(par, 0x01, s);
242 seq_outb(par, 0x00, 0x03);
245 static inline void vga_enable_video(
struct tdfx_par *par)
249 s = seq_inb(par, 0x01) & 0xdf;
250 seq_outb(par, 0x00, 0x01);
251 seq_outb(par, 0x01, s);
252 seq_outb(par, 0x00, 0x03);
255 static inline void vga_enable_palette(
struct tdfx_par *par)
259 vga_outb(par,
ATT_IW, 0x20);
262 static inline u32 tdfx_inl(
struct tdfx_par *par,
unsigned int reg)
264 return readl(par->regbase_virt + reg);
267 static inline void tdfx_outl(
struct tdfx_par *par,
unsigned int reg,
u32 val)
269 writel(val, par->regbase_virt + reg);
272 static inline void banshee_make_room(
struct tdfx_par *par,
int size)
276 while ((tdfx_inl(par,
STATUS) & 0x1f) < size - 1)
282 struct tdfx_par *par = info->
par;
285 banshee_make_room(par, 1);
299 static inline void do_setpalentry(
struct tdfx_par *par,
unsigned regno,
u32 c)
301 banshee_make_room(par, 2);
302 tdfx_outl(par,
DACADDR, regno);
308 static u32 do_calc_pll(
int freq,
int *freq_out)
310 int m,
n,
k, best_m, best_n, best_k, best_error;
314 best_n = best_m = best_k = 0;
316 for (k = 3; k >= 0; k--) {
317 for (m = 63; m >= 0; m--) {
322 int n_estimated = ((freq * (m + 2) << k) / fref) - 2;
325 for (n =
max(0, n_estimated);
326 n <=
min(255, n_estimated + 1);
332 int f = (fref * (n + 2) / (m + 2)) >> k;
339 if (error < best_error) {
352 *freq_out = (fref * (n + 2) / (m + 2)) >> k;
354 return (n << 8) | (m << 2) | k;
357 static void do_write_regs(
struct fb_info *info,
struct banshee_reg *
reg)
359 struct tdfx_par *par = info->
par;
362 banshee_wait_idle(info);
366 crt_outb(par, 0x11, crt_inb(par, 0x11) & 0x7f);
368 banshee_make_room(par, 3);
369 tdfx_outl(par,
VGAINIT1, reg->vgainit1 & 0x001FFFFF);
370 tdfx_outl(par,
VIDPROCCFG, reg->vidcfg & ~0x00000001);
372 tdfx_outl(par,
PLLCTRL1, reg->mempll);
373 tdfx_outl(par,
PLLCTRL2, reg->gfxpll);
375 tdfx_outl(par,
PLLCTRL0, reg->vidpll);
377 vga_outb(par,
MISC_W, reg->misc[0x00] | 0x01);
379 for (i = 0; i < 5; i++)
380 seq_outb(par, i, reg->seq[i]);
382 for (i = 0; i < 25; i++)
383 crt_outb(par, i, reg->crt[i]);
385 for (i = 0; i < 9; i++)
386 gra_outb(par, i, reg->gra[i]);
388 for (i = 0; i < 21; i++)
389 att_outb(par, i, reg->att[i]);
391 crt_outb(par, 0x1a, reg->ext[0]);
392 crt_outb(par, 0x1b, reg->ext[1]);
394 vga_enable_palette(par);
395 vga_enable_video(par);
397 banshee_make_room(par, 9);
398 tdfx_outl(par,
VGAINIT0, reg->vgainit0);
399 tdfx_outl(par,
DACMODE, reg->dacmode);
406 tdfx_outl(par,
VGAINIT1, reg->vgainit1);
407 tdfx_outl(par,
MISCINIT0, reg->miscinit0);
409 banshee_make_room(par, 8);
410 tdfx_outl(par,
SRCBASE, reg->startaddr);
411 tdfx_outl(par,
DSTBASE, reg->startaddr);
414 tdfx_outl(par,
CLIP0MAX, 0x0fff0fff);
416 tdfx_outl(par,
CLIP1MAX, 0x0fff0fff);
417 tdfx_outl(par,
SRCXY, 0);
419 banshee_wait_idle(info);
422 static unsigned long do_lfb_size(
struct tdfx_par *par,
unsigned short dev_id)
448 banshee_make_room(par, 1);
450 return num_chips * chip_size * 1024
l * 1024;
457 struct tdfx_par *par = info->
par;
473 DPRINTK(
"xoffset not supported\n");
486 DPRINTK(
"interlace not supported\n");
492 DPRINTK(
"mode outside monitor's specs\n");
499 if (var->
xres < 320 || var->
xres > 2048) {
504 if (var->
yres < 200 || var->
yres > 2048) {
512 DPRINTK(
"no memory for screen (%ux%ux%u)\n",
520 DPRINTK(
"pixclock too high (%ldKHz)\n",
535 var->
red.offset = 11;
537 var->
green.offset = 5;
538 var->
green.length = 6;
539 var->
blue.offset = 0;
540 var->
blue.length = 5;
546 var->
red.offset = 16;
547 var->
green.offset = 8;
548 var->
blue.offset = 0;
549 var->
red.length = var->
green.length = var->
blue.length = 8;
557 DPRINTK(
"Checking graphics mode at %dx%d depth %d\n",
562 static int tdfxfb_set_par(
struct fb_info *info)
564 struct tdfx_par *par = info->
par;
565 u32 hdispend = info->
var.xres;
566 u32 hsyncsta = hdispend + info->
var.right_margin;
567 u32 hsyncend = hsyncsta + info->
var.hsync_len;
568 u32 htotal = hsyncend + info->
var.left_margin;
569 u32 hd, hs, he, ht, hbs, hbe;
570 u32 vd, vs, ve, vt, vbs, vbe;
571 struct banshee_reg reg;
574 u32 cpp = (info->
var.bits_per_pixel + 7) >> 3;
576 memset(®, 0,
sizeof(reg));
588 if (freq > par->max_pixclock / 2) {
589 freq = freq > par->max_pixclock ? par->max_pixclock :
freq;
598 wd = (hdispend >> 3) - 1;
600 hs = (hsyncsta >> 3) - 1;
601 he = (hsyncend >> 3) - 1;
602 ht = (htotal >> 3) - 1;
607 vd = (info->
var.yres << 1) - 1;
608 vs = vd + (info->
var.lower_margin << 1);
609 ve = vs + (info->
var.vsync_len << 1);
610 vt = ve + (info->
var.upper_margin << 1) - 1;
611 reg.screensize = info->
var.xres | (info->
var.yres << 13);
613 reg.crt[0x09] = 0x80;
615 vd = info->
var.yres - 1;
616 vs = vd + info->
var.lower_margin;
617 ve = vs + info->
var.vsync_len;
618 vt = ve + info->
var.upper_margin - 1;
619 reg.screensize = info->
var.xres | (info->
var.yres << 12);
626 reg.misc[0x00] = 0x0f |
627 (info->
var.xres < 400 ? 0xa0 :
628 info->
var.xres < 480 ? 0x60 :
629 info->
var.xres < 768 ? 0xe0 : 0x20);
631 reg.gra[0x05] = 0x40;
632 reg.gra[0x06] = 0x05;
633 reg.gra[0x07] = 0x0f;
634 reg.gra[0x08] = 0xff;
636 reg.att[0x00] = 0x00;
637 reg.att[0x01] = 0x01;
638 reg.att[0x02] = 0x02;
639 reg.att[0x03] = 0x03;
640 reg.att[0x04] = 0x04;
641 reg.att[0x05] = 0x05;
642 reg.att[0x06] = 0x06;
643 reg.att[0x07] = 0x07;
644 reg.att[0x08] = 0x08;
645 reg.att[0x09] = 0x09;
646 reg.att[0x0a] = 0x0a;
647 reg.att[0x0b] = 0x0b;
648 reg.att[0x0c] = 0x0c;
649 reg.att[0x0d] = 0x0d;
650 reg.att[0x0e] = 0x0e;
651 reg.att[0x0f] = 0x0f;
652 reg.att[0x10] = 0x41;
653 reg.att[0x12] = 0x0f;
655 reg.seq[0x00] = 0x03;
656 reg.seq[0x01] = 0x01;
657 reg.seq[0x02] = 0x0f;
658 reg.seq[0x03] = 0x00;
659 reg.seq[0x04] = 0x0e;
661 reg.crt[0x00] = ht - 4;
664 reg.crt[0x03] = 0x80 | (hbe & 0x1f);
666 reg.crt[0x05] = ((hbe & 0x20) << 2) | (he & 0x1f);
668 reg.crt[0x07] = ((vs & 0x200) >> 2) |
669 ((vd & 0x200) >> 3) |
670 ((vt & 0x200) >> 4) | 0x10 |
671 ((vbs & 0x100) >> 5) |
672 ((vs & 0x100) >> 6) |
673 ((vd & 0x100) >> 7) |
675 reg.crt[0x09] |= 0x40 | ((vbs & 0x200) >> 4);
677 reg.crt[0x11] = (ve & 0x0f) | 0x20;
681 reg.crt[0x16] = vbe + 1;
682 reg.crt[0x17] = 0xc3;
683 reg.crt[0x18] = 0xff;
686 reg.ext[0x00] = (((ht & 0x100) >> 8) |
687 ((hd & 0x100) >> 6) |
688 ((hbs & 0x100) >> 4) |
689 ((hbe & 0x40) >> 1) |
690 ((hs & 0x100) >> 2) |
692 reg.ext[0x01] = (((vt & 0x400) >> 10) |
693 ((vd & 0x400) >> 8) |
694 ((vbs & 0x400) >> 6) |
695 ((vbe & 0x400) >> 4));
702 reg.vgainit1 = tdfx_inl(par,
VGAINIT1) & 0x1fffff;
705 reg.curspataddr = info->
fix.smem_len;
710 reg.cursc1 = 0xffffff;
712 reg.stride = info->
var.xres *
cpp;
713 reg.startaddr = info->
var.yoffset * reg.stride
714 + info->
var.xoffset *
cpp;
716 reg.vidpll = do_calc_pll(freq, &fout);
718 reg.mempll = do_calc_pll(..., &fout);
719 reg.gfxpll = do_calc_pll(..., &fout);
724 reg.miscinit0 = tdfx_inl(par,
MISCINIT0);
726 #if defined(__BIG_ENDIAN)
727 switch (info->
var.bits_per_pixel) {
730 reg.miscinit0 &= ~(1 << 30);
731 reg.miscinit0 &= ~(1 << 31);
734 reg.miscinit0 |= (1 << 30);
735 reg.miscinit0 |= (1 << 31);
738 reg.miscinit0 |= (1 << 30);
739 reg.miscinit0 &= ~(1 << 31);
743 do_write_regs(info, ®);
746 info->
fix.line_length = reg.stride;
747 info->
fix.visual = (info->
var.bits_per_pixel == 8)
750 DPRINTK(
"Graphics mode is now set at %dx%d depth %d\n",
751 info->
var.xres, info->
var.yres, info->
var.bits_per_pixel);
756 #define CNVT_TOHW(val, width) ((((val) << (width)) + 0x7FFF - (val)) >> 16)
758 static int tdfxfb_setcolreg(
unsigned regno,
unsigned red,
unsigned green,
762 struct tdfx_par *par = info->
par;
765 if (regno >= info->
cmap.len || regno > 255)
769 if (info->
var.grayscale) {
771 blue = (red * 77 + green * 151 + blue * 28) >> 8;
776 switch (info->
fix.visual) {
778 rgbcol = (((
u32)red & 0xff00) << 8) |
779 (((
u32)green & 0xff00) << 0) |
780 (((
u32)blue & 0xff00) >> 8);
781 do_setpalentry(par, regno, rgbcol);
787 info->
var.red.offset) |
789 info->
var.green.offset) |
791 info->
var.blue.offset) |
793 info->
var.transp.offset);
794 par->palette[regno] = rgbcol;
799 DPRINTK(
"bad depth %u\n", info->
var.bits_per_pixel);
807 static int tdfxfb_blank(
int blank,
struct fb_info *info)
809 struct tdfx_par *par = info->
par;
813 dacmode &= ~(
BIT(1) |
BIT(3));
828 dacmode |=
BIT(1) |
BIT(3);
832 banshee_make_room(par, 1);
833 tdfx_outl(par,
DACMODE, dacmode);
835 vga_disable_video(par);
837 vga_enable_video(par);
847 struct tdfx_par *par = info->
par;
853 banshee_make_room(par, 1);
859 #ifdef CONFIG_FB_3DFX_ACCEL
863 static void tdfxfb_fillrect(
struct fb_info *info,
866 struct tdfx_par *par = info->
par;
868 u32 stride = info->
fix.line_length;
869 u32 fmt = stride | ((bpp + ((bpp == 8) ? 0 : 8)) << 13);
881 if (dy + rect->height > 4095) {
882 dstbase = stride * dy;
886 if (dx + rect->width > 4095) {
887 dstbase += dx *
bpp >> 3;
890 banshee_make_room(par, 6);
895 tdfx_outl(par,
COLORFORE, par->palette[rect->color]);
898 tdfx_outl(par,
DSTBASE, dstbase);
899 tdfx_outl(par,
DSTSIZE, rect->width | (rect->height << 16));
900 tdfx_outl(par,
LAUNCH_2D, dx | (dy << 16));
906 static void tdfxfb_copyarea(
struct fb_info *info,
909 struct tdfx_par *par = info->
par;
910 u32 sx = area->
sx, sy = area->
sy, dx = area->
dx, dy = area->
dy;
912 u32 stride = info->
fix.line_length;
914 u32 fmt = stride | ((bpp + ((bpp == 8) ? 0 : 8)) << 13);
919 if (sy + area->height > 4095) {
920 srcbase = stride * sy;
924 if (
sx + area->width > 4095) {
925 srcbase +=
sx *
bpp >> 3;
929 if (dy + area->height > 4095) {
930 dstbase = stride * dy;
934 if (dx + area->width > 4095) {
935 dstbase += dx *
bpp >> 3;
939 if (area->sx <= area->dx) {
942 sx += area->width - 1;
943 dx += area->width - 1;
945 if (area->sy <= area->dy) {
948 sy += area->height - 1;
949 dy += area->height - 1;
952 banshee_make_room(par, 8);
957 tdfx_outl(par,
DSTSIZE, area->width | (area->height << 16));
958 tdfx_outl(par,
DSTXY, dx | (dy << 16));
959 tdfx_outl(par,
SRCBASE, srcbase);
960 tdfx_outl(par,
DSTBASE, dstbase);
966 struct tdfx_par *par = info->
par;
969 int i, stride = info->
fix.line_length;
971 u32 dstfmt = stride | ((bpp + ((bpp == 8) ? 0 : 8)) << 13);
980 banshee_make_room(par, 6 + ((size + 3) >> 2));
981 srcfmt = stride | ((
bpp + ((
bpp == 8) ? 0 : 8)) << 13) |
988 banshee_make_room(par, 9);
989 switch (info->
fix.visual) {
997 par->palette[
image->fg_color]);
999 par->palette[
image->bg_color]);
1002 srcfmt = 0x400000 |
BIT(20);
1007 if (dy +
image->height > 4095) {
1008 dstbase = stride * dy;
1012 if (dx +
image->width > 4095) {
1013 dstbase += dx *
bpp >> 3;
1017 tdfx_outl(par,
DSTBASE, dstbase);
1018 tdfx_outl(par,
SRCXY, 0);
1019 tdfx_outl(par,
DSTXY, dx | (dy << 16));
1031 for (i = (size >> 2); i > 0; i--) {
1032 if (--fifo_free < 0) {
1034 banshee_make_room(par, fifo_free);
1041 banshee_make_room(par, 3);
1053 *(
u16 *)chardata | (chardata[3] << 24));
1061 struct tdfx_par *par = info->
par;
1068 if (cursor->
image.width > 64 ||
1069 cursor->
image.height > 64 ||
1070 cursor->
image.depth > 1)
1090 u32 bg_idx = cursor->
image.bg_color;
1091 u32 fg_idx = cursor->
image.fg_color;
1092 unsigned long bg_color, fg_color;
1094 fg_color = (((
u32)cmap.
red[fg_idx] & 0xff00) << 8) |
1095 (((
u32)cmap.
green[fg_idx] & 0xff00) << 0) |
1096 (((
u32)cmap.
blue[fg_idx] & 0xff00) >> 8);
1097 bg_color = (((
u32)cmap.
red[bg_idx] & 0xff00) << 8) |
1098 (((
u32)cmap.
green[bg_idx] & 0xff00) << 0) |
1099 (((
u32)cmap.
blue[bg_idx] & 0xff00) >> 8);
1100 banshee_make_room(par, 2);
1101 tdfx_outl(par,
HWCURC0, bg_color);
1102 tdfx_outl(par,
HWCURC1, fg_color);
1106 int x = cursor->
image.dx;
1107 int y = cursor->
image.dy - info->
var.yoffset;
1111 banshee_make_room(par, 1);
1112 tdfx_outl(par,
HWCURLOC, (y << 16) + x);
1140 for (i = 0; i < cursor->
image.height; i++) {
1142 int j = (cursor->
image.width + 7) >> 3;
1144 for (; j > 0; j--) {
1162 static struct fb_ops tdfxfb_ops = {
1164 .fb_check_var = tdfxfb_check_var,
1165 .fb_set_par = tdfxfb_set_par,
1166 .fb_setcolreg = tdfxfb_setcolreg,
1167 .fb_blank = tdfxfb_blank,
1168 .fb_pan_display = tdfxfb_pan_display,
1169 .fb_sync = banshee_wait_idle,
1170 .fb_cursor = tdfxfb_cursor,
1171 #ifdef CONFIG_FB_3DFX_ACCEL
1172 .fb_fillrect = tdfxfb_fillrect,
1173 .fb_copyarea = tdfxfb_copyarea,
1174 .fb_imageblit = tdfxfb_imageblit,
1182 #ifdef CONFIG_FB_3DFX_I2C
1186 static void tdfxfb_i2c_setscl(
void *
data,
int val)
1188 struct tdfxfb_i2c_chan *
chan =
data;
1189 struct tdfx_par *par = chan->par;
1201 static void tdfxfb_i2c_setsda(
void *data,
int val)
1203 struct tdfxfb_i2c_chan *chan =
data;
1204 struct tdfx_par *par = chan->par;
1220 static int tdfxfb_i2c_getscl(
void *data)
1222 struct tdfxfb_i2c_chan *chan =
data;
1223 struct tdfx_par *par = chan->par;
1228 static int tdfxfb_i2c_getsda(
void *data)
1230 struct tdfxfb_i2c_chan *chan =
data;
1231 struct tdfx_par *par = chan->par;
1236 static void tdfxfb_ddc_setscl(
void *data,
int val)
1238 struct tdfxfb_i2c_chan *chan =
data;
1239 struct tdfx_par *par = chan->par;
1251 static void tdfxfb_ddc_setsda(
void *data,
int val)
1253 struct tdfxfb_i2c_chan *chan =
data;
1254 struct tdfx_par *par = chan->par;
1266 static int tdfxfb_ddc_getscl(
void *data)
1268 struct tdfxfb_i2c_chan *chan =
data;
1269 struct tdfx_par *par = chan->par;
1274 static int tdfxfb_ddc_getsda(
void *data)
1276 struct tdfxfb_i2c_chan *chan =
data;
1277 struct tdfx_par *par = chan->par;
1282 static int __devinit tdfxfb_setup_ddc_bus(
struct tdfxfb_i2c_chan *chan,
1287 strlcpy(chan->adapter.name, name,
sizeof(chan->adapter.name));
1290 chan->adapter.algo_data = &chan->algo;
1291 chan->adapter.dev.parent =
dev;
1292 chan->algo.setsda = tdfxfb_ddc_setsda;
1293 chan->algo.setscl = tdfxfb_ddc_setscl;
1294 chan->algo.getsda = tdfxfb_ddc_getsda;
1295 chan->algo.getscl = tdfxfb_ddc_getscl;
1296 chan->algo.udelay = 10;
1298 chan->algo.data = chan;
1300 i2c_set_adapdata(&chan->adapter, chan);
1304 DPRINTK(
"I2C bus %s registered.\n", name);
1311 static int __devinit tdfxfb_setup_i2c_bus(
struct tdfxfb_i2c_chan *chan,
1312 const char *name,
struct device *dev)
1316 strlcpy(chan->adapter.name, name,
sizeof(chan->adapter.name));
1318 chan->adapter.algo_data = &chan->algo;
1319 chan->adapter.dev.parent =
dev;
1320 chan->algo.setsda = tdfxfb_i2c_setsda;
1321 chan->algo.setscl = tdfxfb_i2c_setscl;
1322 chan->algo.getsda = tdfxfb_i2c_getsda;
1323 chan->algo.getscl = tdfxfb_i2c_getscl;
1324 chan->algo.udelay = 10;
1326 chan->algo.data = chan;
1328 i2c_set_adapdata(&chan->adapter, chan);
1332 DPRINTK(
"I2C bus %s registered.\n", name);
1341 struct tdfx_par *par = info->
par;
1346 par->chan[0].par = par;
1347 par->chan[1].par = par;
1349 tdfxfb_setup_ddc_bus(&par->chan[0],
"Voodoo3-DDC", info->
dev);
1350 tdfxfb_setup_i2c_bus(&par->chan[1],
"Voodoo3-I2C", info->
dev);
1353 static void tdfxfb_delete_i2c_busses(
struct tdfx_par *par)
1355 if (par->chan[0].par)
1357 par->chan[0].par =
NULL;
1359 if (par->chan[1].par)
1361 par->chan[1].par =
NULL;
1364 static int tdfxfb_probe_i2c_connector(
struct tdfx_par *par,
1370 if (par->chan[0].par)
1411 default_par = info->
par;
1412 info->
fix = tdfx_fix;
1438 default_par->regbase_virt =
1440 if (!default_par->regbase_virt) {
1443 goto out_err_regbase;
1447 info->
fix.smem_len = do_lfb_size(default_par, pdev->
device);
1448 if (!info->
fix.smem_len) {
1450 goto out_err_regbase;
1456 goto out_err_regbase;
1460 info->
fix.smem_len);
1464 goto out_err_screenbase;
1472 goto out_err_screenbase;
1476 info->
fix.smem_len >> 10);
1478 default_par->mtrr_handle = -1;
1480 default_par->mtrr_handle =
1484 info->
fix.ypanstep = nopan ? 0 : 1;
1485 info->
fix.ywrapstep = nowrap ? 0 : 1;
1487 info->
fbops = &tdfxfb_ops;
1490 #ifdef CONFIG_FB_3DFX_ACCEL
1499 info->
fix.smem_len = (info->
fix.smem_len - 1024) &
1503 info->
var.bits_per_pixel = 8;
1504 #ifdef CONFIG_FB_3DFX_I2C
1505 tdfxfb_create_i2c_busses(info);
1506 err = tdfxfb_probe_i2c_connector(default_par, specs);
1510 DPRINTK(
"Unable to get Mode Database\n");
1521 if (tdfxfb_check_var(&info->
var, info) < 0)
1522 info->
var = tdfx_var;
1529 if (!mode_option && !found)
1530 mode_option =
"640x480@60";
1535 NULL, info->
var.bits_per_pixel);
1536 if (!err || err == 4)
1537 info->
var = tdfx_var;
1546 lpitch = info->
var.xres_virtual * ((info->
var.bits_per_pixel + 7) >> 3);
1547 info->
var.yres_virtual = info->
fix.smem_len / lpitch;
1548 if (info->
var.yres_virtual < info->
var.yres)
1549 goto out_err_iobase;
1553 goto out_err_iobase;
1559 goto out_err_iobase;
1564 pci_set_drvdata(pdev, info);
1568 #ifdef CONFIG_FB_3DFX_I2C
1569 tdfxfb_delete_i2c_busses(default_par);
1571 if (default_par->mtrr_handle >= 0)
1572 mtrr_del(default_par->mtrr_handle, info->
fix.smem_start,
1573 info->
fix.smem_len);
1584 if (default_par->regbase_virt)
1585 iounmap(default_par->regbase_virt);
1597 if (!options || !*options)
1600 while ((this_opt =
strsep(&options,
",")) !=
NULL) {
1603 if (!
strcmp(this_opt,
"nopan")) {
1605 }
else if (!
strcmp(this_opt,
"nowrap")) {
1607 }
else if (!
strncmp(this_opt,
"hwcursor=", 9)) {
1610 }
else if (!
strncmp(this_opt,
"nomtrr", 6)) {
1614 mode_option = this_opt;
1631 struct fb_info *info = pci_get_drvdata(pdev);
1632 struct tdfx_par *par = info->
par;
1635 #ifdef CONFIG_FB_3DFX_I2C
1636 tdfxfb_delete_i2c_busses(par);
1638 if (par->mtrr_handle >= 0)
1640 info->
fix.smem_len);
1651 pci_set_drvdata(pdev,
NULL);
1656 static int __init tdfxfb_init(
void)
1664 tdfxfb_setup(option);
1666 return pci_register_driver(&tdfxfb_driver);
1669 static void __exit tdfxfb_exit(
void)
1680 "(1=enable, 0=disable, default=1)");