iommu: Support MMU500 Deep Prefetch errata workaround

If deep prefetch is enabled, but not all page table entries in the
prefetch window are valid, improper permissions may be cached for
valid entries in this window. Ensure the start and end of all mapped
buffers are aligned to 16kB to prevent this issue.

Change-Id: I53bc18529b77c775338c477487333b404b225c58
Signed-off-by: Patrick Daly <pdaly@codeaurora.org>
diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index 1e53201..333836c 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -536,6 +536,7 @@
 
 	bool				qsmmuv500_errata1_init;
 	bool				qsmmuv500_errata1_client;
+	bool				qsmmuv500_errata2_min_align;
 };
 
 static DEFINE_SPINLOCK(arm_smmu_devices_lock);
@@ -2898,6 +2899,10 @@
 			& (1 << DOMAIN_ATTR_CB_STALL_DISABLE));
 		ret = 0;
 		break;
+	case DOMAIN_ATTR_QCOM_MMU500_ERRATA_MIN_ALIGN:
+		*((int *)data) = smmu_domain->qsmmuv500_errata2_min_align;
+		ret = 0;
+		break;
 	default:
 		ret = -ENODEV;
 		break;
@@ -4395,6 +4400,9 @@
 
 #define TBU_DBG_TIMEOUT_US		30000
 
+#define QSMMUV500_ACTLR_DEEP_PREFETCH_MASK	0x3
+#define QSMMUV500_ACTLR_DEEP_PREFETCH_SHIFT	0x8
+
 
 struct actlr_setting {
 	struct arm_smmu_smr smr;
@@ -4873,6 +4881,14 @@
 	writel_relaxed(iommudata->actlr, cb_base + ARM_SMMU_CB_ACTLR);
 
 	/*
+	 * Prefetch only works properly if the start and end of all
+	 * buffers in the page table are aligned to 16 Kb.
+	 */
+	if ((iommudata->actlr >> QSMMUV500_ACTLR_DEEP_PREFETCH_SHIFT) &&
+			QSMMUV500_ACTLR_DEEP_PREFETCH_MASK)
+		smmu_domain->qsmmuv500_errata2_min_align = true;
+
+	/*
 	 * Flush the context bank after modifying ACTLR to ensure there
 	 * are no cache entries with stale state
 	 */