2
* Copyright 2000 by Alan Hourihane, Sychdyn, North Wales, UK.
4
* Permission to use, copy, modify, distribute, and sell this software and its
5
* documentation for any purpose is hereby granted without fee, provided that
6
* the above copyright notice appear in all copies and that both that
7
* copyright notice and this permission notice appear in supporting
8
* documentation, and that the name of Alan Hourihane not be used in
9
* advertising or publicity pertaining to distribution of the software without
10
* specific, written prior permission. Alan Hourihane makes no representations
11
* about the suitability of this software for any purpose. It is provided
12
* "as is" without express or implied warranty.
14
* ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16
* EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
20
* PERFORMANCE OF THIS SOFTWARE.
22
* Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk>
25
* Reformatted with GNU indent (2.2.8), using the following options:
27
* -bad -bap -c41 -cd0 -ncdb -ci6 -cli0 -cp0 -ncs -d0 -di3 -i3 -ip3 -l78
28
* -lp -npcs -psl -sob -ss -br -ce -sc -hnl
30
* This provides a good match with the original i810 code and preferred
31
* XFree86 formatting conventions.
33
* When editing this driver, please follow the existing formatting, and edit
34
* with <TAB> characters expanded at 8-column intervals.
37
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i810/i810_dga.c,v 1.6 2003/02/26 04:19:36 dawes Exp $ */
40
#include "xf86_OSproc.h"
41
#include "xf86_ansic.h"
43
#include "xf86PciInfo.h"
51
static Bool I810_OpenFramebuffer(ScrnInfoPtr, char **, unsigned char **,
53
static Bool I810_SetMode(ScrnInfoPtr, DGAModePtr);
54
static void I810_Sync(ScrnInfoPtr);
55
static int I810_GetViewport(ScrnInfoPtr);
56
static void I810_SetViewport(ScrnInfoPtr, int, int, int);
57
static void I810_FillRect(ScrnInfoPtr, int, int, int, int, unsigned long);
58
static void I810_BlitRect(ScrnInfoPtr, int, int, int, int, int, int);
61
static void I810_BlitTransRect(ScrnInfoPtr, int, int, int, int, int, int,
66
DGAFunctionRec I810DGAFuncs = {
83
I810DGAInit(ScreenPtr pScreen)
85
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
86
I810Ptr pI810 = I810PTR(pScrn);
87
DGAModePtr modes = NULL, newmodes = NULL, currentMode;
88
DisplayModePtr pMode, firstMode;
89
int Bpp = pScrn->bitsPerPixel >> 3;
94
pMode = firstMode = pScrn->modes;
98
newmodes = xrealloc(modes, (num + 1) * sizeof(DGAModeRec));
106
currentMode = modes + num;
109
currentMode->mode = pMode;
110
currentMode->flags = DGA_CONCURRENT_ACCESS | DGA_PIXMAP_AVAILABLE;
112
currentMode->flags |= DGA_FILL_RECT | DGA_BLIT_RECT;
113
if (pMode->Flags & V_DBLSCAN)
114
currentMode->flags |= DGA_DOUBLESCAN;
115
if (pMode->Flags & V_INTERLACE)
116
currentMode->flags |= DGA_INTERLACED;
117
currentMode->byteOrder = pScrn->imageByteOrder;
118
currentMode->depth = pScrn->depth;
119
currentMode->bitsPerPixel = pScrn->bitsPerPixel;
120
currentMode->red_mask = pScrn->mask.red;
121
currentMode->green_mask = pScrn->mask.green;
122
currentMode->blue_mask = pScrn->mask.blue;
123
currentMode->visualClass = (Bpp == 1) ? PseudoColor : TrueColor;
124
currentMode->viewportWidth = pMode->HDisplay;
125
currentMode->viewportHeight = pMode->VDisplay;
126
currentMode->xViewportStep = (Bpp == 3) ? 2 : 1;
127
currentMode->yViewportStep = 1;
128
currentMode->viewportFlags = DGA_FLIP_RETRACE;
129
currentMode->offset = 0;
130
currentMode->address = pI810->FbBase;
132
currentMode->bytesPerScanline = ((pScrn->displayWidth * Bpp) + 3) & ~3L;
133
currentMode->imageWidth = pI810->FbMemBox.x2;
134
currentMode->imageHeight = pI810->FbMemBox.y2;
135
currentMode->pixmapWidth = currentMode->imageWidth;
136
currentMode->pixmapHeight = currentMode->imageHeight;
137
currentMode->maxViewportX = currentMode->imageWidth -
138
currentMode->viewportWidth;
139
/* this might need to get clamped to some maximum */
140
currentMode->maxViewportY = currentMode->imageHeight -
141
currentMode->viewportHeight;
144
if (pMode == firstMode)
148
pI810->numDGAModes = num;
149
pI810->DGAModes = modes;
151
return DGAInit(pScreen, &I810DGAFuncs, modes, num);
154
static DisplayModePtr I810SavedDGAModes[MAXSCREENS];
157
I810_SetMode(ScrnInfoPtr pScrn, DGAModePtr pMode)
159
int index = pScrn->pScreen->myNum;
160
I810Ptr pI810 = I810PTR(pScrn);
164
if (!pMode) { /* restore the original mode */
165
DPRINTF(PFX, "Restoring original mode (from DGA mode)\n");
166
if (pI810->DGAactive) {
167
pScrn->currentMode = I810SavedDGAModes[index];
168
pScrn->SwitchMode(index, pScrn->currentMode, 0);
169
pScrn->AdjustFrame(index, 0, 0, 0);
170
pI810->DGAactive = FALSE;
173
if (!pI810->DGAactive) {
174
DPRINTF(PFX, "Setting DGA mode\n");
175
I810SavedDGAModes[index] = pScrn->currentMode;
176
pI810->DGAactive = TRUE;
179
pScrn->SwitchMode(index, pMode->mode, 0);
186
I810_GetViewport(ScrnInfoPtr pScrn)
188
I810Ptr pI810 = I810PTR(pScrn);
192
return pI810->DGAViewportStatus;
196
I810_SetViewport(ScrnInfoPtr pScrn, int x, int y, int flags)
198
I810Ptr pI810 = I810PTR(pScrn);
199
vgaHWPtr hwp = VGAHWPTR(pScrn);
203
pScrn->AdjustFrame(pScrn->pScreen->myNum, x, y, flags);
205
/* wait for retrace */
206
while ((hwp->readST01(hwp) & 0x08)) ;
207
while (!(hwp->readST01(hwp) & 0x08)) ;
209
pI810->DGAViewportStatus = 0;
213
I810_FillRect(ScrnInfoPtr pScrn,
214
int x, int y, int w, int h, unsigned long color)
216
I810Ptr pI810 = I810PTR(pScrn);
220
if (pI810->AccelInfoRec) {
221
(*pI810->AccelInfoRec->SetupForSolidFill) (pScrn, color, GXcopy, ~0);
222
(*pI810->AccelInfoRec->SubsequentSolidFillRect) (pScrn, x, y, w, h);
223
SET_SYNC_FLAG(pI810->AccelInfoRec);
228
I810_Sync(ScrnInfoPtr pScrn)
230
I810Ptr pI810 = I810PTR(pScrn);
234
if (pI810->AccelInfoRec) {
235
(*pI810->AccelInfoRec->Sync) (pScrn);
240
I810_BlitRect(ScrnInfoPtr pScrn,
241
int srcx, int srcy, int w, int h, int dstx, int dsty)
243
I810Ptr pI810 = I810PTR(pScrn);
247
if (pI810->AccelInfoRec) {
248
int xdir = ((srcx < dstx) && (srcy == dsty)) ? -1 : 1;
249
int ydir = (srcy < dsty) ? -1 : 1;
251
(*pI810->AccelInfoRec->SetupForScreenToScreenCopy) (pScrn, xdir, ydir,
253
(*pI810->AccelInfoRec->SubsequentScreenToScreenCopy) (pScrn, srcx, srcy,
255
SET_SYNC_FLAG(pI810->AccelInfoRec);
261
I810_BlitTransRect(ScrnInfoPtr pScrn,
263
int w, int h, int dstx, int dsty, unsigned long color)
268
/* this one should be separate since the XAA function would
269
* prohibit usage of ~0 as the key */
274
I810_OpenFramebuffer(ScrnInfoPtr pScrn,
276
unsigned char **mem, int *size, int *offset, int *flags)
278
I810Ptr pI810 = I810PTR(pScrn);
282
*name = NULL; /* no special device */
283
*mem = (unsigned char *)pI810->LinearAddr;
284
*size = pI810->FbMapSize;
286
*flags = DGA_NEED_ROOT;
289
" mem == 0x%.8x (pI810->LinearAddr)\n"
290
"size == %lu (pI810->FbMapSize)\n", *mem, *size);