1/* 2 * linux/drivers/video/sstfb.c -- voodoo graphics frame buffer 3 * 4 * Copyright (c) 2000-2002 Ghozlane Toumi <gtoumi@laposte.net> 5 * 6 * Created 15 Jan 2000 by Ghozlane Toumi 7 * 8 * Contributions (and many thanks) : 9 * 10 * 03/2001 James Simmons <jsimmons@linux-fbdev.org> 11 * 04/2001 Paul Mundt <lethal@chaoticdreams.org> 12 * 05/2001 Urs Ganse <ursg@uni.de> 13 * (initial work on voodoo2 port, interlace) 14 * 09/2002 Helge Deller <deller@gmx.de> 15 * (enable driver on big-endian machines (hppa), ioctl fixes) 16 * 17 * 18 * $Id: sstfb.c,v 1.1.1.1 2008/10/15 03:27:05 james26_jang Exp $ 19 */ 20 21/* 22 * The voodoo1 has the following memory mapped adress space: 23 * 0x000000 - 0x3fffff : registers (4Mb) 24 * 0x400000 - 0x7fffff : linear frame buffer (4Mb) 25 * 0x800000 - 0xffffff : texture memory (8Mb) 26 */ 27 28 29/* 30 * debug info 31 * SST_DEBUG : enable debugging 32 * SST_DEBUG_REG : debug registers 33 * 0 : no debug 34 * 1 : dac calls, [un]set_bits, FbiInit 35 * 2 : insane debug level (log every register read/write) 36 * SST_DEBUG_FUNC : functions 37 * 0 : no debug 38 * 1 : function call / debug ioctl 39 * 2 : variables 40 * 3 : flood . you don't want to do that. trust me. 41 * SST_DEBUG_VAR : debug display/var structs 42 * 0 : no debug 43 * 1 : dumps display, fb_var 44 * SST_DEBUG_IOCTL : enable sstfb specific ioctls 45 * 0 : disable 46 * 1 : enable debug ioctls : 47 * toggle vga (0x46db) : toggle vga_pass_through 48 * fill fb (0x46dc) : fills fb 49 * dump var (0x46dd) : logs display[0-5].var 50 * test disp (0x46de) : draws a test motif 51 */ 52 53/* #define SST_DEBUG */ 54#undef SST_DEBUG 55 56#define SST_DEBUG_REG 0 57#define SST_DEBUG_FUNC 0 58#define SST_DEBUG_VAR 0 59#define SST_DEBUG_IOCTL 1 60 61/* #define EN_24_32_BPP *//* enable 24/32 bpp functions for testing only */ 62#undef EN_24_32_BPP 63 64/* 65 Default video mode . 66 0 800x600@60 took from glide 67 1 640x480@75 took from glide 68 2 1024x768@76 std fb.mode 69 3 640x480@60 glide default */ 70#define DEFAULT_MODE 1 71/* 72 * Includes 73 */ 74 75#include <linux/string.h> 76#include <linux/config.h> 77#include <linux/kernel.h> 78#include <linux/module.h> 79#include <linux/tty.h> 80#include <linux/fb.h> 81#include <linux/pci.h> 82#include <linux/delay.h> 83#include <linux/init.h> 84#include <linux/version.h> 85#include <linux/slab.h> 86 87#include <asm/io.h> 88#include <asm/ioctl.h> 89#include <asm/uaccess.h> 90 91#include <video/fbcon.h> 92#include <video/fbcon-cfb16.h> 93#ifdef EN_24_32_BPP 94# include <video/fbcon-cfb24.h> 95# include <video/fbcon-cfb32.h> 96#endif 97 98#include "sstfb.h" 99 100/* void __Dump_regs(struct sstfb_info *); 101#define Dump_regs __Dump_regs(sst_info) */ 102 103/********/ 104 105 106/* initialized by setup */ 107static int inverse; /* =0 */ /* invert colormap */ 108static int vgapass; /* =0 */ /* enable Vga passthrough cable */ 109static int mem; /* =0 */ /* mem size in Mb , 0 = autodetect */ 110static int clipping = 1; /* use clipping (slower, safer) */ 111static int gfxclk; /* =0 */ /* force FBI freq in Mhz . Dangerous */ 112static int slowpci; /* =0 */ /* slow PCI settings */ 113static int dev = -2; /* specify device (0..n) -2=all -1=none*/ 114 115static char * mode_option ; 116 117 118/********/ 119 120int sstfb_init(void); 121int sstfb_setup(char *options); 122static int __devinit sstfb_probe(struct pci_dev *pdev, const struct pci_device_id *id); 123static void __devexit sstfb_remove(struct pci_dev *pdev); 124 125 126/* Framebuffer API */ 127static int sstfb_open(struct fb_info *info, int user); 128static int sstfb_release(struct fb_info *info, int user); 129static int sstfb_get_fix(struct fb_fix_screeninfo *fix, 130 int con, struct fb_info *info); 131static int sstfb_get_var(struct fb_var_screeninfo *var, 132 int con, struct fb_info *info); 133static int sstfb_set_var(struct fb_var_screeninfo *var, 134 int con, struct fb_info *info); 135static int sstfb_get_cmap(struct fb_cmap *cmap, int kspc, 136 int con, struct fb_info *info); 137static int sstfb_set_cmap(struct fb_cmap *cmap, int kspc, 138 int con, struct fb_info *info); 139static int sstfb_pan_display(struct fb_var_screeninfo *var, 140 int con, struct fb_info *info); 141static int sstfb_ioctl(struct inode *inode, struct file *file, 142 u_int cmd, u_long arg, int con, 143 struct fb_info *info); 144 145/* Interface to the low level console driver */ 146static int sstfbcon_switch(int con, struct fb_info *info); 147static int sstfbcon_updatevar(int con, struct fb_info *info); 148static void sstfbcon_blank(int blank, struct fb_info *info); 149 150/* Internal routines */ 151static void sstfb_install_cmap(int con, struct fb_info *info); 152static int sstfb_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue, 153 u_int *transp, struct fb_info *info); 154static int sstfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, 155 u_int transp, struct fb_info *info); 156 157static int sstfb_set_par(const struct sstfb_par *par, 158 struct sstfb_info *sst_info); 159static int sstfb_decode_var (const struct fb_var_screeninfo *var, 160 struct sstfb_par *par, 161 const struct sstfb_info *sst_info); 162static int sstfb_encode_var (struct fb_var_screeninfo *var, 163 const struct sstfb_par *par, 164 const struct sstfb_info *sst_info); 165 166static void sstfb_test16(struct sstfb_info *sst_info); 167 168#ifdef EN_24_32_BPP 169static void sstfb_test32(struct sstfb_info *sst_info); 170#endif 171 172/* Low level routines */ 173static int sst_get_memsize(struct sstfb_info *sst_info, u_long *memsize); 174static int __sst_wait_idle(u_long vbase); 175#define sst_wait_idle() __sst_wait_idle(sst_info->mmio.vbase) 176static int sst_detect_dactype(struct sstfb_info *sst_info); 177static int sst_detect_att(struct sstfb_info *sst_info); 178static int sst_detect_ti(struct sstfb_info *sst_info); 179static int sst_detect_ics(struct sstfb_info *sst_info); 180static int sst_calc_pll(const int freq, int *freq_out, struct pll_timing *t); 181static int sst_set_pll_att_ti(struct sstfb_info *sst_info, const struct pll_timing *t, const int clock); 182static int sst_set_pll_ics(struct sstfb_info *sst_info, const struct pll_timing *t, const int clock); 183static void sst_set_vidmod_att_ti(struct sstfb_info *sst_info, const int bpp); 184static void sst_set_vidmod_ics(struct sstfb_info *sst_info, const int bpp); 185static int sst_init(struct sstfb_info *sst_info); 186static void sst_shutdown(struct sstfb_info *sst_info); 187 188static struct fb_ops sstfb_ops = { 189 owner : THIS_MODULE, 190 fb_open: sstfb_open, 191 fb_release: sstfb_release, 192 fb_get_fix: sstfb_get_fix, 193 fb_get_var: sstfb_get_var, 194 fb_set_var: sstfb_set_var, 195 fb_get_cmap: sstfb_get_cmap, 196 fb_set_cmap: sstfb_set_cmap, 197 fb_pan_display: sstfb_pan_display, 198 fb_ioctl: sstfb_ioctl, 199}; 200 201enum { 202 ID_VOODOO1 = 0, 203 ID_VOODOO2 = 1, 204}; 205 206#define IS_VOODOO2(info) ((info)->type == ID_VOODOO2 ) 207 208static struct sst_spec voodoo_spec[] __devinitdata = { 209 { name : "Voodoo Graphics", 210 default_gfx_clock : 50000, 211 max_gfxclk : 60, }, 212 { name : "Voodoo2", 213 default_gfx_clock : 75000, 214 max_gfxclk : 85, }, 215}; 216 217static struct pci_device_id sstfb_id_tbl[] __devinitdata = { 218 { PCI_VENDOR_ID_3DFX, PCI_DEVICE_ID_3DFX_VOODOO, 219 PCI_ANY_ID, PCI_ANY_ID, 0, 0, ID_VOODOO1 }, 220 { PCI_VENDOR_ID_3DFX, PCI_DEVICE_ID_3DFX_VOODOO2, 221 PCI_ANY_ID, PCI_ANY_ID, 0, 0, ID_VOODOO2 }, 222 { 0 }, 223}; 224 225static struct pci_driver sstfb_driver = { 226 name: "sstfb", 227 id_table: sstfb_id_tbl, 228 probe: sstfb_probe, 229 remove: __devexit_p(sstfb_remove), 230}; 231 232static struct fb_var_screeninfo sstfb_default = 233#if DEFAULT_MODE == 0 234 { /* 800x600@60, 16 bpp .borowed from glide/sst1/include/sst1init.h */ 235 800, 600, 800, 600, 0, 0, 16, 0, 236 {11, 5, 0}, {5, 6, 0}, {0, 5, 0}, {0, 0, 0}, 237 0, 0, -1, -1, 0, 238 25000, 86, 41, 23, 1, 127, 4, 239 0, FB_VMODE_NONINTERLACED }; 240#endif 241#if DEFAULT_MODE == 1 242 {/* 640x480@75, 16 bpp .borowed from glide/sst1/include/sst1init.h */ 243 640, 480, 640, 480, 0, 0, 16, 0, 244 {11, 5, 0}, {5, 6, 0}, {0, 5, 0}, {0, 0, 0}, 245 0, 0, -1, -1, 0, 246 31746, 118, 17, 16, 1, 63, 3, 247 0, FB_VMODE_NONINTERLACED }; 248#endif 249#if DEFAULT_MODE == 2 250 { /* 1024x768@76 took from my /etc/fb.modes */ 251 1024, 768, 1024, 768,0, 0, 16,0, 252 {11, 5, 0}, {5, 6, 0}, {0, 5, 0}, {0, 0, 0}, 253 0, 0, -1, -1, 0, 254 11764, 208, 8, 36, 16, 120, 3 , 255 0, FB_VMODE_NONINTERLACED }; 256#endif 257#if DEFAULT_MODE == 3 258 { /* 640x480@60 , 16bpp glide default ?*/ 259 640, 480, 640, 480, 0, 0, 16, 0, 260 {11, 5, 0}, {5, 6, 0}, {0, 5, 0}, {0, 0, 0}, 261 0, 0, -1, -1, 0, 262 39721 , 38, 26 , 25 ,18 , 96 ,2, 263 0, FB_VMODE_NONINTERLACED }; 264#endif 265 266static struct dac_switch dacs[] __devinitdata = { 267 { name: "TI TVP3409", 268 detect: sst_detect_ti, 269 set_pll: sst_set_pll_att_ti, 270 set_vidmod: sst_set_vidmod_att_ti }, 271 272 { name: "AT&T ATT20C409", 273 detect: sst_detect_att, 274 set_pll: sst_set_pll_att_ti, 275 set_vidmod: sst_set_vidmod_att_ti }, 276 { name: "ICS ICS5342", 277 detect: sst_detect_ics, 278 set_pll: sst_set_pll_ics, 279 set_vidmod: sst_set_vidmod_ics }, 280}; 281 282 283/* 284 * 285 * Definitions 286 * 287 */ 288 289#if (SST_DEBUG_VAR > 0) 290/* debug info / dump a fb_var_screeninfo */ 291static void sst_dbg_print_var(struct fb_var_screeninfo *var) { 292 dprintk(" {%d, %d, %d, %d, %d, %d, %d, %d,\n", 293 var->xres, var->yres, var->xres_virtual, var->yres_virtual, 294 var->xoffset, var->yoffset, 295 var->bits_per_pixel, var->grayscale); 296 dprintk(" {%d, %d, %d}, {%d, %d, %d}, {%d, %d, %d}, {%d, %d, %d},\n", 297 var->red.offset, var->red.length, var->red.msb_right, 298 var->green.offset, var->green.length, var->green.msb_right, 299 var->blue.offset, var->blue.length, var->blue.msb_right, 300 var->transp.offset, var->transp.length, 301 var->transp.msb_right); 302 dprintk(" %d, %d, %d, %d, %d,\n", 303 var->nonstd, var->activate, 304 var->height, var->width, var->accel_flags); 305 dprintk(" %d, %d, %d, %d, %d, %d, %d,\n", 306 var->pixclock, var->left_margin, var->right_margin, 307 var->upper_margin, var->lower_margin, 308 var->hsync_len, var->vsync_len); 309 dprintk(" %#x, %#x}\n",var->sync, var->vmode); 310} 311#endif /* (SST_DEBUG_VAR > 0) */ 312 313#if (SST_DEBUG_REG > 0) 314static void sst_dbg_print_read_reg (u32 reg, u32 val) { 315 char * regname =NULL; 316 switch (reg) { 317 case FBIINIT0: regname="FbiInit0"; break; 318 case FBIINIT1: regname="FbiInit1"; break; 319 case FBIINIT2: regname="FbiInit2"; break; 320 case FBIINIT3: regname="FbiInit3"; break; 321 case FBIINIT4: regname="FbiInit4"; break; 322 case FBIINIT5: regname="FbiInit5"; break; 323 case FBIINIT6: regname="FbiInit6"; break; 324 } 325 if (regname == NULL) 326 r_ddprintk("sst_read(%#x): %#x\n", reg, val); 327 else 328 r_dprintk(" sst_read(%s): %#x\n", regname, val); 329} 330 331static void sst_dbg_print_write_reg (u32 reg, u32 val) { 332 char * regname = NULL; 333 334 switch (reg) { 335 case FBIINIT0: regname="FbiInit0"; break; 336 case FBIINIT1: regname="FbiInit1"; break; 337 case FBIINIT2: regname="FbiInit2"; break; 338 case FBIINIT3: regname="FbiInit3"; break; 339 case FBIINIT4: regname="FbiInit4"; break; 340 case FBIINIT5: regname="FbiInit5"; break; 341 case FBIINIT6: regname="FbiInit6"; break; 342 } 343 if (regname == NULL) 344 r_ddprintk("sst_write(%#x, %#x)\n", reg, val); 345 else 346 r_dprintk(" sst_write(%s, %#x)\n", regname, val); 347} 348#else /* (SST_DEBUG_REG > 0) */ 349# define sst_dbg_print_read_reg(reg, val) do {}while(0) 350# define sst_dbg_print_write_reg(reg, val) do {}while(0) 351#endif /* (SST_DEBUG_REG > 0) */ 352 353/* register access */ 354#define sst_read(reg) __sst_read(sst_info->mmio.vbase, reg) 355#define sst_write(reg,val) __sst_write(sst_info->mmio.vbase, reg, val) 356#define sst_set_bits(reg,val) __sst_set_bits(sst_info->mmio.vbase, reg, val) 357#define sst_unset_bits(reg,val) __sst_unset_bits(sst_info->mmio.vbase, reg, val) 358#define sst_dac_read(reg) __sst_dac_read(sst_info->mmio.vbase, reg) 359#define sst_dac_write(reg,val) __sst_dac_write(sst_info->mmio.vbase, reg, val) 360#define dac_i_read(reg) __dac_i_read(sst_info->mmio.vbase, reg) 361#define dac_i_write(reg,val) __dac_i_write(sst_info->mmio.vbase, reg, val) 362 363static inline u32 __sst_read(u_long vbase, u32 reg) 364{ 365 u32 ret; 366 367 ret = readl(vbase + reg); 368 sst_dbg_print_read_reg(reg, ret); 369 return ret; 370} 371 372static inline void __sst_write(u_long vbase, u32 reg, u32 val) 373{ 374 sst_dbg_print_write_reg(reg, val); 375 writel(val, vbase + reg); 376} 377 378static inline void __sst_set_bits(u_long vbase, u32 reg, u32 val) 379{ 380 r_dprintk("sst_set_bits(%#x, %#x)\n", reg, val); 381 __sst_write(vbase, reg, __sst_read(vbase, reg) | val); 382} 383 384static inline void __sst_unset_bits(u_long vbase, u32 reg, u32 val) 385{ 386 r_dprintk("sst_unset_bits(%#x, %#x)\n", reg, val); 387 __sst_write(vbase, reg, __sst_read(vbase, reg) & ~val); 388} 389 390/* dac access */ 391/* dac_read should be remaped to FbiInit2 (via the pci reg init_enable) */ 392static u8 __sst_dac_read(u_long vbase, u8 reg) 393{ 394 u8 ret; 395 396#ifdef SST_DEBUG 397 if ((reg & 0x07) != reg) { 398 dprintk("bug line %d: register adress '%d' is too high\n", 399 __LINE__,reg); 400 } 401#endif 402 reg &= 0x07; 403 __sst_write(vbase, DAC_DATA, ((u32)reg << 8) | DAC_READ_CMD ); 404 __sst_wait_idle(vbase); 405 /*udelay(10);*/ 406 ret=(__sst_read(vbase, DAC_READ) & 0xff); 407 r_dprintk("sst_dac_read(%#x): %#x\n", reg, ret); 408 return (u8)ret; 409} 410 411static void __sst_dac_write(u_long vbase, u8 reg, u8 val) 412{ 413 r_dprintk("sst_dac_write(%#x, %#x)\n", reg, val); 414#ifdef SST_DEBUG 415 if ((reg & 0x07) != reg) 416 dprintk("bug line %d: register adress '%d' is too high\n", 417 __LINE__,reg); 418#endif 419 reg &= 0x07; 420 __sst_write(vbase, DAC_DATA,(((u32)reg << 8)) | (u32)val); 421} 422 423/* indexed access to ti/att dacs */ 424static u32 __dac_i_read(u_long vbase, u8 reg) 425{ 426 u32 ret; 427 428 __sst_dac_write(vbase, DACREG_ADDR_I, reg); 429 ret = __sst_dac_read(vbase, DACREG_DATA_I); 430 r_dprintk("sst_dac_read_i(%#x): %#x\n", reg, ret); 431 return ret; 432} 433static void __dac_i_write(u_long vbase, u8 reg,u8 val) 434{ 435 r_dprintk("sst_dac_write_i(%#x, %#x)\n", reg, val); 436 __sst_dac_write(vbase, DACREG_ADDR_I, reg); 437 __sst_dac_write(vbase, DACREG_DATA_I, val); 438} 439 440/* 441 * 442 * Internal routines 443 * 444 */ 445 446static void sstfb_install_cmap(int con, struct fb_info *info) 447{ 448#define sst_info ((struct sstfb_info *) info) 449 f_dprintk("sstfb_install_cmap(con: %d)\n",con); 450 f_ddprintk("currcon: %d\n", sst_info->currcon); 451 if (con != sst_info->currcon) 452 return; 453 if (fb_display[con].cmap.len) 454 fb_set_cmap(&fb_display[con].cmap, 1, sstfb_setcolreg, info); 455 else 456 fb_set_cmap( 457 fb_default_cmap(1<<fb_display[con].var.bits_per_pixel), 458 1, sstfb_setcolreg, info); 459#undef sst_info 460} 461 462static int sstfb_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue, 463 u_int *transp, struct fb_info *info) 464{ 465#define sst_info ((struct sstfb_info *) info) 466 f_dddprintk("sstfb_getcolreg\n"); 467 if (regno >= 16) return 1; 468 469 *red = sst_info->palette[regno].red; 470 *green = sst_info->palette[regno].green; 471 *blue = sst_info->palette[regno].blue; 472 *transp = sst_info->palette[regno].transp; 473 f_dddprintk("%-2d rvba: %#x, %#x, %#x, %#x\n", 474 regno,*red, *green, *blue, *transp); 475 return 0; 476#undef sst_info 477} 478 479static int sstfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, 480 u_int transp, struct fb_info *info) 481{ 482#define sst_info ((struct sstfb_info *) info) 483 u32 col; 484 struct display * disp; 485 486 f_dddprintk("sstfb_setcolreg\n"); 487 f_dddprintk("%-2d rvba: %#x, %#x, %#x, %#x\n", 488 regno, red, green, blue, transp); 489 if (regno >= 16) return 1; 490 491 sst_info->palette[regno].red = red; 492 sst_info->palette[regno].green = green; 493 sst_info->palette[regno].blue = blue; 494 sst_info->palette[regno].transp= transp; 495 496 disp=&sst_info->disp; 497 red >>= (16 - disp->var.red.length); 498 green >>= (16 - disp->var.green.length); 499 blue >>= (16 - disp->var.blue.length); 500 transp >>= (16 - disp->var.transp.length); 501 col = (red << disp->var.red.offset) 502 | (green << disp->var.green.offset) 503 | (blue << disp->var.blue.offset) 504 | (transp << disp->var.transp.offset); 505 506 switch(disp->var.bits_per_pixel) { 507#ifdef FBCON_HAS_CFB16 508 case 16: 509 sst_info->fbcon_cmap.cfb16[regno]=(u16)col; 510 break; 511#endif 512#ifdef EN_24_32_BPP 513#ifdef FBCON_HAS_CFB24 514 case 24: 515 sst_info->fbcon_cmap.cfb32[regno]=col; 516 break; 517#endif 518#ifdef FBCON_HAS_CFB32 519 case 32: 520 sst_info->fbcon_cmap.cfb32[regno]=col; 521 break; 522#endif 523#endif 524 default: 525 eprintk("bug line %d: bad depth '%u'\n",__LINE__, 526 disp->var.bits_per_pixel); 527 break; 528 } 529 f_dddprintk("bpp: %d . encoded color: %#x\n", 530 disp->var.bits_per_pixel, col); 531 return 0; 532#undef sst_info 533} 534 535/* set par according to var ( checks var ) */ 536static int sstfb_decode_var (const struct fb_var_screeninfo *var, 537 struct sstfb_par *par, 538 const struct sstfb_info *sst_info) 539{ 540 int real_length; 541 542 f_dprintk("sstfb_decode_var\n"); 543 /* Check var validity */ 544 par->valid=0; 545 546 memset(par, 0, sizeof(par)); 547 par->xDim = var->xres; 548 par->hSyncOn = var->hsync_len; 549 par->hSyncOff = var->xres + var->right_margin + var->left_margin; 550 par->hBackPorch = var->left_margin; 551 par->yDim = var->yres; 552 par->vSyncOn = var->vsync_len; 553 par->vSyncOff = var->yres + var->lower_margin + var->upper_margin; 554 par->vBackPorch = var->upper_margin; 555 556 if(sst_calc_pll (PS2KHZ(var->pixclock), &par->freq, &par->pll)) { 557 eprintk("Pixclock %d out of range\n", var->pixclock); 558 return -EINVAL; //XXX 559 } 560 561 par->sync=var->sync & (FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT); 562 par->vmode=var->vmode & (FB_VMODE_INTERLACED | FB_VMODE_DOUBLE); 563 564 /* in laced mode, vBackPorch should be even. odd -> funky display */ 565 if (par->vmode & FB_VMODE_INTERLACED) 566 par->vBackPorch += (par->vBackPorch % 2); 567 if (par->vmode & FB_VMODE_DOUBLE) { 568 par->vBackPorch <<= 1; 569 par->yDim <<=1; 570 par->vSyncOn <<=1; 571 par->vSyncOff <<=1; 572 } 573 574 switch (var->bits_per_pixel) { 575 case 0 ... 16 : 576 par->bpp = 16; 577 break; 578#ifdef EN_24_32_BPP 579 case 17 ... 24 : 580 par->bpp = 24; 581 break; 582 case 25 ... 32 : 583 par->bpp = 32; 584 break; 585#endif 586 default : 587 eprintk ("Unsupported bpp %d\n", par->bpp); 588 return -EINVAL; 589 break; 590 } 591 592 if (IS_VOODOO2(sst_info)) { 593 /* voodoo2 has 32 pixel wide tiles , BUT stange things 594 happen with odd number of tiles */ 595 par->tiles_in_X= (par->xDim + 63 ) / 64 * 2; 596 } else { 597 /* voodoo1 has 64 pixels wide tiles. */ 598 par->tiles_in_X= (par->xDim + 63 ) / 64; 599 } 600 601 /* validity tests */ 602 if((par->xDim <= 1) || (par->yDim <= 0 ) 603 || (par->hSyncOn <= 1) 604 || (par->hSyncOff <= 1) 605 || (par->hBackPorch <= 2) 606 || (par->vSyncOn <= 0) 607 || (par->vSyncOff <= 0) 608 || (par->vBackPorch <= 0) 609 || (par->tiles_in_X <= 0)) { 610 return -EINVAL; 611 } 612 if (IS_VOODOO2(sst_info)) { 613 /* Voodoo 2 limits */ 614 if(((par->xDim-1) >= POW2(11)) || (par->yDim >= POW2(11))) { 615 eprintk ("Unsupported resolution %dx%d\n", 616 var->xres, var->yres); 617 return -EINVAL; 618 } 619 if (((par->hSyncOn-1) >= POW2(9)) 620 || ((par->hSyncOff-1) >= POW2(11)) 621 || ((par->hBackPorch-2) >= POW2(9)) 622 || (par->vSyncOn >= POW2(13)) 623 || (par->vSyncOff >= POW2(13)) 624 || (par->vBackPorch >= POW2(9)) 625 || (par->tiles_in_X >= POW2(6))) { 626 eprintk ("Unsupported Timing\n"); 627 return -EINVAL; 628 } 629 } else { 630 /* Voodoo limits */ 631 if (par->vmode) { 632 eprintk("Interlace/Doublescan not supported %#x\n", 633 par->vmode); 634 return -EINVAL; 635 } 636 if(((par->xDim-1) >= POW2(10)) || (par->yDim >= POW2(10))) { 637 eprintk ("Unsupported resolution %dx%d\n", 638 var->xres, var->yres); 639 return -EINVAL; 640 } 641 if (((par->hSyncOn-1) >= POW2(8)) 642 || ((par->hSyncOff-1) >= POW2(10)) 643 || ((par->hBackPorch-2) >= POW2(8)) 644 || (par->vSyncOn >= POW2(12)) 645 || (par->vSyncOff >= POW2(12)) 646 || (par->vBackPorch >= POW2(8)) 647 || (par->tiles_in_X >= POW2(4))) { 648 eprintk ("Unsupported Timings\n"); 649 return -EINVAL; 650 } 651 } 652 653 /* it seems that the fbi uses tiles of 64x16 pixels to "map" the mem*/ 654 real_length = par->tiles_in_X * (IS_VOODOO2(sst_info) ? 32 : 64 ) 655 * ((par->bpp == 16) ? 2 : 4); 656 657 if ((real_length * var->yres) > sst_info->video.len) { 658 eprintk ("Not enough video memory\n"); 659 return -ENOMEM; 660 } 661 par->valid=1; 662 return 0; 663} 664 665/* sets var according to par (basicaly, sets sane values) */ 666static int sstfb_encode_var (struct fb_var_screeninfo *var, 667 const struct sstfb_par *par, 668 const struct sstfb_info *sst_info) 669{ 670 memset(var,0,sizeof(struct fb_var_screeninfo)); 671 672 var->xres = par->xDim; 673 var->yres = par->yDim; 674 var->xres_virtual = par->xDim; 675 var->yres_virtual = par->yDim; 676 var->bits_per_pixel = par->bpp; 677 /* {x|y}offset = 0 ; sync=0 */ 678 var->height = -1; 679 var->width = -1; 680 var->pixclock = KHZ2PS(par->freq); 681 var->left_margin = par->hBackPorch; 682 var->right_margin = par->hSyncOff - par->xDim - par->hBackPorch; 683 var->upper_margin = par->vBackPorch; 684 var->lower_margin = par->vSyncOff - par->yDim - par->vBackPorch; 685 var->hsync_len = par->hSyncOn; 686 var->vsync_len = par->vSyncOn; 687 var->sync = par->sync; 688 var->vmode = par->vmode; 689 if (var->vmode & FB_VMODE_DOUBLE) { 690 var->yres >>=1; 691 var->yres_virtual >>=1; 692 var->vsync_len >>=1; 693 var->upper_margin >>=1; 694 var->lower_margin >>=1; 695 } 696 697 /* 698 * correct the color bit fields 699 */ 700 /* var->{red|green|blue}.msb_right = 0; */ 701 702 switch (par->bpp) { 703 case 16: /* RGB 565 LfbMode 0 */ 704 var->red.length = 5; 705 var->green.length = 6; 706 var->blue.length = 5; 707 var->transp.length = 0; 708 709 var->red.offset = 11; 710 var->green.offset = 5; 711 var->blue.offset = 0; 712 var->transp.offset = 0; 713 break; 714#ifdef EN_24_32_BPP 715 case 24: /* RGB 888 LfbMode 4 */ 716 case 32: /* ARGB 8888 LfbMode 5 */ 717 var->red.length = 8; 718 var->green.length = 8; 719 var->blue.length = 8; 720 var->transp.length = 0; 721 722 var->red.offset = 16; 723 var->green.offset = 8; 724 var->blue.offset = 0; 725 var->transp.offset = 0; /* in 24bpp we fake a 32 bpp mode */ 726 break; 727#endif 728 default: 729 eprintk ("bug line %d: bad depth '%u'\n", __LINE__, par->bpp); 730 break; 731 } 732 return 0; 733} 734 735/* 736 * Frame buffer API 737 */ 738 739static int sstfb_open(struct fb_info *info, int user) 740{ 741 f_dprintk("sstfb_open(user: %d)\n",user); 742 return 0; 743} 744 745static int sstfb_release(struct fb_info *info, int user) 746{ 747 f_dprintk("sstfb_release(user: %d)\n",user); 748 return 0; 749} 750 751static int sstfb_get_fix(struct fb_fix_screeninfo *fix, 752 int con, struct fb_info *info) 753{ 754#define sst_info ((struct sstfb_info *) info) 755 756 struct fb_var_screeninfo *var; 757 struct fb_var_screeninfo var2; 758 759 f_dprintk("sstfb_get_fix(con: %d)\n",con); 760 memset(fix, 0, sizeof(struct fb_fix_screeninfo)); 761 762 if (con == -1) 763 { 764 sstfb_encode_var(&var2, &sst_info->current_par, sst_info); 765 var = &var2; 766 } 767 else 768 var = &fb_display[con].var; 769 770 strcpy(fix->id, sst_info->info.modename); 771 /* lfb phys address = membase + 4Mb */ 772 fix->smem_start = sst_info->video.base; 773 fix->smem_len = sst_info->video.len; 774 775 fix->type = FB_TYPE_PACKED_PIXELS; 776 fix->visual = FB_VISUAL_TRUECOLOR; 777 fix->accel = FB_ACCEL_NONE; 778 /* 779 * According to the specs, the linelength must be of 1024 *pixels*. 780 * and the 24bpp mode is in fact a 32 bpp mode. 781 */ 782 fix->line_length = (var->bits_per_pixel == 16) ? 2048 : 4096 ; 783 return 0; 784#undef sst_info 785} 786 787static int sstfb_get_var(struct fb_var_screeninfo *var, 788 int con, struct fb_info *info) 789{ 790#define sst_info ((struct sstfb_info *) info) 791 f_dprintk("sstfb_get_var(con: %d)\n",con); 792 if (con == -1) 793 sstfb_encode_var(var, &sst_info->current_par, sst_info); 794 else 795 *var = fb_display[con].var; 796 print_var(var, "var"); 797 return 0; 798#undef sst_info 799 } 800 801static int sstfb_set_var(struct fb_var_screeninfo *var, 802 int con, struct fb_info *info) 803{ 804#define sst_info ((struct sstfb_info *) info) 805 806 struct sstfb_par par; 807 struct display *display; 808 int err; 809 int old_bpp,old_xres,old_yres; 810 811 f_dprintk("sstfb_set_var(con: %d)\n",con); 812 f_ddprintk("xres yres vxres vyres bpp activate\n"); 813 f_ddprintk("%-4d %-4d %-5d %-5d %-3d %#-8x\n", 814 var->xres,var->yres,var->xres_virtual,var->yres_virtual, 815 var->bits_per_pixel,var->activate); 816 if (con < 0) 817 display = &sst_info->disp; 818 else 819 display = &fb_display[con]; 820 821 if ((err = sstfb_decode_var(var, &par, sst_info))) 822 return err; 823 sstfb_encode_var (var, &par, sst_info); 824 825 switch (var->activate & FB_ACTIVATE_MASK) { 826 case FB_ACTIVATE_TEST: 827 return 0; 828 case FB_ACTIVATE_NXTOPEN: 829 case FB_ACTIVATE_NOW: 830 break; 831 default: 832 return -EINVAL; 833 } 834 old_xres = display->var.xres; 835 old_yres = display->var.yres; 836 old_bpp = display->var.bits_per_pixel; 837 display->var = *var; 838 839 if ((old_xres != var->xres) || (old_yres != var->yres) 840 || (old_bpp != var->bits_per_pixel)) { 841 /* 2-3 lignes redondantes avec get_fix */ 842 display->screen_base = (char *) sst_info->video.vbase; 843 display->visual = FB_VISUAL_TRUECOLOR; 844 display->type = FB_TYPE_PACKED_PIXELS; 845 display->type_aux = 0; 846 display->ypanstep = 0; 847 display->ywrapstep = 0; 848 display->line_length = (var->bits_per_pixel==16) ? 2048 : 4096; 849 display->inverse = 0; 850 switch (var->bits_per_pixel) { 851#ifdef FBCON_HAS_CFB16 852 case 16: 853 display->dispsw = &fbcon_cfb16; 854 display->dispsw_data = sst_info->fbcon_cmap.cfb16; 855 break; 856#endif 857#ifdef EN_24_32_BPP 858#if defined(FBCON_HAS_CFB24) || defined(FBCON_HAS_CFB32) 859 case 24: /*24bpp non packed <=> 32 bpp */ 860 case 32: 861 display->dispsw = &fbcon_cfb32; 862 display->dispsw_data = sst_info->fbcon_cmap.cfb32; 863 break; 864#endif 865#endif 866 default: 867 display->dispsw = &fbcon_dummy; 868 break; 869 } 870 display->scrollmode = SCROLL_YREDRAW; 871 if (sst_info->info.changevar) { 872 v_dprintk("fb_info.changevar(con: %d)\n", con); 873 (*sst_info->info.changevar)(con); 874 v_dprintk("fb_info.changevar: done \n"); 875 } else { 876 v_dprintk("fb_info.changevar() == NULL . \n"); 877 } 878 } 879 880 if ((con == -1) || (con==sst_info->currcon)) { 881 sstfb_set_par (&par, sst_info); 882 } 883 print_var(var, "var"); 884 print_var(&display->var, "&display->var"); 885 886 if (old_bpp != var->bits_per_pixel) { 887 if ((err = fb_alloc_cmap(&display->cmap, 0, 0))) 888 return err; 889 sstfb_install_cmap(con, info); 890 } 891 892 return 0; 893#undef sst_info 894} 895 896 897static int sstfb_set_cmap(struct fb_cmap *cmap, int kspc, 898 int con, struct fb_info *info) 899{ 900#define sst_info ((struct sstfb_info *) info) 901 struct display *d = (con<0) ? info->disp : fb_display + con; 902 903 f_dprintk("sstfb_set_cmap\n"); 904 f_ddprintk("con: %d, currcon: %d, d->cmap.len %d\n", 905 con, sst_info->currcon, d->cmap.len); 906 907 if (d->cmap.len != 16 ) { /* or test if cmap.len == 0 ? */ 908 int err; 909 err = fb_alloc_cmap(&d->cmap, 16, 0); /* cmap size=16 */ 910 if (err) return err; 911 } 912 if (con == sst_info->currcon) { 913 return fb_set_cmap(cmap, kspc, sstfb_setcolreg, info); 914 } else { 915 fb_copy_cmap(cmap, &d->cmap, kspc ? 0 : 1); 916 } 917 return 0; 918#undef sst_info 919} 920 921static int sstfb_get_cmap(struct fb_cmap *cmap, int kspc, 922 int con, struct fb_info *info) 923{ 924#define sst_info ((struct sstfb_info *) info) 925 f_dprintk("sstfb_get_cmap\n"); 926 f_ddprintk("con %d, curcon %d, cmap.len %d\n", 927 con, sst_info->currcon, fb_display[con].cmap.len); 928 929 if (con == sst_info->currcon) 930 return fb_get_cmap(cmap, kspc, sstfb_getcolreg, info); 931 else if (fb_display[con].cmap.len) 932 fb_copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2); 933 else 934 fb_copy_cmap( 935 fb_default_cmap(1<<fb_display[con].var.bits_per_pixel), 936 cmap, kspc ? 0 : 2); 937 return 0; 938#undef sst_info 939} 940 941/* TODO */ 942static int sstfb_pan_display(struct fb_var_screeninfo *var, 943 int con, struct fb_info *info) 944{ 945 f_dprintk("sstfb_pan_display\n"); 946 return -EINVAL; 947} 948 949static int sstfb_ioctl(struct inode *inode, struct file *file, 950 u_int cmd, u_long arg, int con, 951 struct fb_info *info) 952{ 953#define sst_info ((struct sstfb_info *) info) 954#if (SST_DEBUG_IOCTL >0) 955 int i; 956 u_long p; 957 u32 tmp, val; 958 u32 fbiinit0; 959 struct pci_dev * sst_dev = sst_info->dev; 960#endif 961 962 f_dprintk("sstfb_ioctl(%x)\n", cmd); 963#if (SST_DEBUG_IOCTL >0) 964 switch (cmd) { 965# if (SST_DEBUG_VAR >0) 966/* tmp ioctl : dumps fb_display[0-5] */ 967 case _IO('F', 0xdb): /* 0x46db */ 968 f_dprintk("dumping fb_display[0-5].var\n"); 969 for (i = 0 ; i< 6 ; i++) { 970 print_var(&fb_display[i].var, "var(%d)", i); 971 } 972 return 0; 973# endif /* (SST_DEBUG_VAR >0) */ 974/* fills the lfb up to *(u32*)arg */ 975 case _IOW('F', 0xdc, u32): /* 0x46dc */ 976 if (copy_from_user(&val, (void *) arg, sizeof(val))) 977 return -EFAULT; 978 if (val > 0x400000 ) 979 val = 0x400000; 980 f_dprintk("filling %#x \n", val); 981 for (p = 0 ; p < val; p+=2) 982 writew( p >> 6 , sst_info->video.vbase + p); 983 return 0; 984/* change VGA pass_through */ 985 case _IOW('F', 0xdd, u32): /* 0x46dd */ 986 if (copy_from_user(&val, (void *) arg, sizeof(val))) 987 return -EFAULT; 988 f_dprintk("switch VGA pass-through\n"); 989 pci_read_config_dword(sst_dev, PCI_INIT_ENABLE, &tmp); 990 pci_write_config_dword(sst_dev, PCI_INIT_ENABLE, 991 tmp | PCI_EN_INIT_WR ); 992 fbiinit0 = sst_read (FBIINIT0); 993 if (val) { 994 sst_write(FBIINIT0, fbiinit0 & ~EN_VGA_PASSTHROUGH); 995 iprintk ( "Disabling VGA pass-through\n"); 996 } else { 997 sst_write(FBIINIT0, fbiinit0 | EN_VGA_PASSTHROUGH); 998 iprintk ( "Enabling VGA pass-through\n"); 999 } 1000 pci_write_config_dword(sst_dev, PCI_INIT_ENABLE, tmp); 1001 return 0; 1002 case _IO('F', 0xde): /* 0x46de */ 1003 f_dprintk("test color display\n"); 1004 f_ddprintk("currcon: %d, bpp %d\n", sst_info->currcon, 1005 sst_info->current_par.bpp); 1006 memset_io(sst_info->video.vbase, 0, sst_info->video.len); 1007 switch (sst_info->current_par.bpp) { 1008 case 16: 1009 sstfb_test16(sst_info); 1010 break; 1011# ifdef EN_24_32_BPP 1012 case 24: 1013 case 32: 1014 sstfb_test32(sst_info); 1015 break; 1016# endif 1017 default: 1018 dprintk("bug line %d: bad depth '%u'\n", __LINE__, 1019 sst_info->current_par.bpp); 1020 } 1021 return 0; 1022 } 1023#endif /* (SST_DEBUG_IOCTL >0) */ 1024 return -EINVAL; 1025#undef sst_info 1026} 1027 1028 1029/* 1030 * Low level routines 1031 */ 1032 1033/* get lfb size */ 1034 1035static int __devinit sst_get_memsize(struct sstfb_info *sst_info, u_long *memsize) 1036{ 1037 u_long fbbase_virt = sst_info->video.vbase; 1038 f_dprintk("sst_get_memsize\n"); 1039 1040 /* force memsize */ 1041 if ((mem >= 1 ) && (mem <= 4)) { 1042 *memsize = (mem * 0x100000); 1043 iprintk("supplied memsize: %#lx\n", *memsize); 1044 return 1; 1045 } 1046 1047 writel (0xdeadbeef, fbbase_virt); 1048 writel (0xdeadbeef, fbbase_virt+0x100000); 1049 writel (0xdeadbeef, fbbase_virt+0x200000); 1050 f_ddprintk("0Mb: %#x, 1Mb: %#x, 2Mb: %#x\n", 1051 readl(fbbase_virt), readl(fbbase_virt + 0x100000), 1052 readl(fbbase_virt + 0x200000)); 1053 1054 writel (0xabcdef01, fbbase_virt); 1055 1056 f_ddprintk("0Mb: %#x, 1Mb: %#x, 2Mb: %#x\n", 1057 readl(fbbase_virt), readl(fbbase_virt + 0x100000), 1058 readl(fbbase_virt + 0x200000)); 1059 1060 /* checks for 4mb lfb , then 2, then defaults to 1*/ 1061 if (readl(fbbase_virt + 0x200000) == 0xdeadbeef) { 1062 *memsize = 0x400000; 1063 } else if (readl(fbbase_virt + 0x100000) == 0xdeadbeef) { 1064 *memsize = 0x200000; 1065 } else { 1066 *memsize = 0x100000; 1067 } 1068 f_ddprintk("detected memsize: %#lx\n", *memsize); 1069 return 1; 1070} 1071 1072 1073/* 1074 * wait for the fbi chip. ASK: what happens if the fbi is stuck ? 1075 * 1076 * the FBI is supposed to be ready if we receive 5 time 1077 * in a row a "idle" answer to our requests 1078 */ 1079 1080static int __sst_wait_idle(u_long vbase) 1081{ 1082 int count = 0; 1083 1084 f_ddprintk("sst_wait_idle\n"); 1085 while(1) { 1086 if (__sst_read(vbase, STATUS) & STATUS_FBI_BUSY) { 1087 f_dddprintk("status: busy\n"); 1088 count = 0; 1089 } else { 1090 count++; 1091 f_dddprintk("status: idle(%d)\n", count); 1092 } 1093 if (count >= 5) return 1; 1094//XXX do something to avoid hanging the machine if the voodoo is out 1095 } 1096} 1097 1098/* 1099 * detect dac type 1100 * prerequisite : write to FbiInitx enabled, video and fbi and pci fifo reset, 1101 * dram refresh disabled, FbiInit remaped. 1102 * TODO: mmh.. maybe i shoud put the "prerequisite" in the func ... 1103 */ 1104static int __devinit sst_detect_dactype(struct sstfb_info * sst_info) 1105{ 1106 int ret=0,i; 1107 f_dprintk("sst_detect_dactype\n"); 1108 for (i=0; i< sizeof(dacs)/sizeof(dacs[0]) ; i++) { 1109 ret = dacs[i].detect(sst_info); 1110 if (ret) break; 1111 } 1112 if (!ret) 1113 return 0; 1114 f_dprintk("found %s\n", dacs[i].name); 1115 sst_info->dac_sw=dacs[i]; 1116 return 1; 1117} 1118 1119/* fbi should be idle, and fifo emty and mem disabled */ 1120/* supposed to detect AT&T ATT20C409 and Ti TVP3409 ramdacs */ 1121 1122static int __devinit sst_detect_att(struct sstfb_info * sst_info) 1123{ 1124 int i, mir, dir; 1125 1126 f_dprintk("sst_detect_att\n"); 1127 for (i = 0; i<3; i++) { 1128 sst_dac_write(DACREG_WMA, 0); /* backdoor */ 1129 sst_dac_read(DACREG_RMR); /* read 4 times RMR */ 1130 sst_dac_read(DACREG_RMR); 1131 sst_dac_read(DACREG_RMR); 1132 sst_dac_read(DACREG_RMR); 1133 /* the fifth time, CR0 is read */ 1134 sst_dac_read(DACREG_RMR); 1135 /* the 6th, manufacturer id register */ 1136 mir = sst_dac_read(DACREG_RMR); 1137 /*the 7th, device ID register */ 1138 dir = sst_dac_read(DACREG_RMR); 1139 f_ddprintk("mir: %#x, dir: %#x\n", mir, dir); 1140 if ((mir == DACREG_MIR_ATT ) && (dir == DACREG_DIR_ATT)) { 1141 return 1; 1142 } 1143 } 1144 return 0; 1145} 1146 1147static int __devinit sst_detect_ti(struct sstfb_info * sst_info) 1148{ 1149 int i, mir, dir; 1150 1151 f_dprintk("sst_detect_ti\n"); 1152 for (i = 0; i<3; i++) { 1153 sst_dac_write(DACREG_WMA, 0); /* backdoor */ 1154 sst_dac_read(DACREG_RMR); /* read 4 times RMR */ 1155 sst_dac_read(DACREG_RMR); 1156 sst_dac_read(DACREG_RMR); 1157 sst_dac_read(DACREG_RMR); 1158 /* the fifth time, CR0 is read */ 1159 sst_dac_read(DACREG_RMR); 1160 /* the 6th, manufacturer id register */ 1161 mir = sst_dac_read(DACREG_RMR); 1162 /*the 7th, device ID register */ 1163 dir = sst_dac_read(DACREG_RMR); 1164 f_ddprintk("mir: %#x, dir: %#x\n", mir, dir); 1165 if ((mir == DACREG_MIR_TI ) && (dir == DACREG_DIR_TI)) { 1166 return 1; 1167 } 1168 } 1169 return 0; 1170} 1171 1172/* 1173 * try to detect ICS5342 ramdac 1174 * we get the 1st byte (M value) of preset f1,f7 and fB 1175 * why those 3 ? mmmh... for now, i'll do it the glide way... 1176 * and ask questions later. anyway, it seems that all the freq registers are 1177 * realy at their default state (cf specs) so i ask again, why those 3 regs ? 1178 * mmmmh.. it seems that's much more ugly than i thought. we use f0 and fA for 1179 * pll programming, so in fact, we *hope* that the f1, f7 & fB won't be 1180 * touched... 1181 * is it realy safe ? how can i reset this ramdac ? geee... 1182 */ 1183static int __devinit sst_detect_ics(struct sstfb_info * sst_info) 1184{ 1185 int i; 1186 int m_clk0_1, m_clk0_7, m_clk1_b; 1187 int n_clk0_1, n_clk0_7, n_clk1_b; 1188 f_dprintk("sst_detect_ics\n"); 1189 for (i = 0; i<5; i++ ) { 1190 sst_dac_write(DACREG_ICS_PLLRMA, 0x1); /* f1 */ 1191 m_clk0_1 = sst_dac_read(DACREG_ICS_PLLDATA); 1192 n_clk0_1 = sst_dac_read(DACREG_ICS_PLLDATA); 1193 sst_dac_write(DACREG_ICS_PLLRMA, 0x7); /* f7 */ 1194 m_clk0_7 = sst_dac_read(DACREG_ICS_PLLDATA); 1195 n_clk0_7 = sst_dac_read(DACREG_ICS_PLLDATA); 1196 sst_dac_write(DACREG_ICS_PLLRMA, 0xb); /* fB */ 1197 m_clk1_b= sst_dac_read(DACREG_ICS_PLLDATA); 1198 n_clk1_b= sst_dac_read(DACREG_ICS_PLLDATA); 1199 f_ddprintk("m_clk0_1: %#x, m_clk0_7: %#x, m_clk1_b: %#x\n", 1200 m_clk0_1, m_clk0_7, m_clk1_b); 1201 f_ddprintk("n_clk0_1: %#x, n_clk0_7: %#x, n_clk1_b: %#x\n", 1202 n_clk0_1, n_clk0_7, n_clk1_b); 1203 if (( m_clk0_1 == DACREG_ICS_PLL_CLK0_1_INI) 1204 && (m_clk0_7 == DACREG_ICS_PLL_CLK0_7_INI) 1205 && (m_clk1_b == DACREG_ICS_PLL_CLK1_B_INI)) { 1206 return 1; 1207 } 1208 } 1209 return 0; 1210} 1211 1212/* compute the m,n,p , returns the real freq 1213 * (ics datasheet : N <-> N1 , P <-> N2) 1214 * 1215 * Fout= Fref * (M+2)/( 2^P * (N+2)) 1216 * we try to get close to the asked freq 1217 * with P as high, and M as low as possible 1218 * range: 1219 * ti/att : 0 <= M <= 255; 0 <= P <= 3; 0<= N <= 63 1220 * ics : 1 <= M <= 127; 0 <= P <= 3; 1<= N <= 31 1221 * we'll use the lowest limitation, should be precise enouth 1222 */ 1223static int sst_calc_pll(const int freq, int *freq_out, struct pll_timing *t) 1224{ 1225 int m, m2, n, p, best_err, fout; 1226 int best_n=-1; 1227 int best_m=-1; 1228 1229 f_dprintk("sst_calc_pll(%dKhz)\n", freq); 1230 best_err = freq; 1231 p=3; 1232 /* f * 2^P = vco should be less than VCOmax ~ 250 MHz for ics*/ 1233 while (((1 << p) * freq > VCO_MAX) && (p >= 0)) 1234 p--; 1235 if (p == -1) 1236 return -EINVAL; 1237 for (n = 1; n < 32; n++) { 1238 /* calc 2 * m so we can round it later*/ 1239 m2 = (2 * freq * (1 << p) * (n + 2) ) / DAC_FREF - 4 ; 1240 1241 m = (m2 % 2 ) ? m2/2+1 : m2/2 ; 1242 if (m >= 128) 1243 break; 1244 fout = (DAC_FREF * (m + 2)) / ((1 << p) * (n + 2)); 1245 if ((ABS(fout - freq) < best_err) && (m > 0)) { 1246 best_n = n; 1247 best_m = m; 1248 best_err = ABS(fout - freq); 1249 /* we get the lowest m , allowing 0.5% error in freq*/ 1250 if (200*best_err < freq) break; 1251 } 1252 } 1253 if (best_n == -1) /* unlikely, but who knows ? */ 1254 return -EINVAL; 1255 t->p=p; 1256 t->n=best_n; 1257 t->m=best_m; 1258 *freq_out=(DAC_FREF * (t->m + 2)) / ((1 << t->p) * (t->n + 2)); 1259 f_ddprintk ("m: %d, n: %d, p: %d, F: %dKhz\n", 1260 t->m, t->n, t->p, *freq_out); 1261 return 0; 1262} 1263 1264/* 1265 * gfx, video, pci fifo should be reset, dram refresh disabled 1266 * see detect_dac 1267 */ 1268 1269static int sst_set_pll_att_ti(struct sstfb_info * sst_info, const struct pll_timing *t, const int clock) 1270{ 1271 u8 cr0, cc; 1272 f_dprintk("sst_set_pll_att_ti\n"); 1273 1274 /* enable indexed mode */ 1275 1276 sst_dac_write(DACREG_WMA, 0); /* backdoor */ 1277 sst_dac_read(DACREG_RMR); /* 1 time: RMR */ 1278 sst_dac_read(DACREG_RMR); /* 2 RMR */ 1279 sst_dac_read(DACREG_RMR); /* 3 // */ 1280 sst_dac_read(DACREG_RMR); /* 4 // */ 1281 cr0 = sst_dac_read(DACREG_RMR); /* 5 CR0 */ 1282 1283 sst_dac_write(DACREG_WMA, 0); 1284 sst_dac_read(DACREG_RMR); 1285 sst_dac_read(DACREG_RMR); 1286 sst_dac_read(DACREG_RMR); 1287 sst_dac_read(DACREG_RMR); 1288 sst_dac_write(DACREG_RMR, (cr0 & 0xf0) 1289 | DACREG_CR0_EN_INDEXED 1290 | DACREG_CR0_8BIT 1291 | DACREG_CR0_PWDOWN ); 1292 /* so, now we are in indexed mode . dunno if its common, but 1293 i find this way of doing things a little bit weird :p */ 1294 1295 udelay(300); 1296 cc = dac_i_read(DACREG_CC_I); 1297 switch (clock) { 1298 case VID_CLOCK: 1299 dac_i_write(DACREG_AC0_I, t->m); 1300 dac_i_write(DACREG_AC1_I, t->p << 6 | t->n); 1301 dac_i_write(DACREG_CC_I, 1302 (cc & 0x0f) | DACREG_CC_CLKA | DACREG_CC_CLKA_C); 1303 break; 1304 case GFX_CLOCK: 1305 dac_i_write(DACREG_BD0_I, t->m); 1306 dac_i_write(DACREG_BD1_I, t->p << 6 | t->n); 1307 dac_i_write(DACREG_CC_I, 1308 (cc & 0xf0) | DACREG_CC_CLKB | DACREG_CC_CLKB_D); 1309 break; 1310 default: 1311 dprintk("bug line %d: wrong clock code '%d'\n", 1312 __LINE__,clock); 1313 return 0; 1314 } 1315 udelay(300); 1316 1317 /* power up the dac & return to "normal" non-indexed mode */ 1318 dac_i_write(DACREG_CR0_I, 1319 cr0 & ~DACREG_CR0_PWDOWN & ~DACREG_CR0_EN_INDEXED); 1320 return 1; 1321} 1322 1323static int sst_set_pll_ics(struct sstfb_info * sst_info, const struct pll_timing *t, const int clock) 1324{ 1325 u8 pll_ctrl; 1326 1327 f_dprintk("sst_set_pll_ics\n"); 1328 1329 sst_dac_write(DACREG_ICS_PLLRMA, DACREG_ICS_PLL_CTRL); 1330 pll_ctrl = sst_dac_read(DACREG_ICS_PLLDATA); 1331 switch(clock) { 1332 case VID_CLOCK: 1333 sst_dac_write(DACREG_ICS_PLLWMA, 0x0); /* CLK0, f0 */ 1334 sst_dac_write(DACREG_ICS_PLLDATA, t->m); 1335 sst_dac_write(DACREG_ICS_PLLDATA, t->p << 5 | t->n); 1336 /* selects freq f0 for clock 0 */ 1337 sst_dac_write(DACREG_ICS_PLLWMA, DACREG_ICS_PLL_CTRL); 1338 sst_dac_write(DACREG_ICS_PLLDATA, 1339 (pll_ctrl & 0xd8) 1340 | DACREG_ICS_CLK0 1341 | DACREG_ICS_CLK0_0); 1342 break; 1343 case GFX_CLOCK : 1344 sst_dac_write(DACREG_ICS_PLLWMA, 0xa); /* CLK1, fA */ 1345 sst_dac_write(DACREG_ICS_PLLDATA, t->m); 1346 sst_dac_write(DACREG_ICS_PLLDATA, t->p << 5 | t->n); 1347 /* selects freq fA for clock 1 */ 1348 sst_dac_write(DACREG_ICS_PLLWMA, DACREG_ICS_PLL_CTRL); 1349 sst_dac_write(DACREG_ICS_PLLDATA, 1350 (pll_ctrl & 0xef) | DACREG_ICS_CLK1_A); 1351 break; 1352 default: 1353 dprintk("bug line %d: wrong clock code '%d'\n", 1354 __LINE__, clock); 1355 return 0; 1356 } 1357 udelay(300); 1358 return 1; 1359} 1360 1361static int sstfb_set_par(const struct sstfb_par * par, struct sstfb_info * sst_info) 1362{ 1363 u32 lfbmode, fbiinit1, fbiinit2, fbiinit3, fbiinit5, fbiinit6=0; 1364 int ntiles; 1365 struct pci_dev * sst_dev = sst_info->dev; 1366 1367 f_dprintk("sst_set_par(%dx%d)\n", par->xDim, par->yDim); 1368 f_ddprintk("hSyncOn hSyncOff vSyncOn vSyncOff\n"); 1369 f_ddprintk("%-7d %-8d %-7d %-8d\n", 1370 par->hSyncOn, par->hSyncOff, 1371 par->vSyncOn, par->vSyncOff); 1372 f_ddprintk("hBackPorch vBackPorch xDim yDim Freq\n"); 1373 f_ddprintk("%-10d %-10d %-4d %-4d %-8d\n", 1374 par->hBackPorch, par->vBackPorch, 1375 par->xDim, par->yDim, par->freq); 1376 1377 if (!par->valid) { 1378 BUG(); 1379 return -1; 1380 } 1381 sst_write(NOPCMD, 0); 1382 sst_wait_idle(); 1383 pci_write_config_dword(sst_dev, PCI_INIT_ENABLE, PCI_EN_INIT_WR); 1384 sst_set_bits(FBIINIT1, VIDEO_RESET); 1385 sst_set_bits(FBIINIT0, FBI_RESET | FIFO_RESET); 1386 sst_unset_bits(FBIINIT2, EN_DRAM_REFRESH); 1387 sst_wait_idle(); 1388 1389 /*sst_unset_bits (FBIINIT0, FBI_RESET); / reenable FBI ? */ 1390 1391 sst_write(BACKPORCH, par->vBackPorch << 16 | (par->hBackPorch - 2)); 1392 sst_write(VIDEODIMENSIONS, par->yDim << 16 | (par->xDim - 1)); 1393 sst_write(HSYNC, (par->hSyncOff - 1) << 16 | (par->hSyncOn - 1)); 1394 sst_write(VSYNC, par->vSyncOff << 16 | par->vSyncOn); 1395 1396 fbiinit2=sst_read(FBIINIT2); 1397 fbiinit3=sst_read(FBIINIT3); 1398 1399 /* everything is reset. we enable fbiinit2/3 remap : dac acces ok */ 1400 pci_write_config_dword(sst_dev, PCI_INIT_ENABLE, 1401 PCI_EN_INIT_WR | PCI_REMAP_DAC ); 1402 1403 sst_info->dac_sw.set_vidmod(sst_info, par->bpp); 1404 1405 /* set video clock */ 1406 sst_info->dac_sw.set_pll(sst_info, &par->pll, VID_CLOCK); 1407 1408 /* disable fbiinit2/3 remap */ 1409 pci_write_config_dword(sst_dev, PCI_INIT_ENABLE, 1410 PCI_EN_INIT_WR); 1411 1412 /* restore fbiinit2/3 */ 1413 sst_write(FBIINIT2,fbiinit2); 1414 sst_write(FBIINIT3,fbiinit3); 1415 1416 fbiinit1 = (sst_read(FBIINIT1) & VIDEO_MASK) 1417 | EN_DATA_OE 1418 | EN_BLANK_OE 1419 | EN_HVSYNC_OE 1420 | EN_DCLK_OE 1421/* | (15 << TILES_IN_X_SHIFT)*/ 1422 | SEL_INPUT_VCLK_2X 1423/* | (2 << VCLK_2X_SEL_DEL_SHIFT) 1424 | (2 << VCLK_DEL_SHIFT)*/; 1425 1426 ntiles = par->tiles_in_X; 1427 if (IS_VOODOO2(sst_info)) { 1428 fbiinit1 |= ((ntiles & 0x20) >> 5) << TILES_IN_X_MSB_SHIFT 1429 | ((ntiles & 0x1e) >> 1) << TILES_IN_X_SHIFT ; 1430/* as the only value of importance for us in fbiinit6 is tiles in X (lsb), 1431 and as reading fbinit 6 will return crap (see FBIINIT6_DEFAULT) we just 1432 write our value. BTW due to the dac unable to read odd number of tiles, this 1433 field is always null ... */ 1434 fbiinit6 = (ntiles & 0x1) << TILES_IN_X_LSB_SHIFT; 1435 } 1436 else 1437 fbiinit1 |= ntiles << TILES_IN_X_SHIFT; 1438 1439 switch(par->bpp) { 1440 case 16: 1441 fbiinit1 |= SEL_SOURCE_VCLK_2X_SEL; 1442 break; 1443#ifdef EN_24_32_BPP 1444 case 24: 1445 case 32: 1446/* orig sst_set_bits(FBIINIT1, SEL_SOURCE_VCLK_2X_DIV2 | EN_24BPP); */ 1447 fbiinit1 |= SEL_SOURCE_VCLK_2X_SEL | EN_24BPP; 1448 break; 1449#endif 1450 default: 1451 dprintk("bug line %d: bad depth '%u'\n", __LINE__, 1452 par->bpp ); 1453 return 0; 1454 break; 1455 } 1456 sst_write(FBIINIT1, fbiinit1); 1457 if (IS_VOODOO2(sst_info)) { 1458 sst_write(FBIINIT6, fbiinit6); 1459 fbiinit5=sst_read(FBIINIT5) & FBIINIT5_MASK ; 1460 if (par->vmode & FB_VMODE_INTERLACED) 1461 fbiinit5 |= INTERLACE; 1462 if (par->vmode & FB_VMODE_DOUBLE ) 1463 fbiinit5 |= VDOUBLESCAN; 1464 if (par->sync & FB_SYNC_HOR_HIGH_ACT) 1465 fbiinit5 |= HSYNC_HIGH; 1466 if (par->sync & FB_SYNC_VERT_HIGH_ACT) 1467 fbiinit5 |= VSYNC_HIGH; 1468 sst_write(FBIINIT5, fbiinit5); 1469 } 1470 sst_wait_idle(); 1471 sst_unset_bits(FBIINIT1, VIDEO_RESET); 1472 sst_unset_bits(FBIINIT0, FBI_RESET | FIFO_RESET); 1473 sst_set_bits(FBIINIT2, EN_DRAM_REFRESH); 1474/* disables fbiinit writes */ 1475 pci_write_config_dword(sst_dev, PCI_INIT_ENABLE, PCI_EN_FIFO_WR); 1476 1477 /* set lfbmode : set mode + front buffer for reads/writes 1478 + disable pipeline */ 1479 switch(par->bpp) { 1480 case 16: 1481 lfbmode = LFB_565; 1482 break; 1483#ifdef EN_24_32_BPP 1484 case 24: 1485 lfbmode = LFB_888; 1486 break; 1487 case 32: 1488 lfbmode = LFB_8888; 1489 break; 1490#endif 1491 default: 1492 dprintk("bug line %d: bad depth '%u'\n", __LINE__, 1493 par->bpp ); 1494 return 0; 1495 break; 1496 } 1497 1498#if defined(__BIG_ENDIAN) 1499 /* enable byte-swizzle functionality in hardware */ 1500 lfbmode |= ( LFB_WORD_SWIZZLE_WR | LFB_BYTE_SWIZZLE_WR | 1501 LFB_WORD_SWIZZLE_RD | LFB_BYTE_SWIZZLE_RD ); 1502#endif 1503 1504 if (clipping) { 1505 sst_write(LFBMODE, lfbmode | EN_PXL_PIPELINE); 1506 /* 1507 * Set "clipping" dimensions. If clipping is disabled and 1508 * writes to offscreen areas of the framebuffer are performed, 1509 * the "behaviour is undefined" (_very_ undefined) - Urs 1510 */ 1511 /* btw, it requires enabling pixel pipeline in LFBMODE . 1512 off screen read/writes will just wrap and read/print pixels 1513 on screen. Ugly but not that dangerous */ 1514 1515 f_ddprintk("setting clipping dimensions 0..%d, 0..%d\n", 1516 par->xDim-1, par->yDim-1); 1517 1518 sst_write(CLIP_LEFT_RIGHT, par->xDim ); 1519 sst_write(CLIP_LOWY_HIGHY, par->yDim ); 1520 sst_set_bits(FBZMODE, EN_CLIPPING | EN_RGB_WRITE); 1521 } else { 1522 /* no clipping : direct access, no pipeline */ 1523 sst_write(LFBMODE, lfbmode ); 1524 } 1525 1526 sst_info->current_par = *par ; 1527 return 1; 1528} 1529 1530static void sst_set_vidmod_att_ti(struct sstfb_info * sst_info, const int bpp) 1531{ 1532 u8 cr0; 1533 1534 f_dprintk("sst_set_vidmod_att_ti(bpp: %d)\n", bpp); 1535 1536 sst_dac_write(DACREG_WMA, 0); /* backdoor */ 1537 sst_dac_read(DACREG_RMR); /* read 4 times RMR */ 1538 sst_dac_read(DACREG_RMR); 1539 sst_dac_read(DACREG_RMR); 1540 sst_dac_read(DACREG_RMR); 1541 /* the fifth time, CR0 is read */ 1542 cr0 = sst_dac_read(DACREG_RMR); 1543 1544 sst_dac_write(DACREG_WMA, 0); /* backdoor */ 1545 sst_dac_read(DACREG_RMR); /* read 4 times RMR */ 1546 sst_dac_read(DACREG_RMR); 1547 sst_dac_read(DACREG_RMR); 1548 sst_dac_read(DACREG_RMR); 1549 /* cr0 */ 1550 switch(bpp) { 1551 case 16: 1552 sst_dac_write(DACREG_RMR, (cr0 & 0x0f) | DACREG_CR0_16BPP); 1553 break; 1554#ifdef EN_24_32_BPP 1555 case 24: 1556 case 32: 1557 sst_dac_write(DACREG_RMR, (cr0 & 0x0f) | DACREG_CR0_24BPP); 1558 break; 1559#endif 1560 default: 1561 dprintk("bug line %d: bad depth '%u'\n", __LINE__, bpp); 1562 break; 1563 } 1564} 1565 1566static void sst_set_vidmod_ics(struct sstfb_info * sst_info, const int bpp) 1567{ 1568 f_dprintk("sst_set_vidmod_ics(bpp: %d)\n", bpp); 1569 switch(bpp) { 1570 case 16: 1571 sst_dac_write(DACREG_ICS_CMD, DACREG_ICS_CMD_16BPP); 1572 break; 1573#ifdef EN_24_32_BPP 1574 case 24: 1575 case 32: 1576 sst_dac_write(DACREG_ICS_CMD, DACREG_ICS_CMD_24BPP); 1577 break; 1578#endif 1579 default: 1580 dprintk("bug line %d: bad depth '%u'\n", __LINE__, bpp); 1581 break; 1582 } 1583} 1584 1585static int __devinit sst_init(struct sstfb_info *sst_info) 1586{ 1587 struct pll_timing gfx_timings; 1588 struct sst_spec * spec; 1589 struct pci_dev * sst_dev = sst_info->dev; 1590 int Fout; 1591 u32 fbiinit0, fbiinit1, fbiinit4; 1592 1593 spec = &voodoo_spec[sst_info->type]; 1594 f_dprintk("sst_init\n"); 1595 f_ddprintk(" fbiinit0 fbiinit1 fbiinit2 fbiinit3 fbiinit4 " 1596 " fbiinit6\n"); 1597 f_ddprintk("%0#10x %0#10x %0#10x %0#10x %0#10x %0#10x\n", 1598 sst_read(FBIINIT0), sst_read(FBIINIT1), sst_read(FBIINIT2), 1599 sst_read(FBIINIT3), sst_read(FBIINIT4), sst_read(FBIINIT6)); 1600 /* disable video clock */ 1601 pci_write_config_dword(sst_dev, PCI_VCLK_DISABLE,0); 1602 1603 /* enable writing to init registers ,disable pci fifo*/ 1604 pci_write_config_dword(sst_dev, PCI_INIT_ENABLE, PCI_EN_INIT_WR); 1605 /* reset video */ 1606 sst_set_bits(FBIINIT1, VIDEO_RESET); 1607 sst_wait_idle(); 1608 /* reset gfx + pci fifo */ 1609 sst_set_bits(FBIINIT0, FBI_RESET | FIFO_RESET); 1610 sst_wait_idle(); 1611 1612 /* unreset fifo */ 1613 /*sst_unset_bits(FBIINIT0, FIFO_RESET); 1614 sst_wait_idle();*/ 1615 /* unreset FBI */ 1616 /*sst_unset_bits(FBIINIT0, FBI_RESET); 1617 sst_wait_idle();*/ 1618 1619 /* disable dram refresh */ 1620 sst_unset_bits(FBIINIT2, EN_DRAM_REFRESH); 1621 sst_wait_idle(); 1622 /* remap fbinit2/3 to dac */ 1623 pci_write_config_dword(sst_dev, PCI_INIT_ENABLE, 1624 PCI_EN_INIT_WR | PCI_REMAP_DAC ); 1625 /* detect dac type */ 1626 if (!sst_detect_dactype(sst_info)) { 1627 eprintk("Unknown dac type\n"); 1628 //FIXME watch it : we are not in a safe state , bad bad bad . 1629 return 0; 1630 } 1631 1632 /* set graphic clock */ 1633 sst_info->gfx_clock = spec->default_gfx_clock; 1634 if ((gfxclk >10 ) && (gfxclk < spec->max_gfxclk)) { 1635 iprintk ("Using supplied graphic freq : %dMHz\n", gfxclk); 1636 sst_info->gfx_clock = gfxclk *1000; 1637 } else if (gfxclk) { 1638 wprintk ("You fool, %dMhz is way out of spec! Using default\n", gfxclk); 1639 } 1640 1641 sst_calc_pll(sst_info->gfx_clock, &Fout, &gfx_timings); 1642 sst_info->dac_sw.set_pll(sst_info, &gfx_timings, GFX_CLOCK); 1643 1644 /* disable fbiinit remap */ 1645 pci_write_config_dword(sst_dev, PCI_INIT_ENABLE, 1646 PCI_EN_INIT_WR| PCI_EN_FIFO_WR ); 1647 /* defaults init registers */ 1648 /* FbiInit0: unreset gfx, unreset fifo */ 1649 fbiinit0 = FBIINIT0_DEFAULT; 1650 fbiinit1 = FBIINIT1_DEFAULT; 1651 fbiinit4 = FBIINIT4_DEFAULT; 1652 if (vgapass) 1653 fbiinit0 &= ~EN_VGA_PASSTHROUGH; 1654 else 1655 fbiinit0 |= EN_VGA_PASSTHROUGH; 1656 if (slowpci) { 1657 fbiinit1 |= SLOW_PCI_WRITES; 1658 fbiinit4 |= SLOW_PCI_READS; 1659 } else { 1660 fbiinit1 &= ~SLOW_PCI_WRITES; 1661 fbiinit4 &= ~SLOW_PCI_READS; 1662 } 1663 sst_write(FBIINIT0, fbiinit0); 1664 sst_wait_idle(); 1665 sst_write(FBIINIT1, fbiinit1); 1666 sst_wait_idle(); 1667 sst_write(FBIINIT2, FBIINIT2_DEFAULT); 1668 sst_wait_idle(); 1669 sst_write(FBIINIT3, FBIINIT3_DEFAULT); 1670 sst_wait_idle(); 1671 sst_write(FBIINIT4, fbiinit4); 1672 sst_wait_idle(); 1673 if (IS_VOODOO2(sst_info)) { 1674 sst_write(FBIINIT6, FBIINIT6_DEFAULT); 1675 sst_wait_idle(); 1676 } 1677 1678 pci_write_config_dword(sst_dev, PCI_INIT_ENABLE, PCI_EN_FIFO_WR ); 1679 pci_write_config_dword(sst_dev, PCI_VCLK_ENABLE, 0); 1680 1681 return 1; 1682} 1683 1684static void __devexit sst_shutdown(struct sstfb_info *sst_info) 1685{ 1686 struct pci_dev * sst_dev = sst_info->dev; 1687 struct pll_timing gfx_timings; 1688 int Fout; 1689 1690 f_dprintk("sst_shutdown\n"); 1691 /* reset video, gfx, fifo, disable dram + remap fbiinit2/3 */ 1692 pci_write_config_dword(sst_dev, PCI_INIT_ENABLE, PCI_EN_INIT_WR); 1693 sst_set_bits(FBIINIT1, VIDEO_RESET | EN_BLANKING); 1694 sst_unset_bits(FBIINIT2, EN_DRAM_REFRESH); 1695 sst_set_bits(FBIINIT0, FBI_RESET | FIFO_RESET); 1696 sst_wait_idle(); 1697 pci_write_config_dword(sst_dev, PCI_INIT_ENABLE, 1698 PCI_EN_INIT_WR | PCI_REMAP_DAC ); 1699 /*set 20Mhz gfx clock */ 1700 sst_calc_pll(20000, &Fout, &gfx_timings); 1701 sst_info->dac_sw.set_pll(sst_info, &gfx_timings, GFX_CLOCK); 1702 /* TODO maybe shutdown the dac, vrefresh and so on... */ 1703 pci_write_config_dword(sst_dev, PCI_INIT_ENABLE, 1704 PCI_EN_INIT_WR); 1705 sst_unset_bits(FBIINIT0, FBI_RESET | FIFO_RESET | EN_VGA_PASSTHROUGH); 1706 pci_write_config_dword(sst_dev, PCI_VCLK_DISABLE,0); 1707/* maybe keep fbiinit* and PCI_INIT_enable in the fb_info struct at the beginining ? */ 1708 pci_write_config_dword(sst_dev, PCI_INIT_ENABLE, 0); 1709 1710} 1711 1712/* 1713 * Interface to the world 1714 */ 1715 1716int __init sstfb_setup(char *options) 1717{ 1718 char *this_opt; 1719 1720 f_dprintk("sstfb_setup\n"); 1721 1722 if (!options || !*options) 1723 return 0; 1724 1725 for(this_opt = strtok(options, ","); this_opt; 1726 this_opt = strtok(NULL, ",")) { //XXX 1727//XXX while ((this_opt = strsep(&options, ",")) != NULL) { 1728 if (!*this_opt) continue; 1729 1730 f_ddprintk("option %s\n", this_opt); 1731 1732 if (!strcmp(this_opt, "inverse")) { 1733 inverse = 1; 1734 fb_invert_cmaps(); 1735 } 1736 else if (!strcmp(this_opt, "vganopass")) 1737 vgapass = 0; 1738 else if (!strcmp(this_opt, "vgapass")) 1739 vgapass = 1; 1740 else if (!strcmp(this_opt, "clipping")) 1741 clipping = 1; 1742 else if (!strcmp(this_opt, "noclipping")) 1743 clipping = 0; 1744 else if (!strcmp(this_opt, "fastpci")) 1745 slowpci = 0; 1746 else if (!strcmp(this_opt, "slowpci")) 1747 slowpci = 1; 1748 else if (!strncmp(this_opt, "mem:",4)) 1749 mem=simple_strtoul (this_opt+4, NULL, 0); 1750 else if (!strncmp(this_opt, "gfxclk:",7)) 1751 gfxclk=simple_strtoul (this_opt+7, NULL, 0); 1752 else if (!strncmp(this_opt, "dev:",4)) 1753 dev=simple_strtoul (this_opt+4, NULL, 0); 1754 else 1755 mode_option=this_opt; 1756 } 1757 return 0; 1758} 1759 1760int __devinit sstfb_init(void) 1761{ 1762 f_dprintk("sstfb_init\n"); 1763 dprintk("Compile date: "__DATE__" "__TIME__"\n"); 1764 return pci_module_init(&sstfb_driver); 1765} 1766 1767void __devexit sstfb_exit(void) 1768{ 1769 f_dprintk("sstfb_exit\n"); 1770 pci_unregister_driver(&sstfb_driver); 1771} 1772 1773#ifdef MODULE 1774module_init(sstfb_init); 1775module_exit(sstfb_exit); 1776#endif 1777 1778static int __devinit sstfb_probe(struct pci_dev *pdev, const struct pci_device_id *id) 1779{ 1780 struct fb_var_screeninfo var; 1781 struct sstfb_info * sst_info; 1782 struct sst_spec * spec; 1783 int tmp,err; 1784 f_dprintk("sstfb_probe\n"); 1785 1786 /* dev > 0 the device is not the one asked for. skip */ 1787 /* dev == 0 this is the device the user asked. init */ 1788 /* dev == -1 we already inited the asked device. skip */ 1789 /* dev < -1 init all devices. including this one. init */ 1790 if ((dev == -1 ) || (dev-- > 0)) 1791 return -1; 1792 1793 if ((err=pci_enable_device(pdev))) { 1794 eprintk("cannot enable device\n"); 1795 return err; 1796 } 1797 1798 sst_info = (struct sstfb_info*)kmalloc(sizeof(*sst_info), GFP_KERNEL); 1799 if (!sst_info) 1800 goto fail_kmalloc; 1801 pci_set_drvdata(pdev, sst_info); 1802 sst_info->type = id->driver_data; 1803 spec = &voodoo_spec[sst_info->type]; 1804 f_ddprintk("found device : %s\n", spec->name); 1805 1806 sst_info->dev = pdev; 1807 pci_read_config_byte(pdev, PCI_REVISION_ID, &sst_info->revision); 1808 1809 sst_info->mmio.base = pci_resource_start(pdev,0); 1810 sst_info->video.base = sst_info->mmio.base+0x400000; 1811 1812 if (!request_mem_region(sst_info->mmio.base,0x400000,"sstfb MMIO")) { 1813 eprintk ("cannot reserve mmio memory\n"); 1814 goto fail_mmio_mem; 1815 } 1816 1817 if (!request_mem_region(sst_info->video.base,0x400000,"sstfb FB")) { 1818 eprintk ("cannot reserve fb memory\n"); 1819 goto fail_fb_mem; 1820 } 1821 1822 sst_info->mmio.vbase = (u_long) ioremap_nocache(sst_info->mmio.base, 0x400000); 1823 if (!sst_info->mmio.vbase) { 1824 eprintk("cannot remap register area %#lx\n", 1825 sst_info->mmio.base); 1826 goto fail_mmio_remap; 1827 } 1828 sst_info->video.vbase = (u_long) ioremap_nocache(sst_info->video.base, 0x400000); 1829 if (!sst_info->video.vbase) { 1830 eprintk("cannot remap framebuffer %#lx\n", 1831 sst_info->video.base); 1832 goto fail_fb_remap; 1833 } 1834 1835 if(!sst_init(sst_info)) { 1836 eprintk("Init failed\n"); 1837 goto fail; 1838 } 1839 sst_get_memsize(sst_info, &sst_info->video.len); 1840 strncpy(sst_info->info.modename, spec->name, 16); 1841 1842 iprintk("%s with %s dac\n", sst_info->info.modename, sst_info->dac_sw.name); 1843 iprintk("framebuffer at %#lx, mapped to %#lx," 1844 " size %ldMb\n", 1845 sst_info->video.base, sst_info->video.vbase, 1846 sst_info->video.len >> 20); 1847 1848 f_ddprintk("revision: %d\n", sst_info->revision); 1849 f_ddprintk("regbase_virt: %#lx\n", sst_info->mmio.vbase); 1850 f_ddprintk("membase_phys: %#lx\n", sst_info->video.base); 1851 f_ddprintk("fbbase_virt: %#lx\n", sst_info->video.vbase); 1852 1853 sst_info->info.node = -1 ; 1854 sst_info->info.flags = FBINFO_FLAG_DEFAULT; 1855 sst_info->info.fbops = &sstfb_ops; 1856 sst_info->info.disp = &sst_info->disp; 1857 sst_info->info.changevar = NULL; 1858 sst_info->info.switch_con = &sstfbcon_switch; 1859 sst_info->info.updatevar = &sstfbcon_updatevar; 1860 sst_info->info.blank = &sstfbcon_blank; 1861 1862 tmp=0; 1863 var = sstfb_default; 1864 if ( mode_option && 1865 fb_find_mode(&var, &sst_info->info, mode_option, 1866 NULL, 0, NULL, 16)) { 1867 if (sstfb_set_var(&var, -1, &sst_info->info)) { 1868 eprintk("can't set supplied video mode. Using default\n"); 1869 var = sstfb_default; 1870 } else { 1871 /* set the new default */ 1872 sstfb_default = var; 1873 tmp=1; /* no need to set the mode. */ 1874 } 1875 } 1876 1877 if (!tmp && sstfb_set_var(&var, -1, &sst_info->info)) { 1878 eprintk("can't set default video mode.\n"); 1879 goto fail; 1880 } 1881 /*clear fb */ 1882 memset_io(sst_info->video.vbase, 0, sst_info->video.len); 1883 /* print some squares ... */ 1884 sstfb_test16(sst_info); 1885 1886 /* register fb */ 1887 if (register_framebuffer(&sst_info->info) < 0) { 1888 eprintk("can't register framebuffer.\n"); 1889 goto fail; 1890 } 1891 printk(KERN_INFO "fb%d: %s frame buffer device\n", 1892 GET_FB_IDX(sst_info->info.node),sst_info->info.modename); 1893 1894 return 0; 1895 1896fail: 1897 iounmap((void *)sst_info->video.base); 1898fail_fb_remap: 1899 iounmap((void *)sst_info->mmio.base); 1900fail_mmio_remap: 1901 release_mem_region(sst_info->video.base,0x400000); 1902fail_fb_mem: 1903 release_mem_region(sst_info->mmio.base,0x400000); 1904fail_mmio_mem: 1905 kfree(sst_info); 1906fail_kmalloc: 1907 return -ENXIO; /* no voodoo detected */ 1908} 1909 1910static void __devexit sstfb_remove(struct pci_dev *pdev) 1911{ 1912 struct sstfb_info * sst_info; 1913 1914 f_dprintk("sstfb_remove\n"); 1915 sst_info=pci_get_drvdata(pdev); 1916 sst_shutdown(sst_info); 1917 1918 unregister_framebuffer(&sst_info->info); 1919 iounmap((void*)sst_info->video.vbase); 1920 iounmap((void*)sst_info->mmio.vbase); 1921 release_mem_region(sst_info->video.base,0x400000); 1922 release_mem_region(sst_info->mmio.base,0x400000); 1923 kfree(sst_info); 1924} 1925 1926 1927/* 1928 * console driver 1929 */ 1930static int sstfbcon_switch(int con, struct fb_info *info) 1931{ 1932#define sst_info ((struct sstfb_info *) info) 1933 struct sstfb_par par; 1934 1935 f_dprintk("sstfbcon_switch(con: %d)\n",con); 1936 f_ddprintk("currcon: %d\n", sst_info->currcon); 1937 v_dprintk("currcon: %d\n", sst_info->currcon); 1938 1939 if (sst_info->currcon >= 0) { 1940 if (fb_display[sst_info->currcon].cmap.len) 1941 fb_get_cmap(&fb_display[sst_info->currcon].cmap, 1, 1942 sstfb_getcolreg, info); 1943 } 1944 sst_info->currcon = con; 1945 fb_display[con].var.activate = FB_ACTIVATE_NOW; 1946 1947 print_var(&fb_display[con].var, "&fb_display[con: %d].var",con); 1948 sstfb_decode_var(&fb_display[con].var, &par, sst_info); 1949 if (memcmp(&par,&(sst_info->current_par),sizeof(par))) { 1950 sstfb_set_par(&par, sst_info); 1951 } 1952 sstfb_install_cmap(con, info); 1953 return 0; 1954#undef sst_info 1955} 1956 1957static int sstfbcon_updatevar(int con, struct fb_info *info) 1958{ 1959 f_dprintk("sstfbcon_updatevar\n"); 1960 return -EINVAL; 1961} 1962 1963static void sstfbcon_blank(int blank, struct fb_info *info) 1964{ 1965 f_dprintk("sstfbcon_blank(level %d)\n", blank); 1966} 1967 1968 1969/* print some squares on the fb (presuming 16bpp) */ 1970static void sstfb_test16(struct sstfb_info *sst_info) 1971{ 1972 int i,j; 1973 u_long p; 1974 u_long fbbase_virt = sst_info->video.vbase; 1975 1976 f_dprintk("sstfb_test16\n"); 1977 /* rect blanc 20x100+200+0 */ 1978 for (i=0 ; i< 100; i++) { 1979 p = fbbase_virt + 2048 *i+400; 1980 for (j=0 ; j < 10 ; j++) { 1981 writel( 0xffffffff, p); 1982 p+=4; 1983 } 1984 } 1985 /* rect bleu 180x200+0+0 */ 1986 for (i=0 ; i< 200; i++) { 1987 p = fbbase_virt + 2048 *i; 1988 for (j=0 ; j < 90 ; j++) { 1989 writel(0x001f001f,p); 1990 p+=4; 1991 } 1992 } 1993 /* carre vert 40x40+100+0 */ 1994 for (i=0 ; i< 40 ; i++) { 1995 p = fbbase_virt + 2048 *i + 200; 1996 for (j=0; j <20;j++) { 1997 writel(0x07e007e0, p); 1998 p+=4; 1999 } 2000 } 2001 /*carre rouge 40x40+100+40 */ 2002 for (i=0; i<40; i++) { 2003 p = fbbase_virt + 2048 * (i+40) + 200; 2004 for (j=0; j <20;j++) { 2005 writel( 0xf800f800, p); 2006 p+=4; 2007 } 2008 } 2009} 2010 2011/* print some squares on the fb (24/32bpp) */ 2012#ifdef EN_24_32_BPP 2013static void sstfb_test32(struct sstfb_info *sst_info) 2014{ 2015 int i,j; 2016 u_long p; 2017 u_long fbbase_virt = sst_info->video.vbase; 2018 2019 f_dprintk("sstfb_test32\n"); 2020 /* rect blanc 20x100+200+0 */ 2021 for (i=0 ; i< 100; i++) { 2022 p = fbbase_virt + 4096*i + 800; 2023 for (j=0 ; j < 20 ; j++) { 2024 writel( 0x00ffffff, p); 2025 p+=4; 2026 } 2027 } 2028 /* rect bleu 180x200+0+0 */ 2029 for (i=0 ; i< 200; i++) { 2030 p = fbbase_virt + 4096 * i; 2031 for (j=0 ; j < 180 ; j++) { 2032 writel(0x000000ff,p); 2033 p+=4; 2034 } 2035 } 2036 /* carre vert 40x40+100+0 */ 2037 for (i=0 ; i< 40 ; i++) { 2038 p = fbbase_virt + 4096 *i + 400; 2039 for (j=0; j <40;j++) { 2040 writel(0x0000ff00, p); 2041 p+=4; 2042 } 2043 } 2044 /*carre rouge 40x40+100+10 */ 2045 for (i=0; i<40; i++) { 2046 p = fbbase_virt + 4096 * (i+40) + 400; 2047 for (j=0; j <40;j++) { 2048 writel( 0x00ff0000, p); 2049 p+=4; 2050 } 2051 } 2052} 2053#endif /* EN_24_32_BPP */ 2054 2055MODULE_AUTHOR("(c) 2000,2002 Ghozlane Toumi <gtoumi@laposte.net>"); 2056MODULE_DESCRIPTION("FBDev driver for 3dfx Voodoo Graphics and Voodoo2 based video boards"); 2057MODULE_LICENSE("GPL"); 2058 2059MODULE_PARM(mem, "i"); 2060MODULE_PARM_DESC(mem, "Size of frame buffer memory in MiB (1, 2, 4 Mb, default=autodetect)"); 2061MODULE_PARM(vgapass, "i"); 2062MODULE_PARM_DESC(vgapass, "Enable VGA PassThrough cable (0 or 1) (default=0)"); 2063MODULE_PARM(inverse, "i"); 2064MODULE_PARM_DESC(inverse, "Inverse colormap (0 or 1) (default=0)"); 2065MODULE_PARM(clipping , "i"); 2066MODULE_PARM_DESC(clipping, "Enable clipping (slower, safer) (0 or 1) (default=1)"); 2067MODULE_PARM(gfxclk , "i"); 2068MODULE_PARM_DESC(gfxclk, "Force graphic chip frequency in Mhz. DANGEROUS. (default=auto)"); 2069MODULE_PARM(slowpci, "i"); 2070MODULE_PARM_DESC(slowpci, "Uses slow PCI settings (0 or 1) (default=0)"); 2071MODULE_PARM(dev,"i"); 2072MODULE_PARM_DESC(dev , "Attach to device ID (0..n) (default=1st device)"); 2073 2074/* 2075 * Overrides for Emacs so that we follow Linus's tabbing style. 2076 * --------------------------------------------------------------------------- 2077 * Local variables: 2078 * c-basic-offset: 8 2079 * End: 2080 */ 2081 2082