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