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