From patchwork Fri Mar 23 12:34:09 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Micha=C5=82_Winiarski?= X-Patchwork-Id: 10304521 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 84A3760385 for ; Fri, 23 Mar 2018 12:36:31 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 75E9528E35 for ; Fri, 23 Mar 2018 12:36:31 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 6A8FC28E38; Fri, 23 Mar 2018 12:36:31 +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.2 required=2.0 tests=BAYES_00, 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 A553328E35 for ; Fri, 23 Mar 2018 12:36:30 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 06F7D6E333; Fri, 23 Mar 2018 12:36:30 +0000 (UTC) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mga04.intel.com (mga04.intel.com [192.55.52.120]) by gabe.freedesktop.org (Postfix) with ESMTPS id 962B96E333 for ; Fri, 23 Mar 2018 12:36:28 +0000 (UTC) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by fmsmga104.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 23 Mar 2018 05:36:28 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.48,350,1517904000"; d="scan'208";a="39985549" Received: from irsmsx102.ger.corp.intel.com ([163.33.3.155]) by fmsmga004.fm.intel.com with ESMTP; 23 Mar 2018 05:36:26 -0700 Received: from localhost (172.28.172.64) by IRSMSX102.ger.corp.intel.com (163.33.3.155) with Microsoft SMTP Server (TLS) id 14.3.319.2; Fri, 23 Mar 2018 12:36:26 +0000 From: =?UTF-8?q?Micha=C5=82=20Winiarski?= To: Date: Fri, 23 Mar 2018 13:34:09 +0100 Message-ID: <20180323123411.3214-6-michal.winiarski@intel.com> X-Mailer: git-send-email 2.14.3 In-Reply-To: <20180323123411.3214-1-michal.winiarski@intel.com> References: <20180323123411.3214-1-michal.winiarski@intel.com> MIME-Version: 1.0 X-Originating-IP: [172.28.172.64] Subject: [Intel-gfx] [PATCH 6/8] drm/i915/guc: Don't give up on WOPCM partitioning regs mismatch X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.23 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 It's possible that when we're being loaded, the write-once registers were already programmed. It's also possible, that values present in those registers match our FW size and HW restrictions. Rather than failing the module load when we detect any differences from our preferred values, let's replace them with what's present in the registers, failing the load only if we're unable to satisfy the constraints. Signed-off-by: MichaƂ Winiarski Cc: Chris Wilson Cc: Jackie Li Cc: Joonas Lahtinen Cc: Michal Wajdeczko --- drivers/gpu/drm/i915/i915_gem.c | 6 +-- drivers/gpu/drm/i915/intel_wopcm.c | 107 +++++++++++++++++++------------------ drivers/gpu/drm/i915/intel_wopcm.h | 6 ++- 3 files changed, 60 insertions(+), 59 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 802df8e1a544..1b25eadc5940 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -5154,11 +5154,7 @@ int i915_gem_init_hw(struct drm_i915_private *dev_priv) goto out; } - ret = intel_wopcm_init_hw(&dev_priv->wopcm); - if (ret) { - DRM_ERROR("Enabling WOPCM failed (%d)\n", ret); - goto out; - } + intel_wopcm_init_hw(&dev_priv->wopcm); /* We can't enable contexts until all firmware is loaded */ ret = intel_uc_init_hw(dev_priv); diff --git a/drivers/gpu/drm/i915/intel_wopcm.c b/drivers/gpu/drm/i915/intel_wopcm.c index 295d302e97b9..be8fca80aeca 100644 --- a/drivers/gpu/drm/i915/intel_wopcm.c +++ b/drivers/gpu/drm/i915/intel_wopcm.c @@ -182,7 +182,7 @@ __guc_region_grow(struct intel_wopcm *wopcm, u32 size) wopcm->guc.size += size; } -static void wopcm_adjust_for_hw_restrictions(struct intel_wopcm *wopcm) +static int wopcm_adjust_for_hw_restrictions(struct intel_wopcm *wopcm) { struct drm_i915_private *i915 = wopcm_to_i915(wopcm); u32 huc_fw_size = intel_uc_fw_get_upload_size(&i915->huc.fw); @@ -191,19 +191,29 @@ static void wopcm_adjust_for_hw_restrictions(struct intel_wopcm *wopcm) if (IS_GEN9(i915) || IS_CNL_REVID(i915, CNL_REVID_A0, CNL_REVID_A0)) { size = gen9_size_for_dword_gap_restriction(wopcm->guc.base, wopcm->guc.size); - if (size) + if (size) { + if (wopcm->guc.base_locked || wopcm->guc.size_locked) + return -E2BIG; + __guc_region_grow(wopcm, size); + } size = gen9_size_for_huc_restriction(wopcm->guc.size, huc_fw_size); - if (size) + if (size) { + if (wopcm->guc.base_locked || wopcm->guc.size_locked) + return -E2BIG; + __guc_region_grow(wopcm, size); + } GEM_BUG_ON(gen9_size_for_dword_gap_restriction(wopcm->guc.base, wopcm->guc.size)); GEM_BUG_ON(gen9_size_for_huc_restriction(wopcm->guc.size, huc_fw_size)); } + + return 0; } static bool wopcm_check_components_fit(struct intel_wopcm *wopcm) @@ -233,12 +243,30 @@ static int wopcm_guc_region_init(struct intel_wopcm *wopcm) { struct drm_i915_private *dev_priv = wopcm_to_i915(wopcm); u32 guc_fw_size = intel_uc_fw_get_upload_size(&dev_priv->guc.fw); + u32 huc_fw_size = intel_uc_fw_get_upload_size(&dev_priv->huc.fw); u32 ctx_rsvd = context_reserved_size(dev_priv); + u32 reg_val; - wopcm->guc.size = guc_fw_size_in_wopcm(guc_fw_size); + reg_val = I915_READ(GUC_WOPCM_SIZE); + if (reg_val & GUC_WOPCM_SIZE_LOCKED) { + wopcm->guc.size = (reg_val & GUC_WOPCM_SIZE_MASK); + wopcm->guc.size_locked = true; + } else { + wopcm->guc.size = guc_fw_size_in_wopcm(guc_fw_size); + } - wopcm->guc.base = ALIGN_DOWN(wopcm->size - ctx_rsvd - wopcm->guc.size, - GUC_WOPCM_OFFSET_ALIGNMENT); + reg_val = I915_READ(DMA_GUC_WOPCM_OFFSET); + if (reg_val & GUC_WOPCM_OFFSET_VALID) { + if (huc_fw_size && !(reg_val & HUC_LOADING_AGENT_GUC)) + return -EIO; + + wopcm->guc.base = (reg_val & GUC_WOPCM_OFFSET_MASK); + wopcm->guc.base_locked = true; + } else { + wopcm->guc.base = ALIGN_DOWN(wopcm->size - wopcm->guc.size - + ctx_rsvd, + GUC_WOPCM_OFFSET_ALIGNMENT); + } return 0; } @@ -265,7 +293,9 @@ int intel_wopcm_init(struct intel_wopcm *wopcm) if (err) return err; - wopcm_adjust_for_hw_restrictions(wopcm); + err = wopcm_adjust_for_hw_restrictions(wopcm); + if (err) + return err; err = wopcm_check_components_fit(wopcm); if (err) @@ -278,66 +308,37 @@ int intel_wopcm_init(struct intel_wopcm *wopcm) return 0; } -static inline int write_and_verify(struct drm_i915_private *dev_priv, - i915_reg_t reg, u32 val, u32 mask, - u32 locked_bit) -{ - u32 reg_val; - - GEM_BUG_ON(val & ~mask); - - I915_WRITE(reg, val); - - reg_val = I915_READ(reg); - - return (reg_val & mask) != (val | locked_bit) ? -EIO : 0; -} - /** * intel_wopcm_init_hw() - Setup GuC WOPCM registers. * @wopcm: pointer to intel_wopcm. * - * Setup the GuC WOPCM size and offset registers with the calculated values. It - * will verify the register values to make sure the registers are locked with - * correct values. + * Setup the GuC WOPCM size and offset registers with the calculated values. * - * Return: 0 on success. -EIO if registers were locked with incorrect values. */ -int intel_wopcm_init_hw(struct intel_wopcm *wopcm) +void intel_wopcm_init_hw(struct intel_wopcm *wopcm) { struct drm_i915_private *dev_priv = wopcm_to_i915(wopcm); - u32 huc_agent; - u32 mask; - int err; if (!USES_GUC(dev_priv)) - return 0; + return; GEM_BUG_ON(!HAS_GUC(dev_priv)); GEM_BUG_ON(!wopcm->guc.size); GEM_BUG_ON(!wopcm->guc.base); - err = write_and_verify(dev_priv, GUC_WOPCM_SIZE, wopcm->guc.size, - GUC_WOPCM_SIZE_MASK | GUC_WOPCM_SIZE_LOCKED, - GUC_WOPCM_SIZE_LOCKED); - if (err) - goto err_out; - - huc_agent = USES_HUC(dev_priv) ? HUC_LOADING_AGENT_GUC : 0; - mask = GUC_WOPCM_OFFSET_MASK | GUC_WOPCM_OFFSET_VALID | huc_agent; - err = write_and_verify(dev_priv, DMA_GUC_WOPCM_OFFSET, - wopcm->guc.base | huc_agent, mask, - GUC_WOPCM_OFFSET_VALID); - if (err) - goto err_out; - - return 0; - -err_out: - DRM_ERROR("Failed to init WOPCM registers:\n"); - DRM_ERROR("DMA_GUC_WOPCM_OFFSET=%#x\n", - I915_READ(DMA_GUC_WOPCM_OFFSET)); - DRM_ERROR("GUC_WOPCM_SIZE=%#x\n", I915_READ(GUC_WOPCM_SIZE)); + if (!wopcm->guc.size_locked) { + I915_WRITE(GUC_WOPCM_SIZE, wopcm->guc.size & + GUC_WOPCM_SIZE_MASK); + wopcm->guc.size_locked = true; + GEM_BUG_ON(!I915_READ(GUC_WOPCM_SIZE) & GUC_WOPCM_SIZE_LOCKED); + } - return err; + if (!wopcm->guc.base_locked) { + I915_WRITE(DMA_GUC_WOPCM_OFFSET, + (GUC_WOPCM_OFFSET_MASK & wopcm->guc.base) | + HUC_LOADING_AGENT_GUC); + wopcm->guc.size_locked = true; + GEM_BUG_ON(!I915_READ(DMA_GUC_WOPCM_OFFSET) & + GUC_WOPCM_OFFSET_VALID); + } } diff --git a/drivers/gpu/drm/i915/intel_wopcm.h b/drivers/gpu/drm/i915/intel_wopcm.h index 6298910a384c..144232999bfe 100644 --- a/drivers/gpu/drm/i915/intel_wopcm.h +++ b/drivers/gpu/drm/i915/intel_wopcm.h @@ -14,18 +14,22 @@ * @size: Size of overall WOPCM. * @guc: GuC WOPCM Region info. * @guc.base: GuC WOPCM base which is offset from WOPCM base. + * @guc.base_locked: True if base register was locked during partitioning. * @guc.size: Size of the GuC WOPCM region. + * @guc.size_locked: True if size register was locked during partitioning. */ struct intel_wopcm { u32 size; struct { u32 base; + bool base_locked; u32 size; + bool size_locked; } guc; }; void intel_wopcm_init_early(struct intel_wopcm *wopcm); int intel_wopcm_init(struct intel_wopcm *wopcm); -int intel_wopcm_init_hw(struct intel_wopcm *wopcm); +void intel_wopcm_init_hw(struct intel_wopcm *wopcm); #endif