]> git.baikalelectronics.ru Git - kernel.git/commitdiff
iommu/arm-smmu-v3: Work around MMU-600 erratum 1076982
authorRobin Murphy <robin.murphy@arm.com>
Wed, 2 Aug 2023 17:20:57 +0000 (17:20 +0000)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 11 Aug 2023 10:08:09 +0000 (12:08 +0200)
commit f322e8af35c7f23a8c08b595c38d6c855b2d836f upstream

MMU-600 versions prior to r1p0 fail to correctly generate a WFE wakeup
event when the command queue transitions fom full to non-full. We can
easily work around this by simply hiding the SEV capability such that we
fall back to polling for space in the queue - since MMU-600 implements
MSIs we wouldn't expect to need SEV for sync completion either, so this
should have little to no impact.

Signed-off-by: Robin Murphy <robin.murphy@arm.com>
Reviewed-by: Nicolin Chen <nicolinc@nvidia.com>
Tested-by: Nicolin Chen <nicolinc@nvidia.com>
Link: https://lore.kernel.org/r/08adbe3d01024d8382a478325f73b56851f76e49.1683731256.git.robin.murphy@arm.com
Signed-off-by: Will Deacon <will@kernel.org>
Signed-off-by: Easwar Hariharan <eahariha@linux.microsoft.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Documentation/arm64/silicon-errata.rst
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h

index bbc80eff03f98006366fc2b83cc94cad8a8aa898..9f94afe2fc17886b6dbedffc2b3c9bb474408c80 100644 (file)
@@ -141,6 +141,8 @@ stable kernels.
 +----------------+-----------------+-----------------+-----------------------------+
 | ARM            | MMU-500         | #841119,826419  | N/A                         |
 +----------------+-----------------+-----------------+-----------------------------+
+| ARM            | MMU-600         | #1076982        | N/A                         |
++----------------+-----------------+-----------------+-----------------------------+
 +----------------+-----------------+-----------------+-----------------------------+
 | Broadcom       | Brahma-B53      | N/A             | ARM64_ERRATUM_845719        |
 +----------------+-----------------+-----------------+-----------------------------+
index d4d8bfee9febc5e5a0a98510d3635c32925974a5..c12b57910c510f81048263628fdf94235a05b9a1 100644 (file)
@@ -3410,6 +3410,33 @@ static int arm_smmu_device_reset(struct arm_smmu_device *smmu, bool bypass)
        return 0;
 }
 
+#define IIDR_IMPLEMENTER_ARM           0x43b
+#define IIDR_PRODUCTID_ARM_MMU_600     0x483
+
+static void arm_smmu_device_iidr_probe(struct arm_smmu_device *smmu)
+{
+       u32 reg;
+       unsigned int implementer, productid, variant, revision;
+
+       reg = readl_relaxed(smmu->base + ARM_SMMU_IIDR);
+       implementer = FIELD_GET(IIDR_IMPLEMENTER, reg);
+       productid = FIELD_GET(IIDR_PRODUCTID, reg);
+       variant = FIELD_GET(IIDR_VARIANT, reg);
+       revision = FIELD_GET(IIDR_REVISION, reg);
+
+       switch (implementer) {
+       case IIDR_IMPLEMENTER_ARM:
+               switch (productid) {
+               case IIDR_PRODUCTID_ARM_MMU_600:
+                       /* Arm erratum 1076982 */
+                       if (variant == 0 && revision <= 2)
+                               smmu->features &= ~ARM_SMMU_FEAT_SEV;
+                       break;
+               }
+               break;
+       }
+}
+
 static int arm_smmu_device_hw_probe(struct arm_smmu_device *smmu)
 {
        u32 reg;
@@ -3615,6 +3642,8 @@ static int arm_smmu_device_hw_probe(struct arm_smmu_device *smmu)
 
        smmu->ias = max(smmu->ias, smmu->oas);
 
+       arm_smmu_device_iidr_probe(smmu);
+
        if (arm_smmu_sva_supported(smmu))
                smmu->features |= ARM_SMMU_FEAT_SVA;
 
index cd48590ada3039ad70eadbc1edaa8bf877ce74ff..ce5e44a13d8405b80ddd1b8948be827609edc14e 100644 (file)
 #define IDR5_VAX                       GENMASK(11, 10)
 #define IDR5_VAX_52_BIT                        1
 
+#define ARM_SMMU_IIDR                  0x18
+#define IIDR_PRODUCTID                 GENMASK(31, 20)
+#define IIDR_VARIANT                   GENMASK(19, 16)
+#define IIDR_REVISION                  GENMASK(15, 12)
+#define IIDR_IMPLEMENTER               GENMASK(11, 0)
+
 #define ARM_SMMU_CR0                   0x20
 #define CR0_ATSCHK                     (1 << 4)
 #define CR0_CMDQEN                     (1 << 3)