return as_send_cmd_and_wait(ptdev, as_nr, AS_COMMAND_UPDATE);
}
-static int panthor_mmu_as_disable(struct panthor_device *ptdev, u32 as_nr)
+static int panthor_mmu_as_disable(struct panthor_device *ptdev, u32 as_nr,
+ bool recycle_slot)
{
int ret;
if (ret)
return ret;
+ /* If the slot is going to be used immediately, don't bother changing
+ * the config.
+ */
+ if (recycle_slot)
+ return 0;
+
gpu_write64(ptdev, AS_TRANSTAB(as_nr), 0);
gpu_write64(ptdev, AS_MEMATTR(as_nr), 0);
gpu_write64(ptdev, AS_TRANSCFG(as_nr), AS_TRANSCFG_ADRMODE_UNMAPPED);
drm_WARN_ON(&ptdev->base, refcount_read(&lru_vm->as.active_cnt));
as = lru_vm->as.id;
+
+ ret = panthor_mmu_as_disable(ptdev, as, true);
+ if (ret)
+ goto out_unlock;
+
panthor_vm_release_as_locked(lru_vm);
}
vm->unusable = true;
mutex_lock(&ptdev->mmu->as.slots_lock);
if (vm->as.id >= 0 && drm_dev_enter(&ptdev->base, &cookie)) {
- panthor_mmu_as_disable(ptdev, vm->as.id);
+ panthor_mmu_as_disable(ptdev, vm->as.id, false);
drm_dev_exit(cookie);
}
mutex_unlock(&ptdev->mmu->as.slots_lock);
ptdev->mmu->as.slots[as].vm->unhandled_fault = true;
/* Disable the MMU to kill jobs on this AS. */
- panthor_mmu_as_disable(ptdev, as);
+ panthor_mmu_as_disable(ptdev, as, false);
mutex_unlock(&ptdev->mmu->as.slots_lock);
status &= ~mask;
struct panthor_vm *vm = ptdev->mmu->as.slots[i].vm;
if (vm) {
- drm_WARN_ON(&ptdev->base, panthor_mmu_as_disable(ptdev, i));
+ drm_WARN_ON(&ptdev->base,
+ panthor_mmu_as_disable(ptdev, i, false));
panthor_vm_release_as_locked(vm);
}
}
int cookie;
if (drm_dev_enter(&ptdev->base, &cookie)) {
- panthor_mmu_as_disable(ptdev, vm->as.id);
+ panthor_mmu_as_disable(ptdev, vm->as.id, false);
drm_dev_exit(cookie);
}
struct panthor_vm *vm = ptdev->mmu->as.slots[i].vm;
if (vm) {
- drm_WARN_ON(&ptdev->base, panthor_mmu_as_disable(ptdev, i));
+ drm_WARN_ON(&ptdev->base,
+ panthor_mmu_as_disable(ptdev, i, false));
panthor_vm_release_as_locked(vm);
}
}