diff options
Diffstat (limited to 'drivers/gpu/drm/i915/i915_dma.c')
-rw-r--r-- | drivers/gpu/drm/i915/i915_dma.c | 15 |
1 files changed, 15 insertions, 0 deletions
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index a9f8589490c..c3cfafcbfe7 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -38,6 +38,7 @@ #include <linux/acpi.h> #include <linux/pnp.h> #include <linux/vga_switcheroo.h> +#include <linux/slab.h> /* Really want an OS-independent resettable timer. Would like to have * this loop run for (eg) 3 sec, but have the timer reset every time @@ -1356,6 +1357,8 @@ static void i915_setup_compression(struct drm_device *dev, int size) dev_priv->cfb_size = size; + dev_priv->compressed_fb = compressed_fb; + if (IS_GM45(dev)) { g4x_disable_fbc(dev); I915_WRITE(DPFC_CB_BASE, compressed_fb->start); @@ -1363,12 +1366,22 @@ static void i915_setup_compression(struct drm_device *dev, int size) i8xx_disable_fbc(dev); I915_WRITE(FBC_CFB_BASE, cfb_base); I915_WRITE(FBC_LL_BASE, ll_base); + dev_priv->compressed_llb = compressed_llb; } DRM_DEBUG("FBC base 0x%08lx, ll base 0x%08lx, size %dM\n", cfb_base, ll_base, size >> 20); } +static void i915_cleanup_compression(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + + drm_mm_put_block(dev_priv->compressed_fb); + if (!IS_GM45(dev)) + drm_mm_put_block(dev_priv->compressed_llb); +} + /* true = enable decode, false = disable decoder */ static unsigned int i915_vga_set_decode(void *cookie, bool state) { @@ -1786,6 +1799,8 @@ int i915_driver_unload(struct drm_device *dev) mutex_lock(&dev->struct_mutex); i915_gem_cleanup_ringbuffer(dev); mutex_unlock(&dev->struct_mutex); + if (I915_HAS_FBC(dev) && i915_powersave) + i915_cleanup_compression(dev); drm_mm_takedown(&dev_priv->vram); i915_gem_lastclose(dev); |