12 #include "xf86drmMode.h"
14 #include "exynos_drm.h"
16 #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
18 drmModeRes *resources;
24 drmModeModeInfo *mode;
25 drmModeEncoder *encoder;
27 unsigned int fb_id[2], current_fb_id;
34 struct kms_driver *kms;
40 connector_find_mode(struct connector *c)
42 drmModeConnector *connector;
45 /* First, find the connector & mode */
47 for (i = 0; i < resources->count_connectors; i++) {
48 connector = drmModeGetConnector(fd, resources->connectors[i]);
51 fprintf(stderr, "could not get connector %i: %s\n",
52 resources->connectors[i], strerror(errno));
53 drmModeFreeConnector(connector);
57 if (!connector->count_modes) {
58 drmModeFreeConnector(connector);
62 if (connector->connector_id != c->id) {
63 drmModeFreeConnector(connector);
67 for (j = 0; j < connector->count_modes; j++) {
68 c->mode = &connector->modes[j];
69 if (!strcmp(c->mode->name, c->mode_str))
73 /* Found it, break out */
77 drmModeFreeConnector(connector);
81 fprintf(stderr, "failed to find mode \"%s\"\n", c->mode_str);
85 /* Now get the encoder */
86 for (i = 0; i < resources->count_encoders; i++) {
87 c->encoder = drmModeGetEncoder(fd, resources->encoders[i]);
90 fprintf(stderr, "could not get encoder %i: %s\n",
91 resources->encoders[i], strerror(errno));
92 drmModeFreeEncoder(c->encoder);
96 if (c->encoder->encoder_id == connector->encoder_id)
99 drmModeFreeEncoder(c->encoder);
103 c->crtc = c->encoder->crtc_id;
106 static struct kms_bo *
107 allocate_buffer(struct kms_driver *kms,
108 int width, int height, unsigned *stride)
111 unsigned bo_attribs[] = {
114 KMS_BO_TYPE, KMS_BO_TYPE_SCANOUT_X8R8G8B8,
115 KMS_TERMINATE_PROP_LIST
119 bo_attribs[1] = width;
120 bo_attribs[3] = height;
122 ret = kms_bo_create(kms, bo_attribs, &bo);
124 fprintf(stderr, "failed to alloc buffer: %s\n",
129 ret = kms_bo_get_prop(bo, KMS_PITCH, stride);
131 fprintf(stderr, "failed to retreive buffer stride: %s\n",
141 create_grey_buffer(struct kms_driver *kms,
142 int width, int height, int *stride_out,
143 struct kms_bo **bo_out, int color)
150 bo = allocate_buffer(kms, width, height, &stride);
154 ret = kms_bo_map(bo, &virtual);
156 fprintf(stderr, "failed to map buffer: %s\n",
162 size = stride * height;
163 memset(virtual, color, size);
167 *stride_out = stride;
173 connector_find_plane(struct connector *c)
175 drmModePlaneRes *plane_resources;
180 plane_resources = drmModeGetPlaneResources(fd);
181 if (!plane_resources) {
182 fprintf(stderr, "drmModeGetPlaneResources failed: %s\n",
187 for (i = 0; i < plane_resources->count_planes; i++) {
188 ovr = drmModeGetPlane(fd, plane_resources->planes[i]);
190 fprintf(stderr, "drmModeGetPlane failed: %s\n",
195 if (ovr->possible_crtcs & (1<<i)) {
197 drmModeFreePlane(ovr);
200 drmModeFreePlane(ovr);
207 connector_find_plane2(struct connector *c, unsigned int *plane_id)
209 drmModePlaneRes *plane_resources;
213 plane_resources = drmModeGetPlaneResources(fd);
214 if (!plane_resources) {
215 fprintf(stderr, "drmModeGetPlaneResources failed: %s\n",
220 for (i = 0; i < plane_resources->count_planes; i++) {
223 ovr = drmModeGetPlane(fd, plane_resources->planes[i]);
225 fprintf(stderr, "drmModeGetPlane failed: %s\n",
230 if (ovr->possible_crtcs & (1 << 0))
231 plane_id[i] = ovr->plane_id;
232 drmModeFreePlane(ovr);
238 static struct fb_data *make_fb(int w, int h, int color)
240 struct fb_data *fb_data;
241 struct kms_driver *kms;
248 fb_data = malloc(sizeof(struct fb_data));
252 memset(fb_data, 0, sizeof(struct fb_data));
254 err = kms_create(fd, &kms);
256 fprintf(stderr, "failed to create kms driver: %s\n",
261 if (create_grey_buffer(kms, w, h, &stride, &bo, color))
264 kms_bo_get_prop(bo, KMS_HANDLE, &handle);
265 err = drmModeAddFB(fd, w, h, 32, 32, stride, handle, &fb_id);
267 fprintf(stderr, "failed to add fb: %s\n", strerror(errno));
271 fb_data->fb_id = fb_id;
282 static int exynos_plane_set_zpos(int fd, unsigned int plane_id, int zpos)
284 struct drm_exynos_plane_set_zpos zpos_req;
287 zpos_req.plane_id = plane_id;
288 zpos_req.zpos = zpos;
290 ret = ioctl(fd, DRM_IOCTL_EXYNOS_PLANE_SET_ZPOS, &zpos_req);
292 fprintf(stderr, "failed to set plane zpos: %s\n",
301 static void planetest_start(int nr, int start_plane, int crtc, int connector)
304 struct fb_data *fb_data[PLANE_NR];
305 unsigned int plane_id[PLANE_NR];
316 if (nr < 1 || nr > PLANE_NR) {
317 fprintf(stderr, "wrong plane count\n");
321 if (start_plane < 0 || start_plane > (nr -1) ) {
322 fprintf(stderr, "Wrong start plane\n");
326 connector_find_mode(&c);
328 if (c.mode == NULL) {
329 fprintf(stderr, "mode is NULL\n");
333 width = c.mode->hdisplay;
334 height = c.mode->vdisplay;
341 ret = connector_find_plane2(&c, plane_id);
345 for (i = start_plane; i < nr; i++) {
349 fb_data[i] = make_fb(width, height, 0x30 + 0x20 * i);
353 if (exynos_plane_set_zpos(fd, plane_id[i], i))
356 if (drmModeSetPlane(fd, plane_id[i], c.crtc, fb_data[i]->fb_id,
358 0, 0, width, height)) {
359 fprintf(stderr, "failed to enable plane: %s\n",
373 for (i = start_plane; i < nr; i++) {
375 kms_bo_destroy(&fb_data[i]->bo);
376 kms_destroy(&fb_data[i]->kms);
383 if (drmModeSetPlane(fd, plane_id[i], c.crtc,
384 0, 0, 0, /* bufferId, crtc_x, crtc_y */
385 0, 0, /* crtc_w, crtc_h */
386 0, 0, 0, 0 /* src_XXX */)) {
387 fprintf(stderr, "failed to enable plane: %s\n",
394 static void help(void)
396 printf("Usage: ./planetest [OPTION]\n"
398 " -s <connector_id>@<crtc_id>/<plane count>/<start_plane>\n"
401 "Default: connector 11, crtc 3, plane_count 5, start_plane 1\n");
405 static char optstr[] = "hs:";
407 int main(int argc, char **argv)
409 char *modules[] = { "exynos-drm" };
411 int i, connector_id, nr, start_plane;
414 // default option (LCD)
422 while ((opt = getopt(argc, argv, optstr)) != -1) {
425 if (sscanf(optarg, "%d@%d/%d/%d",
429 &start_plane) != 4) {
442 for (i = 0; i < ARRAY_SIZE(modules); i++) {
443 printf("trying to load module %s...", modules[i]);
444 fd = drmOpen(modules[i], NULL);
448 printf("success.\n");
453 resources = drmModeGetResources(fd);
455 fprintf(stderr, "drmModeGetResources failed: %s\n",
461 planetest_start(nr, start_plane, crtc_id, connector_id);
465 drmModeFreeResources(resources);