aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoss Oldfield <ross.oldfield@linaro.org>2013-11-28 09:17:04 +0000
committerRoss Oldfield <ross.oldfield@linaro.org>2013-11-28 09:27:25 +0000
commit89e3a09cf913893a251fa812a309c0b227d39ef7 (patch)
tree0264946133e02d2be1a4ea19c159b18218c1e14f
parente2d64d46f0b475a3462d366a51ee61774c90e6cb (diff)
PL111 KMS: add dmabuf importlinaro
-rw-r--r--drivers/gpu/drm/pl111/pl111_drm_device.c3
-rw-r--r--drivers/gpu/drm/pl111/pl111_drm_funcs.h2
-rw-r--r--drivers/gpu/drm/pl111/pl111_drm_gem.c41
3 files changed, 45 insertions, 1 deletions
diff --git a/drivers/gpu/drm/pl111/pl111_drm_device.c b/drivers/gpu/drm/pl111/pl111_drm_device.c
index 4ade09aaad3..59ac27aa779 100644
--- a/drivers/gpu/drm/pl111/pl111_drm_device.c
+++ b/drivers/gpu/drm/pl111/pl111_drm_device.c
@@ -297,6 +297,9 @@ static struct drm_driver driver = {
.gem_vm_ops = &pl111_gem_vm_ops,
.prime_handle_to_fd = &pl111_prime_handle_to_fd,
.gem_prime_export = &pl111_gem_prime_export,
+ .prime_fd_to_handle = drm_gem_prime_fd_to_handle,
+ .gem_prime_import = drm_gem_prime_import,
+ .gem_prime_import_sg_table = pl111_prime_import_sg_table
};
int pl111_drm_init(struct platform_device *dev)
diff --git a/drivers/gpu/drm/pl111/pl111_drm_funcs.h b/drivers/gpu/drm/pl111/pl111_drm_funcs.h
index de8a8266f89..21709d62bb5 100644
--- a/drivers/gpu/drm/pl111/pl111_drm_funcs.h
+++ b/drivers/gpu/drm/pl111/pl111_drm_funcs.h
@@ -97,6 +97,8 @@ int pl111_prime_handle_to_fd(struct drm_device *dev, struct drm_file *file_priv,
uint32_t handle, uint32_t flags, int *prime_fd);
struct dma_buf *pl111_gem_prime_export(struct drm_device *dev,
struct drm_gem_object *obj, int flags);
+struct drm_gem_object *pl111_prime_import_sg_table(struct drm_device *dev,
+ size_t size, struct sg_table *sgt);
/* Pl111 Functions */
void show_framebuffer_on_crtc_cb_internal(struct pl111_drm_flip_resource
diff --git a/drivers/gpu/drm/pl111/pl111_drm_gem.c b/drivers/gpu/drm/pl111/pl111_drm_gem.c
index 01989ecd933..372c2cd9c93 100644
--- a/drivers/gpu/drm/pl111/pl111_drm_gem.c
+++ b/drivers/gpu/drm/pl111/pl111_drm_gem.c
@@ -39,7 +39,7 @@ void pl111_gem_free_object(struct drm_gem_object *obj)
if (obj->map_list.map != NULL)
drm_gem_free_mmap_offset(obj);
- if (bo->type == PL111_BOT_DMA) {
+ if (bo->type == PL111_BOT_DMA && bo->backing_data.dma.fb_cpu_addr) {
dma_free_writecombine(dev->dev, obj->size,
bo->backing_data.dma.fb_cpu_addr,
bo->backing_data.dma.fb_dev_addr);
@@ -285,3 +285,42 @@ int pl111_gem_mmap(struct file *file_priv, struct vm_area_struct *vma)
return pl111_bo_mmap(obj, bo, vma, vma->vm_end - vma->vm_start);
}
+
+struct drm_gem_object *pl111_prime_import_sg_table(struct drm_device *dev,
+ size_t size,struct sg_table *sgt)
+{
+ struct pl111_gem_bo *bo;
+ int ret;
+
+ /* Only import if the buffer is contiguous */
+ if (sgt->nents != 1)
+ return ERR_PTR(-EINVAL);
+
+ /* Create a GEM buffer. */
+ bo = kzalloc(sizeof(*bo), GFP_KERNEL);
+ if (!bo)
+ return ERR_PTR(-ENOMEM);
+
+ bo->type = PL111_BOT_DMA;
+ ret = drm_gem_object_init(dev, &bo->gem_object, size);
+ if(ret)
+ goto error;
+
+ ret = drm_gem_create_mmap_offset(&bo->gem_object);
+ if (ret) {
+ drm_gem_object_release(&bo->gem_object);
+ goto error;
+ }
+
+ bo->backing_data.dma.fb_dev_addr = sg_dma_address(sgt->sgl);
+ bo->backing_data.dma.fb_cpu_addr = NULL;
+
+ return &bo->gem_object;
+
+error:
+ kfree(bo);
+ return ERR_PTR(ret);
+}
+
+
+