[igt-dev] [PATCH i-g-t v1] tests/amdgpu: refactoring and update amd_basic tests
vitaly.prosyak at amd.com
vitaly.prosyak at amd.com
Wed May 18 22:42:43 UTC 2022
From: Vitaly Prosyak <vitaly.prosyak at amd.com>
1. Create auxiliary directory amdgpu into igt-gpu-tools/lib
Put all helpers and reusable functions into this directory using
the following assumptions:
- group memory alloc/free functions into separate file amd_memory.c and h.
- group command submissions helper functions for GFX, COMPUTE and SDMA into
separate file amd_command_submission.c and h.
- for compute put nop command submission into separate file amd_compute.c and h.
- for graphics put command submission into separate file amd_gfx.c and h.
- for fence put command submission into separate file amd_fence.c and h.
2. Simplify implementation and reduce the number of local variables and allocations.
3. The file igt-gpu-tools/tests/amdgpu/amd_basic.c has only functions responsible
for single sub test:
- amdgpu_memory_alloc
- amdgpu_userptr_test
- amdgpu_command_submission_gfx
- amdgpu_command_submission_compute
- amdgpu_command_submission_multi_fence
- amdgpu_command_submission_sdma
- amdgpu_semaphore_test
4. No helper functions into amd_basic.c file.
5. Updated command submissions for secure buffer.
Signed-off-by: Vitaly Prosyak <vitaly.prosyak at amd.com>
---
lib/amdgpu/amd_PM4.h | 201 +++++
lib/amdgpu/amd_command_submission.c | 355 ++++++++
lib/amdgpu/amd_command_submission.h | 43 +
lib/amdgpu/amd_compute.c | 107 +++
lib/amdgpu/amd_compute.h | 31 +
lib/amdgpu/amd_family.h | 161 ++++
lib/amdgpu/amd_fence.c | 123 +++
lib/amdgpu/amd_fence.h | 33 +
lib/amdgpu/amd_gfx.c | 196 +++++
lib/amdgpu/amd_gfx.h | 35 +
lib/amdgpu/amd_ip_blocks.c | 557 ++++++++++++
lib/amdgpu/amd_ip_blocks.h | 114 +++
lib/amdgpu/amd_memory.c | 198 +++++
lib/amdgpu/amd_memory.h | 62 ++
lib/amdgpu/amd_sdma.h | 76 ++
lib/amdgpu/amdgpu_asic_addr.h | 172 ++++
lib/meson.build | 10 +
tests/amdgpu/amd_basic.c | 1242 +++------------------------
18 files changed, 2587 insertions(+), 1129 deletions(-)
create mode 100644 lib/amdgpu/amd_PM4.h
create mode 100644 lib/amdgpu/amd_command_submission.c
create mode 100644 lib/amdgpu/amd_command_submission.h
create mode 100644 lib/amdgpu/amd_compute.c
create mode 100644 lib/amdgpu/amd_compute.h
create mode 100644 lib/amdgpu/amd_family.h
create mode 100644 lib/amdgpu/amd_fence.c
create mode 100644 lib/amdgpu/amd_fence.h
create mode 100644 lib/amdgpu/amd_gfx.c
create mode 100644 lib/amdgpu/amd_gfx.h
create mode 100644 lib/amdgpu/amd_ip_blocks.c
create mode 100644 lib/amdgpu/amd_ip_blocks.h
create mode 100644 lib/amdgpu/amd_memory.c
create mode 100644 lib/amdgpu/amd_memory.h
create mode 100644 lib/amdgpu/amd_sdma.h
create mode 100644 lib/amdgpu/amdgpu_asic_addr.h
diff --git a/lib/amdgpu/amd_PM4.h b/lib/amdgpu/amd_PM4.h
new file mode 100644
index 00000000..a8a74e39
--- /dev/null
+++ b/lib/amdgpu/amd_PM4.h
@@ -0,0 +1,201 @@
+/*
+ * Copyright 2014 Advanced Micro Devices, Inc.
+ * Copyright 2022 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ *
+ */
+
+#ifndef AMD_PM4_H
+#define AMD_PM4_H
+
+/* PM4 */
+#define PACKET_TYPE0 0
+#define PACKET_TYPE1 1
+#define PACKET_TYPE2 2
+#define PACKET_TYPE3 3
+
+#define CP_PACKET_GET_TYPE(h) (((h) >> 30) & 3)
+#define CP_PACKET_GET_COUNT(h) (((h) >> 16) & 0x3FFF)
+#define CP_PACKET0_GET_REG(h) ((h) & 0xFFFF)
+#define CP_PACKET3_GET_OPCODE(h) (((h) >> 8) & 0xFF)
+#define PACKET0(reg, n) ((PACKET_TYPE0 << 30) | \
+ ((reg) & 0xFFFF) | \
+ ((n) & 0x3FFF) << 16)
+#define CP_PACKET2 0x80000000
+#define PACKET2_PAD_SHIFT 0
+#define PACKET2_PAD_MASK (0x3fffffff << 0)
+
+#define PACKET2(v) (CP_PACKET2 | REG_SET(PACKET2_PAD, (v)))
+
+#define PACKET3(op, n) ((PACKET_TYPE3 << 30) | \
+ (((op) & 0xFF) << 8) | \
+ ((n) & 0x3FFF) << 16)
+
+/* Packet 3 types */
+#define PACKET3_NOP 0x10
+
+#define PACKET3_WRITE_DATA 0x37
+#define WRITE_DATA_DST_SEL(x) ((x) << 8)
+ /* 0 - register
+ * 1 - memory (sync - via GRBM)
+ * 2 - gl2
+ * 3 - gds
+ * 4 - reserved
+ * 5 - memory (async - direct)
+ */
+#define WR_ONE_ADDR (1 << 16)
+#define WR_CONFIRM (1 << 20)
+#define WRITE_DATA_CACHE_POLICY(x) ((x) << 25)
+ /* 0 - LRU
+ * 1 - Stream
+ */
+#define WRITE_DATA_ENGINE_SEL(x) ((x) << 30)
+ /* 0 - me
+ * 1 - pfp
+ * 2 - ce
+ */
+
+#define PACKET3_DMA_DATA 0x50
+/* 1. header
+ * 2. CONTROL
+ * 3. SRC_ADDR_LO or DATA [31:0]
+ * 4. SRC_ADDR_HI [31:0]
+ * 5. DST_ADDR_LO [31:0]
+ * 6. DST_ADDR_HI [7:0]
+ * 7. COMMAND [30:21] | BYTE_COUNT [20:0]
+ */
+/* CONTROL */
+# define PACKET3_DMA_DATA_ENGINE(x) ((x) << 0)
+ /* 0 - ME
+ * 1 - PFP
+ */
+# define PACKET3_DMA_DATA_SRC_CACHE_POLICY(x) ((x) << 13)
+ /* 0 - LRU
+ * 1 - Stream
+ * 2 - Bypass
+ */
+# define PACKET3_DMA_DATA_SRC_VOLATILE (1 << 15)
+# define PACKET3_DMA_DATA_DST_SEL(x) ((x) << 20)
+ /* 0 - DST_ADDR using DAS
+ * 1 - GDS
+ * 3 - DST_ADDR using L2
+ */
+# define PACKET3_DMA_DATA_DST_CACHE_POLICY(x) ((x) << 25)
+ /* 0 - LRU
+ * 1 - Stream
+ * 2 - Bypass
+ */
+# define PACKET3_DMA_DATA_DST_VOLATILE (1 << 27)
+# define PACKET3_DMA_DATA_SRC_SEL(x) ((x) << 29)
+ /* 0 - SRC_ADDR using SAS
+ * 1 - GDS
+ * 2 - DATA
+ * 3 - SRC_ADDR using L2
+ */
+# define PACKET3_DMA_DATA_CP_SYNC (1 << 31)
+/* COMMAND */
+# define PACKET3_DMA_DATA_DIS_WC (1 << 21)
+# define PACKET3_DMA_DATA_CMD_SRC_SWAP(x) ((x) << 22)
+ /* 0 - none
+ * 1 - 8 in 16
+ * 2 - 8 in 32
+ * 3 - 8 in 64
+ */
+# define PACKET3_DMA_DATA_CMD_DST_SWAP(x) ((x) << 24)
+ /* 0 - none
+ * 1 - 8 in 16
+ * 2 - 8 in 32
+ * 3 - 8 in 64
+ */
+# define PACKET3_DMA_DATA_CMD_SAS (1 << 26)
+ /* 0 - memory
+ * 1 - register
+ */
+# define PACKET3_DMA_DATA_CMD_DAS (1 << 27)
+ /* 0 - memory
+ * 1 - register
+ */
+# define PACKET3_DMA_DATA_CMD_SAIC (1 << 28)
+# define PACKET3_DMA_DATA_CMD_DAIC (1 << 29)
+# define PACKET3_DMA_DATA_CMD_RAW_WAIT (1 << 30)
+
+
+#define PACKET3_ATOMIC_MEM 0x1E
+#define TC_OP_ATOMIC_CMPSWAP_RTN_32 0x00000008
+#define ATOMIC_MEM_COMMAND(x) ((x) << 8)
+ /* 0 - single_pass_atomic.
+ * 1 - loop_until_compare_satisfied.
+ */
+#define ATOMIC_MEM_CACHEPOLICAY(x) ((x) << 25)
+ /* 0 - lru.
+ * 1 - stream.
+ */
+#define ATOMIC_MEM_ENGINESEL(x) ((x) << 30)
+ /* 0 - micro_engine.*/
+
+#define SDMA_PACKET_SI(op, b, t, s, cnt) ((((op) & 0xF) << 28) | \
+ (((b) & 0x1) << 26) | \
+ (((t) & 0x1) << 23) | \
+ (((s) & 0x1) << 22) | \
+ (((cnt) & 0xFFFFF) << 0))
+#define SDMA_OPCODE_COPY_SI 3
+#define SDMA_OPCODE_CONSTANT_FILL_SI 13
+#define SDMA_NOP_SI 0xf
+#define GFX_COMPUTE_NOP_SI 0x80000000
+#define PACKET3_DMA_DATA_SI 0x41
+# define PACKET3_DMA_DATA_SI_ENGINE(x) ((x) << 27)
+ /* 0 - ME
+ * 1 - PFP
+ */
+# define PACKET3_DMA_DATA_SI_DST_SEL(x) ((x) << 20)
+ /* 0 - DST_ADDR using DAS
+ * 1 - GDS
+ * 3 - DST_ADDR using L2
+ */
+# define PACKET3_DMA_DATA_SI_SRC_SEL(x) ((x) << 29)
+ /* 0 - SRC_ADDR using SAS
+ * 1 - GDS
+ * 2 - DATA
+ * 3 - SRC_ADDR using L2
+ */
+# define PACKET3_DMA_DATA_SI_CP_SYNC (1 << 31)
+
+
+#define PKT3_CONTEXT_CONTROL 0x28
+#define CONTEXT_CONTROL_LOAD_ENABLE(x) (((unsigned)(x) & 0x1) << 31)
+#define CONTEXT_CONTROL_LOAD_CE_RAM(x) (((unsigned)(x) & 0x1) << 28)
+#define CONTEXT_CONTROL_SHADOW_ENABLE(x) (((unsigned)(x) & 0x1) << 31)
+
+#define PKT3_CLEAR_STATE 0x12
+
+#define PKT3_SET_SH_REG 0x76
+#define PACKET3_SET_SH_REG_START 0x00002c00
+
+#define PKT3_SET_SH_REG_INDEX 0x9B
+
+#define PACKET3_DISPATCH_DIRECT 0x15
+#define PACKET3_EVENT_WRITE 0x46
+#define PACKET3_ACQUIRE_MEM 0x58
+#define PACKET3_SET_CONTEXT_REG 0x69
+#define PACKET3_SET_UCONFIG_REG 0x79
+#define PACKET3_DRAW_INDEX_AUTO 0x2D
+
+#endif
diff --git a/lib/amdgpu/amd_command_submission.c b/lib/amdgpu/amd_command_submission.c
new file mode 100644
index 00000000..4dc4df95
--- /dev/null
+++ b/lib/amdgpu/amd_command_submission.c
@@ -0,0 +1,355 @@
+/*
+ * Copyright 2014 Advanced Micro Devices, Inc.
+ * Copyright 2022 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ *
+ */
+#include "lib/amdgpu/amd_memory.h"
+#include "lib/amdgpu/amd_sdma.h"
+#include "lib/amdgpu/amd_PM4.h"
+#include "lib/amdgpu/amd_command_submission.h"
+
+/*
+ *
+ * Caller need create/release:
+ * pm4_src, resources, ib_info, and ibs_request
+ * submit command stream described in ibs_request and wait for this IB accomplished
+ */
+
+void amdgpu_test_exec_cs_helper(amdgpu_device_handle device, unsigned ip_type,
+ struct amdgpu_ring_context *ring_context)
+{
+ int r;
+ uint32_t expired;
+ uint32_t *ring_ptr;
+ amdgpu_bo_handle ib_result_handle;
+ void *ib_result_cpu;
+ uint64_t ib_result_mc_address;
+ struct amdgpu_cs_fence fence_status = {0};
+ amdgpu_va_handle va_handle;
+
+ amdgpu_bo_handle *all_res = alloca(sizeof(ring_context->resources[0]) * (ring_context->res_cnt + 1));
+
+
+ /* prepare CS */
+ igt_assert(ring_context->pm4_dw <= 1024);
+
+ /* allocate IB */
+ r = amdgpu_bo_alloc_and_map(device, 4096, 4096,
+ AMDGPU_GEM_DOMAIN_GTT, 0,
+ &ib_result_handle, &ib_result_cpu,
+ &ib_result_mc_address, &va_handle);
+ igt_assert_eq(r, 0);
+
+ /* copy PM4 packet to ring from caller */
+ ring_ptr = ib_result_cpu;
+ memcpy(ring_ptr, ring_context->pm4, ring_context->pm4_dw * sizeof(*ring_context->pm4));
+
+ ring_context->ib_info.ib_mc_address = ib_result_mc_address;
+ ring_context->ib_info.size = ring_context->pm4_dw;
+ if (ring_context->secure)
+ ring_context->ib_info.flags |= AMDGPU_IB_FLAGS_SECURE;
+
+ ring_context->ibs_request.ip_type = ip_type;
+ ring_context->ibs_request.ring = ring_context->ring_id;
+ ring_context->ibs_request.number_of_ibs = 1;
+ ring_context->ibs_request.ibs = &ring_context->ib_info;
+ ring_context->ibs_request.fence_info.handle = NULL;
+
+ memcpy(all_res, ring_context->resources, sizeof(ring_context->resources[0]) * ring_context->res_cnt);
+ all_res[ring_context->res_cnt] = ib_result_handle;
+
+ r = amdgpu_bo_list_create(device, ring_context->res_cnt+1, all_res,
+ NULL, &ring_context->ibs_request.resources);
+ igt_assert_eq(r, 0);
+
+ /* submit CS */
+ r = amdgpu_cs_submit(ring_context->context_handle, 0, &ring_context->ibs_request, 1);
+ igt_assert_eq(r, 0);
+
+ r = amdgpu_bo_list_destroy(ring_context->ibs_request.resources);
+ igt_assert_eq(r, 0);
+
+ fence_status.ip_type = ip_type;
+ fence_status.ip_instance = 0;
+ fence_status.ring = ring_context->ibs_request.ring;
+ fence_status.context = ring_context->context_handle;
+ fence_status.fence = ring_context->ibs_request.seq_no;
+
+ /* wait for IB accomplished */
+ r = amdgpu_cs_query_fence_status(&fence_status,
+ AMDGPU_TIMEOUT_INFINITE,
+ 0, &expired);
+ igt_assert_eq(r, 0);
+ igt_assert_eq(expired, true);
+
+ amdgpu_bo_unmap_and_free(ib_result_handle, va_handle,
+ ib_result_mc_address, 4096);
+}
+
+void amdgpu_command_submission_write_linear_helper(amdgpu_device_handle device,
+ const struct amdgpu_ip_block_version *ip_block,
+ bool secure)
+
+{
+
+ const int sdma_write_length = 128;
+ const int pm4_dw = 256;
+
+ struct amdgpu_ring_context *ring_context;
+ int i, r, loop, ring_id;
+
+ uint64_t gtt_flags[2] = {0, AMDGPU_GEM_CREATE_CPU_GTT_USWC};
+
+ ring_context = calloc(1, sizeof(*ring_context));
+ igt_assert(ring_context);
+ /* setup parameters */
+ ring_context->write_length = sdma_write_length;
+ ring_context->pm4 = calloc(pm4_dw, sizeof(*ring_context->pm4));
+ ring_context->secure = secure;
+ ring_context->pm4_size = pm4_dw;
+ ring_context->res_cnt = 1;
+ igt_assert(ring_context->pm4);
+
+ r = amdgpu_query_hw_ip_info(device, ip_block->type, 0, &ring_context->hw_ip_info);
+ igt_assert_eq(r, 0);
+
+ for (i = 0; secure && (i < 2); i++)
+ gtt_flags[i] |= AMDGPU_GEM_CREATE_ENCRYPTED;
+
+ r = amdgpu_cs_ctx_create(device, &ring_context->context_handle);
+
+ igt_assert_eq(r, 0);
+
+ for (ring_id = 0; (1 << ring_id) & ring_context->hw_ip_info.available_rings; ring_id++) {
+ loop = 0;
+ while(loop < 2) {
+ /* allocate UC bo for sDMA use */
+ r = amdgpu_bo_alloc_and_map(device,
+ ring_context->write_length * sizeof(uint32_t),
+ 4096, AMDGPU_GEM_DOMAIN_GTT,
+ gtt_flags[loop], &ring_context->bo,
+ (void**)&ring_context->bo_cpu,
+ &ring_context->bo_mc,
+ &ring_context->va_handle);
+ igt_assert_eq(r, 0);
+
+ /* clear bo */
+ memset((void*)ring_context->bo_cpu, 0, ring_context->write_length * sizeof(uint32_t));
+
+ ring_context->resources[0] = ring_context->bo;
+
+ ip_block->funcs->write_linear(ip_block->funcs, ring_context, &ring_context->pm4_dw);
+
+ ring_context->ring_id = ring_id;
+
+ amdgpu_test_exec_cs_helper(device, ip_block->type, ring_context);
+
+ /* verify if SDMA test result meets with expected */
+ i = 0;
+ if (!secure) {
+ r = ip_block->funcs->compare(ip_block->funcs, ring_context, 1);
+ igt_assert_eq(r, 0);
+ } else if (ip_block->type == AMDGPU_HW_IP_GFX) {
+ ip_block->funcs->write_linear(ip_block->funcs, ring_context, &ring_context->pm4_dw);
+
+ amdgpu_test_exec_cs_helper(device, ip_block->type, ring_context);
+
+ } else if (ip_block->type == AMDGPU_HW_IP_DMA) {
+ /* restore the bo_cpu to compare */
+ ring_context->bo_cpu_origin = ring_context->bo_cpu[0];
+ ip_block->funcs->write_linear(ip_block->funcs, ring_context, &ring_context->pm4_dw);
+
+ amdgpu_test_exec_cs_helper(device, ip_block->type, ring_context);
+
+ /* restore again, here dest_data should be */
+ ring_context->bo_cpu_origin = ring_context->bo_cpu[0];
+ ip_block->funcs->write_linear(ip_block->funcs, ring_context, &ring_context->pm4_dw);
+
+ amdgpu_test_exec_cs_helper(device, ip_block->type, ring_context);
+ /* here bo_cpu[0] should be unchanged, still is 0x12345678, otherwise failed*/
+ igt_assert_eq(ring_context->bo_cpu[0], ring_context->bo_cpu_origin);
+ }
+
+ amdgpu_bo_unmap_and_free(ring_context->bo, ring_context->va_handle, ring_context->bo_mc,
+ ring_context->write_length * sizeof(uint32_t));
+ loop++;
+ }
+ }
+ /* clean resources */
+ free(ring_context->pm4);
+ free(ring_context);
+ /* end of test */
+ r = amdgpu_cs_ctx_free(ring_context->context_handle);
+ igt_assert_eq(r, 0);
+}
+
+
+/**
+ *
+ * @param device
+ * @param ip_type
+ */
+void amdgpu_command_submission_const_fill_helper(amdgpu_device_handle device,
+ const struct amdgpu_ip_block_version *ip_block)
+{
+ const int sdma_write_length = 1024 * 1024;
+ const int pm4_dw = 256;
+
+ struct amdgpu_ring_context *ring_context;
+ int r, loop;
+
+ uint64_t gtt_flags[2] = {0, AMDGPU_GEM_CREATE_CPU_GTT_USWC};
+
+ ring_context = calloc(1, sizeof(*ring_context));
+ ring_context->write_length = sdma_write_length;
+ ring_context->pm4 = calloc(pm4_dw, sizeof(*ring_context->pm4));
+ ring_context->secure = false;
+ ring_context->pm4_size = pm4_dw;
+ ring_context->res_cnt = 1;
+ igt_assert(ring_context->pm4);
+
+ r = amdgpu_cs_ctx_create(device, &ring_context->context_handle);
+ igt_assert_eq(r, 0);
+
+ /* prepare resource */
+ loop = 0;
+ while(loop < 2) {
+ /* allocate UC bo for sDMA use */
+ r = amdgpu_bo_alloc_and_map(device,
+ ring_context->write_length, 4096,
+ AMDGPU_GEM_DOMAIN_GTT,
+ gtt_flags[loop], &ring_context->bo, (void**)&ring_context->bo_cpu,
+ &ring_context->bo_mc, &ring_context->va_handle);
+ igt_assert_eq(r, 0);
+
+ /* clear bo */
+ memset((void*)ring_context->bo_cpu, 0, ring_context->write_length);
+
+ ring_context->resources[0] = ring_context->bo;
+
+ /* fulfill PM4: test DMA const fill */
+ ip_block->funcs->const_fill(ip_block->funcs, ring_context, &ring_context->pm4_dw);
+
+ amdgpu_test_exec_cs_helper(device, ip_block->type, ring_context);
+
+ /* verify if SDMA test result meets with expected */
+ r = ip_block->funcs->compare(ip_block->funcs, ring_context, 4);
+ igt_assert_eq(r, 0);
+
+ amdgpu_bo_unmap_and_free(ring_context->bo, ring_context->va_handle, ring_context->bo_mc,
+ ring_context->write_length);
+ loop++;
+ }
+ /* clean resources */
+ free(ring_context->pm4);
+
+ /* end of test */
+ r = amdgpu_cs_ctx_free(ring_context->context_handle);
+ igt_assert_eq(r, 0);
+ free(ring_context);
+}
+
+/**
+ *
+ * @param device
+ * @param ip_type
+ */
+void amdgpu_command_submission_copy_linear_helper(amdgpu_device_handle device,
+ const struct amdgpu_ip_block_version *ip_block)
+{
+ const int sdma_write_length = 1024;
+ const int pm4_dw = 256;
+
+ struct amdgpu_ring_context *ring_context;
+ int r, loop1, loop2;
+
+ uint64_t gtt_flags[2] = {0, AMDGPU_GEM_CREATE_CPU_GTT_USWC};
+
+
+ ring_context = calloc(1, sizeof(*ring_context));
+ ring_context->write_length = sdma_write_length;
+ ring_context->pm4 = calloc(pm4_dw, sizeof(*ring_context->pm4));
+ ring_context->secure = false;
+ ring_context->pm4_size = pm4_dw;
+ ring_context->res_cnt = 2;
+ igt_assert(ring_context->pm4);
+
+
+ r = amdgpu_cs_ctx_create(device, &ring_context->context_handle);
+ igt_assert_eq(r, 0);
+
+
+ loop1 = loop2 = 0;
+ /* run 9 circle to test all mapping combination */
+ while(loop1 < 2) {
+ while(loop2 < 2) {
+ /* allocate UC bo1for sDMA use */
+ r = amdgpu_bo_alloc_and_map(device,
+ ring_context->write_length, 4096,
+ AMDGPU_GEM_DOMAIN_GTT,
+ gtt_flags[loop1], &ring_context->bo,
+ (void**)&ring_context->bo_cpu, &ring_context->bo_mc,
+ &ring_context->va_handle);
+ igt_assert_eq(r, 0);
+
+ /* set bo_cpu */
+ memset((void*)ring_context->bo_cpu, ip_block->funcs->pattern, ring_context->write_length);
+
+ /* allocate UC bo2 for sDMA use */
+ r = amdgpu_bo_alloc_and_map(device,
+ ring_context->write_length, 4096,
+ AMDGPU_GEM_DOMAIN_GTT,
+ gtt_flags[loop2], &ring_context->bo2,
+ (void**)&ring_context->bo2_cpu, &ring_context->bo_mc2,
+ &ring_context->va_handle2);
+ igt_assert_eq(r, 0);
+
+ /* clear bo2_cpu */
+ memset((void*)ring_context->bo2_cpu, 0, ring_context->write_length);
+
+ ring_context->resources[0] = ring_context->bo;
+ ring_context->resources[1] = ring_context->bo2;
+
+ ip_block->funcs->copy_linear(ip_block->funcs, ring_context, &ring_context->pm4_dw);
+
+ amdgpu_test_exec_cs_helper(device, ip_block->type, ring_context);
+
+ /* verify if SDMA test result meets with expected */
+ r = ip_block->funcs->compare_pattern(ip_block->funcs, ring_context, 4);
+ igt_assert_eq(r, 0);
+
+ amdgpu_bo_unmap_and_free(ring_context->bo, ring_context->va_handle, ring_context->bo_mc,
+ ring_context->write_length);
+ amdgpu_bo_unmap_and_free(ring_context->bo2, ring_context->va_handle2, ring_context->bo_mc2,
+ ring_context->write_length);
+ loop2++;
+ }
+ loop1++;
+ }
+ /* clean resources */
+ free(ring_context->pm4);
+
+ /* end of test */
+ r = amdgpu_cs_ctx_free(ring_context->context_handle);
+ igt_assert_eq(r, 0);
+ free(ring_context);
+}
diff --git a/lib/amdgpu/amd_command_submission.h b/lib/amdgpu/amd_command_submission.h
new file mode 100644
index 00000000..0df7c2c1
--- /dev/null
+++ b/lib/amdgpu/amd_command_submission.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2012 Advanced Micro Devices, Inc.
+ * Copyright 2022 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ *
+ */
+
+#ifndef AMD_COMMAND_SUBMISSION
+#define AMD_COMMAND_SUBMISSION
+
+#include "amd_ip_blocks.h"
+
+void amdgpu_test_exec_cs_helper(amdgpu_device_handle device,
+ unsigned ip_type, struct amdgpu_ring_context *ring_context);
+
+void amdgpu_command_submission_write_linear_helper(amdgpu_device_handle device,
+ const struct amdgpu_ip_block_version *ip_block,
+ bool secure);
+
+void amdgpu_command_submission_const_fill_helper(amdgpu_device_handle device,
+ const struct amdgpu_ip_block_version *ip_block);
+
+void amdgpu_command_submission_copy_linear_helper(amdgpu_device_handle device,
+ const struct amdgpu_ip_block_version *ip_block);
+#endif
diff --git a/lib/amdgpu/amd_compute.c b/lib/amdgpu/amd_compute.c
new file mode 100644
index 00000000..5a7fa27e
--- /dev/null
+++ b/lib/amdgpu/amd_compute.c
@@ -0,0 +1,107 @@
+/*
+ * Copyright 2014 Advanced Micro Devices, Inc.
+ * Copyright 2022 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ *
+ */
+#include "amd_PM4.h"
+#include "amd_memory.h"
+#include "amd_compute.h"
+
+/**
+ *
+ * @param device
+ */
+void amdgpu_command_submission_compute_nop(amdgpu_device_handle device)
+{
+ amdgpu_context_handle context_handle;
+ amdgpu_bo_handle ib_result_handle;
+ void *ib_result_cpu;
+ uint64_t ib_result_mc_address;
+ struct amdgpu_cs_request ibs_request;
+ struct amdgpu_cs_ib_info ib_info;
+ struct amdgpu_cs_fence fence_status;
+ struct drm_amdgpu_info_hw_ip info;
+ uint32_t *ptr;
+ uint32_t expired;
+ int r, instance;
+ amdgpu_bo_list_handle bo_list;
+ amdgpu_va_handle va_handle;
+
+ r = amdgpu_query_hw_ip_info(device, AMDGPU_HW_IP_COMPUTE, 0, &info);
+ igt_assert_eq(r, 0);
+
+ r = amdgpu_cs_ctx_create(device, &context_handle);
+ igt_assert_eq(r, 0);
+
+ for (instance = 0; info.available_rings & (1 << instance); instance++) {
+ r = amdgpu_bo_alloc_and_map(device, 4096, 4096,
+ AMDGPU_GEM_DOMAIN_GTT, 0,
+ &ib_result_handle, &ib_result_cpu,
+ &ib_result_mc_address, &va_handle);
+ igt_assert_eq(r, 0);
+
+ r = amdgpu_get_bo_list(device, ib_result_handle, NULL,
+ &bo_list);
+ igt_assert_eq(r, 0);
+
+ ptr = ib_result_cpu;
+ memset(ptr, 0, 16);
+ ptr[0] = PACKET3(PACKET3_NOP, 14);
+
+ memset(&ib_info, 0, sizeof(struct amdgpu_cs_ib_info));
+ ib_info.ib_mc_address = ib_result_mc_address;
+ ib_info.size = 16;
+
+ memset(&ibs_request, 0, sizeof(struct amdgpu_cs_request));
+ ibs_request.ip_type = AMDGPU_HW_IP_COMPUTE;
+ ibs_request.ring = instance;
+ ibs_request.number_of_ibs = 1;
+ ibs_request.ibs = &ib_info;
+ ibs_request.resources = bo_list;
+ ibs_request.fence_info.handle = NULL;
+
+ memset(&fence_status, 0, sizeof(struct amdgpu_cs_fence));
+ r = amdgpu_cs_submit(context_handle, 0,&ibs_request, 1);
+ igt_assert_eq(r, 0);
+
+ fence_status.context = context_handle;
+ fence_status.ip_type = AMDGPU_HW_IP_COMPUTE;
+ fence_status.ip_instance = 0;
+ fence_status.ring = instance;
+ fence_status.fence = ibs_request.seq_no;
+
+ r = amdgpu_cs_query_fence_status(&fence_status,
+ AMDGPU_TIMEOUT_INFINITE,
+ 0, &expired);
+ igt_assert_eq(r, 0);
+
+ r = amdgpu_bo_list_destroy(bo_list);
+ igt_assert_eq(r, 0);
+
+ amdgpu_bo_unmap_and_free(ib_result_handle, va_handle,
+ ib_result_mc_address, 4096);
+ }
+
+ r = amdgpu_cs_ctx_free(context_handle);
+ igt_assert_eq(r, 0);
+}
+
diff --git a/lib/amdgpu/amd_compute.h b/lib/amdgpu/amd_compute.h
new file mode 100644
index 00000000..01eee606
--- /dev/null
+++ b/lib/amdgpu/amd_compute.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2014 Advanced Micro Devices, Inc.
+ * Copyright 2022 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ *
+ */
+#ifndef AMD_COMPUTE_H
+#define AMD_COMPUTE_H
+
+
+void amdgpu_command_submission_compute_nop(amdgpu_device_handle device);
+
+#endif
diff --git a/lib/amdgpu/amd_family.h b/lib/amdgpu/amd_family.h
new file mode 100644
index 00000000..20682483
--- /dev/null
+++ b/lib/amdgpu/amd_family.h
@@ -0,0 +1,161 @@
+/*
+ * Copyright 2008 Corbin Simpson <MostAwesomeDude at gmail.com>
+ * Copyright 2010 Marek Olšák <maraeo at gmail.com>
+ * Copyright 2022 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * on the rights to use, copy, modify, merge, publish, distribute, sub
+ * license, and/or sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE. */
+
+#ifndef AMD_FAMILY_H
+#define AMD_FAMILY_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+enum radeon_family
+{
+ CHIP_UNKNOWN = 0,
+ CHIP_R300, /* R3xx-based cores. (GFX2) */
+ CHIP_R350,
+ CHIP_RV350,
+ CHIP_RV370,
+ CHIP_RV380,
+ CHIP_RS400,
+ CHIP_RC410,
+ CHIP_RS480,
+ CHIP_R420, /* R4xx-based cores. (GFX2) */
+ CHIP_R423,
+ CHIP_R430,
+ CHIP_R480,
+ CHIP_R481,
+ CHIP_RV410,
+ CHIP_RS600,
+ CHIP_RS690,
+ CHIP_RS740,
+ CHIP_RV515, /* R5xx-based cores. (GFX2) */
+ CHIP_R520,
+ CHIP_RV530,
+ CHIP_R580,
+ CHIP_RV560,
+ CHIP_RV570,
+ CHIP_R600, /* GFX3 (R6xx) */
+ CHIP_RV610,
+ CHIP_RV630,
+ CHIP_RV670,
+ CHIP_RV620,
+ CHIP_RV635,
+ CHIP_RS780,
+ CHIP_RS880,
+ CHIP_RV770, /* GFX3 (R7xx) */
+ CHIP_RV730,
+ CHIP_RV710,
+ CHIP_RV740,
+ CHIP_CEDAR, /* GFX4 (Evergreen) */
+ CHIP_REDWOOD,
+ CHIP_JUNIPER,
+ CHIP_CYPRESS,
+ CHIP_HEMLOCK,
+ CHIP_PALM,
+ CHIP_SUMO,
+ CHIP_SUMO2,
+ CHIP_BARTS,
+ CHIP_TURKS,
+ CHIP_CAICOS,
+ CHIP_CAYMAN, /* GFX5 (Northern Islands) */
+ CHIP_ARUBA,
+ CHIP_TAHITI, /* GFX6 (Southern Islands) */
+ CHIP_PITCAIRN,
+ CHIP_VERDE,
+ CHIP_OLAND,
+ CHIP_HAINAN,
+ CHIP_BONAIRE, /* GFX7 (Sea Islands) */
+ CHIP_KAVERI,
+ CHIP_KABINI,
+ CHIP_HAWAII,
+ CHIP_TONGA, /* GFX8 (Volcanic Islands & Polaris) */
+ CHIP_ICELAND,
+ CHIP_CARRIZO,
+ CHIP_FIJI,
+ CHIP_STONEY,
+ CHIP_POLARIS10,
+ CHIP_POLARIS11,
+ CHIP_POLARIS12,
+ CHIP_VEGAM,
+ CHIP_VEGA10, /* GFX9 (Vega) */
+ CHIP_VEGA12,
+ CHIP_VEGA20,
+ CHIP_RAVEN,
+ CHIP_RAVEN2,
+ CHIP_RENOIR,
+ CHIP_ARCTURUS,
+ CHIP_ALDEBARAN,
+ CHIP_NAVI10,
+ CHIP_NAVI12,
+ CHIP_NAVI14,
+ CHIP_SIENNA_CICHLID,
+ CHIP_NAVY_FLOUNDER,
+ CHIP_VANGOGH,
+ CHIP_DIMGREY_CAVEFISH,
+ CHIP_BEIGE_GOBY,
+ CHIP_YELLOW_CARP,
+ CHIP_LAST,
+};
+
+enum chip_class
+{
+ CLASS_UNKNOWN = 0,
+ R300,
+ R400,
+ R500,
+ R600,
+ R700,
+ EVERGREEN,
+ CAYMAN,
+ GFX6,
+ GFX7,
+ GFX8,
+ GFX9,
+ GFX10,
+ GFX10_3,
+
+ NUM_GFX_VERSIONS,
+};
+
+enum ring_type
+{
+ RING_GFX = 0,
+ RING_COMPUTE,
+ RING_DMA,
+ RING_UVD,
+ RING_VCE,
+ RING_UVD_ENC,
+ RING_VCN_DEC,
+ RING_VCN_ENC,
+ RING_VCN_JPEG,
+ NUM_RING_TYPES,
+};
+
+const char *ac_get_family_name(enum radeon_family family);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/amdgpu/amd_fence.c b/lib/amdgpu/amd_fence.c
new file mode 100644
index 00000000..f6d2a1e6
--- /dev/null
+++ b/lib/amdgpu/amd_fence.c
@@ -0,0 +1,123 @@
+/*
+ * Copyright 2014 Advanced Micro Devices, Inc.
+ * Copyright 2022 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ *
+ */
+#include "amd_memory.h"
+#include "amd_fence.h"
+
+
+/**
+ * MULTI FENCE
+ * @param device
+ * @param wait_all
+ */
+void amdgpu_command_submission_multi_fence_wait_all(amdgpu_device_handle device,
+ bool wait_all)
+{
+ amdgpu_context_handle context_handle;
+ amdgpu_bo_handle ib_result_handle, ib_result_ce_handle;
+ void *ib_result_cpu, *ib_result_ce_cpu;
+ uint64_t ib_result_mc_address, ib_result_ce_mc_address;
+ struct amdgpu_cs_request ibs_request[2] = {};
+ struct amdgpu_cs_ib_info ib_info[2];
+ struct amdgpu_cs_fence fence_status[2] = {};
+ uint32_t *ptr;
+ uint32_t expired;
+ amdgpu_bo_list_handle bo_list;
+ amdgpu_va_handle va_handle, va_handle_ce;
+ int r;
+ int i, ib_cs_num = 2;
+
+ r = amdgpu_cs_ctx_create(device, &context_handle);
+ igt_assert_eq(r, 0);
+
+ r = amdgpu_bo_alloc_and_map(device, 4096, 4096,
+ AMDGPU_GEM_DOMAIN_GTT, 0,
+ &ib_result_handle, &ib_result_cpu,
+ &ib_result_mc_address, &va_handle);
+ igt_assert_eq(r, 0);
+
+ r = amdgpu_bo_alloc_and_map(device, 4096, 4096,
+ AMDGPU_GEM_DOMAIN_GTT, 0,
+ &ib_result_ce_handle, &ib_result_ce_cpu,
+ &ib_result_ce_mc_address, &va_handle_ce);
+ igt_assert_eq(r, 0);
+
+ r = amdgpu_get_bo_list(device, ib_result_handle,
+ ib_result_ce_handle, &bo_list);
+ igt_assert_eq(r, 0);
+
+ memset(ib_info, 0, 2 * sizeof(struct amdgpu_cs_ib_info));
+
+ /* IT_SET_CE_DE_COUNTERS */
+ ptr = ib_result_ce_cpu;
+ ptr[0] = 0xc0008900;
+ ptr[1] = 0;
+ ptr[2] = 0xc0008400;
+ ptr[3] = 1;
+ ib_info[0].ib_mc_address = ib_result_ce_mc_address;
+ ib_info[0].size = 4;
+ ib_info[0].flags = AMDGPU_IB_FLAG_CE;
+
+ /* IT_WAIT_ON_CE_COUNTER */
+ ptr = ib_result_cpu;
+ ptr[0] = 0xc0008600;
+ ptr[1] = 0x00000001;
+ ib_info[1].ib_mc_address = ib_result_mc_address;
+ ib_info[1].size = 2;
+
+ for (i = 0; i < ib_cs_num; i++) {
+ ibs_request[i].ip_type = AMDGPU_HW_IP_GFX;
+ ibs_request[i].number_of_ibs = 2;
+ ibs_request[i].ibs = ib_info;
+ ibs_request[i].resources = bo_list;
+ ibs_request[i].fence_info.handle = NULL;
+ }
+
+ r = amdgpu_cs_submit(context_handle, 0,ibs_request, ib_cs_num);
+
+ igt_assert_eq(r, 0);
+
+ for (i = 0; i < ib_cs_num; i++) {
+ fence_status[i].context = context_handle;
+ fence_status[i].ip_type = AMDGPU_HW_IP_GFX;
+ fence_status[i].fence = ibs_request[i].seq_no;
+ }
+
+ r = amdgpu_cs_wait_fences(fence_status, ib_cs_num, wait_all,
+ AMDGPU_TIMEOUT_INFINITE,
+ &expired, NULL);
+ igt_assert_eq(r, 0);
+
+ amdgpu_bo_unmap_and_free(ib_result_handle, va_handle,
+ ib_result_mc_address, 4096);
+
+ amdgpu_bo_unmap_and_free(ib_result_ce_handle, va_handle_ce,
+ ib_result_ce_mc_address, 4096);
+
+ r = amdgpu_bo_list_destroy(bo_list);
+ igt_assert_eq(r, 0);
+
+ r = amdgpu_cs_ctx_free(context_handle);
+ igt_assert_eq(r, 0);
+}
diff --git a/lib/amdgpu/amd_fence.h b/lib/amdgpu/amd_fence.h
new file mode 100644
index 00000000..57d37942
--- /dev/null
+++ b/lib/amdgpu/amd_fence.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2014 Advanced Micro Devices, Inc.
+ * Copyright 2022 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ *
+ */
+#ifndef AMD_FENCE_H
+#define AMD_FENCE_H
+
+
+void amdgpu_command_submission_multi_fence_wait_all(amdgpu_device_handle device,
+ bool wait_all);
+
+
+#endif
diff --git a/lib/amdgpu/amd_gfx.c b/lib/amdgpu/amd_gfx.c
new file mode 100644
index 00000000..a89ff753
--- /dev/null
+++ b/lib/amdgpu/amd_gfx.c
@@ -0,0 +1,196 @@
+/*
+ * Copyright 2014 Advanced Micro Devices, Inc.
+ * Copyright 2022 Advanced Micro Devices, Inc.
+ * *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ *
+ */
+
+#include "amd_memory.h"
+#include "amd_gfx.h"
+
+/**
+ *
+ * @param device
+ */
+void amdgpu_command_submission_gfx_separate_ibs(amdgpu_device_handle device)
+{
+ amdgpu_context_handle context_handle;
+ amdgpu_bo_handle ib_result_handle, ib_result_ce_handle;
+ void *ib_result_cpu, *ib_result_ce_cpu;
+ uint64_t ib_result_mc_address, ib_result_ce_mc_address;
+ struct amdgpu_cs_request ibs_request = {0};
+ struct amdgpu_cs_ib_info ib_info[2];
+ struct amdgpu_cs_fence fence_status = {0};
+ uint32_t *ptr;
+ uint32_t expired;
+ amdgpu_bo_list_handle bo_list;
+ amdgpu_va_handle va_handle, va_handle_ce;
+ int r;
+
+ r = amdgpu_cs_ctx_create(device, &context_handle);
+ igt_assert_eq(r, 0);
+
+ r = amdgpu_bo_alloc_and_map(device, 4096, 4096,
+ AMDGPU_GEM_DOMAIN_GTT, 0,
+ &ib_result_handle, &ib_result_cpu,
+ &ib_result_mc_address, &va_handle);
+ igt_assert_eq(r, 0);
+
+ r = amdgpu_bo_alloc_and_map(device, 4096, 4096,
+ AMDGPU_GEM_DOMAIN_GTT, 0,
+ &ib_result_ce_handle, &ib_result_ce_cpu,
+ &ib_result_ce_mc_address, &va_handle_ce);
+ igt_assert_eq(r, 0);
+
+ r = amdgpu_get_bo_list(device, ib_result_handle,
+ ib_result_ce_handle, &bo_list);
+ igt_assert_eq(r, 0);
+
+ memset(ib_info, 0, 2 * sizeof(struct amdgpu_cs_ib_info));
+
+ /* IT_SET_CE_DE_COUNTERS */
+ ptr = ib_result_ce_cpu;
+ ptr[0] = 0xc0008900;
+ ptr[1] = 0;
+ ptr[2] = 0xc0008400;
+ ptr[3] = 1;
+ ib_info[0].ib_mc_address = ib_result_ce_mc_address;
+ ib_info[0].size = 4;
+ ib_info[0].flags = AMDGPU_IB_FLAG_CE;
+
+ /* IT_WAIT_ON_CE_COUNTER */
+ ptr = ib_result_cpu;
+ ptr[0] = 0xc0008600;
+ ptr[1] = 0x00000001;
+ ib_info[1].ib_mc_address = ib_result_mc_address;
+ ib_info[1].size = 2;
+
+ ibs_request.ip_type = AMDGPU_HW_IP_GFX;
+ ibs_request.number_of_ibs = 2;
+ ibs_request.ibs = ib_info;
+ ibs_request.resources = bo_list;
+ ibs_request.fence_info.handle = NULL;
+
+ r = amdgpu_cs_submit(context_handle, 0,&ibs_request, 1);
+
+ igt_assert_eq(r, 0);
+
+ fence_status.context = context_handle;
+ fence_status.ip_type = AMDGPU_HW_IP_GFX;
+ fence_status.ip_instance = 0;
+ fence_status.fence = ibs_request.seq_no;
+
+ r = amdgpu_cs_query_fence_status(&fence_status,
+ AMDGPU_TIMEOUT_INFINITE,
+ 0, &expired);
+ igt_assert_eq(r, 0);
+
+ amdgpu_bo_unmap_and_free(ib_result_handle, va_handle,
+ ib_result_mc_address, 4096);
+ amdgpu_bo_unmap_and_free(ib_result_ce_handle, va_handle_ce,
+ ib_result_ce_mc_address, 4096);
+
+ r = amdgpu_bo_list_destroy(bo_list);
+ igt_assert_eq(r, 0);
+
+ r = amdgpu_cs_ctx_free(context_handle);
+ igt_assert_eq(r, 0);
+}
+
+/**
+ *
+ * @param device
+ */
+void amdgpu_command_submission_gfx_shared_ib(amdgpu_device_handle device)
+{
+ amdgpu_context_handle context_handle;
+ amdgpu_bo_handle ib_result_handle;
+ void *ib_result_cpu;
+ uint64_t ib_result_mc_address;
+ struct amdgpu_cs_request ibs_request = {0};
+ struct amdgpu_cs_ib_info ib_info[2];
+ struct amdgpu_cs_fence fence_status = {0};
+ uint32_t *ptr;
+ uint32_t expired;
+ amdgpu_bo_list_handle bo_list;
+ amdgpu_va_handle va_handle;
+ int r;
+
+ r = amdgpu_cs_ctx_create(device, &context_handle);
+ igt_assert_eq(r, 0);
+
+ r = amdgpu_bo_alloc_and_map(device, 4096, 4096,
+ AMDGPU_GEM_DOMAIN_GTT, 0,
+ &ib_result_handle, &ib_result_cpu,
+ &ib_result_mc_address, &va_handle);
+ igt_assert_eq(r, 0);
+
+ r = amdgpu_get_bo_list(device, ib_result_handle, NULL,
+ &bo_list);
+ igt_assert_eq(r, 0);
+ r = sizeof(ib_info);
+ memset(ib_info, 0, 2 * sizeof(struct amdgpu_cs_ib_info));
+
+ /* IT_SET_CE_DE_COUNTERS */
+ ptr = ib_result_cpu;
+ ptr[0] = 0xc0008900;
+ ptr[1] = 0;
+ ptr[2] = 0xc0008400;
+ ptr[3] = 1;
+ ib_info[0].ib_mc_address = ib_result_mc_address;
+ ib_info[0].size = 4;
+ ib_info[0].flags = AMDGPU_IB_FLAG_CE;
+
+ ptr = (uint32_t *)ib_result_cpu + 4;
+ ptr[0] = 0xc0008600;
+ ptr[1] = 0x00000001;
+ ib_info[1].ib_mc_address = ib_result_mc_address + 16;
+ ib_info[1].size = 2;
+
+ ibs_request.ip_type = AMDGPU_HW_IP_GFX;
+ ibs_request.number_of_ibs = 2;
+ ibs_request.ibs = ib_info;
+ ibs_request.resources = bo_list;
+ ibs_request.fence_info.handle = NULL;
+
+ r = amdgpu_cs_submit(context_handle, 0, &ibs_request, 1);
+
+ igt_assert_eq(r, 0);
+
+ fence_status.context = context_handle;
+ fence_status.ip_type = AMDGPU_HW_IP_GFX;
+ fence_status.ip_instance = 0;
+ fence_status.fence = ibs_request.seq_no;
+
+ r = amdgpu_cs_query_fence_status(&fence_status,
+ AMDGPU_TIMEOUT_INFINITE,
+ 0, &expired);
+ igt_assert_eq(r, 0);
+
+ amdgpu_bo_unmap_and_free(ib_result_handle, va_handle,
+ ib_result_mc_address, 4096);
+
+ r = amdgpu_bo_list_destroy(bo_list);
+ igt_assert_eq(r, 0);
+
+ r = amdgpu_cs_ctx_free(context_handle);
+ igt_assert_eq(r, 0);
+}
diff --git a/lib/amdgpu/amd_gfx.h b/lib/amdgpu/amd_gfx.h
new file mode 100644
index 00000000..d9da8594
--- /dev/null
+++ b/lib/amdgpu/amd_gfx.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2014 Advanced Micro Devices, Inc.
+ * Copyright 2022 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ *
+ */
+#ifndef AMD_GFX_H
+#define AMD_GFX_H
+
+#include "amd_ip_blocks.h"
+
+
+void amdgpu_command_submission_gfx_separate_ibs(amdgpu_device_handle device);
+
+void amdgpu_command_submission_gfx_shared_ib(amdgpu_device_handle device);
+
+#endif
diff --git a/lib/amdgpu/amd_ip_blocks.c b/lib/amdgpu/amd_ip_blocks.c
new file mode 100644
index 00000000..94bfda88
--- /dev/null
+++ b/lib/amdgpu/amd_ip_blocks.c
@@ -0,0 +1,557 @@
+/*
+ * Copyright 2014 Advanced Micro Devices, Inc.
+ * Copyright 2022 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ *
+ */
+#include "amd_memory.h"
+#include "amd_ip_blocks.h"
+#include "amd_PM4.h"
+#include "amd_sdma.h"
+#include <amdgpu.h>
+
+
+#include <amdgpu_drm.h>
+#include "amdgpu_asic_addr.h"
+#include "amd_family.h"
+
+/*
+ * SDMA functions:
+ * - write_linear
+ * - const_fill
+ * - copy_linear
+ */
+static int
+sdma_ring_write_linear(const struct amdgpu_ip_funcs *func,
+ const struct amdgpu_ring_context *ring_context,
+ uint32_t *pm4_dw)
+{
+ uint32_t i, j;
+
+ i = 0;
+ j = 0;
+ if (ring_context->secure == false) {
+ if (func->family_id == AMDGPU_FAMILY_SI)
+ ring_context->pm4[i++] = SDMA_PACKET_SI(SDMA_OPCODE_WRITE, 0, 0, 0,
+ ring_context->write_length);
+ else
+ ring_context->pm4[i++] = SDMA_PACKET(SDMA_OPCODE_WRITE,
+ SDMA_WRITE_SUB_OPCODE_LINEAR,
+ ring_context->secure ? SDMA_ATOMIC_TMZ(1) : 0);
+
+ ring_context->pm4[i++] = 0xfffffffc & ring_context->bo_mc;
+ ring_context->pm4[i++] = (0xffffffff00000000 & ring_context->bo_mc) >> 32;
+ if (func->family_id >= AMDGPU_FAMILY_AI)
+ ring_context->pm4[i++] = ring_context->write_length - 1;
+ else
+ ring_context->pm4[i++] = ring_context->write_length;
+
+ while(j++ < ring_context->write_length)
+ ring_context->pm4[i++] = func->deadbeaf;
+ } else {
+ memset(ring_context->pm4, 0, ring_context->pm4_size * sizeof(uint32_t));
+
+ /* atomic opcode for 32b w/ RTN and ATOMIC_SWAPCMP_RTN
+ * loop, 1-loop_until_compare_satisfied.
+ * single_pass_atomic, 0-lru
+ */
+ ring_context->pm4[i++] = SDMA_PACKET(SDMA_OPCODE_ATOMIC,
+ 0,
+ SDMA_ATOMIC_LOOP(1) |
+ SDMA_ATOMIC_TMZ(1) |
+ SDMA_ATOMIC_OPCODE(TC_OP_ATOMIC_CMPSWAP_RTN_32));
+ ring_context->pm4[i++] = 0xfffffffc & ring_context->bo_mc;
+ ring_context->pm4[i++] = (0xffffffff00000000 & ring_context->bo_mc) >> 32;
+ ring_context->pm4[i++] = 0x12345678;
+ ring_context->pm4[i++] = 0x0;
+ ring_context->pm4[i++] = func->deadbeaf;
+ ring_context->pm4[i++] = 0x0;
+ ring_context->pm4[i++] = 0x100;
+ }
+
+ *pm4_dw = i;
+
+ return 0;
+}
+
+static int
+sdma_ring_const_fill(const struct amdgpu_ip_funcs *func,
+ const struct amdgpu_ring_context *context,
+ uint32_t *pm4_dw)
+{
+ uint32_t i;
+
+ i = 0;
+ if (func->family_id == AMDGPU_FAMILY_SI) {
+ context->pm4[i++] = SDMA_PACKET_SI(SDMA_OPCODE_CONSTANT_FILL_SI,
+ 0, 0, 0, context->write_length / 4);
+ context->pm4[i++] = 0xfffffffc & context->bo_mc;
+ context->pm4[i++] = 0xdeadbeaf;
+ context->pm4[i++] = (0xffffffff00000000 & context->bo_mc) >> 16;
+ } else {
+ context->pm4[i++] = SDMA_PACKET(SDMA_OPCODE_CONSTANT_FILL, 0,
+ SDMA_CONSTANT_FILL_EXTRA_SIZE(2));
+ context->pm4[i++] = 0xffffffff & context->bo_mc;
+ context->pm4[i++] = (0xffffffff00000000 & context->bo_mc) >> 32;
+ context->pm4[i++] = func->deadbeaf;
+
+ if (func->family_id >= AMDGPU_FAMILY_AI)
+ context->pm4[i++] = context->write_length - 1;
+ else
+ context->pm4[i++] = context->write_length;
+ }
+ *pm4_dw = i;
+
+ return 0;
+}
+
+static int
+sdma_ring_copy_linear(const struct amdgpu_ip_funcs *func,
+ const struct amdgpu_ring_context *context,
+ uint32_t *pm4_dw)
+{
+ uint32_t i;
+
+ i = 0;
+ if (func->family_id == AMDGPU_FAMILY_SI) {
+ context->pm4[i++] = SDMA_PACKET_SI(SDMA_OPCODE_COPY_SI,
+ 0, 0, 0,
+ context->write_length);
+ context->pm4[i++] = 0xffffffff & context->bo_mc;
+ context->pm4[i++] = (0xffffffff00000000 & context->bo_mc) >> 32;
+ context->pm4[i++] = 0xffffffff & context->bo_mc2;
+ context->pm4[i++] = (0xffffffff00000000 & context->bo_mc2) >> 32;
+ } else {
+ context->pm4[i++] = SDMA_PACKET(SDMA_OPCODE_COPY,
+ SDMA_COPY_SUB_OPCODE_LINEAR,
+ 0);
+ if (func->family_id >= AMDGPU_FAMILY_AI)
+ context->pm4[i++] = context->write_length - 1;
+ else
+ context->pm4[i++] = context->write_length;
+ context->pm4[i++] = 0;
+ context->pm4[i++] = 0xffffffff & context->bo_mc;
+ context->pm4[i++] = (0xffffffff00000000 & context->bo_mc) >> 32;
+ context->pm4[i++] = 0xffffffff & context->bo_mc2;
+ context->pm4[i++] = (0xffffffff00000000 & context->bo_mc2) >> 32;
+ }
+
+ *pm4_dw = i;
+
+ return 0;
+}
+
+/*
+ * GFX and COMPUTE functions:
+ * - write_linear
+ * - const_fill
+ * - copy_linear
+ */
+
+
+static int
+gfx_ring_write_linear(const struct amdgpu_ip_funcs *func,
+ const struct amdgpu_ring_context *ring_context,
+ uint32_t *pm4_dw)
+ {
+ uint32_t i, j;
+
+ i = 0;
+ j = 0;
+
+ if (ring_context->secure == false) {
+ ring_context->pm4[i++] = PACKET3(PACKET3_WRITE_DATA, 2 + ring_context->write_length);
+ ring_context->pm4[i++] = WRITE_DATA_DST_SEL(5) | WR_CONFIRM;
+ ring_context->pm4[i++] = 0xfffffffc & ring_context->bo_mc;
+ ring_context->pm4[i++] = (0xffffffff00000000 & ring_context->bo_mc) >> 32;
+ while(j++ < ring_context->write_length)
+ ring_context->pm4[i++] = func->deadbeaf;
+ } else {
+ memset(ring_context->pm4, 0, ring_context->pm4_size * sizeof(uint32_t));
+ ring_context->pm4[i++] = PACKET3(PACKET3_ATOMIC_MEM, 7);
+
+ /* atomic opcode for 32b w/ RTN and ATOMIC_SWAPCMP_RTN
+ * command, 1-loop_until_compare_satisfied.
+ * single_pass_atomic, 0-lru
+ * engine_sel, 0-micro_engine
+ */
+ ring_context->pm4[i++] = (TC_OP_ATOMIC_CMPSWAP_RTN_32 |
+ ATOMIC_MEM_COMMAND(1) |
+ ATOMIC_MEM_CACHEPOLICAY(0) |
+ ATOMIC_MEM_ENGINESEL(0));
+ ring_context->pm4[i++] = 0xfffffffc & ring_context->bo_mc;
+ ring_context->pm4[i++] = (0xffffffff00000000 & ring_context->bo_mc) >> 32;
+ ring_context->pm4[i++] = 0x12345678;
+ ring_context->pm4[i++] = 0x0;
+ ring_context->pm4[i++] = 0xdeadbeaf;
+ ring_context->pm4[i++] = 0x0;
+ ring_context->pm4[i++] = 0x100;
+ }
+
+ *pm4_dw = i;
+
+ return 0;
+ }
+
+ static int
+ gfx_ring_const_fill(const struct amdgpu_ip_funcs *func,
+ const struct amdgpu_ring_context *ring_context,
+ uint32_t *pm4_dw)
+ {
+ uint32_t i;
+
+ i = 0;
+ if (func->family_id == AMDGPU_FAMILY_SI) {
+ ring_context->pm4[i++] = PACKET3(PACKET3_DMA_DATA_SI, 4);
+ ring_context->pm4[i++] = func->deadbeaf;
+ ring_context->pm4[i++] = PACKET3_DMA_DATA_SI_ENGINE(0) |
+ PACKET3_DMA_DATA_SI_DST_SEL(0) |
+ PACKET3_DMA_DATA_SI_SRC_SEL(2) |
+ PACKET3_DMA_DATA_SI_CP_SYNC;
+ ring_context->pm4[i++] = 0xffffffff & ring_context->bo_mc;
+ ring_context->pm4[i++] = (0xffffffff00000000 & ring_context->bo_mc) >> 32;
+ ring_context->pm4[i++] = ring_context->write_length;
+ } else {
+ ring_context->pm4[i++] = PACKET3(PACKET3_DMA_DATA, 5);
+ ring_context->pm4[i++] = PACKET3_DMA_DATA_ENGINE(0) |
+ PACKET3_DMA_DATA_DST_SEL(0) |
+ PACKET3_DMA_DATA_SRC_SEL(2) |
+ PACKET3_DMA_DATA_CP_SYNC;
+ ring_context->pm4[i++] = func->deadbeaf;
+ ring_context->pm4[i++] = 0;
+ ring_context->pm4[i++] = 0xfffffffc & ring_context->bo_mc;
+ ring_context->pm4[i++] = (0xffffffff00000000 & ring_context->bo_mc) >> 32;
+ ring_context->pm4[i++] = ring_context->write_length;
+ }
+ *pm4_dw = i;
+
+ return 0;
+ }
+
+static int
+gfx_ring_copy_linear(const struct amdgpu_ip_funcs *func,
+ const struct amdgpu_ring_context *context,
+ uint32_t *pm4_dw)
+{
+ uint32_t i;
+
+ i = 0;
+ if (func->family_id == AMDGPU_FAMILY_SI) {
+ context->pm4[i++] = PACKET3(PACKET3_DMA_DATA_SI, 4);
+ context->pm4[i++] = 0xfffffffc & context->bo_mc;
+ context->pm4[i++] = PACKET3_DMA_DATA_SI_ENGINE(0) |
+ PACKET3_DMA_DATA_SI_DST_SEL(0) |
+ PACKET3_DMA_DATA_SI_SRC_SEL(0) |
+ PACKET3_DMA_DATA_SI_CP_SYNC |
+ (0xffff00000000 & context->bo_mc) >> 32;
+ context->pm4[i++] = 0xfffffffc & context->bo_mc2;
+ context->pm4[i++] = (0xffffffff00000000 & context->bo_mc2) >> 32;
+ context->pm4[i++] = context->write_length;
+ } else {
+ context->pm4[i++] = PACKET3(PACKET3_DMA_DATA, 5);
+ context->pm4[i++] = PACKET3_DMA_DATA_ENGINE(0) |
+ PACKET3_DMA_DATA_DST_SEL(0) |
+ PACKET3_DMA_DATA_SRC_SEL(0) |
+ PACKET3_DMA_DATA_CP_SYNC;
+ context->pm4[i++] = 0xfffffffc & context->bo_mc;
+ context->pm4[i++] = (0xffffffff00000000 & context->bo_mc) >> 32;
+ context->pm4[i++] = 0xfffffffc & context->bo_mc2;
+ context->pm4[i++] = (0xffffffff00000000 & context->bo_mc2) >> 32;
+ context->pm4[i++] = context->write_length;
+ }
+
+ *pm4_dw = i;
+
+ return 0;
+}
+
+/* we may cobine these two functions later */
+static int
+x_compare(const struct amdgpu_ip_funcs *func,
+ const struct amdgpu_ring_context *ring_context, int div)
+{
+ int i = 0, ret = 0;
+
+ int num_compare = ring_context->write_length/div;
+
+ while(i < num_compare) {
+ if (ring_context->bo_cpu[i++] != func->deadbeaf) {
+ ret = -1;
+ break;
+ }
+ }
+ return ret;
+}
+
+static int
+x_compare_pattern(const struct amdgpu_ip_funcs *func,
+ const struct amdgpu_ring_context *ring_context, int div)
+{
+ int i = 0, ret = 0;
+
+ int num_compare = ring_context->write_length/div;
+
+ while(i < num_compare) {
+ if (ring_context->bo_cpu[i++] != func->pattern) {
+ ret = -1;
+ break;
+ }
+ }
+ return ret;
+}
+
+static const struct amdgpu_ip_funcs gfx_v8_x_ip_funcs = {
+ .family_id = FAMILY_VI,
+ .align_mask = 0xff,
+ .nop = 0x80000000,
+ .deadbeaf = 0xdeadbeaf,
+ .pattern = 0xaaaaaaaa,
+ .write_linear = gfx_ring_write_linear,
+ .const_fill = gfx_ring_const_fill,
+ .copy_linear = gfx_ring_copy_linear,
+ .compare = x_compare,
+ .compare_pattern = x_compare_pattern
+};
+
+
+static const struct amdgpu_ip_funcs sdma_v3_x_ip_funcs = {
+ .family_id = FAMILY_VI,
+ .align_mask = 0xff,
+ .nop = 0x80000000,
+ .deadbeaf = 0xdeadbeaf,
+ .pattern = 0xaaaaaaaa,
+ .write_linear = sdma_ring_write_linear,
+ .const_fill = sdma_ring_const_fill,
+ .copy_linear = sdma_ring_copy_linear,
+ .compare = x_compare,
+ .compare_pattern = x_compare_pattern
+};
+
+
+const struct amdgpu_ip_block_version gfx_v8_x_ip_block = {
+ .type = AMD_IP_GFX,
+ .major = 8,
+ .minor = 0,
+ .rev = 0,
+ .funcs = &gfx_v8_x_ip_funcs
+};
+
+const struct amdgpu_ip_block_version compute_v8_x_ip_block = {
+ .type = AMD_IP_COMPUTE,
+ .major = 8,
+ .minor = 0,
+ .rev = 0,
+ .funcs = &gfx_v8_x_ip_funcs
+};
+
+const struct amdgpu_ip_block_version sdma_v3_x_ip_block = {
+ .type = AMD_IP_DMA,
+ .major = 3,
+ .minor = 0,
+ .rev = 0,
+ .funcs = &sdma_v3_x_ip_funcs
+};
+
+struct chip_info {
+ const char *name;
+ enum radeon_family family;
+ enum chip_class chip_class;
+ amdgpu_device_handle dev;
+};
+
+/* we may improve later */
+struct amdgpu_ip_blocks_device amdgpu_ips;
+struct chip_info g_chip;
+
+static int
+amdgpu_device_ip_block_add(const struct amdgpu_ip_block_version *ip_block_version)
+{
+ if (amdgpu_ips.num_ip_blocks >= AMD_IP_MAX)
+ return -1;
+
+ amdgpu_ips.ip_blocks[amdgpu_ips.num_ip_blocks++] = ip_block_version;
+
+ return 0;
+}
+
+const struct amdgpu_ip_block_version *
+get_ip_block(amdgpu_device_handle device, enum amd_ip_block_type type)
+{
+ int i;
+
+ if (g_chip.dev != device)
+ return NULL;
+
+ for(i = 0; i < amdgpu_ips.num_ip_blocks; i++)
+ if (amdgpu_ips.ip_blocks[i]->type == type)
+ return amdgpu_ips.ip_blocks[i];
+ return NULL;
+}
+
+
+
+
+
+/*
+ * GFX: 8.x
+ * COMPUTE: 8.x
+ * SDMA 3.x
+ *
+ * GFX9:
+ * COMPUTE: 9.x
+ * SDMA 4.x
+ *
+ * GFX10.1:
+ * COMPUTE: 10.1
+ * SDMA 5.0
+ *
+ * GFX10.3:
+ * COMPUTE: 10.3
+ * SDMA 5.2
+ *
+ * copy function from mesa
+ * should be called once per test
+ */
+int setup_amdgpu_ip_blocks(uint32_t major, uint32_t minor, struct amdgpu_gpu_info *amdinfo,
+ amdgpu_device_handle device)
+{
+#define identify_chip2(asic, chipname) \
+ if (ASICREV_IS(amdinfo->chip_external_rev, asic)) { \
+ info->family = CHIP_##chipname; \
+ info->name = #chipname; \
+ }
+#define identify_chip(chipname) identify_chip2(chipname, chipname)
+
+ struct chip_info *info = &g_chip;
+
+ switch (amdinfo->family_id) {
+ case AMDGPU_FAMILY_SI:
+ identify_chip(TAHITI);
+ identify_chip(PITCAIRN);
+ identify_chip2(CAPEVERDE, VERDE);
+ identify_chip(OLAND);
+ identify_chip(HAINAN);
+ break;
+ case FAMILY_CI:
+ identify_chip(BONAIRE);
+ identify_chip(HAWAII);
+ break;
+ case FAMILY_KV:
+ identify_chip2(SPECTRE, KAVERI);
+ identify_chip2(SPOOKY, KAVERI);
+ identify_chip2(KALINDI, KABINI);
+ identify_chip2(GODAVARI, KABINI);
+ break;
+ case FAMILY_VI:
+ identify_chip(ICELAND);
+ identify_chip(TONGA);
+ identify_chip(FIJI);
+ identify_chip(POLARIS10);
+ identify_chip(POLARIS11);
+ identify_chip(POLARIS12);
+ identify_chip(VEGAM);
+ break;
+ case FAMILY_CZ:
+ identify_chip(CARRIZO);
+ identify_chip(STONEY);
+ break;
+ case FAMILY_AI:
+ identify_chip(VEGA10);
+ identify_chip(VEGA12);
+ identify_chip(VEGA20);
+ identify_chip(ARCTURUS);
+ identify_chip(ALDEBARAN);
+ break;
+ case FAMILY_RV:
+ identify_chip(RAVEN);
+ identify_chip(RAVEN2);
+ identify_chip(RENOIR);
+ break;
+ case FAMILY_NV:
+ identify_chip(NAVI10);
+ identify_chip(NAVI12);
+ identify_chip(NAVI14);
+ identify_chip(SIENNA_CICHLID);
+ identify_chip(NAVY_FLOUNDER);
+ identify_chip(DIMGREY_CAVEFISH);
+ identify_chip(BEIGE_GOBY);
+ break;
+ case FAMILY_VGH:
+ identify_chip(VANGOGH);
+ break;
+ case FAMILY_YC:
+ identify_chip(YELLOW_CARP);
+ break;
+ }
+ if (!info->name) {
+ igt_info("amdgpu: unknown (family_id, chip_external_rev): (%u, %u)\n",
+ amdinfo->family_id, amdinfo->chip_external_rev);
+ return -1;
+ }
+
+ if (info->family >= CHIP_SIENNA_CICHLID)
+ info->chip_class = GFX10_3;
+ else if (info->family >= CHIP_NAVI10)
+ info->chip_class = GFX10;
+ else if (info->family >= CHIP_VEGA10)
+ info->chip_class = GFX9;
+ else if (info->family >= CHIP_TONGA)
+ info->chip_class = GFX8;
+ else if (info->family >= CHIP_BONAIRE)
+ info->chip_class = GFX7;
+ else if (info->family >= CHIP_TAHITI)
+ info->chip_class = GFX6;
+ else {
+ igt_info("amdgpu: Unknown family.\n");
+ return -1;
+ }
+
+ switch(info->chip_class) {
+ case GFX6:
+ break;
+ case GFX7:
+ break;
+ case GFX8:
+ amdgpu_device_ip_block_add(&gfx_v8_x_ip_block);
+ amdgpu_device_ip_block_add(&compute_v8_x_ip_block);
+ amdgpu_device_ip_block_add(&sdma_v3_x_ip_block);
+ /* extra precaution if re-factor again */
+ igt_assert_eq(gfx_v8_x_ip_block.major, 8);
+ igt_assert_eq(compute_v8_x_ip_block.major, 8);
+ igt_assert_eq(sdma_v3_x_ip_block.major, 3);
+
+ igt_assert_eq(gfx_v8_x_ip_block.funcs->family_id, FAMILY_VI);
+ igt_assert_eq(sdma_v3_x_ip_block.funcs->family_id, FAMILY_VI);
+ break;
+ case GFX9:
+ break;
+ case GFX10:
+ break;
+ case GFX10_3:
+ break;
+ default:
+ igt_info("amdgpu: GFX or old.\n");
+ return -1;
+ }
+ info->dev = device;
+
+ return 0;
+}
diff --git a/lib/amdgpu/amd_ip_blocks.h b/lib/amdgpu/amd_ip_blocks.h
new file mode 100644
index 00000000..cb7d1474
--- /dev/null
+++ b/lib/amdgpu/amd_ip_blocks.h
@@ -0,0 +1,114 @@
+/*
+ * Copyright 2014 Advanced Micro Devices, Inc.
+ * Copyright 2022 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ *
+ */
+#ifndef AMD_IP_BLOCKS_H
+#define AMD_IP_BLOCKS_H
+
+enum amd_ip_block_type {
+ AMD_IP_GFX,
+ AMD_IP_COMPUTE,
+ AMD_IP_DMA,
+ AMD_IP_UVD,
+ AMD_IP_VCE,
+ AMD_IP_MAX,
+};
+
+
+/* aux struct to hold misc parameters for convenience to maintain */
+struct amdgpu_ring_context {
+
+ int ring_id; /* ring_id from amdgpu_query_hw_ip_info */
+ int res_cnt; /* num of bo in amdgpu_bo_handle resources[2] */
+
+ uint32_t write_length; /* length of data */
+ uint32_t *pm4; /* data of the packet */
+ uint32_t pm4_size; /* max allocated packet size */
+ bool secure; /* secure or not */
+
+ uint64_t bo_mc; /* result from amdgpu_bo_alloc_and_map */
+ uint64_t bo_mc2; /* result from amdgpu_bo_alloc_and_map */
+
+ uint32_t pm4_dw; /* actual size of pm4 */
+
+ volatile uint32_t *bo_cpu;
+ volatile uint32_t *bo2_cpu;
+
+ uint32_t bo_cpu_origin;
+
+ amdgpu_bo_handle bo;
+ amdgpu_bo_handle bo2;
+
+ amdgpu_context_handle context_handle;
+ struct drm_amdgpu_info_hw_ip hw_ip_info; /* result of amdgpu_query_hw_ip_info */
+
+ amdgpu_bo_handle resources[2]; /* amdgpu_bo_alloc_and_map */
+ amdgpu_va_handle va_handle; /* amdgpu_bo_alloc_and_map */
+ amdgpu_va_handle va_handle2; /* amdgpu_bo_alloc_and_map */
+
+ struct amdgpu_cs_ib_info ib_info; /* amdgpu_bo_list_create */
+ struct amdgpu_cs_request ibs_request; /* amdgpu_cs_query_fence_status */
+};
+
+struct amdgpu_ip_funcs {
+ uint32_t family_id;
+ uint32_t align_mask;
+ uint32_t nop;
+ uint32_t deadbeaf;
+ uint32_t pattern;
+ /* functions */
+ int (*write_linear)(const struct amdgpu_ip_funcs *func, const struct amdgpu_ring_context *context, uint32_t *pm4_dw);
+ int (*const_fill)(const struct amdgpu_ip_funcs *func, const struct amdgpu_ring_context *context, uint32_t *pm4_dw);
+ int (*copy_linear)(const struct amdgpu_ip_funcs *func, const struct amdgpu_ring_context *context, uint32_t *pm4_dw);
+ int (*compare)(const struct amdgpu_ip_funcs *func, const struct amdgpu_ring_context *context, int div);
+ int (*compare_pattern)(const struct amdgpu_ip_funcs *func, const struct amdgpu_ring_context *context, int div);
+};
+
+extern const struct amdgpu_ip_block_version gfx_v6_0_ip_block;
+
+struct amdgpu_ip_block_version {
+ const enum amd_ip_block_type type;
+ const int major;
+ const int minor;
+ const int rev;
+ const struct amdgpu_ip_funcs *funcs;
+};
+
+/* global holder for the array of in use ip blocks */
+
+struct amdgpu_ip_blocks_device {
+ const struct amdgpu_ip_block_version *ip_blocks[AMD_IP_MAX];
+ int num_ip_blocks;
+};
+
+extern struct amdgpu_ip_blocks_device amdgpu_ips;
+
+int
+setup_amdgpu_ip_blocks(uint32_t major, uint32_t minor, struct amdgpu_gpu_info *amdinfo,
+ amdgpu_device_handle device);
+
+const struct amdgpu_ip_block_version *
+get_ip_block(amdgpu_device_handle device, enum amd_ip_block_type type);
+
+
+#endif
diff --git a/lib/amdgpu/amd_memory.c b/lib/amdgpu/amd_memory.c
new file mode 100644
index 00000000..e796aae7
--- /dev/null
+++ b/lib/amdgpu/amd_memory.c
@@ -0,0 +1,198 @@
+/*
+ * Copyright 2014 Advanced Micro Devices, Inc.
+ * Copyright 2022 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ *
+ */
+
+#include "amd_memory.h"
+
+/**
+ *
+ * @param device_handle
+ * @param size
+ * @param alignment
+ * @param type
+ * @param flags
+ * @param vmc_addr
+ * @param va_handle
+ * @return
+ */
+ amdgpu_bo_handle
+ gpu_mem_alloc(amdgpu_device_handle device_handle,
+ uint64_t size,
+ uint64_t alignment,
+ uint32_t type,
+ uint64_t flags,
+ uint64_t *vmc_addr,
+ amdgpu_va_handle *va_handle)
+{
+ struct amdgpu_bo_alloc_request req = {
+ .alloc_size = size,
+ .phys_alignment = alignment,
+ .preferred_heap = type,
+ .flags = flags,
+ };
+ amdgpu_bo_handle buf_handle;
+ int r;
+
+ r = amdgpu_bo_alloc(device_handle, &req, &buf_handle);
+ igt_assert_eq(r, 0);
+
+ r = amdgpu_va_range_alloc(device_handle,
+ amdgpu_gpu_va_range_general,
+ size, alignment, 0, vmc_addr,
+ va_handle, 0);
+ igt_assert_eq(r, 0);
+
+ r = amdgpu_bo_va_op(buf_handle, 0, size, *vmc_addr, 0, AMDGPU_VA_OP_MAP);
+ igt_assert_eq(r, 0);
+
+ return buf_handle;
+}
+
+ /**
+ *
+ * @param bo
+ * @param va_handle
+ * @param vmc_addr
+ * @param size
+ */
+ void
+ gpu_mem_free(amdgpu_bo_handle bo,
+ amdgpu_va_handle va_handle,
+ uint64_t vmc_addr,
+ uint64_t size)
+{
+ int r;
+
+ r = amdgpu_bo_va_op(bo, 0, size, vmc_addr, 0, AMDGPU_VA_OP_UNMAP);
+ igt_assert_eq(r, 0);
+
+ r = amdgpu_va_range_free(va_handle);
+ igt_assert_eq(r, 0);
+
+ r = amdgpu_bo_free(bo);
+ igt_assert_eq(r, 0);
+}
+
+/**
+ *
+ * @param dev
+ * @param size
+ * @param alignment
+ * @param heap
+ * @param flags
+ * @param bo
+ * @param cpu
+ * @param mc_address
+ * @param va_handle
+ * @return
+ */
+int
+amdgpu_bo_alloc_and_map(amdgpu_device_handle dev, unsigned size,
+ unsigned alignment, unsigned heap, uint64_t flags,
+ amdgpu_bo_handle *bo, void **cpu, uint64_t *mc_address,
+ amdgpu_va_handle *va_handle)
+{
+ struct amdgpu_bo_alloc_request request = {
+ .alloc_size = size,
+ .phys_alignment = alignment,
+ .preferred_heap = heap,
+ .flags = flags,
+ };
+ amdgpu_bo_handle buf_handle;
+ amdgpu_va_handle handle;
+ uint64_t vmc_addr;
+ int r;
+
+ r = amdgpu_bo_alloc(dev, &request, &buf_handle);
+ if (r)
+ return r;
+
+ r = amdgpu_va_range_alloc(dev,
+ amdgpu_gpu_va_range_general,
+ size, alignment, 0, &vmc_addr,
+ &handle, 0);
+ if (r)
+ goto error_va_alloc;
+
+ r = amdgpu_bo_va_op(buf_handle, 0, size, vmc_addr, 0, AMDGPU_VA_OP_MAP);
+ if (r)
+ goto error_va_map;
+
+ r = amdgpu_bo_cpu_map(buf_handle, cpu);
+ if (r)
+ goto error_cpu_map;
+
+ *bo = buf_handle;
+ *mc_address = vmc_addr;
+ *va_handle = handle;
+
+ return 0;
+
+error_cpu_map:
+ amdgpu_bo_cpu_unmap(buf_handle);
+
+error_va_map:
+ amdgpu_bo_va_op(buf_handle, 0, size, vmc_addr, 0, AMDGPU_VA_OP_UNMAP);
+
+error_va_alloc:
+ amdgpu_bo_free(buf_handle);
+ return r;
+}
+
+/**
+ *
+ * @param bo
+ * @param va_handle
+ * @param mc_addr
+ * @param size
+ */
+void
+amdgpu_bo_unmap_and_free(amdgpu_bo_handle bo, amdgpu_va_handle va_handle,
+ uint64_t mc_addr, uint64_t size)
+{
+ amdgpu_bo_cpu_unmap(bo);
+ amdgpu_bo_va_op(bo, 0, size, mc_addr, 0, AMDGPU_VA_OP_UNMAP);
+ amdgpu_va_range_free(va_handle);
+ amdgpu_bo_free(bo);
+}
+
+/**
+ *
+ * @param dev
+ * @param bo1
+ * @param bo2
+ * @param list
+ * @return
+ */
+int
+amdgpu_get_bo_list(amdgpu_device_handle dev, amdgpu_bo_handle bo1,
+ amdgpu_bo_handle bo2, amdgpu_bo_list_handle *list)
+{
+ amdgpu_bo_handle resources[] = {bo1, bo2};
+
+ return amdgpu_bo_list_create(dev, bo2 ? 2 : 1, resources, NULL, list);
+}
+
+
+
diff --git a/lib/amdgpu/amd_memory.h b/lib/amdgpu/amd_memory.h
new file mode 100644
index 00000000..ddee76e5
--- /dev/null
+++ b/lib/amdgpu/amd_memory.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2014 Advanced Micro Devices, Inc.
+ * Copyright 2022 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ *
+ */
+#ifndef AMD_MEMORY_H
+#define AMD_MEMORY_H
+
+#include "drmtest.h"
+#include <amdgpu.h>
+#include <amdgpu_drm.h>
+
+
+amdgpu_bo_handle
+gpu_mem_alloc(amdgpu_device_handle device_handle,
+ uint64_t size,
+ uint64_t alignment,
+ uint32_t type,
+ uint64_t flags,
+ uint64_t *vmc_addr,
+ amdgpu_va_handle *va_handle);
+
+void
+gpu_mem_free(amdgpu_bo_handle bo,
+ amdgpu_va_handle va_handle,
+ uint64_t vmc_addr,
+ uint64_t size);
+
+int
+amdgpu_bo_alloc_and_map(amdgpu_device_handle dev, unsigned size,
+ unsigned alignment, unsigned heap, uint64_t flags,
+ amdgpu_bo_handle *bo, void **cpu, uint64_t *mc_address,
+ amdgpu_va_handle *va_handle);
+
+void
+amdgpu_bo_unmap_and_free(amdgpu_bo_handle bo, amdgpu_va_handle va_handle,
+ uint64_t mc_addr, uint64_t size);
+
+int
+amdgpu_get_bo_list(amdgpu_device_handle dev, amdgpu_bo_handle bo1,
+ amdgpu_bo_handle bo2, amdgpu_bo_list_handle *list);
+
+#endif
diff --git a/lib/amdgpu/amd_sdma.h b/lib/amdgpu/amd_sdma.h
new file mode 100644
index 00000000..35788434
--- /dev/null
+++ b/lib/amdgpu/amd_sdma.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2014 Advanced Micro Devices, Inc.
+ * Copyright 2022 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ *
+ */
+
+#ifndef AMD_SDMA_H
+#define AMD_SDMA_H
+
+#define SDMA_PKT_HEADER_op_offset 0
+#define SDMA_PKT_HEADER_op_mask 0x000000FF
+#define SDMA_PKT_HEADER_op_shift 0
+#define SDMA_PKT_HEADER_OP(x) (((x) & SDMA_PKT_HEADER_op_mask) << SDMA_PKT_HEADER_op_shift)
+#define SDMA_OPCODE_CONSTANT_FILL 11
+# define SDMA_CONSTANT_FILL_EXTRA_SIZE(x) ((x) << 14)
+ /* 0 = byte fill
+ * 2 = DW fill
+ */
+#define SDMA_PACKET(op, sub_op, e) ((((e) & 0xFFFF) << 16) | \
+ (((sub_op) & 0xFF) << 8) | \
+ (((op) & 0xFF) << 0))
+#define SDMA_OPCODE_WRITE 2
+# define SDMA_WRITE_SUB_OPCODE_LINEAR 0
+# define SDMA_WRTIE_SUB_OPCODE_TILED 1
+
+#define SDMA_OPCODE_COPY 1
+# define SDMA_COPY_SUB_OPCODE_LINEAR 0
+
+#define SDMA_NOP 0x0
+
+
+
+/* taken from basic_tests.c and amdgpu_stress.c */
+
+#define SDMA_PACKET_SI(op, b, t, s, cnt) ((((op) & 0xF) << 28) | \
+ (((b) & 0x1) << 26) | \
+ (((t) & 0x1) << 23) | \
+ (((s) & 0x1) << 22) | \
+ (((cnt) & 0xFFFFF) << 0))
+#define SDMA_OPCODE_COPY_SI 3
+
+
+#define SDMA_OPCODE_ATOMIC 10
+# define SDMA_ATOMIC_LOOP(x) ((x) << 0)
+ /* 0 - single_pass_atomic.
+ * 1 - loop_until_compare_satisfied.
+ */
+# define SDMA_ATOMIC_TMZ(x) ((x) << 2)
+ /* 0 - non-TMZ.
+ * 1 - TMZ.
+ */
+# define SDMA_ATOMIC_OPCODE(x) ((x) << 9)
+ /* TC_OP_ATOMIC_CMPSWAP_RTN_32 0x00000008
+ * same as Packet 3
+ */
+
+#endif
diff --git a/lib/amdgpu/amdgpu_asic_addr.h b/lib/amdgpu/amdgpu_asic_addr.h
new file mode 100644
index 00000000..d147efb8
--- /dev/null
+++ b/lib/amdgpu/amdgpu_asic_addr.h
@@ -0,0 +1,172 @@
+/**
+***********************************************************************************************************************
+*
+* Copyright © 2007-2021 Advanced Micro Devices, Inc.
+* Copyright 2022 Advanced Micro Devices, Inc.
+* All Rights Reserved.
+*
+* Permission is hereby granted, free of charge, to any person obtaining a
+* copy of this software and associated documentation files (the "Software"),
+* to deal in the Software without restriction, including without limitation
+* the rights to use, copy, modify, merge, publish, distribute, sublicense,
+* and/or sell copies of the Software, and to permit persons to whom the
+* Software is furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included in
+* all copies or substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+* OTHER DEALINGS IN THE SOFTWARE
+*
+***********************************************************************************************************************
+*/
+
+#ifndef _AMDGPU_ASIC_ADDR_H
+#define _AMDGPU_ASIC_ADDR_H
+
+#define ATI_VENDOR_ID 0x1002
+#define AMD_VENDOR_ID 0x1022
+
+// AMDGPU_VENDOR_IS_AMD(vendorId)
+#define AMDGPU_VENDOR_IS_AMD(v) ((v == ATI_VENDOR_ID) || (v == AMD_VENDOR_ID))
+
+#define FAMILY_UNKNOWN 0x00
+#define FAMILY_TN 0x69
+#define FAMILY_SI 0x6E
+#define FAMILY_CI 0x78
+#define FAMILY_KV 0x7D
+#define FAMILY_VI 0x82
+#define FAMILY_POLARIS 0x82
+#define FAMILY_CZ 0x87
+#define FAMILY_AI 0x8D
+#define FAMILY_RV 0x8E
+#define FAMILY_NV 0x8F
+#define FAMILY_VGH 0x90
+#define FAMILY_YC 0x92
+
+// AMDGPU_FAMILY_IS(familyId, familyName)
+#define FAMILY_IS(f, fn) (f == FAMILY_##fn)
+#define FAMILY_IS_TN(f) FAMILY_IS(f, TN)
+#define FAMILY_IS_SI(f) FAMILY_IS(f, SI)
+#define FAMILY_IS_CI(f) FAMILY_IS(f, CI)
+#define FAMILY_IS_KV(f) FAMILY_IS(f, KV)
+#define FAMILY_IS_VI(f) FAMILY_IS(f, VI)
+#define FAMILY_IS_POLARIS(f) FAMILY_IS(f, POLARIS)
+#define FAMILY_IS_CZ(f) FAMILY_IS(f, CZ)
+#define FAMILY_IS_AI(f) FAMILY_IS(f, AI)
+#define FAMILY_IS_RV(f) FAMILY_IS(f, RV)
+#define FAMILY_IS_NV(f) FAMILY_IS(f, NV)
+#define FAMILY_IS_YC(f) FAMILY_IS(f, YC)
+
+#define AMDGPU_UNKNOWN 0xFF
+
+#define AMDGPU_TAHITI_RANGE 0x05, 0x14
+#define AMDGPU_PITCAIRN_RANGE 0x15, 0x28
+#define AMDGPU_CAPEVERDE_RANGE 0x29, 0x3C
+#define AMDGPU_OLAND_RANGE 0x3C, 0x46
+#define AMDGPU_HAINAN_RANGE 0x46, 0xFF
+
+#define AMDGPU_BONAIRE_RANGE 0x14, 0x28
+#define AMDGPU_HAWAII_RANGE 0x28, 0x3C
+
+#define AMDGPU_SPECTRE_RANGE 0x01, 0x41
+#define AMDGPU_SPOOKY_RANGE 0x41, 0x81
+#define AMDGPU_KALINDI_RANGE 0x81, 0xA1
+#define AMDGPU_GODAVARI_RANGE 0xA1, 0xFF
+
+#define AMDGPU_ICELAND_RANGE 0x01, 0x14
+#define AMDGPU_TONGA_RANGE 0x14, 0x28
+#define AMDGPU_FIJI_RANGE 0x3C, 0x50
+#define AMDGPU_POLARIS10_RANGE 0x50, 0x5A
+#define AMDGPU_POLARIS11_RANGE 0x5A, 0x64
+#define AMDGPU_POLARIS12_RANGE 0x64, 0x6E
+#define AMDGPU_VEGAM_RANGE 0x6E, 0xFF
+
+#define AMDGPU_CARRIZO_RANGE 0x01, 0x21
+#define AMDGPU_STONEY_RANGE 0x61, 0xFF
+
+#define AMDGPU_VEGA10_RANGE 0x01, 0x14
+#define AMDGPU_VEGA12_RANGE 0x14, 0x28
+#define AMDGPU_VEGA20_RANGE 0x28, 0x32
+#define AMDGPU_ARCTURUS_RANGE 0x32, 0x3C
+#define AMDGPU_ALDEBARAN_RANGE 0x3C, 0xFF
+
+#define AMDGPU_RAVEN_RANGE 0x01, 0x81
+#define AMDGPU_RAVEN2_RANGE 0x81, 0x91
+#define AMDGPU_RENOIR_RANGE 0x91, 0xFF
+
+#define AMDGPU_NAVI10_RANGE 0x01, 0x0A
+#define AMDGPU_NAVI12_RANGE 0x0A, 0x14
+#define AMDGPU_NAVI14_RANGE 0x14, 0x28
+#define AMDGPU_SIENNA_CICHLID_RANGE 0x28, 0x32
+#define AMDGPU_NAVY_FLOUNDER_RANGE 0x32, 0x3C
+#define AMDGPU_DIMGREY_CAVEFISH_RANGE 0x3C, 0x46
+#define AMDGPU_BEIGE_GOBY_RANGE 0x46, 0x50
+
+#define AMDGPU_VANGOGH_RANGE 0x01, 0xFF
+
+#define AMDGPU_YELLOW_CARP_RANGE 0x01, 0xFF
+
+#define AMDGPU_EXPAND_FIX(x) x
+#define AMDGPU_RANGE_HELPER(val, min, max) ((val >= min) && (val < max))
+#define AMDGPU_IN_RANGE(val, ...) AMDGPU_EXPAND_FIX(AMDGPU_RANGE_HELPER(val, __VA_ARGS__))
+
+
+// ASICREV_IS(eRevisionId, revisionName)
+#define ASICREV_IS(r, rn) AMDGPU_IN_RANGE(r, AMDGPU_##rn##_RANGE)
+#define ASICREV_IS_TAHITI_P(r) ASICREV_IS(r, TAHITI)
+#define ASICREV_IS_PITCAIRN_PM(r) ASICREV_IS(r, PITCAIRN)
+#define ASICREV_IS_CAPEVERDE_M(r) ASICREV_IS(r, CAPEVERDE)
+#define ASICREV_IS_OLAND_M(r) ASICREV_IS(r, OLAND)
+#define ASICREV_IS_HAINAN_V(r) ASICREV_IS(r, HAINAN)
+
+#define ASICREV_IS_BONAIRE_M(r) ASICREV_IS(r, BONAIRE)
+#define ASICREV_IS_HAWAII_P(r) ASICREV_IS(r, HAWAII)
+
+#define ASICREV_IS_SPECTRE(r) ASICREV_IS(r, SPECTRE)
+#define ASICREV_IS_SPOOKY(r) ASICREV_IS(r, SPOOKY)
+#define ASICREV_IS_KALINDI(r) ASICREV_IS(r, KALINDI)
+#define ASICREV_IS_KALINDI_GODAVARI(r) ASICREV_IS(r, GODAVARI)
+
+#define ASICREV_IS_ICELAND_M(r) ASICREV_IS(r, ICELAND)
+#define ASICREV_IS_TONGA_P(r) ASICREV_IS(r, TONGA)
+#define ASICREV_IS_FIJI_P(r) ASICREV_IS(r, FIJI)
+
+#define ASICREV_IS_POLARIS10_P(r) ASICREV_IS(r, POLARIS10)
+#define ASICREV_IS_POLARIS11_M(r) ASICREV_IS(r, POLARIS11)
+#define ASICREV_IS_POLARIS12_V(r) ASICREV_IS(r, POLARIS12)
+#define ASICREV_IS_VEGAM_P(r) ASICREV_IS(r, VEGAM)
+
+#define ASICREV_IS_CARRIZO(r) ASICREV_IS(r, CARRIZO)
+#define ASICREV_IS_STONEY(r) ASICREV_IS(r, STONEY)
+
+#define ASICREV_IS_VEGA10_M(r) ASICREV_IS(r, VEGA10)
+#define ASICREV_IS_VEGA10_P(r) ASICREV_IS(r, VEGA10)
+#define ASICREV_IS_VEGA12_P(r) ASICREV_IS(r, VEGA12)
+#define ASICREV_IS_VEGA12_p(r) ASICREV_IS(r, VEGA12)
+#define ASICREV_IS_VEGA20_P(r) ASICREV_IS(r, VEGA20)
+#define ASICREV_IS_ARCTURUS(r) ASICREV_IS(r, ARCTURUS)
+#define ASICREV_IS_ALDEBARAN(r) ASICREV_IS(r, ALDEBARAN)
+
+#define ASICREV_IS_RAVEN(r) ASICREV_IS(r, RAVEN)
+#define ASICREV_IS_RAVEN2(r) ASICREV_IS(r, RAVEN2)
+#define ASICREV_IS_RENOIR(r) ASICREV_IS(r, RENOIR)
+
+#define ASICREV_IS_NAVI10_P(r) ASICREV_IS(r, NAVI10)
+#define ASICREV_IS_NAVI12_P(r) ASICREV_IS(r, NAVI12)
+#define ASICREV_IS_NAVI14_M(r) ASICREV_IS(r, NAVI14)
+#define ASICREV_IS_SIENNA_CICHLID(r) ASICREV_IS(r, SIENNA_CICHLID)
+#define ASICREV_IS_NAVY_FLOUNDER(r) ASICREV_IS(r, NAVY_FLOUNDER)
+#define ASICREV_IS_DIMGREY_CAVEFISH(r) ASICREV_IS(r, DIMGREY_CAVEFISH)
+#define ASICREV_IS_BEIGE_GOBY(r) ASICREV_IS(r, BEIGE_GOBY)
+
+#define ASICREV_IS_VANGOGH(r) ASICREV_IS(r, VANGOGH)
+
+#define ASICREV_IS_YELLOW_CARP(r) ASICREV_IS(r, YELLOW_CARP)
+
+#endif // _AMDGPU_ASIC_ADDR_H
diff --git a/lib/meson.build b/lib/meson.build
index ccee7a59..2ec8baf5 100644
--- a/lib/meson.build
+++ b/lib/meson.build
@@ -13,6 +13,12 @@ lib_sources = [
'i915/intel_memory_region.c',
'i915/intel_mocs.c',
'i915/i915_blt.c',
+ 'amdgpu/amd_memory.c',
+ 'amdgpu/amd_command_submission.c',
+ 'amdgpu/amd_compute.c',
+ 'amdgpu/amd_gfx.c',
+ 'amdgpu/amd_fence.c',
+ 'amdgpu/amd_ip_blocks.c',
'igt_collection.c',
'igt_color_encoding.c',
'igt_debugfs.c',
@@ -122,6 +128,10 @@ if libdrm_nouveau.found()
]
endif
+if libdrm_amdgpu.found()
+ lib_deps += libdrm_amdgpu
+endif
+
if libunwind.found()
lib_deps += libunwind
else
diff --git a/tests/amdgpu/amd_basic.c b/tests/amdgpu/amd_basic.c
index 6c9609b9..4981c4cc 100644
--- a/tests/amdgpu/amd_basic.c
+++ b/tests/amdgpu/amd_basic.c
@@ -1,5 +1,6 @@
/*
* Copyright 2014 Advanced Micro Devices, Inc.
+ * Copyright 2022 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -22,282 +23,24 @@
* Based on libdrm/tests/amdgpu/basic_tests.c
*/
-#include "config.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#ifdef HAVE_ALLOCA_H
-# include <alloca.h>
-#endif
-
-#include "drmtest.h"
-
-#include <amdgpu.h>
-#include <amdgpu_drm.h>
-
-static amdgpu_device_handle device;
-
-static void amdgpu_command_submission_write_linear_helper(unsigned ip_type);
-static void amdgpu_command_submission_const_fill_helper(unsigned ip_type);
-static void amdgpu_command_submission_copy_linear_helper(unsigned ip_type);
+#include "lib/amdgpu/amd_memory.h"
+#include "lib/amdgpu/amd_sdma.h"
+#include "lib/amdgpu/amd_PM4.h"
+#include "lib/amdgpu/amd_command_submission.h"
+#include "lib/amdgpu/amd_compute.h"
+#include "lib/amdgpu/amd_gfx.h"
+#include "lib/amdgpu/amd_fence.h"
#define BUFFER_SIZE (8 * 1024)
-#define SDMA_PKT_HEADER_op_offset 0
-#define SDMA_PKT_HEADER_op_mask 0x000000FF
-#define SDMA_PKT_HEADER_op_shift 0
-#define SDMA_PKT_HEADER_OP(x) (((x) & SDMA_PKT_HEADER_op_mask) << SDMA_PKT_HEADER_op_shift)
-#define SDMA_OPCODE_CONSTANT_FILL 11
-# define SDMA_CONSTANT_FILL_EXTRA_SIZE(x) ((x) << 14)
- /* 0 = byte fill
- * 2 = DW fill
- */
-#define SDMA_PACKET(op, sub_op, e) ((((e) & 0xFFFF) << 16) | \
- (((sub_op) & 0xFF) << 8) | \
- (((op) & 0xFF) << 0))
-#define SDMA_OPCODE_WRITE 2
-# define SDMA_WRITE_SUB_OPCODE_LINEAR 0
-# define SDMA_WRTIE_SUB_OPCODE_TILED 1
-
-#define SDMA_OPCODE_COPY 1
-# define SDMA_COPY_SUB_OPCODE_LINEAR 0
#define GFX_COMPUTE_NOP 0xffff1000
-#define SDMA_NOP 0x0
-
-/* PM4 */
-#define PACKET_TYPE0 0
-#define PACKET_TYPE1 1
-#define PACKET_TYPE2 2
-#define PACKET_TYPE3 3
-
-#define CP_PACKET_GET_TYPE(h) (((h) >> 30) & 3)
-#define CP_PACKET_GET_COUNT(h) (((h) >> 16) & 0x3FFF)
-#define CP_PACKET0_GET_REG(h) ((h) & 0xFFFF)
-#define CP_PACKET3_GET_OPCODE(h) (((h) >> 8) & 0xFF)
-#define PACKET0(reg, n) ((PACKET_TYPE0 << 30) | \
- ((reg) & 0xFFFF) | \
- ((n) & 0x3FFF) << 16)
-#define CP_PACKET2 0x80000000
-#define PACKET2_PAD_SHIFT 0
-#define PACKET2_PAD_MASK (0x3fffffff << 0)
-
-#define PACKET2(v) (CP_PACKET2 | REG_SET(PACKET2_PAD, (v)))
-
-#define PACKET3(op, n) ((PACKET_TYPE3 << 30) | \
- (((op) & 0xFF) << 8) | \
- ((n) & 0x3FFF) << 16)
-
-/* Packet 3 types */
-#define PACKET3_NOP 0x10
-
-#define PACKET3_WRITE_DATA 0x37
-#define WRITE_DATA_DST_SEL(x) ((x) << 8)
- /* 0 - register
- * 1 - memory (sync - via GRBM)
- * 2 - gl2
- * 3 - gds
- * 4 - reserved
- * 5 - memory (async - direct)
- */
-#define WR_ONE_ADDR (1 << 16)
-#define WR_CONFIRM (1 << 20)
-#define WRITE_DATA_CACHE_POLICY(x) ((x) << 25)
- /* 0 - LRU
- * 1 - Stream
- */
-#define WRITE_DATA_ENGINE_SEL(x) ((x) << 30)
- /* 0 - me
- * 1 - pfp
- * 2 - ce
- */
-
-#define PACKET3_DMA_DATA 0x50
-/* 1. header
- * 2. CONTROL
- * 3. SRC_ADDR_LO or DATA [31:0]
- * 4. SRC_ADDR_HI [31:0]
- * 5. DST_ADDR_LO [31:0]
- * 6. DST_ADDR_HI [7:0]
- * 7. COMMAND [30:21] | BYTE_COUNT [20:0]
- */
-/* CONTROL */
-# define PACKET3_DMA_DATA_ENGINE(x) ((x) << 0)
- /* 0 - ME
- * 1 - PFP
- */
-# define PACKET3_DMA_DATA_SRC_CACHE_POLICY(x) ((x) << 13)
- /* 0 - LRU
- * 1 - Stream
- * 2 - Bypass
- */
-# define PACKET3_DMA_DATA_SRC_VOLATILE (1 << 15)
-# define PACKET3_DMA_DATA_DST_SEL(x) ((x) << 20)
- /* 0 - DST_ADDR using DAS
- * 1 - GDS
- * 3 - DST_ADDR using L2
- */
-# define PACKET3_DMA_DATA_DST_CACHE_POLICY(x) ((x) << 25)
- /* 0 - LRU
- * 1 - Stream
- * 2 - Bypass
- */
-# define PACKET3_DMA_DATA_DST_VOLATILE (1 << 27)
-# define PACKET3_DMA_DATA_SRC_SEL(x) ((x) << 29)
- /* 0 - SRC_ADDR using SAS
- * 1 - GDS
- * 2 - DATA
- * 3 - SRC_ADDR using L2
- */
-# define PACKET3_DMA_DATA_CP_SYNC (1 << 31)
-/* COMMAND */
-# define PACKET3_DMA_DATA_DIS_WC (1 << 21)
-# define PACKET3_DMA_DATA_CMD_SRC_SWAP(x) ((x) << 22)
- /* 0 - none
- * 1 - 8 in 16
- * 2 - 8 in 32
- * 3 - 8 in 64
- */
-# define PACKET3_DMA_DATA_CMD_DST_SWAP(x) ((x) << 24)
- /* 0 - none
- * 1 - 8 in 16
- * 2 - 8 in 32
- * 3 - 8 in 64
- */
-# define PACKET3_DMA_DATA_CMD_SAS (1 << 26)
- /* 0 - memory
- * 1 - register
- */
-# define PACKET3_DMA_DATA_CMD_DAS (1 << 27)
- /* 0 - memory
- * 1 - register
- */
-# define PACKET3_DMA_DATA_CMD_SAIC (1 << 28)
-# define PACKET3_DMA_DATA_CMD_DAIC (1 << 29)
-# define PACKET3_DMA_DATA_CMD_RAW_WAIT (1 << 30)
-
-static amdgpu_bo_handle gpu_mem_alloc(amdgpu_device_handle device_handle,
- uint64_t size,
- uint64_t alignment,
- uint32_t type,
- uint64_t flags,
- uint64_t *vmc_addr,
- amdgpu_va_handle *va_handle)
-{
- struct amdgpu_bo_alloc_request req = {
- .alloc_size = size,
- .phys_alignment = alignment,
- .preferred_heap = type,
- .flags = flags,
- };
- amdgpu_bo_handle buf_handle;
- int r;
-
- r = amdgpu_bo_alloc(device_handle, &req, &buf_handle);
- igt_assert_eq(r, 0);
-
- r = amdgpu_va_range_alloc(device_handle,
- amdgpu_gpu_va_range_general,
- size, alignment, 0, vmc_addr,
- va_handle, 0);
- igt_assert_eq(r, 0);
-
- r = amdgpu_bo_va_op(buf_handle, 0, size, *vmc_addr, 0, AMDGPU_VA_OP_MAP);
- igt_assert_eq(r, 0);
-
- return buf_handle;
-}
-
-static void gpu_mem_free(amdgpu_bo_handle bo,
- amdgpu_va_handle va_handle,
- uint64_t vmc_addr,
- uint64_t size)
-{
- int r;
-
- r = amdgpu_bo_va_op(bo, 0, size, vmc_addr, 0, AMDGPU_VA_OP_UNMAP);
- igt_assert_eq(r, 0);
-
- r = amdgpu_va_range_free(va_handle);
- igt_assert_eq(r, 0);
-
- r = amdgpu_bo_free(bo);
- igt_assert_eq(r, 0);
-}
-
-static int
-amdgpu_bo_alloc_and_map(amdgpu_device_handle dev, unsigned size,
- unsigned alignment, unsigned heap, uint64_t flags,
- amdgpu_bo_handle *bo, void **cpu, uint64_t *mc_address,
- amdgpu_va_handle *va_handle)
-{
- struct amdgpu_bo_alloc_request request = {
- .alloc_size = size,
- .phys_alignment = alignment,
- .preferred_heap = heap,
- .flags = flags,
- };
- amdgpu_bo_handle buf_handle;
- amdgpu_va_handle handle;
- uint64_t vmc_addr;
- int r;
-
- r = amdgpu_bo_alloc(dev, &request, &buf_handle);
- if (r)
- return r;
-
- r = amdgpu_va_range_alloc(dev,
- amdgpu_gpu_va_range_general,
- size, alignment, 0, &vmc_addr,
- &handle, 0);
- if (r)
- goto error_va_alloc;
-
- r = amdgpu_bo_va_op(buf_handle, 0, size, vmc_addr, 0, AMDGPU_VA_OP_MAP);
- if (r)
- goto error_va_map;
-
- r = amdgpu_bo_cpu_map(buf_handle, cpu);
- if (r)
- goto error_cpu_map;
-
- *bo = buf_handle;
- *mc_address = vmc_addr;
- *va_handle = handle;
-
- return 0;
-
-error_cpu_map:
- amdgpu_bo_cpu_unmap(buf_handle);
-error_va_map:
- amdgpu_bo_va_op(buf_handle, 0, size, vmc_addr, 0, AMDGPU_VA_OP_UNMAP);
-error_va_alloc:
- amdgpu_bo_free(buf_handle);
- return r;
-}
-
-static void
-amdgpu_bo_unmap_and_free(amdgpu_bo_handle bo, amdgpu_va_handle va_handle,
- uint64_t mc_addr, uint64_t size)
-{
- amdgpu_bo_cpu_unmap(bo);
- amdgpu_bo_va_op(bo, 0, size, mc_addr, 0, AMDGPU_VA_OP_UNMAP);
- amdgpu_va_range_free(va_handle);
- amdgpu_bo_free(bo);
-}
-
-static int
-amdgpu_get_bo_list(amdgpu_device_handle dev, amdgpu_bo_handle bo1,
- amdgpu_bo_handle bo2, amdgpu_bo_list_handle *list)
-{
- amdgpu_bo_handle resources[] = {bo1, bo2};
-
- return amdgpu_bo_list_create(dev, bo2 ? 2 : 1, resources, NULL, list);
-}
-
-static void amdgpu_memory_alloc(void)
+/**
+ * MEM ALLOC TEST
+ * @param device
+ */
+static void amdgpu_memory_alloc(amdgpu_device_handle device)
{
amdgpu_bo_handle bo;
amdgpu_va_handle va_handle;
@@ -339,197 +82,57 @@ static void amdgpu_memory_alloc(void)
gpu_mem_free(bo, va_handle, bo_mc, 4096);
}
-static void amdgpu_command_submission_gfx_separate_ibs(void)
-{
- amdgpu_context_handle context_handle;
- amdgpu_bo_handle ib_result_handle, ib_result_ce_handle;
- void *ib_result_cpu, *ib_result_ce_cpu;
- uint64_t ib_result_mc_address, ib_result_ce_mc_address;
- struct amdgpu_cs_request ibs_request = {0};
- struct amdgpu_cs_ib_info ib_info[2];
- struct amdgpu_cs_fence fence_status = {0};
- uint32_t *ptr;
- uint32_t expired;
- amdgpu_bo_list_handle bo_list;
- amdgpu_va_handle va_handle, va_handle_ce;
- int r;
-
- r = amdgpu_cs_ctx_create(device, &context_handle);
- igt_assert_eq(r, 0);
-
- r = amdgpu_bo_alloc_and_map(device, 4096, 4096,
- AMDGPU_GEM_DOMAIN_GTT, 0,
- &ib_result_handle, &ib_result_cpu,
- &ib_result_mc_address, &va_handle);
- igt_assert_eq(r, 0);
-
- r = amdgpu_bo_alloc_and_map(device, 4096, 4096,
- AMDGPU_GEM_DOMAIN_GTT, 0,
- &ib_result_ce_handle, &ib_result_ce_cpu,
- &ib_result_ce_mc_address, &va_handle_ce);
- igt_assert_eq(r, 0);
-
- r = amdgpu_get_bo_list(device, ib_result_handle,
- ib_result_ce_handle, &bo_list);
- igt_assert_eq(r, 0);
-
- memset(ib_info, 0, 2 * sizeof(struct amdgpu_cs_ib_info));
-
- /* IT_SET_CE_DE_COUNTERS */
- ptr = ib_result_ce_cpu;
- ptr[0] = 0xc0008900;
- ptr[1] = 0;
- ptr[2] = 0xc0008400;
- ptr[3] = 1;
- ib_info[0].ib_mc_address = ib_result_ce_mc_address;
- ib_info[0].size = 4;
- ib_info[0].flags = AMDGPU_IB_FLAG_CE;
-
- /* IT_WAIT_ON_CE_COUNTER */
- ptr = ib_result_cpu;
- ptr[0] = 0xc0008600;
- ptr[1] = 0x00000001;
- ib_info[1].ib_mc_address = ib_result_mc_address;
- ib_info[1].size = 2;
-
- ibs_request.ip_type = AMDGPU_HW_IP_GFX;
- ibs_request.number_of_ibs = 2;
- ibs_request.ibs = ib_info;
- ibs_request.resources = bo_list;
- ibs_request.fence_info.handle = NULL;
-
- r = amdgpu_cs_submit(context_handle, 0,&ibs_request, 1);
-
- igt_assert_eq(r, 0);
- fence_status.context = context_handle;
- fence_status.ip_type = AMDGPU_HW_IP_GFX;
- fence_status.ip_instance = 0;
- fence_status.fence = ibs_request.seq_no;
-
- r = amdgpu_cs_query_fence_status(&fence_status,
- AMDGPU_TIMEOUT_INFINITE,
- 0, &expired);
- igt_assert_eq(r, 0);
-
- amdgpu_bo_unmap_and_free(ib_result_handle, va_handle,
- ib_result_mc_address, 4096);
- amdgpu_bo_unmap_and_free(ib_result_ce_handle, va_handle_ce,
- ib_result_ce_mc_address, 4096);
-
- r = amdgpu_bo_list_destroy(bo_list);
- igt_assert_eq(r, 0);
-
- r = amdgpu_cs_ctx_free(context_handle);
- igt_assert_eq(r, 0);
-}
-
-static void amdgpu_command_submission_gfx_shared_ib(void)
-{
- amdgpu_context_handle context_handle;
- amdgpu_bo_handle ib_result_handle;
- void *ib_result_cpu;
- uint64_t ib_result_mc_address;
- struct amdgpu_cs_request ibs_request = {0};
- struct amdgpu_cs_ib_info ib_info[2];
- struct amdgpu_cs_fence fence_status = {0};
- uint32_t *ptr;
- uint32_t expired;
- amdgpu_bo_list_handle bo_list;
- amdgpu_va_handle va_handle;
- int r;
-
- r = amdgpu_cs_ctx_create(device, &context_handle);
- igt_assert_eq(r, 0);
-
- r = amdgpu_bo_alloc_and_map(device, 4096, 4096,
- AMDGPU_GEM_DOMAIN_GTT, 0,
- &ib_result_handle, &ib_result_cpu,
- &ib_result_mc_address, &va_handle);
- igt_assert_eq(r, 0);
-
- r = amdgpu_get_bo_list(device, ib_result_handle, NULL,
- &bo_list);
- igt_assert_eq(r, 0);
-
- memset(ib_info, 0, 2 * sizeof(struct amdgpu_cs_ib_info));
-
- /* IT_SET_CE_DE_COUNTERS */
- ptr = ib_result_cpu;
- ptr[0] = 0xc0008900;
- ptr[1] = 0;
- ptr[2] = 0xc0008400;
- ptr[3] = 1;
- ib_info[0].ib_mc_address = ib_result_mc_address;
- ib_info[0].size = 4;
- ib_info[0].flags = AMDGPU_IB_FLAG_CE;
-
- ptr = (uint32_t *)ib_result_cpu + 4;
- ptr[0] = 0xc0008600;
- ptr[1] = 0x00000001;
- ib_info[1].ib_mc_address = ib_result_mc_address + 16;
- ib_info[1].size = 2;
-
- ibs_request.ip_type = AMDGPU_HW_IP_GFX;
- ibs_request.number_of_ibs = 2;
- ibs_request.ibs = ib_info;
- ibs_request.resources = bo_list;
- ibs_request.fence_info.handle = NULL;
-
- r = amdgpu_cs_submit(context_handle, 0, &ibs_request, 1);
-
- igt_assert_eq(r, 0);
-
- fence_status.context = context_handle;
- fence_status.ip_type = AMDGPU_HW_IP_GFX;
- fence_status.ip_instance = 0;
- fence_status.fence = ibs_request.seq_no;
-
- r = amdgpu_cs_query_fence_status(&fence_status,
- AMDGPU_TIMEOUT_INFINITE,
- 0, &expired);
- igt_assert_eq(r, 0);
-
- amdgpu_bo_unmap_and_free(ib_result_handle, va_handle,
- ib_result_mc_address, 4096);
-
- r = amdgpu_bo_list_destroy(bo_list);
- igt_assert_eq(r, 0);
-
- r = amdgpu_cs_ctx_free(context_handle);
- igt_assert_eq(r, 0);
-}
-
-static void amdgpu_command_submission_gfx_cp_write_data(void)
-{
- amdgpu_command_submission_write_linear_helper(AMDGPU_HW_IP_GFX);
-}
-
-static void amdgpu_command_submission_gfx_cp_const_fill(void)
-{
- amdgpu_command_submission_const_fill_helper(AMDGPU_HW_IP_GFX);
-}
-
-static void amdgpu_command_submission_gfx_cp_copy_data(void)
+/**
+ * AMDGPU_HW_IP_GFX
+ * @param device
+ */
+static void amdgpu_command_submission_gfx(amdgpu_device_handle device)
{
- amdgpu_command_submission_copy_linear_helper(AMDGPU_HW_IP_GFX);
+ /* write data using the CP */
+ amdgpu_command_submission_write_linear_helper(device, get_ip_block(device, AMDGPU_HW_IP_GFX), false);
+ /* const fill using the CP */
+ amdgpu_command_submission_const_fill_helper(device, get_ip_block(device, AMDGPU_HW_IP_GFX));
+ /* copy data using the CP */
+ amdgpu_command_submission_copy_linear_helper(device, get_ip_block(device, AMDGPU_HW_IP_GFX));
+ /* separate IB buffers for multi-IB submission */
+ amdgpu_command_submission_gfx_separate_ibs(device);
+ /* shared IB buffer for multi-IB submission */
+ amdgpu_command_submission_gfx_shared_ib(device);
}
-static void amdgpu_command_submission_gfx(void)
+/**
+ * AMDGPU_HW_IP_COMPUTE
+ * @param device
+ */
+static void amdgpu_command_submission_compute(amdgpu_device_handle device)
{
/* write data using the CP */
- amdgpu_command_submission_gfx_cp_write_data();
+ amdgpu_command_submission_write_linear_helper(device, get_ip_block(device, AMDGPU_HW_IP_COMPUTE), false);
/* const fill using the CP */
- amdgpu_command_submission_gfx_cp_const_fill();
+ amdgpu_command_submission_const_fill_helper(device, get_ip_block(device, AMDGPU_HW_IP_COMPUTE));
/* copy data using the CP */
- amdgpu_command_submission_gfx_cp_copy_data();
- /* separate IB buffers for multi-IB submission */
- amdgpu_command_submission_gfx_separate_ibs();
- /* shared IB buffer for multi-IB submission */
- amdgpu_command_submission_gfx_shared_ib();
+ amdgpu_command_submission_copy_linear_helper(device, get_ip_block(device, AMDGPU_HW_IP_COMPUTE));
+ /* nop test */
+ amdgpu_command_submission_compute_nop(device);
}
-static void amdgpu_semaphore_test(void)
+/**
+ * AMDGPU_HW_IP_DMA
+ * @param device
+ */
+static void amdgpu_command_submission_sdma(amdgpu_device_handle device)
+{
+ amdgpu_command_submission_write_linear_helper(device, get_ip_block(device, AMDGPU_HW_IP_DMA), false);
+ amdgpu_command_submission_const_fill_helper(device, get_ip_block(device, AMDGPU_HW_IP_DMA));
+ amdgpu_command_submission_copy_linear_helper(device, get_ip_block(device, AMDGPU_HW_IP_DMA));
+}
+
+/**
+ * SEMAPHORE
+ * @param device
+ */
+static void amdgpu_semaphore_test(amdgpu_device_handle device)
{
amdgpu_context_handle context_handle[2];
amdgpu_semaphore_handle sem;
@@ -658,717 +261,92 @@ static void amdgpu_semaphore_test(void)
igt_assert_eq(r, 0);
}
-static void amdgpu_command_submission_compute_nop(void)
-{
- amdgpu_context_handle context_handle;
- amdgpu_bo_handle ib_result_handle;
- void *ib_result_cpu;
- uint64_t ib_result_mc_address;
- struct amdgpu_cs_request ibs_request;
- struct amdgpu_cs_ib_info ib_info;
- struct amdgpu_cs_fence fence_status;
- struct drm_amdgpu_info_hw_ip info;
- uint32_t *ptr;
- uint32_t expired;
- int r, instance;
- amdgpu_bo_list_handle bo_list;
- amdgpu_va_handle va_handle;
-
- r = amdgpu_query_hw_ip_info(device, AMDGPU_HW_IP_COMPUTE, 0, &info);
- igt_assert_eq(r, 0);
-
- r = amdgpu_cs_ctx_create(device, &context_handle);
- igt_assert_eq(r, 0);
-
- for (instance = 0; info.available_rings & (1 << instance); instance++) {
- r = amdgpu_bo_alloc_and_map(device, 4096, 4096,
- AMDGPU_GEM_DOMAIN_GTT, 0,
- &ib_result_handle, &ib_result_cpu,
- &ib_result_mc_address, &va_handle);
- igt_assert_eq(r, 0);
-
- r = amdgpu_get_bo_list(device, ib_result_handle, NULL,
- &bo_list);
- igt_assert_eq(r, 0);
-
- ptr = ib_result_cpu;
- memset(ptr, 0, 16);
- ptr[0] = PACKET3(PACKET3_NOP, 14);
-
- memset(&ib_info, 0, sizeof(struct amdgpu_cs_ib_info));
- ib_info.ib_mc_address = ib_result_mc_address;
- ib_info.size = 16;
-
- memset(&ibs_request, 0, sizeof(struct amdgpu_cs_request));
- ibs_request.ip_type = AMDGPU_HW_IP_COMPUTE;
- ibs_request.ring = instance;
- ibs_request.number_of_ibs = 1;
- ibs_request.ibs = &ib_info;
- ibs_request.resources = bo_list;
- ibs_request.fence_info.handle = NULL;
-
- memset(&fence_status, 0, sizeof(struct amdgpu_cs_fence));
- r = amdgpu_cs_submit(context_handle, 0,&ibs_request, 1);
- igt_assert_eq(r, 0);
-
- fence_status.context = context_handle;
- fence_status.ip_type = AMDGPU_HW_IP_COMPUTE;
- fence_status.ip_instance = 0;
- fence_status.ring = instance;
- fence_status.fence = ibs_request.seq_no;
-
- r = amdgpu_cs_query_fence_status(&fence_status,
- AMDGPU_TIMEOUT_INFINITE,
- 0, &expired);
- igt_assert_eq(r, 0);
-
- r = amdgpu_bo_list_destroy(bo_list);
- igt_assert_eq(r, 0);
-
- amdgpu_bo_unmap_and_free(ib_result_handle, va_handle,
- ib_result_mc_address, 4096);
- }
-
- r = amdgpu_cs_ctx_free(context_handle);
- igt_assert_eq(r, 0);
-}
-
-static void amdgpu_command_submission_compute_cp_write_data(void)
-{
- amdgpu_command_submission_write_linear_helper(AMDGPU_HW_IP_COMPUTE);
-}
-
-static void amdgpu_command_submission_compute_cp_const_fill(void)
-{
- amdgpu_command_submission_const_fill_helper(AMDGPU_HW_IP_COMPUTE);
-}
-
-static void amdgpu_command_submission_compute_cp_copy_data(void)
-{
- amdgpu_command_submission_copy_linear_helper(AMDGPU_HW_IP_COMPUTE);
-}
-
-static void amdgpu_command_submission_compute(void)
-{
- /* write data using the CP */
- amdgpu_command_submission_compute_cp_write_data();
- /* const fill using the CP */
- amdgpu_command_submission_compute_cp_const_fill();
- /* copy data using the CP */
- amdgpu_command_submission_compute_cp_copy_data();
- /* nop test */
- amdgpu_command_submission_compute_nop();
-}
-/*
- * caller need create/release:
- * pm4_src, resources, ib_info, and ibs_request
- * submit command stream described in ibs_request and wait for this IB accomplished
+/**
+ * MULTI FENCE
+ * @param device
*/
-static void amdgpu_test_exec_cs_helper(amdgpu_context_handle context_handle,
- unsigned ip_type,
- int instance, int pm4_dw, uint32_t *pm4_src,
- int res_cnt, amdgpu_bo_handle *resources,
- struct amdgpu_cs_ib_info *ib_info,
- struct amdgpu_cs_request *ibs_request)
-{
- int r;
- uint32_t expired;
- uint32_t *ring_ptr;
- amdgpu_bo_handle ib_result_handle;
- void *ib_result_cpu;
- uint64_t ib_result_mc_address;
- struct amdgpu_cs_fence fence_status = {0};
- amdgpu_bo_handle *all_res = alloca(sizeof(resources[0]) * (res_cnt + 1));
- amdgpu_va_handle va_handle;
-
- /* prepare CS */
- igt_assert(pm4_dw <= 1024);
-
- /* allocate IB */
- r = amdgpu_bo_alloc_and_map(device, 4096, 4096,
- AMDGPU_GEM_DOMAIN_GTT, 0,
- &ib_result_handle, &ib_result_cpu,
- &ib_result_mc_address, &va_handle);
- igt_assert_eq(r, 0);
-
- /* copy PM4 packet to ring from caller */
- ring_ptr = ib_result_cpu;
- memcpy(ring_ptr, pm4_src, pm4_dw * sizeof(*pm4_src));
-
- ib_info->ib_mc_address = ib_result_mc_address;
- ib_info->size = pm4_dw;
-
- ibs_request->ip_type = ip_type;
- ibs_request->ring = instance;
- ibs_request->number_of_ibs = 1;
- ibs_request->ibs = ib_info;
- ibs_request->fence_info.handle = NULL;
-
- memcpy(all_res, resources, sizeof(resources[0]) * res_cnt);
- all_res[res_cnt] = ib_result_handle;
-
- r = amdgpu_bo_list_create(device, res_cnt+1, all_res,
- NULL, &ibs_request->resources);
- igt_assert_eq(r, 0);
-
- /* submit CS */
- r = amdgpu_cs_submit(context_handle, 0, ibs_request, 1);
- igt_assert_eq(r, 0);
-
- r = amdgpu_bo_list_destroy(ibs_request->resources);
- igt_assert_eq(r, 0);
-
- fence_status.ip_type = ip_type;
- fence_status.ip_instance = 0;
- fence_status.ring = ibs_request->ring;
- fence_status.context = context_handle;
- fence_status.fence = ibs_request->seq_no;
-
- /* wait for IB accomplished */
- r = amdgpu_cs_query_fence_status(&fence_status,
- AMDGPU_TIMEOUT_INFINITE,
- 0, &expired);
- igt_assert_eq(r, 0);
- igt_assert_eq(expired, true);
-
- amdgpu_bo_unmap_and_free(ib_result_handle, va_handle,
- ib_result_mc_address, 4096);
-}
-
-static void amdgpu_command_submission_write_linear_helper(unsigned ip_type)
-{
- const int sdma_write_length = 128;
- const int pm4_dw = 256;
- amdgpu_context_handle context_handle;
- amdgpu_bo_handle bo;
- amdgpu_bo_handle *resources;
- uint32_t *pm4;
- struct amdgpu_cs_ib_info *ib_info;
- struct amdgpu_cs_request *ibs_request;
- struct amdgpu_gpu_info gpu_info = {0};
- uint64_t bo_mc;
- volatile uint32_t *bo_cpu;
- int i, j, r, loop;
- uint64_t gtt_flags[2] = {0, AMDGPU_GEM_CREATE_CPU_GTT_USWC};
- amdgpu_va_handle va_handle;
-
- r = amdgpu_query_gpu_info(device, &gpu_info);
- igt_assert_eq(r, 0);
-
- pm4 = calloc(pm4_dw, sizeof(*pm4));
- igt_assert(pm4);
-
- ib_info = calloc(1, sizeof(*ib_info));
- igt_assert(ib_info);
-
- ibs_request = calloc(1, sizeof(*ibs_request));
- igt_assert(ibs_request);
-
- r = amdgpu_cs_ctx_create(device, &context_handle);
- igt_assert_eq(r, 0);
-
- /* prepare resource */
- resources = calloc(1, sizeof(amdgpu_bo_handle));
- igt_assert(resources);
-
- loop = 0;
- while(loop < 2) {
- /* allocate UC bo for sDMA use */
- r = amdgpu_bo_alloc_and_map(device,
- sdma_write_length * sizeof(uint32_t),
- 4096, AMDGPU_GEM_DOMAIN_GTT,
- gtt_flags[loop], &bo, (void**)&bo_cpu,
- &bo_mc, &va_handle);
- igt_assert_eq(r, 0);
-
- /* clear bo */
- memset((void*)bo_cpu, 0, sdma_write_length * sizeof(uint32_t));
-
-
- resources[0] = bo;
-
- /* fulfill PM4: test DMA write-linear */
- i = j = 0;
- if (ip_type == AMDGPU_HW_IP_DMA) {
- pm4[i++] = SDMA_PACKET(SDMA_OPCODE_WRITE,
- SDMA_WRITE_SUB_OPCODE_LINEAR, 0);
- pm4[i++] = 0xffffffff & bo_mc;
- pm4[i++] = (0xffffffff00000000 & bo_mc) >> 32;
- if (gpu_info.family_id >= AMDGPU_FAMILY_AI)
- pm4[i++] = sdma_write_length - 1;
- else
- pm4[i++] = sdma_write_length;
- while(j++ < sdma_write_length)
- pm4[i++] = 0xdeadbeaf;
- } else if ((ip_type == AMDGPU_HW_IP_GFX) ||
- (ip_type == AMDGPU_HW_IP_COMPUTE)) {
- pm4[i++] = PACKET3(PACKET3_WRITE_DATA, 2 + sdma_write_length);
- pm4[i++] = WRITE_DATA_DST_SEL(5) | WR_CONFIRM;
- pm4[i++] = 0xfffffffc & bo_mc;
- pm4[i++] = (0xffffffff00000000 & bo_mc) >> 32;
- while(j++ < sdma_write_length)
- pm4[i++] = 0xdeadbeaf;
- }
-
- amdgpu_test_exec_cs_helper(context_handle,
- ip_type, 0,
- i, pm4,
- 1, resources,
- ib_info, ibs_request);
-
- /* verify if SDMA test result meets with expected */
- i = 0;
- while(i < sdma_write_length) {
- igt_assert_eq(bo_cpu[i++], 0xdeadbeaf);
- }
-
- amdgpu_bo_unmap_and_free(bo, va_handle, bo_mc,
- sdma_write_length * sizeof(uint32_t));
- loop++;
- }
- /* clean resources */
- free(resources);
- free(ibs_request);
- free(ib_info);
- free(pm4);
-
- /* end of test */
- r = amdgpu_cs_ctx_free(context_handle);
- igt_assert_eq(r, 0);
-}
-
-static void amdgpu_command_submission_sdma_write_linear(void)
+static void amdgpu_command_submission_multi_fence(amdgpu_device_handle device)
{
- amdgpu_command_submission_write_linear_helper(AMDGPU_HW_IP_DMA);
+ amdgpu_command_submission_multi_fence_wait_all(device, true);
+ amdgpu_command_submission_multi_fence_wait_all(device, false);
}
-static void amdgpu_command_submission_const_fill_helper(unsigned ip_type)
+static void amdgpu_userptr_test(amdgpu_device_handle device)
{
- const int sdma_write_length = 1024 * 1024;
const int pm4_dw = 256;
- amdgpu_context_handle context_handle;
- amdgpu_bo_handle bo;
- amdgpu_bo_handle *resources;
- uint32_t *pm4;
- struct amdgpu_cs_ib_info *ib_info;
- struct amdgpu_cs_request *ibs_request;
- struct amdgpu_gpu_info gpu_info = {0};
- uint64_t bo_mc;
- volatile uint32_t *bo_cpu;
- int i, j, r, loop;
- uint64_t gtt_flags[2] = {0, AMDGPU_GEM_CREATE_CPU_GTT_USWC};
- amdgpu_va_handle va_handle;
-
- r = amdgpu_query_gpu_info(device, &gpu_info);
- igt_assert_eq(r, 0);
-
- pm4 = calloc(pm4_dw, sizeof(*pm4));
- igt_assert(pm4);
-
- ib_info = calloc(1, sizeof(*ib_info));
- igt_assert(ib_info);
+ const int sdma_write_length = 4;
- ibs_request = calloc(1, sizeof(*ibs_request));
- igt_assert(ibs_request);
-
- r = amdgpu_cs_ctx_create(device, &context_handle);
- igt_assert_eq(r, 0);
-
- /* prepare resource */
- resources = calloc(1, sizeof(amdgpu_bo_handle));
- igt_assert(resources);
-
- loop = 0;
- while(loop < 2) {
- /* allocate UC bo for sDMA use */
- r = amdgpu_bo_alloc_and_map(device,
- sdma_write_length, 4096,
- AMDGPU_GEM_DOMAIN_GTT,
- gtt_flags[loop], &bo, (void**)&bo_cpu,
- &bo_mc, &va_handle);
- igt_assert_eq(r, 0);
-
- /* clear bo */
- memset((void*)bo_cpu, 0, sdma_write_length);
-
- resources[0] = bo;
-
- /* fulfill PM4: test DMA const fill */
- i = j = 0;
- if (ip_type == AMDGPU_HW_IP_DMA) {
- pm4[i++] = SDMA_PACKET(SDMA_OPCODE_CONSTANT_FILL, 0,
- SDMA_CONSTANT_FILL_EXTRA_SIZE(2));
- pm4[i++] = 0xffffffff & bo_mc;
- pm4[i++] = (0xffffffff00000000 & bo_mc) >> 32;
- pm4[i++] = 0xdeadbeaf;
- if (gpu_info.family_id >= AMDGPU_FAMILY_AI)
- pm4[i++] = sdma_write_length - 1;
- else
- pm4[i++] = sdma_write_length;
- } else if ((ip_type == AMDGPU_HW_IP_GFX) ||
- (ip_type == AMDGPU_HW_IP_COMPUTE)) {
- pm4[i++] = PACKET3(PACKET3_DMA_DATA, 5);
- pm4[i++] = PACKET3_DMA_DATA_ENGINE(0) |
- PACKET3_DMA_DATA_DST_SEL(0) |
- PACKET3_DMA_DATA_SRC_SEL(2) |
- PACKET3_DMA_DATA_CP_SYNC;
- pm4[i++] = 0xdeadbeaf;
- pm4[i++] = 0;
- pm4[i++] = 0xfffffffc & bo_mc;
- pm4[i++] = (0xffffffff00000000 & bo_mc) >> 32;
- pm4[i++] = sdma_write_length;
- }
-
- amdgpu_test_exec_cs_helper(context_handle,
- ip_type, 0,
- i, pm4,
- 1, resources,
- ib_info, ibs_request);
-
- /* verify if SDMA test result meets with expected */
- i = 0;
- while(i < (sdma_write_length / 4)) {
- igt_assert_eq(bo_cpu[i++], 0xdeadbeaf);
- }
-
- amdgpu_bo_unmap_and_free(bo, va_handle, bo_mc,
- sdma_write_length);
- loop++;
- }
- /* clean resources */
- free(resources);
- free(ibs_request);
- free(ib_info);
- free(pm4);
-
- /* end of test */
- r = amdgpu_cs_ctx_free(context_handle);
- igt_assert_eq(r, 0);
-}
-
-static void amdgpu_command_submission_sdma_const_fill(void)
-{
- amdgpu_command_submission_const_fill_helper(AMDGPU_HW_IP_DMA);
-}
-
-static void amdgpu_command_submission_copy_linear_helper(unsigned ip_type)
-{
- const int sdma_write_length = 1024;
- const int pm4_dw = 256;
- amdgpu_context_handle context_handle;
- amdgpu_bo_handle bo1, bo2;
- amdgpu_bo_handle *resources;
- uint32_t *pm4;
- struct amdgpu_cs_ib_info *ib_info;
- struct amdgpu_cs_request *ibs_request;
- struct amdgpu_gpu_info gpu_info = {0};
- uint64_t bo1_mc, bo2_mc;
- volatile unsigned char *bo1_cpu, *bo2_cpu;
- int i, j, r, loop1, loop2;
- uint64_t gtt_flags[2] = {0, AMDGPU_GEM_CREATE_CPU_GTT_USWC};
- amdgpu_va_handle bo1_va_handle, bo2_va_handle;
-
- r = amdgpu_query_gpu_info(device, &gpu_info);
- igt_assert_eq(r, 0);
-
- pm4 = calloc(pm4_dw, sizeof(*pm4));
- igt_assert(pm4);
-
- ib_info = calloc(1, sizeof(*ib_info));
- igt_assert(ib_info);
-
- ibs_request = calloc(1, sizeof(*ibs_request));
- igt_assert(ibs_request);
-
- r = amdgpu_cs_ctx_create(device, &context_handle);
- igt_assert_eq(r, 0);
-
- /* prepare resource */
- resources = calloc(2, sizeof(amdgpu_bo_handle));
- igt_assert(resources);
-
- loop1 = loop2 = 0;
- /* run 9 circle to test all mapping combination */
- while(loop1 < 2) {
- while(loop2 < 2) {
- /* allocate UC bo1for sDMA use */
- r = amdgpu_bo_alloc_and_map(device,
- sdma_write_length, 4096,
- AMDGPU_GEM_DOMAIN_GTT,
- gtt_flags[loop1], &bo1,
- (void**)&bo1_cpu, &bo1_mc,
- &bo1_va_handle);
- igt_assert_eq(r, 0);
-
- /* set bo1 */
- memset((void*)bo1_cpu, 0xaa, sdma_write_length);
-
- /* allocate UC bo2 for sDMA use */
- r = amdgpu_bo_alloc_and_map(device,
- sdma_write_length, 4096,
- AMDGPU_GEM_DOMAIN_GTT,
- gtt_flags[loop2], &bo2,
- (void**)&bo2_cpu, &bo2_mc,
- &bo2_va_handle);
- igt_assert_eq(r, 0);
-
- /* clear bo2 */
- memset((void*)bo2_cpu, 0, sdma_write_length);
-
- resources[0] = bo1;
- resources[1] = bo2;
-
- /* fulfill PM4: test DMA copy linear */
- i = j = 0;
- if (ip_type == AMDGPU_HW_IP_DMA) {
- pm4[i++] = SDMA_PACKET(SDMA_OPCODE_COPY, SDMA_COPY_SUB_OPCODE_LINEAR, 0);
- if (gpu_info.family_id >= AMDGPU_FAMILY_AI)
- pm4[i++] = sdma_write_length - 1;
- else
- pm4[i++] = sdma_write_length;
- pm4[i++] = 0;
- pm4[i++] = 0xffffffff & bo1_mc;
- pm4[i++] = (0xffffffff00000000 & bo1_mc) >> 32;
- pm4[i++] = 0xffffffff & bo2_mc;
- pm4[i++] = (0xffffffff00000000 & bo2_mc) >> 32;
- } else if ((ip_type == AMDGPU_HW_IP_GFX) ||
- (ip_type == AMDGPU_HW_IP_COMPUTE)) {
- pm4[i++] = PACKET3(PACKET3_DMA_DATA, 5);
- pm4[i++] = PACKET3_DMA_DATA_ENGINE(0) |
- PACKET3_DMA_DATA_DST_SEL(0) |
- PACKET3_DMA_DATA_SRC_SEL(0) |
- PACKET3_DMA_DATA_CP_SYNC;
- pm4[i++] = 0xfffffffc & bo1_mc;
- pm4[i++] = (0xffffffff00000000 & bo1_mc) >> 32;
- pm4[i++] = 0xfffffffc & bo2_mc;
- pm4[i++] = (0xffffffff00000000 & bo2_mc) >> 32;
- pm4[i++] = sdma_write_length;
- }
-
- amdgpu_test_exec_cs_helper(context_handle,
- ip_type, 0,
- i, pm4,
- 2, resources,
- ib_info, ibs_request);
-
- /* verify if SDMA test result meets with expected */
- i = 0;
- while(i < sdma_write_length) {
- igt_assert_eq(bo2_cpu[i++], 0xaa);
- }
-
- amdgpu_bo_unmap_and_free(bo1, bo1_va_handle, bo1_mc,
- sdma_write_length);
- amdgpu_bo_unmap_and_free(bo2, bo2_va_handle, bo2_mc,
- sdma_write_length);
- loop2++;
- }
- loop1++;
- }
- /* clean resources */
- free(resources);
- free(ibs_request);
- free(ib_info);
- free(pm4);
-
- /* end of test */
- r = amdgpu_cs_ctx_free(context_handle);
- igt_assert_eq(r, 0);
-}
-
-static void amdgpu_command_submission_sdma_copy_linear(void)
-{
- amdgpu_command_submission_copy_linear_helper(AMDGPU_HW_IP_DMA);
-}
-
-static void amdgpu_command_submission_sdma(void)
-{
- amdgpu_command_submission_sdma_write_linear();
- amdgpu_command_submission_sdma_const_fill();
- amdgpu_command_submission_sdma_copy_linear();
-}
-
-static void amdgpu_command_submission_multi_fence_wait_all(bool wait_all)
-{
- amdgpu_context_handle context_handle;
- amdgpu_bo_handle ib_result_handle, ib_result_ce_handle;
- void *ib_result_cpu, *ib_result_ce_cpu;
- uint64_t ib_result_mc_address, ib_result_ce_mc_address;
- struct amdgpu_cs_request ibs_request[2] = {};
- struct amdgpu_cs_ib_info ib_info[2];
- struct amdgpu_cs_fence fence_status[2] = {};
- uint32_t *ptr;
- uint32_t expired;
- amdgpu_bo_list_handle bo_list;
- amdgpu_va_handle va_handle, va_handle_ce;
+ struct amdgpu_ring_context *ring_context;
int r;
- int i, ib_cs_num = 2;
- r = amdgpu_cs_ctx_create(device, &context_handle);
- igt_assert_eq(r, 0);
+ const struct amdgpu_ip_block_version * ip_block = get_ip_block(device, AMDGPU_HW_IP_DMA);
+ igt_assert(ip_block);
+ ring_context = calloc(1, sizeof(*ring_context));
+ igt_assert(ring_context);
- r = amdgpu_bo_alloc_and_map(device, 4096, 4096,
- AMDGPU_GEM_DOMAIN_GTT, 0,
- &ib_result_handle, &ib_result_cpu,
- &ib_result_mc_address, &va_handle);
- igt_assert_eq(r, 0);
-
- r = amdgpu_bo_alloc_and_map(device, 4096, 4096,
- AMDGPU_GEM_DOMAIN_GTT, 0,
- &ib_result_ce_handle, &ib_result_ce_cpu,
- &ib_result_ce_mc_address, &va_handle_ce);
- igt_assert_eq(r, 0);
-
- r = amdgpu_get_bo_list(device, ib_result_handle,
- ib_result_ce_handle, &bo_list);
- igt_assert_eq(r, 0);
+ /* setup parameters */
- memset(ib_info, 0, 2 * sizeof(struct amdgpu_cs_ib_info));
-
- /* IT_SET_CE_DE_COUNTERS */
- ptr = ib_result_ce_cpu;
- ptr[0] = 0xc0008900;
- ptr[1] = 0;
- ptr[2] = 0xc0008400;
- ptr[3] = 1;
- ib_info[0].ib_mc_address = ib_result_ce_mc_address;
- ib_info[0].size = 4;
- ib_info[0].flags = AMDGPU_IB_FLAG_CE;
-
- /* IT_WAIT_ON_CE_COUNTER */
- ptr = ib_result_cpu;
- ptr[0] = 0xc0008600;
- ptr[1] = 0x00000001;
- ib_info[1].ib_mc_address = ib_result_mc_address;
- ib_info[1].size = 2;
-
- for (i = 0; i < ib_cs_num; i++) {
- ibs_request[i].ip_type = AMDGPU_HW_IP_GFX;
- ibs_request[i].number_of_ibs = 2;
- ibs_request[i].ibs = ib_info;
- ibs_request[i].resources = bo_list;
- ibs_request[i].fence_info.handle = NULL;
- }
-
- r = amdgpu_cs_submit(context_handle, 0,ibs_request, ib_cs_num);
+ ring_context->write_length = sdma_write_length;
+ ring_context->pm4 = calloc(pm4_dw, sizeof(*ring_context->pm4));
+ ring_context->secure = false;
+ ring_context->pm4_size = pm4_dw;
+ ring_context->res_cnt = 1;
+ igt_assert(ring_context->pm4);
+ r = amdgpu_cs_ctx_create(device, &ring_context->context_handle);
igt_assert_eq(r, 0);
- for (i = 0; i < ib_cs_num; i++) {
- fence_status[i].context = context_handle;
- fence_status[i].ip_type = AMDGPU_HW_IP_GFX;
- fence_status[i].fence = ibs_request[i].seq_no;
- }
+ posix_memalign((void**)&ring_context->bo_cpu, sysconf(_SC_PAGE_SIZE), BUFFER_SIZE);
+ igt_assert(ring_context->bo_cpu);
+ memset((void*)ring_context->bo_cpu, 0, BUFFER_SIZE);
- r = amdgpu_cs_wait_fences(fence_status, ib_cs_num, wait_all,
- AMDGPU_TIMEOUT_INFINITE,
- &expired, NULL);
+ r = amdgpu_create_bo_from_user_mem(device,
+ (void*)ring_context->bo_cpu,
+ BUFFER_SIZE, &ring_context->bo);
igt_assert_eq(r, 0);
- amdgpu_bo_unmap_and_free(ib_result_handle, va_handle,
- ib_result_mc_address, 4096);
+ ring_context->resources[0] = ring_context->bo;
- amdgpu_bo_unmap_and_free(ib_result_ce_handle, va_handle_ce,
- ib_result_ce_mc_address, 4096);
- r = amdgpu_bo_list_destroy(bo_list);
- igt_assert_eq(r, 0);
+ r = amdgpu_va_range_alloc(device,
+ amdgpu_gpu_va_range_general,
+ BUFFER_SIZE, 1, 0, &ring_context->bo_mc,
+ &ring_context->va_handle, 0);
- r = amdgpu_cs_ctx_free(context_handle);
igt_assert_eq(r, 0);
-}
-static void amdgpu_command_submission_multi_fence(void)
-{
- amdgpu_command_submission_multi_fence_wait_all(true);
- amdgpu_command_submission_multi_fence_wait_all(false);
-}
-
-static void amdgpu_userptr_test(void)
-{
- int i, r, j;
- uint32_t *pm4 = NULL;
- uint64_t bo_mc;
- void *ptr = NULL;
- int pm4_dw = 256;
- int sdma_write_length = 4;
- amdgpu_bo_handle handle;
- amdgpu_context_handle context_handle;
- struct amdgpu_cs_ib_info *ib_info;
- struct amdgpu_cs_request *ibs_request;
- amdgpu_bo_handle buf_handle;
- amdgpu_va_handle va_handle;
+ r = amdgpu_bo_va_op(ring_context->bo, 0, BUFFER_SIZE, ring_context->bo_mc, 0, AMDGPU_VA_OP_MAP);
- pm4 = calloc(pm4_dw, sizeof(*pm4));
- igt_assert(pm4);
-
- ib_info = calloc(1, sizeof(*ib_info));
- igt_assert(ib_info);
-
- ibs_request = calloc(1, sizeof(*ibs_request));
- igt_assert(ibs_request);
-
- r = amdgpu_cs_ctx_create(device, &context_handle);
igt_assert_eq(r, 0);
- posix_memalign(&ptr, sysconf(_SC_PAGE_SIZE), BUFFER_SIZE);
- igt_assert(ptr);
- memset(ptr, 0, BUFFER_SIZE);
+ ip_block->funcs->write_linear(ip_block->funcs, ring_context, &ring_context->pm4_dw);
- r = amdgpu_create_bo_from_user_mem(device,
- ptr, BUFFER_SIZE, &buf_handle);
- igt_assert_eq(r, 0);
-
- r = amdgpu_va_range_alloc(device,
- amdgpu_gpu_va_range_general,
- BUFFER_SIZE, 1, 0, &bo_mc,
- &va_handle, 0);
- igt_assert_eq(r, 0);
+ amdgpu_test_exec_cs_helper(device, ip_block->type, ring_context);
- r = amdgpu_bo_va_op(buf_handle, 0, BUFFER_SIZE, bo_mc, 0, AMDGPU_VA_OP_MAP);
+ r = ip_block->funcs->compare(ip_block->funcs, ring_context, 1);
igt_assert_eq(r, 0);
- handle = buf_handle;
-
- j = i = 0;
- pm4[i++] = SDMA_PACKET(SDMA_OPCODE_WRITE,
- SDMA_WRITE_SUB_OPCODE_LINEAR, 0);
- pm4[i++] = 0xffffffff & bo_mc;
- pm4[i++] = (0xffffffff00000000 & bo_mc) >> 32;
- pm4[i++] = sdma_write_length;
-
- while (j++ < sdma_write_length)
- pm4[i++] = 0xdeadbeaf;
-
- amdgpu_test_exec_cs_helper(context_handle,
- AMDGPU_HW_IP_DMA, 0,
- i, pm4,
- 1, &handle,
- ib_info, ibs_request);
- i = 0;
- while (i < sdma_write_length) {
- igt_assert_eq(((int*)ptr)[i++], 0xdeadbeaf);
- }
- free(ibs_request);
- free(ib_info);
- free(pm4);
-
- r = amdgpu_bo_va_op(buf_handle, 0, BUFFER_SIZE, bo_mc, 0, AMDGPU_VA_OP_UNMAP);
+ r = amdgpu_bo_va_op(ring_context->bo, 0, BUFFER_SIZE, ring_context->bo_mc, 0, AMDGPU_VA_OP_UNMAP);
igt_assert_eq(r, 0);
- r = amdgpu_va_range_free(va_handle);
+ r = amdgpu_va_range_free(ring_context->va_handle);
igt_assert_eq(r, 0);
- r = amdgpu_bo_free(buf_handle);
+ r = amdgpu_bo_free(ring_context->bo);
igt_assert_eq(r, 0);
- free(ptr);
- r = amdgpu_cs_ctx_free(context_handle);
+ r = amdgpu_cs_ctx_free(ring_context->context_handle);
igt_assert_eq(r, 0);
+
+ free(ring_context->pm4);
+ free(ring_context);
}
igt_main
{
+ amdgpu_device_handle device;
+ struct amdgpu_gpu_info gpu_info = {0};
int fd = -1;
+ int r;
igt_fixture {
uint32_t major, minor;
@@ -1381,28 +359,34 @@ igt_main
igt_info("Initialized amdgpu, driver version %d.%d\n",
major, minor);
+
+ r = amdgpu_query_gpu_info(device, &gpu_info);
+ igt_assert_eq(r, 0);
+ r = setup_amdgpu_ip_blocks( major, minor, &gpu_info, device);
+ igt_assert_eq(r, 0);
+
}
igt_subtest("memory-alloc")
- amdgpu_memory_alloc();
+ amdgpu_memory_alloc(device);
igt_subtest("userptr")
- amdgpu_userptr_test();
+ amdgpu_userptr_test(device);
igt_subtest("cs-gfx")
- amdgpu_command_submission_gfx();
+ amdgpu_command_submission_gfx(device);
igt_subtest("cs-compute")
- amdgpu_command_submission_compute();
+ amdgpu_command_submission_compute(device);
igt_subtest("cs-multi-fence")
- amdgpu_command_submission_multi_fence();
+ amdgpu_command_submission_multi_fence(device);
igt_subtest("cs-sdma")
- amdgpu_command_submission_sdma();
+ amdgpu_command_submission_sdma(device);
igt_subtest("semaphore")
- amdgpu_semaphore_test();
+ amdgpu_semaphore_test(device);
igt_fixture {
amdgpu_device_deinitialize(device);
--
2.20.1
More information about the igt-dev
mailing list