ngle_accel.c revision ce159321
1727c6de2Smacallan/* 2727c6de2Smacallan * NGLE - hardware acceleration. 3727c6de2Smacallan * 4727c6de2Smacallan * Copyright (C) 2024 Michael Lorenz 5727c6de2Smacallan * 6727c6de2Smacallan * Permission is hereby granted, free of charge, to any person obtaining a copy 7727c6de2Smacallan * of this software and associated documentation files (the "Software"), to deal 8727c6de2Smacallan * in the Software without restriction, including without limitation the rights 9727c6de2Smacallan * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10727c6de2Smacallan * copies of the Software, and to permit persons to whom the Software is 11727c6de2Smacallan * furnished to do so, subject to the following conditions: 12727c6de2Smacallan * 13727c6de2Smacallan * The above copyright notice and this permission notice shall be included in 14727c6de2Smacallan * all copies or substantial portions of the Software. 15727c6de2Smacallan * 16727c6de2Smacallan * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17727c6de2Smacallan * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18727c6de2Smacallan * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19727c6de2Smacallan * MICHAEL LORENZ BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20727c6de2Smacallan * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21727c6de2Smacallan * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22727c6de2Smacallan */ 23727c6de2Smacallan 24ce159321Smacallan/* $NetBSD: ngle_accel.c,v 1.3 2024/10/22 08:46:07 macallan Exp $ */ 25727c6de2Smacallan 26727c6de2Smacallan#include <sys/types.h> 27727c6de2Smacallan#include <dev/ic/stireg.h> 28727c6de2Smacallan 29727c6de2Smacallan 30727c6de2Smacallan#include "ngle.h" 31727c6de2Smacallan 32727c6de2Smacallan//#define DEBUG 33727c6de2Smacallan 34727c6de2Smacallan#ifdef DEBUG 35727c6de2Smacallan#define ENTER xf86Msg(X_ERROR, "%s\n", __func__) 36727c6de2Smacallan#define LEAVE xf86Msg(X_ERROR, "%s done\n", __func__) 37727c6de2Smacallan#define DBGMSG xf86Msg 38727c6de2Smacallan#else 39727c6de2Smacallan#define ENTER 40727c6de2Smacallan#define DBGMSG if (0) xf86Msg 41727c6de2Smacallan#define LEAVE 42727c6de2Smacallan#endif 43727c6de2Smacallan 44727c6de2Smacallanstatic inline void 45727c6de2SmacallanNGLEWrite4(NGLEPtr fPtr, int offset, uint32_t val) 46727c6de2Smacallan{ 47727c6de2Smacallan volatile uint32_t *ptr = (uint32_t *)((uint8_t *)fPtr->regs + offset); 48727c6de2Smacallan *ptr = val; 49727c6de2Smacallan} 50727c6de2Smacallan 51727c6de2Smacallanstatic inline void 52727c6de2SmacallanNGLEWrite1(NGLEPtr fPtr, int offset, uint8_t val) 53727c6de2Smacallan{ 54727c6de2Smacallan volatile uint8_t *ptr = (uint8_t *)fPtr->regs + offset; 55727c6de2Smacallan *ptr = val; 56727c6de2Smacallan} 57727c6de2Smacallan 58727c6de2Smacallanstatic inline uint32_t 59727c6de2SmacallanNGLERead4(NGLEPtr fPtr, int offset) 60727c6de2Smacallan{ 61727c6de2Smacallan volatile uint32_t *ptr = (uint32_t *)((uint8_t *)fPtr->regs + offset); 62727c6de2Smacallan return *ptr; 63727c6de2Smacallan} 64727c6de2Smacallan 65727c6de2Smacallanstatic inline uint8_t 66727c6de2SmacallanNGLERead1(NGLEPtr fPtr, int offset) 67727c6de2Smacallan{ 68727c6de2Smacallan volatile uint8_t *ptr = (uint8_t *)fPtr->regs + offset; 69727c6de2Smacallan return *ptr; 70727c6de2Smacallan} 71727c6de2Smacallan 72727c6de2Smacallanstatic void 73727c6de2SmacallanNGLEWaitMarker(ScreenPtr pScreen, int Marker) 74727c6de2Smacallan{ 75727c6de2Smacallan ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 76727c6de2Smacallan NGLEPtr fPtr = NGLEPTR(pScrn); 77727c6de2Smacallan uint8_t stat; 78727c6de2Smacallan 79727c6de2Smacallan ENTER; 80727c6de2Smacallan do { 81727c6de2Smacallan stat = NGLERead1(fPtr, NGLE_REG_15b0); 82727c6de2Smacallan if (stat == 0) 83727c6de2Smacallan stat = NGLERead1(fPtr, NGLE_REG_15b0); 84727c6de2Smacallan } while (stat != 0); 85727c6de2Smacallan LEAVE; 86727c6de2Smacallan} 87727c6de2Smacallan 88727c6de2Smacallanstatic void 89727c6de2SmacallanNGLEWaitFifo(NGLEPtr fPtr, int slots) 90727c6de2Smacallan{ 91727c6de2Smacallan uint32_t reg; 92727c6de2Smacallan 93727c6de2Smacallan ENTER; 94727c6de2Smacallan do { 95727c6de2Smacallan reg = NGLERead4(fPtr, NGLE_REG_34); 96727c6de2Smacallan } while (reg < slots); 97727c6de2Smacallan LEAVE; 98727c6de2Smacallan} 99727c6de2Smacallan 100727c6de2Smacallanstatic Bool 101ce159321SmacallanNGLEPrepareCopy_EG 102727c6de2Smacallan( 103727c6de2Smacallan PixmapPtr pSrcPixmap, 104727c6de2Smacallan PixmapPtr pDstPixmap, 105727c6de2Smacallan int xdir, 106727c6de2Smacallan int ydir, 107727c6de2Smacallan int alu, 108727c6de2Smacallan Pixel planemask 109727c6de2Smacallan) 110727c6de2Smacallan{ 111727c6de2Smacallan ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum]; 112727c6de2Smacallan NGLEPtr fPtr = NGLEPTR(pScrn); 113727c6de2Smacallan int srcpitch = exaGetPixmapPitch(pSrcPixmap); 114727c6de2Smacallan int srcoff = exaGetPixmapOffset(pSrcPixmap); 115727c6de2Smacallan 116727c6de2Smacallan ENTER; 117727c6de2Smacallan 118727c6de2Smacallan DBGMSG(X_ERROR, "%s %d %d\n", __func__, srcoff, srcpitch); 119727c6de2Smacallan fPtr->offset = srcoff / srcpitch; 120727c6de2Smacallan NGLEWaitMarker(pDstPixmap->drawable.pScreen, 0); 121727c6de2Smacallan /* XXX HCRX needs ifferent values here */ 122727c6de2Smacallan NGLEWrite4(fPtr, NGLE_REG_10, 123727c6de2Smacallan BA(IndexedDcd, Otc04, Ots08, AddrLong, 0, BINapp0I, 0)); 124727c6de2Smacallan NGLEWrite4(fPtr, NGLE_REG_14, ((alu << 8) & 0xf00) | 0x23000000); 125727c6de2Smacallan NGLEWrite4(fPtr, NGLE_REG_13, planemask); 126727c6de2Smacallan 127727c6de2Smacallan fPtr->hwmode = HW_BLIT; 128727c6de2Smacallan 129727c6de2Smacallan LEAVE; 130727c6de2Smacallan return TRUE; 131727c6de2Smacallan} 132727c6de2Smacallan 133ce159321Smacallanstatic Bool 134ce159321SmacallanNGLEPrepareCopy_HCRX 135ce159321Smacallan( 136ce159321Smacallan PixmapPtr pSrcPixmap, 137ce159321Smacallan PixmapPtr pDstPixmap, 138ce159321Smacallan int xdir, 139ce159321Smacallan int ydir, 140ce159321Smacallan int alu, 141ce159321Smacallan Pixel planemask 142ce159321Smacallan) 143ce159321Smacallan{ 144ce159321Smacallan ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum]; 145ce159321Smacallan NGLEPtr fPtr = NGLEPTR(pScrn); 146ce159321Smacallan int srcpitch = exaGetPixmapPitch(pSrcPixmap); 147ce159321Smacallan int srcoff = exaGetPixmapOffset(pSrcPixmap); 148ce159321Smacallan 149ce159321Smacallan ENTER; 150ce159321Smacallan 151ce159321Smacallan DBGMSG(X_ERROR, "%s %d %d\n", __func__, srcoff, srcpitch); 152ce159321Smacallan fPtr->offset = srcoff / srcpitch; 153ce159321Smacallan NGLEWaitMarker(pDstPixmap->drawable.pScreen, 0); 154ce159321Smacallan /* XXX HCRX needs ifferent values here */ 155ce159321Smacallan NGLEWrite4(fPtr, NGLE_REG_10, 156ce159321Smacallan BA(FractDcd, Otc24, Ots08, AddrLong, 0, BINapp0F8, 0)); 157ce159321Smacallan NGLEWrite4(fPtr, NGLE_REG_14, IBOvals(RopSrc, 0, BitmapExtent32, 0, DataDynamic, MaskOtc, 158ce159321Smacallan 0, 0)); 159ce159321Smacallan NGLEWrite4(fPtr, NGLE_REG_13, planemask); 160ce159321Smacallan 161ce159321Smacallan fPtr->hwmode = HW_BLIT; 162ce159321Smacallan 163ce159321Smacallan LEAVE; 164ce159321Smacallan return TRUE; 165ce159321Smacallan} 166ce159321Smacallan 167727c6de2Smacallanstatic void 168727c6de2SmacallanNGLECopy 169727c6de2Smacallan( 170727c6de2Smacallan PixmapPtr pDstPixmap, 171727c6de2Smacallan int xs, 172727c6de2Smacallan int ys, 173727c6de2Smacallan int xd, 174727c6de2Smacallan int yd, 175727c6de2Smacallan int wi, 176727c6de2Smacallan int he 177727c6de2Smacallan) 178727c6de2Smacallan{ 179727c6de2Smacallan ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum]; 180727c6de2Smacallan NGLEPtr fPtr = NGLEPTR(pScrn); 181727c6de2Smacallan int dstpitch = exaGetPixmapPitch(pDstPixmap); 182727c6de2Smacallan int dstoff = exaGetPixmapOffset(pDstPixmap); 183727c6de2Smacallan 184727c6de2Smacallan ENTER; 185727c6de2Smacallan NGLEWaitFifo(fPtr, 3); 186727c6de2Smacallan NGLEWrite4(fPtr, NGLE_REG_24, (xs << 16) | (ys + fPtr->offset)); 187727c6de2Smacallan NGLEWrite4(fPtr, NGLE_REG_7, (wi << 16) | he); 188727c6de2Smacallan NGLEWrite4(fPtr, NGLE_REG_25, (xd << 16) | (yd + (dstoff / dstpitch))); 189727c6de2Smacallan 190727c6de2Smacallan exaMarkSync(pDstPixmap->drawable.pScreen); 191727c6de2Smacallan LEAVE; 192727c6de2Smacallan} 193727c6de2Smacallan 194727c6de2Smacallanstatic void 195727c6de2SmacallanNGLEDoneCopy(PixmapPtr pDstPixmap) 196727c6de2Smacallan{ 197727c6de2Smacallan ENTER; 198727c6de2Smacallan LEAVE; 199727c6de2Smacallan} 200727c6de2Smacallan 201727c6de2Smacallanstatic Bool 202ce159321SmacallanNGLEPrepareSolid_EG( 203727c6de2Smacallan PixmapPtr pPixmap, 204727c6de2Smacallan int alu, 205727c6de2Smacallan Pixel planemask, 206727c6de2Smacallan Pixel fg) 207727c6de2Smacallan{ 208727c6de2Smacallan ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum]; 209727c6de2Smacallan NGLEPtr fPtr = NGLEPTR(pScrn); 210727c6de2Smacallan 211727c6de2Smacallan ENTER; 212727c6de2Smacallan NGLEWaitFifo(fPtr, 4); 213727c6de2Smacallan /* plane mask */ 214727c6de2Smacallan NGLEWrite4(fPtr, NGLE_REG_13, planemask); 215727c6de2Smacallan /* bitmap op */ 216727c6de2Smacallan NGLEWrite4(fPtr, NGLE_REG_14, 217727c6de2Smacallan IBOvals(alu, 0, BitmapExtent08, 0, DataDynamic, MaskOtc, 1, 0)); 218727c6de2Smacallan 219bc460d0dSmacallan /* XXX HCRX needs different values here */ 220727c6de2Smacallan /* dst bitmap access */ 221727c6de2Smacallan NGLEWrite4(fPtr, NGLE_REG_11, 222727c6de2Smacallan BA(IndexedDcd, Otc32, OtsIndirect, AddrLong, 0, BINapp0I, 0)); 223727c6de2Smacallan NGLEWrite4(fPtr, NGLE_REG_35, fg); 224727c6de2Smacallan fPtr->hwmode = HW_FILL; 225727c6de2Smacallan 226727c6de2Smacallan LEAVE; 227727c6de2Smacallan return TRUE; 228727c6de2Smacallan} 229727c6de2Smacallan 230ce159321Smacallanstatic Bool 231ce159321SmacallanNGLEPrepareSolid_HCRX( 232ce159321Smacallan PixmapPtr pPixmap, 233ce159321Smacallan int alu, 234ce159321Smacallan Pixel planemask, 235ce159321Smacallan Pixel fg) 236ce159321Smacallan{ 237ce159321Smacallan ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum]; 238ce159321Smacallan NGLEPtr fPtr = NGLEPTR(pScrn); 239ce159321Smacallan 240ce159321Smacallan ENTER; 241ce159321Smacallan NGLEWaitFifo(fPtr, 4); 242ce159321Smacallan /* plane mask */ 243ce159321Smacallan NGLEWrite4(fPtr, NGLE_REG_13, planemask); 244ce159321Smacallan /* bitmap op */ 245ce159321Smacallan NGLEWrite4(fPtr, NGLE_REG_14, 246ce159321Smacallan IBOvals(alu, 0, BitmapExtent32, 0, DataDynamic, MaskOtc, 1, 0)); 247ce159321Smacallan 248ce159321Smacallan /* XXX HCRX needs different values here */ 249ce159321Smacallan /* dst bitmap access */ 250ce159321Smacallan NGLEWrite4(fPtr, NGLE_REG_11, 251ce159321Smacallan BA(FractDcd, Otc32, OtsIndirect, AddrLong, 0, BINapp0F8, 0)); 252ce159321Smacallan NGLEWrite4(fPtr, NGLE_REG_35, fg); 253ce159321Smacallan fPtr->hwmode = HW_FILL; 254ce159321Smacallan 255ce159321Smacallan LEAVE; 256ce159321Smacallan return TRUE; 257ce159321Smacallan} 258ce159321Smacallan 259727c6de2Smacallanstatic void 260727c6de2SmacallanNGLESolid( 261727c6de2Smacallan PixmapPtr pPixmap, 262727c6de2Smacallan int x1, 263727c6de2Smacallan int y1, 264727c6de2Smacallan int x2, 265727c6de2Smacallan int y2) 266727c6de2Smacallan{ 267727c6de2Smacallan ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum]; 268727c6de2Smacallan NGLEPtr fPtr = NGLEPTR(pScrn); 269727c6de2Smacallan int w = x2 - x1, h = y2 - y1; 270727c6de2Smacallan int pitch = exaGetPixmapPitch(pPixmap); 271727c6de2Smacallan int offset = exaGetPixmapOffset(pPixmap); 272727c6de2Smacallan uint32_t mask; 273727c6de2Smacallan int wi, rest; 274727c6de2Smacallan 275727c6de2Smacallan ENTER; 276727c6de2Smacallan 277727c6de2Smacallan y1 += offset >> 11; 278727c6de2Smacallan 279bc460d0dSmacallan /* 280bc460d0dSmacallan * XXX 281bc460d0dSmacallan * Turns out this thing always fills rectangles to the next 32 pixel 282bc460d0dSmacallan * boundary on te right. To get around this we split the rectangle 283bc460d0dSmacallan * into a multiples-of-32 part and the rest, so we can mask off the 284bc460d0dSmacallan * excess pixels. 285bc460d0dSmacallan */ 286727c6de2Smacallan rest = w & 0x1f; 287727c6de2Smacallan wi = w & 0xffffe0; 288727c6de2Smacallan if (wi > 0) { 289727c6de2Smacallan NGLEWaitFifo(fPtr, 3); 290727c6de2Smacallan /* transfer data */ 291727c6de2Smacallan NGLEWrite4(fPtr, NGLE_REG_8, 0xffffffff); 292727c6de2Smacallan /* dst XY */ 293727c6de2Smacallan NGLEWrite4(fPtr, NGLE_REG_6, (x1 << 16) | y1); 294727c6de2Smacallan /* len XY start */ 295727c6de2Smacallan NGLEWrite4(fPtr, NGLE_REG_9, (wi << 16) | h); 296727c6de2Smacallan } 297727c6de2Smacallan if (rest > 0) { 298727c6de2Smacallan mask = 0xffffffff << (32 - w); 299727c6de2Smacallan /* transfer data */ 300bc460d0dSmacallan NGLEWaitFifo(fPtr, 3); 301727c6de2Smacallan NGLEWrite4(fPtr, NGLE_REG_8, mask); 302727c6de2Smacallan /* dst XY */ 303727c6de2Smacallan NGLEWrite4(fPtr, NGLE_REG_6, ((x1 + wi) << 16) | y1); 304727c6de2Smacallan /* len XY start */ 305727c6de2Smacallan NGLEWrite4(fPtr, NGLE_REG_9, (rest << 16) | h); 306727c6de2Smacallan } 307727c6de2Smacallan exaMarkSync(pPixmap->drawable.pScreen); 308727c6de2Smacallan LEAVE; 309727c6de2Smacallan} 310727c6de2Smacallan 311727c6de2SmacallanBool 312ce159321SmacallanNGLEPrepareAccess_EG(PixmapPtr pPixmap, int index) 313727c6de2Smacallan{ 314727c6de2Smacallan ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum]; 315727c6de2Smacallan NGLEPtr fPtr = NGLEPTR(pScrn); 316727c6de2Smacallan 317727c6de2Smacallan if (fPtr->hwmode == HW_FB) return TRUE; 318727c6de2Smacallan 319727c6de2Smacallan NGLEWaitMarker(pPixmap->drawable.pScreen, 0); 320ce159321Smacallan NGLEWrite4(fPtr, NGLE_REG_10, 321ce159321Smacallan BA(IndexedDcd, Otc04, Ots08, AddrByte, 0, BINapp0I, 0)); 322727c6de2Smacallan NGLEWrite4(fPtr, NGLE_REG_14, 0x83000300); 323727c6de2Smacallan NGLEWrite4(fPtr, NGLE_REG_13, 0xff); 324727c6de2Smacallan NGLEWaitMarker(pPixmap->drawable.pScreen, 0); 325727c6de2Smacallan NGLEWrite1(fPtr, NGLE_REG_16b1, 1); 326727c6de2Smacallan fPtr->hwmode = HW_FB; 327727c6de2Smacallan return TRUE; 328727c6de2Smacallan} 329727c6de2Smacallan 330ce159321SmacallanBool 331ce159321SmacallanNGLEPrepareAccess_HCRX(PixmapPtr pPixmap, int index) 332ce159321Smacallan{ 333ce159321Smacallan ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum]; 334ce159321Smacallan NGLEPtr fPtr = NGLEPTR(pScrn); 335ce159321Smacallan 336ce159321Smacallan if (fPtr->hwmode == HW_FB) return TRUE; 337ce159321Smacallan 338ce159321Smacallan NGLEWaitMarker(pPixmap->drawable.pScreen, 0); 339ce159321Smacallan NGLEWrite4(fPtr, NGLE_REG_10, 340ce159321Smacallan BA(FractDcd, Otc24, Ots08, AddrLong, 0, BINapp0F8, 0)); 341ce159321Smacallan NGLEWrite4(fPtr, NGLE_REG_14, 0x83000300); 342ce159321Smacallan NGLEWrite4(fPtr, NGLE_REG_13, 0xffffffff); 343ce159321Smacallan NGLEWaitMarker(pPixmap->drawable.pScreen, 0); 344ce159321Smacallan NGLEWrite1(fPtr, NGLE_REG_16b1, 1); 345ce159321Smacallan fPtr->hwmode = HW_FB; 346ce159321Smacallan return TRUE; 347ce159321Smacallan} 348727c6de2SmacallanBool 349727c6de2SmacallanNGLEInitAccel(ScreenPtr pScreen) 350727c6de2Smacallan{ 351727c6de2Smacallan ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 352727c6de2Smacallan NGLEPtr fPtr = NGLEPTR(pScrn); 353727c6de2Smacallan ExaDriverPtr pExa; 354727c6de2Smacallan int lines, bpp = pScrn->bitsPerPixel >> 3; 355727c6de2Smacallan 356727c6de2Smacallan pExa = exaDriverAlloc(); 357727c6de2Smacallan if (!pExa) 358727c6de2Smacallan return FALSE; 359727c6de2Smacallan 360727c6de2Smacallan fPtr->pExa = pExa; 361727c6de2Smacallan 362727c6de2Smacallan pExa->exa_major = EXA_VERSION_MAJOR; 363727c6de2Smacallan pExa->exa_minor = EXA_VERSION_MINOR; 364727c6de2Smacallan 365727c6de2Smacallan pExa->memoryBase = fPtr->fbmem; 366727c6de2Smacallan lines = fPtr->fbmem_len / fPtr->fbi.fbi_stride; 367727c6de2Smacallan DBGMSG(X_ERROR, "lines %d\n", lines); 368727c6de2Smacallan pExa->memorySize = fPtr->fbmem_len; 369727c6de2Smacallan pExa->offScreenBase = fPtr->fbi.fbi_stride * fPtr->fbi.fbi_height; 370727c6de2Smacallan pExa->pixmapOffsetAlign = fPtr->fbi.fbi_stride; 371727c6de2Smacallan pExa->pixmapPitchAlign = fPtr->fbi.fbi_stride; 372727c6de2Smacallan 373727c6de2Smacallan pExa->flags = EXA_OFFSCREEN_PIXMAPS | EXA_MIXED_PIXMAPS; 374727c6de2Smacallan 375727c6de2Smacallan pExa->maxX = 2048; 376727c6de2Smacallan pExa->maxY = 2048; 377727c6de2Smacallan 378727c6de2Smacallan fPtr->hwmode = -1; 379727c6de2Smacallan 380727c6de2Smacallan pExa->WaitMarker = NGLEWaitMarker; 381727c6de2Smacallan pExa->Solid = NGLESolid; 382727c6de2Smacallan pExa->DoneSolid = NGLEDoneCopy; 383727c6de2Smacallan pExa->Copy = NGLECopy; 384727c6de2Smacallan pExa->DoneCopy = NGLEDoneCopy; 385ce159321Smacallan switch (fPtr->gid) { 386ce159321Smacallan case STI_DD_EG: 387ce159321Smacallan pExa->PrepareCopy = NGLEPrepareCopy_EG; 388ce159321Smacallan pExa->PrepareSolid = NGLEPrepareSolid_EG; 389ce159321Smacallan pExa->PrepareAccess = NGLEPrepareAccess_EG; 390ce159321Smacallan break; 391ce159321Smacallan case STI_DD_HCRX: 392ce159321Smacallan pExa->PrepareCopy = NGLEPrepareCopy_HCRX; 393ce159321Smacallan pExa->PrepareSolid = NGLEPrepareSolid_HCRX; 394ce159321Smacallan pExa->PrepareAccess = NGLEPrepareAccess_HCRX; 395ce159321Smacallan break; 396ce159321Smacallan default: 397ce159321Smacallan xf86Msg(X_ERROR, 398ce159321Smacallan "unsupported dvice GID %08x\n", fPtr->gid); 399ce159321Smacallan return FALSE; 400ce159321Smacallan } 401727c6de2Smacallan NGLEWaitMarker(pScreen, 0); 402727c6de2Smacallan 403727c6de2Smacallan return exaDriverInit(pScreen, pExa); 404727c6de2Smacallan} 405