ast_2dtool.c revision 15fb4814
1/*
2 * Copyright (c) 2005 ASPEED Technology Inc.
3 *
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 the authors not be used in
9 * advertising or publicity pertaining to distribution of the software without
10 * specific, written prior permission.  The authors makes no representations
11 * about the suitability of this software for any purpose.  It is provided
12 * "as is" without express or implied warranty.
13 *
14 * THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16 * EVENT SHALL THE AUTHORS 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.
21 */
22
23#ifdef HAVE_CONFIG_H
24#include <config.h>
25#endif
26#include "xf86.h"
27#include "xf86_OSproc.h"
28#include "xf86Resources.h"
29#include "xf86RAC.h"
30#include "xf86cmap.h"
31#include "compiler.h"
32#include "mibstore.h"
33#include "vgaHW.h"
34#include "mipointer.h"
35#include "micmap.h"
36
37#include "fb.h"
38#include "regionstr.h"
39#include "xf86xv.h"
40#include <X11/extensions/Xv.h>
41#include "vbe.h"
42
43#include "xf86PciInfo.h"
44#include "xf86Pci.h"
45
46/* framebuffer offscreen manager */
47#include "xf86fbman.h"
48
49/* include xaa includes */
50#include "xaa.h"
51#include "xaarop.h"
52
53/* H/W cursor support */
54#include "xf86Cursor.h"
55
56/* Driver specific headers */
57#include "ast.h"
58
59#ifdef	Accel_2D
60
61/* Prototype type declaration */
62Bool bInitCMDQInfo(ScrnInfoPtr pScrn, ASTRecPtr pAST);
63Bool bEnableCMDQ(ScrnInfoPtr pScrn, ASTRecPtr pAST);
64Bool bEnable2D(ScrnInfoPtr pScrn, ASTRecPtr pAST);
65void vDisable2D(ScrnInfoPtr pScrn, ASTRecPtr pAST);
66void vWaitEngIdle(ScrnInfoPtr pScrn, ASTRecPtr pAST);
67UCHAR *pjRequestCMDQ(ASTRecPtr pAST, ULONG   ulDataLen);
68Bool bGetLineTerm(_LINEInfo *LineInfo, LINEPARAM *dsLineParam);
69
70Bool
71bInitCMDQInfo(ScrnInfoPtr pScrn, ASTRecPtr pAST)
72{
73
74    ScreenPtr pScreen;
75
76    pAST->CMDQInfo.pjCmdQBasePort    = pAST->MMIOVirtualAddr+ 0x8044;
77    pAST->CMDQInfo.pjWritePort       = pAST->MMIOVirtualAddr+ 0x8048;
78    pAST->CMDQInfo.pjReadPort        = pAST->MMIOVirtualAddr+ 0x804C;
79    pAST->CMDQInfo.pjEngStatePort    = pAST->MMIOVirtualAddr+ 0x804C;
80
81    /* CMDQ mode Init */
82    if (!pAST->MMIO2D) {
83        pAST->CMDQInfo.ulCMDQType = VM_CMD_QUEUE;
84
85        pScreen = screenInfo.screens[pScrn->scrnIndex];
86
87        do {
88            pAST->pCMDQPtr = xf86AllocateOffscreenLinear (pScreen, pAST->CMDQInfo.ulCMDQSize, 8, NULL, NULL, NULL);
89
90            if (pAST->pCMDQPtr) break;
91
92            pAST->CMDQInfo.ulCMDQSize >>= 1;
93
94        } while (pAST->CMDQInfo.ulCMDQSize >= MIN_CMDQ_SIZE);
95
96        if (pAST->pCMDQPtr)
97        {
98           xf86DrvMsg(pScrn->scrnIndex, X_INFO,"Allocate CMDQ size is %ld kbyte \n", (unsigned long) (pAST->CMDQInfo.ulCMDQSize/1024));
99
100           pAST->CMDQInfo.ulCMDQOffsetAddr  = pAST->pCMDQPtr->offset*((pScrn->bitsPerPixel + 1) / 8);
101           pAST->CMDQInfo.pjCMDQVirtualAddr = pAST->FBVirtualAddr + pAST->CMDQInfo.ulCMDQOffsetAddr;
102
103           pAST->CMDQInfo.ulCurCMDQueueLen = pAST->CMDQInfo.ulCMDQSize - CMD_QUEUE_GUARD_BAND;
104           pAST->CMDQInfo.ulCMDQMask = pAST->CMDQInfo.ulCMDQSize - 1 ;
105
106        }
107        else
108        {
109           xf86DrvMsg(pScrn->scrnIndex, X_ERROR,"Allocate CMDQ failed \n");
110           pAST->MMIO2D = TRUE;		/* set to MMIO mode if CMDQ allocate failed */
111        }
112
113    }
114
115    /* MMIO mode init */
116    if (pAST->MMIO2D) {
117        pAST->CMDQInfo.ulCMDQType = VM_CMD_MMIO;
118    }
119
120    return (TRUE);
121}
122
123Bool
124bEnableCMDQ(ScrnInfoPtr pScrn, ASTRecPtr pAST)
125{
126    ULONG ulVMCmdQBasePort = 0;
127
128    vWaitEngIdle(pScrn, pAST);
129
130    /* set DBG Select Info */
131    if (pAST->DBGSelect)
132    {
133        *(ULONG *) (pAST->MMIOVirtualAddr + 0x804C) = (ULONG) (pAST->DBGSelect);
134    }
135
136    /* set CMDQ base */
137    switch (pAST->CMDQInfo.ulCMDQType)
138    {
139    case VM_CMD_QUEUE:
140        ulVMCmdQBasePort  = (pAST->CMDQInfo.ulCMDQOffsetAddr - 0) >> 3;
141
142        /* set CMDQ Threshold */
143        ulVMCmdQBasePort |= 0xF0000000;
144
145        /* set CMDQ Size */
146        switch (pAST->CMDQInfo.ulCMDQSize)
147        {
148        case CMD_QUEUE_SIZE_256K:
149            ulVMCmdQBasePort |= 0x00000000;
150            break;
151
152        case CMD_QUEUE_SIZE_512K:
153            ulVMCmdQBasePort |= 0x04000000;
154            break;
155
156        case CMD_QUEUE_SIZE_1M:
157            ulVMCmdQBasePort |= 0x08000000;
158            break;
159
160        case CMD_QUEUE_SIZE_2M:
161            ulVMCmdQBasePort |= 0x0C000000;
162            break;
163
164        default:
165            return(FALSE);
166            break;
167        }
168
169        *(ULONG *) (pAST->CMDQInfo.pjCmdQBasePort) = ulVMCmdQBasePort;
170        pAST->CMDQInfo.ulWritePointer = *(ULONG *) (pAST->CMDQInfo.pjWritePort);
171        break;
172
173    case VM_CMD_MMIO:
174        /* set CMDQ Threshold */
175        ulVMCmdQBasePort |= 0xF0000000;
176
177        ulVMCmdQBasePort |= 0x02000000;			/* MMIO mode */
178        *(ULONG *) (pAST->CMDQInfo.pjCmdQBasePort) = ulVMCmdQBasePort;
179        break;
180
181    default:
182        return (FALSE);
183        break;
184    }
185
186    return (TRUE);
187}
188
189Bool
190bEnable2D(ScrnInfoPtr pScrn, ASTRecPtr pAST)
191{
192    SetIndexRegMask(CRTC_PORT, 0xA4, 0xFE, 0x01);		/* enable 2D */
193
194    if (!bInitCMDQInfo(pScrn, pAST))
195    {
196        vDisable2D(pScrn, pAST);
197    	return (FALSE);
198    }
199
200    if (!bEnableCMDQ(pScrn, pAST))
201    {
202        vDisable2D(pScrn, pAST);
203    	return (FALSE);
204    }
205
206    return (TRUE);
207}
208
209void
210vDisable2D(ScrnInfoPtr pScrn, ASTRecPtr pAST)
211{
212
213    vWaitEngIdle(pScrn, pAST);
214    vWaitEngIdle(pScrn, pAST);
215
216    SetIndexRegMask(CRTC_PORT, 0xA4, 0xFE, 0x00);
217
218}
219
220
221void
222vWaitEngIdle(ScrnInfoPtr pScrn, ASTRecPtr pAST)
223{
224    ULONG ulEngState, ulEngState2;
225    UCHAR jReg;
226    ULONG ulEngCheckSetting;
227
228    if (pAST->MMIO2D)
229        ulEngCheckSetting = 0x10000000;
230    else
231        ulEngCheckSetting = 0x80000000;
232
233    /* 2D disable if 0xA4 D[0] = 1 */
234    GetIndexRegMask(CRTC_PORT, 0xA4, 0x01, jReg);
235    if (!jReg) goto Exit_vWaitEngIdle;
236
237    /* 2D not work if in std. mode */
238    GetIndexRegMask(CRTC_PORT, 0xA3, 0x0F, jReg);
239    if (!jReg) goto Exit_vWaitEngIdle;
240
241    do
242    {
243        ulEngState = (*(volatile ULONG *)(pAST->CMDQInfo.pjEngStatePort)) & 0xFFFC0000;
244        ulEngState2 = (*(volatile ULONG *)(pAST->CMDQInfo.pjEngStatePort)) & 0xFFFC0000;
245        ulEngState2 = (*(volatile ULONG *)(pAST->CMDQInfo.pjEngStatePort)) & 0xFFFC0000;
246        ulEngState2 = (*(volatile ULONG *)(pAST->CMDQInfo.pjEngStatePort)) & 0xFFFC0000;
247        ulEngState2 = (*(volatile ULONG *)(pAST->CMDQInfo.pjEngStatePort)) & 0xFFFC0000;
248        ulEngState2 = (*(volatile ULONG *)(pAST->CMDQInfo.pjEngStatePort)) & 0xFFFC0000;
249
250    } while ((ulEngState & ulEngCheckSetting) || (ulEngState != ulEngState2));
251
252Exit_vWaitEngIdle:
253    ;
254}
255
256/* ULONG ulGetCMDQLength() */
257__inline ULONG ulGetCMDQLength(ASTRecPtr pAST, ULONG ulWritePointer, ULONG ulCMDQMask)
258{
259    ULONG ulReadPointer, ulReadPointer2;
260
261    do {
262        ulReadPointer  = *((volatile ULONG *)(pAST->CMDQInfo.pjReadPort)) & 0x0003FFFF;
263        ulReadPointer2 = *((volatile ULONG *)(pAST->CMDQInfo.pjReadPort)) & 0x0003FFFF;
264        ulReadPointer2 = *((volatile ULONG *)(pAST->CMDQInfo.pjReadPort)) & 0x0003FFFF;
265        ulReadPointer2 = *((volatile ULONG *)(pAST->CMDQInfo.pjReadPort)) & 0x0003FFFF;
266        ulReadPointer2 = *((volatile ULONG *)(pAST->CMDQInfo.pjReadPort)) & 0x0003FFFF;
267        ulReadPointer2 = *((volatile ULONG *)(pAST->CMDQInfo.pjReadPort)) & 0x0003FFFF;
268     } while (ulReadPointer != ulReadPointer2);
269
270    return ((ulReadPointer << 3) - ulWritePointer - CMD_QUEUE_GUARD_BAND) & ulCMDQMask;
271}
272
273UCHAR *pjRequestCMDQ(
274ASTRecPtr pAST, ULONG   ulDataLen)
275{
276    UCHAR   *pjBuffer;
277    ULONG   i, ulWritePointer, ulCMDQMask, ulCurCMDQLen, ulContinueCMDQLen;
278
279    ulWritePointer = pAST->CMDQInfo.ulWritePointer;
280    ulContinueCMDQLen = pAST->CMDQInfo.ulCMDQSize - ulWritePointer;
281    ulCMDQMask = pAST->CMDQInfo.ulCMDQMask;
282
283    if (ulContinueCMDQLen >= ulDataLen)
284    {
285        /* Get CMDQ Buffer */
286        if (pAST->CMDQInfo.ulCurCMDQueueLen >= ulDataLen)
287        {
288        	;
289        }
290        else
291        {
292
293            do
294            {
295                ulCurCMDQLen = ulGetCMDQLength(pAST, ulWritePointer, ulCMDQMask);
296            } while (ulCurCMDQLen < ulDataLen);
297
298            pAST->CMDQInfo.ulCurCMDQueueLen = ulCurCMDQLen;
299
300        }
301
302        pjBuffer = pAST->CMDQInfo.pjCMDQVirtualAddr + ulWritePointer;
303        pAST->CMDQInfo.ulCurCMDQueueLen -= ulDataLen;
304        pAST->CMDQInfo.ulWritePointer = (ulWritePointer + ulDataLen) & ulCMDQMask;
305        return pjBuffer;
306    }
307    else
308    {
309
310        /* Fill NULL CMD to the last of the CMDQ */
311        if (pAST->CMDQInfo.ulCurCMDQueueLen >= ulContinueCMDQLen)
312        {
313        	;
314        }
315        else
316        {
317
318            do
319            {
320                ulCurCMDQLen = ulGetCMDQLength(pAST, ulWritePointer, ulCMDQMask);
321            } while (ulCurCMDQLen < ulContinueCMDQLen);
322
323            pAST->CMDQInfo.ulCurCMDQueueLen = ulCurCMDQLen;
324
325        }
326
327        pjBuffer = pAST->CMDQInfo.pjCMDQVirtualAddr + ulWritePointer;
328        for (i = 0; i<ulContinueCMDQLen/8; i++, pjBuffer+=8)
329        {
330            *(ULONG *)pjBuffer = (ULONG) PKT_NULL_CMD;
331            *(ULONG *) (pjBuffer+4) = 0;
332
333        }
334        pAST->CMDQInfo.ulCurCMDQueueLen -= ulContinueCMDQLen;
335        pAST->CMDQInfo.ulWritePointer = ulWritePointer = 0;
336
337        /* Get CMDQ Buffer */
338        if (pAST->CMDQInfo.ulCurCMDQueueLen >= ulDataLen)
339        {
340	        ;
341        }
342        else
343        {
344
345            do
346            {
347                ulCurCMDQLen = ulGetCMDQLength(pAST, ulWritePointer, ulCMDQMask);
348            } while (ulCurCMDQLen < ulDataLen);
349
350            pAST->CMDQInfo.ulCurCMDQueueLen = ulCurCMDQLen;
351
352        }
353
354        pAST->CMDQInfo.ulCurCMDQueueLen -= ulDataLen;
355        pjBuffer = pAST->CMDQInfo.pjCMDQVirtualAddr + ulWritePointer;
356        pAST->CMDQInfo.ulWritePointer = (ulWritePointer + ulDataLen) & ulCMDQMask;
357        return pjBuffer;
358
359    }
360
361} /* end of pjRequestCmdQ() */
362
363Bool bGetLineTerm(_LINEInfo *LineInfo, LINEPARAM *dsLineParam)
364{
365    LONG GAbsX, GAbsY, GXInc, GYInc, GXMajor;
366    LONG MM, mm, Error0, K1, K2;
367
368    /* Init */
369#ifdef LONG64
370    GAbsX = abs (LineInfo->X1 - LineInfo->X2);
371    GAbsY = abs (LineInfo->Y1 - LineInfo->Y2);
372#else
373    GAbsX = labs (LineInfo->X1 - LineInfo->X2);
374    GAbsY = labs (LineInfo->Y1 - LineInfo->Y2);
375#endif
376
377    GXInc = (LineInfo->X1 < LineInfo->X2) ? 1:0;
378    GYInc = (LineInfo->Y1 < LineInfo->Y2) ? 1:0;
379    GXMajor = (GAbsX >= GAbsY) ? 1:0;
380
381    /* Calculate */
382    if (GXMajor)
383    {
384        MM = GAbsX;
385        mm = GAbsY;
386    }
387    else
388    {
389        MM = GAbsY;
390        mm = GAbsX;
391    }
392
393    Error0 = (signed) (2*mm - MM);
394
395    K1 = 2* mm;
396    K2 = (signed) (2*mm - 2*MM);
397
398    /*save the Param to dsLineParam */
399    dsLineParam->dsLineX = (USHORT) LineInfo->X1;
400    dsLineParam->dsLineY = (USHORT) LineInfo->Y1;
401    dsLineParam->dsLineWidth = (USHORT) MM;
402    dsLineParam->dwErrorTerm = (ULONG) Error0;
403    dsLineParam->dwK1Term = K1;
404    dsLineParam->dwK2Term = K2;
405
406    dsLineParam->dwLineAttributes = 0;
407    if (GXMajor) dsLineParam->dwLineAttributes |= LINEPARAM_XM;
408    if (!GXInc) dsLineParam->dwLineAttributes |= LINEPARAM_X_DEC;
409    if (!GYInc) dsLineParam->dwLineAttributes |= LINEPARAM_Y_DEC;
410
411    return(TRUE);
412
413}
414#endif	/* end of Accel_2D */
415
416
417