Commit 858fbdbc authored by Dave Airlie's avatar Dave Airlie
Browse files

Merge tag 'drm-intel-fixes-2020-11-13' of...

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: default avatarDave Airlie <airlied@redhat.com>

From: Rodrigo Vivi <rodrigo.vivi@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20201113052551.GA1319429@intel.com
parents 59f7dcd9 5ce6861d
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -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);

+55 −0
Original line number Diff line number Diff line
@@ -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,
};

+2 −1
Original line number Diff line number Diff line
@@ -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;
+6 −26
Original line number Diff line number Diff line
@@ -179,30 +179,6 @@ try_again:
	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);