Initial port of kernel modesetting from old intel-kernelmode branch

Thanks airlied!
This commit is contained in:
Jesse Barnes 2008-08-08 11:54:18 -07:00
parent f9504eff31
commit b1aef6f63c
12 changed files with 1662 additions and 524 deletions

View File

@ -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 \

View File

@ -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 \

View File

@ -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))

695
src/drmmode_display.c Normal file
View File

@ -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

70
src/drmmode_display.h Normal file
View File

@ -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

View File

@ -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,

View File

@ -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,

View File

@ -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;

File diff suppressed because it is too large Load Diff

View File

@ -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;
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;
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;
/* 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

View File

@ -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;

View File

@ -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;