diff options
author | Kaleb Keithley <kaleb@freedesktop.org> | 2003-11-14 16:48:55 +0000 |
---|---|---|
committer | Kaleb Keithley <kaleb@freedesktop.org> | 2003-11-14 16:48:55 +0000 |
commit | 0a3d86ee8123b4ba2c54abbae6675b4bc010f428 (patch) | |
tree | 59f077b15f77e3ad91fda89bb238dc9eba92a61a /util | |
parent | 607c7f48bd004450fda196cd1e8029210cfba0c2 (diff) |
Initial revisionXORG-STABLE
Diffstat (limited to 'util')
-rw-r--r-- | util/AsmMacros.h | 450 | ||||
-rw-r--r-- | util/dRegs.c | 305 | ||||
-rw-r--r-- | util/mRegs.c | 186 | ||||
-rw-r--r-- | util/modClock.c | 412 |
4 files changed, 1353 insertions, 0 deletions
diff --git a/util/AsmMacros.h b/util/AsmMacros.h new file mode 100644 index 0000000..feb5ce0 --- /dev/null +++ b/util/AsmMacros.h @@ -0,0 +1,450 @@ +/* $XConsortium: AsmMacros.h /main/13 1996/10/25 11:33:12 kaleb $ */ +/* + * (c) Copyright 1993,1994 by David Wexelblat <dwex@xfree86.org> + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * DAVID WEXELBLAT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the name of David Wexelblat shall not be + * used in advertising or otherwise to promote the sale, use or other dealings + * in this Software without prior written authorization from David Wexelblat. + * + */ +/* + * Copyright 1997 + * Digital Equipment Corporation. All rights reserved. + * This software is furnished under license and may be used and copied only in + * accordance with the following terms and conditions. Subject to these + * conditions, you may download, copy, install, use, modify and distribute + * this software in source and/or binary form. No title or ownership is + * transferred hereby. + * + * 1) Any source code used, modified or distributed must reproduce and retain + * this copyright notice and list of conditions as they appear in the source + * file. + * + * 2) No right is granted to use any trade name, trademark, or logo of Digital + * Equipment Corporation. Neither the "Digital Equipment Corporation" name + * nor any trademark or logo of Digital Equipment Corporation may be used + * to endorse or promote products derived from this software without the + * prior written permission of Digital Equipment Corporation. + * + * 3) This software is provided "AS-IS" and any express or implied warranties, + * including but not limited to, any implied warranties of merchantability, + * fitness for a particular purpose, or non-infringement are disclaimed. In + * no event shall DIGITAL be liable for any damages whatsoever, and in + * particular, DIGITAL shall not be liable for special, indirect, + * consequential, or incidental damages or damages for + * lost profits, loss of revenue or loss of use, whether such damages arise + * in contract, + * negligence, tort, under statute, in equity, at law or otherwise, even if + * advised of the possibility of such damage. + * + */ + +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/chips/util/AsmMacros.h,v 1.1 2001/11/16 21:13:34 tsi Exp $ */ + +#if defined(__GNUC__) +#if defined(linux) && (defined(__alpha__) || defined(__ia64__)) +#undef inb +#undef inw +#undef inl +#undef outb +#undef outw +#undef outl +#define inb _inb +#define inw _inw +#define inl _inl +#define outb(p,v) _outb((v),(p)) +#define outw(p,v) _outw((v),(p)) +#define outl(p,v) _outl((v),(p)) +#else +#if defined(__sparc__) +#ifndef ASI_PL +#define ASI_PL 0x88 +#endif + +static __inline__ void +outb(port, val) +unsigned long port; +char val; +{ + __asm__ __volatile__("stba %0, [%1] %2" : : "r" (val), "r" (port), "i" (ASI_PL)); +} + +static __inline__ void +outw(port, val) +unsigned long port; +char val; +{ + __asm__ __volatile__("stha %0, [%1] %2" : : "r" (val), "r" (port), "i" (ASI_PL)); +} + +static __inline__ void +outl(port, val) +unsigned long port; +char val; +{ + __asm__ __volatile__("sta %0, [%1] %2" : : "r" (val), "r" (port), "i" (ASI_PL)); +} + +static __inline__ unsigned int +inb(port) +unsigned long port; +{ + unsigned char ret; + __asm__ __volatile__("lduba [%1] %2, %0" : "=r" (ret) : "r" (port), "i" (ASI_PL)); + return ret; +} + +static __inline__ unsigned int +inw(port) +unsigned long port; +{ + unsigned char ret; + __asm__ __volatile__("lduha [%1] %2, %0" : "=r" (ret) : "r" (port), "i" (ASI_PL)); + return ret; +} + +static __inline__ unsigned int +inl(port) +unsigned long port; +{ + unsigned char ret; + __asm__ __volatile__("lda [%1] %2, %0" : "=r" (ret) : "r" (port), "i" (ASI_PL)); + return ret; +} +#else +#ifdef __arm32__ +unsigned int IOPortBase; /* Memory mapped I/O port area */ + +static __inline__ void +outb(port, val) + short port; + char val; +{ + if ((unsigned short)port >= 0x400) return; + + *(volatile unsigned char*)(((unsigned short)(port))+IOPortBase) = val; +} + +static __inline__ void +outw(port, val) + short port; + short val; +{ + if ((unsigned short)port >= 0x400) return; + + *(volatile unsigned short*)(((unsigned short)(port))+IOPortBase) = val; +} + +static __inline__ void +outl(port, val) + short port; + int val; +{ + if ((unsigned short)port >= 0x400) return; + + *(volatile unsigned long*)(((unsigned short)(port))+IOPortBase) = val; +} + +static __inline__ unsigned int +inb(port) + short port; +{ + if ((unsigned short)port >= 0x400) return((unsigned int)-1); + + return(*(volatile unsigned char*)(((unsigned short)(port))+IOPortBase)); +} + +static __inline__ unsigned int +inw(port) + short port; +{ + if ((unsigned short)port >= 0x400) return((unsigned int)-1); + + return(*(volatile unsigned short*)(((unsigned short)(port))+IOPortBase)); +} + +static __inline__ unsigned int +inl(port) + short port; +{ + if ((unsigned short)port >= 0x400) return((unsigned int)-1); + + return(*(volatile unsigned long*)(((unsigned short)(port))+IOPortBase)); +} +#else /* __arm32__ */ +#if defined(Lynx) && defined(__powerpc__) +extern unsigned char *ioBase; + +static volatile void +eieio() +{ + __asm__ __volatile__ ("eieio"); +} + +static void +outb(port, value) +short port; +unsigned char value; +{ + *(uchar *)(ioBase + port) = value; eieio(); +} + +static void +outw(port, value) +short port; +unsigned short value; +{ + *(unsigned short *)(ioBase + port) = value; eieio(); +} + +static void +outl(port, value) +short port; +unsigned long value; +{ + *(unsigned long *)(ioBase + port) = value; eieio(); +} + +static unsigned char +inb(port) +short port; +{ + unsigned char val; + + val = *((unsigned char *)(ioBase + port)); eieio(); + return(val); +} + +static unsigned short +inw(port) +short port; +{ + unsigned short val; + + val = *((unsigned short *)(ioBase + port)); eieio(); + return(val); +} + +static unsigned long +inl(port) +short port; +{ + unsigned long val; + + val = *((unsigned long *)(ioBase + port)); eieio(); + return(val); +} + +#else +#if defined(__FreeBSD__) && defined(__alpha__) + +#include <sys/types.h> + +extern void outb(u_int32_t port, u_int8_t val); +extern void outw(u_int32_t port, u_int16_t val); +extern void outl(u_int32_t port, u_int32_t val); +extern u_int8_t inb(u_int32_t port); +extern u_int16_t inw(u_int32_t port); +extern u_int32_t inl(u_int32_t port); + +#else +#ifdef GCCUSESGAS +static __inline__ void +outb(port, val) +short port; +char val; +{ + __asm__ __volatile__("outb %0,%1" : :"a" (val), "d" (port)); +} + +static __inline__ void +outw(port, val) +short port; +short val; +{ + __asm__ __volatile__("outw %0,%1" : :"a" (val), "d" (port)); +} + +static __inline__ void +outl(port, val) +short port; +unsigned int val; +{ + __asm__ __volatile__("outl %0,%1" : :"a" (val), "d" (port)); +} + +static __inline__ unsigned int +inb(port) +short port; +{ + unsigned char ret; + __asm__ __volatile__("inb %1,%0" : + "=a" (ret) : + "d" (port)); + return ret; +} + +static __inline__ unsigned int +inw(port) +short port; +{ + unsigned short ret; + __asm__ __volatile__("inw %1,%0" : + "=a" (ret) : + "d" (port)); + return ret; +} + +static __inline__ unsigned int +inl(port) +short port; +{ + unsigned int ret; + __asm__ __volatile__("inl %1,%0" : + "=a" (ret) : + "d" (port)); + return ret; +} + +#else /* GCCUSESGAS */ + +static __inline__ void +outb(port, val) + short port; + char val; +{ + __asm__ __volatile__("out%B0 (%1)" : :"a" (val), "d" (port)); +} + +static __inline__ void +outw(port, val) + short port; + short val; +{ + __asm__ __volatile__("out%W0 (%1)" : :"a" (val), "d" (port)); +} + +static __inline__ void +outl(port, val) + short port; + unsigned int val; +{ + __asm__ __volatile__("out%L0 (%1)" : :"a" (val), "d" (port)); +} + +static __inline__ unsigned int +inb(port) + short port; +{ + unsigned int ret; + __asm__ __volatile__("in%B0 (%1)" : + "=a" (ret) : + "d" (port)); + return ret; +} + +static __inline__ unsigned int +inw(port) + short port; +{ + unsigned int ret; + __asm__ __volatile__("in%W0 (%1)" : + "=a" (ret) : + "d" (port)); + return ret; +} + +static __inline__ unsigned int +inl(port) + short port; +{ + unsigned int ret; + __asm__ __volatile__("in%L0 (%1)" : + "=a" (ret) : + "d" (port)); + return ret; +} + +#endif /* GCCUSESGAS */ +#endif /* Lynx && __powerpc__ */ +#endif /* arm32 */ +#endif /* linux && __sparc__ */ +#endif /* linux && __alpha__ */ +#endif /* __FreeBSD__ && __alpha__ */ + +#if defined(linux) || defined(__arm32__) || (defined(Lynx) && defined(__powerpc__)) + +#define intr_disable() +#define intr_enable() + +#else + +static __inline__ void +intr_disable() +{ + __asm__ __volatile__("cli"); +} + +static __inline__ void +intr_enable() +{ + __asm__ __volatile__("sti"); +} + +#endif /* else !linux && !__arm32__ */ + +#else /* __GNUC__ */ + +#if defined(_MINIX) && defined(_ACK) + +/* inb, outb, inw and outw are defined in the library */ +/* ... but I've no idea if the same is true for inl & outl */ + +u8_t inb(U16_t); +void outb(U16_t, U8_t); +u16_t inw(U16_t); +void outw(U16_t, U16_t); +u32_t inl(U16_t); +void outl(U16_t, U32_t); + +#else /* not _MINIX and _ACK */ + +# if defined(__STDC__) && (__STDC__ == 1) +# ifndef NCR +# define asm __asm +# endif +# endif +# ifdef SVR4 +# include <sys/types.h> +# ifndef __USLC__ +# define __USLC__ +# endif +# endif +#ifndef SCO325 +# include <sys/inline.h> +#else +# include "../common/scoasm.h" +#endif +#define intr_disable() asm("cli") +#define intr_enable() asm("sti") + +#endif /* _MINIX and _ACK */ +#endif /* __GNUC__ */ diff --git a/util/dRegs.c b/util/dRegs.c new file mode 100644 index 0000000..0c8ee62 --- /dev/null +++ b/util/dRegs.c @@ -0,0 +1,305 @@ +/* $XConsortium: dRegs.c /main/2 1996/10/27 11:49:40 kaleb $ */ + + + + + +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/chips/util/dRegs.c,v 1.9 2001/11/16 21:13:34 tsi Exp $ */ + +#ifdef __NetBSD__ +# include <sys/types.h> +# include <machine/pio.h> +# include <machine/sysarch.h> +#else +# if defined(SVR4) && defined(i386) +# include <sys/types.h> +# ifdef NCR + /* broken NCR <sys/sysi86.h> */ +# define __STDC +# include <sys/sysi86.h> +# undef __STDC +# else +# include <sys/sysi86.h> +# endif +# ifdef SVR4 +# if !defined(sun) +# include <sys/seg.h> +# endif +# endif +# include <sys/v86.h> +# if defined(sun) +# include <sys/psw.h> +# endif +# endif +# include "AsmMacros.h" +#endif /* NetBSD */ + +#include <unistd.h> +#include <stdio.h> +#include <stdlib.h> + +#ifdef __NetBSD__ +# define SET_IOPL() i386_iopl(3) +# define RESET_IOPL() i386_iopl(0) +#else +# if defined(SVR4) && defined(i386) +# ifndef SI86IOPL +# define SET_IOPL() sysi86(SI86V86,V86SC_IOPL,PS_IOPL) +# define RESET_IOPL() sysi86(SI86V86,V86SC_IOPL,0) +# else +# define SET_IOPL() sysi86(SI86IOPL,3) +# define RESET_IOPL() sysi86(SI86IOPL,0) +# endif +# else +# ifdef linux +# define SET_IOPL() iopl(3) +# define RESET_IOPL() iopl(0) +# else +# define SET_IOPL() (void)0 +# define RESET_IOPL() (void)0 +# endif +# endif +#endif + +int main(void) +{ + int i, HTotal, HDisplay, HSyncStart, HSyncEnd, + VTotal, VDisplay, VSyncStart, VSyncEnd; + unsigned char storeReg, bpp, shift, IOSS = 0, MSS = 0, again = 0; + unsigned short port; + int isHiQV = 0; + int is69030 = 0; + + SET_IOPL(); + + printf("0x3C6\t0x%X\n",inw(0x3C6)); + +/* Check to see if the Chip is HiQV */ + outb(0x3D6,0x02); + storeReg = inb(0x3D7); + if (storeReg == 0xE0 /* CT65550 */ + || storeReg == 0xE4 /* CT65554 */ + || storeReg == 0xE5 /* CT65555 */ + || storeReg == 0xF4 /* CT68554 */ + || storeReg == 0xC0) /* CT69000 */ + { + isHiQV = 1; + } else if (storeReg == 0x30) { + outb(0x3D6,0x03); + storeReg = inb(0x3D7); + if (storeReg == 0xC) { + isHiQV = 1; + is69030 = 1; + IOSS=inb(0x3CD); + MSS=inb(0x3CB); + outb(0x3CD,((IOSS&0xE0)| 0x11)); /* Select Channel 0 */ + outb(0x3CB,((MSS&0xF0)| 0x8)); + again = 1; + printf("Pipeline A:\n"); + } + } + + again: + printf("port 0x3D6 (C&T)\n"); + storeReg = inb(0x3D6); + shift = 3; + if (isHiQV==1) { + outw(0x102,1); /*global enable, VGA awake*/ + printf("0x%2.2X\n",inb(0x3C3)&0xFF); + outb(0x3C3,0); /*disable VGA*/ + outb(0x3C3,1); /*enable VGA*/ + for(i = 0;i < 0xFF;i++){ + outb(0x3D6,i); + printf("XR 0x%2.2X\t0x%2.2X\n",i,inb(0x3D7)&0xFF); + } + outb(0x3D6,0xE2); + bpp = inb(0x3D7)&0xF0; + } else { + outb(0x3D6, 0x70); + outw(0x3D6, (inw(0x3D6) | 0x8070)); + outw(0x46E8,0x0016); /*setup mode*/ + outw(0x102,1); /*global enable, VGA awake*/ + outw(0x46E8,0x000E); /*exit from setup mode*/ + printf("0x%2.2X\n",inb(0x3C3)&0xFF); + outb(0x3C3,0); /*disable VGA*/ + outw(0x46E8,0x0000); /*exit from setup mode*/ + outw(0x46E8,0x000E); /*exit from setup mode*/ + outb(0x3C3,1); /*enable VGA*/ + outw(0x46E8,0x0000); /*exit from setup mode*/ + for(i = 0;i < 0x80;i++){ + outb(0x3D6,i); + printf("XR 0x%2.2X\t0x%2.2X\n",i,inb(0x3D7)&0xFF); + } + outb(0x3D6,0x2B); + bpp = inb(0x3D7)&0xF0; + } + + switch(bpp){ + case 0x20: + bpp = 4; + break; + case 0x30: + bpp = 8; + break; + case 0x40: + bpp = 16; + shift = 2; + break; + case 0x50: + bpp = 24; + break; + default: + bpp = 0; + } + outb(0x3D6,storeReg); + + printf("\nport 0x3D4 (CRTC)\n"); + storeReg = inb(0x3D4); + if (isHiQV==1) { + for(i = 0;i < 0x7F;i++){ + outb(0x3D4,i); + printf("CR 0x%2.2X\t0x%2.2X\n",i,inb(0x3D5)&0xFF); + } + outb(0x3D4,storeReg); + printf("\nport 0x3D0 (Flat Panel)\n"); + storeReg = inb(0x3D0); + for(i = 0;i < 0x7F;i++){ + outb(0x3D0,i); + printf("FR 0x%2.2X\t0x%2.2X\n",i,inb(0x3D1)&0xFF); + } + outb(0x3D1,storeReg); + printf("\nport 0x3D2 (Multimedia)\n"); + storeReg = inb(0x3D2); + for(i = 0;i < 0x7F;i++){ + outb(0x3D2,i); + printf("MR 0x%2.2X\t0x%2.2X\n",i,inb(0x3D3)&0xFF); + } + outb(0x3D3,storeReg); + } else { + for(i = 0;i < 0x40;i++){ + outb(0x3D4,i); + printf("CR 0x%2.2X\t0x%2.2X\n",i,inb(0x3D5)&0xFF); + } + outb(0x3D4,storeReg); + } + + + printf("port 0x3CE (GC)\n"); + storeReg = inb(0x3CE); + for(i = 0;i < 0x10;i++){ + outb(0x3CE,i); + printf("GC 0x%2.2X\t0x%2.2X\n",i,inb(0x3CF)&0xFF); + } + outb(0x3CE,storeReg); + printf("port 0x3C4 (Sequencer)\n"); + storeReg = inb(0x3C4); + for(i = 0;i < 0x10;i++){ + outb(0x3C4,i); + printf("SQ 0x%2.2X\t0x%X2.2\n",i,inb(0x3C5)&0xFF); + } + outb(0x3C4,storeReg); + + + printf("port 0x3C0 (Attribute)\n"); + inb(0x3DA); + storeReg = inb(0x3C0); + for(i = 0;i < 0xFF;i++){ + inb(0x3DA); + outb(0x3C0,i); + printf("AT 0x%2.2X\t0x%2.2X\n",i,inb(0x3C1)&0xFF); + } + inb(0x3DA); + outb(0x3C0,storeReg); + + printf("0x3CC\t0x%X\n",inb(0x3CC)&0xFF); + printf("0x3C2\t0x%X\n",inb(0x3C2)&0xFF); + printf("0x3C3\t0x%X\n",inb(0x3C2)&0xFF); + printf("0x3CA\t0x%X\n",inb(0x3CA)&0xFF); + printf("0x3DA\t0x%X\n",inb(0x3DA)&0xFF); + + printf("\nRAMDAC\nport\tvalue\n"); + for(port = 0x83C6; port < 0x83CA;port++){ + printf("0x%4X\t0x%4X\n",port,inw(port)); + } + + if (isHiQV!=1) { + printf("\nBitBLT\nport\tvalue\n"); + for(port = 0x83D0; port <= 0x9FD0;port+=0x400){ + printf("0x%4.4X\t0x%4X\n",port,inw(port)); + } + + printf("\nH/W cursor\nport\tvalue\n"); + for(port = 0xA3D0; port <= 0xB3D0;port+=0x400){ + printf("0x%4.4X\t0x%4X\n",port,inw(port)); + } + + + outb(0x3D6, 0x70); + outw(0x3D6, (inw(0x3D6) | 0x8070)); + + printf("0x46E8\t0x%8X\n",inl(0x46E8)); + printf("0x4AE8\t0x%8X\n",inl(0x4AE8)); + printf("0x102\t0x%8X\n",inl(0x102)); + printf("0x103\t0x%8X\n",inl(0x103)); + + } + + storeReg = inb(0x3D4); + { + outb(0x3D4,0); + HTotal = ((inb(0x3D5)&0xFF) + 5) << shift; + outb(0x3D4,1); + HDisplay = ((inb(0x3D5)&0xFF) + 1) << shift; + outb(0x3D4,4); + HSyncStart = ((inb(0x3D5)&0xFF) + 1) << shift; + outb(0x3D4,5); + HSyncEnd = inb(0x3D5)&0x1F; + outb(0x3D4,5); + HSyncEnd += HSyncStart >> shift; + HSyncEnd <<= shift; + + outb(0x3D4,6); + VTotal = inb(0x3D5)&0xFF; + outb(0x3D4,7); + VTotal |= (inb(0x3D5)&0x1) << 8; + VTotal |= (inb(0x3D5)&0x20) << 4; + VTotal += 2; + VDisplay = (inb(0x3D5)&0x2) << 7; + VDisplay |= (inb(0x3D5)&0x40) << 3; + VSyncStart = (inb(0x3D5)&0x4) << 6; + VSyncStart |= (inb(0x3D5)&0x80) << 2; + outb(0x3D4,0x12); + VDisplay |= inb(0x3D5)&0xFF; + VDisplay += 1; + outb(0x3D4,0x10); + VSyncStart |= inb(0x3D5)&0xFF; + + outb(0x3D4,0x11); + VSyncEnd = inb(0x3D5)&0xF; + VSyncEnd += VSyncStart; + + } + outb(0x3D4,storeReg); + + printf("\nModeLine with port 0x3D4 (CRTC) %d %d %d %d %d %d %d %d\n", + HDisplay, HSyncStart, HSyncEnd, HTotal, + VDisplay, VSyncStart, VSyncEnd, VTotal); + + + if (is69030==1) { + if (again==1) { + again=0; + printf("\n\nPipeline B:\n"); + outb(0x3CD,((IOSS&0xE0)| 0x1F)); /* Select Channel 1 */ + outb(0x3CB,((MSS&0xF0)| 0xF)); + goto again; + } else { + outb(0x3CD,IOSS); + outb(0x3CB,MSS); + printf("\n\n0x3CB\t0x%X (MSS)\n",inb(0x3CB)&0xFF); + printf("0x3CD\t0x%X (IOSS)\n",inb(0x3CD)&0xFF); + } + } + RESET_IOPL(); + return 0; +} diff --git a/util/mRegs.c b/util/mRegs.c new file mode 100644 index 0000000..4d8da11 --- /dev/null +++ b/util/mRegs.c @@ -0,0 +1,186 @@ +/* $XConsortium: mRegs.c /main/2 1996/10/27 11:49:43 kaleb $ */ + + + + + +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/chips/util/mRegs.c,v 1.6 2001/11/16 21:13:34 tsi Exp $ */ + +#ifdef __NetBSD__ +# include <sys/types.h> +# include <machine/pio.h> +# include <machine/sysarch.h> +#else +# if defined(SVR4) && defined(i386) +# include <sys/types.h> +# ifdef NCR + /* broken NCR <sys/sysi86.h> */ +# define __STDC +# include <sys/sysi86.h> +# undef __STDC +# else +# include <sys/sysi86.h> +# endif +# ifdef SVR4 +# if !defined(sun) +# include <sys/seg.h> +# endif +# endif +# include <sys/v86.h> +# if defined(sun) +# include <sys/psw.h> +# endif +# endif +# include "AsmMacros.h" +#endif /* NetBSD */ + +#include <unistd.h> +#include <stdio.h> +#include <stdlib.h> + +#ifdef __NetBSD__ +# define SET_IOPL() i386_iopl(3) +# define RESET_IOPL() i386_iopl(0) +#else +# if defined(SVR4) && defined(i386) +# ifndef SI86IOPL +# define SET_IOPL() sysi86(SI86V86,V86SC_IOPL,PS_IOPL) +# define RESET_IOPL() sysi86(SI86V86,V86SC_IOPL,0) +# else +# define SET_IOPL() sysi86(SI86IOPL,3) +# define RESET_IOPL() sysi86(SI86IOPL,0) +# endif +# else +# ifdef linux +# define SET_IOPL() iopl(3) +# define RESET_IOPL() iopl(0) +# else +# define SET_IOPL() (void)0 +# define RESET_IOPL() (void)0 +# endif +# endif +#endif + +int hex2int(char* str); + +int main(int argc, char** argv) +{ + int i, value, index = 0; + char c, cport; + char* str; + unsigned int port, port1 = 0; + int query = 0; + + if(argc < 2) { + printf("usage: %s [Cvvxx [Cvvxx]] [Dxx]\n",argv[0]); + printf(" where C = A|a write vv to ARxx\n"); + printf(" = C|c write vv to CRxx\n"); + printf(" = F|f write vv to FRxx (6555x only)\n"); + printf(" = G|g write vv to GRxx\n"); + printf(" = M|m write vv to MRxx (6555x only)\n"); + printf(" = S|s write vv to SRxx\n"); + printf(" = X|x write vv to XRxx\n"); + printf(" where D = Y|y write xx to FCR\n"); + printf(" = Z|z write vv to MSR\n"); + printf(" xx is in hexadecimal\n"); + printf(" vv is in hexadecimal or '?' for query\n"); + } + + SET_IOPL(); + + for(i = 1; i < argc; i++){ + value = 0; + str = argv[i]; + c = *str++; + switch (c) { + case 'f': + case 'F': + cport = 'F'; + port = 0x3D0; + break; + case 'c': + case 'C': + cport = 'C'; + port = 0x3D4; + break; + case 'x': + case 'X': + cport = 'X'; + port = 0x3D6; + break; + case 'g': + case 'G': + cport = 'G'; + port = 0x3CE; + break; + case 'a': + case 'A': + cport = 'A'; + port = 0x3C0; + break; + case 's': + case 'S': + cport = 'S'; + port = 0x3C4; + break; + case 'm': + case 'M': + cport = 'M'; + port = 0x3D2; + break; + case 'y': + case 'Y': + cport = 'Y'; + port = 0x3DA; + port1 = 0x3CA; + break; + case 'z': + case 'Z': + cport = 'Z'; + port = 0x3C2; + port1 = 0x3CC; + break; + default: + continue; + break; + } + if ((cport != 'Z') && (cport != 'Y')) index = inb(port); + while ((c = *str++)) { + if (c == '?') { + query = 1; + } + if(c >= '0' && c <= '9') + value = (value << 4) | (c - '0'); /*ASCII assumed*/ + else if(c >= 'A' && c < 'G') + value = (value << 4) | (c - 'A'+10); /*ASCII assumed*/ + else if(c >= 'a' && c < 'g') + value = (value << 4) | (c - 'a'+10); /*ASCII assumed*/ + } + if ((cport != 'Z') && (cport != 'Y')) outb(port,value&0xFF); + if (query) { + if ((cport != 'Z') && (cport != 'Y')) + printf("%cR%X: 0x%X\n", cport, value & 0xFF, + inb(port+1)&0xFF); + else + if (cport == 'Z') + printf("MSR: 0x%X\n", inb(port1)&0xFF); + else + printf("FCR: 0x%X\n", inb(port1)&0xFF); + } else { + if ((cport != 'Z') && (cport != 'Y')) { + printf("%cR%X: 0x%X -> 0x%X\n", cport, value & 0xFF, + inb(port+1)&0xFF, (value&0xFF00)>>8); + outw(port, value); + outb(port, index &0xFF); + } else { + if (cport == 'Z') + printf("MSR: 0x%X -> 0x%X\n", inb(port1)&0xFF, value&0xFF); + else + printf("FCR: 0x%X -> 0x%X\n", inb(port1)&0xFF, value&0xFF); + outb(port, value & 0xFF); + } + } + } + RESET_IOPL(); + return 0; +} diff --git a/util/modClock.c b/util/modClock.c new file mode 100644 index 0000000..cce4f84 --- /dev/null +++ b/util/modClock.c @@ -0,0 +1,412 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/chips/util/modClock.c,v 1.6 2001/11/16 21:13:34 tsi Exp $ */ + +#ifdef __NetBSD__ +# include <sys/types.h> +# include <machine/pio.h> +# include <machine/sysarch.h> +#else +# if defined(SVR4) && defined(i386) +# include <sys/types.h> +# ifdef NCR + /* broken NCR <sys/sysi86.h> */ +# define __STDC +# include <sys/sysi86.h> +# undef __STDC +# else +# include <sys/sysi86.h> +# endif +# ifdef SVR4 +# if !defined(sun) +# include <sys/seg.h> +# endif +# endif +# include <sys/v86.h> +# if defined(sun) +# include <sys/psw.h> +# endif +# endif +# include "AsmMacros.h" +#endif /* NetBSD */ + +#include <unistd.h> +#include <stdio.h> +#include <stdlib.h> +#ifndef Lynx +#include <fnmatch.h> +#endif + +#ifdef __NetBSD__ +# define SET_IOPL() i386_iopl(3) +# define RESET_IOPL() i386_iopl(0) +#else +# if defined(SVR4) && defined(i386) +# ifndef SI86IOPL +# define SET_IOPL() sysi86(SI86V86,V86SC_IOPL,PS_IOPL) +# define RESET_IOPL() sysi86(SI86V86,V86SC_IOPL,0) +# else +# define SET_IOPL() sysi86(SI86IOPL,3) +# define RESET_IOPL() sysi86(SI86IOPL,0) +# endif +# else +# ifdef linux +# define SET_IOPL() iopl(3) +# define RESET_IOPL() iopl(0) +# else +# define SET_IOPL() (void)0 +# define RESET_IOPL() (void)0 +# endif +# endif +#endif + +#define tolerance 0.01 /* +/- 1% */ + + +#define CT65520 0x1 +#define CT65525 0x2 +#define CT65530 0x3 +#define CT64200 0x4 + +#define CT65535 0x11 +#define CT65540 0x12 +#define CT65545 0x13 +#define CT65546 0x14 +#define CT65548 0x15 +#define CT64300 0x16 + +#define CT65550 0x31 +#define CT65554 0x32 +#define CT65555 0x33 +#define CT68554 0x34 +#define CT69000 0x35 +#define CT69030 0x36 + +#define IS_Programmable(X) X&0x10 +#define IS_HiQV(X) X&0x20 + +#define DotClk 0 +#define MemClk 1 +#define IS_MemClk(X) X&0x1 + +int compute_clock ( + unsigned int ChipType, + double target, + double Fref, + unsigned int ClkMaxN, + unsigned int ClkMaxM, + unsigned int *bestM, + unsigned int *bestN, + unsigned int *bestP, + unsigned int *bestPSN) { + + unsigned int M, N, P, PSN, PSNx; + + double bestError = 0, abest = 42, bestFout = 0; + + double Fvco, Fout; + double error, aerror; + + unsigned int M_min = 3; + unsigned int M_max = ClkMaxM; + + if (target < 1e6){ + fprintf (stderr, "MHz assumed, changed to %g MHz\n", target); + target *= 1e6; + } + + if (target > 220.0e6) { + fprintf (stderr, "too large\n"); + return 1; + } + + /* Other parameters available onthe 65548 but not the 65545, and + not documented in the Clock Synthesizer doc in rev 1.0 of the + 65548 datasheet: + + + XR30[4] = 0, VCO divider loop uses divide by 4 (same as 65545) + 1, VCO divider loop uses divide by 16 + + + XR30[5] = 1, reference clock is divided by 5 + + I haven't put in any support for those here. For simplicity, + they should be set to 0 on the 65548, and left untouched on + earlier chips. */ + + for (PSNx = ((ChipType == CT69000) || (ChipType == CT69030)) ? 1 : 0; + PSNx <= 1; PSNx++) { + unsigned int low_N, high_N; + double Fref4PSN; + + PSN = PSNx ? 1 : 4; + + low_N = 3; + high_N = ClkMaxN; + + while (Fref / (PSN * low_N) > (((ChipType == CT69000) || + (ChipType == CT69030)) ? 5.0e6 : 2.0e6)) + low_N++; + while (Fref / (PSN * high_N) < 150.0e3) + high_N--; + + Fref4PSN = Fref * 4 / PSN; + for (N = low_N; N <= high_N; N++) { + double tmp = Fref4PSN / N; + + for (P = (IS_HiQV(ChipType) && (ChipType != CT69000) && + (ChipType != CT69030)) ? 1 : 0; P <= 5; P++) { + double Fvco_desired = target * (1 << P); + double M_desired = Fvco_desired / tmp; + /* Which way will M_desired be rounded? Do all three just to + be safe. */ + unsigned int M_low = M_desired - 1; + unsigned int M_hi = M_desired + 1; + + if (M_hi < M_min || M_low > M_max) + continue; + + if (M_low < M_min) + M_low = M_min; + if (M_hi > M_max) + M_hi = M_max; + + for (M = M_low; M <= M_hi; M++) { + Fvco = tmp * M; + if (Fvco <= ((ChipType == CT69000) || (ChipType == CT69030) ? + 100e6 : 48.0e6)) + continue; + if (Fvco > 220.0e6) + break; + + Fout = Fvco / (1 << P); + + error = (target - Fout) / target; + + aerror = (error < 0) ? -error : error; + if (aerror < abest) { + abest = aerror; + bestError = error; + *bestM = M; + *bestN = N; + *bestP = P; + *bestPSN = PSN; + bestFout = Fout; + } + } + } + } + } + + if (abest < tolerance) { + printf ("best: M=%d N=%d P=%d PSN=%d\n", *bestM, *bestN, *bestP, *bestPSN); + + if (bestFout > 1.0e6) + printf ("Fout = %g MHz", bestFout / 1.0e6); + else if (bestFout > 1.0e3) + printf ("Fout = %g kHz", bestFout / 1.0e3); + else + printf ("Fout = %g Hz", bestFout); + printf (", error = %g\n", bestError); + return 0; + } + printf ("can't do it with less than %g error\n", bestError); + return 1; +} + +int set_clock( + unsigned int ChipType, + unsigned int ClockType, + unsigned int ProgClock, + unsigned int M, + unsigned int N, + unsigned int P, + unsigned int PSN) { + + unsigned int tmp, idx; + + SET_IOPL(); + + idx = inb(0x3D6); + if (IS_HiQV(ChipType)) { + if (IS_MemClk(ClockType)) { + printf ("XRCC = 0x%02X\n", M - 2); + printf ("XRCD = 0x%02X\n", N - 2); + printf ("XRCE = 0x%02X\n", (0x80 | (P * 16 + (PSN == 1)))); + + outb(0x3D6, 0xCE); /* Select Fix MClk before */ + tmp = inb(0x3D7); + outb(0x3D7, tmp & 0x7F); + outb(0x3D6, 0xCC); + outb(0x3D7, (M - 2)); + outb(0x3D6, 0xCD); + outb(0x3D7, (N - 2)); + outb(0x3D6, 0xCE); + outb(0x3D7, (0x80 | (P * 16 + (PSN == 1)))); + } else { + printf ("XR%X = 0x%02X\n", 0xC0 + 4 * ProgClock, M - 2); + printf ("XR%X = 0x%02X\n", 0xC1 + 4 * ProgClock, N - 2); + printf ("XR%X = 0x%02X\n", 0xC2 + 4 * ProgClock, 0); + printf ("XR%X = 0x%02X\n", 0xC3 + 4 * ProgClock, P * 16 + (PSN == 1)); + + outb(0x3D6, 0xC0 + 4 * ProgClock); + outb(0x3D7, (M - 2)); + outb(0x3D6, 0xC1 + 4 * ProgClock); + outb(0x3D7, (N - 2)); + outb(0x3D6, 0xC2 + 4 * ProgClock); + outb(0x3D7, 0x0); + outb(0x3D6, 0xC3 + 4 * ProgClock); + outb(0x3D7, (P * 16 + (PSN == 1))); + } + } else { + printf ("XR30 = 0x%02X\n", P * 2 + (PSN == 1)); + printf ("XR31 = 0x%02X\n", M - 2); + printf ("XR32 = 0x%02X\n", N - 2); + outb(0x3D6, 0x33); + tmp = inb(0x3D7); + if (IS_MemClk(ClockType)) { + outb(0x3D7, tmp | 0x20); + } else { + outb(0x3D7, tmp & ~0x20); + } + outb(0x3D6, 0x30); + outb(0x3D7, (P * 2 + (PSN == 1))); + outb(0x3D6, 0x31); + outb(0x3D7, (M - 2)); + outb(0x3D6, 0x32); + outb(0x3D7, (N - 2)); + outb(0x3D6, 0x33); + outb(0x3D7, tmp); + } + outb(0x3D6, idx); + RESET_IOPL(); + return 0; +} + +unsigned int probe_chip(void) { + + unsigned int ChipType, temp; + + SET_IOPL(); + + outb(0x3D6, 0x00); + temp = inb(0x3D7); + ChipType = 0; + if (temp != 0xA5) { + if ((temp & 0xF0) == 0x70) { + ChipType = CT65520; + } + if ((temp & 0xF0) == 0x80) { /* could also be a 65525 */ + ChipType = CT65530; + } + if ((temp & 0xF0) == 0xA0) { + ChipType = CT64200; + } + if ((temp & 0xF0) == 0xB0) { + ChipType = CT64300; + } + if ((temp & 0xF0) == 0xC0) { + ChipType = CT65535; + } + if ((temp & 0xF8) == 0xD0) { + ChipType = CT65540; + } + if ((temp & 0xF8) == 0xD8) { + switch (temp & 0x07) { + case 3: + ChipType = CT65546; + break; + case 4: + ChipType = CT65548; + break; + default: + ChipType = CT65545; + } + } + } + /* At this point the chip could still be a HiQV, so check for + * that. This test needs some looking at */ + if ((temp != 0) && (ChipType == 0)) { + outb(0x3D6, 0x02); + temp = inb(0x03D7); + if (temp == 0xE0) { + ChipType = CT65550; + } + if (temp == 0xE4) { + ChipType = CT65554; + } + if (temp == 0xE5) { + ChipType = CT65555; + } + if (temp == 0xF4) { + ChipType = CT68554; + } + if (temp == 0xC0) { + ChipType = CT69000; + } + if (temp == 0x30) { + outb(0x3D6, 0x03); + temp = inb(0x03D7); + if (temp == 0x0C) ChipType = CT69030; + } + } + + RESET_IOPL(); + + if (ChipType == 0) { /* failure */ + fprintf(stderr, "Not a Chips and Technologies Chipset\n"); + } + + return ChipType; +} + + +int main (int argc, char *argv[]) { + double target; + double Fref = 14318180; + unsigned int M, N, P, PSN, ChipType, ClockType, progclock; + + switch (argc) { + case 2: + progclock = 2; + target = atof (argv[1]); + break; + case 3: + progclock = abs(atof (argv[1])); + target = atof (argv[2]); + break; + default: + fprintf (stderr, "usage: %s [-0|-1|-2] freq\n", argv[0]); + return 1; + } + + ClockType = DotClk; +#ifndef Lynx + if (! fnmatch("*memClock",argv[0],FNM_PATHNAME)) { +#else + if (strstr("memClock",argv[0]) != NULL) { +#endif + ClockType = MemClk; + } + + ChipType = probe_chip(); + if (!ChipType) { + return 1; + } + + if (! IS_Programmable(ChipType)) { + fprintf(stderr, "No programmable Clock!\n"); + return 1; + } + + if (IS_HiQV(ChipType)) { + if (! compute_clock(ChipType, target, Fref, 63, 127, &M, &N, &P, &PSN)) { + return set_clock(ChipType, ClockType, progclock, M, N, P, PSN); + } else { + return 1; + } + } else { + if (! compute_clock(ChipType, target, Fref, 127, 127, &M, &N, &P, &PSN)) { + return set_clock(ChipType, ClockType, progclock, M, N, P, PSN); + } else { + return 1; + } + } +} |