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