From patchwork Mon Aug 11 14:29:51 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paulo Zanoni X-Patchwork-Id: 4707561 Return-Path: X-Original-To: patchwork-intel-gfx@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 59ACBC0338 for ; Mon, 11 Aug 2014 14:30:18 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 5E01020123 for ; Mon, 11 Aug 2014 14:30:17 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id 21C962011D for ; Mon, 11 Aug 2014 14:30:16 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id AA86C6E207; Mon, 11 Aug 2014 07:30:15 -0700 (PDT) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mail-yh0-f47.google.com (mail-yh0-f47.google.com [209.85.213.47]) by gabe.freedesktop.org (Postfix) with ESMTP id 369B86E207 for ; Mon, 11 Aug 2014 07:30:14 -0700 (PDT) Received: by mail-yh0-f47.google.com with SMTP id f10so6358801yha.20 for ; Mon, 11 Aug 2014 07:30:13 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=TOKy8DlKSEdPTnYQrYLiQKYJX+ojplAXAwscgloFahQ=; b=rZlNOz9R4b3SaPYKTHm56rYB7scSjuE0yABc+F1XYeOB1zHiAmfSVG/7xEek5Rto2K oFIzZxrYDtrWgo4Wm65xuuxY2F70zHMI0D2yvh/9gDwP3kgVzN7j259aBK71WOKBuGUk cA/IPgaF35nVuVD9TubLwDci5AhEr5Ycs4ltYwmPChLq8R9k/QPOHIK9dWtCmdfWhg2+ z/GVUP1xtpGlY+ZTw528CI2bXWjvka5oipeSY03QQye41PPb6JfrvQ3mdPuR2T5Ay0dI NdcHpj04TPEl5TjB86QjGKoiODs87dPYRIK3G1CnGeRkp4++EeHzWmiCctdnWeaTmh72 Q4gQ== X-Received: by 10.236.21.193 with SMTP id r41mr2888088yhr.179.1407767413501; Mon, 11 Aug 2014 07:30:13 -0700 (PDT) Received: from localhost.localdomain ([177.156.103.25]) by mx.google.com with ESMTPSA id v50sm10248694yhv.22.2014.08.11.07.30.12 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 11 Aug 2014 07:30:12 -0700 (PDT) From: Paulo Zanoni To: intel-gfx@lists.freedesktop.org Date: Mon, 11 Aug 2014 11:29:51 -0300 Message-Id: <1407767391-1764-1-git-send-email-przanoni@gmail.com> X-Mailer: git-send-email 2.0.1 In-Reply-To: References: Cc: Paulo Zanoni , stable@vger.kernel.org Subject: [Intel-gfx] [PATCH] drm/i915: fix plane/cursor handling when runtime suspended X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" X-Spam-Status: No, score=-4.8 required=5.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_MED, RP_MATCHES_RCVD, T_DKIM_INVALID, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Paulo Zanoni If we're runtime suspended and try to use the plane interfaces, we will get a lot of WARNs saying we did the wrong thing. For intel_crtc_update_cursor(), all we need to do is return if the CRTC is not active, since writing the registers won't really have any effect if the screen is not visible, and we will write the registers later when enabling the screen. For all the other cases, we need to get runtime PM references to pin/unpin the objects, and to change the fences. The pin/unpin functions are the ideal places for this, but intel_crtc_cursor_set_obj() doesn't call them, so we also have to add get/put calls inside it. There is no problem if we runtime suspend right after these functions are finished, because the registers weitten are forwarded to system memory. v2: - Narrow the put/get calls on intel_crtc_cursor_set_obj() (Daniel) v3: - Make get/put also surround the fence and unpin calls (Daniel and Ville). - Merge all the plane changes into a single patch since they're the same fix. - Add the comment requested by Daniel. v4: - Remove spurious whitespace (Ville). Testcase: igt/pm_rpm/cursor Testcase: igt/pm_rpm/cursor-dpms Testcase: igt/pm_rpm/legacy-planes Testcase: igt/pm_rpm/legacy-planes-dpms Testcase: igt/pm_rpm/universal-planes Testcase: igt/pm_rpm/universal-planes-dpms Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=81645 Cc: stable@vger.kernel.org Signed-off-by: Paulo Zanoni --- drivers/gpu/drm/i915/intel_display.c | 38 +++++++++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index e9b578e..4e1c957 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -2149,6 +2149,15 @@ intel_pin_and_fence_fb_obj(struct drm_device *dev, if (need_vtd_wa(dev) && alignment < 256 * 1024) alignment = 256 * 1024; + /* + * Global gtt pte registers are special registers which actually forward + * writes to a chunk of system memory. Which means that there is no risk + * that the register values disappear as soon as we call + * intel_runtime_pm_put(), so it is correct to wrap only the + * pin/unpin/fence and not more. + */ + intel_runtime_pm_get(dev_priv); + dev_priv->mm.interruptible = false; ret = i915_gem_object_pin_to_display_plane(obj, alignment, pipelined); if (ret) @@ -2166,21 +2175,30 @@ intel_pin_and_fence_fb_obj(struct drm_device *dev, i915_gem_object_pin_fence(obj); dev_priv->mm.interruptible = true; + intel_runtime_pm_put(dev_priv); return 0; err_unpin: i915_gem_object_unpin_from_display_plane(obj); err_interruptible: dev_priv->mm.interruptible = true; + intel_runtime_pm_put(dev_priv); return ret; } void intel_unpin_fb_obj(struct drm_i915_gem_object *obj) { - WARN_ON(!mutex_is_locked(&obj->base.dev->struct_mutex)); + struct drm_device *dev = obj->base.dev; + struct drm_i915_private *dev_priv = dev->dev_private; + + WARN_ON(!mutex_is_locked(&dev->struct_mutex)); + + intel_runtime_pm_get(dev_priv); i915_gem_object_unpin_fence(obj); i915_gem_object_unpin_from_display_plane(obj); + + intel_runtime_pm_put(dev_priv); } /* Computes the linear offset to the base tile and adjusts x, y. bytes per pixel @@ -8154,6 +8172,9 @@ static void intel_crtc_update_cursor(struct drm_crtc *crtc, if (base == 0 && intel_crtc->cursor_base == 0) return; + if (!intel_crtc->active) + return; + I915_WRITE(CURPOS(pipe), pos); if (IS_IVYBRIDGE(dev) || IS_HASWELL(dev) || IS_BROADWELL(dev)) @@ -8209,6 +8230,16 @@ static int intel_crtc_cursor_set_obj(struct drm_crtc *crtc, /* we only need to pin inside GTT if cursor is non-phy */ mutex_lock(&dev->struct_mutex); + + /* + * Global gtt pte registers are special registers which actually forward + * writes to a chunk of system memory. Which means that there is no risk + * that the register values disappear as soon as we call + * intel_runtime_pm_put(), so it is correct to wrap only the + * pin/unpin/fence and not more. + */ + intel_runtime_pm_get(dev_priv); + if (!INTEL_INFO(dev)->cursor_needs_physical) { unsigned alignment; @@ -8261,6 +8292,10 @@ static int intel_crtc_cursor_set_obj(struct drm_crtc *crtc, i915_gem_track_fb(intel_crtc->cursor_bo, obj, INTEL_FRONTBUFFER_CURSOR(pipe)); + + if (obj) + intel_runtime_pm_put(dev_priv); + mutex_unlock(&dev->struct_mutex); old_width = intel_crtc->cursor_width; @@ -8282,6 +8317,7 @@ static int intel_crtc_cursor_set_obj(struct drm_crtc *crtc, fail_unpin: i915_gem_object_unpin_from_display_plane(obj); fail_locked: + intel_runtime_pm_put(dev_priv); mutex_unlock(&dev->struct_mutex); fail: drm_gem_object_unreference_unlocked(&obj->base);