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