iommu/arm-smmu: Ensure IAS is set correctly for AArch32-capable SMMUs
[firefly-linux-kernel-4.4.55.git] / drivers / iommu / arm-smmu-v3.c
index dafaf59dc3b82833fb78d55e8f194ff728999d35..a24f359fa0d09b11f904bd1ede7216cf6d750f36 100644 (file)
@@ -56,6 +56,7 @@
 #define IDR0_TTF_SHIFT                 2
 #define IDR0_TTF_MASK                  0x3
 #define IDR0_TTF_AARCH64               (2 << IDR0_TTF_SHIFT)
+#define IDR0_TTF_AARCH32_64            (3 << IDR0_TTF_SHIFT)
 #define IDR0_S1P                       (1 << 1)
 #define IDR0_S2P                       (1 << 0)
 
@@ -2460,7 +2461,13 @@ static int arm_smmu_device_probe(struct arm_smmu_device *smmu)
        }
 
        /* We only support the AArch64 table format at present */
-       if ((reg & IDR0_TTF_MASK << IDR0_TTF_SHIFT) < IDR0_TTF_AARCH64) {
+       switch (reg & IDR0_TTF_MASK << IDR0_TTF_SHIFT) {
+       case IDR0_TTF_AARCH32_64:
+               smmu->ias = 40;
+               /* Fallthrough */
+       case IDR0_TTF_AARCH64:
+               break;
+       default:
                dev_err(smmu->dev, "AArch64 table format not supported!\n");
                return -ENXIO;
        }
@@ -2541,8 +2548,7 @@ static int arm_smmu_device_probe(struct arm_smmu_device *smmu)
                dev_warn(smmu->dev,
                         "failed to set DMA mask for table walker\n");
 
-       if (!smmu->ias)
-               smmu->ias = smmu->oas;
+       smmu->ias = max(smmu->ias, smmu->oas);
 
        dev_info(smmu->dev, "ias %lu-bit, oas %lu-bit (features 0x%08x)\n",
                 smmu->ias, smmu->oas, smmu->features);