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