We imposed additional restrictions to GEN9 WOPCM partitioning. However, we ignored early steppings of CNL, to which those restrictions also apply. Let's also tweak the logic a bit by having separate helpers for returning extra size needed for the restriction to be satisfied, and handle the results in the caller. References: 6b0478fb722a ("drm/i915: Implement dynamic GuC WOPCM offset and size calculation") Signed-off-by: Michał Winiarski <michal.winiarski@xxxxxxxxx> Cc: Chris Wilson <chris@xxxxxxxxxxxxxxxxxx> Cc: Jackie Li <yaodong.li@xxxxxxxxx> Cc: Joonas Lahtinen <joonas.lahtinen@xxxxxxxxxxxxxxx> Cc: Michal Wajdeczko <michal.wajdeczko@xxxxxxxxx> --- drivers/gpu/drm/i915/intel_wopcm.c | 63 ++++++++++++++++++++++---------------- 1 file changed, 37 insertions(+), 26 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_wopcm.c b/drivers/gpu/drm/i915/intel_wopcm.c index 42876f8890e7..50854a6b9493 100644 --- a/drivers/gpu/drm/i915/intel_wopcm.c +++ b/drivers/gpu/drm/i915/intel_wopcm.c @@ -84,58 +84,69 @@ static inline u32 context_reserved_size(struct drm_i915_private *i915) return 0; } -static inline int gen9_check_dword_gap(u32 guc_wopcm_base, u32 guc_wopcm_size) +static u32 +gen9_size_for_dword_gap_restriction(u32 guc_wopcm_base, u32 guc_wopcm_size) { - u32 offset; + s32 additional_size; /* * GuC WOPCM size shall be at least a dword larger than the offset from * WOPCM base (GuC WOPCM offset from WOPCM base + GEN9_GUC_WOPCM_OFFSET) * due to hardware limitation on Gen9. */ - offset = guc_wopcm_base + GEN9_GUC_WOPCM_OFFSET; - if (offset > guc_wopcm_size || - (guc_wopcm_size - offset) < sizeof(u32)) { - DRM_ERROR("GuC WOPCM size %uKiB is too small. %uKiB needed.\n", - guc_wopcm_size / 1024, - (u32)(offset + sizeof(u32)) / 1024); - return -E2BIG; - } + additional_size = guc_wopcm_base + GEN9_GUC_WOPCM_OFFSET + + sizeof(u32) - guc_wopcm_size; - return 0; + if (additional_size <= 0) + return 0; + + return additional_size; } -static inline int gen9_check_huc_fw_fits(u32 guc_wopcm_size, u32 huc_fw_size) +static u32 +gen9_size_for_huc_restriction(u32 guc_wopcm_size, u32 huc_fw_size) { + s32 additional_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 > guc_wopcm_size - GUC_WOPCM_RESERVED) { - DRM_ERROR("HuC FW (%uKiB) won't fit in GuC WOPCM (%uKiB).\n", - huc_fw_size / 1024, - (guc_wopcm_size - GUC_WOPCM_RESERVED) / 1024); - return -E2BIG; - } + additional_size = huc_fw_size - (guc_wopcm_size - GUC_WOPCM_RESERVED); - return 0; + if (additional_size <= 0) + return 0; + + return additional_size; } static inline int check_hw_restriction(struct drm_i915_private *i915, u32 guc_wopcm_base, u32 guc_wopcm_size, u32 huc_fw_size) { - int err = 0; + u32 size; + + if (IS_GEN9(i915) || IS_CNL_REVID(i915, CNL_REVID_A0, CNL_REVID_A0)) { + size = gen9_size_for_dword_gap_restriction(guc_wopcm_base, + guc_wopcm_size); + if (size) + goto err; + + size = gen9_size_for_huc_restriction(guc_wopcm_size, + huc_fw_size); + if (size) + goto err; + } - if (IS_GEN9(i915)) - err = gen9_check_dword_gap(guc_wopcm_base, guc_wopcm_size); + return 0; - if (!err && - (IS_GEN9(i915) || IS_CNL_REVID(i915, CNL_REVID_A0, CNL_REVID_A0))) - err = gen9_check_huc_fw_fits(guc_wopcm_size, huc_fw_size); +err: + DRM_ERROR("GuC WOPCM size %uKiB is too small. %uKiB more needed.\n", + guc_wopcm_size / 1024, + size / 1024); - return err; + return -E2BIG; } /** -- 2.14.3 _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/intel-gfx