From patchwork Fri Jun 24 15:20:32 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Chris Wilson X-Patchwork-Id: 9197787 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 0E6366075F for ; Fri, 24 Jun 2016 15:21:04 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id F3101284A2 for ; Fri, 24 Jun 2016 15:21:03 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id E7E94284A4; Fri, 24 Jun 2016 15:21:03 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.1 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_MED,T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 3F6FE284A2 for ; Fri, 24 Jun 2016 15:21:03 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id D82896EAEA; Fri, 24 Jun 2016 15:20:59 +0000 (UTC) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mail-wm0-x243.google.com (mail-wm0-x243.google.com [IPv6:2a00:1450:400c:c09::243]) by gabe.freedesktop.org (Postfix) with ESMTPS id A03DD6EAEC for ; Fri, 24 Jun 2016 15:20:43 +0000 (UTC) Received: by mail-wm0-x243.google.com with SMTP id c82so5795005wme.3 for ; Fri, 24 Jun 2016 08:20:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=+BXAjnEqfcXzpC5s4yVk3itpMKytHjrVftGiO1Pi2UU=; b=xBGpQps3qpR4f0eem9sz3MogTj4SNuvuG7Fb9dWP4Djz8MD64NPVOmHPS1IcDCCiM0 ENcjoVW7ueX0bcFjqwb+Hhf0GTHxUTBq0ccMigjPmUE77UcR3CbFS2S0liBYmmjZIuaA fY29y2pyEg647W8mPZ9DyW6dRIwZ3S6b5OrpJDZIks4vMUisrktEn3UHswoITPULEqTM t8a/CDBMauy61nQQcNoumiG9E5R9ZkOp0DUyX1Wzd6ZH+xQAQpO6IQWpEsfbWUPlz8kX hiRGKeeSe77/IT8vnNg/dR/QyuvCAEXcTlOKo8L9XFnK96/CGQq6tUh3CLqJleXKyN+D siKA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=+BXAjnEqfcXzpC5s4yVk3itpMKytHjrVftGiO1Pi2UU=; b=nCP3M6QK1H/XtiNRaZHJJRdEjNoXf/wJ0AAri6h/5ggOmHTbSJyf0VgKdrMF6+GK7c zeEgVyqpFDX8g0D0vlcEu+oAlazWtYWpH0pOAwocXRVnEEke1DW9W0LdIJSgRfG+vkqC 5k2qrTNDTPFz1moJ/bdLtJG0QG+e6JuUj1fWZeMze08LYv6gCZliDfEDgC7A+ozEh/97 T7ienSW75xG3paEKr5RT+Jc8THXA5QNu/TnEIb2iodBB6Yg2vGYEPHIPjcuCtaJfL7Qz IKWwutVPvdTPl1HUbAPw1+AX2uH4U70AFOgLjwCmSntvufLUSywVE4KHaRpo+itxRz8n Zurw== X-Gm-Message-State: ALyK8tICNbp0Oru3/6fsdooOk3lGy16dzzX7do8hQ7Dk3tbihTTYcTZwKBQ1EiEeaQa+fQ== X-Received: by 10.194.5.40 with SMTP id p8mr4447558wjp.56.1466781641676; Fri, 24 Jun 2016 08:20:41 -0700 (PDT) Received: from haswell.alporthouse.com ([78.156.65.138]) by smtp.gmail.com with ESMTPSA id q69sm3600441wmd.4.2016.06.24.08.20.40 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 24 Jun 2016 08:20:40 -0700 (PDT) From: Chris Wilson To: intel-gfx@lists.freedesktop.org Date: Fri, 24 Jun 2016 16:20:32 +0100 Message-Id: <1466781632-13432-3-git-send-email-chris@chris-wilson.co.uk> X-Mailer: git-send-email 2.8.1 In-Reply-To: <1466781632-13432-1-git-send-email-chris@chris-wilson.co.uk> References: <1466781632-13432-1-git-send-email-chris@chris-wilson.co.uk> MIME-Version: 1.0 Cc: Mika Kuoppala Subject: [Intel-gfx] [PATCH 3/3] drm/i915: Defer enabling rc6 til after we submit the first batch/context X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" X-Virus-Scanned: ClamAV using ClamSMTP Some hardware requires a valid render context before it can initiate rc6 power gating of the GPU; the default state of the GPU is not sufficient and may lead to undefined behaviour. The first execution of any batch will load the "golden render state", at which point it is safe to enable rc6. As we do not forcibly load the kernel context at resume, we have to hook into the batch submission to be sure that the render state is setup before enabling rc6. However, since we don't enable powersaving until that first batch, we queued a delayed task in order to guarantee that the batch is indeed submitted. v2: Rearrange intel_disable_gt_powersave() to match. v3: Apply user specified cur_freq (or idle_freq if not set). v4: Give in, and supply a delayed work to autoenable rc6 Signed-off-by: Chris Wilson Cc: Mika Kuoppala Cc: Ville Syrjälä --- drivers/gpu/drm/i915/i915_drv.c | 7 +- drivers/gpu/drm/i915/intel_display.c | 3 +- drivers/gpu/drm/i915/intel_drv.h | 2 + drivers/gpu/drm/i915/intel_pm.c | 151 +++++++++++++++++++++-------------- drivers/gpu/drm/i915/intel_uncore.c | 2 +- 5 files changed, 98 insertions(+), 67 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index b98afbd33235..e5f2551a2fd7 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -2021,6 +2021,7 @@ static int i915_drm_resume(struct drm_device *dev) intel_opregion_notify_adapter(dev_priv, PCI_D0); + intel_autoenable_gt_powersave(dev_priv); drm_kms_helper_poll_enable(dev); enable_rpm_wakeref_asserts(dev_priv); @@ -2217,8 +2218,7 @@ int i915_reset(struct drm_i915_private *dev_priv) * previous concerns that it doesn't respond well to some forms * of re-init after reset. */ - if (INTEL_INFO(dev)->gen > 5) - intel_enable_gt_powersave(dev_priv); + intel_autoenable_gt_powersave(dev_priv); return 0; @@ -2841,7 +2841,6 @@ static int intel_runtime_resume(struct device *device) * we can do is to hope that things will still work (and disable RPM). */ i915_gem_init_swizzling(dev); - gen6_update_ring_freq(dev_priv); intel_runtime_pm_enable_interrupts(dev_priv); @@ -2853,7 +2852,7 @@ static int intel_runtime_resume(struct device *device) if (!IS_VALLEYVIEW(dev_priv) && !IS_CHERRYVIEW(dev_priv)) intel_hpd_init(dev_priv); - intel_enable_gt_powersave(dev_priv); + intel_autoenable_gt_powersave(dev_priv); enable_rpm_wakeref_asserts(dev_priv); diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index c3b5dc8f5e80..699da067bb85 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -10976,6 +10976,7 @@ void intel_mark_busy(struct drm_i915_private *dev_priv) return; intel_runtime_pm_get(dev_priv); + intel_enable_gt_powersave(dev_priv); i915_update_gfx_val(dev_priv); if (INTEL_GEN(dev_priv) >= 6) gen6_rps_busy(dev_priv); @@ -15545,7 +15546,6 @@ void intel_modeset_init_hw(struct drm_device *dev) dev_priv->atomic_cdclk_freq = dev_priv->cdclk_freq; intel_init_clock_gating(dev); - intel_enable_gt_powersave(dev_priv); } /* @@ -16340,6 +16340,7 @@ void intel_modeset_cleanup(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; + intel_suspend_gt_powersave(dev_priv); intel_disable_gt_powersave(dev_priv); /* diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 3156d8df7921..1f06e7ff5931 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1662,7 +1662,9 @@ void intel_gpu_ips_init(struct drm_i915_private *dev_priv); void intel_gpu_ips_teardown(void); void intel_init_gt_powersave(struct drm_i915_private *dev_priv); void intel_cleanup_gt_powersave(struct drm_i915_private *dev_priv); +void intel_sanitize_gt_powersave(struct drm_i915_private *dev_priv); void intel_enable_gt_powersave(struct drm_i915_private *dev_priv); +void intel_autoenable_gt_powersave(struct drm_i915_private *dev_priv); void intel_disable_gt_powersave(struct drm_i915_private *dev_priv); void intel_suspend_gt_powersave(struct drm_i915_private *dev_priv); void intel_reset_gt_powersave(struct drm_i915_private *dev_priv); diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 78b35b86e80d..4f612b96224e 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -6522,13 +6522,6 @@ void intel_cleanup_gt_powersave(struct drm_i915_private *dev_priv) intel_runtime_pm_put(dev_priv); } -static void gen6_suspend_rps(struct drm_i915_private *dev_priv) -{ - flush_delayed_work(&dev_priv->rps.delayed_resume_work); - - gen6_disable_rps_interrupts(dev_priv); -} - /** * intel_suspend_gt_powersave - suspend PM work and helper threads * @dev_priv: i915 device @@ -6542,50 +6535,65 @@ void intel_suspend_gt_powersave(struct drm_i915_private *dev_priv) if (INTEL_GEN(dev_priv) < 6) return; - gen6_suspend_rps(dev_priv); + cancel_delayed_work_sync(&dev_priv->rps.delayed_resume_work); + + gen6_disable_rps_interrupts(dev_priv); /* Force GPU to min freq during suspend */ gen6_rps_idle(dev_priv); } +void intel_sanitize_gt_powersave(struct drm_i915_private *dev_priv) +{ + dev_priv->rps.enabled = true; /* force disabling */ + intel_disable_gt_powersave(dev_priv); + + gen6_reset_rps_interrupts(dev_priv); +} + void intel_disable_gt_powersave(struct drm_i915_private *dev_priv) { - if (IS_IRONLAKE_M(dev_priv)) { - ironlake_disable_drps(dev_priv); - } else if (INTEL_INFO(dev_priv)->gen >= 6) { - intel_suspend_gt_powersave(dev_priv); + if (!READ_ONCE(dev_priv->rps.enabled)) + return; - mutex_lock(&dev_priv->rps.hw_lock); - if (INTEL_INFO(dev_priv)->gen >= 9) { - gen9_disable_rc6(dev_priv); - gen9_disable_rps(dev_priv); - } else if (IS_CHERRYVIEW(dev_priv)) - cherryview_disable_rps(dev_priv); - else if (IS_VALLEYVIEW(dev_priv)) - valleyview_disable_rps(dev_priv); - else - gen6_disable_rps(dev_priv); + mutex_lock(&dev_priv->rps.hw_lock); - dev_priv->rps.enabled = false; - mutex_unlock(&dev_priv->rps.hw_lock); + if (INTEL_GEN(dev_priv) >= 9) { + gen9_disable_rc6(dev_priv); + gen9_disable_rps(dev_priv); + } else if (IS_CHERRYVIEW(dev_priv)) { + cherryview_disable_rps(dev_priv); + } else if (IS_VALLEYVIEW(dev_priv)) { + valleyview_disable_rps(dev_priv); + } else if (INTEL_GEN(dev_priv) >= 6) { + gen6_disable_rps(dev_priv); + } else if (IS_IRONLAKE_M(dev_priv)) { + ironlake_disable_drps(dev_priv); } + + dev_priv->rps.enabled = false; + mutex_unlock(&dev_priv->rps.hw_lock); } -static void intel_gen6_powersave_work(struct work_struct *work) +void intel_enable_gt_powersave(struct drm_i915_private *dev_priv) { - struct drm_i915_private *dev_priv = - container_of(work, struct drm_i915_private, - rps.delayed_resume_work.work); + /* We shouldn't be disabling as we submit, so this should be less + * racy than it appears! + */ + if (READ_ONCE(dev_priv->rps.enabled)) + return; - mutex_lock(&dev_priv->rps.hw_lock); + /* Powersaving is controlled by the host when inside a VM */ + if (intel_vgpu_active(dev_priv)) + return; - gen6_reset_rps_interrupts(dev_priv); + mutex_lock(&dev_priv->rps.hw_lock); if (IS_CHERRYVIEW(dev_priv)) { cherryview_enable_rps(dev_priv); } else if (IS_VALLEYVIEW(dev_priv)) { valleyview_enable_rps(dev_priv); - } else if (INTEL_INFO(dev_priv)->gen >= 9) { + } else if (INTEL_GEN(dev_priv) >= 9) { gen9_enable_rc6(dev_priv); gen9_enable_rps(dev_priv); if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) @@ -6593,9 +6601,12 @@ static void intel_gen6_powersave_work(struct work_struct *work) } else if (IS_BROADWELL(dev_priv)) { gen8_enable_rps(dev_priv); __gen6_update_ring_freq(dev_priv); - } else { + } else if (INTEL_GEN(dev_priv) >= 6) { gen6_enable_rps(dev_priv); __gen6_update_ring_freq(dev_priv); + } else if (IS_IRONLAKE_M(dev_priv)) { + ironlake_enable_drps(dev_priv); + intel_init_emon(dev_priv); } WARN_ON(dev_priv->rps.max_freq < dev_priv->rps.min_freq); @@ -6604,43 +6615,61 @@ static void intel_gen6_powersave_work(struct work_struct *work) WARN_ON(dev_priv->rps.efficient_freq < dev_priv->rps.min_freq); WARN_ON(dev_priv->rps.efficient_freq > dev_priv->rps.max_freq); + if (INTEL_GEN(dev_priv) >= 6) + gen6_enable_rps_interrupts(dev_priv); + dev_priv->rps.enabled = true; + mutex_unlock(&dev_priv->rps.hw_lock); +} - gen6_enable_rps_interrupts(dev_priv); +static void __intel_autoenable_gt_powersave(struct work_struct *work) +{ + struct drm_i915_private *dev_priv = + container_of(work, typeof(*dev_priv), rps.delayed_resume_work.work); + struct intel_engine_cs *rcs; + struct drm_i915_gem_request *req; + int ret; - mutex_unlock(&dev_priv->rps.hw_lock); + if (READ_ONCE(dev_priv->rps.enabled)) + return; + + rcs = &dev_priv->engine[RCS]; + if (rcs->last_context) + return; + + if (!rcs->init_context) + return; + + intel_runtime_pm_get(dev_priv); + mutex_lock(&dev_priv->dev->struct_mutex); + + req = i915_gem_request_alloc(rcs, dev_priv->kernel_context); + if (IS_ERR(req)) + goto unlock; + + ret = 0; + if (!i915.enable_execlists) + ret = i915_switch_context(req); + if (ret == 0) + rcs->init_context(req); + i915_add_request_no_flush(req); +unlock: + mutex_unlock(&dev_priv->dev->struct_mutex); intel_runtime_pm_put(dev_priv); } -void intel_enable_gt_powersave(struct drm_i915_private *dev_priv) +void intel_autoenable_gt_powersave(struct drm_i915_private *dev_priv) { - /* Powersaving is controlled by the host when inside a VM */ - if (intel_vgpu_active(dev_priv)) + if (READ_ONCE(dev_priv->rps.enabled)) return; - if (IS_IRONLAKE_M(dev_priv)) { - ironlake_enable_drps(dev_priv); - mutex_lock(&dev_priv->dev->struct_mutex); - intel_init_emon(dev_priv); - mutex_unlock(&dev_priv->dev->struct_mutex); - } else if (INTEL_INFO(dev_priv)->gen >= 6) { - /* - * PCU communication is slow and this doesn't need to be - * done at any specific time, so do this out of our fast path - * to make resume and init faster. - * - * We depend on the HW RC6 power context save/restore - * mechanism when entering D3 through runtime PM suspend. So - * disable RPM until RPS/RC6 is properly setup. We can only - * get here via the driver load/system resume/runtime resume - * paths, so the _noresume version is enough (and in case of - * runtime resume it's necessary). - */ - if (schedule_delayed_work(&dev_priv->rps.delayed_resume_work, - round_jiffies_up_relative(HZ))) - intel_runtime_pm_get_noresume(dev_priv); - } + if (INTEL_GEN(dev_priv) < 6) + return; + + queue_delayed_work(dev_priv->wq, + &dev_priv->rps.delayed_resume_work, + round_jiffies_up_relative(2*HZ)); } void intel_reset_gt_powersave(struct drm_i915_private *dev_priv) @@ -6648,7 +6677,7 @@ void intel_reset_gt_powersave(struct drm_i915_private *dev_priv) if (INTEL_INFO(dev_priv)->gen < 6) return; - gen6_suspend_rps(dev_priv); + gen6_disable_rps_interrupts(dev_priv); dev_priv->rps.enabled = false; } @@ -7746,7 +7775,7 @@ void intel_pm_setup(struct drm_device *dev) spin_lock_init(&dev_priv->rps.client_lock); INIT_DELAYED_WORK(&dev_priv->rps.delayed_resume_work, - intel_gen6_powersave_work); + __intel_autoenable_gt_powersave); INIT_LIST_HEAD(&dev_priv->rps.clients); INIT_LIST_HEAD(&dev_priv->rps.semaphores.link); INIT_LIST_HEAD(&dev_priv->rps.mmioflips.link); diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c index c1ca458d688e..1c7ae9dd8cae 100644 --- a/drivers/gpu/drm/i915/intel_uncore.c +++ b/drivers/gpu/drm/i915/intel_uncore.c @@ -435,7 +435,7 @@ void intel_uncore_sanitize(struct drm_i915_private *dev_priv) i915.enable_rc6 = sanitize_rc6_option(dev_priv, i915.enable_rc6); /* BIOS often leaves RC6 enabled, but disable it for hw init */ - intel_disable_gt_powersave(dev_priv); + intel_sanitize_gt_powersave(dev_priv); } static void __intel_uncore_forcewake_get(struct drm_i915_private *dev_priv,