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, 36 insertions, 21 deletions
diff --git a/drivers/gpu/drm/i915/display/intel_fbdev.c b/drivers/gpu/drm/i915/display/intel_fbdev.c index 112aa0447a0d..f76b06293eb9 100644 --- a/drivers/gpu/drm/i915/display/intel_fbdev.c +++ b/drivers/gpu/drm/i915/display/intel_fbdev.c @@ -124,6 +124,8 @@ static const struct fb_ops intelfb_ops = { .owner = THIS_MODULE, 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, @@ -168,14 +170,14 @@ static int intelfb_alloc(struct drm_fb_helper *helper, * important and we should probably use that space with FBC or other * features. */ - if (size * 2 < dev_priv->stolen_usable_size) + if (size * 2 < dev_priv->dsm.usable_size) obj = i915_gem_object_create_stolen(dev_priv, size); if (IS_ERR(obj)) obj = i915_gem_object_create_shmem(dev_priv, size); } if (IS_ERR(obj)) { - drm_err(&dev_priv->drm, "failed to allocate framebuffer\n"); + drm_err(&dev_priv->drm, "failed to allocate framebuffer (%pe)\n", obj); return PTR_ERR(obj); } @@ -254,9 +256,9 @@ static int intelfb_create(struct drm_fb_helper *helper, goto out_unlock; } - info = drm_fb_helper_alloc_fbi(helper); + info = drm_fb_helper_alloc_info(helper); if (IS_ERR(info)) { - drm_err(&dev_priv->drm, "Failed to allocate fb_info\n"); + drm_err(&dev_priv->drm, "Failed to allocate fb_info (%pe)\n", info); ret = PTR_ERR(info); goto out_unpin; } @@ -265,33 +267,26 @@ static int intelfb_create(struct drm_fb_helper *helper, info->fbops = &intelfb_ops; - /* setup aperture base/size for vesafb takeover */ obj = intel_fb_obj(&intel_fb->base); if (i915_gem_object_is_lmem(obj)) { struct intel_memory_region *mem = obj->mm.region; - info->apertures->ranges[0].base = mem->io_start; - info->apertures->ranges[0].size = mem->io_size; - /* Use fbdev's framebuffer from lmem for discrete */ info->fix.smem_start = (unsigned long)(mem->io_start + i915_gem_object_get_dma_address(obj, 0)); info->fix.smem_len = obj->base.size; } else { - info->apertures->ranges[0].base = ggtt->gmadr.start; - info->apertures->ranges[0].size = ggtt->mappable_end; - /* Our framebuffer is the entirety of fbdev's system memory */ info->fix.smem_start = - (unsigned long)(ggtt->gmadr.start + vma->node.start); + (unsigned long)(ggtt->gmadr.start + i915_ggtt_offset(vma)); info->fix.smem_len = vma->size; } vaddr = i915_vma_pin_iomap(vma); if (IS_ERR(vaddr)) { drm_err(&dev_priv->drm, - "Failed to remap framebuffer into virtual memory\n"); + "Failed to remap framebuffer into virtual memory (%pe)\n", vaddr); ret = PTR_ERR(vaddr); goto out_unpin; } @@ -326,8 +321,20 @@ out_unlock: return ret; } +static int intelfb_dirty(struct drm_fb_helper *helper, struct drm_clip_rect *clip) +{ + if (!(clip->x1 < clip->x2 && clip->y1 < clip->y2)) + return 0; + + if (helper->fb->funcs->dirty) + return helper->fb->funcs->dirty(helper->fb, NULL, 0, 0, clip, 1); + + return 0; +} + static const struct drm_fb_helper_funcs intel_fb_helper_funcs = { .fb_probe = intelfb_create, + .fb_dirty = intelfb_dirty, }; static void intel_fbdev_destroy(struct intel_fbdev *ifbdev) @@ -345,6 +352,7 @@ static void intel_fbdev_destroy(struct intel_fbdev *ifbdev) if (ifbdev->fb) drm_framebuffer_remove(&ifbdev->fb->base); + drm_fb_helper_unprepare(&ifbdev->helper); kfree(ifbdev); } @@ -525,10 +533,12 @@ int intel_fbdev_init(struct drm_device *dev) return -ENOMEM; mutex_init(&ifbdev->hpd_lock); - drm_fb_helper_prepare(dev, &ifbdev->helper, &intel_fb_helper_funcs); + drm_fb_helper_prepare(dev, &ifbdev->helper, 32, &intel_fb_helper_funcs); - if (!intel_fbdev_init_bios(dev, ifbdev)) - ifbdev->preferred_bpp = 32; + if (intel_fbdev_init_bios(dev, ifbdev)) + ifbdev->helper.preferred_bpp = ifbdev->preferred_bpp; + else + ifbdev->preferred_bpp = ifbdev->helper.preferred_bpp; ret = drm_fb_helper_init(dev, &ifbdev->helper); if (ret) { @@ -547,8 +557,7 @@ static void intel_fbdev_initial_config(void *data, async_cookie_t cookie) struct intel_fbdev *ifbdev = data; /* Due to peculiar init order wrt to hpd handling this is separate. */ - if (drm_fb_helper_initial_config(&ifbdev->helper, - ifbdev->preferred_bpp)) + if (drm_fb_helper_initial_config(&ifbdev->helper)) intel_fbdev_unregister(to_i915(ifbdev->helper.dev)); } @@ -584,7 +593,7 @@ void intel_fbdev_unregister(struct drm_i915_private *dev_priv) if (!current_is_async()) intel_fbdev_sync(ifbdev); - drm_fb_helper_unregister_fbi(&ifbdev->helper); + drm_fb_helper_unregister_info(&ifbdev->helper); } void intel_fbdev_fini(struct drm_i915_private *dev_priv) @@ -624,10 +633,16 @@ void intel_fbdev_set_suspend(struct drm_device *dev, int state, bool synchronous struct intel_fbdev *ifbdev = dev_priv->display.fbdev.fbdev; struct fb_info *info; - if (!ifbdev || !ifbdev->vma) + if (!ifbdev) + return; + + if (drm_WARN_ON(&dev_priv->drm, !HAS_DISPLAY(dev_priv))) + return; + + if (!ifbdev->vma) goto set_suspend; - info = ifbdev->helper.fbdev; + info = ifbdev->helper.info; if (synchronous) { /* Flush any pending work to turn the console on, and then |