ast_2dtool.c revision b410ddbe
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       break;
276    }
277
278    SetIndexRegMask(CRTC_PORT, 0xA4, 0xFE, 0x01);		/* enable 2D */
279
280    if (!bInitCMDQInfo(pScrn, pAST))
281    {
282        vDisable2D(pScrn, pAST);
283    	return (FALSE);
284    }
285
286    if (!pfnEnableCMDQ(pScrn, pAST))
287    {
288        vDisable2D(pScrn, pAST);
289    	return (FALSE);
290    }
291
292    return (TRUE);
293}
294
295void
296vDisable2D(ScrnInfoPtr pScrn, ASTRecPtr pAST)
297{
298
299    vWaitEngIdle(pScrn, pAST);
300    vWaitEngIdle(pScrn, pAST);
301
302    SetIndexRegMask(CRTC_PORT, 0xA4, 0xFE, 0x00);
303
304}
305
306
307void
308vWaitEngIdle(ScrnInfoPtr pScrn, ASTRecPtr pAST)
309{
310    ULONG ulEngState, ulEngState2;
311    UCHAR jReg;
312    ULONG ulEngCheckSetting;
313
314    if (pAST->MMIO2D)
315        ulEngCheckSetting = 0x10000000;
316    else
317        ulEngCheckSetting = 0x80000000;
318
319    /* 2D disable if 0xA4 D[0] = 1 */
320    GetIndexRegMask(CRTC_PORT, 0xA4, 0x01, jReg);
321    if (!jReg) goto Exit_vWaitEngIdle;
322
323    /* 2D not work if in std. mode */
324    GetIndexRegMask(CRTC_PORT, 0xA3, 0x0F, jReg);
325    if (!jReg) goto Exit_vWaitEngIdle;
326
327    do
328    {
329        ulEngState = (*(volatile ULONG *)(pAST->CMDQInfo.pjEngStatePort)) & 0xFFFC0000;
330        ulEngState2 = (*(volatile ULONG *)(pAST->CMDQInfo.pjEngStatePort)) & 0xFFFC0000;
331        ulEngState2 = (*(volatile ULONG *)(pAST->CMDQInfo.pjEngStatePort)) & 0xFFFC0000;
332        ulEngState2 = (*(volatile ULONG *)(pAST->CMDQInfo.pjEngStatePort)) & 0xFFFC0000;
333        ulEngState2 = (*(volatile ULONG *)(pAST->CMDQInfo.pjEngStatePort)) & 0xFFFC0000;
334        ulEngState2 = (*(volatile ULONG *)(pAST->CMDQInfo.pjEngStatePort)) & 0xFFFC0000;
335
336    } while ((ulEngState & ulEngCheckSetting) || (ulEngState != ulEngState2));
337
338Exit_vWaitEngIdle:
339    ;
340}
341
342/* ULONG ulGetCMDQLength() */
343static __inline ULONG ulGetCMDQLength(ASTRecPtr pAST, ULONG ulWritePointer, ULONG ulCMDQMask)
344{
345    ULONG ulReadPointer, ulReadPointer2;
346
347    do {
348        ulReadPointer  = *((volatile ULONG *)(pAST->CMDQInfo.pjReadPort)) & 0x0003FFFF;
349        ulReadPointer2 = *((volatile ULONG *)(pAST->CMDQInfo.pjReadPort)) & 0x0003FFFF;
350        ulReadPointer2 = *((volatile ULONG *)(pAST->CMDQInfo.pjReadPort)) & 0x0003FFFF;
351        ulReadPointer2 = *((volatile ULONG *)(pAST->CMDQInfo.pjReadPort)) & 0x0003FFFF;
352        ulReadPointer2 = *((volatile ULONG *)(pAST->CMDQInfo.pjReadPort)) & 0x0003FFFF;
353        ulReadPointer2 = *((volatile ULONG *)(pAST->CMDQInfo.pjReadPort)) & 0x0003FFFF;
354     } while (ulReadPointer != ulReadPointer2);
355
356    return ((ulReadPointer << 3) - ulWritePointer - CMD_QUEUE_GUARD_BAND) & ulCMDQMask;
357}
358
359UCHAR *pjRequestCMDQ(
360ASTRecPtr pAST, ULONG   ulDataLen)
361{
362    UCHAR   *pjBuffer;
363    ULONG   i, ulWritePointer, ulCMDQMask, ulCurCMDQLen, ulContinueCMDQLen;
364
365    ulWritePointer = pAST->CMDQInfo.ulWritePointer;
366    ulContinueCMDQLen = pAST->CMDQInfo.ulCMDQSize - ulWritePointer;
367    ulCMDQMask = pAST->CMDQInfo.ulCMDQMask;
368
369    if (ulContinueCMDQLen >= ulDataLen)
370    {
371        /* Get CMDQ Buffer */
372        if (pAST->CMDQInfo.ulCurCMDQueueLen >= ulDataLen)
373        {
374        	;
375        }
376        else
377        {
378
379            do
380            {
381                ulCurCMDQLen = ulGetCMDQLength(pAST, ulWritePointer, ulCMDQMask);
382            } while (ulCurCMDQLen < ulDataLen);
383
384            pAST->CMDQInfo.ulCurCMDQueueLen = ulCurCMDQLen;
385
386        }
387
388        pjBuffer = pAST->CMDQInfo.pjCMDQVirtualAddr + ulWritePointer;
389        pAST->CMDQInfo.ulCurCMDQueueLen -= ulDataLen;
390        pAST->CMDQInfo.ulWritePointer = (ulWritePointer + ulDataLen) & ulCMDQMask;
391        return pjBuffer;
392    }
393    else
394    {
395
396        /* Fill NULL CMD to the last of the CMDQ */
397        if (pAST->CMDQInfo.ulCurCMDQueueLen >= ulContinueCMDQLen)
398        {
399        	;
400        }
401        else
402        {
403
404            do
405            {
406                ulCurCMDQLen = ulGetCMDQLength(pAST, ulWritePointer, ulCMDQMask);
407            } while (ulCurCMDQLen < ulContinueCMDQLen);
408
409            pAST->CMDQInfo.ulCurCMDQueueLen = ulCurCMDQLen;
410
411        }
412
413        pjBuffer = pAST->CMDQInfo.pjCMDQVirtualAddr + ulWritePointer;
414        for (i = 0; i<ulContinueCMDQLen/8; i++, pjBuffer+=8)
415        {
416            *(ULONG *)pjBuffer = (ULONG) PKT_NULL_CMD;
417            *(ULONG *) (pjBuffer+4) = 0;
418
419        }
420        pAST->CMDQInfo.ulCurCMDQueueLen -= ulContinueCMDQLen;
421        pAST->CMDQInfo.ulWritePointer = ulWritePointer = 0;
422
423        /* Get CMDQ Buffer */
424        if (pAST->CMDQInfo.ulCurCMDQueueLen >= ulDataLen)
425        {
426	        ;
427        }
428        else
429        {
430
431            do
432            {
433                ulCurCMDQLen = ulGetCMDQLength(pAST, ulWritePointer, ulCMDQMask);
434            } while (ulCurCMDQLen < ulDataLen);
435
436            pAST->CMDQInfo.ulCurCMDQueueLen = ulCurCMDQLen;
437
438        }
439
440        pAST->CMDQInfo.ulCurCMDQueueLen -= ulDataLen;
441        pjBuffer = pAST->CMDQInfo.pjCMDQVirtualAddr + ulWritePointer;
442        pAST->CMDQInfo.ulWritePointer = (ulWritePointer + ulDataLen) & ulCMDQMask;
443        return pjBuffer;
444
445    }
446
447} /* end of pjRequestCmdQ() */
448
449Bool bGetLineTerm(_LINEInfo *LineInfo, LINEPARAM *dsLineParam)
450{
451    LONG GAbsX, GAbsY, GXInc, GYInc, GXMajor;
452    LONG MM, mm, Error0, K1, K2;
453
454    /* Init */
455#ifdef LONG64
456    GAbsX = abs (LineInfo->X1 - LineInfo->X2);
457    GAbsY = abs (LineInfo->Y1 - LineInfo->Y2);
458#else
459    GAbsX = labs (LineInfo->X1 - LineInfo->X2);
460    GAbsY = labs (LineInfo->Y1 - LineInfo->Y2);
461#endif
462
463    GXInc = (LineInfo->X1 < LineInfo->X2) ? 1:0;
464    GYInc = (LineInfo->Y1 < LineInfo->Y2) ? 1:0;
465    GXMajor = (GAbsX >= GAbsY) ? 1:0;
466
467    /* Calculate */
468    if (GXMajor)
469    {
470        MM = GAbsX;
471        mm = GAbsY;
472    }
473    else
474    {
475        MM = GAbsY;
476        mm = GAbsX;
477    }
478
479    Error0 = (signed) (2*mm - MM);
480
481    K1 = 2* mm;
482    K2 = (signed) (2*mm - 2*MM);
483
484    /*save the Param to dsLineParam */
485    dsLineParam->dsLineX = (USHORT) LineInfo->X1;
486    dsLineParam->dsLineY = (USHORT) LineInfo->Y1;
487    dsLineParam->dsLineWidth = (USHORT) MM;
488    dsLineParam->dwErrorTerm = (ULONG) Error0;
489    dsLineParam->dwK1Term = K1;
490    dsLineParam->dwK2Term = K2;
491
492    dsLineParam->dwLineAttributes = 0;
493    if (GXMajor) dsLineParam->dwLineAttributes |= LINEPARAM_XM;
494    if (!GXInc) dsLineParam->dwLineAttributes |= LINEPARAM_X_DEC;
495    if (!GYInc) dsLineParam->dwLineAttributes |= LINEPARAM_Y_DEC;
496
497    return(TRUE);
498
499}
500#endif	/* end of Accel_2D */
501
502
503