From patchwork Fri Oct 30 16:50:41 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Ville Syrjala X-Patchwork-Id: 11870287 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-12.7 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH,MAILING_LIST_MULTI,SIGNED_OFF_BY, SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7CA7FC55178 for ; Fri, 30 Oct 2020 16:51:11 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 18156208B6 for ; Fri, 30 Oct 2020 16:51:11 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 18156208B6 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=linux.intel.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=intel-gfx-bounces@lists.freedesktop.org Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 943F66E9D9; Fri, 30 Oct 2020 16:51:10 +0000 (UTC) Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) by gabe.freedesktop.org (Postfix) with ESMTPS id AD7FC6E9DC for ; Fri, 30 Oct 2020 16:51:06 +0000 (UTC) IronPort-SDR: 5tuUBTS8QmY03WXu8RIkg7XVtbl5QtEYWXm43mXt2dC+fJYrDBU136Hl0YVG/jcj2facrXT/JB rLu7WrgmWEig== X-IronPort-AV: E=McAfee;i="6000,8403,9790"; a="165136349" X-IronPort-AV: E=Sophos;i="5.77,434,1596524400"; d="scan'208";a="165136349" X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga008.jf.intel.com ([10.7.209.65]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 30 Oct 2020 09:51:06 -0700 IronPort-SDR: /hOcMmb/SkS82NVWsOGrs0h/HoU2A4sr3HOSwS36ytz3wMpe9Xf3o380xIhRdsOlghRyn6fMqM /847axs+k2bA== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.77,434,1596524400"; d="scan'208";a="351341248" Received: from stinkbox.fi.intel.com (HELO stinkbox) ([10.237.72.174]) by orsmga008.jf.intel.com with SMTP; 30 Oct 2020 09:51:04 -0700 Received: by stinkbox (sSMTP sendmail emulation); Fri, 30 Oct 2020 18:51:03 +0200 From: Ville Syrjala To: intel-gfx@lists.freedesktop.org Date: Fri, 30 Oct 2020 18:50:41 +0200 Message-Id: <20201030165045.5000-7-ville.syrjala@linux.intel.com> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20201030165045.5000-1-ville.syrjala@linux.intel.com> References: <20201030165045.5000-1-ville.syrjala@linux.intel.com> MIME-Version: 1.0 Subject: [Intel-gfx] [PATCH 06/10] drm/i915: Stash away the original SSKPD latency values X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.29 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" From: Ville Syrjälä On ILK-IVB we must write the latency value read from SSKPD into the latency field in the WM_LP registers. While bspec was never clear on how the punit (or whatever) interprets these values empirical evidence has shown that these are treated as a cookie rather than as a literal latency value. That is, if we write a value that we didn't get from SSKPD (just off by one is sufficient) the system no longer appears to enter the corresponding power saving state. This was made much more obvious on HSW/BDW since there we longer write the latency value into the WM_LP registers, and rather we write the desired watermark level number (well, 2x the level number). Since we allow the user to adjust the latency values via debugfs, and since we have some quirks where we adjust the values automagically, we must stash away the originals read from SSKPD for later use in the WM_LP registers. v2: s/latency/cookie/ to make it clear what it is s/u16/u8/ since the reg can only hold 7 bits Signed-off-by: Ville Syrjälä --- drivers/gpu/drm/i915/i915_drv.h | 6 ++++++ drivers/gpu/drm/i915/intel_pm.c | 37 +++++++++++++++++++++++---------- 2 files changed, 32 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 0d05f7586e19..533afb4da3c0 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1135,6 +1135,12 @@ struct drm_i915_private { * FIXME get rid of this. */ bool distrust_bios_wm; + + /* + * The values we must write to the LP watermark + * registers' latency field on ILK-BDW. + */ + u8 ilk_wm_lp_cookie[5]; } wm; struct dram_info { diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 61bb36239930..5db20bf36302 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -3085,10 +3085,35 @@ static void snb_wm_lp3_irq_quirk(struct drm_i915_private *dev_priv) intel_print_wm_latency(dev_priv, "Cursor", dev_priv->wm.cur_latency); } +/* The value we need to program into the WM_LPx latency field */ +static u16 ilk_wm_lp_cookie(struct drm_i915_private *dev_priv, int level) +{ + if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) + return 2 * level; + else + return dev_priv->wm.pri_latency[level]; +} + +static void ilk_setup_wm_lp_cookie(struct drm_i915_private *dev_priv) +{ + int level, max_level = ilk_wm_max_level(dev_priv); + + for (level = 1; level <= max_level; level++) + dev_priv->wm.ilk_wm_lp_cookie[level] = + ilk_wm_lp_cookie(dev_priv, level); +} + static void ilk_setup_wm_latency(struct drm_i915_private *dev_priv) { intel_read_wm_latency(dev_priv, dev_priv->wm.pri_latency); + /* + * On ILK-IVB the values written to the LP watermark register + * latency field must match SSKPD 100%. So do this before any + * adjustments are made to the latency values we got from SSKPD. + */ + ilk_setup_wm_lp_cookie(dev_priv); + memcpy(dev_priv->wm.spr_latency, dev_priv->wm.pri_latency, sizeof(dev_priv->wm.pri_latency)); memcpy(dev_priv->wm.cur_latency, dev_priv->wm.pri_latency, @@ -3366,16 +3391,6 @@ static int ilk_wm_lp_to_level(int wm_lp, const struct ilk_wm_state *pipe_wm) return wm_lp + (wm_lp >= 2 && pipe_wm->wm[4].enable); } -/* The value we need to program into the WM_LPx latency field */ -static unsigned int ilk_wm_lp_latency(struct drm_i915_private *dev_priv, - int level) -{ - if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) - return 2 * level; - else - return dev_priv->wm.pri_latency[level]; -} - static void ilk_compute_wm_results(struct drm_i915_private *dev_priv, const struct ilk_wm_state *merged, enum ilk_ddb_partitioning partitioning, @@ -3400,7 +3415,7 @@ static void ilk_compute_wm_results(struct drm_i915_private *dev_priv, * disabled. Doing otherwise could cause underruns. */ results->wm_lp[wm_lp - 1] = - (ilk_wm_lp_latency(dev_priv, level) << WM1_LP_LATENCY_SHIFT) | + (dev_priv->wm.ilk_wm_lp_cookie[level] << WM1_LP_LATENCY_SHIFT) | (r->pri_val << WM1_LP_SR_SHIFT) | r->cur_val;