modetest.c revision ebd7904877d08525beb5039e4ea2f5b6c0a7c23f
1731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes/* 2731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * DRM based mode setting test program 3731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * Copyright 2008 Tungsten Graphics 4731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * Jakob Bornecrantz <jakob@tungstengraphics.com> 5731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * Copyright 2008 Intel Corporation 6731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * Jesse Barnes <jesse.barnes@intel.com> 7731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * 8731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * Permission is hereby granted, free of charge, to any person obtaining a 9731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * copy of this software and associated documentation files (the "Software"), 10731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * to deal in the Software without restriction, including without limitation 11731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * the rights to use, copy, modify, merge, publish, distribute, sublicense, 12731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * and/or sell copies of the Software, and to permit persons to whom the 13731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * Software is furnished to do so, subject to the following conditions: 14731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * 15731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * The above copyright notice and this permission notice shall be included in 16731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * all copies or substantial portions of the Software. 17731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * 18731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 23731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 24731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * IN THE SOFTWARE. 25731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes */ 26731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 27731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes/* 28731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * This fairly simple test program dumps output in a similar format to the 29731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * "xrandr" tool everyone knows & loves. It's necessarily slightly different 30731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * since the kernel separates outputs into encoder and connector structures, 31731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * each with their own unique ID. The program also allows test testing of the 32731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * memory management and mode setting APIs by allowing the user to specify a 33731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * connector and mode to use for mode setting. If all works as expected, a 34731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * blue background should be painted on the monitor attached to the specified 35731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * connector after the selected mode is set. 36731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * 37731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * TODO: use cairo to write the mode info on the selected output once 38731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * the mode has been programmed, along with possible test patterns. 39731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes */ 407a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg#include "config.h" 417a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg 42731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes#include <assert.h> 43731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes#include <stdio.h> 44731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes#include <stdlib.h> 45731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes#include <stdint.h> 46d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni#include <inttypes.h> 47731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes#include <unistd.h> 48731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes#include <string.h> 49731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes#include <errno.h> 501e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg#include <sys/poll.h> 51e4a519635f75bde38aeb5b09f2ff4efbf73453e9Matthew W. S. Bell#include <sys/time.h> 52731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 53731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes#include "xf86drm.h" 54731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes#include "xf86drmMode.h" 55d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark#include "drm_fourcc.h" 568fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke#include "libkms.h" 57731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 58db004badef9315ba6a5f165d0974dd5afd5a6178Laurent Pinchart#include "buffers.h" 597a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg 60731cd5526e5c732d51307b26e784f454a724a699Jesse BarnesdrmModeRes *resources; 61731cd5526e5c732d51307b26e784f454a724a699Jesse Barnesint fd, modes; 62731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 63731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) 64731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 65731cd5526e5c732d51307b26e784f454a724a699Jesse Barnesstruct type_name { 66731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes int type; 67731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes char *name; 68731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes}; 69731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 70731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes#define type_name_fn(res) \ 71731cd5526e5c732d51307b26e784f454a724a699Jesse Barneschar * res##_str(int type) { \ 729b44fbd393b8db571badae41881f490145404ae0Paulo Zanoni unsigned int i; \ 73731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes for (i = 0; i < ARRAY_SIZE(res##_names); i++) { \ 74731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes if (res##_names[i].type == type) \ 75731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes return res##_names[i].name; \ 76731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes } \ 77731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes return "(invalid)"; \ 78731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes} 79731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 80731cd5526e5c732d51307b26e784f454a724a699Jesse Barnesstruct type_name encoder_type_names[] = { 81731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes { DRM_MODE_ENCODER_NONE, "none" }, 82731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes { DRM_MODE_ENCODER_DAC, "DAC" }, 83731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes { DRM_MODE_ENCODER_TMDS, "TMDS" }, 84731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes { DRM_MODE_ENCODER_LVDS, "LVDS" }, 85731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes { DRM_MODE_ENCODER_TVDAC, "TVDAC" }, 86731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes}; 87731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 88731cd5526e5c732d51307b26e784f454a724a699Jesse Barnestype_name_fn(encoder_type) 89731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 90731cd5526e5c732d51307b26e784f454a724a699Jesse Barnesstruct type_name connector_status_names[] = { 91731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes { DRM_MODE_CONNECTED, "connected" }, 92731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes { DRM_MODE_DISCONNECTED, "disconnected" }, 93731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes { DRM_MODE_UNKNOWNCONNECTION, "unknown" }, 94731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes}; 95731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 96731cd5526e5c732d51307b26e784f454a724a699Jesse Barnestype_name_fn(connector_status) 97731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 98731cd5526e5c732d51307b26e784f454a724a699Jesse Barnesstruct type_name connector_type_names[] = { 99731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes { DRM_MODE_CONNECTOR_Unknown, "unknown" }, 100731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes { DRM_MODE_CONNECTOR_VGA, "VGA" }, 101731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes { DRM_MODE_CONNECTOR_DVII, "DVI-I" }, 102731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes { DRM_MODE_CONNECTOR_DVID, "DVI-D" }, 103731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes { DRM_MODE_CONNECTOR_DVIA, "DVI-A" }, 104731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes { DRM_MODE_CONNECTOR_Composite, "composite" }, 105731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes { DRM_MODE_CONNECTOR_SVIDEO, "s-video" }, 106731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes { DRM_MODE_CONNECTOR_LVDS, "LVDS" }, 107731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes { DRM_MODE_CONNECTOR_Component, "component" }, 108731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes { DRM_MODE_CONNECTOR_9PinDIN, "9-pin DIN" }, 109731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes { DRM_MODE_CONNECTOR_DisplayPort, "displayport" }, 110731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes { DRM_MODE_CONNECTOR_HDMIA, "HDMI-A" }, 111731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes { DRM_MODE_CONNECTOR_HDMIB, "HDMI-B" }, 112b8abe6139e5c6779ee87d983346f0f65bf67462eJesse Barnes { DRM_MODE_CONNECTOR_TV, "TV" }, 113b8abe6139e5c6779ee87d983346f0f65bf67462eJesse Barnes { DRM_MODE_CONNECTOR_eDP, "embedded displayport" }, 114731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes}; 115731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 116731cd5526e5c732d51307b26e784f454a724a699Jesse Barnestype_name_fn(connector_type) 117731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 118c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg#define bit_name_fn(res) \ 119c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsbergchar * res##_str(int type) { \ 120c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg int i; \ 121c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg const char *sep = ""; \ 122c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg for (i = 0; i < ARRAY_SIZE(res##_names); i++) { \ 123c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg if (type & (1 << i)) { \ 124c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg printf("%s%s", sep, res##_names[i]); \ 125c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg sep = ", "; \ 126c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg } \ 127c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg } \ 128c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg} 129c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg 130c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsbergstatic const char *mode_type_names[] = { 131c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg "builtin", 132c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg "clock_c", 133c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg "crtc_c", 134c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg "preferred", 135c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg "default", 136c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg "userdef", 137c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg "driver", 138c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg}; 139c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg 140c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsbergbit_name_fn(mode_type) 141c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg 142c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsbergstatic const char *mode_flag_names[] = { 143c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg "phsync", 144c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg "nhsync", 145c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg "pvsync", 146c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg "nvsync", 147c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg "interlace", 148c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg "dblscan", 149c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg "csync", 150c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg "pcsync", 151c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg "ncsync", 152c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg "hskew", 153c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg "bcast", 154c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg "pixmux", 155c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg "dblclk", 156c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg "clkdiv2" 157c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg}; 158c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg 159c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsbergbit_name_fn(mode_flag) 160c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg 161731cd5526e5c732d51307b26e784f454a724a699Jesse Barnesvoid dump_encoders(void) 162731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes{ 163731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes drmModeEncoder *encoder; 164731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes int i; 165731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 166731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes printf("Encoders:\n"); 167731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes printf("id\tcrtc\ttype\tpossible crtcs\tpossible clones\t\n"); 168731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes for (i = 0; i < resources->count_encoders; i++) { 169731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes encoder = drmModeGetEncoder(fd, resources->encoders[i]); 170731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 171731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes if (!encoder) { 172731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes fprintf(stderr, "could not get encoder %i: %s\n", 173731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes resources->encoders[i], strerror(errno)); 174731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes continue; 175731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes } 176731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes printf("%d\t%d\t%s\t0x%08x\t0x%08x\n", 177731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes encoder->encoder_id, 178731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes encoder->crtc_id, 179731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes encoder_type_str(encoder->encoder_type), 180731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes encoder->possible_crtcs, 181731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes encoder->possible_clones); 182731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes drmModeFreeEncoder(encoder); 183731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes } 1840243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg printf("\n"); 1850243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg} 1860243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg 1879fc85b4084b69fefab3dbdf1f6cf97ccb47c963aKristian Høgsbergvoid dump_mode(drmModeModeInfo *mode) 1880243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg{ 189c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg printf(" %s %d %d %d %d %d %d %d %d %d", 1900243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg mode->name, 191694ef59532253727176ed0ce9077ae3ec41dd457Marcin Kościelnicki mode->vrefresh, 1920243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg mode->hdisplay, 1930243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg mode->hsync_start, 1940243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg mode->hsync_end, 1950243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg mode->htotal, 1960243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg mode->vdisplay, 1970243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg mode->vsync_start, 1980243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg mode->vsync_end, 1990243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg mode->vtotal); 200c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg 201c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg printf(" flags: "); 202c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg mode_flag_str(mode->flags); 203c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg printf("; type: "); 204c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg mode_type_str(mode->type); 205c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg printf("\n"); 206731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes} 207731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 2089fc85b4084b69fefab3dbdf1f6cf97ccb47c963aKristian Høgsbergstatic void 209d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanonidump_blob(uint32_t blob_id) 210d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni{ 211d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni uint32_t i; 212d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni unsigned char *blob_data; 213d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni drmModePropertyBlobPtr blob; 214d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni 215d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni blob = drmModeGetPropertyBlob(fd, blob_id); 216d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni if (!blob) 217d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni return; 218d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni 219d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni blob_data = blob->data; 220d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni 221d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni for (i = 0; i < blob->length; i++) { 222d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni if (i % 16 == 0) 223d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni printf("\n\t\t\t"); 224d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni printf("%.2hhx", blob_data[i]); 225d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni } 226d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni printf("\n"); 227d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni 228d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni drmModeFreePropertyBlob(blob); 229d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni} 230d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni 231d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanonistatic void 232d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanonidump_prop(uint32_t prop_id, uint64_t value) 2339fc85b4084b69fefab3dbdf1f6cf97ccb47c963aKristian Høgsberg{ 2349fc85b4084b69fefab3dbdf1f6cf97ccb47c963aKristian Høgsberg int i; 235d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni drmModePropertyPtr prop; 236d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni 237d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni prop = drmModeGetProperty(fd, prop_id); 238d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni 239d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni printf("\t%d", prop_id); 240d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni if (!prop) { 241d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni printf("\n"); 242d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni return; 243d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni } 244d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni 245d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni printf(" %s:\n", prop->name); 246d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni 247d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni printf("\t\tflags:"); 248d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni if (prop->flags & DRM_MODE_PROP_PENDING) 249d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni printf(" pending"); 250d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni if (prop->flags & DRM_MODE_PROP_RANGE) 251d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni printf(" range"); 252d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni if (prop->flags & DRM_MODE_PROP_IMMUTABLE) 253d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni printf(" immutable"); 254d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni if (prop->flags & DRM_MODE_PROP_ENUM) 255d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni printf(" enum"); 2566df9e6af4b34ef2c5278941ee78de029e4040485Rob Clark if (prop->flags & DRM_MODE_PROP_BITMASK) 2576df9e6af4b34ef2c5278941ee78de029e4040485Rob Clark printf(" bitmask"); 258d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni if (prop->flags & DRM_MODE_PROP_BLOB) 259d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni printf(" blob"); 260d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni printf("\n"); 2619fc85b4084b69fefab3dbdf1f6cf97ccb47c963aKristian Høgsberg 262d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni if (prop->flags & DRM_MODE_PROP_RANGE) { 263d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni printf("\t\tvalues:"); 264d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni for (i = 0; i < prop->count_values; i++) 265d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni printf(" %"PRIu64, prop->values[i]); 266d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni printf("\n"); 2679fc85b4084b69fefab3dbdf1f6cf97ccb47c963aKristian Høgsberg } 268d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni 269d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni if (prop->flags & DRM_MODE_PROP_ENUM) { 270d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni printf("\t\tenums:"); 271d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni for (i = 0; i < prop->count_enums; i++) 272d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni printf(" %s=%llu", prop->enums[i].name, 273d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni prop->enums[i].value); 274d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni printf("\n"); 2756df9e6af4b34ef2c5278941ee78de029e4040485Rob Clark } else if (prop->flags & DRM_MODE_PROP_BITMASK) { 2766df9e6af4b34ef2c5278941ee78de029e4040485Rob Clark printf("\t\tvalues:"); 2776df9e6af4b34ef2c5278941ee78de029e4040485Rob Clark for (i = 0; i < prop->count_enums; i++) 2786df9e6af4b34ef2c5278941ee78de029e4040485Rob Clark printf(" %s=0x%llx", prop->enums[i].name, 2796df9e6af4b34ef2c5278941ee78de029e4040485Rob Clark (1LL << prop->enums[i].value)); 2806df9e6af4b34ef2c5278941ee78de029e4040485Rob Clark printf("\n"); 281d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni } else { 282d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni assert(prop->count_enums == 0); 283d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni } 284d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni 285d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni if (prop->flags & DRM_MODE_PROP_BLOB) { 286d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni printf("\t\tblobs:\n"); 287d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni for (i = 0; i < prop->count_blobs; i++) 288d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni dump_blob(prop->blob_ids[i]); 289d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni printf("\n"); 290d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni } else { 291d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni assert(prop->count_blobs == 0); 292d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni } 293d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni 294d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni printf("\t\tvalue:"); 295d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni if (prop->flags & DRM_MODE_PROP_BLOB) 296d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni dump_blob(value); 297d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni else 298d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni printf(" %"PRIu64"\n", value); 299d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni 300d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni drmModeFreeProperty(prop); 3019fc85b4084b69fefab3dbdf1f6cf97ccb47c963aKristian Høgsberg} 3029fc85b4084b69fefab3dbdf1f6cf97ccb47c963aKristian Høgsberg 303731cd5526e5c732d51307b26e784f454a724a699Jesse Barnesvoid dump_connectors(void) 304731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes{ 305731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes drmModeConnector *connector; 306731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes int i, j; 307731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 308731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes printf("Connectors:\n"); 3091e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg printf("id\tencoder\tstatus\t\ttype\tsize (mm)\tmodes\tencoders\n"); 310731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes for (i = 0; i < resources->count_connectors; i++) { 311731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes connector = drmModeGetConnector(fd, resources->connectors[i]); 312731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 313731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes if (!connector) { 314731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes fprintf(stderr, "could not get connector %i: %s\n", 315731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes resources->connectors[i], strerror(errno)); 316731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes continue; 317731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes } 318731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 3191e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg printf("%d\t%d\t%s\t%s\t%dx%d\t\t%d\t", 320731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes connector->connector_id, 321731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes connector->encoder_id, 322731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes connector_status_str(connector->connection), 323731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes connector_type_str(connector->connector_type), 324731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes connector->mmWidth, connector->mmHeight, 325731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes connector->count_modes); 326731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 3271e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg for (j = 0; j < connector->count_encoders; j++) 3281e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg printf("%s%d", j > 0 ? ", " : "", connector->encoders[j]); 3291e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg printf("\n"); 3301e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg 331a10bcaaf668ab16233df10c2742dcb497e17d588Paulo Zanoni if (connector->count_modes) { 332a10bcaaf668ab16233df10c2742dcb497e17d588Paulo Zanoni printf(" modes:\n"); 333d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni printf("\tname refresh (Hz) hdisp hss hse htot vdisp " 334a10bcaaf668ab16233df10c2742dcb497e17d588Paulo Zanoni "vss vse vtot)\n"); 335a10bcaaf668ab16233df10c2742dcb497e17d588Paulo Zanoni for (j = 0; j < connector->count_modes; j++) 336a10bcaaf668ab16233df10c2742dcb497e17d588Paulo Zanoni dump_mode(&connector->modes[j]); 337a10bcaaf668ab16233df10c2742dcb497e17d588Paulo Zanoni 338a10bcaaf668ab16233df10c2742dcb497e17d588Paulo Zanoni printf(" props:\n"); 339d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni for (j = 0; j < connector->count_props; j++) 340d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni dump_prop(connector->props[j], 341d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni connector->prop_values[j]); 342a10bcaaf668ab16233df10c2742dcb497e17d588Paulo Zanoni } 3439a37455b35d746d694760cfe8850a8bf856d73c9Marcin Kościelnicki 3449a37455b35d746d694760cfe8850a8bf856d73c9Marcin Kościelnicki drmModeFreeConnector(connector); 345731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes } 3460243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg printf("\n"); 347731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes} 348731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 349731cd5526e5c732d51307b26e784f454a724a699Jesse Barnesvoid dump_crtcs(void) 350731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes{ 351731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes drmModeCrtc *crtc; 35286dece4cf2f7180b854fbd318fa1a57793f0deacPaulo Zanoni drmModeObjectPropertiesPtr props; 353731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes int i; 35486dece4cf2f7180b854fbd318fa1a57793f0deacPaulo Zanoni uint32_t j; 355731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 3560243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg printf("CRTCs:\n"); 3570243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg printf("id\tfb\tpos\tsize\n"); 358731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes for (i = 0; i < resources->count_crtcs; i++) { 359731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes crtc = drmModeGetCrtc(fd, resources->crtcs[i]); 360731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 361731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes if (!crtc) { 362731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes fprintf(stderr, "could not get crtc %i: %s\n", 363731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes resources->crtcs[i], strerror(errno)); 364731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes continue; 365731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes } 3660243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg printf("%d\t%d\t(%d,%d)\t(%dx%d)\n", 3670243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg crtc->crtc_id, 3680243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg crtc->buffer_id, 3690243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg crtc->x, crtc->y, 3700243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg crtc->width, crtc->height); 3710243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg dump_mode(&crtc->mode); 3720243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg 37386dece4cf2f7180b854fbd318fa1a57793f0deacPaulo Zanoni printf(" props:\n"); 37486dece4cf2f7180b854fbd318fa1a57793f0deacPaulo Zanoni props = drmModeObjectGetProperties(fd, crtc->crtc_id, 37586dece4cf2f7180b854fbd318fa1a57793f0deacPaulo Zanoni DRM_MODE_OBJECT_CRTC); 37686dece4cf2f7180b854fbd318fa1a57793f0deacPaulo Zanoni if (props) { 37786dece4cf2f7180b854fbd318fa1a57793f0deacPaulo Zanoni for (j = 0; j < props->count_props; j++) 37886dece4cf2f7180b854fbd318fa1a57793f0deacPaulo Zanoni dump_prop(props->props[j], 37986dece4cf2f7180b854fbd318fa1a57793f0deacPaulo Zanoni props->prop_values[j]); 38086dece4cf2f7180b854fbd318fa1a57793f0deacPaulo Zanoni drmModeFreeObjectProperties(props); 38186dece4cf2f7180b854fbd318fa1a57793f0deacPaulo Zanoni } else { 38286dece4cf2f7180b854fbd318fa1a57793f0deacPaulo Zanoni printf("\tcould not get crtc properties: %s\n", 38386dece4cf2f7180b854fbd318fa1a57793f0deacPaulo Zanoni strerror(errno)); 38486dece4cf2f7180b854fbd318fa1a57793f0deacPaulo Zanoni } 38586dece4cf2f7180b854fbd318fa1a57793f0deacPaulo Zanoni 386731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes drmModeFreeCrtc(crtc); 387731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes } 3880243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg printf("\n"); 389731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes} 390731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 391731cd5526e5c732d51307b26e784f454a724a699Jesse Barnesvoid dump_framebuffers(void) 392731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes{ 393731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes drmModeFB *fb; 394731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes int i; 395731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 3960243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg printf("Frame buffers:\n"); 3970243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg printf("id\tsize\tpitch\n"); 398731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes for (i = 0; i < resources->count_fbs; i++) { 399731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes fb = drmModeGetFB(fd, resources->fbs[i]); 400731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 401731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes if (!fb) { 402731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes fprintf(stderr, "could not get fb %i: %s\n", 403731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes resources->fbs[i], strerror(errno)); 404731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes continue; 405731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes } 406e4a519635f75bde38aeb5b09f2ff4efbf73453e9Matthew W. S. Bell printf("%u\t(%ux%u)\t%u\n", 4070243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg fb->fb_id, 408e4a519635f75bde38aeb5b09f2ff4efbf73453e9Matthew W. S. Bell fb->width, fb->height, 409e4a519635f75bde38aeb5b09f2ff4efbf73453e9Matthew W. S. Bell fb->pitch); 4100243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg 411731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes drmModeFreeFB(fb); 412731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes } 4130243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg printf("\n"); 414731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes} 415731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 416d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clarkstatic void dump_planes(void) 417d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark{ 41825e4cb4659c62817aae2ca3b83f2d4f598d6474bRob Clark drmModeObjectPropertiesPtr props; 419d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark drmModePlaneRes *plane_resources; 420d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark drmModePlane *ovr; 4219b44fbd393b8db571badae41881f490145404ae0Paulo Zanoni unsigned int i, j; 422d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark 423d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark plane_resources = drmModeGetPlaneResources(fd); 424d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark if (!plane_resources) { 425d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark fprintf(stderr, "drmModeGetPlaneResources failed: %s\n", 426d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark strerror(errno)); 427d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark return; 428d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark } 429d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark 430d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark printf("Planes:\n"); 431d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark printf("id\tcrtc\tfb\tCRTC x,y\tx,y\tgamma size\n"); 432d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark for (i = 0; i < plane_resources->count_planes; i++) { 433d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark ovr = drmModeGetPlane(fd, plane_resources->planes[i]); 434d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark if (!ovr) { 435d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark fprintf(stderr, "drmModeGetPlane failed: %s\n", 436d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark strerror(errno)); 437d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark continue; 438d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark } 439d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark 440d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark printf("%d\t%d\t%d\t%d,%d\t\t%d,%d\t%d\n", 441d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark ovr->plane_id, ovr->crtc_id, ovr->fb_id, 442d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark ovr->crtc_x, ovr->crtc_y, ovr->x, ovr->y, 443d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark ovr->gamma_size); 444d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark 445d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark if (!ovr->count_formats) 446d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark continue; 447d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark 448d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark printf(" formats:"); 449d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark for (j = 0; j < ovr->count_formats; j++) 450d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark printf(" %4.4s", (char *)&ovr->formats[j]); 451d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark printf("\n"); 452d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark 45325e4cb4659c62817aae2ca3b83f2d4f598d6474bRob Clark printf(" props:\n"); 45425e4cb4659c62817aae2ca3b83f2d4f598d6474bRob Clark props = drmModeObjectGetProperties(fd, ovr->plane_id, 45525e4cb4659c62817aae2ca3b83f2d4f598d6474bRob Clark DRM_MODE_OBJECT_PLANE); 45625e4cb4659c62817aae2ca3b83f2d4f598d6474bRob Clark if (props) { 45725e4cb4659c62817aae2ca3b83f2d4f598d6474bRob Clark for (j = 0; j < props->count_props; j++) 45825e4cb4659c62817aae2ca3b83f2d4f598d6474bRob Clark dump_prop(props->props[j], 45925e4cb4659c62817aae2ca3b83f2d4f598d6474bRob Clark props->prop_values[j]); 46025e4cb4659c62817aae2ca3b83f2d4f598d6474bRob Clark drmModeFreeObjectProperties(props); 46125e4cb4659c62817aae2ca3b83f2d4f598d6474bRob Clark } else { 46225e4cb4659c62817aae2ca3b83f2d4f598d6474bRob Clark printf("\tcould not get plane properties: %s\n", 46325e4cb4659c62817aae2ca3b83f2d4f598d6474bRob Clark strerror(errno)); 46425e4cb4659c62817aae2ca3b83f2d4f598d6474bRob Clark } 46525e4cb4659c62817aae2ca3b83f2d4f598d6474bRob Clark 466d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark drmModeFreePlane(ovr); 467d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark } 468d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark printf("\n"); 469d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark 4700ef7644fe5161d3b50f9550ebbf8cbbabd51706fPaulo Zanoni drmModeFreePlaneResources(plane_resources); 471d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark return; 472d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark} 473d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark 474a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart/* ----------------------------------------------------------------------------- 475a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart * Connectors and planes 476a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart */ 477a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart 478731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes/* 479731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * Mode setting with the kernel interfaces is a bit of a chore. 480731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * First you have to find the connector in question and make sure the 481731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * requested mode is available. 482731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * Then you need to find the encoder attached to that connector so you 483731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * can bind it with a free crtc. 484731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes */ 485669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsbergstruct connector { 486e4a519635f75bde38aeb5b09f2ff4efbf73453e9Matthew W. S. Bell uint32_t id; 487669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg char mode_str[64]; 488cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart char format_str[5]; 489cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart unsigned int fourcc; 4909fc85b4084b69fefab3dbdf1f6cf97ccb47c963aKristian Høgsberg drmModeModeInfo *mode; 491669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg drmModeEncoder *encoder; 4928b8803695b24d4cb4d041437a4709be06e59471bKristian Høgsberg int crtc; 493d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark int pipe; 4941e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg unsigned int fb_id[2], current_fb_id; 4951e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg struct timeval start; 4961e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg 4971e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg int swap_count; 498d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark}; 499d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark 500d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clarkstruct plane { 501d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark uint32_t con_id; /* the id of connector to bind to */ 502d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark uint32_t w, h; 503d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark unsigned int fb_id; 504b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark char format_str[5]; /* need to leave room for terminating \0 */ 5050375222c714e8b7ba55f12d5cb389383be1cf54dLaurent Pinchart unsigned int fourcc; 506d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark}; 507669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg 508669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsbergstatic void 509669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsbergconnector_find_mode(struct connector *c) 510731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes{ 511731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes drmModeConnector *connector; 512e4a519635f75bde38aeb5b09f2ff4efbf73453e9Matthew W. S. Bell int i, j; 513731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 514731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes /* First, find the connector & mode */ 515669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg c->mode = NULL; 516731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes for (i = 0; i < resources->count_connectors; i++) { 517731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes connector = drmModeGetConnector(fd, resources->connectors[i]); 518731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 519731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes if (!connector) { 520731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes fprintf(stderr, "could not get connector %i: %s\n", 521731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes resources->connectors[i], strerror(errno)); 522731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes drmModeFreeConnector(connector); 523731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes continue; 524731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes } 525731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 526731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes if (!connector->count_modes) { 527731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes drmModeFreeConnector(connector); 528731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes continue; 529731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes } 530731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 531669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg if (connector->connector_id != c->id) { 532731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes drmModeFreeConnector(connector); 533731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes continue; 534731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes } 535731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 536731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes for (j = 0; j < connector->count_modes; j++) { 537669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg c->mode = &connector->modes[j]; 538669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg if (!strcmp(c->mode->name, c->mode_str)) 539731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes break; 540731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes } 541731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 542731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes /* Found it, break out */ 543669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg if (c->mode) 544731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes break; 545731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 546731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes drmModeFreeConnector(connector); 547731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes } 548731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 549669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg if (!c->mode) { 550669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg fprintf(stderr, "failed to find mode \"%s\"\n", c->mode_str); 551731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes return; 552731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes } 553731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 554731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes /* Now get the encoder */ 555731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes for (i = 0; i < resources->count_encoders; i++) { 556669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg c->encoder = drmModeGetEncoder(fd, resources->encoders[i]); 557731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 558669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg if (!c->encoder) { 559731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes fprintf(stderr, "could not get encoder %i: %s\n", 560731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes resources->encoders[i], strerror(errno)); 561669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg drmModeFreeEncoder(c->encoder); 562731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes continue; 563731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes } 564731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 565669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg if (c->encoder->encoder_id == connector->encoder_id) 566731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes break; 567731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 568669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg drmModeFreeEncoder(c->encoder); 569669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg } 5708b8803695b24d4cb4d041437a4709be06e59471bKristian Høgsberg 5718b8803695b24d4cb4d041437a4709be06e59471bKristian Høgsberg if (c->crtc == -1) 5728b8803695b24d4cb4d041437a4709be06e59471bKristian Høgsberg c->crtc = c->encoder->crtc_id; 573d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark 574d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark /* and figure out which crtc index it is: */ 575d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark for (i = 0; i < resources->count_crtcs; i++) { 576d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark if (c->crtc == resources->crtcs[i]) { 577d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark c->pipe = i; 578d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark break; 579d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark } 580d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark } 581d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark 582669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg} 583669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg 5843fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart/* -------------------------------------------------------------------------- */ 5853fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart 5863fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchartvoid 5873fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchartpage_flip_handler(int fd, unsigned int frame, 5883fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart unsigned int sec, unsigned int usec, void *data) 5893fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart{ 5903fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart struct connector *c; 5913fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart unsigned int new_fb_id; 5923fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart struct timeval end; 5933fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart double t; 5943fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart 5953fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart c = data; 5963fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart if (c->current_fb_id == c->fb_id[0]) 5973fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart new_fb_id = c->fb_id[1]; 5983fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart else 5993fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart new_fb_id = c->fb_id[0]; 6003fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart 6013fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart drmModePageFlip(fd, c->crtc, new_fb_id, 6023fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart DRM_MODE_PAGE_FLIP_EVENT, c); 6033fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart c->current_fb_id = new_fb_id; 6043fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart c->swap_count++; 6053fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart if (c->swap_count == 60) { 6063fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart gettimeofday(&end, NULL); 6073fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart t = end.tv_sec + end.tv_usec * 1e-6 - 6083fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart (c->start.tv_sec + c->start.tv_usec * 1e-6); 6093fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart fprintf(stderr, "freq: %.02fHz\n", c->swap_count / t); 6103fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart c->swap_count = 0; 6113fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart c->start = end; 6123fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart } 6133fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart} 6143fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart 615d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clarkstatic int 616d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clarkset_plane(struct kms_driver *kms, struct connector *c, struct plane *p) 617d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark{ 618d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark drmModePlaneRes *plane_resources; 619d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark drmModePlane *ovr; 620d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark uint32_t handles[4], pitches[4], offsets[4] = {0}; /* we only use [0] */ 621d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark uint32_t plane_id = 0; 622d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark struct kms_bo *plane_bo; 6230375222c714e8b7ba55f12d5cb389383be1cf54dLaurent Pinchart uint32_t plane_flags = 0; 6249b44fbd393b8db571badae41881f490145404ae0Paulo Zanoni int ret, crtc_x, crtc_y, crtc_w, crtc_h; 6259b44fbd393b8db571badae41881f490145404ae0Paulo Zanoni unsigned int i; 626d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark 627d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark /* find an unused plane which can be connected to our crtc */ 628d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark plane_resources = drmModeGetPlaneResources(fd); 629d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark if (!plane_resources) { 630d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark fprintf(stderr, "drmModeGetPlaneResources failed: %s\n", 631d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark strerror(errno)); 632d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark return -1; 633d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark } 634d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark 635d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark for (i = 0; i < plane_resources->count_planes && !plane_id; i++) { 636d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark ovr = drmModeGetPlane(fd, plane_resources->planes[i]); 637d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark if (!ovr) { 638d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark fprintf(stderr, "drmModeGetPlane failed: %s\n", 639d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark strerror(errno)); 640d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark return -1; 641d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark } 642d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark 643d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark if ((ovr->possible_crtcs & (1 << c->pipe)) && !ovr->crtc_id) 644d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark plane_id = ovr->plane_id; 645d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark 646d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark drmModeFreePlane(ovr); 647d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark } 648d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark 649b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark fprintf(stderr, "testing %dx%d@%s overlay plane\n", 650b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark p->w, p->h, p->format_str); 651b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark 652d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark if (!plane_id) { 653d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark fprintf(stderr, "failed to find plane!\n"); 654d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark return -1; 655d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark } 656d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark 6570375222c714e8b7ba55f12d5cb389383be1cf54dLaurent Pinchart plane_bo = create_test_buffer(kms, p->fourcc, p->w, p->h, handles, 658a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart pitches, offsets, PATTERN_TILES); 6593fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart if (plane_bo == NULL) 6603fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart return -1; 661d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark 662d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark /* just use single plane format for now.. */ 6630375222c714e8b7ba55f12d5cb389383be1cf54dLaurent Pinchart if (drmModeAddFB2(fd, p->w, p->h, p->fourcc, 664d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark handles, pitches, offsets, &p->fb_id, plane_flags)) { 665d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark fprintf(stderr, "failed to add fb: %s\n", strerror(errno)); 666d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark return -1; 667d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark } 668d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark 669d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark /* ok, boring.. but for now put in middle of screen: */ 670d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark crtc_x = c->mode->hdisplay / 3; 671d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark crtc_y = c->mode->vdisplay / 3; 672d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark crtc_w = crtc_x; 673d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark crtc_h = crtc_y; 674d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark 675d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark /* note src coords (last 4 args) are in Q16 format */ 676d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark if (drmModeSetPlane(fd, plane_id, c->crtc, p->fb_id, 677d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark plane_flags, crtc_x, crtc_y, crtc_w, crtc_h, 678d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark 0, 0, p->w << 16, p->h << 16)) { 679d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark fprintf(stderr, "failed to enable plane: %s\n", 680d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark strerror(errno)); 681d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark return -1; 682d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark } 683d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark 684d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark return 0; 685d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark} 686d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark 6877a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsbergstatic void 688d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clarkset_mode(struct connector *c, int count, struct plane *p, int plane_count, 689d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark int page_flip) 6907a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg{ 6918fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke struct kms_driver *kms; 6928fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke struct kms_bo *bo, *other_bo; 6931e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg unsigned int fb_id, other_fb_id; 6943fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart int i, j, ret, width, height, x; 6953fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart uint32_t handles[4], pitches[4], offsets[4] = {0}; /* we only use [0] */ 6961e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg drmEventContext evctx; 6977a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg 6987a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg width = 0; 6997a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg height = 0; 7007a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg for (i = 0; i < count; i++) { 7017a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg connector_find_mode(&c[i]); 7027a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg if (c[i].mode == NULL) 7037a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg continue; 7047a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg width += c[i].mode->hdisplay; 7057a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg if (height < c[i].mode->vdisplay) 7067a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg height = c[i].mode->vdisplay; 7077a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg } 7087a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg 7098fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke ret = kms_create(fd, &kms); 7108fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke if (ret) { 7118fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke fprintf(stderr, "failed to create kms driver: %s\n", 7128fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke strerror(-ret)); 7137a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg return; 7147a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg } 7157a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg 716cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart bo = create_test_buffer(kms, c->fourcc, width, height, handles, 717a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart pitches, offsets, PATTERN_SMPTE); 7183fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart if (bo == NULL) 7197a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg return; 720731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 721cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart ret = drmModeAddFB2(fd, width, height, c->fourcc, 722cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart handles, pitches, offsets, &fb_id, 0); 723731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes if (ret) { 724680b9c4fa3dfb329bd74ec08c17cfc876ea2fc5bJakob Bornecrantz fprintf(stderr, "failed to add fb (%ux%u): %s\n", 725680b9c4fa3dfb329bd74ec08c17cfc876ea2fc5bJakob Bornecrantz width, height, strerror(errno)); 726731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes return; 727731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes } 728731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 729669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg x = 0; 730669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg for (i = 0; i < count; i++) { 731669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg if (c[i].mode == NULL) 732669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg continue; 7338b8803695b24d4cb4d041437a4709be06e59471bKristian Høgsberg 734cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart printf("setting mode %s@%s on connector %d, crtc %d\n", 735cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart c[i].mode_str, c[i].format_str, c[i].id, c[i].crtc); 7368b8803695b24d4cb4d041437a4709be06e59471bKristian Høgsberg 7378b8803695b24d4cb4d041437a4709be06e59471bKristian Høgsberg ret = drmModeSetCrtc(fd, c[i].crtc, fb_id, x, 0, 738669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg &c[i].id, 1, c[i].mode); 739d23146f3f0ad14c8ad482a4832cae859c8d646f2Jakob Bornecrantz 740d23146f3f0ad14c8ad482a4832cae859c8d646f2Jakob Bornecrantz /* XXX: Actually check if this is needed */ 741d23146f3f0ad14c8ad482a4832cae859c8d646f2Jakob Bornecrantz drmModeDirtyFB(fd, fb_id, NULL, 0); 742d23146f3f0ad14c8ad482a4832cae859c8d646f2Jakob Bornecrantz 743669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg x += c[i].mode->hdisplay; 744669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg 745669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg if (ret) { 746669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg fprintf(stderr, "failed to set mode: %s\n", strerror(errno)); 747669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg return; 748669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg } 749d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark 750d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark /* if we have a plane/overlay to show, set that up now: */ 751d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark for (j = 0; j < plane_count; j++) 752d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark if (p[j].con_id == c[i].id) 753d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark if (set_plane(kms, &c[i], &p[j])) 754d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark return; 755731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes } 7561e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg 7571e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg if (!page_flip) 7581e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg return; 7598fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke 760cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart other_bo = create_test_buffer(kms, c->fourcc, width, height, handles, 761a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart pitches, offsets, PATTERN_PLAIN); 7623fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart if (other_bo == NULL) 7631e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg return; 7641e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg 765cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart ret = drmModeAddFB2(fd, width, height, c->fourcc, handles, pitches, offsets, 766cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart &other_fb_id, 0); 7671e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg if (ret) { 7681e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg fprintf(stderr, "failed to add fb: %s\n", strerror(errno)); 7691e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg return; 7701e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg } 7711e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg 7721e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg for (i = 0; i < count; i++) { 7731e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg if (c[i].mode == NULL) 7741e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg continue; 7751e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg 7763c8adda6e1e6b0471b3d70a63d795622bbeb1580Jakob Bornecrantz ret = drmModePageFlip(fd, c[i].crtc, other_fb_id, 7773c8adda6e1e6b0471b3d70a63d795622bbeb1580Jakob Bornecrantz DRM_MODE_PAGE_FLIP_EVENT, &c[i]); 7783c8adda6e1e6b0471b3d70a63d795622bbeb1580Jakob Bornecrantz if (ret) { 7793c8adda6e1e6b0471b3d70a63d795622bbeb1580Jakob Bornecrantz fprintf(stderr, "failed to page flip: %s\n", strerror(errno)); 7803c8adda6e1e6b0471b3d70a63d795622bbeb1580Jakob Bornecrantz return; 7813c8adda6e1e6b0471b3d70a63d795622bbeb1580Jakob Bornecrantz } 7821e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg gettimeofday(&c[i].start, NULL); 7831e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg c[i].swap_count = 0; 784e4a519635f75bde38aeb5b09f2ff4efbf73453e9Matthew W. S. Bell c[i].fb_id[0] = fb_id; 785e4a519635f75bde38aeb5b09f2ff4efbf73453e9Matthew W. S. Bell c[i].fb_id[1] = other_fb_id; 786a697fb6acad7992c3d23bb6a663663694782eb7bBenjamin Franzke c[i].current_fb_id = other_fb_id; 7871e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg } 7881e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg 7891e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg memset(&evctx, 0, sizeof evctx); 7901e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg evctx.version = DRM_EVENT_CONTEXT_VERSION; 7911e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg evctx.vblank_handler = NULL; 7926f1eba0548cd6a96e91a4e8be7b91ba6a936eb98Jesse Barnes evctx.page_flip_handler = page_flip_handler; 7931e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg 7941e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg while (1) { 795e6b3f906cef26e1efb8625f5dd4e460b4c79a771Jesse Barnes#if 0 7961e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg struct pollfd pfd[2]; 7971e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg 7981e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg pfd[0].fd = 0; 7991e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg pfd[0].events = POLLIN; 8001e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg pfd[1].fd = fd; 8011e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg pfd[1].events = POLLIN; 8021e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg 8031e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg if (poll(pfd, 2, -1) < 0) { 8041e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg fprintf(stderr, "poll error\n"); 8051e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg break; 8061e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg } 8071e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg 8081e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg if (pfd[0].revents) 8091e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg break; 810e6b3f906cef26e1efb8625f5dd4e460b4c79a771Jesse Barnes#else 811e6b3f906cef26e1efb8625f5dd4e460b4c79a771Jesse Barnes struct timeval timeout = { .tv_sec = 3, .tv_usec = 0 }; 812e6b3f906cef26e1efb8625f5dd4e460b4c79a771Jesse Barnes fd_set fds; 813e6b3f906cef26e1efb8625f5dd4e460b4c79a771Jesse Barnes int ret; 814e6b3f906cef26e1efb8625f5dd4e460b4c79a771Jesse Barnes 815e6b3f906cef26e1efb8625f5dd4e460b4c79a771Jesse Barnes FD_ZERO(&fds); 816e6b3f906cef26e1efb8625f5dd4e460b4c79a771Jesse Barnes FD_SET(0, &fds); 817e6b3f906cef26e1efb8625f5dd4e460b4c79a771Jesse Barnes FD_SET(fd, &fds); 818e6b3f906cef26e1efb8625f5dd4e460b4c79a771Jesse Barnes ret = select(fd + 1, &fds, NULL, NULL, &timeout); 819e6b3f906cef26e1efb8625f5dd4e460b4c79a771Jesse Barnes 820e6b3f906cef26e1efb8625f5dd4e460b4c79a771Jesse Barnes if (ret <= 0) { 821e6b3f906cef26e1efb8625f5dd4e460b4c79a771Jesse Barnes fprintf(stderr, "select timed out or error (ret %d)\n", 822e6b3f906cef26e1efb8625f5dd4e460b4c79a771Jesse Barnes ret); 823e6b3f906cef26e1efb8625f5dd4e460b4c79a771Jesse Barnes continue; 824e6b3f906cef26e1efb8625f5dd4e460b4c79a771Jesse Barnes } else if (FD_ISSET(0, &fds)) { 825e6b3f906cef26e1efb8625f5dd4e460b4c79a771Jesse Barnes break; 826e6b3f906cef26e1efb8625f5dd4e460b4c79a771Jesse Barnes } 827e6b3f906cef26e1efb8625f5dd4e460b4c79a771Jesse Barnes#endif 8281e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg 8291e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg drmHandleEvent(fd, &evctx); 8301e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg } 8318fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke 8328fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke kms_bo_destroy(&bo); 8338fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke kms_bo_destroy(&other_bo); 8348fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke kms_destroy(&kms); 835731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes} 836731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 837731cd5526e5c732d51307b26e784f454a724a699Jesse Barnesextern char *optarg; 838731cd5526e5c732d51307b26e784f454a724a699Jesse Barnesextern int optind, opterr, optopt; 839d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clarkstatic char optstr[] = "ecpmfs:P:v"; 840731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 841cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart#define min(a, b) ((a) < (b) ? (a) : (b)) 842cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart 8430375222c714e8b7ba55f12d5cb389383be1cf54dLaurent Pinchartstatic int parse_connector(struct connector *c, const char *arg) 8440375222c714e8b7ba55f12d5cb389383be1cf54dLaurent Pinchart{ 845cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart unsigned int len; 846cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart const char *p; 847cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart char *endp; 848cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart 8490375222c714e8b7ba55f12d5cb389383be1cf54dLaurent Pinchart c->crtc = -1; 850cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart strcpy(c->format_str, "XR24"); 851cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart 852cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart c->id = strtoul(arg, &endp, 10); 853cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart if (*endp == '@') { 854cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart arg = endp + 1; 855cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart c->crtc = strtoul(arg, &endp, 10); 856cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart } 857cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart if (*endp != ':') 858cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart return -1; 8590375222c714e8b7ba55f12d5cb389383be1cf54dLaurent Pinchart 860cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart arg = endp + 1; 8610375222c714e8b7ba55f12d5cb389383be1cf54dLaurent Pinchart 862cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart p = strchrnul(arg, '@'); 863cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart len = min(sizeof c->mode_str - 1, p - arg); 864cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart strncpy(c->mode_str, arg, len); 865cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart c->mode_str[len] = '\0'; 8660375222c714e8b7ba55f12d5cb389383be1cf54dLaurent Pinchart 867cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart if (*p == '@') { 868cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart strncpy(c->format_str, p + 1, 4); 869cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart c->format_str[4] = '\0'; 870ebd7904877d08525beb5039e4ea2f5b6c0a7c23fRob Clark } 871cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart 872ebd7904877d08525beb5039e4ea2f5b6c0a7c23fRob Clark c->fourcc = format_fourcc(c->format_str); 873ebd7904877d08525beb5039e4ea2f5b6c0a7c23fRob Clark if (c->fourcc == 0) { 874ebd7904877d08525beb5039e4ea2f5b6c0a7c23fRob Clark fprintf(stderr, "unknown format %s\n", c->format_str); 875ebd7904877d08525beb5039e4ea2f5b6c0a7c23fRob Clark return -1; 876cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart } 877cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart 878cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart return 0; 8790375222c714e8b7ba55f12d5cb389383be1cf54dLaurent Pinchart} 8800375222c714e8b7ba55f12d5cb389383be1cf54dLaurent Pinchart 8810375222c714e8b7ba55f12d5cb389383be1cf54dLaurent Pinchartstatic int parse_plane(struct plane *p, const char *arg) 8820375222c714e8b7ba55f12d5cb389383be1cf54dLaurent Pinchart{ 8830375222c714e8b7ba55f12d5cb389383be1cf54dLaurent Pinchart strcpy(p->format_str, "XR24"); 8840375222c714e8b7ba55f12d5cb389383be1cf54dLaurent Pinchart 8850375222c714e8b7ba55f12d5cb389383be1cf54dLaurent Pinchart if (sscanf(arg, "%d:%dx%d@%4s", &p->con_id, &p->w, &p->h, &p->format_str) != 4 && 8860375222c714e8b7ba55f12d5cb389383be1cf54dLaurent Pinchart sscanf(arg, "%d:%dx%d", &p->con_id, &p->w, &p->h) != 3) 8870375222c714e8b7ba55f12d5cb389383be1cf54dLaurent Pinchart return -1; 8880375222c714e8b7ba55f12d5cb389383be1cf54dLaurent Pinchart 8890375222c714e8b7ba55f12d5cb389383be1cf54dLaurent Pinchart p->fourcc = format_fourcc(p->format_str); 8900375222c714e8b7ba55f12d5cb389383be1cf54dLaurent Pinchart if (p->fourcc == 0) { 8910375222c714e8b7ba55f12d5cb389383be1cf54dLaurent Pinchart fprintf(stderr, "unknown format %s\n", p->format_str); 8920375222c714e8b7ba55f12d5cb389383be1cf54dLaurent Pinchart return -1; 8930375222c714e8b7ba55f12d5cb389383be1cf54dLaurent Pinchart } 8940375222c714e8b7ba55f12d5cb389383be1cf54dLaurent Pinchart 8950375222c714e8b7ba55f12d5cb389383be1cf54dLaurent Pinchart return 0; 8960375222c714e8b7ba55f12d5cb389383be1cf54dLaurent Pinchart} 8970375222c714e8b7ba55f12d5cb389383be1cf54dLaurent Pinchart 898731cd5526e5c732d51307b26e784f454a724a699Jesse Barnesvoid usage(char *name) 899731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes{ 900731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes fprintf(stderr, "usage: %s [-ecpmf]\n", name); 901731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes fprintf(stderr, "\t-e\tlist encoders\n"); 902731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes fprintf(stderr, "\t-c\tlist connectors\n"); 903d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark fprintf(stderr, "\t-p\tlist CRTCs and planes (pipes)\n"); 904731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes fprintf(stderr, "\t-m\tlist modes\n"); 905731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes fprintf(stderr, "\t-f\tlist framebuffers\n"); 9061e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg fprintf(stderr, "\t-v\ttest vsynced page flipping\n"); 907cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart fprintf(stderr, "\t-s <connector_id>[@<crtc_id>]:<mode>[@<format>]\tset a mode\n"); 908cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart fprintf(stderr, "\t-P <connector_id>:<w>x<h>[@<format>]\tset a plane\n"); 909731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes fprintf(stderr, "\n\tDefault is to dump all info.\n"); 910731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes exit(0); 911731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes} 912731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 913731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes#define dump_resource(res) if (res) dump_##res() 914731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 9159b44fbd393b8db571badae41881f490145404ae0Paulo Zanonistatic int page_flipping_supported(void) 91659d97e7d6807d9cd076d4e8374aca1d9e8027a6bKristian Høgsberg{ 9178fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke /*FIXME: generic ioctl needed? */ 9188fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke return 1; 9198fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke#if 0 92059d97e7d6807d9cd076d4e8374aca1d9e8027a6bKristian Høgsberg int ret, value; 92159d97e7d6807d9cd076d4e8374aca1d9e8027a6bKristian Høgsberg struct drm_i915_getparam gp; 92259d97e7d6807d9cd076d4e8374aca1d9e8027a6bKristian Høgsberg 92359d97e7d6807d9cd076d4e8374aca1d9e8027a6bKristian Høgsberg gp.param = I915_PARAM_HAS_PAGEFLIPPING; 92459d97e7d6807d9cd076d4e8374aca1d9e8027a6bKristian Høgsberg gp.value = &value; 92559d97e7d6807d9cd076d4e8374aca1d9e8027a6bKristian Høgsberg 92659d97e7d6807d9cd076d4e8374aca1d9e8027a6bKristian Høgsberg ret = drmCommandWriteRead(fd, DRM_I915_GETPARAM, &gp, sizeof(gp)); 92759d97e7d6807d9cd076d4e8374aca1d9e8027a6bKristian Høgsberg if (ret) { 92859d97e7d6807d9cd076d4e8374aca1d9e8027a6bKristian Høgsberg fprintf(stderr, "drm_i915_getparam: %m\n"); 92959d97e7d6807d9cd076d4e8374aca1d9e8027a6bKristian Høgsberg return 0; 93059d97e7d6807d9cd076d4e8374aca1d9e8027a6bKristian Høgsberg } 93159d97e7d6807d9cd076d4e8374aca1d9e8027a6bKristian Høgsberg 932e4a519635f75bde38aeb5b09f2ff4efbf73453e9Matthew W. S. Bell return *gp.value; 9338fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke#endif 93459d97e7d6807d9cd076d4e8374aca1d9e8027a6bKristian Høgsberg} 93559d97e7d6807d9cd076d4e8374aca1d9e8027a6bKristian Høgsberg 936731cd5526e5c732d51307b26e784f454a724a699Jesse Barnesint main(int argc, char **argv) 937731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes{ 938731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes int c; 939d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark int encoders = 0, connectors = 0, crtcs = 0, planes = 0, framebuffers = 0; 9401e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg int test_vsync = 0; 941e07b650662ea0529d99741691c47856ef1034c9cInki Dae char *modules[] = { "i915", "radeon", "nouveau", "vmwgfx", "omapdrm", "exynos" }; 9429b44fbd393b8db571badae41881f490145404ae0Paulo Zanoni unsigned int i; 9439b44fbd393b8db571badae41881f490145404ae0Paulo Zanoni int count = 0, plane_count = 0; 944669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg struct connector con_args[2]; 945b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark struct plane plane_args[2] = {0}; 946669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg 947731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes opterr = 0; 948731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes while ((c = getopt(argc, argv, optstr)) != -1) { 949731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes switch (c) { 950731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes case 'e': 951731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes encoders = 1; 952731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes break; 953731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes case 'c': 954731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes connectors = 1; 955731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes break; 956731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes case 'p': 957731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes crtcs = 1; 958d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark planes = 1; 959731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes break; 960731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes case 'm': 961731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes modes = 1; 962731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes break; 963731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes case 'f': 964731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes framebuffers = 1; 965731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes break; 9661e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg case 'v': 9671e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg test_vsync = 1; 9681e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg break; 969731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes case 's': 9700375222c714e8b7ba55f12d5cb389383be1cf54dLaurent Pinchart if (parse_connector(&con_args[count], optarg) < 0) 971669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg usage(argv[0]); 972669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg count++; 973731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes break; 974d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark case 'P': 9750375222c714e8b7ba55f12d5cb389383be1cf54dLaurent Pinchart if (parse_plane(&plane_args[plane_count], optarg) < 0) 976d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark usage(argv[0]); 977d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark plane_count++; 978d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark break; 979731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes default: 980731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes usage(argv[0]); 981731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes break; 982731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes } 983731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes } 984731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 985731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes if (argc == 1) 986d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark encoders = connectors = crtcs = planes = modes = framebuffers = 1; 987731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 988731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes for (i = 0; i < ARRAY_SIZE(modules); i++) { 989731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes printf("trying to load module %s...", modules[i]); 990731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes fd = drmOpen(modules[i], NULL); 991731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes if (fd < 0) { 992731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes printf("failed.\n"); 993731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes } else { 994731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes printf("success.\n"); 995731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes break; 996731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes } 997731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes } 998731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 9999b44fbd393b8db571badae41881f490145404ae0Paulo Zanoni if (test_vsync && !page_flipping_supported()) { 100059d97e7d6807d9cd076d4e8374aca1d9e8027a6bKristian Høgsberg fprintf(stderr, "page flipping not supported by drm.\n"); 100159d97e7d6807d9cd076d4e8374aca1d9e8027a6bKristian Høgsberg return -1; 100259d97e7d6807d9cd076d4e8374aca1d9e8027a6bKristian Høgsberg } 100359d97e7d6807d9cd076d4e8374aca1d9e8027a6bKristian Høgsberg 1004731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes if (i == ARRAY_SIZE(modules)) { 1005731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes fprintf(stderr, "failed to load any modules, aborting.\n"); 1006731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes return -1; 1007731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes } 1008731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 1009731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes resources = drmModeGetResources(fd); 1010731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes if (!resources) { 1011731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes fprintf(stderr, "drmModeGetResources failed: %s\n", 1012731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes strerror(errno)); 1013731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes drmClose(fd); 1014731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes return 1; 1015731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes } 1016731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 1017731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes dump_resource(encoders); 1018731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes dump_resource(connectors); 1019731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes dump_resource(crtcs); 1020d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark dump_resource(planes); 1021731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes dump_resource(framebuffers); 1022731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 1023669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg if (count > 0) { 1024d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark set_mode(con_args, count, plane_args, plane_count, test_vsync); 10252c113a1b159f57ab94b54316ece49c677cfe04ceKristian Høgsberg getchar(); 1026731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes } 1027731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 1028731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes drmModeFreeResources(resources); 1029731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 1030731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes return 0; 1031731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes} 1032