Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 357872
b: refs/heads/master
c: 11be49e
h: refs/heads/master
v: v3
  • Loading branch information
Chris Wilson authored and Daniel Vetter committed Nov 30, 2012
1 parent 945455c commit f5f81af
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 65 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: ed2f3452677e46a4270c25c1b7fa3e060fdd501e
refs/heads/master: 11be49eb4db24c5e971edef160afb87788cc270c
2 changes: 2 additions & 0 deletions trunk/drivers/gpu/drm/i915/i915_drv.h
Original file line number Diff line number Diff line change
Expand Up @@ -1571,6 +1571,8 @@ int i915_gem_evict_everything(struct drm_device *dev);

/* i915_gem_stolen.c */
int i915_gem_init_stolen(struct drm_device *dev);
int i915_gem_stolen_setup_compression(struct drm_device *dev, int size);
void i915_gem_stolen_cleanup_compression(struct drm_device *dev);
void i915_gem_cleanup_stolen(struct drm_device *dev);

/* i915_gem_tiling.c */
Expand Down
108 changes: 50 additions & 58 deletions trunk/drivers/gpu/drm/i915/i915_gem_stolen.c
Original file line number Diff line number Diff line change
Expand Up @@ -88,33 +88,27 @@ static unsigned long i915_stolen_to_physical(struct drm_device *dev)
return base;
}

static void i915_warn_stolen(struct drm_device *dev)
{
DRM_INFO("not enough stolen space for compressed buffer, disabling\n");
DRM_INFO("hint: you may be able to increase stolen memory size in the BIOS to avoid this\n");
}

static void i915_setup_compression(struct drm_device *dev, int size)
static int i915_setup_compression(struct drm_device *dev, int size)
{
struct drm_i915_private *dev_priv = dev->dev_private;
struct drm_mm_node *compressed_fb, *uninitialized_var(compressed_llb);
unsigned long cfb_base;
unsigned long ll_base = 0;

/* Just in case the BIOS is doing something questionable. */
intel_disable_fbc(dev);

compressed_fb = drm_mm_search_free(&dev_priv->mm.stolen, size, 4096, 0);
/* Try to over-allocate to reduce reallocations and fragmentation */
compressed_fb = drm_mm_search_free(&dev_priv->mm.stolen,
size <<= 1, 4096, 0);
if (!compressed_fb)
compressed_fb = drm_mm_search_free(&dev_priv->mm.stolen,
size >>= 1, 4096, 0);
if (compressed_fb)
compressed_fb = drm_mm_get_block(compressed_fb, size, 4096);
if (!compressed_fb)
goto err;

cfb_base = dev_priv->mm.stolen_base + compressed_fb->start;
if (!cfb_base)
goto err_fb;

if (!(IS_GM45(dev) || HAS_PCH_SPLIT(dev))) {
if (HAS_PCH_SPLIT(dev))
I915_WRITE(ILK_DPFC_CB_BASE, compressed_fb->start);
else if (IS_GM45(dev)) {
I915_WRITE(DPFC_CB_BASE, compressed_fb->start);
} else {
compressed_llb = drm_mm_search_free(&dev_priv->mm.stolen,
4096, 4096, 0);
if (compressed_llb)
Expand All @@ -123,56 +117,68 @@ static void i915_setup_compression(struct drm_device *dev, int size)
if (!compressed_llb)
goto err_fb;

ll_base = dev_priv->mm.stolen_base + compressed_llb->start;
if (!ll_base)
goto err_llb;
dev_priv->compressed_llb = compressed_llb;

I915_WRITE(FBC_CFB_BASE,
dev_priv->mm.stolen_base + compressed_fb->start);
I915_WRITE(FBC_LL_BASE,
dev_priv->mm.stolen_base + compressed_llb->start);
}

dev_priv->compressed_fb = compressed_fb;
dev_priv->cfb_size = size;

dev_priv->compressed_fb = compressed_fb;
if (HAS_PCH_SPLIT(dev))
I915_WRITE(ILK_DPFC_CB_BASE, compressed_fb->start);
else if (IS_GM45(dev)) {
I915_WRITE(DPFC_CB_BASE, compressed_fb->start);
} else {
I915_WRITE(FBC_CFB_BASE, cfb_base);
I915_WRITE(FBC_LL_BASE, ll_base);
dev_priv->compressed_llb = compressed_llb;
}
DRM_DEBUG_KMS("reserved %d bytes of contiguous stolen space for FBC\n",
size);

DRM_DEBUG_KMS("FBC base 0x%08lx, ll base 0x%08lx, size %dM\n",
(long)cfb_base, (long)ll_base, size >> 20);
return;
return 0;

err_llb:
drm_mm_put_block(compressed_llb);
err_fb:
drm_mm_put_block(compressed_fb);
err:
dev_priv->no_fbc_reason = FBC_STOLEN_TOO_SMALL;
i915_warn_stolen(dev);
return -ENOSPC;
}

int i915_gem_stolen_setup_compression(struct drm_device *dev, int size)
{
struct drm_i915_private *dev_priv = dev->dev_private;

if (dev_priv->mm.stolen_base == 0)
return -ENODEV;

if (size < dev_priv->cfb_size)
return 0;

/* Release any current block */
i915_gem_stolen_cleanup_compression(dev);

return i915_setup_compression(dev, size);
}

static void i915_cleanup_compression(struct drm_device *dev)
void i915_gem_stolen_cleanup_compression(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;

drm_mm_put_block(dev_priv->compressed_fb);
if (dev_priv->cfb_size == 0)
return;

if (dev_priv->compressed_fb)
drm_mm_put_block(dev_priv->compressed_fb);

if (dev_priv->compressed_llb)
drm_mm_put_block(dev_priv->compressed_llb);

dev_priv->cfb_size = 0;
}

void i915_gem_cleanup_stolen(struct drm_device *dev)
{
if (I915_HAS_FBC(dev) && i915_powersave)
i915_cleanup_compression(dev);
i915_gem_stolen_cleanup_compression(dev);
}

int i915_gem_init_stolen(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
unsigned long prealloc_size = dev_priv->mm.gtt->stolen_size;

dev_priv->mm.stolen_base = i915_stolen_to_physical(dev);
if (dev_priv->mm.stolen_base == 0)
Expand All @@ -182,21 +188,7 @@ int i915_gem_init_stolen(struct drm_device *dev)
dev_priv->mm.gtt->stolen_size, dev_priv->mm.stolen_base);

/* Basic memrange allocator for stolen space */
drm_mm_init(&dev_priv->mm.stolen, 0, prealloc_size);

/* Try to set up FBC with a reasonable compressed buffer size */
if (I915_HAS_FBC(dev) && i915_powersave) {
int cfb_size;

/* Leave 1M for line length buffer & misc. */

/* Try to get a 32M buffer... */
if (prealloc_size > (36*1024*1024))
cfb_size = 32*1024*1024;
else /* fall back to 7/8 of the stolen space */
cfb_size = prealloc_size * 7 / 8;
i915_setup_compression(dev, cfb_size);
}
drm_mm_init(&dev_priv->mm.stolen, 0, dev_priv->mm.gtt->stolen_size);

return 0;
}
3 changes: 3 additions & 0 deletions trunk/drivers/gpu/drm/i915/intel_display.c
Original file line number Diff line number Diff line change
Expand Up @@ -8655,6 +8655,9 @@ void intel_modeset_init(struct drm_device *dev)
/* Just disable it once at startup */
i915_disable_vga(dev);
intel_setup_outputs(dev);

/* Just in case the BIOS is doing something questionable. */
intel_disable_fbc(dev);
}

static void
Expand Down
15 changes: 9 additions & 6 deletions trunk/drivers/gpu/drm/i915/intel_pm.c
Original file line number Diff line number Diff line change
Expand Up @@ -440,12 +440,6 @@ void intel_update_fbc(struct drm_device *dev)
dev_priv->no_fbc_reason = FBC_MODULE_PARAM;
goto out_disable;
}
if (intel_fb->obj->base.size > dev_priv->cfb_size) {
DRM_DEBUG_KMS("framebuffer too large, disabling "
"compression\n");
dev_priv->no_fbc_reason = FBC_STOLEN_TOO_SMALL;
goto out_disable;
}
if ((crtc->mode.flags & DRM_MODE_FLAG_INTERLACE) ||
(crtc->mode.flags & DRM_MODE_FLAG_DBLSCAN)) {
DRM_DEBUG_KMS("mode incompatible with compression, "
Expand Down Expand Up @@ -479,6 +473,14 @@ void intel_update_fbc(struct drm_device *dev)
if (in_dbg_master())
goto out_disable;

if (i915_gem_stolen_setup_compression(dev, intel_fb->obj->base.size)) {
DRM_INFO("not enough stolen space for compressed buffer (need %zd bytes), disabling\n", intel_fb->obj->base.size);
DRM_INFO("hint: you may be able to increase stolen memory size in the BIOS to avoid this\n");
DRM_DEBUG_KMS("framebuffer too large, disabling compression\n");
dev_priv->no_fbc_reason = FBC_STOLEN_TOO_SMALL;
goto out_disable;
}

/* If the scanout has not changed, don't modify the FBC settings.
* Note that we make the fundamental assumption that the fb->obj
* cannot be unpinned (and have its GTT offset and fence revoked)
Expand Down Expand Up @@ -526,6 +528,7 @@ void intel_update_fbc(struct drm_device *dev)
DRM_DEBUG_KMS("unsupported config, disabling FBC\n");
intel_disable_fbc(dev);
}
i915_gem_stolen_cleanup_compression(dev);
}

static void i915_pineview_get_mem_freq(struct drm_device *dev)
Expand Down

0 comments on commit f5f81af

Please sign in to comment.