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