--- xc/programs/Xserver/hw/xfree86/etc/scanpci.c.336 Fri Dec 3 10:43:47 1999 +++ xc/programs/Xserver/hw/xfree86/etc/scanpci.c Mon Jul 17 11:51:20 2000 @@ -1253,10 +1253,15 @@ { 0x8A13, "Trio3D/2X", NF }, { 0x8A20, "Savage3D", NF }, { 0x8A21, "Savage3D S3 (Macrovision Support)", NF }, + { 0x8A25, "Savage/NB", NF }, { 0x8A22, "Savage4", NF }, { 0x8C01, "ViRGE/MX", NF }, { 0x8C02, "ViRGE/MX+", NF }, { 0x8C03, "ViRGE/MX+MV", NF }, + { 0x8C10, "Savage/MX-MV", NF }, + { 0x8C11, "Savage/MX", NF }, + { 0x8C12, "Savage/IX-MV", NF }, + { 0x8C13, "Savage/IX", NF }, { 0x9102, "Savage2000", NF }, { 0x0000, (char *)NULL, NF } } }, { 0x8086, "Intel", { --- xc/programs/Xserver/hw/xfree86/vga256/vga/vgaPCI.h.336 Sat Jan 8 19:27:07 2000 +++ xc/programs/Xserver/hw/xfree86/vga256/vga/vgaPCI.h Mon Jul 17 11:56:42 2000 @@ -288,6 +288,11 @@ #define PCI_CHIP_SAVAGE3D_M 0x8A21 #define PCI_CHIP_SAVAGE4 0x8A22 #define PCI_CHIP_SAVAGE2000 0x9102 +#define PCI_CHIP_SAVAGE_MX_MV 0x8C10 +#define PCI_CHIP_SAVAGE_MX 0x8C11 +#define PCI_CHIP_SAVAGE_IX_MV 0x8C12 +#define PCI_CHIP_SAVAGE_IX 0x8C13 +#define PCI_CHIP_SAVAGE_370 0x8A25 #define PCI_CHIP_868 0x8880 #define PCI_CHIP_928 0x88B0 #define PCI_CHIP_864_0 0x88C0 @@ -589,6 +594,11 @@ {PCI_CHIP_SAVAGE3D_M, "Savage3D (Macrovision Support)"}, {PCI_CHIP_SAVAGE4, "Savage4"}, {PCI_CHIP_SAVAGE2000, "Savage2000"}, + {PCI_CHIP_SAVAGE_MX_MV, "Savage/MX-MV"}, + {PCI_CHIP_SAVAGE_MX, "Savage/MX"}, + {PCI_CHIP_SAVAGE_IX_MV, "Savage/IX-MV"}, + {PCI_CHIP_SAVAGE_IX, "Savage/IX"}, + {PCI_CHIP_SAVAGE_370, "Savage/NB"}, {PCI_CHIP_868, "868"}, {PCI_CHIP_928, "928"}, {PCI_CHIP_864_0, "864"}, --- xc/programs/Xserver/hw/xfree86/SuperProbe/PCI.h.336 Thu Nov 18 16:52:49 1999 +++ xc/programs/Xserver/hw/xfree86/SuperProbe/PCI.h Mon Jul 17 17:11:25 2000 @@ -362,6 +362,12 @@ #define PCI_CHIP_SAVAGE3D_M 0x8A21 #define PCI_CHIP_SAVAGE4 0x8A22 #define PCI_CHIP_SAVAGE2000 0x9102 +#define PCI_CHIP_SAVAGE_MX_MV 0x8C10 +#define PCI_CHIP_SAVAGE_MX 0x8C11 +#define PCI_CHIP_SAVAGE_IX_MV 0x8C12 +#define PCI_CHIP_SAVAGE_IX 0x8C13 +#define PCI_CHIP_SAVAGE_NB 0x8A25 +#define PCI_CHIP_SAVAGE_MX_MV 0x8C10 /* ARK Logic */ #define PCI_CHIP_1000PV 0xA091 --- xc/programs/Xserver/hw/xfree86/SuperProbe/Probe.h.336 Thu Nov 18 16:52:49 1999 +++ xc/programs/Xserver/hw/xfree86/SuperProbe/Probe.h Mon Jul 17 17:10:07 2000 @@ -611,6 +611,11 @@ #define CHIP_S3_Trio3D_2X SVGA_TYPE(V_S3,40) /* S3 Trio3D/2X */ #define CHIP_S3_Savage4 SVGA_TYPE(V_S3,41) /* S3 Savage4 */ #define CHIP_S3_Savage2000 SVGA_TYPE(V_S3,42) /* S3 Savage2000 */ +#define CHIP_S3_SavageMX_MV SVGA_TYPE(V_S3,43) /* S3 Savage/MX-MV */ +#define CHIP_S3_SavageMX SVGA_TYPE(V_S3,44) /* S3 Savage/MX */ +#define CHIP_S3_SavageIX_MV SVGA_TYPE(V_S3,45) /* S3 Savage/IX-MV */ +#define CHIP_S3_SavageIX SVGA_TYPE(V_S3,46) /* S3 Savage/IX */ +#define CHIP_S3_SavageNB SVGA_TYPE(V_S3,47) /* S3 Savage/NB */ #define CHIP_TVGA_UNK SVGA_TYPE(V_TRIDENT,0) /* Trident unknown */ #define CHIP_TVGA8200 SVGA_TYPE(V_TRIDENT,1) /* Trident LX8200 */ #define CHIP_TVGA8800BR SVGA_TYPE(V_TRIDENT,2) /* Trident 8800BR */ --- xc/programs/Xserver/hw/xfree86/SuperProbe/Print.c.336 Thu Nov 18 16:52:49 1999 +++ xc/programs/Xserver/hw/xfree86/SuperProbe/Print.c Mon Jul 17 12:05:17 2000 @@ -149,6 +149,11 @@ "S3 Trio3D/2X", "S3 Savage4", "S3 Savage2000", + "S3 Savage/MX-MV", + "S3 Savage/MX", + "S3 Savage/IX-MV", + "S3 Savage/IX", + "S3 Savage/NB", }, /* Trident */ { "Trident (chipset unknown)", "Trident LX8200", --- xc/programs/Xserver/hw/xfree86/SuperProbe/S3.c.336 Fri Dec 3 10:41:34 1999 +++ xc/programs/Xserver/hw/xfree86/SuperProbe/S3.c Mon Jul 17 17:11:04 2000 @@ -194,6 +194,26 @@ PCIProbed = TRUE; *Chipset = CHIP_S3_Savage2000; break; + case PCI_CHIP_SAVAGE_MX_MV: + PCIProbed = TRUE; + *Chipset = CHIP_S3_SavageMX_MV; + break; + case PCI_CHIP_SAVAGE_MX: + PCIProbed = TRUE; + *Chipset = CHIP_S3_SavageMX; + break; + case PCI_CHIP_SAVAGE_IX_MV: + PCIProbed = TRUE; + *Chipset = CHIP_S3_SavageIX_MV; + break; + case PCI_CHIP_SAVAGE_IX: + PCIProbed = TRUE; + *Chipset = CHIP_S3_SavageIX; + break; + case PCI_CHIP_SAVAGE_NB: + PCIProbed = TRUE; + *Chipset = CHIP_S3_SavageNB; + break; #if 0 /* use port probing then... */ default: PCIProbed = TRUE; @@ -428,6 +448,21 @@ case PCI_CHIP_SAVAGE2000: *Chipset = CHIP_S3_Savage2000; break; + case PCI_CHIP_SAVAGE_MX_MV: + *Chipset = CHIP_S3_SavageMX_MV; + break; + case PCI_CHIP_SAVAGE_MX: + *Chipset = CHIP_S3_SavageMX; + break; + case PCI_CHIP_SAVAGE_IX_MV: + *Chipset = CHIP_S3_SavageIX_MV; + break; + case PCI_CHIP_SAVAGE_IX: + *Chipset = CHIP_S3_SavageIX; + break; + case PCI_CHIP_SAVAGE_NB: + *Chipset = CHIP_S3_SavageNB; + break; default: Chip_data = rev; Chip_data = (Chip_data << 16) | chip_id; @@ -547,6 +582,19 @@ else if (Chipset == CHIP_S3_Savage2000) { int memsize[] = { 2, 4, 8, 12, 16, 32, 64, 32 }; + int sel = (config & 0xE0) >> 5; + Mem = memsize[sel] * 1024; + } + else if (Chipset == CHIP_S3_SavageMX_MV || Chipset == CHIP_S3_SavageMX || + Chipset == CHIP_S3_SavageIX_MV || Chipset == CHIP_S3_SavageIX) + { + int memsize[] = { 2, 8, 4, 16, 8, 16, 4, 16 }; + int sel = (config & 0x0E) >> 1; + Mem = memsize[sel] * 1024; + } + else if (Chipset == CHIP_S3_SavageNB) + { + int memsize[] = { 0, 2, 4, 8, 16, 32, 2, 2 }; int sel = (config & 0xE0) >> 5; Mem = memsize[sel] * 1024; } diff -u xc/programs/Xserver/hw/xfree86/vga256/drivers/s3_savage.336/lrmi.c xc/programs/Xserver/hw/xfree86/vga256/drivers/s3_savage/lrmi.c --- xc/programs/Xserver/hw/xfree86/vga256/drivers/s3_savage.336/lrmi.c Fri Jul 30 13:21:25 1999 +++ xc/programs/Xserver/hw/xfree86/vga256/drivers/s3_savage/lrmi.c Wed Jan 26 01:44:42 2000 @@ -11,10 +11,10 @@ */ /* $XFree86: xc/programs/Xserver/hw/xfree86/vga256/drivers/s3_savage/lrmi.c,v 1.1.2.1 1999/07/30 11:21:25 hohndel Exp $ */ -#if defined(linux) && defined(__i386__) - #include #include + +#if defined(linux) && defined(__i386__) #include #ifdef USE_LIBC_VM86 diff -u xc/programs/Xserver/hw/xfree86/vga256/drivers/s3_savage.336/newmmio.h xc/programs/Xserver/hw/xfree86/vga256/drivers/s3_savage/newmmio.h --- xc/programs/Xserver/hw/xfree86/vga256/drivers/s3_savage.336/newmmio.h Fri Dec 3 10:46:00 1999 +++ xc/programs/Xserver/hw/xfree86/vga256/drivers/s3_savage/newmmio.h Wed Jan 26 01:44:43 2000 @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/vga256/drivers/s3_savage/newmmio.h,v 1.1.2.2 1999/12/01 12:49:32 hohndel Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/vga256/drivers/s3_savage/newmmio.h,v 1.1.2.1 1999/07/30 11:21:27 hohndel Exp $ */ /* Copied over from accel/s3_virge */ @@ -409,9 +409,9 @@ */ #define IN_SUBSYS_STAT() ((((mmtr)s3savMmioMem)->subsys_regs.regs.subsystem_csr)) #define SET_SUBSYS_CRTL(val) do { write_mem_barrier(); ((((mmtr)s3savMmioMem)->subsys_regs.regs.subsystem_csr)) = (val); write_mem_barrier(); } while (0) -#define STATUS_WORD0 (*(volatile unsigned int*)(((char*)s3savMmioMem) + 0x48C00)) +#define STATUS_WORD0 S3_IN32(0x48C00) /* Savage4 Rev B only: */ -#define ALT_STATUS_WORD0 (*(volatile unsigned int*)(((char*)s3savMmioMem) + 0x48C60)) +#define ALT_STATUS_WORD0 S3_IN32(0x48C60) #define SET_DAC_W_INDEX(index) outb(DAC_W_INDEX, index) diff -u xc/programs/Xserver/hw/xfree86/vga256/drivers/s3_savage.336/regs3sav.h xc/programs/Xserver/hw/xfree86/vga256/drivers/s3_savage/regs3sav.h --- xc/programs/Xserver/hw/xfree86/vga256/drivers/s3_savage.336/regs3sav.h Fri Dec 3 10:46:00 1999 +++ xc/programs/Xserver/hw/xfree86/vga256/drivers/s3_savage/regs3sav.h Thu Feb 10 21:21:14 2000 @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/vga256/drivers/s3_savage/regs3sav.h,v 1.1.2.2 1999/12/01 12:49:32 hohndel Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/vga256/drivers/s3_savage/regs3sav.h,v 1.1.2.1 1999/07/30 11:21:28 hohndel Exp $ */ /* regs3v.h * @@ -55,6 +55,25 @@ }\ } +#if defined(__alpha__) +#define mb() __asm__ __volatile__("mb": : :"memory") +#define S3_IN8(addr) xf86ReadSparse8(s3savMmioMemSparse, (addr)) +#define S3_IN16(addr) xf86ReadSparse16(s3savMmioMemSparse, (addr)) +#define S3_IN32(addr) *(volatile CARD32 *)((char*)s3savMmioMem + (addr)) +#define S3_OUT8(addr, val) do { xf86WriteSparse8((val),s3savMmioMemSparse,(addr)); \ + mb();} while(0) +#define S3_OUT16(addr, val) do { xf86WriteSparse16((val),s3savMmioMemSparse,(addr)); \ + mb();} while(0) +#define S3_OUT32(addr, val) do { *(volatile CARD32 *)((char*)s3savMmioMem + (addr)) = (val); \ + mb();} while(0) +#else /* __alpha__ */ +#define S3_IN8(addr) *(volatile CARD8 *)((char*)s3savMmioMem + (addr)) +#define S3_IN16(addr) *(volatile CARD16 *)((char*)s3savMmioMem + (addr)) +#define S3_IN32(addr) *(volatile CARD32 *)((char*)s3savMmioMem + (addr)) +#define S3_OUT8(addr, val) *(volatile CARD8 *)((char*)s3savMmioMem + (addr)) = (val) +#define S3_OUT16(addr, val) *(volatile CARD16 *)((char*)s3savMmioMem + (addr)) = (val) +#define S3_OUT32(addr, val) *(volatile CARD32 *)((char*)s3savMmioMem + (addr)) = (val) +#endif /* __alpha__ */ #define S3_ViRGE_SERIES(chip) ((chip&0xfff0)==0x31e0) #define S3_ViRGE_GX2_SERIES(chip) (chip == S3_ViRGE_GX2) @@ -66,18 +85,9 @@ #define S3_ANY_SERIES(chip) ( S3_ViRGE_SERIES(chip) \ || S3_ViRGE_VX_SERIES(chip)) -#define S3_SAVAGE3D_SERIES(chip) ((chip == S3_SAVAGE3D_MV) ||\ - (chip == S3_SAVAGE3D)) -#define S3_SAVAGE_MX_SERIES(chip) ((chip == S3_SAVAGE_MX_MV) ||\ - (chip == S3_SAVAGE_MX)) -#define S3_SAVAGE_IX_SERIES(chip) ((chip == S3_SAVAGE_IX_MV) ||\ - (chip == S3_SAVAGE_IX)) -#define S3_SAVAGE_MXIX(chip) (S3_SAVAGE_MX_SERIES(chip) || \ - S3_SAVAGE_IX_SERIES(chip)) - -#define S3_SAVAGE_SERIES(chip) (((chip&0xfff0)==0x8a20) || \ - (chip==0x9102) || \ - S3_SAVAGE_MXIX(chip)) +#define S3_SAVAGE3D_SERIES(chip) ((chip>=S3_SAVAGE3D) && (chip<=S3_SAVAGE_MX)) + +#define S3_SAVAGE_SERIES(chip) ((chip>=S3_SAVAGE3D) && (chip<=S3_SAVAGE2000)) /* PCI data */ #define PCI_S3_VENDOR_ID 0x5333 @@ -89,6 +99,7 @@ #define PCI_SAVAGE_MX 0x8C11 #define PCI_SAVAGE_IX_MV 0x8C12 #define PCI_SAVAGE_IX 0x8C13 +#define PCI_SAVAGE_370 0x8A25 #define PCI_ViRGE 0x5631 #define PCI_ViRGE_VX 0x883D @@ -101,12 +112,10 @@ #define S3_UNKNOWN 0 #define S3_SAVAGE3D 1 #define S3_SAVAGE3D_MV 2 -#define S3_SAVAGE4 3 -#define S3_SAVAGE2000 4 -#define S3_SAVAGE_MX_MV 5 -#define S3_SAVAGE_MX 6 -#define S3_SAVAGE_IX_MV 7 -#define S3_SAVAGE_IX 8 +#define S3_SAVAGE_MX 3 +#define S3_SAVAGE4 4 +#define S3_SAVAGE_370 5 +#define S3_SAVAGE2000 6 #define S3_ViRGE 1 #define S3_ViRGE_VX 2 @@ -403,48 +412,48 @@ } LUTENTRY; -#define MAXLOOP 0xffffff /* timeout value for engine waits, ~6 secs */ +#define MAXLOOP 0xfffff /* timeout value for engine waits, ~6 secs */ /* * The correct value for MAXFIFO actually depends on the size of the * command-overflow-buffer in MM48C14. We happen to use 32K always. */ -#define MAXFIFO 0x80C0 /* Number of on-chip and off-chip FIFO slots */ -void S3VGEReset(int from_timeout, int line, char *file); +#define MAXFIFO 0x7f00 /* Number of on-chip and off-chip FIFO slots */ +void S3SAVGEReset(int from_timeout, int line, char *file); /* Wait until "v" queue entries are free */ #define WaitQueue(v) \ if( s3vPriv.NoPCIRetry ) { \ if( (*s3vPriv.WaitQueue)(v) ) \ - S3VGEReset(1,__LINE__,__FILE__); \ + S3SAVGEReset(1,__LINE__,__FILE__); \ } /* Wait until GP is idle and queue is empty */ #define WaitIdleEmpty() \ if( (*s3vPriv.WaitIdleEmpty)() ) { \ - /*S3VGEReset(1,__LINE__,__FILE__);*/ \ + /*S3SAVGEReset(1,__LINE__,__FILE__);*/ \ } /* Wait until GP is idle */ #define WaitIdle() \ if( s3vPriv.WaitIdle() ) { \ - /*S3VGEReset(1,__LINE__,__FILE__);*/ \ + /*S3SAVGEReset(1,__LINE__,__FILE__);*/ \ } /* Wait until Command FIFO is empty */ #define WaitCommandEmpty() \ if( s3vPriv.WaitCommandEmpty() ) { \ - /* S3VGEReset(1,__LINE__,__FILE__); */ \ + /* S3SAVGEReset(1,__LINE__,__FILE__); */ \ } /* Wait until a DMA transfer is done */ #define WaitDMAEmpty() \ do { int loop=0; mem_barrier(); \ while (((((mmtr)s3savMmioMem)->dma_regs.regs.cmd.write_pointer) != (((mmtr)s3savMmioMem)->dma_regs.regs.cmd.read_pointer)) && (loop++= MAXLOOP) S3VGEReset(1,__LINE__,__FILE__); \ + if (loop >= MAXLOOP) S3SAVGEReset(1,__LINE__,__FILE__); \ } while(0) #ifndef NULL diff -u xc/programs/Xserver/hw/xfree86/vga256/drivers/s3_savage.336/s3bci.h xc/programs/Xserver/hw/xfree86/vga256/drivers/s3_savage/s3bci.h --- xc/programs/Xserver/hw/xfree86/vga256/drivers/s3_savage.336/s3bci.h Fri Dec 3 10:46:00 1999 +++ xc/programs/Xserver/hw/xfree86/vga256/drivers/s3_savage/s3bci.h Thu Feb 3 03:19:00 2000 @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/vga256/drivers/s3_savage/s3bci.h,v 1.1.2.2 1999/12/01 12:49:33 hohndel Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/vga256/drivers/s3_savage/s3bci.h,v 1.1.2.1 1999/07/30 11:21:28 hohndel Exp $ */ #ifndef _S3BCI_H_ #define _S3BCI_H_ @@ -10,10 +10,11 @@ dword |= (temp & 0xFF0000) >> 8; \ dword |= (temp & 0xFF000000) >> 24; } -#define BCI_GET_PTR unsigned int * bci_ptr = s3vPriv.BciMem +#define BCI_GET_PTR volatile unsigned int * bci_ptr = s3vPriv.BciMem +#define BCI_RESET bci_ptr = s3vPriv.BciMem #if 1 -#define BCI_SEND(dw) ((*(unsigned int*)(bci_ptr++)) = (unsigned int)(dw)) +#define BCI_SEND(dw) (*bci_ptr++ = (unsigned int)(dw)) #else __inline__ void BCI_SEND_DEBUG(unsigned int * bci_base, unsigned int * bci_ptr, unsigned int dw) @@ -49,7 +50,7 @@ #define BCI_CMD_DEST_SBD 0x00001000 #define BCI_CMD_DEST_SBD_NEW 0x00001400 -#define BCI_CMD_SRC_TRANSPARENT 0x00000100 +#define BCI_CMD_SRC_TRANSPARENT 0x00000200 #define BCI_CMD_SRC_SOLID 0x00000000 #define BCI_CMD_SRC_GBD 0x00000020 #define BCI_CMD_SRC_COLOR 0x00000040 diff -u xc/programs/Xserver/hw/xfree86/vga256/drivers/s3_savage.336/s3bitmap.c xc/programs/Xserver/hw/xfree86/vga256/drivers/s3_savage/s3bitmap.c --- xc/programs/Xserver/hw/xfree86/vga256/drivers/s3_savage.336/s3bitmap.c Fri Dec 31 18:20:59 1999 +++ xc/programs/Xserver/hw/xfree86/vga256/drivers/s3_savage/s3bitmap.c Wed Jan 26 01:44:45 2000 @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/vga256/drivers/s3_savage/s3bitmap.c,v 1.1.2.4 1999/12/28 12:14:04 hohndel Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/vga256/drivers/s3_savage/s3bitmap.c,v 1.1.2.1 1999/07/30 11:21:30 hohndel Exp $ */ void SavageWriteBitmapScreenToScreenColorExpand ( @@ -13,7 +13,7 @@ { BCI_GET_PTR; unsigned int cmd; - unsigned int bd_offset; + unsigned char * bd_offset; unsigned int bd; cmd = BCI_CMD_RECT | BCI_CMD_RECT_XP | BCI_CMD_RECT_YP @@ -25,11 +25,11 @@ bd |= BCI_BD_BW_DISABLE; BCI_BD_SET_BPP(bd, 1); BCI_BD_SET_STRIDE(bd, srcwidth); - bd_offset = srcwidth * srcy + (srcx >> 3) + (int) src; + bd_offset = srcwidth * srcy + (srcx >> 3) + src; WaitQueue(10); BCI_SEND(cmd); - BCI_SEND(bd_offset); + BCI_SEND((unsigned int)bd_offset); BCI_SEND(bd); BCI_SEND(fg); BCI_SEND((bg != -1) ? bg : 0); @@ -62,7 +62,7 @@ cmd |= s3vAlu[rop]; if( !srcwidth ) - return; + return; BCI_SEND(cmd); BCI_SEND(BCI_CLIP_LR(x, x+w-1)); @@ -84,19 +84,19 @@ for (j = 0; j < h; j ++) { BCI_SEND(BCI_X_Y(x, y+j)); - BCI_SEND(BCI_W_H(w, 1)); - srcp = (unsigned int*) src; - for (i = count; i > 0; srcp ++, i --) { - /* We have to invert the bits in each byte. */ - unsigned long u = *srcp; - u = ((u & 0x0f0f0f0f) << 4) | ((u & 0xf0f0f0f0) >> 4); - u = ((u & 0x33333333) << 2) | ((u & 0xcccccccc) >> 2); - u = ((u & 0x55555555) << 1) | ((u & 0xaaaaaaaa) >> 1); - BCI_SEND(u); - } - src += srcwidth; + BCI_SEND(BCI_W_H(w, 1)); + srcp = (unsigned int*) src; + for (i = count; i > 0; srcp ++, i --) { + /* We have to invert the bits in each byte. */ + unsigned long u = *srcp; + u = ((u & 0x0f0f0f0f) << 4) | ((u & 0xf0f0f0f0) >> 4); + u = ((u & 0x33333333) << 2) | ((u & 0xcccccccc) >> 2); + u = ((u & 0x55555555) << 1) | ((u & 0xaaaaaaaa) >> 1); + BCI_SEND(u); + } + src += srcwidth; if( !--reset ) { - bci_ptr = s3vPriv.BciMem; + BCI_RESET; reset = 65536 / srcwidth; } } @@ -144,6 +144,6 @@ } for (i = count; i > 0; srcp ++, i --) { - BCI_SEND(*srcp); + BCI_SEND(*srcp); } } diff -u xc/programs/Xserver/hw/xfree86/vga256/drivers/s3_savage.336/s3sav_accel.c xc/programs/Xserver/hw/xfree86/vga256/drivers/s3_savage/s3sav_accel.c --- xc/programs/Xserver/hw/xfree86/vga256/drivers/s3_savage.336/s3sav_accel.c Fri Dec 3 10:46:01 1999 +++ xc/programs/Xserver/hw/xfree86/vga256/drivers/s3_savage/s3sav_accel.c Thu Feb 10 21:35:48 2000 @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/vga256/drivers/s3_savage/s3sav_accel.c,v 1.1.2.4 1999/12/02 12:30:36 hohndel Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/vga256/drivers/s3_savage/s3sav_accel.c,v 1.1.2.1 1999/07/30 11:21:31 hohndel Exp $ */ /* * @@ -7,7 +7,7 @@ */ /* - * The accel file for the ViRGE driver. + * The accel file for the Savage driver. * * Created 20/03/97 by Sebastien Marineau * Revision: @@ -38,6 +38,9 @@ /* Globals used in driver */ extern pointer s3savMmioMem; +#ifdef __alpha__ +extern pointer s3savMmioMemSparse; +#endif static int s3DummyTransferArea; static int s3LineHWClipSet = 0; @@ -103,15 +106,10 @@ void S3SAVInitialize2DEngine() { - unsigned long cobWater; - outw(vgaCRIndex, 0x0140); outb(vgaCRIndex, 0x31); outb(vgaCRReg, 0x0c); -#define S3_IN32(off) (*(volatile unsigned int*)(((char*)s3savMmioMem)+(off))) -#define S3_OUT32(off, val) (*(volatile unsigned int*)(((char*)s3savMmioMem)+(off)) = val) -#define S3_OUT16(off, val) (*(volatile unsigned short*)(((char*)s3savMmioMem)+(off)) = val) /* Setup plane masks */ S3_OUT32(0x8128, ~0); /* enable all write planes */ S3_OUT32(0x812C, ~0); /* enable all read planes */ @@ -120,24 +118,18 @@ if( s3vPriv.chip < S3_SAVAGE2000 ) { - /* Sav4 doc shows the smaller value in the upper DWORD. */ - /* However, that's not what the NT driver does. */ - if( s3vPriv.chip == S3_SAVAGE4 ) { - cobWater = (cob.Size >> 7) * 0x10001 - 0x01400300; - } - else { - cobWater = (cob.Size >> 2) * 0x10001 - 0x01C00EC0; - } /* Disable BCI */ S3_OUT32(0x48C18, S3_IN32(0x48C18) & 0x3FF0); /* Disable shadow status update */ S3_OUT32(0x48C0C, 0); /* Setup BCI command overflow buffer */ S3_OUT32(0x48C14, (cob.Offset >> 11) | (cob.Index << 29)); - /* Command overflow buffer HI/LOW watermarks */ - S3_OUT32(0x48C10, cobWater); /* Enable BCI and command overflow buffer */ - S3_OUT32(0x48C18, S3_IN32(0x48C18) | 0x0C); + if( (s3vPriv.chip == S3_SAVAGE4) || (s3vPriv.chip == S3_SAVAGE_370) ) + /* Disable COB on Savage4 */ + S3_OUT32(0x48C18, S3_IN32(0x48C18) | 0x08); + else + S3_OUT32(0x48C18, S3_IN32(0x48C18) | 0x0C); } else { @@ -147,9 +139,6 @@ S3_OUT32(0x48A30, 0); /* Setup BCI command overflow buffer */ S3_OUT32(0x48C18, (cob.Offset >> 7) | (cob.Index)); - /* Command overflow buffer HI/LOW watermarks */ - S3_OUT32(0x48C10, 0x6090); - S3_OUT32(0x48C14, 0x70A8); /* Enable BCI and command overflow buffer */ S3_OUT32(0x48C18, S3_IN32(0x48C18) | 0x00280000 ); } @@ -339,6 +328,7 @@ xf86AccelInfoRec.ColorExpandFlags = SCANLINE_PAD_DWORD | CPU_TRANSFER_PAD_DWORD | + BIT_ORDER_IN_BYTE_MSBFIRST | VIDEO_SOURCE_GRANULARITY_PIXEL | LEFT_EDGE_CLIPPING; /* WriteBitmap color expand */ @@ -355,13 +345,12 @@ S3SAVSubsequentCPUToScreenColorExpand; #endif -#if 0 +#if 1 xf86AccelInfoRec.SetupForCPUToScreenColorExpand = S3SAVSetupForCPUToScreenColorExpand; xf86AccelInfoRec.SubsequentCPUToScreenColorExpand = S3SAVSubsequentCPUToScreenColorExpand; xf86AccelInfoRec.CPUToScreenColorExpandBase = s3vPriv.BciMem; - (void *) &IMG_TRANS; xf86AccelInfoRec.CPUToScreenColorExpandRange = 128 * 1024; #endif @@ -405,7 +394,7 @@ * enabled the PIXMAP_CACHE flag, then these lines can be omitted. */ - if( s3vPriv.chip == S3_SAVAGE4 ) { + if( (s3vPriv.chip == S3_SAVAGE4) || (s3vPriv.chip == S3_SAVAGE_370) ) { cob.Index = 2 /*4*/; cob.Size = 0x8000 << cob.Index; } @@ -438,16 +427,6 @@ void S3SAVAccelSync() { -#if 0 - BCI_GET_PTR; - - WaitQueue(3); - BCI_SEND(BCI_CMD_NOP | BCI_CMD_CLIP_NEW); - BCI_SEND(BCI_CLIP_TL(0, 0)); - BCI_SEND(BCI_CLIP_BR(s3vPriv.ScissB, s3vPriv.Width)); -#endif - - WaitCommandEmpty(); WaitIdleEmpty(); } @@ -499,9 +478,11 @@ switch( s3vPriv.chip ) { case S3_SAVAGE3D: case S3_SAVAGE3D_MV: + case S3_SAVAGE_MX: success = (STATUS_WORD0 & 0x0008ffff) == 0x00080000; break; case S3_SAVAGE4: + case S3_SAVAGE_370: success = (ALT_STATUS_WORD0 & 0x0081ffff) == 0x00800000; break; case S3_SAVAGE2000: @@ -545,7 +526,7 @@ ErrorF("ViRGE register cache hits: %d misses: %d\n", s3vCacheHit, s3vCacheMiss); s3vCacheHit = 0; s3vCacheMiss = 0; - + S3SAVSetGBD(); } @@ -579,9 +560,7 @@ BCI_SEND(cmd); if (transparency_color != -1) { BCI_SEND(transparency_color); - ErrorF("CopyRect transparency\n"); } - /*ErrorF("CopyRect command 0x%.8x sent\n", cmd);*/ #endif s3SavedBciCmd = cmd; s3SavedBgColor = transparency_color; @@ -609,13 +588,11 @@ #if BCI_REPEAT WaitQueue(4); - if (s3SavedBgColor != -1) - BCI_SEND(s3SavedBgColor); BCI_SEND(BCI_X_Y(x1, y1)); BCI_SEND(BCI_X_Y(x2, y2)); BCI_SEND(BCI_W_H(w, h)); #else - WaitQueue(5); + WaitQueue(6); BCI_SEND(s3SavedBciCmd); if (s3SavedBgColor != -1) BCI_SEND(s3SavedBgColor); @@ -643,6 +620,16 @@ | BCI_CMD_RECT_XP | BCI_CMD_RECT_YP | BCI_CMD_DEST_GBD | BCI_CMD_SRC_SOLID; + /* Don't send a color if we don't have to. */ + + if( rop == GXcopy ) + { + if( color == 0 ) + rop = GXclear; + else if( color == MaxMask[s3vPriv.Bpp] ) + rop = GXset; + } + if( (rop != GXclear) && (rop != GXnoop) && @@ -690,7 +677,7 @@ BCI_SEND(BCI_X_Y(x, y)); BCI_SEND(BCI_W_H(w, h)); #else - WaitQueue(4); + WaitQueue(5); BCI_SEND(s3SavedBciCmd); if( s3SavedBciCmd & BCI_CMD_SEND_COLOR ) BCI_SEND(s3SavedFgColor); @@ -745,6 +732,7 @@ int cmd; cmd = BCI_CMD_RECT | BCI_CMD_RECT_XP | BCI_CMD_RECT_YP + | BCI_CMD_CLIP_LR | BCI_CMD_DEST_GBD | BCI_CMD_SRC_MONO; if( @@ -759,7 +747,8 @@ if (bg != -1) cmd |= BCI_CMD_SEND_COLOR; - else cmd |= BCI_CMD_SRC_TRANSPARENT; + else + cmd |= BCI_CMD_SRC_TRANSPARENT; #if BCI_REPEAT WaitQueue(3); @@ -783,51 +772,24 @@ WaitQueue(4); BCI_SEND(BCI_X_Y(x, y)); BCI_SEND(BCI_W_H(w, h)); - BCI_SEND(((w + 31) / 32) * h); #else + /* 7 is not enough. XAA will be sending bitmap data next. We */ + /* should probably wait for empty/idle here. */ + WaitQueue(7); - if ( 0 ) { + BCI_SEND(s3SavedBciCmd); -#if 0 - if(skipleft != 0) - BCI_SEND(BCI_CLIP_LR(x + skipleft, s3vPriv.Width)); - else - BCI_SEND(BCI_CLIP_LR(0, s3vPriv.Width)); -#endif - BCI_SEND(s3SavedFgColor); - if (s3SavedBgColor != -1) + BCI_SEND(BCI_CLIP_LR(x, x+w-1)); + x -= skipleft; + w += skipleft; + w = (w + 31) & ~31; + if( s3SavedBciCmd & BCI_CMD_SEND_COLOR ) + BCI_SEND(s3SavedFgColor); + if( s3SavedBgColor != -1 ) BCI_SEND(s3SavedBgColor); - else BCI_SEND(0); BCI_SEND(BCI_X_Y(x, y)); BCI_SEND(BCI_W_H(w, h)); - /*BCI_SEND(((w + 31) / 32) * h);*/ - } else { - int i, j, count; - s3SavedBciCmd = 0; - BCI_SEND(0x4bcc8060); - BCI_SEND(s3SavedFgColor); - BCI_SEND(s3SavedBgColor); - count = (w + 31) / 32; - for (j = 0; j < 1; j ++) { - BCI_SEND(BCI_X_Y(x, y+j)); - BCI_SEND(BCI_W_H(w, 1)); - for (i = count; i > 0; i--) { - BCI_SEND(0xffffffff); - } - } - } #endif - - if(S3SAVROPHasSrc(s3SavedBciCmd<<1)) { - xf86AccelInfoRec.CPUToScreenColorExpandBase = - (void *) bci_ptr; - xf86AccelInfoRec.ColorExpandFlags &= (~CPU_TRANSFER_BASE_FIXED); - } - else { /* Fix for XAA bug */ - xf86AccelInfoRec.CPUToScreenColorExpandBase = - (void *) &s3DummyTransferArea; - xf86AccelInfoRec.ColorExpandFlags |= CPU_TRANSFER_BASE_FIXED; - } } @@ -978,7 +940,7 @@ dx = x2 - x1; dy = y2 - y1; -#if 0 +#ifdef DEBUG_EXTRA ErrorF("TwoPointLine, (%4d,%4d)-(%4d,%4d), clr %08x, last pt %s\n", x1, y1, x2, y2, s3SavedFgColor, (bias & 0x100)?"NO ":"YES"); #endif @@ -1013,9 +975,10 @@ if( s3LineHWClipSet ) { cmd |= BCI_CMD_CLIP_CURRENT; + s3LineHWClipSet = FALSE; } - WaitQueue(5); + WaitQueue(5); BCI_SEND( cmd ); if( cmd & BCI_CMD_SEND_COLOR ) BCI_SEND( s3SavedFgColor ); @@ -1030,6 +993,10 @@ { BCI_GET_PTR; int cmd; + +#ifdef DEBUG_EXTRA + ErrorF("ClipRect, (%4d,%4d)-(%4d,%4d) \n", x1, y1, x2, y2 ); +#endif cmd = BCI_CMD_NOP | BCI_CMD_CLIP_NEW; WaitQueue(3); diff -u xc/programs/Xserver/hw/xfree86/vga256/drivers/s3_savage.336/s3sav_cursor.c xc/programs/Xserver/hw/xfree86/vga256/drivers/s3_savage/s3sav_cursor.c --- xc/programs/Xserver/hw/xfree86/vga256/drivers/s3_savage.336/s3sav_cursor.c Fri Dec 3 10:46:01 1999 +++ xc/programs/Xserver/hw/xfree86/vga256/drivers/s3_savage/s3sav_cursor.c Thu Mar 30 05:44:55 2000 @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/vga256/drivers/s3_savage/s3sav_cursor.c,v 1.1.2.2 1999/12/01 12:49:33 hohndel Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/vga256/drivers/s3_savage/s3sav_cursor.c,v 1.1.2.1 1999/07/30 11:21:32 hohndel Exp $ */ /* * @@ -110,8 +110,6 @@ * buffer. Savage4 requires 4k alignment for the cursor image. */ -#define S3_IN32(off) (*(unsigned int*)(((char*)s3savMmioMem)+(off))) - if( s3vPriv.chip < S3_SAVAGE2000) { s3vCursorVRAMMemSegment = (S3_IN32(0x48C14) & 0x3FFF) * 2 - 4; } else { @@ -416,16 +414,13 @@ xColorItem sourceColor, maskColor; Bool bNeedExtra = FALSE; - if( S3_SAVAGE_SERIES(s3vPriv.chip) ) + /* Clock doubled modes need an extra cursor stack write. */ + outb(0x3c4, 0x18); + if( inb(0x3c5) & 0x80 ) { - /* Clock doubled modes need an extra cursor stack write. */ - outb(0x3c4, 0x18); - if( inb(0x3c5) & 0x80 ) - { - outb(0x3c4, 0x15); - if( inb(0x3c5) & 0x50 ) - bNeedExtra = TRUE; - } + outb(0x3c4, 0x15); + if( inb(0x3c5) & 0x50 ) + bNeedExtra = TRUE; } if (!xf86VTSema) @@ -434,49 +429,31 @@ if (!displayed) return; - switch (vgaBitsPerPixel) { - case 8: - if (!(S3_ViRGE_GX2_SERIES(s3vPriv.chip) || S3_ViRGE_MX_SERIES(s3vPriv.chip))) { - vgaGetInstalledColormaps(pScr, &pmap); - sourceColor.red = pCurs->foreRed; - sourceColor.green = pCurs->foreGreen; - sourceColor.blue = pCurs->foreBlue; - FakeAllocColor(pmap, &sourceColor); - maskColor.red = pCurs->backRed; - maskColor.green = pCurs->backGreen; - maskColor.blue = pCurs->backBlue; - FakeAllocColor(pmap, &maskColor); - FakeFreeColor(pmap, sourceColor.pixel); - FakeFreeColor(pmap, maskColor.pixel); + /* + * The /MX family is apparently unique among the Savages, in that + * the cursor color is always straight RGB. The rest of the Savages + * use palettized values at 8-bit when not clock doubled. + */ - outb(vgaCRIndex, 0x45); - inb(vgaCRReg); /* reset stack pointer */ - outb(vgaCRIndex, 0x4A); - outb(vgaCRReg, sourceColor.pixel); - outb(vgaCRReg, sourceColor.pixel); - outb(vgaCRIndex, 0x45); - inb(vgaCRReg); /* reset stack pointer */ - outb(vgaCRIndex, 0x4B); - outb(vgaCRReg, maskColor.pixel); - outb(vgaCRReg, maskColor.pixel); - break; - } /* else fall through for ViRGE/MX... */ + if( s3vPriv.chip == S3_SAVAGE_MX ) + bNeedExtra = TRUE; + + switch (vgaBitsPerPixel) { case 16: - if (!(S3_ViRGE_GX2_SERIES(s3vPriv.chip) || S3_ViRGE_MX_SERIES(s3vPriv.chip))) { - if (vga256InfoRec.weight.green == 5 && s3vPriv.chip != S3_ViRGE_VX) { + if (vga256InfoRec.weight.green == 5) { packedcolfg = ((pCurs->foreRed & 0xf800) >> 1) | ((pCurs->foreGreen & 0xf800) >> 6) - | ((pCurs->foreBlue & 0xf800) >> 11); + | ((pCurs->foreBlue & 0xf800) >> 11); packedcolbg = ((pCurs->backRed & 0xf800) >> 1) | ((pCurs->backGreen & 0xf800) >> 6) - | ((pCurs->backBlue & 0xf800) >> 11); + | ((pCurs->backBlue & 0xf800) >> 11); } else { packedcolfg = ((pCurs->foreRed & 0xf800) >> 0) | ((pCurs->foreGreen & 0xfc00) >> 5) - | ((pCurs->foreBlue & 0xf800) >> 11); + | ((pCurs->foreBlue & 0xf800) >> 11); packedcolbg = ((pCurs->backRed & 0xf800) >> 0) | ((pCurs->backGreen & 0xfc00) >> 5) - | ((pCurs->backBlue & 0xf800) >> 11); + | ((pCurs->backBlue & 0xf800) >> 11); } outb(vgaCRIndex, 0x45); inb(vgaCRReg); /* reset stack pointer */ @@ -499,7 +476,35 @@ outb(vgaCRReg, packedcolbg>>8); } break; - } /* else fall through for ViRGE/MX... */ + case 8: + if( !bNeedExtra ) + { + vgaGetInstalledColormaps(pScr, &pmap); + sourceColor.red = pCurs->foreRed; + sourceColor.green = pCurs->foreGreen; + sourceColor.blue = pCurs->foreBlue; + FakeAllocColor(pmap, &sourceColor); + maskColor.red = pCurs->backRed; + maskColor.green = pCurs->backGreen; + maskColor.blue = pCurs->backBlue; + FakeAllocColor(pmap, &maskColor); + FakeFreeColor(pmap, sourceColor.pixel); + FakeFreeColor(pmap, maskColor.pixel); + + outb(vgaCRIndex, 0x45); + inb(vgaCRReg); /* reset stack pointer */ + outb(vgaCRIndex, 0x4A); + outb(vgaCRReg, sourceColor.pixel); + outb(vgaCRReg, sourceColor.pixel); + outb(vgaCRIndex, 0x45); + inb(vgaCRReg); /* reset stack pointer */ + outb(vgaCRIndex, 0x4B); + outb(vgaCRReg, maskColor.pixel); + outb(vgaCRReg, maskColor.pixel); + break; + } + /* else */ + /* FALLTHROUGH */ case 24: case 32: outb(vgaCRIndex, 0x45); @@ -513,7 +518,7 @@ inb(vgaCRReg); /* reset stack pointer */ outb(vgaCRIndex, 0x4B); outb(vgaCRReg, pCurs->backBlue >>8); - outb(vgaCRReg, pCurs->backGreen>>8); + outb(vgaCRReg, pCurs->backGreen>>8); outb(vgaCRReg, pCurs->backRed >>8); break; } diff -u xc/programs/Xserver/hw/xfree86/vga256/drivers/s3_savage.336/s3sav_driver.c xc/programs/Xserver/hw/xfree86/vga256/drivers/s3_savage/s3sav_driver.c --- xc/programs/Xserver/hw/xfree86/vga256/drivers/s3_savage.336/s3sav_driver.c Fri Dec 3 10:46:01 1999 +++ xc/programs/Xserver/hw/xfree86/vga256/drivers/s3_savage/s3sav_driver.c Mon Jun 19 22:11:04 2000 @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/vga256/drivers/s3_savage/s3sav_driver.c,v 1.1.2.4 1999/12/01 12:49:34 hohndel Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/vga256/drivers/s3_savage/s3sav_driver.c,v 1.1.2.1 1999/07/30 11:21:33 hohndel Exp $ */ /* * @@ -13,21 +13,16 @@ * Tim Roberts, 21-June-1999. */ -/* This is an intial version of the ViRGE driver for XAA +/* This is an intial version of the Savage driver for XAA * Started 09/03/97 by S. Marineau * * What works: - * - Supports PCI hardware, ViRGE and ViRGE/VX, probably ViRGE/DXGX - * - Supports 8bpp, 16bpp and 24bpp. There is some support for 32bpp. + * - Supports PCI or AGP hardware, Savage3D, 4 or 2000. + * - Supports 8bpp, 16bpp and 32. There is no support for 24bpp. * - VT switching seems to work well, no corruption. - * - A whole slew of XConfig options for memory, PCI and acceleration * - Acceleration is quite complete * * - * What does not work: - * - None of this doublescan stuff - * - * * What I attempt to do here: * * - Rewrite the init/save functions from the accel server such that they @@ -78,6 +73,8 @@ #include "s3sav_driver.h" #include "regs3sav.h" +static const char S3SAVVersionId[] = "$Version: s3_savage 1.0.11 $"; + /* * If the symbol USEBIOS is defined, we try to use the onboard BIOS to do * mode switches. We query the VESA BIOS list, and match the requested @@ -173,10 +170,8 @@ { S3_SAVAGE3D_MV, "Savage3D/MV"}, { S3_SAVAGE4, "Savage4"}, { S3_SAVAGE2000, "Savage2000"}, - { S3_SAVAGE_MX_MV, "Savage/MX-MV"}, { S3_SAVAGE_MX, "Savage/MX"}, - { S3_SAVAGE_IX_MV, "Savage/IX-MV"}, - { S3_SAVAGE_IX, "Savage/IX"}, + { S3_SAVAGE_370, "Savage/NB"}, { -1, ""}, }; @@ -189,6 +184,9 @@ int vgaCRIndex, vgaCRReg; pointer s3savMmioMem = NULL; /* MMIO base address */ +#ifdef __alpha__ +pointer s3savMmioMemSparse = NULL; +#endif extern vgaHWCursorRec vgaHWCursor; #ifdef USEBIOS @@ -196,7 +194,6 @@ /* Information about the current BIOS modes. */ #define iabs(a) ((int)(a)>0?(a):(-(a))) S3VMODETABLE * s3vModeTable = NULL; -unsigned short s3vModeCount = 0; #endif @@ -222,6 +219,27 @@ * three chips, and even the idle vs busy state flipped in the Sav2K */ +static void +ResetBCI2K() +{ + CARD32 cob = S3_IN32( 0x48c18 ); + /* if BCI is enabled and BCI is busy... */ + + if( + (cob & 0x00000008) && + ! (ALT_STATUS_WORD0 & 0x00200000) + ) + { + ErrorF( "Resetting BCI, stat = %08x...\n", ALT_STATUS_WORD0); + /* Turn off BCI */ + S3_OUT32( 0x48c18, cob & ~8 ); + usleep(10000); + /* Turn it back on */ + S3_OUT32( 0x48c18, cob ); + usleep(10000); + } +} + /* Wait until "v" queue entries are free */ static int @@ -231,6 +249,7 @@ int slots = MAXFIFO - v; mem_barrier(); + loop &= STATUS_WORD0; while( ((STATUS_WORD0 & 0x0000ffff) > slots) && (loop++ < MAXLOOP)) ; return loop >= MAXLOOP; @@ -245,7 +264,7 @@ if( !s3vPriv.NoPCIRetry ) return; mem_barrier(); - while( ((ALT_STATUS_WORD0 & 0x0001ffff) > slots) && (loop++ < MAXLOOP)) + while( ((ALT_STATUS_WORD0 & 0x001fffff) > slots) && (loop++ < MAXLOOP)) ; return loop >= MAXLOOP; } @@ -261,6 +280,8 @@ mem_barrier(); while( ((ALT_STATUS_WORD0 & 0x000fffff) > slots) && (loop++ < MAXLOOP)) ; + if( loop >= MAXLOOP ) + ResetBCI2K(); return loop >= MAXLOOP; } @@ -271,6 +292,7 @@ { int loop = 0; mem_barrier(); + loop &= STATUS_WORD0; while( ((STATUS_WORD0 & 0x0008ffff) != 0x80000) && (loop++ < MAXLOOP) ) ; return loop >= MAXLOOP; @@ -281,7 +303,7 @@ { int loop = 0; mem_barrier(); - while( ((ALT_STATUS_WORD0 & 0x0081ffff) != 0x00800000) && (loop++ < MAXLOOP) ) + while( ((ALT_STATUS_WORD0 & 0x00a1ffff) != 0x00a00000) && (loop++ < MAXLOOP) ) ; return loop >= MAXLOOP; } @@ -291,8 +313,13 @@ { int loop = 0; mem_barrier(); + /* CAUTION! How do we insure this read isn't optimized away? */ + /* Is the "volatile" enough to do that? */ + loop &= ALT_STATUS_WORD0; while( ((ALT_STATUS_WORD0 & 0x009fffff) != 0) && (loop++ < MAXLOOP) ) ; + if( loop >= MAXLOOP ) + ResetBCI2K(); return loop >= MAXLOOP; } @@ -323,6 +350,7 @@ { int loop = 0; mem_barrier(); + loop &= ALT_STATUS_WORD0; while( (ALT_STATUS_WORD0 & 0x00900000) && (loop++ < MAXLOOP) ) ; return loop >= MAXLOOP; @@ -355,6 +383,8 @@ mem_barrier(); while( (ALT_STATUS_WORD0 & 0x001fffff) && (loop++ < MAXLOOP) ) ; + if( loop >= MAXLOOP ) + ResetBCI2K(); return loop >= MAXLOOP; } @@ -392,10 +422,12 @@ outb(vgaCRIndex, 0x38); /* for register CR38, (REG_LOCK1) */ outb(vgaCRReg, 0x48); /* unlock S3 register set for read/write */ outb(vgaCRIndex, 0x39); - outb(vgaCRReg, 0xa5); + outb(vgaCRReg, 0xa0); + #if 0 outb(vgaCRIndex, 0x40); tmp = inb(vgaCRReg); outb(vgaCRReg, tmp & ~0x01); /* avoid lockups when reading I/O port 0x92e8 */ + #endif enterCalled = TRUE; } @@ -512,49 +544,52 @@ /* Patch CR79. These values are magical. */ - outb(vgaCRIndex, 0x6d); - cr6d = inb(vgaCRReg); + if( s3vPriv.chip != S3_SAVAGE_MX ) + { + outb(vgaCRIndex, 0x6d); + cr6d = inb(vgaCRReg); - cr79 = 0x04; + cr79 = 0x04; - if( vga256InfoRec.displayWidth >= 1024 ) - { - if( vgaBitsPerPixel == 32 ) + if( vga256InfoRec.displayWidth >= 1024 ) { - if( restore->refresh >= 130 ) - cr79 = 0x03; - else if( vga256InfoRec.displayWidth >= 1280 ) - cr79 = 0x02; - else if( - (vga256InfoRec.displayWidth == 1024) && - (restore->refresh >= 75) - ) + if( vgaBitsPerPixel == 32 ) { - if( cr6d && LCD_ACTIVE ) - cr79 = 0x05; - else - cr79 = 0x08; + if( restore->refresh >= 130 ) + cr79 = 0x03; + else if( vga256InfoRec.displayWidth >= 1280 ) + cr79 = 0x02; + else if( + (vga256InfoRec.displayWidth == 1024) && + (restore->refresh >= 75) + ) + { + if( cr6d && LCD_ACTIVE ) + cr79 = 0x05; + else + cr79 = 0x08; + } } - } - else if( vgaBitsPerPixel == 16) - { -/* The windows driver uses 0x13 for 16-bit 130Hz, but I see terrible - * screen artifacts with that value. Let's keep it low for now. - * if( restore->refresh >= 130 ) - * cr79 = 0x13; - * else - */ - if( vga256InfoRec.displayWidth == 1024 ) + else if( vgaBitsPerPixel == 16) { - if( cr6d && LCD_ACTIVE ) - cr79 = 0x08; - else - cr79 = 0x0e; + /* The windows driver uses 0x13 for 16-bit 130Hz, but I see terrible + * screen artifacts with that value. Let's keep it low for now. + * if( restore->refresh >= 130 ) + * cr79 = 0x13; + * else + */ + if( vga256InfoRec.displayWidth == 1024 ) + { + if( cr6d && LCD_ACTIVE ) + cr79 = 0x08; + else + cr79 = 0x0e; + } } } } - if( s3vPriv.chip != S3_SAVAGE2000) + if( (s3vPriv.chip != S3_SAVAGE2000) && (s3vPriv.chip != S3_SAVAGE_MX) ) outw(vgaCRIndex, (cr79 << 8) | 0x79); /* Make sure 16-bit memory access is enabled. */ @@ -584,7 +619,7 @@ outb(vgaCRIndex, 0x73); outb(vgaCRReg, inb(vgaCRReg) & 0xdf ); } - else + else if( s3vPriv.chip != S3_SAVAGE_MX ) { outb(vgaCRIndex, 0x68); if( !(inb(vgaCRReg) & 0x80) ) @@ -616,6 +651,18 @@ S3SAVDisableSTREAMS(); /* If STREAMS was running, disable it */ } +#ifdef USEBIOS + /* + * Some Savage/MX and /IX systems go nuts when trying to exit the + * server after WindowMaker has displayed a gradient background. I + * haven't been able to find what causes it, but a non-destructive + * switch to mode 3 here seems to eliminate the issue. + */ + + if( s3vPriv.chip == S3_SAVAGE_MX ) + S3SAVSetTextMode(); +#endif + /* Restore S3 extended regs */ outb(vgaCRIndex, 0x66); outb(vgaCRReg, restore->CR66); @@ -623,6 +670,8 @@ outb(vgaCRReg, restore->CR3A); outb(vgaCRIndex, 0x31); outb(vgaCRReg, restore->CR31); + outb(vgaCRIndex, 0x32); + outb(vgaCRReg, restore->CR32); outb(vgaCRIndex, 0x58); outb(vgaCRReg, restore->CR58); @@ -637,6 +686,19 @@ outb(0x3c4, 0x15); outb(0x3c5, restore->SR15); + /* Restore flat panel expansion regsters. */ + if( s3vPriv.chip == S3_SAVAGE_MX ) { + int i; + for( i = 0; i < 8; i++ ) { + outb(0x3c4, 0x54+i); + outb(0x3c5, restore->SR54[i]); + } + } + + outb(vgaCRIndex, 0x67); + cr67 = inb(vgaCRReg) & 0xf; /* Possible hardware bug on VX? */ + outb(vgaCRReg, 0); + /* Restore the standard VGA registers */ vgaHWRestore((vgaHWPtr)restore); @@ -660,7 +722,9 @@ /* Restore the desired video mode with CR67 */ outb(vgaCRIndex, 0x67); +#if 0 cr67 = inb(vgaCRReg) & 0xf; /* Possible hardware bug on VX? */ +#endif outb(vgaCRReg, 0x50 | cr67); usleep(10000); outb(vgaCRIndex, 0x67); @@ -703,6 +767,9 @@ outb(vgaCRIndex, 0xB0); /* Savage4 config3 */ outb(vgaCRReg, restore->CRB0); + outb(vgaCRIndex, 0x32); + outb(vgaCRReg, restore->CR32); + /* Unlock extended sequencer regs */ outb(0x3c4, 0x08); outb(0x3c5, 0x06); @@ -890,13 +957,15 @@ outb(0x3c5, 0x06); /* Now we save all the s3 extended regs we need */ - outb(vgaCRIndex, 0x31); + outb(vgaCRIndex, 0x31); save->CR31 = inb(vgaCRReg); - outb(vgaCRIndex, 0x34); + outb(vgaCRIndex, 0x32); + save->CR32 = inb(vgaCRReg); + outb(vgaCRIndex, 0x34); save->CR34 = inb(vgaCRReg); - outb(vgaCRIndex, 0x36); + outb(vgaCRIndex, 0x36); save->CR36 = inb(vgaCRReg); - outb(vgaCRIndex, 0x3a); + outb(vgaCRIndex, 0x3a); save->CR3A = inb(vgaCRReg); outb(vgaCRIndex, 0x40); save->CR40 = inb(vgaCRReg); @@ -908,15 +977,15 @@ save->CR50 = inb(vgaCRReg); outb(vgaCRIndex, 0x51); save->CR51 = inb(vgaCRReg); - outb(vgaCRIndex, 0x53); + outb(vgaCRIndex, 0x53); save->CR53 = inb(vgaCRReg); - outb(vgaCRIndex, 0x58); + outb(vgaCRIndex, 0x58); save->CR58 = inb(vgaCRReg); - outb(vgaCRIndex, 0x66); + outb(vgaCRIndex, 0x66); save->CR66 = inb(vgaCRReg); - outb(vgaCRIndex, 0x67); + outb(vgaCRIndex, 0x67); save->CR67 = inb(vgaCRReg); - outb(vgaCRIndex, 0x68); + outb(vgaCRIndex, 0x68); save->CR68 = inb(vgaCRReg); outb(vgaCRIndex, 0x69); save->CR69 = inb(vgaCRReg); @@ -971,6 +1040,15 @@ outb(0x3c4, 0x18); save->SR18 = inb(0x3c5); + /* Save flat panel expansion regsters. */ + + if( s3vPriv.chip == S3_SAVAGE_MX ) { + int i; + for( i = 0; i < 8; i++ ) { + outb(0x3c4, 0x54+i); + save->SR54[i] = inb(0x3c5); + } + } /* And if streams is to be used, save that as well */ @@ -1066,58 +1144,58 @@ static Bool S3SAVProbe() { -S3PCIInformation *pciInfo = NULL; -unsigned char config1, m, n, n1, n2, cr66, sr8; -int mclk; -DisplayModePtr pMode, pEnd; - - if (vga256InfoRec.chipset) { - if (StrCaseCmp(vga256InfoRec.chipset,S3SAVIdent(0))) - return(FALSE); - } - - /* Start with PCI probing, this should get us quite far already */ - - pciInfo = S3SAVGetPCIInfo(); - if (!pciInfo) - return FALSE; - - if (pciInfo && pciInfo->MemBase && !vga256InfoRec.MemBase) { - if (pciInfo->ChipType >= S3_SAVAGE4) { - s3vPriv.MmioBase = pciInfo->MemBase + S3_NEWMMIO_REGBASE_S4; - s3vPriv.FrameBufferBase = pciInfo->MemBase1; - } - else { + S3PCIInformation *pciInfo = NULL; + unsigned char config1, m, n, n1, n2, cr66, sr8; + int mclk; + DisplayModePtr pMode, pEnd; + + if (vga256InfoRec.chipset) { + if (StrCaseCmp(vga256InfoRec.chipset,S3SAVIdent(0))) + return(FALSE); + } + + /* Start with PCI probing, this should get us quite far already */ + + pciInfo = S3SAVGetPCIInfo(); + if (!pciInfo) + return FALSE; + + if( !S3_SAVAGE_SERIES(pciInfo->ChipType) ) { + if (xf86Verbose > 1) + ErrorF("%s %s: Unsupported (non-Savage) S3 chipset detected!\n", + XCONFIG_PROBED, vga256InfoRec.name); + return FALSE; + } + else { + s3vPriv.chip = pciInfo->ChipType; + ErrorF("%s %s: Detected S3 %s\n", XCONFIG_PROBED, vga256InfoRec.name, + xf86TokenToString(s3savChipTable, s3vPriv.chip)); + ErrorF("%s %s: using driver for chipset \"%s\"\n",XCONFIG_PROBED, + vga256InfoRec.name, S3SAVIdent(0)); + } + + if( vgaBitsPerPixel == 24 ) { + ErrorF("%s %s: %s: This server cannot do depth 24. Use depth 32.", + XCONFIG_GIVEN, vga256InfoRec.name, vga256InfoRec.chipset + ); + return FALSE; + } + + if( pciInfo->MemBase && !vga256InfoRec.MemBase) { + if( S3_SAVAGE3D_SERIES(pciInfo->ChipType) ) { s3vPriv.MmioBase = pciInfo->MemBase + S3_NEWMMIO_REGBASE_S3; s3vPriv.FrameBufferBase = pciInfo->MemBase; } - vga256InfoRec.MemBase = s3vPriv.FrameBufferBase; - } - if (pciInfo) - if(pciInfo->ChipType != S3_SAVAGE3D && - pciInfo->ChipType != S3_SAVAGE3D_MV && - pciInfo->ChipType != S3_SAVAGE4 && - pciInfo->ChipType != S3_SAVAGE2000){ - if (xf86Verbose > 1) - ErrorF("%s %s: Unsupported (non-Savage) S3 chipset detected!\n", - XCONFIG_PROBED, vga256InfoRec.name); - return FALSE; - } else { - s3vPriv.chip = pciInfo->ChipType; - ErrorF("%s %s: Detected S3 %s\n",XCONFIG_PROBED, - vga256InfoRec.name, xf86TokenToString(s3savChipTable, s3vPriv.chip)); - ErrorF("%s %s: using driver for chipset \"%s\"\n",XCONFIG_PROBED, - vga256InfoRec.name, S3SAVIdent(0)); - } + s3vPriv.MmioBase = pciInfo->MemBase + S3_NEWMMIO_REGBASE_S4; + s3vPriv.FrameBufferBase = pciInfo->MemBase1; + } + } vga256InfoRec.chipset = S3SAVIdent(0); -#ifdef __alpha__ - if (xf86bpp > 16) - FatalError("%s %s: %d bpp not yet supported for Alpha/AXP\n", - XCONFIG_GIVEN, vga256InfoRec.name, xf86bpp); -#endif + if( s3vPriv.FrameBufferBase && !vga256InfoRec.MemBase ) + vga256InfoRec.MemBase = (CARD32)s3vPriv.FrameBufferBase; /* Add/enable IO ports to list: call EnterLeave */ S3SAVEnterLeave(ENTER); @@ -1139,48 +1217,34 @@ /* And compute the amount of video memory and offscreen memory */ s3vPriv.MemOffScreen = 0; if (!vga256InfoRec.videoRam) { - if( (s3vPriv.ChipId == PCI_SAVAGE4) || - (s3vPriv.ChipId == PCI_SAVAGE2000) - ) { - switch (config1 >> 5) { - case 0: - vga256InfoRec.videoRam = 2; - break; - case 1: - vga256InfoRec.videoRam = 4; + static unsigned char RamSavage3D[] = { 8, 4, 4, 2 }; + static unsigned char RamSavage4[] = { 2, 4, 8, 12, 16, 32, 64, 2 }; + static unsigned char RamSavageMX[] = { 2, 8, 4, 16, 8, 16, 4, 16 }; + static unsigned char RamSavageNB[] = { 0, 2, 4, 8, 16, 32, 2, 2 }; + + switch( s3vPriv.chip ) { + case S3_SAVAGE3D: + case S3_SAVAGE3D_MV: + vga256InfoRec.videoRam = RamSavage3D[ (config1 & 0xC0) >> 6 ]; break; - case 2: - vga256InfoRec.videoRam = 8; - break; - case 3: - vga256InfoRec.videoRam = 12; - break; - case 4: - vga256InfoRec.videoRam = 16; + + case S3_SAVAGE4: + case S3_SAVAGE2000: + vga256InfoRec.videoRam = RamSavage4[ (config1 & 0xE0) >> 5 ]; break; - case 5: - vga256InfoRec.videoRam = 32; + + case S3_SAVAGE_MX: + vga256InfoRec.videoRam = RamSavageMX[ (config1 & 0x0E) >> 1 ]; break; - case 6: - vga256InfoRec.videoRam = 64; + + case S3_SAVAGE_370: + vga256InfoRec.videoRam = RamSavageNB[ (config1 & 0xE0) >> 5 ]; break; + default: - vga256InfoRec.videoRam = 2; - } - } - else { - switch((config1 & 0xC0) >> 6) { - case 0: - vga256InfoRec.videoRam = 8; - break; - case 1: - case 2: - vga256InfoRec.videoRam = 4; + /* How did we get here? */ + vga256InfoRec.videoRam = 0; break; - case 3: - default: - vga256InfoRec.videoRam = 2; - } } vga256InfoRec.videoRam *= 1024; @@ -1217,27 +1281,17 @@ if (vga256InfoRec.dacSpeeds[3] <= 0 && vga256InfoRec.dacSpeeds[2] > 0) vga256InfoRec.dacSpeeds[3] = vga256InfoRec.dacSpeeds[2]; - if (s3vPriv.chip == S3_SAVAGE3D || - s3vPriv.chip == S3_SAVAGE3D_MV || - s3vPriv.chip == S3_SAVAGE4 || - s3vPriv.chip == S3_SAVAGE2000) { - if (vga256InfoRec.dacSpeeds[0] <= 0) vga256InfoRec.dacSpeeds[0] = 250000; - if (vga256InfoRec.dacSpeeds[1] <= 0) vga256InfoRec.dacSpeeds[1] = 250000; - if (vga256InfoRec.dacSpeeds[2] <= 0) vga256InfoRec.dacSpeeds[2] = 220000; - if (vga256InfoRec.dacSpeeds[3] <= 0) vga256InfoRec.dacSpeeds[3] = 220000; - } - else { - if (vga256InfoRec.dacSpeeds[0] <= 0) vga256InfoRec.dacSpeeds[0] = 250000; - if (vga256InfoRec.dacSpeeds[1] <= 0) vga256InfoRec.dacSpeeds[1] = 250000; - if (vga256InfoRec.dacSpeeds[2] <= 0) vga256InfoRec.dacSpeeds[2] = 220000; - if (vga256InfoRec.dacSpeeds[3] <= 0) vga256InfoRec.dacSpeeds[3] = 220000; - } + if (vga256InfoRec.dacSpeeds[0] <= 0) vga256InfoRec.dacSpeeds[0] = 250000; + if (vga256InfoRec.dacSpeeds[1] <= 0) vga256InfoRec.dacSpeeds[1] = 250000; + if (vga256InfoRec.dacSpeeds[2] <= 0) vga256InfoRec.dacSpeeds[2] = 220000; + if (vga256InfoRec.dacSpeeds[3] <= 0) vga256InfoRec.dacSpeeds[3] = 220000; /* Set status word positions based on chip type. */ switch( s3vPriv.chip ) { case S3_SAVAGE3D: case S3_SAVAGE3D_MV: + case S3_SAVAGE_MX: s3vPriv.WaitQueue = WaitQueue3D; s3vPriv.WaitIdle = WaitIdle3D; s3vPriv.WaitIdleEmpty = WaitIdleEmpty3D; @@ -1245,6 +1299,7 @@ break; case S3_SAVAGE4: + case S3_SAVAGE_370: s3vPriv.WaitQueue = WaitQueue4; s3vPriv.WaitIdle = WaitIdle4; s3vPriv.WaitIdleEmpty = WaitIdleEmpty4; @@ -1325,7 +1380,7 @@ s3vPriv.HorizScaleFactor = 1; } else if (vgaBitsPerPixel == 16){ - s3vPriv.HorizScaleFactor = 2; + s3vPriv.HorizScaleFactor = 1; } else { s3vPriv.HorizScaleFactor = 1; @@ -1333,8 +1388,14 @@ /* And map MMIO memory, abort if we cannot */ - s3savMmioMem = xf86MapVidMem(vga256InfoRec.scrnIndex, MMIO_REGION, - (pointer) s3vPriv.MmioBase, S3_NEWMMIO_REGSIZE); +#ifdef __alpha__ + s3savMmioMemSparse = xf86MapVidMemSparse( + vga256InfoRec.scrnIndex, MMIO_REGION, + s3vPriv.MmioBase, S3_NEWMMIO_REGSIZE); +#endif + s3savMmioMem = xf86MapVidMem( + vga256InfoRec.scrnIndex, MMIO_REGION, + s3vPriv.MmioBase, S3_NEWMMIO_REGSIZE); s3vPriv.MmioMem = s3savMmioMem; s3vPriv.BciMem = (char*)s3vPriv.MmioMem + 0x10000; @@ -1352,38 +1413,31 @@ #ifdef USEBIOS /* Go probe the BIOS for all the modes and refreshes at this depth. */ - /* - * What I want here is an array of all mode numbers valid for this - * depth, and the list of valid refresh rates to go with them. - * - * x, y, mode, array[8] of refresh - */ - if( s3vModeTable ) { - xfree( s3vModeTable ); + S3SAVFreeBIOSModeTable( &s3vModeTable ); } - s3vModeCount = S3SAVGetBIOSModeCount( vgaBitsPerPixel ); + s3vModeTable = S3SAVGetBIOSModeTable( vgaBitsPerPixel ); - if( !s3vModeCount ) { + if( !s3vModeTable || !s3vModeTable->NumModes ) { FatalError("%s %s: Failed to fetch any BIOS modes.\n", XCONFIG_PROBED, vga256InfoRec.name ); } - s3vModeTable = (S3VMODETABLE*)xcalloc(sizeof(S3VMODETABLE), s3vModeCount); - S3SAVGetBIOSModeTable( vgaBitsPerPixel, s3vModeTable ); - if( xf86Verbose ) { int i; - S3VMODETABLE* pmt; + PS3VMODEENTRY pmt; - ErrorF("%s %s: Found %d modes at this depth:\n", - XCONFIG_PROBED, vga256InfoRec.name, s3vModeCount); + ErrorF( "%s %s: Found %d modes at this depth:\n", + XCONFIG_PROBED, vga256InfoRec.name, s3vModeTable->NumModes); - for( i = 0, pmt = s3vModeTable; i < s3vModeCount; i++, pmt++ ) + for( + i = 0, pmt = s3vModeTable->Modes; + i < s3vModeTable->NumModes; + i++, pmt++ ) { int j; ErrorF( "[%03x] %d x %d", pmt->VesaMode, pmt->Width, pmt->Height ); @@ -1480,9 +1534,7 @@ ErrorF("%s %s: %s: Horizontal mode timing overflow (%d)\n", XCONFIG_PROBED, vga256InfoRec.name, vga256InfoRec.chipset, mode->HTotal); -#ifndef USEBIOS return MODE_BAD; -#endif } if (mode->VTotal > 2047) { if(verbose) @@ -1530,7 +1582,8 @@ unsigned char tmp; if(s3vPriv.STREAMSRunning == FALSE) { - Base = ((y * vga256InfoRec.displayWidth + x) + /* We can only adjust to even x's. */ + Base = ((y * vga256InfoRec.displayWidth + (x & ~1)) * (vgaBitsPerPixel / 8)) >> 2; if (vgaBitsPerPixel == 24) Base = Base+2 - (Base+2) % 3; @@ -1538,8 +1591,7 @@ /* Now program the start address registers */ outw(vgaCRIndex, (Base & 0x00FF00) | 0x0C); outw(vgaCRIndex, ((Base & 0x00FF) << 8) | 0x0D); - outb(vgaCRIndex, 0x69); - outb(vgaCRReg, (Base & 0xFF0000) >> 16); + outw(vgaCRIndex, ((Base & 0xFF0000) >> 8) | 0x69); } else { /* Change start address for STREAMS case */ VerticalRetraceWait(); @@ -1643,7 +1695,7 @@ int i, j; unsigned int Refresh; #ifdef USEBIOS -S3VMODETABLE * pmt; +S3VMODEENTRY * pmt; #endif /* First we adjust the horizontal timings if needed */ @@ -1678,7 +1730,9 @@ ErrorF( "Desired refresh rate = %dHz\n", Refresh ); #endif - for( i = 0, pmt = s3vModeTable; i < s3vModeCount; i++, pmt++ ) + for( i = 0, pmt = s3vModeTable->Modes; + i < s3vModeTable->NumModes; + i++, pmt++ ) { if( (pmt->Width == mode->HDisplay) && (pmt->Height == mode->VDisplay) ) { diff -u xc/programs/Xserver/hw/xfree86/vga256/drivers/s3_savage.336/s3sav_driver.h xc/programs/Xserver/hw/xfree86/vga256/drivers/s3_savage/s3sav_driver.h --- xc/programs/Xserver/hw/xfree86/vga256/drivers/s3_savage.336/s3sav_driver.h Fri Dec 3 10:46:01 1999 +++ xc/programs/Xserver/hw/xfree86/vga256/drivers/s3_savage/s3sav_driver.h Mon Jun 19 20:20:50 2000 @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/vga256/drivers/s3_savage/s3sav_driver.h,v 1.1.2.2 1999/12/01 12:49:34 hohndel Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/vga256/drivers/s3_savage/s3sav_driver.h,v 1.1.2.1 1999/07/30 11:21:34 hohndel Exp $ */ /* Header file for ViRGE server */ @@ -19,10 +19,10 @@ unsigned int refresh; unsigned char SR8, SR10, SR11, SR12, SR13, SR15, SR18, SR29; /* SR9-SR1C, ext seq. */ - /*unsigned char SR54, SR55, SR56, SR57;*/ + unsigned char SR54[8]; unsigned char Clock; unsigned char s3DacRegs[0x101]; - unsigned char CR31, CR33, CR34, CR36, CR3A, CR3B, CR3C; + unsigned char CR31, CR32, CR33, CR34, CR36, CR3A, CR3B, CR3C; unsigned char CR40, CR42, CR43, CR45; unsigned char CR50, CR51, CR53, CR58, CR5B, CR5D, CR5E; unsigned char CR65, CR66, CR67, CR68, CR69, CR6F; /* Video attrib. */ @@ -47,8 +47,8 @@ int DevID; int ChipType; int ChipRev; - unsigned long MemBase; - unsigned long MemBase1; + unsigned char * MemBase; + unsigned char * MemBase1; } S3PCIInformation; /* Private data structure used for storing all variables needed in driver */ @@ -57,8 +57,8 @@ typedef struct { int chip; unsigned short ChipId; - unsigned int MmioBase; - unsigned int FrameBufferBase; + unsigned char * MmioBase; + unsigned char * FrameBufferBase; pointer MmioMem; pointer BciMem; int MemOffScreen; @@ -82,13 +82,20 @@ /* VESA BIOS Mode information. */ #ifdef USEBIOS -typedef struct _S3VMODETABLE { + +typedef struct _S3VMODEENTRY { unsigned short Width; unsigned short Height; unsigned short VesaMode; unsigned char RefreshCount; - unsigned char RefreshRate[8]; + unsigned char * RefreshRate; +} S3VMODEENTRY, * PS3VMODEENTRY; + +typedef struct _S3VMODETABLE { + unsigned short NumModes; + S3VMODEENTRY Modes[1]; } S3VMODETABLE, * PS3VMODETABLE; + #endif /* Function prototypes */ @@ -99,8 +106,8 @@ extern void S3SAVWarpCursor(); extern void S3SAVQueryBestSize(); #ifdef USEBIOS -extern unsigned short S3SAVGetBIOSModeCount( int ); -extern unsigned short S3SAVGetBIOSModeTable( int, S3VMODETABLE* ); +extern S3VMODETABLE* S3SAVGetBIOSModeTable( int ); +extern void S3SAVFreeBIOSModeTable( S3VMODETABLE** ); extern void S3SAVSetVESAMode( int, int ); extern void S3SAVSetTextMode( ); #endif diff -u xc/programs/Xserver/hw/xfree86/vga256/drivers/s3_savage.336/s3sav_misc.c xc/programs/Xserver/hw/xfree86/vga256/drivers/s3_savage/s3sav_misc.c --- xc/programs/Xserver/hw/xfree86/vga256/drivers/s3_savage.336/s3sav_misc.c Mon Dec 20 17:39:33 1999 +++ xc/programs/Xserver/hw/xfree86/vga256/drivers/s3_savage/s3sav_misc.c Thu Feb 10 20:45:26 2000 @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/vga256/drivers/s3_savage/s3sav_misc.c,v 1.1.2.3 1999/12/20 14:36:28 hohndel Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/vga256/drivers/s3_savage/s3sav_misc.c,v 1.1.2.1 1999/07/30 11:21:35 hohndel Exp $ */ /* * @@ -48,10 +48,26 @@ #include "regs3sav.h" #include "s3sav_driver.h" +/** Why isn't all of this included in s3sav_driver.c? **/ + extern vgaPCIInformation *vgaPCIInfo; extern SymTabRec s3savChipTable[]; extern S3VPRIV s3vPriv; +static S3PCIInformation Mappings[] = { + { PCI_SAVAGE3D, S3_SAVAGE3D }, + { PCI_SAVAGE3D_MV, S3_SAVAGE3D_MV }, + { PCI_SAVAGE4, S3_SAVAGE4 }, + { PCI_SAVAGE2000, S3_SAVAGE2000 }, + { PCI_SAVAGE_MX_MV, S3_SAVAGE_MX }, + { PCI_SAVAGE_MX, S3_SAVAGE_MX }, + { PCI_SAVAGE_IX_MV, S3_SAVAGE_MX }, + { PCI_SAVAGE_IX, S3_SAVAGE_MX }, + { PCI_SAVAGE_370, S3_SAVAGE_370 }, +}; + +#define NMAPPINGS (sizeof(Mappings)/sizeof(Mappings[0])) + /* * s3vGetPCIInfo -- probe for PCI information @@ -68,42 +84,45 @@ if (vgaPCIInfo && vgaPCIInfo->AllCards) { while (pcrp = vgaPCIInfo->AllCards[i]) { - if (pcrp->_vendor == PCI_S3_VENDOR_ID && - (pcrp->_base_class == PCI_CLASS_DISPLAY) && - (pcrp->_sub_class == PCI_SUBCLASS_DISPLAY_VGA) && - pcrp->_command != 0) { + if((pcrp->_vendor == PCI_S3_VENDOR_ID) && + (pcrp->_base_class == PCI_CLASS_DISPLAY) && + (pcrp->_sub_class == PCI_SUBCLASS_DISPLAY_VGA) && + (pcrp->_command != 0) + ) { int ChipId = pcrp->_device; + int j; if (vga256InfoRec.chipID) { ErrorF("%s %s: S3 chipset override, using chip_id = 0x%04x instead of 0x%04x\n", XCONFIG_GIVEN, vga256InfoRec.name, vga256InfoRec.chipID, ChipId); ChipId = vga256InfoRec.chipID; } found = TRUE; + + for( j = 0; j < NMAPPINGS; j++ ) + { + if( ChipId == Mappings[j].DevID ) { + info.ChipType = Mappings[j].ChipType; + break; + } + } - switch (ChipId) { - case PCI_SAVAGE3D: - info.ChipType = S3_SAVAGE3D; - break; - case PCI_SAVAGE3D_MV: - info.ChipType = S3_SAVAGE3D_MV; - break; - case PCI_SAVAGE4: - info.ChipType = S3_SAVAGE4; - break; - case PCI_SAVAGE2000: - info.ChipType = S3_SAVAGE2000; - break; - default: - info.ChipType = S3_UNKNOWN; - info.DevID = pcrp->_device; - break; + if( j >= NMAPPINGS ) + { + info.ChipType = S3_UNKNOWN; + info.DevID = pcrp->_device; } + info.ChipRev = pcrp->_rev_id; - if( (ChipId == PCI_SAVAGE4) || (ChipId == PCI_SAVAGE2000) ) { - info.MemBase = pcrp->_base0 & 0xFFFFFFF0; - info.MemBase1 = pcrp->_base1 & 0xFFFFFFF0; + + info.MemBase = pcrp->_base0 & 0xFFFFFFF0; + + if( + (ChipId == PCI_SAVAGE4) || + (ChipId == PCI_SAVAGE2000) || + (ChipId == PCI_SAVAGE_370) + ) { + info.MemBase1 = pcrp->_base1 & 0xFFFFFFF0; } - else info.MemBase = pcrp->_base0 & 0xFFFFFFF0; break; } i++; diff -u xc/programs/Xserver/hw/xfree86/vga256/drivers/s3_savage.336/s3sav_vbe.c xc/programs/Xserver/hw/xfree86/vga256/drivers/s3_savage/s3sav_vbe.c --- xc/programs/Xserver/hw/xfree86/vga256/drivers/s3_savage.336/s3sav_vbe.c Fri Jul 30 13:21:37 1999 +++ xc/programs/Xserver/hw/xfree86/vga256/drivers/s3_savage/s3sav_vbe.c Mon Jun 19 22:37:41 2000 @@ -45,6 +45,8 @@ #include "vbe.h" #ifdef USEBIOS +unsigned short +S3SAVGetBIOSModes( int, S3VMODEENTRY* ); struct { @@ -137,16 +139,24 @@ void S3SAVSetTextMode(void) { - struct LRMI_regs r; + struct LRMI_regs r; - memset(&r, 0, sizeof(r)); + ioperm( 0x80, 1, 1 ); + ioperm( 0x61, 1, 1 ); + ioperm( 0x40, 4, 1 ); - r.eax = 3; + memset(&r, 0, sizeof(r)); + + r.eax = 0x83; + + if (!LRMI_int(0x10, &r)) + { + ErrorF("Can't set text mode (vm86 failure)\n"); + } - if (!LRMI_int(0x10, &r)) - { - ErrorF("Can't set text mode (vm86 failure)\n"); - } + ioperm( 0x40, 4, 0 ); + ioperm( 0x61, 1, 0 ); + ioperm( 0x80, 1, 1 ); } @@ -156,10 +166,12 @@ struct LRMI_regs r; /* - * The Savage BIOS also writes to a debug card on port 80h. It - * shouldn't, but we can work around it here. + * The Savage BIOS writes to a debug card on port 80h and to the + * timer chip at port 61. */ ioperm( 0x80, 1, 1 ); + ioperm( 0x61, 1, 1 ); + ioperm( 0x40, 4, 1 ); /* First, establish the refresh rate for this mode. */ @@ -177,13 +189,6 @@ /* Now, make this mode current. */ - /* - * The Savage BIOS reprograms the timer chip. One could argue that - * these ports should be virtualized rather than laid wide open. - */ - ioperm( 0x40, 4, 1 ); - ioperm( 0x61, 1, 1 ); - memset(&r, 0, sizeof(r)); r.eax = 0x4f02; @@ -204,15 +209,43 @@ } -unsigned short -S3SAVGetBIOSModeCount( int iDepth ) +void +S3SAVFreeBIOSModeTable( S3VMODETABLE** ppTable ) { - return S3SAVGetBIOSModeTable( iDepth, NULL ); + int i; + PS3VMODEENTRY pMode = (*ppTable)->Modes; + + for( i = (*ppTable)->NumModes; i--; ) + { + if( pMode->RefreshRate ) + { + xfree( pMode->RefreshRate ); + pMode->RefreshRate = NULL; + } + } + + xfree( *ppTable ); } +S3VMODETABLE* +S3SAVGetBIOSModeTable( int iDepth ) +{ + int nModes = S3SAVGetBIOSModes( iDepth, NULL ); + PS3VMODETABLE pTable; + + pTable = (PS3VMODETABLE) + xcalloc( 1, sizeof(S3VMODETABLE) + (nModes-1) * sizeof(S3VMODEENTRY) ); + if( !pTable ) + return NULL; + + pTable->NumModes = nModes; + S3SAVGetBIOSModes( iDepth, pTable->Modes ); + + return pTable; +} unsigned short -S3SAVGetBIOSModeTable( int iDepth, S3VMODETABLE* s3vModeTable ) +S3SAVGetBIOSModes( int iDepth, S3VMODEENTRY* s3vModeTable ) { struct LRMI_regs r; short int *mode_list; @@ -325,6 +358,26 @@ do { + if( (iRefresh % 8) == 0 ) + { + if( s3vModeTable->RefreshRate ) + { + s3vModeTable->RefreshRate = (unsigned char *) + xrealloc( + s3vModeTable->RefreshRate, + (iRefresh+8) * sizeof(unsigned char) + ); + } + else + { + s3vModeTable->RefreshRate = (unsigned char *) + xcalloc( + sizeof(unsigned char), + (iRefresh+8) + ); + } + } + r.eax = 0x4f14; r.ebx = 0x0201; /* query refresh rates */ if( !LRMI_int(0x10, &r) )