All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/4] iommu/exynos: Add basic support for SysMMU v7
@ 2022-07-02 21:37 ` Sam Protsenko
  0 siblings, 0 replies; 47+ messages in thread
From: Sam Protsenko @ 2022-07-02 21:37 UTC (permalink / raw)
  To: Marek Szyprowski, Krzysztof Kozlowski
  Cc: Joerg Roedel, Will Deacon, Robin Murphy, Janghyuck Kim,
	Cho KyongHo, Daniel Mentz, Sumit Semwal, iommu, iommu,
	linux-arm-kernel, linux-samsung-soc, linux-kernel

Existing exynos-iommu driver only supports SysMMU versions up to v5. But
it's pretty much ready for basic usage with SysMMU v7, only small
changes have to be done. As SysMMU version is tested dynamically (by
reading the corresponding register), there is no need to introduce new
compatible string.

One major change is that SysMMU v7 can have different register layouts:
  - with Virtual Machine support
  - without Virtual Machine support

That can be checked by reading the capability registers. In case the
SysMMU IP-core is VM-capable, the VM registers have to be used, and some
additional initialization is needed. That is the case on E850-96 board,
which non-secure SysMMU (v7.4) implements VM-capable register set.

The patch series was tested on E850-96 board. Because at the moment
there are no SysMMU users for that board, the testing was done using so
called "Emulated Translation" registers available on SysMMU v7. That
allows one to initiate the translation from CPU, by writing to those
registers, and then reading the corresponding TLB registers to find out
the translation result. The testing driver can be found in [1] tree.

[1] https://github.com/joe-skb7/linux/tree/e850-96-mainline-iommu

Sam Protsenko (4):
  iommu/exynos: Set correct dma mask for SysMMU v5+
  iommu/exynos: Check if SysMMU v7 has VM registers
  iommu/exynos: Use lookup based approach to access v7 registers
  iommu/exynos: Add minimal support for SysMMU v7 with VM registers

 drivers/iommu/exynos-iommu.c | 112 ++++++++++++++++++++++++++++++++---
 1 file changed, 104 insertions(+), 8 deletions(-)

-- 
2.30.2


^ permalink raw reply	[flat|nested] 47+ messages in thread

* [PATCH 0/4] iommu/exynos: Add basic support for SysMMU v7
@ 2022-07-02 21:37 ` Sam Protsenko
  0 siblings, 0 replies; 47+ messages in thread
From: Sam Protsenko @ 2022-07-02 21:37 UTC (permalink / raw)
  To: Marek Szyprowski, Krzysztof Kozlowski
  Cc: Janghyuck Kim, linux-samsung-soc, Will Deacon, iommu,
	linux-kernel, iommu, Cho KyongHo, Robin Murphy, Sumit Semwal,
	linux-arm-kernel

Existing exynos-iommu driver only supports SysMMU versions up to v5. But
it's pretty much ready for basic usage with SysMMU v7, only small
changes have to be done. As SysMMU version is tested dynamically (by
reading the corresponding register), there is no need to introduce new
compatible string.

One major change is that SysMMU v7 can have different register layouts:
  - with Virtual Machine support
  - without Virtual Machine support

That can be checked by reading the capability registers. In case the
SysMMU IP-core is VM-capable, the VM registers have to be used, and some
additional initialization is needed. That is the case on E850-96 board,
which non-secure SysMMU (v7.4) implements VM-capable register set.

The patch series was tested on E850-96 board. Because at the moment
there are no SysMMU users for that board, the testing was done using so
called "Emulated Translation" registers available on SysMMU v7. That
allows one to initiate the translation from CPU, by writing to those
registers, and then reading the corresponding TLB registers to find out
the translation result. The testing driver can be found in [1] tree.

[1] https://github.com/joe-skb7/linux/tree/e850-96-mainline-iommu

Sam Protsenko (4):
  iommu/exynos: Set correct dma mask for SysMMU v5+
  iommu/exynos: Check if SysMMU v7 has VM registers
  iommu/exynos: Use lookup based approach to access v7 registers
  iommu/exynos: Add minimal support for SysMMU v7 with VM registers

 drivers/iommu/exynos-iommu.c | 112 ++++++++++++++++++++++++++++++++---
 1 file changed, 104 insertions(+), 8 deletions(-)

-- 
2.30.2

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

^ permalink raw reply	[flat|nested] 47+ messages in thread

* [PATCH 0/4] iommu/exynos: Add basic support for SysMMU v7
@ 2022-07-02 21:37 ` Sam Protsenko
  0 siblings, 0 replies; 47+ messages in thread
From: Sam Protsenko @ 2022-07-02 21:37 UTC (permalink / raw)
  To: Marek Szyprowski, Krzysztof Kozlowski
  Cc: Joerg Roedel, Will Deacon, Robin Murphy, Janghyuck Kim,
	Cho KyongHo, Daniel Mentz, Sumit Semwal, iommu, iommu,
	linux-arm-kernel, linux-samsung-soc, linux-kernel

Existing exynos-iommu driver only supports SysMMU versions up to v5. But
it's pretty much ready for basic usage with SysMMU v7, only small
changes have to be done. As SysMMU version is tested dynamically (by
reading the corresponding register), there is no need to introduce new
compatible string.

One major change is that SysMMU v7 can have different register layouts:
  - with Virtual Machine support
  - without Virtual Machine support

That can be checked by reading the capability registers. In case the
SysMMU IP-core is VM-capable, the VM registers have to be used, and some
additional initialization is needed. That is the case on E850-96 board,
which non-secure SysMMU (v7.4) implements VM-capable register set.

The patch series was tested on E850-96 board. Because at the moment
there are no SysMMU users for that board, the testing was done using so
called "Emulated Translation" registers available on SysMMU v7. That
allows one to initiate the translation from CPU, by writing to those
registers, and then reading the corresponding TLB registers to find out
the translation result. The testing driver can be found in [1] tree.

[1] https://github.com/joe-skb7/linux/tree/e850-96-mainline-iommu

Sam Protsenko (4):
  iommu/exynos: Set correct dma mask for SysMMU v5+
  iommu/exynos: Check if SysMMU v7 has VM registers
  iommu/exynos: Use lookup based approach to access v7 registers
  iommu/exynos: Add minimal support for SysMMU v7 with VM registers

 drivers/iommu/exynos-iommu.c | 112 ++++++++++++++++++++++++++++++++---
 1 file changed, 104 insertions(+), 8 deletions(-)

-- 
2.30.2


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 47+ messages in thread

* [PATCH 1/4] iommu/exynos: Set correct dma mask for SysMMU v5+
  2022-07-02 21:37 ` Sam Protsenko
  (?)
@ 2022-07-02 21:37   ` Sam Protsenko
  -1 siblings, 0 replies; 47+ messages in thread
From: Sam Protsenko @ 2022-07-02 21:37 UTC (permalink / raw)
  To: Marek Szyprowski, Krzysztof Kozlowski
  Cc: Joerg Roedel, Will Deacon, Robin Murphy, Janghyuck Kim,
	Cho KyongHo, Daniel Mentz, Sumit Semwal, iommu, iommu,
	linux-arm-kernel, linux-samsung-soc, linux-kernel

SysMMU v5+ supports 36 bit physical address space. Set corresponding DMA
mask to avoid falling back to SWTLBIO usage in dma_map_single() because
of failed dma_capable() check.

The original code for this fix was suggested by Marek.

Originally-by: Marek Szyprowski <m.szyprowski@samsung.com>
Signed-off-by: Sam Protsenko <semen.protsenko@linaro.org>
---
 drivers/iommu/exynos-iommu.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
index 71f2018e23fe..28f8c8d93aa3 100644
--- a/drivers/iommu/exynos-iommu.c
+++ b/drivers/iommu/exynos-iommu.c
@@ -647,6 +647,14 @@ static int exynos_sysmmu_probe(struct platform_device *pdev)
 		}
 	}
 
+	if (MMU_MAJ_VER(data->version) >= 5) {
+		ret = dma_set_mask(dev, DMA_BIT_MASK(36));
+		if (ret) {
+			dev_err(dev, "Unable to set DMA mask: %d\n", ret);
+			return ret;
+		}
+	}
+
 	/*
 	 * use the first registered sysmmu device for performing
 	 * dma mapping operations on iommu page tables (cpu cache flush)
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 47+ messages in thread

* [PATCH 1/4] iommu/exynos: Set correct dma mask for SysMMU v5+
@ 2022-07-02 21:37   ` Sam Protsenko
  0 siblings, 0 replies; 47+ messages in thread
From: Sam Protsenko @ 2022-07-02 21:37 UTC (permalink / raw)
  To: Marek Szyprowski, Krzysztof Kozlowski
  Cc: Janghyuck Kim, linux-samsung-soc, Will Deacon, iommu,
	linux-kernel, iommu, Cho KyongHo, Robin Murphy, Sumit Semwal,
	linux-arm-kernel

SysMMU v5+ supports 36 bit physical address space. Set corresponding DMA
mask to avoid falling back to SWTLBIO usage in dma_map_single() because
of failed dma_capable() check.

The original code for this fix was suggested by Marek.

Originally-by: Marek Szyprowski <m.szyprowski@samsung.com>
Signed-off-by: Sam Protsenko <semen.protsenko@linaro.org>
---
 drivers/iommu/exynos-iommu.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
index 71f2018e23fe..28f8c8d93aa3 100644
--- a/drivers/iommu/exynos-iommu.c
+++ b/drivers/iommu/exynos-iommu.c
@@ -647,6 +647,14 @@ static int exynos_sysmmu_probe(struct platform_device *pdev)
 		}
 	}
 
+	if (MMU_MAJ_VER(data->version) >= 5) {
+		ret = dma_set_mask(dev, DMA_BIT_MASK(36));
+		if (ret) {
+			dev_err(dev, "Unable to set DMA mask: %d\n", ret);
+			return ret;
+		}
+	}
+
 	/*
 	 * use the first registered sysmmu device for performing
 	 * dma mapping operations on iommu page tables (cpu cache flush)
-- 
2.30.2

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

^ permalink raw reply related	[flat|nested] 47+ messages in thread

* [PATCH 1/4] iommu/exynos: Set correct dma mask for SysMMU v5+
@ 2022-07-02 21:37   ` Sam Protsenko
  0 siblings, 0 replies; 47+ messages in thread
From: Sam Protsenko @ 2022-07-02 21:37 UTC (permalink / raw)
  To: Marek Szyprowski, Krzysztof Kozlowski
  Cc: Joerg Roedel, Will Deacon, Robin Murphy, Janghyuck Kim,
	Cho KyongHo, Daniel Mentz, Sumit Semwal, iommu, iommu,
	linux-arm-kernel, linux-samsung-soc, linux-kernel

SysMMU v5+ supports 36 bit physical address space. Set corresponding DMA
mask to avoid falling back to SWTLBIO usage in dma_map_single() because
of failed dma_capable() check.

The original code for this fix was suggested by Marek.

Originally-by: Marek Szyprowski <m.szyprowski@samsung.com>
Signed-off-by: Sam Protsenko <semen.protsenko@linaro.org>
---
 drivers/iommu/exynos-iommu.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
index 71f2018e23fe..28f8c8d93aa3 100644
--- a/drivers/iommu/exynos-iommu.c
+++ b/drivers/iommu/exynos-iommu.c
@@ -647,6 +647,14 @@ static int exynos_sysmmu_probe(struct platform_device *pdev)
 		}
 	}
 
+	if (MMU_MAJ_VER(data->version) >= 5) {
+		ret = dma_set_mask(dev, DMA_BIT_MASK(36));
+		if (ret) {
+			dev_err(dev, "Unable to set DMA mask: %d\n", ret);
+			return ret;
+		}
+	}
+
 	/*
 	 * use the first registered sysmmu device for performing
 	 * dma mapping operations on iommu page tables (cpu cache flush)
-- 
2.30.2


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 47+ messages in thread

* [PATCH 2/4] iommu/exynos: Check if SysMMU v7 has VM registers
  2022-07-02 21:37 ` Sam Protsenko
  (?)
@ 2022-07-02 21:37   ` Sam Protsenko
  -1 siblings, 0 replies; 47+ messages in thread
From: Sam Protsenko @ 2022-07-02 21:37 UTC (permalink / raw)
  To: Marek Szyprowski, Krzysztof Kozlowski
  Cc: Joerg Roedel, Will Deacon, Robin Murphy, Janghyuck Kim,
	Cho KyongHo, Daniel Mentz, Sumit Semwal, iommu, iommu,
	linux-arm-kernel, linux-samsung-soc, linux-kernel

SysMMU v7 can have Virtual Machine registers, which implement multiple
translation domains. The driver should know if it's true or not, as VM
registers shouldn't be accessed if not present. Read corresponding
capabilities register to obtain that info, and store it in driver data.

Signed-off-by: Sam Protsenko <semen.protsenko@linaro.org>
---
 drivers/iommu/exynos-iommu.c | 42 ++++++++++++++++++++++++++++++------
 1 file changed, 36 insertions(+), 6 deletions(-)

diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
index 28f8c8d93aa3..df6ddbebbe2b 100644
--- a/drivers/iommu/exynos-iommu.c
+++ b/drivers/iommu/exynos-iommu.c
@@ -135,6 +135,9 @@ static u32 lv2ent_offset(sysmmu_iova_t iova)
 #define CFG_SYSSEL	(1 << 22) /* System MMU 3.2 only */
 #define CFG_FLPDCACHE	(1 << 20) /* System MMU 3.2+ only */
 
+#define CAPA0_CAPA1_EXIST		BIT(11)
+#define CAPA1_VCR_ENABLED		BIT(14)
+
 /* common registers */
 #define REG_MMU_CTRL		0x000
 #define REG_MMU_CFG		0x004
@@ -171,6 +174,10 @@ static u32 lv2ent_offset(sysmmu_iova_t iova)
 #define REG_V5_FAULT_AR_VA	0x070
 #define REG_V5_FAULT_AW_VA	0x080
 
+/* v7.x registers */
+#define REG_V7_CAPA0		0x870
+#define REG_V7_CAPA1		0x874
+
 #define has_sysmmu(dev)		(dev_iommu_priv_get(dev) != NULL)
 
 static struct device *dma_dev;
@@ -274,6 +281,9 @@ struct sysmmu_drvdata {
 	unsigned int version;		/* our version */
 
 	struct iommu_device iommu;	/* IOMMU core handle */
+
+	/* v7 fields */
+	bool has_vcr;			/* virtual machine control register */
 };
 
 static struct exynos_iommu_domain *to_exynos_domain(struct iommu_domain *dom)
@@ -364,11 +374,7 @@ static void __sysmmu_disable_clocks(struct sysmmu_drvdata *data)
 
 static void __sysmmu_get_version(struct sysmmu_drvdata *data)
 {
-	u32 ver;
-
-	__sysmmu_enable_clocks(data);
-
-	ver = readl(data->sfrbase + REG_MMU_VERSION);
+	const u32 ver = readl(data->sfrbase + REG_MMU_VERSION);
 
 	/* controllers on some SoCs don't report proper version */
 	if (ver == 0x80000001u)
@@ -378,6 +384,29 @@ static void __sysmmu_get_version(struct sysmmu_drvdata *data)
 
 	dev_dbg(data->sysmmu, "hardware version: %d.%d\n",
 		MMU_MAJ_VER(data->version), MMU_MIN_VER(data->version));
+}
+
+static bool __sysmmu_has_capa1(struct sysmmu_drvdata *data)
+{
+	const u32 capa0 = readl(data->sfrbase + REG_V7_CAPA0);
+
+	return capa0 & CAPA0_CAPA1_EXIST;
+}
+
+static void __sysmmu_get_vcr(struct sysmmu_drvdata *data)
+{
+	const u32 capa1 = readl(data->sfrbase + REG_V7_CAPA1);
+
+	data->has_vcr = capa1 & CAPA1_VCR_ENABLED;
+}
+
+static void sysmmu_get_hw_info(struct sysmmu_drvdata *data)
+{
+	__sysmmu_enable_clocks(data);
+
+	__sysmmu_get_version(data);
+	if (MMU_MAJ_VER(data->version) >= 7 && __sysmmu_has_capa1(data))
+		__sysmmu_get_vcr(data);
 
 	__sysmmu_disable_clocks(data);
 }
@@ -623,6 +652,8 @@ static int exynos_sysmmu_probe(struct platform_device *pdev)
 	data->sysmmu = dev;
 	spin_lock_init(&data->lock);
 
+	sysmmu_get_hw_info(data);
+
 	ret = iommu_device_sysfs_add(&data->iommu, &pdev->dev, NULL,
 				     dev_name(data->sysmmu));
 	if (ret)
@@ -634,7 +665,6 @@ static int exynos_sysmmu_probe(struct platform_device *pdev)
 
 	platform_set_drvdata(pdev, data);
 
-	__sysmmu_get_version(data);
 	if (PG_ENT_SHIFT < 0) {
 		if (MMU_MAJ_VER(data->version) < 5) {
 			PG_ENT_SHIFT = SYSMMU_PG_ENT_SHIFT;
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 47+ messages in thread

* [PATCH 2/4] iommu/exynos: Check if SysMMU v7 has VM registers
@ 2022-07-02 21:37   ` Sam Protsenko
  0 siblings, 0 replies; 47+ messages in thread
From: Sam Protsenko @ 2022-07-02 21:37 UTC (permalink / raw)
  To: Marek Szyprowski, Krzysztof Kozlowski
  Cc: Janghyuck Kim, linux-samsung-soc, Will Deacon, iommu,
	linux-kernel, iommu, Cho KyongHo, Robin Murphy, Sumit Semwal,
	linux-arm-kernel

SysMMU v7 can have Virtual Machine registers, which implement multiple
translation domains. The driver should know if it's true or not, as VM
registers shouldn't be accessed if not present. Read corresponding
capabilities register to obtain that info, and store it in driver data.

Signed-off-by: Sam Protsenko <semen.protsenko@linaro.org>
---
 drivers/iommu/exynos-iommu.c | 42 ++++++++++++++++++++++++++++++------
 1 file changed, 36 insertions(+), 6 deletions(-)

diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
index 28f8c8d93aa3..df6ddbebbe2b 100644
--- a/drivers/iommu/exynos-iommu.c
+++ b/drivers/iommu/exynos-iommu.c
@@ -135,6 +135,9 @@ static u32 lv2ent_offset(sysmmu_iova_t iova)
 #define CFG_SYSSEL	(1 << 22) /* System MMU 3.2 only */
 #define CFG_FLPDCACHE	(1 << 20) /* System MMU 3.2+ only */
 
+#define CAPA0_CAPA1_EXIST		BIT(11)
+#define CAPA1_VCR_ENABLED		BIT(14)
+
 /* common registers */
 #define REG_MMU_CTRL		0x000
 #define REG_MMU_CFG		0x004
@@ -171,6 +174,10 @@ static u32 lv2ent_offset(sysmmu_iova_t iova)
 #define REG_V5_FAULT_AR_VA	0x070
 #define REG_V5_FAULT_AW_VA	0x080
 
+/* v7.x registers */
+#define REG_V7_CAPA0		0x870
+#define REG_V7_CAPA1		0x874
+
 #define has_sysmmu(dev)		(dev_iommu_priv_get(dev) != NULL)
 
 static struct device *dma_dev;
@@ -274,6 +281,9 @@ struct sysmmu_drvdata {
 	unsigned int version;		/* our version */
 
 	struct iommu_device iommu;	/* IOMMU core handle */
+
+	/* v7 fields */
+	bool has_vcr;			/* virtual machine control register */
 };
 
 static struct exynos_iommu_domain *to_exynos_domain(struct iommu_domain *dom)
@@ -364,11 +374,7 @@ static void __sysmmu_disable_clocks(struct sysmmu_drvdata *data)
 
 static void __sysmmu_get_version(struct sysmmu_drvdata *data)
 {
-	u32 ver;
-
-	__sysmmu_enable_clocks(data);
-
-	ver = readl(data->sfrbase + REG_MMU_VERSION);
+	const u32 ver = readl(data->sfrbase + REG_MMU_VERSION);
 
 	/* controllers on some SoCs don't report proper version */
 	if (ver == 0x80000001u)
@@ -378,6 +384,29 @@ static void __sysmmu_get_version(struct sysmmu_drvdata *data)
 
 	dev_dbg(data->sysmmu, "hardware version: %d.%d\n",
 		MMU_MAJ_VER(data->version), MMU_MIN_VER(data->version));
+}
+
+static bool __sysmmu_has_capa1(struct sysmmu_drvdata *data)
+{
+	const u32 capa0 = readl(data->sfrbase + REG_V7_CAPA0);
+
+	return capa0 & CAPA0_CAPA1_EXIST;
+}
+
+static void __sysmmu_get_vcr(struct sysmmu_drvdata *data)
+{
+	const u32 capa1 = readl(data->sfrbase + REG_V7_CAPA1);
+
+	data->has_vcr = capa1 & CAPA1_VCR_ENABLED;
+}
+
+static void sysmmu_get_hw_info(struct sysmmu_drvdata *data)
+{
+	__sysmmu_enable_clocks(data);
+
+	__sysmmu_get_version(data);
+	if (MMU_MAJ_VER(data->version) >= 7 && __sysmmu_has_capa1(data))
+		__sysmmu_get_vcr(data);
 
 	__sysmmu_disable_clocks(data);
 }
@@ -623,6 +652,8 @@ static int exynos_sysmmu_probe(struct platform_device *pdev)
 	data->sysmmu = dev;
 	spin_lock_init(&data->lock);
 
+	sysmmu_get_hw_info(data);
+
 	ret = iommu_device_sysfs_add(&data->iommu, &pdev->dev, NULL,
 				     dev_name(data->sysmmu));
 	if (ret)
@@ -634,7 +665,6 @@ static int exynos_sysmmu_probe(struct platform_device *pdev)
 
 	platform_set_drvdata(pdev, data);
 
-	__sysmmu_get_version(data);
 	if (PG_ENT_SHIFT < 0) {
 		if (MMU_MAJ_VER(data->version) < 5) {
 			PG_ENT_SHIFT = SYSMMU_PG_ENT_SHIFT;
-- 
2.30.2

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

^ permalink raw reply related	[flat|nested] 47+ messages in thread

* [PATCH 2/4] iommu/exynos: Check if SysMMU v7 has VM registers
@ 2022-07-02 21:37   ` Sam Protsenko
  0 siblings, 0 replies; 47+ messages in thread
From: Sam Protsenko @ 2022-07-02 21:37 UTC (permalink / raw)
  To: Marek Szyprowski, Krzysztof Kozlowski
  Cc: Joerg Roedel, Will Deacon, Robin Murphy, Janghyuck Kim,
	Cho KyongHo, Daniel Mentz, Sumit Semwal, iommu, iommu,
	linux-arm-kernel, linux-samsung-soc, linux-kernel

SysMMU v7 can have Virtual Machine registers, which implement multiple
translation domains. The driver should know if it's true or not, as VM
registers shouldn't be accessed if not present. Read corresponding
capabilities register to obtain that info, and store it in driver data.

Signed-off-by: Sam Protsenko <semen.protsenko@linaro.org>
---
 drivers/iommu/exynos-iommu.c | 42 ++++++++++++++++++++++++++++++------
 1 file changed, 36 insertions(+), 6 deletions(-)

diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
index 28f8c8d93aa3..df6ddbebbe2b 100644
--- a/drivers/iommu/exynos-iommu.c
+++ b/drivers/iommu/exynos-iommu.c
@@ -135,6 +135,9 @@ static u32 lv2ent_offset(sysmmu_iova_t iova)
 #define CFG_SYSSEL	(1 << 22) /* System MMU 3.2 only */
 #define CFG_FLPDCACHE	(1 << 20) /* System MMU 3.2+ only */
 
+#define CAPA0_CAPA1_EXIST		BIT(11)
+#define CAPA1_VCR_ENABLED		BIT(14)
+
 /* common registers */
 #define REG_MMU_CTRL		0x000
 #define REG_MMU_CFG		0x004
@@ -171,6 +174,10 @@ static u32 lv2ent_offset(sysmmu_iova_t iova)
 #define REG_V5_FAULT_AR_VA	0x070
 #define REG_V5_FAULT_AW_VA	0x080
 
+/* v7.x registers */
+#define REG_V7_CAPA0		0x870
+#define REG_V7_CAPA1		0x874
+
 #define has_sysmmu(dev)		(dev_iommu_priv_get(dev) != NULL)
 
 static struct device *dma_dev;
@@ -274,6 +281,9 @@ struct sysmmu_drvdata {
 	unsigned int version;		/* our version */
 
 	struct iommu_device iommu;	/* IOMMU core handle */
+
+	/* v7 fields */
+	bool has_vcr;			/* virtual machine control register */
 };
 
 static struct exynos_iommu_domain *to_exynos_domain(struct iommu_domain *dom)
@@ -364,11 +374,7 @@ static void __sysmmu_disable_clocks(struct sysmmu_drvdata *data)
 
 static void __sysmmu_get_version(struct sysmmu_drvdata *data)
 {
-	u32 ver;
-
-	__sysmmu_enable_clocks(data);
-
-	ver = readl(data->sfrbase + REG_MMU_VERSION);
+	const u32 ver = readl(data->sfrbase + REG_MMU_VERSION);
 
 	/* controllers on some SoCs don't report proper version */
 	if (ver == 0x80000001u)
@@ -378,6 +384,29 @@ static void __sysmmu_get_version(struct sysmmu_drvdata *data)
 
 	dev_dbg(data->sysmmu, "hardware version: %d.%d\n",
 		MMU_MAJ_VER(data->version), MMU_MIN_VER(data->version));
+}
+
+static bool __sysmmu_has_capa1(struct sysmmu_drvdata *data)
+{
+	const u32 capa0 = readl(data->sfrbase + REG_V7_CAPA0);
+
+	return capa0 & CAPA0_CAPA1_EXIST;
+}
+
+static void __sysmmu_get_vcr(struct sysmmu_drvdata *data)
+{
+	const u32 capa1 = readl(data->sfrbase + REG_V7_CAPA1);
+
+	data->has_vcr = capa1 & CAPA1_VCR_ENABLED;
+}
+
+static void sysmmu_get_hw_info(struct sysmmu_drvdata *data)
+{
+	__sysmmu_enable_clocks(data);
+
+	__sysmmu_get_version(data);
+	if (MMU_MAJ_VER(data->version) >= 7 && __sysmmu_has_capa1(data))
+		__sysmmu_get_vcr(data);
 
 	__sysmmu_disable_clocks(data);
 }
@@ -623,6 +652,8 @@ static int exynos_sysmmu_probe(struct platform_device *pdev)
 	data->sysmmu = dev;
 	spin_lock_init(&data->lock);
 
+	sysmmu_get_hw_info(data);
+
 	ret = iommu_device_sysfs_add(&data->iommu, &pdev->dev, NULL,
 				     dev_name(data->sysmmu));
 	if (ret)
@@ -634,7 +665,6 @@ static int exynos_sysmmu_probe(struct platform_device *pdev)
 
 	platform_set_drvdata(pdev, data);
 
-	__sysmmu_get_version(data);
 	if (PG_ENT_SHIFT < 0) {
 		if (MMU_MAJ_VER(data->version) < 5) {
 			PG_ENT_SHIFT = SYSMMU_PG_ENT_SHIFT;
-- 
2.30.2


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 47+ messages in thread

* [PATCH 3/4] iommu/exynos: Use lookup based approach to access v7 registers
  2022-07-02 21:37 ` Sam Protsenko
  (?)
@ 2022-07-02 21:37   ` Sam Protsenko
  -1 siblings, 0 replies; 47+ messages in thread
From: Sam Protsenko @ 2022-07-02 21:37 UTC (permalink / raw)
  To: Marek Szyprowski, Krzysztof Kozlowski
  Cc: Joerg Roedel, Will Deacon, Robin Murphy, Janghyuck Kim,
	Cho KyongHo, Daniel Mentz, Sumit Semwal, iommu, iommu,
	linux-arm-kernel, linux-samsung-soc, linux-kernel

SysMMU v7 might have different register layouts (VM capable or non-VM
capable). Check which layout is implemented in current SysMMU module and
prepare the corresponding register table for futher usage. This way is
faster and more elegant than checking corresponding condition (if it's
VM or non-VM SysMMU) each time before accessing v7 registers. For now
the register table contains only most basic registers needed to add the
SysMMU v7 support.

This patch is based on downstream work of next authors:
  - Janghyuck Kim <janghyuck.kim@samsung.com>
  - Daniel Mentz <danielmentz@google.com>

Signed-off-by: Sam Protsenko <semen.protsenko@linaro.org>
---
 drivers/iommu/exynos-iommu.c | 46 ++++++++++++++++++++++++++++++++++++
 1 file changed, 46 insertions(+)

diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
index df6ddbebbe2b..47017e8945c5 100644
--- a/drivers/iommu/exynos-iommu.c
+++ b/drivers/iommu/exynos-iommu.c
@@ -180,6 +180,47 @@ static u32 lv2ent_offset(sysmmu_iova_t iova)
 
 #define has_sysmmu(dev)		(dev_iommu_priv_get(dev) != NULL)
 
+#define MMU_REG(data, idx)		\
+	((data)->sfrbase + (data)->regs[idx].off)
+#define MMU_VM_REG(data, idx, vmid)	\
+	(MMU_REG(data, idx) + (vmid) * (data)->regs[idx].mult)
+
+enum {
+	REG_SET_NON_VM,
+	REG_SET_VM,
+	MAX_REG_SET
+};
+
+enum {
+	IDX_CTRL_VM,
+	IDX_CFG_VM,
+	IDX_FLPT_BASE,
+	IDX_ALL_INV,
+	MAX_REG_IDX
+};
+
+struct sysmmu_vm_reg {
+	unsigned int off;	/* register offset */
+	unsigned int mult;	/* VM index offset multiplier */
+};
+
+static const struct sysmmu_vm_reg sysmmu_regs[MAX_REG_SET][MAX_REG_IDX] = {
+	/* Default register set (non-VM) */
+	{
+		/*
+		 * SysMMUs without VM support do not have CTRL_VM and CFG_VM
+		 * registers. Setting the offsets to 1 will trigger an unaligned
+		 * access exception.
+		 */
+		{0x1}, {0x1}, {0x000c}, {0x0010},
+	},
+	/* VM capable register set */
+	{
+		{0x8000, 0x1000}, {0x8004, 0x1000}, {0x800c, 0x1000},
+		{0x8010, 0x1000},
+	},
+};
+
 static struct device *dma_dev;
 static struct kmem_cache *lv2table_kmem_cache;
 static sysmmu_pte_t *zero_lv2_table;
@@ -284,6 +325,7 @@ struct sysmmu_drvdata {
 
 	/* v7 fields */
 	bool has_vcr;			/* virtual machine control register */
+	const struct sysmmu_vm_reg *regs; /* register set */
 };
 
 static struct exynos_iommu_domain *to_exynos_domain(struct iommu_domain *dom)
@@ -407,6 +449,10 @@ static void sysmmu_get_hw_info(struct sysmmu_drvdata *data)
 	__sysmmu_get_version(data);
 	if (MMU_MAJ_VER(data->version) >= 7 && __sysmmu_has_capa1(data))
 		__sysmmu_get_vcr(data);
+	if (data->has_vcr)
+		data->regs = sysmmu_regs[REG_SET_VM];
+	else
+		data->regs = sysmmu_regs[REG_SET_NON_VM];
 
 	__sysmmu_disable_clocks(data);
 }
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 47+ messages in thread

* [PATCH 3/4] iommu/exynos: Use lookup based approach to access v7 registers
@ 2022-07-02 21:37   ` Sam Protsenko
  0 siblings, 0 replies; 47+ messages in thread
From: Sam Protsenko @ 2022-07-02 21:37 UTC (permalink / raw)
  To: Marek Szyprowski, Krzysztof Kozlowski
  Cc: Janghyuck Kim, linux-samsung-soc, Will Deacon, iommu,
	linux-kernel, iommu, Cho KyongHo, Robin Murphy, Sumit Semwal,
	linux-arm-kernel

SysMMU v7 might have different register layouts (VM capable or non-VM
capable). Check which layout is implemented in current SysMMU module and
prepare the corresponding register table for futher usage. This way is
faster and more elegant than checking corresponding condition (if it's
VM or non-VM SysMMU) each time before accessing v7 registers. For now
the register table contains only most basic registers needed to add the
SysMMU v7 support.

This patch is based on downstream work of next authors:
  - Janghyuck Kim <janghyuck.kim@samsung.com>
  - Daniel Mentz <danielmentz@google.com>

Signed-off-by: Sam Protsenko <semen.protsenko@linaro.org>
---
 drivers/iommu/exynos-iommu.c | 46 ++++++++++++++++++++++++++++++++++++
 1 file changed, 46 insertions(+)

diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
index df6ddbebbe2b..47017e8945c5 100644
--- a/drivers/iommu/exynos-iommu.c
+++ b/drivers/iommu/exynos-iommu.c
@@ -180,6 +180,47 @@ static u32 lv2ent_offset(sysmmu_iova_t iova)
 
 #define has_sysmmu(dev)		(dev_iommu_priv_get(dev) != NULL)
 
+#define MMU_REG(data, idx)		\
+	((data)->sfrbase + (data)->regs[idx].off)
+#define MMU_VM_REG(data, idx, vmid)	\
+	(MMU_REG(data, idx) + (vmid) * (data)->regs[idx].mult)
+
+enum {
+	REG_SET_NON_VM,
+	REG_SET_VM,
+	MAX_REG_SET
+};
+
+enum {
+	IDX_CTRL_VM,
+	IDX_CFG_VM,
+	IDX_FLPT_BASE,
+	IDX_ALL_INV,
+	MAX_REG_IDX
+};
+
+struct sysmmu_vm_reg {
+	unsigned int off;	/* register offset */
+	unsigned int mult;	/* VM index offset multiplier */
+};
+
+static const struct sysmmu_vm_reg sysmmu_regs[MAX_REG_SET][MAX_REG_IDX] = {
+	/* Default register set (non-VM) */
+	{
+		/*
+		 * SysMMUs without VM support do not have CTRL_VM and CFG_VM
+		 * registers. Setting the offsets to 1 will trigger an unaligned
+		 * access exception.
+		 */
+		{0x1}, {0x1}, {0x000c}, {0x0010},
+	},
+	/* VM capable register set */
+	{
+		{0x8000, 0x1000}, {0x8004, 0x1000}, {0x800c, 0x1000},
+		{0x8010, 0x1000},
+	},
+};
+
 static struct device *dma_dev;
 static struct kmem_cache *lv2table_kmem_cache;
 static sysmmu_pte_t *zero_lv2_table;
@@ -284,6 +325,7 @@ struct sysmmu_drvdata {
 
 	/* v7 fields */
 	bool has_vcr;			/* virtual machine control register */
+	const struct sysmmu_vm_reg *regs; /* register set */
 };
 
 static struct exynos_iommu_domain *to_exynos_domain(struct iommu_domain *dom)
@@ -407,6 +449,10 @@ static void sysmmu_get_hw_info(struct sysmmu_drvdata *data)
 	__sysmmu_get_version(data);
 	if (MMU_MAJ_VER(data->version) >= 7 && __sysmmu_has_capa1(data))
 		__sysmmu_get_vcr(data);
+	if (data->has_vcr)
+		data->regs = sysmmu_regs[REG_SET_VM];
+	else
+		data->regs = sysmmu_regs[REG_SET_NON_VM];
 
 	__sysmmu_disable_clocks(data);
 }
-- 
2.30.2

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

^ permalink raw reply related	[flat|nested] 47+ messages in thread

* [PATCH 3/4] iommu/exynos: Use lookup based approach to access v7 registers
@ 2022-07-02 21:37   ` Sam Protsenko
  0 siblings, 0 replies; 47+ messages in thread
From: Sam Protsenko @ 2022-07-02 21:37 UTC (permalink / raw)
  To: Marek Szyprowski, Krzysztof Kozlowski
  Cc: Joerg Roedel, Will Deacon, Robin Murphy, Janghyuck Kim,
	Cho KyongHo, Daniel Mentz, Sumit Semwal, iommu, iommu,
	linux-arm-kernel, linux-samsung-soc, linux-kernel

SysMMU v7 might have different register layouts (VM capable or non-VM
capable). Check which layout is implemented in current SysMMU module and
prepare the corresponding register table for futher usage. This way is
faster and more elegant than checking corresponding condition (if it's
VM or non-VM SysMMU) each time before accessing v7 registers. For now
the register table contains only most basic registers needed to add the
SysMMU v7 support.

This patch is based on downstream work of next authors:
  - Janghyuck Kim <janghyuck.kim@samsung.com>
  - Daniel Mentz <danielmentz@google.com>

Signed-off-by: Sam Protsenko <semen.protsenko@linaro.org>
---
 drivers/iommu/exynos-iommu.c | 46 ++++++++++++++++++++++++++++++++++++
 1 file changed, 46 insertions(+)

diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
index df6ddbebbe2b..47017e8945c5 100644
--- a/drivers/iommu/exynos-iommu.c
+++ b/drivers/iommu/exynos-iommu.c
@@ -180,6 +180,47 @@ static u32 lv2ent_offset(sysmmu_iova_t iova)
 
 #define has_sysmmu(dev)		(dev_iommu_priv_get(dev) != NULL)
 
+#define MMU_REG(data, idx)		\
+	((data)->sfrbase + (data)->regs[idx].off)
+#define MMU_VM_REG(data, idx, vmid)	\
+	(MMU_REG(data, idx) + (vmid) * (data)->regs[idx].mult)
+
+enum {
+	REG_SET_NON_VM,
+	REG_SET_VM,
+	MAX_REG_SET
+};
+
+enum {
+	IDX_CTRL_VM,
+	IDX_CFG_VM,
+	IDX_FLPT_BASE,
+	IDX_ALL_INV,
+	MAX_REG_IDX
+};
+
+struct sysmmu_vm_reg {
+	unsigned int off;	/* register offset */
+	unsigned int mult;	/* VM index offset multiplier */
+};
+
+static const struct sysmmu_vm_reg sysmmu_regs[MAX_REG_SET][MAX_REG_IDX] = {
+	/* Default register set (non-VM) */
+	{
+		/*
+		 * SysMMUs without VM support do not have CTRL_VM and CFG_VM
+		 * registers. Setting the offsets to 1 will trigger an unaligned
+		 * access exception.
+		 */
+		{0x1}, {0x1}, {0x000c}, {0x0010},
+	},
+	/* VM capable register set */
+	{
+		{0x8000, 0x1000}, {0x8004, 0x1000}, {0x800c, 0x1000},
+		{0x8010, 0x1000},
+	},
+};
+
 static struct device *dma_dev;
 static struct kmem_cache *lv2table_kmem_cache;
 static sysmmu_pte_t *zero_lv2_table;
@@ -284,6 +325,7 @@ struct sysmmu_drvdata {
 
 	/* v7 fields */
 	bool has_vcr;			/* virtual machine control register */
+	const struct sysmmu_vm_reg *regs; /* register set */
 };
 
 static struct exynos_iommu_domain *to_exynos_domain(struct iommu_domain *dom)
@@ -407,6 +449,10 @@ static void sysmmu_get_hw_info(struct sysmmu_drvdata *data)
 	__sysmmu_get_version(data);
 	if (MMU_MAJ_VER(data->version) >= 7 && __sysmmu_has_capa1(data))
 		__sysmmu_get_vcr(data);
+	if (data->has_vcr)
+		data->regs = sysmmu_regs[REG_SET_VM];
+	else
+		data->regs = sysmmu_regs[REG_SET_NON_VM];
 
 	__sysmmu_disable_clocks(data);
 }
-- 
2.30.2


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 47+ messages in thread

* [PATCH 4/4] iommu/exynos: Add minimal support for SysMMU v7 with VM registers
  2022-07-02 21:37 ` Sam Protsenko
  (?)
@ 2022-07-02 21:37   ` Sam Protsenko
  -1 siblings, 0 replies; 47+ messages in thread
From: Sam Protsenko @ 2022-07-02 21:37 UTC (permalink / raw)
  To: Marek Szyprowski, Krzysztof Kozlowski
  Cc: Joerg Roedel, Will Deacon, Robin Murphy, Janghyuck Kim,
	Cho KyongHo, Daniel Mentz, Sumit Semwal, iommu, iommu,
	linux-arm-kernel, linux-samsung-soc, linux-kernel

Add minimal viable support for SysMMU v7.x, which can be found in modern
Exynos chips (like Exynos850). SysMMU v7.x may implement VM register
set, and those registers should be initialized properly if present.
Usually 8 translation domains are supported via VM registers (0..7), but
only n=0 (default) is used for now.

Changes are as follows:
  - add enabling the default VID instance before enabling SysMMU
  - use v7 VM register for setting the page table base address
  - use v7 VM register for invalidation

Insights for those changes were taken by comparing the I/O dump
(writel() / readl() operations) for vendor driver and this upstream
driver.

It was tested on E850-96 board, which has SysMMU v7.4 with VM registers
present. The testing was done using "Emulated Translation" registers.
That allows initiating translations with no actual users of that IOMMU,
and checking the result by reading the TLB info from corresponding
registers.

Thanks to Marek, who did let me know it only takes a slight change of
registers to make this driver work with v7.

Signed-off-by: Sam Protsenko <semen.protsenko@linaro.org>
---
 drivers/iommu/exynos-iommu.c | 16 ++++++++++++++--
 1 file changed, 14 insertions(+), 2 deletions(-)

diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
index 47017e8945c5..b7b4833161bc 100644
--- a/drivers/iommu/exynos-iommu.c
+++ b/drivers/iommu/exynos-iommu.c
@@ -135,6 +135,8 @@ static u32 lv2ent_offset(sysmmu_iova_t iova)
 #define CFG_SYSSEL	(1 << 22) /* System MMU 3.2 only */
 #define CFG_FLPDCACHE	(1 << 20) /* System MMU 3.2+ only */
 
+#define CTRL_VM_ENABLE			BIT(0)
+#define CTRL_VM_FAULT_MODE_STALL	BIT(3)
 #define CAPA0_CAPA1_EXIST		BIT(11)
 #define CAPA1_VCR_ENABLED		BIT(14)
 
@@ -358,8 +360,10 @@ static void __sysmmu_tlb_invalidate(struct sysmmu_drvdata *data)
 {
 	if (MMU_MAJ_VER(data->version) < 5)
 		writel(0x1, data->sfrbase + REG_MMU_FLUSH);
-	else
+	else if (MMU_MAJ_VER(data->version) < 7)
 		writel(0x1, data->sfrbase + REG_V5_MMU_FLUSH_ALL);
+	else
+		writel(0x1, MMU_VM_REG(data, IDX_ALL_INV, 0));
 }
 
 static void __sysmmu_tlb_invalidate_entry(struct sysmmu_drvdata *data,
@@ -391,9 +395,11 @@ static void __sysmmu_set_ptbase(struct sysmmu_drvdata *data, phys_addr_t pgd)
 {
 	if (MMU_MAJ_VER(data->version) < 5)
 		writel(pgd, data->sfrbase + REG_PT_BASE_ADDR);
-	else
+	else if (MMU_MAJ_VER(data->version) < 7)
 		writel(pgd >> PAGE_SHIFT,
 			     data->sfrbase + REG_V5_PT_BASE_PFN);
+	else
+		writel(pgd >> SPAGE_ORDER, MMU_VM_REG(data, IDX_FLPT_BASE, 0));
 
 	__sysmmu_tlb_invalidate(data);
 }
@@ -571,6 +577,12 @@ static void __sysmmu_enable(struct sysmmu_drvdata *data)
 	writel(CTRL_BLOCK, data->sfrbase + REG_MMU_CTRL);
 	__sysmmu_init_config(data);
 	__sysmmu_set_ptbase(data, data->pgtable);
+	if (MMU_MAJ_VER(data->version) >= 7 && data->has_vcr) {
+		u32 ctrl = readl(MMU_VM_REG(data, IDX_CTRL_VM, 0));
+
+		ctrl |= CTRL_VM_ENABLE | CTRL_VM_FAULT_MODE_STALL;
+		writel(ctrl, MMU_VM_REG(data, IDX_CTRL_VM, 0));
+	}
 	writel(CTRL_ENABLE, data->sfrbase + REG_MMU_CTRL);
 	data->active = true;
 	spin_unlock_irqrestore(&data->lock, flags);
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 47+ messages in thread

* [PATCH 4/4] iommu/exynos: Add minimal support for SysMMU v7 with VM registers
@ 2022-07-02 21:37   ` Sam Protsenko
  0 siblings, 0 replies; 47+ messages in thread
From: Sam Protsenko @ 2022-07-02 21:37 UTC (permalink / raw)
  To: Marek Szyprowski, Krzysztof Kozlowski
  Cc: Janghyuck Kim, linux-samsung-soc, Will Deacon, iommu,
	linux-kernel, iommu, Cho KyongHo, Robin Murphy, Sumit Semwal,
	linux-arm-kernel

Add minimal viable support for SysMMU v7.x, which can be found in modern
Exynos chips (like Exynos850). SysMMU v7.x may implement VM register
set, and those registers should be initialized properly if present.
Usually 8 translation domains are supported via VM registers (0..7), but
only n=0 (default) is used for now.

Changes are as follows:
  - add enabling the default VID instance before enabling SysMMU
  - use v7 VM register for setting the page table base address
  - use v7 VM register for invalidation

Insights for those changes were taken by comparing the I/O dump
(writel() / readl() operations) for vendor driver and this upstream
driver.

It was tested on E850-96 board, which has SysMMU v7.4 with VM registers
present. The testing was done using "Emulated Translation" registers.
That allows initiating translations with no actual users of that IOMMU,
and checking the result by reading the TLB info from corresponding
registers.

Thanks to Marek, who did let me know it only takes a slight change of
registers to make this driver work with v7.

Signed-off-by: Sam Protsenko <semen.protsenko@linaro.org>
---
 drivers/iommu/exynos-iommu.c | 16 ++++++++++++++--
 1 file changed, 14 insertions(+), 2 deletions(-)

diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
index 47017e8945c5..b7b4833161bc 100644
--- a/drivers/iommu/exynos-iommu.c
+++ b/drivers/iommu/exynos-iommu.c
@@ -135,6 +135,8 @@ static u32 lv2ent_offset(sysmmu_iova_t iova)
 #define CFG_SYSSEL	(1 << 22) /* System MMU 3.2 only */
 #define CFG_FLPDCACHE	(1 << 20) /* System MMU 3.2+ only */
 
+#define CTRL_VM_ENABLE			BIT(0)
+#define CTRL_VM_FAULT_MODE_STALL	BIT(3)
 #define CAPA0_CAPA1_EXIST		BIT(11)
 #define CAPA1_VCR_ENABLED		BIT(14)
 
@@ -358,8 +360,10 @@ static void __sysmmu_tlb_invalidate(struct sysmmu_drvdata *data)
 {
 	if (MMU_MAJ_VER(data->version) < 5)
 		writel(0x1, data->sfrbase + REG_MMU_FLUSH);
-	else
+	else if (MMU_MAJ_VER(data->version) < 7)
 		writel(0x1, data->sfrbase + REG_V5_MMU_FLUSH_ALL);
+	else
+		writel(0x1, MMU_VM_REG(data, IDX_ALL_INV, 0));
 }
 
 static void __sysmmu_tlb_invalidate_entry(struct sysmmu_drvdata *data,
@@ -391,9 +395,11 @@ static void __sysmmu_set_ptbase(struct sysmmu_drvdata *data, phys_addr_t pgd)
 {
 	if (MMU_MAJ_VER(data->version) < 5)
 		writel(pgd, data->sfrbase + REG_PT_BASE_ADDR);
-	else
+	else if (MMU_MAJ_VER(data->version) < 7)
 		writel(pgd >> PAGE_SHIFT,
 			     data->sfrbase + REG_V5_PT_BASE_PFN);
+	else
+		writel(pgd >> SPAGE_ORDER, MMU_VM_REG(data, IDX_FLPT_BASE, 0));
 
 	__sysmmu_tlb_invalidate(data);
 }
@@ -571,6 +577,12 @@ static void __sysmmu_enable(struct sysmmu_drvdata *data)
 	writel(CTRL_BLOCK, data->sfrbase + REG_MMU_CTRL);
 	__sysmmu_init_config(data);
 	__sysmmu_set_ptbase(data, data->pgtable);
+	if (MMU_MAJ_VER(data->version) >= 7 && data->has_vcr) {
+		u32 ctrl = readl(MMU_VM_REG(data, IDX_CTRL_VM, 0));
+
+		ctrl |= CTRL_VM_ENABLE | CTRL_VM_FAULT_MODE_STALL;
+		writel(ctrl, MMU_VM_REG(data, IDX_CTRL_VM, 0));
+	}
 	writel(CTRL_ENABLE, data->sfrbase + REG_MMU_CTRL);
 	data->active = true;
 	spin_unlock_irqrestore(&data->lock, flags);
-- 
2.30.2

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

^ permalink raw reply related	[flat|nested] 47+ messages in thread

* [PATCH 4/4] iommu/exynos: Add minimal support for SysMMU v7 with VM registers
@ 2022-07-02 21:37   ` Sam Protsenko
  0 siblings, 0 replies; 47+ messages in thread
From: Sam Protsenko @ 2022-07-02 21:37 UTC (permalink / raw)
  To: Marek Szyprowski, Krzysztof Kozlowski
  Cc: Joerg Roedel, Will Deacon, Robin Murphy, Janghyuck Kim,
	Cho KyongHo, Daniel Mentz, Sumit Semwal, iommu, iommu,
	linux-arm-kernel, linux-samsung-soc, linux-kernel

Add minimal viable support for SysMMU v7.x, which can be found in modern
Exynos chips (like Exynos850). SysMMU v7.x may implement VM register
set, and those registers should be initialized properly if present.
Usually 8 translation domains are supported via VM registers (0..7), but
only n=0 (default) is used for now.

Changes are as follows:
  - add enabling the default VID instance before enabling SysMMU
  - use v7 VM register for setting the page table base address
  - use v7 VM register for invalidation

Insights for those changes were taken by comparing the I/O dump
(writel() / readl() operations) for vendor driver and this upstream
driver.

It was tested on E850-96 board, which has SysMMU v7.4 with VM registers
present. The testing was done using "Emulated Translation" registers.
That allows initiating translations with no actual users of that IOMMU,
and checking the result by reading the TLB info from corresponding
registers.

Thanks to Marek, who did let me know it only takes a slight change of
registers to make this driver work with v7.

Signed-off-by: Sam Protsenko <semen.protsenko@linaro.org>
---
 drivers/iommu/exynos-iommu.c | 16 ++++++++++++++--
 1 file changed, 14 insertions(+), 2 deletions(-)

diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
index 47017e8945c5..b7b4833161bc 100644
--- a/drivers/iommu/exynos-iommu.c
+++ b/drivers/iommu/exynos-iommu.c
@@ -135,6 +135,8 @@ static u32 lv2ent_offset(sysmmu_iova_t iova)
 #define CFG_SYSSEL	(1 << 22) /* System MMU 3.2 only */
 #define CFG_FLPDCACHE	(1 << 20) /* System MMU 3.2+ only */
 
+#define CTRL_VM_ENABLE			BIT(0)
+#define CTRL_VM_FAULT_MODE_STALL	BIT(3)
 #define CAPA0_CAPA1_EXIST		BIT(11)
 #define CAPA1_VCR_ENABLED		BIT(14)
 
@@ -358,8 +360,10 @@ static void __sysmmu_tlb_invalidate(struct sysmmu_drvdata *data)
 {
 	if (MMU_MAJ_VER(data->version) < 5)
 		writel(0x1, data->sfrbase + REG_MMU_FLUSH);
-	else
+	else if (MMU_MAJ_VER(data->version) < 7)
 		writel(0x1, data->sfrbase + REG_V5_MMU_FLUSH_ALL);
+	else
+		writel(0x1, MMU_VM_REG(data, IDX_ALL_INV, 0));
 }
 
 static void __sysmmu_tlb_invalidate_entry(struct sysmmu_drvdata *data,
@@ -391,9 +395,11 @@ static void __sysmmu_set_ptbase(struct sysmmu_drvdata *data, phys_addr_t pgd)
 {
 	if (MMU_MAJ_VER(data->version) < 5)
 		writel(pgd, data->sfrbase + REG_PT_BASE_ADDR);
-	else
+	else if (MMU_MAJ_VER(data->version) < 7)
 		writel(pgd >> PAGE_SHIFT,
 			     data->sfrbase + REG_V5_PT_BASE_PFN);
+	else
+		writel(pgd >> SPAGE_ORDER, MMU_VM_REG(data, IDX_FLPT_BASE, 0));
 
 	__sysmmu_tlb_invalidate(data);
 }
@@ -571,6 +577,12 @@ static void __sysmmu_enable(struct sysmmu_drvdata *data)
 	writel(CTRL_BLOCK, data->sfrbase + REG_MMU_CTRL);
 	__sysmmu_init_config(data);
 	__sysmmu_set_ptbase(data, data->pgtable);
+	if (MMU_MAJ_VER(data->version) >= 7 && data->has_vcr) {
+		u32 ctrl = readl(MMU_VM_REG(data, IDX_CTRL_VM, 0));
+
+		ctrl |= CTRL_VM_ENABLE | CTRL_VM_FAULT_MODE_STALL;
+		writel(ctrl, MMU_VM_REG(data, IDX_CTRL_VM, 0));
+	}
 	writel(CTRL_ENABLE, data->sfrbase + REG_MMU_CTRL);
 	data->active = true;
 	spin_unlock_irqrestore(&data->lock, flags);
-- 
2.30.2


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 47+ messages in thread

* Re: [PATCH 0/4] iommu/exynos: Add basic support for SysMMU v7
  2022-07-02 21:37 ` Sam Protsenko
  (?)
@ 2022-07-02 21:48   ` Sam Protsenko
  -1 siblings, 0 replies; 47+ messages in thread
From: Sam Protsenko @ 2022-07-02 21:48 UTC (permalink / raw)
  To: Marek Szyprowski
  Cc: Krzysztof Kozlowski, Joerg Roedel, Will Deacon, Robin Murphy,
	Janghyuck Kim, Cho KyongHo, Daniel Mentz, Sumit Semwal, iommu,
	iommu, linux-arm-kernel, linux-samsung-soc, linux-kernel

On Sun, 3 Jul 2022 at 00:37, Sam Protsenko <semen.protsenko@linaro.org> wrote:
>
> Existing exynos-iommu driver only supports SysMMU versions up to v5. But
> it's pretty much ready for basic usage with SysMMU v7, only small
> changes have to be done. As SysMMU version is tested dynamically (by
> reading the corresponding register), there is no need to introduce new
> compatible string.
>
> One major change is that SysMMU v7 can have different register layouts:
>   - with Virtual Machine support
>   - without Virtual Machine support
>
> That can be checked by reading the capability registers. In case the
> SysMMU IP-core is VM-capable, the VM registers have to be used, and some
> additional initialization is needed. That is the case on E850-96 board,
> which non-secure SysMMU (v7.4) implements VM-capable register set.
>
> The patch series was tested on E850-96 board. Because at the moment
> there are no SysMMU users for that board, the testing was done using so
> called "Emulated Translation" registers available on SysMMU v7. That
> allows one to initiate the translation from CPU, by writing to those
> registers, and then reading the corresponding TLB registers to find out
> the translation result. The testing driver can be found in [1] tree.
>
> [1] https://github.com/joe-skb7/linux/tree/e850-96-mainline-iommu
>
> Sam Protsenko (4):
>   iommu/exynos: Set correct dma mask for SysMMU v5+
>   iommu/exynos: Check if SysMMU v7 has VM registers
>   iommu/exynos: Use lookup based approach to access v7 registers
>   iommu/exynos: Add minimal support for SysMMU v7 with VM registers
>
>  drivers/iommu/exynos-iommu.c | 112 ++++++++++++++++++++++++++++++++---
>  1 file changed, 104 insertions(+), 8 deletions(-)
>
> --
> 2.30.2
>

Hi Marek,

As I understand, you have some board with SysMMU v7, which is not VM
capable (judging from the patches you shared earlier). Could you
please somehow verify if this series works fine for you? For example,
this testing driver [1] can be helpful.

Thanks!

[1] https://github.com/joe-skb7/linux/commit/bbadd46fa525fe1fef2ccbdfff81f7d29caf0506

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH 0/4] iommu/exynos: Add basic support for SysMMU v7
@ 2022-07-02 21:48   ` Sam Protsenko
  0 siblings, 0 replies; 47+ messages in thread
From: Sam Protsenko @ 2022-07-02 21:48 UTC (permalink / raw)
  To: Marek Szyprowski
  Cc: Janghyuck Kim, linux-samsung-soc, iommu, Will Deacon, iommu,
	linux-kernel, Krzysztof Kozlowski, Cho KyongHo, Robin Murphy,
	Sumit Semwal, linux-arm-kernel

On Sun, 3 Jul 2022 at 00:37, Sam Protsenko <semen.protsenko@linaro.org> wrote:
>
> Existing exynos-iommu driver only supports SysMMU versions up to v5. But
> it's pretty much ready for basic usage with SysMMU v7, only small
> changes have to be done. As SysMMU version is tested dynamically (by
> reading the corresponding register), there is no need to introduce new
> compatible string.
>
> One major change is that SysMMU v7 can have different register layouts:
>   - with Virtual Machine support
>   - without Virtual Machine support
>
> That can be checked by reading the capability registers. In case the
> SysMMU IP-core is VM-capable, the VM registers have to be used, and some
> additional initialization is needed. That is the case on E850-96 board,
> which non-secure SysMMU (v7.4) implements VM-capable register set.
>
> The patch series was tested on E850-96 board. Because at the moment
> there are no SysMMU users for that board, the testing was done using so
> called "Emulated Translation" registers available on SysMMU v7. That
> allows one to initiate the translation from CPU, by writing to those
> registers, and then reading the corresponding TLB registers to find out
> the translation result. The testing driver can be found in [1] tree.
>
> [1] https://github.com/joe-skb7/linux/tree/e850-96-mainline-iommu
>
> Sam Protsenko (4):
>   iommu/exynos: Set correct dma mask for SysMMU v5+
>   iommu/exynos: Check if SysMMU v7 has VM registers
>   iommu/exynos: Use lookup based approach to access v7 registers
>   iommu/exynos: Add minimal support for SysMMU v7 with VM registers
>
>  drivers/iommu/exynos-iommu.c | 112 ++++++++++++++++++++++++++++++++---
>  1 file changed, 104 insertions(+), 8 deletions(-)
>
> --
> 2.30.2
>

Hi Marek,

As I understand, you have some board with SysMMU v7, which is not VM
capable (judging from the patches you shared earlier). Could you
please somehow verify if this series works fine for you? For example,
this testing driver [1] can be helpful.

Thanks!

[1] https://github.com/joe-skb7/linux/commit/bbadd46fa525fe1fef2ccbdfff81f7d29caf0506
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH 0/4] iommu/exynos: Add basic support for SysMMU v7
@ 2022-07-02 21:48   ` Sam Protsenko
  0 siblings, 0 replies; 47+ messages in thread
From: Sam Protsenko @ 2022-07-02 21:48 UTC (permalink / raw)
  To: Marek Szyprowski
  Cc: Krzysztof Kozlowski, Joerg Roedel, Will Deacon, Robin Murphy,
	Janghyuck Kim, Cho KyongHo, Daniel Mentz, Sumit Semwal, iommu,
	iommu, linux-arm-kernel, linux-samsung-soc, linux-kernel

On Sun, 3 Jul 2022 at 00:37, Sam Protsenko <semen.protsenko@linaro.org> wrote:
>
> Existing exynos-iommu driver only supports SysMMU versions up to v5. But
> it's pretty much ready for basic usage with SysMMU v7, only small
> changes have to be done. As SysMMU version is tested dynamically (by
> reading the corresponding register), there is no need to introduce new
> compatible string.
>
> One major change is that SysMMU v7 can have different register layouts:
>   - with Virtual Machine support
>   - without Virtual Machine support
>
> That can be checked by reading the capability registers. In case the
> SysMMU IP-core is VM-capable, the VM registers have to be used, and some
> additional initialization is needed. That is the case on E850-96 board,
> which non-secure SysMMU (v7.4) implements VM-capable register set.
>
> The patch series was tested on E850-96 board. Because at the moment
> there are no SysMMU users for that board, the testing was done using so
> called "Emulated Translation" registers available on SysMMU v7. That
> allows one to initiate the translation from CPU, by writing to those
> registers, and then reading the corresponding TLB registers to find out
> the translation result. The testing driver can be found in [1] tree.
>
> [1] https://github.com/joe-skb7/linux/tree/e850-96-mainline-iommu
>
> Sam Protsenko (4):
>   iommu/exynos: Set correct dma mask for SysMMU v5+
>   iommu/exynos: Check if SysMMU v7 has VM registers
>   iommu/exynos: Use lookup based approach to access v7 registers
>   iommu/exynos: Add minimal support for SysMMU v7 with VM registers
>
>  drivers/iommu/exynos-iommu.c | 112 ++++++++++++++++++++++++++++++++---
>  1 file changed, 104 insertions(+), 8 deletions(-)
>
> --
> 2.30.2
>

Hi Marek,

As I understand, you have some board with SysMMU v7, which is not VM
capable (judging from the patches you shared earlier). Could you
please somehow verify if this series works fine for you? For example,
this testing driver [1] can be helpful.

Thanks!

[1] https://github.com/joe-skb7/linux/commit/bbadd46fa525fe1fef2ccbdfff81f7d29caf0506

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH 0/4] iommu/exynos: Add basic support for SysMMU v7
  2022-07-02 21:48   ` Sam Protsenko
  (?)
@ 2022-07-03 12:47     ` David Virag
  -1 siblings, 0 replies; 47+ messages in thread
From: David Virag @ 2022-07-03 12:47 UTC (permalink / raw)
  To: Sam Protsenko, Marek Szyprowski
  Cc: Krzysztof Kozlowski, Joerg Roedel, Will Deacon, Robin Murphy,
	Janghyuck Kim, Cho KyongHo, Daniel Mentz, Sumit Semwal, iommu,
	iommu, linux-arm-kernel, linux-samsung-soc, linux-kernel

On Sun, 2022-07-03 at 00:48 +0300, Sam Protsenko wrote:
[...]
> Hi Marek,
> 
> As I understand, you have some board with SysMMU v7, which is not VM
> capable (judging from the patches you shared earlier). Could you
> please somehow verify if this series works fine for you? For example,
> this testing driver [1] can be helpful.
> 
> Thanks!
> 
> [1]
> https://github.com/joe-skb7/linux/commit/bbadd46fa525fe1fef2ccbdfff81f7d29caf0506

Hi Sam,

Not Marek here, but I wanted to try this on my jackpotlte (Exynos
7885). The driver reports it's DPU sysmmu as version 7.2, and manually
reading the capabilities registers it looks like it has the 2nd
capability register but not the VM capability.

After applying your patches, adding your test driver (with SYSMMU_BASE
corrected to 7885 value), and adding the sysmmu to dt, I tried to cat
the test file that it creates in debugfs and I got an SError kernel
panic.

I tried tracing where the SError happens and it looks like it's this
line:
	/* Preload for emulation */
	iowrite32(rw | vpn, obj->reg_base + MMU_EMU_PRELOAD);

Trying to read the EMU registers using devmem results in a "Bus error".

Could these emulation registers be missing from my SysMMU? Do you have
any info on what version should have it? Or maybe some capability bit?
I'll try testing it with DECON/DPP later and see if it works that way.

Best regards,
David

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH 0/4] iommu/exynos: Add basic support for SysMMU v7
@ 2022-07-03 12:47     ` David Virag
  0 siblings, 0 replies; 47+ messages in thread
From: David Virag @ 2022-07-03 12:47 UTC (permalink / raw)
  To: Sam Protsenko, Marek Szyprowski
  Cc: Krzysztof Kozlowski, Joerg Roedel, Will Deacon, Robin Murphy,
	Janghyuck Kim, Cho KyongHo, Daniel Mentz, Sumit Semwal, iommu,
	iommu, linux-arm-kernel, linux-samsung-soc, linux-kernel

On Sun, 2022-07-03 at 00:48 +0300, Sam Protsenko wrote:
[...]
> Hi Marek,
> 
> As I understand, you have some board with SysMMU v7, which is not VM
> capable (judging from the patches you shared earlier). Could you
> please somehow verify if this series works fine for you? For example,
> this testing driver [1] can be helpful.
> 
> Thanks!
> 
> [1]
> https://github.com/joe-skb7/linux/commit/bbadd46fa525fe1fef2ccbdfff81f7d29caf0506

Hi Sam,

Not Marek here, but I wanted to try this on my jackpotlte (Exynos
7885). The driver reports it's DPU sysmmu as version 7.2, and manually
reading the capabilities registers it looks like it has the 2nd
capability register but not the VM capability.

After applying your patches, adding your test driver (with SYSMMU_BASE
corrected to 7885 value), and adding the sysmmu to dt, I tried to cat
the test file that it creates in debugfs and I got an SError kernel
panic.

I tried tracing where the SError happens and it looks like it's this
line:
	/* Preload for emulation */
	iowrite32(rw | vpn, obj->reg_base + MMU_EMU_PRELOAD);

Trying to read the EMU registers using devmem results in a "Bus error".

Could these emulation registers be missing from my SysMMU? Do you have
any info on what version should have it? Or maybe some capability bit?
I'll try testing it with DECON/DPP later and see if it works that way.

Best regards,
David

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH 0/4] iommu/exynos: Add basic support for SysMMU v7
@ 2022-07-03 12:47     ` David Virag
  0 siblings, 0 replies; 47+ messages in thread
From: David Virag @ 2022-07-03 12:47 UTC (permalink / raw)
  To: Sam Protsenko, Marek Szyprowski
  Cc: Janghyuck Kim, linux-samsung-soc, iommu, Will Deacon, iommu,
	linux-kernel, Krzysztof Kozlowski, Cho KyongHo, Robin Murphy,
	Sumit Semwal, linux-arm-kernel

On Sun, 2022-07-03 at 00:48 +0300, Sam Protsenko wrote:
[...]
> Hi Marek,
> 
> As I understand, you have some board with SysMMU v7, which is not VM
> capable (judging from the patches you shared earlier). Could you
> please somehow verify if this series works fine for you? For example,
> this testing driver [1] can be helpful.
> 
> Thanks!
> 
> [1]
> https://github.com/joe-skb7/linux/commit/bbadd46fa525fe1fef2ccbdfff81f7d29caf0506

Hi Sam,

Not Marek here, but I wanted to try this on my jackpotlte (Exynos
7885). The driver reports it's DPU sysmmu as version 7.2, and manually
reading the capabilities registers it looks like it has the 2nd
capability register but not the VM capability.

After applying your patches, adding your test driver (with SYSMMU_BASE
corrected to 7885 value), and adding the sysmmu to dt, I tried to cat
the test file that it creates in debugfs and I got an SError kernel
panic.

I tried tracing where the SError happens and it looks like it's this
line:
	/* Preload for emulation */
	iowrite32(rw | vpn, obj->reg_base + MMU_EMU_PRELOAD);

Trying to read the EMU registers using devmem results in a "Bus error".

Could these emulation registers be missing from my SysMMU? Do you have
any info on what version should have it? Or maybe some capability bit?
I'll try testing it with DECON/DPP later and see if it works that way.

Best regards,
David
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH 1/4] iommu/exynos: Set correct dma mask for SysMMU v5+
  2022-07-02 21:37   ` Sam Protsenko
  (?)
@ 2022-07-03 18:50     ` Krzysztof Kozlowski
  -1 siblings, 0 replies; 47+ messages in thread
From: Krzysztof Kozlowski @ 2022-07-03 18:50 UTC (permalink / raw)
  To: Sam Protsenko, Marek Szyprowski
  Cc: Joerg Roedel, Will Deacon, Robin Murphy, Janghyuck Kim,
	Cho KyongHo, Daniel Mentz, Sumit Semwal, iommu, iommu,
	linux-arm-kernel, linux-samsung-soc, linux-kernel

On 02/07/2022 23:37, Sam Protsenko wrote:
> SysMMU v5+ supports 36 bit physical address space. Set corresponding DMA
> mask to avoid falling back to SWTLBIO usage in dma_map_single() because
> of failed dma_capable() check.
> 
> The original code for this fix was suggested by Marek.
> 
> Originally-by: Marek Szyprowski <m.szyprowski@samsung.com>

This is some tip specific tag, I don't think checkpatch allows it.
Either use suggesgted-by or co-developed-by + SoB.

> Signed-off-by: Sam Protsenko <semen.protsenko@linaro.org>
> ---
>  drivers/iommu/exynos-iommu.c | 8 ++++++++
>  1 file changed, 8 insertions(+)
> 
> diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
> index 71f2018e23fe..28f8c8d93aa3 100644
> --- a/drivers/iommu/exynos-iommu.c
> +++ b/drivers/iommu/exynos-iommu.c
> @@ -647,6 +647,14 @@ static int exynos_sysmmu_probe(struct platform_device *pdev)
>  		}
>  	}
>  
> +	if (MMU_MAJ_VER(data->version) >= 5) {
> +		ret = dma_set_mask(dev, DMA_BIT_MASK(36));
> +		if (ret) {
> +			dev_err(dev, "Unable to set DMA mask: %d\n", ret);

Missing cleanup: iommu_device_unregister
and probably also: iommu_device_sysfs_remove

> +			return ret;
> +		}
> +	}
> +
>  	/*
>  	 * use the first registered sysmmu device for performing
>  	 * dma mapping operations on iommu page tables (cpu cache flush)


Best regards,
Krzysztof

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH 1/4] iommu/exynos: Set correct dma mask for SysMMU v5+
@ 2022-07-03 18:50     ` Krzysztof Kozlowski
  0 siblings, 0 replies; 47+ messages in thread
From: Krzysztof Kozlowski @ 2022-07-03 18:50 UTC (permalink / raw)
  To: Sam Protsenko, Marek Szyprowski
  Cc: Janghyuck Kim, linux-samsung-soc, Will Deacon, iommu,
	linux-kernel, iommu, Cho KyongHo, Robin Murphy, Sumit Semwal,
	linux-arm-kernel

On 02/07/2022 23:37, Sam Protsenko wrote:
> SysMMU v5+ supports 36 bit physical address space. Set corresponding DMA
> mask to avoid falling back to SWTLBIO usage in dma_map_single() because
> of failed dma_capable() check.
> 
> The original code for this fix was suggested by Marek.
> 
> Originally-by: Marek Szyprowski <m.szyprowski@samsung.com>

This is some tip specific tag, I don't think checkpatch allows it.
Either use suggesgted-by or co-developed-by + SoB.

> Signed-off-by: Sam Protsenko <semen.protsenko@linaro.org>
> ---
>  drivers/iommu/exynos-iommu.c | 8 ++++++++
>  1 file changed, 8 insertions(+)
> 
> diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
> index 71f2018e23fe..28f8c8d93aa3 100644
> --- a/drivers/iommu/exynos-iommu.c
> +++ b/drivers/iommu/exynos-iommu.c
> @@ -647,6 +647,14 @@ static int exynos_sysmmu_probe(struct platform_device *pdev)
>  		}
>  	}
>  
> +	if (MMU_MAJ_VER(data->version) >= 5) {
> +		ret = dma_set_mask(dev, DMA_BIT_MASK(36));
> +		if (ret) {
> +			dev_err(dev, "Unable to set DMA mask: %d\n", ret);

Missing cleanup: iommu_device_unregister
and probably also: iommu_device_sysfs_remove

> +			return ret;
> +		}
> +	}
> +
>  	/*
>  	 * use the first registered sysmmu device for performing
>  	 * dma mapping operations on iommu page tables (cpu cache flush)


Best regards,
Krzysztof
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH 1/4] iommu/exynos: Set correct dma mask for SysMMU v5+
@ 2022-07-03 18:50     ` Krzysztof Kozlowski
  0 siblings, 0 replies; 47+ messages in thread
From: Krzysztof Kozlowski @ 2022-07-03 18:50 UTC (permalink / raw)
  To: Sam Protsenko, Marek Szyprowski
  Cc: Joerg Roedel, Will Deacon, Robin Murphy, Janghyuck Kim,
	Cho KyongHo, Daniel Mentz, Sumit Semwal, iommu, iommu,
	linux-arm-kernel, linux-samsung-soc, linux-kernel

On 02/07/2022 23:37, Sam Protsenko wrote:
> SysMMU v5+ supports 36 bit physical address space. Set corresponding DMA
> mask to avoid falling back to SWTLBIO usage in dma_map_single() because
> of failed dma_capable() check.
> 
> The original code for this fix was suggested by Marek.
> 
> Originally-by: Marek Szyprowski <m.szyprowski@samsung.com>

This is some tip specific tag, I don't think checkpatch allows it.
Either use suggesgted-by or co-developed-by + SoB.

> Signed-off-by: Sam Protsenko <semen.protsenko@linaro.org>
> ---
>  drivers/iommu/exynos-iommu.c | 8 ++++++++
>  1 file changed, 8 insertions(+)
> 
> diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
> index 71f2018e23fe..28f8c8d93aa3 100644
> --- a/drivers/iommu/exynos-iommu.c
> +++ b/drivers/iommu/exynos-iommu.c
> @@ -647,6 +647,14 @@ static int exynos_sysmmu_probe(struct platform_device *pdev)
>  		}
>  	}
>  
> +	if (MMU_MAJ_VER(data->version) >= 5) {
> +		ret = dma_set_mask(dev, DMA_BIT_MASK(36));
> +		if (ret) {
> +			dev_err(dev, "Unable to set DMA mask: %d\n", ret);

Missing cleanup: iommu_device_unregister
and probably also: iommu_device_sysfs_remove

> +			return ret;
> +		}
> +	}
> +
>  	/*
>  	 * use the first registered sysmmu device for performing
>  	 * dma mapping operations on iommu page tables (cpu cache flush)


Best regards,
Krzysztof

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH 2/4] iommu/exynos: Check if SysMMU v7 has VM registers
  2022-07-02 21:37   ` Sam Protsenko
  (?)
@ 2022-07-03 19:10     ` Krzysztof Kozlowski
  -1 siblings, 0 replies; 47+ messages in thread
From: Krzysztof Kozlowski @ 2022-07-03 19:10 UTC (permalink / raw)
  To: Sam Protsenko, Marek Szyprowski
  Cc: Joerg Roedel, Will Deacon, Robin Murphy, Janghyuck Kim,
	Cho KyongHo, Daniel Mentz, Sumit Semwal, iommu, iommu,
	linux-arm-kernel, linux-samsung-soc, linux-kernel

On 02/07/2022 23:37, Sam Protsenko wrote:
> SysMMU v7 can have Virtual Machine registers, which implement multiple
> translation domains. The driver should know if it's true or not, as VM
> registers shouldn't be accessed if not present. Read corresponding
> capabilities register to obtain that info, and store it in driver data.
> 
> Signed-off-by: Sam Protsenko <semen.protsenko@linaro.org>
> ---
>  drivers/iommu/exynos-iommu.c | 42 ++++++++++++++++++++++++++++++------
>  1 file changed, 36 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
> index 28f8c8d93aa3..df6ddbebbe2b 100644
> --- a/drivers/iommu/exynos-iommu.c
> +++ b/drivers/iommu/exynos-iommu.c
> @@ -135,6 +135,9 @@ static u32 lv2ent_offset(sysmmu_iova_t iova)
>  #define CFG_SYSSEL	(1 << 22) /* System MMU 3.2 only */
>  #define CFG_FLPDCACHE	(1 << 20) /* System MMU 3.2+ only */
>  
> +#define CAPA0_CAPA1_EXIST		BIT(11)
> +#define CAPA1_VCR_ENABLED		BIT(14)
> +
>  /* common registers */
>  #define REG_MMU_CTRL		0x000
>  #define REG_MMU_CFG		0x004
> @@ -171,6 +174,10 @@ static u32 lv2ent_offset(sysmmu_iova_t iova)
>  #define REG_V5_FAULT_AR_VA	0x070
>  #define REG_V5_FAULT_AW_VA	0x080
>  
> +/* v7.x registers */
> +#define REG_V7_CAPA0		0x870
> +#define REG_V7_CAPA1		0x874
> +
>  #define has_sysmmu(dev)		(dev_iommu_priv_get(dev) != NULL)
>  
>  static struct device *dma_dev;
> @@ -274,6 +281,9 @@ struct sysmmu_drvdata {
>  	unsigned int version;		/* our version */
>  
>  	struct iommu_device iommu;	/* IOMMU core handle */
> +
> +	/* v7 fields */
> +	bool has_vcr;			/* virtual machine control register */
>  };
>  
>  static struct exynos_iommu_domain *to_exynos_domain(struct iommu_domain *dom)
> @@ -364,11 +374,7 @@ static void __sysmmu_disable_clocks(struct sysmmu_drvdata *data)
>  
>  static void __sysmmu_get_version(struct sysmmu_drvdata *data)
>  {
> -	u32 ver;
> -
> -	__sysmmu_enable_clocks(data);
> -
> -	ver = readl(data->sfrbase + REG_MMU_VERSION);
> +	const u32 ver = readl(data->sfrbase + REG_MMU_VERSION);


No need for const for local, non-pointer variables. There is no benefit
in preventing the modification and it is not a constant.

>  
>  	/* controllers on some SoCs don't report proper version */
>  	if (ver == 0x80000001u)
> @@ -378,6 +384,29 @@ static void __sysmmu_get_version(struct sysmmu_drvdata *data)
>  
>  	dev_dbg(data->sysmmu, "hardware version: %d.%d\n",
>  		MMU_MAJ_VER(data->version), MMU_MIN_VER(data->version));
> +}
> +
> +static bool __sysmmu_has_capa1(struct sysmmu_drvdata *data)
> +{
> +	const u32 capa0 = readl(data->sfrbase + REG_V7_CAPA0);

Same here and further.


Best regards,
Krzysztof

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH 2/4] iommu/exynos: Check if SysMMU v7 has VM registers
@ 2022-07-03 19:10     ` Krzysztof Kozlowski
  0 siblings, 0 replies; 47+ messages in thread
From: Krzysztof Kozlowski @ 2022-07-03 19:10 UTC (permalink / raw)
  To: Sam Protsenko, Marek Szyprowski
  Cc: Janghyuck Kim, linux-samsung-soc, Will Deacon, iommu,
	linux-kernel, iommu, Cho KyongHo, Robin Murphy, Sumit Semwal,
	linux-arm-kernel

On 02/07/2022 23:37, Sam Protsenko wrote:
> SysMMU v7 can have Virtual Machine registers, which implement multiple
> translation domains. The driver should know if it's true or not, as VM
> registers shouldn't be accessed if not present. Read corresponding
> capabilities register to obtain that info, and store it in driver data.
> 
> Signed-off-by: Sam Protsenko <semen.protsenko@linaro.org>
> ---
>  drivers/iommu/exynos-iommu.c | 42 ++++++++++++++++++++++++++++++------
>  1 file changed, 36 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
> index 28f8c8d93aa3..df6ddbebbe2b 100644
> --- a/drivers/iommu/exynos-iommu.c
> +++ b/drivers/iommu/exynos-iommu.c
> @@ -135,6 +135,9 @@ static u32 lv2ent_offset(sysmmu_iova_t iova)
>  #define CFG_SYSSEL	(1 << 22) /* System MMU 3.2 only */
>  #define CFG_FLPDCACHE	(1 << 20) /* System MMU 3.2+ only */
>  
> +#define CAPA0_CAPA1_EXIST		BIT(11)
> +#define CAPA1_VCR_ENABLED		BIT(14)
> +
>  /* common registers */
>  #define REG_MMU_CTRL		0x000
>  #define REG_MMU_CFG		0x004
> @@ -171,6 +174,10 @@ static u32 lv2ent_offset(sysmmu_iova_t iova)
>  #define REG_V5_FAULT_AR_VA	0x070
>  #define REG_V5_FAULT_AW_VA	0x080
>  
> +/* v7.x registers */
> +#define REG_V7_CAPA0		0x870
> +#define REG_V7_CAPA1		0x874
> +
>  #define has_sysmmu(dev)		(dev_iommu_priv_get(dev) != NULL)
>  
>  static struct device *dma_dev;
> @@ -274,6 +281,9 @@ struct sysmmu_drvdata {
>  	unsigned int version;		/* our version */
>  
>  	struct iommu_device iommu;	/* IOMMU core handle */
> +
> +	/* v7 fields */
> +	bool has_vcr;			/* virtual machine control register */
>  };
>  
>  static struct exynos_iommu_domain *to_exynos_domain(struct iommu_domain *dom)
> @@ -364,11 +374,7 @@ static void __sysmmu_disable_clocks(struct sysmmu_drvdata *data)
>  
>  static void __sysmmu_get_version(struct sysmmu_drvdata *data)
>  {
> -	u32 ver;
> -
> -	__sysmmu_enable_clocks(data);
> -
> -	ver = readl(data->sfrbase + REG_MMU_VERSION);
> +	const u32 ver = readl(data->sfrbase + REG_MMU_VERSION);


No need for const for local, non-pointer variables. There is no benefit
in preventing the modification and it is not a constant.

>  
>  	/* controllers on some SoCs don't report proper version */
>  	if (ver == 0x80000001u)
> @@ -378,6 +384,29 @@ static void __sysmmu_get_version(struct sysmmu_drvdata *data)
>  
>  	dev_dbg(data->sysmmu, "hardware version: %d.%d\n",
>  		MMU_MAJ_VER(data->version), MMU_MIN_VER(data->version));
> +}
> +
> +static bool __sysmmu_has_capa1(struct sysmmu_drvdata *data)
> +{
> +	const u32 capa0 = readl(data->sfrbase + REG_V7_CAPA0);

Same here and further.


Best regards,
Krzysztof
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH 2/4] iommu/exynos: Check if SysMMU v7 has VM registers
@ 2022-07-03 19:10     ` Krzysztof Kozlowski
  0 siblings, 0 replies; 47+ messages in thread
From: Krzysztof Kozlowski @ 2022-07-03 19:10 UTC (permalink / raw)
  To: Sam Protsenko, Marek Szyprowski
  Cc: Joerg Roedel, Will Deacon, Robin Murphy, Janghyuck Kim,
	Cho KyongHo, Daniel Mentz, Sumit Semwal, iommu, iommu,
	linux-arm-kernel, linux-samsung-soc, linux-kernel

On 02/07/2022 23:37, Sam Protsenko wrote:
> SysMMU v7 can have Virtual Machine registers, which implement multiple
> translation domains. The driver should know if it's true or not, as VM
> registers shouldn't be accessed if not present. Read corresponding
> capabilities register to obtain that info, and store it in driver data.
> 
> Signed-off-by: Sam Protsenko <semen.protsenko@linaro.org>
> ---
>  drivers/iommu/exynos-iommu.c | 42 ++++++++++++++++++++++++++++++------
>  1 file changed, 36 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
> index 28f8c8d93aa3..df6ddbebbe2b 100644
> --- a/drivers/iommu/exynos-iommu.c
> +++ b/drivers/iommu/exynos-iommu.c
> @@ -135,6 +135,9 @@ static u32 lv2ent_offset(sysmmu_iova_t iova)
>  #define CFG_SYSSEL	(1 << 22) /* System MMU 3.2 only */
>  #define CFG_FLPDCACHE	(1 << 20) /* System MMU 3.2+ only */
>  
> +#define CAPA0_CAPA1_EXIST		BIT(11)
> +#define CAPA1_VCR_ENABLED		BIT(14)
> +
>  /* common registers */
>  #define REG_MMU_CTRL		0x000
>  #define REG_MMU_CFG		0x004
> @@ -171,6 +174,10 @@ static u32 lv2ent_offset(sysmmu_iova_t iova)
>  #define REG_V5_FAULT_AR_VA	0x070
>  #define REG_V5_FAULT_AW_VA	0x080
>  
> +/* v7.x registers */
> +#define REG_V7_CAPA0		0x870
> +#define REG_V7_CAPA1		0x874
> +
>  #define has_sysmmu(dev)		(dev_iommu_priv_get(dev) != NULL)
>  
>  static struct device *dma_dev;
> @@ -274,6 +281,9 @@ struct sysmmu_drvdata {
>  	unsigned int version;		/* our version */
>  
>  	struct iommu_device iommu;	/* IOMMU core handle */
> +
> +	/* v7 fields */
> +	bool has_vcr;			/* virtual machine control register */
>  };
>  
>  static struct exynos_iommu_domain *to_exynos_domain(struct iommu_domain *dom)
> @@ -364,11 +374,7 @@ static void __sysmmu_disable_clocks(struct sysmmu_drvdata *data)
>  
>  static void __sysmmu_get_version(struct sysmmu_drvdata *data)
>  {
> -	u32 ver;
> -
> -	__sysmmu_enable_clocks(data);
> -
> -	ver = readl(data->sfrbase + REG_MMU_VERSION);
> +	const u32 ver = readl(data->sfrbase + REG_MMU_VERSION);


No need for const for local, non-pointer variables. There is no benefit
in preventing the modification and it is not a constant.

>  
>  	/* controllers on some SoCs don't report proper version */
>  	if (ver == 0x80000001u)
> @@ -378,6 +384,29 @@ static void __sysmmu_get_version(struct sysmmu_drvdata *data)
>  
>  	dev_dbg(data->sysmmu, "hardware version: %d.%d\n",
>  		MMU_MAJ_VER(data->version), MMU_MIN_VER(data->version));
> +}
> +
> +static bool __sysmmu_has_capa1(struct sysmmu_drvdata *data)
> +{
> +	const u32 capa0 = readl(data->sfrbase + REG_V7_CAPA0);

Same here and further.


Best regards,
Krzysztof

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH 3/4] iommu/exynos: Use lookup based approach to access v7 registers
  2022-07-02 21:37   ` Sam Protsenko
  (?)
@ 2022-07-03 19:29     ` Krzysztof Kozlowski
  -1 siblings, 0 replies; 47+ messages in thread
From: Krzysztof Kozlowski @ 2022-07-03 19:29 UTC (permalink / raw)
  To: Sam Protsenko, Marek Szyprowski
  Cc: Joerg Roedel, Will Deacon, Robin Murphy, Janghyuck Kim,
	Cho KyongHo, Daniel Mentz, Sumit Semwal, iommu, iommu,
	linux-arm-kernel, linux-samsung-soc, linux-kernel

On 02/07/2022 23:37, Sam Protsenko wrote:
> SysMMU v7 might have different register layouts (VM capable or non-VM
> capable). Check which layout is implemented in current SysMMU module and
> prepare the corresponding register table for futher usage. This way is
> faster and more elegant than checking corresponding condition (if it's
> VM or non-VM SysMMU) each time before accessing v7 registers. For now
> the register table contains only most basic registers needed to add the
> SysMMU v7 support.
> 
> This patch is based on downstream work of next authors:
>   - Janghyuck Kim <janghyuck.kim@samsung.com>
>   - Daniel Mentz <danielmentz@google.com>
> 
> Signed-off-by: Sam Protsenko <semen.protsenko@linaro.org>
> ---
>  drivers/iommu/exynos-iommu.c | 46 ++++++++++++++++++++++++++++++++++++
>  1 file changed, 46 insertions(+)
> 
> diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
> index df6ddbebbe2b..47017e8945c5 100644
> --- a/drivers/iommu/exynos-iommu.c
> +++ b/drivers/iommu/exynos-iommu.c
> @@ -180,6 +180,47 @@ static u32 lv2ent_offset(sysmmu_iova_t iova)
>  
>  #define has_sysmmu(dev)		(dev_iommu_priv_get(dev) != NULL)
>  
> +#define MMU_REG(data, idx)		\
> +	((data)->sfrbase + (data)->regs[idx].off)

I would expect to see users of this - convert all existing regs.

> +#define MMU_VM_REG(data, idx, vmid)	\
> +	(MMU_REG(data, idx) + (vmid) * (data)->regs[idx].mult)
> +
> +enum {
> +	REG_SET_NON_VM,
> +	REG_SET_VM,
> +	MAX_REG_SET
> +};
> +
> +enum {
> +	IDX_CTRL_VM,
> +	IDX_CFG_VM,
> +	IDX_FLPT_BASE,

Isn't this called REG_MMU_FLUSH? If yes, it's a bit confusing to see
different name used.

> +	IDX_ALL_INV,

Isn't this called REG_MMU_FLUSH_ENTRY?

> +	MAX_REG_IDX
> +};
> +
> +struct sysmmu_vm_reg {
> +	unsigned int off;	/* register offset */
> +	unsigned int mult;	/* VM index offset multiplier */
> +};
> +
> +static const struct sysmmu_vm_reg sysmmu_regs[MAX_REG_SET][MAX_REG_IDX] = {
> +	/* Default register set (non-VM) */
> +	{
> +		/*
> +		 * SysMMUs without VM support do not have CTRL_VM and CFG_VM
> +		 * registers. Setting the offsets to 1 will trigger an unaligned
> +		 * access exception.

So why are you setting offset 1? To trigger unaligned access?

> +		 */
> +		{0x1}, {0x1}, {0x000c}, {0x0010},
> +	},
> +	/* VM capable register set */
> +	{
> +		{0x8000, 0x1000}, {0x8004, 0x1000}, {0x800c, 0x1000},
> +		{0x8010, 0x1000},
> +	},
You add here quite a bit of dead code and some hard-coded numbers.

> +};
> +
>  static struct device *dma_dev;
>  static struct kmem_cache *lv2table_kmem_cache;
>  static sysmmu_pte_t *zero_lv2_table;
> @@ -284,6 +325,7 @@ struct sysmmu_drvdata {
>  
>  	/* v7 fields */
>  	bool has_vcr;			/* virtual machine control register */
> +	const struct sysmmu_vm_reg *regs; /* register set */
>  };
>  
>  static struct exynos_iommu_domain *to_exynos_domain(struct iommu_domain *dom)
> @@ -407,6 +449,10 @@ static void sysmmu_get_hw_info(struct sysmmu_drvdata *data)
>  	__sysmmu_get_version(data);
>  	if (MMU_MAJ_VER(data->version) >= 7 && __sysmmu_has_capa1(data))
>  		__sysmmu_get_vcr(data);
> +	if (data->has_vcr)
> +		data->regs = sysmmu_regs[REG_SET_VM];
> +	else
> +		data->regs = sysmmu_regs[REG_SET_NON_VM];

This is set and not read.

>  
>  	__sysmmu_disable_clocks(data);
>  }


Best regards,
Krzysztof

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH 3/4] iommu/exynos: Use lookup based approach to access v7 registers
@ 2022-07-03 19:29     ` Krzysztof Kozlowski
  0 siblings, 0 replies; 47+ messages in thread
From: Krzysztof Kozlowski @ 2022-07-03 19:29 UTC (permalink / raw)
  To: Sam Protsenko, Marek Szyprowski
  Cc: Janghyuck Kim, linux-samsung-soc, Will Deacon, iommu,
	linux-kernel, iommu, Cho KyongHo, Robin Murphy, Sumit Semwal,
	linux-arm-kernel

On 02/07/2022 23:37, Sam Protsenko wrote:
> SysMMU v7 might have different register layouts (VM capable or non-VM
> capable). Check which layout is implemented in current SysMMU module and
> prepare the corresponding register table for futher usage. This way is
> faster and more elegant than checking corresponding condition (if it's
> VM or non-VM SysMMU) each time before accessing v7 registers. For now
> the register table contains only most basic registers needed to add the
> SysMMU v7 support.
> 
> This patch is based on downstream work of next authors:
>   - Janghyuck Kim <janghyuck.kim@samsung.com>
>   - Daniel Mentz <danielmentz@google.com>
> 
> Signed-off-by: Sam Protsenko <semen.protsenko@linaro.org>
> ---
>  drivers/iommu/exynos-iommu.c | 46 ++++++++++++++++++++++++++++++++++++
>  1 file changed, 46 insertions(+)
> 
> diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
> index df6ddbebbe2b..47017e8945c5 100644
> --- a/drivers/iommu/exynos-iommu.c
> +++ b/drivers/iommu/exynos-iommu.c
> @@ -180,6 +180,47 @@ static u32 lv2ent_offset(sysmmu_iova_t iova)
>  
>  #define has_sysmmu(dev)		(dev_iommu_priv_get(dev) != NULL)
>  
> +#define MMU_REG(data, idx)		\
> +	((data)->sfrbase + (data)->regs[idx].off)

I would expect to see users of this - convert all existing regs.

> +#define MMU_VM_REG(data, idx, vmid)	\
> +	(MMU_REG(data, idx) + (vmid) * (data)->regs[idx].mult)
> +
> +enum {
> +	REG_SET_NON_VM,
> +	REG_SET_VM,
> +	MAX_REG_SET
> +};
> +
> +enum {
> +	IDX_CTRL_VM,
> +	IDX_CFG_VM,
> +	IDX_FLPT_BASE,

Isn't this called REG_MMU_FLUSH? If yes, it's a bit confusing to see
different name used.

> +	IDX_ALL_INV,

Isn't this called REG_MMU_FLUSH_ENTRY?

> +	MAX_REG_IDX
> +};
> +
> +struct sysmmu_vm_reg {
> +	unsigned int off;	/* register offset */
> +	unsigned int mult;	/* VM index offset multiplier */
> +};
> +
> +static const struct sysmmu_vm_reg sysmmu_regs[MAX_REG_SET][MAX_REG_IDX] = {
> +	/* Default register set (non-VM) */
> +	{
> +		/*
> +		 * SysMMUs without VM support do not have CTRL_VM and CFG_VM
> +		 * registers. Setting the offsets to 1 will trigger an unaligned
> +		 * access exception.

So why are you setting offset 1? To trigger unaligned access?

> +		 */
> +		{0x1}, {0x1}, {0x000c}, {0x0010},
> +	},
> +	/* VM capable register set */
> +	{
> +		{0x8000, 0x1000}, {0x8004, 0x1000}, {0x800c, 0x1000},
> +		{0x8010, 0x1000},
> +	},
You add here quite a bit of dead code and some hard-coded numbers.

> +};
> +
>  static struct device *dma_dev;
>  static struct kmem_cache *lv2table_kmem_cache;
>  static sysmmu_pte_t *zero_lv2_table;
> @@ -284,6 +325,7 @@ struct sysmmu_drvdata {
>  
>  	/* v7 fields */
>  	bool has_vcr;			/* virtual machine control register */
> +	const struct sysmmu_vm_reg *regs; /* register set */
>  };
>  
>  static struct exynos_iommu_domain *to_exynos_domain(struct iommu_domain *dom)
> @@ -407,6 +449,10 @@ static void sysmmu_get_hw_info(struct sysmmu_drvdata *data)
>  	__sysmmu_get_version(data);
>  	if (MMU_MAJ_VER(data->version) >= 7 && __sysmmu_has_capa1(data))
>  		__sysmmu_get_vcr(data);
> +	if (data->has_vcr)
> +		data->regs = sysmmu_regs[REG_SET_VM];
> +	else
> +		data->regs = sysmmu_regs[REG_SET_NON_VM];

This is set and not read.

>  
>  	__sysmmu_disable_clocks(data);
>  }


Best regards,
Krzysztof
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH 3/4] iommu/exynos: Use lookup based approach to access v7 registers
@ 2022-07-03 19:29     ` Krzysztof Kozlowski
  0 siblings, 0 replies; 47+ messages in thread
From: Krzysztof Kozlowski @ 2022-07-03 19:29 UTC (permalink / raw)
  To: Sam Protsenko, Marek Szyprowski
  Cc: Joerg Roedel, Will Deacon, Robin Murphy, Janghyuck Kim,
	Cho KyongHo, Daniel Mentz, Sumit Semwal, iommu, iommu,
	linux-arm-kernel, linux-samsung-soc, linux-kernel

On 02/07/2022 23:37, Sam Protsenko wrote:
> SysMMU v7 might have different register layouts (VM capable or non-VM
> capable). Check which layout is implemented in current SysMMU module and
> prepare the corresponding register table for futher usage. This way is
> faster and more elegant than checking corresponding condition (if it's
> VM or non-VM SysMMU) each time before accessing v7 registers. For now
> the register table contains only most basic registers needed to add the
> SysMMU v7 support.
> 
> This patch is based on downstream work of next authors:
>   - Janghyuck Kim <janghyuck.kim@samsung.com>
>   - Daniel Mentz <danielmentz@google.com>
> 
> Signed-off-by: Sam Protsenko <semen.protsenko@linaro.org>
> ---
>  drivers/iommu/exynos-iommu.c | 46 ++++++++++++++++++++++++++++++++++++
>  1 file changed, 46 insertions(+)
> 
> diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
> index df6ddbebbe2b..47017e8945c5 100644
> --- a/drivers/iommu/exynos-iommu.c
> +++ b/drivers/iommu/exynos-iommu.c
> @@ -180,6 +180,47 @@ static u32 lv2ent_offset(sysmmu_iova_t iova)
>  
>  #define has_sysmmu(dev)		(dev_iommu_priv_get(dev) != NULL)
>  
> +#define MMU_REG(data, idx)		\
> +	((data)->sfrbase + (data)->regs[idx].off)

I would expect to see users of this - convert all existing regs.

> +#define MMU_VM_REG(data, idx, vmid)	\
> +	(MMU_REG(data, idx) + (vmid) * (data)->regs[idx].mult)
> +
> +enum {
> +	REG_SET_NON_VM,
> +	REG_SET_VM,
> +	MAX_REG_SET
> +};
> +
> +enum {
> +	IDX_CTRL_VM,
> +	IDX_CFG_VM,
> +	IDX_FLPT_BASE,

Isn't this called REG_MMU_FLUSH? If yes, it's a bit confusing to see
different name used.

> +	IDX_ALL_INV,

Isn't this called REG_MMU_FLUSH_ENTRY?

> +	MAX_REG_IDX
> +};
> +
> +struct sysmmu_vm_reg {
> +	unsigned int off;	/* register offset */
> +	unsigned int mult;	/* VM index offset multiplier */
> +};
> +
> +static const struct sysmmu_vm_reg sysmmu_regs[MAX_REG_SET][MAX_REG_IDX] = {
> +	/* Default register set (non-VM) */
> +	{
> +		/*
> +		 * SysMMUs without VM support do not have CTRL_VM and CFG_VM
> +		 * registers. Setting the offsets to 1 will trigger an unaligned
> +		 * access exception.

So why are you setting offset 1? To trigger unaligned access?

> +		 */
> +		{0x1}, {0x1}, {0x000c}, {0x0010},
> +	},
> +	/* VM capable register set */
> +	{
> +		{0x8000, 0x1000}, {0x8004, 0x1000}, {0x800c, 0x1000},
> +		{0x8010, 0x1000},
> +	},
You add here quite a bit of dead code and some hard-coded numbers.

> +};
> +
>  static struct device *dma_dev;
>  static struct kmem_cache *lv2table_kmem_cache;
>  static sysmmu_pte_t *zero_lv2_table;
> @@ -284,6 +325,7 @@ struct sysmmu_drvdata {
>  
>  	/* v7 fields */
>  	bool has_vcr;			/* virtual machine control register */
> +	const struct sysmmu_vm_reg *regs; /* register set */
>  };
>  
>  static struct exynos_iommu_domain *to_exynos_domain(struct iommu_domain *dom)
> @@ -407,6 +449,10 @@ static void sysmmu_get_hw_info(struct sysmmu_drvdata *data)
>  	__sysmmu_get_version(data);
>  	if (MMU_MAJ_VER(data->version) >= 7 && __sysmmu_has_capa1(data))
>  		__sysmmu_get_vcr(data);
> +	if (data->has_vcr)
> +		data->regs = sysmmu_regs[REG_SET_VM];
> +	else
> +		data->regs = sysmmu_regs[REG_SET_NON_VM];

This is set and not read.

>  
>  	__sysmmu_disable_clocks(data);
>  }


Best regards,
Krzysztof

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH 0/4] iommu/exynos: Add basic support for SysMMU v7
  2022-07-03 12:47     ` David Virag
  (?)
@ 2022-07-06 14:24       ` Sam Protsenko
  -1 siblings, 0 replies; 47+ messages in thread
From: Sam Protsenko @ 2022-07-06 14:24 UTC (permalink / raw)
  To: Janghyuck Kim
  Cc: Marek Szyprowski, Krzysztof Kozlowski, Joerg Roedel, Will Deacon,
	Robin Murphy, David Virag, Cho KyongHo, Daniel Mentz,
	Sumit Semwal, iommu, iommu, linux-arm-kernel, linux-samsung-soc,
	linux-kernel

On Sun, 3 Jul 2022 at 13:47, David Virag <virag.david003@gmail.com> wrote:
>
> On Sun, 2022-07-03 at 00:48 +0300, Sam Protsenko wrote:
> [...]
> > Hi Marek,
> >
> > As I understand, you have some board with SysMMU v7, which is not VM
> > capable (judging from the patches you shared earlier). Could you
> > please somehow verify if this series works fine for you? For example,
> > this testing driver [1] can be helpful.
> >
> > Thanks!
> >
> > [1]
> > https://github.com/joe-skb7/linux/commit/bbadd46fa525fe1fef2ccbdfff81f7d29caf0506
>
> Hi Sam,
>
> Not Marek here, but I wanted to try this on my jackpotlte (Exynos
> 7885). The driver reports it's DPU sysmmu as version 7.2, and manually
> reading the capabilities registers it looks like it has the 2nd
> capability register but not the VM capability.
>
> After applying your patches, adding your test driver (with SYSMMU_BASE
> corrected to 7885 value), and adding the sysmmu to dt, I tried to cat
> the test file that it creates in debugfs and I got an SError kernel
> panic.
>
> I tried tracing where the SError happens and it looks like it's this
> line:
>         /* Preload for emulation */
>         iowrite32(rw | vpn, obj->reg_base + MMU_EMU_PRELOAD);
>
> Trying to read the EMU registers using devmem results in a "Bus error".
>
> Could these emulation registers be missing from my SysMMU? Do you have
> any info on what version should have it? Or maybe some capability bit?
> I'll try testing it with DECON/DPP later and see if it works that way.
>

Hi Janghyuck,

Do you have by chance any info on SysMMU v7.2, which is present e.g.
on Exynos7885? David is trying to use emulation registers there with
no luck, so it would be nice if you can provide some details on
questions above.

Thanks!

> Best regards,
> David

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH 0/4] iommu/exynos: Add basic support for SysMMU v7
@ 2022-07-06 14:24       ` Sam Protsenko
  0 siblings, 0 replies; 47+ messages in thread
From: Sam Protsenko @ 2022-07-06 14:24 UTC (permalink / raw)
  To: Janghyuck Kim
  Cc: linux-samsung-soc, iommu, Will Deacon, iommu, linux-kernel,
	Krzysztof Kozlowski, David Virag, Cho KyongHo, Robin Murphy,
	Sumit Semwal, linux-arm-kernel

On Sun, 3 Jul 2022 at 13:47, David Virag <virag.david003@gmail.com> wrote:
>
> On Sun, 2022-07-03 at 00:48 +0300, Sam Protsenko wrote:
> [...]
> > Hi Marek,
> >
> > As I understand, you have some board with SysMMU v7, which is not VM
> > capable (judging from the patches you shared earlier). Could you
> > please somehow verify if this series works fine for you? For example,
> > this testing driver [1] can be helpful.
> >
> > Thanks!
> >
> > [1]
> > https://github.com/joe-skb7/linux/commit/bbadd46fa525fe1fef2ccbdfff81f7d29caf0506
>
> Hi Sam,
>
> Not Marek here, but I wanted to try this on my jackpotlte (Exynos
> 7885). The driver reports it's DPU sysmmu as version 7.2, and manually
> reading the capabilities registers it looks like it has the 2nd
> capability register but not the VM capability.
>
> After applying your patches, adding your test driver (with SYSMMU_BASE
> corrected to 7885 value), and adding the sysmmu to dt, I tried to cat
> the test file that it creates in debugfs and I got an SError kernel
> panic.
>
> I tried tracing where the SError happens and it looks like it's this
> line:
>         /* Preload for emulation */
>         iowrite32(rw | vpn, obj->reg_base + MMU_EMU_PRELOAD);
>
> Trying to read the EMU registers using devmem results in a "Bus error".
>
> Could these emulation registers be missing from my SysMMU? Do you have
> any info on what version should have it? Or maybe some capability bit?
> I'll try testing it with DECON/DPP later and see if it works that way.
>

Hi Janghyuck,

Do you have by chance any info on SysMMU v7.2, which is present e.g.
on Exynos7885? David is trying to use emulation registers there with
no luck, so it would be nice if you can provide some details on
questions above.

Thanks!

> Best regards,
> David
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH 0/4] iommu/exynos: Add basic support for SysMMU v7
@ 2022-07-06 14:24       ` Sam Protsenko
  0 siblings, 0 replies; 47+ messages in thread
From: Sam Protsenko @ 2022-07-06 14:24 UTC (permalink / raw)
  To: Janghyuck Kim
  Cc: Marek Szyprowski, Krzysztof Kozlowski, Joerg Roedel, Will Deacon,
	Robin Murphy, David Virag, Cho KyongHo, Daniel Mentz,
	Sumit Semwal, iommu, iommu, linux-arm-kernel, linux-samsung-soc,
	linux-kernel

On Sun, 3 Jul 2022 at 13:47, David Virag <virag.david003@gmail.com> wrote:
>
> On Sun, 2022-07-03 at 00:48 +0300, Sam Protsenko wrote:
> [...]
> > Hi Marek,
> >
> > As I understand, you have some board with SysMMU v7, which is not VM
> > capable (judging from the patches you shared earlier). Could you
> > please somehow verify if this series works fine for you? For example,
> > this testing driver [1] can be helpful.
> >
> > Thanks!
> >
> > [1]
> > https://github.com/joe-skb7/linux/commit/bbadd46fa525fe1fef2ccbdfff81f7d29caf0506
>
> Hi Sam,
>
> Not Marek here, but I wanted to try this on my jackpotlte (Exynos
> 7885). The driver reports it's DPU sysmmu as version 7.2, and manually
> reading the capabilities registers it looks like it has the 2nd
> capability register but not the VM capability.
>
> After applying your patches, adding your test driver (with SYSMMU_BASE
> corrected to 7885 value), and adding the sysmmu to dt, I tried to cat
> the test file that it creates in debugfs and I got an SError kernel
> panic.
>
> I tried tracing where the SError happens and it looks like it's this
> line:
>         /* Preload for emulation */
>         iowrite32(rw | vpn, obj->reg_base + MMU_EMU_PRELOAD);
>
> Trying to read the EMU registers using devmem results in a "Bus error".
>
> Could these emulation registers be missing from my SysMMU? Do you have
> any info on what version should have it? Or maybe some capability bit?
> I'll try testing it with DECON/DPP later and see if it works that way.
>

Hi Janghyuck,

Do you have by chance any info on SysMMU v7.2, which is present e.g.
on Exynos7885? David is trying to use emulation registers there with
no luck, so it would be nice if you can provide some details on
questions above.

Thanks!

> Best regards,
> David

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH 1/4] iommu/exynos: Set correct dma mask for SysMMU v5+
  2022-07-03 18:50     ` Krzysztof Kozlowski
@ 2022-07-08 13:18       ` Sam Protsenko
  -1 siblings, 0 replies; 47+ messages in thread
From: Sam Protsenko @ 2022-07-08 13:18 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Marek Szyprowski, Joerg Roedel, Will Deacon, Robin Murphy,
	Janghyuck Kim, Cho KyongHo, Daniel Mentz, Sumit Semwal, iommu,
	iommu, linux-arm-kernel, linux-samsung-soc, linux-kernel

On Sun, 3 Jul 2022 at 21:50, Krzysztof Kozlowski
<krzysztof.kozlowski@linaro.org> wrote:
>
> On 02/07/2022 23:37, Sam Protsenko wrote:
> > SysMMU v5+ supports 36 bit physical address space. Set corresponding DMA
> > mask to avoid falling back to SWTLBIO usage in dma_map_single() because
> > of failed dma_capable() check.
> >
> > The original code for this fix was suggested by Marek.
> >
> > Originally-by: Marek Szyprowski <m.szyprowski@samsung.com>
>
> This is some tip specific tag, I don't think checkpatch allows it.
> Either use suggesgted-by or co-developed-by + SoB.
>

Yes, checkpatch is swearing at that line, though I encountered that
tag mentioning somewhere in Documentation. Will rework it in v2.

> > Signed-off-by: Sam Protsenko <semen.protsenko@linaro.org>
> > ---
> >  drivers/iommu/exynos-iommu.c | 8 ++++++++
> >  1 file changed, 8 insertions(+)
> >
> > diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
> > index 71f2018e23fe..28f8c8d93aa3 100644
> > --- a/drivers/iommu/exynos-iommu.c
> > +++ b/drivers/iommu/exynos-iommu.c
> > @@ -647,6 +647,14 @@ static int exynos_sysmmu_probe(struct platform_device *pdev)
> >               }
> >       }
> >
> > +     if (MMU_MAJ_VER(data->version) >= 5) {
> > +             ret = dma_set_mask(dev, DMA_BIT_MASK(36));
> > +             if (ret) {
> > +                     dev_err(dev, "Unable to set DMA mask: %d\n", ret);
>
> Missing cleanup: iommu_device_unregister
> and probably also: iommu_device_sysfs_remove
>

Right. Also the correct cleanup should be added for failing
iommu_device_register() case, above of the quoted code. Will do that
in v2, thanks.

Another thing is that "remove" method is missing. But guess I'll get
to it later, when adding modularization support for this driver.

> > +                     return ret;
> > +             }
> > +     }
> > +
> >       /*
> >        * use the first registered sysmmu device for performing
> >        * dma mapping operations on iommu page tables (cpu cache flush)
>
>
> Best regards,
> Krzysztof

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH 1/4] iommu/exynos: Set correct dma mask for SysMMU v5+
@ 2022-07-08 13:18       ` Sam Protsenko
  0 siblings, 0 replies; 47+ messages in thread
From: Sam Protsenko @ 2022-07-08 13:18 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Marek Szyprowski, Joerg Roedel, Will Deacon, Robin Murphy,
	Janghyuck Kim, Cho KyongHo, Daniel Mentz, Sumit Semwal, iommu,
	iommu, linux-arm-kernel, linux-samsung-soc, linux-kernel

On Sun, 3 Jul 2022 at 21:50, Krzysztof Kozlowski
<krzysztof.kozlowski@linaro.org> wrote:
>
> On 02/07/2022 23:37, Sam Protsenko wrote:
> > SysMMU v5+ supports 36 bit physical address space. Set corresponding DMA
> > mask to avoid falling back to SWTLBIO usage in dma_map_single() because
> > of failed dma_capable() check.
> >
> > The original code for this fix was suggested by Marek.
> >
> > Originally-by: Marek Szyprowski <m.szyprowski@samsung.com>
>
> This is some tip specific tag, I don't think checkpatch allows it.
> Either use suggesgted-by or co-developed-by + SoB.
>

Yes, checkpatch is swearing at that line, though I encountered that
tag mentioning somewhere in Documentation. Will rework it in v2.

> > Signed-off-by: Sam Protsenko <semen.protsenko@linaro.org>
> > ---
> >  drivers/iommu/exynos-iommu.c | 8 ++++++++
> >  1 file changed, 8 insertions(+)
> >
> > diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
> > index 71f2018e23fe..28f8c8d93aa3 100644
> > --- a/drivers/iommu/exynos-iommu.c
> > +++ b/drivers/iommu/exynos-iommu.c
> > @@ -647,6 +647,14 @@ static int exynos_sysmmu_probe(struct platform_device *pdev)
> >               }
> >       }
> >
> > +     if (MMU_MAJ_VER(data->version) >= 5) {
> > +             ret = dma_set_mask(dev, DMA_BIT_MASK(36));
> > +             if (ret) {
> > +                     dev_err(dev, "Unable to set DMA mask: %d\n", ret);
>
> Missing cleanup: iommu_device_unregister
> and probably also: iommu_device_sysfs_remove
>

Right. Also the correct cleanup should be added for failing
iommu_device_register() case, above of the quoted code. Will do that
in v2, thanks.

Another thing is that "remove" method is missing. But guess I'll get
to it later, when adding modularization support for this driver.

> > +                     return ret;
> > +             }
> > +     }
> > +
> >       /*
> >        * use the first registered sysmmu device for performing
> >        * dma mapping operations on iommu page tables (cpu cache flush)
>
>
> Best regards,
> Krzysztof

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH 2/4] iommu/exynos: Check if SysMMU v7 has VM registers
  2022-07-03 19:10     ` Krzysztof Kozlowski
@ 2022-07-08 13:34       ` Sam Protsenko
  -1 siblings, 0 replies; 47+ messages in thread
From: Sam Protsenko @ 2022-07-08 13:34 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Marek Szyprowski, Joerg Roedel, Will Deacon, Robin Murphy,
	Janghyuck Kim, Cho KyongHo, Daniel Mentz, Sumit Semwal, iommu,
	iommu, linux-arm-kernel, linux-samsung-soc, linux-kernel

On Sun, 3 Jul 2022 at 22:10, Krzysztof Kozlowski
<krzysztof.kozlowski@linaro.org> wrote:
>
> On 02/07/2022 23:37, Sam Protsenko wrote:
> > SysMMU v7 can have Virtual Machine registers, which implement multiple
> > translation domains. The driver should know if it's true or not, as VM
> > registers shouldn't be accessed if not present. Read corresponding
> > capabilities register to obtain that info, and store it in driver data.
> >
> > Signed-off-by: Sam Protsenko <semen.protsenko@linaro.org>
> > ---
> >  drivers/iommu/exynos-iommu.c | 42 ++++++++++++++++++++++++++++++------
> >  1 file changed, 36 insertions(+), 6 deletions(-)
> >
> > diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
> > index 28f8c8d93aa3..df6ddbebbe2b 100644
> > --- a/drivers/iommu/exynos-iommu.c
> > +++ b/drivers/iommu/exynos-iommu.c
> > @@ -135,6 +135,9 @@ static u32 lv2ent_offset(sysmmu_iova_t iova)
> >  #define CFG_SYSSEL   (1 << 22) /* System MMU 3.2 only */
> >  #define CFG_FLPDCACHE        (1 << 20) /* System MMU 3.2+ only */
> >
> > +#define CAPA0_CAPA1_EXIST            BIT(11)
> > +#define CAPA1_VCR_ENABLED            BIT(14)
> > +
> >  /* common registers */
> >  #define REG_MMU_CTRL         0x000
> >  #define REG_MMU_CFG          0x004
> > @@ -171,6 +174,10 @@ static u32 lv2ent_offset(sysmmu_iova_t iova)
> >  #define REG_V5_FAULT_AR_VA   0x070
> >  #define REG_V5_FAULT_AW_VA   0x080
> >
> > +/* v7.x registers */
> > +#define REG_V7_CAPA0         0x870
> > +#define REG_V7_CAPA1         0x874
> > +
> >  #define has_sysmmu(dev)              (dev_iommu_priv_get(dev) != NULL)
> >
> >  static struct device *dma_dev;
> > @@ -274,6 +281,9 @@ struct sysmmu_drvdata {
> >       unsigned int version;           /* our version */
> >
> >       struct iommu_device iommu;      /* IOMMU core handle */
> > +
> > +     /* v7 fields */
> > +     bool has_vcr;                   /* virtual machine control register */
> >  };
> >
> >  static struct exynos_iommu_domain *to_exynos_domain(struct iommu_domain *dom)
> > @@ -364,11 +374,7 @@ static void __sysmmu_disable_clocks(struct sysmmu_drvdata *data)
> >
> >  static void __sysmmu_get_version(struct sysmmu_drvdata *data)
> >  {
> > -     u32 ver;
> > -
> > -     __sysmmu_enable_clocks(data);
> > -
> > -     ver = readl(data->sfrbase + REG_MMU_VERSION);
> > +     const u32 ver = readl(data->sfrbase + REG_MMU_VERSION);
>
>
> No need for const for local, non-pointer variables. There is no benefit
> in preventing the modification and it is not a constant.
>

I'd say it's more a matter of taste, having "const" kinda disciplines
one. But I don't mind removing those bits, will do in v2.

> >
> >       /* controllers on some SoCs don't report proper version */
> >       if (ver == 0x80000001u)
> > @@ -378,6 +384,29 @@ static void __sysmmu_get_version(struct sysmmu_drvdata *data)
> >
> >       dev_dbg(data->sysmmu, "hardware version: %d.%d\n",
> >               MMU_MAJ_VER(data->version), MMU_MIN_VER(data->version));
> > +}
> > +
> > +static bool __sysmmu_has_capa1(struct sysmmu_drvdata *data)
> > +{
> > +     const u32 capa0 = readl(data->sfrbase + REG_V7_CAPA0);
>
> Same here and further.
>
>
> Best regards,
> Krzysztof

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH 2/4] iommu/exynos: Check if SysMMU v7 has VM registers
@ 2022-07-08 13:34       ` Sam Protsenko
  0 siblings, 0 replies; 47+ messages in thread
From: Sam Protsenko @ 2022-07-08 13:34 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Marek Szyprowski, Joerg Roedel, Will Deacon, Robin Murphy,
	Janghyuck Kim, Cho KyongHo, Daniel Mentz, Sumit Semwal, iommu,
	iommu, linux-arm-kernel, linux-samsung-soc, linux-kernel

On Sun, 3 Jul 2022 at 22:10, Krzysztof Kozlowski
<krzysztof.kozlowski@linaro.org> wrote:
>
> On 02/07/2022 23:37, Sam Protsenko wrote:
> > SysMMU v7 can have Virtual Machine registers, which implement multiple
> > translation domains. The driver should know if it's true or not, as VM
> > registers shouldn't be accessed if not present. Read corresponding
> > capabilities register to obtain that info, and store it in driver data.
> >
> > Signed-off-by: Sam Protsenko <semen.protsenko@linaro.org>
> > ---
> >  drivers/iommu/exynos-iommu.c | 42 ++++++++++++++++++++++++++++++------
> >  1 file changed, 36 insertions(+), 6 deletions(-)
> >
> > diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
> > index 28f8c8d93aa3..df6ddbebbe2b 100644
> > --- a/drivers/iommu/exynos-iommu.c
> > +++ b/drivers/iommu/exynos-iommu.c
> > @@ -135,6 +135,9 @@ static u32 lv2ent_offset(sysmmu_iova_t iova)
> >  #define CFG_SYSSEL   (1 << 22) /* System MMU 3.2 only */
> >  #define CFG_FLPDCACHE        (1 << 20) /* System MMU 3.2+ only */
> >
> > +#define CAPA0_CAPA1_EXIST            BIT(11)
> > +#define CAPA1_VCR_ENABLED            BIT(14)
> > +
> >  /* common registers */
> >  #define REG_MMU_CTRL         0x000
> >  #define REG_MMU_CFG          0x004
> > @@ -171,6 +174,10 @@ static u32 lv2ent_offset(sysmmu_iova_t iova)
> >  #define REG_V5_FAULT_AR_VA   0x070
> >  #define REG_V5_FAULT_AW_VA   0x080
> >
> > +/* v7.x registers */
> > +#define REG_V7_CAPA0         0x870
> > +#define REG_V7_CAPA1         0x874
> > +
> >  #define has_sysmmu(dev)              (dev_iommu_priv_get(dev) != NULL)
> >
> >  static struct device *dma_dev;
> > @@ -274,6 +281,9 @@ struct sysmmu_drvdata {
> >       unsigned int version;           /* our version */
> >
> >       struct iommu_device iommu;      /* IOMMU core handle */
> > +
> > +     /* v7 fields */
> > +     bool has_vcr;                   /* virtual machine control register */
> >  };
> >
> >  static struct exynos_iommu_domain *to_exynos_domain(struct iommu_domain *dom)
> > @@ -364,11 +374,7 @@ static void __sysmmu_disable_clocks(struct sysmmu_drvdata *data)
> >
> >  static void __sysmmu_get_version(struct sysmmu_drvdata *data)
> >  {
> > -     u32 ver;
> > -
> > -     __sysmmu_enable_clocks(data);
> > -
> > -     ver = readl(data->sfrbase + REG_MMU_VERSION);
> > +     const u32 ver = readl(data->sfrbase + REG_MMU_VERSION);
>
>
> No need for const for local, non-pointer variables. There is no benefit
> in preventing the modification and it is not a constant.
>

I'd say it's more a matter of taste, having "const" kinda disciplines
one. But I don't mind removing those bits, will do in v2.

> >
> >       /* controllers on some SoCs don't report proper version */
> >       if (ver == 0x80000001u)
> > @@ -378,6 +384,29 @@ static void __sysmmu_get_version(struct sysmmu_drvdata *data)
> >
> >       dev_dbg(data->sysmmu, "hardware version: %d.%d\n",
> >               MMU_MAJ_VER(data->version), MMU_MIN_VER(data->version));
> > +}
> > +
> > +static bool __sysmmu_has_capa1(struct sysmmu_drvdata *data)
> > +{
> > +     const u32 capa0 = readl(data->sfrbase + REG_V7_CAPA0);
>
> Same here and further.
>
>
> Best regards,
> Krzysztof

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH 3/4] iommu/exynos: Use lookup based approach to access v7 registers
  2022-07-03 19:29     ` Krzysztof Kozlowski
@ 2022-07-08 18:13       ` Sam Protsenko
  -1 siblings, 0 replies; 47+ messages in thread
From: Sam Protsenko @ 2022-07-08 18:13 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Marek Szyprowski, Joerg Roedel, Will Deacon, Robin Murphy,
	Janghyuck Kim, Cho KyongHo, Daniel Mentz, Sumit Semwal, iommu,
	iommu, linux-arm-kernel, linux-samsung-soc, linux-kernel

On Sun, 3 Jul 2022 at 22:29, Krzysztof Kozlowski
<krzysztof.kozlowski@linaro.org> wrote:
>
> On 02/07/2022 23:37, Sam Protsenko wrote:
> > SysMMU v7 might have different register layouts (VM capable or non-VM
> > capable). Check which layout is implemented in current SysMMU module and
> > prepare the corresponding register table for futher usage. This way is
> > faster and more elegant than checking corresponding condition (if it's
> > VM or non-VM SysMMU) each time before accessing v7 registers. For now
> > the register table contains only most basic registers needed to add the
> > SysMMU v7 support.
> >
> > This patch is based on downstream work of next authors:
> >   - Janghyuck Kim <janghyuck.kim@samsung.com>
> >   - Daniel Mentz <danielmentz@google.com>
> >
> > Signed-off-by: Sam Protsenko <semen.protsenko@linaro.org>
> > ---
> >  drivers/iommu/exynos-iommu.c | 46 ++++++++++++++++++++++++++++++++++++
> >  1 file changed, 46 insertions(+)
> >
> > diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
> > index df6ddbebbe2b..47017e8945c5 100644
> > --- a/drivers/iommu/exynos-iommu.c
> > +++ b/drivers/iommu/exynos-iommu.c
> > @@ -180,6 +180,47 @@ static u32 lv2ent_offset(sysmmu_iova_t iova)
> >
> >  #define has_sysmmu(dev)              (dev_iommu_priv_get(dev) != NULL)
> >
> > +#define MMU_REG(data, idx)           \
> > +     ((data)->sfrbase + (data)->regs[idx].off)
>
> I would expect to see users of this - convert all existing regs.
>

I was thinking about doing that as a consequent patch (adding SysMMU
v1/v5 register sets). But ok, will add in v2. And will probably split
it per 2 patches:
  1. Rework existing driver to use register sets (lookup table). To
keep it as "no functional change" patch.
  2. Add SysMMU v7 support.

Also, I will probably replace MMU_REG() with more standard approach,
i.e. will add sysmmu_read() / sysmmu_write() functions instead. It
should make the code tidier.

> > +#define MMU_VM_REG(data, idx, vmid)  \
> > +     (MMU_REG(data, idx) + (vmid) * (data)->regs[idx].mult)
> > +
> > +enum {
> > +     REG_SET_NON_VM,
> > +     REG_SET_VM,
> > +     MAX_REG_SET
> > +};
> > +
> > +enum {
> > +     IDX_CTRL_VM,
> > +     IDX_CFG_VM,
> > +     IDX_FLPT_BASE,
>
> Isn't this called REG_MMU_FLUSH? If yes, it's a bit confusing to see
> different name used.
>

I used v7 registers naming, as I only added support for v7 register
set in this patch series. As I said above, I'll add SysMMU v1/v5
register sets in v2, and rename those indexes to have old register
names. Despite the differences between register names in SysMMU v1/v5
and v7, their purpose is the same.

> > +     IDX_ALL_INV,
>
> Isn't this called REG_MMU_FLUSH_ENTRY?
>
> > +     MAX_REG_IDX
> > +};
> > +
> > +struct sysmmu_vm_reg {
> > +     unsigned int off;       /* register offset */
> > +     unsigned int mult;      /* VM index offset multiplier */
> > +};
> > +
> > +static const struct sysmmu_vm_reg sysmmu_regs[MAX_REG_SET][MAX_REG_IDX] = {
> > +     /* Default register set (non-VM) */
> > +     {
> > +             /*
> > +              * SysMMUs without VM support do not have CTRL_VM and CFG_VM
> > +              * registers. Setting the offsets to 1 will trigger an unaligned
> > +              * access exception.
>
> So why are you setting offset 1? To trigger unaligned access?
>

Yes, as comment suggests, 0x1 offset is set intentionally to cause the
exception. That might be useful for debugging (if driver is trying to
access some non-existing register on some particular SysMMU version).
I'll improve the comment in v2.

> > +              */
> > +             {0x1}, {0x1}, {0x000c}, {0x0010},
> > +     },
> > +     /* VM capable register set */
> > +     {
> > +             {0x8000, 0x1000}, {0x8004, 0x1000}, {0x800c, 0x1000},
> > +             {0x8010, 0x1000},
> > +     },
> You add here quite a bit of dead code and some hard-coded numbers.
>

Ok, will remove those multiplier bits for now. It can be added later,
when implementing domains support (to use VM registers other than n=0
instance).

> > +};
> > +
> >  static struct device *dma_dev;
> >  static struct kmem_cache *lv2table_kmem_cache;
> >  static sysmmu_pte_t *zero_lv2_table;
> > @@ -284,6 +325,7 @@ struct sysmmu_drvdata {
> >
> >       /* v7 fields */
> >       bool has_vcr;                   /* virtual machine control register */
> > +     const struct sysmmu_vm_reg *regs; /* register set */
> >  };
> >
> >  static struct exynos_iommu_domain *to_exynos_domain(struct iommu_domain *dom)
> > @@ -407,6 +449,10 @@ static void sysmmu_get_hw_info(struct sysmmu_drvdata *data)
> >       __sysmmu_get_version(data);
> >       if (MMU_MAJ_VER(data->version) >= 7 && __sysmmu_has_capa1(data))
> >               __sysmmu_get_vcr(data);
> > +     if (data->has_vcr)
> > +             data->regs = sysmmu_regs[REG_SET_VM];
> > +     else
> > +             data->regs = sysmmu_regs[REG_SET_NON_VM];
>
> This is set and not read.
>

It's used in patch 4/4. But as discussed above, I will convert
existing code (SysMMU v1/v3/v5) to benefit from register set as well.
Will send in v2.

Thanks for the review!

> >
> >       __sysmmu_disable_clocks(data);
> >  }
>
>
> Best regards,
> Krzysztof

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH 3/4] iommu/exynos: Use lookup based approach to access v7 registers
@ 2022-07-08 18:13       ` Sam Protsenko
  0 siblings, 0 replies; 47+ messages in thread
From: Sam Protsenko @ 2022-07-08 18:13 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Marek Szyprowski, Joerg Roedel, Will Deacon, Robin Murphy,
	Janghyuck Kim, Cho KyongHo, Daniel Mentz, Sumit Semwal, iommu,
	iommu, linux-arm-kernel, linux-samsung-soc, linux-kernel

On Sun, 3 Jul 2022 at 22:29, Krzysztof Kozlowski
<krzysztof.kozlowski@linaro.org> wrote:
>
> On 02/07/2022 23:37, Sam Protsenko wrote:
> > SysMMU v7 might have different register layouts (VM capable or non-VM
> > capable). Check which layout is implemented in current SysMMU module and
> > prepare the corresponding register table for futher usage. This way is
> > faster and more elegant than checking corresponding condition (if it's
> > VM or non-VM SysMMU) each time before accessing v7 registers. For now
> > the register table contains only most basic registers needed to add the
> > SysMMU v7 support.
> >
> > This patch is based on downstream work of next authors:
> >   - Janghyuck Kim <janghyuck.kim@samsung.com>
> >   - Daniel Mentz <danielmentz@google.com>
> >
> > Signed-off-by: Sam Protsenko <semen.protsenko@linaro.org>
> > ---
> >  drivers/iommu/exynos-iommu.c | 46 ++++++++++++++++++++++++++++++++++++
> >  1 file changed, 46 insertions(+)
> >
> > diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
> > index df6ddbebbe2b..47017e8945c5 100644
> > --- a/drivers/iommu/exynos-iommu.c
> > +++ b/drivers/iommu/exynos-iommu.c
> > @@ -180,6 +180,47 @@ static u32 lv2ent_offset(sysmmu_iova_t iova)
> >
> >  #define has_sysmmu(dev)              (dev_iommu_priv_get(dev) != NULL)
> >
> > +#define MMU_REG(data, idx)           \
> > +     ((data)->sfrbase + (data)->regs[idx].off)
>
> I would expect to see users of this - convert all existing regs.
>

I was thinking about doing that as a consequent patch (adding SysMMU
v1/v5 register sets). But ok, will add in v2. And will probably split
it per 2 patches:
  1. Rework existing driver to use register sets (lookup table). To
keep it as "no functional change" patch.
  2. Add SysMMU v7 support.

Also, I will probably replace MMU_REG() with more standard approach,
i.e. will add sysmmu_read() / sysmmu_write() functions instead. It
should make the code tidier.

> > +#define MMU_VM_REG(data, idx, vmid)  \
> > +     (MMU_REG(data, idx) + (vmid) * (data)->regs[idx].mult)
> > +
> > +enum {
> > +     REG_SET_NON_VM,
> > +     REG_SET_VM,
> > +     MAX_REG_SET
> > +};
> > +
> > +enum {
> > +     IDX_CTRL_VM,
> > +     IDX_CFG_VM,
> > +     IDX_FLPT_BASE,
>
> Isn't this called REG_MMU_FLUSH? If yes, it's a bit confusing to see
> different name used.
>

I used v7 registers naming, as I only added support for v7 register
set in this patch series. As I said above, I'll add SysMMU v1/v5
register sets in v2, and rename those indexes to have old register
names. Despite the differences between register names in SysMMU v1/v5
and v7, their purpose is the same.

> > +     IDX_ALL_INV,
>
> Isn't this called REG_MMU_FLUSH_ENTRY?
>
> > +     MAX_REG_IDX
> > +};
> > +
> > +struct sysmmu_vm_reg {
> > +     unsigned int off;       /* register offset */
> > +     unsigned int mult;      /* VM index offset multiplier */
> > +};
> > +
> > +static const struct sysmmu_vm_reg sysmmu_regs[MAX_REG_SET][MAX_REG_IDX] = {
> > +     /* Default register set (non-VM) */
> > +     {
> > +             /*
> > +              * SysMMUs without VM support do not have CTRL_VM and CFG_VM
> > +              * registers. Setting the offsets to 1 will trigger an unaligned
> > +              * access exception.
>
> So why are you setting offset 1? To trigger unaligned access?
>

Yes, as comment suggests, 0x1 offset is set intentionally to cause the
exception. That might be useful for debugging (if driver is trying to
access some non-existing register on some particular SysMMU version).
I'll improve the comment in v2.

> > +              */
> > +             {0x1}, {0x1}, {0x000c}, {0x0010},
> > +     },
> > +     /* VM capable register set */
> > +     {
> > +             {0x8000, 0x1000}, {0x8004, 0x1000}, {0x800c, 0x1000},
> > +             {0x8010, 0x1000},
> > +     },
> You add here quite a bit of dead code and some hard-coded numbers.
>

Ok, will remove those multiplier bits for now. It can be added later,
when implementing domains support (to use VM registers other than n=0
instance).

> > +};
> > +
> >  static struct device *dma_dev;
> >  static struct kmem_cache *lv2table_kmem_cache;
> >  static sysmmu_pte_t *zero_lv2_table;
> > @@ -284,6 +325,7 @@ struct sysmmu_drvdata {
> >
> >       /* v7 fields */
> >       bool has_vcr;                   /* virtual machine control register */
> > +     const struct sysmmu_vm_reg *regs; /* register set */
> >  };
> >
> >  static struct exynos_iommu_domain *to_exynos_domain(struct iommu_domain *dom)
> > @@ -407,6 +449,10 @@ static void sysmmu_get_hw_info(struct sysmmu_drvdata *data)
> >       __sysmmu_get_version(data);
> >       if (MMU_MAJ_VER(data->version) >= 7 && __sysmmu_has_capa1(data))
> >               __sysmmu_get_vcr(data);
> > +     if (data->has_vcr)
> > +             data->regs = sysmmu_regs[REG_SET_VM];
> > +     else
> > +             data->regs = sysmmu_regs[REG_SET_NON_VM];
>
> This is set and not read.
>

It's used in patch 4/4. But as discussed above, I will convert
existing code (SysMMU v1/v3/v5) to benefit from register set as well.
Will send in v2.

Thanks for the review!

> >
> >       __sysmmu_disable_clocks(data);
> >  }
>
>
> Best regards,
> Krzysztof

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH 0/4] iommu/exynos: Add basic support for SysMMU v7
  2022-07-03 12:47     ` David Virag
@ 2022-07-10 23:04       ` Sam Protsenko
  -1 siblings, 0 replies; 47+ messages in thread
From: Sam Protsenko @ 2022-07-10 23:04 UTC (permalink / raw)
  To: David Virag
  Cc: Marek Szyprowski, Krzysztof Kozlowski, Joerg Roedel, Will Deacon,
	Robin Murphy, Janghyuck Kim, Cho KyongHo, Daniel Mentz,
	Sumit Semwal, iommu, iommu, linux-arm-kernel, linux-samsung-soc,
	linux-kernel

On Sun, 3 Jul 2022 at 13:47, David Virag <virag.david003@gmail.com> wrote:
>
> On Sun, 2022-07-03 at 00:48 +0300, Sam Protsenko wrote:
> [...]
> > Hi Marek,
> >
> > As I understand, you have some board with SysMMU v7, which is not VM
> > capable (judging from the patches you shared earlier). Could you
> > please somehow verify if this series works fine for you? For example,
> > this testing driver [1] can be helpful.
> >
> > Thanks!
> >
> > [1]
> > https://github.com/joe-skb7/linux/commit/bbadd46fa525fe1fef2ccbdfff81f7d29caf0506
>
> Hi Sam,
>
> Not Marek here, but I wanted to try this on my jackpotlte (Exynos
> 7885). The driver reports it's DPU sysmmu as version 7.2, and manually
> reading the capabilities registers it looks like it has the 2nd
> capability register but not the VM capability.
>
> After applying your patches, adding your test driver (with SYSMMU_BASE
> corrected to 7885 value), and adding the sysmmu to dt, I tried to cat
> the test file that it creates in debugfs and I got an SError kernel
> panic.
>
> I tried tracing where the SError happens and it looks like it's this
> line:
>         /* Preload for emulation */
>         iowrite32(rw | vpn, obj->reg_base + MMU_EMU_PRELOAD);
>
> Trying to read the EMU registers using devmem results in a "Bus error".
>
> Could these emulation registers be missing from my SysMMU? Do you have
> any info on what version should have it? Or maybe some capability bit?
> I'll try testing it with DECON/DPP later and see if it works that way.
>

I don't have any manuals for v7.2, so I can only assume. Yes, it looks
to me very much like those EMU registers are missing in your SysMMU
IP-core: I remember seeing some similar SError messages while trying
to access some incorrect MMIO addresses. Good news is that once this
patch series is fixed and accepted, you can *probably* base your work
on top of it (as I only validated it with EMU registers for now). I
mean you can add some real IP-core users of that IOMMU, like graphics
(DPU), audio, camera, etc. Not sure though if it would be enough to
just add some DTS nodes, or your SoC support has to be added to some
drivers first.

> Best regards,
> David

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH 0/4] iommu/exynos: Add basic support for SysMMU v7
@ 2022-07-10 23:04       ` Sam Protsenko
  0 siblings, 0 replies; 47+ messages in thread
From: Sam Protsenko @ 2022-07-10 23:04 UTC (permalink / raw)
  To: David Virag
  Cc: Marek Szyprowski, Krzysztof Kozlowski, Joerg Roedel, Will Deacon,
	Robin Murphy, Janghyuck Kim, Cho KyongHo, Daniel Mentz,
	Sumit Semwal, iommu, iommu, linux-arm-kernel, linux-samsung-soc,
	linux-kernel

On Sun, 3 Jul 2022 at 13:47, David Virag <virag.david003@gmail.com> wrote:
>
> On Sun, 2022-07-03 at 00:48 +0300, Sam Protsenko wrote:
> [...]
> > Hi Marek,
> >
> > As I understand, you have some board with SysMMU v7, which is not VM
> > capable (judging from the patches you shared earlier). Could you
> > please somehow verify if this series works fine for you? For example,
> > this testing driver [1] can be helpful.
> >
> > Thanks!
> >
> > [1]
> > https://github.com/joe-skb7/linux/commit/bbadd46fa525fe1fef2ccbdfff81f7d29caf0506
>
> Hi Sam,
>
> Not Marek here, but I wanted to try this on my jackpotlte (Exynos
> 7885). The driver reports it's DPU sysmmu as version 7.2, and manually
> reading the capabilities registers it looks like it has the 2nd
> capability register but not the VM capability.
>
> After applying your patches, adding your test driver (with SYSMMU_BASE
> corrected to 7885 value), and adding the sysmmu to dt, I tried to cat
> the test file that it creates in debugfs and I got an SError kernel
> panic.
>
> I tried tracing where the SError happens and it looks like it's this
> line:
>         /* Preload for emulation */
>         iowrite32(rw | vpn, obj->reg_base + MMU_EMU_PRELOAD);
>
> Trying to read the EMU registers using devmem results in a "Bus error".
>
> Could these emulation registers be missing from my SysMMU? Do you have
> any info on what version should have it? Or maybe some capability bit?
> I'll try testing it with DECON/DPP later and see if it works that way.
>

I don't have any manuals for v7.2, so I can only assume. Yes, it looks
to me very much like those EMU registers are missing in your SysMMU
IP-core: I remember seeing some similar SError messages while trying
to access some incorrect MMIO addresses. Good news is that once this
patch series is fixed and accepted, you can *probably* base your work
on top of it (as I only validated it with EMU registers for now). I
mean you can add some real IP-core users of that IOMMU, like graphics
(DPU), audio, camera, etc. Not sure though if it would be enough to
just add some DTS nodes, or your SoC support has to be added to some
drivers first.

> Best regards,
> David

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH 1/4] iommu/exynos: Set correct dma mask for SysMMU v5+
  2022-07-08 13:18       ` Sam Protsenko
@ 2022-07-11 12:27         ` Krzysztof Kozlowski
  -1 siblings, 0 replies; 47+ messages in thread
From: Krzysztof Kozlowski @ 2022-07-11 12:27 UTC (permalink / raw)
  To: Sam Protsenko
  Cc: Marek Szyprowski, Joerg Roedel, Will Deacon, Robin Murphy,
	Janghyuck Kim, Cho KyongHo, Daniel Mentz, Sumit Semwal, iommu,
	iommu, linux-arm-kernel, linux-samsung-soc, linux-kernel

On 08/07/2022 15:18, Sam Protsenko wrote:
> On Sun, 3 Jul 2022 at 21:50, Krzysztof Kozlowski
> <krzysztof.kozlowski@linaro.org> wrote:
>>
>> On 02/07/2022 23:37, Sam Protsenko wrote:
>>> SysMMU v5+ supports 36 bit physical address space. Set corresponding DMA
>>> mask to avoid falling back to SWTLBIO usage in dma_map_single() because
>>> of failed dma_capable() check.
>>>
>>> The original code for this fix was suggested by Marek.
>>>
>>> Originally-by: Marek Szyprowski <m.szyprowski@samsung.com>
>>
>> This is some tip specific tag, I don't think checkpatch allows it.
>> Either use suggesgted-by or co-developed-by + SoB.
>>
> 
> Yes, checkpatch is swearing at that line, though I encountered that
> tag mentioning somewhere in Documentation. Will rework it in v2.

Yes, in tip. It did not go outside of tip.

> 
>>> Signed-off-by: Sam Protsenko <semen.protsenko@linaro.org>
>>> ---
>>>  drivers/iommu/exynos-iommu.c | 8 ++++++++
>>>  1 file changed, 8 insertions(+)
>>>
>>> diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
>>> index 71f2018e23fe..28f8c8d93aa3 100644
>>> --- a/drivers/iommu/exynos-iommu.c
>>> +++ b/drivers/iommu/exynos-iommu.c
>>> @@ -647,6 +647,14 @@ static int exynos_sysmmu_probe(struct platform_device *pdev)
>>>               }
>>>       }
>>>
>>> +     if (MMU_MAJ_VER(data->version) >= 5) {
>>> +             ret = dma_set_mask(dev, DMA_BIT_MASK(36));
>>> +             if (ret) {
>>> +                     dev_err(dev, "Unable to set DMA mask: %d\n", ret);
>>
>> Missing cleanup: iommu_device_unregister
>> and probably also: iommu_device_sysfs_remove
>>
> 
> Right. Also the correct cleanup should be added for failing
> iommu_device_register() case, above of the quoted code. Will do that
> in v2, thanks.
> 
> Another thing is that "remove" method is missing. But guess I'll get
> to it later, when adding modularization support for this driver.

remove is independent of modules, so it should be here already.

Best regards,
Krzysztof

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH 1/4] iommu/exynos: Set correct dma mask for SysMMU v5+
@ 2022-07-11 12:27         ` Krzysztof Kozlowski
  0 siblings, 0 replies; 47+ messages in thread
From: Krzysztof Kozlowski @ 2022-07-11 12:27 UTC (permalink / raw)
  To: Sam Protsenko
  Cc: Marek Szyprowski, Joerg Roedel, Will Deacon, Robin Murphy,
	Janghyuck Kim, Cho KyongHo, Daniel Mentz, Sumit Semwal, iommu,
	iommu, linux-arm-kernel, linux-samsung-soc, linux-kernel

On 08/07/2022 15:18, Sam Protsenko wrote:
> On Sun, 3 Jul 2022 at 21:50, Krzysztof Kozlowski
> <krzysztof.kozlowski@linaro.org> wrote:
>>
>> On 02/07/2022 23:37, Sam Protsenko wrote:
>>> SysMMU v5+ supports 36 bit physical address space. Set corresponding DMA
>>> mask to avoid falling back to SWTLBIO usage in dma_map_single() because
>>> of failed dma_capable() check.
>>>
>>> The original code for this fix was suggested by Marek.
>>>
>>> Originally-by: Marek Szyprowski <m.szyprowski@samsung.com>
>>
>> This is some tip specific tag, I don't think checkpatch allows it.
>> Either use suggesgted-by or co-developed-by + SoB.
>>
> 
> Yes, checkpatch is swearing at that line, though I encountered that
> tag mentioning somewhere in Documentation. Will rework it in v2.

Yes, in tip. It did not go outside of tip.

> 
>>> Signed-off-by: Sam Protsenko <semen.protsenko@linaro.org>
>>> ---
>>>  drivers/iommu/exynos-iommu.c | 8 ++++++++
>>>  1 file changed, 8 insertions(+)
>>>
>>> diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
>>> index 71f2018e23fe..28f8c8d93aa3 100644
>>> --- a/drivers/iommu/exynos-iommu.c
>>> +++ b/drivers/iommu/exynos-iommu.c
>>> @@ -647,6 +647,14 @@ static int exynos_sysmmu_probe(struct platform_device *pdev)
>>>               }
>>>       }
>>>
>>> +     if (MMU_MAJ_VER(data->version) >= 5) {
>>> +             ret = dma_set_mask(dev, DMA_BIT_MASK(36));
>>> +             if (ret) {
>>> +                     dev_err(dev, "Unable to set DMA mask: %d\n", ret);
>>
>> Missing cleanup: iommu_device_unregister
>> and probably also: iommu_device_sysfs_remove
>>
> 
> Right. Also the correct cleanup should be added for failing
> iommu_device_register() case, above of the quoted code. Will do that
> in v2, thanks.
> 
> Another thing is that "remove" method is missing. But guess I'll get
> to it later, when adding modularization support for this driver.

remove is independent of modules, so it should be here already.

Best regards,
Krzysztof

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH 1/4] iommu/exynos: Set correct dma mask for SysMMU v5+
  2022-07-11 12:27         ` Krzysztof Kozlowski
@ 2022-07-11 12:59           ` Robin Murphy
  -1 siblings, 0 replies; 47+ messages in thread
From: Robin Murphy @ 2022-07-11 12:59 UTC (permalink / raw)
  To: Krzysztof Kozlowski, Sam Protsenko
  Cc: Marek Szyprowski, Joerg Roedel, Will Deacon, Janghyuck Kim,
	Cho KyongHo, Daniel Mentz, Sumit Semwal, iommu, iommu,
	linux-arm-kernel, linux-samsung-soc, linux-kernel

On 2022-07-11 13:27, Krzysztof Kozlowski wrote:
> On 08/07/2022 15:18, Sam Protsenko wrote:
>> On Sun, 3 Jul 2022 at 21:50, Krzysztof Kozlowski
>> <krzysztof.kozlowski@linaro.org> wrote:
>>>
>>> On 02/07/2022 23:37, Sam Protsenko wrote:
>>>> SysMMU v5+ supports 36 bit physical address space. Set corresponding DMA
>>>> mask to avoid falling back to SWTLBIO usage in dma_map_single() because
>>>> of failed dma_capable() check.
>>>>
>>>> The original code for this fix was suggested by Marek.
>>>>
>>>> Originally-by: Marek Szyprowski <m.szyprowski@samsung.com>
>>>
>>> This is some tip specific tag, I don't think checkpatch allows it.
>>> Either use suggesgted-by or co-developed-by + SoB.
>>>
>>
>> Yes, checkpatch is swearing at that line, though I encountered that
>> tag mentioning somewhere in Documentation. Will rework it in v2.
> 
> Yes, in tip. It did not go outside of tip.
> 
>>
>>>> Signed-off-by: Sam Protsenko <semen.protsenko@linaro.org>
>>>> ---
>>>>   drivers/iommu/exynos-iommu.c | 8 ++++++++
>>>>   1 file changed, 8 insertions(+)
>>>>
>>>> diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
>>>> index 71f2018e23fe..28f8c8d93aa3 100644
>>>> --- a/drivers/iommu/exynos-iommu.c
>>>> +++ b/drivers/iommu/exynos-iommu.c
>>>> @@ -647,6 +647,14 @@ static int exynos_sysmmu_probe(struct platform_device *pdev)
>>>>                }
>>>>        }
>>>>
>>>> +     if (MMU_MAJ_VER(data->version) >= 5) {
>>>> +             ret = dma_set_mask(dev, DMA_BIT_MASK(36));
>>>> +             if (ret) {
>>>> +                     dev_err(dev, "Unable to set DMA mask: %d\n", ret);
>>>
>>> Missing cleanup: iommu_device_unregister
>>> and probably also: iommu_device_sysfs_remove
>>>
>>
>> Right. Also the correct cleanup should be added for failing
>> iommu_device_register() case, above of the quoted code. Will do that
>> in v2, thanks.
>>
>> Another thing is that "remove" method is missing. But guess I'll get
>> to it later, when adding modularization support for this driver.
> 
> remove is independent of modules, so it should be here already.

.suppress_bind_attrs is set in the driver, so a .remove method on its 
own would be dead code, since there's no way for it to be called. We can 
permit module unloading since the module itself can be reference counted 
(which in practice usually means that unloading will be denied). However 
that's not the case for driver binding itself, so it's better not to 
even pretend that removing an IOMMU's driver while other drivers are 
using it (usually via DMA ops without even realising) is going to have 
anything other than catastrophic results.

Thanks,
Robin.

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH 1/4] iommu/exynos: Set correct dma mask for SysMMU v5+
@ 2022-07-11 12:59           ` Robin Murphy
  0 siblings, 0 replies; 47+ messages in thread
From: Robin Murphy @ 2022-07-11 12:59 UTC (permalink / raw)
  To: Krzysztof Kozlowski, Sam Protsenko
  Cc: Marek Szyprowski, Joerg Roedel, Will Deacon, Janghyuck Kim,
	Cho KyongHo, Daniel Mentz, Sumit Semwal, iommu, iommu,
	linux-arm-kernel, linux-samsung-soc, linux-kernel

On 2022-07-11 13:27, Krzysztof Kozlowski wrote:
> On 08/07/2022 15:18, Sam Protsenko wrote:
>> On Sun, 3 Jul 2022 at 21:50, Krzysztof Kozlowski
>> <krzysztof.kozlowski@linaro.org> wrote:
>>>
>>> On 02/07/2022 23:37, Sam Protsenko wrote:
>>>> SysMMU v5+ supports 36 bit physical address space. Set corresponding DMA
>>>> mask to avoid falling back to SWTLBIO usage in dma_map_single() because
>>>> of failed dma_capable() check.
>>>>
>>>> The original code for this fix was suggested by Marek.
>>>>
>>>> Originally-by: Marek Szyprowski <m.szyprowski@samsung.com>
>>>
>>> This is some tip specific tag, I don't think checkpatch allows it.
>>> Either use suggesgted-by or co-developed-by + SoB.
>>>
>>
>> Yes, checkpatch is swearing at that line, though I encountered that
>> tag mentioning somewhere in Documentation. Will rework it in v2.
> 
> Yes, in tip. It did not go outside of tip.
> 
>>
>>>> Signed-off-by: Sam Protsenko <semen.protsenko@linaro.org>
>>>> ---
>>>>   drivers/iommu/exynos-iommu.c | 8 ++++++++
>>>>   1 file changed, 8 insertions(+)
>>>>
>>>> diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
>>>> index 71f2018e23fe..28f8c8d93aa3 100644
>>>> --- a/drivers/iommu/exynos-iommu.c
>>>> +++ b/drivers/iommu/exynos-iommu.c
>>>> @@ -647,6 +647,14 @@ static int exynos_sysmmu_probe(struct platform_device *pdev)
>>>>                }
>>>>        }
>>>>
>>>> +     if (MMU_MAJ_VER(data->version) >= 5) {
>>>> +             ret = dma_set_mask(dev, DMA_BIT_MASK(36));
>>>> +             if (ret) {
>>>> +                     dev_err(dev, "Unable to set DMA mask: %d\n", ret);
>>>
>>> Missing cleanup: iommu_device_unregister
>>> and probably also: iommu_device_sysfs_remove
>>>
>>
>> Right. Also the correct cleanup should be added for failing
>> iommu_device_register() case, above of the quoted code. Will do that
>> in v2, thanks.
>>
>> Another thing is that "remove" method is missing. But guess I'll get
>> to it later, when adding modularization support for this driver.
> 
> remove is independent of modules, so it should be here already.

.suppress_bind_attrs is set in the driver, so a .remove method on its 
own would be dead code, since there's no way for it to be called. We can 
permit module unloading since the module itself can be reference counted 
(which in practice usually means that unloading will be denied). However 
that's not the case for driver binding itself, so it's better not to 
even pretend that removing an IOMMU's driver while other drivers are 
using it (usually via DMA ops without even realising) is going to have 
anything other than catastrophic results.

Thanks,
Robin.

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH 0/4] iommu/exynos: Add basic support for SysMMU v7
  2022-07-03 12:47     ` David Virag
@ 2022-07-13 14:14       ` Sam Protsenko
  -1 siblings, 0 replies; 47+ messages in thread
From: Sam Protsenko @ 2022-07-13 14:14 UTC (permalink / raw)
  To: David Virag
  Cc: Marek Szyprowski, Krzysztof Kozlowski, Joerg Roedel, Will Deacon,
	Robin Murphy, Janghyuck Kim, Cho KyongHo, Daniel Mentz,
	Sumit Semwal, iommu, iommu, linux-arm-kernel, linux-samsung-soc,
	linux-kernel

On Sun, 3 Jul 2022 at 13:47, David Virag <virag.david003@gmail.com> wrote:
>
> On Sun, 2022-07-03 at 00:48 +0300, Sam Protsenko wrote:
> [...]
> > Hi Marek,
> >
> > As I understand, you have some board with SysMMU v7, which is not VM
> > capable (judging from the patches you shared earlier). Could you
> > please somehow verify if this series works fine for you? For example,
> > this testing driver [1] can be helpful.
> >
> > Thanks!
> >
> > [1]
> > https://github.com/joe-skb7/linux/commit/bbadd46fa525fe1fef2ccbdfff81f7d29caf0506
>
> Hi Sam,
>
> Not Marek here, but I wanted to try this on my jackpotlte (Exynos
> 7885). The driver reports it's DPU sysmmu as version 7.2, and manually
> reading the capabilities registers it looks like it has the 2nd
> capability register but not the VM capability.
>
> After applying your patches, adding your test driver (with SYSMMU_BASE
> corrected to 7885 value), and adding the sysmmu to dt, I tried to cat
> the test file that it creates in debugfs and I got an SError kernel
> panic.
>
> I tried tracing where the SError happens and it looks like it's this
> line:
>         /* Preload for emulation */
>         iowrite32(rw | vpn, obj->reg_base + MMU_EMU_PRELOAD);
>
> Trying to read the EMU registers using devmem results in a "Bus error".
>
> Could these emulation registers be missing from my SysMMU? Do you have
> any info on what version should have it? Or maybe some capability bit?
> I'll try testing it with DECON/DPP later and see if it works that way.
>

Hey David,

Can you please try out the [1] branch again? I've added support for
Exynos7885 there, using the info provided by Janghyuck Kim: apparently
Exynos7885 has EMU registers, but those have some other offsets than
on Exynos850:

    #define MMU_EMU_PRELOAD    0x8040
    #define MMU_EMU_SHOT       0x8044

I wonder if my changes to [1] do the trick.

[1] https://github.com/joe-skb7/linux/tree/e850-96-mainline-iommu

> Best regards,
> David

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH 0/4] iommu/exynos: Add basic support for SysMMU v7
@ 2022-07-13 14:14       ` Sam Protsenko
  0 siblings, 0 replies; 47+ messages in thread
From: Sam Protsenko @ 2022-07-13 14:14 UTC (permalink / raw)
  To: David Virag
  Cc: Marek Szyprowski, Krzysztof Kozlowski, Joerg Roedel, Will Deacon,
	Robin Murphy, Janghyuck Kim, Cho KyongHo, Daniel Mentz,
	Sumit Semwal, iommu, iommu, linux-arm-kernel, linux-samsung-soc,
	linux-kernel

On Sun, 3 Jul 2022 at 13:47, David Virag <virag.david003@gmail.com> wrote:
>
> On Sun, 2022-07-03 at 00:48 +0300, Sam Protsenko wrote:
> [...]
> > Hi Marek,
> >
> > As I understand, you have some board with SysMMU v7, which is not VM
> > capable (judging from the patches you shared earlier). Could you
> > please somehow verify if this series works fine for you? For example,
> > this testing driver [1] can be helpful.
> >
> > Thanks!
> >
> > [1]
> > https://github.com/joe-skb7/linux/commit/bbadd46fa525fe1fef2ccbdfff81f7d29caf0506
>
> Hi Sam,
>
> Not Marek here, but I wanted to try this on my jackpotlte (Exynos
> 7885). The driver reports it's DPU sysmmu as version 7.2, and manually
> reading the capabilities registers it looks like it has the 2nd
> capability register but not the VM capability.
>
> After applying your patches, adding your test driver (with SYSMMU_BASE
> corrected to 7885 value), and adding the sysmmu to dt, I tried to cat
> the test file that it creates in debugfs and I got an SError kernel
> panic.
>
> I tried tracing where the SError happens and it looks like it's this
> line:
>         /* Preload for emulation */
>         iowrite32(rw | vpn, obj->reg_base + MMU_EMU_PRELOAD);
>
> Trying to read the EMU registers using devmem results in a "Bus error".
>
> Could these emulation registers be missing from my SysMMU? Do you have
> any info on what version should have it? Or maybe some capability bit?
> I'll try testing it with DECON/DPP later and see if it works that way.
>

Hey David,

Can you please try out the [1] branch again? I've added support for
Exynos7885 there, using the info provided by Janghyuck Kim: apparently
Exynos7885 has EMU registers, but those have some other offsets than
on Exynos850:

    #define MMU_EMU_PRELOAD    0x8040
    #define MMU_EMU_SHOT       0x8044

I wonder if my changes to [1] do the trick.

[1] https://github.com/joe-skb7/linux/tree/e850-96-mainline-iommu

> Best regards,
> David

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 47+ messages in thread

end of thread, other threads:[~2022-07-13 14:16 UTC | newest]

Thread overview: 47+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-07-02 21:37 [PATCH 0/4] iommu/exynos: Add basic support for SysMMU v7 Sam Protsenko
2022-07-02 21:37 ` Sam Protsenko
2022-07-02 21:37 ` Sam Protsenko
2022-07-02 21:37 ` [PATCH 1/4] iommu/exynos: Set correct dma mask for SysMMU v5+ Sam Protsenko
2022-07-02 21:37   ` Sam Protsenko
2022-07-02 21:37   ` Sam Protsenko
2022-07-03 18:50   ` Krzysztof Kozlowski
2022-07-03 18:50     ` Krzysztof Kozlowski
2022-07-03 18:50     ` Krzysztof Kozlowski
2022-07-08 13:18     ` Sam Protsenko
2022-07-08 13:18       ` Sam Protsenko
2022-07-11 12:27       ` Krzysztof Kozlowski
2022-07-11 12:27         ` Krzysztof Kozlowski
2022-07-11 12:59         ` Robin Murphy
2022-07-11 12:59           ` Robin Murphy
2022-07-02 21:37 ` [PATCH 2/4] iommu/exynos: Check if SysMMU v7 has VM registers Sam Protsenko
2022-07-02 21:37   ` Sam Protsenko
2022-07-02 21:37   ` Sam Protsenko
2022-07-03 19:10   ` Krzysztof Kozlowski
2022-07-03 19:10     ` Krzysztof Kozlowski
2022-07-03 19:10     ` Krzysztof Kozlowski
2022-07-08 13:34     ` Sam Protsenko
2022-07-08 13:34       ` Sam Protsenko
2022-07-02 21:37 ` [PATCH 3/4] iommu/exynos: Use lookup based approach to access v7 registers Sam Protsenko
2022-07-02 21:37   ` Sam Protsenko
2022-07-02 21:37   ` Sam Protsenko
2022-07-03 19:29   ` Krzysztof Kozlowski
2022-07-03 19:29     ` Krzysztof Kozlowski
2022-07-03 19:29     ` Krzysztof Kozlowski
2022-07-08 18:13     ` Sam Protsenko
2022-07-08 18:13       ` Sam Protsenko
2022-07-02 21:37 ` [PATCH 4/4] iommu/exynos: Add minimal support for SysMMU v7 with VM registers Sam Protsenko
2022-07-02 21:37   ` Sam Protsenko
2022-07-02 21:37   ` Sam Protsenko
2022-07-02 21:48 ` [PATCH 0/4] iommu/exynos: Add basic support for SysMMU v7 Sam Protsenko
2022-07-02 21:48   ` Sam Protsenko
2022-07-02 21:48   ` Sam Protsenko
2022-07-03 12:47   ` David Virag
2022-07-03 12:47     ` David Virag
2022-07-03 12:47     ` David Virag
2022-07-06 14:24     ` Sam Protsenko
2022-07-06 14:24       ` Sam Protsenko
2022-07-06 14:24       ` Sam Protsenko
2022-07-10 23:04     ` Sam Protsenko
2022-07-10 23:04       ` Sam Protsenko
2022-07-13 14:14     ` Sam Protsenko
2022-07-13 14:14       ` Sam Protsenko

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.