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