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