pnozz_exa.c revision 61d63f49
1/*
2 * SBus Weitek P9100 EXA support
3 *
4/*-
5 * Copyright (c) 2021 The NetBSD Foundation, Inc.
6 * All rights reserved.
7 *
8 * This code is derived from software contributed to The NetBSD Foundation
9 * by Julian Coleman.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 *    notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 *    notice, this list of conditions and the following disclaimer in the
18 *    documentation and/or other materials provided with the distribution.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE.
31 */
32
33#ifdef HAVE_CONFIG_H
34#include "config.h"
35#endif
36
37#include "pnozz.h"
38#include "pnozz_regs.h"
39
40
41static CARD32 PnozzCopyROP[] = {
42	/*GXclear*/		0,
43	/*GXand*/		ROP_SRC & ROP_DST,
44	/*GXandReverse*/	ROP_SRC & (~ROP_DST),
45	/*GXcopy*/		ROP_SRC,
46	/*GXandInverted*/	(~ROP_SRC) & ROP_DST,
47	/*GXnoop*/		ROP_DST,
48	/*GXxor*/		ROP_SRC ^ ROP_DST,
49	/*GXor*/		ROP_SRC | ROP_DST,
50	/*GXnor*/		(~ROP_SRC) & (~ROP_DST),
51	/*GXequiv*/		(~ROP_SRC) ^ ROP_DST,
52	/*GXinvert*/		(~ROP_DST),
53	/*GXorReverse*/		ROP_SRC | (~ROP_DST),
54	/*GXcopyInverted*/	(~ROP_SRC),
55	/*GXorInverted*/	(~ROP_SRC) | ROP_DST,
56	/*GXnand*/		(~ROP_SRC) | (~ROP_DST),
57	/*GXset*/		ROP_SET
58};
59
60static CARD32 PnozzDrawROP[] = {
61	/*GXclear*/		0,
62	/*GXand*/		ROP_PAT & ROP_DST,
63	/*GXandReverse*/	ROP_PAT & (~ROP_DST),
64	/*GXcopy*/		ROP_PAT,
65	/*GXandInverted*/	(~ROP_PAT) & ROP_DST,
66	/*GXnoop*/		ROP_DST,
67	/*GXxor*/		ROP_PAT ^ ROP_DST,
68	/*GXor*/		ROP_PAT | ROP_DST,
69	/*GXnor*/		(~ROP_PAT) & (~ROP_DST),
70	/*GXequiv*/		(~ROP_PAT) ^ ROP_DST,
71	/*GXinvert*/		(~ROP_DST),
72	/*GXorReverse*/		ROP_PAT | (~ROP_DST),
73	/*GXcopyInverted*/	(~ROP_PAT),
74	/*GXorInverted*/	(~ROP_PAT) | ROP_DST,
75	/*GXnand*/		(~ROP_PAT) | (~ROP_DST),
76	/*GXset*/		ROP_PAT
77};
78
79#define waitReady(pPnozz) while((pnozz_read_4(pPnozz, ENGINE_STATUS) & \
80				(ENGINE_BUSY | BLITTER_BUSY)) !=0 )
81
82void PnozzInitEngine(PnozzPtr);
83void pnozz_write_colour(PnozzPtr pPnozz, int reg, CARD32 colour);
84
85extern CARD32 MaxClip, junk;
86
87static void
88PnozzWaitMarker(ScreenPtr pScreen, int Marker)
89{
90    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
91    PnozzPtr p = GET_PNOZZ_FROM_SCRN(pScrn);
92
93    waitReady(p);
94}
95
96static Bool
97PnozzPrepareCopy
98(
99    PixmapPtr pSrcPixmap,
100    PixmapPtr pDstPixmap,
101    int       xdir,
102    int       ydir,
103    int       alu,
104    Pixel     planemask
105)
106{
107    ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum];
108    PnozzPtr pPnozz = GET_PNOZZ_FROM_SCRN(pScrn);
109
110    waitReady(pPnozz);
111    pnozz_write_4(pPnozz, RASTER_OP, (PnozzCopyROP[alu] & 0xff));
112    pnozz_write_4(pPnozz, PLANE_MASK, planemask);
113    pPnozz->srcoff = exaGetPixmapOffset(pSrcPixmap) / pPnozz->width;
114
115    return TRUE;
116}
117
118static void
119PnozzCopy
120(
121    PixmapPtr pDstPixmap,
122    int       xSrc,
123    int       ySrc,
124    int       xDst,
125    int       yDst,
126    int       w,
127    int       h
128)
129{
130    ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum];
131    PnozzPtr pPnozz = GET_PNOZZ_FROM_SCRN(pScrn);
132    CARD32 src, dst, srcw, dstw;
133    int doff = exaGetPixmapOffset(pDstPixmap) / pPnozz->width;
134
135    src = (((xSrc << pPnozz->depthshift) & 0x1fff) << 16) |
136	((ySrc + pPnozz->srcoff) & 0x1fff);
137    dst = (((xDst << pPnozz->depthshift) & 0x1fff) << 16) |
138	((yDst + doff) & 0x1fff);
139    srcw = ((((xSrc + w) << pPnozz->depthshift) - 1) << 16) |
140        ((ySrc + pPnozz->srcoff + h - 1) & 0x1fff);
141    dstw = ((((xDst + w) << pPnozz->depthshift) - 1) << 16) |
142        ((yDst + doff + h - 1) & 0x1fff);
143
144    waitReady(pPnozz);
145
146    pnozz_write_4(pPnozz, ABS_XY0, src);
147    pnozz_write_4(pPnozz, ABS_XY1, srcw);
148    pnozz_write_4(pPnozz, ABS_XY2, dst);
149    pnozz_write_4(pPnozz, ABS_XY3, dstw);
150    junk = pnozz_read_4(pPnozz, COMMAND_BLIT);
151    exaMarkSync(pDstPixmap->drawable.pScreen);
152}
153
154static void
155PnozzDoneCopy(PixmapPtr pDstPixmap)
156{
157    ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum];
158    PnozzPtr pPnozz = GET_PNOZZ_FROM_SCRN(pScrn);
159
160    waitReady(pPnozz);
161}
162
163static Bool
164PnozzPrepareSolid(
165    PixmapPtr pPixmap,
166    int alu,
167    Pixel planemask,
168    Pixel fg)
169{
170    ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
171    PnozzPtr pPnozz = GET_PNOZZ_FROM_SCRN(pScrn);
172
173    waitReady(pPnozz);
174    pnozz_write_colour(pPnozz, FOREGROUND_COLOR, fg);
175    pnozz_write_4(pPnozz, RASTER_OP, PnozzDrawROP[alu] & 0xff);
176    pnozz_write_4(pPnozz, PLANE_MASK, planemask);
177    pnozz_write_4(pPnozz, COORD_INDEX, 0);
178
179    return TRUE;
180}
181
182static void
183PnozzSolid(
184    PixmapPtr pPixmap,
185    int x,
186    int y,
187    int x2,
188    int y2)
189{
190    ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
191    PnozzPtr pPnozz = GET_PNOZZ_FROM_SCRN(pScrn);
192    int w = x2 - x - 1;
193    int h = y2 - y - 1;
194
195    waitReady(pPnozz);
196    pnozz_write_4(pPnozz, RECT_RTW_XY, ((x & 0x1fff) << 16) |
197        (y & 0x1fff));
198    pnozz_write_4(pPnozz, RECT_RTP_XY, (((w & 0x1fff) << 16) |
199        (h & 0x1fff)));
200    junk = pnozz_read_4(pPnozz, COMMAND_QUAD);
201    exaMarkSync(pPixmap->drawable.pScreen);
202}
203
204int
205PnozzEXAInit(ScreenPtr pScreen)
206{
207    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
208    PnozzPtr pPnozz = GET_PNOZZ_FROM_SCRN(pScrn);
209    ExaDriverPtr pExa;
210
211    PnozzInitEngine(pPnozz);
212
213    pExa = exaDriverAlloc();
214    if (!pExa)
215	return FALSE;
216
217    pPnozz->pExa = pExa;
218
219    pExa->exa_major = EXA_VERSION_MAJOR;
220    pExa->exa_minor = EXA_VERSION_MINOR;
221
222    pExa->memoryBase = pPnozz->fb;
223
224    /* round to multiple of pixmap pitch */
225    pExa->memorySize = (pPnozz->vidmem / pPnozz->width) * pPnozz->width;
226    pExa->offScreenBase = pPnozz->width * pPnozz->height;
227
228    /*
229     * our blitter can't deal with variable pitches
230     */
231    pExa->pixmapOffsetAlign = pPnozz->width;
232    pExa->pixmapPitchAlign = pPnozz->width;
233
234    pExa->flags = EXA_MIXED_PIXMAPS;
235
236    pExa->maxX = 4096;
237    pExa->maxY = 4096;
238
239    pExa->WaitMarker = PnozzWaitMarker;
240
241    pExa->PrepareSolid = PnozzPrepareSolid;
242    pExa->Solid = PnozzSolid;
243    pExa->DoneSolid = PnozzDoneCopy;
244
245    pExa->PrepareCopy = PnozzPrepareCopy;
246    pExa->Copy = PnozzCopy;
247    pExa->DoneCopy = PnozzDoneCopy;
248
249    return exaDriverInit(pScreen, pExa);;
250}
251