From: Matthijs van Duin matthijsvanduin@gmail.com
On omap5/dra7 tiled memory is currently strongly-ordered, which is just painfully and needlessly slow. Using device memory suffices and is much faster. Even normal uncacheable memory is safe if the application avoids reading from the framebuffer, so I've added a flag to enable userspace to indicate it really wants the memory type requested.
The option to use strongly-ordered memory has been retained as an extra memory type in case anyone needs it for some reason.
Signed-off-by: Matthijs van Duin matthijsvanduin@gmail.com --- drivers/gpu/drm/omapdrm/omap_gem.c | 30 +++++++++++++++++++----------- include/uapi/drm/omap_drm.h | 12 ++++++++---- 2 files changed, 27 insertions(+), 15 deletions(-)
diff --git a/drivers/gpu/drm/omapdrm/omap_gem.c b/drivers/gpu/drm/omapdrm/omap_gem.c index 5c5c86ddd6f4..374f259f367d 100644 --- a/drivers/gpu/drm/omapdrm/omap_gem.c +++ b/drivers/gpu/drm/omapdrm/omap_gem.c @@ -582,11 +582,19 @@ int omap_gem_mmap_obj(struct drm_gem_object *obj, vma->vm_flags &= ~VM_PFNMAP; vma->vm_flags |= VM_MIXEDMAP;
- if (omap_obj->flags & OMAP_BO_WC) { - vma->vm_page_prot = pgprot_writecombine(vm_get_page_prot(vma->vm_flags)); - } else if (omap_obj->flags & OMAP_BO_UNCACHED) { - vma->vm_page_prot = pgprot_noncached(vm_get_page_prot(vma->vm_flags)); - } else { + vma->vm_page_prot = vm_get_page_prot(vma->vm_flags); + + switch (omap_obj->flags & OMAP_BO_CACHE_MASK) { + case OMAP_BO_WC: + vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot); + break; + case OMAP_BO_UNCACHED: + vma->vm_page_prot = pgprot_device(vma->vm_page_prot); + break; + case OMAP_BO_SYNC: + vma->vm_page_prot = pgprot_stronglyordered(vma->vm_page_prot); + break; + default: /* * We do have some private objects, at least for scanout buffers * on hardware without DMM/TILER. But these are allocated write- @@ -603,8 +611,6 @@ int omap_gem_mmap_obj(struct drm_gem_object *obj, fput(vma->vm_file); vma->vm_pgoff = 0; vma->vm_file = get_file(obj->filp); - - vma->vm_page_prot = vm_get_page_prot(vma->vm_flags); }
return 0; @@ -1142,11 +1148,13 @@ struct drm_gem_object *omap_gem_new(struct drm_device *dev, flags |= OMAP_BO_MEM_SHMEM;
/* - * Currently don't allow cached buffers. There is some caching - * stuff that needs to be handled better. + * Unless caller knows what he's doing replace cacheable and + * normal uncacheable memory types by default type for cpu. */ - flags &= ~(OMAP_BO_CACHED|OMAP_BO_WC|OMAP_BO_UNCACHED); - flags |= tiler_get_cpu_cache_flags(); + if (!(flags & (OMAP_BO_UNCACHED | OMAP_BO_FORCE))) { + flags &= ~OMAP_BO_CACHE_MASK; + 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 diff --git a/include/uapi/drm/omap_drm.h b/include/uapi/drm/omap_drm.h index 1fccffef9e27..7fa3bcb6ddbc 100644 --- a/include/uapi/drm/omap_drm.h +++ b/include/uapi/drm/omap_drm.h @@ -42,10 +42,14 @@ struct drm_omap_param { #define OMAP_BO_CACHE_MASK 0x00000006 /* cache type mask, see cache modes */ #define OMAP_BO_TILED_MASK 0x00000f00 /* tiled mapping mask, see tiled modes */
-/* cache modes */ -#define OMAP_BO_CACHED 0x00000000 /* default */ -#define OMAP_BO_WC 0x00000002 /* write-combine */ -#define OMAP_BO_UNCACHED 0x00000004 /* strongly-ordered (uncached) */ +/* memory types / cache modes */ +#define OMAP_BO_CACHED 0x00000000 /* normal cacheable */ +#define OMAP_BO_WC 0x00000002 /* normal non-cacheable */ +#define OMAP_BO_UNCACHED 0x00000004 /* device */ +#define OMAP_BO_SYNC 0x00000006 /* strongly-ordered */ + +/* allow use of normal memory types even when this is hazardous */ +#define OMAP_BO_FORCE 0x00000010
/* tiled modes */ #define OMAP_BO_TILED_8 0x00000100