From cec4fa7511ef7a73eb635834e9d85b25a5b47a98 Mon Sep 17 00:00:00 2001 From: Jean-Jacques Hiblot Date: Thu, 10 Oct 2019 13:59:53 +0200 Subject: drm/omap: use refcount API to track the number of users of dma_addr This would give us a WARN_ON() if the pin/unpin calls are unbalanced. Proposed-by: Laurent Pinchart Signed-off-by: Jean-Jacques Hiblot Reviewed-by: Tomi Valkeinen Signed-off-by: Tomi Valkeinen Link: https://patchwork.freedesktop.org/patch/msgid/20191010120000.1421-2-jjhiblot@ti.com --- drivers/gpu/drm/omapdrm/omap_gem.c | 44 +++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 22 deletions(-) (limited to 'drivers/gpu/drm/omapdrm/omap_gem.c') diff --git a/drivers/gpu/drm/omapdrm/omap_gem.c b/drivers/gpu/drm/omapdrm/omap_gem.c index 08f539efddfb..61caa7a1a24b 100644 --- a/drivers/gpu/drm/omapdrm/omap_gem.c +++ b/drivers/gpu/drm/omapdrm/omap_gem.c @@ -67,7 +67,7 @@ struct omap_gem_object { /** * # of users of dma_addr */ - u32 dma_addr_cnt; + refcount_t dma_addr_cnt; /** * If the buffer has been imported from a dmabuf the OMAP_DB_DMABUF flag @@ -773,13 +773,15 @@ int omap_gem_pin(struct drm_gem_object *obj, dma_addr_t *dma_addr) mutex_lock(&omap_obj->lock); if (!omap_gem_is_contiguous(omap_obj) && priv->has_dmm) { - if (omap_obj->dma_addr_cnt == 0) { + if (refcount_read(&omap_obj->dma_addr_cnt) == 0) { u32 npages = obj->size >> PAGE_SHIFT; enum tiler_fmt fmt = gem2fmt(omap_obj->flags); struct tiler_block *block; BUG_ON(omap_obj->block); + refcount_set(&omap_obj->dma_addr_cnt, 1); + ret = omap_gem_attach_pages(obj); if (ret) goto fail; @@ -813,10 +815,10 @@ int omap_gem_pin(struct drm_gem_object *obj, dma_addr_t *dma_addr) omap_obj->block = block; DBG("got dma address: %pad", &omap_obj->dma_addr); + } else { + refcount_inc(&omap_obj->dma_addr_cnt); } - omap_obj->dma_addr_cnt++; - *dma_addr = omap_obj->dma_addr; } else if (omap_gem_is_contiguous(omap_obj)) { *dma_addr = omap_obj->dma_addr; @@ -846,22 +848,19 @@ void omap_gem_unpin(struct drm_gem_object *obj) mutex_lock(&omap_obj->lock); - if (omap_obj->dma_addr_cnt > 0) { - omap_obj->dma_addr_cnt--; - if (omap_obj->dma_addr_cnt == 0) { - ret = tiler_unpin(omap_obj->block); - if (ret) { - dev_err(obj->dev->dev, - "could not unpin pages: %d\n", ret); - } - ret = tiler_release(omap_obj->block); - if (ret) { - dev_err(obj->dev->dev, - "could not release unmap: %d\n", ret); - } - omap_obj->dma_addr = 0; - omap_obj->block = NULL; + if (refcount_dec_and_test(&omap_obj->dma_addr_cnt)) { + ret = tiler_unpin(omap_obj->block); + if (ret) { + dev_err(obj->dev->dev, + "could not unpin pages: %d\n", ret); + } + ret = tiler_release(omap_obj->block); + if (ret) { + dev_err(obj->dev->dev, + "could not release unmap: %d\n", ret); } + omap_obj->dma_addr = 0; + omap_obj->block = NULL; } mutex_unlock(&omap_obj->lock); @@ -879,7 +878,7 @@ int omap_gem_rotated_dma_addr(struct drm_gem_object *obj, u32 orient, mutex_lock(&omap_obj->lock); - if ((omap_obj->dma_addr_cnt > 0) && omap_obj->block && + if ((refcount_read(&omap_obj->dma_addr_cnt) > 0) && omap_obj->block && (omap_obj->flags & OMAP_BO_TILED)) { *dma_addr = tiler_tsptr(omap_obj->block, orient, x, y); ret = 0; @@ -1030,7 +1029,8 @@ void omap_gem_describe(struct drm_gem_object *obj, struct seq_file *m) seq_printf(m, "%08x: %2d (%2d) %08llx %pad (%2d) %p %4d", omap_obj->flags, obj->name, kref_read(&obj->refcount), - off, &omap_obj->dma_addr, omap_obj->dma_addr_cnt, + off, &omap_obj->dma_addr, + refcount_read(&omap_obj->dma_addr_cnt), omap_obj->vaddr, omap_obj->roll); if (omap_obj->flags & OMAP_BO_TILED) { @@ -1093,7 +1093,7 @@ void omap_gem_free_object(struct drm_gem_object *obj) mutex_lock(&omap_obj->lock); /* The object should not be pinned. */ - WARN_ON(omap_obj->dma_addr_cnt > 0); + WARN_ON(refcount_read(&omap_obj->dma_addr_cnt) > 0); if (omap_obj->pages) { if (omap_obj->flags & OMAP_BO_MEM_DMABUF) -- cgit From d3e4c46df688fa0bfacffd5f040b5ae89562ab0c Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Thu, 10 Oct 2019 13:59:54 +0200 Subject: drm/omap: add omap_gem_unpin_locked() Add omap_gem_unpin_locked() which is a version of omap_gem_unpin() that expects the caller to hold the omap_obj lock. Signed-off-by: Tomi Valkeinen Reviewed-by: Jean-Jacques Hiblot Link: https://patchwork.freedesktop.org/patch/msgid/20191010120000.1421-3-jjhiblot@ti.com --- drivers/gpu/drm/omapdrm/omap_gem.c | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) (limited to 'drivers/gpu/drm/omapdrm/omap_gem.c') diff --git a/drivers/gpu/drm/omapdrm/omap_gem.c b/drivers/gpu/drm/omapdrm/omap_gem.c index 61caa7a1a24b..9201c21e206f 100644 --- a/drivers/gpu/drm/omapdrm/omap_gem.c +++ b/drivers/gpu/drm/omapdrm/omap_gem.c @@ -834,20 +834,16 @@ fail: } /** - * omap_gem_unpin() - Unpin a GEM object from memory + * omap_gem_unpin_locked() - Unpin a GEM object from memory * @obj: the GEM object * - * Unpin the given GEM object previously pinned with omap_gem_pin(). Pins are - * reference-counted, the actualy unpin will only be performed when the number - * of calls to this function matches the number of calls to omap_gem_pin(). + * omap_gem_unpin() without locking. */ -void omap_gem_unpin(struct drm_gem_object *obj) +static void omap_gem_unpin_locked(struct drm_gem_object *obj) { struct omap_gem_object *omap_obj = to_omap_bo(obj); int ret; - mutex_lock(&omap_obj->lock); - if (refcount_dec_and_test(&omap_obj->dma_addr_cnt)) { ret = tiler_unpin(omap_obj->block); if (ret) { @@ -862,7 +858,22 @@ void omap_gem_unpin(struct drm_gem_object *obj) omap_obj->dma_addr = 0; omap_obj->block = NULL; } +} +/** + * omap_gem_unpin() - Unpin a GEM object from memory + * @obj: the GEM object + * + * Unpin the given GEM object previously pinned with omap_gem_pin(). Pins are + * reference-counted, the actual unpin will only be performed when the number + * of calls to this function matches the number of calls to omap_gem_pin(). + */ +void omap_gem_unpin(struct drm_gem_object *obj) +{ + struct omap_gem_object *omap_obj = to_omap_bo(obj); + + mutex_lock(&omap_obj->lock); + omap_gem_unpin_locked(obj); mutex_unlock(&omap_obj->lock); } -- cgit From d6e52e28e4ca5ae5d066048f5ae2eac68dacb453 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Thu, 10 Oct 2019 13:59:55 +0200 Subject: drm/omap: accept NULL for dma_addr in omap_gem_pin Allow NULL to be passed in 'dma_addr' for omap_gem_pin(), in case the caller does not need the dma_addr. Signed-off-by: Tomi Valkeinen Reviewed-by: Jean-Jacques Hiblot Link: https://patchwork.freedesktop.org/patch/msgid/20191010120000.1421-4-jjhiblot@ti.com --- drivers/gpu/drm/omapdrm/omap_gem.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers/gpu/drm/omapdrm/omap_gem.c') diff --git a/drivers/gpu/drm/omapdrm/omap_gem.c b/drivers/gpu/drm/omapdrm/omap_gem.c index 9201c21e206f..a6562d23d314 100644 --- a/drivers/gpu/drm/omapdrm/omap_gem.c +++ b/drivers/gpu/drm/omapdrm/omap_gem.c @@ -819,9 +819,11 @@ int omap_gem_pin(struct drm_gem_object *obj, dma_addr_t *dma_addr) refcount_inc(&omap_obj->dma_addr_cnt); } - *dma_addr = omap_obj->dma_addr; + if (dma_addr) + *dma_addr = omap_obj->dma_addr; } else if (omap_gem_is_contiguous(omap_obj)) { - *dma_addr = omap_obj->dma_addr; + if (dma_addr) + *dma_addr = omap_obj->dma_addr; } else { ret = -EINVAL; goto fail; -- cgit From 48b34ac041756c2fd3a898d6e96be97416858b45 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Thu, 10 Oct 2019 13:59:57 +0200 Subject: drm/omap: remove OMAP_BO_TILED define OMAP_BO_TILED does not make sense, as OMAP_BO_TILED_* values are not bitmasks but normal values. As we already have OMAP_BO_TILED_MASK for the mask, we can remove OMAP_BO_TILED and use OMAP_BO_TILED_MASK instead. Signed-off-by: Tomi Valkeinen Reviewed-by: Jean-Jacques Hiblot Link: https://patchwork.freedesktop.org/patch/msgid/20191010120000.1421-6-jjhiblot@ti.com --- drivers/gpu/drm/omapdrm/omap_gem.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'drivers/gpu/drm/omapdrm/omap_gem.c') diff --git a/drivers/gpu/drm/omapdrm/omap_gem.c b/drivers/gpu/drm/omapdrm/omap_gem.c index a6562d23d314..4e8fcfdff3a0 100644 --- a/drivers/gpu/drm/omapdrm/omap_gem.c +++ b/drivers/gpu/drm/omapdrm/omap_gem.c @@ -196,7 +196,7 @@ static void omap_gem_evict(struct drm_gem_object *obj) struct omap_gem_object *omap_obj = to_omap_bo(obj); struct omap_drm_private *priv = obj->dev->dev_private; - if (omap_obj->flags & OMAP_BO_TILED) { + if (omap_obj->flags & OMAP_BO_TILED_MASK) { enum tiler_fmt fmt = gem2fmt(omap_obj->flags); int i; @@ -324,7 +324,7 @@ size_t omap_gem_mmap_size(struct drm_gem_object *obj) struct omap_gem_object *omap_obj = to_omap_bo(obj); size_t size = obj->size; - if (omap_obj->flags & OMAP_BO_TILED) { + if (omap_obj->flags & OMAP_BO_TILED_MASK) { /* for tiled buffers, the virtual size has stride rounded up * to 4kb.. (to hide the fact that row n+1 might start 16kb or * 32kb later!). But we don't back the entire buffer with @@ -513,7 +513,7 @@ vm_fault_t omap_gem_fault(struct vm_fault *vmf) * probably trigger put_pages()? */ - if (omap_obj->flags & OMAP_BO_TILED) + if (omap_obj->flags & OMAP_BO_TILED_MASK) ret = omap_gem_fault_2d(obj, vma, vmf); else ret = omap_gem_fault_1d(obj, vma, vmf); @@ -786,7 +786,7 @@ int omap_gem_pin(struct drm_gem_object *obj, dma_addr_t *dma_addr) if (ret) goto fail; - if (omap_obj->flags & OMAP_BO_TILED) { + if (omap_obj->flags & OMAP_BO_TILED_MASK) { block = tiler_reserve_2d(fmt, omap_obj->width, omap_obj->height, 0); @@ -892,7 +892,7 @@ int omap_gem_rotated_dma_addr(struct drm_gem_object *obj, u32 orient, mutex_lock(&omap_obj->lock); if ((refcount_read(&omap_obj->dma_addr_cnt) > 0) && omap_obj->block && - (omap_obj->flags & OMAP_BO_TILED)) { + (omap_obj->flags & OMAP_BO_TILED_MASK)) { *dma_addr = tiler_tsptr(omap_obj->block, orient, x, y); ret = 0; } @@ -907,7 +907,7 @@ int omap_gem_tiled_stride(struct drm_gem_object *obj, u32 orient) { struct omap_gem_object *omap_obj = to_omap_bo(obj); int ret = -EINVAL; - if (omap_obj->flags & OMAP_BO_TILED) + if (omap_obj->flags & OMAP_BO_TILED_MASK) ret = tiler_stride(gem2fmt(omap_obj->flags), orient); return ret; } @@ -1046,7 +1046,7 @@ void omap_gem_describe(struct drm_gem_object *obj, struct seq_file *m) refcount_read(&omap_obj->dma_addr_cnt), omap_obj->vaddr, omap_obj->roll); - if (omap_obj->flags & OMAP_BO_TILED) { + if (omap_obj->flags & OMAP_BO_TILED_MASK) { seq_printf(m, " %dx%d", omap_obj->width, omap_obj->height); if (omap_obj->block) { struct tcm_area *area = &omap_obj->block->area; @@ -1145,7 +1145,7 @@ struct drm_gem_object *omap_gem_new(struct drm_device *dev, int ret; /* Validate the flags and compute the memory and cache flags. */ - if (flags & OMAP_BO_TILED) { + if (flags & OMAP_BO_TILED_MASK) { if (!priv->usergart) { dev_err(dev->dev, "Tiled buffers require DMM\n"); return NULL; @@ -1187,7 +1187,7 @@ struct drm_gem_object *omap_gem_new(struct drm_device *dev, omap_obj->flags = flags; mutex_init(&omap_obj->lock); - if (flags & OMAP_BO_TILED) { + if (flags & OMAP_BO_TILED_MASK) { /* * For tiled buffers align dimensions to slot boundaries and * calculate size based on aligned dimensions. -- cgit From 18d7f5ab543eeaddc3609f56b52f51da72aa99ba Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Thu, 10 Oct 2019 13:59:58 +0200 Subject: drm/omap: cleanup OMAP_BO_SCANOUT use omap_gem_new() has a comment about OMAP_BO_SCANOUT which does not make sense. Also, for the TILER case, we drop OMAP_BO_SCANOUT flag for some reason. It's not clear what the original purpose of OMAP_BO_SCANOUT is, but presuming it means "scanout buffer, something that can be consumed by DSS", this patch cleans up the above issues. Signed-off-by: Tomi Valkeinen Reviewed-by: Jean-Jacques Hiblot Link: https://patchwork.freedesktop.org/patch/msgid/20191010120000.1421-7-jjhiblot@ti.com --- drivers/gpu/drm/omapdrm/omap_gem.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers/gpu/drm/omapdrm/omap_gem.c') diff --git a/drivers/gpu/drm/omapdrm/omap_gem.c b/drivers/gpu/drm/omapdrm/omap_gem.c index 4e8fcfdff3a0..27e0a2f8508a 100644 --- a/drivers/gpu/drm/omapdrm/omap_gem.c +++ b/drivers/gpu/drm/omapdrm/omap_gem.c @@ -1155,7 +1155,6 @@ struct drm_gem_object *omap_gem_new(struct drm_device *dev, * Tiled buffers are always shmem paged backed. When they are * scanned out, they are remapped into DMM/TILER. */ - flags &= ~OMAP_BO_SCANOUT; flags |= OMAP_BO_MEM_SHMEM; /* @@ -1166,9 +1165,8 @@ struct drm_gem_object *omap_gem_new(struct drm_device *dev, flags |= tiler_get_cpu_cache_flags(); } else if ((flags & OMAP_BO_SCANOUT) && !priv->has_dmm) { /* - * OMAP_BO_SCANOUT hints that the buffer doesn't need to be - * tiled. However, to lower the pressure on memory allocation, - * use contiguous memory only if no TILER is available. + * If we don't have DMM, we must allocate scanout buffers + * from contiguous DMA memory. */ flags |= OMAP_BO_MEM_DMA_API; } else if (!(flags & OMAP_BO_MEM_DMABUF)) { -- cgit From 4ecc5fbcc4d43e702a473f21fee045f55fc3beb5 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Thu, 10 Oct 2019 13:59:59 +0200 Subject: drm/omap: add omap_gem_validate_flags() Add a helper function omap_gem_validate_flags() which validates the omap_bo flags passed from the userspace. Also drop the dev_err() message, as the userspace can cause that at will. Signed-off-by: Tomi Valkeinen Reviewed-by: Jean-Jacques Hiblot Link: https://patchwork.freedesktop.org/patch/msgid/20191010120000.1421-8-jjhiblot@ti.com --- drivers/gpu/drm/omapdrm/omap_gem.c | 40 +++++++++++++++++++++++++++++++++----- 1 file changed, 35 insertions(+), 5 deletions(-) (limited to 'drivers/gpu/drm/omapdrm/omap_gem.c') diff --git a/drivers/gpu/drm/omapdrm/omap_gem.c b/drivers/gpu/drm/omapdrm/omap_gem.c index 27e0a2f8508a..e518d93ca6df 100644 --- a/drivers/gpu/drm/omapdrm/omap_gem.c +++ b/drivers/gpu/drm/omapdrm/omap_gem.c @@ -1133,6 +1133,38 @@ void omap_gem_free_object(struct drm_gem_object *obj) kfree(omap_obj); } +static bool omap_gem_validate_flags(struct drm_device *dev, u32 flags) +{ + struct omap_drm_private *priv = dev->dev_private; + + switch (flags & OMAP_BO_CACHE_MASK) { + case OMAP_BO_CACHED: + case OMAP_BO_WC: + case OMAP_BO_CACHE_MASK: + break; + + default: + return false; + } + + if (flags & OMAP_BO_TILED_MASK) { + if (!priv->usergart) + return false; + + switch (flags & OMAP_BO_TILED_MASK) { + case OMAP_BO_TILED_8: + case OMAP_BO_TILED_16: + case OMAP_BO_TILED_32: + break; + + default: + return false; + } + } + + return true; +} + /* GEM buffer object constructor */ struct drm_gem_object *omap_gem_new(struct drm_device *dev, union omap_gem_size gsize, u32 flags) @@ -1144,13 +1176,11 @@ struct drm_gem_object *omap_gem_new(struct drm_device *dev, size_t size; int ret; + if (!omap_gem_validate_flags(dev, flags)) + return NULL; + /* Validate the flags and compute the memory and cache flags. */ if (flags & OMAP_BO_TILED_MASK) { - if (!priv->usergart) { - dev_err(dev->dev, "Tiled buffers require DMM\n"); - return NULL; - } - /* * Tiled buffers are always shmem paged backed. When they are * scanned out, they are remapped into DMM/TILER. -- cgit From 23b482252836ab3c5e6b3b20ed3038449cbc7679 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Thu, 10 Oct 2019 14:00:00 +0200 Subject: drm/omap: add OMAP_BO flags to affect buffer allocation On SoCs with DMM/TILER, we have two ways to allocate buffers: normal dma_alloc or via DMM (which basically functions as an IOMMU). DMM can map 128MB at a time, and we only map the DMM buffers when they are used (i.e. not at alloc time). If DMM is present, omapdrm always uses DMM. There are use cases that require lots of big buffers that are being used at the same time by different IPs. At the moment the userspace has a hard maximum of 128MB. This patch adds three new flags that can be used by the userspace to solve the situation: OMAP_BO_MEM_CONTIG: The driver will use dma_alloc to get the memory. This can be used to avoid DMM if the userspace knows it needs more than 128M of memory at the same time. OMAP_BO_MEM_DMM: The driver will use DMM to get the memory. There's not much use for this flag at the moment, as on platforms with DMM it is used by default, but it's here for completeness. OMAP_BO_MEM_PIN: The driver will pin the memory at alloc time, and keep it pinned. This can be used to 1) get an error at alloc time if DMM space is full, and 2) get rid of the constant pin/unpin operations which may have some effect on performance. If none of the flags are given, the behavior is the same as currently. Signed-off-by: Tomi Valkeinen Reviewed-by: Jean-Jacques Hiblot Link: https://patchwork.freedesktop.org/patch/msgid/20191010120000.1421-9-jjhiblot@ti.com --- drivers/gpu/drm/omapdrm/omap_gem.c | 54 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 52 insertions(+), 2 deletions(-) (limited to 'drivers/gpu/drm/omapdrm/omap_gem.c') diff --git a/drivers/gpu/drm/omapdrm/omap_gem.c b/drivers/gpu/drm/omapdrm/omap_gem.c index e518d93ca6df..bf18dfe2b689 100644 --- a/drivers/gpu/drm/omapdrm/omap_gem.c +++ b/drivers/gpu/drm/omapdrm/omap_gem.c @@ -1097,6 +1097,9 @@ void omap_gem_free_object(struct drm_gem_object *obj) list_del(&omap_obj->mm_list); mutex_unlock(&priv->list_lock); + if (omap_obj->flags & OMAP_BO_MEM_PIN) + omap_gem_unpin_locked(obj); + /* * We own the sole reference to the object at this point, but to keep * lockdep happy, we must still take the omap_obj_lock to call @@ -1147,10 +1150,19 @@ static bool omap_gem_validate_flags(struct drm_device *dev, u32 flags) return false; } + if ((flags & OMAP_BO_MEM_CONTIG) && (flags & OMAP_BO_MEM_DMM)) + return false; + + if ((flags & OMAP_BO_MEM_DMM) && !priv->usergart) + return false; + if (flags & OMAP_BO_TILED_MASK) { if (!priv->usergart) return false; + if (flags & OMAP_BO_MEM_CONTIG) + return false; + switch (flags & OMAP_BO_TILED_MASK) { case OMAP_BO_TILED_8: case OMAP_BO_TILED_16: @@ -1165,7 +1177,34 @@ static bool omap_gem_validate_flags(struct drm_device *dev, u32 flags) return true; } -/* GEM buffer object constructor */ +/** + * omap_gem_new() - Create a new GEM buffer + * @dev: The DRM device + * @gsize: The requested size for the GEM buffer. If the buffer is tiled + * (2D buffer), the size is a pair of values: height and width + * expressed in pixels. If the buffers is not tiled, it is expressed + * in bytes. + * @flags: Flags give additionnal information about the allocation: + * OMAP_BO_TILED_x: use the TILER (2D buffers). The TILER container + * unit can be 8, 16 or 32 bits. Cache is always disabled for + * tiled buffers. + * OMAP_BO_SCANOUT: Scannout buffer, consummable by the DSS + * OMAP_BO_CACHED: Buffer CPU caching mode: cached + * OMAP_BO_WC: Buffer CPU caching mode: write-combined + * OMAP_BO_UNCACHED: Buffer CPU caching mode: uncached + * OMAP_BO_MEM_CONTIG: The driver will use dma_alloc to get the memory. + * This can be used to avoid DMM if the userspace knows it needs + * more than 128M of memory at the same time. + * OMAP_BO_MEM_DMM: The driver will use DMM to get the memory. There's + * not much use for this flag at the moment, as on platforms with + * DMM it is used by default, but it's here for completeness. + * OMAP_BO_MEM_PIN: The driver will pin the memory at alloc time, and + * keep it pinned. This can be used to 1) get an error at alloc + * time if DMM space is full, and 2) get rid of the constant + * pin/unpin operations which may have some effect on performance. + * + * Return: The GEM buffer or NULL if the allocation failed + */ struct drm_gem_object *omap_gem_new(struct drm_device *dev, union omap_gem_size gsize, u32 flags) { @@ -1193,7 +1232,8 @@ struct drm_gem_object *omap_gem_new(struct drm_device *dev, */ flags &= ~(OMAP_BO_CACHED|OMAP_BO_WC|OMAP_BO_UNCACHED); flags |= tiler_get_cpu_cache_flags(); - } else if ((flags & OMAP_BO_SCANOUT) && !priv->has_dmm) { + } else if ((flags & OMAP_BO_MEM_CONTIG) || + ((flags & OMAP_BO_SCANOUT) && !priv->has_dmm)) { /* * If we don't have DMM, we must allocate scanout buffers * from contiguous DMA memory. @@ -1253,12 +1293,22 @@ struct drm_gem_object *omap_gem_new(struct drm_device *dev, goto err_release; } + if (flags & OMAP_BO_MEM_PIN) { + ret = omap_gem_pin(obj, NULL); + if (ret) + goto err_free_dma; + } + mutex_lock(&priv->list_lock); list_add(&omap_obj->mm_list, &priv->obj_list); mutex_unlock(&priv->list_lock); return obj; +err_free_dma: + if (flags & OMAP_BO_MEM_DMA_API) + dma_free_wc(dev->dev, size, omap_obj->vaddr, + omap_obj->dma_addr); err_release: drm_gem_object_release(obj); err_free: -- cgit From a96bf3cbd7b8557f5c5c7938e5f8926ea39d55e9 Mon Sep 17 00:00:00 2001 From: Sean Paul Date: Tue, 22 Oct 2019 16:47:29 -0400 Subject: Revert "drm/omap: add OMAP_BO flags to affect buffer allocation" This reverts commit 23b482252836ab3c5e6b3b20ed3038449cbc7679. This patch does not have an acceptable open source userspace implementation, and as such it does not meet the requirements for adding new UAPI. Discussion is in the Link. Link: https://lists.freedesktop.org/archives/dri-devel/2019-October/240586.html Fixes: 23b482252836 ("drm/omap: add OMAP_BO flags to affect buffer allocation") Cc: Tomi Valkeinen Cc: Jean-Jacques Hiblot Cc: David Airlie Cc: Daniel Vetter Cc: dri-devel@lists.freedesktop.org Acked-by: Tomi Valkeinen Acked-by: Daniel Vetter Signed-off-by: Sean Paul Link: https://patchwork.freedesktop.org/patch/msgid/20191022204733.235801-1-sean@poorly.run --- drivers/gpu/drm/omapdrm/omap_gem.c | 54 ++------------------------------------ 1 file changed, 2 insertions(+), 52 deletions(-) (limited to 'drivers/gpu/drm/omapdrm/omap_gem.c') diff --git a/drivers/gpu/drm/omapdrm/omap_gem.c b/drivers/gpu/drm/omapdrm/omap_gem.c index bf18dfe2b689..e518d93ca6df 100644 --- a/drivers/gpu/drm/omapdrm/omap_gem.c +++ b/drivers/gpu/drm/omapdrm/omap_gem.c @@ -1097,9 +1097,6 @@ void omap_gem_free_object(struct drm_gem_object *obj) list_del(&omap_obj->mm_list); mutex_unlock(&priv->list_lock); - if (omap_obj->flags & OMAP_BO_MEM_PIN) - omap_gem_unpin_locked(obj); - /* * We own the sole reference to the object at this point, but to keep * lockdep happy, we must still take the omap_obj_lock to call @@ -1150,19 +1147,10 @@ static bool omap_gem_validate_flags(struct drm_device *dev, u32 flags) return false; } - if ((flags & OMAP_BO_MEM_CONTIG) && (flags & OMAP_BO_MEM_DMM)) - return false; - - if ((flags & OMAP_BO_MEM_DMM) && !priv->usergart) - return false; - if (flags & OMAP_BO_TILED_MASK) { if (!priv->usergart) return false; - if (flags & OMAP_BO_MEM_CONTIG) - return false; - switch (flags & OMAP_BO_TILED_MASK) { case OMAP_BO_TILED_8: case OMAP_BO_TILED_16: @@ -1177,34 +1165,7 @@ static bool omap_gem_validate_flags(struct drm_device *dev, u32 flags) return true; } -/** - * omap_gem_new() - Create a new GEM buffer - * @dev: The DRM device - * @gsize: The requested size for the GEM buffer. If the buffer is tiled - * (2D buffer), the size is a pair of values: height and width - * expressed in pixels. If the buffers is not tiled, it is expressed - * in bytes. - * @flags: Flags give additionnal information about the allocation: - * OMAP_BO_TILED_x: use the TILER (2D buffers). The TILER container - * unit can be 8, 16 or 32 bits. Cache is always disabled for - * tiled buffers. - * OMAP_BO_SCANOUT: Scannout buffer, consummable by the DSS - * OMAP_BO_CACHED: Buffer CPU caching mode: cached - * OMAP_BO_WC: Buffer CPU caching mode: write-combined - * OMAP_BO_UNCACHED: Buffer CPU caching mode: uncached - * OMAP_BO_MEM_CONTIG: The driver will use dma_alloc to get the memory. - * This can be used to avoid DMM if the userspace knows it needs - * more than 128M of memory at the same time. - * OMAP_BO_MEM_DMM: The driver will use DMM to get the memory. There's - * not much use for this flag at the moment, as on platforms with - * DMM it is used by default, but it's here for completeness. - * OMAP_BO_MEM_PIN: The driver will pin the memory at alloc time, and - * keep it pinned. This can be used to 1) get an error at alloc - * time if DMM space is full, and 2) get rid of the constant - * pin/unpin operations which may have some effect on performance. - * - * Return: The GEM buffer or NULL if the allocation failed - */ +/* GEM buffer object constructor */ struct drm_gem_object *omap_gem_new(struct drm_device *dev, union omap_gem_size gsize, u32 flags) { @@ -1232,8 +1193,7 @@ struct drm_gem_object *omap_gem_new(struct drm_device *dev, */ flags &= ~(OMAP_BO_CACHED|OMAP_BO_WC|OMAP_BO_UNCACHED); flags |= tiler_get_cpu_cache_flags(); - } else if ((flags & OMAP_BO_MEM_CONTIG) || - ((flags & OMAP_BO_SCANOUT) && !priv->has_dmm)) { + } else if ((flags & OMAP_BO_SCANOUT) && !priv->has_dmm) { /* * If we don't have DMM, we must allocate scanout buffers * from contiguous DMA memory. @@ -1293,22 +1253,12 @@ struct drm_gem_object *omap_gem_new(struct drm_device *dev, goto err_release; } - if (flags & OMAP_BO_MEM_PIN) { - ret = omap_gem_pin(obj, NULL); - if (ret) - goto err_free_dma; - } - mutex_lock(&priv->list_lock); list_add(&omap_obj->mm_list, &priv->obj_list); mutex_unlock(&priv->list_lock); return obj; -err_free_dma: - if (flags & OMAP_BO_MEM_DMA_API) - dma_free_wc(dev->dev, size, omap_obj->vaddr, - omap_obj->dma_addr); err_release: drm_gem_object_release(obj); err_free: -- cgit