Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

NV50: Some basic code to get kernel modesetting going.

- This will get a cleanup later on.
  • Loading branch information...
commit 75d8947d40e19c5fc039caf4289cf94fd1570eda 1 parent df52dc4
Maarten Maathuis authored
View
13 configure.ac
@@ -91,9 +91,18 @@ CFLAGS="$CFLAGS -minline-all-stringops"
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include <stdio.h> ]], [[ ]])],
[ CFLAGS="$OLD_CFLAGS -minline-all-stringops"],[CFLAGS="$OLD_CFLAGS"])
-AC_SUBST([CFLAGS])
+# needed for the next test
+CFLAGS="$CFLAGS $XORG_CFLAGS"
+
+AC_CHECK_HEADER([xf86drmMode.h],[DRM_MODE=yes],[DRM_MODE=no],
+ [#include "stdint.h" ]
+)
-AC_SUBST([XORG_CFLAGS])
+if test "x$DRM_MODE" = xyes; then
+ AC_DEFINE(XF86DRM_MODE,1,[DRM kernel modesetting])
+fi
+
+AC_SUBST([CFLAGS])
AC_SUBST([moduledir])
DRIVER_NAME=nouveau
View
2  src/Makefile.am
@@ -86,5 +86,7 @@ nouveau_drv_la_SOURCES = \
nouveau_output.h \
nouveau_connector.h \
nouveau_modeset.h \
+ drmmode_display.c \
+ drmmode_display.h \
nv_pcicompat.h
View
585 src/drmmode_display.c
@@ -0,0 +1,585 @@
+/*
+ * Copyright © 2007 Red Hat, Inc.
+ * Copyright © 2008 Maarten Maathuis
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ * Dave Airlie <airlied@redhat.com>
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef XF86DRM_MODE
+
+#include "drmmode_display.h"
+#include "sarea.h"
+
+/* not using for the moment */
+uint32_t drmmode_create_new_fb(ScrnInfoPtr pScrn, int width, int height, int *pitch)
+{
+#if NOUVEAU_EXA_PIXMAPS
+ NVPtr pNv = NVPTR(pScrn);
+ int ret = 0;
+
+ /* temporary hack, allow old framebuffers to continue to exist and idle. */
+ if (pNv->FB_old) {
+ nouveau_bo_del(pNv->FB_old);
+ pNv->FB_old = NULL;
+ }
+
+ pNv->FB_old = pNv->FB;
+ pNv->FB = NULL;
+
+ *pitch = NOUVEAU_ALIGN(*pitch, 64) * (pScrn->bitsPerPixel >> 3);
+
+ ret = nouveau_bo_new(pNv->dev, NOUVEAU_BO_VRAM | NOUVEAU_BO_PIN,
+ 0, *pitch * NOUVEAU_ALIGN(height, 64), &pNv->FB)
+
+ if (ret)
+ return 0;
+
+ ret = nouveau_bo_map(pNv->FB, NOUVEAU_BO_RDWR);
+
+ if (ret)
+ return 0;
+
+ return pNv->FB.handle;
+#else
+ return 0; /* we have a fixed FB */
+#endif /* NOUVEAU_EXA_PIXMAPS */
+}
+
+static Bool drmmode_resize_fb(ScrnInfoPtr scrn, drmmode_ptr drmmode, int width, int height);
+
+static Bool
+drmmode_xf86crtc_resize (ScrnInfoPtr scrn, int width, int height)
+{
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
+ //drmmode_crtc_private_ptr drmmode_crtc = xf86_config->crtc[0]->driver_private;
+ //drmmode_ptr drmmode = drmmode_crtc->drmmode;
+ //Bool ret;
+
+ ErrorF("resize called %d %d\n", width, height);
+ //ret = drmmode_resize_fb(scrn, drmmode, width, height);
+ scrn->virtualX = width;
+ scrn->virtualY = height;
+
+ return TRUE; //ret;
+}
+
+static void
+drmmode_ConvertFromKMode(ScrnInfoPtr scrn,
+ struct drm_mode_modeinfo *kmode,
+ DisplayModePtr mode)
+{
+ memset(mode, 0, sizeof(DisplayModeRec));
+ mode->status = MODE_OK;
+
+ mode->Clock = kmode->clock;
+
+ mode->HDisplay = kmode->hdisplay;
+ mode->HSyncStart = kmode->hsync_start;
+ mode->HSyncEnd = kmode->hsync_end;
+ mode->HTotal = kmode->htotal;
+ mode->HSkew = kmode->hskew;
+
+ mode->VDisplay = kmode->vdisplay;
+ mode->VSyncStart = kmode->vsync_start;
+ mode->VSyncEnd = kmode->vsync_end;
+ mode->VTotal = kmode->vtotal;
+ mode->VScan = kmode->vscan;
+
+ mode->Flags = kmode->flags; //& FLAG_BITS;
+ mode->name = strdup(kmode->name);
+
+ if (kmode->type & DRM_MODE_TYPE_DRIVER)
+ mode->type = M_T_DRIVER;
+ if (kmode->type & DRM_MODE_TYPE_PREFERRED)
+ mode->type |= M_T_PREFERRED;
+ xf86SetModeCrtc (mode, scrn->adjustFlags);
+}
+
+static void
+drmmode_ConvertToKMode(ScrnInfoPtr scrn,
+ struct drm_mode_modeinfo *kmode,
+ DisplayModePtr mode)
+{
+ memset(kmode, 0, sizeof(*kmode));
+
+ kmode->clock = mode->Clock;
+ kmode->hdisplay = mode->HDisplay;
+ kmode->hsync_start = mode->HSyncStart;
+ kmode->hsync_end = mode->HSyncEnd;
+ kmode->htotal = mode->HTotal;
+ kmode->hskew = mode->HSkew;
+
+ kmode->vdisplay = mode->VDisplay;
+ kmode->vsync_start = mode->VSyncStart;
+ kmode->vsync_end = mode->VSyncEnd;
+ kmode->vtotal = mode->VTotal;
+ kmode->vscan = mode->VScan;
+
+ kmode->flags = mode->Flags; //& FLAG_BITS;
+ if (mode->name)
+ strncpy(kmode->name, mode->name, DRM_DISPLAY_MODE_LEN);
+ kmode->name[DRM_DISPLAY_MODE_LEN-1] = 0;
+
+}
+
+static const xf86CrtcConfigFuncsRec drmmode_xf86crtc_config_funcs = {
+ drmmode_xf86crtc_resize
+};
+
+static void
+drmmode_crtc_dpms(xf86CrtcPtr drmmode_crtc, int mode)
+{
+
+}
+
+static Bool
+drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
+ Rotation rotation, int x, int y)
+{
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn);
+ drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
+ drmmode_ptr drmmode = drmmode_crtc->drmmode;
+ int saved_x, saved_y;
+ Rotation saved_rotation;
+ DisplayModeRec saved_mode;
+ uint32_t *output_ids;
+ int output_count = 0;
+ int ret = TRUE;
+ int i;
+ int fb_id;
+ struct drm_mode_modeinfo kmode;
+
+ ErrorF("drmmode_set_mode_major called\n");
+
+ saved_mode = crtc->mode;
+ saved_x = crtc->x;
+ saved_y = crtc->y;
+ saved_rotation = crtc->rotation;
+
+ crtc->mode = *mode;
+ crtc->x = x;
+ crtc->y = y;
+ crtc->rotation = rotation;
+
+ output_ids = xcalloc(sizeof(uint32_t), xf86_config->num_output);
+ if (!output_ids) {
+ ret = FALSE;
+ goto done;
+ }
+
+ for (i = 0; i < xf86_config->num_output; i++) {
+ xf86OutputPtr output = xf86_config->output[i];
+ drmmode_output_private_ptr drmmode_output;
+
+ if (output->crtc != crtc)
+ continue;
+
+ drmmode_output = output->driver_private;
+ output_ids[output_count] = drmmode_output->mode_output->connector_id;
+ output_count++;
+ }
+
+ if (!xf86CrtcRotate(crtc, mode, rotation)) {
+ goto done;
+ }
+
+ drmmode_ConvertToKMode(crtc->scrn, &kmode, mode);
+
+ fb_id = drmmode->fb_id;
+ ErrorF("fb id is %d\n", fb_id);
+ drmModeSetCrtc(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id,
+ fb_id, x, y, output_ids, output_count, &kmode);
+
+done:
+ if (!ret) {
+ crtc->x = saved_x;
+ crtc->y = saved_y;
+ crtc->rotation = saved_rotation;
+ crtc->mode = saved_mode;
+ }
+ return ret;
+}
+
+static void
+drmmode_set_cursor_colors (xf86CrtcPtr crtc, int bg, int fg)
+{
+
+}
+
+static void
+drmmode_set_cursor_position (xf86CrtcPtr crtc, int x, int y)
+{
+ drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
+ drmmode_ptr drmmode = drmmode_crtc->drmmode;
+
+ drmModeMoveCursor(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, x, y);
+}
+
+static void
+drmmode_load_cursor_argb (xf86CrtcPtr crtc, CARD32 *image)
+{
+ drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
+
+ NVPtr pNv = NVPTR(crtc->scrn);
+ uint32_t *dst = NULL;
+
+ if (drmmode_crtc->index == 1)
+ dst = (uint32_t *) pNv->Cursor2->map;
+ else
+ dst = (uint32_t *) pNv->Cursor->map;
+
+ /* Assume cursor is 64x64 */
+ memcpy(dst, (uint32_t *)image, 64 * 64 * 4);
+}
+
+
+static void
+drmmode_hide_cursor (xf86CrtcPtr crtc)
+{
+ drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
+ drmmode_ptr drmmode = drmmode_crtc->drmmode;
+
+ drmModeSetCursor(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, 0, 64, 64);
+
+}
+
+static void
+drmmode_show_cursor (xf86CrtcPtr crtc)
+{
+ drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
+ drmmode_ptr drmmode = drmmode_crtc->drmmode;
+ NVPtr pNv = NVPTR(crtc->scrn);
+
+ drm_handle_t handle = 0;
+
+ if (drmmode_crtc->index == 1)
+ handle = pNv->Cursor2->map_handle;
+ else
+ handle = pNv->Cursor->map_handle;
+
+ drmModeSetCursor(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, handle, 64, 64);
+}
+
+static const xf86CrtcFuncsRec drmmode_crtc_funcs = {
+ .dpms = drmmode_crtc_dpms,
+ .set_mode_major = drmmode_set_mode_major,
+ .set_cursor_colors = drmmode_set_cursor_colors,
+ .set_cursor_position = drmmode_set_cursor_position,
+ .show_cursor = drmmode_show_cursor,
+ .hide_cursor = drmmode_hide_cursor,
+ .load_cursor_argb = drmmode_load_cursor_argb,
+ .destroy = NULL, /* XXX */
+};
+
+
+static void
+drmmode_crtc_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int num)
+{
+ xf86CrtcPtr crtc;
+ drmmode_crtc_private_ptr drmmode_crtc;
+
+ crtc = xf86CrtcCreate(pScrn, &drmmode_crtc_funcs);
+ if (crtc == NULL)
+ return;
+
+ drmmode_crtc = xnfcalloc(sizeof(drmmode_crtc_private_rec), 1);
+ drmmode_crtc->mode_crtc = drmModeGetCrtc(drmmode->fd, drmmode->mode_res->crtcs[num]);
+ drmmode_crtc->drmmode = drmmode;
+ drmmode_crtc->index = num;
+ crtc->driver_private = drmmode_crtc;
+
+ return;
+}
+
+static xf86OutputStatus
+drmmode_output_detect(xf86OutputPtr output)
+{
+ /* go to the hw and retrieve a new output struct */
+ drmmode_output_private_ptr drmmode_output = output->driver_private;
+ drmmode_ptr drmmode = drmmode_output->drmmode;
+ xf86OutputStatus status;
+ drmModeFreeConnector(drmmode_output->mode_output);
+
+ drmmode_output->mode_output = drmModeGetConnector(drmmode->fd, drmmode_output->output_id);
+
+ switch (drmmode_output->mode_output->connection) {
+ case DRM_MODE_CONNECTED:
+ status = XF86OutputStatusConnected;
+ break;
+ case DRM_MODE_DISCONNECTED:
+ status = XF86OutputStatusDisconnected;
+ break;
+ default:
+ case DRM_MODE_UNKNOWNCONNECTION:
+ status = XF86OutputStatusUnknown;
+ break;
+ }
+ return status;
+}
+
+static Bool
+drmmode_output_mode_valid(xf86OutputPtr output, DisplayModePtr pModes)
+{
+ return MODE_OK;
+}
+
+static DisplayModePtr
+drmmode_output_get_modes(xf86OutputPtr output)
+{
+ drmmode_output_private_ptr drmmode_output = output->driver_private;
+ drmModeConnectorPtr koutput = drmmode_output->mode_output;
+ drmmode_ptr drmmode = drmmode_output->drmmode;
+ int i;
+ DisplayModePtr Modes = NULL, Mode;
+ drmModePropertyPtr props;
+
+ ErrorF("drmmode_output_get_modes called\n");
+
+ /* look for an EDID property */
+ for (i = 0; i < koutput->count_props; i++) {
+ props = drmModeGetProperty(drmmode->fd, koutput->props[i]);
+ if (props && (props->flags & DRM_MODE_PROP_BLOB)) {
+ if (!strcmp(props->name, "EDID")) {
+ if (drmmode_output->edid_blob)
+ drmModeFreePropertyBlob(drmmode_output->edid_blob);
+ drmmode_output->edid_blob = drmModeGetPropertyBlob(drmmode->fd, koutput->prop_values[i]);
+ }
+ drmModeFreeProperty(props);
+ }
+ }
+
+ if (drmmode_output->edid_blob)
+ xf86OutputSetEDID(output, xf86InterpretEDID(output->scrn->scrnIndex, drmmode_output->edid_blob->data));
+ else
+ xf86OutputSetEDID(output, xf86InterpretEDID(output->scrn->scrnIndex, NULL));
+
+ /* modes should already be available */
+ for (i = 0; i < koutput->count_modes; i++) {
+ Mode = xnfalloc(sizeof(DisplayModeRec));
+
+ drmmode_ConvertFromKMode(output->scrn, &koutput->modes[i], Mode);
+ Modes = xf86ModesAdd(Modes, Mode);
+
+ }
+ return Modes;
+}
+
+static void
+drmmode_output_destroy(xf86OutputPtr output)
+{
+ drmmode_output_private_ptr drmmode_output = output->driver_private;
+
+ if (drmmode_output->edid_blob)
+ drmModeFreePropertyBlob(drmmode_output->edid_blob);
+ drmModeFreeConnector(drmmode_output->mode_output);
+ xfree(drmmode_output);
+ output->driver_private = NULL;
+}
+
+static void
+drmmode_output_dpms(xf86OutputPtr output, int mode)
+{
+ return;
+}
+
+static const xf86OutputFuncsRec drmmode_output_funcs = {
+ .dpms = drmmode_output_dpms,
+ .detect = drmmode_output_detect,
+ .mode_valid = drmmode_output_mode_valid,
+ .get_modes = drmmode_output_get_modes,
+ .destroy = drmmode_output_destroy
+};
+
+static int subpixel_conv_table[7] = { 0, SubPixelUnknown,
+ SubPixelHorizontalRGB,
+ SubPixelHorizontalBGR,
+ SubPixelVerticalRGB,
+ SubPixelVerticalBGR,
+ SubPixelNone };
+
+struct output_name {
+ const char *name;
+ int count;
+};
+
+struct output_name output_names[] = {
+ { "None", 0 },
+ { "VGA", 0 },
+ { "DVI-I", 0 },
+ { "DVI-D", 0 },
+};
+
+static void
+drmmode_output_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int num)
+{
+ xf86OutputPtr output;
+ drmModeConnectorPtr koutput;
+ drmModeEncoderPtr kencoder;
+ drmmode_output_private_ptr drmmode_output;
+ char name[32];
+
+ koutput = drmModeGetConnector(drmmode->fd, drmmode->mode_res->connectors[num]);
+ if (!koutput)
+ return;
+
+ kencoder = drmModeGetEncoder(drmmode->fd, koutput->encoders[0]);
+ if (!kencoder) {
+ drmModeFreeConnector(koutput);
+ return;
+ }
+
+ snprintf(name, 32, "%s-%d", output_names[koutput->connector_type].name, output_names[koutput->connector_type].count++);
+
+ output = xf86OutputCreate (pScrn, &drmmode_output_funcs, name);
+ if (!output) {
+ drmModeFreeEncoder(kencoder);
+ drmModeFreeConnector(koutput);
+ return;
+ }
+
+ drmmode_output = xcalloc(sizeof(drmmode_output_private_rec), 1);
+ if (!drmmode_output) {
+ xf86OutputDestroy(output);
+ drmModeFreeConnector(koutput);
+ drmModeFreeEncoder(kencoder);
+ return;
+ }
+
+ drmmode_output->output_id = drmmode->mode_res->connectors[num];
+ drmmode_output->mode_output = koutput;
+ drmmode_output->mode_encoder = kencoder;
+ drmmode_output->drmmode = drmmode;
+ output->mm_width = koutput->mmWidth;
+ output->mm_height = koutput->mmHeight;
+
+ output->subpixel_order = subpixel_conv_table[koutput->subpixel];
+ output->driver_private = drmmode_output;
+
+ output->possible_crtcs = kencoder->crtcs;
+ output->possible_clones = kencoder->clones;
+ return;
+}
+
+void drmmode_set_fb(ScrnInfoPtr scrn, drmmode_ptr drmmode, int width, int height, int pitch, struct nouveau_bo *bo)
+{
+ int ret;
+
+ ErrorF("drmmode_set_fb is called\n");
+
+ ret = drmModeAddFB(drmmode->fd, width, height, scrn->depth,
+ scrn->bitsPerPixel, pitch, bo->map_handle, &drmmode->fb_id);
+
+ if (ret) {
+ ErrorF("Failed to add fb\n");
+ }
+
+ drmmode->mode_fb = drmModeGetFB(drmmode->fd, drmmode->fb_id);
+ if (!drmmode->mode_fb)
+ return;
+
+ ErrorF("Add fb id %d %d %d\n", drmmode->fb_id, width, height);
+}
+
+static Bool drmmode_resize_fb(ScrnInfoPtr scrn, drmmode_ptr drmmode, int width, int height)
+{
+ uint32_t handle;
+ int pitch;
+ int ret;
+
+ ErrorF("current width %d height %d\n", drmmode->mode_fb->width, drmmode->mode_fb->height);
+
+ if (drmmode->mode_fb->width == width && drmmode->mode_fb->height == height)
+ return TRUE;
+
+ if (!drmmode->create_new_fb)
+ return FALSE;
+
+ handle = drmmode->create_new_fb(scrn, width, height, &pitch);
+ if (handle == 0)
+ return FALSE;
+
+ ErrorF("pitch is %d\n", pitch);
+ ret = drmModeReplaceFB(drmmode->fd, drmmode->fb_id,
+ width, height,
+ scrn->depth, scrn->depth, pitch,
+ handle);
+
+ if (ret)
+ return FALSE;
+
+ drmModeFreeFB(drmmode->mode_fb);
+ drmmode->mode_fb = drmModeGetFB(drmmode->fd, drmmode->fb_id);
+
+ if (!drmmode->mode_fb)
+ return FALSE;
+
+ return TRUE;
+}
+
+Bool drmmode_pre_init(ScrnInfoPtr pScrn, char *busId, drmmode_ptr drmmode, int cpp)
+{
+ xf86CrtcConfigPtr xf86_config = NULL;
+ NVPtr pNv = NVPTR(pScrn);
+ int i, ret;
+
+ int drm_page_size;
+ drm_page_size = getpagesize();
+
+ /* Create a bus Id */
+ /* Low level DRM open */
+ ret = DRIOpenDRMMaster(pScrn, (drm_page_size > SAREA_MAX) ? drm_page_size : SAREA_MAX, busId, "nouveau");
+ if (!ret) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "[dri] DRIGetVersion failed to open the DRM\n");
+ return FALSE;
+ }
+
+ drmmode->fd = DRIMasterFD(pScrn);
+
+ xf86CrtcConfigInit(pScrn, &drmmode_xf86crtc_config_funcs);
+ xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+
+ drmmode->cpp = cpp;
+ drmmode->mode_res = drmModeGetResources(drmmode->fd);
+ if (!drmmode->mode_res)
+ return FALSE;
+
+ xf86CrtcSetSizeRange(pScrn, 320, 200, drmmode->mode_res->max_width, drmmode->mode_res->max_height);
+ for (i = 0; i < drmmode->mode_res->count_crtcs; i++)
+ drmmode_crtc_init(pScrn, drmmode, i);
+
+ for (i = 0; i < drmmode->mode_res->count_connectors; i++)
+ drmmode_output_init(pScrn, drmmode, i);
+
+ if (!xf86InitialConfiguration(pScrn, FALSE))
+ return FALSE;
+
+ return TRUE;
+}
+
+#endif /* XF86DRM_MODE */
View
65 src/drmmode_display.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright © 2007 Red Hat, Inc.
+ * Copyright © 2008 Maarten Maathuis
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ * Dave Airlie <airlied@redhat.com>
+ *
+ */
+#ifndef DRMMODE_DISPLAY_H
+#define DRMMODE_DISPLAY_H
+
+#ifdef XF86DRM_MODE
+
+#include "nv_include.h"
+#include "xf86drmMode.h"
+
+typedef struct {
+ int fd;
+ int fb_id;
+ drmModeResPtr mode_res;
+ drmModeFBPtr mode_fb;
+ int cpp;
+
+ uint32_t (*create_new_fb)(ScrnInfoPtr pScrn, int width, int height, int *pitch);
+} drmmode_rec, *drmmode_ptr;
+
+typedef struct {
+ int index;
+ drmmode_ptr drmmode;
+ drmModeCrtcPtr mode_crtc;
+} drmmode_crtc_private_rec, *drmmode_crtc_private_ptr;
+
+typedef struct {
+ drmmode_ptr drmmode;
+ int output_id;
+ drmModeConnectorPtr mode_output;
+ drmModeEncoderPtr mode_encoder;
+ drmModePropertyBlobPtr edid_blob;
+} drmmode_output_private_rec, *drmmode_output_private_ptr;
+
+Bool drmmode_pre_init(ScrnInfoPtr pScrn, char *busId, drmmode_ptr drmmode, int cpp);
+void drmmode_set_fb(ScrnInfoPtr scrn, drmmode_ptr drmmode, int width, int height, int pitch, struct nouveau_bo *bo);
+
+#endif /* XF86DRM_MODE */
+
+#endif /* DRMMODE_DISPLAY_H */
View
1  src/nouveau_bo.c
@@ -69,6 +69,7 @@ nouveau_bo_new(struct nouveau_device *userdev, uint32_t flags, int align,
bo->base.size = bo->drm.size;
bo->base.offset = bo->drm.offset;
bo->base.handle = (unsigned long)bo;
+ bo->base.map_handle = bo->drm.map_handle;
bo->refcount = 1;
*userbo = &bo->base;
return 0;
View
1  src/nouveau_bo.h
@@ -38,6 +38,7 @@
struct nouveau_bo {
struct nouveau_device *device;
uint64_t handle;
+ drm_handle_t map_handle;
uint64_t size;
void *map;
View
4 src/nv_const.h
@@ -30,7 +30,8 @@ typedef enum {
OPTION_CMDBUF_SIZE,
OPTION_RANDR12,
OPTION_SCALING_MODE,
- OPTION_NEW_RESTORE
+ OPTION_NEW_RESTORE,
+ OPTION_KMS,
} NVOpts;
@@ -51,6 +52,7 @@ static const OptionInfoRec NVOptions[] = {
{ OPTION_RANDR12, "Randr12", OPTV_BOOLEAN, {0}, FALSE },
{ OPTION_SCALING_MODE, "ScalingMode", OPTV_STRING, {0}, FALSE },
{ OPTION_NEW_RESTORE, "NewRestore", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_KMS, "KMS", OPTV_BOOLEAN, {0}, FALSE },
{ -1, NULL, OPTV_NONE, {0}, FALSE }
};
View
29 src/nv_dri.c
@@ -8,6 +8,7 @@
#include "dri.h"
#include "nv_dripriv.h"
#include "nv_dri.h"
+#include "drmmode_display.h"
static Bool NVCreateContext(ScreenPtr pScreen, VisualPtr visual,
drm_context_t hwContext, void *pVisualConfigPriv,
@@ -167,7 +168,15 @@ Bool NVDRIGetVersion(ScrnInfoPtr pScrn)
{
NVPtr pNv = NVPTR(pScrn);
char *busId;
- int fd;
+ int fd = 0;
+
+#ifdef XF86DRM_MODE
+ /* drm already open */
+ if (pNv->drmmode) {
+ drmmode_ptr drmmode = pNv->drmmode;
+ fd = drmmode->fd;
+ }
+#endif
{
pointer ret;
@@ -189,10 +198,12 @@ Bool NVDRIGetVersion(ScrnInfoPtr pScrn)
xf86LoaderReqSymLists(driSymbols, NULL);
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Loaded DRI module\n");
- busId = DRICreatePCIBusID(pNv->PciInfo);
+ if (!fd) {
+ busId = DRICreatePCIBusID(pNv->PciInfo);
- fd = drmOpen("nouveau", busId);
- xfree(busId);
+ fd = drmOpen("nouveau", busId);
+ xfree(busId);
+ }
if (fd < 0) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"[dri] Failed to open the DRM\n");
@@ -211,7 +222,7 @@ Bool NVDRIGetVersion(ScrnInfoPtr pScrn)
}
pNv->pKernelDRMVersion = drmGetVersion(fd);
- drmClose(fd);
+ //drmClose(fd);
if (pNv->pKernelDRMVersion == NULL) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"failed to get DRM version\n");
@@ -255,6 +266,14 @@ Bool NVDRIScreenInit(ScrnInfoPtr pScrn)
int drm_page_size;
int drm_fd;
+#ifdef XF86DRM_MODE
+ /* drm already open */
+ if (pNv->drmmode) {
+ drmmode_ptr drmmode = pNv->drmmode;
+ drm_fd = drmmode->fd;
+ }
+#endif
+
if (!NVDRICheckModules(pScrn))
return FALSE;
View
121 src/nv_driver.c
@@ -297,7 +297,7 @@ NVFreeRec(ScrnInfoPtr pScrn)
if (pScrn->driverPrivate == NULL)
return;
NVPtr pNv = NVPTR(pScrn);
- if (pNv->Architecture == NV_ARCH_50) {
+ if (pNv->Architecture == NV_ARCH_50 && !pNv->kms_enable) {
NV50ConnectorDestroy(pScrn);
NV50OutputDestroy(pScrn);
NV50CrtcDestroy(pScrn);
@@ -696,35 +696,40 @@ NVEnterVT(int scrnIndex, int flags)
ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
NVPtr pNv = NVPTR(pScrn);
- if (pNv->randr12_enable) {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "NVEnterVT is called.\n");
- xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
- int i;
- pScrn->vtSema = TRUE;
+ if (!pNv->kms_enable) {
+ if (pNv->randr12_enable) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "NVEnterVT is called.\n");
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+ int i;
+ pScrn->vtSema = TRUE;
+
+ if (pNv->Architecture == NV_ARCH_50) {
+ if (!NV50AcquireDisplay(pScrn))
+ return FALSE;
+ return TRUE;
+ }
- if (pNv->Architecture == NV_ARCH_50) {
- if (!NV50AcquireDisplay(pScrn))
- return FALSE;
- return TRUE;
- }
+ /* Save the current state */
+ if (pNv->SaveGeneration != serverGeneration) {
+ pNv->SaveGeneration = serverGeneration;
+ NVSave(pScrn);
+ }
- /* Save the current state */
- if (pNv->SaveGeneration != serverGeneration) {
- pNv->SaveGeneration = serverGeneration;
- NVSave(pScrn);
- }
+ for (i = 0; i < xf86_config->num_crtc; i++) {
+ NVCrtcLockUnlock(xf86_config->crtc[i], 0);
+ }
- for (i = 0; i < xf86_config->num_crtc; i++) {
- NVCrtcLockUnlock(xf86_config->crtc[i], 0);
- }
+ if (!xf86SetDesiredModes(pScrn))
+ return FALSE;
+ } else {
+ if (!NVModeInit(pScrn, pScrn->currentMode))
+ return FALSE;
- if (!xf86SetDesiredModes(pScrn))
- return FALSE;
+ NVAdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
+ }
} else {
- if (!NVModeInit(pScrn, pScrn->currentMode))
- return FALSE;
-
- NVAdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
+ if (!xf86SetDesiredModes(pScrn))
+ return FALSE;
}
if (pNv->overlayAdaptor && pNv->Architecture != NV_ARCH_04)
@@ -750,6 +755,9 @@ NVLeaveVT(int scrnIndex, int flags)
NVSync(pScrn);
+ if (pNv->kms_enable)
+ return;
+
if (pNv->Architecture == NV_ARCH_50) {
NV50ReleaseDisplay(pScrn);
return;
@@ -803,7 +811,9 @@ NVCloseScreen(int scrnIndex, ScreenPtr pScreen)
if (pScrn->vtSema) {
pScrn->vtSema = FALSE;
- if (pNv->Architecture == NV_ARCH_50) {
+ if (pNv->kms_enable) {
+ int dummy = 0; /* TODO */
+ } else if (pNv->Architecture == NV_ARCH_50) {
NV50ReleaseDisplay(pScrn);
} else {
if (pNv->randr12_enable)
@@ -817,6 +827,7 @@ NVCloseScreen(int scrnIndex, ScreenPtr pScreen)
NVUnmapMem(pScrn);
vgaHWUnmapMem(pScrn);
+ nouveau_device_close(pNv->dev);
if (pNv->CursorInfoRec)
xf86DestroyCursorInfoRec(pNv->CursorInfoRec);
if (pNv->ShadowPtr)
@@ -1144,6 +1155,18 @@ NVPreInit(ScrnInfoPtr pScrn, int flags)
from = X_DEFAULT;
+ pNv->kms_enable = false;
+#ifdef XF86DRM_MODE
+ if (pNv->Architecture == NV_ARCH_50) {
+ if (xf86ReturnOptValBool(pNv->Options, OPTION_KMS, FALSE)) {
+ pNv->kms_enable = true;
+ }
+ }
+#endif /* XF86DRM_MODE */
+
+ if (pNv->kms_enable)
+ xf86DrvMsg(pScrn->scrnIndex, from, "NV50 Kernel modesetting enabled\n");
+
if (pNv->Architecture == NV_ARCH_50) {
pNv->randr12_enable = TRUE;
} else {
@@ -1301,15 +1324,29 @@ NVPreInit(ScrnInfoPtr pScrn, int flags)
if (xf86RegisterResources(pNv->pEnt->index, NULL, ResExclusive))
NVPreInitFail("xf86RegisterResources() found resource conflicts\n");
- if(pNv->Architecture < NV_ARCH_10) {
+ if (pNv->Architecture < NV_ARCH_10) {
max_width = (pScrn->bitsPerPixel > 16) ? 2032 : 2048;
max_height = 2048;
- } else {
+ } else if (pNv->Architecture < NV_ARCH_50) {
max_width = (pScrn->bitsPerPixel > 16) ? 4080 : 4096;
max_height = 4096;
+ } else {
+ max_width = (pScrn->bitsPerPixel > 16) ? 8176 : 8192;
+ max_height = 8192;
}
- if (pNv->randr12_enable) {
+ if (pNv->kms_enable){
+ int res = 0;
+ char *bus_id;
+ bus_id = DRICreatePCIBusID(pNv->PciInfo);
+
+ pNv->drmmode = calloc(1, sizeof(drmmode_rec));
+ res = drmmode_pre_init(pScrn, bus_id, pNv->drmmode, pScrn->bitsPerPixel >> 3);
+ if (!res) {
+ xfree(bus_id);
+ NVPreInitFail("Kernel modesetting failed to initialize\n");
+ }
+ } else if (pNv->randr12_enable) {
/* Allocate an xf86CrtcConfig */
xf86CrtcConfigInit(pScrn, &nv_xf86crtc_config_funcs);
xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
@@ -1333,7 +1370,7 @@ NVPreInit(ScrnInfoPtr pScrn, int flags)
NVCommonSetup(pScrn);
- if (pNv->randr12_enable) {
+ if (pNv->randr12_enable && !pNv->kms_enable) {
if (pNv->Architecture == NV_ARCH_50)
if (!NV50DispPreInit(pScrn))
NVPreInitFail("\n");
@@ -1558,8 +1595,12 @@ NVMapMem(ScrnInfoPtr pScrn)
return FALSE;
}
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Allocated %dMiB VRAM for framebuffer + offscreen pixmaps\n",
- (unsigned int)(pNv->FB->size >> 20));
+ "Allocated %dMiB VRAM for framebuffer + offscreen pixmaps, at offset 0x%X\n",
+ (unsigned int)(pNv->FB->size >> 20), pNv->FB->offset);
+#ifdef XF86DRM_MODE
+ if (pNv->kms_enable)
+ drmmode_set_fb(pScrn, pNv->drmmode, pScrn->virtualX, pScrn->virtualY, pScrn->displayWidth*(pScrn->bitsPerPixel >> 3), pNv->FB);
+#endif
#endif
if (pNv->AGPSize) {
@@ -2418,14 +2459,16 @@ NVScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
* Initialize colormap layer.
* Must follow initialization of the default colormap
*/
- if (!pNv->randr12_enable) {
- if(!xf86HandleColormaps(pScreen, 256, 8, NVDACLoadPalette,
- NULL, CMAP_RELOAD_ON_MODE_SWITCH | CMAP_PALETTED_TRUECOLOR))
- return FALSE;
- } else {
- if (!xf86HandleColormaps(pScreen, 256, 8, NVLoadPalette,
- NULL, CMAP_PALETTED_TRUECOLOR))
+ if (!pNv->kms_enable) {
+ if (!pNv->randr12_enable) {
+ if(!xf86HandleColormaps(pScreen, 256, 8, NVDACLoadPalette,
+ NULL, CMAP_RELOAD_ON_MODE_SWITCH | CMAP_PALETTED_TRUECOLOR))
return FALSE;
+ } else {
+ if (!xf86HandleColormaps(pScreen, 256, 8, NVLoadPalette,
+ NULL, CMAP_PALETTED_TRUECOLOR))
+ return FALSE;
+ }
}
if(pNv->ShadowFB) {
View
2  src/nv_include.h
@@ -75,6 +75,8 @@
#include "nvreg.h"
#include "nv50reg.h"
+#include "drmmode_display.h"
+
#include "nouveau_device.h"
#include "nouveau_drmif.h"
#include "nouveau_dma.h"
View
7 src/nv_type.h
@@ -28,6 +28,7 @@
#include "nouveau_connector.h"
#include "nouveau_output.h"
+#include "drmmode_display.h"
#define NV_ARCH_03 0x03
#define NV_ARCH_04 0x04
@@ -384,6 +385,7 @@ typedef struct _NVRec {
/* Various pinned memory regions */
struct nouveau_bo * FB;
+ struct nouveau_bo * FB_old; /* for KMS */
struct nouveau_bo * Cursor;
struct nouveau_bo * Cursor2;
struct nouveau_bo * CLUT0; /* NV50 only */
@@ -463,10 +465,15 @@ typedef struct _NVRec {
drmVersionPtr pKernelDRMVersion;
Bool randr12_enable;
+ Bool kms_enable;
Bool new_restore;
I2CBusPtr pI2CBus[MAX_NUM_DCB_ENTRIES];
+#ifdef XF86DRM_MODE
+ void *drmmode; /* for KMS */
+#endif
+
struct {
int entries;
struct dcb_entry entry[MAX_NUM_DCB_ENTRIES];
Please sign in to comment.
Something went wrong with that request. Please try again.