This is one part in a few fixes needed to make FBC work with limited stolen memory and large resolution displays. It is not the full solution, but one (easy) step. The patch is straight-forward, it attempts to check there will be room for FBC before trying to "reclaim" This modifies behavior originally introduced: commit 0ffb0ff283cca16f72caf29c44496d83b0c291fb Author: Chris Wilson <chris@xxxxxxxxxxxxxxxxxx> Date: Thu Nov 15 11:32:27 2012 +0000 drm/i915: Allocate fbcon from stolen memory Cc: Chris Wilson <chris@xxxxxxxxxxxxxxxxxx> Cc: Jesse Barnes <jbarnes@xxxxxxxxxxxxxxxx> Signed-off-by: Ben Widawsky <ben@xxxxxxxxxxxx> --- drivers/gpu/drm/i915/intel_fbdev.c | 37 +++++++++++++++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_fbdev.c b/drivers/gpu/drm/i915/intel_fbdev.c index 27975c3..ca83af8 100644 --- a/drivers/gpu/drm/i915/intel_fbdev.c +++ b/drivers/gpu/drm/i915/intel_fbdev.c @@ -57,6 +57,36 @@ static struct fb_ops intelfb_ops = { .fb_debug_leave = drm_fb_helper_debug_leave, }; +static bool intelfb_use_stolen(struct drm_device *dev, struct drm_mm *mm, + int size) +{ + struct drm_mm_node *entry; + unsigned long adj_start; + unsigned long adj_end; + + if (!drm_mm_initialized(mm)) + return false; + + if (!HAS_FBC(dev)) + return true; + + /* It is more desirable to use FBC (if enabled) than to allocate the + * framebuffer from stolen. We can cheat this by rounding up the size by + * 2 (and hope to get lucky with alignment). The other options are more + * invasive, and arguably not any more effective. + */ + size *= 2; + __drm_mm_for_each_hole(entry, mm, adj_start, adj_end, + DRM_MM_SEARCH_DEFAULT) { + if (adj_end - adj_start < size) + continue; + + if (adj_end >= adj_start + size) + return true; + } + + return false; +} static int intelfb_alloc(struct drm_fb_helper *helper, struct drm_fb_helper_surface_size *sizes) { @@ -64,8 +94,9 @@ static int intelfb_alloc(struct drm_fb_helper *helper, container_of(helper, struct intel_fbdev, helper); struct drm_framebuffer *fb; struct drm_device *dev = helper->dev; + struct drm_i915_private *dev_priv = dev->dev_private; struct drm_mode_fb_cmd2 mode_cmd = {}; - struct drm_i915_gem_object *obj; + struct drm_i915_gem_object *obj = NULL; int size, ret; /* we don't do packed 24bpp */ @@ -82,7 +113,9 @@ static int intelfb_alloc(struct drm_fb_helper *helper, size = mode_cmd.pitches[0] * mode_cmd.height; size = ALIGN(size, PAGE_SIZE); - obj = i915_gem_object_create_stolen(dev, size); + + if (intelfb_use_stolen(dev, &dev_priv->mm.stolen, size)) + obj = i915_gem_object_create_stolen(dev, size); if (obj == NULL) obj = i915_gem_alloc_object(dev, size); if (!obj) { -- 2.0.0 _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/intel-gfx