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