diff --git a/external/mit/xf86-video-newport/dist/README b/external/mit/xf86-video-newport/dist/README index 659b8010d..4322cc6d6 100644 --- a/external/mit/xf86-video-newport/dist/README +++ b/external/mit/xf86-video-newport/dist/README @@ -18,7 +18,7 @@ 1. Supported Hardware - This is an unaccelerated driver for the SGI newport cards (a.k.a. XL) + This is an XAA accelerated driver for the SGI newport cards (a.k.a. XL) as found in the SGI Indy and Indigo2. Both the 8bit and 24bit versions are tested and working. @@ -30,15 +30,22 @@ o Hardware cursor support to reduce flicker + o Acceleration of XAA operations for both XL8 and XL24 cards + 3. Notes o X -configure does not generate a xorg.conf file. - o There's only a 1280x1024 mode. + o There's support for both 1024x768 and 1280x1024 modes, but with + some caveats/bugs around timing. + o Operating in 8 bit mode will use an 8 bit PseudoColor configuration + with private colour maps, rather than the hardware 24 -> 8 bit colour + dithering support. + o The XAA Acceleration support is slightly different for XL8 versus XL24. 4. Configuration @@ -62,7 +69,13 @@ o BusID - set this to "1" on the Indigo2 XL + o NoAccel - disable Acceleration Options + o XmapTiming - Set the XMAP9 Mode Timing - 1 for Fast, 2 for Slow, + 3 for Very Slow. Since the driver currently doesn't parse all of + the monitor information, you may need to set the Timing to 2 + (ie Slow) for 1024x760 60Hz operation. Very Slow is likely for + NTSC/PAL timings which we currently don't have a way to configure. 5. Authors diff --git a/external/mit/xf86-video-newport/dist/src/newport.h b/external/mit/xf86-video-newport/dist/src/newport.h index 435304310..de6e66715 100644 --- a/external/mit/xf86-video-newport/dist/src/newport.h +++ b/external/mit/xf86-video-newport/dist/src/newport.h @@ -57,10 +57,18 @@ # define TRACE(str) #endif +typedef enum { + XmapTimingUnset = 0, + XmapTimingFast = 1, + XmapTimingSlow = 2, + XmapTimingVerySlow = 3, +} XmapTimingType; + typedef struct { unsigned busID; int bitplanes; - Bool NoAccel; + XmapTimingType XmapTiming; /* which xmap9 timing to use */ + Bool NoAccel; /* TRUE = disable acceleration */ /* 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 */ @@ -152,7 +160,9 @@ 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); +void NewportXmap9WriteRegister(NewportRegsPtr pNewportRegs, unsigned dcbaddr, unsigned dcbreg, CARD8 value); +CARD8 NewportXmap9ReadRegister(NewportRegsPtr pNewportRegs, unsigned dcbaddr, unsigned dcbreg); +void NewportXmap9SetModeRegister(NewportPtr pNewport, CARD8 address, CARD32 mode); CARD32 NewportXmap9GetModeRegister(NewportRegsPtr pNewportRegs, unsigned chip, CARD8 address); void NewportBackupRex3( ScrnInfoPtr pScrn); void NewportRestoreRex3( ScrnInfoPtr pScrn); diff --git a/external/mit/xf86-video-newport/dist/src/newport_accel.c b/external/mit/xf86-video-newport/dist/src/newport_accel.c index 450c88a2a..29b0d8898 100644 --- a/external/mit/xf86-video-newport/dist/src/newport_accel.c +++ b/external/mit/xf86-video-newport/dist/src/newport_accel.c @@ -115,6 +115,21 @@ NewportWaitGFIFO(NewportPtr pNewport, unsigned int uEntries) /******************************************************************************* *******************************************************************************/ + +/* + * Wait until 'uEntries' are available in the GFIFO. + * + * This tracks how many entries are in the fifo via the + * fifoleft value, and will avoid reading the FIFO itself + * if it estimates enough entries are left in the FIFO. + * Once the estimate runs out, it will update the + * number of FIFO entries available. + * + * TODO: add some counters here; it'd be nice to know + * how often the prediction works, how often we ran out + * and needed to read the GFIFO register, how often we + * had to spin waiting. + */ static void NewportWaitGFIFO(NewportPtr pNewport, unsigned int uEntries) { @@ -149,7 +164,14 @@ NewportWaitGFIFO(NewportPtr pNewport, unsigned int uEntries) pNewport->fifoleft -= uEntries; return; } - + + /* + * This is a CPU busy loop which is not the most efficient + * use of CPU, especially if the X server is multi-threaded. + * + * TODO: attempt to keep counters here; it'd be nice to know + * how often this is being hit. + */ for (x = 0, i = 0; i < NEWPORT_DELAY; i++) { x += i; @@ -217,6 +239,15 @@ NewportUpdateClipping(NewportPtr pNewport) /******************************************************************************* *******************************************************************************/ + +/* + * Map the XAA colours to the HOSTRW format. + * + * The HOSTRW format for RGBA-32 is ABGR, A being MSB and + * R being LSB. + * + * See the REX3 specification, Section 3.10 (Framebuffer PIO and DMA.) + */ static unsigned int NewportColor2HOSTRW(unsigned int color) { @@ -236,24 +267,40 @@ NewportColor2HOSTRW(unsigned int color) /******************************************************************************* *******************************************************************************/ + +/* + * Map the 24 bit RGB colour into the required framebuffer pixel + * layout for 24 bit pixels. + * + * The pixel format is in the REX3 specification Section 3.9 + * (framebuffer formats.) It's an interleaved pixel format, + * starting at the MSB (bit 23), going BRG(0), BRG(1), BRG(2) .. + * BRG(7). + */ static unsigned int -NewportColor2Planes24(unsigned int color) +NewportColor2Planes24RGB(unsigned int color) { unsigned int res; unsigned int i; unsigned int mr, mg, mb; unsigned int sr, sg, sb; - + + res = 0; +#if 0 + /* XAA color is 0,R,G,B */ - - res = 0; -#if 0 + mr = 0x800000; mg = 0x008000; mb = 0x000080; -#endif +#endif + + /* + * The XAA format is now BGR, to match the hardware mapping. + * However the raw pixel format is not this. + */ mr = 0x000080; mg = 0x008000; mb = 0x800000; @@ -281,8 +328,14 @@ NewportColor2Planes24(unsigned int color) /******************************************************************************* *******************************************************************************/ + +/* + * Map the 8 bit colour index to the underlying framebuffer pixel layout. + * + * For Psuedocolour pixels, this is a 1:1 mapping of bits 7:0. + */ static unsigned int -NewportColor2Planes8(unsigned int color) +NewportColor2Planes8CI(unsigned int color) { return color; } @@ -305,6 +358,13 @@ NewportUpdateCOLORI(NewportPtr pNewport, unsigned long colori) /******************************************************************************* *******************************************************************************/ + +/* + * Update the DRAWMODE0 register. + * + * TODO: does this register stall the pipeline? The REX3 documentation + * is unclear. + */ static void NewportUpdateDRAWMODE0(NewportPtr pNewport, unsigned long drawmode0) { @@ -320,6 +380,14 @@ NewportUpdateDRAWMODE0(NewportPtr pNewport, unsigned long drawmode0) /******************************************************************************* *******************************************************************************/ + +/* + * Update the DRAWMODE1 register. + * + * This register stalls the pipeline until clear when written to. + * + * TODO: should update GFIFO depth when this is written to! + */ static void NewportUpdateDRAWMODE1(NewportPtr pNewport, unsigned long drawmode1) { @@ -334,6 +402,14 @@ NewportUpdateDRAWMODE1(NewportPtr pNewport, unsigned long drawmode1) /******************************************************************************* *******************************************************************************/ + +/* + * Update the COLORVRAM register. + * + * This register stalls the pipeline until clear when written to. + * + * TODO: should update GFIFO depth when this is written to! + */ static void NewportUpdateCOLORVRAM(NewportPtr pNewport, unsigned long colorvram) { @@ -348,6 +424,14 @@ NewportUpdateCOLORVRAM(NewportPtr pNewport, unsigned long colorvram) /******************************************************************************* *******************************************************************************/ + +/* + * Update the COLORBACK register. + * + * This register stalls the pipeline until clear when written to. + * + * TODO: should update GFIFO depth when this is written to! + */ static void NewportUpdateCOLORBACK(NewportPtr pNewport, unsigned long colorback) { @@ -362,6 +446,14 @@ NewportUpdateCOLORBACK(NewportPtr pNewport, unsigned long colorback) /******************************************************************************* *******************************************************************************/ + +/* + * Update the WRMASK register. + * + * This register stalls the pipeline until clear when written to. + * + * TODO: should update GFIFO depth when this is written to! + */ static void NewportUpdateWRMASK(NewportPtr pNewport, unsigned long wrmask) { @@ -376,6 +468,14 @@ NewportUpdateWRMASK(NewportPtr pNewport, unsigned long wrmask) /******************************************************************************* *******************************************************************************/ + +/* + * Update the XYMOVE register. + * + * This register stalls the pipeline until clear when written to. + * + * TODO: should update GFIFO depth when this is written to! + */ static void NewportUpdateXYMOVE(NewportPtr pNewport, unsigned long xymove) { @@ -558,6 +658,10 @@ NewportXAASubsequentSolidFillRect(ScrnInfoPtr pScrn, /******************************************************************************* *******************************************************************************/ + +/* + * Setup for a Solid Line draw + */ static void NewportXAASetupForSolidLine(ScrnInfoPtr pScrn, int Color, @@ -587,6 +691,18 @@ NewportXAASetupForSolidLine(ScrnInfoPtr pScrn, /******************************************************************************* *******************************************************************************/ + +/* + * Draw a solid line + * + * TODO: surely the XAA server is feeding us a list of lines + * to write, rather than a constant setup/line/setup/line etc. + * See xaa/xaaLine.c for more info. + * + * Apparently if POLYSEGMENT is defined then we get a flag + * that says whether to draw the last pixel or not, but it's + * not really a "this is the last line to batch". + */ static void NewportXAASubsequentSolidTwoPointLine(ScrnInfoPtr pScrn, int x1, @@ -599,7 +715,11 @@ NewportXAASubsequentSolidTwoPointLine(ScrnInfoPtr pScrn, NewportPtr pNewport; pNewport = NEWPORTPTR(pScrn); pNewportRegs = NEWPORTREGSPTR(pScrn); - + + /* + * TODO: if this doesn't stall the pipeline then it makes sense + * that we can keep changing drawmode0 on each line draw. + */ NewportUpdateDRAWMODE0(pNewport, pNewport->setup_drawmode0 | ((flags & OMIT_LAST) ? NPORT_DMODE0_SKLST : 0) @@ -1149,6 +1269,13 @@ NewportXAADisableClipping(ScrnInfoPtr pScrn) /******************************************************************************* *******************************************************************************/ + +/* + * TODO: it would be good to keep some counters on how large + * the average/min/max fill is and how many points are passed + * in; that'd give us a good idea as to whether these would + * benefit by being turned into DMA and save some CPU resources. + */ static void NewportPolyPoint(DrawablePtr pDraw, GCPtr pGC, @@ -1496,11 +1623,12 @@ NewportRenderTexture1to1(NewportPtr pNewport, int srcx, int srcy, int w, int h) p = pNewport->pTexture + srcx + (srcy * pNewport->uTextureWidth); add = pNewport->uTextureWidth - w + srcx; + while (h--) { for (d = w; d; d--) { - /*NewportWaitGFIFO(pNewport, 1);*/ + NewportWaitGFIFO(pNewport, 1); /* hopefully we cannot write faster than XL24 can blend */ pNewportRegs->go.hostrw0 = *p++; } @@ -1539,6 +1667,8 @@ NewportRenderTextureScale(NewportPtr pNewport, int srcx, int srcy, int w, int h) p = (curx + 0x7FFF) >> 16; if (p >= pNewport->uTextureWidth) p = pNewport->uTextureWidth-1; + /* TODO: does this need a FIFO check? */ + NewportWaitGFIFO(pNewport, 1); pNewportRegs->go.hostrw0 = pLine[p]; curx += dx; } @@ -1560,11 +1690,13 @@ NewportRenderTextureRepeat(NewportPtr pNewport, int srcx, int srcy, int w, int h srcx %= pNewport->uTextureWidth; srcy %= pNewport->uTextureHeight; + while (h--) { pLine = pNewport->pTexture + pNewport->uTextureWidth * srcy; for (d = w; d; d--) { + NewportWaitGFIFO(pNewport, 1); pNewportRegs->go.hostrw0 = pLine[srcx]; srcx++; if (srcx >= pNewport->uTextureWidth) @@ -1694,6 +1826,10 @@ NewportXAAScreenInit(ScreenPtr pScreen) pXAAInfoRec->SetupForCPUToScreenColorExpandFill = NewportXAASetupForCPUToScreenColorExpandFill; pXAAInfoRec->SubsequentCPUToScreenColorExpandFill = NewportXAASubsequentCPUToScreenColorExpandFill; pXAAInfoRec->ColorExpandRange = 4; + /* + * TODO: is this OK? There's no FIFO check here, is it possible + * that we'd fill the GFIFO and bus error? + */ pXAAInfoRec->ColorExpandBase = (unsigned char *)&(pNewportRegs->go.zpattern); @@ -1722,6 +1858,10 @@ NewportXAAScreenInit(ScreenPtr pScreen) pXAAInfoRec->SetupForImageWrite = NewportXAASetupForImageWrite; pXAAInfoRec->SubsequentImageWriteRect = NewportXAASubsequentImageWriteRect; pXAAInfoRec->ImageWriteRange = 4; + /* + * TODO: is this OK? There's no FIFO check here, is it possible + * that we'd fill the GFIFO and bus error? + */ pXAAInfoRec->ImageWriteBase = (unsigned char *)&(pNewportRegs->go.hostrw0); /* read pixmap */ @@ -1750,6 +1890,17 @@ NewportXAAScreenInit(ScreenPtr pScreen) pXAAInfoRec->ValidatePolyArc = NewportValidatePolyArc; pXAAInfoRec->PolyArcMask = GCFunction | GCLineWidth; + + /* + * TODO: Revisit this once the rest of the driver is converted to + * properly separate the newport device type / bitplane count versus + * the screen depth. + * + * We're not doing alpha blending on 8bpp screens because + * they're psuedo colour screens, but we CAN do alpha blending + * on an XL8 that's being fed RGB-24 and RGBA-32 pixel data + * via HOSTRW. + */ #ifdef RENDER if (pScrn->bitsPerPixel > 8) { @@ -1769,11 +1920,38 @@ NewportXAAScreenInit(ScreenPtr pScreen) pNewport->pTexture = (unsigned int *)xnfalloc(pNewport->uTextureSize = 16*16*sizeof(unsigned int)); } #endif - - pNewport->Color2Planes = NewportColor2Planes24; + + /* + * Configure acceleration based on the screen config and the + * Newport bitplane config. + * + * The WRMASK register (which this routine is populating) is + * based on the raw framebuffer pixel data being written, + * /not/ specifically the HOSTRW format being written. + * The HOSTRW format can include whether the pixel values + * are packed or not; whereas this field is the raw field + * in the table. + * + * See REX3 specification section 3.3 (Clipping and Masking) + * and 3.9 (Framebuffer formats) for more information. + * + * TODO: this needs to be revisited when configuring other + * framebuffer pixel layouts, eg 24 bit colour writes + * into HOSTRW, but a RGB-332 framebuffer. + * + * In this instance, we'd choose a function based on + * pixel config (eg RGB888, RGB444, RGB332, CI) and + * eventually also the double buffering target plane. + */ + pNewport->Color2Planes = NewportColor2Planes24RGB; + /* + * TODO: this is looking at the screen bpp, it should be changed + * to look at the DRAWDEPTH/PLANES/RWPACKED field and choose + * appropriately. + */ if (pScrn->bitsPerPixel == 8) { - pNewport->Color2Planes = NewportColor2Planes8; + pNewport->Color2Planes = NewportColor2Planes8CI; } if (!XAAInit(pScreen, pXAAInfoRec)) diff --git a/external/mit/xf86-video-newport/dist/src/newport_driver.c b/external/mit/xf86-video-newport/dist/src/newport_driver.c index d4c08598b..da56ffbbb 100644 --- a/external/mit/xf86-video-newport/dist/src/newport_driver.c +++ b/external/mit/xf86-video-newport/dist/src/newport_driver.c @@ -166,7 +166,8 @@ typedef enum { OPTION_BITPLANES, OPTION_BUS_ID, OPTION_HWCURSOR, - OPTION_NOACCEL + OPTION_NOACCEL, + OPTION_XMAP_TIMING, } NewportOpts; /* Supported options */ @@ -175,6 +176,7 @@ static const OptionInfoRec NewportOptions [] = { { OPTION_BUS_ID, "BusID", OPTV_INTEGER, {0}, FALSE }, { OPTION_HWCURSOR, "HWCursor", OPTV_BOOLEAN, {0}, FALSE }, { OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_XMAP_TIMING, "XmapTiming", OPTV_INTEGER, {0}, FALSE }, { -1, NULL, OPTV_NONE, {0}, FALSE } }; @@ -500,6 +502,55 @@ NewportPreInit(ScrnInfoPtr pScrn, int flags) Bool NewportXAAScreenInit(ScreenPtr pScreen); +/* + * Parse the xmap timing option if it exists. + * + * Return true if it's valid, false if it's invalid. + * If it's not present then return true; this is to signal + * if the caller should quit the driver setup path. + */ +static Bool +NewportOptionXmapConfig(ScrnInfoPtr pScrn, NewportPtr pNewport) +{ + int t; + + /* Initialise / parse the Xmap timing type */ + pNewport->XmapTiming = XmapTimingUnset; + + if (xf86GetOptValInteger(pNewport->Options, OPTION_XMAP_TIMING, &t)) { + switch (t) { + case XmapTimingFast: + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "No XmapTiming set to FAST\n"); + pNewport->XmapTiming = t; + break; + case XmapTimingSlow: + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "No XmapTiming set to SLOW\n"); + pNewport->XmapTiming = t; + break; + case XmapTimingVerySlow: + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "No XmapTiming set to VERYSLOW\n"); + pNewport->XmapTiming = t; + break; + default: + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "XmapTiming value (%d) is not valid!\n", t); + return FALSE; + } + } + + /* Default to "fast" for now, preserve existing behaviour */ + if (pNewport->XmapTiming == XmapTimingUnset) { + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "No XmapTiming provided; defaulting to FAST\n"); + pNewport->XmapTiming = XmapTimingFast; + } + + return TRUE; +} + static Bool NewportScreenInit(int index, ScreenPtr pScreen, int argc, char **argv) @@ -574,6 +625,11 @@ NewportScreenInit(int index, ScreenPtr pScreen, int argc, char **argv) xf86SetBackingStore(pScreen); xf86SetBlackWhitePixels(pScreen); + + /* Parse the xmap config */ + if (! NewportOptionXmapConfig(pScrn, pNewport)) + return FALSE; + #ifdef NEWPORT_ACCEL pNewport->NoAccel = FALSE; if (xf86ReturnOptValBool(pNewport->Options, OPTION_NOACCEL, FALSE)) @@ -731,12 +787,54 @@ NewportAvailableOptions(int chipid, int busid) return NewportOptions; } +/* + * Setup all 32 mode/DID entries in the xmap9 tables with the + * same mode. + */ +static void +NewportSetXmapModeTable(NewportPtr pNewport, uint32_t mode) +{ + NewportRegsPtr pNewportRegs = pNewport->pNewportRegs; + int i; + + for (i = 0; i < 32; i++) { + NewportBfwait(pNewport->pNewportRegs); + NewportXmap9SetModeRegister(pNewport, i, mode); + } + + /* select the set up mode register */ + NewportBfwait(pNewport->pNewportRegs); + NewportXmap9WriteRegister(pNewportRegs, DCB_XMAP_ALL, + XM9_CRS_MODE_REG_INDEX, 0); +} + +/* + * Setup the XMAP9 for the given requested operating mode. + * + * For now it's a no-op, but eventually it should explicitly configure + * 8 or 24 bit mode depending upon the requested config and supported + * hardware. + */ +static void +NewportHwSetupXmapMode(NewportPtr pNewport) +{ +#if 0 + /* TODO: refactor this out; program them separately to not mess with odd/even dithering! */ + 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); +#endif +} /* This sets up the actual mode on the Newport */ static Bool NewportModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode) { int width, height; + int i; NewportPtr pNewport = NEWPORTPTR(pScrn); NewportRegsPtr pNewportRegs = NEWPORTREGSPTR(pScrn); @@ -763,33 +861,39 @@ NewportModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode) NPORT_DMODE1_CCEQ | NPORT_DMODE1_CCGT | NPORT_DMODE1_LOSRC; + + /* Configure the XMAP mode */ + NewportHwSetupXmapMode(pNewport); + if( pNewport->Bpp == 1) { /* 8bpp */ + /* + * Configure 8 bit draw depth, 8 bit host pixel packing. + * Note that RGB mode isn't enabled here because + * the CI mode is being used. + */ pNewport->drawmode1 |= NPORT_DMODE1_DD8 | NPORT_DMODE1_HD8 | NPORT_DMODE1_RWPCKD; + + /* + * Setup the mode table for 8 bit colour indexed table, + * not an RGB mode; it will use CMAP CI table 0. + */ + NewportSetXmapModeTable(pNewport, + XM9_MREG_PIX_SIZE_8BPP | XM9_MREG_PIX_MODE_CI | + XM9_MREG_GAMMA_BYPASS); + } else { /* 24bpp */ CARD32 mode = 0L; - LOCO col; - int i; /* 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_RGB2 - | XM9_MREG_GAMMA_BYPASS; - for (i = 0; i < 32; i++) - NewportXmap9SetModeRegister( pNewportRegs , i, 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; + /* + * Setup the mode table for RGB 888 (24 bit), use the + * RGB2 CMAP table. + */ + NewportSetXmapModeTable(pNewport, XM9_MREG_PIX_SIZE_24BPP + | XM9_MREG_PIX_MODE_RGB2 | XM9_MREG_GAMMA_BYPASS); pNewport->drawmode1 |= /* set drawdepth to 24 bit */ @@ -802,19 +906,29 @@ NewportModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode) * After setting up XMAP9 we have to reinitialize the CMAP for * whatever reason (the docs say nothing about it). */ - - for (i = 0; i < 256; i++) { + LOCO col; + col.red = col.green = col.blue = i; NewportCmapSetRGB(NEWPORTREGSPTR(pScrn), i, col); } - for (i = 0; i < 256; i++) { - col.red = col.green = col.blue = i; - NewportCmapSetRGB(NEWPORTREGSPTR(pScrn), i + 0x1f00, - col); - } + } + /* + * Always setup an RGB2 ramp regardless of 8 or 24 bit operation. + * + * This table will be needed if eventually support is added for + * RGB8 operation (whether XL8 or XL24) rather than 8 bit indexed + * colour tables. + */ + for (i = 0; i < 256; i++) { + LOCO col; + + col.red = col.green = col.blue = i; + NewportCmapSetRGB(NEWPORTREGSPTR(pScrn), i + 0x1f00, + col); } + /* blank the framebuffer */ NewportWait(pNewportRegs); pNewportRegs->set.drawmode0 = (NPORT_DMODE0_DRAW | @@ -905,6 +1019,7 @@ static Bool NewportProbeCardInfo(ScrnInfoPtr pScrn) unsigned int tmp,cmap_rev; NewportPtr pNewport = NEWPORTPTR(pScrn); NewportRegsPtr pNewportRegs = pNewport->pNewportRegs; + CARD8 val; NewportWait(pNewportRegs); pNewportRegs->set.dcbmode = (DCB_CMAP0 | NCMAP_PROTOCOL | @@ -915,10 +1030,8 @@ static Bool NewportProbeCardInfo(ScrnInfoPtr pScrn) 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)); + val = NewportXmap9ReadRegister(pNewportRegs, DCB_XMAP0, XM9_CRS_REVISION); + pNewport->xmap9_rev = (char)('A'+(val & 7)); /* XXX: read possible modes from VC2 here */ return TRUE; diff --git a/external/mit/xf86-video-newport/dist/src/newport_regs.c b/external/mit/xf86-video-newport/dist/src/newport_regs.c index a4168e011..16c010a06 100644 --- a/external/mit/xf86-video-newport/dist/src/newport_regs.c +++ b/external/mit/xf86-video-newport/dist/src/newport_regs.c @@ -104,21 +104,91 @@ static void NewportXmap9FifoWait(NewportRegsPtr pNewportRegs, unsigned long xmapChip) { while(1) { + CARD8 val; + NewportBfwait( pNewportRegs); - pNewportRegs->set.dcbmode = (xmapChip | R_DCB_XMAP9_PROTOCOL | - XM9_CRS_FIFO_AVAIL | NPORT_DMODE_W1); - if( (pNewportRegs->set.dcbdata0.bytes.b3) & 7 ) + + val = NewportXmap9ReadRegister(pNewportRegs, xmapChip, + XM9_CRS_FIFO_AVAIL); + + if (val & 0x07) break; } } +/* + * Write a value to the given Xmap9 chip. + * + * The caller is responsible for calling NewportBfwait() first in case + * they want to optimise multiple writes. + * + * This can write to DCB_XMAP0, DCB_XMAP1 or both via DCB_XMAPALL. + * + * dcbreg is one of the XM9_CRS_* values which represent the already + * shifted register values, just to make porting code over easier. + */ void -NewportXmap9SetModeRegister(NewportRegsPtr pNewportRegs, CARD8 address, CARD32 mode) +NewportXmap9WriteRegister(NewportRegsPtr pNewportRegs, unsigned dcbaddr, + unsigned dcbreg, CARD8 value) { + pNewportRegs->set.dcbmode = ( dcbaddr | W_DCB_XMAP9_PROTOCOL | + dcbreg | NPORT_DMODE_W1 ); + pNewportRegs->set.dcbdata0.bytes.b3 = value; +} + +/* + * Read a value to the given Xmap9 chip. + * + * This will stall the BFIFO until pending writes are completed, so I + * believe NewportBfwait() isn't required. + * + * This must only be used on either DCB_XMAP0 or DCB_XMAP1, + * /NOT/ DCB_XMAPALL. + * + * dcbreg is one of the XM9_CRS_* values which represent the already + * shifted register values, just to make porting code over easier. + */ +CARD8 +NewportXmap9ReadRegister(NewportRegsPtr pNewportRegs, unsigned dcbaddr, + unsigned dcbreg) +{ + pNewportRegs->set.dcbmode = ( dcbaddr | R_DCB_XMAP9_PROTOCOL | + dcbreg | NPORT_DMODE_W1 ); + return (pNewportRegs->set.dcbdata0.bytes.b3); +} + +/* + * Configure the XMAP9 Mode Register at DID address 'address'. + * + * The default, "fast", isn't suitable for 1024x768x60Hz, + * the default resolution for the Indy if there's no recognised + * monitor. + */ +void +NewportXmap9SetModeRegister(NewportPtr pNewport, CARD8 address, CARD32 mode) +{ + NewportRegsPtr pNewportRegs = pNewport->pNewportRegs; + uint32_t timing; + NewportXmap9FifoWait( pNewportRegs, DCB_XMAP0); NewportXmap9FifoWait( pNewportRegs, DCB_XMAP1); - pNewportRegs->set.dcbmode = (DCB_XMAP_ALL | W_DCB_XMAP9_PROTOCOL | + switch (pNewport->XmapTiming) { + case XmapTimingFast: + timing = WFAST_DCB_XMAP9_PROTOCOL; + break; + case XmapTimingSlow: + timing = WSLOW_DCB_XMAP9_PROTOCOL; + break; + case XmapTimingVerySlow: + timing = WAYSLOW_DCB_XMAP9_PROTOCOL; + break; + default: + timing = WFAST_DCB_XMAP9_PROTOCOL; + break; + } + + pNewportRegs->set.dcbmode = (DCB_XMAP_ALL | timing | XM9_CRS_MODE_REG_DATA | NPORT_DMODE_W4 ); pNewportRegs->set.dcbdata0.all = (address << 24) | ( mode & 0xffffff ); } @@ -138,12 +208,10 @@ NewportXmap9GetModeRegister(NewportRegsPtr pNewportRegs, unsigned chip, CARD8 ad 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; + NewportXmap9WriteRegister(pNewportRegs, dcbaddr, + XM9_CRS_MODE_REG_INDEX, (index | i)); + val = NewportXmap9ReadRegister(pNewportRegs, dcbaddr, + XM9_CRS_MODE_REG_DATA); mode |= (val << ( i * 8 ) ); } return mode; @@ -186,27 +254,28 @@ 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); + pNewport->txt_xmap9_cfg0 = NewportXmap9ReadRegister(pNewportRegs, + DCB_XMAP0, XM9_CRS_CONFIG); + /* 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); + pNewport->txt_xmap9_cfg1 = NewportXmap9ReadRegister(pNewportRegs, + DCB_XMAP1, XM9_CRS_CONFIG); + /* 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; + NewportBfwait(pNewport->pNewportRegs); + pNewport->txt_xmap9_mi = NewportXmap9ReadRegister(pNewportRegs, + DCB_XMAP0, XM9_CRS_MODE_REG_INDEX); + /* 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; + NewportBfwait(pNewport->pNewportRegs); + pNewport->txt_xmap9_ccmsb = NewportXmap9ReadRegister(pNewportRegs, + DCB_XMAP0, XM9_CRS_CURS_CMAP_MSB); } void NewportRestoreXmap9s( ScrnInfoPtr pScrn) @@ -215,25 +284,26 @@ void NewportRestoreXmap9s( ScrnInfoPtr pScrn) NewportRegsPtr pNewportRegs = NEWPORTREGSPTR(pScrn); /* mode register 0 */ - NewportXmap9SetModeRegister( pNewportRegs , 0, pNewport->txt_xmap9_mod0 ); - NewportBfwait(pNewport->pNewportRegs); + NewportXmap9SetModeRegister( pNewport, 0, pNewport->txt_xmap9_mod0 ); + /* 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); + NewportXmap9WriteRegister(pNewportRegs, DCB_XMAP_ALL, + XM9_CRS_MODE_REG_INDEX, pNewport->txt_xmap9_mi); + /* 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); + NewportXmap9WriteRegister(pNewportRegs, DCB_XMAP0, XM9_CRS_CONFIG, + pNewport->txt_xmap9_cfg0); + /* 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; + NewportBfwait(pNewport->pNewportRegs); + NewportXmap9WriteRegister(pNewportRegs, DCB_XMAP1, XM9_CRS_CONFIG, + 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; + NewportBfwait(pNewport->pNewportRegs); + NewportXmap9WriteRegister(pNewportRegs, DCB_XMAP_ALL, + XM9_CRS_CURS_CMAP_MSB, pNewport->txt_xmap9_ccmsb); } diff --git a/external/mit/xf86-video-newport/dist/src/newport_regs.h b/external/mit/xf86-video-newport/dist/src/newport_regs.h index 5c2a01b99..9e225a5ef 100644 --- a/external/mit/xf86-video-newport/dist/src/newport_regs.h +++ b/external/mit/xf86-video-newport/dist/src/newport_regs.h @@ -412,10 +412,14 @@ struct Newport_regs { (setup << DCB_CSSETUP_SHIFT)| \ (width << DCB_CSWIDTH_SHIFT)) -#define W_DCB_XMAP9_PROTOCOL DCB_CYCLES (1, 2, 3) +/* Normal read/write for single byte register write */ +#define W_DCB_XMAP9_PROTOCOL DCB_CYCLES (2, 1, 0) +#define R_DCB_XMAP9_PROTOCOL DCB_CYCLES (2, 1, 3) + +/* 32 bit mode registers based on pixel clock */ +#define WFAST_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) @@ -423,8 +427,9 @@ struct Newport_regs { #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_CI (0 << 8) #define XM9_MREG_PIX_MODE_RGB0 (1 << 8) -#define XM9_MREG_PIX_MODE_RGB1 (1 << 9) +#define XM9_MREG_PIX_MODE_RGB1 (2 << 8) #define XM9_MREG_PIX_MODE_RGB2 (3 << 8) #define XM9_MREG_PIX_SIZE_MASK (3 << 10) #define XM9_MREG_PIX_SIZE_8BPP (1 << 10)