From patchwork Wed Aug 23 01:44:13 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Wang, Zhi A" X-Patchwork-Id: 9915853 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 183A9603F9 for ; Tue, 22 Aug 2017 17:45:43 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id EED762888A for ; Tue, 22 Aug 2017 17:45:42 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id E389B28892; Tue, 22 Aug 2017 17:45:42 +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=-2.3 required=2.0 tests=BAYES_00, DATE_IN_FUTURE_06_12, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 6810D2888A for ; Tue, 22 Aug 2017 17:45:42 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id F1B156E43D; Tue, 22 Aug 2017 17:45:41 +0000 (UTC) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mga05.intel.com (mga05.intel.com [192.55.52.43]) by gabe.freedesktop.org (Postfix) with ESMTPS id 315766E43B; Tue, 22 Aug 2017 17:45:39 +0000 (UTC) Received: from orsmga005.jf.intel.com ([10.7.209.41]) by fmsmga105.fm.intel.com with ESMTP; 22 Aug 2017 10:45:38 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.41,413,1498546800"; d="scan'208";a="140798494" Received: from unknown (HELO zhiwang1-MOBL.ger.corp.intel.com) ([10.252.28.165]) by orsmga005.jf.intel.com with ESMTP; 22 Aug 2017 10:45:37 -0700 From: Zhi Wang To: intel-gfx@lists.freedesktop.org, intel-gvt-dev@lists.freedesktop.org Date: Wed, 23 Aug 2017 09:44:13 +0800 Message-Id: <1503452653-30903-4-git-send-email-zhi.a.wang@intel.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1503452653-30903-1-git-send-email-zhi.a.wang@intel.com> References: <1503452653-30903-1-git-send-email-zhi.a.wang@intel.com> Subject: [Intel-gfx] [RFCv3 3/3] drm/i915: Introduce per-platform PPAT configurations 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: , MIME-Version: 1.0 Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" X-Virus-Scanned: ClamAV using ClamSMTP The previous static PPAT configuration for each platform is kept unchanged and now configured through intel_ppat_reserve(). Also the PPAT feature of each platform is described in intel PPAT instance during the initialization and related callbacks which supports the PPAT management framework will be hooked. Signed-off-by: Zhi Wang --- drivers/gpu/drm/i915/i915_gem_gtt.c | 145 ++++++++++++++++++++++++------------ 1 file changed, 96 insertions(+), 49 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index 2a521b6..d103ea4 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -2857,41 +2857,92 @@ void intel_ppat_put(struct intel_ppat_entry *entry) kref_put(&entry->ref_count, put_ppat); } -static void cnl_setup_private_ppat(struct drm_i915_private *dev_priv) +static void cnl_private_pat_update(struct drm_i915_private *dev_priv) { + struct intel_ppat *ppat = &dev_priv->ppat; + int i; + + for (i = 0; i < ppat->max_entries; i++) + I915_WRITE(GEN10_PAT_INDEX(i), ppat->entries[i].value); +} + +static void bdw_private_pat_update(struct drm_i915_private *dev_priv) +{ + struct intel_ppat *ppat = &dev_priv->ppat; + u64 pat = 0; + int i; + + for (i = 0; i < ppat->max_entries; i++) + pat |= GEN8_PPAT(i, ppat->entries[i].value); + + I915_WRITE(GEN8_PRIVATE_PAT_LO, pat); + I915_WRITE(GEN8_PRIVATE_PAT_HI, pat >> 32); +} + +#define gen8_pat_ca(v) ((v) & 0x3) +#define gen8_pat_tc(v) (((v) >> 2) & 0x3) +#define gen8_pat_age(v) (((v) >> 4) & 0x3) + +static unsigned int bdw_private_pat_match(u8 src, u8 dst) +{ + unsigned int score = 0; + + /* Cache attribute has to be matched. */ + if (gen8_pat_ca(src) != gen8_pat_ca(dst)) + return 0; + + if (gen8_pat_age(src) == gen8_pat_age(dst)) + score += 1; + + if (gen8_pat_tc(src) == gen8_pat_tc(dst)) + score += 2; + + if (score == 3) + return ~0; + + return score; +} + +#define chv_get_snoop(v) (((v) >> 6) & 0x1) + +static unsigned int chv_private_pat_match(u8 src, u8 dst) +{ + if (chv_get_snoop(src) == chv_get_snoop(dst)) + return ~0; + + return 0; +} + +static void cnl_setup_private_ppat(struct intel_ppat *ppat) +{ + ppat->max_entries = 8; + ppat->update = cnl_private_pat_update; + ppat->match = bdw_private_pat_match; + ppat->dummy_value = GEN8_PPAT_LLCELLC | GEN8_PPAT_AGE(3); + /* XXX: spec is unclear if this is still needed for CNL+ */ if (!USES_PPGTT(dev_priv)) { - I915_WRITE(GEN10_PAT_INDEX(0), GEN8_PPAT_UC); + intel_ppat_reserve(ppat, 0, GEN8_PPAT_UC); return; } - I915_WRITE(GEN10_PAT_INDEX(0), GEN8_PPAT_WB | GEN8_PPAT_LLC); - I915_WRITE(GEN10_PAT_INDEX(1), GEN8_PPAT_WC | GEN8_PPAT_LLCELLC); - I915_WRITE(GEN10_PAT_INDEX(2), GEN8_PPAT_WT | GEN8_PPAT_LLCELLC); - I915_WRITE(GEN10_PAT_INDEX(3), GEN8_PPAT_UC); - I915_WRITE(GEN10_PAT_INDEX(4), GEN8_PPAT_LLCELLC | GEN8_PPAT_AGE(0)); - I915_WRITE(GEN10_PAT_INDEX(5), GEN8_PPAT_LLCELLC | GEN8_PPAT_AGE(1)); - I915_WRITE(GEN10_PAT_INDEX(6), GEN8_PPAT_LLCELLC | GEN8_PPAT_AGE(2)); - I915_WRITE(GEN10_PAT_INDEX(7), GEN8_PPAT_LLCELLC | GEN8_PPAT_AGE(3)); + intel_ppat_reserve(ppat, 0, GEN8_PPAT_WB | GEN8_PPAT_LLC); + intel_ppat_reserve(ppat, 1, GEN8_PPAT_WC | GEN8_PPAT_LLCELLC); + intel_ppat_reserve(ppat, 2, GEN8_PPAT_WT | GEN8_PPAT_LLCELLC); + intel_ppat_reserve(ppat, 3, GEN8_PPAT_UC); } /* The GGTT and PPGTT need a private PPAT setup in order to handle cacheability * bits. When using advanced contexts each context stores its own PAT, but * writing this data shouldn't be harmful even in those cases. */ -static void bdw_setup_private_ppat(struct drm_i915_private *dev_priv) +static void bdw_setup_private_ppat(struct intel_ppat *ppat) { - u64 pat; + ppat->max_entries = 8; + ppat->update = bdw_private_pat_update; + ppat->match = bdw_private_pat_match; + ppat->dummy_value = GEN8_PPAT_LLCELLC | GEN8_PPAT_AGE(3); - pat = GEN8_PPAT(0, GEN8_PPAT_WB | GEN8_PPAT_LLC) | /* for normal objects, no eLLC */ - GEN8_PPAT(1, GEN8_PPAT_WC | GEN8_PPAT_LLCELLC) | /* for something pointing to ptes? */ - GEN8_PPAT(2, GEN8_PPAT_WT | GEN8_PPAT_LLCELLC) | /* for scanout with eLLC */ - GEN8_PPAT(3, GEN8_PPAT_UC) | /* Uncached objects, mostly for scanout */ - GEN8_PPAT(4, GEN8_PPAT_WB | GEN8_PPAT_LLCELLC | GEN8_PPAT_AGE(0)) | - GEN8_PPAT(5, GEN8_PPAT_WB | GEN8_PPAT_LLCELLC | GEN8_PPAT_AGE(1)) | - GEN8_PPAT(6, GEN8_PPAT_WB | GEN8_PPAT_LLCELLC | GEN8_PPAT_AGE(2)) | - GEN8_PPAT(7, GEN8_PPAT_WB | GEN8_PPAT_LLCELLC | GEN8_PPAT_AGE(3)); - - if (!USES_PPGTT(dev_priv)) + if (!USES_PPGTT(dev_priv)) { /* Spec: "For GGTT, there is NO pat_sel[2:0] from the entry, * so RTL will always use the value corresponding to * pat_sel = 000". @@ -2905,17 +2956,22 @@ static void bdw_setup_private_ppat(struct drm_i915_private *dev_priv) * So we can still hold onto all our assumptions wrt cpu * clflushing on LLC machines. */ - pat = GEN8_PPAT(0, GEN8_PPAT_UC); + intel_ppat_reserve(ppat, 0, GEN8_PPAT_UC); + return; + } - /* XXX: spec defines this as 2 distinct registers. It's unclear if a 64b - * write would work. */ - I915_WRITE(GEN8_PRIVATE_PAT_LO, pat); - I915_WRITE(GEN8_PRIVATE_PAT_HI, pat >> 32); + intel_ppat_reserve(ppat, 0, GEN8_PPAT_WB | GEN8_PPAT_LLC); /* for normal objects, no eLLC */ + intel_ppat_reserve(ppat, 1, GEN8_PPAT_WC | GEN8_PPAT_LLCELLC); /* for something pointing to ptes? */ + intel_ppat_reserve(ppat, 2, GEN8_PPAT_WT | GEN8_PPAT_LLCELLC); /* for scanout with eLLC */ + intel_ppat_reserve(ppat, 3, GEN8_PPAT_UC); /* Uncached objects, mostly for scanout */ } -static void chv_setup_private_ppat(struct drm_i915_private *dev_priv) +static void chv_setup_private_ppat(struct intel_ppat *ppat) { - u64 pat; + ppat->max_entries = 8; + ppat->update = bdw_private_pat_update; + ppat->match = chv_private_pat_match; + ppat->dummy_value = CHV_PPAT_SNOOP; /* * Map WB on BDW to snooped on CHV. @@ -2935,17 +2991,11 @@ static void chv_setup_private_ppat(struct drm_i915_private *dev_priv) * Which means we must set the snoop bit in PAT entry 0 * in order to keep the global status page working. */ - pat = GEN8_PPAT(0, CHV_PPAT_SNOOP) | - GEN8_PPAT(1, 0) | - GEN8_PPAT(2, 0) | - GEN8_PPAT(3, 0) | - GEN8_PPAT(4, CHV_PPAT_SNOOP) | - GEN8_PPAT(5, CHV_PPAT_SNOOP) | - GEN8_PPAT(6, CHV_PPAT_SNOOP) | - GEN8_PPAT(7, CHV_PPAT_SNOOP); - I915_WRITE(GEN8_PRIVATE_PAT_LO, pat); - I915_WRITE(GEN8_PRIVATE_PAT_HI, pat >> 32); + intel_ppat_reserve(ppat, 0, CHV_PPAT_SNOOP); + intel_ppat_reserve(ppat, 1, 0); + intel_ppat_reserve(ppat, 2, 0); + intel_ppat_reserve(ppat, 3, 0); } static void gen6_gmch_remove(struct i915_address_space *vm) @@ -2963,20 +3013,23 @@ static void setup_private_pat(struct drm_i915_private *dev_priv) ppat->dev_priv = dev_priv; + /* Load per-platform PPAT configurations */ if (INTEL_GEN(dev_priv) >= 10) - cnl_setup_private_ppat(dev_priv); + cnl_setup_private_ppat(ppat); else if (IS_CHERRYVIEW(dev_priv) || IS_GEN9_LP(dev_priv)) - chv_setup_private_ppat(dev_priv); + chv_setup_private_ppat(ppat); else - bdw_setup_private_ppat(dev_priv); + bdw_setup_private_ppat(ppat); GEM_BUG_ON(ppat->max_entries > INTEL_MAX_PPAT_ENTRIES); + /* Fill unused PPAT entries with dummy PPAT value */ for_each_clear_bit(i, ppat->reserved, ppat->max_entries) { ppat->entries[i].value = ppat->dummy_value; ppat->entries[i].ppat = ppat; } + /* Write the HW */ ppat->update(dev_priv); } @@ -3291,13 +3344,7 @@ void i915_gem_restore_gtt_mappings(struct drm_i915_private *dev_priv) ggtt->base.closed = false; if (INTEL_GEN(dev_priv) >= 8) { - if (INTEL_GEN(dev_priv) >= 10) - cnl_setup_private_ppat(dev_priv); - else if (IS_CHERRYVIEW(dev_priv) || IS_GEN9_LP(dev_priv)) - chv_setup_private_ppat(dev_priv); - else - bdw_setup_private_ppat(dev_priv); - + dev_priv->ppat.update(dev_priv); return; }