igs_accel.c revision 80c47f9a
1be1ef3d3Smacallan/*
2be1ef3d3Smacallan * IGS CyberPro - hardware acceleration.
3be1ef3d3Smacallan *
4be1ef3d3Smacallan * Copyright (C) 2009 Michael Lorenz
5be1ef3d3Smacallan *
6be1ef3d3Smacallan * Permission is hereby granted, free of charge, to any person obtaining a copy
7be1ef3d3Smacallan * of this software and associated documentation files (the "Software"), to deal
8be1ef3d3Smacallan * in the Software without restriction, including without limitation the rights
9be1ef3d3Smacallan * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10be1ef3d3Smacallan * copies of the Software, and to permit persons to whom the Software is
11be1ef3d3Smacallan * furnished to do so, subject to the following conditions:
12be1ef3d3Smacallan *
13be1ef3d3Smacallan * The above copyright notice and this permission notice shall be included in
14be1ef3d3Smacallan * all copies or substantial portions of the Software.
15be1ef3d3Smacallan *
16be1ef3d3Smacallan * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17be1ef3d3Smacallan * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18be1ef3d3Smacallan * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19be1ef3d3Smacallan * MICHAEL LORENZ BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
20be1ef3d3Smacallan * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21be1ef3d3Smacallan * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22be1ef3d3Smacallan */
23be1ef3d3Smacallan
2480c47f9aSchristos/* $NetBSD: igs_accel.c,v 1.7 2011/05/28 13:26:54 christos Exp $ */
25be1ef3d3Smacallan
26be1ef3d3Smacallan#include <sys/types.h>
27be1ef3d3Smacallan
28b4c928c7Schristos/* all driver need this */
29b4c928c7Schristos#include "xf86.h"
30b4c928c7Schristos#include "xf86_OSproc.h"
3180c47f9aSchristos#include "compiler.h"
32b4c928c7Schristos
33be1ef3d3Smacallan#include "igs.h"
34be1ef3d3Smacallan
35be1ef3d3Smacallan/*#define DEBUG*/
36be1ef3d3Smacallan
37be1ef3d3Smacallan#ifdef DEBUG
38be1ef3d3Smacallan#define ENTER xf86Msg(X_ERROR, "%s\n", __func__)
39be1ef3d3Smacallan#define LEAVE xf86Msg(X_ERROR, "%s done\n", __func__)
40be1ef3d3Smacallan#else
41be1ef3d3Smacallan#define ENTER
42be1ef3d3Smacallan#define LEAVE
43be1ef3d3Smacallan#endif
44be1ef3d3Smacallan
45be1ef3d3Smacallanstatic inline void IgsWrite1(IgsPtr fPtr, int offset, uint8_t val)
46be1ef3d3Smacallan{
47be1ef3d3Smacallan	*(fPtr->reg + offset) = val;
48be1ef3d3Smacallan}
49be1ef3d3Smacallan
50be1ef3d3Smacallan
51be1ef3d3Smacallanstatic inline void IgsWrite2(IgsPtr fPtr, int offset, uint16_t val)
52be1ef3d3Smacallan{
53d88e62d8Smacallan	*(volatile uint16_t *)(fPtr->reg + offset) = val;
54be1ef3d3Smacallan}
55be1ef3d3Smacallan
56be1ef3d3Smacallanstatic inline void IgsWrite4(IgsPtr fPtr, int offset, uint32_t val)
57be1ef3d3Smacallan{
58d88e62d8Smacallan	*(volatile uint32_t *)(fPtr->reg + offset) = val;
59be1ef3d3Smacallan}
60be1ef3d3Smacallan
61be1ef3d3Smacallanstatic inline uint8_t IgsRead1(IgsPtr fPtr, int offset)
62be1ef3d3Smacallan{
63be1ef3d3Smacallan	return *(fPtr->reg + offset);
64be1ef3d3Smacallan}
65be1ef3d3Smacallan
66be1ef3d3Smacallanstatic inline uint16_t IgsRead2(IgsPtr fPtr, int offset)
67be1ef3d3Smacallan{
68d88e62d8Smacallan	return *(volatile uint16_t *)(fPtr->reg + offset);
69be1ef3d3Smacallan}
70be1ef3d3Smacallan
71be1ef3d3Smacallanstatic void
72be1ef3d3SmacallanIgsWaitMarker(ScreenPtr pScreen, int Marker)
73be1ef3d3Smacallan{
74be1ef3d3Smacallan	ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
75be1ef3d3Smacallan	IgsPtr fPtr = IGSPTR(pScrn);
76be1ef3d3Smacallan	int bail = 0x0fffffff;
779a5ed1c5Smacallan
78be1ef3d3Smacallan	ENTER;
79727ce256Smacallan	IgsWrite1(fPtr, IGS_COP_MAP_FMT_REG, fPtr->mapfmt);
80be1ef3d3Smacallan	while ((IgsRead1(fPtr,
81be1ef3d3Smacallan	    IGS_COP_CTL_REG) & (IGS_COP_CTL_BUSY | IGS_COP_CTL_HFEMPTZ) != 0)
82be1ef3d3Smacallan	    && (bail > 0)) {
83be1ef3d3Smacallan		bail--;
84727ce256Smacallan		IgsWrite1(fPtr, IGS_COP_MAP_FMT_REG, fPtr->mapfmt);
85be1ef3d3Smacallan	}
86be1ef3d3Smacallan
87be1ef3d3Smacallan	/* reset the coprocessor if we run into a timeout */
88be1ef3d3Smacallan	if (bail == 0) {
89be1ef3d3Smacallan		xf86Msg(X_ERROR, "%s: timeout\n", __func__);
90be1ef3d3Smacallan		IgsWrite1(fPtr, IGS_COP_CTL_REG, 0);
91be1ef3d3Smacallan	}
92be1ef3d3Smacallan	LEAVE;
93be1ef3d3Smacallan}
94be1ef3d3Smacallan
95be1ef3d3Smacallanstatic int
96be1ef3d3SmacallanIgsMarkSync(ScreenPtr pScreenInfo)
97be1ef3d3Smacallan{
989a5ed1c5Smacallan	ENTER;
999a5ed1c5Smacallan	return 0;
100be1ef3d3Smacallan}
101be1ef3d3Smacallan
102be1ef3d3Smacallanstatic void
103be1ef3d3SmacallanIgsWaitReady(IgsPtr fPtr)
104be1ef3d3Smacallan{
105be1ef3d3Smacallan	int bail = 0x0fffffff;
1069a5ed1c5Smacallan
107be1ef3d3Smacallan	ENTER;
108727ce256Smacallan	IgsWrite1(fPtr, IGS_COP_MAP_FMT_REG, fPtr->mapfmt);
109be1ef3d3Smacallan	while (((IgsRead1(fPtr,
110be1ef3d3Smacallan	    IGS_COP_CTL_REG) & (IGS_COP_CTL_BUSY | IGS_COP_CTL_HFEMPTZ)) != 0)
111be1ef3d3Smacallan	    && (bail > 0)) {
112be1ef3d3Smacallan		bail--;
113727ce256Smacallan		IgsWrite1(fPtr, IGS_COP_MAP_FMT_REG, fPtr->mapfmt);
114be1ef3d3Smacallan	}
115be1ef3d3Smacallan
116be1ef3d3Smacallan	/* reset the coprocessor if we run into a timeout */
117be1ef3d3Smacallan	if (bail == 0) {
118be1ef3d3Smacallan		xf86Msg(X_ERROR, "%s: timeout\n", __func__);
119be1ef3d3Smacallan		IgsWrite1(fPtr, IGS_COP_CTL_REG, 0);
120be1ef3d3Smacallan	}
121be1ef3d3Smacallan	LEAVE;
122be1ef3d3Smacallan}
123be1ef3d3Smacallan
124be1ef3d3Smacallanstatic Bool
125be1ef3d3SmacallanIgsPrepareCopy
126be1ef3d3Smacallan(
127be1ef3d3Smacallan    PixmapPtr pSrcPixmap,
128be1ef3d3Smacallan    PixmapPtr pDstPixmap,
129be1ef3d3Smacallan    int       xdir,
130be1ef3d3Smacallan    int       ydir,
131be1ef3d3Smacallan    int       alu,
132be1ef3d3Smacallan    Pixel     planemask
133be1ef3d3Smacallan)
134be1ef3d3Smacallan{
135be1ef3d3Smacallan	ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum];
136be1ef3d3Smacallan	IgsPtr fPtr = IGSPTR(pScrn);
137be1ef3d3Smacallan
138be1ef3d3Smacallan	ENTER;
139be1ef3d3Smacallan	fPtr->cmd = IGS_COP_OP_PXBLT | IGS_COP_OP_FG_FROM_SRC |
140be1ef3d3Smacallan	    IGS_COP_PPM_FIXED_FG;
141be1ef3d3Smacallan	if (xdir < 0)
142be1ef3d3Smacallan		fPtr->cmd |= IGS_COP_OCTANT_X_NEG;
143be1ef3d3Smacallan	if (ydir < 0)
144be1ef3d3Smacallan		fPtr->cmd |= IGS_COP_OCTANT_Y_NEG;
145be1ef3d3Smacallan
146be1ef3d3Smacallan	IgsWaitReady(fPtr);
147be1ef3d3Smacallan	IgsWrite1(fPtr, IGS_COP_CTL_REG, 0);
148be1ef3d3Smacallan	fPtr->srcoff = exaGetPixmapOffset(pSrcPixmap) >> fPtr->shift;
149be1ef3d3Smacallan	fPtr->srcpitch = exaGetPixmapPitch(pSrcPixmap) >> fPtr->shift;
150be1ef3d3Smacallan
151be1ef3d3Smacallan	IgsWrite2(fPtr, IGS_COP_SRC_MAP_WIDTH_REG, fPtr->srcpitch - 1);
152be1ef3d3Smacallan	IgsWrite2(fPtr, IGS_COP_DST_MAP_WIDTH_REG,
153be1ef3d3Smacallan	    (exaGetPixmapPitch(pDstPixmap) >> fPtr->shift) - 1);
154be1ef3d3Smacallan	IgsWrite1(fPtr, IGS_COP_FG_MIX_REG, alu);
155be1ef3d3Smacallan	IgsWrite4(fPtr, IGS_PLANE_MASK_REG, planemask);
156be1ef3d3Smacallan	LEAVE;
157be1ef3d3Smacallan	return TRUE;
158be1ef3d3Smacallan}
159be1ef3d3Smacallan
160be1ef3d3Smacallanstatic void
161be1ef3d3SmacallanIgsCopy
162be1ef3d3Smacallan(
163be1ef3d3Smacallan    PixmapPtr pDstPixmap,
164be1ef3d3Smacallan    int       srcX,
165be1ef3d3Smacallan    int       srcY,
166be1ef3d3Smacallan    int       dstX,
167be1ef3d3Smacallan    int       dstY,
168be1ef3d3Smacallan    int       w,
169be1ef3d3Smacallan    int       h
170be1ef3d3Smacallan)
171be1ef3d3Smacallan{
172be1ef3d3Smacallan	ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum];
173be1ef3d3Smacallan	IgsPtr fPtr = IGSPTR(pScrn);
174be1ef3d3Smacallan	int dstpitch, dstoff;
175be1ef3d3Smacallan
176be1ef3d3Smacallan	if (fPtr->cmd & IGS_COP_OCTANT_X_NEG) {
177be1ef3d3Smacallan		srcX += (w - 1);
178be1ef3d3Smacallan		dstX += (w - 1);
179be1ef3d3Smacallan	}
180be1ef3d3Smacallan
181be1ef3d3Smacallan	if (fPtr->cmd & IGS_COP_OCTANT_Y_NEG) {
182be1ef3d3Smacallan		srcY += (h - 1);
183be1ef3d3Smacallan		dstY += (h - 1);
184be1ef3d3Smacallan	}
185be1ef3d3Smacallan	IgsWaitReady(fPtr);
186be1ef3d3Smacallan	IgsWrite4(fPtr, IGS_COP_SRC_START_REG, fPtr->srcoff + srcX +
187be1ef3d3Smacallan	    fPtr->srcpitch * srcY);
188be1ef3d3Smacallan	dstpitch = exaGetPixmapPitch(pDstPixmap) >> fPtr->shift;
189be1ef3d3Smacallan	dstoff = exaGetPixmapOffset(pDstPixmap) >> fPtr->shift;
190be1ef3d3Smacallan	IgsWrite4(fPtr, IGS_COP_DST_START_REG, dstoff + dstX +
191be1ef3d3Smacallan	    dstpitch * dstY);
192be1ef3d3Smacallan	IgsWrite2(fPtr, IGS_COP_WIDTH_REG, w - 1);
193be1ef3d3Smacallan	IgsWrite2(fPtr, IGS_COP_HEIGHT_REG, h - 1);
194be1ef3d3Smacallan	IgsWrite2(fPtr, IGS_COP_PIXEL_OP_REG, fPtr->cmd & 0xffff);
195be1ef3d3Smacallan	IgsWrite2(fPtr, IGS_COP_PIXEL_OP_REG + 2, (fPtr->cmd >> 16) & 0xffff);
196be1ef3d3Smacallan	LEAVE;
197be1ef3d3Smacallan}
198be1ef3d3Smacallan
199be1ef3d3Smacallanstatic void
200be1ef3d3SmacallanIgsDoneCopy(PixmapPtr pDstPixmap)
201be1ef3d3Smacallan{
202be1ef3d3Smacallan    ENTER;
203be1ef3d3Smacallan    LEAVE;
204be1ef3d3Smacallan}
205be1ef3d3Smacallan
206be1ef3d3Smacallanstatic Bool
207be1ef3d3SmacallanIgsPrepareSolid(
208be1ef3d3Smacallan    PixmapPtr pPixmap,
209be1ef3d3Smacallan    int alu,
210be1ef3d3Smacallan    Pixel planemask,
211be1ef3d3Smacallan    Pixel fg)
212be1ef3d3Smacallan{
213be1ef3d3Smacallan	ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
214be1ef3d3Smacallan	IgsPtr fPtr = IGSPTR(pScrn);
215be1ef3d3Smacallan
216be1ef3d3Smacallan	ENTER;
217be1ef3d3Smacallan	fPtr->cmd = IGS_COP_OP_PXBLT | IGS_COP_PPM_FIXED_FG;
218be1ef3d3Smacallan
219be1ef3d3Smacallan	IgsWaitReady(fPtr);
220be1ef3d3Smacallan
221be1ef3d3Smacallan	IgsWrite1(fPtr, IGS_COP_CTL_REG, 0);
222be1ef3d3Smacallan
223be1ef3d3Smacallan	IgsWrite2(fPtr, IGS_COP_DST_MAP_WIDTH_REG,
224be1ef3d3Smacallan	    (exaGetPixmapPitch(pPixmap) >> fPtr->shift) - 1);
225be1ef3d3Smacallan	IgsWrite1(fPtr, IGS_COP_FG_MIX_REG, alu);
226be1ef3d3Smacallan	IgsWrite4(fPtr, IGS_PLANE_MASK_REG, planemask);
227be1ef3d3Smacallan	IgsWrite4(fPtr, IGS_COP_FG_REG, fg);
228be1ef3d3Smacallan	LEAVE;
229be1ef3d3Smacallan	return TRUE;
230be1ef3d3Smacallan}
231be1ef3d3Smacallan
232be1ef3d3Smacallanstatic void
233be1ef3d3SmacallanIgsSolid(
234be1ef3d3Smacallan    PixmapPtr pPixmap,
235be1ef3d3Smacallan    int x1,
236be1ef3d3Smacallan    int y1,
237be1ef3d3Smacallan    int x2,
238be1ef3d3Smacallan    int y2)
239be1ef3d3Smacallan{
240be1ef3d3Smacallan	ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
241be1ef3d3Smacallan	IgsPtr fPtr = IGSPTR(pScrn);
242be1ef3d3Smacallan	int w = x2 - x1, h = y2 - y1, dstoff, dstpitch;
243be1ef3d3Smacallan
244be1ef3d3Smacallan	ENTER;
245be1ef3d3Smacallan	IgsWaitReady(fPtr);
246be1ef3d3Smacallan	dstpitch = exaGetPixmapPitch(pPixmap) >> fPtr->shift;
247be1ef3d3Smacallan	dstoff = exaGetPixmapOffset(pPixmap) >> fPtr->shift;
248be1ef3d3Smacallan	IgsWrite4(fPtr, IGS_COP_DST_START_REG, dstoff + x1 +
249be1ef3d3Smacallan	    dstpitch * y1);
250be1ef3d3Smacallan	IgsWrite2(fPtr, IGS_COP_WIDTH_REG, w - 1);
251be1ef3d3Smacallan	IgsWrite2(fPtr, IGS_COP_HEIGHT_REG, h - 1);
252be1ef3d3Smacallan	IgsWrite2(fPtr, IGS_COP_PIXEL_OP_REG, fPtr->cmd & 0xffff);
253be1ef3d3Smacallan	IgsWrite2(fPtr, IGS_COP_PIXEL_OP_REG + 2, (fPtr->cmd >> 16) & 0xffff);
254be1ef3d3Smacallan}
255be1ef3d3Smacallan
256be1ef3d3Smacallan/*
257be1ef3d3Smacallan * Memcpy-based UTS.
258be1ef3d3Smacallan */
259be1ef3d3Smacallanstatic Bool
260be1ef3d3SmacallanIgsUploadToScreen(PixmapPtr pDst, int x, int y, int w, int h,
261be1ef3d3Smacallan    char *src, int src_pitch)
262be1ef3d3Smacallan{
2639a5ed1c5Smacallan	ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum];
2649a5ed1c5Smacallan	IgsPtr fPtr = IGSPTR(pScrn);
2659a5ed1c5Smacallan	char  *dst        = fPtr->fbmem + exaGetPixmapOffset(pDst);
2669a5ed1c5Smacallan	int    dst_pitch  = exaGetPixmapPitch(pDst);
267be1ef3d3Smacallan
2689a5ed1c5Smacallan	int bpp    = pDst->drawable.bitsPerPixel;
269727ce256Smacallan	int cpp    = (bpp + 7) >> 3;
2709a5ed1c5Smacallan	int wBytes = w * cpp;
271be1ef3d3Smacallan
2729a5ed1c5Smacallan	ENTER;
2739a5ed1c5Smacallan	dst += (x * cpp) + (y * dst_pitch);
274be1ef3d3Smacallan
275727ce256Smacallan	IgsWaitReady(fPtr);
276727ce256Smacallan
2779a5ed1c5Smacallan	while (h--) {
2789a5ed1c5Smacallan		memcpy(dst, src, wBytes);
2799a5ed1c5Smacallan		src += src_pitch;
2809a5ed1c5Smacallan		dst += dst_pitch;
2819a5ed1c5Smacallan	}
2829a5ed1c5Smacallan	LEAVE;
2839a5ed1c5Smacallan	return TRUE;
284be1ef3d3Smacallan}
285be1ef3d3Smacallan
286be1ef3d3Smacallan/*
287be1ef3d3Smacallan * Memcpy-based DFS.
288be1ef3d3Smacallan */
289be1ef3d3Smacallanstatic Bool
290be1ef3d3SmacallanIgsDownloadFromScreen(PixmapPtr pSrc, int x, int y, int w, int h,
291be1ef3d3Smacallan    char *dst, int dst_pitch)
292be1ef3d3Smacallan{
2939a5ed1c5Smacallan	ScrnInfoPtr pScrn = xf86Screens[pSrc->drawable.pScreen->myNum];
2949a5ed1c5Smacallan	IgsPtr fPtr = IGSPTR(pScrn);
2959a5ed1c5Smacallan	char  *src        = fPtr->fbmem + exaGetPixmapOffset(pSrc);
2969a5ed1c5Smacallan	int    src_pitch  = exaGetPixmapPitch(pSrc);
297be1ef3d3Smacallan
2989a5ed1c5Smacallan	int bpp    = pSrc->drawable.bitsPerPixel;
299727ce256Smacallan	int cpp    = (bpp + 7) >> 3;
3009a5ed1c5Smacallan	int wBytes = w * cpp;
301be1ef3d3Smacallan
3029a5ed1c5Smacallan	ENTER;
3039a5ed1c5Smacallan	src += (x * cpp) + (y * src_pitch);
304be1ef3d3Smacallan
305727ce256Smacallan	IgsWaitReady(fPtr);
306727ce256Smacallan
3079a5ed1c5Smacallan	while (h--) {
3089a5ed1c5Smacallan		memcpy(dst, src, wBytes);
3099a5ed1c5Smacallan		src += src_pitch;
3109a5ed1c5Smacallan		dst += dst_pitch;
3119a5ed1c5Smacallan	}
3129a5ed1c5Smacallan	LEAVE;
3139a5ed1c5Smacallan	return TRUE;
314be1ef3d3Smacallan}
315be1ef3d3Smacallan
31683616484Smacallan#ifdef __arm__
31783616484Smacallanstatic Bool
31883616484SmacallanIgsPrepareAccess(PixmapPtr pPix, int index)
31983616484Smacallan{
32083616484Smacallan	ScrnInfoPtr pScrn = xf86Screens[pPix->drawable.pScreen->myNum];
32183616484Smacallan	IgsPtr fPtr = IGSPTR(pScrn);
32283616484Smacallan
32383616484Smacallan	IgsWaitReady(fPtr);
32483616484Smacallan	return TRUE;
32583616484Smacallan}
32683616484Smacallan
32783616484Smacallanstatic void
32883616484SmacallanIgsFinishAccess(PixmapPtr pPix, int index)
32983616484Smacallan{
33083616484Smacallan}
33183616484Smacallan#endif
33283616484Smacallan
333be1ef3d3SmacallanBool
334be1ef3d3SmacallanIgsInitAccel(ScreenPtr pScreen)
335be1ef3d3Smacallan{
3369a5ed1c5Smacallan	ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
3379a5ed1c5Smacallan	IgsPtr fPtr = IGSPTR(pScrn);
3389a5ed1c5Smacallan	ExaDriverPtr pExa;
3399a5ed1c5Smacallan
3409a5ed1c5Smacallan	pExa = exaDriverAlloc();
3419a5ed1c5Smacallan	if (!pExa)
3429a5ed1c5Smacallan		return FALSE;
3439a5ed1c5Smacallan
3449a5ed1c5Smacallan	fPtr->pExa = pExa;
3459a5ed1c5Smacallan
3469a5ed1c5Smacallan	pExa->exa_major = EXA_VERSION_MAJOR;
3479a5ed1c5Smacallan	pExa->exa_minor = EXA_VERSION_MINOR;
3489a5ed1c5Smacallan
3499a5ed1c5Smacallan	pExa->memoryBase = fPtr->fbmem;
350be1ef3d3Smacallan	pExa->memorySize = fPtr->fbmem_len;
351be1ef3d3Smacallan	pExa->offScreenBase = fPtr->linebytes * fPtr->info.height;
352be1ef3d3Smacallan	pExa->pixmapOffsetAlign = 4;
353be1ef3d3Smacallan	pExa->pixmapPitchAlign = 4;
354be1ef3d3Smacallan
3559a5ed1c5Smacallan	pExa->flags = EXA_OFFSCREEN_PIXMAPS;
356be1ef3d3Smacallan
3579a5ed1c5Smacallan	pExa->maxX = 2048;
3589a5ed1c5Smacallan	pExa->maxY = 2048;
359be1ef3d3Smacallan
3609a5ed1c5Smacallan	pExa->MarkSync = IgsMarkSync;
3619a5ed1c5Smacallan	pExa->WaitMarker = IgsWaitMarker;
3629a5ed1c5Smacallan	pExa->PrepareSolid = IgsPrepareSolid;
3639a5ed1c5Smacallan	pExa->Solid = IgsSolid;
3649a5ed1c5Smacallan	pExa->DoneSolid = IgsDoneCopy;
3659a5ed1c5Smacallan	pExa->PrepareCopy = IgsPrepareCopy;
3669a5ed1c5Smacallan	pExa->Copy = IgsCopy;
3679a5ed1c5Smacallan	pExa->DoneCopy = IgsDoneCopy;
368be1ef3d3Smacallan
369be1ef3d3Smacallan	switch(fPtr->info.depth) {
370be1ef3d3Smacallan		case 8:
371be1ef3d3Smacallan			fPtr->shift = 0;
372727ce256Smacallan			fPtr->mapfmt = IGS_COP_MAP_8BPP;
373be1ef3d3Smacallan			break;
374be1ef3d3Smacallan		case 16:
375be1ef3d3Smacallan			fPtr->shift = 1;
376727ce256Smacallan			fPtr->mapfmt = IGS_COP_MAP_16BPP;
377be1ef3d3Smacallan			break;
378727ce256Smacallan		case 24:
379be1ef3d3Smacallan		case 32:
380be1ef3d3Smacallan			fPtr->shift = 2;
381727ce256Smacallan			fPtr->mapfmt = IGS_COP_MAP_32BPP;
382be1ef3d3Smacallan			break;
383727ce256Smacallan		default:
384727ce256Smacallan			ErrorF("Unsupported depth: %d\n", fPtr->info.depth);
385be1ef3d3Smacallan	}
386727ce256Smacallan	IgsWrite1(fPtr, IGS_COP_MAP_FMT_REG, fPtr->mapfmt);
387727ce256Smacallan
3889a5ed1c5Smacallan	/* EXA hits more optimized paths when it does not have to fallback
3899a5ed1c5Smacallan	 * because of missing UTS/DFS, hook memcpy-based UTS/DFS.
3909a5ed1c5Smacallan	 */
3919a5ed1c5Smacallan	pExa->UploadToScreen = IgsUploadToScreen;
3929a5ed1c5Smacallan	pExa->DownloadFromScreen = IgsDownloadFromScreen;
39383616484Smacallan#ifdef __arm__
39483616484Smacallan	pExa->PrepareAccess = IgsPrepareAccess;
39583616484Smacallan	pExa->FinishAccess = IgsFinishAccess;
39683616484Smacallan#endif
3979a5ed1c5Smacallan	return exaDriverInit(pScreen, pExa);
398be1ef3d3Smacallan}
399