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