1/* 2 * SBus Weitek P9100 EXA support 3 */ 4/*- 5 * Copyright (c) 2021 The NetBSD Foundation, Inc. 6 * All rights reserved. 7 * 8 * This code is derived from software contributed to The NetBSD Foundation 9 * by Julian Coleman. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 * POSSIBILITY OF SUCH DAMAGE. 31 */ 32/* $NetBSD: pnozz_exa.c,v 1.6 2023/11/05 17:06:14 jdc Exp $ */ 33 34#ifdef HAVE_CONFIG_H 35#include "config.h" 36#endif 37 38#include "pnozz.h" 39#include "pnozz_regs.h" 40 41 42static CARD32 PnozzCopyROP[] = { 43 /*GXclear*/ 0, 44 /*GXand*/ ROP_SRC & ROP_DST, 45 /*GXandReverse*/ ROP_SRC & (~ROP_DST), 46 /*GXcopy*/ ROP_SRC, 47 /*GXandInverted*/ (~ROP_SRC) & ROP_DST, 48 /*GXnoop*/ ROP_DST, 49 /*GXxor*/ ROP_SRC ^ ROP_DST, 50 /*GXor*/ ROP_SRC | ROP_DST, 51 /*GXnor*/ (~ROP_SRC) & (~ROP_DST), 52 /*GXequiv*/ (~ROP_SRC) ^ ROP_DST, 53 /*GXinvert*/ (~ROP_DST), 54 /*GXorReverse*/ ROP_SRC | (~ROP_DST), 55 /*GXcopyInverted*/ (~ROP_SRC), 56 /*GXorInverted*/ (~ROP_SRC) | ROP_DST, 57 /*GXnand*/ (~ROP_SRC) | (~ROP_DST), 58 /*GXset*/ ROP_SET 59}; 60 61static CARD32 PnozzDrawROP[] = { 62 /*GXclear*/ 0, 63 /*GXand*/ ROP_PAT & ROP_DST, 64 /*GXandReverse*/ ROP_PAT & (~ROP_DST), 65 /*GXcopy*/ ROP_PAT, 66 /*GXandInverted*/ (~ROP_PAT) & ROP_DST, 67 /*GXnoop*/ ROP_DST, 68 /*GXxor*/ ROP_PAT ^ ROP_DST, 69 /*GXor*/ ROP_PAT | ROP_DST, 70 /*GXnor*/ (~ROP_PAT) & (~ROP_DST), 71 /*GXequiv*/ (~ROP_PAT) ^ ROP_DST, 72 /*GXinvert*/ (~ROP_DST), 73 /*GXorReverse*/ ROP_PAT | (~ROP_DST), 74 /*GXcopyInverted*/ (~ROP_PAT), 75 /*GXorInverted*/ (~ROP_PAT) | ROP_DST, 76 /*GXnand*/ (~ROP_PAT) | (~ROP_DST), 77 /*GXset*/ ROP_PAT 78}; 79 80#define waitReady(pPnozz) while((pnozz_read_4(pPnozz, ENGINE_STATUS) & \ 81 (ENGINE_BUSY | BLITTER_BUSY)) !=0 ) 82 83void PnozzInitEngine(PnozzPtr); 84void pnozz_write_colour(PnozzPtr pPnozz, int reg, CARD32 colour); 85 86extern CARD32 MaxClip, junk; 87 88static void 89PnozzWaitMarker(ScreenPtr pScreen, int Marker) 90{ 91 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 92 PnozzPtr p = GET_PNOZZ_FROM_SCRN(pScrn); 93 94 waitReady(p); 95} 96 97static Bool 98PnozzPrepareCopy 99( 100 PixmapPtr pSrcPixmap, 101 PixmapPtr pDstPixmap, 102 int xdir, 103 int ydir, 104 int alu, 105 Pixel planemask 106) 107{ 108 ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum]; 109 PnozzPtr pPnozz = GET_PNOZZ_FROM_SCRN(pScrn); 110 111 waitReady(pPnozz); 112 pnozz_write_4(pPnozz, RASTER_OP, (PnozzCopyROP[alu] & 0xff)); 113 pnozz_write_4(pPnozz, PLANE_MASK, planemask); 114 pPnozz->srcoff = exaGetPixmapOffset(pSrcPixmap) / pPnozz->width; 115 116 return TRUE; 117} 118 119static void 120PnozzCopy 121( 122 PixmapPtr pDstPixmap, 123 int xSrc, 124 int ySrc, 125 int xDst, 126 int yDst, 127 int w, 128 int h 129) 130{ 131 ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum]; 132 PnozzPtr pPnozz = GET_PNOZZ_FROM_SCRN(pScrn); 133 CARD32 src, dst, srcw, dstw; 134 int doff = exaGetPixmapOffset(pDstPixmap) / pPnozz->width; 135 136 src = (((xSrc << pPnozz->depthshift) & 0x1fff) << 16) | 137 ((ySrc + pPnozz->srcoff) & 0x1fff); 138 dst = (((xDst << pPnozz->depthshift) & 0x1fff) << 16) | 139 ((yDst + doff) & 0x1fff); 140 srcw = ((((xSrc + w) << pPnozz->depthshift) - 1) << 16) | 141 ((ySrc + pPnozz->srcoff + h - 1) & 0x1fff); 142 dstw = ((((xDst + w) << pPnozz->depthshift) - 1) << 16) | 143 ((yDst + doff + h - 1) & 0x1fff); 144 145 waitReady(pPnozz); 146 147 pnozz_write_4(pPnozz, ABS_XY0, src); 148 pnozz_write_4(pPnozz, ABS_XY1, srcw); 149 pnozz_write_4(pPnozz, ABS_XY2, dst); 150 pnozz_write_4(pPnozz, ABS_XY3, dstw); 151 junk = pnozz_read_4(pPnozz, COMMAND_BLIT); 152 exaMarkSync(pDstPixmap->drawable.pScreen); 153} 154 155static void 156PnozzDoneCopy(PixmapPtr pDstPixmap) 157{ 158 ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum]; 159 PnozzPtr pPnozz = GET_PNOZZ_FROM_SCRN(pScrn); 160 161 waitReady(pPnozz); 162} 163 164static Bool 165PnozzPrepareSolid( 166 PixmapPtr pPixmap, 167 int alu, 168 Pixel planemask, 169 Pixel fg) 170{ 171 ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum]; 172 PnozzPtr pPnozz = GET_PNOZZ_FROM_SCRN(pScrn); 173 174 waitReady(pPnozz); 175 pnozz_write_colour(pPnozz, FOREGROUND_COLOR, fg); 176 pnozz_write_4(pPnozz, RASTER_OP, PnozzDrawROP[alu] & 0xff); 177 pnozz_write_4(pPnozz, PLANE_MASK, planemask); 178 pnozz_write_4(pPnozz, COORD_INDEX, 0); 179 180 return TRUE; 181} 182 183static void 184PnozzSolid( 185 PixmapPtr pPixmap, 186 int x, 187 int y, 188 int x2, 189 int y2) 190{ 191 ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum]; 192 PnozzPtr pPnozz = GET_PNOZZ_FROM_SCRN(pScrn); 193 int w = x2 - x - 1; 194 int h = y2 - y - 1; 195 196 waitReady(pPnozz); 197 pnozz_write_4(pPnozz, RECT_RTW_XY, ((x & 0x1fff) << 16) | 198 (y & 0x1fff)); 199 pnozz_write_4(pPnozz, RECT_RTP_XY, (((w & 0x1fff) << 16) | 200 (h & 0x1fff))); 201 junk = pnozz_read_4(pPnozz, COMMAND_QUAD); 202 exaMarkSync(pPixmap->drawable.pScreen); 203} 204 205int 206PnozzEXAInit(ScreenPtr pScreen) 207{ 208 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 209 PnozzPtr pPnozz = GET_PNOZZ_FROM_SCRN(pScrn); 210 ExaDriverPtr pExa; 211 212 PnozzInitEngine(pPnozz); 213 214 pExa = exaDriverAlloc(); 215 if (!pExa) 216 return FALSE; 217 218 pPnozz->pExa = pExa; 219 220 pExa->exa_major = EXA_VERSION_MAJOR; 221 pExa->exa_minor = EXA_VERSION_MINOR; 222 223 pExa->memoryBase = pPnozz->fb; 224 225 /* round to multiple of pixmap pitch */ 226 pExa->memorySize = (pPnozz->vidmem / pPnozz->width) * pPnozz->width; 227 pExa->offScreenBase = pPnozz->width * pPnozz->height; 228 229 /* 230 * our blitter can't deal with variable pitches 231 */ 232 pExa->pixmapOffsetAlign = pPnozz->width; 233 pExa->pixmapPitchAlign = pPnozz->width; 234 235 pExa->flags = EXA_MIXED_PIXMAPS; 236 237 pExa->maxX = 4096; 238 pExa->maxY = 4096; 239 240 pExa->WaitMarker = PnozzWaitMarker; 241 242 pExa->PrepareSolid = PnozzPrepareSolid; 243 pExa->Solid = PnozzSolid; 244 pExa->DoneSolid = PnozzDoneCopy; 245 246 pExa->PrepareCopy = PnozzPrepareCopy; 247 pExa->Copy = PnozzCopy; 248 pExa->DoneCopy = PnozzDoneCopy; 249 250 return exaDriverInit(pScreen, pExa);; 251} 252