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