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 */ 401ec3c44bdd38051d870f64d0b2cc7dbd59760386Thierry Reding 418e93afc9765f1de613c65a76e9a86e17db96e653Emil Velikov#ifdef HAVE_CONFIG_H 427a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg#include "config.h" 438e93afc9765f1de613c65a76e9a86e17db96e653Emil Velikov#endif 447a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg 45731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes#include <assert.h> 462c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart#include <ctype.h> 477badcca4925480ffdc4f3aa5efb88624ce451e70Laurent Pinchart#include <stdbool.h> 48731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes#include <stdio.h> 49731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes#include <stdlib.h> 50731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes#include <stdint.h> 51d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni#include <inttypes.h> 52731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes#include <unistd.h> 53731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes#include <string.h> 541785e2e1f9e876f114465ecf6b6df1428b246833Greg Hackmann#include <strings.h> 55731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes#include <errno.h> 561e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg#include <sys/poll.h> 57e4a519635f75bde38aeb5b09f2ff4efbf73453e9Matthew W. S. Bell#include <sys/time.h> 58731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 59731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes#include "xf86drm.h" 60731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes#include "xf86drmMode.h" 61d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark#include "drm_fourcc.h" 62731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 631ec3c44bdd38051d870f64d0b2cc7dbd59760386Thierry Reding#include "util/common.h" 641ec3c44bdd38051d870f64d0b2cc7dbd59760386Thierry Reding#include "util/format.h" 654664d657ead5ff176c92e8ac54e09ead2e6d94caThierry Reding#include "util/kms.h" 661ec3c44bdd38051d870f64d0b2cc7dbd59760386Thierry Reding#include "util/pattern.h" 671ec3c44bdd38051d870f64d0b2cc7dbd59760386Thierry Reding 68db004badef9315ba6a5f165d0974dd5afd5a6178Laurent Pinchart#include "buffers.h" 690e512794bf6281edfa4543ae7cc408d52ec6e2f3Rob Clark#include "cursor.h" 707a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg 7102fa8f79b05456184028f014432647b19601a288Laurent Pinchartstruct crtc { 7202fa8f79b05456184028f014432647b19601a288Laurent Pinchart drmModeCrtc *crtc; 7302fa8f79b05456184028f014432647b19601a288Laurent Pinchart drmModeObjectProperties *props; 7402fa8f79b05456184028f014432647b19601a288Laurent Pinchart drmModePropertyRes **props_info; 7556592680bbb1bb73d08bdce317046d0401dcfba0Laurent Pinchart drmModeModeInfo *mode; 7602fa8f79b05456184028f014432647b19601a288Laurent Pinchart}; 7702fa8f79b05456184028f014432647b19601a288Laurent Pinchart 7802fa8f79b05456184028f014432647b19601a288Laurent Pinchartstruct encoder { 7902fa8f79b05456184028f014432647b19601a288Laurent Pinchart drmModeEncoder *encoder; 8002fa8f79b05456184028f014432647b19601a288Laurent Pinchart}; 8102fa8f79b05456184028f014432647b19601a288Laurent Pinchart 8202fa8f79b05456184028f014432647b19601a288Laurent Pinchartstruct connector { 8302fa8f79b05456184028f014432647b19601a288Laurent Pinchart drmModeConnector *connector; 8402fa8f79b05456184028f014432647b19601a288Laurent Pinchart drmModeObjectProperties *props; 8502fa8f79b05456184028f014432647b19601a288Laurent Pinchart drmModePropertyRes **props_info; 86f05a74fb9cb07a02c9bade65d66ba6949a2567a2Thierry Reding char *name; 8702fa8f79b05456184028f014432647b19601a288Laurent Pinchart}; 8802fa8f79b05456184028f014432647b19601a288Laurent Pinchart 8902fa8f79b05456184028f014432647b19601a288Laurent Pinchartstruct fb { 9002fa8f79b05456184028f014432647b19601a288Laurent Pinchart drmModeFB *fb; 9102fa8f79b05456184028f014432647b19601a288Laurent Pinchart}; 9202fa8f79b05456184028f014432647b19601a288Laurent Pinchart 9302fa8f79b05456184028f014432647b19601a288Laurent Pinchartstruct plane { 9402fa8f79b05456184028f014432647b19601a288Laurent Pinchart drmModePlane *plane; 9502fa8f79b05456184028f014432647b19601a288Laurent Pinchart drmModeObjectProperties *props; 9602fa8f79b05456184028f014432647b19601a288Laurent Pinchart drmModePropertyRes **props_info; 9702fa8f79b05456184028f014432647b19601a288Laurent Pinchart}; 9802fa8f79b05456184028f014432647b19601a288Laurent Pinchart 9902fa8f79b05456184028f014432647b19601a288Laurent Pinchartstruct resources { 10002fa8f79b05456184028f014432647b19601a288Laurent Pinchart drmModeRes *res; 10102fa8f79b05456184028f014432647b19601a288Laurent Pinchart drmModePlaneRes *plane_res; 10202fa8f79b05456184028f014432647b19601a288Laurent Pinchart 10302fa8f79b05456184028f014432647b19601a288Laurent Pinchart struct crtc *crtcs; 10402fa8f79b05456184028f014432647b19601a288Laurent Pinchart struct encoder *encoders; 10502fa8f79b05456184028f014432647b19601a288Laurent Pinchart struct connector *connectors; 10602fa8f79b05456184028f014432647b19601a288Laurent Pinchart struct fb *fbs; 10702fa8f79b05456184028f014432647b19601a288Laurent Pinchart struct plane *planes; 10802fa8f79b05456184028f014432647b19601a288Laurent Pinchart}; 10902fa8f79b05456184028f014432647b19601a288Laurent Pinchart 110549fe0ba627a67b6ae1334eb5cf274a3dfb1fd69Laurent Pinchartstruct device { 111549fe0ba627a67b6ae1334eb5cf274a3dfb1fd69Laurent Pinchart int fd; 112549fe0ba627a67b6ae1334eb5cf274a3dfb1fd69Laurent Pinchart 113549fe0ba627a67b6ae1334eb5cf274a3dfb1fd69Laurent Pinchart struct resources *resources; 1143813e0f8e1ee4885823cdd0b50b05970257adddcLaurent Pinchart 1153813e0f8e1ee4885823cdd0b50b05970257adddcLaurent Pinchart struct { 1163813e0f8e1ee4885823cdd0b50b05970257adddcLaurent Pinchart unsigned int width; 1173813e0f8e1ee4885823cdd0b50b05970257adddcLaurent Pinchart unsigned int height; 1183813e0f8e1ee4885823cdd0b50b05970257adddcLaurent Pinchart 1193813e0f8e1ee4885823cdd0b50b05970257adddcLaurent Pinchart unsigned int fb_id; 120d7c0a08bc576deb07df6c3f91f393ca8edd0c4bfLaurent Pinchart struct bo *bo; 1219915e68b3b4d69101f3cb6609e796fb8f63320e2Joonyoung Shim struct bo *cursor_bo; 1223813e0f8e1ee4885823cdd0b50b05970257adddcLaurent Pinchart } mode; 123549fe0ba627a67b6ae1334eb5cf274a3dfb1fd69Laurent Pinchart}; 124731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 125fb4177046de19730a784c3c16e4b73aab0ec6e41Rob Clarkstatic inline int64_t U642I64(uint64_t val) 126fb4177046de19730a784c3c16e4b73aab0ec6e41Rob Clark{ 127fb4177046de19730a784c3c16e4b73aab0ec6e41Rob Clark return (int64_t)*((int64_t *)&val); 128fb4177046de19730a784c3c16e4b73aab0ec6e41Rob Clark} 129731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 130c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg#define bit_name_fn(res) \ 131ca9c8f06e0f560082dcd0943e9be29ba9a915ee3Laurent Pinchartconst char * res##_str(int type) { \ 132ca9c8f06e0f560082dcd0943e9be29ba9a915ee3Laurent Pinchart unsigned int i; \ 133c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg const char *sep = ""; \ 134c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg for (i = 0; i < ARRAY_SIZE(res##_names); i++) { \ 135c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg if (type & (1 << i)) { \ 136c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg printf("%s%s", sep, res##_names[i]); \ 137c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg sep = ", "; \ 138c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg } \ 139c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg } \ 1406fa2b29d226306870eebe93afb2106ca7d79569bTobias Klausmann return NULL; \ 141c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg} 142c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg 143c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsbergstatic const char *mode_type_names[] = { 144c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg "builtin", 145c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg "clock_c", 146c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg "crtc_c", 147c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg "preferred", 148c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg "default", 149c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg "userdef", 150c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg "driver", 151c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg}; 152c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg 153ca9c8f06e0f560082dcd0943e9be29ba9a915ee3Laurent Pinchartstatic bit_name_fn(mode_type) 154c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg 155c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsbergstatic const char *mode_flag_names[] = { 156c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg "phsync", 157c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg "nhsync", 158c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg "pvsync", 159c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg "nvsync", 160c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg "interlace", 161c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg "dblscan", 162c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg "csync", 163c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg "pcsync", 164c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg "ncsync", 165c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg "hskew", 166c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg "bcast", 167c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg "pixmux", 168c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg "dblclk", 169c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg "clkdiv2" 170c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg}; 171c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg 172ca9c8f06e0f560082dcd0943e9be29ba9a915ee3Laurent Pinchartstatic bit_name_fn(mode_flag) 173c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg 174549fe0ba627a67b6ae1334eb5cf274a3dfb1fd69Laurent Pinchartstatic void dump_encoders(struct device *dev) 175731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes{ 176731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes drmModeEncoder *encoder; 177731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes int i; 178731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 179731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes printf("Encoders:\n"); 180731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes printf("id\tcrtc\ttype\tpossible crtcs\tpossible clones\t\n"); 181549fe0ba627a67b6ae1334eb5cf274a3dfb1fd69Laurent Pinchart for (i = 0; i < dev->resources->res->count_encoders; i++) { 182549fe0ba627a67b6ae1334eb5cf274a3dfb1fd69Laurent Pinchart encoder = dev->resources->encoders[i].encoder; 18302fa8f79b05456184028f014432647b19601a288Laurent Pinchart if (!encoder) 184731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes continue; 18502fa8f79b05456184028f014432647b19601a288Laurent Pinchart 186731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes printf("%d\t%d\t%s\t0x%08x\t0x%08x\n", 187731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes encoder->encoder_id, 188731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes encoder->crtc_id, 1894664d657ead5ff176c92e8ac54e09ead2e6d94caThierry Reding util_lookup_encoder_type_name(encoder->encoder_type), 190731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes encoder->possible_crtcs, 191731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes encoder->possible_clones); 192731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes } 1930243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg printf("\n"); 1940243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg} 1950243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg 196ca9c8f06e0f560082dcd0943e9be29ba9a915ee3Laurent Pinchartstatic void dump_mode(drmModeModeInfo *mode) 1970243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg{ 198c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg printf(" %s %d %d %d %d %d %d %d %d %d", 1990243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg mode->name, 200694ef59532253727176ed0ce9077ae3ec41dd457Marcin Kościelnicki mode->vrefresh, 2010243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg mode->hdisplay, 2020243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg mode->hsync_start, 2030243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg mode->hsync_end, 2040243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg mode->htotal, 2050243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg mode->vdisplay, 2060243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg mode->vsync_start, 2070243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg mode->vsync_end, 2080243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg mode->vtotal); 209c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg 210c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg printf(" flags: "); 211c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg mode_flag_str(mode->flags); 212c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg printf("; type: "); 213c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg mode_type_str(mode->type); 214c0ed9b23ecb48b8301f66d2270e638249709e94eKristian Høgsberg printf("\n"); 215731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes} 216731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 217549fe0ba627a67b6ae1334eb5cf274a3dfb1fd69Laurent Pinchartstatic void dump_blob(struct device *dev, uint32_t blob_id) 218d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni{ 219d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni uint32_t i; 220d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni unsigned char *blob_data; 221d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni drmModePropertyBlobPtr blob; 222d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni 223549fe0ba627a67b6ae1334eb5cf274a3dfb1fd69Laurent Pinchart blob = drmModeGetPropertyBlob(dev->fd, blob_id); 224c2c0346e1f5ddec4f6497d7c6359157c5f32d442Ville Syrjälä if (!blob) { 225c2c0346e1f5ddec4f6497d7c6359157c5f32d442Ville Syrjälä printf("\n"); 226d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni return; 227c2c0346e1f5ddec4f6497d7c6359157c5f32d442Ville Syrjälä } 228d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni 229d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni blob_data = blob->data; 230d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni 231d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni for (i = 0; i < blob->length; i++) { 232d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni if (i % 16 == 0) 233d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni printf("\n\t\t\t"); 234d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni printf("%.2hhx", blob_data[i]); 235d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni } 236d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni printf("\n"); 237d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni 238d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni drmModeFreePropertyBlob(blob); 239d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni} 240d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni 241549fe0ba627a67b6ae1334eb5cf274a3dfb1fd69Laurent Pinchartstatic void dump_prop(struct device *dev, drmModePropertyPtr prop, 242549fe0ba627a67b6ae1334eb5cf274a3dfb1fd69Laurent Pinchart uint32_t prop_id, uint64_t value) 2439fc85b4084b69fefab3dbdf1f6cf97ccb47c963aKristian Høgsberg{ 2449fc85b4084b69fefab3dbdf1f6cf97ccb47c963aKristian Høgsberg int i; 245d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni printf("\t%d", prop_id); 246d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni if (!prop) { 247d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni printf("\n"); 248d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni return; 249d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni } 250d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni 251d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni printf(" %s:\n", prop->name); 252d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni 253d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni printf("\t\tflags:"); 254d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni if (prop->flags & DRM_MODE_PROP_PENDING) 255d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni printf(" pending"); 256d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni if (prop->flags & DRM_MODE_PROP_IMMUTABLE) 257d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni printf(" immutable"); 258fb4177046de19730a784c3c16e4b73aab0ec6e41Rob Clark if (drm_property_type_is(prop, DRM_MODE_PROP_SIGNED_RANGE)) 259fb4177046de19730a784c3c16e4b73aab0ec6e41Rob Clark printf(" signed range"); 260fb4177046de19730a784c3c16e4b73aab0ec6e41Rob Clark if (drm_property_type_is(prop, DRM_MODE_PROP_RANGE)) 261fb4177046de19730a784c3c16e4b73aab0ec6e41Rob Clark printf(" range"); 262fb4177046de19730a784c3c16e4b73aab0ec6e41Rob Clark if (drm_property_type_is(prop, DRM_MODE_PROP_ENUM)) 263d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni printf(" enum"); 264fb4177046de19730a784c3c16e4b73aab0ec6e41Rob Clark if (drm_property_type_is(prop, DRM_MODE_PROP_BITMASK)) 2656df9e6af4b34ef2c5278941ee78de029e4040485Rob Clark printf(" bitmask"); 266fb4177046de19730a784c3c16e4b73aab0ec6e41Rob Clark if (drm_property_type_is(prop, DRM_MODE_PROP_BLOB)) 267d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni printf(" blob"); 268fb4177046de19730a784c3c16e4b73aab0ec6e41Rob Clark if (drm_property_type_is(prop, DRM_MODE_PROP_OBJECT)) 269fb4177046de19730a784c3c16e4b73aab0ec6e41Rob Clark printf(" object"); 270d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni printf("\n"); 2719fc85b4084b69fefab3dbdf1f6cf97ccb47c963aKristian Høgsberg 272fb4177046de19730a784c3c16e4b73aab0ec6e41Rob Clark if (drm_property_type_is(prop, DRM_MODE_PROP_SIGNED_RANGE)) { 273fb4177046de19730a784c3c16e4b73aab0ec6e41Rob Clark printf("\t\tvalues:"); 274fb4177046de19730a784c3c16e4b73aab0ec6e41Rob Clark for (i = 0; i < prop->count_values; i++) 275fb4177046de19730a784c3c16e4b73aab0ec6e41Rob Clark printf(" %"PRId64, U642I64(prop->values[i])); 276fb4177046de19730a784c3c16e4b73aab0ec6e41Rob Clark printf("\n"); 277fb4177046de19730a784c3c16e4b73aab0ec6e41Rob Clark } 278fb4177046de19730a784c3c16e4b73aab0ec6e41Rob Clark 279fb4177046de19730a784c3c16e4b73aab0ec6e41Rob Clark if (drm_property_type_is(prop, DRM_MODE_PROP_RANGE)) { 280d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni printf("\t\tvalues:"); 281d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni for (i = 0; i < prop->count_values; i++) 282d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni printf(" %"PRIu64, prop->values[i]); 283d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni printf("\n"); 2849fc85b4084b69fefab3dbdf1f6cf97ccb47c963aKristian Høgsberg } 285d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni 286fb4177046de19730a784c3c16e4b73aab0ec6e41Rob Clark if (drm_property_type_is(prop, DRM_MODE_PROP_ENUM)) { 287d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni printf("\t\tenums:"); 288d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni for (i = 0; i < prop->count_enums; i++) 289d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni printf(" %s=%llu", prop->enums[i].name, 290d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni prop->enums[i].value); 291d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni printf("\n"); 292fb4177046de19730a784c3c16e4b73aab0ec6e41Rob Clark } else if (drm_property_type_is(prop, DRM_MODE_PROP_BITMASK)) { 2936df9e6af4b34ef2c5278941ee78de029e4040485Rob Clark printf("\t\tvalues:"); 2946df9e6af4b34ef2c5278941ee78de029e4040485Rob Clark for (i = 0; i < prop->count_enums; i++) 2956df9e6af4b34ef2c5278941ee78de029e4040485Rob Clark printf(" %s=0x%llx", prop->enums[i].name, 2966df9e6af4b34ef2c5278941ee78de029e4040485Rob Clark (1LL << prop->enums[i].value)); 2976df9e6af4b34ef2c5278941ee78de029e4040485Rob Clark printf("\n"); 298d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni } else { 299d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni assert(prop->count_enums == 0); 300d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni } 301d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni 302fb4177046de19730a784c3c16e4b73aab0ec6e41Rob Clark if (drm_property_type_is(prop, DRM_MODE_PROP_BLOB)) { 303d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni printf("\t\tblobs:\n"); 304d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni for (i = 0; i < prop->count_blobs; i++) 305549fe0ba627a67b6ae1334eb5cf274a3dfb1fd69Laurent Pinchart dump_blob(dev, prop->blob_ids[i]); 306d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni printf("\n"); 307d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni } else { 308d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni assert(prop->count_blobs == 0); 309d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni } 310d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni 311d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni printf("\t\tvalue:"); 312fb4177046de19730a784c3c16e4b73aab0ec6e41Rob Clark if (drm_property_type_is(prop, DRM_MODE_PROP_BLOB)) 313549fe0ba627a67b6ae1334eb5cf274a3dfb1fd69Laurent Pinchart dump_blob(dev, value); 314d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni else 315d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni printf(" %"PRIu64"\n", value); 3169fc85b4084b69fefab3dbdf1f6cf97ccb47c963aKristian Høgsberg} 3179fc85b4084b69fefab3dbdf1f6cf97ccb47c963aKristian Høgsberg 318549fe0ba627a67b6ae1334eb5cf274a3dfb1fd69Laurent Pinchartstatic void dump_connectors(struct device *dev) 319731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes{ 320731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes int i, j; 321731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 322731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes printf("Connectors:\n"); 323f05a74fb9cb07a02c9bade65d66ba6949a2567a2Thierry Reding printf("id\tencoder\tstatus\t\tname\t\tsize (mm)\tmodes\tencoders\n"); 324549fe0ba627a67b6ae1334eb5cf274a3dfb1fd69Laurent Pinchart for (i = 0; i < dev->resources->res->count_connectors; i++) { 325549fe0ba627a67b6ae1334eb5cf274a3dfb1fd69Laurent Pinchart struct connector *_connector = &dev->resources->connectors[i]; 32602fa8f79b05456184028f014432647b19601a288Laurent Pinchart drmModeConnector *connector = _connector->connector; 32702fa8f79b05456184028f014432647b19601a288Laurent Pinchart if (!connector) 328731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes continue; 329731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 330f05a74fb9cb07a02c9bade65d66ba6949a2567a2Thierry Reding printf("%d\t%d\t%s\t%-15s\t%dx%d\t\t%d\t", 331731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes connector->connector_id, 332731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes connector->encoder_id, 3334664d657ead5ff176c92e8ac54e09ead2e6d94caThierry Reding util_lookup_connector_status_name(connector->connection), 334f05a74fb9cb07a02c9bade65d66ba6949a2567a2Thierry Reding _connector->name, 335731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes connector->mmWidth, connector->mmHeight, 336731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes connector->count_modes); 337731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 3381e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg for (j = 0; j < connector->count_encoders; j++) 3391e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg printf("%s%d", j > 0 ? ", " : "", connector->encoders[j]); 3401e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg printf("\n"); 3411e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg 342a10bcaaf668ab16233df10c2742dcb497e17d588Paulo Zanoni if (connector->count_modes) { 343a10bcaaf668ab16233df10c2742dcb497e17d588Paulo Zanoni printf(" modes:\n"); 344d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22Paulo Zanoni printf("\tname refresh (Hz) hdisp hss hse htot vdisp " 345a10bcaaf668ab16233df10c2742dcb497e17d588Paulo Zanoni "vss vse vtot)\n"); 346a10bcaaf668ab16233df10c2742dcb497e17d588Paulo Zanoni for (j = 0; j < connector->count_modes; j++) 347a10bcaaf668ab16233df10c2742dcb497e17d588Paulo Zanoni dump_mode(&connector->modes[j]); 34802fa8f79b05456184028f014432647b19601a288Laurent Pinchart } 349a10bcaaf668ab16233df10c2742dcb497e17d588Paulo Zanoni 35002fa8f79b05456184028f014432647b19601a288Laurent Pinchart if (_connector->props) { 351a10bcaaf668ab16233df10c2742dcb497e17d588Paulo Zanoni printf(" props:\n"); 35202fa8f79b05456184028f014432647b19601a288Laurent Pinchart for (j = 0; j < (int)_connector->props->count_props; j++) 353549fe0ba627a67b6ae1334eb5cf274a3dfb1fd69Laurent Pinchart dump_prop(dev, _connector->props_info[j], 35402fa8f79b05456184028f014432647b19601a288Laurent Pinchart _connector->props->props[j], 35502fa8f79b05456184028f014432647b19601a288Laurent Pinchart _connector->props->prop_values[j]); 356a10bcaaf668ab16233df10c2742dcb497e17d588Paulo Zanoni } 357731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes } 3580243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg printf("\n"); 359731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes} 360731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 361549fe0ba627a67b6ae1334eb5cf274a3dfb1fd69Laurent Pinchartstatic void dump_crtcs(struct device *dev) 362731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes{ 363731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes int i; 36486dece4cf2f7180b854fbd318fa1a57793f0deacPaulo Zanoni uint32_t j; 365731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 3660243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg printf("CRTCs:\n"); 3670243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg printf("id\tfb\tpos\tsize\n"); 368549fe0ba627a67b6ae1334eb5cf274a3dfb1fd69Laurent Pinchart for (i = 0; i < dev->resources->res->count_crtcs; i++) { 369549fe0ba627a67b6ae1334eb5cf274a3dfb1fd69Laurent Pinchart struct crtc *_crtc = &dev->resources->crtcs[i]; 37002fa8f79b05456184028f014432647b19601a288Laurent Pinchart drmModeCrtc *crtc = _crtc->crtc; 37102fa8f79b05456184028f014432647b19601a288Laurent Pinchart if (!crtc) 372731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes continue; 37302fa8f79b05456184028f014432647b19601a288Laurent Pinchart 3740243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg printf("%d\t%d\t(%d,%d)\t(%dx%d)\n", 3750243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg crtc->crtc_id, 3760243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg crtc->buffer_id, 3770243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg crtc->x, crtc->y, 3780243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg crtc->width, crtc->height); 3790243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg dump_mode(&crtc->mode); 3800243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg 38102fa8f79b05456184028f014432647b19601a288Laurent Pinchart if (_crtc->props) { 38202fa8f79b05456184028f014432647b19601a288Laurent Pinchart printf(" props:\n"); 38302fa8f79b05456184028f014432647b19601a288Laurent Pinchart for (j = 0; j < _crtc->props->count_props; j++) 384549fe0ba627a67b6ae1334eb5cf274a3dfb1fd69Laurent Pinchart dump_prop(dev, _crtc->props_info[j], 38502fa8f79b05456184028f014432647b19601a288Laurent Pinchart _crtc->props->props[j], 38602fa8f79b05456184028f014432647b19601a288Laurent Pinchart _crtc->props->prop_values[j]); 38786dece4cf2f7180b854fbd318fa1a57793f0deacPaulo Zanoni } else { 38802fa8f79b05456184028f014432647b19601a288Laurent Pinchart printf(" no properties found\n"); 38986dece4cf2f7180b854fbd318fa1a57793f0deacPaulo Zanoni } 390731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes } 3910243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg printf("\n"); 392731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes} 393731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 394549fe0ba627a67b6ae1334eb5cf274a3dfb1fd69Laurent Pinchartstatic void dump_framebuffers(struct device *dev) 395731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes{ 396731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes drmModeFB *fb; 397731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes int i; 398731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 3990243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg printf("Frame buffers:\n"); 4000243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg printf("id\tsize\tpitch\n"); 401549fe0ba627a67b6ae1334eb5cf274a3dfb1fd69Laurent Pinchart for (i = 0; i < dev->resources->res->count_fbs; i++) { 402549fe0ba627a67b6ae1334eb5cf274a3dfb1fd69Laurent Pinchart fb = dev->resources->fbs[i].fb; 40302fa8f79b05456184028f014432647b19601a288Laurent Pinchart if (!fb) 404731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes continue; 40502fa8f79b05456184028f014432647b19601a288Laurent Pinchart 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); 410731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes } 4110243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg printf("\n"); 412731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes} 413731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 414549fe0ba627a67b6ae1334eb5cf274a3dfb1fd69Laurent Pinchartstatic void dump_planes(struct device *dev) 415d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark{ 4169b44fbd393b8db571badae41881f490145404ae0Paulo Zanoni unsigned int i, j; 417d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark 418d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark printf("Planes:\n"); 4198e56579b203a11c718c5e3da6fdb03b4f9b9fe56Ville Syrjälä printf("id\tcrtc\tfb\tCRTC x,y\tx,y\tgamma size\tpossible crtcs\n"); 42002fa8f79b05456184028f014432647b19601a288Laurent Pinchart 421549fe0ba627a67b6ae1334eb5cf274a3dfb1fd69Laurent Pinchart if (!dev->resources->plane_res) 42202fa8f79b05456184028f014432647b19601a288Laurent Pinchart return; 42302fa8f79b05456184028f014432647b19601a288Laurent Pinchart 424549fe0ba627a67b6ae1334eb5cf274a3dfb1fd69Laurent Pinchart for (i = 0; i < dev->resources->plane_res->count_planes; i++) { 425549fe0ba627a67b6ae1334eb5cf274a3dfb1fd69Laurent Pinchart struct plane *plane = &dev->resources->planes[i]; 42602fa8f79b05456184028f014432647b19601a288Laurent Pinchart drmModePlane *ovr = plane->plane; 42702fa8f79b05456184028f014432647b19601a288Laurent Pinchart if (!ovr) 428d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark continue; 429d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark 4308e56579b203a11c718c5e3da6fdb03b4f9b9fe56Ville Syrjälä printf("%d\t%d\t%d\t%d,%d\t\t%d,%d\t%-8d\t0x%08x\n", 431d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark ovr->plane_id, ovr->crtc_id, ovr->fb_id, 432d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark ovr->crtc_x, ovr->crtc_y, ovr->x, ovr->y, 4338e56579b203a11c718c5e3da6fdb03b4f9b9fe56Ville Syrjälä ovr->gamma_size, ovr->possible_crtcs); 434d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark 435d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark if (!ovr->count_formats) 436d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark continue; 437d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark 438d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark printf(" formats:"); 439d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark for (j = 0; j < ovr->count_formats; j++) 440d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark printf(" %4.4s", (char *)&ovr->formats[j]); 441d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark printf("\n"); 442d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark 44302fa8f79b05456184028f014432647b19601a288Laurent Pinchart if (plane->props) { 44402fa8f79b05456184028f014432647b19601a288Laurent Pinchart printf(" props:\n"); 44502fa8f79b05456184028f014432647b19601a288Laurent Pinchart for (j = 0; j < plane->props->count_props; j++) 446549fe0ba627a67b6ae1334eb5cf274a3dfb1fd69Laurent Pinchart dump_prop(dev, plane->props_info[j], 44702fa8f79b05456184028f014432647b19601a288Laurent Pinchart plane->props->props[j], 44802fa8f79b05456184028f014432647b19601a288Laurent Pinchart plane->props->prop_values[j]); 44925e4cb4659c62817aae2ca3b83f2d4f598d6474bRob Clark } else { 45002fa8f79b05456184028f014432647b19601a288Laurent Pinchart printf(" no properties found\n"); 45125e4cb4659c62817aae2ca3b83f2d4f598d6474bRob Clark } 452d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark } 453d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark printf("\n"); 454d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark 455d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark return; 456d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark} 457d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark 45802fa8f79b05456184028f014432647b19601a288Laurent Pinchartstatic void free_resources(struct resources *res) 45902fa8f79b05456184028f014432647b19601a288Laurent Pinchart{ 460f05a74fb9cb07a02c9bade65d66ba6949a2567a2Thierry Reding int i; 461f05a74fb9cb07a02c9bade65d66ba6949a2567a2Thierry Reding 46202fa8f79b05456184028f014432647b19601a288Laurent Pinchart if (!res) 46302fa8f79b05456184028f014432647b19601a288Laurent Pinchart return; 46402fa8f79b05456184028f014432647b19601a288Laurent Pinchart 46502fa8f79b05456184028f014432647b19601a288Laurent Pinchart#define free_resource(_res, __res, type, Type) \ 46602fa8f79b05456184028f014432647b19601a288Laurent Pinchart do { \ 46702fa8f79b05456184028f014432647b19601a288Laurent Pinchart if (!(_res)->type##s) \ 46802fa8f79b05456184028f014432647b19601a288Laurent Pinchart break; \ 46902fa8f79b05456184028f014432647b19601a288Laurent Pinchart for (i = 0; i < (int)(_res)->__res->count_##type##s; ++i) { \ 47002fa8f79b05456184028f014432647b19601a288Laurent Pinchart if (!(_res)->type##s[i].type) \ 47102fa8f79b05456184028f014432647b19601a288Laurent Pinchart break; \ 47202fa8f79b05456184028f014432647b19601a288Laurent Pinchart drmModeFree##Type((_res)->type##s[i].type); \ 47302fa8f79b05456184028f014432647b19601a288Laurent Pinchart } \ 47402fa8f79b05456184028f014432647b19601a288Laurent Pinchart free((_res)->type##s); \ 47502fa8f79b05456184028f014432647b19601a288Laurent Pinchart } while (0) 47602fa8f79b05456184028f014432647b19601a288Laurent Pinchart 47702fa8f79b05456184028f014432647b19601a288Laurent Pinchart#define free_properties(_res, __res, type) \ 47802fa8f79b05456184028f014432647b19601a288Laurent Pinchart do { \ 47902fa8f79b05456184028f014432647b19601a288Laurent Pinchart for (i = 0; i < (int)(_res)->__res->count_##type##s; ++i) { \ 48002fa8f79b05456184028f014432647b19601a288Laurent Pinchart drmModeFreeObjectProperties(res->type##s[i].props); \ 48102fa8f79b05456184028f014432647b19601a288Laurent Pinchart free(res->type##s[i].props_info); \ 48202fa8f79b05456184028f014432647b19601a288Laurent Pinchart } \ 48302fa8f79b05456184028f014432647b19601a288Laurent Pinchart } while (0) 48402fa8f79b05456184028f014432647b19601a288Laurent Pinchart 48502fa8f79b05456184028f014432647b19601a288Laurent Pinchart if (res->res) { 48602fa8f79b05456184028f014432647b19601a288Laurent Pinchart free_properties(res, res, crtc); 48702fa8f79b05456184028f014432647b19601a288Laurent Pinchart 48802fa8f79b05456184028f014432647b19601a288Laurent Pinchart free_resource(res, res, crtc, Crtc); 48902fa8f79b05456184028f014432647b19601a288Laurent Pinchart free_resource(res, res, encoder, Encoder); 490f05a74fb9cb07a02c9bade65d66ba6949a2567a2Thierry Reding 491f05a74fb9cb07a02c9bade65d66ba6949a2567a2Thierry Reding for (i = 0; i < res->res->count_connectors; i++) 492f05a74fb9cb07a02c9bade65d66ba6949a2567a2Thierry Reding free(res->connectors[i].name); 493f05a74fb9cb07a02c9bade65d66ba6949a2567a2Thierry Reding 49402fa8f79b05456184028f014432647b19601a288Laurent Pinchart free_resource(res, res, connector, Connector); 49502fa8f79b05456184028f014432647b19601a288Laurent Pinchart free_resource(res, res, fb, FB); 49602fa8f79b05456184028f014432647b19601a288Laurent Pinchart 49702fa8f79b05456184028f014432647b19601a288Laurent Pinchart drmModeFreeResources(res->res); 49802fa8f79b05456184028f014432647b19601a288Laurent Pinchart } 49902fa8f79b05456184028f014432647b19601a288Laurent Pinchart 50002fa8f79b05456184028f014432647b19601a288Laurent Pinchart if (res->plane_res) { 50102fa8f79b05456184028f014432647b19601a288Laurent Pinchart free_properties(res, plane_res, plane); 50202fa8f79b05456184028f014432647b19601a288Laurent Pinchart 50302fa8f79b05456184028f014432647b19601a288Laurent Pinchart free_resource(res, plane_res, plane, Plane); 50402fa8f79b05456184028f014432647b19601a288Laurent Pinchart 50502fa8f79b05456184028f014432647b19601a288Laurent Pinchart drmModeFreePlaneResources(res->plane_res); 50602fa8f79b05456184028f014432647b19601a288Laurent Pinchart } 50702fa8f79b05456184028f014432647b19601a288Laurent Pinchart 50802fa8f79b05456184028f014432647b19601a288Laurent Pinchart free(res); 50902fa8f79b05456184028f014432647b19601a288Laurent Pinchart} 51002fa8f79b05456184028f014432647b19601a288Laurent Pinchart 511549fe0ba627a67b6ae1334eb5cf274a3dfb1fd69Laurent Pinchartstatic struct resources *get_resources(struct device *dev) 51202fa8f79b05456184028f014432647b19601a288Laurent Pinchart{ 51302fa8f79b05456184028f014432647b19601a288Laurent Pinchart struct resources *res; 51456592680bbb1bb73d08bdce317046d0401dcfba0Laurent Pinchart int i; 51502fa8f79b05456184028f014432647b19601a288Laurent Pinchart 516128344c2cf22385dedece5a3d774d3a24527d2deEmil Velikov res = calloc(1, sizeof(*res)); 51702fa8f79b05456184028f014432647b19601a288Laurent Pinchart if (res == 0) 51802fa8f79b05456184028f014432647b19601a288Laurent Pinchart return NULL; 51902fa8f79b05456184028f014432647b19601a288Laurent Pinchart 5201fec623b029747fa811fab9b52effd8993fc605bRob Clark drmSetClientCap(dev->fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1); 5210f45884ffc7a46dd4aef14ae6d227a10d8d24fd7Rob Clark drmSetClientCap(dev->fd, DRM_CLIENT_CAP_ATOMIC, 1); 5221fec623b029747fa811fab9b52effd8993fc605bRob Clark 523549fe0ba627a67b6ae1334eb5cf274a3dfb1fd69Laurent Pinchart res->res = drmModeGetResources(dev->fd); 52402fa8f79b05456184028f014432647b19601a288Laurent Pinchart if (!res->res) { 52502fa8f79b05456184028f014432647b19601a288Laurent Pinchart fprintf(stderr, "drmModeGetResources failed: %s\n", 52602fa8f79b05456184028f014432647b19601a288Laurent Pinchart strerror(errno)); 52702fa8f79b05456184028f014432647b19601a288Laurent Pinchart goto error; 52802fa8f79b05456184028f014432647b19601a288Laurent Pinchart } 52902fa8f79b05456184028f014432647b19601a288Laurent Pinchart 530128344c2cf22385dedece5a3d774d3a24527d2deEmil Velikov res->crtcs = calloc(res->res->count_crtcs, sizeof(*res->crtcs)); 531128344c2cf22385dedece5a3d774d3a24527d2deEmil Velikov res->encoders = calloc(res->res->count_encoders, sizeof(*res->encoders)); 532128344c2cf22385dedece5a3d774d3a24527d2deEmil Velikov res->connectors = calloc(res->res->count_connectors, sizeof(*res->connectors)); 533128344c2cf22385dedece5a3d774d3a24527d2deEmil Velikov res->fbs = calloc(res->res->count_fbs, sizeof(*res->fbs)); 53402fa8f79b05456184028f014432647b19601a288Laurent Pinchart 53502fa8f79b05456184028f014432647b19601a288Laurent Pinchart if (!res->crtcs || !res->encoders || !res->connectors || !res->fbs) 53602fa8f79b05456184028f014432647b19601a288Laurent Pinchart goto error; 53702fa8f79b05456184028f014432647b19601a288Laurent Pinchart 53802fa8f79b05456184028f014432647b19601a288Laurent Pinchart#define get_resource(_res, __res, type, Type) \ 53902fa8f79b05456184028f014432647b19601a288Laurent Pinchart do { \ 54002fa8f79b05456184028f014432647b19601a288Laurent Pinchart for (i = 0; i < (int)(_res)->__res->count_##type##s; ++i) { \ 54102fa8f79b05456184028f014432647b19601a288Laurent Pinchart (_res)->type##s[i].type = \ 542549fe0ba627a67b6ae1334eb5cf274a3dfb1fd69Laurent Pinchart drmModeGet##Type(dev->fd, (_res)->__res->type##s[i]); \ 54302fa8f79b05456184028f014432647b19601a288Laurent Pinchart if (!(_res)->type##s[i].type) \ 54402fa8f79b05456184028f014432647b19601a288Laurent Pinchart fprintf(stderr, "could not get %s %i: %s\n", \ 54502fa8f79b05456184028f014432647b19601a288Laurent Pinchart #type, (_res)->__res->type##s[i], \ 54602fa8f79b05456184028f014432647b19601a288Laurent Pinchart strerror(errno)); \ 54702fa8f79b05456184028f014432647b19601a288Laurent Pinchart } \ 54802fa8f79b05456184028f014432647b19601a288Laurent Pinchart } while (0) 54902fa8f79b05456184028f014432647b19601a288Laurent Pinchart 55002fa8f79b05456184028f014432647b19601a288Laurent Pinchart get_resource(res, res, crtc, Crtc); 55102fa8f79b05456184028f014432647b19601a288Laurent Pinchart get_resource(res, res, encoder, Encoder); 55202fa8f79b05456184028f014432647b19601a288Laurent Pinchart get_resource(res, res, connector, Connector); 55302fa8f79b05456184028f014432647b19601a288Laurent Pinchart get_resource(res, res, fb, FB); 55402fa8f79b05456184028f014432647b19601a288Laurent Pinchart 555f05a74fb9cb07a02c9bade65d66ba6949a2567a2Thierry Reding /* Set the name of all connectors based on the type name and the per-type ID. */ 556f05a74fb9cb07a02c9bade65d66ba6949a2567a2Thierry Reding for (i = 0; i < res->res->count_connectors; i++) { 557f05a74fb9cb07a02c9bade65d66ba6949a2567a2Thierry Reding struct connector *connector = &res->connectors[i]; 5584664d657ead5ff176c92e8ac54e09ead2e6d94caThierry Reding drmModeConnector *conn = connector->connector; 559f05a74fb9cb07a02c9bade65d66ba6949a2567a2Thierry Reding 560f05a74fb9cb07a02c9bade65d66ba6949a2567a2Thierry Reding asprintf(&connector->name, "%s-%u", 5614664d657ead5ff176c92e8ac54e09ead2e6d94caThierry Reding util_lookup_connector_type_name(conn->connector_type), 5624664d657ead5ff176c92e8ac54e09ead2e6d94caThierry Reding conn->connector_type_id); 563f05a74fb9cb07a02c9bade65d66ba6949a2567a2Thierry Reding } 564f05a74fb9cb07a02c9bade65d66ba6949a2567a2Thierry Reding 56502fa8f79b05456184028f014432647b19601a288Laurent Pinchart#define get_properties(_res, __res, type, Type) \ 56602fa8f79b05456184028f014432647b19601a288Laurent Pinchart do { \ 56702fa8f79b05456184028f014432647b19601a288Laurent Pinchart for (i = 0; i < (int)(_res)->__res->count_##type##s; ++i) { \ 56802fa8f79b05456184028f014432647b19601a288Laurent Pinchart struct type *obj = &res->type##s[i]; \ 56902fa8f79b05456184028f014432647b19601a288Laurent Pinchart unsigned int j; \ 57002fa8f79b05456184028f014432647b19601a288Laurent Pinchart obj->props = \ 571549fe0ba627a67b6ae1334eb5cf274a3dfb1fd69Laurent Pinchart drmModeObjectGetProperties(dev->fd, obj->type->type##_id, \ 57202fa8f79b05456184028f014432647b19601a288Laurent Pinchart DRM_MODE_OBJECT_##Type); \ 57302fa8f79b05456184028f014432647b19601a288Laurent Pinchart if (!obj->props) { \ 57402fa8f79b05456184028f014432647b19601a288Laurent Pinchart fprintf(stderr, \ 57502fa8f79b05456184028f014432647b19601a288Laurent Pinchart "could not get %s %i properties: %s\n", \ 57602fa8f79b05456184028f014432647b19601a288Laurent Pinchart #type, obj->type->type##_id, \ 57702fa8f79b05456184028f014432647b19601a288Laurent Pinchart strerror(errno)); \ 57802fa8f79b05456184028f014432647b19601a288Laurent Pinchart continue; \ 57902fa8f79b05456184028f014432647b19601a288Laurent Pinchart } \ 580128344c2cf22385dedece5a3d774d3a24527d2deEmil Velikov obj->props_info = calloc(obj->props->count_props, \ 581128344c2cf22385dedece5a3d774d3a24527d2deEmil Velikov sizeof(*obj->props_info)); \ 58202fa8f79b05456184028f014432647b19601a288Laurent Pinchart if (!obj->props_info) \ 58302fa8f79b05456184028f014432647b19601a288Laurent Pinchart continue; \ 58402fa8f79b05456184028f014432647b19601a288Laurent Pinchart for (j = 0; j < obj->props->count_props; ++j) \ 58502fa8f79b05456184028f014432647b19601a288Laurent Pinchart obj->props_info[j] = \ 586549fe0ba627a67b6ae1334eb5cf274a3dfb1fd69Laurent Pinchart drmModeGetProperty(dev->fd, obj->props->props[j]); \ 58702fa8f79b05456184028f014432647b19601a288Laurent Pinchart } \ 58802fa8f79b05456184028f014432647b19601a288Laurent Pinchart } while (0) 58902fa8f79b05456184028f014432647b19601a288Laurent Pinchart 59002fa8f79b05456184028f014432647b19601a288Laurent Pinchart get_properties(res, res, crtc, CRTC); 59102fa8f79b05456184028f014432647b19601a288Laurent Pinchart get_properties(res, res, connector, CONNECTOR); 59202fa8f79b05456184028f014432647b19601a288Laurent Pinchart 59356592680bbb1bb73d08bdce317046d0401dcfba0Laurent Pinchart for (i = 0; i < res->res->count_crtcs; ++i) 59456592680bbb1bb73d08bdce317046d0401dcfba0Laurent Pinchart res->crtcs[i].mode = &res->crtcs[i].crtc->mode; 59556592680bbb1bb73d08bdce317046d0401dcfba0Laurent Pinchart 596549fe0ba627a67b6ae1334eb5cf274a3dfb1fd69Laurent Pinchart res->plane_res = drmModeGetPlaneResources(dev->fd); 59702fa8f79b05456184028f014432647b19601a288Laurent Pinchart if (!res->plane_res) { 59802fa8f79b05456184028f014432647b19601a288Laurent Pinchart fprintf(stderr, "drmModeGetPlaneResources failed: %s\n", 59902fa8f79b05456184028f014432647b19601a288Laurent Pinchart strerror(errno)); 60002fa8f79b05456184028f014432647b19601a288Laurent Pinchart return res; 60102fa8f79b05456184028f014432647b19601a288Laurent Pinchart } 60202fa8f79b05456184028f014432647b19601a288Laurent Pinchart 603128344c2cf22385dedece5a3d774d3a24527d2deEmil Velikov res->planes = calloc(res->plane_res->count_planes, sizeof(*res->planes)); 60402fa8f79b05456184028f014432647b19601a288Laurent Pinchart if (!res->planes) 60502fa8f79b05456184028f014432647b19601a288Laurent Pinchart goto error; 60602fa8f79b05456184028f014432647b19601a288Laurent Pinchart 60702fa8f79b05456184028f014432647b19601a288Laurent Pinchart get_resource(res, plane_res, plane, Plane); 60802fa8f79b05456184028f014432647b19601a288Laurent Pinchart get_properties(res, plane_res, plane, PLANE); 60902fa8f79b05456184028f014432647b19601a288Laurent Pinchart 61002fa8f79b05456184028f014432647b19601a288Laurent Pinchart return res; 61102fa8f79b05456184028f014432647b19601a288Laurent Pinchart 61202fa8f79b05456184028f014432647b19601a288Laurent Pincharterror: 61302fa8f79b05456184028f014432647b19601a288Laurent Pinchart free_resources(res); 61402fa8f79b05456184028f014432647b19601a288Laurent Pinchart return NULL; 61502fa8f79b05456184028f014432647b19601a288Laurent Pinchart} 61602fa8f79b05456184028f014432647b19601a288Laurent Pinchart 617a4f2f1b9d1c0b6b7f740951525a14b3d328f0acfLaurent Pinchartstatic int get_crtc_index(struct device *dev, uint32_t id) 618a4f2f1b9d1c0b6b7f740951525a14b3d328f0acfLaurent Pinchart{ 619a4f2f1b9d1c0b6b7f740951525a14b3d328f0acfLaurent Pinchart int i; 620a4f2f1b9d1c0b6b7f740951525a14b3d328f0acfLaurent Pinchart 621a4f2f1b9d1c0b6b7f740951525a14b3d328f0acfLaurent Pinchart for (i = 0; i < dev->resources->res->count_crtcs; ++i) { 622a4f2f1b9d1c0b6b7f740951525a14b3d328f0acfLaurent Pinchart drmModeCrtc *crtc = dev->resources->crtcs[i].crtc; 623a4f2f1b9d1c0b6b7f740951525a14b3d328f0acfLaurent Pinchart if (crtc && crtc->crtc_id == id) 624a4f2f1b9d1c0b6b7f740951525a14b3d328f0acfLaurent Pinchart return i; 625a4f2f1b9d1c0b6b7f740951525a14b3d328f0acfLaurent Pinchart } 626a4f2f1b9d1c0b6b7f740951525a14b3d328f0acfLaurent Pinchart 627a4f2f1b9d1c0b6b7f740951525a14b3d328f0acfLaurent Pinchart return -1; 628a4f2f1b9d1c0b6b7f740951525a14b3d328f0acfLaurent Pinchart} 629a4f2f1b9d1c0b6b7f740951525a14b3d328f0acfLaurent Pinchart 630f05a74fb9cb07a02c9bade65d66ba6949a2567a2Thierry Redingstatic drmModeConnector *get_connector_by_name(struct device *dev, const char *name) 631f05a74fb9cb07a02c9bade65d66ba6949a2567a2Thierry Reding{ 632f05a74fb9cb07a02c9bade65d66ba6949a2567a2Thierry Reding struct connector *connector; 633f05a74fb9cb07a02c9bade65d66ba6949a2567a2Thierry Reding int i; 634f05a74fb9cb07a02c9bade65d66ba6949a2567a2Thierry Reding 635f05a74fb9cb07a02c9bade65d66ba6949a2567a2Thierry Reding for (i = 0; i < dev->resources->res->count_connectors; i++) { 636f05a74fb9cb07a02c9bade65d66ba6949a2567a2Thierry Reding connector = &dev->resources->connectors[i]; 637f05a74fb9cb07a02c9bade65d66ba6949a2567a2Thierry Reding 638f05a74fb9cb07a02c9bade65d66ba6949a2567a2Thierry Reding if (strcmp(connector->name, name) == 0) 639f05a74fb9cb07a02c9bade65d66ba6949a2567a2Thierry Reding return connector->connector; 640f05a74fb9cb07a02c9bade65d66ba6949a2567a2Thierry Reding } 641f05a74fb9cb07a02c9bade65d66ba6949a2567a2Thierry Reding 642f05a74fb9cb07a02c9bade65d66ba6949a2567a2Thierry Reding return NULL; 643f05a74fb9cb07a02c9bade65d66ba6949a2567a2Thierry Reding} 644f05a74fb9cb07a02c9bade65d66ba6949a2567a2Thierry Reding 6452c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchartstatic drmModeConnector *get_connector_by_id(struct device *dev, uint32_t id) 6462c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart{ 6472c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart drmModeConnector *connector; 6482c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart int i; 6492c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart 6502c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart for (i = 0; i < dev->resources->res->count_connectors; i++) { 6512c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart connector = dev->resources->connectors[i].connector; 6522c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart if (connector && connector->connector_id == id) 6532c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart return connector; 6542c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart } 6552c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart 6562c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart return NULL; 6572c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart} 6582c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart 6592c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchartstatic drmModeEncoder *get_encoder_by_id(struct device *dev, uint32_t id) 6602c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart{ 6612c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart drmModeEncoder *encoder; 6622c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart int i; 6632c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart 6642c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart for (i = 0; i < dev->resources->res->count_encoders; i++) { 6652c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart encoder = dev->resources->encoders[i].encoder; 6662c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart if (encoder && encoder->encoder_id == id) 6672c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart return encoder; 6682c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart } 6692c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart 6702c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart return NULL; 6712c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart} 6722c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart 673a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart/* ----------------------------------------------------------------------------- 674b1e0bdeb70b68754c6c4ab1c7d0161709960d49cLaurent Pinchart * Pipes and planes 675a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart */ 676a94ee624292bff96ea1d38e8a0a3fbeefec42fb6Laurent Pinchart 677731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes/* 678731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * Mode setting with the kernel interfaces is a bit of a chore. 679731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * First you have to find the connector in question and make sure the 680731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * requested mode is available. 681731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * Then you need to find the encoder attached to that connector so you 682731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * can bind it with a free crtc. 683731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes */ 684b1e0bdeb70b68754c6c4ab1c7d0161709960d49cLaurent Pinchartstruct pipe_arg { 685f05a74fb9cb07a02c9bade65d66ba6949a2567a2Thierry Reding const char **cons; 6862c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart uint32_t *con_ids; 6872c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart unsigned int num_cons; 688a6349d0a0f9d3e017ac761ba912279c7d1e94eb7Laurent Pinchart uint32_t crtc_id; 689669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg char mode_str[64]; 690cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart char format_str[5]; 691de0970203091618834e4753c14d5169770797800Vincent ABRIOU unsigned int vrefresh; 692cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart unsigned int fourcc; 6939fc85b4084b69fefab3dbdf1f6cf97ccb47c963aKristian Høgsberg drmModeModeInfo *mode; 694a6349d0a0f9d3e017ac761ba912279c7d1e94eb7Laurent Pinchart struct crtc *crtc; 6951e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg unsigned int fb_id[2], current_fb_id; 6961e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg struct timeval start; 6971e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg 6981e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg int swap_count; 699d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark}; 700d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark 70102fa8f79b05456184028f014432647b19601a288Laurent Pinchartstruct plane_arg { 702eabf199dffb0d42e959c50aa820b39228196e031Laurent Pinchart uint32_t crtc_id; /* the id of CRTC to bind to */ 7037badcca4925480ffdc4f3aa5efb88624ce451e70Laurent Pinchart bool has_position; 7047badcca4925480ffdc4f3aa5efb88624ce451e70Laurent Pinchart int32_t x, y; 705d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark uint32_t w, h; 706d8954154fe20036f442e249d964b575a7374c571Ilia Mirkin double scale; 707d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark unsigned int fb_id; 7084d760d7f46b96a88a2e5f21fa983c4806ece1219Joonyoung Shim struct bo *bo; 709b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark char format_str[5]; /* need to leave room for terminating \0 */ 7100375222c714e8b7ba55f12d5cb389383be1cf54dLaurent Pinchart unsigned int fourcc; 711d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark}; 712669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg 7132c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchartstatic drmModeModeInfo * 714de0970203091618834e4753c14d5169770797800Vincent ABRIOUconnector_find_mode(struct device *dev, uint32_t con_id, const char *mode_str, 715de0970203091618834e4753c14d5169770797800Vincent ABRIOU const unsigned int vrefresh) 716731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes{ 717731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes drmModeConnector *connector; 7182c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart drmModeModeInfo *mode; 7192c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart int i; 720731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 7212c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart connector = get_connector_by_id(dev, con_id); 7222c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart if (!connector || !connector->count_modes) 7232c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart return NULL; 7242c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart 7252c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart for (i = 0; i < connector->count_modes; i++) { 7262c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart mode = &connector->modes[i]; 727de0970203091618834e4753c14d5169770797800Vincent ABRIOU if (!strcmp(mode->name, mode_str)) { 728de0970203091618834e4753c14d5169770797800Vincent ABRIOU /* If the vertical refresh frequency is not specified then return the 729de0970203091618834e4753c14d5169770797800Vincent ABRIOU * first mode that match with the name. Else, return the mode that match 730de0970203091618834e4753c14d5169770797800Vincent ABRIOU * the name and the specified vertical refresh frequency. 731de0970203091618834e4753c14d5169770797800Vincent ABRIOU */ 732de0970203091618834e4753c14d5169770797800Vincent ABRIOU if (vrefresh == 0) 733de0970203091618834e4753c14d5169770797800Vincent ABRIOU return mode; 734de0970203091618834e4753c14d5169770797800Vincent ABRIOU else if (mode->vrefresh == vrefresh) 735de0970203091618834e4753c14d5169770797800Vincent ABRIOU return mode; 736de0970203091618834e4753c14d5169770797800Vincent ABRIOU } 7372c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart } 7382c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart 7392c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart return NULL; 7402c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart} 7412c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart 7422c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchartstatic struct crtc *pipe_find_crtc(struct device *dev, struct pipe_arg *pipe) 7432c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart{ 7442c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart uint32_t possible_crtcs = ~0; 7452c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart uint32_t active_crtcs = 0; 7462c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart unsigned int crtc_idx; 7472c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart unsigned int i; 7482c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart int j; 7492c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart 7502c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart for (i = 0; i < pipe->num_cons; ++i) { 751a4f2f1b9d1c0b6b7f740951525a14b3d328f0acfLaurent Pinchart uint32_t crtcs_for_connector = 0; 7522c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart drmModeConnector *connector; 7532c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart drmModeEncoder *encoder; 754a4f2f1b9d1c0b6b7f740951525a14b3d328f0acfLaurent Pinchart int idx; 7552c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart 7562c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart connector = get_connector_by_id(dev, pipe->con_ids[i]); 75702fa8f79b05456184028f014432647b19601a288Laurent Pinchart if (!connector) 7582c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart return NULL; 759731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 760a4f2f1b9d1c0b6b7f740951525a14b3d328f0acfLaurent Pinchart for (j = 0; j < connector->count_encoders; ++j) { 761a4f2f1b9d1c0b6b7f740951525a14b3d328f0acfLaurent Pinchart encoder = get_encoder_by_id(dev, connector->encoders[j]); 762a4f2f1b9d1c0b6b7f740951525a14b3d328f0acfLaurent Pinchart if (!encoder) 763a4f2f1b9d1c0b6b7f740951525a14b3d328f0acfLaurent Pinchart continue; 764731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 765a4f2f1b9d1c0b6b7f740951525a14b3d328f0acfLaurent Pinchart crtcs_for_connector |= encoder->possible_crtcs; 766731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 767a4f2f1b9d1c0b6b7f740951525a14b3d328f0acfLaurent Pinchart idx = get_crtc_index(dev, encoder->crtc_id); 768a4f2f1b9d1c0b6b7f740951525a14b3d328f0acfLaurent Pinchart if (idx >= 0) 769a4f2f1b9d1c0b6b7f740951525a14b3d328f0acfLaurent Pinchart active_crtcs |= 1 << idx; 770731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes } 771a4f2f1b9d1c0b6b7f740951525a14b3d328f0acfLaurent Pinchart 772a4f2f1b9d1c0b6b7f740951525a14b3d328f0acfLaurent Pinchart possible_crtcs &= crtcs_for_connector; 773731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes } 774731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 7752c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart if (!possible_crtcs) 7762c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart return NULL; 7772c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart 7782c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart /* Return the first possible and active CRTC if one exists, or the first 7792c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart * possible CRTC otherwise. 7802c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart */ 7812c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart if (possible_crtcs & active_crtcs) 7822c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart crtc_idx = ffs(possible_crtcs & active_crtcs); 7832c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart else 7842c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart crtc_idx = ffs(possible_crtcs); 7852c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart 7862c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart return &dev->resources->crtcs[crtc_idx - 1]; 7872c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart} 7882c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart 7892c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchartstatic int pipe_find_crtc_and_mode(struct device *dev, struct pipe_arg *pipe) 7902c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart{ 7914a8da02e524d5d70ec638477e36fcafd2c8152ecEmil Velikov drmModeModeInfo *mode = NULL; 7922c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart int i; 7932c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart 7942c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart pipe->mode = NULL; 7952c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart 7962c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart for (i = 0; i < (int)pipe->num_cons; i++) { 7972c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart mode = connector_find_mode(dev, pipe->con_ids[i], 798de0970203091618834e4753c14d5169770797800Vincent ABRIOU pipe->mode_str, pipe->vrefresh); 7992c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart if (mode == NULL) { 8002c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart fprintf(stderr, 801f05a74fb9cb07a02c9bade65d66ba6949a2567a2Thierry Reding "failed to find mode \"%s\" for connector %s\n", 802f05a74fb9cb07a02c9bade65d66ba6949a2567a2Thierry Reding pipe->mode_str, pipe->cons[i]); 8032c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart return -EINVAL; 8042c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart } 805731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes } 806731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 807a6349d0a0f9d3e017ac761ba912279c7d1e94eb7Laurent Pinchart /* If the CRTC ID was specified, get the corresponding CRTC. Otherwise 8082c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart * locate a CRTC that can be attached to all the connectors. 809a6349d0a0f9d3e017ac761ba912279c7d1e94eb7Laurent Pinchart */ 8102c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart if (pipe->crtc_id != (uint32_t)-1) { 8112c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart for (i = 0; i < dev->resources->res->count_crtcs; i++) { 8122c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart struct crtc *crtc = &dev->resources->crtcs[i]; 8132c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart 8142c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart if (pipe->crtc_id == crtc->crtc->crtc_id) { 8152c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart pipe->crtc = crtc; 816a6349d0a0f9d3e017ac761ba912279c7d1e94eb7Laurent Pinchart break; 817a6349d0a0f9d3e017ac761ba912279c7d1e94eb7Laurent Pinchart } 818a6349d0a0f9d3e017ac761ba912279c7d1e94eb7Laurent Pinchart } 8192c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart } else { 8202c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart pipe->crtc = pipe_find_crtc(dev, pipe); 821a6349d0a0f9d3e017ac761ba912279c7d1e94eb7Laurent Pinchart } 822a6349d0a0f9d3e017ac761ba912279c7d1e94eb7Laurent Pinchart 8232c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart if (!pipe->crtc) { 8242c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart fprintf(stderr, "failed to find CRTC for pipe\n"); 8252c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart return -EINVAL; 8262c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart } 827731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 8282c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart pipe->mode = mode; 8292c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart pipe->crtc->mode = mode; 830a6349d0a0f9d3e017ac761ba912279c7d1e94eb7Laurent Pinchart 8312c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart return 0; 832669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg} 833669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg 834d725227cec822b8cfbeb541be17aae30b7612b9fLaurent Pinchart/* ----------------------------------------------------------------------------- 835d725227cec822b8cfbeb541be17aae30b7612b9fLaurent Pinchart * Properties 836d725227cec822b8cfbeb541be17aae30b7612b9fLaurent Pinchart */ 837d725227cec822b8cfbeb541be17aae30b7612b9fLaurent Pinchart 838d725227cec822b8cfbeb541be17aae30b7612b9fLaurent Pinchartstruct property_arg { 839d725227cec822b8cfbeb541be17aae30b7612b9fLaurent Pinchart uint32_t obj_id; 840d725227cec822b8cfbeb541be17aae30b7612b9fLaurent Pinchart uint32_t obj_type; 841d725227cec822b8cfbeb541be17aae30b7612b9fLaurent Pinchart char name[DRM_PROP_NAME_LEN+1]; 842d725227cec822b8cfbeb541be17aae30b7612b9fLaurent Pinchart uint32_t prop_id; 843d725227cec822b8cfbeb541be17aae30b7612b9fLaurent Pinchart uint64_t value; 844d725227cec822b8cfbeb541be17aae30b7612b9fLaurent Pinchart}; 845d725227cec822b8cfbeb541be17aae30b7612b9fLaurent Pinchart 846549fe0ba627a67b6ae1334eb5cf274a3dfb1fd69Laurent Pinchartstatic void set_property(struct device *dev, struct property_arg *p) 847d725227cec822b8cfbeb541be17aae30b7612b9fLaurent Pinchart{ 8484a8da02e524d5d70ec638477e36fcafd2c8152ecEmil Velikov drmModeObjectProperties *props = NULL; 8494a8da02e524d5d70ec638477e36fcafd2c8152ecEmil Velikov drmModePropertyRes **props_info = NULL; 850d725227cec822b8cfbeb541be17aae30b7612b9fLaurent Pinchart const char *obj_type; 851d725227cec822b8cfbeb541be17aae30b7612b9fLaurent Pinchart int ret; 852d725227cec822b8cfbeb541be17aae30b7612b9fLaurent Pinchart int i; 853d725227cec822b8cfbeb541be17aae30b7612b9fLaurent Pinchart 854d725227cec822b8cfbeb541be17aae30b7612b9fLaurent Pinchart p->obj_type = 0; 855d725227cec822b8cfbeb541be17aae30b7612b9fLaurent Pinchart p->prop_id = 0; 856d725227cec822b8cfbeb541be17aae30b7612b9fLaurent Pinchart 857d725227cec822b8cfbeb541be17aae30b7612b9fLaurent Pinchart#define find_object(_res, __res, type, Type) \ 858d725227cec822b8cfbeb541be17aae30b7612b9fLaurent Pinchart do { \ 859d725227cec822b8cfbeb541be17aae30b7612b9fLaurent Pinchart for (i = 0; i < (int)(_res)->__res->count_##type##s; ++i) { \ 860d725227cec822b8cfbeb541be17aae30b7612b9fLaurent Pinchart struct type *obj = &(_res)->type##s[i]; \ 861d725227cec822b8cfbeb541be17aae30b7612b9fLaurent Pinchart if (obj->type->type##_id != p->obj_id) \ 862d725227cec822b8cfbeb541be17aae30b7612b9fLaurent Pinchart continue; \ 863d725227cec822b8cfbeb541be17aae30b7612b9fLaurent Pinchart p->obj_type = DRM_MODE_OBJECT_##Type; \ 864d725227cec822b8cfbeb541be17aae30b7612b9fLaurent Pinchart obj_type = #Type; \ 865d725227cec822b8cfbeb541be17aae30b7612b9fLaurent Pinchart props = obj->props; \ 866d725227cec822b8cfbeb541be17aae30b7612b9fLaurent Pinchart props_info = obj->props_info; \ 867d725227cec822b8cfbeb541be17aae30b7612b9fLaurent Pinchart } \ 868d725227cec822b8cfbeb541be17aae30b7612b9fLaurent Pinchart } while(0) \ 869d725227cec822b8cfbeb541be17aae30b7612b9fLaurent Pinchart 870549fe0ba627a67b6ae1334eb5cf274a3dfb1fd69Laurent Pinchart find_object(dev->resources, res, crtc, CRTC); 871d725227cec822b8cfbeb541be17aae30b7612b9fLaurent Pinchart if (p->obj_type == 0) 872549fe0ba627a67b6ae1334eb5cf274a3dfb1fd69Laurent Pinchart find_object(dev->resources, res, connector, CONNECTOR); 873d725227cec822b8cfbeb541be17aae30b7612b9fLaurent Pinchart if (p->obj_type == 0) 874549fe0ba627a67b6ae1334eb5cf274a3dfb1fd69Laurent Pinchart find_object(dev->resources, plane_res, plane, PLANE); 875d725227cec822b8cfbeb541be17aae30b7612b9fLaurent Pinchart if (p->obj_type == 0) { 876d725227cec822b8cfbeb541be17aae30b7612b9fLaurent Pinchart fprintf(stderr, "Object %i not found, can't set property\n", 877d725227cec822b8cfbeb541be17aae30b7612b9fLaurent Pinchart p->obj_id); 878d725227cec822b8cfbeb541be17aae30b7612b9fLaurent Pinchart return; 879d725227cec822b8cfbeb541be17aae30b7612b9fLaurent Pinchart } 880d725227cec822b8cfbeb541be17aae30b7612b9fLaurent Pinchart 881d725227cec822b8cfbeb541be17aae30b7612b9fLaurent Pinchart if (!props) { 882d725227cec822b8cfbeb541be17aae30b7612b9fLaurent Pinchart fprintf(stderr, "%s %i has no properties\n", 883d725227cec822b8cfbeb541be17aae30b7612b9fLaurent Pinchart obj_type, p->obj_id); 884d725227cec822b8cfbeb541be17aae30b7612b9fLaurent Pinchart return; 885d725227cec822b8cfbeb541be17aae30b7612b9fLaurent Pinchart } 886d725227cec822b8cfbeb541be17aae30b7612b9fLaurent Pinchart 887d725227cec822b8cfbeb541be17aae30b7612b9fLaurent Pinchart for (i = 0; i < (int)props->count_props; ++i) { 888d725227cec822b8cfbeb541be17aae30b7612b9fLaurent Pinchart if (!props_info[i]) 889d725227cec822b8cfbeb541be17aae30b7612b9fLaurent Pinchart continue; 890d725227cec822b8cfbeb541be17aae30b7612b9fLaurent Pinchart if (strcmp(props_info[i]->name, p->name) == 0) 891d725227cec822b8cfbeb541be17aae30b7612b9fLaurent Pinchart break; 892d725227cec822b8cfbeb541be17aae30b7612b9fLaurent Pinchart } 893d725227cec822b8cfbeb541be17aae30b7612b9fLaurent Pinchart 894d725227cec822b8cfbeb541be17aae30b7612b9fLaurent Pinchart if (i == (int)props->count_props) { 895d725227cec822b8cfbeb541be17aae30b7612b9fLaurent Pinchart fprintf(stderr, "%s %i has no %s property\n", 896d725227cec822b8cfbeb541be17aae30b7612b9fLaurent Pinchart obj_type, p->obj_id, p->name); 897d725227cec822b8cfbeb541be17aae30b7612b9fLaurent Pinchart return; 898d725227cec822b8cfbeb541be17aae30b7612b9fLaurent Pinchart } 899d725227cec822b8cfbeb541be17aae30b7612b9fLaurent Pinchart 900d725227cec822b8cfbeb541be17aae30b7612b9fLaurent Pinchart p->prop_id = props->props[i]; 901d725227cec822b8cfbeb541be17aae30b7612b9fLaurent Pinchart 902549fe0ba627a67b6ae1334eb5cf274a3dfb1fd69Laurent Pinchart ret = drmModeObjectSetProperty(dev->fd, p->obj_id, p->obj_type, 903549fe0ba627a67b6ae1334eb5cf274a3dfb1fd69Laurent Pinchart p->prop_id, p->value); 904d725227cec822b8cfbeb541be17aae30b7612b9fLaurent Pinchart if (ret < 0) 905d725227cec822b8cfbeb541be17aae30b7612b9fLaurent Pinchart fprintf(stderr, "failed to set %s %i property %s to %" PRIu64 ": %s\n", 906d725227cec822b8cfbeb541be17aae30b7612b9fLaurent Pinchart obj_type, p->obj_id, p->name, p->value, strerror(errno)); 907d725227cec822b8cfbeb541be17aae30b7612b9fLaurent Pinchart} 908d725227cec822b8cfbeb541be17aae30b7612b9fLaurent Pinchart 9093fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart/* -------------------------------------------------------------------------- */ 9103fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart 911ca9c8f06e0f560082dcd0943e9be29ba9a915ee3Laurent Pinchartstatic void 9123fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchartpage_flip_handler(int fd, unsigned int frame, 9133fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart unsigned int sec, unsigned int usec, void *data) 9143fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart{ 915b1e0bdeb70b68754c6c4ab1c7d0161709960d49cLaurent Pinchart struct pipe_arg *pipe; 9163fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart unsigned int new_fb_id; 9173fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart struct timeval end; 9183fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart double t; 9193fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart 920b1e0bdeb70b68754c6c4ab1c7d0161709960d49cLaurent Pinchart pipe = data; 921b1e0bdeb70b68754c6c4ab1c7d0161709960d49cLaurent Pinchart if (pipe->current_fb_id == pipe->fb_id[0]) 922b1e0bdeb70b68754c6c4ab1c7d0161709960d49cLaurent Pinchart new_fb_id = pipe->fb_id[1]; 9233fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart else 924b1e0bdeb70b68754c6c4ab1c7d0161709960d49cLaurent Pinchart new_fb_id = pipe->fb_id[0]; 9253fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart 9262c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart drmModePageFlip(fd, pipe->crtc->crtc->crtc_id, new_fb_id, 927b1e0bdeb70b68754c6c4ab1c7d0161709960d49cLaurent Pinchart DRM_MODE_PAGE_FLIP_EVENT, pipe); 928b1e0bdeb70b68754c6c4ab1c7d0161709960d49cLaurent Pinchart pipe->current_fb_id = new_fb_id; 929b1e0bdeb70b68754c6c4ab1c7d0161709960d49cLaurent Pinchart pipe->swap_count++; 930b1e0bdeb70b68754c6c4ab1c7d0161709960d49cLaurent Pinchart if (pipe->swap_count == 60) { 9313fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart gettimeofday(&end, NULL); 9323fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart t = end.tv_sec + end.tv_usec * 1e-6 - 933b1e0bdeb70b68754c6c4ab1c7d0161709960d49cLaurent Pinchart (pipe->start.tv_sec + pipe->start.tv_usec * 1e-6); 934b1e0bdeb70b68754c6c4ab1c7d0161709960d49cLaurent Pinchart fprintf(stderr, "freq: %.02fHz\n", pipe->swap_count / t); 935b1e0bdeb70b68754c6c4ab1c7d0161709960d49cLaurent Pinchart pipe->swap_count = 0; 936b1e0bdeb70b68754c6c4ab1c7d0161709960d49cLaurent Pinchart pipe->start = end; 9373fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart } 9383fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart} 9393fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart 940360a7eacd4961ceab72554d36917f031a05ed030Tobias Jakobistatic bool format_support(const drmModePlanePtr ovr, uint32_t fmt) 941360a7eacd4961ceab72554d36917f031a05ed030Tobias Jakobi{ 942360a7eacd4961ceab72554d36917f031a05ed030Tobias Jakobi unsigned int i; 943360a7eacd4961ceab72554d36917f031a05ed030Tobias Jakobi 944360a7eacd4961ceab72554d36917f031a05ed030Tobias Jakobi for (i = 0; i < ovr->count_formats; ++i) { 945360a7eacd4961ceab72554d36917f031a05ed030Tobias Jakobi if (ovr->formats[i] == fmt) 946360a7eacd4961ceab72554d36917f031a05ed030Tobias Jakobi return true; 947360a7eacd4961ceab72554d36917f031a05ed030Tobias Jakobi } 948360a7eacd4961ceab72554d36917f031a05ed030Tobias Jakobi 949360a7eacd4961ceab72554d36917f031a05ed030Tobias Jakobi return false; 950360a7eacd4961ceab72554d36917f031a05ed030Tobias Jakobi} 951360a7eacd4961ceab72554d36917f031a05ed030Tobias Jakobi 952eabf199dffb0d42e959c50aa820b39228196e031Laurent Pinchartstatic int set_plane(struct device *dev, struct plane_arg *p) 953d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark{ 954d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark drmModePlane *ovr; 955b1d19de76468fdb4ae7cb87791c77d1f8839a573Tobias Jakobi uint32_t handles[4] = {0}, pitches[4] = {0}, offsets[4] = {0}; 956d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark uint32_t plane_id = 0; 957d7c0a08bc576deb07df6c3f91f393ca8edd0c4bfLaurent Pinchart struct bo *plane_bo; 9580375222c714e8b7ba55f12d5cb389383be1cf54dLaurent Pinchart uint32_t plane_flags = 0; 959ca9c8f06e0f560082dcd0943e9be29ba9a915ee3Laurent Pinchart int crtc_x, crtc_y, crtc_w, crtc_h; 9603813e0f8e1ee4885823cdd0b50b05970257adddcLaurent Pinchart struct crtc *crtc = NULL; 961605efd7e05e94b8d9d742d3a8af1040776e2742dLaurent Pinchart unsigned int pipe; 9629b44fbd393b8db571badae41881f490145404ae0Paulo Zanoni unsigned int i; 963d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark 964605efd7e05e94b8d9d742d3a8af1040776e2742dLaurent Pinchart /* Find an unused plane which can be connected to our CRTC. Find the 965605efd7e05e94b8d9d742d3a8af1040776e2742dLaurent Pinchart * CRTC index first, then iterate over available planes. 966605efd7e05e94b8d9d742d3a8af1040776e2742dLaurent Pinchart */ 967605efd7e05e94b8d9d742d3a8af1040776e2742dLaurent Pinchart for (i = 0; i < (unsigned int)dev->resources->res->count_crtcs; i++) { 968eabf199dffb0d42e959c50aa820b39228196e031Laurent Pinchart if (p->crtc_id == dev->resources->res->crtcs[i]) { 969eabf199dffb0d42e959c50aa820b39228196e031Laurent Pinchart crtc = &dev->resources->crtcs[i]; 970605efd7e05e94b8d9d742d3a8af1040776e2742dLaurent Pinchart pipe = i; 971605efd7e05e94b8d9d742d3a8af1040776e2742dLaurent Pinchart break; 972605efd7e05e94b8d9d742d3a8af1040776e2742dLaurent Pinchart } 973605efd7e05e94b8d9d742d3a8af1040776e2742dLaurent Pinchart } 974605efd7e05e94b8d9d742d3a8af1040776e2742dLaurent Pinchart 975eabf199dffb0d42e959c50aa820b39228196e031Laurent Pinchart if (!crtc) { 976eabf199dffb0d42e959c50aa820b39228196e031Laurent Pinchart fprintf(stderr, "CRTC %u not found\n", p->crtc_id); 977605efd7e05e94b8d9d742d3a8af1040776e2742dLaurent Pinchart return -1; 978605efd7e05e94b8d9d742d3a8af1040776e2742dLaurent Pinchart } 979605efd7e05e94b8d9d742d3a8af1040776e2742dLaurent Pinchart 980549fe0ba627a67b6ae1334eb5cf274a3dfb1fd69Laurent Pinchart for (i = 0; i < dev->resources->plane_res->count_planes && !plane_id; i++) { 981549fe0ba627a67b6ae1334eb5cf274a3dfb1fd69Laurent Pinchart ovr = dev->resources->planes[i].plane; 982360a7eacd4961ceab72554d36917f031a05ed030Tobias Jakobi if (!ovr || !format_support(ovr, p->fourcc)) 98302fa8f79b05456184028f014432647b19601a288Laurent Pinchart continue; 984d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark 985605efd7e05e94b8d9d742d3a8af1040776e2742dLaurent Pinchart if ((ovr->possible_crtcs & (1 << pipe)) && !ovr->crtc_id) 986d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark plane_id = ovr->plane_id; 987d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark } 988d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark 989d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark if (!plane_id) { 990eabf199dffb0d42e959c50aa820b39228196e031Laurent Pinchart fprintf(stderr, "no unused plane available for CRTC %u\n", 991eabf199dffb0d42e959c50aa820b39228196e031Laurent Pinchart crtc->crtc->crtc_id); 992d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark return -1; 993d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark } 994d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark 995581c7cf86a96a81e76288c8abca03c7f29eac3afLaurent Pinchart fprintf(stderr, "testing %dx%d@%s overlay plane %u\n", 996581c7cf86a96a81e76288c8abca03c7f29eac3afLaurent Pinchart p->w, p->h, p->format_str, plane_id); 997581c7cf86a96a81e76288c8abca03c7f29eac3afLaurent Pinchart 998d7c0a08bc576deb07df6c3f91f393ca8edd0c4bfLaurent Pinchart plane_bo = bo_create(dev->fd, p->fourcc, p->w, p->h, handles, 9991ec3c44bdd38051d870f64d0b2cc7dbd59760386Thierry Reding pitches, offsets, UTIL_PATTERN_TILES); 10003fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart if (plane_bo == NULL) 10013fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart return -1; 1002d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark 10034d760d7f46b96a88a2e5f21fa983c4806ece1219Joonyoung Shim p->bo = plane_bo; 10044d760d7f46b96a88a2e5f21fa983c4806ece1219Joonyoung Shim 1005d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark /* just use single plane format for now.. */ 1006549fe0ba627a67b6ae1334eb5cf274a3dfb1fd69Laurent Pinchart if (drmModeAddFB2(dev->fd, p->w, p->h, p->fourcc, 1007d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark handles, pitches, offsets, &p->fb_id, plane_flags)) { 1008d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark fprintf(stderr, "failed to add fb: %s\n", strerror(errno)); 1009d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark return -1; 1010d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark } 1011d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark 1012d8954154fe20036f442e249d964b575a7374c571Ilia Mirkin crtc_w = p->w * p->scale; 1013d8954154fe20036f442e249d964b575a7374c571Ilia Mirkin crtc_h = p->h * p->scale; 10147badcca4925480ffdc4f3aa5efb88624ce451e70Laurent Pinchart if (!p->has_position) { 10157badcca4925480ffdc4f3aa5efb88624ce451e70Laurent Pinchart /* Default to the middle of the screen */ 1016d8954154fe20036f442e249d964b575a7374c571Ilia Mirkin crtc_x = (crtc->mode->hdisplay - crtc_w) / 2; 1017d8954154fe20036f442e249d964b575a7374c571Ilia Mirkin crtc_y = (crtc->mode->vdisplay - crtc_h) / 2; 10187badcca4925480ffdc4f3aa5efb88624ce451e70Laurent Pinchart } else { 10197badcca4925480ffdc4f3aa5efb88624ce451e70Laurent Pinchart crtc_x = p->x; 10207badcca4925480ffdc4f3aa5efb88624ce451e70Laurent Pinchart crtc_y = p->y; 10217badcca4925480ffdc4f3aa5efb88624ce451e70Laurent Pinchart } 1022d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark 1023d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark /* note src coords (last 4 args) are in Q16 format */ 1024eabf199dffb0d42e959c50aa820b39228196e031Laurent Pinchart if (drmModeSetPlane(dev->fd, plane_id, crtc->crtc->crtc_id, p->fb_id, 1025d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark plane_flags, crtc_x, crtc_y, crtc_w, crtc_h, 1026d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark 0, 0, p->w << 16, p->h << 16)) { 1027d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark fprintf(stderr, "failed to enable plane: %s\n", 1028d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark strerror(errno)); 1029d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark return -1; 1030d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark } 1031d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark 1032eabf199dffb0d42e959c50aa820b39228196e031Laurent Pinchart ovr->crtc_id = crtc->crtc->crtc_id; 103302fa8f79b05456184028f014432647b19601a288Laurent Pinchart 1034d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark return 0; 1035d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark} 1036d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark 10374d760d7f46b96a88a2e5f21fa983c4806ece1219Joonyoung Shimstatic void clear_planes(struct device *dev, struct plane_arg *p, unsigned int count) 10384d760d7f46b96a88a2e5f21fa983c4806ece1219Joonyoung Shim{ 10394d760d7f46b96a88a2e5f21fa983c4806ece1219Joonyoung Shim unsigned int i; 10404d760d7f46b96a88a2e5f21fa983c4806ece1219Joonyoung Shim 10414d760d7f46b96a88a2e5f21fa983c4806ece1219Joonyoung Shim for (i = 0; i < count; i++) { 10424d760d7f46b96a88a2e5f21fa983c4806ece1219Joonyoung Shim if (p[i].fb_id) 10434d760d7f46b96a88a2e5f21fa983c4806ece1219Joonyoung Shim drmModeRmFB(dev->fd, p[i].fb_id); 10444d760d7f46b96a88a2e5f21fa983c4806ece1219Joonyoung Shim if (p[i].bo) 10454d760d7f46b96a88a2e5f21fa983c4806ece1219Joonyoung Shim bo_destroy(p[i].bo); 10464d760d7f46b96a88a2e5f21fa983c4806ece1219Joonyoung Shim } 10474d760d7f46b96a88a2e5f21fa983c4806ece1219Joonyoung Shim} 10484d760d7f46b96a88a2e5f21fa983c4806ece1219Joonyoung Shim 10494d760d7f46b96a88a2e5f21fa983c4806ece1219Joonyoung Shim 1050b1e0bdeb70b68754c6c4ab1c7d0161709960d49cLaurent Pinchartstatic void set_mode(struct device *dev, struct pipe_arg *pipes, unsigned int count) 10517a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg{ 1052b1d19de76468fdb4ae7cb87791c77d1f8839a573Tobias Jakobi uint32_t handles[4] = {0}, pitches[4] = {0}, offsets[4] = {0}; 10533813e0f8e1ee4885823cdd0b50b05970257adddcLaurent Pinchart unsigned int fb_id; 1054d7c0a08bc576deb07df6c3f91f393ca8edd0c4bfLaurent Pinchart struct bo *bo; 10553813e0f8e1ee4885823cdd0b50b05970257adddcLaurent Pinchart unsigned int i; 10562c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart unsigned int j; 10573813e0f8e1ee4885823cdd0b50b05970257adddcLaurent Pinchart int ret, x; 10583813e0f8e1ee4885823cdd0b50b05970257adddcLaurent Pinchart 10593813e0f8e1ee4885823cdd0b50b05970257adddcLaurent Pinchart dev->mode.width = 0; 10603813e0f8e1ee4885823cdd0b50b05970257adddcLaurent Pinchart dev->mode.height = 0; 1061bcaaa75cf482c7d218340c850ffc01f04b78b3ddJoonyoung Shim dev->mode.fb_id = 0; 10627a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg 10637a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg for (i = 0; i < count; i++) { 1064b1e0bdeb70b68754c6c4ab1c7d0161709960d49cLaurent Pinchart struct pipe_arg *pipe = &pipes[i]; 1065b1e0bdeb70b68754c6c4ab1c7d0161709960d49cLaurent Pinchart 10662c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart ret = pipe_find_crtc_and_mode(dev, pipe); 10672c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart if (ret < 0) 10687a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg continue; 10692c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart 1070b1e0bdeb70b68754c6c4ab1c7d0161709960d49cLaurent Pinchart dev->mode.width += pipe->mode->hdisplay; 1071b1e0bdeb70b68754c6c4ab1c7d0161709960d49cLaurent Pinchart if (dev->mode.height < pipe->mode->vdisplay) 1072b1e0bdeb70b68754c6c4ab1c7d0161709960d49cLaurent Pinchart dev->mode.height = pipe->mode->vdisplay; 10737a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg } 10747a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg 10751ec3c44bdd38051d870f64d0b2cc7dbd59760386Thierry Reding bo = bo_create(dev->fd, pipes[0].fourcc, dev->mode.width, 10761ec3c44bdd38051d870f64d0b2cc7dbd59760386Thierry Reding dev->mode.height, handles, pitches, offsets, 10771ec3c44bdd38051d870f64d0b2cc7dbd59760386Thierry Reding UTIL_PATTERN_SMPTE); 10783fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart if (bo == NULL) 10797a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg return; 1080731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 108121170a8c63d2e994317b785f7f7e78ab7e0a4ac4Joonyoung Shim dev->mode.bo = bo; 108221170a8c63d2e994317b785f7f7e78ab7e0a4ac4Joonyoung Shim 1083b1e0bdeb70b68754c6c4ab1c7d0161709960d49cLaurent Pinchart ret = drmModeAddFB2(dev->fd, dev->mode.width, dev->mode.height, 1084b1e0bdeb70b68754c6c4ab1c7d0161709960d49cLaurent Pinchart pipes[0].fourcc, handles, pitches, offsets, &fb_id, 0); 1085731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes if (ret) { 1086680b9c4fa3dfb329bd74ec08c17cfc876ea2fc5bJakob Bornecrantz fprintf(stderr, "failed to add fb (%ux%u): %s\n", 10873813e0f8e1ee4885823cdd0b50b05970257adddcLaurent Pinchart dev->mode.width, dev->mode.height, strerror(errno)); 1088731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes return; 1089731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes } 1090731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 109121170a8c63d2e994317b785f7f7e78ab7e0a4ac4Joonyoung Shim dev->mode.fb_id = fb_id; 109221170a8c63d2e994317b785f7f7e78ab7e0a4ac4Joonyoung Shim 1093669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg x = 0; 1094669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg for (i = 0; i < count; i++) { 1095b1e0bdeb70b68754c6c4ab1c7d0161709960d49cLaurent Pinchart struct pipe_arg *pipe = &pipes[i]; 1096b1e0bdeb70b68754c6c4ab1c7d0161709960d49cLaurent Pinchart 1097b1e0bdeb70b68754c6c4ab1c7d0161709960d49cLaurent Pinchart if (pipe->mode == NULL) 1098669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg continue; 10998b8803695b24d4cb4d041437a4709be06e59471bKristian Høgsberg 1100de0970203091618834e4753c14d5169770797800Vincent ABRIOU printf("setting mode %s-%dHz@%s on connectors ", 1101de0970203091618834e4753c14d5169770797800Vincent ABRIOU pipe->mode_str, pipe->mode->vrefresh, pipe->format_str); 11022c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart for (j = 0; j < pipe->num_cons; ++j) 1103f05a74fb9cb07a02c9bade65d66ba6949a2567a2Thierry Reding printf("%s, ", pipe->cons[j]); 11042c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart printf("crtc %d\n", pipe->crtc->crtc->crtc_id); 11058b8803695b24d4cb4d041437a4709be06e59471bKristian Høgsberg 11062c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart ret = drmModeSetCrtc(dev->fd, pipe->crtc->crtc->crtc_id, fb_id, 11072c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart x, 0, pipe->con_ids, pipe->num_cons, 11082c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart pipe->mode); 1109d23146f3f0ad14c8ad482a4832cae859c8d646f2Jakob Bornecrantz 1110d23146f3f0ad14c8ad482a4832cae859c8d646f2Jakob Bornecrantz /* XXX: Actually check if this is needed */ 1111549fe0ba627a67b6ae1334eb5cf274a3dfb1fd69Laurent Pinchart drmModeDirtyFB(dev->fd, fb_id, NULL, 0); 1112d23146f3f0ad14c8ad482a4832cae859c8d646f2Jakob Bornecrantz 1113b1e0bdeb70b68754c6c4ab1c7d0161709960d49cLaurent Pinchart x += pipe->mode->hdisplay; 1114669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg 1115669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg if (ret) { 1116669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg fprintf(stderr, "failed to set mode: %s\n", strerror(errno)); 1117669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg return; 1118669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg } 1119731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes } 11203813e0f8e1ee4885823cdd0b50b05970257adddcLaurent Pinchart} 11211e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg 11224e4d79d4cae92c5ec29882cea9b8f7e8355f1232Joonyoung Shimstatic void clear_mode(struct device *dev) 11234e4d79d4cae92c5ec29882cea9b8f7e8355f1232Joonyoung Shim{ 1124bcaaa75cf482c7d218340c850ffc01f04b78b3ddJoonyoung Shim if (dev->mode.fb_id) 1125bcaaa75cf482c7d218340c850ffc01f04b78b3ddJoonyoung Shim drmModeRmFB(dev->fd, dev->mode.fb_id); 11264e4d79d4cae92c5ec29882cea9b8f7e8355f1232Joonyoung Shim if (dev->mode.bo) 11274e4d79d4cae92c5ec29882cea9b8f7e8355f1232Joonyoung Shim bo_destroy(dev->mode.bo); 11283813e0f8e1ee4885823cdd0b50b05970257adddcLaurent Pinchart} 11293813e0f8e1ee4885823cdd0b50b05970257adddcLaurent Pinchart 11303813e0f8e1ee4885823cdd0b50b05970257adddcLaurent Pinchartstatic void set_planes(struct device *dev, struct plane_arg *p, unsigned int count) 11313813e0f8e1ee4885823cdd0b50b05970257adddcLaurent Pinchart{ 11323813e0f8e1ee4885823cdd0b50b05970257adddcLaurent Pinchart unsigned int i; 11333813e0f8e1ee4885823cdd0b50b05970257adddcLaurent Pinchart 11343813e0f8e1ee4885823cdd0b50b05970257adddcLaurent Pinchart /* set up planes/overlays */ 11353813e0f8e1ee4885823cdd0b50b05970257adddcLaurent Pinchart for (i = 0; i < count; i++) 11363813e0f8e1ee4885823cdd0b50b05970257adddcLaurent Pinchart if (set_plane(dev, &p[i])) 11373813e0f8e1ee4885823cdd0b50b05970257adddcLaurent Pinchart return; 11383813e0f8e1ee4885823cdd0b50b05970257adddcLaurent Pinchart} 11393813e0f8e1ee4885823cdd0b50b05970257adddcLaurent Pinchart 11400e512794bf6281edfa4543ae7cc408d52ec6e2f3Rob Clarkstatic void set_cursors(struct device *dev, struct pipe_arg *pipes, unsigned int count) 11410e512794bf6281edfa4543ae7cc408d52ec6e2f3Rob Clark{ 1142b1d19de76468fdb4ae7cb87791c77d1f8839a573Tobias Jakobi uint32_t handles[4] = {0}, pitches[4] = {0}, offsets[4] = {0}; 1143d7c0a08bc576deb07df6c3f91f393ca8edd0c4bfLaurent Pinchart struct bo *bo; 11440e512794bf6281edfa4543ae7cc408d52ec6e2f3Rob Clark unsigned int i; 11450e512794bf6281edfa4543ae7cc408d52ec6e2f3Rob Clark int ret; 11460e512794bf6281edfa4543ae7cc408d52ec6e2f3Rob Clark 11470e512794bf6281edfa4543ae7cc408d52ec6e2f3Rob Clark /* maybe make cursor width/height configurable some day */ 11480e512794bf6281edfa4543ae7cc408d52ec6e2f3Rob Clark uint32_t cw = 64; 11490e512794bf6281edfa4543ae7cc408d52ec6e2f3Rob Clark uint32_t ch = 64; 11500e512794bf6281edfa4543ae7cc408d52ec6e2f3Rob Clark 11510e512794bf6281edfa4543ae7cc408d52ec6e2f3Rob Clark /* create cursor bo.. just using PATTERN_PLAIN as it has 11520e512794bf6281edfa4543ae7cc408d52ec6e2f3Rob Clark * translucent alpha 11530e512794bf6281edfa4543ae7cc408d52ec6e2f3Rob Clark */ 1154d7c0a08bc576deb07df6c3f91f393ca8edd0c4bfLaurent Pinchart bo = bo_create(dev->fd, DRM_FORMAT_ARGB8888, cw, ch, handles, pitches, 11551ec3c44bdd38051d870f64d0b2cc7dbd59760386Thierry Reding offsets, UTIL_PATTERN_PLAIN); 11560e512794bf6281edfa4543ae7cc408d52ec6e2f3Rob Clark if (bo == NULL) 11570e512794bf6281edfa4543ae7cc408d52ec6e2f3Rob Clark return; 11580e512794bf6281edfa4543ae7cc408d52ec6e2f3Rob Clark 11599915e68b3b4d69101f3cb6609e796fb8f63320e2Joonyoung Shim dev->mode.cursor_bo = bo; 11609915e68b3b4d69101f3cb6609e796fb8f63320e2Joonyoung Shim 11610e512794bf6281edfa4543ae7cc408d52ec6e2f3Rob Clark for (i = 0; i < count; i++) { 11620e512794bf6281edfa4543ae7cc408d52ec6e2f3Rob Clark struct pipe_arg *pipe = &pipes[i]; 11630e512794bf6281edfa4543ae7cc408d52ec6e2f3Rob Clark ret = cursor_init(dev->fd, handles[0], 11640e512794bf6281edfa4543ae7cc408d52ec6e2f3Rob Clark pipe->crtc->crtc->crtc_id, 11650e512794bf6281edfa4543ae7cc408d52ec6e2f3Rob Clark pipe->mode->hdisplay, pipe->mode->vdisplay, 11660e512794bf6281edfa4543ae7cc408d52ec6e2f3Rob Clark cw, ch); 11670e512794bf6281edfa4543ae7cc408d52ec6e2f3Rob Clark if (ret) { 11680e512794bf6281edfa4543ae7cc408d52ec6e2f3Rob Clark fprintf(stderr, "failed to init cursor for CRTC[%u]\n", 11690e512794bf6281edfa4543ae7cc408d52ec6e2f3Rob Clark pipe->crtc_id); 11700e512794bf6281edfa4543ae7cc408d52ec6e2f3Rob Clark return; 11710e512794bf6281edfa4543ae7cc408d52ec6e2f3Rob Clark } 11720e512794bf6281edfa4543ae7cc408d52ec6e2f3Rob Clark } 11730e512794bf6281edfa4543ae7cc408d52ec6e2f3Rob Clark 11740e512794bf6281edfa4543ae7cc408d52ec6e2f3Rob Clark cursor_start(); 11750e512794bf6281edfa4543ae7cc408d52ec6e2f3Rob Clark} 11760e512794bf6281edfa4543ae7cc408d52ec6e2f3Rob Clark 11770e512794bf6281edfa4543ae7cc408d52ec6e2f3Rob Clarkstatic void clear_cursors(struct device *dev) 11780e512794bf6281edfa4543ae7cc408d52ec6e2f3Rob Clark{ 11790e512794bf6281edfa4543ae7cc408d52ec6e2f3Rob Clark cursor_stop(); 11809915e68b3b4d69101f3cb6609e796fb8f63320e2Joonyoung Shim 11819915e68b3b4d69101f3cb6609e796fb8f63320e2Joonyoung Shim if (dev->mode.cursor_bo) 11829915e68b3b4d69101f3cb6609e796fb8f63320e2Joonyoung Shim bo_destroy(dev->mode.cursor_bo); 11830e512794bf6281edfa4543ae7cc408d52ec6e2f3Rob Clark} 11840e512794bf6281edfa4543ae7cc408d52ec6e2f3Rob Clark 1185b1e0bdeb70b68754c6c4ab1c7d0161709960d49cLaurent Pinchartstatic void test_page_flip(struct device *dev, struct pipe_arg *pipes, unsigned int count) 11863813e0f8e1ee4885823cdd0b50b05970257adddcLaurent Pinchart{ 1187b1d19de76468fdb4ae7cb87791c77d1f8839a573Tobias Jakobi uint32_t handles[4] = {0}, pitches[4] = {0}, offsets[4] = {0}; 11883813e0f8e1ee4885823cdd0b50b05970257adddcLaurent Pinchart unsigned int other_fb_id; 1189d7c0a08bc576deb07df6c3f91f393ca8edd0c4bfLaurent Pinchart struct bo *other_bo; 11903813e0f8e1ee4885823cdd0b50b05970257adddcLaurent Pinchart drmEventContext evctx; 11913813e0f8e1ee4885823cdd0b50b05970257adddcLaurent Pinchart unsigned int i; 11923813e0f8e1ee4885823cdd0b50b05970257adddcLaurent Pinchart int ret; 1193549fe0ba627a67b6ae1334eb5cf274a3dfb1fd69Laurent Pinchart 11941ec3c44bdd38051d870f64d0b2cc7dbd59760386Thierry Reding other_bo = bo_create(dev->fd, pipes[0].fourcc, dev->mode.width, 11951ec3c44bdd38051d870f64d0b2cc7dbd59760386Thierry Reding dev->mode.height, handles, pitches, offsets, 11961ec3c44bdd38051d870f64d0b2cc7dbd59760386Thierry Reding UTIL_PATTERN_PLAIN); 11973fdc1777ee156ebfa4281b49d8783adbbcae3ee1Laurent Pinchart if (other_bo == NULL) 11981e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg return; 11991e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg 1200b1e0bdeb70b68754c6c4ab1c7d0161709960d49cLaurent Pinchart ret = drmModeAddFB2(dev->fd, dev->mode.width, dev->mode.height, 1201b1e0bdeb70b68754c6c4ab1c7d0161709960d49cLaurent Pinchart pipes[0].fourcc, handles, pitches, offsets, 1202b1e0bdeb70b68754c6c4ab1c7d0161709960d49cLaurent Pinchart &other_fb_id, 0); 12031e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg if (ret) { 12041e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg fprintf(stderr, "failed to add fb: %s\n", strerror(errno)); 120521170a8c63d2e994317b785f7f7e78ab7e0a4ac4Joonyoung Shim goto err; 12061e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg } 12071e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg 12081e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg for (i = 0; i < count; i++) { 1209b1e0bdeb70b68754c6c4ab1c7d0161709960d49cLaurent Pinchart struct pipe_arg *pipe = &pipes[i]; 1210b1e0bdeb70b68754c6c4ab1c7d0161709960d49cLaurent Pinchart 1211b1e0bdeb70b68754c6c4ab1c7d0161709960d49cLaurent Pinchart if (pipe->mode == NULL) 12121e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg continue; 12131e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg 12142c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart ret = drmModePageFlip(dev->fd, pipe->crtc->crtc->crtc_id, 12152c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart other_fb_id, DRM_MODE_PAGE_FLIP_EVENT, 12162c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart pipe); 12173c8adda6e1e6b0471b3d70a63d795622bbeb1580Jakob Bornecrantz if (ret) { 12183c8adda6e1e6b0471b3d70a63d795622bbeb1580Jakob Bornecrantz fprintf(stderr, "failed to page flip: %s\n", strerror(errno)); 121921170a8c63d2e994317b785f7f7e78ab7e0a4ac4Joonyoung Shim goto err_rmfb; 12203c8adda6e1e6b0471b3d70a63d795622bbeb1580Jakob Bornecrantz } 1221b1e0bdeb70b68754c6c4ab1c7d0161709960d49cLaurent Pinchart gettimeofday(&pipe->start, NULL); 1222b1e0bdeb70b68754c6c4ab1c7d0161709960d49cLaurent Pinchart pipe->swap_count = 0; 1223b1e0bdeb70b68754c6c4ab1c7d0161709960d49cLaurent Pinchart pipe->fb_id[0] = dev->mode.fb_id; 1224b1e0bdeb70b68754c6c4ab1c7d0161709960d49cLaurent Pinchart pipe->fb_id[1] = other_fb_id; 1225b1e0bdeb70b68754c6c4ab1c7d0161709960d49cLaurent Pinchart pipe->current_fb_id = other_fb_id; 12261e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg } 12271e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg 12281e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg memset(&evctx, 0, sizeof evctx); 12291e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg evctx.version = DRM_EVENT_CONTEXT_VERSION; 12301e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg evctx.vblank_handler = NULL; 12316f1eba0548cd6a96e91a4e8be7b91ba6a936eb98Jesse Barnes evctx.page_flip_handler = page_flip_handler; 12326e84ada4ccf604c32a008fc20c00d79302135601Hyungwon Hwang 12331e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg while (1) { 1234e6b3f906cef26e1efb8625f5dd4e460b4c79a771Jesse Barnes#if 0 12351e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg struct pollfd pfd[2]; 12361e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg 12371e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg pfd[0].fd = 0; 12381e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg pfd[0].events = POLLIN; 12391e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg pfd[1].fd = fd; 12401e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg pfd[1].events = POLLIN; 12411e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg 12421e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg if (poll(pfd, 2, -1) < 0) { 12431e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg fprintf(stderr, "poll error\n"); 12441e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg break; 12451e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg } 12461e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg 12471e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg if (pfd[0].revents) 12481e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg break; 1249e6b3f906cef26e1efb8625f5dd4e460b4c79a771Jesse Barnes#else 1250e6b3f906cef26e1efb8625f5dd4e460b4c79a771Jesse Barnes struct timeval timeout = { .tv_sec = 3, .tv_usec = 0 }; 1251e6b3f906cef26e1efb8625f5dd4e460b4c79a771Jesse Barnes fd_set fds; 1252e6b3f906cef26e1efb8625f5dd4e460b4c79a771Jesse Barnes 1253e6b3f906cef26e1efb8625f5dd4e460b4c79a771Jesse Barnes FD_ZERO(&fds); 1254e6b3f906cef26e1efb8625f5dd4e460b4c79a771Jesse Barnes FD_SET(0, &fds); 1255549fe0ba627a67b6ae1334eb5cf274a3dfb1fd69Laurent Pinchart FD_SET(dev->fd, &fds); 1256549fe0ba627a67b6ae1334eb5cf274a3dfb1fd69Laurent Pinchart ret = select(dev->fd + 1, &fds, NULL, NULL, &timeout); 1257e6b3f906cef26e1efb8625f5dd4e460b4c79a771Jesse Barnes 1258e6b3f906cef26e1efb8625f5dd4e460b4c79a771Jesse Barnes if (ret <= 0) { 1259e6b3f906cef26e1efb8625f5dd4e460b4c79a771Jesse Barnes fprintf(stderr, "select timed out or error (ret %d)\n", 1260e6b3f906cef26e1efb8625f5dd4e460b4c79a771Jesse Barnes ret); 1261e6b3f906cef26e1efb8625f5dd4e460b4c79a771Jesse Barnes continue; 1262e6b3f906cef26e1efb8625f5dd4e460b4c79a771Jesse Barnes } else if (FD_ISSET(0, &fds)) { 1263e6b3f906cef26e1efb8625f5dd4e460b4c79a771Jesse Barnes break; 1264e6b3f906cef26e1efb8625f5dd4e460b4c79a771Jesse Barnes } 1265e6b3f906cef26e1efb8625f5dd4e460b4c79a771Jesse Barnes#endif 12661e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg 1267549fe0ba627a67b6ae1334eb5cf274a3dfb1fd69Laurent Pinchart drmHandleEvent(dev->fd, &evctx); 12681e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg } 12698fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke 127021170a8c63d2e994317b785f7f7e78ab7e0a4ac4Joonyoung Shimerr_rmfb: 1271bcaaa75cf482c7d218340c850ffc01f04b78b3ddJoonyoung Shim drmModeRmFB(dev->fd, other_fb_id); 127221170a8c63d2e994317b785f7f7e78ab7e0a4ac4Joonyoung Shimerr: 1273d7c0a08bc576deb07df6c3f91f393ca8edd0c4bfLaurent Pinchart bo_destroy(other_bo); 1274731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes} 1275731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 1276cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart#define min(a, b) ((a) < (b) ? (a) : (b)) 1277cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart 1278b1e0bdeb70b68754c6c4ab1c7d0161709960d49cLaurent Pinchartstatic int parse_connector(struct pipe_arg *pipe, const char *arg) 12790375222c714e8b7ba55f12d5cb389383be1cf54dLaurent Pinchart{ 1280cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart unsigned int len; 12812c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart unsigned int i; 1282cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart const char *p; 1283cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart char *endp; 1284cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart 1285de0970203091618834e4753c14d5169770797800Vincent ABRIOU pipe->vrefresh = 0; 1286b1e0bdeb70b68754c6c4ab1c7d0161709960d49cLaurent Pinchart pipe->crtc_id = (uint32_t)-1; 1287b1e0bdeb70b68754c6c4ab1c7d0161709960d49cLaurent Pinchart strcpy(pipe->format_str, "XR24"); 1288cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart 12892c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart /* Count the number of connectors and allocate them. */ 12902c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart pipe->num_cons = 1; 1291f05a74fb9cb07a02c9bade65d66ba6949a2567a2Thierry Reding for (p = arg; *p && *p != ':' && *p != '@'; ++p) { 12922c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart if (*p == ',') 12932c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart pipe->num_cons++; 12942c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart } 12952c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart 1296128344c2cf22385dedece5a3d774d3a24527d2deEmil Velikov pipe->con_ids = calloc(pipe->num_cons, sizeof(*pipe->con_ids)); 1297f05a74fb9cb07a02c9bade65d66ba6949a2567a2Thierry Reding pipe->cons = calloc(pipe->num_cons, sizeof(*pipe->cons)); 1298f05a74fb9cb07a02c9bade65d66ba6949a2567a2Thierry Reding if (pipe->con_ids == NULL || pipe->cons == NULL) 12992c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart return -1; 13002c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart 13012c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart /* Parse the connectors. */ 13022c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart for (i = 0, p = arg; i < pipe->num_cons; ++i, p = endp + 1) { 1303f05a74fb9cb07a02c9bade65d66ba6949a2567a2Thierry Reding endp = strpbrk(p, ",@:"); 1304f05a74fb9cb07a02c9bade65d66ba6949a2567a2Thierry Reding if (!endp) 1305f05a74fb9cb07a02c9bade65d66ba6949a2567a2Thierry Reding break; 1306f05a74fb9cb07a02c9bade65d66ba6949a2567a2Thierry Reding 1307f05a74fb9cb07a02c9bade65d66ba6949a2567a2Thierry Reding pipe->cons[i] = strndup(p, endp - p); 1308f05a74fb9cb07a02c9bade65d66ba6949a2567a2Thierry Reding 13092c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart if (*endp != ',') 13102c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart break; 13112c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart } 13122c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart 13132c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart if (i != pipe->num_cons - 1) 13142c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart return -1; 13152c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart 13162c5ee84d30cbd3fba61a8426b1e6bdd4f385de13Laurent Pinchart /* Parse the remaining parameters. */ 1317cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart if (*endp == '@') { 1318cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart arg = endp + 1; 1319b1e0bdeb70b68754c6c4ab1c7d0161709960d49cLaurent Pinchart pipe->crtc_id = strtoul(arg, &endp, 10); 1320cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart } 1321cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart if (*endp != ':') 1322cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart return -1; 13230375222c714e8b7ba55f12d5cb389383be1cf54dLaurent Pinchart 1324cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart arg = endp + 1; 13250375222c714e8b7ba55f12d5cb389383be1cf54dLaurent Pinchart 1326de0970203091618834e4753c14d5169770797800Vincent ABRIOU /* Search for the vertical refresh or the format. */ 1327de0970203091618834e4753c14d5169770797800Vincent ABRIOU p = strpbrk(arg, "-@"); 1328de0970203091618834e4753c14d5169770797800Vincent ABRIOU if (p == NULL) 1329de0970203091618834e4753c14d5169770797800Vincent ABRIOU p = arg + strlen(arg); 1330b1e0bdeb70b68754c6c4ab1c7d0161709960d49cLaurent Pinchart len = min(sizeof pipe->mode_str - 1, (unsigned int)(p - arg)); 1331b1e0bdeb70b68754c6c4ab1c7d0161709960d49cLaurent Pinchart strncpy(pipe->mode_str, arg, len); 1332b1e0bdeb70b68754c6c4ab1c7d0161709960d49cLaurent Pinchart pipe->mode_str[len] = '\0'; 13330375222c714e8b7ba55f12d5cb389383be1cf54dLaurent Pinchart 1334de0970203091618834e4753c14d5169770797800Vincent ABRIOU if (*p == '-') { 1335de0970203091618834e4753c14d5169770797800Vincent ABRIOU pipe->vrefresh = strtoul(p + 1, &endp, 10); 1336de0970203091618834e4753c14d5169770797800Vincent ABRIOU p = endp; 1337de0970203091618834e4753c14d5169770797800Vincent ABRIOU } 1338de0970203091618834e4753c14d5169770797800Vincent ABRIOU 1339cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart if (*p == '@') { 1340b1e0bdeb70b68754c6c4ab1c7d0161709960d49cLaurent Pinchart strncpy(pipe->format_str, p + 1, 4); 1341b1e0bdeb70b68754c6c4ab1c7d0161709960d49cLaurent Pinchart pipe->format_str[4] = '\0'; 1342ebd7904877d08525beb5039e4ea2f5b6c0a7c23fRob Clark } 1343cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart 13441ec3c44bdd38051d870f64d0b2cc7dbd59760386Thierry Reding pipe->fourcc = util_format_fourcc(pipe->format_str); 1345b1e0bdeb70b68754c6c4ab1c7d0161709960d49cLaurent Pinchart if (pipe->fourcc == 0) { 1346b1e0bdeb70b68754c6c4ab1c7d0161709960d49cLaurent Pinchart fprintf(stderr, "unknown format %s\n", pipe->format_str); 1347ebd7904877d08525beb5039e4ea2f5b6c0a7c23fRob Clark return -1; 1348cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart } 1349cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart 1350cc90ffa9b18fc6f925a3a2c36131332b8af558f8Laurent Pinchart return 0; 13510375222c714e8b7ba55f12d5cb389383be1cf54dLaurent Pinchart} 13520375222c714e8b7ba55f12d5cb389383be1cf54dLaurent Pinchart 13537badcca4925480ffdc4f3aa5efb88624ce451e70Laurent Pinchartstatic int parse_plane(struct plane_arg *plane, const char *p) 13540375222c714e8b7ba55f12d5cb389383be1cf54dLaurent Pinchart{ 13557badcca4925480ffdc4f3aa5efb88624ce451e70Laurent Pinchart char *end; 13560375222c714e8b7ba55f12d5cb389383be1cf54dLaurent Pinchart 1357eabf199dffb0d42e959c50aa820b39228196e031Laurent Pinchart plane->crtc_id = strtoul(p, &end, 10); 13587badcca4925480ffdc4f3aa5efb88624ce451e70Laurent Pinchart if (*end != ':') 13597badcca4925480ffdc4f3aa5efb88624ce451e70Laurent Pinchart return -EINVAL; 13607badcca4925480ffdc4f3aa5efb88624ce451e70Laurent Pinchart 13617badcca4925480ffdc4f3aa5efb88624ce451e70Laurent Pinchart p = end + 1; 13627badcca4925480ffdc4f3aa5efb88624ce451e70Laurent Pinchart plane->w = strtoul(p, &end, 10); 13637badcca4925480ffdc4f3aa5efb88624ce451e70Laurent Pinchart if (*end != 'x') 13647badcca4925480ffdc4f3aa5efb88624ce451e70Laurent Pinchart return -EINVAL; 13657badcca4925480ffdc4f3aa5efb88624ce451e70Laurent Pinchart 13667badcca4925480ffdc4f3aa5efb88624ce451e70Laurent Pinchart p = end + 1; 13677badcca4925480ffdc4f3aa5efb88624ce451e70Laurent Pinchart plane->h = strtoul(p, &end, 10); 13687badcca4925480ffdc4f3aa5efb88624ce451e70Laurent Pinchart 13697badcca4925480ffdc4f3aa5efb88624ce451e70Laurent Pinchart if (*end == '+' || *end == '-') { 13707badcca4925480ffdc4f3aa5efb88624ce451e70Laurent Pinchart plane->x = strtol(end, &end, 10); 13717badcca4925480ffdc4f3aa5efb88624ce451e70Laurent Pinchart if (*end != '+' && *end != '-') 13727badcca4925480ffdc4f3aa5efb88624ce451e70Laurent Pinchart return -EINVAL; 13737badcca4925480ffdc4f3aa5efb88624ce451e70Laurent Pinchart plane->y = strtol(end, &end, 10); 13747badcca4925480ffdc4f3aa5efb88624ce451e70Laurent Pinchart 13757badcca4925480ffdc4f3aa5efb88624ce451e70Laurent Pinchart plane->has_position = true; 13767badcca4925480ffdc4f3aa5efb88624ce451e70Laurent Pinchart } 13777badcca4925480ffdc4f3aa5efb88624ce451e70Laurent Pinchart 1378d8954154fe20036f442e249d964b575a7374c571Ilia Mirkin if (*end == '*') { 1379d8954154fe20036f442e249d964b575a7374c571Ilia Mirkin p = end + 1; 1380d8954154fe20036f442e249d964b575a7374c571Ilia Mirkin plane->scale = strtod(p, &end); 1381d8954154fe20036f442e249d964b575a7374c571Ilia Mirkin if (plane->scale <= 0.0) 1382d8954154fe20036f442e249d964b575a7374c571Ilia Mirkin return -EINVAL; 1383d8954154fe20036f442e249d964b575a7374c571Ilia Mirkin } else { 1384d8954154fe20036f442e249d964b575a7374c571Ilia Mirkin plane->scale = 1.0; 1385d8954154fe20036f442e249d964b575a7374c571Ilia Mirkin } 1386d8954154fe20036f442e249d964b575a7374c571Ilia Mirkin 13877badcca4925480ffdc4f3aa5efb88624ce451e70Laurent Pinchart if (*end == '@') { 13887badcca4925480ffdc4f3aa5efb88624ce451e70Laurent Pinchart p = end + 1; 13897badcca4925480ffdc4f3aa5efb88624ce451e70Laurent Pinchart if (strlen(p) != 4) 13907badcca4925480ffdc4f3aa5efb88624ce451e70Laurent Pinchart return -EINVAL; 13917badcca4925480ffdc4f3aa5efb88624ce451e70Laurent Pinchart 13927badcca4925480ffdc4f3aa5efb88624ce451e70Laurent Pinchart strcpy(plane->format_str, p); 13937badcca4925480ffdc4f3aa5efb88624ce451e70Laurent Pinchart } else { 13947badcca4925480ffdc4f3aa5efb88624ce451e70Laurent Pinchart strcpy(plane->format_str, "XR24"); 13957badcca4925480ffdc4f3aa5efb88624ce451e70Laurent Pinchart } 13967badcca4925480ffdc4f3aa5efb88624ce451e70Laurent Pinchart 13971ec3c44bdd38051d870f64d0b2cc7dbd59760386Thierry Reding plane->fourcc = util_format_fourcc(plane->format_str); 13987badcca4925480ffdc4f3aa5efb88624ce451e70Laurent Pinchart if (plane->fourcc == 0) { 13997badcca4925480ffdc4f3aa5efb88624ce451e70Laurent Pinchart fprintf(stderr, "unknown format %s\n", plane->format_str); 14007badcca4925480ffdc4f3aa5efb88624ce451e70Laurent Pinchart return -EINVAL; 14010375222c714e8b7ba55f12d5cb389383be1cf54dLaurent Pinchart } 14020375222c714e8b7ba55f12d5cb389383be1cf54dLaurent Pinchart 14030375222c714e8b7ba55f12d5cb389383be1cf54dLaurent Pinchart return 0; 14040375222c714e8b7ba55f12d5cb389383be1cf54dLaurent Pinchart} 14050375222c714e8b7ba55f12d5cb389383be1cf54dLaurent Pinchart 1406d725227cec822b8cfbeb541be17aae30b7612b9fLaurent Pinchartstatic int parse_property(struct property_arg *p, const char *arg) 1407d725227cec822b8cfbeb541be17aae30b7612b9fLaurent Pinchart{ 1408d725227cec822b8cfbeb541be17aae30b7612b9fLaurent Pinchart if (sscanf(arg, "%d:%32[^:]:%" SCNu64, &p->obj_id, p->name, &p->value) != 3) 1409d725227cec822b8cfbeb541be17aae30b7612b9fLaurent Pinchart return -1; 1410d725227cec822b8cfbeb541be17aae30b7612b9fLaurent Pinchart 1411d725227cec822b8cfbeb541be17aae30b7612b9fLaurent Pinchart p->obj_type = 0; 1412d725227cec822b8cfbeb541be17aae30b7612b9fLaurent Pinchart p->name[DRM_PROP_NAME_LEN] = '\0'; 1413d725227cec822b8cfbeb541be17aae30b7612b9fLaurent Pinchart 1414d725227cec822b8cfbeb541be17aae30b7612b9fLaurent Pinchart return 0; 1415d725227cec822b8cfbeb541be17aae30b7612b9fLaurent Pinchart} 1416d725227cec822b8cfbeb541be17aae30b7612b9fLaurent Pinchart 1417ca9c8f06e0f560082dcd0943e9be29ba9a915ee3Laurent Pinchartstatic void usage(char *name) 1418731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes{ 14190e512794bf6281edfa4543ae7cc408d52ec6e2f3Rob Clark fprintf(stderr, "usage: %s [-cDdefMPpsCvw]\n", name); 1420ef07acf5b79f86ef86efe6e72c1de5726c97e41dLaurent Pinchart 1421ef07acf5b79f86ef86efe6e72c1de5726c97e41dLaurent Pinchart fprintf(stderr, "\n Query options:\n\n"); 1422731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes fprintf(stderr, "\t-c\tlist connectors\n"); 1423ef07acf5b79f86ef86efe6e72c1de5726c97e41dLaurent Pinchart fprintf(stderr, "\t-e\tlist encoders\n"); 1424731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes fprintf(stderr, "\t-f\tlist framebuffers\n"); 1425ef07acf5b79f86ef86efe6e72c1de5726c97e41dLaurent Pinchart fprintf(stderr, "\t-p\tlist CRTCs and planes (pipes)\n"); 1426ef07acf5b79f86ef86efe6e72c1de5726c97e41dLaurent Pinchart 1427ef07acf5b79f86ef86efe6e72c1de5726c97e41dLaurent Pinchart fprintf(stderr, "\n Test options:\n\n"); 1428d8954154fe20036f442e249d964b575a7374c571Ilia Mirkin fprintf(stderr, "\t-P <crtc_id>:<w>x<h>[+<x>+<y>][*<scale>][@<format>]\tset a plane\n"); 1429de0970203091618834e4753c14d5169770797800Vincent ABRIOU fprintf(stderr, "\t-s <connector_id>[,<connector_id>][@<crtc_id>]:<mode>[-<vrefresh>][@<format>]\tset a mode\n"); 14300e512794bf6281edfa4543ae7cc408d52ec6e2f3Rob Clark fprintf(stderr, "\t-C\ttest hw cursor\n"); 1431ef07acf5b79f86ef86efe6e72c1de5726c97e41dLaurent Pinchart fprintf(stderr, "\t-v\ttest vsynced page flipping\n"); 1432d725227cec822b8cfbeb541be17aae30b7612b9fLaurent Pinchart fprintf(stderr, "\t-w <obj_id>:<prop_name>:<value>\tset property\n"); 1433ef07acf5b79f86ef86efe6e72c1de5726c97e41dLaurent Pinchart 143445901fdae66441ffec681e3dbd46b5530107a045Laurent Pinchart fprintf(stderr, "\n Generic options:\n\n"); 1435ab52756a3632fdc38a915a9bbda0b2089b09e38eLaurent Pinchart fprintf(stderr, "\t-d\tdrop master after mode set\n"); 143645901fdae66441ffec681e3dbd46b5530107a045Laurent Pinchart fprintf(stderr, "\t-M module\tuse the given driver\n"); 1437b50826dbd6a10e89ed03c23a16bf62e7d554a2d6Ilia Mirkin fprintf(stderr, "\t-D device\tuse the given device\n"); 143845901fdae66441ffec681e3dbd46b5530107a045Laurent Pinchart 1439731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes fprintf(stderr, "\n\tDefault is to dump all info.\n"); 1440731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes exit(0); 1441731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes} 1442731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 14439b44fbd393b8db571badae41881f490145404ae0Paulo Zanonistatic int page_flipping_supported(void) 144459d97e7d6807d9cd076d4e8374aca1d9e8027a6bKristian Høgsberg{ 14458fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke /*FIXME: generic ioctl needed? */ 14468fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke return 1; 14478fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke#if 0 144859d97e7d6807d9cd076d4e8374aca1d9e8027a6bKristian Høgsberg int ret, value; 144959d97e7d6807d9cd076d4e8374aca1d9e8027a6bKristian Høgsberg struct drm_i915_getparam gp; 145059d97e7d6807d9cd076d4e8374aca1d9e8027a6bKristian Høgsberg 145159d97e7d6807d9cd076d4e8374aca1d9e8027a6bKristian Høgsberg gp.param = I915_PARAM_HAS_PAGEFLIPPING; 145259d97e7d6807d9cd076d4e8374aca1d9e8027a6bKristian Høgsberg gp.value = &value; 145359d97e7d6807d9cd076d4e8374aca1d9e8027a6bKristian Høgsberg 145459d97e7d6807d9cd076d4e8374aca1d9e8027a6bKristian Høgsberg ret = drmCommandWriteRead(fd, DRM_I915_GETPARAM, &gp, sizeof(gp)); 145559d97e7d6807d9cd076d4e8374aca1d9e8027a6bKristian Høgsberg if (ret) { 145659d97e7d6807d9cd076d4e8374aca1d9e8027a6bKristian Høgsberg fprintf(stderr, "drm_i915_getparam: %m\n"); 145759d97e7d6807d9cd076d4e8374aca1d9e8027a6bKristian Høgsberg return 0; 145859d97e7d6807d9cd076d4e8374aca1d9e8027a6bKristian Høgsberg } 145959d97e7d6807d9cd076d4e8374aca1d9e8027a6bKristian Høgsberg 1460e4a519635f75bde38aeb5b09f2ff4efbf73453e9Matthew W. S. Bell return *gp.value; 14618fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke#endif 146259d97e7d6807d9cd076d4e8374aca1d9e8027a6bKristian Høgsberg} 146359d97e7d6807d9cd076d4e8374aca1d9e8027a6bKristian Høgsberg 14640e512794bf6281edfa4543ae7cc408d52ec6e2f3Rob Clarkstatic int cursor_supported(void) 14650e512794bf6281edfa4543ae7cc408d52ec6e2f3Rob Clark{ 14660e512794bf6281edfa4543ae7cc408d52ec6e2f3Rob Clark /*FIXME: generic ioctl needed? */ 14670e512794bf6281edfa4543ae7cc408d52ec6e2f3Rob Clark return 1; 14680e512794bf6281edfa4543ae7cc408d52ec6e2f3Rob Clark} 14690e512794bf6281edfa4543ae7cc408d52ec6e2f3Rob Clark 1470f05a74fb9cb07a02c9bade65d66ba6949a2567a2Thierry Redingstatic int pipe_resolve_connectors(struct device *dev, struct pipe_arg *pipe) 1471f05a74fb9cb07a02c9bade65d66ba6949a2567a2Thierry Reding{ 1472f05a74fb9cb07a02c9bade65d66ba6949a2567a2Thierry Reding drmModeConnector *connector; 1473f05a74fb9cb07a02c9bade65d66ba6949a2567a2Thierry Reding unsigned int i; 1474f05a74fb9cb07a02c9bade65d66ba6949a2567a2Thierry Reding uint32_t id; 1475f05a74fb9cb07a02c9bade65d66ba6949a2567a2Thierry Reding char *endp; 1476f05a74fb9cb07a02c9bade65d66ba6949a2567a2Thierry Reding 1477f05a74fb9cb07a02c9bade65d66ba6949a2567a2Thierry Reding for (i = 0; i < pipe->num_cons; i++) { 1478f05a74fb9cb07a02c9bade65d66ba6949a2567a2Thierry Reding id = strtoul(pipe->cons[i], &endp, 10); 1479f05a74fb9cb07a02c9bade65d66ba6949a2567a2Thierry Reding if (endp == pipe->cons[i]) { 1480f05a74fb9cb07a02c9bade65d66ba6949a2567a2Thierry Reding connector = get_connector_by_name(dev, pipe->cons[i]); 1481f05a74fb9cb07a02c9bade65d66ba6949a2567a2Thierry Reding if (!connector) { 1482f05a74fb9cb07a02c9bade65d66ba6949a2567a2Thierry Reding fprintf(stderr, "no connector named '%s'\n", 1483f05a74fb9cb07a02c9bade65d66ba6949a2567a2Thierry Reding pipe->cons[i]); 1484f05a74fb9cb07a02c9bade65d66ba6949a2567a2Thierry Reding return -ENODEV; 1485f05a74fb9cb07a02c9bade65d66ba6949a2567a2Thierry Reding } 1486f05a74fb9cb07a02c9bade65d66ba6949a2567a2Thierry Reding 1487f05a74fb9cb07a02c9bade65d66ba6949a2567a2Thierry Reding id = connector->connector_id; 1488f05a74fb9cb07a02c9bade65d66ba6949a2567a2Thierry Reding } 1489f05a74fb9cb07a02c9bade65d66ba6949a2567a2Thierry Reding 1490f05a74fb9cb07a02c9bade65d66ba6949a2567a2Thierry Reding pipe->con_ids[i] = id; 1491f05a74fb9cb07a02c9bade65d66ba6949a2567a2Thierry Reding } 1492f05a74fb9cb07a02c9bade65d66ba6949a2567a2Thierry Reding 1493f05a74fb9cb07a02c9bade65d66ba6949a2567a2Thierry Reding return 0; 1494f05a74fb9cb07a02c9bade65d66ba6949a2567a2Thierry Reding} 1495f05a74fb9cb07a02c9bade65d66ba6949a2567a2Thierry Reding 14960e512794bf6281edfa4543ae7cc408d52ec6e2f3Rob Clarkstatic char optstr[] = "cdD:efM:P:ps:Cvw:"; 1497ef07acf5b79f86ef86efe6e72c1de5726c97e41dLaurent Pinchart 1498731cd5526e5c732d51307b26e784f454a724a699Jesse Barnesint main(int argc, char **argv) 1499731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes{ 1500549fe0ba627a67b6ae1334eb5cf274a3dfb1fd69Laurent Pinchart struct device dev; 1501549fe0ba627a67b6ae1334eb5cf274a3dfb1fd69Laurent Pinchart 1502731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes int c; 1503d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark int encoders = 0, connectors = 0, crtcs = 0, planes = 0, framebuffers = 0; 1504ab52756a3632fdc38a915a9bbda0b2089b09e38eLaurent Pinchart int drop_master = 0; 15051e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg int test_vsync = 0; 15060e512794bf6281edfa4543ae7cc408d52ec6e2f3Rob Clark int test_cursor = 0; 1507b50826dbd6a10e89ed03c23a16bf62e7d554a2d6Ilia Mirkin char *device = NULL; 150845901fdae66441ffec681e3dbd46b5530107a045Laurent Pinchart char *module = NULL; 15099b44fbd393b8db571badae41881f490145404ae0Paulo Zanoni unsigned int i; 1510f05a74fb9cb07a02c9bade65d66ba6949a2567a2Thierry Reding unsigned int count = 0, plane_count = 0; 1511d725227cec822b8cfbeb541be17aae30b7612b9fLaurent Pinchart unsigned int prop_count = 0; 1512b1e0bdeb70b68754c6c4ab1c7d0161709960d49cLaurent Pinchart struct pipe_arg *pipe_args = NULL; 15136e0c74c5f8860748f03dad4548d3ef2cf2df5489Laurent Pinchart struct plane_arg *plane_args = NULL; 1514d725227cec822b8cfbeb541be17aae30b7612b9fLaurent Pinchart struct property_arg *prop_args = NULL; 151545901fdae66441ffec681e3dbd46b5530107a045Laurent Pinchart unsigned int args = 0; 1516549fe0ba627a67b6ae1334eb5cf274a3dfb1fd69Laurent Pinchart int ret; 1517549fe0ba627a67b6ae1334eb5cf274a3dfb1fd69Laurent Pinchart 15183813e0f8e1ee4885823cdd0b50b05970257adddcLaurent Pinchart memset(&dev, 0, sizeof dev); 15193813e0f8e1ee4885823cdd0b50b05970257adddcLaurent Pinchart 1520731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes opterr = 0; 1521731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes while ((c = getopt(argc, argv, optstr)) != -1) { 152245901fdae66441ffec681e3dbd46b5530107a045Laurent Pinchart args++; 152345901fdae66441ffec681e3dbd46b5530107a045Laurent Pinchart 1524731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes switch (c) { 1525731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes case 'c': 1526731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes connectors = 1; 1527731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes break; 1528b50826dbd6a10e89ed03c23a16bf62e7d554a2d6Ilia Mirkin case 'D': 1529b50826dbd6a10e89ed03c23a16bf62e7d554a2d6Ilia Mirkin device = optarg; 1530b50826dbd6a10e89ed03c23a16bf62e7d554a2d6Ilia Mirkin args--; 1531b50826dbd6a10e89ed03c23a16bf62e7d554a2d6Ilia Mirkin break; 1532ab52756a3632fdc38a915a9bbda0b2089b09e38eLaurent Pinchart case 'd': 1533ab52756a3632fdc38a915a9bbda0b2089b09e38eLaurent Pinchart drop_master = 1; 1534ab52756a3632fdc38a915a9bbda0b2089b09e38eLaurent Pinchart break; 1535ef07acf5b79f86ef86efe6e72c1de5726c97e41dLaurent Pinchart case 'e': 1536ef07acf5b79f86ef86efe6e72c1de5726c97e41dLaurent Pinchart encoders = 1; 1537ef07acf5b79f86ef86efe6e72c1de5726c97e41dLaurent Pinchart break; 1538ef07acf5b79f86ef86efe6e72c1de5726c97e41dLaurent Pinchart case 'f': 1539ef07acf5b79f86ef86efe6e72c1de5726c97e41dLaurent Pinchart framebuffers = 1; 1540731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes break; 154145901fdae66441ffec681e3dbd46b5530107a045Laurent Pinchart case 'M': 154245901fdae66441ffec681e3dbd46b5530107a045Laurent Pinchart module = optarg; 154345901fdae66441ffec681e3dbd46b5530107a045Laurent Pinchart /* Preserve the default behaviour of dumping all information. */ 154445901fdae66441ffec681e3dbd46b5530107a045Laurent Pinchart args--; 154545901fdae66441ffec681e3dbd46b5530107a045Laurent Pinchart break; 1546ef07acf5b79f86ef86efe6e72c1de5726c97e41dLaurent Pinchart case 'P': 15476e0c74c5f8860748f03dad4548d3ef2cf2df5489Laurent Pinchart plane_args = realloc(plane_args, 15486e0c74c5f8860748f03dad4548d3ef2cf2df5489Laurent Pinchart (plane_count + 1) * sizeof *plane_args); 15496e0c74c5f8860748f03dad4548d3ef2cf2df5489Laurent Pinchart if (plane_args == NULL) { 15506e0c74c5f8860748f03dad4548d3ef2cf2df5489Laurent Pinchart fprintf(stderr, "memory allocation failed\n"); 15516e0c74c5f8860748f03dad4548d3ef2cf2df5489Laurent Pinchart return 1; 15526e0c74c5f8860748f03dad4548d3ef2cf2df5489Laurent Pinchart } 1553c78917ee4fe6c787a5de9aaccc5319fdffc9a354Emil Velikov memset(&plane_args[plane_count], 0, sizeof(*plane_args)); 15546e0c74c5f8860748f03dad4548d3ef2cf2df5489Laurent Pinchart 1555ef07acf5b79f86ef86efe6e72c1de5726c97e41dLaurent Pinchart if (parse_plane(&plane_args[plane_count], optarg) < 0) 1556ef07acf5b79f86ef86efe6e72c1de5726c97e41dLaurent Pinchart usage(argv[0]); 15576e0c74c5f8860748f03dad4548d3ef2cf2df5489Laurent Pinchart 1558ef07acf5b79f86ef86efe6e72c1de5726c97e41dLaurent Pinchart plane_count++; 1559731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes break; 1560ef07acf5b79f86ef86efe6e72c1de5726c97e41dLaurent Pinchart case 'p': 1561ef07acf5b79f86ef86efe6e72c1de5726c97e41dLaurent Pinchart crtcs = 1; 1562ef07acf5b79f86ef86efe6e72c1de5726c97e41dLaurent Pinchart planes = 1; 15631e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg break; 1564731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes case 's': 1565b1e0bdeb70b68754c6c4ab1c7d0161709960d49cLaurent Pinchart pipe_args = realloc(pipe_args, 1566b1e0bdeb70b68754c6c4ab1c7d0161709960d49cLaurent Pinchart (count + 1) * sizeof *pipe_args); 1567b1e0bdeb70b68754c6c4ab1c7d0161709960d49cLaurent Pinchart if (pipe_args == NULL) { 15686e0c74c5f8860748f03dad4548d3ef2cf2df5489Laurent Pinchart fprintf(stderr, "memory allocation failed\n"); 15696e0c74c5f8860748f03dad4548d3ef2cf2df5489Laurent Pinchart return 1; 15706e0c74c5f8860748f03dad4548d3ef2cf2df5489Laurent Pinchart } 1571c78917ee4fe6c787a5de9aaccc5319fdffc9a354Emil Velikov memset(&pipe_args[count], 0, sizeof(*pipe_args)); 15726e0c74c5f8860748f03dad4548d3ef2cf2df5489Laurent Pinchart 1573b1e0bdeb70b68754c6c4ab1c7d0161709960d49cLaurent Pinchart if (parse_connector(&pipe_args[count], optarg) < 0) 1574669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg usage(argv[0]); 15756e0c74c5f8860748f03dad4548d3ef2cf2df5489Laurent Pinchart 15766e84ada4ccf604c32a008fc20c00d79302135601Hyungwon Hwang count++; 1577731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes break; 15780e512794bf6281edfa4543ae7cc408d52ec6e2f3Rob Clark case 'C': 15790e512794bf6281edfa4543ae7cc408d52ec6e2f3Rob Clark test_cursor = 1; 15800e512794bf6281edfa4543ae7cc408d52ec6e2f3Rob Clark break; 1581ef07acf5b79f86ef86efe6e72c1de5726c97e41dLaurent Pinchart case 'v': 1582ef07acf5b79f86ef86efe6e72c1de5726c97e41dLaurent Pinchart test_vsync = 1; 1583d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark break; 1584d725227cec822b8cfbeb541be17aae30b7612b9fLaurent Pinchart case 'w': 1585d725227cec822b8cfbeb541be17aae30b7612b9fLaurent Pinchart prop_args = realloc(prop_args, 1586d725227cec822b8cfbeb541be17aae30b7612b9fLaurent Pinchart (prop_count + 1) * sizeof *prop_args); 1587d725227cec822b8cfbeb541be17aae30b7612b9fLaurent Pinchart if (prop_args == NULL) { 1588d725227cec822b8cfbeb541be17aae30b7612b9fLaurent Pinchart fprintf(stderr, "memory allocation failed\n"); 1589d725227cec822b8cfbeb541be17aae30b7612b9fLaurent Pinchart return 1; 1590d725227cec822b8cfbeb541be17aae30b7612b9fLaurent Pinchart } 1591c78917ee4fe6c787a5de9aaccc5319fdffc9a354Emil Velikov memset(&prop_args[prop_count], 0, sizeof(*prop_args)); 1592d725227cec822b8cfbeb541be17aae30b7612b9fLaurent Pinchart 1593d725227cec822b8cfbeb541be17aae30b7612b9fLaurent Pinchart if (parse_property(&prop_args[prop_count], optarg) < 0) 1594d725227cec822b8cfbeb541be17aae30b7612b9fLaurent Pinchart usage(argv[0]); 1595d725227cec822b8cfbeb541be17aae30b7612b9fLaurent Pinchart 1596d725227cec822b8cfbeb541be17aae30b7612b9fLaurent Pinchart prop_count++; 1597d725227cec822b8cfbeb541be17aae30b7612b9fLaurent Pinchart break; 1598731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes default: 1599731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes usage(argv[0]); 1600731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes break; 1601731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes } 1602731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes } 1603731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 160445901fdae66441ffec681e3dbd46b5530107a045Laurent Pinchart if (!args) 1605dab3c80203e562cfdbe33e7d1627c9dde2f5a7deLaurent Pinchart encoders = connectors = crtcs = planes = framebuffers = 1; 1606731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 1607c26266fcd082a8b67d1f32f5e5351cfa82c7accbThierry Reding dev.fd = util_open(module, device); 1608c26266fcd082a8b67d1f32f5e5351cfa82c7accbThierry Reding if (dev.fd < 0) 1609c26266fcd082a8b67d1f32f5e5351cfa82c7accbThierry Reding return -1; 1610731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 16119b44fbd393b8db571badae41881f490145404ae0Paulo Zanoni if (test_vsync && !page_flipping_supported()) { 161259d97e7d6807d9cd076d4e8374aca1d9e8027a6bKristian Høgsberg fprintf(stderr, "page flipping not supported by drm.\n"); 161359d97e7d6807d9cd076d4e8374aca1d9e8027a6bKristian Høgsberg return -1; 161459d97e7d6807d9cd076d4e8374aca1d9e8027a6bKristian Høgsberg } 161559d97e7d6807d9cd076d4e8374aca1d9e8027a6bKristian Høgsberg 16163813e0f8e1ee4885823cdd0b50b05970257adddcLaurent Pinchart if (test_vsync && !count) { 16173813e0f8e1ee4885823cdd0b50b05970257adddcLaurent Pinchart fprintf(stderr, "page flipping requires at least one -s option.\n"); 16183813e0f8e1ee4885823cdd0b50b05970257adddcLaurent Pinchart return -1; 16193813e0f8e1ee4885823cdd0b50b05970257adddcLaurent Pinchart } 16203813e0f8e1ee4885823cdd0b50b05970257adddcLaurent Pinchart 16210e512794bf6281edfa4543ae7cc408d52ec6e2f3Rob Clark if (test_cursor && !cursor_supported()) { 16220e512794bf6281edfa4543ae7cc408d52ec6e2f3Rob Clark fprintf(stderr, "hw cursor not supported by drm.\n"); 16230e512794bf6281edfa4543ae7cc408d52ec6e2f3Rob Clark return -1; 16240e512794bf6281edfa4543ae7cc408d52ec6e2f3Rob Clark } 16250e512794bf6281edfa4543ae7cc408d52ec6e2f3Rob Clark 1626549fe0ba627a67b6ae1334eb5cf274a3dfb1fd69Laurent Pinchart dev.resources = get_resources(&dev); 1627549fe0ba627a67b6ae1334eb5cf274a3dfb1fd69Laurent Pinchart if (!dev.resources) { 1628549fe0ba627a67b6ae1334eb5cf274a3dfb1fd69Laurent Pinchart drmClose(dev.fd); 1629731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes return 1; 1630731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes } 1631731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 1632f05a74fb9cb07a02c9bade65d66ba6949a2567a2Thierry Reding for (i = 0; i < count; i++) { 1633f05a74fb9cb07a02c9bade65d66ba6949a2567a2Thierry Reding if (pipe_resolve_connectors(&dev, &pipe_args[i]) < 0) { 1634f05a74fb9cb07a02c9bade65d66ba6949a2567a2Thierry Reding free_resources(dev.resources); 1635f05a74fb9cb07a02c9bade65d66ba6949a2567a2Thierry Reding drmClose(dev.fd); 1636f05a74fb9cb07a02c9bade65d66ba6949a2567a2Thierry Reding return 1; 1637f05a74fb9cb07a02c9bade65d66ba6949a2567a2Thierry Reding } 1638f05a74fb9cb07a02c9bade65d66ba6949a2567a2Thierry Reding } 1639f05a74fb9cb07a02c9bade65d66ba6949a2567a2Thierry Reding 1640549fe0ba627a67b6ae1334eb5cf274a3dfb1fd69Laurent Pinchart#define dump_resource(dev, res) if (res) dump_##res(dev) 1641549fe0ba627a67b6ae1334eb5cf274a3dfb1fd69Laurent Pinchart 1642549fe0ba627a67b6ae1334eb5cf274a3dfb1fd69Laurent Pinchart dump_resource(&dev, encoders); 1643549fe0ba627a67b6ae1334eb5cf274a3dfb1fd69Laurent Pinchart dump_resource(&dev, connectors); 1644549fe0ba627a67b6ae1334eb5cf274a3dfb1fd69Laurent Pinchart dump_resource(&dev, crtcs); 1645549fe0ba627a67b6ae1334eb5cf274a3dfb1fd69Laurent Pinchart dump_resource(&dev, planes); 1646549fe0ba627a67b6ae1334eb5cf274a3dfb1fd69Laurent Pinchart dump_resource(&dev, framebuffers); 1647731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 1648d725227cec822b8cfbeb541be17aae30b7612b9fLaurent Pinchart for (i = 0; i < prop_count; ++i) 1649549fe0ba627a67b6ae1334eb5cf274a3dfb1fd69Laurent Pinchart set_property(&dev, &prop_args[i]); 1650d725227cec822b8cfbeb541be17aae30b7612b9fLaurent Pinchart 16513813e0f8e1ee4885823cdd0b50b05970257adddcLaurent Pinchart if (count || plane_count) { 1652d7c0a08bc576deb07df6c3f91f393ca8edd0c4bfLaurent Pinchart uint64_t cap = 0; 1653d7c0a08bc576deb07df6c3f91f393ca8edd0c4bfLaurent Pinchart 1654d7c0a08bc576deb07df6c3f91f393ca8edd0c4bfLaurent Pinchart ret = drmGetCap(dev.fd, DRM_CAP_DUMB_BUFFER, &cap); 1655d7c0a08bc576deb07df6c3f91f393ca8edd0c4bfLaurent Pinchart if (ret || cap == 0) { 1656d7c0a08bc576deb07df6c3f91f393ca8edd0c4bfLaurent Pinchart fprintf(stderr, "driver doesn't support the dumb buffer API\n"); 1657549fe0ba627a67b6ae1334eb5cf274a3dfb1fd69Laurent Pinchart return 1; 1658549fe0ba627a67b6ae1334eb5cf274a3dfb1fd69Laurent Pinchart } 1659549fe0ba627a67b6ae1334eb5cf274a3dfb1fd69Laurent Pinchart 16603813e0f8e1ee4885823cdd0b50b05970257adddcLaurent Pinchart if (count) 1661b1e0bdeb70b68754c6c4ab1c7d0161709960d49cLaurent Pinchart set_mode(&dev, pipe_args, count); 16623813e0f8e1ee4885823cdd0b50b05970257adddcLaurent Pinchart 16633813e0f8e1ee4885823cdd0b50b05970257adddcLaurent Pinchart if (plane_count) 16643813e0f8e1ee4885823cdd0b50b05970257adddcLaurent Pinchart set_planes(&dev, plane_args, plane_count); 16653813e0f8e1ee4885823cdd0b50b05970257adddcLaurent Pinchart 16660e512794bf6281edfa4543ae7cc408d52ec6e2f3Rob Clark if (test_cursor) 16670e512794bf6281edfa4543ae7cc408d52ec6e2f3Rob Clark set_cursors(&dev, pipe_args, count); 16680e512794bf6281edfa4543ae7cc408d52ec6e2f3Rob Clark 16693813e0f8e1ee4885823cdd0b50b05970257adddcLaurent Pinchart if (test_vsync) 1670b1e0bdeb70b68754c6c4ab1c7d0161709960d49cLaurent Pinchart test_page_flip(&dev, pipe_args, count); 16713813e0f8e1ee4885823cdd0b50b05970257adddcLaurent Pinchart 1672ab52756a3632fdc38a915a9bbda0b2089b09e38eLaurent Pinchart if (drop_master) 1673549fe0ba627a67b6ae1334eb5cf274a3dfb1fd69Laurent Pinchart drmDropMaster(dev.fd); 1674549fe0ba627a67b6ae1334eb5cf274a3dfb1fd69Laurent Pinchart 16750e512794bf6281edfa4543ae7cc408d52ec6e2f3Rob Clark getchar(); 16760e512794bf6281edfa4543ae7cc408d52ec6e2f3Rob Clark 16770e512794bf6281edfa4543ae7cc408d52ec6e2f3Rob Clark if (test_cursor) 16780e512794bf6281edfa4543ae7cc408d52ec6e2f3Rob Clark clear_cursors(&dev); 16790e512794bf6281edfa4543ae7cc408d52ec6e2f3Rob Clark 16804d760d7f46b96a88a2e5f21fa983c4806ece1219Joonyoung Shim if (plane_count) 16814d760d7f46b96a88a2e5f21fa983c4806ece1219Joonyoung Shim clear_planes(&dev, plane_args, plane_count); 16824d760d7f46b96a88a2e5f21fa983c4806ece1219Joonyoung Shim 16834e4d79d4cae92c5ec29882cea9b8f7e8355f1232Joonyoung Shim if (count) 16844e4d79d4cae92c5ec29882cea9b8f7e8355f1232Joonyoung Shim clear_mode(&dev); 1685731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes } 1686731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 1687549fe0ba627a67b6ae1334eb5cf274a3dfb1fd69Laurent Pinchart free_resources(dev.resources); 1688731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 1689731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes return 0; 1690731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes} 1691