sis_setup.c revision 72b676d7
1/* $XFree86$ */ 2/* $XdotOrg$ */ 3/* 4 * Basic hardware and memory detection 5 * 6 * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1) Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2) Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3) The name of the author may not be used to endorse or promote products 17 * derived from this software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 * 30 * Author: Thomas Winischhofer <thomas@winischhofer.net> 31 * 32 * Ideas and methods for old series based on code by Can-Ru Yeou, SiS Inc. 33 * 34 */ 35 36#ifdef HAVE_CONFIG_H 37#include "config.h" 38#endif 39 40#include "sis.h" 41#define SIS_NEED_inSISREGW 42#define SIS_NEED_inSISREGL 43#define SIS_NEED_outSISREGW 44#define SIS_NEED_outSISREGL 45#define SIS_NEED_inSISIDXREG 46#define SIS_NEED_outSISIDXREG 47#include "sis_regs.h" 48 49extern int SiSMclk(SISPtr pSiS); 50 51static const char *dramTypeStr[] = { 52 "Fast Page DRAM", 53 "2 cycle EDO RAM", 54 "1 cycle EDO RAM", 55 "SDRAM/SGRAM", 56 "SDR SDRAM", 57 "SGRAM", 58 "ESDRAM", 59 "DDR SDRAM", /* for 550/650/etc */ 60 "DDR SDRAM", /* for 550/650/etc */ 61 "VCM", /* for 630 */ 62 "DDR2 SDRAM", /* for 340 */ 63 "" 64}; 65 66/* MCLK tables for SiS6326 */ 67static const int SiS6326MCLKIndex[4][8] = { 68 { 10, 12, 14, 16, 17, 18, 19, 7 }, /* SGRAM */ 69 { 4, 6, 8, 10, 11, 12, 13, 3 }, /* Fast Page */ 70 { 9, 11, 12, 13, 15, 16, 5, 7 }, /* 2 cycle EDO */ 71 { 10, 12, 14, 16, 17, 18, 19, 7 } /* ? (Not 1 cycle EDO) */ 72}; 73 74static const struct _sis6326mclk { 75 CARD16 mclk; 76 UChar sr13; 77 UChar sr28; 78 UChar sr29; 79} SiS6326MCLK[] = { 80 { 0, 0, 0, 0 }, 81 { 0, 0, 0, 0 }, 82 { 0, 0, 0, 0 }, 83 { 45, 0, 0x2b, 0x26 }, 84 { 53, 0, 0x49, 0xe4 }, 85 { 55, 0, 0x7c, 0xe7 }, 86 { 56, 0, 0x7c, 0xe7 }, 87 { 60, 0, 0x42, 0xe3 }, 88 { 61, 0, 0x21, 0xe1 }, 89 { 65, 0, 0x5a, 0xe4 }, 90 { 66, 0, 0x5a, 0xe4 }, 91 { 70, 0, 0x61, 0xe4 }, 92 { 75, 0, 0x3e, 0xe2 }, 93 { 80, 0, 0x42, 0xe2 }, 94 { 83, 0, 0xb3, 0xc5 }, 95 { 85, 0, 0x5e, 0xe3 }, 96 { 90, 0, 0xae, 0xc4 }, 97 {100, 0, 0x37, 0xe1 }, 98 {115, 0, 0x78, 0x0e }, 99 {134, 0, 0x4a, 0xa3 } 100}; 101 102/* For old chipsets, 5597, 6326, 530/620 */ 103static void 104sisOldSetup(ScrnInfoPtr pScrn) 105{ 106 SISPtr pSiS = SISPTR(pScrn); 107 int ramsize[8] = { 1, 2, 4, 0, 0, 2, 4, 8}; 108 int buswidth[8] = {32, 64, 64, 0, 0, 32, 32, 64 }; 109 int clockTable[4] = { 66, 75, 83, 100 }; 110 int ramtype[4] = { 5, 0, 1, 3 }; 111 int config, temp, i; 112 UChar sr23, sr33, sr37; 113#if 0 114 UChar newsr13, newsr28, newsr29; 115#endif 116 pciConfigPtr pdptr, *systemPCIdevices = NULL; 117 118 if(pSiS->oldChipset <= OC_SIS6225) { 119 inSISIDXREG(SISSR, 0x0F, temp); 120 pScrn->videoRam = (1 << (temp & 0x03)) * 1024; 121 if(pScrn->videoRam > 4096) pScrn->videoRam = 4096; 122 pSiS->BusWidth = 32; 123 } else if(pSiS->Chipset == PCI_CHIP_SIS5597) { 124 inSISIDXREG(SISSR, 0x2F, temp); 125 pScrn->videoRam = ((temp & 0x07) + 1) * 256; 126 inSISIDXREG(SISSR, 0x0C, temp); 127 if(temp & 0x06) { 128 pScrn->videoRam *= 2; 129 pSiS->BusWidth = 64; 130 } else pSiS->BusWidth = 32; 131 } else { 132 inSISIDXREG(SISSR, 0x0C, temp); 133 config = ((temp & 0x10) >> 2 ) | ((temp & 0x06) >> 1); 134 pScrn->videoRam = ramsize[config] * 1024; 135 pSiS->BusWidth = buswidth[config]; 136 } 137 138 if(pSiS->Chipset == PCI_CHIP_SIS530) { 139 140 inSISIDXREG(SISSR, 0x0D, temp); 141 pSiS->Flags &= ~(UMA); 142 if(temp & 0x01) { 143 pSiS->Flags |= UMA; /* Shared fb mode */ 144 inSISIDXREG(SISSR, 0x10, temp); 145 pSiS->MemClock = clockTable[temp & 0x03] * 1000; 146 } else { 147 pSiS->MemClock = SiSMclk(pSiS); /* Local fb mode */ 148 } 149 150 } else if(pSiS->Chipset == PCI_CHIP_SIS6326) { 151 152 inSISIDXREG(SISSR,0x0e,temp); 153 154 i = temp & 0x03; 155 156 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 157 "DRAM type: %s\n", 158 dramTypeStr[ramtype[i]]); 159 160 temp = (temp >> 5) & 0x07; 161 i = SiS6326MCLKIndex[i][temp]; 162 pSiS->MemClock = SiS6326MCLK[i].mclk; 163#if 0 164 /* Correct invalid MCLK settings by old BIOSes */ 165 newsr13 = SiS6326MCLK[i].sr13; 166 newsr28 = SiS6326MCLK[i].sr28; 167 newsr29 = SiS6326MCLK[i].sr29; 168 if((pSiS->ChipRev == 0x92) || 169 (pSiS->ChipRev == 0xd1) || 170 (pSiS->ChipRev == 0xd2)) { 171 if(pSiS->MemClock == 60) { 172 newsr28 = 0xae; 173 newsr29 = 0xc4; 174 } 175 } 176#endif 177 pSiS->MemClock *= 1000; 178#if 0 179 inSISIDXREG(SISSR, 0x13, temp); 180 temp &= 0x80; 181 temp |= (newsr13 & 0x80); 182 outSISIDXREG(SISSR,0x13,temp); 183 outSISIDXREG(SISSR,0x28,newsr28); 184 outSISIDXREG(SISSR,0x29,newsr29); 185#endif 186 187 } else { 188 189 pSiS->MemClock = SiSMclk(pSiS); 190 191 } 192 193 pSiS->Flags &= ~(SYNCDRAM | RAMFLAG); 194 if(pSiS->oldChipset >= OC_SIS82204) { 195 inSISIDXREG(SISSR, 0x23, sr23); 196 inSISIDXREG(SISSR, 0x33, sr33); 197 if(pSiS->oldChipset >= OC_SIS530A) sr33 &= ~0x08; 198 if(sr33 & 0x09) { /* 5597: Sync DRAM timing | One cycle EDO ram; */ 199 pSiS->Flags |= (sr33 & SYNCDRAM); /* 6326: Enable SGRam timing | One cycle EDO ram */ 200 pSiS->Flags |= RAMFLAG; /* 530: Enable SGRAM timing | reserved (0) */ 201 } else if((pSiS->oldChipset < OC_SIS530A) && (sr23 & 0x20)) { 202 pSiS->Flags |= SYNCDRAM; /* 5597, 6326: EDO DRAM enabled */ 203 } /* 530/620: reserved (0) */ 204 } 205 206 pSiS->Flags &= ~(ESS137xPRESENT); 207 if(pSiS->Chipset == PCI_CHIP_SIS530) { 208 if(pSiS->oldChipset == OC_SIS530A) { 209 if((systemPCIdevices = xf86GetPciConfigInfo())) { 210 i = 0; 211 while((pdptr = systemPCIdevices[i])) { 212 if((pdptr->pci_vendor == 0x1274) && 213 ((pdptr->pci_device == 0x5000) || 214 ((pdptr->pci_device & 0xFFF0) == 0x1370))) { 215 pSiS->Flags |= ESS137xPRESENT; 216 break; 217 } 218 i++; 219 } 220 } 221 if(pSiS->Flags & ESS137xPRESENT) { 222 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 223 "SiS530/620: Found ESS device\n"); 224 } 225 } 226 } 227 228 pSiS->Flags &= ~(SECRETFLAG); 229 if(pSiS->oldChipset >= OC_SIS5597) { 230 inSISIDXREG(SISSR, 0x37, sr37); 231 if(sr37 & 0x80) pSiS->Flags |= SECRETFLAG; 232 } 233 234 pSiS->Flags &= ~(A6326REVAB); 235 if(pSiS->Chipset == PCI_CHIP_SIS6326) { 236 if(((pSiS->ChipRev & 0x0f) == 0x0a) || 237 ((pSiS->ChipRev & 0x0f) == 0x0b)) { 238 pSiS->Flags |= A6326REVAB; 239 } 240 } 241 242 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 243 "Memory clock: %3.3f MHz\n", 244 pSiS->MemClock/1000.0); 245 246 if(pSiS->oldChipset > OC_SIS6225) { 247 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 248 "DRAM bus width: %d bit\n", 249 pSiS->BusWidth); 250 } 251 252#ifdef TWDEBUG 253 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 254 "oldChipset = %d, Flags %x\n", pSiS->oldChipset, pSiS->Flags); 255#endif 256} 257 258static void 259sis300Setup(ScrnInfoPtr pScrn) 260{ 261 SISPtr pSiS = SISPTR(pScrn); 262 const int bus[4] = {32, 64, 128, 32}; 263 const int adaptermclk[8] = { 66, 83, 100, 133, 264 100, 100, 100, 100}; 265 const int adaptermclk300[8] = { 125, 125, 125, 100, 266 100, 100, 100, 100}; 267 unsigned int config, pciconfig, sr3a, ramtype; 268 UChar temp; 269 int cpubuswidth; 270 MessageType from = X_PROBED; 271 272 pSiS->MemClock = SiSMclk(pSiS); 273 274 inSISIDXREG(SISSR, 0x14, config); 275 cpubuswidth = bus[config >> 6]; 276 277 inSISIDXREG(SISSR, 0x3A, sr3a); 278 ramtype = (sr3a & 0x03) + 4; 279 280 pSiS->IsPCIExpress = FALSE; 281 282 switch(pSiS->Chipset) { 283 case PCI_CHIP_SIS300: 284 pScrn->videoRam = ((config & 0x3F) + 1) * 1024; 285 pSiS->LFBsize = pScrn->videoRam; 286 pSiS->BusWidth = cpubuswidth; 287 pSiS->IsAGPCard = ((sr3a & 0x30) == 0x30) ? FALSE : TRUE; 288 break; 289 case PCI_CHIP_SIS540: 290 case PCI_CHIP_SIS630: 291 pSiS->IsAGPCard = TRUE; 292 pciconfig = pciReadByte(0x00000000, 0x63); 293 if(pciconfig & 0x80) { 294 pScrn->videoRam = (1 << (((pciconfig & 0x70) >> 4) + 21)) / 1024; 295 pSiS->BusWidth = 64; 296 pciconfig = pciReadByte(0x00000000, 0x64); 297 if((pciconfig & 0x30) == 0x30) { 298 pSiS->BusWidth = 128; 299 pScrn->videoRam <<= 1; 300 } 301 ramtype = pciReadByte(0x00000000,0x65); 302 ramtype &= 0x03; 303 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 304 "Shared Memory Area is on DIMM%d\n", ramtype); 305 ramtype = pciReadByte(0x00000000,(0x60 + ramtype)); 306 if(ramtype & 0x80) ramtype = 9; 307 else ramtype = 4; 308 pSiS->UMAsize = pScrn->videoRam; 309 } else { 310 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 311 "Shared Memory Area is disabled - awaiting doom\n"); 312 pScrn->videoRam = ((config & 0x3F) + 1) * 1024; 313 pSiS->UMAsize = pScrn->videoRam; 314 pSiS->BusWidth = 64; 315 ramtype = 4; 316 from = X_INFO; 317 } 318 break; 319 default: 320 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 321 "Internal error: sis300setup() called with invalid chipset!\n"); 322 pSiS->BusWidth = 64; 323 from = X_INFO; 324 } 325 326 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 327 "DRAM type: %s\n", 328 dramTypeStr[ramtype]); 329 330 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 331 "Memory clock: %3.3f MHz\n", 332 pSiS->MemClock/1000.0); 333 334 if(pSiS->Chipset == PCI_CHIP_SIS300) { 335 if(pSiS->ChipRev > 0x13) { 336 inSISIDXREG(SISSR, 0x3A, temp); 337 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 338 "(Adapter assumes MCLK being %d Mhz)\n", 339 adaptermclk300[(temp & 0x07)]); 340 } 341 } else { 342 inSISIDXREG(SISSR, 0x1A, temp); 343 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 344 "(Adapter assumes MCLK being %d Mhz)\n", 345 adaptermclk[(temp & 0x07)]); 346 } 347 348 xf86DrvMsg(pScrn->scrnIndex, from, 349 "DRAM bus width: %d bit\n", 350 pSiS->BusWidth); 351} 352 353/* For 315, 315H, 315PRO/E, 330, 340 */ 354static void 355sis315Setup(ScrnInfoPtr pScrn) 356{ 357 SISPtr pSiS = SISPTR(pScrn); 358 int busSDR[4] = {64, 64, 128, 128}; 359 int busDDR[4] = {32, 32, 64, 64}; 360 int busDDRA[4] = {64+32, 64+32 , (64+32)*2, (64+32)*2}; 361 unsigned int config, config1, config2, sr3a, cr5f; 362 char *dramTypeStr315[] = { 363 "Single channel 1 rank SDR SDRAM", 364 "Single channel 1 rank SDR SGRAM", 365 "Single channel 1 rank DDR SDRAM", 366 "Single channel 1 rank DDR SGRAM", 367 "Single channel 2 rank SDR SDRAM", 368 "Single channel 2 rank SDR SGRAM", 369 "Single channel 2 rank DDR SDRAM", 370 "Single channel 2 rank DDR SGRAM", 371 "Asymmetric SDR SDRAM", 372 "Asymmetric SDR SGRAM", 373 "Asymmetric DDR SDRAM", 374 "Asymmetric DDR SGRAM", 375 "Dual channel SDR SDRAM", 376 "Dual channel SDR SGRAM", 377 "Dual channel DDR SDRAM", 378 "Dual channel DDR SGRAM" 379 }; 380 char *dramTypeStr330[] = { 381 "Single Channel SDR SDRAM", 382 "", 383 "Single Channel DDR SDRAM", 384 "", 385 "--unknown--", 386 "", 387 "--unknown--", 388 "", 389 "Asymetric Dual Channel SDR SDRAM", 390 "", 391 "Asymetric Dual Channel DDR SDRAM", 392 "", 393 "Dual channel SDR SDRAM", 394 "", 395 "Dual channel DDR SDRAM", 396 "" 397 }; 398 char *dramTypeStr340[] = { 399 "Single channel DDR SDRAM", 400 "Single channel DDR2 SDRAM", 401 "Single channel DDR2x SDRAM", 402 "", 403 "Dual channel DDR SDRAM", 404 "Dual channel DDR2 SDRAM", 405 "Dual channel DDR2x SDRAM", 406 "", 407 "Dual channel DDR SDRAM", 408 "Dual channel DDR2 SDRAM", 409 "Dual channel DDR2x SDRAM", 410 "", 411 "Quad channel DDR SDRAM", 412 "Quad channel DDR2 SDRAM", 413 "Quad channel DDR2x SDRAM", 414 "" 415 }; 416 417 inSISIDXREG(SISSR, 0x14, config); 418 config1 = (config & 0x0C) >> 2; 419 420 inSISIDXREG(SISSR, 0x3a, sr3a); 421 config2 = sr3a & 0x03; 422 423 inSISIDXREG(SISCR,0x5f,cr5f); 424 425 pScrn->videoRam = (1 << ((config & 0xf0) >> 4)) * 1024; 426 427 pSiS->IsPCIExpress = FALSE; 428 429 switch(pSiS->Chipset) { 430 431 case PCI_CHIP_SIS340: 432 case PCI_CHIP_XGIXG20: 433 case PCI_CHIP_XGIXG40: 434 435 if(pSiS->ChipType != XGI_20) { /* SIS340, XGI_40 */ 436 437 pSiS->IsAGPCard = TRUE; 438 439 if(pSiS->ChipRev == 2) { 440 if(config1 & 0x01) config1 = 0x02; 441 else config1 = 0x00; 442 } 443 if(config1 == 0x02) pScrn->videoRam <<= 1; /* dual rank */ 444 else if(config1 == 0x03) pScrn->videoRam <<= 2; /* quad rank */ 445 446 inSISIDXREG(SISSR, 0x39, config2); 447 config2 &= 0x02; 448 if(!config2) { 449 inSISIDXREG(SISSR, 0x3a, config2); 450 config2 = (config2 & 0x02) >> 1; 451 } 452 453 pSiS->BusWidth = (config & 0x02) ? 64 : 32; 454 455 } else { /* XGI_20 (Z7) */ 456 457 config1 = 0x00; 458 inSISIDXREG(SISCR, 0x97, config2); 459 config2 &= 0x01; 460 config2 <<= 1; /* 0 or 2 */ 461 462 pSiS->BusWidth = (config & 0x02) ? 32 : 463 ((config & 0x01) ? 16 : 8); 464 465 } 466 467 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 468 "DRAM type: %s\n", dramTypeStr340[(config1 * 4) + (config2 & 0x03)]); 469 470 pSiS->MemClock = SiSMclk(pSiS); 471 472 pSiS->MemClock *= 2; /* at least DDR */ 473 474 break; 475 476 case PCI_CHIP_SIS330: 477 478 pSiS->IsAGPCard = TRUE; 479 480 if(config1) pScrn->videoRam <<= 1; 481 482 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 483 "DRAM type: %s\n", dramTypeStr330[(config1 * 4) + (config2 & 0x02)]); 484 485 pSiS->MemClock = SiSMclk(pSiS); 486 487 if(config2 & 0x02) { 488 pSiS->MemClock *= 2; 489 if(config1 == 0x02) { 490 pSiS->BusWidth = busDDRA[0]; 491 } else { 492 pSiS->BusWidth = busDDR[(config & 0x02)]; 493 } 494 } else { 495 if(config1 == 0x02) { 496 pSiS->BusWidth = busDDRA[2]; 497 } else { 498 pSiS->BusWidth = busSDR[(config & 0x02)]; 499 } 500 } 501 502 break; 503 504 default: /* 315 */ 505 506 pSiS->IsAGPCard = ((sr3a & 0x30) == 0x30) ? FALSE : TRUE; 507 508 if(cr5f & 0x10) pSiS->ChipFlags |= SiSCF_Is315E; 509 510 /* If SINGLE_CHANNEL_2_RANK or DUAL_CHANNEL_1_RANK -> mem * 2 */ 511 if((config1 == 0x01) || (config1 == 0x03)) pScrn->videoRam <<= 1; 512 513 /* If DDR asymetric -> mem * 1,5 */ 514 if(config1 == 0x02) pScrn->videoRam += pScrn->videoRam/2; 515 516 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 517 "DRAM type: %s\n", dramTypeStr315[(config1 * 4) + config2]); 518 519 pSiS->MemClock = SiSMclk(pSiS); 520 521 /* If DDR -> memclock * 2 */ 522 if(config2 & 0x02) pSiS->MemClock *= 2; 523 524 if(config1 == 0x02) 525 pSiS->BusWidth = busDDRA[(config & 0x03)]; 526 else if(config2 & 0x02) 527 pSiS->BusWidth = busDDR[(config & 0x03)]; 528 else 529 pSiS->BusWidth = busSDR[(config & 0x03)]; 530 531 if(pSiS->ChipFlags & SiSCF_Is315E) { 532 inSISIDXREG(SISSR,0x15,config); 533 if(config & 0x10) pSiS->BusWidth = 32; 534 } 535 536 } 537 538 pSiS->LFBsize = pScrn->videoRam; 539 540 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 541 "Memory clock: %3.3f MHz\n", 542 pSiS->MemClock/1000.0); 543 544 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 545 "DRAM bus width: %d bit\n", 546 pSiS->BusWidth); 547} 548 549/* For 550, 65x, 740, 661, 741, 660, 760, 761 */ 550static void 551sis550Setup(ScrnInfoPtr pScrn) 552{ 553 SISPtr pSiS = SISPTR(pScrn); 554 unsigned int config, ramtype=0, i; 555 CARD8 pciconfig, temp; 556 Bool alldone = FALSE; 557 Bool ddrtimes2 = TRUE; 558 559 pSiS->IsAGPCard = TRUE; 560 pSiS->IsPCIExpress = FALSE; 561 pSiS->ChipFlags &= ~(SiSCF_760UMA | SiSCF_760LFB); 562 563 pSiS->MemClock = SiSMclk(pSiS); 564 565 if(pSiS->Chipset == PCI_CHIP_SIS660) { 566 567 if(pSiS->ChipType >= SIS_660) { 568 569 /* UMA - shared fb */ 570 pScrn->videoRam = 0; 571 pciconfig = pciReadByte(0x00000000, 0x4c); 572 if(pciconfig & 0xe0) { 573 pScrn->videoRam = (1 << (((pciconfig & 0xe0) >> 5) - 2)) * 32768; 574 pSiS->ChipFlags |= SiSCF_760UMA; 575 pSiS->SiS76xUMASize = pScrn->videoRam * 1024; 576 pSiS->UMAsize = pScrn->videoRam; 577 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 578 "%dK shared video RAM (UMA)\n", 579 pScrn->videoRam); 580 } 581 582 /* LFB - local framebuffer: PCI reg hold total RAM (but configurable in BIOS) */ 583 pciconfig = pciReadByte(0x00000800, 0xcd); 584 pciconfig = (pciconfig >> 1) & 0x03; 585 i = 0; 586 if(pciconfig == 0x01) i = 32768; 587 else if(pciconfig == 0x03) i = 65536; 588 if(i) { 589 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "%dK total local video RAM (LFB)\n", i); 590 } 591 592 /* LFB: CR78 holds amount of LFB memory configured in the BIOS setup */ 593 inSISIDXREG(SISCR, 0x78, config); 594 config &= 0x30; 595 if(config) { 596 i = 0; 597 if(config == 0x10) i = 32768; 598 else if(config == 0x30) i = 65536; 599 if(i) { 600 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "%dK configured local video RAM (LFB)\n", i); 601 pScrn->videoRam += i; 602 pSiS->ChipFlags |= SiSCF_760LFB; 603 pSiS->SiS76xLFBSize = i * 1024; 604 pSiS->LFBsize = i; 605 } 606 } 607 608 if((pScrn->videoRam < 32768) || (pScrn->videoRam > 131072)) { 609 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 610 "Illegal video RAM size (%dK) detected, using BIOS provided setting\n", 611 pScrn->videoRam); 612 pSiS->ChipFlags &= ~(SiSCF_760LFB | SiSCF_760UMA); 613 } else { 614 pSiS->BusWidth = 64; 615 ramtype = 8; 616 alldone = TRUE; 617 } 618 619 if(pSiS->ChipType >= SIS_761) { 620 pSiS->IsAGPCard = FALSE; 621 pSiS->IsPCIExpress = TRUE; 622 } 623 624 } else { /* 661, 741 */ 625 626 int dimmnum; 627 628 if(pSiS->ChipType == SIS_741) { 629 dimmnum = 4; 630 } else { 631 dimmnum = 3; 632 } 633 634 pciconfig = pciReadByte(0x00000000, 0x64); 635 if(pciconfig & 0x80) { 636 pScrn->videoRam = (1 << (((pciconfig & 0x70) >> 4) - 1)) * 32768; 637 pSiS->UMAsize = pScrn->videoRam; 638 if((pScrn->videoRam < 32768) || (pScrn->videoRam > (128 * 1024))) { 639 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 640 "Illegal video RAM size (%dK) detected, using BIOS-provided info\n", 641 pScrn->videoRam); 642 } else { 643 pSiS->BusWidth = 64; 644 for(i = 0; i <= (dimmnum - 1); i++) { 645 if(pciconfig & (1 << i)) { 646 temp = pciReadByte(0x00000000, 0x60 + i); 647 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 648 "DIMM%d is %s SDRAM\n", 649 i, (temp & 0x40) ? "DDR" : "SDR"); 650 } else { 651 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 652 "DIMM%d is not installed\n", i); 653 } 654 } 655 pciconfig = pciReadByte(0x00000000, 0x7c); 656 ramtype = (pciconfig & 0x02) ? 8 : 4; 657 alldone = TRUE; 658 } 659 } 660 661 } 662 663 } else if(pSiS->Chipset == PCI_CHIP_SIS650) { 664 665 pciconfig = pciReadByte(0x00000000, 0x64); 666 if(pciconfig & 0x80) { 667 pScrn->videoRam = (1 << (((pciconfig & 0x70) >> 4) + 22)) / 1024; 668 pSiS->UMAsize = pScrn->videoRam; 669 pSiS->BusWidth = 64; 670 for(i=0; i<=3; i++) { 671 if(pciconfig & (1 << i)) { 672 temp = pciReadByte(0x00000000, 0x60 + i); 673 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 674 "DIMM%d is %s SDRAM\n", 675 i, (temp & 0x40) ? "DDR" : "SDR"); 676 } else { 677 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 678 "DIMM%d is not installed\n", i); 679 } 680 } 681 pciconfig = pciReadByte(0x00000000, 0x7c); 682 if(pciconfig & 0x02) ramtype = 8; 683 else ramtype = 4; 684 alldone = TRUE; 685 } 686 687 } else { 688 689 pciconfig = pciReadByte(0x00000000, 0x63); 690 if(pciconfig & 0x80) { 691 pScrn->videoRam = (1 << (((pciconfig & 0x70) >> 4) + 21)) / 1024; 692 pSiS->UMAsize = pScrn->videoRam; 693 pSiS->BusWidth = 64; 694 ramtype = pciReadByte(0x00000000,0x65); 695 ramtype &= 0x01; 696 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 697 "Shared Memory Area is on DIMM%d\n", ramtype); 698 ramtype = 4; 699 alldone = TRUE; 700 } 701 702 } 703 704 /* Fall back to BIOS detection results in case of problems: */ 705 706 if(!alldone) { 707 708 pSiS->SiS76xLFBSize = pSiS->SiS76xUMASize = 0; 709 pSiS->UMAsize = pSiS->LFBsize = 0; 710 711 if(pSiS->Chipset == PCI_CHIP_SIS660) { 712 inSISIDXREG(SISCR, 0x79, config); 713 pSiS->BusWidth = (config & 0x04) ? 128 : 64; 714 ramtype = (config & 0x01) ? 8 : 4; 715 if(pSiS->ChipType >= SIS_660) { 716 pScrn->videoRam = 0; 717 if(config & 0xf0) { 718 pScrn->videoRam = (1 << ((config & 0xf0) >> 4)) * 1024; 719 pSiS->UMAsize = pScrn->videoRam; 720 pSiS->ChipFlags |= SiSCF_760UMA; 721 pSiS->SiS76xUMASize = pScrn->videoRam * 1024; 722 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 723 "%dK shared video RAM (UMA)\n", 724 pScrn->videoRam); 725 } 726 inSISIDXREG(SISCR, 0x78, config); 727 config &= 0x30; 728 if(config) { 729 i = 0; 730 if(config == 0x10) i = 32768; 731 else if(config == 0x30) i = 65536; 732 if(i) { 733 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 734 "%dK configured local video RAM (LFB)\n", i); 735 pScrn->videoRam += i; 736 pSiS->SiS76xLFBSize = i * 1024; 737 pSiS->LFBsize = i; 738 pSiS->ChipFlags |= SiSCF_760LFB; 739 740 } 741 } 742 } else { 743 pScrn->videoRam = (1 << ((config & 0xf0) >> 4)) * 1024; 744 pSiS->UMAsize = pScrn->videoRam; 745 } 746 } else { 747 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 748 "Shared Memory Area is disabled - awaiting doom\n"); 749 inSISIDXREG(SISSR, 0x14, config); 750 pScrn->videoRam = (((config & 0x3F) + 1) * 4) * 1024; 751 pSiS->UMAsize = pScrn->videoRam; 752 if(pSiS->Chipset == PCI_CHIP_SIS650) { 753 ramtype = (((config & 0x80) >> 7) << 2) + 4; 754 pSiS->BusWidth = 64; /* (config & 0x40) ? 128 : 64; */ 755 } else { 756 ramtype = 4; 757 pSiS->BusWidth = 64; 758 } 759 } 760 } 761 762 /* These need special attention: Memory controller in CPU, hence 763 * - no DDR * 2 for bandwidth calculation, 764 * - overlay magic (bandwidth dependent one/two overlay stuff) 765 */ 766 if((pSiS->ChipType >= SIS_760) && (pSiS->ChipType <= SIS_770)) { 767 if(!(pSiS->ChipFlags & SiSCF_760LFB)) { 768 ddrtimes2 = FALSE; 769 pSiS->SiS_SD2_Flags |= SiS_SD2_SUPPORT760OO; 770 } 771 } 772 773 /* DDR -> Mclk * 2 - needed for bandwidth calculation */ 774 if(ddrtimes2) { 775 if(ramtype == 8) pSiS->MemClock *= 2; 776 } 777 778 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 779 "DRAM type: %s\n", 780 dramTypeStr[ramtype]); 781 782 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 783 "Memory clock: %3.3f MHz\n", 784 pSiS->MemClock/1000.0); 785 786 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 787 "DRAM bus width: %d bit\n", 788 pSiS->BusWidth); 789} 790 791void 792SiSSetup(ScrnInfoPtr pScrn) 793{ 794 SISPtr pSiS = SISPTR(pScrn); 795 796 pSiS->Flags = 0; 797 pSiS->VBFlags = 0; 798 pSiS->SiS76xLFBSize = pSiS->SiS76xUMASize = 0; 799 pSiS->UMAsize = pSiS->LFBsize = 0; 800 801 switch (SISPTR(pScrn)->Chipset) { 802 case PCI_CHIP_SIS300: 803 case PCI_CHIP_SIS630: /* +730 */ 804 case PCI_CHIP_SIS540: 805 sis300Setup(pScrn); 806 break; 807 case PCI_CHIP_SIS315: 808 case PCI_CHIP_SIS315H: 809 case PCI_CHIP_SIS315PRO: 810 case PCI_CHIP_SIS330: 811 case PCI_CHIP_SIS340: 812 case PCI_CHIP_XGIXG20: 813 case PCI_CHIP_XGIXG40: 814 sis315Setup(pScrn); 815 break; 816 case PCI_CHIP_SIS550: 817 case PCI_CHIP_SIS650: /* + 740,M650,651 */ 818 case PCI_CHIP_SIS660: /* + (M)661,(M)741,(M)760(GX), (M)761(GX), 770? */ 819 sis550Setup(pScrn); 820 break; 821 case PCI_CHIP_SIS5597: 822 case PCI_CHIP_SIS6326: 823 case PCI_CHIP_SIS530: 824 default: 825 sisOldSetup(pScrn); 826 break; 827 } 828} 829 830 831