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