summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRussell King <rmk_cubox@arm.linux.org.uk>2013-06-14 13:10:03 +0100
committerRussell King <rmk@arm.linux.org.uk>2013-06-16 09:21:10 +0100
commit4495dffb7341629da248142539e50f8ec0479b83 (patch)
tree877c7aa6aa42f954434a148281f58d61f0ea3ebf
parent457cc1fadb456c68a5226e67c95ccd0f1c5e6893 (diff)
downloadxf86-video-armada-4495dffb7341629da248142539e50f8ec0479b83.tar.gz
xf86-video-armada-4495dffb7341629da248142539e50f8ec0479b83.tar.xz
Add remainder of the dmabuf changes
Signed-off-by: Russell King <rmk_cubox@arm.linux.org.uk>
-rw-r--r--src/armada_drm.c33
-rw-r--r--src/gal_extension.h19
-rw-r--r--src/vivante.c48
3 files changed, 99 insertions, 1 deletions
diff --git a/src/armada_drm.c b/src/armada_drm.c
index 2ba77ac..621ca8e 100644
--- a/src/armada_drm.c
+++ b/src/armada_drm.c
@@ -1367,12 +1367,27 @@ static Bool armada_drm_pre_init(ScrnInfoPtr pScrn)
return TRUE;
}
+static int armada_get_cap(struct armada_drm_info *drm, uint64_t cap,
+ uint64_t *val, int scrnIndex, const char *name)
+{
+ int err;
+
+ err = drmGetCap(drm->fd, DRM_CAP_PRIME, val);
+ if (err)
+ xf86DrvMsg(scrnIndex, X_ERROR,
+ "[drm] failed to get %s capability: %s\n",
+ name, strerror(errno));
+
+ return err;
+}
+
static Bool armada_drm_open_master(ScrnInfoPtr pScrn)
{
struct armada_drm_info *drm;
EntityInfoPtr pEnt;
drmSetVersion sv;
const char *busid = DRM_DEFAULT_BUS_ID;
+ uint64_t val;
int err;
pEnt = xf86GetEntityInfo(pScrn->entityList[0]);
@@ -1412,6 +1427,24 @@ static Bool armada_drm_open_master(ScrnInfoPtr pScrn)
goto err_drm_close;
}
+ if (armada_get_cap(drm, DRM_CAP_PRIME, &val,
+ pScrn->scrnIndex, "DRM_CAP_PRIME"))
+ goto err_drm_close;
+ if (!(val & DRM_PRIME_CAP_EXPORT)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "[drm] kernel doesn't support prime export.\n");
+ goto err_drm_close;
+ }
+
+ if (armada_get_cap(drm, DRM_CAP_DUMB_BUFFER, &val,
+ pScrn->scrnIndex, "DRM_CAP_DUMB_BUFFER"))
+ goto err_drm_close;
+ if (!val) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "[drm] kernel doesn't support dumb buffer.\n");
+ goto err_drm_close;
+ }
+
err = drm_armada_init(drm->fd, &drm->bufmgr);
if (err) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
diff --git a/src/gal_extension.h b/src/gal_extension.h
new file mode 100644
index 0000000..5c26ade
--- /dev/null
+++ b/src/gal_extension.h
@@ -0,0 +1,19 @@
+/*
+ * Private extensions to galcore to support Other(tm) ways of doing things.
+ */
+#ifndef GAL_EXTENSION_H
+#define GAL_EXTENSION_H
+
+#include <sys/ioctl.h>
+#include <gc_hal.h>
+
+/* Map a DMABUF fd into galcore */
+struct map_dma_buf {
+ unsigned zero;
+ int fd;
+ gctPOINTER Info;
+ gctUINT32 Address;
+};
+#define IOC_GDMABUF_MAP _IOWR('_', 0, struct map_dma_buf)
+
+#endif
diff --git a/src/vivante.c b/src/vivante.c
index bbc1c8d..c072e73 100644
--- a/src/vivante.c
+++ b/src/vivante.c
@@ -27,6 +27,8 @@
#include <gc_hal.h>
+#include "gal_extension.h"
+
#include "vivante.h"
#include "vivante_accel.h"
#include "vivante_dri2.h"
@@ -39,7 +41,36 @@ vivante_Key vivante_screen_index;
static Bool vivante_map_bo_to_gpu(struct vivante *vivante,
struct drm_armada_bo *bo, void **info, uint32_t *handle)
{
- *handle = drm_armada_bo_phys(bo);
+ struct map_dma_buf map;
+ gceSTATUS status;
+ int fd;
+
+ if (drm_armada_bo_to_fd(bo, &fd)) {
+ xf86DrvMsg(vivante->scrnIndex, X_ERROR,
+ "vivante: unable to get prime fd for bo: %s\n",
+ strerror(errno));
+ return FALSE;
+ }
+
+ map.zero = 0;
+ map.fd = fd;
+
+ status = gcoOS_DeviceControl(vivante->os, IOC_GDMABUF_MAP,
+ &map, sizeof(map), &map, sizeof(map));
+
+ /* we don't need to keep the fd around anymore */
+ close(fd);
+
+ if (gcmIS_ERROR(status)) {
+ xf86DrvMsg(vivante->scrnIndex, X_INFO,
+ "vivante: gpu dmabuf map failed: %d\n",
+ status);
+ return FALSE;
+ }
+
+ *handle = map.Address;
+ *info = map.Info;
+
return TRUE;
}
@@ -54,6 +85,13 @@ void vivante_free_pixmap(PixmapPtr pixmap)
if (vPix->owner == GPU)
vivante_unmap_gpu(vivante, vPix);
drm_armada_bo_put(vPix->bo);
+ /*
+ * Those vPix which still have a handle have been mapped
+ * to the GPU, and have to be unmapped.
+ */
+ if (vPix->handle != -1)
+ gcoOS_UnmapUserMemory(vivante->os, (void *)1, 1,
+ vPix->info, vPix->handle);
free(vPix);
}
}
@@ -405,6 +443,10 @@ static Bool vivante_CloseScreen(int scrnIndex, ScreenPtr pScreen)
pScreen->BitmapToRegion = vivante->BitmapToRegion;
pScreen->BlockHandler = vivante->BlockHandler;
+ gcoOS_UnmapUserMemory(vivante->os, (void *)1, 1,
+ vivante->batch_info,
+ vivante->batch_handle);
+
vivante_accel_shutdown(vivante);
drm_armada_bo_put(vivante->batch_bo);
@@ -653,6 +695,10 @@ Bool vivante_ScreenInit(ScreenPtr pScreen, struct drm_armada_bufmgr *mgr)
return TRUE;
fail:
+ if (vivante->batch_info)
+ gcoOS_UnmapUserMemory(vivante->os, (void *)1, 1,
+ vivante->batch_info,
+ vivante->batch_handle);
vivante_accel_shutdown(vivante);
if (vivante->batch_bo)
drm_armada_bo_put(vivante->batch_bo);