1*7688df22SAndroid Build Coastguard Worker /*
2*7688df22SAndroid Build Coastguard Worker * Copyright 2021 Advanced Micro Devices, Inc.
3*7688df22SAndroid Build Coastguard Worker *
4*7688df22SAndroid Build Coastguard Worker * Permission is hereby granted, free of charge, to any person obtaining a
5*7688df22SAndroid Build Coastguard Worker * copy of this software and associated documentation files (the "Software"),
6*7688df22SAndroid Build Coastguard Worker * to deal in the Software without restriction, including without limitation
7*7688df22SAndroid Build Coastguard Worker * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8*7688df22SAndroid Build Coastguard Worker * and/or sell copies of the Software, and to permit persons to whom the
9*7688df22SAndroid Build Coastguard Worker * Software is furnished to do so, subject to the following conditions:
10*7688df22SAndroid Build Coastguard Worker *
11*7688df22SAndroid Build Coastguard Worker * The above copyright notice and this permission notice shall be included in
12*7688df22SAndroid Build Coastguard Worker * all copies or substantial portions of the Software.
13*7688df22SAndroid Build Coastguard Worker *
14*7688df22SAndroid Build Coastguard Worker * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15*7688df22SAndroid Build Coastguard Worker * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16*7688df22SAndroid Build Coastguard Worker * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17*7688df22SAndroid Build Coastguard Worker * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18*7688df22SAndroid Build Coastguard Worker * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19*7688df22SAndroid Build Coastguard Worker * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20*7688df22SAndroid Build Coastguard Worker * OTHER DEALINGS IN THE SOFTWARE.
21*7688df22SAndroid Build Coastguard Worker *
22*7688df22SAndroid Build Coastguard Worker */
23*7688df22SAndroid Build Coastguard Worker
24*7688df22SAndroid Build Coastguard Worker #include <stdio.h>
25*7688df22SAndroid Build Coastguard Worker #include <sys/types.h>
26*7688df22SAndroid Build Coastguard Worker #include <sys/stat.h>
27*7688df22SAndroid Build Coastguard Worker #include <fcntl.h>
28*7688df22SAndroid Build Coastguard Worker #include <stdarg.h>
29*7688df22SAndroid Build Coastguard Worker #include <string.h>
30*7688df22SAndroid Build Coastguard Worker #include <errno.h>
31*7688df22SAndroid Build Coastguard Worker #include <unistd.h>
32*7688df22SAndroid Build Coastguard Worker #include <stdlib.h>
33*7688df22SAndroid Build Coastguard Worker #include <inttypes.h>
34*7688df22SAndroid Build Coastguard Worker
35*7688df22SAndroid Build Coastguard Worker #include "drm.h"
36*7688df22SAndroid Build Coastguard Worker #include "xf86drmMode.h"
37*7688df22SAndroid Build Coastguard Worker #include "xf86drm.h"
38*7688df22SAndroid Build Coastguard Worker #include "amdgpu.h"
39*7688df22SAndroid Build Coastguard Worker #include "amdgpu_drm.h"
40*7688df22SAndroid Build Coastguard Worker #include "amdgpu_internal.h"
41*7688df22SAndroid Build Coastguard Worker
42*7688df22SAndroid Build Coastguard Worker #define MAX_CARDS_SUPPORTED 4
43*7688df22SAndroid Build Coastguard Worker #define NUM_BUFFER_OBJECTS 1024
44*7688df22SAndroid Build Coastguard Worker
45*7688df22SAndroid Build Coastguard Worker #define SDMA_PACKET(op, sub_op, e) ((((e) & 0xFFFF) << 16) | \
46*7688df22SAndroid Build Coastguard Worker (((sub_op) & 0xFF) << 8) | \
47*7688df22SAndroid Build Coastguard Worker (((op) & 0xFF) << 0))
48*7688df22SAndroid Build Coastguard Worker
49*7688df22SAndroid Build Coastguard Worker #define SDMA_OPCODE_COPY 1
50*7688df22SAndroid Build Coastguard Worker # define SDMA_COPY_SUB_OPCODE_LINEAR 0
51*7688df22SAndroid Build Coastguard Worker
52*7688df22SAndroid Build Coastguard Worker
53*7688df22SAndroid Build Coastguard Worker #define SDMA_PACKET_SI(op, b, t, s, cnt) ((((op) & 0xF) << 28) | \
54*7688df22SAndroid Build Coastguard Worker (((b) & 0x1) << 26) | \
55*7688df22SAndroid Build Coastguard Worker (((t) & 0x1) << 23) | \
56*7688df22SAndroid Build Coastguard Worker (((s) & 0x1) << 22) | \
57*7688df22SAndroid Build Coastguard Worker (((cnt) & 0xFFFFF) << 0))
58*7688df22SAndroid Build Coastguard Worker #define SDMA_OPCODE_COPY_SI 3
59*7688df22SAndroid Build Coastguard Worker
60*7688df22SAndroid Build Coastguard Worker
61*7688df22SAndroid Build Coastguard Worker /** Help string for command line parameters */
62*7688df22SAndroid Build Coastguard Worker static const char usage[] =
63*7688df22SAndroid Build Coastguard Worker "Usage: %s [-?h] [-b v|g|vg size] "
64*7688df22SAndroid Build Coastguard Worker "[-c from to size count]\n"
65*7688df22SAndroid Build Coastguard Worker "where:\n"
66*7688df22SAndroid Build Coastguard Worker " b - Allocate a BO in VRAM, GTT or VRAM|GTT of size bytes.\n"
67*7688df22SAndroid Build Coastguard Worker " This flag can be used multiple times. The first bo will\n"
68*7688df22SAndroid Build Coastguard Worker " have id `1`, then second id `2`, ...\n"
69*7688df22SAndroid Build Coastguard Worker " c - Copy size bytes from BO (bo_id1) to BO (bo_id2), count times\n"
70*7688df22SAndroid Build Coastguard Worker " h - Display this help\n"
71*7688df22SAndroid Build Coastguard Worker "\n"
72*7688df22SAndroid Build Coastguard Worker "Sizes can be postfixes with k, m or g for kilo, mega and gigabyte scaling\n";
73*7688df22SAndroid Build Coastguard Worker
74*7688df22SAndroid Build Coastguard Worker /** Specified options strings for getopt */
75*7688df22SAndroid Build Coastguard Worker static const char options[] = "?hb:c:";
76*7688df22SAndroid Build Coastguard Worker
77*7688df22SAndroid Build Coastguard Worker /* Open AMD devices.
78*7688df22SAndroid Build Coastguard Worker * Returns the fd of the first device it could open.
79*7688df22SAndroid Build Coastguard Worker */
amdgpu_open_device(void)80*7688df22SAndroid Build Coastguard Worker static int amdgpu_open_device(void)
81*7688df22SAndroid Build Coastguard Worker {
82*7688df22SAndroid Build Coastguard Worker drmDevicePtr devices[MAX_CARDS_SUPPORTED];
83*7688df22SAndroid Build Coastguard Worker unsigned int i;
84*7688df22SAndroid Build Coastguard Worker int drm_count;
85*7688df22SAndroid Build Coastguard Worker
86*7688df22SAndroid Build Coastguard Worker drm_count = drmGetDevices2(0, devices, MAX_CARDS_SUPPORTED);
87*7688df22SAndroid Build Coastguard Worker if (drm_count < 0) {
88*7688df22SAndroid Build Coastguard Worker fprintf(stderr, "drmGetDevices2() returned an error %d\n",
89*7688df22SAndroid Build Coastguard Worker drm_count);
90*7688df22SAndroid Build Coastguard Worker return drm_count;
91*7688df22SAndroid Build Coastguard Worker }
92*7688df22SAndroid Build Coastguard Worker
93*7688df22SAndroid Build Coastguard Worker for (i = 0; i < drm_count; i++) {
94*7688df22SAndroid Build Coastguard Worker drmVersionPtr version;
95*7688df22SAndroid Build Coastguard Worker int fd;
96*7688df22SAndroid Build Coastguard Worker
97*7688df22SAndroid Build Coastguard Worker /* If this is not PCI device, skip*/
98*7688df22SAndroid Build Coastguard Worker if (devices[i]->bustype != DRM_BUS_PCI)
99*7688df22SAndroid Build Coastguard Worker continue;
100*7688df22SAndroid Build Coastguard Worker
101*7688df22SAndroid Build Coastguard Worker /* If this is not AMD GPU vender ID, skip*/
102*7688df22SAndroid Build Coastguard Worker if (devices[i]->deviceinfo.pci->vendor_id != 0x1002)
103*7688df22SAndroid Build Coastguard Worker continue;
104*7688df22SAndroid Build Coastguard Worker
105*7688df22SAndroid Build Coastguard Worker if (!(devices[i]->available_nodes & 1 << DRM_NODE_RENDER))
106*7688df22SAndroid Build Coastguard Worker continue;
107*7688df22SAndroid Build Coastguard Worker
108*7688df22SAndroid Build Coastguard Worker fd = open(devices[i]->nodes[DRM_NODE_RENDER], O_RDWR | O_CLOEXEC);
109*7688df22SAndroid Build Coastguard Worker
110*7688df22SAndroid Build Coastguard Worker /* This node is not available. */
111*7688df22SAndroid Build Coastguard Worker if (fd < 0) continue;
112*7688df22SAndroid Build Coastguard Worker
113*7688df22SAndroid Build Coastguard Worker version = drmGetVersion(fd);
114*7688df22SAndroid Build Coastguard Worker if (!version) {
115*7688df22SAndroid Build Coastguard Worker fprintf(stderr,
116*7688df22SAndroid Build Coastguard Worker "Warning: Cannot get version for %s."
117*7688df22SAndroid Build Coastguard Worker "Error is %s\n",
118*7688df22SAndroid Build Coastguard Worker devices[i]->nodes[DRM_NODE_RENDER],
119*7688df22SAndroid Build Coastguard Worker strerror(errno));
120*7688df22SAndroid Build Coastguard Worker close(fd);
121*7688df22SAndroid Build Coastguard Worker continue;
122*7688df22SAndroid Build Coastguard Worker }
123*7688df22SAndroid Build Coastguard Worker
124*7688df22SAndroid Build Coastguard Worker if (strcmp(version->name, "amdgpu")) {
125*7688df22SAndroid Build Coastguard Worker /* This is not AMDGPU driver, skip.*/
126*7688df22SAndroid Build Coastguard Worker drmFreeVersion(version);
127*7688df22SAndroid Build Coastguard Worker close(fd);
128*7688df22SAndroid Build Coastguard Worker continue;
129*7688df22SAndroid Build Coastguard Worker }
130*7688df22SAndroid Build Coastguard Worker
131*7688df22SAndroid Build Coastguard Worker drmFreeVersion(version);
132*7688df22SAndroid Build Coastguard Worker drmFreeDevices(devices, drm_count);
133*7688df22SAndroid Build Coastguard Worker return fd;
134*7688df22SAndroid Build Coastguard Worker }
135*7688df22SAndroid Build Coastguard Worker
136*7688df22SAndroid Build Coastguard Worker return -1;
137*7688df22SAndroid Build Coastguard Worker }
138*7688df22SAndroid Build Coastguard Worker
139*7688df22SAndroid Build Coastguard Worker amdgpu_device_handle device_handle;
140*7688df22SAndroid Build Coastguard Worker amdgpu_context_handle context_handle;
141*7688df22SAndroid Build Coastguard Worker
142*7688df22SAndroid Build Coastguard Worker amdgpu_bo_handle resources[NUM_BUFFER_OBJECTS];
143*7688df22SAndroid Build Coastguard Worker uint64_t virtual[NUM_BUFFER_OBJECTS];
144*7688df22SAndroid Build Coastguard Worker unsigned int num_buffers;
145*7688df22SAndroid Build Coastguard Worker uint32_t *pm4;
146*7688df22SAndroid Build Coastguard Worker
alloc_bo(uint32_t domain,uint64_t size)147*7688df22SAndroid Build Coastguard Worker int alloc_bo(uint32_t domain, uint64_t size)
148*7688df22SAndroid Build Coastguard Worker {
149*7688df22SAndroid Build Coastguard Worker struct amdgpu_bo_alloc_request request = {};
150*7688df22SAndroid Build Coastguard Worker amdgpu_bo_handle bo;
151*7688df22SAndroid Build Coastguard Worker amdgpu_va_handle va;
152*7688df22SAndroid Build Coastguard Worker uint64_t addr;
153*7688df22SAndroid Build Coastguard Worker int r;
154*7688df22SAndroid Build Coastguard Worker
155*7688df22SAndroid Build Coastguard Worker if (num_buffers >= NUM_BUFFER_OBJECTS)
156*7688df22SAndroid Build Coastguard Worker return -ENOSPC;
157*7688df22SAndroid Build Coastguard Worker
158*7688df22SAndroid Build Coastguard Worker request.alloc_size = size;
159*7688df22SAndroid Build Coastguard Worker request.phys_alignment = 0;
160*7688df22SAndroid Build Coastguard Worker request.preferred_heap = domain;
161*7688df22SAndroid Build Coastguard Worker request.flags = 0;
162*7688df22SAndroid Build Coastguard Worker r = amdgpu_bo_alloc(device_handle, &request, &bo);
163*7688df22SAndroid Build Coastguard Worker if (r)
164*7688df22SAndroid Build Coastguard Worker return r;
165*7688df22SAndroid Build Coastguard Worker
166*7688df22SAndroid Build Coastguard Worker r = amdgpu_va_range_alloc(device_handle, amdgpu_gpu_va_range_general,
167*7688df22SAndroid Build Coastguard Worker size, 0, 0, &addr, &va, 0);
168*7688df22SAndroid Build Coastguard Worker if (r)
169*7688df22SAndroid Build Coastguard Worker return r;
170*7688df22SAndroid Build Coastguard Worker
171*7688df22SAndroid Build Coastguard Worker r = amdgpu_bo_va_op_raw(device_handle, bo, 0, size, addr,
172*7688df22SAndroid Build Coastguard Worker AMDGPU_VM_PAGE_READABLE | AMDGPU_VM_PAGE_WRITEABLE |
173*7688df22SAndroid Build Coastguard Worker AMDGPU_VM_PAGE_EXECUTABLE, AMDGPU_VA_OP_MAP);
174*7688df22SAndroid Build Coastguard Worker if (r)
175*7688df22SAndroid Build Coastguard Worker return r;
176*7688df22SAndroid Build Coastguard Worker
177*7688df22SAndroid Build Coastguard Worker resources[num_buffers] = bo;
178*7688df22SAndroid Build Coastguard Worker virtual[num_buffers] = addr;
179*7688df22SAndroid Build Coastguard Worker fprintf(stdout, "Allocated BO number %u at 0x%" PRIx64 ", domain 0x%x, size %" PRIu64 "\n",
180*7688df22SAndroid Build Coastguard Worker num_buffers++, addr, domain, size);
181*7688df22SAndroid Build Coastguard Worker return 0;
182*7688df22SAndroid Build Coastguard Worker }
183*7688df22SAndroid Build Coastguard Worker
submit_ib(uint32_t from,uint32_t to,uint64_t size,uint32_t count)184*7688df22SAndroid Build Coastguard Worker int submit_ib(uint32_t from, uint32_t to, uint64_t size, uint32_t count)
185*7688df22SAndroid Build Coastguard Worker {
186*7688df22SAndroid Build Coastguard Worker struct amdgpu_cs_request ibs_request;
187*7688df22SAndroid Build Coastguard Worker struct amdgpu_cs_fence fence_status;
188*7688df22SAndroid Build Coastguard Worker struct amdgpu_cs_ib_info ib_info;
189*7688df22SAndroid Build Coastguard Worker uint64_t copied = size, delta;
190*7688df22SAndroid Build Coastguard Worker struct timespec start, stop;
191*7688df22SAndroid Build Coastguard Worker
192*7688df22SAndroid Build Coastguard Worker uint64_t src = virtual[from];
193*7688df22SAndroid Build Coastguard Worker uint64_t dst = virtual[to];
194*7688df22SAndroid Build Coastguard Worker uint32_t expired;
195*7688df22SAndroid Build Coastguard Worker int i, r;
196*7688df22SAndroid Build Coastguard Worker
197*7688df22SAndroid Build Coastguard Worker i = 0;
198*7688df22SAndroid Build Coastguard Worker while (size) {
199*7688df22SAndroid Build Coastguard Worker uint64_t bytes = size < 0x40000 ? size : 0x40000;
200*7688df22SAndroid Build Coastguard Worker
201*7688df22SAndroid Build Coastguard Worker if (device_handle->info.family_id == AMDGPU_FAMILY_SI) {
202*7688df22SAndroid Build Coastguard Worker pm4[i++] = SDMA_PACKET_SI(SDMA_OPCODE_COPY_SI, 0, 0, 0,
203*7688df22SAndroid Build Coastguard Worker bytes);
204*7688df22SAndroid Build Coastguard Worker pm4[i++] = 0xffffffff & dst;
205*7688df22SAndroid Build Coastguard Worker pm4[i++] = 0xffffffff & src;
206*7688df22SAndroid Build Coastguard Worker pm4[i++] = (0xffffffff00000000 & dst) >> 32;
207*7688df22SAndroid Build Coastguard Worker pm4[i++] = (0xffffffff00000000 & src) >> 32;
208*7688df22SAndroid Build Coastguard Worker } else {
209*7688df22SAndroid Build Coastguard Worker pm4[i++] = SDMA_PACKET(SDMA_OPCODE_COPY,
210*7688df22SAndroid Build Coastguard Worker SDMA_COPY_SUB_OPCODE_LINEAR,
211*7688df22SAndroid Build Coastguard Worker 0);
212*7688df22SAndroid Build Coastguard Worker if ( device_handle->info.family_id >= AMDGPU_FAMILY_AI)
213*7688df22SAndroid Build Coastguard Worker pm4[i++] = bytes - 1;
214*7688df22SAndroid Build Coastguard Worker else
215*7688df22SAndroid Build Coastguard Worker pm4[i++] = bytes;
216*7688df22SAndroid Build Coastguard Worker pm4[i++] = 0;
217*7688df22SAndroid Build Coastguard Worker pm4[i++] = 0xffffffff & src;
218*7688df22SAndroid Build Coastguard Worker pm4[i++] = (0xffffffff00000000 & src) >> 32;
219*7688df22SAndroid Build Coastguard Worker pm4[i++] = 0xffffffff & dst;
220*7688df22SAndroid Build Coastguard Worker pm4[i++] = (0xffffffff00000000 & dst) >> 32;
221*7688df22SAndroid Build Coastguard Worker }
222*7688df22SAndroid Build Coastguard Worker
223*7688df22SAndroid Build Coastguard Worker size -= bytes;
224*7688df22SAndroid Build Coastguard Worker src += bytes;
225*7688df22SAndroid Build Coastguard Worker dst += bytes;
226*7688df22SAndroid Build Coastguard Worker }
227*7688df22SAndroid Build Coastguard Worker
228*7688df22SAndroid Build Coastguard Worker memset(&ib_info, 0, sizeof(ib_info));
229*7688df22SAndroid Build Coastguard Worker ib_info.ib_mc_address = virtual[0];
230*7688df22SAndroid Build Coastguard Worker ib_info.size = i;
231*7688df22SAndroid Build Coastguard Worker
232*7688df22SAndroid Build Coastguard Worker memset(&ibs_request, 0, sizeof(ibs_request));
233*7688df22SAndroid Build Coastguard Worker ibs_request.ip_type = AMDGPU_HW_IP_DMA;
234*7688df22SAndroid Build Coastguard Worker ibs_request.ring = 0;
235*7688df22SAndroid Build Coastguard Worker ibs_request.number_of_ibs = 1;
236*7688df22SAndroid Build Coastguard Worker ibs_request.ibs = &ib_info;
237*7688df22SAndroid Build Coastguard Worker ibs_request.fence_info.handle = NULL;
238*7688df22SAndroid Build Coastguard Worker
239*7688df22SAndroid Build Coastguard Worker r = clock_gettime(CLOCK_MONOTONIC, &start);
240*7688df22SAndroid Build Coastguard Worker if (r)
241*7688df22SAndroid Build Coastguard Worker return errno;
242*7688df22SAndroid Build Coastguard Worker
243*7688df22SAndroid Build Coastguard Worker r = amdgpu_bo_list_create(device_handle, num_buffers, resources, NULL,
244*7688df22SAndroid Build Coastguard Worker &ibs_request.resources);
245*7688df22SAndroid Build Coastguard Worker if (r)
246*7688df22SAndroid Build Coastguard Worker return r;
247*7688df22SAndroid Build Coastguard Worker
248*7688df22SAndroid Build Coastguard Worker for (i = 0; i < count; ++i) {
249*7688df22SAndroid Build Coastguard Worker r = amdgpu_cs_submit(context_handle, 0, &ibs_request, 1);
250*7688df22SAndroid Build Coastguard Worker if (r)
251*7688df22SAndroid Build Coastguard Worker return r;
252*7688df22SAndroid Build Coastguard Worker }
253*7688df22SAndroid Build Coastguard Worker
254*7688df22SAndroid Build Coastguard Worker r = amdgpu_bo_list_destroy(ibs_request.resources);
255*7688df22SAndroid Build Coastguard Worker if (r)
256*7688df22SAndroid Build Coastguard Worker return r;
257*7688df22SAndroid Build Coastguard Worker
258*7688df22SAndroid Build Coastguard Worker memset(&fence_status, 0, sizeof(fence_status));
259*7688df22SAndroid Build Coastguard Worker fence_status.ip_type = ibs_request.ip_type;
260*7688df22SAndroid Build Coastguard Worker fence_status.ip_instance = 0;
261*7688df22SAndroid Build Coastguard Worker fence_status.ring = ibs_request.ring;
262*7688df22SAndroid Build Coastguard Worker fence_status.context = context_handle;
263*7688df22SAndroid Build Coastguard Worker fence_status.fence = ibs_request.seq_no;
264*7688df22SAndroid Build Coastguard Worker r = amdgpu_cs_query_fence_status(&fence_status,
265*7688df22SAndroid Build Coastguard Worker AMDGPU_TIMEOUT_INFINITE,
266*7688df22SAndroid Build Coastguard Worker 0, &expired);
267*7688df22SAndroid Build Coastguard Worker if (r)
268*7688df22SAndroid Build Coastguard Worker return r;
269*7688df22SAndroid Build Coastguard Worker
270*7688df22SAndroid Build Coastguard Worker r = clock_gettime(CLOCK_MONOTONIC, &stop);
271*7688df22SAndroid Build Coastguard Worker if (r)
272*7688df22SAndroid Build Coastguard Worker return errno;
273*7688df22SAndroid Build Coastguard Worker
274*7688df22SAndroid Build Coastguard Worker delta = stop.tv_nsec + stop.tv_sec * 1000000000UL;
275*7688df22SAndroid Build Coastguard Worker delta -= start.tv_nsec + start.tv_sec * 1000000000UL;
276*7688df22SAndroid Build Coastguard Worker
277*7688df22SAndroid Build Coastguard Worker fprintf(stdout, "Submitted %u IBs to copy from %u(%" PRIx64 ") to %u(%" PRIx64 ") %" PRIu64 " bytes took %" PRIu64 " usec\n",
278*7688df22SAndroid Build Coastguard Worker count, from, virtual[from], to, virtual[to], copied, delta / 1000);
279*7688df22SAndroid Build Coastguard Worker return 0;
280*7688df22SAndroid Build Coastguard Worker }
281*7688df22SAndroid Build Coastguard Worker
next_arg(int argc,char ** argv,const char * msg)282*7688df22SAndroid Build Coastguard Worker void next_arg(int argc, char **argv, const char *msg)
283*7688df22SAndroid Build Coastguard Worker {
284*7688df22SAndroid Build Coastguard Worker optarg = argv[optind++];
285*7688df22SAndroid Build Coastguard Worker if (optind > argc || optarg[0] == '-') {
286*7688df22SAndroid Build Coastguard Worker fprintf(stderr, "%s\n", msg);
287*7688df22SAndroid Build Coastguard Worker exit(EXIT_FAILURE);
288*7688df22SAndroid Build Coastguard Worker }
289*7688df22SAndroid Build Coastguard Worker }
290*7688df22SAndroid Build Coastguard Worker
parse_size(void)291*7688df22SAndroid Build Coastguard Worker uint64_t parse_size(void)
292*7688df22SAndroid Build Coastguard Worker {
293*7688df22SAndroid Build Coastguard Worker uint64_t size;
294*7688df22SAndroid Build Coastguard Worker char ext[2];
295*7688df22SAndroid Build Coastguard Worker
296*7688df22SAndroid Build Coastguard Worker ext[0] = 0;
297*7688df22SAndroid Build Coastguard Worker if (sscanf(optarg, "%" PRIi64 "%1[kmgKMG]", &size, ext) < 1) {
298*7688df22SAndroid Build Coastguard Worker fprintf(stderr, "Can't parse size arg: %s\n", optarg);
299*7688df22SAndroid Build Coastguard Worker exit(EXIT_FAILURE);
300*7688df22SAndroid Build Coastguard Worker }
301*7688df22SAndroid Build Coastguard Worker switch (ext[0]) {
302*7688df22SAndroid Build Coastguard Worker case 'k':
303*7688df22SAndroid Build Coastguard Worker case 'K':
304*7688df22SAndroid Build Coastguard Worker size *= 1024;
305*7688df22SAndroid Build Coastguard Worker break;
306*7688df22SAndroid Build Coastguard Worker case 'm':
307*7688df22SAndroid Build Coastguard Worker case 'M':
308*7688df22SAndroid Build Coastguard Worker size *= 1024 * 1024;
309*7688df22SAndroid Build Coastguard Worker break;
310*7688df22SAndroid Build Coastguard Worker case 'g':
311*7688df22SAndroid Build Coastguard Worker case 'G':
312*7688df22SAndroid Build Coastguard Worker size *= 1024 * 1024 * 1024;
313*7688df22SAndroid Build Coastguard Worker break;
314*7688df22SAndroid Build Coastguard Worker default:
315*7688df22SAndroid Build Coastguard Worker break;
316*7688df22SAndroid Build Coastguard Worker }
317*7688df22SAndroid Build Coastguard Worker return size;
318*7688df22SAndroid Build Coastguard Worker }
319*7688df22SAndroid Build Coastguard Worker
main(int argc,char ** argv)320*7688df22SAndroid Build Coastguard Worker int main(int argc, char **argv)
321*7688df22SAndroid Build Coastguard Worker {
322*7688df22SAndroid Build Coastguard Worker uint32_t major_version, minor_version;
323*7688df22SAndroid Build Coastguard Worker uint32_t domain, from, to, count;
324*7688df22SAndroid Build Coastguard Worker uint64_t size;
325*7688df22SAndroid Build Coastguard Worker int fd, r, c;
326*7688df22SAndroid Build Coastguard Worker
327*7688df22SAndroid Build Coastguard Worker fd = amdgpu_open_device();
328*7688df22SAndroid Build Coastguard Worker if (fd < 0) {
329*7688df22SAndroid Build Coastguard Worker perror("Cannot open AMDGPU device");
330*7688df22SAndroid Build Coastguard Worker exit(EXIT_FAILURE);
331*7688df22SAndroid Build Coastguard Worker }
332*7688df22SAndroid Build Coastguard Worker
333*7688df22SAndroid Build Coastguard Worker r = amdgpu_device_initialize(fd, &major_version, &minor_version, &device_handle);
334*7688df22SAndroid Build Coastguard Worker if (r) {
335*7688df22SAndroid Build Coastguard Worker fprintf(stderr, "amdgpu_device_initialize returned %d\n", r);
336*7688df22SAndroid Build Coastguard Worker exit(EXIT_FAILURE);
337*7688df22SAndroid Build Coastguard Worker }
338*7688df22SAndroid Build Coastguard Worker
339*7688df22SAndroid Build Coastguard Worker r = amdgpu_cs_ctx_create(device_handle, &context_handle);
340*7688df22SAndroid Build Coastguard Worker if (r) {
341*7688df22SAndroid Build Coastguard Worker fprintf(stderr, "amdgpu_cs_ctx_create returned %d\n", r);
342*7688df22SAndroid Build Coastguard Worker exit(EXIT_FAILURE);
343*7688df22SAndroid Build Coastguard Worker }
344*7688df22SAndroid Build Coastguard Worker
345*7688df22SAndroid Build Coastguard Worker if (argc == 1) {
346*7688df22SAndroid Build Coastguard Worker fprintf(stderr, usage, argv[0]);
347*7688df22SAndroid Build Coastguard Worker exit(EXIT_FAILURE);
348*7688df22SAndroid Build Coastguard Worker }
349*7688df22SAndroid Build Coastguard Worker
350*7688df22SAndroid Build Coastguard Worker r = alloc_bo(AMDGPU_GEM_DOMAIN_GTT, 2ULL * 1024 * 1024);
351*7688df22SAndroid Build Coastguard Worker if (r) {
352*7688df22SAndroid Build Coastguard Worker fprintf(stderr, "Buffer allocation failed with %d\n", r);
353*7688df22SAndroid Build Coastguard Worker exit(EXIT_FAILURE);
354*7688df22SAndroid Build Coastguard Worker }
355*7688df22SAndroid Build Coastguard Worker
356*7688df22SAndroid Build Coastguard Worker r = amdgpu_bo_cpu_map(resources[0], (void **)&pm4);
357*7688df22SAndroid Build Coastguard Worker if (r) {
358*7688df22SAndroid Build Coastguard Worker fprintf(stderr, "Buffer mapping failed with %d\n", r);
359*7688df22SAndroid Build Coastguard Worker exit(EXIT_FAILURE);
360*7688df22SAndroid Build Coastguard Worker }
361*7688df22SAndroid Build Coastguard Worker
362*7688df22SAndroid Build Coastguard Worker opterr = 0;
363*7688df22SAndroid Build Coastguard Worker while ((c = getopt(argc, argv, options)) != -1) {
364*7688df22SAndroid Build Coastguard Worker switch (c) {
365*7688df22SAndroid Build Coastguard Worker case 'b':
366*7688df22SAndroid Build Coastguard Worker if (!strcmp(optarg, "v"))
367*7688df22SAndroid Build Coastguard Worker domain = AMDGPU_GEM_DOMAIN_VRAM;
368*7688df22SAndroid Build Coastguard Worker else if (!strcmp(optarg, "g"))
369*7688df22SAndroid Build Coastguard Worker domain = AMDGPU_GEM_DOMAIN_GTT;
370*7688df22SAndroid Build Coastguard Worker else if (!strcmp(optarg, "vg"))
371*7688df22SAndroid Build Coastguard Worker domain = AMDGPU_GEM_DOMAIN_VRAM | AMDGPU_GEM_DOMAIN_GTT;
372*7688df22SAndroid Build Coastguard Worker else {
373*7688df22SAndroid Build Coastguard Worker fprintf(stderr, "Invalid domain: %s\n", optarg);
374*7688df22SAndroid Build Coastguard Worker exit(EXIT_FAILURE);
375*7688df22SAndroid Build Coastguard Worker }
376*7688df22SAndroid Build Coastguard Worker next_arg(argc, argv, "Missing buffer size");
377*7688df22SAndroid Build Coastguard Worker size = parse_size();
378*7688df22SAndroid Build Coastguard Worker if (size < getpagesize()) {
379*7688df22SAndroid Build Coastguard Worker fprintf(stderr, "Buffer size to small %" PRIu64 "\n", size);
380*7688df22SAndroid Build Coastguard Worker exit(EXIT_FAILURE);
381*7688df22SAndroid Build Coastguard Worker }
382*7688df22SAndroid Build Coastguard Worker r = alloc_bo(domain, size);
383*7688df22SAndroid Build Coastguard Worker if (r) {
384*7688df22SAndroid Build Coastguard Worker fprintf(stderr, "Buffer allocation failed with %d\n", r);
385*7688df22SAndroid Build Coastguard Worker exit(EXIT_FAILURE);
386*7688df22SAndroid Build Coastguard Worker }
387*7688df22SAndroid Build Coastguard Worker break;
388*7688df22SAndroid Build Coastguard Worker case 'c':
389*7688df22SAndroid Build Coastguard Worker if (sscanf(optarg, "%u", &from) != 1) {
390*7688df22SAndroid Build Coastguard Worker fprintf(stderr, "Can't parse from buffer: %s\n", optarg);
391*7688df22SAndroid Build Coastguard Worker exit(EXIT_FAILURE);
392*7688df22SAndroid Build Coastguard Worker }
393*7688df22SAndroid Build Coastguard Worker next_arg(argc, argv, "Missing to buffer");
394*7688df22SAndroid Build Coastguard Worker if (sscanf(optarg, "%u", &to) != 1) {
395*7688df22SAndroid Build Coastguard Worker fprintf(stderr, "Can't parse to buffer: %s\n", optarg);
396*7688df22SAndroid Build Coastguard Worker exit(EXIT_FAILURE);
397*7688df22SAndroid Build Coastguard Worker }
398*7688df22SAndroid Build Coastguard Worker next_arg(argc, argv, "Missing size");
399*7688df22SAndroid Build Coastguard Worker size = parse_size();
400*7688df22SAndroid Build Coastguard Worker next_arg(argc, argv, "Missing count");
401*7688df22SAndroid Build Coastguard Worker count = parse_size();
402*7688df22SAndroid Build Coastguard Worker r = submit_ib(from, to, size, count);
403*7688df22SAndroid Build Coastguard Worker if (r) {
404*7688df22SAndroid Build Coastguard Worker fprintf(stderr, "IB submission failed with %d\n", r);
405*7688df22SAndroid Build Coastguard Worker exit(EXIT_FAILURE);
406*7688df22SAndroid Build Coastguard Worker }
407*7688df22SAndroid Build Coastguard Worker break;
408*7688df22SAndroid Build Coastguard Worker case '?':
409*7688df22SAndroid Build Coastguard Worker case 'h':
410*7688df22SAndroid Build Coastguard Worker fprintf(stderr, usage, argv[0]);
411*7688df22SAndroid Build Coastguard Worker exit(EXIT_SUCCESS);
412*7688df22SAndroid Build Coastguard Worker default:
413*7688df22SAndroid Build Coastguard Worker fprintf(stderr, usage, argv[0]);
414*7688df22SAndroid Build Coastguard Worker exit(EXIT_FAILURE);
415*7688df22SAndroid Build Coastguard Worker }
416*7688df22SAndroid Build Coastguard Worker }
417*7688df22SAndroid Build Coastguard Worker
418*7688df22SAndroid Build Coastguard Worker return EXIT_SUCCESS;
419*7688df22SAndroid Build Coastguard Worker }
420