GuC will validate the ring offset and fail if it is in the
[0, GUC_WOPCM_TOP) range. The bias is conditionally applied only
if GuC loading is enabled (we can't check for guc submission enabled as
in other cases because HuC loading requires this fix).
Note that the default context is processed before enable_guc_loading is
sanitized, so we might still apply the bias to its ring even if it is
not needed.
v2: compute the value during ctx init and pass it to
intel_ring_pin (Chris), updated commit message
Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Michal Wajdeczko <michal.wajdeczko@intel.com>
Cc: Arkadiusz Hiler <arkadiusz.hiler@intel.com>
Cc: Anusha Srivatsa <anusha.srivatsa@intel.com>
Cc: MichaĆ Winiarski <michal.winiarski@intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/1482537382-28584-1-git-send-email-daniele.ceraolospurio@intel.com
Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
int priority; /* greater priorities are serviced first */
u32 ggtt_alignment;
+ u32 ggtt_offset_bias;
struct intel_context {
struct i915_vma *state;
GEN8_CTX_ADDRESSING_MODE_SHIFT;
ATOMIC_INIT_NOTIFIER_HEAD(&ctx->status_notifier);
+ /* GuC requires the ring to be placed above GUC_WOPCM_TOP. If GuC is not
+ * present or not in use we still need a small bias as ring wraparound
+ * at offset 0 sometimes hangs. No idea why.
+ */
+ if (HAS_GUC(dev_priv) && i915.enable_guc_loading)
+ ctx->ggtt_offset_bias = GUC_WOPCM_TOP;
+ else
+ ctx->ggtt_offset_bias = 4096;
+
return ctx;
err_pid:
goto unpin_vma;
}
- ret = intel_ring_pin(ce->ring);
+ ret = intel_ring_pin(ce->ring, ctx->ggtt_offset_bias);
if (ret)
goto unpin_map;
return 0;
}
-int intel_ring_pin(struct intel_ring *ring)
+int intel_ring_pin(struct intel_ring *ring, unsigned int offset_bias)
{
- /* Ring wraparound at offset 0 sometimes hangs. No idea why. */
- unsigned int flags = PIN_GLOBAL | PIN_OFFSET_BIAS | 4096;
+ unsigned int flags;
enum i915_map_type map;
struct i915_vma *vma = ring->vma;
void *addr;
map = HAS_LLC(ring->engine->i915) ? I915_MAP_WB : I915_MAP_WC;
+ flags = PIN_GLOBAL;
+ if (offset_bias)
+ flags |= PIN_OFFSET_BIAS | offset_bias;
if (vma->obj->stolen)
flags |= PIN_MAPPABLE;
goto error;
}
- ret = intel_ring_pin(ring);
+ /* Ring wraparound at offset 0 sometimes hangs. No idea why. */
+ ret = intel_ring_pin(ring, 4096);
if (ret) {
intel_ring_free(ring);
goto error;
struct intel_ring *
intel_engine_create_ring(struct intel_engine_cs *engine, int size);
-int intel_ring_pin(struct intel_ring *ring);
+int intel_ring_pin(struct intel_ring *ring, unsigned int offset_bias);
void intel_ring_unpin(struct intel_ring *ring);
void intel_ring_free(struct intel_ring *ring);