IS_ALIGNED(page_address, alignment >> V3D_MMU_PAGE_SHIFT);
}
-int v3d_mmu_flush_all(struct v3d_dev *v3d)
+/*
+ * Issue the MMUC flush and TLB clear unconditionally. The caller must
+ * already know that V3D is reachable. In particular, this is used from
+ * the runtime resume callback.
+ */
+static int v3d_mmu_flush_all_locked(struct v3d_dev *v3d)
{
- int ret = 0;
-
- /* Flush the PTs only if we're already awake */
- if (!pm_runtime_get_if_active(v3d->drm.dev))
- return 0;
+ int ret;
V3D_WRITE(V3D_MMUC_CONTROL, V3D_MMUC_CONTROL_FLUSH |
V3D_MMUC_CONTROL_ENABLE);
V3D_MMUC_CONTROL_FLUSHING), 100);
if (ret) {
dev_err(v3d->drm.dev, "MMUC flush wait idle failed\n");
- goto pm_put;
+ return ret;
}
V3D_WRITE(V3D_MMU_CTL, V3D_READ(V3D_MMU_CTL) |
if (ret)
dev_err(v3d->drm.dev, "MMU TLB clear wait idle failed\n");
-pm_put:
+ return ret;
+}
+
+int v3d_mmu_flush_all(struct v3d_dev *v3d)
+{
+ int ret;
+
+ /* Flush the PTs only if we're already awake */
+ if (!pm_runtime_get_if_active(v3d->drm.dev))
+ return 0;
+
+ ret = v3d_mmu_flush_all_locked(v3d);
+
v3d_pm_runtime_put(v3d);
return ret;
}
V3D_MMU_ILLEGAL_ADDR_ENABLE);
V3D_WRITE(V3D_MMUC_CONTROL, V3D_MMUC_CONTROL_ENABLE);
- return v3d_mmu_flush_all(v3d);
+ return v3d_mmu_flush_all_locked(v3d);
}
void v3d_mmu_insert_ptes(struct v3d_bo *bo)