ast_2dtool.c revision cf503b78
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) )
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       *(ULONG *) (pAST->MMIOVirtualAddr + 0xF004) = 0x1e6e0000;
256       *(ULONG *) (pAST->MMIOVirtualAddr + 0xF000) = 0x1;
257
258       ulData = *(ULONG *) (pAST->MMIOVirtualAddr + 0x1200c);
259       *(ULONG *) (pAST->MMIOVirtualAddr + 0x1200c) = (ulData & 0xFFFFFFFD);
260
261    case AST2000:
262       SetIndexRegMask(CRTC_PORT, 0xA4, 0xFE, 0x01);		/* enable 2D */
263
264       break;
265    }
266
267    if (!bInitCMDQInfo(pScrn, pAST))
268    {
269        vASTDisable2D(pScrn, pAST);
270    	return (FALSE);
271    }
272
273    if (!pfnEnableCMDQ(pScrn, pAST))
274    {
275        vASTDisable2D(pScrn, pAST);
276    	return (FALSE);
277    }
278
279    return (TRUE);
280}
281
282void
283vASTDisable2D(ScrnInfoPtr pScrn, ASTRecPtr pAST)
284{
285
286    vASTWaitEngIdle(pScrn, pAST);
287    vASTWaitEngIdle(pScrn, pAST);
288
289    /* restore 2D settings */
290    if (pAST->jChipType != AST1180)
291    {
292        if (pAST->SavedReg.REGA4 & 0x01)	/* 2D enabled */
293        {
294            SetIndexRegMask(CRTC_PORT, 0xA4, 0xFE, 0x01);
295            *(ULONG *) (pAST->MMIOVirtualAddr + 0x8044) = pAST->SavedReg.ENG8044;
296        }
297        else								/* 2D disabled */
298        {
299            SetIndexRegMask(CRTC_PORT, 0xA4, 0xFE, 0x00);
300        }
301    }
302}
303
304
305void
306vASTWaitEngIdle(ScrnInfoPtr pScrn, ASTRecPtr pAST)
307{
308    ULONG ulEngState, ulEngState2;
309    UCHAR jReg;
310    ULONG ulEngCheckSetting = 0x80000000;
311
312    if (pAST->jChipType != AST1180)
313    {
314
315        /* 2D disable if 0xA4 D[0] = 1 */
316        GetIndexRegMask(CRTC_PORT, 0xA4, 0x01, jReg);
317        if (!jReg) goto Exit_vASTWaitEngIdle;
318
319        /* 2D not work if in std. mode */
320        GetIndexRegMask(CRTC_PORT, 0xA3, 0x0F, jReg);
321        if (!jReg) goto Exit_vASTWaitEngIdle;
322    }
323
324    if (*(ULONG *) (pAST->CMDQInfo.pjCmdQBasePort) & 0x02000000)	/* MMIO Mode */
325        ulEngCheckSetting = 0x10000000;
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_vASTWaitEngIdle:
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));
349	ulReadPointer2 = *((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     } while ( ((ulReadPointer & 0x0003FFFF) != (ulReadPointer2 & 0x0003FFFF)) || (ulReadPointer == 0xFFFFEEEE) );
355
356    return ((ulReadPointer << 3) - ulWritePointer - CMD_QUEUE_GUARD_BAND) & ulCMDQMask;
357}
358
359UCHAR *pASTjRequestCMDQ(
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 bASTGetLineTerm(_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