* [PATCH v9 0/3] iommu/mediatek: TTBR up to 35bit support
@ 2022-06-15 16:12 yf.wang
2022-06-15 16:12 ` [PATCH v9 1/3] iommu/io-pgtable-arm-v7s: Add a quirk to allow pgtable PA up to 35bit yf.wang
` (2 more replies)
0 siblings, 3 replies; 11+ messages in thread
From: yf.wang @ 2022-06-15 16:12 UTC (permalink / raw)
To: Matthias Brugger, moderated list:ARM/Mediatek SoC support,
moderated list:ARM/Mediatek SoC support
Cc: wsd_upstream, Libo Kang, Yong Wu, Miles Chen
Changes in v8:
- Add and update patch
- Add [2/3] patch update MTK_IOMMU_ADDR to calculate the special ttbr.
- Save the special ttbr to mtk_iommu_domain avoid calculate it again.
Changes in v7:
- Update patch and commit message
- Extend arm_v7s_cfg.ttbr to u64.
- Move the special ttbr logical into mtk_iommu.c.
- Update commit message for single normal zone.
Changes in v6:
- Update patch: gfp_l1 = GFP_KERNEL | __GFP_ZERO;
- Update commit message for single normal zone.
Changes in v5:
- Only update message-ID.
Changes in v4:
- Fix build test WARNING: use GENMASK_ULL replace GENMASK.
Changes in v3:
- Add version changes description, there is No new code change in V3.
Changes in v2:
- Update patch and commit message
- Add Level 1 pgtable PA up to 35bit.
- This is new feature, remove stable@vger.kernel.org
- Update commit message.
Yunfei Wang (1):
iommu/mediatek: Rename MTK_IOMMU_TLB_ADDR to MTK_IOMMU_ADDR
Ning Li (2):
iommu/io-pgtable-arm-v7s: Add a quirk to allow pgtable PA up to 35bit
iommu/mediatek: Allow page table PA up to 35bit
drivers/iommu/io-pgtable-arm-v7s.c | 58 +++++++++++++++++++++++-------
drivers/iommu/mtk_iommu.c | 22 ++++++++------
include/linux/io-pgtable.h | 17 +++++----
3 files changed, 69 insertions(+), 28 deletions(-)
^ permalink raw reply [flat|nested] 11+ messages in thread* [PATCH v9 1/3] iommu/io-pgtable-arm-v7s: Add a quirk to allow pgtable PA up to 35bit 2022-06-15 16:12 [PATCH v9 0/3] iommu/mediatek: TTBR up to 35bit support yf.wang @ 2022-06-15 16:12 ` yf.wang 2022-06-15 17:03 ` Robin Murphy 2022-06-15 16:12 ` [PATCH v9 2/3] iommu/mediatek: Rename MTK_IOMMU_TLB_ADDR to MTK_IOMMU_ADDR yf.wang 2022-06-15 16:12 ` [PATCH v9 3/3] iommu/mediatek: Allow page table PA up to 35bit yf.wang 2 siblings, 1 reply; 11+ messages in thread From: yf.wang @ 2022-06-15 16:12 UTC (permalink / raw) To: Will Deacon, Robin Murphy, Joerg Roedel, Matthias Brugger, Georgi Djakov, Isaac J. Manjarres, Ning Li, Sven Peter, Yunfei Wang, moderated list:ARM SMMU DRIVERS, open list:IOMMU DRIVERS, open list, moderated list:ARM/Mediatek SoC support Cc: wsd_upstream, Libo Kang, Yong Wu, Miles Chen From: Yunfei Wang <yf.wang@mediatek.com> Single memory zone feature will remove ZONE_DMA32 and ZONE_DMA and cause pgtable PA size larger than 32bit. Since Mediatek IOMMU hardware support at most 35bit PA in pgtable, so add a quirk to allow the PA of pgtables support up to bit35. Signed-off-by: Ning Li <ning.li@mediatek.com> Signed-off-by: Yunfei Wang <yf.wang@mediatek.com> --- drivers/iommu/io-pgtable-arm-v7s.c | 58 +++++++++++++++++++++++------- include/linux/io-pgtable.h | 17 +++++---- 2 files changed, 56 insertions(+), 19 deletions(-) diff --git a/drivers/iommu/io-pgtable-arm-v7s.c b/drivers/iommu/io-pgtable-arm-v7s.c index be066c1503d3..39e5503ac75a 100644 --- a/drivers/iommu/io-pgtable-arm-v7s.c +++ b/drivers/iommu/io-pgtable-arm-v7s.c @@ -182,14 +182,8 @@ static bool arm_v7s_is_mtk_enabled(struct io_pgtable_cfg *cfg) (cfg->quirks & IO_PGTABLE_QUIRK_ARM_MTK_EXT); } -static arm_v7s_iopte paddr_to_iopte(phys_addr_t paddr, int lvl, - struct io_pgtable_cfg *cfg) +static arm_v7s_iopte to_mtk_iopte(phys_addr_t paddr, arm_v7s_iopte pte) { - arm_v7s_iopte pte = paddr & ARM_V7S_LVL_MASK(lvl); - - if (!arm_v7s_is_mtk_enabled(cfg)) - return pte; - if (paddr & BIT_ULL(32)) pte |= ARM_V7S_ATTR_MTK_PA_BIT32; if (paddr & BIT_ULL(33)) @@ -199,6 +193,17 @@ static arm_v7s_iopte paddr_to_iopte(phys_addr_t paddr, int lvl, return pte; } +static arm_v7s_iopte paddr_to_iopte(phys_addr_t paddr, int lvl, + struct io_pgtable_cfg *cfg) +{ + arm_v7s_iopte pte = paddr & ARM_V7S_LVL_MASK(lvl); + + if (arm_v7s_is_mtk_enabled(cfg)) + return to_mtk_iopte(paddr, pte); + + return pte; +} + static phys_addr_t iopte_to_paddr(arm_v7s_iopte pte, int lvl, struct io_pgtable_cfg *cfg) { @@ -240,10 +245,17 @@ static void *__arm_v7s_alloc_table(int lvl, gfp_t gfp, dma_addr_t dma; size_t size = ARM_V7S_TABLE_SIZE(lvl, cfg); void *table = NULL; + gfp_t gfp_l1; + + /* + * ARM_MTK_TTBR_EXT extend the translation table base support all + * memory address. + */ + gfp_l1 = cfg->quirks & IO_PGTABLE_QUIRK_ARM_MTK_TTBR_EXT ? + GFP_KERNEL : ARM_V7S_TABLE_GFP_DMA; if (lvl == 1) - table = (void *)__get_free_pages( - __GFP_ZERO | ARM_V7S_TABLE_GFP_DMA, get_order(size)); + table = (void *)__get_free_pages(gfp_l1 | __GFP_ZERO, get_order(size)); else if (lvl == 2) table = kmem_cache_zalloc(data->l2_tables, gfp); @@ -251,7 +263,8 @@ static void *__arm_v7s_alloc_table(int lvl, gfp_t gfp, return NULL; phys = virt_to_phys(table); - if (phys != (arm_v7s_iopte)phys) { + if (cfg->quirks & IO_PGTABLE_QUIRK_ARM_MTK_TTBR_EXT ? + phys >= (1ULL << cfg->oas) : phys != (arm_v7s_iopte)phys) { /* Doesn't fit in PTE */ dev_err(dev, "Page table does not fit in PTE: %pa", &phys); goto out_free; @@ -457,9 +470,14 @@ static arm_v7s_iopte arm_v7s_install_table(arm_v7s_iopte *table, arm_v7s_iopte curr, struct io_pgtable_cfg *cfg) { + phys_addr_t phys = virt_to_phys(table); arm_v7s_iopte old, new; - new = virt_to_phys(table) | ARM_V7S_PTE_TYPE_TABLE; + new = phys | ARM_V7S_PTE_TYPE_TABLE; + + if (cfg->quirks & IO_PGTABLE_QUIRK_ARM_MTK_TTBR_EXT) + new = to_mtk_iopte(phys, new); + if (cfg->quirks & IO_PGTABLE_QUIRK_ARM_NS) new |= ARM_V7S_ATTR_NS_TABLE; @@ -779,6 +797,7 @@ static struct io_pgtable *arm_v7s_alloc_pgtable(struct io_pgtable_cfg *cfg, void *cookie) { struct arm_v7s_io_pgtable *data; + slab_flags_t slab_flag; if (cfg->ias > (arm_v7s_is_mtk_enabled(cfg) ? 34 : ARM_V7S_ADDR_BITS)) return NULL; @@ -788,7 +807,8 @@ static struct io_pgtable *arm_v7s_alloc_pgtable(struct io_pgtable_cfg *cfg, if (cfg->quirks & ~(IO_PGTABLE_QUIRK_ARM_NS | IO_PGTABLE_QUIRK_NO_PERMS | - IO_PGTABLE_QUIRK_ARM_MTK_EXT)) + IO_PGTABLE_QUIRK_ARM_MTK_EXT | + IO_PGTABLE_QUIRK_ARM_MTK_TTBR_EXT)) return NULL; /* If ARM_MTK_4GB is enabled, the NO_PERMS is also expected. */ @@ -796,15 +816,27 @@ static struct io_pgtable *arm_v7s_alloc_pgtable(struct io_pgtable_cfg *cfg, !(cfg->quirks & IO_PGTABLE_QUIRK_NO_PERMS)) return NULL; + if ((cfg->quirks & IO_PGTABLE_QUIRK_ARM_MTK_TTBR_EXT) && + !arm_v7s_is_mtk_enabled(cfg)) + return NULL; + data = kmalloc(sizeof(*data), GFP_KERNEL); if (!data) return NULL; spin_lock_init(&data->split_lock); + + /* + * ARM_MTK_TTBR_EXT extend the translation table base support all + * memory address. + */ + slab_flag = cfg->quirks & IO_PGTABLE_QUIRK_ARM_MTK_TTBR_EXT ? + 0 : ARM_V7S_TABLE_SLAB_FLAGS; + data->l2_tables = kmem_cache_create("io-pgtable_armv7s_l2", ARM_V7S_TABLE_SIZE(2, cfg), ARM_V7S_TABLE_SIZE(2, cfg), - ARM_V7S_TABLE_SLAB_FLAGS, NULL); + slab_flag, NULL); if (!data->l2_tables) goto out_free_data; diff --git a/include/linux/io-pgtable.h b/include/linux/io-pgtable.h index 86af6f0a00a2..c9189716f6bd 100644 --- a/include/linux/io-pgtable.h +++ b/include/linux/io-pgtable.h @@ -74,17 +74,22 @@ struct io_pgtable_cfg { * to support up to 35 bits PA where the bit32, bit33 and bit34 are * encoded in the bit9, bit4 and bit5 of the PTE respectively. * + * IO_PGTABLE_QUIRK_ARM_MTK_TTBR_EXT: (ARM v7s format) MediaTek IOMMUs + * extend the translation table base support up to 35 bits PA, the + * encoding format is same with IO_PGTABLE_QUIRK_ARM_MTK_EXT. + * * IO_PGTABLE_QUIRK_ARM_TTBR1: (ARM LPAE format) Configure the table * for use in the upper half of a split address space. * * IO_PGTABLE_QUIRK_ARM_OUTER_WBWA: Override the outer-cacheability * attributes set in the TCR for a non-coherent page-table walker. */ - #define IO_PGTABLE_QUIRK_ARM_NS BIT(0) - #define IO_PGTABLE_QUIRK_NO_PERMS BIT(1) - #define IO_PGTABLE_QUIRK_ARM_MTK_EXT BIT(3) - #define IO_PGTABLE_QUIRK_ARM_TTBR1 BIT(5) - #define IO_PGTABLE_QUIRK_ARM_OUTER_WBWA BIT(6) + #define IO_PGTABLE_QUIRK_ARM_NS BIT(0) + #define IO_PGTABLE_QUIRK_NO_PERMS BIT(1) + #define IO_PGTABLE_QUIRK_ARM_MTK_EXT BIT(3) + #define IO_PGTABLE_QUIRK_ARM_MTK_TTBR_EXT BIT(4) + #define IO_PGTABLE_QUIRK_ARM_TTBR1 BIT(5) + #define IO_PGTABLE_QUIRK_ARM_OUTER_WBWA BIT(6) unsigned long quirks; unsigned long pgsize_bitmap; unsigned int ias; @@ -122,7 +127,7 @@ struct io_pgtable_cfg { } arm_lpae_s2_cfg; struct { - u32 ttbr; + u64 ttbr; u32 tcr; u32 nmrr; u32 prrr; -- 2.18.0 ^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH v9 1/3] iommu/io-pgtable-arm-v7s: Add a quirk to allow pgtable PA up to 35bit 2022-06-15 16:12 ` [PATCH v9 1/3] iommu/io-pgtable-arm-v7s: Add a quirk to allow pgtable PA up to 35bit yf.wang @ 2022-06-15 17:03 ` Robin Murphy 2022-06-16 6:26 ` yf.wang 0 siblings, 1 reply; 11+ messages in thread From: Robin Murphy @ 2022-06-15 17:03 UTC (permalink / raw) To: yf.wang, Will Deacon, Joerg Roedel, Matthias Brugger, Georgi Djakov, Isaac J. Manjarres, Ning Li, Sven Peter, moderated list:ARM SMMU DRIVERS, open list:IOMMU DRIVERS, open list, moderated list:ARM/Mediatek SoC support Cc: wsd_upstream, Libo Kang, Yong Wu, Miles Chen On 2022-06-15 17:12, yf.wang@mediatek.com wrote: > From: Yunfei Wang <yf.wang@mediatek.com> > > Single memory zone feature will remove ZONE_DMA32 and ZONE_DMA and > cause pgtable PA size larger than 32bit. > > Since Mediatek IOMMU hardware support at most 35bit PA in pgtable, > so add a quirk to allow the PA of pgtables support up to bit35. > > Signed-off-by: Ning Li <ning.li@mediatek.com> > Signed-off-by: Yunfei Wang <yf.wang@mediatek.com> > --- > drivers/iommu/io-pgtable-arm-v7s.c | 58 +++++++++++++++++++++++------- > include/linux/io-pgtable.h | 17 +++++---- > 2 files changed, 56 insertions(+), 19 deletions(-) > > diff --git a/drivers/iommu/io-pgtable-arm-v7s.c b/drivers/iommu/io-pgtable-arm-v7s.c > index be066c1503d3..39e5503ac75a 100644 > --- a/drivers/iommu/io-pgtable-arm-v7s.c > +++ b/drivers/iommu/io-pgtable-arm-v7s.c > @@ -182,14 +182,8 @@ static bool arm_v7s_is_mtk_enabled(struct io_pgtable_cfg *cfg) > (cfg->quirks & IO_PGTABLE_QUIRK_ARM_MTK_EXT); > } > > -static arm_v7s_iopte paddr_to_iopte(phys_addr_t paddr, int lvl, > - struct io_pgtable_cfg *cfg) > +static arm_v7s_iopte to_mtk_iopte(phys_addr_t paddr, arm_v7s_iopte pte) > { > - arm_v7s_iopte pte = paddr & ARM_V7S_LVL_MASK(lvl); > - > - if (!arm_v7s_is_mtk_enabled(cfg)) > - return pte; > - > if (paddr & BIT_ULL(32)) > pte |= ARM_V7S_ATTR_MTK_PA_BIT32; > if (paddr & BIT_ULL(33)) > @@ -199,6 +193,17 @@ static arm_v7s_iopte paddr_to_iopte(phys_addr_t paddr, int lvl, > return pte; > } > > +static arm_v7s_iopte paddr_to_iopte(phys_addr_t paddr, int lvl, > + struct io_pgtable_cfg *cfg) > +{ > + arm_v7s_iopte pte = paddr & ARM_V7S_LVL_MASK(lvl); > + > + if (arm_v7s_is_mtk_enabled(cfg)) > + return to_mtk_iopte(paddr, pte); > + > + return pte; > +} > + > static phys_addr_t iopte_to_paddr(arm_v7s_iopte pte, int lvl, > struct io_pgtable_cfg *cfg) > { > @@ -240,10 +245,17 @@ static void *__arm_v7s_alloc_table(int lvl, gfp_t gfp, > dma_addr_t dma; > size_t size = ARM_V7S_TABLE_SIZE(lvl, cfg); > void *table = NULL; > + gfp_t gfp_l1; > + > + /* > + * ARM_MTK_TTBR_EXT extend the translation table base support all > + * memory address. > + */ > + gfp_l1 = cfg->quirks & IO_PGTABLE_QUIRK_ARM_MTK_TTBR_EXT ? > + GFP_KERNEL : ARM_V7S_TABLE_GFP_DMA; > > if (lvl == 1) > - table = (void *)__get_free_pages( > - __GFP_ZERO | ARM_V7S_TABLE_GFP_DMA, get_order(size)); > + table = (void *)__get_free_pages(gfp_l1 | __GFP_ZERO, get_order(size)); > else if (lvl == 2) > table = kmem_cache_zalloc(data->l2_tables, gfp); > > @@ -251,7 +263,8 @@ static void *__arm_v7s_alloc_table(int lvl, gfp_t gfp, > return NULL; > > phys = virt_to_phys(table); > - if (phys != (arm_v7s_iopte)phys) { > + if (cfg->quirks & IO_PGTABLE_QUIRK_ARM_MTK_TTBR_EXT ? > + phys >= (1ULL << cfg->oas) : phys != (arm_v7s_iopte)phys) { Given that the comment above says it supports all of memory, how would phys >= (1ULL << cfg->oas) ever be true? > /* Doesn't fit in PTE */ > dev_err(dev, "Page table does not fit in PTE: %pa", &phys); > goto out_free; > @@ -457,9 +470,14 @@ static arm_v7s_iopte arm_v7s_install_table(arm_v7s_iopte *table, > arm_v7s_iopte curr, > struct io_pgtable_cfg *cfg) > { > + phys_addr_t phys = virt_to_phys(table); > arm_v7s_iopte old, new; > > - new = virt_to_phys(table) | ARM_V7S_PTE_TYPE_TABLE; > + new = phys | ARM_V7S_PTE_TYPE_TABLE; > + > + if (cfg->quirks & IO_PGTABLE_QUIRK_ARM_MTK_TTBR_EXT) > + new = to_mtk_iopte(phys, new); > + > if (cfg->quirks & IO_PGTABLE_QUIRK_ARM_NS) > new |= ARM_V7S_ATTR_NS_TABLE; > > @@ -779,6 +797,7 @@ static struct io_pgtable *arm_v7s_alloc_pgtable(struct io_pgtable_cfg *cfg, > void *cookie) > { > struct arm_v7s_io_pgtable *data; > + slab_flags_t slab_flag; > > if (cfg->ias > (arm_v7s_is_mtk_enabled(cfg) ? 34 : ARM_V7S_ADDR_BITS)) > return NULL; > @@ -788,7 +807,8 @@ static struct io_pgtable *arm_v7s_alloc_pgtable(struct io_pgtable_cfg *cfg, > > if (cfg->quirks & ~(IO_PGTABLE_QUIRK_ARM_NS | > IO_PGTABLE_QUIRK_NO_PERMS | > - IO_PGTABLE_QUIRK_ARM_MTK_EXT)) > + IO_PGTABLE_QUIRK_ARM_MTK_EXT | > + IO_PGTABLE_QUIRK_ARM_MTK_TTBR_EXT)) > return NULL; > > /* If ARM_MTK_4GB is enabled, the NO_PERMS is also expected. */ > @@ -796,15 +816,27 @@ static struct io_pgtable *arm_v7s_alloc_pgtable(struct io_pgtable_cfg *cfg, > !(cfg->quirks & IO_PGTABLE_QUIRK_NO_PERMS)) > return NULL; > > + if ((cfg->quirks & IO_PGTABLE_QUIRK_ARM_MTK_TTBR_EXT) && > + !arm_v7s_is_mtk_enabled(cfg)) > + return NULL; > + > data = kmalloc(sizeof(*data), GFP_KERNEL); > if (!data) > return NULL; > > spin_lock_init(&data->split_lock); > + > + /* > + * ARM_MTK_TTBR_EXT extend the translation table base support all > + * memory address. > + */ > + slab_flag = cfg->quirks & IO_PGTABLE_QUIRK_ARM_MTK_TTBR_EXT ? > + 0 : ARM_V7S_TABLE_SLAB_FLAGS; > + > data->l2_tables = kmem_cache_create("io-pgtable_armv7s_l2", > ARM_V7S_TABLE_SIZE(2, cfg), > ARM_V7S_TABLE_SIZE(2, cfg), > - ARM_V7S_TABLE_SLAB_FLAGS, NULL); > + slab_flag, NULL); > if (!data->l2_tables) > goto out_free_data; > > diff --git a/include/linux/io-pgtable.h b/include/linux/io-pgtable.h > index 86af6f0a00a2..c9189716f6bd 100644 > --- a/include/linux/io-pgtable.h > +++ b/include/linux/io-pgtable.h > @@ -74,17 +74,22 @@ struct io_pgtable_cfg { > * to support up to 35 bits PA where the bit32, bit33 and bit34 are > * encoded in the bit9, bit4 and bit5 of the PTE respectively. > * > + * IO_PGTABLE_QUIRK_ARM_MTK_TTBR_EXT: (ARM v7s format) MediaTek IOMMUs > + * extend the translation table base support up to 35 bits PA, the > + * encoding format is same with IO_PGTABLE_QUIRK_ARM_MTK_EXT. > + * > * IO_PGTABLE_QUIRK_ARM_TTBR1: (ARM LPAE format) Configure the table > * for use in the upper half of a split address space. > * > * IO_PGTABLE_QUIRK_ARM_OUTER_WBWA: Override the outer-cacheability > * attributes set in the TCR for a non-coherent page-table walker. > */ > - #define IO_PGTABLE_QUIRK_ARM_NS BIT(0) > - #define IO_PGTABLE_QUIRK_NO_PERMS BIT(1) > - #define IO_PGTABLE_QUIRK_ARM_MTK_EXT BIT(3) > - #define IO_PGTABLE_QUIRK_ARM_TTBR1 BIT(5) > - #define IO_PGTABLE_QUIRK_ARM_OUTER_WBWA BIT(6) > + #define IO_PGTABLE_QUIRK_ARM_NS BIT(0) > + #define IO_PGTABLE_QUIRK_NO_PERMS BIT(1) > + #define IO_PGTABLE_QUIRK_ARM_MTK_EXT BIT(3) > + #define IO_PGTABLE_QUIRK_ARM_MTK_TTBR_EXT BIT(4) > + #define IO_PGTABLE_QUIRK_ARM_TTBR1 BIT(5) > + #define IO_PGTABLE_QUIRK_ARM_OUTER_WBWA BIT(6) > unsigned long quirks; > unsigned long pgsize_bitmap; > unsigned int ias; > @@ -122,7 +127,7 @@ struct io_pgtable_cfg { > } arm_lpae_s2_cfg; > > struct { > - u32 ttbr; > + u64 ttbr; The point of this is to return an encoded TTBR register value, not a raw base address. I see from the other patches that your register is still 32 bits, so I'd prefer to follow the standard pattern and not need this change. Thanks, Robin. > u32 tcr; > u32 nmrr; > u32 prrr; ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v9 1/3] iommu/io-pgtable-arm-v7s: Add a quirk to allow pgtable PA up to 35bit 2022-06-15 17:03 ` Robin Murphy @ 2022-06-16 6:26 ` yf.wang 0 siblings, 0 replies; 11+ messages in thread From: yf.wang @ 2022-06-16 6:26 UTC (permalink / raw) To: robin.murphy Cc: Libo.Kang, Yong.Wu, iommu, isaacm, joro, linux-arm-kernel, linux-kernel, linux-mediatek, matthias.bgg, miles.chen, ning.li, quic_c_gdjako, sven, will, wsd_upstream, yf.wang On Wed, 2022-06-15 at 18:03 +0100, Robin Murphy wrote: > On 2022-06-15 17:12, yf.wang@mediatek.com wrote: > > > > static phys_addr_t iopte_to_paddr(arm_v7s_iopte pte, int lvl, > > struct io_pgtable_cfg *cfg) > > { > > @@ -240,10 +245,17 @@ static void *__arm_v7s_alloc_table(int lvl, > > gfp_t gfp, > > dma_addr_t dma; > > size_t size = ARM_V7S_TABLE_SIZE(lvl, cfg); > > void *table = NULL; > > + gfp_t gfp_l1; > > + > > + /* > > + * ARM_MTK_TTBR_EXT extend the translation table base support > > all > > + * memory address. > > + */ > > + gfp_l1 = cfg->quirks & IO_PGTABLE_QUIRK_ARM_MTK_TTBR_EXT ? > > + GFP_KERNEL : ARM_V7S_TABLE_GFP_DMA; > > > > if (lvl == 1) > > - table = (void *)__get_free_pages( > > - __GFP_ZERO | ARM_V7S_TABLE_GFP_DMA, > > get_order(size)); > > + table = (void *)__get_free_pages(gfp_l1 | __GFP_ZERO, > > get_order(size)); > > else if (lvl == 2) > > table = kmem_cache_zalloc(data->l2_tables, gfp); > > > > @@ -251,7 +263,8 @@ static void *__arm_v7s_alloc_table(int lvl, > > gfp_t gfp, > > return NULL; > > > > phys = virt_to_phys(table); > > - if (phys != (arm_v7s_iopte)phys) { > > + if (cfg->quirks & IO_PGTABLE_QUIRK_ARM_MTK_TTBR_EXT ? > > + phys >= (1ULL << cfg->oas) : phys != (arm_v7s_iopte)phys) { > > Given that the comment above says it supports all of memory, how > would > phys >= (1ULL << cfg->oas) ever be true? > Hi Robin, Since Mediatek IOMMU hardware support at most 35bit PA in pgtable, so add a quirk to allow the PA of pgtables support up to bit35, but need to check oas do error hanlde. > > /* Doesn't fit in PTE */ > > dev_err(dev, "Page table does not fit in PTE: %pa", > > &phys); > > goto out_free; > > arm_v7s_install_table(arm_v7s_iopte *table, > > arm_v7s_iopte curr, > > struct io_pgtable_cfg *cfg) ... > > diff --git a/include/linux/io-pgtable.h b/include/linux/io- > > pgtable.h > > index 86af6f0a00a2..c9189716f6bd 100644 > > --- a/include/linux/io-pgtable.h > > +++ b/include/linux/io-pgtable.h > > @@ -74,17 +74,22 @@ struct io_pgtable_cfg { > > * to support up to 35 bits PA where the bit32, bit33 and > > bit34 are > > * encoded in the bit9, bit4 and bit5 of the PTE respectively. > > * > > + * IO_PGTABLE_QUIRK_ARM_MTK_TTBR_EXT: (ARM v7s format) MediaTek > > IOMMUs > > + * extend the translation table base support up to 35 bits PA, > > the > > + * encoding format is same with IO_PGTABLE_QUIRK_ARM_MTK_EXT. > > + * > > * IO_PGTABLE_QUIRK_ARM_TTBR1: (ARM LPAE format) Configure the > > table > > * for use in the upper half of a split address space. > > * > > * IO_PGTABLE_QUIRK_ARM_OUTER_WBWA: Override the outer- > > cacheability > > * attributes set in the TCR for a non-coherent page-table > > walker. > > */ > > - #define IO_PGTABLE_QUIRK_ARM_NS BIT(0) > > - #define IO_PGTABLE_QUIRK_NO_PERMS BIT(1) > > - #define IO_PGTABLE_QUIRK_ARM_MTK_EXT BIT(3) > > - #define IO_PGTABLE_QUIRK_ARM_TTBR1 BIT(5) > > - #define IO_PGTABLE_QUIRK_ARM_OUTER_WBWA BIT(6) > > + #define IO_PGTABLE_QUIRK_ARM_NS BIT(0) > > + #define IO_PGTABLE_QUIRK_NO_PERMS BIT(1) > > + #define IO_PGTABLE_QUIRK_ARM_MTK_EXT BIT(3) > > + #define IO_PGTABLE_QUIRK_ARM_MTK_TTBR_EXT BIT(4) > > + #define IO_PGTABLE_QUIRK_ARM_TTBR1 BIT(5) > > + #define IO_PGTABLE_QUIRK_ARM_OUTER_WBWA BIT(6) > > unsigned long quirks; > > unsigned long pgsize_bitmap; > > unsigned int ias; > > @@ -122,7 +127,7 @@ struct io_pgtable_cfg { > > } arm_lpae_s2_cfg; > > > > struct { > > - u32 ttbr; > > + u64 ttbr; > > The point of this is to return an encoded TTBR register value, not a > raw > base address. I see from the other patches that your register is > still > 32 bits, so I'd prefer to follow the standard pattern and not need > this > change. > > Thanks, > Robin. > Hi Robin, Thanks for your suggestion, next version will recovery ttbr to 32 bits, will modify arm_v7s_alloc_pgtable to return an encoded TTBR, encoded PA bits[34:32] to to lower bits, as follows: /* TTBR */ phys_addr_t paddr; paddr = virt_to_phys(data->pgd); cfg->arm_v7s_cfg.ttbr = virt_to_phys(data->pgd) | ARM_V7S_TTBR_S | (cfg->coherent_walk ? (ARM_V7S_TTBR_NOS | ARM_V7S_TTBR_IRGN_ATTR(ARM_V7S_RGN_WBWA) | ARM_V7S_TTBR_ORGN_ATTR(ARM_V7S_RGN_WBWA)) : (ARM_V7S_TTBR_IRGN_ATTR(ARM_V7S_RGN_NC) | ARM_V7S_TTBR_ORGN_ATTR(ARM_V7S_RGN_NC))); if (cfg->quirks & IO_PGTABLE_QUIRK_ARM_MTK_TTBR_EXT) cfg->arm_v7s_cfg.ttbr = (paddr & GENMASK(31, 7)) | upper_32_bits(paddr); Thanks, Yunfei. > > u32 tcr; > > u32 nmrr; > > u32 prrr; ^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH v9 2/3] iommu/mediatek: Rename MTK_IOMMU_TLB_ADDR to MTK_IOMMU_ADDR 2022-06-15 16:12 [PATCH v9 0/3] iommu/mediatek: TTBR up to 35bit support yf.wang 2022-06-15 16:12 ` [PATCH v9 1/3] iommu/io-pgtable-arm-v7s: Add a quirk to allow pgtable PA up to 35bit yf.wang @ 2022-06-15 16:12 ` yf.wang 2022-06-15 17:14 ` Robin Murphy 2022-06-15 16:12 ` [PATCH v9 3/3] iommu/mediatek: Allow page table PA up to 35bit yf.wang 2 siblings, 1 reply; 11+ messages in thread From: yf.wang @ 2022-06-15 16:12 UTC (permalink / raw) To: Yong Wu, Joerg Roedel, Will Deacon, Matthias Brugger, open list:MEDIATEK IOMMU DRIVER, moderated list:MEDIATEK IOMMU DRIVER, moderated list:ARM/Mediatek SoC support, open list Cc: wsd_upstream, Libo Kang, Yong Wu, Miles Chen, Yunfei Wang, Ning Li From: Yunfei Wang <yf.wang@mediatek.com> Rename MTK_IOMMU_TLB_ADDR to MTK_IOMMU_ADDR, and update MTK_IOMMU_ADDR definition for better generality. Signed-off-by: Ning Li <ning.li@mediatek.com> Signed-off-by: Yunfei Wang <yf.wang@mediatek.com> --- drivers/iommu/mtk_iommu.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c index bb9dd92c9898..3d62399e8865 100644 --- a/drivers/iommu/mtk_iommu.c +++ b/drivers/iommu/mtk_iommu.c @@ -265,8 +265,8 @@ static const struct iommu_ops mtk_iommu_ops; static int mtk_iommu_hw_init(const struct mtk_iommu_data *data, unsigned int bankid); -#define MTK_IOMMU_TLB_ADDR(iova) ({ \ - dma_addr_t _addr = iova; \ +#define MTK_IOMMU_ADDR(addr) ({ \ + unsigned long long _addr = addr; \ ((lower_32_bits(_addr) & GENMASK(31, 12)) | upper_32_bits(_addr));\ }) @@ -381,8 +381,8 @@ static void mtk_iommu_tlb_flush_range_sync(unsigned long iova, size_t size, writel_relaxed(F_INVLD_EN1 | F_INVLD_EN0, base + data->plat_data->inv_sel_reg); - writel_relaxed(MTK_IOMMU_TLB_ADDR(iova), base + REG_MMU_INVLD_START_A); - writel_relaxed(MTK_IOMMU_TLB_ADDR(iova + size - 1), + writel_relaxed(MTK_IOMMU_ADDR(iova), base + REG_MMU_INVLD_START_A); + writel_relaxed(MTK_IOMMU_ADDR(iova + size - 1), base + REG_MMU_INVLD_END_A); writel_relaxed(F_MMU_INV_RANGE, base + REG_MMU_INVALIDATE); -- 2.18.0 ^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH v9 2/3] iommu/mediatek: Rename MTK_IOMMU_TLB_ADDR to MTK_IOMMU_ADDR 2022-06-15 16:12 ` [PATCH v9 2/3] iommu/mediatek: Rename MTK_IOMMU_TLB_ADDR to MTK_IOMMU_ADDR yf.wang @ 2022-06-15 17:14 ` Robin Murphy 2022-06-16 6:40 ` yf.wang 0 siblings, 1 reply; 11+ messages in thread From: Robin Murphy @ 2022-06-15 17:14 UTC (permalink / raw) To: yf.wang, Yong Wu, Joerg Roedel, Will Deacon, Matthias Brugger, open list:MEDIATEK IOMMU DRIVER, moderated list:MEDIATEK IOMMU DRIVER, moderated list:ARM/Mediatek SoC support, open list Cc: wsd_upstream, Libo Kang, Miles Chen, Ning Li On 2022-06-15 17:12, yf.wang--- via iommu wrote: > From: Yunfei Wang <yf.wang@mediatek.com> > > Rename MTK_IOMMU_TLB_ADDR to MTK_IOMMU_ADDR, and update MTK_IOMMU_ADDR > definition for better generality. > > Signed-off-by: Ning Li <ning.li@mediatek.com> > Signed-off-by: Yunfei Wang <yf.wang@mediatek.com> > --- > drivers/iommu/mtk_iommu.c | 8 ++++---- > 1 file changed, 4 insertions(+), 4 deletions(-) > > diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c > index bb9dd92c9898..3d62399e8865 100644 > --- a/drivers/iommu/mtk_iommu.c > +++ b/drivers/iommu/mtk_iommu.c > @@ -265,8 +265,8 @@ static const struct iommu_ops mtk_iommu_ops; > > static int mtk_iommu_hw_init(const struct mtk_iommu_data *data, unsigned int bankid); > > -#define MTK_IOMMU_TLB_ADDR(iova) ({ \ > - dma_addr_t _addr = iova; \ > +#define MTK_IOMMU_ADDR(addr) ({ \ > + unsigned long long _addr = addr; \ If phys_addr_t is 64-bit, then dma_addr_t is also 64-bit, so there is no loss of generality from using an appropriate type - IOVAs have to fit into dma_addr_t for iommu-dma, after all. However, since IOVAs also have to fit into unsigned long in the general IOMMU API, as "addr" is here, then this is still just as broken for 32-bit LPAE as the existing code is. Thanks, Robin. > ((lower_32_bits(_addr) & GENMASK(31, 12)) | upper_32_bits(_addr));\ > }) > > @@ -381,8 +381,8 @@ static void mtk_iommu_tlb_flush_range_sync(unsigned long iova, size_t size, > writel_relaxed(F_INVLD_EN1 | F_INVLD_EN0, > base + data->plat_data->inv_sel_reg); > > - writel_relaxed(MTK_IOMMU_TLB_ADDR(iova), base + REG_MMU_INVLD_START_A); > - writel_relaxed(MTK_IOMMU_TLB_ADDR(iova + size - 1), > + writel_relaxed(MTK_IOMMU_ADDR(iova), base + REG_MMU_INVLD_START_A); > + writel_relaxed(MTK_IOMMU_ADDR(iova + size - 1), > base + REG_MMU_INVLD_END_A); > writel_relaxed(F_MMU_INV_RANGE, base + REG_MMU_INVALIDATE); > ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v9 2/3] iommu/mediatek: Rename MTK_IOMMU_TLB_ADDR to MTK_IOMMU_ADDR 2022-06-15 17:14 ` Robin Murphy @ 2022-06-16 6:40 ` yf.wang 0 siblings, 0 replies; 11+ messages in thread From: yf.wang @ 2022-06-16 6:40 UTC (permalink / raw) To: robin.murphy Cc: Libo.Kang, iommu, joro, linux-arm-kernel, linux-kernel, linux-mediatek, matthias.bgg, miles.chen, ning.li, will, wsd_upstream, yf.wang, yong.wu On Wed, 2022-06-15 at 18:14 +0100, Robin Murphy wrote: > On 2022-06-15 17:12, yf.wang--- via iommu wrote: > > From: Yunfei Wang <yf.wang@mediatek.com> > > > > Rename MTK_IOMMU_TLB_ADDR to MTK_IOMMU_ADDR, and update > > MTK_IOMMU_ADDR > > definition for better generality. > > > > Signed-off-by: Ning Li <ning.li@mediatek.com> > > Signed-off-by: Yunfei Wang <yf.wang@mediatek.com> > > --- > > drivers/iommu/mtk_iommu.c | 8 ++++---- > > 1 file changed, 4 insertions(+), 4 deletions(-) > > > > diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c > > index bb9dd92c9898..3d62399e8865 100644 > > --- a/drivers/iommu/mtk_iommu.c > > +++ b/drivers/iommu/mtk_iommu.c > > @@ -265,8 +265,8 @@ static const struct iommu_ops mtk_iommu_ops; > > > > static int mtk_iommu_hw_init(const struct mtk_iommu_data *data, > > unsigned int bankid); > > > > -#define MTK_IOMMU_TLB_ADDR(iova) ({ > > \ > > - dma_addr_t _addr = iova; \ > > +#define MTK_IOMMU_ADDR(addr) ({ > > \ > > + unsigned long long _addr = addr; \ > > If phys_addr_t is 64-bit, then dma_addr_t is also 64-bit, so there is > no > loss of generality from using an appropriate type - IOVAs have to > fit > into dma_addr_t for iommu-dma, after all. However, since IOVAs also > have > to fit into unsigned long in the general IOMMU API, as "addr" is > here, > then this is still just as broken for 32-bit LPAE as the existing > code is. > > Thanks, > Robin. > Hi Robin, According to Path#1's suggestion, next version will keep ttbr to encoded 32 bits, then will don't need to modify it. Thanks, Yunfei. > > ((lower_32_bits(_addr) & GENMASK(31, 12)) | > > upper_32_bits(_addr));\ > > }) > > > > @@ -381,8 +381,8 @@ static void > > mtk_iommu_tlb_flush_range_sync(unsigned long iova, size_t size, > > writel_relaxed(F_INVLD_EN1 | F_INVLD_EN0, > > base + data->plat_data->inv_sel_reg); > > > > - writel_relaxed(MTK_IOMMU_TLB_ADDR(iova), base + > > REG_MMU_INVLD_START_A); > > - writel_relaxed(MTK_IOMMU_TLB_ADDR(iova + size - 1), > > + writel_relaxed(MTK_IOMMU_ADDR(iova), base + > > REG_MMU_INVLD_START_A); > > + writel_relaxed(MTK_IOMMU_ADDR(iova + size - 1), > > base + REG_MMU_INVLD_END_A); > > writel_relaxed(F_MMU_INV_RANGE, base + > > REG_MMU_INVALIDATE); > > ^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH v9 3/3] iommu/mediatek: Allow page table PA up to 35bit 2022-06-15 16:12 [PATCH v9 0/3] iommu/mediatek: TTBR up to 35bit support yf.wang 2022-06-15 16:12 ` [PATCH v9 1/3] iommu/io-pgtable-arm-v7s: Add a quirk to allow pgtable PA up to 35bit yf.wang 2022-06-15 16:12 ` [PATCH v9 2/3] iommu/mediatek: Rename MTK_IOMMU_TLB_ADDR to MTK_IOMMU_ADDR yf.wang @ 2022-06-15 16:12 ` yf.wang 2022-06-15 17:25 ` Robin Murphy 2022-06-16 4:54 ` kernel test robot 2 siblings, 2 replies; 11+ messages in thread From: yf.wang @ 2022-06-15 16:12 UTC (permalink / raw) To: Yong Wu, Joerg Roedel, Will Deacon, Matthias Brugger, open list:MEDIATEK IOMMU DRIVER, moderated list:MEDIATEK IOMMU DRIVER, moderated list:ARM/Mediatek SoC support, open list Cc: wsd_upstream, Libo Kang, Yong Wu, Miles Chen, Yunfei Wang, Ning Li From: Yunfei Wang <yf.wang@mediatek.com> Single memory zone feature will remove ZONE_DMA32 and ZONE_DMA. So add the quirk IO_PGTABLE_QUIRK_ARM_MTK_TTBR_EXT to let level 1 and level 2 pgtable support at most 35bit PA. Signed-off-by: Ning Li <ning.li@mediatek.com> Signed-off-by: Yunfei Wang <yf.wang@mediatek.com> --- drivers/iommu/mtk_iommu.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c index 3d62399e8865..4dbc33758711 100644 --- a/drivers/iommu/mtk_iommu.c +++ b/drivers/iommu/mtk_iommu.c @@ -138,6 +138,7 @@ /* PM and clock always on. e.g. infra iommu */ #define PM_CLK_AO BIT(15) #define IFA_IOMMU_PCIE_SUPPORT BIT(16) +#define PGTABLE_PA_35_EN BIT(17) #define MTK_IOMMU_HAS_FLAG_MASK(pdata, _x, mask) \ ((((pdata)->flags) & (mask)) == (_x)) @@ -240,6 +241,7 @@ struct mtk_iommu_data { struct mtk_iommu_domain { struct io_pgtable_cfg cfg; struct io_pgtable_ops *iop; + u32 ttbr; struct mtk_iommu_bank_data *bank; struct iommu_domain domain; @@ -596,6 +598,9 @@ static int mtk_iommu_domain_finalise(struct mtk_iommu_domain *dom, .iommu_dev = data->dev, }; + if (MTK_IOMMU_HAS_FLAG(data->plat_data, PGTABLE_PA_35_EN)) + dom->cfg.quirks |= IO_PGTABLE_QUIRK_ARM_MTK_TTBR_EXT; + if (MTK_IOMMU_HAS_FLAG(data->plat_data, HAS_4GB_MODE)) dom->cfg.oas = data->enable_4GB ? 33 : 32; else @@ -684,8 +689,8 @@ static int mtk_iommu_attach_device(struct iommu_domain *domain, goto err_unlock; } bank->m4u_dom = dom; - writel(dom->cfg.arm_v7s_cfg.ttbr & MMU_PT_ADDR_MASK, - bank->base + REG_MMU_PT_BASE_ADDR); + bank->m4u_dom->ttbr = MTK_IOMMU_ADDR(dom->cfg.arm_v7s_cfg.ttbr); + writel(bank->m4u_dom->ttbr, data->base + REG_MMU_PT_BASE_ADDR); pm_runtime_put(m4udev); } @@ -1366,8 +1371,7 @@ static int __maybe_unused mtk_iommu_runtime_resume(struct device *dev) writel_relaxed(reg->int_control[i], base + REG_MMU_INT_CONTROL0); writel_relaxed(reg->int_main_control[i], base + REG_MMU_INT_MAIN_CONTROL); writel_relaxed(reg->ivrp_paddr[i], base + REG_MMU_IVRP_PADDR); - writel(m4u_dom->cfg.arm_v7s_cfg.ttbr & MMU_PT_ADDR_MASK, - base + REG_MMU_PT_BASE_ADDR); + writel(m4u_dom->ttbr, base + REG_MMU_PT_BASE_ADDR); } while (++i < data->plat_data->banks_num); /* @@ -1401,7 +1405,7 @@ static const struct mtk_iommu_plat_data mt2712_data = { static const struct mtk_iommu_plat_data mt6779_data = { .m4u_plat = M4U_MT6779, .flags = HAS_SUB_COMM_2BITS | OUT_ORDER_WR_EN | WR_THROT_EN | - MTK_IOMMU_TYPE_MM, + MTK_IOMMU_TYPE_MM | PGTABLE_PA_35_EN, .inv_sel_reg = REG_MMU_INV_SEL_GEN2, .banks_num = 1, .banks_enable = {true}, -- 2.18.0 ^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH v9 3/3] iommu/mediatek: Allow page table PA up to 35bit 2022-06-15 16:12 ` [PATCH v9 3/3] iommu/mediatek: Allow page table PA up to 35bit yf.wang @ 2022-06-15 17:25 ` Robin Murphy 2022-06-16 7:52 ` yf.wang 2022-06-16 4:54 ` kernel test robot 1 sibling, 1 reply; 11+ messages in thread From: Robin Murphy @ 2022-06-15 17:25 UTC (permalink / raw) To: yf.wang, Yong Wu, Joerg Roedel, Will Deacon, Matthias Brugger, open list:MEDIATEK IOMMU DRIVER, moderated list:MEDIATEK IOMMU DRIVER, moderated list:ARM/Mediatek SoC support, open list Cc: wsd_upstream, Libo Kang, Miles Chen, Ning Li On 2022-06-15 17:12, yf.wang--- via iommu wrote: > From: Yunfei Wang <yf.wang@mediatek.com> > > Single memory zone feature will remove ZONE_DMA32 and ZONE_DMA. So add > the quirk IO_PGTABLE_QUIRK_ARM_MTK_TTBR_EXT to let level 1 and level 2 > pgtable support at most 35bit PA. I'm not sure how this works in practice, given that you don't seem to be setting the IOMMU's own DMA masks to more than 32 bits, so the DMA mapping in io-pgtable is going to fail if you ever do actually allocate a pagetable page above 4GB :/ > Signed-off-by: Ning Li <ning.li@mediatek.com> > Signed-off-by: Yunfei Wang <yf.wang@mediatek.com> > --- > drivers/iommu/mtk_iommu.c | 14 +++++++++----- > 1 file changed, 9 insertions(+), 5 deletions(-) > > diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c > index 3d62399e8865..4dbc33758711 100644 > --- a/drivers/iommu/mtk_iommu.c > +++ b/drivers/iommu/mtk_iommu.c > @@ -138,6 +138,7 @@ > /* PM and clock always on. e.g. infra iommu */ > #define PM_CLK_AO BIT(15) > #define IFA_IOMMU_PCIE_SUPPORT BIT(16) > +#define PGTABLE_PA_35_EN BIT(17) > > #define MTK_IOMMU_HAS_FLAG_MASK(pdata, _x, mask) \ > ((((pdata)->flags) & (mask)) == (_x)) > @@ -240,6 +241,7 @@ struct mtk_iommu_data { > struct mtk_iommu_domain { > struct io_pgtable_cfg cfg; > struct io_pgtable_ops *iop; > + u32 ttbr; > > struct mtk_iommu_bank_data *bank; > struct iommu_domain domain; > @@ -596,6 +598,9 @@ static int mtk_iommu_domain_finalise(struct mtk_iommu_domain *dom, > .iommu_dev = data->dev, > }; > > + if (MTK_IOMMU_HAS_FLAG(data->plat_data, PGTABLE_PA_35_EN)) > + dom->cfg.quirks |= IO_PGTABLE_QUIRK_ARM_MTK_TTBR_EXT; > + > if (MTK_IOMMU_HAS_FLAG(data->plat_data, HAS_4GB_MODE)) > dom->cfg.oas = data->enable_4GB ? 33 : 32; > else > @@ -684,8 +689,8 @@ static int mtk_iommu_attach_device(struct iommu_domain *domain, > goto err_unlock; > } > bank->m4u_dom = dom; > - writel(dom->cfg.arm_v7s_cfg.ttbr & MMU_PT_ADDR_MASK, > - bank->base + REG_MMU_PT_BASE_ADDR); > + bank->m4u_dom->ttbr = MTK_IOMMU_ADDR(dom->cfg.arm_v7s_cfg.ttbr); > + writel(bank->m4u_dom->ttbr, data->base + REG_MMU_PT_BASE_ADDR); To add to my comment on patch #1, having to make this change here further indicates that you're using it the wrong way. Thanks, Robin. > > pm_runtime_put(m4udev); > } > @@ -1366,8 +1371,7 @@ static int __maybe_unused mtk_iommu_runtime_resume(struct device *dev) > writel_relaxed(reg->int_control[i], base + REG_MMU_INT_CONTROL0); > writel_relaxed(reg->int_main_control[i], base + REG_MMU_INT_MAIN_CONTROL); > writel_relaxed(reg->ivrp_paddr[i], base + REG_MMU_IVRP_PADDR); > - writel(m4u_dom->cfg.arm_v7s_cfg.ttbr & MMU_PT_ADDR_MASK, > - base + REG_MMU_PT_BASE_ADDR); > + writel(m4u_dom->ttbr, base + REG_MMU_PT_BASE_ADDR); > } while (++i < data->plat_data->banks_num); > > /* > @@ -1401,7 +1405,7 @@ static const struct mtk_iommu_plat_data mt2712_data = { > static const struct mtk_iommu_plat_data mt6779_data = { > .m4u_plat = M4U_MT6779, > .flags = HAS_SUB_COMM_2BITS | OUT_ORDER_WR_EN | WR_THROT_EN | > - MTK_IOMMU_TYPE_MM, > + MTK_IOMMU_TYPE_MM | PGTABLE_PA_35_EN, > .inv_sel_reg = REG_MMU_INV_SEL_GEN2, > .banks_num = 1, > .banks_enable = {true}, ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v9 3/3] iommu/mediatek: Allow page table PA up to 35bit 2022-06-15 17:25 ` Robin Murphy @ 2022-06-16 7:52 ` yf.wang 0 siblings, 0 replies; 11+ messages in thread From: yf.wang @ 2022-06-16 7:52 UTC (permalink / raw) To: robin.murphy Cc: Libo.Kang, iommu, joro, linux-arm-kernel, linux-kernel, linux-mediatek, matthias.bgg, miles.chen, ning.li, will, wsd_upstream, yf.wang, yong.wu On Wed, 2022-06-15 at 18:25 +0100, Robin Murphy wrote: > On 2022-06-15 17:12, yf.wang--- via iommu wrote: > > From: Yunfei Wang <yf.wang@mediatek.com> > > > > Single memory zone feature will remove ZONE_DMA32 and ZONE_DMA. So > > add > > the quirk IO_PGTABLE_QUIRK_ARM_MTK_TTBR_EXT to let level 1 and > > level 2 > > pgtable support at most 35bit PA. > > I'm not sure how this works in practice, given that you don't seem to > be > setting the IOMMU's own DMA masks to more than 32 bits, so the DMA > mapping in io-pgtable is going to fail if you ever do actually > allocate > a pagetable page above 4GB :/ > Hi Robin, About DMA masks, the master device has set dma mask, when iommu do dma map, it will check the dam_mask of the master dev to determine which range the address of the iova alloc is in. Add the quirk ARM_MTK_TTBR_EXT to let pgtable support larger phys memory. Do actually test work fine, example: pgtable phys address:0x12054006a, encoded to 32 bits ttbr:0x20540001 > > Signed-off-by: Ning Li <ning.li@mediatek.com> > > Signed-off-by: Yunfei Wang <yf.wang@mediatek.com> > > --- > > drivers/iommu/mtk_iommu.c | 14 +++++++++----- > > 1 file changed, 9 insertions(+), 5 deletions(-) > > > > diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c > > index 3d62399e8865..4dbc33758711 100644 > > --- a/drivers/iommu/mtk_iommu.c > > +++ b/drivers/iommu/mtk_iommu.c > > @@ -138,6 +138,7 @@ > > /* PM and clock always on. e.g. infra iommu */ > > #define PM_CLK_AO BIT(15) > > #define IFA_IOMMU_PCIE_SUPPORT BIT(16) > > +#define PGTABLE_PA_35_EN BIT(17) > > > > #define MTK_IOMMU_HAS_FLAG_MASK(pdata, _x, mask) \ > > ((((pdata)->flags) & (mask)) == (_x)) > > @@ -240,6 +241,7 @@ struct mtk_iommu_data { > > struct mtk_iommu_domain { > > struct io_pgtable_cfg cfg; > > struct io_pgtable_ops *iop; > > + u32 ttbr; > > > > struct mtk_iommu_bank_data *bank; > > struct iommu_domain domain; > > @@ -596,6 +598,9 @@ static int mtk_iommu_domain_finalise(struct > > mtk_iommu_domain *dom, > > .iommu_dev = data->dev, > > }; > > > > + if (MTK_IOMMU_HAS_FLAG(data->plat_data, PGTABLE_PA_35_EN)) > > + dom->cfg.quirks |= IO_PGTABLE_QUIRK_ARM_MTK_TTBR_EXT; > > + > > if (MTK_IOMMU_HAS_FLAG(data->plat_data, HAS_4GB_MODE)) > > dom->cfg.oas = data->enable_4GB ? 33 : 32; > > else > > @@ -684,8 +689,8 @@ static int mtk_iommu_attach_device(struct > > iommu_domain *domain, > > goto err_unlock; > > } > > bank->m4u_dom = dom; > > - writel(dom->cfg.arm_v7s_cfg.ttbr & MMU_PT_ADDR_MASK, > > - bank->base + REG_MMU_PT_BASE_ADDR); > > + bank->m4u_dom->ttbr = MTK_IOMMU_ADDR(dom- > > >cfg.arm_v7s_cfg.ttbr); > > + writel(bank->m4u_dom->ttbr, data->base + > > REG_MMU_PT_BASE_ADDR); > > To add to my comment on patch #1, having to make this change here > further indicates that you're using it the wrong way. > > Thanks, > Robin. > Hi Robin, According to your Path#1's suggestion, next version will keep ttbr to encoded 32 bits, then will don't need to modify it. Thanks, Yunfei. ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v9 3/3] iommu/mediatek: Allow page table PA up to 35bit 2022-06-15 16:12 ` [PATCH v9 3/3] iommu/mediatek: Allow page table PA up to 35bit yf.wang 2022-06-15 17:25 ` Robin Murphy @ 2022-06-16 4:54 ` kernel test robot 1 sibling, 0 replies; 11+ messages in thread From: kernel test robot @ 2022-06-16 4:54 UTC (permalink / raw) To: yf.wang, Yong Wu, Joerg Roedel, Will Deacon, Matthias Brugger, open list:MEDIATEK IOMMU DRIVER, moderated list:MEDIATEK IOMMU DRIVER, moderated list:ARM/Mediatek SoC support, open list Cc: kbuild-all, wsd_upstream, Libo Kang, Miles Chen, Yunfei Wang, Ning Li Hi, Thank you for the patch! Yet something to improve: [auto build test ERROR on joro-iommu/next] [also build test ERROR on linus/master v5.19-rc2 next-20220615] [cannot apply to arm-perf/for-next/perf] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch] url: https://github.com/intel-lab-lkp/linux/commits/yf-wang-mediatek-com/iommu-io-pgtable-arm-v7s-Add-a-quirk-to-allow-pgtable-PA-up-to-35bit/20220616-011227 base: https://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu.git next config: arc-allyesconfig (https://download.01.org/0day-ci/archive/20220616/202206161233.WDjdWJGb-lkp@intel.com/config) compiler: arceb-elf-gcc (GCC) 11.3.0 reproduce (this is a W=1 build): wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # https://github.com/intel-lab-lkp/linux/commit/0032fcce9c1ab50caec1ef5dd4089a8a61fcf15c git remote add linux-review https://github.com/intel-lab-lkp/linux git fetch --no-tags linux-review yf-wang-mediatek-com/iommu-io-pgtable-arm-v7s-Add-a-quirk-to-allow-pgtable-PA-up-to-35bit/20220616-011227 git checkout 0032fcce9c1ab50caec1ef5dd4089a8a61fcf15c # save the config file mkdir build_dir && cp config build_dir/.config COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.3.0 make.cross W=1 O=build_dir ARCH=arc SHELL=/bin/bash If you fix the issue, kindly add following tag where applicable Reported-by: kernel test robot <lkp@intel.com> All errors (new ones prefixed by >>): In file included from include/linux/scatterlist.h:9, from include/linux/dma-mapping.h:10, from include/linux/dma-direct.h:9, from drivers/iommu/mtk_iommu.c:11: drivers/iommu/mtk_iommu.c: In function 'mtk_iommu_attach_device': >> drivers/iommu/mtk_iommu.c:693:49: error: 'struct mtk_iommu_data' has no member named 'base' 693 | writel(bank->m4u_dom->ttbr, data->base + REG_MMU_PT_BASE_ADDR); | ^~ arch/arc/include/asm/io.h:231:75: note: in definition of macro 'writel_relaxed' 231 | #define writel_relaxed(v,c) __raw_writel((__force u32) cpu_to_le32(v),c) | ^ drivers/iommu/mtk_iommu.c:693:17: note: in expansion of macro 'writel' 693 | writel(bank->m4u_dom->ttbr, data->base + REG_MMU_PT_BASE_ADDR); | ^~~~~~ vim +693 drivers/iommu/mtk_iommu.c 646 647 static int mtk_iommu_attach_device(struct iommu_domain *domain, 648 struct device *dev) 649 { 650 struct mtk_iommu_data *data = dev_iommu_priv_get(dev), *frstdata; 651 struct mtk_iommu_domain *dom = to_mtk_domain(domain); 652 struct list_head *hw_list = data->hw_list; 653 struct device *m4udev = data->dev; 654 struct mtk_iommu_bank_data *bank; 655 unsigned int bankid; 656 int ret, region_id; 657 658 region_id = mtk_iommu_get_iova_region_id(dev, data->plat_data); 659 if (region_id < 0) 660 return region_id; 661 662 bankid = mtk_iommu_get_bank_id(dev, data->plat_data); 663 mutex_lock(&dom->mutex); 664 if (!dom->bank) { 665 /* Data is in the frstdata in sharing pgtable case. */ 666 frstdata = mtk_iommu_get_frst_data(hw_list); 667 668 ret = mtk_iommu_domain_finalise(dom, frstdata, region_id); 669 if (ret) { 670 mutex_unlock(&dom->mutex); 671 return -ENODEV; 672 } 673 dom->bank = &data->bank[bankid]; 674 } 675 mutex_unlock(&dom->mutex); 676 677 mutex_lock(&data->mutex); 678 bank = &data->bank[bankid]; 679 if (!bank->m4u_dom) { /* Initialize the M4U HW for each a BANK */ 680 ret = pm_runtime_resume_and_get(m4udev); 681 if (ret < 0) { 682 dev_err(m4udev, "pm get fail(%d) in attach.\n", ret); 683 goto err_unlock; 684 } 685 686 ret = mtk_iommu_hw_init(data, bankid); 687 if (ret) { 688 pm_runtime_put(m4udev); 689 goto err_unlock; 690 } 691 bank->m4u_dom = dom; 692 bank->m4u_dom->ttbr = MTK_IOMMU_ADDR(dom->cfg.arm_v7s_cfg.ttbr); > 693 writel(bank->m4u_dom->ttbr, data->base + REG_MMU_PT_BASE_ADDR); 694 695 pm_runtime_put(m4udev); 696 } 697 mutex_unlock(&data->mutex); 698 699 return mtk_iommu_config(data, dev, true, region_id); 700 701 err_unlock: 702 mutex_unlock(&data->mutex); 703 return ret; 704 } 705 -- 0-DAY CI Kernel Test Service https://01.org/lkp ^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2022-06-16 8:10 UTC | newest] Thread overview: 11+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2022-06-15 16:12 [PATCH v9 0/3] iommu/mediatek: TTBR up to 35bit support yf.wang 2022-06-15 16:12 ` [PATCH v9 1/3] iommu/io-pgtable-arm-v7s: Add a quirk to allow pgtable PA up to 35bit yf.wang 2022-06-15 17:03 ` Robin Murphy 2022-06-16 6:26 ` yf.wang 2022-06-15 16:12 ` [PATCH v9 2/3] iommu/mediatek: Rename MTK_IOMMU_TLB_ADDR to MTK_IOMMU_ADDR yf.wang 2022-06-15 17:14 ` Robin Murphy 2022-06-16 6:40 ` yf.wang 2022-06-15 16:12 ` [PATCH v9 3/3] iommu/mediatek: Allow page table PA up to 35bit yf.wang 2022-06-15 17:25 ` Robin Murphy 2022-06-16 7:52 ` yf.wang 2022-06-16 4:54 ` kernel test robot
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).