modetest.c revision 7a389aab86bde183de8806878b8cf055f662ee73
1731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes/* 2731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * DRM based mode setting test program 3731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * Copyright 2008 Tungsten Graphics 4731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * Jakob Bornecrantz <jakob@tungstengraphics.com> 5731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * Copyright 2008 Intel Corporation 6731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * Jesse Barnes <jesse.barnes@intel.com> 7731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * 8731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * Permission is hereby granted, free of charge, to any person obtaining a 9731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * copy of this software and associated documentation files (the "Software"), 10731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * to deal in the Software without restriction, including without limitation 11731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * the rights to use, copy, modify, merge, publish, distribute, sublicense, 12731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * and/or sell copies of the Software, and to permit persons to whom the 13731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * Software is furnished to do so, subject to the following conditions: 14731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * 15731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * The above copyright notice and this permission notice shall be included in 16731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * all copies or substantial portions of the Software. 17731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * 18731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 23731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 24731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * IN THE SOFTWARE. 25731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes */ 26731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 27731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes/* 28731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * This fairly simple test program dumps output in a similar format to the 29731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * "xrandr" tool everyone knows & loves. It's necessarily slightly different 30731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * since the kernel separates outputs into encoder and connector structures, 31731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * each with their own unique ID. The program also allows test testing of the 32731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * memory management and mode setting APIs by allowing the user to specify a 33731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * connector and mode to use for mode setting. If all works as expected, a 34731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * blue background should be painted on the monitor attached to the specified 35731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * connector after the selected mode is set. 36731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * 37731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * TODO: use cairo to write the mode info on the selected output once 38731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * the mode has been programmed, along with possible test patterns. 39731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes */ 407a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg#include "config.h" 417a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg 42731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes#include <assert.h> 43731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes#include <stdio.h> 44731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes#include <stdlib.h> 45731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes#include <stdint.h> 46731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes#include <unistd.h> 47731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes#include <string.h> 48731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes#include <errno.h> 49731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 50731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes#include "xf86drm.h" 51731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes#include "xf86drmMode.h" 52731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes#include "intel_bufmgr.h" 53731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 547a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg#ifdef HAVE_CAIRO 557a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg#include <math.h> 567a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg#include <cairo.h> 577a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg#endif 587a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg 59731cd5526e5c732d51307b26e784f454a724a699Jesse BarnesdrmModeRes *resources; 60731cd5526e5c732d51307b26e784f454a724a699Jesse Barnesint fd, modes; 61731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 62731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) 63731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 64731cd5526e5c732d51307b26e784f454a724a699Jesse Barnesstruct type_name { 65731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes int type; 66731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes char *name; 67731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes}; 68731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 69731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes#define type_name_fn(res) \ 70731cd5526e5c732d51307b26e784f454a724a699Jesse Barneschar * res##_str(int type) { \ 71731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes int i; \ 72731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes for (i = 0; i < ARRAY_SIZE(res##_names); i++) { \ 73731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes if (res##_names[i].type == type) \ 74731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes return res##_names[i].name; \ 75731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes } \ 76731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes return "(invalid)"; \ 77731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes} 78731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 79731cd5526e5c732d51307b26e784f454a724a699Jesse Barnesstruct type_name encoder_type_names[] = { 80731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes { DRM_MODE_ENCODER_NONE, "none" }, 81731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes { DRM_MODE_ENCODER_DAC, "DAC" }, 82731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes { DRM_MODE_ENCODER_TMDS, "TMDS" }, 83731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes { DRM_MODE_ENCODER_LVDS, "LVDS" }, 84731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes { DRM_MODE_ENCODER_TVDAC, "TVDAC" }, 85731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes}; 86731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 87731cd5526e5c732d51307b26e784f454a724a699Jesse Barnestype_name_fn(encoder_type) 88731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 89731cd5526e5c732d51307b26e784f454a724a699Jesse Barnesstruct type_name connector_status_names[] = { 90731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes { DRM_MODE_CONNECTED, "connected" }, 91731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes { DRM_MODE_DISCONNECTED, "disconnected" }, 92731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes { DRM_MODE_UNKNOWNCONNECTION, "unknown" }, 93731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes}; 94731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 95731cd5526e5c732d51307b26e784f454a724a699Jesse Barnestype_name_fn(connector_status) 96731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 97731cd5526e5c732d51307b26e784f454a724a699Jesse Barnesstruct type_name connector_type_names[] = { 98731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes { DRM_MODE_CONNECTOR_Unknown, "unknown" }, 99731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes { DRM_MODE_CONNECTOR_VGA, "VGA" }, 100731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes { DRM_MODE_CONNECTOR_DVII, "DVI-I" }, 101731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes { DRM_MODE_CONNECTOR_DVID, "DVI-D" }, 102731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes { DRM_MODE_CONNECTOR_DVIA, "DVI-A" }, 103731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes { DRM_MODE_CONNECTOR_Composite, "composite" }, 104731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes { DRM_MODE_CONNECTOR_SVIDEO, "s-video" }, 105731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes { DRM_MODE_CONNECTOR_LVDS, "LVDS" }, 106731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes { DRM_MODE_CONNECTOR_Component, "component" }, 107731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes { DRM_MODE_CONNECTOR_9PinDIN, "9-pin DIN" }, 108731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes { DRM_MODE_CONNECTOR_DisplayPort, "displayport" }, 109731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes { DRM_MODE_CONNECTOR_HDMIA, "HDMI-A" }, 110731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes { DRM_MODE_CONNECTOR_HDMIB, "HDMI-B" }, 111731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes}; 112731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 113731cd5526e5c732d51307b26e784f454a724a699Jesse Barnestype_name_fn(connector_type) 114731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 115731cd5526e5c732d51307b26e784f454a724a699Jesse Barnesvoid dump_encoders(void) 116731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes{ 117731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes drmModeEncoder *encoder; 118731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes int i; 119731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 120731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes printf("Encoders:\n"); 121731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes printf("id\tcrtc\ttype\tpossible crtcs\tpossible clones\t\n"); 122731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes for (i = 0; i < resources->count_encoders; i++) { 123731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes encoder = drmModeGetEncoder(fd, resources->encoders[i]); 124731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 125731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes if (!encoder) { 126731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes fprintf(stderr, "could not get encoder %i: %s\n", 127731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes resources->encoders[i], strerror(errno)); 128731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes continue; 129731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes } 130731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes printf("%d\t%d\t%s\t0x%08x\t0x%08x\n", 131731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes encoder->encoder_id, 132731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes encoder->crtc_id, 133731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes encoder_type_str(encoder->encoder_type), 134731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes encoder->possible_crtcs, 135731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes encoder->possible_clones); 136731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes drmModeFreeEncoder(encoder); 137731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes } 1380243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg printf("\n"); 1390243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg} 1400243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg 1410243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsbergvoid dump_mode(struct drm_mode_modeinfo *mode) 1420243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg{ 1430243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg printf(" %s %.02f %d %d %d %d %d %d %d %d\n", 1440243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg mode->name, 1450243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg (float)mode->vrefresh / 1000, 1460243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg mode->hdisplay, 1470243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg mode->hsync_start, 1480243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg mode->hsync_end, 1490243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg mode->htotal, 1500243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg mode->vdisplay, 1510243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg mode->vsync_start, 1520243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg mode->vsync_end, 1530243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg mode->vtotal); 154731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes} 155731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 156731cd5526e5c732d51307b26e784f454a724a699Jesse Barnesvoid dump_connectors(void) 157731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes{ 158731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes drmModeConnector *connector; 159731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes int i, j; 160731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 161731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes printf("Connectors:\n"); 162731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes printf("id\tencoder\tstatus\t\ttype\tsize (mm)\tmodes\n"); 163731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes for (i = 0; i < resources->count_connectors; i++) { 164731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes connector = drmModeGetConnector(fd, resources->connectors[i]); 165731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 166731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes if (!connector) { 167731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes fprintf(stderr, "could not get connector %i: %s\n", 168731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes resources->connectors[i], strerror(errno)); 169731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes continue; 170731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes } 171731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 172731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes printf("%d\t%d\t%s\t%s\t%dx%d\t\t%d\n", 173731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes connector->connector_id, 174731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes connector->encoder_id, 175731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes connector_status_str(connector->connection), 176731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes connector_type_str(connector->connector_type), 177731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes connector->mmWidth, connector->mmHeight, 178731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes connector->count_modes); 179731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 180731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes if (!connector->count_modes) 181731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes continue; 182731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 183731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes printf(" modes:\n"); 184731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes printf(" name refresh (Hz) hdisp hss hse htot vdisp " 185731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes "vss vse vtot)\n"); 1860243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg for (j = 0; j < connector->count_modes; j++) 1870243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg dump_mode(&connector->modes[j]); 1880243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg 189731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes drmModeFreeConnector(connector); 190731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes } 1910243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg printf("\n"); 192731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes} 193731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 194731cd5526e5c732d51307b26e784f454a724a699Jesse Barnesvoid dump_crtcs(void) 195731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes{ 196731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes drmModeCrtc *crtc; 197731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes int i; 198731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 1990243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg printf("CRTCs:\n"); 2000243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg printf("id\tfb\tpos\tsize\n"); 201731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes for (i = 0; i < resources->count_crtcs; i++) { 202731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes crtc = drmModeGetCrtc(fd, resources->crtcs[i]); 203731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 204731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes if (!crtc) { 205731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes fprintf(stderr, "could not get crtc %i: %s\n", 206731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes resources->crtcs[i], strerror(errno)); 207731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes continue; 208731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes } 2090243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg printf("%d\t%d\t(%d,%d)\t(%dx%d)\n", 2100243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg crtc->crtc_id, 2110243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg crtc->buffer_id, 2120243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg crtc->x, crtc->y, 2130243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg crtc->width, crtc->height); 2140243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg dump_mode(&crtc->mode); 2150243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg 216731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes drmModeFreeCrtc(crtc); 217731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes } 2180243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg printf("\n"); 219731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes} 220731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 221731cd5526e5c732d51307b26e784f454a724a699Jesse Barnesvoid dump_framebuffers(void) 222731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes{ 223731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes drmModeFB *fb; 224731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes int i; 225731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 2260243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg printf("Frame buffers:\n"); 2270243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg printf("id\tsize\tpitch\n"); 228731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes for (i = 0; i < resources->count_fbs; i++) { 229731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes fb = drmModeGetFB(fd, resources->fbs[i]); 230731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 231731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes if (!fb) { 232731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes fprintf(stderr, "could not get fb %i: %s\n", 233731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes resources->fbs[i], strerror(errno)); 234731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes continue; 235731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes } 2360243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg printf("%d\t(%dx%d)\t%d\n", 2370243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg fb->fb_id, 2380243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg fb->width, fb->height); 2390243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg 240731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes drmModeFreeFB(fb); 241731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes } 2420243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg printf("\n"); 243731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes} 244731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 245731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes/* 246731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * Mode setting with the kernel interfaces is a bit of a chore. 247731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * First you have to find the connector in question and make sure the 248731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * requested mode is available. 249731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * Then you need to find the encoder attached to that connector so you 250731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * can bind it with a free crtc. 251731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes */ 252669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsbergstruct connector { 253669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg int id; 254669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg char mode_str[64]; 255669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg struct drm_mode_modeinfo *mode; 256669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg drmModeEncoder *encoder; 257669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg}; 258669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg 259669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsbergstatic void 260669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsbergconnector_find_mode(struct connector *c) 261731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes{ 262731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes drmModeConnector *connector; 263731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes int i, j, size, ret, width, height; 264731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 265731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes /* First, find the connector & mode */ 266669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg c->mode = NULL; 267731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes for (i = 0; i < resources->count_connectors; i++) { 268731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes connector = drmModeGetConnector(fd, resources->connectors[i]); 269731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 270731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes if (!connector) { 271731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes fprintf(stderr, "could not get connector %i: %s\n", 272731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes resources->connectors[i], strerror(errno)); 273731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes drmModeFreeConnector(connector); 274731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes continue; 275731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes } 276731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 277731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes if (!connector->count_modes) { 278731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes drmModeFreeConnector(connector); 279731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes continue; 280731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes } 281731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 282669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg if (connector->connector_id != c->id) { 283731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes drmModeFreeConnector(connector); 284731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes continue; 285731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes } 286731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 287731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes for (j = 0; j < connector->count_modes; j++) { 288669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg c->mode = &connector->modes[j]; 289669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg if (!strcmp(c->mode->name, c->mode_str)) 290731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes break; 291731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes } 292731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 293731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes /* Found it, break out */ 294669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg if (c->mode) 295731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes break; 296731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 297731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes drmModeFreeConnector(connector); 298731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes } 299731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 300669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg if (!c->mode) { 301669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg fprintf(stderr, "failed to find mode \"%s\"\n", c->mode_str); 302731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes return; 303731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes } 304731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 305731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes /* Now get the encoder */ 306731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes for (i = 0; i < resources->count_encoders; i++) { 307669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg c->encoder = drmModeGetEncoder(fd, resources->encoders[i]); 308731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 309669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg if (!c->encoder) { 310731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes fprintf(stderr, "could not get encoder %i: %s\n", 311731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes resources->encoders[i], strerror(errno)); 312669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg drmModeFreeEncoder(c->encoder); 313731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes continue; 314731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes } 315731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 316669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg if (c->encoder->encoder_id == connector->encoder_id) 317731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes break; 318731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 319669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg drmModeFreeEncoder(c->encoder); 320669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg } 321669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg} 322669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg 3237a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg#ifdef HAVE_CAIRO 3247a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg 3257a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsbergstatic int 3267a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsbergcreate_test_buffer(drm_intel_bufmgr *bufmgr, 3277a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg int width, int height, int *stride_out, drm_intel_bo **bo_out) 328669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg{ 329669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg drm_intel_bo *bo; 3307a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg unsigned int *fb_ptr; 3317a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg int size, ret, i, stride; 332669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg div_t d; 3337a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg cairo_surface_t *surface; 3347a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg cairo_t *cr; 3357a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg char buf[64]; 3367a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg int x, y; 337669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg 3387a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height); 3397a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg stride = cairo_image_surface_get_stride(surface); 3407a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg size = stride * height; 3417a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg fb_ptr = (unsigned int *) cairo_image_surface_get_data(surface); 3427a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg 3437a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg /* paint the buffer with colored tiles */ 3447a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg for (i = 0; i < width * height; i++) { 3457a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg d = div(i, width); 3467a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg fb_ptr[i] = 0x00130502 * (d.quot >> 6) + 0x000a1120 * (d.rem >> 6); 347731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes } 348731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 3497a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg cr = cairo_create(surface); 3507a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg cairo_set_line_cap(cr, CAIRO_LINE_CAP_SQUARE); 3517a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg for (x = 0; x < width; x += 250) 3527a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg for (y = 0; y < height; y += 250) { 3537a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg cairo_set_operator(cr, CAIRO_OPERATOR_OVER); 3547a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg cairo_move_to(cr, x, y - 20); 3557a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg cairo_line_to(cr, x, y + 20); 3567a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg cairo_move_to(cr, x - 20, y); 3577a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg cairo_line_to(cr, x + 20, y); 3587a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg cairo_new_sub_path(cr); 3597a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg cairo_arc(cr, x, y, 10, 0, M_PI * 2); 3607a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg cairo_set_line_width(cr, 4); 3617a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg cairo_set_source_rgb(cr, 0, 0, 0); 3627a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg cairo_stroke_preserve(cr); 3637a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg cairo_set_source_rgb(cr, 1, 1, 1); 3647a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg cairo_set_line_width(cr, 2); 3657a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg cairo_stroke(cr); 3667a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg snprintf(buf, sizeof buf, "%d, %d", x, y); 3677a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg cairo_move_to(cr, x + 20, y + 20); 3687a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg cairo_text_path(cr, buf); 3697a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg cairo_set_source_rgb(cr, 0, 0, 0); 3707a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg cairo_stroke_preserve(cr); 3717a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg cairo_set_source_rgb(cr, 1, 1, 1); 3727a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg cairo_fill(cr); 3737a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg } 3747a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg 3757a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg cairo_destroy(cr); 3767a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg 3777a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg bo = drm_intel_bo_alloc(bufmgr, "frontbuffer", size, 4096); 3787a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg if (!bo) { 3797a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg fprintf(stderr, "failed to alloc buffer: %s\n", 3807a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg strerror(errno)); 3817a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg return -1; 382731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes } 383731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 3847a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg drm_intel_bo_subdata(bo, 0, size, fb_ptr); 3857a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg 3867a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg cairo_surface_destroy(surface); 3877a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg 3887a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg *bo_out = bo; 3897a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg *stride_out = stride; 3907a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg 3917a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg return 0; 3927a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg} 3937a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg 3947a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg#else 3957a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg 3967a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsbergstatic int 3977a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsbergcreate_test_buffer(drm_intel_bufmgr *bufmgr, 3987a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg int width, int height, int *stride_out, drm_intel_bo **bo_out) 3997a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg{ 4007a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg drm_intel_bo *bo; 4017a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg unsigned int *fb_ptr; 4027a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg int size, ret, i, stride; 4037a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg div_t d; 4047a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg 405731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes /* Mode size at 32 bpp */ 4067a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg stride = width * 4; 4077a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg size = stride * height; 408731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 409731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes bo = drm_intel_bo_alloc(bufmgr, "frontbuffer", size, 4096); 410731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes if (!bo) { 411731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes fprintf(stderr, "failed to alloc buffer: %s\n", 412731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes strerror(errno)); 4137a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg return -1; 414731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes } 415731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 416731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes ret = drm_intel_gem_bo_map_gtt(bo); 417731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes if (ret) { 418731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes fprintf(stderr, "failed to GTT map buffer: %s\n", 419731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes strerror(errno)); 4207a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg return -1; 421731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes } 422731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 423731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes fb_ptr = bo->virtual; 424731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 425d9c55a6becb530dcf11bc980cb6b31843be0b8c2Kristian Høgsberg /* paint the buffer with colored tiles */ 426d9c55a6becb530dcf11bc980cb6b31843be0b8c2Kristian Høgsberg for (i = 0; i < width * height; i++) { 427d9c55a6becb530dcf11bc980cb6b31843be0b8c2Kristian Høgsberg d = div(i, width); 428d9c55a6becb530dcf11bc980cb6b31843be0b8c2Kristian Høgsberg fb_ptr[i] = 0x00130502 * (d.quot >> 6) + 0x000a1120 * (d.rem >> 6); 429d9c55a6becb530dcf11bc980cb6b31843be0b8c2Kristian Høgsberg } 4307a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg drm_intel_bo_unmap(bo); 4317a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg 4327a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg *bo_out = bo; 4337a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg *stride_out = stride; 4347a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg 4357a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg return 0; 4367a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg} 4377a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg 4387a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg#endif 4397a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg 4407a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsbergstatic void 4417a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsbergset_mode(struct connector *c, int count) 4427a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg{ 4437a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg drmModeConnector *connector; 4447a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg drmModeEncoder *encoder = NULL; 4457a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg struct drm_mode_modeinfo *mode = NULL; 4467a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg drm_intel_bufmgr *bufmgr; 4477a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg drm_intel_bo *bo; 4487a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg unsigned int fb_id; 4497a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg int i, j, ret, width, height, x, stride; 4507a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg 4517a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg width = 0; 4527a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg height = 0; 4537a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg for (i = 0; i < count; i++) { 4547a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg connector_find_mode(&c[i]); 4557a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg if (c[i].mode == NULL) 4567a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg continue; 4577a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg width += c[i].mode->hdisplay; 4587a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg if (height < c[i].mode->vdisplay) 4597a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg height = c[i].mode->vdisplay; 4607a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg } 4617a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg 4627a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg bufmgr = drm_intel_bufmgr_gem_init(fd, 2<<20); 4637a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg if (!bufmgr) { 4647a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg fprintf(stderr, "failed to init bufmgr: %s\n", strerror(errno)); 4657a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg return; 4667a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg } 4677a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg 4687a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg if (create_test_buffer(bufmgr, width, height, &stride, &bo)) 4697a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg return; 470731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 4717a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg ret = drmModeAddFB(fd, width, height, 32, 32, stride, bo->handle, 472731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes &fb_id); 473731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes if (ret) { 474731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes fprintf(stderr, "failed to add fb: %s\n", strerror(errno)); 475731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes return; 476731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes } 477731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 478669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg x = 0; 479669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg for (i = 0; i < count; i++) { 480669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg if (c[i].mode == NULL) 481669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg continue; 482669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg ret = drmModeSetCrtc(fd, c[i].encoder->crtc_id, fb_id, x, 0, 483669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg &c[i].id, 1, c[i].mode); 484669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg x += c[i].mode->hdisplay; 485669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg 486669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg if (ret) { 487669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg fprintf(stderr, "failed to set mode: %s\n", strerror(errno)); 488669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg return; 489669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg } 490731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes } 491731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes} 492731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 493731cd5526e5c732d51307b26e784f454a724a699Jesse Barnesextern char *optarg; 494731cd5526e5c732d51307b26e784f454a724a699Jesse Barnesextern int optind, opterr, optopt; 495731cd5526e5c732d51307b26e784f454a724a699Jesse Barnesstatic char optstr[] = "ecpmfs:"; 496731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 497731cd5526e5c732d51307b26e784f454a724a699Jesse Barnesvoid usage(char *name) 498731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes{ 499731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes fprintf(stderr, "usage: %s [-ecpmf]\n", name); 500731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes fprintf(stderr, "\t-e\tlist encoders\n"); 501731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes fprintf(stderr, "\t-c\tlist connectors\n"); 502731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes fprintf(stderr, "\t-p\tlist CRTCs (pipes)\n"); 503731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes fprintf(stderr, "\t-m\tlist modes\n"); 504731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes fprintf(stderr, "\t-f\tlist framebuffers\n"); 505731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes fprintf(stderr, "\t-s <connector_id>:<mode>\tset a mode\n"); 506731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes fprintf(stderr, "\n\tDefault is to dump all info.\n"); 507731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes exit(0); 508731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes} 509731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 510731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes#define dump_resource(res) if (res) dump_##res() 511731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 512731cd5526e5c732d51307b26e784f454a724a699Jesse Barnesint main(int argc, char **argv) 513731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes{ 514731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes int c; 515731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes int encoders = 0, connectors = 0, crtcs = 0, framebuffers = 0; 516731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes char *modules[] = { "i915", "radeon" }; 517731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes char *modeset = NULL, *mode, *connector; 518669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg int i, connector_id, count = 0; 519669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg struct connector con_args[2]; 520669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg 521731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes opterr = 0; 522731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes while ((c = getopt(argc, argv, optstr)) != -1) { 523731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes switch (c) { 524731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes case 'e': 525731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes encoders = 1; 526731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes break; 527731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes case 'c': 528731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes connectors = 1; 529731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes break; 530731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes case 'p': 531731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes crtcs = 1; 532731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes break; 533731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes case 'm': 534731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes modes = 1; 535731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes break; 536731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes case 'f': 537731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes framebuffers = 1; 538731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes break; 539731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes case 's': 540731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes modeset = strdup(optarg); 541669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg if (sscanf(optarg, "%d:%64s", 542669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg &con_args[count].id, 543669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg &con_args[count].mode_str) != 2) 544669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg usage(argv[0]); 545669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg printf("setting mode %s on connector %d\n", 546669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg con_args[count].mode_str, 547669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg con_args[count].id); 548669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg count++; 549731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes break; 550731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes default: 551731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes usage(argv[0]); 552731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes break; 553731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes } 554731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes } 555731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 556731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes if (argc == 1) 557731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes encoders = connectors = crtcs = modes = framebuffers = 1; 558731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 559731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes for (i = 0; i < ARRAY_SIZE(modules); i++) { 560731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes printf("trying to load module %s...", modules[i]); 561731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes fd = drmOpen(modules[i], NULL); 562731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes if (fd < 0) { 563731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes printf("failed.\n"); 564731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes } else { 565731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes printf("success.\n"); 566731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes break; 567731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes } 568731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes } 569731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 570731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes if (i == ARRAY_SIZE(modules)) { 571731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes fprintf(stderr, "failed to load any modules, aborting.\n"); 572731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes return -1; 573731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes } 574731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 575731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes resources = drmModeGetResources(fd); 576731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes if (!resources) { 577731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes fprintf(stderr, "drmModeGetResources failed: %s\n", 578731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes strerror(errno)); 579731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes drmClose(fd); 580731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes return 1; 581731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes } 582731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 583731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes dump_resource(encoders); 584731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes dump_resource(connectors); 585731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes dump_resource(crtcs); 586731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes dump_resource(framebuffers); 587731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 588669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg if (count > 0) { 589669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg set_mode(con_args, count); 5902c113a1b159f57ab94b54316ece49c677cfe04ceKristian Høgsberg getchar(); 591731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes } 592731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 593731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes drmModeFreeResources(resources); 594731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 595731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes return 0; 596731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes} 597