1d87a3195Smrg/*
2d87a3195Smrg * Copyright 2006 by Alan Hourihane, North Wales, UK.
3d87a3195Smrg *
4d87a3195Smrg * Permission to use, copy, modify, distribute, and sell this software and its
5d87a3195Smrg * documentation for any purpose is hereby granted without fee, provided that
6d87a3195Smrg * the above copyright notice appear in all copies and that both that
7d87a3195Smrg * copyright notice and this permission notice appear in supporting
8d87a3195Smrg * documentation, and that the name of the authors not be used in
9d87a3195Smrg * advertising or publicity pertaining to distribution of the software without
10d87a3195Smrg * specific, written prior permission.  The authors make no representations
11d87a3195Smrg * about the suitability of this software for any purpose.  It is provided
12d87a3195Smrg * "as is" without express or implied warranty.
13d87a3195Smrg *
14d87a3195Smrg * THE AUTHORS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15d87a3195Smrg * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16d87a3195Smrg * EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17d87a3195Smrg * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18d87a3195Smrg * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19d87a3195Smrg * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
20d87a3195Smrg * PERFORMANCE OF THIS SOFTWARE.
21d87a3195Smrg *
22d87a3195Smrg * Authors:  Alan Hourihane, <alanh@fairlite.demon.co.uk>
23d87a3195Smrg *
24d87a3195Smrg * Trident XP4/XP5 accelerated options.
25d87a3195Smrg */
26d87a3195Smrg
27d87a3195Smrg#ifdef HAVE_CONFIG_H
28d87a3195Smrg#include "config.h"
29d87a3195Smrg#endif
30d87a3195Smrg
31d87a3195Smrg#include "exa.h"
32d87a3195Smrg#include "picture.h"
33d87a3195Smrg
34d87a3195Smrg#include "xf86.h"
35d87a3195Smrg#include "xf86_OSproc.h"
36d87a3195Smrg#include "xf86Pci.h"
37d87a3195Smrg#include "xaarop.h"
38d87a3195Smrg
39d87a3195Smrg#include "trident.h"
40d87a3195Smrg#include "trident_regs.h"
41d87a3195Smrg
42d87a3195Smrgstatic int ropcode;
43d87a3195Smrg
44d87a3195Smrgstatic int CopyROP[16] =
45d87a3195Smrg{
46d87a3195Smrg    ROP_0,              /* GXclear */
47d87a3195Smrg    ROP_DSa,            /* GXand */
48d87a3195Smrg    ROP_SDna,           /* GXandReverse */
49d87a3195Smrg    ROP_S,              /* GXcopy */
50d87a3195Smrg    ROP_DSna,           /* GXandInverted */
51d87a3195Smrg    ROP_D,              /* GXnoop */
52d87a3195Smrg    ROP_DSx,            /* GXxor */
53d87a3195Smrg    ROP_DSo,            /* GXor */
54d87a3195Smrg    ROP_DSon,           /* GXnor */
55d87a3195Smrg    ROP_DSxn,           /* GXequiv */
56d87a3195Smrg    ROP_Dn,             /* GXinvert*/
57d87a3195Smrg    ROP_SDno,           /* GXorReverse */
58d87a3195Smrg    ROP_Sn,             /* GXcopyInverted */
59d87a3195Smrg    ROP_DSno,           /* GXorInverted */
60d87a3195Smrg    ROP_DSan,           /* GXnand */
61d87a3195Smrg    ROP_1               /* GXset */
62d87a3195Smrg};
63d87a3195Smrg
64d87a3195Smrgstatic int PatternROP[16]=
65d87a3195Smrg{
66d87a3195Smrg    ROP_0,
67d87a3195Smrg    ROP_DPa,
68d87a3195Smrg    ROP_PDna,
69d87a3195Smrg    ROP_P,
70d87a3195Smrg    ROP_DPna,
71d87a3195Smrg    ROP_D,
72d87a3195Smrg    ROP_DPx,
73d87a3195Smrg    ROP_DPo,
74d87a3195Smrg    ROP_DPon,
75d87a3195Smrg    ROP_PDxn,
76d87a3195Smrg    ROP_Dn,
77d87a3195Smrg    ROP_PDno,
78d87a3195Smrg    ROP_Pn,
79d87a3195Smrg    ROP_DPno,
80d87a3195Smrg    ROP_DPan,
81d87a3195Smrg    ROP_1
82d87a3195Smrg};
83d87a3195Smrg
84d87a3195Smrgstatic int
85d87a3195SmrgGetCopyROP(int i)
86d87a3195Smrg{
87d87a3195Smrg    return CopyROP[i];
88d87a3195Smrg}
89d87a3195Smrg
90d87a3195Smrgstatic int
91d87a3195SmrgGetPatternROP(int i)
92d87a3195Smrg{
93d87a3195Smrg    return PatternROP[i];
94d87a3195Smrg}
95d87a3195Smrg
96d87a3195Smrgstatic void
97d87a3195SmrgXP4WaitMarker(ScreenPtr pScreen, int Marker)
98d87a3195Smrg{
99d87a3195Smrg    /* Don't need a wait marker as we need to sync on all operations */
100d87a3195Smrg}
101d87a3195Smrg
102d87a3195Smrgstatic void
103d87a3195SmrgXP4Done(PixmapPtr p)
104d87a3195Smrg{
105d87a3195Smrg    ScrnInfoPtr pScrn = xf86ScreenToScrn(p->drawable.pScreen);
106d87a3195Smrg    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
107d87a3195Smrg    int count = 0, timeout = 0;
108d87a3195Smrg    int busy;
109d87a3195Smrg
110d87a3195Smrg    for (;;) {
111d87a3195Smrg        BLTBUSY(busy);
112d87a3195Smrg        if (busy != GE_BUSY) {
113d87a3195Smrg            return;
114d87a3195Smrg        }
115d87a3195Smrg
116d87a3195Smrg        count++;
117d87a3195Smrg        if (count == 10000000) {
118d87a3195Smrg            ErrorF("XP: BitBLT engine time-out.\n");
119d87a3195Smrg            count = 9990000;
120d87a3195Smrg            timeout++;
121d87a3195Smrg            if (timeout == 4) {
122d87a3195Smrg                /* Reset BitBLT Engine */
123d87a3195Smrg                TGUI_STATUS(0x00);
124d87a3195Smrg                return;
125d87a3195Smrg            }
126d87a3195Smrg        }
127d87a3195Smrg    }
128d87a3195Smrg}
129d87a3195Smrg
130d87a3195Smrgstatic Bool
131d87a3195SmrgXP4PrepareSolid(PixmapPtr pPixmap,
132d87a3195Smrg                int alu, Pixel planemask, Pixel fg)
133d87a3195Smrg{
134d87a3195Smrg    ScrnInfoPtr pScrn = xf86ScreenToScrn(pPixmap->drawable.pScreen);
135d87a3195Smrg    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
136d87a3195Smrg    unsigned int dorg = exaGetPixmapOffset(pPixmap);
137d87a3195Smrg    unsigned int dptch = exaGetPixmapPitch(pPixmap);
138d87a3195Smrg
139d87a3195Smrg    if (planemask != -1)
140d87a3195Smrg        return FALSE;
141d87a3195Smrg
142d87a3195Smrg    ropcode = alu;
143d87a3195Smrg
144d87a3195Smrg    MMIO_OUT32(pTrident->IOBase, 0x2150, (dptch << 18) | (dorg >> 4));
145d87a3195Smrg
146d87a3195Smrg    REPLICATE(fg);
147d87a3195Smrg    MMIO_OUT32(pTrident->IOBase, 0x2158, fg);
148d87a3195Smrg    MMIO_OUT32(pTrident->IOBase, 0x2128, 1 << 14);
149d87a3195Smrg
150d87a3195Smrg    return TRUE;
151d87a3195Smrg}
152d87a3195Smrg
153d87a3195Smrgstatic void
154d87a3195SmrgXP4Solid(PixmapPtr pPixmap,
155d87a3195Smrg            int x1, int y1,
156d87a3195Smrg            int x2, int y2)
157d87a3195Smrg{
158d87a3195Smrg    ScrnInfoPtr pScrn = xf86ScreenToScrn(pPixmap->drawable.pScreen);
159d87a3195Smrg    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
160d87a3195Smrg    int bpp;
161d87a3195Smrg
162d87a3195Smrg    switch (pPixmap->drawable.bitsPerPixel) {
163d87a3195Smrg    case 8:
164d87a3195Smrg        bpp = 0x40;
165d87a3195Smrg        break;
166d87a3195Smrg    case 16:
167d87a3195Smrg        bpp = 0x41;
168d87a3195Smrg        break;
169d87a3195Smrg    case 32:
170d87a3195Smrg        bpp = 0x42;
171d87a3195Smrg        break;
172d87a3195Smrg    }
173d87a3195Smrg
174d87a3195Smrg    MMIO_OUT32(pTrident->IOBase, 0x2138, (x1 << 16) | y1);
175d87a3195Smrg    MMIO_OUT32(pTrident->IOBase, 0x2140, ((x2 - x1) << 16) |
176d87a3195Smrg                                            (y2 - y1));
177d87a3195Smrg    MMIO_OUT32(pTrident->IOBase, 0x2124,
178d87a3195Smrg                                    (GetPatternROP(ropcode) << 24) |
179d87a3195Smrg                                    (bpp << 8) |
180d87a3195Smrg                                    2);
181d87a3195Smrg}
182d87a3195Smrg
183d87a3195Smrgstatic Bool
184d87a3195SmrgXP4PrepareCopy(PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap,
185d87a3195Smrg                int dx, int dy,
186d87a3195Smrg                int alu, Pixel planemask)
187d87a3195Smrg{
188d87a3195Smrg    ScrnInfoPtr pScrn = xf86ScreenToScrn(pDstPixmap->drawable.pScreen);
189d87a3195Smrg    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
190d87a3195Smrg    unsigned int sorg = exaGetPixmapOffset(pSrcPixmap);
191d87a3195Smrg    unsigned int dorg = exaGetPixmapOffset(pDstPixmap);
192d87a3195Smrg    unsigned int sptch = exaGetPixmapPitch(pSrcPixmap);
193d87a3195Smrg    unsigned int dptch = exaGetPixmapPitch(pDstPixmap);
194d87a3195Smrg
195d87a3195Smrg    if (planemask != -1)
196d87a3195Smrg        return FALSE;
197d87a3195Smrg
198d87a3195Smrg    pTrident->BltScanDirection = 0;
199d87a3195Smrg    if (dx < 0)
200d87a3195Smrg        pTrident->BltScanDirection |= XNEG;
201d87a3195Smrg    if (dy < 0)
202d87a3195Smrg        pTrident->BltScanDirection |= YNEG;
203d87a3195Smrg
204d87a3195Smrg    ropcode = alu;
205d87a3195Smrg
206d87a3195Smrg    MMIO_OUT32(pTrident->IOBase, 0x2154, (sptch << 18) | (sorg >> 4));
207d87a3195Smrg    MMIO_OUT32(pTrident->IOBase, 0x2150, (dptch << 18) | (dorg >> 4));
208d87a3195Smrg
209d87a3195Smrg    return TRUE;
210d87a3195Smrg}
211d87a3195Smrg
212d87a3195Smrgstatic void
213d87a3195SmrgXP4Copy(PixmapPtr pDstPixmap,
214d87a3195Smrg        int x1, int y1,
215d87a3195Smrg        int x2, int y2,
216d87a3195Smrg        int w, int h)
217d87a3195Smrg{
218d87a3195Smrg    ScrnInfoPtr pScrn = xf86ScreenToScrn(pDstPixmap->drawable.pScreen);
219d87a3195Smrg    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
220d87a3195Smrg    int bpp;
221d87a3195Smrg
222d87a3195Smrg    switch (pDstPixmap->drawable.bitsPerPixel) {
223d87a3195Smrg    case 8:
224d87a3195Smrg        bpp = 0x40;
225d87a3195Smrg        break;
226d87a3195Smrg    case 16:
227d87a3195Smrg        bpp = 0x41;
228d87a3195Smrg        break;
229d87a3195Smrg    case 32:
230d87a3195Smrg        bpp = 0x42;
231d87a3195Smrg        break;
232d87a3195Smrg    }
233d87a3195Smrg
234d87a3195Smrg    if (pTrident->BltScanDirection & YNEG) {
235d87a3195Smrg        y1 = y1 + h - 1;
236d87a3195Smrg        y2 = y2 + h - 1;
237d87a3195Smrg    }
238d87a3195Smrg    if (pTrident->BltScanDirection & XNEG) {
239d87a3195Smrg        x1 = x1 + w - 1;
240d87a3195Smrg        x2 = x2 + w - 1;
241d87a3195Smrg    }
242d87a3195Smrg    MMIO_OUT32(pTrident->IOBase, 0x2128, pTrident->BltScanDirection |
243d87a3195Smrg                                            SCR2SCR);
244d87a3195Smrg    MMIO_OUT32(pTrident->IOBase, 0x2138, (x2 << 16) | y2);
245d87a3195Smrg    MMIO_OUT32(pTrident->IOBase, 0x213C, (x1 << 16) | y1);
246d87a3195Smrg    MMIO_OUT32(pTrident->IOBase, 0x2140, (w << 16) | h);
247d87a3195Smrg    MMIO_OUT32(pTrident->IOBase, 0x2124, (GetCopyROP(ropcode) << 24) |
248d87a3195Smrg                                            (bpp << 8) |
249d87a3195Smrg                                            1);
250d87a3195Smrg}
251d87a3195Smrg
252d87a3195SmrgBool
253d87a3195SmrgXP4ExaInit(ScreenPtr pScreen)
254d87a3195Smrg{
255d87a3195Smrg    ExaDriverPtr pExa;
256d87a3195Smrg    ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
257d87a3195Smrg    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
258d87a3195Smrg
259d87a3195Smrg    if (pTrident->NoAccel)
260d87a3195Smrg        return FALSE;
261d87a3195Smrg
262d87a3195Smrg    if (!(pExa = pTrident->EXADriverPtr = exaDriverAlloc())) {
263d87a3195Smrg        pTrident->NoAccel = TRUE;
264d87a3195Smrg        return FALSE;
265d87a3195Smrg    }
266d87a3195Smrg
267d87a3195Smrg    pExa->exa_major = 2;
268d87a3195Smrg    pExa->exa_minor = 0;
269d87a3195Smrg
270d87a3195Smrg    pExa->flags = EXA_OFFSCREEN_PIXMAPS;
271d87a3195Smrg    pExa->memoryBase = pTrident->FbBase;
272d87a3195Smrg    pExa->memorySize = pTrident->FbMapSize;
273d87a3195Smrg    pExa->offScreenBase = pScrn->displayWidth * pScrn->virtualY *
274d87a3195Smrg                            ((pScrn->bitsPerPixel + 7) / 8);
275d87a3195Smrg
276d87a3195Smrg    pExa->pixmapOffsetAlign = 16;
277d87a3195Smrg    pExa->pixmapPitchAlign = 16;
278d87a3195Smrg
279d87a3195Smrg    pExa->maxX = 4095;
280d87a3195Smrg    pExa->maxY = 4095;
281d87a3195Smrg
282d87a3195Smrg    pExa->WaitMarker = XP4WaitMarker;
283d87a3195Smrg
284d87a3195Smrg    pExa->PrepareSolid = XP4PrepareSolid;
285d87a3195Smrg    pExa->Solid = XP4Solid;
286d87a3195Smrg    pExa->DoneSolid = XP4Done;
287d87a3195Smrg
288d87a3195Smrg    pExa->PrepareCopy = XP4PrepareCopy;
289d87a3195Smrg    pExa->Copy = XP4Copy;
290d87a3195Smrg    pExa->DoneCopy = XP4Done;
291d87a3195Smrg
292d87a3195Smrg    return (exaDriverInit(pScreen, pExa));
293d87a3195Smrg}
294