Re: [PATCH v7 4/5] iommu/mediatek: Add mt8173 IOMMU driver

2015-12-21 Thread Yong Wu
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

2015-12-21 Thread Yong Wu
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

2015-12-18 Thread Robin Murphy

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

2015-12-18 Thread kbuild test robot
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

2015-12-18 Thread Yong Wu
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

2015-12-18 Thread kbuild test robot
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

2015-12-18 Thread Yong Wu
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

2015-12-18 Thread Robin Murphy

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/