Re: [PATCH v7 4/5] iommu/mediatek: Add mt8173 IOMMU driver
On Fri, 2015-12-18 at 17:44 +, Robin Murphy wrote: > On 18/12/15 08:09, Yong Wu wrote: > > This patch adds support for mediatek m4u (MultiMedia Memory Management > > Unit). > > > > Signed-off-by: Yong Wu > > --- > > drivers/iommu/Kconfig | 14 + > > drivers/iommu/Makefile| 1 + > > drivers/iommu/mtk_iommu.c | 734 > > ++ > > 3 files changed, 749 insertions(+) > > create mode 100644 drivers/iommu/mtk_iommu.c > > > > > diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c > > new file mode 100644 > > index 000..d000d31 > > --- /dev/null > > +++ b/drivers/iommu/mtk_iommu.c > > [...] > > > +#define REG_MMU_CTRL_REG 0x110 > > +#define F_MMU_PREFETCH_RT_REPLACE_MOD BIT(4) > > +#define F_MMU_TF_PROTECT_SEL(prot) (((prot) & 0x3) << 5) > > +#define F_COHERENCE_EN BIT(8) > > [...] > > > +static int mtk_iommu_hw_init(const struct mtk_iommu_data *data) > > +{ > > + u32 regval; > > + int ret; > > + > > + ret = clk_prepare_enable(data->bclk); > > + if (ret) { > > + dev_err(data->dev, "Failed to enable iommu bclk(%d)\n", ret); > > + return ret; > > + } > > + > > + regval = F_MMU_PREFETCH_RT_REPLACE_MOD | > > + F_MMU_TF_PROTECT_SEL(2) | > > + F_COHERENCE_EN; > > I meant to ask this last time - does setting F_COHERENCE_EN here imply > that the M4U is capable of cache-coherent page table walks, or something > else? If it's the former, and assuming the MT8173 is actually wired up > to support that, then you should add a dma-coherent property to its DT > node in patch 5 (which will also save you all the cache flushes on page > table updates). No. F_COHERENCE_EN is not for m4u's cache-coherent page table walking. More about it: There are two iommu cells in the HW. one is perisys-iommu, the other is mm-iommu. The perisys-iommu currently is not contained in this upstream version. it will support this F_COHERENCE_EN bit which will enable coherence access for the master port if the sharable(S) bit is set in the pagetable descriptor. And in the mm-iommu, the iommu HW will work regardless of this bit. So I will delete this bit for readable as this is m4u(mm-iommu) in next time. > > > + writel_relaxed(regval, data->base + REG_MMU_CTRL_REG); > > + > > + regval = F_L2_MULIT_HIT_EN | > > + F_TABLE_WALK_FAULT_INT_EN | > > + F_PREETCH_FIFO_OVERFLOW_INT_EN | > > + F_MISS_FIFO_OVERFLOW_INT_EN | > > + F_PREFETCH_FIFO_ERR_INT_EN | > > + F_MISS_FIFO_ERR_INT_EN; > > + writel_relaxed(regval, data->base + REG_MMU_INT_CONTROL0); > > + > > + regval = F_INT_TRANSLATION_FAULT | > > + F_INT_MAIN_MULTI_HIT_FAULT | > > + F_INT_INVALID_PA_FAULT | > > + F_INT_ENTRY_REPLACEMENT_FAULT | > > + F_INT_TLB_MISS_FAULT | > > + F_INT_MISS_TRANSATION_FIFO_FAULT | > > + F_INT_PRETETCH_TRANSATION_FIFO_FAULT; > > + writel_relaxed(regval, data->base + REG_MMU_INT_MAIN_CONTROL); > > + > > + regval = F_MMU_IVRP_PA_SET(data->protect_base); > > + writel_relaxed(regval, data->base + REG_MMU_IVRP_PADDR); > > + > > + writel_relaxed(0, data->base + REG_MMU_DCM_DIS); > > + writel_relaxed(0, data->base + REG_MMU_STANDARD_AXI_MODE); > > + > > + if (devm_request_irq(data->dev, data->irq, mtk_iommu_isr, 0, > > +dev_name(data->dev), (void *)data)) { > > + writel_relaxed(0, data->base + REG_MMU_PT_BASE_ADDR); > > + clk_disable_unprepare(data->bclk); > > + dev_err(data->dev, "Failed @ IRQ-%d Request\n", data->irq); > > + return -ENODEV; > > + } > > + > > + return 0; > > +} > > Otherwise, I've not had the chance to go through this thoroughly but at > a glance it seems in pretty good shape now - nothing immediately jumps > out as looking wrong or worth making a fuss over. > > Thanks, > Robin. -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH v7 4/5] iommu/mediatek: Add mt8173 IOMMU driver
On Fri, 2015-12-18 at 17:44 +, Robin Murphy wrote: > On 18/12/15 08:09, Yong Wu wrote: > > This patch adds support for mediatek m4u (MultiMedia Memory Management > > Unit). > > > > Signed-off-by: Yong Wu> > --- > > drivers/iommu/Kconfig | 14 + > > drivers/iommu/Makefile| 1 + > > drivers/iommu/mtk_iommu.c | 734 > > ++ > > 3 files changed, 749 insertions(+) > > create mode 100644 drivers/iommu/mtk_iommu.c > > > > > diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c > > new file mode 100644 > > index 000..d000d31 > > --- /dev/null > > +++ b/drivers/iommu/mtk_iommu.c > > [...] > > > +#define REG_MMU_CTRL_REG 0x110 > > +#define F_MMU_PREFETCH_RT_REPLACE_MOD BIT(4) > > +#define F_MMU_TF_PROTECT_SEL(prot) (((prot) & 0x3) << 5) > > +#define F_COHERENCE_EN BIT(8) > > [...] > > > +static int mtk_iommu_hw_init(const struct mtk_iommu_data *data) > > +{ > > + u32 regval; > > + int ret; > > + > > + ret = clk_prepare_enable(data->bclk); > > + if (ret) { > > + dev_err(data->dev, "Failed to enable iommu bclk(%d)\n", ret); > > + return ret; > > + } > > + > > + regval = F_MMU_PREFETCH_RT_REPLACE_MOD | > > + F_MMU_TF_PROTECT_SEL(2) | > > + F_COHERENCE_EN; > > I meant to ask this last time - does setting F_COHERENCE_EN here imply > that the M4U is capable of cache-coherent page table walks, or something > else? If it's the former, and assuming the MT8173 is actually wired up > to support that, then you should add a dma-coherent property to its DT > node in patch 5 (which will also save you all the cache flushes on page > table updates). No. F_COHERENCE_EN is not for m4u's cache-coherent page table walking. More about it: There are two iommu cells in the HW. one is perisys-iommu, the other is mm-iommu. The perisys-iommu currently is not contained in this upstream version. it will support this F_COHERENCE_EN bit which will enable coherence access for the master port if the sharable(S) bit is set in the pagetable descriptor. And in the mm-iommu, the iommu HW will work regardless of this bit. So I will delete this bit for readable as this is m4u(mm-iommu) in next time. > > > + writel_relaxed(regval, data->base + REG_MMU_CTRL_REG); > > + > > + regval = F_L2_MULIT_HIT_EN | > > + F_TABLE_WALK_FAULT_INT_EN | > > + F_PREETCH_FIFO_OVERFLOW_INT_EN | > > + F_MISS_FIFO_OVERFLOW_INT_EN | > > + F_PREFETCH_FIFO_ERR_INT_EN | > > + F_MISS_FIFO_ERR_INT_EN; > > + writel_relaxed(regval, data->base + REG_MMU_INT_CONTROL0); > > + > > + regval = F_INT_TRANSLATION_FAULT | > > + F_INT_MAIN_MULTI_HIT_FAULT | > > + F_INT_INVALID_PA_FAULT | > > + F_INT_ENTRY_REPLACEMENT_FAULT | > > + F_INT_TLB_MISS_FAULT | > > + F_INT_MISS_TRANSATION_FIFO_FAULT | > > + F_INT_PRETETCH_TRANSATION_FIFO_FAULT; > > + writel_relaxed(regval, data->base + REG_MMU_INT_MAIN_CONTROL); > > + > > + regval = F_MMU_IVRP_PA_SET(data->protect_base); > > + writel_relaxed(regval, data->base + REG_MMU_IVRP_PADDR); > > + > > + writel_relaxed(0, data->base + REG_MMU_DCM_DIS); > > + writel_relaxed(0, data->base + REG_MMU_STANDARD_AXI_MODE); > > + > > + if (devm_request_irq(data->dev, data->irq, mtk_iommu_isr, 0, > > +dev_name(data->dev), (void *)data)) { > > + writel_relaxed(0, data->base + REG_MMU_PT_BASE_ADDR); > > + clk_disable_unprepare(data->bclk); > > + dev_err(data->dev, "Failed @ IRQ-%d Request\n", data->irq); > > + return -ENODEV; > > + } > > + > > + return 0; > > +} > > Otherwise, I've not had the chance to go through this thoroughly but at > a glance it seems in pretty good shape now - nothing immediately jumps > out as looking wrong or worth making a fuss over. > > Thanks, > Robin. -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH v7 4/5] iommu/mediatek: Add mt8173 IOMMU driver
On 18/12/15 08:09, Yong Wu wrote: This patch adds support for mediatek m4u (MultiMedia Memory Management Unit). Signed-off-by: Yong Wu --- drivers/iommu/Kconfig | 14 + drivers/iommu/Makefile| 1 + drivers/iommu/mtk_iommu.c | 734 ++ 3 files changed, 749 insertions(+) create mode 100644 drivers/iommu/mtk_iommu.c diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c new file mode 100644 index 000..d000d31 --- /dev/null +++ b/drivers/iommu/mtk_iommu.c [...] +#define REG_MMU_CTRL_REG 0x110 +#define F_MMU_PREFETCH_RT_REPLACE_MOD BIT(4) +#define F_MMU_TF_PROTECT_SEL(prot) (((prot) & 0x3) << 5) +#define F_COHERENCE_EN BIT(8) [...] +static int mtk_iommu_hw_init(const struct mtk_iommu_data *data) +{ + u32 regval; + int ret; + + ret = clk_prepare_enable(data->bclk); + if (ret) { + dev_err(data->dev, "Failed to enable iommu bclk(%d)\n", ret); + return ret; + } + + regval = F_MMU_PREFETCH_RT_REPLACE_MOD | + F_MMU_TF_PROTECT_SEL(2) | + F_COHERENCE_EN; I meant to ask this last time - does setting F_COHERENCE_EN here imply that the M4U is capable of cache-coherent page table walks, or something else? If it's the former, and assuming the MT8173 is actually wired up to support that, then you should add a dma-coherent property to its DT node in patch 5 (which will also save you all the cache flushes on page table updates). + writel_relaxed(regval, data->base + REG_MMU_CTRL_REG); + + regval = F_L2_MULIT_HIT_EN | + F_TABLE_WALK_FAULT_INT_EN | + F_PREETCH_FIFO_OVERFLOW_INT_EN | + F_MISS_FIFO_OVERFLOW_INT_EN | + F_PREFETCH_FIFO_ERR_INT_EN | + F_MISS_FIFO_ERR_INT_EN; + writel_relaxed(regval, data->base + REG_MMU_INT_CONTROL0); + + regval = F_INT_TRANSLATION_FAULT | + F_INT_MAIN_MULTI_HIT_FAULT | + F_INT_INVALID_PA_FAULT | + F_INT_ENTRY_REPLACEMENT_FAULT | + F_INT_TLB_MISS_FAULT | + F_INT_MISS_TRANSATION_FIFO_FAULT | + F_INT_PRETETCH_TRANSATION_FIFO_FAULT; + writel_relaxed(regval, data->base + REG_MMU_INT_MAIN_CONTROL); + + regval = F_MMU_IVRP_PA_SET(data->protect_base); + writel_relaxed(regval, data->base + REG_MMU_IVRP_PADDR); + + writel_relaxed(0, data->base + REG_MMU_DCM_DIS); + writel_relaxed(0, data->base + REG_MMU_STANDARD_AXI_MODE); + + if (devm_request_irq(data->dev, data->irq, mtk_iommu_isr, 0, +dev_name(data->dev), (void *)data)) { + writel_relaxed(0, data->base + REG_MMU_PT_BASE_ADDR); + clk_disable_unprepare(data->bclk); + dev_err(data->dev, "Failed @ IRQ-%d Request\n", data->irq); + return -ENODEV; + } + + return 0; +} Otherwise, I've not had the chance to go through this thoroughly but at a glance it seems in pretty good shape now - nothing immediately jumps out as looking wrong or worth making a fuss over. Thanks, Robin. -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH v7 4/5] iommu/mediatek: Add mt8173 IOMMU driver
Hi Yong, [auto build test ERROR on tegra/for-next] [also build test ERROR on v4.4-rc5] [cannot apply to iommu/next next-20151217] url: https://github.com/0day-ci/linux/commits/Yong-Wu/MT8173-IOMMU-SUPPORT/20151218-161550 base: https://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux for-next config: parisc-allyesconfig (attached as .config) reproduce: wget https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # save the attached .config to linux build tree make.cross ARCH=parisc All error/warnings (new ones prefixed by >>): drivers/iommu/dma-iommu.c: In function '__iommu_dma_alloc_pages': drivers/iommu/dma-iommu.c:198:3: error: implicit declaration of function 'vzalloc' [-Werror=implicit-function-declaration] pages = vzalloc(array_size); ^ drivers/iommu/dma-iommu.c:198:9: warning: assignment makes pointer from integer without a cast pages = vzalloc(array_size); ^ drivers/iommu/dma-iommu.c: In function 'iommu_dma_free': >> drivers/iommu/dma-iommu.c:256:12: error: 'DMA_ERROR_CODE' undeclared (first >> use in this function) *handle = DMA_ERROR_CODE; ^ drivers/iommu/dma-iommu.c:256:12: note: each undeclared identifier is reported only once for each function it appears in drivers/iommu/dma-iommu.c: In function 'iommu_dma_alloc': drivers/iommu/dma-iommu.c:288:12: error: 'DMA_ERROR_CODE' undeclared (first use in this function) *handle = DMA_ERROR_CODE; ^ drivers/iommu/dma-iommu.c: In function 'iommu_dma_map_page': drivers/iommu/dma-iommu.c:369:10: error: 'DMA_ERROR_CODE' undeclared (first use in this function) return DMA_ERROR_CODE; ^ drivers/iommu/dma-iommu.c: In function '__invalidate_sg': drivers/iommu/dma-iommu.c:419:28: error: 'DMA_ERROR_CODE' undeclared (first use in this function) if (sg_dma_address(s) != DMA_ERROR_CODE) ^ drivers/iommu/dma-iommu.c: In function 'iommu_dma_mapping_error': drivers/iommu/dma-iommu.c:523:21: error: 'DMA_ERROR_CODE' undeclared (first use in this function) return dma_addr == DMA_ERROR_CODE; ^ >> drivers/iommu/dma-iommu.c:524:1: warning: control reaches end of non-void >> function [-Wreturn-type] } ^ cc1: some warnings being treated as errors -- drivers/iommu/mtk_iommu.c:174:2: warning: initialization from incompatible pointer type .tlb_add_flush = mtk_iommu_tlb_add_flush_nosync, ^ drivers/iommu/mtk_iommu.c:174:2: warning: (near initialization for 'mtk_iommu_gather_ops.tlb_add_flush') drivers/iommu/mtk_iommu.c: In function 'mtk_iommu_config': >> drivers/iommu/mtk_iommu.c:223:22: error: 'struct dev_archdata' has no member >> named 'iommu' head = dev->archdata.iommu; ^ drivers/iommu/mtk_iommu.c: In function 'mtk_iommu_domain_finalise': drivers/iommu/mtk_iommu.c:247:4: error: 'IO_PGTABLE_QUIRK_NO_PERMS' undeclared (first use in this function) IO_PGTABLE_QUIRK_NO_PERMS | ^ drivers/iommu/mtk_iommu.c:247:4: note: each undeclared identifier is reported only once for each function it appears in drivers/iommu/mtk_iommu.c:248:4: error: 'IO_PGTABLE_QUIRK_TLBI_ON_MAP' undeclared (first use in this function) IO_PGTABLE_QUIRK_TLBI_ON_MAP, ^ drivers/iommu/mtk_iommu.c:256:34: error: 'ARM_V7S' undeclared (first use in this function) dom->iop = alloc_io_pgtable_ops(ARM_V7S, >cfg, data); ^ drivers/iommu/mtk_iommu.c:265:27: error: 'struct io_pgtable_cfg' has no member named 'arm_v7s_cfg' writel(data->m4u_dom->cfg.arm_v7s_cfg.ttbr[0], ^ drivers/iommu/mtk_iommu.c: In function 'mtk_iommu_attach_device': drivers/iommu/mtk_iommu.c:303:52: error: 'struct dev_archdata' has no member named 'iommu' struct mtk_iommu_client_priv *priv = dev->archdata.iommu; ^ drivers/iommu/mtk_iommu.c: In function 'mtk_iommu_detach_device': drivers/iommu/mtk_iommu.c:331:52: error: 'struct dev_archdata' has no member named 'iommu' struct mtk_iommu_client_priv *priv = dev->archdata.iommu; ^ drivers/iommu/mtk_iommu.c: In function 'mtk_iommu_add_device': drivers/iommu/mtk_iommu.c:387:20: error: 'struct dev_archdata' has no member named 'iommu' if (!dev->archdata.iommu) /* Not a iommu client device */ ^ drivers/iommu/mtk_iommu.c: In function 'mtk_iommu_remove_device': drivers/iommu/mtk_iommu.c:402:22: error: 'struct dev_archdata' has no member named 'iommu' head = dev->archdata.iommu; ^ drivers/iommu/mtk_iommu.c:411:15: error: 'struct dev_archdata' has no member named 'iommu' dev->archdata.iommu = NULL;
[PATCH v7 4/5] iommu/mediatek: Add mt8173 IOMMU driver
This patch adds support for mediatek m4u (MultiMedia Memory Management Unit). Signed-off-by: Yong Wu --- drivers/iommu/Kconfig | 14 + drivers/iommu/Makefile| 1 + drivers/iommu/mtk_iommu.c | 734 ++ 3 files changed, 749 insertions(+) create mode 100644 drivers/iommu/mtk_iommu.c diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig index b9094e9..01d7c2aa 100644 --- a/drivers/iommu/Kconfig +++ b/drivers/iommu/Kconfig @@ -393,4 +393,18 @@ config S390_IOMMU help Support for the IOMMU API for s390 PCI devices. +config MTK_IOMMU + bool "MTK IOMMU Support" + depends on ARCH_MEDIATEK || COMPILE_TEST + select IOMMU_DMA + select IOMMU_IO_PGTABLE_ARMV7S + select MEMORY + select MTK_SMI + help + Support for the M4U on certain Mediatek SOCs. M4U is MultiMedia + Memory Management Unit. This option enables remapping of DMA memory + accesses for the multimedia subsystem. + + If unsure, say N here. + endif # IOMMU_SUPPORT diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile index 68faca02..02887bc 100644 --- a/drivers/iommu/Makefile +++ b/drivers/iommu/Makefile @@ -22,6 +22,7 @@ obj-$(CONFIG_ROCKCHIP_IOMMU) += rockchip-iommu.o obj-$(CONFIG_TEGRA_IOMMU_GART) += tegra-gart.o obj-$(CONFIG_TEGRA_IOMMU_SMMU) += tegra-smmu.o obj-$(CONFIG_EXYNOS_IOMMU) += exynos-iommu.o +obj-$(CONFIG_MTK_IOMMU) += mtk_iommu.o obj-$(CONFIG_SHMOBILE_IOMMU) += shmobile-iommu.o obj-$(CONFIG_SHMOBILE_IPMMU) += shmobile-ipmmu.o obj-$(CONFIG_FSL_PAMU) += fsl_pamu.o fsl_pamu_domain.o diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c new file mode 100644 index 000..d000d31 --- /dev/null +++ b/drivers/iommu/mtk_iommu.c @@ -0,0 +1,734 @@ +/* + * Copyright (c) 2014-2015 MediaTek Inc. + * Author: Yong Wu + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "io-pgtable.h" + +#define REG_MMU_PT_BASE_ADDR 0x000 + +#define REG_MMU_INVALIDATE 0x020 +#define F_ALL_INVLD0x2 +#define F_MMU_INV_RANGE0x1 + +#define REG_MMU_INVLD_START_A 0x024 +#define REG_MMU_INVLD_END_A0x028 + +#define REG_MMU_INV_SEL0x038 +#define F_INVLD_EN0BIT(0) +#define F_INVLD_EN1BIT(1) + +#define REG_MMU_STANDARD_AXI_MODE 0x048 +#define REG_MMU_DCM_DIS0x050 + +#define REG_MMU_CTRL_REG 0x110 +#define F_MMU_PREFETCH_RT_REPLACE_MOD BIT(4) +#define F_MMU_TF_PROTECT_SEL(prot) (((prot) & 0x3) << 5) +#define F_COHERENCE_EN BIT(8) + +#define REG_MMU_IVRP_PADDR 0x114 +#define F_MMU_IVRP_PA_SET(pa) ((pa) >> 1) + +#define REG_MMU_INT_CONTROL0 0x120 +#define F_L2_MULIT_HIT_EN BIT(0) +#define F_TABLE_WALK_FAULT_INT_EN BIT(1) +#define F_PREETCH_FIFO_OVERFLOW_INT_EN BIT(2) +#define F_MISS_FIFO_OVERFLOW_INT_ENBIT(3) +#define F_PREFETCH_FIFO_ERR_INT_EN BIT(5) +#define F_MISS_FIFO_ERR_INT_EN BIT(6) +#define F_INT_CLR_BIT BIT(12) + +#define REG_MMU_INT_MAIN_CONTROL 0x124 +#define F_INT_TRANSLATION_FAULTBIT(0) +#define F_INT_MAIN_MULTI_HIT_FAULT BIT(1) +#define F_INT_INVALID_PA_FAULT BIT(2) +#define F_INT_ENTRY_REPLACEMENT_FAULT BIT(3) +#define F_INT_TLB_MISS_FAULT BIT(4) +#define F_INT_MISS_TRANSATION_FIFO_FAULT BIT(5) +#define F_INT_PRETETCH_TRANSATION_FIFO_FAULT BIT(6) + +#define REG_MMU_CPE_DONE 0x12C + +#define REG_MMU_FAULT_ST1 0x134 + +#define REG_MMU_FAULT_VA 0x13c +#define F_MMU_FAULT_VA_MSK 0xf000 +#define F_MMU_FAULT_VA_WRITE_BIT BIT(1) +#define F_MMU_FAULT_VA_LAYER_BIT BIT(0) + +#define REG_MMU_INVLD_PA 0x140 +#define REG_MMU_INT_ID 0x150 +#define F_MMU0_INT_ID_LARB_ID(a) (((a) >> 7) & 0x7) +#define F_MMU0_INT_ID_PORT_ID(a) (((a) >> 2) & 0x1f) + +#define
Re: [PATCH v7 4/5] iommu/mediatek: Add mt8173 IOMMU driver
Hi Yong, [auto build test ERROR on tegra/for-next] [also build test ERROR on v4.4-rc5] [cannot apply to iommu/next next-20151217] url: https://github.com/0day-ci/linux/commits/Yong-Wu/MT8173-IOMMU-SUPPORT/20151218-161550 base: https://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux for-next config: parisc-allyesconfig (attached as .config) reproduce: wget https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # save the attached .config to linux build tree make.cross ARCH=parisc All error/warnings (new ones prefixed by >>): drivers/iommu/dma-iommu.c: In function '__iommu_dma_alloc_pages': drivers/iommu/dma-iommu.c:198:3: error: implicit declaration of function 'vzalloc' [-Werror=implicit-function-declaration] pages = vzalloc(array_size); ^ drivers/iommu/dma-iommu.c:198:9: warning: assignment makes pointer from integer without a cast pages = vzalloc(array_size); ^ drivers/iommu/dma-iommu.c: In function 'iommu_dma_free': >> drivers/iommu/dma-iommu.c:256:12: error: 'DMA_ERROR_CODE' undeclared (first >> use in this function) *handle = DMA_ERROR_CODE; ^ drivers/iommu/dma-iommu.c:256:12: note: each undeclared identifier is reported only once for each function it appears in drivers/iommu/dma-iommu.c: In function 'iommu_dma_alloc': drivers/iommu/dma-iommu.c:288:12: error: 'DMA_ERROR_CODE' undeclared (first use in this function) *handle = DMA_ERROR_CODE; ^ drivers/iommu/dma-iommu.c: In function 'iommu_dma_map_page': drivers/iommu/dma-iommu.c:369:10: error: 'DMA_ERROR_CODE' undeclared (first use in this function) return DMA_ERROR_CODE; ^ drivers/iommu/dma-iommu.c: In function '__invalidate_sg': drivers/iommu/dma-iommu.c:419:28: error: 'DMA_ERROR_CODE' undeclared (first use in this function) if (sg_dma_address(s) != DMA_ERROR_CODE) ^ drivers/iommu/dma-iommu.c: In function 'iommu_dma_mapping_error': drivers/iommu/dma-iommu.c:523:21: error: 'DMA_ERROR_CODE' undeclared (first use in this function) return dma_addr == DMA_ERROR_CODE; ^ >> drivers/iommu/dma-iommu.c:524:1: warning: control reaches end of non-void >> function [-Wreturn-type] } ^ cc1: some warnings being treated as errors -- drivers/iommu/mtk_iommu.c:174:2: warning: initialization from incompatible pointer type .tlb_add_flush = mtk_iommu_tlb_add_flush_nosync, ^ drivers/iommu/mtk_iommu.c:174:2: warning: (near initialization for 'mtk_iommu_gather_ops.tlb_add_flush') drivers/iommu/mtk_iommu.c: In function 'mtk_iommu_config': >> drivers/iommu/mtk_iommu.c:223:22: error: 'struct dev_archdata' has no member >> named 'iommu' head = dev->archdata.iommu; ^ drivers/iommu/mtk_iommu.c: In function 'mtk_iommu_domain_finalise': drivers/iommu/mtk_iommu.c:247:4: error: 'IO_PGTABLE_QUIRK_NO_PERMS' undeclared (first use in this function) IO_PGTABLE_QUIRK_NO_PERMS | ^ drivers/iommu/mtk_iommu.c:247:4: note: each undeclared identifier is reported only once for each function it appears in drivers/iommu/mtk_iommu.c:248:4: error: 'IO_PGTABLE_QUIRK_TLBI_ON_MAP' undeclared (first use in this function) IO_PGTABLE_QUIRK_TLBI_ON_MAP, ^ drivers/iommu/mtk_iommu.c:256:34: error: 'ARM_V7S' undeclared (first use in this function) dom->iop = alloc_io_pgtable_ops(ARM_V7S, >cfg, data); ^ drivers/iommu/mtk_iommu.c:265:27: error: 'struct io_pgtable_cfg' has no member named 'arm_v7s_cfg' writel(data->m4u_dom->cfg.arm_v7s_cfg.ttbr[0], ^ drivers/iommu/mtk_iommu.c: In function 'mtk_iommu_attach_device': drivers/iommu/mtk_iommu.c:303:52: error: 'struct dev_archdata' has no member named 'iommu' struct mtk_iommu_client_priv *priv = dev->archdata.iommu; ^ drivers/iommu/mtk_iommu.c: In function 'mtk_iommu_detach_device': drivers/iommu/mtk_iommu.c:331:52: error: 'struct dev_archdata' has no member named 'iommu' struct mtk_iommu_client_priv *priv = dev->archdata.iommu; ^ drivers/iommu/mtk_iommu.c: In function 'mtk_iommu_add_device': drivers/iommu/mtk_iommu.c:387:20: error: 'struct dev_archdata' has no member named 'iommu' if (!dev->archdata.iommu) /* Not a iommu client device */ ^ drivers/iommu/mtk_iommu.c: In function 'mtk_iommu_remove_device': drivers/iommu/mtk_iommu.c:402:22: error: 'struct dev_archdata' has no member named 'iommu' head = dev->archdata.iommu; ^ drivers/iommu/mtk_iommu.c:411:15: error: 'struct dev_archdata' has no member named 'iommu' dev->archdata.iommu = NULL;
[PATCH v7 4/5] iommu/mediatek: Add mt8173 IOMMU driver
This patch adds support for mediatek m4u (MultiMedia Memory Management Unit). Signed-off-by: Yong Wu--- drivers/iommu/Kconfig | 14 + drivers/iommu/Makefile| 1 + drivers/iommu/mtk_iommu.c | 734 ++ 3 files changed, 749 insertions(+) create mode 100644 drivers/iommu/mtk_iommu.c diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig index b9094e9..01d7c2aa 100644 --- a/drivers/iommu/Kconfig +++ b/drivers/iommu/Kconfig @@ -393,4 +393,18 @@ config S390_IOMMU help Support for the IOMMU API for s390 PCI devices. +config MTK_IOMMU + bool "MTK IOMMU Support" + depends on ARCH_MEDIATEK || COMPILE_TEST + select IOMMU_DMA + select IOMMU_IO_PGTABLE_ARMV7S + select MEMORY + select MTK_SMI + help + Support for the M4U on certain Mediatek SOCs. M4U is MultiMedia + Memory Management Unit. This option enables remapping of DMA memory + accesses for the multimedia subsystem. + + If unsure, say N here. + endif # IOMMU_SUPPORT diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile index 68faca02..02887bc 100644 --- a/drivers/iommu/Makefile +++ b/drivers/iommu/Makefile @@ -22,6 +22,7 @@ obj-$(CONFIG_ROCKCHIP_IOMMU) += rockchip-iommu.o obj-$(CONFIG_TEGRA_IOMMU_GART) += tegra-gart.o obj-$(CONFIG_TEGRA_IOMMU_SMMU) += tegra-smmu.o obj-$(CONFIG_EXYNOS_IOMMU) += exynos-iommu.o +obj-$(CONFIG_MTK_IOMMU) += mtk_iommu.o obj-$(CONFIG_SHMOBILE_IOMMU) += shmobile-iommu.o obj-$(CONFIG_SHMOBILE_IPMMU) += shmobile-ipmmu.o obj-$(CONFIG_FSL_PAMU) += fsl_pamu.o fsl_pamu_domain.o diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c new file mode 100644 index 000..d000d31 --- /dev/null +++ b/drivers/iommu/mtk_iommu.c @@ -0,0 +1,734 @@ +/* + * Copyright (c) 2014-2015 MediaTek Inc. + * Author: Yong Wu + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "io-pgtable.h" + +#define REG_MMU_PT_BASE_ADDR 0x000 + +#define REG_MMU_INVALIDATE 0x020 +#define F_ALL_INVLD0x2 +#define F_MMU_INV_RANGE0x1 + +#define REG_MMU_INVLD_START_A 0x024 +#define REG_MMU_INVLD_END_A0x028 + +#define REG_MMU_INV_SEL0x038 +#define F_INVLD_EN0BIT(0) +#define F_INVLD_EN1BIT(1) + +#define REG_MMU_STANDARD_AXI_MODE 0x048 +#define REG_MMU_DCM_DIS0x050 + +#define REG_MMU_CTRL_REG 0x110 +#define F_MMU_PREFETCH_RT_REPLACE_MOD BIT(4) +#define F_MMU_TF_PROTECT_SEL(prot) (((prot) & 0x3) << 5) +#define F_COHERENCE_EN BIT(8) + +#define REG_MMU_IVRP_PADDR 0x114 +#define F_MMU_IVRP_PA_SET(pa) ((pa) >> 1) + +#define REG_MMU_INT_CONTROL0 0x120 +#define F_L2_MULIT_HIT_EN BIT(0) +#define F_TABLE_WALK_FAULT_INT_EN BIT(1) +#define F_PREETCH_FIFO_OVERFLOW_INT_EN BIT(2) +#define F_MISS_FIFO_OVERFLOW_INT_ENBIT(3) +#define F_PREFETCH_FIFO_ERR_INT_EN BIT(5) +#define F_MISS_FIFO_ERR_INT_EN BIT(6) +#define F_INT_CLR_BIT BIT(12) + +#define REG_MMU_INT_MAIN_CONTROL 0x124 +#define F_INT_TRANSLATION_FAULTBIT(0) +#define F_INT_MAIN_MULTI_HIT_FAULT BIT(1) +#define F_INT_INVALID_PA_FAULT BIT(2) +#define F_INT_ENTRY_REPLACEMENT_FAULT BIT(3) +#define F_INT_TLB_MISS_FAULT BIT(4) +#define F_INT_MISS_TRANSATION_FIFO_FAULT BIT(5) +#define F_INT_PRETETCH_TRANSATION_FIFO_FAULT BIT(6) + +#define REG_MMU_CPE_DONE 0x12C + +#define REG_MMU_FAULT_ST1 0x134 + +#define REG_MMU_FAULT_VA 0x13c +#define F_MMU_FAULT_VA_MSK 0xf000 +#define F_MMU_FAULT_VA_WRITE_BIT BIT(1) +#define F_MMU_FAULT_VA_LAYER_BIT BIT(0) + +#define REG_MMU_INVLD_PA 0x140 +#define REG_MMU_INT_ID 0x150 +#define F_MMU0_INT_ID_LARB_ID(a) (((a) >> 7) & 0x7) +#define F_MMU0_INT_ID_PORT_ID(a)
Re: [PATCH v7 4/5] iommu/mediatek: Add mt8173 IOMMU driver
On 18/12/15 08:09, Yong Wu wrote: This patch adds support for mediatek m4u (MultiMedia Memory Management Unit). Signed-off-by: Yong Wu--- drivers/iommu/Kconfig | 14 + drivers/iommu/Makefile| 1 + drivers/iommu/mtk_iommu.c | 734 ++ 3 files changed, 749 insertions(+) create mode 100644 drivers/iommu/mtk_iommu.c diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c new file mode 100644 index 000..d000d31 --- /dev/null +++ b/drivers/iommu/mtk_iommu.c [...] +#define REG_MMU_CTRL_REG 0x110 +#define F_MMU_PREFETCH_RT_REPLACE_MOD BIT(4) +#define F_MMU_TF_PROTECT_SEL(prot) (((prot) & 0x3) << 5) +#define F_COHERENCE_EN BIT(8) [...] +static int mtk_iommu_hw_init(const struct mtk_iommu_data *data) +{ + u32 regval; + int ret; + + ret = clk_prepare_enable(data->bclk); + if (ret) { + dev_err(data->dev, "Failed to enable iommu bclk(%d)\n", ret); + return ret; + } + + regval = F_MMU_PREFETCH_RT_REPLACE_MOD | + F_MMU_TF_PROTECT_SEL(2) | + F_COHERENCE_EN; I meant to ask this last time - does setting F_COHERENCE_EN here imply that the M4U is capable of cache-coherent page table walks, or something else? If it's the former, and assuming the MT8173 is actually wired up to support that, then you should add a dma-coherent property to its DT node in patch 5 (which will also save you all the cache flushes on page table updates). + writel_relaxed(regval, data->base + REG_MMU_CTRL_REG); + + regval = F_L2_MULIT_HIT_EN | + F_TABLE_WALK_FAULT_INT_EN | + F_PREETCH_FIFO_OVERFLOW_INT_EN | + F_MISS_FIFO_OVERFLOW_INT_EN | + F_PREFETCH_FIFO_ERR_INT_EN | + F_MISS_FIFO_ERR_INT_EN; + writel_relaxed(regval, data->base + REG_MMU_INT_CONTROL0); + + regval = F_INT_TRANSLATION_FAULT | + F_INT_MAIN_MULTI_HIT_FAULT | + F_INT_INVALID_PA_FAULT | + F_INT_ENTRY_REPLACEMENT_FAULT | + F_INT_TLB_MISS_FAULT | + F_INT_MISS_TRANSATION_FIFO_FAULT | + F_INT_PRETETCH_TRANSATION_FIFO_FAULT; + writel_relaxed(regval, data->base + REG_MMU_INT_MAIN_CONTROL); + + regval = F_MMU_IVRP_PA_SET(data->protect_base); + writel_relaxed(regval, data->base + REG_MMU_IVRP_PADDR); + + writel_relaxed(0, data->base + REG_MMU_DCM_DIS); + writel_relaxed(0, data->base + REG_MMU_STANDARD_AXI_MODE); + + if (devm_request_irq(data->dev, data->irq, mtk_iommu_isr, 0, +dev_name(data->dev), (void *)data)) { + writel_relaxed(0, data->base + REG_MMU_PT_BASE_ADDR); + clk_disable_unprepare(data->bclk); + dev_err(data->dev, "Failed @ IRQ-%d Request\n", data->irq); + return -ENODEV; + } + + return 0; +} Otherwise, I've not had the chance to go through this thoroughly but at a glance it seems in pretty good shape now - nothing immediately jumps out as looking wrong or worth making a fuss over. Thanks, Robin. -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/