ast_2dtool.c revision de78e416
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) << 3;
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    ULONG ulData;
193
194    switch (pAST->jChipType)
195    {
196    case AST2100:
197    case AST1100:
198    case AST2200:
199    case AST2150:
200       *(ULONG *) (pAST->MMIOVirtualAddr + 0xF004) = 0x1e6e0000;
201       *(ULONG *) (pAST->MMIOVirtualAddr + 0xF000) = 0x1;
202
203       ulData = *(ULONG *) (pAST->MMIOVirtualAddr + 0x1200c);
204       *(ULONG *) (pAST->MMIOVirtualAddr + 0x1200c) = (ulData & 0xFFFFFFFD);
205       break;
206    }
207
208    SetIndexRegMask(CRTC_PORT, 0xA4, 0xFE, 0x01);		/* enable 2D */
209
210    if (!bInitCMDQInfo(pScrn, pAST))
211    {
212        vDisable2D(pScrn, pAST);
213    	return (FALSE);
214    }
215
216    if (!bEnableCMDQ(pScrn, pAST))
217    {
218        vDisable2D(pScrn, pAST);
219    	return (FALSE);
220    }
221
222    return (TRUE);
223}
224
225void
226vDisable2D(ScrnInfoPtr pScrn, ASTRecPtr pAST)
227{
228
229    vWaitEngIdle(pScrn, pAST);
230    vWaitEngIdle(pScrn, pAST);
231
232    SetIndexRegMask(CRTC_PORT, 0xA4, 0xFE, 0x00);
233
234}
235
236
237void
238vWaitEngIdle(ScrnInfoPtr pScrn, ASTRecPtr pAST)
239{
240    ULONG ulEngState, ulEngState2;
241    UCHAR jReg;
242    ULONG ulEngCheckSetting;
243
244    if (pAST->MMIO2D)
245        ulEngCheckSetting = 0x10000000;
246    else
247        ulEngCheckSetting = 0x80000000;
248
249    /* 2D disable if 0xA4 D[0] = 1 */
250    GetIndexRegMask(CRTC_PORT, 0xA4, 0x01, jReg);
251    if (!jReg) goto Exit_vWaitEngIdle;
252
253    /* 2D not work if in std. mode */
254    GetIndexRegMask(CRTC_PORT, 0xA3, 0x0F, jReg);
255    if (!jReg) goto Exit_vWaitEngIdle;
256
257    do
258    {
259        ulEngState = (*(volatile ULONG *)(pAST->CMDQInfo.pjEngStatePort)) & 0xFFFC0000;
260        ulEngState2 = (*(volatile ULONG *)(pAST->CMDQInfo.pjEngStatePort)) & 0xFFFC0000;
261        ulEngState2 = (*(volatile ULONG *)(pAST->CMDQInfo.pjEngStatePort)) & 0xFFFC0000;
262        ulEngState2 = (*(volatile ULONG *)(pAST->CMDQInfo.pjEngStatePort)) & 0xFFFC0000;
263        ulEngState2 = (*(volatile ULONG *)(pAST->CMDQInfo.pjEngStatePort)) & 0xFFFC0000;
264        ulEngState2 = (*(volatile ULONG *)(pAST->CMDQInfo.pjEngStatePort)) & 0xFFFC0000;
265
266    } while ((ulEngState & ulEngCheckSetting) || (ulEngState != ulEngState2));
267
268Exit_vWaitEngIdle:
269    ;
270}
271
272/* ULONG ulGetCMDQLength() */
273static __inline ULONG ulGetCMDQLength(ASTRecPtr pAST, ULONG ulWritePointer, ULONG ulCMDQMask)
274{
275    ULONG ulReadPointer, ulReadPointer2;
276
277    do {
278        ulReadPointer  = *((volatile ULONG *)(pAST->CMDQInfo.pjReadPort)) & 0x0003FFFF;
279        ulReadPointer2 = *((volatile ULONG *)(pAST->CMDQInfo.pjReadPort)) & 0x0003FFFF;
280        ulReadPointer2 = *((volatile ULONG *)(pAST->CMDQInfo.pjReadPort)) & 0x0003FFFF;
281        ulReadPointer2 = *((volatile ULONG *)(pAST->CMDQInfo.pjReadPort)) & 0x0003FFFF;
282        ulReadPointer2 = *((volatile ULONG *)(pAST->CMDQInfo.pjReadPort)) & 0x0003FFFF;
283        ulReadPointer2 = *((volatile ULONG *)(pAST->CMDQInfo.pjReadPort)) & 0x0003FFFF;
284     } while (ulReadPointer != ulReadPointer2);
285
286    return ((ulReadPointer << 3) - ulWritePointer - CMD_QUEUE_GUARD_BAND) & ulCMDQMask;
287}
288
289UCHAR *pjRequestCMDQ(
290ASTRecPtr pAST, ULONG   ulDataLen)
291{
292    UCHAR   *pjBuffer;
293    ULONG   i, ulWritePointer, ulCMDQMask, ulCurCMDQLen, ulContinueCMDQLen;
294
295    ulWritePointer = pAST->CMDQInfo.ulWritePointer;
296    ulContinueCMDQLen = pAST->CMDQInfo.ulCMDQSize - ulWritePointer;
297    ulCMDQMask = pAST->CMDQInfo.ulCMDQMask;
298
299    if (ulContinueCMDQLen >= ulDataLen)
300    {
301        /* Get CMDQ Buffer */
302        if (pAST->CMDQInfo.ulCurCMDQueueLen >= ulDataLen)
303        {
304        	;
305        }
306        else
307        {
308
309            do
310            {
311                ulCurCMDQLen = ulGetCMDQLength(pAST, ulWritePointer, ulCMDQMask);
312            } while (ulCurCMDQLen < ulDataLen);
313
314            pAST->CMDQInfo.ulCurCMDQueueLen = ulCurCMDQLen;
315
316        }
317
318        pjBuffer = pAST->CMDQInfo.pjCMDQVirtualAddr + ulWritePointer;
319        pAST->CMDQInfo.ulCurCMDQueueLen -= ulDataLen;
320        pAST->CMDQInfo.ulWritePointer = (ulWritePointer + ulDataLen) & ulCMDQMask;
321        return pjBuffer;
322    }
323    else
324    {
325
326        /* Fill NULL CMD to the last of the CMDQ */
327        if (pAST->CMDQInfo.ulCurCMDQueueLen >= ulContinueCMDQLen)
328        {
329        	;
330        }
331        else
332        {
333
334            do
335            {
336                ulCurCMDQLen = ulGetCMDQLength(pAST, ulWritePointer, ulCMDQMask);
337            } while (ulCurCMDQLen < ulContinueCMDQLen);
338
339            pAST->CMDQInfo.ulCurCMDQueueLen = ulCurCMDQLen;
340
341        }
342
343        pjBuffer = pAST->CMDQInfo.pjCMDQVirtualAddr + ulWritePointer;
344        for (i = 0; i<ulContinueCMDQLen/8; i++, pjBuffer+=8)
345        {
346            *(ULONG *)pjBuffer = (ULONG) PKT_NULL_CMD;
347            *(ULONG *) (pjBuffer+4) = 0;
348
349        }
350        pAST->CMDQInfo.ulCurCMDQueueLen -= ulContinueCMDQLen;
351        pAST->CMDQInfo.ulWritePointer = ulWritePointer = 0;
352
353        /* Get CMDQ Buffer */
354        if (pAST->CMDQInfo.ulCurCMDQueueLen >= ulDataLen)
355        {
356	        ;
357        }
358        else
359        {
360
361            do
362            {
363                ulCurCMDQLen = ulGetCMDQLength(pAST, ulWritePointer, ulCMDQMask);
364            } while (ulCurCMDQLen < ulDataLen);
365
366            pAST->CMDQInfo.ulCurCMDQueueLen = ulCurCMDQLen;
367
368        }
369
370        pAST->CMDQInfo.ulCurCMDQueueLen -= ulDataLen;
371        pjBuffer = pAST->CMDQInfo.pjCMDQVirtualAddr + ulWritePointer;
372        pAST->CMDQInfo.ulWritePointer = (ulWritePointer + ulDataLen) & ulCMDQMask;
373        return pjBuffer;
374
375    }
376
377} /* end of pjRequestCmdQ() */
378
379Bool bGetLineTerm(_LINEInfo *LineInfo, LINEPARAM *dsLineParam)
380{
381    LONG GAbsX, GAbsY, GXInc, GYInc, GXMajor;
382    LONG MM, mm, Error0, K1, K2;
383
384    /* Init */
385#ifdef LONG64
386    GAbsX = abs (LineInfo->X1 - LineInfo->X2);
387    GAbsY = abs (LineInfo->Y1 - LineInfo->Y2);
388#else
389    GAbsX = labs (LineInfo->X1 - LineInfo->X2);
390    GAbsY = labs (LineInfo->Y1 - LineInfo->Y2);
391#endif
392
393    GXInc = (LineInfo->X1 < LineInfo->X2) ? 1:0;
394    GYInc = (LineInfo->Y1 < LineInfo->Y2) ? 1:0;
395    GXMajor = (GAbsX >= GAbsY) ? 1:0;
396
397    /* Calculate */
398    if (GXMajor)
399    {
400        MM = GAbsX;
401        mm = GAbsY;
402    }
403    else
404    {
405        MM = GAbsY;
406        mm = GAbsX;
407    }
408
409    Error0 = (signed) (2*mm - MM);
410
411    K1 = 2* mm;
412    K2 = (signed) (2*mm - 2*MM);
413
414    /*save the Param to dsLineParam */
415    dsLineParam->dsLineX = (USHORT) LineInfo->X1;
416    dsLineParam->dsLineY = (USHORT) LineInfo->Y1;
417    dsLineParam->dsLineWidth = (USHORT) MM;
418    dsLineParam->dwErrorTerm = (ULONG) Error0;
419    dsLineParam->dwK1Term = K1;
420    dsLineParam->dwK2Term = K2;
421
422    dsLineParam->dwLineAttributes = 0;
423    if (GXMajor) dsLineParam->dwLineAttributes |= LINEPARAM_XM;
424    if (!GXInc) dsLineParam->dwLineAttributes |= LINEPARAM_X_DEC;
425    if (!GYInc) dsLineParam->dwLineAttributes |= LINEPARAM_Y_DEC;
426
427    return(TRUE);
428
429}
430#endif	/* end of Accel_2D */
431
432
433