2 * Copyright © 2007 Red Hat, Inc.
3 * Copyright © 2008 Maarten Maathuis
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25 * Dave Airlie <airlied@redhat.com>
35 #include "drmmode_display.h"
37 #include "X11/Xatom.h"
40 nouveau_bo_get_drm_map(struct nouveau_bo *bo)
46 /* not using for the moment */
47 uint32_t drmmode_create_new_fb(ScrnInfoPtr pScrn, int width, int height, int *pitch)
49 NVPtr pNv = NVPTR(pScrn);
52 /* temporary hack, allow old framebuffers to continue to exist and idle. */
54 nouveau_bo_ref(NULL, pNv->FB_old);
58 pNv->FB_old = pNv->FB;
61 *pitch = NOUVEAU_ALIGN(*pitch, 64) * (pScrn->bitsPerPixel >> 3);
63 ret = nouveau_bo_new(pNv->dev, NOUVEAU_BO_VRAM | NOUVEAU_BO_PIN,
64 0, *pitch * NOUVEAU_ALIGN(height, 64), &pNv->FB)
69 ret = nouveau_bo_map(pNv->FB, NOUVEAU_BO_RDWR);
74 return pNv->FB.handle;
79 static Bool drmmode_resize_fb(ScrnInfoPtr scrn, drmmode_ptr drmmode, int width, int height);
83 drmmode_xf86crtc_resize (ScrnInfoPtr scrn, int width, int height)
85 //xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
86 //drmmode_crtc_private_ptr drmmode_crtc = xf86_config->crtc[0]->driver_private;
87 //drmmode_ptr drmmode = drmmode_crtc->drmmode;
90 ErrorF("resize called %d %d\n", width, height);
91 //ret = drmmode_resize_fb(scrn, drmmode, width, height);
92 scrn->virtualX = width;
93 scrn->virtualY = height;
99 drmmode_ConvertFromKMode(ScrnInfoPtr scrn,
100 struct drm_mode_modeinfo *kmode,
103 memset(mode, 0, sizeof(DisplayModeRec));
104 mode->status = MODE_OK;
106 mode->Clock = kmode->clock;
108 mode->HDisplay = kmode->hdisplay;
109 mode->HSyncStart = kmode->hsync_start;
110 mode->HSyncEnd = kmode->hsync_end;
111 mode->HTotal = kmode->htotal;
112 mode->HSkew = kmode->hskew;
114 mode->VDisplay = kmode->vdisplay;
115 mode->VSyncStart = kmode->vsync_start;
116 mode->VSyncEnd = kmode->vsync_end;
117 mode->VTotal = kmode->vtotal;
118 mode->VScan = kmode->vscan;
120 mode->Flags = kmode->flags; //& FLAG_BITS;
121 mode->name = strdup(kmode->name);
123 if (kmode->type & DRM_MODE_TYPE_DRIVER)
124 mode->type = M_T_DRIVER;
125 if (kmode->type & DRM_MODE_TYPE_PREFERRED)
126 mode->type |= M_T_PREFERRED;
127 xf86SetModeCrtc (mode, scrn->adjustFlags);
131 drmmode_ConvertToKMode(ScrnInfoPtr scrn,
132 struct drm_mode_modeinfo *kmode,
135 memset(kmode, 0, sizeof(*kmode));
137 kmode->clock = mode->Clock;
138 kmode->hdisplay = mode->HDisplay;
139 kmode->hsync_start = mode->HSyncStart;
140 kmode->hsync_end = mode->HSyncEnd;
141 kmode->htotal = mode->HTotal;
142 kmode->hskew = mode->HSkew;
144 kmode->vdisplay = mode->VDisplay;
145 kmode->vsync_start = mode->VSyncStart;
146 kmode->vsync_end = mode->VSyncEnd;
147 kmode->vtotal = mode->VTotal;
148 kmode->vscan = mode->VScan;
150 kmode->flags = mode->Flags; //& FLAG_BITS;
152 strncpy(kmode->name, mode->name, DRM_DISPLAY_MODE_LEN);
153 kmode->name[DRM_DISPLAY_MODE_LEN-1] = 0;
157 static const xf86CrtcConfigFuncsRec drmmode_xf86crtc_config_funcs = {
158 drmmode_xf86crtc_resize
162 drmmode_crtc_dpms(xf86CrtcPtr crtc, int mode)
168 drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
169 Rotation rotation, int x, int y)
171 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn);
172 drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
173 drmmode_ptr drmmode = drmmode_crtc->drmmode;
174 int saved_x, saved_y;
175 Rotation saved_rotation;
176 DisplayModeRec saved_mode;
177 uint32_t *output_ids;
178 int output_count = 0;
182 struct drm_mode_modeinfo kmode;
184 ErrorF("drmmode_set_mode_major called\n");
186 saved_mode = crtc->mode;
189 saved_rotation = crtc->rotation;
194 crtc->rotation = rotation;
196 output_ids = xcalloc(sizeof(uint32_t), xf86_config->num_output);
202 for (i = 0; i < xf86_config->num_output; i++) {
203 xf86OutputPtr output = xf86_config->output[i];
204 drmmode_output_private_ptr drmmode_output;
206 if (output->crtc != crtc)
209 drmmode_output = output->driver_private;
210 output_ids[output_count] = drmmode_output->mode_output->connector_id;
214 if (!xf86CrtcRotate(crtc, mode, rotation)) {
218 drmmode_ConvertToKMode(crtc->scrn, &kmode, mode);
220 if (drmmode_crtc->shadow_id && crtc->rotatedData)
221 fb_id = drmmode_crtc->shadow_id;
223 fb_id = drmmode->fb_id;
224 ErrorF("fb id is %d\n", fb_id);
225 drmModeSetCrtc(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id,
226 fb_id, x, y, output_ids, output_count, &kmode);
232 crtc->rotation = saved_rotation;
233 crtc->mode = saved_mode;
242 drmmode_set_cursor_colors (xf86CrtcPtr crtc, int bg, int fg)
248 drmmode_set_cursor_position (xf86CrtcPtr crtc, int x, int y)
250 drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
251 drmmode_ptr drmmode = drmmode_crtc->drmmode;
253 drmModeMoveCursor(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, x, y);
257 drmmode_load_cursor_argb (xf86CrtcPtr crtc, CARD32 *image)
259 drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
261 NVPtr pNv = NVPTR(crtc->scrn);
262 uint32_t *dst = NULL;
264 if (drmmode_crtc->index == 1)
265 dst = (uint32_t *) pNv->Cursor2->map;
267 dst = (uint32_t *) pNv->Cursor->map;
269 /* Assume cursor is 64x64 */
270 memcpy(dst, (uint32_t *)image, 64 * 64 * 4);
275 drmmode_hide_cursor (xf86CrtcPtr crtc)
277 drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
278 drmmode_ptr drmmode = drmmode_crtc->drmmode;
280 drmModeSetCursor(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, 0, 64, 64);
285 drmmode_show_cursor (xf86CrtcPtr crtc)
287 drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
288 drmmode_ptr drmmode = drmmode_crtc->drmmode;
289 NVPtr pNv = NVPTR(crtc->scrn);
291 drm_handle_t handle = 0;
293 if (drmmode_crtc->index == 1)
294 handle = nouveau_bo_get_drm_map(pNv->Cursor2);
296 handle = nouveau_bo_get_drm_map(pNv->Cursor);
298 drmModeSetCursor(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, handle, 64, 64);
301 /* This stuff isn't ready for NOUVEAU_EXA_PIXMAPS, but can be easily ported. */
303 drmmode_shadow_allocate (xf86CrtcPtr crtc, int width, int height)
305 drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
306 drmmode_ptr drmmode = drmmode_crtc->drmmode;
307 ScrnInfoPtr pScrn = crtc->scrn;
308 NVPtr pNv = NVPTR(pScrn);
309 int size, pitch, ret;
311 ErrorF("drmmode_shadow_allocate\n");
313 pitch = width * (pScrn->bitsPerPixel/8);
314 size = pitch * height;
316 if (nouveau_bo_new(pNv->dev, NOUVEAU_BO_VRAM | NOUVEAU_BO_PIN,
317 64, size, &drmmode_crtc->shadow)) {
318 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to allocate memory for shadow buffer!\n");
322 if (drmmode_crtc->shadow && nouveau_bo_map(drmmode_crtc->shadow, NOUVEAU_BO_RDWR)) {
323 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
324 "Failed to map shadow buffer.\n");
328 ret = drmModeAddFB(drmmode->fd, width, height, pScrn->depth, pScrn->bitsPerPixel, pitch, nouveau_bo_get_drm_map(drmmode_crtc->shadow), &drmmode_crtc->shadow_id);
332 /* for easy acces by exa */
333 pNv->shadow[drmmode_crtc->index] = drmmode_crtc->shadow;
335 return drmmode_crtc->shadow->map;
339 drmmode_shadow_create(xf86CrtcPtr crtc, void *data, int width, int height)
341 ScrnInfoPtr pScrn = crtc->scrn;
343 PixmapPtr rotate_pixmap;
345 ErrorF("drmmode_shadow_create\n");
348 data = crtc->funcs->shadow_allocate (crtc, width, height);
350 pitch = width * (pScrn->bitsPerPixel/8);
352 rotate_pixmap = GetScratchPixmapHeader(pScrn->pScreen,
359 if (rotate_pixmap == NULL) {
360 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
361 "Couldn't allocate shadow pixmap for rotated CRTC\n");
364 return rotate_pixmap;
368 drmmode_shadow_destroy(xf86CrtcPtr crtc, PixmapPtr rotate_pixmap, void *data)
370 drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
371 drmmode_ptr drmmode = drmmode_crtc->drmmode;
372 ScrnInfoPtr pScrn = crtc->scrn;
373 NVPtr pNv = NVPTR(pScrn);
374 ScreenPtr pScreen = pScrn->pScreen;
376 ErrorF("drmmode_shadow_destroy\n");
379 pScreen->DestroyPixmap(rotate_pixmap);
381 if (drmmode_crtc->shadow_id) {
382 drmModeRmFB(drmmode->fd, drmmode_crtc->shadow_id);
383 drmmode_crtc->shadow_id = 0;
386 if (drmmode_crtc->shadow)
387 nouveau_bo_ref(NULL, &drmmode_crtc->shadow);
389 drmmode_crtc->shadow = NULL;
391 /* for easy acces by exa */
392 pNv->shadow[drmmode_crtc->index] = NULL;
396 drmmode_gamma_set(xf86CrtcPtr crtc, CARD16 *red, CARD16 *green, CARD16 *blue, int size)
398 ScrnInfoPtr pScrn = crtc->scrn;
399 drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
400 drmmode_ptr drmmode = drmmode_crtc->drmmode;
403 ErrorF("drmmode_gamma_set\n");
405 ret = drmModeCrtcSetGamma(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, size, (uint16_t *)red, (uint16_t *)green, (uint16_t *)blue);
407 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "drmModeCrtcSetGamma failed\n");
410 static const xf86CrtcFuncsRec drmmode_crtc_funcs = {
411 .dpms = drmmode_crtc_dpms,
412 .set_mode_major = drmmode_set_mode_major,
413 .set_cursor_colors = drmmode_set_cursor_colors,
414 .set_cursor_position = drmmode_set_cursor_position,
415 .show_cursor = drmmode_show_cursor,
416 .hide_cursor = drmmode_hide_cursor,
417 .load_cursor_argb = drmmode_load_cursor_argb,
418 .shadow_create = drmmode_shadow_create,
419 .shadow_allocate = drmmode_shadow_allocate,
420 .shadow_destroy = drmmode_shadow_destroy,
421 .gamma_set = drmmode_gamma_set,
422 .destroy = NULL, /* XXX */
427 drmmode_crtc_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int num)
430 drmmode_crtc_private_ptr drmmode_crtc;
432 crtc = xf86CrtcCreate(pScrn, &drmmode_crtc_funcs);
436 drmmode_crtc = xnfcalloc(sizeof(drmmode_crtc_private_rec), 1);
437 drmmode_crtc->mode_crtc = drmModeGetCrtc(drmmode->fd, drmmode->mode_res->crtcs[num]);
438 drmmode_crtc->drmmode = drmmode;
439 drmmode_crtc->index = num;
440 crtc->driver_private = drmmode_crtc;
445 static xf86OutputStatus
446 drmmode_output_detect(xf86OutputPtr output)
448 /* go to the hw and retrieve a new output struct */
449 drmmode_output_private_ptr drmmode_output = output->driver_private;
450 drmmode_ptr drmmode = drmmode_output->drmmode;
451 xf86OutputStatus status;
452 drmModeFreeConnector(drmmode_output->mode_output);
454 ErrorF("drmmode_output_detect called\n");
456 drmmode_output->mode_output = drmModeGetConnector(drmmode->fd, drmmode_output->output_id);
458 switch (drmmode_output->mode_output->connection) {
459 case DRM_MODE_CONNECTED:
460 status = XF86OutputStatusConnected;
462 case DRM_MODE_DISCONNECTED:
463 status = XF86OutputStatusDisconnected;
466 case DRM_MODE_UNKNOWNCONNECTION:
467 status = XF86OutputStatusUnknown;
474 drmmode_output_mode_valid(xf86OutputPtr output, DisplayModePtr pModes)
479 static DisplayModePtr
480 drmmode_output_get_modes(xf86OutputPtr output)
482 drmmode_output_private_ptr drmmode_output = output->driver_private;
483 drmModeConnectorPtr koutput = drmmode_output->mode_output;
484 drmmode_ptr drmmode = drmmode_output->drmmode;
486 DisplayModePtr Modes = NULL, Mode;
487 drmModePropertyPtr props;
489 ErrorF("drmmode_output_get_modes called\n");
491 /* look for an EDID property */
492 for (i = 0; i < koutput->count_props; i++) {
493 props = drmModeGetProperty(drmmode->fd, koutput->props[i]);
494 if (props && (props->flags & DRM_MODE_PROP_BLOB)) {
495 if (!strcmp(props->name, "EDID")) {
496 ErrorF("EDID property found\n");
497 if (drmmode_output->edid_blob)
498 drmModeFreePropertyBlob(drmmode_output->edid_blob);
499 drmmode_output->edid_blob = drmModeGetPropertyBlob(drmmode->fd, koutput->prop_values[i]);
501 if (!drmmode_output->edid_blob)
502 ErrorF("No EDID blob\n");
504 drmModeFreeProperty(props);
508 if (drmmode_output->edid_blob)
509 xf86OutputSetEDID(output, xf86InterpretEDID(output->scrn->scrnIndex, drmmode_output->edid_blob->data));
511 xf86OutputSetEDID(output, xf86InterpretEDID(output->scrn->scrnIndex, NULL));
513 /* modes should already be available */
514 for (i = 0; i < koutput->count_modes; i++) {
515 Mode = xnfalloc(sizeof(DisplayModeRec));
517 drmmode_ConvertFromKMode(output->scrn, &koutput->modes[i], Mode);
518 Modes = xf86ModesAdd(Modes, Mode);
525 drmmode_output_destroy(xf86OutputPtr output)
527 drmmode_output_private_ptr drmmode_output = output->driver_private;
529 if (drmmode_output->edid_blob)
530 drmModeFreePropertyBlob(drmmode_output->edid_blob);
531 drmModeFreeConnector(drmmode_output->mode_output);
532 xfree(drmmode_output);
533 output->driver_private = NULL;
537 drmmode_output_dpms(xf86OutputPtr output, int mode)
539 drmmode_output_private_ptr drmmode_output = output->driver_private;
540 drmModeConnectorPtr koutput = drmmode_output->mode_output;
541 drmmode_ptr drmmode = drmmode_output->drmmode;
542 drmModePropertyPtr props;
545 ErrorF("drmmode_output_dpms called with mode %d\n", mode);
547 for (i = 0; i < koutput->count_props; i++) {
548 props = drmModeGetProperty(drmmode->fd, koutput->props[i]);
549 if (props && (props->flags & DRM_MODE_PROP_ENUM)) {
550 if (!strcmp(props->name, "DPMS")) {
551 ErrorF("DPMS property found\n");
552 drmModeConnectorSetProperty(drmmode->fd, drmmode_output->output_id, props->prop_id, mode);
554 drmModeFreeProperty(props);
564 * Several scaling modes exist, let the user choose.
566 #define SCALING_MODE_NAME "SCALING_MODE"
567 static const struct {
571 { "non-gpu", DRM_MODE_SCALE_NON_GPU },
572 { "fullscreen", DRM_MODE_SCALE_FULLSCREEN },
573 { "aspect", DRM_MODE_SCALE_ASPECT },
574 { "noscale", DRM_MODE_SCALE_NO_SCALE },
575 { NULL, 0xFFFF /* invalid */ }
577 static Atom scaling_mode_atom;
579 #define DITHERING_MODE_NAME "DITHERING"
580 static const struct {
583 } dithering_mode[] = {
584 { "off", DRM_MODE_DITHERING_OFF },
585 { "on", DRM_MODE_DITHERING_ON },
586 { NULL, 0xFFFF /* invalid */ }
588 static Atom dithering_atom;
591 drmmode_scaling_mode_lookup(char *name, int size)
595 /* for when name is zero terminated */
599 for (i = 0; scaling_mode[i].name; i++)
600 /* We're getting non-terminated strings */
601 if (strlen(scaling_mode[i].name) >= size &&
602 !strncasecmp(name, scaling_mode[i].name, size))
605 return scaling_mode[i].mode;
609 drmmode_dithering_lookup(char *name, int size)
613 /* for when name is zero terminated */
617 for (i = 0; dithering_mode[i].name; i++)
618 /* We're getting non-terminated strings */
619 if (strlen(dithering_mode[i].name) >= size &&
620 !strncasecmp(name, dithering_mode[i].name, size))
623 return dithering_mode[i].mode;
628 drmmode_output_create_resources(xf86OutputPtr output)
630 ScrnInfoPtr pScrn = output->scrn;
634 * Setup scaling mode property.
636 scaling_mode_atom = MakeAtom(SCALING_MODE_NAME, sizeof(SCALING_MODE_NAME) - 1, TRUE);
638 error = RRConfigureOutputProperty(output->randr_output,
639 scaling_mode_atom, FALSE, FALSE, FALSE,
643 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
644 "RRConfigureOutputProperty error, %d\n", error);
647 /* property has unknown initial value (for the moment) */
650 * Setup dithering property.
652 dithering_atom = MakeAtom(DITHERING_MODE_NAME, sizeof(DITHERING_MODE_NAME) - 1, TRUE);
654 error = RRConfigureOutputProperty(output->randr_output,
655 dithering_atom, FALSE, FALSE, FALSE,
659 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
660 "RRConfigureOutputProperty error, %d\n", error);
663 /* property has unknown initial value (for the moment) */
667 drmmode_output_set_property(xf86OutputPtr output, Atom property,
668 RRPropertyValuePtr value)
670 drmmode_output_private_ptr drmmode_output = output->driver_private;
671 drmModeConnectorPtr koutput = drmmode_output->mode_output;
672 drmmode_ptr drmmode = drmmode_output->drmmode;
673 drmModePropertyPtr props;
674 int i, mode, rval = 0;
676 if (property == scaling_mode_atom) {
679 if (value->type != XA_STRING || value->format != 8)
682 name = (char *) value->data;
684 /* Match a string to a scaling mode */
685 mode = drmmode_scaling_mode_lookup(name, value->size);
689 for (i = 0; i < koutput->count_props; i++) {
690 props = drmModeGetProperty(drmmode->fd, koutput->props[i]);
691 if (props && (props->flags & DRM_MODE_PROP_ENUM)) {
692 if (!strcmp(props->name, "scaling mode")) {
693 ErrorF("scaling mode property found\n");
694 rval = drmModeConnectorSetProperty(drmmode->fd, drmmode_output->output_id, props->prop_id, mode);
696 drmModeFreeProperty(props);
704 } else if (property == dithering_atom) {
707 if (value->type != XA_STRING || value->format != 8)
710 name = (char *) value->data;
712 /* Match a string to a scaling mode */
713 mode = drmmode_dithering_lookup(name, value->size);
717 for (i = 0; i < koutput->count_props; i++) {
718 props = drmModeGetProperty(drmmode->fd, koutput->props[i]);
719 if (props && (props->flags & DRM_MODE_PROP_ENUM)) {
720 if (!strcmp(props->name, "dithering")) {
721 ErrorF("dithering property found\n");
722 rval = drmModeConnectorSetProperty(drmmode->fd, drmmode_output->output_id, props->prop_id, mode);
724 drmModeFreeProperty(props);
737 static const xf86OutputFuncsRec drmmode_output_funcs = {
738 .dpms = drmmode_output_dpms,
739 .detect = drmmode_output_detect,
740 .mode_valid = drmmode_output_mode_valid,
741 .get_modes = drmmode_output_get_modes,
742 .destroy = drmmode_output_destroy,
743 .create_resources = drmmode_output_create_resources,
744 .set_property = drmmode_output_set_property,
747 static int subpixel_conv_table[7] = { 0, SubPixelUnknown,
748 SubPixelHorizontalRGB,
749 SubPixelHorizontalBGR,
759 struct output_name output_names[] = {
767 drmmode_output_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int num)
769 xf86OutputPtr output;
770 drmModeConnectorPtr koutput;
771 drmModeEncoderPtr kencoder;
772 drmmode_output_private_ptr drmmode_output;
775 ErrorF("drmmode_output_init\n");
777 koutput = drmModeGetConnector(drmmode->fd, drmmode->mode_res->connectors[num]);
779 ErrorF("No connector\n");
783 kencoder = drmModeGetEncoder(drmmode->fd, koutput->encoders[0]);
785 ErrorF("No encoder\n");
786 drmModeFreeConnector(koutput);
790 snprintf(name, 32, "%s-%d", output_names[koutput->connector_type].name, output_names[koutput->connector_type].count++);
792 output = xf86OutputCreate (pScrn, &drmmode_output_funcs, name);
794 drmModeFreeEncoder(kencoder);
795 drmModeFreeConnector(koutput);
799 drmmode_output = xcalloc(sizeof(drmmode_output_private_rec), 1);
800 if (!drmmode_output) {
801 xf86OutputDestroy(output);
802 drmModeFreeConnector(koutput);
803 drmModeFreeEncoder(kencoder);
807 drmmode_output->output_id = drmmode->mode_res->connectors[num];
808 drmmode_output->mode_output = koutput;
809 drmmode_output->mode_encoder = kencoder;
810 drmmode_output->drmmode = drmmode;
811 output->mm_width = koutput->mmWidth;
812 output->mm_height = koutput->mmHeight;
814 output->subpixel_order = subpixel_conv_table[koutput->subpixel];
815 output->driver_private = drmmode_output;
817 output->possible_crtcs = kencoder->possible_crtcs;
818 output->possible_clones = kencoder->possible_clones;
823 void drmmode_set_fb(ScrnInfoPtr scrn, drmmode_ptr drmmode, int width, int height, int pitch, struct nouveau_bo *bo)
827 ErrorF("drmmode_set_fb is called\n");
829 ret = drmModeAddFB(drmmode->fd, width, height, scrn->depth,
830 scrn->bitsPerPixel, pitch, nouveau_bo_get_drm_map(bo), &drmmode->fb_id);
833 ErrorF("Failed to add fb\n");
836 drmmode->mode_fb = drmModeGetFB(drmmode->fd, drmmode->fb_id);
837 if (!drmmode->mode_fb)
840 ErrorF("Add fb id %d %d %d\n", drmmode->fb_id, width, height);
844 static Bool drmmode_resize_fb(ScrnInfoPtr scrn, drmmode_ptr drmmode, int width, int height)
850 ErrorF("current width %d height %d\n", drmmode->mode_fb->width, drmmode->mode_fb->height);
852 if (drmmode->mode_fb->width == width && drmmode->mode_fb->height == height)
855 if (!drmmode->create_new_fb)
858 handle = drmmode->create_new_fb(scrn, width, height, &pitch);
862 ErrorF("pitch is %d\n", pitch);
863 ret = drmModeReplaceFB(drmmode->fd, drmmode->fb_id,
865 scrn->depth, scrn->depth, pitch,
871 drmModeFreeFB(drmmode->mode_fb);
872 drmmode->mode_fb = drmModeGetFB(drmmode->fd, drmmode->fb_id);
874 if (!drmmode->mode_fb)
881 Bool drmmode_pre_init(ScrnInfoPtr pScrn, char *busId, drmmode_ptr drmmode, int cpp)
883 xf86CrtcConfigPtr xf86_config = NULL;
887 drm_page_size = getpagesize();
889 /* Create a bus Id */
890 /* Low level DRM open */
891 ret = DRIOpenDRMMaster(pScrn, (drm_page_size > SAREA_MAX) ? drm_page_size : SAREA_MAX, busId, "nouveau");
893 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
894 "[dri] DRIGetVersion failed to open the DRM\n");
898 drmmode->fd = DRIMasterFD(pScrn);
900 xf86CrtcConfigInit(pScrn, &drmmode_xf86crtc_config_funcs);
901 xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
904 drmmode->mode_res = drmModeGetResources(drmmode->fd);
905 if (!drmmode->mode_res)
908 xf86CrtcSetSizeRange(pScrn, 320, 200, drmmode->mode_res->max_width, drmmode->mode_res->max_height);
909 for (i = 0; i < drmmode->mode_res->count_crtcs; i++)
910 drmmode_crtc_init(pScrn, drmmode, i);
912 for (i = 0; i < drmmode->mode_res->count_connectors; i++)
913 drmmode_output_init(pScrn, drmmode, i);
915 if (!xf86InitialConfiguration(pScrn, FALSE))
921 #endif /* XF86DRM_MODE */