1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * SiS 300/540/630[S]/730[S], 4 * SiS 315[E|PRO]/550/[M]65x/[M]66x[F|M|G]X/[M]74x[GX]/330/[M]76x[GX], 5 * XGI V3XT/V5/V8, Z7 6 * frame buffer driver for Linux kernels >= 2.4.14 and >=2.6.3 7 * 8 * Copyright (C) 2001-2005 Thomas Winischhofer, Vienna, Austria. 9 * 10 * Author: Thomas Winischhofer <thomas@winischhofer.net> 11 * 12 * Author of (practically wiped) code base: 13 * SiS (www.sis.com) 14 * Copyright (C) 1999 Silicon Integrated Systems, Inc. 15 * 16 * See http://www.winischhofer.net/ for more information and updates 17 * 18 * Originally based on the VBE 2.0 compliant graphic boards framebuffer driver, 19 * which is (c) 1998 Gerd Knorr <kraxel@goldbach.in-berlin.de> 20 */ 21 22 #include <linux/aperture.h> 23 #include <linux/module.h> 24 #include <linux/moduleparam.h> 25 #include <linux/kernel.h> 26 #include <linux/spinlock.h> 27 #include <linux/errno.h> 28 #include <linux/string.h> 29 #include <linux/mm.h> 30 #include <linux/slab.h> 31 #include <linux/fb.h> 32 #include <linux/selection.h> 33 #include <linux/ioport.h> 34 #include <linux/init.h> 35 #include <linux/pci.h> 36 #include <linux/vmalloc.h> 37 #include <linux/capability.h> 38 #include <linux/fs.h> 39 #include <linux/types.h> 40 #include <linux/uaccess.h> 41 #include <asm/io.h> 42 43 #include "sis.h" 44 #include "sis_main.h" 45 #include "init301.h" 46 47 #if !defined(CONFIG_FB_SIS_300) && !defined(CONFIG_FB_SIS_315) 48 #warning Neither CONFIG_FB_SIS_300 nor CONFIG_FB_SIS_315 is set 49 #warning sisfb will not work! 50 #endif 51 52 /* ---------------------- Prototypes ------------------------- */ 53 54 /* Interface used by the world */ 55 #ifndef MODULE 56 static int sisfb_setup(char *options); 57 #endif 58 59 /* Interface to the low level console driver */ 60 static int sisfb_init(void); 61 62 /* fbdev routines */ 63 static int sisfb_get_fix(struct fb_fix_screeninfo *fix, int con, 64 struct fb_info *info); 65 66 static int sisfb_ioctl(struct fb_info *info, unsigned int cmd, 67 unsigned long arg); 68 static int sisfb_set_par(struct fb_info *info); 69 static int sisfb_blank(int blank, 70 struct fb_info *info); 71 72 static void sisfb_handle_command(struct sis_video_info *ivideo, 73 struct sisfb_cmd *sisfb_command); 74 75 static void sisfb_search_mode(char *name, bool quiet); 76 static int sisfb_validate_mode(struct sis_video_info *ivideo, int modeindex, u32 vbflags); 77 static u8 sisfb_search_refresh_rate(struct sis_video_info *ivideo, unsigned int rate, 78 int index); 79 static int sisfb_setcolreg(unsigned regno, unsigned red, unsigned green, 80 unsigned blue, unsigned transp, 81 struct fb_info *fb_info); 82 static int sisfb_do_set_var(struct fb_var_screeninfo *var, int isactive, 83 struct fb_info *info); 84 static void sisfb_pre_setmode(struct sis_video_info *ivideo); 85 static void sisfb_post_setmode(struct sis_video_info *ivideo); 86 static bool sisfb_CheckVBRetrace(struct sis_video_info *ivideo); 87 static bool sisfbcheckvretracecrt2(struct sis_video_info *ivideo); 88 static bool sisfbcheckvretracecrt1(struct sis_video_info *ivideo); 89 static bool sisfb_bridgeisslave(struct sis_video_info *ivideo); 90 static void sisfb_detect_VB_connect(struct sis_video_info *ivideo); 91 static void sisfb_get_VB_type(struct sis_video_info *ivideo); 92 static void sisfb_set_TVxposoffset(struct sis_video_info *ivideo, int val); 93 static void sisfb_set_TVyposoffset(struct sis_video_info *ivideo, int val); 94 95 /* Internal heap routines */ 96 static int sisfb_heap_init(struct sis_video_info *ivideo); 97 static struct SIS_OH * sisfb_poh_new_node(struct SIS_HEAP *memheap); 98 static struct SIS_OH * sisfb_poh_allocate(struct SIS_HEAP *memheap, u32 size); 99 static void sisfb_delete_node(struct SIS_OH *poh); 100 static void sisfb_insert_node(struct SIS_OH *pohList, struct SIS_OH *poh); 101 static struct SIS_OH * sisfb_poh_free(struct SIS_HEAP *memheap, u32 base); 102 static void sisfb_free_node(struct SIS_HEAP *memheap, struct SIS_OH *poh); 103 104 105 /* ------------------ Internal helper routines ----------------- */ 106 107 static void __init 108 sisfb_setdefaultparms(void) 109 { 110 sisfb_off = 0; 111 sisfb_parm_mem = 0; 112 sisfb_accel = -1; 113 sisfb_ypan = -1; 114 sisfb_max = -1; 115 sisfb_userom = -1; 116 sisfb_useoem = -1; 117 sisfb_mode_idx = -1; 118 sisfb_parm_rate = -1; 119 sisfb_crt1off = 0; 120 sisfb_forcecrt1 = -1; 121 sisfb_crt2type = -1; 122 sisfb_crt2flags = 0; 123 sisfb_pdc = 0xff; 124 sisfb_pdca = 0xff; 125 sisfb_scalelcd = -1; 126 sisfb_specialtiming = CUT_NONE; 127 sisfb_lvdshl = -1; 128 sisfb_dstn = 0; 129 sisfb_fstn = 0; 130 sisfb_tvplug = -1; 131 sisfb_tvstd = -1; 132 sisfb_tvxposoffset = 0; 133 sisfb_tvyposoffset = 0; 134 sisfb_nocrt2rate = 0; 135 #if !defined(__i386__) && !defined(__x86_64__) 136 sisfb_resetcard = 0; 137 sisfb_videoram = 0; 138 #endif 139 } 140 141 /* ------------- Parameter parsing -------------- */ 142 143 static void sisfb_search_vesamode(unsigned int vesamode, bool quiet) 144 { 145 int i = 0, j = 0; 146 147 /* We don't know the hardware specs yet and there is no ivideo */ 148 149 if(vesamode == 0) { 150 if(!quiet) 151 printk(KERN_ERR "sisfb: Invalid mode. Using default.\n"); 152 153 sisfb_mode_idx = DEFAULT_MODE; 154 155 return; 156 } 157 158 vesamode &= 0x1dff; /* Clean VESA mode number from other flags */ 159 160 while(sisbios_mode[i++].mode_no[0] != 0) { 161 if( (sisbios_mode[i-1].vesa_mode_no_1 == vesamode) || 162 (sisbios_mode[i-1].vesa_mode_no_2 == vesamode) ) { 163 if(sisfb_fstn) { 164 if(sisbios_mode[i-1].mode_no[1] == 0x50 || 165 sisbios_mode[i-1].mode_no[1] == 0x56 || 166 sisbios_mode[i-1].mode_no[1] == 0x53) 167 continue; 168 } else { 169 if(sisbios_mode[i-1].mode_no[1] == 0x5a || 170 sisbios_mode[i-1].mode_no[1] == 0x5b) 171 continue; 172 } 173 sisfb_mode_idx = i - 1; 174 j = 1; 175 break; 176 } 177 } 178 if((!j) && !quiet) 179 printk(KERN_ERR "sisfb: Invalid VESA mode 0x%x'\n", vesamode); 180 } 181 182 static void sisfb_search_mode(char *name, bool quiet) 183 { 184 unsigned int j = 0, xres = 0, yres = 0, depth = 0, rate = 0; 185 int i = 0; 186 char strbuf[24], strbuf1[20]; 187 char *nameptr = name; 188 189 /* We don't know the hardware specs yet and there is no ivideo */ 190 191 if(name == NULL) { 192 if(!quiet) 193 printk(KERN_ERR "sisfb: Internal error, using default mode.\n"); 194 195 sisfb_mode_idx = DEFAULT_MODE; 196 return; 197 } 198 199 if(!strncasecmp(name, sisbios_mode[MODE_INDEX_NONE].name, strlen(name))) { 200 if(!quiet) 201 printk(KERN_ERR "sisfb: Mode 'none' not supported anymore. Using default.\n"); 202 203 sisfb_mode_idx = DEFAULT_MODE; 204 return; 205 } 206 207 if (strscpy(strbuf1, name) > 0) { 208 for(i = 0; i < strlen(strbuf1); i++) { 209 if(strbuf1[i] < '0' || strbuf1[i] > '9') strbuf1[i] = ' '; 210 } 211 212 /* This does some fuzzy mode naming detection */ 213 if(sscanf(strbuf1, "%u %u %u %u", &xres, &yres, &depth, &rate) == 4) { 214 if((rate <= 32) || (depth > 32)) { 215 swap(rate, depth); 216 } 217 sprintf(strbuf, "%ux%ux%u", xres, yres, depth); 218 nameptr = strbuf; 219 sisfb_parm_rate = rate; 220 } else if(sscanf(strbuf1, "%u %u %u", &xres, &yres, &depth) == 3) { 221 sprintf(strbuf, "%ux%ux%u", xres, yres, depth); 222 nameptr = strbuf; 223 } else { 224 xres = 0; 225 if((sscanf(strbuf1, "%u %u", &xres, &yres) == 2) && (xres != 0)) { 226 sprintf(strbuf, "%ux%ux8", xres, yres); 227 nameptr = strbuf; 228 } else { 229 sisfb_search_vesamode(simple_strtoul(name, NULL, 0), quiet); 230 return; 231 } 232 } 233 } 234 235 i = 0; j = 0; 236 while(sisbios_mode[i].mode_no[0] != 0) { 237 if(!strncasecmp(nameptr, sisbios_mode[i++].name, strlen(nameptr))) { 238 if(sisfb_fstn) { 239 if(sisbios_mode[i-1].mode_no[1] == 0x50 || 240 sisbios_mode[i-1].mode_no[1] == 0x56 || 241 sisbios_mode[i-1].mode_no[1] == 0x53) 242 continue; 243 } else { 244 if(sisbios_mode[i-1].mode_no[1] == 0x5a || 245 sisbios_mode[i-1].mode_no[1] == 0x5b) 246 continue; 247 } 248 sisfb_mode_idx = i - 1; 249 j = 1; 250 break; 251 } 252 } 253 254 if((!j) && !quiet) 255 printk(KERN_ERR "sisfb: Invalid mode '%s'\n", nameptr); 256 } 257 258 static void __init 259 sisfb_search_crt2type(const char *name) 260 { 261 int i = 0; 262 263 /* We don't know the hardware specs yet and there is no ivideo */ 264 265 if(name == NULL) return; 266 267 while(sis_crt2type[i].type_no != -1) { 268 if(!strncasecmp(name, sis_crt2type[i].name, strlen(sis_crt2type[i].name))) { 269 sisfb_crt2type = sis_crt2type[i].type_no; 270 sisfb_tvplug = sis_crt2type[i].tvplug_no; 271 sisfb_crt2flags = sis_crt2type[i].flags; 272 break; 273 } 274 i++; 275 } 276 277 sisfb_dstn = (sisfb_crt2flags & FL_550_DSTN) ? 1 : 0; 278 sisfb_fstn = (sisfb_crt2flags & FL_550_FSTN) ? 1 : 0; 279 280 if(sisfb_crt2type < 0) 281 printk(KERN_ERR "sisfb: Invalid CRT2 type: %s\n", name); 282 } 283 284 static void __init 285 sisfb_search_tvstd(const char *name) 286 { 287 int i = 0; 288 289 /* We don't know the hardware specs yet and there is no ivideo */ 290 291 if(name == NULL) 292 return; 293 294 while(sis_tvtype[i].type_no != -1) { 295 if(!strncasecmp(name, sis_tvtype[i].name, strlen(sis_tvtype[i].name))) { 296 sisfb_tvstd = sis_tvtype[i].type_no; 297 break; 298 } 299 i++; 300 } 301 } 302 303 static void __init 304 sisfb_search_specialtiming(const char *name) 305 { 306 int i = 0; 307 bool found = false; 308 309 /* We don't know the hardware specs yet and there is no ivideo */ 310 311 if(name == NULL) 312 return; 313 314 if(!strncasecmp(name, "none", 4)) { 315 sisfb_specialtiming = CUT_FORCENONE; 316 printk(KERN_DEBUG "sisfb: Special timing disabled\n"); 317 } else { 318 while(mycustomttable[i].chipID != 0) { 319 if(!strncasecmp(name,mycustomttable[i].optionName, 320 strlen(mycustomttable[i].optionName))) { 321 sisfb_specialtiming = mycustomttable[i].SpecialID; 322 found = true; 323 printk(KERN_INFO "sisfb: Special timing for %s %s forced (\"%s\")\n", 324 mycustomttable[i].vendorName, 325 mycustomttable[i].cardName, 326 mycustomttable[i].optionName); 327 break; 328 } 329 i++; 330 } 331 if(!found) { 332 printk(KERN_WARNING "sisfb: Invalid SpecialTiming parameter, valid are:"); 333 printk(KERN_WARNING "\t\"none\" (to disable special timings)\n"); 334 i = 0; 335 while(mycustomttable[i].chipID != 0) { 336 printk(KERN_WARNING "\t\"%s\" (for %s %s)\n", 337 mycustomttable[i].optionName, 338 mycustomttable[i].vendorName, 339 mycustomttable[i].cardName); 340 i++; 341 } 342 } 343 } 344 } 345 346 /* ----------- Various detection routines ----------- */ 347 348 static void sisfb_detect_custom_timing(struct sis_video_info *ivideo) 349 { 350 unsigned char *biosver = NULL; 351 unsigned char *biosdate = NULL; 352 bool footprint; 353 u32 chksum = 0; 354 int i, j; 355 356 if(ivideo->SiS_Pr.UseROM) { 357 biosver = ivideo->SiS_Pr.VirtualRomBase + 0x06; 358 biosdate = ivideo->SiS_Pr.VirtualRomBase + 0x2c; 359 for(i = 0; i < 32768; i++) 360 chksum += ivideo->SiS_Pr.VirtualRomBase[i]; 361 } 362 363 i = 0; 364 do { 365 if( (mycustomttable[i].chipID == ivideo->chip) && 366 ((!strlen(mycustomttable[i].biosversion)) || 367 (ivideo->SiS_Pr.UseROM && 368 (!strncmp(mycustomttable[i].biosversion, biosver, 369 strlen(mycustomttable[i].biosversion))))) && 370 ((!strlen(mycustomttable[i].biosdate)) || 371 (ivideo->SiS_Pr.UseROM && 372 (!strncmp(mycustomttable[i].biosdate, biosdate, 373 strlen(mycustomttable[i].biosdate))))) && 374 ((!mycustomttable[i].bioschksum) || 375 (ivideo->SiS_Pr.UseROM && 376 (mycustomttable[i].bioschksum == chksum))) && 377 (mycustomttable[i].pcisubsysvendor == ivideo->subsysvendor) && 378 (mycustomttable[i].pcisubsyscard == ivideo->subsysdevice) ) { 379 footprint = true; 380 for(j = 0; j < 5; j++) { 381 if(mycustomttable[i].biosFootprintAddr[j]) { 382 if(ivideo->SiS_Pr.UseROM) { 383 if(ivideo->SiS_Pr.VirtualRomBase[mycustomttable[i].biosFootprintAddr[j]] != 384 mycustomttable[i].biosFootprintData[j]) { 385 footprint = false; 386 } 387 } else 388 footprint = false; 389 } 390 } 391 if(footprint) { 392 ivideo->SiS_Pr.SiS_CustomT = mycustomttable[i].SpecialID; 393 printk(KERN_DEBUG "sisfb: Identified [%s %s], special timing applies\n", 394 mycustomttable[i].vendorName, 395 mycustomttable[i].cardName); 396 printk(KERN_DEBUG "sisfb: [specialtiming parameter name: %s]\n", 397 mycustomttable[i].optionName); 398 break; 399 } 400 } 401 i++; 402 } while(mycustomttable[i].chipID); 403 } 404 405 static bool sisfb_interpret_edid(struct sisfb_monitor *monitor, u8 *buffer) 406 { 407 int i, j, xres, yres, refresh, index; 408 u32 emodes; 409 410 if(buffer[0] != 0x00 || buffer[1] != 0xff || 411 buffer[2] != 0xff || buffer[3] != 0xff || 412 buffer[4] != 0xff || buffer[5] != 0xff || 413 buffer[6] != 0xff || buffer[7] != 0x00) { 414 printk(KERN_DEBUG "sisfb: Bad EDID header\n"); 415 return false; 416 } 417 418 if(buffer[0x12] != 0x01) { 419 printk(KERN_INFO "sisfb: EDID version %d not supported\n", 420 buffer[0x12]); 421 return false; 422 } 423 424 monitor->feature = buffer[0x18]; 425 426 if(!(buffer[0x14] & 0x80)) { 427 if(!(buffer[0x14] & 0x08)) { 428 printk(KERN_INFO 429 "sisfb: WARNING: Monitor does not support separate syncs\n"); 430 } 431 } 432 433 if(buffer[0x13] >= 0x01) { 434 /* EDID V1 rev 1 and 2: Search for monitor descriptor 435 * to extract ranges 436 */ 437 j = 0x36; 438 for(i=0; i<4; i++) { 439 if(buffer[j] == 0x00 && buffer[j + 1] == 0x00 && 440 buffer[j + 2] == 0x00 && buffer[j + 3] == 0xfd && 441 buffer[j + 4] == 0x00) { 442 monitor->hmin = buffer[j + 7]; 443 monitor->hmax = buffer[j + 8]; 444 monitor->vmin = buffer[j + 5]; 445 monitor->vmax = buffer[j + 6]; 446 monitor->dclockmax = buffer[j + 9] * 10 * 1000; 447 monitor->datavalid = true; 448 break; 449 } 450 j += 18; 451 } 452 } 453 454 if(!monitor->datavalid) { 455 /* Otherwise: Get a range from the list of supported 456 * Estabished Timings. This is not entirely accurate, 457 * because fixed frequency monitors are not supported 458 * that way. 459 */ 460 monitor->hmin = 65535; monitor->hmax = 0; 461 monitor->vmin = 65535; monitor->vmax = 0; 462 monitor->dclockmax = 0; 463 emodes = buffer[0x23] | (buffer[0x24] << 8) | (buffer[0x25] << 16); 464 for(i = 0; i < 13; i++) { 465 if(emodes & sisfb_ddcsmodes[i].mask) { 466 if(monitor->hmin > sisfb_ddcsmodes[i].h) monitor->hmin = sisfb_ddcsmodes[i].h; 467 if(monitor->hmax < sisfb_ddcsmodes[i].h) monitor->hmax = sisfb_ddcsmodes[i].h + 1; 468 if(monitor->vmin > sisfb_ddcsmodes[i].v) monitor->vmin = sisfb_ddcsmodes[i].v; 469 if(monitor->vmax < sisfb_ddcsmodes[i].v) monitor->vmax = sisfb_ddcsmodes[i].v; 470 if(monitor->dclockmax < sisfb_ddcsmodes[i].d) monitor->dclockmax = sisfb_ddcsmodes[i].d; 471 } 472 } 473 index = 0x26; 474 for(i = 0; i < 8; i++) { 475 xres = (buffer[index] + 31) * 8; 476 switch(buffer[index + 1] & 0xc0) { 477 case 0xc0: yres = (xres * 9) / 16; break; 478 case 0x80: yres = (xres * 4) / 5; break; 479 case 0x40: yres = (xres * 3) / 4; break; 480 default: yres = xres; break; 481 } 482 refresh = (buffer[index + 1] & 0x3f) + 60; 483 if((xres >= 640) && (yres >= 480)) { 484 for(j = 0; j < 8; j++) { 485 if((xres == sisfb_ddcfmodes[j].x) && 486 (yres == sisfb_ddcfmodes[j].y) && 487 (refresh == sisfb_ddcfmodes[j].v)) { 488 if(monitor->hmin > sisfb_ddcfmodes[j].h) monitor->hmin = sisfb_ddcfmodes[j].h; 489 if(monitor->hmax < sisfb_ddcfmodes[j].h) monitor->hmax = sisfb_ddcfmodes[j].h + 1; 490 if(monitor->vmin > sisfb_ddcsmodes[j].v) monitor->vmin = sisfb_ddcsmodes[j].v; 491 if(monitor->vmax < sisfb_ddcsmodes[j].v) monitor->vmax = sisfb_ddcsmodes[j].v; 492 if(monitor->dclockmax < sisfb_ddcsmodes[j].d) monitor->dclockmax = sisfb_ddcsmodes[j].d; 493 } 494 } 495 } 496 index += 2; 497 } 498 if((monitor->hmin <= monitor->hmax) && (monitor->vmin <= monitor->vmax)) { 499 monitor->datavalid = true; 500 } 501 } 502 503 return monitor->datavalid; 504 } 505 506 static void sisfb_handle_ddc(struct sis_video_info *ivideo, 507 struct sisfb_monitor *monitor, int crtno) 508 { 509 unsigned short temp, i, realcrtno = crtno; 510 unsigned char buffer[256]; 511 512 monitor->datavalid = false; 513 514 if(crtno) { 515 if(ivideo->vbflags & CRT2_LCD) realcrtno = 1; 516 else if(ivideo->vbflags & CRT2_VGA) realcrtno = 2; 517 else return; 518 } 519 520 if((ivideo->sisfb_crt1off) && (!crtno)) 521 return; 522 523 temp = SiS_HandleDDC(&ivideo->SiS_Pr, ivideo->vbflags, ivideo->sisvga_engine, 524 realcrtno, 0, &buffer[0], ivideo->vbflags2); 525 if((!temp) || (temp == 0xffff)) { 526 printk(KERN_INFO "sisfb: CRT%d DDC probing failed\n", crtno + 1); 527 return; 528 } else { 529 printk(KERN_INFO "sisfb: CRT%d DDC supported\n", crtno + 1); 530 printk(KERN_INFO "sisfb: CRT%d DDC level: %s%s%s%s\n", 531 crtno + 1, 532 (temp & 0x1a) ? "" : "[none of the supported]", 533 (temp & 0x02) ? "2 " : "", 534 (temp & 0x08) ? "D&P" : "", 535 (temp & 0x10) ? "FPDI-2" : ""); 536 if(temp & 0x02) { 537 i = 3; /* Number of retrys */ 538 do { 539 temp = SiS_HandleDDC(&ivideo->SiS_Pr, ivideo->vbflags, ivideo->sisvga_engine, 540 realcrtno, 1, &buffer[0], ivideo->vbflags2); 541 } while((temp) && i--); 542 if(!temp) { 543 if(sisfb_interpret_edid(monitor, &buffer[0])) { 544 printk(KERN_INFO "sisfb: Monitor range H %d-%dKHz, V %d-%dHz, Max. dotclock %dMHz\n", 545 monitor->hmin, monitor->hmax, monitor->vmin, monitor->vmax, 546 monitor->dclockmax / 1000); 547 } else { 548 printk(KERN_INFO "sisfb: CRT%d DDC EDID corrupt\n", crtno + 1); 549 } 550 } else { 551 printk(KERN_INFO "sisfb: CRT%d DDC reading failed\n", crtno + 1); 552 } 553 } else { 554 printk(KERN_INFO "sisfb: VESA D&P and FPDI-2 not supported yet\n"); 555 } 556 } 557 } 558 559 /* -------------- Mode validation --------------- */ 560 561 static bool 562 sisfb_verify_rate(struct sis_video_info *ivideo, struct sisfb_monitor *monitor, 563 int mode_idx, int rate_idx, int rate) 564 { 565 int htotal, vtotal; 566 unsigned int dclock, hsync; 567 568 if(!monitor->datavalid) 569 return true; 570 571 if(mode_idx < 0) 572 return false; 573 574 /* Skip for 320x200, 320x240, 640x400 */ 575 switch(sisbios_mode[mode_idx].mode_no[ivideo->mni]) { 576 case 0x59: 577 case 0x41: 578 case 0x4f: 579 case 0x50: 580 case 0x56: 581 case 0x53: 582 case 0x2f: 583 case 0x5d: 584 case 0x5e: 585 return true; 586 #ifdef CONFIG_FB_SIS_315 587 case 0x5a: 588 case 0x5b: 589 if(ivideo->sisvga_engine == SIS_315_VGA) return true; 590 #endif 591 } 592 593 if(rate < (monitor->vmin - 1)) 594 return false; 595 if(rate > (monitor->vmax + 1)) 596 return false; 597 598 if(sisfb_gettotalfrommode(&ivideo->SiS_Pr, 599 sisbios_mode[mode_idx].mode_no[ivideo->mni], 600 &htotal, &vtotal, rate_idx)) { 601 dclock = (htotal * vtotal * rate) / 1000; 602 if(dclock > (monitor->dclockmax + 1000)) 603 return false; 604 hsync = dclock / htotal; 605 if(hsync < (monitor->hmin - 1)) 606 return false; 607 if(hsync > (monitor->hmax + 1)) 608 return false; 609 } else { 610 return false; 611 } 612 return true; 613 } 614 615 static int 616 sisfb_validate_mode(struct sis_video_info *ivideo, int myindex, u32 vbflags) 617 { 618 u16 xres=0, yres, myres; 619 620 #ifdef CONFIG_FB_SIS_300 621 if (ivideo->sisvga_engine == SIS_300_VGA) { 622 if (!(sisbios_mode[myindex].chipset & MD_SIS300)) 623 return -1 ; 624 } 625 #endif 626 #ifdef CONFIG_FB_SIS_315 627 if (ivideo->sisvga_engine == SIS_315_VGA) { 628 if (!(sisbios_mode[myindex].chipset & MD_SIS315)) 629 return -1; 630 } 631 #endif 632 633 myres = sisbios_mode[myindex].yres; 634 635 switch (vbflags & VB_DISPTYPE_DISP2) { 636 637 case CRT2_LCD: 638 xres = ivideo->lcdxres; yres = ivideo->lcdyres; 639 640 if ((ivideo->SiS_Pr.SiS_CustomT != CUT_PANEL848) && 641 (ivideo->SiS_Pr.SiS_CustomT != CUT_PANEL856)) { 642 if (sisbios_mode[myindex].xres > xres) 643 return -1; 644 if (myres > yres) 645 return -1; 646 } 647 648 if (ivideo->sisfb_fstn) { 649 if (sisbios_mode[myindex].xres == 320) { 650 if (myres == 240) { 651 switch (sisbios_mode[myindex].mode_no[1]) { 652 case 0x50: myindex = MODE_FSTN_8; break; 653 case 0x56: myindex = MODE_FSTN_16; break; 654 case 0x53: return -1; 655 } 656 } 657 } 658 } 659 660 if (SiS_GetModeID_LCD(ivideo->sisvga_engine, vbflags, sisbios_mode[myindex].xres, 661 sisbios_mode[myindex].yres, 0, ivideo->sisfb_fstn, 662 ivideo->SiS_Pr.SiS_CustomT, xres, yres, ivideo->vbflags2) < 0x14) { 663 return -1; 664 } 665 break; 666 667 case CRT2_TV: 668 if (SiS_GetModeID_TV(ivideo->sisvga_engine, vbflags, sisbios_mode[myindex].xres, 669 sisbios_mode[myindex].yres, 0, ivideo->vbflags2) < 0x14) { 670 return -1; 671 } 672 break; 673 674 case CRT2_VGA: 675 if (SiS_GetModeID_VGA2(ivideo->sisvga_engine, vbflags, sisbios_mode[myindex].xres, 676 sisbios_mode[myindex].yres, 0, ivideo->vbflags2) < 0x14) { 677 return -1; 678 } 679 break; 680 } 681 682 return myindex; 683 } 684 685 static u8 686 sisfb_search_refresh_rate(struct sis_video_info *ivideo, unsigned int rate, int mode_idx) 687 { 688 int i = 0; 689 u16 xres = sisbios_mode[mode_idx].xres; 690 u16 yres = sisbios_mode[mode_idx].yres; 691 692 ivideo->rate_idx = 0; 693 while((sisfb_vrate[i].idx != 0) && (sisfb_vrate[i].xres <= xres)) { 694 if((sisfb_vrate[i].xres == xres) && (sisfb_vrate[i].yres == yres)) { 695 if(sisfb_vrate[i].refresh == rate) { 696 ivideo->rate_idx = sisfb_vrate[i].idx; 697 break; 698 } else if(sisfb_vrate[i].refresh > rate) { 699 if((sisfb_vrate[i].refresh - rate) <= 3) { 700 DPRINTK("sisfb: Adjusting rate from %d up to %d\n", 701 rate, sisfb_vrate[i].refresh); 702 ivideo->rate_idx = sisfb_vrate[i].idx; 703 ivideo->refresh_rate = sisfb_vrate[i].refresh; 704 } else if((sisfb_vrate[i].idx != 1) && 705 ((rate - sisfb_vrate[i-1].refresh) <= 2)) { 706 DPRINTK("sisfb: Adjusting rate from %d down to %d\n", 707 rate, sisfb_vrate[i-1].refresh); 708 ivideo->rate_idx = sisfb_vrate[i-1].idx; 709 ivideo->refresh_rate = sisfb_vrate[i-1].refresh; 710 } 711 break; 712 } else if((rate - sisfb_vrate[i].refresh) <= 2) { 713 DPRINTK("sisfb: Adjusting rate from %d down to %d\n", 714 rate, sisfb_vrate[i].refresh); 715 ivideo->rate_idx = sisfb_vrate[i].idx; 716 break; 717 } 718 } 719 i++; 720 } 721 if(ivideo->rate_idx > 0) { 722 return ivideo->rate_idx; 723 } else { 724 printk(KERN_INFO "sisfb: Unsupported rate %d for %dx%d\n", 725 rate, xres, yres); 726 return 0; 727 } 728 } 729 730 static bool 731 sisfb_bridgeisslave(struct sis_video_info *ivideo) 732 { 733 unsigned char P1_00; 734 735 if(!(ivideo->vbflags2 & VB2_VIDEOBRIDGE)) 736 return false; 737 738 P1_00 = SiS_GetReg(SISPART1, 0x00); 739 if( ((ivideo->sisvga_engine == SIS_300_VGA) && (P1_00 & 0xa0) == 0x20) || 740 ((ivideo->sisvga_engine == SIS_315_VGA) && (P1_00 & 0x50) == 0x10) ) { 741 return true; 742 } else { 743 return false; 744 } 745 } 746 747 static bool 748 sisfballowretracecrt1(struct sis_video_info *ivideo) 749 { 750 u8 temp; 751 752 temp = SiS_GetReg(SISCR, 0x17); 753 if(!(temp & 0x80)) 754 return false; 755 756 temp = SiS_GetReg(SISSR, 0x1f); 757 if(temp & 0xc0) 758 return false; 759 760 return true; 761 } 762 763 static bool 764 sisfbcheckvretracecrt1(struct sis_video_info *ivideo) 765 { 766 if(!sisfballowretracecrt1(ivideo)) 767 return false; 768 769 if (SiS_GetRegByte(SISINPSTAT) & 0x08) 770 return true; 771 else 772 return false; 773 } 774 775 static void 776 sisfbwaitretracecrt1(struct sis_video_info *ivideo) 777 { 778 int watchdog; 779 780 if(!sisfballowretracecrt1(ivideo)) 781 return; 782 783 watchdog = 65536; 784 while ((!(SiS_GetRegByte(SISINPSTAT) & 0x08)) && --watchdog); 785 watchdog = 65536; 786 while ((SiS_GetRegByte(SISINPSTAT) & 0x08) && --watchdog); 787 } 788 789 static bool 790 sisfbcheckvretracecrt2(struct sis_video_info *ivideo) 791 { 792 unsigned char temp, reg; 793 794 switch(ivideo->sisvga_engine) { 795 case SIS_300_VGA: reg = 0x25; break; 796 case SIS_315_VGA: reg = 0x30; break; 797 default: return false; 798 } 799 800 temp = SiS_GetReg(SISPART1, reg); 801 if(temp & 0x02) 802 return true; 803 else 804 return false; 805 } 806 807 static bool 808 sisfb_CheckVBRetrace(struct sis_video_info *ivideo) 809 { 810 if(ivideo->currentvbflags & VB_DISPTYPE_DISP2) { 811 if(!sisfb_bridgeisslave(ivideo)) { 812 return sisfbcheckvretracecrt2(ivideo); 813 } 814 } 815 return sisfbcheckvretracecrt1(ivideo); 816 } 817 818 static u32 819 sisfb_setupvbblankflags(struct sis_video_info *ivideo, u32 *vcount, u32 *hcount) 820 { 821 u8 idx, reg1, reg2, reg3, reg4; 822 u32 ret = 0; 823 824 (*vcount) = (*hcount) = 0; 825 826 if((ivideo->currentvbflags & VB_DISPTYPE_DISP2) && (!(sisfb_bridgeisslave(ivideo)))) { 827 828 ret |= (FB_VBLANK_HAVE_VSYNC | 829 FB_VBLANK_HAVE_HBLANK | 830 FB_VBLANK_HAVE_VBLANK | 831 FB_VBLANK_HAVE_VCOUNT | 832 FB_VBLANK_HAVE_HCOUNT); 833 switch(ivideo->sisvga_engine) { 834 case SIS_300_VGA: idx = 0x25; break; 835 default: 836 case SIS_315_VGA: idx = 0x30; break; 837 } 838 reg1 = SiS_GetReg(SISPART1, (idx+0)); /* 30 */ 839 reg2 = SiS_GetReg(SISPART1, (idx+1)); /* 31 */ 840 reg3 = SiS_GetReg(SISPART1, (idx+2)); /* 32 */ 841 reg4 = SiS_GetReg(SISPART1, (idx+3)); /* 33 */ 842 if(reg1 & 0x01) ret |= FB_VBLANK_VBLANKING; 843 if(reg1 & 0x02) ret |= FB_VBLANK_VSYNCING; 844 if(reg4 & 0x80) ret |= FB_VBLANK_HBLANKING; 845 (*vcount) = reg3 | ((reg4 & 0x70) << 4); 846 (*hcount) = reg2 | ((reg4 & 0x0f) << 8); 847 848 } else if(sisfballowretracecrt1(ivideo)) { 849 850 ret |= (FB_VBLANK_HAVE_VSYNC | 851 FB_VBLANK_HAVE_VBLANK | 852 FB_VBLANK_HAVE_VCOUNT | 853 FB_VBLANK_HAVE_HCOUNT); 854 reg1 = SiS_GetRegByte(SISINPSTAT); 855 if(reg1 & 0x08) ret |= FB_VBLANK_VSYNCING; 856 if(reg1 & 0x01) ret |= FB_VBLANK_VBLANKING; 857 reg1 = SiS_GetReg(SISCR, 0x20); 858 reg1 = SiS_GetReg(SISCR, 0x1b); 859 reg2 = SiS_GetReg(SISCR, 0x1c); 860 reg3 = SiS_GetReg(SISCR, 0x1d); 861 (*vcount) = reg2 | ((reg3 & 0x07) << 8); 862 (*hcount) = (reg1 | ((reg3 & 0x10) << 4)) << 3; 863 } 864 865 return ret; 866 } 867 868 static int 869 sisfb_myblank(struct sis_video_info *ivideo, int blank) 870 { 871 u8 sr01, sr11, sr1f, cr63=0, p2_0, p1_13; 872 bool backlight = true; 873 874 switch(blank) { 875 case FB_BLANK_UNBLANK: /* on */ 876 sr01 = 0x00; 877 sr11 = 0x00; 878 sr1f = 0x00; 879 cr63 = 0x00; 880 p2_0 = 0x20; 881 p1_13 = 0x00; 882 backlight = true; 883 break; 884 case FB_BLANK_NORMAL: /* blank */ 885 sr01 = 0x20; 886 sr11 = 0x00; 887 sr1f = 0x00; 888 cr63 = 0x00; 889 p2_0 = 0x20; 890 p1_13 = 0x00; 891 backlight = true; 892 break; 893 case FB_BLANK_VSYNC_SUSPEND: /* no vsync */ 894 sr01 = 0x20; 895 sr11 = 0x08; 896 sr1f = 0x80; 897 cr63 = 0x40; 898 p2_0 = 0x40; 899 p1_13 = 0x80; 900 backlight = false; 901 break; 902 case FB_BLANK_HSYNC_SUSPEND: /* no hsync */ 903 sr01 = 0x20; 904 sr11 = 0x08; 905 sr1f = 0x40; 906 cr63 = 0x40; 907 p2_0 = 0x80; 908 p1_13 = 0x40; 909 backlight = false; 910 break; 911 case FB_BLANK_POWERDOWN: /* off */ 912 sr01 = 0x20; 913 sr11 = 0x08; 914 sr1f = 0xc0; 915 cr63 = 0x40; 916 p2_0 = 0xc0; 917 p1_13 = 0xc0; 918 backlight = false; 919 break; 920 default: 921 return 1; 922 } 923 924 if(ivideo->currentvbflags & VB_DISPTYPE_CRT1) { 925 926 if( (!ivideo->sisfb_thismonitor.datavalid) || 927 ((ivideo->sisfb_thismonitor.datavalid) && 928 (ivideo->sisfb_thismonitor.feature & 0xe0))) { 929 930 if(ivideo->sisvga_engine == SIS_315_VGA) { 931 SiS_SetRegANDOR(SISCR, ivideo->SiS_Pr.SiS_MyCR63, 0xbf, cr63); 932 } 933 934 if(!(sisfb_bridgeisslave(ivideo))) { 935 SiS_SetRegANDOR(SISSR, 0x01, ~0x20, sr01); 936 SiS_SetRegANDOR(SISSR, 0x1f, 0x3f, sr1f); 937 } 938 } 939 940 } 941 942 if(ivideo->currentvbflags & CRT2_LCD) { 943 944 if(ivideo->vbflags2 & VB2_SISLVDSBRIDGE) { 945 if(backlight) { 946 SiS_SiS30xBLOn(&ivideo->SiS_Pr); 947 } else { 948 SiS_SiS30xBLOff(&ivideo->SiS_Pr); 949 } 950 } else if(ivideo->sisvga_engine == SIS_315_VGA) { 951 #ifdef CONFIG_FB_SIS_315 952 if(ivideo->vbflags2 & VB2_CHRONTEL) { 953 if(backlight) { 954 SiS_Chrontel701xBLOn(&ivideo->SiS_Pr); 955 } else { 956 SiS_Chrontel701xBLOff(&ivideo->SiS_Pr); 957 } 958 } 959 #endif 960 } 961 962 if(((ivideo->sisvga_engine == SIS_300_VGA) && 963 (ivideo->vbflags2 & (VB2_301|VB2_30xBDH|VB2_LVDS))) || 964 ((ivideo->sisvga_engine == SIS_315_VGA) && 965 ((ivideo->vbflags2 & (VB2_LVDS | VB2_CHRONTEL)) == VB2_LVDS))) { 966 SiS_SetRegANDOR(SISSR, 0x11, ~0x0c, sr11); 967 } 968 969 if(ivideo->sisvga_engine == SIS_300_VGA) { 970 if((ivideo->vbflags2 & VB2_30xB) && 971 (!(ivideo->vbflags2 & VB2_30xBDH))) { 972 SiS_SetRegANDOR(SISPART1, 0x13, 0x3f, p1_13); 973 } 974 } else if(ivideo->sisvga_engine == SIS_315_VGA) { 975 if((ivideo->vbflags2 & VB2_30xB) && 976 (!(ivideo->vbflags2 & VB2_30xBDH))) { 977 SiS_SetRegANDOR(SISPART2, 0x00, 0x1f, p2_0); 978 } 979 } 980 981 } else if(ivideo->currentvbflags & CRT2_VGA) { 982 983 if(ivideo->vbflags2 & VB2_30xB) { 984 SiS_SetRegANDOR(SISPART2, 0x00, 0x1f, p2_0); 985 } 986 987 } 988 989 return 0; 990 } 991 992 /* ------------- Callbacks from init.c/init301.c -------------- */ 993 994 #ifdef CONFIG_FB_SIS_300 995 unsigned int 996 sisfb_read_nbridge_pci_dword(struct SiS_Private *SiS_Pr, int reg) 997 { 998 struct sis_video_info *ivideo = (struct sis_video_info *)SiS_Pr->ivideo; 999 u32 val = 0; 1000 1001 pci_read_config_dword(ivideo->nbridge, reg, &val); 1002 return (unsigned int)val; 1003 } 1004 1005 void 1006 sisfb_write_nbridge_pci_dword(struct SiS_Private *SiS_Pr, int reg, unsigned int val) 1007 { 1008 struct sis_video_info *ivideo = (struct sis_video_info *)SiS_Pr->ivideo; 1009 1010 pci_write_config_dword(ivideo->nbridge, reg, (u32)val); 1011 } 1012 1013 unsigned int 1014 sisfb_read_lpc_pci_dword(struct SiS_Private *SiS_Pr, int reg) 1015 { 1016 struct sis_video_info *ivideo = (struct sis_video_info *)SiS_Pr->ivideo; 1017 u32 val = 0; 1018 1019 if(!ivideo->lpcdev) return 0; 1020 1021 pci_read_config_dword(ivideo->lpcdev, reg, &val); 1022 return (unsigned int)val; 1023 } 1024 #endif 1025 1026 #ifdef CONFIG_FB_SIS_315 1027 void 1028 sisfb_write_nbridge_pci_byte(struct SiS_Private *SiS_Pr, int reg, unsigned char val) 1029 { 1030 struct sis_video_info *ivideo = (struct sis_video_info *)SiS_Pr->ivideo; 1031 1032 pci_write_config_byte(ivideo->nbridge, reg, (u8)val); 1033 } 1034 1035 unsigned int 1036 sisfb_read_mio_pci_word(struct SiS_Private *SiS_Pr, int reg) 1037 { 1038 struct sis_video_info *ivideo = (struct sis_video_info *)SiS_Pr->ivideo; 1039 u16 val = 0; 1040 1041 if(!ivideo->lpcdev) return 0; 1042 1043 pci_read_config_word(ivideo->lpcdev, reg, &val); 1044 return (unsigned int)val; 1045 } 1046 #endif 1047 1048 /* ----------- FBDev related routines for all series ----------- */ 1049 1050 static int 1051 sisfb_get_cmap_len(const struct fb_var_screeninfo *var) 1052 { 1053 return (var->bits_per_pixel == 8) ? 256 : 16; 1054 } 1055 1056 static void 1057 sisfb_set_vparms(struct sis_video_info *ivideo) 1058 { 1059 switch(ivideo->video_bpp) { 1060 case 8: 1061 ivideo->DstColor = 0x0000; 1062 ivideo->SiS310_AccelDepth = 0x00000000; 1063 ivideo->video_cmap_len = 256; 1064 break; 1065 case 16: 1066 ivideo->DstColor = 0x8000; 1067 ivideo->SiS310_AccelDepth = 0x00010000; 1068 ivideo->video_cmap_len = 16; 1069 break; 1070 case 32: 1071 ivideo->DstColor = 0xC000; 1072 ivideo->SiS310_AccelDepth = 0x00020000; 1073 ivideo->video_cmap_len = 16; 1074 break; 1075 default: 1076 ivideo->video_cmap_len = 16; 1077 printk(KERN_ERR "sisfb: Unsupported depth %d", ivideo->video_bpp); 1078 ivideo->accel = 0; 1079 } 1080 } 1081 1082 static int 1083 sisfb_calc_maxyres(struct sis_video_info *ivideo, struct fb_var_screeninfo *var) 1084 { 1085 int maxyres = ivideo->sisfb_mem / (var->xres_virtual * (var->bits_per_pixel >> 3)); 1086 1087 if(maxyres > 32767) maxyres = 32767; 1088 1089 return maxyres; 1090 } 1091 1092 static void 1093 sisfb_calc_pitch(struct sis_video_info *ivideo, struct fb_var_screeninfo *var) 1094 { 1095 ivideo->video_linelength = var->xres_virtual * (var->bits_per_pixel >> 3); 1096 ivideo->scrnpitchCRT1 = ivideo->video_linelength; 1097 if(!(ivideo->currentvbflags & CRT1_LCDA)) { 1098 if((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) { 1099 ivideo->scrnpitchCRT1 <<= 1; 1100 } 1101 } 1102 } 1103 1104 static void 1105 sisfb_set_pitch(struct sis_video_info *ivideo) 1106 { 1107 bool isslavemode = false; 1108 unsigned short HDisplay1 = ivideo->scrnpitchCRT1 >> 3; 1109 unsigned short HDisplay2 = ivideo->video_linelength >> 3; 1110 1111 if(sisfb_bridgeisslave(ivideo)) isslavemode = true; 1112 1113 /* We need to set pitch for CRT1 if bridge is in slave mode, too */ 1114 if((ivideo->currentvbflags & VB_DISPTYPE_DISP1) || (isslavemode)) { 1115 SiS_SetReg(SISCR, 0x13, (HDisplay1 & 0xFF)); 1116 SiS_SetRegANDOR(SISSR, 0x0E, 0xF0, (HDisplay1 >> 8)); 1117 } 1118 1119 /* We must not set the pitch for CRT2 if bridge is in slave mode */ 1120 if((ivideo->currentvbflags & VB_DISPTYPE_DISP2) && (!isslavemode)) { 1121 SiS_SetRegOR(SISPART1, ivideo->CRT2_write_enable, 0x01); 1122 SiS_SetReg(SISPART1, 0x07, (HDisplay2 & 0xFF)); 1123 SiS_SetRegANDOR(SISPART1, 0x09, 0xF0, (HDisplay2 >> 8)); 1124 } 1125 } 1126 1127 static void 1128 sisfb_bpp_to_var(struct sis_video_info *ivideo, struct fb_var_screeninfo *var) 1129 { 1130 ivideo->video_cmap_len = sisfb_get_cmap_len(var); 1131 1132 switch(var->bits_per_pixel) { 1133 case 8: 1134 var->red.offset = var->green.offset = var->blue.offset = 0; 1135 var->red.length = var->green.length = var->blue.length = 8; 1136 break; 1137 case 16: 1138 var->red.offset = 11; 1139 var->red.length = 5; 1140 var->green.offset = 5; 1141 var->green.length = 6; 1142 var->blue.offset = 0; 1143 var->blue.length = 5; 1144 var->transp.offset = 0; 1145 var->transp.length = 0; 1146 break; 1147 case 32: 1148 var->red.offset = 16; 1149 var->red.length = 8; 1150 var->green.offset = 8; 1151 var->green.length = 8; 1152 var->blue.offset = 0; 1153 var->blue.length = 8; 1154 var->transp.offset = 24; 1155 var->transp.length = 8; 1156 break; 1157 } 1158 } 1159 1160 static int 1161 sisfb_set_mode(struct sis_video_info *ivideo, int clrscrn) 1162 { 1163 unsigned short modeno = ivideo->mode_no; 1164 1165 /* >=2.6.12's fbcon clears the screen anyway */ 1166 modeno |= 0x80; 1167 1168 SiS_SetReg(SISSR, IND_SIS_PASSWORD, SIS_PASSWORD); 1169 1170 sisfb_pre_setmode(ivideo); 1171 1172 if(!SiSSetMode(&ivideo->SiS_Pr, modeno)) { 1173 printk(KERN_ERR "sisfb: Setting mode[0x%x] failed\n", ivideo->mode_no); 1174 return -EINVAL; 1175 } 1176 1177 SiS_SetReg(SISSR, IND_SIS_PASSWORD, SIS_PASSWORD); 1178 1179 sisfb_post_setmode(ivideo); 1180 1181 return 0; 1182 } 1183 1184 1185 static int 1186 sisfb_do_set_var(struct fb_var_screeninfo *var, int isactive, struct fb_info *info) 1187 { 1188 struct sis_video_info *ivideo = (struct sis_video_info *)info->par; 1189 unsigned int htotal = 0, vtotal = 0; 1190 unsigned int drate = 0, hrate = 0; 1191 int found_mode = 0, ret; 1192 int old_mode; 1193 u32 pixclock; 1194 1195 htotal = var->left_margin + var->xres + var->right_margin + var->hsync_len; 1196 1197 vtotal = var->upper_margin + var->lower_margin + var->vsync_len; 1198 1199 pixclock = var->pixclock; 1200 1201 if((var->vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED) { 1202 vtotal += var->yres; 1203 vtotal <<= 1; 1204 } else if((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) { 1205 vtotal += var->yres; 1206 vtotal <<= 2; 1207 } else if((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) { 1208 vtotal += var->yres; 1209 vtotal <<= 1; 1210 } else vtotal += var->yres; 1211 1212 if(!(htotal) || !(vtotal)) { 1213 DPRINTK("sisfb: Invalid 'var' information\n"); 1214 return -EINVAL; 1215 } 1216 1217 if(pixclock && htotal && vtotal) { 1218 drate = 1000000000 / pixclock; 1219 hrate = (drate * 1000) / htotal; 1220 ivideo->refresh_rate = (unsigned int) (hrate * 2 / vtotal); 1221 } else { 1222 ivideo->refresh_rate = 60; 1223 } 1224 1225 old_mode = ivideo->sisfb_mode_idx; 1226 ivideo->sisfb_mode_idx = 0; 1227 1228 while( (sisbios_mode[ivideo->sisfb_mode_idx].mode_no[0] != 0) && 1229 (sisbios_mode[ivideo->sisfb_mode_idx].xres <= var->xres) ) { 1230 if( (sisbios_mode[ivideo->sisfb_mode_idx].xres == var->xres) && 1231 (sisbios_mode[ivideo->sisfb_mode_idx].yres == var->yres) && 1232 (sisbios_mode[ivideo->sisfb_mode_idx].bpp == var->bits_per_pixel)) { 1233 ivideo->mode_no = sisbios_mode[ivideo->sisfb_mode_idx].mode_no[ivideo->mni]; 1234 found_mode = 1; 1235 break; 1236 } 1237 ivideo->sisfb_mode_idx++; 1238 } 1239 1240 if(found_mode) { 1241 ivideo->sisfb_mode_idx = sisfb_validate_mode(ivideo, 1242 ivideo->sisfb_mode_idx, ivideo->currentvbflags); 1243 } else { 1244 ivideo->sisfb_mode_idx = -1; 1245 } 1246 1247 if(ivideo->sisfb_mode_idx < 0) { 1248 printk(KERN_ERR "sisfb: Mode %dx%dx%d not supported\n", var->xres, 1249 var->yres, var->bits_per_pixel); 1250 ivideo->sisfb_mode_idx = old_mode; 1251 return -EINVAL; 1252 } 1253 1254 ivideo->mode_no = sisbios_mode[ivideo->sisfb_mode_idx].mode_no[ivideo->mni]; 1255 1256 if(sisfb_search_refresh_rate(ivideo, ivideo->refresh_rate, ivideo->sisfb_mode_idx) == 0) { 1257 ivideo->rate_idx = sisbios_mode[ivideo->sisfb_mode_idx].rate_idx; 1258 ivideo->refresh_rate = 60; 1259 } 1260 1261 if(isactive) { 1262 /* If acceleration to be used? Need to know 1263 * before pre/post_set_mode() 1264 */ 1265 ivideo->accel = 0; 1266 #if defined(FBINFO_HWACCEL_DISABLED) && defined(FBINFO_HWACCEL_XPAN) 1267 #ifdef STUPID_ACCELF_TEXT_SHIT 1268 if(var->accel_flags & FB_ACCELF_TEXT) { 1269 info->flags &= ~FBINFO_HWACCEL_DISABLED; 1270 } else { 1271 info->flags |= FBINFO_HWACCEL_DISABLED; 1272 } 1273 #endif 1274 if(!(info->flags & FBINFO_HWACCEL_DISABLED)) ivideo->accel = -1; 1275 #else 1276 if(var->accel_flags & FB_ACCELF_TEXT) ivideo->accel = -1; 1277 #endif 1278 1279 if((ret = sisfb_set_mode(ivideo, 1))) { 1280 return ret; 1281 } 1282 1283 ivideo->video_bpp = sisbios_mode[ivideo->sisfb_mode_idx].bpp; 1284 ivideo->video_width = sisbios_mode[ivideo->sisfb_mode_idx].xres; 1285 ivideo->video_height = sisbios_mode[ivideo->sisfb_mode_idx].yres; 1286 1287 sisfb_calc_pitch(ivideo, var); 1288 sisfb_set_pitch(ivideo); 1289 1290 sisfb_set_vparms(ivideo); 1291 1292 ivideo->current_width = ivideo->video_width; 1293 ivideo->current_height = ivideo->video_height; 1294 ivideo->current_bpp = ivideo->video_bpp; 1295 ivideo->current_htotal = htotal; 1296 ivideo->current_vtotal = vtotal; 1297 ivideo->current_linelength = ivideo->video_linelength; 1298 ivideo->current_pixclock = var->pixclock; 1299 ivideo->current_refresh_rate = ivideo->refresh_rate; 1300 ivideo->sisfb_lastrates[ivideo->mode_no] = ivideo->refresh_rate; 1301 } 1302 1303 return 0; 1304 } 1305 1306 static void 1307 sisfb_set_base_CRT1(struct sis_video_info *ivideo, unsigned int base) 1308 { 1309 SiS_SetReg(SISSR, IND_SIS_PASSWORD, SIS_PASSWORD); 1310 1311 SiS_SetReg(SISCR, 0x0D, base & 0xFF); 1312 SiS_SetReg(SISCR, 0x0C, (base >> 8) & 0xFF); 1313 SiS_SetReg(SISSR, 0x0D, (base >> 16) & 0xFF); 1314 if(ivideo->sisvga_engine == SIS_315_VGA) { 1315 SiS_SetRegANDOR(SISSR, 0x37, 0xFE, (base >> 24) & 0x01); 1316 } 1317 } 1318 1319 static void 1320 sisfb_set_base_CRT2(struct sis_video_info *ivideo, unsigned int base) 1321 { 1322 if(ivideo->currentvbflags & VB_DISPTYPE_DISP2) { 1323 SiS_SetRegOR(SISPART1, ivideo->CRT2_write_enable, 0x01); 1324 SiS_SetReg(SISPART1, 0x06, (base & 0xFF)); 1325 SiS_SetReg(SISPART1, 0x05, ((base >> 8) & 0xFF)); 1326 SiS_SetReg(SISPART1, 0x04, ((base >> 16) & 0xFF)); 1327 if(ivideo->sisvga_engine == SIS_315_VGA) { 1328 SiS_SetRegANDOR(SISPART1, 0x02, 0x7F, ((base >> 24) & 0x01) << 7); 1329 } 1330 } 1331 } 1332 1333 static int 1334 sisfb_pan_var(struct sis_video_info *ivideo, struct fb_info *info, 1335 struct fb_var_screeninfo *var) 1336 { 1337 ivideo->current_base = var->yoffset * info->var.xres_virtual 1338 + var->xoffset; 1339 1340 /* calculate base bpp dep. */ 1341 switch (info->var.bits_per_pixel) { 1342 case 32: 1343 break; 1344 case 16: 1345 ivideo->current_base >>= 1; 1346 break; 1347 case 8: 1348 default: 1349 ivideo->current_base >>= 2; 1350 break; 1351 } 1352 1353 ivideo->current_base += (ivideo->video_offset >> 2); 1354 1355 sisfb_set_base_CRT1(ivideo, ivideo->current_base); 1356 sisfb_set_base_CRT2(ivideo, ivideo->current_base); 1357 1358 return 0; 1359 } 1360 1361 static int 1362 sisfb_open(struct fb_info *info, int user) 1363 { 1364 return 0; 1365 } 1366 1367 static int 1368 sisfb_release(struct fb_info *info, int user) 1369 { 1370 return 0; 1371 } 1372 1373 static int 1374 sisfb_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue, 1375 unsigned transp, struct fb_info *info) 1376 { 1377 struct sis_video_info *ivideo = (struct sis_video_info *)info->par; 1378 1379 if(regno >= sisfb_get_cmap_len(&info->var)) 1380 return 1; 1381 1382 switch(info->var.bits_per_pixel) { 1383 case 8: 1384 SiS_SetRegByte(SISDACA, regno); 1385 SiS_SetRegByte(SISDACD, (red >> 10)); 1386 SiS_SetRegByte(SISDACD, (green >> 10)); 1387 SiS_SetRegByte(SISDACD, (blue >> 10)); 1388 if(ivideo->currentvbflags & VB_DISPTYPE_DISP2) { 1389 SiS_SetRegByte(SISDAC2A, regno); 1390 SiS_SetRegByte(SISDAC2D, (red >> 8)); 1391 SiS_SetRegByte(SISDAC2D, (green >> 8)); 1392 SiS_SetRegByte(SISDAC2D, (blue >> 8)); 1393 } 1394 break; 1395 case 16: 1396 if (regno >= 16) 1397 break; 1398 1399 ((u32 *)(info->pseudo_palette))[regno] = 1400 (red & 0xf800) | 1401 ((green & 0xfc00) >> 5) | 1402 ((blue & 0xf800) >> 11); 1403 break; 1404 case 32: 1405 if (regno >= 16) 1406 break; 1407 1408 red >>= 8; 1409 green >>= 8; 1410 blue >>= 8; 1411 ((u32 *)(info->pseudo_palette))[regno] = 1412 (red << 16) | (green << 8) | (blue); 1413 break; 1414 } 1415 return 0; 1416 } 1417 1418 static int 1419 sisfb_set_par(struct fb_info *info) 1420 { 1421 int err; 1422 1423 if((err = sisfb_do_set_var(&info->var, 1, info))) 1424 return err; 1425 1426 sisfb_get_fix(&info->fix, -1, info); 1427 1428 return 0; 1429 } 1430 1431 static int 1432 sisfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) 1433 { 1434 struct sis_video_info *ivideo = (struct sis_video_info *)info->par; 1435 unsigned int htotal = 0, vtotal = 0, myrateindex = 0; 1436 unsigned int drate = 0, hrate = 0, maxyres; 1437 int found_mode = 0; 1438 int refresh_rate, search_idx, tidx; 1439 bool recalc_clock = false; 1440 u32 pixclock; 1441 1442 htotal = var->left_margin + var->xres + var->right_margin + var->hsync_len; 1443 1444 vtotal = var->upper_margin + var->lower_margin + var->vsync_len; 1445 1446 if (!var->pixclock) 1447 return -EINVAL; 1448 pixclock = var->pixclock; 1449 1450 if((var->vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED) { 1451 vtotal += var->yres; 1452 vtotal <<= 1; 1453 } else if((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) { 1454 vtotal += var->yres; 1455 vtotal <<= 2; 1456 } else if((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) { 1457 vtotal += var->yres; 1458 vtotal <<= 1; 1459 } else 1460 vtotal += var->yres; 1461 1462 if(!(htotal) || !(vtotal)) { 1463 SISFAIL("sisfb: no valid timing data"); 1464 } 1465 1466 search_idx = 0; 1467 while( (sisbios_mode[search_idx].mode_no[0] != 0) && 1468 (sisbios_mode[search_idx].xres <= var->xres) ) { 1469 if( (sisbios_mode[search_idx].xres == var->xres) && 1470 (sisbios_mode[search_idx].yres == var->yres) && 1471 (sisbios_mode[search_idx].bpp == var->bits_per_pixel)) { 1472 if((tidx = sisfb_validate_mode(ivideo, search_idx, 1473 ivideo->currentvbflags)) > 0) { 1474 found_mode = 1; 1475 search_idx = tidx; 1476 break; 1477 } 1478 } 1479 search_idx++; 1480 } 1481 1482 if(!found_mode) { 1483 search_idx = 0; 1484 while(sisbios_mode[search_idx].mode_no[0] != 0) { 1485 if( (var->xres <= sisbios_mode[search_idx].xres) && 1486 (var->yres <= sisbios_mode[search_idx].yres) && 1487 (var->bits_per_pixel == sisbios_mode[search_idx].bpp) ) { 1488 if((tidx = sisfb_validate_mode(ivideo,search_idx, 1489 ivideo->currentvbflags)) > 0) { 1490 found_mode = 1; 1491 search_idx = tidx; 1492 break; 1493 } 1494 } 1495 search_idx++; 1496 } 1497 if(found_mode) { 1498 printk(KERN_DEBUG 1499 "sisfb: Adapted from %dx%dx%d to %dx%dx%d\n", 1500 var->xres, var->yres, var->bits_per_pixel, 1501 sisbios_mode[search_idx].xres, 1502 sisbios_mode[search_idx].yres, 1503 var->bits_per_pixel); 1504 var->xres = sisbios_mode[search_idx].xres; 1505 var->yres = sisbios_mode[search_idx].yres; 1506 } else { 1507 printk(KERN_ERR 1508 "sisfb: Failed to find supported mode near %dx%dx%d\n", 1509 var->xres, var->yres, var->bits_per_pixel); 1510 return -EINVAL; 1511 } 1512 } 1513 1514 if( ((ivideo->vbflags2 & VB2_LVDS) || 1515 ((ivideo->vbflags2 & VB2_30xBDH) && (ivideo->currentvbflags & CRT2_LCD))) && 1516 (var->bits_per_pixel == 8) ) { 1517 /* Slave modes on LVDS and 301B-DH */ 1518 refresh_rate = 60; 1519 recalc_clock = true; 1520 } else if( (ivideo->current_htotal == htotal) && 1521 (ivideo->current_vtotal == vtotal) && 1522 (ivideo->current_pixclock == pixclock) ) { 1523 /* x=x & y=y & c=c -> assume depth change */ 1524 drate = 1000000000 / pixclock; 1525 hrate = (drate * 1000) / htotal; 1526 refresh_rate = (unsigned int) (hrate * 2 / vtotal); 1527 } else if( ( (ivideo->current_htotal != htotal) || 1528 (ivideo->current_vtotal != vtotal) ) && 1529 (ivideo->current_pixclock == var->pixclock) ) { 1530 /* x!=x | y!=y & c=c -> invalid pixclock */ 1531 if(ivideo->sisfb_lastrates[sisbios_mode[search_idx].mode_no[ivideo->mni]]) { 1532 refresh_rate = 1533 ivideo->sisfb_lastrates[sisbios_mode[search_idx].mode_no[ivideo->mni]]; 1534 } else if(ivideo->sisfb_parm_rate != -1) { 1535 /* Sic, sisfb_parm_rate - want to know originally desired rate here */ 1536 refresh_rate = ivideo->sisfb_parm_rate; 1537 } else { 1538 refresh_rate = 60; 1539 } 1540 recalc_clock = true; 1541 } else if((pixclock) && (htotal) && (vtotal)) { 1542 drate = 1000000000 / pixclock; 1543 hrate = (drate * 1000) / htotal; 1544 refresh_rate = (unsigned int) (hrate * 2 / vtotal); 1545 } else if(ivideo->current_refresh_rate) { 1546 refresh_rate = ivideo->current_refresh_rate; 1547 recalc_clock = true; 1548 } else { 1549 refresh_rate = 60; 1550 recalc_clock = true; 1551 } 1552 1553 myrateindex = sisfb_search_refresh_rate(ivideo, refresh_rate, search_idx); 1554 1555 /* Eventually recalculate timing and clock */ 1556 if(recalc_clock) { 1557 if(!myrateindex) myrateindex = sisbios_mode[search_idx].rate_idx; 1558 var->pixclock = (u32) (1000000000 / sisfb_mode_rate_to_dclock(&ivideo->SiS_Pr, 1559 sisbios_mode[search_idx].mode_no[ivideo->mni], 1560 myrateindex)); 1561 sisfb_mode_rate_to_ddata(&ivideo->SiS_Pr, 1562 sisbios_mode[search_idx].mode_no[ivideo->mni], 1563 myrateindex, var); 1564 if((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) { 1565 var->pixclock <<= 1; 1566 } 1567 } 1568 1569 if(ivideo->sisfb_thismonitor.datavalid) { 1570 if(!sisfb_verify_rate(ivideo, &ivideo->sisfb_thismonitor, search_idx, 1571 myrateindex, refresh_rate)) { 1572 printk(KERN_INFO 1573 "sisfb: WARNING: Refresh rate exceeds monitor specs!\n"); 1574 } 1575 } 1576 1577 /* Adapt RGB settings */ 1578 sisfb_bpp_to_var(ivideo, var); 1579 1580 if(var->xres > var->xres_virtual) 1581 var->xres_virtual = var->xres; 1582 1583 if(ivideo->sisfb_ypan) { 1584 maxyres = sisfb_calc_maxyres(ivideo, var); 1585 if(ivideo->sisfb_max) { 1586 var->yres_virtual = maxyres; 1587 } else { 1588 if(var->yres_virtual > maxyres) { 1589 var->yres_virtual = maxyres; 1590 } 1591 } 1592 if(var->yres_virtual <= var->yres) { 1593 var->yres_virtual = var->yres; 1594 } 1595 } else { 1596 if(var->yres != var->yres_virtual) { 1597 var->yres_virtual = var->yres; 1598 } 1599 var->xoffset = 0; 1600 var->yoffset = 0; 1601 } 1602 1603 /* Truncate offsets to maximum if too high */ 1604 if(var->xoffset > var->xres_virtual - var->xres) { 1605 var->xoffset = var->xres_virtual - var->xres - 1; 1606 } 1607 1608 if(var->yoffset > var->yres_virtual - var->yres) { 1609 var->yoffset = var->yres_virtual - var->yres - 1; 1610 } 1611 1612 /* Set everything else to 0 */ 1613 var->red.msb_right = 1614 var->green.msb_right = 1615 var->blue.msb_right = 1616 var->transp.offset = 1617 var->transp.length = 1618 var->transp.msb_right = 0; 1619 1620 return 0; 1621 } 1622 1623 static int 1624 sisfb_pan_display(struct fb_var_screeninfo *var, struct fb_info* info) 1625 { 1626 struct sis_video_info *ivideo = (struct sis_video_info *)info->par; 1627 int err; 1628 1629 if (var->vmode & FB_VMODE_YWRAP) 1630 return -EINVAL; 1631 1632 if (var->xoffset + info->var.xres > info->var.xres_virtual || 1633 var->yoffset + info->var.yres > info->var.yres_virtual) 1634 return -EINVAL; 1635 1636 err = sisfb_pan_var(ivideo, info, var); 1637 if (err < 0) 1638 return err; 1639 1640 info->var.xoffset = var->xoffset; 1641 info->var.yoffset = var->yoffset; 1642 1643 return 0; 1644 } 1645 1646 static int 1647 sisfb_blank(int blank, struct fb_info *info) 1648 { 1649 struct sis_video_info *ivideo = (struct sis_video_info *)info->par; 1650 1651 return sisfb_myblank(ivideo, blank); 1652 } 1653 1654 /* ----------- FBDev related routines for all series ---------- */ 1655 1656 static int sisfb_ioctl(struct fb_info *info, unsigned int cmd, 1657 unsigned long arg) 1658 { 1659 struct sis_video_info *ivideo = (struct sis_video_info *)info->par; 1660 struct sis_memreq sismemreq; 1661 struct fb_vblank sisvbblank; 1662 u32 gpu32 = 0; 1663 #ifndef __user 1664 #define __user 1665 #endif 1666 u32 __user *argp = (u32 __user *)arg; 1667 1668 switch(cmd) { 1669 case FBIO_ALLOC: 1670 if(!capable(CAP_SYS_RAWIO)) 1671 return -EPERM; 1672 1673 if(copy_from_user(&sismemreq, (void __user *)arg, sizeof(sismemreq))) 1674 return -EFAULT; 1675 1676 sis_malloc(&sismemreq); 1677 1678 if(copy_to_user((void __user *)arg, &sismemreq, sizeof(sismemreq))) { 1679 sis_free((u32)sismemreq.offset); 1680 return -EFAULT; 1681 } 1682 break; 1683 1684 case FBIO_FREE: 1685 if(!capable(CAP_SYS_RAWIO)) 1686 return -EPERM; 1687 1688 if(get_user(gpu32, argp)) 1689 return -EFAULT; 1690 1691 sis_free(gpu32); 1692 break; 1693 1694 case FBIOGET_VBLANK: 1695 1696 memset(&sisvbblank, 0, sizeof(struct fb_vblank)); 1697 1698 sisvbblank.count = 0; 1699 sisvbblank.flags = sisfb_setupvbblankflags(ivideo, &sisvbblank.vcount, &sisvbblank.hcount); 1700 1701 if(copy_to_user((void __user *)arg, &sisvbblank, sizeof(sisvbblank))) 1702 return -EFAULT; 1703 1704 break; 1705 1706 case SISFB_GET_INFO_SIZE: 1707 return put_user(sizeof(struct sisfb_info), argp); 1708 1709 case SISFB_GET_INFO_OLD: 1710 if(ivideo->warncount++ < 10) 1711 printk(KERN_INFO 1712 "sisfb: Deprecated ioctl call received - update your application!\n"); 1713 fallthrough; 1714 case SISFB_GET_INFO: /* For communication with X driver */ 1715 ivideo->sisfb_infoblock.sisfb_id = SISFB_ID; 1716 ivideo->sisfb_infoblock.sisfb_version = VER_MAJOR; 1717 ivideo->sisfb_infoblock.sisfb_revision = VER_MINOR; 1718 ivideo->sisfb_infoblock.sisfb_patchlevel = VER_LEVEL; 1719 ivideo->sisfb_infoblock.chip_id = ivideo->chip_id; 1720 ivideo->sisfb_infoblock.sisfb_pci_vendor = ivideo->chip_vendor; 1721 ivideo->sisfb_infoblock.memory = ivideo->video_size / 1024; 1722 ivideo->sisfb_infoblock.heapstart = ivideo->heapstart / 1024; 1723 if(ivideo->modechanged) { 1724 ivideo->sisfb_infoblock.fbvidmode = ivideo->mode_no; 1725 } else { 1726 ivideo->sisfb_infoblock.fbvidmode = ivideo->modeprechange; 1727 } 1728 ivideo->sisfb_infoblock.sisfb_caps = ivideo->caps; 1729 ivideo->sisfb_infoblock.sisfb_tqlen = ivideo->cmdQueueSize / 1024; 1730 ivideo->sisfb_infoblock.sisfb_pcibus = ivideo->pcibus; 1731 ivideo->sisfb_infoblock.sisfb_pcislot = ivideo->pcislot; 1732 ivideo->sisfb_infoblock.sisfb_pcifunc = ivideo->pcifunc; 1733 ivideo->sisfb_infoblock.sisfb_lcdpdc = ivideo->detectedpdc; 1734 ivideo->sisfb_infoblock.sisfb_lcdpdca = ivideo->detectedpdca; 1735 ivideo->sisfb_infoblock.sisfb_lcda = ivideo->detectedlcda; 1736 ivideo->sisfb_infoblock.sisfb_vbflags = ivideo->vbflags; 1737 ivideo->sisfb_infoblock.sisfb_currentvbflags = ivideo->currentvbflags; 1738 ivideo->sisfb_infoblock.sisfb_scalelcd = ivideo->SiS_Pr.UsePanelScaler; 1739 ivideo->sisfb_infoblock.sisfb_specialtiming = ivideo->SiS_Pr.SiS_CustomT; 1740 ivideo->sisfb_infoblock.sisfb_haveemi = ivideo->SiS_Pr.HaveEMI ? 1 : 0; 1741 ivideo->sisfb_infoblock.sisfb_haveemilcd = ivideo->SiS_Pr.HaveEMILCD ? 1 : 0; 1742 ivideo->sisfb_infoblock.sisfb_emi30 = ivideo->SiS_Pr.EMI_30; 1743 ivideo->sisfb_infoblock.sisfb_emi31 = ivideo->SiS_Pr.EMI_31; 1744 ivideo->sisfb_infoblock.sisfb_emi32 = ivideo->SiS_Pr.EMI_32; 1745 ivideo->sisfb_infoblock.sisfb_emi33 = ivideo->SiS_Pr.EMI_33; 1746 ivideo->sisfb_infoblock.sisfb_tvxpos = (u16)(ivideo->tvxpos + 32); 1747 ivideo->sisfb_infoblock.sisfb_tvypos = (u16)(ivideo->tvypos + 32); 1748 ivideo->sisfb_infoblock.sisfb_heapsize = ivideo->sisfb_heap_size / 1024; 1749 ivideo->sisfb_infoblock.sisfb_videooffset = ivideo->video_offset; 1750 ivideo->sisfb_infoblock.sisfb_curfstn = ivideo->curFSTN; 1751 ivideo->sisfb_infoblock.sisfb_curdstn = ivideo->curDSTN; 1752 ivideo->sisfb_infoblock.sisfb_vbflags2 = ivideo->vbflags2; 1753 ivideo->sisfb_infoblock.sisfb_can_post = ivideo->sisfb_can_post ? 1 : 0; 1754 ivideo->sisfb_infoblock.sisfb_card_posted = ivideo->sisfb_card_posted ? 1 : 0; 1755 ivideo->sisfb_infoblock.sisfb_was_boot_device = ivideo->sisfb_was_boot_device ? 1 : 0; 1756 1757 if(copy_to_user((void __user *)arg, &ivideo->sisfb_infoblock, 1758 sizeof(ivideo->sisfb_infoblock))) 1759 return -EFAULT; 1760 1761 break; 1762 1763 case SISFB_GET_VBRSTATUS_OLD: 1764 if(ivideo->warncount++ < 10) 1765 printk(KERN_INFO 1766 "sisfb: Deprecated ioctl call received - update your application!\n"); 1767 fallthrough; 1768 case SISFB_GET_VBRSTATUS: 1769 if(sisfb_CheckVBRetrace(ivideo)) 1770 return put_user((u32)1, argp); 1771 else 1772 return put_user((u32)0, argp); 1773 1774 case SISFB_GET_AUTOMAXIMIZE_OLD: 1775 if(ivideo->warncount++ < 10) 1776 printk(KERN_INFO 1777 "sisfb: Deprecated ioctl call received - update your application!\n"); 1778 fallthrough; 1779 case SISFB_GET_AUTOMAXIMIZE: 1780 if(ivideo->sisfb_max) 1781 return put_user((u32)1, argp); 1782 else 1783 return put_user((u32)0, argp); 1784 1785 case SISFB_SET_AUTOMAXIMIZE_OLD: 1786 if(ivideo->warncount++ < 10) 1787 printk(KERN_INFO 1788 "sisfb: Deprecated ioctl call received - update your application!\n"); 1789 fallthrough; 1790 case SISFB_SET_AUTOMAXIMIZE: 1791 if(get_user(gpu32, argp)) 1792 return -EFAULT; 1793 1794 ivideo->sisfb_max = (gpu32) ? 1 : 0; 1795 break; 1796 1797 case SISFB_SET_TVPOSOFFSET: 1798 if(get_user(gpu32, argp)) 1799 return -EFAULT; 1800 1801 sisfb_set_TVxposoffset(ivideo, ((int)(gpu32 >> 16)) - 32); 1802 sisfb_set_TVyposoffset(ivideo, ((int)(gpu32 & 0xffff)) - 32); 1803 break; 1804 1805 case SISFB_GET_TVPOSOFFSET: 1806 return put_user((u32)(((ivideo->tvxpos+32)<<16)|((ivideo->tvypos+32)&0xffff)), 1807 argp); 1808 1809 case SISFB_COMMAND: 1810 if(copy_from_user(&ivideo->sisfb_command, (void __user *)arg, 1811 sizeof(struct sisfb_cmd))) 1812 return -EFAULT; 1813 1814 sisfb_handle_command(ivideo, &ivideo->sisfb_command); 1815 1816 if(copy_to_user((void __user *)arg, &ivideo->sisfb_command, 1817 sizeof(struct sisfb_cmd))) 1818 return -EFAULT; 1819 1820 break; 1821 1822 case SISFB_SET_LOCK: 1823 if(get_user(gpu32, argp)) 1824 return -EFAULT; 1825 1826 ivideo->sisfblocked = (gpu32) ? 1 : 0; 1827 break; 1828 1829 default: 1830 #ifdef SIS_NEW_CONFIG_COMPAT 1831 return -ENOIOCTLCMD; 1832 #else 1833 return -EINVAL; 1834 #endif 1835 } 1836 return 0; 1837 } 1838 1839 static int 1840 sisfb_get_fix(struct fb_fix_screeninfo *fix, int con, struct fb_info *info) 1841 { 1842 struct sis_video_info *ivideo = (struct sis_video_info *)info->par; 1843 1844 memset(fix, 0, sizeof(struct fb_fix_screeninfo)); 1845 1846 strscpy(fix->id, ivideo->myid, sizeof(fix->id)); 1847 1848 mutex_lock(&info->mm_lock); 1849 fix->smem_start = ivideo->video_base + ivideo->video_offset; 1850 fix->smem_len = ivideo->sisfb_mem; 1851 mutex_unlock(&info->mm_lock); 1852 fix->type = FB_TYPE_PACKED_PIXELS; 1853 fix->type_aux = 0; 1854 fix->visual = (ivideo->video_bpp == 8) ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR; 1855 fix->xpanstep = 1; 1856 fix->ypanstep = (ivideo->sisfb_ypan) ? 1 : 0; 1857 fix->ywrapstep = 0; 1858 fix->line_length = ivideo->video_linelength; 1859 fix->mmio_start = ivideo->mmio_base; 1860 fix->mmio_len = ivideo->mmio_size; 1861 if(ivideo->sisvga_engine == SIS_300_VGA) { 1862 fix->accel = FB_ACCEL_SIS_GLAMOUR; 1863 } else if((ivideo->chip == SIS_330) || 1864 (ivideo->chip == SIS_760) || 1865 (ivideo->chip == SIS_761)) { 1866 fix->accel = FB_ACCEL_SIS_XABRE; 1867 } else if(ivideo->chip == XGI_20) { 1868 fix->accel = FB_ACCEL_XGI_VOLARI_Z; 1869 } else if(ivideo->chip >= XGI_40) { 1870 fix->accel = FB_ACCEL_XGI_VOLARI_V; 1871 } else { 1872 fix->accel = FB_ACCEL_SIS_GLAMOUR_2; 1873 } 1874 1875 return 0; 1876 } 1877 1878 /* ---------------- fb_ops structures ----------------- */ 1879 1880 static const struct fb_ops sisfb_ops = { 1881 .owner = THIS_MODULE, 1882 .fb_open = sisfb_open, 1883 .fb_release = sisfb_release, 1884 __FB_DEFAULT_IOMEM_OPS_RDWR, 1885 .fb_check_var = sisfb_check_var, 1886 .fb_set_par = sisfb_set_par, 1887 .fb_setcolreg = sisfb_setcolreg, 1888 .fb_pan_display = sisfb_pan_display, 1889 .fb_blank = sisfb_blank, 1890 .fb_fillrect = fbcon_sis_fillrect, 1891 .fb_copyarea = fbcon_sis_copyarea, 1892 .fb_imageblit = cfb_imageblit, 1893 .fb_sync = fbcon_sis_sync, 1894 #ifdef SIS_NEW_CONFIG_COMPAT 1895 .fb_compat_ioctl= sisfb_ioctl, 1896 #endif 1897 .fb_ioctl = sisfb_ioctl, 1898 __FB_DEFAULT_IOMEM_OPS_MMAP, 1899 }; 1900 1901 /* ---------------- Chip generation dependent routines ---------------- */ 1902 1903 static struct pci_dev *sisfb_get_northbridge(int basechipid) 1904 { 1905 struct pci_dev *pdev = NULL; 1906 int nbridgenum, nbridgeidx, i; 1907 static const unsigned short nbridgeids[] = { 1908 PCI_DEVICE_ID_SI_540, /* for SiS 540 VGA */ 1909 PCI_DEVICE_ID_SI_630, /* for SiS 630/730 VGA */ 1910 PCI_DEVICE_ID_SI_730, 1911 PCI_DEVICE_ID_SI_550, /* for SiS 550 VGA */ 1912 PCI_DEVICE_ID_SI_650, /* for SiS 650/651/740 VGA */ 1913 PCI_DEVICE_ID_SI_651, 1914 PCI_DEVICE_ID_SI_740, 1915 PCI_DEVICE_ID_SI_661, /* for SiS 661/741/660/760/761 VGA */ 1916 PCI_DEVICE_ID_SI_741, 1917 PCI_DEVICE_ID_SI_660, 1918 PCI_DEVICE_ID_SI_760, 1919 PCI_DEVICE_ID_SI_761 1920 }; 1921 1922 switch(basechipid) { 1923 #ifdef CONFIG_FB_SIS_300 1924 case SIS_540: nbridgeidx = 0; nbridgenum = 1; break; 1925 case SIS_630: nbridgeidx = 1; nbridgenum = 2; break; 1926 #endif 1927 #ifdef CONFIG_FB_SIS_315 1928 case SIS_550: nbridgeidx = 3; nbridgenum = 1; break; 1929 case SIS_650: nbridgeidx = 4; nbridgenum = 3; break; 1930 case SIS_660: nbridgeidx = 7; nbridgenum = 5; break; 1931 #endif 1932 default: return NULL; 1933 } 1934 for(i = 0; i < nbridgenum; i++) { 1935 if((pdev = pci_get_device(PCI_VENDOR_ID_SI, 1936 nbridgeids[nbridgeidx+i], NULL))) 1937 break; 1938 } 1939 return pdev; 1940 } 1941 1942 static int sisfb_get_dram_size(struct sis_video_info *ivideo) 1943 { 1944 #if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315) 1945 u8 reg; 1946 #endif 1947 1948 ivideo->video_size = 0; 1949 ivideo->UMAsize = ivideo->LFBsize = 0; 1950 1951 switch(ivideo->chip) { 1952 #ifdef CONFIG_FB_SIS_300 1953 case SIS_300: 1954 reg = SiS_GetReg(SISSR, 0x14); 1955 ivideo->video_size = ((reg & 0x3F) + 1) << 20; 1956 break; 1957 case SIS_540: 1958 case SIS_630: 1959 case SIS_730: 1960 if(!ivideo->nbridge) 1961 return -1; 1962 pci_read_config_byte(ivideo->nbridge, 0x63, ®); 1963 ivideo->video_size = 1 << (((reg & 0x70) >> 4) + 21); 1964 break; 1965 #endif 1966 #ifdef CONFIG_FB_SIS_315 1967 case SIS_315H: 1968 case SIS_315PRO: 1969 case SIS_315: 1970 reg = SiS_GetReg(SISSR, 0x14); 1971 ivideo->video_size = (1 << ((reg & 0xf0) >> 4)) << 20; 1972 switch((reg >> 2) & 0x03) { 1973 case 0x01: 1974 case 0x03: 1975 ivideo->video_size <<= 1; 1976 break; 1977 case 0x02: 1978 ivideo->video_size += (ivideo->video_size/2); 1979 } 1980 break; 1981 case SIS_330: 1982 reg = SiS_GetReg(SISSR, 0x14); 1983 ivideo->video_size = (1 << ((reg & 0xf0) >> 4)) << 20; 1984 if(reg & 0x0c) ivideo->video_size <<= 1; 1985 break; 1986 case SIS_550: 1987 case SIS_650: 1988 case SIS_740: 1989 reg = SiS_GetReg(SISSR, 0x14); 1990 ivideo->video_size = (((reg & 0x3f) + 1) << 2) << 20; 1991 break; 1992 case SIS_661: 1993 case SIS_741: 1994 reg = SiS_GetReg(SISCR, 0x79); 1995 ivideo->video_size = (1 << ((reg & 0xf0) >> 4)) << 20; 1996 break; 1997 case SIS_660: 1998 case SIS_760: 1999 case SIS_761: 2000 reg = SiS_GetReg(SISCR, 0x79); 2001 reg = (reg & 0xf0) >> 4; 2002 if(reg) { 2003 ivideo->video_size = (1 << reg) << 20; 2004 ivideo->UMAsize = ivideo->video_size; 2005 } 2006 reg = SiS_GetReg(SISCR, 0x78); 2007 reg &= 0x30; 2008 if(reg) { 2009 if(reg == 0x10) { 2010 ivideo->LFBsize = (32 << 20); 2011 } else { 2012 ivideo->LFBsize = (64 << 20); 2013 } 2014 ivideo->video_size += ivideo->LFBsize; 2015 } 2016 break; 2017 case SIS_340: 2018 case XGI_20: 2019 case XGI_40: 2020 reg = SiS_GetReg(SISSR, 0x14); 2021 ivideo->video_size = (1 << ((reg & 0xf0) >> 4)) << 20; 2022 if(ivideo->chip != XGI_20) { 2023 reg = (reg & 0x0c) >> 2; 2024 if(ivideo->revision_id == 2) { 2025 if(reg & 0x01) reg = 0x02; 2026 else reg = 0x00; 2027 } 2028 if(reg == 0x02) ivideo->video_size <<= 1; 2029 else if(reg == 0x03) ivideo->video_size <<= 2; 2030 } 2031 break; 2032 #endif 2033 default: 2034 return -1; 2035 } 2036 return 0; 2037 } 2038 2039 /* -------------- video bridge device detection --------------- */ 2040 2041 static void sisfb_detect_VB_connect(struct sis_video_info *ivideo) 2042 { 2043 u8 cr32, temp; 2044 2045 /* No CRT2 on XGI Z7 */ 2046 if(ivideo->chip == XGI_20) { 2047 ivideo->sisfb_crt1off = 0; 2048 return; 2049 } 2050 2051 #ifdef CONFIG_FB_SIS_300 2052 if(ivideo->sisvga_engine == SIS_300_VGA) { 2053 temp = SiS_GetReg(SISSR, 0x17); 2054 if((temp & 0x0F) && (ivideo->chip != SIS_300)) { 2055 /* PAL/NTSC is stored on SR16 on such machines */ 2056 if(!(ivideo->vbflags & (TV_PAL | TV_NTSC | TV_PALM | TV_PALN))) { 2057 temp = SiS_GetReg(SISSR, 0x16); 2058 if(temp & 0x20) 2059 ivideo->vbflags |= TV_PAL; 2060 else 2061 ivideo->vbflags |= TV_NTSC; 2062 } 2063 } 2064 } 2065 #endif 2066 2067 cr32 = SiS_GetReg(SISCR, 0x32); 2068 2069 if(cr32 & SIS_CRT1) { 2070 ivideo->sisfb_crt1off = 0; 2071 } else { 2072 ivideo->sisfb_crt1off = (cr32 & 0xDF) ? 1 : 0; 2073 } 2074 2075 ivideo->vbflags &= ~(CRT2_TV | CRT2_LCD | CRT2_VGA); 2076 2077 if(cr32 & SIS_VB_TV) ivideo->vbflags |= CRT2_TV; 2078 if(cr32 & SIS_VB_LCD) ivideo->vbflags |= CRT2_LCD; 2079 if(cr32 & SIS_VB_CRT2) ivideo->vbflags |= CRT2_VGA; 2080 2081 /* Check given parms for hardware compatibility. 2082 * (Cannot do this in the search_xx routines since we don't 2083 * know what hardware we are running on then) 2084 */ 2085 2086 if(ivideo->chip != SIS_550) { 2087 ivideo->sisfb_dstn = ivideo->sisfb_fstn = 0; 2088 } 2089 2090 if(ivideo->sisfb_tvplug != -1) { 2091 if( (ivideo->sisvga_engine != SIS_315_VGA) || 2092 (!(ivideo->vbflags2 & VB2_SISYPBPRBRIDGE)) ) { 2093 if(ivideo->sisfb_tvplug & TV_YPBPR) { 2094 ivideo->sisfb_tvplug = -1; 2095 printk(KERN_ERR "sisfb: YPbPr not supported\n"); 2096 } 2097 } 2098 } 2099 if(ivideo->sisfb_tvplug != -1) { 2100 if( (ivideo->sisvga_engine != SIS_315_VGA) || 2101 (!(ivideo->vbflags2 & VB2_SISHIVISIONBRIDGE)) ) { 2102 if(ivideo->sisfb_tvplug & TV_HIVISION) { 2103 ivideo->sisfb_tvplug = -1; 2104 printk(KERN_ERR "sisfb: HiVision not supported\n"); 2105 } 2106 } 2107 } 2108 if(ivideo->sisfb_tvstd != -1) { 2109 if( (!(ivideo->vbflags2 & VB2_SISBRIDGE)) && 2110 (!((ivideo->sisvga_engine == SIS_315_VGA) && 2111 (ivideo->vbflags2 & VB2_CHRONTEL))) ) { 2112 if(ivideo->sisfb_tvstd & (TV_PALM | TV_PALN | TV_NTSCJ)) { 2113 ivideo->sisfb_tvstd = -1; 2114 printk(KERN_ERR "sisfb: PALM/PALN/NTSCJ not supported\n"); 2115 } 2116 } 2117 } 2118 2119 /* Detect/set TV plug & type */ 2120 if(ivideo->sisfb_tvplug != -1) { 2121 ivideo->vbflags |= ivideo->sisfb_tvplug; 2122 } else { 2123 if(cr32 & SIS_VB_YPBPR) ivideo->vbflags |= (TV_YPBPR|TV_YPBPR525I); /* default: 480i */ 2124 else if(cr32 & SIS_VB_HIVISION) ivideo->vbflags |= TV_HIVISION; 2125 else if(cr32 & SIS_VB_SCART) ivideo->vbflags |= TV_SCART; 2126 else { 2127 if(cr32 & SIS_VB_SVIDEO) ivideo->vbflags |= TV_SVIDEO; 2128 if(cr32 & SIS_VB_COMPOSITE) ivideo->vbflags |= TV_AVIDEO; 2129 } 2130 } 2131 2132 if(!(ivideo->vbflags & (TV_YPBPR | TV_HIVISION))) { 2133 if(ivideo->sisfb_tvstd != -1) { 2134 ivideo->vbflags &= ~(TV_NTSC | TV_PAL | TV_PALM | TV_PALN | TV_NTSCJ); 2135 ivideo->vbflags |= ivideo->sisfb_tvstd; 2136 } 2137 if(ivideo->vbflags & TV_SCART) { 2138 ivideo->vbflags &= ~(TV_NTSC | TV_PALM | TV_PALN | TV_NTSCJ); 2139 ivideo->vbflags |= TV_PAL; 2140 } 2141 if(!(ivideo->vbflags & (TV_PAL | TV_NTSC | TV_PALM | TV_PALN | TV_NTSCJ))) { 2142 if(ivideo->sisvga_engine == SIS_300_VGA) { 2143 temp = SiS_GetReg(SISSR, 0x38); 2144 if(temp & 0x01) ivideo->vbflags |= TV_PAL; 2145 else ivideo->vbflags |= TV_NTSC; 2146 } else if((ivideo->chip <= SIS_315PRO) || (ivideo->chip >= SIS_330)) { 2147 temp = SiS_GetReg(SISSR, 0x38); 2148 if(temp & 0x01) ivideo->vbflags |= TV_PAL; 2149 else ivideo->vbflags |= TV_NTSC; 2150 } else { 2151 temp = SiS_GetReg(SISCR, 0x79); 2152 if(temp & 0x20) ivideo->vbflags |= TV_PAL; 2153 else ivideo->vbflags |= TV_NTSC; 2154 } 2155 } 2156 } 2157 2158 /* Copy forceCRT1 option to CRT1off if option is given */ 2159 if(ivideo->sisfb_forcecrt1 != -1) { 2160 ivideo->sisfb_crt1off = (ivideo->sisfb_forcecrt1) ? 0 : 1; 2161 } 2162 } 2163 2164 /* ------------------ Sensing routines ------------------ */ 2165 2166 static bool sisfb_test_DDC1(struct sis_video_info *ivideo) 2167 { 2168 unsigned short old; 2169 int count = 48; 2170 2171 old = SiS_ReadDDC1Bit(&ivideo->SiS_Pr); 2172 do { 2173 if(old != SiS_ReadDDC1Bit(&ivideo->SiS_Pr)) break; 2174 } while(count--); 2175 return (count != -1); 2176 } 2177 2178 static void sisfb_sense_crt1(struct sis_video_info *ivideo) 2179 { 2180 bool mustwait = false; 2181 u8 sr1F, cr17; 2182 #ifdef CONFIG_FB_SIS_315 2183 u8 cr63 = 0; 2184 #endif 2185 u16 temp = 0xffff; 2186 int i; 2187 2188 sr1F = SiS_GetReg(SISSR, 0x1F); 2189 SiS_SetRegOR(SISSR, 0x1F, 0x04); 2190 SiS_SetRegAND(SISSR, 0x1F, 0x3F); 2191 2192 if (sr1F & 0xc0) 2193 mustwait = true; 2194 2195 #ifdef CONFIG_FB_SIS_315 2196 if (ivideo->sisvga_engine == SIS_315_VGA) { 2197 cr63 = SiS_GetReg(SISCR, ivideo->SiS_Pr.SiS_MyCR63); 2198 cr63 &= 0x40; 2199 SiS_SetRegAND(SISCR, ivideo->SiS_Pr.SiS_MyCR63, 0xBF); 2200 } 2201 #endif 2202 2203 cr17 = SiS_GetReg(SISCR, 0x17); 2204 cr17 &= 0x80; 2205 2206 if (!cr17) { 2207 SiS_SetRegOR(SISCR, 0x17, 0x80); 2208 mustwait = true; 2209 SiS_SetReg(SISSR, 0x00, 0x01); 2210 SiS_SetReg(SISSR, 0x00, 0x03); 2211 } 2212 2213 if (mustwait) { 2214 for (i = 0; i < 10; i++) 2215 sisfbwaitretracecrt1(ivideo); 2216 } 2217 #ifdef CONFIG_FB_SIS_315 2218 if (ivideo->chip >= SIS_330) { 2219 SiS_SetRegAND(SISCR, 0x32, ~0x20); 2220 if (ivideo->chip >= SIS_340) 2221 SiS_SetReg(SISCR, 0x57, 0x4a); 2222 else 2223 SiS_SetReg(SISCR, 0x57, 0x5f); 2224 2225 SiS_SetRegOR(SISCR, 0x53, 0x02); 2226 while ((SiS_GetRegByte(SISINPSTAT)) & 0x01) 2227 break; 2228 while (!((SiS_GetRegByte(SISINPSTAT)) & 0x01)) 2229 break; 2230 if ((SiS_GetRegByte(SISMISCW)) & 0x10) 2231 temp = 1; 2232 2233 SiS_SetRegAND(SISCR, 0x53, 0xfd); 2234 SiS_SetRegAND(SISCR, 0x57, 0x00); 2235 } 2236 #endif 2237 2238 if (temp == 0xffff) { 2239 i = 3; 2240 2241 do { 2242 temp = SiS_HandleDDC(&ivideo->SiS_Pr, ivideo->vbflags, 2243 ivideo->sisvga_engine, 0, 0, NULL, ivideo->vbflags2); 2244 } while (((temp == 0) || (temp == 0xffff)) && i--); 2245 2246 if ((temp == 0) || (temp == 0xffff)) { 2247 if (sisfb_test_DDC1(ivideo)) 2248 temp = 1; 2249 } 2250 } 2251 2252 if ((temp) && (temp != 0xffff)) 2253 SiS_SetRegOR(SISCR, 0x32, 0x20); 2254 2255 #ifdef CONFIG_FB_SIS_315 2256 if (ivideo->sisvga_engine == SIS_315_VGA) 2257 SiS_SetRegANDOR(SISCR, ivideo->SiS_Pr.SiS_MyCR63, 0xBF, cr63); 2258 #endif 2259 2260 SiS_SetRegANDOR(SISCR, 0x17, 0x7F, cr17); 2261 SiS_SetReg(SISSR, 0x1F, sr1F); 2262 } 2263 2264 /* Determine and detect attached devices on SiS30x */ 2265 static void SiS_SenseLCD(struct sis_video_info *ivideo) 2266 { 2267 unsigned char buffer[256]; 2268 unsigned short temp, realcrtno, i; 2269 u8 reg, cr37 = 0, paneltype = 0; 2270 u16 xres, yres; 2271 2272 ivideo->SiS_Pr.PanelSelfDetected = false; 2273 2274 /* LCD detection only for TMDS bridges */ 2275 if (!(ivideo->vbflags2 & VB2_SISTMDSBRIDGE)) 2276 return; 2277 if (ivideo->vbflags2 & VB2_30xBDH) 2278 return; 2279 2280 /* If LCD already set up by BIOS, skip it */ 2281 reg = SiS_GetReg(SISCR, 0x32); 2282 if (reg & 0x08) 2283 return; 2284 2285 realcrtno = 1; 2286 if (ivideo->SiS_Pr.DDCPortMixup) 2287 realcrtno = 0; 2288 2289 /* Check DDC capabilities */ 2290 temp = SiS_HandleDDC(&ivideo->SiS_Pr, ivideo->vbflags, ivideo->sisvga_engine, 2291 realcrtno, 0, &buffer[0], ivideo->vbflags2); 2292 2293 if ((!temp) || (temp == 0xffff) || (!(temp & 0x02))) 2294 return; 2295 2296 /* Read DDC data */ 2297 i = 3; /* Number of retrys */ 2298 do { 2299 temp = SiS_HandleDDC(&ivideo->SiS_Pr, ivideo->vbflags, 2300 ivideo->sisvga_engine, realcrtno, 1, 2301 &buffer[0], ivideo->vbflags2); 2302 } while ((temp) && i--); 2303 2304 if (temp) 2305 return; 2306 2307 /* No digital device */ 2308 if (!(buffer[0x14] & 0x80)) 2309 return; 2310 2311 /* First detailed timing preferred timing? */ 2312 if (!(buffer[0x18] & 0x02)) 2313 return; 2314 2315 xres = buffer[0x38] | ((buffer[0x3a] & 0xf0) << 4); 2316 yres = buffer[0x3b] | ((buffer[0x3d] & 0xf0) << 4); 2317 2318 switch(xres) { 2319 case 1024: 2320 if (yres == 768) 2321 paneltype = 0x02; 2322 break; 2323 case 1280: 2324 if (yres == 1024) 2325 paneltype = 0x03; 2326 break; 2327 case 1600: 2328 if ((yres == 1200) && (ivideo->vbflags2 & VB2_30xC)) 2329 paneltype = 0x0b; 2330 break; 2331 } 2332 2333 if (!paneltype) 2334 return; 2335 2336 if (buffer[0x23]) 2337 cr37 |= 0x10; 2338 2339 if ((buffer[0x47] & 0x18) == 0x18) 2340 cr37 |= ((((buffer[0x47] & 0x06) ^ 0x06) << 5) | 0x20); 2341 else 2342 cr37 |= 0xc0; 2343 2344 SiS_SetReg(SISCR, 0x36, paneltype); 2345 cr37 &= 0xf1; 2346 SiS_SetRegANDOR(SISCR, 0x37, 0x0c, cr37); 2347 SiS_SetRegOR(SISCR, 0x32, 0x08); 2348 2349 ivideo->SiS_Pr.PanelSelfDetected = true; 2350 } 2351 2352 static int SISDoSense(struct sis_video_info *ivideo, u16 type, u16 test) 2353 { 2354 int temp, mytest, result, i, j; 2355 2356 for (j = 0; j < 10; j++) { 2357 result = 0; 2358 for (i = 0; i < 3; i++) { 2359 mytest = test; 2360 SiS_SetReg(SISPART4, 0x11, (type & 0x00ff)); 2361 temp = (type >> 8) | (mytest & 0x00ff); 2362 SiS_SetRegANDOR(SISPART4, 0x10, 0xe0, temp); 2363 SiS_DDC2Delay(&ivideo->SiS_Pr, 0x1500); 2364 mytest >>= 8; 2365 mytest &= 0x7f; 2366 temp = SiS_GetReg(SISPART4, 0x03); 2367 temp ^= 0x0e; 2368 temp &= mytest; 2369 if (temp == mytest) 2370 result++; 2371 #if 1 2372 SiS_SetReg(SISPART4, 0x11, 0x00); 2373 SiS_SetRegAND(SISPART4, 0x10, 0xe0); 2374 SiS_DDC2Delay(&ivideo->SiS_Pr, 0x1000); 2375 #endif 2376 } 2377 2378 if ((result == 0) || (result >= 2)) 2379 break; 2380 } 2381 return result; 2382 } 2383 2384 static void SiS_Sense30x(struct sis_video_info *ivideo) 2385 { 2386 u8 backupP4_0d,backupP2_00,backupP2_4d,backupSR_1e,biosflag=0; 2387 u16 svhs=0, svhs_c=0; 2388 u16 cvbs=0, cvbs_c=0; 2389 u16 vga2=0, vga2_c=0; 2390 int myflag, result; 2391 char stdstr[] = "sisfb: Detected"; 2392 char tvstr[] = "TV connected to"; 2393 2394 if(ivideo->vbflags2 & VB2_301) { 2395 svhs = 0x00b9; cvbs = 0x00b3; vga2 = 0x00d1; 2396 myflag = SiS_GetReg(SISPART4, 0x01); 2397 if(myflag & 0x04) { 2398 svhs = 0x00dd; cvbs = 0x00ee; vga2 = 0x00fd; 2399 } 2400 } else if(ivideo->vbflags2 & (VB2_301B | VB2_302B)) { 2401 svhs = 0x016b; cvbs = 0x0174; vga2 = 0x0190; 2402 } else if(ivideo->vbflags2 & (VB2_301LV | VB2_302LV)) { 2403 svhs = 0x0200; cvbs = 0x0100; 2404 } else if(ivideo->vbflags2 & (VB2_301C | VB2_302ELV | VB2_307T | VB2_307LV)) { 2405 svhs = 0x016b; cvbs = 0x0110; vga2 = 0x0190; 2406 } else 2407 return; 2408 2409 vga2_c = 0x0e08; svhs_c = 0x0404; cvbs_c = 0x0804; 2410 if(ivideo->vbflags & (VB2_301LV|VB2_302LV|VB2_302ELV|VB2_307LV)) { 2411 svhs_c = 0x0408; cvbs_c = 0x0808; 2412 } 2413 2414 biosflag = 2; 2415 if(ivideo->haveXGIROM) { 2416 biosflag = ivideo->bios_abase[0x58] & 0x03; 2417 } else if(ivideo->newrom) { 2418 if(ivideo->bios_abase[0x5d] & 0x04) biosflag |= 0x01; 2419 } else if(ivideo->sisvga_engine == SIS_300_VGA) { 2420 if(ivideo->bios_abase) { 2421 biosflag = ivideo->bios_abase[0xfe] & 0x03; 2422 } 2423 } 2424 2425 if(ivideo->chip == SIS_300) { 2426 myflag = SiS_GetReg(SISSR, 0x3b); 2427 if(!(myflag & 0x01)) vga2 = vga2_c = 0; 2428 } 2429 2430 if(!(ivideo->vbflags2 & VB2_SISVGA2BRIDGE)) { 2431 vga2 = vga2_c = 0; 2432 } 2433 2434 backupSR_1e = SiS_GetReg(SISSR, 0x1e); 2435 SiS_SetRegOR(SISSR, 0x1e, 0x20); 2436 2437 backupP4_0d = SiS_GetReg(SISPART4, 0x0d); 2438 if(ivideo->vbflags2 & VB2_30xC) { 2439 SiS_SetRegANDOR(SISPART4, 0x0d, ~0x07, 0x01); 2440 } else { 2441 SiS_SetRegOR(SISPART4, 0x0d, 0x04); 2442 } 2443 SiS_DDC2Delay(&ivideo->SiS_Pr, 0x2000); 2444 2445 backupP2_00 = SiS_GetReg(SISPART2, 0x00); 2446 SiS_SetReg(SISPART2, 0x00, ((backupP2_00 | 0x1c) & 0xfc)); 2447 2448 backupP2_4d = SiS_GetReg(SISPART2, 0x4d); 2449 if(ivideo->vbflags2 & VB2_SISYPBPRBRIDGE) { 2450 SiS_SetReg(SISPART2, 0x4d, (backupP2_4d & ~0x10)); 2451 } 2452 2453 if(!(ivideo->vbflags2 & VB2_30xCLV)) { 2454 SISDoSense(ivideo, 0, 0); 2455 } 2456 2457 SiS_SetRegAND(SISCR, 0x32, ~0x14); 2458 2459 if(vga2_c || vga2) { 2460 if(SISDoSense(ivideo, vga2, vga2_c)) { 2461 if(biosflag & 0x01) { 2462 printk(KERN_INFO "%s %s SCART output\n", stdstr, tvstr); 2463 SiS_SetRegOR(SISCR, 0x32, 0x04); 2464 } else { 2465 printk(KERN_INFO "%s secondary VGA connection\n", stdstr); 2466 SiS_SetRegOR(SISCR, 0x32, 0x10); 2467 } 2468 } 2469 } 2470 2471 SiS_SetRegAND(SISCR, 0x32, 0x3f); 2472 2473 if(ivideo->vbflags2 & VB2_30xCLV) { 2474 SiS_SetRegOR(SISPART4, 0x0d, 0x04); 2475 } 2476 2477 if((ivideo->sisvga_engine == SIS_315_VGA) && (ivideo->vbflags2 & VB2_SISYPBPRBRIDGE)) { 2478 SiS_SetReg(SISPART2, 0x4d, (backupP2_4d | 0x10)); 2479 SiS_DDC2Delay(&ivideo->SiS_Pr, 0x2000); 2480 if((result = SISDoSense(ivideo, svhs, 0x0604))) { 2481 if((result = SISDoSense(ivideo, cvbs, 0x0804))) { 2482 printk(KERN_INFO "%s %s YPbPr component output\n", stdstr, tvstr); 2483 SiS_SetRegOR(SISCR, 0x32, 0x80); 2484 } 2485 } 2486 SiS_SetReg(SISPART2, 0x4d, backupP2_4d); 2487 } 2488 2489 SiS_SetRegAND(SISCR, 0x32, ~0x03); 2490 2491 if(!(ivideo->vbflags & TV_YPBPR)) { 2492 if((result = SISDoSense(ivideo, svhs, svhs_c))) { 2493 printk(KERN_INFO "%s %s SVIDEO output\n", stdstr, tvstr); 2494 SiS_SetRegOR(SISCR, 0x32, 0x02); 2495 } 2496 if((biosflag & 0x02) || (!result)) { 2497 if(SISDoSense(ivideo, cvbs, cvbs_c)) { 2498 printk(KERN_INFO "%s %s COMPOSITE output\n", stdstr, tvstr); 2499 SiS_SetRegOR(SISCR, 0x32, 0x01); 2500 } 2501 } 2502 } 2503 2504 SISDoSense(ivideo, 0, 0); 2505 2506 SiS_SetReg(SISPART2, 0x00, backupP2_00); 2507 SiS_SetReg(SISPART4, 0x0d, backupP4_0d); 2508 SiS_SetReg(SISSR, 0x1e, backupSR_1e); 2509 2510 if(ivideo->vbflags2 & VB2_30xCLV) { 2511 biosflag = SiS_GetReg(SISPART2, 0x00); 2512 if(biosflag & 0x20) { 2513 for(myflag = 2; myflag > 0; myflag--) { 2514 biosflag ^= 0x20; 2515 SiS_SetReg(SISPART2, 0x00, biosflag); 2516 } 2517 } 2518 } 2519 2520 SiS_SetReg(SISPART2, 0x00, backupP2_00); 2521 } 2522 2523 /* Determine and detect attached TV's on Chrontel */ 2524 static void SiS_SenseCh(struct sis_video_info *ivideo) 2525 { 2526 #if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315) 2527 u8 temp1, temp2; 2528 char stdstr[] = "sisfb: Chrontel: Detected TV connected to"; 2529 #endif 2530 #ifdef CONFIG_FB_SIS_300 2531 unsigned char test[3]; 2532 int i; 2533 #endif 2534 2535 if(ivideo->chip < SIS_315H) { 2536 2537 #ifdef CONFIG_FB_SIS_300 2538 ivideo->SiS_Pr.SiS_IF_DEF_CH70xx = 1; /* Chrontel 700x */ 2539 SiS_SetChrontelGPIO(&ivideo->SiS_Pr, 0x9c); /* Set general purpose IO for Chrontel communication */ 2540 SiS_DDC2Delay(&ivideo->SiS_Pr, 1000); 2541 temp1 = SiS_GetCH700x(&ivideo->SiS_Pr, 0x25); 2542 /* See Chrontel TB31 for explanation */ 2543 temp2 = SiS_GetCH700x(&ivideo->SiS_Pr, 0x0e); 2544 if(((temp2 & 0x07) == 0x01) || (temp2 & 0x04)) { 2545 SiS_SetCH700x(&ivideo->SiS_Pr, 0x0e, 0x0b); 2546 SiS_DDC2Delay(&ivideo->SiS_Pr, 300); 2547 } 2548 temp2 = SiS_GetCH700x(&ivideo->SiS_Pr, 0x25); 2549 if(temp2 != temp1) temp1 = temp2; 2550 2551 if((temp1 >= 0x22) && (temp1 <= 0x50)) { 2552 /* Read power status */ 2553 temp1 = SiS_GetCH700x(&ivideo->SiS_Pr, 0x0e); 2554 if((temp1 & 0x03) != 0x03) { 2555 /* Power all outputs */ 2556 SiS_SetCH700x(&ivideo->SiS_Pr, 0x0e,0x0b); 2557 SiS_DDC2Delay(&ivideo->SiS_Pr, 300); 2558 } 2559 /* Sense connected TV devices */ 2560 for(i = 0; i < 3; i++) { 2561 SiS_SetCH700x(&ivideo->SiS_Pr, 0x10, 0x01); 2562 SiS_DDC2Delay(&ivideo->SiS_Pr, 0x96); 2563 SiS_SetCH700x(&ivideo->SiS_Pr, 0x10, 0x00); 2564 SiS_DDC2Delay(&ivideo->SiS_Pr, 0x96); 2565 temp1 = SiS_GetCH700x(&ivideo->SiS_Pr, 0x10); 2566 if(!(temp1 & 0x08)) test[i] = 0x02; 2567 else if(!(temp1 & 0x02)) test[i] = 0x01; 2568 else test[i] = 0; 2569 SiS_DDC2Delay(&ivideo->SiS_Pr, 0x96); 2570 } 2571 2572 if(test[0] == test[1]) temp1 = test[0]; 2573 else if(test[0] == test[2]) temp1 = test[0]; 2574 else if(test[1] == test[2]) temp1 = test[1]; 2575 else { 2576 printk(KERN_INFO 2577 "sisfb: TV detection unreliable - test results varied\n"); 2578 temp1 = test[2]; 2579 } 2580 if(temp1 == 0x02) { 2581 printk(KERN_INFO "%s SVIDEO output\n", stdstr); 2582 ivideo->vbflags |= TV_SVIDEO; 2583 SiS_SetRegOR(SISCR, 0x32, 0x02); 2584 SiS_SetRegAND(SISCR, 0x32, ~0x05); 2585 } else if (temp1 == 0x01) { 2586 printk(KERN_INFO "%s CVBS output\n", stdstr); 2587 ivideo->vbflags |= TV_AVIDEO; 2588 SiS_SetRegOR(SISCR, 0x32, 0x01); 2589 SiS_SetRegAND(SISCR, 0x32, ~0x06); 2590 } else { 2591 SiS_SetCH70xxANDOR(&ivideo->SiS_Pr, 0x0e, 0x01, 0xF8); 2592 SiS_SetRegAND(SISCR, 0x32, ~0x07); 2593 } 2594 } else if(temp1 == 0) { 2595 SiS_SetCH70xxANDOR(&ivideo->SiS_Pr, 0x0e, 0x01, 0xF8); 2596 SiS_SetRegAND(SISCR, 0x32, ~0x07); 2597 } 2598 /* Set general purpose IO for Chrontel communication */ 2599 SiS_SetChrontelGPIO(&ivideo->SiS_Pr, 0x00); 2600 #endif 2601 2602 } else { 2603 2604 #ifdef CONFIG_FB_SIS_315 2605 ivideo->SiS_Pr.SiS_IF_DEF_CH70xx = 2; /* Chrontel 7019 */ 2606 temp1 = SiS_GetCH701x(&ivideo->SiS_Pr, 0x49); 2607 SiS_SetCH701x(&ivideo->SiS_Pr, 0x49, 0x20); 2608 SiS_DDC2Delay(&ivideo->SiS_Pr, 0x96); 2609 temp2 = SiS_GetCH701x(&ivideo->SiS_Pr, 0x20); 2610 temp2 |= 0x01; 2611 SiS_SetCH701x(&ivideo->SiS_Pr, 0x20, temp2); 2612 SiS_DDC2Delay(&ivideo->SiS_Pr, 0x96); 2613 temp2 ^= 0x01; 2614 SiS_SetCH701x(&ivideo->SiS_Pr, 0x20, temp2); 2615 SiS_DDC2Delay(&ivideo->SiS_Pr, 0x96); 2616 temp2 = SiS_GetCH701x(&ivideo->SiS_Pr, 0x20); 2617 SiS_SetCH701x(&ivideo->SiS_Pr, 0x49, temp1); 2618 temp1 = 0; 2619 if(temp2 & 0x02) temp1 |= 0x01; 2620 if(temp2 & 0x10) temp1 |= 0x01; 2621 if(temp2 & 0x04) temp1 |= 0x02; 2622 if( (temp1 & 0x01) && (temp1 & 0x02) ) temp1 = 0x04; 2623 switch(temp1) { 2624 case 0x01: 2625 printk(KERN_INFO "%s CVBS output\n", stdstr); 2626 ivideo->vbflags |= TV_AVIDEO; 2627 SiS_SetRegOR(SISCR, 0x32, 0x01); 2628 SiS_SetRegAND(SISCR, 0x32, ~0x06); 2629 break; 2630 case 0x02: 2631 printk(KERN_INFO "%s SVIDEO output\n", stdstr); 2632 ivideo->vbflags |= TV_SVIDEO; 2633 SiS_SetRegOR(SISCR, 0x32, 0x02); 2634 SiS_SetRegAND(SISCR, 0x32, ~0x05); 2635 break; 2636 case 0x04: 2637 printk(KERN_INFO "%s SCART output\n", stdstr); 2638 SiS_SetRegOR(SISCR, 0x32, 0x04); 2639 SiS_SetRegAND(SISCR, 0x32, ~0x03); 2640 break; 2641 default: 2642 SiS_SetRegAND(SISCR, 0x32, ~0x07); 2643 } 2644 #endif 2645 } 2646 } 2647 2648 static void sisfb_get_VB_type(struct sis_video_info *ivideo) 2649 { 2650 char stdstr[] = "sisfb: Detected"; 2651 char bridgestr[] = "video bridge"; 2652 u8 vb_chipid; 2653 u8 reg; 2654 2655 /* No CRT2 on XGI Z7 */ 2656 if(ivideo->chip == XGI_20) 2657 return; 2658 2659 vb_chipid = SiS_GetReg(SISPART4, 0x00); 2660 switch(vb_chipid) { 2661 case 0x01: 2662 reg = SiS_GetReg(SISPART4, 0x01); 2663 if(reg < 0xb0) { 2664 ivideo->vbflags |= VB_301; /* Deprecated */ 2665 ivideo->vbflags2 |= VB2_301; 2666 printk(KERN_INFO "%s SiS301 %s\n", stdstr, bridgestr); 2667 } else if(reg < 0xc0) { 2668 ivideo->vbflags |= VB_301B; /* Deprecated */ 2669 ivideo->vbflags2 |= VB2_301B; 2670 reg = SiS_GetReg(SISPART4, 0x23); 2671 if(!(reg & 0x02)) { 2672 ivideo->vbflags |= VB_30xBDH; /* Deprecated */ 2673 ivideo->vbflags2 |= VB2_30xBDH; 2674 printk(KERN_INFO "%s SiS301B-DH %s\n", stdstr, bridgestr); 2675 } else { 2676 printk(KERN_INFO "%s SiS301B %s\n", stdstr, bridgestr); 2677 } 2678 } else if(reg < 0xd0) { 2679 ivideo->vbflags |= VB_301C; /* Deprecated */ 2680 ivideo->vbflags2 |= VB2_301C; 2681 printk(KERN_INFO "%s SiS301C %s\n", stdstr, bridgestr); 2682 } else if(reg < 0xe0) { 2683 ivideo->vbflags |= VB_301LV; /* Deprecated */ 2684 ivideo->vbflags2 |= VB2_301LV; 2685 printk(KERN_INFO "%s SiS301LV %s\n", stdstr, bridgestr); 2686 } else if(reg <= 0xe1) { 2687 reg = SiS_GetReg(SISPART4, 0x39); 2688 if(reg == 0xff) { 2689 ivideo->vbflags |= VB_302LV; /* Deprecated */ 2690 ivideo->vbflags2 |= VB2_302LV; 2691 printk(KERN_INFO "%s SiS302LV %s\n", stdstr, bridgestr); 2692 } else { 2693 ivideo->vbflags |= VB_301C; /* Deprecated */ 2694 ivideo->vbflags2 |= VB2_301C; 2695 printk(KERN_INFO "%s SiS301C(P4) %s\n", stdstr, bridgestr); 2696 #if 0 2697 ivideo->vbflags |= VB_302ELV; /* Deprecated */ 2698 ivideo->vbflags2 |= VB2_302ELV; 2699 printk(KERN_INFO "%s SiS302ELV %s\n", stdstr, bridgestr); 2700 #endif 2701 } 2702 } 2703 break; 2704 case 0x02: 2705 ivideo->vbflags |= VB_302B; /* Deprecated */ 2706 ivideo->vbflags2 |= VB2_302B; 2707 printk(KERN_INFO "%s SiS302B %s\n", stdstr, bridgestr); 2708 break; 2709 } 2710 2711 if((!(ivideo->vbflags2 & VB2_VIDEOBRIDGE)) && (ivideo->chip != SIS_300)) { 2712 reg = SiS_GetReg(SISCR, 0x37); 2713 reg &= SIS_EXTERNAL_CHIP_MASK; 2714 reg >>= 1; 2715 if(ivideo->sisvga_engine == SIS_300_VGA) { 2716 #ifdef CONFIG_FB_SIS_300 2717 switch(reg) { 2718 case SIS_EXTERNAL_CHIP_LVDS: 2719 ivideo->vbflags |= VB_LVDS; /* Deprecated */ 2720 ivideo->vbflags2 |= VB2_LVDS; 2721 break; 2722 case SIS_EXTERNAL_CHIP_TRUMPION: 2723 ivideo->vbflags |= (VB_LVDS | VB_TRUMPION); /* Deprecated */ 2724 ivideo->vbflags2 |= (VB2_LVDS | VB2_TRUMPION); 2725 break; 2726 case SIS_EXTERNAL_CHIP_CHRONTEL: 2727 ivideo->vbflags |= VB_CHRONTEL; /* Deprecated */ 2728 ivideo->vbflags2 |= VB2_CHRONTEL; 2729 break; 2730 case SIS_EXTERNAL_CHIP_LVDS_CHRONTEL: 2731 ivideo->vbflags |= (VB_LVDS | VB_CHRONTEL); /* Deprecated */ 2732 ivideo->vbflags2 |= (VB2_LVDS | VB2_CHRONTEL); 2733 break; 2734 } 2735 if(ivideo->vbflags2 & VB2_CHRONTEL) ivideo->chronteltype = 1; 2736 #endif 2737 } else if(ivideo->chip < SIS_661) { 2738 #ifdef CONFIG_FB_SIS_315 2739 switch (reg) { 2740 case SIS310_EXTERNAL_CHIP_LVDS: 2741 ivideo->vbflags |= VB_LVDS; /* Deprecated */ 2742 ivideo->vbflags2 |= VB2_LVDS; 2743 break; 2744 case SIS310_EXTERNAL_CHIP_LVDS_CHRONTEL: 2745 ivideo->vbflags |= (VB_LVDS | VB_CHRONTEL); /* Deprecated */ 2746 ivideo->vbflags2 |= (VB2_LVDS | VB2_CHRONTEL); 2747 break; 2748 } 2749 if(ivideo->vbflags2 & VB2_CHRONTEL) ivideo->chronteltype = 2; 2750 #endif 2751 } else if(ivideo->chip >= SIS_661) { 2752 #ifdef CONFIG_FB_SIS_315 2753 reg = SiS_GetReg(SISCR, 0x38); 2754 reg >>= 5; 2755 switch(reg) { 2756 case 0x02: 2757 ivideo->vbflags |= VB_LVDS; /* Deprecated */ 2758 ivideo->vbflags2 |= VB2_LVDS; 2759 break; 2760 case 0x03: 2761 ivideo->vbflags |= (VB_LVDS | VB_CHRONTEL); /* Deprecated */ 2762 ivideo->vbflags2 |= (VB2_LVDS | VB2_CHRONTEL); 2763 break; 2764 case 0x04: 2765 ivideo->vbflags |= (VB_LVDS | VB_CONEXANT); /* Deprecated */ 2766 ivideo->vbflags2 |= (VB2_LVDS | VB2_CONEXANT); 2767 break; 2768 } 2769 if(ivideo->vbflags2 & VB2_CHRONTEL) ivideo->chronteltype = 2; 2770 #endif 2771 } 2772 if(ivideo->vbflags2 & VB2_LVDS) { 2773 printk(KERN_INFO "%s LVDS transmitter\n", stdstr); 2774 } 2775 if((ivideo->sisvga_engine == SIS_300_VGA) && (ivideo->vbflags2 & VB2_TRUMPION)) { 2776 printk(KERN_INFO "%s Trumpion Zurac LCD scaler\n", stdstr); 2777 } 2778 if(ivideo->vbflags2 & VB2_CHRONTEL) { 2779 printk(KERN_INFO "%s Chrontel TV encoder\n", stdstr); 2780 } 2781 if((ivideo->chip >= SIS_661) && (ivideo->vbflags2 & VB2_CONEXANT)) { 2782 printk(KERN_INFO "%s Conexant external device\n", stdstr); 2783 } 2784 } 2785 2786 if(ivideo->vbflags2 & VB2_SISBRIDGE) { 2787 SiS_SenseLCD(ivideo); 2788 SiS_Sense30x(ivideo); 2789 } else if(ivideo->vbflags2 & VB2_CHRONTEL) { 2790 SiS_SenseCh(ivideo); 2791 } 2792 } 2793 2794 /* ---------- Engine initialization routines ------------ */ 2795 2796 static void 2797 sisfb_engine_init(struct sis_video_info *ivideo) 2798 { 2799 2800 /* Initialize command queue (we use MMIO only) */ 2801 2802 /* BEFORE THIS IS CALLED, THE ENGINES *MUST* BE SYNC'ED */ 2803 2804 ivideo->caps &= ~(TURBO_QUEUE_CAP | 2805 MMIO_CMD_QUEUE_CAP | 2806 VM_CMD_QUEUE_CAP | 2807 AGP_CMD_QUEUE_CAP); 2808 2809 #ifdef CONFIG_FB_SIS_300 2810 if(ivideo->sisvga_engine == SIS_300_VGA) { 2811 u32 tqueue_pos; 2812 u8 tq_state; 2813 2814 tqueue_pos = (ivideo->video_size - ivideo->cmdQueueSize) / (64 * 1024); 2815 2816 tq_state = SiS_GetReg(SISSR, IND_SIS_TURBOQUEUE_SET); 2817 tq_state |= 0xf0; 2818 tq_state &= 0xfc; 2819 tq_state |= (u8)(tqueue_pos >> 8); 2820 SiS_SetReg(SISSR, IND_SIS_TURBOQUEUE_SET, tq_state); 2821 2822 SiS_SetReg(SISSR, IND_SIS_TURBOQUEUE_ADR, (u8)(tqueue_pos & 0xff)); 2823 2824 ivideo->caps |= TURBO_QUEUE_CAP; 2825 } 2826 #endif 2827 2828 #ifdef CONFIG_FB_SIS_315 2829 if(ivideo->sisvga_engine == SIS_315_VGA) { 2830 u32 tempq = 0, templ; 2831 u8 temp; 2832 2833 if(ivideo->chip == XGI_20) { 2834 switch(ivideo->cmdQueueSize) { 2835 case (64 * 1024): 2836 temp = SIS_CMD_QUEUE_SIZE_Z7_64k; 2837 break; 2838 case (128 * 1024): 2839 default: 2840 temp = SIS_CMD_QUEUE_SIZE_Z7_128k; 2841 } 2842 } else { 2843 switch(ivideo->cmdQueueSize) { 2844 case (4 * 1024 * 1024): 2845 temp = SIS_CMD_QUEUE_SIZE_4M; 2846 break; 2847 case (2 * 1024 * 1024): 2848 temp = SIS_CMD_QUEUE_SIZE_2M; 2849 break; 2850 case (1 * 1024 * 1024): 2851 temp = SIS_CMD_QUEUE_SIZE_1M; 2852 break; 2853 default: 2854 case (512 * 1024): 2855 temp = SIS_CMD_QUEUE_SIZE_512k; 2856 } 2857 } 2858 2859 SiS_SetReg(SISSR, IND_SIS_CMDQUEUE_THRESHOLD, COMMAND_QUEUE_THRESHOLD); 2860 SiS_SetReg(SISSR, IND_SIS_CMDQUEUE_SET, SIS_CMD_QUEUE_RESET); 2861 2862 if((ivideo->chip >= XGI_40) && ivideo->modechanged) { 2863 /* Must disable dual pipe on XGI_40. Can't do 2864 * this in MMIO mode, because it requires 2865 * setting/clearing a bit in the MMIO fire trigger 2866 * register. 2867 */ 2868 if(!((templ = MMIO_IN32(ivideo->mmio_vbase, 0x8240)) & (1 << 10))) { 2869 2870 MMIO_OUT32(ivideo->mmio_vbase, Q_WRITE_PTR, 0); 2871 2872 SiS_SetReg(SISSR, IND_SIS_CMDQUEUE_SET, (temp | SIS_VRAM_CMDQUEUE_ENABLE)); 2873 2874 tempq = MMIO_IN32(ivideo->mmio_vbase, Q_READ_PTR); 2875 MMIO_OUT32(ivideo->mmio_vbase, Q_WRITE_PTR, tempq); 2876 2877 tempq = (u32)(ivideo->video_size - ivideo->cmdQueueSize); 2878 MMIO_OUT32(ivideo->mmio_vbase, Q_BASE_ADDR, tempq); 2879 2880 writel(0x16800000 + 0x8240, ivideo->video_vbase + tempq); 2881 writel(templ | (1 << 10), ivideo->video_vbase + tempq + 4); 2882 writel(0x168F0000, ivideo->video_vbase + tempq + 8); 2883 writel(0x168F0000, ivideo->video_vbase + tempq + 12); 2884 2885 MMIO_OUT32(ivideo->mmio_vbase, Q_WRITE_PTR, (tempq + 16)); 2886 2887 sisfb_syncaccel(ivideo); 2888 2889 SiS_SetReg(SISSR, IND_SIS_CMDQUEUE_SET, SIS_CMD_QUEUE_RESET); 2890 2891 } 2892 } 2893 2894 tempq = MMIO_IN32(ivideo->mmio_vbase, MMIO_QUEUE_READPORT); 2895 MMIO_OUT32(ivideo->mmio_vbase, MMIO_QUEUE_WRITEPORT, tempq); 2896 2897 temp |= (SIS_MMIO_CMD_ENABLE | SIS_CMD_AUTO_CORR); 2898 SiS_SetReg(SISSR, IND_SIS_CMDQUEUE_SET, temp); 2899 2900 tempq = (u32)(ivideo->video_size - ivideo->cmdQueueSize); 2901 MMIO_OUT32(ivideo->mmio_vbase, MMIO_QUEUE_PHYBASE, tempq); 2902 2903 ivideo->caps |= MMIO_CMD_QUEUE_CAP; 2904 } 2905 #endif 2906 2907 ivideo->engineok = 1; 2908 } 2909 2910 static void sisfb_detect_lcd_type(struct sis_video_info *ivideo) 2911 { 2912 u8 reg; 2913 int i; 2914 2915 reg = SiS_GetReg(SISCR, 0x36); 2916 reg &= 0x0f; 2917 if(ivideo->sisvga_engine == SIS_300_VGA) { 2918 ivideo->CRT2LCDType = sis300paneltype[reg]; 2919 } else if(ivideo->chip >= SIS_661) { 2920 ivideo->CRT2LCDType = sis661paneltype[reg]; 2921 } else { 2922 ivideo->CRT2LCDType = sis310paneltype[reg]; 2923 if((ivideo->chip == SIS_550) && (sisfb_fstn)) { 2924 if((ivideo->CRT2LCDType != LCD_320x240_2) && 2925 (ivideo->CRT2LCDType != LCD_320x240_3)) { 2926 ivideo->CRT2LCDType = LCD_320x240; 2927 } 2928 } 2929 } 2930 2931 if(ivideo->CRT2LCDType == LCD_UNKNOWN) { 2932 /* For broken BIOSes: Assume 1024x768, RGB18 */ 2933 ivideo->CRT2LCDType = LCD_1024x768; 2934 SiS_SetRegANDOR(SISCR, 0x36, 0xf0, 0x02); 2935 SiS_SetRegANDOR(SISCR, 0x37, 0xee, 0x01); 2936 printk(KERN_DEBUG "sisfb: Invalid panel ID (%02x), assuming 1024x768, RGB18\n", reg); 2937 } 2938 2939 for(i = 0; i < SIS_LCD_NUMBER; i++) { 2940 if(ivideo->CRT2LCDType == sis_lcd_data[i].lcdtype) { 2941 ivideo->lcdxres = sis_lcd_data[i].xres; 2942 ivideo->lcdyres = sis_lcd_data[i].yres; 2943 ivideo->lcddefmodeidx = sis_lcd_data[i].default_mode_idx; 2944 break; 2945 } 2946 } 2947 2948 #ifdef CONFIG_FB_SIS_300 2949 if(ivideo->SiS_Pr.SiS_CustomT == CUT_BARCO1366) { 2950 ivideo->lcdxres = 1360; ivideo->lcdyres = 1024; 2951 ivideo->lcddefmodeidx = DEFAULT_MODE_1360; 2952 } else if(ivideo->SiS_Pr.SiS_CustomT == CUT_PANEL848) { 2953 ivideo->lcdxres = 848; ivideo->lcdyres = 480; 2954 ivideo->lcddefmodeidx = DEFAULT_MODE_848; 2955 } else if(ivideo->SiS_Pr.SiS_CustomT == CUT_PANEL856) { 2956 ivideo->lcdxres = 856; ivideo->lcdyres = 480; 2957 ivideo->lcddefmodeidx = DEFAULT_MODE_856; 2958 } 2959 #endif 2960 2961 printk(KERN_DEBUG "sisfb: Detected %dx%d flat panel\n", 2962 ivideo->lcdxres, ivideo->lcdyres); 2963 } 2964 2965 static void sisfb_save_pdc_emi(struct sis_video_info *ivideo) 2966 { 2967 #ifdef CONFIG_FB_SIS_300 2968 /* Save the current PanelDelayCompensation if the LCD is currently used */ 2969 if(ivideo->sisvga_engine == SIS_300_VGA) { 2970 if(ivideo->vbflags2 & (VB2_LVDS | VB2_30xBDH)) { 2971 int tmp; 2972 tmp = SiS_GetReg(SISCR, 0x30); 2973 if(tmp & 0x20) { 2974 /* Currently on LCD? If yes, read current pdc */ 2975 ivideo->detectedpdc = SiS_GetReg(SISPART1, 0x13); 2976 ivideo->detectedpdc &= 0x3c; 2977 if(ivideo->SiS_Pr.PDC == -1) { 2978 /* Let option override detection */ 2979 ivideo->SiS_Pr.PDC = ivideo->detectedpdc; 2980 } 2981 printk(KERN_INFO "sisfb: Detected LCD PDC 0x%02x\n", 2982 ivideo->detectedpdc); 2983 } 2984 if((ivideo->SiS_Pr.PDC != -1) && 2985 (ivideo->SiS_Pr.PDC != ivideo->detectedpdc)) { 2986 printk(KERN_INFO "sisfb: Using LCD PDC 0x%02x\n", 2987 ivideo->SiS_Pr.PDC); 2988 } 2989 } 2990 } 2991 #endif 2992 2993 #ifdef CONFIG_FB_SIS_315 2994 if(ivideo->sisvga_engine == SIS_315_VGA) { 2995 2996 /* Try to find about LCDA */ 2997 if(ivideo->vbflags2 & VB2_SISLCDABRIDGE) { 2998 int tmp; 2999 tmp = SiS_GetReg(SISPART1, 0x13); 3000 if(tmp & 0x04) { 3001 ivideo->SiS_Pr.SiS_UseLCDA = true; 3002 ivideo->detectedlcda = 0x03; 3003 } 3004 } 3005 3006 /* Save PDC */ 3007 if(ivideo->vbflags2 & VB2_SISLVDSBRIDGE) { 3008 int tmp; 3009 tmp = SiS_GetReg(SISCR, 0x30); 3010 if((tmp & 0x20) || (ivideo->detectedlcda != 0xff)) { 3011 /* Currently on LCD? If yes, read current pdc */ 3012 u8 pdc; 3013 pdc = SiS_GetReg(SISPART1, 0x2D); 3014 ivideo->detectedpdc = (pdc & 0x0f) << 1; 3015 ivideo->detectedpdca = (pdc & 0xf0) >> 3; 3016 pdc = SiS_GetReg(SISPART1, 0x35); 3017 ivideo->detectedpdc |= ((pdc >> 7) & 0x01); 3018 pdc = SiS_GetReg(SISPART1, 0x20); 3019 ivideo->detectedpdca |= ((pdc >> 6) & 0x01); 3020 if(ivideo->newrom) { 3021 /* New ROM invalidates other PDC resp. */ 3022 if(ivideo->detectedlcda != 0xff) { 3023 ivideo->detectedpdc = 0xff; 3024 } else { 3025 ivideo->detectedpdca = 0xff; 3026 } 3027 } 3028 if(ivideo->SiS_Pr.PDC == -1) { 3029 if(ivideo->detectedpdc != 0xff) { 3030 ivideo->SiS_Pr.PDC = ivideo->detectedpdc; 3031 } 3032 } 3033 if(ivideo->SiS_Pr.PDCA == -1) { 3034 if(ivideo->detectedpdca != 0xff) { 3035 ivideo->SiS_Pr.PDCA = ivideo->detectedpdca; 3036 } 3037 } 3038 if(ivideo->detectedpdc != 0xff) { 3039 printk(KERN_INFO 3040 "sisfb: Detected LCD PDC 0x%02x (for LCD=CRT2)\n", 3041 ivideo->detectedpdc); 3042 } 3043 if(ivideo->detectedpdca != 0xff) { 3044 printk(KERN_INFO 3045 "sisfb: Detected LCD PDC1 0x%02x (for LCD=CRT1)\n", 3046 ivideo->detectedpdca); 3047 } 3048 } 3049 3050 /* Save EMI */ 3051 if(ivideo->vbflags2 & VB2_SISEMIBRIDGE) { 3052 ivideo->SiS_Pr.EMI_30 = SiS_GetReg(SISPART4, 0x30); 3053 ivideo->SiS_Pr.EMI_31 = SiS_GetReg(SISPART4, 0x31); 3054 ivideo->SiS_Pr.EMI_32 = SiS_GetReg(SISPART4, 0x32); 3055 ivideo->SiS_Pr.EMI_33 = SiS_GetReg(SISPART4, 0x33); 3056 ivideo->SiS_Pr.HaveEMI = true; 3057 if((tmp & 0x20) || (ivideo->detectedlcda != 0xff)) { 3058 ivideo->SiS_Pr.HaveEMILCD = true; 3059 } 3060 } 3061 } 3062 3063 /* Let user override detected PDCs (all bridges) */ 3064 if(ivideo->vbflags2 & VB2_30xBLV) { 3065 if((ivideo->SiS_Pr.PDC != -1) && 3066 (ivideo->SiS_Pr.PDC != ivideo->detectedpdc)) { 3067 printk(KERN_INFO "sisfb: Using LCD PDC 0x%02x (for LCD=CRT2)\n", 3068 ivideo->SiS_Pr.PDC); 3069 } 3070 if((ivideo->SiS_Pr.PDCA != -1) && 3071 (ivideo->SiS_Pr.PDCA != ivideo->detectedpdca)) { 3072 printk(KERN_INFO "sisfb: Using LCD PDC1 0x%02x (for LCD=CRT1)\n", 3073 ivideo->SiS_Pr.PDCA); 3074 } 3075 } 3076 3077 } 3078 #endif 3079 } 3080 3081 /* -------------------- Memory manager routines ---------------------- */ 3082 3083 static u32 sisfb_getheapstart(struct sis_video_info *ivideo) 3084 { 3085 u32 ret = ivideo->sisfb_parm_mem * 1024; 3086 u32 maxoffs = ivideo->video_size - ivideo->hwcursor_size - ivideo->cmdQueueSize; 3087 u32 def; 3088 3089 /* Calculate heap start = end of memory for console 3090 * 3091 * CCCCCCCCDDDDDDDDDDDDDDDDDDDDDDDDDDDDHHHHQQQQQQQQQQ 3092 * C = console, D = heap, H = HWCursor, Q = cmd-queue 3093 * 3094 * On 76x in UMA+LFB mode, the layout is as follows: 3095 * DDDDDDDDDDDCCCCCCCCCCCCCCCCCCCCCCCCHHHHQQQQQQQQQQQ 3096 * where the heap is the entire UMA area, eventually 3097 * into the LFB area if the given mem parameter is 3098 * higher than the size of the UMA memory. 3099 * 3100 * Basically given by "mem" parameter 3101 * 3102 * maximum = videosize - cmd_queue - hwcursor 3103 * (results in a heap of size 0) 3104 * default = SiS 300: depends on videosize 3105 * SiS 315/330/340/XGI: 32k below max 3106 */ 3107 3108 if(ivideo->sisvga_engine == SIS_300_VGA) { 3109 if(ivideo->video_size > 0x1000000) { 3110 def = 0xc00000; 3111 } else if(ivideo->video_size > 0x800000) { 3112 def = 0x800000; 3113 } else { 3114 def = 0x400000; 3115 } 3116 } else if(ivideo->UMAsize && ivideo->LFBsize) { 3117 ret = def = 0; 3118 } else { 3119 def = maxoffs - 0x8000; 3120 } 3121 3122 /* Use default for secondary card for now (FIXME) */ 3123 if((!ret) || (ret > maxoffs) || (ivideo->cardnumber != 0)) 3124 ret = def; 3125 3126 return ret; 3127 } 3128 3129 static u32 sisfb_getheapsize(struct sis_video_info *ivideo) 3130 { 3131 u32 max = ivideo->video_size - ivideo->hwcursor_size - ivideo->cmdQueueSize; 3132 u32 ret = 0; 3133 3134 if(ivideo->UMAsize && ivideo->LFBsize) { 3135 if( (!ivideo->sisfb_parm_mem) || 3136 ((ivideo->sisfb_parm_mem * 1024) > max) || 3137 ((max - (ivideo->sisfb_parm_mem * 1024)) < ivideo->UMAsize) ) { 3138 ret = ivideo->UMAsize; 3139 max -= ivideo->UMAsize; 3140 } else { 3141 ret = max - (ivideo->sisfb_parm_mem * 1024); 3142 max = ivideo->sisfb_parm_mem * 1024; 3143 } 3144 ivideo->video_offset = ret; 3145 ivideo->sisfb_mem = max; 3146 } else { 3147 ret = max - ivideo->heapstart; 3148 ivideo->sisfb_mem = ivideo->heapstart; 3149 } 3150 3151 return ret; 3152 } 3153 3154 static int sisfb_heap_init(struct sis_video_info *ivideo) 3155 { 3156 struct SIS_OH *poh; 3157 3158 ivideo->video_offset = 0; 3159 if(ivideo->sisfb_parm_mem) { 3160 if( (ivideo->sisfb_parm_mem < (2 * 1024 * 1024)) || 3161 (ivideo->sisfb_parm_mem > ivideo->video_size) ) { 3162 ivideo->sisfb_parm_mem = 0; 3163 } 3164 } 3165 3166 ivideo->heapstart = sisfb_getheapstart(ivideo); 3167 ivideo->sisfb_heap_size = sisfb_getheapsize(ivideo); 3168 3169 ivideo->sisfb_heap_start = ivideo->video_vbase + ivideo->heapstart; 3170 ivideo->sisfb_heap_end = ivideo->sisfb_heap_start + ivideo->sisfb_heap_size; 3171 3172 printk(KERN_INFO "sisfb: Memory heap starting at %dK, size %dK\n", 3173 (int)(ivideo->heapstart / 1024), (int)(ivideo->sisfb_heap_size / 1024)); 3174 3175 ivideo->sisfb_heap.vinfo = ivideo; 3176 3177 ivideo->sisfb_heap.poha_chain = NULL; 3178 ivideo->sisfb_heap.poh_freelist = NULL; 3179 3180 poh = sisfb_poh_new_node(&ivideo->sisfb_heap); 3181 if(poh == NULL) 3182 return 1; 3183 3184 poh->poh_next = &ivideo->sisfb_heap.oh_free; 3185 poh->poh_prev = &ivideo->sisfb_heap.oh_free; 3186 poh->size = ivideo->sisfb_heap_size; 3187 poh->offset = ivideo->heapstart; 3188 3189 ivideo->sisfb_heap.oh_free.poh_next = poh; 3190 ivideo->sisfb_heap.oh_free.poh_prev = poh; 3191 ivideo->sisfb_heap.oh_free.size = 0; 3192 ivideo->sisfb_heap.max_freesize = poh->size; 3193 3194 ivideo->sisfb_heap.oh_used.poh_next = &ivideo->sisfb_heap.oh_used; 3195 ivideo->sisfb_heap.oh_used.poh_prev = &ivideo->sisfb_heap.oh_used; 3196 ivideo->sisfb_heap.oh_used.size = SENTINEL; 3197 3198 if(ivideo->cardnumber == 0) { 3199 /* For the first card, make this heap the "global" one 3200 * for old DRM (which could handle only one card) 3201 */ 3202 sisfb_heap = &ivideo->sisfb_heap; 3203 } 3204 3205 return 0; 3206 } 3207 3208 static struct SIS_OH * 3209 sisfb_poh_new_node(struct SIS_HEAP *memheap) 3210 { 3211 struct SIS_OHALLOC *poha; 3212 struct SIS_OH *poh; 3213 unsigned long cOhs; 3214 int i; 3215 3216 if(memheap->poh_freelist == NULL) { 3217 poha = kmalloc(SIS_OH_ALLOC_SIZE, GFP_KERNEL); 3218 if(!poha) 3219 return NULL; 3220 3221 poha->poha_next = memheap->poha_chain; 3222 memheap->poha_chain = poha; 3223 3224 cOhs = (SIS_OH_ALLOC_SIZE - sizeof(struct SIS_OHALLOC)) / sizeof(struct SIS_OH) + 1; 3225 3226 poh = &poha->aoh[0]; 3227 for(i = cOhs - 1; i != 0; i--) { 3228 poh->poh_next = poh + 1; 3229 poh = poh + 1; 3230 } 3231 3232 poh->poh_next = NULL; 3233 memheap->poh_freelist = &poha->aoh[0]; 3234 } 3235 3236 poh = memheap->poh_freelist; 3237 memheap->poh_freelist = poh->poh_next; 3238 3239 return poh; 3240 } 3241 3242 static struct SIS_OH * 3243 sisfb_poh_allocate(struct SIS_HEAP *memheap, u32 size) 3244 { 3245 struct SIS_OH *pohThis; 3246 struct SIS_OH *pohRoot; 3247 int bAllocated = 0; 3248 3249 if(size > memheap->max_freesize) { 3250 DPRINTK("sisfb: Can't allocate %dk video memory\n", 3251 (unsigned int) size / 1024); 3252 return NULL; 3253 } 3254 3255 pohThis = memheap->oh_free.poh_next; 3256 3257 while(pohThis != &memheap->oh_free) { 3258 if(size <= pohThis->size) { 3259 bAllocated = 1; 3260 break; 3261 } 3262 pohThis = pohThis->poh_next; 3263 } 3264 3265 if(!bAllocated) { 3266 DPRINTK("sisfb: Can't allocate %dk video memory\n", 3267 (unsigned int) size / 1024); 3268 return NULL; 3269 } 3270 3271 if(size == pohThis->size) { 3272 pohRoot = pohThis; 3273 sisfb_delete_node(pohThis); 3274 } else { 3275 pohRoot = sisfb_poh_new_node(memheap); 3276 if(pohRoot == NULL) 3277 return NULL; 3278 3279 pohRoot->offset = pohThis->offset; 3280 pohRoot->size = size; 3281 3282 pohThis->offset += size; 3283 pohThis->size -= size; 3284 } 3285 3286 memheap->max_freesize -= size; 3287 3288 pohThis = &memheap->oh_used; 3289 sisfb_insert_node(pohThis, pohRoot); 3290 3291 return pohRoot; 3292 } 3293 3294 static void 3295 sisfb_delete_node(struct SIS_OH *poh) 3296 { 3297 poh->poh_prev->poh_next = poh->poh_next; 3298 poh->poh_next->poh_prev = poh->poh_prev; 3299 } 3300 3301 static void 3302 sisfb_insert_node(struct SIS_OH *pohList, struct SIS_OH *poh) 3303 { 3304 struct SIS_OH *pohTemp = pohList->poh_next; 3305 3306 pohList->poh_next = poh; 3307 pohTemp->poh_prev = poh; 3308 3309 poh->poh_prev = pohList; 3310 poh->poh_next = pohTemp; 3311 } 3312 3313 static struct SIS_OH * 3314 sisfb_poh_free(struct SIS_HEAP *memheap, u32 base) 3315 { 3316 struct SIS_OH *pohThis; 3317 struct SIS_OH *poh_freed; 3318 struct SIS_OH *poh_prev; 3319 struct SIS_OH *poh_next; 3320 u32 ulUpper; 3321 u32 ulLower; 3322 int foundNode = 0; 3323 3324 poh_freed = memheap->oh_used.poh_next; 3325 3326 while(poh_freed != &memheap->oh_used) { 3327 if(poh_freed->offset == base) { 3328 foundNode = 1; 3329 break; 3330 } 3331 3332 poh_freed = poh_freed->poh_next; 3333 } 3334 3335 if(!foundNode) 3336 return NULL; 3337 3338 memheap->max_freesize += poh_freed->size; 3339 3340 poh_prev = poh_next = NULL; 3341 ulUpper = poh_freed->offset + poh_freed->size; 3342 ulLower = poh_freed->offset; 3343 3344 pohThis = memheap->oh_free.poh_next; 3345 3346 while(pohThis != &memheap->oh_free) { 3347 if(pohThis->offset == ulUpper) { 3348 poh_next = pohThis; 3349 } else if((pohThis->offset + pohThis->size) == ulLower) { 3350 poh_prev = pohThis; 3351 } 3352 pohThis = pohThis->poh_next; 3353 } 3354 3355 sisfb_delete_node(poh_freed); 3356 3357 if(poh_prev && poh_next) { 3358 poh_prev->size += (poh_freed->size + poh_next->size); 3359 sisfb_delete_node(poh_next); 3360 sisfb_free_node(memheap, poh_freed); 3361 sisfb_free_node(memheap, poh_next); 3362 return poh_prev; 3363 } 3364 3365 if(poh_prev) { 3366 poh_prev->size += poh_freed->size; 3367 sisfb_free_node(memheap, poh_freed); 3368 return poh_prev; 3369 } 3370 3371 if(poh_next) { 3372 poh_next->size += poh_freed->size; 3373 poh_next->offset = poh_freed->offset; 3374 sisfb_free_node(memheap, poh_freed); 3375 return poh_next; 3376 } 3377 3378 sisfb_insert_node(&memheap->oh_free, poh_freed); 3379 3380 return poh_freed; 3381 } 3382 3383 static void 3384 sisfb_free_node(struct SIS_HEAP *memheap, struct SIS_OH *poh) 3385 { 3386 if(poh == NULL) 3387 return; 3388 3389 poh->poh_next = memheap->poh_freelist; 3390 memheap->poh_freelist = poh; 3391 } 3392 3393 static void 3394 sis_int_malloc(struct sis_video_info *ivideo, struct sis_memreq *req) 3395 { 3396 struct SIS_OH *poh = NULL; 3397 3398 if((ivideo) && (ivideo->sisfb_id == SISFB_ID) && (!ivideo->havenoheap)) 3399 poh = sisfb_poh_allocate(&ivideo->sisfb_heap, (u32)req->size); 3400 3401 if(poh == NULL) { 3402 req->offset = req->size = 0; 3403 DPRINTK("sisfb: Video RAM allocation failed\n"); 3404 } else { 3405 req->offset = poh->offset; 3406 req->size = poh->size; 3407 DPRINTK("sisfb: Video RAM allocation succeeded: 0x%lx\n", 3408 (poh->offset + ivideo->video_vbase)); 3409 } 3410 } 3411 3412 void 3413 sis_malloc(struct sis_memreq *req) 3414 { 3415 struct sis_video_info *ivideo = sisfb_heap->vinfo; 3416 3417 if(&ivideo->sisfb_heap == sisfb_heap) 3418 sis_int_malloc(ivideo, req); 3419 else 3420 req->offset = req->size = 0; 3421 } 3422 3423 /* sis_free: u32 because "base" is offset inside video ram, can never be >4GB */ 3424 3425 static void 3426 sis_int_free(struct sis_video_info *ivideo, u32 base) 3427 { 3428 struct SIS_OH *poh; 3429 3430 if((!ivideo) || (ivideo->sisfb_id != SISFB_ID) || (ivideo->havenoheap)) 3431 return; 3432 3433 poh = sisfb_poh_free(&ivideo->sisfb_heap, base); 3434 3435 if(poh == NULL) { 3436 DPRINTK("sisfb: sisfb_poh_free() failed at base 0x%x\n", 3437 (unsigned int) base); 3438 } 3439 } 3440 3441 void 3442 sis_free(u32 base) 3443 { 3444 struct sis_video_info *ivideo = sisfb_heap->vinfo; 3445 3446 sis_int_free(ivideo, base); 3447 } 3448 3449 /* --------------------- SetMode routines ------------------------- */ 3450 3451 static void 3452 sisfb_check_engine_and_sync(struct sis_video_info *ivideo) 3453 { 3454 u8 cr30, cr31; 3455 3456 /* Check if MMIO and engines are enabled, 3457 * and sync in case they are. Can't use 3458 * ivideo->accel here, as this might have 3459 * been changed before this is called. 3460 */ 3461 cr30 = SiS_GetReg(SISSR, IND_SIS_PCI_ADDRESS_SET); 3462 cr31 = SiS_GetReg(SISSR, IND_SIS_MODULE_ENABLE); 3463 /* MMIO and 2D/3D engine enabled? */ 3464 if((cr30 & SIS_MEM_MAP_IO_ENABLE) && (cr31 & 0x42)) { 3465 #ifdef CONFIG_FB_SIS_300 3466 if(ivideo->sisvga_engine == SIS_300_VGA) { 3467 /* Don't care about TurboQueue. It's 3468 * enough to know that the engines 3469 * are enabled 3470 */ 3471 sisfb_syncaccel(ivideo); 3472 } 3473 #endif 3474 #ifdef CONFIG_FB_SIS_315 3475 if(ivideo->sisvga_engine == SIS_315_VGA) { 3476 /* Check that any queue mode is 3477 * enabled, and that the queue 3478 * is not in the state of "reset" 3479 */ 3480 cr30 = SiS_GetReg(SISSR, 0x26); 3481 if((cr30 & 0xe0) && (!(cr30 & 0x01))) { 3482 sisfb_syncaccel(ivideo); 3483 } 3484 } 3485 #endif 3486 } 3487 } 3488 3489 static void 3490 sisfb_pre_setmode(struct sis_video_info *ivideo) 3491 { 3492 u8 cr30 = 0, cr31 = 0, cr33 = 0, cr35 = 0, cr38 = 0; 3493 int tvregnum = 0; 3494 3495 ivideo->currentvbflags &= (VB_VIDEOBRIDGE | VB_DISPTYPE_DISP2); 3496 3497 SiS_SetReg(SISSR, 0x05, 0x86); 3498 3499 cr31 = SiS_GetReg(SISCR, 0x31); 3500 cr31 &= ~0x60; 3501 cr31 |= 0x04; 3502 3503 cr33 = ivideo->rate_idx & 0x0F; 3504 3505 #ifdef CONFIG_FB_SIS_315 3506 if(ivideo->sisvga_engine == SIS_315_VGA) { 3507 if(ivideo->chip >= SIS_661) { 3508 cr38 = SiS_GetReg(SISCR, 0x38); 3509 cr38 &= ~0x07; /* Clear LCDA/DualEdge and YPbPr bits */ 3510 } else { 3511 tvregnum = 0x38; 3512 cr38 = SiS_GetReg(SISCR, tvregnum); 3513 cr38 &= ~0x3b; /* Clear LCDA/DualEdge and YPbPr bits */ 3514 } 3515 } 3516 #endif 3517 #ifdef CONFIG_FB_SIS_300 3518 if(ivideo->sisvga_engine == SIS_300_VGA) { 3519 tvregnum = 0x35; 3520 cr38 = SiS_GetReg(SISCR, tvregnum); 3521 } 3522 #endif 3523 3524 SiS_SetEnableDstn(&ivideo->SiS_Pr, false); 3525 SiS_SetEnableFstn(&ivideo->SiS_Pr, false); 3526 ivideo->curFSTN = ivideo->curDSTN = 0; 3527 3528 switch(ivideo->currentvbflags & VB_DISPTYPE_DISP2) { 3529 3530 case CRT2_TV: 3531 cr38 &= ~0xc0; /* Clear PAL-M / PAL-N bits */ 3532 if((ivideo->vbflags & TV_YPBPR) && (ivideo->vbflags2 & VB2_SISYPBPRBRIDGE)) { 3533 #ifdef CONFIG_FB_SIS_315 3534 if(ivideo->chip >= SIS_661) { 3535 cr38 |= 0x04; 3536 if(ivideo->vbflags & TV_YPBPR525P) cr35 |= 0x20; 3537 else if(ivideo->vbflags & TV_YPBPR750P) cr35 |= 0x40; 3538 else if(ivideo->vbflags & TV_YPBPR1080I) cr35 |= 0x60; 3539 cr30 |= SIS_SIMULTANEOUS_VIEW_ENABLE; 3540 cr35 &= ~0x01; 3541 ivideo->currentvbflags |= (TV_YPBPR | (ivideo->vbflags & TV_YPBPRALL)); 3542 } else if(ivideo->sisvga_engine == SIS_315_VGA) { 3543 cr30 |= (0x80 | SIS_SIMULTANEOUS_VIEW_ENABLE); 3544 cr38 |= 0x08; 3545 if(ivideo->vbflags & TV_YPBPR525P) cr38 |= 0x10; 3546 else if(ivideo->vbflags & TV_YPBPR750P) cr38 |= 0x20; 3547 else if(ivideo->vbflags & TV_YPBPR1080I) cr38 |= 0x30; 3548 cr31 &= ~0x01; 3549 ivideo->currentvbflags |= (TV_YPBPR | (ivideo->vbflags & TV_YPBPRALL)); 3550 } 3551 #endif 3552 } else if((ivideo->vbflags & TV_HIVISION) && 3553 (ivideo->vbflags2 & VB2_SISHIVISIONBRIDGE)) { 3554 if(ivideo->chip >= SIS_661) { 3555 cr38 |= 0x04; 3556 cr35 |= 0x60; 3557 } else { 3558 cr30 |= 0x80; 3559 } 3560 cr30 |= SIS_SIMULTANEOUS_VIEW_ENABLE; 3561 cr31 |= 0x01; 3562 cr35 |= 0x01; 3563 ivideo->currentvbflags |= TV_HIVISION; 3564 } else if(ivideo->vbflags & TV_SCART) { 3565 cr30 = (SIS_VB_OUTPUT_SCART | SIS_SIMULTANEOUS_VIEW_ENABLE); 3566 cr31 |= 0x01; 3567 cr35 |= 0x01; 3568 ivideo->currentvbflags |= TV_SCART; 3569 } else { 3570 if(ivideo->vbflags & TV_SVIDEO) { 3571 cr30 = (SIS_VB_OUTPUT_SVIDEO | SIS_SIMULTANEOUS_VIEW_ENABLE); 3572 ivideo->currentvbflags |= TV_SVIDEO; 3573 } 3574 if(ivideo->vbflags & TV_AVIDEO) { 3575 cr30 = (SIS_VB_OUTPUT_COMPOSITE | SIS_SIMULTANEOUS_VIEW_ENABLE); 3576 ivideo->currentvbflags |= TV_AVIDEO; 3577 } 3578 } 3579 cr31 |= SIS_DRIVER_MODE; 3580 3581 if(ivideo->vbflags & (TV_AVIDEO | TV_SVIDEO)) { 3582 if(ivideo->vbflags & TV_PAL) { 3583 cr31 |= 0x01; cr35 |= 0x01; 3584 ivideo->currentvbflags |= TV_PAL; 3585 if(ivideo->vbflags & TV_PALM) { 3586 cr38 |= 0x40; cr35 |= 0x04; 3587 ivideo->currentvbflags |= TV_PALM; 3588 } else if(ivideo->vbflags & TV_PALN) { 3589 cr38 |= 0x80; cr35 |= 0x08; 3590 ivideo->currentvbflags |= TV_PALN; 3591 } 3592 } else { 3593 cr31 &= ~0x01; cr35 &= ~0x01; 3594 ivideo->currentvbflags |= TV_NTSC; 3595 if(ivideo->vbflags & TV_NTSCJ) { 3596 cr38 |= 0x40; cr35 |= 0x02; 3597 ivideo->currentvbflags |= TV_NTSCJ; 3598 } 3599 } 3600 } 3601 break; 3602 3603 case CRT2_LCD: 3604 cr30 = (SIS_VB_OUTPUT_LCD | SIS_SIMULTANEOUS_VIEW_ENABLE); 3605 cr31 |= SIS_DRIVER_MODE; 3606 SiS_SetEnableDstn(&ivideo->SiS_Pr, ivideo->sisfb_dstn); 3607 SiS_SetEnableFstn(&ivideo->SiS_Pr, ivideo->sisfb_fstn); 3608 ivideo->curFSTN = ivideo->sisfb_fstn; 3609 ivideo->curDSTN = ivideo->sisfb_dstn; 3610 break; 3611 3612 case CRT2_VGA: 3613 cr30 = (SIS_VB_OUTPUT_CRT2 | SIS_SIMULTANEOUS_VIEW_ENABLE); 3614 cr31 |= SIS_DRIVER_MODE; 3615 if(ivideo->sisfb_nocrt2rate) { 3616 cr33 |= (sisbios_mode[ivideo->sisfb_mode_idx].rate_idx << 4); 3617 } else { 3618 cr33 |= ((ivideo->rate_idx & 0x0F) << 4); 3619 } 3620 break; 3621 3622 default: /* disable CRT2 */ 3623 cr30 = 0x00; 3624 cr31 |= (SIS_DRIVER_MODE | SIS_VB_OUTPUT_DISABLE); 3625 } 3626 3627 SiS_SetReg(SISCR, 0x30, cr30); 3628 SiS_SetReg(SISCR, 0x33, cr33); 3629 3630 if(ivideo->chip >= SIS_661) { 3631 #ifdef CONFIG_FB_SIS_315 3632 cr31 &= ~0x01; /* Clear PAL flag (now in CR35) */ 3633 SiS_SetRegANDOR(SISCR, 0x35, ~0x10, cr35); /* Leave overscan bit alone */ 3634 cr38 &= 0x07; /* Use only LCDA and HiVision/YPbPr bits */ 3635 SiS_SetRegANDOR(SISCR, 0x38, 0xf8, cr38); 3636 #endif 3637 } else if(ivideo->chip != SIS_300) { 3638 SiS_SetReg(SISCR, tvregnum, cr38); 3639 } 3640 SiS_SetReg(SISCR, 0x31, cr31); 3641 3642 ivideo->SiS_Pr.SiS_UseOEM = ivideo->sisfb_useoem; 3643 3644 sisfb_check_engine_and_sync(ivideo); 3645 } 3646 3647 /* Fix SR11 for 661 and later */ 3648 #ifdef CONFIG_FB_SIS_315 3649 static void 3650 sisfb_fixup_SR11(struct sis_video_info *ivideo) 3651 { 3652 u8 tmpreg; 3653 3654 if(ivideo->chip >= SIS_661) { 3655 tmpreg = SiS_GetReg(SISSR, 0x11); 3656 if(tmpreg & 0x20) { 3657 tmpreg = SiS_GetReg(SISSR, 0x3e); 3658 tmpreg = (tmpreg + 1) & 0xff; 3659 SiS_SetReg(SISSR, 0x3e, tmpreg); 3660 tmpreg = SiS_GetReg(SISSR, 0x11); 3661 } 3662 if(tmpreg & 0xf0) { 3663 SiS_SetRegAND(SISSR, 0x11, 0x0f); 3664 } 3665 } 3666 } 3667 #endif 3668 3669 static void 3670 sisfb_set_TVxposoffset(struct sis_video_info *ivideo, int val) 3671 { 3672 if(val > 32) val = 32; 3673 if(val < -32) val = -32; 3674 ivideo->tvxpos = val; 3675 3676 if(ivideo->sisfblocked) return; 3677 if(!ivideo->modechanged) return; 3678 3679 if(ivideo->currentvbflags & CRT2_TV) { 3680 3681 if(ivideo->vbflags2 & VB2_CHRONTEL) { 3682 3683 int x = ivideo->tvx; 3684 3685 switch(ivideo->chronteltype) { 3686 case 1: 3687 x += val; 3688 if(x < 0) x = 0; 3689 SiS_SetReg(SISSR, 0x05, 0x86); 3690 SiS_SetCH700x(&ivideo->SiS_Pr, 0x0a, (x & 0xff)); 3691 SiS_SetCH70xxANDOR(&ivideo->SiS_Pr, 0x08, ((x & 0x0100) >> 7), 0xFD); 3692 break; 3693 case 2: 3694 /* Not supported by hardware */ 3695 break; 3696 } 3697 3698 } else if(ivideo->vbflags2 & VB2_SISBRIDGE) { 3699 3700 u8 p2_1f,p2_20,p2_2b,p2_42,p2_43; 3701 unsigned short temp; 3702 3703 p2_1f = ivideo->p2_1f; 3704 p2_20 = ivideo->p2_20; 3705 p2_2b = ivideo->p2_2b; 3706 p2_42 = ivideo->p2_42; 3707 p2_43 = ivideo->p2_43; 3708 3709 temp = p2_1f | ((p2_20 & 0xf0) << 4); 3710 temp += (val * 2); 3711 p2_1f = temp & 0xff; 3712 p2_20 = (temp & 0xf00) >> 4; 3713 p2_2b = ((p2_2b & 0x0f) + (val * 2)) & 0x0f; 3714 temp = p2_43 | ((p2_42 & 0xf0) << 4); 3715 temp += (val * 2); 3716 p2_43 = temp & 0xff; 3717 p2_42 = (temp & 0xf00) >> 4; 3718 SiS_SetReg(SISPART2, 0x1f, p2_1f); 3719 SiS_SetRegANDOR(SISPART2, 0x20, 0x0F, p2_20); 3720 SiS_SetRegANDOR(SISPART2, 0x2b, 0xF0, p2_2b); 3721 SiS_SetRegANDOR(SISPART2, 0x42, 0x0F, p2_42); 3722 SiS_SetReg(SISPART2, 0x43, p2_43); 3723 } 3724 } 3725 } 3726 3727 static void 3728 sisfb_set_TVyposoffset(struct sis_video_info *ivideo, int val) 3729 { 3730 if(val > 32) val = 32; 3731 if(val < -32) val = -32; 3732 ivideo->tvypos = val; 3733 3734 if(ivideo->sisfblocked) return; 3735 if(!ivideo->modechanged) return; 3736 3737 if(ivideo->currentvbflags & CRT2_TV) { 3738 3739 if(ivideo->vbflags2 & VB2_CHRONTEL) { 3740 3741 int y = ivideo->tvy; 3742 3743 switch(ivideo->chronteltype) { 3744 case 1: 3745 y -= val; 3746 if(y < 0) y = 0; 3747 SiS_SetReg(SISSR, 0x05, 0x86); 3748 SiS_SetCH700x(&ivideo->SiS_Pr, 0x0b, (y & 0xff)); 3749 SiS_SetCH70xxANDOR(&ivideo->SiS_Pr, 0x08, ((y & 0x0100) >> 8), 0xFE); 3750 break; 3751 case 2: 3752 /* Not supported by hardware */ 3753 break; 3754 } 3755 3756 } else if(ivideo->vbflags2 & VB2_SISBRIDGE) { 3757 3758 char p2_01, p2_02; 3759 val /= 2; 3760 p2_01 = ivideo->p2_01; 3761 p2_02 = ivideo->p2_02; 3762 3763 p2_01 += val; 3764 p2_02 += val; 3765 if(!(ivideo->currentvbflags & (TV_HIVISION | TV_YPBPR))) { 3766 while((p2_01 <= 0) || (p2_02 <= 0)) { 3767 p2_01 += 2; 3768 p2_02 += 2; 3769 } 3770 } 3771 SiS_SetReg(SISPART2, 0x01, p2_01); 3772 SiS_SetReg(SISPART2, 0x02, p2_02); 3773 } 3774 } 3775 } 3776 3777 static void 3778 sisfb_post_setmode(struct sis_video_info *ivideo) 3779 { 3780 bool crt1isoff = false; 3781 bool doit = true; 3782 #if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315) 3783 u8 reg; 3784 #endif 3785 #ifdef CONFIG_FB_SIS_315 3786 u8 reg1; 3787 #endif 3788 3789 SiS_SetReg(SISSR, 0x05, 0x86); 3790 3791 #ifdef CONFIG_FB_SIS_315 3792 sisfb_fixup_SR11(ivideo); 3793 #endif 3794 3795 /* Now we actually HAVE changed the display mode */ 3796 ivideo->modechanged = 1; 3797 3798 /* We can't switch off CRT1 if bridge is in slave mode */ 3799 if(ivideo->vbflags2 & VB2_VIDEOBRIDGE) { 3800 if(sisfb_bridgeisslave(ivideo)) doit = false; 3801 } else 3802 ivideo->sisfb_crt1off = 0; 3803 3804 #ifdef CONFIG_FB_SIS_300 3805 if(ivideo->sisvga_engine == SIS_300_VGA) { 3806 if((ivideo->sisfb_crt1off) && (doit)) { 3807 crt1isoff = true; 3808 reg = 0x00; 3809 } else { 3810 crt1isoff = false; 3811 reg = 0x80; 3812 } 3813 SiS_SetRegANDOR(SISCR, 0x17, 0x7f, reg); 3814 } 3815 #endif 3816 #ifdef CONFIG_FB_SIS_315 3817 if(ivideo->sisvga_engine == SIS_315_VGA) { 3818 if((ivideo->sisfb_crt1off) && (doit)) { 3819 crt1isoff = true; 3820 reg = 0x40; 3821 reg1 = 0xc0; 3822 } else { 3823 crt1isoff = false; 3824 reg = 0x00; 3825 reg1 = 0x00; 3826 } 3827 SiS_SetRegANDOR(SISCR, ivideo->SiS_Pr.SiS_MyCR63, ~0x40, reg); 3828 SiS_SetRegANDOR(SISSR, 0x1f, 0x3f, reg1); 3829 } 3830 #endif 3831 3832 if(crt1isoff) { 3833 ivideo->currentvbflags &= ~VB_DISPTYPE_CRT1; 3834 ivideo->currentvbflags |= VB_SINGLE_MODE; 3835 } else { 3836 ivideo->currentvbflags |= VB_DISPTYPE_CRT1; 3837 if(ivideo->currentvbflags & VB_DISPTYPE_CRT2) { 3838 ivideo->currentvbflags |= VB_MIRROR_MODE; 3839 } else { 3840 ivideo->currentvbflags |= VB_SINGLE_MODE; 3841 } 3842 } 3843 3844 SiS_SetRegAND(SISSR, IND_SIS_RAMDAC_CONTROL, ~0x04); 3845 3846 if(ivideo->currentvbflags & CRT2_TV) { 3847 if(ivideo->vbflags2 & VB2_SISBRIDGE) { 3848 ivideo->p2_1f = SiS_GetReg(SISPART2, 0x1f); 3849 ivideo->p2_20 = SiS_GetReg(SISPART2, 0x20); 3850 ivideo->p2_2b = SiS_GetReg(SISPART2, 0x2b); 3851 ivideo->p2_42 = SiS_GetReg(SISPART2, 0x42); 3852 ivideo->p2_43 = SiS_GetReg(SISPART2, 0x43); 3853 ivideo->p2_01 = SiS_GetReg(SISPART2, 0x01); 3854 ivideo->p2_02 = SiS_GetReg(SISPART2, 0x02); 3855 } else if(ivideo->vbflags2 & VB2_CHRONTEL) { 3856 if(ivideo->chronteltype == 1) { 3857 ivideo->tvx = SiS_GetCH700x(&ivideo->SiS_Pr, 0x0a); 3858 ivideo->tvx |= (((SiS_GetCH700x(&ivideo->SiS_Pr, 0x08) & 0x02) >> 1) << 8); 3859 ivideo->tvy = SiS_GetCH700x(&ivideo->SiS_Pr, 0x0b); 3860 ivideo->tvy |= ((SiS_GetCH700x(&ivideo->SiS_Pr, 0x08) & 0x01) << 8); 3861 } 3862 } 3863 } 3864 3865 if(ivideo->tvxpos) { 3866 sisfb_set_TVxposoffset(ivideo, ivideo->tvxpos); 3867 } 3868 if(ivideo->tvypos) { 3869 sisfb_set_TVyposoffset(ivideo, ivideo->tvypos); 3870 } 3871 3872 /* Eventually sync engines */ 3873 sisfb_check_engine_and_sync(ivideo); 3874 3875 /* (Re-)Initialize chip engines */ 3876 if(ivideo->accel) { 3877 sisfb_engine_init(ivideo); 3878 } else { 3879 ivideo->engineok = 0; 3880 } 3881 } 3882 3883 static int 3884 sisfb_reset_mode(struct sis_video_info *ivideo) 3885 { 3886 if(sisfb_set_mode(ivideo, 0)) 3887 return 1; 3888 3889 sisfb_set_pitch(ivideo); 3890 sisfb_set_base_CRT1(ivideo, ivideo->current_base); 3891 sisfb_set_base_CRT2(ivideo, ivideo->current_base); 3892 3893 return 0; 3894 } 3895 3896 static void 3897 sisfb_handle_command(struct sis_video_info *ivideo, struct sisfb_cmd *sisfb_command) 3898 { 3899 int mycrt1off; 3900 3901 switch(sisfb_command->sisfb_cmd) { 3902 case SISFB_CMD_GETVBFLAGS: 3903 if(!ivideo->modechanged) { 3904 sisfb_command->sisfb_result[0] = SISFB_CMD_ERR_EARLY; 3905 } else { 3906 sisfb_command->sisfb_result[0] = SISFB_CMD_ERR_OK; 3907 sisfb_command->sisfb_result[1] = ivideo->currentvbflags; 3908 sisfb_command->sisfb_result[2] = ivideo->vbflags2; 3909 } 3910 break; 3911 case SISFB_CMD_SWITCHCRT1: 3912 /* arg[0]: 0 = off, 1 = on, 99 = query */ 3913 if(!ivideo->modechanged) { 3914 sisfb_command->sisfb_result[0] = SISFB_CMD_ERR_EARLY; 3915 } else if(sisfb_command->sisfb_arg[0] == 99) { 3916 /* Query */ 3917 sisfb_command->sisfb_result[1] = ivideo->sisfb_crt1off ? 0 : 1; 3918 sisfb_command->sisfb_result[0] = SISFB_CMD_ERR_OK; 3919 } else if(ivideo->sisfblocked) { 3920 sisfb_command->sisfb_result[0] = SISFB_CMD_ERR_LOCKED; 3921 } else if((!(ivideo->currentvbflags & CRT2_ENABLE)) && 3922 (sisfb_command->sisfb_arg[0] == 0)) { 3923 sisfb_command->sisfb_result[0] = SISFB_CMD_ERR_NOCRT2; 3924 } else { 3925 sisfb_command->sisfb_result[0] = SISFB_CMD_ERR_OK; 3926 mycrt1off = sisfb_command->sisfb_arg[0] ? 0 : 1; 3927 if( ((ivideo->currentvbflags & VB_DISPTYPE_CRT1) && mycrt1off) || 3928 ((!(ivideo->currentvbflags & VB_DISPTYPE_CRT1)) && !mycrt1off) ) { 3929 ivideo->sisfb_crt1off = mycrt1off; 3930 if(sisfb_reset_mode(ivideo)) { 3931 sisfb_command->sisfb_result[0] = SISFB_CMD_ERR_OTHER; 3932 } 3933 } 3934 sisfb_command->sisfb_result[1] = ivideo->sisfb_crt1off ? 0 : 1; 3935 } 3936 break; 3937 /* more to come */ 3938 default: 3939 sisfb_command->sisfb_result[0] = SISFB_CMD_ERR_UNKNOWN; 3940 printk(KERN_ERR "sisfb: Unknown command 0x%x\n", 3941 sisfb_command->sisfb_cmd); 3942 } 3943 } 3944 3945 #ifndef MODULE 3946 static int __init sisfb_setup(char *options) 3947 { 3948 char *this_opt; 3949 3950 sisfb_setdefaultparms(); 3951 3952 if(!options || !(*options)) 3953 return 0; 3954 3955 while((this_opt = strsep(&options, ",")) != NULL) { 3956 3957 if(!(*this_opt)) continue; 3958 3959 if(!strncasecmp(this_opt, "off", 3)) { 3960 sisfb_off = 1; 3961 } else if(!strncasecmp(this_opt, "forcecrt2type:", 14)) { 3962 /* Need to check crt2 type first for fstn/dstn */ 3963 sisfb_search_crt2type(this_opt + 14); 3964 } else if(!strncasecmp(this_opt, "tvmode:",7)) { 3965 sisfb_search_tvstd(this_opt + 7); 3966 } else if(!strncasecmp(this_opt, "tvstandard:",11)) { 3967 sisfb_search_tvstd(this_opt + 11); 3968 } else if(!strncasecmp(this_opt, "mode:", 5)) { 3969 sisfb_search_mode(this_opt + 5, false); 3970 } else if(!strncasecmp(this_opt, "vesa:", 5)) { 3971 sisfb_search_vesamode(simple_strtoul(this_opt + 5, NULL, 0), false); 3972 } else if(!strncasecmp(this_opt, "rate:", 5)) { 3973 sisfb_parm_rate = simple_strtoul(this_opt + 5, NULL, 0); 3974 } else if(!strncasecmp(this_opt, "forcecrt1:", 10)) { 3975 sisfb_forcecrt1 = (int)simple_strtoul(this_opt + 10, NULL, 0); 3976 } else if(!strncasecmp(this_opt, "mem:",4)) { 3977 sisfb_parm_mem = simple_strtoul(this_opt + 4, NULL, 0); 3978 } else if(!strncasecmp(this_opt, "pdc:", 4)) { 3979 sisfb_pdc = simple_strtoul(this_opt + 4, NULL, 0); 3980 } else if(!strncasecmp(this_opt, "pdc1:", 5)) { 3981 sisfb_pdca = simple_strtoul(this_opt + 5, NULL, 0); 3982 } else if(!strncasecmp(this_opt, "noaccel", 7)) { 3983 sisfb_accel = 0; 3984 } else if(!strncasecmp(this_opt, "accel", 5)) { 3985 sisfb_accel = -1; 3986 } else if(!strncasecmp(this_opt, "noypan", 6)) { 3987 sisfb_ypan = 0; 3988 } else if(!strncasecmp(this_opt, "ypan", 4)) { 3989 sisfb_ypan = -1; 3990 } else if(!strncasecmp(this_opt, "nomax", 5)) { 3991 sisfb_max = 0; 3992 } else if(!strncasecmp(this_opt, "max", 3)) { 3993 sisfb_max = -1; 3994 } else if(!strncasecmp(this_opt, "userom:", 7)) { 3995 sisfb_userom = (int)simple_strtoul(this_opt + 7, NULL, 0); 3996 } else if(!strncasecmp(this_opt, "useoem:", 7)) { 3997 sisfb_useoem = (int)simple_strtoul(this_opt + 7, NULL, 0); 3998 } else if(!strncasecmp(this_opt, "nocrt2rate", 10)) { 3999 sisfb_nocrt2rate = 1; 4000 } else if(!strncasecmp(this_opt, "scalelcd:", 9)) { 4001 unsigned long temp = 2; 4002 temp = simple_strtoul(this_opt + 9, NULL, 0); 4003 if((temp == 0) || (temp == 1)) { 4004 sisfb_scalelcd = temp ^ 1; 4005 } 4006 } else if(!strncasecmp(this_opt, "tvxposoffset:", 13)) { 4007 int temp = 0; 4008 temp = (int)simple_strtol(this_opt + 13, NULL, 0); 4009 if((temp >= -32) && (temp <= 32)) { 4010 sisfb_tvxposoffset = temp; 4011 } 4012 } else if(!strncasecmp(this_opt, "tvyposoffset:", 13)) { 4013 int temp = 0; 4014 temp = (int)simple_strtol(this_opt + 13, NULL, 0); 4015 if((temp >= -32) && (temp <= 32)) { 4016 sisfb_tvyposoffset = temp; 4017 } 4018 } else if(!strncasecmp(this_opt, "specialtiming:", 14)) { 4019 sisfb_search_specialtiming(this_opt + 14); 4020 } else if(!strncasecmp(this_opt, "lvdshl:", 7)) { 4021 int temp = 4; 4022 temp = simple_strtoul(this_opt + 7, NULL, 0); 4023 if((temp >= 0) && (temp <= 3)) { 4024 sisfb_lvdshl = temp; 4025 } 4026 } else if(this_opt[0] >= '0' && this_opt[0] <= '9') { 4027 sisfb_search_mode(this_opt, true); 4028 #if !defined(__i386__) && !defined(__x86_64__) 4029 } else if(!strncasecmp(this_opt, "resetcard", 9)) { 4030 sisfb_resetcard = 1; 4031 } else if(!strncasecmp(this_opt, "videoram:", 9)) { 4032 sisfb_videoram = simple_strtoul(this_opt + 9, NULL, 0); 4033 #endif 4034 } else { 4035 printk(KERN_INFO "sisfb: Invalid option %s\n", this_opt); 4036 } 4037 4038 } 4039 4040 return 0; 4041 } 4042 #endif 4043 4044 static int sisfb_check_rom(void __iomem *rom_base, 4045 struct sis_video_info *ivideo) 4046 { 4047 void __iomem *rom; 4048 int romptr; 4049 4050 if((readb(rom_base) != 0x55) || (readb(rom_base + 1) != 0xaa)) 4051 return 0; 4052 4053 romptr = (readb(rom_base + 0x18) | (readb(rom_base + 0x19) << 8)); 4054 if(romptr > (0x10000 - 8)) 4055 return 0; 4056 4057 rom = rom_base + romptr; 4058 4059 if((readb(rom) != 'P') || (readb(rom + 1) != 'C') || 4060 (readb(rom + 2) != 'I') || (readb(rom + 3) != 'R')) 4061 return 0; 4062 4063 if((readb(rom + 4) | (readb(rom + 5) << 8)) != ivideo->chip_vendor) 4064 return 0; 4065 4066 if((readb(rom + 6) | (readb(rom + 7) << 8)) != ivideo->chip_id) 4067 return 0; 4068 4069 return 1; 4070 } 4071 4072 static unsigned char *sisfb_find_rom(struct pci_dev *pdev) 4073 { 4074 struct sis_video_info *ivideo = pci_get_drvdata(pdev); 4075 void __iomem *rom_base; 4076 unsigned char *myrombase = NULL; 4077 size_t romsize; 4078 4079 /* First, try the official pci ROM functions (except 4080 * on integrated chipsets which have no ROM). 4081 */ 4082 4083 if(!ivideo->nbridge) { 4084 4085 if((rom_base = pci_map_rom(pdev, &romsize))) { 4086 4087 if(sisfb_check_rom(rom_base, ivideo)) { 4088 4089 if((myrombase = vmalloc(65536))) { 4090 memcpy_fromio(myrombase, rom_base, 4091 (romsize > 65536) ? 65536 : romsize); 4092 } 4093 } 4094 pci_unmap_rom(pdev, rom_base); 4095 } 4096 } 4097 4098 if(myrombase) return myrombase; 4099 4100 /* Otherwise do it the conventional way. */ 4101 4102 #if defined(__i386__) || defined(__x86_64__) 4103 { 4104 u32 temp; 4105 4106 for (temp = 0x000c0000; temp < 0x000f0000; temp += 0x00001000) { 4107 4108 rom_base = ioremap(temp, 65536); 4109 if (!rom_base) 4110 continue; 4111 4112 if (!sisfb_check_rom(rom_base, ivideo)) { 4113 iounmap(rom_base); 4114 continue; 4115 } 4116 4117 if ((myrombase = vmalloc(65536))) 4118 memcpy_fromio(myrombase, rom_base, 65536); 4119 4120 iounmap(rom_base); 4121 break; 4122 4123 } 4124 4125 } 4126 #endif 4127 4128 return myrombase; 4129 } 4130 4131 static void sisfb_post_map_vram(struct sis_video_info *ivideo, 4132 unsigned int *mapsize, unsigned int min) 4133 { 4134 if (*mapsize < (min << 20)) 4135 return; 4136 4137 ivideo->video_vbase = ioremap_wc(ivideo->video_base, (*mapsize)); 4138 4139 if(!ivideo->video_vbase) { 4140 printk(KERN_ERR 4141 "sisfb: Unable to map maximum video RAM for size detection\n"); 4142 (*mapsize) >>= 1; 4143 while((!(ivideo->video_vbase = ioremap_wc(ivideo->video_base, (*mapsize))))) { 4144 (*mapsize) >>= 1; 4145 if((*mapsize) < (min << 20)) 4146 break; 4147 } 4148 if(ivideo->video_vbase) { 4149 printk(KERN_ERR 4150 "sisfb: Video RAM size detection limited to %dMB\n", 4151 (int)((*mapsize) >> 20)); 4152 } 4153 } 4154 } 4155 4156 #ifdef CONFIG_FB_SIS_300 4157 static int sisfb_post_300_buswidth(struct sis_video_info *ivideo) 4158 { 4159 void __iomem *FBAddress = ivideo->video_vbase; 4160 unsigned short temp; 4161 unsigned char reg; 4162 int i, j; 4163 4164 SiS_SetRegAND(SISSR, 0x15, 0xFB); 4165 SiS_SetRegOR(SISSR, 0x15, 0x04); 4166 SiS_SetReg(SISSR, 0x13, 0x00); 4167 SiS_SetReg(SISSR, 0x14, 0xBF); 4168 4169 for(i = 0; i < 2; i++) { 4170 temp = 0x1234; 4171 for(j = 0; j < 4; j++) { 4172 writew(temp, FBAddress); 4173 if(readw(FBAddress) == temp) 4174 break; 4175 SiS_SetRegOR(SISSR, 0x3c, 0x01); 4176 reg = SiS_GetReg(SISSR, 0x05); 4177 reg = SiS_GetReg(SISSR, 0x05); 4178 SiS_SetRegAND(SISSR, 0x3c, 0xfe); 4179 reg = SiS_GetReg(SISSR, 0x05); 4180 reg = SiS_GetReg(SISSR, 0x05); 4181 temp++; 4182 } 4183 } 4184 4185 writel(0x01234567L, FBAddress); 4186 writel(0x456789ABL, (FBAddress + 4)); 4187 writel(0x89ABCDEFL, (FBAddress + 8)); 4188 writel(0xCDEF0123L, (FBAddress + 12)); 4189 4190 reg = SiS_GetReg(SISSR, 0x3b); 4191 if(reg & 0x01) { 4192 if(readl((FBAddress + 12)) == 0xCDEF0123L) 4193 return 4; /* Channel A 128bit */ 4194 } 4195 4196 if(readl((FBAddress + 4)) == 0x456789ABL) 4197 return 2; /* Channel B 64bit */ 4198 4199 return 1; /* 32bit */ 4200 } 4201 4202 static const unsigned short SiS_DRAMType[17][5] = { 4203 {0x0C,0x0A,0x02,0x40,0x39}, 4204 {0x0D,0x0A,0x01,0x40,0x48}, 4205 {0x0C,0x09,0x02,0x20,0x35}, 4206 {0x0D,0x09,0x01,0x20,0x44}, 4207 {0x0C,0x08,0x02,0x10,0x31}, 4208 {0x0D,0x08,0x01,0x10,0x40}, 4209 {0x0C,0x0A,0x01,0x20,0x34}, 4210 {0x0C,0x09,0x01,0x08,0x32}, 4211 {0x0B,0x08,0x02,0x08,0x21}, 4212 {0x0C,0x08,0x01,0x08,0x30}, 4213 {0x0A,0x08,0x02,0x04,0x11}, 4214 {0x0B,0x0A,0x01,0x10,0x28}, 4215 {0x09,0x08,0x02,0x02,0x01}, 4216 {0x0B,0x09,0x01,0x08,0x24}, 4217 {0x0B,0x08,0x01,0x04,0x20}, 4218 {0x0A,0x08,0x01,0x02,0x10}, 4219 {0x09,0x08,0x01,0x01,0x00} 4220 }; 4221 4222 static int sisfb_post_300_rwtest(struct sis_video_info *ivideo, int iteration, 4223 int buswidth, int PseudoRankCapacity, 4224 int PseudoAdrPinCount, unsigned int mapsize) 4225 { 4226 void __iomem *FBAddr = ivideo->video_vbase; 4227 unsigned short sr14; 4228 unsigned int k, RankCapacity, PageCapacity, BankNumHigh, BankNumMid; 4229 unsigned int PhysicalAdrOtherPage, PhysicalAdrHigh, PhysicalAdrHalfPage; 4230 4231 for (k = 0; k < ARRAY_SIZE(SiS_DRAMType); k++) { 4232 RankCapacity = buswidth * SiS_DRAMType[k][3]; 4233 4234 if (RankCapacity != PseudoRankCapacity) 4235 continue; 4236 4237 if ((SiS_DRAMType[k][2] + SiS_DRAMType[k][0]) > PseudoAdrPinCount) 4238 continue; 4239 4240 BankNumHigh = RankCapacity * 16 * iteration - 1; 4241 if (iteration == 3) { /* Rank No */ 4242 BankNumMid = RankCapacity * 16 - 1; 4243 } else { 4244 BankNumMid = RankCapacity * 16 * iteration / 2 - 1; 4245 } 4246 4247 PageCapacity = (1 << SiS_DRAMType[k][1]) * buswidth * 4; 4248 PhysicalAdrHigh = BankNumHigh; 4249 PhysicalAdrHalfPage = (PageCapacity / 2 + PhysicalAdrHigh) % PageCapacity; 4250 PhysicalAdrOtherPage = PageCapacity * SiS_DRAMType[k][2] + PhysicalAdrHigh; 4251 4252 SiS_SetRegAND(SISSR, 0x15, 0xFB); /* Test */ 4253 SiS_SetRegOR(SISSR, 0x15, 0x04); /* Test */ 4254 sr14 = (SiS_DRAMType[k][3] * buswidth) - 1; 4255 4256 if (buswidth == 4) 4257 sr14 |= 0x80; 4258 else if (buswidth == 2) 4259 sr14 |= 0x40; 4260 4261 SiS_SetReg(SISSR, 0x13, SiS_DRAMType[k][4]); 4262 SiS_SetReg(SISSR, 0x14, sr14); 4263 4264 BankNumHigh <<= 16; 4265 BankNumMid <<= 16; 4266 4267 if ((BankNumHigh + PhysicalAdrHigh >= mapsize) || 4268 (BankNumMid + PhysicalAdrHigh >= mapsize) || 4269 (BankNumHigh + PhysicalAdrHalfPage >= mapsize) || 4270 (BankNumHigh + PhysicalAdrOtherPage >= mapsize)) 4271 continue; 4272 4273 /* Write data */ 4274 writew(((unsigned short)PhysicalAdrHigh), 4275 (FBAddr + BankNumHigh + PhysicalAdrHigh)); 4276 writew(((unsigned short)BankNumMid), 4277 (FBAddr + BankNumMid + PhysicalAdrHigh)); 4278 writew(((unsigned short)PhysicalAdrHalfPage), 4279 (FBAddr + BankNumHigh + PhysicalAdrHalfPage)); 4280 writew(((unsigned short)PhysicalAdrOtherPage), 4281 (FBAddr + BankNumHigh + PhysicalAdrOtherPage)); 4282 4283 /* Read data */ 4284 if (readw(FBAddr + BankNumHigh + PhysicalAdrHigh) == PhysicalAdrHigh) 4285 return 1; 4286 } 4287 4288 return 0; 4289 } 4290 4291 static void sisfb_post_300_ramsize(struct pci_dev *pdev, unsigned int mapsize) 4292 { 4293 struct sis_video_info *ivideo = pci_get_drvdata(pdev); 4294 int i, j, buswidth; 4295 int PseudoRankCapacity, PseudoAdrPinCount; 4296 4297 buswidth = sisfb_post_300_buswidth(ivideo); 4298 4299 for(i = 6; i >= 0; i--) { 4300 PseudoRankCapacity = 1 << i; 4301 for(j = 4; j >= 1; j--) { 4302 PseudoAdrPinCount = 15 - j; 4303 if((PseudoRankCapacity * j) <= 64) { 4304 if(sisfb_post_300_rwtest(ivideo, 4305 j, 4306 buswidth, 4307 PseudoRankCapacity, 4308 PseudoAdrPinCount, 4309 mapsize)) 4310 return; 4311 } 4312 } 4313 } 4314 } 4315 4316 static void sisfb_post_sis300(struct pci_dev *pdev) 4317 { 4318 struct sis_video_info *ivideo = pci_get_drvdata(pdev); 4319 unsigned char *bios = ivideo->SiS_Pr.VirtualRomBase; 4320 u8 reg, v1, v2, v3, v4, v5, v6, v7, v8; 4321 u16 index, rindex, memtype = 0; 4322 unsigned int mapsize; 4323 4324 if(!ivideo->SiS_Pr.UseROM) 4325 bios = NULL; 4326 4327 SiS_SetReg(SISSR, 0x05, 0x86); 4328 4329 if(bios) { 4330 if(bios[0x52] & 0x80) { 4331 memtype = bios[0x52]; 4332 } else { 4333 memtype = SiS_GetReg(SISSR, 0x3a); 4334 } 4335 memtype &= 0x07; 4336 } 4337 4338 v3 = 0x80; v6 = 0x80; 4339 if(ivideo->revision_id <= 0x13) { 4340 v1 = 0x44; v2 = 0x42; 4341 v4 = 0x44; v5 = 0x42; 4342 } else { 4343 v1 = 0x68; v2 = 0x43; /* Assume 125Mhz MCLK */ 4344 v4 = 0x68; v5 = 0x43; /* Assume 125Mhz ECLK */ 4345 if(bios) { 4346 index = memtype * 5; 4347 rindex = index + 0x54; 4348 v1 = bios[rindex++]; 4349 v2 = bios[rindex++]; 4350 v3 = bios[rindex++]; 4351 rindex = index + 0x7c; 4352 v4 = bios[rindex++]; 4353 v5 = bios[rindex++]; 4354 v6 = bios[rindex++]; 4355 } 4356 } 4357 SiS_SetReg(SISSR, 0x28, v1); 4358 SiS_SetReg(SISSR, 0x29, v2); 4359 SiS_SetReg(SISSR, 0x2a, v3); 4360 SiS_SetReg(SISSR, 0x2e, v4); 4361 SiS_SetReg(SISSR, 0x2f, v5); 4362 SiS_SetReg(SISSR, 0x30, v6); 4363 4364 v1 = 0x10; 4365 if(bios) 4366 v1 = bios[0xa4]; 4367 SiS_SetReg(SISSR, 0x07, v1); /* DAC speed */ 4368 4369 SiS_SetReg(SISSR, 0x11, 0x0f); /* DDC, power save */ 4370 4371 v1 = 0x01; v2 = 0x43; v3 = 0x1e; v4 = 0x2a; 4372 v5 = 0x06; v6 = 0x00; v7 = 0x00; v8 = 0x00; 4373 if(bios) { 4374 memtype += 0xa5; 4375 v1 = bios[memtype]; 4376 v2 = bios[memtype + 8]; 4377 v3 = bios[memtype + 16]; 4378 v4 = bios[memtype + 24]; 4379 v5 = bios[memtype + 32]; 4380 v6 = bios[memtype + 40]; 4381 v7 = bios[memtype + 48]; 4382 v8 = bios[memtype + 56]; 4383 } 4384 if(ivideo->revision_id >= 0x80) 4385 v3 &= 0xfd; 4386 SiS_SetReg(SISSR, 0x15, v1); /* Ram type (assuming 0, BIOS 0xa5 step 8) */ 4387 SiS_SetReg(SISSR, 0x16, v2); 4388 SiS_SetReg(SISSR, 0x17, v3); 4389 SiS_SetReg(SISSR, 0x18, v4); 4390 SiS_SetReg(SISSR, 0x19, v5); 4391 SiS_SetReg(SISSR, 0x1a, v6); 4392 SiS_SetReg(SISSR, 0x1b, v7); 4393 SiS_SetReg(SISSR, 0x1c, v8); /* ---- */ 4394 SiS_SetRegAND(SISSR, 0x15, 0xfb); 4395 SiS_SetRegOR(SISSR, 0x15, 0x04); 4396 if(bios) { 4397 if(bios[0x53] & 0x02) { 4398 SiS_SetRegOR(SISSR, 0x19, 0x20); 4399 } 4400 } 4401 v1 = 0x04; /* DAC pedestal (BIOS 0xe5) */ 4402 if(ivideo->revision_id >= 0x80) 4403 v1 |= 0x01; 4404 SiS_SetReg(SISSR, 0x1f, v1); 4405 SiS_SetReg(SISSR, 0x20, 0xa4); /* linear & relocated io & disable a0000 */ 4406 v1 = 0xf6; v2 = 0x0d; v3 = 0x00; 4407 if(bios) { 4408 v1 = bios[0xe8]; 4409 v2 = bios[0xe9]; 4410 v3 = bios[0xea]; 4411 } 4412 SiS_SetReg(SISSR, 0x23, v1); 4413 SiS_SetReg(SISSR, 0x24, v2); 4414 SiS_SetReg(SISSR, 0x25, v3); 4415 SiS_SetReg(SISSR, 0x21, 0x84); 4416 SiS_SetReg(SISSR, 0x22, 0x00); 4417 SiS_SetReg(SISCR, 0x37, 0x00); 4418 SiS_SetRegOR(SISPART1, 0x24, 0x01); /* unlock crt2 */ 4419 SiS_SetReg(SISPART1, 0x00, 0x00); 4420 v1 = 0x40; v2 = 0x11; 4421 if(bios) { 4422 v1 = bios[0xec]; 4423 v2 = bios[0xeb]; 4424 } 4425 SiS_SetReg(SISPART1, 0x02, v1); 4426 4427 if(ivideo->revision_id >= 0x80) 4428 v2 &= ~0x01; 4429 4430 reg = SiS_GetReg(SISPART4, 0x00); 4431 if((reg == 1) || (reg == 2)) { 4432 SiS_SetReg(SISCR, 0x37, 0x02); 4433 SiS_SetReg(SISPART2, 0x00, 0x1c); 4434 v4 = 0x00; v5 = 0x00; v6 = 0x10; 4435 if (ivideo->SiS_Pr.UseROM && bios) { 4436 v4 = bios[0xf5]; 4437 v5 = bios[0xf6]; 4438 v6 = bios[0xf7]; 4439 } 4440 SiS_SetReg(SISPART4, 0x0d, v4); 4441 SiS_SetReg(SISPART4, 0x0e, v5); 4442 SiS_SetReg(SISPART4, 0x10, v6); 4443 SiS_SetReg(SISPART4, 0x0f, 0x3f); 4444 reg = SiS_GetReg(SISPART4, 0x01); 4445 if(reg >= 0xb0) { 4446 reg = SiS_GetReg(SISPART4, 0x23); 4447 reg &= 0x20; 4448 reg <<= 1; 4449 SiS_SetReg(SISPART4, 0x23, reg); 4450 } 4451 } else { 4452 v2 &= ~0x10; 4453 } 4454 SiS_SetReg(SISSR, 0x32, v2); 4455 4456 SiS_SetRegAND(SISPART1, 0x24, 0xfe); /* Lock CRT2 */ 4457 4458 reg = SiS_GetReg(SISSR, 0x16); 4459 reg &= 0xc3; 4460 SiS_SetReg(SISCR, 0x35, reg); 4461 SiS_SetReg(SISCR, 0x83, 0x00); 4462 #if !defined(__i386__) && !defined(__x86_64__) 4463 if(sisfb_videoram) { 4464 SiS_SetReg(SISSR, 0x13, 0x28); /* ? */ 4465 reg = ((sisfb_videoram >> 10) - 1) | 0x40; 4466 SiS_SetReg(SISSR, 0x14, reg); 4467 } else { 4468 #endif 4469 /* Need to map max FB size for finding out about RAM size */ 4470 mapsize = ivideo->video_size; 4471 sisfb_post_map_vram(ivideo, &mapsize, 4); 4472 4473 if(ivideo->video_vbase) { 4474 sisfb_post_300_ramsize(pdev, mapsize); 4475 iounmap(ivideo->video_vbase); 4476 } else { 4477 printk(KERN_DEBUG 4478 "sisfb: Failed to map memory for size detection, assuming 8MB\n"); 4479 SiS_SetReg(SISSR, 0x13, 0x28); /* ? */ 4480 SiS_SetReg(SISSR, 0x14, 0x47); /* 8MB, 64bit default */ 4481 } 4482 #if !defined(__i386__) && !defined(__x86_64__) 4483 } 4484 #endif 4485 if(bios) { 4486 v1 = bios[0xe6]; 4487 v2 = bios[0xe7]; 4488 } else { 4489 reg = SiS_GetReg(SISSR, 0x3a); 4490 if((reg & 0x30) == 0x30) { 4491 v1 = 0x04; /* PCI */ 4492 v2 = 0x92; 4493 } else { 4494 v1 = 0x14; /* AGP */ 4495 v2 = 0xb2; 4496 } 4497 } 4498 SiS_SetReg(SISSR, 0x21, v1); 4499 SiS_SetReg(SISSR, 0x22, v2); 4500 4501 /* Sense CRT1 */ 4502 sisfb_sense_crt1(ivideo); 4503 4504 /* Set default mode, don't clear screen */ 4505 ivideo->SiS_Pr.SiS_UseOEM = false; 4506 SiS_SetEnableDstn(&ivideo->SiS_Pr, false); 4507 SiS_SetEnableFstn(&ivideo->SiS_Pr, false); 4508 ivideo->curFSTN = ivideo->curDSTN = 0; 4509 ivideo->SiS_Pr.VideoMemorySize = 8 << 20; 4510 SiSSetMode(&ivideo->SiS_Pr, 0x2e | 0x80); 4511 4512 SiS_SetReg(SISSR, 0x05, 0x86); 4513 4514 /* Display off */ 4515 SiS_SetRegOR(SISSR, 0x01, 0x20); 4516 4517 /* Save mode number in CR34 */ 4518 SiS_SetReg(SISCR, 0x34, 0x2e); 4519 4520 /* Let everyone know what the current mode is */ 4521 ivideo->modeprechange = 0x2e; 4522 } 4523 #endif 4524 4525 #ifdef CONFIG_FB_SIS_315 4526 #if 0 4527 static void sisfb_post_sis315330(struct pci_dev *pdev) 4528 { 4529 /* TODO */ 4530 } 4531 #endif 4532 4533 static inline int sisfb_xgi_is21(struct sis_video_info *ivideo) 4534 { 4535 return ivideo->chip_real_id == XGI_21; 4536 } 4537 4538 static void sisfb_post_xgi_delay(struct sis_video_info *ivideo, int delay) 4539 { 4540 unsigned int i; 4541 u8 reg; 4542 4543 for(i = 0; i <= (delay * 10 * 36); i++) { 4544 reg = SiS_GetReg(SISSR, 0x05); 4545 reg++; 4546 } 4547 } 4548 4549 static int sisfb_find_host_bridge(struct sis_video_info *ivideo, 4550 struct pci_dev *mypdev, 4551 unsigned short pcivendor) 4552 { 4553 struct pci_dev *pdev = NULL; 4554 unsigned short temp; 4555 int ret = 0; 4556 4557 while((pdev = pci_get_class(PCI_CLASS_BRIDGE_HOST, pdev))) { 4558 temp = pdev->vendor; 4559 if(temp == pcivendor) { 4560 ret = 1; 4561 pci_dev_put(pdev); 4562 break; 4563 } 4564 } 4565 4566 return ret; 4567 } 4568 4569 static int sisfb_post_xgi_rwtest(struct sis_video_info *ivideo, int starta, 4570 unsigned int enda, unsigned int mapsize) 4571 { 4572 unsigned int pos; 4573 int i; 4574 4575 writel(0, ivideo->video_vbase); 4576 4577 for(i = starta; i <= enda; i++) { 4578 pos = 1 << i; 4579 if(pos < mapsize) 4580 writel(pos, ivideo->video_vbase + pos); 4581 } 4582 4583 sisfb_post_xgi_delay(ivideo, 150); 4584 4585 if(readl(ivideo->video_vbase) != 0) 4586 return 0; 4587 4588 for(i = starta; i <= enda; i++) { 4589 pos = 1 << i; 4590 if(pos < mapsize) { 4591 if(readl(ivideo->video_vbase + pos) != pos) 4592 return 0; 4593 } else 4594 return 0; 4595 } 4596 4597 return 1; 4598 } 4599 4600 static int sisfb_post_xgi_ramsize(struct sis_video_info *ivideo) 4601 { 4602 unsigned int buswidth, ranksize, channelab, mapsize; 4603 int i, j, k, l, status; 4604 u8 reg, sr14; 4605 static const u8 dramsr13[12 * 5] = { 4606 0x02, 0x0e, 0x0b, 0x80, 0x5d, 4607 0x02, 0x0e, 0x0a, 0x40, 0x59, 4608 0x02, 0x0d, 0x0b, 0x40, 0x4d, 4609 0x02, 0x0e, 0x09, 0x20, 0x55, 4610 0x02, 0x0d, 0x0a, 0x20, 0x49, 4611 0x02, 0x0c, 0x0b, 0x20, 0x3d, 4612 0x02, 0x0e, 0x08, 0x10, 0x51, 4613 0x02, 0x0d, 0x09, 0x10, 0x45, 4614 0x02, 0x0c, 0x0a, 0x10, 0x39, 4615 0x02, 0x0d, 0x08, 0x08, 0x41, 4616 0x02, 0x0c, 0x09, 0x08, 0x35, 4617 0x02, 0x0c, 0x08, 0x04, 0x31 4618 }; 4619 static const u8 dramsr13_4[4 * 5] = { 4620 0x02, 0x0d, 0x09, 0x40, 0x45, 4621 0x02, 0x0c, 0x09, 0x20, 0x35, 4622 0x02, 0x0c, 0x08, 0x10, 0x31, 4623 0x02, 0x0b, 0x08, 0x08, 0x21 4624 }; 4625 4626 /* Enable linear mode, disable 0xa0000 address decoding */ 4627 /* We disable a0000 address decoding, because 4628 * - if running on x86, if the card is disabled, it means 4629 * that another card is in the system. We don't want 4630 * to interphere with that primary card's textmode. 4631 * - if running on non-x86, there usually is no VGA window 4632 * at a0000. 4633 */ 4634 SiS_SetRegOR(SISSR, 0x20, (0x80 | 0x04)); 4635 4636 /* Need to map max FB size for finding out about RAM size */ 4637 mapsize = ivideo->video_size; 4638 sisfb_post_map_vram(ivideo, &mapsize, 32); 4639 4640 if(!ivideo->video_vbase) { 4641 printk(KERN_ERR "sisfb: Unable to detect RAM size. Setting default.\n"); 4642 SiS_SetReg(SISSR, 0x13, 0x35); 4643 SiS_SetReg(SISSR, 0x14, 0x41); 4644 /* TODO */ 4645 return -ENOMEM; 4646 } 4647 4648 /* Non-interleaving */ 4649 SiS_SetReg(SISSR, 0x15, 0x00); 4650 /* No tiling */ 4651 SiS_SetReg(SISSR, 0x1c, 0x00); 4652 4653 if(ivideo->chip == XGI_20) { 4654 4655 channelab = 1; 4656 reg = SiS_GetReg(SISCR, 0x97); 4657 if(!(reg & 0x01)) { /* Single 32/16 */ 4658 buswidth = 32; 4659 SiS_SetReg(SISSR, 0x13, 0xb1); 4660 SiS_SetReg(SISSR, 0x14, 0x52); 4661 sisfb_post_xgi_delay(ivideo, 1); 4662 sr14 = 0x02; 4663 if(sisfb_post_xgi_rwtest(ivideo, 23, 24, mapsize)) 4664 goto bail_out; 4665 4666 SiS_SetReg(SISSR, 0x13, 0x31); 4667 SiS_SetReg(SISSR, 0x14, 0x42); 4668 sisfb_post_xgi_delay(ivideo, 1); 4669 if(sisfb_post_xgi_rwtest(ivideo, 23, 23, mapsize)) 4670 goto bail_out; 4671 4672 buswidth = 16; 4673 SiS_SetReg(SISSR, 0x13, 0xb1); 4674 SiS_SetReg(SISSR, 0x14, 0x41); 4675 sisfb_post_xgi_delay(ivideo, 1); 4676 sr14 = 0x01; 4677 if(sisfb_post_xgi_rwtest(ivideo, 22, 23, mapsize)) 4678 goto bail_out; 4679 else 4680 SiS_SetReg(SISSR, 0x13, 0x31); 4681 } else { /* Dual 16/8 */ 4682 buswidth = 16; 4683 SiS_SetReg(SISSR, 0x13, 0xb1); 4684 SiS_SetReg(SISSR, 0x14, 0x41); 4685 sisfb_post_xgi_delay(ivideo, 1); 4686 sr14 = 0x01; 4687 if(sisfb_post_xgi_rwtest(ivideo, 22, 23, mapsize)) 4688 goto bail_out; 4689 4690 SiS_SetReg(SISSR, 0x13, 0x31); 4691 SiS_SetReg(SISSR, 0x14, 0x31); 4692 sisfb_post_xgi_delay(ivideo, 1); 4693 if(sisfb_post_xgi_rwtest(ivideo, 22, 22, mapsize)) 4694 goto bail_out; 4695 4696 buswidth = 8; 4697 SiS_SetReg(SISSR, 0x13, 0xb1); 4698 SiS_SetReg(SISSR, 0x14, 0x30); 4699 sisfb_post_xgi_delay(ivideo, 1); 4700 sr14 = 0x00; 4701 if(sisfb_post_xgi_rwtest(ivideo, 21, 22, mapsize)) 4702 goto bail_out; 4703 else 4704 SiS_SetReg(SISSR, 0x13, 0x31); 4705 } 4706 4707 } else { /* XGI_40 */ 4708 4709 reg = SiS_GetReg(SISCR, 0x97); 4710 if(!(reg & 0x10)) { 4711 reg = SiS_GetReg(SISSR, 0x39); 4712 reg >>= 1; 4713 } 4714 4715 if(reg & 0x01) { /* DDRII */ 4716 buswidth = 32; 4717 if(ivideo->revision_id == 2) { 4718 channelab = 2; 4719 SiS_SetReg(SISSR, 0x13, 0xa1); 4720 SiS_SetReg(SISSR, 0x14, 0x44); 4721 sr14 = 0x04; 4722 sisfb_post_xgi_delay(ivideo, 1); 4723 if(sisfb_post_xgi_rwtest(ivideo, 23, 24, mapsize)) 4724 goto bail_out; 4725 4726 SiS_SetReg(SISSR, 0x13, 0x21); 4727 SiS_SetReg(SISSR, 0x14, 0x34); 4728 if(sisfb_post_xgi_rwtest(ivideo, 22, 23, mapsize)) 4729 goto bail_out; 4730 4731 channelab = 1; 4732 SiS_SetReg(SISSR, 0x13, 0xa1); 4733 SiS_SetReg(SISSR, 0x14, 0x40); 4734 sr14 = 0x00; 4735 if(sisfb_post_xgi_rwtest(ivideo, 22, 23, mapsize)) 4736 goto bail_out; 4737 4738 SiS_SetReg(SISSR, 0x13, 0x21); 4739 SiS_SetReg(SISSR, 0x14, 0x30); 4740 } else { 4741 channelab = 3; 4742 SiS_SetReg(SISSR, 0x13, 0xa1); 4743 SiS_SetReg(SISSR, 0x14, 0x4c); 4744 sr14 = 0x0c; 4745 sisfb_post_xgi_delay(ivideo, 1); 4746 if(sisfb_post_xgi_rwtest(ivideo, 23, 25, mapsize)) 4747 goto bail_out; 4748 4749 channelab = 2; 4750 SiS_SetReg(SISSR, 0x14, 0x48); 4751 sisfb_post_xgi_delay(ivideo, 1); 4752 sr14 = 0x08; 4753 if(sisfb_post_xgi_rwtest(ivideo, 23, 24, mapsize)) 4754 goto bail_out; 4755 4756 SiS_SetReg(SISSR, 0x13, 0x21); 4757 SiS_SetReg(SISSR, 0x14, 0x3c); 4758 sr14 = 0x0c; 4759 4760 if(sisfb_post_xgi_rwtest(ivideo, 23, 24, mapsize)) { 4761 channelab = 3; 4762 } else { 4763 channelab = 2; 4764 SiS_SetReg(SISSR, 0x14, 0x38); 4765 sr14 = 0x08; 4766 } 4767 } 4768 sisfb_post_xgi_delay(ivideo, 1); 4769 4770 } else { /* DDR */ 4771 4772 buswidth = 64; 4773 if(ivideo->revision_id == 2) { 4774 channelab = 1; 4775 SiS_SetReg(SISSR, 0x13, 0xa1); 4776 SiS_SetReg(SISSR, 0x14, 0x52); 4777 sisfb_post_xgi_delay(ivideo, 1); 4778 sr14 = 0x02; 4779 if(sisfb_post_xgi_rwtest(ivideo, 23, 24, mapsize)) 4780 goto bail_out; 4781 4782 SiS_SetReg(SISSR, 0x13, 0x21); 4783 SiS_SetReg(SISSR, 0x14, 0x42); 4784 } else { 4785 channelab = 2; 4786 SiS_SetReg(SISSR, 0x13, 0xa1); 4787 SiS_SetReg(SISSR, 0x14, 0x5a); 4788 sisfb_post_xgi_delay(ivideo, 1); 4789 sr14 = 0x0a; 4790 if(sisfb_post_xgi_rwtest(ivideo, 24, 25, mapsize)) 4791 goto bail_out; 4792 4793 SiS_SetReg(SISSR, 0x13, 0x21); 4794 SiS_SetReg(SISSR, 0x14, 0x4a); 4795 } 4796 sisfb_post_xgi_delay(ivideo, 1); 4797 4798 } 4799 } 4800 4801 bail_out: 4802 SiS_SetRegANDOR(SISSR, 0x14, 0xf0, sr14); 4803 sisfb_post_xgi_delay(ivideo, 1); 4804 4805 j = (ivideo->chip == XGI_20) ? 5 : 9; 4806 k = (ivideo->chip == XGI_20) ? 12 : 4; 4807 status = -EIO; 4808 4809 for(i = 0; i < k; i++) { 4810 4811 reg = (ivideo->chip == XGI_20) ? 4812 dramsr13[(i * 5) + 4] : dramsr13_4[(i * 5) + 4]; 4813 SiS_SetRegANDOR(SISSR, 0x13, 0x80, reg); 4814 sisfb_post_xgi_delay(ivideo, 50); 4815 4816 ranksize = (ivideo->chip == XGI_20) ? 4817 dramsr13[(i * 5) + 3] : dramsr13_4[(i * 5) + 3]; 4818 4819 reg = SiS_GetReg(SISSR, 0x13); 4820 if(reg & 0x80) ranksize <<= 1; 4821 4822 if(ivideo->chip == XGI_20) { 4823 if(buswidth == 16) ranksize <<= 1; 4824 else if(buswidth == 32) ranksize <<= 2; 4825 } else { 4826 if(buswidth == 64) ranksize <<= 1; 4827 } 4828 4829 reg = 0; 4830 l = channelab; 4831 if(l == 3) l = 4; 4832 if((ranksize * l) <= 256) { 4833 while((ranksize >>= 1)) reg += 0x10; 4834 } 4835 4836 if(!reg) continue; 4837 4838 SiS_SetRegANDOR(SISSR, 0x14, 0x0f, (reg & 0xf0)); 4839 sisfb_post_xgi_delay(ivideo, 1); 4840 4841 if (sisfb_post_xgi_rwtest(ivideo, j, ((reg >> 4) + channelab - 2 + 20), mapsize)) { 4842 status = 0; 4843 break; 4844 } 4845 } 4846 4847 iounmap(ivideo->video_vbase); 4848 4849 return status; 4850 } 4851 4852 static void sisfb_post_xgi_setclocks(struct sis_video_info *ivideo, u8 regb) 4853 { 4854 u8 v1, v2, v3; 4855 int index; 4856 static const u8 cs90[8 * 3] = { 4857 0x16, 0x01, 0x01, 4858 0x3e, 0x03, 0x01, 4859 0x7c, 0x08, 0x01, 4860 0x79, 0x06, 0x01, 4861 0x29, 0x01, 0x81, 4862 0x5c, 0x23, 0x01, 4863 0x5c, 0x23, 0x01, 4864 0x5c, 0x23, 0x01 4865 }; 4866 static const u8 csb8[8 * 3] = { 4867 0x5c, 0x23, 0x01, 4868 0x29, 0x01, 0x01, 4869 0x7c, 0x08, 0x01, 4870 0x79, 0x06, 0x01, 4871 0x29, 0x01, 0x81, 4872 0x5c, 0x23, 0x01, 4873 0x5c, 0x23, 0x01, 4874 0x5c, 0x23, 0x01 4875 }; 4876 4877 regb = 0; /* ! */ 4878 4879 index = regb * 3; 4880 v1 = cs90[index]; v2 = cs90[index + 1]; v3 = cs90[index + 2]; 4881 if(ivideo->haveXGIROM) { 4882 v1 = ivideo->bios_abase[0x90 + index]; 4883 v2 = ivideo->bios_abase[0x90 + index + 1]; 4884 v3 = ivideo->bios_abase[0x90 + index + 2]; 4885 } 4886 SiS_SetReg(SISSR, 0x28, v1); 4887 SiS_SetReg(SISSR, 0x29, v2); 4888 SiS_SetReg(SISSR, 0x2a, v3); 4889 sisfb_post_xgi_delay(ivideo, 0x43); 4890 sisfb_post_xgi_delay(ivideo, 0x43); 4891 sisfb_post_xgi_delay(ivideo, 0x43); 4892 index = regb * 3; 4893 v1 = csb8[index]; v2 = csb8[index + 1]; v3 = csb8[index + 2]; 4894 if(ivideo->haveXGIROM) { 4895 v1 = ivideo->bios_abase[0xb8 + index]; 4896 v2 = ivideo->bios_abase[0xb8 + index + 1]; 4897 v3 = ivideo->bios_abase[0xb8 + index + 2]; 4898 } 4899 SiS_SetReg(SISSR, 0x2e, v1); 4900 SiS_SetReg(SISSR, 0x2f, v2); 4901 SiS_SetReg(SISSR, 0x30, v3); 4902 sisfb_post_xgi_delay(ivideo, 0x43); 4903 sisfb_post_xgi_delay(ivideo, 0x43); 4904 sisfb_post_xgi_delay(ivideo, 0x43); 4905 } 4906 4907 static void sisfb_post_xgi_ddr2_mrs_default(struct sis_video_info *ivideo, 4908 u8 regb) 4909 { 4910 unsigned char *bios = ivideo->bios_abase; 4911 u8 v1; 4912 4913 SiS_SetReg(SISSR, 0x28, 0x64); 4914 SiS_SetReg(SISSR, 0x29, 0x63); 4915 sisfb_post_xgi_delay(ivideo, 15); 4916 SiS_SetReg(SISSR, 0x18, 0x00); 4917 SiS_SetReg(SISSR, 0x19, 0x20); 4918 SiS_SetReg(SISSR, 0x16, 0x00); 4919 SiS_SetReg(SISSR, 0x16, 0x80); 4920 SiS_SetReg(SISSR, 0x18, 0xc5); 4921 SiS_SetReg(SISSR, 0x19, 0x23); 4922 SiS_SetReg(SISSR, 0x16, 0x00); 4923 SiS_SetReg(SISSR, 0x16, 0x80); 4924 sisfb_post_xgi_delay(ivideo, 1); 4925 SiS_SetReg(SISCR, 0x97, 0x11); 4926 sisfb_post_xgi_setclocks(ivideo, regb); 4927 sisfb_post_xgi_delay(ivideo, 0x46); 4928 SiS_SetReg(SISSR, 0x18, 0xc5); 4929 SiS_SetReg(SISSR, 0x19, 0x23); 4930 SiS_SetReg(SISSR, 0x16, 0x00); 4931 SiS_SetReg(SISSR, 0x16, 0x80); 4932 sisfb_post_xgi_delay(ivideo, 1); 4933 SiS_SetReg(SISSR, 0x1b, 0x04); 4934 sisfb_post_xgi_delay(ivideo, 1); 4935 SiS_SetReg(SISSR, 0x1b, 0x00); 4936 sisfb_post_xgi_delay(ivideo, 1); 4937 v1 = 0x31; 4938 if (ivideo->haveXGIROM) { 4939 v1 = bios[0xf0]; 4940 } 4941 SiS_SetReg(SISSR, 0x18, v1); 4942 SiS_SetReg(SISSR, 0x19, 0x06); 4943 SiS_SetReg(SISSR, 0x16, 0x04); 4944 SiS_SetReg(SISSR, 0x16, 0x84); 4945 sisfb_post_xgi_delay(ivideo, 1); 4946 } 4947 4948 static void sisfb_post_xgi_ddr2_mrs_xg21(struct sis_video_info *ivideo) 4949 { 4950 sisfb_post_xgi_setclocks(ivideo, 1); 4951 4952 SiS_SetReg(SISCR, 0x97, 0x11); 4953 sisfb_post_xgi_delay(ivideo, 0x46); 4954 4955 SiS_SetReg(SISSR, 0x18, 0x00); /* EMRS2 */ 4956 SiS_SetReg(SISSR, 0x19, 0x80); 4957 SiS_SetReg(SISSR, 0x16, 0x05); 4958 SiS_SetReg(SISSR, 0x16, 0x85); 4959 4960 SiS_SetReg(SISSR, 0x18, 0x00); /* EMRS3 */ 4961 SiS_SetReg(SISSR, 0x19, 0xc0); 4962 SiS_SetReg(SISSR, 0x16, 0x05); 4963 SiS_SetReg(SISSR, 0x16, 0x85); 4964 4965 SiS_SetReg(SISSR, 0x18, 0x00); /* EMRS1 */ 4966 SiS_SetReg(SISSR, 0x19, 0x40); 4967 SiS_SetReg(SISSR, 0x16, 0x05); 4968 SiS_SetReg(SISSR, 0x16, 0x85); 4969 4970 SiS_SetReg(SISSR, 0x18, 0x42); /* MRS1 */ 4971 SiS_SetReg(SISSR, 0x19, 0x02); 4972 SiS_SetReg(SISSR, 0x16, 0x05); 4973 SiS_SetReg(SISSR, 0x16, 0x85); 4974 sisfb_post_xgi_delay(ivideo, 1); 4975 4976 SiS_SetReg(SISSR, 0x1b, 0x04); 4977 sisfb_post_xgi_delay(ivideo, 1); 4978 4979 SiS_SetReg(SISSR, 0x1b, 0x00); 4980 sisfb_post_xgi_delay(ivideo, 1); 4981 4982 SiS_SetReg(SISSR, 0x18, 0x42); /* MRS1 */ 4983 SiS_SetReg(SISSR, 0x19, 0x00); 4984 SiS_SetReg(SISSR, 0x16, 0x05); 4985 SiS_SetReg(SISSR, 0x16, 0x85); 4986 sisfb_post_xgi_delay(ivideo, 1); 4987 } 4988 4989 static void sisfb_post_xgi_ddr2(struct sis_video_info *ivideo, u8 regb) 4990 { 4991 unsigned char *bios = ivideo->bios_abase; 4992 static const u8 cs158[8] = { 4993 0x88, 0xaa, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00 4994 }; 4995 static const u8 cs160[8] = { 4996 0x44, 0x77, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00 4997 }; 4998 static const u8 cs168[8] = { 4999 0x48, 0x78, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00 5000 }; 5001 u8 v1; 5002 u8 v2; 5003 u8 v3; 5004 5005 SiS_SetReg(SISCR, 0xb0, 0x80); /* DDR2 dual frequency mode */ 5006 SiS_SetReg(SISCR, 0x82, 0x77); 5007 SiS_SetReg(SISCR, 0x86, 0x00); 5008 SiS_GetReg(SISCR, 0x86); 5009 SiS_SetReg(SISCR, 0x86, 0x88); 5010 SiS_GetReg(SISCR, 0x86); 5011 v1 = cs168[regb]; v2 = cs160[regb]; v3 = cs158[regb]; 5012 if (ivideo->haveXGIROM) { 5013 v1 = bios[regb + 0x168]; 5014 v2 = bios[regb + 0x160]; 5015 v3 = bios[regb + 0x158]; 5016 } 5017 SiS_SetReg(SISCR, 0x86, v1); 5018 SiS_SetReg(SISCR, 0x82, 0x77); 5019 SiS_SetReg(SISCR, 0x85, 0x00); 5020 SiS_GetReg(SISCR, 0x85); 5021 SiS_SetReg(SISCR, 0x85, 0x88); 5022 SiS_GetReg(SISCR, 0x85); 5023 SiS_SetReg(SISCR, 0x85, v2); 5024 SiS_SetReg(SISCR, 0x82, v3); 5025 SiS_SetReg(SISCR, 0x98, 0x01); 5026 SiS_SetReg(SISCR, 0x9a, 0x02); 5027 if (sisfb_xgi_is21(ivideo)) 5028 sisfb_post_xgi_ddr2_mrs_xg21(ivideo); 5029 else 5030 sisfb_post_xgi_ddr2_mrs_default(ivideo, regb); 5031 } 5032 5033 static u8 sisfb_post_xgi_ramtype(struct sis_video_info *ivideo) 5034 { 5035 unsigned char *bios = ivideo->bios_abase; 5036 u8 ramtype; 5037 u8 reg; 5038 u8 v1; 5039 5040 ramtype = 0x00; v1 = 0x10; 5041 if (ivideo->haveXGIROM) { 5042 ramtype = bios[0x62]; 5043 v1 = bios[0x1d2]; 5044 } 5045 if (!(ramtype & 0x80)) { 5046 if (sisfb_xgi_is21(ivideo)) { 5047 SiS_SetRegAND(SISCR, 0xb4, 0xfd); /* GPIO control */ 5048 SiS_SetRegOR(SISCR, 0x4a, 0x80); /* GPIOH EN */ 5049 reg = SiS_GetReg(SISCR, 0x48); 5050 SiS_SetRegOR(SISCR, 0xb4, 0x02); 5051 ramtype = reg & 0x01; /* GPIOH */ 5052 } else if (ivideo->chip == XGI_20) { 5053 SiS_SetReg(SISCR, 0x97, v1); 5054 reg = SiS_GetReg(SISCR, 0x97); 5055 if (reg & 0x10) { 5056 ramtype = (reg & 0x01) << 1; 5057 } 5058 } else { 5059 reg = SiS_GetReg(SISSR, 0x39); 5060 ramtype = reg & 0x02; 5061 if (!(ramtype)) { 5062 reg = SiS_GetReg(SISSR, 0x3a); 5063 ramtype = (reg >> 1) & 0x01; 5064 } 5065 } 5066 } 5067 ramtype &= 0x07; 5068 5069 return ramtype; 5070 } 5071 5072 static int sisfb_post_xgi(struct pci_dev *pdev) 5073 { 5074 struct sis_video_info *ivideo = pci_get_drvdata(pdev); 5075 unsigned char *bios = ivideo->bios_abase; 5076 struct pci_dev *mypdev = NULL; 5077 const u8 *ptr, *ptr2; 5078 u8 v1, v2, v3, v4, v5, reg, ramtype; 5079 u32 rega, regb, regd; 5080 int i, j, k, index; 5081 static const u8 cs78[3] = { 0xf6, 0x0d, 0x00 }; 5082 static const u8 cs76[2] = { 0xa3, 0xfb }; 5083 static const u8 cs7b[3] = { 0xc0, 0x11, 0x00 }; 5084 static const u8 cs158[8] = { 5085 0x88, 0xaa, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00 5086 }; 5087 static const u8 cs160[8] = { 5088 0x44, 0x77, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00 5089 }; 5090 static const u8 cs168[8] = { 5091 0x48, 0x78, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00 5092 }; 5093 static const u8 cs128[3 * 8] = { 5094 0x90, 0x28, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 5095 0x77, 0x44, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 5096 0x77, 0x44, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00 5097 }; 5098 static const u8 cs148[2 * 8] = { 5099 0x55, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 5100 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 5101 }; 5102 static const u8 cs31a[8 * 4] = { 5103 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 5104 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 5105 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 5106 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 5107 }; 5108 static const u8 cs33a[8 * 4] = { 5109 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 5110 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 5111 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 5112 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 5113 }; 5114 static const u8 cs45a[8 * 2] = { 5115 0x00, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0x00, 0x00, 5116 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 5117 }; 5118 static const u8 cs170[7 * 8] = { 5119 0x54, 0x32, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 5120 0x54, 0x43, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 5121 0x0a, 0x05, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 5122 0x44, 0x34, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 5123 0x10, 0x0a, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 5124 0x11, 0x0c, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 5125 0x05, 0x05, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00 5126 }; 5127 static const u8 cs1a8[3 * 8] = { 5128 0xf0, 0xf0, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 5129 0x05, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 5130 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 5131 }; 5132 static const u8 cs100[2 * 8] = { 5133 0xc4, 0x04, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 5134 0xc4, 0x04, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00 5135 }; 5136 5137 /* VGA enable */ 5138 reg = SiS_GetRegByte(SISVGAENABLE) | 0x01; 5139 SiS_SetRegByte(SISVGAENABLE, reg); 5140 5141 /* Misc */ 5142 reg = SiS_GetRegByte(SISMISCR) | 0x01; 5143 SiS_SetRegByte(SISMISCW, reg); 5144 5145 /* Unlock SR */ 5146 SiS_SetReg(SISSR, 0x05, 0x86); 5147 reg = SiS_GetReg(SISSR, 0x05); 5148 if(reg != 0xa1) 5149 return 0; 5150 5151 /* Clear some regs */ 5152 for(i = 0; i < 0x22; i++) { 5153 if(0x06 + i == 0x20) continue; 5154 SiS_SetReg(SISSR, 0x06 + i, 0x00); 5155 } 5156 for(i = 0; i < 0x0b; i++) { 5157 SiS_SetReg(SISSR, 0x31 + i, 0x00); 5158 } 5159 for(i = 0; i < 0x10; i++) { 5160 SiS_SetReg(SISCR, 0x30 + i, 0x00); 5161 } 5162 5163 ptr = cs78; 5164 if(ivideo->haveXGIROM) { 5165 ptr = (const u8 *)&bios[0x78]; 5166 } 5167 for(i = 0; i < 3; i++) { 5168 SiS_SetReg(SISSR, 0x23 + i, ptr[i]); 5169 } 5170 5171 ptr = cs76; 5172 if(ivideo->haveXGIROM) { 5173 ptr = (const u8 *)&bios[0x76]; 5174 } 5175 for(i = 0; i < 2; i++) { 5176 SiS_SetReg(SISSR, 0x21 + i, ptr[i]); 5177 } 5178 5179 v1 = 0x18; v2 = 0x00; 5180 if(ivideo->haveXGIROM) { 5181 v1 = bios[0x74]; 5182 v2 = bios[0x75]; 5183 } 5184 SiS_SetReg(SISSR, 0x07, v1); 5185 SiS_SetReg(SISSR, 0x11, 0x0f); 5186 SiS_SetReg(SISSR, 0x1f, v2); 5187 /* PCI linear mode, RelIO enabled, A0000 decoding disabled */ 5188 SiS_SetReg(SISSR, 0x20, 0x80 | 0x20 | 0x04); 5189 SiS_SetReg(SISSR, 0x27, 0x74); 5190 5191 ptr = cs7b; 5192 if(ivideo->haveXGIROM) { 5193 ptr = (const u8 *)&bios[0x7b]; 5194 } 5195 for(i = 0; i < 3; i++) { 5196 SiS_SetReg(SISSR, 0x31 + i, ptr[i]); 5197 } 5198 5199 if(ivideo->chip == XGI_40) { 5200 if(ivideo->revision_id == 2) { 5201 SiS_SetRegANDOR(SISSR, 0x3b, 0x3f, 0xc0); 5202 } 5203 SiS_SetReg(SISCR, 0x7d, 0xfe); 5204 SiS_SetReg(SISCR, 0x7e, 0x0f); 5205 } 5206 if(ivideo->revision_id == 0) { /* 40 *and* 20? */ 5207 SiS_SetRegAND(SISCR, 0x58, 0xd7); 5208 reg = SiS_GetReg(SISCR, 0xcb); 5209 if(reg & 0x20) { 5210 SiS_SetRegANDOR(SISCR, 0x58, 0xd7, (reg & 0x10) ? 0x08 : 0x20); /* =0x28 Z7 ? */ 5211 } 5212 } 5213 5214 reg = (ivideo->chip == XGI_40) ? 0x20 : 0x00; 5215 SiS_SetRegANDOR(SISCR, 0x38, 0x1f, reg); 5216 5217 if(ivideo->chip == XGI_20) { 5218 SiS_SetReg(SISSR, 0x36, 0x70); 5219 } else { 5220 SiS_SetReg(SISVID, 0x00, 0x86); 5221 SiS_SetReg(SISVID, 0x32, 0x00); 5222 SiS_SetReg(SISVID, 0x30, 0x00); 5223 SiS_SetReg(SISVID, 0x32, 0x01); 5224 SiS_SetReg(SISVID, 0x30, 0x00); 5225 SiS_SetRegAND(SISVID, 0x2f, 0xdf); 5226 SiS_SetRegAND(SISCAP, 0x00, 0x3f); 5227 5228 SiS_SetReg(SISPART1, 0x2f, 0x01); 5229 SiS_SetReg(SISPART1, 0x00, 0x00); 5230 SiS_SetReg(SISPART1, 0x02, bios[0x7e]); 5231 SiS_SetReg(SISPART1, 0x2e, 0x08); 5232 SiS_SetRegAND(SISPART1, 0x35, 0x7f); 5233 SiS_SetRegAND(SISPART1, 0x50, 0xfe); 5234 5235 reg = SiS_GetReg(SISPART4, 0x00); 5236 if(reg == 1 || reg == 2) { 5237 SiS_SetReg(SISPART2, 0x00, 0x1c); 5238 SiS_SetReg(SISPART4, 0x0d, bios[0x7f]); 5239 SiS_SetReg(SISPART4, 0x0e, bios[0x80]); 5240 SiS_SetReg(SISPART4, 0x10, bios[0x81]); 5241 SiS_SetRegAND(SISPART4, 0x0f, 0x3f); 5242 5243 reg = SiS_GetReg(SISPART4, 0x01); 5244 if((reg & 0xf0) >= 0xb0) { 5245 reg = SiS_GetReg(SISPART4, 0x23); 5246 if(reg & 0x20) reg |= 0x40; 5247 SiS_SetReg(SISPART4, 0x23, reg); 5248 reg = (reg & 0x20) ? 0x02 : 0x00; 5249 SiS_SetRegANDOR(SISPART1, 0x1e, 0xfd, reg); 5250 } 5251 } 5252 5253 v1 = bios[0x77]; 5254 5255 reg = SiS_GetReg(SISSR, 0x3b); 5256 if(reg & 0x02) { 5257 reg = SiS_GetReg(SISSR, 0x3a); 5258 v2 = (reg & 0x30) >> 3; 5259 if(!(v2 & 0x04)) v2 ^= 0x02; 5260 reg = SiS_GetReg(SISSR, 0x39); 5261 if(reg & 0x80) v2 |= 0x80; 5262 v2 |= 0x01; 5263 5264 if((mypdev = pci_get_device(PCI_VENDOR_ID_SI, 0x0730, NULL))) { 5265 pci_dev_put(mypdev); 5266 if(((v2 & 0x06) == 2) || ((v2 & 0x06) == 4)) 5267 v2 &= 0xf9; 5268 v2 |= 0x08; 5269 v1 &= 0xfe; 5270 } else { 5271 mypdev = pci_get_device(PCI_VENDOR_ID_SI, 0x0735, NULL); 5272 if(!mypdev) 5273 mypdev = pci_get_device(PCI_VENDOR_ID_SI, 0x0645, NULL); 5274 if(!mypdev) 5275 mypdev = pci_get_device(PCI_VENDOR_ID_SI, 0x0650, NULL); 5276 if(mypdev) { 5277 pci_read_config_dword(mypdev, 0x94, ®d); 5278 regd &= 0xfffffeff; 5279 pci_write_config_dword(mypdev, 0x94, regd); 5280 v1 &= 0xfe; 5281 pci_dev_put(mypdev); 5282 } else if(sisfb_find_host_bridge(ivideo, pdev, PCI_VENDOR_ID_SI)) { 5283 v1 &= 0xfe; 5284 } else if(sisfb_find_host_bridge(ivideo, pdev, 0x1106) || 5285 sisfb_find_host_bridge(ivideo, pdev, 0x1022) || 5286 sisfb_find_host_bridge(ivideo, pdev, 0x700e) || 5287 sisfb_find_host_bridge(ivideo, pdev, 0x10de)) { 5288 if((v2 & 0x06) == 4) 5289 v2 ^= 0x06; 5290 v2 |= 0x08; 5291 } 5292 } 5293 SiS_SetRegANDOR(SISCR, 0x5f, 0xf0, v2); 5294 } 5295 SiS_SetReg(SISSR, 0x22, v1); 5296 5297 if(ivideo->revision_id == 2) { 5298 v1 = SiS_GetReg(SISSR, 0x3b); 5299 v2 = SiS_GetReg(SISSR, 0x3a); 5300 regd = bios[0x90 + 3] | (bios[0x90 + 4] << 8); 5301 if( (!(v1 & 0x02)) && (v2 & 0x30) && (regd < 0xcf) ) 5302 SiS_SetRegANDOR(SISCR, 0x5f, 0xf1, 0x01); 5303 5304 if((mypdev = pci_get_device(0x10de, 0x01e0, NULL))) { 5305 /* TODO: set CR5f &0xf1 | 0x01 for version 6570 5306 * of nforce 2 ROM 5307 */ 5308 if(0) 5309 SiS_SetRegANDOR(SISCR, 0x5f, 0xf1, 0x01); 5310 pci_dev_put(mypdev); 5311 } 5312 } 5313 5314 v1 = 0x30; 5315 reg = SiS_GetReg(SISSR, 0x3b); 5316 v2 = SiS_GetReg(SISCR, 0x5f); 5317 if((!(reg & 0x02)) && (v2 & 0x0e)) 5318 v1 |= 0x08; 5319 SiS_SetReg(SISSR, 0x27, v1); 5320 5321 if(bios[0x64] & 0x01) { 5322 SiS_SetRegANDOR(SISCR, 0x5f, 0xf0, bios[0x64]); 5323 } 5324 5325 v1 = bios[0x4f7]; 5326 pci_read_config_dword(pdev, 0x50, ®d); 5327 regd = (regd >> 20) & 0x0f; 5328 if(regd == 1) { 5329 v1 &= 0xfc; 5330 SiS_SetRegOR(SISCR, 0x5f, 0x08); 5331 } 5332 SiS_SetReg(SISCR, 0x48, v1); 5333 5334 SiS_SetRegANDOR(SISCR, 0x47, 0x04, bios[0x4f6] & 0xfb); 5335 SiS_SetRegANDOR(SISCR, 0x49, 0xf0, bios[0x4f8] & 0x0f); 5336 SiS_SetRegANDOR(SISCR, 0x4a, 0x60, bios[0x4f9] & 0x9f); 5337 SiS_SetRegANDOR(SISCR, 0x4b, 0x08, bios[0x4fa] & 0xf7); 5338 SiS_SetRegANDOR(SISCR, 0x4c, 0x80, bios[0x4fb] & 0x7f); 5339 SiS_SetReg(SISCR, 0x70, bios[0x4fc]); 5340 SiS_SetRegANDOR(SISCR, 0x71, 0xf0, bios[0x4fd] & 0x0f); 5341 SiS_SetReg(SISCR, 0x74, 0xd0); 5342 SiS_SetRegANDOR(SISCR, 0x74, 0xcf, bios[0x4fe] & 0x30); 5343 SiS_SetRegANDOR(SISCR, 0x75, 0xe0, bios[0x4ff] & 0x1f); 5344 SiS_SetRegANDOR(SISCR, 0x76, 0xe0, bios[0x500] & 0x1f); 5345 v1 = bios[0x501]; 5346 if((mypdev = pci_get_device(0x8086, 0x2530, NULL))) { 5347 v1 = 0xf0; 5348 pci_dev_put(mypdev); 5349 } 5350 SiS_SetReg(SISCR, 0x77, v1); 5351 } 5352 5353 /* RAM type: 5354 * 5355 * 0 == DDR1, 1 == DDR2, 2..7 == reserved? 5356 * 5357 * The code seems to written so that regb should equal ramtype, 5358 * however, so far it has been hardcoded to 0. Enable other values only 5359 * on XGI Z9, as it passes the POST, and add a warning for others. 5360 */ 5361 ramtype = sisfb_post_xgi_ramtype(ivideo); 5362 if (!sisfb_xgi_is21(ivideo) && ramtype) { 5363 dev_warn(&pdev->dev, 5364 "RAM type something else than expected: %d\n", 5365 ramtype); 5366 regb = 0; 5367 } else { 5368 regb = ramtype; 5369 } 5370 5371 v1 = 0xff; 5372 if(ivideo->haveXGIROM) { 5373 v1 = bios[0x140 + regb]; 5374 } 5375 SiS_SetReg(SISCR, 0x6d, v1); 5376 5377 ptr = cs128; 5378 if(ivideo->haveXGIROM) { 5379 ptr = (const u8 *)&bios[0x128]; 5380 } 5381 for(i = 0, j = 0; i < 3; i++, j += 8) { 5382 SiS_SetReg(SISCR, 0x68 + i, ptr[j + regb]); 5383 } 5384 5385 ptr = cs31a; 5386 ptr2 = cs33a; 5387 if(ivideo->haveXGIROM) { 5388 index = (ivideo->chip == XGI_20) ? 0x31a : 0x3a6; 5389 ptr = (const u8 *)&bios[index]; 5390 ptr2 = (const u8 *)&bios[index + 0x20]; 5391 } 5392 for(i = 0; i < 2; i++) { 5393 if(i == 0) { 5394 regd = le32_to_cpu(((u32 *)ptr)[regb]); 5395 rega = 0x6b; 5396 } else { 5397 regd = le32_to_cpu(((u32 *)ptr2)[regb]); 5398 rega = 0x6e; 5399 } 5400 reg = 0x00; 5401 for(j = 0; j < 16; j++) { 5402 reg &= 0xf3; 5403 if(regd & 0x01) reg |= 0x04; 5404 if(regd & 0x02) reg |= 0x08; 5405 regd >>= 2; 5406 SiS_SetReg(SISCR, rega, reg); 5407 reg = SiS_GetReg(SISCR, rega); 5408 reg = SiS_GetReg(SISCR, rega); 5409 reg += 0x10; 5410 } 5411 } 5412 5413 SiS_SetRegAND(SISCR, 0x6e, 0xfc); 5414 5415 ptr = NULL; 5416 if(ivideo->haveXGIROM) { 5417 index = (ivideo->chip == XGI_20) ? 0x35a : 0x3e6; 5418 ptr = (const u8 *)&bios[index]; 5419 } 5420 for(i = 0; i < 4; i++) { 5421 SiS_SetRegANDOR(SISCR, 0x6e, 0xfc, i); 5422 reg = 0x00; 5423 for(j = 0; j < 2; j++) { 5424 regd = 0; 5425 if(ptr) { 5426 regd = le32_to_cpu(((u32 *)ptr)[regb * 8]); 5427 ptr += 4; 5428 } 5429 /* reg = 0x00; */ 5430 for(k = 0; k < 16; k++) { 5431 reg &= 0xfc; 5432 if(regd & 0x01) reg |= 0x01; 5433 if(regd & 0x02) reg |= 0x02; 5434 regd >>= 2; 5435 SiS_SetReg(SISCR, 0x6f, reg); 5436 reg = SiS_GetReg(SISCR, 0x6f); 5437 reg = SiS_GetReg(SISCR, 0x6f); 5438 reg += 0x08; 5439 } 5440 } 5441 } 5442 5443 ptr = cs148; 5444 if(ivideo->haveXGIROM) { 5445 ptr = (const u8 *)&bios[0x148]; 5446 } 5447 for(i = 0, j = 0; i < 2; i++, j += 8) { 5448 SiS_SetReg(SISCR, 0x80 + i, ptr[j + regb]); 5449 } 5450 5451 SiS_SetRegAND(SISCR, 0x89, 0x8f); 5452 5453 ptr = cs45a; 5454 if(ivideo->haveXGIROM) { 5455 index = (ivideo->chip == XGI_20) ? 0x45a : 0x4e6; 5456 ptr = (const u8 *)&bios[index]; 5457 } 5458 regd = le16_to_cpu(((const u16 *)ptr)[regb]); 5459 reg = 0x80; 5460 for(i = 0; i < 5; i++) { 5461 reg &= 0xfc; 5462 if(regd & 0x01) reg |= 0x01; 5463 if(regd & 0x02) reg |= 0x02; 5464 regd >>= 2; 5465 SiS_SetReg(SISCR, 0x89, reg); 5466 reg = SiS_GetReg(SISCR, 0x89); 5467 reg = SiS_GetReg(SISCR, 0x89); 5468 reg += 0x10; 5469 } 5470 5471 v1 = 0xb5; v2 = 0x20; v3 = 0xf0; v4 = 0x13; 5472 if(ivideo->haveXGIROM) { 5473 v1 = bios[0x118 + regb]; 5474 v2 = bios[0xf8 + regb]; 5475 v3 = bios[0x120 + regb]; 5476 v4 = bios[0x1ca]; 5477 } 5478 SiS_SetReg(SISCR, 0x45, v1 & 0x0f); 5479 SiS_SetReg(SISCR, 0x99, (v1 >> 4) & 0x07); 5480 SiS_SetRegOR(SISCR, 0x40, v1 & 0x80); 5481 SiS_SetReg(SISCR, 0x41, v2); 5482 5483 ptr = cs170; 5484 if(ivideo->haveXGIROM) { 5485 ptr = (const u8 *)&bios[0x170]; 5486 } 5487 for(i = 0, j = 0; i < 7; i++, j += 8) { 5488 SiS_SetReg(SISCR, 0x90 + i, ptr[j + regb]); 5489 } 5490 5491 SiS_SetReg(SISCR, 0x59, v3); 5492 5493 ptr = cs1a8; 5494 if(ivideo->haveXGIROM) { 5495 ptr = (const u8 *)&bios[0x1a8]; 5496 } 5497 for(i = 0, j = 0; i < 3; i++, j += 8) { 5498 SiS_SetReg(SISCR, 0xc3 + i, ptr[j + regb]); 5499 } 5500 5501 ptr = cs100; 5502 if(ivideo->haveXGIROM) { 5503 ptr = (const u8 *)&bios[0x100]; 5504 } 5505 for(i = 0, j = 0; i < 2; i++, j += 8) { 5506 SiS_SetReg(SISCR, 0x8a + i, ptr[j + regb]); 5507 } 5508 5509 SiS_SetReg(SISCR, 0xcf, v4); 5510 5511 SiS_SetReg(SISCR, 0x83, 0x09); 5512 SiS_SetReg(SISCR, 0x87, 0x00); 5513 5514 if(ivideo->chip == XGI_40) { 5515 if( (ivideo->revision_id == 1) || 5516 (ivideo->revision_id == 2) ) { 5517 SiS_SetReg(SISCR, 0x8c, 0x87); 5518 } 5519 } 5520 5521 if (regb == 1) 5522 SiS_SetReg(SISSR, 0x17, 0x80); /* DDR2 */ 5523 else 5524 SiS_SetReg(SISSR, 0x17, 0x00); /* DDR1 */ 5525 SiS_SetReg(SISSR, 0x1a, 0x87); 5526 5527 if(ivideo->chip == XGI_20) { 5528 SiS_SetReg(SISSR, 0x15, 0x00); 5529 SiS_SetReg(SISSR, 0x1c, 0x00); 5530 } 5531 5532 switch(ramtype) { 5533 case 0: 5534 sisfb_post_xgi_setclocks(ivideo, regb); 5535 if((ivideo->chip == XGI_20) || 5536 (ivideo->revision_id == 1) || 5537 (ivideo->revision_id == 2)) { 5538 v1 = cs158[regb]; v2 = cs160[regb]; v3 = cs168[regb]; 5539 if(ivideo->haveXGIROM) { 5540 v1 = bios[regb + 0x158]; 5541 v2 = bios[regb + 0x160]; 5542 v3 = bios[regb + 0x168]; 5543 } 5544 SiS_SetReg(SISCR, 0x82, v1); 5545 SiS_SetReg(SISCR, 0x85, v2); 5546 SiS_SetReg(SISCR, 0x86, v3); 5547 } else { 5548 SiS_SetReg(SISCR, 0x82, 0x88); 5549 SiS_SetReg(SISCR, 0x86, 0x00); 5550 reg = SiS_GetReg(SISCR, 0x86); 5551 SiS_SetReg(SISCR, 0x86, 0x88); 5552 reg = SiS_GetReg(SISCR, 0x86); 5553 SiS_SetReg(SISCR, 0x86, bios[regb + 0x168]); 5554 SiS_SetReg(SISCR, 0x82, 0x77); 5555 SiS_SetReg(SISCR, 0x85, 0x00); 5556 reg = SiS_GetReg(SISCR, 0x85); 5557 SiS_SetReg(SISCR, 0x85, 0x88); 5558 reg = SiS_GetReg(SISCR, 0x85); 5559 SiS_SetReg(SISCR, 0x85, bios[regb + 0x160]); 5560 SiS_SetReg(SISCR, 0x82, bios[regb + 0x158]); 5561 } 5562 if(ivideo->chip == XGI_40) { 5563 SiS_SetReg(SISCR, 0x97, 0x00); 5564 } 5565 SiS_SetReg(SISCR, 0x98, 0x01); 5566 SiS_SetReg(SISCR, 0x9a, 0x02); 5567 5568 SiS_SetReg(SISSR, 0x18, 0x01); 5569 if((ivideo->chip == XGI_20) || 5570 (ivideo->revision_id == 2)) { 5571 SiS_SetReg(SISSR, 0x19, 0x40); 5572 } else { 5573 SiS_SetReg(SISSR, 0x19, 0x20); 5574 } 5575 SiS_SetReg(SISSR, 0x16, 0x00); 5576 SiS_SetReg(SISSR, 0x16, 0x80); 5577 if((ivideo->chip == XGI_20) || (bios[0x1cb] != 0x0c)) { 5578 sisfb_post_xgi_delay(ivideo, 0x43); 5579 sisfb_post_xgi_delay(ivideo, 0x43); 5580 sisfb_post_xgi_delay(ivideo, 0x43); 5581 SiS_SetReg(SISSR, 0x18, 0x00); 5582 if((ivideo->chip == XGI_20) || 5583 (ivideo->revision_id == 2)) { 5584 SiS_SetReg(SISSR, 0x19, 0x40); 5585 } else { 5586 SiS_SetReg(SISSR, 0x19, 0x20); 5587 } 5588 } else if((ivideo->chip == XGI_40) && (bios[0x1cb] == 0x0c)) { 5589 /* SiS_SetReg(SISSR, 0x16, 0x0c); */ /* ? */ 5590 } 5591 SiS_SetReg(SISSR, 0x16, 0x00); 5592 SiS_SetReg(SISSR, 0x16, 0x80); 5593 sisfb_post_xgi_delay(ivideo, 4); 5594 v1 = 0x31; v2 = 0x03; v3 = 0x83; v4 = 0x03; v5 = 0x83; 5595 if(ivideo->haveXGIROM) { 5596 v1 = bios[0xf0]; 5597 index = (ivideo->chip == XGI_20) ? 0x4b2 : 0x53e; 5598 v2 = bios[index]; 5599 v3 = bios[index + 1]; 5600 v4 = bios[index + 2]; 5601 v5 = bios[index + 3]; 5602 } 5603 SiS_SetReg(SISSR, 0x18, v1); 5604 SiS_SetReg(SISSR, 0x19, ((ivideo->chip == XGI_20) ? 0x02 : 0x01)); 5605 SiS_SetReg(SISSR, 0x16, v2); 5606 SiS_SetReg(SISSR, 0x16, v3); 5607 sisfb_post_xgi_delay(ivideo, 0x43); 5608 SiS_SetReg(SISSR, 0x1b, 0x03); 5609 sisfb_post_xgi_delay(ivideo, 0x22); 5610 SiS_SetReg(SISSR, 0x18, v1); 5611 SiS_SetReg(SISSR, 0x19, 0x00); 5612 SiS_SetReg(SISSR, 0x16, v4); 5613 SiS_SetReg(SISSR, 0x16, v5); 5614 SiS_SetReg(SISSR, 0x1b, 0x00); 5615 break; 5616 case 1: 5617 sisfb_post_xgi_ddr2(ivideo, regb); 5618 break; 5619 default: 5620 sisfb_post_xgi_setclocks(ivideo, regb); 5621 if((ivideo->chip == XGI_40) && 5622 ((ivideo->revision_id == 1) || 5623 (ivideo->revision_id == 2))) { 5624 SiS_SetReg(SISCR, 0x82, bios[regb + 0x158]); 5625 SiS_SetReg(SISCR, 0x85, bios[regb + 0x160]); 5626 SiS_SetReg(SISCR, 0x86, bios[regb + 0x168]); 5627 } else { 5628 SiS_SetReg(SISCR, 0x82, 0x88); 5629 SiS_SetReg(SISCR, 0x86, 0x00); 5630 reg = SiS_GetReg(SISCR, 0x86); 5631 SiS_SetReg(SISCR, 0x86, 0x88); 5632 SiS_SetReg(SISCR, 0x82, 0x77); 5633 SiS_SetReg(SISCR, 0x85, 0x00); 5634 reg = SiS_GetReg(SISCR, 0x85); 5635 SiS_SetReg(SISCR, 0x85, 0x88); 5636 reg = SiS_GetReg(SISCR, 0x85); 5637 v1 = cs160[regb]; v2 = cs158[regb]; 5638 if(ivideo->haveXGIROM) { 5639 v1 = bios[regb + 0x160]; 5640 v2 = bios[regb + 0x158]; 5641 } 5642 SiS_SetReg(SISCR, 0x85, v1); 5643 SiS_SetReg(SISCR, 0x82, v2); 5644 } 5645 if(ivideo->chip == XGI_40) { 5646 SiS_SetReg(SISCR, 0x97, 0x11); 5647 } 5648 if((ivideo->chip == XGI_40) && (ivideo->revision_id == 2)) { 5649 SiS_SetReg(SISCR, 0x98, 0x01); 5650 } else { 5651 SiS_SetReg(SISCR, 0x98, 0x03); 5652 } 5653 SiS_SetReg(SISCR, 0x9a, 0x02); 5654 5655 if(ivideo->chip == XGI_40) { 5656 SiS_SetReg(SISSR, 0x18, 0x01); 5657 } else { 5658 SiS_SetReg(SISSR, 0x18, 0x00); 5659 } 5660 SiS_SetReg(SISSR, 0x19, 0x40); 5661 SiS_SetReg(SISSR, 0x16, 0x00); 5662 SiS_SetReg(SISSR, 0x16, 0x80); 5663 if((ivideo->chip == XGI_40) && (bios[0x1cb] != 0x0c)) { 5664 sisfb_post_xgi_delay(ivideo, 0x43); 5665 sisfb_post_xgi_delay(ivideo, 0x43); 5666 sisfb_post_xgi_delay(ivideo, 0x43); 5667 SiS_SetReg(SISSR, 0x18, 0x00); 5668 SiS_SetReg(SISSR, 0x19, 0x40); 5669 SiS_SetReg(SISSR, 0x16, 0x00); 5670 SiS_SetReg(SISSR, 0x16, 0x80); 5671 } 5672 sisfb_post_xgi_delay(ivideo, 4); 5673 v1 = 0x31; 5674 if(ivideo->haveXGIROM) { 5675 v1 = bios[0xf0]; 5676 } 5677 SiS_SetReg(SISSR, 0x18, v1); 5678 SiS_SetReg(SISSR, 0x19, 0x01); 5679 if(ivideo->chip == XGI_40) { 5680 SiS_SetReg(SISSR, 0x16, bios[0x53e]); 5681 SiS_SetReg(SISSR, 0x16, bios[0x53f]); 5682 } else { 5683 SiS_SetReg(SISSR, 0x16, 0x05); 5684 SiS_SetReg(SISSR, 0x16, 0x85); 5685 } 5686 sisfb_post_xgi_delay(ivideo, 0x43); 5687 if(ivideo->chip == XGI_40) { 5688 SiS_SetReg(SISSR, 0x1b, 0x01); 5689 } else { 5690 SiS_SetReg(SISSR, 0x1b, 0x03); 5691 } 5692 sisfb_post_xgi_delay(ivideo, 0x22); 5693 SiS_SetReg(SISSR, 0x18, v1); 5694 SiS_SetReg(SISSR, 0x19, 0x00); 5695 if(ivideo->chip == XGI_40) { 5696 SiS_SetReg(SISSR, 0x16, bios[0x540]); 5697 SiS_SetReg(SISSR, 0x16, bios[0x541]); 5698 } else { 5699 SiS_SetReg(SISSR, 0x16, 0x05); 5700 SiS_SetReg(SISSR, 0x16, 0x85); 5701 } 5702 SiS_SetReg(SISSR, 0x1b, 0x00); 5703 } 5704 5705 regb = 0; /* ! */ 5706 v1 = 0x03; 5707 if(ivideo->haveXGIROM) { 5708 v1 = bios[0x110 + regb]; 5709 } 5710 SiS_SetReg(SISSR, 0x1b, v1); 5711 5712 /* RAM size */ 5713 v1 = 0x00; v2 = 0x00; 5714 if(ivideo->haveXGIROM) { 5715 v1 = bios[0x62]; 5716 v2 = bios[0x63]; 5717 } 5718 regb = 0; /* ! */ 5719 regd = 1 << regb; 5720 if((v1 & 0x40) && (v2 & regd) && ivideo->haveXGIROM) { 5721 5722 SiS_SetReg(SISSR, 0x13, bios[regb + 0xe0]); 5723 SiS_SetReg(SISSR, 0x14, bios[regb + 0xe0 + 8]); 5724 5725 } else { 5726 int err; 5727 5728 /* Set default mode, don't clear screen */ 5729 ivideo->SiS_Pr.SiS_UseOEM = false; 5730 SiS_SetEnableDstn(&ivideo->SiS_Pr, false); 5731 SiS_SetEnableFstn(&ivideo->SiS_Pr, false); 5732 ivideo->curFSTN = ivideo->curDSTN = 0; 5733 ivideo->SiS_Pr.VideoMemorySize = 8 << 20; 5734 SiSSetMode(&ivideo->SiS_Pr, 0x2e | 0x80); 5735 5736 SiS_SetReg(SISSR, 0x05, 0x86); 5737 5738 /* Disable read-cache */ 5739 SiS_SetRegAND(SISSR, 0x21, 0xdf); 5740 err = sisfb_post_xgi_ramsize(ivideo); 5741 /* Enable read-cache */ 5742 SiS_SetRegOR(SISSR, 0x21, 0x20); 5743 5744 if (err) { 5745 dev_err(&pdev->dev, 5746 "%s: RAM size detection failed: %d\n", 5747 __func__, err); 5748 return 0; 5749 } 5750 } 5751 5752 #if 0 5753 printk(KERN_DEBUG "-----------------\n"); 5754 for(i = 0; i < 0xff; i++) { 5755 reg = SiS_GetReg(SISCR, i); 5756 printk(KERN_DEBUG "CR%02x(%x) = 0x%02x\n", i, SISCR, reg); 5757 } 5758 for(i = 0; i < 0x40; i++) { 5759 reg = SiS_GetReg(SISSR, i); 5760 printk(KERN_DEBUG "SR%02x(%x) = 0x%02x\n", i, SISSR, reg); 5761 } 5762 printk(KERN_DEBUG "-----------------\n"); 5763 #endif 5764 5765 /* Sense CRT1 */ 5766 if(ivideo->chip == XGI_20) { 5767 SiS_SetRegOR(SISCR, 0x32, 0x20); 5768 } else { 5769 reg = SiS_GetReg(SISPART4, 0x00); 5770 if((reg == 1) || (reg == 2)) { 5771 sisfb_sense_crt1(ivideo); 5772 } else { 5773 SiS_SetRegOR(SISCR, 0x32, 0x20); 5774 } 5775 } 5776 5777 /* Set default mode, don't clear screen */ 5778 ivideo->SiS_Pr.SiS_UseOEM = false; 5779 SiS_SetEnableDstn(&ivideo->SiS_Pr, false); 5780 SiS_SetEnableFstn(&ivideo->SiS_Pr, false); 5781 ivideo->curFSTN = ivideo->curDSTN = 0; 5782 SiSSetMode(&ivideo->SiS_Pr, 0x2e | 0x80); 5783 5784 SiS_SetReg(SISSR, 0x05, 0x86); 5785 5786 /* Display off */ 5787 SiS_SetRegOR(SISSR, 0x01, 0x20); 5788 5789 /* Save mode number in CR34 */ 5790 SiS_SetReg(SISCR, 0x34, 0x2e); 5791 5792 /* Let everyone know what the current mode is */ 5793 ivideo->modeprechange = 0x2e; 5794 5795 if(ivideo->chip == XGI_40) { 5796 reg = SiS_GetReg(SISCR, 0xca); 5797 v1 = SiS_GetReg(SISCR, 0xcc); 5798 if((reg & 0x10) && (!(v1 & 0x04))) { 5799 printk(KERN_ERR 5800 "sisfb: Please connect power to the card.\n"); 5801 return 0; 5802 } 5803 } 5804 5805 return 1; 5806 } 5807 #endif 5808 5809 static int sisfb_probe(struct pci_dev *pdev, const struct pci_device_id *ent) 5810 { 5811 struct sisfb_chip_info *chipinfo = &sisfb_chip_info[ent->driver_data]; 5812 struct sis_video_info *ivideo = NULL; 5813 struct fb_info *sis_fb_info = NULL; 5814 u16 reg16; 5815 u8 reg; 5816 int i, ret; 5817 5818 if(sisfb_off) 5819 return -ENXIO; 5820 5821 ret = aperture_remove_conflicting_pci_devices(pdev, "sisfb"); 5822 if (ret) 5823 return ret; 5824 5825 sis_fb_info = framebuffer_alloc(sizeof(*ivideo), &pdev->dev); 5826 if(!sis_fb_info) 5827 return -ENOMEM; 5828 5829 ivideo = (struct sis_video_info *)sis_fb_info->par; 5830 ivideo->memyselfandi = sis_fb_info; 5831 5832 ivideo->sisfb_id = SISFB_ID; 5833 5834 if(card_list == NULL) { 5835 ivideo->cardnumber = 0; 5836 } else { 5837 struct sis_video_info *countvideo = card_list; 5838 ivideo->cardnumber = 1; 5839 while((countvideo = countvideo->next) != NULL) 5840 ivideo->cardnumber++; 5841 } 5842 5843 strscpy(ivideo->myid, chipinfo->chip_name, sizeof(ivideo->myid)); 5844 5845 ivideo->warncount = 0; 5846 ivideo->chip_id = pdev->device; 5847 ivideo->chip_vendor = pdev->vendor; 5848 ivideo->revision_id = pdev->revision; 5849 ivideo->SiS_Pr.ChipRevision = ivideo->revision_id; 5850 pci_read_config_word(pdev, PCI_COMMAND, ®16); 5851 ivideo->sisvga_enabled = reg16 & 0x01; 5852 ivideo->pcibus = pdev->bus->number; 5853 ivideo->pcislot = PCI_SLOT(pdev->devfn); 5854 ivideo->pcifunc = PCI_FUNC(pdev->devfn); 5855 ivideo->subsysvendor = pdev->subsystem_vendor; 5856 ivideo->subsysdevice = pdev->subsystem_device; 5857 5858 ivideo->chip = chipinfo->chip; 5859 ivideo->chip_real_id = chipinfo->chip; 5860 ivideo->sisvga_engine = chipinfo->vgaengine; 5861 ivideo->hwcursor_size = chipinfo->hwcursor_size; 5862 ivideo->CRT2_write_enable = chipinfo->CRT2_write_enable; 5863 ivideo->mni = chipinfo->mni; 5864 5865 ivideo->detectedpdc = 0xff; 5866 ivideo->detectedpdca = 0xff; 5867 ivideo->detectedlcda = 0xff; 5868 5869 ivideo->sisfb_thismonitor.datavalid = false; 5870 5871 ivideo->current_base = 0; 5872 5873 ivideo->engineok = 0; 5874 5875 ivideo->sisfb_was_boot_device = 0; 5876 5877 if(pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW) { 5878 if(ivideo->sisvga_enabled) 5879 ivideo->sisfb_was_boot_device = 1; 5880 else { 5881 printk(KERN_DEBUG "sisfb: PCI device is disabled, " 5882 "but marked as boot video device ???\n"); 5883 printk(KERN_DEBUG "sisfb: I will not accept this " 5884 "as the primary VGA device\n"); 5885 } 5886 } 5887 5888 ivideo->sisfb_parm_mem = sisfb_parm_mem; 5889 ivideo->sisfb_accel = sisfb_accel; 5890 ivideo->sisfb_ypan = sisfb_ypan; 5891 ivideo->sisfb_max = sisfb_max; 5892 ivideo->sisfb_userom = sisfb_userom; 5893 ivideo->sisfb_useoem = sisfb_useoem; 5894 ivideo->sisfb_mode_idx = sisfb_mode_idx; 5895 ivideo->sisfb_parm_rate = sisfb_parm_rate; 5896 ivideo->sisfb_crt1off = sisfb_crt1off; 5897 ivideo->sisfb_forcecrt1 = sisfb_forcecrt1; 5898 ivideo->sisfb_crt2type = sisfb_crt2type; 5899 ivideo->sisfb_crt2flags = sisfb_crt2flags; 5900 /* pdc(a), scalelcd, special timing, lvdshl handled below */ 5901 ivideo->sisfb_dstn = sisfb_dstn; 5902 ivideo->sisfb_fstn = sisfb_fstn; 5903 ivideo->sisfb_tvplug = sisfb_tvplug; 5904 ivideo->sisfb_tvstd = sisfb_tvstd; 5905 ivideo->tvxpos = sisfb_tvxposoffset; 5906 ivideo->tvypos = sisfb_tvyposoffset; 5907 ivideo->sisfb_nocrt2rate = sisfb_nocrt2rate; 5908 ivideo->refresh_rate = 0; 5909 if(ivideo->sisfb_parm_rate != -1) { 5910 ivideo->refresh_rate = ivideo->sisfb_parm_rate; 5911 } 5912 5913 ivideo->SiS_Pr.UsePanelScaler = sisfb_scalelcd; 5914 ivideo->SiS_Pr.CenterScreen = -1; 5915 ivideo->SiS_Pr.SiS_CustomT = sisfb_specialtiming; 5916 ivideo->SiS_Pr.LVDSHL = sisfb_lvdshl; 5917 5918 ivideo->SiS_Pr.SiS_Backup70xx = 0xff; 5919 ivideo->SiS_Pr.SiS_CHOverScan = -1; 5920 ivideo->SiS_Pr.SiS_ChSW = false; 5921 ivideo->SiS_Pr.SiS_UseLCDA = false; 5922 ivideo->SiS_Pr.HaveEMI = false; 5923 ivideo->SiS_Pr.HaveEMILCD = false; 5924 ivideo->SiS_Pr.OverruleEMI = false; 5925 ivideo->SiS_Pr.SiS_SensibleSR11 = false; 5926 ivideo->SiS_Pr.SiS_MyCR63 = 0x63; 5927 ivideo->SiS_Pr.PDC = -1; 5928 ivideo->SiS_Pr.PDCA = -1; 5929 ivideo->SiS_Pr.DDCPortMixup = false; 5930 #ifdef CONFIG_FB_SIS_315 5931 if(ivideo->chip >= SIS_330) { 5932 ivideo->SiS_Pr.SiS_MyCR63 = 0x53; 5933 if(ivideo->chip >= SIS_661) { 5934 ivideo->SiS_Pr.SiS_SensibleSR11 = true; 5935 } 5936 } 5937 #endif 5938 5939 memcpy(&ivideo->default_var, &my_default_var, sizeof(my_default_var)); 5940 5941 pci_set_drvdata(pdev, ivideo); 5942 5943 /* Patch special cases */ 5944 if((ivideo->nbridge = sisfb_get_northbridge(ivideo->chip))) { 5945 switch(ivideo->nbridge->device) { 5946 #ifdef CONFIG_FB_SIS_300 5947 case PCI_DEVICE_ID_SI_730: 5948 ivideo->chip = SIS_730; 5949 strcpy(ivideo->myid, "SiS 730"); 5950 break; 5951 #endif 5952 #ifdef CONFIG_FB_SIS_315 5953 case PCI_DEVICE_ID_SI_651: 5954 /* ivideo->chip is ok */ 5955 strcpy(ivideo->myid, "SiS 651"); 5956 break; 5957 case PCI_DEVICE_ID_SI_740: 5958 ivideo->chip = SIS_740; 5959 strcpy(ivideo->myid, "SiS 740"); 5960 break; 5961 case PCI_DEVICE_ID_SI_661: 5962 ivideo->chip = SIS_661; 5963 strcpy(ivideo->myid, "SiS 661"); 5964 break; 5965 case PCI_DEVICE_ID_SI_741: 5966 ivideo->chip = SIS_741; 5967 strcpy(ivideo->myid, "SiS 741"); 5968 break; 5969 case PCI_DEVICE_ID_SI_760: 5970 ivideo->chip = SIS_760; 5971 strcpy(ivideo->myid, "SiS 760"); 5972 break; 5973 case PCI_DEVICE_ID_SI_761: 5974 ivideo->chip = SIS_761; 5975 strcpy(ivideo->myid, "SiS 761"); 5976 break; 5977 #endif 5978 default: 5979 break; 5980 } 5981 } 5982 5983 ivideo->SiS_Pr.ChipType = ivideo->chip; 5984 5985 ivideo->SiS_Pr.ivideo = (void *)ivideo; 5986 5987 #ifdef CONFIG_FB_SIS_315 5988 if((ivideo->SiS_Pr.ChipType == SIS_315PRO) || 5989 (ivideo->SiS_Pr.ChipType == SIS_315)) { 5990 ivideo->SiS_Pr.ChipType = SIS_315H; 5991 } 5992 #endif 5993 5994 if(!ivideo->sisvga_enabled) { 5995 if(pci_enable_device(pdev)) { 5996 pci_dev_put(ivideo->nbridge); 5997 framebuffer_release(sis_fb_info); 5998 return -EIO; 5999 } 6000 } 6001 6002 ivideo->video_base = pci_resource_start(pdev, 0); 6003 ivideo->video_size = pci_resource_len(pdev, 0); 6004 ivideo->mmio_base = pci_resource_start(pdev, 1); 6005 ivideo->mmio_size = pci_resource_len(pdev, 1); 6006 ivideo->SiS_Pr.RelIO = pci_resource_start(pdev, 2) + 0x30; 6007 ivideo->SiS_Pr.IOAddress = ivideo->vga_base = ivideo->SiS_Pr.RelIO; 6008 6009 SiSRegInit(&ivideo->SiS_Pr, ivideo->SiS_Pr.IOAddress); 6010 6011 #ifdef CONFIG_FB_SIS_300 6012 /* Find PCI systems for Chrontel/GPIO communication setup */ 6013 if(ivideo->chip == SIS_630) { 6014 i = 0; 6015 do { 6016 if(mychswtable[i].subsysVendor == ivideo->subsysvendor && 6017 mychswtable[i].subsysCard == ivideo->subsysdevice) { 6018 ivideo->SiS_Pr.SiS_ChSW = true; 6019 printk(KERN_DEBUG "sisfb: Identified [%s %s] " 6020 "requiring Chrontel/GPIO setup\n", 6021 mychswtable[i].vendorName, 6022 mychswtable[i].cardName); 6023 ivideo->lpcdev = pci_get_device(PCI_VENDOR_ID_SI, 0x0008, NULL); 6024 break; 6025 } 6026 i++; 6027 } while(mychswtable[i].subsysVendor != 0); 6028 } 6029 #endif 6030 6031 #ifdef CONFIG_FB_SIS_315 6032 if((ivideo->chip == SIS_760) && (ivideo->nbridge)) { 6033 ivideo->lpcdev = pci_get_slot(ivideo->nbridge->bus, (2 << 3)); 6034 } 6035 #endif 6036 6037 SiS_SetReg(SISSR, 0x05, 0x86); 6038 6039 if( (!ivideo->sisvga_enabled) 6040 #if !defined(__i386__) && !defined(__x86_64__) 6041 || (sisfb_resetcard) 6042 #endif 6043 ) { 6044 for(i = 0x30; i <= 0x3f; i++) { 6045 SiS_SetReg(SISCR, i, 0x00); 6046 } 6047 } 6048 6049 /* Find out about current video mode */ 6050 ivideo->modeprechange = 0x03; 6051 reg = SiS_GetReg(SISCR, 0x34); 6052 if(reg & 0x7f) { 6053 ivideo->modeprechange = reg & 0x7f; 6054 } else if(ivideo->sisvga_enabled) { 6055 #if defined(__i386__) || defined(__x86_64__) 6056 unsigned char __iomem *tt = ioremap(0x400, 0x100); 6057 if(tt) { 6058 ivideo->modeprechange = readb(tt + 0x49); 6059 iounmap(tt); 6060 } 6061 #endif 6062 } 6063 6064 /* Search and copy ROM image */ 6065 ivideo->bios_abase = NULL; 6066 ivideo->SiS_Pr.VirtualRomBase = NULL; 6067 ivideo->SiS_Pr.UseROM = false; 6068 ivideo->haveXGIROM = ivideo->SiS_Pr.SiS_XGIROM = false; 6069 if(ivideo->sisfb_userom) { 6070 ivideo->SiS_Pr.VirtualRomBase = sisfb_find_rom(pdev); 6071 ivideo->bios_abase = ivideo->SiS_Pr.VirtualRomBase; 6072 ivideo->SiS_Pr.UseROM = (bool)(ivideo->SiS_Pr.VirtualRomBase); 6073 printk(KERN_INFO "sisfb: Video ROM %sfound\n", 6074 ivideo->SiS_Pr.UseROM ? "" : "not "); 6075 if((ivideo->SiS_Pr.UseROM) && (ivideo->chip >= XGI_20)) { 6076 ivideo->SiS_Pr.UseROM = false; 6077 ivideo->haveXGIROM = ivideo->SiS_Pr.SiS_XGIROM = true; 6078 if( (ivideo->revision_id == 2) && 6079 (!(ivideo->bios_abase[0x1d1] & 0x01)) ) { 6080 ivideo->SiS_Pr.DDCPortMixup = true; 6081 } 6082 } 6083 } else { 6084 printk(KERN_INFO "sisfb: Video ROM usage disabled\n"); 6085 } 6086 6087 /* Find systems for special custom timing */ 6088 if(ivideo->SiS_Pr.SiS_CustomT == CUT_NONE) { 6089 sisfb_detect_custom_timing(ivideo); 6090 } 6091 6092 #ifdef CONFIG_FB_SIS_315 6093 if (ivideo->chip == XGI_20) { 6094 /* Check if our Z7 chip is actually Z9 */ 6095 SiS_SetRegOR(SISCR, 0x4a, 0x40); /* GPIOG EN */ 6096 reg = SiS_GetReg(SISCR, 0x48); 6097 if (reg & 0x02) { /* GPIOG */ 6098 ivideo->chip_real_id = XGI_21; 6099 dev_info(&pdev->dev, "Z9 detected\n"); 6100 } 6101 } 6102 #endif 6103 6104 /* POST card in case this has not been done by the BIOS */ 6105 if( (!ivideo->sisvga_enabled) 6106 #if !defined(__i386__) && !defined(__x86_64__) 6107 || (sisfb_resetcard) 6108 #endif 6109 ) { 6110 #ifdef CONFIG_FB_SIS_300 6111 if(ivideo->sisvga_engine == SIS_300_VGA) { 6112 if(ivideo->chip == SIS_300) { 6113 sisfb_post_sis300(pdev); 6114 ivideo->sisfb_can_post = 1; 6115 } 6116 } 6117 #endif 6118 6119 #ifdef CONFIG_FB_SIS_315 6120 if (ivideo->sisvga_engine == SIS_315_VGA) { 6121 int result = 1; 6122 6123 if (ivideo->chip == XGI_20) { 6124 result = sisfb_post_xgi(pdev); 6125 ivideo->sisfb_can_post = 1; 6126 } else if ((ivideo->chip == XGI_40) && ivideo->haveXGIROM) { 6127 result = sisfb_post_xgi(pdev); 6128 ivideo->sisfb_can_post = 1; 6129 } else { 6130 printk(KERN_INFO "sisfb: Card is not " 6131 "POSTed and sisfb can't do this either.\n"); 6132 } 6133 if (!result) { 6134 printk(KERN_ERR "sisfb: Failed to POST card\n"); 6135 ret = -ENODEV; 6136 goto error_3; 6137 } 6138 } 6139 #endif 6140 } 6141 6142 ivideo->sisfb_card_posted = 1; 6143 6144 /* Find out about RAM size */ 6145 if(sisfb_get_dram_size(ivideo)) { 6146 printk(KERN_INFO "sisfb: Fatal error: Unable to determine VRAM size.\n"); 6147 ret = -ENODEV; 6148 goto error_3; 6149 } 6150 6151 6152 /* Enable PCI addressing and MMIO */ 6153 if((ivideo->sisfb_mode_idx < 0) || 6154 ((sisbios_mode[ivideo->sisfb_mode_idx].mode_no[ivideo->mni]) != 0xFF)) { 6155 /* Enable PCI_LINEAR_ADDRESSING and MMIO_ENABLE */ 6156 SiS_SetRegOR(SISSR, IND_SIS_PCI_ADDRESS_SET, (SIS_PCI_ADDR_ENABLE | SIS_MEM_MAP_IO_ENABLE)); 6157 /* Enable 2D accelerator engine */ 6158 SiS_SetRegOR(SISSR, IND_SIS_MODULE_ENABLE, SIS_ENABLE_2D); 6159 } 6160 6161 if(sisfb_pdc != 0xff) { 6162 if(ivideo->sisvga_engine == SIS_300_VGA) 6163 sisfb_pdc &= 0x3c; 6164 else 6165 sisfb_pdc &= 0x1f; 6166 ivideo->SiS_Pr.PDC = sisfb_pdc; 6167 } 6168 #ifdef CONFIG_FB_SIS_315 6169 if(ivideo->sisvga_engine == SIS_315_VGA) { 6170 if(sisfb_pdca != 0xff) 6171 ivideo->SiS_Pr.PDCA = sisfb_pdca & 0x1f; 6172 } 6173 #endif 6174 6175 if(!request_mem_region(ivideo->video_base, ivideo->video_size, "sisfb FB")) { 6176 printk(KERN_ERR "sisfb: Fatal error: Unable to reserve %dMB framebuffer memory\n", 6177 (int)(ivideo->video_size >> 20)); 6178 printk(KERN_ERR "sisfb: Is there another framebuffer driver active?\n"); 6179 ret = -ENODEV; 6180 goto error_3; 6181 } 6182 6183 if(!request_mem_region(ivideo->mmio_base, ivideo->mmio_size, "sisfb MMIO")) { 6184 printk(KERN_ERR "sisfb: Fatal error: Unable to reserve MMIO region\n"); 6185 ret = -ENODEV; 6186 goto error_2; 6187 } 6188 6189 ivideo->video_vbase = ioremap_wc(ivideo->video_base, ivideo->video_size); 6190 ivideo->SiS_Pr.VideoMemoryAddress = ivideo->video_vbase; 6191 if(!ivideo->video_vbase) { 6192 printk(KERN_ERR "sisfb: Fatal error: Unable to map framebuffer memory\n"); 6193 ret = -ENODEV; 6194 goto error_1; 6195 } 6196 6197 ivideo->mmio_vbase = ioremap(ivideo->mmio_base, ivideo->mmio_size); 6198 if(!ivideo->mmio_vbase) { 6199 printk(KERN_ERR "sisfb: Fatal error: Unable to map MMIO region\n"); 6200 ret = -ENODEV; 6201 error_0: iounmap(ivideo->video_vbase); 6202 error_1: release_mem_region(ivideo->video_base, ivideo->video_size); 6203 error_2: release_mem_region(ivideo->mmio_base, ivideo->mmio_size); 6204 error_3: vfree(ivideo->bios_abase); 6205 pci_dev_put(ivideo->lpcdev); 6206 pci_dev_put(ivideo->nbridge); 6207 if(!ivideo->sisvga_enabled) 6208 pci_disable_device(pdev); 6209 framebuffer_release(sis_fb_info); 6210 return ret; 6211 } 6212 6213 printk(KERN_INFO "sisfb: Video RAM at 0x%lx, mapped to 0x%lx, size %ldk\n", 6214 ivideo->video_base, (unsigned long)ivideo->video_vbase, ivideo->video_size / 1024); 6215 6216 if(ivideo->video_offset) { 6217 printk(KERN_INFO "sisfb: Viewport offset %ldk\n", 6218 ivideo->video_offset / 1024); 6219 } 6220 6221 printk(KERN_INFO "sisfb: MMIO at 0x%lx, mapped to 0x%lx, size %ldk\n", 6222 ivideo->mmio_base, (unsigned long)ivideo->mmio_vbase, ivideo->mmio_size / 1024); 6223 6224 6225 /* Determine the size of the command queue */ 6226 if(ivideo->sisvga_engine == SIS_300_VGA) { 6227 ivideo->cmdQueueSize = TURBO_QUEUE_AREA_SIZE; 6228 } else { 6229 if(ivideo->chip == XGI_20) { 6230 ivideo->cmdQueueSize = COMMAND_QUEUE_AREA_SIZE_Z7; 6231 } else { 6232 ivideo->cmdQueueSize = COMMAND_QUEUE_AREA_SIZE; 6233 } 6234 } 6235 6236 /* Engines are no longer initialized here; this is 6237 * now done after the first mode-switch (if the 6238 * submitted var has its acceleration flags set). 6239 */ 6240 6241 /* Calculate the base of the (unused) hw cursor */ 6242 ivideo->hwcursor_vbase = ivideo->video_vbase 6243 + ivideo->video_size 6244 - ivideo->cmdQueueSize 6245 - ivideo->hwcursor_size; 6246 ivideo->caps |= HW_CURSOR_CAP; 6247 6248 /* Initialize offscreen memory manager */ 6249 if((ivideo->havenoheap = sisfb_heap_init(ivideo))) { 6250 printk(KERN_WARNING "sisfb: Failed to initialize offscreen memory heap\n"); 6251 } 6252 6253 /* Used for clearing the screen only, therefore respect our mem limit */ 6254 ivideo->SiS_Pr.VideoMemoryAddress += ivideo->video_offset; 6255 ivideo->SiS_Pr.VideoMemorySize = ivideo->sisfb_mem; 6256 6257 ivideo->vbflags = 0; 6258 ivideo->lcddefmodeidx = DEFAULT_LCDMODE; 6259 ivideo->tvdefmodeidx = DEFAULT_TVMODE; 6260 ivideo->defmodeidx = DEFAULT_MODE; 6261 6262 ivideo->newrom = 0; 6263 if(ivideo->chip < XGI_20) { 6264 if(ivideo->bios_abase) { 6265 ivideo->newrom = SiSDetermineROMLayout661(&ivideo->SiS_Pr); 6266 } 6267 } 6268 6269 if((ivideo->sisfb_mode_idx < 0) || 6270 ((sisbios_mode[ivideo->sisfb_mode_idx].mode_no[ivideo->mni]) != 0xFF)) { 6271 6272 sisfb_sense_crt1(ivideo); 6273 6274 sisfb_get_VB_type(ivideo); 6275 6276 if(ivideo->vbflags2 & VB2_VIDEOBRIDGE) { 6277 sisfb_detect_VB_connect(ivideo); 6278 } 6279 6280 ivideo->currentvbflags = ivideo->vbflags & (VB_VIDEOBRIDGE | TV_STANDARD); 6281 6282 /* Decide on which CRT2 device to use */ 6283 if(ivideo->vbflags2 & VB2_VIDEOBRIDGE) { 6284 if(ivideo->sisfb_crt2type != -1) { 6285 if((ivideo->sisfb_crt2type == CRT2_LCD) && 6286 (ivideo->vbflags & CRT2_LCD)) { 6287 ivideo->currentvbflags |= CRT2_LCD; 6288 } else if(ivideo->sisfb_crt2type != CRT2_LCD) { 6289 ivideo->currentvbflags |= ivideo->sisfb_crt2type; 6290 } 6291 } else { 6292 /* Chrontel 700x TV detection often unreliable, therefore 6293 * use a different default order on such machines 6294 */ 6295 if((ivideo->sisvga_engine == SIS_300_VGA) && 6296 (ivideo->vbflags2 & VB2_CHRONTEL)) { 6297 if(ivideo->vbflags & CRT2_LCD) 6298 ivideo->currentvbflags |= CRT2_LCD; 6299 else if(ivideo->vbflags & CRT2_TV) 6300 ivideo->currentvbflags |= CRT2_TV; 6301 else if(ivideo->vbflags & CRT2_VGA) 6302 ivideo->currentvbflags |= CRT2_VGA; 6303 } else { 6304 if(ivideo->vbflags & CRT2_TV) 6305 ivideo->currentvbflags |= CRT2_TV; 6306 else if(ivideo->vbflags & CRT2_LCD) 6307 ivideo->currentvbflags |= CRT2_LCD; 6308 else if(ivideo->vbflags & CRT2_VGA) 6309 ivideo->currentvbflags |= CRT2_VGA; 6310 } 6311 } 6312 } 6313 6314 if(ivideo->vbflags & CRT2_LCD) { 6315 sisfb_detect_lcd_type(ivideo); 6316 } 6317 6318 sisfb_save_pdc_emi(ivideo); 6319 6320 if(!ivideo->sisfb_crt1off) { 6321 sisfb_handle_ddc(ivideo, &ivideo->sisfb_thismonitor, 0); 6322 } else { 6323 if((ivideo->vbflags2 & VB2_SISTMDSBRIDGE) && 6324 (ivideo->vbflags & (CRT2_VGA | CRT2_LCD))) { 6325 sisfb_handle_ddc(ivideo, &ivideo->sisfb_thismonitor, 1); 6326 } 6327 } 6328 6329 if(ivideo->sisfb_mode_idx >= 0) { 6330 int bu = ivideo->sisfb_mode_idx; 6331 ivideo->sisfb_mode_idx = sisfb_validate_mode(ivideo, 6332 ivideo->sisfb_mode_idx, ivideo->currentvbflags); 6333 if(bu != ivideo->sisfb_mode_idx) { 6334 printk(KERN_ERR "Mode %dx%dx%d failed validation\n", 6335 sisbios_mode[bu].xres, 6336 sisbios_mode[bu].yres, 6337 sisbios_mode[bu].bpp); 6338 } 6339 } 6340 6341 if(ivideo->sisfb_mode_idx < 0) { 6342 switch(ivideo->currentvbflags & VB_DISPTYPE_DISP2) { 6343 case CRT2_LCD: 6344 ivideo->sisfb_mode_idx = ivideo->lcddefmodeidx; 6345 break; 6346 case CRT2_TV: 6347 ivideo->sisfb_mode_idx = ivideo->tvdefmodeidx; 6348 break; 6349 default: 6350 ivideo->sisfb_mode_idx = ivideo->defmodeidx; 6351 break; 6352 } 6353 } 6354 6355 ivideo->mode_no = sisbios_mode[ivideo->sisfb_mode_idx].mode_no[ivideo->mni]; 6356 6357 if(ivideo->refresh_rate != 0) { 6358 sisfb_search_refresh_rate(ivideo, ivideo->refresh_rate, 6359 ivideo->sisfb_mode_idx); 6360 } 6361 6362 if(ivideo->rate_idx == 0) { 6363 ivideo->rate_idx = sisbios_mode[ivideo->sisfb_mode_idx].rate_idx; 6364 ivideo->refresh_rate = 60; 6365 } 6366 6367 if(ivideo->sisfb_thismonitor.datavalid) { 6368 if(!sisfb_verify_rate(ivideo, &ivideo->sisfb_thismonitor, 6369 ivideo->sisfb_mode_idx, 6370 ivideo->rate_idx, 6371 ivideo->refresh_rate)) { 6372 printk(KERN_INFO "sisfb: WARNING: Refresh rate " 6373 "exceeds monitor specs!\n"); 6374 } 6375 } 6376 6377 ivideo->video_bpp = sisbios_mode[ivideo->sisfb_mode_idx].bpp; 6378 ivideo->video_width = sisbios_mode[ivideo->sisfb_mode_idx].xres; 6379 ivideo->video_height = sisbios_mode[ivideo->sisfb_mode_idx].yres; 6380 6381 sisfb_set_vparms(ivideo); 6382 6383 printk(KERN_INFO "sisfb: Default mode is %dx%dx%d (%dHz)\n", 6384 ivideo->video_width, ivideo->video_height, ivideo->video_bpp, 6385 ivideo->refresh_rate); 6386 6387 /* Set up the default var according to chosen default display mode */ 6388 ivideo->default_var.xres = ivideo->default_var.xres_virtual = ivideo->video_width; 6389 ivideo->default_var.yres = ivideo->default_var.yres_virtual = ivideo->video_height; 6390 ivideo->default_var.bits_per_pixel = ivideo->video_bpp; 6391 6392 sisfb_bpp_to_var(ivideo, &ivideo->default_var); 6393 6394 ivideo->default_var.pixclock = (u32) (1000000000 / 6395 sisfb_mode_rate_to_dclock(&ivideo->SiS_Pr, ivideo->mode_no, ivideo->rate_idx)); 6396 6397 if(sisfb_mode_rate_to_ddata(&ivideo->SiS_Pr, ivideo->mode_no, 6398 ivideo->rate_idx, &ivideo->default_var)) { 6399 if((ivideo->default_var.vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) { 6400 ivideo->default_var.pixclock <<= 1; 6401 } 6402 } 6403 6404 if(ivideo->sisfb_ypan) { 6405 /* Maximize regardless of sisfb_max at startup */ 6406 ivideo->default_var.yres_virtual = 6407 sisfb_calc_maxyres(ivideo, &ivideo->default_var); 6408 if(ivideo->default_var.yres_virtual < ivideo->default_var.yres) { 6409 ivideo->default_var.yres_virtual = ivideo->default_var.yres; 6410 } 6411 } 6412 6413 sisfb_calc_pitch(ivideo, &ivideo->default_var); 6414 6415 ivideo->accel = 0; 6416 if(ivideo->sisfb_accel) { 6417 ivideo->accel = -1; 6418 #ifdef STUPID_ACCELF_TEXT_SHIT 6419 ivideo->default_var.accel_flags |= FB_ACCELF_TEXT; 6420 #endif 6421 } 6422 sisfb_initaccel(ivideo); 6423 6424 #if defined(FBINFO_HWACCEL_DISABLED) && defined(FBINFO_HWACCEL_XPAN) 6425 sis_fb_info->flags = FBINFO_HWACCEL_YPAN | 6426 FBINFO_HWACCEL_XPAN | 6427 FBINFO_HWACCEL_COPYAREA | 6428 FBINFO_HWACCEL_FILLRECT | 6429 ((ivideo->accel) ? 0 : FBINFO_HWACCEL_DISABLED); 6430 #endif 6431 sis_fb_info->var = ivideo->default_var; 6432 sis_fb_info->fix = ivideo->sisfb_fix; 6433 sis_fb_info->screen_base = ivideo->video_vbase + ivideo->video_offset; 6434 sis_fb_info->fbops = &sisfb_ops; 6435 sis_fb_info->pseudo_palette = ivideo->pseudo_palette; 6436 6437 fb_alloc_cmap(&sis_fb_info->cmap, 256 , 0); 6438 6439 printk(KERN_DEBUG "sisfb: Initial vbflags 0x%x\n", (int)ivideo->vbflags); 6440 6441 ivideo->wc_cookie = arch_phys_wc_add(ivideo->video_base, 6442 ivideo->video_size); 6443 if(register_framebuffer(sis_fb_info) < 0) { 6444 printk(KERN_ERR "sisfb: Fatal error: Failed to register framebuffer\n"); 6445 ret = -EINVAL; 6446 iounmap(ivideo->mmio_vbase); 6447 goto error_0; 6448 } 6449 6450 ivideo->registered = 1; 6451 6452 /* Enlist us */ 6453 ivideo->next = card_list; 6454 card_list = ivideo; 6455 6456 printk(KERN_INFO "sisfb: 2D acceleration is %s, y-panning %s\n", 6457 ivideo->sisfb_accel ? "enabled" : "disabled", 6458 ivideo->sisfb_ypan ? 6459 (ivideo->sisfb_max ? "enabled (auto-max)" : 6460 "enabled (no auto-max)") : 6461 "disabled"); 6462 6463 6464 fb_info(sis_fb_info, "%s frame buffer device version %d.%d.%d\n", 6465 ivideo->myid, VER_MAJOR, VER_MINOR, VER_LEVEL); 6466 6467 printk(KERN_INFO "sisfb: Copyright (C) 2001-2005 Thomas Winischhofer\n"); 6468 6469 } /* if mode = "none" */ 6470 6471 return 0; 6472 } 6473 6474 /*****************************************************/ 6475 /* PCI DEVICE HANDLING */ 6476 /*****************************************************/ 6477 6478 static void sisfb_remove(struct pci_dev *pdev) 6479 { 6480 struct sis_video_info *ivideo = pci_get_drvdata(pdev); 6481 struct fb_info *sis_fb_info = ivideo->memyselfandi; 6482 int registered = ivideo->registered; 6483 int modechanged = ivideo->modechanged; 6484 6485 /* Unmap */ 6486 iounmap(ivideo->mmio_vbase); 6487 iounmap(ivideo->video_vbase); 6488 6489 /* Release mem regions */ 6490 release_mem_region(ivideo->video_base, ivideo->video_size); 6491 release_mem_region(ivideo->mmio_base, ivideo->mmio_size); 6492 6493 vfree(ivideo->bios_abase); 6494 6495 pci_dev_put(ivideo->lpcdev); 6496 6497 pci_dev_put(ivideo->nbridge); 6498 6499 arch_phys_wc_del(ivideo->wc_cookie); 6500 6501 /* If device was disabled when starting, disable 6502 * it when quitting. 6503 */ 6504 if(!ivideo->sisvga_enabled) 6505 pci_disable_device(pdev); 6506 6507 /* Unregister the framebuffer */ 6508 if(ivideo->registered) { 6509 unregister_framebuffer(sis_fb_info); 6510 framebuffer_release(sis_fb_info); 6511 } 6512 6513 /* OK, our ivideo is gone for good from here. */ 6514 6515 /* TODO: Restore the initial mode 6516 * This sounds easy but is as good as impossible 6517 * on many machines with SiS chip and video bridge 6518 * since text modes are always set up differently 6519 * from machine to machine. Depends on the type 6520 * of integration between chipset and bridge. 6521 */ 6522 if(registered && modechanged) 6523 printk(KERN_INFO 6524 "sisfb: Restoring of text mode not supported yet\n"); 6525 }; 6526 6527 static struct pci_driver sisfb_driver = { 6528 .name = "sisfb", 6529 .id_table = sisfb_pci_table, 6530 .probe = sisfb_probe, 6531 .remove = sisfb_remove, 6532 }; 6533 6534 static int __init sisfb_init(void) 6535 { 6536 #ifndef MODULE 6537 char *options = NULL; 6538 #endif 6539 6540 if (fb_modesetting_disabled("sisfb")) 6541 return -ENODEV; 6542 6543 #ifndef MODULE 6544 if(fb_get_options("sisfb", &options)) 6545 return -ENODEV; 6546 6547 sisfb_setup(options); 6548 #endif 6549 return pci_register_driver(&sisfb_driver); 6550 } 6551 6552 #ifndef MODULE 6553 module_init(sisfb_init); 6554 #endif 6555 6556 /*****************************************************/ 6557 /* MODULE */ 6558 /*****************************************************/ 6559 6560 #ifdef MODULE 6561 6562 static char *mode = NULL; 6563 static int vesa = -1; 6564 static unsigned int rate = 0; 6565 static unsigned int crt1off = 1; 6566 static unsigned int mem = 0; 6567 static char *forcecrt2type = NULL; 6568 static int forcecrt1 = -1; 6569 static int pdc = -1; 6570 static int pdc1 = -1; 6571 static int noaccel = -1; 6572 static int noypan = -1; 6573 static int nomax = -1; 6574 static int userom = -1; 6575 static int useoem = -1; 6576 static char *tvstandard = NULL; 6577 static int nocrt2rate = 0; 6578 static int scalelcd = -1; 6579 static char *specialtiming = NULL; 6580 static int lvdshl = -1; 6581 static int tvxposoffset = 0, tvyposoffset = 0; 6582 #if !defined(__i386__) && !defined(__x86_64__) 6583 static int resetcard = 0; 6584 static int videoram = 0; 6585 #endif 6586 6587 static int __init sisfb_init_module(void) 6588 { 6589 sisfb_setdefaultparms(); 6590 6591 if(rate) 6592 sisfb_parm_rate = rate; 6593 6594 if((scalelcd == 0) || (scalelcd == 1)) 6595 sisfb_scalelcd = scalelcd ^ 1; 6596 6597 /* Need to check crt2 type first for fstn/dstn */ 6598 6599 if(forcecrt2type) 6600 sisfb_search_crt2type(forcecrt2type); 6601 6602 if(tvstandard) 6603 sisfb_search_tvstd(tvstandard); 6604 6605 if(mode) 6606 sisfb_search_mode(mode, false); 6607 else if(vesa != -1) 6608 sisfb_search_vesamode(vesa, false); 6609 6610 sisfb_crt1off = (crt1off == 0) ? 1 : 0; 6611 6612 sisfb_forcecrt1 = forcecrt1; 6613 if(forcecrt1 == 1) 6614 sisfb_crt1off = 0; 6615 else if(forcecrt1 == 0) 6616 sisfb_crt1off = 1; 6617 6618 if(noaccel == 1) 6619 sisfb_accel = 0; 6620 else if(noaccel == 0) 6621 sisfb_accel = 1; 6622 6623 if(noypan == 1) 6624 sisfb_ypan = 0; 6625 else if(noypan == 0) 6626 sisfb_ypan = 1; 6627 6628 if(nomax == 1) 6629 sisfb_max = 0; 6630 else if(nomax == 0) 6631 sisfb_max = 1; 6632 6633 if(mem) 6634 sisfb_parm_mem = mem; 6635 6636 if(userom != -1) 6637 sisfb_userom = userom; 6638 6639 if(useoem != -1) 6640 sisfb_useoem = useoem; 6641 6642 if(pdc != -1) 6643 sisfb_pdc = (pdc & 0x7f); 6644 6645 if(pdc1 != -1) 6646 sisfb_pdca = (pdc1 & 0x1f); 6647 6648 sisfb_nocrt2rate = nocrt2rate; 6649 6650 if(specialtiming) 6651 sisfb_search_specialtiming(specialtiming); 6652 6653 if((lvdshl >= 0) && (lvdshl <= 3)) 6654 sisfb_lvdshl = lvdshl; 6655 6656 sisfb_tvxposoffset = tvxposoffset; 6657 sisfb_tvyposoffset = tvyposoffset; 6658 6659 #if !defined(__i386__) && !defined(__x86_64__) 6660 sisfb_resetcard = (resetcard) ? 1 : 0; 6661 if(videoram) 6662 sisfb_videoram = videoram; 6663 #endif 6664 6665 return sisfb_init(); 6666 } 6667 6668 static void __exit sisfb_remove_module(void) 6669 { 6670 pci_unregister_driver(&sisfb_driver); 6671 printk(KERN_DEBUG "sisfb: Module unloaded\n"); 6672 } 6673 6674 module_init(sisfb_init_module); 6675 module_exit(sisfb_remove_module); 6676 6677 MODULE_DESCRIPTION("SiS 300/540/630/730/315/55x/65x/661/74x/330/76x/34x, XGI V3XT/V5/V8/Z7 framebuffer device driver"); 6678 MODULE_LICENSE("GPL"); 6679 MODULE_AUTHOR("Thomas Winischhofer <thomas@winischhofer.net>, Others"); 6680 6681 module_param(mem, int, 0); 6682 module_param(noaccel, int, 0); 6683 module_param(noypan, int, 0); 6684 module_param(nomax, int, 0); 6685 module_param(userom, int, 0); 6686 module_param(useoem, int, 0); 6687 module_param(mode, charp, 0); 6688 module_param(vesa, int, 0); 6689 module_param(rate, int, 0); 6690 module_param(forcecrt1, int, 0); 6691 module_param(forcecrt2type, charp, 0); 6692 module_param(scalelcd, int, 0); 6693 module_param(pdc, int, 0); 6694 module_param(pdc1, int, 0); 6695 module_param(specialtiming, charp, 0); 6696 module_param(lvdshl, int, 0); 6697 module_param(tvstandard, charp, 0); 6698 module_param(tvxposoffset, int, 0); 6699 module_param(tvyposoffset, int, 0); 6700 module_param(nocrt2rate, int, 0); 6701 #if !defined(__i386__) && !defined(__x86_64__) 6702 module_param(resetcard, int, 0); 6703 module_param(videoram, int, 0); 6704 #endif 6705 6706 MODULE_PARM_DESC(mem, 6707 "\nDetermines the beginning of the video memory heap in KB. This heap is used\n" 6708 "for video RAM management for eg. DRM/DRI. On 300 series, the default depends\n" 6709 "on the amount of video RAM available. If 8MB of video RAM or less is available,\n" 6710 "the heap starts at 4096KB, if between 8 and 16MB are available at 8192KB,\n" 6711 "otherwise at 12288KB. On 315/330/340 series, the heap size is 32KB by default.\n" 6712 "The value is to be specified without 'KB'.\n"); 6713 6714 MODULE_PARM_DESC(noaccel, 6715 "\nIf set to anything other than 0, 2D acceleration will be disabled.\n" 6716 "(default: 0)\n"); 6717 6718 MODULE_PARM_DESC(noypan, 6719 "\nIf set to anything other than 0, y-panning will be disabled and scrolling\n" 6720 "will be performed by redrawing the screen. (default: 0)\n"); 6721 6722 MODULE_PARM_DESC(nomax, 6723 "\nIf y-panning is enabled, sisfb will by default use the entire available video\n" 6724 "memory for the virtual screen in order to optimize scrolling performance. If\n" 6725 "this is set to anything other than 0, sisfb will not do this and thereby \n" 6726 "enable the user to positively specify a virtual Y size of the screen using\n" 6727 "fbset. (default: 0)\n"); 6728 6729 MODULE_PARM_DESC(mode, 6730 "\nSelects the desired default display mode in the format XxYxDepth,\n" 6731 "eg. 1024x768x16. Other formats supported include XxY-Depth and\n" 6732 "XxY-Depth@Rate. If the parameter is only one (decimal or hexadecimal)\n" 6733 "number, it will be interpreted as a VESA mode number. (default: 800x600x8)\n"); 6734 6735 MODULE_PARM_DESC(vesa, 6736 "\nSelects the desired default display mode by VESA defined mode number, eg.\n" 6737 "0x117 (default: 0x0103)\n"); 6738 6739 MODULE_PARM_DESC(rate, 6740 "\nSelects the desired vertical refresh rate for CRT1 (external VGA) in Hz.\n" 6741 "If the mode is specified in the format XxY-Depth@Rate, this parameter\n" 6742 "will be ignored (default: 60)\n"); 6743 6744 MODULE_PARM_DESC(forcecrt1, 6745 "\nNormally, the driver autodetects whether or not CRT1 (external VGA) is \n" 6746 "connected. With this option, the detection can be overridden (1=CRT1 ON,\n" 6747 "0=CRT1 OFF) (default: [autodetected])\n"); 6748 6749 MODULE_PARM_DESC(forcecrt2type, 6750 "\nIf this option is omitted, the driver autodetects CRT2 output devices, such as\n" 6751 "LCD, TV or secondary VGA. With this option, this autodetection can be\n" 6752 "overridden. Possible parameters are LCD, TV, VGA or NONE. NONE disables CRT2.\n" 6753 "On systems with a SiS video bridge, parameters SVIDEO, COMPOSITE or SCART can\n" 6754 "be used instead of TV to override the TV detection. Furthermore, on systems\n" 6755 "with a SiS video bridge, SVIDEO+COMPOSITE, HIVISION, YPBPR480I, YPBPR480P,\n" 6756 "YPBPR720P and YPBPR1080I are understood. However, whether or not these work\n" 6757 "depends on the very hardware in use. (default: [autodetected])\n"); 6758 6759 MODULE_PARM_DESC(scalelcd, 6760 "\nSetting this to 1 will force the driver to scale the LCD image to the panel's\n" 6761 "native resolution. Setting it to 0 will disable scaling; LVDS panels will\n" 6762 "show black bars around the image, TMDS panels will probably do the scaling\n" 6763 "themselves. Default: 1 on LVDS panels, 0 on TMDS panels\n"); 6764 6765 MODULE_PARM_DESC(pdc, 6766 "\nThis is for manually selecting the LCD panel delay compensation. The driver\n" 6767 "should detect this correctly in most cases; however, sometimes this is not\n" 6768 "possible. If you see 'small waves' on the LCD, try setting this to 4, 32 or 24\n" 6769 "on a 300 series chipset; 6 on other chipsets. If the problem persists, try\n" 6770 "other values (on 300 series: between 4 and 60 in steps of 4; otherwise: any\n" 6771 "value from 0 to 31). (default: autodetected, if LCD is active during start)\n"); 6772 6773 #ifdef CONFIG_FB_SIS_315 6774 MODULE_PARM_DESC(pdc1, 6775 "\nThis is same as pdc, but for LCD-via CRT1. Hence, this is for the 315/330/340\n" 6776 "series only. (default: autodetected if LCD is in LCD-via-CRT1 mode during\n" 6777 "startup) - Note: currently, this has no effect because LCD-via-CRT1 is not\n" 6778 "implemented yet.\n"); 6779 #endif 6780 6781 MODULE_PARM_DESC(specialtiming, 6782 "\nPlease refer to documentation for more information on this option.\n"); 6783 6784 MODULE_PARM_DESC(lvdshl, 6785 "\nPlease refer to documentation for more information on this option.\n"); 6786 6787 MODULE_PARM_DESC(tvstandard, 6788 "\nThis allows overriding the BIOS default for the TV standard. Valid choices are\n" 6789 "pal, ntsc, palm and paln. (default: [auto; pal or ntsc only])\n"); 6790 6791 MODULE_PARM_DESC(tvxposoffset, 6792 "\nRelocate TV output horizontally. Possible parameters: -32 through 32.\n" 6793 "Default: 0\n"); 6794 6795 MODULE_PARM_DESC(tvyposoffset, 6796 "\nRelocate TV output vertically. Possible parameters: -32 through 32.\n" 6797 "Default: 0\n"); 6798 6799 MODULE_PARM_DESC(nocrt2rate, 6800 "\nSetting this to 1 will force the driver to use the default refresh rate for\n" 6801 "CRT2 if CRT2 type is VGA. (default: 0, use same rate as CRT1)\n"); 6802 6803 #if !defined(__i386__) && !defined(__x86_64__) 6804 #ifdef CONFIG_FB_SIS_300 6805 MODULE_PARM_DESC(resetcard, 6806 "\nSet this to 1 in order to reset (POST) the card on non-x86 machines where\n" 6807 "the BIOS did not POST the card (only supported for SiS 300/305 and XGI cards\n" 6808 "currently). Default: 0\n"); 6809 6810 MODULE_PARM_DESC(videoram, 6811 "\nSet this to the amount of video RAM (in kilobyte) the card has. Required on\n" 6812 "some non-x86 architectures where the memory auto detection fails. Only\n" 6813 "relevant if resetcard is set, too. SiS300/305 only. Default: [auto-detect]\n"); 6814 #endif 6815 #endif 6816 6817 #endif /* /MODULE */ 6818