xref: /aosp_15_r20/external/libdrm/tests/tegra/drm-test.c (revision 7688df22e49036ff52a766b7101da3a49edadb8c)
1*7688df22SAndroid Build Coastguard Worker /*
2*7688df22SAndroid Build Coastguard Worker  * Copyright © 2014 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 #ifdef HAVE_CONFIG_H
24*7688df22SAndroid Build Coastguard Worker #  include "config.h"
25*7688df22SAndroid Build Coastguard Worker #endif
26*7688df22SAndroid Build Coastguard Worker 
27*7688df22SAndroid Build Coastguard Worker #include <errno.h>
28*7688df22SAndroid Build Coastguard Worker #include <fcntl.h>
29*7688df22SAndroid Build Coastguard Worker #include <stdbool.h>
30*7688df22SAndroid Build Coastguard Worker #include <stdint.h>
31*7688df22SAndroid Build Coastguard Worker #include <stdio.h>
32*7688df22SAndroid Build Coastguard Worker #include <stdlib.h>
33*7688df22SAndroid Build Coastguard Worker #include <string.h>
34*7688df22SAndroid Build Coastguard Worker #include <unistd.h>
35*7688df22SAndroid Build Coastguard Worker 
36*7688df22SAndroid Build Coastguard Worker #include <sys/ioctl.h>
37*7688df22SAndroid Build Coastguard Worker 
38*7688df22SAndroid Build Coastguard Worker #include "xf86drm.h"
39*7688df22SAndroid Build Coastguard Worker #include "xf86drmMode.h"
40*7688df22SAndroid Build Coastguard Worker #include "drm_fourcc.h"
41*7688df22SAndroid Build Coastguard Worker 
42*7688df22SAndroid Build Coastguard Worker #include "drm-test.h"
43*7688df22SAndroid Build Coastguard Worker 
drm_screen_probe_connector(struct drm_screen * screen,drmModeConnectorPtr connector)44*7688df22SAndroid Build Coastguard Worker static int drm_screen_probe_connector(struct drm_screen *screen,
45*7688df22SAndroid Build Coastguard Worker                                       drmModeConnectorPtr connector)
46*7688df22SAndroid Build Coastguard Worker {
47*7688df22SAndroid Build Coastguard Worker     drmModeEncoderPtr encoder;
48*7688df22SAndroid Build Coastguard Worker     drmModeCrtcPtr crtc;
49*7688df22SAndroid Build Coastguard Worker     drmModeFBPtr fb;
50*7688df22SAndroid Build Coastguard Worker 
51*7688df22SAndroid Build Coastguard Worker     encoder = drmModeGetEncoder(screen->fd, connector->encoder_id);
52*7688df22SAndroid Build Coastguard Worker     if (!encoder)
53*7688df22SAndroid Build Coastguard Worker         return -ENODEV;
54*7688df22SAndroid Build Coastguard Worker 
55*7688df22SAndroid Build Coastguard Worker     crtc = drmModeGetCrtc(screen->fd, encoder->crtc_id);
56*7688df22SAndroid Build Coastguard Worker     if (!crtc) {
57*7688df22SAndroid Build Coastguard Worker         drmModeFreeEncoder(encoder);
58*7688df22SAndroid Build Coastguard Worker         return -ENODEV;
59*7688df22SAndroid Build Coastguard Worker     }
60*7688df22SAndroid Build Coastguard Worker 
61*7688df22SAndroid Build Coastguard Worker     screen->old_fb = crtc->buffer_id;
62*7688df22SAndroid Build Coastguard Worker 
63*7688df22SAndroid Build Coastguard Worker     fb = drmModeGetFB(screen->fd, crtc->buffer_id);
64*7688df22SAndroid Build Coastguard Worker     if (!fb) {
65*7688df22SAndroid Build Coastguard Worker         /* TODO: create new framebuffer */
66*7688df22SAndroid Build Coastguard Worker         drmModeFreeEncoder(encoder);
67*7688df22SAndroid Build Coastguard Worker         drmModeFreeCrtc(crtc);
68*7688df22SAndroid Build Coastguard Worker         return -ENOSYS;
69*7688df22SAndroid Build Coastguard Worker     }
70*7688df22SAndroid Build Coastguard Worker 
71*7688df22SAndroid Build Coastguard Worker     screen->connector = connector->connector_id;
72*7688df22SAndroid Build Coastguard Worker     screen->old_fb = crtc->buffer_id;
73*7688df22SAndroid Build Coastguard Worker     screen->crtc = encoder->crtc_id;
74*7688df22SAndroid Build Coastguard Worker     /* TODO: check crtc->mode_valid */
75*7688df22SAndroid Build Coastguard Worker     screen->mode = crtc->mode;
76*7688df22SAndroid Build Coastguard Worker 
77*7688df22SAndroid Build Coastguard Worker     screen->width = fb->width;
78*7688df22SAndroid Build Coastguard Worker     screen->height = fb->height;
79*7688df22SAndroid Build Coastguard Worker     screen->pitch = fb->pitch;
80*7688df22SAndroid Build Coastguard Worker     screen->depth = fb->depth;
81*7688df22SAndroid Build Coastguard Worker     screen->bpp = fb->bpp;
82*7688df22SAndroid Build Coastguard Worker 
83*7688df22SAndroid Build Coastguard Worker     drmModeFreeEncoder(encoder);
84*7688df22SAndroid Build Coastguard Worker     drmModeFreeCrtc(crtc);
85*7688df22SAndroid Build Coastguard Worker     drmModeFreeFB(fb);
86*7688df22SAndroid Build Coastguard Worker 
87*7688df22SAndroid Build Coastguard Worker     return 0;
88*7688df22SAndroid Build Coastguard Worker }
89*7688df22SAndroid Build Coastguard Worker 
drm_screen_open(struct drm_screen ** screenp,int fd)90*7688df22SAndroid Build Coastguard Worker int drm_screen_open(struct drm_screen **screenp, int fd)
91*7688df22SAndroid Build Coastguard Worker {
92*7688df22SAndroid Build Coastguard Worker     drmModeConnectorPtr connector;
93*7688df22SAndroid Build Coastguard Worker     struct drm_screen *screen;
94*7688df22SAndroid Build Coastguard Worker     bool found = false;
95*7688df22SAndroid Build Coastguard Worker     drmModeResPtr res;
96*7688df22SAndroid Build Coastguard Worker     unsigned int i;
97*7688df22SAndroid Build Coastguard Worker     int err;
98*7688df22SAndroid Build Coastguard Worker 
99*7688df22SAndroid Build Coastguard Worker     if (!screenp || fd < 0)
100*7688df22SAndroid Build Coastguard Worker         return -EINVAL;
101*7688df22SAndroid Build Coastguard Worker 
102*7688df22SAndroid Build Coastguard Worker     screen = calloc(1, sizeof(*screen));
103*7688df22SAndroid Build Coastguard Worker     if (!screen)
104*7688df22SAndroid Build Coastguard Worker         return -ENOMEM;
105*7688df22SAndroid Build Coastguard Worker 
106*7688df22SAndroid Build Coastguard Worker     screen->format = DRM_FORMAT_XRGB8888;
107*7688df22SAndroid Build Coastguard Worker     screen->fd = fd;
108*7688df22SAndroid Build Coastguard Worker 
109*7688df22SAndroid Build Coastguard Worker     res = drmModeGetResources(fd);
110*7688df22SAndroid Build Coastguard Worker     if (!res) {
111*7688df22SAndroid Build Coastguard Worker         free(screen);
112*7688df22SAndroid Build Coastguard Worker         return -ENOMEM;
113*7688df22SAndroid Build Coastguard Worker     }
114*7688df22SAndroid Build Coastguard Worker 
115*7688df22SAndroid Build Coastguard Worker     for (i = 0; i < (unsigned int)res->count_connectors; i++) {
116*7688df22SAndroid Build Coastguard Worker         connector = drmModeGetConnector(fd, res->connectors[i]);
117*7688df22SAndroid Build Coastguard Worker         if (!connector)
118*7688df22SAndroid Build Coastguard Worker             continue;
119*7688df22SAndroid Build Coastguard Worker 
120*7688df22SAndroid Build Coastguard Worker         if (connector->connection != DRM_MODE_CONNECTED) {
121*7688df22SAndroid Build Coastguard Worker             drmModeFreeConnector(connector);
122*7688df22SAndroid Build Coastguard Worker             continue;
123*7688df22SAndroid Build Coastguard Worker         }
124*7688df22SAndroid Build Coastguard Worker 
125*7688df22SAndroid Build Coastguard Worker         err = drm_screen_probe_connector(screen, connector);
126*7688df22SAndroid Build Coastguard Worker         if (err < 0) {
127*7688df22SAndroid Build Coastguard Worker             drmModeFreeConnector(connector);
128*7688df22SAndroid Build Coastguard Worker             continue;
129*7688df22SAndroid Build Coastguard Worker         }
130*7688df22SAndroid Build Coastguard Worker 
131*7688df22SAndroid Build Coastguard Worker         drmModeFreeConnector(connector);
132*7688df22SAndroid Build Coastguard Worker         found = true;
133*7688df22SAndroid Build Coastguard Worker         break;
134*7688df22SAndroid Build Coastguard Worker     }
135*7688df22SAndroid Build Coastguard Worker 
136*7688df22SAndroid Build Coastguard Worker     drmModeFreeResources(res);
137*7688df22SAndroid Build Coastguard Worker 
138*7688df22SAndroid Build Coastguard Worker     if (!found) {
139*7688df22SAndroid Build Coastguard Worker         free(screen);
140*7688df22SAndroid Build Coastguard Worker         return -ENODEV;
141*7688df22SAndroid Build Coastguard Worker     }
142*7688df22SAndroid Build Coastguard Worker 
143*7688df22SAndroid Build Coastguard Worker     *screenp = screen;
144*7688df22SAndroid Build Coastguard Worker 
145*7688df22SAndroid Build Coastguard Worker     return 0;
146*7688df22SAndroid Build Coastguard Worker }
147*7688df22SAndroid Build Coastguard Worker 
drm_screen_close(struct drm_screen * screen)148*7688df22SAndroid Build Coastguard Worker int drm_screen_close(struct drm_screen *screen)
149*7688df22SAndroid Build Coastguard Worker {
150*7688df22SAndroid Build Coastguard Worker     int err;
151*7688df22SAndroid Build Coastguard Worker 
152*7688df22SAndroid Build Coastguard Worker     err = drmModeSetCrtc(screen->fd, screen->crtc, screen->old_fb, 0, 0,
153*7688df22SAndroid Build Coastguard Worker                          &screen->connector, 1, &screen->mode);
154*7688df22SAndroid Build Coastguard Worker     if (err < 0) {
155*7688df22SAndroid Build Coastguard Worker         fprintf(stderr, "drmModeSetCrtc() failed: %m\n");
156*7688df22SAndroid Build Coastguard Worker         return -errno;
157*7688df22SAndroid Build Coastguard Worker     }
158*7688df22SAndroid Build Coastguard Worker 
159*7688df22SAndroid Build Coastguard Worker     free(screen);
160*7688df22SAndroid Build Coastguard Worker 
161*7688df22SAndroid Build Coastguard Worker     return 0;
162*7688df22SAndroid Build Coastguard Worker }
163*7688df22SAndroid Build Coastguard Worker 
drm_framebuffer_new(struct drm_framebuffer ** fbp,struct drm_screen * screen,uint32_t handle,unsigned int width,unsigned int height,unsigned int pitch,uint32_t format,void * data)164*7688df22SAndroid Build Coastguard Worker int drm_framebuffer_new(struct drm_framebuffer **fbp,
165*7688df22SAndroid Build Coastguard Worker                         struct drm_screen *screen, uint32_t handle,
166*7688df22SAndroid Build Coastguard Worker                         unsigned int width, unsigned int height,
167*7688df22SAndroid Build Coastguard Worker                         unsigned int pitch, uint32_t format,
168*7688df22SAndroid Build Coastguard Worker                         void *data)
169*7688df22SAndroid Build Coastguard Worker {
170*7688df22SAndroid Build Coastguard Worker     struct drm_framebuffer *fb;
171*7688df22SAndroid Build Coastguard Worker     uint32_t handles[4];
172*7688df22SAndroid Build Coastguard Worker     uint32_t pitches[4];
173*7688df22SAndroid Build Coastguard Worker     uint32_t offsets[4];
174*7688df22SAndroid Build Coastguard Worker     int err;
175*7688df22SAndroid Build Coastguard Worker 
176*7688df22SAndroid Build Coastguard Worker     fb = calloc(1, sizeof(*fb));
177*7688df22SAndroid Build Coastguard Worker     if (!fb)
178*7688df22SAndroid Build Coastguard Worker         return -ENOMEM;
179*7688df22SAndroid Build Coastguard Worker 
180*7688df22SAndroid Build Coastguard Worker     fb->fd = screen->fd;
181*7688df22SAndroid Build Coastguard Worker     fb->width = width;
182*7688df22SAndroid Build Coastguard Worker     fb->height = height;
183*7688df22SAndroid Build Coastguard Worker     fb->pitch = pitch;
184*7688df22SAndroid Build Coastguard Worker     fb->format = format;
185*7688df22SAndroid Build Coastguard Worker     fb->data = data;
186*7688df22SAndroid Build Coastguard Worker 
187*7688df22SAndroid Build Coastguard Worker     handles[0] = handle;
188*7688df22SAndroid Build Coastguard Worker     pitches[0] = pitch;
189*7688df22SAndroid Build Coastguard Worker     offsets[0] = 0;
190*7688df22SAndroid Build Coastguard Worker 
191*7688df22SAndroid Build Coastguard Worker     err = drmModeAddFB2(screen->fd, width, height, format, handles,
192*7688df22SAndroid Build Coastguard Worker                         pitches, offsets, &fb->handle, 0);
193*7688df22SAndroid Build Coastguard Worker     if (err < 0)
194*7688df22SAndroid Build Coastguard Worker         return -errno;
195*7688df22SAndroid Build Coastguard Worker 
196*7688df22SAndroid Build Coastguard Worker     *fbp = fb;
197*7688df22SAndroid Build Coastguard Worker 
198*7688df22SAndroid Build Coastguard Worker     return 0;
199*7688df22SAndroid Build Coastguard Worker }
200*7688df22SAndroid Build Coastguard Worker 
drm_framebuffer_free(struct drm_framebuffer * fb)201*7688df22SAndroid Build Coastguard Worker int drm_framebuffer_free(struct drm_framebuffer *fb)
202*7688df22SAndroid Build Coastguard Worker {
203*7688df22SAndroid Build Coastguard Worker     int err;
204*7688df22SAndroid Build Coastguard Worker 
205*7688df22SAndroid Build Coastguard Worker     err = drmModeRmFB(fb->fd, fb->handle);
206*7688df22SAndroid Build Coastguard Worker     if (err < 0)
207*7688df22SAndroid Build Coastguard Worker         return -errno;
208*7688df22SAndroid Build Coastguard Worker 
209*7688df22SAndroid Build Coastguard Worker     free(fb);
210*7688df22SAndroid Build Coastguard Worker 
211*7688df22SAndroid Build Coastguard Worker     return 0;
212*7688df22SAndroid Build Coastguard Worker }
213*7688df22SAndroid Build Coastguard Worker 
drm_screen_set_framebuffer(struct drm_screen * screen,struct drm_framebuffer * fb)214*7688df22SAndroid Build Coastguard Worker int drm_screen_set_framebuffer(struct drm_screen *screen,
215*7688df22SAndroid Build Coastguard Worker                                struct drm_framebuffer *fb)
216*7688df22SAndroid Build Coastguard Worker {
217*7688df22SAndroid Build Coastguard Worker     int err;
218*7688df22SAndroid Build Coastguard Worker 
219*7688df22SAndroid Build Coastguard Worker     err = drmModeSetCrtc(screen->fd, screen->crtc, fb->handle, 0, 0,
220*7688df22SAndroid Build Coastguard Worker                          &screen->connector, 1, &screen->mode);
221*7688df22SAndroid Build Coastguard Worker     if (err < 0)
222*7688df22SAndroid Build Coastguard Worker         return -errno;
223*7688df22SAndroid Build Coastguard Worker 
224*7688df22SAndroid Build Coastguard Worker     return 0;
225*7688df22SAndroid Build Coastguard Worker }
226*7688df22SAndroid Build Coastguard Worker 
drm_open(const char * path)227*7688df22SAndroid Build Coastguard Worker int drm_open(const char *path)
228*7688df22SAndroid Build Coastguard Worker {
229*7688df22SAndroid Build Coastguard Worker     int fd, err;
230*7688df22SAndroid Build Coastguard Worker 
231*7688df22SAndroid Build Coastguard Worker     fd = open(path, O_RDWR);
232*7688df22SAndroid Build Coastguard Worker     if (fd < 0)
233*7688df22SAndroid Build Coastguard Worker         return -errno;
234*7688df22SAndroid Build Coastguard Worker 
235*7688df22SAndroid Build Coastguard Worker     err = drmSetMaster(fd);
236*7688df22SAndroid Build Coastguard Worker     if (err < 0) {
237*7688df22SAndroid Build Coastguard Worker         close(fd);
238*7688df22SAndroid Build Coastguard Worker         return -errno;
239*7688df22SAndroid Build Coastguard Worker     }
240*7688df22SAndroid Build Coastguard Worker 
241*7688df22SAndroid Build Coastguard Worker     return fd;
242*7688df22SAndroid Build Coastguard Worker }
243*7688df22SAndroid Build Coastguard Worker 
drm_close(int fd)244*7688df22SAndroid Build Coastguard Worker void drm_close(int fd)
245*7688df22SAndroid Build Coastguard Worker {
246*7688df22SAndroid Build Coastguard Worker     drmDropMaster(fd);
247*7688df22SAndroid Build Coastguard Worker     close(fd);
248*7688df22SAndroid Build Coastguard Worker }
249