xref: /aosp_15_r20/external/libdrm/tests/kms/libkms-test-device.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 (including the next
12*7688df22SAndroid Build Coastguard Worker  * paragraph) shall be included in all copies or substantial portions of the
13*7688df22SAndroid Build Coastguard Worker  * Software.
14*7688df22SAndroid Build Coastguard Worker  *
15*7688df22SAndroid Build Coastguard Worker  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16*7688df22SAndroid Build Coastguard Worker  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17*7688df22SAndroid Build Coastguard Worker  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18*7688df22SAndroid Build Coastguard Worker  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19*7688df22SAndroid Build Coastguard Worker  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20*7688df22SAndroid Build Coastguard Worker  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21*7688df22SAndroid Build Coastguard Worker  * IN THE SOFTWARE.
22*7688df22SAndroid Build Coastguard Worker  */
23*7688df22SAndroid Build Coastguard Worker 
24*7688df22SAndroid Build Coastguard Worker #include <stdio.h>
25*7688df22SAndroid Build Coastguard Worker #include <string.h>
26*7688df22SAndroid Build Coastguard Worker #include <unistd.h>
27*7688df22SAndroid Build Coastguard Worker 
28*7688df22SAndroid Build Coastguard Worker #include "util/common.h"
29*7688df22SAndroid Build Coastguard Worker #include "libkms-test.h"
30*7688df22SAndroid Build Coastguard Worker 
31*7688df22SAndroid Build Coastguard Worker static const char *const connector_names[] = {
32*7688df22SAndroid Build Coastguard Worker 	"Unknown",
33*7688df22SAndroid Build Coastguard Worker 	"VGA",
34*7688df22SAndroid Build Coastguard Worker 	"DVI-I",
35*7688df22SAndroid Build Coastguard Worker 	"DVI-D",
36*7688df22SAndroid Build Coastguard Worker 	"DVI-A",
37*7688df22SAndroid Build Coastguard Worker 	"Composite",
38*7688df22SAndroid Build Coastguard Worker 	"SVIDEO",
39*7688df22SAndroid Build Coastguard Worker 	"LVDS",
40*7688df22SAndroid Build Coastguard Worker 	"Component",
41*7688df22SAndroid Build Coastguard Worker 	"9PinDIN",
42*7688df22SAndroid Build Coastguard Worker 	"DisplayPort",
43*7688df22SAndroid Build Coastguard Worker 	"HDMI-A",
44*7688df22SAndroid Build Coastguard Worker 	"HDMI-B",
45*7688df22SAndroid Build Coastguard Worker 	"TV",
46*7688df22SAndroid Build Coastguard Worker 	"eDP",
47*7688df22SAndroid Build Coastguard Worker 	"Virtual",
48*7688df22SAndroid Build Coastguard Worker 	"DSI",
49*7688df22SAndroid Build Coastguard Worker };
50*7688df22SAndroid Build Coastguard Worker 
kms_device_probe_screens(struct kms_device * device)51*7688df22SAndroid Build Coastguard Worker static void kms_device_probe_screens(struct kms_device *device)
52*7688df22SAndroid Build Coastguard Worker {
53*7688df22SAndroid Build Coastguard Worker 	unsigned int counts[ARRAY_SIZE(connector_names)];
54*7688df22SAndroid Build Coastguard Worker 	struct kms_screen *screen;
55*7688df22SAndroid Build Coastguard Worker 	drmModeRes *res;
56*7688df22SAndroid Build Coastguard Worker 	int i;
57*7688df22SAndroid Build Coastguard Worker 
58*7688df22SAndroid Build Coastguard Worker 	memset(counts, 0, sizeof(counts));
59*7688df22SAndroid Build Coastguard Worker 
60*7688df22SAndroid Build Coastguard Worker 	res = drmModeGetResources(device->fd);
61*7688df22SAndroid Build Coastguard Worker 	if (!res)
62*7688df22SAndroid Build Coastguard Worker 		return;
63*7688df22SAndroid Build Coastguard Worker 
64*7688df22SAndroid Build Coastguard Worker 	device->screens = calloc(res->count_connectors, sizeof(screen));
65*7688df22SAndroid Build Coastguard Worker 	if (!device->screens)
66*7688df22SAndroid Build Coastguard Worker 		goto err_free_resources;
67*7688df22SAndroid Build Coastguard Worker 
68*7688df22SAndroid Build Coastguard Worker 	for (i = 0; i < res->count_connectors; i++) {
69*7688df22SAndroid Build Coastguard Worker 		unsigned int *count;
70*7688df22SAndroid Build Coastguard Worker 		const char *type;
71*7688df22SAndroid Build Coastguard Worker 		int len;
72*7688df22SAndroid Build Coastguard Worker 
73*7688df22SAndroid Build Coastguard Worker 		screen = kms_screen_create(device, res->connectors[i]);
74*7688df22SAndroid Build Coastguard Worker 		if (!screen)
75*7688df22SAndroid Build Coastguard Worker 			continue;
76*7688df22SAndroid Build Coastguard Worker 
77*7688df22SAndroid Build Coastguard Worker 		/* assign a unique name to this screen */
78*7688df22SAndroid Build Coastguard Worker 		type = connector_names[screen->type];
79*7688df22SAndroid Build Coastguard Worker 		count = &counts[screen->type];
80*7688df22SAndroid Build Coastguard Worker 
81*7688df22SAndroid Build Coastguard Worker 		len = snprintf(NULL, 0, "%s-%u", type, *count);
82*7688df22SAndroid Build Coastguard Worker 
83*7688df22SAndroid Build Coastguard Worker 		screen->name = malloc(len + 1);
84*7688df22SAndroid Build Coastguard Worker 		if (!screen->name) {
85*7688df22SAndroid Build Coastguard Worker 			free(screen);
86*7688df22SAndroid Build Coastguard Worker 			continue;
87*7688df22SAndroid Build Coastguard Worker 		}
88*7688df22SAndroid Build Coastguard Worker 
89*7688df22SAndroid Build Coastguard Worker 		snprintf(screen->name, len + 1, "%s-%u", type, *count);
90*7688df22SAndroid Build Coastguard Worker 		(*count)++;
91*7688df22SAndroid Build Coastguard Worker 
92*7688df22SAndroid Build Coastguard Worker 		device->screens[i] = screen;
93*7688df22SAndroid Build Coastguard Worker 		device->num_screens++;
94*7688df22SAndroid Build Coastguard Worker 	}
95*7688df22SAndroid Build Coastguard Worker 
96*7688df22SAndroid Build Coastguard Worker err_free_resources:
97*7688df22SAndroid Build Coastguard Worker 	drmModeFreeResources(res);
98*7688df22SAndroid Build Coastguard Worker }
99*7688df22SAndroid Build Coastguard Worker 
kms_device_probe_crtcs(struct kms_device * device)100*7688df22SAndroid Build Coastguard Worker static void kms_device_probe_crtcs(struct kms_device *device)
101*7688df22SAndroid Build Coastguard Worker {
102*7688df22SAndroid Build Coastguard Worker 	struct kms_crtc *crtc;
103*7688df22SAndroid Build Coastguard Worker 	drmModeRes *res;
104*7688df22SAndroid Build Coastguard Worker 	int i;
105*7688df22SAndroid Build Coastguard Worker 
106*7688df22SAndroid Build Coastguard Worker 	res = drmModeGetResources(device->fd);
107*7688df22SAndroid Build Coastguard Worker 	if (!res)
108*7688df22SAndroid Build Coastguard Worker 		return;
109*7688df22SAndroid Build Coastguard Worker 
110*7688df22SAndroid Build Coastguard Worker 	device->crtcs = calloc(res->count_crtcs, sizeof(crtc));
111*7688df22SAndroid Build Coastguard Worker 	if (!device->crtcs)
112*7688df22SAndroid Build Coastguard Worker 		goto err_free_resources;
113*7688df22SAndroid Build Coastguard Worker 
114*7688df22SAndroid Build Coastguard Worker 	for (i = 0; i < res->count_crtcs; i++) {
115*7688df22SAndroid Build Coastguard Worker 		crtc = kms_crtc_create(device, res->crtcs[i]);
116*7688df22SAndroid Build Coastguard Worker 		if (!crtc)
117*7688df22SAndroid Build Coastguard Worker 			continue;
118*7688df22SAndroid Build Coastguard Worker 
119*7688df22SAndroid Build Coastguard Worker 		device->crtcs[i] = crtc;
120*7688df22SAndroid Build Coastguard Worker 		device->num_crtcs++;
121*7688df22SAndroid Build Coastguard Worker 	}
122*7688df22SAndroid Build Coastguard Worker 
123*7688df22SAndroid Build Coastguard Worker err_free_resources:
124*7688df22SAndroid Build Coastguard Worker 	drmModeFreeResources(res);
125*7688df22SAndroid Build Coastguard Worker }
126*7688df22SAndroid Build Coastguard Worker 
kms_device_probe_planes(struct kms_device * device)127*7688df22SAndroid Build Coastguard Worker static void kms_device_probe_planes(struct kms_device *device)
128*7688df22SAndroid Build Coastguard Worker {
129*7688df22SAndroid Build Coastguard Worker 	struct kms_plane *plane;
130*7688df22SAndroid Build Coastguard Worker 	drmModePlaneRes *res;
131*7688df22SAndroid Build Coastguard Worker 	unsigned int i;
132*7688df22SAndroid Build Coastguard Worker 
133*7688df22SAndroid Build Coastguard Worker 	res = drmModeGetPlaneResources(device->fd);
134*7688df22SAndroid Build Coastguard Worker 	if (!res)
135*7688df22SAndroid Build Coastguard Worker 		return;
136*7688df22SAndroid Build Coastguard Worker 
137*7688df22SAndroid Build Coastguard Worker 	device->planes = calloc(res->count_planes, sizeof(plane));
138*7688df22SAndroid Build Coastguard Worker 	if (!device->planes)
139*7688df22SAndroid Build Coastguard Worker 		goto err_free_resources;
140*7688df22SAndroid Build Coastguard Worker 
141*7688df22SAndroid Build Coastguard Worker 	for (i = 0; i < res->count_planes; i++) {
142*7688df22SAndroid Build Coastguard Worker 		plane = kms_plane_create(device, res->planes[i]);
143*7688df22SAndroid Build Coastguard Worker 		if (!plane)
144*7688df22SAndroid Build Coastguard Worker 			continue;
145*7688df22SAndroid Build Coastguard Worker 
146*7688df22SAndroid Build Coastguard Worker 		device->planes[i] = plane;
147*7688df22SAndroid Build Coastguard Worker 		device->num_planes++;
148*7688df22SAndroid Build Coastguard Worker 	}
149*7688df22SAndroid Build Coastguard Worker 
150*7688df22SAndroid Build Coastguard Worker err_free_resources:
151*7688df22SAndroid Build Coastguard Worker 	drmModeFreePlaneResources(res);
152*7688df22SAndroid Build Coastguard Worker }
153*7688df22SAndroid Build Coastguard Worker 
kms_device_probe(struct kms_device * device)154*7688df22SAndroid Build Coastguard Worker static void kms_device_probe(struct kms_device *device)
155*7688df22SAndroid Build Coastguard Worker {
156*7688df22SAndroid Build Coastguard Worker 	kms_device_probe_screens(device);
157*7688df22SAndroid Build Coastguard Worker 	kms_device_probe_crtcs(device);
158*7688df22SAndroid Build Coastguard Worker 	kms_device_probe_planes(device);
159*7688df22SAndroid Build Coastguard Worker }
160*7688df22SAndroid Build Coastguard Worker 
kms_device_open(int fd)161*7688df22SAndroid Build Coastguard Worker struct kms_device *kms_device_open(int fd)
162*7688df22SAndroid Build Coastguard Worker {
163*7688df22SAndroid Build Coastguard Worker 	struct kms_device *device;
164*7688df22SAndroid Build Coastguard Worker 
165*7688df22SAndroid Build Coastguard Worker 	device = calloc(1, sizeof(*device));
166*7688df22SAndroid Build Coastguard Worker 	if (!device)
167*7688df22SAndroid Build Coastguard Worker 		return NULL;
168*7688df22SAndroid Build Coastguard Worker 
169*7688df22SAndroid Build Coastguard Worker 	device->fd = fd;
170*7688df22SAndroid Build Coastguard Worker 
171*7688df22SAndroid Build Coastguard Worker 	kms_device_probe(device);
172*7688df22SAndroid Build Coastguard Worker 
173*7688df22SAndroid Build Coastguard Worker 	return device;
174*7688df22SAndroid Build Coastguard Worker }
175*7688df22SAndroid Build Coastguard Worker 
kms_device_close(struct kms_device * device)176*7688df22SAndroid Build Coastguard Worker void kms_device_close(struct kms_device *device)
177*7688df22SAndroid Build Coastguard Worker {
178*7688df22SAndroid Build Coastguard Worker 	unsigned int i;
179*7688df22SAndroid Build Coastguard Worker 
180*7688df22SAndroid Build Coastguard Worker 	for (i = 0; i < device->num_planes; i++)
181*7688df22SAndroid Build Coastguard Worker 		kms_plane_free(device->planes[i]);
182*7688df22SAndroid Build Coastguard Worker 
183*7688df22SAndroid Build Coastguard Worker 	free(device->planes);
184*7688df22SAndroid Build Coastguard Worker 
185*7688df22SAndroid Build Coastguard Worker 	for (i = 0; i < device->num_crtcs; i++)
186*7688df22SAndroid Build Coastguard Worker 		kms_crtc_free(device->crtcs[i]);
187*7688df22SAndroid Build Coastguard Worker 
188*7688df22SAndroid Build Coastguard Worker 	free(device->crtcs);
189*7688df22SAndroid Build Coastguard Worker 
190*7688df22SAndroid Build Coastguard Worker 	for (i = 0; i < device->num_screens; i++)
191*7688df22SAndroid Build Coastguard Worker 		kms_screen_free(device->screens[i]);
192*7688df22SAndroid Build Coastguard Worker 
193*7688df22SAndroid Build Coastguard Worker 	free(device->screens);
194*7688df22SAndroid Build Coastguard Worker 
195*7688df22SAndroid Build Coastguard Worker 	if (device->fd >= 0)
196*7688df22SAndroid Build Coastguard Worker 		close(device->fd);
197*7688df22SAndroid Build Coastguard Worker 
198*7688df22SAndroid Build Coastguard Worker 	free(device);
199*7688df22SAndroid Build Coastguard Worker }
200*7688df22SAndroid Build Coastguard Worker 
kms_device_find_plane_by_type(struct kms_device * device,uint32_t type,unsigned int index)201*7688df22SAndroid Build Coastguard Worker struct kms_plane *kms_device_find_plane_by_type(struct kms_device *device,
202*7688df22SAndroid Build Coastguard Worker 						uint32_t type,
203*7688df22SAndroid Build Coastguard Worker 						unsigned int index)
204*7688df22SAndroid Build Coastguard Worker {
205*7688df22SAndroid Build Coastguard Worker 	unsigned int i;
206*7688df22SAndroid Build Coastguard Worker 
207*7688df22SAndroid Build Coastguard Worker 	for (i = 0; i < device->num_planes; i++) {
208*7688df22SAndroid Build Coastguard Worker 		if (device->planes[i]->type == type) {
209*7688df22SAndroid Build Coastguard Worker 			if (index == 0)
210*7688df22SAndroid Build Coastguard Worker 				return device->planes[i];
211*7688df22SAndroid Build Coastguard Worker 
212*7688df22SAndroid Build Coastguard Worker 			index--;
213*7688df22SAndroid Build Coastguard Worker 		}
214*7688df22SAndroid Build Coastguard Worker 	}
215*7688df22SAndroid Build Coastguard Worker 
216*7688df22SAndroid Build Coastguard Worker 	return NULL;
217*7688df22SAndroid Build Coastguard Worker }
218