diff --git a/configure.ac b/configure.ac index 847a39f..a254353 100644 --- a/configure.ac +++ b/configure.ac @@ -202,6 +202,10 @@ if test "$DRI" = yes; then save_CFLAGS="$CFLAGS" CFLAGS="$XORG_CFLAGS $DRI_CFLAGS" + 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 AC_CHECK_TYPE(drm_i915_flip_t, [AC_DEFINE(HAVE_I915_FLIP, 1, [Have drm_i915_flip_t and related definitions])], diff --git a/src/Makefile.am b/src/Makefile.am index 4f983c7..441f0ca 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -125,7 +125,10 @@ intel_drv_la_SOURCES = \ intel_bufmgr_exa.c \ intel_bufmgr_exa.h \ intel_batchbuffer.c \ - intel_batchbuffer.h + intel_batchbuffer.h \ + drmmode_display.c \ + drmmode_display.h + INTEL_G4A = \ packed_yuv_sf.g4a \ diff --git a/src/common.h b/src/common.h index 7100b4e..47bcf92 100644 --- a/src/common.h +++ b/src/common.h @@ -450,7 +450,8 @@ extern int I810_DEBUG; /* mark chipsets for using gfx VM offset for overlay */ #define OVERLAY_NOPHYSICAL(pI810) (IS_G33CLASS(pI810)) /* chipsets require graphics mem for hardware status page */ -#define HWS_NEED_GFX(pI810) (IS_G33CLASS(pI810) || IS_IGD_GM(pI810)) +#define HWS_NEED_GFX(pI810) (!pI810->use_drm_mode &&\ + (IS_G33CLASS(pI810) || IS_IGD_GM(pI810))) #define GTT_PAGE_SIZE KB(4) #define ROUND_TO(x, y) (((x) + (y) - 1) / (y) * (y)) diff --git a/src/drmmode_display.c b/src/drmmode_display.c new file mode 100644 index 0000000..d60d3f0 --- /dev/null +++ b/src/drmmode_display.c @@ -0,0 +1,680 @@ +/* + * 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 + * + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef XF86DRM_MODE +#include "i830.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; + + ErrorF("resize called %d %d\n", width, height); + 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); + 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; + drmmode_ptr drmmode = drmmode_crtc->drmmode; + + int ret; + void *ptr; + /* need to map the cursor here */ + + ret = drmBOMap(drmmode->fd, &drmmode_crtc->cursor_bo, + DRM_BO_FLAG_WRITE, DRM_BO_HINT_DONT_FENCE, + &ptr); + + if (ret) { + ErrorF("failed to map cursor BO %d\n", ret); + return; + } + + memcpy (ptr, image, 64 * 64 * 4); + + drmBOUnmap(drmmode->fd, &drmmode_crtc->cursor_bo); + 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, I810_CURSOR_X, I810_CURSOR_Y); + +} + +static void +drmmode_show_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, drmmode_crtc->cursor_bo.handle, I810_CURSOR_X, I810_CURSOR_Y); +} + +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 ret; + int size; + unsigned long rotate_pitch; + + rotate_pitch = crtc->scrn->displayWidth * drmmode->cpp; + size = rotate_pitch * height; + + drmmode_crtc->rotate_bo = dri_bo_alloc(drmmode->bufmgr, "rotate", + size, 4096, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_CACHED | DRM_BO_FLAG_CACHED_MAPPED); + + 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, dri_bo_get_handle(drmmode_crtc->rotate_bo), &drmmode_crtc->rotate_fb_id); + if (ret) { + ErrorF("failed to add rotate fb\n"); + } + + return drmmode_crtc->rotate_bo->virtual; +} + +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; + drmmode_ptr drmmode = drmmode_crtc->drmmode; + + if (rotate_pixmap) + FreeScratchPixmapHeader(rotate_pixmap); + + if (data) { + /* 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; + } + +} + +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; + int cursor_size = 64 * 64 * 4; + uint32_t mask; + 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; + + /* allocate cursor BO for this crtc */ + mask = DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE | DRM_BO_FLAG_MAPPABLE | + DRM_BO_FLAG_MEM_VRAM /*| DRM_BO_FLAG_NO_EVICT*/; + ret = drmBOCreate(drmmode->fd, cursor_size, 0, NULL, + mask, 0, &drmmode_crtc->cursor_bo); + + if (ret) { + ErrorF("failed to allocate cursor for crtc %d\n", ret); + return; + } + 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)) { + 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, +#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 }; + +struct output_name { + const char *name; + int count; +}; + +struct output_name output_names[] = { + { "None", 0 }, + { "VGA", 0 }, + { "TMDS", 0 }, + { "LVDS", 0 }, + { "TV", 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[kencoder->encoder_type].name, output_names[kencoder->encoder_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; +} + +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, TRUE); + + return TRUE; +} + +Bool drmmode_set_bufmgr(ScrnInfoPtr pScrn, drmmode_ptr drmmode, dri_bufmgr *bufmgr) +{ + drmmode->bufmgr = bufmgr; + return TRUE; +} + +void drmmode_set_fb(ScrnInfoPtr scrn, drmmode_ptr drmmode, int width, int height, int pitch, drmBO *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\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); +} + +Bool drmmode_is_rotate_pixmap(ScrnInfoPtr pScrn, pointer pPixData, dri_bo **bo) +{ + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR (pScrn); + int i; + + 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; + +} + +static Bool drmmode_resize_fb(ScrnInfoPtr scrn, drmmode_ptr drmmode, int width, int height) +{ + uint32_t handle; + int pitch; + int ret; + + 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 0000000..dda799a --- /dev/null +++ b/src/drmmode_display.h @@ -0,0 +1,69 @@ +/* + * 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 + * + */ +#ifndef DRMMODE_DISPLAY_H +#define DRMMODE_DISPLAY_H + +#ifdef XF86DRM_MODE + +#include "xf86drmMode.h" + +typedef struct { + int fd; + int fb_id; + drmModeResPtr mode_res; + drmModeFBPtr mode_fb; + int cpp; + dri_bufmgr *bufmgr; + + 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; + drmBO cursor_bo; + 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 Bool drmmode_set_bufmgr(ScrnInfoPtr pScrn, drmmode_ptr drmmode, dri_bufmgr *bufmgr); +extern void drmmode_set_fb(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int width, int height, int pitch, drmBO *bo); +extern Bool drmmode_is_rotate_pixmap(ScrnInfoPtr pScrn, pointer pPixData, dri_bo **bo); + +#endif +#endif diff --git a/src/i810_driver.c b/src/i810_driver.c index 53121a6..3fadb01 100644 --- a/src/i810_driver.c +++ b/src/i810_driver.c @@ -158,6 +158,21 @@ static const struct pci_id_match intel_device_match[] = { #endif /* XSERVER_LIBPCIACCESS */ +static Bool +I810DriverFunc(ScrnInfoPtr pScrn, xorgDriverFuncOp op, pointer ptr) +{ + xorgHWFlags *flag; + + switch (op) { + case GET_REQUIRED_HW_INTERFACES: + flag = (CARD32*)ptr; + (*flag) = 0; + return TRUE; + default: + return FALSE; + } +} + _X_EXPORT DriverRec I810 = { I810_VERSION, I810_DRIVER_NAME, @@ -170,7 +185,7 @@ _X_EXPORT DriverRec I810 = { I810AvailableOptions, NULL, 0, - NULL, + I810DriverFunc, #if XSERVER_LIBPCIACCESS intel_device_match, intel_pci_probe diff --git a/src/i830.h b/src/i830.h index 5bc1139..a05da9c 100644 --- a/src/i830.h +++ b/src/i830.h @@ -86,8 +86,12 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #ifdef DAMAGE #include "damage.h" #endif +#include "drmmode_display.h" #endif + + + #ifdef I830_USE_EXA #include "exa.h" Bool I830EXAInit(ScreenPtr pScreen); @@ -412,6 +416,7 @@ typedef struct _I830Rec { #ifdef I830_XV /* For Xvideo */ i830_memory *overlay_regs; + dri_bo *overlay_regs_bo; #endif XF86ModReqInfo shadowReq; /* to test for later libshadow */ Rotation rotation; @@ -548,10 +553,6 @@ typedef struct _I830Rec { Bool StolenOnly; - Bool swfSaved; - CARD32 saveSWF0; - CARD32 saveSWF4; - Bool checkDevices; /* Driver phase/state information */ @@ -573,6 +574,10 @@ typedef struct _I830Rec { enum backlight_control backlight_control_method; + Bool swfSaved; + CARD32 saveSWF0; + CARD32 saveSWF4; + CARD32 saveDSPACNTR; CARD32 saveDSPBCNTR; CARD32 savePIPEACONF; @@ -638,18 +643,24 @@ typedef struct _I830Rec { CARD32 saveFBC_CONTROL; CARD32 saveFBC_FENCE_OFF; - enum last_3d *last_3d; - /** Enables logging of debug output related to mode switching. */ Bool debug_modes; unsigned int quirk_flag; + enum last_3d *last_3d; + /* batchbuffer support */ struct i965_exastate_buffer *exa965; struct intelddx_batchbuffer *batch; dri_bufmgr *bufmgr; unsigned int maxBatchSize; Bool use_ttm_batch; + + int use_drm_mode; +#ifdef XF86DRM_MODE + drmmode_rec drmmode; + int drm_mm_init; +#endif } I830Rec; #define I830PTR(p) ((I830Ptr)((p)->driverPrivate)) @@ -745,6 +756,11 @@ extern void I830DRI2Lock(ScreenPtr pScrn); extern void I830DRI2Unlock(ScreenPtr pScrn); #endif +#ifdef XF86DRI +extern void I830InitBufMgr(ScrnInfoPtr pScrn); +#endif + +void i830_update_front_offset(ScrnInfoPtr pScrn); unsigned long intel_get_pixmap_offset(PixmapPtr pPix); unsigned long intel_get_pixmap_pitch(PixmapPtr pPix); extern Bool I830AccelInit(ScreenPtr pScreen); @@ -780,7 +796,7 @@ extern long I830CheckAvailableMemory(ScrnInfoPtr pScrn); Bool i830_allocate_2d_memory(ScrnInfoPtr pScrn); Bool i830_allocate_texture_memory(ScrnInfoPtr pScrn); Bool i830_allocate_3d_memory(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_dri.c b/src/i830_dri.c index 186a5c0..07ae646 100644 --- a/src/i830_dri.c +++ b/src/i830_dri.c @@ -177,10 +177,12 @@ I830InitDma(ScrnInfoPtr pScrn) memset(&info, 0, sizeof(info)); info.func = I915_INIT_DMA; - - info.ring_start = ring->mem->offset + pI830->LinearAddr; - info.ring_end = ring->mem->end + pI830->LinearAddr; - info.ring_size = ring->mem->size; + + if (!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; + } info.mmio_offset = (unsigned int)pI830DRI->regs; @@ -516,16 +518,13 @@ I830CheckDRIAvailable(ScrnInfoPtr pScrn) return TRUE; } -static void -I830InitBufMgr(ScreenPtr pScreen) +void +I830InitBufMgr(ScrnInfoPtr pScrn) { - ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; I830Ptr pI830 = I830PTR(pScrn); - if (pI830->drmMinor < 11) { - pI830->use_ttm_batch = FALSE; - return; - } + if (pI830->bufmgr) + return; /* 865G appears to have a problem with large batchbuffer sizes, * according to comments in Mesa code. It fixes problems on the hardware. @@ -542,9 +541,10 @@ I830InitBufMgr(ScreenPtr pScreen) if (!pI830->bufmgr) return; - pI830->batch = intelddx_batchbuffer_alloc(pScrn); pI830->use_ttm_batch = TRUE; - +#ifdef XF86DRM_MODE + drmmode_set_bufmgr(pScrn, &pI830->drmmode, pI830->bufmgr); +#endif } Bool @@ -777,7 +777,11 @@ I830DRIScreenInit(ScreenPtr pScreen) } } - I830InitBufMgr(pScreen); + if (pI830->drmMinor < 11) { + pI830->use_ttm_batch = FALSE; + } else { + I830InitBufMgr(pScrn); + } return TRUE; } @@ -823,28 +827,31 @@ I830DRIDoMappings(ScreenPtr pScreen) drmI830Sarea *sarea = (drmI830Sarea *) DRIGetSAREAPrivate(pScreen); DPRINTF(PFX, "I830DRIDoMappings\n"); - pI830DRI->regsSize = I830_REG_SIZE; - if (drmAddMap(pI830->drmSubFD, (drm_handle_t)pI830->MMIOAddr, - pI830DRI->regsSize, DRM_REGISTERS, 0, - (drmAddress) &pI830DRI->regs) < 0) { - xf86DrvMsg(pScreen->myNum, X_ERROR, "[drm] drmAddMap(regs) failed\n"); - DRICloseScreen(pScreen); - return FALSE; - } - xf86DrvMsg(pScreen->myNum, X_INFO, "[drm] Registers = 0x%08x\n", - (int)pI830DRI->regs); - if (drmAddMap(pI830->drmSubFD, - (drm_handle_t)pI830->LpRing->mem->offset + pI830->LinearAddr, - pI830->LpRing->mem->size, DRM_AGP, 0, - (drmAddress) &pI830->ring_map) < 0) { - xf86DrvMsg(pScreen->myNum, X_ERROR, - "[drm] drmAddMap(ring_map) failed. Disabling DRI\n"); - DRICloseScreen(pScreen); - return FALSE; + if (!pI830->use_drm_mode) { + pI830DRI->regsSize = I830_REG_SIZE; + if (drmAddMap(pI830->drmSubFD, (drm_handle_t)pI830->MMIOAddr, + pI830DRI->regsSize, DRM_REGISTERS, 0, + (drmAddress) &pI830DRI->regs) < 0) { + xf86DrvMsg(pScreen->myNum, X_ERROR, "[drm] drmAddMap(regs) failed\n"); + DRICloseScreen(pScreen); + return FALSE; + } + xf86DrvMsg(pScreen->myNum, X_INFO, "[drm] Registers = 0x%08x\n", + (int)pI830DRI->regs); + + if (drmAddMap(pI830->drmSubFD, + (drm_handle_t)pI830->LpRing->mem->offset + pI830->LinearAddr, + pI830->LpRing->mem->size, DRM_AGP, 0, + (drmAddress) &pI830->ring_map) < 0) { + xf86DrvMsg(pScreen->myNum, X_ERROR, + "[drm] drmAddMap(ring_map) failed. Disabling DRI\n"); + DRICloseScreen(pScreen); + return FALSE; + } + xf86DrvMsg(pScreen->myNum, X_INFO, "[drm] ring buffer = 0x%08x\n", + (int)pI830->ring_map); } - xf86DrvMsg(pScreen->myNum, X_INFO, "[drm] ring buffer = 0x%08x\n", - (int)pI830->ring_map); if (!I830InitDma(pScrn)) { DRICloseScreen(pScreen); @@ -1891,22 +1898,24 @@ I830DRI2Prepare(ScreenPtr pScreen) char busId[64]; drmVersionPtr version; + if (!pI830->use_drm_mode) { #if XSERVER_LIBPCIACCESS - sprintf(busId, "pci:%04x:%02x:%02x.%d", - pI830->PciInfo->domain, pI830->PciInfo->bus, - pI830->PciInfo->dev, pI830->PciInfo->func); + sprintf(busId, "pci:%04x:%02x:%02x.%d", + pI830->PciInfo->domain, pI830->PciInfo->bus, + pI830->PciInfo->dev, pI830->PciInfo->func); #else - snprintf(busId, "PCI:%d:%d:%d", - ((pciConfigPtr) pI830->PciInfo->thisCard)->busnum, - ((pciConfigPtr) pI830->PciInfo->thisCard)->devnum, - ((pciConfigPtr) pI830->PciInfo->thisCard)->funcnum); + snprintf(busId, "PCI:%d:%d:%d", + ((pciConfigPtr) pI830->PciInfo->thisCard)->busnum, + ((pciConfigPtr) pI830->PciInfo->thisCard)->devnum, + ((pciConfigPtr) pI830->PciInfo->thisCard)->funcnum); #endif - /* Low level DRM open */ - pI830->drmSubFD = drmOpen("i915", busId); - if (pI830->drmSubFD < 0) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "[DRI2] drmOpen failed\n"); - return; + /* Low level DRM open */ + pI830->drmSubFD = drmOpen("i915", busId); + if (pI830->drmSubFD < 0) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "[DRI2] drmOpen failed\n"); + return; + } } version = drmGetVersion(pI830->drmSubFD); @@ -1930,7 +1939,11 @@ I830DRI2Prepare(ScreenPtr pScreen) xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[DRI2] Opened DRM device successfully\n"); - I830InitBufMgr(pScreen); + if (pI830->drmMinor < 11) { + pI830->use_ttm_batch = FALSE; + } else + I830InitBufMgr(pScrn); + if (!pI830->use_ttm_batch) return; @@ -1991,9 +2004,11 @@ I830DRI2ScreenInit(ScreenPtr pScreen) memset(&info, 0, sizeof(info)); info.func = I915_INIT_DMA2; - info.ring_start = ring->mem->offset + pI830->LinearAddr; - info.ring_end = ring->mem->end + pI830->LinearAddr; - info.ring_size = ring->mem->size; + if (!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; + } info.mmio_offset = 0; info.sarea_priv_offset = 0; info.sarea_handle = sarea_handle; diff --git a/src/i830_driver.c b/src/i830_driver.c index 18c6a6a..f1f798f 100644 --- a/src/i830_driver.c +++ b/src/i830_driver.c @@ -178,6 +178,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" @@ -808,11 +809,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(). @@ -824,7 +826,7 @@ i830_update_front_offset(ScrnInfoPtr pScrn) */ if (!pI830->starting) { if (!pScreen->ModifyPixmapHeader(pScreen->GetScreenPixmap(pScreen), - -1, -1, -1, -1, -1, + pScrn->virtualX, pScrn->virtualY, -1, -1, pitch, (pointer)(pI830->FbBase + pScrn->fbOffset))) FatalError("Couldn't adjust screen pixmap\n"); @@ -1031,6 +1033,9 @@ i830SetHotkeyControl(ScrnInfoPtr pScrn, int mode) I830Ptr pI830 = I830PTR(pScrn); CARD8 gr18; + if (pI830->use_drm_mode) + return; + gr18 = pI830->readControl(pI830, GRX, 0x18); if (mode == HOTKEY_BIOS_SWITCH) gr18 &= ~HOTKEY_VBIOS_SWITCH_BLOCK; @@ -1039,6 +1044,154 @@ 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 + +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 +I830PreInitAddresses(ScrnInfoPtr pScrn) +{ + I830Ptr pI830 = I830PTR(pScrn); + MessageType from = X_PROBED; + int fb_bar, mmio_bar; + + if (IS_I9XX(pI830)) { + fb_bar = 2; + mmio_bar = 0; + } else { + fb_bar = 0; + mmio_bar = 1; + } + + if (pI830->pEnt->device->MemBase != 0) { + pI830->LinearAddr = pI830->pEnt->device->MemBase; + from = X_CONFIG; + } else { + pI830->LinearAddr = I810_MEMBASE (pI830->PciInfo, fb_bar); + if (pI830->LinearAddr == 0) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "No valid FB address in PCI config space\n"); + PreInitCleanup(pScrn); + return FALSE; + } + } + + xf86DrvMsg(pScrn->scrnIndex, from, "Linear framebuffer at 0x%lX\n", + (unsigned long)pI830->LinearAddr); + + if (pI830->pEnt->device->IOBase != 0) { + pI830->MMIOAddr = pI830->pEnt->device->IOBase; + from = X_CONFIG; + } else { + pI830->MMIOAddr = I810_MEMBASE (pI830->PciInfo, mmio_bar); + if (pI830->MMIOAddr == 0) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "No valid MMIO address in PCI config space\n"); + PreInitCleanup(pScrn); + return FALSE; + } + } + + xf86DrvMsg(pScrn->scrnIndex, from, "IO registers at addr 0x%lX\n", + (unsigned long)pI830->MMIOAddr); + + + if (IS_I830(pI830) || IS_845G(pI830)) { +#if XSERVER_LIBPCIACCESS + uint16_t gmch_ctrl; + struct pci_device *bridge; + + bridge = intel_host_bridge (); + pci_device_cfg_read_u16 (bridge, &gmch_ctrl, I830_GMCH_CTRL); +#else + PCITAG bridge; + CARD16 gmch_ctrl; + + bridge = pciTag(0, 0, 0); /* This is always the host bridge */ + gmch_ctrl = pciReadWord(bridge, I830_GMCH_CTRL); +#endif + if ((gmch_ctrl & I830_GMCH_MEM_MASK) == I830_GMCH_MEM_128M) { + pI830->FbMapSize = 0x8000000; + } else { + pI830->FbMapSize = 0x4000000; /* 64MB - has this been tested ?? */ + } + } else { + if (IS_I9XX(pI830)) { +#if XSERVER_LIBPCIACCESS + pI830->FbMapSize = pI830->PciInfo->regions[fb_bar].size; +#else + pI830->FbMapSize = 1UL << pciGetBaseSize(pI830->PciTag, 2, TRUE, + NULL); +#endif + } else { + /* 128MB aperture for later i8xx series. */ + pI830->FbMapSize = 0x8000000; + } + } + return TRUE; +} + +static void +I830PreInitCrtcConfig(ScrnInfoPtr pScrn) +{ + xf86CrtcConfigPtr xf86_config; + I830Ptr pI830 = I830PTR(pScrn); + int max_width, max_height; + /* 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); +} + /** * This is called per zaphod head (so usually just once) to do initialization * before the Screen is created. @@ -1049,7 +1202,6 @@ i830SetHotkeyControl(ScrnInfoPtr pScrn, int mode) static Bool I830PreInit(ScrnInfoPtr pScrn, int flags) { - xf86CrtcConfigPtr xf86_config; vgaHWPtr hwp; I830Ptr pI830; MessageType from = X_PROBED; @@ -1062,39 +1214,47 @@ I830PreInit(ScrnInfoPtr pScrn, int flags) pointer pVBEModule = NULL; const char *chipname; int num_pipe; - int max_width, max_height; uint32_t capid; - int fb_bar, mmio_bar; + 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; + if (!drm_mode_setting) { + /* 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); + + 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; + + hwp = VGAHWPTR(pScrn); + } else { + if (flags & PROBE_DETECT) + 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; - /* Allocate driverPrivate */ if (!I830GetRec(pScrn)) return FALSE; @@ -1102,6 +1262,7 @@ I830PreInit(ScrnInfoPtr pScrn, int flags) pI830 = I830PTR(pScrn); pI830->SaveGeneration = -1; pI830->pEnt = pEnt; + pI830->use_drm_mode = drm_mode_setting; pScrn->displayWidth = 640; /* default it */ @@ -1180,7 +1341,7 @@ I830PreInit(ScrnInfoPtr pScrn, int flags) if (!xf86SetDefaultVisual(pScrn, -1)) return FALSE; - hwp = VGAHWPTR(pScrn); + pI830->cpp = pScrn->bitsPerPixel / 8; pI830->preinit = TRUE; @@ -1322,261 +1483,200 @@ I830PreInit(ScrnInfoPtr pScrn, int flags) xf86DrvMsg(pScrn->scrnIndex, from, "Chipset: \"%s\"\n", (pScrn->chipset != NULL) ? pScrn->chipset : "Unknown i8xx"); - if (IS_I9XX(pI830)) - { - fb_bar = 2; - mmio_bar = 0; - } - else - { - fb_bar = 0; - mmio_bar = 1; - } - - if (pI830->pEnt->device->MemBase != 0) { - pI830->LinearAddr = pI830->pEnt->device->MemBase; - from = X_CONFIG; - } else { - pI830->LinearAddr = I810_MEMBASE (pI830->PciInfo, fb_bar); - if (pI830->LinearAddr == 0) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "No valid FB address in PCI config space\n"); - PreInitCleanup(pScrn); - return FALSE; - } - } - - xf86DrvMsg(pScrn->scrnIndex, from, "Linear framebuffer at 0x%lX\n", - (unsigned long)pI830->LinearAddr); - - if (pI830->pEnt->device->IOBase != 0) { - pI830->MMIOAddr = pI830->pEnt->device->IOBase; - from = X_CONFIG; - } else { - pI830->MMIOAddr = I810_MEMBASE (pI830->PciInfo, mmio_bar); - if (pI830->MMIOAddr == 0) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "No valid MMIO address in PCI config space\n"); - PreInitCleanup(pScrn); - return FALSE; - } - } - - xf86DrvMsg(pScrn->scrnIndex, from, "IO registers at addr 0x%lX\n", - (unsigned long)pI830->MMIOAddr); - - /* 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); - - if (IS_I830(pI830) || IS_845G(pI830)) { -#if XSERVER_LIBPCIACCESS - uint16_t gmch_ctrl; - struct pci_device *bridge; + /* XXX This should go away, replaced by xf86Crtc.c support for it */ + pI830->rotation = RR_Rotate_0; - bridge = intel_host_bridge (); - pci_device_cfg_read_u16 (bridge, &gmch_ctrl, I830_GMCH_CTRL); -#else - PCITAG bridge; - CARD16 gmch_ctrl; + if (!pI830->use_drm_mode) { + Bool ret; - bridge = pciTag(0, 0, 0); /* This is always the host bridge */ - gmch_ctrl = pciReadWord(bridge, I830_GMCH_CTRL); -#endif - if ((gmch_ctrl & I830_GMCH_MEM_MASK) == I830_GMCH_MEM_128M) { - pI830->FbMapSize = 0x8000000; - } else { - pI830->FbMapSize = 0x4000000; /* 64MB - has this been tested ?? */ - } - } else { - if (IS_I9XX(pI830)) { -#if XSERVER_LIBPCIACCESS - pI830->FbMapSize = pI830->PciInfo->regions[fb_bar].size; -#else - pI830->FbMapSize = 1UL << pciGetBaseSize(pI830->PciTag, 2, TRUE, - NULL); -#endif - } else { - /* 128MB aperture for later i8xx series. */ - pI830->FbMapSize = 0x8000000; - } - } + ret = I830PreInitAddresses(pScrn); + if (ret == FALSE) + return ret; - /* Some of the probing needs MMIO access, so map it here. */ - I830MapMMIO(pScrn); + I830PreInitCrtcConfig(pScrn); - if (pI830->debug_modes) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Hardware state on X startup:\n"); - i830DumpRegs (pScrn); - } + /* 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); + } - i830TakeRegSnapshot(pScrn); + i830TakeRegSnapshot(pScrn); #if 1 - pI830->saveSWF0 = INREG(SWF0); - pI830->saveSWF4 = INREG(SWF4); - pI830->swfSaved = TRUE; - - /* Set "extended desktop" */ - OUTREG(SWF0, pI830->saveSWF0 | (1 << 21)); - - /* Set "driver loaded", "OS unknown", "APM 1.2" */ - OUTREG(SWF4, (pI830->saveSWF4 & ~((3 << 19) | (7 << 16))) | - (1 << 23) | (2 << 16)); -#endif - - 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->noAccel = TRUE; - } - - /* - * 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->noAccel) { + pI830->saveSWF0 = INREG(SWF0); + pI830->saveSWF4 = INREG(SWF4); + pI830->swfSaved = TRUE; + + /* Set "extended desktop" */ + OUTREG(SWF0, pI830->saveSWF0 | (1 << 21)); + + /* Set "driver loaded", "OS unknown", "APM 1.2" */ + OUTREG(SWF4, (pI830->saveSWF4 & ~((3 << 19) | (7 << 16))) | + (1 << 23) | (2 << 16)); +#endif + + 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->noAccel = TRUE; + } + + /* + * 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->noAccel) { #ifdef I830_USE_EXA - pI830->useEXA = TRUE; + pI830->useEXA = TRUE; #else - pI830->useEXA = FALSE; + pI830->useEXA = FALSE; #endif #if defined(I830_USE_XAA) && defined(I830_USE_EXA) - int from = X_DEFAULT; - if ((s = (char *)xf86GetOptValString(pI830->Options, - OPTION_ACCELMETHOD))) { - if (!xf86NameCmp(s, "EXA")) { - from = X_CONFIG; - pI830->useEXA = TRUE; - } - else if (!xf86NameCmp(s, "XAA")) { - from = X_CONFIG; - pI830->useEXA = FALSE; + int from = X_DEFAULT; + if ((s = (char *)xf86GetOptValString(pI830->Options, + OPTION_ACCELMETHOD))) { + if (!xf86NameCmp(s, "EXA")) { + from = X_CONFIG; + pI830->useEXA = TRUE; + } + else if (!xf86NameCmp(s, "XAA")) { + from = X_CONFIG; + pI830->useEXA = FALSE; + } } - } #endif - xf86DrvMsg(pScrn->scrnIndex, from, "Using %s for acceleration\n", - pI830->useEXA ? "EXA" : "XAA"); - } - - if (xf86ReturnOptValBool(pI830->Options, OPTION_SW_CURSOR, FALSE)) { - pI830->SWCursor = TRUE; - } + xf86DrvMsg(pScrn->scrnIndex, from, "Using %s for acceleration\n", + pI830->useEXA ? "EXA" : "XAA"); + } + + if (xf86ReturnOptValBool(pI830->Options, OPTION_SW_CURSOR, FALSE)) { + pI830->SWCursor = TRUE; + } - pI830->directRenderingDisabled = - !xf86ReturnOptValBool(pI830->Options, OPTION_DRI, TRUE); + pI830->directRenderingDisabled = + !xf86ReturnOptValBool(pI830->Options, OPTION_DRI, TRUE); #if defined(XF86DRI) || defined(DRI2) - if (!pI830->directRenderingDisabled) { - if (pI830->noAccel || 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; - + if (!pI830->directRenderingDisabled) { + if (pI830->noAccel || 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; - } - } + 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 + + 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); - 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; + /* + * 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); + + } else { +#ifdef XF86DRM_MODE + char *bus_id; + 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; + } - 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->drmmode.create_new_fb = i830_create_new_fb; - pI830->stolen_size = I830DetectMemory(pScrn); + pI830->drmSubFD = pI830->drmmode.fd; + xfree(bus_id); + + pI830->useEXA = TRUE; + pI830->directRenderingDisabled = FALSE; + pI830->allocate_classic_textures = FALSE; + I830InitBufMgr(pScrn); +#endif + } + pI830->XvDisabled = - !xf86ReturnOptValBool(pI830->Options, OPTION_XVIDEO, TRUE); - + !xf86ReturnOptValBool(pI830->Options, OPTION_XVIDEO, TRUE); + #ifdef I830_XV - if (xf86GetOptValInteger(pI830->Options, OPTION_VIDEO_KEY, - &(pI830->colorKey))) { + if (xf86GetOptValInteger(pI830->Options, OPTION_VIDEO_KEY, + &(pI830->colorKey))) { from = X_CONFIG; } else if (xf86GetOptValInteger(pI830->Options, OPTION_COLOR_KEY, &(pI830->colorKey))) { @@ -1720,21 +1820,23 @@ I830PreInit(ScrnInfoPtr pScrn, int flags) xf86LoaderReqSymLists(I810ramdacSymbols, NULL); } - i830CompareRegsToSnapshot(pScrn, "After PreInit"); + if (!pI830->use_drm_mode) { + i830CompareRegsToSnapshot(pScrn, "After PreInit"); - I830UnmapMMIO(pScrn); + I830UnmapMMIO(pScrn); - /* 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); + /* 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); #if 0 - if (I830IsPrimary(pScrn)) { - vbeFree(pI830->pVbe); - } - pI830->pVbe = NULL; + if (I830IsPrimary(pScrn)) { + vbeFree(pI830->pVbe); + } + pI830->pVbe = NULL; #endif + } #if defined(XF86DRI) /* Load the dri module if requested. */ @@ -1748,7 +1850,8 @@ I830PreInit(ScrnInfoPtr pScrn, int flags) #if defined(DRI2) /* Load the dri2 module if requested. */ - if (xf86DRI2Enabled() && !pI830->directRenderingDisabled) { + if (xf86ReturnOptValBool(pI830->Options, OPTION_DRI2, FALSE) && + !pI830->directRenderingDisabled) { xf86LoadSubModule(pScrn, "dri2"); } #endif @@ -2383,7 +2486,9 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) pScrn = xf86Screens[pScreen->myNum]; pI830 = I830PTR(pScrn); - hwp = VGAHWPTR(pScrn); + + if (!pI830->use_drm_mode) + hwp = VGAHWPTR(pScrn); pScrn->displayWidth = (pScrn->virtualX + 63) & ~63; @@ -2429,53 +2534,79 @@ 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 + uint64_t size; + int ret; + ret = drmMMInfo(pI830->drmSubFD, DRM_BO_MEM_VRAM, &size); + if (ret) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Kernel memory manager has no VRAM allocation\n"); + return FALSE; + } + pI830->stolen_size = size * GTT_PAGE_SIZE; + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Kernel stolen allocator is %dkb\n", pI830->stolen_size / KB(1)); + + ret = drmMMInfo(pI830->drmSubFD, DRM_BO_MEM_TT, &size); + if (ret) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Kernel memory manager has no TT allocation\n"); + return FALSE; + } + pScrn->videoRam = (size * GTT_PAGE_SIZE) / KB(1); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Kernel AGP allocator is %dkb\n", pScrn->videoRam); +#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); - } - } + /* 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); + } + } + } - /* 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; + /* 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; + } } pI830->directRendering = DRI_TYPE_NONE; #ifdef DRI2 - if (xf86DRI2Enabled()) + if (xf86ReturnOptValBool(pI830->Options, OPTION_DRI2, FALSE)) I830DRI2Prepare(pScreen); #endif @@ -2520,6 +2651,8 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) return FALSE; } + pI830->batch = intelddx_batchbuffer_alloc(pScrn); + xf86DrvMsg(pScrn->scrnIndex, pI830->pEnt->device->videoRam ? X_CONFIG : X_DEFAULT, "VideoRam: %d KB\n", pScrn->videoRam); @@ -2558,6 +2691,10 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) pI830->fb_compression = FALSE; } +#ifdef XF86DRM_MODE + pI830->fb_compression = FALSE; +#endif + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Framebuffer compression %sabled\n", pI830->fb_compression ? "en" : "dis"); xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Tiling %sabled\n", pI830->tiling ? @@ -2585,12 +2722,14 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) pI8301 = I830PTR(pI830->entityPrivate->pScrn_1); pI830->LpRing = pI8301->LpRing; pI830->overlay_regs = pI8301->overlay_regs; + pI830->overlay_regs_bo = pI8301->overlay_regs_bo; pI830->overlayOn = pI8301->overlayOn; pI830->last_3d = pI8301->last_3d; } /* Need MMIO mapped to do GTT lookups during memory allocation. */ - I830MapMMIO(pScrn); + if (!pI830->use_drm_mode) + I830MapMMIO(pScrn); #if defined(XF86DRI) || defined(DRI2) /* @@ -2781,7 +2920,7 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) pI830->XvEnabled = FALSE; #endif - if (!pI830->noAccel) { + if (!pI830->noAccel && !pI830->use_drm_mode) { if (pI830->LpRing->mem->size == 0) { xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Disabling acceleration because the ring buffer " @@ -2797,7 +2936,7 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) "needs 2D acceleration.\n"); pI830->XvEnabled = FALSE; } - if (!IS_I9XX(pI830) && pI830->overlay_regs == NULL) { + if (!IS_I9XX(pI830) && pI830->overlay_regs == NULL && pI830->overlay_regs_bo == NULL) { xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Disabling Xv because the overlay register buffer " "allocation failed.\n"); @@ -2834,30 +2973,32 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) if (pI830->directRendering == DRI_TYPE_NONE) i830_free_3d_memory(pScrn); - config = XF86_CRTC_CONFIG_PTR(pScrn); + if (!pI830->use_drm_mode) { + 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_IGD_GM(pI830) && - (pI830->directRendering == DRI_TYPE_NONE || - (pI830->directRendering == DRI_TYPE_XF86DRI && pI830->drmMinor >= 10) || - (pI830->directRendering == DRI_TYPE_DRI2))) { - 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; - } + /* + * 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_IGD_GM(pI830) && + (pI830->directRendering == DRI_TYPE_NONE || + (pI830->directRendering == DRI_TYPE_XF86DRI && pI830->drmMinor >= 10) || + (pI830->directRendering == DRI_TYPE_DRI2))) { + 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; + } + } } #endif @@ -2867,11 +3008,13 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) 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; @@ -2882,12 +3025,13 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) pI830->xoffset = (pScrn->fbOffset / pI830->cpp) % pScrn->displayWidth; pI830->yoffset = (pScrn->fbOffset / pI830->cpp) / pScrn->displayWidth; - vgaHWSetMmioFuncs(hwp, pI830->MMIOBase, 0); - vgaHWGetIOBase(hwp); - DPRINTF(PFX, "assert( if(!vgaHWMapMem(pScrn)) )\n"); - if (!vgaHWMapMem(pScrn)) - return FALSE; - + if (!pI830->use_drm_mode) { + vgaHWSetMmioFuncs(hwp, pI830->MMIOBase, 0); + vgaHWGetIOBase(hwp); + DPRINTF(PFX, "assert( if(!vgaHWMapMem(pScrn)) )\n"); + if (!vgaHWMapMem(pScrn)) + return FALSE; + } DPRINTF(PFX, "assert( if(!I830EnterVT(scrnIndex, 0)) )\n"); if (!pI830->useEXA) { @@ -3025,7 +3169,7 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) } #endif -#if !defined(XF86DRI) || !defined(DRI2) +#if !defined(XF86DRI) && !defined(DRI2) xf86DrvMsg(pScrn->scrnIndex, X_INFO, "direct rendering: Not available\n"); #endif @@ -3037,7 +3181,7 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) if (serverGeneration == 1) xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options); - if (IS_I965G(pI830)) { + if (!pI830->use_drm_mode && IS_I965G(pI830)) { /* turn off clock gating */ #if 0 OUTREG(0x6204, 0x70804000); @@ -3126,9 +3270,11 @@ I830LeaveVT(int scrnIndex, int flags) xf86_hide_cursors (pScrn); - RestoreHWState(pScrn); - - i830_stop_ring(pScrn, TRUE); + if (!pI830->use_drm_mode) { + RestoreHWState(pScrn); + + i830_stop_ring(pScrn, TRUE); + } #if defined(XF86DRI) || defined(DRI2) /* don't disable interrupt before stopping the ring for fencing */ @@ -3136,7 +3282,7 @@ I830LeaveVT(int scrnIndex, int flags) drmCtlUninstHandler(pI830->drmSubFD); } #endif - if (pI830->debug_modes) { + if (pI830->debug_modes && !pI830->use_drm_mode) { i830CompareRegsToSnapshot(pScrn, "After LeaveVT"); i830DumpRegs (pScrn); } @@ -3148,7 +3294,7 @@ I830LeaveVT(int scrnIndex, int flags) * allocations until we relese the lock. */ #ifdef XF86DRI_MM - if (pI830->directRenderingOpen) { + if (pI830->directRenderingOpen && !pI830->use_drm_mode) { if (pI830->memory_manager != NULL && pScrn->vtSema) { drmMMLock(pI830->drmSubFD, DRM_BO_MEM_TT, 1, 0); } @@ -3178,7 +3324,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; @@ -3188,7 +3335,7 @@ I830EnterVT(int scrnIndex, int flags) /* Unlock the memory manager first of all so that we can pin our * buffer objects */ - if (pI830->memory_manager != NULL && pScrn->vtSema) { + if (pI830->memory_manager != NULL && pScrn->vtSema && !pI830->use_drm_mode) { drmMMUnlock(pI830->drmSubFD, DRM_BO_MEM_TT, 1); } } @@ -3203,34 +3350,39 @@ I830EnterVT(int scrnIndex, int flags) /* Update the screen pixmap in case the buffer moved */ i830_update_front_offset(pScrn); - if (i830_check_error_state(pScrn)) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Existing errors found in hardware state.\n"); - } + if (!pI830->use_drm_mode) { + if (i830_check_error_state(pScrn)) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Existing errors found in hardware state.\n"); + } + + i830_stop_ring(pScrn, FALSE); + SetHWOperatingState(pScrn); - i830_stop_ring(pScrn, FALSE); - SetHWOperatingState(pScrn); - /* Clear the framebuffer */ - memset(pI830->FbBase + pScrn->fbOffset, 0, - pScrn->virtualY * pScrn->displayWidth * pI830->cpp); + /* Clear the framebuffer */ + memset(pI830->FbBase + pScrn->fbOffset, 0, + pScrn->virtualY * pScrn->displayWidth * pI830->cpp); - for (o = 0; o < config->num_output; o++) { - xf86OutputPtr output = config->output[o]; - output->funcs->dpms(output, DPMSModeOff); + for (o = 0; o < config->num_output; o++) { + xf86OutputPtr output = config->output[o]; + output->funcs->dpms(output, DPMSModeOff); + } } if (!xf86SetDesiredModes (pScrn)) return FALSE; - - if (pI830->debug_modes) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Hardware state at EnterVT:\n"); - i830DumpRegs (pScrn); - } - i830DescribeOutputConfiguration(pScrn); - i830_stop_ring(pScrn, TRUE); - SetHWOperatingState(pScrn); + if (!pI830->use_drm_mode) { + if (pI830->debug_modes) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Hardware state at EnterVT:\n"); + i830DumpRegs (pScrn); + } + i830DescribeOutputConfiguration(pScrn); + + i830_stop_ring(pScrn, TRUE); + SetHWOperatingState(pScrn); + } #ifdef DRI2 if (pI830->directRendering == DRI_TYPE_DRI2) { @@ -3252,9 +3404,11 @@ I830EnterVT(int scrnIndex, int flags) if (!pI830->starting) { I830DRIResume(screenInfo.screens[scrnIndex]); - i830_refresh_ring(pScrn); - I830Sync(pScrn); - DO_RING_IDLE(); + if (!pI830->use_drm_mode) { + i830_refresh_ring(pScrn); + I830Sync(pScrn); + DO_RING_IDLE(); + } DPRINTF(PFX, "calling dri unlock\n"); I830DRIUnlock(pScrn); @@ -3295,9 +3449,11 @@ I830EnterVT(int scrnIndex, int flags) I830DRIResume(screenInfo.screens[scrnIndex]); - i830_refresh_ring(pScrn); - I830Sync(pScrn); - DO_RING_IDLE(); + if (!pI830->use_drm_mode) { + i830_refresh_ring(pScrn); + I830Sync(pScrn); + DO_RING_IDLE(); + } sarea->texAge++; for(i = 0; i < I830_NR_TEX_REGIONS+1 ; i++) @@ -3366,9 +3522,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 2d916b4..3d60f51 100644 --- a/src/i830_exa.c +++ b/src/i830_exa.c @@ -489,8 +489,6 @@ static Bool I830EXAPrepareAccess(PixmapPtr pPix, int index) if (!driver_priv) return FALSE; - dri2Lock(pPix); - if (driver_priv->bo) { mmDebug("mapping %p %d %dx%d\n", pPix, driver_priv->flags, pPix->drawable.width, pPix->drawable.height); @@ -499,17 +497,15 @@ static Bool I830EXAPrepareAccess(PixmapPtr pPix, int index) ret = dri_bo_map(driver_priv->bo, TRUE); if (ret) { FatalError("Failed to map pixmap: %s\n", strerror(-ret)); - goto error; + return FALSE; } pPix->devPrivate.ptr = driver_priv->bo->virtual; } - return TRUE; + dri2Lock(pPix); -error: - dri2Unlock(pPix); - return FALSE; + return TRUE; } static void I830EXAFinishAccess(PixmapPtr pPix, int index) @@ -549,18 +545,32 @@ static Bool I830EXAModifyPixmapHeader(PixmapPtr pPixmap, int width, int height, driver_priv = exaGetPixmapDriverPrivate(pPixmap); + 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(pPixmap, width, height, depth, + bitsPerPixel, devKind, NULL); + } + if (pPixData == pI830->FbBase + pScrn->fbOffset) { /* this is the front buffer pixmap so set it up as such..*/ driver_priv->flags |= I830_EXA_PIXMAP_IS_FRONTBUFFER; + ErrorF("FRONTBUFFER HANDLE CHANGING %p\n", driver_priv->bo); /* get a reference to the front buffer handle */ + if (driver_priv->bo) + dri_bo_unreference(driver_priv->bo); driver_priv->bo = intel_ttm_bo_create_from_handle(pI830->bufmgr, "front", pI830->front_buffer->bo.handle); + miModifyPixmapHeader(pPixmap, width, height, depth, bitsPerPixel, devKind, NULL); - return TRUE; } return FALSE; diff --git a/src/i830_memory.c b/src/i830_memory.c index 018a64c..4ef7e0c 100644 --- a/src/i830_memory.c +++ b/src/i830_memory.c @@ -172,14 +172,13 @@ i830_bind_memory(ScrnInfoPtr pScrn, i830_memory *mem) else flags |= DRM_BO_FLAG_MEM_TT; - flags |= DRM_BO_FLAG_NO_EVICT; + //flags |= DRM_BO_FLAG_NO_EVICT; ret = drmBOSetStatus(pI830->drmSubFD, &mem->bo, flags, DRM_BO_MASK_MEM | DRM_BO_FLAG_READ | - DRM_BO_FLAG_WRITE | - DRM_BO_FLAG_NO_EVICT, + DRM_BO_FLAG_WRITE, 0, 0, 0); if (ret != 0) return FALSE; @@ -203,16 +202,18 @@ 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); } - /* Mark the pages accessible now that they're bound. */ - if (mprotect(pI830->FbBase + mem->offset, ALIGN(mem->size, GTT_PAGE_SIZE), - PROT_READ | PROT_WRITE) != 0) { + if (!pI830->use_drm_mode) { + /* Mark the pages accessible now that they're bound. */ + if (mprotect(pI830->FbBase + mem->offset, ALIGN(mem->size, GTT_PAGE_SIZE), + PROT_READ | PROT_WRITE) != 0) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to mprotect %s: %s\n", mem->name, strerror(errno)); + } } return TRUE; @@ -227,13 +228,15 @@ i830_unbind_memory(ScrnInfoPtr pScrn, i830_memory *mem) return TRUE; /* Mark the pages accessible now that they're bound. */ - if (mprotect(pI830->FbBase + mem->offset, ALIGN(mem->size, GTT_PAGE_SIZE), - PROT_NONE) != 0) { + if (!pI830->use_drm_mode) { + if (mprotect(pI830->FbBase + mem->offset, ALIGN(mem->size, GTT_PAGE_SIZE), + PROT_NONE) != 0) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to mprotect %s: %s\n", mem->name, strerror(errno)); + } } - if (mem->tiling != TILE_NONE) + if (mem->tiling != TILE_NONE && !pI830->use_drm_mode) i830_clear_tiling(pScrn, mem->fence_nr); #ifdef XF86DRI_MM @@ -242,7 +245,7 @@ i830_unbind_memory(ScrnInfoPtr pScrn, i830_memory *mem) int ret; ret = drmBOSetStatus(pI830->drmSubFD, &mem->bo, - 0, DRM_BO_FLAG_NO_EVICT, + 0, 0, 0, 0, 0); if (ret == 0) { @@ -357,6 +360,7 @@ i830_reset_allocations(ScrnInfoPtr pScrn) pI830->exa_offscreen = NULL; pI830->exa_965_state = NULL; pI830->overlay_regs = NULL; + pI830->overlay_regs_bo = NULL; #ifdef XF86DRI pI830->back_buffer = NULL; pI830->third_buffer = NULL; @@ -492,16 +496,18 @@ i830_allocator_init(ScrnInfoPtr pScrn, unsigned long offset, unsigned long size) if (pI830->memory_manager != NULL) { int ret; - /* Tell the kernel to manage it */ - ret = drmMMInit(pI830->drmSubFD, - pI830->memory_manager->offset / GTT_PAGE_SIZE, - pI830->memory_manager->size / GTT_PAGE_SIZE, - DRM_BO_MEM_TT); - if (ret != 0) { + if (!pI830->use_drm_mode) { + /* Tell the kernel to manage it */ + ret = drmMMInit(pI830->drmSubFD, + pI830->memory_manager->offset / GTT_PAGE_SIZE, + pI830->memory_manager->size / GTT_PAGE_SIZE, + DRM_BO_MEM_TT); + 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; + } } } else { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, @@ -526,9 +532,10 @@ i830_allocator_fini(ScrnInfoPtr pScrn) #ifdef XF86DRI_MM /* The memory manager is more special */ if (pI830->memory_manager) { - drmMMTakedown(pI830->drmSubFD, DRM_BO_MEM_TT); - i830_free_memory(pScrn, pI830->memory_manager); - pI830->memory_manager = NULL; + if (!pI830->use_drm_mode) + drmMMTakedown(pI830->drmSubFD, DRM_BO_MEM_TT); + i830_free_memory(pScrn, pI830->memory_manager); + pI830->memory_manager = NULL; } #endif /* XF86DRI_MM */ @@ -845,8 +852,8 @@ i830_allocate_memory(ScrnInfoPtr pScrn, const char *name, #ifdef XF86DRI_MM 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 @@ -1051,6 +1058,24 @@ i830_allocate_overlay(ScrnInfoPtr pScrn) if (!OVERLAY_NOPHYSICAL(pI830)) flags |= NEED_PHYSICAL_ADDR; + if (pI830->use_ttm_batch) { + int mem_space = DRM_BO_FLAG_MEM_TT; + + if (flags & NEED_PHYSICAL_ADDR) + if (pI830->use_drm_mode) + mem_space = DRM_BO_FLAG_MEM_VRAM; + + /* allocate overlay regs from bufmgr */ + pI830->overlay_regs_bo = dri_bo_alloc(pI830->bufmgr,"overlay regs", + OVERLAY_SIZE, GTT_PAGE_SIZE, + mem_space | DRM_BO_FLAG_CACHED | DRM_BO_FLAG_CACHED_MAPPED); + if (pI830->overlay_regs_bo == NULL) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Failed to allocate Overlay register space.\n"); + } + return TRUE; + } + if (!IS_I965G(pI830)) { pI830->overlay_regs = i830_allocate_memory(pScrn, "overlay registers", OVERLAY_SIZE, GTT_PAGE_SIZE, @@ -1139,7 +1164,8 @@ 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; @@ -1208,6 +1234,9 @@ i830_allocate_framebuffer(ScrnInfoPtr pScrn, I830Ptr pI830, BoxPtr FbMemBox, 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 */ @@ -1232,8 +1261,12 @@ i830_allocate_framebuffer(ScrnInfoPtr pScrn, I830Ptr pI830, BoxPtr FbMemBox, return NULL; } - if (pI830->FbBase) - memset (pI830->FbBase + front_buffer->offset, 0, size); + if (pI830->use_drm_mode) { +#ifdef XF86DRM_MODE + 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; } @@ -1242,10 +1275,13 @@ 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 @@ -1358,18 +1394,20 @@ i830_allocate_2d_memory(ScrnInfoPtr pScrn) unsigned int pitch = pScrn->displayWidth * pI830->cpp; long size; - if (!pI830->StolenOnly && - (!xf86AgpGARTSupported() || !xf86AcquireGART(pScrn->scrnIndex))) { + 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); @@ -1930,14 +1968,16 @@ 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)) + if (!pI830->use_drm_mode) { + if (!xf86AcquireGART(pScrn->scrnIndex)) return FALSE; - - pI830->gtt_acquired = TRUE; + + pI830->gtt_acquired = TRUE; + } for (mem = pI830->memory_list->next; mem->next != NULL; mem = mem->next) @@ -1954,7 +1994,7 @@ i830_bind_all_memory(ScrnInfoPtr pScrn) } #endif } - if (!pI830->SWCursor) + if (!pI830->SWCursor && !pI830->use_drm_mode) i830_update_cursor_offsets(pScrn); return TRUE; @@ -1969,7 +2009,7 @@ 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; @@ -1987,10 +2027,12 @@ i830_unbind_all_memory(ScrnInfoPtr pScrn) } #endif - pI830->gtt_acquired = FALSE; - - if (!xf86ReleaseGART(pScrn->scrnIndex)) + if (!pI830->use_drm_mode) { + pI830->gtt_acquired = FALSE; + + if (!xf86ReleaseGART(pScrn->scrnIndex)) return FALSE; + } } return TRUE; @@ -2018,3 +2060,110 @@ I830CheckAvailableMemory(ScrnInfoPtr pScrn) return maxPages * 4; } + +#ifdef XF86DRI_MM +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, maxCacheLines; + 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->useEXA && 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; +} + +uint32_t i830_create_new_fb(ScrnInfoPtr pScrn, int width, int height, int *pitch) +{ + 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 %08x, new front size %08x\n", old_buffer->bo.size, pI830->front_buffer->bo.size); + ErrorF("old front offset %08x, new front offset %08x\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 diff --git a/src/i830_video.c b/src/i830_video.c index dc7c773..feb86c1 100644 --- a/src/i830_video.c +++ b/src/i830_video.c @@ -75,6 +75,7 @@ #include "dixstruct.h" #include "fourcc.h" +#include "i915_drm.h" #ifndef USE_USLEEP_FOR_VIDEO #define USE_USLEEP_FOR_VIDEO 0 #endif @@ -320,6 +321,86 @@ typedef struct { #define I830OVERLAYREG(pI830) ((I830OverlayRegPtr)\ ((pI830)->FbBase + \ (pI830)->overlay_regs->offset)) + +static I830OverlayRegPtr overlay_reg_prepare(I830Ptr pI830) +{ + if (pI830->use_ttm_batch) { + dri_bo_map(pI830->overlay_regs_bo, 1); + return pI830->overlay_regs_bo->virtual; + } else { + return I830OVERLAYREG(pI830); + } +} + +static void overlay_reg_finish(I830Ptr pI830) +{ + if (!pI830->use_ttm_batch) + return; + + dri_bo_unmap(pI830->overlay_regs_bo); + +} + +static void *i830_video_alloc_buf(ScrnInfoPtr pScrn, int size) +{ + I830Ptr pI830 = I830PTR(pScrn); + if (pI830->use_ttm_batch) { + return dri_bo_alloc(pI830->bufmgr, "xv surfaces", + size, GTT_PAGE_SIZE, + DRM_BO_FLAG_MEM_LOCAL | DRM_BO_FLAG_CACHED | DRM_BO_FLAG_CACHED_MAPPED); + + } else { + return i830_allocate_memory(pScrn, "xv surface buffer", size, 16, 0); + } +} + +static void i830_video_free_buf(ScrnInfoPtr pScrn, void *buf) +{ + I830Ptr pI830 = I830PTR(pScrn); + if (pI830->use_ttm_batch) { + dri_bo_unreference((dri_bo *)buf); + } else { + i830_free_memory(pScrn, (i830_memory *)buf); + } +} + +static void *i830_video_map_buf(I830Ptr pI830, I830PortPrivPtr pPriv) +{ + void *ret; + + if (pI830->use_ttm_batch) { + dri_bo_map((dri_bo *)pPriv->buf, 1); + ret = ((dri_bo *)pPriv->buf)->virtual; + } else { + ret = pI830->FbBase; + } + + return ret; +} + +static void i830_video_unmap_buf(I830Ptr pI830, I830PortPrivPtr pPriv) +{ + if (pI830->use_ttm_batch) + dri_bo_unmap((dri_bo *)pPriv->buf); +} + +static uint32_t video_read_dovsta(I830Ptr pI830) +{ + uint32_t result; + if (!pI830->MMIOBase) { + struct drm_i915_mmio io = { + .read_write = I915_MMIO_READ, + .reg = MMIO_REGS_DOVSTA, + .data = &result + }; + + drmCommandWriteRead(pI830->drmSubFD, DRM_I915_MMIO, &io, sizeof(io)); + } else { + result = INREG(DOVSTA); + } + return result; +} + #if VIDEO_DEBUG static void CompareOverlay(I830Ptr pI830, CARD32 * overlay, int size) @@ -352,6 +433,9 @@ i830_overlay_switch_to_crtc (ScrnInfoPtr pScrn, xf86CrtcPtr crtc) I830CrtcPrivatePtr intel_crtc = crtc->driver_private; int pipeconf_reg = intel_crtc->pipe == 0 ? PIPEACONF : PIPEBCONF; + if (pI830->use_drm_mode) + return; + if (INREG(pipeconf_reg) & PIPEACONF_DOUBLE_WIDE) pPriv->overlayOK = FALSE; else @@ -404,13 +488,14 @@ static void i830_overlay_on(ScrnInfoPtr pScrn) { I830Ptr pI830 = I830PTR(pScrn); - I830OverlayRegPtr overlay = I830OVERLAYREG(pI830); + I830OverlayRegPtr overlay; I830PortPrivPtr pPriv = pI830->adaptor->pPortPrivates[0].ptr; Bool deactivate = FALSE; if (*pI830->overlayOn) return; + overlay = overlay_reg_prepare(pI830); /* * On I830, if pipe A is off when the overlayis enabled, it will fail to * turn on and blank the entire screen or lock up the ring. Light up pipe @@ -420,14 +505,21 @@ i830_overlay_on(ScrnInfoPtr pScrn) deactivate = i830_pipe_a_require_activate (pScrn); overlay->OCMD &= ~OVERLAY_ENABLE; + + overlay_reg_finish(pI830); BEGIN_BATCH(6); OUT_BATCH(MI_FLUSH | MI_WRITE_DIRTY_STATE); OUT_BATCH(MI_NOOP); OUT_BATCH(MI_OVERLAY_FLIP | MI_OVERLAY_FLIP_ON); - if (OVERLAY_NOPHYSICAL(pI830)) { - OUT_BATCH(pI830->overlay_regs->offset | OFC_UPDATE); + + if (pI830->use_ttm_batch) { + OUT_RELOC(pI830->overlay_regs_bo, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_READ, OFC_UPDATE); } else { - OUT_BATCH(pI830->overlay_regs->bus_addr | OFC_UPDATE); + if (OVERLAY_NOPHYSICAL(pI830)) { + OUT_BATCH(pI830->overlay_regs->offset | OFC_UPDATE); + } else { + OUT_BATCH(pI830->overlay_regs->bus_addr | OFC_UPDATE); + } } /* Wait for the overlay to light up before attempting to use it */ OUT_BATCH(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP); @@ -443,35 +535,41 @@ i830_overlay_on(ScrnInfoPtr pScrn) i830_pipe_a_require_deactivate (pScrn); OVERLAY_DEBUG("overlay_on\n"); + *pI830->overlayOn = TRUE; + overlay = overlay_reg_prepare(pI830); overlay->OCMD |= OVERLAY_ENABLE; + overlay_reg_finish(pI830); } static void i830_overlay_continue(ScrnInfoPtr pScrn, Bool update_filter) { I830Ptr pI830 = I830PTR(pScrn); - CARD32 flip_addr; - I830OverlayRegPtr overlay = I830OVERLAYREG(pI830); + CARD32 flip_addr = 0; if (!*pI830->overlayOn) return; - if (OVERLAY_NOPHYSICAL(pI830)) - flip_addr = pI830->overlay_regs->offset; - else - flip_addr = pI830->overlay_regs->bus_addr; + if (!pI830->use_ttm_batch) { + if (OVERLAY_NOPHYSICAL(pI830)) + flip_addr = pI830->overlay_regs->offset; + else + flip_addr = pI830->overlay_regs->bus_addr; + } if (update_filter) flip_addr |= OFC_UPDATE; - OVERLAY_DEBUG ("overlay_continue cmd 0x%08" CARD32_HEX - " -> 0x%08" CARD32_HEX " sta 0x%08" CARD32_HEX "\n", - overlay->OCMD, INREG(OCMD_REGISTER), INREG(DOVSTA)); + BEGIN_BATCH(4); OUT_BATCH(MI_FLUSH | MI_WRITE_DIRTY_STATE); OUT_BATCH(MI_NOOP); OUT_BATCH(MI_OVERLAY_FLIP | MI_OVERLAY_FLIP_CONTINUE); - OUT_BATCH(flip_addr); + if (pI830->use_ttm_batch) { + OUT_RELOC(pI830->overlay_regs_bo, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_READ, flip_addr); + } else { + OUT_BATCH(flip_addr); + } ADVANCE_BATCH(); OVERLAY_DEBUG("overlay_continue\n"); } @@ -480,7 +578,7 @@ static void i830_overlay_off(ScrnInfoPtr pScrn) { I830Ptr pI830 = I830PTR(pScrn); - I830OverlayRegPtr overlay = I830OVERLAYREG(pI830); + I830OverlayRegPtr overlay; if (!*pI830->overlayOn) return; @@ -504,18 +602,22 @@ i830_overlay_off(ScrnInfoPtr pScrn) * Turn overlay off */ { + overlay = overlay_reg_prepare(pI830); overlay->OCMD &= ~OVERLAY_ENABLE; - OVERLAY_DEBUG ("overlay_off cmd 0x%08" CARD32_HEX - " -> 0x%08" CARD32_HEX " sta 0x%08" CARD32_HEX "\n", - overlay->OCMD, INREG(OCMD_REGISTER), INREG(DOVSTA)); + overlay_reg_finish(pI830); + BEGIN_BATCH(6); OUT_BATCH(MI_FLUSH | MI_WRITE_DIRTY_STATE); OUT_BATCH(MI_NOOP); OUT_BATCH(MI_OVERLAY_FLIP | MI_OVERLAY_FLIP_CONTINUE); - if (OVERLAY_NOPHYSICAL(pI830)) { - OUT_BATCH(pI830->overlay_regs->offset); + if (pI830->use_ttm_batch) { + OUT_RELOC(pI830->overlay_regs_bo, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_READ, 0); } else { - OUT_BATCH(pI830->overlay_regs->bus_addr); + if (OVERLAY_NOPHYSICAL(pI830)) { + OUT_BATCH(pI830->overlay_regs->offset); + } else { + OUT_BATCH(pI830->overlay_regs->bus_addr); + } } OUT_BATCH(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP); OUT_BATCH(MI_NOOP); @@ -584,7 +686,7 @@ I830InitVideo(ScreenPtr pScreen) /* Set up overlay video if we can do it at this depth. */ if (!IS_I965G(pI830) && pScrn->bitsPerPixel != 8 && - pI830->overlay_regs != NULL) + (pI830->overlay_regs != NULL || pI830->overlay_regs_bo != NULL)) { overlayAdaptor = I830SetupImageVideoOverlay(pScreen); if (overlayAdaptor != NULL) { @@ -608,14 +710,14 @@ I830ResetVideo(ScrnInfoPtr pScrn) { I830Ptr pI830 = I830PTR(pScrn); I830PortPrivPtr pPriv = pI830->adaptor->pPortPrivates[0].ptr; - I830OverlayRegPtr overlay = I830OVERLAYREG(pI830); + I830OverlayRegPtr overlay; OVERLAY_DEBUG("I830ResetVideo: base: %p, offset: 0x%lx, obase: %p\n", pI830->FbBase, pI830->overlay_regs->offset, overlay); /* * Default to maximum image size in YV12 */ - + overlay = overlay_reg_prepare(pI830); memset(overlay, 0, sizeof(*overlay)); overlay->YRGB_VPH = 0; overlay->UV_VPH = 0; @@ -670,6 +772,7 @@ I830ResetVideo(ScrnInfoPtr pScrn) else overlay->OCONFIG |= OVERLAY_PIPE_B; + overlay_reg_finish(pI830); #if 0 /* * XXX DUMP REGISTER CODE !!! @@ -679,7 +782,7 @@ I830ResetVideo(ScrnInfoPtr pScrn) { int i; for (i = 0x30000; i < 0x31000; i += 4) - ErrorF("0x%x 0x%" PRIx32 "\n", i, INREG(i)); + ErrorF("0x%x 0x%lx\n", i, INREG(i)); } #endif } @@ -743,33 +846,41 @@ I830UpdateGamma(ScrnInfoPtr pScrn) { I830Ptr pI830 = I830PTR(pScrn); I830PortPrivPtr pPriv = pI830->adaptor->pPortPrivates[0].ptr; - CARD32 gamma0 = pPriv->gamma0; - CARD32 gamma1 = pPriv->gamma1; - CARD32 gamma2 = pPriv->gamma2; - CARD32 gamma3 = pPriv->gamma3; - CARD32 gamma4 = pPriv->gamma4; - CARD32 gamma5 = pPriv->gamma5; + CARD32 gamma[6] = { pPriv->gamma0, pPriv->gamma1, pPriv->gamma2, + pPriv->gamma3, pPriv->gamma4, pPriv->gamma5 }; #if 0 ErrorF ("Original gamma: 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx\n", gamma0, gamma1, gamma2, gamma3, gamma4, gamma5); #endif - gamma1 = I830BoundGamma (gamma1, gamma0); - gamma2 = I830BoundGamma (gamma2, gamma1); - gamma3 = I830BoundGamma (gamma3, gamma2); - gamma4 = I830BoundGamma (gamma4, gamma3); - gamma5 = I830BoundGamma (gamma5, gamma4); + gamma[1] = I830BoundGamma (gamma[1], gamma[0]); + gamma[2] = I830BoundGamma (gamma[2], gamma[1]); + gamma[3] = I830BoundGamma (gamma[3], gamma[2]); + gamma[4] = I830BoundGamma (gamma[4], gamma[3]); + gamma[5] = I830BoundGamma (gamma[5], gamma[4]); #if 0 ErrorF ("Bounded gamma: 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx\n", gamma0, gamma1, gamma2, gamma3, gamma4, gamma5); #endif - OUTREG(OGAMC5, gamma5); - OUTREG(OGAMC4, gamma4); - OUTREG(OGAMC3, gamma3); - OUTREG(OGAMC2, gamma2); - OUTREG(OGAMC1, gamma1); - OUTREG(OGAMC0, gamma0); + if (pI830->use_drm_mode) { + + struct drm_i915_mmio io = { + .read_write = I915_MMIO_WRITE, + .reg = MMIO_REGS_GAMMA, + .data = gamma + }; + drmCommandWriteRead(pI830->drmSubFD, DRM_I915_MMIO, &io, sizeof(io)); + + } else { + + OUTREG(OGAMC5, gamma[5]); + OUTREG(OGAMC4, gamma[4]); + OUTREG(OGAMC3, gamma[3]); + OUTREG(OGAMC2, gamma[2]); + OUTREG(OGAMC1, gamma[1]); + OUTREG(OGAMC0, gamma[0]); + } } static XF86VideoAdaptorPtr @@ -1038,7 +1149,8 @@ I830SetPortAttribute(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv = (I830PortPrivPtr) data; I830Ptr pI830 = I830PTR(pScrn); I830OverlayRegPtr overlay; - + int ret; + int do_continue = 0; if (pPriv->textured) { /* XXX: Currently the brightness/saturation attributes aren't hooked up. * However, apps expect them to be there, and the spec seems to let us @@ -1047,32 +1159,40 @@ I830SetPortAttribute(ScrnInfoPtr pScrn, return Success; } - overlay = I830OVERLAYREG(pI830); + overlay = overlay_reg_prepare(pI830); if (attribute == xvBrightness) { - if ((value < -128) || (value > 127)) - return BadValue; + if ((value < -128) || (value > 127)) { + ret = BadValue; + goto err; + } pPriv->brightness = value; overlay->OCLRC0 = (pPriv->contrast << 18) | (pPriv->brightness & 0xff); OVERLAY_DEBUG("BRIGHTNESS\n"); - i830_overlay_continue (pScrn, FALSE); + do_continue = 1; } else if (attribute == xvContrast) { - if ((value < 0) || (value > 255)) - return BadValue; + if ((value < 0) || (value > 255)) { + ret = BadValue; + goto err; + } pPriv->contrast = value; overlay->OCLRC0 = (pPriv->contrast << 18) | (pPriv->brightness & 0xff); OVERLAY_DEBUG("CONTRAST\n"); - i830_overlay_continue (pScrn, FALSE); + do_continue = 1; } else if (attribute == xvSaturation) { - if ((value < 0) || (value > 1023)) - return BadValue; + if ((value < 0) || (value > 1023)) { + ret = BadValue; + goto err; + } pPriv->saturation = value; overlay->OCLRC1 = pPriv->saturation; - i830_overlay_continue (pScrn, FALSE); + do_continue = 1; } else if (attribute == xvPipe) { xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); - if ((value < -1) || (value > xf86_config->num_crtc)) - return BadValue; + if ((value < -1) || (value > xf86_config->num_crtc)) { + ret = BadValue; + goto err; + } if (value < 0) pPriv->desired_crtc = NULL; else @@ -1106,17 +1226,23 @@ I830SetPortAttribute(ScrnInfoPtr pScrn, break; } OVERLAY_DEBUG("COLORKEY\n"); - i830_overlay_continue (pScrn, FALSE); + do_continue = 1; REGION_EMPTY(pScrn->pScreen, &pPriv->clip); } else if(attribute == xvDoubleBuffer) { - if ((value < 0) || (value > 1)) - return BadValue; + if ((value < 0) || (value > 1)) { + ret = BadValue; + goto err; + } /* Do not allow buffer change while playing video */ if(!*pI830->overlayOn) pPriv->doubleBuffer = value; } else return BadMatch; + overlay_reg_finish(pI830); + if (do_continue) { + i830_overlay_continue (pScrn, FALSE); + } /* Ensure that the overlay is off, ready for updating */ if ((attribute == xvGamma0 || attribute == xvGamma1 || @@ -1129,6 +1255,9 @@ I830SetPortAttribute(ScrnInfoPtr pScrn, } return Success; + err: + overlay_reg_finish(pI830); + return ret; } static int @@ -1211,7 +1340,7 @@ I830CopyPackedData(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv, dri_bo_map(pPriv->buf, TRUE); if (pPriv->currentBuf == 0) - dst = (unsigned char *) pPriv->buf->virtual + pPriv->YBuf0offset; + dst = (unsigned char *) pPriv->buf->virtual + pPriv->YBuf0offset; else dst = (unsigned char *) pPriv->buf->virtual + pPriv->YBuf1offset; @@ -1301,6 +1430,7 @@ I830CopyPlanarToPackedData(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv, int y; dri_bo_map(pPriv->buf, TRUE); + if (pPriv->currentBuf == 0) dst1 = (unsigned char *) pPriv->buf->virtual + pPriv->YBuf0offset; else @@ -1417,12 +1547,15 @@ I830CopyPlanarData(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv, break; } + i830_video_unmap_buf(pI830, pPriv); + /* Copy V data for YV12, or U data for I420 */ src2 = buf + (srcH * srcPitch) + ((top * srcPitch) >> 2) + (left >> 1); #if 0 ErrorF("src2 is %p, offset is %ld\n", src2, (unsigned long)src2 - (unsigned long)buf); #endif + dst2 = i830_video_map_buf(pI830, pPriv); if (pPriv->currentBuf == 0) { if (id == FOURCC_I420) dst2 = (unsigned char *) pPriv->buf->virtual + pPriv->UBuf0offset; @@ -1471,6 +1604,7 @@ I830CopyPlanarData(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv, } break; } + i830_video_unmap_buf(pI830, pPriv); /* Copy U data for YV12, or V data for I420 */ src3 = buf + (srcH * srcPitch) + ((srcH >> 1) * srcPitch2) + @@ -1479,16 +1613,17 @@ I830CopyPlanarData(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv, ErrorF("src3 is %p, offset is %ld\n", src3, (unsigned long)src3 - (unsigned long)buf); #endif + dst3 = i830_video_map_buf(pI830, pPriv); if (pPriv->currentBuf == 0) { if (id == FOURCC_I420) - dst3 = pI830->FbBase + pPriv->VBuf0offset; + dst3 += pPriv->VBuf0offset; else - dst3 = pI830->FbBase + pPriv->UBuf0offset; + dst3 += pPriv->UBuf0offset; } else { if (id == FOURCC_I420) - dst3 = pI830->FbBase + pPriv->VBuf1offset; + dst3 += pPriv->VBuf1offset; else - dst3 = pI830->FbBase + pPriv->UBuf1offset; + dst3 += pPriv->UBuf1offset; } switch (pPriv->rotation) { @@ -1755,7 +1890,7 @@ i830_display_video(ScrnInfoPtr pScrn, xf86CrtcPtr crtc, { I830Ptr pI830 = I830PTR(pScrn); I830PortPrivPtr pPriv = pI830->adaptor->pPortPrivates[0].ptr; - I830OverlayRegPtr overlay = I830OVERLAYREG(pI830); + I830OverlayRegPtr overlay; unsigned int swidth, swidthy, swidthuv; unsigned int mask, shift, offsety, offsetu; int tmp; @@ -1766,7 +1901,9 @@ i830_display_video(ScrnInfoPtr pScrn, xf86CrtcPtr crtc, dstPitch); #if VIDEO_DEBUG + overlay = overlay_reg_prepare(pI830); CompareOverlay(pI830, (CARD32 *) overlay, 0x100); + overlay_reg_finish(pI830); #endif /* @@ -1870,6 +2007,7 @@ i830_display_video(ScrnInfoPtr pScrn, xf86CrtcPtr crtc, offsetu = pPriv->UBuf1offset; } + overlay = overlay_reg_prepare(pI830); switch (id) { case FOURCC_YV12: case FOURCC_I420: @@ -1912,16 +2050,33 @@ i830_display_video(ScrnInfoPtr pScrn, xf86CrtcPtr crtc, dstBox->x1, dstBox->y1, dstBox->x2, dstBox->y2); /* buffer locations */ - overlay->OBUF_0Y = pPriv->YBuf0offset; - overlay->OBUF_0U = pPriv->UBuf0offset; - overlay->OBUF_0V = pPriv->VBuf0offset; - if(pPriv->doubleBuffer) { + if (pI830->use_ttm_batch) { + dri_emit_reloc(pI830->overlay_regs_bo, DRM_BO_FLAG_READ | DRM_BO_FLAG_MEM_TT, pPriv->YBuf0offset, + offsetof(I830OverlayRegRec, OBUF_0Y), (dri_bo *)pPriv->buf); + dri_emit_reloc(pI830->overlay_regs_bo, DRM_BO_FLAG_READ | DRM_BO_FLAG_MEM_TT, pPriv->UBuf0offset, + offsetof(I830OverlayRegRec, OBUF_0U), (dri_bo *)pPriv->buf); + dri_emit_reloc(pI830->overlay_regs_bo, DRM_BO_FLAG_READ | DRM_BO_FLAG_MEM_TT, pPriv->VBuf0offset, + offsetof(I830OverlayRegRec, OBUF_0V), (dri_bo *)pPriv->buf); + if (pPriv->doubleBuffer) { + dri_emit_reloc(pI830->overlay_regs_bo, DRM_BO_FLAG_READ | DRM_BO_FLAG_MEM_TT, pPriv->YBuf1offset, + offsetof(I830OverlayRegRec, OBUF_1Y), (dri_bo *)pPriv->buf); + dri_emit_reloc(pI830->overlay_regs_bo, DRM_BO_FLAG_READ | DRM_BO_FLAG_MEM_TT, pPriv->UBuf1offset, + offsetof(I830OverlayRegRec, OBUF_1U), (dri_bo *)pPriv->buf); + dri_emit_reloc(pI830->overlay_regs_bo, DRM_BO_FLAG_READ | DRM_BO_FLAG_MEM_TT, pPriv->VBuf1offset, + offsetof(I830OverlayRegRec, OBUF_1V), (dri_bo *)pPriv->buf); + } + } else { + overlay->OBUF_0Y = pPriv->YBuf0offset; + overlay->OBUF_0U = pPriv->UBuf0offset; + overlay->OBUF_0V = pPriv->VBuf0offset; + if(pPriv->doubleBuffer) { overlay->OBUF_1Y = pPriv->YBuf1offset; overlay->OBUF_1U = pPriv->UBuf1offset; overlay->OBUF_1V = pPriv->VBuf1offset; + } } - OVERLAY_DEBUG("pos: 0x%" CARD32_HEX ", size: 0x%" CARD32_HEX "\n", + OVERLAY_DEBUG("pos: 0x%lx, size: 0x%lx\n", overlay->DWINPOS, overlay->DWINSZ); OVERLAY_DEBUG("dst: %d x %d, src: %d x %d\n", drw_w, drw_h, src_w, src_h); @@ -2085,6 +2240,7 @@ i830_display_video(ScrnInfoPtr pScrn, xf86CrtcPtr crtc, overlay->OCMD = OCMD; OVERLAY_DEBUG("OCMD is 0x%" CARD32_HEX "\n", OCMD); + overlay_reg_finish(pI830); /* make sure the overlay is on */ i830_overlay_on (pScrn); /* and show this frame */ @@ -2376,7 +2532,7 @@ I830PutImage(ScrnInfoPtr pScrn, /* Pick the idle buffer */ if (!pPriv->textured && *pI830->overlayOn && pPriv->doubleBuffer) - pPriv->currentBuf = !((INREG(DOVSTA) & OC_BUF) >> 20); + pPriv->currentBuf = !((video_read_dovsta(pI830) & OC_BUF) >> 20); /* copy data */ top = y1 >> 16; @@ -2674,7 +2830,8 @@ I830AllocateSurface(ScrnInfoPtr pScrn, surface->offsets[0] = 0; surface->devPrivate.ptr = (pointer) pPriv; - memset(pI830->FbBase + surface->offsets[0], 0, size); + if (!pI830->use_ttm_batch) + memset(pI830->FbBase + surface->offsets[0], 0, size); return Success; } @@ -2786,7 +2943,7 @@ I830DisplaySurface(XF86SurfacePtr surface, /* Pick the idle buffer */ if (!pI830Priv->textured && *pI830->overlayOn && pI830Priv->doubleBuffer) - pI830Priv->currentBuf = !((INREG(DOVSTA) & OC_BUF) >> 20); + pI830Priv->currentBuf = !((video_read_dovsta(pI830) & OC_BUF) >> 20); i830_display_video(pScrn, crtc, surface->id, surface->width, surface->height, surface->pitches[0], x1, y1, x2, y2, &dstBox, diff --git a/src/intel_bufmgr_ttm.c b/src/intel_bufmgr_ttm.c index c1ad8c7..f9394a0 100644 --- a/src/intel_bufmgr_ttm.c +++ b/src/intel_bufmgr_ttm.c @@ -374,7 +374,7 @@ dri_ttm_alloc(dri_bufmgr *bufmgr, const char *name, ttm_buf->validate_index = -1; ttm_buf->map_count = 0; - DBG("bo_create: %p (%s) %ldb\n", &ttm_buf->bo, ttm_buf->name, size); + DBG("bo_create: %p %08x (%s) %ldb\n", &ttm_buf->bo, ttm_buf->drm_bo.handle, ttm_buf->name, size); return &ttm_buf->bo; }