aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaulo Zanoni <paulo.r.zanoni@intel.com>2014-08-15 14:59:32 -0400
committerJani Nikula <jani.nikula@intel.com>2014-08-26 07:55:53 -0400
commitd6dd6843ff4a57c662dbc378b9f99a9c034b0956 (patch)
tree5809e7e2a8ce5380029b44ac15b2a111aa367cf4
parentdfb3d47b2369ad752ab9f7438bbf9949524b46ae (diff)
drm/i915: fix plane/cursor handling when runtime suspended
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. We need to get runtime PM references to pin the objects, and to change the fences. The pin 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 written are forwarded to system memory. Note: for a complete fix of the cursor-dpms test case, we also need the patch named "drm/i915: Don't try to enable cursor from setplane when crtc is disabled". 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). v5: - Remove intel_crtc_update_cursor() chunk since Ville did an equivalent fix in another patch (Ville). v6: - Remove unpin chunk: it will be on a separate patch (Ville, Chris, Daniel). v7: - Same thing, new color. 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 Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=82603 Cc: stable@vger.kernel.org Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com> Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Jani Nikula <jani.nikula@intel.com>
-rw-r--r--drivers/gpu/drm/i915/intel_display.c24
1 files changed, 24 insertions, 0 deletions
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 625f29d29577..c1c67e53473c 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -2233,6 +2233,15 @@ intel_pin_and_fence_fb_obj(struct drm_device *dev,
2233 if (need_vtd_wa(dev) && alignment < 256 * 1024) 2233 if (need_vtd_wa(dev) && alignment < 256 * 1024)
2234 alignment = 256 * 1024; 2234 alignment = 256 * 1024;
2235 2235
2236 /*
2237 * Global gtt pte registers are special registers which actually forward
2238 * writes to a chunk of system memory. Which means that there is no risk
2239 * that the register values disappear as soon as we call
2240 * intel_runtime_pm_put(), so it is correct to wrap only the
2241 * pin/unpin/fence and not more.
2242 */
2243 intel_runtime_pm_get(dev_priv);
2244
2236 dev_priv->mm.interruptible = false; 2245 dev_priv->mm.interruptible = false;
2237 ret = i915_gem_object_pin_to_display_plane(obj, alignment, pipelined); 2246 ret = i915_gem_object_pin_to_display_plane(obj, alignment, pipelined);
2238 if (ret) 2247 if (ret)
@@ -2250,12 +2259,14 @@ intel_pin_and_fence_fb_obj(struct drm_device *dev,
2250 i915_gem_object_pin_fence(obj); 2259 i915_gem_object_pin_fence(obj);
2251 2260
2252 dev_priv->mm.interruptible = true; 2261 dev_priv->mm.interruptible = true;
2262 intel_runtime_pm_put(dev_priv);
2253 return 0; 2263 return 0;
2254 2264
2255err_unpin: 2265err_unpin:
2256 i915_gem_object_unpin_from_display_plane(obj); 2266 i915_gem_object_unpin_from_display_plane(obj);
2257err_interruptible: 2267err_interruptible:
2258 dev_priv->mm.interruptible = true; 2268 dev_priv->mm.interruptible = true;
2269 intel_runtime_pm_put(dev_priv);
2259 return ret; 2270 return ret;
2260} 2271}
2261 2272
@@ -8240,6 +8251,15 @@ static int intel_crtc_cursor_set_obj(struct drm_crtc *crtc,
8240 goto fail_locked; 8251 goto fail_locked;
8241 } 8252 }
8242 8253
8254 /*
8255 * Global gtt pte registers are special registers which actually
8256 * forward writes to a chunk of system memory. Which means that
8257 * there is no risk that the register values disappear as soon
8258 * as we call intel_runtime_pm_put(), so it is correct to wrap
8259 * only the pin/unpin/fence and not more.
8260 */
8261 intel_runtime_pm_get(dev_priv);
8262
8243 /* Note that the w/a also requires 2 PTE of padding following 8263 /* Note that the w/a also requires 2 PTE of padding following
8244 * the bo. We currently fill all unused PTE with the shadow 8264 * the bo. We currently fill all unused PTE with the shadow
8245 * page and so we should always have valid PTE following the 8265 * page and so we should always have valid PTE following the
@@ -8252,16 +8272,20 @@ static int intel_crtc_cursor_set_obj(struct drm_crtc *crtc,
8252 ret = i915_gem_object_pin_to_display_plane(obj, alignment, NULL); 8272 ret = i915_gem_object_pin_to_display_plane(obj, alignment, NULL);
8253 if (ret) { 8273 if (ret) {
8254 DRM_DEBUG_KMS("failed to move cursor bo into the GTT\n"); 8274 DRM_DEBUG_KMS("failed to move cursor bo into the GTT\n");
8275 intel_runtime_pm_put(dev_priv);
8255 goto fail_locked; 8276 goto fail_locked;
8256 } 8277 }
8257 8278
8258 ret = i915_gem_object_put_fence(obj); 8279 ret = i915_gem_object_put_fence(obj);
8259 if (ret) { 8280 if (ret) {
8260 DRM_DEBUG_KMS("failed to release fence for cursor"); 8281 DRM_DEBUG_KMS("failed to release fence for cursor");
8282 intel_runtime_pm_put(dev_priv);
8261 goto fail_unpin; 8283 goto fail_unpin;
8262 } 8284 }
8263 8285
8264 addr = i915_gem_obj_ggtt_offset(obj); 8286 addr = i915_gem_obj_ggtt_offset(obj);
8287
8288 intel_runtime_pm_put(dev_priv);
8265 } else { 8289 } else {
8266 int align = IS_I830(dev) ? 16 * 1024 : 256; 8290 int align = IS_I830(dev) ? 16 * 1024 : 256;
8267 ret = i915_gem_object_attach_phys(obj, align); 8291 ret = i915_gem_object_attach_phys(obj, align);