mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-05 19:24:01 -04:00
Merge tag 'drm-intel-fixes-2020-11-13' of git://anongit.freedesktop.org/drm/drm-intel into drm-fixes
- Pull phys pread/pwrite implementations to the backend (Chris) - Correctly set SFC capability for video engines (Venkata) Signed-off-by: Dave Airlie <airlied@redhat.com> From: Rodrigo Vivi <rodrigo.vivi@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20201113052551.GA1319429@intel.com
This commit is contained in:
@@ -56,6 +56,8 @@ struct drm_i915_gem_object_ops {
|
||||
void (*truncate)(struct drm_i915_gem_object *obj);
|
||||
void (*writeback)(struct drm_i915_gem_object *obj);
|
||||
|
||||
int (*pread)(struct drm_i915_gem_object *obj,
|
||||
const struct drm_i915_gem_pread *arg);
|
||||
int (*pwrite)(struct drm_i915_gem_object *obj,
|
||||
const struct drm_i915_gem_pwrite *arg);
|
||||
|
||||
|
||||
@@ -134,6 +134,58 @@ i915_gem_object_put_pages_phys(struct drm_i915_gem_object *obj,
|
||||
vaddr, dma);
|
||||
}
|
||||
|
||||
static int
|
||||
phys_pwrite(struct drm_i915_gem_object *obj,
|
||||
const struct drm_i915_gem_pwrite *args)
|
||||
{
|
||||
void *vaddr = sg_page(obj->mm.pages->sgl) + args->offset;
|
||||
char __user *user_data = u64_to_user_ptr(args->data_ptr);
|
||||
int err;
|
||||
|
||||
err = i915_gem_object_wait(obj,
|
||||
I915_WAIT_INTERRUPTIBLE |
|
||||
I915_WAIT_ALL,
|
||||
MAX_SCHEDULE_TIMEOUT);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
/*
|
||||
* We manually control the domain here and pretend that it
|
||||
* remains coherent i.e. in the GTT domain, like shmem_pwrite.
|
||||
*/
|
||||
i915_gem_object_invalidate_frontbuffer(obj, ORIGIN_CPU);
|
||||
|
||||
if (copy_from_user(vaddr, user_data, args->size))
|
||||
return -EFAULT;
|
||||
|
||||
drm_clflush_virt_range(vaddr, args->size);
|
||||
intel_gt_chipset_flush(&to_i915(obj->base.dev)->gt);
|
||||
|
||||
i915_gem_object_flush_frontbuffer(obj, ORIGIN_CPU);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
phys_pread(struct drm_i915_gem_object *obj,
|
||||
const struct drm_i915_gem_pread *args)
|
||||
{
|
||||
void *vaddr = sg_page(obj->mm.pages->sgl) + args->offset;
|
||||
char __user *user_data = u64_to_user_ptr(args->data_ptr);
|
||||
int err;
|
||||
|
||||
err = i915_gem_object_wait(obj,
|
||||
I915_WAIT_INTERRUPTIBLE,
|
||||
MAX_SCHEDULE_TIMEOUT);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
drm_clflush_virt_range(vaddr, args->size);
|
||||
if (copy_to_user(user_data, vaddr, args->size))
|
||||
return -EFAULT;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void phys_release(struct drm_i915_gem_object *obj)
|
||||
{
|
||||
fput(obj->base.filp);
|
||||
@@ -144,6 +196,9 @@ static const struct drm_i915_gem_object_ops i915_gem_phys_ops = {
|
||||
.get_pages = i915_gem_object_get_pages_phys,
|
||||
.put_pages = i915_gem_object_put_pages_phys,
|
||||
|
||||
.pread = phys_pread,
|
||||
.pwrite = phys_pwrite,
|
||||
|
||||
.release = phys_release,
|
||||
};
|
||||
|
||||
|
||||
@@ -371,7 +371,8 @@ static void __setup_engine_capabilities(struct intel_engine_cs *engine)
|
||||
* instances.
|
||||
*/
|
||||
if ((INTEL_GEN(i915) >= 11 &&
|
||||
engine->gt->info.vdbox_sfc_access & engine->mask) ||
|
||||
(engine->gt->info.vdbox_sfc_access &
|
||||
BIT(engine->instance))) ||
|
||||
(INTEL_GEN(i915) >= 9 && engine->instance == 0))
|
||||
engine->uabi_capabilities |=
|
||||
I915_VIDEO_AND_ENHANCE_CLASS_CAPABILITY_SFC;
|
||||
|
||||
@@ -179,30 +179,6 @@ int i915_gem_object_unbind(struct drm_i915_gem_object *obj,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
i915_gem_phys_pwrite(struct drm_i915_gem_object *obj,
|
||||
struct drm_i915_gem_pwrite *args,
|
||||
struct drm_file *file)
|
||||
{
|
||||
void *vaddr = sg_page(obj->mm.pages->sgl) + args->offset;
|
||||
char __user *user_data = u64_to_user_ptr(args->data_ptr);
|
||||
|
||||
/*
|
||||
* We manually control the domain here and pretend that it
|
||||
* remains coherent i.e. in the GTT domain, like shmem_pwrite.
|
||||
*/
|
||||
i915_gem_object_invalidate_frontbuffer(obj, ORIGIN_CPU);
|
||||
|
||||
if (copy_from_user(vaddr, user_data, args->size))
|
||||
return -EFAULT;
|
||||
|
||||
drm_clflush_virt_range(vaddr, args->size);
|
||||
intel_gt_chipset_flush(&to_i915(obj->base.dev)->gt);
|
||||
|
||||
i915_gem_object_flush_frontbuffer(obj, ORIGIN_CPU);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
i915_gem_create(struct drm_file *file,
|
||||
struct intel_memory_region *mr,
|
||||
@@ -527,6 +503,12 @@ i915_gem_pread_ioctl(struct drm_device *dev, void *data,
|
||||
|
||||
trace_i915_gem_object_pread(obj, args->offset, args->size);
|
||||
|
||||
ret = -ENODEV;
|
||||
if (obj->ops->pread)
|
||||
ret = obj->ops->pread(obj, args);
|
||||
if (ret != -ENODEV)
|
||||
goto out;
|
||||
|
||||
ret = i915_gem_object_wait(obj,
|
||||
I915_WAIT_INTERRUPTIBLE,
|
||||
MAX_SCHEDULE_TIMEOUT);
|
||||
@@ -866,8 +848,6 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data,
|
||||
if (ret == -EFAULT || ret == -ENOSPC) {
|
||||
if (i915_gem_object_has_struct_page(obj))
|
||||
ret = i915_gem_shmem_pwrite(obj, args);
|
||||
else
|
||||
ret = i915_gem_phys_pwrite(obj, args, file);
|
||||
}
|
||||
|
||||
i915_gem_object_unpin_pages(obj);
|
||||
|
||||
Reference in New Issue
Block a user