blob: 5973e8ed22cec8de1d04c47fd87c7716ae304615 [file] [log] [blame]
Rob Clark487687e2011-07-17 17:29:02 -05001/*
2 * Copyright © 2007 Red Hat, Inc.
3 * Copyright © 2008 Maarten Maathuis
4 * Copyright © 2011 Texas Instruments, Inc
5 *
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the next
15 * paragraph) shall be included in all copies or substantial portions of the
16 * Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24 * SOFTWARE.
25 *
26 * Authors:
27 * Dave Airlie <airlied@redhat.com>
28 * Ian Elliott <ianelliottus@yahoo.com>
29 */
30
31#ifdef HAVE_CONFIG_H
32#include "config.h"
33#endif
34
Dave Barnish2742d152013-03-13 13:36:58 +000035/* TODO: MIDEGL-1430: cleanup #includes, remove unnecessary ones */
Rob Clark74210d52012-01-08 17:59:08 -060036
Raymond Smithcb4c0372012-03-29 10:44:27 +010037#include "xorg-server.h"
Rob Clark487687e2011-07-17 17:29:02 -050038#include "xorgVersion.h"
39
Rob Clark487687e2011-07-17 17:29:02 -050040#include <sys/stat.h>
41
Rob Clark487687e2011-07-17 17:29:02 -050042#include <string.h>
43#include <math.h>
44#include <errno.h>
45#include <unistd.h>
46#include <stdlib.h>
47
48/* All drivers should typically include these */
49#include "xf86.h"
50#include "xf86_OSproc.h"
51#define PPC_MMIO_IS_BE
52#include "compiler.h"
Rob Clark487687e2011-07-17 17:29:02 -050053#include "mipointer.h"
54
55/* All drivers implementing backing store need this */
56#include "mibstore.h"
57
58#include "micmap.h"
59
60#include "xf86DDC.h"
61
Rob Clark487687e2011-07-17 17:29:02 -050062#include "xf86RandR12.h"
Rob Clark487687e2011-07-17 17:29:02 -050063#include "dixstruct.h"
64#include "scrnintstr.h"
Rob Clark487687e2011-07-17 17:29:02 -050065#include "fb.h"
Rob Clark487687e2011-07-17 17:29:02 -050066#include "xf86cmap.h"
67#include "shadowfb.h"
68
69#include "xf86xv.h"
70#include <X11/extensions/Xv.h>
71
72#include "xf86Cursor.h"
73#include "xf86DDC.h"
74
75#include "region.h"
76
77#include <X11/extensions/randr.h>
78
79#ifdef HAVE_XEXTPROTO_71
80#include <X11/extensions/dpmsconst.h>
81#else
82#define DPMS_SERVER
83#include <X11/extensions/dpms.h>
84#endif
85
Rob Clark487687e2011-07-17 17:29:02 -050086#include "omap_driver.h"
87
Rob Clark487687e2011-07-17 17:29:02 -050088#include "xf86Crtc.h"
Rob Clark487687e2011-07-17 17:29:02 -050089
90#include "xf86drmMode.h"
Rob Clark687c6082012-01-08 19:33:18 -060091#include "drm_fourcc.h"
Rob Clark487687e2011-07-17 17:29:02 -050092#include "X11/Xatom.h"
93
94#include <sys/ioctl.h>
95#include <libudev.h>
96
Ray Smith3c33c3d2013-03-26 16:06:37 +000097#include "drmmode_driver.h"
98
Rob Clark487687e2011-07-17 17:29:02 -050099typedef struct {
Rob Clark687c6082012-01-08 19:33:18 -0600100 /* hardware cursor: */
101 drmModePlane *ovr;
102 struct omap_bo *bo;
103 uint32_t fb_id;
104 int x, y;
Rob Clark687c6082012-01-08 19:33:18 -0600105} drmmode_cursor_rec, *drmmode_cursor_ptr;
106
107typedef struct {
Rob Clark74210d52012-01-08 17:59:08 -0600108 int fd;
Rob Clark74210d52012-01-08 17:59:08 -0600109 drmModeResPtr mode_res;
110 int cpp;
111 struct udev_monitor *uevent_monitor;
112 InputHandlerProc uevent_handler;
Rob Clark687c6082012-01-08 19:33:18 -0600113 drmmode_cursor_ptr cursor;
Rob Clark487687e2011-07-17 17:29:02 -0500114} drmmode_rec, *drmmode_ptr;
115
116typedef struct {
Rob Clark74210d52012-01-08 17:59:08 -0600117 drmmode_ptr drmmode;
118 drmModeCrtcPtr mode_crtc;
Stéphane Marchesinb8b35202012-10-02 20:27:40 -0700119 int cursor_visible;
Rob Clark487687e2011-07-17 17:29:02 -0500120} drmmode_crtc_private_rec, *drmmode_crtc_private_ptr;
121
122typedef struct {
123 drmModePropertyPtr mode_prop;
124 int index; /* Index within the kernel-side property arrays for
Rob Clark74210d52012-01-08 17:59:08 -0600125 * this connector. */
Rob Clark487687e2011-07-17 17:29:02 -0500126 int num_atoms; /* if range prop, num_atoms == 1; if enum prop,
Rob Clark74210d52012-01-08 17:59:08 -0600127 * num_atoms == num_enums + 1 */
Rob Clark487687e2011-07-17 17:29:02 -0500128 Atom *atoms;
129} drmmode_prop_rec, *drmmode_prop_ptr;
130
131typedef struct {
Rob Clark74210d52012-01-08 17:59:08 -0600132 drmmode_ptr drmmode;
133 int output_id;
134 drmModeConnectorPtr mode_output;
135 drmModeEncoderPtr mode_encoder;
136 drmModePropertyBlobPtr edid_blob;
137 int num_props;
138 drmmode_prop_ptr props;
Rob Clark487687e2011-07-17 17:29:02 -0500139} drmmode_output_private_rec, *drmmode_output_private_ptr;
140
141static void drmmode_output_dpms(xf86OutputPtr output, int mode);
Rob Clark487687e2011-07-17 17:29:02 -0500142
Rob Clark687c6082012-01-08 19:33:18 -0600143static drmmode_ptr
144drmmode_from_scrn(ScrnInfoPtr pScrn)
145{
146 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
147 drmmode_crtc_private_ptr drmmode_crtc;
148
149 drmmode_crtc = xf86_config->crtc[0]->driver_private;
150 return drmmode_crtc->drmmode;
151}
152
Rob Clark487687e2011-07-17 17:29:02 -0500153static void
154drmmode_ConvertFromKMode(ScrnInfoPtr pScrn, drmModeModeInfo *kmode,
Rob Clark74210d52012-01-08 17:59:08 -0600155 DisplayModePtr mode)
Rob Clark487687e2011-07-17 17:29:02 -0500156{
Rob Clark74210d52012-01-08 17:59:08 -0600157 memset(mode, 0, sizeof(DisplayModeRec));
158 mode->status = MODE_OK;
Rob Clark487687e2011-07-17 17:29:02 -0500159
Rob Clark74210d52012-01-08 17:59:08 -0600160 mode->Clock = kmode->clock;
Rob Clark487687e2011-07-17 17:29:02 -0500161
Rob Clark74210d52012-01-08 17:59:08 -0600162 mode->HDisplay = kmode->hdisplay;
163 mode->HSyncStart = kmode->hsync_start;
164 mode->HSyncEnd = kmode->hsync_end;
165 mode->HTotal = kmode->htotal;
166 mode->HSkew = kmode->hskew;
Rob Clark487687e2011-07-17 17:29:02 -0500167
Rob Clark74210d52012-01-08 17:59:08 -0600168 mode->VDisplay = kmode->vdisplay;
169 mode->VSyncStart = kmode->vsync_start;
170 mode->VSyncEnd = kmode->vsync_end;
171 mode->VTotal = kmode->vtotal;
172 mode->VScan = kmode->vscan;
Rob Clark487687e2011-07-17 17:29:02 -0500173
Rob Clark74210d52012-01-08 17:59:08 -0600174 mode->Flags = kmode->flags; //& FLAG_BITS;
175 mode->name = strdup(kmode->name);
Rob Clark487687e2011-07-17 17:29:02 -0500176
Rob Clark74210d52012-01-08 17:59:08 -0600177 DEBUG_MSG("copy mode %s (%p %p)", kmode->name, mode->name, mode);
Rob Clark487687e2011-07-17 17:29:02 -0500178
Rob Clark74210d52012-01-08 17:59:08 -0600179 if (kmode->type & DRM_MODE_TYPE_DRIVER)
180 mode->type = M_T_DRIVER;
181 if (kmode->type & DRM_MODE_TYPE_PREFERRED)
182 mode->type |= M_T_PREFERRED;
Rob Clark487687e2011-07-17 17:29:02 -0500183
Rob Clark74210d52012-01-08 17:59:08 -0600184 xf86SetModeCrtc (mode, pScrn->adjustFlags);
185}
Rob Clark487687e2011-07-17 17:29:02 -0500186
187static void
188drmmode_ConvertToKMode(ScrnInfoPtr pScrn, drmModeModeInfo *kmode,
Rob Clark74210d52012-01-08 17:59:08 -0600189 DisplayModePtr mode)
Rob Clark487687e2011-07-17 17:29:02 -0500190{
Rob Clark74210d52012-01-08 17:59:08 -0600191 memset(kmode, 0, sizeof(*kmode));
Rob Clark487687e2011-07-17 17:29:02 -0500192
Rob Clark74210d52012-01-08 17:59:08 -0600193 kmode->clock = mode->Clock;
194 kmode->hdisplay = mode->HDisplay;
195 kmode->hsync_start = mode->HSyncStart;
196 kmode->hsync_end = mode->HSyncEnd;
197 kmode->htotal = mode->HTotal;
198 kmode->hskew = mode->HSkew;
Rob Clark487687e2011-07-17 17:29:02 -0500199
Rob Clark74210d52012-01-08 17:59:08 -0600200 kmode->vdisplay = mode->VDisplay;
201 kmode->vsync_start = mode->VSyncStart;
202 kmode->vsync_end = mode->VSyncEnd;
203 kmode->vtotal = mode->VTotal;
204 kmode->vscan = mode->VScan;
Rob Clark487687e2011-07-17 17:29:02 -0500205
Rob Clark74210d52012-01-08 17:59:08 -0600206 kmode->flags = mode->Flags; //& FLAG_BITS;
207 if (mode->name)
208 strncpy(kmode->name, mode->name, DRM_DISPLAY_MODE_LEN);
209 kmode->name[DRM_DISPLAY_MODE_LEN-1] = 0;
210}
Rob Clark487687e2011-07-17 17:29:02 -0500211
212static void
213drmmode_crtc_dpms(xf86CrtcPtr drmmode_crtc, int mode)
214{
Dave Barnish2742d152013-03-13 13:36:58 +0000215 // TODO: MIDEGL-1431: Implement this function
Rob Clark74210d52012-01-08 17:59:08 -0600216}
Rob Clark487687e2011-07-17 17:29:02 -0500217
218static Bool
219drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
Rob Clark74210d52012-01-08 17:59:08 -0600220 Rotation rotation, int x, int y)
Rob Clark487687e2011-07-17 17:29:02 -0500221{
222 ScrnInfoPtr pScrn = crtc->scrn;
223 OMAPPtr pOMAP = OMAPPTR(pScrn);
224 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn);
225 drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
226 drmmode_ptr drmmode = drmmode_crtc->drmmode;
227 int saved_x, saved_y;
228 Rotation saved_rotation;
229 DisplayModeRec saved_mode;
230 uint32_t *output_ids = NULL;
231 int output_count = 0;
232 int ret = TRUE;
233 int i;
David Garbett7171c522012-05-11 13:12:50 +0100234 uint32_t fb_id;
Rob Clark487687e2011-07-17 17:29:02 -0500235 drmModeModeInfo kmode;
236
237 TRACE_ENTER();
238
David Garbett7171c522012-05-11 13:12:50 +0100239 fb_id = omap_bo_get_fb(pOMAP->scanout);
240
241 if (fb_id == 0) {
David Garbett7171c522012-05-11 13:12:50 +0100242
243 DEBUG_MSG("create framebuffer: %dx%d",
244 pScrn->virtualX, pScrn->virtualY);
245
Sean Paul3e107302012-08-30 12:08:12 -0700246 ret = omap_bo_add_fb(pOMAP->scanout);
247 if (ret)
David Garbett7171c522012-05-11 13:12:50 +0100248 return FALSE;
Dave Barnish523c9ff2013-03-12 10:59:03 +0000249
250 fb_id = omap_bo_get_fb(pOMAP->scanout);
David Garbett7171c522012-05-11 13:12:50 +0100251 }
Rob Clark487687e2011-07-17 17:29:02 -0500252
253 /* Save the current mode in case there's a problem: */
254 saved_mode = crtc->mode;
255 saved_x = crtc->x;
256 saved_y = crtc->y;
257 saved_rotation = crtc->rotation;
258
259 /* Set the new mode: */
260 crtc->mode = *mode;
261 crtc->x = x;
262 crtc->y = y;
263 crtc->rotation = rotation;
264
265 output_ids = calloc(sizeof(uint32_t), xf86_config->num_output);
266 if (!output_ids) {
Dave Barnish523c9ff2013-03-12 10:59:03 +0000267 xf86DrvMsg(crtc->scrn->scrnIndex, X_ERROR,
268 "memory allocation failed in drmmode_set_mode_major()\n");
Rob Clark487687e2011-07-17 17:29:02 -0500269 ret = FALSE;
270 goto done;
271 }
272
273 for (i = 0; i < xf86_config->num_output; i++) {
274 xf86OutputPtr output = xf86_config->output[i];
275 drmmode_output_private_ptr drmmode_output;
276
277 if (output->crtc != crtc)
278 continue;
279
280 drmmode_output = output->driver_private;
281 output_ids[output_count] =
282 drmmode_output->mode_output->connector_id;
283 output_count++;
284 }
285
Dave Barnish523c9ff2013-03-12 10:59:03 +0000286 if (!xf86CrtcRotate(crtc)){
287 xf86DrvMsg(crtc->scrn->scrnIndex, X_ERROR,
288 "failed to assign rotation in drmmode_set_mode_major()\n");
289 ret = FALSE;
Rob Clark487687e2011-07-17 17:29:02 -0500290 goto done;
Dave Barnish523c9ff2013-03-12 10:59:03 +0000291 }
Rob Clark487687e2011-07-17 17:29:02 -0500292
Dave Barnish2742d152013-03-13 13:36:58 +0000293 // TODO: MIDEGL-1432: Intel puts this function here, and Nouveau puts it at the end
294 // of this function -> determine what's best for Armsoc
Mandeep Singh Bainesc874fcb2012-09-13 15:30:00 +0200295 if (crtc->funcs->gamma_set)
296 crtc->funcs->gamma_set(crtc, crtc->gamma_red, crtc->gamma_green,
297 crtc->gamma_blue, crtc->gamma_size);
Rob Clark487687e2011-07-17 17:29:02 -0500298
299 drmmode_ConvertToKMode(crtc->scrn, &kmode, mode);
300
Rob Clark487687e2011-07-17 17:29:02 -0500301 ret = drmModeSetCrtc(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id,
302 fb_id, x, y, output_ids, output_count, &kmode);
303 if (ret) {
304 xf86DrvMsg(crtc->scrn->scrnIndex, X_ERROR,
305 "failed to set mode: %s\n", strerror(-ret));
Dave Barnish523c9ff2013-03-12 10:59:03 +0000306 ret = FALSE;
307 goto done;
Rob Clark487687e2011-07-17 17:29:02 -0500308 } else {
309 ret = TRUE;
310 }
311
Rob Clark487687e2011-07-17 17:29:02 -0500312 /* Turn on any outputs on this crtc that may have been disabled: */
313 for (i = 0; i < xf86_config->num_output; i++) {
314 xf86OutputPtr output = xf86_config->output[i];
315
316 if (output->crtc != crtc)
317 continue;
318
319 drmmode_output_dpms(output, DPMSModeOn);
320 }
321
Dave Barnish2742d152013-03-13 13:36:58 +0000322 // TODO: MIDEGL-1436: Only call this if we are not using sw cursor.. ie. bad to call this
Rob Clark74210d52012-01-08 17:59:08 -0600323 // if we haven't called xf86InitCursor()!!
324 // if (pScrn->pScreen)
325 // xf86_reload_cursors(pScrn->pScreen);
Rob Clark487687e2011-07-17 17:29:02 -0500326
327done:
328 if (output_ids) {
329 free(output_ids);
330 }
331 if (!ret) {
Dave Barnish523c9ff2013-03-12 10:59:03 +0000332 /* If there was a problem, restore the old mode: */
Rob Clark487687e2011-07-17 17:29:02 -0500333 crtc->x = saved_x;
334 crtc->y = saved_y;
335 crtc->rotation = saved_rotation;
336 crtc->mode = saved_mode;
337 }
338
339 TRACE_EXIT();
340 return ret;
Rob Clark74210d52012-01-08 17:59:08 -0600341}
Rob Clark487687e2011-07-17 17:29:02 -0500342
343static void
Rob Clark487687e2011-07-17 17:29:02 -0500344drmmode_hide_cursor(xf86CrtcPtr crtc)
345{
Rob Clark74210d52012-01-08 17:59:08 -0600346 drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
347 drmmode_ptr drmmode = drmmode_crtc->drmmode;
Rob Clark687c6082012-01-08 19:33:18 -0600348 drmmode_cursor_ptr cursor = drmmode->cursor;
Rob Clark487687e2011-07-17 17:29:02 -0500349
Rob Clark687c6082012-01-08 19:33:18 -0600350 if (!cursor)
351 return;
352
Stéphane Marchesinb8b35202012-10-02 20:27:40 -0700353 drmmode_crtc->cursor_visible = FALSE;
Rob Clark687c6082012-01-08 19:33:18 -0600354
355 /* set plane's fb_id to 0 to disable it */
356 drmModeSetPlane(drmmode->fd, cursor->ovr->plane_id,
357 drmmode_crtc->mode_crtc->crtc_id, 0, 0,
358 0, 0, 0, 0, 0, 0, 0, 0);
Rob Clark74210d52012-01-08 17:59:08 -0600359}
Rob Clark487687e2011-07-17 17:29:02 -0500360
361static void
362drmmode_show_cursor(xf86CrtcPtr crtc)
363{
Rob Clark74210d52012-01-08 17:59:08 -0600364 drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
365 drmmode_ptr drmmode = drmmode_crtc->drmmode;
Rob Clark687c6082012-01-08 19:33:18 -0600366 drmmode_cursor_ptr cursor = drmmode->cursor;
Rob Clark60f5bad2012-01-22 18:35:28 -0600367 int crtc_x, crtc_y, src_x, src_y, w, h;
Rob Clark487687e2011-07-17 17:29:02 -0500368
Rob Clark687c6082012-01-08 19:33:18 -0600369 if (!cursor)
370 return;
Rob Clark487687e2011-07-17 17:29:02 -0500371
Stéphane Marchesinb8b35202012-10-02 20:27:40 -0700372 drmmode_crtc->cursor_visible = TRUE;
Rob Clark687c6082012-01-08 19:33:18 -0600373
Rob Clark60f5bad2012-01-22 18:35:28 -0600374 w = CURSORW;
375 h = CURSORH;
376 crtc_x = cursor->x;
377 crtc_y = cursor->y;
378 src_x = 0;
379 src_y = 0;
380
381 if (crtc_x < 0) {
382 src_x += -crtc_x;
383 w -= -crtc_x;
384 crtc_x = 0;
385 }
386
387 if (crtc_y < 0) {
388 src_y += -crtc_y;
389 h -= -crtc_y;
390 crtc_y = 0;
391 }
392
393 if ((crtc_x + w) > crtc->mode.HDisplay) {
394 w = crtc->mode.HDisplay - crtc_x;
395 }
396
397 if ((crtc_y + h) > crtc->mode.VDisplay) {
398 h = crtc->mode.VDisplay - crtc_y;
399 }
400
Rob Clark687c6082012-01-08 19:33:18 -0600401 /* note src coords (last 4 args) are in Q16 format */
402 drmModeSetPlane(drmmode->fd, cursor->ovr->plane_id,
403 drmmode_crtc->mode_crtc->crtc_id, cursor->fb_id, 0,
Rob Clark60f5bad2012-01-22 18:35:28 -0600404 crtc_x, crtc_y, w, h, src_x<<16, src_y<<16, w<<16, h<<16);
Rob Clark687c6082012-01-08 19:33:18 -0600405}
406
407static void
408drmmode_set_cursor_position(xf86CrtcPtr crtc, int x, int y)
409{
410 drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
411 drmmode_ptr drmmode = drmmode_crtc->drmmode;
412 drmmode_cursor_ptr cursor = drmmode->cursor;
413
414 if (!cursor)
415 return;
416
417 cursor->x = x;
418 cursor->y = y;
419
Stéphane Marchesinb8b35202012-10-02 20:27:40 -0700420 if (drmmode_crtc->cursor_visible)
Rob Clark687c6082012-01-08 19:33:18 -0600421 drmmode_show_cursor(crtc);
422}
423
424static void
425drmmode_load_cursor_argb(xf86CrtcPtr crtc, CARD32 *image)
426{
John Rees292ae502013-03-21 16:24:35 +0000427 uint32_t * d;
Rob Clark687c6082012-01-08 19:33:18 -0600428 drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
429 drmmode_ptr drmmode = drmmode_crtc->drmmode;
430 drmmode_cursor_ptr cursor = drmmode->cursor;
Rob Clark979add52012-02-21 18:35:24 -0600431 int visible;
Rob Clark687c6082012-01-08 19:33:18 -0600432
433 if (!cursor)
434 return;
435
Stéphane Marchesinb8b35202012-10-02 20:27:40 -0700436 visible = drmmode_crtc->cursor_visible;
Rob Clark979add52012-02-21 18:35:24 -0600437
438 if (visible)
Rob Clark687c6082012-01-08 19:33:18 -0600439 drmmode_hide_cursor(crtc);
440
John Rees292ae502013-03-21 16:24:35 +0000441 d = omap_bo_map(cursor->bo);
442
443#if ( DRM_CURSOR_PLANE_FORMAT == HW_CURSOR_ARGB )
444 memcpy(d, image, omap_bo_size(cursor->bo));
445#elif ( DRM_CURSOR_PLANE_FORMAT == HW_CURSOR_PL111 )
446 drmmode_argb_cursor_to_pl111_lbbp(crtc, d, image, omap_bo_size(cursor->bo) );
447#else
448 #error Please provide a method to set your cursor image.
449#endif
Rob Clark687c6082012-01-08 19:33:18 -0600450
Rob Clark979add52012-02-21 18:35:24 -0600451 if (visible)
Rob Clark687c6082012-01-08 19:33:18 -0600452 drmmode_show_cursor(crtc);
453}
454
455Bool
456drmmode_cursor_init(ScreenPtr pScreen)
457{
458 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
459 OMAPPtr pOMAP = OMAPPTR(pScrn);
460 drmmode_ptr drmmode = drmmode_from_scrn(pScrn);
461 drmmode_cursor_ptr cursor;
462 drmModePlaneRes *plane_resources;
463 drmModePlane *ovr;
464
465 /* technically we probably don't have any size limit.. since we
466 * are just using an overlay... but xserver will always create
467 * cursor images in the max size, so don't use width/height values
468 * that are too big
469 */
Rob Clark60f5bad2012-01-22 18:35:28 -0600470 int w = CURSORW, h = CURSORH;
Rob Clark687c6082012-01-08 19:33:18 -0600471 uint32_t handles[4], pitches[4], offsets[4]; /* we only use [0] */
472
473 if (drmmode->cursor) {
474 INFO_MSG("cursor already initialized");
475 return TRUE;
476 }
477
Ray Smith003cf5e2013-03-19 10:44:07 +0000478 if(!xf86LoaderCheckSymbol("drmModeGetPlaneResources")) {
479 ERROR_MSG("drmModeGetPlaneResources() not supported (needs libdrm 2.4.30 or higher)");
480 return FALSE;
481 }
Rob Clark687c6082012-01-08 19:33:18 -0600482
483 /* find an unused plane which can be used as a mouse cursor. Note
484 * that we cheat a bit, in order to not burn one overlay per crtc,
485 * and only show the mouse cursor on one crtc at a time
486 */
487 plane_resources = drmModeGetPlaneResources(drmmode->fd);
488 if (!plane_resources) {
489 ERROR_MSG("drmModeGetPlaneResources failed: %s", strerror(errno));
490 return FALSE;
491 }
492
493 if (plane_resources->count_planes < 1) {
494 ERROR_MSG("not enough planes for HW cursor");
Ray Smith003cf5e2013-03-19 10:44:07 +0000495 drmModeFreePlaneResources(plane_resources);
Rob Clark687c6082012-01-08 19:33:18 -0600496 return FALSE;
497 }
498
499 ovr = drmModeGetPlane(drmmode->fd, plane_resources->planes[0]);
500 if (!ovr) {
Daniel Kurtz92205962013-02-05 13:50:12 +0800501 ERROR_MSG("drmModeGetPlane failed: %s", strerror(errno));
Ray Smith003cf5e2013-03-19 10:44:07 +0000502 drmModeFreePlaneResources(plane_resources);
503 return FALSE;
504 }
505
506 cursor = calloc(1, sizeof(drmmode_cursor_rec));
507 if (!cursor) {
508 ERROR_MSG("calloc failed");
509 drmModeFreePlane(ovr);
510 drmModeFreePlaneResources(plane_resources);
Rob Clark687c6082012-01-08 19:33:18 -0600511 return FALSE;
512 }
513
514 cursor->ovr = ovr;
Dave Barnishf4659732013-03-08 10:11:08 +0000515 cursor->bo = omap_bo_new_with_dim(pOMAP->dev, w, h, 0, 32, OMAP_BO_SCANOUT );
Rob Clark687c6082012-01-08 19:33:18 -0600516
Ray Smith003cf5e2013-03-19 10:44:07 +0000517 if (!cursor->bo) {
518 ERROR_MSG("error allocating hw cursor buffer");
519 free(cursor);
520 drmModeFreePlane(ovr);
521 drmModeFreePlaneResources(plane_resources);
522 return FALSE;
523 }
524
Rob Clark687c6082012-01-08 19:33:18 -0600525 handles[0] = omap_bo_handle(cursor->bo);
David Garbettc5901532012-05-29 13:00:52 +0100526 pitches[0] = omap_bo_pitch(cursor->bo);
Rob Clark687c6082012-01-08 19:33:18 -0600527 offsets[0] = 0;
528
529 if (drmModeAddFB2(drmmode->fd, w, h, DRM_FORMAT_ARGB8888,
530 handles, pitches, offsets, &cursor->fb_id, 0)) {
531 ERROR_MSG("drmModeAddFB2 failed: %s", strerror(errno));
Ray Smith003cf5e2013-03-19 10:44:07 +0000532 omap_bo_unreference(cursor->bo);
533 free(cursor);
534 drmModeFreePlane(ovr);
535 drmModeFreePlaneResources(plane_resources);
Rob Clark687c6082012-01-08 19:33:18 -0600536 return FALSE;
537 }
538
Ray Smith003cf5e2013-03-19 10:44:07 +0000539 if (!xf86_cursors_init(pScreen, w, h, HARDWARE_CURSOR_ARGB)) {
540 ERROR_MSG("xf86_cursors_init() failed");
541 if(drmModeRmFB(drmmode->fd, cursor->fb_id)) {
542 ERROR_MSG("drmModeRmFB() failed");
543 }
544 omap_bo_unreference(cursor->bo);
545 free(cursor);
546 drmModeFreePlane(ovr);
547 drmModeFreePlaneResources(plane_resources);
548 return FALSE;
Rob Clark687c6082012-01-08 19:33:18 -0600549 }
550
Ray Smith003cf5e2013-03-19 10:44:07 +0000551 INFO_MSG("HW cursor initialized");
552 drmmode->cursor = cursor;
553 return TRUE;
Rob Clark74210d52012-01-08 17:59:08 -0600554}
Rob Clark487687e2011-07-17 17:29:02 -0500555
Mandeep Singh Bainesc874fcb2012-09-13 15:30:00 +0200556#if 1==OMAP_SUPPORT_GAMMA
Rob Clark487687e2011-07-17 17:29:02 -0500557static void
558drmmode_gamma_set(xf86CrtcPtr crtc, CARD16 *red, CARD16 *green, CARD16 *blue,
Rob Clark74210d52012-01-08 17:59:08 -0600559 int size)
Rob Clark487687e2011-07-17 17:29:02 -0500560{
561 drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
562 drmmode_ptr drmmode = drmmode_crtc->drmmode;
563 int ret;
564
565 ret = drmModeCrtcSetGamma(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id,
Rob Clark74210d52012-01-08 17:59:08 -0600566 size, red, green, blue);
Rob Clark487687e2011-07-17 17:29:02 -0500567 if (ret != 0) {
568 xf86DrvMsg(crtc->scrn->scrnIndex, X_ERROR,
Rob Clark74210d52012-01-08 17:59:08 -0600569 "failed to set gamma: %s\n", strerror(-ret));
Rob Clark487687e2011-07-17 17:29:02 -0500570 }
571}
Mandeep Singh Bainesc874fcb2012-09-13 15:30:00 +0200572#endif
Rob Clark487687e2011-07-17 17:29:02 -0500573
574static const xf86CrtcFuncsRec drmmode_crtc_funcs = {
Rob Clark74210d52012-01-08 17:59:08 -0600575 .dpms = drmmode_crtc_dpms,
576 .set_mode_major = drmmode_set_mode_major,
577 .set_cursor_position = drmmode_set_cursor_position,
578 .show_cursor = drmmode_show_cursor,
579 .hide_cursor = drmmode_hide_cursor,
580 .load_cursor_argb = drmmode_load_cursor_argb,
Mandeep Singh Bainesc874fcb2012-09-13 15:30:00 +0200581#if 1==OMAP_SUPPORT_GAMMA
Rob Clark74210d52012-01-08 17:59:08 -0600582 .gamma_set = drmmode_gamma_set,
Mandeep Singh Bainesc874fcb2012-09-13 15:30:00 +0200583#endif
Rob Clark487687e2011-07-17 17:29:02 -0500584};
585
586
587static void
588drmmode_crtc_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int num)
589{
Rob Clark74210d52012-01-08 17:59:08 -0600590 xf86CrtcPtr crtc;
591 drmmode_crtc_private_ptr drmmode_crtc;
Rob Clark487687e2011-07-17 17:29:02 -0500592
Rob Clark74210d52012-01-08 17:59:08 -0600593 TRACE_ENTER();
Rob Clark487687e2011-07-17 17:29:02 -0500594
Rob Clark74210d52012-01-08 17:59:08 -0600595 crtc = xf86CrtcCreate(pScrn, &drmmode_crtc_funcs);
596 if (crtc == NULL)
597 return;
598
599 drmmode_crtc = xnfcalloc(sizeof(drmmode_crtc_private_rec), 1);
600 drmmode_crtc->mode_crtc = drmModeGetCrtc(drmmode->fd,
601 drmmode->mode_res->crtcs[num]);
602 drmmode_crtc->drmmode = drmmode;
603
Dave Barnish2742d152013-03-13 13:36:58 +0000604 // TODO: MIDEGL-1438: Potentially add code to allocate a HW cursor here.
Rob Clark74210d52012-01-08 17:59:08 -0600605
606 crtc->driver_private = drmmode_crtc;
607
608 TRACE_EXIT();
Rob Clark487687e2011-07-17 17:29:02 -0500609 return;
Rob Clark74210d52012-01-08 17:59:08 -0600610}
Rob Clark487687e2011-07-17 17:29:02 -0500611
612static xf86OutputStatus
613drmmode_output_detect(xf86OutputPtr output)
614{
615 /* go to the hw and retrieve a new output struct */
616 drmmode_output_private_ptr drmmode_output = output->driver_private;
617 drmmode_ptr drmmode = drmmode_output->drmmode;
618 xf86OutputStatus status;
619 drmModeFreeConnector(drmmode_output->mode_output);
620
621 drmmode_output->mode_output =
Rob Clark74210d52012-01-08 17:59:08 -0600622 drmModeGetConnector(drmmode->fd, drmmode_output->output_id);
Rob Clark487687e2011-07-17 17:29:02 -0500623
624 switch (drmmode_output->mode_output->connection) {
625 case DRM_MODE_CONNECTED:
626 status = XF86OutputStatusConnected;
627 break;
628 case DRM_MODE_DISCONNECTED:
629 status = XF86OutputStatusDisconnected;
630 break;
631 default:
632 case DRM_MODE_UNKNOWNCONNECTION:
633 status = XF86OutputStatusUnknown;
634 break;
635 }
636 return status;
637}
638
639static Bool
640drmmode_output_mode_valid(xf86OutputPtr output, DisplayModePtr mode)
641{
642 if (mode->type & M_T_DEFAULT)
643 /* Default modes are harmful here. */
644 return MODE_BAD;
645
646 return MODE_OK;
647}
648
649static DisplayModePtr
650drmmode_output_get_modes(xf86OutputPtr output)
651{
652 ScrnInfoPtr pScrn = output->scrn;
653 drmmode_output_private_ptr drmmode_output = output->driver_private;
654 drmModeConnectorPtr koutput = drmmode_output->mode_output;
655 drmmode_ptr drmmode = drmmode_output->drmmode;
656 DisplayModePtr Modes = NULL, Mode;
Daniel Kurtzb8131892012-10-17 01:39:54 +0800657 drmModePropertyPtr prop;
Rob Clark487687e2011-07-17 17:29:02 -0500658 xf86MonPtr ddc_mon = NULL;
659 int i;
660
661 /* look for an EDID property */
662 for (i = 0; i < koutput->count_props; i++) {
Daniel Kurtzb8131892012-10-17 01:39:54 +0800663 prop = drmModeGetProperty(drmmode->fd, koutput->props[i]);
664 if (!prop)
Rob Clark487687e2011-07-17 17:29:02 -0500665 continue;
666
Daniel Kurtzb8131892012-10-17 01:39:54 +0800667 if ((prop->flags & DRM_MODE_PROP_BLOB) &&
668 !strcmp(prop->name, "EDID")) {
Rob Clark487687e2011-07-17 17:29:02 -0500669 if (drmmode_output->edid_blob)
670 drmModeFreePropertyBlob(drmmode_output->edid_blob);
671 drmmode_output->edid_blob =
Rob Clark74210d52012-01-08 17:59:08 -0600672 drmModeGetPropertyBlob(drmmode->fd,
673 koutput->prop_values[i]);
Rob Clark487687e2011-07-17 17:29:02 -0500674 }
Daniel Kurtzb8131892012-10-17 01:39:54 +0800675 drmModeFreeProperty(prop);
Rob Clark487687e2011-07-17 17:29:02 -0500676 }
677
678 if (drmmode_output->edid_blob)
679 ddc_mon = xf86InterpretEDID(pScrn->scrnIndex,
Rob Clark74210d52012-01-08 17:59:08 -0600680 drmmode_output->edid_blob->data);
Rob Clark487687e2011-07-17 17:29:02 -0500681
682 if (ddc_mon) {
Rob Clark487687e2011-07-17 17:29:02 -0500683 xf86OutputSetEDID(output, ddc_mon);
684 xf86SetDDCproperties(pScrn, ddc_mon);
685 }
686
687 DEBUG_MSG("count_modes: %d", koutput->count_modes);
688
689 /* modes should already be available */
690 for (i = 0; i < koutput->count_modes; i++) {
691 Mode = xnfalloc(sizeof(DisplayModeRec));
692
693 drmmode_ConvertFromKMode(pScrn, &koutput->modes[i],
Rob Clark74210d52012-01-08 17:59:08 -0600694 Mode);
Rob Clark487687e2011-07-17 17:29:02 -0500695 Modes = xf86ModesAdd(Modes, Mode);
696
697 }
698 return Modes;
699}
700
701static void
702drmmode_output_destroy(xf86OutputPtr output)
703{
704 drmmode_output_private_ptr drmmode_output = output->driver_private;
705 int i;
706
707 if (drmmode_output->edid_blob)
708 drmModeFreePropertyBlob(drmmode_output->edid_blob);
709 for (i = 0; i < drmmode_output->num_props; i++) {
710 drmModeFreeProperty(drmmode_output->props[i].mode_prop);
711 free(drmmode_output->props[i].atoms);
712 }
Daniel Kurtzf5a38ad2012-10-17 02:03:34 +0800713 free(drmmode_output->props);
Rob Clark487687e2011-07-17 17:29:02 -0500714 drmModeFreeConnector(drmmode_output->mode_output);
715 free(drmmode_output);
716 output->driver_private = NULL;
717}
718
719static void
720drmmode_output_dpms(xf86OutputPtr output, int mode)
721{
722 drmmode_output_private_ptr drmmode_output = output->driver_private;
723 drmModeConnectorPtr koutput = drmmode_output->mode_output;
Daniel Kurtzb8131892012-10-17 01:39:54 +0800724 drmModePropertyPtr prop;
Rob Clark487687e2011-07-17 17:29:02 -0500725 drmmode_ptr drmmode = drmmode_output->drmmode;
726 int mode_id = -1, i;
727
728 for (i = 0; i < koutput->count_props; i++) {
Daniel Kurtzb8131892012-10-17 01:39:54 +0800729 prop = drmModeGetProperty(drmmode->fd, koutput->props[i]);
730 if (!prop)
731 continue;
732 if ((prop->flags & DRM_MODE_PROP_ENUM) &&
733 !strcmp(prop->name, "DPMS")) {
734 mode_id = koutput->props[i];
735 drmModeFreeProperty(prop);
736 break;
Rob Clark487687e2011-07-17 17:29:02 -0500737 }
Daniel Kurtzb8131892012-10-17 01:39:54 +0800738 drmModeFreeProperty(prop);
Rob Clark487687e2011-07-17 17:29:02 -0500739 }
740
741 if (mode_id < 0)
742 return;
743
744 drmModeConnectorSetProperty(drmmode->fd, koutput->connector_id,
Rob Clark74210d52012-01-08 17:59:08 -0600745 mode_id, mode);
Rob Clark487687e2011-07-17 17:29:02 -0500746}
747
748static Bool
749drmmode_property_ignore(drmModePropertyPtr prop)
750{
751 if (!prop)
Rob Clark74210d52012-01-08 17:59:08 -0600752 return TRUE;
Rob Clark487687e2011-07-17 17:29:02 -0500753 /* ignore blob prop */
754 if (prop->flags & DRM_MODE_PROP_BLOB)
755 return TRUE;
756 /* ignore standard property */
757 if (!strcmp(prop->name, "EDID") ||
Rob Clark74210d52012-01-08 17:59:08 -0600758 !strcmp(prop->name, "DPMS"))
Rob Clark487687e2011-07-17 17:29:02 -0500759 return TRUE;
760
761 return FALSE;
762}
763
764static void
765drmmode_output_create_resources(xf86OutputPtr output)
766{
767 drmmode_output_private_ptr drmmode_output = output->driver_private;
768 drmModeConnectorPtr mode_output = drmmode_output->mode_output;
769 drmmode_ptr drmmode = drmmode_output->drmmode;
770 drmModePropertyPtr drmmode_prop;
771 uint32_t value;
772 int i, j, err;
773
774 drmmode_output->props = calloc(mode_output->count_props, sizeof(drmmode_prop_rec));
775 if (!drmmode_output->props)
776 return;
777
778 drmmode_output->num_props = 0;
779 for (i = 0, j = 0; i < mode_output->count_props; i++) {
780 drmmode_prop = drmModeGetProperty(drmmode->fd, mode_output->props[i]);
781 if (drmmode_property_ignore(drmmode_prop)) {
782 drmModeFreeProperty(drmmode_prop);
783 continue;
784 }
785 drmmode_output->props[j].mode_prop = drmmode_prop;
786 drmmode_output->props[j].index = i;
787 drmmode_output->num_props++;
788 j++;
789 }
790
791 for (i = 0; i < drmmode_output->num_props; i++) {
792 drmmode_prop_ptr p = &drmmode_output->props[i];
793 drmmode_prop = p->mode_prop;
794
795 value = drmmode_output->mode_output->prop_values[p->index];
796
797 if (drmmode_prop->flags & DRM_MODE_PROP_RANGE) {
798 INT32 range[2];
799
800 p->num_atoms = 1;
801 p->atoms = calloc(p->num_atoms, sizeof(Atom));
802 if (!p->atoms)
803 continue;
804 p->atoms[0] = MakeAtom(drmmode_prop->name, strlen(drmmode_prop->name), TRUE);
805 range[0] = drmmode_prop->values[0];
806 range[1] = drmmode_prop->values[1];
807 err = RRConfigureOutputProperty(output->randr_output, p->atoms[0],
Rob Clark74210d52012-01-08 17:59:08 -0600808 FALSE, TRUE,
809 drmmode_prop->flags & DRM_MODE_PROP_IMMUTABLE ? TRUE : FALSE,
Rob Clark487687e2011-07-17 17:29:02 -0500810 2, range);
811 if (err != 0) {
812 xf86DrvMsg(output->scrn->scrnIndex, X_ERROR,
Rob Clark74210d52012-01-08 17:59:08 -0600813 "RRConfigureOutputProperty error, %d\n", err);
Rob Clark487687e2011-07-17 17:29:02 -0500814 }
815 err = RRChangeOutputProperty(output->randr_output, p->atoms[0],
Rob Clark74210d52012-01-08 17:59:08 -0600816 XA_INTEGER, 32, PropModeReplace, 1,
817 &value, FALSE, FALSE);
Rob Clark487687e2011-07-17 17:29:02 -0500818 if (err != 0) {
819 xf86DrvMsg(output->scrn->scrnIndex, X_ERROR,
Rob Clark74210d52012-01-08 17:59:08 -0600820 "RRChangeOutputProperty error, %d\n", err);
Rob Clark487687e2011-07-17 17:29:02 -0500821 }
822 } else if (drmmode_prop->flags & DRM_MODE_PROP_ENUM) {
823 p->num_atoms = drmmode_prop->count_enums + 1;
824 p->atoms = calloc(p->num_atoms, sizeof(Atom));
825 if (!p->atoms)
826 continue;
827 p->atoms[0] = MakeAtom(drmmode_prop->name, strlen(drmmode_prop->name), TRUE);
828 for (j = 1; j <= drmmode_prop->count_enums; j++) {
829 struct drm_mode_property_enum *e = &drmmode_prop->enums[j-1];
830 p->atoms[j] = MakeAtom(e->name, strlen(e->name), TRUE);
831 }
832 err = RRConfigureOutputProperty(output->randr_output, p->atoms[0],
Rob Clark74210d52012-01-08 17:59:08 -0600833 FALSE, FALSE,
834 drmmode_prop->flags & DRM_MODE_PROP_IMMUTABLE ? TRUE : FALSE,
Rob Clark487687e2011-07-17 17:29:02 -0500835 p->num_atoms - 1, (INT32 *)&p->atoms[1]);
836 if (err != 0) {
837 xf86DrvMsg(output->scrn->scrnIndex, X_ERROR,
Rob Clark74210d52012-01-08 17:59:08 -0600838 "RRConfigureOutputProperty error, %d\n", err);
Rob Clark487687e2011-07-17 17:29:02 -0500839 }
840 for (j = 0; j < drmmode_prop->count_enums; j++)
841 if (drmmode_prop->enums[j].value == value)
842 break;
843 /* there's always a matching value */
844 err = RRChangeOutputProperty(output->randr_output, p->atoms[0],
Rob Clark74210d52012-01-08 17:59:08 -0600845 XA_ATOM, 32, PropModeReplace, 1, &p->atoms[j+1], FALSE, FALSE);
Rob Clark487687e2011-07-17 17:29:02 -0500846 if (err != 0) {
847 xf86DrvMsg(output->scrn->scrnIndex, X_ERROR,
Rob Clark74210d52012-01-08 17:59:08 -0600848 "RRChangeOutputProperty error, %d\n", err);
Rob Clark487687e2011-07-17 17:29:02 -0500849 }
850 }
851 }
852}
853
854static Bool
855drmmode_output_set_property(xf86OutputPtr output, Atom property,
Rob Clark74210d52012-01-08 17:59:08 -0600856 RRPropertyValuePtr value)
Rob Clark487687e2011-07-17 17:29:02 -0500857{
858 drmmode_output_private_ptr drmmode_output = output->driver_private;
859 drmmode_ptr drmmode = drmmode_output->drmmode;
860 int i, ret;
861
862 for (i = 0; i < drmmode_output->num_props; i++) {
863 drmmode_prop_ptr p = &drmmode_output->props[i];
864
865 if (p->atoms[0] != property)
866 continue;
867
868 if (p->mode_prop->flags & DRM_MODE_PROP_RANGE) {
869 uint32_t val;
870
871 if (value->type != XA_INTEGER || value->format != 32 ||
Rob Clark74210d52012-01-08 17:59:08 -0600872 value->size != 1)
Rob Clark487687e2011-07-17 17:29:02 -0500873 return FALSE;
874 val = *(uint32_t *)value->data;
875
876 ret = drmModeConnectorSetProperty(drmmode->fd, drmmode_output->output_id,
Rob Clark74210d52012-01-08 17:59:08 -0600877 p->mode_prop->prop_id, (uint64_t)val);
Rob Clark487687e2011-07-17 17:29:02 -0500878
879 if (ret)
880 return FALSE;
881
882 return TRUE;
883
884 } else if (p->mode_prop->flags & DRM_MODE_PROP_ENUM) {
885 Atom atom;
886 const char *name;
887 int j;
888
889 if (value->type != XA_ATOM || value->format != 32 || value->size != 1)
890 return FALSE;
891 memcpy(&atom, value->data, 4);
892 name = NameForAtom(atom);
893
894 /* search for matching name string, then set its value down */
895 for (j = 0; j < p->mode_prop->count_enums; j++) {
896 if (!strcmp(p->mode_prop->enums[j].name, name)) {
897 ret = drmModeConnectorSetProperty(drmmode->fd,
Rob Clark74210d52012-01-08 17:59:08 -0600898 drmmode_output->output_id,
899 p->mode_prop->prop_id,
900 p->mode_prop->enums[j].value);
Rob Clark487687e2011-07-17 17:29:02 -0500901
902 if (ret)
903 return FALSE;
904
905 return TRUE;
906 }
907 }
908
909 return FALSE;
910 }
911 }
912
913 return TRUE;
914}
915
916static Bool
917drmmode_output_get_property(xf86OutputPtr output, Atom property)
918{
919
920 drmmode_output_private_ptr drmmode_output = output->driver_private;
921 drmmode_ptr drmmode = drmmode_output->drmmode;
922 uint32_t value;
923 int err, i;
924
925 if (output->scrn->vtSema) {
926 drmModeFreeConnector(drmmode_output->mode_output);
927 drmmode_output->mode_output =
Rob Clark74210d52012-01-08 17:59:08 -0600928 drmModeGetConnector(drmmode->fd, drmmode_output->output_id);
Rob Clark487687e2011-07-17 17:29:02 -0500929 }
930
931 for (i = 0; i < drmmode_output->num_props; i++) {
932 drmmode_prop_ptr p = &drmmode_output->props[i];
933 if (p->atoms[0] != property)
934 continue;
935
936 value = drmmode_output->mode_output->prop_values[p->index];
937
938 if (p->mode_prop->flags & DRM_MODE_PROP_RANGE) {
939 err = RRChangeOutputProperty(output->randr_output,
Rob Clark74210d52012-01-08 17:59:08 -0600940 property, XA_INTEGER, 32,
941 PropModeReplace, 1, &value,
942 FALSE, FALSE);
Rob Clark487687e2011-07-17 17:29:02 -0500943
944 return !err;
945 } else if (p->mode_prop->flags & DRM_MODE_PROP_ENUM) {
946 int j;
947
948 /* search for matching name string, then set its value down */
949 for (j = 0; j < p->mode_prop->count_enums; j++) {
950 if (p->mode_prop->enums[j].value == value)
951 break;
952 }
953
954 err = RRChangeOutputProperty(output->randr_output, property,
Rob Clark74210d52012-01-08 17:59:08 -0600955 XA_ATOM, 32, PropModeReplace, 1,
956 &p->atoms[j+1], FALSE, FALSE);
Rob Clark487687e2011-07-17 17:29:02 -0500957
958 return !err;
959 }
960 }
961
962 return FALSE;
963}
964
965static const xf86OutputFuncsRec drmmode_output_funcs = {
Rob Clark74210d52012-01-08 17:59:08 -0600966 .create_resources = drmmode_output_create_resources,
967 .dpms = drmmode_output_dpms,
968 .detect = drmmode_output_detect,
969 .mode_valid = drmmode_output_mode_valid,
970 .get_modes = drmmode_output_get_modes,
971 .set_property = drmmode_output_set_property,
972 .get_property = drmmode_output_get_property,
973 .destroy = drmmode_output_destroy
Rob Clark487687e2011-07-17 17:29:02 -0500974};
975
Rob Clark487687e2011-07-17 17:29:02 -0500976const char *output_names[] = { "None",
Rob Clark74210d52012-01-08 17:59:08 -0600977 "VGA",
978 "DVI-I",
979 "DVI-D",
980 "DVI-A",
981 "Composite",
982 "SVIDEO",
983 "LVDS",
984 "CTV",
985 "DIN",
986 "DP",
987 "HDMI",
988 "HDMI",
989 "TV",
990 "eDP",
Rob Clark487687e2011-07-17 17:29:02 -0500991};
992#define NUM_OUTPUT_NAMES (sizeof(output_names) / sizeof(output_names[0]))
993
994static void
995drmmode_output_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int num)
996{
Rob Clark74210d52012-01-08 17:59:08 -0600997 xf86OutputPtr output;
998 drmModeConnectorPtr koutput;
999 drmModeEncoderPtr kencoder;
1000 drmmode_output_private_ptr drmmode_output;
1001 char name[32];
Rob Clark487687e2011-07-17 17:29:02 -05001002
Rob Clark74210d52012-01-08 17:59:08 -06001003 TRACE_ENTER();
Rob Clark487687e2011-07-17 17:29:02 -05001004
Rob Clark74210d52012-01-08 17:59:08 -06001005 koutput = drmModeGetConnector(drmmode->fd,
1006 drmmode->mode_res->connectors[num]);
1007 if (!koutput)
1008 return;
Rob Clark487687e2011-07-17 17:29:02 -05001009
Rob Clark74210d52012-01-08 17:59:08 -06001010 kencoder = drmModeGetEncoder(drmmode->fd, koutput->encoders[0]);
1011 if (!kencoder) {
1012 drmModeFreeConnector(koutput);
1013 return;
1014 }
Rob Clark487687e2011-07-17 17:29:02 -05001015
Rob Clark74210d52012-01-08 17:59:08 -06001016 if (koutput->connector_type >= NUM_OUTPUT_NAMES)
1017 snprintf(name, 32, "Unknown%d-%d", koutput->connector_type,
1018 koutput->connector_type_id);
1019 else
1020 snprintf(name, 32, "%s-%d",
1021 output_names[koutput->connector_type],
1022 koutput->connector_type_id);
Rob Clark487687e2011-07-17 17:29:02 -05001023
Rob Clark74210d52012-01-08 17:59:08 -06001024 output = xf86OutputCreate(pScrn, &drmmode_output_funcs, name);
1025 if (!output) {
1026 drmModeFreeEncoder(kencoder);
1027 drmModeFreeConnector(koutput);
1028 return;
1029 }
Rob Clark487687e2011-07-17 17:29:02 -05001030
Rob Clark74210d52012-01-08 17:59:08 -06001031 drmmode_output = calloc(sizeof(drmmode_output_private_rec), 1);
1032 if (!drmmode_output) {
1033 xf86OutputDestroy(output);
1034 drmModeFreeConnector(koutput);
1035 drmModeFreeEncoder(kencoder);
1036 return;
1037 }
Rob Clark487687e2011-07-17 17:29:02 -05001038
Rob Clark74210d52012-01-08 17:59:08 -06001039 drmmode_output->output_id = drmmode->mode_res->connectors[num];
1040 drmmode_output->mode_output = koutput;
1041 drmmode_output->mode_encoder = kencoder;
1042 drmmode_output->drmmode = drmmode;
Rob Clark487687e2011-07-17 17:29:02 -05001043
Rob Clark74210d52012-01-08 17:59:08 -06001044 output->mm_width = koutput->mmWidth;
1045 output->mm_height = koutput->mmHeight;
1046 output->driver_private = drmmode_output;
Rob Clark487687e2011-07-17 17:29:02 -05001047
Rob Clark74210d52012-01-08 17:59:08 -06001048 output->possible_crtcs = kencoder->possible_crtcs;
1049 output->possible_clones = kencoder->possible_clones;
1050 output->interlaceAllowed = TRUE;
Rob Clark487687e2011-07-17 17:29:02 -05001051
Rob Clark74210d52012-01-08 17:59:08 -06001052 TRACE_EXIT();
1053 return;
1054}
Rob Clark487687e2011-07-17 17:29:02 -05001055
David Garbett3688b332012-05-11 12:17:34 +01001056void set_scanout_bo(ScrnInfoPtr pScrn, struct omap_bo *bo)
1057{
1058 OMAPPtr pOMAP = OMAPPTR(pScrn);
1059
1060 /* It had better have a framebuffer if we're scanning it out */
1061 assert(omap_bo_get_fb(bo));
1062
1063 pOMAP->scanout = bo;
1064}
1065
Rob Clark487687e2011-07-17 17:29:02 -05001066static Bool
1067drmmode_xf86crtc_resize(ScrnInfoPtr pScrn, int width, int height)
1068{
1069 OMAPPtr pOMAP = OMAPPTR(pScrn);
1070 ScreenPtr pScreen = pScrn->pScreen;
David Garbett3688b332012-05-11 12:17:34 +01001071 struct omap_bo *new_scanout;
1072 int res;
Sean Paul3e107302012-08-30 12:08:12 -07001073 uint32_t pitch;
Brian Starkeycd684422012-09-20 09:28:04 +01001074 int i;
1075 xf86CrtcConfigPtr xf86_config;
Rob Clark487687e2011-07-17 17:29:02 -05001076
1077 TRACE_ENTER();
1078
1079 /* if fb required size has changed, realloc! */
1080
1081 DEBUG_MSG("Resize! %dx%d", width, height);
1082
1083 pScrn->virtualX = width;
1084 pScrn->virtualY = height;
1085
David Garbettc5901532012-05-29 13:00:52 +01001086 if ( (width != omap_bo_width(pOMAP->scanout))
1087 || (height != omap_bo_height(pOMAP->scanout))
1088 || (pScrn->bitsPerPixel != omap_bo_bpp(pOMAP->scanout)) ) {
Rob Clark487687e2011-07-17 17:29:02 -05001089
Shirish S29e4a232012-07-13 19:34:24 -07001090 pOMAP->has_resized = TRUE;
David Garbettc5901532012-05-29 13:00:52 +01001091 DEBUG_MSG("allocating new scanout buffer: %dx%d",
1092 width, height);
Rob Clark487687e2011-07-17 17:29:02 -05001093
1094 /* allocate new scanout buffer */
Sean Paul3e107302012-08-30 12:08:12 -07001095 new_scanout = omap_bo_new_with_dim(pOMAP->dev, width, height,
1096 pScrn->depth, pScrn->bitsPerPixel,
Dave Barnishf4659732013-03-08 10:11:08 +00001097 OMAP_BO_SCANOUT );
David Garbett3688b332012-05-11 12:17:34 +01001098
1099 if (!new_scanout) {
Rob Clark487687e2011-07-17 17:29:02 -05001100 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1101 "Error reallocating scanout buffer\n");
1102 return FALSE;
1103 }
David Garbettc5901532012-05-29 13:00:52 +01001104 pitch = omap_bo_pitch(new_scanout);
David Garbett3688b332012-05-11 12:17:34 +01001105
akshu agrawal6a5dead2012-08-09 17:02:21 +05301106 if (omap_bo_clear(new_scanout) || omap_bo_add_fb(new_scanout)) {
David Garbettae5a6362012-07-02 10:15:47 +01001107 omap_bo_unreference(new_scanout);
David Garbett3688b332012-05-11 12:17:34 +01001108 return FALSE;
David Garbettae5a6362012-07-02 10:15:47 +01001109 }
1110
1111 /* Handle dma_buf fd that may be attached to bo */
1112 if(omap_bo_has_dmabuf(pOMAP->scanout))
1113 {
1114 omap_bo_clear_dmabuf(pOMAP->scanout);
1115 res = omap_bo_set_dmabuf(new_scanout);
1116 if(res) {
1117 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1118 "Unable to attach dma_buf fd to new scanout buffer. "
1119 "Error: %d (%s)\n", res, strerror(res));
1120 omap_bo_unreference(new_scanout);
1121 return FALSE;
1122 }
1123 }
1124
1125 /* delete old scanout buffer */
1126 omap_bo_unreference(pOMAP->scanout);
David Garbett3688b332012-05-11 12:17:34 +01001127
1128 set_scanout_bo(pScrn, new_scanout);
1129
Daniel Kurtz34e72b02012-10-19 14:02:05 -07001130 pScrn->displayWidth = pitch / ((pScrn->bitsPerPixel + 7) / 8);
David Garbettc5901532012-05-29 13:00:52 +01001131 }else{
1132 pitch = omap_bo_pitch(pOMAP->scanout);
Rob Clark487687e2011-07-17 17:29:02 -05001133 }
1134
1135 if (pScreen && pScreen->ModifyPixmapHeader) {
1136 PixmapPtr rootPixmap = pScreen->GetScreenPixmap(pScreen);
1137 pScreen->ModifyPixmapHeader(rootPixmap,
1138 pScrn->virtualX, pScrn->virtualY,
1139 pScrn->depth, pScrn->bitsPerPixel, pitch,
1140 omap_bo_map(pOMAP->scanout));
1141 }
1142
Brian Starkeycd684422012-09-20 09:28:04 +01001143 /* Framebuffer needs to be reset on all CRTCs, not just
1144 * those that have repositioned */
1145 xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
1146 for (i = 0; i < xf86_config->num_crtc; i++) {
1147 xf86CrtcPtr crtc = xf86_config->crtc[i];
1148
1149 if (!crtc->enabled)
1150 continue;
1151
1152 drmmode_set_mode_major(crtc, &crtc->mode,
1153 crtc->rotation, crtc->x, crtc->y);
1154 }
1155
1156
Rob Clark487687e2011-07-17 17:29:02 -05001157 TRACE_EXIT();
1158 return TRUE;
Rob Clark74210d52012-01-08 17:59:08 -06001159}
Rob Clark487687e2011-07-17 17:29:02 -05001160
1161static const xf86CrtcConfigFuncsRec drmmode_xf86crtc_config_funcs = {
Rob Clark74210d52012-01-08 17:59:08 -06001162 drmmode_xf86crtc_resize
Rob Clark487687e2011-07-17 17:29:02 -05001163};
1164
1165
1166Bool drmmode_pre_init(ScrnInfoPtr pScrn, int fd, int cpp)
1167{
Rob Clark74210d52012-01-08 17:59:08 -06001168 drmmode_ptr drmmode;
1169 int i;
Rob Clark487687e2011-07-17 17:29:02 -05001170
Rob Clark74210d52012-01-08 17:59:08 -06001171 TRACE_ENTER();
Rob Clark487687e2011-07-17 17:29:02 -05001172
Rob Clark74210d52012-01-08 17:59:08 -06001173 drmmode = calloc(1, sizeof *drmmode);
1174 drmmode->fd = fd;
Rob Clark487687e2011-07-17 17:29:02 -05001175
Rob Clark74210d52012-01-08 17:59:08 -06001176 xf86CrtcConfigInit(pScrn, &drmmode_xf86crtc_config_funcs);
Rob Clark487687e2011-07-17 17:29:02 -05001177
1178
Rob Clark74210d52012-01-08 17:59:08 -06001179 drmmode->cpp = cpp;
1180 drmmode->mode_res = drmModeGetResources(drmmode->fd);
1181 if (!drmmode->mode_res) {
1182 return FALSE;
1183 } else {
1184 DEBUG_MSG("Got KMS resources");
1185 DEBUG_MSG(" %d connectors, %d encoders",
1186 drmmode->mode_res->count_connectors,
1187 drmmode->mode_res->count_encoders);
1188 DEBUG_MSG(" %d crtcs, %d fbs",
1189 drmmode->mode_res->count_crtcs, drmmode->mode_res->count_fbs);
1190 DEBUG_MSG(" %dx%d minimum resolution",
1191 drmmode->mode_res->min_width, drmmode->mode_res->min_height);
1192 DEBUG_MSG(" %dx%d maximum resolution",
1193 drmmode->mode_res->max_width, drmmode->mode_res->max_height);
1194 }
1195 xf86CrtcSetSizeRange(pScrn, 320, 200, drmmode->mode_res->max_width,
1196 drmmode->mode_res->max_height);
1197 for (i = 0; i < drmmode->mode_res->count_crtcs; i++)
1198 drmmode_crtc_init(pScrn, drmmode, i);
Rob Clark487687e2011-07-17 17:29:02 -05001199
Rob Clark74210d52012-01-08 17:59:08 -06001200 for (i = 0; i < drmmode->mode_res->count_connectors; i++)
1201 drmmode_output_init(pScrn, drmmode, i);
Rob Clark487687e2011-07-17 17:29:02 -05001202
Rob Clark74210d52012-01-08 17:59:08 -06001203 xf86InitialConfiguration(pScrn, TRUE);
Rob Clark487687e2011-07-17 17:29:02 -05001204
Rob Clark74210d52012-01-08 17:59:08 -06001205 TRACE_EXIT();
Rob Clark487687e2011-07-17 17:29:02 -05001206
Rob Clark74210d52012-01-08 17:59:08 -06001207 return TRUE;
1208}
Rob Clark487687e2011-07-17 17:29:02 -05001209
1210void
Cooper Yuana83caa62012-06-28 17:19:06 +02001211drmmode_adjust_frame(ScrnInfoPtr pScrn, int x, int y)
Rob Clark487687e2011-07-17 17:29:02 -05001212{
1213 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
1214 xf86OutputPtr output = config->output[config->compat_output];
1215 xf86CrtcPtr crtc = output->crtc;
1216
1217 if (!crtc || !crtc->enabled)
1218 return;
1219
1220 drmmode_set_mode_major(crtc, &crtc->mode, crtc->rotation, x, y);
1221}
1222
Rob Clark4b8f30a2011-08-28 12:51:26 -05001223/*
1224 * Page Flipping
1225 */
1226
1227static void
1228page_flip_handler(int fd, unsigned int sequence, unsigned int tv_sec,
Rob Clark74210d52012-01-08 17:59:08 -06001229 unsigned int tv_usec, void *user_data)
Rob Clark4b8f30a2011-08-28 12:51:26 -05001230{
Rob Clark4b8f30a2011-08-28 12:51:26 -05001231 OMAPDRI2SwapComplete(user_data);
Rob Clark4b8f30a2011-08-28 12:51:26 -05001232}
1233
1234static drmEventContext event_context = {
1235 .version = DRM_EVENT_CONTEXT_VERSION,
1236 .page_flip_handler = page_flip_handler,
1237};
1238
John Sheu022833e2012-08-15 11:40:11 -07001239int
Rob Clark4b8f30a2011-08-28 12:51:26 -05001240drmmode_page_flip(DrawablePtr draw, uint32_t fb_id, void *priv)
1241{
Ray Smith3c33c3d2013-03-26 16:06:37 +00001242 ScrnInfoPtr pScrn = xf86Screens[draw->pScreen->myNum];
1243 OMAPPtr pOMAP = OMAPPTR(pScrn);
1244 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
Rob Clark4b8f30a2011-08-28 12:51:26 -05001245 drmmode_crtc_private_ptr crtc = config->crtc[0]->driver_private;
1246 drmmode_ptr mode = crtc->drmmode;
John Sheu022833e2012-08-15 11:40:11 -07001247 int ret, i, failed = 0, num_flipped = 0;
Raymond Smith16a910e2012-05-09 13:04:51 +01001248 unsigned int flags = 0;
1249
Ray Smith3c33c3d2013-03-26 16:06:37 +00001250 if (pOMAP->drmmode->use_page_flip_events)
1251 flags |= DRM_MODE_PAGE_FLIP_EVENT;
Rob Clark4b8f30a2011-08-28 12:51:26 -05001252
1253 /* if we can flip, we must be fullscreen.. so flip all CRTC's.. */
1254 for (i = 0; i < config->num_crtc; i++) {
1255 crtc = config->crtc[i]->driver_private;
1256
Rob Clark4b8f30a2011-08-28 12:51:26 -05001257 ret = drmModePageFlip(mode->fd, crtc->mode_crtc->crtc_id,
Raymond Smith16a910e2012-05-09 13:04:51 +01001258 fb_id, flags, priv);
Rob Clark4b8f30a2011-08-28 12:51:26 -05001259 if (ret) {
Ray Smith3c33c3d2013-03-26 16:06:37 +00001260 xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
Rob Clark74210d52012-01-08 17:59:08 -06001261 "flip queue failed: %s\n", strerror(errno));
John Sheu022833e2012-08-15 11:40:11 -07001262 failed = 1;
1263 }
1264 else {
1265 num_flipped += 1;
Rob Clark4b8f30a2011-08-28 12:51:26 -05001266 }
1267 }
1268
John Sheu022833e2012-08-15 11:40:11 -07001269 if (failed)
1270 return -(num_flipped + 1);
1271 else
1272 return num_flipped;
Rob Clark4b8f30a2011-08-28 12:51:26 -05001273}
Rob Clark487687e2011-07-17 17:29:02 -05001274
1275/*
1276 * Hot Plug Event handling:
1277 */
1278
Rob Clark487687e2011-07-17 17:29:02 -05001279static void
1280drmmode_handle_uevents(int fd, void *closure)
1281{
Rob Clark74210d52012-01-08 17:59:08 -06001282 ScrnInfoPtr pScrn = closure;
1283 OMAPPtr pOMAP = OMAPPTR(pScrn);
1284 drmmode_ptr drmmode = drmmode_from_scrn(pScrn);
1285 struct udev_device *dev;
1286 const char *hotplug;
1287 struct stat s;
1288 dev_t udev_devnum;
Rob Clark487687e2011-07-17 17:29:02 -05001289
Rob Clark74210d52012-01-08 17:59:08 -06001290 dev = udev_monitor_receive_device(drmmode->uevent_monitor);
1291 if (!dev)
1292 return;
Rob Clark487687e2011-07-17 17:29:02 -05001293
Dave Barnish2742d152013-03-13 13:36:58 +00001294 // TODO: MIDEGL-1441: Do we need to keep this code, which Rob originally wrote
Rob Clark74210d52012-01-08 17:59:08 -06001295 // (i.e. up thru the "if" statement)?:
Rob Clark487687e2011-07-17 17:29:02 -05001296
Rob Clark74210d52012-01-08 17:59:08 -06001297 /*
1298 * Check to make sure this event is directed at our
1299 * device (by comparing dev_t values), then make
1300 * sure it's a hotplug event (HOTPLUG=1)
1301 */
1302 udev_devnum = udev_device_get_devnum(dev);
1303 fstat(pOMAP->drmFD, &s);
Rob Clark487687e2011-07-17 17:29:02 -05001304
Rob Clark74210d52012-01-08 17:59:08 -06001305 hotplug = udev_device_get_property_value(dev, "HOTPLUG");
Rob Clark487687e2011-07-17 17:29:02 -05001306
Rob Clark74210d52012-01-08 17:59:08 -06001307 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "hotplug=%s, match=%d\n", hotplug,
Daniel Kurtz926fd1e2012-11-10 12:20:35 +08001308 !memcmp(&s.st_rdev, &udev_devnum, sizeof (dev_t)));
Rob Clark487687e2011-07-17 17:29:02 -05001309
Rob Clark74210d52012-01-08 17:59:08 -06001310 if (memcmp(&s.st_rdev, &udev_devnum, sizeof (dev_t)) == 0 &&
1311 hotplug && atoi(hotplug) == 1) {
1312 RRGetInfo(screenInfo.screens[pScrn->scrnIndex], TRUE);
1313 }
1314 udev_device_unref(dev);
1315}
Rob Clark487687e2011-07-17 17:29:02 -05001316
Rob Clark4b8f30a2011-08-28 12:51:26 -05001317static void
Rob Clark487687e2011-07-17 17:29:02 -05001318drmmode_uevent_init(ScrnInfoPtr pScrn)
1319{
Rob Clark74210d52012-01-08 17:59:08 -06001320 drmmode_ptr drmmode = drmmode_from_scrn(pScrn);
1321 struct udev *u;
1322 struct udev_monitor *mon;
Rob Clark487687e2011-07-17 17:29:02 -05001323
Rob Clark74210d52012-01-08 17:59:08 -06001324 TRACE_ENTER();
Rob Clark487687e2011-07-17 17:29:02 -05001325
Rob Clark74210d52012-01-08 17:59:08 -06001326 u = udev_new();
1327 if (!u)
1328 return;
1329 mon = udev_monitor_new_from_netlink(u, "udev");
1330 if (!mon) {
1331 udev_unref(u);
1332 return;
1333 }
Rob Clark487687e2011-07-17 17:29:02 -05001334
Rob Clark74210d52012-01-08 17:59:08 -06001335 if (udev_monitor_filter_add_match_subsystem_devtype(mon,
1336 "drm",
1337 "drm_minor") < 0 ||
1338 udev_monitor_enable_receiving(mon) < 0) {
1339 udev_monitor_unref(mon);
1340 udev_unref(u);
1341 return;
1342 }
Rob Clark487687e2011-07-17 17:29:02 -05001343
Rob Clark74210d52012-01-08 17:59:08 -06001344 drmmode->uevent_handler =
1345 xf86AddGeneralHandler(udev_monitor_get_fd(mon),
1346 drmmode_handle_uevents, pScrn);
Rob Clark487687e2011-07-17 17:29:02 -05001347
Rob Clark74210d52012-01-08 17:59:08 -06001348 drmmode->uevent_monitor = mon;
Rob Clark487687e2011-07-17 17:29:02 -05001349
Rob Clark74210d52012-01-08 17:59:08 -06001350 TRACE_EXIT();
1351}
Rob Clark487687e2011-07-17 17:29:02 -05001352
Rob Clark4b8f30a2011-08-28 12:51:26 -05001353static void
Rob Clark487687e2011-07-17 17:29:02 -05001354drmmode_uevent_fini(ScrnInfoPtr pScrn)
1355{
Rob Clark74210d52012-01-08 17:59:08 -06001356 drmmode_ptr drmmode = drmmode_from_scrn(pScrn);
Rob Clark487687e2011-07-17 17:29:02 -05001357
Rob Clark74210d52012-01-08 17:59:08 -06001358 TRACE_ENTER();
Rob Clark487687e2011-07-17 17:29:02 -05001359
Rob Clark74210d52012-01-08 17:59:08 -06001360 if (drmmode->uevent_handler) {
1361 struct udev *u = udev_monitor_get_udev(drmmode->uevent_monitor);
1362 xf86RemoveGeneralHandler(drmmode->uevent_handler);
Rob Clark487687e2011-07-17 17:29:02 -05001363
Rob Clark74210d52012-01-08 17:59:08 -06001364 udev_monitor_unref(drmmode->uevent_monitor);
1365 udev_unref(u);
1366 }
Rob Clark487687e2011-07-17 17:29:02 -05001367
Rob Clark74210d52012-01-08 17:59:08 -06001368 TRACE_EXIT();
1369}
Rob Clark4b8f30a2011-08-28 12:51:26 -05001370
1371static void
1372drmmode_wakeup_handler(pointer data, int err, pointer p)
1373{
Rob Clark67b875f2012-04-20 19:13:57 -05001374 ScrnInfoPtr pScrn = data;
1375 drmmode_ptr drmmode = drmmode_from_scrn(pScrn);
Rob Clark4b8f30a2011-08-28 12:51:26 -05001376 fd_set *read_mask = p;
1377
Rob Clark67b875f2012-04-20 19:13:57 -05001378 if (pScrn == NULL || err < 0)
Rob Clark4b8f30a2011-08-28 12:51:26 -05001379 return;
1380
1381 if (FD_ISSET(drmmode->fd, read_mask))
1382 drmHandleEvent(drmmode->fd, &event_context);
1383}
1384
1385void
Rob Clark67b875f2012-04-20 19:13:57 -05001386drmmode_wait_for_event(ScrnInfoPtr pScrn)
1387{
1388 drmmode_ptr drmmode = drmmode_from_scrn(pScrn);
1389 drmHandleEvent(drmmode->fd, &event_context);
1390}
1391
1392void
Rob Clark4b8f30a2011-08-28 12:51:26 -05001393drmmode_screen_init(ScrnInfoPtr pScrn)
1394{
Rob Clark74210d52012-01-08 17:59:08 -06001395 drmmode_ptr drmmode = drmmode_from_scrn(pScrn);
Rob Clark4b8f30a2011-08-28 12:51:26 -05001396
1397 drmmode_uevent_init(pScrn);
1398
Rob Clark74210d52012-01-08 17:59:08 -06001399 AddGeneralSocket(drmmode->fd);
Rob Clark4b8f30a2011-08-28 12:51:26 -05001400
Rob Clark74210d52012-01-08 17:59:08 -06001401 /* Register a wakeup handler to get informed on DRM events */
1402 RegisterBlockAndWakeupHandlers((BlockHandlerProcPtr)NoopDDA,
1403 drmmode_wakeup_handler, pScrn);
Rob Clark4b8f30a2011-08-28 12:51:26 -05001404}
1405
1406void
1407drmmode_screen_fini(ScrnInfoPtr pScrn)
1408{
1409 drmmode_uevent_fini(pScrn);
1410}