1a6b33934Smacallan/*
2a6b33934Smacallan * SBus Weitek P9100 hardware acceleration support
3a6b33934Smacallan *
4a6b33934Smacallan * Copyright (C) 2005 Michael Lorenz
5a6b33934Smacallan *
6a6b33934Smacallan * Permission is hereby granted, free of charge, to any person obtaining a copy
7a6b33934Smacallan * of this software and associated documentation files (the "Software"), to deal
8a6b33934Smacallan * in the Software without restriction, including without limitation the rights
9a6b33934Smacallan * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10a6b33934Smacallan * copies of the Software, and to permit persons to whom the Software is
11a6b33934Smacallan * furnished to do so, subject to the following conditions:
12a6b33934Smacallan *
13a6b33934Smacallan * The above copyright notice and this permission notice shall be included in
14a6b33934Smacallan * all copies or substantial portions of the Software.
15a6b33934Smacallan *
16a6b33934Smacallan * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17a6b33934Smacallan * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18a6b33934Smacallan * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19a6b33934Smacallan * MICHAEL LORENZ BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
20a6b33934Smacallan * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21a6b33934Smacallan * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22a6b33934Smacallan */
23f55eacdeSjdc/* $NetBSD: pnozz_accel.c,v 1.3 2021/05/27 04:48:10 jdc Exp $ */
24a6b33934Smacallan
25f55eacdeSjdc#ifdef HAVE_CONFIG_H
26f55eacdeSjdc#include "config.h"
27f55eacdeSjdc#endif
28a6b33934Smacallan
29a6b33934Smacallan#include "pnozz.h"
30f55eacdeSjdc#include "pnozz_regs.h"
31f55eacdeSjdc#include "dgaproc.h"
32a6b33934Smacallan
33a6b33934Smacallanstatic CARD32 PnozzCopyROP[] = {
34a6b33934Smacallan	/*GXclear*/		0,
35a6b33934Smacallan	/*GXand*/		ROP_SRC & ROP_DST,
36a6b33934Smacallan	/*GXandReverse*/	ROP_SRC & (~ROP_DST),
37a6b33934Smacallan	/*GXcopy*/		ROP_SRC,
38a6b33934Smacallan	/*GXandInverted*/	(~ROP_SRC) & ROP_DST,
39a6b33934Smacallan	/*GXnoop*/		ROP_DST,
40a6b33934Smacallan	/*GXxor*/		ROP_SRC ^ ROP_DST,
41a6b33934Smacallan	/*GXor*/		ROP_SRC | ROP_DST,
42a6b33934Smacallan	/*GXnor*/		(~ROP_SRC) & (~ROP_DST),
43a6b33934Smacallan	/*GXequiv*/		(~ROP_SRC) ^ ROP_DST,
44a6b33934Smacallan	/*GXinvert*/		(~ROP_DST),
45a6b33934Smacallan	/*GXorReverse*/		ROP_SRC | (~ROP_DST),
46a6b33934Smacallan	/*GXcopyInverted*/	(~ROP_SRC),
47a6b33934Smacallan	/*GXorInverted*/	(~ROP_SRC) | ROP_DST,
48a6b33934Smacallan	/*GXnand*/		(~ROP_SRC) | (~ROP_DST),
49a6b33934Smacallan	/*GXset*/		ROP_SET
50a6b33934Smacallan};
51a6b33934Smacallan
52a6b33934Smacallanstatic CARD32 PnozzDrawROP[] = {
53a6b33934Smacallan	/*GXclear*/		0,
54a6b33934Smacallan	/*GXand*/		ROP_PAT & ROP_DST,
55a6b33934Smacallan	/*GXandReverse*/	ROP_PAT & (~ROP_DST),
56a6b33934Smacallan	/*GXcopy*/		ROP_PAT,
57a6b33934Smacallan	/*GXandInverted*/	(~ROP_PAT) & ROP_DST,
58a6b33934Smacallan	/*GXnoop*/		ROP_DST,
59a6b33934Smacallan	/*GXxor*/		ROP_PAT ^ ROP_DST,
60a6b33934Smacallan	/*GXor*/		ROP_PAT | ROP_DST,
61a6b33934Smacallan	/*GXnor*/		(~ROP_PAT) & (~ROP_DST),
62a6b33934Smacallan	/*GXequiv*/		(~ROP_PAT) ^ ROP_DST,
63a6b33934Smacallan	/*GXinvert*/		(~ROP_DST),
64a6b33934Smacallan	/*GXorReverse*/		ROP_PAT | (~ROP_DST),
65a6b33934Smacallan	/*GXcopyInverted*/	(~ROP_PAT),
66a6b33934Smacallan	/*GXorInverted*/	(~ROP_PAT) | ROP_DST,
67a6b33934Smacallan	/*GXnand*/		(~ROP_PAT) | (~ROP_DST),
68a6b33934Smacallan	/*GXset*/		ROP_PAT
69a6b33934Smacallan};
70a6b33934Smacallan
71f55eacdeSjdc/* DGA stuff */
72f55eacdeSjdc
73f55eacdeSjdcstatic Bool Pnozz_OpenFramebuffer(ScrnInfoPtr pScrn, char **,
74f55eacdeSjdc    unsigned char **mem, int *, int *, int *);
75f55eacdeSjdcstatic Bool Pnozz_SetMode(ScrnInfoPtr, DGAModePtr);
76f55eacdeSjdcstatic void Pnozz_SetViewport(ScrnInfoPtr, int, int, int);
77f55eacdeSjdcstatic int Pnozz_GetViewport(ScrnInfoPtr);
78f55eacdeSjdcstatic void Pnozz_FillRect(ScrnInfoPtr, int, int, int, int, unsigned long);
79f55eacdeSjdcstatic void Pnozz_BlitRect(ScrnInfoPtr, int, int, int, int, int, int);
80f55eacdeSjdc
81f55eacdeSjdcstatic void PnozzSync(ScrnInfoPtr);
82f55eacdeSjdc
83f55eacdeSjdcstatic DGAFunctionRec Pnozz_DGAFuncs = {
84f55eacdeSjdc        Pnozz_OpenFramebuffer,
85f55eacdeSjdc        NULL,
86f55eacdeSjdc        Pnozz_SetMode,
87f55eacdeSjdc        Pnozz_SetViewport,
88f55eacdeSjdc        Pnozz_GetViewport,
89f55eacdeSjdc        PnozzSync,
90f55eacdeSjdc        Pnozz_FillRect,
91f55eacdeSjdc        Pnozz_BlitRect,
92f55eacdeSjdc        NULL
93f55eacdeSjdc};
94f55eacdeSjdc
95f55eacdeSjdc
96a6b33934SmacallanCARD32 MaxClip, junk;
97a6b33934Smacallan
98a6b33934Smacallanvoid
99a6b33934SmacallanPnozzSync(ScrnInfoPtr pScrn)
100a6b33934Smacallan{
101a6b33934Smacallan    PnozzPtr pPnozz = GET_PNOZZ_FROM_SCRN(pScrn);
102a6b33934Smacallan    while((pnozz_read_4(pPnozz, ENGINE_STATUS) &
103a6b33934Smacallan        (ENGINE_BUSY | BLITTER_BUSY)) !=0 );
104a6b33934Smacallan}
105a6b33934Smacallan
106a6b33934Smacallan/*
107a6b33934Smacallan * Both the framebuffer and the colour registers are apparently little endian.
108a6b33934Smacallan * For framebuffer accesses we can just turn on byte swapping, for the colour
109a6b33934Smacallan * registers we need to juggle bytes ourselves.
110a6b33934Smacallan */
111a6b33934Smacallan
112f55eacdeSjdcvoid
113a6b33934Smacallanpnozz_write_colour(PnozzPtr pPnozz, int reg, CARD32 colour)
114a6b33934Smacallan{
115a6b33934Smacallan    CARD32 c2;
116a6b33934Smacallan
117a6b33934Smacallan    switch(pPnozz->depthshift)
118a6b33934Smacallan    {
119a6b33934Smacallan    	case 0:
120a6b33934Smacallan	    c2 = (colour << 8 | colour);
121a6b33934Smacallan	    pnozz_write_4(pPnozz, reg, c2 << 16 | c2);
122a6b33934Smacallan	    break;
123a6b33934Smacallan    	case 1:
124a6b33934Smacallan    	    c2 = ((colour & 0xff) << 8) | ((colour & 0xff00) >> 8);
125a6b33934Smacallan	    c2 |= c2 << 16;
126a6b33934Smacallan	    pnozz_write_4(pPnozz, reg, c2);
127a6b33934Smacallan	    break;
128a6b33934Smacallan    	case 2:
129a6b33934Smacallan    	    c2 = ((colour & 0x00ff00ff) << 8) | ((colour & 0xff00ff00) >> 8);
130a6b33934Smacallan    	    c2 = (( c2 & 0xffff0000) >> 16) | ((c2 & 0x0000ffff) << 16);
131a6b33934Smacallan	    pnozz_write_4(pPnozz, reg, c2);
132a6b33934Smacallan	    break;
133a6b33934Smacallan    }
134a6b33934Smacallan}
135a6b33934Smacallan
136a6b33934Smacallanstatic void unClip(PnozzPtr pPnozz)
137a6b33934Smacallan{
138a6b33934Smacallan    pnozz_write_4(pPnozz, WINDOW_OFFSET, 0);
139a6b33934Smacallan    pnozz_write_4(pPnozz, WINDOW_MIN, 0);
140a6b33934Smacallan    pnozz_write_4(pPnozz, WINDOW_MAX, MaxClip);
141a6b33934Smacallan    pnozz_write_4(pPnozz, BYTE_CLIP_MIN, 0);
142a6b33934Smacallan    pnozz_write_4(pPnozz, BYTE_CLIP_MAX, MaxClip);
143a6b33934Smacallan}
144a6b33934Smacallan
145f55eacdeSjdcvoid
146a6b33934SmacallanPnozzInitEngine(PnozzPtr pPnozz)
147a6b33934Smacallan{
148a6b33934Smacallan    unClip(pPnozz);
149a6b33934Smacallan    pnozz_write_4(pPnozz, DRAW_MODE, 0);
150a6b33934Smacallan    pnozz_write_4(pPnozz, PLANE_MASK, 0xffffffff);
151a6b33934Smacallan    pnozz_write_4(pPnozz, PATTERN0, 0xffffffff);
152a6b33934Smacallan    pnozz_write_4(pPnozz, PATTERN1, 0xffffffff);
153a6b33934Smacallan    pnozz_write_4(pPnozz, PATTERN2, 0xffffffff);
154a6b33934Smacallan    pnozz_write_4(pPnozz, PATTERN3, 0xffffffff);
155a6b33934Smacallan}
156a6b33934Smacallan
157a6b33934Smacallanstatic void
158a6b33934SmacallanPnozzSetupForScreenToScreenCopy(
159a6b33934Smacallan    ScrnInfoPtr  pScrn,
160a6b33934Smacallan    int          xdir,
161a6b33934Smacallan    int          ydir,
162a6b33934Smacallan    int          rop,
163a6b33934Smacallan    unsigned int planemask,
164a6b33934Smacallan    int          TransparencyColour
165a6b33934Smacallan)
166a6b33934Smacallan{
167a6b33934Smacallan    PnozzPtr pPnozz = GET_PNOZZ_FROM_SCRN(pScrn);
168a6b33934Smacallan    PnozzSync(pScrn);
169a6b33934Smacallan
170a6b33934Smacallan    pnozz_write_4(pPnozz, RASTER_OP, (PnozzCopyROP[rop] & 0xff));
171a6b33934Smacallan    pnozz_write_4(pPnozz, PLANE_MASK, planemask);
172a6b33934Smacallan}
173a6b33934Smacallan
174a6b33934Smacallan/*
175a6b33934Smacallan * the drawing engine is weird. Even though BLIT and QUAD commands use the
176a6b33934Smacallan * same registers to program coordinates there's an important difference -
177a6b33934Smacallan * horizontal coordinates for QUAD commands are in pixels, for BLIT commands
178a6b33934Smacallan * and the byte clipping registers they're IN BYTES.
179a6b33934Smacallan */
180a6b33934Smacallanstatic void
181a6b33934SmacallanPnozzSubsequentScreenToScreenCopy
182a6b33934Smacallan(
183a6b33934Smacallan    ScrnInfoPtr pScrn,
184a6b33934Smacallan    int         xSrc,
185a6b33934Smacallan    int         ySrc,
186a6b33934Smacallan    int         xDst,
187a6b33934Smacallan    int         yDst,
188a6b33934Smacallan    int         w,
189a6b33934Smacallan    int         h
190a6b33934Smacallan)
191a6b33934Smacallan{
192a6b33934Smacallan    PnozzPtr pPnozz = GET_PNOZZ_FROM_SCRN(pScrn);
193a6b33934Smacallan    CARD32 src, dst, srcw, dstw;
194a6b33934Smacallan
195a6b33934Smacallan    src = (((xSrc << pPnozz->depthshift) & 0x1fff) << 16) | (ySrc & 0x1fff);
196a6b33934Smacallan    dst = (((xDst << pPnozz->depthshift) & 0x1fff) << 16) | (yDst & 0x1fff);
197a6b33934Smacallan    srcw = ((((xSrc + w) << pPnozz->depthshift) - 1) << 16) |
198a6b33934Smacallan        ((ySrc + h - 1) & 0x1fff);
199a6b33934Smacallan    dstw = ((((xDst + w) << pPnozz->depthshift) - 1) << 16) |
200a6b33934Smacallan        ((yDst + h - 1) & 0x1fff);
201a6b33934Smacallan
202a6b33934Smacallan    PnozzSync(pScrn);
203a6b33934Smacallan
204a6b33934Smacallan    pnozz_write_4(pPnozz, ABS_XY0, src);
205a6b33934Smacallan    pnozz_write_4(pPnozz, ABS_XY1, srcw);
206a6b33934Smacallan    pnozz_write_4(pPnozz, ABS_XY2, dst);
207a6b33934Smacallan    pnozz_write_4(pPnozz, ABS_XY3, dstw);
208a6b33934Smacallan    junk = pnozz_read_4(pPnozz, COMMAND_BLIT);
209a6b33934Smacallan}
210a6b33934Smacallan
211a6b33934Smacallanstatic void
212a6b33934SmacallanPnozzSetupForSolidFill
213a6b33934Smacallan(
214a6b33934Smacallan    ScrnInfoPtr  pScrn,
215a6b33934Smacallan    int          colour,
216a6b33934Smacallan    int          rop,
217a6b33934Smacallan    unsigned int planemask
218a6b33934Smacallan)
219a6b33934Smacallan{
220a6b33934Smacallan    PnozzPtr pPnozz = GET_PNOZZ_FROM_SCRN(pScrn);
221a6b33934Smacallan    CARD32 c2;
222a6b33934Smacallan
223a6b33934Smacallan    PnozzSync(pScrn);
224a6b33934Smacallan
225a6b33934Smacallan    pnozz_write_colour(pPnozz, FOREGROUND_COLOR, colour);
226a6b33934Smacallan    pnozz_write_4(pPnozz, RASTER_OP, PnozzDrawROP[rop] & 0xff);
227a6b33934Smacallan    pnozz_write_4(pPnozz, PLANE_MASK, planemask);
228a6b33934Smacallan    pnozz_write_4(pPnozz, COORD_INDEX, 0);
229a6b33934Smacallan}
230a6b33934Smacallan
231a6b33934Smacallanstatic void
232a6b33934SmacallanPnozzSubsequentSolidFillRect
233a6b33934Smacallan(
234a6b33934Smacallan    ScrnInfoPtr pScrn,
235a6b33934Smacallan    int         x,
236a6b33934Smacallan    int         y,
237a6b33934Smacallan    int         w,
238a6b33934Smacallan    int         h
239a6b33934Smacallan)
240a6b33934Smacallan{
241a6b33934Smacallan    PnozzPtr pPnozz = GET_PNOZZ_FROM_SCRN(pScrn);
242a6b33934Smacallan
243a6b33934Smacallan    PnozzSync(pScrn);
244a6b33934Smacallan    pnozz_write_4(pPnozz, RECT_RTW_XY, ((x & 0x1fff) << 16) |
245a6b33934Smacallan        (y & 0x1fff));
246a6b33934Smacallan    pnozz_write_4(pPnozz, RECT_RTP_XY, (((w & 0x1fff) << 16) |
247a6b33934Smacallan        (h & 0x1fff)));
248a6b33934Smacallan    junk = pnozz_read_4(pPnozz, COMMAND_QUAD);
249a6b33934Smacallan}
250a6b33934Smacallan
251f55eacdeSjdc#ifdef HAVE_XAA_H
252f55eacdeSjdc
253a6b33934Smacallanstatic void
254a6b33934SmacallanPnozzSetupForCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
255a6b33934Smacallan        		int fg, int bg,
256a6b33934Smacallan			int rop,
257a6b33934Smacallan			unsigned int planemask)
258a6b33934Smacallan{
259a6b33934Smacallan    PnozzPtr pPnozz = GET_PNOZZ_FROM_SCRN(pScrn);
260a6b33934Smacallan
261a6b33934Smacallan    PnozzSync(pScrn);
262a6b33934Smacallan
263a6b33934Smacallan    if (bg == -1) {
264a6b33934Smacallan    	/* transparent */
265a6b33934Smacallan	pnozz_write_colour(pPnozz, FOREGROUND_COLOR, fg);
266a6b33934Smacallan	pnozz_write_4(pPnozz, RASTER_OP, PnozzDrawROP[rop] | ROP_PIX1_TRANS);
267a6b33934Smacallan    } else {
268a6b33934Smacallan	/*
269a6b33934Smacallan	 * this doesn't make any sense to me either, but for some reason the
270a6b33934Smacallan	 * chip applies the foreground colour to 0 pixels and background to 1
271a6b33934Smacallan	 * when set to this sort of ROP. The old XF 3.3 driver source claimed
272a6b33934Smacallan	 * that the chip doesn't support opaque colour expansion at all.
273a6b33934Smacallan	 */
274a6b33934Smacallan	pnozz_write_colour(pPnozz, FOREGROUND_COLOR, bg);
275a6b33934Smacallan	pnozz_write_colour(pPnozz, BACKGROUND_COLOR, fg);
276a6b33934Smacallan
277a6b33934Smacallan	pnozz_write_4(pPnozz, RASTER_OP, PnozzCopyROP[rop] & 0xff);
278a6b33934Smacallan    }
279a6b33934Smacallan
280a6b33934Smacallan    pnozz_write_4(pPnozz, PLANE_MASK, planemask);
281a6b33934Smacallan    pnozz_write_4(pPnozz, COORD_INDEX, 0);
282a6b33934Smacallan}
283a6b33934Smacallan
284a6b33934Smacallanstatic void
285a6b33934SmacallanPnozzSubsequentScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
286a6b33934Smacallan			int x, int y, int w, int h,
287a6b33934Smacallan			int skipleft )
288a6b33934Smacallan{
289a6b33934Smacallan    PnozzPtr pPnozz = GET_PNOZZ_FROM_SCRN(pScrn);
290a6b33934Smacallan    CARD32 rest = w & 0x1f;
291a6b33934Smacallan
292a6b33934Smacallan    pnozz_write_4(pPnozz, ABS_X0, x);
293a6b33934Smacallan    pnozz_write_4(pPnozz, ABS_XY1, (x << 16) | (y & 0xFFFFL));
294a6b33934Smacallan    pnozz_write_4(pPnozz, ABS_X2, (x + w));
295a6b33934Smacallan    pnozz_write_4(pPnozz, ABS_Y3, 1);
296a6b33934Smacallan
297a6b33934Smacallan    pPnozz->words = (w >> 5);	/* whole words to write */
298a6b33934Smacallan
299a6b33934Smacallan    if (rest > 0) {
300a6b33934Smacallan    	pPnozz->last_word = (rest - 1) << 2;
301a6b33934Smacallan    } else
302a6b33934Smacallan    	pPnozz->last_word = -1;
303a6b33934Smacallan}
304a6b33934Smacallan
305a6b33934Smacallanstatic void
306a6b33934SmacallanPnozzSubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno)
307a6b33934Smacallan{
308a6b33934Smacallan    PnozzPtr pPnozz = GET_PNOZZ_FROM_SCRN(pScrn);
309a6b33934Smacallan#define PIXEL_1_FULL (PIXEL_1 + (31 << 2))
310a6b33934Smacallan    CARD32 *buf;
311a6b33934Smacallan    volatile CARD32 *pix = ((volatile CARD32 *)(pPnozz->fbc + PIXEL_1_FULL));
312a6b33934Smacallan    int i = 0;
313a6b33934Smacallan
314a6b33934Smacallan    PnozzSync(pScrn);
315a6b33934Smacallan    buf = (CARD32 *)pPnozz->buffers[bufno];
316a6b33934Smacallan    junk = *(volatile CARD32 *)(pPnozz->fb + PIXEL_1_FULL);
317a6b33934Smacallan    for (i = 0; i < pPnozz->words; i++)
318a6b33934Smacallan	*pix = buf[i];
319a6b33934Smacallan    if (pPnozz->last_word >= 0)
320a6b33934Smacallan    	*(volatile CARD32 *)(pPnozz->fbc + PIXEL_1 + pPnozz->last_word) =
321a6b33934Smacallan    	    buf[i];
322a6b33934Smacallan}
323a6b33934Smacallan
324a6b33934Smacallanstatic void
325a6b33934SmacallanPnozzSetupForSolidLine(ScrnInfoPtr pScrn, int color, int rop,
326a6b33934Smacallan    unsigned int planemask)
327a6b33934Smacallan{
328a6b33934Smacallan    PnozzPtr pPnozz = GET_PNOZZ_FROM_SCRN(pScrn);
329a6b33934Smacallan
330a6b33934Smacallan    PnozzSync(pScrn);
331a6b33934Smacallan
332a6b33934Smacallan    pnozz_write_colour(pPnozz, FOREGROUND_COLOR, color);
333a6b33934Smacallan    pnozz_write_4(pPnozz, RASTER_OP, (PnozzDrawROP[rop] & 0xff) | ROP_OVERSIZE);
334a6b33934Smacallan
335a6b33934Smacallan    pnozz_write_4(pPnozz, PLANE_MASK, planemask);
336a6b33934Smacallan    pnozz_write_4(pPnozz, COORD_INDEX, 0);
337a6b33934Smacallan
338a6b33934Smacallan}
339a6b33934Smacallan
340a6b33934Smacallanstatic void
341a6b33934SmacallanPnozzSubsequentSolidTwoPointLine(ScrnInfoPtr pScrn, int x1, int y1, int x2,
342a6b33934Smacallan    int y2, int flags)
343a6b33934Smacallan{
344a6b33934Smacallan    PnozzPtr pPnozz = GET_PNOZZ_FROM_SCRN(pScrn);
345a6b33934Smacallan
346a6b33934Smacallan    PnozzSync(pScrn);
347a6b33934Smacallan
348a6b33934Smacallan    /*
349a6b33934Smacallan     * XXX we're blatantly ignoring the flags parameter which could tell us not
350a6b33934Smacallan     * to draw the last point. Xsun simply reads it from the framebuffer and
351a6b33934Smacallan     * puts it back after drawing the line but that would mean we have to wait
352a6b33934Smacallan     * until the line is actually drawn. On the other hand - line drawing is
353a6b33934Smacallan     * pretty fast so we won't lose too much speed
354a6b33934Smacallan     */
355a6b33934Smacallan    pnozz_write_4(pPnozz, LINE_RTW_XY, (x1 << 16) | y1);
356a6b33934Smacallan    pnozz_write_4(pPnozz, LINE_RTW_XY, (x2 << 16) | y2);
357a6b33934Smacallan    junk = pnozz_read_4(pPnozz, COMMAND_QUAD);
358a6b33934Smacallan}
359a6b33934Smacallan
360a6b33934Smacallanstatic void
361a6b33934SmacallanPnozzSetupForMono8x8PatternFill(ScrnInfoPtr pScrn, int pat0, int pat1,
362a6b33934Smacallan        int fg, int bg, int rop, unsigned int planemask)
363a6b33934Smacallan{
364a6b33934Smacallan    PnozzPtr pPnozz = GET_PNOZZ_FROM_SCRN(pScrn);
365a6b33934Smacallan    CARD32 pat;
366a6b33934Smacallan
367a6b33934Smacallan    PnozzSync(pScrn);
368a6b33934Smacallan
369a6b33934Smacallan    if (bg == -1) {
370a6b33934Smacallan	pnozz_write_4(pPnozz, RASTER_OP,
371a6b33934Smacallan	    (PnozzDrawROP[rop] & 0xff) | ROP_NO_SOLID | ROP_TRANS);
372a6b33934Smacallan    } else {
373a6b33934Smacallan        pnozz_write_colour(pPnozz, COLOR_0, bg);
374a6b33934Smacallan        pnozz_write_4(pPnozz, RASTER_OP,
375a6b33934Smacallan            (PnozzDrawROP[rop] & 0xff) | ROP_NO_SOLID);
376a6b33934Smacallan    }
377a6b33934Smacallan    pnozz_write_colour(pPnozz, COLOR_1, fg);
378a6b33934Smacallan    pnozz_write_4(pPnozz, PLANE_MASK, planemask);
379a6b33934Smacallan    pat = (pat0 & 0xff000000) | ((pat0 >> 8) & 0x00ffff00) |
380a6b33934Smacallan        ((pat0 >> 16) & 0x000000ff);
381a6b33934Smacallan    pnozz_write_4(pPnozz, PATTERN0, pat);
382a6b33934Smacallan    pat = ((pat0 << 8) & 0x00ffff00) | ((pat0 << 16) & 0xff000000) |
383a6b33934Smacallan        (pat0 & 0x000000ff);
384a6b33934Smacallan    pnozz_write_4(pPnozz, PATTERN1, pat);
385a6b33934Smacallan    pat = (pat1 & 0xff000000) | ((pat1 >> 8) & 0x00ffff00) |
386a6b33934Smacallan        ((pat1 >> 16) & 0x000000ff);
387a6b33934Smacallan    pnozz_write_4(pPnozz, PATTERN2, pat);
388a6b33934Smacallan    pat = ((pat1 << 8) & 0x00ffff00) | ((pat1 << 16) & 0xff000000) |
389a6b33934Smacallan        (pat1 & 0x000000ff);
390a6b33934Smacallan    pnozz_write_4(pPnozz, PATTERN3, pat);
391a6b33934Smacallan    pnozz_write_4(pPnozz, COORD_INDEX, 0);
392a6b33934Smacallan}
393a6b33934Smacallan
394a6b33934Smacallanstatic void
395a6b33934SmacallanPnozzSubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn,
396a6b33934Smacallan        	int patx, int paty, int x, int y, int w, int h)
397a6b33934Smacallan{
398a6b33934Smacallan    PnozzPtr pPnozz = GET_PNOZZ_FROM_SCRN(pScrn);
399a6b33934Smacallan
400a6b33934Smacallan    PnozzSync(pScrn);
401a6b33934Smacallan    pnozz_write_4(pPnozz, PATTERN_ORIGIN_X, patx);
402a6b33934Smacallan    pnozz_write_4(pPnozz, PATTERN_ORIGIN_Y, paty);
403a6b33934Smacallan    pnozz_write_4(pPnozz, RECT_RTW_XY, ((x & 0x1fff) << 16) |
404a6b33934Smacallan        (y & 0x1fff));
405a6b33934Smacallan    pnozz_write_4(pPnozz, RECT_RTP_XY, (((w & 0x1fff) << 16) |
406a6b33934Smacallan        (h & 0x1fff)));
407a6b33934Smacallan    junk = pnozz_read_4(pPnozz, COMMAND_QUAD);
408a6b33934Smacallan
409a6b33934Smacallan}
410a6b33934Smacallan
411a6b33934Smacallanstatic void
412a6b33934SmacallanPnozzSetClippingRectangle(ScrnInfoPtr pScrn, int left, int top, int right,
413a6b33934Smacallan			 int bottom)
414a6b33934Smacallan{
415a6b33934Smacallan    PnozzPtr pPnozz = GET_PNOZZ_FROM_SCRN(pScrn);
416a6b33934Smacallan    CARD32 cmin, cmax;
417a6b33934Smacallan
418a6b33934Smacallan    cmin = (left << 16) | top;
419a6b33934Smacallan    cmax = (right << 16) | bottom;
420a6b33934Smacallan
421a6b33934Smacallan    pnozz_write_4(pPnozz, WINDOW_MIN, cmin);
422a6b33934Smacallan    pnozz_write_4(pPnozz, WINDOW_MAX, cmax);
423a6b33934Smacallan
424a6b33934Smacallan    cmin = ((left << pPnozz->depthshift) << 16) | top;
425a6b33934Smacallan    cmax = ((right << pPnozz->depthshift) << 16) | bottom;
426a6b33934Smacallan
427a6b33934Smacallan    pnozz_write_4(pPnozz, BYTE_CLIP_MIN, cmin);
428a6b33934Smacallan    pnozz_write_4(pPnozz, BYTE_CLIP_MAX, cmax);
429a6b33934Smacallan}
430a6b33934Smacallan
431a6b33934Smacallanstatic void
432a6b33934SmacallanPnozzDisableClipping(ScrnInfoPtr pScrn)
433a6b33934Smacallan{
434a6b33934Smacallan    PnozzPtr pPnozz = GET_PNOZZ_FROM_SCRN(pScrn);
435a6b33934Smacallan
436a6b33934Smacallan    pnozz_write_4(pPnozz, WINDOW_MIN, 0);
437a6b33934Smacallan    pnozz_write_4(pPnozz, WINDOW_MAX, MaxClip);
438a6b33934Smacallan    pnozz_write_4(pPnozz, BYTE_CLIP_MIN, 0);
439a6b33934Smacallan    pnozz_write_4(pPnozz, BYTE_CLIP_MAX, MaxClip);
440a6b33934Smacallan}
441a6b33934Smacallan
442a6b33934Smacallanstatic void
443a6b33934SmacallanPnozzSetupForImageWrite(ScrnInfoPtr pScrn, int rop, unsigned int planemask,
444a6b33934Smacallan  int trans_color, int depth, int bpp)
445a6b33934Smacallan{
446a6b33934Smacallan    PnozzPtr pPnozz = GET_PNOZZ_FROM_SCRN(pScrn);
447a6b33934Smacallan
448a6b33934Smacallan    pnozz_write_4(pPnozz, RASTER_OP, PnozzCopyROP[rop] & 0xff);
449a6b33934Smacallan    pnozz_write_4(pPnozz, PLANE_MASK, planemask);
450a6b33934Smacallan    pnozz_write_4(pPnozz, COORD_INDEX, 0);
451a6b33934Smacallan
452b52812cdSchristos    xf86Msg(X_ERROR, "setup for image write\n");
453a6b33934Smacallan}
454a6b33934Smacallan
455a6b33934Smacallanstatic void
456a6b33934SmacallanPnozzImageWriteRect(ScrnInfoPtr pScrn, int x, int y, int wi, int he, int skip)
457a6b33934Smacallan{
458a6b33934Smacallan    PnozzPtr pPnozz = GET_PNOZZ_FROM_SCRN(pScrn);
459a6b33934Smacallan    volatile CARD32 junk;
460a6b33934Smacallan
461a6b33934Smacallan    pnozz_write_4(pPnozz, ABS_X0, x);
462a6b33934Smacallan    pnozz_write_4(pPnozz, ABS_XY1, (x << 16) | y);
463a6b33934Smacallan    pnozz_write_4(pPnozz, ABS_X2, x + wi);
464a6b33934Smacallan    pnozz_write_4(pPnozz, ABS_Y3, 1);
465a6b33934Smacallan    junk = *(volatile CARD32 *)(pPnozz->fb + PIXEL_8);
466a6b33934Smacallan}
467a6b33934Smacallan
468a6b33934Smacallan/*
469a6b33934Smacallan * TODO:
470a6b33934Smacallan * - CPU to VRAM colour blits
471a6b33934Smacallan */
472a6b33934Smacallan
473a6b33934Smacallanint
474a6b33934SmacallanPnozzAccelInit(ScrnInfoPtr pScrn)
475a6b33934Smacallan{
476a6b33934Smacallan    PnozzPtr pPnozz = GET_PNOZZ_FROM_SCRN(pScrn);
477a6b33934Smacallan    XAAInfoRecPtr pXAAInfo = pPnozz->pXAA;
478a6b33934Smacallan
479a6b33934Smacallan    pXAAInfo->Flags = LINEAR_FRAMEBUFFER | PIXMAP_CACHE | OFFSCREEN_PIXMAPS;
480a6b33934Smacallan    pXAAInfo->maxOffPixWidth = pPnozz->width;
481a6b33934Smacallan    pXAAInfo->maxOffPixHeight = pPnozz->maxheight;
482a6b33934Smacallan    MaxClip = ((pPnozz->scanlinesize & 0xffff) << 16) | (pPnozz->maxheight);
483a6b33934Smacallan
484a6b33934Smacallan    PnozzInitEngine(pPnozz);
485a6b33934Smacallan
486a6b33934Smacallan#if 1
487a6b33934Smacallan    {
488a6b33934Smacallan	CARD32 src, srcw, junk;
489a6b33934Smacallan	src = 0;
490a6b33934Smacallan	srcw = pPnozz->width << 16 | pPnozz->height;
491a6b33934Smacallan
492a6b33934Smacallan	/* Blit the screen black. For aesthetic reasons. */
493a6b33934Smacallan
494a6b33934Smacallan	PnozzSync(pScrn);
495a6b33934Smacallan	pnozz_write_4(pPnozz, FOREGROUND_COLOR, 0x00000000);
496a6b33934Smacallan	pnozz_write_4(pPnozz, BACKGROUND_COLOR, 0xffffffff);
497a6b33934Smacallan	pnozz_write_4(pPnozz, RASTER_OP, ROP_PAT);
498a6b33934Smacallan	pnozz_write_4(pPnozz, COORD_INDEX, 0);
499a6b33934Smacallan	pnozz_write_4(pPnozz, RECT_RTW_XY, src);
500a6b33934Smacallan	pnozz_write_4(pPnozz, RECT_RTW_XY, srcw);
501a6b33934Smacallan	junk = pnozz_read_4(pPnozz, COMMAND_QUAD);
502a6b33934Smacallan	PnozzSync(pScrn);
503a6b33934Smacallan    }
504a6b33934Smacallan#endif
505a6b33934Smacallan
506a6b33934Smacallan    /* Sync */
507a6b33934Smacallan    pXAAInfo->Sync = PnozzSync;
508a6b33934Smacallan
509a6b33934Smacallan    /* Screen-to-screen copy */
510a6b33934Smacallan    pXAAInfo->ScreenToScreenCopyFlags = NO_TRANSPARENCY;
511a6b33934Smacallan    pXAAInfo->SetupForScreenToScreenCopy = PnozzSetupForScreenToScreenCopy;
512a6b33934Smacallan    pXAAInfo->SubsequentScreenToScreenCopy =
513a6b33934Smacallan        PnozzSubsequentScreenToScreenCopy;
514a6b33934Smacallan
515a6b33934Smacallan    /* Solid fills */
516a6b33934Smacallan    pXAAInfo->SetupForSolidFill = PnozzSetupForSolidFill;
517a6b33934Smacallan    pXAAInfo->SubsequentSolidFillRect = PnozzSubsequentSolidFillRect;
518a6b33934Smacallan
519a6b33934Smacallan    /* colour expansion */
520a6b33934Smacallan    pXAAInfo->ScanlineCPUToScreenColorExpandFillFlags =
521a6b33934Smacallan	/*LEFT_EDGE_CLIPPING|*/SCANLINE_PAD_DWORD;
522a6b33934Smacallan    pXAAInfo->NumScanlineColorExpandBuffers = 2;
523a6b33934Smacallan    pPnozz->buffers[0] = (unsigned char *)pPnozz->Buffer;
524a6b33934Smacallan    pPnozz->buffers[1] = (unsigned char *)&pPnozz->Buffer[pPnozz->scanlinesize];
525a6b33934Smacallan    pXAAInfo->ScanlineColorExpandBuffers = pPnozz->buffers;
526a6b33934Smacallan    pXAAInfo->SetupForScanlineCPUToScreenColorExpandFill =
527a6b33934Smacallan	PnozzSetupForCPUToScreenColorExpandFill;
528a6b33934Smacallan    pXAAInfo->SubsequentScanlineCPUToScreenColorExpandFill =
529a6b33934Smacallan	PnozzSubsequentScanlineCPUToScreenColorExpandFill;
530a6b33934Smacallan    pXAAInfo->SubsequentColorExpandScanline =
531a6b33934Smacallan	PnozzSubsequentColorExpandScanline;
532a6b33934Smacallan
533a6b33934Smacallan    /* line drawing */
534a6b33934Smacallan    pXAAInfo->SetupForSolidLine = PnozzSetupForSolidLine;
535a6b33934Smacallan    pXAAInfo->SubsequentSolidTwoPointLine = PnozzSubsequentSolidTwoPointLine;
536a6b33934Smacallan    pXAAInfo->SolidLineFlags = BIT_ORDER_IN_BYTE_MSBFIRST;
537a6b33934Smacallan
538a6b33934Smacallan    /* clipping */
539a6b33934Smacallan    pXAAInfo->SetClippingRectangle = PnozzSetClippingRectangle;
540a6b33934Smacallan    pXAAInfo->DisableClipping = PnozzDisableClipping;
541a6b33934Smacallan    pXAAInfo->ClippingFlags = HARDWARE_CLIP_SCREEN_TO_SCREEN_COPY |
542a6b33934Smacallan        HARDWARE_CLIP_SOLID_FILL |
543a6b33934Smacallan        HARDWARE_CLIP_MONO_8x8_FILL |
544a6b33934Smacallan        /*HARDWARE_CLIP_COLOR_8x8_FILL |*/
545a6b33934Smacallan        HARDWARE_CLIP_SOLID_LINE;
546a6b33934Smacallan
547a6b33934Smacallan    /* 8x8 mono pattern fills */
548a6b33934Smacallan    pXAAInfo->Mono8x8PatternFillFlags = HARDWARE_PATTERN_PROGRAMMED_BITS |
549a6b33934Smacallan        HARDWARE_PATTERN_SCREEN_ORIGIN | HARDWARE_PATTERN_PROGRAMMED_ORIGIN;
550a6b33934Smacallan    pXAAInfo->SetupForMono8x8PatternFill = PnozzSetupForMono8x8PatternFill;
551a6b33934Smacallan    pXAAInfo->SubsequentMono8x8PatternFillRect =
552a6b33934Smacallan        PnozzSubsequentMono8x8PatternFillRect;
553a6b33934Smacallan
554a6b33934Smacallan    /* image uploads */
555a6b33934Smacallan    pXAAInfo->ImageWriteBase = pPnozz->fbc + PIXEL_8;
556a6b33934Smacallan    pXAAInfo->ImageWriteRange = 4;
557a6b33934Smacallan    pXAAInfo->ImageWriteFlags = /*CPU_TRANSFER_BASE_FIXED |*/ CPU_TRANSFER_PAD_DWORD |
558a6b33934Smacallan        NO_TRANSPARENCY;
559a6b33934Smacallan    pXAAInfo->SetupForImageWrite = PnozzSetupForImageWrite;
560a6b33934Smacallan    pXAAInfo->SubsequentImageWriteRect = PnozzImageWriteRect;
561a6b33934Smacallan
562a6b33934Smacallan    return 0;
563a6b33934Smacallan}
564f55eacdeSjdc
565f55eacdeSjdc#endif /* HAVE_XAA_H */
566f55eacdeSjdc
567f55eacdeSjdcBool
568f55eacdeSjdcPnozzDGAInit(ScreenPtr pScreen)
569f55eacdeSjdc{
570f55eacdeSjdc    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
571f55eacdeSjdc    PnozzPtr pPnozz = GET_PNOZZ_FROM_SCRN(pScrn);
572f55eacdeSjdc    DGAModePtr mode;
573f55eacdeSjdc    int result;
574f55eacdeSjdc
575f55eacdeSjdc    mode = xnfcalloc(sizeof(DGAModeRec), 1);
576f55eacdeSjdc    if (mode == NULL) {
577f55eacdeSjdc        xf86Msg(X_WARNING, "%s: DGA setup failed, cannot allocate memory\n",
578f55eacdeSjdc            pPnozz->psdp->device);
579f55eacdeSjdc        return FALSE;
580f55eacdeSjdc    }
581f55eacdeSjdc
582f55eacdeSjdc    mode->mode = pScrn->modes;
583f55eacdeSjdc    mode->flags = DGA_PIXMAP_AVAILABLE | DGA_CONCURRENT_ACCESS;
584f55eacdeSjdc    if(!pPnozz->NoAccel) {
585f55eacdeSjdc        mode->flags |= DGA_FILL_RECT | DGA_BLIT_RECT;
586f55eacdeSjdc    }
587f55eacdeSjdc
588f55eacdeSjdc    mode->imageWidth = mode->pixmapWidth = mode->viewportWidth =
589f55eacdeSjdc	pScrn->virtualX;
590f55eacdeSjdc    mode->imageHeight = mode->pixmapHeight = mode->viewportHeight =
591f55eacdeSjdc	pScrn->virtualY;
592f55eacdeSjdc
593f55eacdeSjdc    mode->bytesPerScanline = mode->imageWidth;
594f55eacdeSjdc
595f55eacdeSjdc    mode->byteOrder = pScrn->imageByteOrder;
596f55eacdeSjdc    mode->depth = 8;
597f55eacdeSjdc    mode->bitsPerPixel = 8;
598f55eacdeSjdc    mode->red_mask = pScrn->mask.red;
599f55eacdeSjdc    mode->green_mask = pScrn->mask.green;
600f55eacdeSjdc    mode->blue_mask = pScrn->mask.blue;
601f55eacdeSjdc
602f55eacdeSjdc    mode->visualClass = PseudoColor;
603f55eacdeSjdc    mode->address = pPnozz->fb;
604f55eacdeSjdc
605f55eacdeSjdc    result = DGAInit(pScreen, &Pnozz_DGAFuncs, mode, 1);
606f55eacdeSjdc
607f55eacdeSjdc    if (result) {
608f55eacdeSjdc	xf86Msg(X_INFO, "%s: DGA initialized\n",
609f55eacdeSjdc            pPnozz->psdp->device);
610f55eacdeSjdc	return TRUE;
611f55eacdeSjdc    } else {
612f55eacdeSjdc	xf86Msg(X_WARNING, "%s: DGA setup failed\n",
613f55eacdeSjdc            pPnozz->psdp->device);
614f55eacdeSjdc	return FALSE;
615f55eacdeSjdc    }
616f55eacdeSjdc}
617f55eacdeSjdc
618f55eacdeSjdcstatic Bool
619f55eacdeSjdcPnozz_OpenFramebuffer(ScrnInfoPtr pScrn, char **name,
620f55eacdeSjdc				unsigned char **mem,
621f55eacdeSjdc				int *size, int *offset,
622f55eacdeSjdc				int *extra)
623f55eacdeSjdc{
624f55eacdeSjdc    PnozzPtr pPnozz = GET_PNOZZ_FROM_SCRN(pScrn);
625f55eacdeSjdc
626f55eacdeSjdc    *name = pPnozz->psdp->device;
627f55eacdeSjdc
628f55eacdeSjdc    *mem = (unsigned char*)0;
629f55eacdeSjdc    *size = pPnozz->vidmem;
630f55eacdeSjdc    *offset = 0;
631f55eacdeSjdc    *extra = 0;
632f55eacdeSjdc
633f55eacdeSjdc    return TRUE;
634f55eacdeSjdc}
635f55eacdeSjdc
636f55eacdeSjdcstatic Bool
637f55eacdeSjdcPnozz_SetMode(ScrnInfoPtr pScrn, DGAModePtr pMode)
638f55eacdeSjdc{
639f55eacdeSjdc    /*
640f55eacdeSjdc     * Nothing to do, we currently only support one mode
641f55eacdeSjdc     * and we are always in it.
642f55eacdeSjdc     */
643f55eacdeSjdc    return TRUE;
644f55eacdeSjdc}
645f55eacdeSjdc
646f55eacdeSjdcstatic void
647f55eacdeSjdcPnozz_SetViewport(ScrnInfoPtr pScrn, int x, int y, int flags)
648f55eacdeSjdc{
649f55eacdeSjdc     /* We don't support viewports, so... */
650f55eacdeSjdc}
651f55eacdeSjdc
652f55eacdeSjdcstatic int
653f55eacdeSjdcPnozz_GetViewport(ScrnInfoPtr pScrn)
654f55eacdeSjdc{
655f55eacdeSjdc    /* No viewports, none pending... */
656f55eacdeSjdc    return 0;
657f55eacdeSjdc}
658f55eacdeSjdc
659f55eacdeSjdcstatic void
660f55eacdeSjdcPnozz_FillRect(ScrnInfoPtr pScrn, int x, int y, int w, int h, unsigned long color)
661f55eacdeSjdc{
662f55eacdeSjdc
663f55eacdeSjdc    PnozzSetupForSolidFill(pScrn, color, GXset, 8);
664f55eacdeSjdc    PnozzSubsequentSolidFillRect(pScrn, x, y, w, h);
665f55eacdeSjdc}
666f55eacdeSjdc
667f55eacdeSjdcstatic void
668f55eacdeSjdcPnozz_BlitRect(ScrnInfoPtr pScrn, int srcx, int srcy,
669f55eacdeSjdc			 int w, int h, int dstx, int dsty)
670f55eacdeSjdc{
671f55eacdeSjdc
672f55eacdeSjdc    PnozzSetupForScreenToScreenCopy(pScrn, 0, 0, GXcopy, 8, 0);
673f55eacdeSjdc    PnozzSubsequentScreenToScreenCopy(pScrn, srcx, srcy, dstx, dsty, w, h);
674f55eacdeSjdc}
675