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