summit_accel.c revision ea396379
1/*
2 * hardware acceleration for Visualize FX 4
3 *
4 * Copyright (C) 2024 Michael Lorenz
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19 * MICHAEL LORENZ BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
20 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 */
23
24/* $NetBSD: summit_accel.c,v 1.2 2024/12/25 05:45:53 macallan Exp $ */
25
26#include <sys/types.h>
27#include <dev/ic/summitreg.h>
28
29
30#include "ngle.h"
31
32//#define DEBUG
33
34#ifdef DEBUG
35#define ENTER xf86Msg(X_ERROR, "%s\n", __func__)
36#define LEAVE xf86Msg(X_ERROR, "%s done\n", __func__)
37#define DBGMSG xf86Msg
38#else
39#define ENTER
40#define DBGMSG if (0) xf86Msg
41#define LEAVE
42#endif
43
44static void
45SummitWaitMarker(ScreenPtr pScreen, int Marker)
46{
47	ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
48	NGLEPtr fPtr = NGLEPTR(pScrn);
49	int bail = 10000000, reg;
50
51	ENTER;
52	do {
53		reg = NGLERead4(fPtr, VISFX_STATUS);
54		bail--;
55		if (bail == 0) {
56			xf86Msg(X_ERROR, "%s status %08x\n", __func__, reg);
57			return;
58		}
59	} while (reg != 0);
60	LEAVE;
61}
62
63static Bool
64SummitPrepareCopy
65(
66    PixmapPtr pSrcPixmap,
67    PixmapPtr pDstPixmap,
68    int       xdir,
69    int       ydir,
70    int       alu,
71    Pixel     planemask
72)
73{
74	ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum];
75	NGLEPtr fPtr = NGLEPTR(pScrn);
76	int srcpitch = exaGetPixmapPitch(pSrcPixmap);
77	int srcoff = exaGetPixmapOffset(pSrcPixmap);
78
79	ENTER;
80
81	DBGMSG(X_ERROR, "%s %d %d\n", __func__, srcoff, srcpitch);
82	if (alu != GXcopy) return FALSE;
83	fPtr->offset = srcoff / srcpitch;
84	if (fPtr->hwmode != HW_BLIT) {
85		SummitWaitMarker(pSrcPixmap->drawable.pScreen, 0);
86		NGLEWrite4(fPtr, VISFX_VRAM_WRITE_MODE, OTC01 | BIN8F | BUFFL);
87		NGLEWrite4(fPtr, VISFX_VRAM_READ_MODE, OTC01 | BIN8F | BUFFL);
88		fPtr->hwmode = HW_BLIT;
89	}
90	NGLEWrite4(fPtr, VISFX_PLANE_MASK, planemask);
91	LEAVE;
92	return TRUE;
93}
94
95static void
96SummitCopy
97(
98    PixmapPtr pDstPixmap,
99    int       xs,
100    int       ys,
101    int       xd,
102    int       yd,
103    int       wi,
104    int       he
105)
106{
107	ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum];
108	NGLEPtr fPtr = NGLEPTR(pScrn);
109	int dstpitch = exaGetPixmapPitch(pDstPixmap);
110	int dstoff = exaGetPixmapOffset(pDstPixmap);
111
112	ENTER;
113	SummitWaitMarker(pDstPixmap->drawable.pScreen, 0);
114	NGLEWrite4(fPtr, VISFX_COPY_SRC, (xs << 16) | (ys + fPtr->offset));
115	NGLEWrite4(fPtr, VISFX_COPY_WH, (wi << 16) | he);
116	NGLEWrite4(fPtr, VISFX_COPY_DST, (xd << 16) | (yd + (dstoff / dstpitch)));
117
118	exaMarkSync(pDstPixmap->drawable.pScreen);
119	LEAVE;
120}
121
122static void
123SummitDoneCopy(PixmapPtr pDstPixmap)
124{
125    ENTER;
126    LEAVE;
127}
128
129static Bool
130SummitPrepareSolid(
131    PixmapPtr pPixmap,
132    int alu,
133    Pixel planemask,
134    Pixel fg)
135{
136	ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
137	NGLEPtr fPtr = NGLEPTR(pScrn);
138
139	ENTER;
140	if (alu != GXcopy) return FALSE;
141	if (fPtr->hwmode != HW_FILL) {
142		SummitWaitMarker(pPixmap->drawable.pScreen, 0);
143		NGLEWrite4(fPtr, VISFX_VRAM_WRITE_MODE, OTC32 | BIN8F | BUFFL | 0x8c0);
144		fPtr->hwmode = HW_FILL;
145	}
146	NGLEWrite4(fPtr, VISFX_FG_COLOUR, fg);
147	NGLEWrite4(fPtr, VISFX_PLANE_MASK, planemask);
148	LEAVE;
149	return TRUE;
150}
151
152static void
153SummitSolid(
154    PixmapPtr pPixmap,
155    int x1,
156    int y1,
157    int x2,
158    int y2)
159{
160	ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
161	NGLEPtr fPtr = NGLEPTR(pScrn);
162	int wi = x2 - x1, he = y2 - y1;
163	int pitch = exaGetPixmapPitch(pPixmap);
164	int offset = exaGetPixmapOffset(pPixmap);
165	uint32_t mask;
166
167	ENTER;
168
169	y1 += offset / pitch;
170
171	SummitWaitMarker(pPixmap->drawable.pScreen, 0);
172	NGLEWrite4(fPtr, VISFX_START, (x1 << 16) | y1);
173	NGLEWrite4(fPtr, VISFX_SIZE, (wi << 16) | he);
174
175	exaMarkSync(pPixmap->drawable.pScreen);
176	LEAVE;
177}
178
179Bool
180SummitPrepareAccess(PixmapPtr pPixmap, int index)
181{
182	ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
183	NGLEPtr fPtr = NGLEPTR(pScrn);
184
185	SummitWaitMarker(pPixmap->drawable.pScreen, 0);
186	NGLEWrite4(fPtr, VISFX_VRAM_WRITE_MODE, OTC01 | BIN8F | BUFFL);
187	NGLEWrite4(fPtr, VISFX_VRAM_READ_MODE, OTC01 | BIN8F | BUFFL);
188	fPtr->hwmode = HW_BLIT;
189
190	return TRUE;
191}
192Bool
193SummitInitAccel(ScreenPtr pScreen)
194{
195	ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
196	NGLEPtr fPtr = NGLEPTR(pScrn);
197	ExaDriverPtr pExa;
198	int lines, bpp = pScrn->bitsPerPixel >> 3;
199
200	pExa = exaDriverAlloc();
201	if (!pExa)
202		return FALSE;
203
204	fPtr->pExa = pExa;
205
206	pExa->exa_major = EXA_VERSION_MAJOR;
207	pExa->exa_minor = EXA_VERSION_MINOR;
208
209	pExa->memoryBase = fPtr->fbmem;
210	lines = 1;/* until we figure out how to use more memory */
211	DBGMSG(X_ERROR, "lines %d\n", lines);
212	pExa->memorySize = fPtr->fbi.fbi_stride * (fPtr->fbi.fbi_height + 1);// fPtr->fbmem_len;
213	pExa->offScreenBase = fPtr->fbi.fbi_stride * fPtr->fbi.fbi_height;
214	pExa->pixmapOffsetAlign = fPtr->fbi.fbi_stride;
215	pExa->pixmapPitchAlign = fPtr->fbi.fbi_stride;
216
217	pExa->flags = EXA_OFFSCREEN_PIXMAPS | EXA_MIXED_PIXMAPS;
218
219	pExa->maxX = 2048;
220	pExa->maxY = 2048;
221
222	fPtr->hwmode = -1;
223
224	pExa->WaitMarker = SummitWaitMarker;
225	pExa->Solid = SummitSolid;
226	pExa->DoneSolid = SummitDoneCopy;
227	pExa->Copy = SummitCopy;
228	pExa->DoneCopy = SummitDoneCopy;
229	pExa->PrepareCopy = SummitPrepareCopy;
230	pExa->PrepareSolid = SummitPrepareSolid;
231	pExa->PrepareAccess = SummitPrepareAccess;
232	SummitWaitMarker(pScreen, 0);
233
234	return exaDriverInit(pScreen, pExa);
235}
236