| From af442c6b82d7bc0c8140691aa42ab43dd5b4abd8 Mon Sep 17 00:00:00 2001 |
| From: Daniel Vetter <daniel.vetter@ffwll.ch> |
| Date: Tue, 8 Oct 2013 17:44:49 +0200 |
| Subject: drm/i915: rename intel_fb.c to intel_fbdev.c |
| |
| This file is all about the legacy fbdev support. If we want to extract |
| framebuffer functions, we better put those into a separate file. |
| |
| Also rename functions accordingly, only two have used the intel_fb_ |
| prefix anyway. |
| |
| Reviewed-by: Chon Ming Lee <chon.ming.lee@intel.com> |
| Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch> |
| (cherry picked from commit 0632fef669912a63c99c8ce4c2ca10c6ea04f0df) |
| Signed-off-by: Darren Hart <dvhart@linux.intel.com> |
| --- |
| drivers/gpu/drm/i915/Makefile | 2 |
| drivers/gpu/drm/i915/i915_dma.c | 2 |
| drivers/gpu/drm/i915/intel_display.c | 4 |
| drivers/gpu/drm/i915/intel_drv.h | 8 |
| drivers/gpu/drm/i915/intel_fb.c | 323 ----------------------------------- |
| drivers/gpu/drm/i915/intel_fbdev.c | 323 +++++++++++++++++++++++++++++++++++ |
| 6 files changed, 331 insertions(+), 331 deletions(-) |
| rename drivers/gpu/drm/i915/{intel_fb.c => intel_fbdev.c} (98%) |
| |
| --- a/drivers/gpu/drm/i915/Makefile |
| +++ b/drivers/gpu/drm/i915/Makefile |
| @@ -53,7 +53,7 @@ i915-$(CONFIG_COMPAT) += i915_ioc32.o |
| |
| i915-$(CONFIG_ACPI) += intel_acpi.o |
| |
| -i915-$(CONFIG_DRM_I915_FBDEV) += intel_fb.o |
| +i915-$(CONFIG_DRM_I915_FBDEV) += intel_fbdev.o |
| |
| obj-$(CONFIG_DRM_I915) += i915.o |
| |
| --- a/drivers/gpu/drm/i915/i915_dma.c |
| +++ b/drivers/gpu/drm/i915/i915_dma.c |
| @@ -1862,7 +1862,7 @@ void i915_driver_lastclose(struct drm_de |
| return; |
| |
| if (drm_core_check_feature(dev, DRIVER_MODESET)) { |
| - intel_fb_restore_mode(dev); |
| + intel_fbdev_restore_mode(dev); |
| vga_switcheroo_process_delayed_switch(); |
| return; |
| } |
| --- a/drivers/gpu/drm/i915/intel_display.c |
| +++ b/drivers/gpu/drm/i915/intel_display.c |
| @@ -10106,14 +10106,14 @@ intel_user_framebuffer_create(struct drm |
| } |
| |
| #ifndef CONFIG_DRM_I915_FBDEV |
| -static inline void intel_fb_output_poll_changed(struct drm_device *dev) |
| +static inline void intel_fbdev_output_poll_changed(struct drm_device *dev) |
| { |
| } |
| #endif |
| |
| static const struct drm_mode_config_funcs intel_mode_funcs = { |
| .fb_create = intel_user_framebuffer_create, |
| - .output_poll_changed = intel_fb_output_poll_changed, |
| + .output_poll_changed = intel_fbdev_output_poll_changed, |
| }; |
| |
| /* Set up chip specific display functions */ |
| --- a/drivers/gpu/drm/i915/intel_drv.h |
| +++ b/drivers/gpu/drm/i915/intel_drv.h |
| @@ -713,14 +713,14 @@ bool intel_dsi_init(struct drm_device *d |
| void intel_dvo_init(struct drm_device *dev); |
| |
| |
| -/* legacy fbdev emulation in intel_fb.c */ |
| +/* legacy fbdev emulation in intel_fbdev.c */ |
| #ifdef CONFIG_DRM_I915_FBDEV |
| extern int intel_fbdev_init(struct drm_device *dev); |
| extern void intel_fbdev_initial_config(struct drm_device *dev); |
| extern void intel_fbdev_fini(struct drm_device *dev); |
| extern void intel_fbdev_set_suspend(struct drm_device *dev, int state); |
| -extern void intel_fb_output_poll_changed(struct drm_device *dev); |
| -extern void intel_fb_restore_mode(struct drm_device *dev); |
| +extern void intel_fbdev_output_poll_changed(struct drm_device *dev); |
| +extern void intel_fbdev_restore_mode(struct drm_device *dev); |
| #else |
| static inline int intel_fbdev_init(struct drm_device *dev) |
| { |
| @@ -739,7 +739,7 @@ static inline void intel_fbdev_set_suspe |
| { |
| } |
| |
| -static inline void intel_fb_restore_mode(struct drm_device *dev) |
| +static inline void intel_fbdev_restore_mode(struct drm_device *dev) |
| { |
| } |
| #endif |
| --- a/drivers/gpu/drm/i915/intel_fb.c |
| +++ /dev/null |
| @@ -1,323 +0,0 @@ |
| -/* |
| - * Copyright © 2007 David Airlie |
| - * |
| - * Permission is hereby granted, free of charge, to any person obtaining a |
| - * copy of this software and associated documentation files (the "Software"), |
| - * to deal in the Software without restriction, including without limitation |
| - * the rights to use, copy, modify, merge, publish, distribute, sublicense, |
| - * and/or sell copies of the Software, and to permit persons to whom the |
| - * Software is furnished to do so, subject to the following conditions: |
| - * |
| - * The above copyright notice and this permission notice (including the next |
| - * paragraph) shall be included in all copies or substantial portions of the |
| - * Software. |
| - * |
| - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
| - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
| - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
| - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
| - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
| - * DEALINGS IN THE SOFTWARE. |
| - * |
| - * Authors: |
| - * David Airlie |
| - */ |
| - |
| -#include <linux/module.h> |
| -#include <linux/kernel.h> |
| -#include <linux/errno.h> |
| -#include <linux/string.h> |
| -#include <linux/mm.h> |
| -#include <linux/tty.h> |
| -#include <linux/sysrq.h> |
| -#include <linux/delay.h> |
| -#include <linux/fb.h> |
| -#include <linux/init.h> |
| -#include <linux/vga_switcheroo.h> |
| - |
| -#include <drm/drmP.h> |
| -#include <drm/drm_crtc.h> |
| -#include <drm/drm_fb_helper.h> |
| -#include "intel_drv.h" |
| -#include <drm/i915_drm.h> |
| -#include "i915_drv.h" |
| - |
| -static struct fb_ops intelfb_ops = { |
| - .owner = THIS_MODULE, |
| - .fb_check_var = drm_fb_helper_check_var, |
| - .fb_set_par = drm_fb_helper_set_par, |
| - .fb_fillrect = cfb_fillrect, |
| - .fb_copyarea = cfb_copyarea, |
| - .fb_imageblit = cfb_imageblit, |
| - .fb_pan_display = drm_fb_helper_pan_display, |
| - .fb_blank = drm_fb_helper_blank, |
| - .fb_setcmap = drm_fb_helper_setcmap, |
| - .fb_debug_enter = drm_fb_helper_debug_enter, |
| - .fb_debug_leave = drm_fb_helper_debug_leave, |
| -}; |
| - |
| -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 drm_device *dev = helper->dev; |
| - struct drm_i915_private *dev_priv = dev->dev_private; |
| - struct fb_info *info; |
| - struct drm_framebuffer *fb; |
| - struct drm_mode_fb_cmd2 mode_cmd = {}; |
| - struct drm_i915_gem_object *obj; |
| - struct device *device = &dev->pdev->dev; |
| - int size, ret; |
| - |
| - /* we don't do packed 24bpp */ |
| - if (sizes->surface_bpp == 24) |
| - sizes->surface_bpp = 32; |
| - |
| - mode_cmd.width = sizes->surface_width; |
| - mode_cmd.height = sizes->surface_height; |
| - |
| - mode_cmd.pitches[0] = ALIGN(mode_cmd.width * ((sizes->surface_bpp + 7) / |
| - 8), 64); |
| - mode_cmd.pixel_format = drm_mode_legacy_fb_format(sizes->surface_bpp, |
| - sizes->surface_depth); |
| - |
| - size = mode_cmd.pitches[0] * mode_cmd.height; |
| - size = ALIGN(size, PAGE_SIZE); |
| - obj = i915_gem_object_create_stolen(dev, size); |
| - if (obj == NULL) |
| - obj = i915_gem_alloc_object(dev, size); |
| - if (!obj) { |
| - DRM_ERROR("failed to allocate framebuffer\n"); |
| - ret = -ENOMEM; |
| - goto out; |
| - } |
| - |
| - mutex_lock(&dev->struct_mutex); |
| - |
| - /* Flush everything out, we'll be doing GTT only from now on */ |
| - ret = intel_pin_and_fence_fb_obj(dev, obj, NULL); |
| - if (ret) { |
| - DRM_ERROR("failed to pin fb: %d\n", ret); |
| - goto out_unref; |
| - } |
| - |
| - info = framebuffer_alloc(0, device); |
| - if (!info) { |
| - ret = -ENOMEM; |
| - goto out_unpin; |
| - } |
| - |
| - info->par = helper; |
| - |
| - ret = intel_framebuffer_init(dev, &ifbdev->ifb, &mode_cmd, obj); |
| - if (ret) |
| - goto out_unpin; |
| - |
| - fb = &ifbdev->ifb.base; |
| - |
| - ifbdev->helper.fb = fb; |
| - ifbdev->helper.fbdev = info; |
| - |
| - strcpy(info->fix.id, "inteldrmfb"); |
| - |
| - info->flags = FBINFO_DEFAULT | FBINFO_CAN_FORCE_OUTPUT; |
| - info->fbops = &intelfb_ops; |
| - |
| - ret = fb_alloc_cmap(&info->cmap, 256, 0); |
| - if (ret) { |
| - ret = -ENOMEM; |
| - goto out_unpin; |
| - } |
| - /* setup aperture base/size for vesafb takeover */ |
| - info->apertures = alloc_apertures(1); |
| - if (!info->apertures) { |
| - ret = -ENOMEM; |
| - goto out_unpin; |
| - } |
| - info->apertures->ranges[0].base = dev->mode_config.fb_base; |
| - info->apertures->ranges[0].size = dev_priv->gtt.mappable_end; |
| - |
| - info->fix.smem_start = dev->mode_config.fb_base + i915_gem_obj_ggtt_offset(obj); |
| - info->fix.smem_len = size; |
| - |
| - info->screen_base = |
| - ioremap_wc(dev_priv->gtt.mappable_base + i915_gem_obj_ggtt_offset(obj), |
| - size); |
| - if (!info->screen_base) { |
| - ret = -ENOSPC; |
| - goto out_unpin; |
| - } |
| - info->screen_size = size; |
| - |
| - /* This driver doesn't need a VT switch to restore the mode on resume */ |
| - info->skip_vt_switch = true; |
| - |
| - drm_fb_helper_fill_fix(info, fb->pitches[0], fb->depth); |
| - drm_fb_helper_fill_var(info, &ifbdev->helper, sizes->fb_width, sizes->fb_height); |
| - |
| - /* If the object is shmemfs backed, it will have given us zeroed pages. |
| - * If the object is stolen however, it will be full of whatever |
| - * garbage was left in there. |
| - */ |
| - if (ifbdev->ifb.obj->stolen) |
| - memset_io(info->screen_base, 0, info->screen_size); |
| - |
| - /* Use default scratch pixmap (info->pixmap.flags = FB_PIXMAP_SYSTEM) */ |
| - |
| - DRM_DEBUG_KMS("allocated %dx%d fb: 0x%08lx, bo %p\n", |
| - fb->width, fb->height, |
| - i915_gem_obj_ggtt_offset(obj), obj); |
| - |
| - |
| - mutex_unlock(&dev->struct_mutex); |
| - vga_switcheroo_client_fb_set(dev->pdev, info); |
| - return 0; |
| - |
| -out_unpin: |
| - i915_gem_object_unpin(obj); |
| -out_unref: |
| - drm_gem_object_unreference(&obj->base); |
| - mutex_unlock(&dev->struct_mutex); |
| -out: |
| - return ret; |
| -} |
| - |
| -/** Sets the color ramps on behalf of RandR */ |
| -static void intel_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green, |
| - u16 blue, int regno) |
| -{ |
| - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
| - |
| - intel_crtc->lut_r[regno] = red >> 8; |
| - intel_crtc->lut_g[regno] = green >> 8; |
| - intel_crtc->lut_b[regno] = blue >> 8; |
| -} |
| - |
| -static void intel_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green, |
| - u16 *blue, int regno) |
| -{ |
| - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
| - |
| - *red = intel_crtc->lut_r[regno] << 8; |
| - *green = intel_crtc->lut_g[regno] << 8; |
| - *blue = intel_crtc->lut_b[regno] << 8; |
| -} |
| - |
| -static struct drm_fb_helper_funcs intel_fb_helper_funcs = { |
| - .gamma_set = intel_crtc_fb_gamma_set, |
| - .gamma_get = intel_crtc_fb_gamma_get, |
| - .fb_probe = intelfb_create, |
| -}; |
| - |
| -static void intel_fbdev_destroy(struct drm_device *dev, |
| - struct intel_fbdev *ifbdev) |
| -{ |
| - if (ifbdev->helper.fbdev) { |
| - struct fb_info *info = ifbdev->helper.fbdev; |
| - |
| - unregister_framebuffer(info); |
| - iounmap(info->screen_base); |
| - if (info->cmap.len) |
| - fb_dealloc_cmap(&info->cmap); |
| - |
| - framebuffer_release(info); |
| - } |
| - |
| - drm_fb_helper_fini(&ifbdev->helper); |
| - |
| - drm_framebuffer_unregister_private(&ifbdev->ifb.base); |
| - intel_framebuffer_fini(&ifbdev->ifb); |
| -} |
| - |
| -int intel_fbdev_init(struct drm_device *dev) |
| -{ |
| - struct intel_fbdev *ifbdev; |
| - struct drm_i915_private *dev_priv = dev->dev_private; |
| - int ret; |
| - |
| - ifbdev = kzalloc(sizeof(*ifbdev), GFP_KERNEL); |
| - if (!ifbdev) |
| - return -ENOMEM; |
| - |
| - dev_priv->fbdev = ifbdev; |
| - ifbdev->helper.funcs = &intel_fb_helper_funcs; |
| - |
| - ret = drm_fb_helper_init(dev, &ifbdev->helper, |
| - INTEL_INFO(dev)->num_pipes, |
| - 4); |
| - if (ret) { |
| - kfree(ifbdev); |
| - return ret; |
| - } |
| - |
| - drm_fb_helper_single_add_all_connectors(&ifbdev->helper); |
| - |
| - return 0; |
| -} |
| - |
| -void intel_fbdev_initial_config(struct drm_device *dev) |
| -{ |
| - struct drm_i915_private *dev_priv = dev->dev_private; |
| - |
| - /* Due to peculiar init order wrt to hpd handling this is separate. */ |
| - drm_fb_helper_initial_config(&dev_priv->fbdev->helper, 32); |
| -} |
| - |
| -void intel_fbdev_fini(struct drm_device *dev) |
| -{ |
| - struct drm_i915_private *dev_priv = dev->dev_private; |
| - if (!dev_priv->fbdev) |
| - return; |
| - |
| - intel_fbdev_destroy(dev, dev_priv->fbdev); |
| - kfree(dev_priv->fbdev); |
| - dev_priv->fbdev = NULL; |
| -} |
| - |
| -void intel_fbdev_set_suspend(struct drm_device *dev, int state) |
| -{ |
| - struct drm_i915_private *dev_priv = dev->dev_private; |
| - struct intel_fbdev *ifbdev = dev_priv->fbdev; |
| - struct fb_info *info; |
| - |
| - if (!ifbdev) |
| - return; |
| - |
| - info = ifbdev->helper.fbdev; |
| - |
| - /* On resume from hibernation: If the object is shmemfs backed, it has |
| - * been restored from swap. If the object is stolen however, it will be |
| - * full of whatever garbage was left in there. |
| - */ |
| - if (state == FBINFO_STATE_RUNNING && ifbdev->ifb.obj->stolen) |
| - memset_io(info->screen_base, 0, info->screen_size); |
| - |
| - fb_set_suspend(info, state); |
| -} |
| - |
| -MODULE_LICENSE("GPL and additional rights"); |
| - |
| -void intel_fb_output_poll_changed(struct drm_device *dev) |
| -{ |
| - struct drm_i915_private *dev_priv = dev->dev_private; |
| - drm_fb_helper_hotplug_event(&dev_priv->fbdev->helper); |
| -} |
| - |
| -void intel_fb_restore_mode(struct drm_device *dev) |
| -{ |
| - int ret; |
| - struct drm_i915_private *dev_priv = dev->dev_private; |
| - |
| - if (INTEL_INFO(dev)->num_pipes == 0) |
| - return; |
| - |
| - drm_modeset_lock_all(dev); |
| - |
| - ret = drm_fb_helper_restore_fbdev_mode(&dev_priv->fbdev->helper); |
| - if (ret) |
| - DRM_DEBUG("failed to restore crtc mode\n"); |
| - |
| - drm_modeset_unlock_all(dev); |
| -} |
| --- /dev/null |
| +++ b/drivers/gpu/drm/i915/intel_fbdev.c |
| @@ -0,0 +1,323 @@ |
| +/* |
| + * Copyright © 2007 David Airlie |
| + * |
| + * Permission is hereby granted, free of charge, to any person obtaining a |
| + * copy of this software and associated documentation files (the "Software"), |
| + * to deal in the Software without restriction, including without limitation |
| + * the rights to use, copy, modify, merge, publish, distribute, sublicense, |
| + * and/or sell copies of the Software, and to permit persons to whom the |
| + * Software is furnished to do so, subject to the following conditions: |
| + * |
| + * The above copyright notice and this permission notice (including the next |
| + * paragraph) shall be included in all copies or substantial portions of the |
| + * Software. |
| + * |
| + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
| + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
| + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
| + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
| + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
| + * DEALINGS IN THE SOFTWARE. |
| + * |
| + * Authors: |
| + * David Airlie |
| + */ |
| + |
| +#include <linux/module.h> |
| +#include <linux/kernel.h> |
| +#include <linux/errno.h> |
| +#include <linux/string.h> |
| +#include <linux/mm.h> |
| +#include <linux/tty.h> |
| +#include <linux/sysrq.h> |
| +#include <linux/delay.h> |
| +#include <linux/fb.h> |
| +#include <linux/init.h> |
| +#include <linux/vga_switcheroo.h> |
| + |
| +#include <drm/drmP.h> |
| +#include <drm/drm_crtc.h> |
| +#include <drm/drm_fb_helper.h> |
| +#include "intel_drv.h" |
| +#include <drm/i915_drm.h> |
| +#include "i915_drv.h" |
| + |
| +static struct fb_ops intelfb_ops = { |
| + .owner = THIS_MODULE, |
| + .fb_check_var = drm_fb_helper_check_var, |
| + .fb_set_par = drm_fb_helper_set_par, |
| + .fb_fillrect = cfb_fillrect, |
| + .fb_copyarea = cfb_copyarea, |
| + .fb_imageblit = cfb_imageblit, |
| + .fb_pan_display = drm_fb_helper_pan_display, |
| + .fb_blank = drm_fb_helper_blank, |
| + .fb_setcmap = drm_fb_helper_setcmap, |
| + .fb_debug_enter = drm_fb_helper_debug_enter, |
| + .fb_debug_leave = drm_fb_helper_debug_leave, |
| +}; |
| + |
| +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 drm_device *dev = helper->dev; |
| + struct drm_i915_private *dev_priv = dev->dev_private; |
| + struct fb_info *info; |
| + struct drm_framebuffer *fb; |
| + struct drm_mode_fb_cmd2 mode_cmd = {}; |
| + struct drm_i915_gem_object *obj; |
| + struct device *device = &dev->pdev->dev; |
| + int size, ret; |
| + |
| + /* we don't do packed 24bpp */ |
| + if (sizes->surface_bpp == 24) |
| + sizes->surface_bpp = 32; |
| + |
| + mode_cmd.width = sizes->surface_width; |
| + mode_cmd.height = sizes->surface_height; |
| + |
| + mode_cmd.pitches[0] = ALIGN(mode_cmd.width * ((sizes->surface_bpp + 7) / |
| + 8), 64); |
| + mode_cmd.pixel_format = drm_mode_legacy_fb_format(sizes->surface_bpp, |
| + sizes->surface_depth); |
| + |
| + size = mode_cmd.pitches[0] * mode_cmd.height; |
| + size = ALIGN(size, PAGE_SIZE); |
| + obj = i915_gem_object_create_stolen(dev, size); |
| + if (obj == NULL) |
| + obj = i915_gem_alloc_object(dev, size); |
| + if (!obj) { |
| + DRM_ERROR("failed to allocate framebuffer\n"); |
| + ret = -ENOMEM; |
| + goto out; |
| + } |
| + |
| + mutex_lock(&dev->struct_mutex); |
| + |
| + /* Flush everything out, we'll be doing GTT only from now on */ |
| + ret = intel_pin_and_fence_fb_obj(dev, obj, NULL); |
| + if (ret) { |
| + DRM_ERROR("failed to pin fb: %d\n", ret); |
| + goto out_unref; |
| + } |
| + |
| + info = framebuffer_alloc(0, device); |
| + if (!info) { |
| + ret = -ENOMEM; |
| + goto out_unpin; |
| + } |
| + |
| + info->par = helper; |
| + |
| + ret = intel_framebuffer_init(dev, &ifbdev->ifb, &mode_cmd, obj); |
| + if (ret) |
| + goto out_unpin; |
| + |
| + fb = &ifbdev->ifb.base; |
| + |
| + ifbdev->helper.fb = fb; |
| + ifbdev->helper.fbdev = info; |
| + |
| + strcpy(info->fix.id, "inteldrmfb"); |
| + |
| + info->flags = FBINFO_DEFAULT | FBINFO_CAN_FORCE_OUTPUT; |
| + info->fbops = &intelfb_ops; |
| + |
| + ret = fb_alloc_cmap(&info->cmap, 256, 0); |
| + if (ret) { |
| + ret = -ENOMEM; |
| + goto out_unpin; |
| + } |
| + /* setup aperture base/size for vesafb takeover */ |
| + info->apertures = alloc_apertures(1); |
| + if (!info->apertures) { |
| + ret = -ENOMEM; |
| + goto out_unpin; |
| + } |
| + info->apertures->ranges[0].base = dev->mode_config.fb_base; |
| + info->apertures->ranges[0].size = dev_priv->gtt.mappable_end; |
| + |
| + info->fix.smem_start = dev->mode_config.fb_base + i915_gem_obj_ggtt_offset(obj); |
| + info->fix.smem_len = size; |
| + |
| + info->screen_base = |
| + ioremap_wc(dev_priv->gtt.mappable_base + i915_gem_obj_ggtt_offset(obj), |
| + size); |
| + if (!info->screen_base) { |
| + ret = -ENOSPC; |
| + goto out_unpin; |
| + } |
| + info->screen_size = size; |
| + |
| + /* This driver doesn't need a VT switch to restore the mode on resume */ |
| + info->skip_vt_switch = true; |
| + |
| + drm_fb_helper_fill_fix(info, fb->pitches[0], fb->depth); |
| + drm_fb_helper_fill_var(info, &ifbdev->helper, sizes->fb_width, sizes->fb_height); |
| + |
| + /* If the object is shmemfs backed, it will have given us zeroed pages. |
| + * If the object is stolen however, it will be full of whatever |
| + * garbage was left in there. |
| + */ |
| + if (ifbdev->ifb.obj->stolen) |
| + memset_io(info->screen_base, 0, info->screen_size); |
| + |
| + /* Use default scratch pixmap (info->pixmap.flags = FB_PIXMAP_SYSTEM) */ |
| + |
| + DRM_DEBUG_KMS("allocated %dx%d fb: 0x%08lx, bo %p\n", |
| + fb->width, fb->height, |
| + i915_gem_obj_ggtt_offset(obj), obj); |
| + |
| + |
| + mutex_unlock(&dev->struct_mutex); |
| + vga_switcheroo_client_fb_set(dev->pdev, info); |
| + return 0; |
| + |
| +out_unpin: |
| + i915_gem_object_unpin(obj); |
| +out_unref: |
| + drm_gem_object_unreference(&obj->base); |
| + mutex_unlock(&dev->struct_mutex); |
| +out: |
| + return ret; |
| +} |
| + |
| +/** Sets the color ramps on behalf of RandR */ |
| +static void intel_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green, |
| + u16 blue, int regno) |
| +{ |
| + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
| + |
| + intel_crtc->lut_r[regno] = red >> 8; |
| + intel_crtc->lut_g[regno] = green >> 8; |
| + intel_crtc->lut_b[regno] = blue >> 8; |
| +} |
| + |
| +static void intel_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green, |
| + u16 *blue, int regno) |
| +{ |
| + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
| + |
| + *red = intel_crtc->lut_r[regno] << 8; |
| + *green = intel_crtc->lut_g[regno] << 8; |
| + *blue = intel_crtc->lut_b[regno] << 8; |
| +} |
| + |
| +static struct drm_fb_helper_funcs intel_fb_helper_funcs = { |
| + .gamma_set = intel_crtc_fb_gamma_set, |
| + .gamma_get = intel_crtc_fb_gamma_get, |
| + .fb_probe = intelfb_create, |
| +}; |
| + |
| +static void intel_fbdev_destroy(struct drm_device *dev, |
| + struct intel_fbdev *ifbdev) |
| +{ |
| + if (ifbdev->helper.fbdev) { |
| + struct fb_info *info = ifbdev->helper.fbdev; |
| + |
| + unregister_framebuffer(info); |
| + iounmap(info->screen_base); |
| + if (info->cmap.len) |
| + fb_dealloc_cmap(&info->cmap); |
| + |
| + framebuffer_release(info); |
| + } |
| + |
| + drm_fb_helper_fini(&ifbdev->helper); |
| + |
| + drm_framebuffer_unregister_private(&ifbdev->ifb.base); |
| + intel_framebuffer_fini(&ifbdev->ifb); |
| +} |
| + |
| +int intel_fbdev_init(struct drm_device *dev) |
| +{ |
| + struct intel_fbdev *ifbdev; |
| + struct drm_i915_private *dev_priv = dev->dev_private; |
| + int ret; |
| + |
| + ifbdev = kzalloc(sizeof(*ifbdev), GFP_KERNEL); |
| + if (!ifbdev) |
| + return -ENOMEM; |
| + |
| + dev_priv->fbdev = ifbdev; |
| + ifbdev->helper.funcs = &intel_fb_helper_funcs; |
| + |
| + ret = drm_fb_helper_init(dev, &ifbdev->helper, |
| + INTEL_INFO(dev)->num_pipes, |
| + 4); |
| + if (ret) { |
| + kfree(ifbdev); |
| + return ret; |
| + } |
| + |
| + drm_fb_helper_single_add_all_connectors(&ifbdev->helper); |
| + |
| + return 0; |
| +} |
| + |
| +void intel_fbdev_initial_config(struct drm_device *dev) |
| +{ |
| + struct drm_i915_private *dev_priv = dev->dev_private; |
| + |
| + /* Due to peculiar init order wrt to hpd handling this is separate. */ |
| + drm_fb_helper_initial_config(&dev_priv->fbdev->helper, 32); |
| +} |
| + |
| +void intel_fbdev_fini(struct drm_device *dev) |
| +{ |
| + struct drm_i915_private *dev_priv = dev->dev_private; |
| + if (!dev_priv->fbdev) |
| + return; |
| + |
| + intel_fbdev_destroy(dev, dev_priv->fbdev); |
| + kfree(dev_priv->fbdev); |
| + dev_priv->fbdev = NULL; |
| +} |
| + |
| +void intel_fbdev_set_suspend(struct drm_device *dev, int state) |
| +{ |
| + struct drm_i915_private *dev_priv = dev->dev_private; |
| + struct intel_fbdev *ifbdev = dev_priv->fbdev; |
| + struct fb_info *info; |
| + |
| + if (!ifbdev) |
| + return; |
| + |
| + info = ifbdev->helper.fbdev; |
| + |
| + /* On resume from hibernation: If the object is shmemfs backed, it has |
| + * been restored from swap. If the object is stolen however, it will be |
| + * full of whatever garbage was left in there. |
| + */ |
| + if (state == FBINFO_STATE_RUNNING && ifbdev->ifb.obj->stolen) |
| + memset_io(info->screen_base, 0, info->screen_size); |
| + |
| + fb_set_suspend(info, state); |
| +} |
| + |
| +MODULE_LICENSE("GPL and additional rights"); |
| + |
| +void intel_fbdev_output_poll_changed(struct drm_device *dev) |
| +{ |
| + struct drm_i915_private *dev_priv = dev->dev_private; |
| + drm_fb_helper_hotplug_event(&dev_priv->fbdev->helper); |
| +} |
| + |
| +void intel_fbdev_restore_mode(struct drm_device *dev) |
| +{ |
| + int ret; |
| + struct drm_i915_private *dev_priv = dev->dev_private; |
| + |
| + if (INTEL_INFO(dev)->num_pipes == 0) |
| + return; |
| + |
| + drm_modeset_lock_all(dev); |
| + |
| + ret = drm_fb_helper_restore_fbdev_mode(&dev_priv->fbdev->helper); |
| + if (ret) |
| + DRM_DEBUG("failed to restore crtc mode\n"); |
| + |
| + drm_modeset_unlock_all(dev); |
| +} |