diff -Nru xf86-video-omap-0.4.0/NEWS xf86-video-omap-0.4.1/NEWS --- xf86-video-omap-0.4.0/NEWS 2012-06-20 13:17:08.000000000 +0000 +++ xf86-video-omap-0.4.1/NEWS 2012-10-06 12:31:07.000000000 +0000 @@ -13,3 +13,15 @@ * DRI2: Implement support for triple buffering. +Release 0.4.1 (2012-10-06) +========================== + +* xrandr rotation support. + +* Support for PlatformProbe for latest xserver. + +* DRI2: fix issue w/ flipping multiple drawables. + +* Various other fixes, including updates to build with latest + xserver. + diff -Nru xf86-video-omap-0.4.0/configure.ac xf86-video-omap-0.4.1/configure.ac --- xf86-video-omap-0.4.0/configure.ac 2012-06-20 13:17:08.000000000 +0000 +++ xf86-video-omap-0.4.1/configure.ac 2012-10-06 12:31:07.000000000 +0000 @@ -5,7 +5,7 @@ # XXX bug URL should be https://bugs.freedesktop.org/enter_bug.cgi?product=xorg # but this makes autoheader choke.. AC_INIT([xf86-video-omap], - [0.4.0], + [0.4.1], [https://bugs.freedesktop.org/enter_bug.cgi], [xf86-video-omap]) AC_CONFIG_SRCDIR([Makefile.am]) @@ -44,7 +44,7 @@ XORG_DRIVER_CHECK_EXT(DPMSExtension, xextproto) # Checks for pkg-config packages -PKG_CHECK_MODULES(XORG, [xorg-server >= 1.3] xproto fontsproto libdrm libdrm_omap xf86driproto $REQUIRED_MODULES) +PKG_CHECK_MODULES(XORG, [xorg-server >= 1.3] xproto fontsproto [libdrm >= 2.4.36] libdrm_omap xf86driproto $REQUIRED_MODULES) sdkdir=$(pkg-config --variable=sdkdir xorg-server) # Checks for header files. diff -Nru xf86-video-omap-0.4.0/debian/changelog xf86-video-omap-0.4.1/debian/changelog --- xf86-video-omap-0.4.0/debian/changelog 2012-08-23 13:58:21.000000000 +0000 +++ xf86-video-omap-0.4.1/debian/changelog 2012-10-09 11:14:38.000000000 +0000 @@ -1,17 +1,20 @@ -xf86-video-omap (0.4.0-0ubuntu2) quantal; urgency=low +xf86-video-omap (0.4.1-1) unstable; urgency=low - * Build depending and using quilt for patch management - * debian/patches/01-adding-support-for-platformProbe.patch: - - Adding support for platformProbe, for proper platform device support - (LP: #1015292) + * New upstream release + - xrandr rotation support + - support for PlatformProbe for latest xserver + - DRI2: fix issue w/ flipping multiple drawables + - misc. other fixes + * Update Debian Standards Version to 3.9.4 - -- Ricardo Salveti de Araujo Thu, 23 Aug 2012 02:02:54 -0300 + -- Sebastian Reichel Sun, 07 Oct 2012 13:14:53 +0200 -xf86-video-omap (0.4.0-0ubuntu1) quantal-proposed; urgency=low +xf86-video-omap (0.4.0-1) unstable; urgency=low - * New upstream release. + * New upstream release + - ported to compat-api to be compatible with more xorg releases - -- Timo Aaltonen Tue, 14 Aug 2012 11:41:13 +0300 + -- Sebastian Reichel Tue, 14 Aug 2012 17:50:12 +0200 xf86-video-omap (0.3.0-1) experimental; urgency=low diff -Nru xf86-video-omap-0.4.0/debian/control xf86-video-omap-0.4.1/debian/control --- xf86-video-omap-0.4.0/debian/control 2012-08-23 13:58:21.000000000 +0000 +++ xf86-video-omap-0.4.1/debian/control 2012-10-09 11:14:38.000000000 +0000 @@ -1,10 +1,8 @@ Source: xf86-video-omap Section: x11 Priority: optional -Maintainer: Ubuntu X-SWAT -XSBC-Original-Maintainer: Sebastian Reichel +Maintainer: Sebastian Reichel Build-Depends: debhelper (>= 8), - quilt, dh-autoreconf, libdrm-dev (>= 2.4.33-3), libudev-dev, @@ -16,7 +14,7 @@ x11proto-xf86dri-dev, xutils-dev, xserver-xorg-dev (>= 2:1.9.4) -Standards-Version: 3.9.3 +Standards-Version: 3.9.4 Vcs-Git: git://git.debian.org/git/collab-maint/xf86-video-omap Vcs-Browser: http://git.debian.org/?p=collab-maint/xf86-video-omap.git diff -Nru xf86-video-omap-0.4.0/debian/copyright xf86-video-omap-0.4.1/debian/copyright --- xf86-video-omap-0.4.0/debian/copyright 2012-08-14 08:40:51.000000000 +0000 +++ xf86-video-omap-0.4.1/debian/copyright 2012-10-09 11:14:38.000000000 +0000 @@ -3,13 +3,17 @@ Source: http://cgit.freedesktop.org/xorg/driver/xf86-video-omap/ Files: * -Copyright: 2011-2012, Texas Instruments, Inc +Copyright: 2011-2012, Texas Instruments, Inc. +License: Expat + +Files: src/compat-api.h +Copyright: 2012, Read Hat, Inc. License: Expat Files: src/drmmode_display.c Copyright: 2007, Red Hat, Inc. 2008, Maarten Maathuis - 2011-2012, Texas Instruments, Inc + 2011-2012, Texas Instruments, Inc. License: Expat Files: debian/* diff -Nru xf86-video-omap-0.4.0/debian/patches/01-adding-support-for-platformProbe.patch xf86-video-omap-0.4.1/debian/patches/01-adding-support-for-platformProbe.patch --- xf86-video-omap-0.4.0/debian/patches/01-adding-support-for-platformProbe.patch 2012-08-23 13:58:21.000000000 +0000 +++ xf86-video-omap-0.4.1/debian/patches/01-adding-support-for-platformProbe.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,149 +0,0 @@ -Description: adding support for platformProbe - Since xorg 1.12.99.901 we now have support for platform devices, which - is already responsible for looking over the devices from udev, and - setting up the device attributes, entity and platform slot, simplifying - the probe method. - . - The old probe function is still valid, and also used in case there's no - platform support, so this change only affects users building the driver - agains the latest xorg release. - . - As a consequence, xorg will only load and enable the omap xorg driver, - not loading fbdev and avoiding issues with Qt5 based applications. -Forwarded: yes -Bug-Ubuntu: http://bugs.launchpad.net/bugs/1015292 -Author: Ricardo Salveti de Araujo - -diff --git a/src/omap_driver.c b/src/omap_driver.c -index 178a4cd..43e5aa3 100644 ---- a/src/omap_driver.c -+++ b/src/omap_driver.c -@@ -54,6 +54,10 @@ static void OMAPAdjustFrame(ADJUST_FRAME_ARGS_DECL); - static Bool OMAPEnterVT(VT_FUNC_ARGS_DECL); - static void OMAPLeaveVT(VT_FUNC_ARGS_DECL); - static void OMAPFreeScreen(FREE_SCREEN_ARGS_DECL); -+#ifdef XSERVER_PLATFORM_BUS -+static Bool OMAPPlatformProbe(DriverPtr drv, int entity_num, int flags, -+ struct xf86_platform_device *dev, intptr_t match_data); -+#endif - - - -@@ -74,7 +78,10 @@ _X_EXPORT DriverRec OMAP = { - NULL, - #ifdef XSERVER_LIBPCIACCESS - NULL, -- NULL -+ NULL, -+#endif -+#ifdef XSERVER_PLATFORM_BUS -+ OMAPPlatformProbe, - #endif - }; - -@@ -267,7 +274,11 @@ OMAPSetup(pointer module, pointer opts, int *errmaj, int *errmin) - /* This module should be loaded only once, but check to be sure: */ - if (!setupDone) { - setupDone = TRUE; -+#ifdef XSERVER_PLATFORM_BUS -+ xf86AddDriver(&OMAP, module, HaveDriverFuncs); -+#else - xf86AddDriver(&OMAP, module, 0); -+#endif - - /* The return value must be non-NULL on success even though there is no - * TearDownProc. -@@ -435,6 +446,7 @@ OMAPPreInit(ScrnInfoPtr pScrn, int flags) - rgb defaultWeight = { 0, 0, 0 }; - rgb defaultMask = { 0, 0, 0 }; - Gamma defaultGamma = { 0.0, 0.0, 0.0 }; -+ EntityInfoPtr pEnt; - uint64_t value; - int i; - -@@ -457,7 +469,8 @@ OMAPPreInit(ScrnInfoPtr pScrn, int flags) - OMAPGetRec(pScrn); - pOMAP = OMAPPTR(pScrn); - -- pOMAP->pEntityInfo = xf86GetEntityInfo(pScrn->entityList[0]); -+ pEnt = xf86GetEntityInfo(pScrn->entityList[0]); -+ pOMAP->pEntityInfo = pEnt; - - pScrn->monitor = pScrn->confScreen->monitor; - -@@ -500,7 +513,17 @@ OMAPPreInit(ScrnInfoPtr pScrn, int flags) - /* Using a programmable clock: */ - pScrn->progClock = TRUE; - -- /* Open a connection to the DRM, so we can communicate with the KMS code: */ -+#ifdef XSERVER_PLATFORM_BUS -+ if (pEnt->location.type == BUS_PLATFORM) { -+ char *busid = xf86_get_platform_device_attrib(pEnt->location.id.plat, -+ ODEV_ATTRIB_BUSID); -+ pOMAP->drmFD = drmOpen(NULL, busid); -+ if (pOMAP->drmFD < 0) -+ goto fail; -+ pOMAP->deviceName = drmGetDeviceNameFromFd(pOMAP->drmFD); -+ } -+ else -+#endif - if (!OMAPOpenDRMMaster(pScrn, 0)) { - goto fail; - } -@@ -1057,3 +1080,42 @@ OMAPFreeScreen(FREE_SCREEN_ARGS_DECL) - TRACE_EXIT(); - } - -+#ifdef XSERVER_PLATFORM_BUS -+static Bool -+OMAPPlatformProbe(DriverPtr drv, int entity_num, int flags, -+ struct xf86_platform_device *dev, intptr_t match_data) -+{ -+ ScrnInfoPtr pScrn = NULL; -+ Bool foundScreen = FALSE; -+ char *busid = xf86_get_platform_device_attrib(dev, ODEV_ATTRIB_BUSID); -+ int fd; -+ -+ fd = drmOpen(NULL, busid); -+ if (fd != -1) { -+ pScrn = xf86AllocateScreen(drv, 0); -+ if (!pScrn) { -+ EARLY_ERROR_MSG("Cannot allocate a ScrnInfoPtr"); -+ return FALSE; -+ } -+ -+ xf86AddEntityToScreen(pScrn, entity_num); -+ foundScreen = TRUE; -+ -+ pScrn->driverVersion = OMAP_VERSION; -+ pScrn->driverName = (char *)OMAP_DRIVER_NAME; -+ pScrn->name = (char *)OMAP_NAME; -+ pScrn->Probe = OMAPProbe; -+ pScrn->PreInit = OMAPPreInit; -+ pScrn->ScreenInit = OMAPScreenInit; -+ pScrn->SwitchMode = OMAPSwitchMode; -+ pScrn->AdjustFrame = OMAPAdjustFrame; -+ pScrn->EnterVT = OMAPEnterVT; -+ pScrn->LeaveVT = OMAPLeaveVT; -+ pScrn->FreeScreen = OMAPFreeScreen; -+ -+ drmClose(fd); -+ } -+ -+ return foundScreen; -+} -+#endif -diff --git a/src/omap_driver.h b/src/omap_driver.h -index b1a98af..f3c88be 100644 ---- a/src/omap_driver.h -+++ b/src/omap_driver.h -@@ -56,6 +56,9 @@ - #include "xf86drm.h" - #include "drm_fourcc.h" - #include "dri2.h" -+#ifdef XSERVER_PLATFORM_BUS -+#include "xf86platformBus.h" -+#endif - - #include - #include diff -Nru xf86-video-omap-0.4.0/debian/patches/series xf86-video-omap-0.4.1/debian/patches/series --- xf86-video-omap-0.4.0/debian/patches/series 2012-08-23 13:58:21.000000000 +0000 +++ xf86-video-omap-0.4.1/debian/patches/series 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -01-adding-support-for-platformProbe.patch diff -Nru xf86-video-omap-0.4.0/debian/rules xf86-video-omap-0.4.1/debian/rules --- xf86-video-omap-0.4.0/debian/rules 2012-08-23 13:58:21.000000000 +0000 +++ xf86-video-omap-0.4.1/debian/rules 2012-10-09 11:14:38.000000000 +0000 @@ -1,6 +1,6 @@ #!/usr/bin/make -f %: - dh $@ --with autoreconf,quilt,xsf + dh $@ --with autoreconf,xsf # create m4 directory before running autoreconf override_dh_autoreconf: diff -Nru xf86-video-omap-0.4.0/src/compat-api.h xf86-video-omap-0.4.1/src/compat-api.h --- xf86-video-omap-0.4.0/src/compat-api.h 2012-06-20 13:17:08.000000000 +0000 +++ xf86-video-omap-0.4.1/src/compat-api.h 2012-10-06 12:31:07.000000000 +0000 @@ -64,6 +64,8 @@ #define VT_FUNC_ARGS_DECL int arg, int flags #define VT_FUNC_ARGS(flags) pScrn->scrnIndex, (flags) +#define ENABLE_DISABLE_FB_ACCESS_ARGS(pScrn, b) pScrn->scrnIndex, b + #define XF86_ENABLEDISABLEFB_ARG(x) ((x)->scrnIndex) #else #define SCRN_ARG_TYPE ScrnInfoPtr @@ -89,6 +91,8 @@ #define VT_FUNC_ARGS_DECL ScrnInfoPtr arg #define VT_FUNC_ARGS(flags) pScrn +#define ENABLE_DISABLE_FB_ACCESS_ARGS(pScrn, b) pScrn, b + #define XF86_ENABLEDISABLEFB_ARG(x) (x) #endif diff -Nru xf86-video-omap-0.4.0/src/drmmode_display.c xf86-video-omap-0.4.1/src/drmmode_display.c --- xf86-video-omap-0.4.0/src/drmmode_display.c 2012-06-20 13:17:08.000000000 +0000 +++ xf86-video-omap-0.4.1/src/drmmode_display.c 2012-10-06 12:31:07.000000000 +0000 @@ -51,9 +51,6 @@ #include "compiler.h" #include "mipointer.h" -/* All drivers implementing backing store need this */ -#include "mibstore.h" - #include "micmap.h" #include "xf86DDC.h" @@ -84,6 +81,7 @@ #endif #include "omap_driver.h" +#include "omap_drm.h" #include "xf86Crtc.h" @@ -111,11 +109,16 @@ struct udev_monitor *uevent_monitor; InputHandlerProc uevent_handler; drmmode_cursor_ptr cursor; + int rotated_crtcs; } drmmode_rec, *drmmode_ptr; typedef struct { drmmode_ptr drmmode; drmModeCrtcPtr mode_crtc; + Rotation rotation; + + /* properties that we care about: */ + uint32_t prop_rotation; } drmmode_crtc_private_rec, *drmmode_crtc_private_ptr; typedef struct { @@ -215,33 +218,50 @@ // FIXME - Implement this function } +#define SUPPORTED_ROTATIONS (RR_Rotate_0 | RR_Rotate_90 | RR_Rotate_180 | RR_Rotate_270 | RR_Reflect_X | RR_Reflect_Y) + static Bool -drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode, - Rotation rotation, int x, int y) +drmmode_set_rotation(xf86CrtcPtr crtc, Rotation rotation) +{ +#if XF86_CRTC_VERSION >= 4 + ScrnInfoPtr pScrn = crtc->scrn; + drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; + + if (!(rotation & ~SUPPORTED_ROTATIONS)) { + int ret; + + ret = drmModeObjectSetProperty(drmmode_crtc->drmmode->fd, + drmmode_crtc->mode_crtc->crtc_id, + DRM_MODE_OBJECT_CRTC, + drmmode_crtc->prop_rotation, + rotation); + if (ret) { + ERROR_MSG("failed to set orientation %s", strerror(errno)); + return FALSE; + } + + crtc->driverIsPerformingTransform = TRUE; + } +#endif + return xf86CrtcRotate(crtc); +} + +static Bool +drmmode_restore_crtc(xf86CrtcPtr crtc) { ScrnInfoPtr pScrn = crtc->scrn; OMAPPtr pOMAP = OMAPPTR(pScrn); 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 = NULL; int output_count = 0; int ret = TRUE; int i; - int fb_id; drmModeModeInfo kmode; - TRACE_ENTER(); - - /* remove old fb if it exists */ - drmmode_remove_fb(pScrn); - if (drmmode->fb_id == 0) { - unsigned int pitch = - OMAPCalculateStride(pScrn->virtualX, pScrn->bitsPerPixel); + unsigned int pitch = pScrn->displayWidth * (pScrn->bitsPerPixel / 8); DEBUG_MSG("create framebuffer: %dx%d", pScrn->virtualX, pScrn->virtualY); @@ -252,29 +272,15 @@ pitch, omap_bo_handle(pOMAP->scanout), &drmmode->fb_id); if (ret < 0) { - // Fixme - improve this error message: - ErrorF("failed to add fb\n"); + ERROR_MSG("failed to add fb: %s", strerror(errno)); return FALSE; } } - /* Save the current mode in case there's a problem: */ - saved_mode = crtc->mode; - saved_x = crtc->x; - saved_y = crtc->y; - saved_rotation = crtc->rotation; - - /* Set the new mode: */ - crtc->mode = *mode; - crtc->x = x; - crtc->y = y; - crtc->rotation = rotation; - output_ids = calloc(sizeof(uint32_t), xf86_config->num_output); if (!output_ids) { - // Fixme - have an error message? - ret = FALSE; - goto done; + ERROR_MSG("allocation failed"); + return FALSE; } for (i = 0; i < xf86_config->num_output; i++) { @@ -290,29 +296,18 @@ output_count++; } - if (!xf86CrtcRotate(crtc)) - goto done; - - // Fixme - Intel puts this function here, and Nouveau puts it at the end - // of this function -> determine what's best for TI'S OMAP4: - crtc->funcs->gamma_set(crtc, crtc->gamma_red, crtc->gamma_green, - crtc->gamma_blue, crtc->gamma_size); - - drmmode_ConvertToKMode(crtc->scrn, &kmode, mode); - - fb_id = drmmode->fb_id; + drmmode_ConvertToKMode(crtc->scrn, &kmode, &crtc->mode); ret = drmModeSetCrtc(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, - fb_id, x, y, output_ids, output_count, &kmode); + drmmode->fb_id, crtc->x, crtc->y, + output_ids, output_count, &kmode); if (ret) { - xf86DrvMsg(crtc->scrn->scrnIndex, X_ERROR, - "failed to set mode: %s\n", strerror(-ret)); + ERROR_MSG("failed to set mode: %s", strerror(-ret)); + ret = FALSE; } else { ret = TRUE; } - // FIXME - DO WE NEED TO CALL TO THE PVR EXA/DRI2 CODE TO UPDATE THEM??? - /* Turn on any outputs on this crtc that may have been disabled: */ for (i = 0; i < xf86_config->num_output; i++) { xf86OutputPtr output = xf86_config->output[i]; @@ -323,17 +318,79 @@ drmmode_output_dpms(output, DPMSModeOn); } - // TODO: only call this if we are not using sw cursor.. ie. bad to call this - // if we haven't called xf86InitCursor()!! - // if (pScrn->pScreen) - // xf86_reload_cursors(pScrn->pScreen); - -done: if (output_ids) { free(output_ids); } + + return ret; +} + +static Bool +drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode, + Rotation rotation, int x, int y) +{ + ScrnInfoPtr pScrn = 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; + int ret = TRUE; + Bool was_rotated = drmmode->rotated_crtcs > 0; + + TRACE_ENTER(); + + /* update the count of number of rotated CRTCs.. if we have one or more + * rotated outputs then we want to use a tiled buffer, but otherwise + * stick with non-tiled + */ + if ((drmmode_crtc->rotation != RR_Rotate_0) && + (rotation == RR_Rotate_0)) { + DEBUG_MSG("disabling rotation for crtc: %u", + drmmode_crtc->mode_crtc->crtc_id); + drmmode->rotated_crtcs--; + } else if ((drmmode_crtc->rotation == RR_Rotate_0) && + (rotation != RR_Rotate_0)) { + DEBUG_MSG("enabling rotation for crtc: %u", + drmmode_crtc->mode_crtc->crtc_id); + drmmode->rotated_crtcs++; + } + + drmmode_crtc->rotation = rotation; + + /* at this point, if we are switching from unrotated to rotated + * or visa versa, then we need to reallocate the scanout buffer.. + */ + if (was_rotated != (drmmode->rotated_crtcs > 0)) { + /* reallocate scanout buffer.. */ + drmmode_reallocate_scanout(pScrn, TRUE, crtc); + } + + /* note: this needs to be done before setting the mode, otherwise + * drm core will reject connecting the fb to crtc due to mismatched + * dimensions: + */ + if (!drmmode_set_rotation(crtc, rotation)) { + ERROR_MSG("could not set rotation"); + return FALSE; + } + + /* Save the current mode in case there's a problem: */ + saved_mode = crtc->mode; + saved_x = crtc->x; + saved_y = crtc->y; + saved_rotation = crtc->rotation; + + /* Set the new mode: */ + crtc->mode = *mode; + crtc->x = x; + crtc->y = y; + crtc->rotation = rotation; + + ret = drmmode_restore_crtc(crtc); + if (!ret) { - /* If there was a problem, resture the old mode: */ + /* If there was a problem, restore the old mode: */ crtc->x = saved_x; crtc->y = saved_y; crtc->rotation = saved_rotation; @@ -405,6 +462,15 @@ h = crtc->mode.VDisplay - crtc_y; } +#if XF86_CRTC_VERSION >= 4 + /* NOTE: driver is taking care of rotation in hw, which means + * we need to deal w/ transformation of mouse cursor ourself: + */ + if (crtc->driverIsPerformingTransform) { + xf86CrtcTransformCursorPos(crtc, &crtc_x, &crtc_y); + } +#endif + /* note src coords (last 4 args) are in Q16 format */ drmModeSetPlane(drmmode->fd, cursor->ovr->plane_id, drmmode_crtc->mode_crtc->crtc_id, cursor->fb_id, 0, @@ -550,6 +616,7 @@ static void drmmode_crtc_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int num) { + drmModeObjectPropertiesPtr props; xf86CrtcPtr crtc; drmmode_crtc_private_ptr drmmode_crtc; @@ -563,8 +630,23 @@ drmmode_crtc->mode_crtc = drmModeGetCrtc(drmmode->fd, drmmode->mode_res->crtcs[num]); drmmode_crtc->drmmode = drmmode; + drmmode_crtc->rotation = RR_Rotate_0; - // FIXME - potentially add code to allocate a HW cursor here. + /* find properties that we care about: */ + props = drmModeObjectGetProperties(drmmode->fd, + drmmode_crtc->mode_crtc->crtc_id, DRM_MODE_OBJECT_CRTC); + if (props) { + drmModePropertyPtr prop; + int i; + for (i = 0; i < props->count_props; i++) { + prop = drmModeGetProperty(drmmode->fd, props->props[i]); + if (!strcmp(prop->name, "rotation")) { + drmmode_crtc->prop_rotation = prop->prop_id; + } + drmModeFreeProperty(prop); + } + drmModeFreeObjectProperties(props); + } crtc->driver_private = drmmode_crtc; @@ -1016,55 +1098,123 @@ return; } -static Bool -drmmode_xf86crtc_resize(ScrnInfoPtr pScrn, int width, int height) +Bool +drmmode_is_rotated(ScrnInfoPtr pScrn) +{ + OMAPPtr pOMAP = OMAPPTR(pScrn); + drmmode_ptr drmmode = drmmode_from_scrn(pScrn); + return has_rotation(pOMAP) && drmmode->rotated_crtcs > 0; +} + +Bool +drmmode_reallocate_scanout(ScrnInfoPtr pScrn, Bool redraw, xf86CrtcPtr crtc) { OMAPPtr pOMAP = OMAPPTR(pScrn); ScreenPtr pScreen = pScrn->pScreen; + int width = pScrn->virtualX; + int height = pScrn->virtualY; + Bool rotate = drmmode_is_rotated(pScrn); unsigned int pitch; - TRACE_ENTER(); - - /* if fb required size has changed, realloc! */ - - DEBUG_MSG("Resize! %dx%d", width, height); - - pScrn->virtualX = width; - pScrn->virtualY = height; + if (rotate) { + pitch = OMAPCalculateTiledStride(width, pScrn->bitsPerPixel); + } else { + pitch = OMAPCalculateStride(width, pScrn->bitsPerPixel); + } - pitch = OMAPCalculateStride(width, pScrn->bitsPerPixel); + if ((width != pOMAP->scanout_w) || + (height != pOMAP->scanout_h) || + (rotate != pOMAP->scanout_rotate)) { + uint32_t flags = OMAP_BO_SCANOUT | OMAP_BO_WC; - if ((pitch * height) != omap_bo_size(pOMAP->scanout)) { - /* hmm, should we remove fb here.. we don't want to keep - * scanning out a deallocated buffer.. - */ + /* remove old fb if it exists */ drmmode_remove_fb(pScrn); + if (pScreen && pScrn->EnableDisableFBAccess && redraw) + pScrn->EnableDisableFBAccess(ENABLE_DISABLE_FB_ACCESS_ARGS(pScrn, FALSE)); + /* delete old scanout buffer */ omap_bo_del(pOMAP->scanout); - DEBUG_MSG("allocating new scanout buffer: %dx%d (%d)", - width, height, pitch); + if (rotate) { + DEBUG_MSG("allocating tiled scanout buffer: %dx%d (%d)", + width, height, pitch); + flags |= OMAPTiledFlags(pScrn->bitsPerPixel); + pOMAP->scanout = omap_bo_new_tiled(pOMAP->dev, + width, height, flags); + } else { + DEBUG_MSG("allocating linear scanout buffer: %dx%d (%d)", + width, height, pitch); + pOMAP->scanout = omap_bo_new(pOMAP->dev, height * pitch, flags); + } - /* allocate new scanout buffer */ - pOMAP->scanout = omap_bo_new(pOMAP->dev, height * pitch, - OMAP_BO_SCANOUT | OMAP_BO_WC); if (!pOMAP->scanout) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Error reallocating scanout buffer\n"); return FALSE; } - } - if (pScreen && pScreen->ModifyPixmapHeader) { - PixmapPtr rootPixmap = pScreen->GetScreenPixmap(pScreen); - pScreen->ModifyPixmapHeader(rootPixmap, - pScrn->virtualX, pScrn->virtualY, - pScrn->depth, pScrn->bitsPerPixel, pitch, - omap_bo_map(pOMAP->scanout)); + pOMAP->scanout_w = width; + pOMAP->scanout_h = height; + pOMAP->scanout_rotate = rotate; + + pScrn->displayWidth = pitch / (pScrn->bitsPerPixel / 8); + + if (pScreen && pScreen->ModifyPixmapHeader) { + PixmapPtr rootPixmap = pScreen->GetScreenPixmap(pScreen); + pScreen->ModifyPixmapHeader(rootPixmap, + pScrn->virtualX, pScrn->virtualY, + pScrn->depth, pScrn->bitsPerPixel, pitch, + omap_bo_map(pOMAP->scanout)); + } + + if (pScreen && pScrn->EnableDisableFBAccess && redraw) + pScrn->EnableDisableFBAccess(ENABLE_DISABLE_FB_ACCESS_ARGS(pScrn, TRUE)); + + /* if reallocation triggered by a mode-set, we need to reconfigure any + * other crtc's which have just been torn down by destroying the old fb: + */ + if (crtc) { + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); + int i; + DEBUG_MSG("restoring CRTCs"); + for (i = 0; i < config->num_crtc; i++) { + if (config->crtc[i] != crtc) { + int ret; + DEBUG_MSG("restore CRTC %d", i); + ret = drmmode_restore_crtc(config->crtc[i]); + if (!ret) { + ERROR_MSG("failed to reconfig crtc %d", i); + /* hmm, I guess just keep trying the rest? */ + } + } + } + } + } else { + + if (pScreen && pScreen->ModifyPixmapHeader) { + PixmapPtr rootPixmap = pScreen->GetScreenPixmap(pScreen); + pScreen->ModifyPixmapHeader(rootPixmap, + pScrn->virtualX, pScrn->virtualY, + pScrn->depth, pScrn->bitsPerPixel, pitch, + omap_bo_map(pOMAP->scanout)); + } } - TRACE_EXIT(); + return TRUE; +} + +static Bool +drmmode_xf86crtc_resize(ScrnInfoPtr pScrn, int width, int height) +{ + DEBUG_MSG("Resize! %dx%d", width, height); + + pScrn->virtualX = width; + pScrn->virtualY = height; + + if (!drmmode_reallocate_scanout(pScrn, FALSE, NULL)) + return FALSE; + return TRUE; } @@ -1338,6 +1488,8 @@ if (pScrn == NULL || err < 0) return; + drmmode = drmmode_from_scrn(pScrn); + if (FD_ISSET(drmmode->fd, read_mask)) drmHandleEvent(drmmode->fd, &event_context); } diff -Nru xf86-video-omap-0.4.0/src/omap_dri2.c xf86-video-omap-0.4.1/src/omap_dri2.c --- xf86-video-omap-0.4.0/src/omap_dri2.c 2012-06-20 13:17:08.000000000 +0000 +++ xf86-video-omap-0.4.1/src/omap_dri2.c 2012-10-06 12:31:07.000000000 +0000 @@ -96,6 +96,9 @@ */ OMAPDRISwapCmd *cmd; + /* pending swaps on this drawable (which might or might not be flips) */ + int pending_swaps; + } OMAPDRI2DrawableRec, *OMAPDRI2DrawablePtr; static int @@ -192,10 +195,15 @@ } static PixmapPtr -createpix(DrawablePtr pDraw) +createpix(DrawablePtr pDraw, Bool scanout) { ScreenPtr pScreen = pDraw->pScreen; - int flags = canflip(pDraw) ? OMAP_CREATE_PIXMAP_SCANOUT : 0; + int flags = scanout ? OMAP_CREATE_PIXMAP_SCANOUT : 0; + if (scanout) { + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + Bool rotated = drmmode_is_rotated(pScrn); + flags |= rotated ? OMAP_CREATE_PIXMAP_TILED : 0; + } return pScreen->CreatePixmap(pScreen, pDraw->width, pDraw->height, pDraw->depth, flags); } @@ -245,7 +253,7 @@ (OMAPPixmapBo(pPixmap) != pOMAP->scanout)) { /* need to re-allocate pixmap to get a scanout capable buffer */ - PixmapPtr pNewPix = createpix(pDraw); + PixmapPtr pNewPix = createpix(pDraw, TRUE); // TODO copy contents.. @@ -256,7 +264,7 @@ pPixmap->refcnt++; } else { - pPixmap = createpix(pDraw); + pPixmap = createpix(pDraw, canflip(pDraw)); } bo = OMAPPixmapBo(pPixmap); @@ -423,9 +431,13 @@ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; OMAPDRI2DrawablePtr pPriv = OMAPDRI2GetDrawable(pDraw); OMAPDRI2BufferPtr src = OMAPBUF(cmd->pSrcBuffer); + Bool ok_to_flip = drmmode_is_rotated(pScrn) ? + OMAPPixmapTiled(src->pPixmap) : TRUE; /* if we can flip, do so: */ - if (canflip(pDraw) && drmmode_page_flip(pDraw, src->pPixmap, cmd)) { + if (ok_to_flip && canflip(pDraw) && + drmmode_page_flip(pDraw, src->pPixmap, cmd)) { + OMAPPTR(pScrn)->pending_page_flips++; cmd->type = DRI2_FLIP_COMPLETE; } else if (canexchange(pDraw, cmd->pSrcBuffer, cmd->pDstBuffer)) { /* we can get away w/ pointer swap.. yah! */ @@ -480,13 +492,15 @@ { ScreenPtr pScreen = cmd->pScreen; ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; - OMAPPtr pOMAP = OMAPPTR(pScrn); DrawablePtr pDraw = NULL; int status; DEBUG_MSG("%s complete: %d -> %d", swap_names[cmd->type], cmd->pSrcBuffer->attachment, cmd->pDstBuffer->attachment); + if (cmd->type == DRI2_FLIP_COMPLETE) + OMAPPTR(pScrn)->pending_page_flips--; + status = dixLookupDrawable(&pDraw, cmd->draw_id, serverClient, M_ANY, DixWriteAccess); @@ -501,13 +515,13 @@ OMAPDRI2SwapDispatch(pDraw, pPriv->cmd); pPriv->cmd = NULL; } + pPriv->pending_swaps--; } /* drop extra refcnt we obtained prior to swap: */ OMAPDRI2DestroyBuffer(pDraw, cmd->pSrcBuffer); OMAPDRI2DestroyBuffer(pDraw, cmd->pDstBuffer); - pOMAP->pending_swaps--; free(cmd); } @@ -532,7 +546,7 @@ { ScreenPtr pScreen = pDraw->pScreen; ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; - OMAPPtr pOMAP = OMAPPTR(pScrn); + OMAPDRI2DrawablePtr pPriv = OMAPDRI2GetDrawable(pDraw); OMAPDRISwapCmd *cmd = calloc(1, sizeof(*cmd)); cmd->client = client; @@ -549,14 +563,17 @@ OMAPDRI2ReferenceBuffer(pSrcBuffer); OMAPDRI2ReferenceBuffer(pDstBuffer); - pOMAP->pending_swaps++; + pPriv->pending_swaps++; - if (pOMAP->pending_swaps > 1) { + if (pPriv->pending_swaps > 1) { /* if we already have a pending swap, then just queue this * one up: */ - OMAPDRI2DrawablePtr pPriv = OMAPDRI2GetDrawable(pDraw); - assert(!pPriv->cmd); + if (pPriv->cmd) { + ERROR_MSG("already pending a flip!"); + pPriv->pending_swaps--; + return FALSE; + } pPriv->cmd = cmd; } else { OMAPDRI2SwapDispatch(pDraw, cmd); @@ -639,7 +656,7 @@ { ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; OMAPPtr pOMAP = OMAPPTR(pScrn); - while (pOMAP->pending_swaps > 0) { + while (pOMAP->pending_page_flips > 0) { DEBUG_MSG("waiting.."); drmmode_wait_for_event(pScrn); } diff -Nru xf86-video-omap-0.4.0/src/omap_driver.c xf86-video-omap-0.4.1/src/omap_driver.c --- xf86-video-omap-0.4.0/src/omap_driver.c 2012-06-20 13:17:08.000000000 +0000 +++ xf86-video-omap-0.4.1/src/omap_driver.c 2012-10-06 12:31:07.000000000 +0000 @@ -54,6 +54,10 @@ static Bool OMAPEnterVT(VT_FUNC_ARGS_DECL); static void OMAPLeaveVT(VT_FUNC_ARGS_DECL); static void OMAPFreeScreen(FREE_SCREEN_ARGS_DECL); +#ifdef XSERVER_PLATFORM_BUS +static Bool OMAPPlatformProbe(DriverPtr drv, int entity_num, int flags, + struct xf86_platform_device *dev, intptr_t match_data); +#endif @@ -74,7 +78,10 @@ NULL, #ifdef XSERVER_LIBPCIACCESS NULL, - NULL + NULL, +#endif +#ifdef XSERVER_PLATFORM_BUS + OMAPPlatformProbe, #endif }; @@ -196,29 +203,21 @@ return stride; } +unsigned int +OMAPTiledFlags(unsigned int bitsPerPixel) +{ + switch(bitsPerPixel) { + case 32: return OMAP_BO_TILED_32; + case 16: return OMAP_BO_TILED_16; + case 8: return OMAP_BO_TILED_8; + default: return 0; + } +} static Bool OMAPMapMem(ScrnInfoPtr pScrn) { - OMAPPtr pOMAP = OMAPPTR(pScrn); - int pitch; - - pitch = OMAPCalculateStride(pScrn->virtualX, pScrn->bitsPerPixel); - - DEBUG_MSG("allocating new scanout buffer: %dx%d (%d)", - pScrn->virtualX, pScrn->virtualY, pitch); - - pOMAP->scanout = omap_bo_new(pOMAP->dev, pScrn->virtualY * pitch, - OMAP_BO_SCANOUT | OMAP_BO_WC); - if (!pOMAP->scanout) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Error allocating scanout buffer\n"); - return FALSE; - } - - pScrn->displayWidth = pitch / (pScrn->bitsPerPixel / 8); - - return TRUE; + return drmmode_reallocate_scanout(pScrn, FALSE, NULL); } @@ -229,6 +228,7 @@ drmmode_remove_fb(pScrn); omap_bo_del(pOMAP->scanout); pOMAP->scanout = NULL; + pOMAP->scanout_w = pOMAP->scanout_h = 0; return TRUE; } @@ -267,7 +267,11 @@ /* This module should be loaded only once, but check to be sure: */ if (!setupDone) { setupDone = TRUE; +#ifdef XSERVER_PLATFORM_BUS + xf86AddDriver(&OMAP, module, HaveDriverFuncs); +#else xf86AddDriver(&OMAP, module, 0); +#endif /* The return value must be non-NULL on success even though there is no * TearDownProc. @@ -435,6 +439,7 @@ rgb defaultWeight = { 0, 0, 0 }; rgb defaultMask = { 0, 0, 0 }; Gamma defaultGamma = { 0.0, 0.0, 0.0 }; + EntityInfoPtr pEnt; uint64_t value; int i; @@ -457,7 +462,8 @@ OMAPGetRec(pScrn); pOMAP = OMAPPTR(pScrn); - pOMAP->pEntityInfo = xf86GetEntityInfo(pScrn->entityList[0]); + pEnt = xf86GetEntityInfo(pScrn->entityList[0]); + pOMAP->pEntityInfo = pEnt; pScrn->monitor = pScrn->confScreen->monitor; @@ -500,7 +506,17 @@ /* Using a programmable clock: */ pScrn->progClock = TRUE; - /* Open a connection to the DRM, so we can communicate with the KMS code: */ +#ifdef XSERVER_PLATFORM_BUS + if (pEnt->location.type == BUS_PLATFORM) { + char *busid = xf86_get_platform_device_attrib(pEnt->location.id.plat, + ODEV_ATTRIB_BUSID); + pOMAP->drmFD = drmOpen(NULL, busid); + if (pOMAP->drmFD < 0) + goto fail; + pOMAP->deviceName = drmGetDeviceNameFromFd(pOMAP->drmFD); + } + else +#endif if (!OMAPOpenDRMMaster(pScrn, 0)) { goto fail; } @@ -778,7 +794,6 @@ OMAPAccelInit(pScreen); /* Initialize backing store: */ - miInitializeBackingStore(pScreen); xf86SetBackingStore(pScreen); /* Cause the cursor position to be updated by the mouse signal handler: */ @@ -816,6 +831,16 @@ goto fail; } + if (has_rotation(pOMAP)) { + xf86RandR12SetRotations(pScreen, RR_Rotate_0 | RR_Rotate_90 | + RR_Rotate_180 | RR_Rotate_270 | RR_Reflect_X | RR_Reflect_Y); + } else { +#if XF86_CRTC_VERSION < 4 + WARNING_MSG("rotation not supported by XF86_CRTC_VERSION version: %d", + XF86_CRTC_VERSION); +#endif + } + if (!miCreateDefColormap(pScreen)) { ERROR_MSG("Cannot create colormap!"); goto fail; @@ -1057,3 +1082,42 @@ TRACE_EXIT(); } +#ifdef XSERVER_PLATFORM_BUS +static Bool +OMAPPlatformProbe(DriverPtr drv, int entity_num, int flags, + struct xf86_platform_device *dev, intptr_t match_data) +{ + ScrnInfoPtr pScrn = NULL; + Bool foundScreen = FALSE; + char *busid = xf86_get_platform_device_attrib(dev, ODEV_ATTRIB_BUSID); + int fd; + + fd = drmOpen(NULL, busid); + if (fd != -1) { + pScrn = xf86AllocateScreen(drv, 0); + if (!pScrn) { + EARLY_ERROR_MSG("Cannot allocate a ScrnInfoPtr"); + return FALSE; + } + + xf86AddEntityToScreen(pScrn, entity_num); + foundScreen = TRUE; + + pScrn->driverVersion = OMAP_VERSION; + pScrn->driverName = (char *)OMAP_DRIVER_NAME; + pScrn->name = (char *)OMAP_NAME; + pScrn->Probe = OMAPProbe; + pScrn->PreInit = OMAPPreInit; + pScrn->ScreenInit = OMAPScreenInit; + pScrn->SwitchMode = OMAPSwitchMode; + pScrn->AdjustFrame = OMAPAdjustFrame; + pScrn->EnterVT = OMAPEnterVT; + pScrn->LeaveVT = OMAPLeaveVT; + pScrn->FreeScreen = OMAPFreeScreen; + + drmClose(fd); + } + + return foundScreen; +} +#endif diff -Nru xf86-video-omap-0.4.0/src/omap_driver.h xf86-video-omap-0.4.1/src/omap_driver.h --- xf86-video-omap-0.4.0/src/omap_driver.h 2012-06-20 13:17:08.000000000 +0000 +++ xf86-video-omap-0.4.1/src/omap_driver.h 2012-10-06 12:31:07.000000000 +0000 @@ -38,12 +38,8 @@ * (i.e. so we can use fbdevHW, SW cursor, etc): * XXX - figure out what can be removed.. */ -#include "mipointer.h" -#include "mibstore.h" #include "micmap.h" -#include "colormapst.h" #include "xf86cmap.h" -#include "shadow.h" /* for visuals */ #include "fb.h" #if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 6 @@ -56,6 +52,9 @@ #include "xf86drm.h" #include "drm_fourcc.h" #include "dri2.h" +#ifdef XSERVER_PLATFORM_BUS +#include "xf86platformBus.h" +#endif #include #include @@ -116,6 +115,7 @@ OMAPCalculateStride(unsigned int fbWidth, unsigned int bitsPerPixel); extern unsigned int OMAPCalculateTiledStride(unsigned int width, unsigned int bitsPerPixel); +unsigned int OMAPTiledFlags(unsigned int bitsPerPixel); @@ -146,6 +146,8 @@ /** Scan-out buffer. */ struct omap_bo *scanout; + int scanout_w, scanout_h; + Bool scanout_rotate; /** Pointer to the options for this screen. */ OptionInfoPtr pOptionInfo; @@ -160,8 +162,8 @@ XF86VideoAdaptorPtr textureAdaptor; - /** Swaps we are waiting for: */ - int pending_swaps; + /** Pending page flips we are waiting for: */ + int pending_page_flips; } OMAPRec, *OMAPPtr; @@ -182,6 +184,16 @@ return pOMAP->chipset >= 0x4430; } +static inline Bool has_rotation(OMAPPtr pOMAP) +{ +#if XF86_CRTC_VERSION >= 4 + // TODO .. should somehow check if driver has rotation property.. + return has_dmm(pOMAP); +#else + return FALSE; +#endif +} + /** Return a pointer to the driver's private structure. */ #define OMAPPTR(p) ((OMAPPtr)((p)->driverPrivate)) #define OMAPPTR_FROM_SCREEN(pScreen) \ @@ -225,6 +237,9 @@ Bool drmmode_page_flip(DrawablePtr pDraw, PixmapPtr back, void *priv); void drmmode_wait_for_event(ScrnInfoPtr pScrn); Bool drmmode_cursor_init(ScreenPtr pScreen); +Bool drmmode_is_rotated(ScrnInfoPtr pScrn); +Bool drmmode_reallocate_scanout(ScrnInfoPtr pScrn, Bool redraw, + xf86CrtcPtr crtc); /** diff -Nru xf86-video-omap-0.4.0/src/omap_exa.c xf86-video-omap-0.4.1/src/omap_exa.c --- xf86-video-omap-0.4.0/src/omap_exa.c 2012-06-20 13:17:08.000000000 +0000 +++ xf86-video-omap-0.4.1/src/omap_exa.c 2012-10-06 12:31:07.000000000 +0000 @@ -163,8 +163,10 @@ omap_bo_del(priv->bo); if (flags & OMAP_BO_TILED) { priv->bo = omap_bo_new_tiled(pOMAP->dev, width, height, flags); + priv->tiled = TRUE; } else { priv->bo = omap_bo_new(pOMAP->dev, size, flags); + priv->tiled = FALSE; } } diff -Nru xf86-video-omap-0.4.0/src/omap_exa.h xf86-video-omap-0.4.1/src/omap_exa.h --- xf86-video-omap-0.4.0/src/omap_exa.h 2012-06-20 13:17:08.000000000 +0000 +++ xf86-video-omap-0.4.1/src/omap_exa.h 2012-10-06 12:31:07.000000000 +0000 @@ -125,6 +125,7 @@ typedef struct { void *priv; /* EXA submodule private data */ struct omap_bo *bo; + Bool tiled; } OMAPPixmapPrivRec, *OMAPPixmapPrivPtr; #define OMAP_CREATE_PIXMAP_SCANOUT 0x80000000 @@ -150,6 +151,13 @@ return priv->bo; } +static inline Bool +OMAPPixmapTiled(PixmapPtr pPixmap) +{ + OMAPPixmapPrivPtr priv = exaGetPixmapDriverPrivate(pPixmap); + return priv->tiled; +} + void OMAPPixmapExchange(PixmapPtr a, PixmapPtr b); #endif /* OMAP_EXA_COMMON_H_ */