diff options
author | Russell King <rmk_cubox@arm.linux.org.uk> | 2013-06-14 13:10:03 +0100 |
---|---|---|
committer | Russell King <rmk@arm.linux.org.uk> | 2013-06-16 09:21:10 +0100 |
commit | 4495dffb7341629da248142539e50f8ec0479b83 (patch) | |
tree | 877c7aa6aa42f954434a148281f58d61f0ea3ebf | |
parent | 457cc1fadb456c68a5226e67c95ccd0f1c5e6893 (diff) |
Add remainder of the dmabuf changes
Signed-off-by: Russell King <rmk_cubox@arm.linux.org.uk>
-rw-r--r-- | src/armada_drm.c | 33 | ||||
-rw-r--r-- | src/gal_extension.h | 19 | ||||
-rw-r--r-- | src/vivante.c | 48 |
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); |