Re: [RFC PATCH] virtio_ring: Use DMA API if guest memory is encrypted

2019-08-10 Thread Christoph Hellwig
sev_active() is gone now in linux-next, at least as a global API.

And once again this is entirely going in the wrong direction.  The only
way using the DMA API is going to work at all is if the device is ready
for it.  So we need a flag on the virtio device, exposed by the
hypervisor (or hardware for hw virtio devices) that says:  hey, I'm real,
don't take a shortcut.

And that means on power and s390 qemu will always have to set thos if
you want to be ready for the ultravisor and co games.  It's not like we
haven't been through this a few times before, have we?


RE: [RFC PATCH] virtio_ring: Use DMA API if guest memory is encrypted

2019-08-10 Thread Ram Pai
On Sat, Aug 10, 2019 at 02:57:17PM -0400, Michael S. Tsirkin wrote:
> On Tue, Jan 29, 2019 at 03:08:12PM -0200, Thiago Jung Bauermann wrote:
> > 
> > Hello,
> > 
> > With Christoph's rework of the DMA API that recently landed, the patch
> > below is the only change needed in virtio to make it work in a POWER
> > secure guest under the ultravisor.
> > 
> > The other change we need (making sure the device's dma_map_ops is NULL
> > so that the dma-direct/swiotlb code is used) can be made in
> > powerpc-specific code.
> > 
> > Of course, I also have patches (soon to be posted as RFC) which hook up
> >  to the powerpc secure guest support code.
> > 
> > What do you think?
> > 
> > >From d0629a36a75c678b4a72b853f8f7f8c17eedd6b3 Mon Sep 17 00:00:00 2001
> > From: Thiago Jung Bauermann 
> > Date: Thu, 24 Jan 2019 22:08:02 -0200
> > Subject: [RFC PATCH] virtio_ring: Use DMA API if guest memory is encrypted
> > 
> > The host can't access the guest memory when it's encrypted, so using
> > regular memory pages for the ring isn't an option. Go through the DMA API.
> > 
> > Signed-off-by: Thiago Jung Bauermann 
> > ---
> >  drivers/virtio/virtio_ring.c | 5 -
> >  1 file changed, 4 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c
> > index cd7e755484e3..321a27075380 100644
> > --- a/drivers/virtio/virtio_ring.c
> > +++ b/drivers/virtio/virtio_ring.c
> > @@ -259,8 +259,11 @@ static bool vring_use_dma_api(struct virtio_device 
> > *vdev)
> >  * not work without an even larger kludge.  Instead, enable
> >  * the DMA API if we're a Xen guest, which at least allows
> >  * all of the sensible Xen configurations to work correctly.
> > +*
> > +* Also, if guest memory is encrypted the host can't access
> > +* it directly. In this case, we'll need to use the DMA API.
> >  */
> > -   if (xen_domain())
> > +   if (xen_domain() || sev_active())
> > return true;
> > 
> > return false;
> 
> So I gave this lots of thought, and I'm coming round to
> basically accepting something very similar to this patch.
> 
> But not exactly like this :).
> 
> Let's see what are the requirements.
> 
> If
> 
> 1. We do not trust the device (so we want to use a bounce buffer with it)
> 2. DMA address is also a physical address of a buffer
> 
> then we should use DMA API with virtio.
> 
> 
> sev_active() above is one way to put (1).  I can't say I love it but
> it's tolerable.
> 
> 
> But we also want promise from DMA API about 2.
> 
> 
> Without promise 2 we simply can't use DMA API with a legacy device.
> 
> 
> Otherwise, on a SEV system with an IOMMU which isn't 1:1
> and with a virtio device without ACCESS_PLATFORM, we are trying
> to pass a virtual address, and devices without ACCESS_PLATFORM
> can only access CPU physical addresses.
> 
> So something like:
> 
> dma_addr_is_phys_addr?


On our Secure pseries platform,  dma address is physical address and this
proposal will help us, use DMA API. 

On our normal pseries platform, dma address is physical address too.
But we do not necessarily need to use the DMA API.  We can use the DMA
API, but our handlers will do the same thing, the generic virtio handlers
would do. If there is an opt-out option; even when dma addr is same as
physical addr, than there will be less code duplication.

Would something like this be better.

(dma_addr_is_phys_addr  && arch_want_to_use_dma_api()) ?


RP


> -- 
> MST

-- 
Ram Pai



Re: [RFC PATCH] virtio_ring: Use DMA API if guest memory is encrypted

2019-08-10 Thread Michael S. Tsirkin
On Tue, Jan 29, 2019 at 03:08:12PM -0200, Thiago Jung Bauermann wrote:
> 
> Hello,
> 
> With Christoph's rework of the DMA API that recently landed, the patch
> below is the only change needed in virtio to make it work in a POWER
> secure guest under the ultravisor.
> 
> The other change we need (making sure the device's dma_map_ops is NULL
> so that the dma-direct/swiotlb code is used) can be made in
> powerpc-specific code.
> 
> Of course, I also have patches (soon to be posted as RFC) which hook up
>  to the powerpc secure guest support code.
> 
> What do you think?
> 
> >From d0629a36a75c678b4a72b853f8f7f8c17eedd6b3 Mon Sep 17 00:00:00 2001
> From: Thiago Jung Bauermann 
> Date: Thu, 24 Jan 2019 22:08:02 -0200
> Subject: [RFC PATCH] virtio_ring: Use DMA API if guest memory is encrypted
> 
> The host can't access the guest memory when it's encrypted, so using
> regular memory pages for the ring isn't an option. Go through the DMA API.
> 
> Signed-off-by: Thiago Jung Bauermann 
> ---
>  drivers/virtio/virtio_ring.c | 5 -
>  1 file changed, 4 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c
> index cd7e755484e3..321a27075380 100644
> --- a/drivers/virtio/virtio_ring.c
> +++ b/drivers/virtio/virtio_ring.c
> @@ -259,8 +259,11 @@ static bool vring_use_dma_api(struct virtio_device *vdev)
>* not work without an even larger kludge.  Instead, enable
>* the DMA API if we're a Xen guest, which at least allows
>* all of the sensible Xen configurations to work correctly.
> +  *
> +  * Also, if guest memory is encrypted the host can't access
> +  * it directly. In this case, we'll need to use the DMA API.
>*/
> - if (xen_domain())
> + if (xen_domain() || sev_active())
>   return true;
> 
>   return false;

So I gave this lots of thought, and I'm coming round to
basically accepting something very similar to this patch.

But not exactly like this :).

Let's see what are the requirements.

If

1. We do not trust the device (so we want to use a bounce buffer with it)
2. DMA address is also a physical address of a buffer

then we should use DMA API with virtio.


sev_active() above is one way to put (1).  I can't say I love it but
it's tolerable.


But we also want promise from DMA API about 2.


Without promise 2 we simply can't use DMA API with a legacy device.


Otherwise, on a SEV system with an IOMMU which isn't 1:1
and with a virtio device without ACCESS_PLATFORM, we are trying
to pass a virtual address, and devices without ACCESS_PLATFORM
can only access CPU physical addresses.

So something like:

dma_addr_is_phys_addr?



-- 
MST


[PATCH v9 17/21] memory: mtk-smi: Invoke pm runtime_callback to enable clocks

2019-08-10 Thread Yong Wu
This patch only move the clk_prepare_enable and config_port into the
runtime suspend/resume callback. It doesn't change the code content
and sequence.

This is a preparing patch for adjusting SMI_BUS_SEL for mt8183.
(SMI_BUS_SEL need to be restored after smi-common resume every time.)
Also it gives a chance to get rid of mtk_smi_larb_get/put which could
be a next topic.

CC: Matthias Brugger 
Signed-off-by: Yong Wu 
Reviewed-by: Evan Green 
Reviewed-by: Matthias Brugger 
---
 drivers/memory/mtk-smi.c | 113 ++-
 1 file changed, 72 insertions(+), 41 deletions(-)

diff --git a/drivers/memory/mtk-smi.c b/drivers/memory/mtk-smi.c
index 3dd05de..2bb55b86 100644
--- a/drivers/memory/mtk-smi.c
+++ b/drivers/memory/mtk-smi.c
@@ -78,17 +78,13 @@ struct mtk_smi_larb { /* larb: local arbiter */
u32 *mmu;
 };
 
-static int mtk_smi_enable(const struct mtk_smi *smi)
+static int mtk_smi_clk_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;
+   return ret;
 
ret = clk_prepare_enable(smi->clk_smi);
if (ret)
@@ -110,59 +106,28 @@ static int mtk_smi_enable(const struct mtk_smi *smi)
clk_disable_unprepare(smi->clk_smi);
 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)
+static void mtk_smi_clk_disable(const struct mtk_smi *smi)
 {
clk_disable_unprepare(smi->clk_gals1);
clk_disable_unprepare(smi->clk_gals0);
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);
-   const struct mtk_smi_larb_gen *larb_gen = larb->larb_gen;
-   struct mtk_smi *common = dev_get_drvdata(larb->smi_common_dev);
-   int ret;
+   int ret = pm_runtime_get_sync(larbdev);
 
-   /* 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(>smi);
-   if (ret) {
-   mtk_smi_disable(common);
-   return ret;
-   }
-
-   /* Configure the iommu info for this larb */
-   larb_gen->config_port(larbdev);
-
-   return 0;
+   return (ret < 0) ? ret : 0;
 }
 EXPORT_SYMBOL_GPL(mtk_smi_larb_get);
 
 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);
-
-   /*
-* Don't de-configure the iommu info for this larb since there may be
-* several modules in this larb.
-* The iommu info will be reset after power off.
-*/
-
-   mtk_smi_disable(>smi);
-   mtk_smi_disable(common);
+   pm_runtime_put_sync(larbdev);
 }
 EXPORT_SYMBOL_GPL(mtk_smi_larb_put);
 
@@ -377,12 +342,52 @@ static int mtk_smi_larb_remove(struct platform_device 
*pdev)
return 0;
 }
 
+static int __maybe_unused mtk_smi_larb_resume(struct device *dev)
+{
+   struct mtk_smi_larb *larb = dev_get_drvdata(dev);
+   const struct mtk_smi_larb_gen *larb_gen = larb->larb_gen;
+   int ret;
+
+   /* Power on smi-common. */
+   ret = pm_runtime_get_sync(larb->smi_common_dev);
+   if (ret < 0) {
+   dev_err(dev, "Failed to pm get for smi-common(%d).\n", ret);
+   return ret;
+   }
+
+   ret = mtk_smi_clk_enable(>smi);
+   if (ret < 0) {
+   dev_err(dev, "Failed to enable clock(%d).\n", ret);
+   pm_runtime_put_sync(larb->smi_common_dev);
+   return ret;
+   }
+
+   /* Configure the basic setting for this larb */
+   larb_gen->config_port(dev);
+
+   return 0;
+}
+
+static int __maybe_unused mtk_smi_larb_suspend(struct device *dev)
+{
+   struct mtk_smi_larb *larb = dev_get_drvdata(dev);
+
+   mtk_smi_clk_disable(>smi);
+   pm_runtime_put_sync(larb->smi_common_dev);
+   return 0;
+}
+
+static const struct dev_pm_ops smi_larb_pm_ops = {
+   SET_RUNTIME_PM_OPS(mtk_smi_larb_suspend, mtk_smi_larb_resume, NULL)
+};
+
 static struct platform_driver mtk_smi_larb_driver = {
.probe  = mtk_smi_larb_probe,
.remove = mtk_smi_larb_remove,
.driver = {
.name = "mtk-smi-larb",
.of_match_table = mtk_smi_larb_of_ids,
+   .pm = _larb_pm_ops,
}
 };
 
@@ -481,12 +486,38 @@ static int mtk_smi_common_remove(struct platform_device 
*pdev)
return 0;
 }
 
+static int 

[PATCH v9 21/21] iommu/mediatek: Clean up struct mtk_smi_iommu

2019-08-10 Thread Yong Wu
Remove the "struct mtk_smi_iommu" to simplify the code since it has only
one item in it right now.

Signed-off-by: Yong Wu 
---
 drivers/iommu/mtk_iommu.c| 4 ++--
 drivers/iommu/mtk_iommu.h| 6 +++---
 drivers/iommu/mtk_iommu_v1.c | 4 ++--
 drivers/memory/mtk-smi.c | 6 +++---
 include/soc/mediatek/smi.h   | 4 
 5 files changed, 10 insertions(+), 14 deletions(-)

diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index 274761c..d5b9454 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -254,7 +254,7 @@ static void mtk_iommu_config(struct mtk_iommu_data *data,
for (i = 0; i < fwspec->num_ids; ++i) {
larbid = MTK_M4U_TO_LARB(fwspec->ids[i]);
portid = MTK_M4U_TO_PORT(fwspec->ids[i]);
-   larb_mmu = >smi_imu.larb_imu[larbid];
+   larb_mmu = >larb_imu[larbid];
 
dev_dbg(dev, "%s iommu port: %d\n",
enable ? "enable" : "disable", portid);
@@ -653,7 +653,7 @@ static int mtk_iommu_probe(struct platform_device *pdev)
of_node_put(larbnode);
return -EPROBE_DEFER;
}
-   data->smi_imu.larb_imu[id].dev = >dev;
+   data->larb_imu[id].dev = >dev;
 
component_match_add_release(dev, , release_of,
compare_of, larbnode);
diff --git a/drivers/iommu/mtk_iommu.h b/drivers/iommu/mtk_iommu.h
index 56b579c..fc0f16e 100644
--- a/drivers/iommu/mtk_iommu.h
+++ b/drivers/iommu/mtk_iommu.h
@@ -56,7 +56,6 @@ struct mtk_iommu_data {
struct mtk_iommu_suspend_regreg;
struct mtk_iommu_domain *m4u_dom;
struct iommu_group  *m4u_group;
-   struct mtk_smi_iommusmi_imu;  /* SMI larb iommu info */
boolenable_4GB;
booltlb_flush_active;
 
@@ -64,6 +63,7 @@ struct mtk_iommu_data {
const struct mtk_iommu_plat_data *plat_data;
 
struct list_headlist;
+   struct mtk_smi_larb_iommu   larb_imu[MTK_LARB_NR_MAX];
 };
 
 static inline int compare_of(struct device *dev, void *data)
@@ -80,14 +80,14 @@ static inline int mtk_iommu_bind(struct device *dev)
 {
struct mtk_iommu_data *data = dev_get_drvdata(dev);
 
-   return component_bind_all(dev, >smi_imu);
+   return component_bind_all(dev, >larb_imu);
 }
 
 static inline void mtk_iommu_unbind(struct device *dev)
 {
struct mtk_iommu_data *data = dev_get_drvdata(dev);
 
-   component_unbind_all(dev, >smi_imu);
+   component_unbind_all(dev, >larb_imu);
 }
 
 #endif
diff --git a/drivers/iommu/mtk_iommu_v1.c b/drivers/iommu/mtk_iommu_v1.c
index 3922358..860926c 100644
--- a/drivers/iommu/mtk_iommu_v1.c
+++ b/drivers/iommu/mtk_iommu_v1.c
@@ -206,7 +206,7 @@ static void mtk_iommu_config(struct mtk_iommu_data *data,
for (i = 0; i < fwspec->num_ids; ++i) {
larbid = mt2701_m4u_to_larb(fwspec->ids[i]);
portid = mt2701_m4u_to_port(fwspec->ids[i]);
-   larb_mmu = >smi_imu.larb_imu[larbid];
+   larb_mmu = >larb_imu[larbid];
 
dev_dbg(dev, "%s iommu port: %d\n",
enable ? "enable" : "disable", portid);
@@ -610,7 +610,7 @@ static int mtk_iommu_probe(struct platform_device *pdev)
}
}
 
-   data->smi_imu.larb_imu[larb_nr].dev = >dev;
+   data->larb_imu[larb_nr].dev = >dev;
component_match_add_release(dev, , release_of,
compare_of, larb_spec.np);
larb_nr++;
diff --git a/drivers/memory/mtk-smi.c b/drivers/memory/mtk-smi.c
index d6dc62f..439d7d8 100644
--- a/drivers/memory/mtk-smi.c
+++ b/drivers/memory/mtk-smi.c
@@ -143,13 +143,13 @@ void mtk_smi_larb_put(struct device *larbdev)
 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;
+   struct mtk_smi_larb_iommu *larb_mmu = data;
unsigned int i;
 
for (i = 0; i < MTK_LARB_NR_MAX; i++) {
-   if (dev == smi_iommu->larb_imu[i].dev) {
+   if (dev == larb_mmu[i].dev) {
larb->larbid = i;
-   larb->mmu = _iommu->larb_imu[i].mmu;
+   larb->mmu = _mmu[i].mmu;
return 0;
}
}
diff --git a/include/soc/mediatek/smi.h b/include/soc/mediatek/smi.h
index 6f0b00c..5a34b87 100644
--- a/include/soc/mediatek/smi.h
+++ b/include/soc/mediatek/smi.h
@@ -20,10 +20,6 @@ struct mtk_smi_larb_iommu {
unsigned int   mmu;
 };
 
-struct mtk_smi_iommu {
-   struct mtk_smi_larb_iommu larb_imu[MTK_LARB_NR_MAX];
-};
-
 /*
  * mtk_smi_larb_get: Enable the power domain and 

[PATCH v9 18/21] memory: mtk-smi: Add bus_sel for mt8183

2019-08-10 Thread Yong Wu
There are 2 mmu cells in a M4U HW. we could adjust some larbs entering
mmu0 or mmu1 to balance the bandwidth via the smi-common register
SMI_BUS_SEL(0x220)(Each larb occupy 2 bits).

In mt8183, For better performance, we switch larb1/2/5/7 to enter
mmu1 while the others still keep enter mmu0.

In mt8173 and mt2712, we don't get the performance issue,
Keep its default value(0x0), that means all the larbs enter mmu0.

Note: smi gen1(mt2701/mt7623) don't have this bus_sel.

And, the base of smi-common is completely different with smi_ao_base
of gen1, thus I add new variable for that.

CC: Matthias Brugger 
Signed-off-by: Yong Wu 
Reviewed-by: Evan Green 
Reviewed-by: Matthias Brugger 
---
 drivers/memory/mtk-smi.c | 24 ++--
 1 file changed, 22 insertions(+), 2 deletions(-)

diff --git a/drivers/memory/mtk-smi.c b/drivers/memory/mtk-smi.c
index 2bb55b86..289e595 100644
--- a/drivers/memory/mtk-smi.c
+++ b/drivers/memory/mtk-smi.c
@@ -41,6 +41,12 @@
 #define SMI_LARB_NONSEC_CON(id)(0x380 + ((id) * 4))
 #define F_MMU_EN   BIT(0)
 
+/* SMI COMMON */
+#define SMI_BUS_SEL0x220
+#define SMI_BUS_LARB_SHIFT(larbid) ((larbid) << 1)
+/* All are MMU0 defaultly. Only specialize mmu1 here. */
+#define F_MMU1_LARB(larbid)(0x1 << SMI_BUS_LARB_SHIFT(larbid))
+
 enum mtk_smi_gen {
MTK_SMI_GEN1,
MTK_SMI_GEN2
@@ -49,6 +55,7 @@ enum mtk_smi_gen {
 struct mtk_smi_common_plat {
enum mtk_smi_gen gen;
bool has_gals;
+   u32  bus_sel; /* Balance some larbs to enter mmu0 or mmu1 */
 };
 
 struct mtk_smi_larb_gen {
@@ -64,8 +71,10 @@ struct mtk_smi {
struct clk  *clk_apb, *clk_smi;
struct clk  *clk_gals0, *clk_gals1;
struct clk  *clk_async; /*only needed by mt2701*/
-   void __iomem*smi_ao_base;
-
+   union {
+   void __iomem*smi_ao_base; /* only for gen1 */
+   void __iomem*base;/* only for gen2 */
+   };
const struct mtk_smi_common_plat *plat;
 };
 
@@ -402,6 +411,8 @@ static int __maybe_unused mtk_smi_larb_suspend(struct 
device *dev)
 static const struct mtk_smi_common_plat mtk_smi_common_mt8183 = {
.gen  = MTK_SMI_GEN2,
.has_gals = true,
+   .bus_sel  = F_MMU1_LARB(1) | F_MMU1_LARB(2) | F_MMU1_LARB(5) |
+   F_MMU1_LARB(7),
 };
 
 static const struct of_device_id mtk_smi_common_of_ids[] = {
@@ -474,6 +485,11 @@ static int mtk_smi_common_probe(struct platform_device 
*pdev)
ret = clk_prepare_enable(common->clk_async);
if (ret)
return ret;
+   } else {
+   res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+   common->base = devm_ioremap_resource(dev, res);
+   if (IS_ERR(common->base))
+   return PTR_ERR(common->base);
}
pm_runtime_enable(dev);
platform_set_drvdata(pdev, common);
@@ -489,6 +505,7 @@ static int mtk_smi_common_remove(struct platform_device 
*pdev)
 static int __maybe_unused mtk_smi_common_resume(struct device *dev)
 {
struct mtk_smi *common = dev_get_drvdata(dev);
+   u32 bus_sel = common->plat->bus_sel;
int ret;
 
ret = mtk_smi_clk_enable(common);
@@ -496,6 +513,9 @@ static int __maybe_unused mtk_smi_common_resume(struct 
device *dev)
dev_err(common->dev, "Failed to enable clock(%d).\n", ret);
return ret;
}
+
+   if (common->plat->gen == MTK_SMI_GEN2 && bus_sel)
+   writel(bus_sel, common->base + SMI_BUS_SEL);
return 0;
 }
 
-- 
1.9.1

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


[PATCH v9 20/21] memory: mtk-smi: Get rid of need_larbid

2019-08-10 Thread Yong Wu
The "mediatek,larb-id" has already been parsed in MTK IOMMU driver.
It's no need to parse it again in SMI driver. Only clean some codes.
This patch is fit for all the current mt2701, mt2712, mt7623, mt8173
and mt8183.

After this patch, the "mediatek,larb-id" only be needed for mt2712
which have 2 M4Us. In the other SoCs, we can get the larb-id from M4U
in which the larbs in the "mediatek,larbs" always are ordered.

Correspondingly, the larb_nr in the "struct mtk_smi_iommu" could also
be deleted.

CC: Matthias Brugger 
Signed-off-by: Yong Wu 
Reviewed-by: Evan Green 
Reviewed-by: Matthias Brugger 
---
 drivers/iommu/mtk_iommu.c|  1 -
 drivers/iommu/mtk_iommu_v1.c |  2 --
 drivers/memory/mtk-smi.c | 26 ++
 include/soc/mediatek/smi.h   |  1 -
 4 files changed, 2 insertions(+), 28 deletions(-)

diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index 4f2f114..274761c 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -629,7 +629,6 @@ static int mtk_iommu_probe(struct platform_device *pdev)
 "mediatek,larbs", NULL);
if (larb_nr < 0)
return larb_nr;
-   data->smi_imu.larb_nr = larb_nr;
 
for (i = 0; i < larb_nr; i++) {
struct device_node *larbnode;
diff --git a/drivers/iommu/mtk_iommu_v1.c b/drivers/iommu/mtk_iommu_v1.c
index abeeac4..3922358 100644
--- a/drivers/iommu/mtk_iommu_v1.c
+++ b/drivers/iommu/mtk_iommu_v1.c
@@ -616,8 +616,6 @@ static int mtk_iommu_probe(struct platform_device *pdev)
larb_nr++;
}
 
-   data->smi_imu.larb_nr = larb_nr;
-
platform_set_drvdata(pdev, data);
 
ret = mtk_iommu_hw_init(data);
diff --git a/drivers/memory/mtk-smi.c b/drivers/memory/mtk-smi.c
index 289e595..d6dc62f 100644
--- a/drivers/memory/mtk-smi.c
+++ b/drivers/memory/mtk-smi.c
@@ -59,7 +59,6 @@ struct mtk_smi_common_plat {
 };
 
 struct mtk_smi_larb_gen {
-   bool need_larbid;
int port_in_larb[MTK_LARB_NR_MAX + 1];
void (*config_port)(struct device *);
unsigned intlarb_direct_to_common_mask;
@@ -147,18 +146,9 @@ void mtk_smi_larb_put(struct device *larbdev)
struct mtk_smi_iommu *smi_iommu = data;
unsigned int i;
 
-   if (larb->larb_gen->need_larbid) {
-   larb->mmu = _iommu->larb_imu[larb->larbid].mmu;
-   return 0;
-   }
-
-   /*
-* If there is no larbid property, Loop to find the corresponding
-* iommu information.
-*/
-   for (i = 0; i < smi_iommu->larb_nr; i++) {
+   for (i = 0; i < MTK_LARB_NR_MAX; i++) {
if (dev == smi_iommu->larb_imu[i].dev) {
-   /* The 'mmu' may be updated in iommu-attach/detach. */
+   larb->larbid = i;
larb->mmu = _iommu->larb_imu[i].mmu;
return 0;
}
@@ -237,7 +227,6 @@ static void mtk_smi_larb_config_port_gen1(struct device 
*dev)
 };
 
 static const struct mtk_smi_larb_gen mtk_smi_larb_mt2701 = {
-   .need_larbid = true,
.port_in_larb = {
LARB0_PORT_OFFSET, LARB1_PORT_OFFSET,
LARB2_PORT_OFFSET, LARB3_PORT_OFFSET
@@ -246,7 +235,6 @@ static void mtk_smi_larb_config_port_gen1(struct device 
*dev)
 };
 
 static const struct mtk_smi_larb_gen mtk_smi_larb_mt2712 = {
-   .need_larbid = true,
.config_port= mtk_smi_larb_config_port_gen2_general,
.larb_direct_to_common_mask = BIT(8) | BIT(9),  /* bdpsys */
 };
@@ -285,7 +273,6 @@ static int mtk_smi_larb_probe(struct platform_device *pdev)
struct device *dev = >dev;
struct device_node *smi_node;
struct platform_device *smi_pdev;
-   int err;
 
larb = devm_kzalloc(dev, sizeof(*larb), GFP_KERNEL);
if (!larb)
@@ -315,15 +302,6 @@ static int mtk_smi_larb_probe(struct platform_device *pdev)
}
larb->smi.dev = dev;
 
-   if (larb->larb_gen->need_larbid) {
-   err = of_property_read_u32(dev->of_node, "mediatek,larb-id",
-  >larbid);
-   if (err) {
-   dev_err(dev, "missing larbid property\n");
-   return err;
-   }
-   }
-
smi_node = of_parse_phandle(dev->of_node, "mediatek,smi", 0);
if (!smi_node)
return -EINVAL;
diff --git a/include/soc/mediatek/smi.h b/include/soc/mediatek/smi.h
index 79b74ce..6f0b00c 100644
--- a/include/soc/mediatek/smi.h
+++ b/include/soc/mediatek/smi.h
@@ -21,7 +21,6 @@ struct mtk_smi_larb_iommu {
 };
 
 struct mtk_smi_iommu {
-   unsigned int larb_nr;
struct mtk_smi_larb_iommu larb_imu[MTK_LARB_NR_MAX];
 };
 
-- 
1.9.1



[PATCH v9 19/21] iommu/mediatek: Fix VLD_PA_RNG register backup when suspend

2019-08-10 Thread Yong Wu
The register VLD_PA_RNG(0x118) was forgot to backup while adding 4GB
mode support for mt2712. this patch add it.

Fixes: 30e2fccf9512 ("iommu/mediatek: Enlarge the validate PA range
for 4GB mode")
Signed-off-by: Yong Wu 
Reviewed-by: Evan Green 
Reviewed-by: Matthias Brugger 
---
 drivers/iommu/mtk_iommu.c | 2 ++
 drivers/iommu/mtk_iommu.h | 1 +
 2 files changed, 3 insertions(+)

diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index cbebe11..4f2f114 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -715,6 +715,7 @@ static int __maybe_unused mtk_iommu_suspend(struct device 
*dev)
reg->int_control0 = readl_relaxed(base + REG_MMU_INT_CONTROL0);
reg->int_main_control = readl_relaxed(base + REG_MMU_INT_MAIN_CONTROL);
reg->ivrp_paddr = readl_relaxed(base + REG_MMU_IVRP_PADDR);
+   reg->vld_pa_rng = readl_relaxed(base + REG_MMU_VLD_PA_RNG);
clk_disable_unprepare(data->bclk);
return 0;
 }
@@ -739,6 +740,7 @@ static int __maybe_unused mtk_iommu_resume(struct device 
*dev)
writel_relaxed(reg->int_control0, base + REG_MMU_INT_CONTROL0);
writel_relaxed(reg->int_main_control, base + REG_MMU_INT_MAIN_CONTROL);
writel_relaxed(reg->ivrp_paddr, base + REG_MMU_IVRP_PADDR);
+   writel_relaxed(reg->vld_pa_rng, base + REG_MMU_VLD_PA_RNG);
if (m4u_dom)
writel(m4u_dom->cfg.arm_v7s_cfg.ttbr[0] & MMU_PT_ADDR_MASK,
   base + REG_MMU_PT_BASE_ADDR);
diff --git a/drivers/iommu/mtk_iommu.h b/drivers/iommu/mtk_iommu.h
index 6b1f833..56b579c 100644
--- a/drivers/iommu/mtk_iommu.h
+++ b/drivers/iommu/mtk_iommu.h
@@ -24,6 +24,7 @@ struct mtk_iommu_suspend_reg {
u32 int_control0;
u32 int_main_control;
u32 ivrp_paddr;
+   u32 vld_pa_rng;
 };
 
 enum mtk_iommu_plat {
-- 
1.9.1



[PATCH v9 16/21] iommu/mediatek: Add mmu1 support

2019-08-10 Thread Yong Wu
Normally the M4U HW connect EMI with smi. the diagram is like below:
  EMI
   |
  M4U
   |
smi-common
   |
   -
   ||| |...
larb0 larb1  larb2 larb3

Actually there are 2 mmu cells in the M4U HW, like this diagram:

  EMI
   -
| |
   mmu0  mmu1 <- M4U
| |
   -
   |
smi-common
   |
   -
   ||| |...
larb0 larb1  larb2 larb3

This patch add support for mmu1. In order to get better performance,
we could adjust some larbs go to mmu1 while the others still go to
mmu0. This is controlled by a SMI COMMON register SMI_BUS_SEL(0x220).

mt2712, mt8173 and mt8183 M4U HW all have 2 mmu cells. the default
value of that register is 0 which means all the larbs go to mmu0
defaultly.

This is a preparing patch for adjusting SMI_BUS_SEL for mt8183.

Signed-off-by: Yong Wu 
Reviewed-by: Evan Green 
Reviewed-by: Matthias Brugger 
---
 drivers/iommu/mtk_iommu.c | 46 +-
 1 file changed, 29 insertions(+), 17 deletions(-)

diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index 550b093..cbebe11 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -64,26 +64,32 @@
 #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_TRANSACTION_FIFO_FAULT  BIT(5)
-#define F_INT_PRETETCH_TRANSATION_FIFO_FAULT   BIT(6)
+   /* mmu0 | mmu1 */
+#define F_INT_TRANSLATION_FAULT(BIT(0) | BIT(7))
+#define F_INT_MAIN_MULTI_HIT_FAULT (BIT(1) | BIT(8))
+#define F_INT_INVALID_PA_FAULT (BIT(2) | BIT(9))
+#define F_INT_ENTRY_REPLACEMENT_FAULT  (BIT(3) | BIT(10))
+#define F_INT_TLB_MISS_FAULT   (BIT(4) | BIT(11))
+#define F_INT_MISS_TRANSACTION_FIFO_FAULT  (BIT(5) | BIT(12))
+#define F_INT_PRETETCH_TRANSATION_FIFO_FAULT   (BIT(6) | BIT(13))
 
 #define REG_MMU_CPE_DONE   0x12C
 
 #define REG_MMU_FAULT_ST1  0x134
+#define F_REG_MMU0_FAULT_MASK  GENMASK(6, 0)
+#define F_REG_MMU1_FAULT_MASK  GENMASK(13, 7)
 
-#define REG_MMU_FAULT_VA   0x13c
+#define REG_MMU0_FAULT_VA  0x13c
 #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 REG_MMU0_INVLD_PA  0x140
+#define REG_MMU1_FAULT_VA  0x144
+#define REG_MMU1_INVLD_PA  0x148
+#define REG_MMU0_INT_ID0x150
+#define REG_MMU1_INT_ID0x154
+#define F_MMU_INT_ID_LARB_ID(a)(((a) >> 7) & 0x7)
+#define F_MMU_INT_ID_PORT_ID(a)(((a) >> 2) & 0x1f)
 
 #define MTK_PROTECT_PA_ALIGN   128
 
@@ -202,13 +208,19 @@ static irqreturn_t mtk_iommu_isr(int irq, void *dev_id)
 
/* Read error info from registers */
int_state = readl_relaxed(data->base + REG_MMU_FAULT_ST1);
-   fault_iova = readl_relaxed(data->base + REG_MMU_FAULT_VA);
+   if (int_state & F_REG_MMU0_FAULT_MASK) {
+   regval = readl_relaxed(data->base + REG_MMU0_INT_ID);
+   fault_iova = readl_relaxed(data->base + REG_MMU0_FAULT_VA);
+   fault_pa = readl_relaxed(data->base + REG_MMU0_INVLD_PA);
+   } else {
+   regval = readl_relaxed(data->base + REG_MMU1_INT_ID);
+   fault_iova = readl_relaxed(data->base + REG_MMU1_FAULT_VA);
+   fault_pa = readl_relaxed(data->base + REG_MMU1_INVLD_PA);
+   }
layer = fault_iova & F_MMU_FAULT_VA_LAYER_BIT;
write = fault_iova & F_MMU_FAULT_VA_WRITE_BIT;
-   fault_pa = readl_relaxed(data->base + REG_MMU_INVLD_PA);
-   regval = readl_relaxed(data->base + REG_MMU_INT_ID);
-   fault_larb = F_MMU0_INT_ID_LARB_ID(regval);
-   fault_port = F_MMU0_INT_ID_PORT_ID(regval);
+   fault_larb = F_MMU_INT_ID_LARB_ID(regval);
+   fault_port = F_MMU_INT_ID_PORT_ID(regval);
 
fault_larb = data->plat_data->larbid_remap[fault_larb];
 
-- 
1.9.1


[PATCH v9 14/21] memory: mtk-smi: Add gals support

2019-08-10 Thread Yong Wu
In some SoCs like mt8183, SMI add GALS(Global Async Local Sync) module
which can help synchronize for the modules in different clock frequency.
It can be seen as a "asynchronous fifo". This is a example diagram:

M4U
 |
 --
 ||
 gals0-rx   gals1-rx
 ||
 ||
 gals0-tx   gals1-tx
 ||

 SMI Common

 |
  +-++-+- ...
  | || |
  |  gals-rx  gals-rx  |
  | || |
  | || |
  |  gals-tx  gals-tx  |
  | || |
larb1 larb2   larb3  larb4

GALS only help transfer the command/data while it doesn't have the
configuring register, thus it has the special "smi" clock and doesn't
have the "apb" clock. From the diagram above, we add "gals0" and
"gals1" clocks for smi-common and add a "gals" clock for smi-larb.

This patch adds gals clock supporting in the SMI. Note that some larbs
may still don't have the "gals" clock like larb1 and larb4 above.

This is also a preparing patch for mt8183 which has GALS.

CC: Matthias Brugger 
Signed-off-by: Yong Wu 
Reviewed-by: Evan Green 
Reviewed-by: Matthias Brugger 
---
 drivers/memory/mtk-smi.c | 36 
 1 file changed, 36 insertions(+)

diff --git a/drivers/memory/mtk-smi.c b/drivers/memory/mtk-smi.c
index 47df7d0..53bd379 100644
--- a/drivers/memory/mtk-smi.c
+++ b/drivers/memory/mtk-smi.c
@@ -48,6 +48,7 @@ enum mtk_smi_gen {
 
 struct mtk_smi_common_plat {
enum mtk_smi_gen gen;
+   bool has_gals;
 };
 
 struct mtk_smi_larb_gen {
@@ -55,11 +56,13 @@ struct mtk_smi_larb_gen {
int port_in_larb[MTK_LARB_NR_MAX + 1];
void (*config_port)(struct device *);
unsigned intlarb_direct_to_common_mask;
+   boolhas_gals;
 };
 
 struct mtk_smi {
struct device   *dev;
struct clk  *clk_apb, *clk_smi;
+   struct clk  *clk_gals0, *clk_gals1;
struct clk  *clk_async; /*only needed by mt2701*/
void __iomem*smi_ao_base;
 
@@ -91,8 +94,20 @@ static int mtk_smi_enable(const struct mtk_smi *smi)
if (ret)
goto err_disable_apb;
 
+   ret = clk_prepare_enable(smi->clk_gals0);
+   if (ret)
+   goto err_disable_smi;
+
+   ret = clk_prepare_enable(smi->clk_gals1);
+   if (ret)
+   goto err_disable_gals0;
+
return 0;
 
+err_disable_gals0:
+   clk_disable_unprepare(smi->clk_gals0);
+err_disable_smi:
+   clk_disable_unprepare(smi->clk_smi);
 err_disable_apb:
clk_disable_unprepare(smi->clk_apb);
 err_put_pm:
@@ -102,6 +117,8 @@ static int mtk_smi_enable(const struct mtk_smi *smi)
 
 static void mtk_smi_disable(const struct mtk_smi *smi)
 {
+   clk_disable_unprepare(smi->clk_gals1);
+   clk_disable_unprepare(smi->clk_gals0);
clk_disable_unprepare(smi->clk_smi);
clk_disable_unprepare(smi->clk_apb);
pm_runtime_put_sync(smi->dev);
@@ -302,6 +319,15 @@ static int mtk_smi_larb_probe(struct platform_device *pdev)
larb->smi.clk_smi = devm_clk_get(dev, "smi");
if (IS_ERR(larb->smi.clk_smi))
return PTR_ERR(larb->smi.clk_smi);
+
+   if (larb->larb_gen->has_gals) {
+   /* The larbs may still haven't gals even if the SoC support.*/
+   larb->smi.clk_gals0 = devm_clk_get(dev, "gals");
+   if (PTR_ERR(larb->smi.clk_gals0) == -ENOENT)
+   larb->smi.clk_gals0 = NULL;
+   else if (IS_ERR(larb->smi.clk_gals0))
+   return PTR_ERR(larb->smi.clk_gals0);
+   }
larb->smi.dev = dev;
 
if (larb->larb_gen->need_larbid) {
@@ -394,6 +420,16 @@ static int mtk_smi_common_probe(struct platform_device 
*pdev)
if (IS_ERR(common->clk_smi))
return PTR_ERR(common->clk_smi);
 
+   if (common->plat->has_gals) {
+   common->clk_gals0 = devm_clk_get(dev, "gals0");
+   if (IS_ERR(common->clk_gals0))
+   return PTR_ERR(common->clk_gals0);
+
+   common->clk_gals1 = devm_clk_get(dev, "gals1");
+   if (IS_ERR(common->clk_gals1))
+   return PTR_ERR(common->clk_gals1);
+   }
+
/*
 * for mtk smi gen 1, we need to get the ao(always on) base to config
 * m4u port, and we need to enable the aync clock for transform the smi
-- 
1.9.1



[PATCH v9 13/21] iommu/mediatek: Move vld_pa_rng into plat_data

2019-08-10 Thread Yong Wu
Both mt8173 and mt8183 don't have this vld_pa_rng(valid physical address
range) register while mt2712 have. Move it into the plat_data.

Signed-off-by: Yong Wu 
Reviewed-by: Evan Green 
Reviewed-by: Matthias Brugger 
---
 drivers/iommu/mtk_iommu.c | 3 ++-
 drivers/iommu/mtk_iommu.h | 1 +
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index fce7b6d..790bad8 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -540,7 +540,7 @@ static int mtk_iommu_hw_init(const struct mtk_iommu_data 
*data)
 upper_32_bits(data->protect_base);
writel_relaxed(regval, data->base + REG_MMU_IVRP_PADDR);
 
-   if (data->enable_4GB && data->plat_data->m4u_plat != M4U_MT8173) {
+   if (data->enable_4GB && data->plat_data->has_vld_pa_rng) {
/*
 * If 4GB mode is enabled, the validate PA range is from
 * 0x1__ to 0x1__. here record bit[32:30].
@@ -739,6 +739,7 @@ static int __maybe_unused mtk_iommu_resume(struct device 
*dev)
.m4u_plat = M4U_MT2712,
.has_4gb_mode = true,
.has_bclk = true,
+   .has_vld_pa_rng   = true,
.larbid_remap = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9},
 };
 
diff --git a/drivers/iommu/mtk_iommu.h b/drivers/iommu/mtk_iommu.h
index 8d3b525..973d6e0 100644
--- a/drivers/iommu/mtk_iommu.h
+++ b/drivers/iommu/mtk_iommu.h
@@ -38,6 +38,7 @@ struct mtk_iommu_plat_data {
 
/* HW will use the EMI clock if there isn't the "bclk". */
boolhas_bclk;
+   boolhas_vld_pa_rng;
boolreset_axi;
unsigned char   larbid_remap[MTK_LARB_NR_MAX];
 };
-- 
1.9.1



[PATCH v9 15/21] iommu/mediatek: Add mt8183 IOMMU support

2019-08-10 Thread Yong Wu
The M4U IP blocks in mt8183 is MediaTek's generation2 M4U which use
the ARM Short-descriptor like mt8173, and most of the HW registers
are the same.

Here list main differences between mt8183 and mt8173/mt2712:
1) mt8183 has only one M4U HW like mt8173 while mt2712 has two.
2) mt8183 don't have the "bclk" clock, it use the EMI clock instead.
3) mt8183 can support the dram over 4GB, but it doesn't call this "4GB
mode".
4) mt8183 pgtable base register(0x0) extend bit[1:0] which represent
the bit[33:32] in the physical address of the pgtable base, But the
standard ttbr0[1] means the S bit which is enabled defaultly, Hence,
we add a mask.
5) mt8183 HW has a GALS modules, SMI should enable "has_gals" support.
6) mt8183 need reset_axi like mt8173.
7) the larb-id in smi-common is remapped. M4U should add its larbid_remap.

Signed-off-by: Yong Wu 
Reviewed-by: Evan Green 
Reviewed-by: Matthias Brugger 
---
 drivers/iommu/mtk_iommu.c | 15 ---
 drivers/iommu/mtk_iommu.h |  1 +
 drivers/memory/mtk-smi.c  | 20 
 3 files changed, 33 insertions(+), 3 deletions(-)

diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index 790bad8..550b093 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -28,6 +28,7 @@
 #include "mtk_iommu.h"
 
 #define REG_MMU_PT_BASE_ADDR   0x000
+#define MMU_PT_ADDR_MASK   GENMASK(31, 7)
 
 #define REG_MMU_INVALIDATE 0x020
 #define F_ALL_INVLD0x2
@@ -339,7 +340,7 @@ static int mtk_iommu_attach_device(struct iommu_domain 
*domain,
/* Update the pgtable base address register of the M4U HW */
if (!data->m4u_dom) {
data->m4u_dom = dom;
-   writel(dom->cfg.arm_v7s_cfg.ttbr[0],
+   writel(dom->cfg.arm_v7s_cfg.ttbr[0] & MMU_PT_ADDR_MASK,
   data->base + REG_MMU_PT_BASE_ADDR);
}
 
@@ -710,6 +711,7 @@ static int __maybe_unused mtk_iommu_resume(struct device 
*dev)
 {
struct mtk_iommu_data *data = dev_get_drvdata(dev);
struct mtk_iommu_suspend_reg *reg = >reg;
+   struct mtk_iommu_domain *m4u_dom = data->m4u_dom;
void __iomem *base = data->base;
int ret;
 
@@ -725,8 +727,8 @@ static int __maybe_unused mtk_iommu_resume(struct device 
*dev)
writel_relaxed(reg->int_control0, base + REG_MMU_INT_CONTROL0);
writel_relaxed(reg->int_main_control, base + REG_MMU_INT_MAIN_CONTROL);
writel_relaxed(reg->ivrp_paddr, base + REG_MMU_IVRP_PADDR);
-   if (data->m4u_dom)
-   writel(data->m4u_dom->cfg.arm_v7s_cfg.ttbr[0],
+   if (m4u_dom)
+   writel(m4u_dom->cfg.arm_v7s_cfg.ttbr[0] & MMU_PT_ADDR_MASK,
   base + REG_MMU_PT_BASE_ADDR);
return 0;
 }
@@ -751,9 +753,16 @@ static int __maybe_unused mtk_iommu_resume(struct device 
*dev)
.larbid_remap = {0, 1, 2, 3, 4, 5}, /* Linear mapping. */
 };
 
+static const struct mtk_iommu_plat_data mt8183_data = {
+   .m4u_plat = M4U_MT8183,
+   .reset_axi= true,
+   .larbid_remap = {0, 4, 5, 6, 7, 2, 3, 1},
+};
+
 static const struct of_device_id mtk_iommu_of_ids[] = {
{ .compatible = "mediatek,mt2712-m4u", .data = _data},
{ .compatible = "mediatek,mt8173-m4u", .data = _data},
+   { .compatible = "mediatek,mt8183-m4u", .data = _data},
{}
 };
 
diff --git a/drivers/iommu/mtk_iommu.h b/drivers/iommu/mtk_iommu.h
index 973d6e0..6b1f833 100644
--- a/drivers/iommu/mtk_iommu.h
+++ b/drivers/iommu/mtk_iommu.h
@@ -30,6 +30,7 @@ enum mtk_iommu_plat {
M4U_MT2701,
M4U_MT2712,
M4U_MT8173,
+   M4U_MT8183,
 };
 
 struct mtk_iommu_plat_data {
diff --git a/drivers/memory/mtk-smi.c b/drivers/memory/mtk-smi.c
index 53bd379..3dd05de 100644
--- a/drivers/memory/mtk-smi.c
+++ b/drivers/memory/mtk-smi.c
@@ -277,6 +277,13 @@ static void mtk_smi_larb_config_port_gen1(struct device 
*dev)
.larb_direct_to_common_mask = BIT(8) | BIT(9),  /* bdpsys */
 };
 
+static const struct mtk_smi_larb_gen mtk_smi_larb_mt8183 = {
+   .has_gals   = true,
+   .config_port= mtk_smi_larb_config_port_gen2_general,
+   .larb_direct_to_common_mask = BIT(2) | BIT(3) | BIT(7),
+ /* IPU0 | IPU1 | CCU */
+};
+
 static const struct of_device_id mtk_smi_larb_of_ids[] = {
{
.compatible = "mediatek,mt8173-smi-larb",
@@ -290,6 +297,10 @@ static void mtk_smi_larb_config_port_gen1(struct device 
*dev)
.compatible = "mediatek,mt2712-smi-larb",
.data = _smi_larb_mt2712
},
+   {
+   .compatible = "mediatek,mt8183-smi-larb",
+   .data = _smi_larb_mt8183
+   },
{}
 };
 
@@ -383,6 +394,11 @@ static int mtk_smi_larb_remove(struct platform_device 
*pdev)
.gen = MTK_SMI_GEN2,
 };
 
+static const struct mtk_smi_common_plat 

[PATCH v9 11/21] iommu/mediatek: Refine protect memory definition

2019-08-10 Thread Yong Wu
The protect memory setting is a little different in the different SoCs.
In the register REG_MMU_CTRL_REG(0x110), the TF_PROT(translation fault
protect) shift bit is normally 4 while it shift 5 bits only in the
mt8173. This patch delete the complex MACRO and use a common if-else
instead.

Signed-off-by: Yong Wu 
Reviewed-by: Evan Green 
Reviewed-by: Matthias Brugger 
---
 drivers/iommu/mtk_iommu.c | 13 ++---
 1 file changed, 6 insertions(+), 7 deletions(-)

diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index 1b16efc..066a485 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -44,12 +44,9 @@
 #define REG_MMU_DCM_DIS0x050
 
 #define REG_MMU_CTRL_REG   0x110
+#define F_MMU_TF_PROT_TO_PROGRAM_ADDR  (2 << 4)
 #define F_MMU_PREFETCH_RT_REPLACE_MOD  BIT(4)
-#define F_MMU_TF_PROTECT_SEL_SHIFT(data) \
-   ((data)->plat_data->m4u_plat == M4U_MT2712 ? 4 : 5)
-/* It's named by F_MMU_TF_PROT_SEL in mt2712. */
-#define F_MMU_TF_PROTECT_SEL(prot, data) \
-   (((prot) & 0x3) << F_MMU_TF_PROTECT_SEL_SHIFT(data))
+#define F_MMU_TF_PROT_TO_PROGRAM_ADDR_MT8173   (2 << 5)
 
 #define REG_MMU_IVRP_PADDR 0x114
 
@@ -512,9 +509,11 @@ static int mtk_iommu_hw_init(const struct mtk_iommu_data 
*data)
return ret;
}
 
-   regval = F_MMU_TF_PROTECT_SEL(2, data);
if (data->plat_data->m4u_plat == M4U_MT8173)
-   regval |= F_MMU_PREFETCH_RT_REPLACE_MOD;
+   regval = F_MMU_PREFETCH_RT_REPLACE_MOD |
+F_MMU_TF_PROT_TO_PROGRAM_ADDR_MT8173;
+   else
+   regval = F_MMU_TF_PROT_TO_PROGRAM_ADDR;
writel_relaxed(regval, data->base + REG_MMU_CTRL_REG);
 
regval = F_L2_MULIT_HIT_EN |
-- 
1.9.1

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


[PATCH v9 09/21] iommu/mediatek: Add bclk can be supported optionally

2019-08-10 Thread Yong Wu
In some SoCs, M4U doesn't have its "bclk", it will use the EMI
clock instead which has always been enabled when entering kernel.

Currently mt2712 and mt8173 have this bclk while mt8183 doesn't.

This also is a preparing patch for mt8183.

Signed-off-by: Yong Wu 
Reviewed-by: Evan Green 
Reviewed-by: Matthias Brugger 
---
 drivers/iommu/mtk_iommu.c | 10 +++---
 drivers/iommu/mtk_iommu.h |  3 +++
 2 files changed, 10 insertions(+), 3 deletions(-)

diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index 1a37db0..3f92d27 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -606,9 +606,11 @@ static int mtk_iommu_probe(struct platform_device *pdev)
if (data->irq < 0)
return data->irq;
 
-   data->bclk = devm_clk_get(dev, "bclk");
-   if (IS_ERR(data->bclk))
-   return PTR_ERR(data->bclk);
+   if (data->plat_data->has_bclk) {
+   data->bclk = devm_clk_get(dev, "bclk");
+   if (IS_ERR(data->bclk))
+   return PTR_ERR(data->bclk);
+   }
 
larb_nr = of_count_phandle_with_args(dev->of_node,
 "mediatek,larbs", NULL);
@@ -736,11 +738,13 @@ static int __maybe_unused mtk_iommu_resume(struct device 
*dev)
 static const struct mtk_iommu_plat_data mt2712_data = {
.m4u_plat = M4U_MT2712,
.has_4gb_mode = true,
+   .has_bclk = true,
 };
 
 static const struct mtk_iommu_plat_data mt8173_data = {
.m4u_plat = M4U_MT8173,
.has_4gb_mode = true,
+   .has_bclk = true,
 };
 
 static const struct of_device_id mtk_iommu_of_ids[] = {
diff --git a/drivers/iommu/mtk_iommu.h b/drivers/iommu/mtk_iommu.h
index c281c01..821172b 100644
--- a/drivers/iommu/mtk_iommu.h
+++ b/drivers/iommu/mtk_iommu.h
@@ -35,6 +35,9 @@ enum mtk_iommu_plat {
 struct mtk_iommu_plat_data {
enum mtk_iommu_plat m4u_plat;
boolhas_4gb_mode;
+
+   /* HW will use the EMI clock if there isn't the "bclk". */
+   boolhas_bclk;
 };
 
 struct mtk_iommu_domain;
-- 
1.9.1

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


[PATCH v9 10/21] iommu/mediatek: Add larb-id remapped support

2019-08-10 Thread Yong Wu
The larb-id may be remapped in the smi-common, this means the
larb-id reported in the mtk_iommu_isr isn't the real larb-id,

Take mt8183 as a example:
   M4U
|
-
|   SMI common  |
-0-7-5-6-1-2--3-4- <- Id remapped
 | | | | | |  | |
larb0 larb1 IPU0  IPU1 larb4 larb5  larb6  CCU
disp  vdec  img   cam   venc  imgcam
As above, larb0 connects with the id 0 in smi-common.
  larb1 connects with the id 7 in smi-common.
  ...
If the larb-id reported in the isr is 7, actually it's larb1(vdec).
In order to output the right larb-id in the isr, we add a larb-id
remapping relationship in this patch.

If there is no this larb-id remapping in some SoCs, use the linear
mapping array instead.

This also is a preparing patch for mt8183.

Signed-off-by: Yong Wu 
Reviewed-by: Nicolas Boichat 
Reviewed-by: Evan Green 
Reviewed-by: Matthias Brugger 
---
 drivers/iommu/mtk_iommu.c | 4 
 drivers/iommu/mtk_iommu.h | 2 ++
 2 files changed, 6 insertions(+)

diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index 3f92d27..1b16efc 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -212,6 +212,8 @@ static irqreturn_t mtk_iommu_isr(int irq, void *dev_id)
fault_larb = F_MMU0_INT_ID_LARB_ID(regval);
fault_port = F_MMU0_INT_ID_PORT_ID(regval);
 
+   fault_larb = data->plat_data->larbid_remap[fault_larb];
+
if (report_iommu_fault(>domain, data->dev, fault_iova,
   write ? IOMMU_FAULT_WRITE : IOMMU_FAULT_READ)) {
dev_err_ratelimited(
@@ -739,12 +741,14 @@ static int __maybe_unused mtk_iommu_resume(struct device 
*dev)
.m4u_plat = M4U_MT2712,
.has_4gb_mode = true,
.has_bclk = true,
+   .larbid_remap = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9},
 };
 
 static const struct mtk_iommu_plat_data mt8173_data = {
.m4u_plat = M4U_MT8173,
.has_4gb_mode = true,
.has_bclk = true,
+   .larbid_remap = {0, 1, 2, 3, 4, 5}, /* Linear mapping. */
 };
 
 static const struct of_device_id mtk_iommu_of_ids[] = {
diff --git a/drivers/iommu/mtk_iommu.h b/drivers/iommu/mtk_iommu.h
index 821172b..d1a1d88 100644
--- a/drivers/iommu/mtk_iommu.h
+++ b/drivers/iommu/mtk_iommu.h
@@ -38,6 +38,8 @@ struct mtk_iommu_plat_data {
 
/* HW will use the EMI clock if there isn't the "bclk". */
boolhas_bclk;
+
+   unsigned char   larbid_remap[MTK_LARB_NR_MAX];
 };
 
 struct mtk_iommu_domain;
-- 
1.9.1

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


[PATCH v9 08/21] iommu/io-pgtable-arm-v7s: Extend MediaTek 4GB Mode

2019-08-10 Thread Yong Wu
MediaTek extend the arm v7s descriptor to support the dram over 4GB.

In the mt2712 and mt8173, it's called "4GB mode", the physical address
is from 0x4000_ to 0x1_3fff_, but from EMI point of view, it
is remapped to high address from 0x1__ to 0x1__, the
bit32 is always enabled. thus, in the M4U, we always enable the bit9
for all PTEs which means to enable bit32 of physical address. Here is
the detailed remap relationship in the "4GB mode":
CPU PA ->HW PA
0x4000_  0x1_4000_ (Add bit32)
0x8000_  0x1_8000_ ...
0xc000_  0x1_c000_ ...
0x1__0x1__ (No change)

but in mt8183, M4U support the dram from 0x4000_ to 0x3__
which isn't remaped. We extend the PTEs: the bit9 represent bit32 of
PA and the bit4 represent bit33 of PA. Meanwhile the iova still is
32bits.

The "4GB mode" is so special, it always add bit32 in paddr_to_iopte and
it only add bit32 while pa < 0x4000UL in the iopte_to_paddr since the
valid pa is from 0x4000_ to 0x1_3fff_. Thus I add a special macro
ARM_V7S_MTK_4GB_OAS(oas: 33) for "4GB mode".

Regarding whether the pagetable address could be over 4GB, the mt8183
support it while the previous mt8173 don't. thus keep it as is.

Signed-off-by: Yong Wu 
---
 drivers/iommu/io-pgtable-arm-v7s.c | 36 +---
 drivers/iommu/mtk_iommu.c  | 23 +--
 drivers/iommu/mtk_iommu.h  |  1 +
 include/linux/io-pgtable.h |  9 +
 4 files changed, 48 insertions(+), 21 deletions(-)

diff --git a/drivers/iommu/io-pgtable-arm-v7s.c 
b/drivers/iommu/io-pgtable-arm-v7s.c
index 77cc1eb..ab12ef5 100644
--- a/drivers/iommu/io-pgtable-arm-v7s.c
+++ b/drivers/iommu/io-pgtable-arm-v7s.c
@@ -112,7 +112,9 @@
 #define ARM_V7S_TEX_MASK   0x7
 #define ARM_V7S_ATTR_TEX(val)  (((val) & ARM_V7S_TEX_MASK) << 
ARM_V7S_TEX_SHIFT)
 
-#define ARM_V7S_ATTR_MTK_4GB   BIT(9) /* MTK extend it for 4GB mode */
+/* MediaTek extend the two bits for PA 32bit/33bit */
+#define ARM_V7S_ATTR_MTK_PA_BIT32  BIT(9)
+#define ARM_V7S_ATTR_MTK_PA_BIT33  BIT(4)
 
 /* *well, except for TEX on level 2 large pages, of course :( */
 #define ARM_V7S_CONT_PAGE_TEX_SHIFT6
@@ -179,13 +181,22 @@ static dma_addr_t __arm_v7s_dma_addr(void *pages)
 static arm_v7s_iopte paddr_to_iopte(phys_addr_t paddr, int lvl,
struct io_pgtable_cfg *cfg)
 {
-   return paddr & ARM_V7S_LVL_MASK(lvl);
+   arm_v7s_iopte pte = paddr & ARM_V7S_LVL_MASK(lvl);
+
+   if (cfg->quirks & IO_PGTABLE_QUIRK_ARM_MTK_EXT) {
+   if ((paddr & BIT_ULL(32)) || cfg->oas == ARM_V7S_MTK_4GB_OAS)
+   pte |= ARM_V7S_ATTR_MTK_PA_BIT32;
+   if (paddr & BIT_ULL(33))
+   pte |= ARM_V7S_ATTR_MTK_PA_BIT33;
+   }
+   return pte;
 }
 
 static phys_addr_t iopte_to_paddr(arm_v7s_iopte pte, int lvl,
  struct io_pgtable_cfg *cfg)
 {
arm_v7s_iopte mask;
+   phys_addr_t paddr;
 
if (ARM_V7S_PTE_IS_TABLE(pte, lvl))
mask = ARM_V7S_TABLE_MASK;
@@ -194,7 +205,19 @@ static phys_addr_t iopte_to_paddr(arm_v7s_iopte pte, int 
lvl,
else
mask = ARM_V7S_LVL_MASK(lvl);
 
-   return pte & mask;
+   paddr = pte & mask;
+   if (cfg->oas == 32 || !(cfg->quirks & IO_PGTABLE_QUIRK_ARM_MTK_EXT))
+   return paddr;
+
+   if (pte & ARM_V7S_ATTR_MTK_PA_BIT33)
+   paddr |= BIT_ULL(33);
+
+   /* Workaround for MTK 4GB Mode: Add BIT32 only when PA < 0x4000_.*/
+   if (cfg->oas == ARM_V7S_MTK_4GB_OAS && paddr < 0x4000UL)
+   paddr |= BIT_ULL(32);
+   else if (pte & ARM_V7S_ATTR_MTK_PA_BIT32)
+   paddr |= BIT_ULL(32);
+   return paddr;
 }
 
 static arm_v7s_iopte *iopte_deref(arm_v7s_iopte pte, int lvl,
@@ -315,9 +338,6 @@ static arm_v7s_iopte arm_v7s_prot_to_pte(int prot, int lvl,
if (lvl == 1 && (cfg->quirks & IO_PGTABLE_QUIRK_ARM_NS))
pte |= ARM_V7S_ATTR_NS_SECTION;
 
-   if (cfg->quirks & IO_PGTABLE_QUIRK_ARM_MTK_EXT)
-   pte |= ARM_V7S_ATTR_MTK_4GB;
-
return pte;
 }
 
@@ -731,7 +751,9 @@ static struct io_pgtable *arm_v7s_alloc_pgtable(struct 
io_pgtable_cfg *cfg,
 {
struct arm_v7s_io_pgtable *data;
 
-   if (cfg->ias > ARM_V7S_ADDR_BITS || cfg->oas > ARM_V7S_ADDR_BITS)
+   if (cfg->ias > ARM_V7S_ADDR_BITS ||
+   (cfg->oas > ARM_V7S_ADDR_BITS &&
+!(cfg->quirks & IO_PGTABLE_QUIRK_ARM_MTK_EXT)))
return NULL;
 
if (cfg->quirks & ~(IO_PGTABLE_QUIRK_ARM_NS |
diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index 8300489..1a37db0 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -263,16 +263,20 @@ static int mtk_iommu_domain_finalise(struct 
mtk_iommu_domain *dom)
  

[PATCH v9 12/21] iommu/mediatek: Move reset_axi into plat_data

2019-08-10 Thread Yong Wu
In mt8173 and mt8183, 0x48 is REG_MMU_STANDARD_AXI_MODE while it is
REG_MMU_CTRL in the other SoCs, and the bits meaning is completely
different with the REG_MMU_STANDARD_AXI_MODE.

This patch moves this property to plat_data, it's also a preparing
patch for mt8183.

Signed-off-by: Yong Wu 
Reviewed-by: Nicolas Boichat 
Reviewed-by: Evan Green 
Reviewed-by: Matthias Brugger 
---
 drivers/iommu/mtk_iommu.c | 4 ++--
 drivers/iommu/mtk_iommu.h | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index 066a485..fce7b6d 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -550,8 +550,7 @@ static int mtk_iommu_hw_init(const struct mtk_iommu_data 
*data)
}
writel_relaxed(0, data->base + REG_MMU_DCM_DIS);
 
-   /* It's MISC control register whose default value is ok except mt8173.*/
-   if (data->plat_data->m4u_plat == M4U_MT8173)
+   if (data->plat_data->reset_axi)
writel_relaxed(0, data->base + REG_MMU_STANDARD_AXI_MODE);
 
if (devm_request_irq(data->dev, data->irq, mtk_iommu_isr, 0,
@@ -747,6 +746,7 @@ static int __maybe_unused mtk_iommu_resume(struct device 
*dev)
.m4u_plat = M4U_MT8173,
.has_4gb_mode = true,
.has_bclk = true,
+   .reset_axi= true,
.larbid_remap = {0, 1, 2, 3, 4, 5}, /* Linear mapping. */
 };
 
diff --git a/drivers/iommu/mtk_iommu.h b/drivers/iommu/mtk_iommu.h
index d1a1d88..8d3b525 100644
--- a/drivers/iommu/mtk_iommu.h
+++ b/drivers/iommu/mtk_iommu.h
@@ -38,7 +38,7 @@ struct mtk_iommu_plat_data {
 
/* HW will use the EMI clock if there isn't the "bclk". */
boolhas_bclk;
-
+   boolreset_axi;
unsigned char   larbid_remap[MTK_LARB_NR_MAX];
 };
 
-- 
1.9.1

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


[PATCH v9 05/21] iommu/io-pgtable-arm-v7s: Add paddr_to_iopte and iopte_to_paddr helpers

2019-08-10 Thread Yong Wu
Add two helper functions: paddr_to_iopte and iopte_to_paddr.

Signed-off-by: Yong Wu 
Reviewed-by: Robin Murphy 
Reviewed-by: Evan Green 
---
 drivers/iommu/io-pgtable-arm-v7s.c | 45 --
 1 file changed, 33 insertions(+), 12 deletions(-)

diff --git a/drivers/iommu/io-pgtable-arm-v7s.c 
b/drivers/iommu/io-pgtable-arm-v7s.c
index 0fc8dfa..72f1880 100644
--- a/drivers/iommu/io-pgtable-arm-v7s.c
+++ b/drivers/iommu/io-pgtable-arm-v7s.c
@@ -169,18 +169,38 @@ struct arm_v7s_io_pgtable {
spinlock_t  split_lock;
 };
 
+static bool arm_v7s_pte_is_cont(arm_v7s_iopte pte, int lvl);
+
 static dma_addr_t __arm_v7s_dma_addr(void *pages)
 {
return (dma_addr_t)virt_to_phys(pages);
 }
 
-static arm_v7s_iopte *iopte_deref(arm_v7s_iopte pte, int lvl)
+static arm_v7s_iopte paddr_to_iopte(phys_addr_t paddr, int lvl,
+   struct io_pgtable_cfg *cfg)
 {
+   return paddr & ARM_V7S_LVL_MASK(lvl);
+}
+
+static phys_addr_t iopte_to_paddr(arm_v7s_iopte pte, int lvl,
+ struct io_pgtable_cfg *cfg)
+{
+   arm_v7s_iopte mask;
+
if (ARM_V7S_PTE_IS_TABLE(pte, lvl))
-   pte &= ARM_V7S_TABLE_MASK;
+   mask = ARM_V7S_TABLE_MASK;
+   else if (arm_v7s_pte_is_cont(pte, lvl))
+   mask = ARM_V7S_LVL_MASK(lvl) * ARM_V7S_CONT_PAGES;
else
-   pte &= ARM_V7S_LVL_MASK(lvl);
-   return phys_to_virt(pte);
+   mask = ARM_V7S_LVL_MASK(lvl);
+
+   return pte & mask;
+}
+
+static arm_v7s_iopte *iopte_deref(arm_v7s_iopte pte, int lvl,
+ struct arm_v7s_io_pgtable *data)
+{
+   return phys_to_virt(iopte_to_paddr(pte, lvl, >iop.cfg));
 }
 
 static void *__arm_v7s_alloc_table(int lvl, gfp_t gfp,
@@ -396,7 +416,7 @@ static int arm_v7s_init_pte(struct arm_v7s_io_pgtable *data,
if (num_entries > 1)
pte = arm_v7s_pte_to_cont(pte, lvl);
 
-   pte |= paddr & ARM_V7S_LVL_MASK(lvl);
+   pte |= paddr_to_iopte(paddr, lvl, cfg);
 
__arm_v7s_set_pte(ptep, pte, num_entries, cfg);
return 0;
@@ -462,7 +482,7 @@ static int __arm_v7s_map(struct arm_v7s_io_pgtable *data, 
unsigned long iova,
}
 
if (ARM_V7S_PTE_IS_TABLE(pte, lvl)) {
-   cptep = iopte_deref(pte, lvl);
+   cptep = iopte_deref(pte, lvl, data);
} else if (pte) {
/* We require an unmap first */
WARN_ON(!selftest_running);
@@ -512,7 +532,8 @@ static void arm_v7s_free_pgtable(struct io_pgtable *iop)
arm_v7s_iopte pte = data->pgd[i];
 
if (ARM_V7S_PTE_IS_TABLE(pte, 1))
-   __arm_v7s_free_table(iopte_deref(pte, 1), 2, data);
+   __arm_v7s_free_table(iopte_deref(pte, 1, data),
+2, data);
}
__arm_v7s_free_table(data->pgd, 1, data);
kmem_cache_destroy(data->l2_tables);
@@ -582,7 +603,7 @@ static size_t arm_v7s_split_blk_unmap(struct 
arm_v7s_io_pgtable *data,
if (!ARM_V7S_PTE_IS_TABLE(pte, 1))
return 0;
 
-   tablep = iopte_deref(pte, 1);
+   tablep = iopte_deref(pte, 1, data);
return __arm_v7s_unmap(data, iova, size, 2, tablep);
}
 
@@ -641,7 +662,7 @@ static size_t __arm_v7s_unmap(struct arm_v7s_io_pgtable 
*data,
io_pgtable_tlb_add_flush(iop, iova, blk_size,
ARM_V7S_BLOCK_SIZE(lvl + 1), false);
io_pgtable_tlb_sync(iop);
-   ptep = iopte_deref(pte[i], lvl);
+   ptep = iopte_deref(pte[i], lvl, data);
__arm_v7s_free_table(ptep, lvl + 1, data);
} else if (iop->cfg.quirks & 
IO_PGTABLE_QUIRK_NON_STRICT) {
/*
@@ -666,7 +687,7 @@ static size_t __arm_v7s_unmap(struct arm_v7s_io_pgtable 
*data,
}
 
/* Keep on walkin' */
-   ptep = iopte_deref(pte[0], lvl);
+   ptep = iopte_deref(pte[0], lvl, data);
return __arm_v7s_unmap(data, iova, size, lvl + 1, ptep);
 }
 
@@ -692,7 +713,7 @@ static phys_addr_t arm_v7s_iova_to_phys(struct 
io_pgtable_ops *ops,
do {
ptep += ARM_V7S_LVL_IDX(iova, ++lvl);
pte = READ_ONCE(*ptep);
-   ptep = iopte_deref(pte, lvl);
+   ptep = iopte_deref(pte, lvl, data);
} while (ARM_V7S_PTE_IS_TABLE(pte, lvl));
 
if (!ARM_V7S_PTE_IS_VALID(pte))
@@ -701,7 +722,7 @@ static phys_addr_t arm_v7s_iova_to_phys(struct 
io_pgtable_ops *ops,
mask = ARM_V7S_LVL_MASK(lvl);
if (arm_v7s_pte_is_cont(pte, lvl))
mask *= ARM_V7S_CONT_PAGES;
-   return (pte & mask) | (iova & ~mask);
+   return iopte_to_paddr(pte, lvl, >iop.cfg) | (iova & 

[PATCH v9 07/21] iommu/io-pgtable-arm-v7s: Rename the quirk from MTK_4GB to MTK_EXT

2019-08-10 Thread Yong Wu
In previous mt2712/mt8173, MediaTek extend the v7s to support 4GB dram.
But in the latest mt8183, We extend it to support the PA that reach 33bit.
Then the "MTK_4GB" name is not so fit, This patch only change the quirk name
to "MTK_EXT".

Signed-off-by: Yong Wu 
---
 drivers/iommu/io-pgtable-arm-v7s.c | 6 +++---
 drivers/iommu/mtk_iommu.c  | 2 +-
 include/linux/io-pgtable.h | 4 ++--
 3 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/iommu/io-pgtable-arm-v7s.c 
b/drivers/iommu/io-pgtable-arm-v7s.c
index fa1b38f..77cc1eb 100644
--- a/drivers/iommu/io-pgtable-arm-v7s.c
+++ b/drivers/iommu/io-pgtable-arm-v7s.c
@@ -315,7 +315,7 @@ static arm_v7s_iopte arm_v7s_prot_to_pte(int prot, int lvl,
if (lvl == 1 && (cfg->quirks & IO_PGTABLE_QUIRK_ARM_NS))
pte |= ARM_V7S_ATTR_NS_SECTION;
 
-   if (cfg->quirks & IO_PGTABLE_QUIRK_ARM_MTK_4GB)
+   if (cfg->quirks & IO_PGTABLE_QUIRK_ARM_MTK_EXT)
pte |= ARM_V7S_ATTR_MTK_4GB;
 
return pte;
@@ -737,12 +737,12 @@ static struct io_pgtable *arm_v7s_alloc_pgtable(struct 
io_pgtable_cfg *cfg,
if (cfg->quirks & ~(IO_PGTABLE_QUIRK_ARM_NS |
IO_PGTABLE_QUIRK_NO_PERMS |
IO_PGTABLE_QUIRK_TLBI_ON_MAP |
-   IO_PGTABLE_QUIRK_ARM_MTK_4GB |
+   IO_PGTABLE_QUIRK_ARM_MTK_EXT |
IO_PGTABLE_QUIRK_NON_STRICT))
return NULL;
 
/* If ARM_MTK_4GB is enabled, the NO_PERMS is also expected. */
-   if (cfg->quirks & IO_PGTABLE_QUIRK_ARM_MTK_4GB &&
+   if (cfg->quirks & IO_PGTABLE_QUIRK_ARM_MTK_EXT &&
!(cfg->quirks & IO_PGTABLE_QUIRK_NO_PERMS))
return NULL;
 
diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index c6e6dc3..8300489 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -272,7 +272,7 @@ static int mtk_iommu_domain_finalise(struct 
mtk_iommu_domain *dom)
};
 
if (data->enable_4GB)
-   dom->cfg.quirks |= IO_PGTABLE_QUIRK_ARM_MTK_4GB;
+   dom->cfg.quirks |= IO_PGTABLE_QUIRK_ARM_MTK_EXT;
 
dom->iop = alloc_io_pgtable_ops(ARM_V7S, >cfg, data);
if (!dom->iop) {
diff --git a/include/linux/io-pgtable.h b/include/linux/io-pgtable.h
index b5a450a..915fb73 100644
--- a/include/linux/io-pgtable.h
+++ b/include/linux/io-pgtable.h
@@ -65,7 +65,7 @@ struct io_pgtable_cfg {
 *  (unmapped) entries but the hardware might do so anyway, perform
 *  TLB maintenance when mapping as well as when unmapping.
 *
-* IO_PGTABLE_QUIRK_ARM_MTK_4GB: (ARM v7s format) Set bit 9 in all
+* IO_PGTABLE_QUIRK_ARM_MTK_EXT: (ARM v7s format) Set bit 9 in all
 *  PTEs, for Mediatek IOMMUs which treat it as a 33rd address bit
 *  when the SoC is in "4GB mode" and they can only access the high
 *  remap of DRAM (0x1_ to 0x1_).
@@ -77,7 +77,7 @@ struct io_pgtable_cfg {
#define IO_PGTABLE_QUIRK_ARM_NS BIT(0)
#define IO_PGTABLE_QUIRK_NO_PERMS   BIT(1)
#define IO_PGTABLE_QUIRK_TLBI_ON_MAPBIT(2)
-   #define IO_PGTABLE_QUIRK_ARM_MTK_4GBBIT(3)
+   #define IO_PGTABLE_QUIRK_ARM_MTK_EXTBIT(3)
#define IO_PGTABLE_QUIRK_NON_STRICT BIT(4)
unsigned long   quirks;
unsigned long   pgsize_bitmap;
-- 
1.9.1



[PATCH v9 03/21] memory: mtk-smi: Use a general config_port interface

2019-08-10 Thread Yong Wu
The config_port of mt2712 and mt8183 are the same. Use a general
config_port interface instead.

In addition, in mt2712, larb8 and larb9 are the bdpsys larbs which
are not the normal larb, their register space are different from the
normal one. thus, we can not call the general config_port. In mt8183,
IPU0/1 and CCU connect with smi-common directly, they also are not
the normal larb. Hence, we add a "larb_direct_to_common_mask" for these
larbs which connect to smi-commmon directly.

This is also a preparing patch for adding mt8183 SMI support.

Signed-off-by: Yong Wu 
Reviewed-by: Matthias Brugger 
Reviewed-by: Evan Green 
---
 drivers/memory/mtk-smi.c | 12 +---
 1 file changed, 5 insertions(+), 7 deletions(-)

diff --git a/drivers/memory/mtk-smi.c b/drivers/memory/mtk-smi.c
index 42ab43a..14f70cf 100644
--- a/drivers/memory/mtk-smi.c
+++ b/drivers/memory/mtk-smi.c
@@ -45,6 +45,7 @@ struct mtk_smi_larb_gen {
bool need_larbid;
int port_in_larb[MTK_LARB_NR_MAX + 1];
void (*config_port)(struct device *);
+   unsigned intlarb_direct_to_common_mask;
 };
 
 struct mtk_smi {
@@ -168,17 +169,13 @@ void mtk_smi_larb_put(struct device *larbdev)
return -ENODEV;
 }
 
-static void mtk_smi_larb_config_port_mt2712(struct device *dev)
+static void mtk_smi_larb_config_port_gen2_general(struct device *dev)
 {
struct mtk_smi_larb *larb = dev_get_drvdata(dev);
u32 reg;
int i;
 
-   /*
-* larb 8/9 is the bdpsys larb, the iommu_en is enabled defaultly.
-* Don't need to set it again.
-*/
-   if (larb->larbid == 8 || larb->larbid == 9)
+   if (BIT(larb->larbid) & larb->larb_gen->larb_direct_to_common_mask)
return;
 
for_each_set_bit(i, (unsigned long *)larb->mmu, 32) {
@@ -253,7 +250,8 @@ static void mtk_smi_larb_config_port_gen1(struct device 
*dev)
 
 static const struct mtk_smi_larb_gen mtk_smi_larb_mt2712 = {
.need_larbid = true,
-   .config_port = mtk_smi_larb_config_port_mt2712,
+   .config_port= mtk_smi_larb_config_port_gen2_general,
+   .larb_direct_to_common_mask = BIT(8) | BIT(9),  /* bdpsys */
 };
 
 static const struct of_device_id mtk_smi_larb_of_ids[] = {
-- 
1.9.1

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


[PATCH v9 06/21] iommu/io-pgtable-arm-v7s: Use ias/oas to check the valid iova/pa

2019-08-10 Thread Yong Wu
Use ias/oas to check the valid iova/pa. Synchronize this checking with
io-pgtable-arm.c.

Signed-off-by: Yong Wu 
---
 drivers/iommu/io-pgtable-arm-v7s.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/iommu/io-pgtable-arm-v7s.c 
b/drivers/iommu/io-pgtable-arm-v7s.c
index 72f1880..fa1b38f 100644
--- a/drivers/iommu/io-pgtable-arm-v7s.c
+++ b/drivers/iommu/io-pgtable-arm-v7s.c
@@ -504,7 +504,8 @@ static int arm_v7s_map(struct io_pgtable_ops *ops, unsigned 
long iova,
if (!(prot & (IOMMU_READ | IOMMU_WRITE)))
return 0;
 
-   if (WARN_ON(upper_32_bits(iova) || upper_32_bits(paddr)))
+   if (WARN_ON(iova >= (1ULL << data->iop.cfg.ias) ||
+   paddr >= (1ULL << data->iop.cfg.oas)))
return -ERANGE;
 
ret = __arm_v7s_map(data, iova, paddr, size, prot, 1, data->pgd);
-- 
1.9.1

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


[PATCH v9 04/21] memory: mtk-smi: Use a struct for the platform data for smi-common

2019-08-10 Thread Yong Wu
Use a struct as the platform special data instead of the enumeration.

Also there is a minor change that moving the position of
"enum mtk_smi_gen" definition, this is because we expect define
"struct mtk_smi_common_plat" before it is referred.

This is a preparing patch for mt8183.

Signed-off-by: Yong Wu 
Reviewed-by: Matthias Brugger 
Reviewed-by: Evan Green 
---
 drivers/memory/mtk-smi.c | 35 ---
 1 file changed, 24 insertions(+), 11 deletions(-)

diff --git a/drivers/memory/mtk-smi.c b/drivers/memory/mtk-smi.c
index 14f70cf..47df7d0 100644
--- a/drivers/memory/mtk-smi.c
+++ b/drivers/memory/mtk-smi.c
@@ -41,6 +41,15 @@
 #define SMI_LARB_NONSEC_CON(id)(0x380 + ((id) * 4))
 #define F_MMU_EN   BIT(0)
 
+enum mtk_smi_gen {
+   MTK_SMI_GEN1,
+   MTK_SMI_GEN2
+};
+
+struct mtk_smi_common_plat {
+   enum mtk_smi_gen gen;
+};
+
 struct mtk_smi_larb_gen {
bool need_larbid;
int port_in_larb[MTK_LARB_NR_MAX + 1];
@@ -53,6 +62,8 @@ struct mtk_smi {
struct clk  *clk_apb, *clk_smi;
struct clk  *clk_async; /*only needed by mt2701*/
void __iomem*smi_ao_base;
+
+   const struct mtk_smi_common_plat *plat;
 };
 
 struct mtk_smi_larb { /* larb: local arbiter */
@@ -64,11 +75,6 @@ struct mtk_smi_larb { /* larb: local arbiter */
u32 *mmu;
 };
 
-enum mtk_smi_gen {
-   MTK_SMI_GEN1,
-   MTK_SMI_GEN2
-};
-
 static int mtk_smi_enable(const struct mtk_smi *smi)
 {
int ret;
@@ -343,18 +349,26 @@ static int mtk_smi_larb_remove(struct platform_device 
*pdev)
}
 };
 
+static const struct mtk_smi_common_plat mtk_smi_common_gen1 = {
+   .gen = MTK_SMI_GEN1,
+};
+
+static const struct mtk_smi_common_plat mtk_smi_common_gen2 = {
+   .gen = MTK_SMI_GEN2,
+};
+
 static const struct of_device_id mtk_smi_common_of_ids[] = {
{
.compatible = "mediatek,mt8173-smi-common",
-   .data = (void *)MTK_SMI_GEN2
+   .data = _smi_common_gen2,
},
{
.compatible = "mediatek,mt2701-smi-common",
-   .data = (void *)MTK_SMI_GEN1
+   .data = _smi_common_gen1,
},
{
.compatible = "mediatek,mt2712-smi-common",
-   .data = (void *)MTK_SMI_GEN2
+   .data = _smi_common_gen2,
},
{}
 };
@@ -364,13 +378,13 @@ static int mtk_smi_common_probe(struct platform_device 
*pdev)
struct device *dev = >dev;
struct mtk_smi *common;
struct resource *res;
-   enum mtk_smi_gen smi_gen;
int ret;
 
common = devm_kzalloc(dev, sizeof(*common), GFP_KERNEL);
if (!common)
return -ENOMEM;
common->dev = dev;
+   common->plat = of_device_get_match_data(dev);
 
common->clk_apb = devm_clk_get(dev, "apb");
if (IS_ERR(common->clk_apb))
@@ -386,8 +400,7 @@ static int mtk_smi_common_probe(struct platform_device 
*pdev)
 * clock into emi clock domain, but for mtk smi gen2, there's no smi ao
 * base.
 */
-   smi_gen = (enum mtk_smi_gen)of_device_get_match_data(dev);
-   if (smi_gen == MTK_SMI_GEN1) {
+   if (common->plat->gen == MTK_SMI_GEN1) {
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
common->smi_ao_base = devm_ioremap_resource(dev, res);
if (IS_ERR(common->smi_ao_base))
-- 
1.9.1

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


[PATCH v9 02/21] iommu/mediatek: Use a struct as the platform data

2019-08-10 Thread Yong Wu
Use a struct as the platform special data instead of the enumeration.
This is a prepare patch for adding mt8183 iommu support.

Signed-off-by: Yong Wu 
Reviewed-by: Matthias Brugger 
Reviewed-by: Evan Green 
---
 drivers/iommu/mtk_iommu.c | 24 
 drivers/iommu/mtk_iommu.h |  6 +-
 2 files changed, 21 insertions(+), 9 deletions(-)

diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index 82e4be4..c6e6dc3 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -46,7 +46,7 @@
 #define REG_MMU_CTRL_REG   0x110
 #define F_MMU_PREFETCH_RT_REPLACE_MOD  BIT(4)
 #define F_MMU_TF_PROTECT_SEL_SHIFT(data) \
-   ((data)->m4u_plat == M4U_MT2712 ? 4 : 5)
+   ((data)->plat_data->m4u_plat == M4U_MT2712 ? 4 : 5)
 /* It's named by F_MMU_TF_PROT_SEL in mt2712. */
 #define F_MMU_TF_PROTECT_SEL(prot, data) \
(((prot) & 0x3) << F_MMU_TF_PROTECT_SEL_SHIFT(data))
@@ -512,7 +512,7 @@ static int mtk_iommu_hw_init(const struct mtk_iommu_data 
*data)
}
 
regval = F_MMU_TF_PROTECT_SEL(2, data);
-   if (data->m4u_plat == M4U_MT8173)
+   if (data->plat_data->m4u_plat == M4U_MT8173)
regval |= F_MMU_PREFETCH_RT_REPLACE_MOD;
writel_relaxed(regval, data->base + REG_MMU_CTRL_REG);
 
@@ -533,14 +533,14 @@ static int mtk_iommu_hw_init(const struct mtk_iommu_data 
*data)
F_INT_PRETETCH_TRANSATION_FIFO_FAULT;
writel_relaxed(regval, data->base + REG_MMU_INT_MAIN_CONTROL);
 
-   if (data->m4u_plat == M4U_MT8173)
+   if (data->plat_data->m4u_plat == M4U_MT8173)
regval = (data->protect_base >> 1) | (data->enable_4GB << 31);
else
regval = lower_32_bits(data->protect_base) |
 upper_32_bits(data->protect_base);
writel_relaxed(regval, data->base + REG_MMU_IVRP_PADDR);
 
-   if (data->enable_4GB && data->m4u_plat != M4U_MT8173) {
+   if (data->enable_4GB && data->plat_data->m4u_plat != M4U_MT8173) {
/*
 * If 4GB mode is enabled, the validate PA range is from
 * 0x1__ to 0x1__. here record bit[32:30].
@@ -551,7 +551,7 @@ static int mtk_iommu_hw_init(const struct mtk_iommu_data 
*data)
writel_relaxed(0, data->base + REG_MMU_DCM_DIS);
 
/* It's MISC control register whose default value is ok except mt8173.*/
-   if (data->m4u_plat == M4U_MT8173)
+   if (data->plat_data->m4u_plat == M4U_MT8173)
writel_relaxed(0, data->base + REG_MMU_STANDARD_AXI_MODE);
 
if (devm_request_irq(data->dev, data->irq, mtk_iommu_isr, 0,
@@ -584,7 +584,7 @@ static int mtk_iommu_probe(struct platform_device *pdev)
if (!data)
return -ENOMEM;
data->dev = dev;
-   data->m4u_plat = (enum mtk_iommu_plat)of_device_get_match_data(dev);
+   data->plat_data = of_device_get_match_data(dev);
 
/* Protect memory. HW will access here while translation fault.*/
protect = devm_kzalloc(dev, MTK_PROTECT_PA_ALIGN * 2, GFP_KERNEL);
@@ -732,9 +732,17 @@ static int __maybe_unused mtk_iommu_resume(struct device 
*dev)
SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(mtk_iommu_suspend, mtk_iommu_resume)
 };
 
+static const struct mtk_iommu_plat_data mt2712_data = {
+   .m4u_plat = M4U_MT2712,
+};
+
+static const struct mtk_iommu_plat_data mt8173_data = {
+   .m4u_plat = M4U_MT8173,
+};
+
 static const struct of_device_id mtk_iommu_of_ids[] = {
-   { .compatible = "mediatek,mt2712-m4u", .data = (void *)M4U_MT2712},
-   { .compatible = "mediatek,mt8173-m4u", .data = (void *)M4U_MT8173},
+   { .compatible = "mediatek,mt2712-m4u", .data = _data},
+   { .compatible = "mediatek,mt8173-m4u", .data = _data},
{}
 };
 
diff --git a/drivers/iommu/mtk_iommu.h b/drivers/iommu/mtk_iommu.h
index 59337323..9725b08 100644
--- a/drivers/iommu/mtk_iommu.h
+++ b/drivers/iommu/mtk_iommu.h
@@ -32,6 +32,10 @@ enum mtk_iommu_plat {
M4U_MT8173,
 };
 
+struct mtk_iommu_plat_data {
+   enum mtk_iommu_plat m4u_plat;
+};
+
 struct mtk_iommu_domain;
 
 struct mtk_iommu_data {
@@ -48,7 +52,7 @@ struct mtk_iommu_data {
booltlb_flush_active;
 
struct iommu_device iommu;
-   enum mtk_iommu_plat m4u_plat;
+   const struct mtk_iommu_plat_data *plat_data;
 
struct list_headlist;
 };
-- 
1.9.1

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


[PATCH v9 01/21] dt-bindings: mediatek: Add binding for mt8183 IOMMU and SMI

2019-08-10 Thread Yong Wu
This patch adds decriptions for mt8183 IOMMU and SMI.

mt8183 has only one M4U like mt8173 and is also MTK IOMMU gen2 which
uses ARM Short-Descriptor translation table format.

The mt8183 M4U-SMI HW diagram is as below:

  EMI
   |
  M4U
   |
   --
   ||
   gals0-rx   gals1-rx
   ||
   ||
   gals0-tx   gals1-tx
   ||
  
   SMI Common
  
   |
  +-+-++-+-+---+---+
  | | || | |   |   |
  | |  gals-rx  gals-rx  |   gals-rx gals-rx gals-rx
  | | || | |   |   |
  | | || | |   |   |
  | |  gals-tx  gals-tx  |   gals-tx gals-tx gals-tx
  | | || | |   |   |
larb0 larb1  IPU0IPU1  larb4  larb5  larb6CCU
disp  vdec   img camvenc   imgcam

All the connections are HW fixed, SW can NOT adjust it.

Compared with mt8173, we add a GALS(Global Async Local Sync) module
between SMI-common and M4U, and additional GALS between larb2/3/5/6
and SMI-common. GALS can help synchronize for the modules in different
clock frequency, it can be seen as a "asynchronous fifo".

GALS can only help transfer the command/data while it doesn't have
the configuring register, thus it has the special "smi" clock and it
doesn't have the "apb" clock. From the diagram above, we add "gals0"
and "gals1" clocks for smi-common and add a "gals" clock for smi-larb.

>From the diagram above, IPU0/IPU1(Image Processor Unit) and CCU(Camera
Control Unit) is connected with smi-common directly, we can take them
as "larb2", "larb3" and "larb7", and their register spaces are
different with the normal larb.

Signed-off-by: Yong Wu 
Reviewed-by: Rob Herring 
Reviewed-by: Evan Green 
---
 .../devicetree/bindings/iommu/mediatek,iommu.txt   |  30 -
 .../memory-controllers/mediatek,smi-common.txt |  12 +-
 .../memory-controllers/mediatek,smi-larb.txt   |   4 +
 include/dt-bindings/memory/mt8183-larb-port.h  | 130 +
 4 files changed, 170 insertions(+), 6 deletions(-)
 create mode 100644 include/dt-bindings/memory/mt8183-larb-port.h

diff --git a/Documentation/devicetree/bindings/iommu/mediatek,iommu.txt 
b/Documentation/devicetree/bindings/iommu/mediatek,iommu.txt
index 6922db5..ce59a50 100644
--- a/Documentation/devicetree/bindings/iommu/mediatek,iommu.txt
+++ b/Documentation/devicetree/bindings/iommu/mediatek,iommu.txt
@@ -11,10 +11,23 @@ ARM Short-Descriptor translation table format for address 
translation.
|
   m4u (Multimedia Memory Management Unit)
|
+  ++
+  ||
+  gals0-rx   gals1-rx(Global Async Local Sync rx)
+  ||
+  ||
+  gals0-tx   gals1-tx(Global Async Local Sync tx)
+  ||  Some SoCs may have GALS.
+  ++
+   |
SMI Common(Smart Multimedia Interface Common)
|
++---
||
+   | gals-rxThere may be GALS in some larbs.
+   ||
+   ||
+   | gals-tx
||
SMI larb0SMI larb1   ... SoCs have several SMI local arbiter(larb).
(display) (vdec)
@@ -36,6 +49,10 @@ each local arbiter.
 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.
+  In some SoCs, there may be a GALS(Global Async Local Sync) module between
+smi-common and m4u, and additional GALS module between smi-larb and
+smi-common. GALS can been seen as a "asynchronous fifo" which could help
+synchronize for the modules in different clock frequency.
 
 Required properties:
 - compatible : must be one of the following string:
@@ -44,18 +61,25 @@ Required properties:
"mediatek,mt7623-m4u", "mediatek,mt2701-m4u" for mt7623 which uses
 generation one m4u HW.
"mediatek,mt8173-m4u" for mt8173 which uses generation two m4u HW.
+   "mediatek,mt8183-m4u" for mt8183 which uses generation two m4u HW.
 - 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.
+- clock-names : Only 1 optional clock:
+  - "bclk": the block clock of m4u.
+  Here is the list which require this "bclk":
+  - mt2701, 

[PATCH v9 00/21] MT8183 IOMMU SUPPORT

2019-08-10 Thread Yong Wu
This patchset mainly adds support for mt8183 IOMMU and SMI.

mt8183 has only one M4U like mt8173 and is also MTK IOMMU gen2 which
uses ARM Short-Descriptor translation table format.

The mt8183 M4U-SMI HW diagram is as below:

  EMI
   |
  M4U
   |
   --
   ||
   gals0-rx   gals1-rx
   ||
   ||
   gals0-tx   gals1-tx
   ||
  
   SMI Common
  
   |
  +-+-++-+-+---+---+
  | | || | |   |   |
  | |  gals-rx  gals-rx  |   gals-rx gals-rx gals-rx
  | | || | |   |   |
  | | || | |   |   |
  | |  gals-tx  gals-tx  |   gals-tx gals-tx gals-tx
  | | || | |   |   |
larb0 larb1  IPU0IPU1  larb4  larb5  larb6CCU
disp  vdec   img camvenc   imgcam

All the connections are HW fixed, SW can NOT adjust it.

Compared with mt8173, we add a GALS(Global Async Local Sync) module
between SMI-common and M4U, and additional GALS between larb2/3/5/6
and SMI-common. GALS can help synchronize for the modules in different
clock frequency, it can be seen as a "asynchronous fifo".

GALS can only help transfer the command/data while it doesn't have
the configuring register, thus it has the special "smi" clock and it
doesn't have the "apb" clock. From the diagram above, we add "gals0"
and "gals1" clocks for smi-common and add a "gals" clock for smi-larb.

>From the diagram above, IPU0/IPU1(Image Processor Unit) and CCU(Camera
Control Unit) is connected with smi-common directly, we can take them
as "larb2", "larb3" and "larb7", and their register spaces are
different with the normal larb.

The dtsi was sent at: [1] https://lore.kernel.org/patchwork/patch/1054099/

Change notes:
v9:
   1) rebase on v5.3-rc1.
   2) In v7s, Use oas to implement MTK 4GB mode. It nearly reconstruct the
  patch, so I don't keep the R-b.

v8: https://lists.linuxfoundation.org/pipermail/iommu/2019-June/037095.html
   1) From the 4GB mode:
  a. Move the patch sequency(Move "iommu/mediatek: Fix iova_to_phys PA
  start for 4GB mode" before "iommu/io-pgtable-arm-v7s: Extend MediaTek
  4G Mode").
  b. Remove the patch "Rename enable_4GB to dram_is_4gb" and Use Evan's
  suggestion.
   2) add a "union" for smi gen1/gen2 base.
   3) Clean up the structure "struct mtk_smi_iommu" since it have only one item,
  suggested from Matthias.

v7: https://lists.linuxfoundation.org/pipermail/iommu/2019-June/036552.html
   1) rebase on v5.2-rc1.
   2) Add fixed tags in patch 20.
   3) Remove shutdown patch. I will send it independently if necessary.

v6: https://lists.linuxfoundation.org/pipermail/iommu/2019-February/033685.html
1) rebase on v5.0-rc1.
2) About the register name (VLD_PA_RNG), Keep consistent in the patches.
3) In the 4GB mode, Always add MTK_4GB_quirk.
4) Reword some commit message helped from Evan. like common->smi_ao_base is
   completely different from common->base; STANDARD_AXI_MODE reg is 
completely
   different from CTRL_MISC; commit in the shutdown patch.
5) Add 2 new patches again:
   iommu/mediatek: Rename enable_4GB to dram_is_4gb
   iommu/mediatek: Fix iova_to_phys PA start for 4GB mode

v5: https://lists.linuxfoundation.org/pipermail/iommu/2019-January/032387.html
1) Remove this patch "iommu/mediatek: Constify iommu_ops" from here as it
   was applied for v5.0.
2) Again, add 3 preparing patches. Move two property into the plat_data.
   iommu/mediatek: Move vld_pa_rng into plat_data
   iommu/mediatek: Move reset_axi into plat_data
   iommu/mediatek: Refine protect memory definition
3) Add shutdown callback for mtk_iommu_v1 in patch[19/20].

v4: 
http://lists.infradead.org/pipermail/linux-mediatek/2018-December/016205.html
1) Add 3 preparing patches. Seperate some minor meaningful code into
   a new patch according to Matthias's suggestion.
   memory: mtk-smi: Add gals support 
   iommu/mediatek: Add larb-id remapped support 
   iommu/mediatek: Add bclk can be supported optionally   
2) rebase on "iommu/mediatek: Make it explicitly non-modular"
   which was applied.
   https://lore.kernel.org/patchwork/patch/1020125/
3) add some comment about "mediatek,larb-id" in the commit message of
   the patch "mtk-smi: Get rid of need_larbid".
4) Fix bus_sel value.

v3: https://lists.linuxfoundation.org/pipermail/iommu/2018-November/031121.html
1) rebase on v4.20-rc1.
2) In the dt-binding, add a minor string "mt7623" which also use gen1
   since Matthias 

Re: [PATCH v4 0/6] Remove x86-specific code from generic headers

2019-08-10 Thread Christoph Hellwig
On Fri, Aug 09, 2019 at 10:51:41PM +1000, m...@ellerman.id.au wrote:
> I need to take this series via the powerpc tree because there is another
> fairly large powerpc specific series dependent on it.
> 
> I think this series already has pretty much all the acks it needs, which
> almost never happens, amazing work!
> 
> I'll put the series in a topic branch, just in case there's any bad
> conflicts and other folks want to merge it later on. I'll then merge the
> topic branch into my next, and so this series will be tested in
> linux-next that way.

Sounds good to me, I don't expect conflicts from the dma-mapping tree.
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH v4 0/5] iommu/amd: Convert the AMD iommu driver to the dma-iommu api

2019-08-10 Thread Christoph Hellwig
On Sun, Jun 23, 2019 at 11:19:45PM -0700, Christoph Hellwig wrote:
> Tom,
> 
> next time please cc Jerg as the AMD IOMMU maintainer.
> 
> Joerg, any chance you could review this?  Toms patches to convert the
> AMD and Intel IOMMU drivers to the dma-iommu code are going to make my
> life in DMA land significantly easier, so I have a vested interest
> in this series moving forward :)

Tom, can you repost the series?  Seems like there hasn't been any
news for a month.
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu