2 * Basic hardware and memory detection
4 * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
9 * 1) Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2) Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3) The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 * Author: Thomas Winischhofer <thomas@winischhofer.net>
30 * Ideas and methods for old series based on code by Can-Ru Yeou, SiS Inc.
39 #define SIS_NEED_inSISREGW
40 #define SIS_NEED_inSISREGL
41 #define SIS_NEED_outSISREGW
42 #define SIS_NEED_outSISREGL
43 #define SIS_NEED_inSISIDXREG
44 #define SIS_NEED_outSISIDXREG
47 extern int SiSMclk(SISPtr pSiS
);
49 static const char *dramTypeStr
[] = {
57 "DDR SDRAM", /* for 550/650/etc */
58 "DDR SDRAM", /* for 550/650/etc */
60 "DDR2 SDRAM", /* for 340, 662 */
64 /* MCLK tables for SiS6326 */
65 static const int SiS6326MCLKIndex
[4][8] = {
66 { 10, 12, 14, 16, 17, 18, 19, 7 }, /* SGRAM */
67 { 4, 6, 8, 10, 11, 12, 13, 3 }, /* Fast Page */
68 { 9, 11, 12, 13, 15, 16, 5, 7 }, /* 2 cycle EDO */
69 { 10, 12, 14, 16, 17, 18, 19, 7 } /* ? (Not 1 cycle EDO) */
72 static const struct _sis6326mclk
{
81 { 45, 0, 0x2b, 0x26 },
82 { 53, 0, 0x49, 0xe4 },
83 { 55, 0, 0x7c, 0xe7 },
84 { 56, 0, 0x7c, 0xe7 },
85 { 60, 0, 0x42, 0xe3 },
86 { 61, 0, 0x21, 0xe1 },
87 { 65, 0, 0x5a, 0xe4 },
88 { 66, 0, 0x5a, 0xe4 },
89 { 70, 0, 0x61, 0xe4 },
90 { 75, 0, 0x3e, 0xe2 },
91 { 80, 0, 0x42, 0xe2 },
92 { 83, 0, 0xb3, 0xc5 },
93 { 85, 0, 0x5e, 0xe3 },
94 { 90, 0, 0xae, 0xc4 },
95 {100, 0, 0x37, 0xe1 },
96 {115, 0, 0x78, 0x0e },
100 #ifdef XSERVER_LIBPCIACCESS
102 sis_get_device (int device
)
104 struct pci_slot_match bridge_match
= {
105 0, 0, device
, PCI_MATCH_ANY
, 0
107 struct pci_device_iterator
*slot_iterator
;
108 struct pci_device
*bridge
;
110 slot_iterator
= pci_slot_match_iterator_create (&bridge_match
);
111 bridge
= pci_device_next (slot_iterator
);
112 pci_iterator_destroy (slot_iterator
);
117 sis_pci_read_device_u32(int device
, int offset
)
119 struct pci_device
*host_bridge
= sis_get_device(device
);
122 pci_device_cfg_read_u32(host_bridge
, &result
, offset
);
127 sis_pci_read_device_u8(int device
, int offset
)
129 struct pci_device
*host_bridge
= sis_get_device(device
);
130 unsigned char result
;
132 pci_device_cfg_read_u8(host_bridge
, &result
, offset
);
137 sis_pci_write_host_bridge_u32(int offset
, unsigned int value
)
139 struct pci_device
*host_bridge
= sis_get_device(0);
140 pci_device_cfg_write_u32(host_bridge
, value
, offset
);
144 sis_pci_write_host_bridge_u8(int offset
, unsigned char value
)
146 struct pci_device
*host_bridge
= sis_get_device(0);
147 pci_device_cfg_write_u8(host_bridge
, value
, offset
);
152 sis_pci_read_device_u32(int device
, int offset
)
154 PCITAG tag
= pciTag(0, device
, 0);
155 return pciReadLong(tag
, offset
);
159 sis_pci_read_device_u8(int device
, int offset
)
161 PCITAG tag
= pciTag(0, device
, 0);
162 return pciReadByte(tag
, offset
);
166 sis_pci_write_host_bridge_u32(int offset
, unsigned int value
)
168 pciWriteLong(0x00000000, offset
, value
);
172 sis_pci_write_host_bridge_u8(int offset
, unsigned char value
)
174 pciWriteByte(0x00000000, offset
, value
);
181 sis_pci_read_host_bridge_u32(int offset
)
183 return sis_pci_read_device_u32(0, offset
);
187 sis_pci_read_host_bridge_u8(int offset
)
189 return sis_pci_read_device_u8(0, offset
);
192 static int sisESSPresent(ScrnInfoPtr pScrn
)
195 #ifndef XSERVER_LIBPCIACCESS
197 pciConfigPtr pdptr
, *systemPCIdevices
= NULL
;
199 if((systemPCIdevices
= xf86GetPciConfigInfo())) {
201 while((pdptr
= systemPCIdevices
[i
])) {
202 if((pdptr
->pci_vendor
== 0x1274) &&
203 ((pdptr
->pci_device
== 0x5000) ||
204 ((pdptr
->pci_device
& 0xFFF0) == 0x1370))) {
205 flags
|= ESS137xPRESENT
;
213 struct pci_id_match id_match
= { 0x1274, PCI_MATCH_ANY
,
214 PCI_MATCH_ANY
, PCI_MATCH_ANY
,
215 PCI_MATCH_ANY
, PCI_MATCH_ANY
,
217 struct pci_device_iterator
*id_iterator
;
218 struct pci_device
*ess137x
;
220 id_iterator
= pci_id_match_iterator_create(&id_match
);
222 ess137x
= pci_device_next(id_iterator
);
224 if ((ess137x
->device_id
== 0x5000) ||
225 ((ess137x
->device_id
& 0xfff0) == 0x1370)) {
226 flags
|= ESS137xPRESENT
;
228 ess137x
= pci_device_next(id_iterator
);
234 /* For old chipsets, 5597, 6326, 530/620 */
236 sisOldSetup(ScrnInfoPtr pScrn
)
238 SISPtr pSiS
= SISPTR(pScrn
);
239 int ramsize
[8] = { 1, 2, 4, 0, 0, 2, 4, 8};
240 int buswidth
[8] = {32, 64, 64, 0, 0, 32, 32, 64 };
241 int clockTable
[4] = { 66, 75, 83, 100 };
242 int ramtype
[4] = { 5, 0, 1, 3 };
244 UChar sr23
, sr33
, sr37
;
246 UChar newsr13
, newsr28
, newsr29
;
248 #ifndef XSERVER_LIBPCIACCESS
249 pciConfigPtr pdptr
, *systemPCIdevices
= NULL
;
252 if(pSiS
->oldChipset
<= OC_SIS6225
) {
253 inSISIDXREG(SISSR
, 0x0F, temp
);
254 pScrn
->videoRam
= (1 << (temp
& 0x03)) * 1024;
255 if(pScrn
->videoRam
> 4096) pScrn
->videoRam
= 4096;
257 } else if(pSiS
->Chipset
== PCI_CHIP_SIS5597
) {
258 inSISIDXREG(SISSR
, 0x2F, temp
);
259 pScrn
->videoRam
= ((temp
& 0x07) + 1) * 256;
260 inSISIDXREG(SISSR
, 0x0C, temp
);
262 pScrn
->videoRam
*= 2;
264 } else pSiS
->BusWidth
= 32;
266 inSISIDXREG(SISSR
, 0x0C, temp
);
267 config
= ((temp
& 0x10) >> 2 ) | ((temp
& 0x06) >> 1);
268 pScrn
->videoRam
= ramsize
[config
] * 1024;
269 pSiS
->BusWidth
= buswidth
[config
];
272 if(pSiS
->Chipset
== PCI_CHIP_SIS530
) {
274 inSISIDXREG(SISSR
, 0x0D, temp
);
275 pSiS
->Flags
&= ~(UMA
);
277 pSiS
->Flags
|= UMA
; /* Shared fb mode */
278 inSISIDXREG(SISSR
, 0x10, temp
);
279 pSiS
->MemClock
= clockTable
[temp
& 0x03] * 1000;
281 pSiS
->MemClock
= SiSMclk(pSiS
); /* Local fb mode */
284 } else if(pSiS
->Chipset
== PCI_CHIP_SIS6326
) {
286 inSISIDXREG(SISSR
,0x0e,temp
);
290 xf86DrvMsg(pScrn
->scrnIndex
, X_PROBED
,
292 dramTypeStr
[ramtype
[i
]]);
294 temp
= (temp
>> 5) & 0x07;
295 i
= SiS6326MCLKIndex
[i
][temp
];
296 pSiS
->MemClock
= SiS6326MCLK
[i
].mclk
;
298 /* Correct invalid MCLK settings by old BIOSes */
299 newsr13
= SiS6326MCLK
[i
].sr13
;
300 newsr28
= SiS6326MCLK
[i
].sr28
;
301 newsr29
= SiS6326MCLK
[i
].sr29
;
302 if((pSiS
->ChipRev
== 0x92) ||
303 (pSiS
->ChipRev
== 0xd1) ||
304 (pSiS
->ChipRev
== 0xd2)) {
305 if(pSiS
->MemClock
== 60) {
311 pSiS
->MemClock
*= 1000;
313 inSISIDXREG(SISSR
, 0x13, temp
);
315 temp
|= (newsr13
& 0x80);
316 outSISIDXREG(SISSR
,0x13,temp
);
317 outSISIDXREG(SISSR
,0x28,newsr28
);
318 outSISIDXREG(SISSR
,0x29,newsr29
);
323 pSiS
->MemClock
= SiSMclk(pSiS
);
327 pSiS
->Flags
&= ~(SYNCDRAM
| RAMFLAG
);
328 if(pSiS
->oldChipset
>= OC_SIS82204
) {
329 inSISIDXREG(SISSR
, 0x23, sr23
);
330 inSISIDXREG(SISSR
, 0x33, sr33
);
331 if(pSiS
->oldChipset
>= OC_SIS530A
) sr33
&= ~0x08;
332 if(sr33
& 0x09) { /* 5597: Sync DRAM timing | One cycle EDO ram; */
333 pSiS
->Flags
|= (sr33
& SYNCDRAM
); /* 6326: Enable SGRam timing | One cycle EDO ram */
334 pSiS
->Flags
|= RAMFLAG
; /* 530: Enable SGRAM timing | reserved (0) */
335 } else if((pSiS
->oldChipset
< OC_SIS530A
) && (sr23
& 0x20)) {
336 pSiS
->Flags
|= SYNCDRAM
; /* 5597, 6326: EDO DRAM enabled */
337 } /* 530/620: reserved (0) */
340 pSiS
->Flags
&= ~(ESS137xPRESENT
);
341 if(pSiS
->Chipset
== PCI_CHIP_SIS530
) {
342 if(pSiS
->oldChipset
== OC_SIS530A
) {
343 #ifndef XSERVER_LIBPCIACCESS
344 if((systemPCIdevices
= xf86GetPciConfigInfo())) {
346 while((pdptr
= systemPCIdevices
[i
])) {
347 if((pdptr
->pci_vendor
== 0x1274) &&
348 ((pdptr
->pci_device
== 0x5000) ||
349 ((pdptr
->pci_device
& 0xFFF0) == 0x1370))) {
350 pSiS
->Flags
|= ESS137xPRESENT
;
357 /* FIXME maybe actually do hte detection? */
358 pSiS
->Flags
|= ESS137xPRESENT
;
360 if(pSiS
->Flags
& ESS137xPRESENT
) {
361 xf86DrvMsg(pScrn
->scrnIndex
, X_PROBED
,
362 "SiS530/620: Found ESS device\n");
367 pSiS
->Flags
&= ~(SECRETFLAG
);
368 if(pSiS
->oldChipset
>= OC_SIS5597
) {
369 inSISIDXREG(SISSR
, 0x37, sr37
);
370 if(sr37
& 0x80) pSiS
->Flags
|= SECRETFLAG
;
373 pSiS
->Flags
&= ~(A6326REVAB
);
374 if(pSiS
->Chipset
== PCI_CHIP_SIS6326
) {
375 if(((pSiS
->ChipRev
& 0x0f) == 0x0a) ||
376 ((pSiS
->ChipRev
& 0x0f) == 0x0b)) {
377 pSiS
->Flags
|= A6326REVAB
;
381 xf86DrvMsg(pScrn
->scrnIndex
, X_PROBED
,
382 "Memory clock: %3.3f MHz\n",
383 pSiS
->MemClock
/1000.0);
385 if(pSiS
->oldChipset
> OC_SIS6225
) {
386 xf86DrvMsg(pScrn
->scrnIndex
, X_PROBED
,
387 "DRAM bus width: %d bit\n",
392 xf86DrvMsg(pScrn
->scrnIndex
, X_INFO
,
393 "oldChipset = %d, Flags %x\n", pSiS
->oldChipset
, pSiS
->Flags
);
398 sis300Setup(ScrnInfoPtr pScrn
)
400 SISPtr pSiS
= SISPTR(pScrn
);
401 const int bus
[4] = {32, 64, 128, 32};
402 const int adaptermclk
[8] = { 66, 83, 100, 133,
404 const int adaptermclk300
[8] = { 125, 125, 125, 100,
406 unsigned int config
, pciconfig
, sr3a
, ramtype
;
409 MessageType from
= X_PROBED
;
411 pSiS
->MemClock
= SiSMclk(pSiS
);
413 inSISIDXREG(SISSR
, 0x14, config
);
414 cpubuswidth
= bus
[config
>> 6];
416 inSISIDXREG(SISSR
, 0x3A, sr3a
);
417 ramtype
= (sr3a
& 0x03) + 4;
419 pSiS
->IsPCIExpress
= FALSE
;
421 switch(pSiS
->Chipset
) {
422 case PCI_CHIP_SIS300
:
423 pScrn
->videoRam
= ((config
& 0x3F) + 1) * 1024;
424 pSiS
->LFBsize
= pScrn
->videoRam
;
425 pSiS
->BusWidth
= cpubuswidth
;
426 pSiS
->IsAGPCard
= ((sr3a
& 0x30) == 0x30) ? FALSE
: TRUE
;
428 case PCI_CHIP_SIS540
:
429 case PCI_CHIP_SIS630
:
430 pSiS
->IsAGPCard
= TRUE
;
431 pciconfig
= sis_pci_read_host_bridge_u8(0x63);
432 if(pciconfig
& 0x80) {
433 pScrn
->videoRam
= (1 << (((pciconfig
& 0x70) >> 4) + 21)) / 1024;
435 pciconfig
= sis_pci_read_host_bridge_u8(0x64);
436 if((pciconfig
& 0x30) == 0x30) {
437 pSiS
->BusWidth
= 128;
438 pScrn
->videoRam
<<= 1;
440 ramtype
= sis_pci_read_host_bridge_u8(0x65);
442 xf86DrvMsg(pScrn
->scrnIndex
, X_PROBED
,
443 "Shared Memory Area is on DIMM%d\n", ramtype
);
444 ramtype
= sis_pci_read_host_bridge_u8(0x60 + ramtype
);
445 if(ramtype
& 0x80) ramtype
= 9;
447 pSiS
->UMAsize
= pScrn
->videoRam
;
449 xf86DrvMsg(pScrn
->scrnIndex
, X_WARNING
,
450 "Shared Memory Area is disabled - awaiting doom\n");
451 pScrn
->videoRam
= ((config
& 0x3F) + 1) * 1024;
452 pSiS
->UMAsize
= pScrn
->videoRam
;
459 xf86DrvMsg(pScrn
->scrnIndex
, X_ERROR
,
460 "Internal error: sis300setup() called with invalid chipset!\n");
465 xf86DrvMsg(pScrn
->scrnIndex
, X_PROBED
,
467 dramTypeStr
[ramtype
]);
469 xf86DrvMsg(pScrn
->scrnIndex
, X_PROBED
,
470 "Memory clock: %3.3f MHz\n",
471 pSiS
->MemClock
/1000.0);
473 if(pSiS
->Chipset
== PCI_CHIP_SIS300
) {
474 if(pSiS
->ChipRev
> 0x13) {
475 inSISIDXREG(SISSR
, 0x3A, temp
);
476 xf86DrvMsg(pScrn
->scrnIndex
, X_PROBED
,
477 "(Adapter assumes MCLK being %d Mhz)\n",
478 adaptermclk300
[(temp
& 0x07)]);
481 inSISIDXREG(SISSR
, 0x1A, temp
);
482 xf86DrvMsg(pScrn
->scrnIndex
, X_PROBED
,
483 "(Adapter assumes MCLK being %d Mhz)\n",
484 adaptermclk
[(temp
& 0x07)]);
487 xf86DrvMsg(pScrn
->scrnIndex
, from
,
488 "DRAM bus width: %d bit\n",
492 /* For 315, 315H, 315PRO/E, 330, 340 */
494 sis315Setup(ScrnInfoPtr pScrn
)
496 SISPtr pSiS
= SISPTR(pScrn
);
497 int busSDR
[4] = {64, 64, 128, 128};
498 int busDDR
[4] = {32, 32, 64, 64};
499 int busDDRA
[4] = {64+32, 64+32 , (64+32)*2, (64+32)*2};
500 unsigned int config
, config1
, config2
, sr3a
, cr5f
;
501 char *dramTypeStr315
[] = {
502 "Single channel 1 rank SDR SDRAM",
503 "Single channel 1 rank SDR SGRAM",
504 "Single channel 1 rank DDR SDRAM",
505 "Single channel 1 rank DDR SGRAM",
506 "Single channel 2 rank SDR SDRAM",
507 "Single channel 2 rank SDR SGRAM",
508 "Single channel 2 rank DDR SDRAM",
509 "Single channel 2 rank DDR SGRAM",
510 "Asymmetric SDR SDRAM",
511 "Asymmetric SDR SGRAM",
512 "Asymmetric DDR SDRAM",
513 "Asymmetric DDR SGRAM",
514 "Dual channel SDR SDRAM",
515 "Dual channel SDR SGRAM",
516 "Dual channel DDR SDRAM",
517 "Dual channel DDR SGRAM"
519 char *dramTypeStr330
[] = {
520 "Single Channel SDR SDRAM",
522 "Single Channel DDR SDRAM",
528 "Asymetric Dual Channel SDR SDRAM",
530 "Asymetric Dual Channel DDR SDRAM",
532 "Dual channel SDR SDRAM",
534 "Dual channel DDR SDRAM",
537 char *dramTypeStr340
[] = {
538 "Single channel DDR SDRAM",
539 "Single channel DDR2 SDRAM",
540 "Single channel DDR2x SDRAM",
542 "Dual channel DDR SDRAM",
543 "Dual channel DDR2 SDRAM",
544 "Dual channel DDR2x SDRAM",
546 "Dual channel DDR SDRAM",
547 "Dual channel DDR2 SDRAM",
548 "Dual channel DDR2x SDRAM",
550 "Quad channel DDR SDRAM",
551 "Quad channel DDR2 SDRAM",
552 "Quad channel DDR2x SDRAM",
556 inSISIDXREG(SISSR
, 0x14, config
);
557 config1
= (config
& 0x0C) >> 2;
559 inSISIDXREG(SISSR
, 0x3a, sr3a
);
560 config2
= sr3a
& 0x03;
562 inSISIDXREG(SISCR
,0x5f,cr5f
);
564 pScrn
->videoRam
= (1 << ((config
& 0xf0) >> 4)) * 1024;
566 pSiS
->IsPCIExpress
= FALSE
;
568 switch(pSiS
->Chipset
) {
570 case PCI_CHIP_SIS340
:
571 case PCI_CHIP_XGIXG20
:
572 case PCI_CHIP_XGIXG40
:
574 if(pSiS
->ChipType
!= XGI_20
) { /* SIS340, XGI_40 */
576 pSiS
->IsAGPCard
= TRUE
;
578 if(pSiS
->ChipRev
== 2) {
579 if(config1
& 0x01) config1
= 0x02;
582 if(config1
== 0x02) pScrn
->videoRam
<<= 1; /* dual rank */
583 else if(config1
== 0x03) pScrn
->videoRam
<<= 2; /* quad rank */
585 inSISIDXREG(SISSR
, 0x39, config2
);
588 inSISIDXREG(SISSR
, 0x3a, config2
);
589 config2
= (config2
& 0x02) >> 1;
592 pSiS
->BusWidth
= (config
& 0x02) ? 64 : 32;
594 } else { /* XGI_20 (Z7) */
597 inSISIDXREG(SISCR
, 0x97, config2
);
599 config2
<<= 1; /* 0 or 2 */
601 pSiS
->BusWidth
= (config
& 0x02) ? 32 :
602 ((config
& 0x01) ? 16 : 8);
606 xf86DrvMsg(pScrn
->scrnIndex
, X_PROBED
,
607 "DRAM type: %s\n", dramTypeStr340
[(config1
* 4) + (config2
& 0x03)]);
609 pSiS
->MemClock
= SiSMclk(pSiS
);
611 pSiS
->MemClock
*= 2; /* at least DDR */
615 case PCI_CHIP_SIS330
:
617 pSiS
->IsAGPCard
= TRUE
;
619 if(config1
) pScrn
->videoRam
<<= 1;
621 xf86DrvMsg(pScrn
->scrnIndex
, X_PROBED
,
622 "DRAM type: %s\n", dramTypeStr330
[(config1
* 4) + (config2
& 0x02)]);
624 pSiS
->MemClock
= SiSMclk(pSiS
);
628 if(config1
== 0x02) {
629 pSiS
->BusWidth
= busDDRA
[0];
631 pSiS
->BusWidth
= busDDR
[(config
& 0x02)];
634 if(config1
== 0x02) {
635 pSiS
->BusWidth
= busDDRA
[2];
637 pSiS
->BusWidth
= busSDR
[(config
& 0x02)];
645 pSiS
->IsAGPCard
= ((sr3a
& 0x30) == 0x30) ? FALSE
: TRUE
;
647 if(cr5f
& 0x10) pSiS
->ChipFlags
|= SiSCF_Is315E
;
649 /* If SINGLE_CHANNEL_2_RANK or DUAL_CHANNEL_1_RANK -> mem * 2 */
650 if((config1
== 0x01) || (config1
== 0x03)) pScrn
->videoRam
<<= 1;
652 /* If DDR asymetric -> mem * 1,5 */
653 if(config1
== 0x02) pScrn
->videoRam
+= pScrn
->videoRam
/2;
655 xf86DrvMsg(pScrn
->scrnIndex
, X_PROBED
,
656 "DRAM type: %s\n", dramTypeStr315
[(config1
* 4) + config2
]);
658 pSiS
->MemClock
= SiSMclk(pSiS
);
660 /* If DDR -> memclock * 2 */
661 if(config2
& 0x02) pSiS
->MemClock
*= 2;
664 pSiS
->BusWidth
= busDDRA
[(config
& 0x03)];
665 else if(config2
& 0x02)
666 pSiS
->BusWidth
= busDDR
[(config
& 0x03)];
668 pSiS
->BusWidth
= busSDR
[(config
& 0x03)];
670 if(pSiS
->ChipFlags
& SiSCF_Is315E
) {
671 inSISIDXREG(SISSR
,0x15,config
);
672 if(config
& 0x10) pSiS
->BusWidth
= 32;
677 pSiS
->LFBsize
= pScrn
->videoRam
;
679 xf86DrvMsg(pScrn
->scrnIndex
, X_PROBED
,
680 "Memory clock: %3.3f MHz\n",
681 pSiS
->MemClock
/1000.0);
683 xf86DrvMsg(pScrn
->scrnIndex
, X_PROBED
,
684 "DRAM bus width: %d bit\n",
688 /* For 550, 65x, 740, 661, 741, 660, 760, 761, 670, 770, 662 */
690 sis550Setup(ScrnInfoPtr pScrn
)
692 SISPtr pSiS
= SISPTR(pScrn
);
693 unsigned int config
, ramtype
=0, i
;
694 CARD8 pciconfig
, temp
;
695 Bool alldone
= FALSE
;
696 Bool ddrtimes2
= TRUE
;
698 pSiS
->IsAGPCard
= TRUE
;
699 pSiS
->IsPCIExpress
= FALSE
;
700 pSiS
->ChipFlags
&= ~(SiSCF_760UMA
| SiSCF_760LFB
);
702 pSiS
->MemClock
= SiSMclk(pSiS
);
704 if(pSiS
->Chipset
== PCI_CHIP_SIS670
) {
708 pciconfig
= sis_pci_read_host_bridge_u8(0x4c);
709 if(pciconfig
& 0xe0) {
710 pScrn
->videoRam
= (1 << (((pciconfig
& 0xe0) >> 5) - 2)) * 32768;
711 pSiS
->ChipFlags
|= SiSCF_760UMA
;
712 pSiS
->SiS76xUMASize
= pScrn
->videoRam
* 1024;
713 pSiS
->UMAsize
= pScrn
->videoRam
;
714 xf86DrvMsg(pScrn
->scrnIndex
, X_PROBED
,
715 "%dK shared video RAM (UMA)\n",
722 } else if(pSiS
->Chipset
== PCI_CHIP_SIS660
) {
724 if(pSiS
->ChipType
>= SIS_660
&& pSiS
->ChipType
<= SIS_761
) {
728 /* UMA - shared fb */
730 pciconfig
= sis_pci_read_host_bridge_u8(0x4c);
731 if(pciconfig
& 0xe0) {
732 pScrn
->videoRam
= (1 << (((pciconfig
& 0xe0) >> 5) - 2)) * 32768;
733 pSiS
->ChipFlags
|= SiSCF_760UMA
;
734 pSiS
->SiS76xUMASize
= pScrn
->videoRam
* 1024;
735 pSiS
->UMAsize
= pScrn
->videoRam
;
736 xf86DrvMsg(pScrn
->scrnIndex
, X_PROBED
,
737 "%dK shared video RAM (UMA)\n",
741 /* LFB - local framebuffer: PCI reg hold total RAM (but configurable in BIOS) */
742 pciconfig
= pciReadByte(0x00000800, 0xcd);
743 pciconfig
= (pciconfig
>> 1) & 0x03;
745 if(pciconfig
== 0x01) i
= 32768;
746 else if(pciconfig
== 0x03) i
= 65536;
748 xf86DrvMsg(pScrn
->scrnIndex
, X_PROBED
, "%dK total local video RAM (LFB)\n", i
);
751 /* LFB: CR78 holds amount of LFB memory configured in the BIOS setup */
752 inSISIDXREG(SISCR
, 0x78, config
);
756 if(config
== 0x10) i
= 32768;
757 else if(config
== 0x30) i
= 65536;
759 xf86DrvMsg(pScrn
->scrnIndex
, X_PROBED
, "%dK configured local video RAM (LFB)\n", i
);
760 pScrn
->videoRam
+= i
;
761 pSiS
->ChipFlags
|= SiSCF_760LFB
;
762 pSiS
->SiS76xLFBSize
= i
* 1024;
767 if((pScrn
->videoRam
< 32768) || (pScrn
->videoRam
> 131072)) {
768 xf86DrvMsg(pScrn
->scrnIndex
, X_ERROR
,
769 "Illegal video RAM size (%dK) detected, using BIOS provided setting\n",
771 pSiS
->ChipFlags
&= ~(SiSCF_760LFB
| SiSCF_760UMA
);
778 if(pSiS
->ChipType
>= SIS_761
) {
779 pSiS
->IsAGPCard
= FALSE
;
780 pSiS
->IsPCIExpress
= TRUE
;
783 } else if(pSiS
->ChipType
>= SIS_662
) {
785 /* 662 - This crap written by SiS. FIXME!!! */
787 int dimmnum
= 4; /* ? */
789 if(pSiS
->ChipType
== SIS_662
) {
793 pciconfig
= sis_pci_read_host_bridge_u8(0x64);
794 if(pciconfig
& 0x80) {
795 pScrn
->videoRam
= (1 << (((pciconfig
& 0x60) >> 5))) * 32768;
796 pSiS
->UMAsize
= pScrn
->videoRam
;
797 if((pScrn
->videoRam
< 32768) || (pScrn
->videoRam
> (128 * 1024))) {
798 xf86DrvMsg(pScrn
->scrnIndex
, X_ERROR
,
799 "Illegal video RAM size (%dK) detected, using BIOS-provided info\n",
803 for(i
= 0; i
<= (dimmnum
- 1); i
++) {
804 if(pciconfig
& (1 << i
)) {
805 temp
= sis_pci_read_host_bridge_u8(0x60 + i
);
806 xf86DrvMsg(pScrn
->scrnIndex
, X_PROBED
,
807 "DIMM%d is %s SDRAM\n",
808 i
, (temp
& 0x40) ? "DDR2" : "non-DDR2");
810 xf86DrvMsg(pScrn
->scrnIndex
, X_PROBED
,
811 "DIMM%d is not installed\n", i
);
814 alldone
= FALSE
; /* Why, oh why??? */
824 if(pSiS
->ChipType
== SIS_741
) {
830 pciconfig
= sis_pci_read_host_bridge_u8(0x64);
831 if(pciconfig
& 0x80) {
832 pScrn
->videoRam
= (1 << (((pciconfig
& 0x70) >> 4) - 1)) * 32768;
833 pSiS
->UMAsize
= pScrn
->videoRam
;
834 if((pScrn
->videoRam
< 32768) || (pScrn
->videoRam
> (128 * 1024))) {
835 xf86DrvMsg(pScrn
->scrnIndex
, X_ERROR
,
836 "Illegal video RAM size (%dK) detected, using BIOS-provided info\n",
840 for(i
= 0; i
<= (dimmnum
- 1); i
++) {
841 if(pciconfig
& (1 << i
)) {
842 temp
= sis_pci_read_host_bridge_u8(0x60 + i
);
843 xf86DrvMsg(pScrn
->scrnIndex
, X_PROBED
,
844 "DIMM%d is %s SDRAM\n",
845 i
, (temp
& 0x40) ? "DDR" : "SDR");
847 xf86DrvMsg(pScrn
->scrnIndex
, X_PROBED
,
848 "DIMM%d is not installed\n", i
);
851 pciconfig
= sis_pci_read_host_bridge_u8(0x7c);
852 ramtype
= (pciconfig
& 0x02) ? 8 : 4;
859 } else if(pSiS
->Chipset
== PCI_CHIP_SIS650
) {
863 pciconfig
= sis_pci_read_host_bridge_u8(0x64);
864 if(pciconfig
& 0x80) {
865 pScrn
->videoRam
= (1 << (((pciconfig
& 0x70) >> 4) + 22)) / 1024;
866 pSiS
->UMAsize
= pScrn
->videoRam
;
868 for(i
=0; i
<=3; i
++) {
869 if(pciconfig
& (1 << i
)) {
870 temp
= sis_pci_read_host_bridge_u8(0x60 + i
);
871 xf86DrvMsg(pScrn
->scrnIndex
, X_PROBED
,
872 "DIMM%d is %s SDRAM\n",
873 i
, (temp
& 0x40) ? "DDR" : "SDR");
875 xf86DrvMsg(pScrn
->scrnIndex
, X_PROBED
,
876 "DIMM%d is not installed\n", i
);
879 pciconfig
= sis_pci_read_host_bridge_u8(0x7c);
880 if(pciconfig
& 0x02) ramtype
= 8;
889 pciconfig
= sis_pci_read_host_bridge_u8(0x63);
890 if(pciconfig
& 0x80) {
891 pScrn
->videoRam
= (1 << (((pciconfig
& 0x70) >> 4) + 21)) / 1024;
892 pSiS
->UMAsize
= pScrn
->videoRam
;
894 ramtype
= sis_pci_read_host_bridge_u8(0x65);
896 xf86DrvMsg(pScrn
->scrnIndex
, X_PROBED
,
897 "Shared Memory Area is on DIMM%d\n", ramtype
);
904 /* Fall back to BIOS detection results in case of problems: */
908 pSiS
->SiS76xLFBSize
= pSiS
->SiS76xUMASize
= 0;
909 pSiS
->UMAsize
= pSiS
->LFBsize
= 0;
911 if(pSiS
->Chipset
== PCI_CHIP_SIS670
) {
915 inSISIDXREG(SISCR
, 0x78, config
);
917 pScrn
->videoRam
= (1 << ((config
& 0xf0) >> 4)) * 1024;
918 pSiS
->UMAsize
= pScrn
->videoRam
;
919 pSiS
->ChipFlags
|= SiSCF_760UMA
;
920 pSiS
->SiS76xUMASize
= pScrn
->videoRam
* 1024;
921 xf86DrvMsg(pScrn
->scrnIndex
, X_PROBED
,
922 "%dK shared video RAM (UMA)\n",
926 } else if(pSiS
->Chipset
== PCI_CHIP_SIS660
) {
928 inSISIDXREG(SISCR
, 0x79, config
);
929 pSiS
->BusWidth
= (config
& 0x04) ? 128 : 64;
931 if(pSiS
->ChipType
== SIS_662
) {
932 switch(config
&0x03) {
942 ramtype
= (config
& 0x01) ? 8 : 4;
945 if(pSiS
->ChipType
>= SIS_660
) {
948 pScrn
->videoRam
= (1 << ((config
& 0xf0) >> 4)) * 1024;
949 pSiS
->UMAsize
= pScrn
->videoRam
;
950 pSiS
->ChipFlags
|= SiSCF_760UMA
;
951 pSiS
->SiS76xUMASize
= pScrn
->videoRam
* 1024;
952 xf86DrvMsg(pScrn
->scrnIndex
, X_PROBED
,
953 "%dK shared video RAM (UMA)\n",
956 if(pSiS
->ChipType
< SIS_662
) {
957 inSISIDXREG(SISCR
, 0x78, config
);
961 if(config
== 0x10) i
= 32768;
962 else if(config
== 0x30) i
= 65536;
964 xf86DrvMsg(pScrn
->scrnIndex
, X_PROBED
,
965 "%dK configured local video RAM (LFB)\n", i
);
966 pScrn
->videoRam
+= i
;
967 pSiS
->SiS76xLFBSize
= i
* 1024;
969 pSiS
->ChipFlags
|= SiSCF_760LFB
;
974 pScrn
->videoRam
= (1 << ((config
& 0xf0) >> 4)) * 1024;
975 pSiS
->UMAsize
= pScrn
->videoRam
;
980 xf86DrvMsg(pScrn
->scrnIndex
, X_WARNING
,
981 "Shared Memory Area is disabled - awaiting doom\n");
982 inSISIDXREG(SISSR
, 0x14, config
);
983 pScrn
->videoRam
= (((config
& 0x3F) + 1) * 4) * 1024;
984 pSiS
->UMAsize
= pScrn
->videoRam
;
985 if(pSiS
->Chipset
== PCI_CHIP_SIS650
) {
986 ramtype
= (((config
& 0x80) >> 7) << 2) + 4;
987 pSiS
->BusWidth
= 64; /* (config & 0x40) ? 128 : 64; */
995 /* These (might) need special attention: Memory controller in CPU, hence
996 * - no DDR * 2 for bandwidth calculation,
997 * - overlay magic (bandwidth dependent one/two overlay stuff)
999 switch(pSiS
->ChipType
) {
1008 if(!(pSiS
->ChipFlags
& SiSCF_760LFB
)) {
1010 pSiS
->SiS_SD2_Flags
|= SiS_SD2_SUPPORT760OO
;
1014 /* DDR -> Mclk * 2 - needed for bandwidth calculation */
1016 if(ramtype
== 8) pSiS
->MemClock
*= 2;
1017 if(ramtype
== 0xa) pSiS
->MemClock
*= 2;
1020 xf86DrvMsg(pScrn
->scrnIndex
, X_PROBED
,
1022 dramTypeStr
[ramtype
]);
1024 xf86DrvMsg(pScrn
->scrnIndex
, X_PROBED
,
1025 "Memory clock: %3.3f MHz\n",
1026 pSiS
->MemClock
/1000.0);
1028 xf86DrvMsg(pScrn
->scrnIndex
, X_PROBED
,
1029 "DRAM bus width: %d bit\n",
1034 SiSSetup(ScrnInfoPtr pScrn
)
1036 SISPtr pSiS
= SISPTR(pScrn
);
1040 pSiS
->SiS76xLFBSize
= pSiS
->SiS76xUMASize
= 0;
1041 pSiS
->UMAsize
= pSiS
->LFBsize
= 0;
1043 switch(pSiS
->Chipset
) {
1044 case PCI_CHIP_SIS300
:
1045 case PCI_CHIP_SIS630
: /* +730 */
1046 case PCI_CHIP_SIS540
:
1049 case PCI_CHIP_SIS315
:
1050 case PCI_CHIP_SIS315H
:
1051 case PCI_CHIP_SIS315PRO
:
1052 case PCI_CHIP_SIS330
:
1053 case PCI_CHIP_SIS340
:
1054 case PCI_CHIP_XGIXG20
:
1055 case PCI_CHIP_XGIXG40
:
1058 case PCI_CHIP_SIS550
:
1059 case PCI_CHIP_SIS650
: /* + 740, M650, 651 */
1060 case PCI_CHIP_SIS660
: /* + (M)661, (M)741, (M)760(GX), (M)761(GX), 662 */
1061 case PCI_CHIP_SIS670
: /* 670, 770 */
1064 case PCI_CHIP_SIS5597
:
1065 case PCI_CHIP_SIS6326
:
1066 case PCI_CHIP_SIS530
: