[PATCH] drm/i915: Add fb_mmap
Nirmoy Das
nirmoy.das at intel.com
Tue Mar 7 04:36:52 UTC 2023
Signed-off-by: Nirmoy Das <nirmoy.das at intel.com>
---
drivers/gpu/drm/i915/display/intel_fbdev.c | 24 +++++++
drivers/gpu/drm/i915/gem/i915_gem_mman.c | 75 ++++++++++++++++++++++
drivers/gpu/drm/i915/gem/i915_gem_mman.h | 2 +-
3 files changed, 100 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/i915/display/intel_fbdev.c b/drivers/gpu/drm/i915/display/intel_fbdev.c
index 3659350061a7..f697951b4e4a 100644
--- a/drivers/gpu/drm/i915/display/intel_fbdev.c
+++ b/drivers/gpu/drm/i915/display/intel_fbdev.c
@@ -40,8 +40,10 @@
#include <drm/drm_crtc.h>
#include <drm/drm_fb_helper.h>
#include <drm/drm_fourcc.h>
+#include <drm/drm_gem_framebuffer_helper.h>
#include "gem/i915_gem_lmem.h"
+#include "gem/i915_gem_mman.h"
#include "i915_drv.h"
#include "intel_display_types.h"
@@ -120,6 +122,27 @@ static int intel_fbdev_pan_display(struct fb_var_screeninfo *var,
return ret;
}
+#define to_intel_fbdev(x) container_of(x, struct intel_fbdev, helper)
+static int intel_fbdev_mmap(struct fb_info *info, struct vm_area_struct *vma)
+{
+ struct intel_fbdev *fbdev = to_intel_fbdev(info->par);
+ struct drm_gem_object *bo = drm_gem_fb_get_obj(&fbdev->fb->base, 0);
+ struct drm_i915_gem_object *obj = to_intel_bo(bo);
+ struct drm_device *dev = fbdev->helper.dev;
+ struct intel_memory_region *mr = READ_ONCE(obj->mm.region);
+
+ vma->vm_page_prot =
+ pgprot_writecombine(vm_get_page_prot(vma->vm_flags));
+
+ if (mr && mr->type == INTEL_MEMORY_STOLEN_SYSTEM) {
+ drm_info(dev, "%s doing stolen mmap\n", __func__);
+ return vm_iomap_memory(vma, info->fix.smem_start,
+ info->fix.smem_len);
+ }
+
+ drm_info(dev, "%s doing regular mmap for %p\n", __func__, obj);
+ return i915_gem_object_mmap(obj, vma);
+}
static const struct fb_ops intelfb_ops = {
.owner = THIS_MODULE,
DRM_FB_HELPER_DEFAULT_OPS,
@@ -131,6 +154,7 @@ static const struct fb_ops intelfb_ops = {
.fb_imageblit = drm_fb_helper_cfb_imageblit,
.fb_pan_display = intel_fbdev_pan_display,
.fb_blank = intel_fbdev_blank,
+ .fb_mmap = intel_fbdev_mmap,
};
static int intelfb_alloc(struct drm_fb_helper *helper,
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_mman.c b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
index d3c1dee16af2..6d87bad084c1 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_mman.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
@@ -1043,6 +1043,81 @@ int i915_gem_mmap(struct file *filp, struct vm_area_struct *vma)
return 0;
}
+int i915_gem_object_mmap(struct drm_i915_gem_object *obj, struct vm_area_struct *vma)
+{
+ struct drm_i915_private *i915 = to_i915(obj->base.dev);
+ struct drm_device *dev = &i915->drm;
+ struct i915_mmap_offset *mmo = NULL;
+ struct file *anon;
+
+ if (drm_dev_is_unplugged(dev))
+ return -ENODEV;
+ mmo = mmap_offset_attach(obj, I915_MMAP_TYPE_WC, NULL);
+ printk("i915_gem_object_mmap mmo %p\n", mmo);
+ if (!mmo)
+ return -ENODEV;
+ anon = mmap_singleton(to_i915(dev));
+ if (IS_ERR(anon)) {
+ i915_gem_object_put(obj);
+ return PTR_ERR(anon);
+ }
+
+ vm_flags_set(vma, VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP | VM_IO);
+
+ /*
+ * We keep the ref on mmo->obj, not vm_file, but we require
+ * vma->vm_file->f_mapping, see vma_link(), for later revocation.
+ * Our userspace is accustomed to having per-file resource cleanup
+ * (i.e. contexts, objects and requests) on their close(fd), which
+ * requires avoiding extraneous references to their filp, hence why
+ * we prefer to use an anonymous file for their mmaps.
+ */
+ vma_set_file(vma, anon);
+ /* Drop the initial creation reference, the vma is now holding one. */
+ fput(anon);
+
+ if (obj->ops->mmap_ops) {
+ vma->vm_page_prot = pgprot_decrypted(vm_get_page_prot(vma->vm_flags));
+ vma->vm_ops = obj->ops->mmap_ops;
+ vma->vm_private_data = obj->base.vma_node.driver_private;
+ return 0;
+ }
+
+ vma->vm_private_data = mmo;
+
+ switch (mmo->mmap_type) {
+ case I915_MMAP_TYPE_WC:
+ vma->vm_page_prot =
+ pgprot_writecombine(vm_get_page_prot(vma->vm_flags));
+ vma->vm_ops = &vm_ops_cpu;
+ break;
+
+ case I915_MMAP_TYPE_FIXED:
+ GEM_WARN_ON(1);
+ fallthrough;
+ case I915_MMAP_TYPE_WB:
+ vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
+ vma->vm_ops = &vm_ops_cpu;
+ break;
+
+ case I915_MMAP_TYPE_UC:
+ vma->vm_page_prot =
+ pgprot_noncached(vm_get_page_prot(vma->vm_flags));
+ vma->vm_ops = &vm_ops_cpu;
+ break;
+
+ case I915_MMAP_TYPE_GTT:
+ vma->vm_page_prot =
+ pgprot_writecombine(vm_get_page_prot(vma->vm_flags));
+ vma->vm_ops = &vm_ops_gtt;
+ break;
+ }
+ vma->vm_page_prot = pgprot_decrypted(vma->vm_page_prot);
+
+ return 0;
+}
+
+
#if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
#include "selftests/i915_gem_mman.c"
#endif
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_mman.h b/drivers/gpu/drm/i915/gem/i915_gem_mman.h
index 1fa91b3033b3..59f7d0378d4f 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_mman.h
+++ b/drivers/gpu/drm/i915/gem/i915_gem_mman.h
@@ -29,5 +29,5 @@ void i915_gem_object_release_mmap_gtt(struct drm_i915_gem_object *obj);
void i915_gem_object_runtime_pm_release_mmap_offset(struct drm_i915_gem_object *obj);
void i915_gem_object_release_mmap_offset(struct drm_i915_gem_object *obj);
-
+int i915_gem_object_mmap(struct drm_i915_gem_object *obj, struct vm_area_struct *vma);
#endif
--
2.39.0
More information about the Intel-gfx-trybot
mailing list