diff options
author | Dave Airlie | 2019-04-05 03:21:47 +0200 |
---|---|---|
committer | Dave Airlie | 2019-04-05 03:38:02 +0200 |
commit | 14d2bd53a47a7e1cb3e03d00a6b952734cf90f3f (patch) | |
tree | 616e11aacdf96d495bf6ef9c8163fb83cd5b712b /drivers/gpu/drm/lima/lima_object.c | |
parent | Merge commit 'refs/for-upstream/mali-dp' of git://linux-arm.org/linux-ld into... (diff) | |
parent | MAINTAINERS: Add ASPEED BMC GFX DRM driver entry (diff) | |
download | kernel-qcow2-linux-14d2bd53a47a7e1cb3e03d00a6b952734cf90f3f.tar.gz kernel-qcow2-linux-14d2bd53a47a7e1cb3e03d00a6b952734cf90f3f.tar.xz kernel-qcow2-linux-14d2bd53a47a7e1cb3e03d00a6b952734cf90f3f.zip |
Merge tag 'drm-misc-next-2019-04-04' of git://anongit.freedesktop.org/drm/drm-misc into drm-next
drm-misc-next for 5.2:
UAPI Changes:
-syncobj: Add TIMELINE_WAIT|QUERY|TRANSFER|TIMELINE_SIGNAL ioctls (Chunming)
-Clarify that 1.0 can be represented by drm_color_lut (Daniel)
Cross-subsystem Changes:
-dt-bindings: Add binding for rk3066 hdmi (Johan)
-dt-bindings: Add binding for Feiyang FY07024DI26A30-D panel (Jagan)
-dt-bindings: Add Rocktech vendor prefix and jh057n00900 panel bindings (Guido)
-MAINTAINERS: Add lima and ASPEED entries (Joel & Qiang)
Core Changes:
-memory: use dma_alloc_coherent when mem encryption is active (Christian)
-dma_buf: add support for a dma_fence chain (Christian)
-shmem_gem: fix off-by-one bug in new shmem gem helpers (Dan)
Driver Changes:
-rockchip: Add support for rk3066 hdmi (Johan)
-ASPEED: Add driver supporting ASPEED BMC display controller to drm (Joel)
-lima: Add driver supporting Arm Mali4xx gpus to drm (Qiang)
-vc4/v3d: Various cleanups and improved error handling (Eric)
-panel: Add support for Feiyang FY07024DI26A30-D MIPI-DSI panel (Jagan)
-panel: Add support for Rocktech jh057n00900 MIPI-DSI panel (Guido)
Cc: Johan Jonker <jbx6244@gmail.com>
Cc: Christian König <christian.koenig@amd.com>
Cc: Chunming Zhou <david1.zhou@amd.com>
Cc: Dan Carpenter <dan.carpenter@oracle.com>
Cc: Eric Anholt <eric@anholt.net>
Cc: Qiang Yu <yuq825@gmail.com>
Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
Cc: Jagan Teki <jagan@amarulasolutions.com>
Cc: Guido Günther <agx@sigxcpu.org>
Cc: Joel Stanley <joel@jms.id.au>
[airlied: fixed XA limit build breakage, Rodrigo also submitted the same patch, but
I squashed it in the merge.]
Signed-off-by: Dave Airlie <airlied@redhat.com>
From: Sean Paul <sean@poorly.run>
Link: https://patchwork.freedesktop.org/patch/msgid/20190404201016.GA139524@art_vandelay
Diffstat (limited to 'drivers/gpu/drm/lima/lima_object.c')
-rw-r--r-- | drivers/gpu/drm/lima/lima_object.c | 122 |
1 files changed, 122 insertions, 0 deletions
diff --git a/drivers/gpu/drm/lima/lima_object.c b/drivers/gpu/drm/lima/lima_object.c new file mode 100644 index 000000000000..5c41f859a72f --- /dev/null +++ b/drivers/gpu/drm/lima/lima_object.c @@ -0,0 +1,122 @@ +// SPDX-License-Identifier: GPL-2.0 OR MIT +/* Copyright 2018-2019 Qiang Yu <yuq825@gmail.com> */ + +#include <drm/drm_prime.h> +#include <linux/pagemap.h> +#include <linux/dma-mapping.h> + +#include "lima_object.h" + +void lima_bo_destroy(struct lima_bo *bo) +{ + if (bo->sgt) { + kfree(bo->pages); + drm_prime_gem_destroy(&bo->gem, bo->sgt); + } else { + if (bo->pages_dma_addr) { + int i, npages = bo->gem.size >> PAGE_SHIFT; + + for (i = 0; i < npages; i++) { + if (bo->pages_dma_addr[i]) + dma_unmap_page(bo->gem.dev->dev, + bo->pages_dma_addr[i], + PAGE_SIZE, DMA_BIDIRECTIONAL); + } + } + + if (bo->pages) + drm_gem_put_pages(&bo->gem, bo->pages, true, true); + } + + kfree(bo->pages_dma_addr); + drm_gem_object_release(&bo->gem); + kfree(bo); +} + +static struct lima_bo *lima_bo_create_struct(struct lima_device *dev, u32 size, u32 flags, + struct reservation_object *resv) +{ + struct lima_bo *bo; + int err; + + size = PAGE_ALIGN(size); + + bo = kzalloc(sizeof(*bo), GFP_KERNEL); + if (!bo) + return ERR_PTR(-ENOMEM); + + mutex_init(&bo->lock); + INIT_LIST_HEAD(&bo->va); + bo->gem.resv = resv; + + err = drm_gem_object_init(dev->ddev, &bo->gem, size); + if (err) { + kfree(bo); + return ERR_PTR(err); + } + + return bo; +} + +struct lima_bo *lima_bo_create(struct lima_device *dev, u32 size, + u32 flags, struct sg_table *sgt, + struct reservation_object *resv) +{ + int i, err; + size_t npages; + struct lima_bo *bo, *ret; + + bo = lima_bo_create_struct(dev, size, flags, resv); + if (IS_ERR(bo)) + return bo; + + npages = bo->gem.size >> PAGE_SHIFT; + + bo->pages_dma_addr = kcalloc(npages, sizeof(dma_addr_t), GFP_KERNEL); + if (!bo->pages_dma_addr) { + ret = ERR_PTR(-ENOMEM); + goto err_out; + } + + if (sgt) { + bo->sgt = sgt; + + bo->pages = kcalloc(npages, sizeof(*bo->pages), GFP_KERNEL); + if (!bo->pages) { + ret = ERR_PTR(-ENOMEM); + goto err_out; + } + + err = drm_prime_sg_to_page_addr_arrays( + sgt, bo->pages, bo->pages_dma_addr, npages); + if (err) { + ret = ERR_PTR(err); + goto err_out; + } + } else { + mapping_set_gfp_mask(bo->gem.filp->f_mapping, GFP_DMA32); + bo->pages = drm_gem_get_pages(&bo->gem); + if (IS_ERR(bo->pages)) { + ret = ERR_CAST(bo->pages); + bo->pages = NULL; + goto err_out; + } + + for (i = 0; i < npages; i++) { + dma_addr_t addr = dma_map_page(dev->dev, bo->pages[i], 0, + PAGE_SIZE, DMA_BIDIRECTIONAL); + if (dma_mapping_error(dev->dev, addr)) { + ret = ERR_PTR(-EFAULT); + goto err_out; + } + bo->pages_dma_addr[i] = addr; + } + + } + + return bo; + +err_out: + lima_bo_destroy(bo); + return ret; +} |