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 | 8cf2eff7ea90409df3f75a53080b45dd54acba17 (patch) | |
tree | 3f1ddbc3bd39caed9c18ff7b89fa8c2acd5ab004 |
Initial revisionXORG-STABLE
-rw-r--r-- | README.sgml | 62 | ||||
-rw-r--r-- | man/cyrix.man | 75 | ||||
-rw-r--r-- | src/cyrix.h | 532 | ||||
-rw-r--r-- | src/cyrix_accel.c | 447 | ||||
-rw-r--r-- | src/cyrix_bank.c | 72 | ||||
-rw-r--r-- | src/cyrix_driver.c | 1516 | ||||
-rw-r--r-- | src/cyrix_helper.c | 382 | ||||
-rw-r--r-- | src/cyrix_shadow.c | 155 |
8 files changed, 3241 insertions, 0 deletions
diff --git a/README.sgml b/README.sgml new file mode 100644 index 0000000..a0861c9 --- /dev/null +++ b/README.sgml @@ -0,0 +1,62 @@ +<!DOCTYPE linuxdoc PUBLIC "-//XFree86//DTD linuxdoc//EN" [ +<!ENTITY % defs SYSTEM "defs.ent"> %defs; +]> + +<article> +<title>Information for Cyrix Chipset Users +<author>The XFree86 Project Inc. +<date>7 March 2000 +<ident> +$XFree86: xc/programs/Xserver/hw/xfree86/doc/sgml/cyrix.sgml,v 1.3 2000/03/08 05:38:43 dawes Exp $ +</ident> +<toc> + +<sect>Supported hardware <p> + +This driver +supports a single chipset `mediagx' that should work on the following Cyrix +CPUs with integrated graphics: + +<itemize> +<item>MediaGX +<item>MediaGXi +<item>MediaGXm +</itemize> + +<sect>Features <p> +<itemize> +<item>Rather sparse (color depth hardcoded to 8) +</itemize> + +<sect>XF86Config Option <p> +<descrip> +<tag>Option "sw_cursor"</tag> +disable the hardware cursor. (Code not verified yet!) +<tag>Option "no_accel"</tag> +completely disables acceleration. Usually not recommended. +</descrip> + +<sect>Bugs and Limitations<p> +<itemize> +<item>As a first cut at the new design, known problems are everywhere. +The console font is corrupted upon exit. The server seems stable if +the virtual desktop and resolution size match. I found 1024x768 usable +and that's why I released this version. Geeks can have fun with this +but NEWBIES should use the 3.3.3.1 release instead! +<item>On some older chipsets, the driver may trigger an illegal instruction +just after probing for the ``scratchpad size''. If this is the case, +email to <email>hecker@cat.dfrc.nasa.gov</email> with the output of +<verb> +XFree86 -probeonly -verbose +</verb> +and this will be fixed. +</itemize> + +<sect>Authors<p> +<itemize> +<item>Richard Hecker <email>hecker@cat.dfrc.nasa.gov</email> +</itemize> + + +</article> + diff --git a/man/cyrix.man b/man/cyrix.man new file mode 100644 index 0000000..f8fb670 --- /dev/null +++ b/man/cyrix.man @@ -0,0 +1,75 @@ +.\" $XFree86: xc/programs/Xserver/hw/xfree86/drivers/cyrix/cyrix.man,v 1.3 2002/11/06 11:38:59 alanh Exp $ +.\" shorthand for double quote that works everywhere. +.ds q \N'34' +.TH CYRIX __drivermansuffix__ __vendorversion__ +.SH NAME +cyrix \- Cyrix video driver +.SH SYNOPSIS +.nf +.B "Section \*qDevice\*q" +.BI " Identifier \*q" devname \*q +.B " Driver \*qcyrix\*q" +\ \ ... +.B EndSection +.fi +.SH DESCRIPTION +.B cyrix +is an XFree86 driver for the Cyrix MediaGX (now Natsemi Geode) series of +processors when using the built in video. +.SH SUPPORTED HARDWARE +The +.B cyrix +driver supports the MediaGX, MediaGXi and MediaGXm processors, as well as +the Natsemi 'Geode' branded processors. It supports the CS5510, CS5520, +CS5530 and CS5530A companion chips. The driver supports 4, 8, 15 and 16 bit +deep displays with video compression and acceleration. +.PP +The MediaGX run length compresses its shared framebuffer, for the best +performance on a MediaGX machine pick backgrounds that compress well +horizonally. +.SH CONFIGURATION DETAILS +Please refer to XF86Config(__filemansuffix__) for general configuration +details. This section only covers configuration details specific to this +driver. +.PP +The following driver +.B options +are supported +.TP +.BI "Option \*qNoAccel\*q \*q" boolean \*q +Disable or enable acceleration. Default: acceleration is enabled. +.TP +.BI "Option \*qSWCursor\*q \*q" boolean \*q +Disable or enable software cursor. Default software cursor is enabled and a +hardware cursor is used. +.TP +.BI "Option \*qHWCursor\*q \*q" boolean \*q +Disable or enable hardware cursor. Default hardware cursor is disabled. +.TP +.BI "Option \*qShadowFB\*q \*q" boolean \*q +Disable or enable shadow frame buffer. The shadow buffer is normally only +used when rotating the screen. The default is false. +.TP +.BI "Option \*qRotate\*q \*qCW\*q" +.TP +.BI "Option \*qRotate\*q \*qCCW\*q" +.PP +Rotate the display clockwise or counterclockwise for use on Cyrix based +tablet PC systems. This mode is currently unaccelerated. +.SH "BUGS" +This driver has not been tested on the original 5510 hardware for some +considerable time. +.PP +8bit mode does not currently work on the CS5510 with external RAMDAC. +.PP +The 5530A video overlay facility is not currently supported. +.PP +XFree86 uses the MediaGX 'SoftVGA' interface. On a small number of boards +this is buggy and may result in strange illegal instruction traps. +.PP +Hardware cursors are not currently supported. +.SH "SEE ALSO" +XFree86(1), XF86Config(__filemansuffix__), xf86config(1), Xserver(1), X(__miscmansuffix__) +.SH AUTHORS +Authors include: Richard Hecker, Annius Groenink, Dirk Hohndel, The GGI +Project, Alan Cox. diff --git a/src/cyrix.h b/src/cyrix.h new file mode 100644 index 0000000..c75c222 --- /dev/null +++ b/src/cyrix.h @@ -0,0 +1,532 @@ +/* + * Copyright 2000 by Richard A. Hecker, California, United States + * Copyright 2002 by Red Hat Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Alan Hourihane not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Alan Hourihane makes no representations + * about the suitability of this software for any purpose. It is provided + * "as is" without express or implied warranty. + * + * RICHARD HECKER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL RICHARD HECKER BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + * RED HAT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL RICHARD HECKER BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + * Author: Richard Hecker, hecker@cat.dfrc.nasa.gov + * Re-written for XFree86 v4.0 + * Chunks re-written again for XFree86 v4.2 + * Alan Cox <alan@redhat.com> + * Previous driver (pre-XFree86 v4.0) by + * Annius V. Groenink (A.V.Groenink@zfc.nl, avg@cwi.nl), + * Dirk H. Hohndel (hohndel@suse.de), + * Portions: the GGI project & confidential CYRIX databooks. + */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/cyrix/cyrix.h,v 1.4 2002/11/06 11:38:59 alanh Exp $ */ + +#ifndef _CYRIX_H_ +#define _CYRIX_H_ + +#include "xaa.h" +#include "xf86Cursor.h" +#include "vgaHW.h" + +/* this code is partly based on the MediaGX sources from the GGI project + based on CYRIX example code (gxvideo.c) and included with CYRIX and + GGI's permission under the XFree86 license. +*/ + +/* XFree86 macros */ +#define CYRIXPTR(p) ((CYRIXPrvPtr)((p)->driverPrivate)) + + +/* Driver specific structures */ +typedef struct { + unsigned char cyrixRegs3x4[0x100]; + unsigned char cyrixRegs3CE[0x100]; + unsigned char cyrixRegs3C4[0x100]; + unsigned char cyrixRegsDAC[0x01]; + unsigned char cyrixRegsClock[0x03]; + unsigned char DacRegs[0x300]; + unsigned int Colormap[0x100]; /* Actually 18bit values */ +} CYRIXRegRec, *CYRIXRegPtr; + +typedef struct { + /* extended SoftVGA registers */ + unsigned char VerticalTimingExtension; + unsigned char ExtendedAddressControl; + unsigned char ExtendedOffset; + unsigned char Offset; + unsigned char ExtendedColorControl; + unsigned char DisplayCompression; + unsigned char DriverControl; + unsigned char DACControl; + unsigned char ClockControl; + unsigned char CrtClockFrequency; + unsigned char CrtClockFrequencyFraction; + unsigned char RefreshRate; + + /* display controller hardware registers */ + CARD32 DcGeneralCfg; + CARD32 DcCursStOffset; + CARD32 DcCbStOffset; + CARD32 DcLineDelta; + CARD32 DcBufSize; + CARD32 DcCursorX; + CARD32 DcCursorY; + CARD32 DcCursorColor; + + /* graphics pipeline registers */ + CARD32 GpBlitStatus; + + /* save area for cursor image */ + char cursorPattern[256]; +} prevExt; + +typedef struct { + /* struct for the server */ + CARD32 IOAccelAddress; + CARD32 FbAddress; + char* GXregisters; + int CYRIXcursorAddress; /* relative to fb base */ + int CYRIXbltBuf0Address;/*relative to GXregisters*/ + int CYRIXbltBuf1Address; + int CYRIXbltBufSize; + EntityInfoPtr pEnt; + unsigned char * FbBase; + pciVideoPtr PciInfo; + XAAInfoRecPtr AccelInfoRec; + xf86CursorInfoPtr CursorInfoRec; + CloseScreenProcPtr CloseScreen; + int HwBpp; + int MinClock; + int MaxClock; + int Chipset; + int ChipRev; + int RamDac; + long FbMapSize; + short EngineOperation; + CYRIXRegRec SavedReg; + CYRIXRegRec ModeReg; + vgaHWRec std; + prevExt PrevExt; + Bool HWCursor; +/* Bool IsCyber; + Bool NewClockCode;*/ + Bool NoAccel; + Bool NoCompress; + Bool ShadowFB; + unsigned char * ShadowPtr; + int ShadowPitch; + int Rotate; + void (*PointerMoved)(int index, int x, int y); + OptionInfoPtr Options; + /* accel stuff */ + int bltBufWidth; + int blitMode; + int vectorMode; + int transMode; + int copyXdir; + int setBlitModeOnSync; + +} CYRIXPrivate, *CYRIXPrvPtr; + +typedef struct { + vgaHWRec std; /* IBM VGA */ + prevExt ext; +} CYRIXRec, *CYRIXPtr; + +/* Helper routines */ +extern void Cyrix1bppColorMap(ScrnInfoPtr pScrn); +extern int CyrixHWCursor(ScreenPtr pScr); +extern int CyrixInit(ScrnInfoPtr pScrn, DisplayModePtr mode); +extern void CyrixRestore(ScrnInfoPtr pScrn, CYRIXRegPtr cyrixReg); +extern void * CyrixSave(ScrnInfoPtr pScrn, CYRIXRegPtr cyrixReg); + +/* Shadow routines */ +extern void CYRIXRefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox); +extern void CYRIXPointerMoved(int index, int x, int y); +extern void CYRIXRefreshArea8(ScrnInfoPtr pScrn, int num, BoxPtr pbox); +extern void CYRIXRefreshArea16(ScrnInfoPtr pScrn, int num, BoxPtr pbox); + +extern void CYRIXsetBlitBuffers(void); +extern void CYRIXsetBlitBuffersOnOldChip(void); + +/* 32 bit access to GX registers */ +#define GX_REG(a) (*(volatile CARD32*)(pCyrix->GXregisters + (a))) + + +/* externs in cyrix_accel.c */ +extern void CYRIXAccelInit(ScreenPtr); + +/* A minor Sync() function that only waits for the graphics pipeline + registers to be flushed so we can define a new operation */ +#define CYRIXsetupSync() \ + while (GX_REG(GP_BLIT_STATUS) & BS_BLIT_PENDING) + + +/* access macros to the graphics pipeline registers */ +#define CYRIXsetSrcXY(x, y) \ + GX_REG(GP_SRC_XCOOR) = (((y) << 16) | (x)) + +#define CYRIXsetDstXY(x, y) \ + GX_REG(GP_DST_XCOOR) = (((y) << 16) | (x)) + +#define CYRIXsetWH(w, h) \ + GX_REG(GP_WIDTH) = (((h) << 16) | (w)) + +#define CYRIXsetSourceColors01(p, col0, col1) \ + CYRIXsetColors01((p), GP_SRC_COLOR_0, (col0), (col1)) + +#define CYRIXsetPatColors01(p, col0, col1) \ + CYRIXsetColors01((p), GP_PAT_COLOR_0, (col0), (col1)) + +#define CYRIXsetPatColors23(p, col2, col3) \ + CYRIXsetColors01((p), GP_PAT_COLOR_2, (col2), (col3)) + +#define CYRIXsetPatData(data0, data1) \ + GX_REG(GP_PAT_DATA_0) = (data0); \ + GX_REG(GP_PAT_DATA_1) = (data1) + +#define CYRIXsetPatMode(xrop, pm) \ + GX_REG(GP_RASTER_MODE) = ((pm) | windowsROPpatMask[(xrop)]) + +#define CYRIXsetPatModeX(xrop, pm) \ + GX_REG(GP_RASTER_MODE) = ((pm) | windowsROPsrcMask[(xrop)]) + +#define CYRIXsetPatModeTrans(pm) \ + GX_REG(GP_RASTER_MODE) = ((pm) | RM_CLIP_ENABLE | 0xC6); + +#define CYRIXsetBlitMode() \ + GX_REG(GP_BLIT_MODE) = (pCyrix->blitMode) + +#define CYRIXsetVectorMode() \ + GX_REG(GP_VECTOR_MODE) = (pCyrix->vectorMode) + +#define IfDest(rop, planemask, val) \ + (( (((rop) & 0x5) ^ (((rop) & 0xA) >> 1)) \ + || (~((planemask) & 0xFF)) \ + ) ? (val) : 0) + +/* Generic MediaGX hardware register and value definitions */ + +#define GX_IOPORT_INDEX 0x22 +#define GX_IOPORT_DATA 0x23 + +/* I/O REGISTERS INDEX DEFINITIONS */ + +#define GX_IOIDX_PCR 0x20 +#define GX_IOIDX_CCR1 0xC1 +#define GX_IOIDX_CCR2 0xC2 +#define GX_IOIDX_CCR3 0xC3 +#define GX_IOIDX_CCR4 0xE8 +#define GX_IOIDX_DIR0 0xFE +#define GX_IOIDX_DIR1 0xFF +#define GX_IOIDX_SMAR0 0xCD +#define GX_IOIDX_SMAR1 0xCE +#define GX_IOIDX_SMAR2 0xCF +#define GX_IOIDX_SMHR0 0xB0 +#define GX_IOIDX_SMHR1 0xB1 +#define GX_IOIDX_SMHR2 0xB2 +#define GX_IOIDX_SMHR3 0xB3 +#define GX_IOIDX_GCR 0xB8 +#define GX_IOIDX_VGACTL 0xB9 +#define GX_IOIDX_VGAM0 0xBA +#define GX_IOIDX_VGAM1 0xBB +#define GX_IOIDX_VGAM2 0xBC +#define GX_IOIDX_VGAM3 0xBD + +/* BUS CONTROLLER REGISTER DEFINITIONS */ + +#define BC_DRAM_TOP 0x8000 +#define BC_XMAP_1 0x8004 +#define BC_XMAP_2 0x8008 +#define BC_XMAP_3 0x800C + +/* GRAPHICS PIPELINE REGISTER DEFINITIONS */ + +#define GP_DST_XCOOR 0x8100 /* x destination origin */ +#define GP_DST_YCOOR 0x8102 /* y destination origin */ +#define GP_WIDTH 0x8104 /* pixel width */ +#define GP_HEIGHT 0x8106 /* pixel height */ +#define GP_SRC_XCOOR 0x8108 /* x source origin */ +#define GP_SRC_YCOOR 0x810A /* y source origin */ + +#define GP_VECTOR_LENGTH 0x8104 /* vector length */ +#define GP_INIT_ERROR 0x8106 /* vector initial error */ +#define GP_AXIAL_ERROR 0x8108 /* axial error increment */ +#define GP_DIAG_ERROR 0x810A /* diagonal error increment */ + +#define GP_SRC_COLOR_0 0x810C /* source color 0 */ +#define GP_SRC_COLOR_1 0x810E /* source color 1 */ +#define GP_PAT_COLOR_0 0x8110 /* pattern color 0 */ +#define GP_PAT_COLOR_1 0x8112 /* pattern color 1 */ +#define GP_PAT_COLOR_2 0x8114 /* pattern color 2 */ +#define GP_PAT_COLOR_3 0x8116 /* pattern color 3 */ +#define GP_PAT_DATA_0 0x8120 /* bits 31:0 of pattern */ +#define GP_PAT_DATA_1 0x8124 /* bits 63:32 of pattern */ +#define GP_PAT_DATA_2 0x8128 /* bits 95:64 of pattern */ +#define GP_PAT_DATA_3 0x812C /* bits 127:96 of pattern */ + +#define GP_RASTER_MODE 0x8200 /* raster operation */ +#define GP_VECTOR_MODE 0x8204 /* vector mode register */ +#define GP_BLIT_MODE 0x8208 /* blit mode register */ +#define GP_BLIT_STATUS 0x820C /* blit status register */ + +/* "GP_VECTOR_MODE" BIT DEFINITIONS */ + +#define VM_X_MAJOR 0x0000 /* X major vector */ +#define VM_Y_MAJOR 0x0001 /* Y major vector */ +#define VM_MAJOR_INC 0x0002 /* positive major axis step */ +#define VM_MINOR_INC 0x0004 /* positive minor axis step */ +#define VM_READ_DST_FB 0x0008 /* read destination data */ + +/* "GP_RASTER_MODE" BIT DEFINITIONS */ + +#define RM_PAT_DISABLE 0x0000 /* pattern is disabled */ +#define RM_PAT_MONO 0x0100 /* 1BPP pattern expansion */ +#define RM_PAT_DITHER 0x0200 /* 2BPP pattern expansion */ +#define RM_PAT_COLOR 0x0300 /* 8BPP or 16BPP pattern */ +#define RM_PAT_MASK 0x0300 /* mask for pattern mode */ +#define RM_PAT_TRANSPARENT 0x0400 /* transparent 1BPP pattern */ +#define RM_SRC_TRANSPARENT 0x0800 /* transparent 1BPP source */ +#define RM_CLIP_ENABLE 0x1000 /* enables clipping */ + +/* "GP_BLIT_STATUS" BIT DEFINITIONS */ + +#define BS_BLIT_BUSY 0x0001 /* blit engine is busy */ +#define BS_PIPELINE_BUSY 0x0002 /* graphics pipeline is bus */ +#define BS_BLIT_PENDING 0x0004 /* blit pending */ +#define BC_FLUSH 0x0080 /* flush pipeline requests */ +#define BC_8BPP 0x0000 /* 8BPP mode */ +#define BC_16BPP 0x0100 /* 16BPP mode */ +#define BC_FB_WIDTH_1024 0x0000 /* framebuffer width = 1024 */ +#define BC_FB_WIDTH_2048 0x0200 /* framebuffer width = 2048 */ + +/* "GP_BLIT_MODE" BIT DEFINITIONS */ + +#define BM_READ_SRC_NONE 0x0000 /* source foreground color */ +#define BM_READ_SRC_FB 0x0001 /* read source from FB */ +#define BM_READ_SRC_BB0 0x0002 /* read source from BB0 */ +#define BM_READ_SRC_BB1 0x0003 /* read source from BB1 */ +#define BM_READ_SRC_MASK 0x0003 /* read source mask */ + +#define BM_READ_DST_NONE 0x0000 /* no destination data */ +#define BM_READ_DST_BB0 0x0008 /* destination from BB0 */ +#define BM_READ_DST_BB1 0x000C /* destination from BB1 */ +#define BM_READ_DST_FB0 0x0010 /* dest from FB (store BB0) */ +#define BM_READ_DST_FB1 0x0014 /* dest from FB (store BB1)*/ +#define BM_READ_DST_MASK 0x001C /* read destination mask */ + +#define BM_WRITE_FB 0x0000 /* write to framebuffer */ +#define BM_WRITE_MEM 0x0020 /* write to memory */ +#define BM_WRITE_MASK 0x0020 /* write mask */ + +#define BM_SOURCE_COLOR 0x0000 /* source is 8BPP or 16BPP */ +#define BM_SOURCE_EXPAND 0x0040 /* source is 1BPP */ +#define BM_SOURCE_TEXT 0x00C0 /* source is 1BPP text */ +#define BM_SOURCE_MASK 0x00C0 /* source mask */ + +#define BM_REVERSE_Y 0x0100 /* reverse Y direction */ + +/* DISPLAY CONTROLLER REGISTER DEFINITIONS */ + +#define DC_UNLOCK 0x8300 /* lock register */ +#define DC_GENERAL_CFG 0x8304 /* config registers... */ +#define DC_TIMING_CFG 0x8308 +#define DC_OUTPUT_CFG 0x830C + +#define DC_FB_ST_OFFSET 0x8310 /* framebuffer start offset */ +#define DC_CB_ST_OFFSET 0x8314 /* compression start offset */ +#define DC_CURS_ST_OFFSET 0x8318 /* cursor start offset*/ +#define DC_ICON_ST_OFFSET 0x831C /* icon start offset */ +#define DC_VID_ST_OFFSET 0x8320 /* video start offset */ +#define DC_LINE_DELTA 0x8324 /* fb and cb skip counts */ +#define DC_BUF_SIZE 0x8328 /* fb and cb line size */ + +#define DC_H_TIMING_1 0x8330 /* horizontal timing... */ +#define DC_H_TIMING_2 0x8334 +#define DC_H_TIMING_3 0x8338 +#define DC_FP_H_TIMING 0x833C + +#define DC_V_TIMING_1 0x8340 /* vertical timing... */ +#define DC_V_TIMING_2 0x8344 +#define DC_V_TIMING_3 0x8348 +#define DC_FP_V_TIMING 0x834C + +#define DC_CURSOR_X 0x8350 /* cursor x position */ +#define DC_ICON_X 0x8354 /* HACK - 1.3 definition */ +#define DC_V_LINE_CNT 0x8354 /* vertical line counter */ +#define DC_CURSOR_Y 0x8358 /* cursor y position */ +#define DC_ICON_Y 0x835C /* HACK - 1.3 definition */ +#define DC_SS_LINE_COMPARE 0x835C /* line compare value */ + +#define DC_CURSOR_COLOR 0x8360 /* cursor colors */ +#define DC_ICON_COLOR 0x8364 /* icon colors */ +#define DC_BORDER_COLOR 0x8368 /* border color */ + +#define DC_PAL_ADDRESS 0x8370 /* palette address */ +#define DC_PAL_DATA 0x8374 /* palette data */ + +/* PALETTE ADDRESS DEFINITIONS */ + +#define PAL_CURSOR_COLOR_0 0x100 +#define PAL_CURSOR_COLOR_1 0x101 +#define PAL_ICON_COLOR_0 0x102 +#define PAL_ICON_COLOR_1 0x103 +#define PAL_OVERSCAN_COLOR 0x104 + +/* DC BIT DEFINITIONS */ + +#define DC_UNLOCK_VALUE 0x00004758 /* used to unlock DC regs */ + +#define DC_GCFG_DFLE 0x00000001 /* display FIFO load enable */ +#define DC_GCFG_CURE 0x00000002 /* cursor enable */ +#define DC_GCFG_ICNE 0x00000004 /* HACK - 1.3 definition */ +#define DC_GCFG_PLNO 0x00000004 /* planar offset LSB */ +#define DC_GCFG_VIDE 0x00000008 /* HACK - 1.3 definition */ +#define DC_GCFG_PPC 0x00000008 /* pixel pan compatibility */ +#define DC_GCFG_CMPE 0x00000010 /* compression enable */ +#define DC_GCFG_DECE 0x00000020 /* decompression enable */ +#define DC_GCFG_DCLK_MASK 0x000000C0 /* dotclock multiplier */ +#define DC_GCFG_DCLK_POS 6 /* dotclock multiplier */ +#define DC_GCFG_DFHPSL_MASK 0x00000F00 /* FIFO high-priority start */ +#define DC_GCFG_DFHPSL_POS 8 /* FIFO high-priority start */ +#define DC_GCFG_DFHPEL_MASK 0x0000F000 /* FIFO high-priority end */ +#define DC_GCFG_DFHPEL_POS 12 /* FIFO high-priority end */ +#define DC_GCFG_CIM_MASK 0x00030000 /* compressor insert mode */ +#define DC_GCFG_CIM_POS 16 /* compressor insert mode */ +#define DC_GCFG_FDTY 0x00040000 /* frame dirty mode */ +#define DC_GCFG_RTPM 0x00080000 /* real-time perf. monitor */ +#define DC_GCFG_DAC_RS_MASK 0x00700000 /* DAC register selects */ +#define DC_GCFG_DAC_RS_POS 20 /* DAC register selects */ +#define DC_GCFG_CKWR 0x00800000 /* clock write */ +#define DC_GCFG_LDBL 0x01000000 /* line double */ +#define DC_GCFG_DIAG 0x02000000 /* FIFO diagnostic mode */ +#define DC_GCFG_CH4S 0x04000000 /* sparse refresh mode */ +#define DC_GCFG_SSLC 0x08000000 /* enable line compare */ +#define DC_GCFG_FBLC 0x10000000 /* enable fb offset compare */ +#define DC_GCFG_DFCK 0x20000000 /* divide flat-panel clock */ +#define DC_GCFG_DPCK 0x40000000 /* divide pixel clock */ +#define DC_GCFG_DDCK 0x80000000 /* divide dot clock */ + +#define DC_TCFG_FPPE 0x00000001 /* flat-panel power enable */ +#define DC_TCFG_HSYE 0x00000002 /* horizontal sync enable */ +#define DC_TCFG_VSYE 0x00000004 /* vertical sync enable */ +#define DC_TCFG_BLKE 0x00000008 /* blank enable */ +#define DC_TCFG_DDCK 0x00000010 /* DDC clock */ +#define DC_TCFG_TGEN 0x00000020 /* timing generator enable */ +#define DC_TCFG_VIEN 0x00000040 /* vertical interrupt enable */ +#define DC_TCFG_BLNK 0x00000080 /* blink enable */ +#define DC_TCFG_CHSP 0x00000100 /* horizontal sync polarity */ +#define DC_TCFG_CVSP 0x00000200 /* vertical sync polarity */ +#define DC_TCFG_FHSP 0x00000400 /* panel horz sync polarity */ +#define DC_TCFG_FVSP 0x00000800 /* panel vert sync polarity */ +#define DC_TCFG_FCEN 0x00001000 /* flat-panel centering */ +#define DC_TCFG_CDCE 0x00002000 /* HACK - 1.3 definition */ +#define DC_TCFG_PLNR 0x00002000 /* planar mode enable */ +#define DC_TCFG_INTL 0x00004000 /* interlace scan */ +#define DC_TCFG_PXDB 0x00008000 /* pixel double */ +#define DC_TCFG_BKRT 0x00010000 /* blink rate */ +#define DC_TCFG_PSD_MASK 0x000E0000 /* power sequence delay */ +#define DC_TCFG_PSD_POS 17 /* power sequence delay */ +#define DC_TCFG_DDCI 0x08000000 /* DDC input (RO) */ +#define DC_TCFG_SENS 0x10000000 /* monitor sense (RO) */ +#define DC_TCFG_DNA 0x20000000 /* display not active (RO) */ +#define DC_TCFG_VNA 0x40000000 /* vertical not active (RO) */ +#define DC_TCFG_VINT 0x80000000 /* vertical interrupt (RO) */ + +#define DC_OCFG_8BPP 0x00000001 /* 8/16 bpp select */ +#define DC_OCFG_555 0x00000002 /* 16 bpp format */ +#define DC_OCFG_PCKE 0x00000004 /* PCLK enable */ +#define DC_OCFG_FRME 0x00000008 /* frame rate mod enable */ +#define DC_OCFG_DITE 0x00000010 /* dither enable */ +#define DC_OCFG_2PXE 0x00000020 /* 2 pixel enable */ +#define DC_OCFG_2XCK 0x00000040 /* 2 x pixel clock */ +#define DC_OCFG_2IND 0x00000080 /* 2 index enable */ +#define DC_OCFG_34ADD 0x00000100 /* 3- or 4-bit add */ +#define DC_OCFG_FRMS 0x00000200 /* frame rate mod select */ +#define DC_OCFG_CKSL 0x00000400 /* clock select */ +#define DC_OCFG_PRMP 0x00000800 /* palette re-map */ +#define DC_OCFG_PDEL 0x00001000 /* panel data enable low */ +#define DC_OCFG_PDEH 0x00002000 /* panel data enable high */ +#define DC_OCFG_CFRW 0x00004000 /* comp line buffer r/w sel */ +#define DC_OCFG_DIAG 0x00008000 /* comp line buffer diag */ + +/* MC REGISTER DEFINITIONS */ + +#define MC_GBASE_ADD 0x8414 /* Graphics mem base address */ +#define MC_DR_ADD 0x8418 /* Dirty RAM address index */ +#define MC_DR_ACC 0x841C /* Dirty RAM memory access */ +#define MC_RAMDAC_ACC 0x8420 /* RAMDAC register access */ + +/* CPU REGISTER REGISTER DEFINITIONS */ + +#define BB0_BASE 0xFFFFFF0C /* Blit buffer 0 base */ +#define BB1_BASE 0xFFFFFF1C /* Blit buffer 1 base */ + + + +/* SoftVGA CRTC register indices and bit definitions */ + +#define CrtcExtendedRegisterLock 0x30 +#define CrtcGraphicsMemorySize 0x3E +#define CrtcModeSwitchControl 0x3F +#define CrtcVerticalTimingExtension 0x41 +#define CrtcExtendedAddressControl 0x43 +#define CrtcExtendedStartAddress 0x44 +#define CrtcExtendedOffset 0x45 +#define CrtcExtendedColorControl 0x46 +#define CrtcWriteMemoryAperture 0x47 +#define CrtcReadMemoryAperture 0x48 +#define CrtcDisplayCompression 0x49 +#define CrtcDriverControl 0x4A +#define CrtcDACControl 0x4B +#define CrtcClockControl 0x4C +#define CrtcClockFrequency 0x4D +#define CrtcClockFrequencyFraction 0x4E +#define CrtcRefreshRate 0x4F + +/* ExtendedAddressControl bit definitions */ +#define EAC_PIXEL_DOUBLE 0x04 +#define EAC_DIRECT_FRAME_BUFFER 0x02 +#define EAC_PACKED_CHAIN4 0x01 + +/* ExtendedColorControl bit definitions */ +#define ECC_32BPP 0x04 /* MXi only */ +#define ECC_555_FORMAT 0x02 +#define ECC_565_FORMAT 0x00 +#define ECC_16BPP 0x01 +#define ECC_8BPP 0x00 + +/* DriverControl bit definitions */ +#define DRVCT_DISPLAY_DRIVER_ACTIVE 0x01 + +/* DACControl bit definitions */ +#define DACCT_HALF_PIXEL_PER_CLOCK 0x08 +#define DACCT_TWO_PIXELS_PER_CLOCK 0x04 +#define DACCT_ENABLE_16BIT_BUS 0x02 + +/* ClockControl bit definitions */ +#define CLKCT_EXT_CLOCK_MODE 0x80 +#define CLKCT_HALVE_DOT_CLOCK 0x20 +#define CLKCT_DOUBLE_DOT_CLOCK 0x10 +#define CLKCT_GENDAC_ICS5342 0x00 +#define CLKCT_GENDAC_MASK 0x07 + +#endif /* _CYRIX_H_ */ diff --git a/src/cyrix_accel.c b/src/cyrix_accel.c new file mode 100644 index 0000000..652c1d8 --- /dev/null +++ b/src/cyrix_accel.c @@ -0,0 +1,447 @@ +/* + * Copyright 2000 by Richard A. Hecker, California, United States + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Richard Hecker not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Richard Hecker makes no representations + * about the suitability of this software for any purpose. It is provided + * "as is" without express or implied warranty. + * + * RICHARD HECKER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL RICHARD HECKER BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + * Author: Richard Hecker, hecker@cat.dfrc.nasa.gov + * Re-written for XFree86 v4.0 + * Previous driver (pre-XFree86 v4.0) by + * Annius V. Groenink (A.V.Groenink@zfc.nl, avg@cwi.nl), + * Dirk H. Hohndel (hohndel@suse.de), + * Portions: the GGI project & confidential CYRIX databooks. + */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/cyrix/cyrix_accel.c,v 1.5 2002/11/06 11:38:59 alanh Exp $ */ + +#include "vgaHW.h" +#include "xf86.h" +#include "xf86_ansic.h" +#include "xaalocal.h" +#include "cyrix.h" +#include "miline.h" +#include "xf86_libc.h" +#include "compiler.h" + +/* size of color expand source area (embedded in frame buffer) */ +#define CYRIXexpandSize 32768 + +/* Raster operations are converted in such a way that we can use them to + do planemask operations: lower nybble is NOP (pattern=planemask), + upper nybble inverted X raster operation (bits 0 - 3 correspond to + bits 3 - 0 and 7 - 4 in Windows style ROP). In some routines, + the role of source and pattern is inverted. */ +static const int windowsROPpatMask[16] = { 0x0A, 0x8A, 0x4A, 0xCA, + 0x2A, 0xAA, 0x6A, 0xEA, + 0x1A, 0x9A, 0x5A, 0xDA, + 0x3A, 0xBA, 0x7A, 0xFA }; + +static const int windowsROPsrcMask[16] = { 0x22, 0xA2, 0x62, 0xE2, + 0x2A, 0xAA, 0x6A, 0xEA, + 0x26, 0xA6, 0x66, 0xE6, + 0x2E, 0xAE, 0x6E, 0xEE }; + +/* Forward declaration of functions used in the driver */ +void CYRIXAccelSync(ScrnInfoPtr pScrn); +void CYRIXSetupForSolidFill(ScrnInfoPtr pScrn, int color, int rop, + unsigned int planemask); +void CYRIXSubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y, + int w, int h); +void CYRIXSetupForScreenToScreenCopy(ScrnInfoPtr, int xdir, int ydir, + int rop, unsigned int planemask, int transparency_color); +void CYRIXSubsequentScreenToScreenCopy(ScrnInfoPtr, int x1, int y1, int x2, + int y2, int w, int h); +void CYRIXSubsequentBresenhamLine(ScrnInfoPtr pScrn,int x1, int y1, + int e1, int e2, int err, int length, + int octant); +void CYRIXSetupForColor8x8PatternFillRect(ScrnInfoPtr pScrn, int patternx, + int patterny, int rop, unsigned int planemask, int transparency_color); +void CYRIXSubsequentColor8x8PatternFillRect(ScrnInfoPtr pScrn, int patternx, + int patterny, int x, int y, int w, int h); +void CYRIXSetupForCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, int fg, + int bg, int rop, unsigned int planemask); +void CYRIXSubsequentCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, int x, + int y, int w, int h, int skipleft); +void InitPixmapCache(ScreenPtr pScreen, RegionPtr areas, pointer data); +/* Info Rec for all these routines to use */ + +/* Acceleration init function, sets up pointers to our accelerated functions */ +void +CYRIXAccelInit(ScreenPtr pScreen) +{ /* General acceleration flags */ + + CYRIXPrvPtr pCyrix; + ScrnInfoPtr pScrn; + XAAInfoRecPtr localRecPtr; + + pScrn = xf86Screens[pScreen->myNum]; + pCyrix = CYRIXPTR(pScrn); + pCyrix->AccelInfoRec = localRecPtr = XAACreateInfoRec(); + localRecPtr->Flags = PIXMAP_CACHE + | PW_BACKGROUND +#if 0 + | HARDWARE_PATTERN_MONO_TRANSPARENCY +#endif + | HARDWARE_PATTERN_SCREEN_ORIGIN + | BIT_ORDER_IN_BYTE_MSBFIRST + | HARDWARE_PATTERN_PROGRAMMED_BITS; + + /* Sync */ + localRecPtr->Sync = CYRIXAccelSync; + + /* Filled rectangles */ + localRecPtr->SetupForSolidFill = + CYRIXSetupForSolidFill; + localRecPtr->SubsequentSolidFillRect = + CYRIXSubsequentSolidFillRect; + pCyrix->AccelInfoRec->PolyFillRectSolidFlags = NO_PLANEMASK; + + /* ScreenToScreen copies */ + localRecPtr->SetupForScreenToScreenCopy = + CYRIXSetupForScreenToScreenCopy; + localRecPtr->SubsequentScreenToScreenCopy = + CYRIXSubsequentScreenToScreenCopy; + + pCyrix->AccelInfoRec->CopyAreaFlags = NO_PLANEMASK | GXCOPY_ONLY; + +#if 0 + /* Bresenham lines - disable because of minor display errors */ + localRecPtr->SubsequentBresenhamLine = + CYRIXSubsequentBresenhamLine; + localRecPtr->ErrorTermBits = 15; +#endif + + /* 8x8 color-expanded patterns */ + localRecPtr->SetupForColor8x8PatternFill = + CYRIXSetupForColor8x8PatternFillRect; + localRecPtr->SubsequentColor8x8PatternFillRect = + CYRIXSubsequentColor8x8PatternFillRect; + + /* Color expansion */ + localRecPtr->Color8x8PatternFillFlags = + BIT_ORDER_IN_BYTE_MSBFIRST | NO_PLANEMASK | + TRANSPARENCY_GXCOPY_ONLY | SCANLINE_PAD_DWORD; + + /* Use two blit buffers in a row for text expansion + (this is an undefendable fix to a text display distortion + bug if we don't give XAA enough room, but the only thing that + seems to make it work properly) */ + localRecPtr->ColorExpandBase = + (unsigned char*)(pCyrix->GXregisters + pCyrix->CYRIXbltBuf0Address); + localRecPtr->ColorExpandRange = + pCyrix->CYRIXbltBufSize * 2; + + localRecPtr->SetupForCPUToScreenColorExpandFill = + CYRIXSetupForCPUToScreenColorExpandFill; + localRecPtr->SubsequentCPUToScreenColorExpandFill = + CYRIXSubsequentCPUToScreenColorExpandFill; + + /* calculate the pixel width of a blit buffer for convenience */ + pCyrix->bltBufWidth = pCyrix->CYRIXbltBufSize / (pScrn->bitsPerPixel / 8); +} + + +/* set colors - called through access macros in cyrix.h */ +static __inline__ void CYRIXsetColors01(ScrnInfoPtr pScrn, int reg, + int col0, int col1) { + CYRIXPrvPtr pCyrix = CYRIXPTR(pScrn); + + if (pScrn->bitsPerPixel == 16) + GX_REG(reg) = ((col1 & 0xFFFF) << 16) | (col0 & 0xFFFF); + else + { col0 &= 0xFF; + col1 &= 0xFF; + GX_REG(reg) = (col1 << 24) | (col1 << 16) | (col0 << 8) | col0; +} } + + +/* The generic Sync() function that waits for everything to + be completed (e.g. before writing to the frame buffer + directly). */ +void +CYRIXAccelSync(ScrnInfoPtr pScrn) +{ + CYRIXPrvPtr pCyrix = CYRIXPTR(pScrn); + + if (pCyrix->setBlitModeOnSync) + { pCyrix->setBlitModeOnSync = 0; + CYRIXsetupSync(); + CYRIXsetBlitMode(); + } + while (GX_REG(GP_BLIT_STATUS) & + (BS_BLIT_BUSY|BS_PIPELINE_BUSY|BS_BLIT_PENDING)); +} + + +/* Solid rectangles */ +void +CYRIXSetupForSolidFill(pScrn, color, rop, planemask) +ScrnInfoPtr pScrn; +int color, rop; +unsigned int planemask; +{ + CYRIXPrvPtr pCyrix; + + pCyrix = CYRIXPTR(pScrn); + if (pCyrix->AccelInfoRec->PolyFillRectSolidFlags & GXCOPY_ONLY) + rop = GXcopy; + if (pCyrix->AccelInfoRec->PolyFillRectSolidFlags & NO_PLANEMASK) + planemask = 0xFFFF; + CYRIXsetupSync(); + CYRIXsetSourceColors01(pScrn, color, color); + CYRIXsetPatColors01(pScrn, planemask, 0); + CYRIXsetPatMode(rop, RM_PAT_DISABLE); + pCyrix->blitMode = BM_READ_SRC_NONE | BM_WRITE_FB | BM_SOURCE_EXPAND + | IfDest(rop, planemask, BM_READ_DST_FB0); + pCyrix->vectorMode = IfDest(rop, planemask, VM_READ_DST_FB); +} + + +void +CYRIXSubsequentSolidFillRect(pScrn, x, y, w, h) +ScrnInfoPtr pScrn; +int x, y, w, h; +{ + CYRIXPrvPtr pCyrix = CYRIXPTR(pScrn); + + /* divide the operation into columns if required; use twice the + blit buffer width because buffer 0 will overflow into buffer 1 */ + while (w > 2 * pCyrix->bltBufWidth) + { CYRIXSubsequentSolidFillRect(pScrn, x, y, + 2 * pCyrix->bltBufWidth, h); + x += 2 * pCyrix->bltBufWidth; + w -= 2 * pCyrix->bltBufWidth; + } + CYRIXsetupSync(); + CYRIXsetDstXY(x, y); + CYRIXsetWH(w, h); + CYRIXsetBlitMode(); +} + + +/* Screen to screen copies */ +void +CYRIXSetupForScreenToScreenCopy(pScrn, xdir, ydir, rop, + planemask, transparency_color) +ScrnInfoPtr pScrn; +int xdir, ydir; +int rop; +unsigned int planemask; +int transparency_color; +{ + CYRIXPrvPtr pCyrix; + + pCyrix = CYRIXPTR(pScrn); + if (pCyrix->AccelInfoRec->CopyAreaFlags & NO_PLANEMASK) + planemask = 0xFFFF; + if (pCyrix->AccelInfoRec->CopyAreaFlags & GXCOPY_ONLY) + rop = GXcopy; + if (pCyrix->AccelInfoRec->CopyAreaFlags & NO_TRANSPARENCY) + transparency_color = -1; + + CYRIXsetupSync(); + CYRIXsetPatColors01(pScrn, planemask, 0); + + if (transparency_color == -1) + { CYRIXsetPatMode(rop, RM_PAT_DISABLE); + pCyrix->transMode = 0; + } + else + { CYRIXsetPatModeTrans(RM_PAT_DISABLE); + pCyrix->transMode = 1; + + if (pCyrix->AccelInfoRec->CopyAreaFlags & + TRANSPARENCY_GXCOPY_ONLY) + rop = GXcopy; + + /* fill blit buffer 1 with the transparency color */ + if (pScrn->bitsPerPixel == 16) + { int k = pCyrix->CYRIXbltBufSize / 4; + CARD32 val = (transparency_color << 16) | + transparency_color; + volatile CARD32* buf = &(GX_REG(pCyrix->CYRIXbltBuf1Address)); + + while (--k >= 0) buf[k] = val; + } + else + memset(pCyrix->GXregisters + pCyrix->CYRIXbltBuf1Address, + transparency_color, pCyrix->CYRIXbltBufSize); + } + + pCyrix->blitMode = BM_READ_SRC_FB | BM_WRITE_FB | BM_SOURCE_COLOR + | (pCyrix->transMode ? BM_READ_DST_NONE : IfDest(rop, planemask, BM_READ_DST_FB1)) + | (ydir < 0 ? BM_REVERSE_Y : 0); + + pCyrix->copyXdir = xdir; +} + +void +CYRIXSubsequentScreenToScreenCopy(pScrn, x1, y1, x2, y2, w, h) +ScrnInfoPtr pScrn; +int x1, y1, x2, y2, w, h; +{ + CYRIXPrvPtr pCyrix = CYRIXPTR(pScrn); + int up = (pCyrix->blitMode & BM_REVERSE_Y); + + /* divide the operation into columns when necessary */ + if (pCyrix->copyXdir < 0) + { int x_offset = w - pCyrix->bltBufWidth; + + while (x_offset > 0) + { CYRIXSubsequentScreenToScreenCopy(pScrn, x1 + x_offset, y1, + x2 + x_offset, y2, + pCyrix->bltBufWidth, h); + x_offset -= pCyrix->bltBufWidth; + w -= pCyrix->bltBufWidth; + } } + else while (w > pCyrix->bltBufWidth) + { CYRIXSubsequentScreenToScreenCopy(pScrn, x1, y1, x2, y2, + pCyrix->bltBufWidth, h); + x1 += pCyrix->bltBufWidth; + x2 += pCyrix->bltBufWidth; + w -= pCyrix->bltBufWidth; + } + + CYRIXsetupSync(); + CYRIXsetSrcXY(x1, (up ? (y1 + h - 1) : y1)); + CYRIXsetDstXY(x2, (up ? (y2 + h - 1) : y2)); + + /* in transparent mode, one line reads the transparency color + into a processor-internal register, and the remaining lines + can be done in a single second pass */ + if (pCyrix->transMode) + { pCyrix->blitMode |= BM_READ_DST_BB1; + CYRIXsetWH(w, 1); + CYRIXsetBlitMode(); + h--; + if (!h) return; + if (up) { y1--; y2--; } + else { y1++; y2++; } + CYRIXsetupSync(); + pCyrix->blitMode &= ~(BM_READ_DST_BB1); + } + CYRIXsetWH(w, h); + CYRIXsetBlitMode(); +} + + +/* Bresenham lines */ +void +CYRIXSubsequentBresenhamLine(pScrn, x1, y1, e1, e2, err, length, octant) +ScrnInfoPtr pScrn; int x1, y1, octant, err, e1, e2, length; +{ + CYRIXPrvPtr pCyrix = CYRIXPTR(pScrn); + + if (octant & YMAJOR) { + pCyrix->vectorMode = (pCyrix->vectorMode & VM_READ_DST_FB) | VM_Y_MAJOR; + if (!(octant & XDECREASING)) pCyrix->vectorMode |= VM_MINOR_INC; + if (!(octant & YDECREASING)) pCyrix->vectorMode |= VM_MAJOR_INC; + } else { + pCyrix->vectorMode = (pCyrix->vectorMode & VM_READ_DST_FB) | VM_X_MAJOR; + if (!(octant & XDECREASING)) pCyrix->vectorMode |= VM_MAJOR_INC; + if (!(octant & YDECREASING)) pCyrix->vectorMode |= VM_MINOR_INC; + } + + CYRIXsetupSync(); + CYRIXsetDstXY(x1, y1); + CYRIXsetWH(length, (err & 0xFFFF)); + CYRIXsetSrcXY((e1 & 0xFFFF), (e2 & 0xFFFF)); + CYRIXsetVectorMode(); +} + + +/* 8x8 pattern color expand */ +void CYRIXSetupForColor8x8PatternFillRect(pScrn, patternx, patterny, + rop, planemask, transparency_color) +ScrnInfoPtr pScrn; +int patternx, patterny; +int rop, transparency_color; +unsigned int planemask; +{ + CYRIXPrvPtr pCyrix = CYRIXPTR(pScrn); + XAAInfoRecPtr localRecPtr = pCyrix->AccelInfoRec; + + if (localRecPtr->Color8x8PatternFillFlags & NO_PLANEMASK) + planemask = 0xFFFF; + if ((transparency_color == -1) && (localRecPtr->Color8x8PatternFillFlags & + TRANSPARENCY_GXCOPY_ONLY)) + rop = GXcopy; + + CYRIXsetupSync(); + CYRIXsetPatColors01(pScrn, (transparency_color == -1) ? + 0 : transparency_color, planemask); + CYRIXsetPatData(patternx, patterny); + CYRIXsetPatModeX(rop, RM_PAT_MONO | ((transparency_color == -1) ? + RM_PAT_TRANSPARENT : 0)); + + pCyrix->blitMode = BM_READ_SRC_NONE | BM_WRITE_FB | BM_SOURCE_EXPAND | + ((transparency_color == -1) ? + IfDest(rop, planemask, BM_READ_DST_FB0) : BM_READ_DST_NONE); +} + +void CYRIXSubsequentColor8x8PatternFillRect(pScrn, patternx, patterny, x, y, w, h) +ScrnInfoPtr pScrn; +int patternx, patterny; +int x, y, w, h; +{ CYRIXSubsequentSolidFillRect(pScrn, x, y, w, h); +} + + +/* CPU-to-screen color expansion */ +void CYRIXSetupForCPUToScreenColorExpandFill(pScrn, fg, bg, rop, planemask) +ScrnInfoPtr pScrn; +int bg, fg, rop; +unsigned int planemask; +{ + CYRIXPrvPtr pCyrix = CYRIXPTR(pScrn); + XAAInfoRecPtr localRecPtr = pCyrix->AccelInfoRec; + + int trans = (bg == -1); + + if (trans && (localRecPtr->CPUToScreenColorExpandFillFlags & + TRANSPARENCY_GXCOPY_ONLY)) + rop = GXcopy; + + CYRIXsetupSync(); + CYRIXsetSourceColors01(pScrn, trans ? 0 : bg, fg); + CYRIXsetPatColors01(pScrn, planemask, 0); + + CYRIXsetPatMode(rop, RM_PAT_DISABLE | (trans ? RM_SRC_TRANSPARENT : 0)); + + /* this is formally incorrect: XAA may use both BB0 and BB1 + for the text source bitmap, so READ_DST_FB1 should not be + used. So far, this problem has not manifested itself in + practice. */ + pCyrix->blitMode = BM_READ_SRC_BB0 | BM_WRITE_FB | BM_SOURCE_EXPAND + | (trans ? IfDest(rop, planemask, BM_READ_DST_FB1) : BM_READ_DST_NONE); +} + +void CYRIXSubsequentCPUToScreenColorExpandFill(pScrn, x, y, w, h, skipleft) +ScrnInfoPtr pScrn; +int x, y, w, h; +int skipleft; +{ + CYRIXPrvPtr pCyrix = CYRIXPTR(pScrn); + CYRIXsetupSync(); + CYRIXsetSrcXY(0, 0); + CYRIXsetDstXY(x, y); + CYRIXsetWH(w, h); + + CYRIXAccelSync(pScrn); + pCyrix->setBlitModeOnSync = 1; +} + diff --git a/src/cyrix_bank.c b/src/cyrix_bank.c new file mode 100644 index 0000000..e06d6dd --- /dev/null +++ b/src/cyrix_bank.c @@ -0,0 +1,72 @@ +/* + * Copyright 2000 by Richard A. Hecker, California, United States + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Richard Hecker not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Richard Hecker makes no representations + * about the suitability of this software for any purpose. It is provided + * "as is" without express or implied warranty. + * + * RICHARD HECKER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL RICHARD HECKER BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + * Author: Richard Hecker, hecker@cat.dfrc.nasa.gov + * Re-written for XFree86 v4.0 + * Previous driver (pre-XFree86 v4.0) by + * Annius V. Groenink (A.V.Groenink@zfc.nl, avg@cwi.nl), + * Dirk H. Hohndel (hohndel@suse.de), + * Portions: the GGI project & confidential CYRIX databooks. + */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/cyrix/cyrix_bank.c,v 1.3 2002/11/06 11:38:59 alanh Exp $ */ + +#define PSZ 8 + +/* All drivers should typically include these */ +#include "xf86.h" +#include "xf86_OSproc.h" +#include "xf86_ansic.h" + +/* Everything using inb/outb, etc needs "compiler.h" */ +#include "compiler.h" + +/* Drivers for PCI hardware need this */ +#include "xf86PciInfo.h" + +/* Drivers that need to access the PCI config space directly need this */ +#include "xf86Pci.h" + +/* Driver specific headers */ +#include "cyrix.h" + +int +CYRIXSetRead(ScreenPtr pScreen, int bank) +{ + outw(0x3D6, ((((bank << 3) & 0xFF) << 8) | 0x10)); + return 0; +} + + +int +CYRIXSetWrite(ScreenPtr pScreen, int bank) +{ + outw(0x3D6, ((((bank << 3) & 0xFF) << 8) | 0x11)); + return 0; +} + + +int +CYRIXSetReadWrite(ScreenPtr pScreen, int bank) +{ + outw(0x3D6, ((((bank << 3) & 0xFF) << 8) | 0x10)); + outw(0x3D6, ((((bank << 3) & 0xFF) << 8) | 0x11)); + return 0; +} diff --git a/src/cyrix_driver.c b/src/cyrix_driver.c new file mode 100644 index 0000000..9908478 --- /dev/null +++ b/src/cyrix_driver.c @@ -0,0 +1,1516 @@ +/* + * Copyright 2000 by Richard A. Hecker, California, United States + * Copyright 2002 by Red Hat Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Richard Hecker not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Richard Hecker makes no representations + * about the suitability of this software for any purpose. It is provided + * "as is" without express or implied warranty. + * + * RICHARD HECKER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL RICHARD HECKER BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + * RED HAT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL RICHARD HECKER BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + * Author: Richard Hecker, hecker@cat.dfrc.nasa.gov + * Re-written for XFree86 v4.0 + * + * Chunks re-written again for XFree86 v4.2 + * Alan Cox <alan@redhat.com> + * - Fixed cursor handling + * - Rewrote parts of the broken mode switch code + * - Added proper PCI detection + * - Added ShadowFB support + * - Added rotate support + * - Fixed palette loading/restore + * - Added "Nocompression" option + * - Fixed line length loading + * - Fixed panning logic + * + * Previous driver (pre-XFree86 v4.0) by + * Annius V. Groenink (A.V.Groenink@zfc.nl, avg@cwi.nl), + * Dirk H. Hohndel (hohndel@suse.de), + * Portions: the GGI project & confidential CYRIX databooks. + * (note that most of the data books have been released by + * NatSemi and are downloadable for free as pdf files) + */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/cyrix/cyrix_driver.c,v 1.26 2003/01/07 00:05:13 alanh Exp $ */ + +#include "fb.h" +#include "mibank.h" +#include "micmap.h" +#include "xf86.h" +#include "xf86_OSproc.h" +#include "xf86_ansic.h" +#include "xf86Version.h" +#include "xf86PciInfo.h" +#include "xf86Pci.h" +#include "xf86cmap.h" +#include "shadowfb.h" +#include "vgaHW.h" +#include "xf86DDC.h" +#include "xf86RAC.h" +#include "xf86Resources.h" +#include "compiler.h" +#include "xf86int10.h" +#include "vbe.h" + +#include "cyrix.h" + +#define _XF86DGA_SERVER_ +#include "extensions/xf86dgastr.h" + +#include "opaque.h" +#define DPMS_SERVER +#include "extensions/dpms.h" + +static const OptionInfoRec * CYRIXAvailableOptions(int chip, int busid); +static void CYRIXIdentify(int flags); +static Bool CYRIXProbe(DriverPtr drv, int flags); +static Bool CYRIXPreInit(ScrnInfoPtr pScrn, int flags); +static Bool CYRIXScreenInit(int Index, ScreenPtr pScreen, int argc, + char **argv); +static Bool CYRIXEnterVT(int scrnIndex, int flags); +static void CYRIXLeaveVT(int scrnIndex, int flags); +static Bool CYRIXCloseScreen(int scrnIndex, ScreenPtr pScreen); +static Bool CYRIXSaveScreen(ScreenPtr pScreen, int mode); + +/* Required if the driver supports mode switching */ +static Bool CYRIXSwitchMode(int scrnIndex, DisplayModePtr mode, int flags); +/* Required if the driver supports moving the viewport */ +static void CYRIXAdjustFrame(int scrnIndex, int x, int y, int flags); + +/* Optional functions */ +static void CYRIXFreeScreen(int scrnIndex, int flags); +static int CYRIXFindIsaDevice(GDevPtr dev); +static int CYRIXValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, + int flags); + +/* Internally used functions */ +static void CYRIXSave(ScrnInfoPtr pScrn); +static void CYRIXRestore(ScrnInfoPtr pScrn); +static Bool CYRIXModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode); +static void CYRIXRestorePalette(ScrnInfoPtr pScrn); +static void CYRIXSavePalette(ScrnInfoPtr pScrn); + +/* Misc additional routines */ +void CYRIXSetRead(int bank); +void CYRIXSetWrite(int bank); +void CYRIXSetReadWrite(int bank); + +#define VERSION 4000 +#define CYRIX_NAME "CYRIX" +#define CYRIX_DRIVER_NAME "cyrix" +#define CYRIX_MAJOR_VERSION 1 +#define CYRIX_MINOR_VERSION 0 +#define CYRIX_PATCHLEVEL 0 +#define VGA_REGION 2 + +enum GenericTypes { + CHIP_CYRIXmediagx +}; + +/* + * This contains the functions needed by the server after loading the driver + * module. It must be supplied, and gets passed back by the moduleSetup + * function in the dynamic case. In the static case, a reference to this + * is compiled in, and this requires that the name of this DriverRec be + * an upper-case version of the driver name. + */ + +DriverRec CYRIX = { + VERSION, + CYRIX_DRIVER_NAME, + CYRIXIdentify, + CYRIXProbe, + CYRIXAvailableOptions, + NULL, + 0 +}; + +static SymTabRec CYRIXChipsets[] = { + { CHIP_CYRIXmediagx, "mediagx" }, + { -1, NULL } +}; + +static IsaChipsets CYRIXISAChipsets[] = { + { CHIP_CYRIXmediagx, RES_EXCLUSIVE_VGA }, + { -1, 0 } +}; + +typedef enum { + OPTION_SW_CURSOR, + OPTION_HW_CURSOR, + OPTION_NOACCEL, + OPTION_NOCOMPRESS, + OPTION_SHADOW_FB, + OPTION_ROTATE +} CYRIXOpts; + +static const OptionInfoRec CYRIXOptions[] = { + { OPTION_SW_CURSOR, "SWcursor", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_HW_CURSOR, "HWcursor", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_NOCOMPRESS, "NoCompression",OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_SHADOW_FB, "ShadowFB", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_ROTATE, "Rotate", OPTV_ANYSTR, {0}, FALSE }, + { -1, NULL, OPTV_NONE, {0}, FALSE } +}; + +static const char *vgahwSymbols[] = { + "vgaHWFreeHWRec", + "vgaHWGetHWRec", + "vgaHWGetIOBase", + "vgaHWGetIndex", + "vgaHWHandleColormaps", + "vgaHWInit", + "vgaHWLock", + "vgaHWMapMem", + "vgaHWProtect", + "vgaHWRestore", + "vgaHWSave", + "vgaHWSaveScreen", + "vgaHWUnlock", + NULL +}; + +static const char *fbSymbols[] = { + "fbScreenInit", + "fbPictureInit", + NULL +}; + +static const char *xaaSymbols[] = { + "XAACreateInfoRec", + "XAADestroyInfoRec", + NULL +}; + +static const char *shadowSymbols[] = { + "ShadowFBInit", + NULL +}; + +static const char *vbeSymbols[] = { + "VBEInit", + "vbeDoEDID", + "vbeFree", + NULL +}; + +/* access to the MediaGX video hardware registers */ + + +/* DEBUG variables & flags */ +#define ENTER TRUE +#define LEAVE FALSE + +#ifdef XFree86LOADER + +static MODULESETUPPROTO(cyrixSetup); + +static XF86ModuleVersionInfo cyrixVersRec = +{ + "cyrix", + MODULEVENDORSTRING, + MODINFOSTRING1, + MODINFOSTRING2, + XF86_VERSION_CURRENT, + CYRIX_MAJOR_VERSION, CYRIX_MINOR_VERSION, CYRIX_PATCHLEVEL, + ABI_CLASS_VIDEODRV, /* This is a video driver */ + ABI_VIDEODRV_VERSION, + MOD_CLASS_VIDEODRV, + {0,0,0,0} +}; + +XF86ModuleData cyrixModuleData = { &cyrixVersRec, cyrixSetup, NULL }; + +pointer +cyrixSetup(pointer module, pointer opts, int *errmaj, int *errmin) +{ + static Bool setupDone = FALSE; + + if (!setupDone) { + setupDone = TRUE; + xf86AddDriver(&CYRIX, module, 0); + LoaderRefSymLists(vgahwSymbols, fbSymbols, xaaSymbols, vbeSymbols, shadowSymbols, NULL); + return (pointer)TRUE; + } + + if (errmaj) *errmaj = LDR_ONCEONLY; + return NULL; +} + +#endif /* XFree86LOADER */ + +static Bool +CYRIXGetRec(ScrnInfoPtr pScrn) +{ + /* + * Allocate a CYRIXRec, and hook it into pScrn->driverPrivate. + * pScrn->driverPrivate is initialised to NULL, so we can check if + * the allocation has already been done. + */ + if (pScrn->driverPrivate != NULL) + return TRUE; + + pScrn->driverPrivate = xnfcalloc(sizeof(CYRIXPrivate), 1); + if (pScrn->driverPrivate == NULL) + return FALSE; + + return TRUE; +} + +static void +CYRIXFreeRec(ScrnInfoPtr pScrn) +{ + if (pScrn->driverPrivate == NULL) + return; + xfree(pScrn->driverPrivate); + pScrn->driverPrivate = NULL; +} + +static void +CYRIXDisplayPowerManagementSet(ScrnInfoPtr pScrn, int PowerManagementMode, int flags) +{ + unsigned char DPMSCont, PMCont, temp; + outb(0x3C4, 0x0E); + temp = inb(0x3C5); + outb(0x3C5, 0xC2); + outb(0x83C8, 0x04); /* Read DPMS Control */ + PMCont = inb(0x83C6) & 0xFC; + outb(0x3CE, 0x23); + DPMSCont = inb(0x3CF) & 0xFC; + switch (PowerManagementMode) + { + case DPMSModeOn: + /* Screen: On, HSync: On, VSync: On */ + PMCont |= 0x03; + DPMSCont |= 0x00; + break; + case DPMSModeStandby: + /* Screen: Off, HSync: Off, VSync: On */ + PMCont |= 0x02; + DPMSCont |= 0x01; + break; + case DPMSModeSuspend: + /* Screen: Off, HSync: On, VSync: Off */ + PMCont |= 0x02; + DPMSCont |= 0x02; + break; + case DPMSModeOff: + /* Screen: Off, HSync: Off, VSync: Off */ + PMCont |= 0x00; + DPMSCont |= 0x03; + break; + } + outb(0x3CF, DPMSCont); + outb(0x83C8, 0x04); + outb(0x83C6, PMCont); + outw(0x3C4, (temp<<8) | 0x0E); +} + +/* Mandatory */ +static void +CYRIXIdentify(int flags) +{ + xf86PrintChipsets(CYRIX_NAME, "driver for Cyrix MediaGX Processors", CYRIXChipsets); +} + +static const OptionInfoRec * +CYRIXAvailableOptions(int chip, int busid) +{ + return CYRIXOptions; +} + +#define PCI_CHIP_CYRIX5510 0x0000 +#define PCI_CHIP_CYRIX5520 0x0002 +#define PCI_CHIP_CYRIX5530 0x0104 + +/* Conversion PCI ID to chipset name */ +static PciChipsets CYRIXPCIchipsets[] = { + { CHIP_CYRIXmediagx, PCI_CHIP_CYRIX5510, RES_EXCLUSIVE_VGA }, + { CHIP_CYRIXmediagx, PCI_CHIP_CYRIX5520, RES_EXCLUSIVE_VGA }, + { CHIP_CYRIXmediagx, PCI_CHIP_CYRIX5530, RES_EXCLUSIVE_VGA }, + { -1, -1, RES_UNDEFINED } +}; + +/* Mandatory */ +static Bool +CYRIXProbe(DriverPtr drv, int flags) +{ + int i, numDevSections, numUsed, *usedChips; + GDevPtr *devSections; + ScrnInfoPtr pScrn; + Bool foundScreen = FALSE; + + /* + * The aim here is to find all cards that this driver can handle, + * and for the ones not already claimed by another driver, claim the + * slot, and allocate a ScrnInfoRec. + * + */ + + /* + * Look for config file Device sections with this driver specified. + */ + if ((numDevSections = xf86MatchDevice(CYRIX_DRIVER_NAME, + &devSections)) <= 0) { +#ifdef DEBUG + xf86ErrorFVerb(3,"%s: No Device section found.\n",CYRIX_NAME); +#endif + /* + * There's no matching device section in the config file, so quit + * now. + */ + return FALSE; + } +#ifdef DEBUG + xf86ErrorFVerb(3,"%s: Device Sections found: %d\n",CYRIX_NAME, numDevSections); +#endif + + /* Should look like an ISA device */ + + /* PCI BUS */ + if (xf86GetPciVideoInfo() ) { + numUsed = xf86MatchPciInstances(CYRIX_NAME, PCI_VENDOR_CYRIX, + CYRIXChipsets, CYRIXPCIchipsets, + devSections,numDevSections, + drv, &usedChips); + + if (numUsed > 0) { + if (flags & PROBE_DETECT) + foundScreen = TRUE; + else for (i = 0; i < numUsed; i++) { + ScrnInfoPtr pScrn = NULL; + /* Allocate a ScrnInfoRec and claim the slot */ + if ((pScrn = xf86ConfigPciEntity(pScrn, 0, usedChips[i], + CYRIXPCIchipsets,NULL, NULL, + NULL, NULL, NULL))) { + pScrn->driverVersion = VERSION; + pScrn->driverName = CYRIX_DRIVER_NAME; + pScrn->name = CYRIX_NAME; + pScrn->Probe = CYRIXProbe; + pScrn->PreInit = CYRIXPreInit; + pScrn->ScreenInit = CYRIXScreenInit; + pScrn->SwitchMode = CYRIXSwitchMode; + pScrn->AdjustFrame = CYRIXAdjustFrame; + pScrn->LeaveVT = CYRIXLeaveVT; + pScrn->EnterVT = CYRIXEnterVT; + pScrn->FreeScreen = CYRIXFreeScreen; + pScrn->ValidMode = CYRIXValidMode; + foundScreen = TRUE; + } + } + xfree(usedChips); + } + } + + + numUsed = xf86MatchIsaInstances(CYRIX_NAME,CYRIXChipsets, + CYRIXISAChipsets,drv, + CYRIXFindIsaDevice,devSections, + numDevSections,&usedChips); + if(numUsed > 0) { + foundScreen = TRUE; + + /* Free it since we don't need that list after this */ + xfree(devSections); + + if (!(flags & PROBE_DETECT)) { + for (i=0; i < numUsed; i++) { + + /* Fill in what we can of the ScrnInfoRec */ + pScrn = NULL; + if ((pScrn = xf86ConfigIsaEntity(pScrn, 0, usedChips[i], + CYRIXISAChipsets, NULL, + NULL, NULL, NULL, NULL))){ + pScrn->driverVersion = VERSION; + pScrn->driverName = CYRIX_DRIVER_NAME; + pScrn->name = CYRIX_NAME; + pScrn->Probe = CYRIXProbe; + pScrn->PreInit = CYRIXPreInit; + pScrn->ScreenInit = CYRIXScreenInit; + pScrn->SwitchMode = CYRIXSwitchMode; + pScrn->AdjustFrame = CYRIXAdjustFrame; + pScrn->LeaveVT = CYRIXLeaveVT; + pScrn->EnterVT = CYRIXEnterVT; + pScrn->FreeScreen = CYRIXFreeScreen; + pScrn->ValidMode = CYRIXValidMode; + } + } + } + } + xfree(usedChips); + return (foundScreen); +} + +static int +CYRIXFindIsaDevice(GDevPtr dev) +{ + CARD32 CurrentValue, TestValue; + unsigned char gcr; + + /* No need to unlock VGA CRTC registers here */ + + /* VGA has one more read/write attribute register than EGA */ + /* use register probing to decide whether the chip is + * `suitable' for us. + */ + int vgaIOBase = VGAHW_GET_IOBASE(); + + (void) inb(vgaIOBase + 0x0AU); /* Reset flip-flop */ + outb(0x3C0, 0x14 | 0x20); + CurrentValue = inb(0x3C1); + outb(0x3C0, CurrentValue ^ 0x0F); + outb(0x3C0, 0x14 | 0x20); + TestValue = inb(0x3C1); + outb(0x3C0, CurrentValue); + + /* Quit now if no VGA is present */ + if ((CurrentValue ^ 0x0F) != TestValue) + return -1; + + /* the lock register should read 0xFF after we have + written 0x00 to lock */ + outb(vgaIOBase + 4, CrtcExtendedRegisterLock); + outb(vgaIOBase + 5, 0x00); + + if (inb(vgaIOBase + 5) != 0xFF) return -1; + + /* the lock register should read 0x00 after we have + written the magic word 'WL' to unlock */ + outb(vgaIOBase + 5, 0x57); + outb(vgaIOBase + 5, 0x4C); + + /* GGI's idea to do two comparisons */ + if (inb(vgaIOBase + 5) != 0x00) goto fail; + if (inb(vgaIOBase + 5) != 0x00) goto fail; + + /* OK, it's most likely a MediaGX. Now check the scratchpad + * size. If it is zero, we're not using the MediaGX graphics + * facilities. + */ + outb(GX_IOPORT_INDEX, GX_IOIDX_DIR0); /* doesn't work w/o that */ + outb(GX_IOPORT_INDEX, GX_IOIDX_GCR); + gcr = inb(GX_IOPORT_DATA); + + /* end GGI MediaGX driver based code */ + if (!(gcr & 12)) goto fail; + + /* Unprotect MediaGX extended registers */ + outb(vgaIOBase + 4, CrtcExtendedRegisterLock); + outb(vgaIOBase + 5, 0x00); + + return (int)CHIP_CYRIXmediagx; + + fail: + /* Protect MediaGX extended registers */ + outb(vgaIOBase + 4, CrtcExtendedRegisterLock); + outb(vgaIOBase + 5, 0x00); + return -1; +} + +static void +CYRIXProbeDDC(ScrnInfoPtr pScrn, int index) +{ + vbeInfoPtr pVbe; + if (xf86LoadSubModule(pScrn, "vbe")) { + pVbe = VBEInit(NULL,index); + ConfiguredMonitor = vbeDoEDID(pVbe, NULL); + vbeFree(pVbe); + } +} + +/* Mandatory */ +static Bool +CYRIXPreInit(ScrnInfoPtr pScrn, int flags) +{ + MessageType from; + CYRIXPrvPtr pCyrix; + int videoram; + int i; + ClockRangePtr clockRanges; + CARD32 physbase, padsize; + int CYRIXisOldChipRevision; + int device_step, device_revision; + int vgaIOBase; + unsigned char gcr; + static int accelWidths[3]= {2,1024, 2048}; + const char *s; + + /* Allocate the CYRIXRec driverPrivate */ + if (!CYRIXGetRec(pScrn)) return FALSE; + + /* + * Note: This function is only called once at server startup, and + * not at the start of each server generation. This means that + * only things that are persistent across server generations can + * be initialised here. xf86Screens[] is (pScrn is a pointer to one + * of these). Privates allocated using xf86AllocateScrnInfoPrivateIndex() + * are too, and should be used for data that must persist across + * server generations. + * + * Per-generation data should be allocated with + * AllocateScreenPrivateIndex() from the ScreenInit() function. + */ + pCyrix = CYRIXPTR(pScrn); + + pCyrix->pEnt = xf86GetEntityInfo(pScrn->entityList[0]); + + if (pCyrix->pEnt->location.type != BUS_PCI) + return FALSE; + + if (flags & PROBE_DETECT) { + CYRIXProbeDDC(pScrn, pCyrix->pEnt->index); + return TRUE; + } + + /* The vgahw module should be loaded here when needed */ + if (!xf86LoadSubModule(pScrn, "vgahw")) + return FALSE; + xf86LoaderReqSymLists(vgahwSymbols, NULL); + + /* + * Allocate a vgaHWRec + */ + if (!vgaHWGetHWRec(pScrn)) + return FALSE; + + VGAHWPTR(pScrn)->MapSize = 0x10000; /* Standard 64k VGA window */ + if (!vgaHWMapMem(pScrn)) + return FALSE; + + vgaHWGetIOBase(VGAHWPTR(pScrn)); + vgaIOBase = VGAHWPTR(pScrn)->IOBase; + + + /* Unprotect MediaGX extended registers */ + outb(vgaIOBase + 4, CrtcExtendedRegisterLock); + outb(vgaIOBase + 5, 0x57); + outb(vgaIOBase + 5, 0x4C); + + outb(GX_IOPORT_INDEX, GX_IOIDX_DIR0); /* doesn't work w/o that */ + outb(GX_IOPORT_INDEX, GX_IOIDX_GCR); + gcr = inb(GX_IOPORT_DATA); + + physbase = (gcr & 3) << 30; + padsize = (gcr & 12) ? (((gcr & 12) >> 2) + 1) : 0; + + /* end GGI MediaGX driver based code */ + if (padsize == 0) return (FALSE); + + xf86ErrorF("%s: GX_BASE: 0x%x\n",CYRIX_NAME, physbase); + xf86ErrorF("%s: Scratchpad size: %d kbytes\n",CYRIX_NAME, padsize); + + /* Probe for the MediaGX processor version details. Older versions + * use different op-codes for setting the organization of the + * blit buffers within the scratch padarea. We currently + * also use this version ID to guess whether the chipset has + * an external DAC (in which case we treat the colour maps + * in a slightly different fashion) + */ + outb(0x22, 0xFF); + device_step = device_revision = inb(0x23); + device_step >>= 8; + device_revision &= 0xFF; + xf86ErrorF("%s: MediaGX processor ID %d revision %d\n", + CYRIX_NAME, device_step, device_revision); + + CYRIXisOldChipRevision = (device_step == 0 && device_revision < 40); + + /* Some MediaGX systems have different blit buffer offsets than + * is indicated by the scratchpad size. Make sure that we have + * the right offsets by writing them into the corresponding CPU + * registers. The op-codes to use depend on the processor + * revision. The value `40' is a guess (awaiting details from Cyrix). + */ + pCyrix->CYRIXbltBufSize = (padsize == 4) ? 1840 : (padsize == 3) ? 1328 : 816; + pCyrix->CYRIXbltBuf1Address = 0x0E60 - pCyrix->CYRIXbltBufSize; + pCyrix->CYRIXbltBuf0Address = pCyrix->CYRIXbltBuf1Address - pCyrix->CYRIXbltBufSize; + + /* map the entire area from GX_BASE (scratchpad area) + up to the end of the control registers */ + pCyrix->GXregisters = (char*)xf86MapVidMem(pScrn->scrnIndex, + VGA_REGION, (int )physbase, 0x9000); + if (!pCyrix->GXregisters) { + ErrorF("%s: Cannot map hardware registers\n", CYRIX_NAME); + return FALSE; + } + + /* This is the general case */ + for (i = 0; i<pScrn->numEntities; i++) { + pCyrix->pEnt = xf86GetEntityInfo(pScrn->entityList[i]); + if (pCyrix->pEnt->resources) return FALSE; + pCyrix->Chipset = pCyrix->pEnt->chipset; + pScrn->chipset = (char *)xf86TokenToString(CYRIXChipsets, + pCyrix->pEnt->chipset); + } + + /* Set pScrn->monitor */ + pScrn->monitor = pScrn->confScreen->monitor; + + /* + * The first thing we should figure out is the depth, bpp, etc. + * Our default depth is 8, so pass it to the helper function. + */ + if (!xf86SetDepthBpp(pScrn, 8, 0, 0, Support24bppFb)) { + return FALSE; + } else { + /* Check that the returned depth is one we support */ + switch (pScrn->depth) { + case 1: + case 4: + case 8: + case 15: + case 16: + /* OK */ + break; + default: + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Given depth (%d) is not supported by this driver\n", + pScrn->depth); + return FALSE; + } + } + + /* + * This must happen after pScrn->display has been set because + * xf86SetWeight references it. + */ + if (pScrn->depth > 8) { + /* The defaults are OK for us */ + rgb zeros = {0, 0, 0}; + + if (!xf86SetWeight(pScrn, zeros, zeros)) { + return FALSE; + } else { + /* XXX check that weight returned is supported */ + ; + } + } + xf86PrintDepthBpp(pScrn); + + /* + * The new cmap layer needs this to be initialised. + */ + + { + Gamma zeros = {0.0, 0.0, 0.0}; + + if (!xf86SetGamma(pScrn, zeros)) { + return FALSE; + } + } + + /* We use a programmable clock */ + pScrn->progClock = TRUE; + + /* Allocate the CYRIXRec driverPrivate */ + if (!CYRIXGetRec(pScrn)) { + return FALSE; + } + pCyrix = CYRIXPTR(pScrn); + + /* Collect all of the relevant option flags (fill in pScrn->options) */ + xf86CollectOptions(pScrn, NULL); + + /* Process the options */ + if (!(pCyrix->Options = xalloc(sizeof(CYRIXOptions)))) + return FALSE; + memcpy(pCyrix->Options, CYRIXOptions, sizeof(CYRIXOptions)); + xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, pCyrix->Options); + + /* Set the bits per RGB for 8bpp mode */ + pScrn->rgbBits = 6; + + from = X_DEFAULT; + pCyrix->HWCursor = FALSE; + if (xf86IsOptionSet(pCyrix->Options, OPTION_HW_CURSOR)) { + from = X_CONFIG; + pCyrix->HWCursor = TRUE; + } + if (xf86IsOptionSet(pCyrix->Options, OPTION_SW_CURSOR)) { + from = X_CONFIG; + pCyrix->HWCursor = FALSE; + } + if (pCyrix->HWCursor == TRUE) + xf86DrvMsg(pScrn->scrnIndex, from, "Hardware cursor is disabled in this release\n"); + + if (xf86ReturnOptValBool(pCyrix->Options, OPTION_SHADOW_FB, FALSE)) { + pCyrix->ShadowFB = TRUE; + pCyrix->NoAccel = TRUE; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "Using \"Shadow Framebuffer\" - acceleration disabled\n"); + } + pCyrix->Rotate = 0; + if ((s = xf86GetOptValString(pCyrix->Options, OPTION_ROTATE))) { + if(!xf86NameCmp(s, "CW")) { + pCyrix->ShadowFB = TRUE; + pCyrix->NoAccel = TRUE; + pCyrix->HWCursor = FALSE; + pCyrix->Rotate = 1; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "Rotating screen clockwise - acceleration disabled\n"); + } else + if(!xf86NameCmp(s, "CCW")) { + pCyrix->ShadowFB = TRUE; + pCyrix->NoAccel = TRUE; + pCyrix->HWCursor = FALSE; + pCyrix->Rotate = -1; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "Rotating screen counter clockwise - acceleration disabled\n"); + } else { + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "\"%s\" is not a valid value for Option \"Rotate\"\n", s); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Valid options are \"CW\" or \"CCW\"\n"); + } + } + xf86DrvMsg(pScrn->scrnIndex, from, "Using %s cursor\n", + pCyrix->HWCursor ? "HW" : "SW"); + if (xf86IsOptionSet(pCyrix->Options, OPTION_NOACCEL)) { + pCyrix->NoAccel = TRUE; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Acceleration disabled\n"); + } + + pCyrix->NoCompress = FALSE; + if (xf86IsOptionSet(pCyrix->Options, OPTION_NOCOMPRESS)) { + pCyrix->NoCompress = TRUE; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Compression disabled\n"); + } + + pCyrix->PciInfo = NULL; + pCyrix->RamDac = -1; + + /* + * This shouldn't happen because such problems should be caught in + * CYRIXProbe(), but check it just in case. + */ + if (pScrn->chipset == NULL) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "ChipID 0x%04X is not recognised\n", pCyrix->Chipset); + return FALSE; + } + if (pCyrix->Chipset < 0) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Chipset \"%s\" is not recognised\n", pScrn->chipset); + return FALSE; + } + + + pCyrix->EngineOperation = 0x00; + + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Found %s chip\n", pScrn->chipset); + + if (pCyrix->pEnt->device->MemBase != 0) { + pCyrix->FbAddress = pCyrix->pEnt->device->MemBase; + from = X_CONFIG; + } else { + from = X_PROBED; + pCyrix->FbAddress = 0x40800000; /* Hard coded for 1st try */ + } + + xf86DrvMsg(pScrn->scrnIndex, from, "Linear framebuffer at 0x%lX\n", + (unsigned long)pCyrix->FbAddress); + + if (pCyrix->pEnt->device->IOBase != 0) { + pCyrix->IOAccelAddress = pCyrix->pEnt->device->IOBase; + from = X_CONFIG; + } else { + from = X_PROBED; + pCyrix->IOAccelAddress = 0x40008100; /* Hard coded for 1st try */ + } + + xf86DrvMsg(pScrn->scrnIndex, from,"IO registers at 0x%x\n",pCyrix->IOAccelAddress); + + /* HW bpp matches reported bpp */ + pCyrix->HwBpp = pScrn->bitsPerPixel; + + if (pCyrix->pEnt->device->videoRam != 0) { + pScrn->videoRam = pCyrix->pEnt->device->videoRam; + from = X_CONFIG; + } else { + from = X_PROBED; + outb(vgaIOBase + 4, CrtcGraphicsMemorySize); + videoram = (inb(vgaIOBase + 5) * 64); + pScrn->videoRam = videoram & 0xFFFFFC00; /* mask out the part we want */ + } + + xf86DrvMsg(pScrn->scrnIndex, from, "VideoRAM: %d kByte\n", + pScrn->videoRam); + + pCyrix->FbMapSize = pScrn->videoRam * 1024; + + /* Set the min pixel clock */ + pCyrix->MinClock = 16250; /* XXX Guess, need to check this */ + xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT, "Min pixel clock is %d MHz\n", + pCyrix->MinClock / 1000); + + pCyrix->MaxClock = 135000; + xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT, "Max pixel clock is %d MHz\n", + pCyrix->MaxClock / 1000); + + /* + * Setup the ClockRanges, which describe what clock ranges are available, + * and what sort of modes they can be used for. + */ + clockRanges = (ClockRangePtr)xnfcalloc(sizeof(ClockRange), 1); + clockRanges->next = NULL; + clockRanges->minClock = pCyrix->MinClock; + clockRanges->maxClock = pCyrix->MaxClock; + clockRanges->clockIndex = -1; /* programmable */ + clockRanges->interlaceAllowed = TRUE; + clockRanges->doubleScanAllowed = FALSE; /* XXX check this */ + + /* + * xf86ValidateModes will check that the mode HTotal and VTotal values + * don't exceed the chipset's limit if pScrn->maxHValue and + * pScrn->maxVValue are set. Since our CYRIXValidMode() already takes + * care of this, we don't worry about setting them here. + */ + + /* Select valid modes from those available */ + /* + * XXX Assuming min pitch 256, max 2048 + * XXX Assuming min height 128, max 2048 + */ + i = xf86ValidateModes(pScrn, pScrn->monitor->Modes, + pScrn->display->modes, clockRanges, + accelWidths, 256, 2048, + pScrn->bitsPerPixel, 128, 2048, + pScrn->display->virtualX, + pScrn->display->virtualY, + pCyrix->FbMapSize, + LOOKUP_BEST_REFRESH); + + if (i == -1) { + CYRIXFreeRec(pScrn); + return FALSE; + } + + /* Prune the modes marked as invalid */ + xf86PruneDriverModes(pScrn); + + if (i == 0 || pScrn->modes == NULL) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes found\n"); + CYRIXFreeRec(pScrn); + return FALSE; + } + + xf86SetCrtcForModes(pScrn, INTERLACE_HALVE_V); + + /* Set the current mode to the first in the list */ + pScrn->currentMode = pScrn->modes; + + /* Print the list of modes being used */ + xf86PrintModes(pScrn); + + /* Set display resolution */ + xf86SetDpi(pScrn, 0, 0); + + switch (pScrn->bitsPerPixel) { + case 1: + case 4: + case 8: + pCyrix->EngineOperation |= 0x00; + break; + case 16: + pCyrix->EngineOperation |= 0x01; + break; + } + + /* Load fb module */ + if (xf86LoadSubModule(pScrn, "fb") == NULL) { + CYRIXFreeRec(pScrn); + return FALSE; + } + + xf86LoaderReqSymLists(fbSymbols, NULL); + + /* Load XAA if needed */ + if (!pCyrix->NoAccel) { + if (!xf86LoadSubModule(pScrn, "xaa")) { + CYRIXFreeRec(pScrn); + return FALSE; + } + xf86LoaderReqSymLists(xaaSymbols, NULL); + + switch (pScrn->displayWidth * pScrn->bitsPerPixel / 8) { + case 512: + pCyrix->EngineOperation |= 0x00; + break; + case 1024: + pCyrix->EngineOperation |= 0x04; + break; + case 2048: + pCyrix->EngineOperation |= 0x08; + break; + } + } + + /* Load shadowfb if needed */ + if (pCyrix->ShadowFB) { + if (!xf86LoadSubModule(pScrn, "shadowfb")) { + CYRIXFreeRec(pScrn); + return FALSE; + } + xf86LoaderReqSymLists(shadowSymbols, NULL); + } + + return TRUE; +} + + +/* + * This function saves the video state. + */ +static void +CYRIXSave(ScrnInfoPtr pScrn) +{ + vgaRegPtr vgaReg; + CYRIXPrvPtr pCyrix; + CYRIXRegPtr cyrixReg; + + pCyrix = CYRIXPTR(pScrn); + vgaReg = &VGAHWPTR(pScrn)->SavedReg; + cyrixReg = &pCyrix->SavedReg; + + vgaHWSave(pScrn, vgaReg, VGA_SR_ALL); + CyrixSave(pScrn, cyrixReg); + CYRIXSavePalette(pScrn); +} + + +/* + * Initialise a new mode. This is currently still using the old + * "initialise struct, restore/write struct to HW" model. That could + * be changed. + */ + +static Bool +CYRIXModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode) +{ + int ret = -1; + vgaHWPtr hwp; + vgaRegPtr vgaReg; + CYRIXPrvPtr pCyrix; + CYRIXRegPtr cyrixReg; + + hwp = VGAHWPTR(pScrn); + vgaHWUnlock(hwp); + + /* Initialise the ModeReg values */ + if (!vgaHWInit(pScrn, mode)) + return FALSE; + pScrn->vtSema = TRUE; + + pCyrix = CYRIXPTR(pScrn); + + /* Do the guts of this work */ + ret = CyrixInit(pScrn, mode); + + if (!ret) + return FALSE; + + /* Program the registers */ + vgaReg = &hwp->ModeReg; + cyrixReg = &pCyrix->ModeReg; + + CyrixRestore(pScrn, cyrixReg); +/* vgaHWRestore(pScrn, vgaReg, VGA_SR_MODE);*/ + + return TRUE; +} + +/* + * Restore the initial (text) mode. + */ +static void +CYRIXRestore(ScrnInfoPtr pScrn) +{ + vgaHWPtr hwp; + vgaRegPtr vgaReg; + CYRIXPrvPtr pCyrix; + CYRIXRegPtr cyrixReg; + + hwp = VGAHWPTR(pScrn); + pCyrix = CYRIXPTR(pScrn); + vgaReg = &hwp->SavedReg; + cyrixReg = &pCyrix->SavedReg; + + vgaHWProtect(pScrn, TRUE); + + /*CyrixRestore(pScrn, cyrixReg);*/ + CYRIXRestorePalette(pScrn); + vgaHWRestore(pScrn, vgaReg, VGA_SR_ALL); + + vgaHWProtect(pScrn, FALSE); +} + +/* Needed because we are not VGA enough in all cases (eg 5530 LCD) */ + +static void +CYRIXLoadPalette( + ScrnInfoPtr pScrn, + int numColors, + int *indices, + LOCO *colors, + VisualPtr pVisual +){ + int i; + unsigned int locked; + CYRIXPrvPtr pCyrix = CYRIXPTR(pScrn); + + switch(pScrn->depth) { + case 15: + case 16: + return; + } + + locked = GX_REG(DC_UNLOCK); + GX_REG(DC_UNLOCK) = DC_UNLOCK_VALUE; + + for(i = 0; i < numColors; i++) { + unsigned int red, green, blue; + int index = indices[i]; + + red = colors[index].red; + green = colors[index].green; + blue = colors[index].blue;; + + GX_REG(DC_PAL_ADDRESS) = index; + GX_REG(DC_PAL_DATA) = (red << 12) | (green << 6) | blue; + } + GX_REG(DC_UNLOCK) = locked; +} + +static void CYRIXSavePalette(ScrnInfoPtr pScrn) +{ + int i; + unsigned int locked; + CYRIXPrvPtr pCyrix = CYRIXPTR(pScrn); + + locked = GX_REG(DC_UNLOCK); + GX_REG(DC_UNLOCK) = DC_UNLOCK_VALUE; + + for(i = 0; i < 256; i++) { + GX_REG(DC_PAL_ADDRESS) = i; + pCyrix->SavedReg.Colormap[i] = GX_REG(DC_PAL_DATA); + } + GX_REG(DC_UNLOCK) = locked; +} + +static void CYRIXRestorePalette(ScrnInfoPtr pScrn) +{ + int i; + unsigned int locked; + CYRIXPrvPtr pCyrix = CYRIXPTR(pScrn); + + locked = GX_REG(DC_UNLOCK); + GX_REG(DC_UNLOCK) = DC_UNLOCK_VALUE; + + for(i = 0; i < 256; i++) { + GX_REG(DC_PAL_ADDRESS) = i; + GX_REG(DC_PAL_DATA) = pCyrix->SavedReg.Colormap[i]; + } + GX_REG(DC_UNLOCK) = locked; +} + +/* Mandatory */ + +/* This gets called at the start of each server generation */ + +static Bool +CYRIXScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) +{ + /* The vgaHW references will disappear one day */ + ScrnInfoPtr pScrn; + vgaHWPtr hwp; + CYRIXPrvPtr pCyrix; + int ret; + VisualPtr visual; + int width, height, displayWidth; + unsigned char *FBStart; + /* + * First get the ScrnInfoRec + */ + pScrn = xf86Screens[pScreen->myNum]; + + hwp = VGAHWPTR(pScrn); + + hwp->MapSize = 0x10000; /* Standard 64k VGA window */ + + pCyrix = CYRIXPTR(pScrn); + + /* Map the VGA memory, frambuffer, and get the VGA IO base */ + if (!vgaHWMapMem(pScrn)) + return FALSE; + vgaHWGetIOBase(hwp); + pCyrix->FbBase = xf86MapVidMem(pScrn->scrnIndex, VIDMEM_FRAMEBUFFER, + (unsigned long)pCyrix->FbAddress, pCyrix->FbMapSize); + + /* Save the current state */ + CYRIXSave(pScrn); + + /* Initialise the first mode */ + CYRIXModeInit(pScrn, pScrn->currentMode); + + /* Darken the screen for aesthetic reasons and set the viewport */ + CYRIXSaveScreen(pScreen, SCREEN_SAVER_ON); + CYRIXAdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); + /* XXX Fill the screen with black */ +#if 0 + CYRIXSaveScreen(pScreen, SCREEN_SAVER_OFF); +#endif + + /* + * The next step is to setup the screen's visuals, and initialise the + * framebuffer code. In cases where the framebuffer's default + * choices for things like visual layouts and bits per RGB are OK, + * this may be as simple as calling the framebuffer's ScreenInit() + * function. If not, the visuals will need to be setup before calling + * a fb ScreenInit() function and fixed up after. + * + */ + + /* + * Reset visual list. + */ + if (pScrn->bitsPerPixel >= 8) miClearVisualTypes(); + + /* Setup the visuals we support. */ + if (pScrn->bitsPerPixel > 8) { + if (!miSetVisualTypes(pScrn->depth, TrueColorMask, pScrn->rgbBits, + pScrn->defaultVisual)) + return FALSE; + } else { + if (!xf86SetDefaultVisual(pScrn, -1)) + return FALSE; + + if (!miSetVisualTypes(pScrn->depth, + miGetDefaultVisualMask(pScrn->depth), + pScrn->rgbBits, pScrn->defaultVisual)) + return FALSE; + } + + miSetPixmapDepths (); + + width = pScrn->virtualX; + height = pScrn->virtualY; + displayWidth = pScrn->displayWidth; + + + if(pCyrix->Rotate) { + height = pScrn->virtualX; + width = pScrn->virtualY; + } + + if(pCyrix->ShadowFB) { + pCyrix->ShadowPitch = BitmapBytePad(pScrn->bitsPerPixel * width); + pCyrix->ShadowPtr = xalloc(pCyrix->ShadowPitch * height); + displayWidth = pCyrix->ShadowPitch / (pScrn->bitsPerPixel >> 3); + FBStart = pCyrix->ShadowPtr; + } else { + pCyrix->ShadowPtr = NULL; + FBStart = pCyrix->FbBase; + } + /* + * Call the framebuffer layer's ScreenInit function, and fill in other + * pScreen fields. + */ + + switch (pScrn->bitsPerPixel) { + case 1: + case 4: + case 8: + case 16: + ret = fbScreenInit(pScreen, FBStart, width, + height, pScrn->xDpi, pScrn->yDpi, + displayWidth, pScrn->bitsPerPixel); + break; + default: + xf86DrvMsg(scrnIndex, X_ERROR, + "Internal error: invalid bpp (%d) in CYRIXScreenInit\n", + pScrn->bitsPerPixel); + ret = FALSE; + break; + } + if (!ret) + return FALSE; + + xf86SetBlackWhitePixels(pScreen); + + if (pScrn->bitsPerPixel > 8) { + /* Fixup RGB ordering */ + visual = pScreen->visuals + pScreen->numVisuals; + while (--visual >= pScreen->visuals) { + if ((visual->class | DynamicClass) == DirectColor) { + visual->offsetRed = pScrn->offset.red; + visual->offsetGreen = pScrn->offset.green; + visual->offsetBlue = pScrn->offset.blue; + visual->redMask = pScrn->mask.red; + visual->greenMask = pScrn->mask.green; + visual->blueMask = pScrn->mask.blue; + } + } + } else if (pScrn->depth == 1) { + Cyrix1bppColorMap(pScrn); + } + + /* must be after RGB ordering fixed */ + fbPictureInit (pScreen, 0, 0); + + if (pScrn->depth < 8) { + miBankInfoPtr pBankInfo; + + /* Setup the vga banking variables */ + pBankInfo = (miBankInfoPtr)xnfcalloc(sizeof(miBankInfoRec),1); + if (pBankInfo == NULL) + return FALSE; + + pBankInfo->pBankA = hwp->Base; + pBankInfo->pBankB = hwp->Base; + pBankInfo->BankSize = 0x10000; + pBankInfo->nBankDepth = pScrn->depth; + xf86EnableAccess(pScrn); + + pBankInfo->SetSourceBank = + (miBankProcPtr)CYRIXSetRead; + pBankInfo->SetDestinationBank = + (miBankProcPtr)CYRIXSetWrite; + pBankInfo->SetSourceAndDestinationBanks = + (miBankProcPtr)CYRIXSetReadWrite; + if (!miInitializeBanking(pScreen, pScrn->virtualX, pScrn->virtualY, + pScrn->displayWidth, pBankInfo)) { + xfree(pBankInfo); + pBankInfo = NULL; + return FALSE; + } + } + + if (!pCyrix->NoAccel) + CYRIXAccelInit(pScreen); + + miInitializeBackingStore(pScreen); + xf86SetBackingStore(pScreen); + + xf86SetSilkenMouse(pScreen); + + /* Initialise cursor functions */ + miDCInitialize (pScreen, xf86GetPointerScreenFuncs()); + + + /* Initialise default colourmap */ + if (!miCreateDefColormap(pScreen)) + return FALSE; + + if (!xf86HandleColormaps(pScreen, 256, pScrn->rgbBits, + CYRIXLoadPalette, NULL, + CMAP_RELOAD_ON_MODE_SWITCH)) + return FALSE; + + xf86DPMSInit(pScreen, (DPMSSetProcPtr)CYRIXDisplayPowerManagementSet, 0); + + pScrn->memPhysBase = pCyrix->FbAddress; + pScrn->fbOffset = 0; + + if(pCyrix->ShadowFB) { + RefreshAreaFuncPtr refreshArea = CYRIXRefreshArea; + + if(pCyrix->Rotate) { + if (!pCyrix->PointerMoved) { + pCyrix->PointerMoved = pScrn->PointerMoved; + pScrn->PointerMoved = CYRIXPointerMoved; + } + + switch(pScrn->bitsPerPixel) { + case 8: refreshArea = CYRIXRefreshArea8; break; + case 16: refreshArea = CYRIXRefreshArea16; break; + } + } + + ShadowFBInit(pScreen, refreshArea); + } + + pCyrix->CloseScreen = pScreen->CloseScreen; + pScreen->CloseScreen = CYRIXCloseScreen; + pScreen->SaveScreen = CYRIXSaveScreen; + + /* Report any unused options (only for the first generation) */ + if (serverGeneration == 1) { + xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options); + } + + /* Done */ + return TRUE; +} + + +/* Usually mandatory */ +static Bool +CYRIXSwitchMode(int scrnIndex, DisplayModePtr mode, int flags) +{ + return CYRIXModeInit(xf86Screens[scrnIndex], mode); +} + + +/* Usually mandatory */ +static void +CYRIXAdjustFrame(int scrnIndex, int x, int y, int flags) +{ + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + vgaHWPtr hwp; + CYRIXPrvPtr pCyrix; + int base = y * pScrn->displayWidth + x; + unsigned char temp; + int vgaIOBase; + + hwp = VGAHWPTR(pScrn); + vgaIOBase = hwp->IOBase; + pCyrix = CYRIXPTR(pScrn); + + switch (pScrn->bitsPerPixel) { + case 4: +/* base /= 2; */ + base = base >> 4; + break; + case 8: + base = (base & 0xFFFFFFF8) >> 2; + break; + case 16: +/* base *= (pScrn->bitsPerPixel / 8); */ + base /= 2; + break; + } + + GX_REG(DC_UNLOCK) = DC_UNLOCK_VALUE; + + /* If you switch to poking FB_ST_OFFSET directly it expects to be + fed different values to the SoftVGA emulation code */ + + /*GX_REG(DC_FB_ST_OFFSET) = base; */ + /* CRT bits 0-15 */ + outw(vgaIOBase + 4, (base & 0x00FF00) | 0x0C); + outw(vgaIOBase + 4, ((base & 0x00FF) << 8) | 0x0D); + /* CRT bit 16 */ + outb(vgaIOBase + 4, 0x1E); temp = inb(vgaIOBase + 5) & 0xDF; + outb(vgaIOBase + 5, temp | (base & 0x10000) >> 11); + GX_REG(DC_UNLOCK) = 0; +} + + +/* + * This is called when VT switching back to the X server. Its job is + * to reinitialise the video mode. + * + * We may wish to unmap video/MMIO memory too. + */ + +/* Mandatory */ +static Bool +CYRIXEnterVT(int scrnIndex, int flags) +{ + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + + /* Should we re-save the text mode on each VT enter? */ + if (!CYRIXModeInit(pScrn, pScrn->currentMode)) + return FALSE; + + return TRUE; +} + + +/* + * This is called when VT switching away from the X server. Its job is + * to restore the previous (text) mode. + * + * We may wish to remap video/MMIO memory too. + */ + +/* Mandatory */ +static void +CYRIXLeaveVT(int scrnIndex, int flags) +{ + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + vgaHWPtr hwp = VGAHWPTR(pScrn); + + CYRIXRestore(pScrn); + vgaHWLock(hwp); +} + + +/* + * This is called at the end of each server generation. It restores the + * original (text) mode. It should really also unmap the video memory too. + */ + +/* Mandatory */ +static Bool +CYRIXCloseScreen(int scrnIndex, ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + vgaHWPtr hwp = VGAHWPTR(pScrn); + CYRIXPrvPtr pCyrix; + + if (pScrn->vtSema) { + CYRIXRestore(pScrn); + vgaHWLock(hwp); + } + pCyrix = CYRIXPTR(pScrn); + if(pCyrix->AccelInfoRec) + XAADestroyInfoRec(pCyrix->AccelInfoRec); + if (pCyrix->ShadowPtr) + xfree(pCyrix->ShadowPtr); + pScrn->vtSema = FALSE; + + pScreen->CloseScreen = pCyrix->CloseScreen; + return (*pScreen->CloseScreen)(scrnIndex, pScreen); +} + + +/* Free up any per-generation data structures */ + +/* Optional */ +static void +CYRIXFreeScreen(int scrnIndex, int flags) +{ + vgaHWFreeHWRec(xf86Screens[scrnIndex]); + CYRIXFreeRec(xf86Screens[scrnIndex]); +} + + +/* Checks if a mode is suitable for the selected chipset. */ + +/* Optional */ +static int +CYRIXValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags) +{ + return(MODE_OK); +} + +/* Do screen blanking */ + +/* Mandatory */ +static Bool +CYRIXSaveScreen(ScreenPtr pScreen, int mode) +{ + return vgaHWSaveScreen(pScreen, mode); +} + diff --git a/src/cyrix_helper.c b/src/cyrix_helper.c new file mode 100644 index 0000000..22c46a2 --- /dev/null +++ b/src/cyrix_helper.c @@ -0,0 +1,382 @@ +/* + * Copyright 2000 by Richard A. Hecker, California, United States + * Copyright 2002 by Red Hat Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Richard Hecker not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Richard Hecker makes no representations + * about the suitability of this software for any purpose. It is provided + * "as is" without express or implied warranty. + * + * RICHARD HECKER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL RICHARD HECKER BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + * RED HAT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL RICHARD HECKER BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + * Author: Richard Hecker, hecker@cat.dfrc.nasa.gov + * Re-written for XFree86 v4.0 + * + * Chunks re-written again for XFree86 v4.2 + * Alan Cox <alan@redhat.com> + * + * Previous driver (pre-XFree86 v4.0) by + * Annius V. Groenink (A.V.Groenink@zfc.nl, avg@cwi.nl), + * Dirk H. Hohndel (hohndel@suse.de), + * Portions: the GGI project & confidential CYRIX databooks. + */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/cyrix/cyrix_helper.c,v 1.4 2002/11/06 11:38:59 alanh Exp $ */ + +#include "cyrix.h" +#include "vgaHW.h" +#include "xf86_ansic.h" +#include "compiler.h" + +#define CYRIXmarkLinesDirty { \ + int k = 0; \ + while (k < 1024) { \ + GX_REG(MC_DR_ADD) = k++; \ + GX_REG(MC_DR_ACC) = 0; \ + } \ + } + +static void CYRIXresetVGA(ScrnInfoPtr pScrn, unsigned long vgaIOBase); + +void Cyrix1bppColorMap(ScrnInfoPtr pScrn) +{ /* use dedicated color map routines on new chipsets in 8bpp */ + ErrorF("%s: Cyrix 1BPP is only a stub for now.\n", X_PROBED); + return; +} + + +int CyrixHWCursor(ScreenPtr pScreen) +{ + return 1024; +} + +void CyrixRestore(ScrnInfoPtr pScrn, CYRIXRegPtr cyrixReg) +{ + unsigned char temp; + CYRIXPrvPtr pCyrix; + vgaHWPtr hwp; + vgaRegPtr vgaReg; + unsigned long vgaIOBase; + + vgaHWProtect(pScrn, TRUE); /* Blank the screen */ + pCyrix = CYRIXPTR(pScrn); +/* vgaReg = &VGAHWPTR(pScrn)->SavedReg; */ + hwp = VGAHWPTR(pScrn); + vgaHWUnlock(hwp); + vgaReg = &hwp->ModeReg; + + vgaIOBase = VGAHWPTR(pScrn)->IOBase; + + /* restore standard VGA portion */ + outb(vgaIOBase + 4, CrtcModeSwitchControl); + outb(vgaIOBase + 5, 0x01); + CYRIXresetVGA(pScrn,vgaIOBase); + vgaHWRestore(pScrn, vgaReg, VGA_SR_ALL); + + vgaHWProtect(pScrn, TRUE); /* Blank the screen */ + + CYRIXmarkLinesDirty; + + /* restore miscellaneous output registers */ + outb(0x3C2, vgaReg->MiscOutReg); + + /* restore SoftVGA extended registers */ + outb(vgaIOBase + 4, CrtcDriverControl); + temp = inb(vgaIOBase + 5); + outb(vgaIOBase + 5, (pCyrix->PrevExt.DriverControl & 0x01) + | (temp & 0xfe)); + + outb(vgaIOBase + 4, CrtcVerticalTimingExtension); + temp = inb(vgaIOBase + 5); + outb(vgaIOBase + 5, (pCyrix->PrevExt.VerticalTimingExtension & 0x55) + | (temp & 0xaa)); + + outb(vgaIOBase + 4, CrtcExtendedAddressControl); + temp = inb(vgaIOBase + 5); + outb(vgaIOBase + 5, (pCyrix->PrevExt.ExtendedAddressControl & 0x07) + | (temp & 0xf8)); + + outb(vgaIOBase + 4, 19); + outb(vgaIOBase + 5, pCyrix->PrevExt.Offset); + + outb(vgaIOBase + 4, CrtcExtendedOffset); + temp = inb(vgaIOBase + 5); + outb(vgaIOBase + 5, ((pCyrix->PrevExt.ExtendedOffset) & 0x03) + | (temp & 0xfc)); + + outb(vgaIOBase + 4, CrtcExtendedColorControl); + temp = inb(vgaIOBase + 5); + outb(vgaIOBase + 5, (pCyrix->PrevExt.ExtendedColorControl & 0x07) + | (temp & 0xf8)); + + outb(vgaIOBase + 4, CrtcDisplayCompression); + temp = inb(vgaIOBase + 5); + outb(vgaIOBase + 5, (pCyrix->PrevExt.DisplayCompression & 0x0f) + | (temp & 0xf0)); + + outb(vgaIOBase + 4, CrtcDACControl); + temp = inb(vgaIOBase + 5); + outb(vgaIOBase + 5, (pCyrix->PrevExt.DACControl & 0x0e) + | (temp & 0xf1)); + + outb(vgaIOBase + 4, CrtcModeSwitchControl); + outb(vgaIOBase + 5, 0x00); + + /* let SoftVGA programming settle before we access DC registers, + but don't wait too long */ + usleep(1000); + CYRIXmarkLinesDirty; + + /* restore display controller hardware registers */ +#ifndef MONOVGA +#define DCFG_MASK (DC_GCFG_FDTY | DC_GCFG_DECE | DC_GCFG_CMPE | DC_GCFG_FBLC | DC_GCFG_CURE) +#define GPBS_MASK (BC_16BPP | BC_FB_WIDTH_2048) + + GX_REG(DC_UNLOCK) = DC_UNLOCK_VALUE; + + GX_REG(DC_CURS_ST_OFFSET) = pCyrix->PrevExt.DcCursStOffset; + GX_REG(DC_CB_ST_OFFSET) = pCyrix->PrevExt.DcCbStOffset; + GX_REG(DC_LINE_DELTA) = (GX_REG(DC_LINE_DELTA) & 0xFFC00FFF) + | (pCyrix->PrevExt.DcLineDelta & 0x003FF000); + GX_REG(DC_BUF_SIZE) = (GX_REG(DC_BUF_SIZE) & 0xFFFF01FF) + | (pCyrix->PrevExt.DcBufSize & 0x0000FE00); + GX_REG(DC_CURSOR_X) = pCyrix->PrevExt.DcCursorX; + GX_REG(DC_CURSOR_Y) = pCyrix->PrevExt.DcCursorY; + GX_REG(DC_CURSOR_COLOR) = pCyrix->PrevExt.DcCursorColor; + + GX_REG(DC_GENERAL_CFG) = (GX_REG(DC_GENERAL_CFG) & (~DCFG_MASK)) + | (pCyrix->PrevExt.DcGeneralCfg & DCFG_MASK); + + GX_REG(DC_UNLOCK) = 0; + + GX_REG(GP_BLIT_STATUS) = (GX_REG(GP_BLIT_STATUS) & (~GPBS_MASK)) + | (pCyrix->PrevExt.GpBlitStatus & GPBS_MASK); + +#endif + + vgaHWProtect(pScrn, FALSE); /* Turn on screen */ +} + +void * +CyrixSave(ScrnInfoPtr pScrn, CYRIXRegPtr cyrixReg) +{ + CYRIXPrvPtr pCyrix; + vgaRegPtr vgaReg; + unsigned long vgaIOBase; + +#ifndef MONOVGA + /* If we don't turn on the screen we end up restoring a + blanked display on some boxes whose APM is a bit too smart. + Save the display turned -on- therefore */ + + vgaHWProtect(pScrn, FALSE); /* Turn on screen */ + + /* save graphics pipeline registers */ + pCyrix = CYRIXPTR(pScrn); + vgaIOBase = VGAHWPTR(pScrn)->IOBase; + vgaReg = &VGAHWPTR(pScrn)->SavedReg; + pCyrix->PrevExt.GpBlitStatus = GX_REG(GP_BLIT_STATUS); + + /* save miscellaneous output registers */ + vgaReg->MiscOutReg = inb(0x3CC); + + /* save graphics pipeline registers */ + GX_REG(DC_UNLOCK) = DC_UNLOCK_VALUE; + pCyrix->PrevExt.DcGeneralCfg = GX_REG(DC_GENERAL_CFG); + pCyrix->PrevExt.DcCursStOffset = GX_REG(DC_CURS_ST_OFFSET); + pCyrix->PrevExt.DcCbStOffset = GX_REG(DC_CB_ST_OFFSET); + pCyrix->PrevExt.DcLineDelta = GX_REG(DC_LINE_DELTA); + pCyrix->PrevExt.DcBufSize = GX_REG(DC_BUF_SIZE); + pCyrix->PrevExt.DcCursorX = GX_REG(DC_CURSOR_X); + pCyrix->PrevExt.DcCursorY = GX_REG(DC_CURSOR_Y); + pCyrix->PrevExt.DcCursorColor = GX_REG(DC_CURSOR_COLOR); + GX_REG(DC_UNLOCK) = 0; + +#endif + + /* save SoftVGA pCyrix->PrevExt.nded registers */ + outb(vgaIOBase + 4, CrtcVerticalTimingExtension); + pCyrix->PrevExt.VerticalTimingExtension = inb(vgaIOBase + 5); + + outb(vgaIOBase + 4, CrtcExtendedAddressControl); + pCyrix->PrevExt.ExtendedAddressControl = inb(vgaIOBase + 5); + + outb(vgaIOBase + 4, 19); + pCyrix->PrevExt.Offset = inb(vgaIOBase + 5); + + outb(vgaIOBase + 4, CrtcExtendedOffset); + pCyrix->PrevExt.ExtendedOffset = inb(vgaIOBase + 5); + + outb(vgaIOBase + 4, CrtcExtendedColorControl); + pCyrix->PrevExt.ExtendedColorControl = inb(vgaIOBase + 5); + + outb(vgaIOBase + 4, CrtcDisplayCompression); + pCyrix->PrevExt.DisplayCompression = inb(vgaIOBase + 5); + + outb(vgaIOBase + 4, CrtcDriverControl); + pCyrix->PrevExt.DriverControl = inb(vgaIOBase + 5); + + outb(vgaIOBase + 4, CrtcDACControl); + pCyrix->PrevExt.DACControl = inb(vgaIOBase + 5); + + outb(vgaIOBase + 4, CrtcClockControl); + pCyrix->PrevExt.ClockControl = inb(vgaIOBase + 5); + + outb(vgaIOBase + 4, CrtcClockFrequency); + pCyrix->PrevExt.CrtClockFrequency = inb(vgaIOBase + 5); + + outb(vgaIOBase + 4, CrtcClockFrequencyFraction); + pCyrix->PrevExt.CrtClockFrequencyFraction = inb(vgaIOBase + 5); + + outb(vgaIOBase + 4, CrtcRefreshRate); + pCyrix->PrevExt.RefreshRate = inb(vgaIOBase + 5); + + /* save standard VGA portion */ + CYRIXresetVGA(pScrn,vgaIOBase); + + return((void *)vgaIOBase); +} + + +Bool +CyrixInit(ScrnInfoPtr pScrn, DisplayModePtr mode) +{ + CYRIXPrvPtr pCyrix; + int offset_shift = (pScrn->bitsPerPixel == 16) ? 2 : + (pScrn->bitsPerPixel == 8) ? 3 : 4; + int line_offset = pScrn->displayWidth >> offset_shift; + + pCyrix = CYRIXPTR(pScrn); + + /* initialize standard VGA portion */ + if (!vgaHWInit(pScrn, mode)) + return(FALSE); + + /* initialize SoftVGA extended registers */ + pCyrix->PrevExt.VerticalTimingExtension = + ((mode->CrtcVSyncStart & 0x400) >> 4) | + (((mode->CrtcVDisplay - 1) & 0x400) >> 8) | + (((mode->CrtcVTotal - 2) & 0x400) >> 10) | + ((mode->CrtcVSyncStart & 0x400) >> 6); + + if (pScrn->bitsPerPixel < 8) + pCyrix->PrevExt.ExtendedAddressControl = EAC_DIRECT_FRAME_BUFFER; + else + pCyrix->PrevExt.ExtendedAddressControl = EAC_DIRECT_FRAME_BUFFER | + EAC_PACKED_CHAIN4; + + pCyrix->PrevExt.ExtendedOffset = ((line_offset >> 8) & 0x03); + pCyrix->PrevExt.Offset = line_offset; + + pCyrix->PrevExt.ExtendedColorControl = (pScrn->bitsPerPixel == 16) + ? ECC_16BPP | ECC_565_FORMAT + : ECC_8BPP; + + /* display compression is set using the DC registers */ + pCyrix->PrevExt.DisplayCompression = 0x00; + + /* we drive the palette through the display controller (in new + chipsets only) in 8bpp and 16bpp (that is, whenever the + hardware cursor is used). */ + if (pScrn->bitsPerPixel < 8) + pCyrix->PrevExt.DriverControl = 0x00; + else + pCyrix->PrevExt.DriverControl = DRVCT_DISPLAY_DRIVER_ACTIVE; + + /* set `16 bit bus' or else compression will hang the + system in 16bpp mode */ + if (pScrn->bitsPerPixel == 16) + pCyrix->PrevExt.DACControl = DACCT_ENABLE_16BIT_BUS; + else + pCyrix->PrevExt.DACControl = 0; + + +#ifndef MONOVGA + /* initialize masked contents of display controller + hardware registers. */ + pCyrix->PrevExt.DcCursStOffset = pCyrix->CYRIXcursorAddress; + pCyrix->PrevExt.DcLineDelta = 0 << 12; + pCyrix->PrevExt.DcBufSize = 0x41 << 9; + pCyrix->PrevExt.DcCursorX = 0; + pCyrix->PrevExt.DcCursorY = 0; + pCyrix->PrevExt.DcCursorColor = 0; + + /* Compression is enabled only when a buffer was allocated by + FbInit and provided that the displayed screen is the virtual + screen. If the line delta is not 1024 or 2048, entire frames + will be flagged dirty as opposed to lines. Problems with 16bpp + and line-dirty flagging seem to have been solved now. */ + + if (pCyrix->NoCompress == FALSE && + mode->CrtcVDisplay == pScrn->virtualY && + mode->CrtcHDisplay == pScrn->virtualX && + 0 == GX_REG(DC_FB_ST_OFFSET)) + { + pCyrix->PrevExt.DcGeneralCfg = DC_GCFG_DECE | DC_GCFG_CMPE; + if (/* pScrn->bitsPerPixel != 8 || -- this is OK now */ + (pScrn->displayWidth * (pScrn->bitsPerPixel / 8)) & 0x03FF) + pCyrix->PrevExt.DcGeneralCfg |= DC_GCFG_FDTY; + } + else + pCyrix->PrevExt.DcGeneralCfg = 0; + + + /* initialize the graphics pipeline registers */ + pCyrix->PrevExt.GpBlitStatus = ((pScrn->displayWidth == 2048) ? + BC_FB_WIDTH_2048 : BC_FB_WIDTH_1024) | + ((pScrn->bitsPerPixel == 16) ? + BC_16BPP : BC_8BPP); +#endif + + return(TRUE); +} + + +static void +CYRIXresetVGA(ScrnInfoPtr pScrn, unsigned long vgaIOBase) +{ + CYRIXPrvPtr pCyrix = CYRIXPTR(pScrn); + unsigned char temp; + /* switch off compression and cursor the hard way */ + GX_REG(DC_UNLOCK) = DC_UNLOCK_VALUE; + GX_REG(DC_GENERAL_CFG) &= ~(DC_GCFG_CMPE | DC_GCFG_DECE | DC_GCFG_FDTY | DC_GCFG_CURE); + GX_REG(DC_UNLOCK) = 0; + CYRIXmarkLinesDirty; + + /* reset SoftVGA extensions to standard VGA behaviour */ + outb(vgaIOBase + 4, CrtcExtendedAddressControl); + temp = inb(vgaIOBase + 5); + outb(vgaIOBase + 5, temp & 0xf8); + outb(vgaIOBase + 4, CrtcExtendedStartAddress); + outb(vgaIOBase + 5, 0x00); + outb(vgaIOBase + 4, CrtcWriteMemoryAperture); + temp = inb(vgaIOBase + 5); + outb(vgaIOBase + 5, temp & 0xe0); + outb(vgaIOBase + 4, CrtcReadMemoryAperture); + temp = inb(vgaIOBase + 5); + outb(vgaIOBase + 5, temp & 0xe0); + outb(vgaIOBase + 4, CrtcDriverControl); + temp = inb(vgaIOBase + 5); + outb(vgaIOBase + 5, temp & 0xfe); + outb(vgaIOBase + 4, CrtcDisplayCompression); + temp = inb(vgaIOBase + 5); + outb(vgaIOBase + 5, temp & 0xf0); +} diff --git a/src/cyrix_shadow.c b/src/cyrix_shadow.c new file mode 100644 index 0000000..479ad36 --- /dev/null +++ b/src/cyrix_shadow.c @@ -0,0 +1,155 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/cyrix/cyrix_shadow.c,v 1.1 2002/11/06 11:38:59 alanh Exp $ */ + +/* + Copyright (c) 1999, The XFree86 Project Inc. + Written by Mark Vojkovich <markv@valinux.com> +*/ + +#include "xf86.h" +#include "xf86_OSproc.h" +#include "xf86Resources.h" +#include "xf86_ansic.h" +#include "xf86PciInfo.h" +#include "xf86Pci.h" +#include "cyrix.h" +#include "shadowfb.h" +#include "servermd.h" + + + +void +CYRIXRefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox) +{ + CYRIXPrvPtr pCyrix = CYRIXPTR(pScrn); + int width, height, Bpp, FBPitch; + unsigned char *src, *dst; + + Bpp = pScrn->bitsPerPixel >> 3; + FBPitch = BitmapBytePad(pScrn->displayWidth * pScrn->bitsPerPixel); + + while(num--) { + width = (pbox->x2 - pbox->x1) * Bpp; + height = pbox->y2 - pbox->y1; + src = pCyrix->ShadowPtr + (pbox->y1 * pCyrix->ShadowPitch) + + (pbox->x1 * Bpp); + dst = pCyrix->FbBase + (pbox->y1 * FBPitch) + (pbox->x1 * Bpp); + + while(height--) { + memcpy(dst, src, width); + dst += FBPitch; + src += pCyrix->ShadowPitch; + } + + pbox++; + } +} + +void +CYRIXPointerMoved(int index, int x, int y) +{ + ScrnInfoPtr pScrn = xf86Screens[index]; + CYRIXPrvPtr pCyrix = CYRIXPTR(pScrn); + int newX, newY; + + if(pCyrix->Rotate == 1) { + newX = pScrn->pScreen->height - y - 1; + newY = x; + } else { + newX = y; + newY = pScrn->pScreen->width - x - 1; + } + + (*pCyrix->PointerMoved)(index, newX, newY); +} + +void +CYRIXRefreshArea8(ScrnInfoPtr pScrn, int num, BoxPtr pbox) +{ + CYRIXPrvPtr pCyrix = CYRIXPTR(pScrn); + int count, width, height, y1, y2, dstPitch, srcPitch; + CARD8 *dstPtr, *srcPtr, *src; + CARD32 *dst; + + dstPitch = pScrn->displayWidth; + srcPitch = -pCyrix->Rotate * pCyrix->ShadowPitch; + + while(num--) { + width = pbox->x2 - pbox->x1; + y1 = pbox->y1 & ~3; + y2 = (pbox->y2 + 3) & ~3; + height = (y2 - y1) >> 2; /* in dwords */ + + if(pCyrix->Rotate == 1) { + dstPtr = pCyrix->FbBase + + (pbox->x1 * dstPitch) + pScrn->virtualX - y2; + srcPtr = pCyrix->ShadowPtr + ((1 - y2) * srcPitch) + pbox->x1; + } else { + dstPtr = pCyrix->FbBase + + ((pScrn->virtualY - pbox->x2) * dstPitch) + y1; + srcPtr = pCyrix->ShadowPtr + (y1 * srcPitch) + pbox->x2 - 1; + } + + while(width--) { + src = srcPtr; + dst = (CARD32*)dstPtr; + count = height; + while(count--) { + *(dst++) = src[0] | (src[srcPitch] << 8) | + (src[srcPitch * 2] << 16) | + (src[srcPitch * 3] << 24); + src += srcPitch * 4; + } + srcPtr += pCyrix->Rotate; + dstPtr += dstPitch; + } + + pbox++; + } +} + + +void +CYRIXRefreshArea16(ScrnInfoPtr pScrn, int num, BoxPtr pbox) +{ + CYRIXPrvPtr pCyrix = CYRIXPTR(pScrn); + int count, width, height, y1, y2, dstPitch, srcPitch; + CARD16 *dstPtr, *srcPtr, *src; + CARD32 *dst; + + dstPitch = pScrn->displayWidth; + srcPitch = -pCyrix->Rotate * pCyrix->ShadowPitch >> 1; + + while(num--) { + width = pbox->x2 - pbox->x1; + y1 = pbox->y1 & ~1; + y2 = (pbox->y2 + 1) & ~1; + height = (y2 - y1) >> 1; /* in dwords */ + + if(pCyrix->Rotate == 1) { + dstPtr = (CARD16*)pCyrix->FbBase + + (pbox->x1 * dstPitch) + pScrn->virtualX - y2; + srcPtr = (CARD16*)pCyrix->ShadowPtr + + ((1 - y2) * srcPitch) + pbox->x1; + } else { + dstPtr = (CARD16*)pCyrix->FbBase + + ((pScrn->virtualY - pbox->x2) * dstPitch) + y1; + srcPtr = (CARD16*)pCyrix->ShadowPtr + + (y1 * srcPitch) + pbox->x2 - 1; + } + + while(width--) { + src = srcPtr; + dst = (CARD32*)dstPtr; + count = height; + while(count--) { + *(dst++) = src[0] | (src[srcPitch] << 16); + src += srcPitch * 2; + } + srcPtr += pCyrix->Rotate; + dstPtr += dstPitch; + } + + pbox++; + } +} + |