[PATCH 1/1] iommu/arm-smmu: modify the calculation of PASize and SEP fields

Zhen Lei thunder.leizhen at huawei.com
Fri Dec 12 00:41:03 PST 2014


1. the calculation appear 3 times, it's good to define a function.
2. VA_BITS is dynamic determined by CONFIG_ARM64_VA_BITS yet, but current
   switch..case can not cover all possible values.
3. change TTBCR2_ADDR_xx to ADDR_SIZE_xx, because it's not only TTBCR2 use it.

Signed-off-by: Zhen Lei <thunder.leizhen at huawei.com>
---
 drivers/iommu/arm-smmu.c | 104 ++++++++++++++++-------------------------------
 1 file changed, 34 insertions(+), 70 deletions(-)

diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index 60558f7..968ca76 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -290,12 +290,12 @@
 #define TTBCR2_PASIZE_MASK		0x7

 /* Common definitions for PASize and SEP fields */
-#define TTBCR2_ADDR_32			0
-#define TTBCR2_ADDR_36			1
-#define TTBCR2_ADDR_40			2
-#define TTBCR2_ADDR_42			3
-#define TTBCR2_ADDR_44			4
-#define TTBCR2_ADDR_48			5
+#define ADDR_SIZE_32			0
+#define ADDR_SIZE_36			1
+#define ADDR_SIZE_40			2
+#define ADDR_SIZE_42			3
+#define ADDR_SIZE_44			4
+#define ADDR_SIZE_48			5

 #define TTBRn_HI_ASID_SHIFT		16

@@ -727,6 +727,30 @@ static void arm_smmu_flush_pgtable(struct arm_smmu_device *smmu, void *addr,
 	}
 }

+static u32 size_to_field(unsigned long size, int shift)
+{
+	u32 val;
+
+	/*
+	 * 0b000 32-bits (<=32)
+	 * 0b001 36-bits (33,34,35,36)
+	 * 0b010 40-bits (37,38,39,40)
+	 * 0b011 42-bits (41,42)
+	 * 0b100 44-bits (43,44)
+	 * 0b101 48-bits (>=45)
+	 */
+	if (size <= 32)
+		val = ADDR_SIZE_32;
+	else if (size <= 40)
+		val = ((size - 33) >> 2) + ADDR_SIZE_36;
+	else if (size <= 44)
+		val = ((size - 41) >> 1) + ADDR_SIZE_42;
+	else
+		val = ADDR_SIZE_48;
+
+	return val << shift;
+}
+
 static void arm_smmu_init_context_bank(struct arm_smmu_domain *smmu_domain)
 {
 	u32 reg;
@@ -768,49 +792,8 @@ static void arm_smmu_init_context_bank(struct arm_smmu_domain *smmu_domain)
 			       gr1_base + ARM_SMMU_GR1_CBA2R(cfg->cbndx));

 		/* TTBCR2 */
-		switch (smmu->s1_input_size) {
-		case 32:
-			reg = (TTBCR2_ADDR_32 << TTBCR2_SEP_SHIFT);
-			break;
-		case 36:
-			reg = (TTBCR2_ADDR_36 << TTBCR2_SEP_SHIFT);
-			break;
-		case 39:
-		case 40:
-			reg = (TTBCR2_ADDR_40 << TTBCR2_SEP_SHIFT);
-			break;
-		case 42:
-			reg = (TTBCR2_ADDR_42 << TTBCR2_SEP_SHIFT);
-			break;
-		case 44:
-			reg = (TTBCR2_ADDR_44 << TTBCR2_SEP_SHIFT);
-			break;
-		case 48:
-			reg = (TTBCR2_ADDR_48 << TTBCR2_SEP_SHIFT);
-			break;
-		}
-
-		switch (smmu->s1_output_size) {
-		case 32:
-			reg |= (TTBCR2_ADDR_32 << TTBCR2_PASIZE_SHIFT);
-			break;
-		case 36:
-			reg |= (TTBCR2_ADDR_36 << TTBCR2_PASIZE_SHIFT);
-			break;
-		case 39:
-		case 40:
-			reg |= (TTBCR2_ADDR_40 << TTBCR2_PASIZE_SHIFT);
-			break;
-		case 42:
-			reg |= (TTBCR2_ADDR_42 << TTBCR2_PASIZE_SHIFT);
-			break;
-		case 44:
-			reg |= (TTBCR2_ADDR_44 << TTBCR2_PASIZE_SHIFT);
-			break;
-		case 48:
-			reg |= (TTBCR2_ADDR_48 << TTBCR2_PASIZE_SHIFT);
-			break;
-		}
+		reg  = size_to_field(smmu->s1_input_size, TTBCR2_SEP_SHIFT);
+		reg |= size_to_field(smmu->s1_output_size, TTBCR2_PASIZE_SHIFT);

 		if (stage1)
 			writel_relaxed(reg, cb_base + ARM_SMMU_CB_TTBCR2);
@@ -838,27 +821,8 @@ static void arm_smmu_init_context_bank(struct arm_smmu_domain *smmu_domain)

 		if (!stage1) {
 			reg |= (64 - smmu->s2_input_size) << TTBCR_T0SZ_SHIFT;
-
-			switch (smmu->s2_output_size) {
-			case 32:
-				reg |= (TTBCR2_ADDR_32 << TTBCR_PASIZE_SHIFT);
-				break;
-			case 36:
-				reg |= (TTBCR2_ADDR_36 << TTBCR_PASIZE_SHIFT);
-				break;
-			case 40:
-				reg |= (TTBCR2_ADDR_40 << TTBCR_PASIZE_SHIFT);
-				break;
-			case 42:
-				reg |= (TTBCR2_ADDR_42 << TTBCR_PASIZE_SHIFT);
-				break;
-			case 44:
-				reg |= (TTBCR2_ADDR_44 << TTBCR_PASIZE_SHIFT);
-				break;
-			case 48:
-				reg |= (TTBCR2_ADDR_48 << TTBCR_PASIZE_SHIFT);
-				break;
-			}
+			reg |= size_to_field(smmu->s2_output_size,
+							TTBCR_PASIZE_SHIFT);
 		} else {
 			reg |= (64 - smmu->s1_input_size) << TTBCR_T0SZ_SHIFT;
 		}
--
1.8.0





More information about the linux-arm-kernel mailing list