From: Kunkun Jiang <[email protected]>

This detects BBML feature and if SMMU supports it, transfer BBMLx
quirk to io-pgtable.

Co-developed-by: Keqian Zhu <[email protected]>
Signed-off-by: Kunkun Jiang <[email protected]>
---
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 19 +++++++++++++++++++
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h |  6 ++++++
 2 files changed, 25 insertions(+)

diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c 
b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
index c42e59655fd0..3a2dc3177180 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -2051,6 +2051,11 @@ static int arm_smmu_domain_finalise(struct iommu_domain 
*domain,
        if (smmu->features & ARM_SMMU_FEAT_HD)
                pgtbl_cfg.quirks |= IO_PGTABLE_QUIRK_ARM_HD;
 
+       if (smmu->features & ARM_SMMU_FEAT_BBML1)
+               pgtbl_cfg.quirks |= IO_PGTABLE_QUIRK_ARM_BBML1;
+       else if (smmu->features & ARM_SMMU_FEAT_BBML2)
+               pgtbl_cfg.quirks |= IO_PGTABLE_QUIRK_ARM_BBML2;
+
        pgtbl_ops = alloc_io_pgtable_ops(fmt, &pgtbl_cfg, smmu_domain);
        if (!pgtbl_ops)
                return -ENOMEM;
@@ -3419,6 +3424,20 @@ static int arm_smmu_device_hw_probe(struct 
arm_smmu_device *smmu)
 
        /* IDR3 */
        reg = readl_relaxed(smmu->base + ARM_SMMU_IDR3);
+       switch (FIELD_GET(IDR3_BBML, reg)) {
+       case IDR3_BBML0:
+               break;
+       case IDR3_BBML1:
+               smmu->features |= ARM_SMMU_FEAT_BBML1;
+               break;
+       case IDR3_BBML2:
+               smmu->features |= ARM_SMMU_FEAT_BBML2;
+               break;
+       default:
+               dev_err(smmu->dev, "unknown/unsupported BBM behavior level\n");
+               return -ENXIO;
+       }
+
        if (FIELD_GET(IDR3_RIL, reg))
                smmu->features |= ARM_SMMU_FEAT_RANGE_INV;
 
diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h 
b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
index 3edcd31b046e..e3b6bdd292c9 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
@@ -54,6 +54,10 @@
 #define IDR1_SIDSIZE                   GENMASK(5, 0)
 
 #define ARM_SMMU_IDR3                  0xc
+#define IDR3_BBML                      GENMASK(12, 11)
+#define IDR3_BBML0                     0
+#define IDR3_BBML1                     1
+#define IDR3_BBML2                     2
 #define IDR3_RIL                       (1 << 10)
 
 #define ARM_SMMU_IDR5                  0x14
@@ -613,6 +617,8 @@ struct arm_smmu_device {
 #define ARM_SMMU_FEAT_E2H              (1 << 18)
 #define ARM_SMMU_FEAT_HA               (1 << 19)
 #define ARM_SMMU_FEAT_HD               (1 << 20)
+#define ARM_SMMU_FEAT_BBML1            (1 << 21)
+#define ARM_SMMU_FEAT_BBML2            (1 << 22)
        u32                             features;
 
 #define ARM_SMMU_OPT_SKIP_PREFETCH     (1 << 0)
-- 
2.19.1

_______________________________________________
iommu mailing list
[email protected]
https://lists.linuxfoundation.org/mailman/listinfo/iommu

Reply via email to