summit_accel.c revision 5ec9a660
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.3 2024/12/26 11:26:15 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 reg;
50
51	ENTER;
52	do {
53		reg = NGLERead4(fPtr, VISFX_STATUS);
54	} while ((reg & 0x01000000) != 0);
55	if (reg != 0) {
56		xf86Msg(X_ERROR, "%s status %08x\n", __func__, reg);
57		xf86Msg(X_ERROR, "fault %08x\n", NGLERead4(fPtr, 0x641040));
58	}
59	LEAVE;
60}
61
62static void
63SummitWaitFifo(NGLEPtr fPtr, int count)
64{
65	int reg;
66	do {
67		reg = NGLERead4(fPtr, 0xa41440/*VISFX_FIFO*/);
68	} while (reg < count);
69}
70
71static Bool
72SummitPrepareCopy
73(
74    PixmapPtr pSrcPixmap,
75    PixmapPtr pDstPixmap,
76    int       xdir,
77    int       ydir,
78    int       alu,
79    Pixel     planemask
80)
81{
82	ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum];
83	NGLEPtr fPtr = NGLEPTR(pScrn);
84	int srcpitch = exaGetPixmapPitch(pSrcPixmap);
85	int srcoff = exaGetPixmapOffset(pSrcPixmap);
86
87	ENTER;
88
89	DBGMSG(X_ERROR, "%s %d %d\n", __func__, srcoff, srcpitch);
90	fPtr->offset = srcoff / srcpitch;
91	if (fPtr->hwmode != HW_BLIT) {
92		SummitWaitMarker(pSrcPixmap->drawable.pScreen, 0);
93		//SummitWaitFifo(fPtr, 3);
94		NGLEWrite4(fPtr, VISFX_VRAM_WRITE_MODE, OTC01 | BIN8F | BUFFL);
95		NGLEWrite4(fPtr, VISFX_VRAM_READ_MODE, OTC01 | BIN8F | BUFFL);
96		fPtr->hwmode = HW_BLIT;
97	}
98	NGLEWrite4(fPtr, VISFX_IBO, alu);
99	NGLEWrite4(fPtr, VISFX_PLANE_MASK, planemask);
100	LEAVE;
101	return TRUE;
102}
103
104static void
105SummitCopy
106(
107    PixmapPtr pDstPixmap,
108    int       xs,
109    int       ys,
110    int       xd,
111    int       yd,
112    int       wi,
113    int       he
114)
115{
116	ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum];
117	NGLEPtr fPtr = NGLEPTR(pScrn);
118	int dstpitch = exaGetPixmapPitch(pDstPixmap);
119	int dstoff = exaGetPixmapOffset(pDstPixmap);
120
121	ENTER;
122	SummitWaitMarker(pDstPixmap->drawable.pScreen, 0);
123	//SummitWaitFifo(fPtr, 8);
124	NGLEWrite4(fPtr, VISFX_COPY_SRC, (xs << 16) | (ys + fPtr->offset));
125	NGLEWrite4(fPtr, VISFX_COPY_WH, (wi << 16) | he);
126	NGLEWrite4(fPtr, VISFX_COPY_DST, (xd << 16) | (yd + (dstoff / dstpitch)));
127
128	exaMarkSync(pDstPixmap->drawable.pScreen);
129	LEAVE;
130}
131
132static void
133SummitDoneCopy(PixmapPtr pDstPixmap)
134{
135    ENTER;
136    LEAVE;
137}
138
139static Bool
140SummitPrepareSolid(
141    PixmapPtr pPixmap,
142    int alu,
143    Pixel planemask,
144    Pixel fg)
145{
146	ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
147	NGLEPtr fPtr = NGLEPTR(pScrn);
148
149	ENTER;
150	//SummitWaitFifo(fPtr, 6);
151	if (fPtr->hwmode != HW_FILL) {
152		SummitWaitMarker(pPixmap->drawable.pScreen, 0);
153		NGLEWrite4(fPtr, VISFX_VRAM_WRITE_MODE, OTC32 | BIN8F | BUFFL | 0x8c0);
154		fPtr->hwmode = HW_FILL;
155	}
156	NGLEWrite4(fPtr, VISFX_IBO, alu);
157	NGLEWrite4(fPtr, VISFX_FG_COLOUR, fg);
158	NGLEWrite4(fPtr, VISFX_PLANE_MASK, planemask);
159	LEAVE;
160	return TRUE;
161}
162
163static void
164SummitSolid(
165    PixmapPtr pPixmap,
166    int x1,
167    int y1,
168    int x2,
169    int y2)
170{
171	ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
172	NGLEPtr fPtr = NGLEPTR(pScrn);
173	int wi = x2 - x1, he = y2 - y1;
174	int pitch = exaGetPixmapPitch(pPixmap);
175	int offset = exaGetPixmapOffset(pPixmap);
176	uint32_t mask;
177
178	ENTER;
179
180	y1 += offset / pitch;
181
182	SummitWaitMarker(pPixmap->drawable.pScreen, 0);
183	//SummitWaitFifo(fPtr, 6);
184	NGLEWrite4(fPtr, VISFX_START, (x1 << 16) | y1);
185	NGLEWrite4(fPtr, VISFX_SIZE, (wi << 16) | he);
186
187	exaMarkSync(pPixmap->drawable.pScreen);
188	LEAVE;
189}
190
191static Bool
192SummitUploadToScreen(PixmapPtr pDst, int x, int y, int w, int h,
193    char *src, int src_pitch)
194{
195	ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum];
196	NGLEPtr fPtr = NGLEPTR(pScrn);
197	int	ofs =  exaGetPixmapOffset(pDst);
198	int	dst_pitch  = exaGetPixmapPitch(pDst);
199	int i;
200	uint32_t *line;
201
202//	int bpp    = pDst->drawable.bitsPerPixel;
203//	int cpp    = (bpp + 7) >> 3;
204//	int wBytes = w * cpp;
205
206	ENTER;
207	//xf86Msg(X_ERROR, "%s bpp %d\n", __func__, pDst->drawable.bitsPerPixel);
208	if (fPtr->hwmode != HW_BINC) {
209		SummitWaitMarker(pDst->drawable.pScreen, 0);
210		//SummitWaitFifo(fPtr, 3);
211		NGLEWrite4(fPtr, VISFX_VRAM_WRITE_MODE, OTC01 | BIN8F | BUFFL);
212		NGLEWrite4(fPtr, VISFX_VRAM_READ_MODE, OTC01 | BIN8F | BUFFL);
213		NGLEWrite4(fPtr, VISFX_PLANE_MASK, 0xffffffff);
214		NGLEWrite4(fPtr, VISFX_IBO, GXcopy);
215		fPtr->hwmode = HW_BINC;
216	}
217	while (h--) {
218		NGLEWrite4(fPtr, VISFX_VRAM_WRITE_DEST, (y << 16) | x);
219		line = (uint32_t *)src;
220		for (i = 0; i < w; i++)
221			NGLEWrite4(fPtr, VISFX_VRAM_WRITE_DATA_INCRX, line[i]);
222		src += src_pitch;
223		y++;
224	}
225	return TRUE;
226}
227
228Bool
229SummitPrepareAccess(PixmapPtr pPixmap, int index)
230{
231	ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
232	NGLEPtr fPtr = NGLEPTR(pScrn);
233
234	ENTER;
235	SummitWaitMarker(pPixmap->drawable.pScreen, 0);
236	NGLEWrite4(fPtr, VISFX_VRAM_WRITE_MODE, OTC01 | BIN8F | BUFFL);
237	NGLEWrite4(fPtr, VISFX_VRAM_READ_MODE, OTC01 | BIN8F | BUFFL);
238	NGLEWrite4(fPtr, VISFX_IBO, GXcopy);
239	NGLEWrite4(fPtr, VISFX_CONTROL, 0x200);
240	fPtr->hwmode = HW_FB;
241	LEAVE;
242	return TRUE;
243}
244
245void
246SummitFinishAccess(PixmapPtr pPixmap, int index)
247{
248	ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
249	NGLEPtr fPtr = NGLEPTR(pScrn);
250
251	ENTER;
252	NGLEWrite4(fPtr, VISFX_CONTROL, 0);
253	LEAVE;
254}
255
256Bool
257SummitInitAccel(ScreenPtr pScreen)
258{
259	ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
260	NGLEPtr fPtr = NGLEPTR(pScrn);
261	ExaDriverPtr pExa;
262	int lines, bpp = pScrn->bitsPerPixel >> 3;
263
264	pExa = exaDriverAlloc();
265	if (!pExa)
266		return FALSE;
267
268	fPtr->pExa = pExa;
269
270	pExa->exa_major = EXA_VERSION_MAJOR;
271	pExa->exa_minor = EXA_VERSION_MINOR;
272
273	pExa->memoryBase = fPtr->fbmem;
274	lines = 1;/* until we figure out how to use more memory */
275	DBGMSG(X_ERROR, "lines %d\n", lines);
276	pExa->memorySize = fPtr->fbi.fbi_stride * (fPtr->fbi.fbi_height + 1);// fPtr->fbmem_len;
277	pExa->offScreenBase = fPtr->fbi.fbi_stride * fPtr->fbi.fbi_height;
278	pExa->pixmapOffsetAlign = fPtr->fbi.fbi_stride;
279	pExa->pixmapPitchAlign = fPtr->fbi.fbi_stride;
280
281	pExa->flags = EXA_OFFSCREEN_PIXMAPS | EXA_MIXED_PIXMAPS;
282
283	pExa->maxX = 2048;
284	pExa->maxY = 2048;
285
286	fPtr->hwmode = -1;
287
288	pExa->WaitMarker = SummitWaitMarker;
289	pExa->Solid = SummitSolid;
290	pExa->DoneSolid = SummitDoneCopy;
291	pExa->Copy = SummitCopy;
292	pExa->DoneCopy = SummitDoneCopy;
293	pExa->PrepareCopy = SummitPrepareCopy;
294	pExa->PrepareSolid = SummitPrepareSolid;
295	pExa->UploadToScreen = SummitUploadToScreen;
296	pExa->PrepareAccess = SummitPrepareAccess;
297	pExa->FinishAccess = SummitFinishAccess;
298	SummitWaitMarker(pScreen, 0);
299	NGLEWrite4(fPtr, VISFX_FOE, FOE_BLEND_ROP);
300	NGLEWrite4(fPtr, VISFX_IBO, GXcopy);
301
302	return exaDriverInit(pScreen, pExa);
303}
304