pan/bit: Submit a WRITE_VALUE job as a sanity check
[mesa.git] / src / panfrost / bifrost / test / bi_submit.c
1 /*
2 * Copyright (C) 2020 Collabora Ltd.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
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
21 * SOFTWARE.
22 *
23 * Authors (Collabora):
24 * Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
25 */
26
27 #include "bit.h"
28 #include "panfrost/pandecode/decode.h"
29 #include "drm-uapi/panfrost_drm.h"
30
31 /* Standalone compiler tests submitting jobs directly to the hardware. Uses the
32 * `bit` prefix for `BIfrost Tests` and because bit sounds wicked cool. */
33
34 static struct panfrost_bo *
35 bit_bo_create(struct panfrost_device *dev, size_t size)
36 {
37 struct panfrost_bo *bo = panfrost_bo_create(dev, size, PAN_BO_EXECUTE);
38 pandecode_inject_mmap(bo->gpu, bo->cpu, bo->size, NULL);
39 return bo;
40 }
41
42 struct panfrost_device *
43 bit_initialize(void *memctx)
44 {
45 int fd = drmOpenWithType("panfrost", NULL, DRM_NODE_RENDER);
46
47 if (fd < 0)
48 unreachable("No panfrost device found. Try chmod?");
49
50 struct panfrost_device *dev = rzalloc(memctx, struct panfrost_device);
51 panfrost_open_device(memctx, fd, dev);
52
53 pandecode_initialize(true);
54 printf("%X\n", dev->gpu_id);
55
56 return dev;
57 }
58
59 static bool
60 bit_submit(struct panfrost_device *dev,
61 enum mali_job_type T,
62 void *payload, size_t payload_size,
63 struct panfrost_bo *bos, size_t bo_count)
64 {
65 struct mali_job_descriptor_header header = {
66 .job_descriptor_size = MALI_JOB_64,
67 .job_type = T,
68 .job_index = 1
69 };
70
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);
74
75 uint32_t *bo_handles = calloc(sizeof(uint32_t), bo_count);
76
77 for (unsigned i = 0; i < bo_count; ++i)
78 bo_handles[i] = bos[i].gem_handle;
79
80 uint32_t syncobj = 0;
81 int ret = 0;
82
83 ret = drmSyncobjCreate(dev->fd, DRM_SYNCOBJ_CREATE_SIGNALED, &syncobj);
84 assert(!ret);
85
86 struct drm_panfrost_submit submit = {
87 .jc = job->gpu,
88 .bo_handles = (uintptr_t) bo_handles,
89 .bo_handle_count = bo_count,
90 .out_sync = syncobj,
91 };
92
93 ret = drmIoctl(dev->fd, DRM_IOCTL_PANFROST_SUBMIT, &submit);
94 assert(!ret);
95 free(bo_handles);
96
97 drmSyncobjWait(dev->fd, &syncobj, 1, INT64_MAX, 0, NULL);
98 pandecode_jc(submit.jc, true, dev->gpu_id, false);
99 return true;
100 }
101
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
104 * WRITE_VALUE job */
105
106 bool
107 bit_sanity_check(struct panfrost_device *dev)
108 {
109 struct panfrost_bo *scratch = bit_bo_create(dev, 4096);
110 ((uint32_t *) scratch->cpu)[0] = 0xAA;
111
112 struct mali_payload_write_value payload = {
113 .address = scratch->gpu,
114 .value_descriptor = MALI_WRITE_VALUE_ZERO
115 };
116
117 bool success = bit_submit(dev, JOB_TYPE_WRITE_VALUE,
118 &payload, sizeof(payload), scratch, 1);
119
120 return success && (((uint8_t *) scratch->cpu)[0] == 0x0);
121 }