sis_setup.c revision 72b676d7
172b676d7Smrg/* $XFree86$ */
272b676d7Smrg/* $XdotOrg$ */
372b676d7Smrg/*
472b676d7Smrg * Basic hardware and memory detection
572b676d7Smrg *
672b676d7Smrg * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria.
772b676d7Smrg *
872b676d7Smrg * Redistribution and use in source and binary forms, with or without
972b676d7Smrg * modification, are permitted provided that the following conditions
1072b676d7Smrg * are met:
1172b676d7Smrg * 1) Redistributions of source code must retain the above copyright
1272b676d7Smrg *    notice, this list of conditions and the following disclaimer.
1372b676d7Smrg * 2) Redistributions in binary form must reproduce the above copyright
1472b676d7Smrg *    notice, this list of conditions and the following disclaimer in the
1572b676d7Smrg *    documentation and/or other materials provided with the distribution.
1672b676d7Smrg * 3) The name of the author may not be used to endorse or promote products
1772b676d7Smrg *    derived from this software without specific prior written permission.
1872b676d7Smrg *
1972b676d7Smrg * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
2072b676d7Smrg * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
2172b676d7Smrg * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2272b676d7Smrg * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
2372b676d7Smrg * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
2472b676d7Smrg * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2572b676d7Smrg * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2672b676d7Smrg * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2772b676d7Smrg * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
2872b676d7Smrg * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2972b676d7Smrg *
3072b676d7Smrg * Author:  	Thomas Winischhofer <thomas@winischhofer.net>
3172b676d7Smrg *
3272b676d7Smrg * Ideas and methods for old series based on code by Can-Ru Yeou, SiS Inc.
3372b676d7Smrg *
3472b676d7Smrg */
3572b676d7Smrg
3672b676d7Smrg#ifdef HAVE_CONFIG_H
3772b676d7Smrg#include "config.h"
3872b676d7Smrg#endif
3972b676d7Smrg
4072b676d7Smrg#include "sis.h"
4172b676d7Smrg#define SIS_NEED_inSISREGW
4272b676d7Smrg#define SIS_NEED_inSISREGL
4372b676d7Smrg#define SIS_NEED_outSISREGW
4472b676d7Smrg#define SIS_NEED_outSISREGL
4572b676d7Smrg#define SIS_NEED_inSISIDXREG
4672b676d7Smrg#define SIS_NEED_outSISIDXREG
4772b676d7Smrg#include "sis_regs.h"
4872b676d7Smrg
4972b676d7Smrgextern int SiSMclk(SISPtr pSiS);
5072b676d7Smrg
5172b676d7Smrgstatic const char *dramTypeStr[] = {
5272b676d7Smrg	"Fast Page DRAM",
5372b676d7Smrg	"2 cycle EDO RAM",
5472b676d7Smrg	"1 cycle EDO RAM",
5572b676d7Smrg	"SDRAM/SGRAM",
5672b676d7Smrg	"SDR SDRAM",
5772b676d7Smrg	"SGRAM",
5872b676d7Smrg	"ESDRAM",
5972b676d7Smrg	"DDR SDRAM",  /* for 550/650/etc */
6072b676d7Smrg	"DDR SDRAM",  /* for 550/650/etc */
6172b676d7Smrg	"VCM",	      /* for 630 */
6272b676d7Smrg	"DDR2 SDRAM", /* for 340 */
6372b676d7Smrg	""
6472b676d7Smrg};
6572b676d7Smrg
6672b676d7Smrg/* MCLK tables for SiS6326 */
6772b676d7Smrgstatic const int SiS6326MCLKIndex[4][8] = {
6872b676d7Smrg	{ 10, 12, 14, 16, 17, 18, 19,  7 },  /* SGRAM */
6972b676d7Smrg	{  4,  6,  8, 10, 11, 12, 13,  3 },  /* Fast Page */
7072b676d7Smrg	{  9, 11, 12, 13, 15, 16,  5,  7 },  /* 2 cycle EDO */
7172b676d7Smrg	{ 10, 12, 14, 16, 17, 18, 19,  7 }   /* ? (Not 1 cycle EDO) */
7272b676d7Smrg};
7372b676d7Smrg
7472b676d7Smrgstatic const struct _sis6326mclk {
7572b676d7Smrg    CARD16 mclk;
7672b676d7Smrg    UChar  sr13;
7772b676d7Smrg    UChar  sr28;
7872b676d7Smrg    UChar  sr29;
7972b676d7Smrg} SiS6326MCLK[] = {
8072b676d7Smrg	{  0, 0,    0,    0 },
8172b676d7Smrg	{  0, 0,    0,    0 },
8272b676d7Smrg	{  0, 0,    0,    0 },
8372b676d7Smrg	{ 45, 0, 0x2b, 0x26 },
8472b676d7Smrg	{ 53, 0, 0x49, 0xe4 },
8572b676d7Smrg	{ 55, 0, 0x7c, 0xe7 },
8672b676d7Smrg	{ 56, 0, 0x7c, 0xe7 },
8772b676d7Smrg	{ 60, 0, 0x42, 0xe3 },
8872b676d7Smrg	{ 61, 0, 0x21, 0xe1 },
8972b676d7Smrg	{ 65, 0, 0x5a, 0xe4 },
9072b676d7Smrg	{ 66, 0, 0x5a, 0xe4 },
9172b676d7Smrg	{ 70, 0, 0x61, 0xe4 },
9272b676d7Smrg	{ 75, 0, 0x3e, 0xe2 },
9372b676d7Smrg	{ 80, 0, 0x42, 0xe2 },
9472b676d7Smrg	{ 83, 0, 0xb3, 0xc5 },
9572b676d7Smrg	{ 85, 0, 0x5e, 0xe3 },
9672b676d7Smrg	{ 90, 0, 0xae, 0xc4 },
9772b676d7Smrg	{100, 0, 0x37, 0xe1 },
9872b676d7Smrg	{115, 0, 0x78, 0x0e },
9972b676d7Smrg	{134, 0, 0x4a, 0xa3 }
10072b676d7Smrg};
10172b676d7Smrg
10272b676d7Smrg/* For old chipsets, 5597, 6326, 530/620 */
10372b676d7Smrgstatic void
10472b676d7SmrgsisOldSetup(ScrnInfoPtr pScrn)
10572b676d7Smrg{
10672b676d7Smrg    SISPtr pSiS = SISPTR(pScrn);
10772b676d7Smrg    int    ramsize[8]  = { 1,  2,  4, 0, 0,  2,  4,  8};
10872b676d7Smrg    int    buswidth[8] = {32, 64, 64, 0, 0, 32, 32, 64 };
10972b676d7Smrg    int    clockTable[4] = { 66, 75, 83, 100 };
11072b676d7Smrg    int    ramtype[4]  = { 5, 0, 1, 3 };
11172b676d7Smrg    int    config, temp, i;
11272b676d7Smrg    UChar  sr23, sr33, sr37;
11372b676d7Smrg#if 0
11472b676d7Smrg    UChar  newsr13, newsr28, newsr29;
11572b676d7Smrg#endif
11672b676d7Smrg    pciConfigPtr pdptr, *systemPCIdevices = NULL;
11772b676d7Smrg
11872b676d7Smrg    if(pSiS->oldChipset <= OC_SIS6225) {
11972b676d7Smrg	inSISIDXREG(SISSR, 0x0F, temp);
12072b676d7Smrg	pScrn->videoRam = (1 << (temp & 0x03)) * 1024;
12172b676d7Smrg	if(pScrn->videoRam > 4096) pScrn->videoRam = 4096;
12272b676d7Smrg	pSiS->BusWidth = 32;
12372b676d7Smrg    } else if(pSiS->Chipset == PCI_CHIP_SIS5597) {
12472b676d7Smrg	inSISIDXREG(SISSR, 0x2F, temp);
12572b676d7Smrg	pScrn->videoRam = ((temp & 0x07) + 1) * 256;
12672b676d7Smrg	inSISIDXREG(SISSR, 0x0C, temp);
12772b676d7Smrg	if(temp & 0x06) {
12872b676d7Smrg		pScrn->videoRam *= 2;
12972b676d7Smrg		pSiS->BusWidth = 64;
13072b676d7Smrg	} else  pSiS->BusWidth = 32;
13172b676d7Smrg    } else {
13272b676d7Smrg	inSISIDXREG(SISSR, 0x0C, temp);
13372b676d7Smrg	config = ((temp & 0x10) >> 2 ) | ((temp & 0x06) >> 1);
13472b676d7Smrg	pScrn->videoRam = ramsize[config] * 1024;
13572b676d7Smrg	pSiS->BusWidth = buswidth[config];
13672b676d7Smrg    }
13772b676d7Smrg
13872b676d7Smrg    if(pSiS->Chipset == PCI_CHIP_SIS530)  {
13972b676d7Smrg
14072b676d7Smrg	inSISIDXREG(SISSR, 0x0D, temp);
14172b676d7Smrg	pSiS->Flags &= ~(UMA);
14272b676d7Smrg	if(temp & 0x01) {
14372b676d7Smrg		pSiS->Flags |= UMA;  		/* Shared fb mode */
14472b676d7Smrg		inSISIDXREG(SISSR, 0x10, temp);
14572b676d7Smrg		pSiS->MemClock = clockTable[temp & 0x03] * 1000;
14672b676d7Smrg	} else  {
14772b676d7Smrg		pSiS->MemClock = SiSMclk(pSiS); /* Local fb mode */
14872b676d7Smrg	}
14972b676d7Smrg
15072b676d7Smrg    } else if(pSiS->Chipset == PCI_CHIP_SIS6326) {
15172b676d7Smrg
15272b676d7Smrg	inSISIDXREG(SISSR,0x0e,temp);
15372b676d7Smrg
15472b676d7Smrg	i = temp & 0x03;
15572b676d7Smrg
15672b676d7Smrg	xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
15772b676d7Smrg	    "DRAM type: %s\n",
15872b676d7Smrg	    dramTypeStr[ramtype[i]]);
15972b676d7Smrg
16072b676d7Smrg	temp = (temp >> 5) & 0x07;
16172b676d7Smrg	i = SiS6326MCLKIndex[i][temp];
16272b676d7Smrg	pSiS->MemClock = SiS6326MCLK[i].mclk;
16372b676d7Smrg#if 0
16472b676d7Smrg	/* Correct invalid MCLK settings by old BIOSes */
16572b676d7Smrg	newsr13 = SiS6326MCLK[i].sr13;
16672b676d7Smrg	newsr28 = SiS6326MCLK[i].sr28;
16772b676d7Smrg	newsr29 = SiS6326MCLK[i].sr29;
16872b676d7Smrg	if((pSiS->ChipRev == 0x92) ||
16972b676d7Smrg	   (pSiS->ChipRev == 0xd1) ||
17072b676d7Smrg	   (pSiS->ChipRev == 0xd2)) {
17172b676d7Smrg	   if(pSiS->MemClock == 60) {
17272b676d7Smrg	      newsr28 = 0xae;
17372b676d7Smrg	      newsr29 = 0xc4;
17472b676d7Smrg	   }
17572b676d7Smrg	}
17672b676d7Smrg#endif
17772b676d7Smrg	pSiS->MemClock *= 1000;
17872b676d7Smrg#if 0
17972b676d7Smrg	inSISIDXREG(SISSR, 0x13, temp);
18072b676d7Smrg	temp &= 0x80;
18172b676d7Smrg	temp |= (newsr13 & 0x80);
18272b676d7Smrg	outSISIDXREG(SISSR,0x13,temp);
18372b676d7Smrg	outSISIDXREG(SISSR,0x28,newsr28);
18472b676d7Smrg	outSISIDXREG(SISSR,0x29,newsr29);
18572b676d7Smrg#endif
18672b676d7Smrg
18772b676d7Smrg    } else {
18872b676d7Smrg
18972b676d7Smrg	pSiS->MemClock = SiSMclk(pSiS);
19072b676d7Smrg
19172b676d7Smrg    }
19272b676d7Smrg
19372b676d7Smrg    pSiS->Flags &= ~(SYNCDRAM | RAMFLAG);
19472b676d7Smrg    if(pSiS->oldChipset >= OC_SIS82204) {
19572b676d7Smrg       inSISIDXREG(SISSR, 0x23, sr23);
19672b676d7Smrg       inSISIDXREG(SISSR, 0x33, sr33);
19772b676d7Smrg       if(pSiS->oldChipset >= OC_SIS530A) sr33 &= ~0x08;
19872b676d7Smrg       if(sr33 & 0x09) {				/* 5597: Sync DRAM timing | One cycle EDO ram;   */
19972b676d7Smrg		pSiS->Flags |= (sr33 & SYNCDRAM);	/* 6326: Enable SGRam timing | One cycle EDO ram */
20072b676d7Smrg		pSiS->Flags |= RAMFLAG;			/* 530:  Enable SGRAM timing | reserved (0)      */
20172b676d7Smrg       } else if((pSiS->oldChipset < OC_SIS530A) && (sr23 & 0x20)) {
20272b676d7Smrg		pSiS->Flags |= SYNCDRAM;		/* 5597, 6326: EDO DRAM enabled */
20372b676d7Smrg       }						/* 530/620:    reserved (0)     */
20472b676d7Smrg    }
20572b676d7Smrg
20672b676d7Smrg    pSiS->Flags &= ~(ESS137xPRESENT);
20772b676d7Smrg    if(pSiS->Chipset == PCI_CHIP_SIS530) {
20872b676d7Smrg       if(pSiS->oldChipset == OC_SIS530A) {
20972b676d7Smrg          if((systemPCIdevices = xf86GetPciConfigInfo())) {
21072b676d7Smrg	      i = 0;
21172b676d7Smrg	      while((pdptr = systemPCIdevices[i])) {
21272b676d7Smrg		 if((pdptr->pci_vendor == 0x1274) &&
21372b676d7Smrg		    ((pdptr->pci_device == 0x5000) ||
21472b676d7Smrg		     ((pdptr->pci_device & 0xFFF0) == 0x1370))) {
21572b676d7Smrg		     pSiS->Flags |= ESS137xPRESENT;
21672b676d7Smrg		     break;
21772b676d7Smrg		 }
21872b676d7Smrg		 i++;
21972b676d7Smrg	      }
22072b676d7Smrg	  }
22172b676d7Smrg	  if(pSiS->Flags & ESS137xPRESENT) {
22272b676d7Smrg	     xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
22372b676d7Smrg		 "SiS530/620: Found ESS device\n");
22472b676d7Smrg	  }
22572b676d7Smrg       }
22672b676d7Smrg    }
22772b676d7Smrg
22872b676d7Smrg    pSiS->Flags &= ~(SECRETFLAG);
22972b676d7Smrg    if(pSiS->oldChipset >= OC_SIS5597) {
23072b676d7Smrg	inSISIDXREG(SISSR, 0x37, sr37);
23172b676d7Smrg	if(sr37 & 0x80) pSiS->Flags |= SECRETFLAG;
23272b676d7Smrg    }
23372b676d7Smrg
23472b676d7Smrg    pSiS->Flags &= ~(A6326REVAB);
23572b676d7Smrg    if(pSiS->Chipset == PCI_CHIP_SIS6326) {
23672b676d7Smrg       if(((pSiS->ChipRev & 0x0f) == 0x0a) ||
23772b676d7Smrg	  ((pSiS->ChipRev & 0x0f) == 0x0b)) {
23872b676d7Smrg	    pSiS->Flags |= A6326REVAB;
23972b676d7Smrg       }
24072b676d7Smrg    }
24172b676d7Smrg
24272b676d7Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
24372b676d7Smrg	       "Memory clock: %3.3f MHz\n",
24472b676d7Smrg	       pSiS->MemClock/1000.0);
24572b676d7Smrg
24672b676d7Smrg    if(pSiS->oldChipset > OC_SIS6225) {
24772b676d7Smrg       xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
24872b676d7Smrg	       "DRAM bus width: %d bit\n",
24972b676d7Smrg	       pSiS->BusWidth);
25072b676d7Smrg    }
25172b676d7Smrg
25272b676d7Smrg#ifdef TWDEBUG
25372b676d7Smrg    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
25472b676d7Smrg		"oldChipset = %d, Flags %x\n", pSiS->oldChipset, pSiS->Flags);
25572b676d7Smrg#endif
25672b676d7Smrg}
25772b676d7Smrg
25872b676d7Smrgstatic void
25972b676d7Smrgsis300Setup(ScrnInfoPtr pScrn)
26072b676d7Smrg{
26172b676d7Smrg    SISPtr    pSiS = SISPTR(pScrn);
26272b676d7Smrg    const int bus[4] = {32, 64, 128, 32};
26372b676d7Smrg    const int adaptermclk[8]    = {  66,  83, 100, 133,
26472b676d7Smrg                                    100, 100, 100, 100};
26572b676d7Smrg    const int adaptermclk300[8] = { 125, 125, 125, 100,
26672b676d7Smrg                                    100, 100, 100, 100};
26772b676d7Smrg    unsigned int config, pciconfig, sr3a, ramtype;
26872b676d7Smrg    UChar        temp;
26972b676d7Smrg    int		 cpubuswidth;
27072b676d7Smrg    MessageType	 from = X_PROBED;
27172b676d7Smrg
27272b676d7Smrg    pSiS->MemClock = SiSMclk(pSiS);
27372b676d7Smrg
27472b676d7Smrg    inSISIDXREG(SISSR, 0x14, config);
27572b676d7Smrg    cpubuswidth = bus[config >> 6];
27672b676d7Smrg
27772b676d7Smrg    inSISIDXREG(SISSR, 0x3A, sr3a);
27872b676d7Smrg    ramtype = (sr3a & 0x03) + 4;
27972b676d7Smrg
28072b676d7Smrg    pSiS->IsPCIExpress = FALSE;
28172b676d7Smrg
28272b676d7Smrg    switch(pSiS->Chipset) {
28372b676d7Smrg    case PCI_CHIP_SIS300:
28472b676d7Smrg	pScrn->videoRam = ((config & 0x3F) + 1) * 1024;
28572b676d7Smrg	pSiS->LFBsize = pScrn->videoRam;
28672b676d7Smrg	pSiS->BusWidth = cpubuswidth;
28772b676d7Smrg	pSiS->IsAGPCard = ((sr3a & 0x30) == 0x30) ? FALSE : TRUE;
28872b676d7Smrg	break;
28972b676d7Smrg    case PCI_CHIP_SIS540:
29072b676d7Smrg    case PCI_CHIP_SIS630:
29172b676d7Smrg	pSiS->IsAGPCard = TRUE;
29272b676d7Smrg	pciconfig = pciReadByte(0x00000000, 0x63);
29372b676d7Smrg	if(pciconfig & 0x80) {
29472b676d7Smrg	   pScrn->videoRam = (1 << (((pciconfig & 0x70) >> 4) + 21)) / 1024;
29572b676d7Smrg	   pSiS->BusWidth = 64;
29672b676d7Smrg	   pciconfig = pciReadByte(0x00000000, 0x64);
29772b676d7Smrg	   if((pciconfig & 0x30) == 0x30) {
29872b676d7Smrg	      pSiS->BusWidth = 128;
29972b676d7Smrg	      pScrn->videoRam <<= 1;
30072b676d7Smrg	   }
30172b676d7Smrg	   ramtype = pciReadByte(0x00000000,0x65);
30272b676d7Smrg	   ramtype &= 0x03;
30372b676d7Smrg	   xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
30472b676d7Smrg		"Shared Memory Area is on DIMM%d\n", ramtype);
30572b676d7Smrg	   ramtype = pciReadByte(0x00000000,(0x60 + ramtype));
30672b676d7Smrg	   if(ramtype & 0x80) ramtype = 9;
30772b676d7Smrg	   else               ramtype = 4;
30872b676d7Smrg	   pSiS->UMAsize = pScrn->videoRam;
30972b676d7Smrg	} else {
31072b676d7Smrg	   xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
31172b676d7Smrg		"Shared Memory Area is disabled - awaiting doom\n");
31272b676d7Smrg	   pScrn->videoRam = ((config & 0x3F) + 1) * 1024;
31372b676d7Smrg	   pSiS->UMAsize = pScrn->videoRam;
31472b676d7Smrg	   pSiS->BusWidth = 64;
31572b676d7Smrg	   ramtype = 4;
31672b676d7Smrg	   from = X_INFO;
31772b676d7Smrg	}
31872b676d7Smrg	break;
31972b676d7Smrg    default:
32072b676d7Smrg	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
32172b676d7Smrg		"Internal error: sis300setup() called with invalid chipset!\n");
32272b676d7Smrg	pSiS->BusWidth = 64;
32372b676d7Smrg	from = X_INFO;
32472b676d7Smrg    }
32572b676d7Smrg
32672b676d7Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
32772b676d7Smrg	    "DRAM type: %s\n",
32872b676d7Smrg	    dramTypeStr[ramtype]);
32972b676d7Smrg
33072b676d7Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
33172b676d7Smrg	    "Memory clock: %3.3f MHz\n",
33272b676d7Smrg	    pSiS->MemClock/1000.0);
33372b676d7Smrg
33472b676d7Smrg    if(pSiS->Chipset == PCI_CHIP_SIS300) {
33572b676d7Smrg       if(pSiS->ChipRev > 0x13) {
33672b676d7Smrg	  inSISIDXREG(SISSR, 0x3A, temp);
33772b676d7Smrg	  xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
33872b676d7Smrg	     "(Adapter assumes MCLK being %d Mhz)\n",
33972b676d7Smrg	     adaptermclk300[(temp & 0x07)]);
34072b676d7Smrg       }
34172b676d7Smrg    } else {
34272b676d7Smrg       inSISIDXREG(SISSR, 0x1A, temp);
34372b676d7Smrg       xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
34472b676d7Smrg	    "(Adapter assumes MCLK being %d Mhz)\n",
34572b676d7Smrg	    adaptermclk[(temp & 0x07)]);
34672b676d7Smrg    }
34772b676d7Smrg
34872b676d7Smrg    xf86DrvMsg(pScrn->scrnIndex, from,
34972b676d7Smrg	    "DRAM bus width: %d bit\n",
35072b676d7Smrg	    pSiS->BusWidth);
35172b676d7Smrg}
35272b676d7Smrg
35372b676d7Smrg/* For 315, 315H, 315PRO/E, 330, 340 */
35472b676d7Smrgstatic void
35572b676d7Smrgsis315Setup(ScrnInfoPtr pScrn)
35672b676d7Smrg{
35772b676d7Smrg    SISPtr  pSiS = SISPTR(pScrn);
35872b676d7Smrg    int     busSDR[4]  = {64, 64, 128, 128};
35972b676d7Smrg    int     busDDR[4]  = {32, 32,  64,  64};
36072b676d7Smrg    int     busDDRA[4] = {64+32, 64+32 , (64+32)*2, (64+32)*2};
36172b676d7Smrg    unsigned int config, config1, config2, sr3a, cr5f;
36272b676d7Smrg    char    *dramTypeStr315[] = {
36372b676d7Smrg	"Single channel 1 rank SDR SDRAM",
36472b676d7Smrg	"Single channel 1 rank SDR SGRAM",
36572b676d7Smrg	"Single channel 1 rank DDR SDRAM",
36672b676d7Smrg	"Single channel 1 rank DDR SGRAM",
36772b676d7Smrg	"Single channel 2 rank SDR SDRAM",
36872b676d7Smrg	"Single channel 2 rank SDR SGRAM",
36972b676d7Smrg	"Single channel 2 rank DDR SDRAM",
37072b676d7Smrg	"Single channel 2 rank DDR SGRAM",
37172b676d7Smrg	"Asymmetric SDR SDRAM",
37272b676d7Smrg	"Asymmetric SDR SGRAM",
37372b676d7Smrg	"Asymmetric DDR SDRAM",
37472b676d7Smrg	"Asymmetric DDR SGRAM",
37572b676d7Smrg	"Dual channel SDR SDRAM",
37672b676d7Smrg	"Dual channel SDR SGRAM",
37772b676d7Smrg	"Dual channel DDR SDRAM",
37872b676d7Smrg	"Dual channel DDR SGRAM"
37972b676d7Smrg    };
38072b676d7Smrg    char    *dramTypeStr330[] = {
38172b676d7Smrg	"Single Channel SDR SDRAM",
38272b676d7Smrg	"",
38372b676d7Smrg	"Single Channel DDR SDRAM",
38472b676d7Smrg	"",
38572b676d7Smrg	"--unknown--",
38672b676d7Smrg	"",
38772b676d7Smrg	"--unknown--",
38872b676d7Smrg	"",
38972b676d7Smrg	"Asymetric Dual Channel SDR SDRAM",
39072b676d7Smrg	"",
39172b676d7Smrg	"Asymetric Dual Channel DDR SDRAM",
39272b676d7Smrg	"",
39372b676d7Smrg	"Dual channel SDR SDRAM",
39472b676d7Smrg	"",
39572b676d7Smrg	"Dual channel DDR SDRAM",
39672b676d7Smrg	""
39772b676d7Smrg    };
39872b676d7Smrg    char    *dramTypeStr340[] = {
39972b676d7Smrg	"Single channel DDR SDRAM",
40072b676d7Smrg	"Single channel DDR2 SDRAM",
40172b676d7Smrg	"Single channel DDR2x SDRAM",
40272b676d7Smrg	"",
40372b676d7Smrg	"Dual channel DDR SDRAM",
40472b676d7Smrg	"Dual channel DDR2 SDRAM",
40572b676d7Smrg	"Dual channel DDR2x SDRAM",
40672b676d7Smrg	"",
40772b676d7Smrg	"Dual channel DDR SDRAM",
40872b676d7Smrg	"Dual channel DDR2 SDRAM",
40972b676d7Smrg	"Dual channel DDR2x SDRAM",
41072b676d7Smrg	"",
41172b676d7Smrg	"Quad channel DDR SDRAM",
41272b676d7Smrg	"Quad channel DDR2 SDRAM",
41372b676d7Smrg	"Quad channel DDR2x SDRAM",
41472b676d7Smrg	""
41572b676d7Smrg    };
41672b676d7Smrg
41772b676d7Smrg    inSISIDXREG(SISSR, 0x14, config);
41872b676d7Smrg    config1 = (config & 0x0C) >> 2;
41972b676d7Smrg
42072b676d7Smrg    inSISIDXREG(SISSR, 0x3a, sr3a);
42172b676d7Smrg    config2 = sr3a & 0x03;
42272b676d7Smrg
42372b676d7Smrg    inSISIDXREG(SISCR,0x5f,cr5f);
42472b676d7Smrg
42572b676d7Smrg    pScrn->videoRam = (1 << ((config & 0xf0) >> 4)) * 1024;
42672b676d7Smrg
42772b676d7Smrg    pSiS->IsPCIExpress = FALSE;
42872b676d7Smrg
42972b676d7Smrg    switch(pSiS->Chipset) {
43072b676d7Smrg
43172b676d7Smrg    case PCI_CHIP_SIS340:
43272b676d7Smrg    case PCI_CHIP_XGIXG20:
43372b676d7Smrg    case PCI_CHIP_XGIXG40:
43472b676d7Smrg
43572b676d7Smrg       if(pSiS->ChipType != XGI_20) {	/* SIS340, XGI_40 */
43672b676d7Smrg
43772b676d7Smrg          pSiS->IsAGPCard = TRUE;
43872b676d7Smrg
43972b676d7Smrg          if(pSiS->ChipRev == 2) {
44072b676d7Smrg	     if(config1 & 0x01) config1 = 0x02;
44172b676d7Smrg	     else               config1 = 0x00;
44272b676d7Smrg          }
44372b676d7Smrg          if(config1 == 0x02)      pScrn->videoRam <<= 1; /* dual rank */
44472b676d7Smrg          else if(config1 == 0x03) pScrn->videoRam <<= 2; /* quad rank */
44572b676d7Smrg
44672b676d7Smrg	  inSISIDXREG(SISSR, 0x39, config2);
44772b676d7Smrg	  config2 &= 0x02;
44872b676d7Smrg	  if(!config2) {
44972b676d7Smrg	     inSISIDXREG(SISSR, 0x3a, config2);
45072b676d7Smrg	     config2 = (config2 & 0x02) >> 1;
45172b676d7Smrg          }
45272b676d7Smrg
45372b676d7Smrg	  pSiS->BusWidth = (config & 0x02) ? 64 : 32;
45472b676d7Smrg
45572b676d7Smrg       } else {				/* XGI_20 (Z7) */
45672b676d7Smrg
45772b676d7Smrg	  config1 = 0x00;
45872b676d7Smrg	  inSISIDXREG(SISCR, 0x97, config2);
45972b676d7Smrg	  config2 &= 0x01;
46072b676d7Smrg	  config2 <<= 1;	/* 0 or 2 */
46172b676d7Smrg
46272b676d7Smrg	  pSiS->BusWidth = (config & 0x02) ? 32 :
46372b676d7Smrg				((config & 0x01) ? 16 : 8);
46472b676d7Smrg
46572b676d7Smrg       }
46672b676d7Smrg
46772b676d7Smrg       xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
46872b676d7Smrg	    "DRAM type: %s\n", dramTypeStr340[(config1 * 4) + (config2 & 0x03)]);
46972b676d7Smrg
47072b676d7Smrg       pSiS->MemClock = SiSMclk(pSiS);
47172b676d7Smrg
47272b676d7Smrg       pSiS->MemClock *= 2; /* at least DDR */
47372b676d7Smrg
47472b676d7Smrg       break;
47572b676d7Smrg
47672b676d7Smrg    case PCI_CHIP_SIS330:
47772b676d7Smrg
47872b676d7Smrg       pSiS->IsAGPCard = TRUE;
47972b676d7Smrg
48072b676d7Smrg       if(config1) pScrn->videoRam <<= 1;
48172b676d7Smrg
48272b676d7Smrg       xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
48372b676d7Smrg	   "DRAM type: %s\n", dramTypeStr330[(config1 * 4) + (config2 & 0x02)]);
48472b676d7Smrg
48572b676d7Smrg       pSiS->MemClock = SiSMclk(pSiS);
48672b676d7Smrg
48772b676d7Smrg       if(config2 & 0x02) {
48872b676d7Smrg	  pSiS->MemClock *= 2;
48972b676d7Smrg	  if(config1 == 0x02) {
49072b676d7Smrg	     pSiS->BusWidth = busDDRA[0];
49172b676d7Smrg	  } else {
49272b676d7Smrg	     pSiS->BusWidth = busDDR[(config & 0x02)];
49372b676d7Smrg	  }
49472b676d7Smrg       } else {
49572b676d7Smrg	  if(config1 == 0x02) {
49672b676d7Smrg	     pSiS->BusWidth = busDDRA[2];
49772b676d7Smrg	  } else {
49872b676d7Smrg	     pSiS->BusWidth = busSDR[(config & 0x02)];
49972b676d7Smrg	  }
50072b676d7Smrg       }
50172b676d7Smrg
50272b676d7Smrg       break;
50372b676d7Smrg
50472b676d7Smrg    default: /* 315 */
50572b676d7Smrg
50672b676d7Smrg       pSiS->IsAGPCard = ((sr3a & 0x30) == 0x30) ? FALSE : TRUE;
50772b676d7Smrg
50872b676d7Smrg       if(cr5f & 0x10) pSiS->ChipFlags |= SiSCF_Is315E;
50972b676d7Smrg
51072b676d7Smrg       /* If SINGLE_CHANNEL_2_RANK or DUAL_CHANNEL_1_RANK -> mem * 2 */
51172b676d7Smrg       if((config1 == 0x01) || (config1 == 0x03)) pScrn->videoRam <<= 1;
51272b676d7Smrg
51372b676d7Smrg       /* If DDR asymetric -> mem * 1,5 */
51472b676d7Smrg       if(config1 == 0x02) pScrn->videoRam += pScrn->videoRam/2;
51572b676d7Smrg
51672b676d7Smrg       xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
51772b676d7Smrg	    "DRAM type: %s\n", dramTypeStr315[(config1 * 4) + config2]);
51872b676d7Smrg
51972b676d7Smrg       pSiS->MemClock = SiSMclk(pSiS);
52072b676d7Smrg
52172b676d7Smrg       /* If DDR -> memclock * 2 */
52272b676d7Smrg       if(config2 & 0x02) pSiS->MemClock *= 2;
52372b676d7Smrg
52472b676d7Smrg       if(config1 == 0x02)
52572b676d7Smrg	  pSiS->BusWidth = busDDRA[(config & 0x03)];
52672b676d7Smrg       else if(config2 & 0x02)
52772b676d7Smrg	  pSiS->BusWidth = busDDR[(config & 0x03)];
52872b676d7Smrg       else
52972b676d7Smrg	  pSiS->BusWidth = busSDR[(config & 0x03)];
53072b676d7Smrg
53172b676d7Smrg       if(pSiS->ChipFlags & SiSCF_Is315E) {
53272b676d7Smrg	  inSISIDXREG(SISSR,0x15,config);
53372b676d7Smrg	  if(config & 0x10) pSiS->BusWidth = 32;
53472b676d7Smrg       }
53572b676d7Smrg
53672b676d7Smrg    }
53772b676d7Smrg
53872b676d7Smrg    pSiS->LFBsize = pScrn->videoRam;
53972b676d7Smrg
54072b676d7Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
54172b676d7Smrg		"Memory clock: %3.3f MHz\n",
54272b676d7Smrg		pSiS->MemClock/1000.0);
54372b676d7Smrg
54472b676d7Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
54572b676d7Smrg		"DRAM bus width: %d bit\n",
54672b676d7Smrg		pSiS->BusWidth);
54772b676d7Smrg}
54872b676d7Smrg
54972b676d7Smrg/* For 550, 65x, 740, 661, 741, 660, 760, 761 */
55072b676d7Smrgstatic void
55172b676d7Smrgsis550Setup(ScrnInfoPtr pScrn)
55272b676d7Smrg{
55372b676d7Smrg    SISPtr       pSiS = SISPTR(pScrn);
55472b676d7Smrg    unsigned int config, ramtype=0, i;
55572b676d7Smrg    CARD8	 pciconfig, temp;
55672b676d7Smrg    Bool	 alldone = FALSE;
55772b676d7Smrg    Bool	 ddrtimes2 = TRUE;
55872b676d7Smrg
55972b676d7Smrg    pSiS->IsAGPCard = TRUE;
56072b676d7Smrg    pSiS->IsPCIExpress = FALSE;
56172b676d7Smrg    pSiS->ChipFlags &= ~(SiSCF_760UMA | SiSCF_760LFB);
56272b676d7Smrg
56372b676d7Smrg    pSiS->MemClock = SiSMclk(pSiS);
56472b676d7Smrg
56572b676d7Smrg    if(pSiS->Chipset == PCI_CHIP_SIS660) {
56672b676d7Smrg
56772b676d7Smrg       if(pSiS->ChipType >= SIS_660) {
56872b676d7Smrg
56972b676d7Smrg	  /* UMA - shared fb */
57072b676d7Smrg	  pScrn->videoRam = 0;
57172b676d7Smrg	  pciconfig = pciReadByte(0x00000000, 0x4c);
57272b676d7Smrg	  if(pciconfig & 0xe0) {
57372b676d7Smrg	     pScrn->videoRam = (1 << (((pciconfig & 0xe0) >> 5) - 2)) * 32768;
57472b676d7Smrg	     pSiS->ChipFlags |= SiSCF_760UMA;
57572b676d7Smrg	     pSiS->SiS76xUMASize = pScrn->videoRam * 1024;
57672b676d7Smrg	     pSiS->UMAsize = pScrn->videoRam;
57772b676d7Smrg	     xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
57872b676d7Smrg		"%dK shared video RAM (UMA)\n",
57972b676d7Smrg		pScrn->videoRam);
58072b676d7Smrg	  }
58172b676d7Smrg
58272b676d7Smrg	  /* LFB - local framebuffer: PCI reg hold total RAM (but configurable in BIOS) */
58372b676d7Smrg	  pciconfig = pciReadByte(0x00000800, 0xcd);
58472b676d7Smrg	  pciconfig = (pciconfig >> 1) & 0x03;
58572b676d7Smrg	  i = 0;
58672b676d7Smrg	  if(pciconfig == 0x01)      i = 32768;
58772b676d7Smrg	  else if(pciconfig == 0x03) i = 65536;
58872b676d7Smrg	  if(i) {
58972b676d7Smrg	     xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "%dK total local video RAM (LFB)\n", i);
59072b676d7Smrg	  }
59172b676d7Smrg
59272b676d7Smrg	  /* LFB: CR78 holds amount of LFB memory configured in the BIOS setup */
59372b676d7Smrg	  inSISIDXREG(SISCR, 0x78, config);
59472b676d7Smrg	  config &= 0x30;
59572b676d7Smrg	  if(config) {
59672b676d7Smrg	     i = 0;
59772b676d7Smrg	     if(config == 0x10)      i = 32768;
59872b676d7Smrg	     else if(config == 0x30) i = 65536;
59972b676d7Smrg	     if(i) {
60072b676d7Smrg		xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "%dK configured local video RAM (LFB)\n", i);
60172b676d7Smrg		pScrn->videoRam += i;
60272b676d7Smrg		pSiS->ChipFlags |= SiSCF_760LFB;
60372b676d7Smrg		pSiS->SiS76xLFBSize = i * 1024;
60472b676d7Smrg		pSiS->LFBsize = i;
60572b676d7Smrg	     }
60672b676d7Smrg	  }
60772b676d7Smrg
60872b676d7Smrg	  if((pScrn->videoRam < 32768) || (pScrn->videoRam > 131072)) {
60972b676d7Smrg	     xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
61072b676d7Smrg		 "Illegal video RAM size (%dK) detected, using BIOS provided setting\n",
61172b676d7Smrg		 pScrn->videoRam);
61272b676d7Smrg	     pSiS->ChipFlags &= ~(SiSCF_760LFB | SiSCF_760UMA);
61372b676d7Smrg	  } else {
61472b676d7Smrg	     pSiS->BusWidth = 64;
61572b676d7Smrg	     ramtype = 8;
61672b676d7Smrg	     alldone = TRUE;
61772b676d7Smrg	  }
61872b676d7Smrg
61972b676d7Smrg	  if(pSiS->ChipType >= SIS_761) {
62072b676d7Smrg	     pSiS->IsAGPCard = FALSE;
62172b676d7Smrg	     pSiS->IsPCIExpress = TRUE;
62272b676d7Smrg	  }
62372b676d7Smrg
62472b676d7Smrg       } else {  /* 661, 741 */
62572b676d7Smrg
62672b676d7Smrg	  int dimmnum;
62772b676d7Smrg
62872b676d7Smrg	  if(pSiS->ChipType == SIS_741) {
62972b676d7Smrg	     dimmnum = 4;
63072b676d7Smrg	  } else {
63172b676d7Smrg	     dimmnum = 3;
63272b676d7Smrg	  }
63372b676d7Smrg
63472b676d7Smrg	  pciconfig = pciReadByte(0x00000000, 0x64);
63572b676d7Smrg	  if(pciconfig & 0x80) {
63672b676d7Smrg	     pScrn->videoRam = (1 << (((pciconfig & 0x70) >> 4) - 1)) * 32768;
63772b676d7Smrg	     pSiS->UMAsize = pScrn->videoRam;
63872b676d7Smrg	     if((pScrn->videoRam < 32768) || (pScrn->videoRam > (128 * 1024))) {
63972b676d7Smrg		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
64072b676d7Smrg			"Illegal video RAM size (%dK) detected, using BIOS-provided info\n",
64172b676d7Smrg			pScrn->videoRam);
64272b676d7Smrg	     } else {
64372b676d7Smrg		pSiS->BusWidth = 64;
64472b676d7Smrg		for(i = 0; i <= (dimmnum - 1); i++) {
64572b676d7Smrg		   if(pciconfig & (1 << i)) {
64672b676d7Smrg		      temp = pciReadByte(0x00000000, 0x60 + i);
64772b676d7Smrg		      xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
64872b676d7Smrg			  "DIMM%d is %s SDRAM\n",
64972b676d7Smrg			  i, (temp & 0x40) ? "DDR" : "SDR");
65072b676d7Smrg		   } else {
65172b676d7Smrg		      xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
65272b676d7Smrg			  "DIMM%d is not installed\n", i);
65372b676d7Smrg		   }
65472b676d7Smrg		}
65572b676d7Smrg		pciconfig = pciReadByte(0x00000000, 0x7c);
65672b676d7Smrg		ramtype = (pciconfig & 0x02) ? 8 : 4;
65772b676d7Smrg		alldone = TRUE;
65872b676d7Smrg	     }
65972b676d7Smrg          }
66072b676d7Smrg
66172b676d7Smrg       }
66272b676d7Smrg
66372b676d7Smrg    } else if(pSiS->Chipset == PCI_CHIP_SIS650) {
66472b676d7Smrg
66572b676d7Smrg       pciconfig = pciReadByte(0x00000000, 0x64);
66672b676d7Smrg       if(pciconfig & 0x80) {
66772b676d7Smrg          pScrn->videoRam = (1 << (((pciconfig & 0x70) >> 4) + 22)) / 1024;
66872b676d7Smrg	  pSiS->UMAsize = pScrn->videoRam;
66972b676d7Smrg	  pSiS->BusWidth = 64;
67072b676d7Smrg	  for(i=0; i<=3; i++) {
67172b676d7Smrg	     if(pciconfig & (1 << i)) {
67272b676d7Smrg		temp = pciReadByte(0x00000000, 0x60 + i);
67372b676d7Smrg		xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
67472b676d7Smrg		   "DIMM%d is %s SDRAM\n",
67572b676d7Smrg		   i, (temp & 0x40) ? "DDR" : "SDR");
67672b676d7Smrg	     } else {
67772b676d7Smrg		xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
67872b676d7Smrg		   "DIMM%d is not installed\n", i);
67972b676d7Smrg	     }
68072b676d7Smrg	  }
68172b676d7Smrg	  pciconfig = pciReadByte(0x00000000, 0x7c);
68272b676d7Smrg	  if(pciconfig & 0x02) ramtype = 8;
68372b676d7Smrg	  else                 ramtype = 4;
68472b676d7Smrg	  alldone = TRUE;
68572b676d7Smrg       }
68672b676d7Smrg
68772b676d7Smrg    } else {
68872b676d7Smrg
68972b676d7Smrg       pciconfig = pciReadByte(0x00000000, 0x63);
69072b676d7Smrg       if(pciconfig & 0x80) {
69172b676d7Smrg	  pScrn->videoRam = (1 << (((pciconfig & 0x70) >> 4) + 21)) / 1024;
69272b676d7Smrg	  pSiS->UMAsize = pScrn->videoRam;
69372b676d7Smrg	  pSiS->BusWidth = 64;
69472b676d7Smrg	  ramtype = pciReadByte(0x00000000,0x65);
69572b676d7Smrg	  ramtype &= 0x01;
69672b676d7Smrg	  xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
69772b676d7Smrg	   	"Shared Memory Area is on DIMM%d\n", ramtype);
69872b676d7Smrg	  ramtype = 4;
69972b676d7Smrg	  alldone = TRUE;
70072b676d7Smrg       }
70172b676d7Smrg
70272b676d7Smrg    }
70372b676d7Smrg
70472b676d7Smrg    /* Fall back to BIOS detection results in case of problems: */
70572b676d7Smrg
70672b676d7Smrg    if(!alldone) {
70772b676d7Smrg
70872b676d7Smrg       pSiS->SiS76xLFBSize = pSiS->SiS76xUMASize = 0;
70972b676d7Smrg       pSiS->UMAsize = pSiS->LFBsize = 0;
71072b676d7Smrg
71172b676d7Smrg       if(pSiS->Chipset == PCI_CHIP_SIS660) {
71272b676d7Smrg	  inSISIDXREG(SISCR, 0x79, config);
71372b676d7Smrg	  pSiS->BusWidth = (config & 0x04) ? 128 : 64;
71472b676d7Smrg	  ramtype = (config & 0x01) ? 8 : 4;
71572b676d7Smrg	  if(pSiS->ChipType >= SIS_660) {
71672b676d7Smrg	     pScrn->videoRam = 0;
71772b676d7Smrg	     if(config & 0xf0) {
71872b676d7Smrg		pScrn->videoRam = (1 << ((config & 0xf0) >> 4)) * 1024;
71972b676d7Smrg		pSiS->UMAsize = pScrn->videoRam;
72072b676d7Smrg		pSiS->ChipFlags |= SiSCF_760UMA;
72172b676d7Smrg		pSiS->SiS76xUMASize = pScrn->videoRam * 1024;
72272b676d7Smrg		xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
72372b676d7Smrg				"%dK shared video RAM (UMA)\n",
72472b676d7Smrg				pScrn->videoRam);
72572b676d7Smrg	     }
72672b676d7Smrg	     inSISIDXREG(SISCR, 0x78, config);
72772b676d7Smrg	     config &= 0x30;
72872b676d7Smrg	     if(config) {
72972b676d7Smrg	        i = 0;
73072b676d7Smrg		if(config == 0x10)      i = 32768;
73172b676d7Smrg		else if(config == 0x30) i = 65536;
73272b676d7Smrg		if(i) {
73372b676d7Smrg		   xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
73472b676d7Smrg				"%dK configured local video RAM (LFB)\n", i);
73572b676d7Smrg		   pScrn->videoRam += i;
73672b676d7Smrg		   pSiS->SiS76xLFBSize = i * 1024;
73772b676d7Smrg		   pSiS->LFBsize = i;
73872b676d7Smrg		   pSiS->ChipFlags |= SiSCF_760LFB;
73972b676d7Smrg
74072b676d7Smrg		}
74172b676d7Smrg	     }
74272b676d7Smrg	  } else {
74372b676d7Smrg	     pScrn->videoRam = (1 << ((config & 0xf0) >> 4)) * 1024;
74472b676d7Smrg	     pSiS->UMAsize = pScrn->videoRam;
74572b676d7Smrg	  }
74672b676d7Smrg       } else {
74772b676d7Smrg	  xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
74872b676d7Smrg	      "Shared Memory Area is disabled - awaiting doom\n");
74972b676d7Smrg	  inSISIDXREG(SISSR, 0x14, config);
75072b676d7Smrg	  pScrn->videoRam = (((config & 0x3F) + 1) * 4) * 1024;
75172b676d7Smrg	  pSiS->UMAsize = pScrn->videoRam;
75272b676d7Smrg	  if(pSiS->Chipset == PCI_CHIP_SIS650) {
75372b676d7Smrg	     ramtype = (((config & 0x80) >> 7) << 2) + 4;
75472b676d7Smrg	     pSiS->BusWidth = 64;   /* (config & 0x40) ? 128 : 64; */
75572b676d7Smrg	  } else {
75672b676d7Smrg	     ramtype = 4;
75772b676d7Smrg	     pSiS->BusWidth = 64;
75872b676d7Smrg	  }
75972b676d7Smrg       }
76072b676d7Smrg    }
76172b676d7Smrg
76272b676d7Smrg    /* These need special attention: Memory controller in CPU, hence
76372b676d7Smrg     * - no DDR * 2 for bandwidth calculation,
76472b676d7Smrg     * - overlay magic (bandwidth dependent one/two overlay stuff)
76572b676d7Smrg     */
76672b676d7Smrg    if((pSiS->ChipType >= SIS_760) && (pSiS->ChipType <= SIS_770)) {
76772b676d7Smrg       if(!(pSiS->ChipFlags & SiSCF_760LFB)) {
76872b676d7Smrg	  ddrtimes2 = FALSE;
76972b676d7Smrg	  pSiS->SiS_SD2_Flags |= SiS_SD2_SUPPORT760OO;
77072b676d7Smrg       }
77172b676d7Smrg    }
77272b676d7Smrg
77372b676d7Smrg    /* DDR -> Mclk * 2 - needed for bandwidth calculation */
77472b676d7Smrg    if(ddrtimes2) {
77572b676d7Smrg       if(ramtype == 8) pSiS->MemClock *= 2;
77672b676d7Smrg    }
77772b676d7Smrg
77872b676d7Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
77972b676d7Smrg		"DRAM type: %s\n",
78072b676d7Smrg		dramTypeStr[ramtype]);
78172b676d7Smrg
78272b676d7Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
78372b676d7Smrg		"Memory clock: %3.3f MHz\n",
78472b676d7Smrg		pSiS->MemClock/1000.0);
78572b676d7Smrg
78672b676d7Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
78772b676d7Smrg		"DRAM bus width: %d bit\n",
78872b676d7Smrg		pSiS->BusWidth);
78972b676d7Smrg}
79072b676d7Smrg
79172b676d7Smrgvoid
79272b676d7SmrgSiSSetup(ScrnInfoPtr pScrn)
79372b676d7Smrg{
79472b676d7Smrg    SISPtr pSiS = SISPTR(pScrn);
79572b676d7Smrg
79672b676d7Smrg    pSiS->Flags = 0;
79772b676d7Smrg    pSiS->VBFlags = 0;
79872b676d7Smrg    pSiS->SiS76xLFBSize = pSiS->SiS76xUMASize = 0;
79972b676d7Smrg    pSiS->UMAsize = pSiS->LFBsize = 0;
80072b676d7Smrg
80172b676d7Smrg    switch (SISPTR(pScrn)->Chipset) {
80272b676d7Smrg    case PCI_CHIP_SIS300:
80372b676d7Smrg    case PCI_CHIP_SIS630:  /* +730 */
80472b676d7Smrg    case PCI_CHIP_SIS540:
80572b676d7Smrg        sis300Setup(pScrn);
80672b676d7Smrg        break;
80772b676d7Smrg    case PCI_CHIP_SIS315:
80872b676d7Smrg    case PCI_CHIP_SIS315H:
80972b676d7Smrg    case PCI_CHIP_SIS315PRO:
81072b676d7Smrg    case PCI_CHIP_SIS330:
81172b676d7Smrg    case PCI_CHIP_SIS340:
81272b676d7Smrg    case PCI_CHIP_XGIXG20:
81372b676d7Smrg    case PCI_CHIP_XGIXG40:
81472b676d7Smrg    	sis315Setup(pScrn);
81572b676d7Smrg	break;
81672b676d7Smrg    case PCI_CHIP_SIS550:
81772b676d7Smrg    case PCI_CHIP_SIS650: /* + 740,M650,651 */
81872b676d7Smrg    case PCI_CHIP_SIS660: /* + (M)661,(M)741,(M)760(GX), (M)761(GX), 770? */
81972b676d7Smrg        sis550Setup(pScrn);
82072b676d7Smrg	break;
82172b676d7Smrg    case PCI_CHIP_SIS5597:
82272b676d7Smrg    case PCI_CHIP_SIS6326:
82372b676d7Smrg    case PCI_CHIP_SIS530:
82472b676d7Smrg    default:
82572b676d7Smrg        sisOldSetup(pScrn);
82672b676d7Smrg        break;
82772b676d7Smrg    }
82872b676d7Smrg}
82972b676d7Smrg
83072b676d7Smrg
831