1ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul#include <stdio.h> 2ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul#include <stdlib.h> 3ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul#include <fcntl.h> 4ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul#include <unistd.h> 5ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul#include <string.h> 62e205d896cfea030d2ce7f577afeb3cc4db30ec4Sean Paul#include <getopt.h> 7ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul 8ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul#include <drm.h> 9ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul#include <drm_fourcc.h> 10ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul#include <errno.h> 11ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul#include <xf86drm.h> 12ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul#include <xf86drmMode.h> 13ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul 14ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul#include "bo.h" 15ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul#include "dev.h" 16ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul#include "modeset.h" 17ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul 182e205d896cfea030d2ce7f577afeb3cc4db30ec4Sean Paulstatic void show_usage(char *name) 192e205d896cfea030d2ce7f577afeb3cc4db30ec4Sean Paul{ 202e205d896cfea030d2ce7f577afeb3cc4db30ec4Sean Paul printf("Usage: %s [OPTION]\n", name); 212e205d896cfea030d2ce7f577afeb3cc4db30ec4Sean Paul printf(" -c, --card Index of dri card (ie: /dev/dri/cardN)\n"); 222e205d896cfea030d2ce7f577afeb3cc4db30ec4Sean Paul printf(" -r, --crtc Index of crtc to use for test\n"); 232e205d896cfea030d2ce7f577afeb3cc4db30ec4Sean Paul printf("\n\n"); 242e205d896cfea030d2ce7f577afeb3cc4db30ec4Sean Paul} 252e205d896cfea030d2ce7f577afeb3cc4db30ec4Sean Paul 262e205d896cfea030d2ce7f577afeb3cc4db30ec4Sean Paulvoid parse_arguments(int argc, char *argv[], int *card, int *crtc) 272e205d896cfea030d2ce7f577afeb3cc4db30ec4Sean Paul{ 282e205d896cfea030d2ce7f577afeb3cc4db30ec4Sean Paul static struct option options[] = { 292e205d896cfea030d2ce7f577afeb3cc4db30ec4Sean Paul { "card", required_argument, NULL, 'c' }, 302e205d896cfea030d2ce7f577afeb3cc4db30ec4Sean Paul { "crtc", required_argument, NULL, 'r' }, 312e205d896cfea030d2ce7f577afeb3cc4db30ec4Sean Paul { "help", no_argument, NULL, 'h' }, 322e205d896cfea030d2ce7f577afeb3cc4db30ec4Sean Paul }; 332e205d896cfea030d2ce7f577afeb3cc4db30ec4Sean Paul int option_index = 0; 342e205d896cfea030d2ce7f577afeb3cc4db30ec4Sean Paul int c; 352e205d896cfea030d2ce7f577afeb3cc4db30ec4Sean Paul 362e205d896cfea030d2ce7f577afeb3cc4db30ec4Sean Paul *card = -1; 372e205d896cfea030d2ce7f577afeb3cc4db30ec4Sean Paul *crtc = -1; 382e205d896cfea030d2ce7f577afeb3cc4db30ec4Sean Paul do { 392e205d896cfea030d2ce7f577afeb3cc4db30ec4Sean Paul c = getopt_long(argc, argv, "c:r:h", options, &option_index); 402e205d896cfea030d2ce7f577afeb3cc4db30ec4Sean Paul switch (c) { 412e205d896cfea030d2ce7f577afeb3cc4db30ec4Sean Paul case 0: 422e205d896cfea030d2ce7f577afeb3cc4db30ec4Sean Paul case 'h': 432e205d896cfea030d2ce7f577afeb3cc4db30ec4Sean Paul show_usage(argv[0]); 442e205d896cfea030d2ce7f577afeb3cc4db30ec4Sean Paul exit(0); 452e205d896cfea030d2ce7f577afeb3cc4db30ec4Sean Paul case -1: 462e205d896cfea030d2ce7f577afeb3cc4db30ec4Sean Paul break; 472e205d896cfea030d2ce7f577afeb3cc4db30ec4Sean Paul case 'c': 482e205d896cfea030d2ce7f577afeb3cc4db30ec4Sean Paul if (optarg[0] < '0' || optarg[0] > '9') { 492e205d896cfea030d2ce7f577afeb3cc4db30ec4Sean Paul printf("Invalid card value '%s'!\n", optarg); 502e205d896cfea030d2ce7f577afeb3cc4db30ec4Sean Paul show_usage(argv[0]); 512e205d896cfea030d2ce7f577afeb3cc4db30ec4Sean Paul exit(-1); 522e205d896cfea030d2ce7f577afeb3cc4db30ec4Sean Paul } 532e205d896cfea030d2ce7f577afeb3cc4db30ec4Sean Paul *card = optarg[0] - '0'; 542e205d896cfea030d2ce7f577afeb3cc4db30ec4Sean Paul break; 552e205d896cfea030d2ce7f577afeb3cc4db30ec4Sean Paul case 'r': 562e205d896cfea030d2ce7f577afeb3cc4db30ec4Sean Paul if (optarg[0] < '0' || optarg[0] > '9') { 572e205d896cfea030d2ce7f577afeb3cc4db30ec4Sean Paul printf("Invalid crtc value '%s'!\n", optarg); 582e205d896cfea030d2ce7f577afeb3cc4db30ec4Sean Paul show_usage(argv[0]); 592e205d896cfea030d2ce7f577afeb3cc4db30ec4Sean Paul exit(-1); 602e205d896cfea030d2ce7f577afeb3cc4db30ec4Sean Paul } 612e205d896cfea030d2ce7f577afeb3cc4db30ec4Sean Paul *crtc = optarg[0] - '0'; 622e205d896cfea030d2ce7f577afeb3cc4db30ec4Sean Paul break; 632e205d896cfea030d2ce7f577afeb3cc4db30ec4Sean Paul } 642e205d896cfea030d2ce7f577afeb3cc4db30ec4Sean Paul } while (c != -1); 652e205d896cfea030d2ce7f577afeb3cc4db30ec4Sean Paul 662e205d896cfea030d2ce7f577afeb3cc4db30ec4Sean Paul if (*card < 0 || *crtc < 0) { 672e205d896cfea030d2ce7f577afeb3cc4db30ec4Sean Paul show_usage(argv[0]); 682e205d896cfea030d2ce7f577afeb3cc4db30ec4Sean Paul exit(-1); 692e205d896cfea030d2ce7f577afeb3cc4db30ec4Sean Paul } 702e205d896cfea030d2ce7f577afeb3cc4db30ec4Sean Paul} 712e205d896cfea030d2ce7f577afeb3cc4db30ec4Sean Paul 72ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paulstatic uint32_t get_prop_id(struct sp_dev *dev, 73ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul drmModeObjectPropertiesPtr props, const char *name) 74ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul{ 75ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul drmModePropertyPtr p; 76ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul uint32_t i, prop_id = 0; /* Property ID should always be > 0 */ 77ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul 78ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul for (i = 0; !prop_id && i < props->count_props; i++) { 79ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul p = drmModeGetProperty(dev->fd, props->props[i]); 80ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul if (!strcmp(p->name, name)) 81ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul prop_id = p->prop_id; 82ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul drmModeFreeProperty(p); 83ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul } 84ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul if (!prop_id) 85ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul printf("Could not find %s property\n", name); 86ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul return prop_id; 87ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul} 88ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul 89ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paulstatic int get_supported_format(struct sp_plane *plane, uint32_t *format) 90ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul{ 91ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul uint32_t i; 92ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul 93ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul for (i = 0; i < plane->plane->count_formats; i++) { 94ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul if (plane->plane->formats[i] == DRM_FORMAT_XRGB8888 || 95ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul plane->plane->formats[i] == DRM_FORMAT_ARGB8888 || 965ba2bf74d75d9753f9aec1e83798070e78918109Benjamin Gaignard plane->plane->formats[i] == DRM_FORMAT_RGBA8888 || 975ba2bf74d75d9753f9aec1e83798070e78918109Benjamin Gaignard plane->plane->formats[i] == DRM_FORMAT_NV12) { 98ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul *format = plane->plane->formats[i]; 99ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul return 0; 100ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul } 101ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul } 102ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul printf("No suitable formats found!\n"); 103ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul return -ENOENT; 104ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul} 105ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul 1062e205d896cfea030d2ce7f577afeb3cc4db30ec4Sean Paulstruct sp_dev *create_sp_dev(int card) 107ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul{ 108ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul struct sp_dev *dev; 109ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul int ret, fd, i, j; 110ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul drmModeRes *r = NULL; 111ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul drmModePlaneRes *pr = NULL; 1122e205d896cfea030d2ce7f577afeb3cc4db30ec4Sean Paul char card_path[256]; 1132e205d896cfea030d2ce7f577afeb3cc4db30ec4Sean Paul 1142e205d896cfea030d2ce7f577afeb3cc4db30ec4Sean Paul snprintf(card_path, sizeof(card_path), "/dev/dri/card%d", card); 115ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul 1162e205d896cfea030d2ce7f577afeb3cc4db30ec4Sean Paul fd = open(card_path, O_RDWR); 117ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul if (fd < 0) { 118ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul printf("failed to open card0\n"); 119ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul return NULL; 120ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul } 121ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul 122ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul dev = calloc(1, sizeof(*dev)); 123ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul if (!dev) { 124ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul printf("failed to allocate dev\n"); 125ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul return NULL; 126ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul } 127ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul 128ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul dev->fd = fd; 129085db961ef8c2b6d7c939fe1fda8152e40b23071Sean Paul 130ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul ret = drmSetClientCap(dev->fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1); 131ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul if (ret) { 132ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul printf("failed to set client cap\n"); 133ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul goto err; 134ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul } 135ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul 136085db961ef8c2b6d7c939fe1fda8152e40b23071Sean Paul ret = drmSetClientCap(dev->fd, DRM_CLIENT_CAP_ATOMIC, 1); 137085db961ef8c2b6d7c939fe1fda8152e40b23071Sean Paul if (ret) { 138085db961ef8c2b6d7c939fe1fda8152e40b23071Sean Paul printf("Failed to set atomic cap %d", ret); 139085db961ef8c2b6d7c939fe1fda8152e40b23071Sean Paul goto err; 140085db961ef8c2b6d7c939fe1fda8152e40b23071Sean Paul } 141085db961ef8c2b6d7c939fe1fda8152e40b23071Sean Paul 142ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul r = drmModeGetResources(dev->fd); 143ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul if (!r) { 144ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul printf("failed to get r\n"); 145ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul goto err; 146ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul } 147ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul 148ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul dev->num_connectors = r->count_connectors; 149085db961ef8c2b6d7c939fe1fda8152e40b23071Sean Paul dev->connectors = calloc(dev->num_connectors, 150085db961ef8c2b6d7c939fe1fda8152e40b23071Sean Paul sizeof(struct sp_connector)); 151ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul if (!dev->connectors) { 152ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul printf("failed to allocate connectors\n"); 153ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul goto err; 154ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul } 155ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul for (i = 0; i < dev->num_connectors; i++) { 156085db961ef8c2b6d7c939fe1fda8152e40b23071Sean Paul drmModeObjectPropertiesPtr props; 157085db961ef8c2b6d7c939fe1fda8152e40b23071Sean Paul dev->connectors[i].conn = drmModeGetConnector(dev->fd, 158ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul r->connectors[i]); 159085db961ef8c2b6d7c939fe1fda8152e40b23071Sean Paul if (!dev->connectors[i].conn) { 160ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul printf("failed to get connector %d\n", i); 161ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul goto err; 162ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul } 163085db961ef8c2b6d7c939fe1fda8152e40b23071Sean Paul 164085db961ef8c2b6d7c939fe1fda8152e40b23071Sean Paul props = drmModeObjectGetProperties(dev->fd, r->connectors[i], 165085db961ef8c2b6d7c939fe1fda8152e40b23071Sean Paul DRM_MODE_OBJECT_CONNECTOR); 166085db961ef8c2b6d7c939fe1fda8152e40b23071Sean Paul if (!props) { 167085db961ef8c2b6d7c939fe1fda8152e40b23071Sean Paul printf("failed to get connector properties\n"); 168085db961ef8c2b6d7c939fe1fda8152e40b23071Sean Paul goto err; 169085db961ef8c2b6d7c939fe1fda8152e40b23071Sean Paul } 170085db961ef8c2b6d7c939fe1fda8152e40b23071Sean Paul 171085db961ef8c2b6d7c939fe1fda8152e40b23071Sean Paul dev->connectors[i].crtc_id_pid = get_prop_id(dev, props, 172085db961ef8c2b6d7c939fe1fda8152e40b23071Sean Paul "CRTC_ID"); 173085db961ef8c2b6d7c939fe1fda8152e40b23071Sean Paul drmModeFreeObjectProperties(props); 174085db961ef8c2b6d7c939fe1fda8152e40b23071Sean Paul if (!dev->connectors[i].crtc_id_pid) 175085db961ef8c2b6d7c939fe1fda8152e40b23071Sean Paul goto err; 176ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul } 177ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul 178ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul dev->num_encoders = r->count_encoders; 179ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul dev->encoders = calloc(dev->num_encoders, sizeof(*dev->encoders)); 180ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul if (!dev->encoders) { 181ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul printf("failed to allocate encoders\n"); 182ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul goto err; 183ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul } 184ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul for (i = 0; i < dev->num_encoders; i++) { 185ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul dev->encoders[i] = drmModeGetEncoder(dev->fd, r->encoders[i]); 186ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul if (!dev->encoders[i]) { 187ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul printf("failed to get encoder %d\n", i); 188ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul goto err; 189ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul } 190ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul } 191ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul 192ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul dev->num_crtcs = r->count_crtcs; 193ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul dev->crtcs = calloc(dev->num_crtcs, sizeof(struct sp_crtc)); 194ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul if (!dev->crtcs) { 195ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul printf("failed to allocate crtcs\n"); 196ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul goto err; 197ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul } 198ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul for (i = 0; i < dev->num_crtcs; i++) { 199085db961ef8c2b6d7c939fe1fda8152e40b23071Sean Paul drmModeObjectPropertiesPtr props; 200085db961ef8c2b6d7c939fe1fda8152e40b23071Sean Paul 201ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul dev->crtcs[i].crtc = drmModeGetCrtc(dev->fd, r->crtcs[i]); 202ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul if (!dev->crtcs[i].crtc) { 203ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul printf("failed to get crtc %d\n", i); 204ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul goto err; 205ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul } 206ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul dev->crtcs[i].pipe = i; 207ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul dev->crtcs[i].num_planes = 0; 208085db961ef8c2b6d7c939fe1fda8152e40b23071Sean Paul 209085db961ef8c2b6d7c939fe1fda8152e40b23071Sean Paul props = drmModeObjectGetProperties(dev->fd, r->crtcs[i], 210085db961ef8c2b6d7c939fe1fda8152e40b23071Sean Paul DRM_MODE_OBJECT_CRTC); 211085db961ef8c2b6d7c939fe1fda8152e40b23071Sean Paul if (!props) { 212085db961ef8c2b6d7c939fe1fda8152e40b23071Sean Paul printf("failed to get crtc properties\n"); 213085db961ef8c2b6d7c939fe1fda8152e40b23071Sean Paul goto err; 214085db961ef8c2b6d7c939fe1fda8152e40b23071Sean Paul } 215085db961ef8c2b6d7c939fe1fda8152e40b23071Sean Paul 216085db961ef8c2b6d7c939fe1fda8152e40b23071Sean Paul dev->crtcs[i].mode_pid = get_prop_id(dev, props, "MODE_ID"); 2179d5cde03d9c5499e29a12541087f4dff31141e70Sean Paul dev->crtcs[i].active_pid = get_prop_id(dev, props, "ACTIVE"); 218085db961ef8c2b6d7c939fe1fda8152e40b23071Sean Paul drmModeFreeObjectProperties(props); 2199d5cde03d9c5499e29a12541087f4dff31141e70Sean Paul if (!dev->crtcs[i].mode_pid || !dev->crtcs[i].active_pid) 220085db961ef8c2b6d7c939fe1fda8152e40b23071Sean Paul goto err; 221ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul } 222ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul 223ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul pr = drmModeGetPlaneResources(dev->fd); 224ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul if (!pr) { 225ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul printf("failed to get plane resources\n"); 226ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul goto err; 227ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul } 228ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul dev->num_planes = pr->count_planes; 229ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul dev->planes = calloc(dev->num_planes, sizeof(struct sp_plane)); 230ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul for(i = 0; i < dev->num_planes; i++) { 231ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul drmModeObjectPropertiesPtr props; 232ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul struct sp_plane *plane = &dev->planes[i]; 233ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul 234ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul plane->dev = dev; 235ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul plane->plane = drmModeGetPlane(dev->fd, pr->planes[i]); 236ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul if (!plane->plane) { 237ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul printf("failed to get plane %d\n", i); 238ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul goto err; 239ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul } 240ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul plane->bo = NULL; 241ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul plane->in_use = 0; 242ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul 243ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul ret = get_supported_format(plane, &plane->format); 244ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul if (ret) { 245ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul printf("failed to get supported format: %d\n", ret); 246ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul goto err; 247ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul } 248ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul 249ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul for (j = 0; j < dev->num_crtcs; j++) { 250ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul if (plane->plane->possible_crtcs & (1 << j)) 251ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul dev->crtcs[j].num_planes++; 252ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul } 253ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul 254ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul props = drmModeObjectGetProperties(dev->fd, pr->planes[i], 255ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul DRM_MODE_OBJECT_PLANE); 256ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul if (!props) { 257ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul printf("failed to get plane properties\n"); 258ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul goto err; 259ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul } 260ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul plane->crtc_pid = get_prop_id(dev, props, "CRTC_ID"); 261ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul if (!plane->crtc_pid) { 262ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul drmModeFreeObjectProperties(props); 263ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul goto err; 264ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul } 265ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul plane->fb_pid = get_prop_id(dev, props, "FB_ID"); 266ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul if (!plane->fb_pid) { 267ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul drmModeFreeObjectProperties(props); 268ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul goto err; 269ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul } 270ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul plane->crtc_x_pid = get_prop_id(dev, props, "CRTC_X"); 271ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul if (!plane->crtc_x_pid) { 272ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul drmModeFreeObjectProperties(props); 273ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul goto err; 274ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul } 275ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul plane->crtc_y_pid = get_prop_id(dev, props, "CRTC_Y"); 276ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul if (!plane->crtc_y_pid) { 277ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul drmModeFreeObjectProperties(props); 278ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul goto err; 279ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul } 280ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul plane->crtc_w_pid = get_prop_id(dev, props, "CRTC_W"); 281ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul if (!plane->crtc_w_pid) { 282ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul drmModeFreeObjectProperties(props); 283ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul goto err; 284ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul } 285ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul plane->crtc_h_pid = get_prop_id(dev, props, "CRTC_H"); 286ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul if (!plane->crtc_h_pid) { 287ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul drmModeFreeObjectProperties(props); 288ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul goto err; 289ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul } 290ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul plane->src_x_pid = get_prop_id(dev, props, "SRC_X"); 291ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul if (!plane->src_x_pid) { 292ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul drmModeFreeObjectProperties(props); 293ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul goto err; 294ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul } 295ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul plane->src_y_pid = get_prop_id(dev, props, "SRC_Y"); 296ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul if (!plane->src_y_pid) { 297ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul drmModeFreeObjectProperties(props); 298ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul goto err; 299ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul } 300ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul plane->src_w_pid = get_prop_id(dev, props, "SRC_W"); 301ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul if (!plane->src_w_pid) { 302ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul drmModeFreeObjectProperties(props); 303ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul goto err; 304ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul } 305ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul plane->src_h_pid = get_prop_id(dev, props, "SRC_H"); 306ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul if (!plane->src_h_pid) { 307ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul drmModeFreeObjectProperties(props); 308ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul goto err; 309ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul } 310ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul drmModeFreeObjectProperties(props); 311ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul } 312ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul 313ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul if (pr) 314ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul drmModeFreePlaneResources(pr); 315ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul if (r) 316ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul drmModeFreeResources(r); 317ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul 318ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul return dev; 319ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paulerr: 320ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul if (pr) 321ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul drmModeFreePlaneResources(pr); 322ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul if (r) 323ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul drmModeFreeResources(r); 324ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul destroy_sp_dev(dev); 325ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul return NULL; 326ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul} 327ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul 328ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paulvoid destroy_sp_dev(struct sp_dev *dev) 329ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul{ 330ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul int i; 331ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul 332ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul if (dev->planes) { 333ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul for (i = 0; i< dev->num_planes; i++) { 334ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul if (dev->planes[i].in_use) 335ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul put_sp_plane(&dev->planes[i]); 336ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul if (dev->planes[i].plane) 337ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul drmModeFreePlane(dev->planes[i].plane); 338ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul if (dev->planes[i].bo) 339ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul free_sp_bo(dev->planes[i].bo); 340ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul } 341ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul free(dev->planes); 342ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul } 343ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul if (dev->crtcs) { 344ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul for (i = 0; i< dev->num_crtcs; i++) { 345ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul if (dev->crtcs[i].crtc) 346ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul drmModeFreeCrtc(dev->crtcs[i].crtc); 347ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul } 348ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul free(dev->crtcs); 349ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul } 350ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul if (dev->encoders) { 351ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul for (i = 0; i< dev->num_encoders; i++) { 352ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul if (dev->encoders[i]) 353ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul drmModeFreeEncoder(dev->encoders[i]); 354ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul } 355ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul free(dev->encoders); 356ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul } 357ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul if (dev->connectors) { 358ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul for (i = 0; i< dev->num_connectors; i++) { 359085db961ef8c2b6d7c939fe1fda8152e40b23071Sean Paul if (dev->connectors[i].conn) 360085db961ef8c2b6d7c939fe1fda8152e40b23071Sean Paul drmModeFreeConnector(dev->connectors[i].conn); 361ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul } 362ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul free(dev->connectors); 363ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul } 364ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul 365ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul close(dev->fd); 366ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul free(dev); 367ef6e8f241ab759e3f707c33d5c700baadae5badbSean Paul} 368