iommu/io-pgtable-dart: Add DART PTE support for t6000
authorSven Peter <sven@svenpeter.dev>
Fri, 16 Sep 2022 09:41:51 +0000 (11:41 +0200)
committerJoerg Roedel <jroedel@suse.de>
Mon, 26 Sep 2022 11:49:40 +0000 (13:49 +0200)
The DARTs present in the M1 Pro/Max/Ultra SoC use a diffent PTE format.
They support a 42bit physical address space by shifting the paddr and
extending its mask inside the PTE.
They also come with mandatory sub-page protection now which we just
configure to always allow access to the entire page. This feature is
already present but optional on the previous DARTs which allows to
unconditionally configure it.

Signed-off-by: Sven Peter <sven@svenpeter.dev>
Co-developed-by: Janne Grunau <j@jannau.net>
Signed-off-by: Janne Grunau <j@jannau.net>
Reviewed-by: Rob Herring <robh@kernel.org>
Acked-by: Hector Martin <marcan@marcan.st>
Link: https://lore.kernel.org/r/20220916094152.87137-5-j@jannau.net
Signed-off-by: Joerg Roedel <jroedel@suse.de>
drivers/iommu/io-pgtable-dart.c
drivers/iommu/io-pgtable.c
include/linux/io-pgtable.h

index fc76b6168055680fd6a00f70830a92ba86803406..74b1ef2b96bee119854ce825aac08ec6add76fbe 100644 (file)
 #define APPLE_DART_PTE_SUBPAGE_END     GENMASK_ULL(51, 40)
 
 #define APPLE_DART1_PADDR_MASK GENMASK_ULL(35, 12)
+#define APPLE_DART2_PADDR_MASK GENMASK_ULL(37, 10)
+#define APPLE_DART2_PADDR_SHIFT        (4)
 
 /* Apple DART1 protection bits */
 #define APPLE_DART1_PTE_PROT_NO_READ   BIT(8)
 #define APPLE_DART1_PTE_PROT_NO_WRITE  BIT(7)
 #define APPLE_DART1_PTE_PROT_SP_DIS    BIT(1)
 
+/* Apple DART2 protection bits */
+#define APPLE_DART2_PTE_PROT_NO_READ   BIT(3)
+#define APPLE_DART2_PTE_PROT_NO_WRITE  BIT(2)
+#define APPLE_DART2_PTE_PROT_NO_CACHE  BIT(1)
+
 /* marks PTE as valid */
 #define APPLE_DART_PTE_VALID           BIT(0)
 
@@ -72,13 +79,31 @@ typedef u64 dart_iopte;
 static dart_iopte paddr_to_iopte(phys_addr_t paddr,
                                     struct dart_io_pgtable *data)
 {
-       return paddr & APPLE_DART1_PADDR_MASK;
+       dart_iopte pte;
+
+       if (data->iop.fmt == APPLE_DART)
+               return paddr & APPLE_DART1_PADDR_MASK;
+
+       /* format is APPLE_DART2 */
+       pte = paddr >> APPLE_DART2_PADDR_SHIFT;
+       pte &= APPLE_DART2_PADDR_MASK;
+
+       return pte;
 }
 
 static phys_addr_t iopte_to_paddr(dart_iopte pte,
                                  struct dart_io_pgtable *data)
 {
-       return pte & APPLE_DART1_PADDR_MASK;
+       u64 paddr;
+
+       if (data->iop.fmt == APPLE_DART)
+               return pte & APPLE_DART1_PADDR_MASK;
+
+       /* format is APPLE_DART2 */
+       paddr = pte & APPLE_DART2_PADDR_MASK;
+       paddr <<= APPLE_DART2_PADDR_SHIFT;
+
+       return paddr;
 }
 
 static void *__dart_alloc_pages(size_t size, gfp_t gfp,
@@ -190,10 +215,20 @@ static dart_iopte dart_prot_to_pte(struct dart_io_pgtable *data,
 {
        dart_iopte pte = 0;
 
-       if (!(prot & IOMMU_WRITE))
-               pte |= APPLE_DART1_PTE_PROT_NO_WRITE;
-       if (!(prot & IOMMU_READ))
-               pte |= APPLE_DART1_PTE_PROT_NO_READ;
+       if (data->iop.fmt == APPLE_DART) {
+               if (!(prot & IOMMU_WRITE))
+                       pte |= APPLE_DART1_PTE_PROT_NO_WRITE;
+               if (!(prot & IOMMU_READ))
+                       pte |= APPLE_DART1_PTE_PROT_NO_READ;
+       }
+       if (data->iop.fmt == APPLE_DART2) {
+               if (!(prot & IOMMU_WRITE))
+                       pte |= APPLE_DART2_PTE_PROT_NO_WRITE;
+               if (!(prot & IOMMU_READ))
+                       pte |= APPLE_DART2_PTE_PROT_NO_READ;
+               if (!(prot & IOMMU_CACHE))
+                       pte |= APPLE_DART2_PTE_PROT_NO_CACHE;
+       }
 
        return pte;
 }
@@ -368,7 +403,7 @@ apple_dart_alloc_pgtable(struct io_pgtable_cfg *cfg, void *cookie)
        if (!cfg->coherent_walk)
                return NULL;
 
-       if (cfg->oas > DART1_MAX_ADDR_BITS)
+       if (cfg->oas != 36 && cfg->oas != 42)
                return NULL;
 
        if (cfg->ias > cfg->oas)
index 16205ea9272c3b514f9a48ef28f8f035249d4f9e..49f46e1eabf7a98b26872061710309a624cd6640 100644 (file)
@@ -23,6 +23,7 @@ io_pgtable_init_table[IO_PGTABLE_NUM_FMTS] = {
 #endif
 #ifdef CONFIG_IOMMU_IO_PGTABLE_DART
        [APPLE_DART] = &io_pgtable_apple_dart_init_fns,
+       [APPLE_DART2] = &io_pgtable_apple_dart_init_fns,
 #endif
 #ifdef CONFIG_IOMMU_IO_PGTABLE_ARMV7S
        [ARM_V7S] = &io_pgtable_arm_v7s_init_fns,
index ca98aeadcc80485d6e005d66ae925c773e792fa1..b768937382cd51be2c5c4120cd9441492cf807b2 100644 (file)
@@ -17,6 +17,7 @@ enum io_pgtable_fmt {
        ARM_MALI_LPAE,
        AMD_IOMMU_V1,
        APPLE_DART,
+       APPLE_DART2,
        IO_PGTABLE_NUM_FMTS,
 };