diff options
author | Robin Wang <robin.wang@arm.com> | 2014-06-19 10:13:01 +0800 |
---|---|---|
committer | Robin Wang <robin.wang@arm.com> | 2014-11-07 10:00:48 +0000 |
commit | c9dcb42fd9102fb9436e9fc5f070f9ec8ad1e533 (patch) | |
tree | 6300246e134cada7646f3ebdc8a08e3a86825983 | |
parent | b946f71f773e066669bbeb8b42f0ecc5ed1f3d24 (diff) |
Integrate umplock to armsoc ddx driver for MALI400
MALI400 EGL driver use umplock for CPU/GPU accessing synchronization.
Port umplock related changes from xf86-video-mali to xf86-video-armsoc DDX driver.
Change-Id: I0765e4a747153ff72cb7ebb44afe0136aacd5834
-rw-r--r-- | man/armsoc.man | 5 | ||||
-rw-r--r-- | src/armsoc_driver.c | 20 | ||||
-rw-r--r-- | src/armsoc_driver.h | 4 | ||||
-rw-r--r-- | src/armsoc_exa.c | 80 | ||||
-rw-r--r-- | src/umplock/umplock_ioctl.h | 82 |
5 files changed, 177 insertions, 14 deletions
diff --git a/man/armsoc.man b/man/armsoc.man index 4a1b16a..d85c2fa 100644 --- a/man/armsoc.man +++ b/man/armsoc.man @@ -64,6 +64,11 @@ an error will be logged, and the -background none functionality will be disabled. .IP Default: NULL +.TP +.BI "Option \*qUMP_LOCK\*q \*q" boolean \*q +Use the umplock module for cross-process access synchronization. It should be only enabled for Mali400 +.IP +Default: Umplock is Disabled .SH DRM DEVICE SELECTION diff --git a/src/armsoc_driver.c b/src/armsoc_driver.c index 6e21182..39aa608 100644 --- a/src/armsoc_driver.c +++ b/src/armsoc_driver.c @@ -108,6 +108,7 @@ enum { OPTION_DRIVERNAME, OPTION_DRI_NUM_BUF, OPTION_INIT_FROM_FBDEV, + OPTION_UMP_LOCK, }; /** Supported options. */ @@ -119,6 +120,7 @@ static const OptionInfoRec ARMSOCOptions[] = { { OPTION_DRIVERNAME, "DriverName", OPTV_STRING, {0}, FALSE }, { OPTION_DRI_NUM_BUF, "DRI2MaxBuffers", OPTV_INTEGER, {-1}, FALSE }, { OPTION_INIT_FROM_FBDEV, "InitFromFBDev", OPTV_STRING, {0}, FALSE }, + { OPTION_UMP_LOCK, "UMP_LOCK", OPTV_BOOLEAN, {0}, FALSE }, { -1, NULL, OPTV_NONE, {0}, FALSE } }; @@ -856,6 +858,10 @@ ARMSOCPreInit(ScrnInfoPtr pScrn, int flags) OPTION_NO_FLIP, FALSE); INFO_MSG("Buffer Flipping is %s", pARMSOC->NoFlip ? "Disabled" : "Enabled"); + pARMSOC->useUmplock = xf86ReturnOptValBool(pARMSOC->pOptionInfo, + OPTION_UMP_LOCK, FALSE); + INFO_MSG("umplock is %s", + pARMSOC->useUmplock ? "Disabled" : "Enabled"); /* * Select the video modes: @@ -1127,6 +1133,15 @@ ARMSOCScreenInit(SCREEN_INIT_ARGS_DECL) wrap(pARMSOC, pScreen, BlockHandler, ARMSOCBlockHandler); drmmode_screen_init(pScrn); + if (pARMSOC->useUmplock) { + pARMSOC->lockFD = open("/dev/umplock", O_RDWR); + + if (-1 == pARMSOC->lockFD) + ERROR_MSG("Failed to open umplock device!"); + } else { + pARMSOC->lockFD = -1; + } + TRACE_EXIT(); return TRUE; @@ -1241,6 +1256,11 @@ ARMSOCCloseScreen(CLOSE_SCREEN_ARGS_DECL) pScrn->vtSema = FALSE; + if (-1 != pARMSOC->lockFD) { + close(pARMSOC->lockFD); + pARMSOC->lockFD = -1; + } + TRACE_EXIT(); return ret; diff --git a/src/armsoc_driver.h b/src/armsoc_driver.h index 4621dcc..947b2e4 100644 --- a/src/armsoc_driver.h +++ b/src/armsoc_driver.h @@ -151,6 +151,10 @@ struct ARMSOCRec { /* Identify which CRTC to use. -1 uses all CRTCs */ int crtcNum; + Bool useUmplock; + /* File descriptor of the umplock*/ + int lockFD; + /* The Swap Chain stores the pending swap operations */ struct ARMSOCDRISwapCmd **swap_chain; diff --git a/src/armsoc_exa.c b/src/armsoc_exa.c index 87f28e1..a310727 100644 --- a/src/armsoc_exa.c +++ b/src/armsoc_exa.c @@ -31,6 +31,9 @@ #include "armsoc_exa.h" #include "armsoc_driver.h" +#include "umplock/umplock_ioctl.h" +#include <sys/ioctl.h> +#include <unistd.h> /* keep this here, instead of static-inline so submodule doesn't * need to know layout of ARMSOCRec. @@ -324,6 +327,12 @@ static inline enum armsoc_gem_op idx2op(int index) _X_EXPORT Bool ARMSOCPrepareAccess(PixmapPtr pPixmap, int index) { + ScreenPtr pScreen = pPixmap->drawable.pScreen; + ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); + struct ARMSOCRec *pARMSOC = ARMSOCPTR(pScrn); + uint32_t dmabuf_name = 0; + _lock_item_s item; + int ret; struct ARMSOCPixmapPrivRec *priv = exaGetPixmapDriverPrivate(pPixmap); pPixmap->devPrivate.ptr = armsoc_bo_map(priv->bo); @@ -344,13 +353,39 @@ ARMSOCPrepareAccess(PixmapPtr pPixmap, int index) } } - if (armsoc_bo_cpu_prep(priv->bo, idx2op(index))) { - xf86DrvMsg(-1, X_ERROR, - "%s: armsoc_bo_cpu_prep failed - unable to synchronise access.\n", - __func__); - return FALSE; - } + if (-1 != pARMSOC->lockFD) { + ret = armsoc_bo_get_name(priv->bo, &dmabuf_name); + + if (ret) { + ERROR_MSG("could not get buffer name"); + return FALSE; + } + + item.secure_id = dmabuf_name; + item.usage = _LOCK_ACCESS_CPU_WRITE; + if (ioctl(pARMSOC->lockFD, LOCK_IOCTL_CREATE, &item) < 0) { + ERROR_MSG("Unable to create lock item\n"); + return FALSE; + } + if (ioctl(pARMSOC->lockFD, LOCK_IOCTL_PROCESS, &item) < 0) { + int max_retries = 5; + ERROR_MSG("Unable to process lock item with ID 0x%x - throttling\n", item.secure_id); + while ((ioctl(pARMSOC->lockFD, LOCK_IOCTL_PROCESS, &item) < 0) && max_retries) { + usleep(2000); + max_retries--; + } + if (max_retries == 0) + ERROR_MSG("Warning: Max retries == 0\n"); + } + } else { + if (armsoc_bo_cpu_prep(priv->bo, idx2op(index))) { + xf86DrvMsg(-1, X_ERROR, + "%s: armsoc_bo_cpu_prep failed - unable to synchronise access.\n", + __func__); + return FALSE; + } + } return TRUE; } @@ -367,15 +402,32 @@ ARMSOCPrepareAccess(PixmapPtr pPixmap, int index) _X_EXPORT void ARMSOCFinishAccess(PixmapPtr pPixmap, int index) { + ScreenPtr pScreen = pPixmap->drawable.pScreen; + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; struct ARMSOCPixmapPrivRec *priv = exaGetPixmapDriverPrivate(pPixmap); - - pPixmap->devPrivate.ptr = NULL; - - /* NOTE: can we use EXA migration module to track which parts of the - * buffer was accessed by sw, and pass that info down to kernel to - * do a more precise cache flush.. - */ - armsoc_bo_cpu_fini(priv->bo, idx2op(index)); + struct ARMSOCRec *pARMSOC = ARMSOCPTR(pScrn); + if (-1 != pARMSOC->lockFD){ + uint32_t dmabuf_name = 0; + _lock_item_s item; + int ret; + + pPixmap->devPrivate.ptr = NULL; + ret = armsoc_bo_get_name(priv->bo, &dmabuf_name); + if (ret) { + ERROR_MSG("could not get buffer name"); + return ; + } + item.secure_id = dmabuf_name; + item.usage = _LOCK_ACCESS_CPU_WRITE; + ioctl(pARMSOC->lockFD, LOCK_IOCTL_RELEASE, &item); + }else{ + /* NOTE: can we use EXA migration module to track which parts of the + * buffer was accessed by sw, and pass that info down to kernel to + * do a more precise cache flush.. + */ + pPixmap->devPrivate.ptr = NULL; + armsoc_bo_cpu_fini(priv->bo, idx2op(index)); + } } /** diff --git a/src/umplock/umplock_ioctl.h b/src/umplock/umplock_ioctl.h new file mode 100644 index 0000000..4be19a0 --- /dev/null +++ b/src/umplock/umplock_ioctl.h @@ -0,0 +1,82 @@ +/* + * Copyright © 2013 ARM Limited. + * + * 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. + * + */ + +#ifndef __UMPLOCK_IOCTL_H__ +#define __UMPLOCK_IOCTL_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <linux/types.h> +#include <linux/ioctl.h> + +#ifndef __user +#define __user +#endif + + +/** + * @file umplock_ioctl.h + * This file describes the interface needed to use the Linux device driver. + * The interface is used by the userpace Mali DDK. + */ + +typedef enum +{ + _LOCK_ACCESS_RENDERABLE = 1, + _LOCK_ACCESS_TEXTURE, + _LOCK_ACCESS_CPU_WRITE, + _LOCK_ACCESS_CPU_READ, +} _lock_access_usage; + +typedef struct _lock_item_s +{ + unsigned int secure_id; + _lock_access_usage usage; +} _lock_item_s; + + +#define LOCK_IOCTL_GROUP 0x91 + +#define _LOCK_IOCTL_CREATE_CMD 0 /* create kernel lock item */ +#define _LOCK_IOCTL_PROCESS_CMD 1 /* process kernel lock item */ +#define _LOCK_IOCTL_RELEASE_CMD 2 /* release kernel lock item */ +#define _LOCK_IOCTL_ZAP_CMD 3 /* clean up all kernel lock items */ +#define _LOCK_IOCTL_DUMP_CMD 4 /* dump all the items */ + +#define LOCK_IOCTL_MAX_CMDS 5 + +#define LOCK_IOCTL_CREATE _IOW( LOCK_IOCTL_GROUP, _LOCK_IOCTL_CREATE_CMD, _lock_item_s ) +#define LOCK_IOCTL_PROCESS _IOW( LOCK_IOCTL_GROUP, _LOCK_IOCTL_PROCESS_CMD, _lock_item_s ) +#define LOCK_IOCTL_RELEASE _IOW( LOCK_IOCTL_GROUP, _LOCK_IOCTL_RELEASE_CMD, _lock_item_s ) +#define LOCK_IOCTL_ZAP _IO ( LOCK_IOCTL_GROUP, _LOCK_IOCTL_ZAP_CMD ) +#define LOCK_IOCTL_DUMP _IO ( LOCK_IOCTL_GROUP, _LOCK_IOCTL_DUMP_CMD ) + +#ifdef __cplusplus +} +#endif + +#endif /* __UMPLOCK_IOCTL_H__ */ + |