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