diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/newport.h | 128 | ||||
-rw-r--r-- | src/newport_cmap.c | 120 | ||||
-rw-r--r-- | src/newport_cursor.c | 165 | ||||
-rw-r--r-- | src/newport_driver.c | 856 | ||||
-rw-r--r-- | src/newport_regs.c | 235 | ||||
-rw-r--r-- | src/newport_regs.h | 457 | ||||
-rw-r--r-- | src/newport_shadow.c | 89 |
7 files changed, 2050 insertions, 0 deletions
diff --git a/src/newport.h b/src/newport.h new file mode 100644 index 0000000..ee71736 --- /dev/null +++ b/src/newport.h @@ -0,0 +1,128 @@ +/* + * Id: newport.h,v 1.4 2000/11/29 20:58:10 agx Exp $ + */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/newport/newport.h,v 1.10 2002/12/10 04:03:00 dawes Exp $ */ + +#ifndef __NEWPORT_H__ +#define __NEWPORT_H__ + +/* + * All drivers should include these: + */ +#include "xf86.h" +#include "xf86_OSproc.h" +#include "xf86_ansic.h" +#include "compiler.h" +#include "xf86Resources.h" + +#include "xf86cmap.h" + +/* xaa & hardware cursor */ +#include "xaa.h" +#include "xf86Cursor.h" + +/* register definitions of the Newport card */ +#include "newport_regs.h" + +#define NEWPORT_BASE_ADDR0 0x1f0f0000 +#define NEWPORT_BASE_OFFSET 0x00400000 +#define NEWPORT_MAX_BOARDS 4 + +#if 0 +# define DEBUG 1 +#endif + +#ifdef DEBUG +# define TRACE_ENTER(str) ErrorF("newport: " str " %d\n",pScrn->scrnIndex) +# define TRACE_EXIT(str) ErrorF("newport: " str " done\n") +# define TRACE(str) ErrorF("newport trace: " str "\n") +#else +# define TRACE_ENTER(str) +# define TRACE_EXIT(str) +# define TRACE(str) +#endif + +typedef struct { + unsigned busID; + int bitplanes; + /* revision numbers of the various pieces of silicon */ + unsigned int board_rev, cmap_rev, rex3_rev, xmap9_rev, bt445_rev; + /* shadow copies of frequently used registers */ + NewportRegsPtr pNewportRegs; /* Pointer to REX3 registers */ + npireg_t drawmode1; /* REX3 drawmode1 common to all drawing operations */ + CARD16 vc2ctrl; /* VC2 control register */ + + /* ShadowFB stuff: */ + CARD32* ShadowPtr; + unsigned long int ShadowPitch; + unsigned int Bpp; /* Bytes per pixel */ + + /* HWCursour stuff: */ + Bool hwCursor; + xf86CursorInfoPtr CursorInfoRec; + CARD16 curs_cmap_base; /* MSB of the cursor's cmap */ + + /* wrapped funtions: */ + CloseScreenProcPtr CloseScreen; + + /* newport register backups: */ + npireg_t txt_drawmode0; /* Rex3 drawmode0 register */ + npireg_t txt_drawmode1; /* Rex3 drawmode1 register */ + npireg_t txt_wrmask; /* Rex3 write mask register */ + npireg_t txt_smask1x; /* Rex3 screen mask 1 registers */ + npireg_t txt_smask1y; + npireg_t txt_smask2x; /* Rex3 screen mask 2 registers */ + npireg_t txt_smask2y; + npireg_t txt_clipmode; /* Rex3 clip mode register */ + + CARD16 txt_vc2ctrl; /* VC2 control register */ + CARD16 txt_vc2cur_x; /* VC2 hw cursor x location */ + CARD16 txt_vc2cur_y; /* VC2 hw cursor x location */ + CARD32 txt_vc2cur_data[64]; /* VC2 hw cursor glyph data */ + + CARD8 txt_xmap9_cfg0; /* 0. Xmap9's control register */ + CARD8 txt_xmap9_cfg1; /* 1. Xmap9's control register */ + CARD8 txt_xmap9_ccmsb; /* cursor cmap msb */ + CARD8 txt_xmap9_mi; /* Xmap9s' mode index register */ + CARD32 txt_xmap9_mod0; /* Xmap9s' mode 0 register */ + + LOCO txt_colormap[256]; + + OptionInfoPtr Options; +} NewportRec, *NewportPtr; + +#define NEWPORTPTR(p) ((NewportPtr)((p)->driverPrivate)) +#define NEWPORTREGSPTR(p) ((NEWPORTPTR(p))->pNewportRegs) + +/* Newport_regs.c */ +unsigned short NewportVc2Get(NewportRegsPtr, unsigned char vc2Ireg); +void NewportVc2Set(NewportRegsPtr pNewportRegs, unsigned char vc2Ireg, unsigned short val); +void NewportWait(NewportRegsPtr pNewportRegs); +void NewportBfwait(NewportRegsPtr pNewportRegs); +void NewportXmap9SetModeRegister(NewportRegsPtr pNewportRegs, CARD8 address, CARD32 mode); +CARD32 NewportXmap9GetModeRegister(NewportRegsPtr pNewportRegs, unsigned chip, CARD8 address); +void NewportBackupRex3( ScrnInfoPtr pScrn); +void NewportRestoreRex3( ScrnInfoPtr pScrn); +void NewportBackupXmap9s( ScrnInfoPtr pScrn); +void NewportRestoreXmap9s( ScrnInfoPtr pScrn); +void NewportBackupVc2( ScrnInfoPtr pScrn); +void NewportRestoreVc2( ScrnInfoPtr pScrn); +void NewportBackupVc2Cursor( ScrnInfoPtr pScrn); +void NewportRestoreVc2Cursor( ScrnInfoPtr pScrn); + +/* newort_cmap.c */ +void NewportLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices, + LOCO* colors, VisualPtr pVisual); +void NewportRestorePalette(ScrnInfoPtr pScrn); +void NewportBackupPalette(ScrnInfoPtr pScrn); +void NewportCmapSetRGB( NewportRegsPtr pNewportRegs, unsigned short addr, LOCO color); + +/* newport_shadow.c */ +void NewportRefreshArea8(ScrnInfoPtr pScrn, int num, BoxPtr pbox); +void NewportRefreshArea24(ScrnInfoPtr pScrn, int num, BoxPtr pbox); + +/* newport_cursor.c */ +Bool NewportHWCursorInit(ScreenPtr pScreen); +void NewportLoadCursorImage(ScrnInfoPtr pScrn, unsigned char *bits); + +#endif /* __NEWPORT_H__ */ diff --git a/src/newport_cmap.c b/src/newport_cmap.c new file mode 100644 index 0000000..8052bdb --- /dev/null +++ b/src/newport_cmap.c @@ -0,0 +1,120 @@ +/* + * Id: newport_cmap.c,v 1.1 2000/11/29 20:58:10 agx Exp $ + */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/newport/newport_cmap.c,v 1.3 2002/12/10 04:03:00 dawes Exp $ */ + +#include "newport.h" + +#ifndef USEFIFOWAIT +#define USEFIFOWAIT 0 +#endif + +static void NewportCmapGetRGB( NewportRegsPtr pNewportRegs, unsigned short addr, LOCO *color); +#if USEFIFOWAIT +static void NewportCmapFifoWait( NewportRegsPtr pNewportRegs); +#endif + +/* Load a colormap into the hardware */ +void NewportLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices, \ + LOCO* colors, VisualPtr pVisual) +{ + int i,index; + NewportRegsPtr pNewportRegs = NEWPORTPTR(pScrn)->pNewportRegs; + + for(i = 0; i < numColors; i++) { + index=indices[i]; + NewportBfwait(pNewportRegs); + NewportCmapSetRGB(pNewportRegs, index, colors[index]); + } +} + +void NewportBackupPalette(ScrnInfoPtr pScrn) +{ + int i; + NewportPtr pNewport = NEWPORTPTR(pScrn); + + NewportWait(pNewport->pNewportRegs); + for(i = 0; i < 256; i++) { + NewportCmapGetRGB(pNewport->pNewportRegs, i, &(pNewport->txt_colormap[i])); + } +} + +#ifdef linux +/* stolen from kernel :) */ +static unsigned char color_table[] = { 0, 4, 2, 6, 1, 5, 3, 7, + 8,12,10,14, 9,13,11,15 }; + +/* the default colour table, for VGA+ colour systems */ +static int default_red[] = {0x00,0xaa,0x00,0xaa,0x00,0xaa,0x00,0xaa, + 0x55,0xff,0x55,0xff,0x55,0xff,0x55,0xff}; +static int default_grn[] = {0x00,0x00,0xaa,0x55,0x00,0x00,0xaa,0xaa, + 0x55,0x55,0xff,0xff,0x55,0x55,0xff,0xff}; +static int default_blu[] = {0x00,0x00,0x00,0x00,0xaa,0xaa,0xaa,0xaa, + 0x55,0x55,0x55,0x55,0xff,0xff,0xff,0xff}; +#endif + +/* restore the default colormap */ +void NewportRestorePalette(ScrnInfoPtr pScrn) +{ + int i; + NewportPtr pNewport = NEWPORTPTR(pScrn); + +#ifdef linux + for (i = 0; i < 16; i++) { + pNewport->txt_colormap[color_table[i]].red = default_red[i]; + pNewport->txt_colormap[color_table[i]].green = default_grn[i]; + pNewport->txt_colormap[color_table[i]].blue = default_blu[i]; + } +#endif + for(i = 0; i < 256; i++) { + NewportCmapSetRGB(pNewport->pNewportRegs, i, pNewport->txt_colormap[i]); + } +} + +#if USEFIFOWAIT +/* wait 'til cmap fifo is completely empty */ +static void NewportCmapFifoWait(NewportRegsPtr pNewportRegs) +{ + while(1) { + pNewportRegs->set.dcbmode = (NPORT_DMODE_ACM0 | NCMAP_PROTOCOL | + NCMAP_REGADDR_SREG | NPORT_DMODE_W1); + if(!(pNewportRegs->set.dcbdata0.bytes.b3 & 4)) + break; + } +} +#endif + +/* set the colormap entry at addr to color */ +void NewportCmapSetRGB( NewportRegsPtr pNewportRegs, unsigned short addr, LOCO color) +{ + NewportWait(pNewportRegs); /* this one should not be necessary */ + NewportBfwait(pNewportRegs); + pNewportRegs->set.dcbmode = (NPORT_DMODE_ACMALL | NCMAP_PROTOCOL | + NPORT_DMODE_SENDIAN | NPORT_DMODE_ECINC | + NCMAP_REGADDR_AREG | NPORT_DMODE_W2); + pNewportRegs->set.dcbdata0.hwords.s1 = addr; + pNewportRegs->set.dcbmode = (NPORT_DMODE_ACMALL | NCMAP_PROTOCOL | + NCMAP_REGADDR_PBUF | NPORT_DMODE_W3); + pNewportRegs->set.dcbdata0.all = (color.red << 24) | + (color.green << 16) | + (color.blue << 8); +} + +/* get the colormap entry at addr */ +static void NewportCmapGetRGB( NewportRegsPtr pNewportRegs, unsigned short addr, LOCO* color) +{ + npireg_t tmp; + + NewportBfwait(pNewportRegs); + pNewportRegs->set.dcbmode = (NPORT_DMODE_ACM0 | NCMAP_PROTOCOL | + NPORT_DMODE_SENDIAN | NPORT_DMODE_ECINC | + NCMAP_REGADDR_AREG | NPORT_DMODE_W2); + pNewportRegs->set.dcbdata0.hwords.s1 = addr; + pNewportRegs->set.dcbmode = (NPORT_DMODE_ACM0 | NCMAP_PROTOCOL | + NCMAP_REGADDR_PBUF | NPORT_DMODE_W3); + tmp = pNewportRegs->set.dcbdata0.all; + color->red = (tmp >> 24) & 0xff; + color->green = (tmp >> 16) & 0xff; + color->blue = (tmp >> 8) & 0xff; +} + diff --git a/src/newport_cursor.c b/src/newport_cursor.c new file mode 100644 index 0000000..b5328f8 --- /dev/null +++ b/src/newport_cursor.c @@ -0,0 +1,165 @@ +/* + * newport_cursor.c + */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/newport/newport_cursor.c,v 1.1 2002/12/10 04:03:00 dawes Exp $ */ + +#include "newport.h" +#include "cursorstr.h" + +#include "servermd.h" + +#define MAX_CURS 32 + +static void NewportShowCursor(ScrnInfoPtr pScrn); +static void NewportHideCursor(ScrnInfoPtr pScrn); +static void NewportSetCursorPosition(ScrnInfoPtr pScrn, int x, int y); +static void NewportSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg); +/* static void NewportLoadCursorImage(ScrnInfoPtr pScrn, unsigned char *bits); */ +static unsigned char* NewportRealizeCursor(xf86CursorInfoPtr infoPtr, CursorPtr pCurs); + +Bool +NewportHWCursorInit(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + NewportPtr pNewport = NEWPORTPTR(pScrn); + NewportRegsPtr pNewportRegs = NEWPORTREGSPTR(pScrn); + xf86CursorInfoPtr infoPtr; + CARD16 tmp; + + infoPtr = xf86CreateCursorInfoRec(); + if(!infoPtr) + return FALSE; + + pNewport->CursorInfoRec = infoPtr; + infoPtr->MaxWidth = MAX_CURS; + infoPtr->MaxHeight = MAX_CURS; + infoPtr->Flags = HARDWARE_CURSOR_TRUECOLOR_AT_8BPP; + + infoPtr->SetCursorColors = NewportSetCursorColors; + infoPtr->SetCursorPosition = NewportSetCursorPosition; + infoPtr->LoadCursorImage = NewportLoadCursorImage; + infoPtr->HideCursor = NewportHideCursor; + infoPtr->ShowCursor = NewportShowCursor; + infoPtr->RealizeCursor = NewportRealizeCursor; + infoPtr->UseHWCursor = NULL; + + /* enable cursor funtion in shadow register */ + pNewport->vc2ctrl |= VC2_CTRL_ECURS; + /* enable glyph cursor, maximum size is 32x32x2 */ + pNewport->vc2ctrl &= ~( VC2_CTRL_ECG64 | VC2_CTRL_ECCURS); + /* setup hw cursors cmap base address */ + NewportBfwait(pNewportRegs); + pNewportRegs->set.dcbmode = (DCB_XMAP0 | R_DCB_XMAP9_PROTOCOL | + XM9_CRS_CURS_CMAP_MSB | NPORT_DMODE_W1 ); + tmp = pNewportRegs->set.dcbdata0.bytes.b3; +#if 0 + /* The docs say we can change base address of the cursors + * cmap entries, but it doesn't work. */ + tmp++; +#endif + pNewportRegs->set.dcbmode = (DCB_XMAP0 | W_DCB_XMAP9_PROTOCOL | + XM9_CRS_CURS_CMAP_MSB | NPORT_DMODE_W1 ); + pNewportRegs->set.dcbdata0.bytes.b3 = tmp; + pNewport->curs_cmap_base = (tmp << 5) & 0xffe0; + + return xf86InitCursor(pScreen, infoPtr); +} + + +static void NewportShowCursor(ScrnInfoPtr pScrn) +{ + NewportPtr pNewport = NEWPORTPTR(pScrn); + NewportRegsPtr pNewportRegs = NEWPORTREGSPTR(pScrn); + + pNewport->vc2ctrl |= VC2_CTRL_ECDISP; + NewportVc2Set( pNewportRegs, VC2_IREG_CONTROL, pNewport->vc2ctrl); +} + +static void NewportHideCursor(ScrnInfoPtr pScrn) +{ + NewportPtr pNewport = NEWPORTPTR(pScrn); + NewportRegsPtr pNewportRegs = NEWPORTREGSPTR(pScrn); + + pNewport->vc2ctrl &= ~VC2_CTRL_ECDISP; + NewportVc2Set( pNewportRegs, VC2_IREG_CONTROL, pNewport->vc2ctrl); +} + +static void NewportSetCursorPosition(ScrnInfoPtr pScrn, int x, int y) +{ + CARD16 x_off; + NewportRegsPtr pNewportRegs = NEWPORTREGSPTR(pScrn); + NewportPtr pNewport = NEWPORTPTR(pScrn); + + /* the docu says this should always be 31, but it isn't */ + x_off = 31; + if ( pNewport->board_rev < 6 ) + x_off = 21; + NewportVc2Set( pNewportRegs, VC2_IREG_CURSX, (CARD16) x + x_off); + NewportVc2Set( pNewportRegs, VC2_IREG_CURSY, (CARD16) y + 31); +} + +static void NewportSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg) +{ + NewportPtr pNewport = NEWPORTPTR(pScrn); + NewportRegsPtr pNewportRegs = NEWPORTREGSPTR(pScrn); + LOCO color; + + color.blue = bg & 0xff; + color.green = (bg & 0xff00) >> 8; + color.red = (bg & 0xff0000) >> 16; + NewportCmapSetRGB( pNewportRegs, pNewport->curs_cmap_base+2, color); + + color.blue = fg & 0xff; + color.green = (fg & 0xff00) >> 8; + color.red = (fg & 0xff0000) >> 16; + NewportCmapSetRGB( pNewportRegs, pNewport->curs_cmap_base+1, color); +} + +static unsigned char* NewportRealizeCursor(xf86CursorInfoPtr infoPtr, CursorPtr pCurs) +{ + int size = (infoPtr->MaxWidth * infoPtr->MaxHeight) >> 2; + CARD32 *mem, *SrcS, *SrcM, *DstS; + unsigned int i; + + if (!(mem = xcalloc(1, size))) + return NULL; + + SrcS = (CARD32*)pCurs->bits->source; + SrcM = (CARD32*)pCurs->bits->mask; + DstS = mem; + /* first color: maximum is 32*4 Bytes */ + for(i=0; i < pCurs->bits->height; i++) { + *DstS = *SrcS & *SrcM; + DstS++, SrcS++, SrcM++; + } + /* second color is the lower of mem: again 32*4 Bytes at most */ + DstS = mem + MAX_CURS; + SrcS = (CARD32*)pCurs->bits->source; + SrcM = (CARD32*)pCurs->bits->mask; + for(i=0; i < pCurs->bits->height; i++) { + *DstS = (~*SrcS) & *SrcM; + DstS++, SrcS++, SrcM++; + } + return (unsigned char*) mem; +} + +void NewportLoadCursorImage(ScrnInfoPtr pScrn, unsigned char *bits) +{ + int i; + CARD16 tmp; + NewportRegsPtr pNewportRegs = NEWPORTREGSPTR(pScrn); + + /* address of cursor data in vc2's ram */ + tmp = NewportVc2Get( pNewportRegs, VC2_IREG_CENTRY); + /* this is where we want to write to: */ + NewportVc2Set( pNewportRegs, VC2_IREG_RADDR, tmp); + pNewportRegs->set.dcbmode = (NPORT_DMODE_AVC2 | VC2_REGADDR_RAM | + NPORT_DMODE_W2 | VC2_PROTOCOL); + /* write cursor data */ + for (i = 0; i < ((MAX_CURS * MAX_CURS) >> 3); i++) { + NewportBfwait(pNewportRegs); + pNewportRegs->set.dcbdata0.hwords.s1 = *(unsigned short*)bits; + bits += sizeof(unsigned short); + } +} + diff --git a/src/newport_driver.c b/src/newport_driver.c new file mode 100644 index 0000000..e55354c --- /dev/null +++ b/src/newport_driver.c @@ -0,0 +1,856 @@ +/* + * Id: newport_driver.c,v 1.2 2000/11/29 20:58:10 agx Exp $ + * + * Driver for the SGI Indy's Newport graphics card + * + * This driver is based on the newport.c & newport_con.c kernel code + * + * (c) 2000-2002 Guido Guenther <agx@sigxcpu.org> + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is fur- + * nished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FIT- + * NESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CON- + * NECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of the XFree86 Project shall not + * be used in advertising or otherwise to promote the sale, use or other deal- + * ings in this Software without prior written authorization from the XFree86 + * Project. + * + */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/newport/newport_driver.c,v 1.24 2003/02/18 19:10:36 alanh Exp $ */ + +/* function prototypes, common data structures & generic includes */ +#include "newport.h" + +/* Drivers using the mi SW cursor need: */ +#include "mipointer.h" +/* Drivers using the mi implementation of backing store need: */ +#include "mibstore.h" +/* Drivers using the mi colourmap code need: */ +#include "micmap.h" + +/* Drivers using fb need: */ +#include "fb.h" + +/* Drivers using the shadow frame buffer need: */ +#include "shadowfb.h" + +/* Xv Extension */ +#include "xf86xv.h" +#include "Xv.h" + +#define VERSION 4000 +#define NEWPORT_NAME "NEWPORT" +#define NEWPORT_DRIVER_NAME "newport" +#define NEWPORT_MAJOR_VERSION 0 +#define NEWPORT_MINOR_VERSION 1 +#define NEWPORT_PATCHLEVEL 3 + + +/* Prototypes ------------------------------------------------------- */ +static void NewportIdentify(int flags); +static const OptionInfoRec * NewportAvailableOptions(int chipid, int busid); +static Bool NewportProbe(DriverPtr drv, int flags); +static Bool NewportPreInit(ScrnInfoPtr pScrn, int flags); +static Bool NewportScreenInit(int Index, ScreenPtr pScreen, int argc, char **argv); +static Bool NewportEnterVT(int scrnIndex, int flags); +static void NewportLeaveVT(int scrnIndex, int flags); +static Bool NewportCloseScreen(int scrnIndex, ScreenPtr pScreen); +static Bool NewportSaveScreen(ScreenPtr pScreen, int mode); +static unsigned NewportHWProbe(unsigned probedIDs[]); /* return number of found boards */ +static Bool NewportModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode); +static void NewportRestore(ScrnInfoPtr pScrn, Bool Closing); +static Bool NewportGetRec(ScrnInfoPtr pScrn); +static Bool NewportFreeRec(ScrnInfoPtr pScrn); +static Bool NewportMapRegs(ScrnInfoPtr pScrn); +static void NewportUnmapRegs(ScrnInfoPtr pScrn); +static Bool NewportProbeCardInfo(ScrnInfoPtr pScrn); +/* ------------------------------------------------------------------ */ + +DriverRec NEWPORT = { + VERSION, + NEWPORT_DRIVER_NAME, + NewportIdentify, + NewportProbe, + NewportAvailableOptions, + NULL, + 0 +}; + +/* Supported "chipsets" */ +#define CHIP_XL 0x1 + +static SymTabRec NewportChipsets[] = { + { CHIP_XL, "XL" }, + {-1, NULL } +}; + +/* List of Symbols from other modules that this module references */ + +static const char *fbSymbols[] = { + "fbPictureInit", + "fbScreenInit", + NULL +}; + +static const char *ramdacSymbols[] = { + "xf86CreateCursorInfoRec", + "xf86InitCursor", + NULL +}; + +static const char *shadowSymbols[] = { + "ShadowFBInit", + NULL +}; + +#ifdef XFree86LOADER + +static MODULESETUPPROTO(newportSetup); + +static XF86ModuleVersionInfo newportVersRec = +{ + "newport", + MODULEVENDORSTRING, + MODINFOSTRING1, + MODINFOSTRING2, + XF86_VERSION_CURRENT, + NEWPORT_MAJOR_VERSION, NEWPORT_MINOR_VERSION, NEWPORT_PATCHLEVEL, + ABI_CLASS_VIDEODRV, + ABI_VIDEODRV_VERSION, + MOD_CLASS_VIDEODRV, + {0,0,0,0} +}; + +XF86ModuleData newportModuleData = { &newportVersRec, newportSetup, NULL }; + +static pointer +newportSetup(pointer module, pointer opts, int *errmaj, int *errmin) +{ + static Bool setupDone = FALSE; + +/* This module should be loaded only once, but check to be sure. */ + if (!setupDone) { + /* + * Modules that this driver always requires may be loaded + * here by calling LoadSubModule(). + */ + setupDone = TRUE; + xf86AddDriver(&NEWPORT, module, 0); + + /* + * Tell the loader about symbols from other modules that this module + * might refer to. + * + */ + LoaderRefSymLists( fbSymbols, ramdacSymbols, shadowSymbols, NULL); + + + /* + * The return value must be non-NULL on success even though + * there is no TearDownProc. + */ + return (pointer)1; + } else { + if (errmaj) *errmaj = LDR_ONCEONLY; + return NULL; + } +} + +#endif /* XFree86LOADER */ + +typedef enum { + OPTION_BITPLANES, + OPTION_BUS_ID, + OPTION_HWCURSOR +} NewportOpts; + +/* Supported options */ +static const OptionInfoRec NewportOptions [] = { + { OPTION_BITPLANES, "bitplanes", OPTV_INTEGER, {0}, FALSE }, + { OPTION_BUS_ID, "BusID", OPTV_INTEGER, {0}, FALSE }, + { OPTION_HWCURSOR, "HWCursor", OPTV_BOOLEAN, {0}, FALSE }, + { -1, NULL, OPTV_NONE, {0}, FALSE } +}; + +/* ------------------------------------------------------------------ */ + +static Bool +NewportGetRec(ScrnInfoPtr pScrn) +{ + NewportPtr pNewport; + if (pScrn->driverPrivate != NULL) + return TRUE; + pScrn->driverPrivate = xnfcalloc(sizeof(NewportRec), 1); + + pNewport = NEWPORTPTR(pScrn); + pNewport->pNewportRegs = NULL; + + return TRUE; +} + +static Bool +NewportFreeRec(ScrnInfoPtr pScrn) +{ + if (pScrn->driverPrivate == NULL) + return TRUE; + xfree(pScrn->driverPrivate); + pScrn->driverPrivate = NULL; + return TRUE; +} + +static void +NewportIdentify(int flags) +{ + xf86PrintChipsets( NEWPORT_NAME, "driver for Newport Graphics Card", NewportChipsets); +} + +static Bool +NewportProbe(DriverPtr drv, int flags) +{ + int numDevSections, numUsed, i, j, busID; + Bool foundScreen = FALSE; + GDevPtr *devSections; + GDevPtr dev = NULL; + resRange range[] = { {ResExcMemBlock ,0,0}, _END }; + unsigned probedIDs[NEWPORT_MAX_BOARDS]; + memType base; + + if ((numDevSections = xf86MatchDevice(NEWPORT_DRIVER_NAME, &devSections)) <= 0) + return FALSE; + numUsed = NewportHWProbe(probedIDs); + if ( numUsed <= 0 ) + return FALSE; + + if(flags & PROBE_DETECT) + foundScreen = TRUE; + else { + for (i = 0; i < numDevSections; i++) { + dev = devSections[i]; + busID = xf86SetIntOption(dev->options, "BusID", 0); + + for( j = 0; j < numUsed; j++) { + if ( busID == probedIDs[j] ) { + int entity; + ScrnInfoPtr pScrn = NULL; + + /* This is a hack because don't have the RAC info(and don't want it). + * Set it as an ISA entity to get the entity field set up right. + */ + entity = xf86ClaimIsaSlot(drv, 0, dev, TRUE); + base = (NEWPORT_BASE_ADDR0 + + busID * NEWPORT_BASE_OFFSET); + RANGE(range[0], base, base + sizeof(NewportRegs),\ + ResExcMemBlock); + pScrn = xf86ConfigIsaEntity(pScrn, 0, entity, NULL, range, \ + NULL, NULL, NULL, NULL); + /* Allocate a ScrnInfoRec */ + pScrn->driverVersion = VERSION; + pScrn->driverName = NEWPORT_DRIVER_NAME; + pScrn->name = NEWPORT_NAME; + pScrn->Probe = NewportProbe; + pScrn->PreInit = NewportPreInit; + pScrn->ScreenInit = NewportScreenInit; + pScrn->EnterVT = NewportEnterVT; + pScrn->LeaveVT = NewportLeaveVT; + pScrn->driverPrivate = (void*)(long)busID; + foundScreen = TRUE; + break; + } + } + } + } + xfree(devSections); + return foundScreen; +} + +/* most of this is from DESIGN.TXT s20.3.6 */ +static Bool +NewportPreInit(ScrnInfoPtr pScrn, int flags) +{ + int i, busID; + NewportPtr pNewport; + MessageType from; + ClockRangePtr clockRanges; + + if (flags & PROBE_DETECT) return FALSE; + + if (pScrn->numEntities != 1) + return FALSE; + + busID = (long)(pScrn->driverPrivate); + pScrn->driverPrivate = NULL; + + /* Fill in the monitor field */ + pScrn->monitor = pScrn->confScreen->monitor; + + if (!xf86SetDepthBpp(pScrn, 8, 8, 8, + Support24bppFb | SupportConvert32to24 | + PreferConvert32to24 )) + return FALSE; + + switch( pScrn->depth ) { + /* check if the returned depth is one we support */ + case 8: + case 24: + /* OK */ + break; + default: + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Given depth (%d) is not supported by Newport driver\n", + pScrn->depth); + return FALSE; + } + xf86PrintDepthBpp(pScrn); + + /* Set bits per RGB for 8bpp */ + if( pScrn->depth == 8) + pScrn->rgbBits = 8; + + /* Set Default Weight */ + if( pScrn->depth > 8 ) { + rgb zeros = {0, 0, 0}; + if (!xf86SetWeight(pScrn, zeros, zeros)) + return FALSE; + } + + if (!xf86SetDefaultVisual(pScrn, -1)) { + return FALSE; + } else { + 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); + return FALSE; + } + } + + { /* Set default Gamma */ + Gamma zeros = {0.0, 0.0, 0.0}; + + if (!xf86SetGamma(pScrn, zeros)) { + return FALSE; + } + } + + /* Allocate the NewportRec driverPrivate */ + if (!NewportGetRec(pScrn)) { + return FALSE; + } + pNewport = NEWPORTPTR(pScrn); + pNewport->busID = busID; + + /* We use a programmable clock */ + pScrn->progClock = TRUE; + + /* Fill in pScrn->options) */ + xf86CollectOptions(pScrn, NULL); + if (!(pNewport->Options = xalloc(sizeof(NewportOptions)))) + return FALSE; + memcpy(pNewport->Options, NewportOptions, sizeof(NewportOptions)); + xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, pNewport->Options); + + /* Set fields in ScreenInfoRec && NewportRec */ + pScrn->videoRam = 1280 * (pScrn->bitsPerPixel >> 3); + + /* get revisions of REX3, etc. */ + if( ! NewportMapRegs(pScrn)) + return FALSE; + NewportProbeCardInfo(pScrn); + NewportUnmapRegs(pScrn); + + from=X_PROBED; + xf86DrvMsg(pScrn->scrnIndex, from, + "Newport Graphics Revisions: Board: %d, Rex3: %c, Cmap: %c, Xmap9: %c\n", + pNewport->board_rev, pNewport->rex3_rev, + pNewport->cmap_rev, pNewport->xmap9_rev); + + if ( (xf86GetOptValInteger(pNewport->Options, OPTION_BITPLANES, &pNewport->bitplanes))) + from = X_CONFIG; + xf86DrvMsg(pScrn->scrnIndex, from, "Newport has %d bitplanes\n", pNewport->bitplanes); + + if ( pScrn->depth > pNewport->bitplanes ) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, \ + "Display depth(%d) > number of bitplanes on Newport board(%d)\n", \ + pScrn->depth, pNewport->bitplanes); + return FALSE; + } + if ( ( pNewport->bitplanes != 8 ) && ( pNewport->bitplanes != 24 ) ) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, \ + "Number of bitplanes on newport must be either 8 or 24 not %d\n", \ + pNewport->bitplanes); + return FALSE; + } + + from=X_DEFAULT; + pNewport->hwCursor = TRUE; + if (xf86GetOptValBool(pNewport->Options, OPTION_HWCURSOR, &pNewport->hwCursor)) + from = X_CONFIG; + xf86DrvMsg(pScrn->scrnIndex, from, "Using %s cursor\n", + pNewport->hwCursor ? "HW" : "SW"); + + /* Set up clock ranges that are alway ok */ + /* XXX: Use information from VC2 here */ + clockRanges = xnfcalloc(sizeof(ClockRange),1); + clockRanges->next = NULL; + clockRanges->minClock = 10000; + clockRanges->maxClock = 300000; + clockRanges->clockIndex = -1; /* programmable */ + clockRanges->interlaceAllowed = TRUE; + clockRanges->doubleScanAllowed = TRUE; + + /* see above note */ + /* There is currently only an 1280x1024 mode */ + i = xf86ValidateModes(pScrn, pScrn->monitor->Modes, + pScrn->display->modes, clockRanges, + NULL, 256, 2048, + pScrn->bitsPerPixel, 128, 2048, + pScrn->display->virtualX, + pScrn->display->virtualY, + pScrn->videoRam * 1024, + LOOKUP_BEST_REFRESH); + + if (i == -1) { + NewportFreeRec(pScrn); + return FALSE; + } + + xf86PruneDriverModes(pScrn); + if( i == 0 || pScrn->modes == NULL) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes found\n"); + NewportFreeRec(pScrn); + return FALSE; + } + + /* unnecessary, but do it to get a valid ScrnInfoRec */ + xf86SetCrtcForModes(pScrn, INTERLACE_HALVE_V); + + /* Set the current mode to the first in the list */ + pScrn->currentMode = pScrn->modes; + + /* Print the list of modes being used */ + xf86PrintModes(pScrn); + xf86SetDpi (pScrn, 0, 0); + + /* Load FB module */ + if (!xf86LoadSubModule (pScrn, "fb")) { + NewportFreeRec(pScrn); + return FALSE; + } + xf86LoaderReqSymLists( fbSymbols, NULL); + + /* Load ramdac modules */ + if (pNewport->hwCursor) { + if (!xf86LoadSubModule(pScrn, "ramdac")) { + NewportFreeRec(pScrn); + return FALSE; + } + xf86LoaderReqSymLists(ramdacSymbols, NULL); + } + + /* Load ShadowFB module */ + if (!xf86LoadSubModule(pScrn, "shadowfb")) { + NewportFreeRec(pScrn); + return FALSE; + } + xf86LoaderReqSymLists(shadowSymbols, NULL); + + return TRUE; +} + +static Bool +NewportScreenInit(int index, ScreenPtr pScreen, int argc, char **argv) +{ + ScrnInfoPtr pScrn; + NewportPtr pNewport; + VisualPtr visual; + BOOL ret; + int i; + + /* First get a pointer to our private info */ + pScrn = xf86Screens[pScreen->myNum]; + pNewport = NEWPORTPTR(pScrn); + + /* map the Newportregs until the server dies */ + if( ! NewportMapRegs(pScrn)) + return FALSE; + + /* Reset visual list. */ + miClearVisualTypes(); + + if (!miSetVisualTypes(pScrn->depth, pScrn->depth != 8 ? TrueColorMask : + miGetDefaultVisualMask(pScrn->depth), + pScrn->rgbBits, pScrn->defaultVisual)) + return FALSE; + + miSetPixmapDepths (); + + pNewport->Bpp = pScrn->bitsPerPixel >> 3; + /* Setup the stuff for the shadow framebuffer */ + pNewport->ShadowPitch = (( pScrn->virtualX * pNewport->Bpp ) + 3) & ~3L; + pNewport->ShadowPtr = xnfalloc(pNewport->ShadowPitch * pScrn->virtualY); + + if (!NewportModeInit(pScrn, pScrn->currentMode)) + return FALSE; + + ret = fbScreenInit(pScreen, pNewport->ShadowPtr, + pScrn->virtualX, pScrn->virtualY, + pScrn->xDpi, pScrn->yDpi, + pScrn->displayWidth, + pScrn->bitsPerPixel); + + if(!ret) + return FALSE; + + /* we need rgb ordering if bitsPerPixel > 8 */ + if (pScrn->bitsPerPixel > 8) { + for (i = 0, visual = pScreen->visuals; + i < pScreen->numVisuals; i++, visual++) { + if ((visual->class | DynamicClass) == DirectColor) { + visual->offsetRed = pScrn->offset.red; + visual->offsetGreen = pScrn->offset.green; + visual->offsetBlue = pScrn->offset.blue; + visual->redMask = pScrn->mask.red; + visual->greenMask = pScrn->mask.green; + visual->blueMask = pScrn->mask.blue; + } + } + } + + /* must be after RGB ordering fixed */ + fbPictureInit (pScreen, 0, 0); + + miInitializeBackingStore(pScreen); + xf86SetBackingStore(pScreen); + + xf86SetBlackWhitePixels(pScreen); + + /* Initialize software cursor */ + if(!miDCInitialize(pScreen, xf86GetPointerScreenFuncs())) + return FALSE; + + /* Initialize hardware cursor */ + if(pNewport->hwCursor) + if(!NewportHWCursorInit(pScreen)) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Hardware cursor initialization failed\n"); + return FALSE; + } + + /* Initialise default colourmap */ + if (!miCreateDefColormap(pScreen)) + return FALSE; + + /* Install our LoadPalette funciton */ + if(!xf86HandleColormaps(pScreen, 256, 8, NewportLoadPalette, 0, + CMAP_RELOAD_ON_MODE_SWITCH )) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Colormap initialization failed\n"); + return FALSE; + } + + /* Initialise shadow frame buffer */ + if(!ShadowFBInit(pScreen, (pNewport->Bpp == 1) ? &NewportRefreshArea8 : + &NewportRefreshArea24)) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "ShadowFB initialization failed\n"); + return FALSE; + } + + +#ifdef XvExtension + { + XF86VideoAdaptorPtr *ptr; + int n; + + n = xf86XVListGenericAdaptors(pScrn,&ptr); + if (n) { + xf86XVScreenInit(pScreen, ptr, n); + } + } +#endif + + + pScreen->SaveScreen = NewportSaveScreen; + /* Wrap the current CloseScreen function */ + pNewport->CloseScreen = pScreen->CloseScreen; + pScreen->CloseScreen = NewportCloseScreen; + + if (serverGeneration == 1) { + xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options); + } + + return TRUE; +} + +/* called when switching away from a VT */ +static Bool +NewportEnterVT(int scrnIndex, int flags) +{ + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + return NewportModeInit(pScrn, pScrn->currentMode); +} + +/* called when switching to a VT */ +static void +NewportLeaveVT(int scrnIndex, int flags) +{ + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + NewportRestore(pScrn, FALSE); +} + +/* called at the end of each server generation */ +static Bool +NewportCloseScreen(int scrnIndex, ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + NewportPtr pNewport = NEWPORTPTR(pScrn); + + NewportRestore(pScrn, TRUE); + if (pNewport->ShadowPtr) + xfree(pNewport->ShadowPtr); + + /* unmap the Newport's registers from memory */ + NewportUnmapRegs(pScrn); + pScrn->vtSema = FALSE; + + pScreen->CloseScreen = pNewport->CloseScreen; + return (*pScreen->CloseScreen)(scrnIndex, pScreen); +} + +/* Blank or unblank the screen */ +static Bool +NewportSaveScreen(ScreenPtr pScreen, int mode) +{ + ScrnInfoPtr pScrn; + NewportPtr pNewport; + NewportRegsPtr pNewportRegs; + Bool unblank; + + if (!pScreen) + return TRUE; + + unblank = xf86IsUnblank(mode); + pScrn = xf86Screens[pScreen->myNum]; + + if (!pScrn->vtSema) + return TRUE; + + pNewport = NEWPORTPTR(pScrn); + pNewportRegs = NEWPORTPTR(pScrn)->pNewportRegs; + + if (unblank) + pNewport->vc2ctrl |= VC2_CTRL_EDISP; + else + pNewport->vc2ctrl &= ~VC2_CTRL_EDISP; + NewportVc2Set( pNewportRegs, VC2_IREG_CONTROL, pNewport->vc2ctrl); + return TRUE; +} + + +static const OptionInfoRec * +NewportAvailableOptions(int chipid, int busid) +{ + return NewportOptions; +} + + +/* This sets up the actual mode on the Newport */ +static Bool +NewportModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode) +{ + int width, height; + NewportPtr pNewport = NEWPORTPTR(pScrn); + NewportRegsPtr pNewportRegs = NEWPORTREGSPTR(pScrn); + + width = mode->HDisplay; + height = mode->VDisplay; + if (width != 1280 || height != 1024) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, \ + "Width = %d and height = %d is not supported by by this driver\n", width, height); + return FALSE; + } + + pScrn->vtSema = TRUE; + /* first backup the necessary registers... */ + NewportBackupRex3(pScrn); + if( pNewport->hwCursor ) + NewportBackupVc2Cursor( pScrn ); + NewportBackupVc2(pScrn); + NewportBackupPalette(pScrn); + NewportBackupXmap9s( pScrn ); + /* ...then setup the hardware */ + pNewport->drawmode1 = DM1_RGBPLANES | + NPORT_DMODE1_CCLT | + NPORT_DMODE1_CCEQ | + NPORT_DMODE1_CCGT | + NPORT_DMODE1_LOSRC; + if( pNewport->Bpp == 1) { /* 8bpp */ + pNewport->drawmode1 |= NPORT_DMODE1_DD8 | + NPORT_DMODE1_HD8 | + NPORT_DMODE1_RWPCKD; + } else { /* 24bpp */ + CARD32 mode = 0L; + + /* tell the xmap9s that we are using 24bpp */ + NewportBfwait(pNewport->pNewportRegs); + pNewportRegs->set.dcbmode = (DCB_XMAP_ALL | W_DCB_XMAP9_PROTOCOL | + XM9_CRS_CONFIG | NPORT_DMODE_W1 ); + pNewportRegs->set.dcbdata0.bytes.b3 &= ~(XM9_8_BITPLANES | XM9_PUPMODE); + NewportBfwait(pNewport->pNewportRegs); + /* set up the mode register for 24bpp */ + mode = XM9_MREG_PIX_SIZE_24BPP | XM9_MREG_PIX_MODE_RGB1 + | XM9_MREG_GAMMA_BYPASS; + NewportXmap9SetModeRegister( pNewportRegs , 0, mode); + /* select the set up mode register */ + NewportBfwait(pNewport->pNewportRegs); + pNewportRegs->set.dcbmode = (DCB_XMAP_ALL | W_DCB_XMAP9_PROTOCOL | + XM9_CRS_MODE_REG_INDEX | NPORT_DMODE_W1 ); + pNewportRegs->set.dcbdata0.bytes.b3 = 0; + + pNewport->drawmode1 |= + /* set drawdepth to 24 bit */ + NPORT_DMODE1_DD24 | + /* turn on RGB mode */ + NPORT_DMODE1_RGBMD | + /* turn on 8888 = RGBA pixel packing */ + NPORT_DMODE1_HD32 | NPORT_DMODE1_RWPCKD; + /* After setting up XMAP9 we have to reinitialize the CMAP for + * whatever reason (the docs say nothing about it). RestorePalette() + * is just a lazy way to do this */ + NewportRestorePalette( pScrn ); + } + /* blank the framebuffer */ + NewportWait(pNewportRegs); + pNewportRegs->set.drawmode0 = (NPORT_DMODE0_DRAW | NPORT_DMODE0_DOSETUP | + NPORT_DMODE0_STOPX | NPORT_DMODE0_STOPY | + NPORT_DMODE0_BLOCK); + pNewportRegs->set.drawmode1 = pNewport->drawmode1 | + NPORT_DMODE1_FCLR | + NPORT_DMODE1_RGBMD; + pNewportRegs->set.colorvram = 0; + pNewportRegs->set.xystarti = 0; + pNewportRegs->go.xyendi = ( (1279+64) << 16) | 1023; + + /* default drawmode */ + NewportWait(pNewportRegs); + pNewportRegs->set.drawmode1 = pNewport->drawmode1; + + /* XXX: Lazy mode on: just use the textmode value */ + pNewport->vc2ctrl = pNewport->txt_vc2ctrl; + + return TRUE; +} + + +/* + * This will actually restore the saved state + * (either when switching back to a VT or when the server is going down) + * Closing is true if the X server is really going down + */ +static void +NewportRestore(ScrnInfoPtr pScrn, Bool Closing) +{ + NewportPtr pNewport = NEWPORTPTR(pScrn); + + /* Restore backed up registers */ + NewportRestoreRex3( pScrn ); + if( pNewport->hwCursor ) + NewportRestoreVc2Cursor( pScrn ); + NewportRestoreVc2( pScrn ); + NewportRestorePalette( pScrn ); + NewportRestoreXmap9s( pScrn ); +} + + +/* Probe for the Newport card ;) */ +/* XXX: we need a better probe here in order to support multihead! */ +static unsigned +NewportHWProbe(unsigned probedIDs[]) +{ + FILE* cpuinfo; + char line[80]; + unsigned hasNewport = 0; + + if ((cpuinfo = fopen("/proc/cpuinfo", "r"))) { + while(fgets(line, 80, cpuinfo) != NULL) { + if(strstr(line, "SGI Indy") != NULL) { + hasNewport = 1; + probedIDs[0] = 0; + break; + } + if(strstr(line, "SGI Indigo2") != NULL) { + hasNewport = 1; + probedIDs[0] = 1; + break; + } + } + fclose(cpuinfo); + } + return hasNewport; +} + +/* Probe for Chipset revisions */ +static Bool NewportProbeCardInfo(ScrnInfoPtr pScrn) +{ + unsigned int tmp,cmap_rev; + NewportPtr pNewport = NEWPORTPTR(pScrn); + NewportRegsPtr pNewportRegs = pNewport->pNewportRegs; + + NewportWait(pNewportRegs); + pNewportRegs->set.dcbmode = (DCB_CMAP0 | NCMAP_PROTOCOL | + NCMAP_REGADDR_RREG | NPORT_DMODE_W1); + tmp = pNewportRegs->set.dcbdata0.bytes.b3; + pNewport->board_rev = (tmp >> 4) & 7; + pNewport->bitplanes = ((pNewport->board_rev > 1) && (tmp & 0x80)) ? 8 : 24; + cmap_rev = tmp & 7; + pNewport->cmap_rev = (char)('A'+(cmap_rev ? (cmap_rev+1):0)); + pNewport->rex3_rev = (char)('A'+(pNewportRegs->cset.ustat & 7)); + + pNewportRegs->set.dcbmode = (DCB_XMAP0 | R_DCB_XMAP9_PROTOCOL | + XM9_CRS_REVISION | NPORT_DMODE_W1); + pNewport->xmap9_rev = (char)('A'+(pNewportRegs->set.dcbdata0.bytes.b3 & 7)); + + /* XXX: read possible modes from VC2 here */ + return TRUE; +} + + +/* map NewportRegs */ +static Bool +NewportMapRegs(ScrnInfoPtr pScrn) +{ + NewportPtr pNewport = NEWPORTPTR(pScrn); + + pNewport->pNewportRegs = xf86MapVidMem(pScrn->scrnIndex, + VIDMEM_MMIO, + NEWPORT_BASE_ADDR0 + pNewport->busID * NEWPORT_BASE_OFFSET, + sizeof(NewportRegs)); + if ( ! pNewport->pNewportRegs ) + return FALSE; + return TRUE; +} + +/* unmap NewportRegs */ +static void +NewportUnmapRegs(ScrnInfoPtr pScrn) +{ + NewportPtr pNewport = NEWPORTPTR(pScrn); + + xf86UnMapVidMem( pScrn->scrnIndex, pNewport->pNewportRegs, + sizeof(NewportRegs)); + pNewport->pNewportRegs = NULL; +} diff --git a/src/newport_regs.c b/src/newport_regs.c new file mode 100644 index 0000000..30028d1 --- /dev/null +++ b/src/newport_regs.c @@ -0,0 +1,235 @@ +/* + * Id: newport_regs.c,v 1.3 2000/11/29 20:58:10 agx Exp $ + */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/newport/newport_regs.c,v 1.7 2002/12/10 04:03:00 dawes Exp $ */ + +#include "newport.h" + +static void NewportXmap9FifoWait(NewportRegsPtr pNewportRegs, unsigned long xmapChip); + +void +NewportVc2Set(NewportRegsPtr pNewportRegs, unsigned char vc2Ireg, unsigned short val) +{ + pNewportRegs->set.dcbmode = (NPORT_DMODE_AVC2 | VC2_REGADDR_INDEX | NPORT_DMODE_W3 | + NPORT_DMODE_ECINC | VC2_PROTOCOL); + pNewportRegs->set.dcbdata0.all = (vc2Ireg << 24) | (val << 8); +} + +unsigned short +NewportVc2Get(NewportRegsPtr pNewportRegs, unsigned char vc2Ireg) +{ + pNewportRegs->set.dcbmode = (NPORT_DMODE_AVC2 | VC2_REGADDR_INDEX | NPORT_DMODE_W1 | + NPORT_DMODE_ECINC | VC2_PROTOCOL); + pNewportRegs->set.dcbdata0.bytes.b3 = vc2Ireg; + pNewportRegs->set.dcbmode = (NPORT_DMODE_AVC2 | VC2_REGADDR_IREG | NPORT_DMODE_W2 | + NPORT_DMODE_ECINC | VC2_PROTOCOL); + return pNewportRegs->set.dcbdata0.hwords.s1; +} + +void +NewportBackupVc2( ScrnInfoPtr pScrn) +{ + NewportPtr pNewport = NEWPORTPTR(pScrn); + NewportRegsPtr pNewportRegs = NEWPORTREGSPTR(pScrn); + + pNewport->txt_vc2ctrl = NewportVc2Get( pNewportRegs, VC2_IREG_CONTROL ); + pNewport->txt_vc2cur_x = NewportVc2Get( pNewportRegs, VC2_IREG_CURSX ); + pNewport->txt_vc2cur_y = NewportVc2Get( pNewportRegs, VC2_IREG_CURSY ); +} + +void +NewportRestoreVc2( ScrnInfoPtr pScrn) +{ + NewportPtr pNewport = NEWPORTPTR(pScrn); + NewportRegsPtr pNewportRegs = NEWPORTREGSPTR(pScrn); + + NewportVc2Set( pNewportRegs, VC2_IREG_CONTROL, pNewport->txt_vc2ctrl ); + NewportVc2Set( pNewportRegs, VC2_IREG_CURSX, pNewport->txt_vc2cur_x ); + NewportVc2Set( pNewportRegs, VC2_IREG_CURSY, pNewport->txt_vc2cur_y ); +} + +void +NewportRestoreVc2Cursor( ScrnInfoPtr pScrn) +{ + NewportPtr pNewport = NEWPORTPTR(pScrn); + NewportLoadCursorImage( pScrn, (CARD8*)pNewport->txt_vc2cur_data); +} + +void +NewportBackupVc2Cursor( ScrnInfoPtr pScrn) +{ + int i; + CARD16 tmp, *data; + NewportPtr pNewport = NEWPORTPTR(pScrn); + NewportRegsPtr pNewportRegs = NEWPORTREGSPTR(pScrn); + + data = (CARD16*)pNewport->txt_vc2cur_data; + /* address of cursor data in vc2's ram */ + tmp = NewportVc2Get( pNewportRegs, VC2_IREG_CENTRY); + /* this is where we want to write to: */ + NewportVc2Set( pNewportRegs, VC2_IREG_RADDR, tmp); + pNewportRegs->set.dcbmode = (NPORT_DMODE_AVC2 | VC2_REGADDR_RAM | + NPORT_DMODE_W2 | VC2_PROTOCOL); + /* read cursor data */ + for (i = 0; i < 128; i++) { + NewportBfwait(pNewportRegs); + *data = pNewportRegs->set.dcbdata0.hwords.s1; + data++; + } +} + +/* Sometimes we just have to wait until we can do anything */ +void +NewportWait(NewportRegsPtr pNewportRegs) +{ + while(1) + if(!(pNewportRegs->cset.stat & NPORT_STAT_GBUSY)) + break; +} + +void +NewportBfwait(NewportRegsPtr pNewportRegs) +{ + while(1) + if(!(pNewportRegs->cset.stat & NPORT_STAT_BBUSY)) + break; +} + +/* wait til an entry in the Xmap9's Mode Fifo is free (xmapChip = DCB_XMAP0 | DCB_XMAP1) */ +static void +NewportXmap9FifoWait(NewportRegsPtr pNewportRegs, unsigned long xmapChip) +{ + while(1) { + NewportBfwait( pNewportRegs); + pNewportRegs->set.dcbmode = (xmapChip | R_DCB_XMAP9_PROTOCOL | + XM9_CRS_FIFO_AVAIL | NPORT_DMODE_W1); + if( (pNewportRegs->set.dcbdata0.bytes.b3) & 7 ) + break; + } +} + +void +NewportXmap9SetModeRegister(NewportRegsPtr pNewportRegs, CARD8 address, CARD32 mode) +{ + NewportXmap9FifoWait( pNewportRegs, DCB_XMAP0); + NewportXmap9FifoWait( pNewportRegs, DCB_XMAP1); + + pNewportRegs->set.dcbmode = (DCB_XMAP_ALL | W_DCB_XMAP9_PROTOCOL | + XM9_CRS_MODE_REG_DATA | NPORT_DMODE_W4 ); + pNewportRegs->set.dcbdata0.all = (address << 24) | ( mode & 0xffffff ); +} + +CARD32 +NewportXmap9GetModeRegister(NewportRegsPtr pNewportRegs, unsigned chip, CARD8 address) +{ + CARD32 dcbaddr, i, val, mode = 0; + CARD8 index = ( address << 2 ); + + if(chip) + dcbaddr = DCB_XMAP1; + else + dcbaddr = DCB_XMAP0; + + /* we have to read one byte at at time */ + for( i = 0; i < 4; i++ ) { + NewportXmap9FifoWait( pNewportRegs, dcbaddr); + + pNewportRegs->set.dcbmode = ( dcbaddr | W_DCB_XMAP9_PROTOCOL | + XM9_CRS_MODE_REG_INDEX | NPORT_DMODE_W1 ); + pNewportRegs->set.dcbdata0.bytes.b3 = (index | i); + pNewportRegs->set.dcbmode = ( dcbaddr | W_DCB_XMAP9_PROTOCOL | + XM9_CRS_MODE_REG_DATA | NPORT_DMODE_W1 ); + val = pNewportRegs->set.dcbdata0.bytes.b3; + mode |= (val << ( i * 8 ) ); + } + return mode; +} + +void +NewportBackupRex3( ScrnInfoPtr pScrn) +{ + NewportPtr pNewport = NEWPORTPTR(pScrn); + NewportRegsPtr pNewportRegs = NEWPORTREGSPTR(pScrn); + + pNewport->txt_drawmode0 = pNewportRegs->set.drawmode0; + pNewport->txt_drawmode1 = pNewportRegs->set.drawmode1; + pNewport->txt_wrmask = pNewportRegs->set.wrmask; + pNewport->txt_smask1x = pNewportRegs->cset.smask1x; + pNewport->txt_smask1y = pNewportRegs->cset.smask1y; + pNewport->txt_smask2x = pNewportRegs->cset.smask2x; + pNewport->txt_smask2y = pNewportRegs->cset.smask2y; + pNewport->txt_clipmode = pNewportRegs->cset.clipmode; +} + +void +NewportRestoreRex3( ScrnInfoPtr pScrn) +{ + NewportPtr pNewport = NEWPORTPTR(pScrn); + NewportRegsPtr pNewportRegs = NEWPORTREGSPTR(pScrn); + + pNewportRegs->set.drawmode0 = pNewport->txt_drawmode0; + pNewportRegs->set.drawmode1 = pNewport->txt_drawmode1; + pNewportRegs->set.wrmask = pNewport->txt_wrmask; + pNewportRegs->cset.smask1x = pNewport->txt_smask1x; + pNewportRegs->cset.smask1y = pNewport->txt_smask1y; + pNewportRegs->cset.smask2x = pNewport->txt_smask2x; + pNewportRegs->cset.smask2y = pNewport->txt_smask2y; + pNewportRegs->cset.clipmode = pNewport->txt_clipmode; +} + +void NewportBackupXmap9s( ScrnInfoPtr pScrn) +{ + NewportPtr pNewport = NEWPORTPTR(pScrn); + NewportRegsPtr pNewportRegs = NEWPORTREGSPTR(pScrn); + + NewportBfwait(pNewport->pNewportRegs); + /* config of xmap0 */ + pNewportRegs->set.dcbmode = (DCB_XMAP0 | R_DCB_XMAP9_PROTOCOL | + XM9_CRS_CONFIG | NPORT_DMODE_W1 ); + pNewport->txt_xmap9_cfg0 = pNewportRegs->set.dcbdata0.bytes.b3; + NewportBfwait(pNewport->pNewportRegs); + /* config of xmap1 */ + pNewportRegs->set.dcbmode = (DCB_XMAP1 | R_DCB_XMAP9_PROTOCOL | + XM9_CRS_CONFIG | NPORT_DMODE_W1 ); + pNewport->txt_xmap9_cfg1 = pNewportRegs->set.dcbdata0.bytes.b3; + NewportBfwait(pNewport->pNewportRegs); + /* mode index register of xmap0 */ + pNewportRegs->set.dcbmode = (DCB_XMAP0 | R_DCB_XMAP9_PROTOCOL | + XM9_CRS_MODE_REG_INDEX | NPORT_DMODE_W1 ); + pNewport->txt_xmap9_mi = pNewportRegs->set.dcbdata0.bytes.b3; + /* mode register 0 of xmap 0 */ + pNewport->txt_xmap9_mod0 = NewportXmap9GetModeRegister(pNewportRegs, 0, 0); + /* cursor cmap msb */ + pNewportRegs->set.dcbmode = (DCB_XMAP0 | R_DCB_XMAP9_PROTOCOL | + XM9_CRS_CURS_CMAP_MSB | NPORT_DMODE_W1 ); + pNewport->txt_xmap9_ccmsb = pNewportRegs->set.dcbdata0.bytes.b3; +} + +void NewportRestoreXmap9s( ScrnInfoPtr pScrn) +{ + NewportPtr pNewport = NEWPORTPTR(pScrn); + NewportRegsPtr pNewportRegs = NEWPORTREGSPTR(pScrn); + + /* mode register 0 */ + NewportXmap9SetModeRegister( pNewportRegs , 0, pNewport->txt_xmap9_mod0 ); + NewportBfwait(pNewport->pNewportRegs); + /* mode index register */ + pNewportRegs->set.dcbmode = (DCB_XMAP_ALL | W_DCB_XMAP9_PROTOCOL | + XM9_CRS_MODE_REG_INDEX | NPORT_DMODE_W1 ); + pNewportRegs->set.dcbdata0.bytes.b3 = pNewport->txt_xmap9_mi; + NewportBfwait(pNewport->pNewportRegs); + /* cfg xmap0 */ + pNewportRegs->set.dcbmode = (DCB_XMAP0 | W_DCB_XMAP9_PROTOCOL | + XM9_CRS_CONFIG | NPORT_DMODE_W1 ); + pNewportRegs->set.dcbdata0.bytes.b3 = pNewport->txt_xmap9_cfg0; + NewportBfwait(pNewport->pNewportRegs); + /* cfg xmap1 */ + pNewportRegs->set.dcbmode = (DCB_XMAP1 | W_DCB_XMAP9_PROTOCOL | + XM9_CRS_CONFIG | NPORT_DMODE_W1 ); + pNewportRegs->set.dcbdata0.bytes.b3 = pNewport->txt_xmap9_cfg1; + /* cursor cmap msb */ + pNewportRegs->set.dcbmode = (DCB_XMAP0 | R_DCB_XMAP9_PROTOCOL | + XM9_CRS_CURS_CMAP_MSB | NPORT_DMODE_W1 ); + pNewportRegs->set.dcbdata0.bytes.b3 = pNewport->txt_xmap9_ccmsb; +} + diff --git a/src/newport_regs.h b/src/newport_regs.h new file mode 100644 index 0000000..f4b04cb --- /dev/null +++ b/src/newport_regs.h @@ -0,0 +1,457 @@ +/* + * Id: newport_regs.h,v 1.5 2000/11/18 23:23:14 agx Exp $ + * + * Register Layouts of the various newport chips + * mostly as found in linux/include/asm/newport.h + */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/newport/newport_regs.h,v 1.3 2002/12/10 04:03:00 dawes Exp $ */ + +typedef volatile unsigned long npireg_t; + +union npfloat { + volatile float f; + npireg_t i; +}; + +typedef union npfloat npfreg_t; + +union np_dcb { + npireg_t all; + struct { volatile unsigned short s0, s1; } hwords; + struct { volatile unsigned char b0, b1, b2, b3; } bytes; +}; + +struct Newport_rexregs { + npireg_t drawmode1; /* GL extra mode bits */ + +#define DM1_PLANES 0x00000007 +#define DM1_NOPLANES 0x00000000 +#define DM1_RGBPLANES 0x00000001 +#define DM1_RGBAPLANES 0x00000002 +#define DM1_OLAYPLANES 0x00000004 +#define DM1_PUPPLANES 0x00000005 +#define DM1_CIDPLANES 0x00000006 + +#define NPORT_DMODE1_DDMASK 0x00000018 +#define NPORT_DMODE1_DD4 0x00000000 +#define NPORT_DMODE1_DD8 0x00000008 +#define NPORT_DMODE1_DD12 0x00000010 +#define NPORT_DMODE1_DD24 0x00000018 +#define NPORT_DMODE1_DSRC 0x00000020 +#define NPORT_DMODE1_YFLIP 0x00000040 +#define NPORT_DMODE1_RWPCKD 0x00000080 +#define NPORT_DMODE1_HDMASK 0x00000300 +#define NPORT_DMODE1_HD4 0x00000000 +#define NPORT_DMODE1_HD8 0x00000100 +#define NPORT_DMODE1_HD12 0x00000200 +#define NPORT_DMODE1_HD32 0x00000300 +#define NPORT_DMODE1_RWDBL 0x00000400 +#define NPORT_DMODE1_ESWAP 0x00000800 /* Endian swap */ +#define NPORT_DMODE1_CCMASK 0x00007000 +#define NPORT_DMODE1_CCLT 0x00001000 +#define NPORT_DMODE1_CCEQ 0x00002000 +#define NPORT_DMODE1_CCGT 0x00004000 +#define NPORT_DMODE1_RGBMD 0x00008000 +#define NPORT_DMODE1_DENAB 0x00010000 /* Dither enable */ +#define NPORT_DMODE1_FCLR 0x00020000 /* Fast clear */ +#define NPORT_DMODE1_BENAB 0x00040000 /* Blend enable */ +#define NPORT_DMODE1_SFMASK 0x00380000 +#define NPORT_DMODE1_SF0 0x00000000 +#define NPORT_DMODE1_SF1 0x00080000 +#define NPORT_DMODE1_SFDC 0x00100000 +#define NPORT_DMODE1_SFMDC 0x00180000 +#define NPORT_DMODE1_SFSA 0x00200000 +#define NPORT_DMODE1_SFMSA 0x00280000 +#define NPORT_DMODE1_DFMASK 0x01c00000 +#define NPORT_DMODE1_DF0 0x00000000 +#define NPORT_DMODE1_DF1 0x00400000 +#define NPORT_DMODE1_DFSC 0x00800000 +#define NPORT_DMODE1_DFMSC 0x00c00000 +#define NPORT_DMODE1_DFSA 0x01000000 +#define NPORT_DMODE1_DFMSA 0x01400000 +#define NPORT_DMODE1_BBENAB 0x02000000 /* Back blend enable */ +#define NPORT_DMODE1_PFENAB 0x04000000 /* Pre-fetch enable */ +#define NPORT_DMODE1_ABLEND 0x08000000 /* Alpha blend */ +#define NPORT_DMODE1_LOMASK 0xf0000000 +#define NPORT_DMODE1_LOZERO 0x00000000 +#define NPORT_DMODE1_LOAND 0x10000000 +#define NPORT_DMODE1_LOANDR 0x20000000 +#define NPORT_DMODE1_LOSRC 0x30000000 +#define NPORT_DMODE1_LOANDI 0x40000000 +#define NPORT_DMODE1_LODST 0x50000000 +#define NPORT_DMODE1_LOXOR 0x60000000 +#define NPORT_DMODE1_LOOR 0x70000000 +#define NPORT_DMODE1_LONOR 0x80000000 +#define NPORT_DMODE1_LOXNOR 0x90000000 +#define NPORT_DMODE1_LONDST 0xa0000000 +#define NPORT_DMODE1_LOORR 0xb0000000 +#define NPORT_DMODE1_LONSRC 0xc0000000 +#define NPORT_DMODE1_LOORI 0xd0000000 +#define NPORT_DMODE1_LONAND 0xe0000000 +#define NPORT_DMODE1_LOONE 0xf0000000 + + npireg_t drawmode0; /* REX command register */ + + /* These bits define the graphics opcode being performed. */ +#define NPORT_DMODE0_OPMASK 0x00000003 /* Opcode mask */ +#define NPORT_DMODE0_NOP 0x00000000 /* No operation */ +#define NPORT_DMODE0_RD 0x00000001 /* Read operation */ +#define NPORT_DMODE0_DRAW 0x00000002 /* Draw operation */ +#define NPORT_DMODE0_S2S 0x00000003 /* Screen to screen operation */ + + /* The following decide what addressing mode(s) are to be used */ +#define NPORT_DMODE0_AMMASK 0x0000001c /* Address mode mask */ +#define NPORT_DMODE0_SPAN 0x00000000 /* Spanning address mode */ +#define NPORT_DMODE0_BLOCK 0x00000004 /* Block address mode */ +#define NPORT_DMODE0_ILINE 0x00000008 /* Iline address mode */ +#define NPORT_DMODE0_FLINE 0x0000000c /* Fline address mode */ +#define NPORT_DMODE0_ALINE 0x00000010 /* Aline address mode */ +#define NPORT_DMODE0_TLINE 0x00000014 /* Tline address mode */ +#define NPORT_DMODE0_BLINE 0x00000018 /* Bline address mode */ + + /* And now some misc. operation control bits. */ +#define NPORT_DMODE0_DOSETUP 0x00000020 +#define NPORT_DMODE0_CHOST 0x00000040 +#define NPORT_DMODE0_AHOST 0x00000080 +#define NPORT_DMODE0_STOPX 0x00000100 +#define NPORT_DMODE0_STOPY 0x00000200 +#define NPORT_DMODE0_SK1ST 0x00000400 +#define NPORT_DMODE0_SKLST 0x00000800 +#define NPORT_DMODE0_ZPENAB 0x00001000 +#define NPORT_DMODE0_LISPENAB 0x00002000 +#define NPORT_DMODE0_LISLST 0x00004000 +#define NPORT_DMODE0_L32 0x00008000 +#define NPORT_DMODE0_ZOPQ 0x00010000 +#define NPORT_DMODE0_LISOPQ 0x00020000 +#define NPORT_DMODE0_SHADE 0x00040000 +#define NPORT_DMODE0_LRONLY 0x00080000 +#define NPORT_DMODE0_XYOFF 0x00100000 +#define NPORT_DMODE0_CLAMP 0x00200000 +#define NPORT_DMODE0_ENDPF 0x00400000 +#define NPORT_DMODE0_YSTR 0x00800000 + + npireg_t lsmode; /* Mode for line stipple ops */ +#define NPORT_LSMODE_REPMASK 0x0000ff00 +#define NPORT_LSMODE_LENMASK 0x0f000000 + npireg_t lspattern; /* Pattern for line stipple ops */ + npireg_t lspatsave; /* Backup save pattern */ + npireg_t zpattern; /* Pixel zpattern */ + npireg_t colorback; /* Background color */ + npireg_t colorvram; /* Clear color for fast vram */ + npireg_t alpharef; /* Reference value for afunctions */ + unsigned long pad0; + npireg_t smask0x; /* Window GL relative screen mask 0 */ + npireg_t smask0y; /* Window GL relative screen mask 0 */ + npireg_t _setup; + npireg_t _stepz; + npireg_t _lsrestore; + npireg_t _lssave; + + unsigned long _pad1[0x30]; + + /* Iterators, full state for context switch */ + npfreg_t _xstart; /* X-start point (current) */ + npfreg_t _ystart; /* Y-start point (current) */ + npfreg_t _xend; /* x-end point */ + npfreg_t _yend; /* y-end point */ + npireg_t xsave; /* copy of xstart integer value for BLOCk addressing MODE */ + npireg_t xymove; /* x.y offset from xstart, ystart for relative operations */ + npfreg_t bresd; + npfreg_t bress1; + npireg_t bresoctinc1; + volatile int bresrndinc2; + npireg_t brese1; + npireg_t bress2; + npireg_t aweight0; + npireg_t aweight1; + npfreg_t xstartf; + npfreg_t ystartf; + npfreg_t xendf; + npfreg_t yendf; + npireg_t xstarti; + npfreg_t xendf1; + npireg_t xystarti; + npireg_t xyendi; + npireg_t xstartendi; + + unsigned long _unused2[0x29]; + + npfreg_t colorred; + npfreg_t coloralpha; + npfreg_t colorgrn; + npfreg_t colorblue; + npfreg_t slopered; + npfreg_t slopealpha; + npfreg_t slopegrn; + npfreg_t slopeblue; + npireg_t wrmask; + npireg_t colori; + npfreg_t colorx; + npfreg_t slopered1; + npireg_t hostrw0; + npireg_t hostrw1; + npireg_t dcbmode; +#define NPORT_DMODE_WMASK 0x00000003 /* dataWidth of data being transfered */ +#define NPORT_DMODE_W4 0x00000000 +#define NPORT_DMODE_W1 0x00000001 +#define NPORT_DMODE_W2 0x00000002 +#define NPORT_DMODE_W3 0x00000003 +#define NPORT_DMODE_EDPACK 0x00000004 +#define NPORT_DMODE_ECINC 0x00000008 +#define NPORT_DMODE_CMASK 0x00000070 +#define NPORT_DMODE_AMASK 0x00000780 +#define NPORT_DMODE_AVC2 0x00000000 +#define NPORT_DMODE_ACMALL 0x00000080 +#define NPORT_DMODE_ACM0 0x00000100 +#define NPORT_DMODE_ACM1 0x00000180 +#define NPORT_DMODE_AXMALL 0x00000200 +#define NPORT_DMODE_AXM0 0x00000280 +#define NPORT_DMODE_AXM1 0x00000300 +#define NPORT_DMODE_ABT 0x00000380 +#define NPORT_DMODE_AVCC1 0x00000400 +#define NPORT_DMODE_AVAB1 0x00000480 +#define NPORT_DMODE_ALG3V0 0x00000500 +#define NPORT_DMODE_A1562 0x00000580 +#define NPORT_DMODE_ESACK 0x00000800 +#define NPORT_DMODE_EASACK 0x00001000 +#define NPORT_DMODE_CWMASK 0x0003e000 +#define NPORT_DMODE_CHMASK 0x007c0000 +#define NPORT_DMODE_CSMASK 0x0f800000 +#define NPORT_DMODE_SENDIAN 0x10000000 + + unsigned long _unused3; + + union np_dcb dcbdata0; + npireg_t dcbdata1; +}; + +struct Newport_cregs { + npireg_t smask1x; + npireg_t smask1y; + npireg_t smask2x; + npireg_t smask2y; + npireg_t smask3x; + npireg_t smask3y; + npireg_t smask4x; + npireg_t smask4y; + npireg_t topscan; + npireg_t xywin; + npireg_t clipmode; +#define NPORT_SMASKXOFF 4096 +#define NPORT_SMASKYOFF 4096 +#define NPORT_CMODE_SM0 0x00000001 +#define NPORT_CMODE_SM1 0x00000002 +#define NPORT_CMODE_SM2 0x00000004 +#define NPORT_CMODE_SM3 0x00000008 +#define NPORT_CMODE_SM4 0x00000010 +#define NPORT_CMODE_CMSK 0x00001e00 + + unsigned long _unused0; + unsigned long config; +#define NPORT_CFG_G32MD 0x00000001 +#define NPORT_CFG_BWIDTH 0x00000002 +#define NPORT_CFG_ERCVR 0x00000004 +#define NPORT_CFG_BDMSK 0x00000078 +#define NPORT_CFG_GDMSK 0x00000f80 +#define NPORT_CFG_GD0 0x00000080 +#define NPORT_CFG_GD1 0x00000100 +#define NPORT_CFG_GD2 0x00000200 +#define NPORT_CFG_GD3 0x00000400 +#define NPORT_CFG_GD4 0x00000800 +#define NPORT_CFG_GFAINT 0x00001000 +#define NPORT_CFG_TOMSK 0x0000e000 +#define NPORT_CFG_VRMSK 0x00070000 +#define NPORT_CFG_FBTYP 0x00080000 + + npireg_t _unused1; + npireg_t stat; +#define NPORT_STAT_VERS 0x00000007 +#define NPORT_STAT_GBUSY 0x00000008 +#define NPORT_STAT_BBUSY 0x00000010 +#define NPORT_STAT_VRINT 0x00000020 +#define NPORT_STAT_VIDINT 0x00000040 +#define NPORT_STAT_GLMSK 0x00001f80 +#define NPORT_STAT_BLMSK 0x0007e000 +#define NPORT_STAT_BFIRQ 0x00080000 +#define NPORT_STAT_GFIRQ 0x00100000 + + npireg_t ustat; + npireg_t dreset; +}; + +typedef +struct Newport_regs { + struct Newport_rexregs set; + unsigned long _unused0[0x16e]; + struct Newport_rexregs go; + unsigned long _unused1[0x22e]; + struct Newport_cregs cset; + unsigned long _unused2[0x1ef]; + struct Newport_cregs cgo; +} NewportRegs, *NewportRegsPtr; + +/* Reading/writing VC2 registers. */ +#define VC2_REGADDR_INDEX 0x00000000 +#define VC2_REGADDR_IREG 0x00000010 +#define VC2_REGADDR_RAM 0x00000030 +#define VC2_PROTOCOL (NPORT_DMODE_EASACK | 0x00800000 | 0x00040000) + +#define VC2_VLINET_ADDR 0x000 +#define VC2_VFRAMET_ADDR 0x400 +#define VC2_CGLYPH_ADDR 0x500 + +/* Now the Indexed registers of the VC2. */ +#define VC2_IREG_VENTRY 0x00 +#define VC2_IREG_CENTRY 0x01 +#define VC2_IREG_CURSX 0x02 +#define VC2_IREG_CURSY 0x03 +#define VC2_IREG_CCURSX 0x04 +#define VC2_IREG_DENTRY 0x05 +#define VC2_IREG_SLEN 0x06 +#define VC2_IREG_RADDR 0x07 +#define VC2_IREG_VFPTR 0x08 +#define VC2_IREG_VLSPTR 0x09 +#define VC2_IREG_VLIR 0x0a +#define VC2_IREG_VLCTR 0x0b +#define VC2_IREG_CTPTR 0x0c +#define VC2_IREG_WCURSY 0x0d +#define VC2_IREG_DFPTR 0x0e +#define VC2_IREG_DLTPTR 0x0f +#define VC2_IREG_CONTROL 0x10 +#define VC2_IREG_CONFIG 0x20 + +/* VC2 Control register bits */ +#define VC2_CTRL_EVIRQ 0x0001 +#define VC2_CTRL_EDISP 0x0002 +#define VC2_CTRL_EVIDEO 0x0004 +#define VC2_CTRL_EDIDS 0x0008 +#define VC2_CTRL_ECURS 0x0010 +#define VC2_CTRL_EGSYNC 0x0020 +#define VC2_CTRL_EILACE 0x0040 +#define VC2_CTRL_ECDISP 0x0080 +#define VC2_CTRL_ECCURS 0x0100 +#define VC2_CTRL_ECG64 0x0200 +#define VC2_CTRL_GLSEL 0x0400 + +/* Controlling the color map on Newport. */ +#define NCMAP_REGADDR_AREG 0x00000000 +#define NCMAP_REGADDR_ALO 0x00000000 /* address register low */ +#define NCMAP_REGADDR_AHI 0x00000010 /* address register high */ +#define NCMAP_REGADDR_PBUF 0x00000020 /* color palette buffer */ +#define NCMAP_REGADDR_CREG 0x00000030 /* command register */ +#define NCMAP_REGADDR_SREG 0x00000040 /* color buffer register */ +#define NCMAP_REGADDR_RREG 0x00000060 /* revision register */ +#define NCMAP_PROTOCOL (0x00008000 | 0x00040000 | 0x00800000) + +/* + * DCBMODE register defines: + */ + +/* Widht of the data being transfered for each DCBDATA[01] word */ +#define DCB_DATAWIDTH_4 0x0 +#define DCB_DATAWIDTH_1 0x1 +#define DCB_DATAWIDTH_2 0x2 +#define DCB_DATAWIDTH_3 0x3 + +/* If set, all of DCBDATA will be moved, otherwise only DATAWIDTH bytes */ +#define DCB_ENDATAPACK (1 << 2) + +/* Enables DCBCRS auto increment after each DCB transfer */ +#define DCB_ENCRSINC (1 << 3) + +/* shift for accessing the control register select address (DBCCRS, 3 bits) */ +#define DCB_CRS_SHIFT 4 + +/* DCBADDR (4 bits): display bus slave address */ +#define DCB_ADDR_SHIFT 7 +#define DCB_VC2 (0 << DCB_ADDR_SHIFT) +#define DCB_CMAP_ALL (1 << DCB_ADDR_SHIFT) +#define DCB_CMAP0 (2 << DCB_ADDR_SHIFT) +#define DCB_CMAP1 (3 << DCB_ADDR_SHIFT) +#define DCB_XMAP_ALL (4 << DCB_ADDR_SHIFT) +#define DCB_XMAP0 (5 << DCB_ADDR_SHIFT) +#define DCB_XMAP1 (6 << DCB_ADDR_SHIFT) +#define DCB_BT445 (7 << DCB_ADDR_SHIFT) +#define DCB_VCC1 (8 << DCB_ADDR_SHIFT) +#define DCB_VAB1 (9 << DCB_ADDR_SHIFT) +#define DCB_LG3_BDVERS0 (10 << DCB_ADDR_SHIFT) +#define DCB_LG3_ICS1562 (11 << DCB_ADDR_SHIFT) +#define DCB_RESERVED (15 << DCB_ADDR_SHIFT) + +/* DCB protocol ack types */ +#define DCB_ENSYNCACK (1 << 11) +#define DCB_ENASYNCACK (1 << 12) + +#define DCB_CSWIDTH_SHIFT 13 +#define DCB_CSHOLD_SHIFT 18 +#define DCB_CSSETUP_SHIFT 23 + +/* XMAP9 specific defines */ +/* XMAP9 -- registers as seen on the DCBMODE register*/ +# define XM9_CRS_CONFIG (0 << DCB_CRS_SHIFT) +# define XM9_PUPMODE (1 << 0) +# define XM9_ODD_PIXEL (1 << 1) +# define XM9_8_BITPLANES (1 << 2) +# define XM9_SLOW_DCB (1 << 3) +# define XM9_VIDEO_RGBMAP_MASK (3 << 4) +# define XM9_VIDEO_RGBMAP_M0 (1 << 4) +# define XM9_VIDEO_RGMPAP_M1 (1 << 5) +# define XM9_VIDEO_RGBMAP_M2 (3 << 4) +# define XM9_EXPRESS_VIDEO (1 << 6) +# define XM9_VIDEO_OPTION (1 << 7) +# define XM9_CRS_REVISION (1 << DCB_CRS_SHIFT) +# define XM9_CRS_FIFO_AVAIL (2 << DCB_CRS_SHIFT) +# define XM9_FIFO_0_AVAIL 0 +# define XM9_FIFO_1_AVAIL 1 +# define XM9_FIFO_2_AVAIL 3 +# define XM9_FIFO_3_AVAIL 2 +# define XM9_FIFO_FULL XM9_FIFO_0_AVAIL +# define XM9_FIFO_EMPTY XM9_FIFO_3_AVAIL +# define XM9_CRS_CURS_CMAP_MSB (3 << DCB_CRS_SHIFT) +# define XM9_CRS_PUP_CMAP_MSB (4 << DCB_CRS_SHIFT) +# define XM9_CRS_MODE_REG_DATA (5 << DCB_CRS_SHIFT) +# define XM9_CRS_MODE_REG_INDEX (7 << DCB_CRS_SHIFT) + + +#define DCB_CYCLES(setup,hold,width) \ + ((hold << DCB_CSHOLD_SHIFT) | \ + (setup << DCB_CSSETUP_SHIFT)| \ + (width << DCB_CSWIDTH_SHIFT)) + +#define W_DCB_XMAP9_PROTOCOL DCB_CYCLES (2, 1, 0) +#define WSLOW_DCB_XMAP9_PROTOCOL DCB_CYCLES (5, 5, 0) +#define WAYSLOW_DCB_XMAP9_PROTOCOL DCB_CYCLES (12, 12, 0) +#define R_DCB_XMAP9_PROTOCOL DCB_CYCLES (2, 1, 3) + +/* xmap9 mode register layout */ +#define XM9_MREG_BUF_SEL (1 << 0) +#define XM9_MREG_OVL_BUF_SEL (1 << 1) +#define XM9_MREG_GAMMA_BYPASS (1 << 2) +#define XM9_MREG_MSB_CMAP (31 << 3) +#define XM9_MREG_PIX_MODE_MASK (3 << 8) +#define XM9_MREG_PIX_MODE_RGB0 (1 << 8) +#define XM9_MREG_PIX_MODE_RGB1 (1 << 9) +#define XM9_MREG_PIX_MODE_RGB2 (3 << 8) +#define XM9_MREG_PIX_SIZE_MASK (3 << 10) +#define XM9_MREG_PIX_SIZE_8BPP (1 << 10) +#define XM9_MREG_PIX_SIZE_12BPP (1 << 11) +#define XM9_MREG_PIX_SIZE_24BPP (3 << 10) +#define XM9_MREG_VID_MODE_MASK (3 << 12) +#define XM9_MREG_VID_MODE_OVL (1 << 12) +#define XM9_MREG_VID_MODE_UDL (1 << 13) +#define XM9_MREG_VID_MODE_RPL (3 << 12) +#define XM9_MREG_BUF_VID_ALPHA (1 << 15) +#define XM9_MREG_APIX_MODE_MASK (7 << 16) +#define XM9_MREG_APIX_MODE_FUDL (1 << 16) +#define XM9_MREG_APIX_MODE_FOVL (1 << 17) +#define XM9_MREG_APIX_MODE_ODB (3 << 17) +#define XM9_MREG_APIX_MODE_BOTH (7 << 16) +#define XM9_MREG_AMSB_CMAP_MASK (31 << 19) + + +#define BT445_PROTOCOL DCB_CYCLES(1,1,3) + +#define BT445_CSR_ADDR_REG (0 << DCB_CRS_SHIFT) +#define BT445_CSR_REVISION (2 << DCB_CRS_SHIFT) + +#define BT445_REVISION_REG 0x01 diff --git a/src/newport_shadow.c b/src/newport_shadow.c new file mode 100644 index 0000000..cfbf522 --- /dev/null +++ b/src/newport_shadow.c @@ -0,0 +1,89 @@ +/* + * Id: newport_shadow.c,v 1.3 2000/11/29 20:58:10 agx Exp $ + */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/newport/newport_shadow.c,v 1.3 2002/09/30 22:17:55 alanh Exp $ */ + +#include "newport.h" + +void +NewportRefreshArea8(ScrnInfoPtr pScrn, int num, BoxPtr pbox) +{ + int dx, dy, x; + CARD32 *base, *src; + NewportPtr pNewport = NEWPORTPTR(pScrn); + NewportRegsPtr pNewportRegs = pNewport->pNewportRegs; + +#define RA8_BYTES 4 /* burst 4 pixels each time */ +#define RA8_BYTE_SHIFT 2 /* 4 Pixels on each burst, so divide ShadowPitch by 4 */ +#define RA8_MASK 0xffc /* move to 4 byte boundary */ + + TRACE_ENTER("NewportRefreshArea8"); + NewportWait(pNewportRegs); + pNewportRegs->set.drawmode0 = (NPORT_DMODE0_DRAW | + NPORT_DMODE0_BLOCK | + NPORT_DMODE0_CHOST); + while(num--) { + NewportWait(pNewportRegs); + x = pbox->x1 & RA8_MASK; /* move x to 4 byte boundary */ + base = pNewport->ShadowPtr + + (pbox->y1 * (pNewport->ShadowPitch >> RA8_BYTE_SHIFT) ) + + ( x >> RA8_BYTE_SHIFT); + + pNewportRegs->set.xystarti = (x << 16) | pbox->y1; + pNewportRegs->set.xyendi = ((pbox->x2-1) << 16) | (pbox->y2-1); + + for ( dy = pbox->y1; dy < pbox->y2; dy++) { + + src = base; + for ( dx = x; dx < pbox->x2; dx += RA8_BYTES) { + pNewportRegs->go.hostrw0 = *src; + src++; + } + base += ( pNewport->ShadowPitch >> RA8_BYTE_SHIFT ); + } + pbox++; + } + TRACE_EXIT("NewportRefreshArea8"); +} + + +void +NewportRefreshArea24(ScrnInfoPtr pScrn, int num, BoxPtr pbox) +{ + int dx, dy; + CARD8 *src, *base; + CARD32 dest; + NewportPtr pNewport = NEWPORTPTR(pScrn); + NewportRegsPtr pNewportRegs = pNewport->pNewportRegs; + + TRACE_ENTER("NewportRefreshArea24"); + NewportWait(pNewportRegs); + + /* block transfers */ + pNewportRegs->set.drawmode0 = (NPORT_DMODE0_DRAW | + NPORT_DMODE0_BLOCK | + NPORT_DMODE0_CHOST); + + while(num--) { + base = (CARD8*)pNewport->ShadowPtr + pbox->y1 * pNewport->ShadowPitch + pbox->x1 * 3; + + pNewportRegs->set.xystarti = (pbox->x1 << 16) | pbox->y1; + pNewportRegs->set.xyendi = ((pbox->x2-1) << 16) | (pbox->y2-1); + + for ( dy = pbox->y1; dy < pbox->y2; dy++) { + src = base; + for ( dx = pbox->x1 ; dx < pbox->x2 ; dx++) { + /* Removing these shifts by using 32bpp fb + * yields < 2% percent performance gain and wastes 25% memory + */ + dest = src[0] | src[1] << 8 | src[2] << 16; + pNewportRegs->go.hostrw0 = dest; + src+=3; + } + base += pNewport->ShadowPitch; + } + pbox++; + } + TRACE_EXIT("NewportRefreshArea24"); +} + |