2 * Copyright (C) 2020 Collabora Ltd.
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 * Authors (Collabora):
24 * Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
28 #include "panfrost/pandecode/decode.h"
29 #include "drm-uapi/panfrost_drm.h"
31 /* Standalone compiler tests submitting jobs directly to the hardware. Uses the
32 * `bit` prefix for `BIfrost Tests` and because bit sounds wicked cool. */
34 static struct panfrost_bo
*
35 bit_bo_create(struct panfrost_device
*dev
, size_t size
)
37 struct panfrost_bo
*bo
= panfrost_bo_create(dev
, size
, PAN_BO_EXECUTE
);
38 pandecode_inject_mmap(bo
->gpu
, bo
->cpu
, bo
->size
, NULL
);
42 struct panfrost_device
*
43 bit_initialize(void *memctx
)
45 int fd
= drmOpenWithType("panfrost", NULL
, DRM_NODE_RENDER
);
48 unreachable("No panfrost device found. Try chmod?");
50 struct panfrost_device
*dev
= rzalloc(memctx
, struct panfrost_device
);
51 panfrost_open_device(memctx
, fd
, dev
);
53 pandecode_initialize(true);
54 printf("%X\n", dev
->gpu_id
);
60 bit_submit(struct panfrost_device
*dev
,
62 void *payload
, size_t payload_size
,
63 struct panfrost_bo
*bos
, size_t bo_count
)
65 struct mali_job_descriptor_header header
= {
66 .job_descriptor_size
= MALI_JOB_64
,
71 struct panfrost_bo
*job
= bit_bo_create(dev
, 4096);
72 memcpy(job
->cpu
, &header
, sizeof(header
));
73 memcpy(job
->cpu
+ sizeof(header
), payload
, payload_size
);
75 uint32_t *bo_handles
= calloc(sizeof(uint32_t), bo_count
);
77 for (unsigned i
= 0; i
< bo_count
; ++i
)
78 bo_handles
[i
] = bos
[i
].gem_handle
;
83 ret
= drmSyncobjCreate(dev
->fd
, DRM_SYNCOBJ_CREATE_SIGNALED
, &syncobj
);
86 struct drm_panfrost_submit submit
= {
88 .bo_handles
= (uintptr_t) bo_handles
,
89 .bo_handle_count
= bo_count
,
93 ret
= drmIoctl(dev
->fd
, DRM_IOCTL_PANFROST_SUBMIT
, &submit
);
97 drmSyncobjWait(dev
->fd
, &syncobj
, 1, INT64_MAX
, 0, NULL
);
98 pandecode_jc(submit
.jc
, true, dev
->gpu_id
, false);
102 /* Checks that the device is alive and responding to basic jobs as a sanity
103 * check - prerequisite to running code on the device. We test this via a
107 bit_sanity_check(struct panfrost_device
*dev
)
109 struct panfrost_bo
*scratch
= bit_bo_create(dev
, 4096);
110 ((uint32_t *) scratch
->cpu
)[0] = 0xAA;
112 struct mali_payload_write_value payload
= {
113 .address
= scratch
->gpu
,
114 .value_descriptor
= MALI_WRITE_VALUE_ZERO
117 bool success
= bit_submit(dev
, JOB_TYPE_WRITE_VALUE
,
118 &payload
, sizeof(payload
), scratch
, 1);
120 return success
&& (((uint8_t *) scratch
->cpu
)[0] == 0x0);