xref: /third_party/libdrm/tests/amdgpu/cs_tests.c (revision d722e3fb)
1/*
2 * Copyright 2014 Advanced Micro Devices, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22*/
23
24#include <stdio.h>
25
26#include "CUnit/Basic.h"
27
28#include "util_math.h"
29
30#include "amdgpu_test.h"
31#include "decode_messages.h"
32#include "amdgpu_drm.h"
33#include "amdgpu_internal.h"
34
35#define IB_SIZE		4096
36#define MAX_RESOURCES	16
37
38static amdgpu_device_handle device_handle;
39static uint32_t major_version;
40static uint32_t minor_version;
41static uint32_t family_id;
42static uint32_t chip_rev;
43static uint32_t chip_id;
44
45static amdgpu_context_handle context_handle;
46static amdgpu_bo_handle ib_handle;
47static uint64_t ib_mc_address;
48static uint32_t *ib_cpu;
49static amdgpu_va_handle ib_va_handle;
50
51static amdgpu_bo_handle resources[MAX_RESOURCES];
52static unsigned num_resources;
53
54static void amdgpu_cs_uvd_create(void);
55static void amdgpu_cs_uvd_decode(void);
56static void amdgpu_cs_uvd_destroy(void);
57
58CU_TestInfo cs_tests[] = {
59	{ "UVD create",  amdgpu_cs_uvd_create },
60	{ "UVD decode",  amdgpu_cs_uvd_decode },
61	{ "UVD destroy",  amdgpu_cs_uvd_destroy },
62	CU_TEST_INFO_NULL,
63};
64
65CU_BOOL suite_cs_tests_enable(void)
66{
67	if (amdgpu_device_initialize(drm_amdgpu[0], &major_version,
68					     &minor_version, &device_handle))
69		return CU_FALSE;
70
71	family_id = device_handle->info.family_id;
72    chip_id = device_handle->info.chip_external_rev;
73    chip_rev = device_handle->info.chip_rev;
74
75	if (amdgpu_device_deinitialize(device_handle))
76		return CU_FALSE;
77
78
79	if (family_id >= AMDGPU_FAMILY_RV || family_id == AMDGPU_FAMILY_SI ||
80		asic_is_gfx_pipe_removed(family_id, chip_id, chip_rev)) {
81		printf("\n\nThe ASIC NOT support UVD, suite disabled\n");
82		return CU_FALSE;
83	}
84
85	return CU_TRUE;
86}
87
88int suite_cs_tests_init(void)
89{
90	amdgpu_bo_handle ib_result_handle;
91	void *ib_result_cpu;
92	uint64_t ib_result_mc_address;
93	amdgpu_va_handle ib_result_va_handle;
94	int r;
95
96	r = amdgpu_device_initialize(drm_amdgpu[0], &major_version,
97				     &minor_version, &device_handle);
98	if (r) {
99		if ((r == -EACCES) && (errno == EACCES))
100			printf("\n\nError:%s. "
101				"Hint:Try to run this test program as root.",
102				strerror(errno));
103
104		return CUE_SINIT_FAILED;
105	}
106
107	family_id = device_handle->info.family_id;
108	/* VI asic POLARIS10/11 have specific external_rev_id */
109	chip_rev = device_handle->info.chip_rev;
110	chip_id = device_handle->info.chip_external_rev;
111
112	r = amdgpu_cs_ctx_create(device_handle, &context_handle);
113	if (r)
114		return CUE_SINIT_FAILED;
115
116	r = amdgpu_bo_alloc_and_map(device_handle, IB_SIZE, 4096,
117				    AMDGPU_GEM_DOMAIN_GTT, 0,
118				    &ib_result_handle, &ib_result_cpu,
119				    &ib_result_mc_address,
120				    &ib_result_va_handle);
121	if (r)
122		return CUE_SINIT_FAILED;
123
124	ib_handle = ib_result_handle;
125	ib_mc_address = ib_result_mc_address;
126	ib_cpu = ib_result_cpu;
127	ib_va_handle = ib_result_va_handle;
128
129	return CUE_SUCCESS;
130}
131
132int suite_cs_tests_clean(void)
133{
134	int r;
135
136	r = amdgpu_bo_unmap_and_free(ib_handle, ib_va_handle,
137				     ib_mc_address, IB_SIZE);
138	if (r)
139		return CUE_SCLEAN_FAILED;
140
141	r = amdgpu_cs_ctx_free(context_handle);
142	if (r)
143		return CUE_SCLEAN_FAILED;
144
145	r = amdgpu_device_deinitialize(device_handle);
146	if (r)
147		return CUE_SCLEAN_FAILED;
148
149	return CUE_SUCCESS;
150}
151
152static int submit(unsigned ndw, unsigned ip)
153{
154	struct amdgpu_cs_request ibs_request = {0};
155	struct amdgpu_cs_ib_info ib_info = {0};
156	struct amdgpu_cs_fence fence_status = {0};
157	uint32_t expired;
158	int r;
159
160	ib_info.ib_mc_address = ib_mc_address;
161	ib_info.size = ndw;
162
163	ibs_request.ip_type = ip;
164
165	r = amdgpu_bo_list_create(device_handle, num_resources, resources,
166				  NULL, &ibs_request.resources);
167	if (r)
168		return r;
169
170	ibs_request.number_of_ibs = 1;
171	ibs_request.ibs = &ib_info;
172	ibs_request.fence_info.handle = NULL;
173
174	r = amdgpu_cs_submit(context_handle, 0, &ibs_request, 1);
175	if (r)
176		return r;
177
178	r = amdgpu_bo_list_destroy(ibs_request.resources);
179	if (r)
180		return r;
181
182	fence_status.context = context_handle;
183	fence_status.ip_type = ip;
184	fence_status.fence = ibs_request.seq_no;
185
186	r = amdgpu_cs_query_fence_status(&fence_status,
187					 AMDGPU_TIMEOUT_INFINITE,
188					 0, &expired);
189	if (r)
190		return r;
191
192	return 0;
193}
194
195static void uvd_cmd(uint64_t addr, unsigned cmd, int *idx)
196{
197	ib_cpu[(*idx)++] = (family_id < AMDGPU_FAMILY_AI) ? 0x3BC4 : 0x81C4;
198	ib_cpu[(*idx)++] = addr;
199	ib_cpu[(*idx)++] = (family_id < AMDGPU_FAMILY_AI) ? 0x3BC5 : 0x81C5;
200	ib_cpu[(*idx)++] = addr >> 32;
201	ib_cpu[(*idx)++] = (family_id < AMDGPU_FAMILY_AI) ? 0x3BC3 : 0x81C3;
202	ib_cpu[(*idx)++] = cmd << 1;
203}
204
205static void amdgpu_cs_uvd_create(void)
206{
207	struct amdgpu_bo_alloc_request req = {0};
208	amdgpu_bo_handle buf_handle;
209	uint64_t va = 0;
210	amdgpu_va_handle va_handle;
211	void *msg;
212	int i, r;
213
214	req.alloc_size = 4*1024;
215	req.preferred_heap = AMDGPU_GEM_DOMAIN_GTT;
216
217	r = amdgpu_bo_alloc(device_handle, &req, &buf_handle);
218	CU_ASSERT_EQUAL(r, 0);
219
220	r = amdgpu_va_range_alloc(device_handle,
221				  amdgpu_gpu_va_range_general,
222				  4096, 1, 0, &va,
223				  &va_handle, 0);
224	CU_ASSERT_EQUAL(r, 0);
225
226	r = amdgpu_bo_va_op(buf_handle, 0, 4096, va, 0, AMDGPU_VA_OP_MAP);
227	CU_ASSERT_EQUAL(r, 0);
228
229	r = amdgpu_bo_cpu_map(buf_handle, &msg);
230	CU_ASSERT_EQUAL(r, 0);
231
232	memcpy(msg, uvd_create_msg, sizeof(uvd_create_msg));
233
234	if (family_id >= AMDGPU_FAMILY_VI) {
235		((uint8_t*)msg)[0x10] = 7;
236		/* chip beyond polaris 10/11 */
237		if ((family_id == AMDGPU_FAMILY_AI) ||
238		    (chip_id == chip_rev+0x50 || chip_id == chip_rev+0x5A ||
239		     chip_id == chip_rev+0x64)) {
240			/* dpb size */
241			((uint8_t*)msg)[0x28] = 0x00;
242			((uint8_t*)msg)[0x29] = 0x94;
243			((uint8_t*)msg)[0x2A] = 0x6B;
244			((uint8_t*)msg)[0x2B] = 0x00;
245		}
246	}
247
248	r = amdgpu_bo_cpu_unmap(buf_handle);
249	CU_ASSERT_EQUAL(r, 0);
250
251	num_resources = 0;
252	resources[num_resources++] = buf_handle;
253	resources[num_resources++] = ib_handle;
254
255	i = 0;
256	uvd_cmd(va, 0x0, &i);
257	for (; i % 16; ++i)
258		ib_cpu[i] = 0x80000000;
259
260	r = submit(i, AMDGPU_HW_IP_UVD);
261	CU_ASSERT_EQUAL(r, 0);
262
263	r = amdgpu_bo_va_op(buf_handle, 0, 4096, va, 0, AMDGPU_VA_OP_UNMAP);
264	CU_ASSERT_EQUAL(r, 0);
265
266	r = amdgpu_va_range_free(va_handle);
267	CU_ASSERT_EQUAL(r, 0);
268
269	r = amdgpu_bo_free(buf_handle);
270	CU_ASSERT_EQUAL(r, 0);
271}
272
273static void amdgpu_cs_uvd_decode(void)
274{
275	const unsigned dpb_size = 15923584, dt_size = 737280;
276	uint64_t msg_addr, fb_addr, bs_addr, dpb_addr, ctx_addr, dt_addr, it_addr;
277	struct amdgpu_bo_alloc_request req = {0};
278	amdgpu_bo_handle buf_handle;
279	amdgpu_va_handle va_handle;
280	uint64_t va = 0;
281	uint64_t sum;
282	uint8_t *ptr;
283	int i, r;
284
285	req.alloc_size = 4*1024; /* msg */
286	req.alloc_size += 4*1024; /* fb */
287	if (family_id >= AMDGPU_FAMILY_VI)
288		req.alloc_size += 4096; /*it_scaling_table*/
289	req.alloc_size += ALIGN(sizeof(uvd_bitstream), 4*1024);
290	req.alloc_size += ALIGN(dpb_size, 4*1024);
291	req.alloc_size += ALIGN(dt_size, 4*1024);
292
293	req.preferred_heap = AMDGPU_GEM_DOMAIN_GTT;
294
295	r = amdgpu_bo_alloc(device_handle, &req, &buf_handle);
296	CU_ASSERT_EQUAL(r, 0);
297
298	r = amdgpu_va_range_alloc(device_handle,
299				  amdgpu_gpu_va_range_general,
300				  req.alloc_size, 1, 0, &va,
301				  &va_handle, 0);
302	CU_ASSERT_EQUAL(r, 0);
303
304	r = amdgpu_bo_va_op(buf_handle, 0, req.alloc_size, va, 0,
305			    AMDGPU_VA_OP_MAP);
306	CU_ASSERT_EQUAL(r, 0);
307
308	r = amdgpu_bo_cpu_map(buf_handle, (void **)&ptr);
309	CU_ASSERT_EQUAL(r, 0);
310
311	memcpy(ptr, uvd_decode_msg, sizeof(uvd_decode_msg));
312	memcpy(ptr + sizeof(uvd_decode_msg), avc_decode_msg, sizeof(avc_decode_msg));
313
314	if (family_id >= AMDGPU_FAMILY_VI) {
315		ptr[0x10] = 7;
316		ptr[0x98] = 0x00;
317		ptr[0x99] = 0x02;
318		/* chip beyond polaris10/11 */
319		if ((family_id == AMDGPU_FAMILY_AI) ||
320		    (chip_id == chip_rev+0x50 || chip_id == chip_rev+0x5A ||
321		     chip_id == chip_rev+0x64)) {
322			/* dpb size */
323			ptr[0x24] = 0x00;
324			ptr[0x25] = 0x94;
325			ptr[0x26] = 0x6B;
326			ptr[0x27] = 0x00;
327			/*ctx size */
328			ptr[0x2C] = 0x00;
329			ptr[0x2D] = 0xAF;
330			ptr[0x2E] = 0x50;
331			ptr[0x2F] = 0x00;
332		}
333	}
334
335	ptr += 4*1024;
336	memset(ptr, 0, 4*1024);
337	if (family_id >= AMDGPU_FAMILY_VI) {
338		ptr += 4*1024;
339		memcpy(ptr, uvd_it_scaling_table, sizeof(uvd_it_scaling_table));
340	}
341
342	ptr += 4*1024;
343	memcpy(ptr, uvd_bitstream, sizeof(uvd_bitstream));
344
345	ptr += ALIGN(sizeof(uvd_bitstream), 4*1024);
346	memset(ptr, 0, dpb_size);
347
348	ptr += ALIGN(dpb_size, 4*1024);
349	memset(ptr, 0, dt_size);
350
351	num_resources = 0;
352	resources[num_resources++] = buf_handle;
353	resources[num_resources++] = ib_handle;
354
355	msg_addr = va;
356	fb_addr = msg_addr + 4*1024;
357	if (family_id >= AMDGPU_FAMILY_VI) {
358		it_addr = fb_addr + 4*1024;
359		bs_addr = it_addr + 4*1024;
360	} else
361		bs_addr = fb_addr + 4*1024;
362	dpb_addr = ALIGN(bs_addr + sizeof(uvd_bitstream), 4*1024);
363
364	ctx_addr = 0;
365	if (family_id >= AMDGPU_FAMILY_VI) {
366		if ((family_id == AMDGPU_FAMILY_AI) ||
367		    (chip_id == chip_rev+0x50 || chip_id == chip_rev+0x5A ||
368		     chip_id == chip_rev+0x64)) {
369			ctx_addr = ALIGN(dpb_addr + 0x006B9400, 4*1024);
370		}
371	}
372
373	dt_addr = ALIGN(dpb_addr + dpb_size, 4*1024);
374
375	i = 0;
376	uvd_cmd(msg_addr, 0x0, &i);
377	uvd_cmd(dpb_addr, 0x1, &i);
378	uvd_cmd(dt_addr, 0x2, &i);
379	uvd_cmd(fb_addr, 0x3, &i);
380	uvd_cmd(bs_addr, 0x100, &i);
381
382	if (family_id >= AMDGPU_FAMILY_VI) {
383		uvd_cmd(it_addr, 0x204, &i);
384		if ((family_id == AMDGPU_FAMILY_AI) ||
385		    (chip_id == chip_rev+0x50 || chip_id == chip_rev+0x5A ||
386		     chip_id == chip_rev+0x64))
387			uvd_cmd(ctx_addr, 0x206, &i);
388	}
389
390	ib_cpu[i++] = (family_id < AMDGPU_FAMILY_AI) ? 0x3BC6 : 0x81C6;
391	ib_cpu[i++] = 0x1;
392	for (; i % 16; ++i)
393		ib_cpu[i] = 0x80000000;
394
395	r = submit(i, AMDGPU_HW_IP_UVD);
396	CU_ASSERT_EQUAL(r, 0);
397
398	/* TODO: use a real CRC32 */
399	for (i = 0, sum = 0; i < dt_size; ++i)
400		sum += ptr[i];
401	CU_ASSERT_EQUAL(sum, SUM_DECODE);
402
403	r = amdgpu_bo_cpu_unmap(buf_handle);
404	CU_ASSERT_EQUAL(r, 0);
405
406	r = amdgpu_bo_va_op(buf_handle, 0, req.alloc_size, va, 0, AMDGPU_VA_OP_UNMAP);
407	CU_ASSERT_EQUAL(r, 0);
408
409	r = amdgpu_va_range_free(va_handle);
410	CU_ASSERT_EQUAL(r, 0);
411
412	r = amdgpu_bo_free(buf_handle);
413	CU_ASSERT_EQUAL(r, 0);
414}
415
416static void amdgpu_cs_uvd_destroy(void)
417{
418	struct amdgpu_bo_alloc_request req = {0};
419	amdgpu_bo_handle buf_handle;
420	amdgpu_va_handle va_handle;
421	uint64_t va = 0;
422	void *msg;
423	int i, r;
424
425	req.alloc_size = 4*1024;
426	req.preferred_heap = AMDGPU_GEM_DOMAIN_GTT;
427
428	r = amdgpu_bo_alloc(device_handle, &req, &buf_handle);
429	CU_ASSERT_EQUAL(r, 0);
430
431	r = amdgpu_va_range_alloc(device_handle,
432				  amdgpu_gpu_va_range_general,
433				  req.alloc_size, 1, 0, &va,
434				  &va_handle, 0);
435	CU_ASSERT_EQUAL(r, 0);
436
437	r = amdgpu_bo_va_op(buf_handle, 0, req.alloc_size, va, 0,
438			    AMDGPU_VA_OP_MAP);
439	CU_ASSERT_EQUAL(r, 0);
440
441	r = amdgpu_bo_cpu_map(buf_handle, &msg);
442	CU_ASSERT_EQUAL(r, 0);
443
444	memcpy(msg, uvd_destroy_msg, sizeof(uvd_destroy_msg));
445	if (family_id >= AMDGPU_FAMILY_VI)
446		((uint8_t*)msg)[0x10] = 7;
447
448	r = amdgpu_bo_cpu_unmap(buf_handle);
449	CU_ASSERT_EQUAL(r, 0);
450
451	num_resources = 0;
452	resources[num_resources++] = buf_handle;
453	resources[num_resources++] = ib_handle;
454
455	i = 0;
456	uvd_cmd(va, 0x0, &i);
457	for (; i % 16; ++i)
458		ib_cpu[i] = 0x80000000;
459
460	r = submit(i, AMDGPU_HW_IP_UVD);
461	CU_ASSERT_EQUAL(r, 0);
462
463	r = amdgpu_bo_va_op(buf_handle, 0, req.alloc_size, va, 0, AMDGPU_VA_OP_UNMAP);
464	CU_ASSERT_EQUAL(r, 0);
465
466	r = amdgpu_va_range_free(va_handle);
467	CU_ASSERT_EQUAL(r, 0);
468
469	r = amdgpu_bo_free(buf_handle);
470	CU_ASSERT_EQUAL(r, 0);
471}
472