modetest.c revision 8e56579b203a11c718c5e3da6fdb03b4f9b9fe56
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 } \ 1286fa2b29d226306870eebe93afb2106ca7d79569bTobias Klausmann return NULL; \ 129c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg} 130c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg 131c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsbergstatic const char *mode_type_names[] = { 132c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg "builtin", 133c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg "clock_c", 134c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg "crtc_c", 135c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg "preferred", 136c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg "default", 137c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg "userdef", 138c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg "driver", 139c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg}; 140c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg 141c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsbergbit_name_fn(mode_type) 142c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg 143c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsbergstatic const char *mode_flag_names[] = { 144c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg "phsync", 145c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg "nhsync", 146c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg "pvsync", 147c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg "nvsync", 148c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg "interlace", 149c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg "dblscan", 150c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg "csync", 151c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg "pcsync", 152c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg "ncsync", 153c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg "hskew", 154c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg "bcast", 155c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg "pixmux", 156c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg "dblclk", 157c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg "clkdiv2" 158c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg}; 159c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg 160c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsbergbit_name_fn(mode_flag) 161c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg 162731cd5526e5c732d51307b26e784f454a724a699Jesse Barnesvoid dump_encoders(void) 163731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes{ 164731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes drmModeEncoder *encoder; 165731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes int i; 166731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 167731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes printf("Encoders:\n"); 168731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes printf("id\tcrtc\ttype\tpossible crtcs\tpossible clones\t\n"); 169731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes for (i = 0; i < resources->count_encoders; i++) { 170731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes encoder = drmModeGetEncoder(fd, resources->encoders[i]); 171731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 172731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes if (!encoder) { 173731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes fprintf(stderr, "could not get encoder %i: %s\n", 174731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes resources->encoders[i], strerror(errno)); 175731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes continue; 176731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes } 177731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes printf("%d\t%d\t%s\t0x%08x\t0x%08x\n", 178731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes encoder->encoder_id, 179731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes encoder->crtc_id, 180731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes encoder_type_str(encoder->encoder_type), 181731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes encoder->possible_crtcs, 182731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes encoder->possible_clones); 183731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes drmModeFreeEncoder(encoder); 184731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes } 1850243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg printf("\n"); 1860243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg} 1870243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg 1889fc85b4084b69fefab3dbdf1f6cf97ccb47c963aKristian Høgsbergvoid dump_mode(drmModeModeInfo *mode) 1890243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg{ 190c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg printf(" %s %d %d %d %d %d %d %d %d %d", 1910243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg mode->name, 192694ef59532253727176ed0ce9077ae3ec41dd457Marcin Kościelnicki mode->vrefresh, 1930243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg mode->hdisplay, 1940243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg mode->hsync_start, 1950243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg mode->hsync_end, 1960243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg mode->htotal, 1970243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg mode->vdisplay, 1980243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg mode->vsync_start, 1990243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg mode->vsync_end, 2000243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg mode->vtotal); 201c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg 202c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg printf(" flags: "); 203c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg mode_flag_str(mode->flags); 204c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg printf("; type: "); 205c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg mode_type_str(mode->type); 206c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg printf("\n"); 207731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes} 208731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 2099fc85b4084b69fefab3dbdf1f6cf97ccb47c963aKristian Høgsbergstatic void 210d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanonidump_blob(uint32_t blob_id) 211d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni{ 212d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni uint32_t i; 213d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni unsigned char *blob_data; 214d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni drmModePropertyBlobPtr blob; 215d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni 216d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni blob = drmModeGetPropertyBlob(fd, blob_id); 217d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni if (!blob) 218d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni return; 219d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni 220d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni blob_data = blob->data; 221d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni 222d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni for (i = 0; i < blob->length; i++) { 223d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni if (i % 16 == 0) 224d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni printf("\n\t\t\t"); 225d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni printf("%.2hhx", blob_data[i]); 226d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni } 227d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni printf("\n"); 228d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni 229d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni drmModeFreePropertyBlob(blob); 230d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni} 231d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni 232d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanonistatic void 233d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanonidump_prop(uint32_t prop_id, uint64_t value) 2349fc85b4084b69fefab3dbdf1f6cf97ccb47c963aKristian Høgsberg{ 2359fc85b4084b69fefab3dbdf1f6cf97ccb47c963aKristian Høgsberg int i; 236d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni drmModePropertyPtr prop; 237d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni 238d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni prop = drmModeGetProperty(fd, prop_id); 239d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni 240d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni printf("\t%d", prop_id); 241d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni if (!prop) { 242d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni printf("\n"); 243d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni return; 244d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni } 245d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni 246d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni printf(" %s:\n", prop->name); 247d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni 248d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni printf("\t\tflags:"); 249d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni if (prop->flags & DRM_MODE_PROP_PENDING) 250d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni printf(" pending"); 251d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni if (prop->flags & DRM_MODE_PROP_RANGE) 252d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni printf(" range"); 253d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni if (prop->flags & DRM_MODE_PROP_IMMUTABLE) 254d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni printf(" immutable"); 255d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni if (prop->flags & DRM_MODE_PROP_ENUM) 256d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni printf(" enum"); 2576df9e6af4b34ef2c5278941ee78de029e4040485Rob Clark if (prop->flags & DRM_MODE_PROP_BITMASK) 2586df9e6af4b34ef2c5278941ee78de029e4040485Rob Clark printf(" bitmask"); 259d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni if (prop->flags & DRM_MODE_PROP_BLOB) 260d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni printf(" blob"); 261d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni printf("\n"); 2629fc85b4084b69fefab3dbdf1f6cf97ccb47c963aKristian Høgsberg 263d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni if (prop->flags & DRM_MODE_PROP_RANGE) { 264d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni printf("\t\tvalues:"); 265d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni for (i = 0; i < prop->count_values; i++) 266d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni printf(" %"PRIu64, prop->values[i]); 267d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni printf("\n"); 2689fc85b4084b69fefab3dbdf1f6cf97ccb47c963aKristian Høgsberg } 269d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni 270d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni if (prop->flags & DRM_MODE_PROP_ENUM) { 271d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni printf("\t\tenums:"); 272d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni for (i = 0; i < prop->count_enums; i++) 273d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni printf(" %s=%llu", prop->enums[i].name, 274d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni prop->enums[i].value); 275d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni printf("\n"); 2766df9e6af4b34ef2c5278941ee78de029e4040485Rob Clark } else if (prop->flags & DRM_MODE_PROP_BITMASK) { 2776df9e6af4b34ef2c5278941ee78de029e4040485Rob Clark printf("\t\tvalues:"); 2786df9e6af4b34ef2c5278941ee78de029e4040485Rob Clark for (i = 0; i < prop->count_enums; i++) 2796df9e6af4b34ef2c5278941ee78de029e4040485Rob Clark printf(" %s=0x%llx", prop->enums[i].name, 2806df9e6af4b34ef2c5278941ee78de029e4040485Rob Clark (1LL << prop->enums[i].value)); 2816df9e6af4b34ef2c5278941ee78de029e4040485Rob Clark printf("\n"); 282d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni } else { 283d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni assert(prop->count_enums == 0); 284d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni } 285d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni 286d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni if (prop->flags & DRM_MODE_PROP_BLOB) { 287d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni printf("\t\tblobs:\n"); 288d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni for (i = 0; i < prop->count_blobs; i++) 289d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni dump_blob(prop->blob_ids[i]); 290d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni printf("\n"); 291d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni } else { 292d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni assert(prop->count_blobs == 0); 293d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni } 294d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni 295d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni printf("\t\tvalue:"); 296d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni if (prop->flags & DRM_MODE_PROP_BLOB) 297d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni dump_blob(value); 298d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni else 299d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni printf(" %"PRIu64"\n", value); 300d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni 301d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni drmModeFreeProperty(prop); 3029fc85b4084b69fefab3dbdf1f6cf97ccb47c963aKristian Høgsberg} 3039fc85b4084b69fefab3dbdf1f6cf97ccb47c963aKristian Høgsberg 304731cd5526e5c732d51307b26e784f454a724a699Jesse Barnesvoid dump_connectors(void) 305731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes{ 306731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes drmModeConnector *connector; 307731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes int i, j; 308731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 309731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes printf("Connectors:\n"); 3101e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg printf("id\tencoder\tstatus\t\ttype\tsize (mm)\tmodes\tencoders\n"); 311731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes for (i = 0; i < resources->count_connectors; i++) { 312731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes connector = drmModeGetConnector(fd, resources->connectors[i]); 313731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 314731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes if (!connector) { 315731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes fprintf(stderr, "could not get connector %i: %s\n", 316731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes resources->connectors[i], strerror(errno)); 317731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes continue; 318731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes } 319731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 3201e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg printf("%d\t%d\t%s\t%s\t%dx%d\t\t%d\t", 321731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes connector->connector_id, 322731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes connector->encoder_id, 323731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes connector_status_str(connector->connection), 324731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes connector_type_str(connector->connector_type), 325731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes connector->mmWidth, connector->mmHeight, 326731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes connector->count_modes); 327731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 3281e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg for (j = 0; j < connector->count_encoders; j++) 3291e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg printf("%s%d", j > 0 ? ", " : "", connector->encoders[j]); 3301e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg printf("\n"); 3311e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg 332a10bcaaf668ab16233df10c2742dcb497e17d588Paulo Zanoni if (connector->count_modes) { 333a10bcaaf668ab16233df10c2742dcb497e17d588Paulo Zanoni printf(" modes:\n"); 334d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni printf("\tname refresh (Hz) hdisp hss hse htot vdisp " 335a10bcaaf668ab16233df10c2742dcb497e17d588Paulo Zanoni "vss vse vtot)\n"); 336a10bcaaf668ab16233df10c2742dcb497e17d588Paulo Zanoni for (j = 0; j < connector->count_modes; j++) 337a10bcaaf668ab16233df10c2742dcb497e17d588Paulo Zanoni dump_mode(&connector->modes[j]); 338a10bcaaf668ab16233df10c2742dcb497e17d588Paulo Zanoni 339a10bcaaf668ab16233df10c2742dcb497e17d588Paulo Zanoni printf(" props:\n"); 340d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni for (j = 0; j < connector->count_props; j++) 341d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni dump_prop(connector->props[j], 342d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni connector->prop_values[j]); 343a10bcaaf668ab16233df10c2742dcb497e17d588Paulo Zanoni } 3449a37455b35d746d694760cfe8850a8bf856d73c9Marcin Kościelnicki 3459a37455b35d746d694760cfe8850a8bf856d73c9Marcin Kościelnicki drmModeFreeConnector(connector); 346731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes } 3470243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg printf("\n"); 348731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes} 349731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 350731cd5526e5c732d51307b26e784f454a724a699Jesse Barnesvoid dump_crtcs(void) 351731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes{ 352731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes drmModeCrtc *crtc; 35386dece4cf2f7180b854fbd318fa1a57793f0deacPaulo Zanoni drmModeObjectPropertiesPtr props; 354731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes int i; 35586dece4cf2f7180b854fbd318fa1a57793f0deacPaulo Zanoni uint32_t j; 356731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 3570243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg printf("CRTCs:\n"); 3580243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg printf("id\tfb\tpos\tsize\n"); 359731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes for (i = 0; i < resources->count_crtcs; i++) { 360731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes crtc = drmModeGetCrtc(fd, resources->crtcs[i]); 361731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 362731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes if (!crtc) { 363731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes fprintf(stderr, "could not get crtc %i: %s\n", 364731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes resources->crtcs[i], strerror(errno)); 365731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes continue; 366731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes } 3670243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg printf("%d\t%d\t(%d,%d)\t(%dx%d)\n", 3680243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg crtc->crtc_id, 3690243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg crtc->buffer_id, 3700243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg crtc->x, crtc->y, 3710243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg crtc->width, crtc->height); 3720243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg dump_mode(&crtc->mode); 3730243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg 37486dece4cf2f7180b854fbd318fa1a57793f0deacPaulo Zanoni printf(" props:\n"); 37586dece4cf2f7180b854fbd318fa1a57793f0deacPaulo Zanoni props = drmModeObjectGetProperties(fd, crtc->crtc_id, 37686dece4cf2f7180b854fbd318fa1a57793f0deacPaulo Zanoni DRM_MODE_OBJECT_CRTC); 37786dece4cf2f7180b854fbd318fa1a57793f0deacPaulo Zanoni if (props) { 37886dece4cf2f7180b854fbd318fa1a57793f0deacPaulo Zanoni for (j = 0; j < props->count_props; j++) 37986dece4cf2f7180b854fbd318fa1a57793f0deacPaulo Zanoni dump_prop(props->props[j], 38086dece4cf2f7180b854fbd318fa1a57793f0deacPaulo Zanoni props->prop_values[j]); 38186dece4cf2f7180b854fbd318fa1a57793f0deacPaulo Zanoni drmModeFreeObjectProperties(props); 38286dece4cf2f7180b854fbd318fa1a57793f0deacPaulo Zanoni } else { 38386dece4cf2f7180b854fbd318fa1a57793f0deacPaulo Zanoni printf("\tcould not get crtc properties: %s\n", 38486dece4cf2f7180b854fbd318fa1a57793f0deacPaulo Zanoni strerror(errno)); 38586dece4cf2f7180b854fbd318fa1a57793f0deacPaulo Zanoni } 38686dece4cf2f7180b854fbd318fa1a57793f0deacPaulo Zanoni 387731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes drmModeFreeCrtc(crtc); 388731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes } 3890243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg printf("\n"); 390731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes} 391731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 392731cd5526e5c732d51307b26e784f454a724a699Jesse Barnesvoid dump_framebuffers(void) 393731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes{ 394731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes drmModeFB *fb; 395731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes int i; 396731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 3970243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg printf("Frame buffers:\n"); 3980243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg printf("id\tsize\tpitch\n"); 399731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes for (i = 0; i < resources->count_fbs; i++) { 400731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes fb = drmModeGetFB(fd, resources->fbs[i]); 401731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 402731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes if (!fb) { 403731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes fprintf(stderr, "could not get fb %i: %s\n", 404731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes resources->fbs[i], strerror(errno)); 405731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes continue; 406731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes } 407e4a519635f75bde38aeb5b09f2ff4efbf73453e9Matthew W. S. Bell printf("%u\t(%ux%u)\t%u\n", 4080243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg fb->fb_id, 409e4a519635f75bde38aeb5b09f2ff4efbf73453e9Matthew W. S. Bell fb->width, fb->height, 410e4a519635f75bde38aeb5b09f2ff4efbf73453e9Matthew W. S. Bell fb->pitch); 4110243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg 412731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes drmModeFreeFB(fb); 413731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes } 4140243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg printf("\n"); 415731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes} 416731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 417d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clarkstatic void dump_planes(void) 418d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark{ 41925e4cb4659c62817aae2ca3b83f2d4f598d6474bRob Clark drmModeObjectPropertiesPtr props; 420d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark drmModePlaneRes *plane_resources; 421d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark drmModePlane *ovr; 4229b44fbd393b8db571badae41881f490145404ae0Paulo Zanoni unsigned int i, j; 423d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark 424d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark plane_resources = drmModeGetPlaneResources(fd); 425d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark if (!plane_resources) { 426d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark fprintf(stderr, "drmModeGetPlaneResources failed: %s\n", 427d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark strerror(errno)); 428d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark return; 429d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark } 430d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark 431d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark printf("Planes:\n"); 4328e56579b203a11c718c5e3da6fdb03b4f9b9fe56Ville Syrjälä printf("id\tcrtc\tfb\tCRTC x,y\tx,y\tgamma size\tpossible crtcs\n"); 433d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark for (i = 0; i < plane_resources->count_planes; i++) { 434d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark ovr = drmModeGetPlane(fd, plane_resources->planes[i]); 435d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark if (!ovr) { 436d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark fprintf(stderr, "drmModeGetPlane failed: %s\n", 437d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark strerror(errno)); 438d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark continue; 439d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark } 440d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark 4418e56579b203a11c718c5e3da6fdb03b4f9b9fe56Ville Syrjälä printf("%d\t%d\t%d\t%d,%d\t\t%d,%d\t%-8d\t0x%08x\n", 442d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark ovr->plane_id, ovr->crtc_id, ovr->fb_id, 443d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark ovr->crtc_x, ovr->crtc_y, ovr->x, ovr->y, 4448e56579b203a11c718c5e3da6fdb03b4f9b9fe56Ville Syrjälä ovr->gamma_size, ovr->possible_crtcs); 445d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark 446d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark if (!ovr->count_formats) 447d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark continue; 448d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark 449d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark printf(" formats:"); 450d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark for (j = 0; j < ovr->count_formats; j++) 451d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark printf(" %4.4s", (char *)&ovr->formats[j]); 452d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark printf("\n"); 453d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark 45425e4cb4659c62817aae2ca3b83f2d4f598d6474bRob Clark printf(" props:\n"); 45525e4cb4659c62817aae2ca3b83f2d4f598d6474bRob Clark props = drmModeObjectGetProperties(fd, ovr->plane_id, 45625e4cb4659c62817aae2ca3b83f2d4f598d6474bRob Clark DRM_MODE_OBJECT_PLANE); 45725e4cb4659c62817aae2ca3b83f2d4f598d6474bRob Clark if (props) { 45825e4cb4659c62817aae2ca3b83f2d4f598d6474bRob Clark for (j = 0; j < props->count_props; j++) 45925e4cb4659c62817aae2ca3b83f2d4f598d6474bRob Clark dump_prop(props->props[j], 46025e4cb4659c62817aae2ca3b83f2d4f598d6474bRob Clark props->prop_values[j]); 46125e4cb4659c62817aae2ca3b83f2d4f598d6474bRob Clark drmModeFreeObjectProperties(props); 46225e4cb4659c62817aae2ca3b83f2d4f598d6474bRob Clark } else { 46325e4cb4659c62817aae2ca3b83f2d4f598d6474bRob Clark printf("\tcould not get plane properties: %s\n", 46425e4cb4659c62817aae2ca3b83f2d4f598d6474bRob Clark strerror(errno)); 46525e4cb4659c62817aae2ca3b83f2d4f598d6474bRob Clark } 46625e4cb4659c62817aae2ca3b83f2d4f598d6474bRob Clark 467d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark drmModeFreePlane(ovr); 468d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark } 469d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark printf("\n"); 470d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark 4710ef7644fe5161d3b50f9550ebbf8cbbabd51706fPaulo Zanoni drmModeFreePlaneResources(plane_resources); 472d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark return; 473d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark} 474d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark 475a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart/* ----------------------------------------------------------------------------- 476a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart * Connectors and planes 477a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart */ 478a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart 479731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes/* 480731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * Mode setting with the kernel interfaces is a bit of a chore. 481731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * First you have to find the connector in question and make sure the 482731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * requested mode is available. 483731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * Then you need to find the encoder attached to that connector so you 484731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * can bind it with a free crtc. 485731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes */ 486669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsbergstruct connector { 487e4a519635f75bde38aeb5b09f2ff4efbf73453e9Matthew W. S. Bell uint32_t id; 488669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg char mode_str[64]; 489cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart char format_str[5]; 490cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart unsigned int fourcc; 4919fc85b4084b69fefab3dbdf1f6cf97ccb47c963aKristian Høgsberg drmModeModeInfo *mode; 492669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg drmModeEncoder *encoder; 4938b8803695b24d4cb4d041437a4709be06e59471bKristian Høgsberg int crtc; 494d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark int pipe; 4951e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg unsigned int fb_id[2], current_fb_id; 4961e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg struct timeval start; 4971e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg 4981e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg int swap_count; 499d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark}; 500d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark 501d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clarkstruct plane { 502d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark uint32_t con_id; /* the id of connector to bind to */ 503d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark uint32_t w, h; 504d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark unsigned int fb_id; 505b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark char format_str[5]; /* need to leave room for terminating \0 */ 5060375222c714e8b7ba55f12d5cb389383be1cf54dLaurent Pinchart unsigned int fourcc; 507d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark}; 508669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg 509669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsbergstatic void 510669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsbergconnector_find_mode(struct connector *c) 511731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes{ 512731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes drmModeConnector *connector; 513e4a519635f75bde38aeb5b09f2ff4efbf73453e9Matthew W. S. Bell int i, j; 514731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 515731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes /* First, find the connector & mode */ 516669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg c->mode = NULL; 517731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes for (i = 0; i < resources->count_connectors; i++) { 518731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes connector = drmModeGetConnector(fd, resources->connectors[i]); 519731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 520731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes if (!connector) { 521731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes fprintf(stderr, "could not get connector %i: %s\n", 522731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes resources->connectors[i], strerror(errno)); 523731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes drmModeFreeConnector(connector); 524731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes continue; 525731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes } 526731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 527731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes if (!connector->count_modes) { 528731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes drmModeFreeConnector(connector); 529731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes continue; 530731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes } 531731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 532669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg if (connector->connector_id != c->id) { 533731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes drmModeFreeConnector(connector); 534731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes continue; 535731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes } 536731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 537731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes for (j = 0; j < connector->count_modes; j++) { 538669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg c->mode = &connector->modes[j]; 539669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg if (!strcmp(c->mode->name, c->mode_str)) 540731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes break; 541731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes } 542731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 543731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes /* Found it, break out */ 544669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg if (c->mode) 545731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes break; 546731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 547731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes drmModeFreeConnector(connector); 548731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes } 549731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 550669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg if (!c->mode) { 551669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg fprintf(stderr, "failed to find mode \"%s\"\n", c->mode_str); 552731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes return; 553731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes } 554731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 555731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes /* Now get the encoder */ 556731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes for (i = 0; i < resources->count_encoders; i++) { 557669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg c->encoder = drmModeGetEncoder(fd, resources->encoders[i]); 558731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 559669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg if (!c->encoder) { 560731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes fprintf(stderr, "could not get encoder %i: %s\n", 561731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes resources->encoders[i], strerror(errno)); 562669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg drmModeFreeEncoder(c->encoder); 563731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes continue; 564731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes } 565731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 566669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg if (c->encoder->encoder_id == connector->encoder_id) 567731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes break; 568731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 569669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg drmModeFreeEncoder(c->encoder); 570669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg } 5718b8803695b24d4cb4d041437a4709be06e59471bKristian Høgsberg 5728b8803695b24d4cb4d041437a4709be06e59471bKristian Høgsberg if (c->crtc == -1) 5738b8803695b24d4cb4d041437a4709be06e59471bKristian Høgsberg c->crtc = c->encoder->crtc_id; 574d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark 575d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark /* and figure out which crtc index it is: */ 576d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark for (i = 0; i < resources->count_crtcs; i++) { 577d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark if (c->crtc == resources->crtcs[i]) { 578d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark c->pipe = i; 579d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark break; 580d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark } 581d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark } 582d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark 583669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg} 584669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg 5853fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart/* -------------------------------------------------------------------------- */ 5863fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart 5873fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchartvoid 5883fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchartpage_flip_handler(int fd, unsigned int frame, 5893fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart unsigned int sec, unsigned int usec, void *data) 5903fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart{ 5913fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart struct connector *c; 5923fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart unsigned int new_fb_id; 5933fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart struct timeval end; 5943fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart double t; 5953fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart 5963fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart c = data; 5973fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart if (c->current_fb_id == c->fb_id[0]) 5983fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart new_fb_id = c->fb_id[1]; 5993fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart else 6003fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart new_fb_id = c->fb_id[0]; 6013fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart 6023fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart drmModePageFlip(fd, c->crtc, new_fb_id, 6033fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart DRM_MODE_PAGE_FLIP_EVENT, c); 6043fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart c->current_fb_id = new_fb_id; 6053fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart c->swap_count++; 6063fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart if (c->swap_count == 60) { 6073fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart gettimeofday(&end, NULL); 6083fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart t = end.tv_sec + end.tv_usec * 1e-6 - 6093fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart (c->start.tv_sec + c->start.tv_usec * 1e-6); 6103fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart fprintf(stderr, "freq: %.02fHz\n", c->swap_count / t); 6113fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart c->swap_count = 0; 6123fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart c->start = end; 6133fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart } 6143fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart} 6153fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart 616d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clarkstatic int 617d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clarkset_plane(struct kms_driver *kms, struct connector *c, struct plane *p) 618d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark{ 619d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark drmModePlaneRes *plane_resources; 620d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark drmModePlane *ovr; 621d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark uint32_t handles[4], pitches[4], offsets[4] = {0}; /* we only use [0] */ 622d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark uint32_t plane_id = 0; 623d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark struct kms_bo *plane_bo; 6240375222c714e8b7ba55f12d5cb389383be1cf54dLaurent Pinchart uint32_t plane_flags = 0; 6259b44fbd393b8db571badae41881f490145404ae0Paulo Zanoni int ret, crtc_x, crtc_y, crtc_w, crtc_h; 6269b44fbd393b8db571badae41881f490145404ae0Paulo Zanoni unsigned int i; 627d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark 628d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark /* find an unused plane which can be connected to our crtc */ 629d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark plane_resources = drmModeGetPlaneResources(fd); 630d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark if (!plane_resources) { 631d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark fprintf(stderr, "drmModeGetPlaneResources failed: %s\n", 632d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark strerror(errno)); 633d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark return -1; 634d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark } 635d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark 636d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark for (i = 0; i < plane_resources->count_planes && !plane_id; i++) { 637d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark ovr = drmModeGetPlane(fd, plane_resources->planes[i]); 638d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark if (!ovr) { 639d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark fprintf(stderr, "drmModeGetPlane failed: %s\n", 640d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark strerror(errno)); 641d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark return -1; 642d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark } 643d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark 644d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark if ((ovr->possible_crtcs & (1 << c->pipe)) && !ovr->crtc_id) 645d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark plane_id = ovr->plane_id; 646d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark 647d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark drmModeFreePlane(ovr); 648d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark } 649d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark 650b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark fprintf(stderr, "testing %dx%d@%s overlay plane\n", 651b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark p->w, p->h, p->format_str); 652b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark 653d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark if (!plane_id) { 654d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark fprintf(stderr, "failed to find plane!\n"); 655d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark return -1; 656d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark } 657d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark 6580375222c714e8b7ba55f12d5cb389383be1cf54dLaurent Pinchart plane_bo = create_test_buffer(kms, p->fourcc, p->w, p->h, handles, 659a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart pitches, offsets, PATTERN_TILES); 6603fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart if (plane_bo == NULL) 6613fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart return -1; 662d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark 663d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark /* just use single plane format for now.. */ 6640375222c714e8b7ba55f12d5cb389383be1cf54dLaurent Pinchart if (drmModeAddFB2(fd, p->w, p->h, p->fourcc, 665d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark handles, pitches, offsets, &p->fb_id, plane_flags)) { 666d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark fprintf(stderr, "failed to add fb: %s\n", strerror(errno)); 667d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark return -1; 668d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark } 669d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark 670d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark /* ok, boring.. but for now put in middle of screen: */ 671d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark crtc_x = c->mode->hdisplay / 3; 672d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark crtc_y = c->mode->vdisplay / 3; 673d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark crtc_w = crtc_x; 674d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark crtc_h = crtc_y; 675d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark 676d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark /* note src coords (last 4 args) are in Q16 format */ 677d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark if (drmModeSetPlane(fd, plane_id, c->crtc, p->fb_id, 678d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark plane_flags, crtc_x, crtc_y, crtc_w, crtc_h, 679d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark 0, 0, p->w << 16, p->h << 16)) { 680d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark fprintf(stderr, "failed to enable plane: %s\n", 681d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark strerror(errno)); 682d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark return -1; 683d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark } 684d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark 685d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark return 0; 686d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark} 687d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark 6887a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsbergstatic void 689d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clarkset_mode(struct connector *c, int count, struct plane *p, int plane_count, 690d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark int page_flip) 6917a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg{ 6928fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke struct kms_driver *kms; 6938fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke struct kms_bo *bo, *other_bo; 6941e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg unsigned int fb_id, other_fb_id; 6953fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart int i, j, ret, width, height, x; 6963fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart uint32_t handles[4], pitches[4], offsets[4] = {0}; /* we only use [0] */ 6971e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg drmEventContext evctx; 6987a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg 6997a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg width = 0; 7007a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg height = 0; 7017a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg for (i = 0; i < count; i++) { 7027a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg connector_find_mode(&c[i]); 7037a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg if (c[i].mode == NULL) 7047a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg continue; 7057a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg width += c[i].mode->hdisplay; 7067a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg if (height < c[i].mode->vdisplay) 7077a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg height = c[i].mode->vdisplay; 7087a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg } 7097a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg 7108fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke ret = kms_create(fd, &kms); 7118fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke if (ret) { 7128fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke fprintf(stderr, "failed to create kms driver: %s\n", 7138fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke strerror(-ret)); 7147a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg return; 7157a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg } 7167a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg 717cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart bo = create_test_buffer(kms, c->fourcc, width, height, handles, 718a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart pitches, offsets, PATTERN_SMPTE); 7193fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart if (bo == NULL) 7207a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg return; 721731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 722cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart ret = drmModeAddFB2(fd, width, height, c->fourcc, 723cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart handles, pitches, offsets, &fb_id, 0); 724731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes if (ret) { 725680b9c4fa3dfb329bd74ec08c17cfc876ea2fc5bJakob Bornecrantz fprintf(stderr, "failed to add fb (%ux%u): %s\n", 726680b9c4fa3dfb329bd74ec08c17cfc876ea2fc5bJakob Bornecrantz width, height, strerror(errno)); 727731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes return; 728731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes } 729731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 730669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg x = 0; 731669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg for (i = 0; i < count; i++) { 732669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg if (c[i].mode == NULL) 733669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg continue; 7348b8803695b24d4cb4d041437a4709be06e59471bKristian Høgsberg 735cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart printf("setting mode %s@%s on connector %d, crtc %d\n", 736cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart c[i].mode_str, c[i].format_str, c[i].id, c[i].crtc); 7378b8803695b24d4cb4d041437a4709be06e59471bKristian Høgsberg 7388b8803695b24d4cb4d041437a4709be06e59471bKristian Høgsberg ret = drmModeSetCrtc(fd, c[i].crtc, fb_id, x, 0, 739669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg &c[i].id, 1, c[i].mode); 740d23146f3f0ad14c8ad482a4832cae859c8d646f2Jakob Bornecrantz 741d23146f3f0ad14c8ad482a4832cae859c8d646f2Jakob Bornecrantz /* XXX: Actually check if this is needed */ 742d23146f3f0ad14c8ad482a4832cae859c8d646f2Jakob Bornecrantz drmModeDirtyFB(fd, fb_id, NULL, 0); 743d23146f3f0ad14c8ad482a4832cae859c8d646f2Jakob Bornecrantz 744669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg x += c[i].mode->hdisplay; 745669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg 746669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg if (ret) { 747669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg fprintf(stderr, "failed to set mode: %s\n", strerror(errno)); 748669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg return; 749669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg } 750d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark 751d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark /* if we have a plane/overlay to show, set that up now: */ 752d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark for (j = 0; j < plane_count; j++) 753d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark if (p[j].con_id == c[i].id) 754d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark if (set_plane(kms, &c[i], &p[j])) 755d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark return; 756731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes } 7571e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg 7581e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg if (!page_flip) 7591e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg return; 7608fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke 761cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart other_bo = create_test_buffer(kms, c->fourcc, width, height, handles, 762a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart pitches, offsets, PATTERN_PLAIN); 7633fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart if (other_bo == NULL) 7641e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg return; 7651e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg 766cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart ret = drmModeAddFB2(fd, width, height, c->fourcc, handles, pitches, offsets, 767cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart &other_fb_id, 0); 7681e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg if (ret) { 7691e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg fprintf(stderr, "failed to add fb: %s\n", strerror(errno)); 7701e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg return; 7711e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg } 7721e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg 7731e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg for (i = 0; i < count; i++) { 7741e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg if (c[i].mode == NULL) 7751e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg continue; 7761e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg 7773c8adda6e1e6b0471b3d70a63d795622bbeb1580Jakob Bornecrantz ret = drmModePageFlip(fd, c[i].crtc, other_fb_id, 7783c8adda6e1e6b0471b3d70a63d795622bbeb1580Jakob Bornecrantz DRM_MODE_PAGE_FLIP_EVENT, &c[i]); 7793c8adda6e1e6b0471b3d70a63d795622bbeb1580Jakob Bornecrantz if (ret) { 7803c8adda6e1e6b0471b3d70a63d795622bbeb1580Jakob Bornecrantz fprintf(stderr, "failed to page flip: %s\n", strerror(errno)); 7813c8adda6e1e6b0471b3d70a63d795622bbeb1580Jakob Bornecrantz return; 7823c8adda6e1e6b0471b3d70a63d795622bbeb1580Jakob Bornecrantz } 7831e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg gettimeofday(&c[i].start, NULL); 7841e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg c[i].swap_count = 0; 785e4a519635f75bde38aeb5b09f2ff4efbf73453e9Matthew W. S. Bell c[i].fb_id[0] = fb_id; 786e4a519635f75bde38aeb5b09f2ff4efbf73453e9Matthew W. S. Bell c[i].fb_id[1] = other_fb_id; 787a697fb6acad7992c3d23bb6a663663694782eb7bBenjamin Franzke c[i].current_fb_id = other_fb_id; 7881e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg } 7891e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg 7901e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg memset(&evctx, 0, sizeof evctx); 7911e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg evctx.version = DRM_EVENT_CONTEXT_VERSION; 7921e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg evctx.vblank_handler = NULL; 7936f1eba0548cd6a96e91a4e8be7b91ba6a936eb98Jesse Barnes evctx.page_flip_handler = page_flip_handler; 7941e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg 7951e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg while (1) { 796e6b3f906cef26e1efb8625f5dd4e460b4c79a771Jesse Barnes#if 0 7971e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg struct pollfd pfd[2]; 7981e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg 7991e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg pfd[0].fd = 0; 8001e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg pfd[0].events = POLLIN; 8011e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg pfd[1].fd = fd; 8021e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg pfd[1].events = POLLIN; 8031e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg 8041e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg if (poll(pfd, 2, -1) < 0) { 8051e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg fprintf(stderr, "poll error\n"); 8061e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg break; 8071e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg } 8081e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg 8091e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg if (pfd[0].revents) 8101e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg break; 811e6b3f906cef26e1efb8625f5dd4e460b4c79a771Jesse Barnes#else 812e6b3f906cef26e1efb8625f5dd4e460b4c79a771Jesse Barnes struct timeval timeout = { .tv_sec = 3, .tv_usec = 0 }; 813e6b3f906cef26e1efb8625f5dd4e460b4c79a771Jesse Barnes fd_set fds; 814e6b3f906cef26e1efb8625f5dd4e460b4c79a771Jesse Barnes int ret; 815e6b3f906cef26e1efb8625f5dd4e460b4c79a771Jesse Barnes 816e6b3f906cef26e1efb8625f5dd4e460b4c79a771Jesse Barnes FD_ZERO(&fds); 817e6b3f906cef26e1efb8625f5dd4e460b4c79a771Jesse Barnes FD_SET(0, &fds); 818e6b3f906cef26e1efb8625f5dd4e460b4c79a771Jesse Barnes FD_SET(fd, &fds); 819e6b3f906cef26e1efb8625f5dd4e460b4c79a771Jesse Barnes ret = select(fd + 1, &fds, NULL, NULL, &timeout); 820e6b3f906cef26e1efb8625f5dd4e460b4c79a771Jesse Barnes 821e6b3f906cef26e1efb8625f5dd4e460b4c79a771Jesse Barnes if (ret <= 0) { 822e6b3f906cef26e1efb8625f5dd4e460b4c79a771Jesse Barnes fprintf(stderr, "select timed out or error (ret %d)\n", 823e6b3f906cef26e1efb8625f5dd4e460b4c79a771Jesse Barnes ret); 824e6b3f906cef26e1efb8625f5dd4e460b4c79a771Jesse Barnes continue; 825e6b3f906cef26e1efb8625f5dd4e460b4c79a771Jesse Barnes } else if (FD_ISSET(0, &fds)) { 826e6b3f906cef26e1efb8625f5dd4e460b4c79a771Jesse Barnes break; 827e6b3f906cef26e1efb8625f5dd4e460b4c79a771Jesse Barnes } 828e6b3f906cef26e1efb8625f5dd4e460b4c79a771Jesse Barnes#endif 8291e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg 8301e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg drmHandleEvent(fd, &evctx); 8311e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg } 8328fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke 8338fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke kms_bo_destroy(&bo); 8348fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke kms_bo_destroy(&other_bo); 8358fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke kms_destroy(&kms); 836731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes} 837731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 838731cd5526e5c732d51307b26e784f454a724a699Jesse Barnesextern char *optarg; 839731cd5526e5c732d51307b26e784f454a724a699Jesse Barnesextern int optind, opterr, optopt; 840d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clarkstatic char optstr[] = "ecpmfs:P:v"; 841731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 842cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart#define min(a, b) ((a) < (b) ? (a) : (b)) 843cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart 8440375222c714e8b7ba55f12d5cb389383be1cf54dLaurent Pinchartstatic int parse_connector(struct connector *c, const char *arg) 8450375222c714e8b7ba55f12d5cb389383be1cf54dLaurent Pinchart{ 846cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart unsigned int len; 847cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart const char *p; 848cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart char *endp; 849cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart 8500375222c714e8b7ba55f12d5cb389383be1cf54dLaurent Pinchart c->crtc = -1; 851cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart strcpy(c->format_str, "XR24"); 852cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart 853cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart c->id = strtoul(arg, &endp, 10); 854cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart if (*endp == '@') { 855cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart arg = endp + 1; 856cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart c->crtc = strtoul(arg, &endp, 10); 857cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart } 858cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart if (*endp != ':') 859cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart return -1; 8600375222c714e8b7ba55f12d5cb389383be1cf54dLaurent Pinchart 861cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart arg = endp + 1; 8620375222c714e8b7ba55f12d5cb389383be1cf54dLaurent Pinchart 863cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart p = strchrnul(arg, '@'); 864cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart len = min(sizeof c->mode_str - 1, p - arg); 865cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart strncpy(c->mode_str, arg, len); 866cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart c->mode_str[len] = '\0'; 8670375222c714e8b7ba55f12d5cb389383be1cf54dLaurent Pinchart 868cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart if (*p == '@') { 869cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart strncpy(c->format_str, p + 1, 4); 870cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart c->format_str[4] = '\0'; 871ebd7904877d08525beb5039e4ea2f5b6c0a7c23fRob Clark } 872cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart 873ebd7904877d08525beb5039e4ea2f5b6c0a7c23fRob Clark c->fourcc = format_fourcc(c->format_str); 874ebd7904877d08525beb5039e4ea2f5b6c0a7c23fRob Clark if (c->fourcc == 0) { 875ebd7904877d08525beb5039e4ea2f5b6c0a7c23fRob Clark fprintf(stderr, "unknown format %s\n", c->format_str); 876ebd7904877d08525beb5039e4ea2f5b6c0a7c23fRob Clark return -1; 877cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart } 878cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart 879cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart return 0; 8800375222c714e8b7ba55f12d5cb389383be1cf54dLaurent Pinchart} 8810375222c714e8b7ba55f12d5cb389383be1cf54dLaurent Pinchart 8820375222c714e8b7ba55f12d5cb389383be1cf54dLaurent Pinchartstatic int parse_plane(struct plane *p, const char *arg) 8830375222c714e8b7ba55f12d5cb389383be1cf54dLaurent Pinchart{ 8840375222c714e8b7ba55f12d5cb389383be1cf54dLaurent Pinchart strcpy(p->format_str, "XR24"); 8850375222c714e8b7ba55f12d5cb389383be1cf54dLaurent Pinchart 8860375222c714e8b7ba55f12d5cb389383be1cf54dLaurent Pinchart if (sscanf(arg, "%d:%dx%d@%4s", &p->con_id, &p->w, &p->h, &p->format_str) != 4 && 8870375222c714e8b7ba55f12d5cb389383be1cf54dLaurent Pinchart sscanf(arg, "%d:%dx%d", &p->con_id, &p->w, &p->h) != 3) 8880375222c714e8b7ba55f12d5cb389383be1cf54dLaurent Pinchart return -1; 8890375222c714e8b7ba55f12d5cb389383be1cf54dLaurent Pinchart 8900375222c714e8b7ba55f12d5cb389383be1cf54dLaurent Pinchart p->fourcc = format_fourcc(p->format_str); 8910375222c714e8b7ba55f12d5cb389383be1cf54dLaurent Pinchart if (p->fourcc == 0) { 8920375222c714e8b7ba55f12d5cb389383be1cf54dLaurent Pinchart fprintf(stderr, "unknown format %s\n", p->format_str); 8930375222c714e8b7ba55f12d5cb389383be1cf54dLaurent Pinchart return -1; 8940375222c714e8b7ba55f12d5cb389383be1cf54dLaurent Pinchart } 8950375222c714e8b7ba55f12d5cb389383be1cf54dLaurent Pinchart 8960375222c714e8b7ba55f12d5cb389383be1cf54dLaurent Pinchart return 0; 8970375222c714e8b7ba55f12d5cb389383be1cf54dLaurent Pinchart} 8980375222c714e8b7ba55f12d5cb389383be1cf54dLaurent Pinchart 899731cd5526e5c732d51307b26e784f454a724a699Jesse Barnesvoid usage(char *name) 900731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes{ 901731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes fprintf(stderr, "usage: %s [-ecpmf]\n", name); 902731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes fprintf(stderr, "\t-e\tlist encoders\n"); 903731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes fprintf(stderr, "\t-c\tlist connectors\n"); 904d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark fprintf(stderr, "\t-p\tlist CRTCs and planes (pipes)\n"); 905731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes fprintf(stderr, "\t-m\tlist modes\n"); 906731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes fprintf(stderr, "\t-f\tlist framebuffers\n"); 9071e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg fprintf(stderr, "\t-v\ttest vsynced page flipping\n"); 908cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart fprintf(stderr, "\t-s <connector_id>[@<crtc_id>]:<mode>[@<format>]\tset a mode\n"); 909cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart fprintf(stderr, "\t-P <connector_id>:<w>x<h>[@<format>]\tset a plane\n"); 910731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes fprintf(stderr, "\n\tDefault is to dump all info.\n"); 911731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes exit(0); 912731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes} 913731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 914731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes#define dump_resource(res) if (res) dump_##res() 915731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 9169b44fbd393b8db571badae41881f490145404ae0Paulo Zanonistatic int page_flipping_supported(void) 91759d97e7d6807d9cd076d4e8374aca1d9e8027a6bKristian Høgsberg{ 9188fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke /*FIXME: generic ioctl needed? */ 9198fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke return 1; 9208fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke#if 0 92159d97e7d6807d9cd076d4e8374aca1d9e8027a6bKristian Høgsberg int ret, value; 92259d97e7d6807d9cd076d4e8374aca1d9e8027a6bKristian Høgsberg struct drm_i915_getparam gp; 92359d97e7d6807d9cd076d4e8374aca1d9e8027a6bKristian Høgsberg 92459d97e7d6807d9cd076d4e8374aca1d9e8027a6bKristian Høgsberg gp.param = I915_PARAM_HAS_PAGEFLIPPING; 92559d97e7d6807d9cd076d4e8374aca1d9e8027a6bKristian Høgsberg gp.value = &value; 92659d97e7d6807d9cd076d4e8374aca1d9e8027a6bKristian Høgsberg 92759d97e7d6807d9cd076d4e8374aca1d9e8027a6bKristian Høgsberg ret = drmCommandWriteRead(fd, DRM_I915_GETPARAM, &gp, sizeof(gp)); 92859d97e7d6807d9cd076d4e8374aca1d9e8027a6bKristian Høgsberg if (ret) { 92959d97e7d6807d9cd076d4e8374aca1d9e8027a6bKristian Høgsberg fprintf(stderr, "drm_i915_getparam: %m\n"); 93059d97e7d6807d9cd076d4e8374aca1d9e8027a6bKristian Høgsberg return 0; 93159d97e7d6807d9cd076d4e8374aca1d9e8027a6bKristian Høgsberg } 93259d97e7d6807d9cd076d4e8374aca1d9e8027a6bKristian Høgsberg 933e4a519635f75bde38aeb5b09f2ff4efbf73453e9Matthew W. S. Bell return *gp.value; 9348fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke#endif 93559d97e7d6807d9cd076d4e8374aca1d9e8027a6bKristian Høgsberg} 93659d97e7d6807d9cd076d4e8374aca1d9e8027a6bKristian Høgsberg 937731cd5526e5c732d51307b26e784f454a724a699Jesse Barnesint main(int argc, char **argv) 938731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes{ 939731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes int c; 940d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark int encoders = 0, connectors = 0, crtcs = 0, planes = 0, framebuffers = 0; 9411e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg int test_vsync = 0; 942e07b650662ea0529d99741691c47856ef1034c9cInki Dae char *modules[] = { "i915", "radeon", "nouveau", "vmwgfx", "omapdrm", "exynos" }; 9439b44fbd393b8db571badae41881f490145404ae0Paulo Zanoni unsigned int i; 9449b44fbd393b8db571badae41881f490145404ae0Paulo Zanoni int count = 0, plane_count = 0; 945669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg struct connector con_args[2]; 946b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark struct plane plane_args[2] = {0}; 947669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg 948731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes opterr = 0; 949731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes while ((c = getopt(argc, argv, optstr)) != -1) { 950731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes switch (c) { 951731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes case 'e': 952731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes encoders = 1; 953731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes break; 954731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes case 'c': 955731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes connectors = 1; 956731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes break; 957731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes case 'p': 958731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes crtcs = 1; 959d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark planes = 1; 960731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes break; 961731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes case 'm': 962731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes modes = 1; 963731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes break; 964731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes case 'f': 965731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes framebuffers = 1; 966731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes break; 9671e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg case 'v': 9681e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg test_vsync = 1; 9691e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg break; 970731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes case 's': 9710375222c714e8b7ba55f12d5cb389383be1cf54dLaurent Pinchart if (parse_connector(&con_args[count], optarg) < 0) 972669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg usage(argv[0]); 973669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg count++; 974731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes break; 975d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark case 'P': 9760375222c714e8b7ba55f12d5cb389383be1cf54dLaurent Pinchart if (parse_plane(&plane_args[plane_count], optarg) < 0) 977d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark usage(argv[0]); 978d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark plane_count++; 979d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark break; 980731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes default: 981731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes usage(argv[0]); 982731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes break; 983731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes } 984731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes } 985731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 986731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes if (argc == 1) 987d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark encoders = connectors = crtcs = planes = modes = framebuffers = 1; 988731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 989731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes for (i = 0; i < ARRAY_SIZE(modules); i++) { 990731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes printf("trying to load module %s...", modules[i]); 991731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes fd = drmOpen(modules[i], NULL); 992731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes if (fd < 0) { 993731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes printf("failed.\n"); 994731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes } else { 995731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes printf("success.\n"); 996731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes break; 997731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes } 998731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes } 999731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 10009b44fbd393b8db571badae41881f490145404ae0Paulo Zanoni if (test_vsync && !page_flipping_supported()) { 100159d97e7d6807d9cd076d4e8374aca1d9e8027a6bKristian Høgsberg fprintf(stderr, "page flipping not supported by drm.\n"); 100259d97e7d6807d9cd076d4e8374aca1d9e8027a6bKristian Høgsberg return -1; 100359d97e7d6807d9cd076d4e8374aca1d9e8027a6bKristian Høgsberg } 100459d97e7d6807d9cd076d4e8374aca1d9e8027a6bKristian Høgsberg 1005731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes if (i == ARRAY_SIZE(modules)) { 1006731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes fprintf(stderr, "failed to load any modules, aborting.\n"); 1007731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes return -1; 1008731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes } 1009731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 1010731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes resources = drmModeGetResources(fd); 1011731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes if (!resources) { 1012731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes fprintf(stderr, "drmModeGetResources failed: %s\n", 1013731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes strerror(errno)); 1014731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes drmClose(fd); 1015731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes return 1; 1016731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes } 1017731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 1018731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes dump_resource(encoders); 1019731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes dump_resource(connectors); 1020731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes dump_resource(crtcs); 1021d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark dump_resource(planes); 1022731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes dump_resource(framebuffers); 1023731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 1024669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg if (count > 0) { 1025d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark set_mode(con_args, count, plane_args, plane_count, test_vsync); 10262c113a1b159f57ab94b54316ece49c677cfe04ceKristian Høgsberg getchar(); 1027731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes } 1028731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 1029731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes drmModeFreeResources(resources); 1030731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 1031731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes return 0; 1032731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes} 1033