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 strscpy(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_DEFAULT_IOMEM_OPS_RDWR, 1915 .fb_check_var = sisfb_check_var, 1916 .fb_set_par = sisfb_set_par, 1917 .fb_setcolreg = sisfb_setcolreg, 1918 .fb_pan_display = sisfb_pan_display, 1919 .fb_blank = sisfb_blank, 1920 .fb_fillrect = fbcon_sis_fillrect, 1921 .fb_copyarea = fbcon_sis_copyarea, 1922 .fb_imageblit = cfb_imageblit, 1923 .fb_sync = fbcon_sis_sync, 1924 #ifdef SIS_NEW_CONFIG_COMPAT 1925 .fb_compat_ioctl= sisfb_ioctl, 1926 #endif 1927 .fb_ioctl = sisfb_ioctl, 1928 __FB_DEFAULT_IOMEM_OPS_MMAP, 1929 }; 1930 1931 /* ---------------- Chip generation dependent routines ---------------- */ 1932 1933 static struct pci_dev *sisfb_get_northbridge(int basechipid) 1934 { 1935 struct pci_dev *pdev = NULL; 1936 int nbridgenum, nbridgeidx, i; 1937 static const unsigned short nbridgeids[] = { 1938 PCI_DEVICE_ID_SI_540, /* for SiS 540 VGA */ 1939 PCI_DEVICE_ID_SI_630, /* for SiS 630/730 VGA */ 1940 PCI_DEVICE_ID_SI_730, 1941 PCI_DEVICE_ID_SI_550, /* for SiS 550 VGA */ 1942 PCI_DEVICE_ID_SI_650, /* for SiS 650/651/740 VGA */ 1943 PCI_DEVICE_ID_SI_651, 1944 PCI_DEVICE_ID_SI_740, 1945 PCI_DEVICE_ID_SI_661, /* for SiS 661/741/660/760/761 VGA */ 1946 PCI_DEVICE_ID_SI_741, 1947 PCI_DEVICE_ID_SI_660, 1948 PCI_DEVICE_ID_SI_760, 1949 PCI_DEVICE_ID_SI_761 1950 }; 1951 1952 switch(basechipid) { 1953 #ifdef CONFIG_FB_SIS_300 1954 case SIS_540: nbridgeidx = 0; nbridgenum = 1; break; 1955 case SIS_630: nbridgeidx = 1; nbridgenum = 2; break; 1956 #endif 1957 #ifdef CONFIG_FB_SIS_315 1958 case SIS_550: nbridgeidx = 3; nbridgenum = 1; break; 1959 case SIS_650: nbridgeidx = 4; nbridgenum = 3; break; 1960 case SIS_660: nbridgeidx = 7; nbridgenum = 5; break; 1961 #endif 1962 default: return NULL; 1963 } 1964 for(i = 0; i < nbridgenum; i++) { 1965 if((pdev = pci_get_device(PCI_VENDOR_ID_SI, 1966 nbridgeids[nbridgeidx+i], NULL))) 1967 break; 1968 } 1969 return pdev; 1970 } 1971 1972 static int sisfb_get_dram_size(struct sis_video_info *ivideo) 1973 { 1974 #if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315) 1975 u8 reg; 1976 #endif 1977 1978 ivideo->video_size = 0; 1979 ivideo->UMAsize = ivideo->LFBsize = 0; 1980 1981 switch(ivideo->chip) { 1982 #ifdef CONFIG_FB_SIS_300 1983 case SIS_300: 1984 reg = SiS_GetReg(SISSR, 0x14); 1985 ivideo->video_size = ((reg & 0x3F) + 1) << 20; 1986 break; 1987 case SIS_540: 1988 case SIS_630: 1989 case SIS_730: 1990 if(!ivideo->nbridge) 1991 return -1; 1992 pci_read_config_byte(ivideo->nbridge, 0x63, ®); 1993 ivideo->video_size = 1 << (((reg & 0x70) >> 4) + 21); 1994 break; 1995 #endif 1996 #ifdef CONFIG_FB_SIS_315 1997 case SIS_315H: 1998 case SIS_315PRO: 1999 case SIS_315: 2000 reg = SiS_GetReg(SISSR, 0x14); 2001 ivideo->video_size = (1 << ((reg & 0xf0) >> 4)) << 20; 2002 switch((reg >> 2) & 0x03) { 2003 case 0x01: 2004 case 0x03: 2005 ivideo->video_size <<= 1; 2006 break; 2007 case 0x02: 2008 ivideo->video_size += (ivideo->video_size/2); 2009 } 2010 break; 2011 case SIS_330: 2012 reg = SiS_GetReg(SISSR, 0x14); 2013 ivideo->video_size = (1 << ((reg & 0xf0) >> 4)) << 20; 2014 if(reg & 0x0c) ivideo->video_size <<= 1; 2015 break; 2016 case SIS_550: 2017 case SIS_650: 2018 case SIS_740: 2019 reg = SiS_GetReg(SISSR, 0x14); 2020 ivideo->video_size = (((reg & 0x3f) + 1) << 2) << 20; 2021 break; 2022 case SIS_661: 2023 case SIS_741: 2024 reg = SiS_GetReg(SISCR, 0x79); 2025 ivideo->video_size = (1 << ((reg & 0xf0) >> 4)) << 20; 2026 break; 2027 case SIS_660: 2028 case SIS_760: 2029 case SIS_761: 2030 reg = SiS_GetReg(SISCR, 0x79); 2031 reg = (reg & 0xf0) >> 4; 2032 if(reg) { 2033 ivideo->video_size = (1 << reg) << 20; 2034 ivideo->UMAsize = ivideo->video_size; 2035 } 2036 reg = SiS_GetReg(SISCR, 0x78); 2037 reg &= 0x30; 2038 if(reg) { 2039 if(reg == 0x10) { 2040 ivideo->LFBsize = (32 << 20); 2041 } else { 2042 ivideo->LFBsize = (64 << 20); 2043 } 2044 ivideo->video_size += ivideo->LFBsize; 2045 } 2046 break; 2047 case SIS_340: 2048 case XGI_20: 2049 case XGI_40: 2050 reg = SiS_GetReg(SISSR, 0x14); 2051 ivideo->video_size = (1 << ((reg & 0xf0) >> 4)) << 20; 2052 if(ivideo->chip != XGI_20) { 2053 reg = (reg & 0x0c) >> 2; 2054 if(ivideo->revision_id == 2) { 2055 if(reg & 0x01) reg = 0x02; 2056 else reg = 0x00; 2057 } 2058 if(reg == 0x02) ivideo->video_size <<= 1; 2059 else if(reg == 0x03) ivideo->video_size <<= 2; 2060 } 2061 break; 2062 #endif 2063 default: 2064 return -1; 2065 } 2066 return 0; 2067 } 2068 2069 /* -------------- video bridge device detection --------------- */ 2070 2071 static void sisfb_detect_VB_connect(struct sis_video_info *ivideo) 2072 { 2073 u8 cr32, temp; 2074 2075 /* No CRT2 on XGI Z7 */ 2076 if(ivideo->chip == XGI_20) { 2077 ivideo->sisfb_crt1off = 0; 2078 return; 2079 } 2080 2081 #ifdef CONFIG_FB_SIS_300 2082 if(ivideo->sisvga_engine == SIS_300_VGA) { 2083 temp = SiS_GetReg(SISSR, 0x17); 2084 if((temp & 0x0F) && (ivideo->chip != SIS_300)) { 2085 /* PAL/NTSC is stored on SR16 on such machines */ 2086 if(!(ivideo->vbflags & (TV_PAL | TV_NTSC | TV_PALM | TV_PALN))) { 2087 temp = SiS_GetReg(SISSR, 0x16); 2088 if(temp & 0x20) 2089 ivideo->vbflags |= TV_PAL; 2090 else 2091 ivideo->vbflags |= TV_NTSC; 2092 } 2093 } 2094 } 2095 #endif 2096 2097 cr32 = SiS_GetReg(SISCR, 0x32); 2098 2099 if(cr32 & SIS_CRT1) { 2100 ivideo->sisfb_crt1off = 0; 2101 } else { 2102 ivideo->sisfb_crt1off = (cr32 & 0xDF) ? 1 : 0; 2103 } 2104 2105 ivideo->vbflags &= ~(CRT2_TV | CRT2_LCD | CRT2_VGA); 2106 2107 if(cr32 & SIS_VB_TV) ivideo->vbflags |= CRT2_TV; 2108 if(cr32 & SIS_VB_LCD) ivideo->vbflags |= CRT2_LCD; 2109 if(cr32 & SIS_VB_CRT2) ivideo->vbflags |= CRT2_VGA; 2110 2111 /* Check given parms for hardware compatibility. 2112 * (Cannot do this in the search_xx routines since we don't 2113 * know what hardware we are running on then) 2114 */ 2115 2116 if(ivideo->chip != SIS_550) { 2117 ivideo->sisfb_dstn = ivideo->sisfb_fstn = 0; 2118 } 2119 2120 if(ivideo->sisfb_tvplug != -1) { 2121 if( (ivideo->sisvga_engine != SIS_315_VGA) || 2122 (!(ivideo->vbflags2 & VB2_SISYPBPRBRIDGE)) ) { 2123 if(ivideo->sisfb_tvplug & TV_YPBPR) { 2124 ivideo->sisfb_tvplug = -1; 2125 printk(KERN_ERR "sisfb: YPbPr not supported\n"); 2126 } 2127 } 2128 } 2129 if(ivideo->sisfb_tvplug != -1) { 2130 if( (ivideo->sisvga_engine != SIS_315_VGA) || 2131 (!(ivideo->vbflags2 & VB2_SISHIVISIONBRIDGE)) ) { 2132 if(ivideo->sisfb_tvplug & TV_HIVISION) { 2133 ivideo->sisfb_tvplug = -1; 2134 printk(KERN_ERR "sisfb: HiVision not supported\n"); 2135 } 2136 } 2137 } 2138 if(ivideo->sisfb_tvstd != -1) { 2139 if( (!(ivideo->vbflags2 & VB2_SISBRIDGE)) && 2140 (!((ivideo->sisvga_engine == SIS_315_VGA) && 2141 (ivideo->vbflags2 & VB2_CHRONTEL))) ) { 2142 if(ivideo->sisfb_tvstd & (TV_PALM | TV_PALN | TV_NTSCJ)) { 2143 ivideo->sisfb_tvstd = -1; 2144 printk(KERN_ERR "sisfb: PALM/PALN/NTSCJ not supported\n"); 2145 } 2146 } 2147 } 2148 2149 /* Detect/set TV plug & type */ 2150 if(ivideo->sisfb_tvplug != -1) { 2151 ivideo->vbflags |= ivideo->sisfb_tvplug; 2152 } else { 2153 if(cr32 & SIS_VB_YPBPR) ivideo->vbflags |= (TV_YPBPR|TV_YPBPR525I); /* default: 480i */ 2154 else if(cr32 & SIS_VB_HIVISION) ivideo->vbflags |= TV_HIVISION; 2155 else if(cr32 & SIS_VB_SCART) ivideo->vbflags |= TV_SCART; 2156 else { 2157 if(cr32 & SIS_VB_SVIDEO) ivideo->vbflags |= TV_SVIDEO; 2158 if(cr32 & SIS_VB_COMPOSITE) ivideo->vbflags |= TV_AVIDEO; 2159 } 2160 } 2161 2162 if(!(ivideo->vbflags & (TV_YPBPR | TV_HIVISION))) { 2163 if(ivideo->sisfb_tvstd != -1) { 2164 ivideo->vbflags &= ~(TV_NTSC | TV_PAL | TV_PALM | TV_PALN | TV_NTSCJ); 2165 ivideo->vbflags |= ivideo->sisfb_tvstd; 2166 } 2167 if(ivideo->vbflags & TV_SCART) { 2168 ivideo->vbflags &= ~(TV_NTSC | TV_PALM | TV_PALN | TV_NTSCJ); 2169 ivideo->vbflags |= TV_PAL; 2170 } 2171 if(!(ivideo->vbflags & (TV_PAL | TV_NTSC | TV_PALM | TV_PALN | TV_NTSCJ))) { 2172 if(ivideo->sisvga_engine == SIS_300_VGA) { 2173 temp = SiS_GetReg(SISSR, 0x38); 2174 if(temp & 0x01) ivideo->vbflags |= TV_PAL; 2175 else ivideo->vbflags |= TV_NTSC; 2176 } else if((ivideo->chip <= SIS_315PRO) || (ivideo->chip >= SIS_330)) { 2177 temp = SiS_GetReg(SISSR, 0x38); 2178 if(temp & 0x01) ivideo->vbflags |= TV_PAL; 2179 else ivideo->vbflags |= TV_NTSC; 2180 } else { 2181 temp = SiS_GetReg(SISCR, 0x79); 2182 if(temp & 0x20) ivideo->vbflags |= TV_PAL; 2183 else ivideo->vbflags |= TV_NTSC; 2184 } 2185 } 2186 } 2187 2188 /* Copy forceCRT1 option to CRT1off if option is given */ 2189 if(ivideo->sisfb_forcecrt1 != -1) { 2190 ivideo->sisfb_crt1off = (ivideo->sisfb_forcecrt1) ? 0 : 1; 2191 } 2192 } 2193 2194 /* ------------------ Sensing routines ------------------ */ 2195 2196 static bool sisfb_test_DDC1(struct sis_video_info *ivideo) 2197 { 2198 unsigned short old; 2199 int count = 48; 2200 2201 old = SiS_ReadDDC1Bit(&ivideo->SiS_Pr); 2202 do { 2203 if(old != SiS_ReadDDC1Bit(&ivideo->SiS_Pr)) break; 2204 } while(count--); 2205 return (count != -1); 2206 } 2207 2208 static void sisfb_sense_crt1(struct sis_video_info *ivideo) 2209 { 2210 bool mustwait = false; 2211 u8 sr1F, cr17; 2212 #ifdef CONFIG_FB_SIS_315 2213 u8 cr63 = 0; 2214 #endif 2215 u16 temp = 0xffff; 2216 int i; 2217 2218 sr1F = SiS_GetReg(SISSR, 0x1F); 2219 SiS_SetRegOR(SISSR, 0x1F, 0x04); 2220 SiS_SetRegAND(SISSR, 0x1F, 0x3F); 2221 2222 if (sr1F & 0xc0) 2223 mustwait = true; 2224 2225 #ifdef CONFIG_FB_SIS_315 2226 if (ivideo->sisvga_engine == SIS_315_VGA) { 2227 cr63 = SiS_GetReg(SISCR, ivideo->SiS_Pr.SiS_MyCR63); 2228 cr63 &= 0x40; 2229 SiS_SetRegAND(SISCR, ivideo->SiS_Pr.SiS_MyCR63, 0xBF); 2230 } 2231 #endif 2232 2233 cr17 = SiS_GetReg(SISCR, 0x17); 2234 cr17 &= 0x80; 2235 2236 if (!cr17) { 2237 SiS_SetRegOR(SISCR, 0x17, 0x80); 2238 mustwait = true; 2239 SiS_SetReg(SISSR, 0x00, 0x01); 2240 SiS_SetReg(SISSR, 0x00, 0x03); 2241 } 2242 2243 if (mustwait) { 2244 for (i = 0; i < 10; i++) 2245 sisfbwaitretracecrt1(ivideo); 2246 } 2247 #ifdef CONFIG_FB_SIS_315 2248 if (ivideo->chip >= SIS_330) { 2249 SiS_SetRegAND(SISCR, 0x32, ~0x20); 2250 if (ivideo->chip >= SIS_340) 2251 SiS_SetReg(SISCR, 0x57, 0x4a); 2252 else 2253 SiS_SetReg(SISCR, 0x57, 0x5f); 2254 2255 SiS_SetRegOR(SISCR, 0x53, 0x02); 2256 while ((SiS_GetRegByte(SISINPSTAT)) & 0x01) 2257 break; 2258 while (!((SiS_GetRegByte(SISINPSTAT)) & 0x01)) 2259 break; 2260 if ((SiS_GetRegByte(SISMISCW)) & 0x10) 2261 temp = 1; 2262 2263 SiS_SetRegAND(SISCR, 0x53, 0xfd); 2264 SiS_SetRegAND(SISCR, 0x57, 0x00); 2265 } 2266 #endif 2267 2268 if (temp == 0xffff) { 2269 i = 3; 2270 2271 do { 2272 temp = SiS_HandleDDC(&ivideo->SiS_Pr, ivideo->vbflags, 2273 ivideo->sisvga_engine, 0, 0, NULL, ivideo->vbflags2); 2274 } while (((temp == 0) || (temp == 0xffff)) && i--); 2275 2276 if ((temp == 0) || (temp == 0xffff)) { 2277 if (sisfb_test_DDC1(ivideo)) 2278 temp = 1; 2279 } 2280 } 2281 2282 if ((temp) && (temp != 0xffff)) 2283 SiS_SetRegOR(SISCR, 0x32, 0x20); 2284 2285 #ifdef CONFIG_FB_SIS_315 2286 if (ivideo->sisvga_engine == SIS_315_VGA) 2287 SiS_SetRegANDOR(SISCR, ivideo->SiS_Pr.SiS_MyCR63, 0xBF, cr63); 2288 #endif 2289 2290 SiS_SetRegANDOR(SISCR, 0x17, 0x7F, cr17); 2291 SiS_SetReg(SISSR, 0x1F, sr1F); 2292 } 2293 2294 /* Determine and detect attached devices on SiS30x */ 2295 static void SiS_SenseLCD(struct sis_video_info *ivideo) 2296 { 2297 unsigned char buffer[256]; 2298 unsigned short temp, realcrtno, i; 2299 u8 reg, cr37 = 0, paneltype = 0; 2300 u16 xres, yres; 2301 2302 ivideo->SiS_Pr.PanelSelfDetected = false; 2303 2304 /* LCD detection only for TMDS bridges */ 2305 if (!(ivideo->vbflags2 & VB2_SISTMDSBRIDGE)) 2306 return; 2307 if (ivideo->vbflags2 & VB2_30xBDH) 2308 return; 2309 2310 /* If LCD already set up by BIOS, skip it */ 2311 reg = SiS_GetReg(SISCR, 0x32); 2312 if (reg & 0x08) 2313 return; 2314 2315 realcrtno = 1; 2316 if (ivideo->SiS_Pr.DDCPortMixup) 2317 realcrtno = 0; 2318 2319 /* Check DDC capabilities */ 2320 temp = SiS_HandleDDC(&ivideo->SiS_Pr, ivideo->vbflags, ivideo->sisvga_engine, 2321 realcrtno, 0, &buffer[0], ivideo->vbflags2); 2322 2323 if ((!temp) || (temp == 0xffff) || (!(temp & 0x02))) 2324 return; 2325 2326 /* Read DDC data */ 2327 i = 3; /* Number of retrys */ 2328 do { 2329 temp = SiS_HandleDDC(&ivideo->SiS_Pr, ivideo->vbflags, 2330 ivideo->sisvga_engine, realcrtno, 1, 2331 &buffer[0], ivideo->vbflags2); 2332 } while ((temp) && i--); 2333 2334 if (temp) 2335 return; 2336 2337 /* No digital device */ 2338 if (!(buffer[0x14] & 0x80)) 2339 return; 2340 2341 /* First detailed timing preferred timing? */ 2342 if (!(buffer[0x18] & 0x02)) 2343 return; 2344 2345 xres = buffer[0x38] | ((buffer[0x3a] & 0xf0) << 4); 2346 yres = buffer[0x3b] | ((buffer[0x3d] & 0xf0) << 4); 2347 2348 switch(xres) { 2349 case 1024: 2350 if (yres == 768) 2351 paneltype = 0x02; 2352 break; 2353 case 1280: 2354 if (yres == 1024) 2355 paneltype = 0x03; 2356 break; 2357 case 1600: 2358 if ((yres == 1200) && (ivideo->vbflags2 & VB2_30xC)) 2359 paneltype = 0x0b; 2360 break; 2361 } 2362 2363 if (!paneltype) 2364 return; 2365 2366 if (buffer[0x23]) 2367 cr37 |= 0x10; 2368 2369 if ((buffer[0x47] & 0x18) == 0x18) 2370 cr37 |= ((((buffer[0x47] & 0x06) ^ 0x06) << 5) | 0x20); 2371 else 2372 cr37 |= 0xc0; 2373 2374 SiS_SetReg(SISCR, 0x36, paneltype); 2375 cr37 &= 0xf1; 2376 SiS_SetRegANDOR(SISCR, 0x37, 0x0c, cr37); 2377 SiS_SetRegOR(SISCR, 0x32, 0x08); 2378 2379 ivideo->SiS_Pr.PanelSelfDetected = true; 2380 } 2381 2382 static int SISDoSense(struct sis_video_info *ivideo, u16 type, u16 test) 2383 { 2384 int temp, mytest, result, i, j; 2385 2386 for (j = 0; j < 10; j++) { 2387 result = 0; 2388 for (i = 0; i < 3; i++) { 2389 mytest = test; 2390 SiS_SetReg(SISPART4, 0x11, (type & 0x00ff)); 2391 temp = (type >> 8) | (mytest & 0x00ff); 2392 SiS_SetRegANDOR(SISPART4, 0x10, 0xe0, temp); 2393 SiS_DDC2Delay(&ivideo->SiS_Pr, 0x1500); 2394 mytest >>= 8; 2395 mytest &= 0x7f; 2396 temp = SiS_GetReg(SISPART4, 0x03); 2397 temp ^= 0x0e; 2398 temp &= mytest; 2399 if (temp == mytest) 2400 result++; 2401 #if 1 2402 SiS_SetReg(SISPART4, 0x11, 0x00); 2403 SiS_SetRegAND(SISPART4, 0x10, 0xe0); 2404 SiS_DDC2Delay(&ivideo->SiS_Pr, 0x1000); 2405 #endif 2406 } 2407 2408 if ((result == 0) || (result >= 2)) 2409 break; 2410 } 2411 return result; 2412 } 2413 2414 static void SiS_Sense30x(struct sis_video_info *ivideo) 2415 { 2416 u8 backupP4_0d,backupP2_00,backupP2_4d,backupSR_1e,biosflag=0; 2417 u16 svhs=0, svhs_c=0; 2418 u16 cvbs=0, cvbs_c=0; 2419 u16 vga2=0, vga2_c=0; 2420 int myflag, result; 2421 char stdstr[] = "sisfb: Detected"; 2422 char tvstr[] = "TV connected to"; 2423 2424 if(ivideo->vbflags2 & VB2_301) { 2425 svhs = 0x00b9; cvbs = 0x00b3; vga2 = 0x00d1; 2426 myflag = SiS_GetReg(SISPART4, 0x01); 2427 if(myflag & 0x04) { 2428 svhs = 0x00dd; cvbs = 0x00ee; vga2 = 0x00fd; 2429 } 2430 } else if(ivideo->vbflags2 & (VB2_301B | VB2_302B)) { 2431 svhs = 0x016b; cvbs = 0x0174; vga2 = 0x0190; 2432 } else if(ivideo->vbflags2 & (VB2_301LV | VB2_302LV)) { 2433 svhs = 0x0200; cvbs = 0x0100; 2434 } else if(ivideo->vbflags2 & (VB2_301C | VB2_302ELV | VB2_307T | VB2_307LV)) { 2435 svhs = 0x016b; cvbs = 0x0110; vga2 = 0x0190; 2436 } else 2437 return; 2438 2439 vga2_c = 0x0e08; svhs_c = 0x0404; cvbs_c = 0x0804; 2440 if(ivideo->vbflags & (VB2_301LV|VB2_302LV|VB2_302ELV|VB2_307LV)) { 2441 svhs_c = 0x0408; cvbs_c = 0x0808; 2442 } 2443 2444 biosflag = 2; 2445 if(ivideo->haveXGIROM) { 2446 biosflag = ivideo->bios_abase[0x58] & 0x03; 2447 } else if(ivideo->newrom) { 2448 if(ivideo->bios_abase[0x5d] & 0x04) biosflag |= 0x01; 2449 } else if(ivideo->sisvga_engine == SIS_300_VGA) { 2450 if(ivideo->bios_abase) { 2451 biosflag = ivideo->bios_abase[0xfe] & 0x03; 2452 } 2453 } 2454 2455 if(ivideo->chip == SIS_300) { 2456 myflag = SiS_GetReg(SISSR, 0x3b); 2457 if(!(myflag & 0x01)) vga2 = vga2_c = 0; 2458 } 2459 2460 if(!(ivideo->vbflags2 & VB2_SISVGA2BRIDGE)) { 2461 vga2 = vga2_c = 0; 2462 } 2463 2464 backupSR_1e = SiS_GetReg(SISSR, 0x1e); 2465 SiS_SetRegOR(SISSR, 0x1e, 0x20); 2466 2467 backupP4_0d = SiS_GetReg(SISPART4, 0x0d); 2468 if(ivideo->vbflags2 & VB2_30xC) { 2469 SiS_SetRegANDOR(SISPART4, 0x0d, ~0x07, 0x01); 2470 } else { 2471 SiS_SetRegOR(SISPART4, 0x0d, 0x04); 2472 } 2473 SiS_DDC2Delay(&ivideo->SiS_Pr, 0x2000); 2474 2475 backupP2_00 = SiS_GetReg(SISPART2, 0x00); 2476 SiS_SetReg(SISPART2, 0x00, ((backupP2_00 | 0x1c) & 0xfc)); 2477 2478 backupP2_4d = SiS_GetReg(SISPART2, 0x4d); 2479 if(ivideo->vbflags2 & VB2_SISYPBPRBRIDGE) { 2480 SiS_SetReg(SISPART2, 0x4d, (backupP2_4d & ~0x10)); 2481 } 2482 2483 if(!(ivideo->vbflags2 & VB2_30xCLV)) { 2484 SISDoSense(ivideo, 0, 0); 2485 } 2486 2487 SiS_SetRegAND(SISCR, 0x32, ~0x14); 2488 2489 if(vga2_c || vga2) { 2490 if(SISDoSense(ivideo, vga2, vga2_c)) { 2491 if(biosflag & 0x01) { 2492 printk(KERN_INFO "%s %s SCART output\n", stdstr, tvstr); 2493 SiS_SetRegOR(SISCR, 0x32, 0x04); 2494 } else { 2495 printk(KERN_INFO "%s secondary VGA connection\n", stdstr); 2496 SiS_SetRegOR(SISCR, 0x32, 0x10); 2497 } 2498 } 2499 } 2500 2501 SiS_SetRegAND(SISCR, 0x32, 0x3f); 2502 2503 if(ivideo->vbflags2 & VB2_30xCLV) { 2504 SiS_SetRegOR(SISPART4, 0x0d, 0x04); 2505 } 2506 2507 if((ivideo->sisvga_engine == SIS_315_VGA) && (ivideo->vbflags2 & VB2_SISYPBPRBRIDGE)) { 2508 SiS_SetReg(SISPART2, 0x4d, (backupP2_4d | 0x10)); 2509 SiS_DDC2Delay(&ivideo->SiS_Pr, 0x2000); 2510 if((result = SISDoSense(ivideo, svhs, 0x0604))) { 2511 if((result = SISDoSense(ivideo, cvbs, 0x0804))) { 2512 printk(KERN_INFO "%s %s YPbPr component output\n", stdstr, tvstr); 2513 SiS_SetRegOR(SISCR, 0x32, 0x80); 2514 } 2515 } 2516 SiS_SetReg(SISPART2, 0x4d, backupP2_4d); 2517 } 2518 2519 SiS_SetRegAND(SISCR, 0x32, ~0x03); 2520 2521 if(!(ivideo->vbflags & TV_YPBPR)) { 2522 if((result = SISDoSense(ivideo, svhs, svhs_c))) { 2523 printk(KERN_INFO "%s %s SVIDEO output\n", stdstr, tvstr); 2524 SiS_SetRegOR(SISCR, 0x32, 0x02); 2525 } 2526 if((biosflag & 0x02) || (!result)) { 2527 if(SISDoSense(ivideo, cvbs, cvbs_c)) { 2528 printk(KERN_INFO "%s %s COMPOSITE output\n", stdstr, tvstr); 2529 SiS_SetRegOR(SISCR, 0x32, 0x01); 2530 } 2531 } 2532 } 2533 2534 SISDoSense(ivideo, 0, 0); 2535 2536 SiS_SetReg(SISPART2, 0x00, backupP2_00); 2537 SiS_SetReg(SISPART4, 0x0d, backupP4_0d); 2538 SiS_SetReg(SISSR, 0x1e, backupSR_1e); 2539 2540 if(ivideo->vbflags2 & VB2_30xCLV) { 2541 biosflag = SiS_GetReg(SISPART2, 0x00); 2542 if(biosflag & 0x20) { 2543 for(myflag = 2; myflag > 0; myflag--) { 2544 biosflag ^= 0x20; 2545 SiS_SetReg(SISPART2, 0x00, biosflag); 2546 } 2547 } 2548 } 2549 2550 SiS_SetReg(SISPART2, 0x00, backupP2_00); 2551 } 2552 2553 /* Determine and detect attached TV's on Chrontel */ 2554 static void SiS_SenseCh(struct sis_video_info *ivideo) 2555 { 2556 #if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315) 2557 u8 temp1, temp2; 2558 char stdstr[] = "sisfb: Chrontel: Detected TV connected to"; 2559 #endif 2560 #ifdef CONFIG_FB_SIS_300 2561 unsigned char test[3]; 2562 int i; 2563 #endif 2564 2565 if(ivideo->chip < SIS_315H) { 2566 2567 #ifdef CONFIG_FB_SIS_300 2568 ivideo->SiS_Pr.SiS_IF_DEF_CH70xx = 1; /* Chrontel 700x */ 2569 SiS_SetChrontelGPIO(&ivideo->SiS_Pr, 0x9c); /* Set general purpose IO for Chrontel communication */ 2570 SiS_DDC2Delay(&ivideo->SiS_Pr, 1000); 2571 temp1 = SiS_GetCH700x(&ivideo->SiS_Pr, 0x25); 2572 /* See Chrontel TB31 for explanation */ 2573 temp2 = SiS_GetCH700x(&ivideo->SiS_Pr, 0x0e); 2574 if(((temp2 & 0x07) == 0x01) || (temp2 & 0x04)) { 2575 SiS_SetCH700x(&ivideo->SiS_Pr, 0x0e, 0x0b); 2576 SiS_DDC2Delay(&ivideo->SiS_Pr, 300); 2577 } 2578 temp2 = SiS_GetCH700x(&ivideo->SiS_Pr, 0x25); 2579 if(temp2 != temp1) temp1 = temp2; 2580 2581 if((temp1 >= 0x22) && (temp1 <= 0x50)) { 2582 /* Read power status */ 2583 temp1 = SiS_GetCH700x(&ivideo->SiS_Pr, 0x0e); 2584 if((temp1 & 0x03) != 0x03) { 2585 /* Power all outputs */ 2586 SiS_SetCH700x(&ivideo->SiS_Pr, 0x0e,0x0b); 2587 SiS_DDC2Delay(&ivideo->SiS_Pr, 300); 2588 } 2589 /* Sense connected TV devices */ 2590 for(i = 0; i < 3; i++) { 2591 SiS_SetCH700x(&ivideo->SiS_Pr, 0x10, 0x01); 2592 SiS_DDC2Delay(&ivideo->SiS_Pr, 0x96); 2593 SiS_SetCH700x(&ivideo->SiS_Pr, 0x10, 0x00); 2594 SiS_DDC2Delay(&ivideo->SiS_Pr, 0x96); 2595 temp1 = SiS_GetCH700x(&ivideo->SiS_Pr, 0x10); 2596 if(!(temp1 & 0x08)) test[i] = 0x02; 2597 else if(!(temp1 & 0x02)) test[i] = 0x01; 2598 else test[i] = 0; 2599 SiS_DDC2Delay(&ivideo->SiS_Pr, 0x96); 2600 } 2601 2602 if(test[0] == test[1]) temp1 = test[0]; 2603 else if(test[0] == test[2]) temp1 = test[0]; 2604 else if(test[1] == test[2]) temp1 = test[1]; 2605 else { 2606 printk(KERN_INFO 2607 "sisfb: TV detection unreliable - test results varied\n"); 2608 temp1 = test[2]; 2609 } 2610 if(temp1 == 0x02) { 2611 printk(KERN_INFO "%s SVIDEO output\n", stdstr); 2612 ivideo->vbflags |= TV_SVIDEO; 2613 SiS_SetRegOR(SISCR, 0x32, 0x02); 2614 SiS_SetRegAND(SISCR, 0x32, ~0x05); 2615 } else if (temp1 == 0x01) { 2616 printk(KERN_INFO "%s CVBS output\n", stdstr); 2617 ivideo->vbflags |= TV_AVIDEO; 2618 SiS_SetRegOR(SISCR, 0x32, 0x01); 2619 SiS_SetRegAND(SISCR, 0x32, ~0x06); 2620 } else { 2621 SiS_SetCH70xxANDOR(&ivideo->SiS_Pr, 0x0e, 0x01, 0xF8); 2622 SiS_SetRegAND(SISCR, 0x32, ~0x07); 2623 } 2624 } else if(temp1 == 0) { 2625 SiS_SetCH70xxANDOR(&ivideo->SiS_Pr, 0x0e, 0x01, 0xF8); 2626 SiS_SetRegAND(SISCR, 0x32, ~0x07); 2627 } 2628 /* Set general purpose IO for Chrontel communication */ 2629 SiS_SetChrontelGPIO(&ivideo->SiS_Pr, 0x00); 2630 #endif 2631 2632 } else { 2633 2634 #ifdef CONFIG_FB_SIS_315 2635 ivideo->SiS_Pr.SiS_IF_DEF_CH70xx = 2; /* Chrontel 7019 */ 2636 temp1 = SiS_GetCH701x(&ivideo->SiS_Pr, 0x49); 2637 SiS_SetCH701x(&ivideo->SiS_Pr, 0x49, 0x20); 2638 SiS_DDC2Delay(&ivideo->SiS_Pr, 0x96); 2639 temp2 = SiS_GetCH701x(&ivideo->SiS_Pr, 0x20); 2640 temp2 |= 0x01; 2641 SiS_SetCH701x(&ivideo->SiS_Pr, 0x20, temp2); 2642 SiS_DDC2Delay(&ivideo->SiS_Pr, 0x96); 2643 temp2 ^= 0x01; 2644 SiS_SetCH701x(&ivideo->SiS_Pr, 0x20, temp2); 2645 SiS_DDC2Delay(&ivideo->SiS_Pr, 0x96); 2646 temp2 = SiS_GetCH701x(&ivideo->SiS_Pr, 0x20); 2647 SiS_SetCH701x(&ivideo->SiS_Pr, 0x49, temp1); 2648 temp1 = 0; 2649 if(temp2 & 0x02) temp1 |= 0x01; 2650 if(temp2 & 0x10) temp1 |= 0x01; 2651 if(temp2 & 0x04) temp1 |= 0x02; 2652 if( (temp1 & 0x01) && (temp1 & 0x02) ) temp1 = 0x04; 2653 switch(temp1) { 2654 case 0x01: 2655 printk(KERN_INFO "%s CVBS output\n", stdstr); 2656 ivideo->vbflags |= TV_AVIDEO; 2657 SiS_SetRegOR(SISCR, 0x32, 0x01); 2658 SiS_SetRegAND(SISCR, 0x32, ~0x06); 2659 break; 2660 case 0x02: 2661 printk(KERN_INFO "%s SVIDEO output\n", stdstr); 2662 ivideo->vbflags |= TV_SVIDEO; 2663 SiS_SetRegOR(SISCR, 0x32, 0x02); 2664 SiS_SetRegAND(SISCR, 0x32, ~0x05); 2665 break; 2666 case 0x04: 2667 printk(KERN_INFO "%s SCART output\n", stdstr); 2668 SiS_SetRegOR(SISCR, 0x32, 0x04); 2669 SiS_SetRegAND(SISCR, 0x32, ~0x03); 2670 break; 2671 default: 2672 SiS_SetRegAND(SISCR, 0x32, ~0x07); 2673 } 2674 #endif 2675 } 2676 } 2677 2678 static void sisfb_get_VB_type(struct sis_video_info *ivideo) 2679 { 2680 char stdstr[] = "sisfb: Detected"; 2681 char bridgestr[] = "video bridge"; 2682 u8 vb_chipid; 2683 u8 reg; 2684 2685 /* No CRT2 on XGI Z7 */ 2686 if(ivideo->chip == XGI_20) 2687 return; 2688 2689 vb_chipid = SiS_GetReg(SISPART4, 0x00); 2690 switch(vb_chipid) { 2691 case 0x01: 2692 reg = SiS_GetReg(SISPART4, 0x01); 2693 if(reg < 0xb0) { 2694 ivideo->vbflags |= VB_301; /* Deprecated */ 2695 ivideo->vbflags2 |= VB2_301; 2696 printk(KERN_INFO "%s SiS301 %s\n", stdstr, bridgestr); 2697 } else if(reg < 0xc0) { 2698 ivideo->vbflags |= VB_301B; /* Deprecated */ 2699 ivideo->vbflags2 |= VB2_301B; 2700 reg = SiS_GetReg(SISPART4, 0x23); 2701 if(!(reg & 0x02)) { 2702 ivideo->vbflags |= VB_30xBDH; /* Deprecated */ 2703 ivideo->vbflags2 |= VB2_30xBDH; 2704 printk(KERN_INFO "%s SiS301B-DH %s\n", stdstr, bridgestr); 2705 } else { 2706 printk(KERN_INFO "%s SiS301B %s\n", stdstr, bridgestr); 2707 } 2708 } else if(reg < 0xd0) { 2709 ivideo->vbflags |= VB_301C; /* Deprecated */ 2710 ivideo->vbflags2 |= VB2_301C; 2711 printk(KERN_INFO "%s SiS301C %s\n", stdstr, bridgestr); 2712 } else if(reg < 0xe0) { 2713 ivideo->vbflags |= VB_301LV; /* Deprecated */ 2714 ivideo->vbflags2 |= VB2_301LV; 2715 printk(KERN_INFO "%s SiS301LV %s\n", stdstr, bridgestr); 2716 } else if(reg <= 0xe1) { 2717 reg = SiS_GetReg(SISPART4, 0x39); 2718 if(reg == 0xff) { 2719 ivideo->vbflags |= VB_302LV; /* Deprecated */ 2720 ivideo->vbflags2 |= VB2_302LV; 2721 printk(KERN_INFO "%s SiS302LV %s\n", stdstr, bridgestr); 2722 } else { 2723 ivideo->vbflags |= VB_301C; /* Deprecated */ 2724 ivideo->vbflags2 |= VB2_301C; 2725 printk(KERN_INFO "%s SiS301C(P4) %s\n", stdstr, bridgestr); 2726 #if 0 2727 ivideo->vbflags |= VB_302ELV; /* Deprecated */ 2728 ivideo->vbflags2 |= VB2_302ELV; 2729 printk(KERN_INFO "%s SiS302ELV %s\n", stdstr, bridgestr); 2730 #endif 2731 } 2732 } 2733 break; 2734 case 0x02: 2735 ivideo->vbflags |= VB_302B; /* Deprecated */ 2736 ivideo->vbflags2 |= VB2_302B; 2737 printk(KERN_INFO "%s SiS302B %s\n", stdstr, bridgestr); 2738 break; 2739 } 2740 2741 if((!(ivideo->vbflags2 & VB2_VIDEOBRIDGE)) && (ivideo->chip != SIS_300)) { 2742 reg = SiS_GetReg(SISCR, 0x37); 2743 reg &= SIS_EXTERNAL_CHIP_MASK; 2744 reg >>= 1; 2745 if(ivideo->sisvga_engine == SIS_300_VGA) { 2746 #ifdef CONFIG_FB_SIS_300 2747 switch(reg) { 2748 case SIS_EXTERNAL_CHIP_LVDS: 2749 ivideo->vbflags |= VB_LVDS; /* Deprecated */ 2750 ivideo->vbflags2 |= VB2_LVDS; 2751 break; 2752 case SIS_EXTERNAL_CHIP_TRUMPION: 2753 ivideo->vbflags |= (VB_LVDS | VB_TRUMPION); /* Deprecated */ 2754 ivideo->vbflags2 |= (VB2_LVDS | VB2_TRUMPION); 2755 break; 2756 case SIS_EXTERNAL_CHIP_CHRONTEL: 2757 ivideo->vbflags |= VB_CHRONTEL; /* Deprecated */ 2758 ivideo->vbflags2 |= VB2_CHRONTEL; 2759 break; 2760 case SIS_EXTERNAL_CHIP_LVDS_CHRONTEL: 2761 ivideo->vbflags |= (VB_LVDS | VB_CHRONTEL); /* Deprecated */ 2762 ivideo->vbflags2 |= (VB2_LVDS | VB2_CHRONTEL); 2763 break; 2764 } 2765 if(ivideo->vbflags2 & VB2_CHRONTEL) ivideo->chronteltype = 1; 2766 #endif 2767 } else if(ivideo->chip < SIS_661) { 2768 #ifdef CONFIG_FB_SIS_315 2769 switch (reg) { 2770 case SIS310_EXTERNAL_CHIP_LVDS: 2771 ivideo->vbflags |= VB_LVDS; /* Deprecated */ 2772 ivideo->vbflags2 |= VB2_LVDS; 2773 break; 2774 case SIS310_EXTERNAL_CHIP_LVDS_CHRONTEL: 2775 ivideo->vbflags |= (VB_LVDS | VB_CHRONTEL); /* Deprecated */ 2776 ivideo->vbflags2 |= (VB2_LVDS | VB2_CHRONTEL); 2777 break; 2778 } 2779 if(ivideo->vbflags2 & VB2_CHRONTEL) ivideo->chronteltype = 2; 2780 #endif 2781 } else if(ivideo->chip >= SIS_661) { 2782 #ifdef CONFIG_FB_SIS_315 2783 reg = SiS_GetReg(SISCR, 0x38); 2784 reg >>= 5; 2785 switch(reg) { 2786 case 0x02: 2787 ivideo->vbflags |= VB_LVDS; /* Deprecated */ 2788 ivideo->vbflags2 |= VB2_LVDS; 2789 break; 2790 case 0x03: 2791 ivideo->vbflags |= (VB_LVDS | VB_CHRONTEL); /* Deprecated */ 2792 ivideo->vbflags2 |= (VB2_LVDS | VB2_CHRONTEL); 2793 break; 2794 case 0x04: 2795 ivideo->vbflags |= (VB_LVDS | VB_CONEXANT); /* Deprecated */ 2796 ivideo->vbflags2 |= (VB2_LVDS | VB2_CONEXANT); 2797 break; 2798 } 2799 if(ivideo->vbflags2 & VB2_CHRONTEL) ivideo->chronteltype = 2; 2800 #endif 2801 } 2802 if(ivideo->vbflags2 & VB2_LVDS) { 2803 printk(KERN_INFO "%s LVDS transmitter\n", stdstr); 2804 } 2805 if((ivideo->sisvga_engine == SIS_300_VGA) && (ivideo->vbflags2 & VB2_TRUMPION)) { 2806 printk(KERN_INFO "%s Trumpion Zurac LCD scaler\n", stdstr); 2807 } 2808 if(ivideo->vbflags2 & VB2_CHRONTEL) { 2809 printk(KERN_INFO "%s Chrontel TV encoder\n", stdstr); 2810 } 2811 if((ivideo->chip >= SIS_661) && (ivideo->vbflags2 & VB2_CONEXANT)) { 2812 printk(KERN_INFO "%s Conexant external device\n", stdstr); 2813 } 2814 } 2815 2816 if(ivideo->vbflags2 & VB2_SISBRIDGE) { 2817 SiS_SenseLCD(ivideo); 2818 SiS_Sense30x(ivideo); 2819 } else if(ivideo->vbflags2 & VB2_CHRONTEL) { 2820 SiS_SenseCh(ivideo); 2821 } 2822 } 2823 2824 /* ---------- Engine initialization routines ------------ */ 2825 2826 static void 2827 sisfb_engine_init(struct sis_video_info *ivideo) 2828 { 2829 2830 /* Initialize command queue (we use MMIO only) */ 2831 2832 /* BEFORE THIS IS CALLED, THE ENGINES *MUST* BE SYNC'ED */ 2833 2834 ivideo->caps &= ~(TURBO_QUEUE_CAP | 2835 MMIO_CMD_QUEUE_CAP | 2836 VM_CMD_QUEUE_CAP | 2837 AGP_CMD_QUEUE_CAP); 2838 2839 #ifdef CONFIG_FB_SIS_300 2840 if(ivideo->sisvga_engine == SIS_300_VGA) { 2841 u32 tqueue_pos; 2842 u8 tq_state; 2843 2844 tqueue_pos = (ivideo->video_size - ivideo->cmdQueueSize) / (64 * 1024); 2845 2846 tq_state = SiS_GetReg(SISSR, IND_SIS_TURBOQUEUE_SET); 2847 tq_state |= 0xf0; 2848 tq_state &= 0xfc; 2849 tq_state |= (u8)(tqueue_pos >> 8); 2850 SiS_SetReg(SISSR, IND_SIS_TURBOQUEUE_SET, tq_state); 2851 2852 SiS_SetReg(SISSR, IND_SIS_TURBOQUEUE_ADR, (u8)(tqueue_pos & 0xff)); 2853 2854 ivideo->caps |= TURBO_QUEUE_CAP; 2855 } 2856 #endif 2857 2858 #ifdef CONFIG_FB_SIS_315 2859 if(ivideo->sisvga_engine == SIS_315_VGA) { 2860 u32 tempq = 0, templ; 2861 u8 temp; 2862 2863 if(ivideo->chip == XGI_20) { 2864 switch(ivideo->cmdQueueSize) { 2865 case (64 * 1024): 2866 temp = SIS_CMD_QUEUE_SIZE_Z7_64k; 2867 break; 2868 case (128 * 1024): 2869 default: 2870 temp = SIS_CMD_QUEUE_SIZE_Z7_128k; 2871 } 2872 } else { 2873 switch(ivideo->cmdQueueSize) { 2874 case (4 * 1024 * 1024): 2875 temp = SIS_CMD_QUEUE_SIZE_4M; 2876 break; 2877 case (2 * 1024 * 1024): 2878 temp = SIS_CMD_QUEUE_SIZE_2M; 2879 break; 2880 case (1 * 1024 * 1024): 2881 temp = SIS_CMD_QUEUE_SIZE_1M; 2882 break; 2883 default: 2884 case (512 * 1024): 2885 temp = SIS_CMD_QUEUE_SIZE_512k; 2886 } 2887 } 2888 2889 SiS_SetReg(SISSR, IND_SIS_CMDQUEUE_THRESHOLD, COMMAND_QUEUE_THRESHOLD); 2890 SiS_SetReg(SISSR, IND_SIS_CMDQUEUE_SET, SIS_CMD_QUEUE_RESET); 2891 2892 if((ivideo->chip >= XGI_40) && ivideo->modechanged) { 2893 /* Must disable dual pipe on XGI_40. Can't do 2894 * this in MMIO mode, because it requires 2895 * setting/clearing a bit in the MMIO fire trigger 2896 * register. 2897 */ 2898 if(!((templ = MMIO_IN32(ivideo->mmio_vbase, 0x8240)) & (1 << 10))) { 2899 2900 MMIO_OUT32(ivideo->mmio_vbase, Q_WRITE_PTR, 0); 2901 2902 SiS_SetReg(SISSR, IND_SIS_CMDQUEUE_SET, (temp | SIS_VRAM_CMDQUEUE_ENABLE)); 2903 2904 tempq = MMIO_IN32(ivideo->mmio_vbase, Q_READ_PTR); 2905 MMIO_OUT32(ivideo->mmio_vbase, Q_WRITE_PTR, tempq); 2906 2907 tempq = (u32)(ivideo->video_size - ivideo->cmdQueueSize); 2908 MMIO_OUT32(ivideo->mmio_vbase, Q_BASE_ADDR, tempq); 2909 2910 writel(0x16800000 + 0x8240, ivideo->video_vbase + tempq); 2911 writel(templ | (1 << 10), ivideo->video_vbase + tempq + 4); 2912 writel(0x168F0000, ivideo->video_vbase + tempq + 8); 2913 writel(0x168F0000, ivideo->video_vbase + tempq + 12); 2914 2915 MMIO_OUT32(ivideo->mmio_vbase, Q_WRITE_PTR, (tempq + 16)); 2916 2917 sisfb_syncaccel(ivideo); 2918 2919 SiS_SetReg(SISSR, IND_SIS_CMDQUEUE_SET, SIS_CMD_QUEUE_RESET); 2920 2921 } 2922 } 2923 2924 tempq = MMIO_IN32(ivideo->mmio_vbase, MMIO_QUEUE_READPORT); 2925 MMIO_OUT32(ivideo->mmio_vbase, MMIO_QUEUE_WRITEPORT, tempq); 2926 2927 temp |= (SIS_MMIO_CMD_ENABLE | SIS_CMD_AUTO_CORR); 2928 SiS_SetReg(SISSR, IND_SIS_CMDQUEUE_SET, temp); 2929 2930 tempq = (u32)(ivideo->video_size - ivideo->cmdQueueSize); 2931 MMIO_OUT32(ivideo->mmio_vbase, MMIO_QUEUE_PHYBASE, tempq); 2932 2933 ivideo->caps |= MMIO_CMD_QUEUE_CAP; 2934 } 2935 #endif 2936 2937 ivideo->engineok = 1; 2938 } 2939 2940 static void sisfb_detect_lcd_type(struct sis_video_info *ivideo) 2941 { 2942 u8 reg; 2943 int i; 2944 2945 reg = SiS_GetReg(SISCR, 0x36); 2946 reg &= 0x0f; 2947 if(ivideo->sisvga_engine == SIS_300_VGA) { 2948 ivideo->CRT2LCDType = sis300paneltype[reg]; 2949 } else if(ivideo->chip >= SIS_661) { 2950 ivideo->CRT2LCDType = sis661paneltype[reg]; 2951 } else { 2952 ivideo->CRT2LCDType = sis310paneltype[reg]; 2953 if((ivideo->chip == SIS_550) && (sisfb_fstn)) { 2954 if((ivideo->CRT2LCDType != LCD_320x240_2) && 2955 (ivideo->CRT2LCDType != LCD_320x240_3)) { 2956 ivideo->CRT2LCDType = LCD_320x240; 2957 } 2958 } 2959 } 2960 2961 if(ivideo->CRT2LCDType == LCD_UNKNOWN) { 2962 /* For broken BIOSes: Assume 1024x768, RGB18 */ 2963 ivideo->CRT2LCDType = LCD_1024x768; 2964 SiS_SetRegANDOR(SISCR, 0x36, 0xf0, 0x02); 2965 SiS_SetRegANDOR(SISCR, 0x37, 0xee, 0x01); 2966 printk(KERN_DEBUG "sisfb: Invalid panel ID (%02x), assuming 1024x768, RGB18\n", reg); 2967 } 2968 2969 for(i = 0; i < SIS_LCD_NUMBER; i++) { 2970 if(ivideo->CRT2LCDType == sis_lcd_data[i].lcdtype) { 2971 ivideo->lcdxres = sis_lcd_data[i].xres; 2972 ivideo->lcdyres = sis_lcd_data[i].yres; 2973 ivideo->lcddefmodeidx = sis_lcd_data[i].default_mode_idx; 2974 break; 2975 } 2976 } 2977 2978 #ifdef CONFIG_FB_SIS_300 2979 if(ivideo->SiS_Pr.SiS_CustomT == CUT_BARCO1366) { 2980 ivideo->lcdxres = 1360; ivideo->lcdyres = 1024; 2981 ivideo->lcddefmodeidx = DEFAULT_MODE_1360; 2982 } else if(ivideo->SiS_Pr.SiS_CustomT == CUT_PANEL848) { 2983 ivideo->lcdxres = 848; ivideo->lcdyres = 480; 2984 ivideo->lcddefmodeidx = DEFAULT_MODE_848; 2985 } else if(ivideo->SiS_Pr.SiS_CustomT == CUT_PANEL856) { 2986 ivideo->lcdxres = 856; ivideo->lcdyres = 480; 2987 ivideo->lcddefmodeidx = DEFAULT_MODE_856; 2988 } 2989 #endif 2990 2991 printk(KERN_DEBUG "sisfb: Detected %dx%d flat panel\n", 2992 ivideo->lcdxres, ivideo->lcdyres); 2993 } 2994 2995 static void sisfb_save_pdc_emi(struct sis_video_info *ivideo) 2996 { 2997 #ifdef CONFIG_FB_SIS_300 2998 /* Save the current PanelDelayCompensation if the LCD is currently used */ 2999 if(ivideo->sisvga_engine == SIS_300_VGA) { 3000 if(ivideo->vbflags2 & (VB2_LVDS | VB2_30xBDH)) { 3001 int tmp; 3002 tmp = SiS_GetReg(SISCR, 0x30); 3003 if(tmp & 0x20) { 3004 /* Currently on LCD? If yes, read current pdc */ 3005 ivideo->detectedpdc = SiS_GetReg(SISPART1, 0x13); 3006 ivideo->detectedpdc &= 0x3c; 3007 if(ivideo->SiS_Pr.PDC == -1) { 3008 /* Let option override detection */ 3009 ivideo->SiS_Pr.PDC = ivideo->detectedpdc; 3010 } 3011 printk(KERN_INFO "sisfb: Detected LCD PDC 0x%02x\n", 3012 ivideo->detectedpdc); 3013 } 3014 if((ivideo->SiS_Pr.PDC != -1) && 3015 (ivideo->SiS_Pr.PDC != ivideo->detectedpdc)) { 3016 printk(KERN_INFO "sisfb: Using LCD PDC 0x%02x\n", 3017 ivideo->SiS_Pr.PDC); 3018 } 3019 } 3020 } 3021 #endif 3022 3023 #ifdef CONFIG_FB_SIS_315 3024 if(ivideo->sisvga_engine == SIS_315_VGA) { 3025 3026 /* Try to find about LCDA */ 3027 if(ivideo->vbflags2 & VB2_SISLCDABRIDGE) { 3028 int tmp; 3029 tmp = SiS_GetReg(SISPART1, 0x13); 3030 if(tmp & 0x04) { 3031 ivideo->SiS_Pr.SiS_UseLCDA = true; 3032 ivideo->detectedlcda = 0x03; 3033 } 3034 } 3035 3036 /* Save PDC */ 3037 if(ivideo->vbflags2 & VB2_SISLVDSBRIDGE) { 3038 int tmp; 3039 tmp = SiS_GetReg(SISCR, 0x30); 3040 if((tmp & 0x20) || (ivideo->detectedlcda != 0xff)) { 3041 /* Currently on LCD? If yes, read current pdc */ 3042 u8 pdc; 3043 pdc = SiS_GetReg(SISPART1, 0x2D); 3044 ivideo->detectedpdc = (pdc & 0x0f) << 1; 3045 ivideo->detectedpdca = (pdc & 0xf0) >> 3; 3046 pdc = SiS_GetReg(SISPART1, 0x35); 3047 ivideo->detectedpdc |= ((pdc >> 7) & 0x01); 3048 pdc = SiS_GetReg(SISPART1, 0x20); 3049 ivideo->detectedpdca |= ((pdc >> 6) & 0x01); 3050 if(ivideo->newrom) { 3051 /* New ROM invalidates other PDC resp. */ 3052 if(ivideo->detectedlcda != 0xff) { 3053 ivideo->detectedpdc = 0xff; 3054 } else { 3055 ivideo->detectedpdca = 0xff; 3056 } 3057 } 3058 if(ivideo->SiS_Pr.PDC == -1) { 3059 if(ivideo->detectedpdc != 0xff) { 3060 ivideo->SiS_Pr.PDC = ivideo->detectedpdc; 3061 } 3062 } 3063 if(ivideo->SiS_Pr.PDCA == -1) { 3064 if(ivideo->detectedpdca != 0xff) { 3065 ivideo->SiS_Pr.PDCA = ivideo->detectedpdca; 3066 } 3067 } 3068 if(ivideo->detectedpdc != 0xff) { 3069 printk(KERN_INFO 3070 "sisfb: Detected LCD PDC 0x%02x (for LCD=CRT2)\n", 3071 ivideo->detectedpdc); 3072 } 3073 if(ivideo->detectedpdca != 0xff) { 3074 printk(KERN_INFO 3075 "sisfb: Detected LCD PDC1 0x%02x (for LCD=CRT1)\n", 3076 ivideo->detectedpdca); 3077 } 3078 } 3079 3080 /* Save EMI */ 3081 if(ivideo->vbflags2 & VB2_SISEMIBRIDGE) { 3082 ivideo->SiS_Pr.EMI_30 = SiS_GetReg(SISPART4, 0x30); 3083 ivideo->SiS_Pr.EMI_31 = SiS_GetReg(SISPART4, 0x31); 3084 ivideo->SiS_Pr.EMI_32 = SiS_GetReg(SISPART4, 0x32); 3085 ivideo->SiS_Pr.EMI_33 = SiS_GetReg(SISPART4, 0x33); 3086 ivideo->SiS_Pr.HaveEMI = true; 3087 if((tmp & 0x20) || (ivideo->detectedlcda != 0xff)) { 3088 ivideo->SiS_Pr.HaveEMILCD = true; 3089 } 3090 } 3091 } 3092 3093 /* Let user override detected PDCs (all bridges) */ 3094 if(ivideo->vbflags2 & VB2_30xBLV) { 3095 if((ivideo->SiS_Pr.PDC != -1) && 3096 (ivideo->SiS_Pr.PDC != ivideo->detectedpdc)) { 3097 printk(KERN_INFO "sisfb: Using LCD PDC 0x%02x (for LCD=CRT2)\n", 3098 ivideo->SiS_Pr.PDC); 3099 } 3100 if((ivideo->SiS_Pr.PDCA != -1) && 3101 (ivideo->SiS_Pr.PDCA != ivideo->detectedpdca)) { 3102 printk(KERN_INFO "sisfb: Using LCD PDC1 0x%02x (for LCD=CRT1)\n", 3103 ivideo->SiS_Pr.PDCA); 3104 } 3105 } 3106 3107 } 3108 #endif 3109 } 3110 3111 /* -------------------- Memory manager routines ---------------------- */ 3112 3113 static u32 sisfb_getheapstart(struct sis_video_info *ivideo) 3114 { 3115 u32 ret = ivideo->sisfb_parm_mem * 1024; 3116 u32 maxoffs = ivideo->video_size - ivideo->hwcursor_size - ivideo->cmdQueueSize; 3117 u32 def; 3118 3119 /* Calculate heap start = end of memory for console 3120 * 3121 * CCCCCCCCDDDDDDDDDDDDDDDDDDDDDDDDDDDDHHHHQQQQQQQQQQ 3122 * C = console, D = heap, H = HWCursor, Q = cmd-queue 3123 * 3124 * On 76x in UMA+LFB mode, the layout is as follows: 3125 * DDDDDDDDDDDCCCCCCCCCCCCCCCCCCCCCCCCHHHHQQQQQQQQQQQ 3126 * where the heap is the entire UMA area, eventually 3127 * into the LFB area if the given mem parameter is 3128 * higher than the size of the UMA memory. 3129 * 3130 * Basically given by "mem" parameter 3131 * 3132 * maximum = videosize - cmd_queue - hwcursor 3133 * (results in a heap of size 0) 3134 * default = SiS 300: depends on videosize 3135 * SiS 315/330/340/XGI: 32k below max 3136 */ 3137 3138 if(ivideo->sisvga_engine == SIS_300_VGA) { 3139 if(ivideo->video_size > 0x1000000) { 3140 def = 0xc00000; 3141 } else if(ivideo->video_size > 0x800000) { 3142 def = 0x800000; 3143 } else { 3144 def = 0x400000; 3145 } 3146 } else if(ivideo->UMAsize && ivideo->LFBsize) { 3147 ret = def = 0; 3148 } else { 3149 def = maxoffs - 0x8000; 3150 } 3151 3152 /* Use default for secondary card for now (FIXME) */ 3153 if((!ret) || (ret > maxoffs) || (ivideo->cardnumber != 0)) 3154 ret = def; 3155 3156 return ret; 3157 } 3158 3159 static u32 sisfb_getheapsize(struct sis_video_info *ivideo) 3160 { 3161 u32 max = ivideo->video_size - ivideo->hwcursor_size - ivideo->cmdQueueSize; 3162 u32 ret = 0; 3163 3164 if(ivideo->UMAsize && ivideo->LFBsize) { 3165 if( (!ivideo->sisfb_parm_mem) || 3166 ((ivideo->sisfb_parm_mem * 1024) > max) || 3167 ((max - (ivideo->sisfb_parm_mem * 1024)) < ivideo->UMAsize) ) { 3168 ret = ivideo->UMAsize; 3169 max -= ivideo->UMAsize; 3170 } else { 3171 ret = max - (ivideo->sisfb_parm_mem * 1024); 3172 max = ivideo->sisfb_parm_mem * 1024; 3173 } 3174 ivideo->video_offset = ret; 3175 ivideo->sisfb_mem = max; 3176 } else { 3177 ret = max - ivideo->heapstart; 3178 ivideo->sisfb_mem = ivideo->heapstart; 3179 } 3180 3181 return ret; 3182 } 3183 3184 static int sisfb_heap_init(struct sis_video_info *ivideo) 3185 { 3186 struct SIS_OH *poh; 3187 3188 ivideo->video_offset = 0; 3189 if(ivideo->sisfb_parm_mem) { 3190 if( (ivideo->sisfb_parm_mem < (2 * 1024 * 1024)) || 3191 (ivideo->sisfb_parm_mem > ivideo->video_size) ) { 3192 ivideo->sisfb_parm_mem = 0; 3193 } 3194 } 3195 3196 ivideo->heapstart = sisfb_getheapstart(ivideo); 3197 ivideo->sisfb_heap_size = sisfb_getheapsize(ivideo); 3198 3199 ivideo->sisfb_heap_start = ivideo->video_vbase + ivideo->heapstart; 3200 ivideo->sisfb_heap_end = ivideo->sisfb_heap_start + ivideo->sisfb_heap_size; 3201 3202 printk(KERN_INFO "sisfb: Memory heap starting at %dK, size %dK\n", 3203 (int)(ivideo->heapstart / 1024), (int)(ivideo->sisfb_heap_size / 1024)); 3204 3205 ivideo->sisfb_heap.vinfo = ivideo; 3206 3207 ivideo->sisfb_heap.poha_chain = NULL; 3208 ivideo->sisfb_heap.poh_freelist = NULL; 3209 3210 poh = sisfb_poh_new_node(&ivideo->sisfb_heap); 3211 if(poh == NULL) 3212 return 1; 3213 3214 poh->poh_next = &ivideo->sisfb_heap.oh_free; 3215 poh->poh_prev = &ivideo->sisfb_heap.oh_free; 3216 poh->size = ivideo->sisfb_heap_size; 3217 poh->offset = ivideo->heapstart; 3218 3219 ivideo->sisfb_heap.oh_free.poh_next = poh; 3220 ivideo->sisfb_heap.oh_free.poh_prev = poh; 3221 ivideo->sisfb_heap.oh_free.size = 0; 3222 ivideo->sisfb_heap.max_freesize = poh->size; 3223 3224 ivideo->sisfb_heap.oh_used.poh_next = &ivideo->sisfb_heap.oh_used; 3225 ivideo->sisfb_heap.oh_used.poh_prev = &ivideo->sisfb_heap.oh_used; 3226 ivideo->sisfb_heap.oh_used.size = SENTINEL; 3227 3228 if(ivideo->cardnumber == 0) { 3229 /* For the first card, make this heap the "global" one 3230 * for old DRM (which could handle only one card) 3231 */ 3232 sisfb_heap = &ivideo->sisfb_heap; 3233 } 3234 3235 return 0; 3236 } 3237 3238 static struct SIS_OH * 3239 sisfb_poh_new_node(struct SIS_HEAP *memheap) 3240 { 3241 struct SIS_OHALLOC *poha; 3242 struct SIS_OH *poh; 3243 unsigned long cOhs; 3244 int i; 3245 3246 if(memheap->poh_freelist == NULL) { 3247 poha = kmalloc(SIS_OH_ALLOC_SIZE, GFP_KERNEL); 3248 if(!poha) 3249 return NULL; 3250 3251 poha->poha_next = memheap->poha_chain; 3252 memheap->poha_chain = poha; 3253 3254 cOhs = (SIS_OH_ALLOC_SIZE - sizeof(struct SIS_OHALLOC)) / sizeof(struct SIS_OH) + 1; 3255 3256 poh = &poha->aoh[0]; 3257 for(i = cOhs - 1; i != 0; i--) { 3258 poh->poh_next = poh + 1; 3259 poh = poh + 1; 3260 } 3261 3262 poh->poh_next = NULL; 3263 memheap->poh_freelist = &poha->aoh[0]; 3264 } 3265 3266 poh = memheap->poh_freelist; 3267 memheap->poh_freelist = poh->poh_next; 3268 3269 return poh; 3270 } 3271 3272 static struct SIS_OH * 3273 sisfb_poh_allocate(struct SIS_HEAP *memheap, u32 size) 3274 { 3275 struct SIS_OH *pohThis; 3276 struct SIS_OH *pohRoot; 3277 int bAllocated = 0; 3278 3279 if(size > memheap->max_freesize) { 3280 DPRINTK("sisfb: Can't allocate %dk video memory\n", 3281 (unsigned int) size / 1024); 3282 return NULL; 3283 } 3284 3285 pohThis = memheap->oh_free.poh_next; 3286 3287 while(pohThis != &memheap->oh_free) { 3288 if(size <= pohThis->size) { 3289 bAllocated = 1; 3290 break; 3291 } 3292 pohThis = pohThis->poh_next; 3293 } 3294 3295 if(!bAllocated) { 3296 DPRINTK("sisfb: Can't allocate %dk video memory\n", 3297 (unsigned int) size / 1024); 3298 return NULL; 3299 } 3300 3301 if(size == pohThis->size) { 3302 pohRoot = pohThis; 3303 sisfb_delete_node(pohThis); 3304 } else { 3305 pohRoot = sisfb_poh_new_node(memheap); 3306 if(pohRoot == NULL) 3307 return NULL; 3308 3309 pohRoot->offset = pohThis->offset; 3310 pohRoot->size = size; 3311 3312 pohThis->offset += size; 3313 pohThis->size -= size; 3314 } 3315 3316 memheap->max_freesize -= size; 3317 3318 pohThis = &memheap->oh_used; 3319 sisfb_insert_node(pohThis, pohRoot); 3320 3321 return pohRoot; 3322 } 3323 3324 static void 3325 sisfb_delete_node(struct SIS_OH *poh) 3326 { 3327 poh->poh_prev->poh_next = poh->poh_next; 3328 poh->poh_next->poh_prev = poh->poh_prev; 3329 } 3330 3331 static void 3332 sisfb_insert_node(struct SIS_OH *pohList, struct SIS_OH *poh) 3333 { 3334 struct SIS_OH *pohTemp = pohList->poh_next; 3335 3336 pohList->poh_next = poh; 3337 pohTemp->poh_prev = poh; 3338 3339 poh->poh_prev = pohList; 3340 poh->poh_next = pohTemp; 3341 } 3342 3343 static struct SIS_OH * 3344 sisfb_poh_free(struct SIS_HEAP *memheap, u32 base) 3345 { 3346 struct SIS_OH *pohThis; 3347 struct SIS_OH *poh_freed; 3348 struct SIS_OH *poh_prev; 3349 struct SIS_OH *poh_next; 3350 u32 ulUpper; 3351 u32 ulLower; 3352 int foundNode = 0; 3353 3354 poh_freed = memheap->oh_used.poh_next; 3355 3356 while(poh_freed != &memheap->oh_used) { 3357 if(poh_freed->offset == base) { 3358 foundNode = 1; 3359 break; 3360 } 3361 3362 poh_freed = poh_freed->poh_next; 3363 } 3364 3365 if(!foundNode) 3366 return NULL; 3367 3368 memheap->max_freesize += poh_freed->size; 3369 3370 poh_prev = poh_next = NULL; 3371 ulUpper = poh_freed->offset + poh_freed->size; 3372 ulLower = poh_freed->offset; 3373 3374 pohThis = memheap->oh_free.poh_next; 3375 3376 while(pohThis != &memheap->oh_free) { 3377 if(pohThis->offset == ulUpper) { 3378 poh_next = pohThis; 3379 } else if((pohThis->offset + pohThis->size) == ulLower) { 3380 poh_prev = pohThis; 3381 } 3382 pohThis = pohThis->poh_next; 3383 } 3384 3385 sisfb_delete_node(poh_freed); 3386 3387 if(poh_prev && poh_next) { 3388 poh_prev->size += (poh_freed->size + poh_next->size); 3389 sisfb_delete_node(poh_next); 3390 sisfb_free_node(memheap, poh_freed); 3391 sisfb_free_node(memheap, poh_next); 3392 return poh_prev; 3393 } 3394 3395 if(poh_prev) { 3396 poh_prev->size += poh_freed->size; 3397 sisfb_free_node(memheap, poh_freed); 3398 return poh_prev; 3399 } 3400 3401 if(poh_next) { 3402 poh_next->size += poh_freed->size; 3403 poh_next->offset = poh_freed->offset; 3404 sisfb_free_node(memheap, poh_freed); 3405 return poh_next; 3406 } 3407 3408 sisfb_insert_node(&memheap->oh_free, poh_freed); 3409 3410 return poh_freed; 3411 } 3412 3413 static void 3414 sisfb_free_node(struct SIS_HEAP *memheap, struct SIS_OH *poh) 3415 { 3416 if(poh == NULL) 3417 return; 3418 3419 poh->poh_next = memheap->poh_freelist; 3420 memheap->poh_freelist = poh; 3421 } 3422 3423 static void 3424 sis_int_malloc(struct sis_video_info *ivideo, struct sis_memreq *req) 3425 { 3426 struct SIS_OH *poh = NULL; 3427 3428 if((ivideo) && (ivideo->sisfb_id == SISFB_ID) && (!ivideo->havenoheap)) 3429 poh = sisfb_poh_allocate(&ivideo->sisfb_heap, (u32)req->size); 3430 3431 if(poh == NULL) { 3432 req->offset = req->size = 0; 3433 DPRINTK("sisfb: Video RAM allocation failed\n"); 3434 } else { 3435 req->offset = poh->offset; 3436 req->size = poh->size; 3437 DPRINTK("sisfb: Video RAM allocation succeeded: 0x%lx\n", 3438 (poh->offset + ivideo->video_vbase)); 3439 } 3440 } 3441 3442 void 3443 sis_malloc(struct sis_memreq *req) 3444 { 3445 struct sis_video_info *ivideo = sisfb_heap->vinfo; 3446 3447 if(&ivideo->sisfb_heap == sisfb_heap) 3448 sis_int_malloc(ivideo, req); 3449 else 3450 req->offset = req->size = 0; 3451 } 3452 3453 void 3454 sis_malloc_new(struct pci_dev *pdev, struct sis_memreq *req) 3455 { 3456 struct sis_video_info *ivideo = pci_get_drvdata(pdev); 3457 3458 sis_int_malloc(ivideo, req); 3459 } 3460 3461 /* sis_free: u32 because "base" is offset inside video ram, can never be >4GB */ 3462 3463 static void 3464 sis_int_free(struct sis_video_info *ivideo, u32 base) 3465 { 3466 struct SIS_OH *poh; 3467 3468 if((!ivideo) || (ivideo->sisfb_id != SISFB_ID) || (ivideo->havenoheap)) 3469 return; 3470 3471 poh = sisfb_poh_free(&ivideo->sisfb_heap, base); 3472 3473 if(poh == NULL) { 3474 DPRINTK("sisfb: sisfb_poh_free() failed at base 0x%x\n", 3475 (unsigned int) base); 3476 } 3477 } 3478 3479 void 3480 sis_free(u32 base) 3481 { 3482 struct sis_video_info *ivideo = sisfb_heap->vinfo; 3483 3484 sis_int_free(ivideo, base); 3485 } 3486 3487 void 3488 sis_free_new(struct pci_dev *pdev, u32 base) 3489 { 3490 struct sis_video_info *ivideo = pci_get_drvdata(pdev); 3491 3492 sis_int_free(ivideo, base); 3493 } 3494 3495 /* --------------------- SetMode routines ------------------------- */ 3496 3497 static void 3498 sisfb_check_engine_and_sync(struct sis_video_info *ivideo) 3499 { 3500 u8 cr30, cr31; 3501 3502 /* Check if MMIO and engines are enabled, 3503 * and sync in case they are. Can't use 3504 * ivideo->accel here, as this might have 3505 * been changed before this is called. 3506 */ 3507 cr30 = SiS_GetReg(SISSR, IND_SIS_PCI_ADDRESS_SET); 3508 cr31 = SiS_GetReg(SISSR, IND_SIS_MODULE_ENABLE); 3509 /* MMIO and 2D/3D engine enabled? */ 3510 if((cr30 & SIS_MEM_MAP_IO_ENABLE) && (cr31 & 0x42)) { 3511 #ifdef CONFIG_FB_SIS_300 3512 if(ivideo->sisvga_engine == SIS_300_VGA) { 3513 /* Don't care about TurboQueue. It's 3514 * enough to know that the engines 3515 * are enabled 3516 */ 3517 sisfb_syncaccel(ivideo); 3518 } 3519 #endif 3520 #ifdef CONFIG_FB_SIS_315 3521 if(ivideo->sisvga_engine == SIS_315_VGA) { 3522 /* Check that any queue mode is 3523 * enabled, and that the queue 3524 * is not in the state of "reset" 3525 */ 3526 cr30 = SiS_GetReg(SISSR, 0x26); 3527 if((cr30 & 0xe0) && (!(cr30 & 0x01))) { 3528 sisfb_syncaccel(ivideo); 3529 } 3530 } 3531 #endif 3532 } 3533 } 3534 3535 static void 3536 sisfb_pre_setmode(struct sis_video_info *ivideo) 3537 { 3538 u8 cr30 = 0, cr31 = 0, cr33 = 0, cr35 = 0, cr38 = 0; 3539 int tvregnum = 0; 3540 3541 ivideo->currentvbflags &= (VB_VIDEOBRIDGE | VB_DISPTYPE_DISP2); 3542 3543 SiS_SetReg(SISSR, 0x05, 0x86); 3544 3545 cr31 = SiS_GetReg(SISCR, 0x31); 3546 cr31 &= ~0x60; 3547 cr31 |= 0x04; 3548 3549 cr33 = ivideo->rate_idx & 0x0F; 3550 3551 #ifdef CONFIG_FB_SIS_315 3552 if(ivideo->sisvga_engine == SIS_315_VGA) { 3553 if(ivideo->chip >= SIS_661) { 3554 cr38 = SiS_GetReg(SISCR, 0x38); 3555 cr38 &= ~0x07; /* Clear LCDA/DualEdge and YPbPr bits */ 3556 } else { 3557 tvregnum = 0x38; 3558 cr38 = SiS_GetReg(SISCR, tvregnum); 3559 cr38 &= ~0x3b; /* Clear LCDA/DualEdge and YPbPr bits */ 3560 } 3561 } 3562 #endif 3563 #ifdef CONFIG_FB_SIS_300 3564 if(ivideo->sisvga_engine == SIS_300_VGA) { 3565 tvregnum = 0x35; 3566 cr38 = SiS_GetReg(SISCR, tvregnum); 3567 } 3568 #endif 3569 3570 SiS_SetEnableDstn(&ivideo->SiS_Pr, false); 3571 SiS_SetEnableFstn(&ivideo->SiS_Pr, false); 3572 ivideo->curFSTN = ivideo->curDSTN = 0; 3573 3574 switch(ivideo->currentvbflags & VB_DISPTYPE_DISP2) { 3575 3576 case CRT2_TV: 3577 cr38 &= ~0xc0; /* Clear PAL-M / PAL-N bits */ 3578 if((ivideo->vbflags & TV_YPBPR) && (ivideo->vbflags2 & VB2_SISYPBPRBRIDGE)) { 3579 #ifdef CONFIG_FB_SIS_315 3580 if(ivideo->chip >= SIS_661) { 3581 cr38 |= 0x04; 3582 if(ivideo->vbflags & TV_YPBPR525P) cr35 |= 0x20; 3583 else if(ivideo->vbflags & TV_YPBPR750P) cr35 |= 0x40; 3584 else if(ivideo->vbflags & TV_YPBPR1080I) cr35 |= 0x60; 3585 cr30 |= SIS_SIMULTANEOUS_VIEW_ENABLE; 3586 cr35 &= ~0x01; 3587 ivideo->currentvbflags |= (TV_YPBPR | (ivideo->vbflags & TV_YPBPRALL)); 3588 } else if(ivideo->sisvga_engine == SIS_315_VGA) { 3589 cr30 |= (0x80 | SIS_SIMULTANEOUS_VIEW_ENABLE); 3590 cr38 |= 0x08; 3591 if(ivideo->vbflags & TV_YPBPR525P) cr38 |= 0x10; 3592 else if(ivideo->vbflags & TV_YPBPR750P) cr38 |= 0x20; 3593 else if(ivideo->vbflags & TV_YPBPR1080I) cr38 |= 0x30; 3594 cr31 &= ~0x01; 3595 ivideo->currentvbflags |= (TV_YPBPR | (ivideo->vbflags & TV_YPBPRALL)); 3596 } 3597 #endif 3598 } else if((ivideo->vbflags & TV_HIVISION) && 3599 (ivideo->vbflags2 & VB2_SISHIVISIONBRIDGE)) { 3600 if(ivideo->chip >= SIS_661) { 3601 cr38 |= 0x04; 3602 cr35 |= 0x60; 3603 } else { 3604 cr30 |= 0x80; 3605 } 3606 cr30 |= SIS_SIMULTANEOUS_VIEW_ENABLE; 3607 cr31 |= 0x01; 3608 cr35 |= 0x01; 3609 ivideo->currentvbflags |= TV_HIVISION; 3610 } else if(ivideo->vbflags & TV_SCART) { 3611 cr30 = (SIS_VB_OUTPUT_SCART | SIS_SIMULTANEOUS_VIEW_ENABLE); 3612 cr31 |= 0x01; 3613 cr35 |= 0x01; 3614 ivideo->currentvbflags |= TV_SCART; 3615 } else { 3616 if(ivideo->vbflags & TV_SVIDEO) { 3617 cr30 = (SIS_VB_OUTPUT_SVIDEO | SIS_SIMULTANEOUS_VIEW_ENABLE); 3618 ivideo->currentvbflags |= TV_SVIDEO; 3619 } 3620 if(ivideo->vbflags & TV_AVIDEO) { 3621 cr30 = (SIS_VB_OUTPUT_COMPOSITE | SIS_SIMULTANEOUS_VIEW_ENABLE); 3622 ivideo->currentvbflags |= TV_AVIDEO; 3623 } 3624 } 3625 cr31 |= SIS_DRIVER_MODE; 3626 3627 if(ivideo->vbflags & (TV_AVIDEO | TV_SVIDEO)) { 3628 if(ivideo->vbflags & TV_PAL) { 3629 cr31 |= 0x01; cr35 |= 0x01; 3630 ivideo->currentvbflags |= TV_PAL; 3631 if(ivideo->vbflags & TV_PALM) { 3632 cr38 |= 0x40; cr35 |= 0x04; 3633 ivideo->currentvbflags |= TV_PALM; 3634 } else if(ivideo->vbflags & TV_PALN) { 3635 cr38 |= 0x80; cr35 |= 0x08; 3636 ivideo->currentvbflags |= TV_PALN; 3637 } 3638 } else { 3639 cr31 &= ~0x01; cr35 &= ~0x01; 3640 ivideo->currentvbflags |= TV_NTSC; 3641 if(ivideo->vbflags & TV_NTSCJ) { 3642 cr38 |= 0x40; cr35 |= 0x02; 3643 ivideo->currentvbflags |= TV_NTSCJ; 3644 } 3645 } 3646 } 3647 break; 3648 3649 case CRT2_LCD: 3650 cr30 = (SIS_VB_OUTPUT_LCD | SIS_SIMULTANEOUS_VIEW_ENABLE); 3651 cr31 |= SIS_DRIVER_MODE; 3652 SiS_SetEnableDstn(&ivideo->SiS_Pr, ivideo->sisfb_dstn); 3653 SiS_SetEnableFstn(&ivideo->SiS_Pr, ivideo->sisfb_fstn); 3654 ivideo->curFSTN = ivideo->sisfb_fstn; 3655 ivideo->curDSTN = ivideo->sisfb_dstn; 3656 break; 3657 3658 case CRT2_VGA: 3659 cr30 = (SIS_VB_OUTPUT_CRT2 | SIS_SIMULTANEOUS_VIEW_ENABLE); 3660 cr31 |= SIS_DRIVER_MODE; 3661 if(ivideo->sisfb_nocrt2rate) { 3662 cr33 |= (sisbios_mode[ivideo->sisfb_mode_idx].rate_idx << 4); 3663 } else { 3664 cr33 |= ((ivideo->rate_idx & 0x0F) << 4); 3665 } 3666 break; 3667 3668 default: /* disable CRT2 */ 3669 cr30 = 0x00; 3670 cr31 |= (SIS_DRIVER_MODE | SIS_VB_OUTPUT_DISABLE); 3671 } 3672 3673 SiS_SetReg(SISCR, 0x30, cr30); 3674 SiS_SetReg(SISCR, 0x33, cr33); 3675 3676 if(ivideo->chip >= SIS_661) { 3677 #ifdef CONFIG_FB_SIS_315 3678 cr31 &= ~0x01; /* Clear PAL flag (now in CR35) */ 3679 SiS_SetRegANDOR(SISCR, 0x35, ~0x10, cr35); /* Leave overscan bit alone */ 3680 cr38 &= 0x07; /* Use only LCDA and HiVision/YPbPr bits */ 3681 SiS_SetRegANDOR(SISCR, 0x38, 0xf8, cr38); 3682 #endif 3683 } else if(ivideo->chip != SIS_300) { 3684 SiS_SetReg(SISCR, tvregnum, cr38); 3685 } 3686 SiS_SetReg(SISCR, 0x31, cr31); 3687 3688 ivideo->SiS_Pr.SiS_UseOEM = ivideo->sisfb_useoem; 3689 3690 sisfb_check_engine_and_sync(ivideo); 3691 } 3692 3693 /* Fix SR11 for 661 and later */ 3694 #ifdef CONFIG_FB_SIS_315 3695 static void 3696 sisfb_fixup_SR11(struct sis_video_info *ivideo) 3697 { 3698 u8 tmpreg; 3699 3700 if(ivideo->chip >= SIS_661) { 3701 tmpreg = SiS_GetReg(SISSR, 0x11); 3702 if(tmpreg & 0x20) { 3703 tmpreg = SiS_GetReg(SISSR, 0x3e); 3704 tmpreg = (tmpreg + 1) & 0xff; 3705 SiS_SetReg(SISSR, 0x3e, tmpreg); 3706 tmpreg = SiS_GetReg(SISSR, 0x11); 3707 } 3708 if(tmpreg & 0xf0) { 3709 SiS_SetRegAND(SISSR, 0x11, 0x0f); 3710 } 3711 } 3712 } 3713 #endif 3714 3715 static void 3716 sisfb_set_TVxposoffset(struct sis_video_info *ivideo, int val) 3717 { 3718 if(val > 32) val = 32; 3719 if(val < -32) val = -32; 3720 ivideo->tvxpos = val; 3721 3722 if(ivideo->sisfblocked) return; 3723 if(!ivideo->modechanged) return; 3724 3725 if(ivideo->currentvbflags & CRT2_TV) { 3726 3727 if(ivideo->vbflags2 & VB2_CHRONTEL) { 3728 3729 int x = ivideo->tvx; 3730 3731 switch(ivideo->chronteltype) { 3732 case 1: 3733 x += val; 3734 if(x < 0) x = 0; 3735 SiS_SetReg(SISSR, 0x05, 0x86); 3736 SiS_SetCH700x(&ivideo->SiS_Pr, 0x0a, (x & 0xff)); 3737 SiS_SetCH70xxANDOR(&ivideo->SiS_Pr, 0x08, ((x & 0x0100) >> 7), 0xFD); 3738 break; 3739 case 2: 3740 /* Not supported by hardware */ 3741 break; 3742 } 3743 3744 } else if(ivideo->vbflags2 & VB2_SISBRIDGE) { 3745 3746 u8 p2_1f,p2_20,p2_2b,p2_42,p2_43; 3747 unsigned short temp; 3748 3749 p2_1f = ivideo->p2_1f; 3750 p2_20 = ivideo->p2_20; 3751 p2_2b = ivideo->p2_2b; 3752 p2_42 = ivideo->p2_42; 3753 p2_43 = ivideo->p2_43; 3754 3755 temp = p2_1f | ((p2_20 & 0xf0) << 4); 3756 temp += (val * 2); 3757 p2_1f = temp & 0xff; 3758 p2_20 = (temp & 0xf00) >> 4; 3759 p2_2b = ((p2_2b & 0x0f) + (val * 2)) & 0x0f; 3760 temp = p2_43 | ((p2_42 & 0xf0) << 4); 3761 temp += (val * 2); 3762 p2_43 = temp & 0xff; 3763 p2_42 = (temp & 0xf00) >> 4; 3764 SiS_SetReg(SISPART2, 0x1f, p2_1f); 3765 SiS_SetRegANDOR(SISPART2, 0x20, 0x0F, p2_20); 3766 SiS_SetRegANDOR(SISPART2, 0x2b, 0xF0, p2_2b); 3767 SiS_SetRegANDOR(SISPART2, 0x42, 0x0F, p2_42); 3768 SiS_SetReg(SISPART2, 0x43, p2_43); 3769 } 3770 } 3771 } 3772 3773 static void 3774 sisfb_set_TVyposoffset(struct sis_video_info *ivideo, int val) 3775 { 3776 if(val > 32) val = 32; 3777 if(val < -32) val = -32; 3778 ivideo->tvypos = val; 3779 3780 if(ivideo->sisfblocked) return; 3781 if(!ivideo->modechanged) return; 3782 3783 if(ivideo->currentvbflags & CRT2_TV) { 3784 3785 if(ivideo->vbflags2 & VB2_CHRONTEL) { 3786 3787 int y = ivideo->tvy; 3788 3789 switch(ivideo->chronteltype) { 3790 case 1: 3791 y -= val; 3792 if(y < 0) y = 0; 3793 SiS_SetReg(SISSR, 0x05, 0x86); 3794 SiS_SetCH700x(&ivideo->SiS_Pr, 0x0b, (y & 0xff)); 3795 SiS_SetCH70xxANDOR(&ivideo->SiS_Pr, 0x08, ((y & 0x0100) >> 8), 0xFE); 3796 break; 3797 case 2: 3798 /* Not supported by hardware */ 3799 break; 3800 } 3801 3802 } else if(ivideo->vbflags2 & VB2_SISBRIDGE) { 3803 3804 char p2_01, p2_02; 3805 val /= 2; 3806 p2_01 = ivideo->p2_01; 3807 p2_02 = ivideo->p2_02; 3808 3809 p2_01 += val; 3810 p2_02 += val; 3811 if(!(ivideo->currentvbflags & (TV_HIVISION | TV_YPBPR))) { 3812 while((p2_01 <= 0) || (p2_02 <= 0)) { 3813 p2_01 += 2; 3814 p2_02 += 2; 3815 } 3816 } 3817 SiS_SetReg(SISPART2, 0x01, p2_01); 3818 SiS_SetReg(SISPART2, 0x02, p2_02); 3819 } 3820 } 3821 } 3822 3823 static void 3824 sisfb_post_setmode(struct sis_video_info *ivideo) 3825 { 3826 bool crt1isoff = false; 3827 bool doit = true; 3828 #if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315) 3829 u8 reg; 3830 #endif 3831 #ifdef CONFIG_FB_SIS_315 3832 u8 reg1; 3833 #endif 3834 3835 SiS_SetReg(SISSR, 0x05, 0x86); 3836 3837 #ifdef CONFIG_FB_SIS_315 3838 sisfb_fixup_SR11(ivideo); 3839 #endif 3840 3841 /* Now we actually HAVE changed the display mode */ 3842 ivideo->modechanged = 1; 3843 3844 /* We can't switch off CRT1 if bridge is in slave mode */ 3845 if(ivideo->vbflags2 & VB2_VIDEOBRIDGE) { 3846 if(sisfb_bridgeisslave(ivideo)) doit = false; 3847 } else 3848 ivideo->sisfb_crt1off = 0; 3849 3850 #ifdef CONFIG_FB_SIS_300 3851 if(ivideo->sisvga_engine == SIS_300_VGA) { 3852 if((ivideo->sisfb_crt1off) && (doit)) { 3853 crt1isoff = true; 3854 reg = 0x00; 3855 } else { 3856 crt1isoff = false; 3857 reg = 0x80; 3858 } 3859 SiS_SetRegANDOR(SISCR, 0x17, 0x7f, reg); 3860 } 3861 #endif 3862 #ifdef CONFIG_FB_SIS_315 3863 if(ivideo->sisvga_engine == SIS_315_VGA) { 3864 if((ivideo->sisfb_crt1off) && (doit)) { 3865 crt1isoff = true; 3866 reg = 0x40; 3867 reg1 = 0xc0; 3868 } else { 3869 crt1isoff = false; 3870 reg = 0x00; 3871 reg1 = 0x00; 3872 } 3873 SiS_SetRegANDOR(SISCR, ivideo->SiS_Pr.SiS_MyCR63, ~0x40, reg); 3874 SiS_SetRegANDOR(SISSR, 0x1f, 0x3f, reg1); 3875 } 3876 #endif 3877 3878 if(crt1isoff) { 3879 ivideo->currentvbflags &= ~VB_DISPTYPE_CRT1; 3880 ivideo->currentvbflags |= VB_SINGLE_MODE; 3881 } else { 3882 ivideo->currentvbflags |= VB_DISPTYPE_CRT1; 3883 if(ivideo->currentvbflags & VB_DISPTYPE_CRT2) { 3884 ivideo->currentvbflags |= VB_MIRROR_MODE; 3885 } else { 3886 ivideo->currentvbflags |= VB_SINGLE_MODE; 3887 } 3888 } 3889 3890 SiS_SetRegAND(SISSR, IND_SIS_RAMDAC_CONTROL, ~0x04); 3891 3892 if(ivideo->currentvbflags & CRT2_TV) { 3893 if(ivideo->vbflags2 & VB2_SISBRIDGE) { 3894 ivideo->p2_1f = SiS_GetReg(SISPART2, 0x1f); 3895 ivideo->p2_20 = SiS_GetReg(SISPART2, 0x20); 3896 ivideo->p2_2b = SiS_GetReg(SISPART2, 0x2b); 3897 ivideo->p2_42 = SiS_GetReg(SISPART2, 0x42); 3898 ivideo->p2_43 = SiS_GetReg(SISPART2, 0x43); 3899 ivideo->p2_01 = SiS_GetReg(SISPART2, 0x01); 3900 ivideo->p2_02 = SiS_GetReg(SISPART2, 0x02); 3901 } else if(ivideo->vbflags2 & VB2_CHRONTEL) { 3902 if(ivideo->chronteltype == 1) { 3903 ivideo->tvx = SiS_GetCH700x(&ivideo->SiS_Pr, 0x0a); 3904 ivideo->tvx |= (((SiS_GetCH700x(&ivideo->SiS_Pr, 0x08) & 0x02) >> 1) << 8); 3905 ivideo->tvy = SiS_GetCH700x(&ivideo->SiS_Pr, 0x0b); 3906 ivideo->tvy |= ((SiS_GetCH700x(&ivideo->SiS_Pr, 0x08) & 0x01) << 8); 3907 } 3908 } 3909 } 3910 3911 if(ivideo->tvxpos) { 3912 sisfb_set_TVxposoffset(ivideo, ivideo->tvxpos); 3913 } 3914 if(ivideo->tvypos) { 3915 sisfb_set_TVyposoffset(ivideo, ivideo->tvypos); 3916 } 3917 3918 /* Eventually sync engines */ 3919 sisfb_check_engine_and_sync(ivideo); 3920 3921 /* (Re-)Initialize chip engines */ 3922 if(ivideo->accel) { 3923 sisfb_engine_init(ivideo); 3924 } else { 3925 ivideo->engineok = 0; 3926 } 3927 } 3928 3929 static int 3930 sisfb_reset_mode(struct sis_video_info *ivideo) 3931 { 3932 if(sisfb_set_mode(ivideo, 0)) 3933 return 1; 3934 3935 sisfb_set_pitch(ivideo); 3936 sisfb_set_base_CRT1(ivideo, ivideo->current_base); 3937 sisfb_set_base_CRT2(ivideo, ivideo->current_base); 3938 3939 return 0; 3940 } 3941 3942 static void 3943 sisfb_handle_command(struct sis_video_info *ivideo, struct sisfb_cmd *sisfb_command) 3944 { 3945 int mycrt1off; 3946 3947 switch(sisfb_command->sisfb_cmd) { 3948 case SISFB_CMD_GETVBFLAGS: 3949 if(!ivideo->modechanged) { 3950 sisfb_command->sisfb_result[0] = SISFB_CMD_ERR_EARLY; 3951 } else { 3952 sisfb_command->sisfb_result[0] = SISFB_CMD_ERR_OK; 3953 sisfb_command->sisfb_result[1] = ivideo->currentvbflags; 3954 sisfb_command->sisfb_result[2] = ivideo->vbflags2; 3955 } 3956 break; 3957 case SISFB_CMD_SWITCHCRT1: 3958 /* arg[0]: 0 = off, 1 = on, 99 = query */ 3959 if(!ivideo->modechanged) { 3960 sisfb_command->sisfb_result[0] = SISFB_CMD_ERR_EARLY; 3961 } else if(sisfb_command->sisfb_arg[0] == 99) { 3962 /* Query */ 3963 sisfb_command->sisfb_result[1] = ivideo->sisfb_crt1off ? 0 : 1; 3964 sisfb_command->sisfb_result[0] = SISFB_CMD_ERR_OK; 3965 } else if(ivideo->sisfblocked) { 3966 sisfb_command->sisfb_result[0] = SISFB_CMD_ERR_LOCKED; 3967 } else if((!(ivideo->currentvbflags & CRT2_ENABLE)) && 3968 (sisfb_command->sisfb_arg[0] == 0)) { 3969 sisfb_command->sisfb_result[0] = SISFB_CMD_ERR_NOCRT2; 3970 } else { 3971 sisfb_command->sisfb_result[0] = SISFB_CMD_ERR_OK; 3972 mycrt1off = sisfb_command->sisfb_arg[0] ? 0 : 1; 3973 if( ((ivideo->currentvbflags & VB_DISPTYPE_CRT1) && mycrt1off) || 3974 ((!(ivideo->currentvbflags & VB_DISPTYPE_CRT1)) && !mycrt1off) ) { 3975 ivideo->sisfb_crt1off = mycrt1off; 3976 if(sisfb_reset_mode(ivideo)) { 3977 sisfb_command->sisfb_result[0] = SISFB_CMD_ERR_OTHER; 3978 } 3979 } 3980 sisfb_command->sisfb_result[1] = ivideo->sisfb_crt1off ? 0 : 1; 3981 } 3982 break; 3983 /* more to come */ 3984 default: 3985 sisfb_command->sisfb_result[0] = SISFB_CMD_ERR_UNKNOWN; 3986 printk(KERN_ERR "sisfb: Unknown command 0x%x\n", 3987 sisfb_command->sisfb_cmd); 3988 } 3989 } 3990 3991 #ifndef MODULE 3992 static int __init sisfb_setup(char *options) 3993 { 3994 char *this_opt; 3995 3996 sisfb_setdefaultparms(); 3997 3998 if(!options || !(*options)) 3999 return 0; 4000 4001 while((this_opt = strsep(&options, ",")) != NULL) { 4002 4003 if(!(*this_opt)) continue; 4004 4005 if(!strncasecmp(this_opt, "off", 3)) { 4006 sisfb_off = 1; 4007 } else if(!strncasecmp(this_opt, "forcecrt2type:", 14)) { 4008 /* Need to check crt2 type first for fstn/dstn */ 4009 sisfb_search_crt2type(this_opt + 14); 4010 } else if(!strncasecmp(this_opt, "tvmode:",7)) { 4011 sisfb_search_tvstd(this_opt + 7); 4012 } else if(!strncasecmp(this_opt, "tvstandard:",11)) { 4013 sisfb_search_tvstd(this_opt + 11); 4014 } else if(!strncasecmp(this_opt, "mode:", 5)) { 4015 sisfb_search_mode(this_opt + 5, false); 4016 } else if(!strncasecmp(this_opt, "vesa:", 5)) { 4017 sisfb_search_vesamode(simple_strtoul(this_opt + 5, NULL, 0), false); 4018 } else if(!strncasecmp(this_opt, "rate:", 5)) { 4019 sisfb_parm_rate = simple_strtoul(this_opt + 5, NULL, 0); 4020 } else if(!strncasecmp(this_opt, "forcecrt1:", 10)) { 4021 sisfb_forcecrt1 = (int)simple_strtoul(this_opt + 10, NULL, 0); 4022 } else if(!strncasecmp(this_opt, "mem:",4)) { 4023 sisfb_parm_mem = simple_strtoul(this_opt + 4, NULL, 0); 4024 } else if(!strncasecmp(this_opt, "pdc:", 4)) { 4025 sisfb_pdc = simple_strtoul(this_opt + 4, NULL, 0); 4026 } else if(!strncasecmp(this_opt, "pdc1:", 5)) { 4027 sisfb_pdca = simple_strtoul(this_opt + 5, NULL, 0); 4028 } else if(!strncasecmp(this_opt, "noaccel", 7)) { 4029 sisfb_accel = 0; 4030 } else if(!strncasecmp(this_opt, "accel", 5)) { 4031 sisfb_accel = -1; 4032 } else if(!strncasecmp(this_opt, "noypan", 6)) { 4033 sisfb_ypan = 0; 4034 } else if(!strncasecmp(this_opt, "ypan", 4)) { 4035 sisfb_ypan = -1; 4036 } else if(!strncasecmp(this_opt, "nomax", 5)) { 4037 sisfb_max = 0; 4038 } else if(!strncasecmp(this_opt, "max", 3)) { 4039 sisfb_max = -1; 4040 } else if(!strncasecmp(this_opt, "userom:", 7)) { 4041 sisfb_userom = (int)simple_strtoul(this_opt + 7, NULL, 0); 4042 } else if(!strncasecmp(this_opt, "useoem:", 7)) { 4043 sisfb_useoem = (int)simple_strtoul(this_opt + 7, NULL, 0); 4044 } else if(!strncasecmp(this_opt, "nocrt2rate", 10)) { 4045 sisfb_nocrt2rate = 1; 4046 } else if(!strncasecmp(this_opt, "scalelcd:", 9)) { 4047 unsigned long temp = 2; 4048 temp = simple_strtoul(this_opt + 9, NULL, 0); 4049 if((temp == 0) || (temp == 1)) { 4050 sisfb_scalelcd = temp ^ 1; 4051 } 4052 } else if(!strncasecmp(this_opt, "tvxposoffset:", 13)) { 4053 int temp = 0; 4054 temp = (int)simple_strtol(this_opt + 13, NULL, 0); 4055 if((temp >= -32) && (temp <= 32)) { 4056 sisfb_tvxposoffset = temp; 4057 } 4058 } else if(!strncasecmp(this_opt, "tvyposoffset:", 13)) { 4059 int temp = 0; 4060 temp = (int)simple_strtol(this_opt + 13, NULL, 0); 4061 if((temp >= -32) && (temp <= 32)) { 4062 sisfb_tvyposoffset = temp; 4063 } 4064 } else if(!strncasecmp(this_opt, "specialtiming:", 14)) { 4065 sisfb_search_specialtiming(this_opt + 14); 4066 } else if(!strncasecmp(this_opt, "lvdshl:", 7)) { 4067 int temp = 4; 4068 temp = simple_strtoul(this_opt + 7, NULL, 0); 4069 if((temp >= 0) && (temp <= 3)) { 4070 sisfb_lvdshl = temp; 4071 } 4072 } else if(this_opt[0] >= '0' && this_opt[0] <= '9') { 4073 sisfb_search_mode(this_opt, true); 4074 #if !defined(__i386__) && !defined(__x86_64__) 4075 } else if(!strncasecmp(this_opt, "resetcard", 9)) { 4076 sisfb_resetcard = 1; 4077 } else if(!strncasecmp(this_opt, "videoram:", 9)) { 4078 sisfb_videoram = simple_strtoul(this_opt + 9, NULL, 0); 4079 #endif 4080 } else { 4081 printk(KERN_INFO "sisfb: Invalid option %s\n", this_opt); 4082 } 4083 4084 } 4085 4086 return 0; 4087 } 4088 #endif 4089 4090 static int sisfb_check_rom(void __iomem *rom_base, 4091 struct sis_video_info *ivideo) 4092 { 4093 void __iomem *rom; 4094 int romptr; 4095 4096 if((readb(rom_base) != 0x55) || (readb(rom_base + 1) != 0xaa)) 4097 return 0; 4098 4099 romptr = (readb(rom_base + 0x18) | (readb(rom_base + 0x19) << 8)); 4100 if(romptr > (0x10000 - 8)) 4101 return 0; 4102 4103 rom = rom_base + romptr; 4104 4105 if((readb(rom) != 'P') || (readb(rom + 1) != 'C') || 4106 (readb(rom + 2) != 'I') || (readb(rom + 3) != 'R')) 4107 return 0; 4108 4109 if((readb(rom + 4) | (readb(rom + 5) << 8)) != ivideo->chip_vendor) 4110 return 0; 4111 4112 if((readb(rom + 6) | (readb(rom + 7) << 8)) != ivideo->chip_id) 4113 return 0; 4114 4115 return 1; 4116 } 4117 4118 static unsigned char *sisfb_find_rom(struct pci_dev *pdev) 4119 { 4120 struct sis_video_info *ivideo = pci_get_drvdata(pdev); 4121 void __iomem *rom_base; 4122 unsigned char *myrombase = NULL; 4123 size_t romsize; 4124 4125 /* First, try the official pci ROM functions (except 4126 * on integrated chipsets which have no ROM). 4127 */ 4128 4129 if(!ivideo->nbridge) { 4130 4131 if((rom_base = pci_map_rom(pdev, &romsize))) { 4132 4133 if(sisfb_check_rom(rom_base, ivideo)) { 4134 4135 if((myrombase = vmalloc(65536))) { 4136 memcpy_fromio(myrombase, rom_base, 4137 (romsize > 65536) ? 65536 : romsize); 4138 } 4139 } 4140 pci_unmap_rom(pdev, rom_base); 4141 } 4142 } 4143 4144 if(myrombase) return myrombase; 4145 4146 /* Otherwise do it the conventional way. */ 4147 4148 #if defined(__i386__) || defined(__x86_64__) 4149 { 4150 u32 temp; 4151 4152 for (temp = 0x000c0000; temp < 0x000f0000; temp += 0x00001000) { 4153 4154 rom_base = ioremap(temp, 65536); 4155 if (!rom_base) 4156 continue; 4157 4158 if (!sisfb_check_rom(rom_base, ivideo)) { 4159 iounmap(rom_base); 4160 continue; 4161 } 4162 4163 if ((myrombase = vmalloc(65536))) 4164 memcpy_fromio(myrombase, rom_base, 65536); 4165 4166 iounmap(rom_base); 4167 break; 4168 4169 } 4170 4171 } 4172 #endif 4173 4174 return myrombase; 4175 } 4176 4177 static void sisfb_post_map_vram(struct sis_video_info *ivideo, 4178 unsigned int *mapsize, unsigned int min) 4179 { 4180 if (*mapsize < (min << 20)) 4181 return; 4182 4183 ivideo->video_vbase = ioremap_wc(ivideo->video_base, (*mapsize)); 4184 4185 if(!ivideo->video_vbase) { 4186 printk(KERN_ERR 4187 "sisfb: Unable to map maximum video RAM for size detection\n"); 4188 (*mapsize) >>= 1; 4189 while((!(ivideo->video_vbase = ioremap_wc(ivideo->video_base, (*mapsize))))) { 4190 (*mapsize) >>= 1; 4191 if((*mapsize) < (min << 20)) 4192 break; 4193 } 4194 if(ivideo->video_vbase) { 4195 printk(KERN_ERR 4196 "sisfb: Video RAM size detection limited to %dMB\n", 4197 (int)((*mapsize) >> 20)); 4198 } 4199 } 4200 } 4201 4202 #ifdef CONFIG_FB_SIS_300 4203 static int sisfb_post_300_buswidth(struct sis_video_info *ivideo) 4204 { 4205 void __iomem *FBAddress = ivideo->video_vbase; 4206 unsigned short temp; 4207 unsigned char reg; 4208 int i, j; 4209 4210 SiS_SetRegAND(SISSR, 0x15, 0xFB); 4211 SiS_SetRegOR(SISSR, 0x15, 0x04); 4212 SiS_SetReg(SISSR, 0x13, 0x00); 4213 SiS_SetReg(SISSR, 0x14, 0xBF); 4214 4215 for(i = 0; i < 2; i++) { 4216 temp = 0x1234; 4217 for(j = 0; j < 4; j++) { 4218 writew(temp, FBAddress); 4219 if(readw(FBAddress) == temp) 4220 break; 4221 SiS_SetRegOR(SISSR, 0x3c, 0x01); 4222 reg = SiS_GetReg(SISSR, 0x05); 4223 reg = SiS_GetReg(SISSR, 0x05); 4224 SiS_SetRegAND(SISSR, 0x3c, 0xfe); 4225 reg = SiS_GetReg(SISSR, 0x05); 4226 reg = SiS_GetReg(SISSR, 0x05); 4227 temp++; 4228 } 4229 } 4230 4231 writel(0x01234567L, FBAddress); 4232 writel(0x456789ABL, (FBAddress + 4)); 4233 writel(0x89ABCDEFL, (FBAddress + 8)); 4234 writel(0xCDEF0123L, (FBAddress + 12)); 4235 4236 reg = SiS_GetReg(SISSR, 0x3b); 4237 if(reg & 0x01) { 4238 if(readl((FBAddress + 12)) == 0xCDEF0123L) 4239 return 4; /* Channel A 128bit */ 4240 } 4241 4242 if(readl((FBAddress + 4)) == 0x456789ABL) 4243 return 2; /* Channel B 64bit */ 4244 4245 return 1; /* 32bit */ 4246 } 4247 4248 static const unsigned short SiS_DRAMType[17][5] = { 4249 {0x0C,0x0A,0x02,0x40,0x39}, 4250 {0x0D,0x0A,0x01,0x40,0x48}, 4251 {0x0C,0x09,0x02,0x20,0x35}, 4252 {0x0D,0x09,0x01,0x20,0x44}, 4253 {0x0C,0x08,0x02,0x10,0x31}, 4254 {0x0D,0x08,0x01,0x10,0x40}, 4255 {0x0C,0x0A,0x01,0x20,0x34}, 4256 {0x0C,0x09,0x01,0x08,0x32}, 4257 {0x0B,0x08,0x02,0x08,0x21}, 4258 {0x0C,0x08,0x01,0x08,0x30}, 4259 {0x0A,0x08,0x02,0x04,0x11}, 4260 {0x0B,0x0A,0x01,0x10,0x28}, 4261 {0x09,0x08,0x02,0x02,0x01}, 4262 {0x0B,0x09,0x01,0x08,0x24}, 4263 {0x0B,0x08,0x01,0x04,0x20}, 4264 {0x0A,0x08,0x01,0x02,0x10}, 4265 {0x09,0x08,0x01,0x01,0x00} 4266 }; 4267 4268 static int sisfb_post_300_rwtest(struct sis_video_info *ivideo, int iteration, 4269 int buswidth, int PseudoRankCapacity, 4270 int PseudoAdrPinCount, unsigned int mapsize) 4271 { 4272 void __iomem *FBAddr = ivideo->video_vbase; 4273 unsigned short sr14; 4274 unsigned int k, RankCapacity, PageCapacity, BankNumHigh, BankNumMid; 4275 unsigned int PhysicalAdrOtherPage, PhysicalAdrHigh, PhysicalAdrHalfPage; 4276 4277 for (k = 0; k < ARRAY_SIZE(SiS_DRAMType); k++) { 4278 RankCapacity = buswidth * SiS_DRAMType[k][3]; 4279 4280 if (RankCapacity != PseudoRankCapacity) 4281 continue; 4282 4283 if ((SiS_DRAMType[k][2] + SiS_DRAMType[k][0]) > PseudoAdrPinCount) 4284 continue; 4285 4286 BankNumHigh = RankCapacity * 16 * iteration - 1; 4287 if (iteration == 3) { /* Rank No */ 4288 BankNumMid = RankCapacity * 16 - 1; 4289 } else { 4290 BankNumMid = RankCapacity * 16 * iteration / 2 - 1; 4291 } 4292 4293 PageCapacity = (1 << SiS_DRAMType[k][1]) * buswidth * 4; 4294 PhysicalAdrHigh = BankNumHigh; 4295 PhysicalAdrHalfPage = (PageCapacity / 2 + PhysicalAdrHigh) % PageCapacity; 4296 PhysicalAdrOtherPage = PageCapacity * SiS_DRAMType[k][2] + PhysicalAdrHigh; 4297 4298 SiS_SetRegAND(SISSR, 0x15, 0xFB); /* Test */ 4299 SiS_SetRegOR(SISSR, 0x15, 0x04); /* Test */ 4300 sr14 = (SiS_DRAMType[k][3] * buswidth) - 1; 4301 4302 if (buswidth == 4) 4303 sr14 |= 0x80; 4304 else if (buswidth == 2) 4305 sr14 |= 0x40; 4306 4307 SiS_SetReg(SISSR, 0x13, SiS_DRAMType[k][4]); 4308 SiS_SetReg(SISSR, 0x14, sr14); 4309 4310 BankNumHigh <<= 16; 4311 BankNumMid <<= 16; 4312 4313 if ((BankNumHigh + PhysicalAdrHigh >= mapsize) || 4314 (BankNumMid + PhysicalAdrHigh >= mapsize) || 4315 (BankNumHigh + PhysicalAdrHalfPage >= mapsize) || 4316 (BankNumHigh + PhysicalAdrOtherPage >= mapsize)) 4317 continue; 4318 4319 /* Write data */ 4320 writew(((unsigned short)PhysicalAdrHigh), 4321 (FBAddr + BankNumHigh + PhysicalAdrHigh)); 4322 writew(((unsigned short)BankNumMid), 4323 (FBAddr + BankNumMid + PhysicalAdrHigh)); 4324 writew(((unsigned short)PhysicalAdrHalfPage), 4325 (FBAddr + BankNumHigh + PhysicalAdrHalfPage)); 4326 writew(((unsigned short)PhysicalAdrOtherPage), 4327 (FBAddr + BankNumHigh + PhysicalAdrOtherPage)); 4328 4329 /* Read data */ 4330 if (readw(FBAddr + BankNumHigh + PhysicalAdrHigh) == PhysicalAdrHigh) 4331 return 1; 4332 } 4333 4334 return 0; 4335 } 4336 4337 static void sisfb_post_300_ramsize(struct pci_dev *pdev, unsigned int mapsize) 4338 { 4339 struct sis_video_info *ivideo = pci_get_drvdata(pdev); 4340 int i, j, buswidth; 4341 int PseudoRankCapacity, PseudoAdrPinCount; 4342 4343 buswidth = sisfb_post_300_buswidth(ivideo); 4344 4345 for(i = 6; i >= 0; i--) { 4346 PseudoRankCapacity = 1 << i; 4347 for(j = 4; j >= 1; j--) { 4348 PseudoAdrPinCount = 15 - j; 4349 if((PseudoRankCapacity * j) <= 64) { 4350 if(sisfb_post_300_rwtest(ivideo, 4351 j, 4352 buswidth, 4353 PseudoRankCapacity, 4354 PseudoAdrPinCount, 4355 mapsize)) 4356 return; 4357 } 4358 } 4359 } 4360 } 4361 4362 static void sisfb_post_sis300(struct pci_dev *pdev) 4363 { 4364 struct sis_video_info *ivideo = pci_get_drvdata(pdev); 4365 unsigned char *bios = ivideo->SiS_Pr.VirtualRomBase; 4366 u8 reg, v1, v2, v3, v4, v5, v6, v7, v8; 4367 u16 index, rindex, memtype = 0; 4368 unsigned int mapsize; 4369 4370 if(!ivideo->SiS_Pr.UseROM) 4371 bios = NULL; 4372 4373 SiS_SetReg(SISSR, 0x05, 0x86); 4374 4375 if(bios) { 4376 if(bios[0x52] & 0x80) { 4377 memtype = bios[0x52]; 4378 } else { 4379 memtype = SiS_GetReg(SISSR, 0x3a); 4380 } 4381 memtype &= 0x07; 4382 } 4383 4384 v3 = 0x80; v6 = 0x80; 4385 if(ivideo->revision_id <= 0x13) { 4386 v1 = 0x44; v2 = 0x42; 4387 v4 = 0x44; v5 = 0x42; 4388 } else { 4389 v1 = 0x68; v2 = 0x43; /* Assume 125Mhz MCLK */ 4390 v4 = 0x68; v5 = 0x43; /* Assume 125Mhz ECLK */ 4391 if(bios) { 4392 index = memtype * 5; 4393 rindex = index + 0x54; 4394 v1 = bios[rindex++]; 4395 v2 = bios[rindex++]; 4396 v3 = bios[rindex++]; 4397 rindex = index + 0x7c; 4398 v4 = bios[rindex++]; 4399 v5 = bios[rindex++]; 4400 v6 = bios[rindex++]; 4401 } 4402 } 4403 SiS_SetReg(SISSR, 0x28, v1); 4404 SiS_SetReg(SISSR, 0x29, v2); 4405 SiS_SetReg(SISSR, 0x2a, v3); 4406 SiS_SetReg(SISSR, 0x2e, v4); 4407 SiS_SetReg(SISSR, 0x2f, v5); 4408 SiS_SetReg(SISSR, 0x30, v6); 4409 4410 v1 = 0x10; 4411 if(bios) 4412 v1 = bios[0xa4]; 4413 SiS_SetReg(SISSR, 0x07, v1); /* DAC speed */ 4414 4415 SiS_SetReg(SISSR, 0x11, 0x0f); /* DDC, power save */ 4416 4417 v1 = 0x01; v2 = 0x43; v3 = 0x1e; v4 = 0x2a; 4418 v5 = 0x06; v6 = 0x00; v7 = 0x00; v8 = 0x00; 4419 if(bios) { 4420 memtype += 0xa5; 4421 v1 = bios[memtype]; 4422 v2 = bios[memtype + 8]; 4423 v3 = bios[memtype + 16]; 4424 v4 = bios[memtype + 24]; 4425 v5 = bios[memtype + 32]; 4426 v6 = bios[memtype + 40]; 4427 v7 = bios[memtype + 48]; 4428 v8 = bios[memtype + 56]; 4429 } 4430 if(ivideo->revision_id >= 0x80) 4431 v3 &= 0xfd; 4432 SiS_SetReg(SISSR, 0x15, v1); /* Ram type (assuming 0, BIOS 0xa5 step 8) */ 4433 SiS_SetReg(SISSR, 0x16, v2); 4434 SiS_SetReg(SISSR, 0x17, v3); 4435 SiS_SetReg(SISSR, 0x18, v4); 4436 SiS_SetReg(SISSR, 0x19, v5); 4437 SiS_SetReg(SISSR, 0x1a, v6); 4438 SiS_SetReg(SISSR, 0x1b, v7); 4439 SiS_SetReg(SISSR, 0x1c, v8); /* ---- */ 4440 SiS_SetRegAND(SISSR, 0x15, 0xfb); 4441 SiS_SetRegOR(SISSR, 0x15, 0x04); 4442 if(bios) { 4443 if(bios[0x53] & 0x02) { 4444 SiS_SetRegOR(SISSR, 0x19, 0x20); 4445 } 4446 } 4447 v1 = 0x04; /* DAC pedestal (BIOS 0xe5) */ 4448 if(ivideo->revision_id >= 0x80) 4449 v1 |= 0x01; 4450 SiS_SetReg(SISSR, 0x1f, v1); 4451 SiS_SetReg(SISSR, 0x20, 0xa4); /* linear & relocated io & disable a0000 */ 4452 v1 = 0xf6; v2 = 0x0d; v3 = 0x00; 4453 if(bios) { 4454 v1 = bios[0xe8]; 4455 v2 = bios[0xe9]; 4456 v3 = bios[0xea]; 4457 } 4458 SiS_SetReg(SISSR, 0x23, v1); 4459 SiS_SetReg(SISSR, 0x24, v2); 4460 SiS_SetReg(SISSR, 0x25, v3); 4461 SiS_SetReg(SISSR, 0x21, 0x84); 4462 SiS_SetReg(SISSR, 0x22, 0x00); 4463 SiS_SetReg(SISCR, 0x37, 0x00); 4464 SiS_SetRegOR(SISPART1, 0x24, 0x01); /* unlock crt2 */ 4465 SiS_SetReg(SISPART1, 0x00, 0x00); 4466 v1 = 0x40; v2 = 0x11; 4467 if(bios) { 4468 v1 = bios[0xec]; 4469 v2 = bios[0xeb]; 4470 } 4471 SiS_SetReg(SISPART1, 0x02, v1); 4472 4473 if(ivideo->revision_id >= 0x80) 4474 v2 &= ~0x01; 4475 4476 reg = SiS_GetReg(SISPART4, 0x00); 4477 if((reg == 1) || (reg == 2)) { 4478 SiS_SetReg(SISCR, 0x37, 0x02); 4479 SiS_SetReg(SISPART2, 0x00, 0x1c); 4480 v4 = 0x00; v5 = 0x00; v6 = 0x10; 4481 if (ivideo->SiS_Pr.UseROM && bios) { 4482 v4 = bios[0xf5]; 4483 v5 = bios[0xf6]; 4484 v6 = bios[0xf7]; 4485 } 4486 SiS_SetReg(SISPART4, 0x0d, v4); 4487 SiS_SetReg(SISPART4, 0x0e, v5); 4488 SiS_SetReg(SISPART4, 0x10, v6); 4489 SiS_SetReg(SISPART4, 0x0f, 0x3f); 4490 reg = SiS_GetReg(SISPART4, 0x01); 4491 if(reg >= 0xb0) { 4492 reg = SiS_GetReg(SISPART4, 0x23); 4493 reg &= 0x20; 4494 reg <<= 1; 4495 SiS_SetReg(SISPART4, 0x23, reg); 4496 } 4497 } else { 4498 v2 &= ~0x10; 4499 } 4500 SiS_SetReg(SISSR, 0x32, v2); 4501 4502 SiS_SetRegAND(SISPART1, 0x24, 0xfe); /* Lock CRT2 */ 4503 4504 reg = SiS_GetReg(SISSR, 0x16); 4505 reg &= 0xc3; 4506 SiS_SetReg(SISCR, 0x35, reg); 4507 SiS_SetReg(SISCR, 0x83, 0x00); 4508 #if !defined(__i386__) && !defined(__x86_64__) 4509 if(sisfb_videoram) { 4510 SiS_SetReg(SISSR, 0x13, 0x28); /* ? */ 4511 reg = ((sisfb_videoram >> 10) - 1) | 0x40; 4512 SiS_SetReg(SISSR, 0x14, reg); 4513 } else { 4514 #endif 4515 /* Need to map max FB size for finding out about RAM size */ 4516 mapsize = ivideo->video_size; 4517 sisfb_post_map_vram(ivideo, &mapsize, 4); 4518 4519 if(ivideo->video_vbase) { 4520 sisfb_post_300_ramsize(pdev, mapsize); 4521 iounmap(ivideo->video_vbase); 4522 } else { 4523 printk(KERN_DEBUG 4524 "sisfb: Failed to map memory for size detection, assuming 8MB\n"); 4525 SiS_SetReg(SISSR, 0x13, 0x28); /* ? */ 4526 SiS_SetReg(SISSR, 0x14, 0x47); /* 8MB, 64bit default */ 4527 } 4528 #if !defined(__i386__) && !defined(__x86_64__) 4529 } 4530 #endif 4531 if(bios) { 4532 v1 = bios[0xe6]; 4533 v2 = bios[0xe7]; 4534 } else { 4535 reg = SiS_GetReg(SISSR, 0x3a); 4536 if((reg & 0x30) == 0x30) { 4537 v1 = 0x04; /* PCI */ 4538 v2 = 0x92; 4539 } else { 4540 v1 = 0x14; /* AGP */ 4541 v2 = 0xb2; 4542 } 4543 } 4544 SiS_SetReg(SISSR, 0x21, v1); 4545 SiS_SetReg(SISSR, 0x22, v2); 4546 4547 /* Sense CRT1 */ 4548 sisfb_sense_crt1(ivideo); 4549 4550 /* Set default mode, don't clear screen */ 4551 ivideo->SiS_Pr.SiS_UseOEM = false; 4552 SiS_SetEnableDstn(&ivideo->SiS_Pr, false); 4553 SiS_SetEnableFstn(&ivideo->SiS_Pr, false); 4554 ivideo->curFSTN = ivideo->curDSTN = 0; 4555 ivideo->SiS_Pr.VideoMemorySize = 8 << 20; 4556 SiSSetMode(&ivideo->SiS_Pr, 0x2e | 0x80); 4557 4558 SiS_SetReg(SISSR, 0x05, 0x86); 4559 4560 /* Display off */ 4561 SiS_SetRegOR(SISSR, 0x01, 0x20); 4562 4563 /* Save mode number in CR34 */ 4564 SiS_SetReg(SISCR, 0x34, 0x2e); 4565 4566 /* Let everyone know what the current mode is */ 4567 ivideo->modeprechange = 0x2e; 4568 } 4569 #endif 4570 4571 #ifdef CONFIG_FB_SIS_315 4572 #if 0 4573 static void sisfb_post_sis315330(struct pci_dev *pdev) 4574 { 4575 /* TODO */ 4576 } 4577 #endif 4578 4579 static inline int sisfb_xgi_is21(struct sis_video_info *ivideo) 4580 { 4581 return ivideo->chip_real_id == XGI_21; 4582 } 4583 4584 static void sisfb_post_xgi_delay(struct sis_video_info *ivideo, int delay) 4585 { 4586 unsigned int i; 4587 u8 reg; 4588 4589 for(i = 0; i <= (delay * 10 * 36); i++) { 4590 reg = SiS_GetReg(SISSR, 0x05); 4591 reg++; 4592 } 4593 } 4594 4595 static int sisfb_find_host_bridge(struct sis_video_info *ivideo, 4596 struct pci_dev *mypdev, 4597 unsigned short pcivendor) 4598 { 4599 struct pci_dev *pdev = NULL; 4600 unsigned short temp; 4601 int ret = 0; 4602 4603 while((pdev = pci_get_class(PCI_CLASS_BRIDGE_HOST, pdev))) { 4604 temp = pdev->vendor; 4605 if(temp == pcivendor) { 4606 ret = 1; 4607 pci_dev_put(pdev); 4608 break; 4609 } 4610 } 4611 4612 return ret; 4613 } 4614 4615 static int sisfb_post_xgi_rwtest(struct sis_video_info *ivideo, int starta, 4616 unsigned int enda, unsigned int mapsize) 4617 { 4618 unsigned int pos; 4619 int i; 4620 4621 writel(0, ivideo->video_vbase); 4622 4623 for(i = starta; i <= enda; i++) { 4624 pos = 1 << i; 4625 if(pos < mapsize) 4626 writel(pos, ivideo->video_vbase + pos); 4627 } 4628 4629 sisfb_post_xgi_delay(ivideo, 150); 4630 4631 if(readl(ivideo->video_vbase) != 0) 4632 return 0; 4633 4634 for(i = starta; i <= enda; i++) { 4635 pos = 1 << i; 4636 if(pos < mapsize) { 4637 if(readl(ivideo->video_vbase + pos) != pos) 4638 return 0; 4639 } else 4640 return 0; 4641 } 4642 4643 return 1; 4644 } 4645 4646 static int sisfb_post_xgi_ramsize(struct sis_video_info *ivideo) 4647 { 4648 unsigned int buswidth, ranksize, channelab, mapsize; 4649 int i, j, k, l, status; 4650 u8 reg, sr14; 4651 static const u8 dramsr13[12 * 5] = { 4652 0x02, 0x0e, 0x0b, 0x80, 0x5d, 4653 0x02, 0x0e, 0x0a, 0x40, 0x59, 4654 0x02, 0x0d, 0x0b, 0x40, 0x4d, 4655 0x02, 0x0e, 0x09, 0x20, 0x55, 4656 0x02, 0x0d, 0x0a, 0x20, 0x49, 4657 0x02, 0x0c, 0x0b, 0x20, 0x3d, 4658 0x02, 0x0e, 0x08, 0x10, 0x51, 4659 0x02, 0x0d, 0x09, 0x10, 0x45, 4660 0x02, 0x0c, 0x0a, 0x10, 0x39, 4661 0x02, 0x0d, 0x08, 0x08, 0x41, 4662 0x02, 0x0c, 0x09, 0x08, 0x35, 4663 0x02, 0x0c, 0x08, 0x04, 0x31 4664 }; 4665 static const u8 dramsr13_4[4 * 5] = { 4666 0x02, 0x0d, 0x09, 0x40, 0x45, 4667 0x02, 0x0c, 0x09, 0x20, 0x35, 4668 0x02, 0x0c, 0x08, 0x10, 0x31, 4669 0x02, 0x0b, 0x08, 0x08, 0x21 4670 }; 4671 4672 /* Enable linear mode, disable 0xa0000 address decoding */ 4673 /* We disable a0000 address decoding, because 4674 * - if running on x86, if the card is disabled, it means 4675 * that another card is in the system. We don't want 4676 * to interphere with that primary card's textmode. 4677 * - if running on non-x86, there usually is no VGA window 4678 * at a0000. 4679 */ 4680 SiS_SetRegOR(SISSR, 0x20, (0x80 | 0x04)); 4681 4682 /* Need to map max FB size for finding out about RAM size */ 4683 mapsize = ivideo->video_size; 4684 sisfb_post_map_vram(ivideo, &mapsize, 32); 4685 4686 if(!ivideo->video_vbase) { 4687 printk(KERN_ERR "sisfb: Unable to detect RAM size. Setting default.\n"); 4688 SiS_SetReg(SISSR, 0x13, 0x35); 4689 SiS_SetReg(SISSR, 0x14, 0x41); 4690 /* TODO */ 4691 return -ENOMEM; 4692 } 4693 4694 /* Non-interleaving */ 4695 SiS_SetReg(SISSR, 0x15, 0x00); 4696 /* No tiling */ 4697 SiS_SetReg(SISSR, 0x1c, 0x00); 4698 4699 if(ivideo->chip == XGI_20) { 4700 4701 channelab = 1; 4702 reg = SiS_GetReg(SISCR, 0x97); 4703 if(!(reg & 0x01)) { /* Single 32/16 */ 4704 buswidth = 32; 4705 SiS_SetReg(SISSR, 0x13, 0xb1); 4706 SiS_SetReg(SISSR, 0x14, 0x52); 4707 sisfb_post_xgi_delay(ivideo, 1); 4708 sr14 = 0x02; 4709 if(sisfb_post_xgi_rwtest(ivideo, 23, 24, mapsize)) 4710 goto bail_out; 4711 4712 SiS_SetReg(SISSR, 0x13, 0x31); 4713 SiS_SetReg(SISSR, 0x14, 0x42); 4714 sisfb_post_xgi_delay(ivideo, 1); 4715 if(sisfb_post_xgi_rwtest(ivideo, 23, 23, mapsize)) 4716 goto bail_out; 4717 4718 buswidth = 16; 4719 SiS_SetReg(SISSR, 0x13, 0xb1); 4720 SiS_SetReg(SISSR, 0x14, 0x41); 4721 sisfb_post_xgi_delay(ivideo, 1); 4722 sr14 = 0x01; 4723 if(sisfb_post_xgi_rwtest(ivideo, 22, 23, mapsize)) 4724 goto bail_out; 4725 else 4726 SiS_SetReg(SISSR, 0x13, 0x31); 4727 } else { /* Dual 16/8 */ 4728 buswidth = 16; 4729 SiS_SetReg(SISSR, 0x13, 0xb1); 4730 SiS_SetReg(SISSR, 0x14, 0x41); 4731 sisfb_post_xgi_delay(ivideo, 1); 4732 sr14 = 0x01; 4733 if(sisfb_post_xgi_rwtest(ivideo, 22, 23, mapsize)) 4734 goto bail_out; 4735 4736 SiS_SetReg(SISSR, 0x13, 0x31); 4737 SiS_SetReg(SISSR, 0x14, 0x31); 4738 sisfb_post_xgi_delay(ivideo, 1); 4739 if(sisfb_post_xgi_rwtest(ivideo, 22, 22, mapsize)) 4740 goto bail_out; 4741 4742 buswidth = 8; 4743 SiS_SetReg(SISSR, 0x13, 0xb1); 4744 SiS_SetReg(SISSR, 0x14, 0x30); 4745 sisfb_post_xgi_delay(ivideo, 1); 4746 sr14 = 0x00; 4747 if(sisfb_post_xgi_rwtest(ivideo, 21, 22, mapsize)) 4748 goto bail_out; 4749 else 4750 SiS_SetReg(SISSR, 0x13, 0x31); 4751 } 4752 4753 } else { /* XGI_40 */ 4754 4755 reg = SiS_GetReg(SISCR, 0x97); 4756 if(!(reg & 0x10)) { 4757 reg = SiS_GetReg(SISSR, 0x39); 4758 reg >>= 1; 4759 } 4760 4761 if(reg & 0x01) { /* DDRII */ 4762 buswidth = 32; 4763 if(ivideo->revision_id == 2) { 4764 channelab = 2; 4765 SiS_SetReg(SISSR, 0x13, 0xa1); 4766 SiS_SetReg(SISSR, 0x14, 0x44); 4767 sr14 = 0x04; 4768 sisfb_post_xgi_delay(ivideo, 1); 4769 if(sisfb_post_xgi_rwtest(ivideo, 23, 24, mapsize)) 4770 goto bail_out; 4771 4772 SiS_SetReg(SISSR, 0x13, 0x21); 4773 SiS_SetReg(SISSR, 0x14, 0x34); 4774 if(sisfb_post_xgi_rwtest(ivideo, 22, 23, mapsize)) 4775 goto bail_out; 4776 4777 channelab = 1; 4778 SiS_SetReg(SISSR, 0x13, 0xa1); 4779 SiS_SetReg(SISSR, 0x14, 0x40); 4780 sr14 = 0x00; 4781 if(sisfb_post_xgi_rwtest(ivideo, 22, 23, mapsize)) 4782 goto bail_out; 4783 4784 SiS_SetReg(SISSR, 0x13, 0x21); 4785 SiS_SetReg(SISSR, 0x14, 0x30); 4786 } else { 4787 channelab = 3; 4788 SiS_SetReg(SISSR, 0x13, 0xa1); 4789 SiS_SetReg(SISSR, 0x14, 0x4c); 4790 sr14 = 0x0c; 4791 sisfb_post_xgi_delay(ivideo, 1); 4792 if(sisfb_post_xgi_rwtest(ivideo, 23, 25, mapsize)) 4793 goto bail_out; 4794 4795 channelab = 2; 4796 SiS_SetReg(SISSR, 0x14, 0x48); 4797 sisfb_post_xgi_delay(ivideo, 1); 4798 sr14 = 0x08; 4799 if(sisfb_post_xgi_rwtest(ivideo, 23, 24, mapsize)) 4800 goto bail_out; 4801 4802 SiS_SetReg(SISSR, 0x13, 0x21); 4803 SiS_SetReg(SISSR, 0x14, 0x3c); 4804 sr14 = 0x0c; 4805 4806 if(sisfb_post_xgi_rwtest(ivideo, 23, 24, mapsize)) { 4807 channelab = 3; 4808 } else { 4809 channelab = 2; 4810 SiS_SetReg(SISSR, 0x14, 0x38); 4811 sr14 = 0x08; 4812 } 4813 } 4814 sisfb_post_xgi_delay(ivideo, 1); 4815 4816 } else { /* DDR */ 4817 4818 buswidth = 64; 4819 if(ivideo->revision_id == 2) { 4820 channelab = 1; 4821 SiS_SetReg(SISSR, 0x13, 0xa1); 4822 SiS_SetReg(SISSR, 0x14, 0x52); 4823 sisfb_post_xgi_delay(ivideo, 1); 4824 sr14 = 0x02; 4825 if(sisfb_post_xgi_rwtest(ivideo, 23, 24, mapsize)) 4826 goto bail_out; 4827 4828 SiS_SetReg(SISSR, 0x13, 0x21); 4829 SiS_SetReg(SISSR, 0x14, 0x42); 4830 } else { 4831 channelab = 2; 4832 SiS_SetReg(SISSR, 0x13, 0xa1); 4833 SiS_SetReg(SISSR, 0x14, 0x5a); 4834 sisfb_post_xgi_delay(ivideo, 1); 4835 sr14 = 0x0a; 4836 if(sisfb_post_xgi_rwtest(ivideo, 24, 25, mapsize)) 4837 goto bail_out; 4838 4839 SiS_SetReg(SISSR, 0x13, 0x21); 4840 SiS_SetReg(SISSR, 0x14, 0x4a); 4841 } 4842 sisfb_post_xgi_delay(ivideo, 1); 4843 4844 } 4845 } 4846 4847 bail_out: 4848 SiS_SetRegANDOR(SISSR, 0x14, 0xf0, sr14); 4849 sisfb_post_xgi_delay(ivideo, 1); 4850 4851 j = (ivideo->chip == XGI_20) ? 5 : 9; 4852 k = (ivideo->chip == XGI_20) ? 12 : 4; 4853 status = -EIO; 4854 4855 for(i = 0; i < k; i++) { 4856 4857 reg = (ivideo->chip == XGI_20) ? 4858 dramsr13[(i * 5) + 4] : dramsr13_4[(i * 5) + 4]; 4859 SiS_SetRegANDOR(SISSR, 0x13, 0x80, reg); 4860 sisfb_post_xgi_delay(ivideo, 50); 4861 4862 ranksize = (ivideo->chip == XGI_20) ? 4863 dramsr13[(i * 5) + 3] : dramsr13_4[(i * 5) + 3]; 4864 4865 reg = SiS_GetReg(SISSR, 0x13); 4866 if(reg & 0x80) ranksize <<= 1; 4867 4868 if(ivideo->chip == XGI_20) { 4869 if(buswidth == 16) ranksize <<= 1; 4870 else if(buswidth == 32) ranksize <<= 2; 4871 } else { 4872 if(buswidth == 64) ranksize <<= 1; 4873 } 4874 4875 reg = 0; 4876 l = channelab; 4877 if(l == 3) l = 4; 4878 if((ranksize * l) <= 256) { 4879 while((ranksize >>= 1)) reg += 0x10; 4880 } 4881 4882 if(!reg) continue; 4883 4884 SiS_SetRegANDOR(SISSR, 0x14, 0x0f, (reg & 0xf0)); 4885 sisfb_post_xgi_delay(ivideo, 1); 4886 4887 if (sisfb_post_xgi_rwtest(ivideo, j, ((reg >> 4) + channelab - 2 + 20), mapsize)) { 4888 status = 0; 4889 break; 4890 } 4891 } 4892 4893 iounmap(ivideo->video_vbase); 4894 4895 return status; 4896 } 4897 4898 static void sisfb_post_xgi_setclocks(struct sis_video_info *ivideo, u8 regb) 4899 { 4900 u8 v1, v2, v3; 4901 int index; 4902 static const u8 cs90[8 * 3] = { 4903 0x16, 0x01, 0x01, 4904 0x3e, 0x03, 0x01, 4905 0x7c, 0x08, 0x01, 4906 0x79, 0x06, 0x01, 4907 0x29, 0x01, 0x81, 4908 0x5c, 0x23, 0x01, 4909 0x5c, 0x23, 0x01, 4910 0x5c, 0x23, 0x01 4911 }; 4912 static const u8 csb8[8 * 3] = { 4913 0x5c, 0x23, 0x01, 4914 0x29, 0x01, 0x01, 4915 0x7c, 0x08, 0x01, 4916 0x79, 0x06, 0x01, 4917 0x29, 0x01, 0x81, 4918 0x5c, 0x23, 0x01, 4919 0x5c, 0x23, 0x01, 4920 0x5c, 0x23, 0x01 4921 }; 4922 4923 regb = 0; /* ! */ 4924 4925 index = regb * 3; 4926 v1 = cs90[index]; v2 = cs90[index + 1]; v3 = cs90[index + 2]; 4927 if(ivideo->haveXGIROM) { 4928 v1 = ivideo->bios_abase[0x90 + index]; 4929 v2 = ivideo->bios_abase[0x90 + index + 1]; 4930 v3 = ivideo->bios_abase[0x90 + index + 2]; 4931 } 4932 SiS_SetReg(SISSR, 0x28, v1); 4933 SiS_SetReg(SISSR, 0x29, v2); 4934 SiS_SetReg(SISSR, 0x2a, v3); 4935 sisfb_post_xgi_delay(ivideo, 0x43); 4936 sisfb_post_xgi_delay(ivideo, 0x43); 4937 sisfb_post_xgi_delay(ivideo, 0x43); 4938 index = regb * 3; 4939 v1 = csb8[index]; v2 = csb8[index + 1]; v3 = csb8[index + 2]; 4940 if(ivideo->haveXGIROM) { 4941 v1 = ivideo->bios_abase[0xb8 + index]; 4942 v2 = ivideo->bios_abase[0xb8 + index + 1]; 4943 v3 = ivideo->bios_abase[0xb8 + index + 2]; 4944 } 4945 SiS_SetReg(SISSR, 0x2e, v1); 4946 SiS_SetReg(SISSR, 0x2f, v2); 4947 SiS_SetReg(SISSR, 0x30, v3); 4948 sisfb_post_xgi_delay(ivideo, 0x43); 4949 sisfb_post_xgi_delay(ivideo, 0x43); 4950 sisfb_post_xgi_delay(ivideo, 0x43); 4951 } 4952 4953 static void sisfb_post_xgi_ddr2_mrs_default(struct sis_video_info *ivideo, 4954 u8 regb) 4955 { 4956 unsigned char *bios = ivideo->bios_abase; 4957 u8 v1; 4958 4959 SiS_SetReg(SISSR, 0x28, 0x64); 4960 SiS_SetReg(SISSR, 0x29, 0x63); 4961 sisfb_post_xgi_delay(ivideo, 15); 4962 SiS_SetReg(SISSR, 0x18, 0x00); 4963 SiS_SetReg(SISSR, 0x19, 0x20); 4964 SiS_SetReg(SISSR, 0x16, 0x00); 4965 SiS_SetReg(SISSR, 0x16, 0x80); 4966 SiS_SetReg(SISSR, 0x18, 0xc5); 4967 SiS_SetReg(SISSR, 0x19, 0x23); 4968 SiS_SetReg(SISSR, 0x16, 0x00); 4969 SiS_SetReg(SISSR, 0x16, 0x80); 4970 sisfb_post_xgi_delay(ivideo, 1); 4971 SiS_SetReg(SISCR, 0x97, 0x11); 4972 sisfb_post_xgi_setclocks(ivideo, regb); 4973 sisfb_post_xgi_delay(ivideo, 0x46); 4974 SiS_SetReg(SISSR, 0x18, 0xc5); 4975 SiS_SetReg(SISSR, 0x19, 0x23); 4976 SiS_SetReg(SISSR, 0x16, 0x00); 4977 SiS_SetReg(SISSR, 0x16, 0x80); 4978 sisfb_post_xgi_delay(ivideo, 1); 4979 SiS_SetReg(SISSR, 0x1b, 0x04); 4980 sisfb_post_xgi_delay(ivideo, 1); 4981 SiS_SetReg(SISSR, 0x1b, 0x00); 4982 sisfb_post_xgi_delay(ivideo, 1); 4983 v1 = 0x31; 4984 if (ivideo->haveXGIROM) { 4985 v1 = bios[0xf0]; 4986 } 4987 SiS_SetReg(SISSR, 0x18, v1); 4988 SiS_SetReg(SISSR, 0x19, 0x06); 4989 SiS_SetReg(SISSR, 0x16, 0x04); 4990 SiS_SetReg(SISSR, 0x16, 0x84); 4991 sisfb_post_xgi_delay(ivideo, 1); 4992 } 4993 4994 static void sisfb_post_xgi_ddr2_mrs_xg21(struct sis_video_info *ivideo) 4995 { 4996 sisfb_post_xgi_setclocks(ivideo, 1); 4997 4998 SiS_SetReg(SISCR, 0x97, 0x11); 4999 sisfb_post_xgi_delay(ivideo, 0x46); 5000 5001 SiS_SetReg(SISSR, 0x18, 0x00); /* EMRS2 */ 5002 SiS_SetReg(SISSR, 0x19, 0x80); 5003 SiS_SetReg(SISSR, 0x16, 0x05); 5004 SiS_SetReg(SISSR, 0x16, 0x85); 5005 5006 SiS_SetReg(SISSR, 0x18, 0x00); /* EMRS3 */ 5007 SiS_SetReg(SISSR, 0x19, 0xc0); 5008 SiS_SetReg(SISSR, 0x16, 0x05); 5009 SiS_SetReg(SISSR, 0x16, 0x85); 5010 5011 SiS_SetReg(SISSR, 0x18, 0x00); /* EMRS1 */ 5012 SiS_SetReg(SISSR, 0x19, 0x40); 5013 SiS_SetReg(SISSR, 0x16, 0x05); 5014 SiS_SetReg(SISSR, 0x16, 0x85); 5015 5016 SiS_SetReg(SISSR, 0x18, 0x42); /* MRS1 */ 5017 SiS_SetReg(SISSR, 0x19, 0x02); 5018 SiS_SetReg(SISSR, 0x16, 0x05); 5019 SiS_SetReg(SISSR, 0x16, 0x85); 5020 sisfb_post_xgi_delay(ivideo, 1); 5021 5022 SiS_SetReg(SISSR, 0x1b, 0x04); 5023 sisfb_post_xgi_delay(ivideo, 1); 5024 5025 SiS_SetReg(SISSR, 0x1b, 0x00); 5026 sisfb_post_xgi_delay(ivideo, 1); 5027 5028 SiS_SetReg(SISSR, 0x18, 0x42); /* MRS1 */ 5029 SiS_SetReg(SISSR, 0x19, 0x00); 5030 SiS_SetReg(SISSR, 0x16, 0x05); 5031 SiS_SetReg(SISSR, 0x16, 0x85); 5032 sisfb_post_xgi_delay(ivideo, 1); 5033 } 5034 5035 static void sisfb_post_xgi_ddr2(struct sis_video_info *ivideo, u8 regb) 5036 { 5037 unsigned char *bios = ivideo->bios_abase; 5038 static const u8 cs158[8] = { 5039 0x88, 0xaa, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00 5040 }; 5041 static const u8 cs160[8] = { 5042 0x44, 0x77, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00 5043 }; 5044 static const u8 cs168[8] = { 5045 0x48, 0x78, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00 5046 }; 5047 u8 v1; 5048 u8 v2; 5049 u8 v3; 5050 5051 SiS_SetReg(SISCR, 0xb0, 0x80); /* DDR2 dual frequency mode */ 5052 SiS_SetReg(SISCR, 0x82, 0x77); 5053 SiS_SetReg(SISCR, 0x86, 0x00); 5054 SiS_GetReg(SISCR, 0x86); 5055 SiS_SetReg(SISCR, 0x86, 0x88); 5056 SiS_GetReg(SISCR, 0x86); 5057 v1 = cs168[regb]; v2 = cs160[regb]; v3 = cs158[regb]; 5058 if (ivideo->haveXGIROM) { 5059 v1 = bios[regb + 0x168]; 5060 v2 = bios[regb + 0x160]; 5061 v3 = bios[regb + 0x158]; 5062 } 5063 SiS_SetReg(SISCR, 0x86, v1); 5064 SiS_SetReg(SISCR, 0x82, 0x77); 5065 SiS_SetReg(SISCR, 0x85, 0x00); 5066 SiS_GetReg(SISCR, 0x85); 5067 SiS_SetReg(SISCR, 0x85, 0x88); 5068 SiS_GetReg(SISCR, 0x85); 5069 SiS_SetReg(SISCR, 0x85, v2); 5070 SiS_SetReg(SISCR, 0x82, v3); 5071 SiS_SetReg(SISCR, 0x98, 0x01); 5072 SiS_SetReg(SISCR, 0x9a, 0x02); 5073 if (sisfb_xgi_is21(ivideo)) 5074 sisfb_post_xgi_ddr2_mrs_xg21(ivideo); 5075 else 5076 sisfb_post_xgi_ddr2_mrs_default(ivideo, regb); 5077 } 5078 5079 static u8 sisfb_post_xgi_ramtype(struct sis_video_info *ivideo) 5080 { 5081 unsigned char *bios = ivideo->bios_abase; 5082 u8 ramtype; 5083 u8 reg; 5084 u8 v1; 5085 5086 ramtype = 0x00; v1 = 0x10; 5087 if (ivideo->haveXGIROM) { 5088 ramtype = bios[0x62]; 5089 v1 = bios[0x1d2]; 5090 } 5091 if (!(ramtype & 0x80)) { 5092 if (sisfb_xgi_is21(ivideo)) { 5093 SiS_SetRegAND(SISCR, 0xb4, 0xfd); /* GPIO control */ 5094 SiS_SetRegOR(SISCR, 0x4a, 0x80); /* GPIOH EN */ 5095 reg = SiS_GetReg(SISCR, 0x48); 5096 SiS_SetRegOR(SISCR, 0xb4, 0x02); 5097 ramtype = reg & 0x01; /* GPIOH */ 5098 } else if (ivideo->chip == XGI_20) { 5099 SiS_SetReg(SISCR, 0x97, v1); 5100 reg = SiS_GetReg(SISCR, 0x97); 5101 if (reg & 0x10) { 5102 ramtype = (reg & 0x01) << 1; 5103 } 5104 } else { 5105 reg = SiS_GetReg(SISSR, 0x39); 5106 ramtype = reg & 0x02; 5107 if (!(ramtype)) { 5108 reg = SiS_GetReg(SISSR, 0x3a); 5109 ramtype = (reg >> 1) & 0x01; 5110 } 5111 } 5112 } 5113 ramtype &= 0x07; 5114 5115 return ramtype; 5116 } 5117 5118 static int sisfb_post_xgi(struct pci_dev *pdev) 5119 { 5120 struct sis_video_info *ivideo = pci_get_drvdata(pdev); 5121 unsigned char *bios = ivideo->bios_abase; 5122 struct pci_dev *mypdev = NULL; 5123 const u8 *ptr, *ptr2; 5124 u8 v1, v2, v3, v4, v5, reg, ramtype; 5125 u32 rega, regb, regd; 5126 int i, j, k, index; 5127 static const u8 cs78[3] = { 0xf6, 0x0d, 0x00 }; 5128 static const u8 cs76[2] = { 0xa3, 0xfb }; 5129 static const u8 cs7b[3] = { 0xc0, 0x11, 0x00 }; 5130 static const u8 cs158[8] = { 5131 0x88, 0xaa, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00 5132 }; 5133 static const u8 cs160[8] = { 5134 0x44, 0x77, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00 5135 }; 5136 static const u8 cs168[8] = { 5137 0x48, 0x78, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00 5138 }; 5139 static const u8 cs128[3 * 8] = { 5140 0x90, 0x28, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 5141 0x77, 0x44, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 5142 0x77, 0x44, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00 5143 }; 5144 static const u8 cs148[2 * 8] = { 5145 0x55, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 5146 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 5147 }; 5148 static const u8 cs31a[8 * 4] = { 5149 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 5150 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 5151 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 5152 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 5153 }; 5154 static const u8 cs33a[8 * 4] = { 5155 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 5156 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 5157 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 5158 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 5159 }; 5160 static const u8 cs45a[8 * 2] = { 5161 0x00, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0x00, 0x00, 5162 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 5163 }; 5164 static const u8 cs170[7 * 8] = { 5165 0x54, 0x32, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 5166 0x54, 0x43, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 5167 0x0a, 0x05, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 5168 0x44, 0x34, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 5169 0x10, 0x0a, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 5170 0x11, 0x0c, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 5171 0x05, 0x05, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00 5172 }; 5173 static const u8 cs1a8[3 * 8] = { 5174 0xf0, 0xf0, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 5175 0x05, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 5176 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 5177 }; 5178 static const u8 cs100[2 * 8] = { 5179 0xc4, 0x04, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 5180 0xc4, 0x04, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00 5181 }; 5182 5183 /* VGA enable */ 5184 reg = SiS_GetRegByte(SISVGAENABLE) | 0x01; 5185 SiS_SetRegByte(SISVGAENABLE, reg); 5186 5187 /* Misc */ 5188 reg = SiS_GetRegByte(SISMISCR) | 0x01; 5189 SiS_SetRegByte(SISMISCW, reg); 5190 5191 /* Unlock SR */ 5192 SiS_SetReg(SISSR, 0x05, 0x86); 5193 reg = SiS_GetReg(SISSR, 0x05); 5194 if(reg != 0xa1) 5195 return 0; 5196 5197 /* Clear some regs */ 5198 for(i = 0; i < 0x22; i++) { 5199 if(0x06 + i == 0x20) continue; 5200 SiS_SetReg(SISSR, 0x06 + i, 0x00); 5201 } 5202 for(i = 0; i < 0x0b; i++) { 5203 SiS_SetReg(SISSR, 0x31 + i, 0x00); 5204 } 5205 for(i = 0; i < 0x10; i++) { 5206 SiS_SetReg(SISCR, 0x30 + i, 0x00); 5207 } 5208 5209 ptr = cs78; 5210 if(ivideo->haveXGIROM) { 5211 ptr = (const u8 *)&bios[0x78]; 5212 } 5213 for(i = 0; i < 3; i++) { 5214 SiS_SetReg(SISSR, 0x23 + i, ptr[i]); 5215 } 5216 5217 ptr = cs76; 5218 if(ivideo->haveXGIROM) { 5219 ptr = (const u8 *)&bios[0x76]; 5220 } 5221 for(i = 0; i < 2; i++) { 5222 SiS_SetReg(SISSR, 0x21 + i, ptr[i]); 5223 } 5224 5225 v1 = 0x18; v2 = 0x00; 5226 if(ivideo->haveXGIROM) { 5227 v1 = bios[0x74]; 5228 v2 = bios[0x75]; 5229 } 5230 SiS_SetReg(SISSR, 0x07, v1); 5231 SiS_SetReg(SISSR, 0x11, 0x0f); 5232 SiS_SetReg(SISSR, 0x1f, v2); 5233 /* PCI linear mode, RelIO enabled, A0000 decoding disabled */ 5234 SiS_SetReg(SISSR, 0x20, 0x80 | 0x20 | 0x04); 5235 SiS_SetReg(SISSR, 0x27, 0x74); 5236 5237 ptr = cs7b; 5238 if(ivideo->haveXGIROM) { 5239 ptr = (const u8 *)&bios[0x7b]; 5240 } 5241 for(i = 0; i < 3; i++) { 5242 SiS_SetReg(SISSR, 0x31 + i, ptr[i]); 5243 } 5244 5245 if(ivideo->chip == XGI_40) { 5246 if(ivideo->revision_id == 2) { 5247 SiS_SetRegANDOR(SISSR, 0x3b, 0x3f, 0xc0); 5248 } 5249 SiS_SetReg(SISCR, 0x7d, 0xfe); 5250 SiS_SetReg(SISCR, 0x7e, 0x0f); 5251 } 5252 if(ivideo->revision_id == 0) { /* 40 *and* 20? */ 5253 SiS_SetRegAND(SISCR, 0x58, 0xd7); 5254 reg = SiS_GetReg(SISCR, 0xcb); 5255 if(reg & 0x20) { 5256 SiS_SetRegANDOR(SISCR, 0x58, 0xd7, (reg & 0x10) ? 0x08 : 0x20); /* =0x28 Z7 ? */ 5257 } 5258 } 5259 5260 reg = (ivideo->chip == XGI_40) ? 0x20 : 0x00; 5261 SiS_SetRegANDOR(SISCR, 0x38, 0x1f, reg); 5262 5263 if(ivideo->chip == XGI_20) { 5264 SiS_SetReg(SISSR, 0x36, 0x70); 5265 } else { 5266 SiS_SetReg(SISVID, 0x00, 0x86); 5267 SiS_SetReg(SISVID, 0x32, 0x00); 5268 SiS_SetReg(SISVID, 0x30, 0x00); 5269 SiS_SetReg(SISVID, 0x32, 0x01); 5270 SiS_SetReg(SISVID, 0x30, 0x00); 5271 SiS_SetRegAND(SISVID, 0x2f, 0xdf); 5272 SiS_SetRegAND(SISCAP, 0x00, 0x3f); 5273 5274 SiS_SetReg(SISPART1, 0x2f, 0x01); 5275 SiS_SetReg(SISPART1, 0x00, 0x00); 5276 SiS_SetReg(SISPART1, 0x02, bios[0x7e]); 5277 SiS_SetReg(SISPART1, 0x2e, 0x08); 5278 SiS_SetRegAND(SISPART1, 0x35, 0x7f); 5279 SiS_SetRegAND(SISPART1, 0x50, 0xfe); 5280 5281 reg = SiS_GetReg(SISPART4, 0x00); 5282 if(reg == 1 || reg == 2) { 5283 SiS_SetReg(SISPART2, 0x00, 0x1c); 5284 SiS_SetReg(SISPART4, 0x0d, bios[0x7f]); 5285 SiS_SetReg(SISPART4, 0x0e, bios[0x80]); 5286 SiS_SetReg(SISPART4, 0x10, bios[0x81]); 5287 SiS_SetRegAND(SISPART4, 0x0f, 0x3f); 5288 5289 reg = SiS_GetReg(SISPART4, 0x01); 5290 if((reg & 0xf0) >= 0xb0) { 5291 reg = SiS_GetReg(SISPART4, 0x23); 5292 if(reg & 0x20) reg |= 0x40; 5293 SiS_SetReg(SISPART4, 0x23, reg); 5294 reg = (reg & 0x20) ? 0x02 : 0x00; 5295 SiS_SetRegANDOR(SISPART1, 0x1e, 0xfd, reg); 5296 } 5297 } 5298 5299 v1 = bios[0x77]; 5300 5301 reg = SiS_GetReg(SISSR, 0x3b); 5302 if(reg & 0x02) { 5303 reg = SiS_GetReg(SISSR, 0x3a); 5304 v2 = (reg & 0x30) >> 3; 5305 if(!(v2 & 0x04)) v2 ^= 0x02; 5306 reg = SiS_GetReg(SISSR, 0x39); 5307 if(reg & 0x80) v2 |= 0x80; 5308 v2 |= 0x01; 5309 5310 if((mypdev = pci_get_device(PCI_VENDOR_ID_SI, 0x0730, NULL))) { 5311 pci_dev_put(mypdev); 5312 if(((v2 & 0x06) == 2) || ((v2 & 0x06) == 4)) 5313 v2 &= 0xf9; 5314 v2 |= 0x08; 5315 v1 &= 0xfe; 5316 } else { 5317 mypdev = pci_get_device(PCI_VENDOR_ID_SI, 0x0735, NULL); 5318 if(!mypdev) 5319 mypdev = pci_get_device(PCI_VENDOR_ID_SI, 0x0645, NULL); 5320 if(!mypdev) 5321 mypdev = pci_get_device(PCI_VENDOR_ID_SI, 0x0650, NULL); 5322 if(mypdev) { 5323 pci_read_config_dword(mypdev, 0x94, ®d); 5324 regd &= 0xfffffeff; 5325 pci_write_config_dword(mypdev, 0x94, regd); 5326 v1 &= 0xfe; 5327 pci_dev_put(mypdev); 5328 } else if(sisfb_find_host_bridge(ivideo, pdev, PCI_VENDOR_ID_SI)) { 5329 v1 &= 0xfe; 5330 } else if(sisfb_find_host_bridge(ivideo, pdev, 0x1106) || 5331 sisfb_find_host_bridge(ivideo, pdev, 0x1022) || 5332 sisfb_find_host_bridge(ivideo, pdev, 0x700e) || 5333 sisfb_find_host_bridge(ivideo, pdev, 0x10de)) { 5334 if((v2 & 0x06) == 4) 5335 v2 ^= 0x06; 5336 v2 |= 0x08; 5337 } 5338 } 5339 SiS_SetRegANDOR(SISCR, 0x5f, 0xf0, v2); 5340 } 5341 SiS_SetReg(SISSR, 0x22, v1); 5342 5343 if(ivideo->revision_id == 2) { 5344 v1 = SiS_GetReg(SISSR, 0x3b); 5345 v2 = SiS_GetReg(SISSR, 0x3a); 5346 regd = bios[0x90 + 3] | (bios[0x90 + 4] << 8); 5347 if( (!(v1 & 0x02)) && (v2 & 0x30) && (regd < 0xcf) ) 5348 SiS_SetRegANDOR(SISCR, 0x5f, 0xf1, 0x01); 5349 5350 if((mypdev = pci_get_device(0x10de, 0x01e0, NULL))) { 5351 /* TODO: set CR5f &0xf1 | 0x01 for version 6570 5352 * of nforce 2 ROM 5353 */ 5354 if(0) 5355 SiS_SetRegANDOR(SISCR, 0x5f, 0xf1, 0x01); 5356 pci_dev_put(mypdev); 5357 } 5358 } 5359 5360 v1 = 0x30; 5361 reg = SiS_GetReg(SISSR, 0x3b); 5362 v2 = SiS_GetReg(SISCR, 0x5f); 5363 if((!(reg & 0x02)) && (v2 & 0x0e)) 5364 v1 |= 0x08; 5365 SiS_SetReg(SISSR, 0x27, v1); 5366 5367 if(bios[0x64] & 0x01) { 5368 SiS_SetRegANDOR(SISCR, 0x5f, 0xf0, bios[0x64]); 5369 } 5370 5371 v1 = bios[0x4f7]; 5372 pci_read_config_dword(pdev, 0x50, ®d); 5373 regd = (regd >> 20) & 0x0f; 5374 if(regd == 1) { 5375 v1 &= 0xfc; 5376 SiS_SetRegOR(SISCR, 0x5f, 0x08); 5377 } 5378 SiS_SetReg(SISCR, 0x48, v1); 5379 5380 SiS_SetRegANDOR(SISCR, 0x47, 0x04, bios[0x4f6] & 0xfb); 5381 SiS_SetRegANDOR(SISCR, 0x49, 0xf0, bios[0x4f8] & 0x0f); 5382 SiS_SetRegANDOR(SISCR, 0x4a, 0x60, bios[0x4f9] & 0x9f); 5383 SiS_SetRegANDOR(SISCR, 0x4b, 0x08, bios[0x4fa] & 0xf7); 5384 SiS_SetRegANDOR(SISCR, 0x4c, 0x80, bios[0x4fb] & 0x7f); 5385 SiS_SetReg(SISCR, 0x70, bios[0x4fc]); 5386 SiS_SetRegANDOR(SISCR, 0x71, 0xf0, bios[0x4fd] & 0x0f); 5387 SiS_SetReg(SISCR, 0x74, 0xd0); 5388 SiS_SetRegANDOR(SISCR, 0x74, 0xcf, bios[0x4fe] & 0x30); 5389 SiS_SetRegANDOR(SISCR, 0x75, 0xe0, bios[0x4ff] & 0x1f); 5390 SiS_SetRegANDOR(SISCR, 0x76, 0xe0, bios[0x500] & 0x1f); 5391 v1 = bios[0x501]; 5392 if((mypdev = pci_get_device(0x8086, 0x2530, NULL))) { 5393 v1 = 0xf0; 5394 pci_dev_put(mypdev); 5395 } 5396 SiS_SetReg(SISCR, 0x77, v1); 5397 } 5398 5399 /* RAM type: 5400 * 5401 * 0 == DDR1, 1 == DDR2, 2..7 == reserved? 5402 * 5403 * The code seems to written so that regb should equal ramtype, 5404 * however, so far it has been hardcoded to 0. Enable other values only 5405 * on XGI Z9, as it passes the POST, and add a warning for others. 5406 */ 5407 ramtype = sisfb_post_xgi_ramtype(ivideo); 5408 if (!sisfb_xgi_is21(ivideo) && ramtype) { 5409 dev_warn(&pdev->dev, 5410 "RAM type something else than expected: %d\n", 5411 ramtype); 5412 regb = 0; 5413 } else { 5414 regb = ramtype; 5415 } 5416 5417 v1 = 0xff; 5418 if(ivideo->haveXGIROM) { 5419 v1 = bios[0x140 + regb]; 5420 } 5421 SiS_SetReg(SISCR, 0x6d, v1); 5422 5423 ptr = cs128; 5424 if(ivideo->haveXGIROM) { 5425 ptr = (const u8 *)&bios[0x128]; 5426 } 5427 for(i = 0, j = 0; i < 3; i++, j += 8) { 5428 SiS_SetReg(SISCR, 0x68 + i, ptr[j + regb]); 5429 } 5430 5431 ptr = cs31a; 5432 ptr2 = cs33a; 5433 if(ivideo->haveXGIROM) { 5434 index = (ivideo->chip == XGI_20) ? 0x31a : 0x3a6; 5435 ptr = (const u8 *)&bios[index]; 5436 ptr2 = (const u8 *)&bios[index + 0x20]; 5437 } 5438 for(i = 0; i < 2; i++) { 5439 if(i == 0) { 5440 regd = le32_to_cpu(((u32 *)ptr)[regb]); 5441 rega = 0x6b; 5442 } else { 5443 regd = le32_to_cpu(((u32 *)ptr2)[regb]); 5444 rega = 0x6e; 5445 } 5446 reg = 0x00; 5447 for(j = 0; j < 16; j++) { 5448 reg &= 0xf3; 5449 if(regd & 0x01) reg |= 0x04; 5450 if(regd & 0x02) reg |= 0x08; 5451 regd >>= 2; 5452 SiS_SetReg(SISCR, rega, reg); 5453 reg = SiS_GetReg(SISCR, rega); 5454 reg = SiS_GetReg(SISCR, rega); 5455 reg += 0x10; 5456 } 5457 } 5458 5459 SiS_SetRegAND(SISCR, 0x6e, 0xfc); 5460 5461 ptr = NULL; 5462 if(ivideo->haveXGIROM) { 5463 index = (ivideo->chip == XGI_20) ? 0x35a : 0x3e6; 5464 ptr = (const u8 *)&bios[index]; 5465 } 5466 for(i = 0; i < 4; i++) { 5467 SiS_SetRegANDOR(SISCR, 0x6e, 0xfc, i); 5468 reg = 0x00; 5469 for(j = 0; j < 2; j++) { 5470 regd = 0; 5471 if(ptr) { 5472 regd = le32_to_cpu(((u32 *)ptr)[regb * 8]); 5473 ptr += 4; 5474 } 5475 /* reg = 0x00; */ 5476 for(k = 0; k < 16; k++) { 5477 reg &= 0xfc; 5478 if(regd & 0x01) reg |= 0x01; 5479 if(regd & 0x02) reg |= 0x02; 5480 regd >>= 2; 5481 SiS_SetReg(SISCR, 0x6f, reg); 5482 reg = SiS_GetReg(SISCR, 0x6f); 5483 reg = SiS_GetReg(SISCR, 0x6f); 5484 reg += 0x08; 5485 } 5486 } 5487 } 5488 5489 ptr = cs148; 5490 if(ivideo->haveXGIROM) { 5491 ptr = (const u8 *)&bios[0x148]; 5492 } 5493 for(i = 0, j = 0; i < 2; i++, j += 8) { 5494 SiS_SetReg(SISCR, 0x80 + i, ptr[j + regb]); 5495 } 5496 5497 SiS_SetRegAND(SISCR, 0x89, 0x8f); 5498 5499 ptr = cs45a; 5500 if(ivideo->haveXGIROM) { 5501 index = (ivideo->chip == XGI_20) ? 0x45a : 0x4e6; 5502 ptr = (const u8 *)&bios[index]; 5503 } 5504 regd = le16_to_cpu(((const u16 *)ptr)[regb]); 5505 reg = 0x80; 5506 for(i = 0; i < 5; i++) { 5507 reg &= 0xfc; 5508 if(regd & 0x01) reg |= 0x01; 5509 if(regd & 0x02) reg |= 0x02; 5510 regd >>= 2; 5511 SiS_SetReg(SISCR, 0x89, reg); 5512 reg = SiS_GetReg(SISCR, 0x89); 5513 reg = SiS_GetReg(SISCR, 0x89); 5514 reg += 0x10; 5515 } 5516 5517 v1 = 0xb5; v2 = 0x20; v3 = 0xf0; v4 = 0x13; 5518 if(ivideo->haveXGIROM) { 5519 v1 = bios[0x118 + regb]; 5520 v2 = bios[0xf8 + regb]; 5521 v3 = bios[0x120 + regb]; 5522 v4 = bios[0x1ca]; 5523 } 5524 SiS_SetReg(SISCR, 0x45, v1 & 0x0f); 5525 SiS_SetReg(SISCR, 0x99, (v1 >> 4) & 0x07); 5526 SiS_SetRegOR(SISCR, 0x40, v1 & 0x80); 5527 SiS_SetReg(SISCR, 0x41, v2); 5528 5529 ptr = cs170; 5530 if(ivideo->haveXGIROM) { 5531 ptr = (const u8 *)&bios[0x170]; 5532 } 5533 for(i = 0, j = 0; i < 7; i++, j += 8) { 5534 SiS_SetReg(SISCR, 0x90 + i, ptr[j + regb]); 5535 } 5536 5537 SiS_SetReg(SISCR, 0x59, v3); 5538 5539 ptr = cs1a8; 5540 if(ivideo->haveXGIROM) { 5541 ptr = (const u8 *)&bios[0x1a8]; 5542 } 5543 for(i = 0, j = 0; i < 3; i++, j += 8) { 5544 SiS_SetReg(SISCR, 0xc3 + i, ptr[j + regb]); 5545 } 5546 5547 ptr = cs100; 5548 if(ivideo->haveXGIROM) { 5549 ptr = (const u8 *)&bios[0x100]; 5550 } 5551 for(i = 0, j = 0; i < 2; i++, j += 8) { 5552 SiS_SetReg(SISCR, 0x8a + i, ptr[j + regb]); 5553 } 5554 5555 SiS_SetReg(SISCR, 0xcf, v4); 5556 5557 SiS_SetReg(SISCR, 0x83, 0x09); 5558 SiS_SetReg(SISCR, 0x87, 0x00); 5559 5560 if(ivideo->chip == XGI_40) { 5561 if( (ivideo->revision_id == 1) || 5562 (ivideo->revision_id == 2) ) { 5563 SiS_SetReg(SISCR, 0x8c, 0x87); 5564 } 5565 } 5566 5567 if (regb == 1) 5568 SiS_SetReg(SISSR, 0x17, 0x80); /* DDR2 */ 5569 else 5570 SiS_SetReg(SISSR, 0x17, 0x00); /* DDR1 */ 5571 SiS_SetReg(SISSR, 0x1a, 0x87); 5572 5573 if(ivideo->chip == XGI_20) { 5574 SiS_SetReg(SISSR, 0x15, 0x00); 5575 SiS_SetReg(SISSR, 0x1c, 0x00); 5576 } 5577 5578 switch(ramtype) { 5579 case 0: 5580 sisfb_post_xgi_setclocks(ivideo, regb); 5581 if((ivideo->chip == XGI_20) || 5582 (ivideo->revision_id == 1) || 5583 (ivideo->revision_id == 2)) { 5584 v1 = cs158[regb]; v2 = cs160[regb]; v3 = cs168[regb]; 5585 if(ivideo->haveXGIROM) { 5586 v1 = bios[regb + 0x158]; 5587 v2 = bios[regb + 0x160]; 5588 v3 = bios[regb + 0x168]; 5589 } 5590 SiS_SetReg(SISCR, 0x82, v1); 5591 SiS_SetReg(SISCR, 0x85, v2); 5592 SiS_SetReg(SISCR, 0x86, v3); 5593 } else { 5594 SiS_SetReg(SISCR, 0x82, 0x88); 5595 SiS_SetReg(SISCR, 0x86, 0x00); 5596 reg = SiS_GetReg(SISCR, 0x86); 5597 SiS_SetReg(SISCR, 0x86, 0x88); 5598 reg = SiS_GetReg(SISCR, 0x86); 5599 SiS_SetReg(SISCR, 0x86, bios[regb + 0x168]); 5600 SiS_SetReg(SISCR, 0x82, 0x77); 5601 SiS_SetReg(SISCR, 0x85, 0x00); 5602 reg = SiS_GetReg(SISCR, 0x85); 5603 SiS_SetReg(SISCR, 0x85, 0x88); 5604 reg = SiS_GetReg(SISCR, 0x85); 5605 SiS_SetReg(SISCR, 0x85, bios[regb + 0x160]); 5606 SiS_SetReg(SISCR, 0x82, bios[regb + 0x158]); 5607 } 5608 if(ivideo->chip == XGI_40) { 5609 SiS_SetReg(SISCR, 0x97, 0x00); 5610 } 5611 SiS_SetReg(SISCR, 0x98, 0x01); 5612 SiS_SetReg(SISCR, 0x9a, 0x02); 5613 5614 SiS_SetReg(SISSR, 0x18, 0x01); 5615 if((ivideo->chip == XGI_20) || 5616 (ivideo->revision_id == 2)) { 5617 SiS_SetReg(SISSR, 0x19, 0x40); 5618 } else { 5619 SiS_SetReg(SISSR, 0x19, 0x20); 5620 } 5621 SiS_SetReg(SISSR, 0x16, 0x00); 5622 SiS_SetReg(SISSR, 0x16, 0x80); 5623 if((ivideo->chip == XGI_20) || (bios[0x1cb] != 0x0c)) { 5624 sisfb_post_xgi_delay(ivideo, 0x43); 5625 sisfb_post_xgi_delay(ivideo, 0x43); 5626 sisfb_post_xgi_delay(ivideo, 0x43); 5627 SiS_SetReg(SISSR, 0x18, 0x00); 5628 if((ivideo->chip == XGI_20) || 5629 (ivideo->revision_id == 2)) { 5630 SiS_SetReg(SISSR, 0x19, 0x40); 5631 } else { 5632 SiS_SetReg(SISSR, 0x19, 0x20); 5633 } 5634 } else if((ivideo->chip == XGI_40) && (bios[0x1cb] == 0x0c)) { 5635 /* SiS_SetReg(SISSR, 0x16, 0x0c); */ /* ? */ 5636 } 5637 SiS_SetReg(SISSR, 0x16, 0x00); 5638 SiS_SetReg(SISSR, 0x16, 0x80); 5639 sisfb_post_xgi_delay(ivideo, 4); 5640 v1 = 0x31; v2 = 0x03; v3 = 0x83; v4 = 0x03; v5 = 0x83; 5641 if(ivideo->haveXGIROM) { 5642 v1 = bios[0xf0]; 5643 index = (ivideo->chip == XGI_20) ? 0x4b2 : 0x53e; 5644 v2 = bios[index]; 5645 v3 = bios[index + 1]; 5646 v4 = bios[index + 2]; 5647 v5 = bios[index + 3]; 5648 } 5649 SiS_SetReg(SISSR, 0x18, v1); 5650 SiS_SetReg(SISSR, 0x19, ((ivideo->chip == XGI_20) ? 0x02 : 0x01)); 5651 SiS_SetReg(SISSR, 0x16, v2); 5652 SiS_SetReg(SISSR, 0x16, v3); 5653 sisfb_post_xgi_delay(ivideo, 0x43); 5654 SiS_SetReg(SISSR, 0x1b, 0x03); 5655 sisfb_post_xgi_delay(ivideo, 0x22); 5656 SiS_SetReg(SISSR, 0x18, v1); 5657 SiS_SetReg(SISSR, 0x19, 0x00); 5658 SiS_SetReg(SISSR, 0x16, v4); 5659 SiS_SetReg(SISSR, 0x16, v5); 5660 SiS_SetReg(SISSR, 0x1b, 0x00); 5661 break; 5662 case 1: 5663 sisfb_post_xgi_ddr2(ivideo, regb); 5664 break; 5665 default: 5666 sisfb_post_xgi_setclocks(ivideo, regb); 5667 if((ivideo->chip == XGI_40) && 5668 ((ivideo->revision_id == 1) || 5669 (ivideo->revision_id == 2))) { 5670 SiS_SetReg(SISCR, 0x82, bios[regb + 0x158]); 5671 SiS_SetReg(SISCR, 0x85, bios[regb + 0x160]); 5672 SiS_SetReg(SISCR, 0x86, bios[regb + 0x168]); 5673 } else { 5674 SiS_SetReg(SISCR, 0x82, 0x88); 5675 SiS_SetReg(SISCR, 0x86, 0x00); 5676 reg = SiS_GetReg(SISCR, 0x86); 5677 SiS_SetReg(SISCR, 0x86, 0x88); 5678 SiS_SetReg(SISCR, 0x82, 0x77); 5679 SiS_SetReg(SISCR, 0x85, 0x00); 5680 reg = SiS_GetReg(SISCR, 0x85); 5681 SiS_SetReg(SISCR, 0x85, 0x88); 5682 reg = SiS_GetReg(SISCR, 0x85); 5683 v1 = cs160[regb]; v2 = cs158[regb]; 5684 if(ivideo->haveXGIROM) { 5685 v1 = bios[regb + 0x160]; 5686 v2 = bios[regb + 0x158]; 5687 } 5688 SiS_SetReg(SISCR, 0x85, v1); 5689 SiS_SetReg(SISCR, 0x82, v2); 5690 } 5691 if(ivideo->chip == XGI_40) { 5692 SiS_SetReg(SISCR, 0x97, 0x11); 5693 } 5694 if((ivideo->chip == XGI_40) && (ivideo->revision_id == 2)) { 5695 SiS_SetReg(SISCR, 0x98, 0x01); 5696 } else { 5697 SiS_SetReg(SISCR, 0x98, 0x03); 5698 } 5699 SiS_SetReg(SISCR, 0x9a, 0x02); 5700 5701 if(ivideo->chip == XGI_40) { 5702 SiS_SetReg(SISSR, 0x18, 0x01); 5703 } else { 5704 SiS_SetReg(SISSR, 0x18, 0x00); 5705 } 5706 SiS_SetReg(SISSR, 0x19, 0x40); 5707 SiS_SetReg(SISSR, 0x16, 0x00); 5708 SiS_SetReg(SISSR, 0x16, 0x80); 5709 if((ivideo->chip == XGI_40) && (bios[0x1cb] != 0x0c)) { 5710 sisfb_post_xgi_delay(ivideo, 0x43); 5711 sisfb_post_xgi_delay(ivideo, 0x43); 5712 sisfb_post_xgi_delay(ivideo, 0x43); 5713 SiS_SetReg(SISSR, 0x18, 0x00); 5714 SiS_SetReg(SISSR, 0x19, 0x40); 5715 SiS_SetReg(SISSR, 0x16, 0x00); 5716 SiS_SetReg(SISSR, 0x16, 0x80); 5717 } 5718 sisfb_post_xgi_delay(ivideo, 4); 5719 v1 = 0x31; 5720 if(ivideo->haveXGIROM) { 5721 v1 = bios[0xf0]; 5722 } 5723 SiS_SetReg(SISSR, 0x18, v1); 5724 SiS_SetReg(SISSR, 0x19, 0x01); 5725 if(ivideo->chip == XGI_40) { 5726 SiS_SetReg(SISSR, 0x16, bios[0x53e]); 5727 SiS_SetReg(SISSR, 0x16, bios[0x53f]); 5728 } else { 5729 SiS_SetReg(SISSR, 0x16, 0x05); 5730 SiS_SetReg(SISSR, 0x16, 0x85); 5731 } 5732 sisfb_post_xgi_delay(ivideo, 0x43); 5733 if(ivideo->chip == XGI_40) { 5734 SiS_SetReg(SISSR, 0x1b, 0x01); 5735 } else { 5736 SiS_SetReg(SISSR, 0x1b, 0x03); 5737 } 5738 sisfb_post_xgi_delay(ivideo, 0x22); 5739 SiS_SetReg(SISSR, 0x18, v1); 5740 SiS_SetReg(SISSR, 0x19, 0x00); 5741 if(ivideo->chip == XGI_40) { 5742 SiS_SetReg(SISSR, 0x16, bios[0x540]); 5743 SiS_SetReg(SISSR, 0x16, bios[0x541]); 5744 } else { 5745 SiS_SetReg(SISSR, 0x16, 0x05); 5746 SiS_SetReg(SISSR, 0x16, 0x85); 5747 } 5748 SiS_SetReg(SISSR, 0x1b, 0x00); 5749 } 5750 5751 regb = 0; /* ! */ 5752 v1 = 0x03; 5753 if(ivideo->haveXGIROM) { 5754 v1 = bios[0x110 + regb]; 5755 } 5756 SiS_SetReg(SISSR, 0x1b, v1); 5757 5758 /* RAM size */ 5759 v1 = 0x00; v2 = 0x00; 5760 if(ivideo->haveXGIROM) { 5761 v1 = bios[0x62]; 5762 v2 = bios[0x63]; 5763 } 5764 regb = 0; /* ! */ 5765 regd = 1 << regb; 5766 if((v1 & 0x40) && (v2 & regd) && ivideo->haveXGIROM) { 5767 5768 SiS_SetReg(SISSR, 0x13, bios[regb + 0xe0]); 5769 SiS_SetReg(SISSR, 0x14, bios[regb + 0xe0 + 8]); 5770 5771 } else { 5772 int err; 5773 5774 /* Set default mode, don't clear screen */ 5775 ivideo->SiS_Pr.SiS_UseOEM = false; 5776 SiS_SetEnableDstn(&ivideo->SiS_Pr, false); 5777 SiS_SetEnableFstn(&ivideo->SiS_Pr, false); 5778 ivideo->curFSTN = ivideo->curDSTN = 0; 5779 ivideo->SiS_Pr.VideoMemorySize = 8 << 20; 5780 SiSSetMode(&ivideo->SiS_Pr, 0x2e | 0x80); 5781 5782 SiS_SetReg(SISSR, 0x05, 0x86); 5783 5784 /* Disable read-cache */ 5785 SiS_SetRegAND(SISSR, 0x21, 0xdf); 5786 err = sisfb_post_xgi_ramsize(ivideo); 5787 /* Enable read-cache */ 5788 SiS_SetRegOR(SISSR, 0x21, 0x20); 5789 5790 if (err) { 5791 dev_err(&pdev->dev, 5792 "%s: RAM size detection failed: %d\n", 5793 __func__, err); 5794 return 0; 5795 } 5796 } 5797 5798 #if 0 5799 printk(KERN_DEBUG "-----------------\n"); 5800 for(i = 0; i < 0xff; i++) { 5801 reg = SiS_GetReg(SISCR, i); 5802 printk(KERN_DEBUG "CR%02x(%x) = 0x%02x\n", i, SISCR, reg); 5803 } 5804 for(i = 0; i < 0x40; i++) { 5805 reg = SiS_GetReg(SISSR, i); 5806 printk(KERN_DEBUG "SR%02x(%x) = 0x%02x\n", i, SISSR, reg); 5807 } 5808 printk(KERN_DEBUG "-----------------\n"); 5809 #endif 5810 5811 /* Sense CRT1 */ 5812 if(ivideo->chip == XGI_20) { 5813 SiS_SetRegOR(SISCR, 0x32, 0x20); 5814 } else { 5815 reg = SiS_GetReg(SISPART4, 0x00); 5816 if((reg == 1) || (reg == 2)) { 5817 sisfb_sense_crt1(ivideo); 5818 } else { 5819 SiS_SetRegOR(SISCR, 0x32, 0x20); 5820 } 5821 } 5822 5823 /* Set default mode, don't clear screen */ 5824 ivideo->SiS_Pr.SiS_UseOEM = false; 5825 SiS_SetEnableDstn(&ivideo->SiS_Pr, false); 5826 SiS_SetEnableFstn(&ivideo->SiS_Pr, false); 5827 ivideo->curFSTN = ivideo->curDSTN = 0; 5828 SiSSetMode(&ivideo->SiS_Pr, 0x2e | 0x80); 5829 5830 SiS_SetReg(SISSR, 0x05, 0x86); 5831 5832 /* Display off */ 5833 SiS_SetRegOR(SISSR, 0x01, 0x20); 5834 5835 /* Save mode number in CR34 */ 5836 SiS_SetReg(SISCR, 0x34, 0x2e); 5837 5838 /* Let everyone know what the current mode is */ 5839 ivideo->modeprechange = 0x2e; 5840 5841 if(ivideo->chip == XGI_40) { 5842 reg = SiS_GetReg(SISCR, 0xca); 5843 v1 = SiS_GetReg(SISCR, 0xcc); 5844 if((reg & 0x10) && (!(v1 & 0x04))) { 5845 printk(KERN_ERR 5846 "sisfb: Please connect power to the card.\n"); 5847 return 0; 5848 } 5849 } 5850 5851 return 1; 5852 } 5853 #endif 5854 5855 static int sisfb_probe(struct pci_dev *pdev, const struct pci_device_id *ent) 5856 { 5857 struct sisfb_chip_info *chipinfo = &sisfb_chip_info[ent->driver_data]; 5858 struct sis_video_info *ivideo = NULL; 5859 struct fb_info *sis_fb_info = NULL; 5860 u16 reg16; 5861 u8 reg; 5862 int i, ret; 5863 5864 if(sisfb_off) 5865 return -ENXIO; 5866 5867 ret = aperture_remove_conflicting_pci_devices(pdev, "sisfb"); 5868 if (ret) 5869 return ret; 5870 5871 sis_fb_info = framebuffer_alloc(sizeof(*ivideo), &pdev->dev); 5872 if(!sis_fb_info) 5873 return -ENOMEM; 5874 5875 ivideo = (struct sis_video_info *)sis_fb_info->par; 5876 ivideo->memyselfandi = sis_fb_info; 5877 5878 ivideo->sisfb_id = SISFB_ID; 5879 5880 if(card_list == NULL) { 5881 ivideo->cardnumber = 0; 5882 } else { 5883 struct sis_video_info *countvideo = card_list; 5884 ivideo->cardnumber = 1; 5885 while((countvideo = countvideo->next) != NULL) 5886 ivideo->cardnumber++; 5887 } 5888 5889 strscpy(ivideo->myid, chipinfo->chip_name, sizeof(ivideo->myid)); 5890 5891 ivideo->warncount = 0; 5892 ivideo->chip_id = pdev->device; 5893 ivideo->chip_vendor = pdev->vendor; 5894 ivideo->revision_id = pdev->revision; 5895 ivideo->SiS_Pr.ChipRevision = ivideo->revision_id; 5896 pci_read_config_word(pdev, PCI_COMMAND, ®16); 5897 ivideo->sisvga_enabled = reg16 & 0x01; 5898 ivideo->pcibus = pdev->bus->number; 5899 ivideo->pcislot = PCI_SLOT(pdev->devfn); 5900 ivideo->pcifunc = PCI_FUNC(pdev->devfn); 5901 ivideo->subsysvendor = pdev->subsystem_vendor; 5902 ivideo->subsysdevice = pdev->subsystem_device; 5903 5904 #ifndef MODULE 5905 if(sisfb_mode_idx == -1) { 5906 sisfb_get_vga_mode_from_kernel(); 5907 } 5908 #endif 5909 5910 ivideo->chip = chipinfo->chip; 5911 ivideo->chip_real_id = chipinfo->chip; 5912 ivideo->sisvga_engine = chipinfo->vgaengine; 5913 ivideo->hwcursor_size = chipinfo->hwcursor_size; 5914 ivideo->CRT2_write_enable = chipinfo->CRT2_write_enable; 5915 ivideo->mni = chipinfo->mni; 5916 5917 ivideo->detectedpdc = 0xff; 5918 ivideo->detectedpdca = 0xff; 5919 ivideo->detectedlcda = 0xff; 5920 5921 ivideo->sisfb_thismonitor.datavalid = false; 5922 5923 ivideo->current_base = 0; 5924 5925 ivideo->engineok = 0; 5926 5927 ivideo->sisfb_was_boot_device = 0; 5928 5929 if(pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW) { 5930 if(ivideo->sisvga_enabled) 5931 ivideo->sisfb_was_boot_device = 1; 5932 else { 5933 printk(KERN_DEBUG "sisfb: PCI device is disabled, " 5934 "but marked as boot video device ???\n"); 5935 printk(KERN_DEBUG "sisfb: I will not accept this " 5936 "as the primary VGA device\n"); 5937 } 5938 } 5939 5940 ivideo->sisfb_parm_mem = sisfb_parm_mem; 5941 ivideo->sisfb_accel = sisfb_accel; 5942 ivideo->sisfb_ypan = sisfb_ypan; 5943 ivideo->sisfb_max = sisfb_max; 5944 ivideo->sisfb_userom = sisfb_userom; 5945 ivideo->sisfb_useoem = sisfb_useoem; 5946 ivideo->sisfb_mode_idx = sisfb_mode_idx; 5947 ivideo->sisfb_parm_rate = sisfb_parm_rate; 5948 ivideo->sisfb_crt1off = sisfb_crt1off; 5949 ivideo->sisfb_forcecrt1 = sisfb_forcecrt1; 5950 ivideo->sisfb_crt2type = sisfb_crt2type; 5951 ivideo->sisfb_crt2flags = sisfb_crt2flags; 5952 /* pdc(a), scalelcd, special timing, lvdshl handled below */ 5953 ivideo->sisfb_dstn = sisfb_dstn; 5954 ivideo->sisfb_fstn = sisfb_fstn; 5955 ivideo->sisfb_tvplug = sisfb_tvplug; 5956 ivideo->sisfb_tvstd = sisfb_tvstd; 5957 ivideo->tvxpos = sisfb_tvxposoffset; 5958 ivideo->tvypos = sisfb_tvyposoffset; 5959 ivideo->sisfb_nocrt2rate = sisfb_nocrt2rate; 5960 ivideo->refresh_rate = 0; 5961 if(ivideo->sisfb_parm_rate != -1) { 5962 ivideo->refresh_rate = ivideo->sisfb_parm_rate; 5963 } 5964 5965 ivideo->SiS_Pr.UsePanelScaler = sisfb_scalelcd; 5966 ivideo->SiS_Pr.CenterScreen = -1; 5967 ivideo->SiS_Pr.SiS_CustomT = sisfb_specialtiming; 5968 ivideo->SiS_Pr.LVDSHL = sisfb_lvdshl; 5969 5970 ivideo->SiS_Pr.SiS_Backup70xx = 0xff; 5971 ivideo->SiS_Pr.SiS_CHOverScan = -1; 5972 ivideo->SiS_Pr.SiS_ChSW = false; 5973 ivideo->SiS_Pr.SiS_UseLCDA = false; 5974 ivideo->SiS_Pr.HaveEMI = false; 5975 ivideo->SiS_Pr.HaveEMILCD = false; 5976 ivideo->SiS_Pr.OverruleEMI = false; 5977 ivideo->SiS_Pr.SiS_SensibleSR11 = false; 5978 ivideo->SiS_Pr.SiS_MyCR63 = 0x63; 5979 ivideo->SiS_Pr.PDC = -1; 5980 ivideo->SiS_Pr.PDCA = -1; 5981 ivideo->SiS_Pr.DDCPortMixup = false; 5982 #ifdef CONFIG_FB_SIS_315 5983 if(ivideo->chip >= SIS_330) { 5984 ivideo->SiS_Pr.SiS_MyCR63 = 0x53; 5985 if(ivideo->chip >= SIS_661) { 5986 ivideo->SiS_Pr.SiS_SensibleSR11 = true; 5987 } 5988 } 5989 #endif 5990 5991 memcpy(&ivideo->default_var, &my_default_var, sizeof(my_default_var)); 5992 5993 pci_set_drvdata(pdev, ivideo); 5994 5995 /* Patch special cases */ 5996 if((ivideo->nbridge = sisfb_get_northbridge(ivideo->chip))) { 5997 switch(ivideo->nbridge->device) { 5998 #ifdef CONFIG_FB_SIS_300 5999 case PCI_DEVICE_ID_SI_730: 6000 ivideo->chip = SIS_730; 6001 strcpy(ivideo->myid, "SiS 730"); 6002 break; 6003 #endif 6004 #ifdef CONFIG_FB_SIS_315 6005 case PCI_DEVICE_ID_SI_651: 6006 /* ivideo->chip is ok */ 6007 strcpy(ivideo->myid, "SiS 651"); 6008 break; 6009 case PCI_DEVICE_ID_SI_740: 6010 ivideo->chip = SIS_740; 6011 strcpy(ivideo->myid, "SiS 740"); 6012 break; 6013 case PCI_DEVICE_ID_SI_661: 6014 ivideo->chip = SIS_661; 6015 strcpy(ivideo->myid, "SiS 661"); 6016 break; 6017 case PCI_DEVICE_ID_SI_741: 6018 ivideo->chip = SIS_741; 6019 strcpy(ivideo->myid, "SiS 741"); 6020 break; 6021 case PCI_DEVICE_ID_SI_760: 6022 ivideo->chip = SIS_760; 6023 strcpy(ivideo->myid, "SiS 760"); 6024 break; 6025 case PCI_DEVICE_ID_SI_761: 6026 ivideo->chip = SIS_761; 6027 strcpy(ivideo->myid, "SiS 761"); 6028 break; 6029 #endif 6030 default: 6031 break; 6032 } 6033 } 6034 6035 ivideo->SiS_Pr.ChipType = ivideo->chip; 6036 6037 ivideo->SiS_Pr.ivideo = (void *)ivideo; 6038 6039 #ifdef CONFIG_FB_SIS_315 6040 if((ivideo->SiS_Pr.ChipType == SIS_315PRO) || 6041 (ivideo->SiS_Pr.ChipType == SIS_315)) { 6042 ivideo->SiS_Pr.ChipType = SIS_315H; 6043 } 6044 #endif 6045 6046 if(!ivideo->sisvga_enabled) { 6047 if(pci_enable_device(pdev)) { 6048 pci_dev_put(ivideo->nbridge); 6049 framebuffer_release(sis_fb_info); 6050 return -EIO; 6051 } 6052 } 6053 6054 ivideo->video_base = pci_resource_start(pdev, 0); 6055 ivideo->video_size = pci_resource_len(pdev, 0); 6056 ivideo->mmio_base = pci_resource_start(pdev, 1); 6057 ivideo->mmio_size = pci_resource_len(pdev, 1); 6058 ivideo->SiS_Pr.RelIO = pci_resource_start(pdev, 2) + 0x30; 6059 ivideo->SiS_Pr.IOAddress = ivideo->vga_base = ivideo->SiS_Pr.RelIO; 6060 6061 SiSRegInit(&ivideo->SiS_Pr, ivideo->SiS_Pr.IOAddress); 6062 6063 #ifdef CONFIG_FB_SIS_300 6064 /* Find PCI systems for Chrontel/GPIO communication setup */ 6065 if(ivideo->chip == SIS_630) { 6066 i = 0; 6067 do { 6068 if(mychswtable[i].subsysVendor == ivideo->subsysvendor && 6069 mychswtable[i].subsysCard == ivideo->subsysdevice) { 6070 ivideo->SiS_Pr.SiS_ChSW = true; 6071 printk(KERN_DEBUG "sisfb: Identified [%s %s] " 6072 "requiring Chrontel/GPIO setup\n", 6073 mychswtable[i].vendorName, 6074 mychswtable[i].cardName); 6075 ivideo->lpcdev = pci_get_device(PCI_VENDOR_ID_SI, 0x0008, NULL); 6076 break; 6077 } 6078 i++; 6079 } while(mychswtable[i].subsysVendor != 0); 6080 } 6081 #endif 6082 6083 #ifdef CONFIG_FB_SIS_315 6084 if((ivideo->chip == SIS_760) && (ivideo->nbridge)) { 6085 ivideo->lpcdev = pci_get_slot(ivideo->nbridge->bus, (2 << 3)); 6086 } 6087 #endif 6088 6089 SiS_SetReg(SISSR, 0x05, 0x86); 6090 6091 if( (!ivideo->sisvga_enabled) 6092 #if !defined(__i386__) && !defined(__x86_64__) 6093 || (sisfb_resetcard) 6094 #endif 6095 ) { 6096 for(i = 0x30; i <= 0x3f; i++) { 6097 SiS_SetReg(SISCR, i, 0x00); 6098 } 6099 } 6100 6101 /* Find out about current video mode */ 6102 ivideo->modeprechange = 0x03; 6103 reg = SiS_GetReg(SISCR, 0x34); 6104 if(reg & 0x7f) { 6105 ivideo->modeprechange = reg & 0x7f; 6106 } else if(ivideo->sisvga_enabled) { 6107 #if defined(__i386__) || defined(__x86_64__) 6108 unsigned char __iomem *tt = ioremap(0x400, 0x100); 6109 if(tt) { 6110 ivideo->modeprechange = readb(tt + 0x49); 6111 iounmap(tt); 6112 } 6113 #endif 6114 } 6115 6116 /* Search and copy ROM image */ 6117 ivideo->bios_abase = NULL; 6118 ivideo->SiS_Pr.VirtualRomBase = NULL; 6119 ivideo->SiS_Pr.UseROM = false; 6120 ivideo->haveXGIROM = ivideo->SiS_Pr.SiS_XGIROM = false; 6121 if(ivideo->sisfb_userom) { 6122 ivideo->SiS_Pr.VirtualRomBase = sisfb_find_rom(pdev); 6123 ivideo->bios_abase = ivideo->SiS_Pr.VirtualRomBase; 6124 ivideo->SiS_Pr.UseROM = (bool)(ivideo->SiS_Pr.VirtualRomBase); 6125 printk(KERN_INFO "sisfb: Video ROM %sfound\n", 6126 ivideo->SiS_Pr.UseROM ? "" : "not "); 6127 if((ivideo->SiS_Pr.UseROM) && (ivideo->chip >= XGI_20)) { 6128 ivideo->SiS_Pr.UseROM = false; 6129 ivideo->haveXGIROM = ivideo->SiS_Pr.SiS_XGIROM = true; 6130 if( (ivideo->revision_id == 2) && 6131 (!(ivideo->bios_abase[0x1d1] & 0x01)) ) { 6132 ivideo->SiS_Pr.DDCPortMixup = true; 6133 } 6134 } 6135 } else { 6136 printk(KERN_INFO "sisfb: Video ROM usage disabled\n"); 6137 } 6138 6139 /* Find systems for special custom timing */ 6140 if(ivideo->SiS_Pr.SiS_CustomT == CUT_NONE) { 6141 sisfb_detect_custom_timing(ivideo); 6142 } 6143 6144 #ifdef CONFIG_FB_SIS_315 6145 if (ivideo->chip == XGI_20) { 6146 /* Check if our Z7 chip is actually Z9 */ 6147 SiS_SetRegOR(SISCR, 0x4a, 0x40); /* GPIOG EN */ 6148 reg = SiS_GetReg(SISCR, 0x48); 6149 if (reg & 0x02) { /* GPIOG */ 6150 ivideo->chip_real_id = XGI_21; 6151 dev_info(&pdev->dev, "Z9 detected\n"); 6152 } 6153 } 6154 #endif 6155 6156 /* POST card in case this has not been done by the BIOS */ 6157 if( (!ivideo->sisvga_enabled) 6158 #if !defined(__i386__) && !defined(__x86_64__) 6159 || (sisfb_resetcard) 6160 #endif 6161 ) { 6162 #ifdef CONFIG_FB_SIS_300 6163 if(ivideo->sisvga_engine == SIS_300_VGA) { 6164 if(ivideo->chip == SIS_300) { 6165 sisfb_post_sis300(pdev); 6166 ivideo->sisfb_can_post = 1; 6167 } 6168 } 6169 #endif 6170 6171 #ifdef CONFIG_FB_SIS_315 6172 if (ivideo->sisvga_engine == SIS_315_VGA) { 6173 int result = 1; 6174 6175 if (ivideo->chip == XGI_20) { 6176 result = sisfb_post_xgi(pdev); 6177 ivideo->sisfb_can_post = 1; 6178 } else if ((ivideo->chip == XGI_40) && ivideo->haveXGIROM) { 6179 result = sisfb_post_xgi(pdev); 6180 ivideo->sisfb_can_post = 1; 6181 } else { 6182 printk(KERN_INFO "sisfb: Card is not " 6183 "POSTed and sisfb can't do this either.\n"); 6184 } 6185 if (!result) { 6186 printk(KERN_ERR "sisfb: Failed to POST card\n"); 6187 ret = -ENODEV; 6188 goto error_3; 6189 } 6190 } 6191 #endif 6192 } 6193 6194 ivideo->sisfb_card_posted = 1; 6195 6196 /* Find out about RAM size */ 6197 if(sisfb_get_dram_size(ivideo)) { 6198 printk(KERN_INFO "sisfb: Fatal error: Unable to determine VRAM size.\n"); 6199 ret = -ENODEV; 6200 goto error_3; 6201 } 6202 6203 6204 /* Enable PCI addressing and MMIO */ 6205 if((ivideo->sisfb_mode_idx < 0) || 6206 ((sisbios_mode[ivideo->sisfb_mode_idx].mode_no[ivideo->mni]) != 0xFF)) { 6207 /* Enable PCI_LINEAR_ADDRESSING and MMIO_ENABLE */ 6208 SiS_SetRegOR(SISSR, IND_SIS_PCI_ADDRESS_SET, (SIS_PCI_ADDR_ENABLE | SIS_MEM_MAP_IO_ENABLE)); 6209 /* Enable 2D accelerator engine */ 6210 SiS_SetRegOR(SISSR, IND_SIS_MODULE_ENABLE, SIS_ENABLE_2D); 6211 } 6212 6213 if(sisfb_pdc != 0xff) { 6214 if(ivideo->sisvga_engine == SIS_300_VGA) 6215 sisfb_pdc &= 0x3c; 6216 else 6217 sisfb_pdc &= 0x1f; 6218 ivideo->SiS_Pr.PDC = sisfb_pdc; 6219 } 6220 #ifdef CONFIG_FB_SIS_315 6221 if(ivideo->sisvga_engine == SIS_315_VGA) { 6222 if(sisfb_pdca != 0xff) 6223 ivideo->SiS_Pr.PDCA = sisfb_pdca & 0x1f; 6224 } 6225 #endif 6226 6227 if(!request_mem_region(ivideo->video_base, ivideo->video_size, "sisfb FB")) { 6228 printk(KERN_ERR "sisfb: Fatal error: Unable to reserve %dMB framebuffer memory\n", 6229 (int)(ivideo->video_size >> 20)); 6230 printk(KERN_ERR "sisfb: Is there another framebuffer driver active?\n"); 6231 ret = -ENODEV; 6232 goto error_3; 6233 } 6234 6235 if(!request_mem_region(ivideo->mmio_base, ivideo->mmio_size, "sisfb MMIO")) { 6236 printk(KERN_ERR "sisfb: Fatal error: Unable to reserve MMIO region\n"); 6237 ret = -ENODEV; 6238 goto error_2; 6239 } 6240 6241 ivideo->video_vbase = ioremap_wc(ivideo->video_base, ivideo->video_size); 6242 ivideo->SiS_Pr.VideoMemoryAddress = ivideo->video_vbase; 6243 if(!ivideo->video_vbase) { 6244 printk(KERN_ERR "sisfb: Fatal error: Unable to map framebuffer memory\n"); 6245 ret = -ENODEV; 6246 goto error_1; 6247 } 6248 6249 ivideo->mmio_vbase = ioremap(ivideo->mmio_base, ivideo->mmio_size); 6250 if(!ivideo->mmio_vbase) { 6251 printk(KERN_ERR "sisfb: Fatal error: Unable to map MMIO region\n"); 6252 ret = -ENODEV; 6253 error_0: iounmap(ivideo->video_vbase); 6254 error_1: release_mem_region(ivideo->video_base, ivideo->video_size); 6255 error_2: release_mem_region(ivideo->mmio_base, ivideo->mmio_size); 6256 error_3: vfree(ivideo->bios_abase); 6257 pci_dev_put(ivideo->lpcdev); 6258 pci_dev_put(ivideo->nbridge); 6259 if(!ivideo->sisvga_enabled) 6260 pci_disable_device(pdev); 6261 framebuffer_release(sis_fb_info); 6262 return ret; 6263 } 6264 6265 printk(KERN_INFO "sisfb: Video RAM at 0x%lx, mapped to 0x%lx, size %ldk\n", 6266 ivideo->video_base, (unsigned long)ivideo->video_vbase, ivideo->video_size / 1024); 6267 6268 if(ivideo->video_offset) { 6269 printk(KERN_INFO "sisfb: Viewport offset %ldk\n", 6270 ivideo->video_offset / 1024); 6271 } 6272 6273 printk(KERN_INFO "sisfb: MMIO at 0x%lx, mapped to 0x%lx, size %ldk\n", 6274 ivideo->mmio_base, (unsigned long)ivideo->mmio_vbase, ivideo->mmio_size / 1024); 6275 6276 6277 /* Determine the size of the command queue */ 6278 if(ivideo->sisvga_engine == SIS_300_VGA) { 6279 ivideo->cmdQueueSize = TURBO_QUEUE_AREA_SIZE; 6280 } else { 6281 if(ivideo->chip == XGI_20) { 6282 ivideo->cmdQueueSize = COMMAND_QUEUE_AREA_SIZE_Z7; 6283 } else { 6284 ivideo->cmdQueueSize = COMMAND_QUEUE_AREA_SIZE; 6285 } 6286 } 6287 6288 /* Engines are no longer initialized here; this is 6289 * now done after the first mode-switch (if the 6290 * submitted var has its acceleration flags set). 6291 */ 6292 6293 /* Calculate the base of the (unused) hw cursor */ 6294 ivideo->hwcursor_vbase = ivideo->video_vbase 6295 + ivideo->video_size 6296 - ivideo->cmdQueueSize 6297 - ivideo->hwcursor_size; 6298 ivideo->caps |= HW_CURSOR_CAP; 6299 6300 /* Initialize offscreen memory manager */ 6301 if((ivideo->havenoheap = sisfb_heap_init(ivideo))) { 6302 printk(KERN_WARNING "sisfb: Failed to initialize offscreen memory heap\n"); 6303 } 6304 6305 /* Used for clearing the screen only, therefore respect our mem limit */ 6306 ivideo->SiS_Pr.VideoMemoryAddress += ivideo->video_offset; 6307 ivideo->SiS_Pr.VideoMemorySize = ivideo->sisfb_mem; 6308 6309 ivideo->vbflags = 0; 6310 ivideo->lcddefmodeidx = DEFAULT_LCDMODE; 6311 ivideo->tvdefmodeidx = DEFAULT_TVMODE; 6312 ivideo->defmodeidx = DEFAULT_MODE; 6313 6314 ivideo->newrom = 0; 6315 if(ivideo->chip < XGI_20) { 6316 if(ivideo->bios_abase) { 6317 ivideo->newrom = SiSDetermineROMLayout661(&ivideo->SiS_Pr); 6318 } 6319 } 6320 6321 if((ivideo->sisfb_mode_idx < 0) || 6322 ((sisbios_mode[ivideo->sisfb_mode_idx].mode_no[ivideo->mni]) != 0xFF)) { 6323 6324 sisfb_sense_crt1(ivideo); 6325 6326 sisfb_get_VB_type(ivideo); 6327 6328 if(ivideo->vbflags2 & VB2_VIDEOBRIDGE) { 6329 sisfb_detect_VB_connect(ivideo); 6330 } 6331 6332 ivideo->currentvbflags = ivideo->vbflags & (VB_VIDEOBRIDGE | TV_STANDARD); 6333 6334 /* Decide on which CRT2 device to use */ 6335 if(ivideo->vbflags2 & VB2_VIDEOBRIDGE) { 6336 if(ivideo->sisfb_crt2type != -1) { 6337 if((ivideo->sisfb_crt2type == CRT2_LCD) && 6338 (ivideo->vbflags & CRT2_LCD)) { 6339 ivideo->currentvbflags |= CRT2_LCD; 6340 } else if(ivideo->sisfb_crt2type != CRT2_LCD) { 6341 ivideo->currentvbflags |= ivideo->sisfb_crt2type; 6342 } 6343 } else { 6344 /* Chrontel 700x TV detection often unreliable, therefore 6345 * use a different default order on such machines 6346 */ 6347 if((ivideo->sisvga_engine == SIS_300_VGA) && 6348 (ivideo->vbflags2 & VB2_CHRONTEL)) { 6349 if(ivideo->vbflags & CRT2_LCD) 6350 ivideo->currentvbflags |= CRT2_LCD; 6351 else if(ivideo->vbflags & CRT2_TV) 6352 ivideo->currentvbflags |= CRT2_TV; 6353 else if(ivideo->vbflags & CRT2_VGA) 6354 ivideo->currentvbflags |= CRT2_VGA; 6355 } else { 6356 if(ivideo->vbflags & CRT2_TV) 6357 ivideo->currentvbflags |= CRT2_TV; 6358 else if(ivideo->vbflags & CRT2_LCD) 6359 ivideo->currentvbflags |= CRT2_LCD; 6360 else if(ivideo->vbflags & CRT2_VGA) 6361 ivideo->currentvbflags |= CRT2_VGA; 6362 } 6363 } 6364 } 6365 6366 if(ivideo->vbflags & CRT2_LCD) { 6367 sisfb_detect_lcd_type(ivideo); 6368 } 6369 6370 sisfb_save_pdc_emi(ivideo); 6371 6372 if(!ivideo->sisfb_crt1off) { 6373 sisfb_handle_ddc(ivideo, &ivideo->sisfb_thismonitor, 0); 6374 } else { 6375 if((ivideo->vbflags2 & VB2_SISTMDSBRIDGE) && 6376 (ivideo->vbflags & (CRT2_VGA | CRT2_LCD))) { 6377 sisfb_handle_ddc(ivideo, &ivideo->sisfb_thismonitor, 1); 6378 } 6379 } 6380 6381 if(ivideo->sisfb_mode_idx >= 0) { 6382 int bu = ivideo->sisfb_mode_idx; 6383 ivideo->sisfb_mode_idx = sisfb_validate_mode(ivideo, 6384 ivideo->sisfb_mode_idx, ivideo->currentvbflags); 6385 if(bu != ivideo->sisfb_mode_idx) { 6386 printk(KERN_ERR "Mode %dx%dx%d failed validation\n", 6387 sisbios_mode[bu].xres, 6388 sisbios_mode[bu].yres, 6389 sisbios_mode[bu].bpp); 6390 } 6391 } 6392 6393 if(ivideo->sisfb_mode_idx < 0) { 6394 switch(ivideo->currentvbflags & VB_DISPTYPE_DISP2) { 6395 case CRT2_LCD: 6396 ivideo->sisfb_mode_idx = ivideo->lcddefmodeidx; 6397 break; 6398 case CRT2_TV: 6399 ivideo->sisfb_mode_idx = ivideo->tvdefmodeidx; 6400 break; 6401 default: 6402 ivideo->sisfb_mode_idx = ivideo->defmodeidx; 6403 break; 6404 } 6405 } 6406 6407 ivideo->mode_no = sisbios_mode[ivideo->sisfb_mode_idx].mode_no[ivideo->mni]; 6408 6409 if(ivideo->refresh_rate != 0) { 6410 sisfb_search_refresh_rate(ivideo, ivideo->refresh_rate, 6411 ivideo->sisfb_mode_idx); 6412 } 6413 6414 if(ivideo->rate_idx == 0) { 6415 ivideo->rate_idx = sisbios_mode[ivideo->sisfb_mode_idx].rate_idx; 6416 ivideo->refresh_rate = 60; 6417 } 6418 6419 if(ivideo->sisfb_thismonitor.datavalid) { 6420 if(!sisfb_verify_rate(ivideo, &ivideo->sisfb_thismonitor, 6421 ivideo->sisfb_mode_idx, 6422 ivideo->rate_idx, 6423 ivideo->refresh_rate)) { 6424 printk(KERN_INFO "sisfb: WARNING: Refresh rate " 6425 "exceeds monitor specs!\n"); 6426 } 6427 } 6428 6429 ivideo->video_bpp = sisbios_mode[ivideo->sisfb_mode_idx].bpp; 6430 ivideo->video_width = sisbios_mode[ivideo->sisfb_mode_idx].xres; 6431 ivideo->video_height = sisbios_mode[ivideo->sisfb_mode_idx].yres; 6432 6433 sisfb_set_vparms(ivideo); 6434 6435 printk(KERN_INFO "sisfb: Default mode is %dx%dx%d (%dHz)\n", 6436 ivideo->video_width, ivideo->video_height, ivideo->video_bpp, 6437 ivideo->refresh_rate); 6438 6439 /* Set up the default var according to chosen default display mode */ 6440 ivideo->default_var.xres = ivideo->default_var.xres_virtual = ivideo->video_width; 6441 ivideo->default_var.yres = ivideo->default_var.yres_virtual = ivideo->video_height; 6442 ivideo->default_var.bits_per_pixel = ivideo->video_bpp; 6443 6444 sisfb_bpp_to_var(ivideo, &ivideo->default_var); 6445 6446 ivideo->default_var.pixclock = (u32) (1000000000 / 6447 sisfb_mode_rate_to_dclock(&ivideo->SiS_Pr, ivideo->mode_no, ivideo->rate_idx)); 6448 6449 if(sisfb_mode_rate_to_ddata(&ivideo->SiS_Pr, ivideo->mode_no, 6450 ivideo->rate_idx, &ivideo->default_var)) { 6451 if((ivideo->default_var.vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) { 6452 ivideo->default_var.pixclock <<= 1; 6453 } 6454 } 6455 6456 if(ivideo->sisfb_ypan) { 6457 /* Maximize regardless of sisfb_max at startup */ 6458 ivideo->default_var.yres_virtual = 6459 sisfb_calc_maxyres(ivideo, &ivideo->default_var); 6460 if(ivideo->default_var.yres_virtual < ivideo->default_var.yres) { 6461 ivideo->default_var.yres_virtual = ivideo->default_var.yres; 6462 } 6463 } 6464 6465 sisfb_calc_pitch(ivideo, &ivideo->default_var); 6466 6467 ivideo->accel = 0; 6468 if(ivideo->sisfb_accel) { 6469 ivideo->accel = -1; 6470 #ifdef STUPID_ACCELF_TEXT_SHIT 6471 ivideo->default_var.accel_flags |= FB_ACCELF_TEXT; 6472 #endif 6473 } 6474 sisfb_initaccel(ivideo); 6475 6476 #if defined(FBINFO_HWACCEL_DISABLED) && defined(FBINFO_HWACCEL_XPAN) 6477 sis_fb_info->flags = FBINFO_HWACCEL_YPAN | 6478 FBINFO_HWACCEL_XPAN | 6479 FBINFO_HWACCEL_COPYAREA | 6480 FBINFO_HWACCEL_FILLRECT | 6481 ((ivideo->accel) ? 0 : FBINFO_HWACCEL_DISABLED); 6482 #endif 6483 sis_fb_info->var = ivideo->default_var; 6484 sis_fb_info->fix = ivideo->sisfb_fix; 6485 sis_fb_info->screen_base = ivideo->video_vbase + ivideo->video_offset; 6486 sis_fb_info->fbops = &sisfb_ops; 6487 sis_fb_info->pseudo_palette = ivideo->pseudo_palette; 6488 6489 fb_alloc_cmap(&sis_fb_info->cmap, 256 , 0); 6490 6491 printk(KERN_DEBUG "sisfb: Initial vbflags 0x%x\n", (int)ivideo->vbflags); 6492 6493 ivideo->wc_cookie = arch_phys_wc_add(ivideo->video_base, 6494 ivideo->video_size); 6495 if(register_framebuffer(sis_fb_info) < 0) { 6496 printk(KERN_ERR "sisfb: Fatal error: Failed to register framebuffer\n"); 6497 ret = -EINVAL; 6498 iounmap(ivideo->mmio_vbase); 6499 goto error_0; 6500 } 6501 6502 ivideo->registered = 1; 6503 6504 /* Enlist us */ 6505 ivideo->next = card_list; 6506 card_list = ivideo; 6507 6508 printk(KERN_INFO "sisfb: 2D acceleration is %s, y-panning %s\n", 6509 ivideo->sisfb_accel ? "enabled" : "disabled", 6510 ivideo->sisfb_ypan ? 6511 (ivideo->sisfb_max ? "enabled (auto-max)" : 6512 "enabled (no auto-max)") : 6513 "disabled"); 6514 6515 6516 fb_info(sis_fb_info, "%s frame buffer device version %d.%d.%d\n", 6517 ivideo->myid, VER_MAJOR, VER_MINOR, VER_LEVEL); 6518 6519 printk(KERN_INFO "sisfb: Copyright (C) 2001-2005 Thomas Winischhofer\n"); 6520 6521 } /* if mode = "none" */ 6522 6523 return 0; 6524 } 6525 6526 /*****************************************************/ 6527 /* PCI DEVICE HANDLING */ 6528 /*****************************************************/ 6529 6530 static void sisfb_remove(struct pci_dev *pdev) 6531 { 6532 struct sis_video_info *ivideo = pci_get_drvdata(pdev); 6533 struct fb_info *sis_fb_info = ivideo->memyselfandi; 6534 int registered = ivideo->registered; 6535 int modechanged = ivideo->modechanged; 6536 6537 /* Unmap */ 6538 iounmap(ivideo->mmio_vbase); 6539 iounmap(ivideo->video_vbase); 6540 6541 /* Release mem regions */ 6542 release_mem_region(ivideo->video_base, ivideo->video_size); 6543 release_mem_region(ivideo->mmio_base, ivideo->mmio_size); 6544 6545 vfree(ivideo->bios_abase); 6546 6547 pci_dev_put(ivideo->lpcdev); 6548 6549 pci_dev_put(ivideo->nbridge); 6550 6551 arch_phys_wc_del(ivideo->wc_cookie); 6552 6553 /* If device was disabled when starting, disable 6554 * it when quitting. 6555 */ 6556 if(!ivideo->sisvga_enabled) 6557 pci_disable_device(pdev); 6558 6559 /* Unregister the framebuffer */ 6560 if(ivideo->registered) { 6561 unregister_framebuffer(sis_fb_info); 6562 framebuffer_release(sis_fb_info); 6563 } 6564 6565 /* OK, our ivideo is gone for good from here. */ 6566 6567 /* TODO: Restore the initial mode 6568 * This sounds easy but is as good as impossible 6569 * on many machines with SiS chip and video bridge 6570 * since text modes are always set up differently 6571 * from machine to machine. Depends on the type 6572 * of integration between chipset and bridge. 6573 */ 6574 if(registered && modechanged) 6575 printk(KERN_INFO 6576 "sisfb: Restoring of text mode not supported yet\n"); 6577 }; 6578 6579 static struct pci_driver sisfb_driver = { 6580 .name = "sisfb", 6581 .id_table = sisfb_pci_table, 6582 .probe = sisfb_probe, 6583 .remove = sisfb_remove, 6584 }; 6585 6586 static int __init sisfb_init(void) 6587 { 6588 #ifndef MODULE 6589 char *options = NULL; 6590 #endif 6591 6592 if (fb_modesetting_disabled("sisfb")) 6593 return -ENODEV; 6594 6595 #ifndef MODULE 6596 if(fb_get_options("sisfb", &options)) 6597 return -ENODEV; 6598 6599 sisfb_setup(options); 6600 #endif 6601 return pci_register_driver(&sisfb_driver); 6602 } 6603 6604 #ifndef MODULE 6605 module_init(sisfb_init); 6606 #endif 6607 6608 /*****************************************************/ 6609 /* MODULE */ 6610 /*****************************************************/ 6611 6612 #ifdef MODULE 6613 6614 static char *mode = NULL; 6615 static int vesa = -1; 6616 static unsigned int rate = 0; 6617 static unsigned int crt1off = 1; 6618 static unsigned int mem = 0; 6619 static char *forcecrt2type = NULL; 6620 static int forcecrt1 = -1; 6621 static int pdc = -1; 6622 static int pdc1 = -1; 6623 static int noaccel = -1; 6624 static int noypan = -1; 6625 static int nomax = -1; 6626 static int userom = -1; 6627 static int useoem = -1; 6628 static char *tvstandard = NULL; 6629 static int nocrt2rate = 0; 6630 static int scalelcd = -1; 6631 static char *specialtiming = NULL; 6632 static int lvdshl = -1; 6633 static int tvxposoffset = 0, tvyposoffset = 0; 6634 #if !defined(__i386__) && !defined(__x86_64__) 6635 static int resetcard = 0; 6636 static int videoram = 0; 6637 #endif 6638 6639 static int __init sisfb_init_module(void) 6640 { 6641 sisfb_setdefaultparms(); 6642 6643 if(rate) 6644 sisfb_parm_rate = rate; 6645 6646 if((scalelcd == 0) || (scalelcd == 1)) 6647 sisfb_scalelcd = scalelcd ^ 1; 6648 6649 /* Need to check crt2 type first for fstn/dstn */ 6650 6651 if(forcecrt2type) 6652 sisfb_search_crt2type(forcecrt2type); 6653 6654 if(tvstandard) 6655 sisfb_search_tvstd(tvstandard); 6656 6657 if(mode) 6658 sisfb_search_mode(mode, false); 6659 else if(vesa != -1) 6660 sisfb_search_vesamode(vesa, false); 6661 6662 sisfb_crt1off = (crt1off == 0) ? 1 : 0; 6663 6664 sisfb_forcecrt1 = forcecrt1; 6665 if(forcecrt1 == 1) 6666 sisfb_crt1off = 0; 6667 else if(forcecrt1 == 0) 6668 sisfb_crt1off = 1; 6669 6670 if(noaccel == 1) 6671 sisfb_accel = 0; 6672 else if(noaccel == 0) 6673 sisfb_accel = 1; 6674 6675 if(noypan == 1) 6676 sisfb_ypan = 0; 6677 else if(noypan == 0) 6678 sisfb_ypan = 1; 6679 6680 if(nomax == 1) 6681 sisfb_max = 0; 6682 else if(nomax == 0) 6683 sisfb_max = 1; 6684 6685 if(mem) 6686 sisfb_parm_mem = mem; 6687 6688 if(userom != -1) 6689 sisfb_userom = userom; 6690 6691 if(useoem != -1) 6692 sisfb_useoem = useoem; 6693 6694 if(pdc != -1) 6695 sisfb_pdc = (pdc & 0x7f); 6696 6697 if(pdc1 != -1) 6698 sisfb_pdca = (pdc1 & 0x1f); 6699 6700 sisfb_nocrt2rate = nocrt2rate; 6701 6702 if(specialtiming) 6703 sisfb_search_specialtiming(specialtiming); 6704 6705 if((lvdshl >= 0) && (lvdshl <= 3)) 6706 sisfb_lvdshl = lvdshl; 6707 6708 sisfb_tvxposoffset = tvxposoffset; 6709 sisfb_tvyposoffset = tvyposoffset; 6710 6711 #if !defined(__i386__) && !defined(__x86_64__) 6712 sisfb_resetcard = (resetcard) ? 1 : 0; 6713 if(videoram) 6714 sisfb_videoram = videoram; 6715 #endif 6716 6717 return sisfb_init(); 6718 } 6719 6720 static void __exit sisfb_remove_module(void) 6721 { 6722 pci_unregister_driver(&sisfb_driver); 6723 printk(KERN_DEBUG "sisfb: Module unloaded\n"); 6724 } 6725 6726 module_init(sisfb_init_module); 6727 module_exit(sisfb_remove_module); 6728 6729 MODULE_DESCRIPTION("SiS 300/540/630/730/315/55x/65x/661/74x/330/76x/34x, XGI V3XT/V5/V8/Z7 framebuffer device driver"); 6730 MODULE_LICENSE("GPL"); 6731 MODULE_AUTHOR("Thomas Winischhofer <thomas@winischhofer.net>, Others"); 6732 6733 module_param(mem, int, 0); 6734 module_param(noaccel, int, 0); 6735 module_param(noypan, int, 0); 6736 module_param(nomax, int, 0); 6737 module_param(userom, int, 0); 6738 module_param(useoem, int, 0); 6739 module_param(mode, charp, 0); 6740 module_param(vesa, int, 0); 6741 module_param(rate, int, 0); 6742 module_param(forcecrt1, int, 0); 6743 module_param(forcecrt2type, charp, 0); 6744 module_param(scalelcd, int, 0); 6745 module_param(pdc, int, 0); 6746 module_param(pdc1, int, 0); 6747 module_param(specialtiming, charp, 0); 6748 module_param(lvdshl, int, 0); 6749 module_param(tvstandard, charp, 0); 6750 module_param(tvxposoffset, int, 0); 6751 module_param(tvyposoffset, int, 0); 6752 module_param(nocrt2rate, int, 0); 6753 #if !defined(__i386__) && !defined(__x86_64__) 6754 module_param(resetcard, int, 0); 6755 module_param(videoram, int, 0); 6756 #endif 6757 6758 MODULE_PARM_DESC(mem, 6759 "\nDetermines the beginning of the video memory heap in KB. This heap is used\n" 6760 "for video RAM management for eg. DRM/DRI. On 300 series, the default depends\n" 6761 "on the amount of video RAM available. If 8MB of video RAM or less is available,\n" 6762 "the heap starts at 4096KB, if between 8 and 16MB are available at 8192KB,\n" 6763 "otherwise at 12288KB. On 315/330/340 series, the heap size is 32KB by default.\n" 6764 "The value is to be specified without 'KB'.\n"); 6765 6766 MODULE_PARM_DESC(noaccel, 6767 "\nIf set to anything other than 0, 2D acceleration will be disabled.\n" 6768 "(default: 0)\n"); 6769 6770 MODULE_PARM_DESC(noypan, 6771 "\nIf set to anything other than 0, y-panning will be disabled and scrolling\n" 6772 "will be performed by redrawing the screen. (default: 0)\n"); 6773 6774 MODULE_PARM_DESC(nomax, 6775 "\nIf y-panning is enabled, sisfb will by default use the entire available video\n" 6776 "memory for the virtual screen in order to optimize scrolling performance. If\n" 6777 "this is set to anything other than 0, sisfb will not do this and thereby \n" 6778 "enable the user to positively specify a virtual Y size of the screen using\n" 6779 "fbset. (default: 0)\n"); 6780 6781 MODULE_PARM_DESC(mode, 6782 "\nSelects the desired default display mode in the format XxYxDepth,\n" 6783 "eg. 1024x768x16. Other formats supported include XxY-Depth and\n" 6784 "XxY-Depth@Rate. If the parameter is only one (decimal or hexadecimal)\n" 6785 "number, it will be interpreted as a VESA mode number. (default: 800x600x8)\n"); 6786 6787 MODULE_PARM_DESC(vesa, 6788 "\nSelects the desired default display mode by VESA defined mode number, eg.\n" 6789 "0x117 (default: 0x0103)\n"); 6790 6791 MODULE_PARM_DESC(rate, 6792 "\nSelects the desired vertical refresh rate for CRT1 (external VGA) in Hz.\n" 6793 "If the mode is specified in the format XxY-Depth@Rate, this parameter\n" 6794 "will be ignored (default: 60)\n"); 6795 6796 MODULE_PARM_DESC(forcecrt1, 6797 "\nNormally, the driver autodetects whether or not CRT1 (external VGA) is \n" 6798 "connected. With this option, the detection can be overridden (1=CRT1 ON,\n" 6799 "0=CRT1 OFF) (default: [autodetected])\n"); 6800 6801 MODULE_PARM_DESC(forcecrt2type, 6802 "\nIf this option is omitted, the driver autodetects CRT2 output devices, such as\n" 6803 "LCD, TV or secondary VGA. With this option, this autodetection can be\n" 6804 "overridden. Possible parameters are LCD, TV, VGA or NONE. NONE disables CRT2.\n" 6805 "On systems with a SiS video bridge, parameters SVIDEO, COMPOSITE or SCART can\n" 6806 "be used instead of TV to override the TV detection. Furthermore, on systems\n" 6807 "with a SiS video bridge, SVIDEO+COMPOSITE, HIVISION, YPBPR480I, YPBPR480P,\n" 6808 "YPBPR720P and YPBPR1080I are understood. However, whether or not these work\n" 6809 "depends on the very hardware in use. (default: [autodetected])\n"); 6810 6811 MODULE_PARM_DESC(scalelcd, 6812 "\nSetting this to 1 will force the driver to scale the LCD image to the panel's\n" 6813 "native resolution. Setting it to 0 will disable scaling; LVDS panels will\n" 6814 "show black bars around the image, TMDS panels will probably do the scaling\n" 6815 "themselves. Default: 1 on LVDS panels, 0 on TMDS panels\n"); 6816 6817 MODULE_PARM_DESC(pdc, 6818 "\nThis is for manually selecting the LCD panel delay compensation. The driver\n" 6819 "should detect this correctly in most cases; however, sometimes this is not\n" 6820 "possible. If you see 'small waves' on the LCD, try setting this to 4, 32 or 24\n" 6821 "on a 300 series chipset; 6 on other chipsets. If the problem persists, try\n" 6822 "other values (on 300 series: between 4 and 60 in steps of 4; otherwise: any\n" 6823 "value from 0 to 31). (default: autodetected, if LCD is active during start)\n"); 6824 6825 #ifdef CONFIG_FB_SIS_315 6826 MODULE_PARM_DESC(pdc1, 6827 "\nThis is same as pdc, but for LCD-via CRT1. Hence, this is for the 315/330/340\n" 6828 "series only. (default: autodetected if LCD is in LCD-via-CRT1 mode during\n" 6829 "startup) - Note: currently, this has no effect because LCD-via-CRT1 is not\n" 6830 "implemented yet.\n"); 6831 #endif 6832 6833 MODULE_PARM_DESC(specialtiming, 6834 "\nPlease refer to documentation for more information on this option.\n"); 6835 6836 MODULE_PARM_DESC(lvdshl, 6837 "\nPlease refer to documentation for more information on this option.\n"); 6838 6839 MODULE_PARM_DESC(tvstandard, 6840 "\nThis allows overriding the BIOS default for the TV standard. Valid choices are\n" 6841 "pal, ntsc, palm and paln. (default: [auto; pal or ntsc only])\n"); 6842 6843 MODULE_PARM_DESC(tvxposoffset, 6844 "\nRelocate TV output horizontally. Possible parameters: -32 through 32.\n" 6845 "Default: 0\n"); 6846 6847 MODULE_PARM_DESC(tvyposoffset, 6848 "\nRelocate TV output vertically. Possible parameters: -32 through 32.\n" 6849 "Default: 0\n"); 6850 6851 MODULE_PARM_DESC(nocrt2rate, 6852 "\nSetting this to 1 will force the driver to use the default refresh rate for\n" 6853 "CRT2 if CRT2 type is VGA. (default: 0, use same rate as CRT1)\n"); 6854 6855 #if !defined(__i386__) && !defined(__x86_64__) 6856 #ifdef CONFIG_FB_SIS_300 6857 MODULE_PARM_DESC(resetcard, 6858 "\nSet this to 1 in order to reset (POST) the card on non-x86 machines where\n" 6859 "the BIOS did not POST the card (only supported for SiS 300/305 and XGI cards\n" 6860 "currently). Default: 0\n"); 6861 6862 MODULE_PARM_DESC(videoram, 6863 "\nSet this to the amount of video RAM (in kilobyte) the card has. Required on\n" 6864 "some non-x86 architectures where the memory auto detection fails. Only\n" 6865 "relevant if resetcard is set, too. SiS300/305 only. Default: [auto-detect]\n"); 6866 #endif 6867 #endif 6868 6869 #endif /* /MODULE */ 6870 6871 /* _GPL only for new symbols. */ 6872 EXPORT_SYMBOL(sis_malloc); 6873 EXPORT_SYMBOL(sis_free); 6874 EXPORT_SYMBOL_GPL(sis_malloc_new); 6875 EXPORT_SYMBOL_GPL(sis_free_new); 6876 6877 6878 6879