[PATCH 4/8] extract-workarounds

MichaƂ Winiarski michal.winiarski at intel.com
Tue Mar 20 21:08:28 UTC 2018


---
 drivers/gpu/drm/i915/intel_wopcm.c | 64 +++++++++++++++++++++-----------------
 1 file changed, 36 insertions(+), 28 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_wopcm.c b/drivers/gpu/drm/i915/intel_wopcm.c
index c903fa6a3a67..36aef79459fb 100644
--- a/drivers/gpu/drm/i915/intel_wopcm.c
+++ b/drivers/gpu/drm/i915/intel_wopcm.c
@@ -82,9 +82,9 @@ static inline u32 context_reserved_size(struct drm_i915_private *i915)
 		return 0;
 }
 
-static int check_dword_gap(struct intel_wopcm *wopcm)
+static ssize_t gen9_wa_dword_gap_size(struct intel_wopcm *wopcm)
 {
-	u32 offset;
+	ssize_t offset;
 
 	/*
 	 * GuC WOPCM size shall be at least a dword larger than the offset from
@@ -92,31 +92,19 @@ static int check_dword_gap(struct intel_wopcm *wopcm)
 	 * due to hardware limitation on Gen9.
 	 */
 	offset = wopcm->guc.base + GEN9_GUC_WOPCM_OFFSET + sizeof(u32);
-	if (wopcm->guc.size < offset) {
-		DRM_ERROR("GuC WOPCM size %uKiB is too small. %uKiB needed.\n",
-			  wopcm->guc.size / 1024,
-			  offset / 1024);
-		return -E2BIG;
-	}
 
-	return 0;
+	return offset - wopcm->guc.size;
 }
 
-static int check_huc_fw_fits(struct intel_wopcm *wopcm, u32 huc_fw_size)
+static ssize_t gen9_wa_huc_gap_size(struct intel_wopcm *wopcm, u32 huc_fw_size)
 {
 	/*
 	 * On Gen9 & CNL A0, hardware requires the total available GuC WOPCM
 	 * size to be larger than or equal to HuC firmware size. Otherwise,
 	 * firmware uploading would fail.
 	 */
-	if (huc_fw_size >= wopcm->guc.size - GUC_WOPCM_RESERVED) {
-		DRM_ERROR("HuC FW (%uKiB) won't fit in GuC WOPCM (%uKiB).\n",
-			  huc_fw_size / 1024,
-			  (wopcm->guc.size - GUC_WOPCM_RESERVED) / 1024);
-		return -E2BIG;
-	}
 
-	return 0;
+	return (ssize_t)huc_fw_size - (wopcm->guc.size - GUC_WOPCM_RESERVED);
 }
 
 static int check_guc_fw_fits(struct intel_wopcm *wopcm, u32 guc_fw_size)
@@ -142,24 +130,40 @@ static int check_ctx_rsvd_fits(struct intel_wopcm *wopcm, u32 ctx_rsvd)
 	return 0;
 }
 
-static int wopcm_check_constraints(struct intel_wopcm *wopcm)
+static int wopcm_apply_workarounds(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);
-	u32 guc_fw_size = intel_uc_fw_get_upload_size(&i915->guc.fw);
-	u32 ctx_rsvd = context_reserved_size(i915);
-	int err;
+	ssize_t gap_size;
 
 	if (IS_GEN9(i915) || IS_CNL_REVID(i915, CNL_REVID_A0, CNL_REVID_A0)) {
-		err = check_dword_gap(wopcm);
-		if (err)
-			return err;
-
-		err = check_huc_fw_fits(wopcm, huc_fw_size);
-		if (err)
-			return err;
+		gap_size = gen9_wa_dword_gap_size(wopcm);
+		if (gap_size > 0) {
+			DRM_ERROR("GuC WOPCM size (%uKiB) too small. %ldKiB more needed.\n",
+				  wopcm->guc.size / 1024,
+				  gap_size / 1024);
+			return -E2BIG;
+		}
+
+		gap_size = gen9_wa_huc_gap_size(wopcm, huc_fw_size);
+		if (gap_size > 0) {
+			DRM_ERROR("HuC FW (%uKiB) won't fit, %ldKiB more needed.\n",
+				  huc_fw_size / 1024,
+				  gap_size / 1024);
+			return -E2BIG;
+		}
 	}
 
+	return 0;
+}
+
+static int wopcm_check_constraints(struct intel_wopcm *wopcm)
+{
+	struct drm_i915_private *i915 = wopcm_to_i915(wopcm);
+	u32 guc_fw_size = intel_uc_fw_get_upload_size(&i915->guc.fw);
+	u32 ctx_rsvd = context_reserved_size(i915);
+	int err;
+
 	err = check_guc_fw_fits(wopcm, guc_fw_size);
 	if (err)
 		return err;
@@ -212,6 +216,10 @@ int intel_wopcm_init(struct intel_wopcm *wopcm)
 	if (err)
 		return err;
 
+	err = wopcm_apply_workarounds(wopcm);
+	if (err)
+		return err;
+
 	err = wopcm_check_constraints(wopcm);
 	if (err)
 		return err;
-- 
2.14.3



More information about the Intel-gfx-trybot mailing list