ast_2dtool.c revision b534f209
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
58typedef Bool (*PFN_bENABLE_CMDQ)(ScrnInfoPtr , ASTRecPtr);
59
60/* Prototype type declaration */
61Bool bInitCMDQInfo(ScrnInfoPtr pScrn, ASTRecPtr pAST);
62Bool bEnableCMDQ(ScrnInfoPtr pScrn, ASTRecPtr pAST);
63Bool bEnableCMDQ2300(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
190bEnableCMDQ2300(ScrnInfoPtr pScrn, ASTRecPtr pAST)
191{
192    ULONG ulVMCmdQBasePort = 0, ulNewModeData;
193
194    vWaitEngIdle(pScrn, pAST);
195
196    /* set DBG Select Info */
197    if (pAST->DBGSelect)
198    {
199        *(ULONG *) (pAST->MMIOVirtualAddr + 0x804C) = (ULONG) (pAST->DBGSelect);
200    }
201
202    /* set CMDQ base */
203    switch (pAST->CMDQInfo.ulCMDQType)
204    {
205    case VM_CMD_QUEUE:
206        /* enable new CMDQ mode */
207        ulNewModeData = 0xc00000f0;
208        /* set CMDQ Size */
209        switch (pAST->CMDQInfo.ulCMDQSize)
210        {
211        case CMD_QUEUE_SIZE_256K:
212            ulNewModeData |= 0x00000000;
213            break;
214
215        case CMD_QUEUE_SIZE_512K:
216            ulNewModeData |= 0x00000004;
217            break;
218
219        case CMD_QUEUE_SIZE_1M:
220            ulNewModeData |= 0x00000008;
221            break;
222
223        case CMD_QUEUE_SIZE_2M:
224            ulNewModeData |= 0x0000000C;
225            break;
226
227        default:
228            return(FALSE);
229            break;
230        }
231        *(ULONG *) (pAST->MMIOVirtualAddr + 0x8060) = ulNewModeData;
232
233        /* Set CMDQ Base */
234        ulVMCmdQBasePort  = (pAST->CMDQInfo.ulCMDQOffsetAddr - 0) >> 3;
235        *(ULONG *) (pAST->CMDQInfo.pjCmdQBasePort) = ulVMCmdQBasePort;
236        pAST->CMDQInfo.ulWritePointer = *(ULONG *) (pAST->CMDQInfo.pjWritePort) << 3;
237        break;
238
239    case VM_CMD_MMIO:
240        /* enable new CMDQ mode */
241        ulNewModeData = 0xc00000f2;
242        *(ULONG *) (pAST->MMIOVirtualAddr + 0x8060) = ulNewModeData;
243        break;
244
245    default:
246        return (FALSE);
247        break;
248    }
249
250    return (TRUE);
251
252} /* bEnableCMDQ2300 */
253
254Bool
255bEnable2D(ScrnInfoPtr pScrn, ASTRecPtr pAST)
256{
257    ULONG ulData;
258    PFN_bENABLE_CMDQ pfnEnableCMDQ = bEnableCMDQ;
259
260    if (pAST->jChipType == AST2300)
261        pfnEnableCMDQ = bEnableCMDQ2300;
262
263    switch (pAST->jChipType)
264    {
265    case AST2100:
266    case AST1100:
267    case AST2200:
268    case AST2150:
269    case AST2300:
270       *(ULONG *) (pAST->MMIOVirtualAddr + 0xF004) = 0x1e6e0000;
271       *(ULONG *) (pAST->MMIOVirtualAddr + 0xF000) = 0x1;
272
273       ulData = *(ULONG *) (pAST->MMIOVirtualAddr + 0x1200c);
274       *(ULONG *) (pAST->MMIOVirtualAddr + 0x1200c) = (ulData & 0xFFFFFFFD);
275
276    case AST2000:
277       SetIndexRegMask(CRTC_PORT, 0xA4, 0xFE, 0x01);		/* enable 2D */
278
279       break;
280    }
281
282    if (!bInitCMDQInfo(pScrn, pAST))
283    {
284        vDisable2D(pScrn, pAST);
285    	return (FALSE);
286    }
287
288    if (!pfnEnableCMDQ(pScrn, pAST))
289    {
290        vDisable2D(pScrn, pAST);
291    	return (FALSE);
292    }
293
294    return (TRUE);
295}
296
297void
298vDisable2D(ScrnInfoPtr pScrn, ASTRecPtr pAST)
299{
300
301    vWaitEngIdle(pScrn, pAST);
302    vWaitEngIdle(pScrn, pAST);
303
304    if (pAST->jChipType != AST1180)
305        SetIndexRegMask(CRTC_PORT, 0xA4, 0xFE, 0x00);
306
307}
308
309
310void
311vWaitEngIdle(ScrnInfoPtr pScrn, ASTRecPtr pAST)
312{
313    ULONG ulEngState, ulEngState2;
314    UCHAR jReg;
315    ULONG ulEngCheckSetting;
316
317    if (pAST->MMIO2D)
318        ulEngCheckSetting = 0x10000000;
319    else
320        ulEngCheckSetting = 0x80000000;
321
322    if (pAST->jChipType != AST1180)
323    {
324
325        /* 2D disable if 0xA4 D[0] = 1 */
326        GetIndexRegMask(CRTC_PORT, 0xA4, 0x01, jReg);
327        if (!jReg) goto Exit_vWaitEngIdle;
328
329        /* 2D not work if in std. mode */
330        GetIndexRegMask(CRTC_PORT, 0xA3, 0x0F, jReg);
331        if (!jReg) goto Exit_vWaitEngIdle;
332    }
333
334    do
335    {
336        ulEngState = (*(volatile ULONG *)(pAST->CMDQInfo.pjEngStatePort)) & 0xFFFC0000;
337        ulEngState2 = (*(volatile ULONG *)(pAST->CMDQInfo.pjEngStatePort)) & 0xFFFC0000;
338        ulEngState2 = (*(volatile ULONG *)(pAST->CMDQInfo.pjEngStatePort)) & 0xFFFC0000;
339        ulEngState2 = (*(volatile ULONG *)(pAST->CMDQInfo.pjEngStatePort)) & 0xFFFC0000;
340        ulEngState2 = (*(volatile ULONG *)(pAST->CMDQInfo.pjEngStatePort)) & 0xFFFC0000;
341        ulEngState2 = (*(volatile ULONG *)(pAST->CMDQInfo.pjEngStatePort)) & 0xFFFC0000;
342
343    } while ((ulEngState & ulEngCheckSetting) || (ulEngState != ulEngState2));
344
345Exit_vWaitEngIdle:
346    ;
347}
348
349/* ULONG ulGetCMDQLength() */
350static __inline ULONG ulGetCMDQLength(ASTRecPtr pAST, ULONG ulWritePointer, ULONG ulCMDQMask)
351{
352    ULONG ulReadPointer, ulReadPointer2;
353
354    do {
355        ulReadPointer  = *((volatile ULONG *)(pAST->CMDQInfo.pjReadPort)) & 0x0003FFFF;
356        ulReadPointer2 = *((volatile ULONG *)(pAST->CMDQInfo.pjReadPort)) & 0x0003FFFF;
357        ulReadPointer2 = *((volatile ULONG *)(pAST->CMDQInfo.pjReadPort)) & 0x0003FFFF;
358        ulReadPointer2 = *((volatile ULONG *)(pAST->CMDQInfo.pjReadPort)) & 0x0003FFFF;
359        ulReadPointer2 = *((volatile ULONG *)(pAST->CMDQInfo.pjReadPort)) & 0x0003FFFF;
360        ulReadPointer2 = *((volatile ULONG *)(pAST->CMDQInfo.pjReadPort)) & 0x0003FFFF;
361     } while (ulReadPointer != ulReadPointer2);
362
363    return ((ulReadPointer << 3) - ulWritePointer - CMD_QUEUE_GUARD_BAND) & ulCMDQMask;
364}
365
366UCHAR *pjRequestCMDQ(
367ASTRecPtr pAST, ULONG   ulDataLen)
368{
369    UCHAR   *pjBuffer;
370    ULONG   i, ulWritePointer, ulCMDQMask, ulCurCMDQLen, ulContinueCMDQLen;
371
372    ulWritePointer = pAST->CMDQInfo.ulWritePointer;
373    ulContinueCMDQLen = pAST->CMDQInfo.ulCMDQSize - ulWritePointer;
374    ulCMDQMask = pAST->CMDQInfo.ulCMDQMask;
375
376    if (ulContinueCMDQLen >= ulDataLen)
377    {
378        /* Get CMDQ Buffer */
379        if (pAST->CMDQInfo.ulCurCMDQueueLen >= ulDataLen)
380        {
381        	;
382        }
383        else
384        {
385
386            do
387            {
388                ulCurCMDQLen = ulGetCMDQLength(pAST, ulWritePointer, ulCMDQMask);
389            } while (ulCurCMDQLen < ulDataLen);
390
391            pAST->CMDQInfo.ulCurCMDQueueLen = ulCurCMDQLen;
392
393        }
394
395        pjBuffer = pAST->CMDQInfo.pjCMDQVirtualAddr + ulWritePointer;
396        pAST->CMDQInfo.ulCurCMDQueueLen -= ulDataLen;
397        pAST->CMDQInfo.ulWritePointer = (ulWritePointer + ulDataLen) & ulCMDQMask;
398        return pjBuffer;
399    }
400    else
401    {
402
403        /* Fill NULL CMD to the last of the CMDQ */
404        if (pAST->CMDQInfo.ulCurCMDQueueLen >= ulContinueCMDQLen)
405        {
406        	;
407        }
408        else
409        {
410
411            do
412            {
413                ulCurCMDQLen = ulGetCMDQLength(pAST, ulWritePointer, ulCMDQMask);
414            } while (ulCurCMDQLen < ulContinueCMDQLen);
415
416            pAST->CMDQInfo.ulCurCMDQueueLen = ulCurCMDQLen;
417
418        }
419
420        pjBuffer = pAST->CMDQInfo.pjCMDQVirtualAddr + ulWritePointer;
421        for (i = 0; i<ulContinueCMDQLen/8; i++, pjBuffer+=8)
422        {
423            *(ULONG *)pjBuffer = (ULONG) PKT_NULL_CMD;
424            *(ULONG *) (pjBuffer+4) = 0;
425
426        }
427        pAST->CMDQInfo.ulCurCMDQueueLen -= ulContinueCMDQLen;
428        pAST->CMDQInfo.ulWritePointer = ulWritePointer = 0;
429
430        /* Get CMDQ Buffer */
431        if (pAST->CMDQInfo.ulCurCMDQueueLen >= ulDataLen)
432        {
433	        ;
434        }
435        else
436        {
437
438            do
439            {
440                ulCurCMDQLen = ulGetCMDQLength(pAST, ulWritePointer, ulCMDQMask);
441            } while (ulCurCMDQLen < ulDataLen);
442
443            pAST->CMDQInfo.ulCurCMDQueueLen = ulCurCMDQLen;
444
445        }
446
447        pAST->CMDQInfo.ulCurCMDQueueLen -= ulDataLen;
448        pjBuffer = pAST->CMDQInfo.pjCMDQVirtualAddr + ulWritePointer;
449        pAST->CMDQInfo.ulWritePointer = (ulWritePointer + ulDataLen) & ulCMDQMask;
450        return pjBuffer;
451
452    }
453
454} /* end of pjRequestCmdQ() */
455
456Bool bGetLineTerm(_LINEInfo *LineInfo, LINEPARAM *dsLineParam)
457{
458    LONG GAbsX, GAbsY, GXInc, GYInc, GXMajor;
459    LONG MM, mm, Error0, K1, K2;
460
461    /* Init */
462#ifdef LONG64
463    GAbsX = abs (LineInfo->X1 - LineInfo->X2);
464    GAbsY = abs (LineInfo->Y1 - LineInfo->Y2);
465#else
466    GAbsX = labs (LineInfo->X1 - LineInfo->X2);
467    GAbsY = labs (LineInfo->Y1 - LineInfo->Y2);
468#endif
469
470    GXInc = (LineInfo->X1 < LineInfo->X2) ? 1:0;
471    GYInc = (LineInfo->Y1 < LineInfo->Y2) ? 1:0;
472    GXMajor = (GAbsX >= GAbsY) ? 1:0;
473
474    /* Calculate */
475    if (GXMajor)
476    {
477        MM = GAbsX;
478        mm = GAbsY;
479    }
480    else
481    {
482        MM = GAbsY;
483        mm = GAbsX;
484    }
485
486    Error0 = (signed) (2*mm - MM);
487
488    K1 = 2* mm;
489    K2 = (signed) (2*mm - 2*MM);
490
491    /*save the Param to dsLineParam */
492    dsLineParam->dsLineX = (USHORT) LineInfo->X1;
493    dsLineParam->dsLineY = (USHORT) LineInfo->Y1;
494    dsLineParam->dsLineWidth = (USHORT) MM;
495    dsLineParam->dwErrorTerm = (ULONG) Error0;
496    dsLineParam->dwK1Term = K1;
497    dsLineParam->dwK2Term = K2;
498
499    dsLineParam->dwLineAttributes = 0;
500    if (GXMajor) dsLineParam->dwLineAttributes |= LINEPARAM_XM;
501    if (!GXInc) dsLineParam->dwLineAttributes |= LINEPARAM_X_DEC;
502    if (!GYInc) dsLineParam->dwLineAttributes |= LINEPARAM_Y_DEC;
503
504    return(TRUE);
505
506}
507#endif	/* end of Accel_2D */
508
509
510