Commit c9dcb42f authored by Robin Wang's avatar Robin Wang

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
parent b946f71f
......@@ -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
......
......@@ -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;
......
......@@ -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;
......
......@@ -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));
}
}
/**
......
/*
* 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__ */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment