diff options
Diffstat (limited to 'xc/programs/Xserver/hw/xfree86/drivers/neomagic')
12 files changed, 1899 insertions, 778 deletions
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/neomagic/README b/xc/programs/Xserver/hw/xfree86/drivers/neomagic/README index 059be1857..3d7f20016 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/neomagic/README +++ b/xc/programs/Xserver/hw/xfree86/drivers/neomagic/README @@ -134,7 +134,7 @@ The original version of the driver - written for Xfree86 3.3 - done by: - Jens Owen (jens@precisioninsight.com) + Jens Owen (jens@tungstengraphics.com) Kevin E. Martin (kevin@precisioninsight.com) Precision Insight, Inc. diff --git a/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo.h b/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo.h index 34047d90d..6ff546901 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo.h +++ b/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo.h @@ -22,37 +22,49 @@ 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. **********************************************************************/ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo.h,v 1.4 1999/06/27 14:08:08 dawes Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo.h,v 1.22 2002/09/16 18:05:57 eich Exp $ */ /* * The original Precision Insight driver for * XFree86 v.3.3 has been sponsored by Red Hat. * * Authors: - * Jens Owen (jens@precisioninsight.com) + * Jens Owen (jens@tungstengraphics.com) * Kevin E. Martin (kevin@precisioninsight.com) * * Port to Xfree86 v.4.0 * 1998, 1999 by Egbert Eich (Egbert.Eich@Physik.TU-Darmstadt.DE) */ -/* Everything using inb/outb, etc needs "compiler.h" */ -#include "compiler.h" - /* 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" + #include "xaa.h" #include "xaalocal.h" /* XAA internals as we replace some of XAA */ #include "xf86Cursor.h" +#include "shadowfb.h" + +#include "vbe.h" + +/* Needed by the Shadow Framebuffer */ +#include "shadow.h" + /* Drivers that need to access the PCI config space directly need this */ #include "xf86Pci.h" #include "xf86i2c.h" +#ifdef XvExtension +# include "xf86xv.h" +# include "Xv.h" +#endif /* XvExtension */ + /* * Driver data structures. */ @@ -66,11 +78,17 @@ typedef enum { NM2093, NM2097, NM2160, - NM2200 + NM2200, + NM2230, + NM2360, + NM2380 } NEOType; /* function prototypes */ +extern Bool NEOSwitchMode(int scrnIndex, DisplayModePtr mode, int flags); +extern void NEOAdjustFrame(int scrnIndex, int x, int y, int flags); + /* in neo_2070.c */ extern Bool Neo2070AccelInit(ScreenPtr pScreen); @@ -96,6 +114,22 @@ int NEOSetRead(ScreenPtr pScreen, int bank); /* in neo_i2c.c */ extern Bool neo_I2CInit(ScrnInfoPtr pScrn); +/* in neo_shadow.c */ +void neoShadowUpdate (ScreenPtr pScreen, shadowBufPtr pBuf); +void neoPointerMoved(int index, int x, int y); +void neoRefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox); +void neoRefreshArea8(ScrnInfoPtr pScrn, int num, BoxPtr pbox); +void neoRefreshArea16(ScrnInfoPtr pScrn, int num, BoxPtr pbox); +void neoRefreshArea24(ScrnInfoPtr pScrn, int num, BoxPtr pbox); +void neoRefreshArea32(ScrnInfoPtr pScrn, int num, BoxPtr pbox); + +/* in neo_dga.c */ +Bool NEODGAInit(ScreenPtr pScreen); + +/* in neo_video.c */ +extern void NEOInitVideo(ScreenPtr pScreen); +extern void NEOResetVideo(ScrnInfoPtr pScrn); + /* shadow regs */ #define NEO_EXT_CR_MAX 0x85 @@ -115,6 +149,7 @@ typedef struct { unsigned char ExtColorModeSelect; unsigned char SingleAddrPage; unsigned char DualAddrPage; + unsigned char biosMode; unsigned char PanelDispCntlReg1; unsigned char PanelDispCntlReg2; unsigned char PanelDispCntlReg3; @@ -128,6 +163,7 @@ typedef struct { unsigned char PanelHorizCenterReg3; unsigned char PanelHorizCenterReg4; unsigned char PanelHorizCenterReg5; + unsigned char Sequencer1; Bool ProgramVCLK; unsigned char VCLK3NumeratorLow; unsigned char VCLK3NumeratorHigh; @@ -140,6 +176,8 @@ typedef struct { /* Hardware cursor address */ unsigned int CursorAddress; Bool UseHWCursor; + Bool NoCursorMode; + unsigned char CursTemp[1024]; /* Boundaries of the pixmap cache */ unsigned int cacheStart; unsigned int cacheEnd; @@ -151,6 +189,11 @@ typedef struct { unsigned int Pitch; unsigned int PixelWidth; unsigned int PlaneMask; + int CPUToScreenColorExpandFill_x; + int CPUToScreenColorExpandFill_y; + int CPUToScreenColorExpandFill_w; + int CPUToScreenColorExpandFill_h; + int CPUToScreenColorExpandFill_skipleft; } NEOACLRec, *NEOACLPtr; #define NEOACLPTR(p) &((NEOPtr)((p)->driverPrivate))->Accel @@ -163,12 +206,18 @@ typedef struct neoRec EntityInfoPtr pEnt; XAAInfoRecPtr AccelInfoRec; NEOACLRec Accel; - unsigned int NeoMMIOAddr; - unsigned int NeoLinearAddr; + unsigned long NeoMMIOAddr; + unsigned long NeoLinearAddr; unsigned char* NeoMMIOBase; + unsigned long NeoMMIOAddr2; + unsigned char* NeoMMIOBase2; unsigned char* NeoFbBase; long NeoFbMapSize; - unsigned int vgaIOBase; + unsigned long vgaIOBase; + DGAModePtr DGAModes; + int numDGAModes; + Bool DGAactive; + int DGAViewportStatus; /* ??? */ int NeoFifoCount; /* cursor */ @@ -187,6 +236,7 @@ typedef struct neoRec OptionInfoPtr Options; Bool noLinear; Bool noAccel; + Bool noAccelSet; Bool swCursor; Bool noMMIO; Bool internDisp; @@ -197,18 +247,40 @@ typedef struct neoRec Bool onPciBurst; Bool progLcdRegs; Bool progLcdStretch; - Bool progLcdStrechOpt; + Bool progLcdStretchOpt; Bool overrideValidate; + Bool strangeLockups; /* registers */ NeoRegRec NeoModeReg; NeoRegRec NeoSavedReg; /* proc pointer */ CloseScreenProcPtr CloseScreen; I2CBusPtr I2C; + vbeInfoPtr pVbe; unsigned char * ShadowPtr; int ShadowPitch; + RefreshAreaFuncPtr refreshArea; + void (*PointerMoved)(int index, int x, int y); + int rotate; + Bool showcache; +#ifdef XvExtension + Bool video; + double videoHZoom; + double videoVZoom; + XF86VideoAdaptorPtr overlayAdaptor; + int overlay; + int overlay_offset; + int videoKey; + int interlace; +#endif /* XvExtension */ } NEORec, *NEOPtr; +typedef struct { + int x_res; + int y_res; + int mode; +} biosMode; + /* The privates of the NEO driver */ #define NEOPTR(p) ((NEOPtr)((p)->driverPrivate)) @@ -216,18 +288,20 @@ typedef struct neoRec #define GRAX 0x3CE /* vga IO functions */ -#define VGArCR(index) hwp->readCrtc(hwp,index) -#define VGAwCR(index,val) hwp->writeCrtc(hwp,index,val) -#define VGArGR(index) hwp->readGr(hwp,index) -#define VGAwGR(index,val) hwp->writeGr(hwp,index,val) +#define VGArCR(index) (*hwp->readCrtc)(hwp, index) +#define VGAwCR(index, val) (*hwp->writeCrtc)(hwp, index, val) +#define VGArGR(index) (*hwp->readGr)(hwp, index) +#define VGAwGR(index, val) (*hwp->writeGr)(hwp, index, val) +#define VGArSR(index) (*hwp->readSeq)(hwp, index) +#define VGAwSR(index, val) (*hwp->writeSeq)(hwp, index, val) /* memory mapped register access macros */ -#define INREG8(addr) *(volatile CARD8 *)(nPtr->NeoMMIOBase + (addr)) -#define INREG16(addr) *(volatile CARD16 *)(nPtr->NeoMMIOBase + (addr)) -#define INREG(addr) *(volatile CARD32 *)(nPtr->NeoMMIOBase + (addr)) -#define OUTREG8(addr, val) *(volatile CARD8 *)(nPtr->NeoMMIOBase + (addr)) = (val) -#define OUTREG16(addr, val) *(volatile CARD16 *)(nPtr->NeoMMIOBase + (addr)) = (val) -#define OUTREG(addr, val) *(volatile CARD32 *)(nPtr->NeoMMIOBase + (addr)) = (val) +#define INREG8(addr) MMIO_IN8(nPtr->NeoMMIOBase, addr) +#define INREG16(addr) MMIO_IN16(nPtr->NeoMMIOBase, addr) +#define INREG(addr) MMIO_IN32(nPtr->NeoMMIOBase, addr) +#define OUTREG8(addr, val) MMIO_OUT8(nPtr->NeoMMIOBase, addr, val) +#define OUTREG16(addr, val) MMIO_OUT16(nPtr->NeoMMIOBase, addr, val) +#define OUTREG(addr, val) MMIO_OUT32(nPtr->NeoMMIOBase, addr, val) /* This swizzle macro is to support the manipulation of cursor masks when * the sprite moves off the left edge of the display. This code is diff --git a/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_2070.c b/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_2070.c index 47584537c..a67b891ee 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_2070.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_2070.c @@ -22,14 +22,14 @@ 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. **********************************************************************/ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_2070.c,v 1.2 1999/06/27 14:08:08 dawes Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_2070.c,v 1.4 2002/04/04 14:05:44 eich Exp $ */ /* * The original Precision Insight driver for * XFree86 v.3.3 has been sponsored by Red Hat. * * Authors: - * Jens Owen (jens@precisioninsight.com) + * Jens Owen (jens@tungstengraphics.com) * Kevin E. Martin (kevin@precisioninsight.com) * * Port to Xfree86 v.4.0 @@ -104,7 +104,6 @@ Neo2070AccelInit(ScreenPtr pScreen) ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; NEOPtr nPtr = NEOPTR(pScrn); NEOACLPtr nAcl = NEOACLPTR(pScrn); - BoxRec AvailFBArea; nPtr->AccelInfoRec = infoPtr = XAACreateInfoRec(); if(!infoPtr) return FALSE; @@ -112,8 +111,8 @@ Neo2070AccelInit(ScreenPtr pScreen) /* * Set up the main acceleration flags. */ - infoPtr->Flags |= LINEAR_FRAMEBUFFER | OFFSCREEN_PIXMAPS; - if(nAcl->cacheEnd > nAcl->cacheStart) infoPtr->Flags = PIXMAP_CACHE; + infoPtr->Flags = LINEAR_FRAMEBUFFER | OFFSCREEN_PIXMAPS; + if(nAcl->cacheEnd > nAcl->cacheStart) infoPtr->Flags |= PIXMAP_CACHE; #if 0 infoPtr->PixmapCacheFlags |= DO_NOT_BLIT_STIPPLES; #endif @@ -157,17 +156,7 @@ Neo2070AccelInit(ScreenPtr pScreen) default: return FALSE; } - - /* Initialize for widths */ - nAcl->Pitch = pScrn->displayWidth * nAcl->PixelWidth; - - AvailFBArea.x1 = 0; - AvailFBArea.y1 = 0; - AvailFBArea.x2 = pScrn->displayWidth; - AvailFBArea.y2 = nAcl->cacheEnd / - (pScrn->displayWidth * (pScrn->bitsPerPixel >> 3)); - xf86InitFBManager(pScreen, &AvailFBArea); - + return(XAAInit(pScreen, infoPtr)); } diff --git a/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_2090.c b/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_2090.c index d9f311504..2b757576a 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_2090.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_2090.c @@ -22,14 +22,14 @@ 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. **********************************************************************/ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_2090.c,v 1.2 1999/06/27 14:08:08 dawes Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_2090.c,v 1.6 2002/04/04 14:05:44 eich Exp $ */ /* * The original Precision Insight driver for * XFree86 v.3.3 has been sponsored by Red Hat. * * Authors: - * Jens Owen (jens@precisioninsight.com) + * Jens Owen (jens@tungstengraphics.com) * Kevin E. Martin (kevin@precisioninsight.com) * * Port to Xfree86 v.4.0 @@ -40,6 +40,7 @@ CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include "xf86_OSproc.h" #include "xf86_ansic.h" #include "compiler.h" +#include "xf86PciInfo.h" /* Drivers that use XAA need this */ #include "xf86fbman.h" @@ -81,16 +82,17 @@ static void Neo2090SetupForSolidFillRect(ScrnInfoPtr pScrn, int color, int rop, unsigned int planemask); static void Neo2090SubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y, int w, int h); -#ifdef colorexpandfill -static void Neo2090SetupForCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, +static void Neo2093SetupForScanlineCPUToScreenColorExpandFill( + ScrnInfoPtr pScrn, int fg, int bg, int rop, unsigned int planemask); -static void Neo2093SubsequentCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, +static void Neo2093SubsequentScanlineCPUToScreenColorExpandFill( + ScrnInfoPtr pScrn, int x, int y, int w, int h, int skipleft); -#endif +static void Neo2093SubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno); Bool Neo2090AccelInit(ScreenPtr pScreen) @@ -99,7 +101,6 @@ Neo2090AccelInit(ScreenPtr pScreen) ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; NEOPtr nPtr = NEOPTR(pScrn); NEOACLPtr nAcl = NEOACLPTR(pScrn); - BoxRec AvailFBArea; nPtr->AccelInfoRec = infoPtr = XAACreateInfoRec(); if(!infoPtr) return FALSE; @@ -107,8 +108,8 @@ Neo2090AccelInit(ScreenPtr pScreen) /* * Set up the main acceleration flags. */ - infoPtr->Flags |= LINEAR_FRAMEBUFFER | OFFSCREEN_PIXMAPS; - if(nAcl->cacheEnd > nAcl->cacheStart) infoPtr->Flags = PIXMAP_CACHE; + infoPtr->Flags = LINEAR_FRAMEBUFFER | OFFSCREEN_PIXMAPS; + if(nAcl->cacheEnd > nAcl->cacheStart) infoPtr->Flags |= PIXMAP_CACHE; #if 0 infoPtr->PixmapCacheFlags |= DO_NOT_BLIT_STIPPLES; #endif @@ -128,29 +129,34 @@ Neo2090AccelInit(ScreenPtr pScreen) Neo2090SetupForSolidFillRect; infoPtr->SubsequentSolidFillRect = Neo2090SubsequentSolidFillRect; -#ifdef colorexpandfill - /* We need byte scanline padding before we can use this - * or does anyone know how to switch the chip to dword - * padding? if we could do right edge clipping this would - * help also. Left edge clipping cannot be used since it - * allows only clipping of up to 8 pixels :-(( - */ /*§§§*/ - if (NeoChipset == PCI_CHIP_NM2093) { + + if (nPtr->NeoChipset == PCI_CHIP_NM2093 && !nPtr->strangeLockups) { + /* + * We do CPUToScreenColorExpand (ab)using the Scanline functions: + * the neo chipsets need byte padding however we can only do dword + * padding. Fortunately the graphics engine doesn't choke if we + * transfer up to 3 bytes more than it wants. + */ + /* cpu to screen color expansion */ - infoPtr->CPUToScreenColorExpandFillFlags = ( NO_PLANEMASK | - SCANLINE_PAD_BYTE | - CPU_TRANSFER_PAD_DWORD | - BIT_ORDER_IN_BYTE_MSBFIRST ); - infoPtr->ColorExpandBase = + infoPtr->ScanlineColorExpandBuffers = + (unsigned char **)xnfalloc(sizeof(char*)); + infoPtr->ScanlineColorExpandBuffers[0] = (unsigned char *)(nPtr->NeoMMIOBase + 0x100000); - infoPtr->ColorExpandRange = 0x100000; - - infoPtr->SetupForCPUToScreenColorExpandFill = - Neo2093SetupForCPUToScreenColorExpandFill; - infoPtr->SubsequentCPUToScreenColorExpandFill = - Neo2093SubsequentCPUToScreenColorExpandFill; + infoPtr->NumScanlineColorExpandBuffers = 1; + infoPtr->ScanlineCPUToScreenColorExpandFillFlags = ( NO_PLANEMASK | + SCANLINE_PAD_DWORD | + CPU_TRANSFER_PAD_DWORD | + BIT_ORDER_IN_BYTE_MSBFIRST ); + + infoPtr->SetupForScanlineCPUToScreenColorExpandFill = + Neo2093SetupForScanlineCPUToScreenColorExpandFill; + infoPtr->SubsequentScanlineCPUToScreenColorExpandFill = + Neo2093SubsequentScanlineCPUToScreenColorExpandFill; + infoPtr->SubsequentColorExpandScanline = + Neo2093SubsequentColorExpandScanline; } -#endif + /* * Setup some global variables */ @@ -189,15 +195,7 @@ Neo2090AccelInit(ScreenPtr pScreen) nAcl->BltCntlFlags |= NEO_BC3_FIFO_EN; - AvailFBArea.x1 = 0; - AvailFBArea.y1 = 0; - AvailFBArea.x2 = pScrn->displayWidth; - AvailFBArea.y2 = nAcl->cacheEnd / - (pScrn->displayWidth * (pScrn->bitsPerPixel >> 3)); - xf86InitFBManager(pScreen, &AvailFBArea); - return(XAAInit(pScreen, infoPtr)); - } static void @@ -289,9 +287,9 @@ Neo2090SubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y, int w, int h) } -#ifdef colorexpandfill static void -Neo2093SetupForCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, int fg, int bg, +Neo2093SetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, + int fg, int bg, int rop, unsigned int planemask) { @@ -325,19 +323,44 @@ Neo2093SetupForCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, int fg, int bg, } static void -Neo2093SubsequentCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, +Neo2093SubsequentScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, int x, int y, int w, int h, int skipleft) { NEOPtr nPtr = NEOPTR(pScrn); + NEOACLPtr nAcl = NEOACLPTR(pScrn); + + nAcl->CPUToScreenColorExpandFill_x = x; + nAcl->CPUToScreenColorExpandFill_y = y; + nAcl->CPUToScreenColorExpandFill_w = w; + nAcl->CPUToScreenColorExpandFill_h = h; + nAcl->CPUToScreenColorExpandFill_skipleft = skipleft; WAIT_FIFO(4); OUTREG(NEOREG_SRCBITOFF, skipleft); OUTREG(NEOREG_SRCSTARTOFF, 0); OUTREG(NEOREG_DSTSTARTOFF, (y<<16) | (x & 0xffff)); - OUTREG(NEOREG_XYEXT, (h<<16) | (w & 0xffff)); + OUTREG(NEOREG_XYEXT, (1<<16) | (w & 0xffff)); } -#endif + +static void +Neo2093SubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno) +{ + NEOPtr nPtr = NEOPTR(pScrn); + NEOACLPtr nAcl = NEOACLPTR(pScrn); + + if (!(--nAcl->CPUToScreenColorExpandFill_h)) + return; + + WAIT_FIFO(4); + OUTREG(NEOREG_SRCBITOFF, nAcl->CPUToScreenColorExpandFill_skipleft); + OUTREG(NEOREG_SRCSTARTOFF, 0); + OUTREG(NEOREG_DSTSTARTOFF, ((++nAcl->CPUToScreenColorExpandFill_y)<<16) + | (nAcl->CPUToScreenColorExpandFill_x & 0xffff)); + OUTREG(NEOREG_XYEXT, (1<<16) + | (nAcl->CPUToScreenColorExpandFill_w & 0xffff)); +} + diff --git a/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_2097.c b/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_2097.c index 563e720b5..d95be89f5 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_2097.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_2097.c @@ -22,14 +22,14 @@ 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. **********************************************************************/ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_2097.c,v 1.2 1999/06/27 14:08:08 dawes Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_2097.c,v 1.10 2002/10/08 22:14:09 tsi Exp $ */ /* * The original Precision Insight driver for * XFree86 v.3.3 has been sponsored by Red Hat. * * Authors: - * Jens Owen (jens@precisioninsight.com) + * Jens Owen (jens@tungstengraphics.com) * Kevin E. Martin (kevin@precisioninsight.com) * * Port to Xfree86 v.4.0 @@ -66,16 +66,18 @@ static void Neo2097SetupForSolidFillRect(ScrnInfoPtr pScrn, int color, int rop, unsigned int planemask); static void Neo2097SubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y, int w, int h); -#ifdef colorexpandfill -static void Neo2097SetupForCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, +static void Neo2097SetupScanlineForCPUToScreenColorExpandFill( + ScrnInfoPtr pScrn, int fg, int bg, int rop, unsigned int planemask); -static void Neo2097SubsequentCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, +static void Neo2097SubsequentScanlineCPUToScreenColorExpandFill( + ScrnInfoPtr pScrn, int x, int y, int w, int h, int skipleft); -#endif +static void Neo2097SubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno); +#if 0 static void Neo2097SetupForMono8x8PatternFill(ScrnInfoPtr pScrn, int patternx, int patterny, @@ -86,6 +88,13 @@ static void Neo2097SubsequentMono8x8PatternFill(ScrnInfoPtr pScrn, int patterny, int x, int y, int w, int h); +#endif +static void Neo2097SetupForScanlineImageWrite(ScrnInfoPtr pScrn, int rop, + unsigned int planemask, + int transparency_color, int bpp, int depth); +static void Neo2097SubsequentScanlineImageWriteRect(ScrnInfoPtr pScrn, + int x, int y, int w, int h, int skipleft); +static void Neo2097SubsequentImageWriteScanline(ScrnInfoPtr pScrn, int num); @@ -116,7 +125,6 @@ Neo2097AccelInit(ScreenPtr pScreen) ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; NEOPtr nPtr = NEOPTR(pScrn); NEOACLPtr nAcl = NEOACLPTR(pScrn); - BoxRec AvailFBArea; nPtr->AccelInfoRec = infoPtr = XAACreateInfoRec(); if(!infoPtr) return FALSE; @@ -124,11 +132,11 @@ Neo2097AccelInit(ScreenPtr pScreen) /* * Set up the main acceleration flags. */ - infoPtr->Flags |= LINEAR_FRAMEBUFFER | OFFSCREEN_PIXMAPS; - if(nAcl->cacheEnd > nAcl->cacheStart) infoPtr->Flags = PIXMAP_CACHE; -#if 0 - infoPtr->PixmapCacheFlags |= DO_NOT_BLIT_STIPPLES; -#endif + infoPtr->Flags = LINEAR_FRAMEBUFFER | OFFSCREEN_PIXMAPS; + if(nAcl->cacheEnd > nAcl->cacheStart) infoPtr->Flags |= PIXMAP_CACHE; + + infoPtr->PixmapCacheFlags = DO_NOT_BLIT_STIPPLES; + /* sync */ infoPtr->Sync = Neo2097Sync; @@ -146,37 +154,62 @@ Neo2097AccelInit(ScreenPtr pScreen) infoPtr->SubsequentSolidFillRect = Neo2097SubsequentSolidFillRect; -#ifdef colorexpandfill - /* We need byte scanline padding before we can use this - * or does anyone know how to switch the chip to dword - * padding? if we could do right edge clipping this would - * help also. Left edge clipping cannot be used since it - * allows only clipping of up to 8 pixels :-(( - */ /*§§§*/ - - /* cpu to screen color expansion */ - infoPtr->CPUToScreenColorExpandFillFlags = ( NO_PLANEMASK | - CPU_TRANSFER_PAD_DWORD | - BIT_ORDER_IN_BYTE_MSBFIRST ); - infoPtr->ColorExpandBase = - (unsigned char *)(nPtr->NeoMMIOBase + 0x100000); - infoPtr->ColorExpandRange = 0x100000; - - infoPtr->SetupForCPUToScreenColorExpandFill = - Neo2097SetupForCPUToScreenColorExpandFill; - infoPtr->SubsequentCPUToScreenColorExpandFill = - Neo2097SubsequentCPUToScreenColorExpandFill; + if (!nPtr->strangeLockups) { + /* cpu to screen color expansion */ + /* + * We do CPUToScreenColorExpand (ab)using the Scanline functions: + * the neo chipsets need byte padding however we can only do dword + * padding. Fortunately the graphics engine doesn't choke if we + * transfer up to 3 bytes more than it wants. + */ + infoPtr->ScanlineColorExpandBuffers = + (unsigned char **)xnfalloc(sizeof(char*)); + infoPtr->ScanlineColorExpandBuffers[0] = (unsigned char *)(nPtr->NeoMMIOBase + 0x100000); + infoPtr->NumScanlineColorExpandBuffers = 1; + infoPtr->ScanlineCPUToScreenColorExpandFillFlags = ( NO_PLANEMASK | +#ifdef NEO_DO_CLIPPING + LEFT_EDGE_CLIPPING | #endif + CPU_TRANSFER_PAD_DWORD | + BIT_ORDER_IN_BYTE_MSBFIRST ); + infoPtr->SetupForScanlineCPUToScreenColorExpandFill = + Neo2097SetupScanlineForCPUToScreenColorExpandFill; + infoPtr->SubsequentScanlineCPUToScreenColorExpandFill = + Neo2097SubsequentScanlineCPUToScreenColorExpandFill; + infoPtr->SubsequentColorExpandScanline = + Neo2097SubsequentColorExpandScanline; + } + +#if 0 /* 8x8 pattern fills */ infoPtr->Mono8x8PatternFillFlags = NO_PLANEMASK | HARDWARE_PATTERN_PROGRAMMED_ORIGIN - |BIT_ORDER_IN_BYTE_MSBFIRST; + | BIT_ORDER_IN_BYTE_MSBFIRST; infoPtr->SetupForMono8x8PatternFill = Neo2097SetupForMono8x8PatternFill; infoPtr->SubsequentMono8x8PatternFillRect = Neo2097SubsequentMono8x8PatternFill; +#endif + if (nPtr->strangeLockups) { + /* image writes */ + infoPtr->ScanlineImageWriteFlags = ( CPU_TRANSFER_PAD_DWORD | + SCANLINE_PAD_DWORD | + NO_TRANSPARENCY | + NO_PLANEMASK ); + + infoPtr->SetupForScanlineImageWrite = + Neo2097SetupForScanlineImageWrite; + infoPtr->SubsequentScanlineImageWriteRect = + Neo2097SubsequentScanlineImageWriteRect; + infoPtr->SubsequentImageWriteScanline = + Neo2097SubsequentImageWriteScanline; + infoPtr->NumScanlineImageWriteBuffers = 1; + infoPtr->ScanlineImageWriteBuffers = + infoPtr->ScanlineColorExpandBuffers; + } + /* * Setup some global variables */ @@ -212,16 +245,8 @@ Neo2097AccelInit(ScreenPtr pScreen) default: return FALSE; } - - AvailFBArea.x1 = 0; - AvailFBArea.y1 = 0; - AvailFBArea.x2 = pScrn->displayWidth; - AvailFBArea.y2 = nAcl->cacheEnd / - (pScrn->displayWidth * (pScrn->bitsPerPixel >> 3)); - xf86InitFBManager(pScreen, &AvailFBArea); - + return(XAAInit(pScreen, infoPtr)); - } static void @@ -238,17 +263,12 @@ Neo2097SetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir, int ydir, unsigned int planemask, int trans_color) { - NEOPtr nPtr = NEOPTR(pScrn); NEOACLPtr nAcl = NEOACLPTR(pScrn); nAcl->tmpBltCntlFlags = (nAcl->BltCntlFlags | NEO_BC3_SKIP_MAPPING | NEO_BC3_DST_XY_ADDR | NEO_BC3_SRC_XY_ADDR | neo2097Rop[rop]); - - /* set blt control */ - WAIT_ENGINE_IDLE(); - OUTREG(NEOREG_BLTCNTL, nAcl->BltCntlFlags); } static void @@ -312,12 +332,11 @@ Neo2097SubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y, int w, int h) OUTREG(NEOREG_XYEXT, (h<<16) | (w & 0xffff)); } - -#ifdef colorexpandfill static void -Neo2097SetupForCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, int fg, int bg, - int rop, - unsigned int planemask) +Neo2097SetupScanlineForCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, + int fg, int bg, + int rop, + unsigned int planemask) { NEOPtr nPtr = NEOPTR(pScrn); NEOACLPtr nAcl = NEOACLPTR(pScrn); @@ -325,45 +344,103 @@ Neo2097SetupForCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, int fg, int bg, if (bg == -1) { /* transparent setup */ WAIT_ENGINE_IDLE(); +#ifdef NEO_DO_CLIPPING OUTREG(NEOREG_BLTCNTL, nAcl->BltCntlFlags | NEO_BC0_SYS_TO_VID | NEO_BC0_SRC_MONO | NEO_BC0_SRC_TRANS | NEO_BC3_SKIP_MAPPING | - NEO_BC3_DST_XY_ADDR | neo2097Rop[rop]); + NEO_BC3_CLIP_ON | + NEO_BC3_DST_XY_ADDR | neo2097Rop[rop]); +#else + OUTREG(NEOREG_BLTCNTL, nAcl->BltCntlFlags | + NEO_BC0_SYS_TO_VID | + NEO_BC0_SRC_MONO | + NEO_BC0_SRC_TRANS | + NEO_BC3_SKIP_MAPPING | + NEO_BC3_DST_XY_ADDR | neo2097Rop[rop]); +#endif OUTREG(NEOREG_FGCOLOR, fg |= (fg << nAcl->ColorShiftAmt)); } else { /* opaque setup */ WAIT_ENGINE_IDLE(); +#ifdef NEO_DO_CLIPPING OUTREG(NEOREG_BLTCNTL, nAcl->BltCntlFlags | NEO_BC0_SYS_TO_VID | NEO_BC0_SRC_MONO | NEO_BC3_SKIP_MAPPING | + NEO_BC3_CLIP_ON | NEO_BC3_DST_XY_ADDR | neo2097Rop[rop]); +#else + OUTREG(NEOREG_BLTCNTL, nAcl->BltCntlFlags | + NEO_BC0_SYS_TO_VID | + NEO_BC0_SRC_MONO | + NEO_BC3_SKIP_MAPPING | + NEO_BC3_DST_XY_ADDR | neo2097Rop[rop]); +#endif OUTREG(NEOREG_FGCOLOR, fg |= (fg << nAcl->ColorShiftAmt)); OUTREG(NEOREG_BGCOLOR, bg |= (bg << nAcl->ColorShiftAmt)); } } -#endif -#ifdef colorexpandfill + static void -Neo2097SubsequentCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, +Neo2097SubsequentScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, int x, int y, int w, int h, int skipleft) { NEOPtr nPtr = NEOPTR(pScrn); + NEOACLPtr nAcl = NEOACLPTR(pScrn); +#ifdef NEO_DO_CLIPPING + w = (w + 31) & ~31; +#else + nAcl->CPUToScreenColorExpandFill_x = x; + nAcl->CPUToScreenColorExpandFill_y = y; + nAcl->CPUToScreenColorExpandFill_w = w; + nAcl->CPUToScreenColorExpandFill_h = h; +#endif WAIT_ENGINE_IDLE(); +#ifdef NEO_DO_CLIPPING + OUTREG(NEOREG_CLIPLT, (y << 16) | (x + skipleft)); + OUTREG(NEOREG_CLIPRB, ((y + h) << 16) | (x + w)); + WAIT_ENGINE_IDLE(); +#endif OUTREG(NEOREG_SRCSTARTOFF, 0); OUTREG(NEOREG_DSTSTARTOFF, (y<<16) | (x & 0xffff)); +#ifdef NEO_DO_CLIPPING OUTREG(NEOREG_XYEXT, (h<<16) | (w & 0xffff)); +#else + OUTREG(NEOREG_XYEXT, (1<<16) | (w & 0xffff)); +#endif } + +static void +Neo2097SubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno) +{ +#ifdef NEO_DO_CLIPPING + /* Should I be waiting for fifo slots to prevent retries ? + How do I do that on this engine ? */ +#else + NEOPtr nPtr = NEOPTR(pScrn); + NEOACLPtr nAcl = NEOACLPTR(pScrn); + + if (!(--nAcl->CPUToScreenColorExpandFill_h)) + return; + + WAIT_ENGINE_IDLE(); + OUTREG(NEOREG_SRCSTARTOFF, 0); + OUTREG(NEOREG_DSTSTARTOFF, ((++nAcl->CPUToScreenColorExpandFill_y)<<16) + | (nAcl->CPUToScreenColorExpandFill_x & 0xffff)); + OUTREG(NEOREG_XYEXT, (1<<16) + | (nAcl->CPUToScreenColorExpandFill_w & 0xffff)); #endif +} +#if 0 static void Neo2097SetupForMono8x8PatternFill(ScrnInfoPtr pScrn, int patternx, @@ -376,33 +453,31 @@ Neo2097SetupForMono8x8PatternFill(ScrnInfoPtr pScrn, if (bg == -1) { /* transparent setup */ - nAcl->tmpBltCntlFlags = ( nAcl->BltCntlFlags | + nAcl->tmpBltCntlFlags = ( nAcl->BltCntlFlags | NEO_BC0_SRC_MONO | NEO_BC0_FILL_PAT | NEO_BC0_SRC_TRANS | NEO_BC3_SKIP_MAPPING | + NEO_BC3_SRC_XY_ADDR | NEO_BC3_DST_XY_ADDR | neo2097Rop[rop]); WAIT_ENGINE_IDLE(); OUTREG(NEOREG_FGCOLOR, fg |= (fg << nAcl->ColorShiftAmt)); - OUTREG(NEOREG_SRCSTARTOFF, - (patterny*pScrn->displayWidth*pScrn->bitsPerPixel + patternx) - >> 3); + OUTREG(NEOREG_SRCSTARTOFF, (patterny << 16) | patternx); } else { /* opaque setup */ - nAcl->tmpBltCntlFlags = ( nAcl->BltCntlFlags | + nAcl->tmpBltCntlFlags = ( nAcl->BltCntlFlags | NEO_BC0_SRC_MONO | NEO_BC0_FILL_PAT | NEO_BC3_SKIP_MAPPING | + NEO_BC3_SRC_XY_ADDR | NEO_BC3_DST_XY_ADDR | neo2097Rop[rop]); WAIT_ENGINE_IDLE(); OUTREG(NEOREG_FGCOLOR, fg |= (fg << nAcl->ColorShiftAmt)); OUTREG(NEOREG_BGCOLOR, bg |= (bg << nAcl->ColorShiftAmt)); - OUTREG(NEOREG_SRCSTARTOFF, - (patterny*pScrn->displayWidth*pScrn->bitsPerPixel + patternx) - >> 3); + OUTREG(NEOREG_SRCSTARTOFF, (patterny << 16) | patternx); } } @@ -421,10 +496,49 @@ Neo2097SubsequentMono8x8PatternFill(ScrnInfoPtr pScrn, WAIT_ENGINE_IDLE(); OUTREG(NEOREG_BLTCNTL, nAcl->tmpBltCntlFlags | (patterny << 20)); - OUTREG(NEOREG_SRCBITOFF, patternx); +/* OUTREG(NEOREG_SRCBITOFF, patternx); Bad Register */ OUTREG(NEOREG_DSTSTARTOFF, (y<<16) | (x & 0xffff)); OUTREG(NEOREG_XYEXT, (h<<16) | (w & 0xffff)); } +#endif + +static void +Neo2097SetupForScanlineImageWrite( + ScrnInfoPtr pScrn, + int rop, + unsigned int planemask, + int transparency_color, + int bpp, int depth +){ + NEOACLPtr nAcl = NEOACLPTR(pScrn); + + nAcl->tmpBltCntlFlags = (nAcl->BltCntlFlags | + NEO_BC0_SYS_TO_VID | + NEO_BC3_SKIP_MAPPING | + NEO_BC3_DST_XY_ADDR | neo2097Rop[rop]); +} +static void +Neo2097SubsequentScanlineImageWriteRect( + ScrnInfoPtr pScrn, + int x, int y, int w, int h, + int skipleft +){ + NEOPtr nPtr = NEOPTR(pScrn); + NEOACLPtr nAcl = NEOACLPTR(pScrn); + + WAIT_ENGINE_IDLE(); + OUTREG(NEOREG_BLTCNTL, nAcl->tmpBltCntlFlags); + OUTREG(NEOREG_SRCSTARTOFF, 0); + OUTREG(NEOREG_DSTSTARTOFF, (y << 16) | (x & 0xffff)); + OUTREG(NEOREG_XYEXT, (h << 16) | w); +} +static void +Neo2097SubsequentImageWriteScanline( + ScrnInfoPtr pScrn, + int bufno +){ + /* should I be checking for fifo slots here ? */ +} diff --git a/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_2200.c b/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_2200.c index 9df558dc1..fc8e64bb8 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_2200.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_2200.c @@ -1,4 +1,4 @@ -/********************************************************************** +/******************************************************************** Copyright 1998, 1999 by Precision Insight, Inc., Cedar Park, Texas. All Rights Reserved @@ -22,14 +22,13 @@ 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. **********************************************************************/ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_2200.c,v 1.2 1999/06/27 14:08:09 dawes Exp $ */ - +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_2200.c,v 1.18 2002/10/08 22:14:10 tsi Exp $ */ /* * The original Precision Insight driver for * XFree86 v.3.3 has been sponsored by Red Hat. * * Authors: - * Jens Owen (jens@precisioninsight.com) + * Jens Owen (jens@tungstengraphics.com) * Kevin E. Martin (kevin@precisioninsight.com) * * Port to Xfree86 v.4.0 @@ -55,23 +54,31 @@ static void Neo2200SetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir, int ydir, int rop, unsigned int planemask, int trans_color); +#ifdef NOT_BROKEN static void Neo2200SubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int srcX, int srcY, int dstX, int dstY, int w, int h); +#else +static void Neo2200SubsequentScreenToScreenCopyBroken(ScrnInfoPtr pScrn, int srcX, + int srcY, int dstX, int dstY, + int w, int h); +#endif static void Neo2200SetupForSolidFillRect(ScrnInfoPtr pScrn, int color, int rop, unsigned int planemask); static void Neo2200SubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y, int w, int h); -#ifdef colorexpandfill -static void Neo2200SetupForCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, +static void Neo2200SetupForScanlineCPUToScreenColorExpandFill( + ScrnInfoPtr pScrn, int fg, int bg, int rop, unsigned int planemask); -static void Neo2200SubsequentCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, +static void Neo2200SubsequentScanlineCPUToScreenColorExpandFill( + ScrnInfoPtr pScrn, int x, int y, int w, int h, int skipleft); -#endif +static void Neo2200SubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno); +#if 0 static void Neo2200SetupForMono8x8PatternFill(ScrnInfoPtr pScrn, int patternx, int patterny, @@ -84,7 +91,7 @@ static void Neo2200SubsequentMono8x8PatternFill(ScrnInfoPtr pScrn, int patterny, int x, int y, int w, int h); - +#endif static unsigned int neo2200Rop[16] = { @@ -114,7 +121,6 @@ Neo2200AccelInit(ScreenPtr pScreen) ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; NEOPtr nPtr = NEOPTR(pScrn); NEOACLPtr nAcl = NEOACLPTR(pScrn); - BoxRec AvailFBArea; nPtr->AccelInfoRec = infoPtr = XAACreateInfoRec(); if(!infoPtr) return FALSE; @@ -122,8 +128,8 @@ Neo2200AccelInit(ScreenPtr pScreen) /* * Set up the main acceleration flags. */ - infoPtr->Flags |= LINEAR_FRAMEBUFFER | OFFSCREEN_PIXMAPS; - if(nAcl->cacheEnd > nAcl->cacheStart) infoPtr->Flags = PIXMAP_CACHE; + infoPtr->Flags = LINEAR_FRAMEBUFFER | OFFSCREEN_PIXMAPS; + if(nAcl->cacheEnd > nAcl->cacheStart) infoPtr->Flags |= PIXMAP_CACHE; #if 0 infoPtr->PixmapCacheFlags |= DO_NOT_BLIT_STIPPLES; #endif @@ -134,8 +140,12 @@ Neo2200AccelInit(ScreenPtr pScreen) infoPtr->ScreenToScreenCopyFlags = (NO_TRANSPARENCY | NO_PLANEMASK); infoPtr->SetupForScreenToScreenCopy = Neo2200SetupForScreenToScreenCopy; - infoPtr->SubsequentScreenToScreenCopy = - Neo2200SubsequentScreenToScreenCopy; + infoPtr->SubsequentScreenToScreenCopy +#ifdef NOT_BROKEN + = Neo2200SubsequentScreenToScreenCopy; +#else + = Neo2200SubsequentScreenToScreenCopyBroken; +#endif /* solid filled rectangles */ infoPtr->SolidFillFlags = NO_PLANEMASK; @@ -144,28 +154,37 @@ Neo2200AccelInit(ScreenPtr pScreen) infoPtr->SubsequentSolidFillRect = Neo2200SubsequentSolidFillRect; -#ifdef colorexpandfill - /* We need byte scanline padding before we can use this - * or does anyone know how to switch the chip to dword - * padding? if we could do right edge clipping this would - * help also. Left edge clipping cannot be used since it - * allows only clipping of up to 8 pixels :-(( - */ /*§§§*/ - /* cpu to screen color expansion */ - infoPtr->CPUToScreenColorExpandFillFlags = ( NO_PLANEMASK | - /* SCANLINE_PAD_BYTE | */ - CPU_TRANSFER_PAD_DWORD | - BIT_ORDER_IN_BYTE_MSBFIRST ); - infoPtr->ColorExpandBase = - (unsigned char *)(nPtr->NeoMMIOBase + 0x100000); - infoPtr->ColorExpandRange = 0x100000; - - infoPtr->SetupForCPUToScreenColorExpandFill = - Neo2200SetupForCPUToScreenColorExpandFill; - infoPtr->SubsequentCPUToScreenColorExpandFill = - Neo2200SubsequentCPUToScreenColorExpandFill; + /* + * We do CPUToScreenColorExpand (ab)using the Scanline functions: + * the neo chipsets need byte padding however we can only do dword + * padding. Fortunately the graphics engine doesn't choke if we + * transfer up to 3 bytes more than it wants. + */ + + if (!nPtr->strangeLockups) { + + infoPtr->ScanlineCPUToScreenColorExpandFillFlags = ( NO_PLANEMASK | +#ifdef NEO_DO_CLIPPING + LEFT_EDGE_CLIPPING | #endif + SCANLINE_PAD_DWORD | + CPU_TRANSFER_PAD_DWORD | + BIT_ORDER_IN_BYTE_MSBFIRST ); + infoPtr->ScanlineColorExpandBuffers = + (unsigned char **)xnfalloc(sizeof(char*)); + infoPtr->ScanlineColorExpandBuffers[0] = + (unsigned char *)(nPtr->NeoMMIOBase + 0x100000); + infoPtr->NumScanlineColorExpandBuffers = 1; + infoPtr->SetupForScanlineCPUToScreenColorExpandFill = + Neo2200SetupForScanlineCPUToScreenColorExpandFill; + infoPtr->SubsequentScanlineCPUToScreenColorExpandFill = + Neo2200SubsequentScanlineCPUToScreenColorExpandFill; + infoPtr->SubsequentColorExpandScanline = + Neo2200SubsequentColorExpandScanline; + } + +#if 0 /* 8x8 pattern fills */ infoPtr->Mono8x8PatternFillFlags = NO_PLANEMASK | HARDWARE_PATTERN_PROGRAMMED_ORIGIN @@ -175,13 +194,13 @@ Neo2200AccelInit(ScreenPtr pScreen) Neo2200SetupForMono8x8PatternFill; infoPtr->SubsequentMono8x8PatternFillRect = Neo2200SubsequentMono8x8PatternFill; +#endif /* * Setup some global variables */ - nAcl->Pitch = pScrn->displayWidth * nAcl->PixelWidth; - /* Initialize for 8bpp or 15/16bpp support accellerated */ + /* Initialize for 8bpp or 15/16bpp support accelerated */ switch (pScrn->bitsPerPixel) { case 8: nAcl->BltModeFlags = NEO_MODE1_DEPTH8; @@ -193,9 +212,18 @@ Neo2200AccelInit(ScreenPtr pScreen) nAcl->PixelWidth = 2; break; case 24: + if (nPtr->noAccelSet || nPtr->NeoChipset == NM2230 + || nPtr->NeoChipset == NM2360 + || nPtr->NeoChipset == NM2380) { + nAcl->BltModeFlags = NEO_MODE1_DEPTH24; + nAcl->PixelWidth = 3; + } else + return FALSE; + break; default: return FALSE; } + nAcl->Pitch = pScrn->displayWidth * nAcl->PixelWidth; /* Initialize for widths */ switch (pScrn->displayWidth) { @@ -224,15 +252,8 @@ Neo2200AccelInit(ScreenPtr pScreen) return FALSE; } - AvailFBArea.x1 = 0; - AvailFBArea.y1 = 0; - AvailFBArea.x2 = pScrn->displayWidth; - AvailFBArea.y2 = nAcl->cacheEnd / - (pScrn->displayWidth * (pScrn->bitsPerPixel >> 3)); - xf86InitFBManager(pScreen, &AvailFBArea); return(XAAInit(pScreen, infoPtr)); - } static void @@ -253,15 +274,16 @@ Neo2200SetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir, int ydir, NEOACLPtr nAcl = NEOACLPTR(pScrn); nAcl->tmpBltCntlFlags = (NEO_BC3_SKIP_MAPPING | neo2200Rop[rop]); - /* set blt control */ WAIT_ENGINE_IDLE(); - OUTREG16(NEOREG_BLTMODE, nAcl->BltModeFlags); + /*OUTREG16(NEOREG_BLTMODE, nAcl->BltModeFlags);*/ + OUTREG(NEOREG_BLTSTAT, nAcl->BltModeFlags << 16); OUTREG(NEOREG_BLTCNTL, nAcl->tmpBltCntlFlags); OUTREG(NEOREG_PITCH, (nAcl->Pitch<<16) | (nAcl->Pitch & 0xffff)); } +#ifdef NOT_BROKEN static void Neo2200SubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int srcX, int srcY, @@ -274,7 +296,9 @@ Neo2200SubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, if ((dstY < srcY) || ((dstY == srcY) && (dstX < srcX))) { /* start with upper left corner */ WAIT_ENGINE_IDLE(); +#if 0 OUTREG(NEOREG_BLTCNTL, nAcl->tmpBltCntlFlags); +#endif OUTREG(NEOREG_SRCSTARTOFF, (srcY * nAcl->Pitch) + (srcX * nAcl->PixelWidth)); OUTREG(NEOREG_DSTSTARTOFF, @@ -284,10 +308,12 @@ Neo2200SubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, else { /* start with lower right corner */ WAIT_ENGINE_IDLE(); +#if 0 OUTREG(NEOREG_BLTCNTL, (nAcl->tmpBltCntlFlags | NEO_BC0_X_DEC | NEO_BC0_DST_Y_DEC | NEO_BC0_SRC_Y_DEC)); +#endif OUTREG(NEOREG_SRCSTARTOFF, ((srcY+h-1) * nAcl->Pitch) + ((srcX+w-1) * nAcl->PixelWidth)); @@ -298,6 +324,123 @@ Neo2200SubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, } } +#else /* NOT_BROKEN */ + +static void +Neo2200SubsequentScreenToScreenCopyBroken(ScrnInfoPtr pScrn, + int srcX, int srcY, + int dstX, int dstY, + int w, int h) +{ + NEOPtr nPtr = NEOPTR(pScrn); + NEOACLPtr nAcl = NEOACLPTR(pScrn); + + if ((dstY < srcY) || ((dstY == srcY) && (dstX < srcX))) { + if ((((dstX < 64) && ((srcX + w + 64) >= pScrn->displayWidth)) || + ((dstX == 0) && (w > (pScrn->displayWidth - 64)))) && (w > 64)) { + +#define COPY_64 \ + OUTREG(NEOREG_SRCSTARTOFF,\ + (srcY * nAcl->Pitch) + (srcX * nAcl->PixelWidth));\ + OUTREG(NEOREG_DSTSTARTOFF,\ + (dstY * nAcl->Pitch) + (dstX * nAcl->PixelWidth));\ + OUTREG(NEOREG_XYEXT, (h<<16) | (64)); +#define COPY_W \ + OUTREG(NEOREG_SRCSTARTOFF,\ + (srcY * nAcl->Pitch) + (srcX1 * nAcl->PixelWidth));\ + OUTREG(NEOREG_DSTSTARTOFF,\ + (dstY * nAcl->Pitch) + (dstX1 * nAcl->PixelWidth));\ + OUTREG(NEOREG_XYEXT, (h<<16) | (w & 0xffff)); + + int srcX1 = srcX + 64; + int dstX1 = dstX + 64; + w -= 64; + /* start with upper left corner */ + WAIT_ENGINE_IDLE(); + OUTREG(NEOREG_BLTCNTL, nAcl->tmpBltCntlFlags); + if (srcX < dstX) { + COPY_W; + WAIT_ENGINE_IDLE(); + COPY_64; + } else { + COPY_64; + WAIT_ENGINE_IDLE(); + COPY_W; + } +#undef COPY_W +#undef COPY_64 + } else { + /* start with upper left corner */ + WAIT_ENGINE_IDLE(); + OUTREG(NEOREG_BLTCNTL, nAcl->tmpBltCntlFlags); + OUTREG(NEOREG_SRCSTARTOFF, + (srcY * nAcl->Pitch) + (srcX * nAcl->PixelWidth)); + OUTREG(NEOREG_DSTSTARTOFF, + (dstY * nAcl->Pitch) + (dstX * nAcl->PixelWidth)); + OUTREG(NEOREG_XYEXT, (h<<16) | (w & 0xffff)); + } + } else { + if (((((dstX + w) > (pScrn->displayWidth - 64)) && (srcX == 0)) + || (((dstX + w + 64) >= pScrn->displayWidth) + && (w > (pScrn->displayWidth - 64)))) && (w > 64)) { +#define COPY_64 \ + OUTREG(NEOREG_SRCSTARTOFF, \ + ((srcY+h-1) * nAcl->Pitch) + ((srcX1+64-1) \ + * nAcl->PixelWidth)); \ + OUTREG(NEOREG_DSTSTARTOFF, \ + ((dstY+h-1) * nAcl->Pitch) + ((dstX1+64-1) \ + * nAcl->PixelWidth)); \ + OUTREG(NEOREG_XYEXT, (h<<16) | (64 & 0xffff)); +#define COPY_W \ + OUTREG(NEOREG_SRCSTARTOFF, \ + ((srcY+h-1) * nAcl->Pitch) + ((srcX + w -1) \ + * nAcl->PixelWidth)); \ + OUTREG(NEOREG_DSTSTARTOFF, \ + ((dstY+h-1) * nAcl->Pitch) + ((dstX + w -1) \ + * nAcl->PixelWidth)); \ + OUTREG(NEOREG_XYEXT, (h<<16) | (w & 0xffff)); + + int srcX1, dstX1; + + w -= 64; + srcX1 = srcX + w; + dstX1 = dstX + w; + /* start with lower right corner */ + WAIT_ENGINE_IDLE(); + OUTREG(NEOREG_BLTCNTL, (nAcl->tmpBltCntlFlags + | NEO_BC0_X_DEC + | NEO_BC0_DST_Y_DEC + | NEO_BC0_SRC_Y_DEC)); + if (srcX < dstX) { + COPY_64; + WAIT_ENGINE_IDLE(); + COPY_W; + } else { + COPY_W; + WAIT_ENGINE_IDLE(); + COPY_64; + } +#undef COPY_W +#undef COPY_64 + } else { + /* start with lower right corner */ + WAIT_ENGINE_IDLE(); + OUTREG(NEOREG_BLTCNTL, (nAcl->tmpBltCntlFlags + | NEO_BC0_X_DEC + | NEO_BC0_DST_Y_DEC + | NEO_BC0_SRC_Y_DEC)); + OUTREG(NEOREG_SRCSTARTOFF, + ((srcY+h-1) * nAcl->Pitch) + ((srcX+w-1) + * nAcl->PixelWidth)); + OUTREG(NEOREG_DSTSTARTOFF, + ((dstY+h-1) * nAcl->Pitch) + ((dstX+w-1) + * nAcl->PixelWidth)); + OUTREG(NEOREG_XYEXT, (h<<16) | (w & 0xffff)); + } + } +} + +#endif /* NOT_BROKEN */ static void Neo2200SetupForSolidFillRect(ScrnInfoPtr pScrn, int color, int rop, @@ -309,7 +452,8 @@ Neo2200SetupForSolidFillRect(ScrnInfoPtr pScrn, int color, int rop, WAIT_ENGINE_IDLE(); /* set blt control */ - OUTREG16(NEOREG_BLTMODE, nAcl->BltModeFlags); + /*OUTREG16(NEOREG_BLTMODE, nAcl->BltModeFlags);*/ + OUTREG(NEOREG_BLTSTAT, nAcl->BltModeFlags << 16); OUTREG(NEOREG_BLTCNTL, NEO_BC0_SRC_IS_FG | NEO_BC3_SKIP_MAPPING | NEO_BC3_DST_XY_ADDR | @@ -326,14 +470,13 @@ Neo2200SubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y, int w, int h) NEOPtr nPtr = NEOPTR(pScrn); WAIT_ENGINE_IDLE(); - OUTREG(NEOREG_DSTSTARTOFF, (y<<16) | (x & 0xffff)); + OUTREG(NEOREG_DSTSTARTOFF, (y <<16) | (x & 0xffff)); OUTREG(NEOREG_XYEXT, (h<<16) | (w & 0xffff)); } - -#ifdef colorexpandfill static void -Neo2200SetupForCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, int fg, int bg, +Neo2200SetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, + int fg, int bg, int rop, unsigned int planemask) { @@ -347,10 +490,14 @@ Neo2200SetupForCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, int fg, int bg, NEO_BC0_SRC_TRANS | NEO_BC3_SKIP_MAPPING | NEO_BC3_DST_XY_ADDR | - neo2200Rop[rop]); +#ifdef NEO_DO_CLIPPING + NEO_BC3_CLIP_ON | +#endif + neo2200Rop[rop]); WAIT_ENGINE_IDLE(); - OUTREG16(NEOREG_BLTMODE, nAcl->BltModeFlags); + /*OUTREG16(NEOREG_BLTMODE, nAcl->BltModeFlags);*/ + OUTREG(NEOREG_BLTSTAT, nAcl->BltModeFlags << 16); OUTREG(NEOREG_BLTCNTL, nAcl->tmpBltCntlFlags); OUTREG(NEOREG_FGCOLOR, fg); } @@ -360,11 +507,14 @@ Neo2200SetupForCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, int fg, int bg, NEO_BC0_SRC_MONO | NEO_BC3_SKIP_MAPPING | NEO_BC3_DST_XY_ADDR | +#ifdef NEO_DO_CLIPPING + NEO_BC3_CLIP_ON | +#endif neo2200Rop[rop]); WAIT_ENGINE_IDLE(); - OUTREG16(NEOREG_BLTMODE, nAcl->BltModeFlags); - OUTREG(NEOREG_BLTCNTL, nAcl->tmpBltCntlFlags); + /*OUTREG16(NEOREG_BLTMODE, nAcl->BltModeFlags);*/ + OUTREG(NEOREG_BLTSTAT, nAcl->BltModeFlags << 16); OUTREG(NEOREG_FGCOLOR, fg); OUTREG(NEOREG_BGCOLOR, bg); } @@ -372,7 +522,7 @@ Neo2200SetupForCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, int fg, int bg, static void -Neo2200SubsequentCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, +Neo2200SubsequentScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, int x, int y, int w, int h, int skipleft) @@ -380,14 +530,55 @@ Neo2200SubsequentCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, NEOPtr nPtr = NEOPTR(pScrn); NEOACLPtr nAcl = NEOACLPTR(pScrn); +#ifdef NEO_DO_CLIPPING + w = (w + 31) & ~31; +#else + nAcl->CPUToScreenColorExpandFill_x = x; + nAcl->CPUToScreenColorExpandFill_y = y; + nAcl->CPUToScreenColorExpandFill_w = w; + nAcl->CPUToScreenColorExpandFill_h = h; + nAcl->CPUToScreenColorExpandFill_skipleft = skipleft; +#endif OUTREG(NEOREG_BLTCNTL, nAcl->tmpBltCntlFlags | ((skipleft << 2) & 0x1C)); + #ifdef NEO_DO_CLIPPING + OUTREG(NEOREG_CLIPLT, (y << 16) | (x + skipleft)); + OUTREG(NEOREG_CLIPRB, ((y + h) << 16) | (x + w)); +#endif OUTREG(NEOREG_SRCSTARTOFF, 0); OUTREG(NEOREG_DSTSTARTOFF, (y<<16) | (x & 0xffff)); +#ifdef NEO_DO_CLIPPING OUTREG(NEOREG_XYEXT, (h<<16) | (w & 0xffff)); +#else + OUTREG(NEOREG_XYEXT, (1<<16) | (w & 0xffff)); +#endif } + +static void +Neo2200SubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno) +{ + NEOPtr nPtr = NEOPTR(pScrn); + NEOACLPtr nAcl = NEOACLPTR(pScrn); + +#ifdef NEO_DO_CLIPPING + /* Should I be waiting for fifo slots to prevent retries ? + How do I do that on this engine ? */ +#else + if (!(--nAcl->CPUToScreenColorExpandFill_h)) + return; + + WAIT_ENGINE_IDLE(); + OUTREG(NEOREG_BLTCNTL, nAcl->tmpBltCntlFlags + | ((nAcl->CPUToScreenColorExpandFill_skipleft << 2) & 0x1C)); + OUTREG(NEOREG_SRCSTARTOFF, 0); + OUTREG(NEOREG_DSTSTARTOFF, ((++nAcl->CPUToScreenColorExpandFill_y)<<16) + | (nAcl->CPUToScreenColorExpandFill_x & 0xffff)); + OUTREG(NEOREG_XYEXT, (1<<16) + | (nAcl->CPUToScreenColorExpandFill_w & 0xffff)); #endif +} +#if 0 static void Neo2200SetupForMono8x8PatternFill(ScrnInfoPtr pScrn, int patternx, @@ -408,7 +599,8 @@ Neo2200SetupForMono8x8PatternFill(ScrnInfoPtr pScrn, neo2200Rop[rop]); WAIT_ENGINE_IDLE(); - OUTREG16(NEOREG_BLTMODE, nAcl->BltModeFlags); + /*OUTREG16(NEOREG_BLTMODE, nAcl->BltModeFlags);*/ + OUTREG(NEOREG_BLTSTAT, nAcl->BltModeFlags << 16); OUTREG(NEOREG_FGCOLOR, fg); OUTREG(NEOREG_SRCSTARTOFF, (patterny * pScrn->displayWidth * pScrn->bitsPerPixel @@ -423,7 +615,8 @@ Neo2200SetupForMono8x8PatternFill(ScrnInfoPtr pScrn, neo2200Rop[rop]); WAIT_ENGINE_IDLE(); - OUTREG16(NEOREG_BLTMODE, nAcl->BltModeFlags); + /*OUTREG16(NEOREG_BLTMODE, nAcl->BltModeFlags);*/ + OUTREG(NEOREG_BLTSTAT, nAcl->BltModeFlags << 16); OUTREG(NEOREG_FGCOLOR, fg); OUTREG(NEOREG_BGCOLOR, bg); OUTREG(NEOREG_SRCSTARTOFF, @@ -453,3 +646,4 @@ Neo2200SubsequentMono8x8PatternFill(ScrnInfoPtr pScrn, OUTREG(NEOREG_DSTSTARTOFF, (y<<16) | (x & 0xffff)); OUTREG(NEOREG_XYEXT, (h<<16) | (w & 0xffff)); } +#endif diff --git a/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_bank.c b/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_bank.c index c7e1c6237..668aad0ff 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_bank.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_bank.c @@ -11,7 +11,7 @@ supporting documentation, and that the name of Precision Insight not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. Precision Insight and its suppliers make no representations about the suitability of this -software for any purpose. It is provided "as is" without express or +software for any purpose. It is provided "as is" without express or implied warranty. PRECISION INSIGHT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, @@ -22,14 +22,14 @@ 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. **********************************************************************/ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_bank.c,v 1.1 1999/04/17 07:06:22 dawes Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_bank.c,v 1.3 2002/01/25 21:56:05 tsi Exp $ */ /* * The original Precision Insight driver for * XFree86 v.3.3 has been sponsored by Red Hat. * * Authors: - * Jens Owen (jens@precisioninsight.com) + * Jens Owen (jens@tungstengraphics.com) * Kevin E. Martin (kevin@precisioninsight.com) * * Port to Xfree86 v.4.0 @@ -38,38 +38,40 @@ CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #define PSZ 8 -/* Everything using inb/outb, etc needs "compiler.h" */ -#include "compiler.h" - /* 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" + /* Driver specific headers */ #include "neo.h" int NEOSetReadWrite(ScreenPtr pScreen, int bank) -{ +{ + IOADDRESS ioBase = xf86Screens[pScreen->myNum]->domainIOBase + 0x3CE; unsigned char tmp; - - outb(0x3CE, 0x11); - tmp = inb(0x3CF); - outw(0x3CE, (( tmp & 0xFC ) << 8 ) | 0x11); - outw(0x3CE, ((((bank << 2) & 0xFF) << 8) | 0x15)); + + outb(ioBase, 0x11); + tmp = inb(ioBase + 1); + outw(ioBase, (( tmp & 0xFC ) << 8 ) | 0x11); + outw(ioBase, ((((bank << 2) & 0xFF) << 8) | 0x15)); return 0; } int NEOSetWrite(ScreenPtr pScreen, int bank) { + IOADDRESS ioBase = xf86Screens[pScreen->myNum]->domainIOBase + 0x3CE; unsigned char tmp; - - outb(0x3CE, 0x11); - tmp = inb(0x3CF); - outw(0x3CE, ((( tmp & 0xFC ) | 0x01 ) << 8 ) | 0x11); - outw(0x3CE, ((((bank << 2) & 0xFF) << 8) | 0x16)); + + outb(ioBase, 0x11); + tmp = inb(ioBase + 1); + outw(ioBase, ((( tmp & 0xFC ) | 0x01 ) << 8 ) | 0x11); + outw(ioBase, ((((bank << 2) & 0xFF) << 8) | 0x16)); return 0; } @@ -77,19 +79,12 @@ NEOSetWrite(ScreenPtr pScreen, int bank) int NEOSetRead(ScreenPtr pScreen, int bank) { + IOADDRESS ioBase = xf86Screens[pScreen->myNum]->domainIOBase + 0x3CE; unsigned char tmp; - - outb(0x3CE, 0x11); - tmp = inb(0x3CF); - outw(0x3CE, ((( tmp & 0xFC ) | 0x01 ) << 8 ) | 0x11); - outw(0x3CE, ((((bank << 2) & 0xFF) << 8) | 0x15)); + + outb(ioBase, 0x11); + tmp = inb(ioBase + 1); + outw(ioBase, ((( tmp & 0xFC ) | 0x01 ) << 8 ) | 0x11); + outw(ioBase, ((((bank << 2) & 0xFF) << 8) | 0x15)); return 0; } - - - - - - - - diff --git a/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_cursor.c b/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_cursor.c index f476fb66e..4f17a3673 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_cursor.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_cursor.c @@ -22,14 +22,14 @@ 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. **********************************************************************/ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_cursor.c,v 1.2 1999/06/27 14:08:09 dawes Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_cursor.c,v 1.8 2001/10/28 03:33:42 tsi Exp $ */ /* * The original Precision Insight driver for * XFree86 v.3.3 has been sponsored by Red Hat. * * Authors: - * Jens Owen (jens@precisioninsight.com) + * Jens Owen (jens@tungstengraphics.com) * Kevin E. Martin (kevin@precisioninsight.com) * * Port to Xfree86 v.4.0 @@ -78,28 +78,100 @@ NeoHideCursor(ScrnInfoPtr pScrn) nPtr->NeoHWCursorShown = FALSE; } +#define MAX_CURS 64 + +#define REVBITS_32(__b) { \ + ((unsigned char *)&__b)[0] = byte_reversed[((unsigned char *)&__b)[0]]; \ + ((unsigned char *)&__b)[1] = byte_reversed[((unsigned char *)&__b)[1]]; \ + ((unsigned char *)&__b)[2] = byte_reversed[((unsigned char *)&__b)[2]]; \ + ((unsigned char *)&__b)[3] = byte_reversed[((unsigned char *)&__b)[3]]; \ +} + static void neoSetCursorPosition(ScrnInfoPtr pScrn, int x, int y) { NEOPtr nPtr = NEOPTR(pScrn); + NEOACLPtr nAcl = NEOACLPTR(pScrn); + int i; + CARD32 bits, bits2; + unsigned char *_dest = ((unsigned char *)nPtr->NeoFbBase + + nAcl->CursorAddress); + unsigned char *src = nPtr->NeoCursorImage; int xoff = 0, yoff = 0; - if (y < 0) { + if ((y < 0) && (y > (-MAX_CURS))) { yoff = -y; y = 0; } - if (x < 0) { + if ((x < 0) && (x > (-MAX_CURS))) { xoff = -x; x = 0; } if (yoff != nPtr->NeoCursorPrevY || xoff !=nPtr->NeoCursorPrevX) { - _neoLoadCursorImage(pScrn, nPtr->NeoCursorImage - + ((nPtr->CursorInfo->MaxWidth >> 2) * yoff) - + ((xoff + 4) >> 3),(xoff + 4),yoff); nPtr->NeoCursorPrevY = yoff; nPtr->NeoCursorPrevX = xoff; + + /* This is for sprites that move off the top of the display. + * this code simply updates the pointer used for loading the sprite. + * Note, in our driver's RealizeCursor, the allocated buffer size + * is twice as large as needed, and we initialize the upper half to all + * zeros, so we can use this pointer trick here. + */ + + if (yoff) { + src += (yoff * 16); + } + + /* This is for sprites that move off the left edge of the display. + * this code has to do some ugly bit swizzling to generate new cursor + * masks that give the impression the cursor is moving off the screen. + * WARNING: PLATFORM SPECIFIC! This is 32-bit little endian code! + */ + if (xoff) + { + if (xoff < 32) { /* offset 1-31 */ + for (i=0; i<256; i+=2) { + bits = ((CARD32 *)src)[i]; + bits2 = ((CARD32 *)src)[i+1]; + + REVBITS_32(bits); + REVBITS_32(bits2); + + bits = ((bits >> xoff) | (bits2 << (32-xoff))); + bits2 >>= xoff; + + REVBITS_32(bits); + REVBITS_32(bits2); + + ((CARD32 *) nAcl->CursTemp)[i] = bits; + ((CARD32 *) nAcl->CursTemp)[i+1] = bits2; + } + } + else { /* offset 32-63 */ + for (i=0; i<256; i+=2) { + bits = ((CARD32 *)src)[i]; + bits2 = ((CARD32 *)src)[i+1]; + + REVBITS_32(bits2); + + bits = (bits2 >> (xoff-32)); + bits2 = 0; + + REVBITS_32(bits); + + ((CARD32 *)nAcl->CursTemp)[i] = bits; + ((CARD32 *)nAcl->CursTemp)[i+1] = bits2; + } + } + src = nAcl->CursTemp; + } + memcpy(_dest, src, 1024); + OUTREG(NEOREG_CURSMEMPOS, ((0x000f & (nAcl->CursorAddress >> 10)) << 8) | + ((0x0ff0 & (nAcl->CursorAddress >> 10)) >> 4)); + + } - + /* Move the cursor */ OUTREG(NEOREG_CURSX, x); OUTREG(NEOREG_CURSY, y); @@ -128,52 +200,27 @@ _neoLoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src, int xoff, int yoff) unsigned char *_dest, *_src; int _width, _fill; - if (!nPtr->noLinear) { - for (i = 0; i< nPtr->CursorInfo->MaxHeight - yoff; i++) { - _dest = ((unsigned char *)nPtr->NeoFbBase - + nAcl->CursorAddress - + ((nPtr->CursorInfo->MaxWidth >> 2) * i)); - _width = (nPtr->CursorInfo->MaxWidth - - (xoff & 0x38)) >> 3; - _src = (src + ((nPtr->CursorInfo->MaxWidth >> 2) * i)); - _fill = (xoff & 0x38) >> 3; - - memcpy(_dest,_src,_width); - memset(_dest + _width, 0, _fill); - - _dest += (nPtr->CursorInfo->MaxWidth >> 3); - _src += (nPtr->CursorInfo->MaxWidth >> 3); - memcpy(_dest,_src,_width); - memset(_dest + _width, 0, _fill); - } - memset(nPtr->NeoFbBase + nAcl->CursorAddress - + ((nPtr->CursorInfo->MaxWidth >> 2) * i), - 0, (nPtr->CursorInfo->MaxHeight - i) - * (nPtr->CursorInfo->MaxWidth >> 2)); - } else { - /* - * The cursor can only be in the last 16K of video memory, - * which fits in the last banking window. - */ - for (i = 0; i<nPtr->CursorInfo->MaxHeight; i++) { - _dest = ((unsigned char *)nPtr->NeoFbBase - + (nAcl->CursorAddress & 0xFFFF) - + ((nPtr->CursorInfo->MaxWidth >> 2) * i)); - _width = (nPtr->CursorInfo->MaxWidth - - ((xoff & 0x38) >> 3)); - _src = (src + ((nPtr->CursorInfo->MaxWidth >> 2) * i)); - _fill = (xoff & 0x38) >> 3; - - NEOSetWrite(pScrn->pScreen, (int)(nAcl->CursorAddress >> 16)); - memcpy(_dest,_src,_width); - memset(_dest + _width, 0, _fill); - - _dest += (nPtr->CursorInfo->MaxWidth >> 3); - _src += (nPtr->CursorInfo->MaxWidth >> 3); - memcpy(_dest,_src,_width); - memset(_dest + _width, 0, _fill); - } + for (i = 0; i< nPtr->CursorInfo->MaxHeight - yoff; i++) { + _dest = ((unsigned char *)nPtr->NeoFbBase + + nAcl->CursorAddress + + ((nPtr->CursorInfo->MaxWidth >> 2) * i)); + _width = (nPtr->CursorInfo->MaxWidth + - (xoff & 0x38)) >> 3; + _src = (src + ((nPtr->CursorInfo->MaxWidth >> 2) * i)); + _fill = (xoff & 0x38) >> 3; + + memcpy(_dest,_src,_width); + memset(_dest + _width, 0, _fill); + + _dest += (nPtr->CursorInfo->MaxWidth >> 3); + _src += (nPtr->CursorInfo->MaxWidth >> 3); + memcpy(_dest,_src,_width); + memset(_dest + _width, 0, _fill); } + memset(nPtr->NeoFbBase + nAcl->CursorAddress + + ((nPtr->CursorInfo->MaxWidth >> 2) * i), + 0, (nPtr->CursorInfo->MaxHeight - i) + * (nPtr->CursorInfo->MaxWidth >> 2)); /* set cursor address here or we loose the cursor on video mode change */ /* Load storage location. */ OUTREG(NEOREG_CURSMEMPOS, ((0x000f & (nAcl->CursorAddress >> 10)) << 8) | @@ -185,6 +232,10 @@ neoLoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src) { NEOPtr nPtr = NEOPTR(pScrn); nPtr->NeoCursorImage = src; /* store src address for later use */ + + /* Reset these because we have a new cursor image */ + nPtr->NeoCursorPrevY = nPtr->NeoCursorPrevX = 0; + _neoLoadCursorImage(pScrn,src,0,0); } @@ -193,7 +244,7 @@ neoUseHWCursor(ScreenPtr pScr, CursorPtr pCurs) { NEOACLPtr nAcl = NEOACLPTR(xf86Screens[pScr->myNum]); - return nAcl->UseHWCursor; + return(nAcl->UseHWCursor && !nAcl->NoCursorMode); } static unsigned char* @@ -242,7 +293,6 @@ NeoCursorInit(ScreenPtr pScreen) ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; NEOPtr nPtr = NEOPTR(pScrn); xf86CursorInfoPtr infoPtr; - infoPtr = xf86CreateCursorInfoRec(); if(!infoPtr) return FALSE; diff --git a/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_driver.c b/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_driver.c index f508c5c1b..46f4bfc6e 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_driver.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_driver.c @@ -22,28 +22,36 @@ 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. **********************************************************************/ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_driver.c,v 1.7 1999/08/21 13:48:38 dawes Exp $ */ + +/* + * Copyright 1998, 1999 Egbert Eich + * Copyright 2000, 2001 SuSE GmbH, Author: Egbert Eich + * Copyright 2002 SuSE Linux AG, Author: Egbert Eich + * Copyright 2002 Shigehiro Nomura + */ + +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_driver.c,v 1.63 2002/09/16 18:05:57 eich Exp $ */ /* * The original Precision Insight driver for * XFree86 v.3.3 has been sponsored by Red Hat. * * Authors: - * Jens Owen (jens@precisioninsight.com) + * Jens Owen (jens@tungstengraphics.com) * Kevin E. Martin (kevin@precisioninsight.com) * * Port to Xfree86 v.4.0 * 1998, 1999 by Egbert Eich (Egbert.Eich@Physik.TU-Darmstadt.DE) */ -/* Everything using inb/outb, etc needs "compiler.h" */ -#include "compiler.h" - /* 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" + #include "xf86Resources.h" /* Drivers for PCI hardware need this */ @@ -70,24 +78,27 @@ CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. /* All drivers using the mi colormap manipulation need this */ #include "micmap.h" -/* If using cfb, cfb.h is required. */ -#define PSZ 8 -#include "cfb.h" -#undef PSZ -#include "cfb16.h" -#include "cfb24.h" -#include "cfb32.h" -#include "cfb24_32.h" +#include "xf86cmap.h" + +#include "fb.h" /* Needed by Resources Access Control (RAC) */ #include "xf86RAC.h" -/* Needed by the Shadow Framebuffer */ -#include "shadowfb.h" +/* int10 */ +#include "xf86int10.h" +#include "vbe.h" /* Needed for Device Data Channel (DDC) support */ #include "xf86DDC.h" +#include "picturestr.h" + +#ifdef XvExtension +#include "xf86xv.h" +#include "Xv.h" +#endif + /* * Driver data structures. */ @@ -96,26 +107,20 @@ CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include "neo_macros.h" /* These need to be checked */ -#if 0 -#ifdef XFreeXDGA #include "X.h" #include "Xproto.h" #include "scrnintstr.h" #include "servermd.h" #define _XF86DGA_SERVER_ #include "extensions/xf86dgastr.h" -#endif -#endif /* Mandatory functions */ +static const OptionInfoRec * NEOAvailableOptions(int chipid, int busid); static void NEOIdentify(int flags); static Bool NEOProbe(DriverPtr drv, int flags); static Bool NEOPreInit(ScrnInfoPtr pScrn, int flags); static Bool NEOScreenInit(int Index, ScreenPtr pScreen, int argc, char **argv); -static Bool NEOSwitchMode(int scrnIndex, DisplayModePtr mode, - int flags); -static void NEOAdjustFrame(int scrnIndex, int x, int y, int flags); static Bool NEOEnterVT(int scrnIndex, int flags); static void NEOLeaveVT(int scrnIndex, int flags); static Bool NEOCloseScreen(int scrnIndex, ScreenPtr pScreen); @@ -128,7 +133,7 @@ static int neoFindIsaDevice(GDevPtr dev); static Bool neoModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode); static void neoSave(ScrnInfoPtr pScrn); static void neoRestore(ScrnInfoPtr pScrn, vgaRegPtr VgaReg, - NeoRegPtr NeoReg, Bool restoreFonts); + NeoRegPtr NeoReg, Bool restoreText); static void neoLock(ScrnInfoPtr pScrn); static void neoUnlock(ScrnInfoPtr pScrn); static Bool neoMapMem(ScrnInfoPtr pScrn); @@ -136,10 +141,14 @@ static Bool neoUnmapMem(ScrnInfoPtr pScrn); static void neoProgramShadowRegs(ScrnInfoPtr pScrn, vgaRegPtr VgaReg, NeoRegPtr restore); static void neoCalcVCLK(ScrnInfoPtr pScrn, long freq); -static void neo_ddc1(int scrnIndex); -static void neoRefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox); +static xf86MonPtr neo_ddc1(int scrnIndex); +static Bool neoDoDDC1(ScrnInfoPtr pScrn); +static Bool neoDoDDC2(ScrnInfoPtr pScrn); +static Bool neoDoDDCVBE(ScrnInfoPtr pScrn); +static void neoProbeDDC(ScrnInfoPtr pScrn, int index); static void NeoDisplayPowerManagementSet(ScrnInfoPtr pScrn, int PowerManagementMode, int flags); +static int neoFindMode(int xres, int yres, int depth); #define VERSION 4000 #define NEO_NAME "NEOMAGIC" @@ -155,6 +164,120 @@ static void NeoDisplayPowerManagementSet(ScrnInfoPtr pScrn, */ static int pix24bpp = 0; + +static biosMode bios8[] = { + { 320, 240, 0x40 }, + { 300, 400, 0x42 }, + { 640, 400, 0x20 }, + { 640, 480, 0x21 }, + { 800, 600, 0x23 }, + { 1024, 768, 0x25 } +}; + +static biosMode bios15[] = { + { 320, 200, 0x2D }, + { 640, 480, 0x30 }, + { 800, 600, 0x33 }, + { 1024, 768, 0x36 } +}; + +static biosMode bios16[] = { + { 320, 200, 0x2e }, + { 320, 240, 0x41 }, + { 300, 400, 0x43 }, + { 640, 480, 0x31 }, + { 800, 600, 0x34 }, + { 1024, 768, 0x37 } +}; + +static biosMode bios24[] = { + { 640, 480, 0x32 }, + { 800, 600, 0x35 }, + { 1024, 768, 0x38 } +}; + +static DisplayModeRec neo800x480Mode = { + NULL, /* prev */ + NULL, /* next */ + "800x480", /* identifier of this mode */ + MODE_OK, /* mode status */ + M_T_BUILTIN, /* mode type */ + 35260, /* Clock frequency */ + 800, /* HDisplay */ + 856, /* HSyncStart */ + 1040, /* HSyncEnd */ + 1056, /* HTotal */ + 0, /* HSkew */ + 480, /* VDisplay */ + 480, /* VSyncStart */ + 486, /* VSyncEnd */ + 488, /* VTotal */ + 0, /* VScan */ + V_PHSYNC | V_PVSYNC, /* Flags */ + -1, /* ClockIndex */ + 35260, /* SynthClock */ + 800, /* CRTC HDisplay */ + 800, /* CRTC HBlankStart */ + 856, /* CRTC HSyncStart */ + 1040, /* CRTC HSyncEnd */ + 872, /* CRTC HBlankEnd */ + 1048, /* CRTC HTotal */ + 0, /* CRTC HSkew */ + 480, /* CRTC VDisplay */ + 480, /* CRTC VBlankStart */ + 480, /* CRTC VSyncStart */ + 486, /* CRTC VSyncEnd */ + 487, /* CRTC VBlankEnd */ + 488, /* CRTC VTotal */ + FALSE, /* CrtcHAdjusted */ + FALSE, /* CrtcVAdjusted */ + 0, /* PrivSize */ + NULL, /* Private */ + 0.0, /* HSync */ + 0.0 /* VRefresh */ +}; + +static DisplayModeRec neo1024x480Mode = { + NULL, /* prev */ + NULL, /* next */ + "1024x480", /* identifier of this mode */ + MODE_OK, /* mode status */ + M_T_BUILTIN, /* mode type */ + 45900, /* Clock frequency */ + 1024, /* HDisplay */ + 1048, /* HSyncStart */ + 1184, /* HSyncEnd */ + 1344, /* HTotal */ + 0, /* HSkew */ + 480, /* VDisplay */ + 480, /* VSyncStart */ + 486, /* VSyncEnd */ + 488, /* VTotal */ + 0, /* VScan */ + V_PHSYNC | V_PVSYNC, /* Flags */ + -1, /* ClockIndex */ + 45900, /* SynthClock */ + 1024, /* CRTC HDisplay */ + 1024, /* CRTC HBlankStart */ + 1048, /* CRTC HSyncStart */ + 1184, /* CRTC HSyncEnd */ + 1072, /* CRTC HBlankEnd */ + 1344, /* CRTC HTotal */ + 0, /* CRTC HSkew */ + 480, /* CRTC VDisplay */ + 480, /* CRTC VBlankStart */ + 480, /* CRTC VSyncStart */ + 486, /* CRTC VSyncEnd */ + 487, /* CRTC VBlankEnd */ + 488, /* CRTC VTotal */ + FALSE, /* CrtcHAdjusted */ + FALSE, /* CrtcVAdjusted */ + 0, /* PrivSize */ + NULL, /* Private */ + 0.0, /* HSync */ + 0.0 /* VRefresh */ +}; + /* * This contains the functions needed by the server after loading the driver * module. It must be supplied, and gets passed back by the SetupProc @@ -165,9 +288,10 @@ static int pix24bpp = 0; DriverRec NEOMAGIC = { VERSION, - "Driver for the Neomagic chipsets", + NEO_DRIVER_NAME, NEOIdentify, NEOProbe, + NEOAvailableOptions, NULL, 0 }; @@ -179,6 +303,9 @@ static SymTabRec NEOChipsets[] = { { NM2097, "neo2097" }, { NM2160, "neo2160" }, { NM2200, "neo2200" }, + { NM2230, "neo2230" }, + { NM2360, "neo2360" }, + { NM2380, "neo2380" }, { -1, NULL } }; @@ -190,6 +317,9 @@ static PciChipsets NEOPCIchipsets[] = { { NM2097, PCI_CHIP_NM2097, RES_SHARED_VGA }, { NM2160, PCI_CHIP_NM2160, RES_SHARED_VGA }, { NM2200, PCI_CHIP_NM2200, RES_SHARED_VGA }, + { NM2230, PCI_CHIP_NM2230, RES_SHARED_VGA }, + { NM2360, PCI_CHIP_NM2360, RES_SHARED_VGA }, + { NM2380, PCI_CHIP_NM2380, RES_SHARED_VGA }, { -1, -1, RES_UNDEFINED} }; @@ -217,10 +347,17 @@ typedef enum { OPTION_PCI_BURST, OPTION_PROG_LCD_MODE_REGS, OPTION_PROG_LCD_MODE_STRETCH, - OPTION_OVERRIDE_VALIDATE_MODE + OPTION_OVERRIDE_VALIDATE_MODE, + OPTION_SHOWCACHE, + OPTION_ROTATE, + OPTION_VIDEO_KEY, + OPTION_OVERLAYMEM, + OPTION_VIDEO_INTERLACE, + OPTION_DISPLAY_HEIGHT_480, + OPTION_STRANGE_LOCKUPS } NEOOpts; -static OptionInfoRec NEO_2070_Options[] = { +static const OptionInfoRec NEO_2070_Options[] = { { OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE }, { OPTION_SW_CURSOR, "SWcursor", OPTV_BOOLEAN, {0}, FALSE }, { OPTION_NO_MMIO, "noMMIO", OPTV_BOOLEAN, {0}, FALSE }, @@ -230,16 +367,22 @@ static OptionInfoRec NEO_2070_Options[] = { { OPTION_LCD_STRETCH, "NoStretch", OPTV_BOOLEAN, {0}, FALSE }, { OPTION_SHADOW_FB, "ShadowFB", OPTV_BOOLEAN, {0}, FALSE }, { OPTION_PCI_BURST, "pciBurst", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_SHOWCACHE, "ShowCache", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_ROTATE, "Rotate", OPTV_ANYSTR, {0}, FALSE }, { OPTION_PROG_LCD_MODE_REGS, "progLcdModeRegs", OPTV_BOOLEAN, {0}, FALSE }, { OPTION_PROG_LCD_MODE_STRETCH, "progLcdModeStretch", OPTV_BOOLEAN, {0}, FALSE }, { OPTION_OVERRIDE_VALIDATE_MODE, "overrideValidateMode", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_VIDEO_KEY, "VideoKey", OPTV_INTEGER, {0}, FALSE }, + { OPTION_OVERLAYMEM, "OverlayMem", OPTV_INTEGER, {0}, FALSE }, + { OPTION_VIDEO_INTERLACE, "Interlace", + OPTV_INTEGER, {0}, FALSE }, { -1, NULL, OPTV_NONE, {0}, FALSE } }; -static OptionInfoRec NEOOptions[] = { +static const OptionInfoRec NEOOptions[] = { { OPTION_NOLINEAR_MODE,"NoLinear", OPTV_BOOLEAN, {0}, FALSE }, { OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE }, { OPTION_SW_CURSOR, "SWcursor", OPTV_BOOLEAN, {0}, FALSE }, @@ -250,12 +393,21 @@ static OptionInfoRec NEOOptions[] = { { OPTION_SHADOW_FB, "ShadowFB", OPTV_BOOLEAN, {0}, FALSE }, { OPTION_LCD_STRETCH,"NoStretch", OPTV_BOOLEAN, {0}, FALSE }, { OPTION_PCI_BURST, "pciBurst", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_SHOWCACHE, "ShowCache", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_ROTATE, "Rotate", OPTV_ANYSTR, {0}, FALSE }, + { OPTION_STRANGE_LOCKUPS, "StrangeLockups", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_DISPLAY_HEIGHT_480, "DisplayHeight480", + OPTV_BOOLEAN, {0}, FALSE }, { OPTION_PROG_LCD_MODE_REGS, "progLcdModeRegs", OPTV_BOOLEAN, {0}, FALSE }, { OPTION_PROG_LCD_MODE_STRETCH, "progLcdModeStretch", OPTV_BOOLEAN, {0}, FALSE }, { OPTION_OVERRIDE_VALIDATE_MODE, "overrideValidateMode", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_VIDEO_KEY, "VideoKey", OPTV_INTEGER, {0}, FALSE }, + { OPTION_OVERLAYMEM, "OverlayMem", OPTV_INTEGER, {0}, FALSE }, + { OPTION_VIDEO_INTERLACE, "Interlace", + OPTV_INTEGER, {0}, FALSE }, { -1, NULL, OPTV_NONE, {0}, FALSE } }; @@ -269,49 +421,60 @@ static OptionInfoRec NEOOptions[] = { */ static const char *vgahwSymbols[] = { + "vgaHWFreeHWRec", "vgaHWGetHWRec", - "vgaHWUnlock", - "vgaHWInit", - "vgaHWProtect", "vgaHWGetIOBase", - "vgaHWMapMem", + "vgaHWGetIndex", + "vgaHWInit", "vgaHWLock", - "vgaHWFreeHWRec", + "vgaHWMapMem", + "vgaHWProtect", + "vgaHWRestore", + "vgaHWSave", "vgaHWSaveScreen", + "vgaHWSetStdFuncs", + "vgaHWUnlock", + "vgaHWddc1SetSpeed", NULL }; -static const char *cfbSymbols[] = { - "cfbScreenInit", - "cfb16ScreenInit", - "cfb24ScreenInit", - "cfb24_32ScreenInit", +static const char *fbSymbols[] = { + "fbPictureInit", + "fbScreenInit", NULL }; static const char *xaaSymbols[] = { - "XAADestroyInfoRec", "XAACreateInfoRec", + "XAADestroyInfoRec", "XAAInit", NULL }; static const char *ramdacSymbols[] = { - "xf86InitCursor", "xf86CreateCursorInfoRec", "xf86DestroyCursorInfoRec", + "xf86InitCursor", NULL }; static const char *shadowSymbols[] = { - "ShadowFBInit", + "shadowInit", NULL }; static const char *ddcSymbols[] = { - "xf86PrintEDID", "xf86DoEDID_DDC1", "xf86DoEDID_DDC2", + "xf86PrintEDID", + "xf86SetDDCproperties", + NULL +}; + +static const char *vbeSymbols[] = { + "VBEInit", + "vbeDoEDID", + "vbeFree", NULL }; @@ -363,14 +526,14 @@ neoSetup(pointer module, pointer opts, int *errmaj, int *errmin) * Tell the loader about symbols from other modules that this module * might refer to. */ - LoaderRefSymLists(vgahwSymbols, cfbSymbols, xaaSymbols, + LoaderRefSymLists(vgahwSymbols, fbSymbols, xaaSymbols, ramdacSymbols, shadowSymbols, - ddcSymbols, i2cSymbols, NULL); + ddcSymbols, vbeSymbols, i2cSymbols, NULL); /* * The return value must be non-NULL on success even though there * is no TearDownProc. */ - return (pointer)1; + return (pointer)1; } else { if (errmaj) *errmaj = LDR_ONCEONLY; return NULL; @@ -406,6 +569,17 @@ NEOFreeRec(ScrnInfoPtr pScrn) pScrn->driverPrivate = NULL; } +static const OptionInfoRec * +NEOAvailableOptions(int chipid, int busid) +{ + int chip = (chipid & 0x0000ffff); + + if (chip == PCI_CHIP_NM2070) + return NEO_2070_Options; + else + return NEOOptions; +} + /* Mandatory */ static void NEOIdentify(int flags) @@ -439,10 +613,48 @@ NEOProbe(DriverPtr drv, int flags) NEOChipsets, NEOPCIchipsets, devSections,numDevSections, drv, &usedChips); - for (i = 0; i < numUsed; i++) { - ScrnInfoPtr pScrn; - /* Allocate a ScrnInfoRec and claim the slot */ - pScrn = xf86AllocateScreen(drv,0); + + 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], + NEOPCIchipsets,NULL, NULL, + NULL, NULL, NULL))) { + pScrn->driverVersion = VERSION; + pScrn->driverName = NEO_DRIVER_NAME; + pScrn->name = NEO_NAME; + pScrn->Probe = NEOProbe; + pScrn->PreInit = NEOPreInit; + pScrn->ScreenInit = NEOScreenInit; + pScrn->SwitchMode = NEOSwitchMode; + pScrn->AdjustFrame = NEOAdjustFrame; + pScrn->EnterVT = NEOEnterVT; + pScrn->LeaveVT = NEOLeaveVT; + pScrn->FreeScreen = NEOFreeScreen; + pScrn->ValidMode = NEOValidMode; + foundScreen = TRUE; + } + } + xfree(usedChips); + } + } + + /* Isa Bus */ + + numUsed = xf86MatchIsaInstances(NEO_NAME,NEOChipsets,NEOISAchipsets, + drv,neoFindIsaDevice,devSections, + numDevSections,&usedChips); + if (numUsed > 0) { + if (flags & PROBE_DETECT) + foundScreen = TRUE; + else for (i = 0; i < numUsed; i++) { + ScrnInfoPtr pScrn = NULL; + if ((pScrn = xf86ConfigIsaEntity(pScrn, 0, usedChips[i], + NEOISAchipsets, NULL, NULL, + NULL, NULL, NULL))) { pScrn->driverVersion = VERSION; pScrn->driverName = NEO_DRIVER_NAME; pScrn->name = NEO_NAME; @@ -456,39 +668,10 @@ NEOProbe(DriverPtr drv, int flags) pScrn->FreeScreen = NEOFreeScreen; pScrn->ValidMode = NEOValidMode; foundScreen = TRUE; - xf86ConfigActivePciEntity(pScrn, usedChips[i], NEOPCIchipsets, - NULL, NULL, NULL, NULL, NULL); } - if (numUsed > 0) - xfree(usedChips); + } + xfree(usedChips); } - /* Isa Bus */ - - numUsed = xf86MatchIsaInstances(NEO_NAME,NEOChipsets,NEOISAchipsets, - drv,neoFindIsaDevice,devSections, - numDevSections,&usedChips); - for (i = 0; i < numUsed; i++) { - ScrnInfoPtr pScrn; - - pScrn = xf86AllocateScreen(drv,0); - pScrn->driverVersion = VERSION; - pScrn->driverName = NEO_DRIVER_NAME; - pScrn->name = NEO_NAME; - pScrn->Probe = NEOProbe; - pScrn->PreInit = NEOPreInit; - pScrn->ScreenInit = NEOScreenInit; - pScrn->SwitchMode = NEOSwitchMode; - pScrn->AdjustFrame = NEOAdjustFrame; - pScrn->EnterVT = NEOEnterVT; - pScrn->LeaveVT = NEOLeaveVT; - pScrn->FreeScreen = NEOFreeScreen; - pScrn->ValidMode = NEOValidMode; - foundScreen = TRUE; - xf86ConfigActiveIsaEntity(pScrn, usedChips[i], NEOISAchipsets, - NULL, NULL, NULL, NULL, NULL); - } - if (numUsed > 0) - xfree(usedChips); xfree(devSections); return foundScreen; @@ -497,7 +680,7 @@ NEOProbe(DriverPtr drv, int flags) static int neoFindIsaDevice(GDevPtr dev) { - unsigned char vgaIOBase; + unsigned int vgaIOBase; unsigned char id; vgaIOBase = (inb(0x3CC) & 0x01) ? 0x3D0 : 0x3B0; @@ -527,11 +710,9 @@ Bool NEOPreInit(ScrnInfoPtr pScrn, int flags) { ClockRangePtr clockRanges; - char *mod = NULL; int i; NEOPtr nPtr; vgaHWPtr hwp; - const char *reqSym = NULL; int bppSupport = NoDepth24Support; int videoRam = 896; int maxClock = 65000; @@ -539,9 +720,18 @@ NEOPreInit(ScrnInfoPtr pScrn, int flags) int CursorOff = 0x100; int linearSize = 1024; int maxWidth = 1024; - unsigned char type; + int maxHeight = 1024; + unsigned char type, dpy; int w; int apertureSize; + Bool height_480 = FALSE; + Bool lcdCenterOptSet = FALSE; + char *s; + + if (flags & PROBE_DETECT) { + neoProbeDDC( pScrn, xf86GetEntityInfo(pScrn->entityList[0])->index ); + return TRUE; + } /* The vgahw module should be loaded here when needed */ if (!xf86LoadSubModule(pScrn, "vgahw")) @@ -555,7 +745,7 @@ NEOPreInit(ScrnInfoPtr pScrn, int flags) if (!vgaHWGetHWRec(pScrn)) return FALSE; hwp = VGAHWPTR(pScrn); - + /* Allocate the NeoRec driverPrivate */ if (!NEOGetRec(pScrn)) { return FALSE; @@ -592,33 +782,43 @@ NEOPreInit(ScrnInfoPtr pScrn, int flags) xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Chipset is a "); switch(nPtr->NeoChipset){ case NM2070: - ErrorF("MagicGraph 128 (NM2070)"); + xf86ErrorF("MagicGraph 128 (NM2070)"); break; case NM2090 : - ErrorF("MagicGraph 128V (NM2090)"); + xf86ErrorF("MagicGraph 128V (NM2090)"); break; case NM2093 : - ErrorF("MagicGraph 128ZV (NM2093)"); + xf86ErrorF("MagicGraph 128ZV (NM2093)"); break; case NM2097 : - ErrorF("MagicGraph 128ZV+ (NM2097)"); + xf86ErrorF("MagicGraph 128ZV+ (NM2097)"); break; case NM2160 : - ErrorF("MagicGraph 128XD (NM2160)"); + xf86ErrorF("MagicGraph 128XD (NM2160)"); break; case NM2200 : - ErrorF("MagicMedia 256AV (NM2200)"); + xf86ErrorF("MagicMedia 256AV (NM2200)"); + break; + case NM2230 : + xf86ErrorF("MagicMedia 256AV+ (NM2230)"); + break; + case NM2360 : + xf86ErrorF("MagicMedia 256ZX (NM2360)"); + break; + case NM2380 : + xf86ErrorF("MagicMedia 256XL+ (NM2380)"); break; } - ErrorF("\n"); - + xf86ErrorF("\n"); + vgaHWGetIOBase(hwp); nPtr->vgaIOBase = hwp->IOBase; vgaHWSetStdFuncs(hwp); - + /* Determine the panel type */ VGAwGR(0x09,0x26); type = VGArGR(0x21); + dpy = VGArGR(0x20); /* Determine panel width -- used in NeoValidMode. */ w = VGArGR(0x20); @@ -643,7 +843,8 @@ NEOPreInit(ScrnInfoPtr pScrn, int flags) nPtr->NeoPanelHeight = 1024; break; #else - ErrorF("\nOnly 640x480,\n" + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Only 640x480,\n" " 800x600,\n" " and 1024x768 panels are currently supported\n"); return FALSE; @@ -653,12 +854,14 @@ NEOPreInit(ScrnInfoPtr pScrn, int flags) nPtr->NeoPanelHeight = 480; break; } + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Panel is a %dx%d %s %s display\n", nPtr->NeoPanelWidth, nPtr->NeoPanelHeight, (type & 0x02) ? "color" : "monochrome", (type & 0x10) ? "TFT" : "dual scan"); + switch (nPtr->NeoChipset){ case NM2070: bppSupport = NoDepth24Support; @@ -668,6 +871,7 @@ NEOPreInit(ScrnInfoPtr pScrn, int flags) CursorOff = 0x100; linearSize = 1024; maxWidth = 1024; + maxHeight = 1024; break; case NM2090: case NM2093: @@ -679,16 +883,18 @@ NEOPreInit(ScrnInfoPtr pScrn, int flags) CursorOff = 0x100; linearSize = 2048; maxWidth = 1024; + maxHeight = 1024; break; case NM2097: bppSupport = Support24bppFb | Support32bppFb | - SupportConvert32to24 | PreferConvert32to24; + SupportConvert32to24 | PreferConvert32to24; videoRam = 1152; maxClock = 80000; CursorMem = 1024; CursorOff = 0x100; linearSize = 2048; maxWidth = 1024; + maxHeight = 1024; break; case NM2160: bppSupport = Support24bppFb | Support32bppFb | @@ -699,6 +905,7 @@ NEOPreInit(ScrnInfoPtr pScrn, int flags) CursorOff = 0x100; linearSize = 2048; maxWidth = 1024; + maxHeight = 1024; break; case NM2200: bppSupport = Support24bppFb | Support32bppFb | @@ -709,34 +916,61 @@ NEOPreInit(ScrnInfoPtr pScrn, int flags) CursorOff = 0x1000; linearSize = 4096; maxWidth = 1280; + maxHeight = 1024; /* ???? */ + break; + case NM2230: + bppSupport = Support24bppFb | Support32bppFb | + SupportConvert32to24 | PreferConvert32to24; + videoRam = 3008; + maxClock = 110000; + CursorMem = 1024; + CursorOff = 0x1000; + linearSize = 4096; + maxWidth = 1280; + maxHeight = 1024; /* ???? */ + break; + case NM2360: + bppSupport = Support24bppFb | Support32bppFb | + SupportConvert32to24 | PreferConvert32to24; + videoRam = 4096; + maxClock = 110000; + CursorMem = 1024; + CursorOff = 0x1000; + linearSize = 4096; + maxWidth = 1280; + maxHeight = 1024; /* ???? */ + break; + case NM2380: + bppSupport = Support24bppFb | Support32bppFb | + SupportConvert32to24 | PreferConvert32to24; + videoRam = 6144; + maxClock = 110000; + CursorMem = 1024; + CursorOff = 0x1000; + linearSize = 8192; + maxWidth = 1280; + maxHeight = 1024; /* ???? */ break; } - if (!xf86LoadSubModule(pScrn, "ddc")) - return FALSE; - xf86LoaderReqSymLists(ddcSymbols, NULL); -#if 0 - VGAwGR(0x09,0x26); - neo_ddc1(pScrn->scrnIndex); - VGAwGR(0x09,0x00); -#endif - if (!xf86LoadSubModule(pScrn, "i2c")) - return FALSE; - xf86LoaderReqSymLists(i2cSymbols, NULL); - if (!neo_I2CInit(pScrn)) - return FALSE; + pScrn->monitor = pScrn->confScreen->monitor; - VGAwGR(0x09,0x26); - xf86PrintEDID(xf86DoEDID_DDC2(pScrn->scrnIndex,nPtr->I2C)); - VGAwGR(0x09,0x00); + if (xf86LoadSubModule(pScrn, "ddc")) { + xf86LoaderReqSymLists(ddcSymbols, NULL); +#if 1 /* for DDC1 testing */ + if (!neoDoDDCVBE(pScrn)) + if (!neoDoDDC2(pScrn)) +#endif + neoDoDDC1(pScrn); + } - pScrn->monitor = pScrn->confScreen->monitor; if (!xf86SetDepthBpp(pScrn, 8, 8, 8, bppSupport )) return FALSE; else { /* Check that the returned depth is one we support */ switch (pScrn->depth) { case 8: + case 15: case 16: break; case 24: @@ -773,49 +1007,125 @@ NEOPreInit(ScrnInfoPtr pScrn, int flags) } } - if (!xf86SetDefaultVisual(pScrn, -1)) { + if (!xf86SetDefaultVisual(pScrn, -1)) return FALSE; - } else { - /* We don't currently support DirectColor at > 8bpp */ - if (pScrn->depth > 8 && pScrn->defaultVisual != TrueColor) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Given default visual" - " (%s) is not supported at depth %d\n", - xf86GetVisualName(pScrn->defaultVisual), pScrn->depth); + + if (pScrn->depth > 1) { + Gamma zeros = {0.0, 0.0, 0.0}; + + if (!xf86SetGamma(pScrn, zeros)) return FALSE; - } } + nPtr->strangeLockups = TRUE; + /* Collect all of the relevant option flags (fill in pScrn->options) */ xf86CollectOptions(pScrn, NULL); /* Process the options */ - if (nPtr->NeoChipset == NM2070) - nPtr->Options = (OptionInfoPtr)NEO_2070_Options; - else - nPtr->Options = (OptionInfoPtr)NEOOptions; + if (nPtr->NeoChipset == NM2070) { + if (!(nPtr->Options = xalloc(sizeof(NEO_2070_Options)))) + return FALSE; + memcpy(nPtr->Options, NEO_2070_Options, sizeof(NEO_2070_Options)); + } else { + if (!(nPtr->Options = xalloc(sizeof(NEOOptions)))) + return FALSE; + memcpy(nPtr->Options, NEOOptions, sizeof(NEOOptions)); + } xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, nPtr->Options); xf86GetOptValBool(nPtr->Options, OPTION_NOLINEAR_MODE,&nPtr->noLinear); - xf86GetOptValBool(nPtr->Options, OPTION_NOACCEL,&nPtr->noAccel); xf86GetOptValBool(nPtr->Options, OPTION_SW_CURSOR,&nPtr->swCursor); xf86GetOptValBool(nPtr->Options, OPTION_NO_MMIO,&nPtr->noMMIO); xf86GetOptValBool(nPtr->Options, OPTION_INTERN_DISP,&nPtr->internDisp); xf86GetOptValBool(nPtr->Options, OPTION_EXTERN_DISP,&nPtr->externDisp); - xf86GetOptValBool(nPtr->Options, OPTION_LCD_CENTER,&nPtr->lcdCenter); + if (xf86GetOptValBool(nPtr->Options, OPTION_LCD_CENTER,&nPtr->lcdCenter)) + lcdCenterOptSet = TRUE; xf86GetOptValBool(nPtr->Options, OPTION_LCD_STRETCH,&nPtr->noLcdStretch); xf86GetOptValBool(nPtr->Options, OPTION_SHADOW_FB,&nPtr->shadowFB); + xf86GetOptValBool(nPtr->Options, OPTION_SHOWCACHE,&nPtr->showcache); + nPtr->onPciBurst = TRUE; xf86GetOptValBool(nPtr->Options, OPTION_PCI_BURST,&nPtr->onPciBurst); xf86GetOptValBool(nPtr->Options, OPTION_PROG_LCD_MODE_REGS,&nPtr->progLcdRegs); if (xf86GetOptValBool(nPtr->Options, OPTION_PROG_LCD_MODE_STRETCH,&nPtr->progLcdStretch)) - nPtr->progLcdStrechOpt = TRUE; + nPtr->progLcdStretchOpt = TRUE; xf86GetOptValBool(nPtr->Options, OPTION_OVERRIDE_VALIDATE_MODE, &nPtr->overrideValidate); - if (nPtr->shadowFB) - ErrorF("shadow\n"); - else - ErrorF("no shadow\n"); + xf86GetOptValBool(nPtr->Options, OPTION_DISPLAY_HEIGHT_480,&height_480); + xf86GetOptValBool(nPtr->Options, OPTION_STRANGE_LOCKUPS, + &nPtr->strangeLockups); + nPtr->noAccelSet = + xf86GetOptValBool(nPtr->Options, OPTION_NOACCEL,&nPtr->noAccel); + + nPtr->rotate = 0; + if ((s = xf86GetOptValString(nPtr->Options, OPTION_ROTATE))) { + if(!xf86NameCmp(s, "CW")) { + /* accel is disabled below for shadowFB */ + nPtr->shadowFB = TRUE; + nPtr->swCursor = TRUE; + nPtr->rotate = 1; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "Rotating screen clockwise - acceleration disabled\n"); + } else if(!xf86NameCmp(s, "CCW")) { + nPtr->shadowFB = TRUE; + nPtr->swCursor = TRUE; + nPtr->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"); + } + } +#ifdef XvExtension + if(xf86GetOptValInteger(nPtr->Options, + OPTION_VIDEO_KEY, &(nPtr->videoKey))) { + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "video key set to 0x%x\n", + nPtr->videoKey); + } else { + nPtr->videoKey = (1 << pScrn->offset.red) | + (1 << pScrn->offset.green) | + (((pScrn->mask.blue >> pScrn->offset.blue) - 1) + << pScrn->offset.blue); + } + if(xf86GetOptValInteger(nPtr->Options, OPTION_OVERLAYMEM, + &(nPtr->overlay))) { + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "reserve %d bytes for overlay.\n", nPtr->overlay); + } else { + nPtr->overlay = 0; + } + nPtr->interlace = 0; + if(xf86GetOptValInteger(nPtr->Options, OPTION_VIDEO_INTERLACE, + &(nPtr->interlace))) { + if (nPtr->interlace >= 0 && nPtr->interlace <= 2){ + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "interlace flag = %d\n", + nPtr->interlace); + } else { + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "\"%s\" is not a valid value for " + "Option \"Interlaced\"\n", s); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Valid options are 0..2\n"); + } + } +#endif /* XvExtension */ + + + if (height_480 + && (nPtr->NeoPanelWidth == 800 || nPtr->NeoPanelWidth == 1024)) { + xf86DrvMsg(pScrn->scrnIndex,X_CONFIG, + "Overriding Panel height: Set to 480\n"); + nPtr->NeoPanelHeight = 480; + xf86DrvMsg(pScrn->scrnIndex,X_CONFIG, + "Disabling LCD stretching for panel height 480\n"); + nPtr->noLcdStretch = TRUE; + if (!lcdCenterOptSet) + nPtr->lcdCenter = TRUE; + } if (nPtr->internDisp && nPtr->externDisp) xf86DrvMsg(pScrn->scrnIndex,X_CONFIG, @@ -826,6 +1136,26 @@ NEOPreInit(ScrnInfoPtr pScrn, int flags) else if (nPtr->internDisp) xf86DrvMsg(pScrn->scrnIndex,X_CONFIG, "Internal LCD only display mode\n"); + else { + nPtr->internDisp = ((dpy & 0x02) == 0x02); + nPtr->externDisp = ((dpy & 0x01) == 0x01); + if (nPtr->internDisp && nPtr->externDisp) + xf86DrvMsg(pScrn->scrnIndex,X_PROBED, + "Simultaneous LCD/CRT display mode\n"); + else if (nPtr->externDisp) + xf86DrvMsg(pScrn->scrnIndex,X_PROBED, + "External CRT only display mode\n"); + else if (nPtr->internDisp) + xf86DrvMsg(pScrn->scrnIndex,X_PROBED, + "Internal LCD only display mode\n"); + else { + /* this is a fallback if probed values are bogus */ + nPtr->internDisp = TRUE; + xf86DrvMsg(pScrn->scrnIndex,X_DEFAULT, + "Internal LCD only display mode\n"); + } + } + if (nPtr->noLcdStretch) xf86DrvMsg(pScrn->scrnIndex,X_CONFIG, "Low resolution video modes are not stretched\n"); @@ -842,12 +1172,19 @@ NEOPreInit(ScrnInfoPtr pScrn, int flags) xf86DrvMsg(pScrn->scrnIndex,X_CONFIG, "MMIO mode disabled\n"); if (nPtr->onPciBurst) xf86DrvMsg(pScrn->scrnIndex,X_CONFIG, "using PCI Burst mode\n"); + if (nPtr->strangeLockups) + xf86DrvMsg(pScrn->scrnIndex,X_CONFIG, + "Option StrangeLockups set: disabling some acceleration\n"); + if (nPtr->showcache) + xf86DrvMsg(pScrn->scrnIndex,X_CONFIG, + "Show chache for debugging\n"); if (nPtr->shadowFB) { if (nPtr->noLinear) { xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Option \"ShadowFB\" ignored. Not supported without" " linear addressing\n"); nPtr->shadowFB = FALSE; + nPtr->rotate = 0; } else { nPtr->noAccel = TRUE; xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, @@ -862,17 +1199,19 @@ NEOPreInit(ScrnInfoPtr pScrn, int flags) /* XXX Check this matches a PCI base address */ nPtr->NeoLinearAddr = nPtr->pEnt->device->MemBase; xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, - "base address is set at 0x%X.\n", + "FB base address is set at 0x%X.\n", nPtr->NeoLinearAddr); } else { nPtr->NeoLinearAddr = 0; } - if (nPtr->pEnt->device->IOBase) { + nPtr->NeoMMIOAddr2 = 0; + nPtr->NeoMMIOBase2 = NULL; + if (nPtr->pEnt->device->IOBase && !nPtr->noMMIO) { /* XXX Check this matches a PCI base address */ nPtr->NeoMMIOAddr = nPtr->pEnt->device->IOBase; xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, - "base address is set at 0x%X.\n", + "MMIO base address is set at 0x%X.\n", nPtr->NeoMMIOAddr); } else { nPtr->NeoMMIOAddr = 0; @@ -882,10 +1221,10 @@ NEOPreInit(ScrnInfoPtr pScrn, int flags) if (!nPtr->NeoLinearAddr) { nPtr->NeoLinearAddr = nPtr->PciInfo->memBase[0]; xf86DrvMsg(pScrn->scrnIndex, X_PROBED, - "base address is set at 0x%X.\n", + "FB base address is set at 0x%X.\n", nPtr->NeoLinearAddr); } - if (!nPtr->NeoMMIOAddr) { + if (!nPtr->NeoMMIOAddr && !nPtr->noMMIO) { switch (nPtr->NeoChipset) { case NM2070 : nPtr->NeoMMIOAddr = nPtr->NeoLinearAddr + 0x100000; @@ -897,12 +1236,21 @@ NEOPreInit(ScrnInfoPtr pScrn, int flags) case NM2160: case NM2097: case NM2200: + case NM2230: + case NM2360: + case NM2380: nPtr->NeoMMIOAddr = nPtr->PciInfo->memBase[1]; + nPtr->NeoMMIOAddr2 = nPtr->PciInfo->memBase[2]; break; } xf86DrvMsg(pScrn->scrnIndex, X_PROBED, - "base address is set at 0x%X.\n", + "MMIO base address is set at 0x%X.\n", nPtr->NeoMMIOAddr); + if (nPtr->NeoMMIOAddr2 != 0){ + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "MMIO base address2 is set at 0x%X.\n", + nPtr->NeoMMIOAddr2); + } } /* XXX What about VGA resources in OPERATING mode? */ if (xf86RegisterResources(nPtr->pEnt->index, NULL, ResExclusive)) @@ -910,7 +1258,7 @@ NEOPreInit(ScrnInfoPtr pScrn, int flags) } else if (nPtr->pEnt->location.type == BUS_ISA) { unsigned int addr; - resRange linearRes[] = { {ResExcMemBlock|ResBios,0,0},_END }; + resRange linearRes[] = { {ResExcMemBlock|ResBios|ResBus,0,0},_END }; if (!nPtr->NeoLinearAddr) { VGAwGR(0x09,0x26); @@ -918,13 +1266,13 @@ NEOPreInit(ScrnInfoPtr pScrn, int flags) VGAwGR(0x09,0x00); nPtr->NeoLinearAddr = addr << 20; xf86DrvMsg(pScrn->scrnIndex, X_PROBED, - "base address is set at 0x%X.\n", + "FB base address is set at 0x%X.\n", nPtr->NeoLinearAddr); } - if (!nPtr->NeoMMIOAddr) { + if (!nPtr->NeoMMIOAddr && !nPtr->noMMIO) { nPtr->NeoMMIOAddr = nPtr->NeoLinearAddr + 0x100000; xf86DrvMsg(pScrn->scrnIndex, X_PROBED, - "base address is set at 0x%X.\n", + "MMIO base address is set at 0x%X.\n", nPtr->NeoMMIOAddr); } linearRes[0].rBegin = nPtr->NeoLinearAddr; @@ -950,7 +1298,7 @@ NEOPreInit(ScrnInfoPtr pScrn, int flags) xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Max Clock: %d kHz\n", maxClock); } else { - xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Max Clock: %d kByte\n", + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Max Clock: %d kHz\n", maxClock); } @@ -959,14 +1307,14 @@ NEOPreInit(ScrnInfoPtr pScrn, int flags) * Setup the ClockRanges, which describe what clock ranges are available, * and what sort of modes they can be used for. */ - clockRanges = (ClockRangePtr)xnfalloc(sizeof(ClockRange)); + clockRanges = (ClockRangePtr)xnfcalloc(sizeof(ClockRange), 1); clockRanges->next = NULL; clockRanges->ClockMulFactor = 1; clockRanges->minClock = 11000; /* guessed §§§ */ clockRanges->maxClock = maxClock; clockRanges->clockIndex = -1; /* programmable */ if (!nPtr->internDisp && nPtr->externDisp) - clockRanges->interlaceAllowed = TRUE; /* §§§ */ + clockRanges->interlaceAllowed = TRUE; else clockRanges->interlaceAllowed = FALSE; clockRanges->doubleScanAllowed = TRUE; @@ -976,19 +1324,30 @@ NEOPreInit(ScrnInfoPtr pScrn, int flags) nPtr->NeoCursorMem = CursorMem; else nPtr->NeoCursorMem = 0; - apertureSize = nPtr->NeoFbMapSize - nPtr->NeoCursorMem; + apertureSize = (pScrn->videoRam * 1024) - nPtr->NeoCursorMem; + + if ((nPtr->NeoPanelWidth == 800) && (nPtr->NeoPanelHeight == 480)) { + neo800x480Mode.next = pScrn->monitor->Modes; + pScrn->monitor->Modes = &neo800x480Mode; + } + if ((nPtr->NeoPanelWidth == 1024) && (nPtr->NeoPanelHeight == 480)) { + neo1024x480Mode.next = pScrn->monitor->Modes; + pScrn->monitor->Modes = &neo1024x480Mode; + } /* * For external displays, limit the width to 1024 pixels or less. */ - i = xf86ValidateModes(pScrn, pScrn->monitor->Modes, + { + i = xf86ValidateModes(pScrn, pScrn->monitor->Modes, pScrn->display->modes, clockRanges, NULL, 256, maxWidth,(8 * pScrn->bitsPerPixel),/*§§§*/ - 128, 2048, pScrn->display->virtualX, + 128, maxHeight, pScrn->display->virtualX, pScrn->display->virtualY, apertureSize, LOOKUP_BEST_REFRESH); - if (i == -1) - RETURN; + if (i == -1) + RETURN; + } /* Prune the modes marked as invalid */ xf86PruneDriverModes(pScrn); @@ -1017,31 +1376,11 @@ NEOPreInit(ScrnInfoPtr pScrn, int flags) /* If monitor resolution is set on the command line, use it */ xf86SetDpi(pScrn, 0, 0); - /* Load bpp-specific modules */ - switch (pScrn->bitsPerPixel) { - case 8: - mod = "cfb"; - reqSym = "cfbScreenInit"; - break; - case 16: - mod = "cfb16"; - reqSym = "cfb16ScreenInit"; - break; - case 24: - if (pix24bpp == 24) { - mod = "cfb24"; - reqSym = "cfb24ScreenInit"; - } else { - mod = "xf24_32bpp"; - reqSym = "cfb24_32ScreenInit"; - } - break; - } - if (mod && xf86LoadSubModule(pScrn, mod) == NULL) { + if (xf86LoadSubModule(pScrn, "fb") == NULL) { RETURN; } - xf86LoaderReqSymbols(reqSym, NULL); + xf86LoaderReqSymLists(fbSymbols, NULL); if (!nPtr->noLinear) { if (!xf86LoadSubModule(pScrn, "xaa")) @@ -1050,7 +1389,7 @@ NEOPreInit(ScrnInfoPtr pScrn, int flags) } if (nPtr->shadowFB) { - if (!xf86LoadSubModule(pScrn, "shadowfb")) { + if (!xf86LoadSubModule(pScrn, "shadow")) { RETURN; } xf86LoaderReqSymLists(shadowSymbols, NULL); @@ -1061,7 +1400,6 @@ NEOPreInit(ScrnInfoPtr pScrn, int flags) RETURN; xf86LoaderReqSymLists(ramdacSymbols, NULL); } - return TRUE; } #undef RETURN @@ -1076,9 +1414,14 @@ NEOEnterVT(int scrnIndex, int flags) /* Should we re-save the text mode on each VT enter? */ if(!neoModeInit(pScrn, pScrn->currentMode)) return FALSE; +#ifdef XvExtension + if (nPtr->video) + NEOResetVideo(pScrn); +#endif if (nPtr->NeoHWCursorShown) NeoShowCursor(pScrn); NEOAdjustFrame(pScrn->scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); + return TRUE; } @@ -1088,27 +1431,50 @@ NEOLeaveVT(int scrnIndex, int flags) { ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; NEOPtr nPtr = NEOPTR(pScrn); - -#if 0 -#ifdef XFreeXDGA - if (vga256InfoRec.directMode&XF86DGADirectGraphics && !enter) { - /* - * Disable HW cursor. I hope DGA can't call this function twice - * in a row, without calling EnterVT in between. Otherwise the - * effect will be to hide the cursor, perhaps permanently!! - */ - if (nPtr->NeoHWCursorShown) - NeoHideCursor(pScrn); - return; - } -#endif -#endif - + /* Invalidate the cached acceleration registers */ if (nPtr->NeoHWCursorShown) NeoHideCursor(pScrn); neoRestore(pScrn, &(VGAHWPTR(pScrn))->SavedReg, &nPtr->NeoSavedReg, TRUE); neoLock(pScrn); + +} + +static void +NEOLoadPalette( + ScrnInfoPtr pScrn, + int numColors, + int *indices, + LOCO *colors, + VisualPtr pVisual +){ + int i, index, shift, Gshift; + vgaHWPtr hwp = VGAHWPTR(pScrn); + + switch(pScrn->depth) { + case 15: + shift = Gshift = 1; + break; + case 16: + shift = 0; + Gshift = 0; + break; + default: + shift = Gshift = 0; + break; + } + + for(i = 0; i < numColors; i++) { + index = indices[i]; + hwp->writeDacWriteAddr(hwp, index); + DACDelay(hwp); + hwp->writeDacData(hwp, colors[index].red << shift); + DACDelay(hwp); + hwp->writeDacData(hwp, colors[index].green << Gshift); + DACDelay(hwp); + hwp->writeDacData(hwp, colors[index].blue << shift); + DACDelay(hwp); + } } /* Mandatory */ @@ -1124,7 +1490,8 @@ NEOScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) int allocatebase, freespace, currentaddr; unsigned int racflag = RAC_FB; unsigned char *FBStart; - + int height, width, displayWidth; + /* * we need to get the ScrnInfoRec for this screen, so let's allocate * one first thing @@ -1142,28 +1509,16 @@ NEOScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) /* Map the Neo memory and possible MMIO areas */ if (!neoMapMem(pScrn)) return FALSE; - + /* * next we save the current state and setup the first mode */ neoSave(pScrn); - + if (!neoModeInit(pScrn,pScrn->currentMode)) return FALSE; - vgaHWSaveScreen(pScreen,FALSE); + vgaHWSaveScreen(pScreen,SCREEN_SAVER_ON); NEOAdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); - - /* - * 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. - * - * For most PC hardware at depths >= 8, the defaults that cfb uses - * are not appropriate. In this driver, we fixup the visuals after. - */ /* * Reset visual list. @@ -1172,82 +1527,40 @@ NEOScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) /* Setup the visuals we support. */ - /* - * For bpp > 8, the default visuals are not acceptable because we only - * support TrueColor and not DirectColor. To deal with this, call - * miSetVisualTypes for each visual supported. - */ + if (!miSetVisualTypes(pScrn->depth, + miGetDefaultVisualMask(pScrn->depth), + pScrn->rgbBits, pScrn->defaultVisual)) + return FALSE; - if (pScrn->depth > 8) { - if (!miSetVisualTypes(pScrn->depth, TrueColorMask, pScrn->rgbBits, - pScrn->defaultVisual)) - return FALSE; - } else { - if (!miSetVisualTypes(pScrn->depth, - miGetDefaultVisualMask(pScrn->depth), - pScrn->rgbBits, pScrn->defaultVisual)) - return FALSE; - } - - /* - * Temporarily set the global defaultColorVisualClass to make - * cfbInitVisuals do what we want. - */ -#if 0 - savedDefaultVisualClass = xf86GetDefaultColorVisualClass(); - xf86SetDefaultColorVisualClass(pScrn->defaultVisual); -#endif + if (!miSetPixmapDepths ()) return FALSE; /* * Call the framebuffer layer's ScreenInit function, and fill in other * pScreen fields. */ + displayWidth = pScrn->displayWidth; + if (nPtr->rotate) { + height = pScrn->virtualX; + width = pScrn->virtualY; + } else { + width = pScrn->virtualX; + height = pScrn->virtualY; + } + if(nPtr->shadowFB) { - nPtr->ShadowPitch = - ((pScrn->virtualX * pScrn->bitsPerPixel >> 3) + 3) & ~3L; - nPtr->ShadowPtr = xalloc(nPtr->ShadowPitch * pScrn->virtualY); + nPtr->ShadowPitch = BitmapBytePad(pScrn->bitsPerPixel * width); + nPtr->ShadowPtr = xalloc(nPtr->ShadowPitch * height); + displayWidth = nPtr->ShadowPitch / (pScrn->bitsPerPixel >> 3); FBStart = nPtr->ShadowPtr; } else { nPtr->ShadowPtr = NULL; FBStart = nPtr->NeoFbBase; } - - switch (pScrn->bitsPerPixel) { - case 8: - ret = cfbScreenInit(pScreen, FBStart, - pScrn->virtualX, pScrn->virtualY, + + ret = fbScreenInit(pScreen, FBStart, + width, height, pScrn->xDpi, pScrn->yDpi, - pScrn->displayWidth); - break; - case 16: - ret = cfb16ScreenInit(pScreen, FBStart, - pScrn->virtualX, pScrn->virtualY, - pScrn->xDpi, pScrn->yDpi, - pScrn->displayWidth); - break; - case 24: - if (pix24bpp == 24) - ret = cfb24ScreenInit(pScreen, FBStart, - pScrn->virtualX, pScrn->virtualY, - pScrn->xDpi, pScrn->yDpi, - pScrn->displayWidth); - else - ret = cfb24_32ScreenInit(pScreen, FBStart, - pScrn->virtualX, pScrn->virtualY, - pScrn->xDpi, pScrn->yDpi, - pScrn->displayWidth); - break; - default: - xf86DrvMsg(scrnIndex, X_ERROR, - "Internal error: invalid bpp (%d) in NEOScreenInit\n", - pScrn->bitsPerPixel); - ret = FALSE; - break; - } - -#if 0 - xf86SetDefaultColorVisualClass(savedDefaultVisualClass); -#endif + displayWidth, pScrn->bitsPerPixel); if (!ret) return FALSE; @@ -1266,11 +1579,18 @@ NEOScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) } } + /* must be after RGB ordering fixed */ + fbPictureInit(pScreen, 0, 0); + xf86SetBlackWhitePixels(pScreen); + + if (!nPtr->shadowFB) + NEODGAInit(pScreen); nPtr->NeoHWCursorShown = FALSE; nPtr->NeoHWCursorInitialized = FALSE; nAcl->UseHWCursor = FALSE; + nAcl->CursorAddress = -1; if (nPtr->noLinear) { miBankInfoPtr pBankInfo; @@ -1281,7 +1601,7 @@ NEOScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) return FALSE; pBankInfo->pBankA = hwp->Base; - pBankInfo->pBankB = (unsigned char *)hwp->Base + 0x10000; + pBankInfo->pBankB = (unsigned char *)hwp->Base; pBankInfo->BankSize = 0x10000; pBankInfo->nBankDepth = pScrn->depth; @@ -1297,16 +1617,16 @@ NEOScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) return FALSE; } xf86DrvMsg(pScrn->scrnIndex,X_INFO, "Using nonlinear mode\n"); - xf86DrvMsg(pScrn->scrnIndex,X_INFO, "Using software cursor\n"); - + xf86DrvMsg(pScrn->scrnIndex,X_INFO, "Using software cursor in " + "nonlinear mode\n"); miInitializeBackingStore(pScreen); xf86SetBackingStore(pScreen); + xf86SetSilkenMouse(pScreen); /* Initialise cursor functions */ miDCInitialize (pScreen, xf86GetPointerScreenFuncs()); } else { - nAcl->CursorAddress = -1; nAcl->cacheStart = -1; nAcl->cacheEnd = -1; xf86DrvMsg(pScrn->scrnIndex,X_INFO, @@ -1314,13 +1634,14 @@ NEOScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) nPtr->NeoLinearAddr); /* Setup pointers to free space in video ram */ allocatebase = (pScrn->videoRam << 10); - freespace = allocatebase - pScrn->displayWidth * + freespace = allocatebase - pScrn->displayWidth * pScrn->virtualY * (pScrn->bitsPerPixel >> 3); currentaddr = allocatebase; xf86DrvMsg(scrnIndex, X_PROBED, "%d bytes off-screen memory available\n", freespace); - if (nPtr->swCursor || nPtr->noMMIO) { + nAcl->CursorAddress = 0; + if (nPtr->swCursor || !nPtr->NeoMMIOBase) { xf86DrvMsg(scrnIndex, X_CONFIG, "Using Software Cursor.\n"); } else if (nPtr->NeoCursorMem <= freespace) { @@ -1332,81 +1653,154 @@ NEOScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) nAcl->CursorAddress = currentaddr; xf86DrvMsg(scrnIndex, X_INFO, "Using H/W Cursor.\n"); - } else xf86DrvMsg(scrnIndex, X_ERROR, - "Too little space for H/W cursor.\n"); + } else { + xf86DrvMsg(scrnIndex, X_ERROR, + "Too little space for H/W cursor.\n"); + } + if (!nPtr->noAccel && !nPtr->NeoMMIOBase) + xf86DrvMsg(pScrn->scrnIndex,X_INFO, + "Acceleration disabled when not using MMIO\n"); + +#ifdef XvExtension + if (nPtr->overlay > 0){ + if (nPtr->overlay > freespace){ + xf86DrvMsg(pScrn->scrnIndex,X_INFO, + "Can not reserve %d bytes for overlay. " + "Resize to %d bytes.\n", + nPtr->overlay, freespace); + nPtr->overlay = freespace; + } + currentaddr -= nPtr->overlay; + freespace -= nPtr->overlay; + nPtr->overlay_offset = currentaddr; + xf86DrvMsg(pScrn->scrnIndex,X_INFO,"Overlay at 0x%x\n", + nPtr->overlay_offset); + } +#endif /* XvExtension */ + nAcl->cacheStart = currentaddr - freespace; + nAcl->cacheEnd = currentaddr; + freespace = 0; + if (nAcl->cacheStart < nAcl->cacheEnd) { + BoxRec AvailFBArea; + int lines = nAcl->cacheEnd / + (pScrn->displayWidth * (pScrn->bitsPerPixel >> 3)); + if (!nPtr->noAccel && nPtr->NeoMMIOBase && lines > 1024) + lines = 1024; + AvailFBArea.x1 = 0; + AvailFBArea.y1 = 0; + AvailFBArea.x2 = pScrn->displayWidth; + AvailFBArea.y2 = lines; + xf86InitFBManager(pScreen, &AvailFBArea); + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Using %i scanlines of offscreen memory \n", + lines - pScrn->virtualY); + } + /* Setup the acceleration primitives */ - if (!nPtr->noAccel) { - nAcl->cacheStart = currentaddr - freespace; - nAcl->cacheEnd = currentaddr; - freespace = 0; + if (!nPtr->noAccel && nPtr->NeoMMIOBase) { + Bool ret = FALSE; if (nAcl->cacheStart >= nAcl->cacheEnd) { xf86DrvMsg(scrnIndex, X_ERROR, "Too little space for pixmap cache.\n"); - } + } switch(nPtr->NeoChipset) { case NM2070 : - Neo2070AccelInit(pScreen); + ret = Neo2070AccelInit(pScreen); break; case NM2090 : case NM2093 : - Neo2090AccelInit(pScreen); + ret = Neo2090AccelInit(pScreen); break; case NM2097 : case NM2160 : - Neo2097AccelInit(pScreen); + ret = Neo2097AccelInit(pScreen); break; case NM2200 : - Neo2200AccelInit(pScreen); + case NM2230 : + case NM2360 : + case NM2380 : + ret = Neo2200AccelInit(pScreen); break; } - xf86DrvMsg(pScrn->scrnIndex,X_INFO,"Acceleration Initialized\n"); + xf86DrvMsg(pScrn->scrnIndex,X_INFO, + "Acceleration %s Initialized\n",ret ? "" : "not"); } - + miInitializeBackingStore(pScreen); xf86SetBackingStore(pScreen); + xf86SetSilkenMouse(pScreen); /* Initialise cursor functions */ miDCInitialize (pScreen, xf86GetPointerScreenFuncs()); - if (nAcl->CursorAddress != -1) { - /* HW cursor functions */ - if (!NeoCursorInit(pScreen)) { - xf86DrvMsg(scrnIndex, X_ERROR, - "Hardware cursor initialization failed\n"); - return FALSE; - } - nAcl->UseHWCursor = TRUE; - nPtr->NeoHWCursorInitialized = TRUE; - } } - if (nPtr->shadowFB) - ShadowFBInit(pScreen, neoRefreshArea); + if (nAcl->CursorAddress != -1) { + /* HW cursor functions */ + if (!NeoCursorInit(pScreen)) { + xf86DrvMsg(scrnIndex, X_ERROR, + "Hardware cursor initialization failed\n"); + return FALSE; + } + nAcl->UseHWCursor = TRUE; + nPtr->NeoHWCursorInitialized = TRUE; + } else + nAcl->UseHWCursor = FALSE; + + if (nPtr->shadowFB) { + nPtr->refreshArea = neoRefreshArea; + if(nPtr->rotate) { + if (!nPtr->PointerMoved) { + nPtr->PointerMoved = pScrn->PointerMoved; + pScrn->PointerMoved = neoPointerMoved; + } + + switch(pScrn->bitsPerPixel) { + case 8: nPtr->refreshArea = neoRefreshArea8; break; + case 16: nPtr->refreshArea = neoRefreshArea16; break; + case 24: nPtr->refreshArea = neoRefreshArea24; break; + case 32: nPtr->refreshArea = neoRefreshArea32; break; + } + } +#if 0 + ShadowFBInit(pScreen, nPtr->refreshArea); +#else + shadowInit (pScreen, neoShadowUpdate, 0); +#endif + } + /* Initialise default colourmap */ if(!miCreateDefColormap(pScreen)) return FALSE; - if (!vgaHWHandleColormaps(pScreen)) + if (!xf86HandleColormaps(pScreen, 256, pScrn->rgbBits, + NEOLoadPalette, NULL, + CMAP_PALETTED_TRUECOLOR | CMAP_RELOAD_ON_MODE_SWITCH)) return FALSE; - if (pScrn->bitsPerPixel == 8) - racflag |= RAC_COLORMAP; + racflag |= RAC_COLORMAP; if (nPtr->NeoHWCursorInitialized) racflag |= RAC_CURSOR; pScrn->racIoFlags = pScrn->racMemFlags = racflag; + NEOInitVideo(pScreen); + pScreen->SaveScreen = vgaHWSaveScreen; -#ifdef DPMSExtension /* Setup DPMS mode */ if (nPtr->NeoChipset != NM2070) xf86DPMSInit(pScreen, (DPMSSetProcPtr)NeoDisplayPowerManagementSet, 0); -#endif + if (!nPtr->noLinear) { + pScrn->memPhysBase = (unsigned long)nPtr->NeoFbBase; + pScrn->fbOffset = 0; + } + /* Wrap the current CloseScreen function */ nPtr->CloseScreen = pScreen->CloseScreen; pScreen->CloseScreen = NEOCloseScreen; @@ -1420,14 +1814,14 @@ NEOScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) } /* Mandatory */ -static Bool +Bool NEOSwitchMode(int scrnIndex, DisplayModePtr mode, int flags) { return neoModeInit(xf86Screens[scrnIndex], mode); } /* Mandatory */ -static void +void NEOAdjustFrame(int scrnIndex, int x, int y, int flags) { ScrnInfoPtr pScrn; @@ -1437,12 +1831,22 @@ NEOAdjustFrame(int scrnIndex, int x, int y, int flags) int Base; pScrn = xf86Screens[scrnIndex]; - Base = (y * pScrn->displayWidth + x) >> 2; hwp = VGAHWPTR(pScrn); nPtr = NEOPTR(pScrn); - /* Scale Base by the number of bytes per pixel. */ - switch (pScrn->bitsPerPixel) { + if (nPtr->showcache && y) { + int lastline = nPtr->NeoFbMapSize / + ((pScrn->displayWidth * pScrn->bitsPerPixel) / 8); + + lastline -= pScrn->currentMode->VDisplay; + y += pScrn->virtualY - 1; + if (y > lastline) y = lastline; + } + + Base = (y * pScrn->displayWidth + x) >> 2; + + /* Scale Base by the number of bytes per pixel. */ + switch (pScrn->depth) { case 8 : break; case 15 : @@ -1490,6 +1894,7 @@ NEOCloseScreen(int scrnIndex, ScreenPtr pScreen) if (nPtr->NeoHWCursorShown) NeoHideCursor(pScrn); neoRestore(pScrn, &(VGAHWPTR(pScrn))->SavedReg, &nPtr->NeoSavedReg, TRUE); + neoLock(pScrn); neoUnmapMem(pScrn); } @@ -1497,6 +1902,8 @@ NEOCloseScreen(int scrnIndex, ScreenPtr pScreen) XAADestroyInfoRec(nPtr->AccelInfoRec); if (nPtr->CursorInfo) xf86DestroyCursorInfoRec(nPtr->CursorInfo); + if (nPtr->ShadowPtr) + xfree(nPtr->ShadowPtr); pScrn->vtSema = FALSE; pScreen->CloseScreen = nPtr->CloseScreen; @@ -1507,7 +1914,8 @@ NEOCloseScreen(int scrnIndex, ScreenPtr pScreen) static void NEOFreeScreen(int scrnIndex, int flags) { - vgaHWFreeHWRec(xf86Screens[scrnIndex]); + if (xf86LoaderCheckSymbol("vgaHWFreeHWRec")) + vgaHWFreeHWRec(xf86Screens[scrnIndex]); NEOFreeRec(xf86Screens[scrnIndex]); } @@ -1553,15 +1961,27 @@ NEOValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags) case 1024 : if (mode->VDisplay == 768) return(MODE_OK); + if ((mode->VDisplay == 480) && (nPtr->NeoPanelHeight == 480)) + return(MODE_OK); break; case 800 : - if (mode->VDisplay == 600) + if (mode->VDisplay == 600) + return(MODE_OK); + if ((mode->VDisplay == 480) && (nPtr->NeoPanelHeight == 480)) return(MODE_OK); break; case 640 : if (mode->VDisplay == 480) return(MODE_OK); break; +#if 1 + case 320: + if (mode->VDisplay == 240) + return(MODE_OK); + break; +#endif + default: + break; } xf86DrvMsg(scrnIndex, X_INFO, "Removing mode (%dx%d) that won't " @@ -1600,19 +2020,25 @@ neoMapMem(ScrnInfoPtr pScrn) if (!nPtr->noLinear) { if (!nPtr->noMMIO) { - if (nPtr->pEnt->location.type == BUS_PCI) + if (nPtr->pEnt->location.type == BUS_PCI){ nPtr->NeoMMIOBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO, nPtr->PciTag, nPtr->NeoMMIOAddr, 0x200000L); - else + if (nPtr->NeoMMIOAddr2 != 0){ + nPtr->NeoMMIOBase2 = + xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO, + nPtr->PciTag, nPtr->NeoMMIOAddr2, + 0x100000L); + } + } else nPtr->NeoMMIOBase = xf86MapVidMem(pScrn->scrnIndex, VIDMEM_MMIO, nPtr->NeoMMIOAddr, 0x200000L); + if (nPtr->NeoMMIOBase == NULL) + return FALSE; } - if (nPtr->NeoMMIOBase == NULL) - return FALSE; if (nPtr->pEnt->location.type == BUS_PCI) nPtr->NeoFbBase = @@ -1644,8 +2070,14 @@ neoUnmapMem(ScrnInfoPtr pScrn) NEOPtr nPtr = NEOPTR(pScrn); if (!nPtr->noLinear) { - xf86UnMapVidMem(pScrn->scrnIndex, (pointer)nPtr->NeoMMIOBase, 0x200000L); + if (nPtr->NeoMMIOBase) + xf86UnMapVidMem(pScrn->scrnIndex, (pointer)nPtr->NeoMMIOBase, + 0x200000L); nPtr->NeoMMIOBase = NULL; + if (nPtr->NeoMMIOBase2) + xf86UnMapVidMem(pScrn->scrnIndex, (pointer)nPtr->NeoMMIOBase2, + 0x100000L); + nPtr->NeoMMIOBase2 = NULL; xf86UnMapVidMem(pScrn->scrnIndex, (pointer)nPtr->NeoFbBase, nPtr->NeoFbMapSize); } @@ -1704,22 +2136,27 @@ neoSave(ScrnInfoPtr pScrn) if (nPtr->NeoChipset == NM2160) { save->PanelHorizCenterReg4 = VGArGR(0x36); } - if (nPtr->NeoChipset == NM2200) { + if (nPtr->NeoChipset == NM2200 || nPtr->NeoChipset == NM2230 + || nPtr->NeoChipset == NM2360 || nPtr->NeoChipset == NM2380) { save->PanelHorizCenterReg4 = VGArGR(0x36); save->PanelVertCenterReg5 = VGArGR(0x37); save->PanelHorizCenterReg5 = VGArGR(0x38); } save->ExtColorModeSelect = VGArGR(0x90); save->VCLK3NumeratorLow = VGArGR(0x9B); - if (nPtr->NeoChipset == NM2200) + if (nPtr->NeoChipset == NM2200 || nPtr->NeoChipset == NM2230 + || nPtr->NeoChipset == NM2360 || nPtr->NeoChipset == NM2380) save->VCLK3NumeratorHigh = VGArGR(0x8F); save->VCLK3Denominator = VGArGR(0x9F); - + save->ProgramVCLK = TRUE; + if (save->reg == NULL) save->reg = (regSavePtr)xnfcalloc(sizeof(regSaveRec), 1); else - ErrorF("WARNING: Non-NULL reg in NeoSave: reg=0x%08X\n", save->reg); + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Non-NULL reg in NeoSave: reg=0x%08X\n", save->reg); + save->reg->CR[0x23] = VGArCR(0x23); save->reg->CR[0x25] = VGArCR(0x25); save->reg->CR[0x2F] = VGArCR(0x2F); for (i = 0x40; i <= 0x59; i++) { @@ -1750,6 +2187,14 @@ neoProgramShadowRegs(ScrnInfoPtr pScrn, vgaRegPtr VgaReg, NeoRegPtr restore) Bool noProgramShadowRegs; vgaHWPtr hwp = VGAHWPTR(pScrn); NEOPtr nPtr = NEOPTR(pScrn); + Bool prog_lcd; + + /* + * If display is external only and we want internal + * we need to program the shadow registers. + */ + prog_lcd = (((VGArGR(0x20) & 0x3) == 0x1) && nPtr->internDisp); + /* * Convoluted logic for shadow register programming. @@ -1761,13 +2206,13 @@ neoProgramShadowRegs(ScrnInfoPtr pScrn, vgaRegPtr VgaReg, NeoRegPtr restore) case NM2070: /* Program the shadow regs by default */ noProgramShadowRegs = FALSE; - if (!nPtr->progLcdRegs) + if (!nPtr->progLcdRegs && !prog_lcd) noProgramShadowRegs = TRUE; if (restore->PanelDispCntlReg2 & 0x84) { /* Don't program by default if in stretch mode */ noProgramShadowRegs = TRUE; - if (nPtr->progLcdStretch) + if (nPtr->progLcdStretch) noProgramShadowRegs = FALSE; } break; @@ -1776,21 +2221,25 @@ neoProgramShadowRegs(ScrnInfoPtr pScrn, vgaRegPtr VgaReg, NeoRegPtr restore) case NM2097: case NM2160: case NM2200: + case NM2230: + case NM2360: + case NM2380: default: /* Don't program the shadow regs by default */ noProgramShadowRegs = TRUE; - if (nPtr->progLcdRegs) + if (nPtr->progLcdRegs || prog_lcd) noProgramShadowRegs = FALSE; if (restore->PanelDispCntlReg2 & 0x84) { /* Only change the behavior if an option is set */ - if (nPtr->progLcdStrechOpt) + if (nPtr->progLcdStretchOpt) noProgramShadowRegs = !nPtr->progLcdStretch; } break; } if (noProgramShadowRegs) { + xf86DrvMsgVerb(pScrn->scrnIndex,X_INFO,5,"Not programming shadow registers\n"); if (nPtr->NeoSavedReg.reg){ for (i = 0x40; i <= 0x59; i++) { VGAwCR(i, nPtr->NeoSavedReg.reg->CR[i]); @@ -1825,79 +2274,150 @@ neoProgramShadowRegs(ScrnInfoPtr pScrn, vgaRegPtr VgaReg, NeoRegPtr restore) VGAwCR(0x4F,0xA0); break; case 800 : - VGAwCR(0x40,0x7F); - VGAwCR(0x41,0x63); - VGAwCR(0x42,0x02); - VGAwCR(0x43,0x6C); - VGAwCR(0x44,0x1C); - VGAwCR(0x45,0x72); - VGAwCR(0x46,0xE0); - VGAwCR(0x47,0x58); - VGAwCR(0x48,0x0C); - VGAwCR(0x49,0x57); - VGAwCR(0x4A,0x73); - VGAwCR(0x4B,0x3D); - VGAwCR(0x4C,0x31); - VGAwCR(0x4D,0x01); - VGAwCR(0x4E,0x36); - VGAwCR(0x4F,0x1E); - if (nPtr->NeoChipset != NM2070) { + switch (nPtr->NeoPanelHeight) { + case 600: + VGAwCR(0x40,0x7F); + VGAwCR(0x41,0x63); + VGAwCR(0x42,0x02); + VGAwCR(0x43,0x6C); + VGAwCR(0x44,0x1C); + VGAwCR(0x45,0x72); + VGAwCR(0x46,0xE0); + VGAwCR(0x47,0x58); + VGAwCR(0x48,0x0C); + VGAwCR(0x49,0x57); + VGAwCR(0x4A,0x73); + VGAwCR(0x4B,0x3D); + VGAwCR(0x4C,0x31); + VGAwCR(0x4D,0x01); + VGAwCR(0x4E,0x36); + VGAwCR(0x4F,0x1E); + if (nPtr->NeoChipset != NM2070) { + VGAwCR(0x50,0x6B); + VGAwCR(0x51,0x4F); + VGAwCR(0x52,0x0E); + VGAwCR(0x53,0x58); + VGAwCR(0x54,0x88); + VGAwCR(0x55,0x33); + VGAwCR(0x56,0x27); + VGAwCR(0x57,0x16); + VGAwCR(0x58,0x2C); + VGAwCR(0x59,0x94); + } + break; + case 480: + VGAwCR(0x40,0x7F); + VGAwCR(0x41,0x63); + VGAwCR(0x42,0x02); + VGAwCR(0x43,0x6B); + VGAwCR(0x44,0x1B); + VGAwCR(0x45,0x72); + VGAwCR(0x46,0xE0); + VGAwCR(0x47,0x1C); + VGAwCR(0x48,0x00); + VGAwCR(0x49,0x57); + VGAwCR(0x4A,0x73); + VGAwCR(0x4B,0x3E); + VGAwCR(0x4C,0x31); + VGAwCR(0x4D,0x01); + VGAwCR(0x4E,0x36); + VGAwCR(0x4F,0x1E); VGAwCR(0x50,0x6B); VGAwCR(0x51,0x4F); VGAwCR(0x52,0x0E); - VGAwCR(0x53,0x58); - VGAwCR(0x54,0x88); + VGAwCR(0x53,0x57); + VGAwCR(0x54,0x87); VGAwCR(0x55,0x33); VGAwCR(0x56,0x27); VGAwCR(0x57,0x16); VGAwCR(0x58,0x2C); VGAwCR(0x59,0x94); + break; + break; + /* Not done */ } break; case 1024 : - VGAwCR(0x40,0xA3); - VGAwCR(0x41,0x7F); - VGAwCR(0x42,0x06); - VGAwCR(0x43,0x85); - VGAwCR(0x44,0x96); - VGAwCR(0x45,0x24); - VGAwCR(0x46,0xE5); - VGAwCR(0x47,0x02); - VGAwCR(0x48,0x08); - VGAwCR(0x49,0xFF); - VGAwCR(0x4A,0x25); - VGAwCR(0x4B,0x4F); - VGAwCR(0x4C,0x40); - VGAwCR(0x4D,0x00); - VGAwCR(0x4E,0x44); - VGAwCR(0x4F,0x0C); - VGAwCR(0x50,0x7A); - VGAwCR(0x51,0x56); - VGAwCR(0x52,0x00); - VGAwCR(0x53,0x5D); - VGAwCR(0x54,0x0E); - VGAwCR(0x55,0x3B); - VGAwCR(0x56,0x2B); - VGAwCR(0x57,0x00); - VGAwCR(0x58,0x2F); - VGAwCR(0x59,0x18); - VGAwCR(0x60,0x88); - VGAwCR(0x61,0x63); - VGAwCR(0x62,0x0B); - VGAwCR(0x63,0x69); - VGAwCR(0x64,0x1A); + switch (nPtr->NeoPanelHeight) { + case 768: + VGAwCR(0x40,0xA3); + VGAwCR(0x41,0x7F); + VGAwCR(0x42,0x06); + VGAwCR(0x43,0x85); + VGAwCR(0x44,0x96); + VGAwCR(0x45,0x24); + VGAwCR(0x46,0xE5); + VGAwCR(0x47,0x02); + VGAwCR(0x48,0x08); + VGAwCR(0x49,0xFF); + VGAwCR(0x4A,0x25); + VGAwCR(0x4B,0x4F); + VGAwCR(0x4C,0x40); + VGAwCR(0x4D,0x00); + VGAwCR(0x4E,0x44); + VGAwCR(0x4F,0x0C); + VGAwCR(0x50,0x7A); + VGAwCR(0x51,0x56); + VGAwCR(0x52,0x00); + VGAwCR(0x53,0x5D); + VGAwCR(0x54,0x0E); + VGAwCR(0x55,0x3B); + VGAwCR(0x56,0x2B); + VGAwCR(0x57,0x00); + VGAwCR(0x58,0x2F); + VGAwCR(0x59,0x18); + VGAwCR(0x60,0x88); + VGAwCR(0x61,0x63); + VGAwCR(0x62,0x0B); + VGAwCR(0x63,0x69); + VGAwCR(0x64,0x1A); + break; + case 480: + VGAwCR(0x40,0xA3); + VGAwCR(0x41,0x7F); + VGAwCR(0x42,0x1B); + VGAwCR(0x43,0x89); + VGAwCR(0x44,0x16); + VGAwCR(0x45,0x0B); + VGAwCR(0x46,0x2C); + VGAwCR(0x47,0xE8); + VGAwCR(0x48,0x0C); + VGAwCR(0x49,0xE7); + VGAwCR(0x4A,0x09); + VGAwCR(0x4B,0x4F); + VGAwCR(0x4C,0x40); + VGAwCR(0x4D,0x00); + VGAwCR(0x4E,0x44); + VGAwCR(0x4F,0x0C); + VGAwCR(0x50,0x7A); + VGAwCR(0x51,0x56); + VGAwCR(0x52,0x00); + VGAwCR(0x53,0x5D); + VGAwCR(0x54,0x0E); + VGAwCR(0x55,0x3B); + VGAwCR(0x56,0x2A); + VGAwCR(0x57,0x00); + VGAwCR(0x58,0x2F); + VGAwCR(0x59,0x18); + VGAwCR(0x60,0x88); + VGAwCR(0x61,0x63); + VGAwCR(0x62,0x0B); + VGAwCR(0x63,0x69); + VGAwCR(0x64,0x1A); + break; + } break; case 1280: #ifdef NOT_DONE VGAwCR(0x40,0x?? ); . - . - . - VGAwCR(0x64,0x?? ); - break; + . + . + VGAwCR(0x64,0x?? ); + break; #else - /* Probe should prevent this case for now */ - FatalError("1280 panel support incomplete\n"); + /* Probe should prevent this case for now */ + FatalError("1280 panel support incomplete\n"); #endif } } @@ -1905,15 +2425,16 @@ neoProgramShadowRegs(ScrnInfoPtr pScrn, vgaRegPtr VgaReg, NeoRegPtr restore) static void neoRestore(ScrnInfoPtr pScrn, vgaRegPtr VgaReg, NeoRegPtr restore, - Bool restoreFonts) + Bool restoreText) { NEOPtr nPtr = NEOPTR(pScrn); vgaHWPtr hwp = VGAHWPTR(pScrn); unsigned char temp; int i; + Bool clock_hi = FALSE; vgaHWProtect(pScrn,TRUE); /* Blank the screen */ - + VGAwGR(0x09,0x26); /* Init the shadow registers if necessary */ @@ -1931,6 +2452,7 @@ neoRestore(ScrnInfoPtr pScrn, vgaRegPtr VgaReg, NeoRegPtr restore, * any reserved bits. */ temp = VGArGR(0x90); + switch (nPtr->NeoChipset) { case NM2070 : temp &= 0xF0; /* Save bits 7:4 */ @@ -1941,12 +2463,20 @@ neoRestore(ScrnInfoPtr pScrn, vgaRegPtr VgaReg, NeoRegPtr restore, case NM2097 : case NM2160 : case NM2200 : + case NM2230 : + case NM2360 : + case NM2380 : temp &= 0x70; /* Save bits 6:4 */ temp |= (restore->ExtColorModeSelect & ~0x70); break; } VGAwGR(0x90,temp); - + + /* + * In some rare cases a lockup might occur if we don't delay + * here. (Reported by Miles Lane) + */ + xf86UDelay(200000); /* * Disable horizontal and vertical graphics and text expansions so * that vgaHWRestore works properly. @@ -1959,12 +2489,12 @@ neoRestore(ScrnInfoPtr pScrn, vgaRegPtr VgaReg, NeoRegPtr restore, * Sleep for 200ms to make sure that the two operations above have * had time to take effect. */ - usleep(200000); - + xf86UDelay(200000); /* * This function handles restoring the generic VGA registers. */ vgaHWRestore(pScrn, VgaReg, - VGA_SR_MODE | VGA_SR_CMAP | (restoreFonts ? VGA_SR_FONTS : 0)); + VGA_SR_MODE + | (restoreText ? (VGA_SR_FONTS | VGA_SR_CMAP) : 0)); VGAwGR(0x0E, restore->ExtCRTDispAddr); VGAwGR(0x0F, restore->ExtCRTOffset); @@ -1976,6 +2506,7 @@ neoRestore(ScrnInfoPtr pScrn, vgaRegPtr VgaReg, NeoRegPtr restore, VGAwGR(0x11, restore->SysIfaceCntl2); VGAwGR(0x15, restore->SingleAddrPage); VGAwGR(0x16, restore->DualAddrPage); + temp = VGArGR(0x20); switch (nPtr->NeoChipset) { case NM2070 : @@ -1990,11 +2521,15 @@ neoRestore(ScrnInfoPtr pScrn, vgaRegPtr VgaReg, NeoRegPtr restore, temp |= (restore->PanelDispCntlReg1 & ~0xDC); break; case NM2200 : + case NM2230 : + case NM2360 : + case NM2380 : temp &= 0x98; /* Save bits 7,4:3 */ temp |= (restore->PanelDispCntlReg1 & ~0x98); break; } VGAwGR(0x20, temp); + temp = VGArGR(0x25); temp &= 0x38; /* Save bits 5:3 */ temp |= (restore->PanelDispCntlReg2 & ~0x38); @@ -2022,16 +2557,24 @@ neoRestore(ScrnInfoPtr pScrn, vgaRegPtr VgaReg, NeoRegPtr restore, VGAwGR(0x36, restore->PanelHorizCenterReg4); } - if (nPtr->NeoChipset == NM2200) { + if (nPtr->NeoChipset == NM2200 || nPtr->NeoChipset == NM2230 + || nPtr->NeoChipset == NM2360 || nPtr->NeoChipset == NM2380) { VGAwGR(0x36, restore->PanelHorizCenterReg4); VGAwGR(0x37, restore->PanelVertCenterReg5); VGAwGR(0x38, restore->PanelHorizCenterReg5); } - + if (nPtr->NeoChipset == NM2200 || nPtr->NeoChipset == NM2230 + || nPtr->NeoChipset == NM2360 || nPtr->NeoChipset == NM2380) + clock_hi = TRUE; + /* Program VCLK3 if needed. */ - if (restore->ProgramVCLK) { + if (restore->ProgramVCLK + && ((VGArGR(0x9B) != restore->VCLK3NumeratorLow) + || (VGArGR(0x9F) != restore->VCLK3Denominator) + || (clock_hi && ((VGArGR(0x8F) & ~0x0f) + != (restore->VCLK3NumeratorHigh & ~0x0F))))) { VGAwGR(0x9B, restore->VCLK3NumeratorLow); - if (nPtr->NeoChipset == NM2200) { + if (clock_hi) { temp = VGArGR(0x8F); temp &= 0x0F; /* Save bits 3:0 */ temp |= (restore->VCLK3NumeratorHigh & ~0x0F); @@ -2039,8 +2582,11 @@ neoRestore(ScrnInfoPtr pScrn, vgaRegPtr VgaReg, NeoRegPtr restore, } VGAwGR(0x9F, restore->VCLK3Denominator); } + if (restore->biosMode) + VGAwCR(0x23,restore->biosMode); if (restore->reg) { + VGAwCR(0x23,restore->reg->CR[0x23]); VGAwCR(0x25,restore->reg->CR[0x25]); VGAwCR(0x2F,restore->reg->CR[0x2F]); for (i = 0x40; i <= 0x59; i++) { @@ -2059,15 +2605,14 @@ neoRestore(ScrnInfoPtr pScrn, vgaRegPtr VgaReg, NeoRegPtr restore, for (i = 0x90; i <= NEO_EXT_GR_MAX; i++) { VGAwGR(i, restore->reg->GR[i]); } - xfree(restore->reg); - restore->reg = NULL; } + /* Program vertical extension register */ - if (nPtr->NeoChipset == NM2200) { + if (nPtr->NeoChipset == NM2200 || nPtr->NeoChipset == NM2230 + || nPtr->NeoChipset == NM2360 || nPtr->NeoChipset == NM2380) { VGAwCR(0x70, restore->VerticalExt); } - - + vgaHWProtect(pScrn, FALSE); /* Turn on screen */ } @@ -2077,18 +2622,20 @@ neoModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode) { NEOPtr nPtr = NEOPTR(pScrn); NEOACLPtr nAcl = NEOACLPTR(pScrn); - int i; int hoffset, voffset; vgaHWPtr hwp = VGAHWPTR(pScrn); NeoRegPtr NeoNew = &nPtr->NeoModeReg; vgaRegPtr NeoStd = &hwp->ModeReg; - + Bool noLcdStretch = nPtr->noLcdStretch; + int clockMul = 1; + neoUnlock(pScrn); /* * This will allocate the datastructure and initialize all of the * generic VGA registers. */ + if (!vgaHWInit(pScrn, mode)) return(FALSE); @@ -2104,43 +2651,23 @@ neoModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode) */ NeoStd->Attribute[16] = 0x01; - switch (pScrn->bitsPerPixel) { + switch (pScrn->depth) { case 8 : NeoStd->CRTC[0x13] = pScrn->displayWidth >> 3; NeoNew->ExtCRTOffset = pScrn->displayWidth >> 11; NeoNew->ExtColorModeSelect = 0x11; break; case 15 : + NeoNew->ExtColorModeSelect = 0x12; + NeoStd->CRTC[0x13] = pScrn->displayWidth >> 2; + NeoNew->ExtCRTOffset = pScrn->displayWidth >> 10; + break; case 16 : - if ((pScrn->weight.red == 5) && - (pScrn->weight.green == 5) && - (pScrn->weight.blue == 5)) { - /* 15bpp */ - for (i = 0; i < 64; i++) { - NeoStd->DAC[i*3+0] = i << 1; - NeoStd->DAC[i*3+1] = i << 1; - NeoStd->DAC[i*3+2] = i << 1; - } - NeoNew->ExtColorModeSelect = 0x12; - } else { - /* 16bpp */ - for (i = 0; i < 64; i++) { - NeoStd->DAC[i*3+0] = i << 1; - NeoStd->DAC[i*3+1] = i; - NeoStd->DAC[i*3+2] = i << 1; - } - NeoNew->ExtColorModeSelect = 0x13; - } - /* 15bpp & 16bpp */ + NeoNew->ExtColorModeSelect = 0x13; NeoStd->CRTC[0x13] = pScrn->displayWidth >> 2; NeoNew->ExtCRTOffset = pScrn->displayWidth >> 10; break; case 24 : - for (i = 0; i < 256; i++) { - NeoStd->DAC[i*3+0] = i; - NeoStd->DAC[i*3+1] = i; - NeoStd->DAC[i*3+2] = i; - } NeoStd->CRTC[0x13] = (pScrn->displayWidth * 3) >> 3; NeoNew->ExtCRTOffset = (pScrn->displayWidth * 3) >> 11; NeoNew->ExtColorModeSelect = 0x14; @@ -2157,7 +2684,7 @@ neoModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode) | (((mode->CrtcVSyncStart) & 0x400) >> 8 ) | (((mode->CrtcVSyncStart) & 0x400) >> 7 ); - /* Disable read/write bursts if requested. */ + /* Fast write bursts on unless disabled. */ if (nPtr->onPciBurst) { NeoNew->SysIfaceCntl1 = 0x30; } else { @@ -2180,12 +2707,18 @@ neoModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode) NeoNew->PanelDispCntlReg1 |= 0x01; } +#if 0 + /* + * This was replaced: if no devices are specified take the + * probed settings. If the probed settings are bogus fallback + * to internal only. + */ /* If the user did not specify any display devices, then... */ if (NeoNew->PanelDispCntlReg1 == 0x00) { /* Default to internal (i.e., LCD) only. */ NeoNew->PanelDispCntlReg1 |= 0x02; } - +#endif /* If we are using a fixed mode, then tell the chip we are. */ switch (mode->HDisplay) { case 1280: @@ -2225,15 +2758,23 @@ neoModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode) */ NeoNew->PanelDispCntlReg2 = 0x00; NeoNew->PanelDispCntlReg3 = 0x00; - if ((!nPtr->noLcdStretch) && + nAcl->NoCursorMode = FALSE; + + if ((!noLcdStretch) && (NeoNew->PanelDispCntlReg1 & 0x02)) { if (mode->HDisplay == nPtr->NeoPanelWidth) { /* + * Don't disable the flag. It will be needed if another mode + * is selected. + */ + /* * No stretching required when the requested display width * equals the panel width. */ - if (nPtr->NeoHWCursorInitialized) nAcl->UseHWCursor = TRUE; + xf86DrvMsg(pScrn->scrnIndex,X_INFO,"Stretching disabled\n"); + noLcdStretch = TRUE; } else { + switch (mode->HDisplay) { case 320 : /* Needs testing. KEM -- 24 May 98 */ case 400 : /* Needs testing. KEM -- 24 May 98 */ @@ -2241,20 +2782,20 @@ neoModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode) case 800 : case 1024 : NeoNew->PanelDispCntlReg2 |= 0xC6; - if (nPtr->NeoHWCursorInitialized) nAcl->UseHWCursor = FALSE; + nAcl->NoCursorMode = TRUE; break; default : /* No stretching in these modes. */ - if (nPtr->NeoHWCursorInitialized) nAcl->UseHWCursor = TRUE; + xf86DrvMsg(pScrn->scrnIndex,X_INFO, + "Stretching disabled not supported in this mode\n"); + noLcdStretch = TRUE; break; } } } else if (mode->Flags & V_DBLSCAN) { - if (nPtr->NeoHWCursorInitialized) nAcl->UseHWCursor = FALSE; - } else { - if (nPtr->NeoHWCursorInitialized) nAcl->UseHWCursor = TRUE; + nAcl->NoCursorMode = TRUE; } - + /* * If the screen is to be centerd, turn on the centering for the * various modes. @@ -2269,32 +2810,57 @@ neoModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode) NeoNew->PanelHorizCenterReg3 = 0x00; NeoNew->PanelHorizCenterReg4 = 0x00; NeoNew->PanelHorizCenterReg5 = 0x00; - + if (nPtr->lcdCenter && (NeoNew->PanelDispCntlReg1 & 0x02)) { + Bool doCenter = FALSE; + + hoffset = 0; + voffset = 0; if (mode->HDisplay == nPtr->NeoPanelWidth) { /* * No centering required when the requested display width * equals the panel width. */ } else { - NeoNew->PanelDispCntlReg2 |= 0x01; NeoNew->PanelDispCntlReg3 |= 0x10; - - /* Calculate the horizontal and vertical offsets. */ - if (nPtr->noLcdStretch) { - hoffset = ((nPtr->NeoPanelWidth - mode->HDisplay) >> 4) - 1; - voffset = ((nPtr->NeoPanelHeight - mode->VDisplay) >> 1) - 2; + if (noLcdStretch) { + /* Calculate the horizontal offsets. */ + int HDisplay = mode->HDisplay + << ((mode->VDisplay < 480) ? 1 : 0); + hoffset = ((nPtr->NeoPanelWidth - HDisplay) >> 4) - 1; + if (mode->VDisplay <= 480) + hoffset >>= 1; + doCenter = TRUE; } else { /* Stretched modes cannot be centered. */ hoffset = 0; + } + } + if (mode->VDisplay == nPtr->NeoPanelHeight) { + /* + * No centering required when the requested display width + * equals the panel width. + */ + } else { + NeoNew->PanelDispCntlReg2 |= 0x01; + if (noLcdStretch) { + /* Calculate the vertical offsets. */ + int VDisplay = mode->VDisplay + << ((mode->Flags | V_DBLSCAN) ? 1 : 0); + voffset = ((nPtr->NeoPanelHeight - VDisplay) >> 1) - 2; + doCenter = TRUE; + } else { + /* Stretched modes cannot be centered. */ voffset = 0; } + } + if (doCenter) { switch (mode->HDisplay) { case 320 : /* Needs testing. KEM -- 24 May 98 */ - NeoNew->PanelHorizCenterReg3 = hoffset; - NeoNew->PanelVertCenterReg2 = voffset; + NeoNew->PanelHorizCenterReg3 = hoffset; + NeoNew->PanelVertCenterReg3 = voffset; break; case 400 : /* Needs testing. KEM -- 24 May 98 */ NeoNew->PanelHorizCenterReg4 = hoffset; @@ -2306,7 +2872,15 @@ neoModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode) break; case 800 : NeoNew->PanelHorizCenterReg2 = hoffset; - NeoNew->PanelVertCenterReg4 = voffset; + switch (mode->VDisplay) { + case 600: + NeoNew->PanelVertCenterReg4 = voffset; + break; + case 480: + /* Not sure if this is correct */ + NeoNew->PanelVertCenterReg3 = voffset; + break; + } break; case 1024 : NeoNew->PanelHorizCenterReg5 = hoffset; @@ -2319,13 +2893,34 @@ neoModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode) } } } + +#ifdef XvExtension + if (!noLcdStretch && + (NeoNew->PanelDispCntlReg1 & 0x02)) { + if (mode->HDisplay != nPtr->NeoPanelWidth) + nPtr->videoHZoom = (double)nPtr->NeoPanelWidth/mode->HDisplay; + if (mode->VDisplay != nPtr->NeoPanelHeight) + nPtr->videoVZoom = (double)nPtr->NeoPanelHeight/mode->VDisplay; + } else { + nPtr->videoHZoom = 1.0; + nPtr->videoVZoom = 1.0; + } +#endif + if (mode->VDisplay <= 480) { + NeoStd->Sequencer[1] |= 0x8; + clockMul = 2; + } + + NeoNew->biosMode = neoFindMode(mode->HDisplay,mode->VDisplay,pScrn->depth); + /* * New->reg should be empty. Just in * case it isn't, warn us and clear it anyway. */ if (NeoNew->reg) { - ErrorF("WARNING: Non-NULL reg in NeoInit: reg=0x%08X\n", NeoNew->reg); + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Non-NULL reg in NeoInit: reg=0x%08X\n", NeoNew->reg); xfree(NeoNew->reg); NeoNew->reg = NULL; } @@ -2334,7 +2929,7 @@ neoModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode) * Calculate the VCLK that most closely matches the requested dot * clock. */ - neoCalcVCLK(pScrn, mode->SynthClock); + neoCalcVCLK(pScrn, mode->SynthClock*clockMul); /* Since we program the clocks ourselves, always use VCLK3. */ NeoStd->MiscOutReg |= 0x0C; @@ -2379,7 +2974,8 @@ neoCalcVCLK(ScrnInfoPtr pScrn, long freq) } } - if (nPtr->NeoChipset == NM2200) { + if (nPtr->NeoChipset == NM2200 || nPtr->NeoChipset == NM2230 + || nPtr->NeoChipset == NM2360 || nPtr->NeoChipset == NM2380) { /* NOT_DONE: We are trying the full range of the 2200 clock. We should be able to try n up to 2047 */ nPtr->NeoModeReg.VCLK3NumeratorLow = n_best; @@ -2389,6 +2985,14 @@ neoCalcVCLK(ScrnInfoPtr pScrn, long freq) nPtr->NeoModeReg.VCLK3NumeratorLow = n_best | (f_best << 7); } nPtr->NeoModeReg.VCLK3Denominator = d_best; +#ifdef DEBUG + ErrorF("neoVCLK: f:%f NumLow=%i NumHi=%i Den=%i Df=%f\n", + f_target, + nPtr->NeoModeReg.VCLK3NumeratorLow, + nPtr->NeoModeReg.VCLK3NumeratorHigh, + nPtr->NeoModeReg.VCLK3Denominator, + f_best_diff); +#endif } /* @@ -2396,7 +3000,6 @@ neoCalcVCLK(ScrnInfoPtr pScrn, long freq) * * Sets VESA Display Power Management Signaling (DPMS) Mode. */ -#ifdef DPMSExtension static void NeoDisplayPowerManagementSet(ScrnInfoPtr pScrn, int PowerManagementMode, int flags) @@ -2407,7 +3010,7 @@ NeoDisplayPowerManagementSet(ScrnInfoPtr pScrn, int PowerManagementMode, unsigned char LogicPowerMgmt = 0; unsigned char LCD_on = 0; - if (pScrn->vtSema) + if (!pScrn->vtSema) return; switch (PowerManagementMode) { @@ -2441,9 +3044,8 @@ NeoDisplayPowerManagementSet(ScrnInfoPtr pScrn, int PowerManagementMode, } /* Turn the screen on/off */ - outb(0x3C4, 0x01); - SEQ01 |= inb(0x3C5) & ~0x20; - outb(0x3C5, SEQ01); + SEQ01 |= VGArSR(0x01) & ~0x20; + VGAwSR(0x01, SEQ01); /* Turn the LCD on/off */ LCD_on |= VGArGR(0x20) & ~0x02; @@ -2454,35 +3056,28 @@ NeoDisplayPowerManagementSet(ScrnInfoPtr pScrn, int PowerManagementMode, LogicPowerMgmt |= VGArGR(0x01) & ~0xF0; VGAwGR(0x01,LogicPowerMgmt); } -#endif static unsigned int neo_ddc1Read(ScrnInfoPtr pScrn) { register vgaHWPtr hwp = VGAHWPTR(pScrn); -#if 0 - register unsigned int ST01reg = ((NEOPtr)pScrn->driverPrivate)->vgaIOBase - + 0x0A; -#endif register unsigned int tmp; -#if 0 - while(inb(ST01reg)&0x8){}; - while(!(inb(ST01reg)&0x8)) {}; -#endif + /* This needs to be investigated: we may have to swap this around */ + while (!(hwp->readST01(hwp)&0x8)) {}; while (hwp->readST01(hwp)&0x8) {}; - while (!hwp->readST01(hwp)&0x8) {}; tmp = (VGArGR(0xA1) & 0x08); return (tmp); } -static void +static xf86MonPtr neo_ddc1(int scrnIndex) { vgaHWPtr hwp = VGAHWPTR(xf86Screens[scrnIndex]); unsigned int reg1, reg2, reg3; + xf86MonPtr ret; /* initialize chipset */ reg1 = VGArCR(0x21); @@ -2491,36 +3086,120 @@ neo_ddc1(int scrnIndex) VGAwCR(0x21,0x00); VGAwCR(0x1D,0x01); /* some Voodoo */ VGAwGR(0xA1,0x2F); - xf86PrintEDID(xf86DoEDID_DDC1(scrnIndex,vgaHWddc1SetSpeed,neo_ddc1Read)); + ret = xf86DoEDID_DDC1(scrnIndex,vgaHWddc1SetSpeed,neo_ddc1Read); /* undo initialization */ VGAwCR(0x21,reg1); VGAwCR(0x1D,reg2); + return ret; } -static void -neoRefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox) +static Bool +neoDoDDC1(ScrnInfoPtr pScrn) { - NEOPtr nPtr = NEOPTR(pScrn); - int width, height, Bpp, FBPitch; - unsigned char *src = NULL, *dst = NULL; - - Bpp = pScrn->bitsPerPixel >> 3; - FBPitch = pScrn->displayWidth * Bpp; - - while(num--) { - width = (pbox->x2 - pbox->x1) * Bpp; - height = pbox->y2 - pbox->y1; - src = nPtr->ShadowPtr + (pbox->y1 * nPtr->ShadowPitch) + - (pbox->x1 * Bpp); - dst = nPtr->NeoFbBase + (pbox->y1 * FBPitch) + (pbox->x1 * Bpp); - - while(height--) { - memcpy(dst, src, width); - dst += FBPitch; - src += nPtr->ShadowPitch; + Bool ret = FALSE; + vgaHWPtr hwp = VGAHWPTR(pScrn); + + VGAwGR(0x09,0x26); + ret = xf86SetDDCproperties(pScrn, + xf86PrintEDID(neo_ddc1(pScrn->scrnIndex))); + VGAwGR(0x09,0x00); + + return ret; +} + +static Bool +neoDoDDC2(ScrnInfoPtr pScrn) +{ + NEOPtr nPtr = NEOPTR(pScrn); + vgaHWPtr hwp = VGAHWPTR(pScrn); + Bool ret = FALSE; + + VGAwGR(0x09,0x26); + if (xf86LoadSubModule(pScrn, "i2c")) { + xf86LoaderReqSymLists(i2cSymbols, NULL); + if (neo_I2CInit(pScrn)) { + ret = xf86SetDDCproperties(pScrn,xf86PrintEDID(xf86DoEDID_DDC2( + pScrn->scrnIndex,nPtr->I2C))); } - - pbox++; } + VGAwGR(0x09,0x00); + + return ret; } +static Bool +neoDoDDCVBE(ScrnInfoPtr pScrn) +{ + NEOPtr nPtr = NEOPTR(pScrn); + vgaHWPtr hwp = VGAHWPTR(pScrn); + vbeInfoPtr pVbe; + Bool ret = FALSE; + + VGAwGR(0x09,0x26); + if (xf86LoadSubModule(pScrn, "vbe")) { + xf86LoaderReqSymLists(vbeSymbols, NULL); + if ((pVbe = VBEInit(NULL,nPtr->pEnt->index))) { + ret = xf86SetDDCproperties( + pScrn,xf86PrintEDID(vbeDoEDID(pVbe,NULL))); + vbeFree(pVbe); + } + } + VGAwGR(0x09,0x00); + return ret; +} + +static int +neoFindMode(int xres, int yres, int depth) +{ + int xres_s; + int i, size; + biosMode *mode; + + switch (depth) { + case 8: + size = sizeof(bios8) / sizeof(biosMode); + mode = bios8; + break; + case 15: + size = sizeof(bios15) / sizeof(biosMode); + mode = bios15; + break; + case 16: + size = sizeof(bios16) / sizeof(biosMode); + mode = bios16; + break; + case 24: + size = sizeof(bios24) / sizeof(biosMode); + mode = bios24; + break; + default: + return 0; + } + + for (i = 0; i < size; i++) { + if (xres <= mode[i].x_res) { + xres_s = mode[i].x_res; + for (; i < size; i++) { + if (mode[i].x_res != xres_s) + return mode[i-1].mode; + if (yres <= mode[i].y_res) + return mode[i].mode; + } + } + } + return mode[size - 1].mode; + +} + +static void +neoProbeDDC(ScrnInfoPtr pScrn, int index) +{ + vbeInfoPtr pVbe; + + if (xf86LoadSubModule(pScrn, "vbe")) { + if ((pVbe = VBEInit(NULL,index))) { + ConfiguredMonitor = vbeDoEDID(pVbe, NULL); + vbeFree(pVbe); + } + } +} diff --git a/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_i2c.c b/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_i2c.c index e7f74f327..8a297868d 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_i2c.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_i2c.c @@ -22,14 +22,14 @@ 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. **********************************************************************/ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_i2c.c,v 1.2 1999/06/27 14:08:10 dawes Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_i2c.c,v 1.4 2002/09/16 18:05:58 eich Exp $ */ /* * The original Precision Insight driver for * XFree86 v.3.3 has been sponsored by Red Hat. * * Authors: - * Jens Owen (jens@precisioninsight.com) + * Jens Owen (jens@tungstengraphics.com) * Kevin E. Martin (kevin@precisioninsight.com) * * Port to Xfree86 v.4.0 @@ -79,8 +79,8 @@ neo_I2CInit(ScrnInfoPtr pScrn) NEOPtr pNeo = NEOPTR(pScrn); I2CBusPtr I2CPtr; - I2CPtr = xf86CreateI2CBusRec(); + if(!I2CPtr) return FALSE; pNeo->I2C = I2CPtr; @@ -89,6 +89,9 @@ neo_I2CInit(ScrnInfoPtr pScrn) I2CPtr->scrnIndex = pScrn->scrnIndex; I2CPtr->I2CPutBits = neo_I2CPutBits; I2CPtr->I2CGetBits = neo_I2CGetBits; + /* increase these as the defaults are too low */ + I2CPtr->RiseFallTime = 2; + I2CPtr->HoldTime = 40; if (!xf86I2CBusInit(I2CPtr)) return FALSE; diff --git a/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_macros.h b/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_macros.h index fdb4d44c1..abc08f100 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_macros.h +++ b/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_macros.h @@ -29,7 +29,7 @@ CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * XFree86 v.3.3 has been sponsored by Red Hat. * * Authors: - * Jens Owen (jens@precisioninsight.com) + * Jens Owen (jens@tungstengraphics.com) * Kevin E. Martin (kevin@precisioninsight.com) * * Port to Xfree86 v.4.0 diff --git a/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_reg.h b/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_reg.h index 676719f75..fddc016c0 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_reg.h +++ b/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_reg.h @@ -29,7 +29,7 @@ CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * XFree86 v.3.3 has been sponsored by Red Hat. * * Authors: - * Jens Owen (jens@precisioninsight.com) + * Jens Owen (jens@tungstengraphics.com) * Kevin E. Martin (kevin@precisioninsight.com) * * Port to Xfree86 v.4.0 |