From 455e00f1412fe51fa7bd21ad6fe0015b163fa9e5 Mon Sep 17 00:00:00 2001 From: Daniel Stone Date: Mon, 16 Dec 2019 19:46:43 -0800 Subject: drm: Add getfb2 ioctl MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit getfb2 allows us to pass multiple planes and modifiers, just like addfb2 over addfb. Changes since v2: - add privilege checks from getfb1 since handles should only be returned to master/root Changes since v1: - unused modifiers set to 0 instead of DRM_FORMAT_MOD_INVALID - update ioctl number Signed-off-by: Daniel Stone Signed-off-by: Juston Li Acked-by: Daniel Vetter Reviewed-by: Ville Syrjälä Signed-off-by: Lyude Paul Link: https://patchwork.freedesktop.org/patch/msgid/20191217034642.3814-1-juston.li@intel.com --- include/uapi/drm/drm.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/uapi') diff --git a/include/uapi/drm/drm.h b/include/uapi/drm/drm.h index 868bf7996c0f..808b48a93330 100644 --- a/include/uapi/drm/drm.h +++ b/include/uapi/drm/drm.h @@ -948,6 +948,8 @@ extern "C" { #define DRM_IOCTL_SYNCOBJ_TRANSFER DRM_IOWR(0xCC, struct drm_syncobj_transfer) #define DRM_IOCTL_SYNCOBJ_TIMELINE_SIGNAL DRM_IOWR(0xCD, struct drm_syncobj_timeline_array) +#define DRM_IOCTL_MODE_GETFB2 DRM_IOWR(0xCE, struct drm_mode_fb_cmd2) + /** * Device specific ioctls should only be in their respective headers * The device specific ioctl range is from 0x40 to 0x9f. -- cgit v1.2.3 From 6aebc51d7aeff5a30d86485f320f0c871b5f23a4 Mon Sep 17 00:00:00 2001 From: Qiang Yu Date: Thu, 16 Jan 2020 21:11:55 +0800 Subject: drm/lima: support heap buffer creation heap buffer is used as output of GP and input of PP for Mali Utgard GPU. Size of heap buffer depends on the task so is a runtime variable. Previously we just create a large enough buffer as heap buffer. Now we add a heap buffer type to be able to increase the backup memory dynamically when GP fail due to lack of heap memory. Reviewed-by: Vasily Khoruzhick Tested-by: Andreas Baierl Signed-off-by: Qiang Yu Link: https://patchwork.freedesktop.org/patch/msgid/20200116131157.13346-4-yuq825@gmail.com --- drivers/gpu/drm/lima/lima_drv.c | 6 +- drivers/gpu/drm/lima/lima_drv.h | 1 + drivers/gpu/drm/lima/lima_gem.c | 134 +++++++++++++++++++++++++++++++++++++--- drivers/gpu/drm/lima/lima_gem.h | 4 ++ drivers/gpu/drm/lima/lima_vm.c | 4 +- include/uapi/drm/lima_drm.h | 9 ++- 6 files changed, 147 insertions(+), 11 deletions(-) (limited to 'include/uapi') diff --git a/drivers/gpu/drm/lima/lima_drv.c b/drivers/gpu/drm/lima/lima_drv.c index 124efe4fa97b..18f88aaef1a2 100644 --- a/drivers/gpu/drm/lima/lima_drv.c +++ b/drivers/gpu/drm/lima/lima_drv.c @@ -15,10 +15,14 @@ #include "lima_vm.h" int lima_sched_timeout_ms; +uint lima_heap_init_nr_pages = 8; MODULE_PARM_DESC(sched_timeout_ms, "task run timeout in ms"); module_param_named(sched_timeout_ms, lima_sched_timeout_ms, int, 0444); +MODULE_PARM_DESC(heap_init_nr_pages, "heap buffer init number of pages"); +module_param_named(heap_init_nr_pages, lima_heap_init_nr_pages, uint, 0444); + static int lima_ioctl_get_param(struct drm_device *dev, void *data, struct drm_file *file) { struct drm_lima_get_param *args = data; @@ -68,7 +72,7 @@ static int lima_ioctl_gem_create(struct drm_device *dev, void *data, struct drm_ if (args->pad) return -EINVAL; - if (args->flags) + if (args->flags & ~(LIMA_BO_FLAG_HEAP)) return -EINVAL; if (args->size == 0) diff --git a/drivers/gpu/drm/lima/lima_drv.h b/drivers/gpu/drm/lima/lima_drv.h index 69c7344715c9..f492ecc6a5d9 100644 --- a/drivers/gpu/drm/lima/lima_drv.h +++ b/drivers/gpu/drm/lima/lima_drv.h @@ -9,6 +9,7 @@ #include "lima_ctx.h" extern int lima_sched_timeout_ms; +extern uint lima_heap_init_nr_pages; struct lima_vm; struct lima_bo; diff --git a/drivers/gpu/drm/lima/lima_gem.c b/drivers/gpu/drm/lima/lima_gem.c index d0059d8c97d8..5404e0d668db 100644 --- a/drivers/gpu/drm/lima/lima_gem.c +++ b/drivers/gpu/drm/lima/lima_gem.c @@ -4,6 +4,8 @@ #include #include #include +#include +#include #include #include @@ -15,6 +17,83 @@ #include "lima_gem.h" #include "lima_vm.h" +int lima_heap_alloc(struct lima_bo *bo, struct lima_vm *vm) +{ + struct page **pages; + struct address_space *mapping = bo->base.base.filp->f_mapping; + struct device *dev = bo->base.base.dev->dev; + size_t old_size = bo->heap_size; + size_t new_size = bo->heap_size ? bo->heap_size * 2 : + (lima_heap_init_nr_pages << PAGE_SHIFT); + struct sg_table sgt; + int i, ret; + + if (bo->heap_size >= bo->base.base.size) + return -ENOSPC; + + new_size = min(new_size, bo->base.base.size); + + mutex_lock(&bo->base.pages_lock); + + if (bo->base.pages) { + pages = bo->base.pages; + } else { + pages = kvmalloc_array(bo->base.base.size >> PAGE_SHIFT, + sizeof(*pages), GFP_KERNEL | __GFP_ZERO); + if (!pages) { + mutex_unlock(&bo->base.pages_lock); + return -ENOMEM; + } + + bo->base.pages = pages; + bo->base.pages_use_count = 1; + + mapping_set_unevictable(mapping); + } + + for (i = old_size >> PAGE_SHIFT; i < new_size >> PAGE_SHIFT; i++) { + struct page *page = shmem_read_mapping_page(mapping, i); + + if (IS_ERR(page)) { + mutex_unlock(&bo->base.pages_lock); + return PTR_ERR(page); + } + pages[i] = page; + } + + mutex_unlock(&bo->base.pages_lock); + + ret = sg_alloc_table_from_pages(&sgt, pages, i, 0, + new_size, GFP_KERNEL); + if (ret) + return ret; + + if (bo->base.sgt) { + dma_unmap_sg(dev, bo->base.sgt->sgl, + bo->base.sgt->nents, DMA_BIDIRECTIONAL); + sg_free_table(bo->base.sgt); + } else { + bo->base.sgt = kmalloc(sizeof(*bo->base.sgt), GFP_KERNEL); + if (!bo->base.sgt) { + sg_free_table(&sgt); + return -ENOMEM; + } + } + + dma_map_sg(dev, sgt.sgl, sgt.nents, DMA_BIDIRECTIONAL); + + *bo->base.sgt = sgt; + + if (vm) { + ret = lima_vm_map_bo(vm, bo, old_size >> PAGE_SHIFT); + if (ret) + return ret; + } + + bo->heap_size = new_size; + return 0; +} + int lima_gem_create_handle(struct drm_device *dev, struct drm_file *file, u32 size, u32 flags, u32 *handle) { @@ -22,7 +101,8 @@ int lima_gem_create_handle(struct drm_device *dev, struct drm_file *file, gfp_t mask; struct drm_gem_shmem_object *shmem; struct drm_gem_object *obj; - struct sg_table *sgt; + struct lima_bo *bo; + bool is_heap = flags & LIMA_BO_FLAG_HEAP; shmem = drm_gem_shmem_create(dev, size); if (IS_ERR(shmem)) @@ -36,10 +116,18 @@ int lima_gem_create_handle(struct drm_device *dev, struct drm_file *file, mask |= __GFP_DMA32; mapping_set_gfp_mask(obj->filp->f_mapping, mask); - sgt = drm_gem_shmem_get_pages_sgt(obj); - if (IS_ERR(sgt)) { - err = PTR_ERR(sgt); - goto out; + if (is_heap) { + bo = to_lima_bo(obj); + err = lima_heap_alloc(bo, NULL); + if (err) + goto out; + } else { + struct sg_table *sgt = drm_gem_shmem_get_pages_sgt(obj); + + if (IS_ERR(sgt)) { + err = PTR_ERR(sgt); + goto out; + } } err = drm_gem_handle_create(file, obj, handle); @@ -79,17 +167,47 @@ static void lima_gem_object_close(struct drm_gem_object *obj, struct drm_file *f lima_vm_bo_del(vm, bo); } +static int lima_gem_pin(struct drm_gem_object *obj) +{ + struct lima_bo *bo = to_lima_bo(obj); + + if (bo->heap_size) + return -EINVAL; + + return drm_gem_shmem_pin(obj); +} + +static void *lima_gem_vmap(struct drm_gem_object *obj) +{ + struct lima_bo *bo = to_lima_bo(obj); + + if (bo->heap_size) + return ERR_PTR(-EINVAL); + + return drm_gem_shmem_vmap(obj); +} + +static int lima_gem_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma) +{ + struct lima_bo *bo = to_lima_bo(obj); + + if (bo->heap_size) + return -EINVAL; + + return drm_gem_shmem_mmap(obj, vma); +} + static const struct drm_gem_object_funcs lima_gem_funcs = { .free = lima_gem_free_object, .open = lima_gem_object_open, .close = lima_gem_object_close, .print_info = drm_gem_shmem_print_info, - .pin = drm_gem_shmem_pin, + .pin = lima_gem_pin, .unpin = drm_gem_shmem_unpin, .get_sg_table = drm_gem_shmem_get_sg_table, - .vmap = drm_gem_shmem_vmap, + .vmap = lima_gem_vmap, .vunmap = drm_gem_shmem_vunmap, - .mmap = drm_gem_shmem_mmap, + .mmap = lima_gem_mmap, }; struct drm_gem_object *lima_gem_create_object(struct drm_device *dev, size_t size) diff --git a/drivers/gpu/drm/lima/lima_gem.h b/drivers/gpu/drm/lima/lima_gem.h index 1800feb3e47f..ccea06142f4b 100644 --- a/drivers/gpu/drm/lima/lima_gem.h +++ b/drivers/gpu/drm/lima/lima_gem.h @@ -7,12 +7,15 @@ #include struct lima_submit; +struct lima_vm; struct lima_bo { struct drm_gem_shmem_object base; struct mutex lock; struct list_head va; + + size_t heap_size; }; static inline struct lima_bo * @@ -31,6 +34,7 @@ static inline struct dma_resv *lima_bo_resv(struct lima_bo *bo) return bo->base.base.resv; } +int lima_heap_alloc(struct lima_bo *bo, struct lima_vm *vm); struct drm_gem_object *lima_gem_create_object(struct drm_device *dev, size_t size); int lima_gem_create_handle(struct drm_device *dev, struct drm_file *file, u32 size, u32 flags, u32 *handle); diff --git a/drivers/gpu/drm/lima/lima_vm.c b/drivers/gpu/drm/lima/lima_vm.c index 2e513841de6c..5b92fb82674a 100644 --- a/drivers/gpu/drm/lima/lima_vm.c +++ b/drivers/gpu/drm/lima/lima_vm.c @@ -155,6 +155,7 @@ err_out0: void lima_vm_bo_del(struct lima_vm *vm, struct lima_bo *bo) { struct lima_bo_va *bo_va; + u32 size; mutex_lock(&bo->lock); @@ -166,8 +167,9 @@ void lima_vm_bo_del(struct lima_vm *vm, struct lima_bo *bo) mutex_lock(&vm->lock); + size = bo->heap_size ? bo->heap_size : bo_va->node.size; lima_vm_unmap_range(vm, bo_va->node.start, - bo_va->node.start + bo_va->node.size - 1); + bo_va->node.start + size - 1); drm_mm_remove_node(&bo_va->node); diff --git a/include/uapi/drm/lima_drm.h b/include/uapi/drm/lima_drm.h index 95a00fb867e6..1ec58d652a5a 100644 --- a/include/uapi/drm/lima_drm.h +++ b/include/uapi/drm/lima_drm.h @@ -32,12 +32,19 @@ struct drm_lima_get_param { __u64 value; /* out, parameter value */ }; +/* + * heap buffer dynamically increase backup memory size when GP task fail + * due to lack of heap memory. size field of heap buffer is an up bound of + * the backup memory which can be set to a fairly large value. + */ +#define LIMA_BO_FLAG_HEAP (1 << 0) + /** * create a buffer for used by GPU */ struct drm_lima_gem_create { __u32 size; /* in, buffer size */ - __u32 flags; /* in, currently no flags, must be zero */ + __u32 flags; /* in, buffer flags */ __u32 handle; /* out, GEM buffer handle */ __u32 pad; /* pad, must be zero */ }; -- cgit v1.2.3 From 88be76cdafc7e60e2e4ed883bfe7e8dd7f35fa3a Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 25 Feb 2020 19:22:05 +0000 Subject: drm/i915: Allow userspace to specify ringsize on construction No good reason why we must always use a static ringsize, so let userspace select one during construction. Link: https://github.com/intel/compute-runtime/pull/261 Signed-off-by: Chris Wilson Cc: Joonas Lahtinen Cc: Steve Carbonari Reviewed-by: Janusz Krzysztofik Link: https://patchwork.freedesktop.org/patch/msgid/20200225192206.1107336-2-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/Makefile | 1 + drivers/gpu/drm/i915/gem/i915_gem_context.c | 110 ++++++++++++++++++++++++-- drivers/gpu/drm/i915/gt/intel_context_param.c | 63 +++++++++++++++ drivers/gpu/drm/i915/gt/intel_context_param.h | 14 ++++ drivers/gpu/drm/i915/gt/intel_lrc.c | 1 + include/uapi/drm/i915_drm.h | 21 +++++ 6 files changed, 202 insertions(+), 8 deletions(-) create mode 100644 drivers/gpu/drm/i915/gt/intel_context_param.c create mode 100644 drivers/gpu/drm/i915/gt/intel_context_param.h (limited to 'include/uapi') diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index bc28c31c4f78..9db81b9ac0f3 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile @@ -82,6 +82,7 @@ gt-y += \ gt/gen8_ppgtt.o \ gt/intel_breadcrumbs.o \ gt/intel_context.o \ + gt/intel_context_param.o \ gt/intel_context_sseu.o \ gt/intel_engine_cs.o \ gt/intel_engine_heartbeat.o \ diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context.c b/drivers/gpu/drm/i915/gem/i915_gem_context.c index adcebf22a3d3..b24ee8e104cf 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_context.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_context.c @@ -71,6 +71,7 @@ #include "gt/gen6_ppgtt.h" #include "gt/intel_context.h" +#include "gt/intel_context_param.h" #include "gt/intel_engine_heartbeat.h" #include "gt/intel_engine_user.h" #include "gt/intel_ring.h" @@ -668,23 +669,30 @@ err_free: return ERR_PTR(err); } -static void +static int context_apply_all(struct i915_gem_context *ctx, - void (*fn)(struct intel_context *ce, void *data), + int (*fn)(struct intel_context *ce, void *data), void *data) { struct i915_gem_engines_iter it; struct intel_context *ce; + int err = 0; - for_each_gem_engine(ce, i915_gem_context_lock_engines(ctx), it) - fn(ce, data); + for_each_gem_engine(ce, i915_gem_context_lock_engines(ctx), it) { + err = fn(ce, data); + if (err) + break; + } i915_gem_context_unlock_engines(ctx); + + return err; } -static void __apply_ppgtt(struct intel_context *ce, void *vm) +static int __apply_ppgtt(struct intel_context *ce, void *vm) { i915_vm_put(ce->vm); ce->vm = i915_vm_get(vm); + return 0; } static struct i915_address_space * @@ -722,9 +730,10 @@ static void __set_timeline(struct intel_timeline **dst, intel_timeline_put(old); } -static void __apply_timeline(struct intel_context *ce, void *timeline) +static int __apply_timeline(struct intel_context *ce, void *timeline) { __set_timeline(&ce->timeline, timeline); + return 0; } static void __assign_timeline(struct i915_gem_context *ctx, @@ -1215,6 +1224,63 @@ out: return err; } +static int __apply_ringsize(struct intel_context *ce, void *sz) +{ + return intel_context_set_ring_size(ce, (unsigned long)sz); +} + +static int set_ringsize(struct i915_gem_context *ctx, + struct drm_i915_gem_context_param *args) +{ + if (!HAS_LOGICAL_RING_CONTEXTS(ctx->i915)) + return -ENODEV; + + if (args->size) + return -EINVAL; + + if (!IS_ALIGNED(args->value, I915_GTT_PAGE_SIZE)) + return -EINVAL; + + if (args->value < I915_GTT_PAGE_SIZE) + return -EINVAL; + + if (args->value > 128 * I915_GTT_PAGE_SIZE) + return -EINVAL; + + return context_apply_all(ctx, + __apply_ringsize, + __intel_context_ring_size(args->value)); +} + +static int __get_ringsize(struct intel_context *ce, void *arg) +{ + long sz; + + sz = intel_context_get_ring_size(ce); + GEM_BUG_ON(sz > INT_MAX); + + return sz; /* stop on first engine */ +} + +static int get_ringsize(struct i915_gem_context *ctx, + struct drm_i915_gem_context_param *args) +{ + int sz; + + if (!HAS_LOGICAL_RING_CONTEXTS(ctx->i915)) + return -ENODEV; + + if (args->size) + return -EINVAL; + + sz = context_apply_all(ctx, __get_ringsize, NULL); + if (sz < 0) + return sz; + + args->value = sz; + return 0; +} + static int user_to_context_sseu(struct drm_i915_private *i915, const struct drm_i915_gem_context_param_sseu *user, @@ -1852,17 +1918,19 @@ set_persistence(struct i915_gem_context *ctx, return __context_set_persistence(ctx, args->value); } -static void __apply_priority(struct intel_context *ce, void *arg) +static int __apply_priority(struct intel_context *ce, void *arg) { struct i915_gem_context *ctx = arg; if (!intel_engine_has_semaphores(ce->engine)) - return; + return 0; if (ctx->sched.priority >= I915_PRIORITY_NORMAL) intel_context_set_use_semaphores(ce); else intel_context_clear_use_semaphores(ce); + + return 0; } static int set_priority(struct i915_gem_context *ctx, @@ -1955,6 +2023,10 @@ static int ctx_setparam(struct drm_i915_file_private *fpriv, ret = set_persistence(ctx, args); break; + case I915_CONTEXT_PARAM_RINGSIZE: + ret = set_ringsize(ctx, args); + break; + case I915_CONTEXT_PARAM_BAN_PERIOD: default: ret = -EINVAL; @@ -1983,6 +2055,18 @@ static int create_setparam(struct i915_user_extension __user *ext, void *data) return ctx_setparam(arg->fpriv, arg->ctx, &local.param); } +static int copy_ring_size(struct intel_context *dst, + struct intel_context *src) +{ + long sz; + + sz = intel_context_get_ring_size(src); + if (sz < 0) + return sz; + + return intel_context_set_ring_size(dst, sz); +} + static int clone_engines(struct i915_gem_context *dst, struct i915_gem_context *src) { @@ -2026,6 +2110,12 @@ static int clone_engines(struct i915_gem_context *dst, } intel_context_set_gem(clone->engines[n], dst); + + /* Copy across the preferred ringsize */ + if (copy_ring_size(clone->engines[n], e->engines[n])) { + __free_engines(clone, n + 1); + goto err_unlock; + } } clone->num_engines = n; @@ -2388,6 +2478,10 @@ int i915_gem_context_getparam_ioctl(struct drm_device *dev, void *data, args->value = i915_gem_context_is_persistent(ctx); break; + case I915_CONTEXT_PARAM_RINGSIZE: + ret = get_ringsize(ctx, args); + break; + case I915_CONTEXT_PARAM_BAN_PERIOD: default: ret = -EINVAL; diff --git a/drivers/gpu/drm/i915/gt/intel_context_param.c b/drivers/gpu/drm/i915/gt/intel_context_param.c new file mode 100644 index 000000000000..65dcd090245d --- /dev/null +++ b/drivers/gpu/drm/i915/gt/intel_context_param.c @@ -0,0 +1,63 @@ +// SPDX-License-Identifier: MIT +/* + * Copyright © 2019 Intel Corporation + */ + +#include "i915_active.h" +#include "intel_context.h" +#include "intel_context_param.h" +#include "intel_ring.h" + +int intel_context_set_ring_size(struct intel_context *ce, long sz) +{ + int err; + + if (intel_context_lock_pinned(ce)) + return -EINTR; + + err = i915_active_wait(&ce->active); + if (err < 0) + goto unlock; + + if (intel_context_is_pinned(ce)) { + err = -EBUSY; /* In active use, come back later! */ + goto unlock; + } + + if (test_bit(CONTEXT_ALLOC_BIT, &ce->flags)) { + struct intel_ring *ring; + + /* Replace the existing ringbuffer */ + ring = intel_engine_create_ring(ce->engine, sz); + if (IS_ERR(ring)) { + err = PTR_ERR(ring); + goto unlock; + } + + intel_ring_put(ce->ring); + ce->ring = ring; + + /* Context image will be updated on next pin */ + } else { + ce->ring = __intel_context_ring_size(sz); + } + +unlock: + intel_context_unlock_pinned(ce); + return err; +} + +long intel_context_get_ring_size(struct intel_context *ce) +{ + long sz = (unsigned long)READ_ONCE(ce->ring); + + if (test_bit(CONTEXT_ALLOC_BIT, &ce->flags)) { + if (intel_context_lock_pinned(ce)) + return -EINTR; + + sz = ce->ring->size; + intel_context_unlock_pinned(ce); + } + + return sz; +} diff --git a/drivers/gpu/drm/i915/gt/intel_context_param.h b/drivers/gpu/drm/i915/gt/intel_context_param.h new file mode 100644 index 000000000000..f053d8633fe2 --- /dev/null +++ b/drivers/gpu/drm/i915/gt/intel_context_param.h @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: MIT */ +/* + * Copyright © 2019 Intel Corporation + */ + +#ifndef INTEL_CONTEXT_PARAM_H +#define INTEL_CONTEXT_PARAM_H + +struct intel_context; + +int intel_context_set_ring_size(struct intel_context *ce, long sz); +long intel_context_get_ring_size(struct intel_context *ce); + +#endif /* INTEL_CONTEXT_PARAM_H */ diff --git a/drivers/gpu/drm/i915/gt/intel_lrc.c b/drivers/gpu/drm/i915/gt/intel_lrc.c index 47561dc29304..39b0125b7143 100644 --- a/drivers/gpu/drm/i915/gt/intel_lrc.c +++ b/drivers/gpu/drm/i915/gt/intel_lrc.c @@ -2966,6 +2966,7 @@ __execlists_update_reg_state(const struct intel_context *ce, regs[CTX_RING_START] = i915_ggtt_offset(ring->vma); regs[CTX_RING_HEAD] = head; regs[CTX_RING_TAIL] = ring->tail; + regs[CTX_RING_CTL] = RING_CTL_SIZE(ring->size) | RING_VALID; /* RPCS */ if (engine->class == RENDER_CLASS) { diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h index 829c0a48577f..2813e579b480 100644 --- a/include/uapi/drm/i915_drm.h +++ b/include/uapi/drm/i915_drm.h @@ -1619,6 +1619,27 @@ struct drm_i915_gem_context_param { * By default, new contexts allow persistence. */ #define I915_CONTEXT_PARAM_PERSISTENCE 0xb + +/* + * I915_CONTEXT_PARAM_RINGSIZE: + * + * Sets the size of the CS ringbuffer to use for logical ring contexts. This + * applies a limit of how many batches can be queued to HW before the caller + * is blocked due to lack of space for more commands. + * + * Only reliably possible to be set prior to first use, i.e. during + * construction. At any later point, the current execution must be flushed as + * the ring can only be changed while the context is idle. Note, the ringsize + * can be specified as a constructor property, see + * I915_CONTEXT_CREATE_EXT_SETPARAM, but can also be set later if required. + * + * Only applies to the current set of engine and lost when those engines + * are replaced by a new mapping (see I915_CONTEXT_PARAM_ENGINES). + * + * Must be between 4 - 512 KiB, in intervals of page size [4 KiB]. + * Default is 16 KiB. + */ +#define I915_CONTEXT_PARAM_RINGSIZE 0xc /* Must be kept compact -- no holes and well documented */ __u64 value; -- cgit v1.2.3 From fa5bde8056cfb837a097785edb1e92f0985778ed Mon Sep 17 00:00:00 2001 From: Yong Zhao Date: Fri, 6 Mar 2020 14:33:39 -0500 Subject: drm/amdgpu: Use better names to reflect it is CP MQD buffer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add "CP" to AMDGPU_GEM_CREATE_MQD_GFX9 to indicate it is only for CP MQD buffer. Signed-off-by: Yong Zhao Acked-by: Christian König Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c | 6 +++--- drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 7 +++++-- include/uapi/drm/amdgpu_drm.h | 5 +++-- 3 files changed, 11 insertions(+), 7 deletions(-) (limited to 'include/uapi') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c index bc2e72a66db9..726c91ab6761 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c @@ -224,7 +224,7 @@ void amdgpu_amdkfd_gpu_reset(struct kgd_dev *kgd) int amdgpu_amdkfd_alloc_gtt_mem(struct kgd_dev *kgd, size_t size, void **mem_obj, uint64_t *gpu_addr, - void **cpu_ptr, bool mqd_gfx9) + void **cpu_ptr, bool cp_mqd_gfx9) { struct amdgpu_device *adev = (struct amdgpu_device *)kgd; struct amdgpu_bo *bo = NULL; @@ -240,8 +240,8 @@ int amdgpu_amdkfd_alloc_gtt_mem(struct kgd_dev *kgd, size_t size, bp.type = ttm_bo_type_kernel; bp.resv = NULL; - if (mqd_gfx9) - bp.flags |= AMDGPU_GEM_CREATE_MQD_GFX9; + if (cp_mqd_gfx9) + bp.flags |= AMDGPU_GEM_CREATE_CP_MQD_GFX9; r = amdgpu_bo_create(adev, &bp, &bo); if (r) { diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c index a470ba576867..c10ae1cdc1b9 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c @@ -1028,7 +1028,7 @@ int amdgpu_ttm_gart_bind(struct amdgpu_device *adev, struct amdgpu_ttm_tt *gtt = (void *)ttm; int r; - if (abo->flags & AMDGPU_GEM_CREATE_MQD_GFX9) { + if (abo->flags & AMDGPU_GEM_CREATE_CP_MQD_GFX9) { uint64_t page_idx = 1; r = amdgpu_gart_bind(adev, gtt->offset, page_idx, @@ -1036,7 +1036,10 @@ int amdgpu_ttm_gart_bind(struct amdgpu_device *adev, if (r) goto gart_bind_fail; - /* Patch mtype of the second part BO */ + /* The memory type of the first page defaults to UC. Now + * modify the memory type to NC from the second page of + * the BO onward. + */ flags &= ~AMDGPU_PTE_MTYPE_VG10_MASK; flags |= AMDGPU_PTE_MTYPE_VG10(AMDGPU_MTYPE_NC); diff --git a/include/uapi/drm/amdgpu_drm.h b/include/uapi/drm/amdgpu_drm.h index ac3879829bb5..65f69723cbdc 100644 --- a/include/uapi/drm/amdgpu_drm.h +++ b/include/uapi/drm/amdgpu_drm.h @@ -125,9 +125,10 @@ extern "C" { /* Flag that BO sharing will be explicitly synchronized */ #define AMDGPU_GEM_CREATE_EXPLICIT_SYNC (1 << 7) /* Flag that indicates allocating MQD gart on GFX9, where the mtype - * for the second page onward should be set to NC. + * for the second page onward should be set to NC. It should never + * be used by user space applications. */ -#define AMDGPU_GEM_CREATE_MQD_GFX9 (1 << 8) +#define AMDGPU_GEM_CREATE_CP_MQD_GFX9 (1 << 8) /* Flag that BO may contain sensitive data that must be wiped before * releasing the memory */ -- cgit v1.2.3 From 2a50f06d639bc6d21e855296c2fa511b080f9a79 Mon Sep 17 00:00:00 2001 From: Deepak Rawat Date: Tue, 30 Apr 2019 13:04:55 -0700 Subject: drm/vmwgfx: Add surface define v4 command MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Surface define v4 added new member buffer_byte_stride. With this patch add buffer_byte_stride in surface metadata and create surface using new command if support is available. Also with this patch replace device specific data types with kernel types. Signed-off-by: Deepak Rawat Reviewed-by: Thomas Hellström (VMware) Reviewed-by: Roland Scheidegger Signed-off-by: Roland Scheidegger --- drivers/gpu/drm/vmwgfx/vmwgfx_drv.h | 2 ++ drivers/gpu/drm/vmwgfx/vmwgfx_surface.c | 36 +++++++++++++++++++++++++++++++-- include/uapi/drm/vmwgfx_drm.h | 12 ++++++----- 3 files changed, 43 insertions(+), 7 deletions(-) (limited to 'include/uapi') diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h index 326d1dd58bc5..0447be87697e 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h @@ -238,6 +238,7 @@ struct vmw_surface_offset; * @array_size: Number of array elements for a 1D/2D texture. For cubemap texture number of faces * array_size. This should be 0 for pre SM4 device. + * @buffer_byte_stride: Buffer byte stride. * @num_sizes: Size of @sizes. For GB surface this should always be 1. * @base_size: Surface dimension. * @sizes: Array representing mip sizes. Legacy only. @@ -255,6 +256,7 @@ struct vmw_surface_metadata { u32 autogen_filter; u32 array_size; u32 num_sizes; + u32 buffer_byte_stride; struct drm_vmw_size base_size; struct drm_vmw_size *sizes; bool scanout; diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c b/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c index 6c907b147e97..7ef51fa84b01 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c @@ -1082,6 +1082,10 @@ static int vmw_gb_surface_create(struct vmw_resource *res) SVGA3dCmdHeader header; SVGA3dCmdDefineGBSurface_v3 body; } *cmd3; + struct { + SVGA3dCmdHeader header; + SVGA3dCmdDefineGBSurface_v4 body; + } *cmd4; if (likely(res->id != -1)) return 0; @@ -1098,7 +1102,11 @@ static int vmw_gb_surface_create(struct vmw_resource *res) goto out_no_fifo; } - if (has_sm4_1_context(dev_priv) && metadata->array_size > 0) { + if (has_sm5_context(dev_priv) && metadata->array_size > 0) { + cmd_id = SVGA_3D_CMD_DEFINE_GB_SURFACE_V4; + cmd_len = sizeof(cmd4->body); + submit_len = sizeof(*cmd4); + } else if (has_sm4_1_context(dev_priv) && metadata->array_size > 0) { cmd_id = SVGA_3D_CMD_DEFINE_GB_SURFACE_V3; cmd_len = sizeof(cmd3->body); submit_len = sizeof(*cmd3); @@ -1116,12 +1124,29 @@ static int vmw_gb_surface_create(struct vmw_resource *res) cmd = VMW_FIFO_RESERVE(dev_priv, submit_len); cmd2 = (typeof(cmd2))cmd; cmd3 = (typeof(cmd3))cmd; + cmd4 = (typeof(cmd4))cmd; if (unlikely(!cmd)) { ret = -ENOMEM; goto out_no_fifo; } - if (has_sm4_1_context(dev_priv) && metadata->array_size > 0) { + if (has_sm5_context(dev_priv) && metadata->array_size > 0) { + cmd4->header.id = cmd_id; + cmd4->header.size = cmd_len; + cmd4->body.sid = srf->res.id; + cmd4->body.surfaceFlags = metadata->flags; + cmd4->body.format = metadata->format; + cmd4->body.numMipLevels = metadata->mip_levels[0]; + cmd4->body.multisampleCount = metadata->multisample_count; + cmd4->body.multisamplePattern = metadata->multisample_pattern; + cmd4->body.qualityLevel = metadata->quality_level; + cmd4->body.autogenFilter = metadata->autogen_filter; + cmd4->body.size.width = metadata->base_size.width; + cmd4->body.size.height = metadata->base_size.height; + cmd4->body.size.depth = metadata->base_size.depth; + cmd4->body.arraySize = metadata->array_size; + cmd4->body.bufferByteStride = metadata->buffer_byte_stride; + } else if (has_sm4_1_context(dev_priv) && metadata->array_size > 0) { cmd3->header.id = cmd_id; cmd3->header.size = cmd_len; cmd3->body.sid = srf->res.id; @@ -1341,6 +1366,7 @@ int vmw_gb_surface_define_ioctl(struct drm_device *dev, void *data, req_ext.svga3d_flags_upper_32_bits = 0; req_ext.multisample_pattern = SVGA3D_MS_PATTERN_NONE; req_ext.quality_level = SVGA3D_MS_QUALITY_NONE; + req_ext.buffer_byte_stride = 0; req_ext.must_be_zero = 0; return vmw_gb_surface_define_internal(dev, &req_ext, rep, file_priv); @@ -1467,6 +1493,11 @@ vmw_gb_surface_define_internal(struct drm_device *dev, } } + if (req->buffer_byte_stride > 0 && !has_sm5_context(dev_priv)) { + VMW_DEBUG_USER("SM5 surface not supported.\n"); + return -EINVAL; + } + if ((svga3d_flags_64 & SVGA3D_SURFACE_MULTISAMPLE) && req->base.multisample_count == 0) { VMW_DEBUG_USER("Invalid sample count.\n"); @@ -1491,6 +1522,7 @@ vmw_gb_surface_define_internal(struct drm_device *dev, metadata.multisample_pattern = req->multisample_pattern; metadata.quality_level = req->quality_level; metadata.array_size = req->base.array_size; + metadata.buffer_byte_stride = req->buffer_byte_stride; metadata.num_sizes = 1; metadata.base_size = req->base.base_size; metadata.scanout = req->base.drm_surface_flags & diff --git a/include/uapi/drm/vmwgfx_drm.h b/include/uapi/drm/vmwgfx_drm.h index fcb741e3068f..8cd4b321597c 100644 --- a/include/uapi/drm/vmwgfx_drm.h +++ b/include/uapi/drm/vmwgfx_drm.h @@ -1133,7 +1133,7 @@ struct drm_vmw_handle_close_arg { * svga3d surface flags split into 2, upper half and lower half. */ enum drm_vmw_surface_version { - drm_vmw_gb_surface_v1 + drm_vmw_gb_surface_v1, }; /** @@ -1144,6 +1144,7 @@ enum drm_vmw_surface_version { * @svga3d_flags_upper_32_bits: Upper 32 bits of svga3d flags. * @multisample_pattern: Multisampling pattern when msaa is supported. * @quality_level: Precision settings for each sample. + * @buffer_byte_stride: Buffer byte stride. * @must_be_zero: Reserved for future usage. * * Input argument to the DRM_VMW_GB_SURFACE_CREATE_EXT Ioctl. @@ -1152,10 +1153,11 @@ enum drm_vmw_surface_version { struct drm_vmw_gb_surface_create_ext_req { struct drm_vmw_gb_surface_create_req base; enum drm_vmw_surface_version version; - uint32_t svga3d_flags_upper_32_bits; - SVGA3dMSPattern multisample_pattern; - SVGA3dMSQualityLevel quality_level; - uint64_t must_be_zero; + __u32 svga3d_flags_upper_32_bits; + __u32 multisample_pattern; + __u32 quality_level; + __u32 buffer_byte_stride; + __u32 must_be_zero; }; /** -- cgit v1.2.3 From f0fce23384dad01ae65ba30552f91f6cb76ee56f Mon Sep 17 00:00:00 2001 From: Deepak Rawat Date: Thu, 13 Dec 2018 14:23:46 -0800 Subject: drm/vmwgfx: Add SM5 param for userspace MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a new param for user-space to determine if kernel module is SM5 capable. Signed-off-by: Deepak Rawat Reviewed-by: Thomas Hellström (VMware) Reviewed-by: Roland Scheidegger Signed-off-by: Roland Scheidegger --- drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c | 3 +++ include/uapi/drm/vmwgfx_drm.h | 4 ++++ 2 files changed, 7 insertions(+) (limited to 'include/uapi') diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c index 0af42875ba4e..f681b7b4df1b 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c @@ -119,6 +119,9 @@ int vmw_getparam_ioctl(struct drm_device *dev, void *data, case DRM_VMW_PARAM_SM4_1: param->value = has_sm4_1_context(dev_priv); break; + case DRM_VMW_PARAM_SM5: + param->value = has_sm5_context(dev_priv); + break; default: return -EINVAL; } diff --git a/include/uapi/drm/vmwgfx_drm.h b/include/uapi/drm/vmwgfx_drm.h index 8cd4b321597c..02e917507479 100644 --- a/include/uapi/drm/vmwgfx_drm.h +++ b/include/uapi/drm/vmwgfx_drm.h @@ -86,6 +86,9 @@ extern "C" { * * DRM_VMW_PARAM_SM4_1 * SM4_1 support is enabled. + * + * DRM_VMW_PARAM_SM5 + * SM5 support is enabled. */ #define DRM_VMW_PARAM_NUM_STREAMS 0 @@ -103,6 +106,7 @@ extern "C" { #define DRM_VMW_PARAM_DX 12 #define DRM_VMW_PARAM_HW_CAPS2 13 #define DRM_VMW_PARAM_SM4_1 14 +#define DRM_VMW_PARAM_SM5 15 /** * enum drm_vmw_handle_type - handle type for ref ioctls -- cgit v1.2.3