From e4e818cc2d7ccfa76d258e4a63ceba9880591303 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 24 Apr 2017 13:50:19 +0900 Subject: drm: make drm_panel.h self-contained -ENOSYS and -EINVAL are referenced in some static inline functions. of_drm_find_pane() takes a pointer to struct device_node. Make this header self-contained to not depend on specific include order. Signed-off-by: Masahiro Yamada Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1493009447-31524-2-git-send-email-yamada.masahiro@socionext.com --- include/drm/drm_panel.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/drm/drm_panel.h b/include/drm/drm_panel.h index 1b364b0100f4..14ac240a1f64 100644 --- a/include/drm/drm_panel.h +++ b/include/drm/drm_panel.h @@ -24,8 +24,10 @@ #ifndef __DRM_PANEL_H__ #define __DRM_PANEL_H__ +#include #include +struct device_node; struct drm_connector; struct drm_device; struct drm_panel; -- cgit v1.2.3 From 2da83319a19f9d9e0058e4c0a6a115b8456fcd48 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 24 Apr 2017 13:50:20 +0900 Subject: drm/ttm: fix include notation and remove -Iinclude/drm flag MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For the C file, include instead of relative path from include/drm. For headers in include/drm/ttm, simplify the with "*.h". This allows us to remove the -Iinclude/drm compiler flag from drivers/gpu/drm/ttm/Makefile (and from other drivers' Makefiles). Signed-off-by: Masahiro Yamada Reviewed-by: Michel Dänzer Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1493009447-31524-3-git-send-email-yamada.masahiro@socionext.com --- drivers/gpu/drm/ttm/Makefile | 1 - drivers/gpu/drm/ttm/ttm_bo_vm.c | 6 +++--- include/drm/ttm/ttm_bo_driver.h | 9 +++++---- include/drm/ttm/ttm_execbuf_util.h | 3 ++- include/drm/ttm/ttm_lock.h | 3 ++- include/drm/ttm/ttm_object.h | 3 ++- 6 files changed, 14 insertions(+), 11 deletions(-) (limited to 'include') diff --git a/drivers/gpu/drm/ttm/Makefile b/drivers/gpu/drm/ttm/Makefile index f92325800f8a..4d0c938ff4b2 100644 --- a/drivers/gpu/drm/ttm/Makefile +++ b/drivers/gpu/drm/ttm/Makefile @@ -1,7 +1,6 @@ # # Makefile for the drm device driver. This driver provides support for the -ccflags-y := -Iinclude/drm ttm-y := ttm_memory.o ttm_tt.o ttm_bo.o \ ttm_bo_util.o ttm_bo_vm.o ttm_module.o \ ttm_object.o ttm_lock.o ttm_execbuf_util.o ttm_page_alloc.o \ diff --git a/drivers/gpu/drm/ttm/ttm_bo_vm.c b/drivers/gpu/drm/ttm/ttm_bo_vm.c index 9f53df95f35c..b442d12f2f7d 100644 --- a/drivers/gpu/drm/ttm/ttm_bo_vm.c +++ b/drivers/gpu/drm/ttm/ttm_bo_vm.c @@ -30,9 +30,9 @@ #define pr_fmt(fmt) "[TTM] " fmt -#include -#include -#include +#include +#include +#include #include #include #include diff --git a/include/drm/ttm/ttm_bo_driver.h b/include/drm/ttm/ttm_bo_driver.h index 6bbd34d25a8d..990d529f823c 100644 --- a/include/drm/ttm/ttm_bo_driver.h +++ b/include/drm/ttm/ttm_bo_driver.h @@ -30,10 +30,6 @@ #ifndef _TTM_BO_DRIVER_H_ #define _TTM_BO_DRIVER_H_ -#include -#include -#include -#include #include #include #include @@ -42,6 +38,11 @@ #include #include +#include "ttm_bo_api.h" +#include "ttm_memory.h" +#include "ttm_module.h" +#include "ttm_placement.h" + #define TTM_MAX_BO_PRIORITY 4U struct ttm_backend_func { diff --git a/include/drm/ttm/ttm_execbuf_util.h b/include/drm/ttm/ttm_execbuf_util.h index 47f35b8e6d09..b0fdd1980034 100644 --- a/include/drm/ttm/ttm_execbuf_util.h +++ b/include/drm/ttm/ttm_execbuf_util.h @@ -31,9 +31,10 @@ #ifndef _TTM_EXECBUF_UTIL_H_ #define _TTM_EXECBUF_UTIL_H_ -#include #include +#include "ttm_bo_api.h" + /** * struct ttm_validate_buffer * diff --git a/include/drm/ttm/ttm_lock.h b/include/drm/ttm/ttm_lock.h index 2902beb5f689..0c3af9836863 100644 --- a/include/drm/ttm/ttm_lock.h +++ b/include/drm/ttm/ttm_lock.h @@ -49,10 +49,11 @@ #ifndef _TTM_LOCK_H_ #define _TTM_LOCK_H_ -#include #include #include +#include "ttm_object.h" + /** * struct ttm_lock * diff --git a/include/drm/ttm/ttm_object.h b/include/drm/ttm/ttm_object.h index 1487011fe057..a98bfeb4239e 100644 --- a/include/drm/ttm/ttm_object.h +++ b/include/drm/ttm/ttm_object.h @@ -42,7 +42,8 @@ #include #include #include -#include + +#include "ttm_memory.h" /** * enum ttm_ref_type -- cgit v1.2.3 From 5e851c9de72b3e8316997e022f0c589429aca7a3 Mon Sep 17 00:00:00 2001 From: Gabriel Krisman Bertazi Date: Thu, 20 Apr 2017 21:38:19 -0300 Subject: drm: trivial documentation fix to drm_for_each_connector_iter While reading drm_for_each_connector_iter, I noticed a mention to drm_connector_begin which doesn't exist. It should be drm_connector_get. Signed-off-by: Gabriel Krisman Bertazi Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/20170421003819.17685-1-krisman@collabora.co.uk --- include/drm/drm_connector.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h index 9c15993b9071..2fe09c1ddfb8 100644 --- a/include/drm/drm_connector.h +++ b/include/drm/drm_connector.h @@ -1052,7 +1052,7 @@ void drm_connector_list_iter_end(struct drm_connector_list_iter *iter); * * Note that @connector is only valid within the list body, if you want to use * @connector after calling drm_connector_list_iter_end() then you need to grab - * your own reference first using drm_connector_begin(). + * your own reference first using drm_connector_get(). */ #define drm_for_each_connector_iter(connector, iter) \ while ((connector = drm_connector_list_iter_next(iter))) -- cgit v1.2.3 From c4f51dc8729645f755ee59b5a2535b6f567b4b05 Mon Sep 17 00:00:00 2001 From: Michal Hocko Date: Wed, 17 May 2017 08:55:08 +0200 Subject: drm: replace drm_[cm]alloc* by kvmalloc alternatives drm_[cm]alloc* has grown their own kvmalloc with vmalloc fallback implementations. MM has grown kvmalloc* helpers in the meantime. Let's use those because it a) reduces the code and b) MM has a better idea how to implement fallbacks (e.g. do not vmalloc before kmalloc is tried with __GFP_NORETRY). drm_calloc_large needs to get __GFP_ZERO explicitly but it is the same thing as kvmalloc_array in principle. Signed-off-by: Michal Hocko Reviewed-by: Chris Wilson Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/20170517065509.18659-1-mhocko@kernel.org --- include/drm/drm_mem_util.h | 78 ---------------------------------------------- 1 file changed, 78 deletions(-) delete mode 100644 include/drm/drm_mem_util.h (limited to 'include') diff --git a/include/drm/drm_mem_util.h b/include/drm/drm_mem_util.h deleted file mode 100644 index d0f6cf2e5324..000000000000 --- a/include/drm/drm_mem_util.h +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright © 2008 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - * - * Authors: - * Jesse Barnes - * - */ -#ifndef _DRM_MEM_UTIL_H_ -#define _DRM_MEM_UTIL_H_ - -#include - -static __inline__ void *drm_calloc_large(size_t nmemb, size_t size) -{ - if (size != 0 && nmemb > SIZE_MAX / size) - return NULL; - - if (size * nmemb <= PAGE_SIZE) - return kcalloc(nmemb, size, GFP_KERNEL); - - return vzalloc(size * nmemb); -} - -/* Modeled after cairo's malloc_ab, it's like calloc but without the zeroing. */ -static __inline__ void *drm_malloc_ab(size_t nmemb, size_t size) -{ - if (size != 0 && nmemb > SIZE_MAX / size) - return NULL; - - if (size * nmemb <= PAGE_SIZE) - return kmalloc(nmemb * size, GFP_KERNEL); - - return vmalloc(size * nmemb); -} - -static __inline__ void *drm_malloc_gfp(size_t nmemb, size_t size, gfp_t gfp) -{ - if (size != 0 && nmemb > SIZE_MAX / size) - return NULL; - - if (size * nmemb <= PAGE_SIZE) - return kmalloc(nmemb * size, gfp); - - if (gfp & __GFP_RECLAIMABLE) { - void *ptr = kmalloc(nmemb * size, - gfp | __GFP_NOWARN | __GFP_NORETRY); - if (ptr) - return ptr; - } - - return __vmalloc(size * nmemb, gfp, PAGE_KERNEL); -} - -static __inline void drm_free_large(void *ptr) -{ - kvfree(ptr); -} - -#endif -- cgit v1.2.3 From 2098105ec65cb364f3d77baa446b2ad5ba6bc7b9 Mon Sep 17 00:00:00 2001 From: Michal Hocko Date: Wed, 17 May 2017 14:23:12 +0200 Subject: drm: drop drm_[cm]alloc* helpers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Now that drm_[cm]alloc* helpers are simple one line wrappers around kvmalloc_array and drm_free_large is just kvfree alias we can drop them and replace by their native forms. This shouldn't introduce any functional change. Changes since v1 - fix typo in drivers/gpu//drm/etnaviv/etnaviv_gem.c - noticed by 0day build robot Suggested-by: Daniel Vetter Signed-off-by: Michal Hocko drm: drop drm_[cm]alloc* helpers [danvet: Fixup vgem which grew another user very recently.] Signed-off-by: Daniel Vetter Acked-by: Christian König Link: http://patchwork.freedesktop.org/patch/msgid/20170517122312.GK18247@dhcp22.suse.cz --- drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c | 16 +++++----- drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 19 ++++++------ drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 7 +++-- drivers/gpu/drm/drm_gem.c | 6 ++-- drivers/gpu/drm/etnaviv/etnaviv_gem.c | 12 ++++---- drivers/gpu/drm/etnaviv/etnaviv_gem_prime.c | 4 +-- drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c | 12 ++++---- drivers/gpu/drm/exynos/exynos_drm_gem.c | 11 +++---- drivers/gpu/drm/i915/i915_debugfs.c | 4 +-- drivers/gpu/drm/i915/i915_gem.c | 4 +-- drivers/gpu/drm/i915/i915_gem_execbuffer.c | 34 +++++++++++----------- drivers/gpu/drm/i915/i915_gem_gtt.c | 6 ++-- drivers/gpu/drm/i915/i915_gem_userptr.c | 8 ++--- drivers/gpu/drm/i915/selftests/intel_breadcrumbs.c | 12 ++++---- drivers/gpu/drm/msm/msm_gem.c | 10 +++---- drivers/gpu/drm/radeon/radeon_cs.c | 11 +++---- drivers/gpu/drm/radeon/radeon_gem.c | 2 +- drivers/gpu/drm/radeon/radeon_ring.c | 4 +-- drivers/gpu/drm/radeon/radeon_vm.c | 4 +-- drivers/gpu/drm/ttm/ttm_tt.c | 13 +++++---- drivers/gpu/drm/udl/udl_dmabuf.c | 2 +- drivers/gpu/drm/udl/udl_gem.c | 2 +- drivers/gpu/drm/vc4/vc4_gem.c | 15 +++++----- drivers/gpu/drm/vgem/vgem_drv.c | 4 +-- drivers/gpu/drm/virtio/virtgpu_ioctl.c | 27 ++++++++--------- include/drm/drmP.h | 1 - 26 files changed, 128 insertions(+), 122 deletions(-) (limited to 'include') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c index a6649874e6ce..9f0247cdda5e 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c @@ -96,7 +96,7 @@ static int amdgpu_bo_list_set(struct amdgpu_device *adev, int r; unsigned long total_size = 0; - array = drm_malloc_ab(num_entries, sizeof(struct amdgpu_bo_list_entry)); + array = kvmalloc_array(num_entries, sizeof(struct amdgpu_bo_list_entry), GFP_KERNEL); if (!array) return -ENOMEM; memset(array, 0, num_entries * sizeof(struct amdgpu_bo_list_entry)); @@ -148,7 +148,7 @@ static int amdgpu_bo_list_set(struct amdgpu_device *adev, for (i = 0; i < list->num_entries; ++i) amdgpu_bo_unref(&list->array[i].robj); - drm_free_large(list->array); + kvfree(list->array); list->gds_obj = gds_obj; list->gws_obj = gws_obj; @@ -163,7 +163,7 @@ static int amdgpu_bo_list_set(struct amdgpu_device *adev, error_free: while (i--) amdgpu_bo_unref(&array[i].robj); - drm_free_large(array); + kvfree(array); return r; } @@ -224,7 +224,7 @@ void amdgpu_bo_list_free(struct amdgpu_bo_list *list) amdgpu_bo_unref(&list->array[i].robj); mutex_destroy(&list->lock); - drm_free_large(list->array); + kvfree(list->array); kfree(list); } @@ -244,8 +244,8 @@ int amdgpu_bo_list_ioctl(struct drm_device *dev, void *data, int r; - info = drm_malloc_ab(args->in.bo_number, - sizeof(struct drm_amdgpu_bo_list_entry)); + info = kvmalloc_array(args->in.bo_number, + sizeof(struct drm_amdgpu_bo_list_entry), GFP_KERNEL); if (!info) return -ENOMEM; @@ -311,11 +311,11 @@ int amdgpu_bo_list_ioctl(struct drm_device *dev, void *data, memset(args, 0, sizeof(*args)); args->out.list_handle = handle; - drm_free_large(info); + kvfree(info); return 0; error_free: - drm_free_large(info); + kvfree(info); return r; } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c index 4e6b9501ab0a..5b3e0f63a115 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c @@ -194,7 +194,7 @@ int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, void *data) size = p->chunks[i].length_dw; cdata = (void __user *)(uintptr_t)user_chunk.chunk_data; - p->chunks[i].kdata = drm_malloc_ab(size, sizeof(uint32_t)); + p->chunks[i].kdata = kvmalloc_array(size, sizeof(uint32_t), GFP_KERNEL); if (p->chunks[i].kdata == NULL) { ret = -ENOMEM; i--; @@ -247,7 +247,7 @@ free_all_kdata: i = p->nchunks - 1; free_partial_kdata: for (; i >= 0; i--) - drm_free_large(p->chunks[i].kdata); + kvfree(p->chunks[i].kdata); kfree(p->chunks); p->chunks = NULL; p->nchunks = 0; @@ -505,7 +505,7 @@ static int amdgpu_cs_list_validate(struct amdgpu_cs_parser *p, return r; if (binding_userptr) { - drm_free_large(lobj->user_pages); + kvfree(lobj->user_pages); lobj->user_pages = NULL; } } @@ -571,7 +571,7 @@ static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p, release_pages(e->user_pages, e->robj->tbo.ttm->num_pages, false); - drm_free_large(e->user_pages); + kvfree(e->user_pages); e->user_pages = NULL; } @@ -601,8 +601,9 @@ static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p, list_for_each_entry(e, &need_pages, tv.head) { struct ttm_tt *ttm = e->robj->tbo.ttm; - e->user_pages = drm_calloc_large(ttm->num_pages, - sizeof(struct page*)); + e->user_pages = kvmalloc_array(ttm->num_pages, + sizeof(struct page*), + GFP_KERNEL | __GFP_ZERO); if (!e->user_pages) { r = -ENOMEM; DRM_ERROR("calloc failure in %s\n", __func__); @@ -612,7 +613,7 @@ static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p, r = amdgpu_ttm_tt_get_user_pages(ttm, e->user_pages); if (r) { DRM_ERROR("amdgpu_ttm_tt_get_user_pages failed.\n"); - drm_free_large(e->user_pages); + kvfree(e->user_pages); e->user_pages = NULL; goto error_free_pages; } @@ -708,7 +709,7 @@ error_free_pages: release_pages(e->user_pages, e->robj->tbo.ttm->num_pages, false); - drm_free_large(e->user_pages); + kvfree(e->user_pages); } } @@ -761,7 +762,7 @@ static void amdgpu_cs_parser_fini(struct amdgpu_cs_parser *parser, int error, bo amdgpu_bo_list_put(parser->bo_list); for (i = 0; i < parser->nchunks; i++) - drm_free_large(parser->chunks[i].kdata); + kvfree(parser->chunks[i].kdata); kfree(parser->chunks); if (parser->job) amdgpu_job_free(parser->job); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c index 07ff3b1514f1..749a6cde7985 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c @@ -279,8 +279,9 @@ static int amdgpu_vm_alloc_levels(struct amdgpu_device *adev, if (!parent->entries) { unsigned num_entries = amdgpu_vm_num_entries(adev, level); - parent->entries = drm_calloc_large(num_entries, - sizeof(struct amdgpu_vm_pt)); + parent->entries = kvmalloc_array(num_entries, + sizeof(struct amdgpu_vm_pt), + GFP_KERNEL | __GFP_ZERO); if (!parent->entries) return -ENOMEM; memset(parent->entries, 0 , sizeof(struct amdgpu_vm_pt)); @@ -2198,7 +2199,7 @@ static void amdgpu_vm_free_levels(struct amdgpu_vm_pt *level) for (i = 0; i <= level->last_entry_used; i++) amdgpu_vm_free_levels(&level->entries[i]); - drm_free_large(level->entries); + kvfree(level->entries); } /** diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c index b1e28c944637..8dc11064253d 100644 --- a/drivers/gpu/drm/drm_gem.c +++ b/drivers/gpu/drm/drm_gem.c @@ -521,7 +521,7 @@ struct page **drm_gem_get_pages(struct drm_gem_object *obj) npages = obj->size >> PAGE_SHIFT; - pages = drm_malloc_ab(npages, sizeof(struct page *)); + pages = kvmalloc_array(npages, sizeof(struct page *), GFP_KERNEL); if (pages == NULL) return ERR_PTR(-ENOMEM); @@ -546,7 +546,7 @@ fail: while (i--) put_page(pages[i]); - drm_free_large(pages); + kvfree(pages); return ERR_CAST(p); } EXPORT_SYMBOL(drm_gem_get_pages); @@ -582,7 +582,7 @@ void drm_gem_put_pages(struct drm_gem_object *obj, struct page **pages, put_page(pages[i]); } - drm_free_large(pages); + kvfree(pages); } EXPORT_SYMBOL(drm_gem_put_pages); diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gem.c b/drivers/gpu/drm/etnaviv/etnaviv_gem.c index fd56f92f3469..d6fb724fc3cc 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_gem.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_gem.c @@ -748,7 +748,7 @@ static struct page **etnaviv_gem_userptr_do_get_pages( uintptr_t ptr; unsigned int flags = 0; - pvec = drm_malloc_ab(npages, sizeof(struct page *)); + pvec = kvmalloc_array(npages, sizeof(struct page *), GFP_KERNEL); if (!pvec) return ERR_PTR(-ENOMEM); @@ -772,7 +772,7 @@ static struct page **etnaviv_gem_userptr_do_get_pages( if (ret < 0) { release_pages(pvec, pinned, 0); - drm_free_large(pvec); + kvfree(pvec); return ERR_PTR(ret); } @@ -823,7 +823,7 @@ static int etnaviv_gem_userptr_get_pages(struct etnaviv_gem_object *etnaviv_obj) mm = get_task_mm(etnaviv_obj->userptr.task); pinned = 0; if (mm == current->mm) { - pvec = drm_malloc_ab(npages, sizeof(struct page *)); + pvec = kvmalloc_array(npages, sizeof(struct page *), GFP_KERNEL); if (!pvec) { mmput(mm); return -ENOMEM; @@ -832,7 +832,7 @@ static int etnaviv_gem_userptr_get_pages(struct etnaviv_gem_object *etnaviv_obj) pinned = __get_user_pages_fast(etnaviv_obj->userptr.ptr, npages, !etnaviv_obj->userptr.ro, pvec); if (pinned < 0) { - drm_free_large(pvec); + kvfree(pvec); mmput(mm); return pinned; } @@ -845,7 +845,7 @@ static int etnaviv_gem_userptr_get_pages(struct etnaviv_gem_object *etnaviv_obj) } release_pages(pvec, pinned, 0); - drm_free_large(pvec); + kvfree(pvec); work = kmalloc(sizeof(*work), GFP_KERNEL); if (!work) { @@ -879,7 +879,7 @@ static void etnaviv_gem_userptr_release(struct etnaviv_gem_object *etnaviv_obj) int npages = etnaviv_obj->base.size >> PAGE_SHIFT; release_pages(etnaviv_obj->pages, npages, 0); - drm_free_large(etnaviv_obj->pages); + kvfree(etnaviv_obj->pages); } put_task_struct(etnaviv_obj->userptr.task); } diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gem_prime.c b/drivers/gpu/drm/etnaviv/etnaviv_gem_prime.c index 62b47972a52e..367bf952f61a 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_gem_prime.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_gem_prime.c @@ -87,7 +87,7 @@ static void etnaviv_gem_prime_release(struct etnaviv_gem_object *etnaviv_obj) * ours, just free the array we allocated: */ if (etnaviv_obj->pages) - drm_free_large(etnaviv_obj->pages); + kvfree(etnaviv_obj->pages); drm_prime_gem_destroy(&etnaviv_obj->base, etnaviv_obj->sgt); } @@ -128,7 +128,7 @@ struct drm_gem_object *etnaviv_gem_prime_import_sg_table(struct drm_device *dev, npages = size / PAGE_SIZE; etnaviv_obj->sgt = sgt; - etnaviv_obj->pages = drm_malloc_ab(npages, sizeof(struct page *)); + etnaviv_obj->pages = kvmalloc_array(npages, sizeof(struct page *), GFP_KERNEL); if (!etnaviv_obj->pages) { ret = -ENOMEM; goto fail; diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c b/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c index e1909429837e..a13930e1d8c9 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c @@ -343,9 +343,9 @@ int etnaviv_ioctl_gem_submit(struct drm_device *dev, void *data, * Copy the command submission and bo array to kernel space in * one go, and do this outside of any locks. */ - bos = drm_malloc_ab(args->nr_bos, sizeof(*bos)); - relocs = drm_malloc_ab(args->nr_relocs, sizeof(*relocs)); - stream = drm_malloc_ab(1, args->stream_size); + bos = kvmalloc_array(args->nr_bos, sizeof(*bos), GFP_KERNEL); + relocs = kvmalloc_array(args->nr_relocs, sizeof(*relocs), GFP_KERNEL); + stream = kvmalloc_array(1, args->stream_size, GFP_KERNEL); cmdbuf = etnaviv_cmdbuf_new(gpu->cmdbuf_suballoc, ALIGN(args->stream_size, 8) + 8, args->nr_bos); @@ -487,11 +487,11 @@ err_submit_cmds: if (cmdbuf) etnaviv_cmdbuf_free(cmdbuf); if (stream) - drm_free_large(stream); + kvfree(stream); if (bos) - drm_free_large(bos); + kvfree(bos); if (relocs) - drm_free_large(relocs); + kvfree(relocs); return ret; } diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c b/drivers/gpu/drm/exynos/exynos_drm_gem.c index 55a1579d11b3..c23479be4850 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_gem.c +++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c @@ -59,7 +59,8 @@ static int exynos_drm_alloc_buf(struct exynos_drm_gem *exynos_gem) nr_pages = exynos_gem->size >> PAGE_SHIFT; - exynos_gem->pages = drm_calloc_large(nr_pages, sizeof(struct page *)); + exynos_gem->pages = kvmalloc_array(nr_pages, sizeof(struct page *), + GFP_KERNEL | __GFP_ZERO); if (!exynos_gem->pages) { DRM_ERROR("failed to allocate pages.\n"); return -ENOMEM; @@ -101,7 +102,7 @@ err_dma_free: dma_free_attrs(to_dma_dev(dev), exynos_gem->size, exynos_gem->cookie, exynos_gem->dma_addr, exynos_gem->dma_attrs); err_free: - drm_free_large(exynos_gem->pages); + kvfree(exynos_gem->pages); return ret; } @@ -122,7 +123,7 @@ static void exynos_drm_free_buf(struct exynos_drm_gem *exynos_gem) (dma_addr_t)exynos_gem->dma_addr, exynos_gem->dma_attrs); - drm_free_large(exynos_gem->pages); + kvfree(exynos_gem->pages); } static int exynos_drm_gem_handle_create(struct drm_gem_object *obj, @@ -559,7 +560,7 @@ exynos_drm_gem_prime_import_sg_table(struct drm_device *dev, exynos_gem->dma_addr = sg_dma_address(sgt->sgl); npages = exynos_gem->size >> PAGE_SHIFT; - exynos_gem->pages = drm_malloc_ab(npages, sizeof(struct page *)); + exynos_gem->pages = kvmalloc_array(npages, sizeof(struct page *), GFP_KERNEL); if (!exynos_gem->pages) { ret = -ENOMEM; goto err; @@ -588,7 +589,7 @@ exynos_drm_gem_prime_import_sg_table(struct drm_device *dev, return &exynos_gem->base; err_free_large: - drm_free_large(exynos_gem->pages); + kvfree(exynos_gem->pages); err: drm_gem_object_release(&exynos_gem->base); kfree(exynos_gem); diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index d689e511744e..07f87985ea0b 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -229,7 +229,7 @@ static int i915_gem_stolen_list_info(struct seq_file *m, void *data) int ret; total = READ_ONCE(dev_priv->mm.object_count); - objects = drm_malloc_ab(total, sizeof(*objects)); + objects = kvmalloc_array(total, sizeof(*objects), GFP_KERNEL); if (!objects) return -ENOMEM; @@ -274,7 +274,7 @@ static int i915_gem_stolen_list_info(struct seq_file *m, void *data) mutex_unlock(&dev->struct_mutex); out: - drm_free_large(objects); + kvfree(objects); return ret; } diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index b6ac3df18b58..0e07f35e270c 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -2504,7 +2504,7 @@ static void *i915_gem_object_map(const struct drm_i915_gem_object *obj, if (n_pages > ARRAY_SIZE(stack_pages)) { /* Too big for stack -- allocate temporary array instead */ - pages = drm_malloc_gfp(n_pages, sizeof(*pages), GFP_TEMPORARY); + pages = kvmalloc_array(n_pages, sizeof(*pages), GFP_TEMPORARY); if (!pages) return NULL; } @@ -2526,7 +2526,7 @@ static void *i915_gem_object_map(const struct drm_i915_gem_object *obj, addr = vmap(pages, n_pages, 0, pgprot); if (pages != stack_pages) - drm_free_large(pages); + kvfree(pages); return addr; } diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index a3e59c8ef27b..4ee2dc38b7c9 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c @@ -1019,11 +1019,11 @@ i915_gem_execbuffer_relocate_slow(struct drm_device *dev, for (i = 0; i < count; i++) total += exec[i].relocation_count; - reloc_offset = drm_malloc_ab(count, sizeof(*reloc_offset)); - reloc = drm_malloc_ab(total, sizeof(*reloc)); + reloc_offset = kvmalloc_array(count, sizeof(*reloc_offset), GFP_KERNEL); + reloc = kvmalloc_array(total, sizeof(*reloc), GFP_KERNEL); if (reloc == NULL || reloc_offset == NULL) { - drm_free_large(reloc); - drm_free_large(reloc_offset); + kvfree(reloc); + kvfree(reloc_offset); mutex_lock(&dev->struct_mutex); return -ENOMEM; } @@ -1099,8 +1099,8 @@ i915_gem_execbuffer_relocate_slow(struct drm_device *dev, */ err: - drm_free_large(reloc); - drm_free_large(reloc_offset); + kvfree(reloc); + kvfree(reloc_offset); return ret; } @@ -1859,13 +1859,13 @@ i915_gem_execbuffer(struct drm_device *dev, void *data, } /* Copy in the exec list from userland */ - exec_list = drm_malloc_ab(sizeof(*exec_list), args->buffer_count); - exec2_list = drm_malloc_ab(sizeof(*exec2_list), args->buffer_count); + exec_list = kvmalloc_array(sizeof(*exec_list), args->buffer_count, GFP_KERNEL); + exec2_list = kvmalloc_array(sizeof(*exec2_list), args->buffer_count, GFP_KERNEL); if (exec_list == NULL || exec2_list == NULL) { DRM_DEBUG("Failed to allocate exec list for %d buffers\n", args->buffer_count); - drm_free_large(exec_list); - drm_free_large(exec2_list); + kvfree(exec_list); + kvfree(exec2_list); return -ENOMEM; } ret = copy_from_user(exec_list, @@ -1874,8 +1874,8 @@ i915_gem_execbuffer(struct drm_device *dev, void *data, if (ret != 0) { DRM_DEBUG("copy %d exec entries failed %d\n", args->buffer_count, ret); - drm_free_large(exec_list); - drm_free_large(exec2_list); + kvfree(exec_list); + kvfree(exec2_list); return -EFAULT; } @@ -1924,8 +1924,8 @@ i915_gem_execbuffer(struct drm_device *dev, void *data, } } - drm_free_large(exec_list); - drm_free_large(exec2_list); + kvfree(exec_list); + kvfree(exec2_list); return ret; } @@ -1943,7 +1943,7 @@ i915_gem_execbuffer2(struct drm_device *dev, void *data, return -EINVAL; } - exec2_list = drm_malloc_gfp(args->buffer_count, + exec2_list = kvmalloc_array(args->buffer_count, sizeof(*exec2_list), GFP_TEMPORARY); if (exec2_list == NULL) { @@ -1957,7 +1957,7 @@ i915_gem_execbuffer2(struct drm_device *dev, void *data, if (ret != 0) { DRM_DEBUG("copy %d exec entries failed %d\n", args->buffer_count, ret); - drm_free_large(exec2_list); + kvfree(exec2_list); return -EFAULT; } @@ -1984,6 +1984,6 @@ i915_gem_execbuffer2(struct drm_device *dev, void *data, } } - drm_free_large(exec2_list); + kvfree(exec2_list); return ret; } diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index 2aa6b97fd22f..7e3193aa7da1 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -3102,7 +3102,7 @@ intel_rotate_pages(struct intel_rotation_info *rot_info, int ret = -ENOMEM; /* Allocate a temporary list of source pages for random access. */ - page_addr_list = drm_malloc_gfp(n_pages, + page_addr_list = kvmalloc_array(n_pages, sizeof(dma_addr_t), GFP_TEMPORARY); if (!page_addr_list) @@ -3135,14 +3135,14 @@ intel_rotate_pages(struct intel_rotation_info *rot_info, DRM_DEBUG_KMS("Created rotated page mapping for object size %zu (%ux%u tiles, %u pages)\n", obj->base.size, rot_info->plane[0].width, rot_info->plane[0].height, size); - drm_free_large(page_addr_list); + kvfree(page_addr_list); return st; err_sg_alloc: kfree(st); err_st_alloc: - drm_free_large(page_addr_list); + kvfree(page_addr_list); DRM_DEBUG_KMS("Failed to create rotated mapping for object size %zu! (%ux%u tiles, %u pages)\n", obj->base.size, rot_info->plane[0].width, rot_info->plane[0].height, size); diff --git a/drivers/gpu/drm/i915/i915_gem_userptr.c b/drivers/gpu/drm/i915/i915_gem_userptr.c index 58ccf8b8ca1c..1a0ce1dc68f5 100644 --- a/drivers/gpu/drm/i915/i915_gem_userptr.c +++ b/drivers/gpu/drm/i915/i915_gem_userptr.c @@ -507,7 +507,7 @@ __i915_gem_userptr_get_pages_worker(struct work_struct *_work) ret = -ENOMEM; pinned = 0; - pvec = drm_malloc_gfp(npages, sizeof(struct page *), GFP_TEMPORARY); + pvec = kvmalloc_array(npages, sizeof(struct page *), GFP_TEMPORARY); if (pvec != NULL) { struct mm_struct *mm = obj->userptr.mm->mm; unsigned int flags = 0; @@ -555,7 +555,7 @@ __i915_gem_userptr_get_pages_worker(struct work_struct *_work) mutex_unlock(&obj->mm.lock); release_pages(pvec, pinned, 0); - drm_free_large(pvec); + kvfree(pvec); i915_gem_object_put(obj); put_task_struct(work->task); @@ -642,7 +642,7 @@ i915_gem_userptr_get_pages(struct drm_i915_gem_object *obj) pinned = 0; if (mm == current->mm) { - pvec = drm_malloc_gfp(num_pages, sizeof(struct page *), + pvec = kvmalloc_array(num_pages, sizeof(struct page *), GFP_TEMPORARY | __GFP_NORETRY | __GFP_NOWARN); @@ -669,7 +669,7 @@ i915_gem_userptr_get_pages(struct drm_i915_gem_object *obj) if (IS_ERR(pages)) release_pages(pvec, pinned, 0); - drm_free_large(pvec); + kvfree(pvec); return pages; } diff --git a/drivers/gpu/drm/i915/selftests/intel_breadcrumbs.c b/drivers/gpu/drm/i915/selftests/intel_breadcrumbs.c index 19860a372d90..7276194c04f7 100644 --- a/drivers/gpu/drm/i915/selftests/intel_breadcrumbs.c +++ b/drivers/gpu/drm/i915/selftests/intel_breadcrumbs.c @@ -117,7 +117,7 @@ static int igt_random_insert_remove(void *arg) mock_engine_reset(engine); - waiters = drm_malloc_gfp(count, sizeof(*waiters), GFP_TEMPORARY); + waiters = kvmalloc_array(count, sizeof(*waiters), GFP_TEMPORARY); if (!waiters) goto out_engines; @@ -169,7 +169,7 @@ out_order: out_bitmap: kfree(bitmap); out_waiters: - drm_free_large(waiters); + kvfree(waiters); out_engines: mock_engine_flush(engine); return err; @@ -187,7 +187,7 @@ static int igt_insert_complete(void *arg) mock_engine_reset(engine); - waiters = drm_malloc_gfp(count, sizeof(*waiters), GFP_TEMPORARY); + waiters = kvmalloc_array(count, sizeof(*waiters), GFP_TEMPORARY); if (!waiters) goto out_engines; @@ -254,7 +254,7 @@ static int igt_insert_complete(void *arg) out_bitmap: kfree(bitmap); out_waiters: - drm_free_large(waiters); + kvfree(waiters); out_engines: mock_engine_flush(engine); return err; @@ -368,7 +368,7 @@ static int igt_wakeup(void *arg) mock_engine_reset(engine); - waiters = drm_malloc_gfp(count, sizeof(*waiters), GFP_TEMPORARY); + waiters = kvmalloc_array(count, sizeof(*waiters), GFP_TEMPORARY); if (!waiters) goto out_engines; @@ -454,7 +454,7 @@ out_waiters: put_task_struct(waiters[n].tsk); } - drm_free_large(waiters); + kvfree(waiters); out_engines: mock_engine_flush(engine); return err; diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c index 68e509b3b9e4..465dab942afa 100644 --- a/drivers/gpu/drm/msm/msm_gem.c +++ b/drivers/gpu/drm/msm/msm_gem.c @@ -50,13 +50,13 @@ static struct page **get_pages_vram(struct drm_gem_object *obj, struct page **p; int ret, i; - p = drm_malloc_ab(npages, sizeof(struct page *)); + p = kvmalloc_array(npages, sizeof(struct page *), GFP_KERNEL); if (!p) return ERR_PTR(-ENOMEM); ret = drm_mm_insert_node(&priv->vram.mm, msm_obj->vram_node, npages); if (ret) { - drm_free_large(p); + kvfree(p); return ERR_PTR(ret); } @@ -127,7 +127,7 @@ static void put_pages(struct drm_gem_object *obj) drm_gem_put_pages(obj, msm_obj->pages, true, false); else { drm_mm_remove_node(msm_obj->vram_node); - drm_free_large(msm_obj->pages); + kvfree(msm_obj->pages); } msm_obj->pages = NULL; @@ -707,7 +707,7 @@ void msm_gem_free_object(struct drm_gem_object *obj) * ours, just free the array we allocated: */ if (msm_obj->pages) - drm_free_large(msm_obj->pages); + kvfree(msm_obj->pages); drm_prime_gem_destroy(obj, msm_obj->sgt); } else { @@ -863,7 +863,7 @@ struct drm_gem_object *msm_gem_import(struct drm_device *dev, msm_obj = to_msm_bo(obj); msm_obj->sgt = sgt; - msm_obj->pages = drm_malloc_ab(npages, sizeof(struct page *)); + msm_obj->pages = kvmalloc_array(npages, sizeof(struct page *), GFP_KERNEL); if (!msm_obj->pages) { ret = -ENOMEM; goto fail; diff --git a/drivers/gpu/drm/radeon/radeon_cs.c b/drivers/gpu/drm/radeon/radeon_cs.c index 3ac671f6c8e1..00b22af70f5c 100644 --- a/drivers/gpu/drm/radeon/radeon_cs.c +++ b/drivers/gpu/drm/radeon/radeon_cs.c @@ -87,7 +87,8 @@ static int radeon_cs_parser_relocs(struct radeon_cs_parser *p) p->dma_reloc_idx = 0; /* FIXME: we assume that each relocs use 4 dwords */ p->nrelocs = chunk->length_dw / 4; - p->relocs = drm_calloc_large(p->nrelocs, sizeof(struct radeon_bo_list)); + p->relocs = kvmalloc_array(p->nrelocs, sizeof(struct radeon_bo_list), + GFP_KERNEL | __GFP_ZERO); if (p->relocs == NULL) { return -ENOMEM; } @@ -341,7 +342,7 @@ int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data) continue; } - p->chunks[i].kdata = drm_malloc_ab(size, sizeof(uint32_t)); + p->chunks[i].kdata = kvmalloc_array(size, sizeof(uint32_t), GFP_KERNEL); size *= sizeof(uint32_t); if (p->chunks[i].kdata == NULL) { return -ENOMEM; @@ -440,10 +441,10 @@ static void radeon_cs_parser_fini(struct radeon_cs_parser *parser, int error, bo } } kfree(parser->track); - drm_free_large(parser->relocs); - drm_free_large(parser->vm_bos); + kvfree(parser->relocs); + kvfree(parser->vm_bos); for (i = 0; i < parser->nchunks; i++) - drm_free_large(parser->chunks[i].kdata); + kvfree(parser->chunks[i].kdata); kfree(parser->chunks); kfree(parser->chunks_array); radeon_ib_free(parser->rdev, &parser->ib); diff --git a/drivers/gpu/drm/radeon/radeon_gem.c b/drivers/gpu/drm/radeon/radeon_gem.c index dddb372de2b9..574bf7e6b118 100644 --- a/drivers/gpu/drm/radeon/radeon_gem.c +++ b/drivers/gpu/drm/radeon/radeon_gem.c @@ -587,7 +587,7 @@ error_unreserve: ttm_eu_backoff_reservation(&ticket, &list); error_free: - drm_free_large(vm_bos); + kvfree(vm_bos); if (r && r != -ERESTARTSYS) DRM_ERROR("Couldn't update BO_VA (%d)\n", r); diff --git a/drivers/gpu/drm/radeon/radeon_ring.c b/drivers/gpu/drm/radeon/radeon_ring.c index 8c7872339c2a..84802b201bef 100644 --- a/drivers/gpu/drm/radeon/radeon_ring.c +++ b/drivers/gpu/drm/radeon/radeon_ring.c @@ -314,7 +314,7 @@ unsigned radeon_ring_backup(struct radeon_device *rdev, struct radeon_ring *ring } /* and then save the content of the ring */ - *data = drm_malloc_ab(size, sizeof(uint32_t)); + *data = kvmalloc_array(size, sizeof(uint32_t), GFP_KERNEL); if (!*data) { mutex_unlock(&rdev->ring_lock); return 0; @@ -356,7 +356,7 @@ int radeon_ring_restore(struct radeon_device *rdev, struct radeon_ring *ring, } radeon_ring_unlock_commit(rdev, ring, false); - drm_free_large(data); + kvfree(data); return 0; } diff --git a/drivers/gpu/drm/radeon/radeon_vm.c b/drivers/gpu/drm/radeon/radeon_vm.c index a1358748cea5..5f68245579a3 100644 --- a/drivers/gpu/drm/radeon/radeon_vm.c +++ b/drivers/gpu/drm/radeon/radeon_vm.c @@ -132,8 +132,8 @@ struct radeon_bo_list *radeon_vm_get_bos(struct radeon_device *rdev, struct radeon_bo_list *list; unsigned i, idx; - list = drm_malloc_ab(vm->max_pde_used + 2, - sizeof(struct radeon_bo_list)); + list = kvmalloc_array(vm->max_pde_used + 2, + sizeof(struct radeon_bo_list), GFP_KERNEL); if (!list) return NULL; diff --git a/drivers/gpu/drm/ttm/ttm_tt.c b/drivers/gpu/drm/ttm/ttm_tt.c index 5260179d788a..8ebc8d3560c3 100644 --- a/drivers/gpu/drm/ttm/ttm_tt.c +++ b/drivers/gpu/drm/ttm/ttm_tt.c @@ -39,7 +39,6 @@ #include #include #include -#include #include #include #include @@ -53,14 +52,16 @@ */ static void ttm_tt_alloc_page_directory(struct ttm_tt *ttm) { - ttm->pages = drm_calloc_large(ttm->num_pages, sizeof(void*)); + ttm->pages = kvmalloc_array(ttm->num_pages, sizeof(void*), + GFP_KERNEL | __GFP_ZERO); } static void ttm_dma_tt_alloc_page_directory(struct ttm_dma_tt *ttm) { - ttm->ttm.pages = drm_calloc_large(ttm->ttm.num_pages, + ttm->ttm.pages = kvmalloc_array(ttm->ttm.num_pages, sizeof(*ttm->ttm.pages) + - sizeof(*ttm->dma_address)); + sizeof(*ttm->dma_address), + GFP_KERNEL | __GFP_ZERO); ttm->dma_address = (void *) (ttm->ttm.pages + ttm->ttm.num_pages); } @@ -208,7 +209,7 @@ EXPORT_SYMBOL(ttm_tt_init); void ttm_tt_fini(struct ttm_tt *ttm) { - drm_free_large(ttm->pages); + kvfree(ttm->pages); ttm->pages = NULL; } EXPORT_SYMBOL(ttm_tt_fini); @@ -243,7 +244,7 @@ void ttm_dma_tt_fini(struct ttm_dma_tt *ttm_dma) { struct ttm_tt *ttm = &ttm_dma->ttm; - drm_free_large(ttm->pages); + kvfree(ttm->pages); ttm->pages = NULL; ttm_dma->dma_address = NULL; } diff --git a/drivers/gpu/drm/udl/udl_dmabuf.c b/drivers/gpu/drm/udl/udl_dmabuf.c index ed0e636243b2..2e031a894813 100644 --- a/drivers/gpu/drm/udl/udl_dmabuf.c +++ b/drivers/gpu/drm/udl/udl_dmabuf.c @@ -228,7 +228,7 @@ static int udl_prime_create(struct drm_device *dev, return -ENOMEM; obj->sg = sg; - obj->pages = drm_malloc_ab(npages, sizeof(struct page *)); + obj->pages = kvmalloc_array(npages, sizeof(struct page *), GFP_KERNEL); if (obj->pages == NULL) { DRM_ERROR("obj pages is NULL %d\n", npages); return -ENOMEM; diff --git a/drivers/gpu/drm/udl/udl_gem.c b/drivers/gpu/drm/udl/udl_gem.c index 775c50e4f02c..db9ceceba30e 100644 --- a/drivers/gpu/drm/udl/udl_gem.c +++ b/drivers/gpu/drm/udl/udl_gem.c @@ -146,7 +146,7 @@ int udl_gem_get_pages(struct udl_gem_object *obj) void udl_gem_put_pages(struct udl_gem_object *obj) { if (obj->base.import_attach) { - drm_free_large(obj->pages); + kvfree(obj->pages); obj->pages = NULL; return; } diff --git a/drivers/gpu/drm/vc4/vc4_gem.c b/drivers/gpu/drm/vc4/vc4_gem.c index 735412e3725a..9dc7646d49ed 100644 --- a/drivers/gpu/drm/vc4/vc4_gem.c +++ b/drivers/gpu/drm/vc4/vc4_gem.c @@ -660,14 +660,15 @@ vc4_cl_lookup_bos(struct drm_device *dev, return -EINVAL; } - exec->bo = drm_calloc_large(exec->bo_count, - sizeof(struct drm_gem_cma_object *)); + exec->bo = kvmalloc_array(exec->bo_count, + sizeof(struct drm_gem_cma_object *), + GFP_KERNEL | __GFP_ZERO); if (!exec->bo) { DRM_ERROR("Failed to allocate validated BO pointers\n"); return -ENOMEM; } - handles = drm_malloc_ab(exec->bo_count, sizeof(uint32_t)); + handles = kvmalloc_array(exec->bo_count, sizeof(uint32_t), GFP_KERNEL); if (!handles) { ret = -ENOMEM; DRM_ERROR("Failed to allocate incoming GEM handles\n"); @@ -699,7 +700,7 @@ vc4_cl_lookup_bos(struct drm_device *dev, spin_unlock(&file_priv->table_lock); fail: - drm_free_large(handles); + kvfree(handles); return ret; } @@ -737,7 +738,7 @@ vc4_get_bcl(struct drm_device *dev, struct vc4_exec_info *exec) * read the contents back for validation, and I think the * bo->vaddr is uncached access. */ - temp = drm_malloc_ab(temp_size, 1); + temp = kvmalloc_array(temp_size, 1, GFP_KERNEL); if (!temp) { DRM_ERROR("Failed to allocate storage for copying " "in bin/render CLs.\n"); @@ -812,7 +813,7 @@ vc4_get_bcl(struct drm_device *dev, struct vc4_exec_info *exec) ret = vc4_wait_for_seqno(dev, exec->bin_dep_seqno, ~0ull, true); fail: - drm_free_large(temp); + kvfree(temp); return ret; } @@ -832,7 +833,7 @@ vc4_complete_exec(struct drm_device *dev, struct vc4_exec_info *exec) if (exec->bo) { for (i = 0; i < exec->bo_count; i++) drm_gem_object_unreference_unlocked(&exec->bo[i]->base); - drm_free_large(exec->bo); + kvfree(exec->bo); } while (!list_empty(&exec->unref_list)) { diff --git a/drivers/gpu/drm/vgem/vgem_drv.c b/drivers/gpu/drm/vgem/vgem_drv.c index 4b23ba049632..54ec94c5e9ac 100644 --- a/drivers/gpu/drm/vgem/vgem_drv.c +++ b/drivers/gpu/drm/vgem/vgem_drv.c @@ -51,7 +51,7 @@ static void vgem_gem_free_object(struct drm_gem_object *obj) { struct drm_vgem_gem_object *vgem_obj = to_vgem_bo(obj); - drm_free_large(vgem_obj->pages); + kvfree(vgem_obj->pages); if (obj->import_attach) drm_prime_gem_destroy(obj, vgem_obj->table); @@ -328,7 +328,7 @@ static struct drm_gem_object *vgem_prime_import_sg_table(struct drm_device *dev, npages = PAGE_ALIGN(attach->dmabuf->size) / PAGE_SIZE; obj->table = sg; - obj->pages = drm_malloc_ab(npages, sizeof(struct page *)); + obj->pages = kvmalloc_array(npages, sizeof(struct page *), GFP_KERNEL); if (!obj->pages) { __vgem_gem_destroy(obj); return ERR_PTR(-ENOMEM); diff --git a/drivers/gpu/drm/virtio/virtgpu_ioctl.c b/drivers/gpu/drm/virtio/virtgpu_ioctl.c index 06cb16d75f4b..b94bd5440e57 100644 --- a/drivers/gpu/drm/virtio/virtgpu_ioctl.c +++ b/drivers/gpu/drm/virtio/virtgpu_ioctl.c @@ -120,13 +120,14 @@ static int virtio_gpu_execbuffer_ioctl(struct drm_device *dev, void *data, INIT_LIST_HEAD(&validate_list); if (exbuf->num_bo_handles) { - bo_handles = drm_malloc_ab(exbuf->num_bo_handles, - sizeof(uint32_t)); - buflist = drm_calloc_large(exbuf->num_bo_handles, - sizeof(struct ttm_validate_buffer)); + bo_handles = kvmalloc_array(exbuf->num_bo_handles, + sizeof(uint32_t), GFP_KERNEL); + buflist = kvmalloc_array(exbuf->num_bo_handles, + sizeof(struct ttm_validate_buffer), + GFP_KERNEL | __GFP_ZERO); if (!bo_handles || !buflist) { - drm_free_large(bo_handles); - drm_free_large(buflist); + kvfree(bo_handles); + kvfree(buflist); return -ENOMEM; } @@ -134,16 +135,16 @@ static int virtio_gpu_execbuffer_ioctl(struct drm_device *dev, void *data, if (copy_from_user(bo_handles, user_bo_handles, exbuf->num_bo_handles * sizeof(uint32_t))) { ret = -EFAULT; - drm_free_large(bo_handles); - drm_free_large(buflist); + kvfree(bo_handles); + kvfree(buflist); return ret; } for (i = 0; i < exbuf->num_bo_handles; i++) { gobj = drm_gem_object_lookup(drm_file, bo_handles[i]); if (!gobj) { - drm_free_large(bo_handles); - drm_free_large(buflist); + kvfree(bo_handles); + kvfree(buflist); return -ENOENT; } @@ -152,7 +153,7 @@ static int virtio_gpu_execbuffer_ioctl(struct drm_device *dev, void *data, list_add(&buflist[i].head, &validate_list); } - drm_free_large(bo_handles); + kvfree(bo_handles); } ret = virtio_gpu_object_list_validate(&ticket, &validate_list); @@ -172,7 +173,7 @@ static int virtio_gpu_execbuffer_ioctl(struct drm_device *dev, void *data, /* fence the command bo */ virtio_gpu_unref_list(&validate_list); - drm_free_large(buflist); + kvfree(buflist); dma_fence_put(&fence->f); return 0; @@ -180,7 +181,7 @@ out_unresv: ttm_eu_backoff_reservation(&ticket, &validate_list); out_free: virtio_gpu_unref_list(&validate_list); - drm_free_large(buflist); + kvfree(buflist); return ret; } diff --git a/include/drm/drmP.h b/include/drm/drmP.h index 52085832f711..b9b5566acfe6 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -70,7 +70,6 @@ #include #include #include -#include #include #include #include -- cgit v1.2.3 From 032838f9cb4014af8a974374db9e2ce6f3aa8d3b Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 8 May 2017 12:33:48 -0700 Subject: drm/pl111: Register the clock divider and use it. This is required for the panel to work on bcm911360, where CLCDCLK is the fixed 200Mhz AXI41 clock. The rate set is still passed up to the CLCDCLK, for platforms that have a settable rate on that one. v2: Set SET_RATE_PARENT (caught by Linus Walleij), depend on COMMON_CLK. v3: Mark the clk_ops static (caught by Stephen). Signed-off-by: Eric Anholt Link: http://patchwork.freedesktop.org/patch/msgid/20170508193348.30236-1-eric@anholt.net Reviewed-by: Linus Walleij Reviewed-by: Stephen Boyd --- drivers/gpu/drm/pl111/Kconfig | 1 + drivers/gpu/drm/pl111/pl111_display.c | 162 ++++++++++++++++++++++++++++++---- drivers/gpu/drm/pl111/pl111_drm.h | 8 ++ drivers/gpu/drm/pl111/pl111_drv.c | 11 +-- include/linux/amba/clcd-regs.h | 5 ++ 5 files changed, 163 insertions(+), 24 deletions(-) (limited to 'include') diff --git a/drivers/gpu/drm/pl111/Kconfig b/drivers/gpu/drm/pl111/Kconfig index ede49efd531f..309f4fd52de7 100644 --- a/drivers/gpu/drm/pl111/Kconfig +++ b/drivers/gpu/drm/pl111/Kconfig @@ -2,6 +2,7 @@ config DRM_PL111 tristate "DRM Support for PL111 CLCD Controller" depends on DRM depends on ARM || ARM64 || COMPILE_TEST + depends on COMMON_CLK select DRM_KMS_HELPER select DRM_KMS_CMA_HELPER select DRM_GEM_CMA_HELPER diff --git a/drivers/gpu/drm/pl111/pl111_display.c b/drivers/gpu/drm/pl111/pl111_display.c index 39a5c33bce7d..fbf8fbec6c16 100644 --- a/drivers/gpu/drm/pl111/pl111_display.c +++ b/drivers/gpu/drm/pl111/pl111_display.c @@ -108,7 +108,7 @@ static void pl111_display_enable(struct drm_simple_display_pipe *pipe, u32 cntl; u32 ppl, hsw, hfp, hbp; u32 lpp, vsw, vfp, vbp; - u32 cpl; + u32 cpl, tim2; int ret; ret = clk_set_rate(priv->clk, mode->clock * 1000); @@ -142,20 +142,28 @@ static void pl111_display_enable(struct drm_simple_display_pipe *pipe, (vfp << 16) | (vbp << 24), priv->regs + CLCD_TIM1); - /* XXX: We currently always use CLCDCLK with no divisor. We - * could probably reduce power consumption by using HCLK - * (apb_pclk) with a divisor when it gets us near our target - * pixel clock. - */ - writel(((mode->flags & DRM_MODE_FLAG_NHSYNC) ? TIM2_IHS : 0) | - ((mode->flags & DRM_MODE_FLAG_NVSYNC) ? TIM2_IVS : 0) | - ((connector->display_info.bus_flags & - DRM_BUS_FLAG_DE_LOW) ? TIM2_IOE : 0) | - ((connector->display_info.bus_flags & - DRM_BUS_FLAG_PIXDATA_NEGEDGE) ? TIM2_IPC : 0) | - TIM2_BCD | - (cpl << 16), - priv->regs + CLCD_TIM2); + + spin_lock(&priv->tim2_lock); + + tim2 = readl(priv->regs + CLCD_TIM2); + tim2 &= (TIM2_BCD | TIM2_PCD_LO_MASK | TIM2_PCD_HI_MASK); + + if (mode->flags & DRM_MODE_FLAG_NHSYNC) + tim2 |= TIM2_IHS; + + if (mode->flags & DRM_MODE_FLAG_NVSYNC) + tim2 |= TIM2_IVS; + + if (connector->display_info.bus_flags & DRM_BUS_FLAG_DE_LOW) + tim2 |= TIM2_IOE; + + if (connector->display_info.bus_flags & DRM_BUS_FLAG_PIXDATA_NEGEDGE) + tim2 |= TIM2_IPC; + + tim2 |= cpl << 16; + writel(tim2, priv->regs + CLCD_TIM2); + spin_unlock(&priv->tim2_lock); + writel(0, priv->regs + CLCD_TIM3); drm_panel_prepare(priv->connector.panel); @@ -288,6 +296,126 @@ const struct drm_simple_display_pipe_funcs pl111_display_funcs = { .prepare_fb = pl111_display_prepare_fb, }; +static int pl111_clk_div_choose_div(struct clk_hw *hw, unsigned long rate, + unsigned long *prate, bool set_parent) +{ + int best_div = 1, div; + struct clk_hw *parent = clk_hw_get_parent(hw); + unsigned long best_prate = 0; + unsigned long best_diff = ~0ul; + int max_div = (1 << (TIM2_PCD_LO_BITS + TIM2_PCD_HI_BITS)) - 1; + + for (div = 1; div < max_div; div++) { + unsigned long this_prate, div_rate, diff; + + if (set_parent) + this_prate = clk_hw_round_rate(parent, rate * div); + else + this_prate = *prate; + div_rate = DIV_ROUND_UP_ULL(this_prate, div); + diff = abs(rate - div_rate); + + if (diff < best_diff) { + best_div = div; + best_diff = diff; + best_prate = this_prate; + } + } + + *prate = best_prate; + return best_div; +} + +static long pl111_clk_div_round_rate(struct clk_hw *hw, unsigned long rate, + unsigned long *prate) +{ + int div = pl111_clk_div_choose_div(hw, rate, prate, true); + + return DIV_ROUND_UP_ULL(*prate, div); +} + +static unsigned long pl111_clk_div_recalc_rate(struct clk_hw *hw, + unsigned long prate) +{ + struct pl111_drm_dev_private *priv = + container_of(hw, struct pl111_drm_dev_private, clk_div); + u32 tim2 = readl(priv->regs + CLCD_TIM2); + int div; + + if (tim2 & TIM2_BCD) + return prate; + + div = tim2 & TIM2_PCD_LO_MASK; + div |= (tim2 & TIM2_PCD_HI_MASK) >> + (TIM2_PCD_HI_SHIFT - TIM2_PCD_LO_BITS); + div += 2; + + return DIV_ROUND_UP_ULL(prate, div); +} + +static int pl111_clk_div_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long prate) +{ + struct pl111_drm_dev_private *priv = + container_of(hw, struct pl111_drm_dev_private, clk_div); + int div = pl111_clk_div_choose_div(hw, rate, &prate, false); + u32 tim2; + + spin_lock(&priv->tim2_lock); + tim2 = readl(priv->regs + CLCD_TIM2); + tim2 &= ~(TIM2_BCD | TIM2_PCD_LO_MASK | TIM2_PCD_HI_MASK); + + if (div == 1) { + tim2 |= TIM2_BCD; + } else { + div -= 2; + tim2 |= div & TIM2_PCD_LO_MASK; + tim2 |= (div >> TIM2_PCD_LO_BITS) << TIM2_PCD_HI_SHIFT; + } + + writel(tim2, priv->regs + CLCD_TIM2); + spin_unlock(&priv->tim2_lock); + + return 0; +} + +static const struct clk_ops pl111_clk_div_ops = { + .recalc_rate = pl111_clk_div_recalc_rate, + .round_rate = pl111_clk_div_round_rate, + .set_rate = pl111_clk_div_set_rate, +}; + +static int +pl111_init_clock_divider(struct drm_device *drm) +{ + struct pl111_drm_dev_private *priv = drm->dev_private; + struct clk *parent = devm_clk_get(drm->dev, "clcdclk"); + struct clk_hw *div = &priv->clk_div; + const char *parent_name; + struct clk_init_data init = { + .name = "pl111_div", + .ops = &pl111_clk_div_ops, + .parent_names = &parent_name, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }; + int ret; + + if (IS_ERR(parent)) { + dev_err(drm->dev, "CLCD: unable to get clcdclk.\n"); + return PTR_ERR(parent); + } + parent_name = __clk_get_name(parent); + + spin_lock_init(&priv->tim2_lock); + div->init = &init; + + ret = devm_clk_hw_register(drm->dev, div); + + priv->clk = div->clk; + return ret; +} + int pl111_display_init(struct drm_device *drm) { struct pl111_drm_dev_private *priv = drm->dev_private; @@ -333,6 +461,10 @@ int pl111_display_init(struct drm_device *drm) return -EINVAL; } + ret = pl111_init_clock_divider(drm); + if (ret) + return ret; + ret = drm_simple_display_pipe_init(drm, &priv->pipe, &pl111_display_funcs, formats, ARRAY_SIZE(formats), diff --git a/drivers/gpu/drm/pl111/pl111_drm.h b/drivers/gpu/drm/pl111/pl111_drm.h index f381593921b7..4162c6aa5dbb 100644 --- a/drivers/gpu/drm/pl111/pl111_drm.h +++ b/drivers/gpu/drm/pl111/pl111_drm.h @@ -21,6 +21,7 @@ #include #include +#include #define CLCD_IRQ_NEXTBASE_UPDATE BIT(2) @@ -37,7 +38,14 @@ struct pl111_drm_dev_private { struct drm_fbdev_cma *fbdev; void *regs; + /* The pixel clock (a reference to our clock divider off of CLCDCLK). */ struct clk *clk; + /* pl111's internal clock divider. */ + struct clk_hw clk_div; + /* Lock to sync access to CLCD_TIM2 between the common clock + * subsystem and pl111_display_enable(). + */ + spinlock_t tim2_lock; }; #define to_pl111_connector(x) \ diff --git a/drivers/gpu/drm/pl111/pl111_drv.c b/drivers/gpu/drm/pl111/pl111_drv.c index 936403f65508..9d1467492cb9 100644 --- a/drivers/gpu/drm/pl111/pl111_drv.c +++ b/drivers/gpu/drm/pl111/pl111_drv.c @@ -50,8 +50,8 @@ * - Read back hardware state at boot to skip reprogramming the * hardware when doing a no-op modeset. * - * - Use the internal clock divisor to reduce power consumption by - * using HCLK (apb_pclk) when appropriate. + * - Use the CLKSEL bit to support switching between the two external + * clock parents. */ #include @@ -195,13 +195,6 @@ static int pl111_amba_probe(struct amba_device *amba_dev, priv->drm = drm; drm->dev_private = priv; - priv->clk = devm_clk_get(dev, "clcdclk"); - if (IS_ERR(priv->clk)) { - dev_err(dev, "CLCD: unable to get clk.\n"); - ret = PTR_ERR(priv->clk); - goto dev_unref; - } - priv->regs = devm_ioremap_resource(dev, &amba_dev->res); if (!priv->regs) { dev_err(dev, "%s failed mmio\n", __func__); diff --git a/include/linux/amba/clcd-regs.h b/include/linux/amba/clcd-regs.h index 69c0e2143003..516a6fda83c5 100644 --- a/include/linux/amba/clcd-regs.h +++ b/include/linux/amba/clcd-regs.h @@ -39,12 +39,17 @@ #define CLCD_PALL 0x00000200 #define CLCD_PALETTE 0x00000200 +#define TIM2_PCD_LO_MASK GENMASK(4, 0) +#define TIM2_PCD_LO_BITS 5 #define TIM2_CLKSEL (1 << 5) #define TIM2_IVS (1 << 11) #define TIM2_IHS (1 << 12) #define TIM2_IPC (1 << 13) #define TIM2_IOE (1 << 14) #define TIM2_BCD (1 << 26) +#define TIM2_PCD_HI_MASK GENMASK(31, 27) +#define TIM2_PCD_HI_BITS 5 +#define TIM2_PCD_HI_SHIFT 27 #define CNTL_LCDEN (1 << 0) #define CNTL_LCDBPP1 (0 << 1) -- cgit v1.2.3 From c2c446ad29437bb92b157423c632286608ebd3ec Mon Sep 17 00:00:00 2001 From: Robert Foss Date: Fri, 19 May 2017 16:50:17 -0400 Subject: drm: Add DRM_MODE_ROTATE_ and DRM_MODE_REFLECT_ to UAPI Add DRM_MODE_ROTATE_ and DRM_MODE_REFLECT_ defines to the UAPI as a convenience. Ideally the DRM_ROTATE_ and DRM_REFLECT_ property ids are looked up through the atomic API, but realizing that userspace is likely to take shortcuts and assume that the enum values are what is sent over the wire. As a result these defines are provided purely as a convenience to userspace applications. Changes since v3: - Switched away from past tense in comments - Add define name change to previously mis-spelled DRM_REFLECT_X comment - Improved the comment for the DRM_MODE_REFLECT_ comment Changes since v2: - Changed define prefix from DRM_MODE_PROP_ to DRM_MODE_ - Fix compilation errors - Changed comment formatting - Deduplicated comment lines - Clarified DRM_MODE_PROP_REFLECT_ comment Changes since v1: - Moved defines from drm.h to drm_mode.h - Changed define prefix from DRM_ to DRM_MODE_PROP_ - Updated uses of the defines to the new prefix - Removed include from drm_rect.c - Stopped using the BIT() macro Signed-off-by: Robert Foss Reviewed-by: Emil Velikov Reviewed-by: Sinclair Yeh Acked-by: Liviu Dudau Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/20170519205017.23307-2-robert.foss@collabora.com --- drivers/gpu/drm/arm/malidp_drv.h | 2 +- drivers/gpu/drm/arm/malidp_planes.c | 18 ++++----- drivers/gpu/drm/armada/armada_overlay.c | 2 +- drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c | 20 +++++----- drivers/gpu/drm/drm_atomic.c | 2 +- drivers/gpu/drm/drm_atomic_helper.c | 2 +- drivers/gpu/drm/drm_blend.c | 45 +++++++++++----------- drivers/gpu/drm/drm_fb_helper.c | 4 +- drivers/gpu/drm/drm_plane_helper.c | 2 +- drivers/gpu/drm/drm_rect.c | 36 +++++++++--------- drivers/gpu/drm/i915/i915_debugfs.c | 14 +++---- drivers/gpu/drm/i915/intel_atomic_plane.c | 6 +-- drivers/gpu/drm/i915/intel_display.c | 50 ++++++++++++------------- drivers/gpu/drm/i915/intel_fbc.c | 2 +- drivers/gpu/drm/i915/intel_fbdev.c | 2 +- drivers/gpu/drm/i915/intel_sprite.c | 20 +++++----- drivers/gpu/drm/imx/ipuv3-plane.c | 2 +- drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c | 30 +++++++-------- drivers/gpu/drm/nouveau/nv50_display.c | 2 +- drivers/gpu/drm/omapdrm/omap_drv.c | 4 +- drivers/gpu/drm/omapdrm/omap_fb.c | 18 ++++----- drivers/gpu/drm/omapdrm/omap_plane.c | 16 ++++---- drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | 4 +- include/drm/drm_blend.h | 21 +---------- include/uapi/drm/drm_mode.h | 49 +++++++++++++++++++++++- 25 files changed, 202 insertions(+), 171 deletions(-) (limited to 'include') diff --git a/drivers/gpu/drm/arm/malidp_drv.h b/drivers/gpu/drm/arm/malidp_drv.h index 040311ffcaec..2e2033140efc 100644 --- a/drivers/gpu/drm/arm/malidp_drv.h +++ b/drivers/gpu/drm/arm/malidp_drv.h @@ -65,6 +65,6 @@ void malidp_de_planes_destroy(struct drm_device *drm); int malidp_crtc_init(struct drm_device *drm); /* often used combination of rotational bits */ -#define MALIDP_ROTATED_MASK (DRM_ROTATE_90 | DRM_ROTATE_270) +#define MALIDP_ROTATED_MASK (DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_270) #endif /* __MALIDP_DRV_H__ */ diff --git a/drivers/gpu/drm/arm/malidp_planes.c b/drivers/gpu/drm/arm/malidp_planes.c index 814fda23cead..063a8d2b0be3 100644 --- a/drivers/gpu/drm/arm/malidp_planes.c +++ b/drivers/gpu/drm/arm/malidp_planes.c @@ -80,7 +80,7 @@ static void malidp_plane_reset(struct drm_plane *plane) state = kzalloc(sizeof(*state), GFP_KERNEL); if (state) { state->base.plane = plane; - state->base.rotation = DRM_ROTATE_0; + state->base.rotation = DRM_MODE_ROTATE_0; plane->state = &state->base; } } @@ -221,7 +221,7 @@ static int malidp_de_plane_check(struct drm_plane *plane, return ret; /* packed RGB888 / BGR888 can't be rotated or flipped */ - if (state->rotation != DRM_ROTATE_0 && + if (state->rotation != DRM_MODE_ROTATE_0 && (fb->format->format == DRM_FORMAT_RGB888 || fb->format->format == DRM_FORMAT_BGR888)) return -EINVAL; @@ -315,12 +315,12 @@ static void malidp_de_plane_update(struct drm_plane *plane, val &= ~LAYER_ROT_MASK; /* setup the rotation and axis flip bits */ - if (plane->state->rotation & DRM_ROTATE_MASK) - val |= ilog2(plane->state->rotation & DRM_ROTATE_MASK) << + if (plane->state->rotation & DRM_MODE_ROTATE_MASK) + val |= ilog2(plane->state->rotation & DRM_MODE_ROTATE_MASK) << LAYER_ROT_OFFSET; - if (plane->state->rotation & DRM_REFLECT_X) + if (plane->state->rotation & DRM_MODE_REFLECT_X) val |= LAYER_H_FLIP; - if (plane->state->rotation & DRM_REFLECT_Y) + if (plane->state->rotation & DRM_MODE_REFLECT_Y) val |= LAYER_V_FLIP; /* @@ -370,8 +370,8 @@ int malidp_de_planes_init(struct drm_device *drm) struct malidp_plane *plane = NULL; enum drm_plane_type plane_type; unsigned long crtcs = 1 << drm->mode_config.num_crtc; - unsigned long flags = DRM_ROTATE_0 | DRM_ROTATE_90 | DRM_ROTATE_180 | - DRM_ROTATE_270 | DRM_REFLECT_X | DRM_REFLECT_Y; + unsigned long flags = DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_180 | + DRM_MODE_ROTATE_270 | DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y; u32 *formats; int ret, i, j, n; @@ -420,7 +420,7 @@ int malidp_de_planes_init(struct drm_device *drm) continue; } - drm_plane_create_rotation_property(&plane->base, DRM_ROTATE_0, flags); + drm_plane_create_rotation_property(&plane->base, DRM_MODE_ROTATE_0, flags); malidp_hw_write(malidp->dev, MALIDP_ALPHA_LUT, plane->layer->base + MALIDP_LAYER_COMPOSE); } diff --git a/drivers/gpu/drm/armada/armada_overlay.c b/drivers/gpu/drm/armada/armada_overlay.c index 424e465ff407..e9a29df4b443 100644 --- a/drivers/gpu/drm/armada/armada_overlay.c +++ b/drivers/gpu/drm/armada/armada_overlay.c @@ -125,7 +125,7 @@ armada_ovl_plane_update(struct drm_plane *plane, struct drm_crtc *crtc, src_x, src_y, src_w, src_h); ret = drm_plane_helper_check_update(plane, crtc, fb, &src, &dest, &clip, - DRM_ROTATE_0, + DRM_MODE_ROTATE_0, 0, INT_MAX, true, false, &visible); if (ret) return ret; diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c index 29cc10d053eb..1124200bb280 100644 --- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c +++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c @@ -678,8 +678,8 @@ static int atmel_hlcdc_plane_atomic_check(struct drm_plane *p, if (!state->bpp[i]) return -EINVAL; - switch (state->base.rotation & DRM_ROTATE_MASK) { - case DRM_ROTATE_90: + switch (state->base.rotation & DRM_MODE_ROTATE_MASK) { + case DRM_MODE_ROTATE_90: offset = ((y_offset + state->src_y + patched_src_w - 1) / ydiv) * fb->pitches[i]; offset += ((x_offset + state->src_x) / xdiv) * @@ -688,7 +688,7 @@ static int atmel_hlcdc_plane_atomic_check(struct drm_plane *p, fb->pitches[i]; state->pstride[i] = -fb->pitches[i] - state->bpp[i]; break; - case DRM_ROTATE_180: + case DRM_MODE_ROTATE_180: offset = ((y_offset + state->src_y + patched_src_h - 1) / ydiv) * fb->pitches[i]; offset += ((x_offset + state->src_x + patched_src_w - 1) / @@ -697,7 +697,7 @@ static int atmel_hlcdc_plane_atomic_check(struct drm_plane *p, state->bpp[i]) - fb->pitches[i]; state->pstride[i] = -2 * state->bpp[i]; break; - case DRM_ROTATE_270: + case DRM_MODE_ROTATE_270: offset = ((y_offset + state->src_y) / ydiv) * fb->pitches[i]; offset += ((x_offset + state->src_x + patched_src_h - 1) / @@ -707,7 +707,7 @@ static int atmel_hlcdc_plane_atomic_check(struct drm_plane *p, (2 * state->bpp[i]); state->pstride[i] = fb->pitches[i] - state->bpp[i]; break; - case DRM_ROTATE_0: + case DRM_MODE_ROTATE_0: default: offset = ((y_offset + state->src_y) / ydiv) * fb->pitches[i]; @@ -864,11 +864,11 @@ static int atmel_hlcdc_plane_init_properties(struct atmel_hlcdc_plane *plane, int ret; ret = drm_plane_create_rotation_property(&plane->base, - DRM_ROTATE_0, - DRM_ROTATE_0 | - DRM_ROTATE_90 | - DRM_ROTATE_180 | - DRM_ROTATE_270); + DRM_MODE_ROTATE_0, + DRM_MODE_ROTATE_0 | + DRM_MODE_ROTATE_90 | + DRM_MODE_ROTATE_180 | + DRM_MODE_ROTATE_270); if (ret) return ret; } diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index cdec19a86af3..e1637011e18a 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c @@ -781,7 +781,7 @@ int drm_atomic_plane_set_property(struct drm_plane *plane, } else if (property == config->prop_src_h) { state->src_h = val; } else if (property == plane->rotation_property) { - if (!is_power_of_2(val & DRM_ROTATE_MASK)) + if (!is_power_of_2(val & DRM_MODE_ROTATE_MASK)) return -EINVAL; state->rotation = val; } else if (property == plane->zpos_property) { diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c index 6426339427a4..636e561486a8 100644 --- a/drivers/gpu/drm/drm_atomic_helper.c +++ b/drivers/gpu/drm/drm_atomic_helper.c @@ -3225,7 +3225,7 @@ void drm_atomic_helper_plane_reset(struct drm_plane *plane) if (plane->state) { plane->state->plane = plane; - plane->state->rotation = DRM_ROTATE_0; + plane->state->rotation = DRM_MODE_ROTATE_0; } } EXPORT_SYMBOL(drm_atomic_helper_plane_reset); diff --git a/drivers/gpu/drm/drm_blend.c b/drivers/gpu/drm/drm_blend.c index dee67ef6c670..db6aeec50b82 100644 --- a/drivers/gpu/drm/drm_blend.c +++ b/drivers/gpu/drm/drm_blend.c @@ -119,17 +119,17 @@ * drm_property_create_bitmask()) called "rotation" and has the following * bitmask enumaration values: * - * DRM_ROTATE_0: + * DRM_MODE_ROTATE_0: * "rotate-0" - * DRM_ROTATE_90: + * DRM_MODE_ROTATE_90: * "rotate-90" - * DRM_ROTATE_180: + * DRM_MODE_ROTATE_180: * "rotate-180" - * DRM_ROTATE_270: + * DRM_MODE_ROTATE_270: * "rotate-270" - * DRM_REFLECT_X: + * DRM_MODE_REFLECT_X: * "reflect-x" - * DRM_REFLECT_Y: + * DRM_MODE_REFLECT_Y: * "reflect-y" * * Rotation is the specified amount in degrees in counter clockwise direction, @@ -142,17 +142,17 @@ int drm_plane_create_rotation_property(struct drm_plane *plane, unsigned int supported_rotations) { static const struct drm_prop_enum_list props[] = { - { __builtin_ffs(DRM_ROTATE_0) - 1, "rotate-0" }, - { __builtin_ffs(DRM_ROTATE_90) - 1, "rotate-90" }, - { __builtin_ffs(DRM_ROTATE_180) - 1, "rotate-180" }, - { __builtin_ffs(DRM_ROTATE_270) - 1, "rotate-270" }, - { __builtin_ffs(DRM_REFLECT_X) - 1, "reflect-x" }, - { __builtin_ffs(DRM_REFLECT_Y) - 1, "reflect-y" }, + { __builtin_ffs(DRM_MODE_ROTATE_0) - 1, "rotate-0" }, + { __builtin_ffs(DRM_MODE_ROTATE_90) - 1, "rotate-90" }, + { __builtin_ffs(DRM_MODE_ROTATE_180) - 1, "rotate-180" }, + { __builtin_ffs(DRM_MODE_ROTATE_270) - 1, "rotate-270" }, + { __builtin_ffs(DRM_MODE_REFLECT_X) - 1, "reflect-x" }, + { __builtin_ffs(DRM_MODE_REFLECT_Y) - 1, "reflect-y" }, }; struct drm_property *prop; - WARN_ON((supported_rotations & DRM_ROTATE_MASK) == 0); - WARN_ON(!is_power_of_2(rotation & DRM_ROTATE_MASK)); + WARN_ON((supported_rotations & DRM_MODE_ROTATE_MASK) == 0); + WARN_ON(!is_power_of_2(rotation & DRM_MODE_ROTATE_MASK)); WARN_ON(rotation & ~supported_rotations); prop = drm_property_create_bitmask(plane->dev, 0, "rotation", @@ -178,14 +178,14 @@ EXPORT_SYMBOL(drm_plane_create_rotation_property); * @supported_rotations: Supported rotations * * Attempt to simplify the rotation to a form that is supported. - * Eg. if the hardware supports everything except DRM_REFLECT_X + * Eg. if the hardware supports everything except DRM_MODE_REFLECT_X * one could call this function like this: * - * drm_rotation_simplify(rotation, DRM_ROTATE_0 | - * DRM_ROTATE_90 | DRM_ROTATE_180 | - * DRM_ROTATE_270 | DRM_REFLECT_Y); + * drm_rotation_simplify(rotation, DRM_MODE_ROTATE_0 | + * DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_180 | + * DRM_MODE_ROTATE_270 | DRM_MODE_REFLECT_Y); * - * to eliminate the DRM_ROTATE_X flag. Depending on what kind of + * to eliminate the DRM_MODE_ROTATE_X flag. Depending on what kind of * transforms the hardware supports, this function may not * be able to produce a supported transform, so the caller should * check the result afterwards. @@ -194,9 +194,10 @@ unsigned int drm_rotation_simplify(unsigned int rotation, unsigned int supported_rotations) { if (rotation & ~supported_rotations) { - rotation ^= DRM_REFLECT_X | DRM_REFLECT_Y; - rotation = (rotation & DRM_REFLECT_MASK) | - BIT((ffs(rotation & DRM_ROTATE_MASK) + 1) % 4); + rotation ^= DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y; + rotation = (rotation & DRM_MODE_REFLECT_MASK) | + BIT((ffs(rotation & DRM_MODE_ROTATE_MASK) + 1) + % 4); } return rotation; diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index 1f178b878e42..574af01d3ce9 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -378,7 +378,7 @@ retry: goto fail; } - plane_state->rotation = DRM_ROTATE_0; + plane_state->rotation = DRM_MODE_ROTATE_0; plane->old_fb = plane->fb; plane_mask |= 1 << drm_plane_index(plane); @@ -431,7 +431,7 @@ static int restore_fbdev_mode_legacy(struct drm_fb_helper *fb_helper) if (plane->rotation_property) drm_mode_plane_set_obj_prop(plane, plane->rotation_property, - DRM_ROTATE_0); + DRM_MODE_ROTATE_0); } for (i = 0; i < fb_helper->crtc_count; i++) { diff --git a/drivers/gpu/drm/drm_plane_helper.c b/drivers/gpu/drm/drm_plane_helper.c index 2c27f6f5a668..06aee1741e96 100644 --- a/drivers/gpu/drm/drm_plane_helper.c +++ b/drivers/gpu/drm/drm_plane_helper.c @@ -336,7 +336,7 @@ int drm_primary_helper_update(struct drm_plane *plane, struct drm_crtc *crtc, ret = drm_plane_helper_check_update(plane, crtc, fb, &src, &dest, &clip, - DRM_ROTATE_0, + DRM_MODE_ROTATE_0, DRM_PLANE_HELPER_NO_SCALING, DRM_PLANE_HELPER_NO_SCALING, false, false, &visible); diff --git a/drivers/gpu/drm/drm_rect.c b/drivers/gpu/drm/drm_rect.c index bc5575960ebc..9817c1445ba9 100644 --- a/drivers/gpu/drm/drm_rect.c +++ b/drivers/gpu/drm/drm_rect.c @@ -310,38 +310,38 @@ void drm_rect_rotate(struct drm_rect *r, { struct drm_rect tmp; - if (rotation & (DRM_REFLECT_X | DRM_REFLECT_Y)) { + if (rotation & (DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y)) { tmp = *r; - if (rotation & DRM_REFLECT_X) { + if (rotation & DRM_MODE_REFLECT_X) { r->x1 = width - tmp.x2; r->x2 = width - tmp.x1; } - if (rotation & DRM_REFLECT_Y) { + if (rotation & DRM_MODE_REFLECT_Y) { r->y1 = height - tmp.y2; r->y2 = height - tmp.y1; } } - switch (rotation & DRM_ROTATE_MASK) { - case DRM_ROTATE_0: + switch (rotation & DRM_MODE_ROTATE_MASK) { + case DRM_MODE_ROTATE_0: break; - case DRM_ROTATE_90: + case DRM_MODE_ROTATE_90: tmp = *r; r->x1 = tmp.y1; r->x2 = tmp.y2; r->y1 = width - tmp.x2; r->y2 = width - tmp.x1; break; - case DRM_ROTATE_180: + case DRM_MODE_ROTATE_180: tmp = *r; r->x1 = width - tmp.x2; r->x2 = width - tmp.x1; r->y1 = height - tmp.y2; r->y2 = height - tmp.y1; break; - case DRM_ROTATE_270: + case DRM_MODE_ROTATE_270: tmp = *r; r->x1 = height - tmp.y2; r->x2 = height - tmp.y1; @@ -373,8 +373,8 @@ EXPORT_SYMBOL(drm_rect_rotate); * them when doing a rotatation and its inverse. * That is, if you do :: * - * drm_rotate(&r, width, height, rotation); - * drm_rotate_inv(&r, width, height, rotation); + * DRM_MODE_PROP_ROTATE(&r, width, height, rotation); + * DRM_MODE_ROTATE_inv(&r, width, height, rotation); * * you will always get back the original rectangle. */ @@ -384,24 +384,24 @@ void drm_rect_rotate_inv(struct drm_rect *r, { struct drm_rect tmp; - switch (rotation & DRM_ROTATE_MASK) { - case DRM_ROTATE_0: + switch (rotation & DRM_MODE_ROTATE_MASK) { + case DRM_MODE_ROTATE_0: break; - case DRM_ROTATE_90: + case DRM_MODE_ROTATE_90: tmp = *r; r->x1 = width - tmp.y2; r->x2 = width - tmp.y1; r->y1 = tmp.x1; r->y2 = tmp.x2; break; - case DRM_ROTATE_180: + case DRM_MODE_ROTATE_180: tmp = *r; r->x1 = width - tmp.x2; r->x2 = width - tmp.x1; r->y1 = height - tmp.y2; r->y2 = height - tmp.y1; break; - case DRM_ROTATE_270: + case DRM_MODE_ROTATE_270: tmp = *r; r->x1 = tmp.y1; r->x2 = tmp.y2; @@ -412,15 +412,15 @@ void drm_rect_rotate_inv(struct drm_rect *r, break; } - if (rotation & (DRM_REFLECT_X | DRM_REFLECT_Y)) { + if (rotation & (DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y)) { tmp = *r; - if (rotation & DRM_REFLECT_X) { + if (rotation & DRM_MODE_REFLECT_X) { r->x1 = width - tmp.x2; r->x2 = width - tmp.x1; } - if (rotation & DRM_REFLECT_Y) { + if (rotation & DRM_MODE_REFLECT_Y) { r->y1 = height - tmp.y2; r->y2 = height - tmp.y1; } diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 07f87985ea0b..1c66108f4333 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -3095,17 +3095,17 @@ static const char *plane_rotation(unsigned int rotation) { static char buf[48]; /* - * According to doc only one DRM_ROTATE_ is allowed but this + * According to doc only one DRM_MODE_ROTATE_ is allowed but this * will print them all to visualize if the values are misused */ snprintf(buf, sizeof(buf), "%s%s%s%s%s%s(0x%08x)", - (rotation & DRM_ROTATE_0) ? "0 " : "", - (rotation & DRM_ROTATE_90) ? "90 " : "", - (rotation & DRM_ROTATE_180) ? "180 " : "", - (rotation & DRM_ROTATE_270) ? "270 " : "", - (rotation & DRM_REFLECT_X) ? "FLIPX " : "", - (rotation & DRM_REFLECT_Y) ? "FLIPY " : "", + (rotation & DRM_MODE_ROTATE_0) ? "0 " : "", + (rotation & DRM_MODE_ROTATE_90) ? "90 " : "", + (rotation & DRM_MODE_ROTATE_180) ? "180 " : "", + (rotation & DRM_MODE_ROTATE_270) ? "270 " : "", + (rotation & DRM_MODE_REFLECT_X) ? "FLIPX " : "", + (rotation & DRM_MODE_REFLECT_Y) ? "FLIPY " : "", rotation); return buf; diff --git a/drivers/gpu/drm/i915/intel_atomic_plane.c b/drivers/gpu/drm/i915/intel_atomic_plane.c index cfb47293fd53..a40c82c65450 100644 --- a/drivers/gpu/drm/i915/intel_atomic_plane.c +++ b/drivers/gpu/drm/i915/intel_atomic_plane.c @@ -55,7 +55,7 @@ intel_create_plane_state(struct drm_plane *plane) return NULL; state->base.plane = plane; - state->base.rotation = DRM_ROTATE_0; + state->base.rotation = DRM_MODE_ROTATE_0; state->ckey.flags = I915_SET_COLORKEY_NONE; return state; @@ -178,8 +178,8 @@ int intel_plane_atomic_check_with_state(struct intel_crtc_state *crtc_state, /* CHV ignores the mirror bit when the rotate bit is set :( */ if (IS_CHERRYVIEW(dev_priv) && - state->rotation & DRM_ROTATE_180 && - state->rotation & DRM_REFLECT_X) { + state->rotation & DRM_MODE_ROTATE_180 && + state->rotation & DRM_MODE_REFLECT_X) { DRM_DEBUG_KMS("Cannot rotate and reflect at the same time\n"); return -EINVAL; } diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 2f2bb623cf5f..6a037b856d96 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -2468,7 +2468,7 @@ intel_fill_fb_info(struct drm_i915_private *dev_priv, offset = _intel_compute_tile_offset(dev_priv, &x, &y, fb, i, fb->pitches[i], - DRM_ROTATE_0, tile_size); + DRM_MODE_ROTATE_0, tile_size); offset /= tile_size; if (fb->modifier != DRM_FORMAT_MOD_LINEAR) { @@ -2503,7 +2503,7 @@ intel_fill_fb_info(struct drm_i915_private *dev_priv, drm_rect_rotate(&r, rot_info->plane[i].width * tile_width, rot_info->plane[i].height * tile_height, - DRM_ROTATE_270); + DRM_MODE_ROTATE_270); x = r.x1; y = r.y1; @@ -2939,7 +2939,7 @@ int skl_check_plane_surface(struct intel_plane_state *plane_state) if (drm_rotation_90_or_270(rotation)) drm_rect_rotate(&plane_state->base.src, fb->width << 16, fb->height << 16, - DRM_ROTATE_270); + DRM_MODE_ROTATE_270); /* * Handle the AUX surface first since @@ -3017,10 +3017,10 @@ static u32 i9xx_plane_ctl(const struct intel_crtc_state *crtc_state, fb->modifier == I915_FORMAT_MOD_X_TILED) dspcntr |= DISPPLANE_TILED; - if (rotation & DRM_ROTATE_180) + if (rotation & DRM_MODE_ROTATE_180) dspcntr |= DISPPLANE_ROTATE_180; - if (rotation & DRM_REFLECT_X) + if (rotation & DRM_MODE_REFLECT_X) dspcntr |= DISPPLANE_MIRROR; return dspcntr; @@ -3048,10 +3048,10 @@ int i9xx_check_plane_surface(struct intel_plane_state *plane_state) int src_w = drm_rect_width(&plane_state->base.src) >> 16; int src_h = drm_rect_height(&plane_state->base.src) >> 16; - if (rotation & DRM_ROTATE_180) { + if (rotation & DRM_MODE_ROTATE_180) { src_x += src_w - 1; src_y += src_h - 1; - } else if (rotation & DRM_REFLECT_X) { + } else if (rotation & DRM_MODE_REFLECT_X) { src_x += src_w - 1; } } @@ -3271,17 +3271,17 @@ static u32 skl_plane_ctl_tiling(uint64_t fb_modifier) static u32 skl_plane_ctl_rotation(unsigned int rotation) { switch (rotation) { - case DRM_ROTATE_0: + case DRM_MODE_ROTATE_0: break; /* - * DRM_ROTATE_ is counter clockwise to stay compatible with Xrandr + * DRM_MODE_ROTATE_ is counter clockwise to stay compatible with Xrandr * while i915 HW rotation is clockwise, thats why this swapping. */ - case DRM_ROTATE_90: + case DRM_MODE_ROTATE_90: return PLANE_CTL_ROTATE_270; - case DRM_ROTATE_180: + case DRM_MODE_ROTATE_180: return PLANE_CTL_ROTATE_180; - case DRM_ROTATE_270: + case DRM_MODE_ROTATE_270: return PLANE_CTL_ROTATE_90; default: MISSING_CASE(rotation); @@ -4671,7 +4671,7 @@ int skl_update_scaler_crtc(struct intel_crtc_state *state) const struct drm_display_mode *adjusted_mode = &state->base.adjusted_mode; return skl_update_scaler(state, !state->base.active, SKL_CRTC_INDEX, - &state->scaler_state.scaler_id, DRM_ROTATE_0, + &state->scaler_state.scaler_id, DRM_MODE_ROTATE_0, state->pipe_src_w, state->pipe_src_h, adjusted_mode->crtc_hdisplay, adjusted_mode->crtc_vdisplay); } @@ -9239,7 +9239,7 @@ static u32 i9xx_cursor_ctl(const struct intel_crtc_state *crtc_state, return 0; } - if (plane_state->base.rotation & DRM_ROTATE_180) + if (plane_state->base.rotation & DRM_MODE_ROTATE_180) cntl |= CURSOR_ROTATE_180; return cntl; @@ -9300,7 +9300,7 @@ static void intel_crtc_update_cursor(struct drm_crtc *crtc, /* ILK+ do this automagically */ if (HAS_GMCH_DISPLAY(dev_priv) && - plane_state->base.rotation & DRM_ROTATE_180) { + plane_state->base.rotation & DRM_MODE_ROTATE_180) { base += (plane_state->base.crtc_h * plane_state->base.crtc_w - 1) * 4; } @@ -13607,22 +13607,22 @@ intel_primary_plane_create(struct drm_i915_private *dev_priv, enum pipe pipe) if (INTEL_GEN(dev_priv) >= 9) { supported_rotations = - DRM_ROTATE_0 | DRM_ROTATE_90 | - DRM_ROTATE_180 | DRM_ROTATE_270; + DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_90 | + DRM_MODE_ROTATE_180 | DRM_MODE_ROTATE_270; } else if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_B) { supported_rotations = - DRM_ROTATE_0 | DRM_ROTATE_180 | - DRM_REFLECT_X; + DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180 | + DRM_MODE_REFLECT_X; } else if (INTEL_GEN(dev_priv) >= 4) { supported_rotations = - DRM_ROTATE_0 | DRM_ROTATE_180; + DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180; } else { - supported_rotations = DRM_ROTATE_0; + supported_rotations = DRM_MODE_ROTATE_0; } if (INTEL_GEN(dev_priv) >= 4) drm_plane_create_rotation_property(&primary->base, - DRM_ROTATE_0, + DRM_MODE_ROTATE_0, supported_rotations); drm_plane_helper_add(&primary->base, &intel_plane_helper_funcs); @@ -13777,9 +13777,9 @@ intel_cursor_plane_create(struct drm_i915_private *dev_priv, enum pipe pipe) if (INTEL_GEN(dev_priv) >= 4) drm_plane_create_rotation_property(&cursor->base, - DRM_ROTATE_0, - DRM_ROTATE_0 | - DRM_ROTATE_180); + DRM_MODE_ROTATE_0, + DRM_MODE_ROTATE_0 | + DRM_MODE_ROTATE_180); if (INTEL_GEN(dev_priv) >= 9) state->scaler_id = -1; diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c index ded2add18b26..db7f8f0a1f36 100644 --- a/drivers/gpu/drm/i915/intel_fbc.c +++ b/drivers/gpu/drm/i915/intel_fbc.c @@ -801,7 +801,7 @@ static bool intel_fbc_can_activate(struct intel_crtc *crtc) return false; } if (INTEL_GEN(dev_priv) <= 4 && !IS_G4X(dev_priv) && - cache->plane.rotation != DRM_ROTATE_0) { + cache->plane.rotation != DRM_MODE_ROTATE_0) { fbc->no_fbc_reason = "rotation unsupported"; return false; } diff --git a/drivers/gpu/drm/i915/intel_fbdev.c b/drivers/gpu/drm/i915/intel_fbdev.c index 332254a8eebe..03347c6ae599 100644 --- a/drivers/gpu/drm/i915/intel_fbdev.c +++ b/drivers/gpu/drm/i915/intel_fbdev.c @@ -211,7 +211,7 @@ static int intelfb_create(struct drm_fb_helper *helper, * This also validates that any existing fb inherited from the * BIOS is suitable for own access. */ - vma = intel_pin_and_fence_fb_obj(&ifbdev->fb->base, DRM_ROTATE_0); + vma = intel_pin_and_fence_fb_obj(&ifbdev->fb->base, DRM_MODE_ROTATE_0); if (IS_ERR(vma)) { ret = PTR_ERR(vma); goto out_unlock; diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index 8c87c717c7cd..191e14ddde0c 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c @@ -398,10 +398,10 @@ static u32 vlv_sprite_ctl(const struct intel_crtc_state *crtc_state, if (fb->modifier == I915_FORMAT_MOD_X_TILED) sprctl |= SP_TILED; - if (rotation & DRM_ROTATE_180) + if (rotation & DRM_MODE_ROTATE_180) sprctl |= SP_ROTATE_180; - if (rotation & DRM_REFLECT_X) + if (rotation & DRM_MODE_REFLECT_X) sprctl |= SP_MIRROR; if (key->flags & I915_SET_COLORKEY_SOURCE) @@ -533,7 +533,7 @@ static u32 ivb_sprite_ctl(const struct intel_crtc_state *crtc_state, if (fb->modifier == I915_FORMAT_MOD_X_TILED) sprctl |= SPRITE_TILED; - if (rotation & DRM_ROTATE_180) + if (rotation & DRM_MODE_ROTATE_180) sprctl |= SPRITE_ROTATE_180; if (key->flags & I915_SET_COLORKEY_DESTINATION) @@ -674,7 +674,7 @@ static u32 ilk_sprite_ctl(const struct intel_crtc_state *crtc_state, if (fb->modifier == I915_FORMAT_MOD_X_TILED) dvscntr |= DVS_TILED; - if (rotation & DRM_ROTATE_180) + if (rotation & DRM_MODE_ROTATE_180) dvscntr |= DVS_ROTATE_180; if (key->flags & I915_SET_COLORKEY_DESTINATION) @@ -1145,15 +1145,15 @@ intel_sprite_plane_create(struct drm_i915_private *dev_priv, if (INTEL_GEN(dev_priv) >= 9) { supported_rotations = - DRM_ROTATE_0 | DRM_ROTATE_90 | - DRM_ROTATE_180 | DRM_ROTATE_270; + DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_90 | + DRM_MODE_ROTATE_180 | DRM_MODE_ROTATE_270; } else if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_B) { supported_rotations = - DRM_ROTATE_0 | DRM_ROTATE_180 | - DRM_REFLECT_X; + DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180 | + DRM_MODE_REFLECT_X; } else { supported_rotations = - DRM_ROTATE_0 | DRM_ROTATE_180; + DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180; } intel_plane->pipe = pipe; @@ -1180,7 +1180,7 @@ intel_sprite_plane_create(struct drm_i915_private *dev_priv, goto fail; drm_plane_create_rotation_property(&intel_plane->base, - DRM_ROTATE_0, + DRM_MODE_ROTATE_0, supported_rotations); drm_plane_helper_add(&intel_plane->base, &intel_plane_helper_funcs); diff --git a/drivers/gpu/drm/imx/ipuv3-plane.c b/drivers/gpu/drm/imx/ipuv3-plane.c index d63e853a0300..49546222c6d3 100644 --- a/drivers/gpu/drm/imx/ipuv3-plane.c +++ b/drivers/gpu/drm/imx/ipuv3-plane.c @@ -273,7 +273,7 @@ void ipu_plane_state_reset(struct drm_plane *plane) if (ipu_state) { ipu_state->base.plane = plane; - ipu_state->base.rotation = DRM_ROTATE_0; + ipu_state->base.rotation = DRM_MODE_ROTATE_0; } plane->state = &ipu_state->base; diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c index a38c5fe6cc19..5e7d9af4cba8 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c @@ -67,11 +67,11 @@ static void mdp5_plane_install_rotation_property(struct drm_device *dev, struct drm_plane *plane) { drm_plane_create_rotation_property(plane, - DRM_ROTATE_0, - DRM_ROTATE_0 | - DRM_ROTATE_180 | - DRM_REFLECT_X | - DRM_REFLECT_Y); + DRM_MODE_ROTATE_0, + DRM_MODE_ROTATE_0 | + DRM_MODE_ROTATE_180 | + DRM_MODE_REFLECT_X | + DRM_MODE_REFLECT_Y); } /* helper to install properties which are common to planes and crtcs */ @@ -369,14 +369,14 @@ static int mdp5_plane_atomic_check_with_state(struct drm_crtc_state *crtc_state, caps |= MDP_PIPE_CAP_SCALE; rotation = drm_rotation_simplify(state->rotation, - DRM_ROTATE_0 | - DRM_REFLECT_X | - DRM_REFLECT_Y); + DRM_MODE_ROTATE_0 | + DRM_MODE_REFLECT_X | + DRM_MODE_REFLECT_Y); - if (rotation & DRM_REFLECT_X) + if (rotation & DRM_MODE_REFLECT_X) caps |= MDP_PIPE_CAP_HFLIP; - if (rotation & DRM_REFLECT_Y) + if (rotation & DRM_MODE_REFLECT_Y) caps |= MDP_PIPE_CAP_VFLIP; if (plane->type == DRM_PLANE_TYPE_CURSOR) @@ -970,11 +970,11 @@ static int mdp5_plane_mode_set(struct drm_plane *plane, DBG("scale config = %x", config); rotation = drm_rotation_simplify(pstate->rotation, - DRM_ROTATE_0 | - DRM_REFLECT_X | - DRM_REFLECT_Y); - hflip = !!(rotation & DRM_REFLECT_X); - vflip = !!(rotation & DRM_REFLECT_Y); + DRM_MODE_ROTATE_0 | + DRM_MODE_REFLECT_X | + DRM_MODE_REFLECT_Y); + hflip = !!(rotation & DRM_MODE_REFLECT_X); + vflip = !!(rotation & DRM_MODE_REFLECT_Y); spin_lock_irqsave(&mdp5_plane->pipe_lock, flags); diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c index a7663249b3ba..9303daa79aba 100644 --- a/drivers/gpu/drm/nouveau/nv50_display.c +++ b/drivers/gpu/drm/nouveau/nv50_display.c @@ -1033,7 +1033,7 @@ nv50_wndw_reset(struct drm_plane *plane) plane->funcs->atomic_destroy_state(plane, plane->state); plane->state = &asyw->state; plane->state->plane = plane; - plane->state->rotation = DRM_ROTATE_0; + plane->state->rotation = DRM_MODE_ROTATE_0; } static void diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c b/drivers/gpu/drm/omapdrm/omap_drv.c index e1f47f0b3ccf..663e930a7b0f 100644 --- a/drivers/gpu/drm/omapdrm/omap_drv.c +++ b/drivers/gpu/drm/omapdrm/omap_drv.c @@ -577,7 +577,7 @@ static void dev_lastclose(struct drm_device *dev) drm_object_property_set_value(&crtc->base, crtc->primary->rotation_property, - DRM_ROTATE_0); + DRM_MODE_ROTATE_0); } for (i = 0; i < priv->num_planes; i++) { @@ -588,7 +588,7 @@ static void dev_lastclose(struct drm_device *dev) drm_object_property_set_value(&plane->base, plane->rotation_property, - DRM_ROTATE_0); + DRM_MODE_ROTATE_0); } if (priv->fbdev) { diff --git a/drivers/gpu/drm/omapdrm/omap_fb.c b/drivers/gpu/drm/omapdrm/omap_fb.c index 29dc677dd4d3..5ca0537bb427 100644 --- a/drivers/gpu/drm/omapdrm/omap_fb.c +++ b/drivers/gpu/drm/omapdrm/omap_fb.c @@ -167,30 +167,30 @@ void omap_framebuffer_update_scanout(struct drm_framebuffer *fb, uint32_t w = win->src_w; uint32_t h = win->src_h; - switch (win->rotation & DRM_ROTATE_MASK) { + switch (win->rotation & DRM_MODE_ROTATE_MASK) { default: dev_err(fb->dev->dev, "invalid rotation: %02x", (uint32_t)win->rotation); /* fallthru to default to no rotation */ case 0: - case DRM_ROTATE_0: + case DRM_MODE_ROTATE_0: orient = 0; break; - case DRM_ROTATE_90: + case DRM_MODE_ROTATE_90: orient = MASK_XY_FLIP | MASK_X_INVERT; break; - case DRM_ROTATE_180: + case DRM_MODE_ROTATE_180: orient = MASK_X_INVERT | MASK_Y_INVERT; break; - case DRM_ROTATE_270: + case DRM_MODE_ROTATE_270: orient = MASK_XY_FLIP | MASK_Y_INVERT; break; } - if (win->rotation & DRM_REFLECT_X) + if (win->rotation & DRM_MODE_REFLECT_X) orient ^= MASK_X_INVERT; - if (win->rotation & DRM_REFLECT_Y) + if (win->rotation & DRM_MODE_REFLECT_Y) orient ^= MASK_Y_INVERT; /* adjust x,y offset for flip/invert: */ @@ -205,9 +205,9 @@ void omap_framebuffer_update_scanout(struct drm_framebuffer *fb, info->rotation_type = OMAP_DSS_ROT_TILER; info->screen_width = omap_gem_tiled_stride(plane->bo, orient); } else { - switch (win->rotation & DRM_ROTATE_MASK) { + switch (win->rotation & DRM_MODE_ROTATE_MASK) { case 0: - case DRM_ROTATE_0: + case DRM_MODE_ROTATE_0: /* OK */ break; diff --git a/drivers/gpu/drm/omapdrm/omap_plane.c b/drivers/gpu/drm/omapdrm/omap_plane.c index 9168154d749e..d3d6818c68f8 100644 --- a/drivers/gpu/drm/omapdrm/omap_plane.c +++ b/drivers/gpu/drm/omapdrm/omap_plane.c @@ -141,7 +141,7 @@ static void omap_plane_atomic_disable(struct drm_plane *plane, struct omap_plane_state *omap_state = to_omap_plane_state(plane->state); struct omap_plane *omap_plane = to_omap_plane(plane); - plane->state->rotation = DRM_ROTATE_0; + plane->state->rotation = DRM_MODE_ROTATE_0; omap_state->zorder = plane->type == DRM_PLANE_TYPE_PRIMARY ? 0 : omap_plane->id; @@ -177,7 +177,7 @@ static int omap_plane_atomic_check(struct drm_plane *plane, if (state->crtc_y + state->crtc_h > crtc_state->adjusted_mode.vdisplay) return -EINVAL; - if (state->rotation != DRM_ROTATE_0 && + if (state->rotation != DRM_MODE_ROTATE_0 && !omap_framebuffer_supports_rotation(state->fb)) return -EINVAL; @@ -213,15 +213,15 @@ void omap_plane_install_properties(struct drm_plane *plane, if (priv->has_dmm) { if (!plane->rotation_property) drm_plane_create_rotation_property(plane, - DRM_ROTATE_0, - DRM_ROTATE_0 | DRM_ROTATE_90 | - DRM_ROTATE_180 | DRM_ROTATE_270 | - DRM_REFLECT_X | DRM_REFLECT_Y); + DRM_MODE_ROTATE_0, + DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_90 | + DRM_MODE_ROTATE_180 | DRM_MODE_ROTATE_270 | + DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y); /* Attach the rotation property also to the crtc object */ if (plane->rotation_property && obj != &plane->base) drm_object_attach_property(obj, plane->rotation_property, - DRM_ROTATE_0); + DRM_MODE_ROTATE_0); } drm_object_attach_property(obj, priv->zorder_prop, 0); @@ -273,7 +273,7 @@ static void omap_plane_reset(struct drm_plane *plane) */ omap_state->zorder = plane->type == DRM_PLANE_TYPE_PRIMARY ? 0 : omap_plane->id; - omap_state->base.rotation = DRM_ROTATE_0; + omap_state->base.rotation = DRM_MODE_ROTATE_0; plane->state = &omap_state->base; plane->state->plane = plane; diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c index ef9f3a2a4030..a8876b070168 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c @@ -566,7 +566,7 @@ int vmw_du_primary_plane_atomic_check(struct drm_plane *plane, ret = drm_plane_helper_check_update(plane, state->crtc, new_fb, &src, &dest, &clip, - DRM_ROTATE_0, + DRM_MODE_ROTATE_0, DRM_PLANE_HELPER_NO_SCALING, DRM_PLANE_HELPER_NO_SCALING, false, true, &visible); @@ -845,7 +845,7 @@ void vmw_du_plane_reset(struct drm_plane *plane) plane->state = &vps->base; plane->state->plane = plane; - plane->state->rotation = DRM_ROTATE_0; + plane->state->rotation = DRM_MODE_ROTATE_0; } diff --git a/include/drm/drm_blend.h b/include/drm/drm_blend.h index bc9e596be4c2..17606026590b 100644 --- a/include/drm/drm_blend.h +++ b/include/drm/drm_blend.h @@ -25,32 +25,15 @@ #include #include +#include struct drm_device; struct drm_atomic_state; struct drm_plane; -/* - * Rotation property bits. DRM_ROTATE_ rotates the image by the - * specified amount in degrees in counter clockwise direction. DRM_REFLECT_X and - * DRM_REFLECT_Y reflects the image along the specified axis prior to rotation - * - * WARNING: These defines are UABI since they're exposed in the rotation - * property. - */ -#define DRM_ROTATE_0 BIT(0) -#define DRM_ROTATE_90 BIT(1) -#define DRM_ROTATE_180 BIT(2) -#define DRM_ROTATE_270 BIT(3) -#define DRM_ROTATE_MASK (DRM_ROTATE_0 | DRM_ROTATE_90 | \ - DRM_ROTATE_180 | DRM_ROTATE_270) -#define DRM_REFLECT_X BIT(4) -#define DRM_REFLECT_Y BIT(5) -#define DRM_REFLECT_MASK (DRM_REFLECT_X | DRM_REFLECT_Y) - static inline bool drm_rotation_90_or_270(unsigned int rotation) { - return rotation & (DRM_ROTATE_90 | DRM_ROTATE_270); + return rotation & (DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_270); } int drm_plane_create_rotation_property(struct drm_plane *plane, diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h index 8c67fc03d53d..403339f98a92 100644 --- a/include/uapi/drm/drm_mode.h +++ b/include/uapi/drm/drm_mode.h @@ -75,7 +75,7 @@ extern "C" { * (define not exposed to user space). */ #define DRM_MODE_FLAG_3D_MASK (0x1f<<14) -#define DRM_MODE_FLAG_3D_NONE (0<<14) +#define DRM_MODE_FLAG_3D_NONE (0<<14) #define DRM_MODE_FLAG_3D_FRAME_PACKING (1<<14) #define DRM_MODE_FLAG_3D_FIELD_ALTERNATIVE (2<<14) #define DRM_MODE_FLAG_3D_LINE_ALTERNATIVE (3<<14) @@ -127,6 +127,53 @@ extern "C" { #define DRM_MODE_LINK_STATUS_GOOD 0 #define DRM_MODE_LINK_STATUS_BAD 1 +/* + * DRM_MODE_ROTATE_ + * + * Signals that a drm plane is been rotated degrees in counter + * clockwise direction. + * + * This define is provided as a convenience, looking up the property id + * using the name->prop id lookup is the preferred method. + */ +#define DRM_MODE_ROTATE_0 (1<<0) +#define DRM_MODE_ROTATE_90 (1<<1) +#define DRM_MODE_ROTATE_180 (1<<2) +#define DRM_MODE_ROTATE_270 (1<<3) + +/* + * DRM_MODE_ROTATE_MASK + * + * Bitmask used to look for drm plane rotations. + */ +#define DRM_MODE_ROTATE_MASK (\ + DRM_MODE_ROTATE_0 | \ + DRM_MODE_ROTATE_90 | \ + DRM_MODE_ROTATE_180 | \ + DRM_MODE_ROTATE_270) + +/* + * DRM_MODE_REFLECT_ + * + * Signals that the contents of a drm plane is reflected in the axis, + * in the same way as mirroring. + * + * This define is provided as a convenience, looking up the property id + * using the name->prop id lookup is the preferred method. + */ +#define DRM_MODE_REFLECT_X (1<<4) +#define DRM_MODE_REFLECT_Y (1<<5) + +/* + * DRM_MODE_REFLECT_MASK + * + * Bitmask used to look for drm plane reflections. + */ +#define DRM_MODE_REFLECT_MASK (\ + DRM_MODE_REFLECT_X | \ + DRM_MODE_REFLECT_Y) + + struct drm_mode_modeinfo { __u32 clock; __u16 hdisplay; -- cgit v1.2.3 From 3eb220a5319169fb44dcfe1944c731424c2bee5f Mon Sep 17 00:00:00 2001 From: Jose Abreu Date: Mon, 15 May 2017 11:33:47 +0200 Subject: drm: Add crtc/encoder/bridge->mode_valid() callbacks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This adds a new callback to crtc, encoder and bridge helper functions called mode_valid(). This callback shall be implemented if the corresponding component has some sort of restriction in the modes that can be displayed. A NULL callback implicates that the component can display all the modes. We also change the documentation so that the new and old callbacks are correctly documented. Only the callbacks were implemented to simplify review process, following patches will make use of them. Changes in v2 from Daniel: - Update the warning about how modes aren't filtered in atomic_check - the heleprs help out a lot more now. - Consistenly roll out that warning, crtc/encoder's atomic_check missed it. - Sprinkle more links all over the place, so it's easier to see where this stuff is used and how the differen hooks are related. - Note that ->mode_valid is optional everywhere. - Explain why the connector's mode_valid is special and does _not_ get called in atomic_check. v3: Document what can and cannot be checked in mode_valid a bit better (Andrjez). Answer: Only allowed to look at the mode, nothing else. Cc: Laurent Pinchart Signed-off-by: Jose Abreu Cc: Jose Abreu Cc: Carlos Palminha Cc: Alexey Brodkin Cc: Ville Syrjälä Cc: Daniel Vetter Cc: Dave Airlie Cc: Andrzej Hajda Cc: Archit Taneja Signed-off-by: Daniel Vetter (v2) Reviewed-by: Jose Abreu (v2) Reviewed-by: Andrzej Hajda Link: http://patchwork.freedesktop.org/patch/msgid/20170515093347.31098-1-daniel.vetter@ffwll.ch --- include/drm/drm_bridge.h | 40 +++++++++ include/drm/drm_modeset_helper_vtables.h | 134 +++++++++++++++++++++++-------- 2 files changed, 141 insertions(+), 33 deletions(-) (limited to 'include') diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h index fdd82fcbf168..f703bafc2e30 100644 --- a/include/drm/drm_bridge.h +++ b/include/drm/drm_bridge.h @@ -58,6 +58,40 @@ struct drm_bridge_funcs { */ void (*detach)(struct drm_bridge *bridge); + /** + * @mode_valid: + * + * This callback is used to check if a specific mode is valid in this + * bridge. This should be implemented if the bridge has some sort of + * restriction in the modes it can display. For example, a given bridge + * may be responsible to set a clock value. If the clock can not + * produce all the values for the available modes then this callback + * can be used to restrict the number of modes to only the ones that + * can be displayed. + * + * This hook is used by the probe helpers to filter the mode list in + * drm_helper_probe_single_connector_modes(), and it is used by the + * atomic helpers to validate modes supplied by userspace in + * drm_atomic_helper_check_modeset(). + * + * This function is optional. + * + * NOTE: + * + * Since this function is both called from the check phase of an atomic + * commit, and the mode validation in the probe paths it is not allowed + * to look at anything else but the passed-in mode, and validate it + * against configuration-invariant hardward constraints. Any further + * limits which depend upon the configuration can only be checked in + * @mode_fixup. + * + * RETURNS: + * + * drm_mode_status Enum + */ + enum drm_mode_status (*mode_valid)(struct drm_bridge *crtc, + const struct drm_display_mode *mode); + /** * @mode_fixup: * @@ -82,6 +116,12 @@ struct drm_bridge_funcs { * NOT touch any persistent state (hardware or software) or data * structures except the passed in @state parameter. * + * Also beware that userspace can request its own custom modes, neither + * core nor helpers filter modes to the list of probe modes reported by + * the GETCONNECTOR IOCTL and stored in &drm_connector.modes. To ensure + * that modes are filtered consistently put any bridge constraints and + * limits checks into @mode_valid. + * * RETURNS: * * True if an acceptable configuration is possible, false if the modeset diff --git a/include/drm/drm_modeset_helper_vtables.h b/include/drm/drm_modeset_helper_vtables.h index c01c328f6cc8..739b832eb304 100644 --- a/include/drm/drm_modeset_helper_vtables.h +++ b/include/drm/drm_modeset_helper_vtables.h @@ -105,6 +105,40 @@ struct drm_crtc_helper_funcs { */ void (*commit)(struct drm_crtc *crtc); + /** + * @mode_valid: + * + * This callback is used to check if a specific mode is valid in this + * crtc. This should be implemented if the crtc has some sort of + * restriction in the modes it can display. For example, a given crtc + * may be responsible to set a clock value. If the clock can not + * produce all the values for the available modes then this callback + * can be used to restrict the number of modes to only the ones that + * can be displayed. + * + * This hook is used by the probe helpers to filter the mode list in + * drm_helper_probe_single_connector_modes(), and it is used by the + * atomic helpers to validate modes supplied by userspace in + * drm_atomic_helper_check_modeset(). + * + * This function is optional. + * + * NOTE: + * + * Since this function is both called from the check phase of an atomic + * commit, and the mode validation in the probe paths it is not allowed + * to look at anything else but the passed-in mode, and validate it + * against configuration-invariant hardward constraints. Any further + * limits which depend upon the configuration can only be checked in + * @mode_fixup or @atomic_check. + * + * RETURNS: + * + * drm_mode_status Enum + */ + enum drm_mode_status (*mode_valid)(struct drm_crtc *crtc, + const struct drm_display_mode *mode); + /** * @mode_fixup: * @@ -132,20 +166,11 @@ struct drm_crtc_helper_funcs { * Atomic drivers which need to inspect and adjust more state should * instead use the @atomic_check callback. * - * Also beware that neither core nor helpers filter modes before - * passing them to the driver: While the list of modes that is - * advertised to userspace is filtered using the - * &drm_connector.mode_valid callback, neither the core nor the helpers - * do any filtering on modes passed in from userspace when setting a - * mode. It is therefore possible for userspace to pass in a mode that - * was previously filtered out using &drm_connector.mode_valid or add a - * custom mode that wasn't probed from EDID or similar to begin with. - * Even though this is an advanced feature and rarely used nowadays, - * some users rely on being able to specify modes manually so drivers - * must be prepared to deal with it. Specifically this means that all - * drivers need not only validate modes in &drm_connector.mode_valid but - * also in this or in the &drm_encoder_helper_funcs.mode_fixup callback - * to make sure invalid modes passed in from userspace are rejected. + * Also beware that userspace can request its own custom modes, neither + * core nor helpers filter modes to the list of probe modes reported by + * the GETCONNECTOR IOCTL and stored in &drm_connector.modes. To ensure + * that modes are filtered consistently put any CRTC constraints and + * limits checks into @mode_valid. * * RETURNS: * @@ -341,6 +366,12 @@ struct drm_crtc_helper_funcs { * state objects passed-in or assembled in the overall &drm_atomic_state * update tracking structure. * + * Also beware that userspace can request its own custom modes, neither + * core nor helpers filter modes to the list of probe modes reported by + * the GETCONNECTOR IOCTL and stored in &drm_connector.modes. To ensure + * that modes are filtered consistently put any CRTC constraints and + * limits checks into @mode_valid. + * * RETURNS: * * 0 on success, -EINVAL if the state or the transition can't be @@ -456,6 +487,40 @@ struct drm_encoder_helper_funcs { */ void (*dpms)(struct drm_encoder *encoder, int mode); + /** + * @mode_valid: + * + * This callback is used to check if a specific mode is valid in this + * encoder. This should be implemented if the encoder has some sort + * of restriction in the modes it can display. For example, a given + * encoder may be responsible to set a clock value. If the clock can + * not produce all the values for the available modes then this callback + * can be used to restrict the number of modes to only the ones that + * can be displayed. + * + * This hook is used by the probe helpers to filter the mode list in + * drm_helper_probe_single_connector_modes(), and it is used by the + * atomic helpers to validate modes supplied by userspace in + * drm_atomic_helper_check_modeset(). + * + * This function is optional. + * + * NOTE: + * + * Since this function is both called from the check phase of an atomic + * commit, and the mode validation in the probe paths it is not allowed + * to look at anything else but the passed-in mode, and validate it + * against configuration-invariant hardward constraints. Any further + * limits which depend upon the configuration can only be checked in + * @mode_fixup or @atomic_check. + * + * RETURNS: + * + * drm_mode_status Enum + */ + enum drm_mode_status (*mode_valid)(struct drm_encoder *crtc, + const struct drm_display_mode *mode); + /** * @mode_fixup: * @@ -482,21 +547,11 @@ struct drm_encoder_helper_funcs { * Atomic drivers which need to inspect and adjust more state should * instead use the @atomic_check callback. * - * Also beware that neither core nor helpers filter modes before - * passing them to the driver: While the list of modes that is - * advertised to userspace is filtered using the connector's - * &drm_connector_helper_funcs.mode_valid callback, neither the core nor - * the helpers do any filtering on modes passed in from userspace when - * setting a mode. It is therefore possible for userspace to pass in a - * mode that was previously filtered out using - * &drm_connector_helper_funcs.mode_valid or add a custom mode that - * wasn't probed from EDID or similar to begin with. Even though this - * is an advanced feature and rarely used nowadays, some users rely on - * being able to specify modes manually so drivers must be prepared to - * deal with it. Specifically this means that all drivers need not only - * validate modes in &drm_connector.mode_valid but also in this or in - * the &drm_crtc_helper_funcs.mode_fixup callback to make sure - * invalid modes passed in from userspace are rejected. + * Also beware that userspace can request its own custom modes, neither + * core nor helpers filter modes to the list of probe modes reported by + * the GETCONNECTOR IOCTL and stored in &drm_connector.modes. To ensure + * that modes are filtered consistently put any encoder constraints and + * limits checks into @mode_valid. * * RETURNS: * @@ -686,6 +741,12 @@ struct drm_encoder_helper_funcs { * state objects passed-in or assembled in the overall &drm_atomic_state * update tracking structure. * + * Also beware that userspace can request its own custom modes, neither + * core nor helpers filter modes to the list of probe modes reported by + * the GETCONNECTOR IOCTL and stored in &drm_connector.modes. To ensure + * that modes are filtered consistently put any encoder constraints and + * limits checks into @mode_valid. + * * RETURNS: * * 0 on success, -EINVAL if the state or the transition can't be @@ -795,13 +856,20 @@ struct drm_connector_helper_funcs { * (which is usually derived from the EDID data block from the sink). * See e.g. drm_helper_probe_single_connector_modes(). * + * This function is optional. + * * NOTE: * * This only filters the mode list supplied to userspace in the - * GETCONNECOTR IOCTL. Userspace is free to create modes of its own and - * ask the kernel to use them. It this case the atomic helpers or legacy - * CRTC helpers will not call this function. Drivers therefore must - * still fully validate any mode passed in in a modeset request. + * GETCONNECTOR IOCTL. Compared to &drm_encoder_helper_funcs.mode_valid, + * &drm_crtc_helper_funcs.mode_valid and &drm_bridge_funcs.mode_valid, + * which are also called by the atomic helpers from + * drm_atomic_helper_check_modeset(). This allows userspace to force and + * ignore sink constraint (like the pixel clock limits in the screen's + * EDID), which is useful for e.g. testing, or working around a broken + * EDID. Any source hardware constraint (which always need to be + * enforced) therefore should be checked in one of the above callbacks, + * and not this one here. * * To avoid races with concurrent connector state updates, the helper * libraries always call this with the &drm_mode_config.connection_mutex -- cgit v1.2.3 From 9de5d4a61cc2a99634e3b51bda0f8e2fdd8f4287 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Mon, 15 May 2017 11:11:35 +0200 Subject: drm/doc: Document adjusted/request modes a bit better MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Laurent started a massive discussion on IRC about this. Let's try to document common usage a bit better. v2: Cross-links+typos. Cc: Laurent Pinchart Cc: Ville Syrjälä Cc: Jose Abreu Reviewed-by: Jose Abreu Reviewed-by: Andrzej Hajda Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/20170515091136.26307-1-daniel.vetter@ffwll.ch --- include/drm/drm_bridge.h | 2 +- include/drm/drm_crtc.h | 28 +++++++++++++++++++++++++--- include/drm/drm_modeset_helper_vtables.h | 6 ++++-- 3 files changed, 30 insertions(+), 6 deletions(-) (limited to 'include') diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h index f703bafc2e30..983054f2e86e 100644 --- a/include/drm/drm_bridge.h +++ b/include/drm/drm_bridge.h @@ -100,7 +100,7 @@ struct drm_bridge_funcs { * the display chain, either the final &drm_connector or the next * &drm_bridge. The parameter adjusted_mode is the input mode the bridge * requires. It can be modified by this callback and does not need to - * match mode. + * match mode. See also &drm_crtc_state.adjusted_mode for more details. * * This is the only hook that allows a bridge to reject a modeset. If * this function passes all other callbacks must succeed for this diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index adf4e91a9399..b6e3713bd7a9 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -90,8 +90,6 @@ struct drm_plane_helper_funcs; * @plane_mask: bitmask of (1 << drm_plane_index(plane)) of attached planes * @connector_mask: bitmask of (1 << drm_connector_index(connector)) of attached connectors * @encoder_mask: bitmask of (1 << drm_encoder_index(encoder)) of attached encoders - * @adjusted_mode: for use by helpers and drivers to compute adjusted mode timings - * @mode: current mode timings * @mode_blob: &drm_property_blob for @mode * @state: backpointer to global drm_atomic_state * @@ -131,9 +129,33 @@ struct drm_crtc_state { u32 connector_mask; u32 encoder_mask; - /* adjusted_mode: for use by helpers and drivers */ + /** + * @adjusted_mode: + * + * Internal display timings which can be used by the driver to handle + * differences between the mode requested by userspace in @mode and what + * is actually programmed into the hardware. It is purely driver + * implementation defined what exactly this adjusted mode means. Usually + * it is used to store the hardware display timings used between the + * CRTC and encoder blocks. + */ struct drm_display_mode adjusted_mode; + /** + * @mode: + * + * Display timings requested by userspace. The driver should try to + * match the refresh rate as close as possible (but note that it's + * undefined what exactly is close enough, e.g. some of the HDMI modes + * only differ in less than 1% of the refresh rate). The active width + * and height as observed by userspace for positioning planes must match + * exactly. + * + * For external connectors where the sink isn't fixed (like with a + * built-in panel), this mode here should match the physical mode on the + * wire to the last details (i.e. including sync polarities and + * everything). + */ struct drm_display_mode mode; /* blob property to expose current mode to atomic userspace */ diff --git a/include/drm/drm_modeset_helper_vtables.h b/include/drm/drm_modeset_helper_vtables.h index 739b832eb304..361240ca738e 100644 --- a/include/drm/drm_modeset_helper_vtables.h +++ b/include/drm/drm_modeset_helper_vtables.h @@ -147,7 +147,8 @@ struct drm_crtc_helper_funcs { * encoders need to be fed with. Note that this is the inverse semantics * of the meaning for the &drm_encoder and &drm_bridge_funcs.mode_fixup * vfunc. If the CRTC cannot support the requested conversion from mode - * to adjusted_mode it should reject the modeset. + * to adjusted_mode it should reject the modeset. See also + * &drm_crtc_state.adjusted_mode for more details. * * This function is used by both legacy CRTC helpers and atomic helpers. * With atomic helpers it is optional. @@ -528,7 +529,8 @@ struct drm_encoder_helper_funcs { * mode is the display mode that should be fed to the next element in * the display chain, either the final &drm_connector or a &drm_bridge. * The parameter adjusted_mode is the input mode the encoder requires. It - * can be modified by this callback and does not need to match mode. + * can be modified by this callback and does not need to match mode. See + * also &drm_crtc_state.adjusted_mode for more details. * * This function is used by both legacy CRTC helpers and atomic helpers. * This hook is optional. -- cgit v1.2.3 From 9f800214731fddb0a99810bcd1af8d93d22076e0 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Mon, 15 May 2017 11:11:36 +0200 Subject: drm/doc: Clarify mode_fixup vs. atomic_check a bit more Brought up by both Laurent and Andrzej when reviewing the new ->mode_valid hooks. Since mode_fixup is just a simpler version of the much more generic atomic_check we can't really unify it with mode_valid. Most drivers should probably switch their current mode_fixup code to either the new mode_valid or the atomic_check hooks, but e.g. that doesn't exist yet for bridges, and for CRTCs the situation is a bit more complicated. Hence there's no clear equivalence between mode_fixup and mode_valid, even if it looks like that at first glance. v2: Fix accidental double-dot (Adnrzej). Cc: Andrzej Hajda Cc: Laurent Pinchart Cc: Jose Abreu Reviewed-by: Jose Abreu Reviewed-by: Andrzej Hajda Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/20170515091136.26307-2-daniel.vetter@ffwll.ch --- include/drm/drm_modeset_helper_vtables.h | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/drm/drm_modeset_helper_vtables.h b/include/drm/drm_modeset_helper_vtables.h index 361240ca738e..85984b208218 100644 --- a/include/drm/drm_modeset_helper_vtables.h +++ b/include/drm/drm_modeset_helper_vtables.h @@ -165,7 +165,11 @@ struct drm_crtc_helper_funcs { * allowed. * * Atomic drivers which need to inspect and adjust more state should - * instead use the @atomic_check callback. + * instead use the @atomic_check callback, but note that they're not + * perfectly equivalent: @mode_valid is called from + * drm_atomic_helper_check_modeset(), but @atomic_check is called from + * drm_atomic_helper_check_planes(), because originally it was meant for + * plane update checks only. * * Also beware that userspace can request its own custom modes, neither * core nor helpers filter modes to the list of probe modes reported by @@ -547,7 +551,9 @@ struct drm_encoder_helper_funcs { * allowed. * * Atomic drivers which need to inspect and adjust more state should - * instead use the @atomic_check callback. + * instead use the @atomic_check callback. If @atomic_check is used, + * this hook isn't called since @atomic_check allows a strict superset + * of the functionality of @mode_fixup. * * Also beware that userspace can request its own custom modes, neither * core nor helpers filter modes to the list of probe modes reported by @@ -734,6 +740,11 @@ struct drm_encoder_helper_funcs { * update the CRTC to match what the encoder needs for the requested * connector. * + * Since this provides a strict superset of the functionality of + * @mode_fixup (the requested and adjusted modes are both available + * through the passed in &struct drm_crtc_state) @mode_fixup is not + * called when @atomic_check is implemented. + * * This function is used by the atomic helpers, but it is optional. * * NOTE: -- cgit v1.2.3 From 71ebc9a3795818eab52e81bbcbdfae130ee35d9e Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 16 May 2017 12:10:42 +0100 Subject: dma-buf/sync-file: Defer creation of sync_file->name Constructing the name takes the majority of the time for allocating a sync_file to wrap a fence, and the name is very rarely used (only via the sync_file status user interface). To reduce the impact on the common path (that of creating sync_file to pass around), defer the construction of the name until it is first used. v2: Update kerneldoc (kbuild test robot) v3: sync_debug.c was peeking at the name v4: Comment upon the potential race between two users of sync_file_get_name() and claim that such a race is below the level of notice. However, to prevent any future nuisance, use a global spinlock to serialize the assignment of the name. v5: Completely avoid the read/write race by only storing the name passed in from the user inside sync_file->user_name and passing in a buffer to dynamically construct the name otherwise. Signed-off-by: Chris Wilson Cc: Sumit Semwal Cc: Gustavo Padovan Cc: Daniel Vetter Cc: David Herrmann Reviewed-by: Daniel Vetter Signed-off-by: Gustavo Padovan Link: http://patchwork.freedesktop.org/patch/msgid/20170516111042.24719-1-chris@chris-wilson.co.uk --- drivers/dma-buf/sync_debug.c | 4 +++- drivers/dma-buf/sync_file.c | 39 ++++++++++++++++++++++++++++++++------- include/linux/sync_file.h | 11 +++++++++-- 3 files changed, 44 insertions(+), 10 deletions(-) (limited to 'include') diff --git a/drivers/dma-buf/sync_debug.c b/drivers/dma-buf/sync_debug.c index a0d780ab68c3..82a6e7f6d37f 100644 --- a/drivers/dma-buf/sync_debug.c +++ b/drivers/dma-buf/sync_debug.c @@ -132,9 +132,11 @@ static void sync_print_obj(struct seq_file *s, struct sync_timeline *obj) static void sync_print_sync_file(struct seq_file *s, struct sync_file *sync_file) { + char buf[128]; int i; - seq_printf(s, "[%p] %s: %s\n", sync_file, sync_file->name, + seq_printf(s, "[%p] %s: %s\n", sync_file, + sync_file_get_name(sync_file, buf, sizeof(buf)), sync_status_str(dma_fence_get_status(sync_file->fence))); if (dma_fence_is_array(sync_file->fence)) { diff --git a/drivers/dma-buf/sync_file.c b/drivers/dma-buf/sync_file.c index dc89b1d484e8..545e2c5c4815 100644 --- a/drivers/dma-buf/sync_file.c +++ b/drivers/dma-buf/sync_file.c @@ -80,11 +80,6 @@ struct sync_file *sync_file_create(struct dma_fence *fence) sync_file->fence = dma_fence_get(fence); - snprintf(sync_file->name, sizeof(sync_file->name), "%s-%s%llu-%d", - fence->ops->get_driver_name(fence), - fence->ops->get_timeline_name(fence), fence->context, - fence->seqno); - return sync_file; } EXPORT_SYMBOL(sync_file_create); @@ -129,6 +124,36 @@ struct dma_fence *sync_file_get_fence(int fd) } EXPORT_SYMBOL(sync_file_get_fence); +/** + * sync_file_get_name - get the name of the sync_file + * @sync_file: sync_file to get the fence from + * @buf: destination buffer to copy sync_file name into + * @len: available size of destination buffer. + * + * Each sync_file may have a name assigned either by the user (when merging + * sync_files together) or created from the fence it contains. In the latter + * case construction of the name is deferred until use, and so requires + * sync_file_get_name(). + * + * Returns: a string representing the name. + */ +char *sync_file_get_name(struct sync_file *sync_file, char *buf, int len) +{ + if (sync_file->user_name[0]) { + strlcpy(buf, sync_file->user_name, len); + } else { + struct dma_fence *fence = sync_file->fence; + + snprintf(buf, len, "%s-%s%llu-%d", + fence->ops->get_driver_name(fence), + fence->ops->get_timeline_name(fence), + fence->context, + fence->seqno); + } + + return buf; +} + static int sync_file_set_fence(struct sync_file *sync_file, struct dma_fence **fences, int num_fences) { @@ -266,7 +291,7 @@ static struct sync_file *sync_file_merge(const char *name, struct sync_file *a, goto err; } - strlcpy(sync_file->name, name, sizeof(sync_file->name)); + strlcpy(sync_file->user_name, name, sizeof(sync_file->user_name)); return sync_file; err: @@ -413,7 +438,7 @@ static long sync_file_ioctl_fence_info(struct sync_file *sync_file, } no_fences: - strlcpy(info.name, sync_file->name, sizeof(info.name)); + sync_file_get_name(sync_file, info.name, sizeof(info.name)); info.status = dma_fence_is_signaled(sync_file->fence); info.num_fences = num_fences; diff --git a/include/linux/sync_file.h b/include/linux/sync_file.h index d37beefdfbd5..5726107963b2 100644 --- a/include/linux/sync_file.h +++ b/include/linux/sync_file.h @@ -23,7 +23,6 @@ /** * struct sync_file - sync file to export to the userspace * @file: file representing this fence - * @name: name of sync_file. Useful for debugging * @sync_file_list: membership in global file list * @wq: wait queue for fence signaling * @fence: fence with the fences in the sync_file @@ -31,7 +30,14 @@ */ struct sync_file { struct file *file; - char name[32]; + /** + * @user_name: + * + * Name of the sync file provided by userspace, for merged fences. + * Otherwise generated through driver callbacks (in which case the + * entire array is 0). + */ + char user_name[32]; #ifdef CONFIG_DEBUG_FS struct list_head sync_file_list; #endif @@ -46,5 +52,6 @@ struct sync_file { struct sync_file *sync_file_create(struct dma_fence *fence); struct dma_fence *sync_file_get_fence(int fd); +char *sync_file_get_name(struct sync_file *sync_file, char *buf, int len); #endif /* _LINUX_SYNC_H */ -- cgit v1.2.3