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"
39 /* not using for the moment */
40 uint32_t drmmode_create_new_fb(ScrnInfoPtr pScrn, int width, int height, int *pitch)
42 #if NOUVEAU_EXA_PIXMAPS
43 NVPtr pNv = NVPTR(pScrn);
46 /* temporary hack, allow old framebuffers to continue to exist and idle. */
48 nouveau_bo_del(pNv->FB_old);
52 pNv->FB_old = pNv->FB;
55 *pitch = NOUVEAU_ALIGN(*pitch, 64) * (pScrn->bitsPerPixel >> 3);
57 ret = nouveau_bo_new(pNv->dev, NOUVEAU_BO_VRAM | NOUVEAU_BO_PIN,
58 0, *pitch * NOUVEAU_ALIGN(height, 64), &pNv->FB)
63 ret = nouveau_bo_map(pNv->FB, NOUVEAU_BO_RDWR);
68 return pNv->FB.handle;
70 return 0; /* we have a fixed FB */
71 #endif /* NOUVEAU_EXA_PIXMAPS */
75 static Bool drmmode_resize_fb(ScrnInfoPtr scrn, drmmode_ptr drmmode, int width, int height);
79 drmmode_xf86crtc_resize (ScrnInfoPtr scrn, int width, int height)
81 //xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
82 //drmmode_crtc_private_ptr drmmode_crtc = xf86_config->crtc[0]->driver_private;
83 //drmmode_ptr drmmode = drmmode_crtc->drmmode;
86 ErrorF("resize called %d %d\n", width, height);
87 //ret = drmmode_resize_fb(scrn, drmmode, width, height);
88 scrn->virtualX = width;
89 scrn->virtualY = height;
95 drmmode_ConvertFromKMode(ScrnInfoPtr scrn,
96 struct drm_mode_modeinfo *kmode,
99 memset(mode, 0, sizeof(DisplayModeRec));
100 mode->status = MODE_OK;
102 mode->Clock = kmode->clock;
104 mode->HDisplay = kmode->hdisplay;
105 mode->HSyncStart = kmode->hsync_start;
106 mode->HSyncEnd = kmode->hsync_end;
107 mode->HTotal = kmode->htotal;
108 mode->HSkew = kmode->hskew;
110 mode->VDisplay = kmode->vdisplay;
111 mode->VSyncStart = kmode->vsync_start;
112 mode->VSyncEnd = kmode->vsync_end;
113 mode->VTotal = kmode->vtotal;
114 mode->VScan = kmode->vscan;
116 mode->Flags = kmode->flags; //& FLAG_BITS;
117 mode->name = strdup(kmode->name);
119 if (kmode->type & DRM_MODE_TYPE_DRIVER)
120 mode->type = M_T_DRIVER;
121 if (kmode->type & DRM_MODE_TYPE_PREFERRED)
122 mode->type |= M_T_PREFERRED;
123 xf86SetModeCrtc (mode, scrn->adjustFlags);
127 drmmode_ConvertToKMode(ScrnInfoPtr scrn,
128 struct drm_mode_modeinfo *kmode,
131 memset(kmode, 0, sizeof(*kmode));
133 kmode->clock = mode->Clock;
134 kmode->hdisplay = mode->HDisplay;
135 kmode->hsync_start = mode->HSyncStart;
136 kmode->hsync_end = mode->HSyncEnd;
137 kmode->htotal = mode->HTotal;
138 kmode->hskew = mode->HSkew;
140 kmode->vdisplay = mode->VDisplay;
141 kmode->vsync_start = mode->VSyncStart;
142 kmode->vsync_end = mode->VSyncEnd;
143 kmode->vtotal = mode->VTotal;
144 kmode->vscan = mode->VScan;
146 kmode->flags = mode->Flags; //& FLAG_BITS;
148 strncpy(kmode->name, mode->name, DRM_DISPLAY_MODE_LEN);
149 kmode->name[DRM_DISPLAY_MODE_LEN-1] = 0;
153 static const xf86CrtcConfigFuncsRec drmmode_xf86crtc_config_funcs = {
154 drmmode_xf86crtc_resize
158 drmmode_crtc_dpms(xf86CrtcPtr crtc, int mode)
164 drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
165 Rotation rotation, int x, int y)
167 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn);
168 drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
169 drmmode_ptr drmmode = drmmode_crtc->drmmode;
170 int saved_x, saved_y;
171 Rotation saved_rotation;
172 DisplayModeRec saved_mode;
173 uint32_t *output_ids;
174 int output_count = 0;
178 struct drm_mode_modeinfo kmode;
180 ErrorF("drmmode_set_mode_major called\n");
182 saved_mode = crtc->mode;
185 saved_rotation = crtc->rotation;
190 crtc->rotation = rotation;
192 output_ids = xcalloc(sizeof(uint32_t), xf86_config->num_output);
198 for (i = 0; i < xf86_config->num_output; i++) {
199 xf86OutputPtr output = xf86_config->output[i];
200 drmmode_output_private_ptr drmmode_output;
202 if (output->crtc != crtc)
205 drmmode_output = output->driver_private;
206 output_ids[output_count] = drmmode_output->mode_output->connector_id;
210 if (!xf86CrtcRotate(crtc, mode, rotation)) {
214 drmmode_ConvertToKMode(crtc->scrn, &kmode, mode);
216 if (drmmode_crtc->shadow_id && crtc->rotatedData)
217 fb_id = drmmode_crtc->shadow_id;
219 fb_id = drmmode->fb_id;
220 ErrorF("fb id is %d\n", fb_id);
221 drmModeSetCrtc(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id,
222 fb_id, x, y, output_ids, output_count, &kmode);
228 crtc->rotation = saved_rotation;
229 crtc->mode = saved_mode;
238 drmmode_set_cursor_colors (xf86CrtcPtr crtc, int bg, int fg)
244 drmmode_set_cursor_position (xf86CrtcPtr crtc, int x, int y)
246 drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
247 drmmode_ptr drmmode = drmmode_crtc->drmmode;
249 drmModeMoveCursor(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, x, y);
253 drmmode_load_cursor_argb (xf86CrtcPtr crtc, CARD32 *image)
255 drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
257 NVPtr pNv = NVPTR(crtc->scrn);
258 uint32_t *dst = NULL;
260 if (drmmode_crtc->index == 1)
261 dst = (uint32_t *) pNv->Cursor2->map;
263 dst = (uint32_t *) pNv->Cursor->map;
265 /* Assume cursor is 64x64 */
266 memcpy(dst, (uint32_t *)image, 64 * 64 * 4);
271 drmmode_hide_cursor (xf86CrtcPtr crtc)
273 drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
274 drmmode_ptr drmmode = drmmode_crtc->drmmode;
276 drmModeSetCursor(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, 0, 64, 64);
281 drmmode_show_cursor (xf86CrtcPtr crtc)
283 drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
284 drmmode_ptr drmmode = drmmode_crtc->drmmode;
285 NVPtr pNv = NVPTR(crtc->scrn);
287 drm_handle_t handle = 0;
289 if (drmmode_crtc->index == 1)
290 handle = pNv->Cursor2->map_handle;
292 handle = pNv->Cursor->map_handle;
294 drmModeSetCursor(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, handle, 64, 64);
297 /* This stuff isn't ready for NOUVEAU_EXA_PIXMAPS, but can be easily ported. */
299 drmmode_shadow_allocate (xf86CrtcPtr crtc, int width, int height)
301 drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
302 drmmode_ptr drmmode = drmmode_crtc->drmmode;
303 ScrnInfoPtr pScrn = crtc->scrn;
304 NVPtr pNv = NVPTR(pScrn);
305 int size, pitch, ret;
307 ErrorF("drmmode_shadow_allocate\n");
309 pitch = width * (pScrn->bitsPerPixel/8);
310 size = pitch * height;
312 if (nouveau_bo_new(pNv->dev, NOUVEAU_BO_VRAM | NOUVEAU_BO_PIN,
313 64, size, &drmmode_crtc->shadow)) {
314 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to allocate memory for shadow buffer!\n");
318 if (drmmode_crtc->shadow && nouveau_bo_map(drmmode_crtc->shadow, NOUVEAU_BO_RDWR)) {
319 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
320 "Failed to map shadow buffer.\n");
324 ret = drmModeAddFB(drmmode->fd, width, height, pScrn->depth, pScrn->bitsPerPixel, pitch, drmmode_crtc->shadow->map_handle, &drmmode_crtc->shadow_id);
328 /* for easy acces by exa */
329 pNv->shadow[drmmode_crtc->index] = drmmode_crtc->shadow;
331 return drmmode_crtc->shadow->map;
335 drmmode_shadow_create(xf86CrtcPtr crtc, void *data, int width, int height)
337 ScrnInfoPtr pScrn = crtc->scrn;
339 PixmapPtr rotate_pixmap;
341 ErrorF("drmmode_shadow_create\n");
344 data = crtc->funcs->shadow_allocate (crtc, width, height);
346 pitch = width * (pScrn->bitsPerPixel/8);
348 rotate_pixmap = GetScratchPixmapHeader(pScrn->pScreen,
355 if (rotate_pixmap == NULL) {
356 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
357 "Couldn't allocate shadow pixmap for rotated CRTC\n");
360 return rotate_pixmap;
364 drmmode_shadow_destroy(xf86CrtcPtr crtc, PixmapPtr rotate_pixmap, void *data)
366 drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
367 drmmode_ptr drmmode = drmmode_crtc->drmmode;
368 ScrnInfoPtr pScrn = crtc->scrn;
369 NVPtr pNv = NVPTR(pScrn);
370 ScreenPtr pScreen = pScrn->pScreen;
372 ErrorF("drmmode_shadow_destroy\n");
375 pScreen->DestroyPixmap(rotate_pixmap);
377 if (drmmode_crtc->shadow_id) {
378 drmModeRmFB(drmmode->fd, drmmode_crtc->shadow_id);
379 drmmode_crtc->shadow_id = 0;
382 if (drmmode_crtc->shadow)
383 nouveau_bo_del(&drmmode_crtc->shadow);
385 drmmode_crtc->shadow = NULL;
387 /* for easy acces by exa */
388 pNv->shadow[drmmode_crtc->index] = NULL;
392 drmmode_gamma_set(xf86CrtcPtr crtc, CARD16 *red, CARD16 *green, CARD16 *blue, int size)
394 ScrnInfoPtr pScrn = crtc->scrn;
395 drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
396 drmmode_ptr drmmode = drmmode_crtc->drmmode;
399 ErrorF("drmmode_gamma_set\n");
401 ret = drmModeCrtcSetGamma(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, size, (uint16_t *)red, (uint16_t *)green, (uint16_t *)blue);
403 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "drmModeCrtcSetGamma failed\n");
406 static const xf86CrtcFuncsRec drmmode_crtc_funcs = {
407 .dpms = drmmode_crtc_dpms,
408 .set_mode_major = drmmode_set_mode_major,
409 .set_cursor_colors = drmmode_set_cursor_colors,
410 .set_cursor_position = drmmode_set_cursor_position,
411 .show_cursor = drmmode_show_cursor,
412 .hide_cursor = drmmode_hide_cursor,
413 .load_cursor_argb = drmmode_load_cursor_argb,
414 .shadow_create = drmmode_shadow_create,
415 .shadow_allocate = drmmode_shadow_allocate,
416 .shadow_destroy = drmmode_shadow_destroy,
417 .gamma_set = drmmode_gamma_set,
418 .destroy = NULL, /* XXX */
423 drmmode_crtc_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int num)
426 drmmode_crtc_private_ptr drmmode_crtc;
428 crtc = xf86CrtcCreate(pScrn, &drmmode_crtc_funcs);
432 drmmode_crtc = xnfcalloc(sizeof(drmmode_crtc_private_rec), 1);
433 drmmode_crtc->mode_crtc = drmModeGetCrtc(drmmode->fd, drmmode->mode_res->crtcs[num]);
434 drmmode_crtc->drmmode = drmmode;
435 drmmode_crtc->index = num;
436 crtc->driver_private = drmmode_crtc;
441 static xf86OutputStatus
442 drmmode_output_detect(xf86OutputPtr output)
444 /* go to the hw and retrieve a new output struct */
445 drmmode_output_private_ptr drmmode_output = output->driver_private;
446 drmmode_ptr drmmode = drmmode_output->drmmode;
447 xf86OutputStatus status;
448 drmModeFreeConnector(drmmode_output->mode_output);
450 ErrorF("drmmode_output_detect called\n");
452 drmmode_output->mode_output = drmModeGetConnector(drmmode->fd, drmmode_output->output_id);
454 switch (drmmode_output->mode_output->connection) {
455 case DRM_MODE_CONNECTED:
456 status = XF86OutputStatusConnected;
458 case DRM_MODE_DISCONNECTED:
459 status = XF86OutputStatusDisconnected;
462 case DRM_MODE_UNKNOWNCONNECTION:
463 status = XF86OutputStatusUnknown;
470 drmmode_output_mode_valid(xf86OutputPtr output, DisplayModePtr pModes)
475 static DisplayModePtr
476 drmmode_output_get_modes(xf86OutputPtr output)
478 drmmode_output_private_ptr drmmode_output = output->driver_private;
479 drmModeConnectorPtr koutput = drmmode_output->mode_output;
480 drmmode_ptr drmmode = drmmode_output->drmmode;
482 DisplayModePtr Modes = NULL, Mode;
483 drmModePropertyPtr props;
485 ErrorF("drmmode_output_get_modes called\n");
487 /* look for an EDID property */
488 for (i = 0; i < koutput->count_props; i++) {
489 props = drmModeGetProperty(drmmode->fd, koutput->props[i]);
490 if (props && (props->flags & DRM_MODE_PROP_BLOB)) {
491 if (!strcmp(props->name, "EDID")) {
492 ErrorF("EDID property found\n");
493 if (drmmode_output->edid_blob)
494 drmModeFreePropertyBlob(drmmode_output->edid_blob);
495 drmmode_output->edid_blob = drmModeGetPropertyBlob(drmmode->fd, koutput->prop_values[i]);
497 if (!drmmode_output->edid_blob)
498 ErrorF("No EDID blob\n");
500 drmModeFreeProperty(props);
504 if (drmmode_output->edid_blob)
505 xf86OutputSetEDID(output, xf86InterpretEDID(output->scrn->scrnIndex, drmmode_output->edid_blob->data));
507 xf86OutputSetEDID(output, xf86InterpretEDID(output->scrn->scrnIndex, NULL));
509 /* modes should already be available */
510 for (i = 0; i < koutput->count_modes; i++) {
511 Mode = xnfalloc(sizeof(DisplayModeRec));
513 drmmode_ConvertFromKMode(output->scrn, &koutput->modes[i], Mode);
514 Modes = xf86ModesAdd(Modes, Mode);
521 drmmode_output_destroy(xf86OutputPtr output)
523 drmmode_output_private_ptr drmmode_output = output->driver_private;
525 if (drmmode_output->edid_blob)
526 drmModeFreePropertyBlob(drmmode_output->edid_blob);
527 drmModeFreeConnector(drmmode_output->mode_output);
528 xfree(drmmode_output);
529 output->driver_private = NULL;
533 drmmode_output_dpms(xf86OutputPtr output, int mode)
535 drmmode_output_private_ptr drmmode_output = output->driver_private;
536 drmModeConnectorPtr koutput = drmmode_output->mode_output;
537 drmmode_ptr drmmode = drmmode_output->drmmode;
538 drmModePropertyPtr props;
541 ErrorF("drmmode_output_dpms called with mode %d\n", mode);
543 for (i = 0; i < koutput->count_props; i++) {
544 props = drmModeGetProperty(drmmode->fd, koutput->props[i]);
545 if (props && (props->flags & DRM_MODE_PROP_ENUM)) {
546 if (!strcmp(props->name, "DPMS")) {
547 ErrorF("DPMS property found\n");
548 drmModeConnectorSetProperty(drmmode->fd, drmmode_output->output_id, props->prop_id, mode);
550 drmModeFreeProperty(props);
560 * Several scaling modes exist, let the user choose.
562 #define SCALING_MODE_NAME "SCALING_MODE"
563 static const struct {
567 { "non-gpu", DRM_MODE_SCALE_NON_GPU },
568 { "fullscreen", DRM_MODE_SCALE_FULLSCREEN },
569 { "aspect", DRM_MODE_SCALE_ASPECT },
570 { "noscale", DRM_MODE_SCALE_NO_SCALE },
571 { NULL, 0xFFFF /* invalid */ }
573 static Atom scaling_mode_atom;
575 #define DITHERING_MODE_NAME "DITHERING"
576 static const struct {
579 } dithering_mode[] = {
580 { "off", DRM_MODE_DITHERING_OFF },
581 { "on", DRM_MODE_DITHERING_ON },
582 { NULL, 0xFFFF /* invalid */ }
584 static Atom dithering_atom;
587 drmmode_scaling_mode_lookup(char *name, int size)
591 /* for when name is zero terminated */
595 for (i = 0; scaling_mode[i].name; i++)
596 /* We're getting non-terminated strings */
597 if (strlen(scaling_mode[i].name) >= size &&
598 !strncasecmp(name, scaling_mode[i].name, size))
601 return scaling_mode[i].mode;
605 drmmode_dithering_lookup(char *name, int size)
609 /* for when name is zero terminated */
613 for (i = 0; dithering_mode[i].name; i++)
614 /* We're getting non-terminated strings */
615 if (strlen(dithering_mode[i].name) >= size &&
616 !strncasecmp(name, dithering_mode[i].name, size))
619 return dithering_mode[i].mode;
624 drmmode_output_create_resources(xf86OutputPtr output)
626 ScrnInfoPtr pScrn = output->scrn;
630 * Setup scaling mode property.
632 scaling_mode_atom = MakeAtom(SCALING_MODE_NAME, sizeof(SCALING_MODE_NAME) - 1, TRUE);
634 error = RRConfigureOutputProperty(output->randr_output,
635 scaling_mode_atom, FALSE, FALSE, FALSE,
639 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
640 "RRConfigureOutputProperty error, %d\n", error);
643 /* property has unknown initial value (for the moment) */
646 * Setup dithering property.
648 dithering_atom = MakeAtom(DITHERING_MODE_NAME, sizeof(DITHERING_MODE_NAME) - 1, TRUE);
650 error = RRConfigureOutputProperty(output->randr_output,
651 dithering_atom, FALSE, FALSE, FALSE,
655 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
656 "RRConfigureOutputProperty error, %d\n", error);
659 /* property has unknown initial value (for the moment) */
663 drmmode_output_set_property(xf86OutputPtr output, Atom property,
664 RRPropertyValuePtr value)
666 drmmode_output_private_ptr drmmode_output = output->driver_private;
667 drmModeConnectorPtr koutput = drmmode_output->mode_output;
668 drmmode_ptr drmmode = drmmode_output->drmmode;
669 drmModePropertyPtr props;
670 int i, mode, rval = 0;
672 if (property == scaling_mode_atom) {
675 if (value->type != XA_STRING || value->format != 8)
678 name = (char *) value->data;
680 /* Match a string to a scaling mode */
681 mode = drmmode_scaling_mode_lookup(name, value->size);
685 for (i = 0; i < koutput->count_props; i++) {
686 props = drmModeGetProperty(drmmode->fd, koutput->props[i]);
687 if (props && (props->flags & DRM_MODE_PROP_ENUM)) {
688 if (!strcmp(props->name, "scaling mode")) {
689 ErrorF("scaling mode property found\n");
690 rval = drmModeConnectorSetProperty(drmmode->fd, drmmode_output->output_id, props->prop_id, mode);
692 drmModeFreeProperty(props);
700 } else if (property == dithering_atom) {
703 if (value->type != XA_STRING || value->format != 8)
706 name = (char *) value->data;
708 /* Match a string to a scaling mode */
709 mode = drmmode_dithering_lookup(name, value->size);
713 for (i = 0; i < koutput->count_props; i++) {
714 props = drmModeGetProperty(drmmode->fd, koutput->props[i]);
715 if (props && (props->flags & DRM_MODE_PROP_ENUM)) {
716 if (!strcmp(props->name, "dithering")) {
717 ErrorF("dithering property found\n");
718 rval = drmModeConnectorSetProperty(drmmode->fd, drmmode_output->output_id, props->prop_id, mode);
720 drmModeFreeProperty(props);
733 static const xf86OutputFuncsRec drmmode_output_funcs = {
734 .dpms = drmmode_output_dpms,
735 .detect = drmmode_output_detect,
736 .mode_valid = drmmode_output_mode_valid,
737 .get_modes = drmmode_output_get_modes,
738 .destroy = drmmode_output_destroy,
739 .create_resources = drmmode_output_create_resources,
740 .set_property = drmmode_output_set_property,
743 static int subpixel_conv_table[7] = { 0, SubPixelUnknown,
744 SubPixelHorizontalRGB,
745 SubPixelHorizontalBGR,
755 struct output_name output_names[] = {
763 drmmode_output_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int num)
765 xf86OutputPtr output;
766 drmModeConnectorPtr koutput;
767 drmModeEncoderPtr kencoder;
768 drmmode_output_private_ptr drmmode_output;
771 ErrorF("drmmode_output_init\n");
773 koutput = drmModeGetConnector(drmmode->fd, drmmode->mode_res->connectors[num]);
775 ErrorF("No connector\n");
779 kencoder = drmModeGetEncoder(drmmode->fd, koutput->encoders[0]);
781 ErrorF("No encoder\n");
782 drmModeFreeConnector(koutput);
786 snprintf(name, 32, "%s-%d", output_names[koutput->connector_type].name, output_names[koutput->connector_type].count++);
788 output = xf86OutputCreate (pScrn, &drmmode_output_funcs, name);
790 drmModeFreeEncoder(kencoder);
791 drmModeFreeConnector(koutput);
795 drmmode_output = xcalloc(sizeof(drmmode_output_private_rec), 1);
796 if (!drmmode_output) {
797 xf86OutputDestroy(output);
798 drmModeFreeConnector(koutput);
799 drmModeFreeEncoder(kencoder);
803 drmmode_output->output_id = drmmode->mode_res->connectors[num];
804 drmmode_output->mode_output = koutput;
805 drmmode_output->mode_encoder = kencoder;
806 drmmode_output->drmmode = drmmode;
807 output->mm_width = koutput->mmWidth;
808 output->mm_height = koutput->mmHeight;
810 output->subpixel_order = subpixel_conv_table[koutput->subpixel];
811 output->driver_private = drmmode_output;
813 output->possible_crtcs = kencoder->possible_crtcs;
814 output->possible_clones = kencoder->possible_clones;
819 void drmmode_set_fb(ScrnInfoPtr scrn, drmmode_ptr drmmode, int width, int height, int pitch, struct nouveau_bo *bo)
823 ErrorF("drmmode_set_fb is called\n");
825 ret = drmModeAddFB(drmmode->fd, width, height, scrn->depth,
826 scrn->bitsPerPixel, pitch, bo->map_handle, &drmmode->fb_id);
829 ErrorF("Failed to add fb\n");
832 drmmode->mode_fb = drmModeGetFB(drmmode->fd, drmmode->fb_id);
833 if (!drmmode->mode_fb)
836 ErrorF("Add fb id %d %d %d\n", drmmode->fb_id, width, height);
840 static Bool drmmode_resize_fb(ScrnInfoPtr scrn, drmmode_ptr drmmode, int width, int height)
846 ErrorF("current width %d height %d\n", drmmode->mode_fb->width, drmmode->mode_fb->height);
848 if (drmmode->mode_fb->width == width && drmmode->mode_fb->height == height)
851 if (!drmmode->create_new_fb)
854 handle = drmmode->create_new_fb(scrn, width, height, &pitch);
858 ErrorF("pitch is %d\n", pitch);
859 ret = drmModeReplaceFB(drmmode->fd, drmmode->fb_id,
861 scrn->depth, scrn->depth, pitch,
867 drmModeFreeFB(drmmode->mode_fb);
868 drmmode->mode_fb = drmModeGetFB(drmmode->fd, drmmode->fb_id);
870 if (!drmmode->mode_fb)
877 Bool drmmode_pre_init(ScrnInfoPtr pScrn, char *busId, drmmode_ptr drmmode, int cpp)
879 xf86CrtcConfigPtr xf86_config = NULL;
883 drm_page_size = getpagesize();
885 /* Create a bus Id */
886 /* Low level DRM open */
887 ret = DRIOpenDRMMaster(pScrn, (drm_page_size > SAREA_MAX) ? drm_page_size : SAREA_MAX, busId, "nouveau");
889 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
890 "[dri] DRIGetVersion failed to open the DRM\n");
894 drmmode->fd = DRIMasterFD(pScrn);
896 xf86CrtcConfigInit(pScrn, &drmmode_xf86crtc_config_funcs);
897 xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
900 drmmode->mode_res = drmModeGetResources(drmmode->fd);
901 if (!drmmode->mode_res)
904 xf86CrtcSetSizeRange(pScrn, 320, 200, drmmode->mode_res->max_width, drmmode->mode_res->max_height);
905 for (i = 0; i < drmmode->mode_res->count_crtcs; i++)
906 drmmode_crtc_init(pScrn, drmmode, i);
908 for (i = 0; i < drmmode->mode_res->count_connectors; i++)
909 drmmode_output_init(pScrn, drmmode, i);
911 if (!xf86InitialConfiguration(pScrn, FALSE))
917 #endif /* XF86DRM_MODE */