Re: [PATCH v5 04/16] memory: mtk-smi: Add device-link between smi-larb and smi-common

2021-04-13 Thread Yong Wu
On Sat, 2021-04-10 at 14:40 +0200, Krzysztof Kozlowski wrote:
> On 10/04/2021 11:11, Yong Wu wrote:
> > Normally, If the smi-larb HW need work, we should enable the smi-common
> > HW power and clock firstly.
> > This patch adds device-link between the smi-larb dev and the smi-common
> > dev. then If pm_runtime_get_sync(smi-larb-dev), the pm_runtime_get_sync
> > (smi-common-dev) will be called automatically.
> > 
> > Also, Add DL_FLAG_STATELESS to avoid the smi-common clocks be gated when
> > probe.
> > 
> > CC: Matthias Brugger 
> > Suggested-by: Tomasz Figa 
> > Signed-off-by: Yong Wu 
> > ---
> >  drivers/memory/mtk-smi.c | 19 ++-
> >  1 file changed, 10 insertions(+), 9 deletions(-)
> 
> I understood this is a dependency for other patches, so:
> Acked-by: Krzysztof Kozlowski 
> 
> If I am wrong and I can take it via memory tree, let me know.

Hi Krzysztof,

Thanks very much for your quickly review.

I think it is ok if it go through memory tree. In the original patch, we
pm_runtime_get(smi-common-dev) in the smi-larb's pm resume callback.
This patch only use device-link do this. thus, this patch have no
function change. it only adjusts the SMI internal code flow.

In addition, [14/16] expects your Acked-by. and that one should be
merged with the others.

About the others patches, I'm not sure which tree they should go
through. they cross several trees, dt-binding/iommu/media/drm/dts.

Not sure if Matthias could have time to review and give some suggestion.

> 
> Best regards,
> Krzysztof
> 
> ___
> Linux-mediatek mailing list
> linux-media...@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-mediatek



[PATCH 2/2] iommu/mediatek-v1: Add error handle for mtk_iommu_probe

2021-04-12 Thread Yong Wu
In the original code, we lack the error handle. This patch adds them.

Signed-off-by: Yong Wu 
---
 drivers/iommu/mtk_iommu_v1.c | 22 ++
 1 file changed, 18 insertions(+), 4 deletions(-)

diff --git a/drivers/iommu/mtk_iommu_v1.c b/drivers/iommu/mtk_iommu_v1.c
index bed0bb9d63fd..8ba9a2ec5509 100644
--- a/drivers/iommu/mtk_iommu_v1.c
+++ b/drivers/iommu/mtk_iommu_v1.c
@@ -620,12 +620,26 @@ static int mtk_iommu_probe(struct platform_device *pdev)
 
ret = iommu_device_register(>iommu);
if (ret)
-   return ret;
+   goto out_sysfs_remove;
 
-   if (!iommu_present(_bus_type))
-   bus_set_iommu(_bus_type,  _iommu_ops);
+   if (!iommu_present(_bus_type)) {
+   ret = bus_set_iommu(_bus_type,  _iommu_ops);
+   if (ret)
+   goto out_dev_unreg;
+   }
 
-   return component_master_add_with_match(dev, _iommu_com_ops, match);
+   ret = component_master_add_with_match(dev, _iommu_com_ops, match);
+   if (ret)
+   goto out_bus_set_null;
+   return ret;
+
+out_bus_set_null:
+   bus_set_iommu(_bus_type, NULL);
+out_dev_unreg:
+   iommu_device_unregister(>iommu);
+out_sysfs_remove:
+   iommu_device_sysfs_remove(>iommu);
+   return ret;
 }
 
 static int mtk_iommu_remove(struct platform_device *pdev)
-- 
2.18.0



[PATCH 1/2] iommu/mediatek-v1: Avoid build fail when build as module

2021-04-12 Thread Yong Wu
When this driver build as module, It build fail like:

ERROR: modpost: "of_phandle_iterator_args"
[drivers/iommu/mtk_iommu_v1.ko] undefined!

This patch remove this interface to avoid this build fail.

Reported-by: Valdis Kletnieks 
Signed-off-by: Yong Wu 
---
Currently below patch is only in linux-next-20210409. This fixes tag may be
not needed. we can add this if it is need.
Fixes: 8de000cf0265 ("iommu/mediatek-v1: Allow building as module")
---
 drivers/iommu/mtk_iommu_v1.c | 62 
 1 file changed, 28 insertions(+), 34 deletions(-)

diff --git a/drivers/iommu/mtk_iommu_v1.c b/drivers/iommu/mtk_iommu_v1.c
index be1b20e3f20e..bed0bb9d63fd 100644
--- a/drivers/iommu/mtk_iommu_v1.c
+++ b/drivers/iommu/mtk_iommu_v1.c
@@ -424,23 +424,21 @@ static struct iommu_device *mtk_iommu_probe_device(struct 
device *dev)
 {
struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
struct of_phandle_args iommu_spec;
-   struct of_phandle_iterator it;
struct mtk_iommu_data *data;
-   int err;
+   int err, idx = 0;
 
-   of_for_each_phandle(, err, dev->of_node, "iommus",
-   "#iommu-cells", -1) {
-   int count = of_phandle_iterator_args(, iommu_spec.args,
-   MAX_PHANDLE_ARGS);
-   iommu_spec.np = of_node_get(it.node);
-   iommu_spec.args_count = count;
+   while (!of_parse_phandle_with_args(dev->of_node, "iommus",
+  "#iommu-cells",
+  idx, _spec)) {
 
-   mtk_iommu_create_mapping(dev, _spec);
+   err = mtk_iommu_create_mapping(dev, _spec);
+   of_node_put(iommu_spec.np);
+   if (err)
+   return ERR_PTR(err);
 
/* dev->iommu_fwspec might have changed */
fwspec = dev_iommu_fwspec_get(dev);
-
-   of_node_put(iommu_spec.np);
+   idx++;
}
 
if (!fwspec || fwspec->ops != _iommu_ops)
@@ -549,10 +547,8 @@ static int mtk_iommu_probe(struct platform_device *pdev)
struct device   *dev = >dev;
struct resource *res;
struct component_match  *match = NULL;
-   struct of_phandle_args  larb_spec;
-   struct of_phandle_iterator  it;
void*protect;
-   int larb_nr, ret, err;
+   int larb_nr, ret, i;
 
data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
if (!data)
@@ -580,35 +576,33 @@ static int mtk_iommu_probe(struct platform_device *pdev)
if (IS_ERR(data->bclk))
return PTR_ERR(data->bclk);
 
-   larb_nr = 0;
-   of_for_each_phandle(, err, dev->of_node,
-   "mediatek,larbs", NULL, 0) {
+   larb_nr = of_count_phandle_with_args(dev->of_node,
+"mediatek,larbs", NULL);
+   if (larb_nr < 0)
+   return larb_nr;
+
+   for (i = 0; i < larb_nr; i++) {
+   struct device_node *larbnode;
struct platform_device *plarbdev;
-   int count = of_phandle_iterator_args(, larb_spec.args,
-   MAX_PHANDLE_ARGS);
 
-   if (count)
-   continue;
+   larbnode = of_parse_phandle(dev->of_node, "mediatek,larbs", i);
+   if (!larbnode)
+   return -EINVAL;
 
-   larb_spec.np = of_node_get(it.node);
-   if (!of_device_is_available(larb_spec.np))
+   if (!of_device_is_available(larbnode)) {
+   of_node_put(larbnode);
continue;
+   }
 
-   plarbdev = of_find_device_by_node(larb_spec.np);
+   plarbdev = of_find_device_by_node(larbnode);
if (!plarbdev) {
-   plarbdev = of_platform_device_create(
-   larb_spec.np, NULL,
-   platform_bus_type.dev_root);
-   if (!plarbdev) {
-   of_node_put(larb_spec.np);
-   return -EPROBE_DEFER;
-   }
+   of_node_put(larbnode);
+   return -EPROBE_DEFER;
}
+   data->larb_imu[i].dev = >dev;
 
-   data->larb_imu[larb_nr].dev = >dev;
component_match_add_release(dev, , release_of,
-   compare_of, larb_spec.np);
-   larb_nr++;
+   compare_of, larbnode);
}
 
platform_set_drvdata(pdev, data);
-- 
2.18.0



[PATCH v5 16/16] arm64: dts: mediatek: Get rid of mediatek,larb for MM nodes

2021-04-10 Thread Yong Wu
After adding device_link between the IOMMU consumer and smi,
the mediatek,larb is unnecessary now.

CC: Matthias Brugger 
Signed-off-by: Yong Wu 
Reviewed-by: Evan Green 
---
 arch/arm64/boot/dts/mediatek/mt8173.dtsi | 16 
 arch/arm64/boot/dts/mediatek/mt8183.dtsi |  5 -
 2 files changed, 21 deletions(-)

diff --git a/arch/arm64/boot/dts/mediatek/mt8173.dtsi 
b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
index f5950e9fc51d..683bce5eef37 100644
--- a/arch/arm64/boot/dts/mediatek/mt8173.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
@@ -1008,7 +1008,6 @@
 < CLK_MM_MUTEX_32K>;
power-domains = < MT8173_POWER_DOMAIN_MM>;
iommus = < M4U_PORT_MDP_RDMA0>;
-   mediatek,larb = <>;
mediatek,vpu = <>;
};
 
@@ -1019,7 +1018,6 @@
 < CLK_MM_MUTEX_32K>;
power-domains = < MT8173_POWER_DOMAIN_MM>;
iommus = < M4U_PORT_MDP_RDMA1>;
-   mediatek,larb = <>;
};
 
mdp_rsz0: rsz@14003000 {
@@ -1049,7 +1047,6 @@
clocks = < CLK_MM_MDP_WDMA>;
power-domains = < MT8173_POWER_DOMAIN_MM>;
iommus = < M4U_PORT_MDP_WDMA>;
-   mediatek,larb = <>;
};
 
mdp_wrot0: wrot@14007000 {
@@ -1058,7 +1055,6 @@
clocks = < CLK_MM_MDP_WROT0>;
power-domains = < MT8173_POWER_DOMAIN_MM>;
iommus = < M4U_PORT_MDP_WROT0>;
-   mediatek,larb = <>;
};
 
mdp_wrot1: wrot@14008000 {
@@ -1067,7 +1063,6 @@
clocks = < CLK_MM_MDP_WROT1>;
power-domains = < MT8173_POWER_DOMAIN_MM>;
iommus = < M4U_PORT_MDP_WROT1>;
-   mediatek,larb = <>;
};
 
ovl0: ovl@1400c000 {
@@ -1077,7 +1072,6 @@
power-domains = < MT8173_POWER_DOMAIN_MM>;
clocks = < CLK_MM_DISP_OVL0>;
iommus = < M4U_PORT_DISP_OVL0>;
-   mediatek,larb = <>;
mediatek,gce-client-reg = < SUBSYS_1400 0xc000 
0x1000>;
};
 
@@ -1088,7 +1082,6 @@
power-domains = < MT8173_POWER_DOMAIN_MM>;
clocks = < CLK_MM_DISP_OVL1>;
iommus = < M4U_PORT_DISP_OVL1>;
-   mediatek,larb = <>;
mediatek,gce-client-reg = < SUBSYS_1400 0xd000 
0x1000>;
};
 
@@ -1099,7 +1092,6 @@
power-domains = < MT8173_POWER_DOMAIN_MM>;
clocks = < CLK_MM_DISP_RDMA0>;
iommus = < M4U_PORT_DISP_RDMA0>;
-   mediatek,larb = <>;
mediatek,gce-client-reg = < SUBSYS_1400 0xe000 
0x1000>;
};
 
@@ -1110,7 +1102,6 @@
power-domains = < MT8173_POWER_DOMAIN_MM>;
clocks = < CLK_MM_DISP_RDMA1>;
iommus = < M4U_PORT_DISP_RDMA1>;
-   mediatek,larb = <>;
mediatek,gce-client-reg = < SUBSYS_1400 0xf000 
0x1000>;
};
 
@@ -1121,7 +1112,6 @@
power-domains = < MT8173_POWER_DOMAIN_MM>;
clocks = < CLK_MM_DISP_RDMA2>;
iommus = < M4U_PORT_DISP_RDMA2>;
-   mediatek,larb = <>;
mediatek,gce-client-reg = < SUBSYS_1401 0 
0x1000>;
};
 
@@ -1132,7 +1122,6 @@
power-domains = < MT8173_POWER_DOMAIN_MM>;
clocks = < CLK_MM_DISP_WDMA0>;
iommus = < M4U_PORT_DISP_WDMA0>;
-   mediatek,larb = <>;
mediatek,gce-client-reg = < SUBSYS_1401 0x1000 
0x1000>;
};
 
@@ -1143,7 +1132,6 @@
power-domains = < MT8173_POWER_DOMAIN_MM>;
clocks = < CLK_MM_DISP_WDMA1>;
iommus = < M4U_PORT_DISP_WDMA1>;
-   mediatek,larb = <>;
mediatek,gce-client-reg = < SUBSYS_1401 0x2000 
0x1000>;
};
 
@@ -1394,7 +1382,6 @@
  <0 0x16027800 0 0x800>,   /* VDEC_HWB */
 

[PATCH v5 15/16] arm: dts: mediatek: Get rid of mediatek,larb for MM nodes

2021-04-10 Thread Yong Wu
After adding device_link between the IOMMU consumer and smi,
the mediatek,larb is unnecessary now.

CC: Matthias Brugger 
Signed-off-by: Yong Wu 
Reviewed-by: Evan Green 
---
 arch/arm/boot/dts/mt2701.dtsi  | 2 --
 arch/arm/boot/dts/mt7623n.dtsi | 5 -
 2 files changed, 7 deletions(-)

diff --git a/arch/arm/boot/dts/mt2701.dtsi b/arch/arm/boot/dts/mt2701.dtsi
index fade14284017..0a7892bcf536 100644
--- a/arch/arm/boot/dts/mt2701.dtsi
+++ b/arch/arm/boot/dts/mt2701.dtsi
@@ -564,7 +564,6 @@
clock-names = "jpgdec-smi",
  "jpgdec";
power-domains = < MT2701_POWER_DOMAIN_ISP>;
-   mediatek,larb = <>;
iommus = < MT2701_M4U_PORT_JPGDEC_WDMA>,
 < MT2701_M4U_PORT_JPGDEC_BSDMA>;
};
@@ -577,7 +576,6 @@
clocks =  < CLK_IMG_VENC>;
clock-names = "jpgenc";
power-domains = < MT2701_POWER_DOMAIN_ISP>;
-   mediatek,larb = <>;
iommus = < MT2701_M4U_PORT_JPGENC_RDMA>,
 < MT2701_M4U_PORT_JPGENC_BSDMA>;
};
diff --git a/arch/arm/boot/dts/mt7623n.dtsi b/arch/arm/boot/dts/mt7623n.dtsi
index 1880ac9e32cf..2e6c16164744 100644
--- a/arch/arm/boot/dts/mt7623n.dtsi
+++ b/arch/arm/boot/dts/mt7623n.dtsi
@@ -121,7 +121,6 @@
clock-names = "jpgdec-smi",
  "jpgdec";
power-domains = < MT2701_POWER_DOMAIN_ISP>;
-   mediatek,larb = <>;
iommus = < MT2701_M4U_PORT_JPGDEC_WDMA>,
 < MT2701_M4U_PORT_JPGDEC_BSDMA>;
};
@@ -144,7 +143,6 @@
interrupts = ;
clocks = < CLK_MM_DISP_OVL>;
iommus = < MT2701_M4U_PORT_DISP_OVL_0>;
-   mediatek,larb = <>;
};
 
rdma0: rdma@14008000 {
@@ -154,7 +152,6 @@
interrupts = ;
clocks = < CLK_MM_DISP_RDMA>;
iommus = < MT2701_M4U_PORT_DISP_RDMA>;
-   mediatek,larb = <>;
};
 
wdma@14009000 {
@@ -164,7 +161,6 @@
interrupts = ;
clocks = < CLK_MM_DISP_WDMA>;
iommus = < MT2701_M4U_PORT_DISP_WDMA>;
-   mediatek,larb = <>;
};
 
bls: pwm@1400a000 {
@@ -215,7 +211,6 @@
interrupts = ;
clocks = < CLK_MM_DISP_RDMA1>;
iommus = < MT2701_M4U_PORT_DISP_RDMA1>;
-   mediatek,larb = <>;
};
 
dpi0: dpi@14014000 {
-- 
2.18.0



[PATCH v5 14/16] memory: mtk-smi: Get rid of mtk_smi_larb_get/put

2021-04-10 Thread Yong Wu
After adding device_link between the iommu consumer and smi-larb,
the pm_runtime_get(_sync) of smi-larb and smi-common will be called
automatically. we can get rid of mtk_smi_larb_get/put.

CC: Matthias Brugger 
Signed-off-by: Yong Wu 
Reviewed-by: Evan Green 
---
 drivers/memory/mtk-smi.c   | 14 --
 include/soc/mediatek/smi.h | 20 
 2 files changed, 34 deletions(-)

diff --git a/drivers/memory/mtk-smi.c b/drivers/memory/mtk-smi.c
index c5fb51f73b34..7c61c924e220 100644
--- a/drivers/memory/mtk-smi.c
+++ b/drivers/memory/mtk-smi.c
@@ -134,20 +134,6 @@ static void mtk_smi_clk_disable(const struct mtk_smi *smi)
clk_disable_unprepare(smi->clk_apb);
 }
 
-int mtk_smi_larb_get(struct device *larbdev)
-{
-   int ret = pm_runtime_resume_and_get(larbdev);
-
-   return (ret < 0) ? ret : 0;
-}
-EXPORT_SYMBOL_GPL(mtk_smi_larb_get);
-
-void mtk_smi_larb_put(struct device *larbdev)
-{
-   pm_runtime_put_sync(larbdev);
-}
-EXPORT_SYMBOL_GPL(mtk_smi_larb_put);
-
 static int
 mtk_smi_larb_bind(struct device *dev, struct device *master, void *data)
 {
diff --git a/include/soc/mediatek/smi.h b/include/soc/mediatek/smi.h
index 15e3397cec58..11f7d6b59642 100644
--- a/include/soc/mediatek/smi.h
+++ b/include/soc/mediatek/smi.h
@@ -19,26 +19,6 @@ struct mtk_smi_larb_iommu {
unsigned char  bank[32];
 };
 
-/*
- * mtk_smi_larb_get: Enable the power domain and clocks for this local arbiter.
- *   It also initialize some basic setting(like iommu).
- * mtk_smi_larb_put: Disable the power domain and clocks for this local 
arbiter.
- * Both should be called in non-atomic context.
- *
- * Returns 0 if successful, negative on failure.
- */
-int mtk_smi_larb_get(struct device *larbdev);
-void mtk_smi_larb_put(struct device *larbdev);
-
-#else
-
-static inline int mtk_smi_larb_get(struct device *larbdev)
-{
-   return 0;
-}
-
-static inline void mtk_smi_larb_put(struct device *larbdev) { }
-
 #endif
 
 #endif
-- 
2.18.0



[PATCH v5 13/16] media: mtk-vcodec: Get rid of mtk_smi_larb_get/put

2021-04-10 Thread Yong Wu
MediaTek IOMMU has already added the device_link between the consumer
and smi-larb device. If the vcodec device call the pm_runtime_get_sync,
the smi-larb's pm_runtime_get_sync also be called automatically.

CC: Tiffany Lin 
CC: Irui Wang 
Signed-off-by: Yong Wu 
Reviewed-by: Evan Green 
Acked-by: Tiffany Lin 
---
 .../platform/mtk-vcodec/mtk_vcodec_dec_pm.c   | 37 ++-
 .../platform/mtk-vcodec/mtk_vcodec_drv.h  |  3 --
 .../platform/mtk-vcodec/mtk_vcodec_enc.c  |  1 -
 .../platform/mtk-vcodec/mtk_vcodec_enc_pm.c   | 46 ++-
 4 files changed, 10 insertions(+), 77 deletions(-)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c 
b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c
index 32e1858e9f1d..2b3562e47f4f 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c
@@ -8,14 +8,12 @@
 #include 
 #include 
 #include 
-#include 
 
 #include "mtk_vcodec_dec_pm.h"
 #include "mtk_vcodec_util.h"
 
 int mtk_vcodec_init_dec_pm(struct mtk_vcodec_dev *mtkdev)
 {
-   struct device_node *node;
struct platform_device *pdev;
struct mtk_vcodec_pm *pm;
struct mtk_vcodec_clk *dec_clk;
@@ -26,18 +24,7 @@ int mtk_vcodec_init_dec_pm(struct mtk_vcodec_dev *mtkdev)
pm = >pm;
pm->mtkdev = mtkdev;
dec_clk = >vdec_clk;
-   node = of_parse_phandle(pdev->dev.of_node, "mediatek,larb", 0);
-   if (!node) {
-   mtk_v4l2_err("of_parse_phandle mediatek,larb fail!");
-   return -1;
-   }
 
-   pdev = of_find_device_by_node(node);
-   of_node_put(node);
-   if (WARN_ON(!pdev)) {
-   return -1;
-   }
-   pm->larbvdec = >dev;
pdev = mtkdev->plat_dev;
pm->dev = >dev;
 
@@ -47,14 +34,11 @@ int mtk_vcodec_init_dec_pm(struct mtk_vcodec_dev *mtkdev)
dec_clk->clk_info = devm_kcalloc(>dev,
dec_clk->clk_num, sizeof(*clk_info),
GFP_KERNEL);
-   if (!dec_clk->clk_info) {
-   ret = -ENOMEM;
-   goto put_device;
-   }
+   if (!dec_clk->clk_info)
+   return -ENOMEM;
} else {
mtk_v4l2_err("Failed to get vdec clock count");
-   ret = -EINVAL;
-   goto put_device;
+   return -EINVAL;
}
 
for (i = 0; i < dec_clk->clk_num; i++) {
@@ -63,29 +47,24 @@ int mtk_vcodec_init_dec_pm(struct mtk_vcodec_dev *mtkdev)
"clock-names", i, _info->clk_name);
if (ret) {
mtk_v4l2_err("Failed to get clock name id = %d", i);
-   goto put_device;
+   return ret;
}
clk_info->vcodec_clk = devm_clk_get(>dev,
clk_info->clk_name);
if (IS_ERR(clk_info->vcodec_clk)) {
mtk_v4l2_err("devm_clk_get (%d)%s fail", i,
clk_info->clk_name);
-   ret = PTR_ERR(clk_info->vcodec_clk);
-   goto put_device;
+   return PTR_ERR(clk_info->vcodec_clk);
}
}
 
pm_runtime_enable(>dev);
return 0;
-put_device:
-   put_device(pm->larbvdec);
-   return ret;
 }
 
 void mtk_vcodec_release_dec_pm(struct mtk_vcodec_dev *dev)
 {
pm_runtime_disable(dev->pm.dev);
-   put_device(dev->pm.larbvdec);
 }
 
 void mtk_vcodec_dec_pw_on(struct mtk_vcodec_pm *pm)
@@ -121,11 +100,6 @@ void mtk_vcodec_dec_clock_on(struct mtk_vcodec_pm *pm)
}
}
 
-   ret = mtk_smi_larb_get(pm->larbvdec);
-   if (ret) {
-   mtk_v4l2_err("mtk_smi_larb_get larbvdec fail %d", ret);
-   goto error;
-   }
return;
 
 error:
@@ -138,7 +112,6 @@ void mtk_vcodec_dec_clock_off(struct mtk_vcodec_pm *pm)
struct mtk_vcodec_clk *dec_clk = >vdec_clk;
int i = 0;
 
-   mtk_smi_larb_put(pm->larbvdec);
for (i = dec_clk->clk_num - 1; i >= 0; i--)
clk_disable_unprepare(dec_clk->clk_info[i].vcodec_clk);
 }
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h 
b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
index 869d958d2b99..659790398809 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
@@ -189,10 +189,7 @@ struct mtk_vcodec_clk {
  */
 struct mtk_vcodec_pm {
struct mtk_vcodec_clk   vdec_clk;
-   struct device   *larbvdec;
-
struct mtk_vcodec_clk   venc_clk;
-   struct device   *larbvenc;
struct device   *dev;
st

[PATCH v5 12/16] media: mtk-vcodec: Use pm_runtime_resume_and_get for PM get_sync

2021-04-10 Thread Yong Wu
pm_runtime_get_sync will increment pm usage counter even it failed.
This patch use pm_runtime_resume_and_get instead of
pm_runtime_get_sync to keep usage counter balanced.

Signed-off-by: Yong Wu 
---
 drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c 
b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c
index ddee7046ce42..32e1858e9f1d 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c
@@ -92,9 +92,10 @@ void mtk_vcodec_dec_pw_on(struct mtk_vcodec_pm *pm)
 {
int ret;
 
-   ret = pm_runtime_get_sync(pm->dev);
+   ret = pm_runtime_resume_and_get(pm->dev);
if (ret)
-   mtk_v4l2_err("pm_runtime_get_sync fail %d", ret);
+   mtk_v4l2_err("pm_runtime_resume_and_get fail %d", ret);
+
 }
 
 void mtk_vcodec_dec_pw_off(struct mtk_vcodec_pm *pm)
-- 
2.18.0



[PATCH v5 11/16] drm/mediatek: Get rid of mtk_smi_larb_get/put

2021-04-10 Thread Yong Wu
MediaTek IOMMU has already added the device_link between the consumer
and smi-larb device. If the drm device call the pm_runtime_get_sync,
the smi-larb's pm_runtime_get_sync also be called automatically.

CC: CK Hu 
CC: Philipp Zabel 
Signed-off-by: Yong Wu 
Reviewed-by: Evan Green 
Acked-by: Chun-Kuang Hu 
---
 drivers/gpu/drm/mediatek/mtk_drm_crtc.c |  9 --
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 35 -
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h |  1 -
 drivers/gpu/drm/mediatek/mtk_drm_drv.c  |  5 +--
 4 files changed, 1 insertion(+), 49 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c 
b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
index 971ef58ac1dc..d59353af4019 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
@@ -10,7 +10,6 @@
 #include 
 
 #include 
-#include 
 
 #include 
 #include 
@@ -544,12 +543,6 @@ static void mtk_drm_crtc_atomic_enable(struct drm_crtc 
*crtc,
 
DRM_DEBUG_DRIVER("%s %d\n", __func__, crtc->base.id);
 
-   ret = mtk_smi_larb_get(comp->larb_dev);
-   if (ret) {
-   DRM_ERROR("Failed to get larb: %d\n", ret);
-   return;
-   }
-
ret = pm_runtime_resume_and_get(comp->dev);
if (ret < 0)
DRM_DEV_ERROR(comp->dev, "Failed to enable power domain: %d\n",
@@ -557,7 +550,6 @@ static void mtk_drm_crtc_atomic_enable(struct drm_crtc 
*crtc,
 
ret = mtk_crtc_ddp_hw_init(mtk_crtc);
if (ret) {
-   mtk_smi_larb_put(comp->larb_dev);
pm_runtime_put(comp->dev);
return;
}
@@ -594,7 +586,6 @@ static void mtk_drm_crtc_atomic_disable(struct drm_crtc 
*crtc,
 
drm_crtc_vblank_off(crtc);
mtk_crtc_ddp_hw_fini(mtk_crtc);
-   mtk_smi_larb_put(comp->larb_dev);
ret = pm_runtime_put(comp->dev);
if (ret < 0)
DRM_DEV_ERROR(comp->dev, "Failed to disable power domain: %d\n",
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c 
b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
index 75bc00e17fc4..6c01492ba4df 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
@@ -449,37 +449,12 @@ unsigned int mtk_drm_find_possible_crtc_by_comp(struct 
drm_device *drm,
return ret;
 }
 
-static int mtk_ddp_get_larb_dev(struct device_node *node, struct mtk_ddp_comp 
*comp,
-   struct device *dev)
-{
-   struct device_node *larb_node;
-   struct platform_device *larb_pdev;
-
-   larb_node = of_parse_phandle(node, "mediatek,larb", 0);
-   if (!larb_node) {
-   dev_err(dev, "Missing mediadek,larb phandle in %pOF node\n", 
node);
-   return -EINVAL;
-   }
-
-   larb_pdev = of_find_device_by_node(larb_node);
-   if (!larb_pdev) {
-   dev_warn(dev, "Waiting for larb device %pOF\n", larb_node);
-   of_node_put(larb_node);
-   return -EPROBE_DEFER;
-   }
-   of_node_put(larb_node);
-   comp->larb_dev = _pdev->dev;
-
-   return 0;
-}
-
 int mtk_ddp_comp_init(struct device_node *node, struct mtk_ddp_comp *comp,
  enum mtk_ddp_comp_id comp_id)
 {
struct platform_device *comp_pdev;
enum mtk_ddp_comp_type type;
struct mtk_ddp_comp_dev *priv;
-   int ret;
 
if (comp_id < 0 || comp_id >= DDP_COMPONENT_ID_MAX)
return -EINVAL;
@@ -495,16 +470,6 @@ int mtk_ddp_comp_init(struct device_node *node, struct 
mtk_ddp_comp *comp,
}
comp->dev = _pdev->dev;
 
-   /* Only DMA capable components need the LARB property */
-   if (type == MTK_DISP_OVL ||
-   type == MTK_DISP_OVL_2L ||
-   type == MTK_DISP_RDMA ||
-   type == MTK_DISP_WDMA) {
-   ret = mtk_ddp_get_larb_dev(node, comp, comp->dev);
-   if (ret)
-   return ret;
-   }
-
if (type == MTK_DISP_BLS ||
type == MTK_DISP_CCORR ||
type == MTK_DISP_COLOR ||
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h 
b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
index bb914d976cf5..1b582262b682 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
@@ -70,7 +70,6 @@ struct mtk_ddp_comp_funcs {
 struct mtk_ddp_comp {
struct device *dev;
int irq;
-   struct device *larb_dev;
enum mtk_ddp_comp_id id;
const struct mtk_ddp_comp_funcs *funcs;
 };
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c 
b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
index b013d56d2777..622de47239eb 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
@@ -576,11 +576,8 @@ static int mtk_drm_probe(struct platfo

[PATCH v5 10/16] drm/mediatek: Add pm runtime support for ovl and rdma

2021-04-10 Thread Yong Wu
From: Yongqiang Niu 

Display use the dispsys device to call pm_rumtime_get_sync before.
This patch add pm_runtime_xx with ovl and rdma device whose nodes has
"iommus" property, then display could help pm_runtime_get for smi via
ovl or rdma device.

This is a preparing patch that smi cleaning up "mediatek,larb".

CC: CK Hu 
Signed-off-by: Yongqiang Niu 
Signed-off-by: Yong Wu 
(Yong: Use pm_runtime_resume_and_get instead of pm_runtime_get_sync)
Acked-by: Chun-Kuang Hu 
---
 drivers/gpu/drm/mediatek/mtk_disp_ovl.c  |  9 -
 drivers/gpu/drm/mediatek/mtk_disp_rdma.c |  9 -
 drivers/gpu/drm/mediatek/mtk_drm_crtc.c  | 12 +++-
 3 files changed, 27 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c 
b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
index 961f87f8d4d1..ee464ccd8a9c 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
@@ -11,6 +11,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 #include "mtk_disp_drv.h"
@@ -415,15 +416,21 @@ static int mtk_disp_ovl_probe(struct platform_device 
*pdev)
return ret;
}
 
+   pm_runtime_enable(dev);
+
ret = component_add(dev, _disp_ovl_component_ops);
-   if (ret)
+   if (ret) {
+   pm_runtime_disable(dev);
dev_err(dev, "Failed to add component: %d\n", ret);
+   }
 
return ret;
 }
 
 static int mtk_disp_ovl_remove(struct platform_device *pdev)
 {
+   pm_runtime_disable(>dev);
+
return 0;
 }
 
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_rdma.c 
b/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
index 728aaadfea8c..9565f3de773e 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
@@ -9,6 +9,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 #include "mtk_disp_drv.h"
@@ -329,9 +330,13 @@ static int mtk_disp_rdma_probe(struct platform_device 
*pdev)
 
platform_set_drvdata(pdev, priv);
 
+   pm_runtime_enable(dev);
+
ret = component_add(dev, _disp_rdma_component_ops);
-   if (ret)
+   if (ret) {
+   pm_runtime_disable(dev);
dev_err(dev, "Failed to add component: %d\n", ret);
+   }
 
return ret;
 }
@@ -340,6 +345,8 @@ static int mtk_disp_rdma_remove(struct platform_device 
*pdev)
 {
component_del(>dev, _disp_rdma_component_ops);
 
+   pm_runtime_disable(>dev);
+
return 0;
 }
 
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c 
b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
index 69d23ce56d2c..971ef58ac1dc 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
@@ -550,9 +550,15 @@ static void mtk_drm_crtc_atomic_enable(struct drm_crtc 
*crtc,
return;
}
 
+   ret = pm_runtime_resume_and_get(comp->dev);
+   if (ret < 0)
+   DRM_DEV_ERROR(comp->dev, "Failed to enable power domain: %d\n",
+ ret);
+
ret = mtk_crtc_ddp_hw_init(mtk_crtc);
if (ret) {
mtk_smi_larb_put(comp->larb_dev);
+   pm_runtime_put(comp->dev);
return;
}
 
@@ -565,7 +571,7 @@ static void mtk_drm_crtc_atomic_disable(struct drm_crtc 
*crtc,
 {
struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
struct mtk_ddp_comp *comp = mtk_crtc->ddp_comp[0];
-   int i;
+   int i, ret;
 
DRM_DEBUG_DRIVER("%s %d\n", __func__, crtc->base.id);
if (!mtk_crtc->enabled)
@@ -589,6 +595,10 @@ static void mtk_drm_crtc_atomic_disable(struct drm_crtc 
*crtc,
drm_crtc_vblank_off(crtc);
mtk_crtc_ddp_hw_fini(mtk_crtc);
mtk_smi_larb_put(comp->larb_dev);
+   ret = pm_runtime_put(comp->dev);
+   if (ret < 0)
+   DRM_DEV_ERROR(comp->dev, "Failed to disable power domain: %d\n",
+ ret);
 
mtk_crtc->enabled = false;
 }
-- 
2.18.0



[PATCH v5 09/16] drm/mediatek: Use pm_runtime_resume_and_get for PM get_sync

2021-04-10 Thread Yong Wu
pm_runtime_get_sync will increment pm usage counter even it failed.
This patch use pm_runtime_resume_and_get instead of pm_runtime_get
to keep usage counter balanced.

Signed-off-by: Yong Wu 
---
 drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c 
b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
index 8b0de90156c6..69d23ce56d2c 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
@@ -259,7 +259,7 @@ static int mtk_crtc_ddp_hw_init(struct mtk_drm_crtc 
*mtk_crtc)
drm_connector_list_iter_end(_iter);
}
 
-   ret = pm_runtime_get_sync(crtc->dev->dev);
+   ret = pm_runtime_resume_and_get(crtc->dev->dev);
if (ret < 0) {
DRM_ERROR("Failed to enable power domain: %d\n", ret);
return ret;
-- 
2.18.0



[PATCH v5 08/16] media: mtk-mdp: Get rid of mtk_smi_larb_get/put

2021-04-10 Thread Yong Wu
MediaTek IOMMU has already added the device_link between the consumer
and smi-larb device. If the mdp device call the pm_runtime_get_sync,
the smi-larb's pm_runtime_get_sync also be called automatically.

CC: Minghsiu Tsai 
CC: Houlong Wei 
Signed-off-by: Yong Wu 
Reviewed-by: Evan Green 
---
 drivers/media/platform/mtk-mdp/mtk_mdp_comp.c | 40 ---
 drivers/media/platform/mtk-mdp/mtk_mdp_comp.h |  2 -
 drivers/media/platform/mtk-mdp/mtk_mdp_core.c |  1 -
 3 files changed, 43 deletions(-)

diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c 
b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
index b3426a551bea..1e3833f1c9ae 100644
--- a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
+++ b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
@@ -9,7 +9,6 @@
 #include 
 #include 
 #include 
-#include 
 
 #include "mtk_mdp_comp.h"
 
@@ -18,14 +17,6 @@ void mtk_mdp_comp_clock_on(struct device *dev, struct 
mtk_mdp_comp *comp)
 {
int i, err;
 
-   if (comp->larb_dev) {
-   err = mtk_smi_larb_get(comp->larb_dev);
-   if (err)
-   dev_err(dev,
-   "failed to get larb, err %d. type:%d\n",
-   err, comp->type);
-   }
-
for (i = 0; i < ARRAY_SIZE(comp->clk); i++) {
if (IS_ERR(comp->clk[i]))
continue;
@@ -46,17 +37,12 @@ void mtk_mdp_comp_clock_off(struct device *dev, struct 
mtk_mdp_comp *comp)
continue;
clk_disable_unprepare(comp->clk[i]);
}
-
-   if (comp->larb_dev)
-   mtk_smi_larb_put(comp->larb_dev);
 }
 
 int mtk_mdp_comp_init(struct device *dev, struct device_node *node,
  struct mtk_mdp_comp *comp,
  enum mtk_mdp_comp_type comp_type)
 {
-   struct device_node *larb_node;
-   struct platform_device *larb_pdev;
int ret;
int i;
 
@@ -77,32 +63,6 @@ int mtk_mdp_comp_init(struct device *dev, struct device_node 
*node,
break;
}
 
-   /* Only DMA capable components need the LARB property */
-   comp->larb_dev = NULL;
-   if (comp->type != MTK_MDP_RDMA &&
-   comp->type != MTK_MDP_WDMA &&
-   comp->type != MTK_MDP_WROT)
-   return 0;
-
-   larb_node = of_parse_phandle(node, "mediatek,larb", 0);
-   if (!larb_node) {
-   dev_err(dev,
-   "Missing mediadek,larb phandle in %pOF node\n", node);
-   ret = -EINVAL;
-   goto put_dev;
-   }
-
-   larb_pdev = of_find_device_by_node(larb_node);
-   if (!larb_pdev) {
-   dev_warn(dev, "Waiting for larb device %pOF\n", larb_node);
-   of_node_put(larb_node);
-   ret = -EPROBE_DEFER;
-   goto put_dev;
-   }
-   of_node_put(larb_node);
-
-   comp->larb_dev = _pdev->dev;
-
return 0;
 
 put_dev:
diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h 
b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h
index 1bf0242cce46..36bc1b8f6222 100644
--- a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h
+++ b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h
@@ -27,14 +27,12 @@ enum mtk_mdp_comp_type {
  * @node:  list node to track sibing MDP components
  * @dev_node:  component device node
  * @clk:   clocks required for component
- * @larb_dev:  SMI device required for component
  * @type:  component type
  */
 struct mtk_mdp_comp {
struct list_headnode;
struct device_node  *dev_node;
struct clk  *clk[2];
-   struct device   *larb_dev;
enum mtk_mdp_comp_type  type;
 };
 
diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c 
b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
index 976aa1f4829b..70a8eab16863 100644
--- a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
+++ b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
@@ -17,7 +17,6 @@
 #include 
 #include 
 #include 
-#include 
 
 #include "mtk_mdp_core.h"
 #include "mtk_mdp_m2m.h"
-- 
2.18.0



[PATCH v5 07/16] media: mtk-mdp: Use pm_runtime_resume_and_get for PM get_sync

2021-04-10 Thread Yong Wu
pm_runtime_get_sync will increment pm usage counter even it failed.
This patch use pm_runtime_resume_and_get instead of pm_runtime_get
to keep usage counter balanced.

Signed-off-by: Yong Wu 
---
 drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c 
b/drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c
index ace4528cdc5e..93c9df15084a 100644
--- a/drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c
+++ b/drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c
@@ -391,9 +391,9 @@ static int mtk_mdp_m2m_start_streaming(struct vb2_queue *q, 
unsigned int count)
struct mtk_mdp_ctx *ctx = q->drv_priv;
int ret;
 
-   ret = pm_runtime_get_sync(>mdp_dev->pdev->dev);
+   ret = pm_runtime_resume_and_get(>mdp_dev->pdev->dev);
if (ret < 0)
-   mtk_mdp_dbg(1, "[%d] pm_runtime_get_sync failed:%d",
+   mtk_mdp_dbg(1, "[%d] pm_runtime_resume_and_get failed:%d",
ctx->id, ret);
 
return 0;
-- 
2.18.0



[PATCH v5 06/16] media: mtk-jpeg: Get rid of mtk_smi_larb_get/put

2021-04-10 Thread Yong Wu
MediaTek IOMMU has already added device_link between the consumer
and smi-larb device. If the jpg device call the pm_runtime_get_sync,
the smi-larb's pm_runtime_get_sync also be called automatically.

CC: Rick Chang 
CC: Xia Jiang 
Signed-off-by: Yong Wu 
Reviewed-by: Evan Green 
Acked-by: Rick Chang 
---
 .../media/platform/mtk-jpeg/mtk_jpeg_core.c   | 30 +--
 .../media/platform/mtk-jpeg/mtk_jpeg_core.h   |  2 --
 2 files changed, 1 insertion(+), 31 deletions(-)

diff --git a/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c 
b/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c
index a89c7b206eef..a47832a1b316 100644
--- a/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c
+++ b/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c
@@ -22,7 +22,6 @@
 #include 
 #include 
 #include 
-#include 
 
 #include "mtk_jpeg_enc_hw.h"
 #include "mtk_jpeg_dec_hw.h"
@@ -1055,10 +1054,6 @@ static void mtk_jpeg_clk_on(struct mtk_jpeg_dev *jpeg)
 {
int ret;
 
-   ret = mtk_smi_larb_get(jpeg->larb);
-   if (ret)
-   dev_err(jpeg->dev, "mtk_smi_larb_get larbvdec fail %d\n", ret);
-
ret = clk_bulk_prepare_enable(jpeg->variant->num_clks,
  jpeg->variant->clks);
if (ret)
@@ -1069,7 +1064,6 @@ static void mtk_jpeg_clk_off(struct mtk_jpeg_dev *jpeg)
 {
clk_bulk_disable_unprepare(jpeg->variant->num_clks,
   jpeg->variant->clks);
-   mtk_smi_larb_put(jpeg->larb);
 }
 
 static irqreturn_t mtk_jpeg_enc_done(struct mtk_jpeg_dev *jpeg)
@@ -1286,27 +1280,12 @@ static struct clk_bulk_data mtk_jpeg_clocks[] = {
 
 static int mtk_jpeg_clk_init(struct mtk_jpeg_dev *jpeg)
 {
-   struct device_node *node;
-   struct platform_device *pdev;
int ret;
 
-   node = of_parse_phandle(jpeg->dev->of_node, "mediatek,larb", 0);
-   if (!node)
-   return -EINVAL;
-   pdev = of_find_device_by_node(node);
-   if (WARN_ON(!pdev)) {
-   of_node_put(node);
-   return -EINVAL;
-   }
-   of_node_put(node);
-
-   jpeg->larb = >dev;
-
ret = devm_clk_bulk_get(jpeg->dev, jpeg->variant->num_clks,
jpeg->variant->clks);
if (ret) {
-   dev_err(>dev, "failed to get jpeg clock:%d\n", ret);
-   put_device(>dev);
+   dev_err(jpeg->dev, "failed to get jpeg clock:%d\n", ret);
return ret;
}
 
@@ -1333,11 +1312,6 @@ static void mtk_jpeg_job_timeout_work(struct work_struct 
*work)
v4l2_m2m_job_finish(jpeg->m2m_dev, ctx->fh.m2m_ctx);
 }
 
-static inline void mtk_jpeg_clk_release(struct mtk_jpeg_dev *jpeg)
-{
-   put_device(jpeg->larb);
-}
-
 static int mtk_jpeg_probe(struct platform_device *pdev)
 {
struct mtk_jpeg_dev *jpeg;
@@ -1442,7 +1416,6 @@ static int mtk_jpeg_probe(struct platform_device *pdev)
v4l2_device_unregister(>v4l2_dev);
 
 err_dev_register:
-   mtk_jpeg_clk_release(jpeg);
 
 err_clk_init:
 
@@ -1460,7 +1433,6 @@ static int mtk_jpeg_remove(struct platform_device *pdev)
video_device_release(jpeg->vdev);
v4l2_m2m_release(jpeg->m2m_dev);
v4l2_device_unregister(>v4l2_dev);
-   mtk_jpeg_clk_release(jpeg);
 
return 0;
 }
diff --git a/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.h 
b/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.h
index 68e634f02e00..6e558e97a2d8 100644
--- a/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.h
+++ b/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.h
@@ -85,7 +85,6 @@ struct mtk_jpeg_variant {
  * @alloc_ctx: videobuf2 memory allocator's context
  * @vdev:  video device node for jpeg mem2mem mode
  * @reg_base:  JPEG registers mapping
- * @larb:  SMI device
  * @job_timeout_work:  IRQ timeout structure
  * @variant:   driver variant to be used
  */
@@ -99,7 +98,6 @@ struct mtk_jpeg_dev {
void*alloc_ctx;
struct video_device *vdev;
void __iomem*reg_base;
-   struct device   *larb;
struct delayed_work job_timeout_work;
const struct mtk_jpeg_variant *variant;
 };
-- 
2.18.0



[PATCH v5 05/16] media: mtk-jpeg: Use pm_runtime_resume_and_get for PM get_sync

2021-04-10 Thread Yong Wu
pm_runtime_get_sync will increment pm usage counter even it failed.
This patch use pm_runtime_resume_and_get instead of pm_runtime_get
to keep usage counter balanced.

CC: Xia Jiang 
Signed-off-by: Yong Wu 
---
 drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c 
b/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c
index 88a23bce569d..a89c7b206eef 100644
--- a/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c
+++ b/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c
@@ -920,7 +920,7 @@ static void mtk_jpeg_enc_device_run(void *priv)
src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
 
-   ret = pm_runtime_get_sync(jpeg->dev);
+   ret = pm_runtime_resume_and_get(jpeg->dev);
if (ret < 0)
goto enc_end;
 
@@ -973,7 +973,7 @@ static void mtk_jpeg_dec_device_run(void *priv)
return;
}
 
-   ret = pm_runtime_get_sync(jpeg->dev);
+   ret = pm_runtime_resume_and_get(jpeg->dev);
if (ret < 0)
goto dec_end;
 
-- 
2.18.0



[PATCH v5 04/16] memory: mtk-smi: Add device-link between smi-larb and smi-common

2021-04-10 Thread Yong Wu
Normally, If the smi-larb HW need work, we should enable the smi-common
HW power and clock firstly.
This patch adds device-link between the smi-larb dev and the smi-common
dev. then If pm_runtime_get_sync(smi-larb-dev), the pm_runtime_get_sync
(smi-common-dev) will be called automatically.

Also, Add DL_FLAG_STATELESS to avoid the smi-common clocks be gated when
probe.

CC: Matthias Brugger 
Suggested-by: Tomasz Figa 
Signed-off-by: Yong Wu 
---
 drivers/memory/mtk-smi.c | 19 ++-
 1 file changed, 10 insertions(+), 9 deletions(-)

diff --git a/drivers/memory/mtk-smi.c b/drivers/memory/mtk-smi.c
index b396253fcf4b..c5fb51f73b34 100644
--- a/drivers/memory/mtk-smi.c
+++ b/drivers/memory/mtk-smi.c
@@ -319,6 +319,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;
+   struct device_link *link;
 
larb = devm_kzalloc(dev, sizeof(*larb), GFP_KERNEL);
if (!larb)
@@ -358,6 +359,12 @@ static int mtk_smi_larb_probe(struct platform_device *pdev)
if (!platform_get_drvdata(smi_pdev))
return -EPROBE_DEFER;
larb->smi_common_dev = _pdev->dev;
+   link = device_link_add(dev, larb->smi_common_dev,
+  DL_FLAG_PM_RUNTIME | DL_FLAG_STATELESS);
+   if (!link) {
+   dev_err(dev, "Unable to link smi-common dev\n");
+   return -ENODEV;
+   }
} else {
dev_err(dev, "Failed to get the smi_common device\n");
return -EINVAL;
@@ -370,6 +377,9 @@ static int mtk_smi_larb_probe(struct platform_device *pdev)
 
 static int mtk_smi_larb_remove(struct platform_device *pdev)
 {
+   struct mtk_smi_larb *larb = platform_get_drvdata(pdev);
+
+   device_link_remove(>dev, larb->smi_common_dev);
pm_runtime_disable(>dev);
component_del(>dev, _smi_larb_component_ops);
return 0;
@@ -381,17 +391,9 @@ static int __maybe_unused mtk_smi_larb_resume(struct 
device *dev)
const struct mtk_smi_larb_gen *larb_gen = larb->larb_gen;
int ret;
 
-   /* Power on smi-common. */
-   ret = pm_runtime_resume_and_get(larb->smi_common_dev);
-   if (ret < 0) {
-   dev_err(dev, "Failed to pm get for smi-common(%d).\n", ret);
-   return ret;
-   }
-
ret = mtk_smi_clk_enable(>smi);
if (ret < 0) {
dev_err(dev, "Failed to enable clock(%d).\n", ret);
-   pm_runtime_put_sync(larb->smi_common_dev);
return ret;
}
 
@@ -406,7 +408,6 @@ static int __maybe_unused mtk_smi_larb_suspend(struct 
device *dev)
struct mtk_smi_larb *larb = dev_get_drvdata(dev);
 
mtk_smi_clk_disable(>smi);
-   pm_runtime_put_sync(larb->smi_common_dev);
return 0;
 }
 
-- 
2.18.0



[PATCH v5 03/16] iommu/mediatek: Add device_link between the consumer and the larb devices

2021-04-10 Thread Yong Wu
MediaTek IOMMU-SMI diagram is like below. all the consumer connect with
smi-larb, then connect with smi-common.

M4U
 |
smi-common
 |
  -
  | |...
  | |
larb1 larb2
  | |
vdec   venc

When the consumer works, it should enable the smi-larb's power which
also need enable the smi-common's power firstly.

Thus, First of all, use the device link connect the consumer and the
smi-larbs. then add device link between the smi-larb and smi-common.

This patch adds device_link between the consumer and the larbs.

When device_link_add, I add the flag DL_FLAG_STATELESS to avoid calling
pm_runtime_xx to keep the original status of clocks. It can avoid two
issues:
1) Display HW show fastlogo abnormally reported in [1]. At the beggining,
all the clocks are enabled before entering kernel, but the clocks for
display HW(always in larb0) will be gated after clk_enable and clk_disable
called from device_link_add(->pm_runtime_resume) and rpm_idle. The clock
operation happened before display driver probe. At that time, the display
HW will be abnormal.

2) A deadlock issue reported in [2]. Use DL_FLAG_STATELESS to skip
pm_runtime_xx to avoid the deadlock.

Corresponding, DL_FLAG_AUTOREMOVE_CONSUMER can't be added, then
device_link_removed should be added explicitly.

[1] https://lore.kernel.org/linux-mediatek/1564213888.22908.4.camel@mhfsdcap03/
[2] https://lore.kernel.org/patchwork/patch/1086569/

Suggested-by: Tomasz Figa 
Signed-off-by: Yong Wu 
---
 drivers/iommu/mtk_iommu.c| 22 ++
 drivers/iommu/mtk_iommu_v1.c | 20 +++-
 2 files changed, 41 insertions(+), 1 deletion(-)

diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index 7a7b8260d308..cd054bd3f0df 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -571,22 +571,44 @@ static struct iommu_device *mtk_iommu_probe_device(struct 
device *dev)
 {
struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
struct mtk_iommu_data *data;
+   struct device_link *link;
+   struct device *larbdev;
+   unsigned int larbid;
 
if (!fwspec || fwspec->ops != _iommu_ops)
return ERR_PTR(-ENODEV); /* Not a iommu client device */
 
data = dev_iommu_priv_get(dev);
 
+   /*
+* Link the consumer device with the smi-larb device(supplier)
+* The device in each a larb is a independent HW. thus only link
+* one larb here.
+*/
+   larbid = MTK_M4U_TO_LARB(fwspec->ids[0]);
+   larbdev = data->larb_imu[larbid].dev;
+   link = device_link_add(dev, larbdev,
+  DL_FLAG_PM_RUNTIME | DL_FLAG_STATELESS);
+   if (!link)
+   dev_err(dev, "Unable to link %s\n", dev_name(larbdev));
return >iommu;
 }
 
 static void mtk_iommu_release_device(struct device *dev)
 {
struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
+   struct mtk_iommu_data *data;
+   struct device *larbdev;
+   unsigned int larbid;
 
if (!fwspec || fwspec->ops != _iommu_ops)
return;
 
+   data = dev_iommu_priv_get(dev);
+   larbid = MTK_M4U_TO_LARB(fwspec->ids[0]);
+   larbdev = data->larb_imu[larbid].dev;
+   device_link_remove(dev, larbdev);
+
iommu_fwspec_free(dev);
 }
 
diff --git a/drivers/iommu/mtk_iommu_v1.c b/drivers/iommu/mtk_iommu_v1.c
index a82466e4046e..43dbdf692894 100644
--- a/drivers/iommu/mtk_iommu_v1.c
+++ b/drivers/iommu/mtk_iommu_v1.c
@@ -425,7 +425,9 @@ static struct iommu_device *mtk_iommu_probe_device(struct 
device *dev)
struct of_phandle_args iommu_spec;
struct of_phandle_iterator it;
struct mtk_iommu_data *data;
-   int err;
+   struct device_link *link;
+   struct device *larbdev;
+   int err, larbid;
 
of_for_each_phandle(, err, dev->of_node, "iommus",
"#iommu-cells", -1) {
@@ -447,6 +449,14 @@ static struct iommu_device *mtk_iommu_probe_device(struct 
device *dev)
 
data = dev_iommu_priv_get(dev);
 
+   /* Link the consumer device with the smi-larb device(supplier) */
+   larbid = mt2701_m4u_to_larb(fwspec->ids[0]);
+   larbdev = data->larb_imu[larbid].dev;
+   link = device_link_add(dev, larbdev,
+  DL_FLAG_PM_RUNTIME | DL_FLAG_STATELESS);
+   if (!link)
+   dev_err(dev, "Unable to link %s\n", dev_name(larbdev));
+
return >iommu;
 }
 
@@ -467,10 +477,18 @@ static void mtk_iommu_probe_finalize(struct device *dev)
 static void mtk_iommu_release_device(struct device *dev)
 {
struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
+   struct mtk_iommu_data *data;
+   struct device *larbdev;
+   unsigned int larbid;
 
if (!fwspec || fwspec->ops != _iommu_ops)
return;
 
+   da

[PATCH v5 02/16] iommu/mediatek: Add probe_defer for smi-larb

2021-04-10 Thread Yong Wu
The iommu consumer should use device_link to connect with the
smi-larb(supplier). then the smi-larb should run before the iommu
consumer. Here we delay the iommu driver until the smi driver is
ready, then all the iommu consumer always is after the smi driver.

When there is no this patch, if some consumer drivers run before
smi-larb, the supplier link_status is DL_DEV_NO_DRIVER(0) in the
device_link_add, then device_links_driver_bound will use WARN_ON
to complain that the link_status of supplier is not right.

This is a preparing patch for adding device_link.

Signed-off-by: Yong Wu 
---
To Matthias,

In v2, You suggested use device_is_bound here. But from [1], this
interface is not allowed to be EXPORT. It will affect this driver
built as module. thus I still use dev.driver to check here.

[1] https://lore.kernel.org/patchwork/patch/1334670/
---
 drivers/iommu/mtk_iommu.c| 2 +-
 drivers/iommu/mtk_iommu_v1.c | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index 6ecc007f07cd..7a7b8260d308 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -862,7 +862,7 @@ static int mtk_iommu_probe(struct platform_device *pdev)
id = i;
 
plarbdev = of_find_device_by_node(larbnode);
-   if (!plarbdev) {
+   if (!plarbdev || !plarbdev->dev.driver) {
of_node_put(larbnode);
return -EPROBE_DEFER;
}
diff --git a/drivers/iommu/mtk_iommu_v1.c b/drivers/iommu/mtk_iommu_v1.c
index 82ddfe9170d4..a82466e4046e 100644
--- a/drivers/iommu/mtk_iommu_v1.c
+++ b/drivers/iommu/mtk_iommu_v1.c
@@ -597,7 +597,7 @@ static int mtk_iommu_probe(struct platform_device *pdev)
plarbdev = of_platform_device_create(
larb_spec.np, NULL,
platform_bus_type.dev_root);
-   if (!plarbdev) {
+   if (!plarbdev || !plarbdev->dev.driver) {
of_node_put(larb_spec.np);
return -EPROBE_DEFER;
}
-- 
2.18.0



[PATCH v5 01/16] dt-binding: mediatek: Get rid of mediatek,larb for multimedia HW

2021-04-10 Thread Yong Wu
After adding device_link between the consumer with the smi-larbs,
if the consumer call its owner pm_runtime_get(_sync), the
pm_runtime_get(_sync) of smi-larb and smi-common will be called
automatically. Thus, the consumer don't need the property.

And IOMMU also know which larb this consumer connects with from
iommu id in the "iommus=" property.

Signed-off-by: Yong Wu 
Reviewed-by: Rob Herring 
Reviewed-by: Evan Green 
---
 .../bindings/display/mediatek/mediatek,disp.txt  | 9 -
 .../devicetree/bindings/media/mediatek-jpeg-decoder.txt  | 4 
 .../devicetree/bindings/media/mediatek-jpeg-encoder.txt  | 4 
 Documentation/devicetree/bindings/media/mediatek-mdp.txt | 8 
 .../devicetree/bindings/media/mediatek-vcodec.txt| 4 
 5 files changed, 29 deletions(-)

diff --git 
a/Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt 
b/Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt
index 93b160df3eec..6336bae8a6d7 100644
--- a/Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt
@@ -61,8 +61,6 @@ Required properties (DMA function blocks):
"mediatek,-disp-rdma"
"mediatek,-disp-wdma"
   the supported chips are mt2701, mt8167 and mt8173.
-- larb: Should contain a phandle pointing to the local arbiter device as 
defined
-  in 
Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml
 - iommus: Should point to the respective IOMMU block with master port as
   argument, see Documentation/devicetree/bindings/iommu/mediatek,iommu.txt
   for details.
@@ -91,7 +89,6 @@ ovl0: ovl@1400c000 {
power-domains = < MT8173_POWER_DOMAIN_MM>;
clocks = < CLK_MM_DISP_OVL0>;
iommus = < M4U_PORT_DISP_OVL0>;
-   mediatek,larb = <>;
 };
 
 ovl1: ovl@1400d000 {
@@ -101,7 +98,6 @@ ovl1: ovl@1400d000 {
power-domains = < MT8173_POWER_DOMAIN_MM>;
clocks = < CLK_MM_DISP_OVL1>;
iommus = < M4U_PORT_DISP_OVL1>;
-   mediatek,larb = <>;
 };
 
 rdma0: rdma@1400e000 {
@@ -111,7 +107,6 @@ rdma0: rdma@1400e000 {
power-domains = < MT8173_POWER_DOMAIN_MM>;
clocks = < CLK_MM_DISP_RDMA0>;
iommus = < M4U_PORT_DISP_RDMA0>;
-   mediatek,larb = <>;
mediatek,rdma-fifosize = <8192>;
 };
 
@@ -122,7 +117,6 @@ rdma1: rdma@1400f000 {
power-domains = < MT8173_POWER_DOMAIN_MM>;
clocks = < CLK_MM_DISP_RDMA1>;
iommus = < M4U_PORT_DISP_RDMA1>;
-   mediatek,larb = <>;
 };
 
 rdma2: rdma@1401 {
@@ -132,7 +126,6 @@ rdma2: rdma@1401 {
power-domains = < MT8173_POWER_DOMAIN_MM>;
clocks = < CLK_MM_DISP_RDMA2>;
iommus = < M4U_PORT_DISP_RDMA2>;
-   mediatek,larb = <>;
 };
 
 wdma0: wdma@14011000 {
@@ -142,7 +135,6 @@ wdma0: wdma@14011000 {
power-domains = < MT8173_POWER_DOMAIN_MM>;
clocks = < CLK_MM_DISP_WDMA0>;
iommus = < M4U_PORT_DISP_WDMA0>;
-   mediatek,larb = <>;
 };
 
 wdma1: wdma@14012000 {
@@ -152,7 +144,6 @@ wdma1: wdma@14012000 {
power-domains = < MT8173_POWER_DOMAIN_MM>;
clocks = < CLK_MM_DISP_WDMA1>;
iommus = < M4U_PORT_DISP_WDMA1>;
-   mediatek,larb = <>;
 };
 
 color0: color@14013000 {
diff --git a/Documentation/devicetree/bindings/media/mediatek-jpeg-decoder.txt 
b/Documentation/devicetree/bindings/media/mediatek-jpeg-decoder.txt
index cf60c5acc0e4..7978f210e3d4 100644
--- a/Documentation/devicetree/bindings/media/mediatek-jpeg-decoder.txt
+++ b/Documentation/devicetree/bindings/media/mediatek-jpeg-decoder.txt
@@ -15,9 +15,6 @@ Required properties:
 - clock-names: must contain "jpgdec-smi" and "jpgdec".
 - power-domains: a phandle to the power domain, see
   Documentation/devicetree/bindings/power/power_domain.txt for details.
-- mediatek,larb: must contain the local arbiters in the current Socs, see
-  Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml
-  for details.
 - iommus: should point to the respective IOMMU block with master port as
   argument, see Documentation/devicetree/bindings/iommu/mediatek,iommu.txt
   for details.
@@ -32,7 +29,6 @@ Example:
clock-names = "jpgdec-smi",
  "jpgdec";
power-domains = < MT2701_POWER_DOMAIN_ISP>;
-   mediatek,larb = <>;
iommus = < MT2701_M4U_PORT_JPGDEC_WDMA>,
 < MT2701_M4U_PORT_JPGDEC_BSDMA>;
};
diff --git a/Documentation/devicetree/bindings/media/mediatek-jpeg-encoder.txt 
b/Documentation/devicetree/bindings/media/mediatek-jpeg-encoder.txt
index acfb50375b8a..4b3664987362 100644
--- a/Documentation/devicet

[PATCH v5 00/16] Clean up "mediatek,larb"

2021-04-10 Thread Yong Wu
MediaTek IOMMU block diagram always like below:

M4U
 |
smi-common
 |
  -
  | |  ...
  | |
larb1 larb2
  | |
vdec   venc

All the consumer connect with smi-larb, then connect with smi-common.

When the consumer works, it should enable the smi-larb's power which also
need enable the smi-common's power firstly.

Thus, Firstly, use the device link connect the consumer and the
smi-larbs. then add device link between the smi-larb and smi-common.

After adding the device_link, then "mediatek,larb" property can be removed.
the iommu consumer don't need call the mtk_smi_larb_get/put to enable
the power and clock of smi-larb and smi-common.

About the MM dt-bindings/dtsi patches, I guess they will go through Matthias's
tree, so I don't split them for each a MM module and each a SoC.

This patchset base on v5.12-rc2 and a vcodec patchset(separating its node)[1]
which has already been in linux-next.

[1] 
https://lore.kernel.org/linux-mediatek/20210325122625.15100-1-irui.w...@mediatek.com/

Change notes:
v5: 1) Base on v5.12-rc2.
2) Remove changing the mtk-iommu to module_platform_driver patch, It have
already been a independent patch.
3) Add several patches for the MM drivers with pm_runtime_resume_and_get
instead of pm_runtime_get_sync since smi already use it.

v4: 
https://lore.kernel.org/linux-mediatek/1590826218-23653-1-git-send-email-yong...@mediatek.com/
 
base on v5.7-rc1.
  1) Move drm PM patch before smi patchs.
  2) Change builtin_platform_driver to module_platform_driver since we may need
 build as module.
  3) Rebase many patchset as above.

v3: 
https://lore.kernel.org/linux-iommu/1567503456-24725-1-git-send-email-yong...@mediatek.com/
1) rebase on v5.3-rc1 and the latest mt8183 patchset.
2) Use device_is_bound to check whether the driver is ready from Matthias.  
  
3) Add DL_FLAG_STATELESS flag when calling device_link_add and explain the
   reason in the commit message[3/14].
4) Add a display patch[12/14] into this series. otherwise it may affect
   display HW fastlogo even though it don't happen in mt8183.
   
v2: 
https://lore.kernel.org/linux-iommu/1560171313-28299-1-git-send-email-yong...@mediatek.com/
   1) rebase on v5.2-rc1.
   2) Move adding device_link between the consumer and smi-larb into
iommu_add_device from Robin.
   3) add DL_FLAG_AUTOREMOVE_CONSUMER even though the smi is built-in from Evan.
   4) Remove the shutdown callback in iommu.   

v1: 
https://lore.kernel.org/linux-iommu/1546318276-18993-1-git-send-email-yong...@mediatek.com/

Yong Wu (15):
  dt-binding: mediatek: Get rid of mediatek,larb for multimedia HW
  iommu/mediatek: Add probe_defer for smi-larb
  iommu/mediatek: Add device_link between the consumer and the larb
devices
  memory: mtk-smi: Add device-link between smi-larb and smi-common
  media: mtk-jpeg: Use pm_runtime_resume_and_get for PM get_sync
  media: mtk-jpeg: Get rid of mtk_smi_larb_get/put
  media: mtk-mdp: Use pm_runtime_resume_and_get for PM get_sync
  media: mtk-mdp: Get rid of mtk_smi_larb_get/put
  drm/mediatek: Use pm_runtime_resume_and_get for PM get_sync
  drm/mediatek: Get rid of mtk_smi_larb_get/put
  media: mtk-vcodec: Use pm_runtime_resume_and_get for PM get_sync
  media: mtk-vcodec: Get rid of mtk_smi_larb_get/put
  memory: mtk-smi: Get rid of mtk_smi_larb_get/put
  arm: dts: mediatek: Get rid of mediatek,larb for MM nodes
  arm64: dts: mediatek: Get rid of mediatek,larb for MM nodes

Yongqiang Niu (1):
  drm/mediatek: Add pm runtime support for ovl and rdma

 .../display/mediatek/mediatek,disp.txt|  9 
 .../bindings/media/mediatek-jpeg-decoder.txt  |  4 --
 .../bindings/media/mediatek-jpeg-encoder.txt  |  4 --
 .../bindings/media/mediatek-mdp.txt   |  8 
 .../bindings/media/mediatek-vcodec.txt|  4 --
 arch/arm/boot/dts/mt2701.dtsi |  2 -
 arch/arm/boot/dts/mt7623n.dtsi|  5 --
 arch/arm64/boot/dts/mediatek/mt8173.dtsi  | 16 ---
 arch/arm64/boot/dts/mediatek/mt8183.dtsi  |  5 --
 drivers/gpu/drm/mediatek/mtk_disp_ovl.c   |  9 +++-
 drivers/gpu/drm/mediatek/mtk_disp_rdma.c  |  9 +++-
 drivers/gpu/drm/mediatek/mtk_drm_crtc.c   | 21 +
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c   | 35 --
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h   |  1 -
 drivers/gpu/drm/mediatek/mtk_drm_drv.c|  5 +-
 drivers/iommu/mtk_iommu.c | 24 +-
 drivers/iommu/mtk_iommu_v1.c  | 22 -
 .../media/platform/mtk-jpeg/mtk_jpeg_core.c   | 34 ++
 .../media/platform/mtk-jpeg/mtk_jpeg_core.h   |  2 -
 drivers/media/platform/mtk-mdp/mtk_mdp_comp.c | 40 
 drivers/media/platform/mtk-mdp/mtk_mdp_comp.h |  2 -
 drivers/media/platform/mtk-mdp/mtk_mdp_core.c |  1 -
 drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c  |  4 +-
 .../platform/mtk-vcodec/mtk_vcodec_dec_p

Re: [PATCH] iommu/mediatek: always enable the clk on resume

2021-04-09 Thread Yong Wu
On Thu, 2021-04-08 at 14:28 +0200, Dafna Hirschfeld wrote:
> In mtk_iommu_runtime_resume always enable the clk, even
> if m4u_dom is null. Otherwise the 'suspend' cb might
> disable the clk which is already disabled causing the warning:

Hi Dafna,

Thanks very much for testing and report. I have reproduced this issue
locally. It happened when iommu probe before than smi-common(iommu is
the supplier in the dev-link).

I put clk_prepare_enable in the _hw_init since I have plan to remove the
pm_runtime_get/put in the _attach_device(This will turn off the display
power domain if we show fastlogo at that time.) May be we should keep
the smi-common probe always before than iommu.

Anyway, This patch makes code symmetrical and it is good for now.

Reviewed-by: Yong Wu 

> 
> [1.586104] infra_m4u already disabled
> [1.586133] WARNING: CPU: 0 PID: 121 at drivers/clk/clk.c:952 
> clk_core_disable+0xb0/0xb8
> [1.594391] mtk-iommu 10205000.iommu: bound 18001000.larb (ops 
> mtk_smi_larb_component_ops)
> [1.598108] Modules linked in:
> [1.598114] CPU: 0 PID: 121 Comm: kworker/0:2 Not tainted 5.12.0-rc5 #69
> [1.609246] mtk-iommu 10205000.iommu: bound 14027000.larb (ops 
> mtk_smi_larb_component_ops)
> [1.617487] Hardware name: Google Elm (DT)
> [1.617491] Workqueue: pm pm_runtime_work
> [1.620545] mtk-iommu 10205000.iommu: bound 19001000.larb (ops 
> mtk_smi_larb_component_ops)
> 
> [1.627229] pstate: 6085 (nZCv daIf -PAN -UAO -TCO BTYPE=--)
> [1.659297] pc : clk_core_disable+0xb0/0xb8
> [1.663475] lr : clk_core_disable+0xb0/0xb8
> [1.667652] sp : 800011b9bbe0
> [1.670959] x29: 800011b9bbe0 x28: 
> [1.676267] x27: 800011448000 x26: 8000100cfd98
> [1.681574] x25: 800011b9bd48 x24: 
> [1.686882] x23:  x22: 8000106fad90
> [1.692189] x21: 000a x20: c0048500
> [1.697496] x19: c0048500 x18: 
> [1.702804] x17:  x16: 
> [1.708112] x15: 800011460300 x14: fffe
> [1.713420] x13: 8000114602d8 x12: 0720072007200720
> [1.718727] x11: 0720072007200720 x10: 0720072007200720
> [1.724035] x9 : 800011b9bbe0 x8 : 800011b9bbe0
> [1.729342] x7 : 0009 x6 : 8000114b8328
> [1.734649] x5 :  x4 : 
> [1.739956] x3 :  x2 : 800011460298
> [1.745263] x1 : 1af1d7de276f4500 x0 : 
> [1.750572] Call trace:
> [1.753010]  clk_core_disable+0xb0/0xb8
> [1.756840]  clk_core_disable_lock+0x24/0x40
> [1.761105]  clk_disable+0x20/0x30
> [1.764501]  mtk_iommu_runtime_suspend+0x88/0xa8
> [1.769114]  pm_generic_runtime_suspend+0x2c/0x48
> [1.773815]  __rpm_callback+0xe0/0x178
> [1.777559]  rpm_callback+0x24/0x88
> [1.781041]  rpm_suspend+0xdc/0x470
> [1.784523]  rpm_idle+0x12c/0x170
> [1.787831]  pm_runtime_work+0xa8/0xc0
> [1.791573]  process_one_work+0x1e8/0x360
> [1.795580]  worker_thread+0x44/0x478
> [1.799237]  kthread+0x150/0x158
> [1.802460]  ret_from_fork+0x10/0x30
> [1.806034] ---[ end trace 82402920ef64573b ]---
> [1.810728] [ cut here ]
> 
> In addition, we now don't need to enable the clock from the
> function mtk_iommu_hw_init since it is already enabled by the resume.
> 
> Fixes: commit c0b57581b73b ("iommu/mediatek: Add power-domain operation")
> Signed-off-by: Dafna Hirschfeld 
> ---
>  drivers/iommu/mtk_iommu.c | 19 ---
>  1 file changed, 8 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
> index 6ecc007f07cd..e168a682806a 100644
> --- a/drivers/iommu/mtk_iommu.c
> +++ b/drivers/iommu/mtk_iommu.c
> @@ -688,13 +688,6 @@ static const struct iommu_ops mtk_iommu_ops = {
>  static int mtk_iommu_hw_init(const struct mtk_iommu_data *data)
>  {
>   u32 regval;
> - int ret;
> -
> - ret = clk_prepare_enable(data->bclk);
> - if (ret) {
> - dev_err(data->dev, "Failed to enable iommu bclk(%d)\n", ret);
> - return ret;
> - }
>  
>   if (data->plat_data->m4u_plat == M4U_MT8173) {
>   regval = F_MMU_PREFETCH_RT_REPLACE_MOD |
> @@ -760,7 +753,6 @@ static int mtk_iommu_hw_init(const struct mtk_iommu_data 
> *data)
>   if (devm_request_irq(data->dev, data->irq, mtk_iommu_isr, 0,
>dev_name(data->dev), (void *)data)) {
>   writel_relaxed(0, data->base + REG_MMU_PT_BASE_ADDR);
> - clk_disable_unprepare(data->bclk);
>  

Re: [PATCH 3/5] arm64: dts: mediatek: mt8167: add larb nodes

2021-04-06 Thread Yong Wu
On Mon, 2021-04-05 at 22:08 +0200, Fabien Parent wrote:
> Add larb nodes for MT8167:
> * larb0 is used for display (dsi and hdmi)
> * larb1 is used for camera (csi)
> * larb2 is used for the video hardware decoder
> 
> Signed-off-by: Fabien Parent 
> ---
>  arch/arm64/boot/dts/mediatek/mt8167.dtsi | 33 
>  1 file changed, 33 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/mediatek/mt8167.dtsi 
> b/arch/arm64/boot/dts/mediatek/mt8167.dtsi
> index 4b951f81db9e..9b352031c5f6 100644
> --- a/arch/arm64/boot/dts/mediatek/mt8167.dtsi
> +++ b/arch/arm64/boot/dts/mediatek/mt8167.dtsi
> @@ -140,5 +140,38 @@ smi_common: smi@14017000 {
>   clock-names = "apb", "smi";
>   power-domains = < MT8167_POWER_DOMAIN_MM>;
>   };
> +
> + larb0: larb@14016000 {
> + compatible = "mediatek,mt8167-smi-larb";
> + reg = <0 0x14016000 0 0x1000>;
> + mediatek,smi = <_common>;
> + mediatek,larbid = <0>;

From [1], This should be: mediatek,larb-id.

Actually this property is unnecessary in this SoC since this larb-id in
the m4u node is consecutive.

[1]
https://elixir.bootlin.com/linux/v5.12-rc2/source/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml#L58

> + clocks = < CLK_MM_SMI_LARB0>,
> +  < CLK_MM_SMI_LARB0>;
> + clock-names = "apb", "smi";
> + power-domains = < MT8167_POWER_DOMAIN_MM>;
> + };
> +
> + larb1: larb@15001000 {
> + compatible = "mediatek,mt8167-smi-larb";
> + reg = <0 0x15001000 0 0x1000>;
> + mediatek,smi = <_common>;
> + mediatek,larbid = <1>;
> + clocks = < CLK_IMG_LARB1_SMI>,
> +  < CLK_IMG_LARB1_SMI>;
> + clock-names = "apb", "smi";
> + power-domains = < MT8167_POWER_DOMAIN_ISP>;
> + };
> +
> + larb2: larb@1601 {
> + compatible = "mediatek,mt8167-smi-larb";
> + reg = <0 0x1601 0 0x1000>;
> + mediatek,smi = <_common>;
> + mediatek,larbid = <2>;
> + clocks = < CLK_VDEC_CKEN>,
> +  < CLK_VDEC_LARB1_CKEN>;
> + clock-names = "apb", "smi";
> + power-domains = < MT8167_POWER_DOMAIN_VDEC>;
> + };
>   };
>  };



[PATCH v2 2/2] iommu/mediatek: Allow building as module

2021-03-25 Thread Yong Wu
The IOMMU in many SoC depends on the MM clocks and power-domain which
are device_initcall normally, thus the subsys_init here is not helpful.
This patch switches it to module_platform_driver which also allow the
driver built as module.

Correspondingly switch the config to tristate, and update the
iommu_ops's owner.

Signed-off-by: Yong Wu 
---
 drivers/iommu/Kconfig |  2 +-
 drivers/iommu/mtk_iommu.c | 17 +
 2 files changed, 6 insertions(+), 13 deletions(-)

diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
index bc93da48bed0..74f3e15edc14 100644
--- a/drivers/iommu/Kconfig
+++ b/drivers/iommu/Kconfig
@@ -349,7 +349,7 @@ config S390_AP_IOMMU
  is not implemented as it is not necessary for VFIO.
 
 config MTK_IOMMU
-   bool "MTK IOMMU Support"
+   tristate "MediaTek IOMMU Support"
depends on ARCH_MEDIATEK || COMPILE_TEST
select ARM_DMA_USE_IOMMU
select IOMMU_API
diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index 6ecc007f07cd..75375935f301 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -17,6 +17,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -683,6 +684,7 @@ static const struct iommu_ops mtk_iommu_ops = {
.get_resv_regions = mtk_iommu_get_resv_regions,
.put_resv_regions = generic_iommu_put_resv_regions,
.pgsize_bitmap  = SZ_4K | SZ_64K | SZ_1M | SZ_16M,
+   .owner  = THIS_MODULE,
 };
 
 static int mtk_iommu_hw_init(const struct mtk_iommu_data *data)
@@ -1079,16 +1081,7 @@ static struct platform_driver mtk_iommu_driver = {
.pm = _iommu_pm_ops,
}
 };
+module_platform_driver(mtk_iommu_driver);
 
-static int __init mtk_iommu_init(void)
-{
-   int ret;
-
-   ret = platform_driver_register(_iommu_driver);
-   if (ret != 0)
-   pr_err("Failed to register MTK IOMMU driver\n");
-
-   return ret;
-}
-
-subsys_initcall(mtk_iommu_init)
+MODULE_DESCRIPTION("IOMMU API for MediaTek M4U implementations");
+MODULE_LICENSE("GPL v2");
-- 
2.18.0



[PATCH v2 1/2] iommu/mediatek-v1: Allow building as module

2021-03-25 Thread Yong Wu
This patch only adds support for building the IOMMU-v1 driver as module.
Correspondingly switch the config to tristate and update the iommu_ops's
owner to THIS_MODULE.

Signed-off-by: Yong Wu 
---
v2: change note:
a) Update iommu_ops's owner to THIS_MODULE
b) Fix typo in the title from "Alloc" to "Allow"

v1: rebase on v5.12-rc2
---
 drivers/iommu/Kconfig|  2 +-
 drivers/iommu/mtk_iommu_v1.c | 10 +-
 2 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
index 192ef8f61310..bc93da48bed0 100644
--- a/drivers/iommu/Kconfig
+++ b/drivers/iommu/Kconfig
@@ -364,7 +364,7 @@ config MTK_IOMMU
  If unsure, say N here.
 
 config MTK_IOMMU_V1
-   bool "MTK IOMMU Version 1 (M4U gen1) Support"
+   tristate "MediaTek IOMMU Version 1 (M4U gen1) Support"
depends on ARM
depends on ARCH_MEDIATEK || COMPILE_TEST
select ARM_DMA_USE_IOMMU
diff --git a/drivers/iommu/mtk_iommu_v1.c b/drivers/iommu/mtk_iommu_v1.c
index 82ddfe9170d4..be1b20e3f20e 100644
--- a/drivers/iommu/mtk_iommu_v1.c
+++ b/drivers/iommu/mtk_iommu_v1.c
@@ -20,6 +20,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -529,6 +530,7 @@ static const struct iommu_ops mtk_iommu_ops = {
.def_domain_type = mtk_iommu_def_domain_type,
.device_group   = generic_device_group,
.pgsize_bitmap  = ~0UL << MT2701_IOMMU_PAGE_SHIFT,
+   .owner  = THIS_MODULE,
 };
 
 static const struct of_device_id mtk_iommu_of_ids[] = {
@@ -691,9 +693,7 @@ static struct platform_driver mtk_iommu_driver = {
.pm = _iommu_pm_ops,
}
 };
+module_platform_driver(mtk_iommu_driver);
 
-static int __init m4u_init(void)
-{
-   return platform_driver_register(_iommu_driver);
-}
-subsys_initcall(m4u_init);
+MODULE_DESCRIPTION("IOMMU API for MediaTek M4U v1 implementations");
+MODULE_LICENSE("GPL v2");
-- 
2.18.0



[PATCH 2/2] iommu/mediatek: Alloc building as module

2021-03-22 Thread Yong Wu
The IOMMU in many SoC depends on the MM clocks and power-domain which
are device_initcall normally, thus the subsys_init here is not helpful.
This patch switches it to module_platform_driver which allow the
driver built as module.

Correspondingly switch the config to tristate.

Signed-off-by: Yong Wu 
---
 drivers/iommu/Kconfig |  2 +-
 drivers/iommu/mtk_iommu.c | 16 
 2 files changed, 5 insertions(+), 13 deletions(-)

diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
index bc93da48bed0..74f3e15edc14 100644
--- a/drivers/iommu/Kconfig
+++ b/drivers/iommu/Kconfig
@@ -349,7 +349,7 @@ config S390_AP_IOMMU
  is not implemented as it is not necessary for VFIO.
 
 config MTK_IOMMU
-   bool "MTK IOMMU Support"
+   tristate "MediaTek IOMMU Support"
depends on ARCH_MEDIATEK || COMPILE_TEST
select ARM_DMA_USE_IOMMU
select IOMMU_API
diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index 6ecc007f07cd..a73ff3e20480 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -17,6 +17,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -1079,16 +1080,7 @@ static struct platform_driver mtk_iommu_driver = {
.pm = _iommu_pm_ops,
}
 };
+module_platform_driver(mtk_iommu_driver);
 
-static int __init mtk_iommu_init(void)
-{
-   int ret;
-
-   ret = platform_driver_register(_iommu_driver);
-   if (ret != 0)
-   pr_err("Failed to register MTK IOMMU driver\n");
-
-   return ret;
-}
-
-subsys_initcall(mtk_iommu_init)
+MODULE_DESCRIPTION("IOMMU API for MediaTek M4U implementations");
+MODULE_LICENSE("GPL v2");
-- 
2.18.0



[PATCH 1/2] iommu/mediatek-v1: Alloc building as module

2021-03-22 Thread Yong Wu
This patch only adds support for building the IOMMU-v1 driver as module.
Correspondingly switch the config to tristate.

Signed-off-by: Yong Wu 
---
rebase on v5.12-rc2.
---
 drivers/iommu/Kconfig| 2 +-
 drivers/iommu/mtk_iommu_v1.c | 9 -
 2 files changed, 5 insertions(+), 6 deletions(-)

diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
index 192ef8f61310..bc93da48bed0 100644
--- a/drivers/iommu/Kconfig
+++ b/drivers/iommu/Kconfig
@@ -364,7 +364,7 @@ config MTK_IOMMU
  If unsure, say N here.
 
 config MTK_IOMMU_V1
-   bool "MTK IOMMU Version 1 (M4U gen1) Support"
+   tristate "MediaTek IOMMU Version 1 (M4U gen1) Support"
depends on ARM
depends on ARCH_MEDIATEK || COMPILE_TEST
select ARM_DMA_USE_IOMMU
diff --git a/drivers/iommu/mtk_iommu_v1.c b/drivers/iommu/mtk_iommu_v1.c
index 82ddfe9170d4..71370037083a 100644
--- a/drivers/iommu/mtk_iommu_v1.c
+++ b/drivers/iommu/mtk_iommu_v1.c
@@ -20,6 +20,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -691,9 +692,7 @@ static struct platform_driver mtk_iommu_driver = {
.pm = _iommu_pm_ops,
}
 };
+module_platform_driver(mtk_iommu_driver);
 
-static int __init m4u_init(void)
-{
-   return platform_driver_register(_iommu_driver);
-}
-subsys_initcall(m4u_init);
+MODULE_DESCRIPTION("IOMMU API for MediaTek M4U v1 implementations");
+MODULE_LICENSE("GPL v2");
-- 
2.18.0



Re: [PATCH] MAINTAINERS: repair file pattern in MEDIATEK IOMMU DRIVER

2021-02-07 Thread Yong Wu
On Mon, 2021-02-08 at 07:10 +0100, Lukas Bulwahn wrote:
> Commit 6af4873852c4 ("MAINTAINERS: Add entry for MediaTek IOMMU") mentions
> the pattern 'drivers/iommu/mtk-iommu*', but the files are actually named
> with an underscore, not with a hyphen.
> 
> Hence, ./scripts/get_maintainer.pl --self-test=patterns complains:
> 
>   warning: no file matches  F:drivers/iommu/mtk-iommu*
> 
> Repair this minor typo in the file pattern.
> 
> Signed-off-by: Lukas Bulwahn 
> ---
> applies cleanly on next-20210205
> 
> Yong, please ack.

+Joerg.

sorry for the typo.

Acked-by: Yong Wu 

> Will, please pick this minor fixup for your iommu-next tree.
> 
>  MAINTAINERS | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 674f42375acf..6b507e8d7828 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -11200,7 +11200,7 @@ L:io...@lists.linux-foundation.org
>  L:   linux-media...@lists.infradead.org (moderated for non-subscribers)
>  S:   Supported
>  F:   Documentation/devicetree/bindings/iommu/mediatek*
> -F:   drivers/iommu/mtk-iommu*
> +F:   drivers/iommu/mtk_iommu*
>  F:   include/dt-bindings/memory/mt*-port.h
>  
>  MEDIATEK JPEG DRIVER



Re: [PATCH] iommu/mediatek: Fix error code in probe()

2021-02-06 Thread Yong Wu
On Fri, 2021-02-05 at 15:46 +0300, Dan Carpenter wrote:
> This error path is supposed to return -EINVAL.  It used to return
> directly but we added some clean up and accidentally removed the
> error code.  Also I fixed a typo in the error message.
> 
> Fixes: c0b57581b73b ("iommu/mediatek: Add power-domain operation")
> Signed-off-by: Dan Carpenter 

Reviewed-by: Yong Wu 

> ---
>  drivers/iommu/mtk_iommu.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
> index 0ad14a7604b1..5f78ac0dc30e 100644
> --- a/drivers/iommu/mtk_iommu.c
> +++ b/drivers/iommu/mtk_iommu.c
> @@ -886,7 +886,8 @@ static int mtk_iommu_probe(struct platform_device *pdev)
>   link = device_link_add(data->smicomm_dev, dev,
>   DL_FLAG_STATELESS | DL_FLAG_PM_RUNTIME);
>   if (!link) {
> - dev_err(dev, "Unable link %s.\n", dev_name(data->smicomm_dev));
> + dev_err(dev, "Unable to link %s.\n", 
> dev_name(data->smicomm_dev));
> + ret = -EINVAL;
>   goto out_runtime_disable;
>   }
>  



Re: [PATCH][next] iommu/mediatek: Fix unsigned domid comparison with less than zero

2021-02-03 Thread Yong Wu
On Wed, 2021-02-03 at 13:59 +, Colin King wrote:
> From: Colin Ian King 
> 
> Currently the check for domid < 0 is always false because domid
> is unsigned.  Fix this by making it signed.
> 
> Addresses-CoverityL ("Unsigned comparison against 0")
> Fixes: ab1d5281a62b ("iommu/mediatek: Add iova reserved function")
> Signed-off-by: Colin Ian King 

Thanks for the fix.

Reviewed-by: Yong Wu 

> ---
>  drivers/iommu/mtk_iommu.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
> index 0ad14a7604b1..823d719945b2 100644
> --- a/drivers/iommu/mtk_iommu.c
> +++ b/drivers/iommu/mtk_iommu.c
> @@ -640,7 +640,7 @@ static void mtk_iommu_get_resv_regions(struct device *dev,
>  struct list_head *head)
>  {
>   struct mtk_iommu_data *data = dev_iommu_priv_get(dev);
> - unsigned int domid = mtk_iommu_get_domain_id(dev, data->plat_data), i;
> + int domid = mtk_iommu_get_domain_id(dev, data->plat_data), i;
>   const struct mtk_iommu_iova_region *resv, *curdom;
>   struct iommu_resv_region *region;
>   int prot = IOMMU_WRITE | IOMMU_READ;



Re: [PATCH v6 00/33] MT8192 IOMMU support

2021-02-01 Thread Yong Wu
On Mon, 2021-02-01 at 14:54 +, Will Deacon wrote:
> On Mon, Jan 11, 2021 at 07:18:41PM +0800, Yong Wu wrote:
> > This patch mainly adds support for mt8192 Multimedia IOMMU and SMI.
> > 
> > mt8192 also is MTK IOMMU gen2 which uses ARM Short-Descriptor translation
> > table format. The M4U-SMI HW diagram is as below:
> > 
> >   EMI
> >|
> >   M4U
> >|
> >   
> >SMI Common
> >   
> >|
> >   +---+--+--+--+---+
> >   |   |  |  |   .. |   |
> >   |   |  |  |  |   |
> > larb0   larb1  larb2  larb4 ..  larb19   larb20
> > disp0   disp1   mdpvdec   IPE  IPE
> > 
> > All the connections are HW fixed, SW can NOT adjust it.
> > 
> > Comparing with the preview SoC, this patchset mainly adds two new functions:
> > a) add iova 34 bits support.
> > b) add multi domains support since several HW has the special iova
> > region requirement.
> > 
> > change note:
> > v6:a) base on v5.11-rc1. and tlb v4:
> >   
> > https://lore.kernel.org/linux-mediatek/20210107122909.16317-1-yong...@mediatek.com/T/#t
> >  
> 
> I've queued this up apart from patches 6 and 7.

Thanks very much for the applying. I'd like to show there is a little
conflict with a smi change[1] in /include/soc/mediatek/smi.h.

This is the detailed conflict:

--- a/include/soc/mediatek/smi.h
+++ b/include/soc/mediatek/smi.h
@@ -9,7 +9,7 @@
 #include 
 #include 
 
-#ifdef CONFIG_MTK_SMI
+#if IS_ENABLED(CONFIG_MTK_SMI)   <---The smi patch change here.
 
 #define MTK_LARB_NR_MAX   16  <---This iommu patchset delete this line.


This code is simple. Please feel free to tell me how to do this if this
is not convenient to merge.

[1]
https://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux-mem-ctrl.git/commit/?h=for-next=50fc8d9232cdc64b9e9d1b9488452f153de52b69

> 
> Thanks,
> 
> Will



Re: [PATCH] iommu: Properly pass gfp_t in _iommu_map() to avoid atomic sleeping

2021-02-01 Thread Yong Wu
On Mon, 2021-02-01 at 17:06 -0800, Douglas Anderson wrote:
> Sleeping while atomic = bad.  Let's fix an obvious typo to try to avoid it.
> 
> The warning that was seen (on a downstream kernel with the problematic
> patch backported):
> 
>  BUG: sleeping function called from invalid context at mm/page_alloc.c:4726
>  in_atomic(): 1, irqs_disabled(): 0, non_block: 0, pid: 9, name: ksoftirqd/0
>  CPU: 0 PID: 9 Comm: ksoftirqd/0 Not tainted 5.4.93-12508-gc10c93e28e39 #1
>  Call trace:
>   dump_backtrace+0x0/0x154
>   show_stack+0x20/0x2c
>   dump_stack+0xa0/0xfc
>   ___might_sleep+0x11c/0x12c
>   __might_sleep+0x50/0x84
>   __alloc_pages_nodemask+0xf8/0x2bc
>   __arm_lpae_alloc_pages+0x48/0x1b4
>   __arm_lpae_map+0x124/0x274
>   __arm_lpae_map+0x1cc/0x274
>   arm_lpae_map+0x140/0x170
>   arm_smmu_map+0x78/0xbc
>   __iommu_map+0xd4/0x210
>   _iommu_map+0x4c/0x84
>   iommu_map_atomic+0x44/0x58
>   __iommu_dma_map+0x8c/0xc4
>   iommu_dma_map_page+0xac/0xf0
> 
> Fixes: d8c1df02ac7f ("iommu: Move iotlb_sync_map out from __iommu_map")
> Signed-off-by: Douglas Anderson 

oh. This is my fault. Thanks for the fix.

Reviewed-by: Yong Wu 

> ---
> I haven't done any serious testing on this.  I saw a report of the
> warning and the fix seemed obvious so I'm shooting it out.
> 
>  drivers/iommu/iommu.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
> index 3d099a31ddca..2b06b01850d5 100644
> --- a/drivers/iommu/iommu.c
> +++ b/drivers/iommu/iommu.c
> @@ -2441,7 +2441,7 @@ static int _iommu_map(struct iommu_domain *domain, 
> unsigned long iova,
>   const struct iommu_ops *ops = domain->ops;
>   int ret;
>  
> - ret = __iommu_map(domain, iova, paddr, size, prot, GFP_KERNEL);
> + ret = __iommu_map(domain, iova, paddr, size, prot, gfp);
>   if (ret == 0 && ops->iotlb_sync_map)
>   ops->iotlb_sync_map(domain, iova, size);
>  



Re: [PATCH v5 06/27] dt-bindings: mediatek: Add binding for mt8192 IOMMU

2021-01-31 Thread Yong Wu
On Fri, 2021-01-29 at 20:45 +0900, Tomasz Figa wrote:
> On Mon, Jan 25, 2021 at 4:34 PM Yong Wu  wrote:
> >
> > On Mon, 2021-01-25 at 13:18 +0900, Tomasz Figa wrote:
> > > On Wed, Jan 20, 2021 at 4:08 PM Yong Wu  wrote:
> > > >
> > > > On Wed, 2021-01-20 at 13:15 +0900, Tomasz Figa wrote:
> > > > > On Wed, Jan 13, 2021 at 3:45 PM Yong Wu  wrote:
> > > > > >
> > > > > > On Wed, 2021-01-13 at 14:30 +0900, Tomasz Figa wrote:
> > > > > > > On Thu, Dec 24, 2020 at 8:35 PM Yong Wu  
> > > > > > > wrote:
> > > > > > > >
> > > > > > > > On Wed, 2020-12-23 at 17:18 +0900, Tomasz Figa wrote:
> > > > > > > > > On Wed, Dec 09, 2020 at 04:00:41PM +0800, Yong Wu wrote:
> > > > > > > > > > This patch adds decriptions for mt8192 IOMMU and SMI.
> > > > > > > > > >
> > > > > > > > > > mt8192 also is MTK IOMMU gen2 which uses ARM 
> > > > > > > > > > Short-Descriptor translation
> > > > > > > > > > table format. The M4U-SMI HW diagram is as below:
> > > > > > > > > >
> > > > > > > > > >   EMI
> > > > > > > > > >|
> > > > > > > > > >   M4U
> > > > > > > > > >|
> > > > > > > > > >   
> > > > > > > > > >SMI Common
> > > > > > > > > >   
> > > > > > > > > >|
> > > > > > > > > >   +---+--+--+--+---+
> > > > > > > > > >   |   |  |  |   .. |   |
> > > > > > > > > >   |   |  |  |  |   |
> > > > > > > > > > larb0   larb1  larb2  larb4 ..  larb19   larb20
> > > > > > > > > > disp0   disp1   mdpvdec   IPE  IPE
> > > > > > > > > >
> > > > > > > > > > All the connections are HW fixed, SW can NOT adjust it.
> > > > > > > > > >
> > > > > > > > > > mt8192 M4U support 0~16GB iova range. we preassign 
> > > > > > > > > > different engines
> > > > > > > > > > into different iova ranges:
> > > > > > > > > >
> > > > > > > > > > domain-id  module iova-range  larbs
> > > > > > > > > >0   disp0 ~ 4G  larb0/1
> > > > > > > > > >1   vcodec  4G ~ 8G larb4/5/7
> > > > > > > > > >2   cam/mdp 8G ~ 12G 
> > > > > > > > > > larb2/9/11/13/14/16/17/18/19/20
> > > > > > > > >
> > > > > > > > > Why do we preassign these addresses in DT? Shouldn't it be a 
> > > > > > > > > user's or
> > > > > > > > > integrator's decision to split the 16 GB address range into 
> > > > > > > > > sub-ranges
> > > > > > > > > and define which larbs those sub-ranges are shared with?
> > > > > > > >
> > > > > > > > The problem is that we can't split the 16GB range with the larb 
> > > > > > > > as unit.
> > > > > > > > The example is the below ccu0(larb13 port9/10) is a independent
> > > > > > > > range(domain), the others ports in larb13 is in another domain.
> > > > > > > >
> > > > > > > > disp/vcodec/cam/mdp don't have special iova requirement, they 
> > > > > > > > could
> > > > > > > > access any range. vcodec also can locate 8G~12G. it don't care 
> > > > > > > > about
> > > > > > > > where its iova locate. here I preassign like this following 
> > > > > > > > with our
> > > > > > > > internal project setting.
> > 

Re: [PATCH v6 07/33] iommu: Avoid reallocate default domain for a group

2021-01-28 Thread Yong Wu
On Thu, 2021-01-28 at 21:14 +, Will Deacon wrote:
> On Thu, Jan 28, 2021 at 09:10:20PM +, Will Deacon wrote:
> > On Wed, Jan 27, 2021 at 05:39:16PM +0800, Yong Wu wrote:
> > > On Tue, 2021-01-26 at 22:23 +, Will Deacon wrote:
> > > > On Mon, Jan 11, 2021 at 07:18:48PM +0800, Yong Wu wrote:
> > > > > If group->default_domain exists, avoid reallocate it.
> > > > > 
> > > > > In some iommu drivers, there may be several devices share a group. 
> > > > > Avoid
> > > > > realloc the default domain for this case.
> > > > > 
> > > > > Signed-off-by: Yong Wu 
> > > > > ---
> > > > >  drivers/iommu/iommu.c | 3 ++-
> > > > >  1 file changed, 2 insertions(+), 1 deletion(-)
> > > > > 
> > > > > diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
> > > > > index 3d099a31ddca..f4b87e6abe80 100644
> > > > > --- a/drivers/iommu/iommu.c
> > > > > +++ b/drivers/iommu/iommu.c
> > > > > @@ -266,7 +266,8 @@ int iommu_probe_device(struct device *dev)
> > > > >* support default domains, so the return value is not yet
> > > > >* checked.
> > > > >*/
> > > > > - iommu_alloc_default_domain(group, dev);
> > > > > + if (!group->default_domain)
> > > > > + iommu_alloc_default_domain(group, dev);
> > > > 
> > > > I don't really get what this achieves, since 
> > > > iommu_alloc_default_domain()
> > > > looks like this:
> > > > 
> > > > static int iommu_alloc_default_domain(struct iommu_group *group,
> > > >   struct device *dev)
> > > > {
> > > > unsigned int type;
> > > > 
> > > > if (group->default_domain)
> > > > return 0;
> > > > 
> > > > ...
> > > > 
> > > > in which case, it should be fine?
> > > 
> > > oh. sorry, I overlooked this. the current code is enough.
> > > I will remove this patch. and send the next version in this week.
> > > Thanks very much.
> > 
> > Actually, looking at this again, if we're dropping this patch and patch 6
> > just needs the kfree() moving about, then there's no need to repost. The
> > issue that Robin and Paul are discussing can be handled separately.
> 
> Argh, except that this version of the patches doesn't apply :)
> 
> So after all that, please go ahead and post a v7 ASAP based on this branch:
> 
> https://git.kernel.org/pub/scm/linux/kernel/git/will/linux.git/log/?h=for-joerg/mtk

After confirm with Tomasz, He still need some time to take a look at v6.

thus I need wait some time to send v7 after his feedback.

Thanks for your comment. and Thanks Tomasz for the review.

> 
> Will



Re: [PATCH v6 07/33] iommu: Avoid reallocate default domain for a group

2021-01-27 Thread Yong Wu
On Tue, 2021-01-26 at 22:23 +, Will Deacon wrote:
> On Mon, Jan 11, 2021 at 07:18:48PM +0800, Yong Wu wrote:
> > If group->default_domain exists, avoid reallocate it.
> > 
> > In some iommu drivers, there may be several devices share a group. Avoid
> > realloc the default domain for this case.
> > 
> > Signed-off-by: Yong Wu 
> > ---
> >  drivers/iommu/iommu.c | 3 ++-
> >  1 file changed, 2 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
> > index 3d099a31ddca..f4b87e6abe80 100644
> > --- a/drivers/iommu/iommu.c
> > +++ b/drivers/iommu/iommu.c
> > @@ -266,7 +266,8 @@ int iommu_probe_device(struct device *dev)
> >  * support default domains, so the return value is not yet
> >  * checked.
> >  */
> > -   iommu_alloc_default_domain(group, dev);
> > +   if (!group->default_domain)
> > +   iommu_alloc_default_domain(group, dev);
> 
> I don't really get what this achieves, since iommu_alloc_default_domain()
> looks like this:
> 
> static int iommu_alloc_default_domain(struct iommu_group *group,
> struct device *dev)
> {
>   unsigned int type;
> 
>   if (group->default_domain)
>   return 0;
> 
>   ...
> 
> in which case, it should be fine?

oh. sorry, I overlooked this. the current code is enough.
I will remove this patch. and send the next version in this week.
Thanks very much.

> 
> Will



Re: [PATCH 3/3] memory: mtk-smi: Switch MTK_SMI to tristate

2021-01-26 Thread Yong Wu
On Mon, 2021-01-25 at 09:44 +0100, Krzysztof Kozlowski wrote:
> On Mon, Jan 25, 2021 at 02:49:44PM +0800, Yong Wu wrote:
> > On Fri, 2021-01-22 at 22:35 +0100, Krzysztof Kozlowski wrote:
> > > On Thu, Jan 21, 2021 at 02:24:29PM +0800, Yong Wu wrote:
> > > > This patch switches MTK_SMI to tristate. Support it could be 'm'.
> > > > 
> > > > Meanwhile, Fix a build issue while MTK_SMI is built as module.
> > > 
> > > s/Fix/fix.
> > > 
> > > What error is being fixed here? How can I reproduce it? Aren't you just
> > > adjusting it to being buildable by module?
> > 
> > Sorry, I didn't copy the fail log here. This is the build log:
> > 
> > In file included from .../drivers/iommu/mtk_iommu.c:34:0:
> > .../drivers/iommu/mtk_iommu.h:84:28: error: array type has incomplete
> > element type 'struct mtk_smi_larb_iommu'
> >   struct mtk_smi_larb_iommu larb_imu[MTK_LARB_NR_MAX];
> > 
> > Our iommu driver will use this structure. but it was contained by
> > "#ifdef CONFIG_MTK_SMI". thus I change it to "#if
> > IS_ENABLED(CONFIG_MTK_SMI)"
> > 
> > If reproducing it, we should change mtk-iommu to module_init[1]. and
> > switch kconfig MTK_IOMMU to tristate, then change the CONFIG_MTK_IOMMU
> > to m. we could get the fail log.
> > 
> > In this case, Should I squash this change into this patch? I though this
> > is a preparing patch and the fail is caused by MTK_SMI. thus I squash
> > that into this patch. or change it as a independent patch and send when
> > I change MTK_IOMMU to tristate?
> 
> If I understand correctly, there is no error before this patch. In such
> case just don't mention the error to fix, because it is simply part of
> making things modular.

Yes. No error before this patch.

Appreciate for your help. I will remove this in the comment message in
the next version.

> 
> Best regards,
> Krzysztof
> 



[PATCH v2] memory: mtk-smi: Support SMI modular

2021-01-26 Thread Yong Wu
This patch mainly support SMI modular. Switch MTK_SMI to tristate,
and add module_exit/module_license.

Signed-off-by: Yong Wu 
---
This patch rebase on the clean v5.11-rc1.
and this one: memory: mtk-smi: Use platform_register_drivers
https://lore.kernel.org/linux-arm-kernel/20210121062429.26504-2-yong...@mediatek.com/

change note:
a) squash the last two of v1 into one patch.
b) Remove module_alias
---
 drivers/memory/Kconfig | 2 +-
 drivers/memory/mtk-smi.c   | 9 +
 include/soc/mediatek/smi.h | 2 +-
 3 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/drivers/memory/Kconfig b/drivers/memory/Kconfig
index 3ea6913df176..05c6d4a32285 100644
--- a/drivers/memory/Kconfig
+++ b/drivers/memory/Kconfig
@@ -173,7 +173,7 @@ config JZ4780_NEMC
  memory devices such as NAND and SRAM.
 
 config MTK_SMI
-   bool "Mediatek SoC Memory Controller driver" if COMPILE_TEST
+   tristate "MediaTek SoC Memory Controller driver" if COMPILE_TEST
depends on ARCH_MEDIATEK || COMPILE_TEST
help
  This driver is for the Memory Controller module in MediaTek SoCs,
diff --git a/drivers/memory/mtk-smi.c b/drivers/memory/mtk-smi.c
index e2aebd2bfa8e..3a269415db73 100644
--- a/drivers/memory/mtk-smi.c
+++ b/drivers/memory/mtk-smi.c
@@ -597,3 +597,12 @@ static int __init mtk_smi_init(void)
return platform_register_drivers(smidrivers, ARRAY_SIZE(smidrivers));
 }
 module_init(mtk_smi_init);
+
+static void __exit mtk_smi_exit(void)
+{
+   platform_unregister_drivers(smidrivers, ARRAY_SIZE(smidrivers));
+}
+module_exit(mtk_smi_exit);
+
+MODULE_DESCRIPTION("MediaTek SMI driver");
+MODULE_LICENSE("GPL v2");
diff --git a/include/soc/mediatek/smi.h b/include/soc/mediatek/smi.h
index 5a34b87d89e3..29e2fb8f33d6 100644
--- a/include/soc/mediatek/smi.h
+++ b/include/soc/mediatek/smi.h
@@ -9,7 +9,7 @@
 #include 
 #include 
 
-#ifdef CONFIG_MTK_SMI
+#if IS_ENABLED(CONFIG_MTK_SMI)
 
 #define MTK_LARB_NR_MAX16
 
-- 
2.18.0



Re: [PATCH 2/3] memory: mtk-smi: Add module_exit and module_license

2021-01-26 Thread Yong Wu
On Mon, 2021-01-25 at 11:40 +0100, Krzysztof Kozlowski wrote:
> On Mon, Jan 25, 2021 at 05:28:05PM +0800, Yong Wu wrote:
> > On Mon, 2021-01-25 at 09:40 +0100, Krzysztof Kozlowski wrote:
> > > On Mon, Jan 25, 2021 at 02:49:41PM +0800, Yong Wu wrote:
> > > > On Fri, 2021-01-22 at 22:34 +0100, Krzysztof Kozlowski wrote:
> > > > > On Thu, Jan 21, 2021 at 02:24:28PM +0800, Yong Wu wrote:
> > > > > > The config MTK_SMI always depends on MTK_IOMMU which is built-in
> > > > > > currently. Thus we don't have module_exit before. This patch adds
> > > > > > module_exit and module_license. It is a preparing patch for 
> > > > > > supporting
> > > > > > MTK_SMI could been built as a module.
> > > > > > 
> > > > > > Signed-off-by: Yong Wu 
> > > > > > ---
> > > > > >  drivers/memory/mtk-smi.c | 10 ++
> > > > > >  1 file changed, 10 insertions(+)
> > > > > > 
> > > > > > diff --git a/drivers/memory/mtk-smi.c b/drivers/memory/mtk-smi.c
> > > > > > index e2aebd2bfa8e..aa2a25abf04f 100644
> > > > > > --- a/drivers/memory/mtk-smi.c
> > > > > > +++ b/drivers/memory/mtk-smi.c
> > > > > > @@ -597,3 +597,13 @@ static int __init mtk_smi_init(void)
> > > > > > return platform_register_drivers(smidrivers, 
> > > > > > ARRAY_SIZE(smidrivers));
> > > > > >  }
> > > > > >  module_init(mtk_smi_init);
> > > > > > +
> > > > > > +static void __exit mtk_smi_exit(void)
> > > > > > +{
> > > > > > +   platform_unregister_drivers(smidrivers, ARRAY_SIZE(smidrivers));
> > > > > > +}
> > > > > > +module_exit(mtk_smi_exit);
> > > > > > +
> > > > > > +MODULE_DESCRIPTION("MediaTek SMI driver");
> > > > > > +MODULE_ALIAS("platform:MediaTek-SMI");
> > > > > 
> > > > > Drivers do not use capital letters, so I have doubts whether this 
> > > > > alias
> > > > > is correct.
> > > > 
> > > > I didn't care the upper/lower-case. I will change to lower case in next
> > > > time.
> > > 
> > > Then why do you need the alias? The name does not match driver name, so
> > > what's the purpose of this alias/
> > 
> > I think it is not so necessary for us. I will delete this line in next
> > version.
> > 
> > Only curious what's alias is fit in our case? normally it should be the
> > file name: mtk-smi?
> 
> If autoloading of your module works, then remove it. The alias is
> necessary for some cases when a device table is missing (e.g. platform
> driver is matched via devicetree but not having the platform_device_id
> table) or matching is done via different method (e.g. driver is matched
> from MFD via devicetree compatible even though there is a
> platform_device_id table).

Thanks for explaination so detailly. v2 is sent just now.

> 
> Best regards,
> Krzysztof



Re: [PATCH 2/3] memory: mtk-smi: Add module_exit and module_license

2021-01-25 Thread Yong Wu
On Mon, 2021-01-25 at 09:40 +0100, Krzysztof Kozlowski wrote:
> On Mon, Jan 25, 2021 at 02:49:41PM +0800, Yong Wu wrote:
> > On Fri, 2021-01-22 at 22:34 +0100, Krzysztof Kozlowski wrote:
> > > On Thu, Jan 21, 2021 at 02:24:28PM +0800, Yong Wu wrote:
> > > > The config MTK_SMI always depends on MTK_IOMMU which is built-in
> > > > currently. Thus we don't have module_exit before. This patch adds
> > > > module_exit and module_license. It is a preparing patch for supporting
> > > > MTK_SMI could been built as a module.
> > > > 
> > > > Signed-off-by: Yong Wu 
> > > > ---
> > > >  drivers/memory/mtk-smi.c | 10 ++
> > > >  1 file changed, 10 insertions(+)
> > > > 
> > > > diff --git a/drivers/memory/mtk-smi.c b/drivers/memory/mtk-smi.c
> > > > index e2aebd2bfa8e..aa2a25abf04f 100644
> > > > --- a/drivers/memory/mtk-smi.c
> > > > +++ b/drivers/memory/mtk-smi.c
> > > > @@ -597,3 +597,13 @@ static int __init mtk_smi_init(void)
> > > > return platform_register_drivers(smidrivers, 
> > > > ARRAY_SIZE(smidrivers));
> > > >  }
> > > >  module_init(mtk_smi_init);
> > > > +
> > > > +static void __exit mtk_smi_exit(void)
> > > > +{
> > > > +   platform_unregister_drivers(smidrivers, ARRAY_SIZE(smidrivers));
> > > > +}
> > > > +module_exit(mtk_smi_exit);
> > > > +
> > > > +MODULE_DESCRIPTION("MediaTek SMI driver");
> > > > +MODULE_ALIAS("platform:MediaTek-SMI");
> > > 
> > > Drivers do not use capital letters, so I have doubts whether this alias
> > > is correct.
> > 
> > I didn't care the upper/lower-case. I will change to lower case in next
> > time.
> 
> Then why do you need the alias? The name does not match driver name, so
> what's the purpose of this alias/

I think it is not so necessary for us. I will delete this line in next
version.

Only curious what's alias is fit in our case? normally it should be the
file name: mtk-smi?

> 
> > 
> > MODULE_ALIAS("platform:MediaTek-smi")
> > 
> > > 
> > > Adding all these should be squashed with changing Kconfig into tristate.
> > > It does not have sense on its own.
> > 
> > Thanks  very much for review.
> > 
> > Only confirm: Squash whole this patch or only squash the MODULE_x into
> > the next patch?
> 
> This entire patch 2/3 should be with 3/3.

Thanks for the confirm.

> 
> Best regards,
> Krzysztof



Re: [PATCH v5 06/27] dt-bindings: mediatek: Add binding for mt8192 IOMMU

2021-01-24 Thread Yong Wu
On Mon, 2021-01-25 at 13:18 +0900, Tomasz Figa wrote:
> On Wed, Jan 20, 2021 at 4:08 PM Yong Wu  wrote:
> >
> > On Wed, 2021-01-20 at 13:15 +0900, Tomasz Figa wrote:
> > > On Wed, Jan 13, 2021 at 3:45 PM Yong Wu  wrote:
> > > >
> > > > On Wed, 2021-01-13 at 14:30 +0900, Tomasz Figa wrote:
> > > > > On Thu, Dec 24, 2020 at 8:35 PM Yong Wu  wrote:
> > > > > >
> > > > > > On Wed, 2020-12-23 at 17:18 +0900, Tomasz Figa wrote:
> > > > > > > On Wed, Dec 09, 2020 at 04:00:41PM +0800, Yong Wu wrote:
> > > > > > > > This patch adds decriptions for mt8192 IOMMU and SMI.
> > > > > > > >
> > > > > > > > mt8192 also is MTK IOMMU gen2 which uses ARM Short-Descriptor 
> > > > > > > > translation
> > > > > > > > table format. The M4U-SMI HW diagram is as below:
> > > > > > > >
> > > > > > > >   EMI
> > > > > > > >|
> > > > > > > >   M4U
> > > > > > > >|
> > > > > > > >   
> > > > > > > >SMI Common
> > > > > > > >   
> > > > > > > >|
> > > > > > > >   +---+--+--+--+---+
> > > > > > > >   |   |  |  |   .. |   |
> > > > > > > >   |   |  |  |  |   |
> > > > > > > > larb0   larb1  larb2  larb4 ..  larb19   larb20
> > > > > > > > disp0   disp1   mdpvdec   IPE  IPE
> > > > > > > >
> > > > > > > > All the connections are HW fixed, SW can NOT adjust it.
> > > > > > > >
> > > > > > > > mt8192 M4U support 0~16GB iova range. we preassign different 
> > > > > > > > engines
> > > > > > > > into different iova ranges:
> > > > > > > >
> > > > > > > > domain-id  module iova-range  larbs
> > > > > > > >0   disp0 ~ 4G  larb0/1
> > > > > > > >1   vcodec  4G ~ 8G larb4/5/7
> > > > > > > >2   cam/mdp 8G ~ 12G 
> > > > > > > > larb2/9/11/13/14/16/17/18/19/20
> > > > > > >
> > > > > > > Why do we preassign these addresses in DT? Shouldn't it be a 
> > > > > > > user's or
> > > > > > > integrator's decision to split the 16 GB address range into 
> > > > > > > sub-ranges
> > > > > > > and define which larbs those sub-ranges are shared with?
> > > > > >
> > > > > > The problem is that we can't split the 16GB range with the larb as 
> > > > > > unit.
> > > > > > The example is the below ccu0(larb13 port9/10) is a independent
> > > > > > range(domain), the others ports in larb13 is in another domain.
> > > > > >
> > > > > > disp/vcodec/cam/mdp don't have special iova requirement, they could
> > > > > > access any range. vcodec also can locate 8G~12G. it don't care about
> > > > > > where its iova locate. here I preassign like this following with our
> > > > > > internal project setting.
> > > > >
> > > > > Let me try to understand this a bit more. Given the split you're
> > > > > proposing, is there actually any isolation enforced between particular
> > > > > domains? For example, if I program vcodec to with a DMA address from
> > > > > the 0-4G range, would the IOMMU actually generate a fault, even if
> > > > > disp had some memory mapped at that address?
> > > >
> > > > In this case. we will get fault in current SW setting.
> > > >
> > >
> > > Okay, thanks.
> > >
> > > > >
> > > > > >
> > > > > > Why set this in DT?, this is only for simplifying the code. Assume 
> > > > > > we
> > > > > > put it in 

Re: [PATCH 2/3] memory: mtk-smi: Add module_exit and module_license

2021-01-24 Thread Yong Wu
On Fri, 2021-01-22 at 22:34 +0100, Krzysztof Kozlowski wrote:
> On Thu, Jan 21, 2021 at 02:24:28PM +0800, Yong Wu wrote:
> > The config MTK_SMI always depends on MTK_IOMMU which is built-in
> > currently. Thus we don't have module_exit before. This patch adds
> > module_exit and module_license. It is a preparing patch for supporting
> > MTK_SMI could been built as a module.
> > 
> > Signed-off-by: Yong Wu 
> > ---
> >  drivers/memory/mtk-smi.c | 10 ++
> >  1 file changed, 10 insertions(+)
> > 
> > diff --git a/drivers/memory/mtk-smi.c b/drivers/memory/mtk-smi.c
> > index e2aebd2bfa8e..aa2a25abf04f 100644
> > --- a/drivers/memory/mtk-smi.c
> > +++ b/drivers/memory/mtk-smi.c
> > @@ -597,3 +597,13 @@ static int __init mtk_smi_init(void)
> > return platform_register_drivers(smidrivers, ARRAY_SIZE(smidrivers));
> >  }
> >  module_init(mtk_smi_init);
> > +
> > +static void __exit mtk_smi_exit(void)
> > +{
> > +   platform_unregister_drivers(smidrivers, ARRAY_SIZE(smidrivers));
> > +}
> > +module_exit(mtk_smi_exit);
> > +
> > +MODULE_DESCRIPTION("MediaTek SMI driver");
> > +MODULE_ALIAS("platform:MediaTek-SMI");
> 
> Drivers do not use capital letters, so I have doubts whether this alias
> is correct.

I didn't care the upper/lower-case. I will change to lower case in next
time.

MODULE_ALIAS("platform:MediaTek-smi")

> 
> Adding all these should be squashed with changing Kconfig into tristate.
> It does not have sense on its own.

Thanks  very much for review.

Only confirm: Squash whole this patch or only squash the MODULE_x into
the next patch?

> 
> Best regards,
> Krzysztof



Re: [PATCH 3/3] memory: mtk-smi: Switch MTK_SMI to tristate

2021-01-24 Thread Yong Wu
On Fri, 2021-01-22 at 22:35 +0100, Krzysztof Kozlowski wrote:
> On Thu, Jan 21, 2021 at 02:24:29PM +0800, Yong Wu wrote:
> > This patch switches MTK_SMI to tristate. Support it could be 'm'.
> > 
> > Meanwhile, Fix a build issue while MTK_SMI is built as module.
> 
> s/Fix/fix.
> 
> What error is being fixed here? How can I reproduce it? Aren't you just
> adjusting it to being buildable by module?

Sorry, I didn't copy the fail log here. This is the build log:

In file included from .../drivers/iommu/mtk_iommu.c:34:0:
.../drivers/iommu/mtk_iommu.h:84:28: error: array type has incomplete
element type 'struct mtk_smi_larb_iommu'
  struct mtk_smi_larb_iommu larb_imu[MTK_LARB_NR_MAX];

Our iommu driver will use this structure. but it was contained by
"#ifdef CONFIG_MTK_SMI". thus I change it to "#if
IS_ENABLED(CONFIG_MTK_SMI)"

If reproducing it, we should change mtk-iommu to module_init[1]. and
switch kconfig MTK_IOMMU to tristate, then change the CONFIG_MTK_IOMMU
to m. we could get the fail log.

In this case, Should I squash this change into this patch? I though this
is a preparing patch and the fail is caused by MTK_SMI. thus I squash
that into this patch. or change it as a independent patch and send when
I change MTK_IOMMU to tristate?

[1]
https://lore.kernel.org/linux-mediatek/1590826218-23653-14-git-send-email-yong...@mediatek.com/


> 
> Best regards,
> Krzysztof
> 
> 
> > 
> > Signed-off-by: Yong Wu 
> > ---
> > This patch has a little conflict with the mt8192 iommu patch which
> > delete the MTK_LARB_NR_MAX in smi.h(It's still reviewing).
> > This patch rebase on the clean v5.11-rc1.
> > ---
> >  drivers/memory/Kconfig | 2 +-
> >  include/soc/mediatek/smi.h | 2 +-
> >  2 files changed, 2 insertions(+), 2 deletions(-)
> > 
> > diff --git a/drivers/memory/Kconfig b/drivers/memory/Kconfig
> > index 3ea6913df176..d5f0f4680880 100644
> > --- a/drivers/memory/Kconfig
> > +++ b/drivers/memory/Kconfig
> > @@ -173,7 +173,7 @@ config JZ4780_NEMC
> >   memory devices such as NAND and SRAM.
> >  
> >  config MTK_SMI
> > -   bool "Mediatek SoC Memory Controller driver" if COMPILE_TEST
> > +   tristate "Mediatek SoC Memory Controller driver" if COMPILE_TEST
> > depends on ARCH_MEDIATEK || COMPILE_TEST
> > help
> >   This driver is for the Memory Controller module in MediaTek SoCs,
> > diff --git a/include/soc/mediatek/smi.h b/include/soc/mediatek/smi.h
> > index 5a34b87d89e3..29e2fb8f33d6 100644
> > --- a/include/soc/mediatek/smi.h
> > +++ b/include/soc/mediatek/smi.h
> > @@ -9,7 +9,7 @@
> >  #include 
> >  #include 
> >  
> > -#ifdef CONFIG_MTK_SMI
> > +#if IS_ENABLED(CONFIG_MTK_SMI)



[PATCH 3/3] memory: mtk-smi: Switch MTK_SMI to tristate

2021-01-20 Thread Yong Wu
This patch switches MTK_SMI to tristate. Support it could be 'm'.

Meanwhile, Fix a build issue while MTK_SMI is built as module.

Signed-off-by: Yong Wu 
---
This patch has a little conflict with the mt8192 iommu patch which
delete the MTK_LARB_NR_MAX in smi.h(It's still reviewing).
This patch rebase on the clean v5.11-rc1.
---
 drivers/memory/Kconfig | 2 +-
 include/soc/mediatek/smi.h | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/memory/Kconfig b/drivers/memory/Kconfig
index 3ea6913df176..d5f0f4680880 100644
--- a/drivers/memory/Kconfig
+++ b/drivers/memory/Kconfig
@@ -173,7 +173,7 @@ config JZ4780_NEMC
  memory devices such as NAND and SRAM.
 
 config MTK_SMI
-   bool "Mediatek SoC Memory Controller driver" if COMPILE_TEST
+   tristate "Mediatek SoC Memory Controller driver" if COMPILE_TEST
depends on ARCH_MEDIATEK || COMPILE_TEST
help
  This driver is for the Memory Controller module in MediaTek SoCs,
diff --git a/include/soc/mediatek/smi.h b/include/soc/mediatek/smi.h
index 5a34b87d89e3..29e2fb8f33d6 100644
--- a/include/soc/mediatek/smi.h
+++ b/include/soc/mediatek/smi.h
@@ -9,7 +9,7 @@
 #include 
 #include 
 
-#ifdef CONFIG_MTK_SMI
+#if IS_ENABLED(CONFIG_MTK_SMI)
 
 #define MTK_LARB_NR_MAX16
 
-- 
2.18.0



[PATCH 2/3] memory: mtk-smi: Add module_exit and module_license

2021-01-20 Thread Yong Wu
The config MTK_SMI always depends on MTK_IOMMU which is built-in
currently. Thus we don't have module_exit before. This patch adds
module_exit and module_license. It is a preparing patch for supporting
MTK_SMI could been built as a module.

Signed-off-by: Yong Wu 
---
 drivers/memory/mtk-smi.c | 10 ++
 1 file changed, 10 insertions(+)

diff --git a/drivers/memory/mtk-smi.c b/drivers/memory/mtk-smi.c
index e2aebd2bfa8e..aa2a25abf04f 100644
--- a/drivers/memory/mtk-smi.c
+++ b/drivers/memory/mtk-smi.c
@@ -597,3 +597,13 @@ static int __init mtk_smi_init(void)
return platform_register_drivers(smidrivers, ARRAY_SIZE(smidrivers));
 }
 module_init(mtk_smi_init);
+
+static void __exit mtk_smi_exit(void)
+{
+   platform_unregister_drivers(smidrivers, ARRAY_SIZE(smidrivers));
+}
+module_exit(mtk_smi_exit);
+
+MODULE_DESCRIPTION("MediaTek SMI driver");
+MODULE_ALIAS("platform:MediaTek-SMI");
+MODULE_LICENSE("GPL v2");
-- 
2.18.0



[PATCH 1/3] memory: mtk-smi: Use platform_register_drivers

2021-01-20 Thread Yong Wu
In this file, we have 2 drivers, smi-common and smi-larb.
Use platform_register_drivers.

Signed-off-by: Yong Wu 
---
 drivers/memory/mtk-smi.c | 25 ++---
 1 file changed, 6 insertions(+), 19 deletions(-)

diff --git a/drivers/memory/mtk-smi.c b/drivers/memory/mtk-smi.c
index ac350f8d1e20..e2aebd2bfa8e 100644
--- a/drivers/memory/mtk-smi.c
+++ b/drivers/memory/mtk-smi.c
@@ -587,26 +587,13 @@ static struct platform_driver mtk_smi_common_driver = {
}
 };
 
+static struct platform_driver * const smidrivers[] = {
+   _smi_common_driver,
+   _smi_larb_driver,
+};
+
 static int __init mtk_smi_init(void)
 {
-   int ret;
-
-   ret = platform_driver_register(_smi_common_driver);
-   if (ret != 0) {
-   pr_err("Failed to register SMI driver\n");
-   return ret;
-   }
-
-   ret = platform_driver_register(_smi_larb_driver);
-   if (ret != 0) {
-   pr_err("Failed to register SMI-LARB driver\n");
-   goto err_unreg_smi;
-   }
-   return ret;
-
-err_unreg_smi:
-   platform_driver_unregister(_smi_common_driver);
-   return ret;
+   return platform_register_drivers(smidrivers, ARRAY_SIZE(smidrivers));
 }
-
 module_init(mtk_smi_init);
-- 
2.18.0



Support MTK_SMI modular

2021-01-20 Thread Yong Wu
This patchset mainly support MTK_SMI could be modular. No other function add.
The MTK_IOMMU config will be another patchset.

rebase on v5.11-rc1.

Yong Wu (3):
  memory: mtk-smi: Use platform_register_drivers
  memory: mtk-smi: Add module_exit and module_license
  memory: mtk-smi: Switch MTK_SMI to tristate

 drivers/memory/Kconfig |  2 +-
 drivers/memory/mtk-smi.c   | 33 +++--
 include/soc/mediatek/smi.h |  2 +-
 3 files changed, 17 insertions(+), 20 deletions(-)

-- 
2.18.0




Re: [PATCH v5 06/27] dt-bindings: mediatek: Add binding for mt8192 IOMMU

2021-01-19 Thread Yong Wu
On Wed, 2021-01-20 at 13:15 +0900, Tomasz Figa wrote:
> On Wed, Jan 13, 2021 at 3:45 PM Yong Wu  wrote:
> >
> > On Wed, 2021-01-13 at 14:30 +0900, Tomasz Figa wrote:
> > > On Thu, Dec 24, 2020 at 8:35 PM Yong Wu  wrote:
> > > >
> > > > On Wed, 2020-12-23 at 17:18 +0900, Tomasz Figa wrote:
> > > > > On Wed, Dec 09, 2020 at 04:00:41PM +0800, Yong Wu wrote:
> > > > > > This patch adds decriptions for mt8192 IOMMU and SMI.
> > > > > >
> > > > > > mt8192 also is MTK IOMMU gen2 which uses ARM Short-Descriptor 
> > > > > > translation
> > > > > > table format. The M4U-SMI HW diagram is as below:
> > > > > >
> > > > > >   EMI
> > > > > >|
> > > > > >   M4U
> > > > > >|
> > > > > >   
> > > > > >SMI Common
> > > > > >   
> > > > > >|
> > > > > >   +---+--+--+--+---+
> > > > > >   |   |  |  |   .. |   |
> > > > > >   |   |  |  |  |   |
> > > > > > larb0   larb1  larb2  larb4 ..  larb19   larb20
> > > > > > disp0   disp1   mdpvdec   IPE  IPE
> > > > > >
> > > > > > All the connections are HW fixed, SW can NOT adjust it.
> > > > > >
> > > > > > mt8192 M4U support 0~16GB iova range. we preassign different engines
> > > > > > into different iova ranges:
> > > > > >
> > > > > > domain-id  module iova-range  larbs
> > > > > >0   disp0 ~ 4G  larb0/1
> > > > > >1   vcodec  4G ~ 8G larb4/5/7
> > > > > >2   cam/mdp 8G ~ 12G 
> > > > > > larb2/9/11/13/14/16/17/18/19/20
> > > > >
> > > > > Why do we preassign these addresses in DT? Shouldn't it be a user's or
> > > > > integrator's decision to split the 16 GB address range into sub-ranges
> > > > > and define which larbs those sub-ranges are shared with?
> > > >
> > > > The problem is that we can't split the 16GB range with the larb as unit.
> > > > The example is the below ccu0(larb13 port9/10) is a independent
> > > > range(domain), the others ports in larb13 is in another domain.
> > > >
> > > > disp/vcodec/cam/mdp don't have special iova requirement, they could
> > > > access any range. vcodec also can locate 8G~12G. it don't care about
> > > > where its iova locate. here I preassign like this following with our
> > > > internal project setting.
> > >
> > > Let me try to understand this a bit more. Given the split you're
> > > proposing, is there actually any isolation enforced between particular
> > > domains? For example, if I program vcodec to with a DMA address from
> > > the 0-4G range, would the IOMMU actually generate a fault, even if
> > > disp had some memory mapped at that address?
> >
> > In this case. we will get fault in current SW setting.
> >
> 
> Okay, thanks.
> 
> > >
> > > >
> > > > Why set this in DT?, this is only for simplifying the code. Assume we
> > > > put it in the platform data. We have up to 32 larbs, each larb has up to
> > > > 32 ports, each port may be in different iommu domains. we should have a
> > > > big array for this..however we only use a macro to get the domain in the
> > > > DT method.
> > > >
> > > > When replying this mail, I happen to see there is a "dev->dev_range_map"
> > > > which has "dma-range" information, I think I could use this value to get
> > > > which domain the device belong to. then no need put domid in DT. I will
> > > > test this.
> > >
> > > My feeling is that the only part that needs to be enforced statically
> > > is the reserved IOVA range for CCUs. The other ranges should be
> > > determined dynamically, although I think I need to understand better
> > > how the hardware and your proposed design wo

[PATCH v2] of/device: Update dma_range_map only when dev has valid dma-ranges

2021-01-19 Thread Yong Wu
The commit e0d072782c73 ("dma-mapping: introduce DMA range map,
supplanting dma_pfn_offset") always update dma_range_map even though it was
already set, like in the sunxi_mbus driver. the issue is reported at [1].
This patch avoid this(Updating it only when dev has valid dma-ranges).

Meanwhile, dma_range_map contains the devices' dma_ranges information,
This patch moves dma_range_map before of_iommu_configure. The iommu
driver may need to know the dma_address requirements of its iommu
consumer devices.

[1] 
https://lore.kernel.org/linux-arm-kernel/5c7946f3-b56e-da00-a750-be097c7ce...@arm.com/

CC: Rob Herring 
CC: Frank Rowand 
Fixes: e0d072782c73 ("dma-mapping: introduce DMA range map, supplanting 
dma_pfn_offset"),
Suggested-by: Robin Murphy 
Signed-off-by: Yong Wu 
Signed-off-by: Paul Kocialkowski 
Reviewed-by: Rob Herring 
---
 drivers/of/device.c | 10 +++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/drivers/of/device.c b/drivers/of/device.c
index aedfaaafd3e7..1122daa8e273 100644
--- a/drivers/of/device.c
+++ b/drivers/of/device.c
@@ -162,9 +162,11 @@ int of_dma_configure_id(struct device *dev, struct 
device_node *np,
mask = DMA_BIT_MASK(ilog2(end) + 1);
dev->coherent_dma_mask &= mask;
*dev->dma_mask &= mask;
-   /* ...but only set bus limit if we found valid dma-ranges earlier */
-   if (!ret)
+   /* ...but only set bus limit and range map if we found valid dma-ranges 
earlier */
+   if (!ret) {
dev->bus_dma_limit = end;
+   dev->dma_range_map = map;
+   }
 
coherent = of_dma_is_coherent(np);
dev_dbg(dev, "device is%sdma coherent\n",
@@ -172,6 +174,9 @@ int of_dma_configure_id(struct device *dev, struct 
device_node *np,
 
iommu = of_iommu_configure(dev, np, id);
if (PTR_ERR(iommu) == -EPROBE_DEFER) {
+   /* Don't touch range map if it wasn't set from a valid 
dma-ranges */
+   if (!ret)
+   dev->dma_range_map = NULL;
kfree(map);
return -EPROBE_DEFER;
}
@@ -181,7 +186,6 @@ int of_dma_configure_id(struct device *dev, struct 
device_node *np,
 
arch_setup_dma_ops(dev, dma_start, size, iommu, coherent);
 
-   dev->dma_range_map = map;
return 0;
 }
 EXPORT_SYMBOL_GPL(of_dma_configure_id);
-- 
2.18.0



Re: [PATCH v6 06/33] of/device: Move dma_range_map before of_iommu_configure

2021-01-19 Thread Yong Wu
On Mon, 2021-01-18 at 15:49 +, Robin Murphy wrote:
> On 2021-01-15 05:30, Yong Wu wrote:
> > On Thu, 2021-01-14 at 13:27 -0600, Rob Herring wrote:
> >> On Mon, Jan 11, 2021 at 07:18:47PM +0800, Yong Wu wrote:
> >>> "dev->dma_range_map" contains the devices' dma_ranges information,
> >>> This patch moves dma_range_map before of_iommu_configure. The iommu
> >>> driver may need to know the dma_address requirements of its iommu
> >>> consumer devices.
> >>>
> >>> CC: Rob Herring 
> >>> CC: Frank Rowand 
> >>> Signed-off-by: Yong Wu 
> >>> ---
> >>>   drivers/of/device.c | 3 ++-
> >>>   1 file changed, 2 insertions(+), 1 deletion(-)
> >>>
> >>> diff --git a/drivers/of/device.c b/drivers/of/device.c
> >>> index aedfaaafd3e7..1d84636149df 100644
> >>> --- a/drivers/of/device.c
> >>> +++ b/drivers/of/device.c
> >>> @@ -170,9 +170,11 @@ int of_dma_configure_id(struct device *dev, struct 
> >>> device_node *np,
> >>>   dev_dbg(dev, "device is%sdma coherent\n",
> >>>   coherent ? " " : " not ");
> >>>   
> >>> + dev->dma_range_map = map;
> >>>   iommu = of_iommu_configure(dev, np, id);
> >>>   if (PTR_ERR(iommu) == -EPROBE_DEFER) {
> >>>   kfree(map);
> >>> + dev->dma_range_map = NULL;
> >>
> >> Not really going to matter, but you should probably clear dma_range_map
> >> before what it points to is freed.
> >>
> >> With that,
> >>
> >> Reviewed-by: Rob Herring 
> > 
> > Thanks for the review. I will move it before "kfree(map)" in next
> > version.
> 
> Paul noticed that we already have a bug in assigning to this 
> unconditionally[1] - I'd totally forgotten about this series when I 
> theorised about IOMMU drivers wanting the information earlier, but 
> sweeping my inbox now only goes to show I was right to think of it :)
> 
> We should really get something in as a fix independent of this series, 
> taking both angles into account.

Thanks this info. Following your suggestion, Move this into the "if (!
ret)". Then it is like this:


--- a/drivers/of/device.c
+++ b/drivers/of/device.c
@@ -163,8 +163,10 @@ int of_dma_configure_id(struct device *dev, struct
device_node *np,
dev->coherent_dma_mask &= mask;
*dev->dma_mask &= mask;
/* ...but only set bus limit if we found valid dma-ranges earlier */
-   if (!ret)
+   if (!ret) {
dev->bus_dma_limit = end;
+   dev->dma_range_map = map;
+   }
 
coherent = of_dma_is_coherent(np);
dev_dbg(dev, "device is%sdma coherent\n",
@@ -172,6 +174,8 @@ int of_dma_configure_id(struct device *dev, struct
device_node *np,
 
iommu = of_iommu_configure(dev, np, id);
if (PTR_ERR(iommu) == -EPROBE_DEFER) {
+   if (!ret)
+   dev->dma_range_map = NULL;
kfree(map);
return -EPROBE_DEFER;
}
@@ -181,7 +185,6 @@ int of_dma_configure_id(struct device *dev, struct
device_node *np,
 
arch_setup_dma_ops(dev, dma_start, size, iommu, coherent);
 
-   dev->dma_range_map = map;
return 0;
 }
 EXPORT_SYMBOL_GPL(of_dma_configure_id);


If this is ok, I will send this as a independent patch.

> 
> Robin.
> 
> [1] 
> https://lore.kernel.org/linux-arm-kernel/5c7946f3-b56e-da00-a750-be097c7ce...@arm.com/
> 
> >>
> >>>   return -EPROBE_DEFER;
> >>>   }
> >>>   
> >>> @@ -181,7 +183,6 @@ int of_dma_configure_id(struct device *dev, struct 
> >>> device_node *np,
> >>>   
> >>>   arch_setup_dma_ops(dev, dma_start, size, iommu, coherent);
> >>>   
> >>> - dev->dma_range_map = map;
> >>>   return 0;
> >>>   }
> >>>   EXPORT_SYMBOL_GPL(of_dma_configure_id);
> >>> -- 
> >>> 2.18.0
> >>>
> > 
> > ___
> > iommu mailing list
> > io...@lists.linux-foundation.org
> > https://lists.linuxfoundation.org/mailman/listinfo/iommu
> > 



Re: [PATCH v6 06/33] of/device: Move dma_range_map before of_iommu_configure

2021-01-14 Thread Yong Wu
On Thu, 2021-01-14 at 13:27 -0600, Rob Herring wrote:
> On Mon, Jan 11, 2021 at 07:18:47PM +0800, Yong Wu wrote:
> > "dev->dma_range_map" contains the devices' dma_ranges information,
> > This patch moves dma_range_map before of_iommu_configure. The iommu
> > driver may need to know the dma_address requirements of its iommu
> > consumer devices.
> > 
> > CC: Rob Herring 
> > CC: Frank Rowand 
> > Signed-off-by: Yong Wu 
> > ---
> >  drivers/of/device.c | 3 ++-
> >  1 file changed, 2 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/of/device.c b/drivers/of/device.c
> > index aedfaaafd3e7..1d84636149df 100644
> > --- a/drivers/of/device.c
> > +++ b/drivers/of/device.c
> > @@ -170,9 +170,11 @@ int of_dma_configure_id(struct device *dev, struct 
> > device_node *np,
> > dev_dbg(dev, "device is%sdma coherent\n",
> > coherent ? " " : " not ");
> >  
> > +   dev->dma_range_map = map;
> > iommu = of_iommu_configure(dev, np, id);
> > if (PTR_ERR(iommu) == -EPROBE_DEFER) {
> > kfree(map);
> > +   dev->dma_range_map = NULL;
> 
> Not really going to matter, but you should probably clear dma_range_map 
> before what it points to is freed.
> 
> With that,
> 
> Reviewed-by: Rob Herring 

Thanks for the review. I will move it before "kfree(map)" in next
version.

> 
> > return -EPROBE_DEFER;
> > }
> >  
> > @@ -181,7 +183,6 @@ int of_dma_configure_id(struct device *dev, struct 
> > device_node *np,
> >  
> > arch_setup_dma_ops(dev, dma_start, size, iommu, coherent);
> >  
> > -   dev->dma_range_map = map;
> > return 0;
> >  }
> >  EXPORT_SYMBOL_GPL(of_dma_configure_id);
> > -- 
> > 2.18.0
> > 



Re: [PATCH v5 06/27] dt-bindings: mediatek: Add binding for mt8192 IOMMU

2021-01-12 Thread Yong Wu
On Wed, 2021-01-13 at 14:30 +0900, Tomasz Figa wrote:
> On Thu, Dec 24, 2020 at 8:35 PM Yong Wu  wrote:
> >
> > On Wed, 2020-12-23 at 17:18 +0900, Tomasz Figa wrote:
> > > On Wed, Dec 09, 2020 at 04:00:41PM +0800, Yong Wu wrote:
> > > > This patch adds decriptions for mt8192 IOMMU and SMI.
> > > >
> > > > mt8192 also is MTK IOMMU gen2 which uses ARM Short-Descriptor 
> > > > translation
> > > > table format. The M4U-SMI HW diagram is as below:
> > > >
> > > >   EMI
> > > >|
> > > >   M4U
> > > >|
> > > >   
> > > >SMI Common
> > > >   
> > > >|
> > > >   +---+--+--+--+---+
> > > >   |   |  |  |   .. |   |
> > > >   |   |  |  |  |   |
> > > > larb0   larb1  larb2  larb4 ..  larb19   larb20
> > > > disp0   disp1   mdpvdec   IPE  IPE
> > > >
> > > > All the connections are HW fixed, SW can NOT adjust it.
> > > >
> > > > mt8192 M4U support 0~16GB iova range. we preassign different engines
> > > > into different iova ranges:
> > > >
> > > > domain-id  module iova-range  larbs
> > > >0   disp0 ~ 4G  larb0/1
> > > >1   vcodec  4G ~ 8G larb4/5/7
> > > >2   cam/mdp 8G ~ 12G 
> > > > larb2/9/11/13/14/16/17/18/19/20
> > >
> > > Why do we preassign these addresses in DT? Shouldn't it be a user's or
> > > integrator's decision to split the 16 GB address range into sub-ranges
> > > and define which larbs those sub-ranges are shared with?
> >
> > The problem is that we can't split the 16GB range with the larb as unit.
> > The example is the below ccu0(larb13 port9/10) is a independent
> > range(domain), the others ports in larb13 is in another domain.
> >
> > disp/vcodec/cam/mdp don't have special iova requirement, they could
> > access any range. vcodec also can locate 8G~12G. it don't care about
> > where its iova locate. here I preassign like this following with our
> > internal project setting.
> 
> Let me try to understand this a bit more. Given the split you're
> proposing, is there actually any isolation enforced between particular
> domains? For example, if I program vcodec to with a DMA address from
> the 0-4G range, would the IOMMU actually generate a fault, even if
> disp had some memory mapped at that address?

In this case. we will get fault in current SW setting.

> 
> >
> > Why set this in DT?, this is only for simplifying the code. Assume we
> > put it in the platform data. We have up to 32 larbs, each larb has up to
> > 32 ports, each port may be in different iommu domains. we should have a
> > big array for this..however we only use a macro to get the domain in the
> > DT method.
> >
> > When replying this mail, I happen to see there is a "dev->dev_range_map"
> > which has "dma-range" information, I think I could use this value to get
> > which domain the device belong to. then no need put domid in DT. I will
> > test this.
> 
> My feeling is that the only part that needs to be enforced statically
> is the reserved IOVA range for CCUs. The other ranges should be
> determined dynamically, although I think I need to understand better
> how the hardware and your proposed design work to tell what would be
> likely the best choice here.

I have removed the domid patch in v6. and get the domain id in [27/33]
in v6..

About the other ranges should be dynamical, the commit message [30/33]
of v6 should be helpful. the problem is that we have a bank_sel setting
for the iova[32:33]. currently we preassign this value. thus, all the
ranges are fixed. If you adjust this setting, you can let vcodec access
0~4G.

Currently we have no interface to adjust this setting. Suppose we add a
new interface for this. It would be something like:

   int mtk_smi_larb_config_banksel(struct device *larb, int banksel)
  
   Then, all the MM drivers should call it before the HW works every
time, and its implement will be a bit complex since we aren't sure if
the larb has power at that time. the important thing is that the MM
devices have already not known which larb it con

[PATCH v6 30/33] iommu/mediatek: Support master use iova over 32bit

2021-01-11 Thread Yong Wu
After extending v7s, our pagetable already support iova reach
16GB(34bit). the master got the iova via dma_alloc_attrs may reach
34bits, but its HW register still is 32bit. then how to set the
bit32/bit33 iova? this depend on a SMI larb setting(bank_sel).

we separate whole 16GB iova to four banks:
bank: 0: 0~4G; 1: 4~8G; 2: 8-12G; 3: 12-16G;
The bank number is (iova >> 32).

We will preassign which bank the larbs belong to. currently we don't
have a interface for master to adjust its bank number.

Each a bank is a iova_region which is a independent iommu-domain.
the iova range for each iommu-domain can't cross 4G.

Signed-off-by: Yong Wu 
Acked-by: Krzysztof Kozlowski  #for memory part
---
 drivers/iommu/mtk_iommu.c  | 18 --
 drivers/memory/mtk-smi.c   |  7 +++
 include/soc/mediatek/smi.h |  1 +
 3 files changed, 20 insertions(+), 6 deletions(-)

diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index 764dc0b93477..7403a7cb90ea 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -345,21 +345,27 @@ static int mtk_iommu_get_domain_id(struct device *dev,
return -EINVAL;
 }
 
-static void mtk_iommu_config(struct mtk_iommu_data *data,
-struct device *dev, bool enable)
+static void mtk_iommu_config(struct mtk_iommu_data *data, struct device *dev,
+bool enable, unsigned int domid)
 {
struct mtk_smi_larb_iommu*larb_mmu;
unsigned int larbid, portid;
struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
+   const struct mtk_iommu_iova_region *region;
int i;
 
for (i = 0; i < fwspec->num_ids; ++i) {
larbid = MTK_M4U_TO_LARB(fwspec->ids[i]);
portid = MTK_M4U_TO_PORT(fwspec->ids[i]);
+
larb_mmu = >larb_imu[larbid];
 
-   dev_dbg(dev, "%s iommu port: %d\n",
-   enable ? "enable" : "disable", portid);
+   region = data->plat_data->iova_region + domid;
+   larb_mmu->bank[portid] = upper_32_bits(region->iova_base);
+
+   dev_dbg(dev, "%s iommu for larb(%s) port %d dom %d bank %d.\n",
+   enable ? "enable" : "disable", dev_name(larb_mmu->dev),
+   portid, domid, larb_mmu->bank[portid]);
 
if (enable)
larb_mmu->mmu |= MTK_SMI_MMU_EN(portid);
@@ -477,7 +483,7 @@ static int mtk_iommu_attach_device(struct iommu_domain 
*domain,
pm_runtime_put(m4udev);
}
 
-   mtk_iommu_config(data, dev, true);
+   mtk_iommu_config(data, dev, true, domid);
return 0;
 }
 
@@ -489,7 +495,7 @@ static void mtk_iommu_detach_device(struct iommu_domain 
*domain,
if (!data)
return;
 
-   mtk_iommu_config(data, dev, false);
+   mtk_iommu_config(data, dev, false, 0);
 }
 
 static int mtk_iommu_map(struct iommu_domain *domain, unsigned long iova,
diff --git a/drivers/memory/mtk-smi.c b/drivers/memory/mtk-smi.c
index 89f92fa2afa5..fae61c5fbd70 100644
--- a/drivers/memory/mtk-smi.c
+++ b/drivers/memory/mtk-smi.c
@@ -44,6 +44,10 @@
 /* mt2712 */
 #define SMI_LARB_NONSEC_CON(id)(0x380 + ((id) * 4))
 #define F_MMU_EN   BIT(0)
+#define BANK_SEL(id)   ({  \
+   u32 _id = (id) & 0x3;   \
+   (_id << 8 | _id << 10 | _id << 12 | _id << 14); \
+})
 
 /* SMI COMMON */
 #define SMI_BUS_SEL0x220
@@ -88,6 +92,7 @@ struct mtk_smi_larb { /* larb: local arbiter */
const struct mtk_smi_larb_gen   *larb_gen;
int larbid;
u32 *mmu;
+   unsigned char   *bank;
 };
 
 static int mtk_smi_clk_enable(const struct mtk_smi *smi)
@@ -154,6 +159,7 @@ mtk_smi_larb_bind(struct device *dev, struct device 
*master, void *data)
if (dev == larb_mmu[i].dev) {
larb->larbid = i;
larb->mmu = _mmu[i].mmu;
+   larb->bank = larb_mmu[i].bank;
return 0;
}
}
@@ -172,6 +178,7 @@ static void mtk_smi_larb_config_port_gen2_general(struct 
device *dev)
for_each_set_bit(i, (unsigned long *)larb->mmu, 32) {
reg = readl_relaxed(larb->base + SMI_LARB_NONSEC_CON(i));
reg |= F_MMU_EN;
+   reg |= BANK_SEL(larb->bank[i]);
writel(reg, larb->base + SMI_LARB_NONSEC_CON(i));
}
 }
diff --git a/include/soc/mediatek/smi.h b/include/soc/mediatek/smi.h
index 9371bf572ab8..4cf445dbbdaa 100644
--- a/include/soc/mediatek/smi.h
+++ b/include/soc/mediatek/smi.h
@@ -16,6 +16,7 @@
 struct mtk_smi_larb_iommu {
struct device *dev;
unsigned int   mmu;
+   unsigned char  bank[32];
 };
 
 /*
-- 
2.18.0



[PATCH v6 33/33] MAINTAINERS: Add entry for MediaTek IOMMU

2021-01-11 Thread Yong Wu
I am the author of MediaTek iommu driver, and will to maintain and
develop it further.
Add myself to cover these items.

Signed-off-by: Yong Wu 
Reviewed-by: Chun-Kuang Hu 
---
 MAINTAINERS | 9 +
 1 file changed, 9 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 546aa66428c9..35bc20398139 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -11182,6 +11182,15 @@ S: Maintained
 F: Documentation/devicetree/bindings/i2c/i2c-mt65xx.txt
 F: drivers/i2c/busses/i2c-mt65xx.c
 
+MEDIATEK IOMMU DRIVER
+M: Yong Wu 
+L: io...@lists.linux-foundation.org
+L: linux-media...@lists.infradead.org (moderated for non-subscribers)
+S: Supported
+F: Documentation/devicetree/bindings/iommu/mediatek*
+F: drivers/iommu/mtk-iommu*
+F: include/dt-bindings/memory/mt*-port.h
+
 MEDIATEK JPEG DRIVER
 M: Rick Chang 
 M: Bin Liu 
-- 
2.18.0



[PATCH v6 32/33] iommu/mediatek: Add mt8192 support

2021-01-11 Thread Yong Wu
Add mt8192 iommu support.

Signed-off-by: Yong Wu 
---
 drivers/iommu/mtk_iommu.c | 22 ++
 drivers/iommu/mtk_iommu.h |  1 +
 2 files changed, 23 insertions(+)

diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index 084fb4394ffc..0ad14a7604b1 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -177,6 +177,16 @@ static const struct mtk_iommu_iova_region single_domain[] 
= {
{.iova_base = 0,.size = SZ_4G},
 };
 
+static const struct mtk_iommu_iova_region mt8192_multi_dom[] = {
+   { .iova_base = 0x0, .size = SZ_4G}, /* disp: 0 ~ 4G 
*/
+   #if IS_ENABLED(CONFIG_ARCH_DMA_ADDR_T_64BIT)
+   { .iova_base = SZ_4G,   .size = SZ_4G}, /* vdec: 4G ~ 
8G */
+   { .iova_base = SZ_4G * 2,   .size = SZ_4G}, /* CAM/MDP: 8G 
~ 12G */
+   { .iova_base = 0x24000ULL,  .size = 0x400}, /* CCU0 */
+   { .iova_base = 0x24400ULL,  .size = 0x400}, /* CCU1 */
+   #endif
+};
+
 /*
  * There may be 1 or 2 M4U HWs, But we always expect they are in the same 
domain
  * for the performance.
@@ -1038,12 +1048,24 @@ static const struct mtk_iommu_plat_data mt8183_data = {
.larbid_remap = {{0}, {4}, {5}, {6}, {7}, {2}, {3}, {1}},
 };
 
+static const struct mtk_iommu_plat_data mt8192_data = {
+   .m4u_plat   = M4U_MT8192,
+   .flags  = HAS_BCLK | HAS_SUB_COMM | OUT_ORDER_WR_EN |
+ WR_THROT_EN | IOVA_34_EN,
+   .inv_sel_reg= REG_MMU_INV_SEL_GEN2,
+   .iova_region= mt8192_multi_dom,
+   .iova_region_nr = ARRAY_SIZE(mt8192_multi_dom),
+   .larbid_remap   = {{0}, {1}, {4, 5}, {7}, {2}, {9, 11, 19, 20},
+  {0, 14, 16}, {0, 13, 18, 17}},
+};
+
 static const struct of_device_id mtk_iommu_of_ids[] = {
{ .compatible = "mediatek,mt2712-m4u", .data = _data},
{ .compatible = "mediatek,mt6779-m4u", .data = _data},
{ .compatible = "mediatek,mt8167-m4u", .data = _data},
{ .compatible = "mediatek,mt8173-m4u", .data = _data},
{ .compatible = "mediatek,mt8183-m4u", .data = _data},
+   { .compatible = "mediatek,mt8192-m4u", .data = _data},
{}
 };
 
diff --git a/drivers/iommu/mtk_iommu.h b/drivers/iommu/mtk_iommu.h
index 6f2168e3222d..f81fa8862ed0 100644
--- a/drivers/iommu/mtk_iommu.h
+++ b/drivers/iommu/mtk_iommu.h
@@ -45,6 +45,7 @@ enum mtk_iommu_plat {
M4U_MT8167,
M4U_MT8173,
M4U_MT8183,
+   M4U_MT8192,
 };
 
 struct mtk_iommu_iova_region;
-- 
2.18.0



[PATCH v6 29/33] iommu/mediatek: Add iova reserved function

2021-01-11 Thread Yong Wu
For multiple iommu_domains, we need to reserve some iova regions. Take a
example, If the default iova region is 0 ~ 4G, but the 0x4000_ ~
0x43ff_ is only for the special CCU0 domain. Thus we should exclude
this region for the default iova region.

Signed-off-by: Anan sun 
Signed-off-by: Chao Hao 
Signed-off-by: Yong Wu 
---
 drivers/iommu/mtk_iommu.c | 31 +++
 1 file changed, 31 insertions(+)

diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index b42fd2535b77..764dc0b93477 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -626,6 +626,35 @@ static int mtk_iommu_of_xlate(struct device *dev, struct 
of_phandle_args *args)
return iommu_fwspec_add_ids(dev, args->args, 1);
 }
 
+static void mtk_iommu_get_resv_regions(struct device *dev,
+  struct list_head *head)
+{
+   struct mtk_iommu_data *data = dev_iommu_priv_get(dev);
+   unsigned int domid = mtk_iommu_get_domain_id(dev, data->plat_data), i;
+   const struct mtk_iommu_iova_region *resv, *curdom;
+   struct iommu_resv_region *region;
+   int prot = IOMMU_WRITE | IOMMU_READ;
+
+   if (domid < 0)
+   return;
+   curdom = data->plat_data->iova_region + domid;
+   for (i = 0; i < data->plat_data->iova_region_nr; i++) {
+   resv = data->plat_data->iova_region + i;
+
+   /* Only reserve when the region is inside the current domain */
+   if (resv->iova_base <= curdom->iova_base ||
+   resv->iova_base + resv->size >= curdom->iova_base + 
curdom->size)
+   continue;
+
+   region = iommu_alloc_resv_region(resv->iova_base, resv->size,
+prot, IOMMU_RESV_RESERVED);
+   if (!region)
+   return;
+
+   list_add_tail(>list, head);
+   }
+}
+
 static const struct iommu_ops mtk_iommu_ops = {
.domain_alloc   = mtk_iommu_domain_alloc,
.domain_free= mtk_iommu_domain_free,
@@ -641,6 +670,8 @@ static const struct iommu_ops mtk_iommu_ops = {
.release_device = mtk_iommu_release_device,
.device_group   = mtk_iommu_device_group,
.of_xlate   = mtk_iommu_of_xlate,
+   .get_resv_regions = mtk_iommu_get_resv_regions,
+   .put_resv_regions = generic_iommu_put_resv_regions,
.pgsize_bitmap  = SZ_4K | SZ_64K | SZ_1M | SZ_16M,
 };
 
-- 
2.18.0



[PATCH v6 31/33] iommu/mediatek: Remove unnecessary check in attach_device

2021-01-11 Thread Yong Wu
This priv_data is set in the of_xlate. if of_xlate failed, it should
not enter attach_device. remove the unnecessary check.

Signed-off-by: Yong Wu 
---
 drivers/iommu/mtk_iommu.c | 6 --
 1 file changed, 6 deletions(-)

diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index 7403a7cb90ea..084fb4394ffc 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -453,9 +453,6 @@ static int mtk_iommu_attach_device(struct iommu_domain 
*domain,
struct device *m4udev = data->dev;
int ret, domid;
 
-   if (!data)
-   return -ENODEV;
-
domid = mtk_iommu_get_domain_id(dev, data->plat_data);
if (domid < 0)
return domid;
@@ -492,9 +489,6 @@ static void mtk_iommu_detach_device(struct iommu_domain 
*domain,
 {
struct mtk_iommu_data *data = dev_iommu_priv_get(dev);
 
-   if (!data)
-   return;
-
mtk_iommu_config(data, dev, false, 0);
 }
 
-- 
2.18.0



[PATCH v6 24/33] iommu/mediatek: Move domain_finalise into attach_device

2021-01-11 Thread Yong Wu
Currently domain_alloc only has a parameter(type), We have no chance to
input some special data. This patch moves the domain_finalise into
attach_device which has the device information, then could update
the domain's geometry.aperture ranges for each a device.

Strictly, I should use the data from mtk_iommu_get_m4u_data as the
parameter of mtk_iommu_domain_finalise in this patch. but dom->data
only is used in tlb ops in which the data is get from the m4u_list, thus
it is ok here.

Signed-off-by: Yong Wu 
---
 drivers/iommu/mtk_iommu.c | 31 ---
 1 file changed, 12 insertions(+), 19 deletions(-)

diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index f1941608ccb7..d321d09ac4c2 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -328,10 +328,9 @@ static void mtk_iommu_config(struct mtk_iommu_data *data,
}
 }
 
-static int mtk_iommu_domain_finalise(struct mtk_iommu_domain *dom)
+static int mtk_iommu_domain_finalise(struct mtk_iommu_domain *dom,
+struct mtk_iommu_data *data)
 {
-   struct mtk_iommu_data *data = mtk_iommu_get_m4u_data();
-
dom->cfg = (struct io_pgtable_cfg) {
.quirks = IO_PGTABLE_QUIRK_ARM_NS |
IO_PGTABLE_QUIRK_NO_PERMS |
@@ -352,7 +351,6 @@ static int mtk_iommu_domain_finalise(struct 
mtk_iommu_domain *dom)
return -EINVAL;
}
 
-   dom->data = data;
/* Update our support page sizes bitmap */
dom->domain.pgsize_bitmap = dom->cfg.pgsize_bitmap;
return 0;
@@ -369,30 +367,19 @@ static struct iommu_domain 
*mtk_iommu_domain_alloc(unsigned type)
if (!dom)
return NULL;
 
-   if (iommu_get_dma_cookie(>domain))
-   goto  free_dom;
-
-   if (mtk_iommu_domain_finalise(dom))
-   goto  put_dma_cookie;
+   if (iommu_get_dma_cookie(>domain)) {
+   kfree(dom);
+   return NULL;
+   }
 
dom->domain.geometry.aperture_start = 0;
dom->domain.geometry.aperture_end = DMA_BIT_MASK(32);
dom->domain.geometry.force_aperture = true;
-
return >domain;
-
-put_dma_cookie:
-   iommu_put_dma_cookie(>domain);
-free_dom:
-   kfree(dom);
-   return NULL;
 }
 
 static void mtk_iommu_domain_free(struct iommu_domain *domain)
 {
-   struct mtk_iommu_domain *dom = to_mtk_domain(domain);
-
-   free_io_pgtable_ops(dom->iop);
iommu_put_dma_cookie(domain);
kfree(to_mtk_domain(domain));
 }
@@ -408,6 +395,12 @@ static int mtk_iommu_attach_device(struct iommu_domain 
*domain,
if (!data)
return -ENODEV;
 
+   if (!dom->data) {
+   if (mtk_iommu_domain_finalise(dom, data))
+   return -ENODEV;
+   dom->data = data;
+   }
+
if (!data->m4u_dom) { /* Initialize the M4U HW */
ret = pm_runtime_resume_and_get(m4udev);
if (ret < 0)
-- 
2.18.0



[PATCH v6 22/33] iommu/mediatek: Support report iova 34bit translation fault in ISR

2021-01-11 Thread Yong Wu
If the iova is over 32bit, the fault status register bit is a little
different.

Signed-off-by: Yong Wu 
---
 drivers/iommu/mtk_iommu.c | 17 +++--
 1 file changed, 15 insertions(+), 2 deletions(-)

diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index 468be7ca62e4..f3666b0d7577 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -3,6 +3,7 @@
  * Copyright (c) 2015-2016 MediaTek Inc.
  * Author: Yong Wu 
  */
+#include 
 #include 
 #include 
 #include 
@@ -89,6 +90,9 @@
 #define F_REG_MMU1_FAULT_MASK  GENMASK(13, 7)
 
 #define REG_MMU0_FAULT_VA  0x13c
+#define F_MMU_INVAL_VA_31_12_MASK  GENMASK(31, 12)
+#define F_MMU_INVAL_VA_34_32_MASK  GENMASK(11, 9)
+#define F_MMU_INVAL_PA_34_32_MASK  GENMASK(8, 6)
 #define F_MMU_FAULT_VA_WRITE_BIT   BIT(1)
 #define F_MMU_FAULT_VA_LAYER_BIT   BIT(0)
 
@@ -246,8 +250,9 @@ static irqreturn_t mtk_iommu_isr(int irq, void *dev_id)
 {
struct mtk_iommu_data *data = dev_id;
struct mtk_iommu_domain *dom = data->m4u_dom;
-   u32 int_state, regval, fault_iova, fault_pa;
unsigned int fault_larb, fault_port, sub_comm = 0;
+   u32 int_state, regval, va34_32, pa34_32;
+   u64 fault_iova, fault_pa;
bool layer, write;
 
/* Read error info from registers */
@@ -263,6 +268,14 @@ static irqreturn_t mtk_iommu_isr(int irq, void *dev_id)
}
layer = fault_iova & F_MMU_FAULT_VA_LAYER_BIT;
write = fault_iova & F_MMU_FAULT_VA_WRITE_BIT;
+   if (MTK_IOMMU_HAS_FLAG(data->plat_data, IOVA_34_EN)) {
+   va34_32 = FIELD_GET(F_MMU_INVAL_VA_34_32_MASK, fault_iova);
+   pa34_32 = FIELD_GET(F_MMU_INVAL_PA_34_32_MASK, fault_iova);
+   fault_iova = fault_iova & F_MMU_INVAL_VA_31_12_MASK;
+   fault_iova |= (u64)va34_32 << 32;
+   fault_pa |= (u64)pa34_32 << 32;
+   }
+
fault_port = F_MMU_INT_ID_PORT_ID(regval);
if (MTK_IOMMU_HAS_FLAG(data->plat_data, HAS_SUB_COMM)) {
fault_larb = F_MMU_INT_ID_COMM_ID(regval);
@@ -276,7 +289,7 @@ static irqreturn_t mtk_iommu_isr(int irq, void *dev_id)
   write ? IOMMU_FAULT_WRITE : IOMMU_FAULT_READ)) {
dev_err_ratelimited(
data->dev,
-   "fault type=0x%x iova=0x%x pa=0x%x larb=%d port=%d 
layer=%d %s\n",
+   "fault type=0x%x iova=0x%llx pa=0x%llx larb=%d port=%d 
layer=%d %s\n",
int_state, fault_iova, fault_pa, fault_larb, fault_port,
layer, write ? "write" : "read");
}
-- 
2.18.0



[PATCH v6 23/33] iommu/mediatek: Adjust the structure

2021-01-11 Thread Yong Wu
Add "struct mtk_iommu_data *" in the "struct mtk_iommu_domain",
reduce the call mtk_iommu_get_m4u_data().
No functional change.

Signed-off-by: Yong Wu 
---
 drivers/iommu/mtk_iommu.c | 20 +++-
 1 file changed, 11 insertions(+), 9 deletions(-)

diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index f3666b0d7577..f1941608ccb7 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -126,6 +126,7 @@ struct mtk_iommu_domain {
struct io_pgtable_cfg   cfg;
struct io_pgtable_ops   *iop;
 
+   struct mtk_iommu_data   *data;
struct iommu_domain domain;
 };
 
@@ -351,6 +352,7 @@ static int mtk_iommu_domain_finalise(struct 
mtk_iommu_domain *dom)
return -EINVAL;
}
 
+   dom->data = data;
/* Update our support page sizes bitmap */
dom->domain.pgsize_bitmap = dom->cfg.pgsize_bitmap;
return 0;
@@ -442,10 +444,9 @@ static int mtk_iommu_map(struct iommu_domain *domain, 
unsigned long iova,
 phys_addr_t paddr, size_t size, int prot, gfp_t gfp)
 {
struct mtk_iommu_domain *dom = to_mtk_domain(domain);
-   struct mtk_iommu_data *data = mtk_iommu_get_m4u_data();
 
/* The "4GB mode" M4U physically can not use the lower remap of Dram. */
-   if (data->enable_4GB)
+   if (dom->data->enable_4GB)
paddr |= BIT_ULL(32);
 
/* Synchronize with the tlb_lock */
@@ -468,36 +469,37 @@ static size_t mtk_iommu_unmap(struct iommu_domain *domain,
 
 static void mtk_iommu_flush_iotlb_all(struct iommu_domain *domain)
 {
-   mtk_iommu_tlb_flush_all(mtk_iommu_get_m4u_data());
+   struct mtk_iommu_domain *dom = to_mtk_domain(domain);
+
+   mtk_iommu_tlb_flush_all(dom->data);
 }
 
 static void mtk_iommu_iotlb_sync(struct iommu_domain *domain,
 struct iommu_iotlb_gather *gather)
 {
-   struct mtk_iommu_data *data = mtk_iommu_get_m4u_data();
+   struct mtk_iommu_domain *dom = to_mtk_domain(domain);
size_t length = gather->end - gather->start + 1;
 
mtk_iommu_tlb_flush_range_sync(gather->start, length, gather->pgsize,
-  data);
+  dom->data);
 }
 
 static void mtk_iommu_sync_map(struct iommu_domain *domain, unsigned long iova,
   size_t size)
 {
-   struct mtk_iommu_data *data = mtk_iommu_get_m4u_data();
+   struct mtk_iommu_domain *dom = to_mtk_domain(domain);
 
-   mtk_iommu_tlb_flush_range_sync(iova, size, size, data);
+   mtk_iommu_tlb_flush_range_sync(iova, size, size, dom->data);
 }
 
 static phys_addr_t mtk_iommu_iova_to_phys(struct iommu_domain *domain,
  dma_addr_t iova)
 {
struct mtk_iommu_domain *dom = to_mtk_domain(domain);
-   struct mtk_iommu_data *data = mtk_iommu_get_m4u_data();
phys_addr_t pa;
 
pa = dom->iop->iova_to_phys(dom->iop, iova);
-   if (data->enable_4GB && pa >= MTK_IOMMU_4GB_MODE_REMAP_BASE)
+   if (dom->data->enable_4GB && pa >= MTK_IOMMU_4GB_MODE_REMAP_BASE)
pa &= ~BIT_ULL(32);
 
return pa;
-- 
2.18.0



[PATCH v6 28/33] iommu/mediatek: Support for multi domains

2021-01-11 Thread Yong Wu
Some HW IP(ex: CCU) require the special iova range. That means the iova
got from dma_alloc_attrs for that devices must locate in his special range.
In this patch, we prepare a iommu group(domain) for each a iova range
requirement.

Meanwhile we still use one pagetable which support 16GB iova.

After this patch, If the iova range of a master is over 4G, the master
should:
a) Declare its special dma-ranges in its dtsi node. For example, If we
   preassign the iova 4G-8G for vcodec, then the vcodec dtsi node should
   add this:
   /*
* iova start at 0x1__, pa still start at 0x4000_
* size is 0x1__.
*/
   dma-ranges = <0x1 0x0 0x0 0x4000 0x1 0x0>;  /* 4G ~ 8G */
 Note: we don't have a actual bus concept here. the master doesn't have its
 special parent node, thus this dma-ranges can only be put in the master's
 node.

b) Update the dma_mask:
  dma_set_mask_and_coherent(dev, DMA_BIT_MASK(33));

Signed-off-by: Yong Wu 
---
 drivers/iommu/mtk_iommu.c | 37 ++---
 drivers/iommu/mtk_iommu.h |  4 +++-
 2 files changed, 29 insertions(+), 12 deletions(-)

diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index 8fc17158bc28..b42fd2535b77 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -369,8 +369,19 @@ static void mtk_iommu_config(struct mtk_iommu_data *data,
 }
 
 static int mtk_iommu_domain_finalise(struct mtk_iommu_domain *dom,
-struct mtk_iommu_data *data)
+struct mtk_iommu_data *data,
+unsigned int domid)
 {
+   const struct mtk_iommu_iova_region *region;
+
+   /* Use the exist domain as there is only one pgtable here. */
+   if (data->m4u_dom) {
+   dom->iop = data->m4u_dom->iop;
+   dom->cfg = data->m4u_dom->cfg;
+   dom->domain.pgsize_bitmap = data->m4u_dom->cfg.pgsize_bitmap;
+   goto update_iova_region;
+   }
+
dom->cfg = (struct io_pgtable_cfg) {
.quirks = IO_PGTABLE_QUIRK_ARM_NS |
IO_PGTABLE_QUIRK_NO_PERMS |
@@ -394,8 +405,11 @@ static int mtk_iommu_domain_finalise(struct 
mtk_iommu_domain *dom,
/* Update our support page sizes bitmap */
dom->domain.pgsize_bitmap = dom->cfg.pgsize_bitmap;
 
-   dom->domain.geometry.aperture_start = 0;
-   dom->domain.geometry.aperture_end = DMA_BIT_MASK(32);
+update_iova_region:
+   /* Update the iova region for this domain */
+   region = data->plat_data->iova_region + domid;
+   dom->domain.geometry.aperture_start = region->iova_base;
+   dom->domain.geometry.aperture_end = region->iova_base + region->size - 
1;
dom->domain.geometry.force_aperture = true;
return 0;
 }
@@ -441,7 +455,7 @@ static int mtk_iommu_attach_device(struct iommu_domain 
*domain,
return domid;
 
if (!dom->data) {
-   if (mtk_iommu_domain_finalise(dom, data))
+   if (mtk_iommu_domain_finalise(dom, data, domid))
return -ENODEV;
dom->data = data;
}
@@ -569,6 +583,7 @@ static void mtk_iommu_release_device(struct device *dev)
 static struct iommu_group *mtk_iommu_device_group(struct device *dev)
 {
struct mtk_iommu_data *data = mtk_iommu_get_m4u_data();
+   struct iommu_group *group;
int domid;
 
if (!data)
@@ -578,15 +593,15 @@ static struct iommu_group *mtk_iommu_device_group(struct 
device *dev)
if (domid < 0)
return ERR_PTR(domid);
 
-   /* All the client devices are in the same m4u iommu-group */
-   if (!data->m4u_group) {
-   data->m4u_group = iommu_group_alloc();
-   if (IS_ERR(data->m4u_group))
-   dev_err(dev, "Failed to allocate M4U IOMMU group\n");
+   group = data->m4u_group[domid];
+   if (!group) {
+   group = iommu_group_alloc();
+   if (!IS_ERR(group))
+   data->m4u_group[domid] = group;
} else {
-   iommu_group_ref_get(data->m4u_group);
+   iommu_group_ref_get(group);
}
-   return data->m4u_group;
+   return group;
 }
 
 static int mtk_iommu_of_xlate(struct device *dev, struct of_phandle_args *args)
diff --git a/drivers/iommu/mtk_iommu.h b/drivers/iommu/mtk_iommu.h
index 118170af1974..6f2168e3222d 100644
--- a/drivers/iommu/mtk_iommu.h
+++ b/drivers/iommu/mtk_iommu.h
@@ -22,6 +22,8 @@
 #define MTK_LARB_COM_MAX   8
 #define MTK_LARB_SUBCOM_MAX4
 
+#define MTK_IOMMU_GROUP_MAX8
+
 struct mtk_iommu_suspend_reg {
union {
u32 standard_axi_mode;/* v1 */
@@ -67,7 +69,7 @@ struct mtk_iommu_data {
phys_addr_t protect_base; /* p

[PATCH v6 26/33] iommu/mediatek: Add iova_region structure

2021-01-11 Thread Yong Wu
Add a new structure for the iova_region. Each a region will be a
independent iommu domain.

For the previous SoC, there is single iova region(0~4G). For the SoC
that need support multi-domains, there will be several regions.

Signed-off-by: Yong Wu 
---
 drivers/iommu/mtk_iommu.c | 19 +++
 drivers/iommu/mtk_iommu.h |  5 +
 2 files changed, 24 insertions(+)

diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index 309b06d5e1f9..6875ca1225f0 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -167,6 +167,15 @@ static LIST_HEAD(m4ulist); /* List all the M4U HWs */
 
 #define for_each_m4u(data) list_for_each_entry(data, , list)
 
+struct mtk_iommu_iova_region {
+   dma_addr_t  iova_base;
+   unsigned long long  size;
+};
+
+static const struct mtk_iommu_iova_region single_domain[] = {
+   {.iova_base = 0,.size = SZ_4G},
+};
+
 /*
  * There may be 1 or 2 M4U HWs, But we always expect they are in the same 
domain
  * for the performance.
@@ -901,6 +910,8 @@ static const struct mtk_iommu_plat_data mt2712_data = {
.m4u_plat = M4U_MT2712,
.flags= HAS_4GB_MODE | HAS_BCLK | HAS_VLD_PA_RNG,
.inv_sel_reg  = REG_MMU_INV_SEL_GEN1,
+   .iova_region  = single_domain,
+   .iova_region_nr = ARRAY_SIZE(single_domain),
.larbid_remap = {{0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}},
 };
 
@@ -908,6 +919,8 @@ static const struct mtk_iommu_plat_data mt6779_data = {
.m4u_plat  = M4U_MT6779,
.flags = HAS_SUB_COMM | OUT_ORDER_WR_EN | WR_THROT_EN,
.inv_sel_reg   = REG_MMU_INV_SEL_GEN2,
+   .iova_region   = single_domain,
+   .iova_region_nr = ARRAY_SIZE(single_domain),
.larbid_remap  = {{0}, {1}, {2}, {3}, {5}, {7, 8}, {10}, {9}},
 };
 
@@ -915,6 +928,8 @@ static const struct mtk_iommu_plat_data mt8167_data = {
.m4u_plat = M4U_MT8167,
.flags= RESET_AXI | HAS_LEGACY_IVRP_PADDR,
.inv_sel_reg  = REG_MMU_INV_SEL_GEN1,
+   .iova_region  = single_domain,
+   .iova_region_nr = ARRAY_SIZE(single_domain),
.larbid_remap = {{0}, {1}, {2}}, /* Linear mapping. */
 };
 
@@ -923,6 +938,8 @@ static const struct mtk_iommu_plat_data mt8173_data = {
.flags= HAS_4GB_MODE | HAS_BCLK | RESET_AXI |
HAS_LEGACY_IVRP_PADDR,
.inv_sel_reg  = REG_MMU_INV_SEL_GEN1,
+   .iova_region  = single_domain,
+   .iova_region_nr = ARRAY_SIZE(single_domain),
.larbid_remap = {{0}, {1}, {2}, {3}, {4}, {5}}, /* Linear mapping. */
 };
 
@@ -930,6 +947,8 @@ static const struct mtk_iommu_plat_data mt8183_data = {
.m4u_plat = M4U_MT8183,
.flags= RESET_AXI,
.inv_sel_reg  = REG_MMU_INV_SEL_GEN1,
+   .iova_region  = single_domain,
+   .iova_region_nr = ARRAY_SIZE(single_domain),
.larbid_remap = {{0}, {4}, {5}, {6}, {7}, {2}, {3}, {1}},
 };
 
diff --git a/drivers/iommu/mtk_iommu.h b/drivers/iommu/mtk_iommu.h
index a9b79e118f02..118170af1974 100644
--- a/drivers/iommu/mtk_iommu.h
+++ b/drivers/iommu/mtk_iommu.h
@@ -45,10 +45,15 @@ enum mtk_iommu_plat {
M4U_MT8183,
 };
 
+struct mtk_iommu_iova_region;
+
 struct mtk_iommu_plat_data {
enum mtk_iommu_plat m4u_plat;
u32 flags;
u32 inv_sel_reg;
+
+   unsigned intiova_region_nr;
+   const struct mtk_iommu_iova_region  *iova_region;
unsigned char   larbid_remap[MTK_LARB_COM_MAX][MTK_LARB_SUBCOM_MAX];
 };
 
-- 
2.18.0



[PATCH v6 25/33] iommu/mediatek: Move geometry.aperture updating into domain_finalise

2021-01-11 Thread Yong Wu
Move the domain geometry.aperture updating into domain_finalise.
This is a preparing patch for updating the domain region. We know the
detailed iova region in the attach_device.

Signed-off-by: Yong Wu 
---
 drivers/iommu/mtk_iommu.c | 7 ---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index d321d09ac4c2..309b06d5e1f9 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -353,6 +353,10 @@ static int mtk_iommu_domain_finalise(struct 
mtk_iommu_domain *dom,
 
/* Update our support page sizes bitmap */
dom->domain.pgsize_bitmap = dom->cfg.pgsize_bitmap;
+
+   dom->domain.geometry.aperture_start = 0;
+   dom->domain.geometry.aperture_end = DMA_BIT_MASK(32);
+   dom->domain.geometry.force_aperture = true;
return 0;
 }
 
@@ -372,9 +376,6 @@ static struct iommu_domain *mtk_iommu_domain_alloc(unsigned 
type)
return NULL;
}
 
-   dom->domain.geometry.aperture_start = 0;
-   dom->domain.geometry.aperture_end = DMA_BIT_MASK(32);
-   dom->domain.geometry.force_aperture = true;
return >domain;
 }
 
-- 
2.18.0



[PATCH v6 27/33] iommu/mediatek: Add get_domain_id from dev->dma_range_map

2021-01-11 Thread Yong Wu
Add a new interface _get_domain_id from dev->dma_range_map,
The iommu consumer device will use dma-ranges in dtsi node to indicate
its dma address region requirement. In this iommu driver, we will get
the requirement and decide which iova domain it should locate.

In the lastest SoC, there will be several iova-regions(domains), we will
compare and calculate which domain is right. If the start/end of device
requirement equal some region. it is best fit of course. If it is inside
some region, it is also ok. the iova requirement of a device should not
be inside two or more regions.

Signed-off-by: Yong Wu 
---
 drivers/iommu/mtk_iommu.c | 42 ++-
 1 file changed, 41 insertions(+), 1 deletion(-)

diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index 6875ca1225f0..8fc17158bc28 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -8,6 +8,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -314,6 +315,36 @@ static irqreturn_t mtk_iommu_isr(int irq, void *dev_id)
return IRQ_HANDLED;
 }
 
+static int mtk_iommu_get_domain_id(struct device *dev,
+  const struct mtk_iommu_plat_data *plat_data)
+{
+   const struct mtk_iommu_iova_region *rgn = plat_data->iova_region;
+   const struct bus_dma_region *dma_rgn = dev->dma_range_map;
+   int i, candidate = -1;
+   dma_addr_t dma_end;
+
+   if (!dma_rgn || plat_data->iova_region_nr == 1)
+   return 0;
+
+   dma_end = dma_rgn->dma_start + dma_rgn->size - 1;
+   for (i = 0; i < plat_data->iova_region_nr; i++, rgn++) {
+   /* Best fit. */
+   if (dma_rgn->dma_start == rgn->iova_base &&
+   dma_end == rgn->iova_base + rgn->size - 1)
+   return i;
+   /* ok if it is inside this region. */
+   if (dma_rgn->dma_start >= rgn->iova_base &&
+   dma_end < rgn->iova_base + rgn->size)
+   candidate = i;
+   }
+
+   if (candidate >= 0)
+   return candidate;
+   dev_err(dev, "Can NOT find the iommu domain id(%pad 0x%llx).\n",
+   _rgn->dma_start, dma_rgn->size);
+   return -EINVAL;
+}
+
 static void mtk_iommu_config(struct mtk_iommu_data *data,
 struct device *dev, bool enable)
 {
@@ -400,11 +431,15 @@ static int mtk_iommu_attach_device(struct iommu_domain 
*domain,
struct mtk_iommu_data *data = dev_iommu_priv_get(dev);
struct mtk_iommu_domain *dom = to_mtk_domain(domain);
struct device *m4udev = data->dev;
-   int ret;
+   int ret, domid;
 
if (!data)
return -ENODEV;
 
+   domid = mtk_iommu_get_domain_id(dev, data->plat_data);
+   if (domid < 0)
+   return domid;
+
if (!dom->data) {
if (mtk_iommu_domain_finalise(dom, data))
return -ENODEV;
@@ -534,10 +569,15 @@ static void mtk_iommu_release_device(struct device *dev)
 static struct iommu_group *mtk_iommu_device_group(struct device *dev)
 {
struct mtk_iommu_data *data = mtk_iommu_get_m4u_data();
+   int domid;
 
if (!data)
return ERR_PTR(-ENODEV);
 
+   domid = mtk_iommu_get_domain_id(dev, data->plat_data);
+   if (domid < 0)
+   return ERR_PTR(domid);
+
/* All the client devices are in the same m4u iommu-group */
if (!data->m4u_group) {
data->m4u_group = iommu_group_alloc();
-- 
2.18.0



[PATCH v6 20/33] iommu/mediatek: Add power-domain operation

2021-01-11 Thread Yong Wu
In the previous SoC, the M4U HW is in the EMI power domain which is
always on. the latest M4U is in the display power domain which may be
turned on/off, thus we have to add pm_runtime interface for it.

When the engine work, the engine always enable the power and clocks for
smi-larb/smi-common, then the M4U's power will always be powered on
automatically via the device link with smi-common.

Note: we don't enable the M4U power in iommu_map/unmap for tlb flush.
If its power already is on, of course it is ok. if the power is off,
the main tlb will be reset while M4U power on, thus the tlb flush while
m4u power off is unnecessary, just skip it.
Therefore, we increase the ref_count for pm when pm status is ACTIVE,
otherwise, skip it. Meanwhile, the tlb_flush_range is called so often,
thus, update pm ref_count while the SoC has power-domain to avoid touch the
dev->power.lock. and the tlb_flush_all only is called when boot, so no
need check if the SoC has power-domain to keep code clean.

There will be one case that pm runctime status is not expected when tlb
flush. After boot, the display may call dma_alloc_attrs before it call
pm_runtime_get(disp-dev), then the m4u's pm status is not active inside
the dma_alloc_attrs. Since it only happens after boot, the tlb is clean
at that time, I also think this is ok.

Signed-off-by: Yong Wu 
---
 drivers/iommu/mtk_iommu.c | 39 ++-
 1 file changed, 34 insertions(+), 5 deletions(-)

diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index 3682137b789a..b9c63c8de33e 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -182,10 +182,15 @@ static struct mtk_iommu_domain *to_mtk_domain(struct 
iommu_domain *dom)
 static void mtk_iommu_tlb_flush_all(struct mtk_iommu_data *data)
 {
for_each_m4u(data) {
+   if (pm_runtime_get_if_in_use(data->dev) <= 0)
+   continue;
+
writel_relaxed(F_INVLD_EN1 | F_INVLD_EN0,
   data->base + data->plat_data->inv_sel_reg);
writel_relaxed(F_ALL_INVLD, data->base + REG_MMU_INVALIDATE);
wmb(); /* Make sure the tlb flush all done */
+
+   pm_runtime_put(data->dev);
}
 }
 
@@ -193,11 +198,17 @@ static void mtk_iommu_tlb_flush_range_sync(unsigned long 
iova, size_t size,
   size_t granule,
   struct mtk_iommu_data *data)
 {
+   bool has_pm = !!data->dev->pm_domain;
unsigned long flags;
int ret;
u32 tmp;
 
for_each_m4u(data) {
+   if (has_pm) {
+   if (pm_runtime_get_if_in_use(data->dev) <= 0)
+   continue;
+   }
+
spin_lock_irqsave(>tlb_lock, flags);
writel_relaxed(F_INVLD_EN1 | F_INVLD_EN0,
   data->base + data->plat_data->inv_sel_reg);
@@ -219,6 +230,9 @@ static void mtk_iommu_tlb_flush_range_sync(unsigned long 
iova, size_t size,
/* Clear the CPE status */
writel_relaxed(0, data->base + REG_MMU_CPE_DONE);
spin_unlock_irqrestore(>tlb_lock, flags);
+
+   if (has_pm)
+   pm_runtime_put(data->dev);
}
 }
 
@@ -367,18 +381,27 @@ static int mtk_iommu_attach_device(struct iommu_domain 
*domain,
 {
struct mtk_iommu_data *data = dev_iommu_priv_get(dev);
struct mtk_iommu_domain *dom = to_mtk_domain(domain);
+   struct device *m4udev = data->dev;
int ret;
 
if (!data)
return -ENODEV;
 
if (!data->m4u_dom) { /* Initialize the M4U HW */
+   ret = pm_runtime_resume_and_get(m4udev);
+   if (ret < 0)
+   return ret;
+
ret = mtk_iommu_hw_init(data);
-   if (ret)
+   if (ret) {
+   pm_runtime_put(m4udev);
return ret;
+   }
data->m4u_dom = dom;
writel(dom->cfg.arm_v7s_cfg.ttbr & MMU_PT_ADDR_MASK,
   data->base + REG_MMU_PT_BASE_ADDR);
+
+   pm_runtime_put(m4udev);
}
 
mtk_iommu_config(data, dev, true);
@@ -738,11 +761,13 @@ static int mtk_iommu_probe(struct platform_device *pdev)
of_node_put(smicomm_node);
data->smicomm_dev = >dev;
 
+   pm_runtime_enable(dev);
+
link = device_link_add(data->smicomm_dev, dev,
DL_FLAG_STATELESS | DL_FLAG_PM_RUNTIME);
if (!link) {
dev_err(dev, "Unable link %s.\n", dev_name(data->smicomm_dev));
-   return -EINVAL;
+   goto out_runtime_disable;
}
 
platform_set_drvdata(pdev, data);
@@ -782,6 +807,8 @@ static int mtk_

[PATCH v6 21/33] iommu/mediatek: Support up to 34bit iova in tlb flush

2021-01-11 Thread Yong Wu
If the iova is 34bit, the iova[32][33] is the bit0/1 in the tlb flush
register. Add a new macro for this.

In the macro, since (iova + size - 1) may be end with 0xfff, then the
bit0/1 always is 1, thus add a mask.

Signed-off-by: Yong Wu 
---
 drivers/iommu/mtk_iommu.c | 10 --
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index b9c63c8de33e..468be7ca62e4 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -129,6 +129,11 @@ static const struct iommu_ops mtk_iommu_ops;
 
 static int mtk_iommu_hw_init(const struct mtk_iommu_data *data);
 
+#define MTK_IOMMU_TLB_ADDR(iova) ({\
+   dma_addr_t _addr = iova;\
+   ((lower_32_bits(_addr) & GENMASK(31, 12)) | upper_32_bits(_addr));\
+})
+
 /*
  * In M4U 4GB mode, the physical address is remapped as below:
  *
@@ -213,8 +218,9 @@ static void mtk_iommu_tlb_flush_range_sync(unsigned long 
iova, size_t size,
writel_relaxed(F_INVLD_EN1 | F_INVLD_EN0,
   data->base + data->plat_data->inv_sel_reg);
 
-   writel_relaxed(iova, data->base + REG_MMU_INVLD_START_A);
-   writel_relaxed(iova + size - 1,
+   writel_relaxed(MTK_IOMMU_TLB_ADDR(iova),
+  data->base + REG_MMU_INVLD_START_A);
+   writel_relaxed(MTK_IOMMU_TLB_ADDR(iova + size - 1),
   data->base + REG_MMU_INVLD_END_A);
writel_relaxed(F_MMU_INV_RANGE,
   data->base + REG_MMU_INVALIDATE);
-- 
2.18.0



[PATCH v6 16/33] iommu/mediatek: Move hw_init into attach_device

2021-01-11 Thread Yong Wu
In attach device, it will update the pagetable base address register.
Move the hw_init function also here. Then it only need call
pm_runtime_get/put one time here if m4u has power domain.

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

diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index 1c4af574f5f7..87c4626c9072 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -126,6 +126,8 @@ struct mtk_iommu_domain {
 
 static const struct iommu_ops mtk_iommu_ops;
 
+static int mtk_iommu_hw_init(const struct mtk_iommu_data *data);
+
 /*
  * In M4U 4GB mode, the physical address is remapped as below:
  *
@@ -364,12 +366,15 @@ static int mtk_iommu_attach_device(struct iommu_domain 
*domain,
 {
struct mtk_iommu_data *data = dev_iommu_priv_get(dev);
struct mtk_iommu_domain *dom = to_mtk_domain(domain);
+   int ret;
 
if (!data)
return -ENODEV;
 
-   /* Update the pgtable base address register of the M4U HW */
-   if (!data->m4u_dom) {
+   if (!data->m4u_dom) { /* Initialize the M4U HW */
+   ret = mtk_iommu_hw_init(data);
+   if (ret)
+   return ret;
data->m4u_dom = dom;
writel(dom->cfg.arm_v7s_cfg.ttbr & MMU_PT_ADDR_MASK,
   data->base + REG_MMU_PT_BASE_ADDR);
@@ -724,10 +729,6 @@ static int mtk_iommu_probe(struct platform_device *pdev)
 
platform_set_drvdata(pdev, data);
 
-   ret = mtk_iommu_hw_init(data);
-   if (ret)
-   return ret;
-
ret = iommu_device_sysfs_add(>iommu, dev, NULL,
 "mtk-iommu.%pa", );
if (ret)
-- 
2.18.0



[PATCH v6 19/33] iommu/mediatek: Add pm runtime callback

2021-01-11 Thread Yong Wu
In pm runtime case, all the registers backup/restore and bclk are
controlled in the pm_runtime callback, Rename the original
suspend/resume to the runtime_suspend/resume.

Use pm_runtime_force_suspend/resume as the normal suspend/resume.
iommu should suspend after iommu consumer devices, thus use _LATE_.

Signed-off-by: Yong Wu 
---
 drivers/iommu/mtk_iommu.c | 8 +---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index 0fe7c1617dc3..3682137b789a 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -802,7 +802,7 @@ static int mtk_iommu_remove(struct platform_device *pdev)
return 0;
 }
 
-static int __maybe_unused mtk_iommu_suspend(struct device *dev)
+static int __maybe_unused mtk_iommu_runtime_suspend(struct device *dev)
 {
struct mtk_iommu_data *data = dev_get_drvdata(dev);
struct mtk_iommu_suspend_reg *reg = >reg;
@@ -820,7 +820,7 @@ static int __maybe_unused mtk_iommu_suspend(struct device 
*dev)
return 0;
 }
 
-static int __maybe_unused mtk_iommu_resume(struct device *dev)
+static int __maybe_unused mtk_iommu_runtime_resume(struct device *dev)
 {
struct mtk_iommu_data *data = dev_get_drvdata(dev);
struct mtk_iommu_suspend_reg *reg = >reg;
@@ -848,7 +848,9 @@ static int __maybe_unused mtk_iommu_resume(struct device 
*dev)
 }
 
 static const struct dev_pm_ops mtk_iommu_pm_ops = {
-   SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(mtk_iommu_suspend, mtk_iommu_resume)
+   SET_RUNTIME_PM_OPS(mtk_iommu_runtime_suspend, mtk_iommu_runtime_resume, 
NULL)
+   SET_LATE_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
+pm_runtime_force_resume)
 };
 
 static const struct mtk_iommu_plat_data mt2712_data = {
-- 
2.18.0



[PATCH v6 18/33] iommu/mediatek: Add device link for smi-common and m4u

2021-01-11 Thread Yong Wu
In the lastest SoC, M4U has its special power domain. thus, If the engine
begin to work, it should help enable the power for M4U firstly.
Currently if the engine work, it always enable the power/clocks for
smi-larbs/smi-common. This patch adds device_link for smi-common and M4U.
then, if smi-common power is enabled, the M4U power also is powered on
automatically.

Normally M4U connect with several smi-larbs and their smi-common always
are the same, In this patch it get smi-common dev from the last smi-larb
device, then add the device_link.

Signed-off-by: Yong Wu 
---
 drivers/iommu/mtk_iommu.c | 27 ---
 drivers/iommu/mtk_iommu.h |  1 +
 2 files changed, 25 insertions(+), 3 deletions(-)

diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index 189165e7a2ab..0fe7c1617dc3 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -20,6 +20,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -633,6 +634,9 @@ static int mtk_iommu_probe(struct platform_device *pdev)
 {
struct mtk_iommu_data   *data;
struct device   *dev = >dev;
+   struct device_node  *larbnode, *smicomm_node;
+   struct platform_device  *plarbdev;
+   struct device_link  *link;
struct resource *res;
resource_size_t ioaddr;
struct component_match  *match = NULL;
@@ -699,8 +703,6 @@ static int mtk_iommu_probe(struct platform_device *pdev)
return larb_nr;
 
for (i = 0; i < larb_nr; i++) {
-   struct device_node *larbnode;
-   struct platform_device *plarbdev;
u32 id;
 
larbnode = of_parse_phandle(dev->of_node, "mediatek,larbs", i);
@@ -727,12 +729,28 @@ static int mtk_iommu_probe(struct platform_device *pdev)
compare_of, larbnode);
}
 
+   /* Get smi-common dev from the last larb. */
+   smicomm_node = of_parse_phandle(larbnode, "mediatek,smi", 0);
+   if (!smicomm_node)
+   return -EINVAL;
+
+   plarbdev = of_find_device_by_node(smicomm_node);
+   of_node_put(smicomm_node);
+   data->smicomm_dev = >dev;
+
+   link = device_link_add(data->smicomm_dev, dev,
+   DL_FLAG_STATELESS | DL_FLAG_PM_RUNTIME);
+   if (!link) {
+   dev_err(dev, "Unable link %s.\n", dev_name(data->smicomm_dev));
+   return -EINVAL;
+   }
+
platform_set_drvdata(pdev, data);
 
ret = iommu_device_sysfs_add(>iommu, dev, NULL,
 "mtk-iommu.%pa", );
if (ret)
-   return ret;
+   goto out_link_remove;
 
iommu_device_set_ops(>iommu, _iommu_ops);
iommu_device_set_fwnode(>iommu, >dev.of_node->fwnode);
@@ -762,6 +780,8 @@ static int mtk_iommu_probe(struct platform_device *pdev)
iommu_device_unregister(>iommu);
 out_sysfs_remove:
iommu_device_sysfs_remove(>iommu);
+out_link_remove:
+   device_link_remove(data->smicomm_dev, dev);
return ret;
 }
 
@@ -776,6 +796,7 @@ static int mtk_iommu_remove(struct platform_device *pdev)
bus_set_iommu(_bus_type, NULL);
 
clk_disable_unprepare(data->bclk);
+   device_link_remove(data->smicomm_dev, >dev);
devm_free_irq(>dev, data->irq, data);
component_master_del(>dev, _iommu_com_ops);
return 0;
diff --git a/drivers/iommu/mtk_iommu.h b/drivers/iommu/mtk_iommu.h
index c1584dea66cb..a9b79e118f02 100644
--- a/drivers/iommu/mtk_iommu.h
+++ b/drivers/iommu/mtk_iommu.h
@@ -68,6 +68,7 @@ struct mtk_iommu_data {
 
struct iommu_device iommu;
const struct mtk_iommu_plat_data *plat_data;
+   struct device   *smicomm_dev;
 
struct dma_iommu_mapping*mapping; /* For mtk_iommu_v1.c */
 
-- 
2.18.0



[PATCH v6 17/33] iommu/mediatek: Add error handle for mtk_iommu_probe

2021-01-11 Thread Yong Wu
In the original code, we lack the error handle. This patch adds them.

Signed-off-by: Yong Wu 
---
 drivers/iommu/mtk_iommu.c | 23 +++
 1 file changed, 19 insertions(+), 4 deletions(-)

diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index 87c4626c9072..189165e7a2ab 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -739,15 +739,30 @@ static int mtk_iommu_probe(struct platform_device *pdev)
 
ret = iommu_device_register(>iommu);
if (ret)
-   return ret;
+   goto out_sysfs_remove;
 
spin_lock_init(>tlb_lock);
list_add_tail(>list, );
 
-   if (!iommu_present(_bus_type))
-   bus_set_iommu(_bus_type, _iommu_ops);
+   if (!iommu_present(_bus_type)) {
+   ret = bus_set_iommu(_bus_type, _iommu_ops);
+   if (ret)
+   goto out_list_del;
+   }
 
-   return component_master_add_with_match(dev, _iommu_com_ops, match);
+   ret = component_master_add_with_match(dev, _iommu_com_ops, match);
+   if (ret)
+   goto out_bus_set_null;
+   return ret;
+
+out_bus_set_null:
+   bus_set_iommu(_bus_type, NULL);
+out_list_del:
+   list_del(>list);
+   iommu_device_unregister(>iommu);
+out_sysfs_remove:
+   iommu_device_sysfs_remove(>iommu);
+   return ret;
 }
 
 static int mtk_iommu_remove(struct platform_device *pdev)
-- 
2.18.0



[PATCH v6 15/33] iommu/mediatek: Update oas for v7s

2021-01-11 Thread Yong Wu
This patch only updates oas in different SoCs.

If the SoC supports 4GB-mode and current dram size is 4GB, the oas is 33.
otherwise, it's still 32. In the lastest SoC, the oas is 35bits.

Signed-off-by: Yong Wu 
---
 drivers/iommu/mtk_iommu.c | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index bf1277d58121..1c4af574f5f7 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -301,10 +301,14 @@ static int mtk_iommu_domain_finalise(struct 
mtk_iommu_domain *dom)
IO_PGTABLE_QUIRK_ARM_MTK_EXT,
.pgsize_bitmap = mtk_iommu_ops.pgsize_bitmap,
.ias = MTK_IOMMU_HAS_FLAG(data->plat_data, IOVA_34_EN) ? 34 : 
32,
-   .oas = 35,
.iommu_dev = data->dev,
};
 
+   if (MTK_IOMMU_HAS_FLAG(data->plat_data, HAS_4GB_MODE))
+   dom->cfg.oas = data->enable_4GB ? 33 : 32;
+   else
+   dom->cfg.oas = 35;
+
dom->iop = alloc_io_pgtable_ops(ARM_V7S, >cfg, data);
if (!dom->iop) {
dev_err(data->dev, "Failed to alloc io pgtable\n");
-- 
2.18.0



[PATCH v6 13/33] iommu/io-pgtable-arm-v7s: Quad lvl1 pgtable for MediaTek

2021-01-11 Thread Yong Wu
The standard input iova bits is 32. MediaTek quad the lvl1 pagetable
(4 * lvl1). No change for lvl2 pagetable. Then the iova bits can reach
34bit.

Signed-off-by: Yong Wu 
Reviewed-by: Robin Murphy 
---
 drivers/iommu/io-pgtable-arm-v7s.c | 7 ---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/iommu/io-pgtable-arm-v7s.c 
b/drivers/iommu/io-pgtable-arm-v7s.c
index 243476fdad9e..697dee76f6cb 100644
--- a/drivers/iommu/io-pgtable-arm-v7s.c
+++ b/drivers/iommu/io-pgtable-arm-v7s.c
@@ -45,9 +45,10 @@
 /*
  * We have 32 bits total; 12 bits resolved at level 1, 8 bits at level 2,
  * and 12 bits in a page.
+ * MediaTek extend 2 bits to reach 34bits, 14 bits at lvl1 and 8 bits at lvl2.
  */
 #define ARM_V7S_ADDR_BITS  32
-#define _ARM_V7S_LVL_BITS(lvl, cfg)((lvl) == 1 ? 12 : 8)
+#define _ARM_V7S_LVL_BITS(lvl, cfg)((lvl) == 1 ? ((cfg)->ias - 20) : 8)
 #define ARM_V7S_LVL_SHIFT(lvl) ((lvl) == 1 ? 20 : 12)
 #define ARM_V7S_TABLE_SHIFT10
 
@@ -61,7 +62,7 @@
 #define _ARM_V7S_IDX_MASK(lvl, cfg)(ARM_V7S_PTES_PER_LVL(lvl, cfg) - 1)
 #define ARM_V7S_LVL_IDX(addr, lvl, cfg)({  
\
int _l = lvl;   \
-   ((u32)(addr) >> ARM_V7S_LVL_SHIFT(_l)) & _ARM_V7S_IDX_MASK(_l, cfg); \
+   ((addr) >> ARM_V7S_LVL_SHIFT(_l)) & _ARM_V7S_IDX_MASK(_l, cfg); \
 })
 
 /*
@@ -754,7 +755,7 @@ static struct io_pgtable *arm_v7s_alloc_pgtable(struct 
io_pgtable_cfg *cfg,
 {
struct arm_v7s_io_pgtable *data;
 
-   if (cfg->ias > ARM_V7S_ADDR_BITS)
+   if (cfg->ias > (arm_v7s_is_mtk_enabled(cfg) ? 34 : ARM_V7S_ADDR_BITS))
return NULL;
 
if (cfg->oas > (arm_v7s_is_mtk_enabled(cfg) ? 35 : ARM_V7S_ADDR_BITS))
-- 
2.18.0



[PATCH v6 14/33] iommu/mediatek: Add a flag for iova 34bits case

2021-01-11 Thread Yong Wu
Add a HW flag for if the HW support 34bit IOVA. the previous SoC
still use 32bit. normally the lvl1 pgtable size is 16KB when ias == 32.
if ias == 34, lvl1 pgtable size is 16KB * 4. The purpose of this patch
is to save 16KB*3 continuous memory for the previous SoC.

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

diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index 485f3b6d1a21..bf1277d58121 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -112,6 +112,7 @@
 #define HAS_SUB_COMM   BIT(5)
 #define WR_THROT_ENBIT(6)
 #define HAS_LEGACY_IVRP_PADDR  BIT(7)
+#define IOVA_34_EN BIT(8)
 
 #define MTK_IOMMU_HAS_FLAG(pdata, _x) \
pdata)->flags) & (_x)) == (_x))
@@ -299,7 +300,7 @@ static int mtk_iommu_domain_finalise(struct 
mtk_iommu_domain *dom)
IO_PGTABLE_QUIRK_NO_PERMS |
IO_PGTABLE_QUIRK_ARM_MTK_EXT,
.pgsize_bitmap = mtk_iommu_ops.pgsize_bitmap,
-   .ias = 32,
+   .ias = MTK_IOMMU_HAS_FLAG(data->plat_data, IOVA_34_EN) ? 34 : 
32,
.oas = 35,
.iommu_dev = data->dev,
};
-- 
2.18.0



[PATCH v6 10/33] iommu/io-pgtable-arm-v7s: Extend PA34 for MediaTek

2021-01-11 Thread Yong Wu
MediaTek extend the bit5 in lvl1 and lvl2 descriptor as PA34.

Signed-off-by: Yong Wu 
Acked-by: Will Deacon 
Reviewed-by: Robin Murphy 
---
 drivers/iommu/io-pgtable-arm-v7s.c | 9 +++--
 drivers/iommu/mtk_iommu.c  | 2 +-
 include/linux/io-pgtable.h | 4 ++--
 3 files changed, 10 insertions(+), 5 deletions(-)

diff --git a/drivers/iommu/io-pgtable-arm-v7s.c 
b/drivers/iommu/io-pgtable-arm-v7s.c
index eb3703bfd98e..acfdb0163af8 100644
--- a/drivers/iommu/io-pgtable-arm-v7s.c
+++ b/drivers/iommu/io-pgtable-arm-v7s.c
@@ -112,9 +112,10 @@
 #define ARM_V7S_TEX_MASK   0x7
 #define ARM_V7S_ATTR_TEX(val)  (((val) & ARM_V7S_TEX_MASK) << 
ARM_V7S_TEX_SHIFT)
 
-/* MediaTek extend the two bits for PA 32bit/33bit */
+/* MediaTek extend the bits below for PA 32bit/33bit/34bit */
 #define ARM_V7S_ATTR_MTK_PA_BIT32  BIT(9)
 #define ARM_V7S_ATTR_MTK_PA_BIT33  BIT(4)
+#define ARM_V7S_ATTR_MTK_PA_BIT34  BIT(5)
 
 /* *well, except for TEX on level 2 large pages, of course :( */
 #define ARM_V7S_CONT_PAGE_TEX_SHIFT6
@@ -194,6 +195,8 @@ static arm_v7s_iopte paddr_to_iopte(phys_addr_t paddr, int 
lvl,
pte |= ARM_V7S_ATTR_MTK_PA_BIT32;
if (paddr & BIT_ULL(33))
pte |= ARM_V7S_ATTR_MTK_PA_BIT33;
+   if (paddr & BIT_ULL(34))
+   pte |= ARM_V7S_ATTR_MTK_PA_BIT34;
return pte;
 }
 
@@ -218,6 +221,8 @@ static phys_addr_t iopte_to_paddr(arm_v7s_iopte pte, int 
lvl,
paddr |= BIT_ULL(32);
if (pte & ARM_V7S_ATTR_MTK_PA_BIT33)
paddr |= BIT_ULL(33);
+   if (pte & ARM_V7S_ATTR_MTK_PA_BIT34)
+   paddr |= BIT_ULL(34);
return paddr;
 }
 
@@ -754,7 +759,7 @@ static struct io_pgtable *arm_v7s_alloc_pgtable(struct 
io_pgtable_cfg *cfg,
if (cfg->ias > ARM_V7S_ADDR_BITS)
return NULL;
 
-   if (cfg->oas > (arm_v7s_is_mtk_enabled(cfg) ? 34 : ARM_V7S_ADDR_BITS))
+   if (cfg->oas > (arm_v7s_is_mtk_enabled(cfg) ? 35 : ARM_V7S_ADDR_BITS))
return NULL;
 
if (cfg->quirks & ~(IO_PGTABLE_QUIRK_ARM_NS |
diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index f594971dbeb2..485f3b6d1a21 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -300,7 +300,7 @@ static int mtk_iommu_domain_finalise(struct 
mtk_iommu_domain *dom)
IO_PGTABLE_QUIRK_ARM_MTK_EXT,
.pgsize_bitmap = mtk_iommu_ops.pgsize_bitmap,
.ias = 32,
-   .oas = 34,
+   .oas = 35,
.iommu_dev = data->dev,
};
 
diff --git a/include/linux/io-pgtable.h b/include/linux/io-pgtable.h
index 2a5686ca2ba3..8d3228899a2b 100644
--- a/include/linux/io-pgtable.h
+++ b/include/linux/io-pgtable.h
@@ -73,8 +73,8 @@ struct io_pgtable_cfg {
 *  TLB maintenance when mapping as well as when unmapping.
 *
 * IO_PGTABLE_QUIRK_ARM_MTK_EXT: (ARM v7s format) MediaTek IOMMUs extend
-*  to support up to 34 bits PA where the bit32 and bit33 are
-*  encoded in the bit9 and bit4 of the PTE respectively.
+*  to support up to 35 bits PA where the bit32, bit33 and bit34 are
+*  encoded in the bit9, bit4 and bit5 of the PTE respectively.
 *
 * IO_PGTABLE_QUIRK_NON_STRICT: Skip issuing synchronous leaf TLBIs
 *  on unmap, for DMA domains using the flush queue mechanism for
-- 
2.18.0



[PATCH v6 12/33] iommu/io-pgtable-arm-v7s: Add cfg as a param in some macros

2021-01-11 Thread Yong Wu
Add "cfg" as a parameter for some macros. This is a preparing patch for
mediatek extend the lvl1 pgtable. No functional change.

Signed-off-by: Yong Wu 
Acked-by: Will Deacon 
Reviewed-by: Robin Murphy 
---
 drivers/iommu/io-pgtable-arm-v7s.c | 36 +++---
 1 file changed, 18 insertions(+), 18 deletions(-)

diff --git a/drivers/iommu/io-pgtable-arm-v7s.c 
b/drivers/iommu/io-pgtable-arm-v7s.c
index 0ce9a14300e9..243476fdad9e 100644
--- a/drivers/iommu/io-pgtable-arm-v7s.c
+++ b/drivers/iommu/io-pgtable-arm-v7s.c
@@ -47,21 +47,21 @@
  * and 12 bits in a page.
  */
 #define ARM_V7S_ADDR_BITS  32
-#define _ARM_V7S_LVL_BITS(lvl) ((lvl) == 1 ? 12 : 8)
+#define _ARM_V7S_LVL_BITS(lvl, cfg)((lvl) == 1 ? 12 : 8)
 #define ARM_V7S_LVL_SHIFT(lvl) ((lvl) == 1 ? 20 : 12)
 #define ARM_V7S_TABLE_SHIFT10
 
-#define ARM_V7S_PTES_PER_LVL(lvl)  (1 << _ARM_V7S_LVL_BITS(lvl))
-#define ARM_V7S_TABLE_SIZE(lvl)
\
-   (ARM_V7S_PTES_PER_LVL(lvl) * sizeof(arm_v7s_iopte))
+#define ARM_V7S_PTES_PER_LVL(lvl, cfg) (1 << _ARM_V7S_LVL_BITS(lvl, cfg))
+#define ARM_V7S_TABLE_SIZE(lvl, cfg)   
\
+   (ARM_V7S_PTES_PER_LVL(lvl, cfg) * sizeof(arm_v7s_iopte))
 
 #define ARM_V7S_BLOCK_SIZE(lvl)(1UL << ARM_V7S_LVL_SHIFT(lvl))
 #define ARM_V7S_LVL_MASK(lvl)  ((u32)(~0U << ARM_V7S_LVL_SHIFT(lvl)))
 #define ARM_V7S_TABLE_MASK ((u32)(~0U << ARM_V7S_TABLE_SHIFT))
-#define _ARM_V7S_IDX_MASK(lvl) (ARM_V7S_PTES_PER_LVL(lvl) - 1)
-#define ARM_V7S_LVL_IDX(addr, lvl) ({  \
+#define _ARM_V7S_IDX_MASK(lvl, cfg)(ARM_V7S_PTES_PER_LVL(lvl, cfg) - 1)
+#define ARM_V7S_LVL_IDX(addr, lvl, cfg)({  
\
int _l = lvl;   \
-   ((u32)(addr) >> ARM_V7S_LVL_SHIFT(_l)) & _ARM_V7S_IDX_MASK(_l); \
+   ((u32)(addr) >> ARM_V7S_LVL_SHIFT(_l)) & _ARM_V7S_IDX_MASK(_l, cfg); \
 })
 
 /*
@@ -237,7 +237,7 @@ static void *__arm_v7s_alloc_table(int lvl, gfp_t gfp,
struct device *dev = cfg->iommu_dev;
phys_addr_t phys;
dma_addr_t dma;
-   size_t size = ARM_V7S_TABLE_SIZE(lvl);
+   size_t size = ARM_V7S_TABLE_SIZE(lvl, cfg);
void *table = NULL;
 
if (lvl == 1)
@@ -283,7 +283,7 @@ static void __arm_v7s_free_table(void *table, int lvl,
 {
struct io_pgtable_cfg *cfg = >iop.cfg;
struct device *dev = cfg->iommu_dev;
-   size_t size = ARM_V7S_TABLE_SIZE(lvl);
+   size_t size = ARM_V7S_TABLE_SIZE(lvl, cfg);
 
if (!cfg->coherent_walk)
dma_unmap_single(dev, __arm_v7s_dma_addr(table), size,
@@ -427,7 +427,7 @@ static int arm_v7s_init_pte(struct arm_v7s_io_pgtable *data,
arm_v7s_iopte *tblp;
size_t sz = ARM_V7S_BLOCK_SIZE(lvl);
 
-   tblp = ptep - ARM_V7S_LVL_IDX(iova, lvl);
+   tblp = ptep - ARM_V7S_LVL_IDX(iova, lvl, cfg);
if (WARN_ON(__arm_v7s_unmap(data, NULL, iova + i * sz,
sz, lvl, tblp) != sz))
return -EINVAL;
@@ -480,7 +480,7 @@ static int __arm_v7s_map(struct arm_v7s_io_pgtable *data, 
unsigned long iova,
int num_entries = size >> ARM_V7S_LVL_SHIFT(lvl);
 
/* Find our entry at the current level */
-   ptep += ARM_V7S_LVL_IDX(iova, lvl);
+   ptep += ARM_V7S_LVL_IDX(iova, lvl, cfg);
 
/* If we can install a leaf entry at this level, then do so */
if (num_entries)
@@ -553,7 +553,7 @@ static void arm_v7s_free_pgtable(struct io_pgtable *iop)
struct arm_v7s_io_pgtable *data = io_pgtable_to_data(iop);
int i;
 
-   for (i = 0; i < ARM_V7S_PTES_PER_LVL(1); i++) {
+   for (i = 0; i < ARM_V7S_PTES_PER_LVL(1, >iop.cfg); i++) {
arm_v7s_iopte pte = data->pgd[i];
 
if (ARM_V7S_PTE_IS_TABLE(pte, 1))
@@ -605,9 +605,9 @@ static size_t arm_v7s_split_blk_unmap(struct 
arm_v7s_io_pgtable *data,
if (!tablep)
return 0; /* Bytes unmapped */
 
-   num_ptes = ARM_V7S_PTES_PER_LVL(2);
+   num_ptes = ARM_V7S_PTES_PER_LVL(2, cfg);
num_entries = size >> ARM_V7S_LVL_SHIFT(2);
-   unmap_idx = ARM_V7S_LVL_IDX(iova, 2);
+   unmap_idx = ARM_V7S_LVL_IDX(iova, 2, cfg);
 
pte = arm_v7s_prot_to_pte(arm_v7s_pte_to_prot(blk_pte, 1), 2, cfg);
if (num_entries > 1)
@@ -649,7 +649,7 @@ static size_t __arm_v7s_unmap(struct arm_v7s_io_pgtable 
*data,
if (WARN_ON(lvl > 2))
return 0;
 
-   idx = ARM_V7S_LVL_IDX(iova, lvl);
+   idx = ARM_V7S_LVL_IDX(iova, lvl, >cfg);
ptep += idx;
do {
pte[i]

[PATCH v6 11/33] iommu/io-pgtable-arm-v7s: Clarify LVL_SHIFT/BITS macro

2021-01-11 Thread Yong Wu
The current _ARM_V7S_LVL_BITS/ARM_V7S_LVL_SHIFT use a formula to calculate
the corresponding value for level1 and level2 to pretend the code sane.
Actually their level1 and level2 values are different from each other.
This patch only clarify the two macro. No functional change.

Suggested-by: Robin Murphy 
Signed-off-by: Yong Wu 
Reviewed-by: Robin Murphy 
---
 drivers/iommu/io-pgtable-arm-v7s.c | 8 +++-
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/drivers/iommu/io-pgtable-arm-v7s.c 
b/drivers/iommu/io-pgtable-arm-v7s.c
index acfdb0163af8..0ce9a14300e9 100644
--- a/drivers/iommu/io-pgtable-arm-v7s.c
+++ b/drivers/iommu/io-pgtable-arm-v7s.c
@@ -44,13 +44,11 @@
 
 /*
  * We have 32 bits total; 12 bits resolved at level 1, 8 bits at level 2,
- * and 12 bits in a page. With some carefully-chosen coefficients we can
- * hide the ugly inconsistencies behind these macros and at least let the
- * rest of the code pretend to be somewhat sane.
+ * and 12 bits in a page.
  */
 #define ARM_V7S_ADDR_BITS  32
-#define _ARM_V7S_LVL_BITS(lvl) (16 - (lvl) * 4)
-#define ARM_V7S_LVL_SHIFT(lvl) (ARM_V7S_ADDR_BITS - (4 + 8 * (lvl)))
+#define _ARM_V7S_LVL_BITS(lvl) ((lvl) == 1 ? 12 : 8)
+#define ARM_V7S_LVL_SHIFT(lvl) ((lvl) == 1 ? 20 : 12)
 #define ARM_V7S_TABLE_SHIFT10
 
 #define ARM_V7S_PTES_PER_LVL(lvl)  (1 << _ARM_V7S_LVL_BITS(lvl))
-- 
2.18.0



[PATCH v6 08/33] iommu/mediatek: Use the common mtk-memory-port.h

2021-01-11 Thread Yong Wu
Use the common memory header(larb-port) in the source code.

Signed-off-by: Yong Wu 
Acked-by: Krzysztof Kozlowski 
---
 drivers/iommu/mtk_iommu.c  | 7 ---
 drivers/iommu/mtk_iommu.h  | 1 +
 drivers/memory/mtk-smi.c   | 1 +
 include/soc/mediatek/smi.h | 2 --
 4 files changed, 2 insertions(+), 9 deletions(-)

diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index 86ab577c9520..f594971dbeb2 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -103,13 +103,6 @@
 
 #define MTK_PROTECT_PA_ALIGN   256
 
-/*
- * Get the local arbiter ID and the portid within the larb arbiter
- * from mtk_m4u_id which is defined by MTK_M4U_ID.
- */
-#define MTK_M4U_TO_LARB(id)(((id) >> 5) & 0xf)
-#define MTK_M4U_TO_PORT(id)((id) & 0x1f)
-
 #define HAS_4GB_MODE   BIT(0)
 /* HW will use the EMI clock if there isn't the "bclk". */
 #define HAS_BCLK   BIT(1)
diff --git a/drivers/iommu/mtk_iommu.h b/drivers/iommu/mtk_iommu.h
index df32b3e3408b..c1584dea66cb 100644
--- a/drivers/iommu/mtk_iommu.h
+++ b/drivers/iommu/mtk_iommu.h
@@ -17,6 +17,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #define MTK_LARB_COM_MAX   8
 #define MTK_LARB_SUBCOM_MAX4
diff --git a/drivers/memory/mtk-smi.c b/drivers/memory/mtk-smi.c
index ac350f8d1e20..89f92fa2afa5 100644
--- a/drivers/memory/mtk-smi.c
+++ b/drivers/memory/mtk-smi.c
@@ -15,6 +15,7 @@
 #include 
 #include 
 #include 
+#include 
 
 /* mt8173 */
 #define SMI_LARB_MMU_EN0xf00
diff --git a/include/soc/mediatek/smi.h b/include/soc/mediatek/smi.h
index 5a34b87d89e3..9371bf572ab8 100644
--- a/include/soc/mediatek/smi.h
+++ b/include/soc/mediatek/smi.h
@@ -11,8 +11,6 @@
 
 #ifdef CONFIG_MTK_SMI
 
-#define MTK_LARB_NR_MAX16
-
 #define MTK_SMI_MMU_EN(port)   BIT(port)
 
 struct mtk_smi_larb_iommu {
-- 
2.18.0



[PATCH v6 09/33] iommu/io-pgtable-arm-v7s: Use ias to check the valid iova in unmap

2021-01-11 Thread Yong Wu
Use the ias for the valid iova checking in arm_v7s_unmap. This is a
preparing patch for supporting iova 34bit for MediaTek.

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

diff --git a/drivers/iommu/io-pgtable-arm-v7s.c 
b/drivers/iommu/io-pgtable-arm-v7s.c
index 1d92ac948db7..eb3703bfd98e 100644
--- a/drivers/iommu/io-pgtable-arm-v7s.c
+++ b/drivers/iommu/io-pgtable-arm-v7s.c
@@ -717,7 +717,7 @@ static size_t arm_v7s_unmap(struct io_pgtable_ops *ops, 
unsigned long iova,
 {
struct arm_v7s_io_pgtable *data = io_pgtable_ops_to_data(ops);
 
-   if (WARN_ON(upper_32_bits(iova)))
+   if (WARN_ON(iova >= (1ULL << data->iop.cfg.ias)))
return 0;
 
return __arm_v7s_unmap(data, gather, iova, size, 1, data->pgd);
-- 
2.18.0



[PATCH v6 05/33] dt-bindings: mediatek: Add binding for mt8192 IOMMU

2021-01-11 Thread Yong Wu
This patch adds decriptions for mt8192 IOMMU and SMI.

mt8192 also is MTK IOMMU gen2 which uses ARM Short-Descriptor translation
table format. The M4U-SMI HW diagram is as below:

  EMI
   |
  M4U
   |
  
   SMI Common
  
   |
  +---+--+--+--+---+
  |   |  |  |   .. |   |
  |   |  |  |  |   |
larb0   larb1  larb2  larb4 ..  larb19   larb20
disp0   disp1   mdpvdec   IPE  IPE

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

mt8192 M4U support 0~16GB iova range. we preassign different engines
into different iova ranges:

domain-id  module iova-range  larbs
   0   disp0 ~ 4G  larb0/1
   1   vcodec  4G ~ 8G larb4/5/7
   2   cam/mdp 8G ~ 12G larb2/9/11/13/14/16/17/18/19/20
   3   CCU00x4000_ ~ 0x43ff_ larb13: port 9/10
   4   CCU10x4400_ ~ 0x47ff_ larb14: port 4/5

The iova range for CCU0/1(camera control unit) is HW requirement.

Signed-off-by: Yong Wu 
Reviewed-by: Rob Herring 
Acked-by: Krzysztof Kozlowski 
---
 .../bindings/iommu/mediatek,iommu.yaml|  18 +-
 include/dt-bindings/memory/mt8192-larb-port.h | 243 ++
 2 files changed, 260 insertions(+), 1 deletion(-)
 create mode 100644 include/dt-bindings/memory/mt8192-larb-port.h

diff --git a/Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml 
b/Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml
index ba6626347381..0f26fe14c8e2 100644
--- a/Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml
+++ b/Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml
@@ -76,6 +76,7 @@ properties:
   - mediatek,mt8167-m4u  # generation two
   - mediatek,mt8173-m4u  # generation two
   - mediatek,mt8183-m4u  # generation two
+  - mediatek,mt8192-m4u  # generation two
 
   - description: mt7623 generation one
 items:
@@ -115,7 +116,11 @@ properties:
   dt-binding/memory/mt6779-larb-port.h for mt6779,
   dt-binding/memory/mt8167-larb-port.h for mt8167,
   dt-binding/memory/mt8173-larb-port.h for mt8173,
-  dt-binding/memory/mt8183-larb-port.h for mt8183.
+  dt-binding/memory/mt8183-larb-port.h for mt8183,
+  dt-binding/memory/mt8192-larb-port.h for mt8192.
+
+  power-domains:
+maxItems: 1
 
 required:
   - compatible
@@ -133,11 +138,22 @@ allOf:
   - mediatek,mt2701-m4u
   - mediatek,mt2712-m4u
   - mediatek,mt8173-m4u
+  - mediatek,mt8192-m4u
 
 then:
   required:
 - clocks
 
+  - if:
+  properties:
+compatible:
+  enum:
+- mediatek,mt8192-m4u
+
+then:
+  required:
+- power-domains
+
 additionalProperties: false
 
 examples:
diff --git a/include/dt-bindings/memory/mt8192-larb-port.h 
b/include/dt-bindings/memory/mt8192-larb-port.h
new file mode 100644
index ..23035a52c675
--- /dev/null
+++ b/include/dt-bindings/memory/mt8192-larb-port.h
@@ -0,0 +1,243 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2020 MediaTek Inc.
+ *
+ * Author: Chao Hao 
+ * Author: Yong Wu 
+ */
+#ifndef _DT_BINDINGS_MEMORY_MT8192_LARB_PORT_H_
+#define _DT_BINDINGS_MEMORY_MT8192_LARB_PORT_H_
+
+#include 
+
+/*
+ * MM IOMMU supports 16GB dma address.
+ *
+ * The address will preassign like this:
+ *
+ * modulesdma-address-region   larbs-ports
+ * disp 0 ~ 4G   larb0/1
+ * vcodec  4G ~ 8G  larb4/5/7
+ * cam/mdp 8G ~ 12G larb2/9/11/13/14/16/17/18/19/20
+ * CCU00x4000_ ~ 0x43ff_ larb13: port 9/10
+ * CCU10x4400_ ~ 0x47ff_ larb14: port 4/5
+ *
+ * larb3/6/8/10/12/15 is null.
+ */
+
+/* larb0 */
+#define M4U_PORT_L0_DISP_POSTMASK0 MTK_M4U_ID(0, 0)
+#define M4U_PORT_L0_OVL_RDMA0_HDR  MTK_M4U_ID(0, 1)
+#define M4U_PORT_L0_OVL_RDMA0  MTK_M4U_ID(0, 2)
+#define M4U_PORT_L0_DISP_RDMA0 MTK_M4U_ID(0, 3)
+#define M4U_PORT_L0_DISP_WDMA0 MTK_M4U_ID(0, 4)
+#define M4U_PORT_L0_DISP_FAKE0 MTK_M4U_ID(0, 5)
+
+/* larb1 */
+#define M4U_PORT_L1_OVL_2L_RDMA0_HDR   MTK_M4U_ID(1, 0)
+#define M4U_PORT_L1_OVL_2L_RDMA2_HDR   MTK_M4U_ID(1, 1)
+#define M4U_PORT_L1_OVL_2L_RDMA0   MTK_M4U_ID(1, 2)
+#define M4U_PORT_L1_OVL_2L_RDMA2   MTK_M4U_ID(1, 3)
+#define M4U_PORT_L1_DISP_MDP_RDMA4 MTK_M4U_ID(1, 4)
+#define M4U_PORT_L1_DISP_RDMA4 MTK_M4U_ID(1, 5)
+#define M4U_PORT_L1_DISP_UFBC_WDMA0MTK_M4U_ID(1, 6)
+#define

[PATCH v6 07/33] iommu: Avoid reallocate default domain for a group

2021-01-11 Thread Yong Wu
If group->default_domain exists, avoid reallocate it.

In some iommu drivers, there may be several devices share a group. Avoid
realloc the default domain for this case.

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

diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 3d099a31ddca..f4b87e6abe80 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -266,7 +266,8 @@ int iommu_probe_device(struct device *dev)
 * support default domains, so the return value is not yet
 * checked.
 */
-   iommu_alloc_default_domain(group, dev);
+   if (!group->default_domain)
+   iommu_alloc_default_domain(group, dev);
 
if (group->default_domain) {
ret = __iommu_attach_device(group->default_domain, dev);
-- 
2.18.0



[PATCH v6 06/33] of/device: Move dma_range_map before of_iommu_configure

2021-01-11 Thread Yong Wu
"dev->dma_range_map" contains the devices' dma_ranges information,
This patch moves dma_range_map before of_iommu_configure. The iommu
driver may need to know the dma_address requirements of its iommu
consumer devices.

CC: Rob Herring 
CC: Frank Rowand 
Signed-off-by: Yong Wu 
---
 drivers/of/device.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/of/device.c b/drivers/of/device.c
index aedfaaafd3e7..1d84636149df 100644
--- a/drivers/of/device.c
+++ b/drivers/of/device.c
@@ -170,9 +170,11 @@ int of_dma_configure_id(struct device *dev, struct 
device_node *np,
dev_dbg(dev, "device is%sdma coherent\n",
coherent ? " " : " not ");
 
+   dev->dma_range_map = map;
iommu = of_iommu_configure(dev, np, id);
if (PTR_ERR(iommu) == -EPROBE_DEFER) {
kfree(map);
+   dev->dma_range_map = NULL;
return -EPROBE_DEFER;
}
 
@@ -181,7 +183,6 @@ int of_dma_configure_id(struct device *dev, struct 
device_node *np,
 
arch_setup_dma_ops(dev, dma_start, size, iommu, coherent);
 
-   dev->dma_range_map = map;
return 0;
 }
 EXPORT_SYMBOL_GPL(of_dma_configure_id);
-- 
2.18.0



[PATCH v6 04/33] dt-bindings: memory: mediatek: Rename header guard for SMI header file

2021-01-11 Thread Yong Wu
Only rename the header guard for all the SoC larb port header file.
No funtional change.

Suggested-by: Krzysztof Kozlowski 
Signed-off-by: Yong Wu 
Acked-by: Krzysztof Kozlowski 
Acked-by: Rob Herring 
---
 include/dt-bindings/memory/mt2701-larb-port.h | 4 ++--
 include/dt-bindings/memory/mt2712-larb-port.h | 4 ++--
 include/dt-bindings/memory/mt6779-larb-port.h | 4 ++--
 include/dt-bindings/memory/mt8167-larb-port.h | 4 ++--
 include/dt-bindings/memory/mt8173-larb-port.h | 4 ++--
 include/dt-bindings/memory/mt8183-larb-port.h | 4 ++--
 6 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/include/dt-bindings/memory/mt2701-larb-port.h 
b/include/dt-bindings/memory/mt2701-larb-port.h
index 2d85c2ec6cfd..25d03526f142 100644
--- a/include/dt-bindings/memory/mt2701-larb-port.h
+++ b/include/dt-bindings/memory/mt2701-larb-port.h
@@ -4,8 +4,8 @@
  * Author: Honghui Zhang 
  */
 
-#ifndef _MT2701_LARB_PORT_H_
-#define _MT2701_LARB_PORT_H_
+#ifndef _DT_BINDINGS_MEMORY_MT2701_LARB_PORT_H_
+#define _DT_BINDINGS_MEMORY_MT2701_LARB_PORT_H_
 
 /*
  * Mediatek m4u generation 1 such as mt2701 has flat m4u port numbers,
diff --git a/include/dt-bindings/memory/mt2712-larb-port.h 
b/include/dt-bindings/memory/mt2712-larb-port.h
index 83e8070b4c1c..e41a2841bcff 100644
--- a/include/dt-bindings/memory/mt2712-larb-port.h
+++ b/include/dt-bindings/memory/mt2712-larb-port.h
@@ -3,8 +3,8 @@
  * Copyright (c) 2017 MediaTek Inc.
  * Author: Yong Wu 
  */
-#ifndef __DTS_IOMMU_PORT_MT2712_H
-#define __DTS_IOMMU_PORT_MT2712_H
+#ifndef _DT_BINDINGS_MEMORY_MT2712_LARB_PORT_H_
+#define _DT_BINDINGS_MEMORY_MT2712_LARB_PORT_H_
 
 #include 
 
diff --git a/include/dt-bindings/memory/mt6779-larb-port.h 
b/include/dt-bindings/memory/mt6779-larb-port.h
index 91b0be285f41..3fb438a96e35 100644
--- a/include/dt-bindings/memory/mt6779-larb-port.h
+++ b/include/dt-bindings/memory/mt6779-larb-port.h
@@ -4,8 +4,8 @@
  * Author: Chao Hao 
  */
 
-#ifndef _DTS_IOMMU_PORT_MT6779_H_
-#define _DTS_IOMMU_PORT_MT6779_H_
+#ifndef _DT_BINDINGS_MEMORY_MT6779_LARB_PORT_H_
+#define _DT_BINDINGS_MEMORY_MT6779_LARB_PORT_H_
 
 #include 
 
diff --git a/include/dt-bindings/memory/mt8167-larb-port.h 
b/include/dt-bindings/memory/mt8167-larb-port.h
index 13925c4fee00..aae57d4824ca 100644
--- a/include/dt-bindings/memory/mt8167-larb-port.h
+++ b/include/dt-bindings/memory/mt8167-larb-port.h
@@ -5,8 +5,8 @@
  * Author: Honghui Zhang 
  * Author: Fabien Parent 
  */
-#ifndef __DTS_IOMMU_PORT_MT8167_H
-#define __DTS_IOMMU_PORT_MT8167_H
+#ifndef _DT_BINDINGS_MEMORY_MT8167_LARB_PORT_H_
+#define _DT_BINDINGS_MEMORY_MT8167_LARB_PORT_H_
 
 #include 
 
diff --git a/include/dt-bindings/memory/mt8173-larb-port.h 
b/include/dt-bindings/memory/mt8173-larb-port.h
index c2379b3236d6..167a7fc51868 100644
--- a/include/dt-bindings/memory/mt8173-larb-port.h
+++ b/include/dt-bindings/memory/mt8173-larb-port.h
@@ -3,8 +3,8 @@
  * Copyright (c) 2015-2016 MediaTek Inc.
  * Author: Yong Wu 
  */
-#ifndef __DTS_IOMMU_PORT_MT8173_H
-#define __DTS_IOMMU_PORT_MT8173_H
+#ifndef _DT_BINDINGS_MEMORY_MT8173_LARB_PORT_H_
+#define _DT_BINDINGS_MEMORY_MT8173_LARB_PORT_H_
 
 #include 
 
diff --git a/include/dt-bindings/memory/mt8183-larb-port.h 
b/include/dt-bindings/memory/mt8183-larb-port.h
index de8bf81b5d9e..36abdf0ce5a2 100644
--- a/include/dt-bindings/memory/mt8183-larb-port.h
+++ b/include/dt-bindings/memory/mt8183-larb-port.h
@@ -3,8 +3,8 @@
  * Copyright (c) 2018 MediaTek Inc.
  * Author: Yong Wu 
  */
-#ifndef __DTS_IOMMU_PORT_MT8183_H
-#define __DTS_IOMMU_PORT_MT8183_H
+#ifndef _DT_BINDINGS_MEMORY_MT8183_LARB_PORT_H_
+#define _DT_BINDINGS_MEMORY_MT8183_LARB_PORT_H_
 
 #include 
 
-- 
2.18.0



[PATCH v6 03/33] dt-bindings: memory: mediatek: Extend LARB_NR_MAX to 32

2021-01-11 Thread Yong Wu
Extend the max larb number definition as mt8192 has larb_nr over 16.

Signed-off-by: Yong Wu 
Acked-by: Rob Herring 
Acked-by: Krzysztof Kozlowski 
---
 Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml | 2 +-
 include/dt-bindings/memory/mtk-memory-port.h| 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml 
b/Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml
index b9946809fc2b..ba6626347381 100644
--- a/Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml
+++ b/Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml
@@ -99,7 +99,7 @@ properties:
   mediatek,larbs:
 $ref: /schemas/types.yaml#/definitions/phandle-array
 minItems: 1
-maxItems: 16
+maxItems: 32
 description: |
   List of phandle to the local arbiters in the current Socs.
   Refer to bindings/memory-controllers/mediatek,smi-larb.yaml. It must sort
diff --git a/include/dt-bindings/memory/mtk-memory-port.h 
b/include/dt-bindings/memory/mtk-memory-port.h
index 53354cf4f6e3..7d64103209af 100644
--- a/include/dt-bindings/memory/mtk-memory-port.h
+++ b/include/dt-bindings/memory/mtk-memory-port.h
@@ -6,10 +6,10 @@
 #ifndef __DT_BINDINGS_MEMORY_MTK_MEMORY_PORT_H_
 #define __DT_BINDINGS_MEMORY_MTK_MEMORY_PORT_H_
 
-#define MTK_LARB_NR_MAX16
+#define MTK_LARB_NR_MAX32
 
 #define MTK_M4U_ID(larb, port) (((larb) << 5) | (port))
-#define MTK_M4U_TO_LARB(id)(((id) >> 5) & 0xf)
+#define MTK_M4U_TO_LARB(id)(((id) >> 5) & 0x1f)
 #define MTK_M4U_TO_PORT(id)((id) & 0x1f)
 
 #endif
-- 
2.18.0



[PATCH v6 02/33] dt-bindings: memory: mediatek: Add a common memory header file

2021-01-11 Thread Yong Wu
Put all the macros about smi larb/port togethers.

Signed-off-by: Yong Wu 
Acked-by: Rob Herring 
Acked-by: Krzysztof Kozlowski 
---
 include/dt-bindings/memory/mt2712-larb-port.h |  2 +-
 include/dt-bindings/memory/mt6779-larb-port.h |  2 +-
 include/dt-bindings/memory/mt8167-larb-port.h |  2 +-
 include/dt-bindings/memory/mt8173-larb-port.h |  2 +-
 include/dt-bindings/memory/mt8183-larb-port.h |  2 +-
 include/dt-bindings/memory/mtk-memory-port.h  | 15 +++
 6 files changed, 20 insertions(+), 5 deletions(-)
 create mode 100644 include/dt-bindings/memory/mtk-memory-port.h

diff --git a/include/dt-bindings/memory/mt2712-larb-port.h 
b/include/dt-bindings/memory/mt2712-larb-port.h
index 6f9aa7349cef..83e8070b4c1c 100644
--- a/include/dt-bindings/memory/mt2712-larb-port.h
+++ b/include/dt-bindings/memory/mt2712-larb-port.h
@@ -6,7 +6,7 @@
 #ifndef __DTS_IOMMU_PORT_MT2712_H
 #define __DTS_IOMMU_PORT_MT2712_H
 
-#define MTK_M4U_ID(larb, port) (((larb) << 5) | (port))
+#include 
 
 #define M4U_LARB0_ID   0
 #define M4U_LARB1_ID   1
diff --git a/include/dt-bindings/memory/mt6779-larb-port.h 
b/include/dt-bindings/memory/mt6779-larb-port.h
index 2ad0899fbf2f..91b0be285f41 100644
--- a/include/dt-bindings/memory/mt6779-larb-port.h
+++ b/include/dt-bindings/memory/mt6779-larb-port.h
@@ -7,7 +7,7 @@
 #ifndef _DTS_IOMMU_PORT_MT6779_H_
 #define _DTS_IOMMU_PORT_MT6779_H_
 
-#define MTK_M4U_ID(larb, port)  (((larb) << 5) | (port))
+#include 
 
 #define M4U_LARB0_ID0
 #define M4U_LARB1_ID1
diff --git a/include/dt-bindings/memory/mt8167-larb-port.h 
b/include/dt-bindings/memory/mt8167-larb-port.h
index 000fb299a408..13925c4fee00 100644
--- a/include/dt-bindings/memory/mt8167-larb-port.h
+++ b/include/dt-bindings/memory/mt8167-larb-port.h
@@ -8,7 +8,7 @@
 #ifndef __DTS_IOMMU_PORT_MT8167_H
 #define __DTS_IOMMU_PORT_MT8167_H
 
-#define MTK_M4U_ID(larb, port) (((larb) << 5) | (port))
+#include 
 
 #define M4U_LARB0_ID   0
 #define M4U_LARB1_ID   1
diff --git a/include/dt-bindings/memory/mt8173-larb-port.h 
b/include/dt-bindings/memory/mt8173-larb-port.h
index 9f31ccfeca21..c2379b3236d6 100644
--- a/include/dt-bindings/memory/mt8173-larb-port.h
+++ b/include/dt-bindings/memory/mt8173-larb-port.h
@@ -6,7 +6,7 @@
 #ifndef __DTS_IOMMU_PORT_MT8173_H
 #define __DTS_IOMMU_PORT_MT8173_H
 
-#define MTK_M4U_ID(larb, port) (((larb) << 5) | (port))
+#include 
 
 #define M4U_LARB0_ID   0
 #define M4U_LARB1_ID   1
diff --git a/include/dt-bindings/memory/mt8183-larb-port.h 
b/include/dt-bindings/memory/mt8183-larb-port.h
index 2c579f305162..de8bf81b5d9e 100644
--- a/include/dt-bindings/memory/mt8183-larb-port.h
+++ b/include/dt-bindings/memory/mt8183-larb-port.h
@@ -6,7 +6,7 @@
 #ifndef __DTS_IOMMU_PORT_MT8183_H
 #define __DTS_IOMMU_PORT_MT8183_H
 
-#define MTK_M4U_ID(larb, port) (((larb) << 5) | (port))
+#include 
 
 #define M4U_LARB0_ID   0
 #define M4U_LARB1_ID   1
diff --git a/include/dt-bindings/memory/mtk-memory-port.h 
b/include/dt-bindings/memory/mtk-memory-port.h
new file mode 100644
index ..53354cf4f6e3
--- /dev/null
+++ b/include/dt-bindings/memory/mtk-memory-port.h
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2020 MediaTek Inc.
+ * Author: Yong Wu 
+ */
+#ifndef __DT_BINDINGS_MEMORY_MTK_MEMORY_PORT_H_
+#define __DT_BINDINGS_MEMORY_MTK_MEMORY_PORT_H_
+
+#define MTK_LARB_NR_MAX16
+
+#define MTK_M4U_ID(larb, port) (((larb) << 5) | (port))
+#define MTK_M4U_TO_LARB(id)(((id) >> 5) & 0xf)
+#define MTK_M4U_TO_PORT(id)((id) & 0x1f)
+
+#endif
-- 
2.18.0



[PATCH v6 01/33] dt-bindings: iommu: mediatek: Convert IOMMU to DT schema

2021-01-11 Thread Yong Wu
Convert MediaTek IOMMU to DT schema.

Signed-off-by: Yong Wu 
Reviewed-by: Rob Herring 
---
 .../bindings/iommu/mediatek,iommu.txt | 105 ---
 .../bindings/iommu/mediatek,iommu.yaml| 167 ++
 2 files changed, 167 insertions(+), 105 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/iommu/mediatek,iommu.txt
 create mode 100644 Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml

diff --git a/Documentation/devicetree/bindings/iommu/mediatek,iommu.txt 
b/Documentation/devicetree/bindings/iommu/mediatek,iommu.txt
deleted file mode 100644
index ac949f7fe3d4..
--- a/Documentation/devicetree/bindings/iommu/mediatek,iommu.txt
+++ /dev/null
@@ -1,105 +0,0 @@
-* Mediatek IOMMU Architecture Implementation
-
-  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:
-
-  EMI (External Memory Interface)
-   |
-  m4u (Multimedia Memory Management Unit)
-   |
-  ++
-  ||
-  gals0-rx   gals1-rx(Global Async Local Sync rx)
-  ||
-  ||
-  gals0-tx   gals1-tx(Global Async Local Sync tx)
-  ||  Some SoCs may have GALS.
-  ++
-   |
-   SMI Common(Smart Multimedia Interface Common)
-   |
-   ++---
-   ||
-   | gals-rxThere may be GALS in some larbs.
-   ||
-   ||
-   | gals-tx
-   ||
-   SMI larb0SMI larb1   ... SoCs have several SMI local arbiter(larb).
-   (display) (vdec)
-   ||
-   ||
- +-+-+ +++
- | | | |||
- | | |...  |||  ... There are different ports in each larb.
- | | | |||
-OVL0 RDMA0 WDMA0  MC   PP   VLD
-
-  As above, The Multimedia HW will go through SMI and M4U while it
-access EMI. SMI is a bridge between m4u and the Multimedia HW. It contain
-smi local arbiter and smi common. It will control whether the Multimedia
-HW should go though the m4u for translation or bypass it and talk
-directly with EMI. And also SMI help control the power domain and clocks for
-each local arbiter.
-  Normally we specify a local arbiter(larb) for each multimedia HW
-like display, video decode, and camera. And there are different ports
-in each larb. Take a example, There are many ports like MC, PP, VLD in the
-video decode local arbiter, all these ports are according to the video HW.
-  In some SoCs, there may be a GALS(Global Async Local Sync) module between
-smi-common and m4u, and additional GALS module between smi-larb and
-smi-common. GALS can been seen as a "asynchronous fifo" which could help
-synchronize for the modules in different clock frequency.
-
-Required properties:
-- compatible : must be one of the following string:
-   "mediatek,mt2701-m4u" for mt2701 which uses generation one m4u HW.
-   "mediatek,mt2712-m4u" for mt2712 which uses generation two m4u HW.
-   "mediatek,mt6779-m4u" for mt6779 which uses generation two m4u HW.
-   "mediatek,mt7623-m4u", "mediatek,mt2701-m4u" for mt7623 which uses
-generation one m4u HW.
-   "mediatek,mt8167-m4u" for mt8167 which uses generation two m4u HW.
-   "mediatek,mt8173-m4u" for mt8173 which uses generation two m4u HW.
-   "mediatek,mt8183-m4u" for mt8183 which uses generation two m4u HW.
-- reg : m4u register base and size.
-- interrupts : the interrupt of m4u.
-- clocks : must contain one entry for each clock-names.
-- clock-names : Only 1 optional clock:
-  - "bclk": the block clock of m4u.
-  Here is the list which require this "bclk":
-  - mt2701, mt2712, mt7623 and mt8173.
-  Note that m4u use the EMI clock which always has been enabled before kernel
-  if there is no this "bclk".
-- mediatek,larbs : List of phandle to the local arbiters in the current Socs.
-   Refer to bindings/memory-controllers/mediatek,smi-larb.txt. It must sort
-   according to the local arbiter index, like larb0, larb1, larb2...
-- iommu-cells : must be 1. This is the mtk_m4u_id according to the HW.
-   Specifies the mtk_m4u_id as defined in
-   dt-binding/memory/mt2701-larb-port.h for mt2701, mt7623
-   dt-binding/memory/mt2712-larb-port.h for mt2712,
-   dt-binding/memory/mt6779-larb-port.h for mt6779,
-   dt-binding/memory/mt8167-la

[PATCH v6 00/33] MT8192 IOMMU support

2021-01-11 Thread Yong Wu
This patch mainly adds support for mt8192 Multimedia IOMMU and SMI.

mt8192 also is MTK IOMMU gen2 which uses ARM Short-Descriptor translation
table format. The M4U-SMI HW diagram is as below:

  EMI
   |
  M4U
   |
  
   SMI Common
  
   |
  +---+--+--+--+---+
  |   |  |  |   .. |   |
  |   |  |  |  |   |
larb0   larb1  larb2  larb4 ..  larb19   larb20
disp0   disp1   mdpvdec   IPE  IPE

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

Comparing with the preview SoC, this patchset mainly adds two new functions:
a) add iova 34 bits support.
b) add multi domains support since several HW has the special iova
region requirement.

change note:
v6:a) base on v5.11-rc1. and tlb v4:
  
https://lore.kernel.org/linux-mediatek/20210107122909.16317-1-yong...@mediatek.com/T/#t
 
   b) Remove the "domain id" definition in the binding header file.
  Get the domain from dev->dma_range_map.
  After this, Change many codes flow.
   c) the patchset adds a new common file(mtk_smi-larb-port.h).
  This version changes that name into mtk-memory-port.h which reflect 
  its file path. This only changes the file name. no other change.
  thus I keep all the Reviewed-by Tags.
  (another reason is that we will add some iommu ports unrelated with
   smi-larb)
   d) Refactor the power-domain flow suggestted by Tomasz.
   e) Some other small fix. use different oas for different soc; Change the
   macro for 34bit iova tlb flush.

v5: 
https://lore.kernel.org/linux-iommu/20201209080102.26626-1-yong...@mediatek.com/
a) Add a new patch for the header guard for smi-larb-port.h in [5/27].
b) Add a new patch for error handle for iommu_device_sysfs_add and
 iommu_device_register[15/27].
c) Add a flag for the iova "ias == 34" case. the previous SoC still keep
 32bits to save 16KB*3 lvl1 pgtable memory[13/27].
d) Add include  for FIELD_GET build fail.
e) In PM power domain patch, add a checking "pm_runtime_enabled" when call
 pm_runtime_get_sync for non power-domain case. and add a pm_runtime_put_noidle
 while pm_runtime_get_sync fail case.

v4: 
https://lore.kernel.org/linux-iommu/2020123838.15682-1-yong...@mediatek.com/
  a) rebase on v5.10-rc1
  b) Move the smi part to a independent patchset.
  c) Improve v7s code from Robin and Will.
  d) Add a mediatek iommu entry patch in MAINTAIN.

v3: 
https://lore.kernel.org/linux-iommu/20200930070647.10188-1-yong...@mediatek.com/
  a) Fix DT schema issue commented from Rob.
  b) Fix a v7s issue. Use "_lvl" instead of "_l" in the 
macro(ARM_V7S_PTES_PER_LVL) since 
  it is called in ARM_V7S_LVL_IDX which has already used "_l".
  c) Fix a PM suspend issue: Avoid pm suspend in pm runtime case.

v2: 
https://lore.kernel.org/linux-iommu/20200905080920.13396-1-yong...@mediatek.com/
  a) Convert IOMMU/SMI dt-binding to DT schema.
  b) Fix some comment from Pi-Hsun and Nicolas. like use
  generic_iommu_put_resv_regions.
  c) Reword some comment, like add how to use domain-id.

v1: 
https://lore.kernel.org/linux-iommu/20200711064846.16007-1-yong...@mediatek.com/

Yong Wu (33):
  dt-bindings: iommu: mediatek: Convert IOMMU to DT schema
  dt-bindings: memory: mediatek: Add a common memory header file
  dt-bindings: memory: mediatek: Extend LARB_NR_MAX to 32
  dt-bindings: memory: mediatek: Rename header guard for SMI header file
  dt-bindings: mediatek: Add binding for mt8192 IOMMU
  of/device: Move dma_range_map before of_iommu_configure
  iommu: Avoid reallocate default domain for a group
  iommu/mediatek: Use the common mtk-memory-port.h
  iommu/io-pgtable-arm-v7s: Use ias to check the valid iova in unmap
  iommu/io-pgtable-arm-v7s: Extend PA34 for MediaTek
  iommu/io-pgtable-arm-v7s: Clarify LVL_SHIFT/BITS macro
  iommu/io-pgtable-arm-v7s: Add cfg as a param in some macros
  iommu/io-pgtable-arm-v7s: Quad lvl1 pgtable for MediaTek
  iommu/mediatek: Add a flag for iova 34bits case
  iommu/mediatek: Update oas for v7s
  iommu/mediatek: Move hw_init into attach_device
  iommu/mediatek: Add error handle for mtk_iommu_probe
  iommu/mediatek: Add device link for smi-common and m4u
  iommu/mediatek: Add pm runtime callback
  iommu/mediatek: Add power-domain operation
  iommu/mediatek: Support up to 34bit iova in tlb flush
  iommu/mediatek: Support report iova 34bit translation fault in ISR
  iommu/mediatek: Adjust the structure
  iommu/mediatek: Move domain_finalise into attach_device
  iommu/mediatek: Move geometry.aperture updating into domain_finalise
  iommu/mediatek: Add iova_region structure
  iommu/mediatek: Add get_domain_id from dev->dma_rang

[PATCH v4 1/7] iommu: Move iotlb_sync_map out from __iommu_map

2021-01-07 Thread Yong Wu
In the end of __iommu_map, It alway call iotlb_sync_map.

This patch moves iotlb_sync_map out from __iommu_map since it is
unnecessary to call this for each sg segment especially iotlb_sync_map
is flush tlb all currently. Add a little helper _iommu_map for this.

Signed-off-by: Yong Wu 
Reviewed-by: Robin Murphy 
---
 drivers/iommu/iommu.c | 23 ++-
 1 file changed, 18 insertions(+), 5 deletions(-)

diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index ffeebda8d6de..c304a6a30d42 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -2426,9 +2426,6 @@ static int __iommu_map(struct iommu_domain *domain, 
unsigned long iova,
size -= pgsize;
}
 
-   if (ops->iotlb_sync_map)
-   ops->iotlb_sync_map(domain);
-
/* unroll mapping in case something went wrong */
if (ret)
iommu_unmap(domain, orig_iova, orig_size - size);
@@ -2438,18 +2435,31 @@ static int __iommu_map(struct iommu_domain *domain, 
unsigned long iova,
return ret;
 }
 
+static int _iommu_map(struct iommu_domain *domain, unsigned long iova,
+ phys_addr_t paddr, size_t size, int prot, gfp_t gfp)
+{
+   const struct iommu_ops *ops = domain->ops;
+   int ret;
+
+   ret = __iommu_map(domain, iova, paddr, size, prot, GFP_KERNEL);
+   if (ret == 0 && ops->iotlb_sync_map)
+   ops->iotlb_sync_map(domain);
+
+   return ret;
+}
+
 int iommu_map(struct iommu_domain *domain, unsigned long iova,
  phys_addr_t paddr, size_t size, int prot)
 {
might_sleep();
-   return __iommu_map(domain, iova, paddr, size, prot, GFP_KERNEL);
+   return _iommu_map(domain, iova, paddr, size, prot, GFP_KERNEL);
 }
 EXPORT_SYMBOL_GPL(iommu_map);
 
 int iommu_map_atomic(struct iommu_domain *domain, unsigned long iova,
  phys_addr_t paddr, size_t size, int prot)
 {
-   return __iommu_map(domain, iova, paddr, size, prot, GFP_ATOMIC);
+   return _iommu_map(domain, iova, paddr, size, prot, GFP_ATOMIC);
 }
 EXPORT_SYMBOL_GPL(iommu_map_atomic);
 
@@ -2533,6 +2543,7 @@ static size_t __iommu_map_sg(struct iommu_domain *domain, 
unsigned long iova,
 struct scatterlist *sg, unsigned int nents, int 
prot,
 gfp_t gfp)
 {
+   const struct iommu_ops *ops = domain->ops;
size_t len = 0, mapped = 0;
phys_addr_t start;
unsigned int i = 0;
@@ -2563,6 +2574,8 @@ static size_t __iommu_map_sg(struct iommu_domain *domain, 
unsigned long iova,
sg = sg_next(sg);
}
 
+   if (ops->iotlb_sync_map)
+   ops->iotlb_sync_map(domain);
return mapped;
 
 out_err:
-- 
2.18.0



[PATCH v4 4/7] iommu: Switch gather->end to the inclusive end

2021-01-07 Thread Yong Wu
Currently gather->end is "unsigned long" which may be overflow in
arch32 in the corner case: 0xfff0 + 0x10(iova + size).
Although it doesn't affect the size(end - start), it affects the checking
"gather->end < end"

This patch changes this "end" to the real end address
(end = start + size - 1). Correspondingly, update the length to
"end - start + 1".

Fixes: a7d20dc19d9e ("iommu: Introduce struct iommu_iotlb_gather for batching 
TLB flushes")
Signed-off-by: Yong Wu 
---
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 2 +-
 drivers/iommu/mtk_iommu.c   | 2 +-
 drivers/iommu/tegra-gart.c  | 2 +-
 include/linux/iommu.h   | 4 ++--
 4 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c 
b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
index 8ca7415d785d..c70d6e79f534 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -2280,7 +2280,7 @@ static void arm_smmu_iotlb_sync(struct iommu_domain 
*domain,
 {
struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
 
-   arm_smmu_tlb_inv_range(gather->start, gather->end - gather->start,
+   arm_smmu_tlb_inv_range(gather->start, gather->end - gather->start + 1,
   gather->pgsize, true, smmu_domain);
 }
 
diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index f579fc21971e..66a00a2cb445 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -443,7 +443,7 @@ static void mtk_iommu_iotlb_sync(struct iommu_domain 
*domain,
 struct iommu_iotlb_gather *gather)
 {
struct mtk_iommu_data *data = mtk_iommu_get_m4u_data();
-   size_t length = gather->end - gather->start;
+   size_t length = gather->end - gather->start + 1;
 
if (gather->start == ULONG_MAX)
return;
diff --git a/drivers/iommu/tegra-gart.c b/drivers/iommu/tegra-gart.c
index 05e8e19b8269..6f130e51f072 100644
--- a/drivers/iommu/tegra-gart.c
+++ b/drivers/iommu/tegra-gart.c
@@ -270,7 +270,7 @@ static void gart_iommu_sync_map(struct iommu_domain 
*domain, unsigned long iova,
 static void gart_iommu_sync(struct iommu_domain *domain,
struct iommu_iotlb_gather *gather)
 {
-   size_t length = gather->end - gather->start;
+   size_t length = gather->end - gather->start + 1;
 
gart_iommu_sync_map(domain, gather->start, length);
 }
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index 9ce0aa9e236b..ae8eddd4621b 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -170,7 +170,7 @@ enum iommu_dev_features {
  * struct iommu_iotlb_gather - Range information for a pending IOTLB flush
  *
  * @start: IOVA representing the start of the range to be flushed
- * @end: IOVA representing the end of the range to be flushed (exclusive)
+ * @end: IOVA representing the end of the range to be flushed (inclusive)
  * @pgsize: The interval at which to perform the flush
  *
  * This structure is intended to be updated by multiple calls to the
@@ -539,7 +539,7 @@ static inline void iommu_iotlb_gather_add_page(struct 
iommu_domain *domain,
   struct iommu_iotlb_gather 
*gather,
   unsigned long iova, size_t size)
 {
-   unsigned long start = iova, end = start + size;
+   unsigned long start = iova, end = start + size - 1;
 
/*
 * If the new page is disjoint from the current range or is mapped at
-- 
2.18.0



[PATCH v4 6/7] iommu/mediatek: Gather iova in iommu_unmap to achieve tlb sync once

2021-01-07 Thread Yong Wu
In current iommu_unmap, this code is:

iommu_iotlb_gather_init(_gather);
ret = __iommu_unmap(domain, iova, size, _gather);
iommu_iotlb_sync(domain, _gather);

We could gather the whole iova range in __iommu_unmap, and then do tlb
synchronization in the iommu_iotlb_sync.

This patch implement this, Gather the range in mtk_iommu_unmap.
then iommu_iotlb_sync call tlb synchronization for the gathered iova range.
we don't call iommu_iotlb_gather_add_page since our tlb synchronization
could be regardless of granule size.

In this way, gather->start is impossible ULONG_MAX, remove the checking.

This patch aims to do tlb synchronization *once* in the iommu_unmap.

Signed-off-by: Yong Wu 
---
 drivers/iommu/mtk_iommu.c | 8 +---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index 66a00a2cb445..d3b8a1649093 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -430,7 +430,12 @@ static size_t mtk_iommu_unmap(struct iommu_domain *domain,
  struct iommu_iotlb_gather *gather)
 {
struct mtk_iommu_domain *dom = to_mtk_domain(domain);
+   unsigned long end = iova + size - 1;
 
+   if (gather->start > iova)
+   gather->start = iova;
+   if (gather->end < end)
+   gather->end = end;
return dom->iop->unmap(dom->iop, iova, size, gather);
 }
 
@@ -445,9 +450,6 @@ static void mtk_iommu_iotlb_sync(struct iommu_domain 
*domain,
struct mtk_iommu_data *data = mtk_iommu_get_m4u_data();
size_t length = gather->end - gather->start + 1;
 
-   if (gather->start == ULONG_MAX)
-   return;
-
mtk_iommu_tlb_flush_range_sync(gather->start, length, gather->pgsize,
   data);
 }
-- 
2.18.0



[PATCH v4 7/7] iommu/mediatek: Remove the tlb-ops for v7s

2021-01-07 Thread Yong Wu
Until now, we have already used the tlb operations from iommu framework,
then the tlb operations for v7s can be removed.

Correspondingly, Switch the paramenter "cookie" to the internal structure.

Signed-off-by: Yong Wu 
---
 drivers/iommu/mtk_iommu.c | 27 ---
 1 file changed, 4 insertions(+), 23 deletions(-)

diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index d3b8a1649093..86ab577c9520 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -182,10 +182,8 @@ 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)
+static void mtk_iommu_tlb_flush_all(struct mtk_iommu_data *data)
 {
-   struct mtk_iommu_data *data = cookie;
-
for_each_m4u(data) {
writel_relaxed(F_INVLD_EN1 | F_INVLD_EN0,
   data->base + data->plat_data->inv_sel_reg);
@@ -195,9 +193,9 @@ static void mtk_iommu_tlb_flush_all(void *cookie)
 }
 
 static void mtk_iommu_tlb_flush_range_sync(unsigned long iova, size_t size,
-  size_t granule, void *cookie)
+  size_t granule,
+  struct mtk_iommu_data *data)
 {
-   struct mtk_iommu_data *data = cookie;
unsigned long flags;
int ret;
u32 tmp;
@@ -219,7 +217,7 @@ static void mtk_iommu_tlb_flush_range_sync(unsigned long 
iova, size_t size,
if (ret) {
dev_warn(data->dev,
 "Partial TLB flush timed out, falling back to 
full flush\n");
-   mtk_iommu_tlb_flush_all(cookie);
+   mtk_iommu_tlb_flush_all(data);
}
/* Clear the CPE status */
writel_relaxed(0, data->base + REG_MMU_CPE_DONE);
@@ -227,22 +225,6 @@ static void mtk_iommu_tlb_flush_range_sync(unsigned long 
iova, size_t size,
}
 }
 
-static void mtk_iommu_tlb_flush_page_nosync(struct iommu_iotlb_gather *gather,
-   unsigned long iova, size_t granule,
-   void *cookie)
-{
-   struct mtk_iommu_data *data = cookie;
-   struct iommu_domain *domain = >m4u_dom->domain;
-
-   iommu_iotlb_gather_add_page(domain, gather, iova, granule);
-}
-
-static const struct iommu_flush_ops mtk_iommu_flush_ops = {
-   .tlb_flush_all = mtk_iommu_tlb_flush_all,
-   .tlb_flush_walk = mtk_iommu_tlb_flush_range_sync,
-   .tlb_add_page = mtk_iommu_tlb_flush_page_nosync,
-};
-
 static irqreturn_t mtk_iommu_isr(int irq, void *dev_id)
 {
struct mtk_iommu_data *data = dev_id;
@@ -326,7 +308,6 @@ static int mtk_iommu_domain_finalise(struct 
mtk_iommu_domain *dom)
.pgsize_bitmap = mtk_iommu_ops.pgsize_bitmap,
.ias = 32,
.oas = 34,
-   .tlb = _iommu_flush_ops,
.iommu_dev = data->dev,
};
 
-- 
2.18.0



[PATCH v4 5/7] iommu/io-pgtable: Allow io_pgtable_tlb ops optional

2021-01-07 Thread Yong Wu
This patch allows io_pgtable_tlb ops could be null since the IOMMU drivers
may use the tlb ops from iommu framework.

Signed-off-by: Yong Wu 
---
 include/linux/io-pgtable.h | 8 +---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/include/linux/io-pgtable.h b/include/linux/io-pgtable.h
index ea727eb1a1a9..2a5686ca2ba3 100644
--- a/include/linux/io-pgtable.h
+++ b/include/linux/io-pgtable.h
@@ -214,14 +214,16 @@ struct io_pgtable_domain_attr {
 
 static inline void io_pgtable_tlb_flush_all(struct io_pgtable *iop)
 {
-   iop->cfg.tlb->tlb_flush_all(iop->cookie);
+   if (iop->cfg.tlb && iop->cfg.tlb->tlb_flush_all)
+   iop->cfg.tlb->tlb_flush_all(iop->cookie);
 }
 
 static inline void
 io_pgtable_tlb_flush_walk(struct io_pgtable *iop, unsigned long iova,
  size_t size, size_t granule)
 {
-   iop->cfg.tlb->tlb_flush_walk(iova, size, granule, iop->cookie);
+   if (iop->cfg.tlb && iop->cfg.tlb->tlb_flush_walk)
+   iop->cfg.tlb->tlb_flush_walk(iova, size, granule, iop->cookie);
 }
 
 static inline void
@@ -229,7 +231,7 @@ io_pgtable_tlb_add_page(struct io_pgtable *iop,
struct iommu_iotlb_gather * gather, unsigned long iova,
size_t granule)
 {
-   if (iop->cfg.tlb->tlb_add_page)
+   if (iop->cfg.tlb && iop->cfg.tlb->tlb_add_page)
iop->cfg.tlb->tlb_add_page(gather, iova, granule, iop->cookie);
 }
 
-- 
2.18.0



[PATCH v4 2/7] iommu: Add iova and size as parameters in iotlb_sync_map

2021-01-07 Thread Yong Wu
iotlb_sync_map allow IOMMU drivers tlb sync after completing the whole
mapping. This patch adds iova and size as the parameters in it. then the
IOMMU driver could flush tlb with the whole range once after iova mapping
to improve performance.

Signed-off-by: Yong Wu 
Reviewed-by: Robin Murphy 
---
 drivers/iommu/iommu.c  | 4 ++--
 drivers/iommu/tegra-gart.c | 7 +--
 include/linux/iommu.h  | 3 ++-
 3 files changed, 9 insertions(+), 5 deletions(-)

diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index c304a6a30d42..3d099a31ddca 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -2443,7 +2443,7 @@ static int _iommu_map(struct iommu_domain *domain, 
unsigned long iova,
 
ret = __iommu_map(domain, iova, paddr, size, prot, GFP_KERNEL);
if (ret == 0 && ops->iotlb_sync_map)
-   ops->iotlb_sync_map(domain);
+   ops->iotlb_sync_map(domain, iova, size);
 
return ret;
 }
@@ -2575,7 +2575,7 @@ static size_t __iommu_map_sg(struct iommu_domain *domain, 
unsigned long iova,
}
 
if (ops->iotlb_sync_map)
-   ops->iotlb_sync_map(domain);
+   ops->iotlb_sync_map(domain, iova, mapped);
return mapped;
 
 out_err:
diff --git a/drivers/iommu/tegra-gart.c b/drivers/iommu/tegra-gart.c
index fac720273889..05e8e19b8269 100644
--- a/drivers/iommu/tegra-gart.c
+++ b/drivers/iommu/tegra-gart.c
@@ -261,7 +261,8 @@ static int gart_iommu_of_xlate(struct device *dev,
return 0;
 }
 
-static void gart_iommu_sync_map(struct iommu_domain *domain)
+static void gart_iommu_sync_map(struct iommu_domain *domain, unsigned long 
iova,
+   size_t size)
 {
FLUSH_GART_REGS(gart_handle);
 }
@@ -269,7 +270,9 @@ static void gart_iommu_sync_map(struct iommu_domain *domain)
 static void gart_iommu_sync(struct iommu_domain *domain,
struct iommu_iotlb_gather *gather)
 {
-   gart_iommu_sync_map(domain);
+   size_t length = gather->end - gather->start;
+
+   gart_iommu_sync_map(domain, gather->start, length);
 }
 
 static const struct iommu_ops gart_iommu_ops = {
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index b3f0e2018c62..9ce0aa9e236b 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -246,7 +246,8 @@ struct iommu_ops {
size_t (*unmap)(struct iommu_domain *domain, unsigned long iova,
 size_t size, struct iommu_iotlb_gather *iotlb_gather);
void (*flush_iotlb_all)(struct iommu_domain *domain);
-   void (*iotlb_sync_map)(struct iommu_domain *domain);
+   void (*iotlb_sync_map)(struct iommu_domain *domain, unsigned long iova,
+  size_t size);
void (*iotlb_sync)(struct iommu_domain *domain,
   struct iommu_iotlb_gather *iotlb_gather);
phys_addr_t (*iova_to_phys)(struct iommu_domain *domain, dma_addr_t 
iova);
-- 
2.18.0



[PATCH v4 0/7] MediaTek IOMMU improve tlb flush performance in map/unmap

2021-01-07 Thread Yong Wu
This patchset is to improve tlb flushing performance in iommu_map/unmap
for MediaTek IOMMU.

For iommu_map, currently MediaTek IOMMU use IO_PGTABLE_QUIRK_TLBI_ON_MAP
to do tlb_flush for each a memory chunk. this is so unnecessary. we could
improve it by tlb flushing one time at the end of iommu_map.

For iommu_unmap, currently we have already improve this performance by
gather. But the current gather should take care its granule size. if the
granule size is different, it will do tlb flush and gather again. Our HW
don't care about granule size. thus I gather the range in our file.

After this patchset, we could achieve only tlb flushing once in iommu_map
and iommu_unmap.

Regardless of sg, for each a segment, I did a simple test:
  
  size = 20 * SZ_1M;
  /* the worst case, all are 4k mapping. */
  ret = iommu_map(domain, 0x5bb02000, 0x123f1000, size, IOMMU_READ);
  iommu_unmap(domain, 0x5bb02000, size);

This is the comparing time(unit is us):
  original-time  after-improve
   map-20M59943   2347
   unmap-20M  264 36

This patchset also flush tlb once in the iommu_map_sg case.

patch [1/7][2/7][3/7] are for map while the others are for unmap.

change note:
v4: a. base on v5.11-rc1.
b. Add a little helper _iommu_map.
c. Fix a build fail for tegra-gart.c. I didn't notice there is another place
call gart_iommu_sync_map.
d. Switch gather->end to the read end address("start + end - 1").

v3: 
https://lore.kernel.org/linux-iommu/20201216103607.23050-1-yong...@mediatek.com/#r
Refactor the unmap flow suggested by Robin.
 
v2: 
https://lore.kernel.org/linux-iommu/20201119061836.15238-1-yong...@mediatek.com/
Refactor all the code.
base on v5.10-rc1.

Yong Wu (7):
  iommu: Move iotlb_sync_map out from __iommu_map
  iommu: Add iova and size as parameters in iotlb_sync_map
  iommu/mediatek: Add iotlb_sync_map to sync whole the iova range
  iommu: Switch gather->end to the inclusive end
  iommu/io-pgtable: Allow io_pgtable_tlb ops optional
  iommu/mediatek: Gather iova in iommu_unmap to achieve tlb sync once
  iommu/mediatek: Remove the tlb-ops for v7s

 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c |  2 +-
 drivers/iommu/iommu.c   | 23 +++---
 drivers/iommu/mtk_iommu.c   | 47 +
 drivers/iommu/tegra-gart.c  |  7 ++-
 include/linux/io-pgtable.h  |  8 ++--
 include/linux/iommu.h   |  7 +--
 6 files changed, 52 insertions(+), 42 deletions(-)

-- 
2.18.0




[PATCH v4 3/7] iommu/mediatek: Add iotlb_sync_map to sync whole the iova range

2021-01-07 Thread Yong Wu
Remove IO_PGTABLE_QUIRK_TLBI_ON_MAP to avoid tlb sync for each a small
chunk memory, Use the new iotlb_sync_map to tlb_sync once for whole the
iova range of iommu_map.

Signed-off-by: Yong Wu 
Reviewed-by: Robin Murphy 
---
 drivers/iommu/mtk_iommu.c | 10 +-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index 8e56cec532e7..f579fc21971e 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -322,7 +322,6 @@ static int mtk_iommu_domain_finalise(struct 
mtk_iommu_domain *dom)
dom->cfg = (struct io_pgtable_cfg) {
.quirks = IO_PGTABLE_QUIRK_ARM_NS |
IO_PGTABLE_QUIRK_NO_PERMS |
-   IO_PGTABLE_QUIRK_TLBI_ON_MAP |
IO_PGTABLE_QUIRK_ARM_MTK_EXT,
.pgsize_bitmap = mtk_iommu_ops.pgsize_bitmap,
.ias = 32,
@@ -453,6 +452,14 @@ static void mtk_iommu_iotlb_sync(struct iommu_domain 
*domain,
   data);
 }
 
+static void mtk_iommu_sync_map(struct iommu_domain *domain, unsigned long iova,
+  size_t size)
+{
+   struct mtk_iommu_data *data = mtk_iommu_get_m4u_data();
+
+   mtk_iommu_tlb_flush_range_sync(iova, size, size, data);
+}
+
 static phys_addr_t mtk_iommu_iova_to_phys(struct iommu_domain *domain,
  dma_addr_t iova)
 {
@@ -539,6 +546,7 @@ static const struct iommu_ops mtk_iommu_ops = {
.unmap  = mtk_iommu_unmap,
.flush_iotlb_all = mtk_iommu_flush_iotlb_all,
.iotlb_sync = mtk_iommu_iotlb_sync,
+   .iotlb_sync_map = mtk_iommu_sync_map,
.iova_to_phys   = mtk_iommu_iova_to_phys,
.probe_device   = mtk_iommu_probe_device,
.release_device = mtk_iommu_release_device,
-- 
2.18.0



Re: [PATCH v5 16/27] iommu/mediatek: Add device link for smi-common and m4u

2020-12-29 Thread Yong Wu
On Wed, 2020-12-23 at 17:29 +0900, Tomasz Figa wrote:
> On Wed, Dec 09, 2020 at 04:00:51PM +0800, Yong Wu wrote:
> > In the lastest SoC, M4U has its special power domain. thus, If the engine
> > begin to work, it should help enable the power for M4U firstly.
> > Currently if the engine work, it always enable the power/clocks for
> > smi-larbs/smi-common. This patch adds device_link for smi-common and M4U.
> > then, if smi-common power is enabled, the M4U power also is powered on
> > automatically.
> > 
> > Normally M4U connect with several smi-larbs and their smi-common always
> > are the same, In this patch it get smi-common dev from the first smi-larb
> > device(i==0), then add the device_link only while m4u has power-domain.
> > 
> > Signed-off-by: Yong Wu 
> > ---
> >  drivers/iommu/mtk_iommu.c | 30 --
> >  drivers/iommu/mtk_iommu.h |  1 +
> >  2 files changed, 29 insertions(+), 2 deletions(-)
> > 
> > diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
> > index 09c8c58feb78..5614015e5b96 100644
> > --- a/drivers/iommu/mtk_iommu.c
> > +++ b/drivers/iommu/mtk_iommu.c
> > @@ -20,6 +20,7 @@
> >  #include 
> >  #include 
> >  #include 
> > +#include 
> >  #include 
> >  #include 
> >  #include 
> > @@ -706,7 +707,7 @@ static int mtk_iommu_probe(struct platform_device *pdev)
> > return larb_nr;
> >  
> > for (i = 0; i < larb_nr; i++) {
> > -   struct device_node *larbnode;
> > +   struct device_node *larbnode, *smicomm_node;
> > struct platform_device *plarbdev;
> > u32 id;
> >  
> > @@ -732,6 +733,26 @@ static int mtk_iommu_probe(struct platform_device 
> > *pdev)
> >  
> > component_match_add_release(dev, , release_of,
> > compare_of, larbnode);
> > +   if (i != 0)
> > +   continue;
> 
> How about using the last larb instead and moving the code below outside
> of the loop?

Of course OK. Thanks.



Re: [PATCH v5 09/27] iommu/io-pgtable-arm-v7s: Extend PA34 for MediaTek

2020-12-29 Thread Yong Wu
On Wed, 2020-12-23 at 17:20 +0900, Tomasz Figa wrote:
> On Wed, Dec 09, 2020 at 04:00:44PM +0800, Yong Wu wrote:
> > MediaTek extend the bit5 in lvl1 and lvl2 descriptor as PA34.
> > 
> > Signed-off-by: Yong Wu 
> > Acked-by: Will Deacon 
> > Reviewed-by: Robin Murphy 
> > ---
> >  drivers/iommu/io-pgtable-arm-v7s.c | 9 +++--
> >  drivers/iommu/mtk_iommu.c  | 2 +-
> >  include/linux/io-pgtable.h | 4 ++--
> >  3 files changed, 10 insertions(+), 5 deletions(-)
> > 
> > diff --git a/drivers/iommu/io-pgtable-arm-v7s.c 
> > b/drivers/iommu/io-pgtable-arm-v7s.c
> > index e880745ab1e8..4d0aa079470f 100644
> > --- a/drivers/iommu/io-pgtable-arm-v7s.c
> > +++ b/drivers/iommu/io-pgtable-arm-v7s.c
> > @@ -112,9 +112,10 @@
> >  #define ARM_V7S_TEX_MASK   0x7
> >  #define ARM_V7S_ATTR_TEX(val)  (((val) & ARM_V7S_TEX_MASK) << 
> > ARM_V7S_TEX_SHIFT)
> >  
> > -/* MediaTek extend the two bits for PA 32bit/33bit */
> > +/* MediaTek extend the bits below for PA 32bit/33bit/34bit */
> >  #define ARM_V7S_ATTR_MTK_PA_BIT32  BIT(9)
> >  #define ARM_V7S_ATTR_MTK_PA_BIT33  BIT(4)
> > +#define ARM_V7S_ATTR_MTK_PA_BIT34  BIT(5)
> >  
> >  /* *well, except for TEX on level 2 large pages, of course :( */
> >  #define ARM_V7S_CONT_PAGE_TEX_SHIFT6
> > @@ -194,6 +195,8 @@ static arm_v7s_iopte paddr_to_iopte(phys_addr_t paddr, 
> > int lvl,
> > pte |= ARM_V7S_ATTR_MTK_PA_BIT32;
> > if (paddr & BIT_ULL(33))
> > pte |= ARM_V7S_ATTR_MTK_PA_BIT33;
> > +   if (paddr & BIT_ULL(34))
> > +   pte |= ARM_V7S_ATTR_MTK_PA_BIT34;
> > return pte;
> >  }
> >  
> > @@ -218,6 +221,8 @@ static phys_addr_t iopte_to_paddr(arm_v7s_iopte pte, 
> > int lvl,
> > paddr |= BIT_ULL(32);
> > if (pte & ARM_V7S_ATTR_MTK_PA_BIT33)
> > paddr |= BIT_ULL(33);
> > +   if (pte & ARM_V7S_ATTR_MTK_PA_BIT34)
> > +   paddr |= BIT_ULL(34);
> > return paddr;
> >  }
> >  
> > @@ -754,7 +759,7 @@ static struct io_pgtable *arm_v7s_alloc_pgtable(struct 
> > io_pgtable_cfg *cfg,
> > if (cfg->ias > ARM_V7S_ADDR_BITS)
> > return NULL;
> >  
> > -   if (cfg->oas > (arm_v7s_is_mtk_enabled(cfg) ? 34 : ARM_V7S_ADDR_BITS))
> > +   if (cfg->oas > (arm_v7s_is_mtk_enabled(cfg) ? 35 : ARM_V7S_ADDR_BITS))
> > return NULL;
> >  
> > if (cfg->quirks & ~(IO_PGTABLE_QUIRK_ARM_NS |
> > diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
> > index 6451d83753e1..ec3c87d4b172 100644
> > --- a/drivers/iommu/mtk_iommu.c
> > +++ b/drivers/iommu/mtk_iommu.c
> > @@ -320,7 +320,7 @@ static int mtk_iommu_domain_finalise(struct 
> > mtk_iommu_domain *dom)
> > IO_PGTABLE_QUIRK_ARM_MTK_EXT,
> > .pgsize_bitmap = mtk_iommu_ops.pgsize_bitmap,
> > .ias = 32,
> > -   .oas = 34,
> > +   .oas = 35,
> 
> Shouldn't this be set according to the real hardware capabilities,
> instead of always setting it to 35?

Here only make the code clean. 35 is ok for all the SoC.
But you are right from the HW point, the logic is like this:

if (MTK_IOMMU_HAS_FLAG(data->plat_data, HAS_4GB_MODE))
dom->cfg.oas = data->enable_4GB ? 33 : 32;
else
dom->cfg.oas = 35;

I will use this in next version.

> 
> Best regards,
> Tomasz
> 
> > .tlb = _iommu_flush_ops,
> > .iommu_dev = data->dev,
> > };
> > diff --git a/include/linux/io-pgtable.h b/include/linux/io-pgtable.h
> > index 4cde111e425b..1ae0757f4f94 100644
> > --- a/include/linux/io-pgtable.h
> > +++ b/include/linux/io-pgtable.h
> > @@ -77,8 +77,8 @@ struct io_pgtable_cfg {
> >  *  TLB maintenance when mapping as well as when unmapping.
> >  *
> >  * IO_PGTABLE_QUIRK_ARM_MTK_EXT: (ARM v7s format) MediaTek IOMMUs extend
> > -*  to support up to 34 bits PA where the bit32 and bit33 are
> > -*  encoded in the bit9 and bit4 of the PTE respectively.
> > +*  to support up to 35 bits PA where the bit32, bit33 and bit34 are
> > +*  encoded in the bit9, bit4 and bit5 of the PTE respectively.
> >  *
> >  * IO_PGTABLE_QUIRK_NON_STRICT: Skip issuing synchronous leaf TLBIs
> >  *  on unmap, for DMA domains using the flush queue mechanism for
> > -- 
> > 2.18.0
> > 
> > ___
> > iommu mailing list
> > io...@lists.linux-foundation.org
> > https://lists.linuxfoundation.org/mailman/listinfo/iommu



Re: [PATCH v5 18/27] iommu/mediatek: Add power-domain operation

2020-12-29 Thread Yong Wu
On Wed, 2020-12-23 at 17:36 +0900, Tomasz Figa wrote:
> On Wed, Dec 09, 2020 at 04:00:53PM +0800, Yong Wu wrote:
> > In the previous SoC, the M4U HW is in the EMI power domain which is
> > always on. the latest M4U is in the display power domain which may be
> > turned on/off, thus we have to add pm_runtime interface for it.
> > 
> > When the engine work, the engine always enable the power and clocks for
> > smi-larb/smi-common, then the M4U's power will always be powered on
> > automatically via the device link with smi-common.
> > 
> > Note: we don't enable the M4U power in iommu_map/unmap for tlb flush.
> > If its power already is on, of course it is ok. if the power is off,
> > the main tlb will be reset while M4U power on, thus the tlb flush while
> > m4u power off is unnecessary, just skip it.
> > 
> > There will be one case that pm runctime status is not expected when tlb
> > flush. After boot, the display may call dma_alloc_attrs before it call
> > pm_runtime_get(disp-dev), then the m4u's pm status is not active inside
> > the dma_alloc_attrs. Since it only happens after boot, the tlb is clean
> > at that time, I also think this is ok.
> > 
> > Signed-off-by: Yong Wu 
> > ---
> >  drivers/iommu/mtk_iommu.c | 41 +--
> >  1 file changed, 35 insertions(+), 6 deletions(-)
> > 
> > diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
> > index 6fe3ee2b2bf5..0e9c03cbab32 100644
> > --- a/drivers/iommu/mtk_iommu.c
> > +++ b/drivers/iommu/mtk_iommu.c
> > @@ -184,6 +184,8 @@ static void mtk_iommu_tlb_flush_all(void *cookie)
> > struct mtk_iommu_data *data = cookie;
> >  
> > for_each_m4u(data) {
> > +   if (!pm_runtime_active(data->dev))
> > +   continue;
> 
> Is it guaranteed that the status is active in the check above, but then
> the process is preempted and it goes down here?
> 
> Shouldn't we do something like below?
> 
> ret = pm_runtime_get_if_active();
> if (!ret)
> continue;
> if (ret < 0)
> // handle error
> 
> // Flush
> 
> pm_runtime_put();

Make sense. Thanks. There is a comment in arm_smmu.c "avoid touching
dev->power.lock in fastpaths". To avoid this here too(we have many SoC
don't have power-domain). then the code will be like:

bool has_pm = !!data->dev->pm_domain;

if (has_pm) {
if (pm_runtime_get_if_in_use(data->dev) <= 0)
continue;
}



if (has_pm)
pm_runtime_put(data->dev);
> 
> Similar comment to the other places being changed by this patch.
> 
> > writel_relaxed(F_INVLD_EN1 | F_INVLD_EN0,
> >data->base + data->plat_data->inv_sel_reg);
> > writel_relaxed(F_ALL_INVLD, data->base + REG_MMU_INVALIDATE);
> > @@ -200,6 +202,10 @@ static void mtk_iommu_tlb_flush_range_sync(unsigned 
> > long iova, size_t size,
> > u32 tmp;
> >  
> > for_each_m4u(data) {
> > +   /* skip tlb flush when pm is not active. */
> > +   if (!pm_runtime_active(data->dev))
> > +   continue;
> > +
> > spin_lock_irqsave(>tlb_lock, flags);
> > writel_relaxed(F_INVLD_EN1 | F_INVLD_EN0,
> >data->base + data->plat_data->inv_sel_reg);
[snip]


Re: [PATCH v5 17/27] iommu/mediatek: Add pm runtime callback

2020-12-29 Thread Yong Wu
On Wed, 2020-12-23 at 17:32 +0900, Tomasz Figa wrote:
> On Wed, Dec 09, 2020 at 04:00:52PM +0800, Yong Wu wrote:
> > This patch adds pm runtime callback.
> > 
> > In pm runtime case, all the registers backup/restore and bclk are
> > controlled in the pm_runtime callback, then pm_suspend is not needed in
> > this case.
> > 
> > runtime PM is disabled when suspend, thus we call
> > pm_runtime_status_suspended instead of pm_runtime_suspended.
> > 
> > And, m4u doesn't have its special pm runtime domain in previous SoC, in
> > this case dev->power.runtime_status is RPM_SUSPENDED defaultly,
> 
> This sounds wrong and could lead to hard to debug errors when the driver
> is changed in the future. Would it be possible to make the behavior
> consistent across the SoCs instead, so that runtime PM status is ACTIVE
> when needed, even on SoCs without an IOMMU PM domain?

Appreciate the reviewing so detailly.

I have tested this.
a) always call pm_runtime_enable.
b) always add device_link with smi_common.

Then, the runtime PM status meet expectation. 

We don't call pm_runtime_get_sync so often, thus, we don't always touch
dev->power.lock. this is ok for us.

I will use this in the next version.

> 
> > thus add
> > a "dev->pm_domain" checking for the SoC that has pm runtime domain.
> > 
> > Signed-off-by: Yong Wu 
> > ---
> >  drivers/iommu/mtk_iommu.c | 22 --
> >  1 file changed, 20 insertions(+), 2 deletions(-)
> > 
> > diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
> > index 5614015e5b96..6fe3ee2b2bf5 100644
> > --- a/drivers/iommu/mtk_iommu.c
> > +++ b/drivers/iommu/mtk_iommu.c
> > @@ -808,7 +808,7 @@ static int mtk_iommu_remove(struct platform_device 
> > *pdev)
> > return 0;
> >  }
> >  
> > -static int __maybe_unused mtk_iommu_suspend(struct device *dev)
> > +static int __maybe_unused mtk_iommu_runtime_suspend(struct device *dev)
> >  {
> > struct mtk_iommu_data *data = dev_get_drvdata(dev);
> > struct mtk_iommu_suspend_reg *reg = >reg;
> > @@ -826,7 +826,7 @@ static int __maybe_unused mtk_iommu_suspend(struct 
> > device *dev)
> > return 0;
> >  }
> >  
> > -static int __maybe_unused mtk_iommu_resume(struct device *dev)
> > +static int __maybe_unused mtk_iommu_runtime_resume(struct device *dev)
> >  {
> > struct mtk_iommu_data *data = dev_get_drvdata(dev);
> > struct mtk_iommu_suspend_reg *reg = >reg;
> > @@ -853,7 +853,25 @@ static int __maybe_unused mtk_iommu_resume(struct 
> > device *dev)
> > return 0;
> >  }
> >  
> > +static int __maybe_unused mtk_iommu_suspend(struct device *dev)
> > +{
> > +   /* runtime PM is disabled when suspend in pm_runtime case. */
> > +   if (dev->pm_domain && pm_runtime_status_suspended(dev))
> > +   return 0;
> > +
> > +   return mtk_iommu_runtime_suspend(dev);
> > +}
> > +
> > +static int __maybe_unused mtk_iommu_resume(struct device *dev)
> > +{
> > +   if (dev->pm_domain && pm_runtime_status_suspended(dev))
> > +   return 0;
> > +
> > +   return mtk_iommu_runtime_resume(dev);
> > +}
> 
> Wouldn't it be enough to just use pm_runtime_force_suspend() and
> pm_runtime_force_resume() as system sleep ops?

After above solution, this is ok.

Thanks.
> 
> > +
> >  static const struct dev_pm_ops mtk_iommu_pm_ops = {
> > +   SET_RUNTIME_PM_OPS(mtk_iommu_runtime_suspend, mtk_iommu_runtime_resume, 
> > NULL)
> > SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(mtk_iommu_suspend, mtk_iommu_resume)
> >  };
> >  
> > -- 
> > 2.18.0
> > 
> > ___
> > iommu mailing list
> > io...@lists.linux-foundation.org
> > https://lists.linuxfoundation.org/mailman/listinfo/iommu



Re: [PATCH v5 15/27] iommu/mediatek: Add fail handle for sysfs_add and device_register

2020-12-29 Thread Yong Wu
On Wed, 2020-12-23 at 17:25 +0900, Tomasz Figa wrote:
> On Wed, Dec 09, 2020 at 04:00:50PM +0800, Yong Wu wrote:
> > Add fail handle for iommu_device_sysfs_add and iommu_device_register.
> > 
> > Fixes: b16c0170b53c ("iommu/mediatek: Make use of iommu_device_register 
> > interface")
> > Signed-off-by: Yong Wu 
> > ---
> >  drivers/iommu/mtk_iommu.c | 13 +++--
> >  1 file changed, 11 insertions(+), 2 deletions(-)
> > 
> > diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
> > index 39478cfbe0f1..09c8c58feb78 100644
> > --- a/drivers/iommu/mtk_iommu.c
> > +++ b/drivers/iommu/mtk_iommu.c
> > @@ -746,7 +746,7 @@ static int mtk_iommu_probe(struct platform_device *pdev)
> >  
> > ret = iommu_device_register(>iommu);
> > if (ret)
> > -   return ret;
> > +   goto out_sysfs_remove;
> >  
> > spin_lock_init(>tlb_lock);
> > list_add_tail(>list, );
> > @@ -754,7 +754,16 @@ static int mtk_iommu_probe(struct platform_device 
> > *pdev)
> > if (!iommu_present(_bus_type))
> > bus_set_iommu(_bus_type, _iommu_ops);
> >  
> > -   return component_master_add_with_match(dev, _iommu_com_ops, match);
> > +   ret = component_master_add_with_match(dev, _iommu_com_ops, match);
> > +   if (ret)
> > +   goto out_dev_unreg;
> > +   return ret;
> > +
> > +out_dev_unreg:
> 
> Shouldn't other operations be undone as well? I can see that above
> bus_set_iommu() is set and an entry is added to m4ulist.

Oh. Yes. I will add them. and remove the fixes tag since they are not
introduced by it. these error handle are not added in the first version.

> 
> > +   iommu_device_unregister(>iommu);
> > +out_sysfs_remove:
> > +   iommu_device_sysfs_remove(>iommu);
> > +   return ret;
> >  }
> >  
> >  static int mtk_iommu_remove(struct platform_device *pdev)
> > -- 
> > 2.18.0
> > 
> > ___
> > iommu mailing list
> > io...@lists.linux-foundation.org
> > https://lists.linuxfoundation.org/mailman/listinfo/iommu



Re: [PATCH v5 06/27] dt-bindings: mediatek: Add binding for mt8192 IOMMU

2020-12-24 Thread Yong Wu
On Wed, 2020-12-23 at 17:18 +0900, Tomasz Figa wrote:
> On Wed, Dec 09, 2020 at 04:00:41PM +0800, Yong Wu wrote:
> > This patch adds decriptions for mt8192 IOMMU and SMI.
> > 
> > mt8192 also is MTK IOMMU gen2 which uses ARM Short-Descriptor translation
> > table format. The M4U-SMI HW diagram is as below:
> > 
> >   EMI
> >|
> >   M4U
> >|
> >   
> >SMI Common
> >   
> >|
> >   +---+--+--+--+---+
> >   |   |  |  |   .. |   |
> >   |   |  |  |  |   |
> > larb0   larb1  larb2  larb4 ..  larb19   larb20
> > disp0   disp1   mdpvdec   IPE  IPE
> > 
> > All the connections are HW fixed, SW can NOT adjust it.
> > 
> > mt8192 M4U support 0~16GB iova range. we preassign different engines
> > into different iova ranges:
> > 
> > domain-id  module iova-range  larbs
> >0   disp0 ~ 4G  larb0/1
> >1   vcodec  4G ~ 8G larb4/5/7
> >2   cam/mdp 8G ~ 12G larb2/9/11/13/14/16/17/18/19/20
> 
> Why do we preassign these addresses in DT? Shouldn't it be a user's or
> integrator's decision to split the 16 GB address range into sub-ranges
> and define which larbs those sub-ranges are shared with?

The problem is that we can't split the 16GB range with the larb as unit.
The example is the below ccu0(larb13 port9/10) is a independent
range(domain), the others ports in larb13 is in another domain.

disp/vcodec/cam/mdp don't have special iova requirement, they could
access any range. vcodec also can locate 8G~12G. it don't care about
where its iova locate. here I preassign like this following with our
internal project setting.

Why set this in DT?, this is only for simplifying the code. Assume we
put it in the platform data. We have up to 32 larbs, each larb has up to
32 ports, each port may be in different iommu domains. we should have a
big array for this..however we only use a macro to get the domain in the
DT method.

When replying this mail, I happen to see there is a "dev->dev_range_map"
which has "dma-range" information, I think I could use this value to get
which domain the device belong to. then no need put domid in DT. I will
test this.

Thanks.
> 
> Best regards,
> Tomasz
> 
> >3   CCU0    0x4000_ ~ 0x43ff_ larb13: port 9/10
> >4   CCU10x4400_ ~ 0x47ff_ larb14: port 4/5
> > 
> > The iova range for CCU0/1(camera control unit) is HW requirement.
> > 
> > Signed-off-by: Yong Wu 
> > Reviewed-by: Rob Herring 
> > ---
> >  .../bindings/iommu/mediatek,iommu.yaml|  18 +-
> >  include/dt-bindings/memory/mt8192-larb-port.h | 240 ++
> >  2 files changed, 257 insertions(+), 1 deletion(-)
> >  create mode 100644 include/dt-bindings/memory/mt8192-larb-port.h
> > 
[snip]


Re: [PATCH v3 1/7] iommu: Move iotlb_sync_map out from __iommu_map

2020-12-24 Thread Yong Wu
On Wed, 2020-12-23 at 08:51 +, Christoph Hellwig wrote:
> On Wed, Dec 16, 2020 at 06:36:01PM +0800, Yong Wu wrote:
> > In the end of __iommu_map, It alway call iotlb_sync_map.
> > This patch moves iotlb_sync_map out from __iommu_map since it is
> > unnecessary to call this for each sg segment especially iotlb_sync_map
> > is flush tlb all currently.
> > 
> > Signed-off-by: Yong Wu 
> > Reviewed-by: Robin Murphy 
> 
> What about adding a little helper that does the NULL check and method
> call instead of duplicating it all over?

Thanks for the review. Of course OK.

Then the code like below. 
(If the helper name "_iommu_map" is not good, please tell me.)

+static int _iommu_map(struct iommu_domain *domain, unsigned long iova,
+  phys_addr_t paddr, size_t size, int prot, gfp_t gfp)
+{
+   const struct iommu_ops *ops = domain->ops;
+   int ret;
+
+   ret = __iommu_map(domain, iova, paddr, size, prot, gfp);
+   if (ret == 0 && ops->iotlb_sync_map)
+   ops->iotlb_sync_map(domain);
+   return ret;
+}
+
 int iommu_map(struct iommu_domain *domain, unsigned long iova,
  phys_addr_t paddr, size_t size, int prot)
 {
might_sleep();
-   return __iommu_map(domain, iova, paddr, size, prot, GFP_KERNEL);
+   return _iommu_map(domain, iova, paddr, size, prot, GFP_KERNEL);
 }
 EXPORT_SYMBOL_GPL(iommu_map);
 
 int iommu_map_atomic(struct iommu_domain *domain, unsigned long iova,
  phys_addr_t paddr, size_t size, int prot)
 {
-   return __iommu_map(domain, iova, paddr, size, prot, GFP_ATOMIC);
+   return _iommu_map(domain, iova, paddr, size, prot, GFP_ATOMIC);
 }
 EXPORT_SYMBOL_GPL(iommu_map_atomic);



Re: [PATCH v5 04/27] dt-bindings: memory: mediatek: Add domain definition

2020-12-24 Thread Yong Wu
On Wed, 2020-12-23 at 17:15 +0900, Tomasz Figa wrote:
> Hi Yong,
> 
> On Wed, Dec 09, 2020 at 04:00:39PM +0800, Yong Wu wrote:
> > In the latest SoC, there are several HW IP require a sepecial iova
> > range, mainly CCU and VPU has this requirement. Take CCU as a example,
> > CCU require its iova locate in the range(0x4000_ ~ 0x43ff_).
> 
> Is this really a domain? Does the address range come from the design of
> the IOMMU?

It is not a really a domain. The address range comes from CCU HW
requirement. That HW can only access this iova range. thus I create a
special iommu domain for it.

> 
> Best regards,
> Tomasz
> 
> > 
> > In this patch we add a domain definition for the special port. In the
> > example of CCU, If we preassign CCU port in domain1, then iommu driver
> > will prepare a independent iommu domain of the special iova range for it,
> > then the iova got from dma_alloc_attrs(ccu-dev) will locate in its special
> > range.
> > 
> > This is a preparing patch for multi-domain support.
> > 
> > Signed-off-by: Yong Wu 
> > Acked-by: Krzysztof Kozlowski 
> > Acked-by: Rob Herring 
> > ---
> >  include/dt-bindings/memory/mtk-smi-larb-port.h | 9 -
> >  1 file changed, 8 insertions(+), 1 deletion(-)
> > 
> > diff --git a/include/dt-bindings/memory/mtk-smi-larb-port.h 
> > b/include/dt-bindings/memory/mtk-smi-larb-port.h
> > index 7d64103209af..2d4c973c174f 100644
> > --- a/include/dt-bindings/memory/mtk-smi-larb-port.h
> > +++ b/include/dt-bindings/memory/mtk-smi-larb-port.h
> > @@ -7,9 +7,16 @@
> >  #define __DT_BINDINGS_MEMORY_MTK_MEMORY_PORT_H_
> >  
> >  #define MTK_LARB_NR_MAX32
> > +#define MTK_M4U_DOM_NR_MAX 8
> > +
> > +#define MTK_M4U_DOM_ID(domid, larb, port)  \
> > +   (((domid) & 0x7) << 16 | (((larb) & 0x1f) << 5) | ((port) & 0x1f))
> > +
> > +/* The default dom id is 0. */
> > +#define MTK_M4U_ID(larb, port) MTK_M4U_DOM_ID(0, larb, port)
> >  
> > -#define MTK_M4U_ID(larb, port) (((larb) << 5) | (port))
> >  #define MTK_M4U_TO_LARB(id)(((id) >> 5) & 0x1f)
> >  #define MTK_M4U_TO_PORT(id)((id) & 0x1f)
> > +#define MTK_M4U_TO_DOM(id) (((id) >> 16) & 0x7)
> >  
> >  #endif
> > -- 
> > 2.18.0
> > 
> > ___
> > iommu mailing list
> > io...@lists.linux-foundation.org
> > https://lists.linuxfoundation.org/mailman/listinfo/iommu



  1   2   3   4   5   6   7   8   9   10   >