[Intel-gfx] [PATCH 4/4] drm/i915: Reserve space for FBC (fbcon)

Ben Widawsky benjamin.widawsky at intel.com
Thu Jun 19 21:06:13 CEST 2014


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 at chris-wilson.co.uk>
Date:   Thu Nov 15 11:32:27 2012 +0000

    drm/i915: Allocate fbcon from stolen memory

Cc: Chris Wilson <chris at chris-wilson.co.uk>
Cc: Jesse Barnes <jbarnes at virtuousgeek.org>
Signed-off-by: Ben Widawsky <ben at bwidawsk.net>
---
 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




More information about the Intel-gfx mailing list