RE: [PATCH v2 1/2] IOMMU: arm-smmu-v3: Fix broken STE.VALID check in Broadcom Vulcan

2015-12-18 Thread Prem (Premachandra) Mallappa
Hi Will, 

> 
> Is this workaround only needed for bypass STEs? If not, we have a problem
> when we install a stage-1 entry, because we'll clear the EATS bits as it 
> stands.
>

Yes, this _was_ needed only in Bypass STEs, AFAIK.
However, the h/w fixes that were committed recently has this worked out. 
I have tested and confirmed this patch is no longer necessary. We'll drop this 
series as STE.VALID is not broken anymore :).

Cheers,
/Prem
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH v7 1/5] dt-bindings: iommu: Add binding for mediatek IOMMU

2015-12-18 Thread Rob Herring
On Fri, Dec 18, 2015 at 04:09:39PM +0800, Yong Wu wrote:
> This patch add mediatek iommu dts binding document.
> 
> Signed-off-by: Yong Wu 

Acked-by: Rob Herring 
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH 3/3] iommu/dma: Avoid unlikely high-order allocations

2015-12-18 Thread Doug Anderson
Robin,

On Fri, Dec 18, 2015 at 9:01 AM, Robin Murphy  wrote:
> Doug reports that the equivalent page allocator on 32-bit ARM exhibits
> particularly pathalogical behaviour under memory pressure when
> fragmentation is high, where allocating a 4MB buffer takes tens of
> seconds and the number of calls to alloc_pages() is over 9000![1]
>
> We can drastically improve that situation without losing the other
> benefits of high-order allocations when they would succeed, by assuming
> memory pressure is relatively constant over the course of an allocation,
> and not retrying allocations at orders we know to have failed before.
> This way, the best-case behaviour remains unchanged, and in the worst
> case we should see at most a dozen or so (MAX_ORDER - 1) failed attempts
> before falling back to single pages for the remainder of the buffer.
>
> [1]:http://lists.infradead.org/pipermail/linux-arm-kernel/2015-December/394660.html
>
> Reported-by: Douglas Anderson 
> Signed-off-by: Robin Murphy 
> ---
>  drivers/iommu/dma-iommu.c | 6 --
>  1 file changed, 4 insertions(+), 2 deletions(-)

Presumably it makes sense to update this based on v2 of my patch to
the original code?  AKA: 
?
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH 2/2] iommu/arm-smmu: Tidy up 64-bit/atomic I/O accesses

2015-12-18 Thread Robin Murphy
With {read,write}q_relaxed now able to fall back to the common
nonatomic-hi-lo helper, make use of that so that we don't have to
open-code our own. In the process, also convert the other remaining
split accesses, and repurpose the custom accessor to smooth out the
couple of troublesome instances where we really want to avoid
nonatomic writes (and a 64-bit access is unnecessary in the 32-bit
context formats we would use on a 32-bit CPU).

This paves the way for getting rid of some of the assumptions currently
baked into the driver which make it really awkward to use 32-bit context
formats with SMMUv2 under a 64-bit kernel.

Signed-off-by: Robin Murphy 
---
 drivers/iommu/arm-smmu.c | 48 +++-
 1 file changed, 19 insertions(+), 29 deletions(-)

diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index 59ee4b8..bdb85b5 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -33,6 +33,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -70,16 +71,15 @@
((smmu->options & ARM_SMMU_OPT_SECURE_CFG_ACCESS)   \
? 0x400 : 0))
 
+/*
+ * Some 64-bit registers only make sense to write atomically, but in such
+ * cases all the data relevant to AArch32 formats lies within the lower word,
+ * therefore this actually makes more sense than it might first appear.
+ */
 #ifdef CONFIG_64BIT
-#define smmu_writeqwriteq_relaxed
+#define smmu_write_atomic_lq   writeq_relaxed
 #else
-#define smmu_writeq(reg64, addr)   \
-   do {\
-   u64 __val = (reg64);\
-   void __iomem *__addr = (addr);  \
-   writel_relaxed(__val >> 32, __addr + 4);\
-   writel_relaxed(__val, __addr);  \
-   } while (0)
+#define smmu_write_atomic_lq   writel_relaxed
 #endif
 
 /* Configuration registers */
@@ -202,11 +202,9 @@
 #define ARM_SMMU_CB_TTBCR  0x30
 #define ARM_SMMU_CB_S1_MAIR0   0x38
 #define ARM_SMMU_CB_S1_MAIR1   0x3c
-#define ARM_SMMU_CB_PAR_LO 0x50
-#define ARM_SMMU_CB_PAR_HI 0x54
+#define ARM_SMMU_CB_PAR0x50
 #define ARM_SMMU_CB_FSR0x58
-#define ARM_SMMU_CB_FAR_LO 0x60
-#define ARM_SMMU_CB_FAR_HI 0x64
+#define ARM_SMMU_CB_FAR0x60
 #define ARM_SMMU_CB_FSYNR0 0x68
 #define ARM_SMMU_CB_S1_TLBIVA  0x600
 #define ARM_SMMU_CB_S1_TLBIASID0x610
@@ -618,7 +616,7 @@ static void arm_smmu_tlb_inv_range_nosync(unsigned long 
iova, size_t size,
  ARM_SMMU_CB_S2_TLBIIPAS2;
iova >>= 12;
do {
-   writeq_relaxed(iova, reg);
+   smmu_write_atomic_lq(iova, reg);
iova += granule >> 12;
} while (size -= granule);
 #endif
@@ -637,7 +635,7 @@ static struct iommu_gather_ops arm_smmu_gather_ops = {
 static irqreturn_t arm_smmu_context_fault(int irq, void *dev)
 {
int flags, ret;
-   u32 fsr, far, fsynr, resume;
+   u32 fsr, fsynr, resume;
unsigned long iova;
struct iommu_domain *domain = dev;
struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
@@ -659,13 +657,7 @@ static irqreturn_t arm_smmu_context_fault(int irq, void 
*dev)
fsynr = readl_relaxed(cb_base + ARM_SMMU_CB_FSYNR0);
flags = fsynr & FSYNR0_WNR ? IOMMU_FAULT_WRITE : IOMMU_FAULT_READ;
 
-   far = readl_relaxed(cb_base + ARM_SMMU_CB_FAR_LO);
-   iova = far;
-#ifdef CONFIG_64BIT
-   far = readl_relaxed(cb_base + ARM_SMMU_CB_FAR_HI);
-   iova |= ((unsigned long)far << 32);
-#endif
-
+   iova = readq_relaxed(cb_base + ARM_SMMU_CB_FAR);
if (!report_iommu_fault(domain, smmu->dev, iova, flags)) {
ret = IRQ_HANDLED;
resume = RESUME_RETRY;
@@ -761,14 +753,14 @@ static void arm_smmu_init_context_bank(struct 
arm_smmu_domain *smmu_domain,
reg64 = pgtbl_cfg->arm_lpae_s1_cfg.ttbr[0];
 
reg64 |= ((u64)ARM_SMMU_CB_ASID(cfg)) << TTBRn_ASID_SHIFT;
-   smmu_writeq(reg64, cb_base + ARM_SMMU_CB_TTBR0);
+   writeq_relaxed(reg64, cb_base + ARM_SMMU_CB_TTBR0);
 
reg64 = pgtbl_cfg->arm_lpae_s1_cfg.ttbr[1];
reg64 |= ((u64)ARM_SMMU_CB_ASID(cfg)) << TTBRn_ASID_SHIFT;
-   smmu_writeq(reg64, cb_base + ARM_SMMU_CB_TTBR1);
+   writeq_relaxed(reg64, cb_base + ARM_SMMU_CB_TTBR1);
} else {
reg64 = pgtbl_cfg->arm_lpae_s2_cfg.vttbr;
-   smmu_writeq(reg64, cb_base + ARM_SMMU_CB_TTBR0);
+   writeq_relaxed(reg64, cb_base + ARM_SMMU_CB_TTBR0);
}
 
/* TTBCR */
@@ -1226,8 +

[PATCH 1/2] io-64-nonatomic: Add relaxed accessor variants

2015-12-18 Thread Robin Murphy
Whilst commit 9439eb3ab9d1 ("asm-generic: io: implement relaxed
accessor macros as conditional wrappers") makes the *_relaxed forms of
I/O accessors universally available to drivers, in cases where writeq()
is implemented via the io-64-nonatomic helpers, writeq_relaxed() will
end up falling back to writel() regardless of whether writel_relaxed()
is available (identically for s/write/read/).

Add corresponding relaxed forms of the nonatomic helpers to delegate
to the equivalent 32-bit accessors as appropriate.

CC: Arnd Bergmann 
CC: Christoph Hellwig 
CC: Darren Hart 
CC: Hitoshi Mitake 
Signed-off-by: Robin Murphy 
---
 include/linux/io-64-nonatomic-hi-lo.h | 25 +
 include/linux/io-64-nonatomic-lo-hi.h | 25 +
 2 files changed, 50 insertions(+)

diff --git a/include/linux/io-64-nonatomic-hi-lo.h 
b/include/linux/io-64-nonatomic-hi-lo.h
index 11d7e84..1a85566 100644
--- a/include/linux/io-64-nonatomic-hi-lo.h
+++ b/include/linux/io-64-nonatomic-hi-lo.h
@@ -21,6 +21,23 @@ static inline void hi_lo_writeq(__u64 val, volatile void 
__iomem *addr)
writel(val, addr);
 }
 
+static inline __u64 hi_lo_readq_relaxed(const volatile void __iomem *addr)
+{
+   const volatile u32 __iomem *p = addr;
+   u32 low, high;
+
+   high = readl_relaxed(p + 1);
+   low = readl_relaxed(p);
+
+   return low + ((u64)high << 32);
+}
+
+static inline void hi_lo_writeq_relaxed(__u64 val, volatile void __iomem *addr)
+{
+   writel_relaxed(val >> 32, addr + 4);
+   writel_relaxed(val, addr);
+}
+
 #ifndef readq
 #define readq hi_lo_readq
 #endif
@@ -29,4 +46,12 @@ static inline void hi_lo_writeq(__u64 val, volatile void 
__iomem *addr)
 #define writeq hi_lo_writeq
 #endif
 
+#ifndef readq_relaxed
+#define readq_relaxed hi_lo_readq_relaxed
+#endif
+
+#ifndef writeq_relaxed
+#define writeq hi_lo_writeq_relaxed
+#endif
+
 #endif /* _LINUX_IO_64_NONATOMIC_HI_LO_H_ */
diff --git a/include/linux/io-64-nonatomic-lo-hi.h 
b/include/linux/io-64-nonatomic-lo-hi.h
index 1a4315f..1b7411d 100644
--- a/include/linux/io-64-nonatomic-lo-hi.h
+++ b/include/linux/io-64-nonatomic-lo-hi.h
@@ -21,6 +21,23 @@ static inline void lo_hi_writeq(__u64 val, volatile void 
__iomem *addr)
writel(val >> 32, addr + 4);
 }
 
+static inline __u64 lo_hi_readq_relaxed(const volatile void __iomem *addr)
+{
+   const volatile u32 __iomem *p = addr;
+   u32 low, high;
+
+   low = readl_relaxed(p);
+   high = readl_relaxed(p + 1);
+
+   return low + ((u64)high << 32);
+}
+
+static inline void lo_hi_writeq_relaxed(__u64 val, volatile void __iomem *addr)
+{
+   writel_relaxed(val, addr);
+   writel_relaxed(val >> 32, addr + 4);
+}
+
 #ifndef readq
 #define readq lo_hi_readq
 #endif
@@ -29,4 +46,12 @@ static inline void lo_hi_writeq(__u64 val, volatile void 
__iomem *addr)
 #define writeq lo_hi_writeq
 #endif
 
+#ifndef readq_relaxed
+#define readq_relaxed hi_lo_readq_relaxed
+#endif
+
+#ifndef writeq_relaxed
+#define writeq hi_lo_writeq_relaxed
+#endif
+
 #endif /* _LINUX_IO_64_NONATOMIC_LO_HI_H_ */
-- 
1.9.1

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


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.
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH 3/3] iommu/dma: Avoid unlikely high-order allocations

2015-12-18 Thread Robin Murphy
Doug reports that the equivalent page allocator on 32-bit ARM exhibits
particularly pathalogical behaviour under memory pressure when
fragmentation is high, where allocating a 4MB buffer takes tens of
seconds and the number of calls to alloc_pages() is over 9000![1]

We can drastically improve that situation without losing the other
benefits of high-order allocations when they would succeed, by assuming
memory pressure is relatively constant over the course of an allocation,
and not retrying allocations at orders we know to have failed before.
This way, the best-case behaviour remains unchanged, and in the worst
case we should see at most a dozen or so (MAX_ORDER - 1) failed attempts
before falling back to single pages for the remainder of the buffer.

[1]:http://lists.infradead.org/pipermail/linux-arm-kernel/2015-December/394660.html

Reported-by: Douglas Anderson 
Signed-off-by: Robin Murphy 
---
 drivers/iommu/dma-iommu.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c
index 03811e3..e37516a 100644
--- a/drivers/iommu/dma-iommu.c
+++ b/drivers/iommu/dma-iommu.c
@@ -194,6 +194,7 @@ static struct page **__iommu_dma_alloc_pages(unsigned int 
count, gfp_t gfp)
 {
struct page **pages;
unsigned int i = 0, array_size = count * sizeof(*pages);
+   unsigned int order = MAX_ORDER;
 
if (array_size <= PAGE_SIZE)
pages = kzalloc(array_size, GFP_KERNEL);
@@ -207,14 +208,15 @@ static struct page **__iommu_dma_alloc_pages(unsigned int 
count, gfp_t gfp)
 
while (count) {
struct page *page = NULL;
-   int j, order = __fls(count);
+   int j;
 
/*
 * Higher-order allocations are a convenience rather
 * than a necessity, hence using __GFP_NORETRY until
 * falling back to single-page allocations.
 */
-   for (order = min(order, MAX_ORDER); order > 0; order--) {
+   for (order = min_t(unsigned int, order, __fls(count));
+order > 0; order--) {
page = alloc_pages(gfp | __GFP_NORETRY, order);
if (!page)
continue;
-- 
1.9.1

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH 2/3] iommu/dma: Use correct offset in map_sg

2015-12-18 Thread Robin Murphy
When mapping a non-page-aligned scatterlist entry, we copy the original
offset to the output DMA address before aligning it to hand off to
iommu_map_sg(), then later adding the IOVA page address portion to get
the final mapped address. However, when the IOVA page size is smaller
than the CPU page size, it is the offset within the IOVA page we want,
not that within the CPU page, which can easily be larger than an IOVA
page and thus result in an incorrect final address.

Fix the bug by taking only the IOVA-aligned part of the offset as the
basis of the DMA address, not the whole thing.

Signed-off-by: Robin Murphy 
---
 drivers/iommu/dma-iommu.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c
index 982e716..03811e3 100644
--- a/drivers/iommu/dma-iommu.c
+++ b/drivers/iommu/dma-iommu.c
@@ -458,7 +458,7 @@ int iommu_dma_map_sg(struct device *dev, struct scatterlist 
*sg,
size_t s_length = s->length;
size_t pad_len = (mask - iova_len + 1) & mask;
 
-   sg_dma_address(s) = s->offset;
+   sg_dma_address(s) = s_offset;
sg_dma_len(s) = s_length;
s->offset -= s_offset;
s_length = iova_align(iovad, s_length + s_offset);
-- 
1.9.1

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH 1/3] iommu/dma: Add some missing #includes

2015-12-18 Thread Robin Murphy
dma-iommu.c was naughtily relying on an implicit transitive #include of
linux/vmalloc.h, which is apparently not present on some architectures.
Add that, plus a couple more headers for other functions which are used
similarly.

Reported-by: kbuild test robot 
Signed-off-by: Robin Murphy 
---

Hi Joerg,

here are a couple more minor fixes for some obscure subtleties in the
common DMA code. I see I've just missed the rc5 fixes pull, but I hope
you can pick these up for rc6 (unless of course you're also just about
to disappear for 2 weeks like I am).

Thanks,
Robin.


 drivers/iommu/dma-iommu.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c
index 427fdc1..982e716 100644
--- a/drivers/iommu/dma-iommu.c
+++ b/drivers/iommu/dma-iommu.c
@@ -21,10 +21,13 @@
 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
 #include 
+#include 
+#include 
 
 int iommu_dma_init(void)
 {
-- 
1.9.1

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[git pull] IOMMU Fixes for Linux v4.4-rc5

2015-12-18 Thread Joerg Roedel
Hi Linus,

The following changes since commit 9f9499ae8e6415cefc4fe0a96ad0e27864353c89:

  Linux 4.4-rc5 (2015-12-13 17:42:58 -0800)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu.git 
tags/iommu-fixes-v4.4-rc5

for you to fetch changes up to 7f8312a3b31de5676144d9e75f2f2647c8b4b769:

  iommu/vt-d: Do access checks before calling handle_mm_fault() (2015-12-14 
15:37:55 +0100)


IOMMU Fixes for Linux v4.4-rc5

* Two similar fixes for the Intel and AMD IOMMU drivers to add
  proper access checks before calling handle_mm_fault.


Joerg Roedel (2):
  iommu/amd: Do proper access checking before calling handle_mm_fault()
  iommu/vt-d: Do access checks before calling handle_mm_fault()

 drivers/iommu/amd_iommu_v2.c | 20 ++--
 drivers/iommu/intel-svm.c| 20 
 2 files changed, 38 insertions(+), 2 deletions(-)

Please pull.

Thanks,

Joerg



signature.asc
Description: Digital signature
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

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, &dom->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 devic

[PATCH v7 2/5] dt-bindings: mediatek: Add smi dts binding

2015-12-18 Thread Yong Wu
This patch add smi binding document and smi local arbiter header file.

Signed-off-by: Yong Wu 
---
Hi Rob,
   Because I move the header file(dt-bindings/memory/mt8173-larb-port.h)
from our patch[1/5] into here. I am not sure you agree with this,
so don't add your Ack above.
Acked-by: Rob Herring 

 .../memory-controllers/mediatek,smi-common.txt |  24 +
 .../memory-controllers/mediatek,smi-larb.txt   |  25 +
 include/dt-bindings/memory/mt8173-larb-port.h  | 111 +
 3 files changed, 160 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/memory-controllers/mediatek,smi-common.txt
 create mode 100644 
Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.txt
 create mode 100644 include/dt-bindings/memory/mt8173-larb-port.h

diff --git 
a/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-common.txt 
b/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-common.txt
new file mode 100644
index 000..06a83ce
--- /dev/null
+++ 
b/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-common.txt
@@ -0,0 +1,24 @@
+SMI (Smart Multimedia Interface) Common
+
+The hardware block diagram please check bindings/iommu/mediatek,iommu.txt
+
+Required properties:
+- compatible : must be "mediatek,mt8173-smi-common"
+- reg : the register and size of the SMI block.
+- power-domains : a phandle to the power domain of this local arbiter.
+- clocks : Must contain an entry for each entry in clock-names.
+- clock-names : must contain 2 entries, as follows:
+  - "apb" : Advanced Peripheral Bus clock, It's the clock for setting
+   the register.
+  - "smi" : It's the clock for transfer data and command.
+  They may be the same if both source clocks are the same.
+
+Example:
+   smi_common: smi@14022000 {
+   compatible = "mediatek,mt8173-smi-common";
+   reg = <0 0x14022000 0 0x1000>;
+   power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
+   clocks = <&mmsys CLK_MM_SMI_COMMON>,
+<&mmsys CLK_MM_SMI_COMMON>;
+   clock-names = "apb", "smi";
+   };
diff --git 
a/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.txt 
b/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.txt
new file mode 100644
index 000..55ff3b7
--- /dev/null
+++ b/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.txt
@@ -0,0 +1,25 @@
+SMI (Smart Multimedia Interface) Local Arbiter
+
+The hardware block diagram please check bindings/iommu/mediatek,iommu.txt
+
+Required properties:
+- compatible : must be "mediatek,mt8173-smi-larb"
+- reg : the register and size of this local arbiter.
+- mediatek,smi : a phandle to the smi_common node.
+- power-domains : a phandle to the power domain of this local arbiter.
+- clocks : Must contain an entry for each entry in clock-names.
+- clock-names: must contain 2 entries, as follows:
+  - "apb" : Advanced Peripheral Bus clock, It's the clock for setting
+   the register.
+  - "smi" : It's the clock for transfer data and command.
+
+Example:
+   larb1: larb@1601 {
+   compatible = "mediatek,mt8173-smi-larb";
+   reg = <0 0x1601 0 0x1000>;
+   mediatek,smi = <&smi_common>;
+   power-domains = <&scpsys MT8173_POWER_DOMAIN_VDEC>;
+   clocks = <&vdecsys CLK_VDEC_CKEN>,
+<&vdecsys CLK_VDEC_LARB_CKEN>;
+   clock-names = "apb", "smi";
+   };
diff --git a/include/dt-bindings/memory/mt8173-larb-port.h 
b/include/dt-bindings/memory/mt8173-larb-port.h
new file mode 100644
index 000..50ccb93
--- /dev/null
+++ b/include/dt-bindings/memory/mt8173-larb-port.h
@@ -0,0 +1,111 @@
+/*
+ * 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.
+ */
+#ifndef __DTS_IOMMU_PORT_MT8173_H
+#define __DTS_IOMMU_PORT_MT8173_H
+
+#define MTK_M4U_ID(larb, port) (((larb) << 5) | (port))
+/* Local arbiter ID */
+#define MTK_M4U_TO_LARB(id)(((id) >> 5) & 0x7)
+/* PortID within the local arbiter */
+#define MTK_M4U_TO_PORT(id)((id) & 0x1f)
+
+#define M4U_LARB0_ID   0
+#define M4U_LARB1_ID   1
+#define M4U_LARB2_ID   2
+#define M4U_LARB3_ID   3
+#define M4U_LARB4_ID   4
+#define M4U_LARB5_ID   5
+
+/* larb0 */
+#define M4U_PORT_DISP_OVL0 MTK_M4U_ID(M4U_LARB0_ID, 0)
+#define M4U_PORT_DISP_RDMA0  

[PATCH v7 3/5] memory: mediatek: Add SMI driver

2015-12-18 Thread Yong Wu
This patch add SMI(Smart Multimedia Interface) driver. This driver
is responsible to enable/disable iommu and control the power domain
and clocks of each local arbiter.

Signed-off-by: Yong Wu 
---
 drivers/memory/Kconfig |   8 ++
 drivers/memory/Makefile|   1 +
 drivers/memory/mtk-smi.c   | 268 +
 include/soc/mediatek/smi.h |  58 ++
 4 files changed, 335 insertions(+)
 create mode 100644 drivers/memory/mtk-smi.c
 create mode 100644 include/soc/mediatek/smi.h

diff --git a/drivers/memory/Kconfig b/drivers/memory/Kconfig
index 6f31546..51d5cd2 100644
--- a/drivers/memory/Kconfig
+++ b/drivers/memory/Kconfig
@@ -114,6 +114,14 @@ config JZ4780_NEMC
  the Ingenic JZ4780. This controller is used to handle external
  memory devices such as NAND and SRAM.
 
+config MTK_SMI
+   bool
+   depends on ARCH_MEDIATEK || COMPILE_TEST
+   help
+ This driver is for the Memory Controller module in MediaTek SoCs,
+ mainly help enable/disable iommu and control the power domain and
+ clocks for each local arbiter.
+
 source "drivers/memory/tegra/Kconfig"
 
 endif
diff --git a/drivers/memory/Makefile b/drivers/memory/Makefile
index 1c46af5..890bdf4 100644
--- a/drivers/memory/Makefile
+++ b/drivers/memory/Makefile
@@ -15,5 +15,6 @@ obj-$(CONFIG_FSL_IFC) += fsl_ifc.o
 obj-$(CONFIG_MVEBU_DEVBUS) += mvebu-devbus.o
 obj-$(CONFIG_TEGRA20_MC)   += tegra20-mc.o
 obj-$(CONFIG_JZ4780_NEMC)  += jz4780-nemc.o
+obj-$(CONFIG_MTK_SMI)  += mtk-smi.o
 
 obj-$(CONFIG_TEGRA_MC) += tegra/
diff --git a/drivers/memory/mtk-smi.c b/drivers/memory/mtk-smi.c
new file mode 100644
index 000..3714f604
--- /dev/null
+++ b/drivers/memory/mtk-smi.c
@@ -0,0 +1,268 @@
+/*
+ * 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 
+
+#define SMI_LARB_MMU_EN0xf00
+
+struct mtk_smi {
+   struct device   *dev;
+   struct clk  *clk_apb, *clk_smi;
+};
+
+struct mtk_smi_larb { /* larb: local arbiter */
+   struct mtk_smi  smi;
+   void __iomem*base;
+   struct device   *smi_common_dev;
+   u32 *mmu;
+};
+
+static int mtk_smi_enable(const struct mtk_smi *smi)
+{
+   int ret;
+
+   ret = pm_runtime_get_sync(smi->dev);
+   if (ret < 0)
+   return ret;
+
+   ret = clk_prepare_enable(smi->clk_apb);
+   if (ret)
+   goto err_put_pm;
+
+   ret = clk_prepare_enable(smi->clk_smi);
+   if (ret)
+   goto err_disable_apb;
+
+   return 0;
+
+err_disable_apb:
+   clk_disable_unprepare(smi->clk_apb);
+err_put_pm:
+   pm_runtime_put_sync(smi->dev);
+   return ret;
+}
+
+static void mtk_smi_disable(const struct mtk_smi *smi)
+{
+   clk_disable_unprepare(smi->clk_smi);
+   clk_disable_unprepare(smi->clk_apb);
+   pm_runtime_put_sync(smi->dev);
+}
+
+int mtk_smi_larb_get(struct device *larbdev)
+{
+   struct mtk_smi_larb *larb = dev_get_drvdata(larbdev);
+   struct mtk_smi *common = dev_get_drvdata(larb->smi_common_dev);
+   int ret;
+
+   /* Enable the smi-common's power and clocks */
+   ret = mtk_smi_enable(common);
+   if (ret)
+   return ret;
+
+   /* Enable the larb's power and clocks */
+   ret = mtk_smi_enable(&larb->smi);
+   if (ret) {
+   mtk_smi_disable(common);
+   return ret;
+   }
+
+   /* Configure the iommu info */
+   if (larb->mmu)
+   writel(*larb->mmu, larb->base + SMI_LARB_MMU_EN);
+
+   return 0;
+}
+
+void mtk_smi_larb_put(struct device *larbdev)
+{
+   struct mtk_smi_larb *larb = dev_get_drvdata(larbdev);
+   struct mtk_smi *common = dev_get_drvdata(larb->smi_common_dev);
+
+   mtk_smi_disable(&larb->smi);
+   mtk_smi_disable(common);
+}
+
+static int
+mtk_smi_larb_bind(struct device *dev, struct device *master, void *data)
+{
+   struct mtk_smi_larb *larb = dev_get_drvdata(dev);
+   struct mtk_smi_iommu *smi_iommu = data;
+   unsigned int i;
+
+   for (i = 0; i < smi_iommu->larb_nr; i++) {
+   if (dev == smi_iommu->larb_imu[i].dev) {
+   larb->mmu = &smi_iommu->larb_imu[i].mmu;
+   return 0;
+   }
+   }
+   return -ENODEV;
+}
+
+static void
+mtk_smi_larb_unbind(struct device *dev, struct device *master, void 

[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 MTK

[PATCH v7 5/5] dts: mt8173: Add iommu/smi nodes for mt8173

2015-12-18 Thread Yong Wu
This patch add the iommu/larbs nodes for mt8173

Signed-off-by: Yong Wu 
---
 arch/arm64/boot/dts/mediatek/mt8173.dtsi | 81 
 1 file changed, 81 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt8173.dtsi 
b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
index 4dd5f93..8b50951 100644
--- a/arch/arm64/boot/dts/mediatek/mt8173.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
@@ -14,6 +14,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include "mt8173-pinfunc.h"
@@ -267,6 +268,17 @@
reg = <0 0x10200620 0 0x20>;
};
 
+   iommu: iommu@10205000 {
+   compatible = "mediatek,mt8173-m4u";
+   reg = <0 0x10205000 0 0x1000>;
+   interrupts = ;
+   clocks = <&infracfg CLK_INFRA_M4U>;
+   clock-names = "bclk";
+   mediatek,larbs = <&larb0 &larb1 &larb2
+ &larb3 &larb4 &larb5>;
+   #iommu-cells = <1>;
+   };
+
apmixedsys: clock-controller@10209000 {
compatible = "mediatek,mt8173-apmixedsys";
reg = <0 0x10209000 0 0x1000>;
@@ -516,29 +528,98 @@
#clock-cells = <1>;
};
 
+   larb0: larb@14021000 {
+   compatible = "mediatek,mt8173-smi-larb";
+   reg = <0 0x14021000 0 0x1000>;
+   mediatek,smi = <&smi_common>;
+   power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
+   clocks = <&mmsys CLK_MM_SMI_LARB0>,
+<&mmsys CLK_MM_SMI_LARB0>;
+   clock-names = "apb", "smi";
+   };
+
+   smi_common: smi@14022000 {
+   compatible = "mediatek,mt8173-smi-common";
+   reg = <0 0x14022000 0 0x1000>;
+   power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
+   clocks = <&mmsys CLK_MM_SMI_COMMON>,
+<&mmsys CLK_MM_SMI_COMMON>;
+   clock-names = "apb", "smi";
+   };
+
+   larb4: larb@14027000 {
+   compatible = "mediatek,mt8173-smi-larb";
+   reg = <0 0x14027000 0 0x1000>;
+   mediatek,smi = <&smi_common>;
+   power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
+   clocks = <&mmsys CLK_MM_SMI_LARB4>,
+<&mmsys CLK_MM_SMI_LARB4>;
+   clock-names = "apb", "smi";
+   };
+
imgsys: clock-controller@1500 {
compatible = "mediatek,mt8173-imgsys", "syscon";
reg = <0 0x1500 0 0x1000>;
#clock-cells = <1>;
};
 
+   larb2: larb@15001000 {
+   compatible = "mediatek,mt8173-smi-larb";
+   reg = <0 0x15001000 0 0x1000>;
+   mediatek,smi = <&smi_common>;
+   power-domains = <&scpsys MT8173_POWER_DOMAIN_ISP>;
+   clocks = <&imgsys CLK_IMG_LARB2_SMI>,
+<&imgsys CLK_IMG_LARB2_SMI>;
+   clock-names = "apb", "smi";
+   };
+
vdecsys: clock-controller@1600 {
compatible = "mediatek,mt8173-vdecsys", "syscon";
reg = <0 0x1600 0 0x1000>;
#clock-cells = <1>;
};
 
+   larb1: larb@1601 {
+   compatible = "mediatek,mt8173-smi-larb";
+   reg = <0 0x1601 0 0x1000>;
+   mediatek,smi = <&smi_common>;
+   power-domains = <&scpsys MT8173_POWER_DOMAIN_VDEC>;
+   clocks = <&vdecsys CLK_VDEC_CKEN>,
+<&vdecsys CLK_VDEC_LARB_CKEN>;
+   clock-names = "apb", "smi";
+   };
+
vencsys: clock-controller@1800 {
compatible = "mediatek,mt8173-vencsys", "syscon";
reg = <0 0x1800 0 0x1000>;
#clock-cells = <1>;
};
 
+   larb3: larb@18001000 {
+   compatible = "mediatek,mt8173-smi-larb";
+   reg = <0 0x18001000 0 0x1000>;
+   mediatek,smi = <&smi_common>;
+   power-domains = <&scpsys MT8173_POWER_DOMAIN_VENC>;
+   clocks = <&vencsys CLK_VENC_CKE1>,
+<&vencsys CLK_VENC_CKE0>;
+   clock-names = "apb", "smi";
+   };
+
vencltsys: clock-con

[PATCH v7 0/5] MT8173 IOMMU SUPPORT

2015-12-18 Thread Yong Wu
  This patch set adds support for m4u(Multimedia Memory Management Unit),
Currently it only support the m4u with 2 levels of pagetable on mt8173.

  It's based on Robin Murphy's reposting Short-descriptor v2[1].
 
  Please check the hardware block diagram of Mediatek IOMMU.
 
  m4u (Multimedia Memory Management Unit)
   |
   SMI Common(Smart Multimedia Interface Common)
   |
   ++---
   ||
   ||
   SMI larb0SMI larb1   ... SoCs have several SMI local arbiter(larb).
   (display) (vdec)
   ||
   ||
 +-+-+ +++
 | | | |||
 | | |...  |||  ... There are different ports in each larb.
 | | | |||
OVL0 RDMA0 WDMA0  MC   PP   VLD

  As above, The Multimedia HW will go through SMI and M4U while it
access EMI. SMI is a brige between m4u and the Multimedia HW. It contain
smi local arbiter and smi common. It will control whether the Multimedia
HW should go though the m4u for translation or bypass it and talk
directly with EMI. And also SMI help control the power domain and clocks for
each local arbiter.
  Normally we specify a local arbiter(larb) for each multimedia HW
like display, video decode, and camera. And there are different ports
in each larb. Take a example, There are many ports like MC, PP, VLD in the
video decode local arbiter, all these ports are according to the video HW.

[1] http://lists.linuxfoundation.org/pipermail/iommu/2015-December/015210.html

v7:
- rebase onto Robin's short v2
- Adjust the iommu probe sequence to meet the expectant flow that the iommu
  core help create the domain.
- use component additional data instead of the interface mtk_smi_config_port.
- reconstruct the SMI help function.

v6: http://lists.linuxfoundation.org/pipermail/iommu/2015-December/015105.html
-rebase onto v4.4-rc1.
-Use Robin's reposting Short-decriptor.
 http://lists.linuxfoundation.org/pipermail/iommu/2015-December/015088.html
-Add component for m4u and smi since m4u should depend on smi-larb.
 The master device is the m4u device, and the client one is the smi-larb 
device. 
-Change mtk iommu-cells from 2 to 1 since the mapping between larb and port is
 fixed. Compare this with v2, we redefine MTK_M4U_ID following this register
 REG_MMU_INT_ID.
-About SMI: Add some help funcion and rename some function and struction for
 more readable. 
 These three above are according to Daniel Kurtz's suggestion.

v5: http://lists.linuxfoundation.org/pipermail/iommu/2015-October/014586.html
-rebase onto v4.3-rc1.
-About MTK iommu: don't return the same domain while domain_alloc, change the
 domain's flow according to the M4U HW.
-About Short-descriptor: Improve many error-handles, NO_PERMS quirk, and 
 add TLBI_MAP quirk following Will's Suggestion; Add io-pgtable don't use 
 dma_to_phys; Add a loop in arm_short_unmap since iommu_unmap don't care the 
 physical address align.
-About SMI driver: Add a help funcion for some similar code. Add PROPRE_DEFER
 for power-domain as MTK SCPSYS is module_init currently.

v4: http://lists.linuxfoundation.org/pipermail/iommu/2015-August/013903.html
-use only one iommu domain here based on the Robin's DMA-v5:
 http://lists.linuxfoundation.org/pipermail/iommu/2015-July/013900.html
-remove flush_pgtable.
-change writel to writel_relaxed.
-about Short-descriptor: move dma_map_single into io-pgtable-arm-short.
 Improve the flow of free pgtable and add NO_XN+NO_PERMS quirk following
 Will's suggestion.
-Change two sytle issues in dtsi according to Daniel's suggestion.

v3: http://lists.linuxfoundation.org/pipermail/iommu/2015-July/013632.html
-rebased onto v4.2-rc1
-improve iommu flow based on the Robin's DMA v3:
 http://lists.linuxfoundation.org/pipermail/iommu/2015-July/013597.html
-change mtk iommu-cells from 1 to 2.
-about Short-descriptor: add split function; add self-test; add some other bits 
like nG,
 XN according to the spec; add SUPERSECTION and MTK quirk; move 
io_pgtable_ops_to_pgtable
 out from LPAE to the header file.
-about SMI: move from driver/soc/mediatek to driver/memory; change the clocks 
from
 clk[2] to clk_apb and clk_smi; add pm.
-add iommu suspend/resume to backup/restore register.

v2: http://lists.linuxfoundation.org/pipermail/iommu/2015-May/013028.html
-add arm short descriptor support.
-seperate smi common from smi and change the clock-names according
 to smi HW.
-delete the hardcode of the port-names in mt8173.
 replace this with larb-portes-nr in dtsi.
-fix some coding style issues.

v1: http://lists.infradead.org/pipermail/linux-mediatek/2015-March/58.html
-initial version.

Yong Wu (5):
  dt-bindings: iommu: Add binding for mediatek IOMMU
  dt-bindings: mediatek: Add smi dts binding
  memory: mediatek: Add SMI driver
  iommu/mediatek: Add mt8173 IOMMU driver
  dts: mt8173: Add iommu/smi nodes for mt8173

 .../devicetree/bindings

[PATCH v7 1/5] dt-bindings: iommu: Add binding for mediatek IOMMU

2015-12-18 Thread Yong Wu
This patch add mediatek iommu dts binding document.

Signed-off-by: Yong Wu 
---
 .../devicetree/bindings/iommu/mediatek,iommu.txt   | 68 ++
 1 file changed, 68 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/iommu/mediatek,iommu.txt

diff --git a/Documentation/devicetree/bindings/iommu/mediatek,iommu.txt 
b/Documentation/devicetree/bindings/iommu/mediatek,iommu.txt
new file mode 100644
index 000..c2fb06e
--- /dev/null
+++ b/Documentation/devicetree/bindings/iommu/mediatek,iommu.txt
@@ -0,0 +1,68 @@
+* Mediatek IOMMU Architecture Implementation
+
+  Some Mediatek SOCs contain a Multimedia Memory Management Unit (M4U) which
+uses the ARM Short-Descriptor translation table format for address translation.
+
+  About the M4U Hardware Block Diagram, please check below:
+
+  EMI (External Memory Interface)
+   |
+  m4u (Multimedia Memory Management Unit)
+   |
+   SMI Common(Smart Multimedia Interface Common)
+   |
+   ++---
+   ||
+   ||
+   SMI larb0SMI larb1   ... SoCs have several SMI local arbiter(larb).
+   (display) (vdec)
+   ||
+   ||
+ +-+-+ +++
+ | | | |||
+ | | |...  |||  ... There are different ports in each larb.
+ | | | |||
+OVL0 RDMA0 WDMA0  MC   PP   VLD
+
+  As above, The Multimedia HW will go through SMI and M4U while it
+access EMI. SMI is a brige between m4u and the Multimedia HW. It contain
+smi local arbiter and smi common. It will control whether the Multimedia
+HW should go though the m4u for translation or bypass it and talk
+directly with EMI. And also SMI help control the power domain and clocks for
+each local arbiter.
+  Normally we specify a local arbiter(larb) for each multimedia HW
+like display, video decode, and camera. And there are different ports
+in each larb. Take a example, There are many ports like MC, PP, VLD in the
+video decode local arbiter, all these ports are according to the video HW.
+
+Required properties:
+- compatible : must be "mediatek,mt8173-m4u".
+- reg : m4u register base and size.
+- interrupts : the interrupt of m4u.
+- clocks : must contain one entry for each clock-names.
+- clock-names : must be "bclk", It is the block clock of m4u.
+- mediatek,larbs : List of phandle to the local arbiters in the current Socs.
+   Refer to bindings/memory-controllers/mediatek,smi-larb.txt. It must sort
+   according to the local arbiter index, like larb0, larb1, larb2...
+- iommu-cells : must be 1. This is the mtk_m4u_id according to the HW.
+   Specifies the mtk_m4u_id as defined in
+   dt-binding/memory/mt8173-larb-port.h.
+
+Example:
+   iommu: iommu@10205000 {
+   compatible = "mediatek,mt8173-m4u";
+   reg = <0 0x10205000 0 0x1000>;
+   interrupts = ;
+   clocks = <&infracfg CLK_INFRA_M4U>;
+   clock-names = "bclk";
+   mediatek,larbs = <&larb0 &larb1 &larb2 &larb3 &larb4 &larb5>;
+   #iommu-cells = <1>;
+   };
+
+Example for a client device:
+   display {
+   compatible = "mediatek,mt8173-disp";
+   iommus = <&iommu M4U_PORT_DISP_OVL0>,
+<&iommu M4U_PORT_DISP_RDMA0>;
+   ...
+   };
-- 
1.8.1.1.dirty

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu