mirror of
https://github.com/coolsnowwolf/lede.git
synced 2025-04-16 04:13:31 +00:00
159 lines
4.8 KiB
Diff
159 lines
4.8 KiB
Diff
From 318506bc8e5c558c1df0a964ce2fe112681d3452 Mon Sep 17 00:00:00 2001
|
|
From: Sven Peter <sven@svenpeter.dev>
|
|
Date: Tue, 2 Nov 2021 18:10:53 +0100
|
|
Subject: [PATCH 049/171] iommu/io-pgtable-dart: Add DART PTE support for t6000
|
|
|
|
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>
|
|
|
|
Commit-changes: 2
|
|
- add APPLE_DART2 PTE format
|
|
|
|
Commit-changes: 3
|
|
- apply change to io-pgtable-dart.c
|
|
- handle pte <> paddr conversion based on the pte format instead of
|
|
the output address size
|
|
---
|
|
drivers/iommu/io-pgtable-dart.c | 51 +++++++++++++++++++++++++++------
|
|
drivers/iommu/io-pgtable.c | 1 +
|
|
include/linux/io-pgtable.h | 1 +
|
|
3 files changed, 45 insertions(+), 8 deletions(-)
|
|
|
|
diff --git a/drivers/iommu/io-pgtable-dart.c b/drivers/iommu/io-pgtable-dart.c
|
|
index fa8025c03bb5..9c3c2505f3dc 100644
|
|
--- a/drivers/iommu/io-pgtable-dart.c
|
|
+++ b/drivers/iommu/io-pgtable-dart.c
|
|
@@ -68,12 +68,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)
|
|
|
|
@@ -101,13 +108,31 @@ static inline bool iopte_leaf(dart_iopte pte, int lvl,
|
|
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,
|
|
@@ -139,7 +164,7 @@ static void __dart_init_pte(struct dart_io_pgtable *data,
|
|
size_t sz = DART_BLOCK_SIZE(lvl, data);
|
|
int i;
|
|
|
|
- if (lvl == DART_MAX_LEVELS - 1)
|
|
+ if (lvl == DART_MAX_LEVELS - 1 && data->iop.fmt == APPLE_DART)
|
|
pte |= APPLE_DART1_PTE_PROT_SP_DIS;
|
|
|
|
pte |= APPLE_DART_PTE_VALID;
|
|
@@ -251,10 +276,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;
|
|
}
|
|
@@ -536,7 +571,7 @@ apple_dart_alloc_pgtable(struct io_pgtable_cfg *cfg, void *cookie)
|
|
if (!cfg->coherent_walk)
|
|
return NULL;
|
|
|
|
- if (cfg->oas > 36)
|
|
+ if (cfg->oas != 36 && cfg->oas != 42)
|
|
return NULL;
|
|
|
|
data = dart_alloc_pgtable(cfg);
|
|
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 86af6f0a00a2..76b98511cbc8 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,
|
|
};
|
|
|
|
--
|
|
2.34.1
|
|
|