From patchwork Fri Mar 21 09:00:48 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jani Nikula X-Patchwork-Id: 3871701 Return-Path: X-Original-To: patchwork-intel-gfx@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 6FE5D9F382 for ; Fri, 21 Mar 2014 09:00:53 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 8D58B20279 for ; Fri, 21 Mar 2014 09:00:52 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id 773E020274 for ; Fri, 21 Mar 2014 09:00:51 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id C87486E283; Fri, 21 Mar 2014 02:00:50 -0700 (PDT) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mga02.intel.com (mga02.intel.com [134.134.136.20]) by gabe.freedesktop.org (Postfix) with ESMTP id 30EFC6E282 for ; Fri, 21 Mar 2014 02:00:49 -0700 (PDT) Received: from orsmga001.jf.intel.com ([10.7.209.18]) by orsmga101.jf.intel.com with ESMTP; 21 Mar 2014 02:00:48 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="4.97,702,1389772800"; d="scan'208";a="477090890" Received: from jnikula-mobl1.fi.intel.com (HELO localhost) ([10.237.72.185]) by orsmga001.jf.intel.com with ESMTP; 21 Mar 2014 02:00:30 -0700 From: Jani Nikula To: intel-gfx@lists.freedesktop.org Date: Fri, 21 Mar 2014 11:00:48 +0200 Message-Id: <1395392448-6337-1-git-send-email-jani.nikula@intel.com> X-Mailer: git-send-email 1.7.9.5 MIME-Version: 1.0 Organization: Intel Finland Oy - BIC 0357606-4 - Westendinkatu 7, 02160 Espoo Cc: jani.nikula@intel.com Subject: [Intel-gfx] [PATCH] drm/i915: Increase WM memory latency values on SNB with high pixel clock 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: , Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" X-Spam-Status: No, score=-4.2 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, T_RP_MATCHES_RCVD, 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: Ville Syrjälä On SNB the BIOS provided WM memory latency values seem insufficient to handle high resolution displays. In this particular case the display mode was a 2560x1440@60Hz, which makes the pixel clock 241.5 MHz. It was empirically found that a memory latency value if 1.2 usec is enough to avoid underruns, whereas the BIOS provided value of 0.7 usec was clearly too low. Incidentally 1.2 usec is what the typical BIOS provided values are on IVB systems. Increase the WM memory latency values to 1.2 usec when encountering a display mode with pixel clock exceeding 225 MHz. 225 MHz was chosen as the threshold simply because that's the documented limit of SNB with HDMI, so one might surmise that the hardware may have been tested up to that frequency. In theory the latency shouldn't depend on the pixel clock at all. So it may be that we should just increase the latency values across the board for all SNB systems. But for now I'm inclined to limit this quirk to only those cases that are proven to need it, as doing otherwise might cause some increase in power consumption for everyone. Cc: Robert N Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=70254 Signed-off-by: Ville Syrjälä --- I'm just relaying the patch from bugzilla to the list as it seems to fix the bug. Don't ask me anything about it. BR, Jani. --- drivers/gpu/drm/i915/intel_display.c | 10 ++++++++++ drivers/gpu/drm/i915/intel_drv.h | 1 + drivers/gpu/drm/i915/intel_pm.c | 33 +++++++++++++++++++++++++++++++++ 3 files changed, 44 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 0b19afdfbaa7..b0ac92d8f461 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -9933,6 +9933,16 @@ static int __intel_set_mode(struct drm_crtc *crtc, */ drm_calc_timestamping_constants(crtc, &pipe_config->adjusted_mode); + + + /* + * The BIOS provided WM memory latency values are often + * inadequate for high resolution displays. Adjust them. + * + * FIXME not sure 225MHz is a good threshold. + */ + if (IS_GEN6(dev) && pipe_config->adjusted_mode.crtc_clock > 225000) + snb_wm_latency_quirk(dev); } /* Only after disabling all output pipelines that will be changed can we diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 60ffad376390..b1d631c9dfa5 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -903,6 +903,7 @@ void intel_runtime_pm_put(struct drm_i915_private *dev_priv); void intel_init_runtime_pm(struct drm_i915_private *dev_priv); void intel_fini_runtime_pm(struct drm_i915_private *dev_priv); void ilk_wm_get_hw_state(struct drm_device *dev); +void snb_wm_latency_quirk(struct drm_device *dev); /* intel_sdvo.c */ diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 39f3238bf1c3..226750452637 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -2104,6 +2104,39 @@ static void ilk_setup_wm_latency(struct drm_device *dev) intel_print_wm_latency(dev, "Cursor", dev_priv->wm.cur_latency); } +static bool ilk_increase_wm_latency(struct drm_i915_private *dev_priv, + uint16_t wm[5], uint16_t min) +{ + int level, max_level = ilk_wm_max_level(dev_priv->dev); + + if (wm[0] >= min) + return false; + + wm[0] = max(wm[0], min); + for (level = 1; level <= max_level; level++) + wm[level] = max_t(uint16_t, wm[level], DIV_ROUND_UP(min, 5)); + + return true; +} + +void snb_wm_latency_quirk(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + bool changed; + + changed = ilk_increase_wm_latency(dev_priv, dev_priv->wm.pri_latency, 12) | + ilk_increase_wm_latency(dev_priv, dev_priv->wm.spr_latency, 12) | + ilk_increase_wm_latency(dev_priv, dev_priv->wm.cur_latency, 12); + + if (!changed) + return; + + DRM_DEBUG_KMS("WM latency values increased due to high pixel clock\n"); + intel_print_wm_latency(dev, "Primary", dev_priv->wm.pri_latency); + intel_print_wm_latency(dev, "Sprite", dev_priv->wm.spr_latency); + intel_print_wm_latency(dev, "Cursor", dev_priv->wm.cur_latency); +} + static void ilk_compute_wm_parameters(struct drm_crtc *crtc, struct ilk_pipe_wm_parameters *p, struct intel_wm_config *config)