diff options
author | Jesse Barnes <jbarnes@virtuousgeek.org> | 2008-08-08 11:54:18 -0700 |
---|---|---|
committer | Jesse Barnes <jbarnes@virtuousgeek.org> | 2008-08-08 11:54:18 -0700 |
commit | b1aef6f63c151dcb202fce869e4b80598b4b2052 (patch) | |
tree | 95bc73bc1aa7a9a8ffe39ab8dc2215e26b5b799e | |
parent | f9504eff31eb3c9c6c6b33dced9875866ff8307e (diff) |
Initial port of kernel modesetting from old intel-kernelmode branch
Thanks airlied!
-rw-r--r-- | configure.ac | 4 | ||||
-rw-r--r-- | src/Makefile.am | 4 | ||||
-rw-r--r-- | src/common.h | 4 | ||||
-rw-r--r-- | src/drmmode_display.c | 695 | ||||
-rw-r--r-- | src/drmmode_display.h | 70 | ||||
-rw-r--r-- | src/i830.h | 11 | ||||
-rw-r--r-- | src/i830_bios.c | 6 | ||||
-rw-r--r-- | src/i830_dri.c | 37 | ||||
-rw-r--r-- | src/i830_driver.c | 1111 | ||||
-rw-r--r-- | src/i830_memory.c | 233 | ||||
-rw-r--r-- | src/i830_video.c | 2 | ||||
-rw-r--r-- | src/reg_dumper/reg_dumper.h | 1 |
12 files changed, 1658 insertions, 520 deletions
diff --git a/configure.ac b/configure.ac index b24a1541..61202271 100644 --- a/configure.ac +++ b/configure.ac @@ -101,6 +101,10 @@ if test x$DRI = xauto; then [have_dristruct_h="yes"], [have_dristruct_h="no"]) AC_CHECK_FILE([${sdkdir}/damage.h], [have_damage_h="yes"], [have_damage_h="no"]) + AC_CHECK_HEADER(xf86drmMode.h,[DRM_MODE=yes],[DRM_MODE=no],[#include "stdint.h"]) + if test "x$DRM_MODE" = xyes; then + AC_DEFINE(XF86DRM_MODE,1,[DRM kernel modesetting]) + fi if test "$have_dri_h" = yes -a \ "$have_sarea_h" = yes -a \ diff --git a/src/Makefile.am b/src/Makefile.am index dd92c8d9..1b1b67c8 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -130,7 +130,9 @@ intel_drv_la_SOURCES = \ i830_xaa.c \ i830_render.c \ i915_render.c \ - i965_render.c + i965_render.c \ + drmmode_display.c \ + drmmode_display.h INTEL_G4A = \ packed_yuv_sf.g4a \ diff --git a/src/common.h b/src/common.h index f2ae502b..ece1def0 100644 --- a/src/common.h +++ b/src/common.h @@ -370,7 +370,9 @@ extern int I810_DEBUG; /* mark chipsets without overlay hw */ #define OVERLAY_NOEXIST(pI810) (IS_GM45(pI810) || IS_G4X(pI810)) /* chipsets require graphics mem for hardware status page */ -#define HWS_NEED_GFX(pI810) (IS_G33CLASS(pI810) || IS_GM45(pI810) || IS_G4X(pI810)) +#define HWS_NEED_GFX(pI810) (!pI810->use_drm_mode && \ + (IS_G33CLASS(pI810) || IS_GM45(pI810) || \ + IS_G4X(pI810))) /* chipsets require status page in non stolen memory */ #define HWS_NEED_NONSTOLEN(pI810) (IS_GM45(pI810) || IS_G4X(pI810)) #define SUPPORTS_INTEGRATED_HDMI(pI810) (IS_GM45(pI810) || IS_G4X(pI810)) diff --git a/src/drmmode_display.c b/src/drmmode_display.c new file mode 100644 index 00000000..b329090a --- /dev/null +++ b/src/drmmode_display.c @@ -0,0 +1,695 @@ +/* + * Copyright © 2007 Red Hat, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Authors: + * Dave Airlie <airlied@redhat.com> + * + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef XF86DRM_MODE +#include "radeon.h" +#include "sarea.h" + +static Bool drmmode_resize_fb(ScrnInfoPtr scrn, drmmode_ptr drmmode, int width, int height); + +static Bool +drmmode_xf86crtc_resize (ScrnInfoPtr scrn, int width, int height) +{ + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); + drmmode_crtc_private_ptr drmmode_crtc = xf86_config->crtc[0]->driver_private; + drmmode_ptr drmmode = drmmode_crtc->drmmode; + Bool ret; + + 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; + + /* cursor should be mapped already */ + ptr = drmmode_crtc->cursor_map; + + memcpy (ptr, image, 64 * 64 * 4); + + return; +} + + +static void +drmmode_hide_cursor (xf86CrtcPtr crtc) +{ + drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; + drmmode_ptr drmmode = drmmode_crtc->drmmode; + + drmModeSetCursor(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, 0, 64, 64); + +} + +static void +drmmode_show_cursor (xf86CrtcPtr crtc) +{ + drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; + drmmode_ptr drmmode = drmmode_crtc->drmmode; + + drmModeSetCursor(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, drmmode_crtc->cursor_handle, 64, 64); +} + +static void * +drmmode_crtc_shadow_allocate(xf86CrtcPtr crtc, int width, int height) +{ + drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; + drmmode_ptr drmmode = drmmode_crtc->drmmode; + int ret; + int size; + unsigned long rotate_pitch; + + rotate_pitch = crtc->scrn->displayWidth * drmmode->cpp; + size = rotate_pitch * height; + +#if 0 + drmmode_crtc->rotate_bo = dri_bo_alloc(drmmode->bufmgr, "rotate", + size, 4096, 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; +#endif + return NULL; +} + +static PixmapPtr +drmmode_crtc_shadow_create(xf86CrtcPtr crtc, void *data, int width, int height) +{ + ScrnInfoPtr pScrn = crtc->scrn; + drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; + drmmode_ptr drmmode = drmmode_crtc->drmmode; + unsigned long rotate_pitch; + PixmapPtr rotate_pixmap; + + if (!data) + data = drmmode_crtc_shadow_allocate (crtc, width, height); + + rotate_pitch = pScrn->displayWidth * drmmode->cpp; + + rotate_pixmap = GetScratchPixmapHeader(pScrn->pScreen, + width, height, + pScrn->depth, + pScrn->bitsPerPixel, + rotate_pitch, + data); + + if (rotate_pixmap == NULL) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Couldn't allocate shadow pixmap for rotated CRTC\n"); + } + return rotate_pixmap; + +} + +static void +drmmode_crtc_shadow_destroy(xf86CrtcPtr crtc, PixmapPtr rotate_pixmap, void *data) +{ + drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; + drmmode_ptr drmmode = drmmode_crtc->drmmode; + + if (rotate_pixmap) + FreeScratchPixmapHeader(rotate_pixmap); + + if (data) { +#if 0 + /* Be sure to sync acceleration before the memory gets unbound. */ + drmModeRmFB(drmmode->fd, drmmode_crtc->rotate_fb_id); + drmmode_crtc->rotate_fb_id = 0; + dri_bo_unreference(drmmode_crtc->rotate_bo); + drmmode_crtc->rotate_bo = NULL; +#endif + } + +} + +static const xf86CrtcFuncsRec drmmode_crtc_funcs = { + .dpms = drmmode_crtc_dpms, + .set_mode_major = drmmode_set_mode_major, + .set_cursor_colors = drmmode_set_cursor_colors, + .set_cursor_position = drmmode_set_cursor_position, + .show_cursor = drmmode_show_cursor, + .hide_cursor = drmmode_hide_cursor, + .load_cursor_argb = drmmode_load_cursor_argb, + + .shadow_create = drmmode_crtc_shadow_create, + .shadow_allocate = drmmode_crtc_shadow_allocate, + .shadow_destroy = drmmode_crtc_shadow_destroy, +#if 0 + .gamma_set = i830_crtc_gamma_set, + .shadow_create = i830_crtc_shadow_create, + .shadow_allocate = i830_crtc_shadow_allocate, + .shadow_destroy = i830_crtc_shadow_destroy, + .set_cursor_colors = i830_crtc_set_cursor_colors, +#endif + .destroy = NULL, /* XXX */ +}; + + +static void +drmmode_crtc_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int num) +{ + xf86CrtcPtr crtc; + drmmode_crtc_private_ptr drmmode_crtc; + 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; + +#if 0 + drmmode_crtc->cursor_handle = drmmode->alloc_cursor(pScrn, num, 64, 64, &drmmode_crtc->cursor_map); + if (!drmmode_crtc->cursor_handle) { + ErrorF("failed to allocate cursor for crtc\n"); + return; + } +#endif + 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 }; + +const char *output_names[] = { "None", + "VGA", + "DVI", + "DVI", + "DVI", + "Composite" + "TV", + "LVDS", + "CTV", + "DIN", + "DP", + "HDMI", + "HDMI", +}; + + +static void +drmmode_output_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int num) +{ + xf86OutputPtr output; + drmModeConnectorPtr koutput; + drmModeEncoderPtr kencoder; + drmmode_output_private_ptr drmmode_output; + char name[32]; + + koutput = drmModeGetConnector(drmmode->fd, drmmode->mode_res->connectors[num]); + if (!koutput) + return; + + kencoder = drmModeGetEncoder(drmmode->fd, koutput->encoders[0]); + if (!kencoder) { + drmModeFreeConnector(koutput); + return; + } + + snprintf(name, 32, "%s%d", output_names[koutput->connector_type], koutput->connector_type_id); + + output = xf86OutputCreate (pScrn, &drmmode_output_funcs, name); + if (!output) { + drmModeFreeEncoder(kencoder); + drmModeFreeConnector(koutput); + return; + } + + drmmode_output = xcalloc(sizeof(drmmode_output_private_rec), 1); + if (!drmmode_output) { + xf86OutputDestroy(output); + drmModeFreeConnector(koutput); + drmModeFreeEncoder(kencoder); + return; + } + + drmmode_output->output_id = drmmode->mode_res->connectors[num]; + drmmode_output->mode_output = koutput; + drmmode_output->mode_encoder = kencoder; + drmmode_output->drmmode = drmmode; + output->mm_width = koutput->mmWidth; + output->mm_height = koutput->mmHeight; + + output->subpixel_order = subpixel_conv_table[koutput->subpixel]; + output->driver_private = drmmode_output; + + output->possible_crtcs = kencoder->possible_crtcs; + output->possible_clones = kencoder->possible_clones; + return; +} + +Bool drmmode_pre_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, char *busId, char *driver_name, int cpp) +{ + xf86CrtcConfigPtr xf86_config; + int i; + Bool ret; + + /* Create a bus Id */ + /* Low level DRM open */ + ret = DRIOpenDRMMaster(pScrn, SAREA_MAX, busId, driver_name); + if (!ret) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "[dri] DRIGetVersion failed to open the DRM\n" + "[dri] Disabling DRI.\n"); + return FALSE; + } + + drmmode->fd = DRIMasterFD(pScrn); + + xf86CrtcConfigInit(pScrn, &drmmode_xf86crtc_config_funcs); + xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); + + drmmode->cpp = cpp; + drmmode->mode_res = drmModeGetResources(drmmode->fd); + if (!drmmode->mode_res) + return FALSE; + + xf86CrtcSetSizeRange(pScrn, 320, 200, drmmode->mode_res->max_width, drmmode->mode_res->max_height); + for (i = 0; i < drmmode->mode_res->count_crtcs; i++) + drmmode_crtc_init(pScrn, drmmode, i); + + for (i = 0; i < drmmode->mode_res->count_connectors; i++) + drmmode_output_init(pScrn, drmmode, i); + + xf86InitialConfiguration(pScrn, FALSE); + + return TRUE; +} + +#if 0 +Bool drmmode_set_bufmgr(ScrnInfoPtr pScrn, drmmode_ptr drmmode, dri_bufmgr *bufmgr) +{ + drmmode->bufmgr = bufmgr; + return TRUE; +} +#endif + +void drmmode_set_fb(ScrnInfoPtr scrn, drmmode_ptr drmmode, int width, int height, int pitch, uint32_t handle) +{ + int ret; + + ret = drmModeAddFB(drmmode->fd, width, height, scrn->depth, + scrn->bitsPerPixel, pitch, 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); +} + +void drmmode_set_cursor(ScrnInfoPtr scrn, drmmode_ptr drmmode, int id, void *ptr, uint32_t handle) +{ + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); + xf86CrtcPtr crtc = xf86_config->crtc[id]; + drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; + + + drmmode_crtc->cursor_handle = handle; + drmmode_crtc->cursor_map = ptr; +} + +#if 0 +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; + +} +#endif + +static Bool drmmode_resize_fb(ScrnInfoPtr scrn, drmmode_ptr drmmode, int width, int height) +{ + uint32_t handle; + int pitch; + int ret; + + return FALSE; + + if (drmmode->mode_fb->width == width && drmmode->mode_fb->height == height) + return TRUE; + + if (!drmmode->create_new_fb) + return FALSE; + + handle = drmmode->create_new_fb(scrn, width, height, &pitch); + if (handle == 0) + return FALSE; + + ret = drmModeReplaceFB(drmmode->fd, drmmode->fb_id, + width, height, + scrn->depth, scrn->bitsPerPixel, pitch, + handle); + + if (ret) + return FALSE; + + drmModeFreeFB(drmmode->mode_fb); + drmmode->mode_fb = drmModeGetFB(drmmode->fd, drmmode->fb_id); + if (!drmmode->mode_fb) + return FALSE; + + return TRUE; +} + +#endif + diff --git a/src/drmmode_display.h b/src/drmmode_display.h new file mode 100644 index 00000000..59e6307a --- /dev/null +++ b/src/drmmode_display.h @@ -0,0 +1,70 @@ +/* + * Copyright © 2007 Red Hat, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Authors: + * Dave Airlie <airlied@redhat.com> + * + */ +#ifndef DRMMODE_DISPLAY_H +#define DRMMODE_DISPLAY_H + +#ifdef XF86DRM_MODE + +#include "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; + uint32_t cursor_handle; + void *cursor_map; + // 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, uint32_t handle); +//extern Bool drmmode_is_rotate_pixmap(ScrnInfoPtr pScrn, pointer pPixData, dri_bo **bo); +extern void drmmode_set_cursor(ScrnInfoPtr scrn, drmmode_ptr drmmode, int id, void *ptr, uint32_t handle); +#endif +#endif @@ -77,6 +77,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #ifdef DAMAGE #include "damage.h" #endif +#include "drmmode_display.h" #endif #include "dri_bufmgr.h" #include "intel_bufmgr.h" @@ -702,6 +703,12 @@ typedef struct _I830Rec { enum last_3d *last_3d; + Bool use_drm_mode; +#ifdef XF86DRM_MODE + drmmode_rec drmmode; + int drm_mm_init; +#endif + /** Enables logging of debug output related to mode switching. */ Bool debug_modes; unsigned int quirk_flag; @@ -832,7 +839,9 @@ void i830_init_bufmgr(ScrnInfoPtr pScrn); Bool i830_allocate_xvmc_buffer(ScrnInfoPtr pScrn, const char *name, i830_memory **buffer, unsigned long size, int flags); #endif - +extern void i830_update_front_offset(ScrnInfoPtr pScrn); +extern uint32_t i830_create_new_fb(ScrnInfoPtr pScrn, int width, int height, + int *pitch); extern Bool I830IsPrimary(ScrnInfoPtr pScrn); extern Bool I830I2CInit(ScrnInfoPtr pScrn, I2CBusPtr *bus_ptr, int i2c_reg, diff --git a/src/i830_bios.c b/src/i830_bios.c index fe55d239..ff49025d 100644 --- a/src/i830_bios.c +++ b/src/i830_bios.c @@ -180,11 +180,17 @@ i830_bios_init(ScrnInfoPtr pScrn) int vbt_off, bdb_off; unsigned char *bios; vbeInfoPtr pVbe; + pointer pVBEModule = NULL; bios = xalloc(INTEL_VBIOS_SIZE); if (bios == NULL) return -1; + /* Load vbe module */ + if (!(pVBEModule = xf86LoadSubModule(pScrn, "vbe"))) + return FALSE; + xf86LoaderReqSymLists(I810vbeSymbols, NULL); + pVbe = VBEInit(NULL, pI830->pEnt->index); if (pVbe != NULL) { memcpy(bios, xf86int10Addr(pVbe->pInt10, diff --git a/src/i830_dri.c b/src/i830_dri.c index d40ada56..9d7271ea 100644 --- a/src/i830_dri.c +++ b/src/i830_dri.c @@ -766,20 +766,22 @@ I830InitTextureHeap(ScrnInfoPtr pScrn) } } -/** - * Sets up mappings for static, lifetime-fixed allocations, and inital SAREA - * setup. +/* + * Map registers & ring buffer */ -Bool -I830DRIDoMappings(ScreenPtr pScreen) +static Bool +I830DRIMapHW(ScreenPtr pScreen) { ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; I830Ptr pI830 = I830PTR(pScrn); DRIInfoPtr pDRIInfo = pI830->pDRIInfo; I830DRIPtr pI830DRI = pDRIInfo->devPrivate; - drmI830Sarea *sarea = (drmI830Sarea *) DRIGetSAREAPrivate(pScreen); - DPRINTF(PFX, "I830DRIDoMappings\n"); + /* Kernel deals with direct hw access in this case */ + if (pI830->use_drm_mode) + return TRUE; + + DPRINTF(PFX, "I830DRIMapHW\n"); pI830DRI->regsSize = I830_REG_SIZE; if (drmAddMap(pI830->drmSubFD, (drm_handle_t)pI830->MMIOAddr, pI830DRI->regsSize, DRM_REGISTERS, 0, @@ -806,6 +808,27 @@ I830DRIDoMappings(ScreenPtr pScreen) (int)pI830->ring_map); } + return TRUE; +} + +/** + * Sets up mappings for static, lifetime-fixed allocations, and inital SAREA + * setup. + */ +Bool +I830DRIDoMappings(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + I830Ptr pI830 = I830PTR(pScrn); + DRIInfoPtr pDRIInfo = pI830->pDRIInfo; + I830DRIPtr pI830DRI = pDRIInfo->devPrivate; + drmI830Sarea *sarea = (drmI830Sarea *) DRIGetSAREAPrivate(pScreen); + + if (!I830DRIMapHW(pScreen)) { + DRICloseScreen(pScreen); + return FALSE; + } + if (!I830InitDma(pScrn)) { DRICloseScreen(pScreen); return FALSE; diff --git a/src/i830_driver.c b/src/i830_driver.c index 8ea05af0..01073fe7 100644 --- a/src/i830_driver.c +++ b/src/i830_driver.c @@ -177,6 +177,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "xf86_OSproc.h" #include "xf86Resources.h" #include "xf86RAC.h" +#include "xf86Priv.h" #include "xf86cmap.h" #include "compiler.h" #include "mibstore.h" @@ -426,17 +427,6 @@ I830FreeRec(ScrnInfoPtr pScrn) pScrn->driverPrivate = NULL; } -static void -I830ProbeDDC(ScrnInfoPtr pScrn, int index) -{ - vbeInfoPtr pVbe; - - /* The vbe module gets loaded in PreInit(), so no need to load it here. */ - - pVbe = VBEInit(NULL, index); - ConfiguredMonitor = vbeDoEDID(pVbe, NULL); -} - static int I830DetectMemory(ScrnInfoPtr pScrn) { @@ -835,11 +825,12 @@ I830LoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices, } } -static void +void i830_update_front_offset(ScrnInfoPtr pScrn) { ScreenPtr pScreen = pScrn->pScreen; I830Ptr pI830 = I830PTR(pScrn); + int pitch = pScrn->displayWidth * pI830->cpp; /* Update buffer locations, which may have changed as a result of * i830_bind_all_memory(). @@ -851,9 +842,9 @@ i830_update_front_offset(ScrnInfoPtr pScrn) */ if (!pI830->starting && pI830->accel != ACCEL_UXA) { if (!pScreen->ModifyPixmapHeader(pScreen->GetScreenPixmap(pScreen), - -1, -1, -1, -1, -1, - (pointer)(pI830->FbBase + - pScrn->fbOffset))) + pScrn->virtualX, pScrn->virtualY, -1, -1, + pitch, (pointer)(pI830->FbBase + + pScrn->fbOffset))) FatalError("Couldn't adjust screen pixmap\n"); } } @@ -1116,6 +1107,10 @@ i830SetHotkeyControl(ScrnInfoPtr pScrn, int mode) I830Ptr pI830 = I830PTR(pScrn); uint8_t gr18; + /* Don't mess with kernel settings... */ + if (pI830->use_drm_mode) + return; + gr18 = pI830->readControl(pI830, GRX, 0x18); if (mode == HOTKEY_BIOS_SWITCH) gr18 &= ~HOTKEY_VBIOS_SWITCH_BLOCK; @@ -1124,6 +1119,45 @@ i830SetHotkeyControl(ScrnInfoPtr pScrn, int mode) pI830->writeControl(pI830, GRX, 0x18, gr18); } +#ifdef XF86DRM_MODE +/* + * DRM mode setting Linux only at this point... later on we could + * add a wrapper here. + */ +#include <linux/kd.h> + +static Bool i830_kernel_mode_enabled(ScrnInfoPtr pScrn) +{ +#if XSERVER_LIBPCIACCESS + struct pci_device *PciInfo; +#else + pciVideoPtr PciInfo; +#endif + EntityInfoPtr pEnt; + char *busIdString; + int ret; + + pEnt = xf86GetEntityInfo(pScrn->entityList[0]); + PciInfo = xf86GetPciInfoForEntity(pEnt->index); + + if (!xf86LoaderCheckSymbol("DRICreatePCIBusID")) + return FALSE; + + busIdString = DRICreatePCIBusID(PciInfo); + + ret = drmCheckModesettingSupported(busIdString); + xfree(busIdString); + if (ret) + return FALSE; + + ioctl(xf86Info.consoleFd, KDSETMODE, KD_TEXT); + + return TRUE; +} +#else +#define i830_kernel_mode_enabled(x) FALSE +#endif + static Bool i830_detect_chipset(ScrnInfoPtr pScrn) { @@ -1133,6 +1167,11 @@ i830_detect_chipset(ScrnInfoPtr pScrn) uint32_t capid; int fb_bar, mmio_bar; + + /* We have to use PIO to probe, because we haven't mapped yet. */ + if (!pI830->use_drm_mode) + I830SetPIOAccess(pI830); + switch (DEVICE_ID(pI830->PciInfo)) { case PCI_CHIP_I830_M: chipname = "830M"; @@ -1260,6 +1299,19 @@ i830_detect_chipset(ScrnInfoPtr pScrn) xf86DrvMsg(pScrn->scrnIndex, from, "Chipset: \"%s\"\n", (pScrn->chipset != NULL) ? pScrn->chipset : "Unknown i8xx"); + /* Check if the HW cursor needs physical address. */ + if (IS_MOBILE(pI830) || IS_I9XX(pI830)) + pI830->CursorNeedsPhysical = TRUE; + else + pI830->CursorNeedsPhysical = FALSE; + + if (IS_I965G(pI830) || IS_G33CLASS(pI830)) + pI830->CursorNeedsPhysical = FALSE; + + /* Skip the rest if the kernel is taking care of things */ + if (pI830->use_drm_mode) + return TRUE; + /* Now that we know the chipset, figure out the resource base addrs */ if (IS_I9XX(pI830)) { fb_bar = 2; @@ -1347,6 +1399,342 @@ static const char *accel_name[] = "UXA", }; +static Bool +I830LoadSyms(ScrnInfoPtr pScrn) +{ + I830Ptr pI830 = I830PTR(pScrn); + + if (pI830->use_drm_mode) + return TRUE; + + /* Load int10 module */ + if (!xf86LoadSubModule(pScrn, "int10")) + return FALSE; + xf86LoaderReqSymLists(I810int10Symbols, NULL); + + /* The vgahw module should be loaded here when needed */ + if (!xf86LoadSubModule(pScrn, "vgahw")) + return FALSE; + xf86LoaderReqSymLists(I810vgahwSymbols, NULL); + + return TRUE; +} + +static Bool +I830GetEarlyOptions(ScrnInfoPtr pScrn) +{ + I830Ptr pI830 = I830PTR(pScrn); + + /* Process the options */ + xf86CollectOptions(pScrn, NULL); + if (!(pI830->Options = xalloc(sizeof(I830Options)))) + return FALSE; + memcpy(pI830->Options, I830Options, sizeof(I830Options)); + xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, pI830->Options); + + if (xf86ReturnOptValBool(pI830->Options, OPTION_MODEDEBUG, FALSE)) { + pI830->debug_modes = TRUE; + } else { + pI830->debug_modes = FALSE; + } + + if (xf86ReturnOptValBool(pI830->Options, OPTION_LVDS24BITMODE, FALSE)) { + pI830->lvds_24_bit_mode = TRUE; + } else { + pI830->lvds_24_bit_mode = FALSE; + } + + if (xf86ReturnOptValBool(pI830->Options, OPTION_LVDSFIXEDMODE, TRUE)) { + pI830->skip_panel_detect = TRUE; + } else { + pI830->skip_panel_detect = FALSE; + } + + if (xf86ReturnOptValBool(pI830->Options, OPTION_FORCEENABLEPIPEA, FALSE)) + pI830->quirk_flag |= QUIRK_PIPEA_FORCE; + + return TRUE; +} + +static void +I830PreInitCrtcConfig(ScrnInfoPtr pScrn) +{ + xf86CrtcConfigPtr xf86_config; + I830Ptr pI830 = I830PTR(pScrn); + int max_width, max_height; + + if (pI830->use_drm_mode) + return; + + /* check quirks */ + i830_fixup_devices(pScrn); + + /* Allocate an xf86CrtcConfig */ + xf86CrtcConfigInit (pScrn, &i830_xf86crtc_config_funcs); + xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); + + /* See i830_exa.c comments for why we limit the framebuffer size like this. + */ + if (IS_I965G(pI830)) { + max_width = 8192; + max_height = 8192; + } else { + max_width = 2048; + max_height = 2048; + } + xf86CrtcSetSizeRange (pScrn, 320, 200, max_width, max_height); +} + +static Bool +I830AccelMethodInit(ScrnInfoPtr pScrn) +{ + I830Ptr pI830 = I830PTR(pScrn); + MessageType from = X_PROBED; + char *s; + int i, num_pipe; + + if (xf86ReturnOptValBool(pI830->Options, OPTION_NOACCEL, FALSE)) { + pI830->accel = ACCEL_NONE; + } + + /* + * The ugliness below: + * If either XAA or EXA (exclusive) is compiled in, default to it. + * + * If both are compiled in, and the user didn't specify noAccel, use the + * config option AccelMethod to determine which to use, defaulting to EXA + * if none is specified, or if the string was unrecognized. + * + * All this *could* go away if we removed XAA support from this driver, + * for example. :) + */ + if (!(pI830->accel == ACCEL_NONE)) { +#ifdef I830_USE_UXA + pI830->accel = ACCEL_UXA; +#endif +#ifdef I830_USE_EXA + pI830->accel = ACCEL_EXA; +#endif +#if I830_USE_XAA + I830_USE_EXA + I830_USE_UXA >= 2 + from = X_DEFAULT; + if ((s = (char *)xf86GetOptValString(pI830->Options, + OPTION_ACCELMETHOD))) { + if (!xf86NameCmp(s, "EXA")) { + from = X_CONFIG; + pI830->accel = ACCEL_EXA; + } + else if (!xf86NameCmp(s, "XAA")) { + from = X_CONFIG; + pI830->accel = ACCEL_XAA; + } + else if (!xf86NameCmp(s, "UXA")) { + from = X_CONFIG; + pI830->accel = ACCEL_UXA; + } + } +#endif + xf86DrvMsg(pScrn->scrnIndex, from, "Using %s for acceleration\n", + accel_name[pI830->accel]); + } + + if (xf86ReturnOptValBool(pI830->Options, OPTION_SW_CURSOR, FALSE)) { + pI830->SWCursor = TRUE; + } + + pI830->directRenderingDisabled = + !xf86ReturnOptValBool(pI830->Options, OPTION_DRI, TRUE); + +#ifdef XF86DRI + if (!pI830->directRenderingDisabled) { + if ((pI830->accel == ACCEL_NONE) || pI830->SWCursor) { + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "DRI is disabled because it " + "needs HW cursor and 2D acceleration.\n"); + pI830->directRenderingDisabled = TRUE; + } else if (pScrn->depth != 16 && pScrn->depth != 24) { + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "DRI is disabled because it " + "runs only at depths 16 and 24.\n"); + pI830->directRenderingDisabled = TRUE; + } + + if (!pI830->directRenderingDisabled) { + pI830->allocate_classic_textures = TRUE; + + from = X_PROBED; + +#ifdef XF86DRI_MM + if (!IS_I965G(pI830)) { + Bool tmp; + + if (xf86GetOptValBool(pI830->Options, + OPTION_INTELTEXPOOL, &tmp)) { + from = X_CONFIG; + if (!tmp) + pI830->allocate_classic_textures = FALSE; + } + } +#endif /* XF86DRI_MM */ + } + } +#endif /* XF86DRI */ + + I830MapMMIO(pScrn); + + if (pI830->debug_modes) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Hardware state on X startup:\n"); + i830DumpRegs (pScrn); + } + + i830TakeRegSnapshot(pScrn); + + if (DEVICE_ID(pI830->PciInfo) == PCI_CHIP_E7221_G) + num_pipe = 1; + else + if (IS_MOBILE(pI830) || IS_I9XX(pI830)) + num_pipe = 2; + else + num_pipe = 1; + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "%d display pipe%s available.\n", + num_pipe, num_pipe > 1 ? "s" : ""); + + I830PreInitDDC(pScrn); + for (i = 0; i < num_pipe; i++) { + i830_crtc_init(pScrn, i); + } + I830SetupOutputs(pScrn); + + SaveHWState(pScrn); + if (!xf86InitialConfiguration (pScrn, FALSE)) + { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes.\n"); + RestoreHWState(pScrn); + PreInitCleanup(pScrn); + return FALSE; + } + RestoreHWState(pScrn); + + /* XXX This should go away, replaced by xf86Crtc.c support for it */ + pI830->rotation = RR_Rotate_0; + + /* + * Let's setup the mobile systems to check the lid status + */ + if (IS_MOBILE(pI830)) { + pI830->checkDevices = TRUE; + + if (!xf86ReturnOptValBool(pI830->Options, OPTION_CHECKDEVICES, TRUE)) { + pI830->checkDevices = FALSE; + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Monitoring connected displays disabled\n"); + } else + if (pI830->entityPrivate && !I830IsPrimary(pScrn) && + !I830PTR(pI830->entityPrivate->pScrn_1)->checkDevices) { + /* If checklid is off, on the primary head, then + * turn it off on the secondary*/ + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Monitoring connected displays disabled\n"); + pI830->checkDevices = FALSE; + } else + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Monitoring connected displays enabled\n"); + } else + pI830->checkDevices = FALSE; + + pI830->stolen_size = I830DetectMemory(pScrn); + + return TRUE; +} + +static Bool +I830DrmModeInit(ScrnInfoPtr pScrn) +{ +#ifdef XF86DRM_MODE + I830Ptr pI830 = I830PTR(pScrn); + char *bus_id; + + bus_id = DRICreatePCIBusID(pI830->PciInfo); + if (drmmode_pre_init(pScrn, &pI830->drmmode, bus_id, "i915", + pI830->cpp) == FALSE) { + xfree(bus_id); + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Kernel modesetting setup failed\n"); + PreInitCleanup(pScrn); + return FALSE; + } + + pI830->drmmode.create_new_fb = i830_create_new_fb; + + pI830->drmSubFD = pI830->drmmode.fd; + xfree(bus_id); + + pI830->accel = ACCEL_EXA; + pI830->directRenderingDisabled = FALSE; + pI830->allocate_classic_textures = FALSE; + + I830InitBufMgr(pScrn); +#endif + + return TRUE; +} + +static void +I830XvInit(ScrnInfoPtr pScrn) +{ + I830Ptr pI830 = I830PTR(pScrn); + MessageType from = X_PROBED; + + pI830->XvDisabled = + !xf86ReturnOptValBool(pI830->Options, OPTION_XVIDEO, TRUE); + +#ifdef I830_XV + if (xf86GetOptValInteger(pI830->Options, OPTION_VIDEO_KEY, + &(pI830->colorKey))) { + from = X_CONFIG; + } else if (xf86GetOptValInteger(pI830->Options, OPTION_COLOR_KEY, + &(pI830->colorKey))) { + from = X_CONFIG; + } else { + pI830->colorKey = + (1 << pScrn->offset.red) | (1 << pScrn->offset.green) | + (((pScrn->mask.blue >> pScrn->offset.blue) - 1) << + pScrn->offset.blue); + from = X_DEFAULT; + } + xf86DrvMsg(pScrn->scrnIndex, from, "video overlay key set to 0x%x\n", + pI830->colorKey); +#endif +#ifdef INTEL_XVMC + pI830->XvMCEnabled = FALSE; + from = (!pI830->directRenderingDisabled && + xf86GetOptValBool(pI830->Options, OPTION_XVMC, + &pI830->XvMCEnabled)) ? X_CONFIG : X_DEFAULT; + xf86DrvMsg(pScrn->scrnIndex, from, "Intel XvMC decoder %sabled\n", + pI830->XvMCEnabled ? "en" : "dis"); +#endif +} + +static void +I830DriOptsInit(ScrnInfoPtr pScrn) +{ +#ifdef XF86DRI + I830Ptr pI830 = I830PTR(pScrn); + MessageType from = X_PROBED; + + pI830->allowPageFlip = FALSE; + from = (!pI830->directRenderingDisabled && + xf86GetOptValBool(pI830->Options, OPTION_PAGEFLIP, + &pI830->allowPageFlip)) ? X_CONFIG : X_DEFAULT; + + xf86DrvMsg(pScrn->scrnIndex, from, "Will%s try to enable page flipping\n", + pI830->allowPageFlip ? "" : " not"); + + pI830->TripleBuffer = FALSE; + from = (!pI830->directRenderingDisabled && + xf86GetOptValBool(pI830->Options, OPTION_TRIPLEBUFFER, + &pI830->TripleBuffer)) ? X_CONFIG : X_DEFAULT; + + xf86DrvMsg(pScrn->scrnIndex, from, "Triple buffering %sabled\n", + pI830->TripleBuffer ? "en" : "dis"); +#endif /* XF86DRI */ +} + /** * This is called per zaphod head (so usually just once) to do initialization * before the Screen is created. @@ -1357,48 +1745,24 @@ static const char *accel_name[] = static Bool I830PreInit(ScrnInfoPtr pScrn, int flags) { - xf86CrtcConfigPtr xf86_config; vgaHWPtr hwp; I830Ptr pI830; - MessageType from = X_PROBED; rgb defaultWeight = { 0, 0, 0 }; EntityInfoPtr pEnt; - I830EntPtr pI830Ent = NULL; + I830EntPtr pI830Ent = NULL; int flags24; - int i; - char *s; - pointer pVBEModule = NULL; - int num_pipe; - int max_width, max_height; + Gamma zeros = { 0.0, 0.0, 0.0 }; + int drm_mode_setting; if (pScrn->numEntities != 1) return FALSE; - /* Load int10 module */ - if (!xf86LoadSubModule(pScrn, "int10")) - return FALSE; - xf86LoaderReqSymLists(I810int10Symbols, NULL); - - /* Load vbe module */ - if (!(pVBEModule = xf86LoadSubModule(pScrn, "vbe"))) - return FALSE; - xf86LoaderReqSymLists(I810vbeSymbols, NULL); + drm_mode_setting = i830_kernel_mode_enabled(pScrn); pEnt = xf86GetEntityInfo(pScrn->entityList[0]); - if (flags & PROBE_DETECT) { - I830ProbeDDC(pScrn, pEnt->index); - return TRUE; - } - - /* The vgahw module should be loaded here when needed */ - if (!xf86LoadSubModule(pScrn, "vgahw")) - return FALSE; - xf86LoaderReqSymLists(I810vgahwSymbols, NULL); - - /* Allocate a vgaHWRec */ - if (!vgaHWGetHWRec(pScrn)) - return FALSE; + if (flags & PROBE_DETECT) + return TRUE; /* Allocate driverPrivate */ if (!I830GetRec(pScrn)) @@ -1407,6 +1771,17 @@ I830PreInit(ScrnInfoPtr pScrn, int flags) pI830 = I830PTR(pScrn); pI830->SaveGeneration = -1; pI830->pEnt = pEnt; + pI830->use_drm_mode = drm_mode_setting; + + if (!I830LoadSyms(pScrn)) + return FALSE; + + if (!drm_mode_setting) { + /* Allocate a vgaHWRec */ + if (!vgaHWGetHWRec(pScrn)) + return FALSE; + hwp = VGAHWPTR(pScrn); + } pScrn->displayWidth = 640; /* default it */ @@ -1424,7 +1799,7 @@ I830PreInit(ScrnInfoPtr pScrn, int flags) pI830Ent = xf86GetEntityPrivate(pScrn->entityList[0], I830EntityIndex)->ptr; pI830->entityPrivate = pI830Ent; - } else + } else pI830->entityPrivate = NULL; if (xf86RegisterResources(pI830->pEnt->index, NULL, ResNone)) { @@ -1490,284 +1865,31 @@ I830PreInit(ScrnInfoPtr pScrn, int flags) pI830->preinit = TRUE; - /* Process the options */ - xf86CollectOptions(pScrn, NULL); - if (!(pI830->Options = xalloc(sizeof(I830Options)))) - return FALSE; - memcpy(pI830->Options, I830Options, sizeof(I830Options)); - xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, pI830->Options); - - if (xf86ReturnOptValBool(pI830->Options, OPTION_MODEDEBUG, FALSE)) { - pI830->debug_modes = TRUE; - } else { - pI830->debug_modes = FALSE; - } - - if (xf86ReturnOptValBool(pI830->Options, OPTION_LVDS24BITMODE, FALSE)) { - pI830->lvds_24_bit_mode = TRUE; - } else { - pI830->lvds_24_bit_mode = FALSE; - } - - if (xf86ReturnOptValBool(pI830->Options, OPTION_LVDSFIXEDMODE, TRUE)) { - pI830->skip_panel_detect = TRUE; - } else { - pI830->skip_panel_detect = FALSE; - } - - if (xf86ReturnOptValBool(pI830->Options, OPTION_FORCEENABLEPIPEA, FALSE)) - pI830->quirk_flag |= QUIRK_PIPEA_FORCE; - - /* We have to use PIO to probe, because we haven't mapped yet. */ - I830SetPIOAccess(pI830); + if (!I830GetEarlyOptions(pScrn)) + return FALSE; if (!i830_detect_chipset(pScrn)) return FALSE; - /* check quirks */ - i830_fixup_devices(pScrn); - - /* 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); - - /* 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); - } - - i830TakeRegSnapshot(pScrn); + if (pI830->use_drm_mode && !I830DrmModeInit(pScrn)) + return FALSE; + else if (!I830AccelMethodInit(pScrn)) + return FALSE; - 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" : ""); + I830XvInit(pScrn); - if (xf86ReturnOptValBool(pI830->Options, OPTION_NOACCEL, FALSE)) { - pI830->accel = ACCEL_NONE; - } + I830DriOptsInit(pScrn); - /* - * The ugliness below: - * If either XAA or EXA (exclusive) is compiled in, default to it. - * - * If both are compiled in, and the user didn't specify noAccel, use the - * config option AccelMethod to determine which to use, defaulting to EXA - * if none is specified, or if the string was unrecognized. - * - * All this *could* go away if we removed XAA support from this driver, - * for example. :) - */ - if (pI830->accel == ACCEL_UNINIT) { - pI830->accel = ACCEL_NONE; -#ifdef I830_USE_XAA - pI830->accel = ACCEL_XAA; -#endif -#ifdef I830_USE_UXA - pI830->accel = ACCEL_UXA; -#endif -#ifdef I830_USE_EXA - pI830->accel = ACCEL_EXA; -#endif -#if I830_USE_XAA + I830_USE_EXA + I830_USE_UXA >= 2 - from = X_DEFAULT; - if ((s = (char *)xf86GetOptValString(pI830->Options, - OPTION_ACCELMETHOD))) { - if (!xf86NameCmp(s, "EXA")) { - from = X_CONFIG; - pI830->accel = ACCEL_EXA; - } - else if (!xf86NameCmp(s, "XAA")) { - from = X_CONFIG; - pI830->accel = ACCEL_XAA; - } - else if (!xf86NameCmp(s, "UXA")) { - from = X_CONFIG; - pI830->accel = ACCEL_UXA; - } - } -#endif - } - xf86DrvMsg(pScrn->scrnIndex, from, "Using %s acceleration\n", - accel_name[pI830->accel]); - - if (xf86ReturnOptValBool(pI830->Options, OPTION_SW_CURSOR, FALSE)) { - pI830->SWCursor = TRUE; + if (!xf86SetGamma(pScrn, zeros)) { + PreInitCleanup(pScrn); + return FALSE; } - pI830->directRenderingDisabled = - !xf86ReturnOptValBool(pI830->Options, OPTION_DRI, TRUE); - -#ifdef XF86DRI - if (!pI830->directRenderingDisabled) { - if (pI830->accel == ACCEL_NONE || pI830->SWCursor) { - xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "DRI is disabled because it " - "needs HW cursor and 2D acceleration.\n"); - pI830->directRenderingDisabled = TRUE; - } else if (pScrn->depth != 16 && pScrn->depth != 24) { - xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "DRI is disabled because it " - "runs only at depths 16 and 24.\n"); - pI830->directRenderingDisabled = TRUE; - } - - if (!pI830->directRenderingDisabled) { - pI830->allocate_classic_textures = TRUE; - - from = X_PROBED; - -#ifdef XF86DRI - if (!IS_I965G(pI830)) { - Bool tmp; - - if (xf86GetOptValBool(pI830->Options, - OPTION_INTELTEXPOOL, &tmp)) { - from = X_CONFIG; - if (!tmp) - pI830->allocate_classic_textures = FALSE; - } - } -#endif - } - } - -#endif - if (i830_bios_init(pScrn)) - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "VBIOS initialization failed.\n"); - - I830PreInitDDC(pScrn); - for (i = 0; i < num_pipe; i++) { - i830_crtc_init(pScrn, i); - } - I830SetupOutputs(pScrn); - - SaveHWState(pScrn); - if (!xf86InitialConfiguration (pScrn, FALSE)) - { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes.\n"); - RestoreHWState(pScrn); - PreInitCleanup(pScrn); - return FALSE; - } - RestoreHWState(pScrn); - - /* XXX This should go away, replaced by xf86Crtc.c support for it */ - pI830->rotation = RR_Rotate_0; - - /* - * Let's setup the mobile systems to check the lid status - */ - if (IS_MOBILE(pI830)) { - pI830->checkDevices = TRUE; - - if (!xf86ReturnOptValBool(pI830->Options, OPTION_CHECKDEVICES, TRUE)) { - pI830->checkDevices = FALSE; - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Monitoring connected displays disabled\n"); - } else - if (pI830->entityPrivate && !I830IsPrimary(pScrn) && - !I830PTR(pI830->entityPrivate->pScrn_1)->checkDevices) { - /* If checklid is off, on the primary head, then - * turn it off on the secondary*/ - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Monitoring connected displays disabled\n"); - pI830->checkDevices = FALSE; - } else - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Monitoring connected displays enabled\n"); - } else - pI830->checkDevices = FALSE; - - pI830->stolen_size = I830DetectMemory(pScrn); - - pI830->XvDisabled = - !xf86ReturnOptValBool(pI830->Options, OPTION_XVIDEO, TRUE); - -#ifdef I830_XV - if (xf86GetOptValInteger(pI830->Options, OPTION_VIDEO_KEY, - &(pI830->colorKey))) { - from = X_CONFIG; - } else if (xf86GetOptValInteger(pI830->Options, OPTION_COLOR_KEY, - &(pI830->colorKey))) { - from = X_CONFIG; - } else { - pI830->colorKey = (1 << pScrn->offset.red) | - (1 << pScrn->offset.green) | - (((pScrn->mask.blue >> pScrn->offset.blue) - 1) << - pScrn->offset.blue); - from = X_DEFAULT; - } - xf86DrvMsg(pScrn->scrnIndex, from, "video overlay key set to 0x%x\n", - pI830->colorKey); -#endif - -#ifdef XF86DRI - pI830->allowPageFlip = FALSE; - from = (!pI830->directRenderingDisabled && - xf86GetOptValBool(pI830->Options, OPTION_PAGEFLIP, - &pI830->allowPageFlip)) ? X_CONFIG : X_DEFAULT; - - xf86DrvMsg(pScrn->scrnIndex, from, "Will%s try to enable page flipping\n", - pI830->allowPageFlip ? "" : " not"); -#endif - -#ifdef XF86DRI - pI830->TripleBuffer = FALSE; - from = (!pI830->directRenderingDisabled && - xf86GetOptValBool(pI830->Options, OPTION_TRIPLEBUFFER, - &pI830->TripleBuffer)) ? X_CONFIG : X_DEFAULT; - - xf86DrvMsg(pScrn->scrnIndex, from, "Triple buffering %sabled\n", - pI830->TripleBuffer ? "en" : "dis"); -#endif - -#ifdef INTEL_XVMC - pI830->XvMCEnabled = FALSE; - from = (!pI830->directRenderingDisabled && - xf86GetOptValBool(pI830->Options, OPTION_XVMC, - &pI830->XvMCEnabled)) ? X_CONFIG : X_DEFAULT; - xf86DrvMsg(pScrn->scrnIndex, from, "Intel XvMC decoder %sabled\n", - pI830->XvMCEnabled ? "en" : "dis"); -#endif - - /* - * If the driver can do gamma correction, it should call xf86SetGamma() here. - */ - - { - Gamma zeros = { 0.0, 0.0, 0.0 }; - - if (!xf86SetGamma(pScrn, zeros)) { - PreInitCleanup(pScrn); - return FALSE; - } - } - - /* Check if the HW cursor needs physical address. */ - if (IS_MOBILE(pI830) || IS_I9XX(pI830)) - pI830->CursorNeedsPhysical = TRUE; - else - pI830->CursorNeedsPhysical = FALSE; - - if (IS_I965G(pI830) || IS_G33CLASS(pI830)) - pI830->CursorNeedsPhysical = FALSE; + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "VBIOS initialization failed.\n"); /* * XXX If we knew the pre-initialised GTT format for certain, we could @@ -1780,8 +1902,8 @@ I830PreInit(ScrnInfoPtr pScrn, int flags) "Using HW Cursor because it's enabled on primary head.\n"); pI830->SWCursor = FALSE; } - } else - if (pI830->StolenOnly && pI830->CursorNeedsPhysical && !pI830->SWCursor) { + } else if (pI830->StolenOnly && pI830->CursorNeedsPhysical && + !pI830->SWCursor) { xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "HW Cursor disabled because it needs agpgart memory.\n"); pI830->SWCursor = TRUE; @@ -1854,21 +1976,16 @@ I830PreInit(ScrnInfoPtr pScrn, int flags) xf86LoaderReqSymLists(I810ramdacSymbols, NULL); } - i830CompareRegsToSnapshot(pScrn, "After PreInit"); + if (!pI830->use_drm_mode) { + i830CompareRegsToSnapshot(pScrn, "After PreInit"); - 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); + I830UnmapMMIO(pScrn); -#if 0 - if (I830IsPrimary(pScrn)) { - vbeFree(pI830->pVbe); + /* We won't be using the VGA access after the probe. */ + I830SetMMIOAccess(pI830); + xf86SetOperatingState(resVgaIo, pI830->pEnt->index, ResUnusedOpr); + xf86SetOperatingState(resVgaMem, pI830->pEnt->index, ResDisableOpr); } - pI830->pVbe = NULL; -#endif #if defined(XF86DRI) /* Load the dri module if requested. */ @@ -2819,68 +2936,16 @@ i830_init_bufmgr(ScrnInfoPtr pScrn) } -static Bool -I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) +static void +I830AdjustMemory(ScreenPtr pScreen) { ScrnInfoPtr pScrn; - vgaHWPtr hwp; I830Ptr pI830; - VisualPtr visual; - I830Ptr pI8301 = NULL; unsigned long sys_mem; - int c; MessageType from; -#ifdef XF86DRI - xf86CrtcConfigPtr config; -#endif pScrn = xf86Screens[pScreen->myNum]; pI830 = I830PTR(pScrn); - hwp = VGAHWPTR(pScrn); - - pScrn->displayWidth = (pScrn->virtualX + 63) & ~63; - - /* - * The "VideoRam" config file parameter specifies the maximum amount of - * memory that will be used/allocated. When not present, we allow the - * driver to allocate as much memory as it wishes to satisfy its - * allocations, but if agpgart support isn't available, it gets limited - * to the amount of pre-allocated ("stolen") memory. - * - * Note that in using this value for allocator initialization, we're - * limiting aperture allocation to the VideoRam option, rather than limiting - * actual memory allocation, so alignment and things will cause less than - * VideoRam to be actually used. - */ - if (pI830->pEnt->device->videoRam == 0) { - from = X_DEFAULT; - pScrn->videoRam = pI830->FbMapSize / KB(1); - } else { -#if 0 - from = X_CONFIG; - pScrn->videoRam = pI830->pEnt->device->videoRam; -#else - /* Disable VideoRam configuration, at least for now. Previously, - * VideoRam was necessary to avoid overly low limits on allocated - * memory, so users created larger, yet still small, fixed allocation - * limits in their config files. Now, the driver wants to allocate more, - * and the old intention of the VideoRam lines that had been entered is - * obsolete. - */ - from = X_DEFAULT; - pScrn->videoRam = pI830->FbMapSize / KB(1); - - if (pScrn->videoRam != pI830->pEnt->device->videoRam) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "VideoRam configuration found, which is no longer " - "recommended.\n"); - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Continuing with default %dkB VideoRam instead of %d " - "kB.\n", - pScrn->videoRam, pI830->pEnt->device->videoRam); - } -#endif - } /* Limit videoRam to how much we might be able to allocate from AGP */ sys_mem = I830CheckAvailableMemory(pScrn); @@ -2931,6 +2996,129 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) "Cannot support DRI with frame buffer width > 2048.\n"); pI830->directRenderingDisabled = TRUE; } +} + +static void +I830SwapPipes(ScrnInfoPtr pScrn) +{ + I830Ptr pI830 = I830PTR(pScrn); + xf86CrtcConfigPtr config; + int c; + + config = XF86_CRTC_CONFIG_PTR(pScrn); + + /* + * If an LVDS display is present, swap the plane/pipe mappings so we can + * use FBC on the builtin display. + * Note: 965+ chips can compress either plane, so we leave the mapping + * alone in that case. + * Also make sure the DRM can handle the swap. + */ + if (I830LVDSPresent(pScrn) && !IS_I965GM(pI830) && !IS_GM45(pI830) && + (!pI830->directRenderingEnabled || + (pI830->directRenderingEnabled && pI830->drmMinor >= 10))) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "adjusting plane->pipe mappings " + "to allow for framebuffer compression\n"); + for (c = 0; c < config->num_crtc; c++) { + xf86CrtcPtr crtc = config->crtc[c]; + I830CrtcPrivatePtr intel_crtc = crtc->driver_private; + + if (intel_crtc->pipe == 0) + intel_crtc->plane = 1; + else if (intel_crtc->pipe == 1) + intel_crtc->plane = 0; + } + } +} + +static Bool +I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) +{ + ScrnInfoPtr pScrn; + vgaHWPtr hwp; + I830Ptr pI830; + VisualPtr visual; + I830Ptr pI8301 = NULL; + MessageType from; + + pScrn = xf86Screens[pScreen->myNum]; + pI830 = I830PTR(pScrn); + + if (!pI830->use_drm_mode) + hwp = VGAHWPTR(pScrn); + + pScrn->displayWidth = (pScrn->virtualX + 63) & ~63; + + /* + * The "VideoRam" config file parameter specifies the maximum amount of + * memory that will be used/allocated. When not present, we allow the + * driver to allocate as much memory as it wishes to satisfy its + * allocations, but if agpgart support isn't available, it gets limited + * to the amount of pre-allocated ("stolen") memory. + * + * Note that in using this value for allocator initialization, we're + * limiting aperture allocation to the VideoRam option, rather than limiting + * actual memory allocation, so alignment and things will cause less than + * VideoRam to be actually used. + */ + if (pI830->pEnt->device->videoRam == 0) { + from = X_DEFAULT; + pScrn->videoRam = pI830->FbMapSize / KB(1); + } else { +#if 0 + from = X_CONFIG; + pScrn->videoRam = pI830->pEnt->device->videoRam; +#else + /* Disable VideoRam configuration, at least for now. Previously, + * VideoRam was necessary to avoid overly low limits on allocated + * memory, so users created larger, yet still small, fixed allocation + * limits in their config files. Now, the driver wants to allocate more, + * and the old intention of the VideoRam lines that had been entered is + * obsolete. + */ + from = X_DEFAULT; + pScrn->videoRam = pI830->FbMapSize / KB(1); + + if (pScrn->videoRam != pI830->pEnt->device->videoRam) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "VideoRam configuration found, which is no longer " + "recommended.\n"); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Continuing with default %dkB VideoRam instead of %d " + "kB.\n", + pScrn->videoRam, pI830->pEnt->device->videoRam); + } +#endif + } + + 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 { + I830AdjustMemory(pScreen); + } #ifdef XF86DRI /* If DRI hasn't been explicitly disabled, try to initialize it. @@ -2969,6 +3157,12 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) pI830->fb_compression = FALSE; } + if (pI830->use_drm_mode && pI830->fb_compression == TRUE) { + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "Kernel mode setting active, disabling FBC.\n"); + pI830->fb_compression = FALSE; + } + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Framebuffer compression %sabled\n", pI830->fb_compression ? "en" : "dis"); xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Tiling %sabled\n", pI830->tiling ? @@ -3010,7 +3204,8 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) /* Need MMIO mapped to do GTT lookups during memory allocation. */ - I830MapMMIO(pScrn); + if (!pI830->use_drm_mode) + I830MapMMIO(pScrn); if (!i830_memory_init(pScrn)) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, @@ -3051,7 +3246,7 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) pI830->XvEnabled = FALSE; #endif - if (pI830->accel != ACCEL_NONE) { + if (pI830->accel != ACCEL_NONE && !pI830->use_drm_mode) { if (pI830->memory_manager == NULL && pI830->LpRing->mem->size == 0) { xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Disabling acceleration because the ring buffer " @@ -3092,69 +3287,49 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) } if (pI830->directRenderingEnabled) - pI830->directRenderingEnabled = I830DRIDoMappings(pScreen); + pI830->directRenderingEnabled = I830DRIDoMappings(pScreen); /* If we failed for any reason, free DRI memory. */ if (!pI830->directRenderingEnabled) - i830_free_3d_memory(pScrn); - - config = XF86_CRTC_CONFIG_PTR(pScrn); - - /* - * If an LVDS display is present, swap the plane/pipe mappings so we can - * use FBC on the builtin display. - * Note: 965+ chips can compress either plane, so we leave the mapping - * alone in that case. - * Also make sure the DRM can handle the swap. - */ - if (I830LVDSPresent(pScrn) && !IS_I965GM(pI830) && !IS_GM45(pI830) && - (!pI830->directRenderingEnabled || - (pI830->directRenderingEnabled && pI830->drmMinor >= 10))) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "adjusting plane->pipe mappings " - "to allow for framebuffer compression\n"); - for (c = 0; c < config->num_crtc; c++) { - xf86CrtcPtr crtc = config->crtc[c]; - I830CrtcPrivatePtr intel_crtc = crtc->driver_private; - - if (intel_crtc->pipe == 0) - intel_crtc->plane = 1; - else if (intel_crtc->pipe == 1) - intel_crtc->plane = 0; - } - } + i830_free_3d_memory(pScrn); + if (!pI830->use_drm_mode) + I830SwapPipes(pScrn); #else pI830->directRenderingEnabled = FALSE; #endif #ifdef XF86DRI - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Page Flipping %sabled\n", pI830->allowPageFlip ? "en" : "dis"); #endif - DPRINTF(PFX, "assert( if(!I830MapMem(pScrn)) )\n"); - if (!I830MapMem(pScrn)) - return FALSE; + if (!pI830->use_drm_mode) { + DPRINTF(PFX, "assert( if(!I830MapMem(pScrn)) )\n"); + if (!I830MapMem(pScrn)) + return FALSE; - pScrn->memPhysBase = (unsigned long)pI830->FbBase; + pScrn->memPhysBase = (unsigned long)pI830->FbBase; + } if (I830IsPrimary(pScrn)) { - pScrn->fbOffset = pI830->front_buffer->offset; + pScrn->fbOffset = pI830->front_buffer->offset; } else { - pScrn->fbOffset = pI8301->front_buffer_2->offset; + pScrn->fbOffset = pI8301->front_buffer_2->offset; } pI830->xoffset = (pScrn->fbOffset / pI830->cpp) % pScrn->displayWidth; pI830->yoffset = (pScrn->fbOffset / pI830->cpp) / pScrn->displayWidth; - i830_init_bufmgr(pScrn); + if (!pI830->use_drm_mode) { + vgaHWSetMmioFuncs(hwp, pI830->MMIOBase, 0); + vgaHWGetIOBase(hwp); + DPRINTF(PFX, "assert( if(!vgaHWMapMem(pScrn)) )\n"); + if (!vgaHWMapMem(pScrn)) + return FALSE; + } - vgaHWSetMmioFuncs(hwp, pI830->MMIOBase, 0); - vgaHWGetIOBase(hwp); - DPRINTF(PFX, "assert( if(!vgaHWMapMem(pScrn)) )\n"); - if (!vgaHWMapMem(pScrn)) - return FALSE; + i830_init_bufmgr(pScrn); DPRINTF(PFX, "assert( if(!I830EnterVT(scrnIndex, 0)) )\n"); @@ -3395,21 +3570,22 @@ I830LeaveVT(int scrnIndex, int flags) I830Sync(pScrn); - RestoreHWState(pScrn); - - /* Evict everything from the bufmgr, as we're about to lose ownership of - * the graphics memory. - */ - if (!pI830->memory_manager) - intel_bufmgr_fake_evict_all(pI830->bufmgr); - intel_batch_teardown(pScrn); + if (!pI830->use_drm_mode) { + RestoreHWState(pScrn); + /* Evict everything from the bufmgr, as we're about to lose ownership of + * the graphics memory. + */ + if (!pI830->memory_manager) + intel_bufmgr_fake_evict_all(pI830->bufmgr); + intel_batch_teardown(pScrn); - if (!pI830->memory_manager) - i830_stop_ring(pScrn, TRUE); + if (!pI830->memory_manager) + i830_stop_ring(pScrn, TRUE); - if (pI830->debug_modes) { - i830CompareRegsToSnapshot(pScrn, "After LeaveVT"); - i830DumpRegs (pScrn); + if (pI830->debug_modes) { + i830CompareRegsToSnapshot(pScrn, "After LeaveVT"); + i830DumpRegs (pScrn); + } } if (I830IsPrimary(pScrn)) @@ -3452,7 +3628,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; @@ -3484,39 +3661,43 @@ I830EnterVT(int scrnIndex, int flags) if ((pI830->accel == ACCEL_EXA || pI830->accel == ACCEL_UXA) && IS_I965G(pI830)) gen4_render_state_init(pScrn); - if (i830_check_error_state(pScrn)) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Existing errors found in hardware state.\n"); - } + if (!pI830->use_drm_mode) { + if (i830_check_error_state(pScrn)) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Existing errors found in hardware state.\n"); + } - /* Re-set up the ring. */ - if (!pI830->memory_manager) { - i830_stop_ring(pScrn, FALSE); - i830_start_ring(pScrn); - } - if (!pI830->SWCursor) - I830InitHWCursor(pScrn); + /* Re-set up the ring. */ + if (!pI830->memory_manager) { + i830_stop_ring(pScrn, FALSE); + i830_start_ring(pScrn); + } + if (!pI830->SWCursor) + I830InitHWCursor(pScrn); - /* Tell the BIOS that we're in control of mode setting now. */ - i830_init_bios_control(pScrn); + /* Tell the BIOS that we're in control of mode setting now. */ + i830_init_bios_control(pScrn); - i830_init_clock_gating(pScrn); + i830_init_clock_gating(pScrn); - if (pI830->power_context) - OUTREG(PWRCTXA, pI830->power_context->offset | PWRCTX_EN); + if (pI830->power_context) + OUTREG(PWRCTXA, pI830->power_context->offset | PWRCTX_EN); - /* Clear the framebuffer */ - memset(pI830->FbBase + pScrn->fbOffset, 0, - pScrn->virtualY * pScrn->displayWidth * pI830->cpp); + /* Clear the framebuffer */ + memset(pI830->FbBase + pScrn->fbOffset, 0, + pScrn->virtualY * pScrn->displayWidth * pI830->cpp); + } if (!xf86SetDesiredModes (pScrn)) return FALSE; - - if (pI830->debug_modes) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Hardware state at EnterVT:\n"); - i830DumpRegs (pScrn); + + if (!pI830->use_drm_mode) { + if (pI830->debug_modes) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Hardware state at EnterVT:\n"); + i830DumpRegs (pScrn); + } + i830DescribeOutputConfiguration(pScrn); } - i830DescribeOutputConfiguration(pScrn); #ifdef XF86DRI if (pI830->directRenderingEnabled) { @@ -3614,9 +3795,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_memory.c b/src/i830_memory.c index ff5def69..57b9d275 100644 --- a/src/i830_memory.c +++ b/src/i830_memory.c @@ -184,7 +184,7 @@ i830_bind_memory(ScrnInfoPtr pScrn, i830_memory *mem) if (!pI830->gtt_acquired) return TRUE; - if (mem->key != -1 && + if (mem->key != -1 && !xf86BindGARTMemory(pScrn->scrnIndex, mem->key, mem->agp_offset)) { return FALSE; @@ -193,7 +193,7 @@ i830_bind_memory(ScrnInfoPtr pScrn, i830_memory *mem) mem->bound = TRUE; } - if (mem->tiling != TILE_NONE) { + if (mem->tiling != TILE_NONE && pI830->use_drm_mode) { mem->fence_nr = i830_set_tiling(pScrn, mem->offset, mem->pitch, mem->allocated_size, mem->tiling); } @@ -204,10 +204,12 @@ i830_bind_memory(ScrnInfoPtr pScrn, i830_memory *mem) static Bool i830_unbind_memory(ScrnInfoPtr pScrn, i830_memory *mem) { + I830Ptr pI830 = I830PTR(pScrn); + if (mem == NULL || !mem->bound) return TRUE; - if (mem->tiling != TILE_NONE) + if (mem->tiling != TILE_NONE && !pI830->use_drm_mode) i830_clear_tiling(pScrn, mem->fence_nr); #ifdef XF86DRI @@ -460,22 +462,24 @@ i830_allocator_init(ScrnInfoPtr pScrn, unsigned long offset, unsigned long size) ALIGN_BOTH_ENDS | NEED_NON_STOLEN); if (pI830->memory_manager != NULL) { - struct drm_i915_gem_init init; - int ret; - - init.gtt_start = pI830->memory_manager->offset; - init.gtt_end = pI830->memory_manager->offset + - pI830->memory_manager->size; - - /* Tell the kernel to manage it */ - ret = ioctl(pI830->drmSubFD, DRM_IOCTL_I915_GEM_INIT, &init); - if (ret != 0) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Failed to initialize kernel memory manager\n"); - i830_free_memory(pScrn, pI830->memory_manager); - pI830->memory_manager = NULL; + if (!pI830->use_drm_mode) { + struct drm_i915_gem_init init; + int ret; + + init.gtt_start = pI830->memory_manager->offset; + init.gtt_end = pI830->memory_manager->offset + + pI830->memory_manager->size; + + /* Tell the kernel to manage it */ + ret = ioctl(pI830->drmSubFD, DRM_IOCTL_I915_GEM_INIT, &init); + if (ret != 0) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Failed to initialize kernel memory manager\n"); + i830_free_memory(pScrn, pI830->memory_manager); + pI830->memory_manager = NULL; + } + i830_init_bufmgr(pScrn); } - i830_init_bufmgr(pScrn); } else { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to allocate space for kernel memory manager\n"); @@ -800,8 +804,9 @@ i830_allocate_memory(ScrnInfoPtr pScrn, const char *name, #ifdef XF86DRI I830Ptr pI830 = I830PTR(pScrn); - if (pI830->memory_manager && !(flags & NEED_PHYSICAL_ADDR) && - !(flags & NEED_LIFETIME_FIXED)) + if (pI830->use_drm_mode || (pI830->memory_manager && + !(flags & NEED_PHYSICAL_ADDR) && + !(flags & NEED_LIFETIME_FIXED))) { return i830_allocate_memory_bo(pScrn, name, size, alignment, flags); } else @@ -1025,6 +1030,7 @@ i830_allocate_overlay(ScrnInfoPtr pScrn) { I830Ptr pI830 = I830PTR(pScrn); int flags = 0; + int mem_space = DRM_BO_FLAG_MEM_TT; /* Only allocate if overlay is going to be enabled. */ if (!pI830->XvEnabled) @@ -1045,6 +1051,10 @@ i830_allocate_overlay(ScrnInfoPtr pScrn) /* This failure isn't fatal. */ } + if (flags & NEED_PHYSICAL_ADDR) + if (pI830->use_drm_mode) + mem_space = DRM_BO_FLAG_MEM_VRAM; + return TRUE; } #endif @@ -1122,7 +1132,7 @@ i830_allocate_framebuffer(ScrnInfoPtr pScrn, I830Ptr pI830, BoxPtr FbMemBox, /* We'll allocate the fb such that the root window will fit regardless of * rotation. */ - if (pScrn->virtualX > pScrn->virtualY) + if (!pI830->use_drm_mode && pScrn->virtualX > pScrn->virtualY) fb_height = pScrn->virtualX; else fb_height = pScrn->virtualY; @@ -1186,7 +1196,7 @@ i830_allocate_framebuffer(ScrnInfoPtr pScrn, I830Ptr pI830, BoxPtr FbMemBox, * acceleration operations (non-XY COLOR_BLT) can't be done to tiled * buffers. */ - if (pI830->accel <= ACCEL_XAA && IS_I965G(pI830)) + if ((pI830->accel <= ACCEL_XAA && IS_I965G(pI830)) || pI830->use_drm_mode) tiling = FALSE; else tiling = pI830->tiling; @@ -1215,8 +1225,14 @@ i830_allocate_framebuffer(ScrnInfoPtr pScrn, I830Ptr pI830, BoxPtr FbMemBox, return NULL; } - if (pI830->FbBase) + 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; } @@ -1225,10 +1241,15 @@ i830_allocate_cursor_buffers(ScrnInfoPtr pScrn) { I830Ptr pI830 = I830PTR(pScrn); xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); - int flags = pI830->CursorNeedsPhysical ? NEED_PHYSICAL_ADDR : 0; + int flags; int i; long size; + if (pI830->use_drm_mode) + pI830->CursorNeedsPhysical = FALSE; + + flags = pI830->CursorNeedsPhysical ? NEED_PHYSICAL_ADDR : 0; + /* Try to allocate one big blob for our cursor memory. This works * around a limitation in the FreeBSD AGP driver that allows only one * physical allocation larger than a page, and could allow us @@ -1341,18 +1362,20 @@ i830_allocate_2d_memory(ScrnInfoPtr pScrn) unsigned int pitch = pScrn->displayWidth * pI830->cpp; long size; - if (!pI830->StolenOnly && - (!xf86AgpGARTSupported() || !xf86AcquireGART(pScrn->scrnIndex))) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "AGP GART support is either not available or cannot " - "be used.\n" - "\tMake sure your kernel has agpgart support or has\n" - "\tthe agpgart module loaded.\n"); - return FALSE; - } + if (!pI830->use_drm_mode) { + if (!pI830->StolenOnly && + (!xf86AgpGARTSupported() || !xf86AcquireGART(pScrn->scrnIndex))) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "AGP GART support is either not available or cannot " + "be used.\n" + "\tMake sure your kernel has agpgart support or has\n" + "\tthe agpgart module loaded.\n"); + return FALSE; + } - /* Allocate the ring buffer first, so it ends up in stolen mem. */ - i830_allocate_ringbuffer(pScrn); + /* Allocate the ring buffer first, so it ends up in stolen mem. */ + i830_allocate_ringbuffer(pScrn); + } if (pI830->fb_compression) i830_setup_fb_compression(pScrn); @@ -1950,13 +1973,15 @@ i830_bind_all_memory(ScrnInfoPtr pScrn) if (pI830->StolenOnly == TRUE || pI830->memory_list == NULL) return TRUE; - if (xf86AgpGARTSupported() && !pI830->gtt_acquired) { + if (pI830->use_drm_mode || (xf86AgpGARTSupported() && + !pI830->gtt_acquired)) { i830_memory *mem; - if (!xf86AcquireGART(pScrn->scrnIndex)) - return FALSE; - - pI830->gtt_acquired = TRUE; + if (!pI830->use_drm_mode) { + if (!xf86AcquireGART(pScrn->scrnIndex)) + return FALSE; + pI830->gtt_acquired = TRUE; + } for (mem = pI830->memory_list->next; mem->next != NULL; mem = mem->next) @@ -1971,7 +1996,7 @@ i830_bind_all_memory(ScrnInfoPtr pScrn) FatalError("Couldn't bind memory for BO %s\n", mem->name); } } - if (!pI830->SWCursor) + if (!pI830->SWCursor && !pI830->use_drm_mode) i830_update_cursor_offsets(pScrn); return TRUE; @@ -1986,7 +2011,8 @@ i830_unbind_all_memory(ScrnInfoPtr pScrn) if (pI830->StolenOnly == TRUE) return TRUE; - if (xf86AgpGARTSupported() && pI830->gtt_acquired) { + if (pI830->use_drm_mode || (xf86AgpGARTSupported() && + pI830->gtt_acquired)) { i830_memory *mem; for (mem = pI830->memory_list->next; mem->next != NULL; @@ -2002,10 +2028,12 @@ i830_unbind_all_memory(ScrnInfoPtr pScrn) i830_unbind_memory(pScrn, mem); } - pI830->gtt_acquired = FALSE; + if (!pI830->use_drm_mode) { + pI830->gtt_acquired = FALSE; - if (!xf86ReleaseGART(pScrn->scrnIndex)) - return FALSE; + if (!xf86ReleaseGART(pScrn->scrnIndex)) + return FALSE; + } } return TRUE; @@ -2057,3 +2085,118 @@ Bool i830_allocate_xvmc_buffer(ScrnInfoPtr pScrn, const char *name, return TRUE; } #endif + +#ifdef XF86DRI_MM +#if 0 +static i830_memory * +i830_allocate_framebuffer_new(ScrnInfoPtr pScrn, I830Ptr pI830, BoxPtr FbMemBox) +{ + unsigned int pitch = pScrn->displayWidth * pI830->cpp; + unsigned long minspace, avail; + int cacheLines; + int align; + long size, fb_height; + char *name; + int flags; + i830_memory *front_buffer = NULL; + Bool tiling; + + flags = ALLOW_SHARING; + + /* Clear everything first. */ + memset(FbMemBox, 0, sizeof(*FbMemBox)); + + fb_height = pScrn->virtualY; + + FbMemBox->x1 = 0; + FbMemBox->x2 = pScrn->displayWidth; + FbMemBox->y1 = 0; + FbMemBox->y2 = fb_height; + + /* Calculate how much framebuffer memory to allocate. For the + * initial allocation, calculate a reasonable minimum. This is + * enough for the virtual screen size, plus some pixmap cache + * space if we're using XAA. + */ + minspace = pitch * pScrn->virtualY; + avail = pScrn->videoRam * 1024; + cacheLines = 0; + + size = pitch * (fb_height + cacheLines); + size = ROUND_TO_PAGE(size); + + name = "front buffer"; + + /* Front buffer tiling has to be disabled with G965 XAA because some of the + * acceleration operations (non-XY COLOR_BLT) can't be done to tiled + * buffers. + */ + if (!(pI830->accel == ACCEL_EXA) && IS_I965G(pI830)) + tiling = FALSE; + else + tiling = pI830->tiling; + + if (pI830->use_drm_mode) + tiling = FALSE; + + /* Attempt to allocate it tiled first if we have page flipping on. */ + if (tiling && IsTileable(pScrn, pitch)) { + /* XXX: probably not the case on 965 */ + if (IS_I9XX(pI830)) + align = MB(1); + else + align = KB(512); + front_buffer = i830_allocate_memory_tiled(pScrn, name, size, + pitch, align, flags, + TILE_XMAJOR); + } + + /* If not, attempt it linear */ + if (front_buffer == NULL) { + front_buffer = i830_allocate_memory(pScrn, name, size, KB(64), flags); + } + + if (front_buffer == NULL) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to allocate " + "framebuffer. Is your VideoRAM set too low?\n"); + + return NULL; + } + + return front_buffer; +} +#endif +uint32_t +i830_create_new_fb(ScrnInfoPtr pScrn, int width, int height, int *pitch) +{ + return 0; + +#if 0 + I830Ptr pI830 = I830PTR(pScrn); + i830_memory *old_buffer; + + pScrn->virtualX = width; + pScrn->virtualY = height; + pScrn->displayWidth = (pScrn->virtualX + 63) & ~63; + + *pitch = pScrn->displayWidth * pI830->cpp; + + old_buffer = pI830->front_buffer; + + pI830->front_buffer = + i830_allocate_framebuffer_new(pScrn, pI830, &pI830->FbMemBox); + + ErrorF("old front size %08lx, new front size %08lx\n", + old_buffer->bo->size, pI830->front_buffer->bo->size); + ErrorF("old front offset %08lx, new front offset %08lx\n", + old_buffer->bo->offset, pI830->front_buffer->bo->offset); + + i830_free_memory(pScrn, old_buffer); + + i830_update_front_offset(pScrn); + + return pI830->front_buffer->bo->handle; +#endif +} + +#endif diff --git a/src/i830_video.c b/src/i830_video.c index 1719835c..5e6ebd77 100644 --- a/src/i830_video.c +++ b/src/i830_video.c @@ -2394,7 +2394,7 @@ I830PutImage(ScrnInfoPtr pScrn, /* fixup pointers */ #ifdef INTEL_XVMC if (id == FOURCC_XVMC && IS_I915(pI830)) { - pPriv->YBuf0offset = (uint32_t)buf; + pPriv->YBuf0offset = (uint32_t)((uint64_t)buf); pPriv->VBuf0offset = pPriv->YBuf0offset + (dstPitch2 * height); pPriv->UBuf0offset = pPriv->VBuf0offset + (dstPitch * height / 2); destId = FOURCC_YV12; diff --git a/src/reg_dumper/reg_dumper.h b/src/reg_dumper/reg_dumper.h index 241b2419..9f24d5cc 100644 --- a/src/reg_dumper/reg_dumper.h +++ b/src/reg_dumper/reg_dumper.h @@ -52,6 +52,7 @@ struct pci_info_rec { typedef struct _i830 { /* Fields in common with the real pI830 */ struct pci_info_rec *PciInfo; + Bool use_drm_mode; /* Fields used for setting up reg_dumper */ struct pci_device *pci_dev; |