All of lore.kernel.org
 help / color / mirror / Atom feed
From: Chris Wilson <chris@chris-wilson.co.uk>
To: intel-gfx@lists.freedesktop.org
Subject: [PATCH] drm/i915: Attach a fb to the load-detect pipe
Date: Wed, 20 Apr 2011 21:16:36 +0100	[thread overview]
Message-ID: <1303330596-32628-1-git-send-email-chris@chris-wilson.co.uk> (raw)
In-Reply-To: <yunhb9shig5.fsf@aiko.keithp.com>

We need to ensure that we feed valid memory into the display plane
attached to the pipe when switching the pipe on. Otherwise, the display
engine may read through an invalid PTE and so throw an PGTBL_ER
exception.

As we need to perform load detection before even the first object is
allocated for the fbdev, there is no pre-existing object large enough
for us to borrow to use as the framebuffer. So we need to create one
and cleanup afterwards.

Found by assert_fb_bound_for_plane().

Reported-by: Knut Petersen <Knut_Petersen@t-online.de>
References: https://bugs.freedesktop.org/show_bug.cgi?id=36246
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
---

I've only compile tested this so far. I manage to break my grub
installation on the only 915GM I have (and the debian installer doesn't),
so I haven't been able to test this yet.

We can refactor half of intel_framebuffer_create_for_mode and share the
kzalloc+init with intel_user_framebuffer_create.

But I think this is close.
-Chris

---
 drivers/gpu/drm/i915/intel_display.c |   57 +++++++++++++++++++++++++++++++++-
 1 files changed, 56 insertions(+), 1 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 9b1a3e1..f1cb91e 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -5539,6 +5539,43 @@ static struct drm_display_mode load_detect_mode = {
 		 704, 832, 0, 480, 489, 491, 520, 0, DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
 };
 
+static struct drm_framebuffer *
+intel_framebuffer_create_for_mode(struct drm_device *dev,
+				  struct drm_display_mode *mode)
+{
+	struct drm_i915_gem_object *obj;
+	struct intel_framebuffer *intel_fb;
+	struct drm_mode_fb_cmd mode_cmd;
+	u32 size;
+
+	/* Presume a 32-bpp fb is correct */
+	mode_cmd.width = mode->hdisplay;
+	mode_cmd.height = mode->vdisplay;
+	mode_cmd.depth = 24;
+	mode_cmd.bpp = 32;
+	mode_cmd.pitch = ALIGN(mode->hdisplay * 4, 64);
+
+	size = ALIGN(mode_cmd.pitch * mode_cmd.height, PAGE_SIZE);
+
+	obj = i915_gem_alloc_object(dev, size);
+	if (obj == NULL)
+		return NULL;
+
+	intel_fb = kzalloc(sizeof(*intel_fb), GFP_KERNEL);
+	if (!intel_fb) {
+		drm_gem_object_unreference_unlocked(&obj->base);
+		return NULL;
+	}
+
+	if (intel_framebuffer_init(dev, intel_fb, &mode_cmd, obj)) {
+		drm_gem_object_unreference_unlocked(&obj->base);
+		kfree(intel_fb);
+		return NULL;
+	}
+
+	return &intel_fb->base;
+}
+
 bool intel_get_load_detect_pipe(struct intel_encoder *intel_encoder,
 				struct drm_connector *connector,
 				struct drm_display_mode *mode,
@@ -5549,6 +5586,7 @@ bool intel_get_load_detect_pipe(struct intel_encoder *intel_encoder,
 	struct drm_encoder *encoder = &intel_encoder->base;
 	struct drm_crtc *crtc = NULL;
 	struct drm_device *dev = encoder->dev;
+	struct drm_framebuffer *old_fb;
 	int i = -1;
 
 	/*
@@ -5613,8 +5651,21 @@ bool intel_get_load_detect_pipe(struct intel_encoder *intel_encoder,
 	if (!mode)
 		mode = &load_detect_mode;
 
-	if (!drm_crtc_helper_set_mode(crtc, mode, 0, 0, crtc->fb)) {
+	/* We need a framebuffer large enough to accommodate all accesses
+	 * that the plane may generate whilst we perform load detection.
+	 */
+	old_fb = crtc->fb;
+	crtc->fb = intel_framebuffer_create_for_mode(dev, mode);
+	if (crtc->fb == NULL) {
+		DRM_DEBUG_KMS("failed to allocate framebuffer for load-detection\n");
+		crtc->fb = old_fb;
+		return false;
+	}
+
+	if (!drm_crtc_helper_set_mode(crtc, mode, 0, 0, old_fb)) {
 		DRM_DEBUG_KMS("failed to set mode on load-detect pipe\n");
+		crtc->fb->funcs->destroy(crtc->fb);
+		crtc->fb = old_fb;
 		return false;
 	}
 
@@ -5635,10 +5686,14 @@ void intel_release_load_detect_pipe(struct intel_encoder *intel_encoder,
 	struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
 
 	if (old->load_detect_temp) {
+		struct drm_framebuffer *fb = crtc->fb;
+
 		encoder->crtc = NULL;
 		connector->encoder = NULL;
 		crtc->enabled = drm_helper_crtc_in_use(crtc);
 		drm_helper_disable_unused_functions(dev);
+
+		fb->funcs->destroy(fb);
 	}
 
 	/* Switch crtc and encoder back off if necessary */
-- 
1.7.4.1

      parent reply	other threads:[~2011-04-20 20:16 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-04-20  9:22 Remove dead code from intel_get_load_detect_pipe Chris Wilson
2011-04-20  9:22 ` [PATCH 1/6] drm/i915: Simplify return value " Chris Wilson
2011-04-20 18:10   ` Keith Packard
2011-04-20 18:26     ` [PATCH 1/2] " Chris Wilson
2011-04-20 18:26       ` [PATCH 2/2] drm/i915: Propagate failure to set mode for load-detect pipe Chris Wilson
2011-04-20  9:22 ` [PATCH 2/6] drm/i915: Don't store temporary load-detect variables in the generic encoder Chris Wilson
2011-04-20 18:12   ` Keith Packard
2011-04-20  9:22 ` [PATCH 3/6] drm/i915: Remove unused supported_crtc from intel_load_detect_pipe Chris Wilson
2011-04-20 18:12   ` Keith Packard
2011-04-20  9:22 ` [PATCH 4/6] drm/i915: Pass the saved adjusted_mode when adding to the load-detect crtc Chris Wilson
2011-04-20 18:23   ` Keith Packard
2011-04-20 19:38     ` Chris Wilson
2011-04-20 21:00       ` Keith Packard
2011-04-20  9:22 ` [PATCH 5/6] drm/i915: Remove dead code from intel_get_load_detect_pipe() Chris Wilson
2011-04-20 18:26   ` Keith Packard
2011-04-20  9:22 ` [PATCH 6/6] drm/i915: Attach a fb to the load-detect pipe Chris Wilson
2011-04-20 18:43   ` Keith Packard
2011-04-20 18:55     ` Chris Wilson
2011-04-20 21:03       ` Keith Packard
2011-04-20 21:43         ` [PATCH] " Chris Wilson
2011-04-21  8:45           ` When in doubt, use a temporary fb Chris Wilson
2011-04-21  8:45             ` [PATCH 1/3] drm/i915: Remove dead code from intel_release_load_detect_pipe() Chris Wilson
2011-04-21  8:45             ` [PATCH 2/3] drm/i915: Attach a fb to the load-detect pipe Chris Wilson
2011-04-21  8:45             ` [PATCH 3/3] drm/i915: Move the tracking of dpms_mode down into crtc enable/disable Chris Wilson
2011-04-20 20:16     ` Chris Wilson [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1303330596-32628-1-git-send-email-chris@chris-wilson.co.uk \
    --to=chris@chris-wilson.co.uk \
    --cc=intel-gfx@lists.freedesktop.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.