[Intel-gfx] [PATCH] drm/i915: Break workaround register emission into batches of 15
Chris Wilson
chris at chris-wilson.co.uk
Fri Jun 15 08:00:30 UTC 2018
We are restricted to the number of registers we can rewrite into a
single command by the packet length. If we have more registers than can
be fitted into a single packet, we therefore need to split the writes
into multiple packets.
Reported-by: Kenneth Graunke <kenneth at whitecape.org>
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
Cc: Oscar Mateo <oscar.mateo at intel.com>
Cc: Mika Kuoppala <mika.kuoppala at linux.intel.com>
Cc: Joonas Lahtinen <joonas.lahtinen at linux.intel.com>
Cc: Kenneth Graunke <kenneth at whitecape.org>
---
drivers/gpu/drm/i915/intel_workarounds.c | 31 ++++++++++++++++--------
1 file changed, 21 insertions(+), 10 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_workarounds.c b/drivers/gpu/drm/i915/intel_workarounds.c
index f8bb32e974f6..d82e08af6a60 100644
--- a/drivers/gpu/drm/i915/intel_workarounds.c
+++ b/drivers/gpu/drm/i915/intel_workarounds.c
@@ -553,6 +553,8 @@ int intel_ctx_workarounds_init(struct drm_i915_private *dev_priv)
int intel_ctx_workarounds_emit(struct i915_request *rq)
{
struct i915_workarounds *w = &rq->i915->workarounds;
+ struct i915_wa_reg *reg = w->reg;
+ unsigned int remain;
u32 *cs;
int ret, i;
@@ -563,18 +565,27 @@ int intel_ctx_workarounds_emit(struct i915_request *rq)
if (ret)
return ret;
- cs = intel_ring_begin(rq, (w->count * 2 + 2));
- if (IS_ERR(cs))
- return PTR_ERR(cs);
+ remain = w->count;
+ do {
+ unsigned int count;
- *cs++ = MI_LOAD_REGISTER_IMM(w->count);
- for (i = 0; i < w->count; i++) {
- *cs++ = w->reg[i].addr;
- *cs++ = w->reg[i].value;
- }
- *cs++ = MI_NOOP;
+ count = min(remain, 15u);
+ remain -= count;
+
+ cs = intel_ring_begin(rq, 2 * count + 2);
+ if (IS_ERR(cs))
+ return PTR_ERR(cs);
+
+ *cs++ = MI_LOAD_REGISTER_IMM(count);
+ for (i = 0; i < count; i++) {
+ *cs++ = reg->addr;
+ *cs++ = reg->value;
+ reg++;
+ }
+ *cs++ = MI_NOOP;
- intel_ring_advance(rq, cs);
+ intel_ring_advance(rq, cs);
+ } while (remain);
ret = rq->engine->emit_flush(rq, EMIT_BARRIER);
if (ret)
--
2.17.1
More information about the Intel-gfx
mailing list