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 */
32f9211c3fSjdc/* $NetBSD: pnozz_exa.c,v 1.6 2023/11/05 17:06:14 jdc Exp $ */
33f55eacdeSjdc
34f55eacdeSjdc#ifdef HAVE_CONFIG_H
35f55eacdeSjdc#include "config.h"
36f55eacdeSjdc#endif
37f55eacdeSjdc
38f55eacdeSjdc#include "pnozz.h"
39f55eacdeSjdc#include "pnozz_regs.h"
40f55eacdeSjdc
41f55eacdeSjdc
42f55eacdeSjdcstatic CARD32 PnozzCopyROP[] = {
43f55eacdeSjdc	/*GXclear*/		0,
44f55eacdeSjdc	/*GXand*/		ROP_SRC & ROP_DST,
45f55eacdeSjdc	/*GXandReverse*/	ROP_SRC & (~ROP_DST),
46f55eacdeSjdc	/*GXcopy*/		ROP_SRC,
47f55eacdeSjdc	/*GXandInverted*/	(~ROP_SRC) & ROP_DST,
48f55eacdeSjdc	/*GXnoop*/		ROP_DST,
49f55eacdeSjdc	/*GXxor*/		ROP_SRC ^ ROP_DST,
50f55eacdeSjdc	/*GXor*/		ROP_SRC | ROP_DST,
51f55eacdeSjdc	/*GXnor*/		(~ROP_SRC) & (~ROP_DST),
52f55eacdeSjdc	/*GXequiv*/		(~ROP_SRC) ^ ROP_DST,
53f55eacdeSjdc	/*GXinvert*/		(~ROP_DST),
54f55eacdeSjdc	/*GXorReverse*/		ROP_SRC | (~ROP_DST),
55f55eacdeSjdc	/*GXcopyInverted*/	(~ROP_SRC),
56f55eacdeSjdc	/*GXorInverted*/	(~ROP_SRC) | ROP_DST,
57f55eacdeSjdc	/*GXnand*/		(~ROP_SRC) | (~ROP_DST),
58f55eacdeSjdc	/*GXset*/		ROP_SET
59f55eacdeSjdc};
60f55eacdeSjdc
61f55eacdeSjdcstatic CARD32 PnozzDrawROP[] = {
62f55eacdeSjdc	/*GXclear*/		0,
63f55eacdeSjdc	/*GXand*/		ROP_PAT & ROP_DST,
64f55eacdeSjdc	/*GXandReverse*/	ROP_PAT & (~ROP_DST),
65f55eacdeSjdc	/*GXcopy*/		ROP_PAT,
66f55eacdeSjdc	/*GXandInverted*/	(~ROP_PAT) & ROP_DST,
67f55eacdeSjdc	/*GXnoop*/		ROP_DST,
68f55eacdeSjdc	/*GXxor*/		ROP_PAT ^ ROP_DST,
69f55eacdeSjdc	/*GXor*/		ROP_PAT | ROP_DST,
70f55eacdeSjdc	/*GXnor*/		(~ROP_PAT) & (~ROP_DST),
71f55eacdeSjdc	/*GXequiv*/		(~ROP_PAT) ^ ROP_DST,
72f55eacdeSjdc	/*GXinvert*/		(~ROP_DST),
73f55eacdeSjdc	/*GXorReverse*/		ROP_PAT | (~ROP_DST),
74f55eacdeSjdc	/*GXcopyInverted*/	(~ROP_PAT),
75f55eacdeSjdc	/*GXorInverted*/	(~ROP_PAT) | ROP_DST,
76f55eacdeSjdc	/*GXnand*/		(~ROP_PAT) | (~ROP_DST),
77f55eacdeSjdc	/*GXset*/		ROP_PAT
78f55eacdeSjdc};
79f55eacdeSjdc
80f55eacdeSjdc#define waitReady(pPnozz) while((pnozz_read_4(pPnozz, ENGINE_STATUS) & \
81f55eacdeSjdc				(ENGINE_BUSY | BLITTER_BUSY)) !=0 )
82f55eacdeSjdc
83b2794957Sjdcvoid PnozzInitEngine(PnozzPtr);
84f55eacdeSjdcvoid pnozz_write_colour(PnozzPtr pPnozz, int reg, CARD32 colour);
85f55eacdeSjdc
86b2794957Sjdcextern CARD32 MaxClip, junk;
87b2794957Sjdc
88f55eacdeSjdcstatic void
89f55eacdeSjdcPnozzWaitMarker(ScreenPtr pScreen, int Marker)
90f55eacdeSjdc{
91f55eacdeSjdc    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
92f55eacdeSjdc    PnozzPtr p = GET_PNOZZ_FROM_SCRN(pScrn);
93f55eacdeSjdc
94f55eacdeSjdc    waitReady(p);
95f55eacdeSjdc}
96f55eacdeSjdc
97f55eacdeSjdcstatic Bool
98f55eacdeSjdcPnozzPrepareCopy
99f55eacdeSjdc(
100f55eacdeSjdc    PixmapPtr pSrcPixmap,
101f55eacdeSjdc    PixmapPtr pDstPixmap,
102f55eacdeSjdc    int       xdir,
103f55eacdeSjdc    int       ydir,
104f55eacdeSjdc    int       alu,
105f55eacdeSjdc    Pixel     planemask
106f55eacdeSjdc)
107f55eacdeSjdc{
108f55eacdeSjdc    ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum];
109f55eacdeSjdc    PnozzPtr pPnozz = GET_PNOZZ_FROM_SCRN(pScrn);
110f55eacdeSjdc
111f55eacdeSjdc    waitReady(pPnozz);
112f55eacdeSjdc    pnozz_write_4(pPnozz, RASTER_OP, (PnozzCopyROP[alu] & 0xff));
113f55eacdeSjdc    pnozz_write_4(pPnozz, PLANE_MASK, planemask);
114b2794957Sjdc    pPnozz->srcoff = exaGetPixmapOffset(pSrcPixmap) / pPnozz->width;
115f55eacdeSjdc
116f55eacdeSjdc    return TRUE;
117f55eacdeSjdc}
118f55eacdeSjdc
119f55eacdeSjdcstatic void
120f55eacdeSjdcPnozzCopy
121f55eacdeSjdc(
122f55eacdeSjdc    PixmapPtr pDstPixmap,
123f55eacdeSjdc    int       xSrc,
124f55eacdeSjdc    int       ySrc,
125f55eacdeSjdc    int       xDst,
126f55eacdeSjdc    int       yDst,
127f55eacdeSjdc    int       w,
128f55eacdeSjdc    int       h
129f55eacdeSjdc)
130f55eacdeSjdc{
131f55eacdeSjdc    ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum];
132f55eacdeSjdc    PnozzPtr pPnozz = GET_PNOZZ_FROM_SCRN(pScrn);
133f55eacdeSjdc    CARD32 src, dst, srcw, dstw;
134b2794957Sjdc    int doff = exaGetPixmapOffset(pDstPixmap) / pPnozz->width;
135f55eacdeSjdc
136f55eacdeSjdc    src = (((xSrc << pPnozz->depthshift) & 0x1fff) << 16) |
137b2794957Sjdc	((ySrc + pPnozz->srcoff) & 0x1fff);
138f55eacdeSjdc    dst = (((xDst << pPnozz->depthshift) & 0x1fff) << 16) |
139f55eacdeSjdc	((yDst + doff) & 0x1fff);
140b2794957Sjdc    srcw = ((((xSrc + w) << pPnozz->depthshift) - 1) << 16) |
141b2794957Sjdc        ((ySrc + pPnozz->srcoff + h - 1) & 0x1fff);
142f55eacdeSjdc    dstw = ((((xDst + w) << pPnozz->depthshift) - 1) << 16) |
143b2794957Sjdc        ((yDst + doff + h - 1) & 0x1fff);
144f55eacdeSjdc
145f55eacdeSjdc    waitReady(pPnozz);
146b2794957Sjdc
147f55eacdeSjdc    pnozz_write_4(pPnozz, ABS_XY0, src);
148f55eacdeSjdc    pnozz_write_4(pPnozz, ABS_XY1, srcw);
149f55eacdeSjdc    pnozz_write_4(pPnozz, ABS_XY2, dst);
150f55eacdeSjdc    pnozz_write_4(pPnozz, ABS_XY3, dstw);
151b2794957Sjdc    junk = pnozz_read_4(pPnozz, COMMAND_BLIT);
152f55eacdeSjdc    exaMarkSync(pDstPixmap->drawable.pScreen);
153f55eacdeSjdc}
154f55eacdeSjdc
155f55eacdeSjdcstatic void
156f55eacdeSjdcPnozzDoneCopy(PixmapPtr pDstPixmap)
157f55eacdeSjdc{
158f55eacdeSjdc    ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum];
159f55eacdeSjdc    PnozzPtr pPnozz = GET_PNOZZ_FROM_SCRN(pScrn);
160f55eacdeSjdc
161f55eacdeSjdc    waitReady(pPnozz);
162f55eacdeSjdc}
163f55eacdeSjdc
164f55eacdeSjdcstatic Bool
165f55eacdeSjdcPnozzPrepareSolid(
166f55eacdeSjdc    PixmapPtr pPixmap,
167f55eacdeSjdc    int alu,
168f55eacdeSjdc    Pixel planemask,
169f55eacdeSjdc    Pixel fg)
170f55eacdeSjdc{
171f55eacdeSjdc    ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
172f55eacdeSjdc    PnozzPtr pPnozz = GET_PNOZZ_FROM_SCRN(pScrn);
173f55eacdeSjdc
174f55eacdeSjdc    waitReady(pPnozz);
175f55eacdeSjdc    pnozz_write_colour(pPnozz, FOREGROUND_COLOR, fg);
176b2794957Sjdc    pnozz_write_4(pPnozz, RASTER_OP, PnozzDrawROP[alu] & 0xff);
177f55eacdeSjdc    pnozz_write_4(pPnozz, PLANE_MASK, planemask);
178f55eacdeSjdc    pnozz_write_4(pPnozz, COORD_INDEX, 0);
179f55eacdeSjdc
180f55eacdeSjdc    return TRUE;
181f55eacdeSjdc}
182f55eacdeSjdc
183f55eacdeSjdcstatic void
184f55eacdeSjdcPnozzSolid(
185f55eacdeSjdc    PixmapPtr pPixmap,
186f55eacdeSjdc    int x,
187f55eacdeSjdc    int y,
188f55eacdeSjdc    int x2,
189f55eacdeSjdc    int y2)
190f55eacdeSjdc{
191f55eacdeSjdc    ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
192f55eacdeSjdc    PnozzPtr pPnozz = GET_PNOZZ_FROM_SCRN(pScrn);
193b2794957Sjdc    int w = x2 - x - 1;
194b2794957Sjdc    int h = y2 - y - 1;
195f55eacdeSjdc
196f55eacdeSjdc    waitReady(pPnozz);
197b2794957Sjdc    pnozz_write_4(pPnozz, RECT_RTW_XY, ((x & 0x1fff) << 16) |
198b2794957Sjdc        (y & 0x1fff));
199b2794957Sjdc    pnozz_write_4(pPnozz, RECT_RTP_XY, (((w & 0x1fff) << 16) |
200b2794957Sjdc        (h & 0x1fff)));
201b2794957Sjdc    junk = pnozz_read_4(pPnozz, COMMAND_QUAD);
202f55eacdeSjdc    exaMarkSync(pPixmap->drawable.pScreen);
203f55eacdeSjdc}
204f55eacdeSjdc
205f55eacdeSjdcint
206f55eacdeSjdcPnozzEXAInit(ScreenPtr pScreen)
207f55eacdeSjdc{
208f55eacdeSjdc    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
209f55eacdeSjdc    PnozzPtr pPnozz = GET_PNOZZ_FROM_SCRN(pScrn);
210f55eacdeSjdc    ExaDriverPtr pExa;
211f55eacdeSjdc
212b2794957Sjdc    PnozzInitEngine(pPnozz);
213b2794957Sjdc
214f55eacdeSjdc    pExa = exaDriverAlloc();
215f55eacdeSjdc    if (!pExa)
216f55eacdeSjdc	return FALSE;
217f55eacdeSjdc
218f55eacdeSjdc    pPnozz->pExa = pExa;
219f55eacdeSjdc
220f55eacdeSjdc    pExa->exa_major = EXA_VERSION_MAJOR;
221f55eacdeSjdc    pExa->exa_minor = EXA_VERSION_MINOR;
222f55eacdeSjdc
223f55eacdeSjdc    pExa->memoryBase = pPnozz->fb;
224f55eacdeSjdc
225f55eacdeSjdc    /* round to multiple of pixmap pitch */
226f55eacdeSjdc    pExa->memorySize = (pPnozz->vidmem / pPnozz->width) * pPnozz->width;
227b2794957Sjdc    pExa->offScreenBase = pPnozz->width * pPnozz->height;
228f55eacdeSjdc
229f55eacdeSjdc    /*
230f55eacdeSjdc     * our blitter can't deal with variable pitches
231f55eacdeSjdc     */
232f55eacdeSjdc    pExa->pixmapOffsetAlign = pPnozz->width;
233f55eacdeSjdc    pExa->pixmapPitchAlign = pPnozz->width;
234f55eacdeSjdc
235b2794957Sjdc    pExa->flags = EXA_MIXED_PIXMAPS;
236f55eacdeSjdc
237b2794957Sjdc    pExa->maxX = 4096;
238b2794957Sjdc    pExa->maxY = 4096;
239f55eacdeSjdc
240f55eacdeSjdc    pExa->WaitMarker = PnozzWaitMarker;
241f55eacdeSjdc
242f55eacdeSjdc    pExa->PrepareSolid = PnozzPrepareSolid;
243f55eacdeSjdc    pExa->Solid = PnozzSolid;
244f55eacdeSjdc    pExa->DoneSolid = PnozzDoneCopy;
245f55eacdeSjdc
246f55eacdeSjdc    pExa->PrepareCopy = PnozzPrepareCopy;
247f55eacdeSjdc    pExa->Copy = PnozzCopy;
248f55eacdeSjdc    pExa->DoneCopy = PnozzDoneCopy;
249f55eacdeSjdc
250f55eacdeSjdc    return exaDriverInit(pScreen, pExa);;
251f55eacdeSjdc}
252