[PATCH v2 0/2] PCI: mediatek: Fixups for the IRQ handle routine and MT7622's class code

2017-12-20 Thread honghui.zhang
From: Honghui Zhang 

Two fixups for mediatek's host bridge:
The first patch fixup the IRQ handle routine to avoid IRQ reentry which
may exist for both MT2712 and MT7622.
The second patch fixup class type for MT7622.

Change Since v1:
 - Add the second patch.
 - Make the first patch's commit message more standard.

Honghui Zhang (2):
  PCI: mediatek: Clear IRQ status after IRQ dispatched to avoid reentry
  PCI: mediatek: Fixup class type for MT7622

 drivers/pci/host/pcie-mediatek.c | 20 
 1 file changed, 16 insertions(+), 4 deletions(-)

-- 
2.6.4

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


[PATCH v2 1/2] PCI: mediatek: Clear IRQ status after IRQ dispatched to avoid reentry

2017-12-20 Thread honghui.zhang
From: Honghui Zhang 

There maybe a same IRQ reentry scenario after IRQ received in current
IRQ handle flow:
EP device   PCIe host driverEP driver
1. issue an IRQ
2. received IRQ
3. clear IRQ status
4. dispatch IRQ
5. clear IRQ source
The IRQ status was not successfully cleared at step 2 since the IRQ
source was not cleared yet. So the PCIe host driver may receive the
same IRQ after step 5. Then there's an IRQ reentry occurred.
Even worse, if the reentry IRQ was not an IRQ that EP driver expected,
it may not handle the IRQ. Then we may run into the infinite loop from
step 2 to step 4.
Clear the IRQ status after IRQ have been dispatched to avoid the IRQ
reentry.

Signed-off-by: Honghui Zhang 
Acked-by: Ryder Lee 
---
 drivers/pci/host/pcie-mediatek.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/pci/host/pcie-mediatek.c b/drivers/pci/host/pcie-mediatek.c
index db93efd..3248771 100644
--- a/drivers/pci/host/pcie-mediatek.c
+++ b/drivers/pci/host/pcie-mediatek.c
@@ -605,11 +605,11 @@ static irqreturn_t mtk_pcie_intr_handler(int irq, void 
*data)
 
while ((status = readl(port->base + PCIE_INT_STATUS)) & INTX_MASK) {
for_each_set_bit_from(bit, , PCI_NUM_INTX + INTX_SHIFT) {
-   /* Clear the INTx */
-   writel(1 << bit, port->base + PCIE_INT_STATUS);
virq = irq_find_mapping(port->irq_domain,
bit - INTX_SHIFT);
generic_handle_irq(virq);
+   /* Clear the INTx */
+   writel(1 << bit, port->base + PCIE_INT_STATUS);
}
}
 
@@ -619,10 +619,10 @@ static irqreturn_t mtk_pcie_intr_handler(int irq, void 
*data)
 
while ((imsi_status = readl(port->base + 
PCIE_IMSI_STATUS))) {
for_each_set_bit(bit, _status, 
MTK_MSI_IRQS_NUM) {
-   /* Clear the MSI */
-   writel(1 << bit, port->base + 
PCIE_IMSI_STATUS);
virq = 
irq_find_mapping(port->msi_domain, bit);
generic_handle_irq(virq);
+   /* Clear the MSI */
+   writel(1 << bit, port->base + 
PCIE_IMSI_STATUS);
}
}
/* Clear MSI interrupt status */
-- 
2.6.4

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


[PATCH v2 2/2] PCI: mediatek: Fixup class type for MT7622

2017-12-20 Thread honghui.zhang
From: Honghui Zhang 

The host bridge of MT7622 has hardware code the class code to an
arbitrary, meaningless value, fix that.

Signed-off-by: Honghui Zhang 
---
 drivers/pci/host/pcie-mediatek.c | 12 
 1 file changed, 12 insertions(+)

diff --git a/drivers/pci/host/pcie-mediatek.c b/drivers/pci/host/pcie-mediatek.c
index 3248771..ae8d367 100644
--- a/drivers/pci/host/pcie-mediatek.c
+++ b/drivers/pci/host/pcie-mediatek.c
@@ -1174,3 +1174,15 @@ static struct platform_driver mtk_pcie_driver = {
},
 };
 builtin_platform_driver(mtk_pcie_driver);
+
+/* The host bridge of MT7622 advertises the wrong device class. */
+static void mtk_fixup_class(struct pci_dev *dev)
+{
+   dev->class = PCI_CLASS_BRIDGE_PCI << 8;
+}
+
+/*
+ * The HW default value of vendor id and device id for mt7622 are 0x0e8d,
+ * 0x3258, which are arbitrary, meaningless values.
+ */
+DECLARE_PCI_FIXUP_EARLY(0x0e8d, 0x3258, mtk_fixup_class);
-- 
2.6.4

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


[PATCH v3 4/4] arm: dts: mediatek: add larbid property for larb

2017-08-03 Thread honghui.zhang
From: Honghui Zhang 

Add mediatek's hardware id information for smi larb.

Signed-off-by: Honghui Zhang 
---
 arch/arm/boot/dts/mt2701.dtsi | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/arm/boot/dts/mt2701.dtsi b/arch/arm/boot/dts/mt2701.dtsi
index f1efdc6..d95bfe0 100644
--- a/arch/arm/boot/dts/mt2701.dtsi
+++ b/arch/arm/boot/dts/mt2701.dtsi
@@ -533,6 +533,7 @@
compatible = "mediatek,mt2701-smi-larb";
reg = <0 0x1401 0 0x1000>;
mediatek,smi = <_common>;
+   mediatek,larb-id = <0>;
clocks = < CLK_MM_SMI_LARB0>,
 < CLK_MM_SMI_LARB0>;
clock-names = "apb", "smi";
@@ -549,6 +550,7 @@
compatible = "mediatek,mt2701-smi-larb";
reg = <0 0x15001000 0 0x1000>;
mediatek,smi = <_common>;
+   mediatek,larb-id = <2>;
clocks = < CLK_IMG_SMI_COMM>,
 < CLK_IMG_SMI_COMM>;
clock-names = "apb", "smi";
@@ -579,6 +581,7 @@
compatible = "mediatek,mt2701-smi-larb";
reg = <0 0x1601 0 0x1000>;
mediatek,smi = <_common>;
+   mediatek,larb-id = <1>;
clocks = < CLK_VDEC_CKGEN>,
 < CLK_VDEC_LARB>;
clock-names = "apb", "smi";
-- 
2.6.4

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


[PATCH v3 3/4] dt-bindings: mediatek: add descriptions for larbid

2017-08-03 Thread honghui.zhang
From: Honghui Zhang 

This patch add larbid descritptions for mediatek's gen1 smi larb hardware.

Acked-by: Rob Herring 
Signed-off-by: Honghui Zhang 
---
 .../bindings/memory-controllers/mediatek,smi-larb.txt | 15 +++
 1 file changed, 15 insertions(+)

diff --git 
a/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.txt 
b/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.txt
index 21277a5..ddf46b8 100644
--- a/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.txt
+++ b/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.txt
@@ -15,6 +15,9 @@ Required properties:
the register.
   - "smi" : It's the clock for transfer data and command.
 
+Required property for mt2701:
+- mediatek,larb-id :the hardware id of this larb.
+
 Example:
larb1: larb@1601 {
compatible = "mediatek,mt8173-smi-larb";
@@ -25,3 +28,15 @@ Example:
 < CLK_VDEC_LARB_CKEN>;
clock-names = "apb", "smi";
};
+
+Example for mt2701:
+   larb0: larb@1401 {
+   compatible = "mediatek,mt2701-smi-larb";
+   reg = <0 0x1401 0 0x1000>;
+   mediatek,smi = <_common>;
+   mediatek,larb-id = <0>;
+   clocks = < CLK_MM_SMI_LARB0>,
+< CLK_MM_SMI_LARB0>;
+   clock-names = "apb", "smi";
+   power-domains = < MT2701_POWER_DOMAIN_DISP>;
+   };
-- 
2.6.4

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


[PATCH v3 1/4] memory: mtk-smi: Use of_device_get_match_data helper

2017-08-03 Thread honghui.zhang
From: Honghui Zhang 

Replace custom code with generic helper to retrieve driver data.

Signed-off-by: Honghui Zhang 
---
 drivers/memory/mtk-smi.c | 14 ++
 1 file changed, 2 insertions(+), 12 deletions(-)

diff --git a/drivers/memory/mtk-smi.c b/drivers/memory/mtk-smi.c
index 4afbc41..2b798bb4 100644
--- a/drivers/memory/mtk-smi.c
+++ b/drivers/memory/mtk-smi.c
@@ -240,20 +240,15 @@ static int mtk_smi_larb_probe(struct platform_device 
*pdev)
struct device *dev = >dev;
struct device_node *smi_node;
struct platform_device *smi_pdev;
-   const struct of_device_id *of_id;
 
if (!dev->pm_domain)
return -EPROBE_DEFER;
 
-   of_id = of_match_node(mtk_smi_larb_of_ids, pdev->dev.of_node);
-   if (!of_id)
-   return -EINVAL;
-
larb = devm_kzalloc(dev, sizeof(*larb), GFP_KERNEL);
if (!larb)
return -ENOMEM;
 
-   larb->larb_gen = of_id->data;
+   larb->larb_gen = of_device_get_match_data(dev);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
larb->base = devm_ioremap_resource(dev, res);
if (IS_ERR(larb->base))
@@ -319,7 +314,6 @@ static int mtk_smi_common_probe(struct platform_device 
*pdev)
struct device *dev = >dev;
struct mtk_smi *common;
struct resource *res;
-   const struct of_device_id *of_id;
enum mtk_smi_gen smi_gen;
 
if (!dev->pm_domain)
@@ -338,17 +332,13 @@ static int mtk_smi_common_probe(struct platform_device 
*pdev)
if (IS_ERR(common->clk_smi))
return PTR_ERR(common->clk_smi);
 
-   of_id = of_match_node(mtk_smi_common_of_ids, pdev->dev.of_node);
-   if (!of_id)
-   return -EINVAL;
-
/*
 * 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
 * clock into emi clock domain, but for mtk smi gen2, there's no smi ao
 * base.
 */
-   smi_gen = (enum mtk_smi_gen)of_id->data;
+   smi_gen = (enum mtk_smi_gen)of_device_get_match_data(dev);
if (smi_gen == MTK_SMI_GEN1) {
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
common->smi_ao_base = devm_ioremap_resource(dev, res);
-- 
2.6.4

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


[PATCH v3 0/4] Add larbid init routine for mediatek's gen1 smi larb driver

2017-08-03 Thread honghui.zhang
From: Honghui Zhang 

Mediatek's gen1 smi need the hardware larb-id to identify the offset for
the register which controls whether enable iommu for this larb.
In the commit 3c8f4ad85c4b ("memory/mediatek: add support for mt2701"),
the larbid was used without properly initialized. This patchset fixed
that.
Also include a patch which using the of_device_get_match_data helper to
simplify the code.
This patchset was base on 4.13-rc1.

Change since v2:
 - Using compatible strings of "mediatek,larb-id" instead of "mediatek,larbid"
   to make it a bit easier to read.
 - Put the v2 of the patch ("memory: mtk-smi: Use of_device_get_match_data 
helper")[1]
   in this patchset to make the changes easier for review.
 - Add the reivewer's tag in commit messages.

Change since v1:
 - Using mtk_smi_larb_gen to identify whether larbid was needed instead of
   checking hard code bindings.

[1] https://patchwork.kernel.org/patch/9864719

Honghui Zhang (4):
  memory: mtk-smi: Use of_device_get_match_data helper
  memory: mtk-smi: add larbid handle routine
  dt-bindings: mediatek: add descriptions for larbid
  arm: dts: mediatek: add larbid property for larb

 .../memory-controllers/mediatek,smi-larb.txt   | 15 +
 arch/arm/boot/dts/mt2701.dtsi  |  3 +++
 drivers/memory/mtk-smi.c   | 26 --
 3 files changed, 32 insertions(+), 12 deletions(-)

-- 
2.6.4

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


[PATCH v2 3/3] arm: dts: mediatek: add larbid property for larb

2017-07-28 Thread honghui.zhang
From: Honghui Zhang 

Add mediatek's hardware id information for smi larb.

Signed-off-by: Honghui Zhang 
---
 arch/arm/boot/dts/mt2701.dtsi | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/arm/boot/dts/mt2701.dtsi b/arch/arm/boot/dts/mt2701.dtsi
index f1efdc6..2cddbec 100644
--- a/arch/arm/boot/dts/mt2701.dtsi
+++ b/arch/arm/boot/dts/mt2701.dtsi
@@ -533,6 +533,7 @@
compatible = "mediatek,mt2701-smi-larb";
reg = <0 0x1401 0 0x1000>;
mediatek,smi = <_common>;
+   mediatek,larbid = <0>;
clocks = < CLK_MM_SMI_LARB0>,
 < CLK_MM_SMI_LARB0>;
clock-names = "apb", "smi";
@@ -549,6 +550,7 @@
compatible = "mediatek,mt2701-smi-larb";
reg = <0 0x15001000 0 0x1000>;
mediatek,smi = <_common>;
+   mediatek,larbid = <2>;
clocks = < CLK_IMG_SMI_COMM>,
 < CLK_IMG_SMI_COMM>;
clock-names = "apb", "smi";
@@ -579,6 +581,7 @@
compatible = "mediatek,mt2701-smi-larb";
reg = <0 0x1601 0 0x1000>;
mediatek,smi = <_common>;
+   mediatek,larbid = <1>;
clocks = < CLK_VDEC_CKGEN>,
 < CLK_VDEC_LARB>;
clock-names = "apb", "smi";
-- 
2.6.4

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


[PATCH v2 2/3] dt-bindings: mediatek: add descriptions for larbid

2017-07-28 Thread honghui.zhang
From: Honghui Zhang 

This patch add larbid descritptions for mediatek's gen1 smi larb hardware.

Signed-off-by: Honghui Zhang 
---
 .../bindings/memory-controllers/mediatek,smi-larb.txt | 15 +++
 1 file changed, 15 insertions(+)

diff --git 
a/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.txt 
b/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.txt
index 21277a5..d1b115c 100644
--- a/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.txt
+++ b/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.txt
@@ -15,6 +15,9 @@ Required properties:
the register.
   - "smi" : It's the clock for transfer data and command.
 
+Required property for mt2701:
+- mediatek,larbid :the hardware id of this larb.
+
 Example:
larb1: larb@1601 {
compatible = "mediatek,mt8173-smi-larb";
@@ -25,3 +28,15 @@ Example:
 < CLK_VDEC_LARB_CKEN>;
clock-names = "apb", "smi";
};
+
+Example for mt2701:
+   larb0: larb@1401 {
+   compatible = "mediatek,mt2701-smi-larb";
+   reg = <0 0x1401 0 0x1000>;
+   mediatek,smi = <_common>;
+   mediatek,larbid = <0>;
+   clocks = < CLK_MM_SMI_LARB0>,
+< CLK_MM_SMI_LARB0>;
+   clock-names = "apb", "smi";
+   power-domains = < MT2701_POWER_DOMAIN_DISP>;
+   };
-- 
2.6.4

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


[PATCH v2 1/3] memory: mtk-smi: add larbid handle routine

2017-07-28 Thread honghui.zhang
From: Honghui Zhang 

In the commit 3c8f4ad85c4b ("memory/mediatek: add support for mt2701"),
the larb->larbid was added but not initialized.
Mediatek's gen1 smi need this hardware larbid information to get the
register offset which controls whether enable iommu for this larb.
This patch add the initialize routine for larbid.

Signed-off-by: Honghui Zhang 
---
 drivers/memory/mtk-smi.c | 12 
 1 file changed, 12 insertions(+)

diff --git a/drivers/memory/mtk-smi.c b/drivers/memory/mtk-smi.c
index 2b798bb4..8f75aaa 100644
--- a/drivers/memory/mtk-smi.c
+++ b/drivers/memory/mtk-smi.c
@@ -42,6 +42,7 @@
 #define SMI_SECUR_CON_VAL_DOMAIN(id)   (0x3 << id) & 0x7) << 2) + 1))
 
 struct mtk_smi_larb_gen {
+   bool need_larbid;
int port_in_larb[MTK_LARB_NR_MAX + 1];
void (*config_port)(struct device *);
 };
@@ -214,6 +215,7 @@ static const struct mtk_smi_larb_gen mtk_smi_larb_mt8173 = {
 };
 
 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
@@ -240,6 +242,7 @@ 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;
 
if (!dev->pm_domain)
return -EPROBE_DEFER;
@@ -263,6 +266,15 @@ static int mtk_smi_larb_probe(struct platform_device *pdev)
return PTR_ERR(larb->smi.clk_smi);
larb->smi.dev = dev;
 
+   if (larb->larb_gen->need_larbid) {
+   err = of_property_read_u32(dev->of_node, "mediatek,larbid",
+  >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;
-- 
2.6.4

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


[PATCH 3/3] arm: dts: mediatek: add larbid property for larb

2017-07-26 Thread honghui.zhang
From: Honghui Zhang 

Add mediatek's hardware id information for smi larb.

Signed-off-by: Honghui Zhang 
---
 arch/arm/boot/dts/mt2701.dtsi | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/arm/boot/dts/mt2701.dtsi b/arch/arm/boot/dts/mt2701.dtsi
index f1efdc6..2cddbec 100644
--- a/arch/arm/boot/dts/mt2701.dtsi
+++ b/arch/arm/boot/dts/mt2701.dtsi
@@ -533,6 +533,7 @@
compatible = "mediatek,mt2701-smi-larb";
reg = <0 0x1401 0 0x1000>;
mediatek,smi = <_common>;
+   mediatek,larbid = <0>;
clocks = < CLK_MM_SMI_LARB0>,
 < CLK_MM_SMI_LARB0>;
clock-names = "apb", "smi";
@@ -549,6 +550,7 @@
compatible = "mediatek,mt2701-smi-larb";
reg = <0 0x15001000 0 0x1000>;
mediatek,smi = <_common>;
+   mediatek,larbid = <2>;
clocks = < CLK_IMG_SMI_COMM>,
 < CLK_IMG_SMI_COMM>;
clock-names = "apb", "smi";
@@ -579,6 +581,7 @@
compatible = "mediatek,mt2701-smi-larb";
reg = <0 0x1601 0 0x1000>;
mediatek,smi = <_common>;
+   mediatek,larbid = <1>;
clocks = < CLK_VDEC_CKGEN>,
 < CLK_VDEC_LARB>;
clock-names = "apb", "smi";
-- 
2.6.4

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


[PATCH 1/3] memory: mtk-smi: add larbid init routine

2017-07-26 Thread honghui.zhang
From: Honghui Zhang 

In the commit 3c8f4ad85c4b ("memory/mediatek: add support for mt2701"),
the larb->larbid was added but not initialized.
Mediatek's gen1 smi need this hardware larbid information to get the
register offset which controls whether enable iommu for this larb.
This patch add the initialize routine for larbid.

Signed-off-by: Honghui Zhang 
---
 drivers/memory/mtk-smi.c | 9 +
 1 file changed, 9 insertions(+)

diff --git a/drivers/memory/mtk-smi.c b/drivers/memory/mtk-smi.c
index 2b798bb4..fe36b3e 100644
--- a/drivers/memory/mtk-smi.c
+++ b/drivers/memory/mtk-smi.c
@@ -240,6 +240,7 @@ 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;
 
if (!dev->pm_domain)
return -EPROBE_DEFER;
@@ -263,6 +264,14 @@ static int mtk_smi_larb_probe(struct platform_device *pdev)
return PTR_ERR(larb->smi.clk_smi);
larb->smi.dev = dev;
 
+   err = of_property_read_u32(dev->of_node, "mediatek,larbid",
+  >larbid);
+   if (err && of_device_is_compatible(dev->of_node,
+  "mediatek,mt2701-smi-larb")) {
+   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;
-- 
2.6.4

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


[PATCH 0/3] Add larbid init routine for mediatek's gen1 smi larb driver

2017-07-26 Thread honghui.zhang
From: Honghui Zhang 

Mediatek's gen1 smi need the hardware larbid to identify the offset for
the register which controls whether enable iommu for this larb.
In the commit 3c8f4ad85c4b ("memory/mediatek: add support for mt2701"),
the larbid was used without properly initialized. This patchset fixed
that.

Honghui Zhang (3):
  memory: mtk-smi: add larbid init routine
  dt-bindings: mediatek: add descriptions for larbid
  arm: dts: mediatek: add larbid property for larb

 .../bindings/memory-controllers/mediatek,smi-larb.txt | 15 +++
 arch/arm/boot/dts/mt2701.dtsi |  3 +++
 drivers/memory/mtk-smi.c  |  9 +
 3 files changed, 27 insertions(+)

-- 
2.6.4

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


[PATCH 2/3] dt-bindings: mediatek: add descriptions for larbid

2017-07-26 Thread honghui.zhang
From: Honghui Zhang 

This patch add larbid descritptions for mediatek's gen1 smi larb hardware.

Signed-off-by: Honghui Zhang 
---
 .../bindings/memory-controllers/mediatek,smi-larb.txt | 15 +++
 1 file changed, 15 insertions(+)

diff --git 
a/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.txt 
b/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.txt
index 21277a5..d1b115c 100644
--- a/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.txt
+++ b/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.txt
@@ -15,6 +15,9 @@ Required properties:
the register.
   - "smi" : It's the clock for transfer data and command.
 
+Required property for mt2701:
+- mediatek,larbid :the hardware id of this larb.
+
 Example:
larb1: larb@1601 {
compatible = "mediatek,mt8173-smi-larb";
@@ -25,3 +28,15 @@ Example:
 < CLK_VDEC_LARB_CKEN>;
clock-names = "apb", "smi";
};
+
+Example for mt2701:
+   larb0: larb@1401 {
+   compatible = "mediatek,mt2701-smi-larb";
+   reg = <0 0x1401 0 0x1000>;
+   mediatek,smi = <_common>;
+   mediatek,larbid = <0>;
+   clocks = < CLK_MM_SMI_LARB0>,
+< CLK_MM_SMI_LARB0>;
+   clock-names = "apb", "smi";
+   power-domains = < MT2701_POWER_DOMAIN_DISP>;
+   };
-- 
2.6.4

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


[PATCH v2] memory: mtk-smi: Use of_device_get_match_data helper

2017-07-26 Thread honghui.zhang
From: Honghui Zhang 

Replace custom code with generic helper to retrieve driver data.

Signed-off-by: Honghui Zhang 
---
 drivers/memory/mtk-smi.c | 14 ++
 1 file changed, 2 insertions(+), 12 deletions(-)

diff --git a/drivers/memory/mtk-smi.c b/drivers/memory/mtk-smi.c
index 4afbc41..2b798bb4 100644
--- a/drivers/memory/mtk-smi.c
+++ b/drivers/memory/mtk-smi.c
@@ -240,20 +240,15 @@ static int mtk_smi_larb_probe(struct platform_device 
*pdev)
struct device *dev = >dev;
struct device_node *smi_node;
struct platform_device *smi_pdev;
-   const struct of_device_id *of_id;
 
if (!dev->pm_domain)
return -EPROBE_DEFER;
 
-   of_id = of_match_node(mtk_smi_larb_of_ids, pdev->dev.of_node);
-   if (!of_id)
-   return -EINVAL;
-
larb = devm_kzalloc(dev, sizeof(*larb), GFP_KERNEL);
if (!larb)
return -ENOMEM;
 
-   larb->larb_gen = of_id->data;
+   larb->larb_gen = of_device_get_match_data(dev);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
larb->base = devm_ioremap_resource(dev, res);
if (IS_ERR(larb->base))
@@ -319,7 +314,6 @@ static int mtk_smi_common_probe(struct platform_device 
*pdev)
struct device *dev = >dev;
struct mtk_smi *common;
struct resource *res;
-   const struct of_device_id *of_id;
enum mtk_smi_gen smi_gen;
 
if (!dev->pm_domain)
@@ -338,17 +332,13 @@ static int mtk_smi_common_probe(struct platform_device 
*pdev)
if (IS_ERR(common->clk_smi))
return PTR_ERR(common->clk_smi);
 
-   of_id = of_match_node(mtk_smi_common_of_ids, pdev->dev.of_node);
-   if (!of_id)
-   return -EINVAL;
-
/*
 * 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
 * clock into emi clock domain, but for mtk smi gen2, there's no smi ao
 * base.
 */
-   smi_gen = (enum mtk_smi_gen)of_id->data;
+   smi_gen = (enum mtk_smi_gen)of_device_get_match_data(dev);
if (smi_gen == MTK_SMI_GEN1) {
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
common->smi_ao_base = devm_ioremap_resource(dev, res);
-- 
2.6.4

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


[PATCH] memory: mtk-smi: Use of_device_get_match_data helper

2017-07-26 Thread honghui.zhang
From: Honghui Zhang 

Replace custom code with generic helper to retrieve driver data.

Signed-off-by: Honghui Zhang 
---
 drivers/memory/mtk-smi.c | 18 --
 1 file changed, 4 insertions(+), 14 deletions(-)

diff --git a/drivers/memory/mtk-smi.c b/drivers/memory/mtk-smi.c
index 4afbc41..fe8b81a 100644
--- a/drivers/memory/mtk-smi.c
+++ b/drivers/memory/mtk-smi.c
@@ -240,20 +240,15 @@ static int mtk_smi_larb_probe(struct platform_device 
*pdev)
struct device *dev = >dev;
struct device_node *smi_node;
struct platform_device *smi_pdev;
-   const struct of_device_id *of_id;
 
if (!dev->pm_domain)
return -EPROBE_DEFER;
 
-   of_id = of_match_node(mtk_smi_larb_of_ids, pdev->dev.of_node);
-   if (!of_id)
-   return -EINVAL;
-
larb = devm_kzalloc(dev, sizeof(*larb), GFP_KERNEL);
if (!larb)
return -ENOMEM;
 
-   larb->larb_gen = of_id->data;
+   larb->larb_gen = of_device_get_match_data(dev);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
larb->base = devm_ioremap_resource(dev, res);
if (IS_ERR(larb->base))
@@ -319,8 +314,7 @@ static int mtk_smi_common_probe(struct platform_device 
*pdev)
struct device *dev = >dev;
struct mtk_smi *common;
struct resource *res;
-   const struct of_device_id *of_id;
-   enum mtk_smi_gen smi_gen;
+   const enum mtk_smi_gen *smi_gen;
 
if (!dev->pm_domain)
return -EPROBE_DEFER;
@@ -338,18 +332,14 @@ static int mtk_smi_common_probe(struct platform_device 
*pdev)
if (IS_ERR(common->clk_smi))
return PTR_ERR(common->clk_smi);
 
-   of_id = of_match_node(mtk_smi_common_of_ids, pdev->dev.of_node);
-   if (!of_id)
-   return -EINVAL;
-
/*
 * 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
 * clock into emi clock domain, but for mtk smi gen2, there's no smi ao
 * base.
 */
-   smi_gen = (enum mtk_smi_gen)of_id->data;
-   if (smi_gen == MTK_SMI_GEN1) {
+   smi_gen = of_device_get_match_data(dev);
+   if (*smi_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))
-- 
2.6.4

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


[PATCH] memory: mtk-smi: Use of_device_get_match_data helper

2017-07-26 Thread honghui.zhang
From: Honghui Zhang 

Replace custom code with generic helper to retrieve driver data.

Signed-off-by: Honghui Zhang 
---
 drivers/memory/mtk-smi.c | 14 ++
 1 file changed, 2 insertions(+), 12 deletions(-)

diff --git a/drivers/memory/mtk-smi.c b/drivers/memory/mtk-smi.c
index 4afbc41..69249f5 100644
--- a/drivers/memory/mtk-smi.c
+++ b/drivers/memory/mtk-smi.c
@@ -240,20 +240,15 @@ static int mtk_smi_larb_probe(struct platform_device 
*pdev)
struct device *dev = >dev;
struct device_node *smi_node;
struct platform_device *smi_pdev;
-   const struct of_device_id *of_id;
 
if (!dev->pm_domain)
return -EPROBE_DEFER;
 
-   of_id = of_match_node(mtk_smi_larb_of_ids, pdev->dev.of_node);
-   if (!of_id)
-   return -EINVAL;
-
larb = devm_kzalloc(dev, sizeof(*larb), GFP_KERNEL);
if (!larb)
return -ENOMEM;
 
-   larb->larb_gen = of_id->data;
+   larb->larb_gen = of_device_get_match_data(dev);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
larb->base = devm_ioremap_resource(dev, res);
if (IS_ERR(larb->base))
@@ -319,7 +314,6 @@ static int mtk_smi_common_probe(struct platform_device 
*pdev)
struct device *dev = >dev;
struct mtk_smi *common;
struct resource *res;
-   const struct of_device_id *of_id;
enum mtk_smi_gen smi_gen;
 
if (!dev->pm_domain)
@@ -338,17 +332,13 @@ static int mtk_smi_common_probe(struct platform_device 
*pdev)
if (IS_ERR(common->clk_smi))
return PTR_ERR(common->clk_smi);
 
-   of_id = of_match_node(mtk_smi_common_of_ids, pdev->dev.of_node);
-   if (!of_id)
-   return -EINVAL;
-
/*
 * 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
 * clock into emi clock domain, but for mtk smi gen2, there's no smi ao
 * base.
 */
-   smi_gen = (enum mtk_smi_gen)of_id->data;
+   smi_gen = of_device_get_match_data(dev);
if (smi_gen == MTK_SMI_GEN1) {
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
common->smi_ao_base = devm_ioremap_resource(dev, res);
-- 
2.6.4

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


[PATCH] dt-binding: correct the larb port offset defines for mt2701

2016-08-11 Thread honghui.zhang
From: Honghui Zhang 

larb2 have 23 ports, the LARB3_PORT_OFFSET should be LARB2_PORT_OFFSET
plus larb2's port number, it should be 44 instead of 43.

Signed-off-by: Honghui Zhang 
---
 include/dt-bindings/memory/mt2701-larb-port.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/dt-bindings/memory/mt2701-larb-port.h 
b/include/dt-bindings/memory/mt2701-larb-port.h
index 78f6678..6764d74 100644
--- a/include/dt-bindings/memory/mt2701-larb-port.h
+++ b/include/dt-bindings/memory/mt2701-larb-port.h
@@ -26,7 +26,7 @@
 #define LARB0_PORT_OFFSET  0
 #define LARB1_PORT_OFFSET  11
 #define LARB2_PORT_OFFSET  21
-#define LARB3_PORT_OFFSET  43
+#define LARB3_PORT_OFFSET  44
 
 #define MT2701_M4U_ID_LARB0(port)  ((port) + LARB0_PORT_OFFSET)
 #define MT2701_M4U_ID_LARB1(port)  ((port) + LARB1_PORT_OFFSET)
-- 
1.8.1.1.dirty

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


[RFC PATCH] iommu: create direct_mapping after device attached

2016-07-20 Thread honghui.zhang
From: Honghui Zhang 

For mtk iommu, the domain_finalize was called in device attatch, the mtk
iommu iopgt ops was allocated and initialized in domain_finalize, the
iommu_group_create_direct_mappings would call the map interface to
implement the map. If it's earlier than device attach, there would be NULL
dereference. Move the iommu_group_create_direct_mappings call after device
attached.

Signed-off-by: Honghui Zhang 
---
 drivers/iommu/iommu.c | 9 +++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 351..24c671c 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -427,14 +427,19 @@ rename:
 
dev->iommu_group = group;
 
-   iommu_group_create_direct_mappings(group, dev);
-
mutex_lock(>mutex);
list_add_tail(>list, >devices);
if (group->domain)
__iommu_attach_device(group->domain, dev);
mutex_unlock(>mutex);
 
+   /*
+* For some iommu driver like mtk iommu, the map callback was assigned
+* after device attached. The direct_mappings would call iommu map and
+* dereference NULL if it's called earlier than attach_device.
+*/
+   iommu_group_create_direct_mappings(group, dev);
+
/* Notify any listeners about change to group. */
blocking_notifier_call_chain(>notifier,
 IOMMU_GROUP_NOTIFY_ADD_DEVICE, dev);
-- 
1.8.1.1.dirty

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


[PATCH v4 2/5] iommu/mediatek: move the common struct into header file

2016-06-08 Thread honghui.zhang
From: Honghui Zhang 

Move the struct defines of mtk iommu into a new header files for
common use.

Signed-off-by: Honghui Zhang 
---
 drivers/iommu/mtk_iommu.c | 48 +
 drivers/iommu/mtk_iommu.h | 77 +++
 2 files changed, 78 insertions(+), 47 deletions(-)
 create mode 100644 drivers/iommu/mtk_iommu.h

diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index c3043d8..4f18ff5 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -34,7 +34,7 @@
 #include 
 #include 
 
-#include "io-pgtable.h"
+#include "mtk_iommu.h"
 
 #define REG_MMU_PT_BASE_ADDR   0x000
 
@@ -93,20 +93,6 @@
 
 #define MTK_PROTECT_PA_ALIGN   128
 
-struct mtk_iommu_suspend_reg {
-   u32 standard_axi_mode;
-   u32 dcm_dis;
-   u32 ctrl_reg;
-   u32 int_control0;
-   u32 int_main_control;
-};
-
-struct mtk_iommu_client_priv {
-   struct list_headclient;
-   unsigned intmtk_m4u_id;
-   struct device   *m4udev;
-};
-
 struct mtk_iommu_domain {
spinlock_t  pgtlock; /* lock for page table */
 
@@ -116,19 +102,6 @@ struct mtk_iommu_domain {
struct iommu_domain domain;
 };
 
-struct mtk_iommu_data {
-   void __iomem*base;
-   int irq;
-   struct device   *dev;
-   struct clk  *bclk;
-   phys_addr_t protect_base; /* protect memory base */
-   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;
-};
-
 static struct iommu_ops mtk_iommu_ops;
 
 static struct mtk_iommu_domain *to_mtk_domain(struct iommu_domain *dom)
@@ -552,25 +525,6 @@ static int mtk_iommu_hw_init(const struct mtk_iommu_data 
*data)
return 0;
 }
 
-static int compare_of(struct device *dev, void *data)
-{
-   return dev->of_node == data;
-}
-
-static int mtk_iommu_bind(struct device *dev)
-{
-   struct mtk_iommu_data *data = dev_get_drvdata(dev);
-
-   return component_bind_all(dev, >smi_imu);
-}
-
-static void mtk_iommu_unbind(struct device *dev)
-{
-   struct mtk_iommu_data *data = dev_get_drvdata(dev);
-
-   component_unbind_all(dev, >smi_imu);
-}
-
 static const struct component_master_ops mtk_iommu_com_ops = {
.bind   = mtk_iommu_bind,
.unbind = mtk_iommu_unbind,
diff --git a/drivers/iommu/mtk_iommu.h b/drivers/iommu/mtk_iommu.h
new file mode 100644
index 000..9ed0a84
--- /dev/null
+++ b/drivers/iommu/mtk_iommu.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2015-2016 MediaTek Inc.
+ * Author: Honghui Zhang 
+ *
+ * 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 _MTK_IOMMU_H_
+#define _MTK_IOMMU_H_
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "io-pgtable.h"
+
+struct mtk_iommu_suspend_reg {
+   u32 standard_axi_mode;
+   u32 dcm_dis;
+   u32 ctrl_reg;
+   u32 int_control0;
+   u32 int_main_control;
+};
+
+struct mtk_iommu_client_priv {
+   struct list_headclient;
+   unsigned intmtk_m4u_id;
+   struct device   *m4udev;
+};
+
+struct mtk_iommu_domain;
+
+struct mtk_iommu_data {
+   void __iomem*base;
+   int irq;
+   struct device   *dev;
+   struct clk  *bclk;
+   phys_addr_t protect_base; /* protect memory base */
+   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;
+};
+
+static int compare_of(struct device *dev, void *data)
+{
+   return dev->of_node == data;
+}
+
+static 

[PATCH v4 1/5] dt-bindings: mediatek: add descriptions for mediatek mt2701 iommu and smi

2016-06-08 Thread honghui.zhang
From: Honghui Zhang 

This patch defines the local arbitor port IDs for mediatek SoC MT2701 and
add descriptions of binding for mediatek generation one iommu and smi.

Signed-off-by: Honghui Zhang 
Acked-by: Rob Herring 
---
 .../devicetree/bindings/iommu/mediatek,iommu.txt   | 13 +++-
 .../memory-controllers/mediatek,smi-common.txt | 21 +-
 .../memory-controllers/mediatek,smi-larb.txt   |  4 +-
 include/dt-bindings/memory/mt2701-larb-port.h  | 85 ++
 4 files changed, 115 insertions(+), 8 deletions(-)
 create mode 100644 include/dt-bindings/memory/mt2701-larb-port.h

diff --git a/Documentation/devicetree/bindings/iommu/mediatek,iommu.txt 
b/Documentation/devicetree/bindings/iommu/mediatek,iommu.txt
index cd1b1cd..53c20ca 100644
--- a/Documentation/devicetree/bindings/iommu/mediatek,iommu.txt
+++ b/Documentation/devicetree/bindings/iommu/mediatek,iommu.txt
@@ -1,7 +1,9 @@
 * 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.
+  Some Mediatek SOCs contain a Multimedia Memory Management Unit (M4U), and
+this M4U have two generations of HW architecture. Generation one uses flat
+pagetable, and only supports 4K size page mapping. Generation two uses the
+ARM Short-Descriptor translation table format for address translation.
 
   About the M4U Hardware Block Diagram, please check below:
 
@@ -36,7 +38,9 @@ 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".
+- compatible : must be one of the following string:
+   "mediatek,mt2701-m4u" for mt2701 which uses generation one m4u HW.
+   "mediatek,mt8173-m4u" for mt8173 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.
@@ -46,7 +50,8 @@ Required properties:
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.
+   dt-binding/memory/mt2701-larb-port.h for mt2701 and
+   dt-binding/memory/mt8173-larb-port.h for mt8173
 
 Example:
iommu: iommu@10205000 {
diff --git 
a/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-common.txt 
b/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-common.txt
index 06a83ce..aa614b2 100644
--- 
a/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-common.txt
+++ 
b/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-common.txt
@@ -2,16 +2,31 @@ SMI (Smart Multimedia Interface) Common
 
 The hardware block diagram please check bindings/iommu/mediatek,iommu.txt
 
+Mediatek SMI have two generations of HW architecture, mt8173 uses the second
+generation of SMI HW while mt2701 uses the first generation HW of SMI.
+
+There's slight differences between the two SMI, for generation 2, the
+register which control the iommu port is at each larb's register base. But
+for generation 1, the register is at smi ao base(smi always on register
+base). Besides that, the smi async clock should be prepared and enabled for
+SMI generation 1 to transform the smi clock into emi clock domain, but that is
+not needed for SMI generation 2.
+
 Required properties:
-- compatible : must be "mediatek,mt8173-smi-common"
+- compatible : must be one of :
+   "mediatek,mt2701-smi-common"
+   "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:
+- clock-names : must contain 3 entries for generation 1 smi HW and 2 entries
+  for generation 2 smi HW 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.
+   They may be the same if both source clocks are the same.
+  - "async" : asynchronous clock, it help transform the smi clock into the emi
+ clock domain, this clock is only needed by generation 1 smi HW.
 
 Example:
smi_common: smi@14022000 {
diff --git 
a/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.txt 
b/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.txt
index 55ff3b7..21277a5 100644
--- a/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.txt
+++ 

[PATCH v4 0/5] MT2701 iommu support

2016-06-08 Thread honghui.zhang
From: Honghui Zhang 

  Mediatek's m4u(Multimedia Memory Management Unit) and SMI(Smart
Multimedia Interface)have two generations HW. They basically sharing the
same hardware block diagram, but have some difference as below:

  Generation one m4u only supports one layer, flat pagetable addressing,
and only supports 4K size page mapping. While generation two m4u supports 2
levels of pagetable which uses the ARM short-descriptor translation table
format for address translation.
They have slight different register base and register offset.
They have very different HW ports defines.

  Generaion one SMI has additional "async" clock which transform the smi
clock into emi clock domain, this clock should be prepared and enabled for
SMI generation one HW.
The register which control the iommu need to translation the address or not
for a particular port is located at smi ao base(smi always on register
base) for generation one SMI HW, but located at each larb's register base
for generation two HW.

This patch set add mt2701 iommu support, it's based on 4.7-rc1 and James
Liao's "Add clock support for Mediatek MT2701 v8[1]" and "Mediatek MT2701
SCPSYS power domain support v7[2]" patch.

v4:
-Rebase on 4.7-rc1.
-Do not call of_node_put call in mtk_iommu_create_mapping.

v3: https://lists.linuxfoundation.org/pipermail/iommu/2016-May/017179.html
-Rebase on "of: Implement iterator for phandles[3]" and take use of
 of_for_each_phandle.
-Forward-declare mtk_iommu_domain and implement the struct separately.
-Free the pagetable memory in mtk_iommu_domain_free
-Roll back the mapping in error case.
-Minor cleanups.

v2: https://lists.linuxfoundation.org/pipermail/iommu/2016-May/017068.html
-Fix syntax errors in dt-bindings.
-Use dma_alloc/free_coherent to allocate pagetable memory and reduce the
 streaming DMA stuff.
-Make the mtk_iommu_ops.pgsize_bitmap as ~0UL << MT2701_IOMMU_PAGE_SHIFT.
-Use macro instead of variable to indicate the pagetable size.
-Change some macro name from MTK_XXX to MT2701_XXX.

v1: http://lists.infradead.org/pipermail/linux-mediatek/2016-May/005301.html
-initial version

[1] http://lists.infradead.org/pipermail/linux-mediatek/2016-May/005439.html
[2] http://lists.infradead.org/pipermail/linux-mediatek/2016-May/005429.html
[3] https://lists.linuxfoundation.org/pipermail/iommu/2016-April/016300.html

Honghui Zhang (5):
  dt-bindings: mediatek: add descriptions for mediatek mt2701 iommu and
smi
  iommu/mediatek: move the common struct into header file
  memory/mediatek: add support for mt2701
  iommu/mediatek: add support for mtk iommu generation one HW
  ARM: dts: mt2701: add iommu/smi dtsi node for mt2701

 .../devicetree/bindings/iommu/mediatek,iommu.txt   |  13 +-
 .../memory-controllers/mediatek,smi-common.txt |  21 +-
 .../memory-controllers/mediatek,smi-larb.txt   |   4 +-
 arch/arm/boot/dts/mt2701.dtsi  |  51 ++
 drivers/iommu/Kconfig  |  18 +
 drivers/iommu/Makefile |   1 +
 drivers/iommu/mtk_iommu.c  |  48 +-
 drivers/iommu/mtk_iommu.h  |  77 +++
 drivers/iommu/mtk_iommu_v1.c   | 727 +
 drivers/memory/mtk-smi.c   | 167 -
 include/dt-bindings/memory/mt2701-larb-port.h  |  85 +++
 11 files changed, 1139 insertions(+), 73 deletions(-)
 create mode 100644 drivers/iommu/mtk_iommu.h
 create mode 100644 drivers/iommu/mtk_iommu_v1.c
 create mode 100644 include/dt-bindings/memory/mt2701-larb-port.h

-- 
1.8.1.1.dirty

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


[PATCH v4 4/5] iommu/mediatek: add support for mtk iommu generation one HW

2016-06-08 Thread honghui.zhang
From: Honghui Zhang 

Mediatek SoC's M4U has two generations of HW architcture. Generation one
uses flat, one layer pagetable, and was shipped with ARM architecture, it
only supports 4K size page mapping. MT2701 SoC uses this generation one
m4u HW. Generation two uses the ARM short-descriptor translation table
format for address translation, and was shipped with ARM64 architecture,
MT8173 uses this generation two m4u HW. All the two generation iommu HW
only have one iommu domain, and all its iommu clients share the same
iova address.

These two generation m4u HW have slit different register groups and
register offset, but most register names are the same. This patch add iommu
support for mediatek SoC mt2701.

Signed-off-by: Honghui Zhang 
---
 drivers/iommu/Kconfig|  18 ++
 drivers/iommu/Makefile   |   1 +
 drivers/iommu/mtk_iommu_v1.c | 727 +++
 3 files changed, 746 insertions(+)
 create mode 100644 drivers/iommu/mtk_iommu_v1.c

diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
index ad08603..32bb1e5 100644
--- a/drivers/iommu/Kconfig
+++ b/drivers/iommu/Kconfig
@@ -343,4 +343,22 @@ config MTK_IOMMU
 
  If unsure, say N here.
 
+config MTK_IOMMU_V1
+   bool "MTK IOMMU Version 1 (M4U gen1) Support"
+   depends on ARM
+   depends on ARCH_MEDIATEK || COMPILE_TEST
+   select ARM_DMA_USE_IOMMU
+   select IOMMU_API
+   select MEMORY
+   select MTK_SMI
+   select COMMON_CLK_MT2701_MMSYS
+   select COMMON_CLK_MT2701_IMGSYS
+   select COMMON_CLK_MT2701_VDECSYS
+   help
+ Support for the M4U on certain Mediatek SoCs. M4U generation 1 HW is
+ Multimedia Memory Managememt 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 c6edb31..778baf5 100644
--- a/drivers/iommu/Makefile
+++ b/drivers/iommu/Makefile
@@ -18,6 +18,7 @@ obj-$(CONFIG_INTEL_IOMMU_SVM) += intel-svm.o
 obj-$(CONFIG_IPMMU_VMSA) += ipmmu-vmsa.o
 obj-$(CONFIG_IRQ_REMAP) += intel_irq_remapping.o irq_remapping.o
 obj-$(CONFIG_MTK_IOMMU) += mtk_iommu.o
+obj-$(CONFIG_MTK_IOMMU_V1) += mtk_iommu_v1.o
 obj-$(CONFIG_OMAP_IOMMU) += omap-iommu.o
 obj-$(CONFIG_OMAP_IOMMU_DEBUG) += omap-iommu-debug.o
 obj-$(CONFIG_ROCKCHIP_IOMMU) += rockchip-iommu.o
diff --git a/drivers/iommu/mtk_iommu_v1.c b/drivers/iommu/mtk_iommu_v1.c
new file mode 100644
index 000..294485d
--- /dev/null
+++ b/drivers/iommu/mtk_iommu_v1.c
@@ -0,0 +1,727 @@
+/*
+ * Copyright (c) 2015-2016 MediaTek Inc.
+ * Author: Honghui Zhang 
+ *
+ * Based on driver/iommu/mtk_iommu.c
+ *
+ * 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 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "mtk_iommu.h"
+
+#define REG_MMU_PT_BASE_ADDR   0x000
+
+#define F_ALL_INVLD0x2
+#define F_MMU_INV_RANGE0x1
+#define F_INVLD_EN0BIT(0)
+#define F_INVLD_EN1BIT(1)
+
+#define F_MMU_FAULT_VA_MSK 0xf000
+#define MTK_PROTECT_PA_ALIGN   128
+
+#define REG_MMU_CTRL_REG   0x210
+#define F_MMU_CTRL_COHERENT_EN BIT(8)
+#define REG_MMU_IVRP_PADDR 0x214
+#define REG_MMU_INT_CONTROL0x220
+#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_TABLE_WALK_FAULT BIT(4)
+#define F_INT_TLB_MISS_FAULT   BIT(5)
+#define F_INT_PFH_DMA_FIFO_OVERFLOWBIT(6)
+#define F_INT_MISS_DMA_FIFO_OVERFLOW   BIT(7)
+
+#define F_MMU_TF_PROTECT_SEL(prot) (((prot) & 0x3) << 5)
+#define F_INT_CLR_BIT  BIT(12)
+
+#define REG_MMU_FAULT_ST   0x224
+#define REG_MMU_FAULT_VA   0x228
+#define REG_MMU_INVLD_PA   0x22C
+#define REG_MMU_INT_ID 0x388
+#define REG_MMU_INVALIDATE   

[PATCH v4 3/5] memory/mediatek: add support for mt2701

2016-06-08 Thread honghui.zhang
From: Honghui Zhang 

Mediatek SMI has two generations of HW architecture, mt8173 uses the
second generation of SMI HW while mt2701 uses the first generation
HW of SMI.

There's slight differences between the two generations, for generation 2,
the register which control the iommu port access PA or IOVA is at each
larb's register base. But for generation 1, the register is at smi ao
base(smi always on register base).
Besides that, the smi async clock should be prepared and enabled for SMI
generation 1 HW to transform the smi clock into emi clock domain, but is
not needed for SMI generation 2.

This patch add SMI driver for mt2701 which use generation 1 SMI HW.

Signed-off-by: Honghui Zhang 
---
 drivers/memory/mtk-smi.c | 167 ++-
 1 file changed, 149 insertions(+), 18 deletions(-)

diff --git a/drivers/memory/mtk-smi.c b/drivers/memory/mtk-smi.c
index f6b5757..4afbc41 100644
--- a/drivers/memory/mtk-smi.c
+++ b/drivers/memory/mtk-smi.c
@@ -21,19 +21,50 @@
 #include 
 #include 
 #include 
+#include 
 
 #define SMI_LARB_MMU_EN0xf00
+#define REG_SMI_SECUR_CON_BASE 0x5c0
+
+/* every register control 8 port, register offset 0x4 */
+#define REG_SMI_SECUR_CON_OFFSET(id)   (((id) >> 3) << 2)
+#define REG_SMI_SECUR_CON_ADDR(id) \
+   (REG_SMI_SECUR_CON_BASE + REG_SMI_SECUR_CON_OFFSET(id))
+
+/*
+ * every port have 4 bit to control, bit[port + 3] control virtual or physical,
+ * bit[port + 2 : port + 1] control the domain, bit[port] control the security
+ * or non-security.
+ */
+#define SMI_SECUR_CON_VAL_MSK(id)  (~(0xf << (((id) & 0x7) << 2)))
+#define SMI_SECUR_CON_VAL_VIRT(id) BITid) & 0x7) << 2) + 3)
+/* mt2701 domain should be set to 3 */
+#define SMI_SECUR_CON_VAL_DOMAIN(id)   (0x3 << id) & 0x7) << 2) + 1))
+
+struct mtk_smi_larb_gen {
+   int port_in_larb[MTK_LARB_NR_MAX + 1];
+   void (*config_port)(struct device *);
+};
 
 struct mtk_smi {
-   struct device   *dev;
-   struct clk  *clk_apb, *clk_smi;
+   struct device   *dev;
+   struct clk  *clk_apb, *clk_smi;
+   struct clk  *clk_async; /*only needed by mt2701*/
+   void __iomem*smi_ao_base;
 };
 
 struct mtk_smi_larb { /* larb: local arbiter */
-   struct mtk_smi  smi;
-   void __iomem*base;
-   struct device   *smi_common_dev;
-   u32 *mmu;
+   struct mtk_smi  smi;
+   void __iomem*base;
+   struct device   *smi_common_dev;
+   const struct mtk_smi_larb_gen   *larb_gen;
+   int larbid;
+   u32 *mmu;
+};
+
+enum mtk_smi_gen {
+   MTK_SMI_GEN1,
+   MTK_SMI_GEN2
 };
 
 static int mtk_smi_enable(const struct mtk_smi *smi)
@@ -71,6 +102,7 @@ static void mtk_smi_disable(const struct mtk_smi *smi)
 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;
 
@@ -87,7 +119,7 @@ int mtk_smi_larb_get(struct device *larbdev)
}
 
/* Configure the iommu info for this larb */
-   writel(*larb->mmu, larb->base + SMI_LARB_MMU_EN);
+   larb_gen->config_port(larbdev);
 
return 0;
 }
@@ -126,6 +158,45 @@ mtk_smi_larb_bind(struct device *dev, struct device 
*master, void *data)
return -ENODEV;
 }
 
+static void mtk_smi_larb_config_port(struct device *dev)
+{
+   struct mtk_smi_larb *larb = dev_get_drvdata(dev);
+
+   writel(*larb->mmu, larb->base + SMI_LARB_MMU_EN);
+}
+
+
+static void mtk_smi_larb_config_port_gen1(struct device *dev)
+{
+   struct mtk_smi_larb *larb = dev_get_drvdata(dev);
+   const struct mtk_smi_larb_gen *larb_gen = larb->larb_gen;
+   struct mtk_smi *common = dev_get_drvdata(larb->smi_common_dev);
+   int i, m4u_port_id, larb_port_num;
+   u32 sec_con_val, reg_val;
+
+   m4u_port_id = larb_gen->port_in_larb[larb->larbid];
+   larb_port_num = larb_gen->port_in_larb[larb->larbid + 1]
+   - larb_gen->port_in_larb[larb->larbid];
+
+   for (i = 0; i < larb_port_num; i++, m4u_port_id++) {
+   if (*larb->mmu & BIT(i)) {
+   /* bit[port + 3] controls the virtual or physical */
+   sec_con_val = SMI_SECUR_CON_VAL_VIRT(m4u_port_id);
+   } else {
+   /* do not need to enable m4u for this port */
+   continue;
+   }
+   reg_val = readl(common->smi_ao_base
+   + REG_SMI_SECUR_CON_ADDR(m4u_port_id));
+   reg_val &= SMI_SECUR_CON_VAL_MSK(m4u_port_id);
+   reg_val |= 

[PATCH] iommu/mediatek: Do not call of_node_put in mtk_iommu_of_xlate

2016-06-08 Thread honghui.zhang
From: Honghui Zhang 

The device_node will be released in of_iommu_configure, it may be double
released if call of_node_put in mtk_iommu_of_xlate.

Signed-off-by: Honghui Zhang 
---
 drivers/iommu/mtk_iommu.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index c3043d8..493bd3e 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -455,7 +455,6 @@ static int mtk_iommu_of_xlate(struct device *dev, struct 
of_phandle_args *args)
if (!dev->archdata.iommu) {
/* Get the m4u device */
m4updev = of_find_device_by_node(args->np);
-   of_node_put(args->np);
if (WARN_ON(!m4updev))
return -EINVAL;
 
-- 
1.8.1.1.dirty

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


[PATCH v3 0/5] MT2701 iommu support

2016-05-27 Thread honghui.zhang
From: Honghui Zhang 

  Mediatek's m4u(Multimedia Memory Management Unit) and SMI(Smart
Multimedia Interface)have two generations HW. They basically sharing the
same hardware block diagram, but have some difference as below:

  Generation one m4u only supports one layer, flat pagetable addressing,
and only supports 4K size page mapping. While generation two m4u supports 2
levels of pagetable which uses the ARM short-descriptor translation table
format for address translation.
They have slight different register base and register offset.
They have very different HW ports defines.

  Generaion one SMI has additional "async" clock which transform the smi
clock into emi clock domain, this clock should be prepared and enabled for
SMI generation one HW.
The register which control the iommu need to translation the address or not
for a particular port is located at smi ao base(smi always on register
base) for generation one SMI HW, but located at each larb's register base
for generation two HW.

This patch set add mt2701 iommu support, it's based on 4.6-rc1 and James
Liao's "Add clock support for Mediatek MT2701 v8[1]" and "Mediatek MT2701
SCPSYS power domain support v7[2]" patch.

v3:
-Rebase on "of: Implement iterator for phandles[3]" and take use of
 of_for_each_phandle.
-Forward-declare mtk_iommu_domain and implement the struct separately.
-Free the pagetable memory in mtk_iommu_domain_free
-Roll back the mapping in error case.
-Minor cleanups.

v2: https://lists.linuxfoundation.org/pipermail/iommu/2016-May/017068.html
-Fix syntax errors in dt-bindings.
-Use dma_alloc/free_coherent to allocate pagetable memory and reduce the
 streaming DMA stuff.
-Make the mtk_iommu_ops.pgsize_bitmap as ~0UL << MT2701_IOMMU_PAGE_SHIFT.
-Use macro instead of variable to indicate the pagetable size.
-Change some macro name from MTK_XXX to MT2701_XXX.

v1: http://lists.infradead.org/pipermail/linux-mediatek/2016-May/005301.html
-initial version

[1] http://lists.infradead.org/pipermail/linux-mediatek/2016-May/005439.html
[2] http://lists.infradead.org/pipermail/linux-mediatek/2016-May/005429.html
[3] https://lists.linuxfoundation.org/pipermail/iommu/2016-April/016300.html

Honghui Zhang (5):
  dt-bindings: mediatek: add descriptions for mediatek mt2701 iommu and
smi
  iommu/mediatek: move the common struct into header file
  memory/mediatek: add support for mt2701
  iommu/mediatek: add support for mtk iommu generation one HW
  ARM: dts: mt2701: add iommu/smi dtsi node for mt2701

 .../devicetree/bindings/iommu/mediatek,iommu.txt   |  13 +-
 .../memory-controllers/mediatek,smi-common.txt |  21 +-
 .../memory-controllers/mediatek,smi-larb.txt   |   4 +-
 arch/arm/boot/dts/mt2701.dtsi  |  51 ++
 drivers/iommu/Kconfig  |  18 +
 drivers/iommu/Makefile |   1 +
 drivers/iommu/mtk_iommu.c  |  48 +-
 drivers/iommu/mtk_iommu.h  |  77 +++
 drivers/iommu/mtk_iommu_v1.c   | 728 +
 drivers/memory/mtk-smi.c   | 168 -
 include/dt-bindings/memory/mt2701-larb-port.h  |  85 +++
 11 files changed, 1140 insertions(+), 74 deletions(-)
 create mode 100644 drivers/iommu/mtk_iommu.h
 create mode 100644 drivers/iommu/mtk_iommu_v1.c
 create mode 100644 include/dt-bindings/memory/mt2701-larb-port.h

-- 
1.8.1.1.dirty

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


[PATCH v3 3/5] memory/mediatek: add support for mt2701

2016-05-27 Thread honghui.zhang
From: Honghui Zhang 

Mediatek SMI has two generations of HW architecture, mt8173 uses the
second generation of SMI HW while mt2701 uses the first generation
HW of SMI.

There's slight differences between the two generations, for generation 2,
the register which control the iommu port access PA or IOVA is at each
larb's register base. But for generation 1, the register is at smi ao
base(smi always on register base).
Besides that, the smi async clock should be prepared and enabled for SMI
generation 1 HW to transform the smi clock into emi clock domain, but is
not needed for SMI generation 2.

This patch add SMI driver for mt2701 which use generation 1 SMI HW.

Signed-off-by: Honghui Zhang 
---
 drivers/memory/mtk-smi.c | 168 +--
 1 file changed, 149 insertions(+), 19 deletions(-)

diff --git a/drivers/memory/mtk-smi.c b/drivers/memory/mtk-smi.c
index 089091f..0a47382 100644
--- a/drivers/memory/mtk-smi.c
+++ b/drivers/memory/mtk-smi.c
@@ -21,19 +21,50 @@
 #include 
 #include 
 #include 
+#include 
 
 #define SMI_LARB_MMU_EN0xf00
+#define REG_SMI_SECUR_CON_BASE 0x5c0
+
+/* every register control 8 port, register offset 0x4 */
+#define REG_SMI_SECUR_CON_OFFSET(id)   (((id) >> 3) << 2)
+#define REG_SMI_SECUR_CON_ADDR(id) \
+   (REG_SMI_SECUR_CON_BASE + REG_SMI_SECUR_CON_OFFSET(id))
+
+/*
+ * every port have 4 bit to control, bit[port + 3] control virtual or physical,
+ * bit[port + 2 : port + 1] control the domain, bit[port] control the security
+ * or non-security.
+ */
+#define SMI_SECUR_CON_VAL_MSK(id)  (~(0xf << (((id) & 0x7) << 2)))
+#define SMI_SECUR_CON_VAL_VIRT(id) BITid) & 0x7) << 2) + 3)
+/* mt2701 domain should be set to 3 */
+#define SMI_SECUR_CON_VAL_DOMAIN(id)   (0x3 << id) & 0x7) << 2) + 1))
+
+struct mtk_smi_larb_gen {
+   int port_in_larb[MTK_LARB_NR_MAX + 1];
+   void (*config_port)(struct device *);
+};
 
 struct mtk_smi {
-   struct device   *dev;
-   struct clk  *clk_apb, *clk_smi;
+   struct device   *dev;
+   struct clk  *clk_apb, *clk_smi;
+   struct clk  *clk_async; /*only needed by mt2701*/
+   void __iomem*smi_ao_base;
 };
 
 struct mtk_smi_larb { /* larb: local arbiter */
-   struct mtk_smi  smi;
-   void __iomem*base;
-   struct device   *smi_common_dev;
-   u32 *mmu;
+   struct mtk_smi  smi;
+   void __iomem*base;
+   struct device   *smi_common_dev;
+   const struct mtk_smi_larb_gen   *larb_gen;
+   int larbid;
+   u32 *mmu;
+};
+
+enum mtk_smi_gen {
+   MTK_SMI_GEN1,
+   MTK_SMI_GEN2
 };
 
 static int mtk_smi_enable(const struct mtk_smi *smi)
@@ -71,6 +102,7 @@ static void mtk_smi_disable(const struct mtk_smi *smi)
 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;
 
@@ -87,8 +119,7 @@ int mtk_smi_larb_get(struct device *larbdev)
}
 
/* Configure the iommu info for this larb */
-   writel(*larb->mmu, larb->base + SMI_LARB_MMU_EN);
-
+   larb_gen->config_port(larbdev);
return 0;
 }
 
@@ -124,6 +155,45 @@ mtk_smi_larb_bind(struct device *dev, struct device 
*master, void *data)
return -ENODEV;
 }
 
+static void mtk_smi_larb_config_port(struct device *dev)
+{
+   struct mtk_smi_larb *larb = dev_get_drvdata(dev);
+
+   writel(*larb->mmu, larb->base + SMI_LARB_MMU_EN);
+}
+
+
+static void mtk_smi_larb_config_port_gen1(struct device *dev)
+{
+   struct mtk_smi_larb *larb = dev_get_drvdata(dev);
+   const struct mtk_smi_larb_gen *larb_gen = larb->larb_gen;
+   struct mtk_smi *common = dev_get_drvdata(larb->smi_common_dev);
+   int i, m4u_port_id, larb_port_num;
+   u32 sec_con_val, reg_val;
+
+   m4u_port_id = larb_gen->port_in_larb[larb->larbid];
+   larb_port_num = larb_gen->port_in_larb[larb->larbid + 1]
+   - larb_gen->port_in_larb[larb->larbid];
+
+   for (i = 0; i < larb_port_num; i++, m4u_port_id++) {
+   if (*larb->mmu & BIT(i)) {
+   /* bit[port + 3] controls the virtual or physical */
+   sec_con_val = SMI_SECUR_CON_VAL_VIRT(m4u_port_id);
+   } else {
+   /* do not need to enable m4u for this port */
+   continue;
+   }
+   reg_val = readl(common->smi_ao_base
+   + REG_SMI_SECUR_CON_ADDR(m4u_port_id));
+   reg_val &= SMI_SECUR_CON_VAL_MSK(m4u_port_id);
+   reg_val |= 

[PATCH v3 4/5] iommu/mediatek: add support for mtk iommu generation one HW

2016-05-27 Thread honghui.zhang
From: Honghui Zhang 

Mediatek SoC's M4U has two generations of HW architcture. Generation one
uses flat, one layer pagetable, and was shipped with ARM architecture, it
only supports 4K size page mapping. MT2701 SoC uses this generation one
m4u HW. Generation two uses the ARM short-descriptor translation table
format for address translation, and was shipped with ARM64 architecture,
MT8173 uses this generation two m4u HW. All the two generation iommu HW
only have one iommu domain, and all its iommu clients share the same
iova address.

These two generation m4u HW have slit different register groups and
register offset, but most register names are the same. This patch add iommu
support for mediatek SoC mt2701.

Signed-off-by: Honghui Zhang 
---
 drivers/iommu/Kconfig|  18 ++
 drivers/iommu/Makefile   |   1 +
 drivers/iommu/mtk_iommu_v1.c | 728 +++
 3 files changed, 747 insertions(+)
 create mode 100644 drivers/iommu/mtk_iommu_v1.c

diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
index dd1dc39..363c1d8 100644
--- a/drivers/iommu/Kconfig
+++ b/drivers/iommu/Kconfig
@@ -354,4 +354,22 @@ config MTK_IOMMU
 
  If unsure, say N here.
 
+config MTK_IOMMU_V1
+   bool "MTK IOMMU Version 1 (M4U gen1) Support"
+   depends on ARM
+   depends on ARCH_MEDIATEK || COMPILE_TEST
+   select ARM_DMA_USE_IOMMU
+   select IOMMU_API
+   select MEMORY
+   select MTK_SMI
+   select COMMON_CLK_MT2701_MMSYS
+   select COMMON_CLK_MT2701_IMGSYS
+   select COMMON_CLK_MT2701_VDECSYS
+   help
+ Support for the M4U on certain Mediatek SoCs. M4U generation 1 HW is
+ Multimedia Memory Managememt 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 c6edb31..778baf5 100644
--- a/drivers/iommu/Makefile
+++ b/drivers/iommu/Makefile
@@ -18,6 +18,7 @@ obj-$(CONFIG_INTEL_IOMMU_SVM) += intel-svm.o
 obj-$(CONFIG_IPMMU_VMSA) += ipmmu-vmsa.o
 obj-$(CONFIG_IRQ_REMAP) += intel_irq_remapping.o irq_remapping.o
 obj-$(CONFIG_MTK_IOMMU) += mtk_iommu.o
+obj-$(CONFIG_MTK_IOMMU_V1) += mtk_iommu_v1.o
 obj-$(CONFIG_OMAP_IOMMU) += omap-iommu.o
 obj-$(CONFIG_OMAP_IOMMU_DEBUG) += omap-iommu-debug.o
 obj-$(CONFIG_ROCKCHIP_IOMMU) += rockchip-iommu.o
diff --git a/drivers/iommu/mtk_iommu_v1.c b/drivers/iommu/mtk_iommu_v1.c
new file mode 100644
index 000..a2a2554
--- /dev/null
+++ b/drivers/iommu/mtk_iommu_v1.c
@@ -0,0 +1,728 @@
+/*
+ * Copyright (c) 2015-2016 MediaTek Inc.
+ * Author: Honghui Zhang 
+ *
+ * Based on driver/iommu/mtk_iommu.c
+ *
+ * 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 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "mtk_iommu.h"
+
+#define REG_MMU_PT_BASE_ADDR   0x000
+
+#define F_ALL_INVLD0x2
+#define F_MMU_INV_RANGE0x1
+#define F_INVLD_EN0BIT(0)
+#define F_INVLD_EN1BIT(1)
+
+#define F_MMU_FAULT_VA_MSK 0xf000
+#define MTK_PROTECT_PA_ALIGN   128
+
+#define REG_MMU_CTRL_REG   0x210
+#define F_MMU_CTRL_COHERENT_EN BIT(8)
+#define REG_MMU_IVRP_PADDR 0x214
+#define REG_MMU_INT_CONTROL0x220
+#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_TABLE_WALK_FAULT BIT(4)
+#define F_INT_TLB_MISS_FAULT   BIT(5)
+#define F_INT_PFH_DMA_FIFO_OVERFLOWBIT(6)
+#define F_INT_MISS_DMA_FIFO_OVERFLOW   BIT(7)
+
+#define F_MMU_TF_PROTECT_SEL(prot) (((prot) & 0x3) << 5)
+#define F_INT_CLR_BIT  BIT(12)
+
+#define REG_MMU_FAULT_ST   0x224
+#define REG_MMU_FAULT_VA   0x228
+#define REG_MMU_INVLD_PA   0x22C
+#define REG_MMU_INT_ID 0x388
+#define REG_MMU_INVALIDATE   

[PATCH v3 1/5] dt-bindings: mediatek: add descriptions for mediatek mt2701 iommu and smi

2016-05-27 Thread honghui.zhang
From: Honghui Zhang 

This patch defines the local arbitor port IDs for mediatek SoC MT2701 and
add descriptions of binding for mediatek generation one iommu and smi.

Signed-off-by: Honghui Zhang 
Acked-by: Rob Herring 
---
 .../devicetree/bindings/iommu/mediatek,iommu.txt   | 13 +++-
 .../memory-controllers/mediatek,smi-common.txt | 21 +-
 .../memory-controllers/mediatek,smi-larb.txt   |  4 +-
 include/dt-bindings/memory/mt2701-larb-port.h  | 85 ++
 4 files changed, 115 insertions(+), 8 deletions(-)
 create mode 100644 include/dt-bindings/memory/mt2701-larb-port.h

diff --git a/Documentation/devicetree/bindings/iommu/mediatek,iommu.txt 
b/Documentation/devicetree/bindings/iommu/mediatek,iommu.txt
index cd1b1cd..53c20ca 100644
--- a/Documentation/devicetree/bindings/iommu/mediatek,iommu.txt
+++ b/Documentation/devicetree/bindings/iommu/mediatek,iommu.txt
@@ -1,7 +1,9 @@
 * 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.
+  Some Mediatek SOCs contain a Multimedia Memory Management Unit (M4U), and
+this M4U have two generations of HW architecture. Generation one uses flat
+pagetable, and only supports 4K size page mapping. Generation two uses the
+ARM Short-Descriptor translation table format for address translation.
 
   About the M4U Hardware Block Diagram, please check below:
 
@@ -36,7 +38,9 @@ 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".
+- compatible : must be one of the following string:
+   "mediatek,mt2701-m4u" for mt2701 which uses generation one m4u HW.
+   "mediatek,mt8173-m4u" for mt8173 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.
@@ -46,7 +50,8 @@ Required properties:
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.
+   dt-binding/memory/mt2701-larb-port.h for mt2701 and
+   dt-binding/memory/mt8173-larb-port.h for mt8173
 
 Example:
iommu: iommu@10205000 {
diff --git 
a/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-common.txt 
b/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-common.txt
index 06a83ce..aa614b2 100644
--- 
a/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-common.txt
+++ 
b/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-common.txt
@@ -2,16 +2,31 @@ SMI (Smart Multimedia Interface) Common
 
 The hardware block diagram please check bindings/iommu/mediatek,iommu.txt
 
+Mediatek SMI have two generations of HW architecture, mt8173 uses the second
+generation of SMI HW while mt2701 uses the first generation HW of SMI.
+
+There's slight differences between the two SMI, for generation 2, the
+register which control the iommu port is at each larb's register base. But
+for generation 1, the register is at smi ao base(smi always on register
+base). Besides that, the smi async clock should be prepared and enabled for
+SMI generation 1 to transform the smi clock into emi clock domain, but that is
+not needed for SMI generation 2.
+
 Required properties:
-- compatible : must be "mediatek,mt8173-smi-common"
+- compatible : must be one of :
+   "mediatek,mt2701-smi-common"
+   "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:
+- clock-names : must contain 3 entries for generation 1 smi HW and 2 entries
+  for generation 2 smi HW 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.
+   They may be the same if both source clocks are the same.
+  - "async" : asynchronous clock, it help transform the smi clock into the emi
+ clock domain, this clock is only needed by generation 1 smi HW.
 
 Example:
smi_common: smi@14022000 {
diff --git 
a/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.txt 
b/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.txt
index 55ff3b7..21277a5 100644
--- a/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.txt
+++ 

[PATCH v3 5/5] ARM: dts: mt2701: add iommu/smi dtsi node for mt2701

2016-05-27 Thread honghui.zhang
From: Honghui Zhang 

Add the dtsi node of iommu and smi for mt2701.

Signed-off-by: Honghui Zhang 
---
 arch/arm/boot/dts/mt2701.dtsi | 51 +++
 1 file changed, 51 insertions(+)

diff --git a/arch/arm/boot/dts/mt2701.dtsi b/arch/arm/boot/dts/mt2701.dtsi
index 42d5a37..363de0d 100644
--- a/arch/arm/boot/dts/mt2701.dtsi
+++ b/arch/arm/boot/dts/mt2701.dtsi
@@ -16,6 +16,7 @@
 #include 
 #include 
 #include 
+#include 
 #include "skeleton64.dtsi"
 #include "mt2701-pinfunc.h"
 
@@ -160,6 +161,16 @@
clock-names = "system-clk", "rtc-clk";
};
 
+   smi_common: smi@1000c000 {
+   compatible = "mediatek,mt2701-smi-common";
+   reg = <0 0x1000c000 0 0x1000>;
+   clocks = < CLK_INFRA_SMI>,
+< CLK_MM_SMI_COMMON>,
+< CLK_INFRA_SMI>;
+   clock-names = "apb", "smi", "async";
+   power-domains = < MT2701_POWER_DOMAIN_DISP>;
+   };
+
sysirq: interrupt-controller@10200100 {
compatible = "mediatek,mt2701-sysirq",
 "mediatek,mt6577-sysirq";
@@ -169,6 +180,16 @@
reg = <0 0x10200100 0 0x1c>;
};
 
+   iommu: mmsys_iommu@10205000 {
+   compatible = "mediatek,mt2701-m4u";
+   reg = <0 0x10205000 0 0x1000>;
+   interrupts = ;
+   clocks = < CLK_INFRA_M4U>;
+   clock-names = "bclk";
+   mediatek,larbs = <  >;
+   #iommu-cells = <1>;
+   };
+
apmixedsys: syscon@10209000 {
compatible = "mediatek,mt2701-apmixedsys", "syscon";
reg = <0 0x10209000 0 0x1000>;
@@ -234,6 +255,16 @@
status = "disabled";
};
 
+   larb0: larb@1401 {
+   compatible = "mediatek,mt2701-smi-larb";
+   reg = <0 0x1401 0 0x1000>;
+   mediatek,smi = <_common>;
+   clocks = < CLK_MM_SMI_LARB0>,
+< CLK_MM_SMI_LARB0>;
+   clock-names = "apb", "smi";
+   power-domains = < MT2701_POWER_DOMAIN_DISP>;
+   };
+
imgsys: syscon@1500 {
compatible = "mediatek,mt2701-imgsys", "syscon";
reg = <0 0x1500 0 0x1000>;
@@ -241,6 +272,16 @@
status = "disabled";
};
 
+   larb2: larb@15001000 {
+   compatible = "mediatek,mt2701-smi-larb";
+   reg = <0 0x15001000 0 0x1000>;
+   mediatek,smi = <_common>;
+   clocks = < CLK_IMG_SMI_COMM>,
+< CLK_IMG_SMI_COMM>;
+   clock-names = "apb", "smi";
+   power-domains = < MT2701_POWER_DOMAIN_ISP>;
+   };
+
vdecsys: syscon@1600 {
compatible = "mediatek,mt2701-vdecsys", "syscon";
reg = <0 0x1600 0 0x1000>;
@@ -248,6 +289,16 @@
status = "disabled";
};
 
+   larb1: larb@1601 {
+   compatible = "mediatek,mt2701-smi-larb";
+   reg = <0 0x1601 0 0x1000>;
+   mediatek,smi = <_common>;
+   clocks = < CLK_VDEC_CKGEN>,
+< CLK_VDEC_LARB>;
+   clock-names = "apb", "smi";
+   power-domains = < MT2701_POWER_DOMAIN_VDEC>;
+   };
+
hifsys: syscon@1a00 {
compatible = "mediatek,mt2701-hifsys", "syscon";
reg = <0 0x1a00 0 0x1000>;
-- 
1.8.1.1.dirty

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


[PATCH v3 2/5] iommu/mediatek: move the common struct into header file

2016-05-27 Thread honghui.zhang
From: Honghui Zhang 

Move the struct defines of mtk iommu into a new header files for
common use.

Signed-off-by: Honghui Zhang 
---
 drivers/iommu/mtk_iommu.c | 48 +
 drivers/iommu/mtk_iommu.h | 77 +++
 2 files changed, 78 insertions(+), 47 deletions(-)
 create mode 100644 drivers/iommu/mtk_iommu.h

diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index db74553..f83c9bc 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -34,7 +34,7 @@
 #include 
 #include 
 
-#include "io-pgtable.h"
+#include "mtk_iommu.h"
 
 #define REG_MMU_PT_BASE_ADDR   0x000
 
@@ -93,20 +93,6 @@
 
 #define MTK_PROTECT_PA_ALIGN   128
 
-struct mtk_iommu_suspend_reg {
-   u32 standard_axi_mode;
-   u32 dcm_dis;
-   u32 ctrl_reg;
-   u32 int_control0;
-   u32 int_main_control;
-};
-
-struct mtk_iommu_client_priv {
-   struct list_headclient;
-   unsigned intmtk_m4u_id;
-   struct device   *m4udev;
-};
-
 struct mtk_iommu_domain {
spinlock_t  pgtlock; /* lock for page table */
 
@@ -116,19 +102,6 @@ struct mtk_iommu_domain {
struct iommu_domain domain;
 };
 
-struct mtk_iommu_data {
-   void __iomem*base;
-   int irq;
-   struct device   *dev;
-   struct clk  *bclk;
-   phys_addr_t protect_base; /* protect memory base */
-   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;
-};
-
 static struct iommu_ops mtk_iommu_ops;
 
 static struct mtk_iommu_domain *to_mtk_domain(struct iommu_domain *dom)
@@ -552,25 +525,6 @@ static int mtk_iommu_hw_init(const struct mtk_iommu_data 
*data)
return 0;
 }
 
-static int compare_of(struct device *dev, void *data)
-{
-   return dev->of_node == data;
-}
-
-static int mtk_iommu_bind(struct device *dev)
-{
-   struct mtk_iommu_data *data = dev_get_drvdata(dev);
-
-   return component_bind_all(dev, >smi_imu);
-}
-
-static void mtk_iommu_unbind(struct device *dev)
-{
-   struct mtk_iommu_data *data = dev_get_drvdata(dev);
-
-   component_unbind_all(dev, >smi_imu);
-}
-
 static const struct component_master_ops mtk_iommu_com_ops = {
.bind   = mtk_iommu_bind,
.unbind = mtk_iommu_unbind,
diff --git a/drivers/iommu/mtk_iommu.h b/drivers/iommu/mtk_iommu.h
new file mode 100644
index 000..9ed0a84
--- /dev/null
+++ b/drivers/iommu/mtk_iommu.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2015-2016 MediaTek Inc.
+ * Author: Honghui Zhang 
+ *
+ * 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 _MTK_IOMMU_H_
+#define _MTK_IOMMU_H_
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "io-pgtable.h"
+
+struct mtk_iommu_suspend_reg {
+   u32 standard_axi_mode;
+   u32 dcm_dis;
+   u32 ctrl_reg;
+   u32 int_control0;
+   u32 int_main_control;
+};
+
+struct mtk_iommu_client_priv {
+   struct list_headclient;
+   unsigned intmtk_m4u_id;
+   struct device   *m4udev;
+};
+
+struct mtk_iommu_domain;
+
+struct mtk_iommu_data {
+   void __iomem*base;
+   int irq;
+   struct device   *dev;
+   struct clk  *bclk;
+   phys_addr_t protect_base; /* protect memory base */
+   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;
+};
+
+static int compare_of(struct device *dev, void *data)
+{
+   return dev->of_node == data;
+}
+
+static 

[PATCH v2 2/5] iommu/mediatek: move the common struct into header file

2016-05-19 Thread honghui.zhang
From: Honghui Zhang 

Move the struct defines of mtk iommu into a new header files for
common use.

Signed-off-by: Honghui Zhang 
---
 drivers/iommu/mtk_iommu.c | 62 +---
 drivers/iommu/mtk_iommu.h | 90 +++
 2 files changed, 91 insertions(+), 61 deletions(-)
 create mode 100644 drivers/iommu/mtk_iommu.h

diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index db74553..a6b7846 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -34,7 +34,7 @@
 #include 
 #include 
 
-#include "io-pgtable.h"
+#include "mtk_iommu.h"
 
 #define REG_MMU_PT_BASE_ADDR   0x000
 
@@ -93,49 +93,8 @@
 
 #define MTK_PROTECT_PA_ALIGN   128
 
-struct mtk_iommu_suspend_reg {
-   u32 standard_axi_mode;
-   u32 dcm_dis;
-   u32 ctrl_reg;
-   u32 int_control0;
-   u32 int_main_control;
-};
-
-struct mtk_iommu_client_priv {
-   struct list_headclient;
-   unsigned intmtk_m4u_id;
-   struct device   *m4udev;
-};
-
-struct mtk_iommu_domain {
-   spinlock_t  pgtlock; /* lock for page table */
-
-   struct io_pgtable_cfg   cfg;
-   struct io_pgtable_ops   *iop;
-
-   struct iommu_domain domain;
-};
-
-struct mtk_iommu_data {
-   void __iomem*base;
-   int irq;
-   struct device   *dev;
-   struct clk  *bclk;
-   phys_addr_t protect_base; /* protect memory base */
-   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;
-};
-
 static struct iommu_ops mtk_iommu_ops;
 
-static struct mtk_iommu_domain *to_mtk_domain(struct iommu_domain *dom)
-{
-   return container_of(dom, struct mtk_iommu_domain, domain);
-}
-
 static void mtk_iommu_tlb_flush_all(void *cookie)
 {
struct mtk_iommu_data *data = cookie;
@@ -552,25 +511,6 @@ static int mtk_iommu_hw_init(const struct mtk_iommu_data 
*data)
return 0;
 }
 
-static int compare_of(struct device *dev, void *data)
-{
-   return dev->of_node == data;
-}
-
-static int mtk_iommu_bind(struct device *dev)
-{
-   struct mtk_iommu_data *data = dev_get_drvdata(dev);
-
-   return component_bind_all(dev, >smi_imu);
-}
-
-static void mtk_iommu_unbind(struct device *dev)
-{
-   struct mtk_iommu_data *data = dev_get_drvdata(dev);
-
-   component_unbind_all(dev, >smi_imu);
-}
-
 static const struct component_master_ops mtk_iommu_com_ops = {
.bind   = mtk_iommu_bind,
.unbind = mtk_iommu_unbind,
diff --git a/drivers/iommu/mtk_iommu.h b/drivers/iommu/mtk_iommu.h
new file mode 100644
index 000..5656355
--- /dev/null
+++ b/drivers/iommu/mtk_iommu.h
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2015-2016 MediaTek Inc.
+ * Author: Yong Wu 
+ *   : Honghui Zhang 
+ *
+ * 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 _MTK_IOMMU_H_
+#define _MTK_IOMMU_H_
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "io-pgtable.h"
+
+struct mtk_iommu_suspend_reg {
+   u32 standard_axi_mode;
+   u32 dcm_dis;
+   u32 ctrl_reg;
+   u32 int_control0;
+   u32 int_main_control;
+};
+
+struct mtk_iommu_client_priv {
+   struct list_headclient;
+   unsigned intmtk_m4u_id;
+   struct device   *m4udev;
+};
+
+struct mtk_iommu_domain {
+   spinlock_t  pgtlock; /* lock for page table */
+
+   struct io_pgtable_cfg   cfg;
+   struct io_pgtable_ops   *iop;
+
+   struct iommu_domain domain;
+};
+
+struct mtk_iommu_data {
+   void __iomem*base;
+   int irq;
+   struct device   *dev;
+   struct clk 

[PATCH 5/5] ARM: dts: mt2701: add iommu/smi dtsi node for mt2701

2016-05-19 Thread honghui.zhang
From: Honghui Zhang 

Add the dtsi node of iommu and smi for mt2701.

Signed-off-by: Honghui Zhang 
---
 arch/arm/boot/dts/mt2701.dtsi | 51 +++
 1 file changed, 51 insertions(+)

diff --git a/arch/arm/boot/dts/mt2701.dtsi b/arch/arm/boot/dts/mt2701.dtsi
index 42d5a37..363de0d 100644
--- a/arch/arm/boot/dts/mt2701.dtsi
+++ b/arch/arm/boot/dts/mt2701.dtsi
@@ -16,6 +16,7 @@
 #include 
 #include 
 #include 
+#include 
 #include "skeleton64.dtsi"
 #include "mt2701-pinfunc.h"
 
@@ -160,6 +161,16 @@
clock-names = "system-clk", "rtc-clk";
};
 
+   smi_common: smi@1000c000 {
+   compatible = "mediatek,mt2701-smi-common";
+   reg = <0 0x1000c000 0 0x1000>;
+   clocks = < CLK_INFRA_SMI>,
+< CLK_MM_SMI_COMMON>,
+< CLK_INFRA_SMI>;
+   clock-names = "apb", "smi", "async";
+   power-domains = < MT2701_POWER_DOMAIN_DISP>;
+   };
+
sysirq: interrupt-controller@10200100 {
compatible = "mediatek,mt2701-sysirq",
 "mediatek,mt6577-sysirq";
@@ -169,6 +180,16 @@
reg = <0 0x10200100 0 0x1c>;
};
 
+   iommu: mmsys_iommu@10205000 {
+   compatible = "mediatek,mt2701-m4u";
+   reg = <0 0x10205000 0 0x1000>;
+   interrupts = ;
+   clocks = < CLK_INFRA_M4U>;
+   clock-names = "bclk";
+   mediatek,larbs = <  >;
+   #iommu-cells = <1>;
+   };
+
apmixedsys: syscon@10209000 {
compatible = "mediatek,mt2701-apmixedsys", "syscon";
reg = <0 0x10209000 0 0x1000>;
@@ -234,6 +255,16 @@
status = "disabled";
};
 
+   larb0: larb@1401 {
+   compatible = "mediatek,mt2701-smi-larb";
+   reg = <0 0x1401 0 0x1000>;
+   mediatek,smi = <_common>;
+   clocks = < CLK_MM_SMI_LARB0>,
+< CLK_MM_SMI_LARB0>;
+   clock-names = "apb", "smi";
+   power-domains = < MT2701_POWER_DOMAIN_DISP>;
+   };
+
imgsys: syscon@1500 {
compatible = "mediatek,mt2701-imgsys", "syscon";
reg = <0 0x1500 0 0x1000>;
@@ -241,6 +272,16 @@
status = "disabled";
};
 
+   larb2: larb@15001000 {
+   compatible = "mediatek,mt2701-smi-larb";
+   reg = <0 0x15001000 0 0x1000>;
+   mediatek,smi = <_common>;
+   clocks = < CLK_IMG_SMI_COMM>,
+< CLK_IMG_SMI_COMM>;
+   clock-names = "apb", "smi";
+   power-domains = < MT2701_POWER_DOMAIN_ISP>;
+   };
+
vdecsys: syscon@1600 {
compatible = "mediatek,mt2701-vdecsys", "syscon";
reg = <0 0x1600 0 0x1000>;
@@ -248,6 +289,16 @@
status = "disabled";
};
 
+   larb1: larb@1601 {
+   compatible = "mediatek,mt2701-smi-larb";
+   reg = <0 0x1601 0 0x1000>;
+   mediatek,smi = <_common>;
+   clocks = < CLK_VDEC_CKGEN>,
+< CLK_VDEC_LARB>;
+   clock-names = "apb", "smi";
+   power-domains = < MT2701_POWER_DOMAIN_VDEC>;
+   };
+
hifsys: syscon@1a00 {
compatible = "mediatek,mt2701-hifsys", "syscon";
reg = <0 0x1a00 0 0x1000>;
-- 
1.8.1.1.dirty

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


[PATCH v2 0/5] MT2701 iommu support

2016-05-19 Thread honghui.zhang
From: Honghui Zhang 

  Mediatek's m4u(Multimedia Memory Management Unit) and SMI(Smart
Multimedia Interface)have two generations HW. They basically sharing the
same hardware block diagram, but have some difference as below:

  Generation one m4u only supports one layer, flat pagetable addressing,
and only supports 4K size page mapping. While generation two m4u supports 2
levels of pagetable which uses the ARM short-descriptor translation table
format for address translation.
They have slight different register base and register offset.
They have very different HW ports defines.

  Generaion one SMI has additional "async" clock which transform the smi
clock into emi clock domain, this clock should be prepared and enabled for
SMI generation one HW.
The register which control the iommu need to translation the address or not
for a particular port is located at smi ao base(smi always on register
base) for generation one SMI HW, but located at each larb's register base
for generation two HW.

This patch set add mt2701 iommu support, it's based on 4.6-rc1 and James
Liao's "Add clock support for Mediatek MT2701 v8[1]" and "Mediatek MT2701
SCPSYS power domain support v7[2]" patch.

v2:
-Fix syntax errors in dt-bindings.
-Use dma_alloc/free_coherent to allocate pagetable memory and reduce the
 streaming DMA stuff.
-Make the mtk_iommu_ops.pgsize_bitmap as ~0UL << MT2701_IOMMU_PAGE_SHIFT.
-Use macro instead of variable to indicate the pagetable size.
-Change some macro name from MTK_XXX to MT2701_XXX.

v1: http://lists.infradead.org/pipermail/linux-mediatek/2016-May/005301.html
-initial version

[1] http://lists.infradead.org/pipermail/linux-mediatek/2016-May/005439.html
[2] http://lists.infradead.org/pipermail/linux-mediatek/2016-May/005429.html

Honghui Zhang (5):
  dt-bindings: mediatek: add descriptions for mediatek mt2701 iommu and
smi
  iommu/mediatek: move the common struct into header file
  memory/mediatek: add support for mt2701
  iommu/mediatek: add support for mtk iommu generation one HW
  ARM: dts: mt2701: add iommu/smi dtsi node for mt2701

 .../devicetree/bindings/iommu/mediatek,iommu.txt   |  13 +-
 .../memory-controllers/mediatek,smi-common.txt |  21 +-
 .../memory-controllers/mediatek,smi-larb.txt   |   4 +-
 arch/arm/boot/dts/mt2701.dtsi  |  51 ++
 drivers/iommu/Kconfig  |  19 +
 drivers/iommu/Makefile |   1 +
 drivers/iommu/mtk_iommu.c  |  62 +-
 drivers/iommu/mtk_iommu.h  |  93 +++
 drivers/iommu/mtk_iommu_v1.c   | 742 +
 drivers/memory/mtk-smi.c   | 168 -
 include/dt-bindings/memory/mt2701-larb-port.h  |  85 +++
 11 files changed, 1171 insertions(+), 88 deletions(-)
 create mode 100644 drivers/iommu/mtk_iommu.h
 create mode 100644 drivers/iommu/mtk_iommu_v1.c
 create mode 100644 include/dt-bindings/memory/mt2701-larb-port.h

-- 
1.8.1.1.dirty

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


[PATCH v2 4/5] iommu/mediatek: add support for mtk iommu generation one HW

2016-05-19 Thread honghui.zhang
From: Honghui Zhang 

Mediatek SoC's M4U has two generations of HW architcture. Generation one
uses flat, one layer pagetable, and was shipped with ARM architecture, it
only supports 4K size page mapping. MT2701 SoC uses this generation one
m4u HW. Generation two uses the ARM short-descriptor translation table
format for address translation, and was shipped with ARM64 architecture,
MT8173 uses this generation two m4u HW. All the two generation iommu HW
only have one iommu domain, and all its iommu clients share the same
iova address.

These two generation m4u HW have slit different register groups and
register offset, but most register names are the same. This patch add iommu
support for mediatek SoC mt2701.

Signed-off-by: Honghui Zhang 
---
 drivers/iommu/Kconfig|  19 ++
 drivers/iommu/Makefile   |   1 +
 drivers/iommu/mtk_iommu.h|   3 +
 drivers/iommu/mtk_iommu_v1.c | 742 +++
 4 files changed, 765 insertions(+)
 create mode 100644 drivers/iommu/mtk_iommu_v1.c

diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
index dd1dc39..2e17d70 100644
--- a/drivers/iommu/Kconfig
+++ b/drivers/iommu/Kconfig
@@ -354,4 +354,23 @@ config MTK_IOMMU
 
  If unsure, say N here.
 
+config MTK_IOMMU_V1
+   bool "MTK IOMMU Version 1 (M4U gen1) Support"
+   depends on ARM || ARM64
+   depends on ARCH_MEDIATEK || COMPILE_TEST
+   select ARM_DMA_USE_IOMMU
+   select IOMMU_API
+   select IOMMU_DMA
+   select MEMORY
+   select MTK_SMI
+   select COMMON_CLK_MT2701_MMSYS
+   select COMMON_CLK_MT2701_IMGSYS
+   select COMMON_CLK_MT2701_VDECSYS
+   help
+ Support for the M4U on certain Mediatek SoCs. M4U generation 1 HW is
+ Multimedia Memory Managememt 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 c6edb31..778baf5 100644
--- a/drivers/iommu/Makefile
+++ b/drivers/iommu/Makefile
@@ -18,6 +18,7 @@ obj-$(CONFIG_INTEL_IOMMU_SVM) += intel-svm.o
 obj-$(CONFIG_IPMMU_VMSA) += ipmmu-vmsa.o
 obj-$(CONFIG_IRQ_REMAP) += intel_irq_remapping.o irq_remapping.o
 obj-$(CONFIG_MTK_IOMMU) += mtk_iommu.o
+obj-$(CONFIG_MTK_IOMMU_V1) += mtk_iommu_v1.o
 obj-$(CONFIG_OMAP_IOMMU) += omap-iommu.o
 obj-$(CONFIG_OMAP_IOMMU_DEBUG) += omap-iommu-debug.o
 obj-$(CONFIG_ROCKCHIP_IOMMU) += rockchip-iommu.o
diff --git a/drivers/iommu/mtk_iommu.h b/drivers/iommu/mtk_iommu.h
index 5656355..8d60f21 100644
--- a/drivers/iommu/mtk_iommu.h
+++ b/drivers/iommu/mtk_iommu.h
@@ -48,6 +48,9 @@ struct mtk_iommu_domain {
struct io_pgtable_ops   *iop;
 
struct iommu_domain domain;
+   void*pgt_va;
+   dma_addr_t  pgt_pa;
+   void*cookie;
 };
 
 struct mtk_iommu_data {
diff --git a/drivers/iommu/mtk_iommu_v1.c b/drivers/iommu/mtk_iommu_v1.c
new file mode 100644
index 000..55023e1
--- /dev/null
+++ b/drivers/iommu/mtk_iommu_v1.c
@@ -0,0 +1,742 @@
+/*
+ * Copyright (c) 2015-2016 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 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "mtk_iommu.h"
+
+#define REG_MMU_PT_BASE_ADDR   0x000
+
+#define F_ALL_INVLD0x2
+#define F_MMU_INV_RANGE0x1
+#define F_INVLD_EN0BIT(0)
+#define F_INVLD_EN1BIT(1)
+
+#define F_MMU_FAULT_VA_MSK 0xf000
+#define MTK_PROTECT_PA_ALIGN   128
+
+#define REG_MMU_CTRL_REG   0x210
+#define F_MMU_CTRL_COHERENT_EN BIT(8)
+#define REG_MMU_IVRP_PADDR 0x214
+#define REG_MMU_INT_CONTROL0x220
+#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_TABLE_WALK_FAULT BIT(4)
+#define F_INT_TLB_MISS_FAULT

[PATCH v2 1/5] dt-bindings: mediatek: add descriptions for mediatek mt2701 iommu and smi

2016-05-19 Thread honghui.zhang
From: Honghui Zhang 

This patch defines the local arbitor port IDs for mediatek SoC MT2701 and
add descriptions of binding for mediatek generation one iommu and smi.

Signed-off-by: Honghui Zhang 
---
 .../devicetree/bindings/iommu/mediatek,iommu.txt   | 13 +++-
 .../memory-controllers/mediatek,smi-common.txt | 21 +-
 .../memory-controllers/mediatek,smi-larb.txt   |  4 +-
 include/dt-bindings/memory/mt2701-larb-port.h  | 85 ++
 4 files changed, 115 insertions(+), 8 deletions(-)
 create mode 100644 include/dt-bindings/memory/mt2701-larb-port.h

diff --git a/Documentation/devicetree/bindings/iommu/mediatek,iommu.txt 
b/Documentation/devicetree/bindings/iommu/mediatek,iommu.txt
index cd1b1cd..53c20ca 100644
--- a/Documentation/devicetree/bindings/iommu/mediatek,iommu.txt
+++ b/Documentation/devicetree/bindings/iommu/mediatek,iommu.txt
@@ -1,7 +1,9 @@
 * 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.
+  Some Mediatek SOCs contain a Multimedia Memory Management Unit (M4U), and
+this M4U have two generations of HW architecture. Generation one uses flat
+pagetable, and only supports 4K size page mapping. Generation two uses the
+ARM Short-Descriptor translation table format for address translation.
 
   About the M4U Hardware Block Diagram, please check below:
 
@@ -36,7 +38,9 @@ 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".
+- compatible : must be one of the following string:
+   "mediatek,mt2701-m4u" for mt2701 which uses generation one m4u HW.
+   "mediatek,mt8173-m4u" for mt8173 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.
@@ -46,7 +50,8 @@ Required properties:
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.
+   dt-binding/memory/mt2701-larb-port.h for mt2701 and
+   dt-binding/memory/mt8173-larb-port.h for mt8173
 
 Example:
iommu: iommu@10205000 {
diff --git 
a/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-common.txt 
b/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-common.txt
index 06a83ce..aa614b2 100644
--- 
a/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-common.txt
+++ 
b/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-common.txt
@@ -2,16 +2,31 @@ SMI (Smart Multimedia Interface) Common
 
 The hardware block diagram please check bindings/iommu/mediatek,iommu.txt
 
+Mediatek SMI have two generations of HW architecture, mt8173 uses the second
+generation of SMI HW while mt2701 uses the first generation HW of SMI.
+
+There's slight differences between the two SMI, for generation 2, the
+register which control the iommu port is at each larb's register base. But
+for generation 1, the register is at smi ao base(smi always on register
+base). Besides that, the smi async clock should be prepared and enabled for
+SMI generation 1 to transform the smi clock into emi clock domain, but that is
+not needed for SMI generation 2.
+
 Required properties:
-- compatible : must be "mediatek,mt8173-smi-common"
+- compatible : must be one of :
+   "mediatek,mt2701-smi-common"
+   "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:
+- clock-names : must contain 3 entries for generation 1 smi HW and 2 entries
+  for generation 2 smi HW 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.
+   They may be the same if both source clocks are the same.
+  - "async" : asynchronous clock, it help transform the smi clock into the emi
+ clock domain, this clock is only needed by generation 1 smi HW.
 
 Example:
smi_common: smi@14022000 {
diff --git 
a/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.txt 
b/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.txt
index 55ff3b7..21277a5 100644
--- a/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.txt
+++ b/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.txt

[PATCH v2 3/5] memory/mediatek: add support for mt2701

2016-05-19 Thread honghui.zhang
From: Honghui Zhang 

Mediatek SMI has two generations of HW architecture, mt8173 uses the
second generation of SMI HW while mt2701 uses the first generation
HW of SMI.

There's slight differences between the two generations, for generation 2,
the register which control the iommu port access PA or IOVA is at each
larb's register base. But for generation 1, the register is at smi ao
base(smi always on register base).
Besides that, the smi async clock should be prepared and enabled for SMI
generation 1 HW to transform the smi clock into emi clock domain, but is
not needed for SMI generation 2.

This patch add SMI driver for mt2701 which use generation 1 SMI HW.

Signed-off-by: Honghui Zhang 
---
 drivers/memory/mtk-smi.c | 168 +--
 1 file changed, 149 insertions(+), 19 deletions(-)

diff --git a/drivers/memory/mtk-smi.c b/drivers/memory/mtk-smi.c
index 089091f..0a47382 100644
--- a/drivers/memory/mtk-smi.c
+++ b/drivers/memory/mtk-smi.c
@@ -21,19 +21,50 @@
 #include 
 #include 
 #include 
+#include 
 
 #define SMI_LARB_MMU_EN0xf00
+#define REG_SMI_SECUR_CON_BASE 0x5c0
+
+/* every register control 8 port, register offset 0x4 */
+#define REG_SMI_SECUR_CON_OFFSET(id)   (((id) >> 3) << 2)
+#define REG_SMI_SECUR_CON_ADDR(id) \
+   (REG_SMI_SECUR_CON_BASE + REG_SMI_SECUR_CON_OFFSET(id))
+
+/*
+ * every port have 4 bit to control, bit[port + 3] control virtual or physical,
+ * bit[port + 2 : port + 1] control the domain, bit[port] control the security
+ * or non-security.
+ */
+#define SMI_SECUR_CON_VAL_MSK(id)  (~(0xf << (((id) & 0x7) << 2)))
+#define SMI_SECUR_CON_VAL_VIRT(id) BITid) & 0x7) << 2) + 3)
+/* mt2701 domain should be set to 3 */
+#define SMI_SECUR_CON_VAL_DOMAIN(id)   (0x3 << id) & 0x7) << 2) + 1))
+
+struct mtk_smi_larb_gen {
+   int port_in_larb[MTK_LARB_NR_MAX + 1];
+   void (*config_port)(struct device *);
+};
 
 struct mtk_smi {
-   struct device   *dev;
-   struct clk  *clk_apb, *clk_smi;
+   struct device   *dev;
+   struct clk  *clk_apb, *clk_smi;
+   struct clk  *clk_async; /*only needed by mt2701*/
+   void __iomem*smi_ao_base;
 };
 
 struct mtk_smi_larb { /* larb: local arbiter */
-   struct mtk_smi  smi;
-   void __iomem*base;
-   struct device   *smi_common_dev;
-   u32 *mmu;
+   struct mtk_smi  smi;
+   void __iomem*base;
+   struct device   *smi_common_dev;
+   const struct mtk_smi_larb_gen   *larb_gen;
+   int larbid;
+   u32 *mmu;
+};
+
+enum mtk_smi_gen {
+   MTK_SMI_GEN1,
+   MTK_SMI_GEN2
 };
 
 static int mtk_smi_enable(const struct mtk_smi *smi)
@@ -71,6 +102,7 @@ static void mtk_smi_disable(const struct mtk_smi *smi)
 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;
 
@@ -87,8 +119,7 @@ int mtk_smi_larb_get(struct device *larbdev)
}
 
/* Configure the iommu info for this larb */
-   writel(*larb->mmu, larb->base + SMI_LARB_MMU_EN);
-
+   larb_gen->config_port(larbdev);
return 0;
 }
 
@@ -124,6 +155,45 @@ mtk_smi_larb_bind(struct device *dev, struct device 
*master, void *data)
return -ENODEV;
 }
 
+static void mtk_smi_larb_config_port(struct device *dev)
+{
+   struct mtk_smi_larb *larb = dev_get_drvdata(dev);
+
+   writel(*larb->mmu, larb->base + SMI_LARB_MMU_EN);
+}
+
+
+static void mtk_smi_larb_config_port_gen1(struct device *dev)
+{
+   struct mtk_smi_larb *larb = dev_get_drvdata(dev);
+   const struct mtk_smi_larb_gen *larb_gen = larb->larb_gen;
+   struct mtk_smi *common = dev_get_drvdata(larb->smi_common_dev);
+   int i, m4u_port_id, larb_port_num;
+   u32 sec_con_val, reg_val;
+
+   m4u_port_id = larb_gen->port_in_larb[larb->larbid];
+   larb_port_num = larb_gen->port_in_larb[larb->larbid + 1]
+   - larb_gen->port_in_larb[larb->larbid];
+
+   for (i = 0; i < larb_port_num; i++, m4u_port_id++) {
+   if (*larb->mmu & BIT(i)) {
+   /* bit[port + 3] controls the virtual or physical */
+   sec_con_val = SMI_SECUR_CON_VAL_VIRT(m4u_port_id);
+   } else {
+   /* do not need to enable m4u for this port */
+   continue;
+   }
+   reg_val = readl(common->smi_ao_base
+   + REG_SMI_SECUR_CON_ADDR(m4u_port_id));
+   reg_val &= SMI_SECUR_CON_VAL_MSK(m4u_port_id);
+   reg_val |= 

[PATCH 4/5] iommu/mediatek: add support for mtk iommu generation one HW

2016-05-09 Thread honghui.zhang
From: Honghui Zhang 

Mediatek SoC's M4U have two generations of HW architcture. Generation one
use flat, one layer pagetable, and was shipped with ARM architecture, it
only support 4K size page mapping. MT2701 SoC use this generation one
m4u HW. Generation two uses the ARM short-descriptor translation table
format for address translation, and was shipped with ARM64 architecture,
MT8173 use this generation two m4u HW. All the two generation iommu HW
only have one iommu domain, and all it's iommu clients share the same
iova address.

These two generation m4u HW have slit different register groups and
register offset, but most register names are the same. This patch add iommu
support for mediatek SoC mt2701.

Signed-off-by: Honghui Zhang 
---
 drivers/iommu/Kconfig|  19 ++
 drivers/iommu/Makefile   |   1 +
 drivers/iommu/mtk_iommu.h|   4 +
 drivers/iommu/mtk_iommu_v1.c | 767 +++
 4 files changed, 791 insertions(+)
 create mode 100644 drivers/iommu/mtk_iommu_v1.c

diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
index dd1dc39..2e17d70 100644
--- a/drivers/iommu/Kconfig
+++ b/drivers/iommu/Kconfig
@@ -354,4 +354,23 @@ config MTK_IOMMU
 
  If unsure, say N here.
 
+config MTK_IOMMU_V1
+   bool "MTK IOMMU Version 1 (M4U gen1) Support"
+   depends on ARM || ARM64
+   depends on ARCH_MEDIATEK || COMPILE_TEST
+   select ARM_DMA_USE_IOMMU
+   select IOMMU_API
+   select IOMMU_DMA
+   select MEMORY
+   select MTK_SMI
+   select COMMON_CLK_MT2701_MMSYS
+   select COMMON_CLK_MT2701_IMGSYS
+   select COMMON_CLK_MT2701_VDECSYS
+   help
+ Support for the M4U on certain Mediatek SoCs. M4U generation 1 HW is
+ Multimedia Memory Managememt 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 c6edb31..778baf5 100644
--- a/drivers/iommu/Makefile
+++ b/drivers/iommu/Makefile
@@ -18,6 +18,7 @@ obj-$(CONFIG_INTEL_IOMMU_SVM) += intel-svm.o
 obj-$(CONFIG_IPMMU_VMSA) += ipmmu-vmsa.o
 obj-$(CONFIG_IRQ_REMAP) += intel_irq_remapping.o irq_remapping.o
 obj-$(CONFIG_MTK_IOMMU) += mtk_iommu.o
+obj-$(CONFIG_MTK_IOMMU_V1) += mtk_iommu_v1.o
 obj-$(CONFIG_OMAP_IOMMU) += omap-iommu.o
 obj-$(CONFIG_OMAP_IOMMU_DEBUG) += omap-iommu-debug.o
 obj-$(CONFIG_ROCKCHIP_IOMMU) += rockchip-iommu.o
diff --git a/drivers/iommu/mtk_iommu.h b/drivers/iommu/mtk_iommu.h
index 5656355..c894784 100644
--- a/drivers/iommu/mtk_iommu.h
+++ b/drivers/iommu/mtk_iommu.h
@@ -48,6 +48,10 @@ struct mtk_iommu_domain {
struct io_pgtable_ops   *iop;
 
struct iommu_domain domain;
+   size_t  pgt_size;
+   void*pgt_va;
+   dma_addr_t  pgt_pa;
+   void*cookie;
 };
 
 struct mtk_iommu_data {
diff --git a/drivers/iommu/mtk_iommu_v1.c b/drivers/iommu/mtk_iommu_v1.c
new file mode 100644
index 000..1fece92
--- /dev/null
+++ b/drivers/iommu/mtk_iommu_v1.c
@@ -0,0 +1,767 @@
+/*
+ * Copyright (c) 2015-2016 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 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "mtk_iommu.h"
+
+#define REG_MMU_PT_BASE_ADDR   0x000
+
+#define F_ALL_INVLD0x2
+#define F_MMU_INV_RANGE0x1
+#define F_INVLD_EN0BIT(0)
+#define F_INVLD_EN1BIT(1)
+
+#define F_MMU_FAULT_VA_MSK 0xf000
+#define MTK_PROTECT_PA_ALIGN   128
+
+#define REG_MMU_CTRL_REG   0x210
+#define F_MMU_CTRL_COHERENT_EN BIT(8)
+#define REG_MMU_IVRP_PADDR 0x214
+#define REG_MMU_INT_CONTROL0x220
+#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_TABLE_WALK_FAULT 

[PATCH 2/5] iommu/mediatek: move the common struct into header file

2016-05-09 Thread honghui.zhang
From: Honghui Zhang 

Move the struct defines of mtk iommu into a new header files for
common use.

Signed-off-by: Honghui Zhang 
---
 drivers/iommu/mtk_iommu.c | 62 +---
 drivers/iommu/mtk_iommu.h | 90 +++
 2 files changed, 91 insertions(+), 61 deletions(-)
 create mode 100644 drivers/iommu/mtk_iommu.h

diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index db74553..a6b7846 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -34,7 +34,7 @@
 #include 
 #include 
 
-#include "io-pgtable.h"
+#include "mtk_iommu.h"
 
 #define REG_MMU_PT_BASE_ADDR   0x000
 
@@ -93,49 +93,8 @@
 
 #define MTK_PROTECT_PA_ALIGN   128
 
-struct mtk_iommu_suspend_reg {
-   u32 standard_axi_mode;
-   u32 dcm_dis;
-   u32 ctrl_reg;
-   u32 int_control0;
-   u32 int_main_control;
-};
-
-struct mtk_iommu_client_priv {
-   struct list_headclient;
-   unsigned intmtk_m4u_id;
-   struct device   *m4udev;
-};
-
-struct mtk_iommu_domain {
-   spinlock_t  pgtlock; /* lock for page table */
-
-   struct io_pgtable_cfg   cfg;
-   struct io_pgtable_ops   *iop;
-
-   struct iommu_domain domain;
-};
-
-struct mtk_iommu_data {
-   void __iomem*base;
-   int irq;
-   struct device   *dev;
-   struct clk  *bclk;
-   phys_addr_t protect_base; /* protect memory base */
-   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;
-};
-
 static struct iommu_ops mtk_iommu_ops;
 
-static struct mtk_iommu_domain *to_mtk_domain(struct iommu_domain *dom)
-{
-   return container_of(dom, struct mtk_iommu_domain, domain);
-}
-
 static void mtk_iommu_tlb_flush_all(void *cookie)
 {
struct mtk_iommu_data *data = cookie;
@@ -552,25 +511,6 @@ static int mtk_iommu_hw_init(const struct mtk_iommu_data 
*data)
return 0;
 }
 
-static int compare_of(struct device *dev, void *data)
-{
-   return dev->of_node == data;
-}
-
-static int mtk_iommu_bind(struct device *dev)
-{
-   struct mtk_iommu_data *data = dev_get_drvdata(dev);
-
-   return component_bind_all(dev, >smi_imu);
-}
-
-static void mtk_iommu_unbind(struct device *dev)
-{
-   struct mtk_iommu_data *data = dev_get_drvdata(dev);
-
-   component_unbind_all(dev, >smi_imu);
-}
-
 static const struct component_master_ops mtk_iommu_com_ops = {
.bind   = mtk_iommu_bind,
.unbind = mtk_iommu_unbind,
diff --git a/drivers/iommu/mtk_iommu.h b/drivers/iommu/mtk_iommu.h
new file mode 100644
index 000..5656355
--- /dev/null
+++ b/drivers/iommu/mtk_iommu.h
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2015-2016 MediaTek Inc.
+ * Author: Yong Wu 
+ *   : Honghui Zhang 
+ *
+ * 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 _MTK_IOMMU_H_
+#define _MTK_IOMMU_H_
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "io-pgtable.h"
+
+struct mtk_iommu_suspend_reg {
+   u32 standard_axi_mode;
+   u32 dcm_dis;
+   u32 ctrl_reg;
+   u32 int_control0;
+   u32 int_main_control;
+};
+
+struct mtk_iommu_client_priv {
+   struct list_headclient;
+   unsigned intmtk_m4u_id;
+   struct device   *m4udev;
+};
+
+struct mtk_iommu_domain {
+   spinlock_t  pgtlock; /* lock for page table */
+
+   struct io_pgtable_cfg   cfg;
+   struct io_pgtable_ops   *iop;
+
+   struct iommu_domain domain;
+};
+
+struct mtk_iommu_data {
+   void __iomem*base;
+   int irq;
+   struct device   *dev;
+   struct clk 

[PATCH 0/5] MT2701 iommu support

2016-05-09 Thread honghui.zhang
From: Honghui Zhang 

  Mediatek's m4u(Multimedia Memory Management Unit) and SMI(Smart
Multimedia Interface)have two generations HW. They basically sharing the
same hardware block diagram, but have some difference as below:

  Generation one m4u only support one layer, flat pagetable addressing, and
only support 4K size page mapping. While generation two m4u support 2
levels of pagetable which use the ARM short-descriptor translation table
format for address translation.
They have slight different register base and register offset.
They have very different HW ports defines.

  Generaion one SMI have additional "async" clock which transform the smi
clock into emi clock domain, this clock should be prepare and enabled for
cMI generation one HW.
The register which control the iommu need to translation the address or not
for a particular port is located at smi ao base(smi always on register
base) for generation one SMI HW, but located at each larb's register base
for generation two HW.

This patch set add mt2701 iommu support, it's based on 4.6-rc1 and James
Liao's "Add clock support for Mediatek MT2701 v7[1]" and "Mediatek MT2701
SCPSYS power domain support v6[2]" patch.

[1] 
http://lists.infradead.org/pipermail/linux-mediatek/2016-February/004030.html
[2] http://www.spinics.net/lists/arm-kernel/msg497028.html

Honghui Zhang (5):
  dt-bindings: mediatek: add descriptions for mediatek mt2701 iommu and
smi
  iommu/mediatek: move the common struct into header file
  memory/mediatek: add support for mt2701
  iommu/mediatek: add support for mtk iommu generation one HW
  ARM: dts: mt2701: add iommu/smi dtsi node for mt2701

 .../devicetree/bindings/iommu/mediatek,iommu.txt   |  13 +-
 .../memory-controllers/mediatek,smi-common.txt |  21 +-
 .../memory-controllers/mediatek,smi-larb.txt   |   4 +-
 arch/arm/boot/dts/mt2701.dtsi  |  51 ++
 drivers/iommu/Kconfig  |  19 +
 drivers/iommu/Makefile |   1 +
 drivers/iommu/mtk_iommu.c  |  62 +-
 drivers/iommu/mtk_iommu.h  |  94 +++
 drivers/iommu/mtk_iommu_v1.c   | 767 +
 drivers/memory/mtk-smi.c   | 168 -
 include/dt-bindings/memory/mt2701-larb-port.h  |  85 +++
 11 files changed, 1197 insertions(+), 88 deletions(-)
 create mode 100644 drivers/iommu/mtk_iommu.h
 create mode 100644 drivers/iommu/mtk_iommu_v1.c
 create mode 100644 include/dt-bindings/memory/mt2701-larb-port.h

-- 
1.8.1.1.dirty

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


[PATCH 5/5] ARM: dts: mt2701: add iommu/smi dtsi node for mt2701

2016-05-09 Thread honghui.zhang
From: Honghui Zhang 

Add the dtsi node of iommu and smi for mt2701.

Signed-off-by: Honghui Zhang 
---
 arch/arm/boot/dts/mt2701.dtsi | 51 +++
 1 file changed, 51 insertions(+)

diff --git a/arch/arm/boot/dts/mt2701.dtsi b/arch/arm/boot/dts/mt2701.dtsi
index 42d5a37..363de0d 100644
--- a/arch/arm/boot/dts/mt2701.dtsi
+++ b/arch/arm/boot/dts/mt2701.dtsi
@@ -16,6 +16,7 @@
 #include 
 #include 
 #include 
+#include 
 #include "skeleton64.dtsi"
 #include "mt2701-pinfunc.h"
 
@@ -160,6 +161,16 @@
clock-names = "system-clk", "rtc-clk";
};
 
+   smi_common: smi@1000c000 {
+   compatible = "mediatek,mt2701-smi-common";
+   reg = <0 0x1000c000 0 0x1000>;
+   clocks = < CLK_INFRA_SMI>,
+< CLK_MM_SMI_COMMON>,
+< CLK_INFRA_SMI>;
+   clock-names = "apb", "smi", "async";
+   power-domains = < MT2701_POWER_DOMAIN_DISP>;
+   };
+
sysirq: interrupt-controller@10200100 {
compatible = "mediatek,mt2701-sysirq",
 "mediatek,mt6577-sysirq";
@@ -169,6 +180,16 @@
reg = <0 0x10200100 0 0x1c>;
};
 
+   iommu: mmsys_iommu@10205000 {
+   compatible = "mediatek,mt2701-m4u";
+   reg = <0 0x10205000 0 0x1000>;
+   interrupts = ;
+   clocks = < CLK_INFRA_M4U>;
+   clock-names = "bclk";
+   mediatek,larbs = <  >;
+   #iommu-cells = <1>;
+   };
+
apmixedsys: syscon@10209000 {
compatible = "mediatek,mt2701-apmixedsys", "syscon";
reg = <0 0x10209000 0 0x1000>;
@@ -234,6 +255,16 @@
status = "disabled";
};
 
+   larb0: larb@1401 {
+   compatible = "mediatek,mt2701-smi-larb";
+   reg = <0 0x1401 0 0x1000>;
+   mediatek,smi = <_common>;
+   clocks = < CLK_MM_SMI_LARB0>,
+< CLK_MM_SMI_LARB0>;
+   clock-names = "apb", "smi";
+   power-domains = < MT2701_POWER_DOMAIN_DISP>;
+   };
+
imgsys: syscon@1500 {
compatible = "mediatek,mt2701-imgsys", "syscon";
reg = <0 0x1500 0 0x1000>;
@@ -241,6 +272,16 @@
status = "disabled";
};
 
+   larb2: larb@15001000 {
+   compatible = "mediatek,mt2701-smi-larb";
+   reg = <0 0x15001000 0 0x1000>;
+   mediatek,smi = <_common>;
+   clocks = < CLK_IMG_SMI_COMM>,
+< CLK_IMG_SMI_COMM>;
+   clock-names = "apb", "smi";
+   power-domains = < MT2701_POWER_DOMAIN_ISP>;
+   };
+
vdecsys: syscon@1600 {
compatible = "mediatek,mt2701-vdecsys", "syscon";
reg = <0 0x1600 0 0x1000>;
@@ -248,6 +289,16 @@
status = "disabled";
};
 
+   larb1: larb@1601 {
+   compatible = "mediatek,mt2701-smi-larb";
+   reg = <0 0x1601 0 0x1000>;
+   mediatek,smi = <_common>;
+   clocks = < CLK_VDEC_CKGEN>,
+< CLK_VDEC_LARB>;
+   clock-names = "apb", "smi";
+   power-domains = < MT2701_POWER_DOMAIN_VDEC>;
+   };
+
hifsys: syscon@1a00 {
compatible = "mediatek,mt2701-hifsys", "syscon";
reg = <0 0x1a00 0 0x1000>;
-- 
1.8.1.1.dirty

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


[PATCH 3/5] memory/mediatek: add support for mt2701

2016-05-09 Thread honghui.zhang
From: Honghui Zhang 

Mediatek SMI have two generation HW architecture, mt8173 use the
secondary generation of SMI HW while mt2701 use the first generation
HW of SMI.

There's slight differences between the two generation, for generation 2,
the register which control the iommu port access PA or IOVA is at each
larb's register base. But for generation 1, the register is at smi ao
base(smi always on register base).
Besides that, the smi async clock should be prepare and enabled for SMI
generation 1 HW to transform the smi clock into emi clock domain, but no
needed for SMI generation 2.

This patch add SMI driver for mt2701 which use generation 1 SMI HW.

Signed-off-by: Honghui Zhang 
---
 drivers/memory/mtk-smi.c | 168 +--
 1 file changed, 149 insertions(+), 19 deletions(-)

diff --git a/drivers/memory/mtk-smi.c b/drivers/memory/mtk-smi.c
index 089091f..0a47382 100644
--- a/drivers/memory/mtk-smi.c
+++ b/drivers/memory/mtk-smi.c
@@ -21,19 +21,50 @@
 #include 
 #include 
 #include 
+#include 
 
 #define SMI_LARB_MMU_EN0xf00
+#define REG_SMI_SECUR_CON_BASE 0x5c0
+
+/* every register control 8 port, register offset 0x4 */
+#define REG_SMI_SECUR_CON_OFFSET(id)   (((id) >> 3) << 2)
+#define REG_SMI_SECUR_CON_ADDR(id) \
+   (REG_SMI_SECUR_CON_BASE + REG_SMI_SECUR_CON_OFFSET(id))
+
+/*
+ * every port have 4 bit to control, bit[port + 3] control virtual or physical,
+ * bit[port + 2 : port + 1] control the domain, bit[port] control the security
+ * or non-security.
+ */
+#define SMI_SECUR_CON_VAL_MSK(id)  (~(0xf << (((id) & 0x7) << 2)))
+#define SMI_SECUR_CON_VAL_VIRT(id) BITid) & 0x7) << 2) + 3)
+/* mt2701 domain should be set to 3 */
+#define SMI_SECUR_CON_VAL_DOMAIN(id)   (0x3 << id) & 0x7) << 2) + 1))
+
+struct mtk_smi_larb_gen {
+   int port_in_larb[MTK_LARB_NR_MAX + 1];
+   void (*config_port)(struct device *);
+};
 
 struct mtk_smi {
-   struct device   *dev;
-   struct clk  *clk_apb, *clk_smi;
+   struct device   *dev;
+   struct clk  *clk_apb, *clk_smi;
+   struct clk  *clk_async; /*only needed by mt2701*/
+   void __iomem*smi_ao_base;
 };
 
 struct mtk_smi_larb { /* larb: local arbiter */
-   struct mtk_smi  smi;
-   void __iomem*base;
-   struct device   *smi_common_dev;
-   u32 *mmu;
+   struct mtk_smi  smi;
+   void __iomem*base;
+   struct device   *smi_common_dev;
+   const struct mtk_smi_larb_gen   *larb_gen;
+   int larbid;
+   u32 *mmu;
+};
+
+enum mtk_smi_gen {
+   MTK_SMI_GEN1,
+   MTK_SMI_GEN2
 };
 
 static int mtk_smi_enable(const struct mtk_smi *smi)
@@ -71,6 +102,7 @@ static void mtk_smi_disable(const struct mtk_smi *smi)
 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;
 
@@ -87,8 +119,7 @@ int mtk_smi_larb_get(struct device *larbdev)
}
 
/* Configure the iommu info for this larb */
-   writel(*larb->mmu, larb->base + SMI_LARB_MMU_EN);
-
+   larb_gen->config_port(larbdev);
return 0;
 }
 
@@ -124,6 +155,45 @@ mtk_smi_larb_bind(struct device *dev, struct device 
*master, void *data)
return -ENODEV;
 }
 
+static void mtk_smi_larb_config_port(struct device *dev)
+{
+   struct mtk_smi_larb *larb = dev_get_drvdata(dev);
+
+   writel(*larb->mmu, larb->base + SMI_LARB_MMU_EN);
+}
+
+
+static void mtk_smi_larb_config_port_gen1(struct device *dev)
+{
+   struct mtk_smi_larb *larb = dev_get_drvdata(dev);
+   const struct mtk_smi_larb_gen *larb_gen = larb->larb_gen;
+   struct mtk_smi *common = dev_get_drvdata(larb->smi_common_dev);
+   int i, m4u_port_id, larb_port_num;
+   u32 sec_con_val, reg_val;
+
+   m4u_port_id = larb_gen->port_in_larb[larb->larbid];
+   larb_port_num = larb_gen->port_in_larb[larb->larbid + 1]
+   - larb_gen->port_in_larb[larb->larbid];
+
+   for (i = 0; i < larb_port_num; i++, m4u_port_id++) {
+   if (*larb->mmu & BIT(i)) {
+   /* bit[port + 3] controls the virtual or physical */
+   sec_con_val = SMI_SECUR_CON_VAL_VIRT(m4u_port_id);
+   } else {
+   /* do not need to enable m4u for this port */
+   continue;
+   }
+   reg_val = readl(common->smi_ao_base
+   + REG_SMI_SECUR_CON_ADDR(m4u_port_id));
+   reg_val &= SMI_SECUR_CON_VAL_MSK(m4u_port_id);
+   reg_val |= sec_con_val;

[PATCH 1/5] dt-bindings: mediatek: add descriptions for mediatek mt2701 iommu and smi

2016-05-09 Thread honghui.zhang
From: Honghui Zhang 

This patch defines the local arbitor port IDs for mediatek SoC MT2701 and
add descriptions of binding for mediatek generation one iommu and smi.

Signed-off-by: Honghui Zhang 
---
 .../devicetree/bindings/iommu/mediatek,iommu.txt   | 13 +++-
 .../memory-controllers/mediatek,smi-common.txt | 21 +-
 .../memory-controllers/mediatek,smi-larb.txt   |  4 +-
 include/dt-bindings/memory/mt2701-larb-port.h  | 85 ++
 4 files changed, 115 insertions(+), 8 deletions(-)
 create mode 100644 include/dt-bindings/memory/mt2701-larb-port.h

diff --git a/Documentation/devicetree/bindings/iommu/mediatek,iommu.txt 
b/Documentation/devicetree/bindings/iommu/mediatek,iommu.txt
index cd1b1cd..9a4a5b5 100644
--- a/Documentation/devicetree/bindings/iommu/mediatek,iommu.txt
+++ b/Documentation/devicetree/bindings/iommu/mediatek,iommu.txt
@@ -1,7 +1,9 @@
 * 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.
+  Some Mediatek SOCs contain a Multimedia Memory Management Unit (M4U), and
+this M4U have two generations of HW architecture. Generation one use flat
+pagetable, and only support 4K size page mapping. Generation two uses the
+ARM Short-Descriptor translation table format for address translation.
 
   About the M4U Hardware Block Diagram, please check below:
 
@@ -36,7 +38,9 @@ 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".
+- compatible : must be one of the following string:
+   "mediatek,mt2701-m4u" for mt2701 which use generation one m4u HW.
+   "mediatek,mt8173-m4u" for mt8173 which use generation two m4u HW.
 - reg : m4u register base and size.
 - interrupts : the interrupt of m4u.
 - clocks : must contain one entry for each clock-names.
@@ -46,7 +50,8 @@ Required properties:
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.
+   dt-binding/memory/mt2701-larb-port.h for mt2701 and
+   dt-binding/memory/mt8173-larb-port.h for mt8173
 
 Example:
iommu: iommu@10205000 {
diff --git 
a/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-common.txt 
b/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-common.txt
index 06a83ce..80c0e22 100644
--- 
a/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-common.txt
+++ 
b/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-common.txt
@@ -2,16 +2,31 @@ SMI (Smart Multimedia Interface) Common
 
 The hardware block diagram please check bindings/iommu/mediatek,iommu.txt
 
+Mediatek SMI have two generation HW architecture, mt8173 use the secondary
+generation of SMI HW while mt2701 use the first generation HW of SMI.
+
+There's slight differences between the two SMI, for generation 2, the
+register which control the iommu port is at each larb's register base. But
+for generation 1, the register is at smi ao base(smi always on register
+base). Besides that, the smi async clock should be prepare and enabled for
+SMI generation 1 to transform the smi clock into emi clock domain, but no
+needed for SMI generation 2.
+
 Required properties:
-- compatible : must be "mediatek,mt8173-smi-common"
+- compatible : must be one of :
+   "mediatek,mt2701-smi-common"
+   "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:
+- clock-names : must contain 3 entries for generation 1 smi HW and 2 entries
+  for generation 2 smi HW 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.
+   They may be the same if both source clocks are the same.
+  - "async" : asynchronous clock, it help transform the smi clock into the emi
+ clock domain, this clock is only needed by generation 1 smi HW.
 
 Example:
smi_common: smi@14022000 {
diff --git 
a/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.txt 
b/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.txt
index 55ff3b7..21277a5 100644
--- a/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.txt
+++ b/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.txt
@@ -3,7 +3,9 @@