glint_dga.c revision c35d236e
1c35d236eSmrg/*
2c35d236eSmrg * Copyright 2000-2001 by Alan Hourihane, Sychdyn, North Wales, UK.
3c35d236eSmrg *
4c35d236eSmrg * Permission to use, copy, modify, distribute, and sell this software and its
5c35d236eSmrg * documentation for any purpose is hereby granted without fee, provided that
6c35d236eSmrg * the above copyright notice appear in all copies and that both that
7c35d236eSmrg * copyright notice and this permission notice appear in supporting
8c35d236eSmrg * documentation, and that the name of Alan Hourihane not be used in
9c35d236eSmrg * advertising or publicity pertaining to distribution of the software without
10c35d236eSmrg * specific, written prior permission.  Alan Hourihane makes no representations
11c35d236eSmrg * about the suitability of this software for any purpose.  It is provided
12c35d236eSmrg * "as is" without express or implied warranty.
13c35d236eSmrg *
14c35d236eSmrg * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15c35d236eSmrg * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16c35d236eSmrg * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17c35d236eSmrg * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18c35d236eSmrg * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19c35d236eSmrg * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
20c35d236eSmrg * PERFORMANCE OF THIS SOFTWARE.
21c35d236eSmrg *
22c35d236eSmrg * Authors:  Alan Hourihane, <alanh@fairlite.demon.co.uk>
23c35d236eSmrg */
24c35d236eSmrg/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/glint/glint_dga.c,v 1.3 2001/04/10 20:33:30 dawes Exp $ */
25c35d236eSmrg
26c35d236eSmrg#ifdef HAVE_CONFIG_H
27c35d236eSmrg#include "config.h"
28c35d236eSmrg#endif
29c35d236eSmrg
30c35d236eSmrg#include "xf86.h"
31c35d236eSmrg#include "xf86_OSproc.h"
32c35d236eSmrg#include "xf86Pci.h"
33c35d236eSmrg#include "xf86PciInfo.h"
34c35d236eSmrg#include "xaa.h"
35c35d236eSmrg#include "xaalocal.h"
36c35d236eSmrg#include "glint.h"
37c35d236eSmrg#include "glint_regs.h"
38c35d236eSmrg#include "dgaproc.h"
39c35d236eSmrg
40c35d236eSmrgstatic Bool GLINT_OpenFramebuffer(ScrnInfoPtr, char **, unsigned char **,
41c35d236eSmrg					int *, int *, int *);
42c35d236eSmrgstatic Bool GLINT_SetMode(ScrnInfoPtr, DGAModePtr);
43c35d236eSmrgstatic void GLINT_Sync(ScrnInfoPtr);
44c35d236eSmrgstatic int  GLINT_GetViewport(ScrnInfoPtr);
45c35d236eSmrgstatic void GLINT_SetViewport(ScrnInfoPtr, int, int, int);
46c35d236eSmrgstatic void GLINT_FillRect(ScrnInfoPtr, int, int, int, int, unsigned long);
47c35d236eSmrgstatic void GLINT_BlitRect(ScrnInfoPtr, int, int, int, int, int, int);
48c35d236eSmrg
49c35d236eSmrgstatic
50c35d236eSmrgDGAFunctionRec GLINTDGAFuncs = {
51c35d236eSmrg   GLINT_OpenFramebuffer,
52c35d236eSmrg   NULL,
53c35d236eSmrg   GLINT_SetMode,
54c35d236eSmrg   GLINT_SetViewport,
55c35d236eSmrg   GLINT_GetViewport,
56c35d236eSmrg   GLINT_Sync,
57c35d236eSmrg   GLINT_FillRect,
58c35d236eSmrg   GLINT_BlitRect,
59c35d236eSmrg   NULL
60c35d236eSmrg};
61c35d236eSmrg
62c35d236eSmrgBool
63c35d236eSmrgGLINTDGAInit(ScreenPtr pScreen)
64c35d236eSmrg{
65c35d236eSmrg   ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
66c35d236eSmrg   GLINTPtr pGlint = GLINTPTR(pScrn);
67c35d236eSmrg   DGAModePtr modes = NULL, newmodes = NULL, currentMode;
68c35d236eSmrg   DisplayModePtr pMode, firstMode;
69c35d236eSmrg   int Bpp = pScrn->bitsPerPixel >> 3;
70c35d236eSmrg   int num = 0;
71c35d236eSmrg   Bool oneMore;
72c35d236eSmrg
73c35d236eSmrg   pMode = firstMode = pScrn->modes;
74c35d236eSmrg
75c35d236eSmrg   while(pMode) {
76c35d236eSmrg
77c35d236eSmrg	if(0 /*pScrn->displayWidth != pMode->HDisplay*/) {
78c35d236eSmrg	    newmodes = xrealloc(modes, (num + 2) * sizeof(DGAModeRec));
79c35d236eSmrg	    oneMore = TRUE;
80c35d236eSmrg	} else {
81c35d236eSmrg	    newmodes = xrealloc(modes, (num + 1) * sizeof(DGAModeRec));
82c35d236eSmrg	    oneMore = FALSE;
83c35d236eSmrg	}
84c35d236eSmrg
85c35d236eSmrg	if(!newmodes) {
86c35d236eSmrg	   xfree(modes);
87c35d236eSmrg	   return FALSE;
88c35d236eSmrg	}
89c35d236eSmrg	modes = newmodes;
90c35d236eSmrg
91c35d236eSmrgSECOND_PASS:
92c35d236eSmrg
93c35d236eSmrg	currentMode = modes + num;
94c35d236eSmrg	num++;
95c35d236eSmrg
96c35d236eSmrg	currentMode->mode = pMode;
97c35d236eSmrg	currentMode->flags = DGA_CONCURRENT_ACCESS | DGA_PIXMAP_AVAILABLE;
98c35d236eSmrg	if(!pGlint->NoAccel)
99c35d236eSmrg	   currentMode->flags |= DGA_FILL_RECT | DGA_BLIT_RECT;
100c35d236eSmrg	if(pMode->Flags & V_DBLSCAN)
101c35d236eSmrg	   currentMode->flags |= DGA_DOUBLESCAN;
102c35d236eSmrg	if(pMode->Flags & V_INTERLACE)
103c35d236eSmrg	   currentMode->flags |= DGA_INTERLACED;
104c35d236eSmrg	currentMode->byteOrder = pScrn->imageByteOrder;
105c35d236eSmrg	currentMode->depth = pScrn->depth;
106c35d236eSmrg	currentMode->bitsPerPixel = pScrn->bitsPerPixel;
107c35d236eSmrg	currentMode->red_mask = pScrn->mask.red;
108c35d236eSmrg	currentMode->green_mask = pScrn->mask.green;
109c35d236eSmrg	currentMode->blue_mask = pScrn->mask.blue;
110c35d236eSmrg	currentMode->visualClass = (Bpp == 1) ? PseudoColor : TrueColor;
111c35d236eSmrg	currentMode->viewportWidth = pMode->HDisplay;
112c35d236eSmrg	currentMode->viewportHeight = pMode->VDisplay;
113c35d236eSmrg	currentMode->xViewportStep = 1;
114c35d236eSmrg	currentMode->yViewportStep = 1;
115c35d236eSmrg	currentMode->viewportFlags = DGA_FLIP_RETRACE;
116c35d236eSmrg	currentMode->offset = 0;
117c35d236eSmrg	currentMode->address = pGlint->FbBase;
118c35d236eSmrg
119c35d236eSmrg	if(oneMore) { /* first one is narrow width */
120c35d236eSmrg	    currentMode->bytesPerScanline = ((pMode->HDisplay * Bpp) + 3) & ~3L;
121c35d236eSmrg	    currentMode->imageWidth = pMode->HDisplay;
122c35d236eSmrg	    currentMode->imageHeight =  pMode->VDisplay;
123c35d236eSmrg	    currentMode->pixmapWidth = currentMode->imageWidth;
124c35d236eSmrg	    currentMode->pixmapHeight = currentMode->imageHeight;
125c35d236eSmrg	    currentMode->maxViewportX = currentMode->imageWidth -
126c35d236eSmrg					currentMode->viewportWidth;
127c35d236eSmrg	    /* this might need to get clamped to some maximum */
128c35d236eSmrg	    currentMode->maxViewportY = currentMode->imageHeight -
129c35d236eSmrg					currentMode->viewportHeight;
130c35d236eSmrg	    oneMore = FALSE;
131c35d236eSmrg	    goto SECOND_PASS;
132c35d236eSmrg	} else {
133c35d236eSmrg	    currentMode->bytesPerScanline =
134c35d236eSmrg			((pScrn->displayWidth * Bpp) + 3) & ~3L;
135c35d236eSmrg	    currentMode->imageWidth = pScrn->displayWidth;
136c35d236eSmrg	    currentMode->imageHeight =  pMode->VDisplay;
137c35d236eSmrg	    currentMode->pixmapWidth = currentMode->imageWidth;
138c35d236eSmrg	    currentMode->pixmapHeight = currentMode->imageHeight;
139c35d236eSmrg	    currentMode->maxViewportX = currentMode->imageWidth -
140c35d236eSmrg					currentMode->viewportWidth;
141c35d236eSmrg	    /* this might need to get clamped to some maximum */
142c35d236eSmrg	    currentMode->maxViewportY = currentMode->imageHeight -
143c35d236eSmrg					currentMode->viewportHeight;
144c35d236eSmrg	}
145c35d236eSmrg
146c35d236eSmrg	pMode = pMode->next;
147c35d236eSmrg	if(pMode == firstMode)
148c35d236eSmrg	   break;
149c35d236eSmrg   }
150c35d236eSmrg
151c35d236eSmrg   pGlint->numDGAModes = num;
152c35d236eSmrg   pGlint->DGAModes = modes;
153c35d236eSmrg
154c35d236eSmrg   return DGAInit(pScreen, &GLINTDGAFuncs, modes, num);
155c35d236eSmrg}
156c35d236eSmrg
157c35d236eSmrg
158c35d236eSmrgstatic Bool
159c35d236eSmrgGLINT_SetMode(
160c35d236eSmrg   ScrnInfoPtr pScrn,
161c35d236eSmrg   DGAModePtr pMode
162c35d236eSmrg){
163c35d236eSmrg   static int OldDisplayWidth[MAXSCREENS];
164c35d236eSmrg   int index = pScrn->pScreen->myNum;
165c35d236eSmrg   GLINTPtr pGlint = GLINTPTR(pScrn);
166c35d236eSmrg
167c35d236eSmrg   if(!pMode) { /* restore the original mode */
168c35d236eSmrg	/* put the ScreenParameters back */
169c35d236eSmrg
170c35d236eSmrg	pScrn->displayWidth = OldDisplayWidth[index];
171c35d236eSmrg
172c35d236eSmrg        GLINTSwitchMode(index, pScrn->currentMode, 0);
173c35d236eSmrg	pGlint->DGAactive = FALSE;
174c35d236eSmrg   } else {
175c35d236eSmrg	if(!pGlint->DGAactive) {  /* save the old parameters */
176c35d236eSmrg	    OldDisplayWidth[index] = pScrn->displayWidth;
177c35d236eSmrg
178c35d236eSmrg	    pGlint->DGAactive = TRUE;
179c35d236eSmrg	}
180c35d236eSmrg
181c35d236eSmrg	pScrn->displayWidth = pMode->bytesPerScanline /
182c35d236eSmrg			      (pMode->bitsPerPixel >> 3);
183c35d236eSmrg
184c35d236eSmrg        GLINTSwitchMode(index, pMode->mode, 0);
185c35d236eSmrg   }
186c35d236eSmrg
187c35d236eSmrg   return TRUE;
188c35d236eSmrg}
189c35d236eSmrg
190c35d236eSmrgstatic int
191c35d236eSmrgGLINT_GetViewport(
192c35d236eSmrg  ScrnInfoPtr pScrn
193c35d236eSmrg){
194c35d236eSmrg    GLINTPtr pGlint = GLINTPTR(pScrn);
195c35d236eSmrg
196c35d236eSmrg    return pGlint->DGAViewportStatus;
197c35d236eSmrg}
198c35d236eSmrg
199c35d236eSmrgstatic void
200c35d236eSmrgGLINT_SetViewport(
201c35d236eSmrg   ScrnInfoPtr pScrn,
202c35d236eSmrg   int x, int y,
203c35d236eSmrg   int flags
204c35d236eSmrg){
205c35d236eSmrg   GLINTPtr pGlint = GLINTPTR(pScrn);
206c35d236eSmrg
207c35d236eSmrg   GLINTAdjustFrame(pScrn->pScreen->myNum, x, y, flags);
208c35d236eSmrg   pGlint->DGAViewportStatus = 0;  /* GLINTAdjustFrame loops until finished */
209c35d236eSmrg}
210c35d236eSmrg
211c35d236eSmrgstatic void
212c35d236eSmrgGLINT_FillRect (
213c35d236eSmrg   ScrnInfoPtr pScrn,
214c35d236eSmrg   int x, int y, int w, int h,
215c35d236eSmrg   unsigned long color
216c35d236eSmrg){
217c35d236eSmrg    GLINTPtr pGlint = GLINTPTR(pScrn);
218c35d236eSmrg
219c35d236eSmrg    if(pGlint->AccelInfoRec) {
220c35d236eSmrg	(*pGlint->AccelInfoRec->SetupForSolidFill)(pScrn, color, GXcopy, ~0);
221c35d236eSmrg	(*pGlint->AccelInfoRec->SubsequentSolidFillRect)(pScrn, x, y, w, h);
222c35d236eSmrg	SET_SYNC_FLAG(pGlint->AccelInfoRec);
223c35d236eSmrg    }
224c35d236eSmrg}
225c35d236eSmrg
226c35d236eSmrgstatic void
227c35d236eSmrgGLINT_Sync(
228c35d236eSmrg   ScrnInfoPtr pScrn
229c35d236eSmrg){
230c35d236eSmrg    GLINTPtr pGlint = GLINTPTR(pScrn);
231c35d236eSmrg
232c35d236eSmrg    if(pGlint->AccelInfoRec) {
233c35d236eSmrg	(*pGlint->AccelInfoRec->Sync)(pScrn);
234c35d236eSmrg    }
235c35d236eSmrg}
236c35d236eSmrg
237c35d236eSmrgstatic void
238c35d236eSmrgGLINT_BlitRect(
239c35d236eSmrg   ScrnInfoPtr pScrn,
240c35d236eSmrg   int srcx, int srcy,
241c35d236eSmrg   int w, int h,
242c35d236eSmrg   int dstx, int dsty
243c35d236eSmrg){
244c35d236eSmrg    GLINTPtr pGlint = GLINTPTR(pScrn);
245c35d236eSmrg
246c35d236eSmrg    if(pGlint->AccelInfoRec) {
247c35d236eSmrg	int xdir = ((srcx < dstx) && (srcy == dsty)) ? -1 : 1;
248c35d236eSmrg	int ydir = (srcy < dsty) ? -1 : 1;
249c35d236eSmrg
250c35d236eSmrg	(*pGlint->AccelInfoRec->SetupForScreenToScreenCopy)(
251c35d236eSmrg		pScrn, xdir, ydir, GXcopy, ~0, -1);
252c35d236eSmrg	(*pGlint->AccelInfoRec->SubsequentScreenToScreenCopy)(
253c35d236eSmrg		pScrn, srcx, srcy, dstx, dsty, w, h);
254c35d236eSmrg	SET_SYNC_FLAG(pGlint->AccelInfoRec);
255c35d236eSmrg    }
256c35d236eSmrg}
257c35d236eSmrg
258c35d236eSmrgstatic Bool
259c35d236eSmrgGLINT_OpenFramebuffer(
260c35d236eSmrg   ScrnInfoPtr pScrn,
261c35d236eSmrg   char **name,
262c35d236eSmrg   unsigned char **mem,
263c35d236eSmrg   int *size,
264c35d236eSmrg   int *offset,
265c35d236eSmrg   int *flags
266c35d236eSmrg){
267c35d236eSmrg    GLINTPtr pGlint = GLINTPTR(pScrn);
268c35d236eSmrg
269c35d236eSmrg    *name = NULL; 		/* no special device */
270c35d236eSmrg    *mem = (unsigned char*)pGlint->FbAddress;
271c35d236eSmrg    *size = pGlint->FbMapSize;
272c35d236eSmrg    *offset = 0;
273c35d236eSmrg    *flags = DGA_NEED_ROOT;
274c35d236eSmrg
275c35d236eSmrg    return TRUE;
276c35d236eSmrg}
277