• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright © 2016 Broadcom
3  * Copyright © 2019 Collabora, Ltd.
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a
6  * copy of this software and associated documentation files (the "Software"),
7  * to deal in the Software without restriction, including without limitation
8  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9  * and/or sell copies of the Software, and to permit persons to whom the
10  * Software is furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice (including the next
13  * paragraph) shall be included in all copies or substantial portions of the
14  * Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22  * IN THE SOFTWARE.
23  */
24 
25 #include "igt.h"
26 #include "igt_panfrost.h"
27 #include "igt_syncobj.h"
28 #include <unistd.h>
29 #include <stdlib.h>
30 #include <stdio.h>
31 #include <string.h>
32 #include <fcntl.h>
33 #include <inttypes.h>
34 #include <errno.h>
35 #include <sys/stat.h>
36 #include <sys/ioctl.h>
37 #include "panfrost-job.h"
38 #include "panfrost_drm.h"
39 
40 #define WIDTH          1920
41 #define HEIGHT         1080
42 #define CLEAR_COLOR    0xff7f7f7f
43 
44 /* One tenth of a second */
45 #define SHORT_TIME_NSEC 100000000ull
46 
47 /* Add the time that the bad job takes to timeout (sched->timeout) and the time that a reset can take */
48 #define BAD_JOB_TIME_NSEC (SHORT_TIME_NSEC + 500000000ull + 100000000ull)
49 
50 #define NSECS_PER_SEC 1000000000ull
51 
52 static uint64_t
abs_timeout(uint64_t duration)53 abs_timeout(uint64_t duration)
54 {
55         struct timespec current;
56         clock_gettime(CLOCK_MONOTONIC, &current);
57         return (uint64_t)current.tv_sec * NSECS_PER_SEC + current.tv_nsec + duration;
58 }
59 
check_error(int fd,struct panfrost_submit * submit)60 static void check_error(int fd, struct panfrost_submit *submit)
61 {
62 	struct mali_job_descriptor_header *header;
63 
64         header = submit->submit_bo->map;
65         igt_assert_eq_u64(header->fault_pointer, 0);
66 }
67 
check_fb(int fd,struct panfrost_bo * bo)68 static void check_fb(int fd, struct panfrost_bo *bo)
69 {
70         int gpu_prod_id = igt_panfrost_get_param(fd, DRM_PANFROST_PARAM_GPU_PROD_ID);
71         __uint32_t *fbo;
72         int i;
73 
74         fbo = bo->map;
75 
76         if (gpu_prod_id >= 0x0750) {
77                 for (i = 0; i < ALIGN(WIDTH, 16) * HEIGHT; i++)
78                         igt_assert_eq_u32(fbo[i], CLEAR_COLOR);
79         } else {
80                 // Mask the alpha away because on <=T720 we don't know how to have it
81                 for (i = 0; i < ALIGN(WIDTH, 16) * HEIGHT; i++)
82                         igt_assert_eq_u32(fbo[i], CLEAR_COLOR & 0x00ffffff);
83         }
84 }
85 
86 igt_main
87 {
88         int fd;
89 
90         igt_fixture {
91                 fd = drm_open_driver(DRIVER_PANFROST);
92         }
93 
94         igt_subtest("pan-submit") {
95                 struct panfrost_submit *submit;
96 
97                 submit = igt_panfrost_trivial_job(fd, false, WIDTH, HEIGHT,
98                                                   CLEAR_COLOR);
99 
100                 igt_panfrost_bo_mmap(fd, submit->fbo);
101                 do_ioctl(fd, DRM_IOCTL_PANFROST_SUBMIT, submit->args);
102                 igt_assert(syncobj_wait(fd, &submit->args->out_sync, 1,
103                                         abs_timeout(SHORT_TIME_NSEC), 0, NULL));
104                 check_error(fd, submit);
105                 check_fb(fd, submit->fbo);
106                 igt_panfrost_free_job(fd, submit);
107         }
108 
109         igt_subtest("pan-submit-error-no-jc") {
110                 struct drm_panfrost_submit submit = {.jc = 0,};
111                 do_ioctl_err(fd, DRM_IOCTL_PANFROST_SUBMIT, &submit, EINVAL);
112         }
113 
114         igt_subtest("pan-submit-error-bad-in-syncs") {
115                 struct panfrost_submit *submit;
116 
117                 submit = igt_panfrost_trivial_job(fd, false, WIDTH, HEIGHT,
118                                                   CLEAR_COLOR);
119                 submit->args->in_syncs = 0ULL;
120                 submit->args->in_sync_count = 1;
121 
122                 do_ioctl_err(fd, DRM_IOCTL_PANFROST_SUBMIT, submit->args, EFAULT);
123         }
124 
125         igt_subtest("pan-submit-error-bad-bo-handles") {
126                 struct panfrost_submit *submit;
127 
128                 submit = igt_panfrost_trivial_job(fd, false, WIDTH, HEIGHT,
129                                                   CLEAR_COLOR);
130                 submit->args->bo_handles = 0ULL;
131                 submit->args->bo_handle_count = 1;
132 
133                 do_ioctl_err(fd, DRM_IOCTL_PANFROST_SUBMIT, submit->args, EFAULT);
134         }
135 
136         igt_subtest("pan-submit-error-bad-requirements") {
137                 struct panfrost_submit *submit;
138 
139                 submit = igt_panfrost_trivial_job(fd, false, WIDTH, HEIGHT,
140                                                   CLEAR_COLOR);
141                 submit->args->requirements = 2;
142 
143                 do_ioctl_err(fd, DRM_IOCTL_PANFROST_SUBMIT, submit->args, EINVAL);
144         }
145 
146         igt_subtest("pan-submit-error-bad-out-sync") {
147                 struct panfrost_submit *submit;
148 
149                 submit = igt_panfrost_trivial_job(fd, false, WIDTH, HEIGHT,
150                                                   CLEAR_COLOR);
151                 submit->args->out_sync = -1;
152 
153                 do_ioctl_err(fd, DRM_IOCTL_PANFROST_SUBMIT, submit->args, ENODEV);
154         }
155 
156         igt_subtest("pan-reset") {
157                 struct panfrost_submit *submit;
158 
159                 submit = igt_panfrost_trivial_job(fd, true, WIDTH, HEIGHT,
160                                                   CLEAR_COLOR);
161                 do_ioctl(fd, DRM_IOCTL_PANFROST_SUBMIT, submit->args);
162                 /* Expect for this job to timeout */
163                 igt_assert(!syncobj_wait(fd, &submit->args->out_sync, 1,
164                                          abs_timeout(SHORT_TIME_NSEC), 0, NULL));
165                 igt_panfrost_free_job(fd, submit);
166 
167                 submit = igt_panfrost_trivial_job(fd, false, WIDTH, HEIGHT,
168                                                   CLEAR_COLOR);
169                 igt_panfrost_bo_mmap(fd, submit->fbo);
170                 do_ioctl(fd, DRM_IOCTL_PANFROST_SUBMIT, submit->args);
171                 /* This one should work */
172                 igt_assert(syncobj_wait(fd, &submit->args->out_sync, 1,
173                                         abs_timeout(BAD_JOB_TIME_NSEC), 0, NULL));
174                 check_fb(fd, submit->fbo);
175                 igt_panfrost_free_job(fd, submit);
176         }
177 
178         igt_fixture {
179                 close(fd);
180         }
181 }
182