Home | History | Annotate | Download | only in amdgpu
      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 #ifdef HAVE_CONFIG_H
     25 #include "config.h"
     26 #endif
     27 
     28 #include <stdio.h>
     29 
     30 #include "CUnit/Basic.h"
     31 
     32 #include "util_math.h"
     33 
     34 #include "amdgpu_test.h"
     35 #include "uvd_messages.h"
     36 #include "amdgpu_drm.h"
     37 #include "amdgpu_internal.h"
     38 
     39 #define IB_SIZE		4096
     40 #define MAX_RESOURCES	16
     41 
     42 static amdgpu_device_handle device_handle;
     43 static uint32_t major_version;
     44 static uint32_t minor_version;
     45 static uint32_t family_id;
     46 
     47 static amdgpu_context_handle context_handle;
     48 static amdgpu_bo_handle ib_handle;
     49 static uint64_t ib_mc_address;
     50 static uint32_t *ib_cpu;
     51 static amdgpu_va_handle ib_va_handle;
     52 
     53 static amdgpu_bo_handle resources[MAX_RESOURCES];
     54 static unsigned num_resources;
     55 
     56 static void amdgpu_cs_uvd_create(void);
     57 static void amdgpu_cs_uvd_decode(void);
     58 static void amdgpu_cs_uvd_destroy(void);
     59 
     60 CU_TestInfo cs_tests[] = {
     61 	{ "UVD create",  amdgpu_cs_uvd_create },
     62 	{ "UVD decode",  amdgpu_cs_uvd_decode },
     63 	{ "UVD destroy",  amdgpu_cs_uvd_destroy },
     64 	CU_TEST_INFO_NULL,
     65 };
     66 
     67 int suite_cs_tests_init(void)
     68 {
     69 	amdgpu_bo_handle ib_result_handle;
     70 	void *ib_result_cpu;
     71 	uint64_t ib_result_mc_address;
     72 	amdgpu_va_handle ib_result_va_handle;
     73 	int r;
     74 
     75 	r = amdgpu_device_initialize(drm_amdgpu[0], &major_version,
     76 				     &minor_version, &device_handle);
     77 	if (r)
     78 		return CUE_SINIT_FAILED;
     79 
     80 	family_id = device_handle->info.family_id;
     81 
     82 	r = amdgpu_cs_ctx_create(device_handle, &context_handle);
     83 	if (r)
     84 		return CUE_SINIT_FAILED;
     85 
     86 	r = amdgpu_bo_alloc_and_map(device_handle, IB_SIZE, 4096,
     87 				    AMDGPU_GEM_DOMAIN_GTT, 0,
     88 				    &ib_result_handle, &ib_result_cpu,
     89 				    &ib_result_mc_address,
     90 				    &ib_result_va_handle);
     91 	if (r)
     92 		return CUE_SINIT_FAILED;
     93 
     94 	ib_handle = ib_result_handle;
     95 	ib_mc_address = ib_result_mc_address;
     96 	ib_cpu = ib_result_cpu;
     97 	ib_va_handle = ib_result_va_handle;
     98 
     99 	return CUE_SUCCESS;
    100 }
    101 
    102 int suite_cs_tests_clean(void)
    103 {
    104 	int r;
    105 
    106 	r = amdgpu_bo_unmap_and_free(ib_handle, ib_va_handle,
    107 				     ib_mc_address, IB_SIZE);
    108 	if (r)
    109 		return CUE_SCLEAN_FAILED;
    110 
    111 	r = amdgpu_cs_ctx_free(context_handle);
    112 	if (r)
    113 		return CUE_SCLEAN_FAILED;
    114 
    115 	r = amdgpu_device_deinitialize(device_handle);
    116 	if (r)
    117 		return CUE_SCLEAN_FAILED;
    118 
    119 	return CUE_SUCCESS;
    120 }
    121 
    122 static int submit(unsigned ndw, unsigned ip)
    123 {
    124 	struct amdgpu_cs_request ibs_request = {0};
    125 	struct amdgpu_cs_ib_info ib_info = {0};
    126 	struct amdgpu_cs_fence fence_status = {0};
    127 	uint32_t expired;
    128 	int r;
    129 
    130 	ib_info.ib_mc_address = ib_mc_address;
    131 	ib_info.size = ndw;
    132 
    133 	ibs_request.ip_type = ip;
    134 
    135 	r = amdgpu_bo_list_create(device_handle, num_resources, resources,
    136 				  NULL, &ibs_request.resources);
    137 	if (r)
    138 		return r;
    139 
    140 	ibs_request.number_of_ibs = 1;
    141 	ibs_request.ibs = &ib_info;
    142 	ibs_request.fence_info.handle = NULL;
    143 
    144 	r = amdgpu_cs_submit(context_handle, 0, &ibs_request, 1);
    145 	if (r)
    146 		return r;
    147 
    148 	r = amdgpu_bo_list_destroy(ibs_request.resources);
    149 	if (r)
    150 		return r;
    151 
    152 	fence_status.context = context_handle;
    153 	fence_status.ip_type = ip;
    154 	fence_status.fence = ibs_request.seq_no;
    155 
    156 	r = amdgpu_cs_query_fence_status(&fence_status,
    157 					 AMDGPU_TIMEOUT_INFINITE,
    158 					 0, &expired);
    159 	if (r)
    160 		return r;
    161 
    162 	return 0;
    163 }
    164 
    165 static void uvd_cmd(uint64_t addr, unsigned cmd, int *idx)
    166 {
    167 	ib_cpu[(*idx)++] = 0x3BC4;
    168 	ib_cpu[(*idx)++] = addr;
    169 	ib_cpu[(*idx)++] = 0x3BC5;
    170 	ib_cpu[(*idx)++] = addr >> 32;
    171 	ib_cpu[(*idx)++] = 0x3BC3;
    172 	ib_cpu[(*idx)++] = cmd << 1;
    173 }
    174 
    175 static void amdgpu_cs_uvd_create(void)
    176 {
    177 	struct amdgpu_bo_alloc_request req = {0};
    178 	amdgpu_bo_handle buf_handle;
    179 	uint64_t va = 0;
    180 	amdgpu_va_handle va_handle;
    181 	void *msg;
    182 	int i, r;
    183 
    184 	req.alloc_size = 4*1024;
    185 	req.preferred_heap = AMDGPU_GEM_DOMAIN_GTT;
    186 
    187 	r = amdgpu_bo_alloc(device_handle, &req, &buf_handle);
    188 	CU_ASSERT_EQUAL(r, 0);
    189 
    190 	r = amdgpu_va_range_alloc(device_handle,
    191 				  amdgpu_gpu_va_range_general,
    192 				  4096, 1, 0, &va,
    193 				  &va_handle, 0);
    194 	CU_ASSERT_EQUAL(r, 0);
    195 
    196 	r = amdgpu_bo_va_op(buf_handle, 0, 4096, va, 0, AMDGPU_VA_OP_MAP);
    197 	CU_ASSERT_EQUAL(r, 0);
    198 
    199 	r = amdgpu_bo_cpu_map(buf_handle, &msg);
    200 	CU_ASSERT_EQUAL(r, 0);
    201 
    202 	memcpy(msg, uvd_create_msg, sizeof(uvd_create_msg));
    203 	if (family_id >= AMDGPU_FAMILY_VI)
    204 		((uint8_t*)msg)[0x10] = 7;
    205 
    206 	r = amdgpu_bo_cpu_unmap(buf_handle);
    207 	CU_ASSERT_EQUAL(r, 0);
    208 
    209 	num_resources = 0;
    210 	resources[num_resources++] = buf_handle;
    211 	resources[num_resources++] = ib_handle;
    212 
    213 	i = 0;
    214 	uvd_cmd(va, 0x0, &i);
    215 	for (; i % 16; ++i)
    216 		ib_cpu[i] = 0x80000000;
    217 
    218 	r = submit(i, AMDGPU_HW_IP_UVD);
    219 	CU_ASSERT_EQUAL(r, 0);
    220 
    221 	r = amdgpu_bo_va_op(buf_handle, 0, 4096, va, 0, AMDGPU_VA_OP_UNMAP);
    222 	CU_ASSERT_EQUAL(r, 0);
    223 
    224 	r = amdgpu_va_range_free(va_handle);
    225 	CU_ASSERT_EQUAL(r, 0);
    226 
    227 	r = amdgpu_bo_free(buf_handle);
    228 	CU_ASSERT_EQUAL(r, 0);
    229 }
    230 
    231 static void amdgpu_cs_uvd_decode(void)
    232 {
    233 	const unsigned dpb_size = 15923584, dt_size = 737280;
    234 	uint64_t msg_addr, fb_addr, bs_addr, dpb_addr, dt_addr, it_addr;
    235 	struct amdgpu_bo_alloc_request req = {0};
    236 	amdgpu_bo_handle buf_handle;
    237 	amdgpu_va_handle va_handle;
    238 	uint64_t va = 0;
    239 	uint64_t sum;
    240 	uint8_t *ptr;
    241 	int i, r;
    242 
    243 	req.alloc_size = 4*1024; /* msg */
    244 	req.alloc_size += 4*1024; /* fb */
    245 	if (family_id >= AMDGPU_FAMILY_VI)
    246 		req.alloc_size += 4096; /*it_scaling_table*/
    247 	req.alloc_size += ALIGN(sizeof(uvd_bitstream), 4*1024);
    248 	req.alloc_size += ALIGN(dpb_size, 4*1024);
    249 	req.alloc_size += ALIGN(dt_size, 4*1024);
    250 
    251 	req.preferred_heap = AMDGPU_GEM_DOMAIN_GTT;
    252 
    253 	r = amdgpu_bo_alloc(device_handle, &req, &buf_handle);
    254 	CU_ASSERT_EQUAL(r, 0);
    255 
    256 	r = amdgpu_va_range_alloc(device_handle,
    257 				  amdgpu_gpu_va_range_general,
    258 				  req.alloc_size, 1, 0, &va,
    259 				  &va_handle, 0);
    260 	CU_ASSERT_EQUAL(r, 0);
    261 
    262 	r = amdgpu_bo_va_op(buf_handle, 0, req.alloc_size, va, 0,
    263 			    AMDGPU_VA_OP_MAP);
    264 	CU_ASSERT_EQUAL(r, 0);
    265 
    266 	r = amdgpu_bo_cpu_map(buf_handle, (void **)&ptr);
    267 	CU_ASSERT_EQUAL(r, 0);
    268 
    269 	memcpy(ptr, uvd_decode_msg, sizeof(uvd_decode_msg));
    270 	if (family_id >= AMDGPU_FAMILY_VI)
    271 		ptr[0x10] = 7;
    272 
    273 	ptr += 4*1024;
    274 	memset(ptr, 0, 4*1024);
    275 	if (family_id >= AMDGPU_FAMILY_VI) {
    276 		ptr += 4*1024;
    277 		memcpy(ptr, uvd_it_scaling_table, sizeof(uvd_it_scaling_table));
    278 	}
    279 
    280 	ptr += 4*1024;
    281 	memcpy(ptr, uvd_bitstream, sizeof(uvd_bitstream));
    282 
    283 	ptr += ALIGN(sizeof(uvd_bitstream), 4*1024);
    284 	memset(ptr, 0, dpb_size);
    285 
    286 	ptr += ALIGN(dpb_size, 4*1024);
    287 	memset(ptr, 0, dt_size);
    288 
    289 	num_resources = 0;
    290 	resources[num_resources++] = buf_handle;
    291 	resources[num_resources++] = ib_handle;
    292 
    293 	msg_addr = va;
    294 	fb_addr = msg_addr + 4*1024;
    295 	if (family_id >= AMDGPU_FAMILY_VI) {
    296 		it_addr = fb_addr + 4*1024;
    297 		bs_addr = it_addr + 4*1024;
    298 	} else
    299 		bs_addr = fb_addr + 4*1024;
    300 	dpb_addr = ALIGN(bs_addr + sizeof(uvd_bitstream), 4*1024);
    301 	dt_addr = ALIGN(dpb_addr + dpb_size, 4*1024);
    302 
    303 	i = 0;
    304 	uvd_cmd(msg_addr, 0x0, &i);
    305 	uvd_cmd(dpb_addr, 0x1, &i);
    306 	uvd_cmd(dt_addr, 0x2, &i);
    307 	uvd_cmd(fb_addr, 0x3, &i);
    308 	uvd_cmd(bs_addr, 0x100, &i);
    309 	if (family_id >= AMDGPU_FAMILY_VI)
    310 		uvd_cmd(it_addr, 0x204, &i);
    311 	ib_cpu[i++] = 0x3BC6;
    312 	ib_cpu[i++] = 0x1;
    313 	for (; i % 16; ++i)
    314 		ib_cpu[i] = 0x80000000;
    315 
    316 	r = submit(i, AMDGPU_HW_IP_UVD);
    317 	CU_ASSERT_EQUAL(r, 0);
    318 
    319 	/* TODO: use a real CRC32 */
    320 	for (i = 0, sum = 0; i < dt_size; ++i)
    321 		sum += ptr[i];
    322 	CU_ASSERT_EQUAL(sum, 0x20345d8);
    323 
    324 	r = amdgpu_bo_cpu_unmap(buf_handle);
    325 	CU_ASSERT_EQUAL(r, 0);
    326 
    327 	r = amdgpu_bo_va_op(buf_handle, 0, req.alloc_size, va, 0, AMDGPU_VA_OP_UNMAP);
    328 	CU_ASSERT_EQUAL(r, 0);
    329 
    330 	r = amdgpu_va_range_free(va_handle);
    331 	CU_ASSERT_EQUAL(r, 0);
    332 
    333 	r = amdgpu_bo_free(buf_handle);
    334 	CU_ASSERT_EQUAL(r, 0);
    335 }
    336 
    337 static void amdgpu_cs_uvd_destroy(void)
    338 {
    339 	struct amdgpu_bo_alloc_request req = {0};
    340 	amdgpu_bo_handle buf_handle;
    341 	amdgpu_va_handle va_handle;
    342 	uint64_t va = 0;
    343 	void *msg;
    344 	int i, r;
    345 
    346 	req.alloc_size = 4*1024;
    347 	req.preferred_heap = AMDGPU_GEM_DOMAIN_GTT;
    348 
    349 	r = amdgpu_bo_alloc(device_handle, &req, &buf_handle);
    350 	CU_ASSERT_EQUAL(r, 0);
    351 
    352 	r = amdgpu_va_range_alloc(device_handle,
    353 				  amdgpu_gpu_va_range_general,
    354 				  req.alloc_size, 1, 0, &va,
    355 				  &va_handle, 0);
    356 	CU_ASSERT_EQUAL(r, 0);
    357 
    358 	r = amdgpu_bo_va_op(buf_handle, 0, req.alloc_size, va, 0,
    359 			    AMDGPU_VA_OP_MAP);
    360 	CU_ASSERT_EQUAL(r, 0);
    361 
    362 	r = amdgpu_bo_cpu_map(buf_handle, &msg);
    363 	CU_ASSERT_EQUAL(r, 0);
    364 
    365 	memcpy(msg, uvd_destroy_msg, sizeof(uvd_destroy_msg));
    366 	if (family_id >= AMDGPU_FAMILY_VI)
    367 		((uint8_t*)msg)[0x10] = 7;
    368 
    369 	r = amdgpu_bo_cpu_unmap(buf_handle);
    370 	CU_ASSERT_EQUAL(r, 0);
    371 
    372 	num_resources = 0;
    373 	resources[num_resources++] = buf_handle;
    374 	resources[num_resources++] = ib_handle;
    375 
    376 	i = 0;
    377 	uvd_cmd(va, 0x0, &i);
    378 	for (; i % 16; ++i)
    379 		ib_cpu[i] = 0x80000000;
    380 
    381 	r = submit(i, AMDGPU_HW_IP_UVD);
    382 	CU_ASSERT_EQUAL(r, 0);
    383 
    384 	r = amdgpu_bo_va_op(buf_handle, 0, req.alloc_size, va, 0, AMDGPU_VA_OP_UNMAP);
    385 	CU_ASSERT_EQUAL(r, 0);
    386 
    387 	r = amdgpu_va_range_free(va_handle);
    388 	CU_ASSERT_EQUAL(r, 0);
    389 
    390 	r = amdgpu_bo_free(buf_handle);
    391 	CU_ASSERT_EQUAL(r, 0);
    392 }
    393