aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/iommu/io-pgtable-dart.c49
-rw-r--r--drivers/iommu/io-pgtable.c1
-rw-r--r--include/linux/io-pgtable.h1
3 files changed, 44 insertions, 7 deletions
diff --git a/drivers/iommu/io-pgtable-dart.c b/drivers/iommu/io-pgtable-dart.c
index fc76b6168055..74b1ef2b96be 100644
--- a/drivers/iommu/io-pgtable-dart.c
+++ b/drivers/iommu/io-pgtable-dart.c
@@ -45,12 +45,19 @@
#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)
diff --git a/drivers/iommu/io-pgtable.c b/drivers/iommu/io-pgtable.c
index 16205ea9272c..49f46e1eabf7 100644
--- a/drivers/iommu/io-pgtable.c
+++ b/drivers/iommu/io-pgtable.c
@@ -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,
diff --git a/include/linux/io-pgtable.h b/include/linux/io-pgtable.h
index ca98aeadcc80..b768937382cd 100644
--- a/include/linux/io-pgtable.h
+++ b/include/linux/io-pgtable.h
@@ -17,6 +17,7 @@ enum io_pgtable_fmt {
ARM_MALI_LPAE,
AMD_IOMMU_V1,
APPLE_DART,
+ APPLE_DART2,
IO_PGTABLE_NUM_FMTS,
};