SiS driver:
[xf86-video-sis/mirage.git] / src / sis_setup.c
blobc2271cceac8466d58899f1064ebff981d24f373c
1 /* $XFree86$ */
2 /* $XdotOrg$ */
3 /*
4 * Basic hardware and memory detection
6 * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria.
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.
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.
30 * Author: Thomas Winischhofer <thomas@winischhofer.net>
32 * Ideas and methods for old series based on code by Can-Ru Yeou, SiS Inc.
36 #include "sis.h"
37 #define SIS_NEED_inSISREGW
38 #define SIS_NEED_inSISREGL
39 #define SIS_NEED_outSISREGW
40 #define SIS_NEED_outSISREGL
41 #define SIS_NEED_inSISIDXREG
42 #define SIS_NEED_outSISIDXREG
43 #include "sis_regs.h"
45 extern int SiSMclk(SISPtr pSiS);
47 static const char *dramTypeStr[] = {
48 "Fast Page DRAM",
49 "2 cycle EDO RAM",
50 "1 cycle EDO RAM",
51 "SDRAM/SGRAM",
52 "SDR SDRAM",
53 "SGRAM",
54 "ESDRAM",
55 "DDR SDRAM", /* for 550/650/etc */
56 "DDR SDRAM", /* for 550/650/etc */
57 "VCM", /* for 630 */
58 "DDR2 SDRAM", /* for 340 */
62 /* MCLK tables for SiS6326 */
63 static const int SiS6326MCLKIndex[4][8] = {
64 { 10, 12, 14, 16, 17, 18, 19, 7 }, /* SGRAM */
65 { 4, 6, 8, 10, 11, 12, 13, 3 }, /* Fast Page */
66 { 9, 11, 12, 13, 15, 16, 5, 7 }, /* 2 cycle EDO */
67 { 10, 12, 14, 16, 17, 18, 19, 7 } /* ? (Not 1 cycle EDO) */
70 static const struct _sis6326mclk {
71 CARD16 mclk;
72 UChar sr13;
73 UChar sr28;
74 UChar sr29;
75 } SiS6326MCLK[] = {
76 { 0, 0, 0, 0 },
77 { 0, 0, 0, 0 },
78 { 0, 0, 0, 0 },
79 { 45, 0, 0x2b, 0x26 },
80 { 53, 0, 0x49, 0xe4 },
81 { 55, 0, 0x7c, 0xe7 },
82 { 56, 0, 0x7c, 0xe7 },
83 { 60, 0, 0x42, 0xe3 },
84 { 61, 0, 0x21, 0xe1 },
85 { 65, 0, 0x5a, 0xe4 },
86 { 66, 0, 0x5a, 0xe4 },
87 { 70, 0, 0x61, 0xe4 },
88 { 75, 0, 0x3e, 0xe2 },
89 { 80, 0, 0x42, 0xe2 },
90 { 83, 0, 0xb3, 0xc5 },
91 { 85, 0, 0x5e, 0xe3 },
92 { 90, 0, 0xae, 0xc4 },
93 {100, 0, 0x37, 0xe1 },
94 {115, 0, 0x78, 0x0e },
95 {134, 0, 0x4a, 0xa3 }
98 /* For old chipsets, 5597, 6326, 530/620 */
99 static void
100 sisOldSetup(ScrnInfoPtr pScrn)
102 SISPtr pSiS = SISPTR(pScrn);
103 int ramsize[8] = { 1, 2, 4, 0, 0, 2, 4, 8};
104 int buswidth[8] = {32, 64, 64, 0, 0, 32, 32, 64 };
105 int clockTable[4] = { 66, 75, 83, 100 };
106 int ramtype[4] = { 5, 0, 1, 3 };
107 int config, temp, i;
108 UChar sr23, sr33, sr37;
109 #if 0
110 UChar newsr13, newsr28, newsr29;
111 #endif
112 pciConfigPtr pdptr, *systemPCIdevices = NULL;
114 if(pSiS->oldChipset <= OC_SIS6225) {
115 inSISIDXREG(SISSR, 0x0F, temp);
116 pScrn->videoRam = (1 << (temp & 0x03)) * 1024;
117 if(pScrn->videoRam > 4096) pScrn->videoRam = 4096;
118 pSiS->BusWidth = 32;
119 } else if(pSiS->Chipset == PCI_CHIP_SIS5597) {
120 inSISIDXREG(SISSR, 0x2F, temp);
121 pScrn->videoRam = ((temp & 0x07) + 1) * 256;
122 inSISIDXREG(SISSR, 0x0C, temp);
123 if(temp & 0x06) {
124 pScrn->videoRam *= 2;
125 pSiS->BusWidth = 64;
126 } else pSiS->BusWidth = 32;
127 } else {
128 inSISIDXREG(SISSR, 0x0C, temp);
129 config = ((temp & 0x10) >> 2 ) | ((temp & 0x06) >> 1);
130 pScrn->videoRam = ramsize[config] * 1024;
131 pSiS->BusWidth = buswidth[config];
134 if(pSiS->Chipset == PCI_CHIP_SIS530) {
136 inSISIDXREG(SISSR, 0x0D, temp);
137 pSiS->Flags &= ~(UMA);
138 if(temp & 0x01) {
139 pSiS->Flags |= UMA; /* Shared fb mode */
140 inSISIDXREG(SISSR, 0x10, temp);
141 pSiS->MemClock = clockTable[temp & 0x03] * 1000;
142 } else {
143 pSiS->MemClock = SiSMclk(pSiS); /* Local fb mode */
146 } else if(pSiS->Chipset == PCI_CHIP_SIS6326) {
148 inSISIDXREG(SISSR,0x0e,temp);
150 i = temp & 0x03;
152 xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
153 "DRAM type: %s\n",
154 dramTypeStr[ramtype[i]]);
156 temp = (temp >> 5) & 0x07;
157 i = SiS6326MCLKIndex[i][temp];
158 pSiS->MemClock = SiS6326MCLK[i].mclk;
159 #if 0
160 /* Correct invalid MCLK settings by old BIOSes */
161 newsr13 = SiS6326MCLK[i].sr13;
162 newsr28 = SiS6326MCLK[i].sr28;
163 newsr29 = SiS6326MCLK[i].sr29;
164 if((pSiS->ChipRev == 0x92) ||
165 (pSiS->ChipRev == 0xd1) ||
166 (pSiS->ChipRev == 0xd2)) {
167 if(pSiS->MemClock == 60) {
168 newsr28 = 0xae;
169 newsr29 = 0xc4;
172 #endif
173 pSiS->MemClock *= 1000;
174 #if 0
175 inSISIDXREG(SISSR, 0x13, temp);
176 temp &= 0x80;
177 temp |= (newsr13 & 0x80);
178 outSISIDXREG(SISSR,0x13,temp);
179 outSISIDXREG(SISSR,0x28,newsr28);
180 outSISIDXREG(SISSR,0x29,newsr29);
181 #endif
183 } else {
185 pSiS->MemClock = SiSMclk(pSiS);
189 pSiS->Flags &= ~(SYNCDRAM | RAMFLAG);
190 if(pSiS->oldChipset >= OC_SIS82204) {
191 inSISIDXREG(SISSR, 0x23, sr23);
192 inSISIDXREG(SISSR, 0x33, sr33);
193 if(pSiS->oldChipset >= OC_SIS530A) sr33 &= ~0x08;
194 if(sr33 & 0x09) { /* 5597: Sync DRAM timing | One cycle EDO ram; */
195 pSiS->Flags |= (sr33 & SYNCDRAM); /* 6326: Enable SGRam timing | One cycle EDO ram */
196 pSiS->Flags |= RAMFLAG; /* 530: Enable SGRAM timing | reserved (0) */
197 } else if((pSiS->oldChipset < OC_SIS530A) && (sr23 & 0x20)) {
198 pSiS->Flags |= SYNCDRAM; /* 5597, 6326: EDO DRAM enabled */
199 } /* 530/620: reserved (0) */
202 pSiS->Flags &= ~(ESS137xPRESENT);
203 if(pSiS->Chipset == PCI_CHIP_SIS530) {
204 if(pSiS->oldChipset == OC_SIS530A) {
205 if((systemPCIdevices = xf86GetPciConfigInfo())) {
206 i = 0;
207 while((pdptr = systemPCIdevices[i])) {
208 if((pdptr->pci_vendor == 0x1274) &&
209 ((pdptr->pci_device == 0x5000) ||
210 ((pdptr->pci_device & 0xFFF0) == 0x1370))) {
211 pSiS->Flags |= ESS137xPRESENT;
212 break;
214 i++;
217 if(pSiS->Flags & ESS137xPRESENT) {
218 xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
219 "SiS530/620: Found ESS device\n");
224 pSiS->Flags &= ~(SECRETFLAG);
225 if(pSiS->oldChipset >= OC_SIS5597) {
226 inSISIDXREG(SISSR, 0x37, sr37);
227 if(sr37 & 0x80) pSiS->Flags |= SECRETFLAG;
230 pSiS->Flags &= ~(A6326REVAB);
231 if(pSiS->Chipset == PCI_CHIP_SIS6326) {
232 if(((pSiS->ChipRev & 0x0f) == 0x0a) ||
233 ((pSiS->ChipRev & 0x0f) == 0x0b)) {
234 pSiS->Flags |= A6326REVAB;
238 xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
239 "Memory clock: %3.3f MHz\n",
240 pSiS->MemClock/1000.0);
242 if(pSiS->oldChipset > OC_SIS6225) {
243 xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
244 "DRAM bus width: %d bit\n",
245 pSiS->BusWidth);
248 #ifdef TWDEBUG
249 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
250 "oldChipset = %d, Flags %x\n", pSiS->oldChipset, pSiS->Flags);
251 #endif
254 static void
255 sis300Setup(ScrnInfoPtr pScrn)
257 SISPtr pSiS = SISPTR(pScrn);
258 const int bus[4] = {32, 64, 128, 32};
259 const int adaptermclk[8] = { 66, 83, 100, 133,
260 100, 100, 100, 100};
261 const int adaptermclk300[8] = { 125, 125, 125, 100,
262 100, 100, 100, 100};
263 unsigned int config, pciconfig, sr3a, ramtype;
264 UChar temp;
265 int cpubuswidth;
266 MessageType from = X_PROBED;
268 pSiS->MemClock = SiSMclk(pSiS);
270 inSISIDXREG(SISSR, 0x14, config);
271 cpubuswidth = bus[config >> 6];
273 inSISIDXREG(SISSR, 0x3A, sr3a);
274 ramtype = (sr3a & 0x03) + 4;
276 switch(pSiS->Chipset) {
277 case PCI_CHIP_SIS300:
278 pScrn->videoRam = ((config & 0x3F) + 1) * 1024;
279 pSiS->BusWidth = cpubuswidth;
280 pSiS->IsAGPCard = ((sr3a & 0x30) == 0x30) ? FALSE : TRUE;
281 break;
282 case PCI_CHIP_SIS540:
283 case PCI_CHIP_SIS630:
284 pSiS->IsAGPCard = TRUE;
285 pciconfig = pciReadByte(0x00000000, 0x63);
286 if(pciconfig & 0x80) {
287 pScrn->videoRam = (1 << (((pciconfig & 0x70) >> 4) + 21)) / 1024;
288 pSiS->BusWidth = 64;
289 pciconfig = pciReadByte(0x00000000, 0x64);
290 if((pciconfig & 0x30) == 0x30) {
291 pSiS->BusWidth = 128;
292 pScrn->videoRam <<= 1;
294 ramtype = pciReadByte(0x00000000,0x65);
295 ramtype &= 0x03;
296 xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
297 "Shared Memory Area is on DIMM%d\n", ramtype);
298 ramtype = pciReadByte(0x00000000,(0x60 + ramtype));
299 if(ramtype & 0x80) ramtype = 9;
300 else ramtype = 4;
301 } else {
302 xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
303 "Shared Memory Area is disabled - awaiting doom\n");
304 pScrn->videoRam = ((config & 0x3F) + 1) * 1024;
305 pSiS->BusWidth = 64;
306 ramtype = 4;
307 from = X_INFO;
309 break;
310 default:
311 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
312 "Internal error: sis300setup() called with invalid chipset!\n");
313 pSiS->BusWidth = 64;
314 from = X_INFO;
317 xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
318 "DRAM type: %s\n",
319 dramTypeStr[ramtype]);
321 xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
322 "Memory clock: %3.3f MHz\n",
323 pSiS->MemClock/1000.0);
325 if(pSiS->Chipset == PCI_CHIP_SIS300) {
326 if(pSiS->ChipRev > 0x13) {
327 inSISIDXREG(SISSR, 0x3A, temp);
328 xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
329 "(Adapter assumes MCLK being %d Mhz)\n",
330 adaptermclk300[(temp & 0x07)]);
332 } else {
333 inSISIDXREG(SISSR, 0x1A, temp);
334 xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
335 "(Adapter assumes MCLK being %d Mhz)\n",
336 adaptermclk[(temp & 0x07)]);
339 xf86DrvMsg(pScrn->scrnIndex, from,
340 "DRAM bus width: %d bit\n",
341 pSiS->BusWidth);
344 /* For 315, 315H, 315PRO/E, 330, 340 */
345 static void
346 sis315Setup(ScrnInfoPtr pScrn)
348 SISPtr pSiS = SISPTR(pScrn);
349 int busSDR[4] = {64, 64, 128, 128};
350 int busDDR[4] = {32, 32, 64, 64};
351 int busDDRA[4] = {64+32, 64+32 , (64+32)*2, (64+32)*2};
352 unsigned int config, config1, config2, sr3a, cr5f;
353 char *dramTypeStr315[] = {
354 "Single channel 1 rank SDR SDRAM",
355 "Single channel 1 rank SDR SGRAM",
356 "Single channel 1 rank DDR SDRAM",
357 "Single channel 1 rank DDR SGRAM",
358 "Single channel 2 rank SDR SDRAM",
359 "Single channel 2 rank SDR SGRAM",
360 "Single channel 2 rank DDR SDRAM",
361 "Single channel 2 rank DDR SGRAM",
362 "Asymmetric SDR SDRAM",
363 "Asymmetric SDR SGRAM",
364 "Asymmetric DDR SDRAM",
365 "Asymmetric DDR SGRAM",
366 "Dual channel SDR SDRAM",
367 "Dual channel SDR SGRAM",
368 "Dual channel DDR SDRAM",
369 "Dual channel DDR SGRAM"
371 char *dramTypeStr330[] = {
372 "Single Channel SDR SDRAM",
374 "Single Channel DDR SDRAM",
376 "--unknown--",
378 "--unknown--",
380 "Asymetric Dual Channel SDR SDRAM",
382 "Asymetric Dual Channel DDR SDRAM",
384 "Dual channel SDR SDRAM",
386 "Dual channel DDR SDRAM",
389 char *dramTypeStr340[] = {
390 "Single channel 1 Rank DDR SDRAM",
391 "Single channel 1 Rank DDR2 SDRAM",
392 "Single channel 1 Rank DDR2x SDRAM",
394 "Single channel 2 Rank DDR SDRAM",
395 "Single channel 2 Rank DDR2 SDRAM",
396 "Single channel 2 Rank DDR2x SDRAM",
398 "Dual channel 1 rank DDR SDRAM",
399 "Dual channel 1 rank DDR2 SDRAM",
400 "Dual channel 1 rank DDR2x SDRAM",
402 "Quad channel 1 rank DDR SDRAM",
403 "Quad channel 1 rank DDR2 SDRAM",
404 "Quad channel 1 rank DDR2x SDRAM",
408 inSISIDXREG(SISSR, 0x14, config);
409 config1 = (config & 0x0C) >> 2;
411 inSISIDXREG(SISSR, 0x3a, sr3a);
412 config2 = sr3a & 0x03;
414 inSISIDXREG(SISCR,0x5f,cr5f);
416 pScrn->videoRam = (1 << ((config & 0xf0) >> 4)) * 1024;
418 switch(pSiS->Chipset) {
420 case PCI_CHIP_SIS340:
422 pSiS->IsAGPCard = TRUE;
424 if(config1 == 0x02) pScrn->videoRam <<= 1; /* dual rank */
425 else if(config1 == 0x03) pScrn->videoRam <<= 2; /* quad rank */
427 inSISIDXREG(SISSR, 0x39, config2);
428 config2 &= 0x02;
429 if(!config2) {
430 inSISIDXREG(SISSR, 0x3a, config2);
431 config2 = (config2 & 0x02) >> 1;
434 xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
435 "DRAM type: %s\n", dramTypeStr340[(config1 * 4) + (config2 & 0x03)]);
437 pSiS->MemClock = SiSMclk(pSiS);
439 pSiS->MemClock *= 2; /* at least DDR */
441 inSISIDXREG(SISCR,0x97,config);
442 if(!(config & 0x10)) {
443 inSISIDXREG(SISSR,0x39,config);
444 config = (config & 0x02) >> 1;
445 } else config &= 0x01;
447 if(config) {
448 pSiS->MemClock *= 2; /* DDR2 ? */
449 pSiS->BusWidth = 32; /* DDR2 ? */
450 } else {
451 pSiS->BusWidth = 64;
454 break;
456 case PCI_CHIP_SIS330:
458 pSiS->IsAGPCard = TRUE;
460 if(config1) pScrn->videoRam <<= 1;
462 xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
463 "DRAM type: %s\n", dramTypeStr330[(config1 * 4) + (config2 & 0x02)]);
465 pSiS->MemClock = SiSMclk(pSiS);
467 if(config2 & 0x02) {
468 pSiS->MemClock *= 2;
469 if(config1 == 0x02) {
470 pSiS->BusWidth = busDDRA[0];
471 } else {
472 pSiS->BusWidth = busDDR[(config & 0x02)];
474 } else {
475 if(config1 == 0x02) {
476 pSiS->BusWidth = busDDRA[2];
477 } else {
478 pSiS->BusWidth = busSDR[(config & 0x02)];
482 break;
484 default: /* 315 */
486 pSiS->IsAGPCard = ((sr3a & 0x30) == 0x30) ? FALSE : TRUE;
488 if(cr5f & 0x10) pSiS->ChipFlags |= SiSCF_Is315E;
490 /* If SINGLE_CHANNEL_2_RANK or DUAL_CHANNEL_1_RANK -> mem * 2 */
491 if((config1 == 0x01) || (config1 == 0x03)) pScrn->videoRam <<= 1;
493 /* If DDR asymetric -> mem * 1,5 */
494 if(config1 == 0x02) pScrn->videoRam += pScrn->videoRam/2;
496 xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
497 "DRAM type: %s\n", dramTypeStr315[(config1 * 4) + config2]);
499 pSiS->MemClock = SiSMclk(pSiS);
501 /* If DDR -> memclock * 2 */
502 if(config2 & 0x02) pSiS->MemClock *= 2;
504 if(config1 == 0x02)
505 pSiS->BusWidth = busDDRA[(config & 0x03)];
506 else if(config2 & 0x02)
507 pSiS->BusWidth = busDDR[(config & 0x03)];
508 else
509 pSiS->BusWidth = busSDR[(config & 0x03)];
511 if(pSiS->ChipFlags & SiSCF_Is315E) {
512 inSISIDXREG(SISSR,0x15,config);
513 if(config & 0x10) pSiS->BusWidth = 32;
518 xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
519 "Memory clock: %3.3f MHz\n",
520 pSiS->MemClock/1000.0);
522 xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
523 "DRAM bus width: %d bit\n",
524 pSiS->BusWidth);
527 /* For 550, 65x, 740, 661, 741, 660, 760, 761 */
528 static void
529 sis550Setup(ScrnInfoPtr pScrn)
531 SISPtr pSiS = SISPTR(pScrn);
532 unsigned int config, ramtype=0, i;
533 CARD8 pciconfig, temp;
534 Bool alldone = FALSE;
535 Bool ddrtimes2 = TRUE;
537 pSiS->IsAGPCard = TRUE;
538 pSiS->ChipFlags &= ~(SiSCF_760UMA | SiSCF_760LFB);
540 pSiS->MemClock = SiSMclk(pSiS);
542 if(pSiS->Chipset == PCI_CHIP_SIS660) {
544 if(pSiS->sishw_ext.jChipType >= SIS_660) {
546 /* UMA - shared fb */
547 pScrn->videoRam = 0;
548 pciconfig = pciReadByte(0x00000000, 0x4c);
549 if(pciconfig & 0xe0) {
550 pScrn->videoRam = (1 << (((pciconfig & 0xe0) >> 5) - 2)) * 32768;
551 pSiS->ChipFlags |= SiSCF_760UMA;
552 pSiS->SiS76xUMASize = pScrn->videoRam * 1024;
553 xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
554 "%dK shared video RAM (UMA)\n",
555 pScrn->videoRam);
558 /* LFB - local framebuffer: PCI reg hold total RAM (but configurable in BIOS) */
559 pciconfig = pciReadByte(0x00000800, 0xcd);
560 pciconfig = (pciconfig >> 1) & 0x03;
561 i = 0;
562 if(pciconfig == 0x01) i = 32768;
563 else if(pciconfig == 0x03) i = 65536;
564 if(i) {
565 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "%dK total local video RAM (LFB)\n", i);
568 /* LFB: CR78 holds amount of LFB memory configured in the BIOS setup */
569 inSISIDXREG(SISCR, 0x78, config);
570 config &= 0x30;
571 if(config) {
572 i = 0;
573 if(config == 0x10) i = 32768;
574 else if(config == 0x30) i = 65536;
575 if(i) {
576 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "%dK configured local video RAM (LFB)\n", i);
577 pScrn->videoRam += i;
578 pSiS->ChipFlags |= SiSCF_760LFB;
579 pSiS->SiS76xLFBSize = i * 1024;
583 if((pScrn->videoRam < 32768) || (pScrn->videoRam > 131072)) {
584 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
585 "Illegal video RAM size (%dK) detected, using BIOS provided setting\n",
586 pScrn->videoRam);
587 pSiS->ChipFlags &= ~(SiSCF_760LFB | SiSCF_760UMA);
588 } else {
589 pSiS->BusWidth = 64;
590 ramtype = 8;
591 alldone = TRUE;
594 } else { /* 661, 741 */
596 int dimmnum;
598 if(pSiS->sishw_ext.jChipType == SIS_741) {
599 dimmnum = 4;
600 } else {
601 dimmnum = 3;
604 pciconfig = pciReadByte(0x00000000, 0x64);
605 if(pciconfig & 0x80) {
606 pScrn->videoRam = (1 << (((pciconfig & 0x70) >> 4) - 1)) * 32768;
607 if((pScrn->videoRam < 32768) || (pScrn->videoRam > (128 * 1024))) {
608 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
609 "Illegal video RAM size (%dK) detected, using BIOS-provided info\n",
610 pScrn->videoRam);
611 } else {
612 pSiS->BusWidth = 64;
613 for(i = 0; i <= (dimmnum - 1); i++) {
614 if(pciconfig & (1 << i)) {
615 temp = pciReadByte(0x00000000, 0x60 + i);
616 xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
617 "DIMM%d is %s SDRAM\n",
618 i, (temp & 0x40) ? "DDR" : "SDR");
619 } else {
620 xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
621 "DIMM%d is not installed\n", i);
624 pciconfig = pciReadByte(0x00000000, 0x7c);
625 ramtype = (pciconfig & 0x02) ? 8 : 4;
626 alldone = TRUE;
632 } else if(pSiS->Chipset == PCI_CHIP_SIS650) {
634 pciconfig = pciReadByte(0x00000000, 0x64);
635 if(pciconfig & 0x80) {
636 pScrn->videoRam = (1 << (((pciconfig & 0x70) >> 4) + 22)) / 1024;
637 pSiS->BusWidth = 64;
638 for(i=0; i<=3; i++) {
639 if(pciconfig & (1 << i)) {
640 temp = pciReadByte(0x00000000, 0x60 + i);
641 xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
642 "DIMM%d is %s SDRAM\n",
643 i, (temp & 0x40) ? "DDR" : "SDR");
644 } else {
645 xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
646 "DIMM%d is not installed\n", i);
649 pciconfig = pciReadByte(0x00000000, 0x7c);
650 if(pciconfig & 0x02) ramtype = 8;
651 else ramtype = 4;
652 alldone = TRUE;
655 } else {
657 pciconfig = pciReadByte(0x00000000, 0x63);
658 if(pciconfig & 0x80) {
659 pScrn->videoRam = (1 << (((pciconfig & 0x70) >> 4) + 21)) / 1024;
660 pSiS->BusWidth = 64;
661 ramtype = pciReadByte(0x00000000,0x65);
662 ramtype &= 0x01;
663 xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
664 "Shared Memory Area is on DIMM%d\n", ramtype);
665 ramtype = 4;
666 alldone = TRUE;
671 /* Fall back to BIOS detection results in case of problems: */
673 if(!alldone) {
675 pSiS->SiS76xLFBSize = pSiS->SiS76xUMASize = 0;
677 if(pSiS->Chipset == PCI_CHIP_SIS660) {
678 inSISIDXREG(SISCR, 0x79, config);
679 pSiS->BusWidth = (config & 0x04) ? 128 : 64;
680 ramtype = (config & 0x01) ? 8 : 4;
681 if(pSiS->sishw_ext.jChipType >= SIS_660) {
682 pScrn->videoRam = 0;
683 if(config & 0xf0) {
684 pScrn->videoRam = (1 << ((config & 0xf0) >> 4)) * 1024;
685 pSiS->ChipFlags |= SiSCF_760UMA;
686 pSiS->SiS76xUMASize = pScrn->videoRam * 1024;
687 xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
688 "%dK shared video RAM (UMA)\n",
689 pScrn->videoRam);
691 inSISIDXREG(SISCR, 0x78, config);
692 config &= 0x30;
693 if(config) {
694 if(config == 0x10) {
695 pScrn->videoRam += 32768;
696 pSiS->SiS76xLFBSize = 32768 * 1024;
697 } else {
698 pScrn->videoRam += 65536;
699 pSiS->SiS76xLFBSize = 65536 * 1024;
701 pSiS->ChipFlags |= SiSCF_760LFB;
702 xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
703 "%dK configured local video RAM (LFB)\n",
704 pSiS->SiS76xLFBSize / 1024);
706 } else {
707 pScrn->videoRam = (1 << ((config & 0xf0) >> 4)) * 1024;
709 } else {
710 xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
711 "Shared Memory Area is disabled - awaiting doom\n");
712 inSISIDXREG(SISSR, 0x14, config);
713 pScrn->videoRam = (((config & 0x3F) + 1) * 4) * 1024;
714 if(pSiS->Chipset == PCI_CHIP_SIS650) {
715 ramtype = (((config & 0x80) >> 7) << 2) + 4;
716 pSiS->BusWidth = 64; /* (config & 0x40) ? 128 : 64; */
717 } else {
718 ramtype = 4;
719 pSiS->BusWidth = 64;
724 /* These need special attention: Memory controller in CPU, hence
725 * - no DDR * 2 for bandwidth calculation,
726 * - overlay magic (bandwidth dependent one/two overlay stuff)
728 if((pSiS->sishw_ext.jChipType >= SIS_760) && (pSiS->sishw_ext.jChipType <= SIS_770)) {
729 if(!(pSiS->ChipFlags & SiSCF_760LFB)) {
730 ddrtimes2 = FALSE;
731 pSiS->SiS_SD2_Flags |= SiS_SD2_SUPPORT760OO;
735 /* DDR -> Mclk * 2 - needed for bandwidth calculation */
736 if(ddrtimes2) {
737 if(ramtype == 8) pSiS->MemClock *= 2;
740 xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
741 "DRAM type: %s\n",
742 dramTypeStr[ramtype]);
744 xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
745 "Memory clock: %3.3f MHz\n",
746 pSiS->MemClock/1000.0);
748 xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
749 "DRAM bus width: %d bit\n",
750 pSiS->BusWidth);
753 void
754 SiSSetup(ScrnInfoPtr pScrn)
756 SISPtr pSiS = SISPTR(pScrn);
758 pSiS->Flags = 0;
759 pSiS->VBFlags = 0;
760 pSiS->SiS76xLFBSize = pSiS->SiS76xUMASize = 0;
762 switch (SISPTR(pScrn)->Chipset) {
763 case PCI_CHIP_SIS300:
764 case PCI_CHIP_SIS630: /* +730 */
765 case PCI_CHIP_SIS540:
766 sis300Setup(pScrn);
767 break;
768 case PCI_CHIP_SIS315:
769 case PCI_CHIP_SIS315H:
770 case PCI_CHIP_SIS315PRO:
771 case PCI_CHIP_SIS330:
772 case PCI_CHIP_SIS340:
773 sis315Setup(pScrn);
774 break;
775 case PCI_CHIP_SIS550:
776 case PCI_CHIP_SIS650: /* + 740,M650,651 */
777 case PCI_CHIP_SIS660: /* + (M)661,(M)741,(M)760(GX), (M)761(GX), 770? */
778 sis550Setup(pScrn);
779 break;
780 case PCI_CHIP_SIS5597:
781 case PCI_CHIP_SIS6326:
782 case PCI_CHIP_SIS530:
783 default:
784 sisOldSetup(pScrn);
785 break;