diff options
Diffstat (limited to 'drivers/gpu/drm/i915/display/intel_fbdev.c')
-rw-r--r-- | drivers/gpu/drm/i915/display/intel_fbdev.c | 57 |
1 files changed, 37 insertions, 20 deletions
diff --git a/drivers/gpu/drm/i915/display/intel_fbdev.c b/drivers/gpu/drm/i915/display/intel_fbdev.c index 673bcdfb7ff6..3b5690acd720 100644 --- a/drivers/gpu/drm/i915/display/intel_fbdev.c +++ b/drivers/gpu/drm/i915/display/intel_fbdev.c @@ -28,6 +28,7 @@ #include <linux/console.h> #include <linux/delay.h> #include <linux/errno.h> +#include <linux/fb.h> #include <linux/init.h> #include <linux/kernel.h> #include <linux/mm.h> @@ -40,8 +41,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" @@ -67,6 +70,11 @@ struct intel_fbdev { struct mutex hpd_lock; }; +static struct intel_fbdev *to_intel_fbdev(struct drm_fb_helper *fb_helper) +{ + return container_of(fb_helper, struct intel_fbdev, helper); +} + static struct intel_frontbuffer *to_frontbuffer(struct intel_fbdev *ifbdev) { return ifbdev->fb->frontbuffer; @@ -77,11 +85,13 @@ static void intel_fbdev_invalidate(struct intel_fbdev *ifbdev) intel_frontbuffer_invalidate(to_frontbuffer(ifbdev), ORIGIN_CPU); } +FB_GEN_DEFAULT_DEFERRED_IO_OPS(intel_fbdev, + drm_fb_helper_damage_range, + drm_fb_helper_damage_area) + static int intel_fbdev_set_par(struct fb_info *info) { - struct drm_fb_helper *fb_helper = info->par; - struct intel_fbdev *ifbdev = - container_of(fb_helper, struct intel_fbdev, helper); + struct intel_fbdev *ifbdev = to_intel_fbdev(info->par); int ret; ret = drm_fb_helper_set_par(info); @@ -93,9 +103,7 @@ static int intel_fbdev_set_par(struct fb_info *info) static int intel_fbdev_blank(int blank, struct fb_info *info) { - struct drm_fb_helper *fb_helper = info->par; - struct intel_fbdev *ifbdev = - container_of(fb_helper, struct intel_fbdev, helper); + struct intel_fbdev *ifbdev = to_intel_fbdev(info->par); int ret; ret = drm_fb_helper_blank(blank, info); @@ -108,9 +116,7 @@ static int intel_fbdev_blank(int blank, struct fb_info *info) static int intel_fbdev_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) { - struct drm_fb_helper *fb_helper = info->par; - struct intel_fbdev *ifbdev = - container_of(fb_helper, struct intel_fbdev, helper); + struct intel_fbdev *ifbdev = to_intel_fbdev(info->par); int ret; ret = drm_fb_helper_pan_display(var, info); @@ -120,24 +126,35 @@ static int intel_fbdev_pan_display(struct fb_var_screeninfo *var, return ret; } +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); + + return i915_gem_fb_mmap(obj, vma); +} + +__diag_push(); +__diag_ignore_all("-Woverride-init", "Allow overriding the default ops"); + static const struct fb_ops intelfb_ops = { .owner = THIS_MODULE, + __FB_DEFAULT_DEFERRED_OPS_RDWR(intel_fbdev), DRM_FB_HELPER_DEFAULT_OPS, .fb_set_par = intel_fbdev_set_par, - .fb_read = drm_fb_helper_cfb_read, - .fb_write = drm_fb_helper_cfb_write, - .fb_fillrect = drm_fb_helper_cfb_fillrect, - .fb_copyarea = drm_fb_helper_cfb_copyarea, - .fb_imageblit = drm_fb_helper_cfb_imageblit, - .fb_pan_display = intel_fbdev_pan_display, .fb_blank = intel_fbdev_blank, + .fb_pan_display = intel_fbdev_pan_display, + __FB_DEFAULT_DEFERRED_OPS_DRAW(intel_fbdev), + .fb_mmap = intel_fbdev_mmap, }; +__diag_pop(); + static int intelfb_alloc(struct drm_fb_helper *helper, struct drm_fb_helper_surface_size *sizes) { - struct intel_fbdev *ifbdev = - container_of(helper, struct intel_fbdev, helper); + struct intel_fbdev *ifbdev = to_intel_fbdev(helper); struct drm_framebuffer *fb; struct drm_device *dev = helper->dev; struct drm_i915_private *dev_priv = to_i915(dev); @@ -163,7 +180,8 @@ static int intelfb_alloc(struct drm_fb_helper *helper, obj = ERR_PTR(-ENODEV); if (HAS_LMEM(dev_priv)) { obj = i915_gem_object_create_lmem(dev_priv, size, - I915_BO_ALLOC_CONTIGUOUS); + I915_BO_ALLOC_CONTIGUOUS | + I915_BO_ALLOC_USER); } else { /* * If the FB is too big, just don't use it since fbdev is not very @@ -193,8 +211,7 @@ static int intelfb_alloc(struct drm_fb_helper *helper, static int intelfb_create(struct drm_fb_helper *helper, struct drm_fb_helper_surface_size *sizes) { - struct intel_fbdev *ifbdev = - container_of(helper, struct intel_fbdev, helper); + struct intel_fbdev *ifbdev = to_intel_fbdev(helper); struct intel_framebuffer *intel_fb = ifbdev->fb; struct drm_device *dev = helper->dev; struct drm_i915_private *dev_priv = to_i915(dev); |