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