2020-07-02 09:38:10

by Miles Chen

[permalink] [raw]
Subject: [PATCH 1/4] dt-bindings: mediatek: add mediatek,infracfg phandle

Add a description for mediatek,infracfg. We can check if 4GB mode
is enable by reading it instead of checking the unexported
symbol "max_pfn".

This is a step towards building mtk_iommu as a kernel module.

Cc: Yong Wu <[email protected]>
Signed-off-by: Miles Chen <[email protected]>
---
Documentation/devicetree/bindings/iommu/mediatek,iommu.txt | 2 ++
1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/iommu/mediatek,iommu.txt b/Documentation/devicetree/bindings/iommu/mediatek,iommu.txt
index ce59a505f5a4..a7881deabcca 100644
--- a/Documentation/devicetree/bindings/iommu/mediatek,iommu.txt
+++ b/Documentation/devicetree/bindings/iommu/mediatek,iommu.txt
@@ -74,6 +74,8 @@ Required properties:
- 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...
+- mediatek,infracfg: a phandle to infracfg. It is used to confirm if 4GB mode is set.
+ It is an optional property, add it when the SoC have 4g mode.
- 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
--
2.18.0


2020-07-02 09:38:30

by Miles Chen

[permalink] [raw]
Subject: [PATCH 4/4] iommu/mediatek: check 4GB mode by reading infracfg

In previous disscusion [1] and [2], we found that it is risky to
use max_pfn or totalram_pages to tell if 4GB mode is enabled.

Check 4GB mode by reading infracfg register, remove the usage
of the unexported symbol max_pfn.

[1] https://lkml.org/lkml/2020/6/3/733
[2] https://lkml.org/lkml/2020/6/4/136

Cc: Mike Rapoport <[email protected]>
Cc: David Hildenbrand <[email protected]>
Cc: Yong Wu <[email protected]>
Cc: Yingjoe Chen <[email protected]>
Cc: Christoph Hellwig <[email protected]>
Signed-off-by: Miles Chen <[email protected]>
---
drivers/iommu/mtk_iommu.c | 22 ++++++++++++++++++----
1 file changed, 18 insertions(+), 4 deletions(-)

diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index 2be96f1cdbd2..09be57bd8d74 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -3,7 +3,6 @@
* Copyright (c) 2015-2016 MediaTek Inc.
* Author: Yong Wu <[email protected]>
*/
-#include <linux/memblock.h>
#include <linux/bug.h>
#include <linux/clk.h>
#include <linux/component.h>
@@ -15,11 +14,13 @@
#include <linux/iommu.h>
#include <linux/iopoll.h>
#include <linux/list.h>
+#include <linux/mfd/syscon.h>
#include <linux/of_address.h>
#include <linux/of_iommu.h>
#include <linux/of_irq.h>
#include <linux/of_platform.h>
#include <linux/platform_device.h>
+#include <linux/regmap.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <asm/barrier.h>
@@ -91,6 +92,9 @@
#define F_MMU_INT_ID_LARB_ID(a) (((a) >> 7) & 0x7)
#define F_MMU_INT_ID_PORT_ID(a) (((a) >> 2) & 0x1f)

+#define REG_INFRA_MISC 0xf00
+#define F_DDR_4GB_SUPPORT_EN BIT(13)
+
#define MTK_PROTECT_PA_ALIGN 128

/*
@@ -599,8 +603,10 @@ static int mtk_iommu_probe(struct platform_device *pdev)
struct resource *res;
resource_size_t ioaddr;
struct component_match *match = NULL;
+ struct regmap *infracfg_regmap;
void *protect;
int i, larb_nr, ret;
+ u32 val;

data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
if (!data)
@@ -614,10 +620,18 @@ static int mtk_iommu_probe(struct platform_device *pdev)
return -ENOMEM;
data->protect_base = ALIGN(virt_to_phys(protect), MTK_PROTECT_PA_ALIGN);

- /* Whether the current dram is over 4GB */
- data->enable_4GB = !!(max_pfn > (BIT_ULL(32) >> PAGE_SHIFT));
- if (!data->plat_data->has_4gb_mode)
+ if (data->plat_data->has_4gb_mode) {
+ infracfg_regmap = syscon_regmap_lookup_by_phandle(dev->of_node,
+ "mediatek,infracfg");
+ if (IS_ERR(infracfg_regmap))
+ return PTR_ERR(infracfg_regmap);
+ ret = regmap_read(infracfg_regmap, REG_INFRA_MISC, &val);
+ if (ret)
+ return ret;
+ data->enable_4GB = !!(val & F_DDR_4GB_SUPPORT_EN);
+ } else {
data->enable_4GB = false;
+ }

res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
data->base = devm_ioremap_resource(dev, res);
--
2.18.0

2020-07-02 09:39:29

by Miles Chen

[permalink] [raw]
Subject: [PATCH 3/4] arm64: dts: mt8173: add mediatek,infracfg to iommu

Add mediatek,infracfg to iommu node.

Signed-off-by: Miles Chen <[email protected]>
---
arch/arm64/boot/dts/mediatek/mt8173.dtsi | 1 +
1 file changed, 1 insertion(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt8173.dtsi b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
index 70b1ffcab7f0..a6f14f68ef7e 100644
--- a/arch/arm64/boot/dts/mediatek/mt8173.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
@@ -524,6 +524,7 @@
clock-names = "bclk";
mediatek,larbs = <&larb0 &larb1 &larb2
&larb3 &larb4 &larb5>;
+ mediatek,infracfg = <&infracfg>;
#iommu-cells = <1>;
};

--
2.18.0

2020-07-02 09:39:59

by Miles Chen

[permalink] [raw]
Subject: [PATCH 2/4] arm64: dts: mt2712: add mediatek,infracfg to iommu

Add mediatek,infracfg to iommu node.

Signed-off-by: Miles Chen <[email protected]>
---
arch/arm64/boot/dts/mediatek/mt2712e.dtsi | 1 +
1 file changed, 1 insertion(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt2712e.dtsi b/arch/arm64/boot/dts/mediatek/mt2712e.dtsi
index db17d0a4ed57..0749b0f4834c 100644
--- a/arch/arm64/boot/dts/mediatek/mt2712e.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt2712e.dtsi
@@ -331,6 +331,7 @@
clock-names = "bclk";
mediatek,larbs = <&larb0 &larb1 &larb2
&larb3 &larb6>;
+ mediatek,infracfg = <&infracfg>;
#iommu-cells = <1>;
};

--
2.18.0

2020-07-15 20:54:08

by Rob Herring

[permalink] [raw]
Subject: Re: [PATCH 1/4] dt-bindings: mediatek: add mediatek,infracfg phandle

On Thu, Jul 02, 2020 at 05:37:17PM +0800, Miles Chen wrote:
> Add a description for mediatek,infracfg. We can check if 4GB mode
> is enable by reading it instead of checking the unexported
> symbol "max_pfn".
>
> This is a step towards building mtk_iommu as a kernel module.

You determined this before without DT, so it is an OS problem and
shouldn't need a DT update.

I'd assume there's only one instance of the node mediatek,infracfg
points to, so just search for it if you want to get the info from DT.


>
> Cc: Yong Wu <[email protected]>
> Signed-off-by: Miles Chen <[email protected]>
> ---
> Documentation/devicetree/bindings/iommu/mediatek,iommu.txt | 2 ++
> 1 file changed, 2 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/iommu/mediatek,iommu.txt b/Documentation/devicetree/bindings/iommu/mediatek,iommu.txt
> index ce59a505f5a4..a7881deabcca 100644
> --- a/Documentation/devicetree/bindings/iommu/mediatek,iommu.txt
> +++ b/Documentation/devicetree/bindings/iommu/mediatek,iommu.txt
> @@ -74,6 +74,8 @@ Required properties:
> - 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...
> +- mediatek,infracfg: a phandle to infracfg. It is used to confirm if 4GB mode is set.
> + It is an optional property, add it when the SoC have 4g mode.
> - 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
> --
> 2.18.0

2020-07-15 21:06:08

by Matthias Brugger

[permalink] [raw]
Subject: Re: [PATCH 4/4] iommu/mediatek: check 4GB mode by reading infracfg



On 02/07/2020 11:37, Miles Chen wrote:
> In previous disscusion [1] and [2], we found that it is risky to
> use max_pfn or totalram_pages to tell if 4GB mode is enabled.
>
> Check 4GB mode by reading infracfg register, remove the usage
> of the unexported symbol max_pfn.
>
> [1] https://lkml.org/lkml/2020/6/3/733
> [2] https://lkml.org/lkml/2020/6/4/136
>
> Cc: Mike Rapoport <[email protected]>
> Cc: David Hildenbrand <[email protected]>
> Cc: Yong Wu <[email protected]>
> Cc: Yingjoe Chen <[email protected]>
> Cc: Christoph Hellwig <[email protected]>
> Signed-off-by: Miles Chen <[email protected]>
> ---
> drivers/iommu/mtk_iommu.c | 22 ++++++++++++++++++----
> 1 file changed, 18 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
> index 2be96f1cdbd2..09be57bd8d74 100644
> --- a/drivers/iommu/mtk_iommu.c
> +++ b/drivers/iommu/mtk_iommu.c
> @@ -3,7 +3,6 @@
> * Copyright (c) 2015-2016 MediaTek Inc.
> * Author: Yong Wu <[email protected]>
> */
> -#include <linux/memblock.h>
> #include <linux/bug.h>
> #include <linux/clk.h>
> #include <linux/component.h>
> @@ -15,11 +14,13 @@
> #include <linux/iommu.h>
> #include <linux/iopoll.h>
> #include <linux/list.h>
> +#include <linux/mfd/syscon.h>
> #include <linux/of_address.h>
> #include <linux/of_iommu.h>
> #include <linux/of_irq.h>
> #include <linux/of_platform.h>
> #include <linux/platform_device.h>
> +#include <linux/regmap.h>
> #include <linux/slab.h>
> #include <linux/spinlock.h>
> #include <asm/barrier.h>
> @@ -91,6 +92,9 @@
> #define F_MMU_INT_ID_LARB_ID(a) (((a) >> 7) & 0x7)
> #define F_MMU_INT_ID_PORT_ID(a) (((a) >> 2) & 0x1f)
>
> +#define REG_INFRA_MISC 0xf00
> +#define F_DDR_4GB_SUPPORT_EN BIT(13)
> +

As this is used for infracfg, I think it would be good to add it to
include/linux/soc/mediatek/infracfg.h and include that file here.

> #define MTK_PROTECT_PA_ALIGN 128
>
> /*
> @@ -599,8 +603,10 @@ static int mtk_iommu_probe(struct platform_device *pdev)
> struct resource *res;
> resource_size_t ioaddr;
> struct component_match *match = NULL;
> + struct regmap *infracfg_regmap;

Maybe call it just infracfg.

> void *protect;
> int i, larb_nr, ret;
> + u32 val;
>
> data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
> if (!data)
> @@ -614,10 +620,18 @@ static int mtk_iommu_probe(struct platform_device *pdev)
> return -ENOMEM;
> data->protect_base = ALIGN(virt_to_phys(protect), MTK_PROTECT_PA_ALIGN);
>
> - /* Whether the current dram is over 4GB */
> - data->enable_4GB = !!(max_pfn > (BIT_ULL(32) >> PAGE_SHIFT));
> - if (!data->plat_data->has_4gb_mode)
> + if (data->plat_data->has_4gb_mode) {
> + infracfg_regmap = syscon_regmap_lookup_by_phandle(dev->of_node,
> + "mediatek,infracfg");
> + if (IS_ERR(infracfg_regmap))
> + return PTR_ERR(infracfg_regmap);

Do we need to error out, or could we be conservative and set endable_4GB = false?

> + ret = regmap_read(infracfg_regmap, REG_INFRA_MISC, &val);
> + if (ret)
> + return ret;
> + data->enable_4GB = !!(val & F_DDR_4GB_SUPPORT_EN);
> + } else {
> data->enable_4GB = false;

Move that before the if() and update enable_4GB only in case of has_4gb_mode.

> + }
>
> res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> data->base = devm_ioremap_resource(dev, res);
>

2020-07-17 08:21:46

by Miles Chen

[permalink] [raw]
Subject: Re: [PATCH 1/4] dt-bindings: mediatek: add mediatek,infracfg phandle

On Wed, 2020-07-15 at 14:51 -0600, Rob Herring wrote:
> On Thu, Jul 02, 2020 at 05:37:17PM +0800, Miles Chen wrote:
> > Add a description for mediatek,infracfg. We can check if 4GB mode
> > is enable by reading it instead of checking the unexported
> > symbol "max_pfn".
> >
> > This is a step towards building mtk_iommu as a kernel module.
>
> You determined this before without DT, so it is an OS problem and
> shouldn't need a DT update.

Thanks for your comment.

The old way (using max_pfn) do determine this is risky because the
max_pfn may lower than (GB if reserved memory regions occupy memory
higher than 4GB.

So, the better way to do this is by reading register from H/W.
>
> I'd assume there's only one instance of the node mediatek,infracfg
> points to, so just search for it if you want to get the info from DT.
>
I can do syscon_regmap_lookup_by_compatible() to search for it. However,
the compatibles are different in mt2712e.dtsi and mt8173.dtsi. so I have
to search "mediatek,mt2712-infracfg" and "mediatek,mt8173-infracfg"
respectively.

Using mediatek,infracfg phandle can make the code easier to read.
Is it possible to reconsider the phandle approach, please?


arch/arm64/boot/dts/mediatek/mt2712e.dtsi:253:
infracfg: syscon@10001000 {
compatible = "mediatek,mt2712-infracfg", "syscon";
arch/arm64/boot/dts/mediatek/mt8173.dtsi:363:
infracfg: power-controller@10001000 {
compatible = "mediatek,mt8173-infracfg", "syscon";



>
> >
> > Cc: Yong Wu <[email protected]>
> > Signed-off-by: Miles Chen <[email protected]>
> > ---
> > Documentation/devicetree/bindings/iommu/mediatek,iommu.txt | 2 ++
> > 1 file changed, 2 insertions(+)
> >
> > diff --git a/Documentation/devicetree/bindings/iommu/mediatek,iommu.txt b/Documentation/devicetree/bindings/iommu/mediatek,iommu.txt
> > index ce59a505f5a4..a7881deabcca 100644
> > --- a/Documentation/devicetree/bindings/iommu/mediatek,iommu.txt
> > +++ b/Documentation/devicetree/bindings/iommu/mediatek,iommu.txt
> > @@ -74,6 +74,8 @@ Required properties:
> > - 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...
> > +- mediatek,infracfg: a phandle to infracfg. It is used to confirm if 4GB mode is set.
> > + It is an optional property, add it when the SoC have 4g mode.
> > - 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
> > --
> > 2.18.0

2020-07-17 08:27:14

by Miles Chen

[permalink] [raw]
Subject: Re: [PATCH 4/4] iommu/mediatek: check 4GB mode by reading infracfg

On Wed, 2020-07-15 at 23:05 +0200, Matthias Brugger wrote:
>
> On 02/07/2020 11:37, Miles Chen wrote:
> > In previous disscusion [1] and [2], we found that it is risky to
> > use max_pfn or totalram_pages to tell if 4GB mode is enabled.
> >
> > Check 4GB mode by reading infracfg register, remove the usage
> > of the unexported symbol max_pfn.
> >
> > [1] https://urldefense.com/v3/__https://lkml.org/lkml/2020/6/3/733__;!!CTRNKA9wMg0ARbw!16gAfVnSY87W4t5kE4iw20QPxBgS_SHBvPKlePKU7CGIb18nUzuRUjHumcf4oYVhIQ$
> > [2] https://urldefense.com/v3/__https://lkml.org/lkml/2020/6/4/136__;!!CTRNKA9wMg0ARbw!16gAfVnSY87W4t5kE4iw20QPxBgS_SHBvPKlePKU7CGIb18nUzuRUjHumcfr4i9p5g$
> >
> > Cc: Mike Rapoport <[email protected]>
> > Cc: David Hildenbrand <[email protected]>
> > Cc: Yong Wu <[email protected]>
> > Cc: Yingjoe Chen <[email protected]>
> > Cc: Christoph Hellwig <[email protected]>
> > Signed-off-by: Miles Chen <[email protected]>
> > ---
> > drivers/iommu/mtk_iommu.c | 22 ++++++++++++++++++----
> > 1 file changed, 18 insertions(+), 4 deletions(-)
> >
> > diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
> > index 2be96f1cdbd2..09be57bd8d74 100644
> > --- a/drivers/iommu/mtk_iommu.c
> > +++ b/drivers/iommu/mtk_iommu.c
> > @@ -3,7 +3,6 @@
> > * Copyright (c) 2015-2016 MediaTek Inc.
> > * Author: Yong Wu <[email protected]>
> > */
> > -#include <linux/memblock.h>
> > #include <linux/bug.h>
> > #include <linux/clk.h>
> > #include <linux/component.h>
> > @@ -15,11 +14,13 @@
> > #include <linux/iommu.h>
> > #include <linux/iopoll.h>
> > #include <linux/list.h>
> > +#include <linux/mfd/syscon.h>
> > #include <linux/of_address.h>
> > #include <linux/of_iommu.h>
> > #include <linux/of_irq.h>
> > #include <linux/of_platform.h>
> > #include <linux/platform_device.h>
> > +#include <linux/regmap.h>
> > #include <linux/slab.h>
> > #include <linux/spinlock.h>
> > #include <asm/barrier.h>
> > @@ -91,6 +92,9 @@
> > #define F_MMU_INT_ID_LARB_ID(a) (((a) >> 7) & 0x7)
> > #define F_MMU_INT_ID_PORT_ID(a) (((a) >> 2) & 0x1f)
> >
> > +#define REG_INFRA_MISC 0xf00
> > +#define F_DDR_4GB_SUPPORT_EN BIT(13)
> > +
>
> As this is used for infracfg, I think it would be good to add it to
> include/linux/soc/mediatek/infracfg.h and include that file here.
Thanks for your comment.

ok. I'll do this in next version.
>
> > #define MTK_PROTECT_PA_ALIGN 128
> >
> > /*
> > @@ -599,8 +603,10 @@ static int mtk_iommu_probe(struct platform_device *pdev)
> > struct resource *res;
> > resource_size_t ioaddr;
> > struct component_match *match = NULL;
> > + struct regmap *infracfg_regmap;
>
> Maybe call it just infracfg.

ok. I'll do this in next version.
>
> > void *protect;
> > int i, larb_nr, ret;
> > + u32 val;
> >
> > data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
> > if (!data)
> > @@ -614,10 +620,18 @@ static int mtk_iommu_probe(struct platform_device *pdev)
> > return -ENOMEM;
> > data->protect_base = ALIGN(virt_to_phys(protect), MTK_PROTECT_PA_ALIGN);
> >
> > - /* Whether the current dram is over 4GB */
> > - data->enable_4GB = !!(max_pfn > (BIT_ULL(32) >> PAGE_SHIFT));
> > - if (!data->plat_data->has_4gb_mode)
> > + if (data->plat_data->has_4gb_mode) {
> > + infracfg_regmap = syscon_regmap_lookup_by_phandle(dev->of_node,
> > + "mediatek,infracfg");
> > + if (IS_ERR(infracfg_regmap))
> > + return PTR_ERR(infracfg_regmap);
>
> Do we need to error out, or could we be conservative and set endable_4GB = false?

We have to error out in this case because the 4gb_mode setting must be
consistent with the h/w setting.

>
> > + ret = regmap_read(infracfg_regmap, REG_INFRA_MISC, &val);
> > + if (ret)
> > + return ret;
> > + data->enable_4GB = !!(val & F_DDR_4GB_SUPPORT_EN);
> > + } else {
> > data->enable_4GB = false;
>
> Move that before the if() and update enable_4GB only in case of has_4gb_mode.

ok. I'll do this in next version.

Miles
>
> > + }
> >
> > res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> > data->base = devm_ioremap_resource(dev, res);
> >