aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/omapdrm/omap_gem.c
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2021-12-10 15:08:11 +1000
committerDave Airlie <airlied@redhat.com>2021-12-10 15:08:21 +1000
commit15bb79910fe734ad21c765d1cae762e855969caa (patch)
tree6181e8cb79578eb21bb1302111908a9cd9c93682 /drivers/gpu/drm/omapdrm/omap_gem.c
parentMerge tag 'du-next-20211206' of git://linuxtv.org/pinchartl/media into drm-next (diff)
parentdrm/bridge: sn65dsi86: defer if there is no dsi host (diff)
downloadlinux-dev-15bb79910fe734ad21c765d1cae762e855969caa.tar.xz
linux-dev-15bb79910fe734ad21c765d1cae762e855969caa.zip
Merge tag 'drm-misc-next-2021-12-09' of git://anongit.freedesktop.org/drm/drm-misc into drm-next
drm-misc-next for 5.17: UAPI Changes: Cross-subsystem Changes: * dma-buf: Make fences mandatory in dma_resv_add_excl_fence Core Changes: * Move hashtable to legacy code * Return error pointers from struct drm_driver.gem_create_object * cma-helper: Improve public interfaces; Remove CONFIG_DRM_KMS_CMA_HELPER option * mipi-dbi: Don't depend on CMA helpers * ttm: Don't include DRM hashtable; Stop prunning fences after wait; Documentation Driver Changes: * aspeed: Select CONFIG_DRM_GEM_CMA_HELPER * bridge/lontium-lt9611: Fix HDMI sensing * bridge/parade-ps8640: Fixes * bridge/sn65dsi86: Defer probe is no dsi host found * fsl-dcu: Select CONFIG_DRM_GEM_CMA_HELPER * i915: Remove dma_resv_prune * omapdrm: Fix scatterlist export; Support virtual planes; Fixes * panel: Boe-tv110c9m,Inx-hj110iz: Update init code * qxl: Use dma-resv iterator * rockchip: Use generic fbdev emulation * tidss: Fixes * vmwgfx: Fix leak on probe errors; Fail probing on broken hosts; New placement for MOB page tables; Hide internal BOs from userspace; Cleanups Signed-off-by: Dave Airlie <airlied@redhat.com> From: Thomas Zimmermann <tzimmermann@suse.de> Link: https://patchwork.freedesktop.org/patch/msgid/YbHskHZc9HoAYuPZ@linux-uq9g.fritz.box
Diffstat (limited to 'drivers/gpu/drm/omapdrm/omap_gem.c')
-rw-r--r--drivers/gpu/drm/omapdrm/omap_gem.c79
1 files changed, 78 insertions, 1 deletions
diff --git a/drivers/gpu/drm/omapdrm/omap_gem.c b/drivers/gpu/drm/omapdrm/omap_gem.c
index 38af6195d959..b0fa17409b66 100644
--- a/drivers/gpu/drm/omapdrm/omap_gem.c
+++ b/drivers/gpu/drm/omapdrm/omap_gem.c
@@ -789,7 +789,7 @@ int omap_gem_pin(struct drm_gem_object *obj, dma_addr_t *dma_addr)
if (omap_obj->flags & OMAP_BO_TILED_MASK) {
block = tiler_reserve_2d(fmt,
omap_obj->width,
- omap_obj->height, 0);
+ omap_obj->height, PAGE_SIZE);
} else {
block = tiler_reserve_1d(obj->size);
}
@@ -851,6 +851,11 @@ static void omap_gem_unpin_locked(struct drm_gem_object *obj)
return;
if (refcount_dec_and_test(&omap_obj->dma_addr_cnt)) {
+ if (omap_obj->sgt) {
+ sg_free_table(omap_obj->sgt);
+ kfree(omap_obj->sgt);
+ omap_obj->sgt = NULL;
+ }
ret = tiler_unpin(omap_obj->block);
if (ret) {
dev_err(obj->dev->dev,
@@ -963,6 +968,78 @@ int omap_gem_put_pages(struct drm_gem_object *obj)
return 0;
}
+struct sg_table *omap_gem_get_sg(struct drm_gem_object *obj)
+{
+ struct omap_gem_object *omap_obj = to_omap_bo(obj);
+ dma_addr_t addr;
+ struct sg_table *sgt;
+ struct scatterlist *sg;
+ unsigned int count, len, stride, i;
+ int ret;
+
+ ret = omap_gem_pin(obj, &addr);
+ if (ret)
+ return ERR_PTR(ret);
+
+ mutex_lock(&omap_obj->lock);
+
+ sgt = omap_obj->sgt;
+ if (sgt)
+ goto out;
+
+ sgt = kzalloc(sizeof(*sgt), GFP_KERNEL);
+ if (!sgt) {
+ ret = -ENOMEM;
+ goto err_unpin;
+ }
+
+ if (omap_obj->flags & OMAP_BO_TILED_MASK) {
+ enum tiler_fmt fmt = gem2fmt(omap_obj->flags);
+
+ len = omap_obj->width << (int)fmt;
+ count = omap_obj->height;
+ stride = tiler_stride(fmt, 0);
+ } else {
+ len = obj->size;
+ count = 1;
+ stride = 0;
+ }
+
+ ret = sg_alloc_table(sgt, count, GFP_KERNEL);
+ if (ret)
+ goto err_free;
+
+ for_each_sg(sgt->sgl, sg, count, i) {
+ sg_set_page(sg, phys_to_page(addr), len, offset_in_page(addr));
+ sg_dma_address(sg) = addr;
+ sg_dma_len(sg) = len;
+
+ addr += stride;
+ }
+
+ omap_obj->sgt = sgt;
+out:
+ mutex_unlock(&omap_obj->lock);
+ return sgt;
+
+err_free:
+ kfree(sgt);
+err_unpin:
+ mutex_unlock(&omap_obj->lock);
+ omap_gem_unpin(obj);
+ return ERR_PTR(ret);
+}
+
+void omap_gem_put_sg(struct drm_gem_object *obj, struct sg_table *sgt)
+{
+ struct omap_gem_object *omap_obj = to_omap_bo(obj);
+
+ if (WARN_ON(omap_obj->sgt != sgt))
+ return;
+
+ omap_gem_unpin(obj);
+}
+
#ifdef CONFIG_DRM_FBDEV_EMULATION
/*
* Get kernel virtual address for CPU access.. this more or less only