xref: /aosp_15_r20/external/igt-gpu-tools/tests/prime_nv_pcopy.c (revision d83cc019efdc2edc6c4b16e9034a3ceb8d35d77c)
1*d83cc019SAndroid Build Coastguard Worker /* basic set of prime tests between intel and nouveau */
2*d83cc019SAndroid Build Coastguard Worker 
3*d83cc019SAndroid Build Coastguard Worker /* test list -
4*d83cc019SAndroid Build Coastguard Worker    1. share buffer from intel -> nouveau.
5*d83cc019SAndroid Build Coastguard Worker    2. share buffer from nouveau -> intel
6*d83cc019SAndroid Build Coastguard Worker    3. share intel->nouveau, map on both, write intel, read nouveau
7*d83cc019SAndroid Build Coastguard Worker    4. share intel->nouveau, blit intel fill, readback on nouveau
8*d83cc019SAndroid Build Coastguard Worker    test 1 + map buffer, read/write, map other size.
9*d83cc019SAndroid Build Coastguard Worker    do some hw actions on the buffer
10*d83cc019SAndroid Build Coastguard Worker    some illegal operations -
11*d83cc019SAndroid Build Coastguard Worker        close prime fd try and map
12*d83cc019SAndroid Build Coastguard Worker 
13*d83cc019SAndroid Build Coastguard Worker    TODO add some nouveau rendering tests
14*d83cc019SAndroid Build Coastguard Worker */
15*d83cc019SAndroid Build Coastguard Worker 
16*d83cc019SAndroid Build Coastguard Worker 
17*d83cc019SAndroid Build Coastguard Worker #include "igt.h"
18*d83cc019SAndroid Build Coastguard Worker #include <inttypes.h>
19*d83cc019SAndroid Build Coastguard Worker #include <stdio.h>
20*d83cc019SAndroid Build Coastguard Worker #include <stdlib.h>
21*d83cc019SAndroid Build Coastguard Worker #include <unistd.h>
22*d83cc019SAndroid Build Coastguard Worker #include <fcntl.h>
23*d83cc019SAndroid Build Coastguard Worker #include <string.h>
24*d83cc019SAndroid Build Coastguard Worker #include <sys/stat.h>
25*d83cc019SAndroid Build Coastguard Worker #include <sys/ioctl.h>
26*d83cc019SAndroid Build Coastguard Worker #include <errno.h>
27*d83cc019SAndroid Build Coastguard Worker 
28*d83cc019SAndroid Build Coastguard Worker #include "intel_bufmgr.h"
29*d83cc019SAndroid Build Coastguard Worker #include "nouveau.h"
30*d83cc019SAndroid Build Coastguard Worker 
31*d83cc019SAndroid Build Coastguard Worker static int intel_fd = -1, nouveau_fd = -1;
32*d83cc019SAndroid Build Coastguard Worker static drm_intel_bufmgr *bufmgr;
33*d83cc019SAndroid Build Coastguard Worker static struct nouveau_device *ndev;
34*d83cc019SAndroid Build Coastguard Worker static struct nouveau_client *nclient;
35*d83cc019SAndroid Build Coastguard Worker static uint32_t devid;
36*d83cc019SAndroid Build Coastguard Worker static struct intel_batchbuffer *batch;
37*d83cc019SAndroid Build Coastguard Worker static struct nouveau_object *nchannel, *pcopy;
38*d83cc019SAndroid Build Coastguard Worker static struct nouveau_bufctx *nbufctx;
39*d83cc019SAndroid Build Coastguard Worker static struct nouveau_pushbuf *npush;
40*d83cc019SAndroid Build Coastguard Worker 
41*d83cc019SAndroid Build Coastguard Worker static struct nouveau_bo *query_bo;
42*d83cc019SAndroid Build Coastguard Worker static uint32_t query_counter;
43*d83cc019SAndroid Build Coastguard Worker static volatile uint32_t *query;
44*d83cc019SAndroid Build Coastguard Worker static uint32_t memtype_intel, tile_intel_y, tile_intel_x;
45*d83cc019SAndroid Build Coastguard Worker 
46*d83cc019SAndroid Build Coastguard Worker #define SUBC_COPY(x) 6, (x)
47*d83cc019SAndroid Build Coastguard Worker #define NV01_SUBCHAN_OBJECT 0
48*d83cc019SAndroid Build Coastguard Worker 
49*d83cc019SAndroid Build Coastguard Worker #define NV01_SUBC(subc, mthd) SUBC_##subc((NV01_SUBCHAN_##mthd))
50*d83cc019SAndroid Build Coastguard Worker 
51*d83cc019SAndroid Build Coastguard Worker typedef struct {
52*d83cc019SAndroid Build Coastguard Worker 	uint32_t w, h;
53*d83cc019SAndroid Build Coastguard Worker 	uint32_t pitch, lines;
54*d83cc019SAndroid Build Coastguard Worker } rect;
55*d83cc019SAndroid Build Coastguard Worker 
nv_bo_alloc(struct nouveau_bo ** bo,rect * r,uint32_t w,uint32_t h,uint32_t tile_mode,int handle,uint32_t dom)56*d83cc019SAndroid Build Coastguard Worker static void nv_bo_alloc(struct nouveau_bo **bo, rect *r,
57*d83cc019SAndroid Build Coastguard Worker 			uint32_t w, uint32_t h, uint32_t tile_mode,
58*d83cc019SAndroid Build Coastguard Worker 			int handle, uint32_t dom)
59*d83cc019SAndroid Build Coastguard Worker {
60*d83cc019SAndroid Build Coastguard Worker 	uint32_t size;
61*d83cc019SAndroid Build Coastguard Worker 	uint32_t dx = 1, dy = 1, memtype = 0;
62*d83cc019SAndroid Build Coastguard Worker 
63*d83cc019SAndroid Build Coastguard Worker 	*bo = NULL;
64*d83cc019SAndroid Build Coastguard Worker 	if (tile_mode) {
65*d83cc019SAndroid Build Coastguard Worker 		uint32_t tile_y;
66*d83cc019SAndroid Build Coastguard Worker 		uint32_t tile_x;
67*d83cc019SAndroid Build Coastguard Worker 
68*d83cc019SAndroid Build Coastguard Worker 		/* Y major tiling */
69*d83cc019SAndroid Build Coastguard Worker 		if ((tile_mode & 0xf) == 0xe)
70*d83cc019SAndroid Build Coastguard Worker 			/* but the internal layout is different */
71*d83cc019SAndroid Build Coastguard Worker 			tile_x = 7;
72*d83cc019SAndroid Build Coastguard Worker 		else
73*d83cc019SAndroid Build Coastguard Worker 			tile_x = 6 + (tile_mode & 0xf);
74*d83cc019SAndroid Build Coastguard Worker 		if (ndev->chipset < 0xc0) {
75*d83cc019SAndroid Build Coastguard Worker 			memtype = 0x70;
76*d83cc019SAndroid Build Coastguard Worker 			tile_y = 2;
77*d83cc019SAndroid Build Coastguard Worker 		} else {
78*d83cc019SAndroid Build Coastguard Worker 			memtype = 0xfe;
79*d83cc019SAndroid Build Coastguard Worker 			tile_y = 3;
80*d83cc019SAndroid Build Coastguard Worker 		}
81*d83cc019SAndroid Build Coastguard Worker 		if ((tile_mode & 0xf) == 0xe)
82*d83cc019SAndroid Build Coastguard Worker 			memtype = memtype_intel;
83*d83cc019SAndroid Build Coastguard Worker 		tile_y += ((tile_mode & 0xf0)>>4);
84*d83cc019SAndroid Build Coastguard Worker 
85*d83cc019SAndroid Build Coastguard Worker 		dx = 1 << tile_x;
86*d83cc019SAndroid Build Coastguard Worker 		dy = 1 << tile_y;
87*d83cc019SAndroid Build Coastguard Worker 		igt_debug("Tiling requirements: x y %u %u\n", dx, dy);
88*d83cc019SAndroid Build Coastguard Worker 	}
89*d83cc019SAndroid Build Coastguard Worker 
90*d83cc019SAndroid Build Coastguard Worker 	r->w = w;
91*d83cc019SAndroid Build Coastguard Worker 	r->h = h;
92*d83cc019SAndroid Build Coastguard Worker 
93*d83cc019SAndroid Build Coastguard Worker 	r->pitch = w = (w + dx-1) & ~(dx-1);
94*d83cc019SAndroid Build Coastguard Worker 	r->lines = h = (h + dy-1) & ~(dy-1);
95*d83cc019SAndroid Build Coastguard Worker 	size = w*h;
96*d83cc019SAndroid Build Coastguard Worker 
97*d83cc019SAndroid Build Coastguard Worker 	if (handle < 0) {
98*d83cc019SAndroid Build Coastguard Worker 		union nouveau_bo_config cfg;
99*d83cc019SAndroid Build Coastguard Worker 		cfg.nv50.memtype = memtype;
100*d83cc019SAndroid Build Coastguard Worker 		cfg.nv50.tile_mode = tile_mode;
101*d83cc019SAndroid Build Coastguard Worker 		if (dom == NOUVEAU_BO_GART)
102*d83cc019SAndroid Build Coastguard Worker 			dom |= NOUVEAU_BO_MAP;
103*d83cc019SAndroid Build Coastguard Worker 		igt_assert(nouveau_bo_new(ndev, dom, 4096, size, &cfg, bo) == 0);
104*d83cc019SAndroid Build Coastguard Worker 		igt_assert(nouveau_bo_map(*bo, NOUVEAU_BO_RDWR, nclient) == 0);
105*d83cc019SAndroid Build Coastguard Worker 
106*d83cc019SAndroid Build Coastguard Worker 		igt_debug("new flags %08x memtype %08x tile %08x\n",
107*d83cc019SAndroid Build Coastguard Worker 			  (*bo)->flags, (*bo)->config.nv50.memtype,
108*d83cc019SAndroid Build Coastguard Worker 			  (*bo)->config.nv50.tile_mode);
109*d83cc019SAndroid Build Coastguard Worker 		if (tile_mode == tile_intel_y || tile_mode == tile_intel_x) {
110*d83cc019SAndroid Build Coastguard Worker 			igt_debug("tile mode was: %02x, now: %02x\n",
111*d83cc019SAndroid Build Coastguard Worker 				  (*bo)->config.nv50.tile_mode, tile_mode);
112*d83cc019SAndroid Build Coastguard Worker 			/* Doesn't like intel tiling much.. */
113*d83cc019SAndroid Build Coastguard Worker 			(*bo)->config.nv50.tile_mode = tile_mode;
114*d83cc019SAndroid Build Coastguard Worker 		}
115*d83cc019SAndroid Build Coastguard Worker 	} else {
116*d83cc019SAndroid Build Coastguard Worker 		igt_assert(nouveau_bo_prime_handle_ref(ndev, handle, bo) == 0);
117*d83cc019SAndroid Build Coastguard Worker 		close(handle);
118*d83cc019SAndroid Build Coastguard Worker 		igt_assert_f((*bo)->size >= size,
119*d83cc019SAndroid Build Coastguard Worker 			     "expected bo size to be at least %u,"
120*d83cc019SAndroid Build Coastguard Worker 			     "but received %"PRIu64"\n", size, (*bo)->size);
121*d83cc019SAndroid Build Coastguard Worker 		igt_debug("prime flags %08x memtype %08x tile %08x\n",
122*d83cc019SAndroid Build Coastguard Worker 			  (*bo)->flags, (*bo)->config.nv50.memtype,
123*d83cc019SAndroid Build Coastguard Worker 			  (*bo)->config.nv50.tile_mode);
124*d83cc019SAndroid Build Coastguard Worker 		(*bo)->config.nv50.memtype = memtype;
125*d83cc019SAndroid Build Coastguard Worker 		(*bo)->config.nv50.tile_mode = tile_mode;
126*d83cc019SAndroid Build Coastguard Worker 	}
127*d83cc019SAndroid Build Coastguard Worker 	igt_debug("size: %"PRIu64"\n", (*bo)->size);
128*d83cc019SAndroid Build Coastguard Worker }
129*d83cc019SAndroid Build Coastguard Worker 
130*d83cc019SAndroid Build Coastguard Worker static inline void
PUSH_DATA(struct nouveau_pushbuf * push,uint32_t data)131*d83cc019SAndroid Build Coastguard Worker PUSH_DATA(struct nouveau_pushbuf *push, uint32_t data)
132*d83cc019SAndroid Build Coastguard Worker {
133*d83cc019SAndroid Build Coastguard Worker 	*push->cur++ = data;
134*d83cc019SAndroid Build Coastguard Worker }
135*d83cc019SAndroid Build Coastguard Worker 
136*d83cc019SAndroid Build Coastguard Worker static inline void
BEGIN_NV04(struct nouveau_pushbuf * push,int subc,int mthd,int size)137*d83cc019SAndroid Build Coastguard Worker BEGIN_NV04(struct nouveau_pushbuf *push, int subc, int mthd, int size)
138*d83cc019SAndroid Build Coastguard Worker {
139*d83cc019SAndroid Build Coastguard Worker 	PUSH_DATA (push, 0x00000000 | (size << 18) | (subc << 13) | mthd);
140*d83cc019SAndroid Build Coastguard Worker }
141*d83cc019SAndroid Build Coastguard Worker 
142*d83cc019SAndroid Build Coastguard Worker static inline void
BEGIN_NI04(struct nouveau_pushbuf * push,int subc,int mthd,int size)143*d83cc019SAndroid Build Coastguard Worker BEGIN_NI04(struct nouveau_pushbuf *push, int subc, int mthd, int size)
144*d83cc019SAndroid Build Coastguard Worker {
145*d83cc019SAndroid Build Coastguard Worker 	PUSH_DATA (push, 0x40000000 | (size << 18) | (subc << 13) | mthd);
146*d83cc019SAndroid Build Coastguard Worker }
147*d83cc019SAndroid Build Coastguard Worker 
148*d83cc019SAndroid Build Coastguard Worker static inline void
BEGIN_NVC0(struct nouveau_pushbuf * push,int subc,int mthd,int size)149*d83cc019SAndroid Build Coastguard Worker BEGIN_NVC0(struct nouveau_pushbuf *push, int subc, int mthd, int size)
150*d83cc019SAndroid Build Coastguard Worker {
151*d83cc019SAndroid Build Coastguard Worker 	PUSH_DATA (push, 0x20000000 | (size << 16) | (subc << 13) | (mthd / 4));
152*d83cc019SAndroid Build Coastguard Worker }
153*d83cc019SAndroid Build Coastguard Worker 
154*d83cc019SAndroid Build Coastguard Worker static inline void
BEGIN_NVXX(struct nouveau_pushbuf * push,int subc,int mthd,int size)155*d83cc019SAndroid Build Coastguard Worker BEGIN_NVXX(struct nouveau_pushbuf *push, int subc, int mthd, int size)
156*d83cc019SAndroid Build Coastguard Worker {
157*d83cc019SAndroid Build Coastguard Worker 	if (ndev->chipset < 0xc0)
158*d83cc019SAndroid Build Coastguard Worker 		BEGIN_NV04(push, subc, mthd, size);
159*d83cc019SAndroid Build Coastguard Worker 	else
160*d83cc019SAndroid Build Coastguard Worker 		BEGIN_NVC0(push, subc, mthd, size);
161*d83cc019SAndroid Build Coastguard Worker }
162*d83cc019SAndroid Build Coastguard Worker 
163*d83cc019SAndroid Build Coastguard Worker static void
noop_intel(drm_intel_bo * bo)164*d83cc019SAndroid Build Coastguard Worker noop_intel(drm_intel_bo *bo)
165*d83cc019SAndroid Build Coastguard Worker {
166*d83cc019SAndroid Build Coastguard Worker 	BEGIN_BATCH(3, 1);
167*d83cc019SAndroid Build Coastguard Worker 	OUT_BATCH(MI_NOOP);
168*d83cc019SAndroid Build Coastguard Worker 	OUT_BATCH(MI_BATCH_BUFFER_END);
169*d83cc019SAndroid Build Coastguard Worker 	OUT_RELOC(bo, I915_GEM_DOMAIN_RENDER,
170*d83cc019SAndroid Build Coastguard Worker 			I915_GEM_DOMAIN_RENDER, 0);
171*d83cc019SAndroid Build Coastguard Worker 	ADVANCE_BATCH();
172*d83cc019SAndroid Build Coastguard Worker 
173*d83cc019SAndroid Build Coastguard Worker 	intel_batchbuffer_flush(batch);
174*d83cc019SAndroid Build Coastguard Worker }
175*d83cc019SAndroid Build Coastguard Worker 
find_and_open_devices(void)176*d83cc019SAndroid Build Coastguard Worker static void find_and_open_devices(void)
177*d83cc019SAndroid Build Coastguard Worker {
178*d83cc019SAndroid Build Coastguard Worker 	int i;
179*d83cc019SAndroid Build Coastguard Worker 	char path[80], *unused;
180*d83cc019SAndroid Build Coastguard Worker 	struct stat buf;
181*d83cc019SAndroid Build Coastguard Worker 	FILE *fl;
182*d83cc019SAndroid Build Coastguard Worker 	char vendor_id[8] = {};
183*d83cc019SAndroid Build Coastguard Worker 	int venid;
184*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < 9; i++) {
185*d83cc019SAndroid Build Coastguard Worker 		sprintf(path, "/sys/class/drm/card%d/device/vendor", i);
186*d83cc019SAndroid Build Coastguard Worker 		if (stat(path, &buf))
187*d83cc019SAndroid Build Coastguard Worker 			break;
188*d83cc019SAndroid Build Coastguard Worker 
189*d83cc019SAndroid Build Coastguard Worker 		fl = fopen(path, "r");
190*d83cc019SAndroid Build Coastguard Worker 		if (!fl)
191*d83cc019SAndroid Build Coastguard Worker 			break;
192*d83cc019SAndroid Build Coastguard Worker 
193*d83cc019SAndroid Build Coastguard Worker 		unused = fgets(vendor_id, sizeof(vendor_id)-1, fl);
194*d83cc019SAndroid Build Coastguard Worker 		(void)unused;
195*d83cc019SAndroid Build Coastguard Worker 		fclose(fl);
196*d83cc019SAndroid Build Coastguard Worker 
197*d83cc019SAndroid Build Coastguard Worker 		venid = strtoul(vendor_id, NULL, 16);
198*d83cc019SAndroid Build Coastguard Worker 		sprintf(path, "/dev/dri/card%d", i);
199*d83cc019SAndroid Build Coastguard Worker 		if (venid == 0x8086) {
200*d83cc019SAndroid Build Coastguard Worker 			intel_fd = open(path, O_RDWR);
201*d83cc019SAndroid Build Coastguard Worker 			igt_assert(intel_fd);
202*d83cc019SAndroid Build Coastguard Worker 		} else if (venid == 0x10de) {
203*d83cc019SAndroid Build Coastguard Worker 			nouveau_fd = open(path, O_RDWR);
204*d83cc019SAndroid Build Coastguard Worker 			igt_assert(nouveau_fd);
205*d83cc019SAndroid Build Coastguard Worker 		}
206*d83cc019SAndroid Build Coastguard Worker 	}
207*d83cc019SAndroid Build Coastguard Worker }
208*d83cc019SAndroid Build Coastguard Worker 
init_nouveau(void)209*d83cc019SAndroid Build Coastguard Worker static void init_nouveau(void)
210*d83cc019SAndroid Build Coastguard Worker {
211*d83cc019SAndroid Build Coastguard Worker 	struct nv04_fifo nv04_data = { .vram = 0xbeef0201,
212*d83cc019SAndroid Build Coastguard Worker 				       .gart = 0xbeef0202 };
213*d83cc019SAndroid Build Coastguard Worker 	struct nvc0_fifo nvc0_data = { };
214*d83cc019SAndroid Build Coastguard Worker 	struct nouveau_fifo *fifo;
215*d83cc019SAndroid Build Coastguard Worker 	int size;
216*d83cc019SAndroid Build Coastguard Worker 	uint32_t class;
217*d83cc019SAndroid Build Coastguard Worker 	void *data;
218*d83cc019SAndroid Build Coastguard Worker 
219*d83cc019SAndroid Build Coastguard Worker 	igt_assert(nouveau_device_wrap(nouveau_fd, 0, &ndev) == 0);
220*d83cc019SAndroid Build Coastguard Worker 
221*d83cc019SAndroid Build Coastguard Worker 	igt_assert(nouveau_client_new(ndev, &nclient) == 0);
222*d83cc019SAndroid Build Coastguard Worker 
223*d83cc019SAndroid Build Coastguard Worker 	igt_skip_on_f(ndev->chipset < 0xa3 || ndev->chipset == 0xaa || ndev->chipset == 0xac,
224*d83cc019SAndroid Build Coastguard Worker 		      "Your card doesn't support PCOPY\n");
225*d83cc019SAndroid Build Coastguard Worker 
226*d83cc019SAndroid Build Coastguard Worker 	// TODO: Get a kepler and add support for it
227*d83cc019SAndroid Build Coastguard Worker 	igt_skip_on_f(ndev->chipset >= 0xe0,
228*d83cc019SAndroid Build Coastguard Worker 		      "Unsure how kepler works!\n");
229*d83cc019SAndroid Build Coastguard Worker 	igt_assert(nouveau_bo_new(ndev,  NOUVEAU_BO_GART | NOUVEAU_BO_MAP,
230*d83cc019SAndroid Build Coastguard Worker 				  4096, 4096, NULL, &query_bo) == 0);
231*d83cc019SAndroid Build Coastguard Worker 	igt_assert(nouveau_bo_map(query_bo, NOUVEAU_BO_RDWR, nclient) == 0);
232*d83cc019SAndroid Build Coastguard Worker 	query = query_bo->map;
233*d83cc019SAndroid Build Coastguard Worker 	*query = query_counter;
234*d83cc019SAndroid Build Coastguard Worker 
235*d83cc019SAndroid Build Coastguard Worker 	if (ndev->chipset < 0xc0) {
236*d83cc019SAndroid Build Coastguard Worker 		class = 0x85b5;
237*d83cc019SAndroid Build Coastguard Worker 		data = &nv04_data;
238*d83cc019SAndroid Build Coastguard Worker 		size = sizeof(nv04_data);
239*d83cc019SAndroid Build Coastguard Worker 	} else {
240*d83cc019SAndroid Build Coastguard Worker 		class = ndev->chipset < 0xe0 ? 0x490b5 : 0xa0b5;
241*d83cc019SAndroid Build Coastguard Worker 		data = &nvc0_data;
242*d83cc019SAndroid Build Coastguard Worker 		size = sizeof(nvc0_data);
243*d83cc019SAndroid Build Coastguard Worker 	}
244*d83cc019SAndroid Build Coastguard Worker 
245*d83cc019SAndroid Build Coastguard Worker 	igt_assert(nouveau_object_new(&ndev->object, 0, NOUVEAU_FIFO_CHANNEL_CLASS,
246*d83cc019SAndroid Build Coastguard Worker 				      data, size, &nchannel) == 0);
247*d83cc019SAndroid Build Coastguard Worker 
248*d83cc019SAndroid Build Coastguard Worker 	fifo = nchannel->data;
249*d83cc019SAndroid Build Coastguard Worker 
250*d83cc019SAndroid Build Coastguard Worker 	igt_assert(nouveau_pushbuf_new(nclient, nchannel, 4, 32 * 1024,
251*d83cc019SAndroid Build Coastguard Worker 				       true, &npush) == 0);
252*d83cc019SAndroid Build Coastguard Worker 
253*d83cc019SAndroid Build Coastguard Worker 	igt_assert(nouveau_bufctx_new(nclient, 1, &nbufctx) == 0);
254*d83cc019SAndroid Build Coastguard Worker 
255*d83cc019SAndroid Build Coastguard Worker 	npush->user_priv = nbufctx;
256*d83cc019SAndroid Build Coastguard Worker 
257*d83cc019SAndroid Build Coastguard Worker 	/* Hope this is enough init for PCOPY */
258*d83cc019SAndroid Build Coastguard Worker 	igt_assert(nouveau_object_new(nchannel, class, class & 0xffff, NULL, 0, &pcopy) == 0);
259*d83cc019SAndroid Build Coastguard Worker 	igt_assert(nouveau_pushbuf_space(npush, 512, 0, 0) == 0);
260*d83cc019SAndroid Build Coastguard Worker 
261*d83cc019SAndroid Build Coastguard Worker 	if (ndev->chipset < 0xc0) {
262*d83cc019SAndroid Build Coastguard Worker 		struct nv04_fifo *nv04_fifo = (struct nv04_fifo*)fifo;
263*d83cc019SAndroid Build Coastguard Worker 		tile_intel_y = 0x3e;
264*d83cc019SAndroid Build Coastguard Worker 		tile_intel_x = 0x13;
265*d83cc019SAndroid Build Coastguard Worker 
266*d83cc019SAndroid Build Coastguard Worker 		BEGIN_NV04(npush, NV01_SUBC(COPY, OBJECT), 1);
267*d83cc019SAndroid Build Coastguard Worker 		PUSH_DATA(npush, pcopy->handle);
268*d83cc019SAndroid Build Coastguard Worker 		BEGIN_NV04(npush, SUBC_COPY(0x0180), 3);
269*d83cc019SAndroid Build Coastguard Worker 		PUSH_DATA(npush, nv04_fifo->vram);
270*d83cc019SAndroid Build Coastguard Worker 		PUSH_DATA(npush, nv04_fifo->vram);
271*d83cc019SAndroid Build Coastguard Worker 		PUSH_DATA(npush, nv04_fifo->vram);
272*d83cc019SAndroid Build Coastguard Worker 	} else {
273*d83cc019SAndroid Build Coastguard Worker 		tile_intel_y = 0x2e;
274*d83cc019SAndroid Build Coastguard Worker 		tile_intel_x = 0x03;
275*d83cc019SAndroid Build Coastguard Worker 		BEGIN_NVC0(npush, NV01_SUBC(COPY, OBJECT), 1);
276*d83cc019SAndroid Build Coastguard Worker 		PUSH_DATA(npush, pcopy->handle);
277*d83cc019SAndroid Build Coastguard Worker 	}
278*d83cc019SAndroid Build Coastguard Worker 	nouveau_pushbuf_kick(npush, npush->channel);
279*d83cc019SAndroid Build Coastguard Worker }
280*d83cc019SAndroid Build Coastguard Worker 
fill16(void * ptr,uint32_t val)281*d83cc019SAndroid Build Coastguard Worker static void fill16(void *ptr, uint32_t val)
282*d83cc019SAndroid Build Coastguard Worker {
283*d83cc019SAndroid Build Coastguard Worker 	uint32_t *p = ptr;
284*d83cc019SAndroid Build Coastguard Worker 	val = (val) | (val << 8) | (val << 16) | (val << 24);
285*d83cc019SAndroid Build Coastguard Worker 	p[0] = p[1] = p[2] = p[3] = val;
286*d83cc019SAndroid Build Coastguard Worker }
287*d83cc019SAndroid Build Coastguard Worker 
288*d83cc019SAndroid Build Coastguard Worker #define TILE_SIZE 4096
289*d83cc019SAndroid Build Coastguard Worker 
swtile_y(uint8_t * out,const uint8_t * in,int w,int h)290*d83cc019SAndroid Build Coastguard Worker static void swtile_y(uint8_t *out, const uint8_t *in, int w, int h)
291*d83cc019SAndroid Build Coastguard Worker {
292*d83cc019SAndroid Build Coastguard Worker 	uint32_t x, y, dx, dy;
293*d83cc019SAndroid Build Coastguard Worker 	uint8_t *endptr = out + w * h;
294*d83cc019SAndroid Build Coastguard Worker 	igt_assert(!(w % 128));
295*d83cc019SAndroid Build Coastguard Worker 	igt_assert(!(h % 32));
296*d83cc019SAndroid Build Coastguard Worker 
297*d83cc019SAndroid Build Coastguard Worker 	for (y = 0; y < h; y += 32) {
298*d83cc019SAndroid Build Coastguard Worker 		for (x = 0; x < w; x += 128, out += TILE_SIZE) {
299*d83cc019SAndroid Build Coastguard Worker 			for (dx = 0; dx < 8; ++dx) {
300*d83cc019SAndroid Build Coastguard Worker 				for (dy = 0; dy < 32; ++dy) {
301*d83cc019SAndroid Build Coastguard Worker 					uint32_t out_ofs = (dx * 32 + dy) * 16;
302*d83cc019SAndroid Build Coastguard Worker 					uint32_t in_ofs = (y + dy) * w + (x + 16 * dx);
303*d83cc019SAndroid Build Coastguard Worker 					igt_assert(out_ofs < TILE_SIZE);
304*d83cc019SAndroid Build Coastguard Worker 					igt_assert(in_ofs < w*h);
305*d83cc019SAndroid Build Coastguard Worker 
306*d83cc019SAndroid Build Coastguard Worker 					// To do the Y tiling quirk:
307*d83cc019SAndroid Build Coastguard Worker 					// out_ofs = out_ofs ^ (((out_ofs >> 9) & 1) << 6);
308*d83cc019SAndroid Build Coastguard Worker 					memcpy(&out[out_ofs], &in[in_ofs], 16);
309*d83cc019SAndroid Build Coastguard Worker 				}
310*d83cc019SAndroid Build Coastguard Worker 			}
311*d83cc019SAndroid Build Coastguard Worker 		}
312*d83cc019SAndroid Build Coastguard Worker 	}
313*d83cc019SAndroid Build Coastguard Worker 	igt_assert(out == endptr);
314*d83cc019SAndroid Build Coastguard Worker }
315*d83cc019SAndroid Build Coastguard Worker 
swtile_x(uint8_t * out,const uint8_t * in,int w,int h)316*d83cc019SAndroid Build Coastguard Worker static void swtile_x(uint8_t *out, const uint8_t *in, int w, int h)
317*d83cc019SAndroid Build Coastguard Worker {
318*d83cc019SAndroid Build Coastguard Worker 	uint32_t x, y, dy;
319*d83cc019SAndroid Build Coastguard Worker 	uint8_t *endptr = out + w * h;
320*d83cc019SAndroid Build Coastguard Worker 	igt_assert(!(w % 512));
321*d83cc019SAndroid Build Coastguard Worker 	igt_assert(!(h % 8));
322*d83cc019SAndroid Build Coastguard Worker 
323*d83cc019SAndroid Build Coastguard Worker 	for (y = 0; y < h; y += 8) {
324*d83cc019SAndroid Build Coastguard Worker 		for (x = 0; x < w; x += 512, out += TILE_SIZE) {
325*d83cc019SAndroid Build Coastguard Worker 			for (dy = 0; dy < 8; ++dy) {
326*d83cc019SAndroid Build Coastguard Worker 				uint32_t out_ofs = 512 * dy;
327*d83cc019SAndroid Build Coastguard Worker 				uint32_t in_ofs = (y + dy) * w + x;
328*d83cc019SAndroid Build Coastguard Worker 				igt_assert(out_ofs < TILE_SIZE);
329*d83cc019SAndroid Build Coastguard Worker 				igt_assert(in_ofs < w*h);
330*d83cc019SAndroid Build Coastguard Worker 				memcpy(&out[out_ofs], &in[in_ofs], 512);
331*d83cc019SAndroid Build Coastguard Worker 			}
332*d83cc019SAndroid Build Coastguard Worker 		}
333*d83cc019SAndroid Build Coastguard Worker 	}
334*d83cc019SAndroid Build Coastguard Worker 	igt_assert(out == endptr);
335*d83cc019SAndroid Build Coastguard Worker }
336*d83cc019SAndroid Build Coastguard Worker 
perform_copy(struct nouveau_bo * nvbo,const rect * dst,uint32_t dst_x,uint32_t dst_y,struct nouveau_bo * nvbi,const rect * src,uint32_t src_x,uint32_t src_y,uint32_t w,uint32_t h)337*d83cc019SAndroid Build Coastguard Worker static void perform_copy(struct nouveau_bo *nvbo, const rect *dst,
338*d83cc019SAndroid Build Coastguard Worker 			 uint32_t dst_x, uint32_t dst_y,
339*d83cc019SAndroid Build Coastguard Worker 			 struct nouveau_bo *nvbi, const rect *src,
340*d83cc019SAndroid Build Coastguard Worker 			 uint32_t src_x, uint32_t src_y,
341*d83cc019SAndroid Build Coastguard Worker 			 uint32_t w, uint32_t h)
342*d83cc019SAndroid Build Coastguard Worker {
343*d83cc019SAndroid Build Coastguard Worker 	struct nouveau_pushbuf_refn refs[] = {
344*d83cc019SAndroid Build Coastguard Worker 		{ nvbi, (nvbi->flags & NOUVEAU_BO_APER) | NOUVEAU_BO_RD },
345*d83cc019SAndroid Build Coastguard Worker 		{ nvbo, (nvbo->flags & NOUVEAU_BO_APER) | NOUVEAU_BO_WR },
346*d83cc019SAndroid Build Coastguard Worker 		{ query_bo, NOUVEAU_BO_GART | NOUVEAU_BO_RDWR }
347*d83cc019SAndroid Build Coastguard Worker 	};
348*d83cc019SAndroid Build Coastguard Worker 	uint32_t cpp = 1, exec = 0x00003000; /* QUERY|QUERY_SHORT|FORMAT */
349*d83cc019SAndroid Build Coastguard Worker 	uint32_t src_off = 0, dst_off = 0;
350*d83cc019SAndroid Build Coastguard Worker 	struct nouveau_pushbuf *push = npush;
351*d83cc019SAndroid Build Coastguard Worker 	int ret;
352*d83cc019SAndroid Build Coastguard Worker 
353*d83cc019SAndroid Build Coastguard Worker 	if (nvbi->config.nv50.tile_mode == tile_intel_y)
354*d83cc019SAndroid Build Coastguard Worker 		igt_debug("src is y-tiled\n");
355*d83cc019SAndroid Build Coastguard Worker 	if (nvbo->config.nv50.tile_mode == tile_intel_y)
356*d83cc019SAndroid Build Coastguard Worker 		igt_debug("dst is y-tiled\n");
357*d83cc019SAndroid Build Coastguard Worker 
358*d83cc019SAndroid Build Coastguard Worker 	igt_assert(nouveau_pushbuf_space(push, 64, 0, 0) == 0);
359*d83cc019SAndroid Build Coastguard Worker 	igt_assert(nouveau_pushbuf_refn(push, refs, 3) == 0);
360*d83cc019SAndroid Build Coastguard Worker 
361*d83cc019SAndroid Build Coastguard Worker 	if (!nvbi->config.nv50.tile_mode) {
362*d83cc019SAndroid Build Coastguard Worker 		src_off = src_y * src->pitch + src_x;
363*d83cc019SAndroid Build Coastguard Worker 		exec |= 0x00000010;
364*d83cc019SAndroid Build Coastguard Worker 	}
365*d83cc019SAndroid Build Coastguard Worker 
366*d83cc019SAndroid Build Coastguard Worker 	if (!nvbo->config.nv50.tile_mode) {
367*d83cc019SAndroid Build Coastguard Worker 		dst_off = dst_y * dst->pitch + dst_x;
368*d83cc019SAndroid Build Coastguard Worker 		exec |= 0x00000100;
369*d83cc019SAndroid Build Coastguard Worker 	}
370*d83cc019SAndroid Build Coastguard Worker 
371*d83cc019SAndroid Build Coastguard Worker 	BEGIN_NVXX(push, SUBC_COPY(0x0200), 7);
372*d83cc019SAndroid Build Coastguard Worker 	PUSH_DATA (push, nvbi->config.nv50.tile_mode);
373*d83cc019SAndroid Build Coastguard Worker 	PUSH_DATA (push, src->pitch / cpp);
374*d83cc019SAndroid Build Coastguard Worker 	PUSH_DATA (push, src->h);
375*d83cc019SAndroid Build Coastguard Worker 	PUSH_DATA (push, 1);
376*d83cc019SAndroid Build Coastguard Worker 	PUSH_DATA (push, 0);
377*d83cc019SAndroid Build Coastguard Worker 	PUSH_DATA (push, src_x / cpp);
378*d83cc019SAndroid Build Coastguard Worker 	PUSH_DATA (push, src_y);
379*d83cc019SAndroid Build Coastguard Worker 
380*d83cc019SAndroid Build Coastguard Worker 	BEGIN_NVXX(push, SUBC_COPY(0x0220), 7);
381*d83cc019SAndroid Build Coastguard Worker 	PUSH_DATA (push, nvbo->config.nv50.tile_mode);
382*d83cc019SAndroid Build Coastguard Worker 	PUSH_DATA (push, dst->pitch / cpp);
383*d83cc019SAndroid Build Coastguard Worker 	PUSH_DATA (push, dst->h);
384*d83cc019SAndroid Build Coastguard Worker 	PUSH_DATA (push, 1);
385*d83cc019SAndroid Build Coastguard Worker 	PUSH_DATA (push, 0);
386*d83cc019SAndroid Build Coastguard Worker 	PUSH_DATA (push, dst_x / cpp);
387*d83cc019SAndroid Build Coastguard Worker 	PUSH_DATA (push, dst_y);
388*d83cc019SAndroid Build Coastguard Worker 
389*d83cc019SAndroid Build Coastguard Worker 	BEGIN_NVXX(push, SUBC_COPY(0x030c), 9);
390*d83cc019SAndroid Build Coastguard Worker 	PUSH_DATA (push, (nvbi->offset + src_off) >> 32);
391*d83cc019SAndroid Build Coastguard Worker 	PUSH_DATA (push, (nvbi->offset + src_off));
392*d83cc019SAndroid Build Coastguard Worker 	PUSH_DATA (push, (nvbo->offset + dst_off) >> 32);
393*d83cc019SAndroid Build Coastguard Worker 	PUSH_DATA (push, (nvbo->offset + dst_off));
394*d83cc019SAndroid Build Coastguard Worker 	PUSH_DATA (push, src->pitch);
395*d83cc019SAndroid Build Coastguard Worker 	PUSH_DATA (push, dst->pitch);
396*d83cc019SAndroid Build Coastguard Worker 	PUSH_DATA (push, w / cpp);
397*d83cc019SAndroid Build Coastguard Worker 	PUSH_DATA (push, h);
398*d83cc019SAndroid Build Coastguard Worker 	PUSH_DATA (push, 0x03333120);
399*d83cc019SAndroid Build Coastguard Worker 
400*d83cc019SAndroid Build Coastguard Worker 	BEGIN_NVXX(push, SUBC_COPY(0x0338), 3);
401*d83cc019SAndroid Build Coastguard Worker 	PUSH_DATA (push, (query_bo->offset) >> 32);
402*d83cc019SAndroid Build Coastguard Worker 	PUSH_DATA (push, (query_bo->offset));
403*d83cc019SAndroid Build Coastguard Worker 	PUSH_DATA (push, ++query_counter);
404*d83cc019SAndroid Build Coastguard Worker 
405*d83cc019SAndroid Build Coastguard Worker 	BEGIN_NVXX(push, SUBC_COPY(0x0300), 1);
406*d83cc019SAndroid Build Coastguard Worker 	PUSH_DATA (push, exec);
407*d83cc019SAndroid Build Coastguard Worker 
408*d83cc019SAndroid Build Coastguard Worker 	ret = nouveau_pushbuf_kick(push, push->channel);
409*d83cc019SAndroid Build Coastguard Worker 	while (!ret && *query < query_counter) { usleep(1000); }
410*d83cc019SAndroid Build Coastguard Worker 
411*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(ret, 0);
412*d83cc019SAndroid Build Coastguard Worker }
413*d83cc019SAndroid Build Coastguard Worker 
check1_macro(uint32_t * p,uint32_t w,uint32_t h)414*d83cc019SAndroid Build Coastguard Worker static void check1_macro(uint32_t *p, uint32_t w, uint32_t h)
415*d83cc019SAndroid Build Coastguard Worker {
416*d83cc019SAndroid Build Coastguard Worker 	uint32_t i, val, j;
417*d83cc019SAndroid Build Coastguard Worker 
418*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < 256; ++i, p += 4) {
419*d83cc019SAndroid Build Coastguard Worker 		val = (i) | (i << 8) | (i << 16) | (i << 24);
420*d83cc019SAndroid Build Coastguard Worker 		igt_assert_f(p[0] == val && p[1] == val && p[2] == val && p[3] == val,
421*d83cc019SAndroid Build Coastguard Worker 			     "Retile check failed in first tile!\n"
422*d83cc019SAndroid Build Coastguard Worker 			     "%08x %08x %08x %08x instead of %08x\n",
423*d83cc019SAndroid Build Coastguard Worker 			     p[0], p[1], p[2], p[3], val);
424*d83cc019SAndroid Build Coastguard Worker 	}
425*d83cc019SAndroid Build Coastguard Worker 
426*d83cc019SAndroid Build Coastguard Worker 	val = 0x3e3e3e3e;
427*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < 256 * (w-1); ++i, p += 4) {
428*d83cc019SAndroid Build Coastguard Worker 		igt_assert_f(p[0] == val && p[1] == val && p[2] == val && p[3] == val,
429*d83cc019SAndroid Build Coastguard Worker 			     "Retile check failed in second tile!\n"
430*d83cc019SAndroid Build Coastguard Worker 			     "%08x %08x %08x %08x instead of %08x\n",
431*d83cc019SAndroid Build Coastguard Worker 			     p[0], p[1], p[2], p[3], val);
432*d83cc019SAndroid Build Coastguard Worker 	}
433*d83cc019SAndroid Build Coastguard Worker 
434*d83cc019SAndroid Build Coastguard Worker 	for (j = 1; j < h; ++j) {
435*d83cc019SAndroid Build Coastguard Worker 		val = 0x7e7e7e7e;
436*d83cc019SAndroid Build Coastguard Worker 		for (i = 0; i < 256; ++i, p += 4) {
437*d83cc019SAndroid Build Coastguard Worker 			igt_assert_f(p[0] == val && p[1] == val && p[2] == val && p[3] == val,
438*d83cc019SAndroid Build Coastguard Worker 				     "Retile check failed in third tile!\n"
439*d83cc019SAndroid Build Coastguard Worker 				     "%08x %08x %08x %08x instead of %08x\n",
440*d83cc019SAndroid Build Coastguard Worker 				     p[0], p[1], p[2], p[3], val);
441*d83cc019SAndroid Build Coastguard Worker 		}
442*d83cc019SAndroid Build Coastguard Worker 
443*d83cc019SAndroid Build Coastguard Worker 		val = 0xcececece;
444*d83cc019SAndroid Build Coastguard Worker 		for (i = 0; i < 256 * (w-1); ++i, p += 4) {
445*d83cc019SAndroid Build Coastguard Worker 			igt_assert_f(p[0] == val && p[1] == val && p[2] == val && p[3] == val,
446*d83cc019SAndroid Build Coastguard Worker 				     "Retile check failed in fourth tile!\n"
447*d83cc019SAndroid Build Coastguard Worker 				     "%08x %08x %08x %08x instead of %08x\n",
448*d83cc019SAndroid Build Coastguard Worker 				     p[0], p[1], p[2], p[3], val);
449*d83cc019SAndroid Build Coastguard Worker 		}
450*d83cc019SAndroid Build Coastguard Worker 	}
451*d83cc019SAndroid Build Coastguard Worker }
452*d83cc019SAndroid Build Coastguard Worker 
453*d83cc019SAndroid Build Coastguard Worker /* test 1, see if we can copy from linear to intel Y format safely */
test1_macro(void)454*d83cc019SAndroid Build Coastguard Worker static void test1_macro(void)
455*d83cc019SAndroid Build Coastguard Worker {
456*d83cc019SAndroid Build Coastguard Worker 	int prime_fd = -1;
457*d83cc019SAndroid Build Coastguard Worker 	struct nouveau_bo *nvbo = NULL, *nvbi = NULL;
458*d83cc019SAndroid Build Coastguard Worker 	rect dst, src;
459*d83cc019SAndroid Build Coastguard Worker 	uint8_t *ptr;
460*d83cc019SAndroid Build Coastguard Worker 	uint32_t w = 2 * 128, h = 2 * 32, x, y;
461*d83cc019SAndroid Build Coastguard Worker 
462*d83cc019SAndroid Build Coastguard Worker 	nv_bo_alloc(&nvbi, &src, w, h, 0, -1, NOUVEAU_BO_GART);
463*d83cc019SAndroid Build Coastguard Worker 	nv_bo_alloc(&nvbo, &dst, w, h, tile_intel_y, -1, NOUVEAU_BO_GART);
464*d83cc019SAndroid Build Coastguard Worker 
465*d83cc019SAndroid Build Coastguard Worker 	nouveau_bo_set_prime(nvbo, &prime_fd);
466*d83cc019SAndroid Build Coastguard Worker 
467*d83cc019SAndroid Build Coastguard Worker 	/* Set up something for our tile that should map into the first
468*d83cc019SAndroid Build Coastguard Worker 	 * y-major tile, assuming my understanding of documentation is
469*d83cc019SAndroid Build Coastguard Worker 	 * correct
470*d83cc019SAndroid Build Coastguard Worker 	 */
471*d83cc019SAndroid Build Coastguard Worker 
472*d83cc019SAndroid Build Coastguard Worker 	/* First tile should be read out in groups of 16 bytes that
473*d83cc019SAndroid Build Coastguard Worker 	 * are all set to a linear increasing value..
474*d83cc019SAndroid Build Coastguard Worker 	 */
475*d83cc019SAndroid Build Coastguard Worker 	ptr = nvbi->map;
476*d83cc019SAndroid Build Coastguard Worker 	for (x = 0; x < 128; x += 16)
477*d83cc019SAndroid Build Coastguard Worker 		for (y = 0; y < 32; ++y)
478*d83cc019SAndroid Build Coastguard Worker 			fill16(&ptr[y * w + x], x * 2 + y);
479*d83cc019SAndroid Build Coastguard Worker 
480*d83cc019SAndroid Build Coastguard Worker 	/* second tile */
481*d83cc019SAndroid Build Coastguard Worker 	for (x = 128; x < w; x += 16)
482*d83cc019SAndroid Build Coastguard Worker 		for (y = 0; y < 32; ++y)
483*d83cc019SAndroid Build Coastguard Worker 			fill16(&ptr[y * w + x], 0x3e);
484*d83cc019SAndroid Build Coastguard Worker 
485*d83cc019SAndroid Build Coastguard Worker 	/* third tile */
486*d83cc019SAndroid Build Coastguard Worker 	for (x = 0; x < 128; x += 16)
487*d83cc019SAndroid Build Coastguard Worker 		for (y = 32; y < h; ++y)
488*d83cc019SAndroid Build Coastguard Worker 			fill16(&ptr[y * w + x], 0x7e);
489*d83cc019SAndroid Build Coastguard Worker 
490*d83cc019SAndroid Build Coastguard Worker 	/* last tile */
491*d83cc019SAndroid Build Coastguard Worker 	for (x = 128; x < w; x += 16)
492*d83cc019SAndroid Build Coastguard Worker 		for (y = 32; y < h; ++y)
493*d83cc019SAndroid Build Coastguard Worker 			fill16(&ptr[y * w + x], 0xce);
494*d83cc019SAndroid Build Coastguard Worker 	memset(nvbo->map, 0xfc, w * h);
495*d83cc019SAndroid Build Coastguard Worker 
496*d83cc019SAndroid Build Coastguard Worker 	if (pcopy)
497*d83cc019SAndroid Build Coastguard Worker 		perform_copy(nvbo, &dst, 0, 0, nvbi, &src, 0, 0, w, h);
498*d83cc019SAndroid Build Coastguard Worker 	else
499*d83cc019SAndroid Build Coastguard Worker 		swtile_y(nvbo->map, nvbi->map, w, h);
500*d83cc019SAndroid Build Coastguard Worker 	check1_macro(nvbo->map, w/128, h/32);
501*d83cc019SAndroid Build Coastguard Worker 
502*d83cc019SAndroid Build Coastguard Worker 	nouveau_bo_ref(NULL, &nvbo);
503*d83cc019SAndroid Build Coastguard Worker 	nouveau_bo_ref(NULL, &nvbi);
504*d83cc019SAndroid Build Coastguard Worker 	close(prime_fd);
505*d83cc019SAndroid Build Coastguard Worker }
506*d83cc019SAndroid Build Coastguard Worker 
dump_line(uint8_t * map)507*d83cc019SAndroid Build Coastguard Worker static void dump_line(uint8_t *map)
508*d83cc019SAndroid Build Coastguard Worker {
509*d83cc019SAndroid Build Coastguard Worker 	uint32_t dx, dy;
510*d83cc019SAndroid Build Coastguard Worker 	igt_debug("Dumping sub-tile:\n");
511*d83cc019SAndroid Build Coastguard Worker 	for (dy = 0; dy < 32; ++dy) {
512*d83cc019SAndroid Build Coastguard Worker 		for (dx = 0; dx < 15; ++dx, ++map) {
513*d83cc019SAndroid Build Coastguard Worker 			igt_debug("%02x ", *map);
514*d83cc019SAndroid Build Coastguard Worker 		}
515*d83cc019SAndroid Build Coastguard Worker 		igt_debug("%02x\n", *(map++));
516*d83cc019SAndroid Build Coastguard Worker 	}
517*d83cc019SAndroid Build Coastguard Worker }
518*d83cc019SAndroid Build Coastguard Worker 
check1_micro(void * map,uint32_t pitch,uint32_t lines,uint32_t dst_x,uint32_t dst_y,uint32_t w,uint32_t h)519*d83cc019SAndroid Build Coastguard Worker static void check1_micro(void *map, uint32_t pitch, uint32_t lines,
520*d83cc019SAndroid Build Coastguard Worker 			 uint32_t dst_x, uint32_t dst_y, uint32_t w, uint32_t h)
521*d83cc019SAndroid Build Coastguard Worker {
522*d83cc019SAndroid Build Coastguard Worker 	uint32_t x, y;
523*d83cc019SAndroid Build Coastguard Worker 
524*d83cc019SAndroid Build Coastguard Worker 	/* check only the relevant subrectangle [0..w) [0...h) */
525*d83cc019SAndroid Build Coastguard Worker 	uint8_t *m = map;
526*d83cc019SAndroid Build Coastguard Worker 	for (y = 0; y < h; ++y, m += pitch) {
527*d83cc019SAndroid Build Coastguard Worker 		for (x = 0; x < w; ++x) {
528*d83cc019SAndroid Build Coastguard Worker 			uint8_t expected = ((y & 3) << 6) | (x & 0x3f);
529*d83cc019SAndroid Build Coastguard Worker 
530*d83cc019SAndroid Build Coastguard Worker 			if (expected != m[x])
531*d83cc019SAndroid Build Coastguard Worker 				dump_line(m);
532*d83cc019SAndroid Build Coastguard Worker 
533*d83cc019SAndroid Build Coastguard Worker 			igt_assert_f(expected == m[x],
534*d83cc019SAndroid Build Coastguard Worker 				     "failed check at x=%u y=%u, expected %02x got %02x\n",
535*d83cc019SAndroid Build Coastguard Worker 				     x, y, expected, m[x]);
536*d83cc019SAndroid Build Coastguard Worker 		}
537*d83cc019SAndroid Build Coastguard Worker 	}
538*d83cc019SAndroid Build Coastguard Worker }
539*d83cc019SAndroid Build Coastguard Worker 
540*d83cc019SAndroid Build Coastguard Worker /* test 1, but check micro format, should be unaffected by bit9 swizzling */
test1_micro(void)541*d83cc019SAndroid Build Coastguard Worker static void test1_micro(void)
542*d83cc019SAndroid Build Coastguard Worker {
543*d83cc019SAndroid Build Coastguard Worker 	struct nouveau_bo *bo_intel = NULL, *bo_nvidia = NULL, *bo_linear = NULL;
544*d83cc019SAndroid Build Coastguard Worker 	rect intel, nvidia, linear;
545*d83cc019SAndroid Build Coastguard Worker 	uint32_t tiling = I915_TILING_Y;
546*d83cc019SAndroid Build Coastguard Worker 
547*d83cc019SAndroid Build Coastguard Worker 	uint32_t src_x = 0, src_y = 0;
548*d83cc019SAndroid Build Coastguard Worker 	uint32_t dst_x = 0, dst_y = 0;
549*d83cc019SAndroid Build Coastguard Worker 	uint32_t x, y, w = 256, h = 64;
550*d83cc019SAndroid Build Coastguard Worker 
551*d83cc019SAndroid Build Coastguard Worker 	drm_intel_bo *test_intel_bo;
552*d83cc019SAndroid Build Coastguard Worker 	int prime_fd;
553*d83cc019SAndroid Build Coastguard Worker 
554*d83cc019SAndroid Build Coastguard Worker 	test_intel_bo = drm_intel_bo_alloc(bufmgr, "test bo", w * h, 4096);
555*d83cc019SAndroid Build Coastguard Worker 	igt_assert(test_intel_bo);
556*d83cc019SAndroid Build Coastguard Worker 	drm_intel_bo_set_tiling(test_intel_bo, &tiling, w);
557*d83cc019SAndroid Build Coastguard Worker 	igt_assert(tiling == I915_TILING_Y);
558*d83cc019SAndroid Build Coastguard Worker 	igt_assert(drm_intel_gem_bo_map_gtt(test_intel_bo) == 0);
559*d83cc019SAndroid Build Coastguard Worker 
560*d83cc019SAndroid Build Coastguard Worker 	drm_intel_bo_gem_export_to_prime(test_intel_bo, &prime_fd);
561*d83cc019SAndroid Build Coastguard Worker 	igt_assert_lte(0, prime_fd);
562*d83cc019SAndroid Build Coastguard Worker 	noop_intel(test_intel_bo);
563*d83cc019SAndroid Build Coastguard Worker 
564*d83cc019SAndroid Build Coastguard Worker 	nv_bo_alloc(&bo_intel, &intel, w, h, tile_intel_y, prime_fd, 0);
565*d83cc019SAndroid Build Coastguard Worker 	nv_bo_alloc(&bo_nvidia, &nvidia, w, h, 0x10, -1, NOUVEAU_BO_VRAM);
566*d83cc019SAndroid Build Coastguard Worker 	nv_bo_alloc(&bo_linear, &linear, w, h, 0, -1, NOUVEAU_BO_GART);
567*d83cc019SAndroid Build Coastguard Worker 
568*d83cc019SAndroid Build Coastguard Worker 	for (y = 0; y < linear.h; ++y) {
569*d83cc019SAndroid Build Coastguard Worker 		uint8_t *map = bo_linear->map;
570*d83cc019SAndroid Build Coastguard Worker 		map += y * linear.pitch;
571*d83cc019SAndroid Build Coastguard Worker 		for (x = 0; x < linear.pitch; ++x) {
572*d83cc019SAndroid Build Coastguard Worker 			uint8_t pos = x & 0x3f;
573*d83cc019SAndroid Build Coastguard Worker 			/* low 4 bits: micro tile pos */
574*d83cc019SAndroid Build Coastguard Worker 			/* 2 bits: x pos in tile (wraps) */
575*d83cc019SAndroid Build Coastguard Worker 			/* 2 bits: y pos in tile (wraps) */
576*d83cc019SAndroid Build Coastguard Worker 			pos |= (y & 3) << 6;
577*d83cc019SAndroid Build Coastguard Worker 			map[x] = pos;
578*d83cc019SAndroid Build Coastguard Worker 		}
579*d83cc019SAndroid Build Coastguard Worker 	}
580*d83cc019SAndroid Build Coastguard Worker 
581*d83cc019SAndroid Build Coastguard Worker 	perform_copy(bo_nvidia, &nvidia, 0, 0, bo_linear, &linear, 0, 0, nvidia.pitch, nvidia.h);
582*d83cc019SAndroid Build Coastguard Worker 
583*d83cc019SAndroid Build Coastguard Worker 	/* Perform the actual sub rectangle copy */
584*d83cc019SAndroid Build Coastguard Worker 	if (pcopy)
585*d83cc019SAndroid Build Coastguard Worker 		perform_copy(bo_intel, &intel, dst_x, dst_y, bo_nvidia, &nvidia, src_x, src_y, w, h);
586*d83cc019SAndroid Build Coastguard Worker 	else
587*d83cc019SAndroid Build Coastguard Worker 		swtile_y(test_intel_bo->virtual, bo_linear->map, w, h);
588*d83cc019SAndroid Build Coastguard Worker 
589*d83cc019SAndroid Build Coastguard Worker 	noop_intel(test_intel_bo);
590*d83cc019SAndroid Build Coastguard Worker 	check1_micro(test_intel_bo->virtual, intel.pitch, intel.h, dst_x, dst_y, w, h);
591*d83cc019SAndroid Build Coastguard Worker 
592*d83cc019SAndroid Build Coastguard Worker 	nouveau_bo_ref(NULL, &bo_linear);
593*d83cc019SAndroid Build Coastguard Worker 	nouveau_bo_ref(NULL, &bo_nvidia);
594*d83cc019SAndroid Build Coastguard Worker 	nouveau_bo_ref(NULL, &bo_intel);
595*d83cc019SAndroid Build Coastguard Worker 	drm_intel_bo_unreference(test_intel_bo);
596*d83cc019SAndroid Build Coastguard Worker }
597*d83cc019SAndroid Build Coastguard Worker 
598*d83cc019SAndroid Build Coastguard Worker /* test 2, see if we can copy from linear to intel X format safely
599*d83cc019SAndroid Build Coastguard Worker  * Seems nvidia lacks a method to do it, so just keep this test
600*d83cc019SAndroid Build Coastguard Worker  * as a reference for potential future tests. Software tiling is
601*d83cc019SAndroid Build Coastguard Worker  * used for now
602*d83cc019SAndroid Build Coastguard Worker  */
test2(void)603*d83cc019SAndroid Build Coastguard Worker static void test2(void)
604*d83cc019SAndroid Build Coastguard Worker {
605*d83cc019SAndroid Build Coastguard Worker 	struct nouveau_bo *nvbo = NULL, *nvbi = NULL;
606*d83cc019SAndroid Build Coastguard Worker 	rect dst, src;
607*d83cc019SAndroid Build Coastguard Worker 	uint8_t *ptr;
608*d83cc019SAndroid Build Coastguard Worker 	uint32_t w = 1024, h = 16, x, y;
609*d83cc019SAndroid Build Coastguard Worker 
610*d83cc019SAndroid Build Coastguard Worker 	nv_bo_alloc(&nvbi, &src, w, h, 0, -1, NOUVEAU_BO_GART);
611*d83cc019SAndroid Build Coastguard Worker 	nv_bo_alloc(&nvbo, &dst, w, h, tile_intel_x, -1, NOUVEAU_BO_GART);
612*d83cc019SAndroid Build Coastguard Worker 
613*d83cc019SAndroid Build Coastguard Worker 	/* Set up something for our tile that should map into the first
614*d83cc019SAndroid Build Coastguard Worker 	 * y-major tile, assuming my understanding of documentation is
615*d83cc019SAndroid Build Coastguard Worker 	 * correct
616*d83cc019SAndroid Build Coastguard Worker 	 */
617*d83cc019SAndroid Build Coastguard Worker 
618*d83cc019SAndroid Build Coastguard Worker 	/* First tile should be read out in groups of 16 bytes that
619*d83cc019SAndroid Build Coastguard Worker 	 * are all set to a linear increasing value..
620*d83cc019SAndroid Build Coastguard Worker 	 */
621*d83cc019SAndroid Build Coastguard Worker 	ptr = nvbi->map;
622*d83cc019SAndroid Build Coastguard Worker 	for (y = 0; y < 8; ++y)
623*d83cc019SAndroid Build Coastguard Worker 		for (x = 0; x < 512; x += 16)
624*d83cc019SAndroid Build Coastguard Worker 			fill16(&ptr[y * w + x], (y * 512 + x)/16);
625*d83cc019SAndroid Build Coastguard Worker 
626*d83cc019SAndroid Build Coastguard Worker 	for (y = 0; y < 8; ++y)
627*d83cc019SAndroid Build Coastguard Worker 		for (x = 512; x < w; x += 16)
628*d83cc019SAndroid Build Coastguard Worker 			fill16(&ptr[y * w + x], 0x3e);
629*d83cc019SAndroid Build Coastguard Worker 
630*d83cc019SAndroid Build Coastguard Worker 	for (y = 8; y < h; ++y)
631*d83cc019SAndroid Build Coastguard Worker 		for (x = 0; x < 512; x += 16)
632*d83cc019SAndroid Build Coastguard Worker 			fill16(&ptr[y * w + x], 0x7e);
633*d83cc019SAndroid Build Coastguard Worker 
634*d83cc019SAndroid Build Coastguard Worker 	for (y = 8; y < h; ++y)
635*d83cc019SAndroid Build Coastguard Worker 		for (x = 512; x < w; x += 16)
636*d83cc019SAndroid Build Coastguard Worker 			fill16(&ptr[y * w + x], 0xce);
637*d83cc019SAndroid Build Coastguard Worker 	memset(nvbo->map, 0xfc, w * h);
638*d83cc019SAndroid Build Coastguard Worker 
639*d83cc019SAndroid Build Coastguard Worker 	/* do this in software, there is no X major tiling in PCOPY (yet?) */
640*d83cc019SAndroid Build Coastguard Worker 	if (0 && pcopy)
641*d83cc019SAndroid Build Coastguard Worker 		perform_copy(nvbo, &dst, 0, 0, nvbi, &src, 0, 0, w, h);
642*d83cc019SAndroid Build Coastguard Worker 	else
643*d83cc019SAndroid Build Coastguard Worker 		swtile_x(nvbo->map, nvbi->map, w, h);
644*d83cc019SAndroid Build Coastguard Worker 	check1_macro(nvbo->map, w/512, h/8);
645*d83cc019SAndroid Build Coastguard Worker 
646*d83cc019SAndroid Build Coastguard Worker 	nouveau_bo_ref(NULL, &nvbo);
647*d83cc019SAndroid Build Coastguard Worker 	nouveau_bo_ref(NULL, &nvbi);
648*d83cc019SAndroid Build Coastguard Worker }
649*d83cc019SAndroid Build Coastguard Worker 
check3(const uint32_t * p,uint32_t pitch,uint32_t lines,uint32_t sub_x,uint32_t sub_y,uint32_t sub_w,uint32_t sub_h)650*d83cc019SAndroid Build Coastguard Worker static void check3(const uint32_t *p, uint32_t pitch, uint32_t lines,
651*d83cc019SAndroid Build Coastguard Worker 		   uint32_t sub_x, uint32_t sub_y,
652*d83cc019SAndroid Build Coastguard Worker 		   uint32_t sub_w, uint32_t sub_h)
653*d83cc019SAndroid Build Coastguard Worker {
654*d83cc019SAndroid Build Coastguard Worker 	uint32_t x, y;
655*d83cc019SAndroid Build Coastguard Worker 
656*d83cc019SAndroid Build Coastguard Worker 	sub_w += sub_x;
657*d83cc019SAndroid Build Coastguard Worker 	sub_h += sub_y;
658*d83cc019SAndroid Build Coastguard Worker 
659*d83cc019SAndroid Build Coastguard Worker 	igt_assert_f(p[pitch * lines / 4 - 1] != 0x03030303,
660*d83cc019SAndroid Build Coastguard Worker 		     "copy failed: Not all lines have been copied back!\n");
661*d83cc019SAndroid Build Coastguard Worker 
662*d83cc019SAndroid Build Coastguard Worker 	for (y = 0; y < lines; ++y) {
663*d83cc019SAndroid Build Coastguard Worker 		for (x = 0; x < pitch; x += 4, ++p) {
664*d83cc019SAndroid Build Coastguard Worker 			uint32_t expected;
665*d83cc019SAndroid Build Coastguard Worker 			if ((x < sub_x || x >= sub_w) ||
666*d83cc019SAndroid Build Coastguard Worker 			    (y < sub_y || y >= sub_h))
667*d83cc019SAndroid Build Coastguard Worker 				expected = 0x80808080;
668*d83cc019SAndroid Build Coastguard Worker 			else
669*d83cc019SAndroid Build Coastguard Worker 				expected = 0x04040404;
670*d83cc019SAndroid Build Coastguard Worker 			igt_assert_f(*p == expected,
671*d83cc019SAndroid Build Coastguard Worker 				     "%u,%u should be %08x, but is %08x\n",
672*d83cc019SAndroid Build Coastguard Worker 				     x, y, expected, *p);
673*d83cc019SAndroid Build Coastguard Worker 		}
674*d83cc019SAndroid Build Coastguard Worker 	}
675*d83cc019SAndroid Build Coastguard Worker }
676*d83cc019SAndroid Build Coastguard Worker 
677*d83cc019SAndroid Build Coastguard Worker /* copy from nvidia bo to intel bo and copy to a linear bo to check if tiling went succesful */
test3_base(int tile_src,int tile_dst)678*d83cc019SAndroid Build Coastguard Worker static void test3_base(int tile_src, int tile_dst)
679*d83cc019SAndroid Build Coastguard Worker {
680*d83cc019SAndroid Build Coastguard Worker 	struct nouveau_bo *bo_intel = NULL, *bo_nvidia = NULL, *bo_linear = NULL;
681*d83cc019SAndroid Build Coastguard Worker 	rect intel, nvidia, linear;
682*d83cc019SAndroid Build Coastguard Worker 	uint32_t cpp = 4;
683*d83cc019SAndroid Build Coastguard Worker 
684*d83cc019SAndroid Build Coastguard Worker 	uint32_t src_x = 1 * cpp, src_y = 1;
685*d83cc019SAndroid Build Coastguard Worker 	uint32_t dst_x = 2 * cpp, dst_y = 26;
686*d83cc019SAndroid Build Coastguard Worker 	uint32_t w = 298 * cpp, h = 298;
687*d83cc019SAndroid Build Coastguard Worker 
688*d83cc019SAndroid Build Coastguard Worker 	drm_intel_bo *test_intel_bo;
689*d83cc019SAndroid Build Coastguard Worker 	int prime_fd;
690*d83cc019SAndroid Build Coastguard Worker 
691*d83cc019SAndroid Build Coastguard Worker 	test_intel_bo = drm_intel_bo_alloc(bufmgr, "test bo", 2048 * cpp * 768, 4096);
692*d83cc019SAndroid Build Coastguard Worker 	igt_assert(test_intel_bo);
693*d83cc019SAndroid Build Coastguard Worker 
694*d83cc019SAndroid Build Coastguard Worker 	drm_intel_bo_gem_export_to_prime(test_intel_bo, &prime_fd);
695*d83cc019SAndroid Build Coastguard Worker 	igt_assert_lte(0, prime_fd);
696*d83cc019SAndroid Build Coastguard Worker 
697*d83cc019SAndroid Build Coastguard Worker 	nv_bo_alloc(&bo_intel, &intel, 2048 * cpp, 768, tile_dst, prime_fd, 0);
698*d83cc019SAndroid Build Coastguard Worker 	nv_bo_alloc(&bo_nvidia, &nvidia, 300 * cpp, 300, tile_src, -1, NOUVEAU_BO_VRAM);
699*d83cc019SAndroid Build Coastguard Worker 	nv_bo_alloc(&bo_linear, &linear, 2048 * cpp, 768, 0, -1, NOUVEAU_BO_GART);
700*d83cc019SAndroid Build Coastguard Worker 
701*d83cc019SAndroid Build Coastguard Worker 	noop_intel(test_intel_bo);
702*d83cc019SAndroid Build Coastguard Worker 	memset(bo_linear->map, 0x80, bo_linear->size);
703*d83cc019SAndroid Build Coastguard Worker 	perform_copy(bo_intel, &intel, 0, 0, bo_linear, &linear, 0, 0, linear.pitch, linear.h);
704*d83cc019SAndroid Build Coastguard Worker 	noop_intel(test_intel_bo);
705*d83cc019SAndroid Build Coastguard Worker 
706*d83cc019SAndroid Build Coastguard Worker 	memset(bo_linear->map, 0x04, bo_linear->size);
707*d83cc019SAndroid Build Coastguard Worker 	perform_copy(bo_nvidia, &nvidia, 0, 0, bo_linear, &linear, 0, 0, nvidia.pitch, nvidia.h);
708*d83cc019SAndroid Build Coastguard Worker 
709*d83cc019SAndroid Build Coastguard Worker 	/* Perform the actual sub rectangle copy */
710*d83cc019SAndroid Build Coastguard Worker 	noop_intel(test_intel_bo);
711*d83cc019SAndroid Build Coastguard Worker 	perform_copy(bo_intel, &intel, dst_x, dst_y, bo_nvidia, &nvidia, src_x, src_y, w, h);
712*d83cc019SAndroid Build Coastguard Worker 	noop_intel(test_intel_bo);
713*d83cc019SAndroid Build Coastguard Worker 
714*d83cc019SAndroid Build Coastguard Worker 	memset(bo_linear->map, 0x3, bo_linear->size);
715*d83cc019SAndroid Build Coastguard Worker 	noop_intel(test_intel_bo);
716*d83cc019SAndroid Build Coastguard Worker 	perform_copy(bo_linear, &linear, 0, 0, bo_intel, &intel, 0, 0, intel.pitch, intel.h);
717*d83cc019SAndroid Build Coastguard Worker 	noop_intel(test_intel_bo);
718*d83cc019SAndroid Build Coastguard Worker 
719*d83cc019SAndroid Build Coastguard Worker 	check3(bo_linear->map, linear.pitch, linear.h, dst_x, dst_y, w, h);
720*d83cc019SAndroid Build Coastguard Worker 
721*d83cc019SAndroid Build Coastguard Worker 	nouveau_bo_ref(NULL, &bo_linear);
722*d83cc019SAndroid Build Coastguard Worker 	nouveau_bo_ref(NULL, &bo_nvidia);
723*d83cc019SAndroid Build Coastguard Worker 	nouveau_bo_ref(NULL, &bo_intel);
724*d83cc019SAndroid Build Coastguard Worker 	drm_intel_bo_unreference(test_intel_bo);
725*d83cc019SAndroid Build Coastguard Worker }
726*d83cc019SAndroid Build Coastguard Worker 
test3_1(void)727*d83cc019SAndroid Build Coastguard Worker static void test3_1(void)
728*d83cc019SAndroid Build Coastguard Worker {
729*d83cc019SAndroid Build Coastguard Worker 	/* nvidia tiling to intel */
730*d83cc019SAndroid Build Coastguard Worker 	test3_base(0x40, tile_intel_y);
731*d83cc019SAndroid Build Coastguard Worker }
732*d83cc019SAndroid Build Coastguard Worker 
test3_2(void)733*d83cc019SAndroid Build Coastguard Worker static void test3_2(void)
734*d83cc019SAndroid Build Coastguard Worker {
735*d83cc019SAndroid Build Coastguard Worker 	/* intel tiling to nvidia */
736*d83cc019SAndroid Build Coastguard Worker 	test3_base(tile_intel_y, 0x40);
737*d83cc019SAndroid Build Coastguard Worker }
738*d83cc019SAndroid Build Coastguard Worker 
test3_3(void)739*d83cc019SAndroid Build Coastguard Worker static void test3_3(void)
740*d83cc019SAndroid Build Coastguard Worker {
741*d83cc019SAndroid Build Coastguard Worker 	/* intel tiling to linear */
742*d83cc019SAndroid Build Coastguard Worker 	test3_base(tile_intel_y, 0);
743*d83cc019SAndroid Build Coastguard Worker }
744*d83cc019SAndroid Build Coastguard Worker 
test3_4(void)745*d83cc019SAndroid Build Coastguard Worker static void test3_4(void)
746*d83cc019SAndroid Build Coastguard Worker {
747*d83cc019SAndroid Build Coastguard Worker 	/* linear tiling to intel */
748*d83cc019SAndroid Build Coastguard Worker 	test3_base(0, tile_intel_y);
749*d83cc019SAndroid Build Coastguard Worker }
750*d83cc019SAndroid Build Coastguard Worker 
test3_5(void)751*d83cc019SAndroid Build Coastguard Worker static void test3_5(void)
752*d83cc019SAndroid Build Coastguard Worker {
753*d83cc019SAndroid Build Coastguard Worker 	/* linear to linear */
754*d83cc019SAndroid Build Coastguard Worker 	test3_base(0, 0);
755*d83cc019SAndroid Build Coastguard Worker }
756*d83cc019SAndroid Build Coastguard Worker 
757*d83cc019SAndroid Build Coastguard Worker /* Acquire when == SEQUENCE */
758*d83cc019SAndroid Build Coastguard Worker #define SEMA_ACQUIRE_EQUAL 1
759*d83cc019SAndroid Build Coastguard Worker 
760*d83cc019SAndroid Build Coastguard Worker /* Release, and write a 16 byte query structure to sema:
761*d83cc019SAndroid Build Coastguard Worker  * { (uint32)seq, (uint32)0, (uint64)timestamp } */
762*d83cc019SAndroid Build Coastguard Worker #define SEMA_WRITE_LONG 2
763*d83cc019SAndroid Build Coastguard Worker 
764*d83cc019SAndroid Build Coastguard Worker /* Acquire when >= SEQUENCE */
765*d83cc019SAndroid Build Coastguard Worker #define SEMA_ACQUIRE_GEQUAL 4
766*d83cc019SAndroid Build Coastguard Worker 
767*d83cc019SAndroid Build Coastguard Worker /* Test only new style semaphores, old ones are AWFUL */
test_semaphore(void)768*d83cc019SAndroid Build Coastguard Worker static void test_semaphore(void)
769*d83cc019SAndroid Build Coastguard Worker {
770*d83cc019SAndroid Build Coastguard Worker 	drm_intel_bo *test_intel_bo = NULL;
771*d83cc019SAndroid Build Coastguard Worker 	struct nouveau_bo *sema_bo = NULL;
772*d83cc019SAndroid Build Coastguard Worker 	int prime_fd;
773*d83cc019SAndroid Build Coastguard Worker 	uint32_t *sema;
774*d83cc019SAndroid Build Coastguard Worker 	struct nouveau_pushbuf *push = npush;
775*d83cc019SAndroid Build Coastguard Worker 
776*d83cc019SAndroid Build Coastguard Worker 	igt_skip_on(ndev->chipset < 0x84);
777*d83cc019SAndroid Build Coastguard Worker 
778*d83cc019SAndroid Build Coastguard Worker 	/* Should probably be kept in sysmem */
779*d83cc019SAndroid Build Coastguard Worker 	test_intel_bo = drm_intel_bo_alloc(bufmgr, "semaphore bo", 4096, 4096);
780*d83cc019SAndroid Build Coastguard Worker 	igt_assert(test_intel_bo);
781*d83cc019SAndroid Build Coastguard Worker 
782*d83cc019SAndroid Build Coastguard Worker 	drm_intel_bo_gem_export_to_prime(test_intel_bo, &prime_fd);
783*d83cc019SAndroid Build Coastguard Worker 	igt_assert_lte(0, prime_fd);
784*d83cc019SAndroid Build Coastguard Worker 	igt_assert(nouveau_bo_prime_handle_ref(ndev, prime_fd, &sema_bo) == 0);
785*d83cc019SAndroid Build Coastguard Worker 	close(prime_fd);
786*d83cc019SAndroid Build Coastguard Worker 
787*d83cc019SAndroid Build Coastguard Worker 	igt_assert(drm_intel_gem_bo_map_gtt(test_intel_bo) == 0);
788*d83cc019SAndroid Build Coastguard Worker 	sema = test_intel_bo->virtual;
789*d83cc019SAndroid Build Coastguard Worker 	sema++;
790*d83cc019SAndroid Build Coastguard Worker 	*sema = 0;
791*d83cc019SAndroid Build Coastguard Worker 
792*d83cc019SAndroid Build Coastguard Worker 	igt_assert(nouveau_pushbuf_space(push, 64, 0, 0) == 0);
793*d83cc019SAndroid Build Coastguard Worker 	igt_assert(nouveau_pushbuf_refn(push, &(struct nouveau_pushbuf_refn)
794*d83cc019SAndroid Build Coastguard Worker 					{ sema_bo, NOUVEAU_BO_GART|NOUVEAU_BO_RDWR }, 1) == 0);
795*d83cc019SAndroid Build Coastguard Worker 
796*d83cc019SAndroid Build Coastguard Worker 	if (ndev->chipset < 0xc0) {
797*d83cc019SAndroid Build Coastguard Worker 		struct nv04_fifo *nv04_fifo = nchannel->data;
798*d83cc019SAndroid Build Coastguard Worker 		/* kernel binds it's own dma object here and overwrites old one,
799*d83cc019SAndroid Build Coastguard Worker 		 * so just rebind vram every time we submit
800*d83cc019SAndroid Build Coastguard Worker 		 */
801*d83cc019SAndroid Build Coastguard Worker 		BEGIN_NV04(npush, SUBC_COPY(0x0060), 1);
802*d83cc019SAndroid Build Coastguard Worker 		PUSH_DATA(npush, nv04_fifo->vram);
803*d83cc019SAndroid Build Coastguard Worker 	}
804*d83cc019SAndroid Build Coastguard Worker 	BEGIN_NVXX(push, SUBC_COPY(0x0010), 4);
805*d83cc019SAndroid Build Coastguard Worker 	PUSH_DATA(push, sema_bo->offset >> 32);
806*d83cc019SAndroid Build Coastguard Worker 	PUSH_DATA(push, sema_bo->offset + 4);
807*d83cc019SAndroid Build Coastguard Worker 	PUSH_DATA(push, 2); // SEQUENCE
808*d83cc019SAndroid Build Coastguard Worker 	PUSH_DATA(push, SEMA_WRITE_LONG); // TRIGGER
809*d83cc019SAndroid Build Coastguard Worker 
810*d83cc019SAndroid Build Coastguard Worker 	BEGIN_NVXX(push, SUBC_COPY(0x0018), 2);
811*d83cc019SAndroid Build Coastguard Worker 	PUSH_DATA(push, 3);
812*d83cc019SAndroid Build Coastguard Worker 	PUSH_DATA(push, SEMA_ACQUIRE_EQUAL);
813*d83cc019SAndroid Build Coastguard Worker 	BEGIN_NVXX(push, SUBC_COPY(0x0018), 2);
814*d83cc019SAndroid Build Coastguard Worker 	PUSH_DATA(push, 4);
815*d83cc019SAndroid Build Coastguard Worker 	PUSH_DATA(push, SEMA_WRITE_LONG);
816*d83cc019SAndroid Build Coastguard Worker 
817*d83cc019SAndroid Build Coastguard Worker 	BEGIN_NVXX(push, SUBC_COPY(0x0018), 2);
818*d83cc019SAndroid Build Coastguard Worker 	PUSH_DATA(push, 5);
819*d83cc019SAndroid Build Coastguard Worker 	PUSH_DATA(push, SEMA_ACQUIRE_GEQUAL);
820*d83cc019SAndroid Build Coastguard Worker 	BEGIN_NVXX(push, SUBC_COPY(0x0018), 2);
821*d83cc019SAndroid Build Coastguard Worker 	PUSH_DATA(push, 6);
822*d83cc019SAndroid Build Coastguard Worker 	PUSH_DATA(push, SEMA_WRITE_LONG);
823*d83cc019SAndroid Build Coastguard Worker 
824*d83cc019SAndroid Build Coastguard Worker 	BEGIN_NVXX(push, SUBC_COPY(0x0018), 2);
825*d83cc019SAndroid Build Coastguard Worker 	PUSH_DATA(push, 7);
826*d83cc019SAndroid Build Coastguard Worker 	PUSH_DATA(push, SEMA_ACQUIRE_GEQUAL);
827*d83cc019SAndroid Build Coastguard Worker 	BEGIN_NVXX(push, SUBC_COPY(0x0018), 2);
828*d83cc019SAndroid Build Coastguard Worker 	PUSH_DATA(push, 9);
829*d83cc019SAndroid Build Coastguard Worker 	PUSH_DATA(push, SEMA_WRITE_LONG);
830*d83cc019SAndroid Build Coastguard Worker 	nouveau_pushbuf_kick(push, push->channel);
831*d83cc019SAndroid Build Coastguard Worker 
832*d83cc019SAndroid Build Coastguard Worker 	usleep(1000);
833*d83cc019SAndroid Build Coastguard Worker 	igt_assert(*sema == 2);
834*d83cc019SAndroid Build Coastguard Worker 
835*d83cc019SAndroid Build Coastguard Worker 	*sema = 3;
836*d83cc019SAndroid Build Coastguard Worker 	usleep(1000);
837*d83cc019SAndroid Build Coastguard Worker 	igt_assert(*sema == 4);
838*d83cc019SAndroid Build Coastguard Worker 
839*d83cc019SAndroid Build Coastguard Worker 	*sema = 5;
840*d83cc019SAndroid Build Coastguard Worker 	usleep(1000);
841*d83cc019SAndroid Build Coastguard Worker 	igt_assert(*sema == 6);
842*d83cc019SAndroid Build Coastguard Worker 
843*d83cc019SAndroid Build Coastguard Worker 	*sema = 8;
844*d83cc019SAndroid Build Coastguard Worker 	usleep(1000);
845*d83cc019SAndroid Build Coastguard Worker 	igt_assert(*sema == 9);
846*d83cc019SAndroid Build Coastguard Worker 
847*d83cc019SAndroid Build Coastguard Worker 	nouveau_bo_ref(NULL, &sema_bo);
848*d83cc019SAndroid Build Coastguard Worker 	drm_intel_bo_unreference(test_intel_bo);
849*d83cc019SAndroid Build Coastguard Worker }
850*d83cc019SAndroid Build Coastguard Worker 
851*d83cc019SAndroid Build Coastguard Worker igt_main
852*d83cc019SAndroid Build Coastguard Worker {
853*d83cc019SAndroid Build Coastguard Worker 	igt_fixture {
854*d83cc019SAndroid Build Coastguard Worker 		find_and_open_devices();
855*d83cc019SAndroid Build Coastguard Worker 
856*d83cc019SAndroid Build Coastguard Worker 		igt_require(nouveau_fd != -1);
857*d83cc019SAndroid Build Coastguard Worker 		igt_require(intel_fd != -1);
858*d83cc019SAndroid Build Coastguard Worker 
859*d83cc019SAndroid Build Coastguard Worker 		/* set up intel bufmgr */
860*d83cc019SAndroid Build Coastguard Worker 		bufmgr = drm_intel_bufmgr_gem_init(intel_fd, 4096);
861*d83cc019SAndroid Build Coastguard Worker 		igt_assert(bufmgr);
862*d83cc019SAndroid Build Coastguard Worker 		/* Do not enable reuse, we share (almost) all buffers. */
863*d83cc019SAndroid Build Coastguard Worker 		//drm_intel_bufmgr_gem_enable_reuse(bufmgr);
864*d83cc019SAndroid Build Coastguard Worker 
865*d83cc019SAndroid Build Coastguard Worker 		/* set up nouveau bufmgr */
866*d83cc019SAndroid Build Coastguard Worker 		init_nouveau();
867*d83cc019SAndroid Build Coastguard Worker 
868*d83cc019SAndroid Build Coastguard Worker 		/* set up an intel batch buffer */
869*d83cc019SAndroid Build Coastguard Worker 		devid = intel_get_drm_devid(intel_fd);
870*d83cc019SAndroid Build Coastguard Worker 		batch = intel_batchbuffer_alloc(bufmgr, devid);
871*d83cc019SAndroid Build Coastguard Worker 		igt_assert(batch);
872*d83cc019SAndroid Build Coastguard Worker 	}
873*d83cc019SAndroid Build Coastguard Worker 
874*d83cc019SAndroid Build Coastguard Worker #define xtest(x, args...) \
875*d83cc019SAndroid Build Coastguard Worker 	igt_subtest( #x ) \
876*d83cc019SAndroid Build Coastguard Worker 		(x)(args);
877*d83cc019SAndroid Build Coastguard Worker 
878*d83cc019SAndroid Build Coastguard Worker 	xtest(test1_macro);
879*d83cc019SAndroid Build Coastguard Worker 	xtest(test1_micro);
880*d83cc019SAndroid Build Coastguard Worker 	//xtest(test1_swizzle);
881*d83cc019SAndroid Build Coastguard Worker 	xtest(test2);
882*d83cc019SAndroid Build Coastguard Worker 	xtest(test3_1);
883*d83cc019SAndroid Build Coastguard Worker 	xtest(test3_2);
884*d83cc019SAndroid Build Coastguard Worker 	xtest(test3_3);
885*d83cc019SAndroid Build Coastguard Worker 	xtest(test3_4);
886*d83cc019SAndroid Build Coastguard Worker 	xtest(test3_5);
887*d83cc019SAndroid Build Coastguard Worker 	xtest(test_semaphore);
888*d83cc019SAndroid Build Coastguard Worker 
889*d83cc019SAndroid Build Coastguard Worker 	igt_fixture {
890*d83cc019SAndroid Build Coastguard Worker 		nouveau_bo_ref(NULL, &query_bo);
891*d83cc019SAndroid Build Coastguard Worker 		nouveau_object_del(&pcopy);
892*d83cc019SAndroid Build Coastguard Worker 		nouveau_bufctx_del(&nbufctx);
893*d83cc019SAndroid Build Coastguard Worker 		nouveau_pushbuf_del(&npush);
894*d83cc019SAndroid Build Coastguard Worker 		nouveau_object_del(&nchannel);
895*d83cc019SAndroid Build Coastguard Worker 
896*d83cc019SAndroid Build Coastguard Worker 		intel_batchbuffer_free(batch);
897*d83cc019SAndroid Build Coastguard Worker 
898*d83cc019SAndroid Build Coastguard Worker 		nouveau_client_del(&nclient);
899*d83cc019SAndroid Build Coastguard Worker 		nouveau_device_del(&ndev);
900*d83cc019SAndroid Build Coastguard Worker 		drm_intel_bufmgr_destroy(bufmgr);
901*d83cc019SAndroid Build Coastguard Worker 
902*d83cc019SAndroid Build Coastguard Worker 		close(intel_fd);
903*d83cc019SAndroid Build Coastguard Worker 		close(nouveau_fd);
904*d83cc019SAndroid Build Coastguard Worker 	}
905*d83cc019SAndroid Build Coastguard Worker }
906