aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/iommu
diff options
context:
space:
mode:
authorYong Wu <yong.wu@mediatek.com>2019-08-23 23:01:54 -0400
committerJoerg Roedel <jroedel@suse.de>2019-08-30 09:57:26 -0400
commit4c019de653237674d38cf2b3119153b144ffe173 (patch)
treebc3fe26f138130a39bbf1aa7f1b593deefb84deb /drivers/iommu
parent73d50811bc91d2a173213a78b6b43ac762f6cc54 (diff)
iommu/io-pgtable-arm-v7s: Extend to support PA[33:32] for MediaTek
MediaTek extend the arm v7s descriptor to support up to 34 bits PA where the bit32 and bit33 are encoded in the bit9 and bit4 of the PTE respectively. Meanwhile the iova still is 32bits. Regarding whether the pagetable address could be over 4GB, the mt8183 support it while the previous mt8173 don't, thus keep it as is. Signed-off-by: Yong Wu <yong.wu@mediatek.com> Acked-by: Will Deacon <will@kernel.org> Signed-off-by: Joerg Roedel <jroedel@suse.de>
Diffstat (limited to 'drivers/iommu')
-rw-r--r--drivers/iommu/io-pgtable-arm-v7s.c40
1 files changed, 33 insertions, 7 deletions
diff --git a/drivers/iommu/io-pgtable-arm-v7s.c b/drivers/iommu/io-pgtable-arm-v7s.c
index 77cc1eb1243b..545287148147 100644
--- a/drivers/iommu/io-pgtable-arm-v7s.c
+++ b/drivers/iommu/io-pgtable-arm-v7s.c
@@ -112,7 +112,9 @@
112#define ARM_V7S_TEX_MASK 0x7 112#define ARM_V7S_TEX_MASK 0x7
113#define ARM_V7S_ATTR_TEX(val) (((val) & ARM_V7S_TEX_MASK) << ARM_V7S_TEX_SHIFT) 113#define ARM_V7S_ATTR_TEX(val) (((val) & ARM_V7S_TEX_MASK) << ARM_V7S_TEX_SHIFT)
114 114
115#define ARM_V7S_ATTR_MTK_4GB BIT(9) /* MTK extend it for 4GB mode */ 115/* MediaTek extend the two bits for PA 32bit/33bit */
116#define ARM_V7S_ATTR_MTK_PA_BIT32 BIT(9)
117#define ARM_V7S_ATTR_MTK_PA_BIT33 BIT(4)
116 118
117/* *well, except for TEX on level 2 large pages, of course :( */ 119/* *well, except for TEX on level 2 large pages, of course :( */
118#define ARM_V7S_CONT_PAGE_TEX_SHIFT 6 120#define ARM_V7S_CONT_PAGE_TEX_SHIFT 6
@@ -176,16 +178,32 @@ static dma_addr_t __arm_v7s_dma_addr(void *pages)
176 return (dma_addr_t)virt_to_phys(pages); 178 return (dma_addr_t)virt_to_phys(pages);
177} 179}
178 180
181static bool arm_v7s_is_mtk_enabled(struct io_pgtable_cfg *cfg)
182{
183 return IS_ENABLED(CONFIG_PHYS_ADDR_T_64BIT) &&
184 (cfg->quirks & IO_PGTABLE_QUIRK_ARM_MTK_EXT);
185}
186
179static arm_v7s_iopte paddr_to_iopte(phys_addr_t paddr, int lvl, 187static arm_v7s_iopte paddr_to_iopte(phys_addr_t paddr, int lvl,
180 struct io_pgtable_cfg *cfg) 188 struct io_pgtable_cfg *cfg)
181{ 189{
182 return paddr & ARM_V7S_LVL_MASK(lvl); 190 arm_v7s_iopte pte = paddr & ARM_V7S_LVL_MASK(lvl);
191
192 if (!arm_v7s_is_mtk_enabled(cfg))
193 return pte;
194
195 if (paddr & BIT_ULL(32))
196 pte |= ARM_V7S_ATTR_MTK_PA_BIT32;
197 if (paddr & BIT_ULL(33))
198 pte |= ARM_V7S_ATTR_MTK_PA_BIT33;
199 return pte;
183} 200}
184 201
185static phys_addr_t iopte_to_paddr(arm_v7s_iopte pte, int lvl, 202static phys_addr_t iopte_to_paddr(arm_v7s_iopte pte, int lvl,
186 struct io_pgtable_cfg *cfg) 203 struct io_pgtable_cfg *cfg)
187{ 204{
188 arm_v7s_iopte mask; 205 arm_v7s_iopte mask;
206 phys_addr_t paddr;
189 207
190 if (ARM_V7S_PTE_IS_TABLE(pte, lvl)) 208 if (ARM_V7S_PTE_IS_TABLE(pte, lvl))
191 mask = ARM_V7S_TABLE_MASK; 209 mask = ARM_V7S_TABLE_MASK;
@@ -194,7 +212,15 @@ static phys_addr_t iopte_to_paddr(arm_v7s_iopte pte, int lvl,
194 else 212 else
195 mask = ARM_V7S_LVL_MASK(lvl); 213 mask = ARM_V7S_LVL_MASK(lvl);
196 214
197 return pte & mask; 215 paddr = pte & mask;
216 if (!arm_v7s_is_mtk_enabled(cfg))
217 return paddr;
218
219 if (pte & ARM_V7S_ATTR_MTK_PA_BIT32)
220 paddr |= BIT_ULL(32);
221 if (pte & ARM_V7S_ATTR_MTK_PA_BIT33)
222 paddr |= BIT_ULL(33);
223 return paddr;
198} 224}
199 225
200static arm_v7s_iopte *iopte_deref(arm_v7s_iopte pte, int lvl, 226static arm_v7s_iopte *iopte_deref(arm_v7s_iopte pte, int lvl,
@@ -315,9 +341,6 @@ static arm_v7s_iopte arm_v7s_prot_to_pte(int prot, int lvl,
315 if (lvl == 1 && (cfg->quirks & IO_PGTABLE_QUIRK_ARM_NS)) 341 if (lvl == 1 && (cfg->quirks & IO_PGTABLE_QUIRK_ARM_NS))
316 pte |= ARM_V7S_ATTR_NS_SECTION; 342 pte |= ARM_V7S_ATTR_NS_SECTION;
317 343
318 if (cfg->quirks & IO_PGTABLE_QUIRK_ARM_MTK_EXT)
319 pte |= ARM_V7S_ATTR_MTK_4GB;
320
321 return pte; 344 return pte;
322} 345}
323 346
@@ -731,7 +754,10 @@ static struct io_pgtable *arm_v7s_alloc_pgtable(struct io_pgtable_cfg *cfg,
731{ 754{
732 struct arm_v7s_io_pgtable *data; 755 struct arm_v7s_io_pgtable *data;
733 756
734 if (cfg->ias > ARM_V7S_ADDR_BITS || cfg->oas > ARM_V7S_ADDR_BITS) 757 if (cfg->ias > ARM_V7S_ADDR_BITS)
758 return NULL;
759
760 if (cfg->oas > (arm_v7s_is_mtk_enabled(cfg) ? 34 : ARM_V7S_ADDR_BITS))
735 return NULL; 761 return NULL;
736 762
737 if (cfg->quirks & ~(IO_PGTABLE_QUIRK_ARM_NS | 763 if (cfg->quirks & ~(IO_PGTABLE_QUIRK_ARM_NS |