- Add a helper to remove whitelisted register from the list. - Refactor _wa_add to use _wa_index to find an existing whitelisted register. - Free the old list when growing the whitelist. Signed-off-by: Umesh Nerlige Ramappa <umesh.nerlige.ramappa@xxxxxxxxx> --- drivers/gpu/drm/i915/gt/intel_workarounds.c | 82 +++++++++++++++------ 1 file changed, 58 insertions(+), 24 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/intel_workarounds.c b/drivers/gpu/drm/i915/gt/intel_workarounds.c index cef1c122696f..98927f5d63ab 100644 --- a/drivers/gpu/drm/i915/gt/intel_workarounds.c +++ b/drivers/gpu/drm/i915/gt/intel_workarounds.c @@ -81,10 +81,49 @@ static void wa_init_finish(struct i915_wa_list *wal) wal->wa_count, wal->name, wal->engine_name); } +static int _wa_index(struct i915_wa_list *wal, i915_reg_t reg) +{ + unsigned int addr = i915_mmio_reg_offset(reg); + int start = 0, end = wal->count; + + while (start < end) { + int mid = start + (end - start) / 2; + unsigned int wal_reg = i915_mmio_reg_offset(wal->list[mid].reg); + + wal_reg &= RING_FORCE_TO_NONPRIV_ADDRESS_MASK; + + if (wal_reg < addr) + start = mid + 1; + else if (wal_reg > addr) + end = mid; + else + return mid; + } + + return -1; +} + +static void _wa_remove(struct i915_wa_list *wal, i915_reg_t reg) +{ + int index = _wa_index(wal, reg); + struct i915_wa *wa = wal->list; + + if (index < 0) + return; + + memset(wa + index, 0, sizeof(*wa)); + + while (index < wal->count - 1) { + swap(wa[index], wa[index + 1]); + index++; + } + + wal->count--; +} + static void _wa_add(struct i915_wa_list *wal, const struct i915_wa *wa) { - unsigned int addr = i915_mmio_reg_offset(wa->reg); - unsigned int start = 0, end = wal->count; + int index; const unsigned int grow = WA_LIST_CHUNK; struct i915_wa *wa_; @@ -100,36 +139,31 @@ static void _wa_add(struct i915_wa_list *wal, const struct i915_wa *wa) return; } - if (wal->list) + if (wal->list) { memcpy(list, wal->list, sizeof(*wa) * wal->count); + kfree(wal->list); + } wal->list = list; } - while (start < end) { - unsigned int mid = start + (end - start) / 2; + index = _wa_index(wal, wa->reg); + if (index >= 0) { + wa_ = &wal->list[index]; - if (i915_mmio_reg_offset(wal->list[mid].reg) < addr) { - start = mid + 1; - } else if (i915_mmio_reg_offset(wal->list[mid].reg) > addr) { - end = mid; - } else { - wa_ = &wal->list[mid]; - - if ((wa->clr | wa_->clr) && !(wa->clr & ~wa_->clr)) { - DRM_ERROR("Discarding overwritten w/a for reg %04x (clear: %08x, set: %08x)\n", - i915_mmio_reg_offset(wa_->reg), - wa_->clr, wa_->set); - - wa_->set &= ~wa->clr; - } + if ((wa->clr | wa_->clr) && !(wa->clr & ~wa_->clr)) { + DRM_ERROR("Discarding overwritten w/a for reg %04x (clear: %08x, set: %08x)\n", + i915_mmio_reg_offset(wa_->reg), + wa_->clr, wa_->set); - wal->wa_count++; - wa_->set |= wa->set; - wa_->clr |= wa->clr; - wa_->read |= wa->read; - return; + wa_->set &= ~wa->clr; } + + wal->wa_count++; + wa_->set |= wa->set; + wa_->clr |= wa->clr; + wa_->read |= wa->read; + return; } wal->wa_count++; -- 2.20.1 _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/intel-gfx