modetest.c revision 8b8803695b24d4cb4d041437a4709be06e59471b
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; 2578b8803695b24d4cb4d041437a4709be06e59471bKristian Høgsberg int crtc; 258669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg}; 259669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg 260669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsbergstatic void 261669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsbergconnector_find_mode(struct connector *c) 262731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes{ 263731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes drmModeConnector *connector; 264731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes int i, j, size, ret, width, height; 265731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 266731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes /* First, find the connector & mode */ 267669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg c->mode = NULL; 268731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes for (i = 0; i < resources->count_connectors; i++) { 269731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes connector = drmModeGetConnector(fd, resources->connectors[i]); 270731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 271731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes if (!connector) { 272731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes fprintf(stderr, "could not get connector %i: %s\n", 273731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes resources->connectors[i], strerror(errno)); 274731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes drmModeFreeConnector(connector); 275731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes continue; 276731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes } 277731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 278731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes if (!connector->count_modes) { 279731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes drmModeFreeConnector(connector); 280731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes continue; 281731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes } 282731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 283669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg if (connector->connector_id != c->id) { 284731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes drmModeFreeConnector(connector); 285731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes continue; 286731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes } 287731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 288731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes for (j = 0; j < connector->count_modes; j++) { 289669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg c->mode = &connector->modes[j]; 290669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg if (!strcmp(c->mode->name, c->mode_str)) 291731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes break; 292731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes } 293731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 294731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes /* Found it, break out */ 295669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg if (c->mode) 296731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes break; 297731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 298731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes drmModeFreeConnector(connector); 299731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes } 300731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 301669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg if (!c->mode) { 302669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg fprintf(stderr, "failed to find mode \"%s\"\n", c->mode_str); 303731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes return; 304731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes } 305731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 306731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes /* Now get the encoder */ 307731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes for (i = 0; i < resources->count_encoders; i++) { 308669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg c->encoder = drmModeGetEncoder(fd, resources->encoders[i]); 309731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 310669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg if (!c->encoder) { 311731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes fprintf(stderr, "could not get encoder %i: %s\n", 312731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes resources->encoders[i], strerror(errno)); 313669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg drmModeFreeEncoder(c->encoder); 314731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes continue; 315731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes } 316731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 317669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg if (c->encoder->encoder_id == connector->encoder_id) 318731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes break; 319731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 320669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg drmModeFreeEncoder(c->encoder); 321669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg } 3228b8803695b24d4cb4d041437a4709be06e59471bKristian Høgsberg 3238b8803695b24d4cb4d041437a4709be06e59471bKristian Høgsberg if (c->crtc == -1) 3248b8803695b24d4cb4d041437a4709be06e59471bKristian Høgsberg c->crtc = c->encoder->crtc_id; 325669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg} 326669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg 3277a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg#ifdef HAVE_CAIRO 3287a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg 3297a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsbergstatic int 3307a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsbergcreate_test_buffer(drm_intel_bufmgr *bufmgr, 3317a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg int width, int height, int *stride_out, drm_intel_bo **bo_out) 332669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg{ 333669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg drm_intel_bo *bo; 3347a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg unsigned int *fb_ptr; 3357a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg int size, ret, i, stride; 336669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg div_t d; 3377a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg cairo_surface_t *surface; 3387a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg cairo_t *cr; 3397a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg char buf[64]; 3407a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg int x, y; 341669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg 3427a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height); 3437a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg stride = cairo_image_surface_get_stride(surface); 3447a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg size = stride * height; 3457a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg fb_ptr = (unsigned int *) cairo_image_surface_get_data(surface); 3467a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg 3477a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg /* paint the buffer with colored tiles */ 3487a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg for (i = 0; i < width * height; i++) { 3497a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg d = div(i, width); 3507a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg fb_ptr[i] = 0x00130502 * (d.quot >> 6) + 0x000a1120 * (d.rem >> 6); 351731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes } 352731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 3537a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg cr = cairo_create(surface); 3547a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg cairo_set_line_cap(cr, CAIRO_LINE_CAP_SQUARE); 3557a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg for (x = 0; x < width; x += 250) 3567a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg for (y = 0; y < height; y += 250) { 3577a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg cairo_set_operator(cr, CAIRO_OPERATOR_OVER); 3587a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg cairo_move_to(cr, x, y - 20); 3597a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg cairo_line_to(cr, x, y + 20); 3607a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg cairo_move_to(cr, x - 20, y); 3617a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg cairo_line_to(cr, x + 20, y); 3627a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg cairo_new_sub_path(cr); 3637a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg cairo_arc(cr, x, y, 10, 0, M_PI * 2); 3647a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg cairo_set_line_width(cr, 4); 3657a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg cairo_set_source_rgb(cr, 0, 0, 0); 3667a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg cairo_stroke_preserve(cr); 3677a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg cairo_set_source_rgb(cr, 1, 1, 1); 3687a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg cairo_set_line_width(cr, 2); 3697a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg cairo_stroke(cr); 3707a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg snprintf(buf, sizeof buf, "%d, %d", x, y); 3717a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg cairo_move_to(cr, x + 20, y + 20); 3727a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg cairo_text_path(cr, buf); 3737a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg cairo_set_source_rgb(cr, 0, 0, 0); 3747a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg cairo_stroke_preserve(cr); 3757a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg cairo_set_source_rgb(cr, 1, 1, 1); 3767a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg cairo_fill(cr); 3777a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg } 3787a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg 3797a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg cairo_destroy(cr); 3807a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg 3817a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg bo = drm_intel_bo_alloc(bufmgr, "frontbuffer", size, 4096); 3827a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg if (!bo) { 3837a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg fprintf(stderr, "failed to alloc buffer: %s\n", 3847a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg strerror(errno)); 3857a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg return -1; 386731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes } 387731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 3887a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg drm_intel_bo_subdata(bo, 0, size, fb_ptr); 3897a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg 3907a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg cairo_surface_destroy(surface); 3917a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg 3927a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg *bo_out = bo; 3937a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg *stride_out = stride; 3947a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg 3957a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg return 0; 3967a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg} 3977a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg 3987a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg#else 3997a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg 4007a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsbergstatic int 4017a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsbergcreate_test_buffer(drm_intel_bufmgr *bufmgr, 4027a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg int width, int height, int *stride_out, drm_intel_bo **bo_out) 4037a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg{ 4047a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg drm_intel_bo *bo; 4057a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg unsigned int *fb_ptr; 4067a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg int size, ret, i, stride; 4077a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg div_t d; 4087a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg 409731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes /* Mode size at 32 bpp */ 4107a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg stride = width * 4; 4117a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg size = stride * height; 412731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 413731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes bo = drm_intel_bo_alloc(bufmgr, "frontbuffer", size, 4096); 414731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes if (!bo) { 415731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes fprintf(stderr, "failed to alloc buffer: %s\n", 416731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes strerror(errno)); 4177a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg return -1; 418731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes } 419731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 420731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes ret = drm_intel_gem_bo_map_gtt(bo); 421731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes if (ret) { 422731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes fprintf(stderr, "failed to GTT map buffer: %s\n", 423731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes strerror(errno)); 4247a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg return -1; 425731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes } 426731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 427731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes fb_ptr = bo->virtual; 428731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 429d9c55a6becb530dcf11bc980cb6b31843be0b8c2Kristian Høgsberg /* paint the buffer with colored tiles */ 430d9c55a6becb530dcf11bc980cb6b31843be0b8c2Kristian Høgsberg for (i = 0; i < width * height; i++) { 431d9c55a6becb530dcf11bc980cb6b31843be0b8c2Kristian Høgsberg d = div(i, width); 432d9c55a6becb530dcf11bc980cb6b31843be0b8c2Kristian Høgsberg fb_ptr[i] = 0x00130502 * (d.quot >> 6) + 0x000a1120 * (d.rem >> 6); 433d9c55a6becb530dcf11bc980cb6b31843be0b8c2Kristian Høgsberg } 4347a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg drm_intel_bo_unmap(bo); 4357a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg 4367a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg *bo_out = bo; 4377a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg *stride_out = stride; 4387a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg 4397a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg return 0; 4407a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg} 4417a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg 4427a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg#endif 4437a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg 4447a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsbergstatic void 4457a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsbergset_mode(struct connector *c, int count) 4467a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg{ 4477a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg drmModeConnector *connector; 4487a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg drmModeEncoder *encoder = NULL; 4497a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg struct drm_mode_modeinfo *mode = NULL; 4507a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg drm_intel_bufmgr *bufmgr; 4517a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg drm_intel_bo *bo; 4527a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg unsigned int fb_id; 4537a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg int i, j, ret, width, height, x, stride; 4547a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg 4557a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg width = 0; 4567a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg height = 0; 4577a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg for (i = 0; i < count; i++) { 4587a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg connector_find_mode(&c[i]); 4597a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg if (c[i].mode == NULL) 4607a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg continue; 4617a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg width += c[i].mode->hdisplay; 4627a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg if (height < c[i].mode->vdisplay) 4637a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg height = c[i].mode->vdisplay; 4647a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg } 4657a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg 4667a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg bufmgr = drm_intel_bufmgr_gem_init(fd, 2<<20); 4677a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg if (!bufmgr) { 4687a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg fprintf(stderr, "failed to init bufmgr: %s\n", strerror(errno)); 4697a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg return; 4707a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg } 4717a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg 4727a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg if (create_test_buffer(bufmgr, width, height, &stride, &bo)) 4737a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg return; 474731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 4757a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg ret = drmModeAddFB(fd, width, height, 32, 32, stride, bo->handle, 476731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes &fb_id); 477731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes if (ret) { 478731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes fprintf(stderr, "failed to add fb: %s\n", strerror(errno)); 479731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes return; 480731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes } 481731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 482669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg x = 0; 483669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg for (i = 0; i < count; i++) { 4848b8803695b24d4cb4d041437a4709be06e59471bKristian Høgsberg int crtc_id; 485669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg if (c[i].mode == NULL) 486669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg continue; 4878b8803695b24d4cb4d041437a4709be06e59471bKristian Høgsberg 4888b8803695b24d4cb4d041437a4709be06e59471bKristian Høgsberg printf("setting mode %s on connector %d, crtc %d\n", 4898b8803695b24d4cb4d041437a4709be06e59471bKristian Høgsberg c[i].mode_str, c[i].id, c[i].crtc); 4908b8803695b24d4cb4d041437a4709be06e59471bKristian Høgsberg 4918b8803695b24d4cb4d041437a4709be06e59471bKristian Høgsberg ret = drmModeSetCrtc(fd, c[i].crtc, fb_id, x, 0, 492669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg &c[i].id, 1, c[i].mode); 493669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg x += c[i].mode->hdisplay; 494669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg 495669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg if (ret) { 496669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg fprintf(stderr, "failed to set mode: %s\n", strerror(errno)); 497669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg return; 498669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg } 499731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes } 500731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes} 501731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 502731cd5526e5c732d51307b26e784f454a724a699Jesse Barnesextern char *optarg; 503731cd5526e5c732d51307b26e784f454a724a699Jesse Barnesextern int optind, opterr, optopt; 504731cd5526e5c732d51307b26e784f454a724a699Jesse Barnesstatic char optstr[] = "ecpmfs:"; 505731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 506731cd5526e5c732d51307b26e784f454a724a699Jesse Barnesvoid usage(char *name) 507731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes{ 508731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes fprintf(stderr, "usage: %s [-ecpmf]\n", name); 509731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes fprintf(stderr, "\t-e\tlist encoders\n"); 510731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes fprintf(stderr, "\t-c\tlist connectors\n"); 511731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes fprintf(stderr, "\t-p\tlist CRTCs (pipes)\n"); 512731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes fprintf(stderr, "\t-m\tlist modes\n"); 513731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes fprintf(stderr, "\t-f\tlist framebuffers\n"); 514731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes fprintf(stderr, "\t-s <connector_id>:<mode>\tset a mode\n"); 5158b8803695b24d4cb4d041437a4709be06e59471bKristian Høgsberg fprintf(stderr, "\t-s <connector_id>@<crtc_id>:<mode>\tset a mode\n"); 516731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes fprintf(stderr, "\n\tDefault is to dump all info.\n"); 517731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes exit(0); 518731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes} 519731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 520731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes#define dump_resource(res) if (res) dump_##res() 521731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 522731cd5526e5c732d51307b26e784f454a724a699Jesse Barnesint main(int argc, char **argv) 523731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes{ 524731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes int c; 525731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes int encoders = 0, connectors = 0, crtcs = 0, framebuffers = 0; 526731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes char *modules[] = { "i915", "radeon" }; 527731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes char *modeset = NULL, *mode, *connector; 528669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg int i, connector_id, count = 0; 529669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg struct connector con_args[2]; 530669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg 531731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes opterr = 0; 532731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes while ((c = getopt(argc, argv, optstr)) != -1) { 533731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes switch (c) { 534731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes case 'e': 535731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes encoders = 1; 536731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes break; 537731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes case 'c': 538731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes connectors = 1; 539731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes break; 540731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes case 'p': 541731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes crtcs = 1; 542731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes break; 543731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes case 'm': 544731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes modes = 1; 545731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes break; 546731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes case 'f': 547731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes framebuffers = 1; 548731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes break; 549731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes case 's': 550731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes modeset = strdup(optarg); 5518b8803695b24d4cb4d041437a4709be06e59471bKristian Høgsberg con_args[count].crtc = -1; 552669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg if (sscanf(optarg, "%d:%64s", 553669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg &con_args[count].id, 5548b8803695b24d4cb4d041437a4709be06e59471bKristian Høgsberg &con_args[count].mode_str) != 2 && 5558b8803695b24d4cb4d041437a4709be06e59471bKristian Høgsberg sscanf(optarg, "%d@%d:%64s", 5568b8803695b24d4cb4d041437a4709be06e59471bKristian Høgsberg &con_args[count].id, 5578b8803695b24d4cb4d041437a4709be06e59471bKristian Høgsberg &con_args[count].crtc, 5588b8803695b24d4cb4d041437a4709be06e59471bKristian Høgsberg &con_args[count].mode_str) != 3) 559669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg usage(argv[0]); 560669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg count++; 561731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes break; 562731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes default: 563731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes usage(argv[0]); 564731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes break; 565731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes } 566731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes } 567731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 568731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes if (argc == 1) 569731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes encoders = connectors = crtcs = modes = framebuffers = 1; 570731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 571731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes for (i = 0; i < ARRAY_SIZE(modules); i++) { 572731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes printf("trying to load module %s...", modules[i]); 573731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes fd = drmOpen(modules[i], NULL); 574731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes if (fd < 0) { 575731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes printf("failed.\n"); 576731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes } else { 577731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes printf("success.\n"); 578731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes break; 579731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes } 580731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes } 581731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 582731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes if (i == ARRAY_SIZE(modules)) { 583731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes fprintf(stderr, "failed to load any modules, aborting.\n"); 584731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes return -1; 585731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes } 586731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 587731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes resources = drmModeGetResources(fd); 588731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes if (!resources) { 589731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes fprintf(stderr, "drmModeGetResources failed: %s\n", 590731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes strerror(errno)); 591731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes drmClose(fd); 592731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes return 1; 593731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes } 594731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 595731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes dump_resource(encoders); 596731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes dump_resource(connectors); 597731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes dump_resource(crtcs); 598731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes dump_resource(framebuffers); 599731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 600669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg if (count > 0) { 601669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg set_mode(con_args, count); 6022c113a1b159f57ab94b54316ece49c677cfe04ceKristian Høgsberg getchar(); 603731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes } 604731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 605731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes drmModeFreeResources(resources); 606731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 607731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes return 0; 608731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes} 609