1*7688df22SAndroid Build Coastguard Worker /*
2*7688df22SAndroid Build Coastguard Worker * Copyright © 2018 NVIDIA Corporation
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 #include <errno.h>
24*7688df22SAndroid Build Coastguard Worker #include <fcntl.h>
25*7688df22SAndroid Build Coastguard Worker #include <stdio.h>
26*7688df22SAndroid Build Coastguard Worker #include <string.h>
27*7688df22SAndroid Build Coastguard Worker #include <unistd.h>
28*7688df22SAndroid Build Coastguard Worker
29*7688df22SAndroid Build Coastguard Worker #include "tegra.h"
30*7688df22SAndroid Build Coastguard Worker
31*7688df22SAndroid Build Coastguard Worker #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
32*7688df22SAndroid Build Coastguard Worker
channel_open(struct drm_tegra * drm,struct drm_tegra_channel ** channel)33*7688df22SAndroid Build Coastguard Worker static int channel_open(struct drm_tegra *drm,
34*7688df22SAndroid Build Coastguard Worker struct drm_tegra_channel **channel)
35*7688df22SAndroid Build Coastguard Worker {
36*7688df22SAndroid Build Coastguard Worker static const struct {
37*7688df22SAndroid Build Coastguard Worker enum drm_tegra_class class;
38*7688df22SAndroid Build Coastguard Worker const char *name;
39*7688df22SAndroid Build Coastguard Worker } classes[] = {
40*7688df22SAndroid Build Coastguard Worker { DRM_TEGRA_VIC, "VIC" },
41*7688df22SAndroid Build Coastguard Worker { DRM_TEGRA_GR2D, "GR2D" },
42*7688df22SAndroid Build Coastguard Worker };
43*7688df22SAndroid Build Coastguard Worker unsigned int i;
44*7688df22SAndroid Build Coastguard Worker int err;
45*7688df22SAndroid Build Coastguard Worker
46*7688df22SAndroid Build Coastguard Worker for (i = 0; i < ARRAY_SIZE(classes); i++) {
47*7688df22SAndroid Build Coastguard Worker err = drm_tegra_channel_open(drm, classes[i].class, channel);
48*7688df22SAndroid Build Coastguard Worker if (err < 0) {
49*7688df22SAndroid Build Coastguard Worker fprintf(stderr, "failed to open channel to %s: %s\n",
50*7688df22SAndroid Build Coastguard Worker classes[i].name, strerror(-err));
51*7688df22SAndroid Build Coastguard Worker continue;
52*7688df22SAndroid Build Coastguard Worker }
53*7688df22SAndroid Build Coastguard Worker
54*7688df22SAndroid Build Coastguard Worker break;
55*7688df22SAndroid Build Coastguard Worker }
56*7688df22SAndroid Build Coastguard Worker
57*7688df22SAndroid Build Coastguard Worker return err;
58*7688df22SAndroid Build Coastguard Worker }
59*7688df22SAndroid Build Coastguard Worker
main(int argc,char * argv[])60*7688df22SAndroid Build Coastguard Worker int main(int argc, char *argv[])
61*7688df22SAndroid Build Coastguard Worker {
62*7688df22SAndroid Build Coastguard Worker const char *device = "/dev/dri/renderD128";
63*7688df22SAndroid Build Coastguard Worker struct drm_tegra_syncpoint *syncpt;
64*7688df22SAndroid Build Coastguard Worker struct drm_tegra_channel *channel;
65*7688df22SAndroid Build Coastguard Worker struct drm_tegra_pushbuf *pushbuf;
66*7688df22SAndroid Build Coastguard Worker struct drm_tegra_job *job;
67*7688df22SAndroid Build Coastguard Worker struct drm_tegra *drm;
68*7688df22SAndroid Build Coastguard Worker uint32_t *ptr;
69*7688df22SAndroid Build Coastguard Worker int fd, err;
70*7688df22SAndroid Build Coastguard Worker
71*7688df22SAndroid Build Coastguard Worker if (argc > 1)
72*7688df22SAndroid Build Coastguard Worker device = argv[1];
73*7688df22SAndroid Build Coastguard Worker
74*7688df22SAndroid Build Coastguard Worker fd = open(device, O_RDWR);
75*7688df22SAndroid Build Coastguard Worker if (fd < 0) {
76*7688df22SAndroid Build Coastguard Worker fprintf(stderr, "open() failed: %s\n", strerror(errno));
77*7688df22SAndroid Build Coastguard Worker return 1;
78*7688df22SAndroid Build Coastguard Worker }
79*7688df22SAndroid Build Coastguard Worker
80*7688df22SAndroid Build Coastguard Worker err = drm_tegra_new(fd, &drm);
81*7688df22SAndroid Build Coastguard Worker if (err < 0) {
82*7688df22SAndroid Build Coastguard Worker fprintf(stderr, "failed to open Tegra device: %s\n", strerror(-err));
83*7688df22SAndroid Build Coastguard Worker close(fd);
84*7688df22SAndroid Build Coastguard Worker return 1;
85*7688df22SAndroid Build Coastguard Worker }
86*7688df22SAndroid Build Coastguard Worker
87*7688df22SAndroid Build Coastguard Worker err = drm_tegra_syncpoint_new(drm, &syncpt);
88*7688df22SAndroid Build Coastguard Worker if (err < 0) {
89*7688df22SAndroid Build Coastguard Worker fprintf(stderr, "failed to allocate syncpoint: %s\n", strerror(-err));
90*7688df22SAndroid Build Coastguard Worker drm_tegra_close(drm);
91*7688df22SAndroid Build Coastguard Worker close(fd);
92*7688df22SAndroid Build Coastguard Worker return 1;
93*7688df22SAndroid Build Coastguard Worker }
94*7688df22SAndroid Build Coastguard Worker
95*7688df22SAndroid Build Coastguard Worker err = channel_open(drm, &channel);
96*7688df22SAndroid Build Coastguard Worker if (err < 0) {
97*7688df22SAndroid Build Coastguard Worker fprintf(stderr, "failed to open channel: %s\n", strerror(-err));
98*7688df22SAndroid Build Coastguard Worker return 1;
99*7688df22SAndroid Build Coastguard Worker }
100*7688df22SAndroid Build Coastguard Worker
101*7688df22SAndroid Build Coastguard Worker err = drm_tegra_job_new(channel, &job);
102*7688df22SAndroid Build Coastguard Worker if (err < 0) {
103*7688df22SAndroid Build Coastguard Worker fprintf(stderr, "failed to create job: %s\n", strerror(-err));
104*7688df22SAndroid Build Coastguard Worker return 1;
105*7688df22SAndroid Build Coastguard Worker }
106*7688df22SAndroid Build Coastguard Worker
107*7688df22SAndroid Build Coastguard Worker err = drm_tegra_job_get_pushbuf(job, &pushbuf);
108*7688df22SAndroid Build Coastguard Worker if (err < 0) {
109*7688df22SAndroid Build Coastguard Worker fprintf(stderr, "failed to create push buffer: %s\n", strerror(-err));
110*7688df22SAndroid Build Coastguard Worker return 1;
111*7688df22SAndroid Build Coastguard Worker }
112*7688df22SAndroid Build Coastguard Worker
113*7688df22SAndroid Build Coastguard Worker err = drm_tegra_pushbuf_begin(pushbuf, 8, &ptr);
114*7688df22SAndroid Build Coastguard Worker if (err < 0) {
115*7688df22SAndroid Build Coastguard Worker fprintf(stderr, "failed to prepare push buffer: %s\n", strerror(-err));
116*7688df22SAndroid Build Coastguard Worker return 1;
117*7688df22SAndroid Build Coastguard Worker }
118*7688df22SAndroid Build Coastguard Worker
119*7688df22SAndroid Build Coastguard Worker /*
120*7688df22SAndroid Build Coastguard Worker * Empty command streams will be rejected, so we use this as an easy way
121*7688df22SAndroid Build Coastguard Worker * to add something to the command stream. But this could be any other,
122*7688df22SAndroid Build Coastguard Worker * valid command stream.
123*7688df22SAndroid Build Coastguard Worker */
124*7688df22SAndroid Build Coastguard Worker err = drm_tegra_pushbuf_sync_cond(pushbuf, &ptr, syncpt,
125*7688df22SAndroid Build Coastguard Worker DRM_TEGRA_SYNC_COND_IMMEDIATE);
126*7688df22SAndroid Build Coastguard Worker if (err < 0) {
127*7688df22SAndroid Build Coastguard Worker fprintf(stderr, "failed to push syncpoint: %s\n", strerror(-err));
128*7688df22SAndroid Build Coastguard Worker return 1;
129*7688df22SAndroid Build Coastguard Worker }
130*7688df22SAndroid Build Coastguard Worker
131*7688df22SAndroid Build Coastguard Worker /* pretend that the syncpoint was incremented a second time */
132*7688df22SAndroid Build Coastguard Worker err = drm_tegra_pushbuf_sync(pushbuf, syncpt, 1);
133*7688df22SAndroid Build Coastguard Worker if (err < 0) {
134*7688df22SAndroid Build Coastguard Worker fprintf(stderr, "failed to push syncpoint: %s\n", strerror(-err));
135*7688df22SAndroid Build Coastguard Worker return 1;
136*7688df22SAndroid Build Coastguard Worker }
137*7688df22SAndroid Build Coastguard Worker
138*7688df22SAndroid Build Coastguard Worker err = drm_tegra_pushbuf_end(pushbuf, ptr);
139*7688df22SAndroid Build Coastguard Worker if (err < 0) {
140*7688df22SAndroid Build Coastguard Worker fprintf(stderr, "failed to update push buffer: %s\n", strerror(-err));
141*7688df22SAndroid Build Coastguard Worker return 1;
142*7688df22SAndroid Build Coastguard Worker }
143*7688df22SAndroid Build Coastguard Worker
144*7688df22SAndroid Build Coastguard Worker err = drm_tegra_job_submit(job, NULL);
145*7688df22SAndroid Build Coastguard Worker if (err < 0) {
146*7688df22SAndroid Build Coastguard Worker fprintf(stderr, "failed to submit job: %s\n", strerror(-err));
147*7688df22SAndroid Build Coastguard Worker return 1;
148*7688df22SAndroid Build Coastguard Worker }
149*7688df22SAndroid Build Coastguard Worker
150*7688df22SAndroid Build Coastguard Worker err = drm_tegra_job_wait(job, 250000);
151*7688df22SAndroid Build Coastguard Worker if (err < 0) {
152*7688df22SAndroid Build Coastguard Worker fprintf(stderr, "failed to wait for job: %s\n", strerror(-err));
153*7688df22SAndroid Build Coastguard Worker return 1;
154*7688df22SAndroid Build Coastguard Worker }
155*7688df22SAndroid Build Coastguard Worker
156*7688df22SAndroid Build Coastguard Worker drm_tegra_job_free(job);
157*7688df22SAndroid Build Coastguard Worker drm_tegra_channel_close(channel);
158*7688df22SAndroid Build Coastguard Worker drm_tegra_syncpoint_free(syncpt);
159*7688df22SAndroid Build Coastguard Worker drm_tegra_close(drm);
160*7688df22SAndroid Build Coastguard Worker close(fd);
161*7688df22SAndroid Build Coastguard Worker
162*7688df22SAndroid Build Coastguard Worker return 0;
163*7688df22SAndroid Build Coastguard Worker }
164