summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobin Wang <robin.wang@arm.com>2014-06-19 10:13:01 +0800
committerRobin Wang <robin.wang@arm.com>2014-11-07 10:00:48 +0000
commitc9dcb42fd9102fb9436e9fc5f070f9ec8ad1e533 (patch)
tree6300246e134cada7646f3ebdc8a08e3a86825983
parentb946f71f773e066669bbeb8b42f0ecc5ed1f3d24 (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.man5
-rw-r--r--src/armsoc_driver.c20
-rw-r--r--src/armsoc_driver.h4
-rw-r--r--src/armsoc_exa.c80
-rw-r--r--src/umplock/umplock_ioctl.h82
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__ */
+