150806d53Smrg
250806d53Smrg#ifdef HAVE_CONFIG_H
350806d53Smrg#include "config.h"
450806d53Smrg#endif
550806d53Smrg
650806d53Smrg#include "xf86.h"
750806d53Smrg#include "xf86_OSproc.h"
850806d53Smrg#include "xf86Pci.h"
950806d53Smrg#include "i128.h"
1050806d53Smrg#include "dgaproc.h"
1150806d53Smrg
1250806d53Smrg
1350806d53Smrgstatic Bool I128_OpenFramebuffer(ScrnInfoPtr, char **, unsigned char **,
1450806d53Smrg					int *, int *, int *);
1550806d53Smrgstatic Bool I128_SetMode(ScrnInfoPtr, DGAModePtr);
1650806d53Smrgstatic int  I128_GetViewport(ScrnInfoPtr);
1750806d53Smrgstatic void I128_SetViewport(ScrnInfoPtr, int, int, int);
18a73423d7Smrg#ifdef HAVE_XAA_H
1950806d53Smrgstatic void I128_FillRect(ScrnInfoPtr, int, int, int, int, unsigned long);
2050806d53Smrgstatic void I128_BlitRect(ScrnInfoPtr, int, int, int, int, int, int);
2150806d53Smrg#if 0
2250806d53Smrgstatic void I128_BlitTransRect(ScrnInfoPtr, int, int, int, int, int, int,
2350806d53Smrg					unsigned long);
2450806d53Smrg#endif
25a73423d7Smrg#endif
2650806d53Smrg
2750806d53Smrgstatic
2850806d53SmrgDGAFunctionRec I128_DGAFuncs = {
2950806d53Smrg   I128_OpenFramebuffer,
3050806d53Smrg   NULL,
3150806d53Smrg   I128_SetMode,
3250806d53Smrg   I128_SetViewport,
3350806d53Smrg   I128_GetViewport,
3450806d53Smrg   I128EngineDone,
35a73423d7Smrg#ifdef HAVE_XAA_H
3650806d53Smrg   I128_FillRect,
3750806d53Smrg   I128_BlitRect,
3850806d53Smrg#if 0
3950806d53Smrg   I128_BlitTransRect
4050806d53Smrg#else
4150806d53Smrg   NULL
4250806d53Smrg#endif
43a73423d7Smrg#else
44a73423d7Smrg   NULL, NULL, NULL
45a73423d7Smrg#endif
4650806d53Smrg};
4750806d53Smrg
4850806d53Smrg
4950806d53SmrgBool
5050806d53SmrgI128DGAInit(ScreenPtr pScreen)
5150806d53Smrg{
52a73423d7Smrg   ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
5350806d53Smrg   I128Ptr pI128 = I128PTR(pScrn);
5450806d53Smrg   DGAModePtr modes = NULL, newmodes = NULL, currentMode;
5550806d53Smrg   DisplayModePtr pMode, firstMode;
5650806d53Smrg   int Bpp = pScrn->bitsPerPixel >> 3;
5750806d53Smrg   int num = 0;
5850806d53Smrg   Bool oneMore;
5950806d53Smrg
6050806d53Smrg   pMode = firstMode = pScrn->modes;
6150806d53Smrg
6250806d53Smrg   while(pMode) {
6350806d53Smrg
6450806d53Smrg	if(0 /*pScrn->displayWidth != pMode->HDisplay*/) {
65a73423d7Smrg	    newmodes = realloc(modes, (num + 2) * sizeof(DGAModeRec));
6650806d53Smrg	    oneMore = TRUE;
6750806d53Smrg	} else {
68a73423d7Smrg	    newmodes = realloc(modes, (num + 1) * sizeof(DGAModeRec));
6950806d53Smrg	    oneMore = FALSE;
7050806d53Smrg	}
7150806d53Smrg
7250806d53Smrg	if(!newmodes) {
73a73423d7Smrg	   free(modes);
7450806d53Smrg	   return FALSE;
7550806d53Smrg	}
7650806d53Smrg	modes = newmodes;
7750806d53Smrg
7850806d53SmrgSECOND_PASS:
7950806d53Smrg
8050806d53Smrg	currentMode = modes + num;
8150806d53Smrg	num++;
8250806d53Smrg
8350806d53Smrg	currentMode->mode = pMode;
8450806d53Smrg	currentMode->flags = DGA_CONCURRENT_ACCESS | DGA_PIXMAP_AVAILABLE;
8550806d53Smrg	currentMode->flags |= DGA_FILL_RECT | DGA_BLIT_RECT;
8650806d53Smrg	if(pMode->Flags & V_DBLSCAN)
8750806d53Smrg	   currentMode->flags |= DGA_DOUBLESCAN;
8850806d53Smrg	if(pMode->Flags & V_INTERLACE)
8950806d53Smrg	   currentMode->flags |= DGA_INTERLACED;
9050806d53Smrg	currentMode->byteOrder = pScrn->imageByteOrder;
9150806d53Smrg	currentMode->depth = pScrn->depth;
9250806d53Smrg	currentMode->bitsPerPixel = pScrn->bitsPerPixel;
9350806d53Smrg	currentMode->red_mask = pScrn->mask.red;
9450806d53Smrg	currentMode->green_mask = pScrn->mask.green;
9550806d53Smrg	currentMode->blue_mask = pScrn->mask.blue;
9650806d53Smrg	currentMode->visualClass = (Bpp == 1) ? PseudoColor : TrueColor;
9750806d53Smrg	currentMode->viewportWidth = pMode->HDisplay;
9850806d53Smrg	currentMode->viewportHeight = pMode->VDisplay;
9950806d53Smrg	currentMode->xViewportStep = 1;
10050806d53Smrg	currentMode->yViewportStep = 1;
10150806d53Smrg	currentMode->viewportFlags = DGA_FLIP_RETRACE;
10250806d53Smrg	currentMode->offset = 0;
10350806d53Smrg	currentMode->address = pI128->MemoryPtr;
10450806d53Smrg
10550806d53Smrg	if(oneMore) { /* first one is narrow width */
10650806d53Smrg	    currentMode->bytesPerScanline = ((pMode->HDisplay * Bpp) + 3) & ~3L;
10750806d53Smrg	    currentMode->imageWidth = pMode->HDisplay;
10850806d53Smrg	    currentMode->imageHeight =  pMode->VDisplay;
10950806d53Smrg	    currentMode->pixmapWidth = currentMode->imageWidth;
11050806d53Smrg	    currentMode->pixmapHeight = currentMode->imageHeight;
11150806d53Smrg	    currentMode->maxViewportX = currentMode->imageWidth -
11250806d53Smrg					currentMode->viewportWidth;
11350806d53Smrg	    /* this might need to get clamped to some maximum */
11450806d53Smrg	    currentMode->maxViewportY = currentMode->imageHeight -
11550806d53Smrg					currentMode->viewportHeight;
11650806d53Smrg	    oneMore = FALSE;
11750806d53Smrg	    goto SECOND_PASS;
11850806d53Smrg	} else {
11950806d53Smrg	    currentMode->bytesPerScanline =
12050806d53Smrg			((pScrn->displayWidth * Bpp) + 3) & ~3L;
12150806d53Smrg	    currentMode->imageWidth = pScrn->displayWidth;
12250806d53Smrg	    currentMode->imageHeight =  pMode->VDisplay;
12350806d53Smrg	    currentMode->pixmapWidth = currentMode->imageWidth;
12450806d53Smrg	    currentMode->pixmapHeight = currentMode->imageHeight;
12550806d53Smrg	    currentMode->maxViewportX = currentMode->imageWidth -
12650806d53Smrg					currentMode->viewportWidth;
12750806d53Smrg	    /* this might need to get clamped to some maximum */
12850806d53Smrg	    currentMode->maxViewportY = currentMode->imageHeight -
12950806d53Smrg					currentMode->viewportHeight;
13050806d53Smrg	}
13150806d53Smrg
13250806d53Smrg	pMode = pMode->next;
13350806d53Smrg	if(pMode == firstMode)
13450806d53Smrg	   break;
13550806d53Smrg   }
13650806d53Smrg
13750806d53Smrg   pI128->numDGAModes = num;
13850806d53Smrg   pI128->DGAModes = modes;
13950806d53Smrg
14050806d53Smrg    return DGAInit(pScreen, &I128_DGAFuncs, modes, num);
14150806d53Smrg}
14250806d53Smrg
14350806d53Smrg
14450806d53Smrgstatic Bool
14550806d53SmrgI128_SetMode(
14650806d53Smrg   ScrnInfoPtr pScrn,
14750806d53Smrg   DGAModePtr pMode
14850806d53Smrg){
14950806d53Smrg   static int OldDisplayWidth[MAXSCREENS];
15050806d53Smrg   int index = pScrn->pScreen->myNum;
15150806d53Smrg
15250806d53Smrg   I128Ptr pI128 = I128PTR(pScrn);
15350806d53Smrg
15450806d53Smrg   if(!pMode) { /* restore the original mode */
15550806d53Smrg	/* put the ScreenParameters back */
15650806d53Smrg
15750806d53Smrg	pScrn->displayWidth = OldDisplayWidth[index];
15850806d53Smrg
159a73423d7Smrg        I128SwitchMode(SWITCH_MODE_ARGS(pScrn, pScrn->currentMode));
16050806d53Smrg	pI128->DGAactive = FALSE;
16150806d53Smrg   } else {
16250806d53Smrg	if(!pI128->DGAactive) {  /* save the old parameters */
16350806d53Smrg	    OldDisplayWidth[index] = pScrn->displayWidth;
16450806d53Smrg
16550806d53Smrg	    pI128->DGAactive = TRUE;
16650806d53Smrg	}
16750806d53Smrg
16850806d53Smrg	pScrn->displayWidth = pMode->bytesPerScanline /
16950806d53Smrg			      (pMode->bitsPerPixel >> 3);
17050806d53Smrg
171a73423d7Smrg        I128SwitchMode(SWITCH_MODE_ARGS(pScrn, pMode->mode));
17250806d53Smrg   }
17350806d53Smrg
17450806d53Smrg   return TRUE;
17550806d53Smrg}
17650806d53Smrg
17750806d53Smrg
17850806d53Smrg
17950806d53Smrgstatic int
18050806d53SmrgI128_GetViewport(
18150806d53Smrg  ScrnInfoPtr pScrn
18250806d53Smrg){
18350806d53Smrg    I128Ptr pI128 = I128PTR(pScrn);
18450806d53Smrg
18550806d53Smrg    return pI128->DGAViewportStatus;
18650806d53Smrg}
18750806d53Smrg
18850806d53Smrgstatic void
18950806d53SmrgI128_SetViewport(
19050806d53Smrg   ScrnInfoPtr pScrn,
19150806d53Smrg   int x, int y,
19250806d53Smrg   int flags
19350806d53Smrg){
19450806d53Smrg   I128Ptr pI128 = I128PTR(pScrn);
19550806d53Smrg
196a73423d7Smrg   I128AdjustFrame(ADJUST_FRAME_ARGS(pScrn, x, y));
19750806d53Smrg   pI128->DGAViewportStatus = 0;  /* I128AdjustFrame loops until finished */
19850806d53Smrg}
19950806d53Smrg
200a73423d7Smrg#ifdef HAVE_XAA_H
20150806d53Smrgstatic void
20250806d53SmrgI128_FillRect (
20350806d53Smrg   ScrnInfoPtr pScrn,
20450806d53Smrg   int x, int y, int w, int h,
20550806d53Smrg   unsigned long color
20650806d53Smrg){
20750806d53Smrg    I128Ptr pI128 = I128PTR(pScrn);
20850806d53Smrg
20950806d53Smrg    if(pI128->XaaInfoRec) {
21050806d53Smrg	(*pI128->XaaInfoRec->SetupForSolidFill)(pScrn, color, GXcopy, ~0);
21150806d53Smrg	(*pI128->XaaInfoRec->SubsequentSolidFillRect)(pScrn, x, y, w, h);
21250806d53Smrg	SET_SYNC_FLAG(pI128->XaaInfoRec);
21350806d53Smrg    }
21450806d53Smrg}
21550806d53Smrg
21650806d53Smrgstatic void
21750806d53SmrgI128_BlitRect(
21850806d53Smrg   ScrnInfoPtr pScrn,
21950806d53Smrg   int srcx, int srcy,
22050806d53Smrg   int w, int h,
22150806d53Smrg   int dstx, int dsty
22250806d53Smrg){
22350806d53Smrg    I128Ptr pI128 = I128PTR(pScrn);
22450806d53Smrg
22550806d53Smrg    if(pI128->XaaInfoRec) {
22650806d53Smrg	int xdir = ((srcx < dstx) && (srcy == dsty)) ? -1 : 1;
22750806d53Smrg	int ydir = (srcy < dsty) ? -1 : 1;
22850806d53Smrg
22950806d53Smrg	(*pI128->XaaInfoRec->SetupForScreenToScreenCopy)(
23050806d53Smrg		pScrn, xdir, ydir, GXcopy, ~0, -1);
23150806d53Smrg	(*pI128->XaaInfoRec->SubsequentScreenToScreenCopy)(
23250806d53Smrg		pScrn, srcx, srcy, dstx, dsty, w, h);
23350806d53Smrg	SET_SYNC_FLAG(pI128->XaaInfoRec);
23450806d53Smrg    }
23550806d53Smrg}
23650806d53Smrg
23750806d53Smrg#if 0
23850806d53Smrgstatic void
23950806d53SmrgI128_BlitTransRect(
24050806d53Smrg   ScrnInfoPtr pScrn,
24150806d53Smrg   int srcx, int srcy,
24250806d53Smrg   int w, int h,
24350806d53Smrg   int dstx, int dsty,
24450806d53Smrg   unsigned long color
24550806d53Smrg){
24650806d53Smrg    I128Ptr pI128 = I128PTR(pScrn);
24750806d53Smrg
24850806d53Smrg    if(pI128->XaaInfoRec) {
24950806d53Smrg	int xdir = ((srcx < dstx) && (srcy == dsty)) ? -1 : 1;
25050806d53Smrg	int ydir = (srcy < dsty) ? -1 : 1;
25150806d53Smrg
25250806d53Smrg	(*pI128->XaaInfoRec->SetupForScreenToScreenCopy)(
25350806d53Smrg		pScrn, xdir, ydir, GXcopy, ~0, color);
25450806d53Smrg	(*pI128->XaaInfoRec->SubsequentScreenToScreenCopy)(
25550806d53Smrg		pScrn, srcx, srcy, dstx, dsty, w, h);
25650806d53Smrg	SET_SYNC_FLAG(pI128->XaaInfoRec);
25750806d53Smrg    }
25850806d53Smrg}
25950806d53Smrg#endif
260a73423d7Smrg#endif
26150806d53Smrgstatic Bool
26250806d53SmrgI128_OpenFramebuffer(
26350806d53Smrg   ScrnInfoPtr pScrn,
26450806d53Smrg   char **name,
26550806d53Smrg   unsigned char **mem,
26650806d53Smrg   int *size,
26750806d53Smrg   int *offset,
26850806d53Smrg   int *flags
26950806d53Smrg){
27050806d53Smrg    I128Ptr pI128 = I128PTR(pScrn);
2717965d9acSmrg    unsigned long FbAddress = PCI_REGION_BASE(pI128->PciInfo, 0, REGION_MEM) & 0xFFC00000;
27250806d53Smrg
27350806d53Smrg    *name = NULL; 		/* no special device */
27450806d53Smrg    *mem = (unsigned char*)FbAddress;
27550806d53Smrg    *size = pI128->MemorySize*1024;
27650806d53Smrg    *offset = 0;
27750806d53Smrg    *flags = DGA_NEED_ROOT;
27850806d53Smrg
27950806d53Smrg    return TRUE;
28050806d53Smrg}
281