diff options
author | Jesse Barnes <jbarnes@virtuousgeek.org> | 2008-08-21 09:30:38 -0700 |
---|---|---|
committer | Jesse Barnes <jbarnes@virtuousgeek.org> | 2008-08-21 09:30:38 -0700 |
commit | 08326827fdb8abecbff20c7b051537dbad433c40 (patch) | |
tree | 532df345e42bb72e6e18dbcb5073b581a49f8e16 | |
parent | 5af504166f14f4401818f3b7c27ac2ccba7b9ff5 (diff) | |
parent | 0de8ca36306c506356e82d500134b4eeb96a6080 (diff) |
Merge branch 'modesetting-gem'
-rw-r--r-- | configure.ac | 13 | ||||
-rw-r--r-- | src/Makefile.am | 4 | ||||
-rw-r--r-- | src/common.h | 4 | ||||
-rw-r--r-- | src/drmmode_display.c | 703 | ||||
-rw-r--r-- | src/drmmode_display.h | 73 | ||||
-rw-r--r-- | src/i830.h | 20 | ||||
-rw-r--r-- | src/i830_accel.c | 2 | ||||
-rw-r--r-- | src/i830_batchbuffer.h | 6 | ||||
-rw-r--r-- | src/i830_bios.c | 6 | ||||
-rw-r--r-- | src/i830_dri.c | 39 | ||||
-rw-r--r-- | src/i830_driver.c | 1127 | ||||
-rw-r--r-- | src/i830_exa.c | 206 | ||||
-rw-r--r-- | src/i830_memory.c | 242 | ||||
-rw-r--r-- | src/i830_video.c | 2 | ||||
-rw-r--r-- | src/i965_render.c | 20 | ||||
-rw-r--r-- | src/reg_dumper/reg_dumper.h | 1 |
16 files changed, 1907 insertions, 561 deletions
diff --git a/configure.ac b/configure.ac index 47f7fe23..e6a2f6fb 100644 --- a/configure.ac +++ b/configure.ac @@ -85,12 +85,17 @@ XORG_DRIVER_CHECK_EXT(DPMSExtension, xextproto) # Checks for pkg-config packages PKG_CHECK_MODULES(XORG, [xorg-server xproto fontsproto $REQUIRED_MODULES]) sdkdir=$(pkg-config --variable=sdkdir xorg-server) +drm_cflags=$(pkg-config --cflags libdrm) # Checks for libraries. # Checks for header files. AC_HEADER_STDC +save_CFLAGS="$CFLAGS" +CFLAGS="$XORG_CFLAGS $DRI_CFLAGS $drm_cflags" +CPPFLAGS="$XORG_CFLAGS $DRI_CFLAGS $drm_cflags" +AC_MSG_CHECKING([whether to include DRI support]) if test x$DRI != xno; then AC_CHECK_FILE([${sdkdir}/dri.h], [have_dri_h="yes"], [have_dri_h="no"]) @@ -100,6 +105,12 @@ if test x$DRI != xno; then [have_dristruct_h="yes"], [have_dristruct_h="no"]) AC_CHECK_FILE([${sdkdir}/damage.h], [have_damage_h="yes"], [have_damage_h="no"]) + AC_CHECK_HEADER(xf86drmMode.h, + [DRM_MODE=yes],[DRM_MODE=no] + [#include "stdint.h"]) + if test "x$DRM_MODE" = xyes; then + AC_DEFINE(XF86DRM_MODE,1,[DRM kernel modesetting]) + fi fi AC_MSG_CHECKING([whether to include DRI support]) if test x$DRI = xauto; then @@ -113,8 +124,6 @@ if test x$DRI = xauto; then fi AC_MSG_RESULT([$DRI]) -save_CFLAGS="$CFLAGS" -CFLAGS="$XORG_CFLAGS" AC_CHECK_HEADER(xf86Modes.h,[XMODES=yes],[XMODES=no],[#include "xorg-server.h"]) AC_CHECK_DECL(XSERVER_LIBPCIACCESS, [XSERVER_LIBPCIACCESS=yes],[XSERVER_LIBPCIACCESS=no], diff --git a/src/Makefile.am b/src/Makefile.am index dd92c8d9..1b1b67c8 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -130,7 +130,9 @@ intel_drv_la_SOURCES = \ i830_xaa.c \ i830_render.c \ i915_render.c \ - i965_render.c + i965_render.c \ + drmmode_display.c \ + drmmode_display.h INTEL_G4A = \ packed_yuv_sf.g4a \ diff --git a/src/common.h b/src/common.h index f2ae502b..ece1def0 100644 --- a/src/common.h +++ b/src/common.h @@ -370,7 +370,9 @@ extern int I810_DEBUG; /* mark chipsets without overlay hw */ #define OVERLAY_NOEXIST(pI810) (IS_GM45(pI810) || IS_G4X(pI810)) /* chipsets require graphics mem for hardware status page */ -#define HWS_NEED_GFX(pI810) (IS_G33CLASS(pI810) || IS_GM45(pI810) || IS_G4X(pI810)) +#define HWS_NEED_GFX(pI810) (!pI810->use_drm_mode && \ + (IS_G33CLASS(pI810) || IS_GM45(pI810) || \ + IS_G4X(pI810))) /* chipsets require status page in non stolen memory */ #define HWS_NEED_NONSTOLEN(pI810) (IS_GM45(pI810) || IS_G4X(pI810)) #define SUPPORTS_INTEGRATED_HDMI(pI810) (IS_GM45(pI810) || IS_G4X(pI810)) diff --git a/src/drmmode_display.c b/src/drmmode_display.c new file mode 100644 index 00000000..5154b423 --- /dev/null +++ b/src/drmmode_display.c @@ -0,0 +1,703 @@ +/* + * Copyright © 2007 Red Hat, Inc. + * + * 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 "i830.h" +#include "sarea.h" + +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; + + ret = drmmode_resize_fb(scrn, drmmode, width, height); + scrn->virtualX = width; + scrn->virtualY = height; + return 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; + + 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; + if (drmmode_crtc->rotate_fb_id) + fb_id = drmmode_crtc->rotate_fb_id; + ErrorF("fb id is %d\n", fb_id); + ret = drmModeSetCrtc(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, + fb_id, x, y, output_ids, output_count, &kmode); + if (ret) + xf86DrvMsg(crtc->scrn->scrnIndex, X_ERROR, + "failed to set mode: %s", strerror(-ret)); + else + ret = TRUE; + +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; + ScrnInfoPtr pScrn = crtc->scrn; + I830Ptr pI830 = I830PTR(pScrn); + int ret; + + /* cursor should be mapped already */ + ret = dri_bo_subdata(pI830->cursor_mem->bo, 0, 64*64*4, image); + if (ret) + xf86DrvMsg(crtc->scrn->scrnIndex, X_ERROR, + "failed to set cursor: %s", strerror(-ret)); + + return; +} + + +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; + ScrnInfoPtr pScrn = crtc->scrn; + I830Ptr pI830 = I830PTR(pScrn); + + drmModeSetCursor(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, + pI830->cursor_mem->bo->handle, 64, 64); +} + +static void * +drmmode_crtc_shadow_allocate(xf86CrtcPtr crtc, int width, int height) +{ + drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; + drmmode_ptr drmmode = drmmode_crtc->drmmode; + int size; + unsigned long rotate_pitch; + + rotate_pitch = crtc->scrn->displayWidth * drmmode->cpp; + size = rotate_pitch * height; + +#if 0 + drmmode_crtc->rotate_bo = + dri_bo_alloc(drmmode->bufmgr, "rotate", size, 4096); + + if (!drmmode_crtc->rotate_bo) { + xf86DrvMsg(crtc->scrn->scrnIndex, X_ERROR, + "Couldn't allocate shadow memory for rotated CRTC\n"); + return NULL; + } + + dri_bo_map(drmmode_crtc->rotate_bo, 1); + + ret = drmModeAddFB(drmmode->fd, width, height, crtc->scrn->depth, + crtc->scrn->bitsPerPixel, rotate_pitch, + drmmode_crtc->rotate_bo->handle, + &drmmode_crtc->rotate_fb_id); + if (ret) + ErrorF("failed to add rotate fb\n"); + + return drmmode_crtc->rotate_bo->virtual; +#endif + return NULL; +} + +static PixmapPtr +drmmode_crtc_shadow_create(xf86CrtcPtr crtc, void *data, int width, int height) +{ + ScrnInfoPtr pScrn = crtc->scrn; + drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; + drmmode_ptr drmmode = drmmode_crtc->drmmode; + unsigned long rotate_pitch; + PixmapPtr rotate_pixmap; + + if (!data) + data = drmmode_crtc_shadow_allocate (crtc, width, height); + + rotate_pitch = pScrn->displayWidth * drmmode->cpp; + + rotate_pixmap = GetScratchPixmapHeader(pScrn->pScreen, + width, height, + pScrn->depth, + pScrn->bitsPerPixel, + rotate_pitch, + data); + + if (rotate_pixmap == NULL) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Couldn't allocate shadow pixmap for rotated CRTC\n"); + } + return rotate_pixmap; + +} + +static void +drmmode_crtc_shadow_destroy(xf86CrtcPtr crtc, PixmapPtr rotate_pixmap, void *data) +{ + drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; + + if (rotate_pixmap) + FreeScratchPixmapHeader(rotate_pixmap); + + if (data) { +#if 0 + /* Be sure to sync acceleration before the memory gets unbound. */ + drmModeRmFB(drmmode->fd, drmmode_crtc->rotate_fb_id); + drmmode_crtc->rotate_fb_id = 0; + dri_bo_unreference(drmmode_crtc->rotate_bo); + drmmode_crtc->rotate_bo = NULL; +#endif + } + +} + +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, + + .shadow_create = drmmode_crtc_shadow_create, + .shadow_allocate = drmmode_crtc_shadow_allocate, + .shadow_destroy = drmmode_crtc_shadow_destroy, +#if 0 + .gamma_set = i830_crtc_gamma_set, + .shadow_create = i830_crtc_shadow_create, + .shadow_allocate = i830_crtc_shadow_allocate, + .shadow_destroy = i830_crtc_shadow_destroy, + .set_cursor_colors = i830_crtc_set_cursor_colors, +#endif + .destroy = NULL, /* XXX */ +}; + + +static void +drmmode_crtc_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int num) +{ + xf86CrtcPtr crtc; + drmmode_crtc_private_ptr drmmode_crtc; + I830Ptr pI830 = I830PTR(pScrn); + int ret; + + 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; + 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; + + /* 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)) + continue; + + if (!strcmp(props->name, "EDID") && 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, +#if 0 + + .save = drmmode_crt_save, + .restore = drmmode_crt_restore, + .mode_fixup = drmmode_crt_mode_fixup, + .prepare = drmmode_output_prepare, + .mode_set = drmmode_crt_mode_set, + .commit = drmmode_output_commit, +#endif + .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 }; + +const char *output_names[] = { "None", + "VGA", + "DVI", + "DVI", + "DVI", + "Composite" + "TV", + "LVDS", + "CTV", + "DIN", + "DP", + "HDMI", + "HDMI", +}; + + +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], + koutput->connector_type_id); + + 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->possible_crtcs; + output->possible_clones = kencoder->possible_clones; + return; +} + +Bool drmmode_pre_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, char *busId, + char *driver_name, int cpp) +{ + xf86CrtcConfigPtr xf86_config; + int i; + Bool ret; + + /* Create a bus Id */ + /* Low level DRM open */ + ret = DRIOpenDRMMaster(pScrn, SAREA_MAX, busId, driver_name); + if (!ret) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "[dri] DRIGetVersion failed to open the DRM\n" + "[dri] Disabling DRI.\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); + + xf86InitialConfiguration(pScrn, FALSE); + + return TRUE; +} + +#if 0 +Bool drmmode_set_bufmgr(ScrnInfoPtr pScrn, drmmode_ptr drmmode, + dri_bufmgr *bufmgr) +{ + drmmode->bufmgr = bufmgr; + return TRUE; +} +#endif + +void drmmode_set_fb(ScrnInfoPtr scrn, drmmode_ptr drmmode, int width, + int height, int pitch, dri_bo *bo) +{ + int ret; + + ret = drmModeAddFB(drmmode->fd, width, height, scrn->depth, + scrn->bitsPerPixel, pitch, bo->handle, + &drmmode->fb_id); + + if (ret) { + ErrorF("Failed to add fb: %s\n", strerror(-ret)); + } + + 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); +} + +Bool drmmode_is_rotate_pixmap(ScrnInfoPtr pScrn, pointer pPixData, dri_bo **bo) +{ + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR (pScrn); + int i; + + return FALSE; + +#if 0 + for (i = 0; i < config->num_crtc; i++) { + xf86CrtcPtr crtc = config->crtc[i]; + drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; + + if (!drmmode_crtc->rotate_bo) + continue; + + if (drmmode_crtc->rotate_bo->virtual == pPixData) { + *bo = drmmode_crtc->rotate_bo; + return TRUE; + } + } + return FALSE; +#endif +} + +static Bool drmmode_resize_fb(ScrnInfoPtr scrn, drmmode_ptr drmmode, int width, + int height) +{ + uint32_t handle; + int pitch; + int ret; + + return FALSE; + + 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; + + ret = drmModeReplaceFB(drmmode->fd, drmmode->fb_id, + width, height, + scrn->depth, scrn->bitsPerPixel, 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; +} + +#endif + diff --git a/src/drmmode_display.h b/src/drmmode_display.h new file mode 100644 index 00000000..fc7c1df1 --- /dev/null +++ b/src/drmmode_display.h @@ -0,0 +1,73 @@ +/* + * Copyright © 2007 Red Hat, Inc. + * + * 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 "dri_bufmgr.h" +#include "xf86drmMode.h" + +typedef struct { + int fd; + uint32_t 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 { + + drmmode_ptr drmmode; + drmModeCrtcPtr mode_crtc; + dri_bo *cursor; + dri_bo *rotate_bo; + int rotate_fb_id; +} 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; + + +extern Bool drmmode_pre_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, + char *busId, char *driver_name, int cpp); +extern void drmmode_set_fb(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int width, + int height, int pitch, dri_bo *bo); +extern Bool drmmode_is_rotate_pixmap(ScrnInfoPtr pScrn, pointer pPixData, + dri_bo **bo); +extern void drmmode_set_cursor(ScrnInfoPtr scrn, drmmode_ptr drmmode, int id, + void *ptr, uint32_t handle); +#endif /* XF86DRM_MODE */ + +#endif /* DRMMODE_DISPLAY_H */ @@ -77,6 +77,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #ifdef DAMAGE #include "damage.h" #endif +#include "drmmode_display.h" #endif #include "dri_bufmgr.h" #include "intel_bufmgr.h" @@ -91,11 +92,14 @@ unsigned long long I830TexOffsetStart(PixmapPtr pPix); #ifdef I830_USE_UXA #include "uxa.h" Bool i830_uxa_init(ScreenPtr pScreen); -dri_bo *i830_uxa_get_pixmap_bo (PixmapPtr pixmap); void i830_uxa_create_screen_resources(ScreenPtr pScreen); void i830_uxa_block_handler (ScreenPtr pScreen); #endif +#if defined(I830_USE_UXA) || defined(I830_USE_EXA) +dri_bo *i830_get_pixmap_bo (PixmapPtr pixmap); +#endif + #ifdef I830_USE_XAA Bool I830XAAInit(ScreenPtr pScreen); #endif @@ -702,6 +706,12 @@ typedef struct _I830Rec { enum last_3d *last_3d; + Bool use_drm_mode; +#ifdef XF86DRM_MODE + drmmode_rec drmmode; + int drm_mm_init; +#endif + /** Enables logging of debug output related to mode switching. */ Bool debug_modes; unsigned int quirk_flag; @@ -719,6 +729,10 @@ typedef struct _I830Rec { unsigned long intel_get_pixmap_offset(PixmapPtr pPix); unsigned long intel_get_pixmap_pitch(PixmapPtr pPix); +struct i830_exa_pixmap_priv { + dri_bo *bo; +}; + /* Batchbuffer support macros and functions */ #include "i830_batchbuffer.h" @@ -832,7 +846,9 @@ void i830_init_bufmgr(ScrnInfoPtr pScrn); Bool i830_allocate_xvmc_buffer(ScrnInfoPtr pScrn, const char *name, i830_memory **buffer, unsigned long size, int flags); #endif - +extern void i830_update_front_offset(ScrnInfoPtr pScrn); +extern uint32_t i830_create_new_fb(ScrnInfoPtr pScrn, int width, int height, + int *pitch); extern Bool I830IsPrimary(ScrnInfoPtr pScrn); extern Bool I830I2CInit(ScrnInfoPtr pScrn, I2CBusPtr *bus_ptr, int i2c_reg, diff --git a/src/i830_accel.c b/src/i830_accel.c index a3018187..386e653f 100644 --- a/src/i830_accel.c +++ b/src/i830_accel.c @@ -220,7 +220,7 @@ I830Sync(ScrnInfoPtr pScrn) if (!pI830->memory_manager) i830_refresh_ring(pScrn); - } else { + } else if (!pI830->use_drm_mode) { i830_wait_ring_idle(pScrn); } diff --git a/src/i830_batchbuffer.h b/src/i830_batchbuffer.h index 4c1198d6..2a23cae3 100644 --- a/src/i830_batchbuffer.h +++ b/src/i830_batchbuffer.h @@ -78,13 +78,13 @@ intel_batch_emit_reloc_pixmap(I830Ptr pI830, PixmapPtr pPixmap, uint32_t read_domains, uint32_t write_domain, uint32_t delta) { -#if I830_USE_UXA - dri_bo *bo = i830_uxa_get_pixmap_bo(pPixmap); +#if I830_USE_UXA || I830_USE_EXA + dri_bo *bo = i830_get_pixmap_bo(pPixmap); #endif uint32_t offset; assert(pI830->batch_ptr != NULL); assert(intel_batch_space(pI830) >= 4); -#if I830_USE_UXA +#if I830_USE_UXA || I830_USE_EXA if (bo) { intel_batch_emit_reloc(pI830, bo, read_domains, write_domain, delta); return; diff --git a/src/i830_bios.c b/src/i830_bios.c index fe55d239..ff49025d 100644 --- a/src/i830_bios.c +++ b/src/i830_bios.c @@ -180,11 +180,17 @@ i830_bios_init(ScrnInfoPtr pScrn) int vbt_off, bdb_off; unsigned char *bios; vbeInfoPtr pVbe; + pointer pVBEModule = NULL; bios = xalloc(INTEL_VBIOS_SIZE); if (bios == NULL) return -1; + /* Load vbe module */ + if (!(pVBEModule = xf86LoadSubModule(pScrn, "vbe"))) + return FALSE; + xf86LoaderReqSymLists(I810vbeSymbols, NULL); + pVbe = VBEInit(NULL, pI830->pEnt->index); if (pVbe != NULL) { memcpy(bios, xf86int10Addr(pVbe->pInt10, diff --git a/src/i830_dri.c b/src/i830_dri.c index d40ada56..ca3bc621 100644 --- a/src/i830_dri.c +++ b/src/i830_dri.c @@ -159,7 +159,7 @@ I830InitDma(ScrnInfoPtr pScrn) info.func = I830_INIT_DMA; /* Initialize fields that are used in the absence of GEM */ - if (!pI830->memory_manager) { + if (!pI830->memory_manager && !pI830->use_drm_mode) { info.ring_start = ring->mem->offset + pI830->LinearAddr; info.ring_end = ring->mem->end + pI830->LinearAddr; info.ring_size = ring->mem->size; @@ -766,20 +766,22 @@ I830InitTextureHeap(ScrnInfoPtr pScrn) } } -/** - * Sets up mappings for static, lifetime-fixed allocations, and inital SAREA - * setup. +/* + * Map registers & ring buffer */ -Bool -I830DRIDoMappings(ScreenPtr pScreen) +static Bool +I830DRIMapHW(ScreenPtr pScreen) { ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; I830Ptr pI830 = I830PTR(pScrn); DRIInfoPtr pDRIInfo = pI830->pDRIInfo; I830DRIPtr pI830DRI = pDRIInfo->devPrivate; - drmI830Sarea *sarea = (drmI830Sarea *) DRIGetSAREAPrivate(pScreen); - DPRINTF(PFX, "I830DRIDoMappings\n"); + /* Kernel deals with direct hw access in this case */ + if (pI830->use_drm_mode) + return TRUE; + + DPRINTF(PFX, "I830DRIMapHW\n"); pI830DRI->regsSize = I830_REG_SIZE; if (drmAddMap(pI830->drmSubFD, (drm_handle_t)pI830->MMIOAddr, pI830DRI->regsSize, DRM_REGISTERS, 0, @@ -806,6 +808,27 @@ I830DRIDoMappings(ScreenPtr pScreen) (int)pI830->ring_map); } + return TRUE; +} + +/** + * Sets up mappings for static, lifetime-fixed allocations, and inital SAREA + * setup. + */ +Bool +I830DRIDoMappings(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + I830Ptr pI830 = I830PTR(pScrn); + DRIInfoPtr pDRIInfo = pI830->pDRIInfo; + I830DRIPtr pI830DRI = pDRIInfo->devPrivate; + drmI830Sarea *sarea = (drmI830Sarea *) DRIGetSAREAPrivate(pScreen); + + if (!I830DRIMapHW(pScreen)) { + DRICloseScreen(pScreen); + return FALSE; + } + if (!I830InitDma(pScrn)) { DRICloseScreen(pScreen); return FALSE; diff --git a/src/i830_driver.c b/src/i830_driver.c index 79c2078f..2ce8942c 100644 --- a/src/i830_driver.c +++ b/src/i830_driver.c @@ -177,6 +177,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "xf86_OSproc.h" #include "xf86Resources.h" #include "xf86RAC.h" +#include "xf86Priv.h" #include "xf86cmap.h" #include "compiler.h" #include "mibstore.h" @@ -426,17 +427,6 @@ I830FreeRec(ScrnInfoPtr pScrn) pScrn->driverPrivate = NULL; } -static void -I830ProbeDDC(ScrnInfoPtr pScrn, int index) -{ - vbeInfoPtr pVbe; - - /* The vbe module gets loaded in PreInit(), so no need to load it here. */ - - pVbe = VBEInit(NULL, index); - ConfiguredMonitor = vbeDoEDID(pVbe, NULL); -} - static int I830DetectMemory(ScrnInfoPtr pScrn) { @@ -835,11 +825,12 @@ I830LoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices, } } -static void +void i830_update_front_offset(ScrnInfoPtr pScrn) { ScreenPtr pScreen = pScrn->pScreen; I830Ptr pI830 = I830PTR(pScrn); + int pitch = pScrn->displayWidth * pI830->cpp; /* Update buffer locations, which may have changed as a result of * i830_bind_all_memory(). @@ -851,9 +842,9 @@ i830_update_front_offset(ScrnInfoPtr pScrn) */ if (!pI830->starting && pI830->accel != ACCEL_UXA) { if (!pScreen->ModifyPixmapHeader(pScreen->GetScreenPixmap(pScreen), - -1, -1, -1, -1, -1, - (pointer)(pI830->FbBase + - pScrn->fbOffset))) + pScrn->virtualX, pScrn->virtualY, -1, -1, + pitch, (pointer)(pI830->FbBase + + pScrn->fbOffset))) FatalError("Couldn't adjust screen pixmap\n"); } } @@ -1116,6 +1107,10 @@ i830SetHotkeyControl(ScrnInfoPtr pScrn, int mode) I830Ptr pI830 = I830PTR(pScrn); uint8_t gr18; + /* Don't mess with kernel settings... */ + if (pI830->use_drm_mode) + return; + gr18 = pI830->readControl(pI830, GRX, 0x18); if (mode == HOTKEY_BIOS_SWITCH) gr18 &= ~HOTKEY_VBIOS_SWITCH_BLOCK; @@ -1124,6 +1119,45 @@ i830SetHotkeyControl(ScrnInfoPtr pScrn, int mode) pI830->writeControl(pI830, GRX, 0x18, gr18); } +#ifdef XF86DRM_MODE +/* + * DRM mode setting Linux only at this point... later on we could + * add a wrapper here. + */ +#include <linux/kd.h> + +static Bool i830_kernel_mode_enabled(ScrnInfoPtr pScrn) +{ +#if XSERVER_LIBPCIACCESS + struct pci_device *PciInfo; +#else + pciVideoPtr PciInfo; +#endif + EntityInfoPtr pEnt; + char *busIdString; + int ret; + + pEnt = xf86GetEntityInfo(pScrn->entityList[0]); + PciInfo = xf86GetPciInfoForEntity(pEnt->index); + + if (!xf86LoaderCheckSymbol("DRICreatePCIBusID")) + return FALSE; + + busIdString = DRICreatePCIBusID(PciInfo); + + ret = drmCheckModesettingSupported(busIdString); + xfree(busIdString); + if (ret) + return FALSE; + + ioctl(xf86Info.consoleFd, KDSETMODE, KD_TEXT); + + return TRUE; +} +#else +#define i830_kernel_mode_enabled(x) FALSE +#endif + static Bool i830_detect_chipset(ScrnInfoPtr pScrn) { @@ -1133,6 +1167,11 @@ i830_detect_chipset(ScrnInfoPtr pScrn) uint32_t capid; int fb_bar, mmio_bar; + + /* We have to use PIO to probe, because we haven't mapped yet. */ + if (!pI830->use_drm_mode) + I830SetPIOAccess(pI830); + switch (DEVICE_ID(pI830->PciInfo)) { case PCI_CHIP_I830_M: chipname = "830M"; @@ -1260,6 +1299,19 @@ i830_detect_chipset(ScrnInfoPtr pScrn) xf86DrvMsg(pScrn->scrnIndex, from, "Chipset: \"%s\"\n", (pScrn->chipset != NULL) ? pScrn->chipset : "Unknown i8xx"); + /* Check if the HW cursor needs physical address. */ + if (IS_MOBILE(pI830) || IS_I9XX(pI830)) + pI830->CursorNeedsPhysical = TRUE; + else + pI830->CursorNeedsPhysical = FALSE; + + if (IS_I965G(pI830) || IS_G33CLASS(pI830)) + pI830->CursorNeedsPhysical = FALSE; + + /* Skip the rest if the kernel is taking care of things */ + if (pI830->use_drm_mode) + return TRUE; + /* Now that we know the chipset, figure out the resource base addrs */ if (IS_I9XX(pI830)) { fb_bar = 2; @@ -1347,6 +1399,354 @@ static const char *accel_name[] = "UXA", }; +static Bool +I830LoadSyms(ScrnInfoPtr pScrn) +{ + I830Ptr pI830 = I830PTR(pScrn); + + if (pI830->use_drm_mode) + return TRUE; + + /* Load int10 module */ + if (!xf86LoadSubModule(pScrn, "int10")) + return FALSE; + xf86LoaderReqSymLists(I810int10Symbols, NULL); + + /* The vgahw module should be loaded here when needed */ + if (!xf86LoadSubModule(pScrn, "vgahw")) + return FALSE; + xf86LoaderReqSymLists(I810vgahwSymbols, NULL); + + return TRUE; +} + +static Bool +I830GetEarlyOptions(ScrnInfoPtr pScrn) +{ + I830Ptr pI830 = I830PTR(pScrn); + + /* Process the options */ + xf86CollectOptions(pScrn, NULL); + if (!(pI830->Options = xalloc(sizeof(I830Options)))) + return FALSE; + memcpy(pI830->Options, I830Options, sizeof(I830Options)); + xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, pI830->Options); + + if (xf86ReturnOptValBool(pI830->Options, OPTION_MODEDEBUG, FALSE)) { + pI830->debug_modes = TRUE; + } else { + pI830->debug_modes = FALSE; + } + + if (xf86ReturnOptValBool(pI830->Options, OPTION_LVDS24BITMODE, FALSE)) { + pI830->lvds_24_bit_mode = TRUE; + } else { + pI830->lvds_24_bit_mode = FALSE; + } + + if (xf86ReturnOptValBool(pI830->Options, OPTION_LVDSFIXEDMODE, TRUE)) { + pI830->skip_panel_detect = FALSE; + } else { + pI830->skip_panel_detect = TRUE; + } + + if (xf86ReturnOptValBool(pI830->Options, OPTION_FORCEENABLEPIPEA, FALSE)) + pI830->quirk_flag |= QUIRK_PIPEA_FORCE; + + return TRUE; +} + +static void +I830PreInitCrtcConfig(ScrnInfoPtr pScrn) +{ + xf86CrtcConfigPtr xf86_config; + I830Ptr pI830 = I830PTR(pScrn); + int max_width, max_height; + + if (pI830->use_drm_mode) + return; + + /* check quirks */ + i830_fixup_devices(pScrn); + + /* Allocate an xf86CrtcConfig */ + xf86CrtcConfigInit (pScrn, &i830_xf86crtc_config_funcs); + xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); + + /* See i830_exa.c comments for why we limit the framebuffer size like this. + */ + if (IS_I965G(pI830)) { + max_width = 8192; + max_height = 8192; + } else { + max_width = 2048; + max_height = 2048; + } + xf86CrtcSetSizeRange (pScrn, 320, 200, max_width, max_height); +} + +static Bool +I830AccelMethodInit(ScrnInfoPtr pScrn) +{ + I830Ptr pI830 = I830PTR(pScrn); + MessageType from = X_PROBED; + char *s; + int i, num_pipe; + + if (xf86ReturnOptValBool(pI830->Options, OPTION_NOACCEL, FALSE)) { + pI830->accel = ACCEL_NONE; + } + + /* + * The ugliness below: + * If either XAA or EXA (exclusive) is compiled in, default to it. + * + * If both are compiled in, and the user didn't specify noAccel, use the + * config option AccelMethod to determine which to use, defaulting to EXA + * if none is specified, or if the string was unrecognized. + * + * All this *could* go away if we removed XAA support from this driver, + * for example. :) + */ + if (!(pI830->accel == ACCEL_NONE)) { +#ifdef I830_USE_UXA + pI830->accel = ACCEL_UXA; +#endif +#ifdef I830_USE_EXA + pI830->accel = ACCEL_EXA; +#endif +#if I830_USE_XAA + I830_USE_EXA + I830_USE_UXA >= 2 + from = X_DEFAULT; + if ((s = (char *)xf86GetOptValString(pI830->Options, + OPTION_ACCELMETHOD))) { + if (!xf86NameCmp(s, "EXA")) { + from = X_CONFIG; + pI830->accel = ACCEL_EXA; + } + else if (!xf86NameCmp(s, "XAA")) { + from = X_CONFIG; + pI830->accel = ACCEL_XAA; + } + else if (!xf86NameCmp(s, "UXA")) { + from = X_CONFIG; + pI830->accel = ACCEL_UXA; + } + } +#endif + xf86DrvMsg(pScrn->scrnIndex, from, "Using %s for acceleration\n", + accel_name[pI830->accel]); + } + + if (xf86ReturnOptValBool(pI830->Options, OPTION_SW_CURSOR, FALSE)) { + pI830->SWCursor = TRUE; + } + + pI830->directRenderingDisabled = + !xf86ReturnOptValBool(pI830->Options, OPTION_DRI, TRUE); + +#ifdef XF86DRI + if (!pI830->directRenderingDisabled) { + if ((pI830->accel == ACCEL_NONE) || pI830->SWCursor) { + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "DRI is disabled because it " + "needs HW cursor and 2D acceleration.\n"); + pI830->directRenderingDisabled = TRUE; + } else if (pScrn->depth != 16 && pScrn->depth != 24) { + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "DRI is disabled because it " + "runs only at depths 16 and 24.\n"); + pI830->directRenderingDisabled = TRUE; + } + + if (!pI830->directRenderingDisabled) { + pI830->allocate_classic_textures = TRUE; + + from = X_PROBED; + +#ifdef XF86DRI_MM + if (!IS_I965G(pI830)) { + Bool tmp; + + if (xf86GetOptValBool(pI830->Options, + OPTION_INTELTEXPOOL, &tmp)) { + from = X_CONFIG; + if (!tmp) + pI830->allocate_classic_textures = FALSE; + } + } +#endif /* XF86DRI_MM */ + } + } +#endif /* XF86DRI */ + + I830MapMMIO(pScrn); + + if (pI830->debug_modes) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Hardware state on X startup:\n"); + i830DumpRegs (pScrn); + } + + i830TakeRegSnapshot(pScrn); + + if (DEVICE_ID(pI830->PciInfo) == PCI_CHIP_E7221_G) + num_pipe = 1; + else + if (IS_MOBILE(pI830) || IS_I9XX(pI830)) + num_pipe = 2; + else + num_pipe = 1; + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "%d display pipe%s available.\n", + num_pipe, num_pipe > 1 ? "s" : ""); + + I830PreInitDDC(pScrn); + for (i = 0; i < num_pipe; i++) { + i830_crtc_init(pScrn, i); + } + I830SetupOutputs(pScrn); + + SaveHWState(pScrn); + if (!xf86InitialConfiguration (pScrn, FALSE)) + { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes.\n"); + RestoreHWState(pScrn); + PreInitCleanup(pScrn); + return FALSE; + } + RestoreHWState(pScrn); + + /* XXX This should go away, replaced by xf86Crtc.c support for it */ + pI830->rotation = RR_Rotate_0; + + /* + * Let's setup the mobile systems to check the lid status + */ + if (IS_MOBILE(pI830)) { + pI830->checkDevices = TRUE; + + if (!xf86ReturnOptValBool(pI830->Options, OPTION_CHECKDEVICES, TRUE)) { + pI830->checkDevices = FALSE; + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Monitoring connected displays disabled\n"); + } else + if (pI830->entityPrivate && !I830IsPrimary(pScrn) && + !I830PTR(pI830->entityPrivate->pScrn_1)->checkDevices) { + /* If checklid is off, on the primary head, then + * turn it off on the secondary*/ + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Monitoring connected displays disabled\n"); + pI830->checkDevices = FALSE; + } else + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Monitoring connected displays enabled\n"); + } else + pI830->checkDevices = FALSE; + + pI830->stolen_size = I830DetectMemory(pScrn); + + return TRUE; +} + +static Bool +I830DrmModeInit(ScrnInfoPtr pScrn) +{ +#ifdef XF86DRM_MODE + I830Ptr pI830 = I830PTR(pScrn); + char *bus_id; + char *s; + + /* Default to EXA but allow override */ + pI830->accel = ACCEL_EXA; + + if ((s = (char *)xf86GetOptValString(pI830->Options, OPTION_ACCELMETHOD))) { + if (!xf86NameCmp(s, "EXA")) + pI830->accel = ACCEL_EXA; + else if (!xf86NameCmp(s, "UXA")) + pI830->accel = ACCEL_UXA; + else + pI830->accel = ACCEL_EXA; + } + + bus_id = DRICreatePCIBusID(pI830->PciInfo); + if (drmmode_pre_init(pScrn, &pI830->drmmode, bus_id, "i915", + pI830->cpp) == FALSE) { + xfree(bus_id); + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Kernel modesetting setup failed\n"); + PreInitCleanup(pScrn); + return FALSE; + } + + pI830->drmmode.create_new_fb = i830_create_new_fb; + + pI830->drmSubFD = pI830->drmmode.fd; + xfree(bus_id); + + pI830->directRenderingDisabled = FALSE; + pI830->allocate_classic_textures = FALSE; + + i830_init_bufmgr(pScrn); +#endif + + return TRUE; +} + +static void +I830XvInit(ScrnInfoPtr pScrn) +{ + I830Ptr pI830 = I830PTR(pScrn); + MessageType from = X_PROBED; + + pI830->XvDisabled = + !xf86ReturnOptValBool(pI830->Options, OPTION_XVIDEO, TRUE); + +#ifdef I830_XV + if (xf86GetOptValInteger(pI830->Options, OPTION_VIDEO_KEY, + &(pI830->colorKey))) { + from = X_CONFIG; + } else if (xf86GetOptValInteger(pI830->Options, OPTION_COLOR_KEY, + &(pI830->colorKey))) { + from = X_CONFIG; + } else { + pI830->colorKey = + (1 << pScrn->offset.red) | (1 << pScrn->offset.green) | + (((pScrn->mask.blue >> pScrn->offset.blue) - 1) << + pScrn->offset.blue); + from = X_DEFAULT; + } + xf86DrvMsg(pScrn->scrnIndex, from, "video overlay key set to 0x%x\n", + pI830->colorKey); +#endif +#ifdef INTEL_XVMC + pI830->XvMCEnabled = FALSE; + from = (!pI830->directRenderingDisabled && + xf86GetOptValBool(pI830->Options, OPTION_XVMC, + &pI830->XvMCEnabled)) ? X_CONFIG : X_DEFAULT; + xf86DrvMsg(pScrn->scrnIndex, from, "Intel XvMC decoder %sabled\n", + pI830->XvMCEnabled ? "en" : "dis"); +#endif +} + +static void +I830DriOptsInit(ScrnInfoPtr pScrn) +{ +#ifdef XF86DRI + I830Ptr pI830 = I830PTR(pScrn); + MessageType from = X_PROBED; + + pI830->allowPageFlip = FALSE; + from = (!pI830->directRenderingDisabled && + xf86GetOptValBool(pI830->Options, OPTION_PAGEFLIP, + &pI830->allowPageFlip)) ? X_CONFIG : X_DEFAULT; + + xf86DrvMsg(pScrn->scrnIndex, from, "Will%s try to enable page flipping\n", + pI830->allowPageFlip ? "" : " not"); + + pI830->TripleBuffer = FALSE; + from = (!pI830->directRenderingDisabled && + xf86GetOptValBool(pI830->Options, OPTION_TRIPLEBUFFER, + &pI830->TripleBuffer)) ? X_CONFIG : X_DEFAULT; + + xf86DrvMsg(pScrn->scrnIndex, from, "Triple buffering %sabled\n", + pI830->TripleBuffer ? "en" : "dis"); +#endif /* XF86DRI */ +} + /** * This is called per zaphod head (so usually just once) to do initialization * before the Screen is created. @@ -1357,48 +1757,24 @@ static const char *accel_name[] = static Bool I830PreInit(ScrnInfoPtr pScrn, int flags) { - xf86CrtcConfigPtr xf86_config; vgaHWPtr hwp; I830Ptr pI830; - MessageType from = X_PROBED; rgb defaultWeight = { 0, 0, 0 }; EntityInfoPtr pEnt; - I830EntPtr pI830Ent = NULL; + I830EntPtr pI830Ent = NULL; int flags24; - int i; - char *s; - pointer pVBEModule = NULL; - int num_pipe; - int max_width, max_height; + Gamma zeros = { 0.0, 0.0, 0.0 }; + int drm_mode_setting; if (pScrn->numEntities != 1) return FALSE; - /* Load int10 module */ - if (!xf86LoadSubModule(pScrn, "int10")) - return FALSE; - xf86LoaderReqSymLists(I810int10Symbols, NULL); - - /* Load vbe module */ - if (!(pVBEModule = xf86LoadSubModule(pScrn, "vbe"))) - return FALSE; - xf86LoaderReqSymLists(I810vbeSymbols, NULL); + drm_mode_setting = i830_kernel_mode_enabled(pScrn); pEnt = xf86GetEntityInfo(pScrn->entityList[0]); - if (flags & PROBE_DETECT) { - I830ProbeDDC(pScrn, pEnt->index); - return TRUE; - } - - /* The vgahw module should be loaded here when needed */ - if (!xf86LoadSubModule(pScrn, "vgahw")) - return FALSE; - xf86LoaderReqSymLists(I810vgahwSymbols, NULL); - - /* Allocate a vgaHWRec */ - if (!vgaHWGetHWRec(pScrn)) - return FALSE; + if (flags & PROBE_DETECT) + return TRUE; /* Allocate driverPrivate */ if (!I830GetRec(pScrn)) @@ -1407,6 +1783,17 @@ I830PreInit(ScrnInfoPtr pScrn, int flags) pI830 = I830PTR(pScrn); pI830->SaveGeneration = -1; pI830->pEnt = pEnt; + pI830->use_drm_mode = drm_mode_setting; + + if (!I830LoadSyms(pScrn)) + return FALSE; + + if (!drm_mode_setting) { + /* Allocate a vgaHWRec */ + if (!vgaHWGetHWRec(pScrn)) + return FALSE; + hwp = VGAHWPTR(pScrn); + } pScrn->displayWidth = 640; /* default it */ @@ -1424,7 +1811,7 @@ I830PreInit(ScrnInfoPtr pScrn, int flags) pI830Ent = xf86GetEntityPrivate(pScrn->entityList[0], I830EntityIndex)->ptr; pI830->entityPrivate = pI830Ent; - } else + } else pI830->entityPrivate = NULL; if (xf86RegisterResources(pI830->pEnt->index, NULL, ResNone)) { @@ -1485,289 +1872,41 @@ I830PreInit(ScrnInfoPtr pScrn, int flags) if (!xf86SetDefaultVisual(pScrn, -1)) return FALSE; - hwp = VGAHWPTR(pScrn); + if (!pI830->use_drm_mode) + hwp = VGAHWPTR(pScrn); + pI830->cpp = pScrn->bitsPerPixel / 8; pI830->preinit = TRUE; - /* Process the options */ - xf86CollectOptions(pScrn, NULL); - if (!(pI830->Options = xalloc(sizeof(I830Options)))) - return FALSE; - memcpy(pI830->Options, I830Options, sizeof(I830Options)); - xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, pI830->Options); - - if (xf86ReturnOptValBool(pI830->Options, OPTION_MODEDEBUG, FALSE)) { - pI830->debug_modes = TRUE; - } else { - pI830->debug_modes = FALSE; - } - - if (xf86ReturnOptValBool(pI830->Options, OPTION_LVDS24BITMODE, FALSE)) { - pI830->lvds_24_bit_mode = TRUE; - } else { - pI830->lvds_24_bit_mode = FALSE; - } - - if (xf86ReturnOptValBool(pI830->Options, OPTION_LVDSFIXEDMODE, TRUE)) { - pI830->skip_panel_detect = FALSE; - } else { - pI830->skip_panel_detect = TRUE; - } - - if (xf86ReturnOptValBool(pI830->Options, OPTION_FORCEENABLEPIPEA, FALSE)) - pI830->quirk_flag |= QUIRK_PIPEA_FORCE; - - /* We have to use PIO to probe, because we haven't mapped yet. */ - I830SetPIOAccess(pI830); + if (!I830GetEarlyOptions(pScrn)) + return FALSE; if (!i830_detect_chipset(pScrn)) return FALSE; - /* check quirks */ - i830_fixup_devices(pScrn); + I830PreInitCrtcConfig(pScrn); - /* Allocate an xf86CrtcConfig */ - xf86CrtcConfigInit (pScrn, &i830_xf86crtc_config_funcs); - xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); - - /* See i830_exa.c comments for why we limit the framebuffer size like this. - */ - if (IS_I965G(pI830)) { - max_width = 8192; - max_height = 8192; + if (pI830->use_drm_mode) { + if (!I830DrmModeInit(pScrn)) + return FALSE; } else { - max_width = 2048; - max_height = 2048; - } - xf86CrtcSetSizeRange (pScrn, 320, 200, max_width, max_height); - - /* Some of the probing needs MMIO access, so map it here. */ - I830MapMMIO(pScrn); - - if (pI830->debug_modes) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Hardware state on X startup:\n"); - i830DumpRegs (pScrn); + if (!I830AccelMethodInit(pScrn)) + return FALSE; } - i830TakeRegSnapshot(pScrn); - - if (DEVICE_ID(pI830->PciInfo) == PCI_CHIP_E7221_G) - num_pipe = 1; - else - if (IS_MOBILE(pI830) || IS_I9XX(pI830)) - num_pipe = 2; - else - num_pipe = 1; - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "%d display pipe%s available.\n", - num_pipe, num_pipe > 1 ? "s" : ""); - - if (xf86ReturnOptValBool(pI830->Options, OPTION_NOACCEL, FALSE)) { - pI830->accel = ACCEL_NONE; - } + I830XvInit(pScrn); - /* - * The ugliness below: - * If either XAA or EXA (exclusive) is compiled in, default to it. - * - * If both are compiled in, and the user didn't specify noAccel, use the - * config option AccelMethod to determine which to use, defaulting to EXA - * if none is specified, or if the string was unrecognized. - * - * All this *could* go away if we removed XAA support from this driver, - * for example. :) - */ - if (pI830->accel == ACCEL_UNINIT) { - pI830->accel = ACCEL_NONE; -#ifdef I830_USE_XAA - pI830->accel = ACCEL_XAA; -#endif -#ifdef I830_USE_UXA - pI830->accel = ACCEL_UXA; -#endif -#ifdef I830_USE_EXA - pI830->accel = ACCEL_EXA; -#endif -#if I830_USE_XAA + I830_USE_EXA + I830_USE_UXA >= 2 - from = X_DEFAULT; - if ((s = (char *)xf86GetOptValString(pI830->Options, - OPTION_ACCELMETHOD))) { - if (!xf86NameCmp(s, "EXA")) { - from = X_CONFIG; - pI830->accel = ACCEL_EXA; - } - else if (!xf86NameCmp(s, "XAA")) { - from = X_CONFIG; - pI830->accel = ACCEL_XAA; - } - else if (!xf86NameCmp(s, "UXA")) { - from = X_CONFIG; - pI830->accel = ACCEL_UXA; - } - } -#endif - } - xf86DrvMsg(pScrn->scrnIndex, from, "Using %s acceleration\n", - accel_name[pI830->accel]); + I830DriOptsInit(pScrn); - if (xf86ReturnOptValBool(pI830->Options, OPTION_SW_CURSOR, FALSE)) { - pI830->SWCursor = TRUE; + if (!xf86SetGamma(pScrn, zeros)) { + PreInitCleanup(pScrn); + return FALSE; } - pI830->directRenderingDisabled = - !xf86ReturnOptValBool(pI830->Options, OPTION_DRI, TRUE); - -#ifdef XF86DRI - if (!pI830->directRenderingDisabled) { - if (pI830->accel == ACCEL_NONE || pI830->SWCursor) { - xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "DRI is disabled because it " - "needs HW cursor and 2D acceleration.\n"); - pI830->directRenderingDisabled = TRUE; - } else if (pScrn->depth != 16 && pScrn->depth != 24) { - xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "DRI is disabled because it " - "runs only at depths 16 and 24.\n"); - pI830->directRenderingDisabled = TRUE; - } - - if (!pI830->directRenderingDisabled) { - pI830->allocate_classic_textures = TRUE; - - from = X_PROBED; - -#ifdef XF86DRI - if (!IS_I965G(pI830)) { - Bool tmp; - - if (xf86GetOptValBool(pI830->Options, - OPTION_INTELTEXPOOL, &tmp)) { - from = X_CONFIG; - if (!tmp) - pI830->allocate_classic_textures = FALSE; - } - } -#endif - } - } - -#endif - if (i830_bios_init(pScrn)) - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "VBIOS initialization failed.\n"); - - I830PreInitDDC(pScrn); - for (i = 0; i < num_pipe; i++) { - i830_crtc_init(pScrn, i); - } - I830SetupOutputs(pScrn); - - SaveHWState(pScrn); - if (!xf86InitialConfiguration (pScrn, FALSE)) - { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes.\n"); - RestoreHWState(pScrn); - PreInitCleanup(pScrn); - return FALSE; - } - RestoreHWState(pScrn); - - /* XXX This should go away, replaced by xf86Crtc.c support for it */ - pI830->rotation = RR_Rotate_0; - - /* - * Let's setup the mobile systems to check the lid status - */ - if (IS_MOBILE(pI830)) { - pI830->checkDevices = TRUE; - - if (!xf86ReturnOptValBool(pI830->Options, OPTION_CHECKDEVICES, TRUE)) { - pI830->checkDevices = FALSE; - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Monitoring connected displays disabled\n"); - } else - if (pI830->entityPrivate && !I830IsPrimary(pScrn) && - !I830PTR(pI830->entityPrivate->pScrn_1)->checkDevices) { - /* If checklid is off, on the primary head, then - * turn it off on the secondary*/ - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Monitoring connected displays disabled\n"); - pI830->checkDevices = FALSE; - } else - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Monitoring connected displays enabled\n"); - } else - pI830->checkDevices = FALSE; - - pI830->stolen_size = I830DetectMemory(pScrn); - - pI830->XvDisabled = - !xf86ReturnOptValBool(pI830->Options, OPTION_XVIDEO, TRUE); - -#ifdef I830_XV - if (xf86GetOptValInteger(pI830->Options, OPTION_VIDEO_KEY, - &(pI830->colorKey))) { - from = X_CONFIG; - } else if (xf86GetOptValInteger(pI830->Options, OPTION_COLOR_KEY, - &(pI830->colorKey))) { - from = X_CONFIG; - } else { - pI830->colorKey = (1 << pScrn->offset.red) | - (1 << pScrn->offset.green) | - (((pScrn->mask.blue >> pScrn->offset.blue) - 1) << - pScrn->offset.blue); - from = X_DEFAULT; - } - xf86DrvMsg(pScrn->scrnIndex, from, "video overlay key set to 0x%x\n", - pI830->colorKey); -#endif - -#ifdef XF86DRI - pI830->allowPageFlip = FALSE; - from = (!pI830->directRenderingDisabled && - xf86GetOptValBool(pI830->Options, OPTION_PAGEFLIP, - &pI830->allowPageFlip)) ? X_CONFIG : X_DEFAULT; - - xf86DrvMsg(pScrn->scrnIndex, from, "Will%s try to enable page flipping\n", - pI830->allowPageFlip ? "" : " not"); -#endif - -#ifdef XF86DRI - pI830->TripleBuffer = FALSE; - from = (!pI830->directRenderingDisabled && - xf86GetOptValBool(pI830->Options, OPTION_TRIPLEBUFFER, - &pI830->TripleBuffer)) ? X_CONFIG : X_DEFAULT; - - xf86DrvMsg(pScrn->scrnIndex, from, "Triple buffering %sabled\n", - pI830->TripleBuffer ? "en" : "dis"); -#endif - -#ifdef INTEL_XVMC - pI830->XvMCEnabled = FALSE; - from = (!pI830->directRenderingDisabled && - xf86GetOptValBool(pI830->Options, OPTION_XVMC, - &pI830->XvMCEnabled)) ? X_CONFIG : X_DEFAULT; - xf86DrvMsg(pScrn->scrnIndex, from, "Intel XvMC decoder %sabled\n", - pI830->XvMCEnabled ? "en" : "dis"); -#endif - - /* - * If the driver can do gamma correction, it should call xf86SetGamma() here. - */ - - { - Gamma zeros = { 0.0, 0.0, 0.0 }; - - if (!xf86SetGamma(pScrn, zeros)) { - PreInitCleanup(pScrn); - return FALSE; - } - } - - /* Check if the HW cursor needs physical address. */ - if (IS_MOBILE(pI830) || IS_I9XX(pI830)) - pI830->CursorNeedsPhysical = TRUE; - else - pI830->CursorNeedsPhysical = FALSE; - - if (IS_I965G(pI830) || IS_G33CLASS(pI830)) - pI830->CursorNeedsPhysical = FALSE; + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "VBIOS initialization failed.\n"); /* * XXX If we knew the pre-initialised GTT format for certain, we could @@ -1780,8 +1919,8 @@ I830PreInit(ScrnInfoPtr pScrn, int flags) "Using HW Cursor because it's enabled on primary head.\n"); pI830->SWCursor = FALSE; } - } else - if (pI830->StolenOnly && pI830->CursorNeedsPhysical && !pI830->SWCursor) { + } else if (pI830->StolenOnly && pI830->CursorNeedsPhysical && + !pI830->SWCursor) { xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "HW Cursor disabled because it needs agpgart memory.\n"); pI830->SWCursor = TRUE; @@ -1854,21 +1993,16 @@ I830PreInit(ScrnInfoPtr pScrn, int flags) xf86LoaderReqSymLists(I810ramdacSymbols, NULL); } - i830CompareRegsToSnapshot(pScrn, "After PreInit"); - - I830UnmapMMIO(pScrn); + if (!pI830->use_drm_mode) { + i830CompareRegsToSnapshot(pScrn, "After PreInit"); - /* We won't be using the VGA access after the probe. */ - I830SetMMIOAccess(pI830); - xf86SetOperatingState(resVgaIo, pI830->pEnt->index, ResUnusedOpr); - xf86SetOperatingState(resVgaMem, pI830->pEnt->index, ResDisableOpr); + I830UnmapMMIO(pScrn); -#if 0 - if (I830IsPrimary(pScrn)) { - vbeFree(pI830->pVbe); + /* We won't be using the VGA access after the probe. */ + I830SetMMIOAccess(pI830); + xf86SetOperatingState(resVgaIo, pI830->pEnt->index, ResUnusedOpr); + xf86SetOperatingState(resVgaMem, pI830->pEnt->index, ResDisableOpr); } - pI830->pVbe = NULL; -#endif #if defined(XF86DRI) /* Load the dri module if requested. */ @@ -2541,9 +2675,6 @@ I830BlockHandler(int i, #endif pI830->need_mi_flush = FALSE; -#ifdef XF86DRI - drmCommandNone(pI830->drmSubFD, DRM_I915_GEM_THROTTLE); -#endif } if (pI830->accel == ACCEL_UXA) @@ -2555,7 +2686,7 @@ I830BlockHandler(int i, * (except for mode setting, where it may occur naturally). * Check & ack the condition. */ - if (pScrn->vtSema && !DSPARB_HWCONTROL(pI830)) { + if (!pI830->use_drm_mode && pScrn->vtSema && !DSPARB_HWCONTROL(pI830)) { if (xf86_config->crtc[0]->enabled && (INREG(PIPEASTAT) & FIFO_UNDERRUN)) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "underrun on pipe A!\n"); @@ -2793,9 +2924,10 @@ i830_init_bufmgr(ScrnInfoPtr pScrn) { I830Ptr pI830 = I830PTR(pScrn); - if (pI830->bufmgr) return; + if (pI830->bufmgr) + return; - if (pI830->memory_manager) { + if (pI830->memory_manager || pI830->use_drm_mode) { int batch_size; batch_size = 4096 * 4; @@ -2819,6 +2951,101 @@ i830_init_bufmgr(ScrnInfoPtr pScrn) } +static void +I830AdjustMemory(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn; + I830Ptr pI830; + unsigned long sys_mem; + MessageType from; + + pScrn = xf86Screens[pScreen->myNum]; + pI830 = I830PTR(pScrn); + + /* Limit videoRam to how much we might be able to allocate from AGP */ + sys_mem = I830CheckAvailableMemory(pScrn); + if (sys_mem == -1) { + if (pScrn->videoRam > pI830->stolen_size / KB(1)) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "/dev/agpgart is either not available, or no memory " + "is available\nfor allocation. " + "Using pre-allocated memory only.\n"); + pScrn->videoRam = pI830->stolen_size / KB(1); + } + pI830->StolenOnly = TRUE; + } else { + if (sys_mem + (pI830->stolen_size / 1024) < pScrn->videoRam) { + pScrn->videoRam = sys_mem + (pI830->stolen_size / 1024); + from = X_PROBED; + if (sys_mem + (pI830->stolen_size / 1024) < + pI830->pEnt->device->videoRam) + { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "VideoRAM reduced to %d kByte " + "(limited to available sysmem)\n", pScrn->videoRam); + } + } + } + + /* Limit video RAM to the actual aperture size */ + if (pScrn->videoRam > pI830->FbMapSize / 1024) { + pScrn->videoRam = pI830->FbMapSize / 1024; + if (pI830->FbMapSize / 1024 < pI830->pEnt->device->videoRam) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "VideoRam reduced to %d kByte (limited to aperture " + "size)\n", + pScrn->videoRam); + } + } + + /* Make sure it's on a page boundary */ + if (pScrn->videoRam & 3) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "VideoRam reduced to %d KB " + "(page aligned - was %d KB)\n", + pScrn->videoRam & ~3, pScrn->videoRam); + pScrn->videoRam &= ~3; + } + + if (!IS_I965G(pI830) && pScrn->displayWidth > 2048) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Cannot support DRI with frame buffer width > 2048.\n"); + pI830->directRenderingDisabled = TRUE; + } +} + +static void +I830SwapPipes(ScrnInfoPtr pScrn) +{ + I830Ptr pI830 = I830PTR(pScrn); + xf86CrtcConfigPtr config; + int c; + + config = XF86_CRTC_CONFIG_PTR(pScrn); + + /* + * If an LVDS display is present, swap the plane/pipe mappings so we can + * use FBC on the builtin display. + * Note: 965+ chips can compress either plane, so we leave the mapping + * alone in that case. + * Also make sure the DRM can handle the swap. + */ + if (I830LVDSPresent(pScrn) && !IS_I965GM(pI830) && !IS_GM45(pI830) && + (!pI830->directRenderingEnabled || + (pI830->directRenderingEnabled && pI830->drmMinor >= 10))) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "adjusting plane->pipe mappings " + "to allow for framebuffer compression\n"); + for (c = 0; c < config->num_crtc; c++) { + xf86CrtcPtr crtc = config->crtc[c]; + I830CrtcPrivatePtr intel_crtc = crtc->driver_private; + + if (intel_crtc->pipe == 0) + intel_crtc->plane = 1; + else if (intel_crtc->pipe == 1) + intel_crtc->plane = 0; + } + } +} + static Bool I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) { @@ -2827,16 +3054,13 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) I830Ptr pI830; VisualPtr visual; I830Ptr pI8301 = NULL; - unsigned long sys_mem; - int c; MessageType from; -#ifdef XF86DRI - xf86CrtcConfigPtr config; -#endif pScrn = xf86Screens[pScreen->myNum]; pI830 = I830PTR(pScrn); - hwp = VGAHWPTR(pScrn); + + if (!pI830->use_drm_mode) + hwp = VGAHWPTR(pScrn); pScrn->displayWidth = (pScrn->virtualX + 63) & ~63; @@ -2882,54 +3106,13 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) #endif } - /* Limit videoRam to how much we might be able to allocate from AGP */ - sys_mem = I830CheckAvailableMemory(pScrn); - if (sys_mem == -1) { - if (pScrn->videoRam > pI830->stolen_size / KB(1)) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "/dev/agpgart is either not available, or no memory " - "is available\nfor allocation. " - "Using pre-allocated memory only.\n"); - pScrn->videoRam = pI830->stolen_size / KB(1); - } - pI830->StolenOnly = TRUE; + if (pI830->use_drm_mode) { +#ifdef XF86DRM_MODE + pI830->stolen_size = 0; + pScrn->videoRam = ~0UL / KB(1); +#endif } else { - if (sys_mem + (pI830->stolen_size / 1024) < pScrn->videoRam) { - pScrn->videoRam = sys_mem + (pI830->stolen_size / 1024); - from = X_PROBED; - if (sys_mem + (pI830->stolen_size / 1024) < - pI830->pEnt->device->videoRam) - { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "VideoRAM reduced to %d kByte " - "(limited to available sysmem)\n", pScrn->videoRam); - } - } - } - - /* Limit video RAM to the actual aperture size */ - if (pScrn->videoRam > pI830->FbMapSize / 1024) { - pScrn->videoRam = pI830->FbMapSize / 1024; - if (pI830->FbMapSize / 1024 < pI830->pEnt->device->videoRam) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "VideoRam reduced to %d kByte (limited to aperture " - "size)\n", - pScrn->videoRam); - } - } - - /* Make sure it's on a page boundary */ - if (pScrn->videoRam & 3) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "VideoRam reduced to %d KB " - "(page aligned - was %d KB)\n", - pScrn->videoRam & ~3, pScrn->videoRam); - pScrn->videoRam &= ~3; - } - - if (!IS_I965G(pI830) && pScrn->displayWidth > 2048) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Cannot support DRI with frame buffer width > 2048.\n"); - pI830->directRenderingDisabled = TRUE; + I830AdjustMemory(pScreen); } #ifdef XF86DRI @@ -2969,6 +3152,12 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) pI830->fb_compression = FALSE; } + if (pI830->use_drm_mode && pI830->fb_compression == TRUE) { + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "Kernel mode setting active, disabling FBC.\n"); + pI830->fb_compression = FALSE; + } + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Framebuffer compression %sabled\n", pI830->fb_compression ? "en" : "dis"); xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Tiling %sabled\n", pI830->tiling ? @@ -3010,7 +3199,8 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) /* Need MMIO mapped to do GTT lookups during memory allocation. */ - I830MapMMIO(pScrn); + if (!pI830->use_drm_mode) + I830MapMMIO(pScrn); if (!i830_memory_init(pScrn)) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, @@ -3051,7 +3241,7 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) pI830->XvEnabled = FALSE; #endif - if (pI830->accel != ACCEL_NONE) { + if (pI830->accel != ACCEL_NONE && !pI830->use_drm_mode) { if (pI830->memory_manager == NULL && pI830->LpRing->mem->size == 0) { xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Disabling acceleration because the ring buffer " @@ -3092,69 +3282,48 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) } if (pI830->directRenderingEnabled) - pI830->directRenderingEnabled = I830DRIDoMappings(pScreen); + pI830->directRenderingEnabled = I830DRIDoMappings(pScreen); /* If we failed for any reason, free DRI memory. */ if (!pI830->directRenderingEnabled) - i830_free_3d_memory(pScrn); - - config = XF86_CRTC_CONFIG_PTR(pScrn); - - /* - * If an LVDS display is present, swap the plane/pipe mappings so we can - * use FBC on the builtin display. - * Note: 965+ chips can compress either plane, so we leave the mapping - * alone in that case. - * Also make sure the DRM can handle the swap. - */ - if (I830LVDSPresent(pScrn) && !IS_I965GM(pI830) && !IS_GM45(pI830) && - (!pI830->directRenderingEnabled || - (pI830->directRenderingEnabled && pI830->drmMinor >= 10))) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "adjusting plane->pipe mappings " - "to allow for framebuffer compression\n"); - for (c = 0; c < config->num_crtc; c++) { - xf86CrtcPtr crtc = config->crtc[c]; - I830CrtcPrivatePtr intel_crtc = crtc->driver_private; - - if (intel_crtc->pipe == 0) - intel_crtc->plane = 1; - else if (intel_crtc->pipe == 1) - intel_crtc->plane = 0; - } - } + i830_free_3d_memory(pScrn); + if (!pI830->use_drm_mode) + I830SwapPipes(pScrn); #else pI830->directRenderingEnabled = FALSE; #endif #ifdef XF86DRI - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Page Flipping %sabled\n", pI830->allowPageFlip ? "en" : "dis"); #endif - DPRINTF(PFX, "assert( if(!I830MapMem(pScrn)) )\n"); - if (!I830MapMem(pScrn)) - return FALSE; - - pScrn->memPhysBase = (unsigned long)pI830->FbBase; + if (!pI830->use_drm_mode) { + DPRINTF(PFX, "assert( if(!I830MapMem(pScrn)) )\n"); + if (!I830MapMem(pScrn)) + return FALSE; + pScrn->memPhysBase = (unsigned long)pI830->FbBase; + } if (I830IsPrimary(pScrn)) { - pScrn->fbOffset = pI830->front_buffer->offset; + pScrn->fbOffset = pI830->front_buffer->offset; } else { - pScrn->fbOffset = pI8301->front_buffer_2->offset; + pScrn->fbOffset = pI8301->front_buffer_2->offset; } pI830->xoffset = (pScrn->fbOffset / pI830->cpp) % pScrn->displayWidth; pI830->yoffset = (pScrn->fbOffset / pI830->cpp) / pScrn->displayWidth; - i830_init_bufmgr(pScrn); + if (!pI830->use_drm_mode) { + vgaHWSetMmioFuncs(hwp, pI830->MMIOBase, 0); + vgaHWGetIOBase(hwp); + DPRINTF(PFX, "assert( if(!vgaHWMapMem(pScrn)) )\n"); + if (!vgaHWMapMem(pScrn)) + return FALSE; + } - vgaHWSetMmioFuncs(hwp, pI830->MMIOBase, 0); - vgaHWGetIOBase(hwp); - DPRINTF(PFX, "assert( if(!vgaHWMapMem(pScrn)) )\n"); - if (!vgaHWMapMem(pScrn)) - return FALSE; + i830_init_bufmgr(pScrn); DPRINTF(PFX, "assert( if(!I830EnterVT(scrnIndex, 0)) )\n"); @@ -3268,7 +3437,7 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) #ifdef I830_XV /* Init video */ - if (pI830->XvEnabled) + if (pI830->XvEnabled && !pI830->use_drm_mode) I830InitVideo(pScreen); #endif @@ -3279,11 +3448,15 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) if (pI830->directRenderingEnabled) { pI830->directRenderingOpen = TRUE; xf86DrvMsg(pScrn->scrnIndex, X_INFO, "direct rendering: Enabled\n"); - } else { + } else if (!pI830->use_drm_mode) { if (pI830->directRenderingDisabled) xf86DrvMsg(pScrn->scrnIndex, X_INFO, "direct rendering: Disabled\n"); else xf86DrvMsg(pScrn->scrnIndex, X_INFO, "direct rendering: Failed\n"); + } else { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "failed to enable direct rendering, aborting\n"); + return FALSE; } #else xf86DrvMsg(pScrn->scrnIndex, X_INFO, "direct rendering: Not available\n"); @@ -3395,21 +3568,22 @@ I830LeaveVT(int scrnIndex, int flags) I830Sync(pScrn); - RestoreHWState(pScrn); - - /* Evict everything from the bufmgr, as we're about to lose ownership of - * the graphics memory. - */ - if (!pI830->memory_manager) - intel_bufmgr_fake_evict_all(pI830->bufmgr); - intel_batch_teardown(pScrn); + if (!pI830->use_drm_mode) { + RestoreHWState(pScrn); + /* Evict everything from the bufmgr, as we're about to lose ownership of + * the graphics memory. + */ + if (!pI830->memory_manager) + intel_bufmgr_fake_evict_all(pI830->bufmgr); + intel_batch_teardown(pScrn); - if (!pI830->memory_manager) - i830_stop_ring(pScrn, TRUE); + if (!pI830->memory_manager) + i830_stop_ring(pScrn, TRUE); - if (pI830->debug_modes) { - i830CompareRegsToSnapshot(pScrn, "After LeaveVT"); - i830DumpRegs (pScrn); + if (pI830->debug_modes) { + i830CompareRegsToSnapshot(pScrn, "After LeaveVT"); + i830DumpRegs (pScrn); + } } if (I830IsPrimary(pScrn)) @@ -3452,7 +3626,8 @@ I830EnterVT(int scrnIndex, int flags) */ if (pI830->SaveGeneration != serverGeneration) { pI830->SaveGeneration = serverGeneration; - SaveHWState(pScrn); + if (!pI830->use_drm_mode) + SaveHWState(pScrn); } pI830->leaving = FALSE; @@ -3481,42 +3656,46 @@ I830EnterVT(int scrnIndex, int flags) intel_batch_init(pScrn); - if ((pI830->accel == ACCEL_EXA || pI830->accel == ACCEL_UXA) && IS_I965G(pI830)) + if ((pI830->accel == ACCEL_EXA || pI830->accel == ACCEL_UXA) && + IS_I965G(pI830)) gen4_render_state_init(pScrn); - if (i830_check_error_state(pScrn)) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Existing errors found in hardware state.\n"); - } - - /* Re-set up the ring. */ - if (!pI830->memory_manager) { - i830_stop_ring(pScrn, FALSE); - i830_start_ring(pScrn); - } - if (!pI830->SWCursor) - I830InitHWCursor(pScrn); + if (!pI830->use_drm_mode) { + if (i830_check_error_state(pScrn)) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Existing errors found in hardware state.\n"); + } - /* Tell the BIOS that we're in control of mode setting now. */ - i830_init_bios_control(pScrn); + /* Re-set up the ring. */ + if (!pI830->memory_manager) { + i830_stop_ring(pScrn, FALSE); + i830_start_ring(pScrn); + } + if (!pI830->SWCursor) + I830InitHWCursor(pScrn); - i830_init_clock_gating(pScrn); + /* Tell the BIOS that we're in control of mode setting now. */ + i830_init_bios_control(pScrn); - if (pI830->power_context) - OUTREG(PWRCTXA, pI830->power_context->offset | PWRCTX_EN); + i830_init_clock_gating(pScrn); - /* Clear the framebuffer */ - memset(pI830->FbBase + pScrn->fbOffset, 0, - pScrn->virtualY * pScrn->displayWidth * pI830->cpp); + if (pI830->power_context) + OUTREG(PWRCTXA, pI830->power_context->offset | PWRCTX_EN); + /* Clear the framebuffer */ + memset(pI830->FbBase + pScrn->fbOffset, 0, + pScrn->virtualY * pScrn->displayWidth * pI830->cpp); + } if (!xf86SetDesiredModes (pScrn)) return FALSE; - - if (pI830->debug_modes) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Hardware state at EnterVT:\n"); - i830DumpRegs (pScrn); + + if (!pI830->use_drm_mode) { + if (pI830->debug_modes) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Hardware state at EnterVT:\n"); + i830DumpRegs (pScrn); + } + i830DescribeOutputConfiguration(pScrn); } - i830DescribeOutputConfiguration(pScrn); #ifdef XF86DRI if (pI830->directRenderingEnabled) { @@ -3614,9 +3793,11 @@ I830CloseScreen(int scrnIndex, ScreenPtr pScreen) TimerCancel(pI830->devicesTimer); pI830->devicesTimer = NULL; - DPRINTF(PFX, "\nUnmapping memory\n"); - I830UnmapMem(pScrn); - vgaHWUnmapMem(pScrn); + if (!pI830->use_drm_mode) { + DPRINTF(PFX, "\nUnmapping memory\n"); + I830UnmapMem(pScrn); + vgaHWUnmapMem(pScrn); + } if (pI830->ScanlineColorExpandBuffers) { xfree(pI830->ScanlineColorExpandBuffers); diff --git a/src/i830_exa.c b/src/i830_exa.c index 20417410..9ba8df90 100644 --- a/src/i830_exa.c +++ b/src/i830_exa.c @@ -465,16 +465,159 @@ i830_transform_is_affine (PictTransformPtr t) return t->matrix[2][0] == 0 && t->matrix[2][1] == 0; } -/* - * TODO: - * - Dual head? - */ +static DevPrivateKey exa_pixmap_key = &exa_pixmap_key; + +static void * +I830EXACreatePixmap(ScreenPtr screen, int size, int align) +{ + ScrnInfoPtr scrn = xf86Screens[screen->myNum]; + I830Ptr i830 = I830PTR(scrn); + struct i830_exa_pixmap_priv *new_priv; + + new_priv = xcalloc(1, sizeof(struct i830_exa_pixmap_priv)); + if (!new_priv) + return NULL; + + if (size == 0) + return new_priv; + + new_priv->bo = dri_bo_alloc(i830->bufmgr, "pixmap", size, + i830->accel_pixmap_offset_alignment); + if (!new_priv->bo) { + xfree(new_priv); + return NULL; + } + + return new_priv; +} + +static void +I830EXADestroyPixmap(ScreenPtr pScreen, void *driverPriv) +{ + struct i830_exa_pixmap_priv *priv = driverPriv; + + if (priv->bo) + dri_bo_unreference(priv->bo); + xfree(priv); +} + +static Bool I830EXAPixmapIsOffscreen(PixmapPtr pPix) +{ + struct i830_exa_pixmap_priv *driver_priv = exaGetPixmapDriverPrivate(pPix); + + if (driver_priv && driver_priv->bo) + return TRUE; + + return FALSE; +} + +static Bool I830EXAPrepareAccess(PixmapPtr pPix, int index) +{ + ScreenPtr screen = pPix->drawable.pScreen; + ScrnInfoPtr scrn = xf86Screens[screen->myNum]; + I830Ptr i830 = I830PTR(scrn); + struct i830_exa_pixmap_priv *driver_priv = exaGetPixmapDriverPrivate(pPix); + + if (!driver_priv) { + xf86DrvMsg(scrn->scrnIndex, X_WARNING, "%s: no driver private?\n", + __FUNCTION__); + return FALSE; + } + + if (!driver_priv->bo) { + xf86DrvMsg(scrn->scrnIndex, X_WARNING, "%s: no buffer object?\n", + __FUNCTION__); + return TRUE; + } + + intel_batch_flush(scrn); + if (i830->need_sync) { + I830Sync(scrn); + i830->need_sync = FALSE; + } + if (dri_gem_bo_map_gtt(driver_priv->bo)) { + xf86DrvMsg(scrn->scrnIndex, X_WARNING, "%s: bo map failed\n", + __FUNCTION__); + return FALSE; + } + pPix->devPrivate.ptr = driver_priv->bo->virtual; + + return TRUE; +} + +static void I830EXAFinishAccess(PixmapPtr pPix, int index) +{ + ScreenPtr screen = pPix->drawable.pScreen; + ScrnInfoPtr scrn = xf86Screens[screen->myNum]; + I830Ptr i830 = I830PTR(scrn); + struct i830_exa_pixmap_priv *driver_priv = exaGetPixmapDriverPrivate(pPix); + + if (!driver_priv) { + xf86DrvMsg(scrn->scrnIndex, X_WARNING, "%s: no driver private?\n", + __FUNCTION__); + return; + } + + if (!driver_priv->bo) { + xf86DrvMsg(scrn->scrnIndex, X_WARNING, "%s: no buffer object?\n", + __FUNCTION__); + return; + } + + dri_bo_unmap(driver_priv->bo); + pPix->devPrivate.ptr = NULL; + if (driver_priv->bo == i830->front_buffer->bo) + i830->need_flush = TRUE; +} + +static Bool I830EXAModifyPixmapHeader(PixmapPtr pPix, int width, int height, + int depth, int bitsPerPixel, int devKind, + pointer pPixData) +{ + ScreenPtr pScreen = pPix->drawable.pScreen; + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + I830Ptr pI830 = I830PTR(pScrn); + struct i830_exa_pixmap_priv *driver_priv = exaGetPixmapDriverPrivate(pPix); + + if (!driver_priv) + return FALSE; + + if (pI830->use_drm_mode && + drmmode_is_rotate_pixmap(pScrn, pPixData, &driver_priv->bo)) { + /* this is a rotate pixmap */ + dri_bo_unmap(driver_priv->bo); + dri_bo_reference(driver_priv->bo); + miModifyPixmapHeader(pPix, width, height, depth, + bitsPerPixel, devKind, NULL); + } + + if (pPixData == pI830->FbBase + pScrn->fbOffset) { + if (driver_priv->bo) + dri_bo_unreference(driver_priv->bo); + driver_priv->bo = + intel_bo_gem_create_from_name(pI830->bufmgr, "front", + pI830->front_buffer->gem_name); + if (!driver_priv->bo) + return FALSE; + + miModifyPixmapHeader(pPix, width, height, depth, + bitsPerPixel, devKind, NULL); + + return TRUE; + } + return FALSE; +} + + Bool I830EXAInit(ScreenPtr pScreen) { ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; I830Ptr pI830 = I830PTR(pScrn); + if (!dixRequestPrivate(exa_pixmap_key, 0)) + return FALSE; + pI830->EXADriverPtr = exaDriverAlloc(); if (pI830->EXADriverPtr == NULL) { pI830->accel = ACCEL_NONE; @@ -495,16 +638,28 @@ I830EXAInit(ScreenPtr pScreen) "EXA compatibility mode. Output rotation rendering " "performance may suffer\n"); #endif - pI830->EXADriverPtr->memoryBase = pI830->FbBase; - if (pI830->exa_offscreen) { - pI830->EXADriverPtr->offScreenBase = pI830->exa_offscreen->offset; - pI830->EXADriverPtr->memorySize = pI830->exa_offscreen->offset + - pI830->exa_offscreen->size; + if (!pI830->use_drm_mode) { + pI830->EXADriverPtr->memoryBase = pI830->FbBase; + if (pI830->exa_offscreen) { + pI830->EXADriverPtr->offScreenBase = pI830->exa_offscreen->offset; + pI830->EXADriverPtr->memorySize = pI830->exa_offscreen->offset + + pI830->exa_offscreen->size; + } else { + pI830->EXADriverPtr->offScreenBase = pI830->FbMapSize; + pI830->EXADriverPtr->memorySize = pI830->FbMapSize; + } + pI830->EXADriverPtr->flags = EXA_OFFSCREEN_PIXMAPS; } else { - pI830->EXADriverPtr->offScreenBase = pI830->FbMapSize; - pI830->EXADriverPtr->memorySize = pI830->FbMapSize; + pI830->EXADriverPtr->flags = EXA_OFFSCREEN_PIXMAPS | EXA_HANDLES_PIXMAPS; + pI830->EXADriverPtr->PrepareAccess = I830EXAPrepareAccess; + pI830->EXADriverPtr->FinishAccess = I830EXAFinishAccess; +#if EXA_VERSION_MINOR >= 4 + pI830->EXADriverPtr->CreatePixmap = I830EXACreatePixmap; + pI830->EXADriverPtr->DestroyPixmap = I830EXADestroyPixmap; + pI830->EXADriverPtr->PixmapIsOffscreen = I830EXAPixmapIsOffscreen; + pI830->EXADriverPtr->ModifyPixmapHeader = I830EXAModifyPixmapHeader; +#endif } - pI830->EXADriverPtr->flags = EXA_OFFSCREEN_PIXMAPS; DPRINTF(PFX, "EXA Mem: memoryBase 0x%x, end 0x%x, offscreen base 0x%x, " "memorySize 0x%x\n", @@ -551,7 +706,8 @@ I830EXAInit(ScreenPtr pScreen) pI830->EXADriverPtr->DoneComposite = i830_done_composite; } #if EXA_VERSION_MINOR >= 2 - pI830->EXADriverPtr->PixmapIsOffscreen = i830_exa_pixmap_is_offscreen; + if (!pI830->use_drm_mode) + pI830->EXADriverPtr->PixmapIsOffscreen = i830_exa_pixmap_is_offscreen; #endif if(!exaDriverInit(pScreen, pI830->EXADriverPtr)) { @@ -579,15 +735,27 @@ i830_uxa_set_pixmap_bo (PixmapPtr pixmap, dri_bo *bo) } dri_bo * -i830_uxa_get_pixmap_bo (PixmapPtr pixmap) +i830_get_pixmap_bo(PixmapPtr pixmap) { - return dixLookupPrivate(&pixmap->devPrivates, uxa_pixmap_key); + ScreenPtr screen = pixmap->drawable.pScreen; + ScrnInfoPtr scrn = xf86Screens[screen->myNum]; + I830Ptr i830 = I830PTR(scrn); + + if (i830->accel == ACCEL_UXA) { + return dixLookupPrivate(&pixmap->devPrivates, uxa_pixmap_key); + } else if (i830->accel == ACCEL_EXA) { + struct i830_exa_pixmap_priv *driver_priv = + exaGetPixmapDriverPrivate(pixmap); + return driver_priv ? driver_priv->bo : NULL; + } + + return NULL; } static Bool i830_uxa_prepare_access (PixmapPtr pixmap, uxa_access_t access) { - dri_bo *bo = i830_uxa_get_pixmap_bo (pixmap); + dri_bo *bo = i830_get_pixmap_bo (pixmap); if (bo) { ScreenPtr screen = pixmap->drawable.pScreen; @@ -609,7 +777,7 @@ i830_uxa_prepare_access (PixmapPtr pixmap, uxa_access_t access) static void i830_uxa_finish_access (PixmapPtr pixmap) { - dri_bo *bo = i830_uxa_get_pixmap_bo (pixmap); + dri_bo *bo = i830_get_pixmap_bo (pixmap); if (bo) { ScreenPtr screen = pixmap->drawable.pScreen; @@ -638,7 +806,7 @@ i830_uxa_block_handler (ScreenPtr screen) static Bool i830_uxa_pixmap_is_offscreen(PixmapPtr pixmap) { - return i830_uxa_get_pixmap_bo (pixmap) != NULL; + return i830_get_pixmap_bo (pixmap) != NULL; } static PixmapPtr @@ -679,7 +847,7 @@ static Bool i830_uxa_destroy_pixmap (PixmapPtr pixmap) { if (pixmap->refcnt == 1) { - dri_bo *bo = i830_uxa_get_pixmap_bo (pixmap); + dri_bo *bo = i830_get_pixmap_bo (pixmap); if (bo) dri_bo_unreference (bo); diff --git a/src/i830_memory.c b/src/i830_memory.c index ff5def69..443cc4e5 100644 --- a/src/i830_memory.c +++ b/src/i830_memory.c @@ -184,7 +184,7 @@ i830_bind_memory(ScrnInfoPtr pScrn, i830_memory *mem) if (!pI830->gtt_acquired) return TRUE; - if (mem->key != -1 && + if (mem->key != -1 && !xf86BindGARTMemory(pScrn->scrnIndex, mem->key, mem->agp_offset)) { return FALSE; @@ -193,7 +193,7 @@ i830_bind_memory(ScrnInfoPtr pScrn, i830_memory *mem) mem->bound = TRUE; } - if (mem->tiling != TILE_NONE) { + if (mem->tiling != TILE_NONE && !pI830->use_drm_mode) { mem->fence_nr = i830_set_tiling(pScrn, mem->offset, mem->pitch, mem->allocated_size, mem->tiling); } @@ -204,10 +204,12 @@ i830_bind_memory(ScrnInfoPtr pScrn, i830_memory *mem) static Bool i830_unbind_memory(ScrnInfoPtr pScrn, i830_memory *mem) { + I830Ptr pI830 = I830PTR(pScrn); + if (mem == NULL || !mem->bound) return TRUE; - if (mem->tiling != TILE_NONE) + if (mem->tiling != TILE_NONE && !pI830->use_drm_mode) i830_clear_tiling(pScrn, mem->fence_nr); #ifdef XF86DRI @@ -460,22 +462,24 @@ i830_allocator_init(ScrnInfoPtr pScrn, unsigned long offset, unsigned long size) ALIGN_BOTH_ENDS | NEED_NON_STOLEN); if (pI830->memory_manager != NULL) { - struct drm_i915_gem_init init; - int ret; - - init.gtt_start = pI830->memory_manager->offset; - init.gtt_end = pI830->memory_manager->offset + - pI830->memory_manager->size; - - /* Tell the kernel to manage it */ - ret = ioctl(pI830->drmSubFD, DRM_IOCTL_I915_GEM_INIT, &init); - if (ret != 0) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Failed to initialize kernel memory manager\n"); - i830_free_memory(pScrn, pI830->memory_manager); - pI830->memory_manager = NULL; + if (!pI830->use_drm_mode) { + struct drm_i915_gem_init init; + int ret; + + init.gtt_start = pI830->memory_manager->offset; + init.gtt_end = pI830->memory_manager->offset + + pI830->memory_manager->size; + + /* Tell the kernel to manage it */ + ret = ioctl(pI830->drmSubFD, DRM_IOCTL_I915_GEM_INIT, &init); + if (ret != 0) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Failed to initialize kernel memory manager\n"); + i830_free_memory(pScrn, pI830->memory_manager); + pI830->memory_manager = NULL; + } + i830_init_bufmgr(pScrn); } - i830_init_bufmgr(pScrn); } else { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to allocate space for kernel memory manager\n"); @@ -753,7 +757,7 @@ i830_allocate_memory_bo(ScrnInfoPtr pScrn, const char *name, mem->lifetime_fixed_offset = TRUE; /* Bind it if we currently control the VT */ - if (pScrn->vtSema) { + if (pScrn->vtSema || pI830->use_drm_mode) { if (!i830_bind_memory(pScrn, mem)) { dri_bo_unreference (mem->bo); xfree(mem->name); @@ -800,8 +804,9 @@ i830_allocate_memory(ScrnInfoPtr pScrn, const char *name, #ifdef XF86DRI I830Ptr pI830 = I830PTR(pScrn); - if (pI830->memory_manager && !(flags & NEED_PHYSICAL_ADDR) && - !(flags & NEED_LIFETIME_FIXED)) + if (pI830->use_drm_mode || (pI830->memory_manager && + !(flags & NEED_PHYSICAL_ADDR) && + !(flags & NEED_LIFETIME_FIXED))) { return i830_allocate_memory_bo(pScrn, name, size, alignment, flags); } else @@ -1045,6 +1050,10 @@ i830_allocate_overlay(ScrnInfoPtr pScrn) /* This failure isn't fatal. */ } + if (flags & NEED_PHYSICAL_ADDR) + if (pI830->use_drm_mode) + ; /* need physical addr */ + return TRUE; } #endif @@ -1122,7 +1131,7 @@ i830_allocate_framebuffer(ScrnInfoPtr pScrn, I830Ptr pI830, BoxPtr FbMemBox, /* We'll allocate the fb such that the root window will fit regardless of * rotation. */ - if (pScrn->virtualX > pScrn->virtualY) + if (!pI830->use_drm_mode && pScrn->virtualX > pScrn->virtualY) fb_height = pScrn->virtualX; else fb_height = pScrn->virtualY; @@ -1186,7 +1195,7 @@ i830_allocate_framebuffer(ScrnInfoPtr pScrn, I830Ptr pI830, BoxPtr FbMemBox, * acceleration operations (non-XY COLOR_BLT) can't be done to tiled * buffers. */ - if (pI830->accel <= ACCEL_XAA && IS_I965G(pI830)) + if ((pI830->accel <= ACCEL_XAA && IS_I965G(pI830)) || pI830->use_drm_mode) tiling = FALSE; else tiling = pI830->tiling; @@ -1215,8 +1224,16 @@ i830_allocate_framebuffer(ScrnInfoPtr pScrn, I830Ptr pI830, BoxPtr FbMemBox, return NULL; } - if (pI830->FbBase) + if (pI830->use_drm_mode) { +#ifdef XF86DRM_MODE + ErrorF("setting kernel fb to new front buffer\n"); + ErrorF("front_buffer->bo->size: %ld\n", front_buffer->bo->size); + drmmode_set_fb(pScrn, &pI830->drmmode, pScrn->virtualX, fb_height, + pScrn->displayWidth * pI830->cpp, front_buffer->bo); +#endif + } else if (pI830->FbBase) memset (pI830->FbBase + front_buffer->offset, 0, size); + return front_buffer; } @@ -1225,10 +1242,15 @@ i830_allocate_cursor_buffers(ScrnInfoPtr pScrn) { I830Ptr pI830 = I830PTR(pScrn); xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); - int flags = pI830->CursorNeedsPhysical ? NEED_PHYSICAL_ADDR : 0; + int flags; int i; long size; + if (pI830->use_drm_mode) + pI830->CursorNeedsPhysical = FALSE; + + flags = pI830->CursorNeedsPhysical ? NEED_PHYSICAL_ADDR : 0; + /* Try to allocate one big blob for our cursor memory. This works * around a limitation in the FreeBSD AGP driver that allows only one * physical allocation larger than a page, and could allow us @@ -1341,18 +1363,20 @@ i830_allocate_2d_memory(ScrnInfoPtr pScrn) unsigned int pitch = pScrn->displayWidth * pI830->cpp; long size; - if (!pI830->StolenOnly && - (!xf86AgpGARTSupported() || !xf86AcquireGART(pScrn->scrnIndex))) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "AGP GART support is either not available or cannot " - "be used.\n" - "\tMake sure your kernel has agpgart support or has\n" - "\tthe agpgart module loaded.\n"); - return FALSE; - } + if (!pI830->use_drm_mode) { + if (!pI830->StolenOnly && + (!xf86AgpGARTSupported() || !xf86AcquireGART(pScrn->scrnIndex))) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "AGP GART support is either not available or cannot " + "be used.\n" + "\tMake sure your kernel has agpgart support or has\n" + "\tthe agpgart module loaded.\n"); + return FALSE; + } - /* Allocate the ring buffer first, so it ends up in stolen mem. */ - i830_allocate_ringbuffer(pScrn); + /* Allocate the ring buffer first, so it ends up in stolen mem. */ + i830_allocate_ringbuffer(pScrn); + } if (pI830->fb_compression) i830_setup_fb_compression(pScrn); @@ -1423,7 +1447,7 @@ i830_allocate_2d_memory(ScrnInfoPtr pScrn) return FALSE; #ifdef I830_USE_EXA - if (pI830->accel == ACCEL_EXA) { + if (pI830->accel == ACCEL_EXA && !pI830->use_drm_mode) { if (pI830->exa_offscreen == NULL) { /* Default EXA to having 3 screens worth of offscreen memory space * (for pixmaps). @@ -1950,28 +1974,32 @@ i830_bind_all_memory(ScrnInfoPtr pScrn) if (pI830->StolenOnly == TRUE || pI830->memory_list == NULL) return TRUE; - if (xf86AgpGARTSupported() && !pI830->gtt_acquired) { + if (pI830->use_drm_mode || (xf86AgpGARTSupported() && + !pI830->gtt_acquired)) { i830_memory *mem; - if (!xf86AcquireGART(pScrn->scrnIndex)) - return FALSE; - - pI830->gtt_acquired = TRUE; + if (!pI830->use_drm_mode) { + if (!xf86AcquireGART(pScrn->scrnIndex)) + return FALSE; + pI830->gtt_acquired = TRUE; + } for (mem = pI830->memory_list->next; mem->next != NULL; mem = mem->next) { - if (!i830_bind_memory(pScrn, mem)) { + if (!mem->bound && !i830_bind_memory(pScrn, mem)) { /* This shouldn't happen */ FatalError("Couldn't bind memory for %s\n", mem->name); } } for (mem = pI830->bo_list; mem != NULL; mem = mem->next) { + if (mem->bound) + continue; if (!mem->lifetime_fixed_offset && !i830_bind_memory(pScrn, mem)) FatalError("Couldn't bind memory for BO %s\n", mem->name); } } - if (!pI830->SWCursor) + if (!pI830->SWCursor && !pI830->use_drm_mode) i830_update_cursor_offsets(pScrn); return TRUE; @@ -1986,7 +2014,8 @@ i830_unbind_all_memory(ScrnInfoPtr pScrn) if (pI830->StolenOnly == TRUE) return TRUE; - if (xf86AgpGARTSupported() && pI830->gtt_acquired) { + if (pI830->use_drm_mode || (xf86AgpGARTSupported() && + pI830->gtt_acquired)) { i830_memory *mem; for (mem = pI830->memory_list->next; mem->next != NULL; @@ -2002,10 +2031,12 @@ i830_unbind_all_memory(ScrnInfoPtr pScrn) i830_unbind_memory(pScrn, mem); } - pI830->gtt_acquired = FALSE; + if (!pI830->use_drm_mode) { + pI830->gtt_acquired = FALSE; - if (!xf86ReleaseGART(pScrn->scrnIndex)) - return FALSE; + if (!xf86ReleaseGART(pScrn->scrnIndex)) + return FALSE; + } } return TRUE; @@ -2057,3 +2088,118 @@ Bool i830_allocate_xvmc_buffer(ScrnInfoPtr pScrn, const char *name, return TRUE; } #endif + +#ifdef XF86DRI_MM +#if 0 +static i830_memory * +i830_allocate_framebuffer_new(ScrnInfoPtr pScrn, I830Ptr pI830, BoxPtr FbMemBox) +{ + unsigned int pitch = pScrn->displayWidth * pI830->cpp; + unsigned long minspace, avail; + int cacheLines; + int align; + long size, fb_height; + char *name; + int flags; + i830_memory *front_buffer = NULL; + Bool tiling; + + flags = ALLOW_SHARING; + + /* Clear everything first. */ + memset(FbMemBox, 0, sizeof(*FbMemBox)); + + fb_height = pScrn->virtualY; + + FbMemBox->x1 = 0; + FbMemBox->x2 = pScrn->displayWidth; + FbMemBox->y1 = 0; + FbMemBox->y2 = fb_height; + + /* Calculate how much framebuffer memory to allocate. For the + * initial allocation, calculate a reasonable minimum. This is + * enough for the virtual screen size, plus some pixmap cache + * space if we're using XAA. + */ + minspace = pitch * pScrn->virtualY; + avail = pScrn->videoRam * 1024; + cacheLines = 0; + + size = pitch * (fb_height + cacheLines); + size = ROUND_TO_PAGE(size); + + name = "front buffer"; + + /* Front buffer tiling has to be disabled with G965 XAA because some of the + * acceleration operations (non-XY COLOR_BLT) can't be done to tiled + * buffers. + */ + if (!(pI830->accel == ACCEL_EXA) && IS_I965G(pI830)) + tiling = FALSE; + else + tiling = pI830->tiling; + + if (pI830->use_drm_mode) + tiling = FALSE; + + /* Attempt to allocate it tiled first if we have page flipping on. */ + if (tiling && IsTileable(pScrn, pitch)) { + /* XXX: probably not the case on 965 */ + if (IS_I9XX(pI830)) + align = MB(1); + else + align = KB(512); + front_buffer = i830_allocate_memory_tiled(pScrn, name, size, + pitch, align, flags, + TILE_XMAJOR); + } + + /* If not, attempt it linear */ + if (front_buffer == NULL) { + front_buffer = i830_allocate_memory(pScrn, name, size, KB(64), flags); + } + + if (front_buffer == NULL) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to allocate " + "framebuffer. Is your VideoRAM set too low?\n"); + + return NULL; + } + + return front_buffer; +} +#endif +uint32_t +i830_create_new_fb(ScrnInfoPtr pScrn, int width, int height, int *pitch) +{ + return 0; + +#if 0 + I830Ptr pI830 = I830PTR(pScrn); + i830_memory *old_buffer; + + pScrn->virtualX = width; + pScrn->virtualY = height; + pScrn->displayWidth = (pScrn->virtualX + 63) & ~63; + + *pitch = pScrn->displayWidth * pI830->cpp; + + old_buffer = pI830->front_buffer; + + pI830->front_buffer = + i830_allocate_framebuffer_new(pScrn, pI830, &pI830->FbMemBox); + + ErrorF("old front size %08lx, new front size %08lx\n", + old_buffer->bo->size, pI830->front_buffer->bo->size); + ErrorF("old front offset %08lx, new front offset %08lx\n", + old_buffer->bo->offset, pI830->front_buffer->bo->offset); + + i830_free_memory(pScrn, old_buffer); + + i830_update_front_offset(pScrn); + + return pI830->front_buffer->bo->handle; +#endif +} + +#endif diff --git a/src/i830_video.c b/src/i830_video.c index 1719835c..5e6ebd77 100644 --- a/src/i830_video.c +++ b/src/i830_video.c @@ -2394,7 +2394,7 @@ I830PutImage(ScrnInfoPtr pScrn, /* fixup pointers */ #ifdef INTEL_XVMC if (id == FOURCC_XVMC && IS_I915(pI830)) { - pPriv->YBuf0offset = (uint32_t)buf; + pPriv->YBuf0offset = (uint32_t)((uint64_t)buf); pPriv->VBuf0offset = pPriv->YBuf0offset + (dstPitch2 * height); pPriv->UBuf0offset = pPriv->VBuf0offset + (dstPitch * height / 2); destId = FOURCC_YV12; diff --git a/src/i965_render.c b/src/i965_render.c index 391e0633..a4334c65 100644 --- a/src/i965_render.c +++ b/src/i965_render.c @@ -1441,6 +1441,7 @@ gen4_render_state_init(ScrnInfoPtr pScrn) { I830Ptr pI830 = I830PTR(pScrn); struct gen4_render_state *render_state; + int ret; if (pI830->gen4_render_state == NULL) pI830->gen4_render_state = calloc(sizeof(*render_state), 1); @@ -1448,8 +1449,19 @@ gen4_render_state_init(ScrnInfoPtr pScrn) render_state = pI830->gen4_render_state; render_state->card_state_offset = pI830->gen4_render_state_mem->offset; - render_state->card_state = (gen4_state_t *) - (pI830->FbBase + render_state->card_state_offset); + + if (pI830->gen4_render_state_mem->bo) { + ret = dri_bo_map(pI830->gen4_render_state_mem->bo, 1); + if (ret) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Failed to map gen4 state\n"); + return; + } + render_state->card_state = pI830->gen4_render_state_mem->bo->virtual; + } else { + render_state->card_state = (gen4_state_t *) + (pI830->FbBase + render_state->card_state_offset); + } gen4_state_init(render_state); } @@ -1462,6 +1474,10 @@ gen4_render_state_cleanup(ScrnInfoPtr pScrn) { I830Ptr pI830 = I830PTR(pScrn); + if (pI830->gen4_render_state_mem->bo) { + dri_bo_unmap(pI830->gen4_render_state_mem->bo); + dri_bo_unreference(pI830->gen4_render_state_mem->bo); + } pI830->gen4_render_state->card_state = NULL; } diff --git a/src/reg_dumper/reg_dumper.h b/src/reg_dumper/reg_dumper.h index 241b2419..9f24d5cc 100644 --- a/src/reg_dumper/reg_dumper.h +++ b/src/reg_dumper/reg_dumper.h @@ -52,6 +52,7 @@ struct pci_info_rec { typedef struct _i830 { /* Fields in common with the real pI830 */ struct pci_info_rec *PciInfo; + Bool use_drm_mode; /* Fields used for setting up reg_dumper */ struct pci_device *pci_dev; |