linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v8 00/14] iommu/rockchip: Use OF_IOMMU
@ 2018-03-23  7:38 Jeffy Chen
  2018-03-23  7:38 ` [PATCH v8 01/14] iommu/rockchip: Prohibit unbind and remove Jeffy Chen
                   ` (14 more replies)
  0 siblings, 15 replies; 27+ messages in thread
From: Jeffy Chen @ 2018-03-23  7:38 UTC (permalink / raw)
  To: linux-kernel
  Cc: jcliang, robin.murphy, xxm, tfiga, Jeffy Chen, Romain Perier,
	Yakir Yang, Arnd Bergmann, Liang Chen, Rob Herring, Shawn Lin,
	Catalin Marinas, Joerg Roedel, David Wu, Finley Xiao,
	Enric Balletbo i Serra, Heiko Stuebner, Jacob Chen, Kever Yang,
	Brian Norris, linux-rockchip, Rocky Hao, Will Deacon,
	Nickey Yang, devicetree, Mark Yao, Russell King,
	linux-arm-kernel, Sugar Zhang, iommu, Caesar Wang, Mark Rutland


This series fixes some issues in rockchip iommu driver, and add of_iommu
support in it.

Changes in v8:
Rebase on newest for-next.
Don't introduce the additional return.
Rename startup()/shutdown() to enable()/disable().
Do runtime PM suspend in .shutdown().
Modify pm_runtime_get_if_in_use()/pm_runtime_put() as Tomasz suggested.

Changes in v7:
Use iommu_group_ref_get to avoid ref leak

Changes in v6:
Add clk names, and modify all iommu nodes in all existing rockchip dts
Fix dt-binding as Robin suggested.
Use aclk and iface clk as Rob and Robin suggested, and split binding
patch.

Changes in v5:
Use out labels to save the duplication between the error and success paths.
Use RK_MMU_POLL_PERIOD_US instead of 100.
Remove clk names.
Use clk_bulk APIs.
Avoid race about pm_runtime_get_if_in_use() and pm_runtime_enabled().

Changes in v4:
Rewrite commit message.

Changes in v3:
Also remove remove() and module_exit() as Tomasz suggested.
Loop platform_get_irq() as Robin suggested.
Add struct rk_iommudata.
Squash iommu/rockchip: Use iommu_group_get_for_dev() for add_device
Only call startup() and shutdown() when iommu attached.
Remove pm_mutex.
Check runtime PM disabled.
Check pm_runtime in rk_iommu_irq().
Remove rk_iommudata->domain.

Changes in v2:
Move irq request to probe(in patch[0])
Move bus_set_iommu() to rk_iommu_probe().

Jeffy Chen (10):
  iommu/rockchip: Prohibit unbind and remove
  iommu/rockchip: Fix error handling in probe
  iommu/rockchip: Request irqs in rk_iommu_probe()
  ARM: dts: rockchip: add clocks in iommu nodes
  dt-bindings: iommu/rockchip: Add clock property
  iommu/rockchip: Use IOMMU device for dma mapping operations
  iommu/rockchip: Use OF_IOMMU to attach devices automatically
  iommu/rockchip: Fix error handling in init
  iommu/rockchip: Add runtime PM support
  iommu/rockchip: Support sharing IOMMU between masters

Tomasz Figa (4):
  iommu/rockchip: Fix error handling in attach
  iommu/rockchip: Use iopoll helpers to wait for hardware
  iommu/rockchip: Fix TLB flush of secondary IOMMUs
  iommu/rockchip: Control clocks needed to access the IOMMU

 .../devicetree/bindings/iommu/rockchip,iommu.txt   |   7 +
 arch/arm/boot/dts/rk3036.dtsi                      |   2 +
 arch/arm/boot/dts/rk322x.dtsi                      |   8 +
 arch/arm/boot/dts/rk3288.dtsi                      |  12 +
 arch/arm64/boot/dts/rockchip/rk3328.dtsi           |  10 +
 arch/arm64/boot/dts/rockchip/rk3368.dtsi           |  10 +
 arch/arm64/boot/dts/rockchip/rk3399.dtsi           |  14 +-
 drivers/iommu/rockchip-iommu.c                     | 600 +++++++++++----------
 8 files changed, 363 insertions(+), 300 deletions(-)

-- 
2.11.0

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

* [PATCH v8 01/14] iommu/rockchip: Prohibit unbind and remove
  2018-03-23  7:38 [PATCH v8 00/14] iommu/rockchip: Use OF_IOMMU Jeffy Chen
@ 2018-03-23  7:38 ` Jeffy Chen
  2018-03-23  7:38 ` [PATCH v8 02/14] iommu/rockchip: Fix error handling in probe Jeffy Chen
                   ` (13 subsequent siblings)
  14 siblings, 0 replies; 27+ messages in thread
From: Jeffy Chen @ 2018-03-23  7:38 UTC (permalink / raw)
  To: linux-kernel
  Cc: jcliang, robin.murphy, xxm, tfiga, Jeffy Chen, Heiko Stuebner,
	linux-rockchip, iommu, Joerg Roedel, linux-arm-kernel

Removal of IOMMUs cannot be done reliably.

This is similar to exynos iommu driver.

Signed-off-by: Jeffy Chen <jeffy.chen@rock-chips.com>
Reviewed-by: Tomasz Figa <tfiga@chromium.org>
Acked-by: Robin Murphy <robin.murphy@arm.com>
---

Changes in v8:
Rebase on newest for-next.

Changes in v7: None
Changes in v6: None
Changes in v5: None
Changes in v4:
Rewrite commit message.

Changes in v3:
Also remove remove() and module_exit() as Tomasz suggested.

Changes in v2: None

 drivers/iommu/rockchip-iommu.c | 21 +--------------------
 1 file changed, 1 insertion(+), 20 deletions(-)

diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c
index 6a3719e118da..e7fb824d123e 100644
--- a/drivers/iommu/rockchip-iommu.c
+++ b/drivers/iommu/rockchip-iommu.c
@@ -1197,18 +1197,6 @@ static int rk_iommu_probe(struct platform_device *pdev)
 	return err;
 }
 
-static int rk_iommu_remove(struct platform_device *pdev)
-{
-	struct rk_iommu *iommu = platform_get_drvdata(pdev);
-
-	if (iommu) {
-		iommu_device_sysfs_remove(&iommu->iommu);
-		iommu_device_unregister(&iommu->iommu);
-	}
-
-	return 0;
-}
-
 static void rk_iommu_shutdown(struct platform_device *pdev)
 {
 	struct rk_iommu *iommu = platform_get_drvdata(pdev);
@@ -1234,11 +1222,11 @@ MODULE_DEVICE_TABLE(of, rk_iommu_dt_ids);
 
 static struct platform_driver rk_iommu_driver = {
 	.probe = rk_iommu_probe,
-	.remove = rk_iommu_remove,
 	.shutdown = rk_iommu_shutdown,
 	.driver = {
 		   .name = "rk_iommu",
 		   .of_match_table = rk_iommu_dt_ids,
+		   .suppress_bind_attrs = true,
 	},
 };
 
@@ -1266,14 +1254,7 @@ static int __init rk_iommu_init(void)
 		platform_driver_unregister(&rk_iommu_domain_driver);
 	return ret;
 }
-static void __exit rk_iommu_exit(void)
-{
-	platform_driver_unregister(&rk_iommu_driver);
-	platform_driver_unregister(&rk_iommu_domain_driver);
-}
-
 subsys_initcall(rk_iommu_init);
-module_exit(rk_iommu_exit);
 
 MODULE_DESCRIPTION("IOMMU API for Rockchip");
 MODULE_AUTHOR("Simon Xue <xxm@rock-chips.com> and Daniel Kurtz <djkurtz@chromium.org>");
-- 
2.11.0

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

* [PATCH v8 02/14] iommu/rockchip: Fix error handling in probe
  2018-03-23  7:38 [PATCH v8 00/14] iommu/rockchip: Use OF_IOMMU Jeffy Chen
  2018-03-23  7:38 ` [PATCH v8 01/14] iommu/rockchip: Prohibit unbind and remove Jeffy Chen
@ 2018-03-23  7:38 ` Jeffy Chen
  2018-03-23  7:38 ` [PATCH v8 03/14] iommu/rockchip: Request irqs in rk_iommu_probe() Jeffy Chen
                   ` (12 subsequent siblings)
  14 siblings, 0 replies; 27+ messages in thread
From: Jeffy Chen @ 2018-03-23  7:38 UTC (permalink / raw)
  To: linux-kernel
  Cc: jcliang, robin.murphy, xxm, tfiga, Jeffy Chen, Heiko Stuebner,
	linux-rockchip, iommu, Joerg Roedel, linux-arm-kernel

Add missing iommu_device_sysfs_remove in error path.

Signed-off-by: Jeffy Chen <jeffy.chen@rock-chips.com>
Reviewed-by: Tomasz Figa <tfiga@chromium.org>
Acked-by: Robin Murphy <robin.murphy@arm.com>
---

Changes in v8:
Don't introduce the additional return.

Changes in v7: None
Changes in v6: None
Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2: None

 drivers/iommu/rockchip-iommu.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c
index e7fb824d123e..73117dbe839e 100644
--- a/drivers/iommu/rockchip-iommu.c
+++ b/drivers/iommu/rockchip-iommu.c
@@ -1193,6 +1193,8 @@ static int rk_iommu_probe(struct platform_device *pdev)
 
 	iommu_device_set_ops(&iommu->iommu, &rk_iommu_ops);
 	err = iommu_device_register(&iommu->iommu);
+	if (err)
+		iommu_device_sysfs_remove(&iommu->iommu);
 
 	return err;
 }
-- 
2.11.0

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

* [PATCH v8 03/14] iommu/rockchip: Request irqs in rk_iommu_probe()
  2018-03-23  7:38 [PATCH v8 00/14] iommu/rockchip: Use OF_IOMMU Jeffy Chen
  2018-03-23  7:38 ` [PATCH v8 01/14] iommu/rockchip: Prohibit unbind and remove Jeffy Chen
  2018-03-23  7:38 ` [PATCH v8 02/14] iommu/rockchip: Fix error handling in probe Jeffy Chen
@ 2018-03-23  7:38 ` Jeffy Chen
  2018-03-23  7:38 ` [PATCH v8 04/14] iommu/rockchip: Fix error handling in attach Jeffy Chen
                   ` (11 subsequent siblings)
  14 siblings, 0 replies; 27+ messages in thread
From: Jeffy Chen @ 2018-03-23  7:38 UTC (permalink / raw)
  To: linux-kernel
  Cc: jcliang, robin.murphy, xxm, tfiga, Jeffy Chen, Heiko Stuebner,
	linux-rockchip, iommu, Joerg Roedel, linux-arm-kernel

Move request_irq to the end of rk_iommu_probe().

Suggested-by: Robin Murphy <robin.murphy@arm.com>
Signed-off-by: Jeffy Chen <jeffy.chen@rock-chips.com>
Acked-by: Robin Murphy <robin.murphy@arm.com>
---

Changes in v8: None
Changes in v7: None
Changes in v6: None
Changes in v5: None
Changes in v4: None
Changes in v3:
Loop platform_get_irq() as Robin suggested.

Changes in v2: None

 drivers/iommu/rockchip-iommu.c | 38 +++++++++-----------------------------
 1 file changed, 9 insertions(+), 29 deletions(-)

diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c
index 73117dbe839e..ec3ff936aa60 100644
--- a/drivers/iommu/rockchip-iommu.c
+++ b/drivers/iommu/rockchip-iommu.c
@@ -90,8 +90,6 @@ struct rk_iommu {
 	struct device *dev;
 	void __iomem **bases;
 	int num_mmu;
-	int *irq;
-	int num_irq;
 	bool reset_disabled;
 	struct iommu_device iommu;
 	struct list_head node; /* entry in rk_iommu_domain.iommus */
@@ -830,13 +828,6 @@ static int rk_iommu_attach_device(struct iommu_domain *domain,
 
 	iommu->domain = domain;
 
-	for (i = 0; i < iommu->num_irq; i++) {
-		ret = devm_request_irq(iommu->dev, iommu->irq[i], rk_iommu_irq,
-				       IRQF_SHARED, dev_name(dev), iommu);
-		if (ret)
-			return ret;
-	}
-
 	for (i = 0; i < iommu->num_mmu; i++) {
 		rk_iommu_write(iommu->bases[i], RK_MMU_DTE_ADDR,
 			       rk_domain->dt_dma);
@@ -885,9 +876,6 @@ static void rk_iommu_detach_device(struct iommu_domain *domain,
 	}
 	rk_iommu_disable_stall(iommu);
 
-	for (i = 0; i < iommu->num_irq; i++)
-		devm_free_irq(iommu->dev, iommu->irq[i], iommu);
-
 	iommu->domain = NULL;
 
 	dev_dbg(dev, "Detached from iommu domain\n");
@@ -1138,7 +1126,7 @@ static int rk_iommu_probe(struct platform_device *pdev)
 	struct rk_iommu *iommu;
 	struct resource *res;
 	int num_res = pdev->num_resources;
-	int err, i;
+	int err, i, irq;
 
 	iommu = devm_kzalloc(dev, sizeof(*iommu), GFP_KERNEL);
 	if (!iommu)
@@ -1165,23 +1153,15 @@ static int rk_iommu_probe(struct platform_device *pdev)
 	if (iommu->num_mmu == 0)
 		return PTR_ERR(iommu->bases[0]);
 
-	iommu->num_irq = platform_irq_count(pdev);
-	if (iommu->num_irq < 0)
-		return iommu->num_irq;
-	if (iommu->num_irq == 0)
-		return -ENXIO;
+	i = 0;
+	while ((irq = platform_get_irq(pdev, i++)) != -ENXIO) {
+		if (irq < 0)
+			return irq;
 
-	iommu->irq = devm_kcalloc(dev, iommu->num_irq, sizeof(*iommu->irq),
-				  GFP_KERNEL);
-	if (!iommu->irq)
-		return -ENOMEM;
-
-	for (i = 0; i < iommu->num_irq; i++) {
-		iommu->irq[i] = platform_get_irq(pdev, i);
-		if (iommu->irq[i] < 0) {
-			dev_err(dev, "Failed to get IRQ, %d\n", iommu->irq[i]);
-			return -ENXIO;
-		}
+		err = devm_request_irq(iommu->dev, irq, rk_iommu_irq,
+				       IRQF_SHARED, dev_name(dev), iommu);
+		if (err)
+			return err;
 	}
 
 	iommu->reset_disabled = device_property_read_bool(dev,
-- 
2.11.0

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

* [PATCH v8 04/14] iommu/rockchip: Fix error handling in attach
  2018-03-23  7:38 [PATCH v8 00/14] iommu/rockchip: Use OF_IOMMU Jeffy Chen
                   ` (2 preceding siblings ...)
  2018-03-23  7:38 ` [PATCH v8 03/14] iommu/rockchip: Request irqs in rk_iommu_probe() Jeffy Chen
@ 2018-03-23  7:38 ` Jeffy Chen
  2018-03-23  7:38 ` [PATCH v8 05/14] iommu/rockchip: Use iopoll helpers to wait for hardware Jeffy Chen
                   ` (10 subsequent siblings)
  14 siblings, 0 replies; 27+ messages in thread
From: Jeffy Chen @ 2018-03-23  7:38 UTC (permalink / raw)
  To: linux-kernel
  Cc: jcliang, robin.murphy, xxm, tfiga, Jeffy Chen, Heiko Stuebner,
	linux-rockchip, iommu, Joerg Roedel, linux-arm-kernel

From: Tomasz Figa <tfiga@chromium.org>

Currently if the driver encounters an error while attaching device, it
will leave the IOMMU in an inconsistent state. Even though it shouldn't
really happen in reality, let's just add proper error path to keep
things consistent.

Signed-off-by: Tomasz Figa <tfiga@chromium.org>
Signed-off-by: Jeffy Chen <jeffy.chen@rock-chips.com>
Reviewed-by: Robin Murphy <robin.murphy@arm.com>
---

Changes in v8: None
Changes in v7: None
Changes in v6: None
Changes in v5:
Use out labels to save the duplication between the error and success paths.

Changes in v4: None
Changes in v3: None
Changes in v2:
Move irq request to probe(in patch[0])

 drivers/iommu/rockchip-iommu.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c
index ec3ff936aa60..5cbd5ceeb039 100644
--- a/drivers/iommu/rockchip-iommu.c
+++ b/drivers/iommu/rockchip-iommu.c
@@ -824,7 +824,7 @@ static int rk_iommu_attach_device(struct iommu_domain *domain,
 
 	ret = rk_iommu_force_reset(iommu);
 	if (ret)
-		return ret;
+		goto out_disable_stall;
 
 	iommu->domain = domain;
 
@@ -837,7 +837,7 @@ static int rk_iommu_attach_device(struct iommu_domain *domain,
 
 	ret = rk_iommu_enable_paging(iommu);
 	if (ret)
-		return ret;
+		goto out_disable_stall;
 
 	spin_lock_irqsave(&rk_domain->iommus_lock, flags);
 	list_add_tail(&iommu->node, &rk_domain->iommus);
@@ -845,9 +845,9 @@ static int rk_iommu_attach_device(struct iommu_domain *domain,
 
 	dev_dbg(dev, "Attached to iommu domain\n");
 
+out_disable_stall:
 	rk_iommu_disable_stall(iommu);
-
-	return 0;
+	return ret;
 }
 
 static void rk_iommu_detach_device(struct iommu_domain *domain,
-- 
2.11.0

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

* [PATCH v8 05/14] iommu/rockchip: Use iopoll helpers to wait for hardware
  2018-03-23  7:38 [PATCH v8 00/14] iommu/rockchip: Use OF_IOMMU Jeffy Chen
                   ` (3 preceding siblings ...)
  2018-03-23  7:38 ` [PATCH v8 04/14] iommu/rockchip: Fix error handling in attach Jeffy Chen
@ 2018-03-23  7:38 ` Jeffy Chen
  2018-03-23  7:38 ` [PATCH v8 06/14] iommu/rockchip: Fix TLB flush of secondary IOMMUs Jeffy Chen
                   ` (9 subsequent siblings)
  14 siblings, 0 replies; 27+ messages in thread
From: Jeffy Chen @ 2018-03-23  7:38 UTC (permalink / raw)
  To: linux-kernel
  Cc: jcliang, robin.murphy, xxm, tfiga, Jeffy Chen, Heiko Stuebner,
	linux-rockchip, iommu, Joerg Roedel, linux-arm-kernel

From: Tomasz Figa <tfiga@chromium.org>

This patch converts the rockchip-iommu driver to use the in-kernel
iopoll helpers to wait for certain status bits to change in registers
instead of an open-coded custom macro.

Signed-off-by: Tomasz Figa <tfiga@chromium.org>
Signed-off-by: Jeffy Chen <jeffy.chen@rock-chips.com>
Reviewed-by: Robin Murphy <robin.murphy@arm.com>
---

Changes in v8: None
Changes in v7: None
Changes in v6: None
Changes in v5:
Use RK_MMU_POLL_PERIOD_US instead of 100.

Changes in v4: None
Changes in v3: None
Changes in v2: None

 drivers/iommu/rockchip-iommu.c | 75 ++++++++++++++++++++++--------------------
 1 file changed, 39 insertions(+), 36 deletions(-)

diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c
index 5cbd5ceeb039..7130d92ff79c 100644
--- a/drivers/iommu/rockchip-iommu.c
+++ b/drivers/iommu/rockchip-iommu.c
@@ -13,7 +13,7 @@
 #include <linux/interrupt.h>
 #include <linux/io.h>
 #include <linux/iommu.h>
-#include <linux/jiffies.h>
+#include <linux/iopoll.h>
 #include <linux/list.h>
 #include <linux/mm.h>
 #include <linux/module.h>
@@ -36,7 +36,10 @@
 #define RK_MMU_AUTO_GATING	0x24
 
 #define DTE_ADDR_DUMMY		0xCAFEBABE
-#define FORCE_RESET_TIMEOUT	100	/* ms */
+
+#define RK_MMU_POLL_PERIOD_US		100
+#define RK_MMU_FORCE_RESET_TIMEOUT_US	100000
+#define RK_MMU_POLL_TIMEOUT_US		1000
 
 /* RK_MMU_STATUS fields */
 #define RK_MMU_STATUS_PAGING_ENABLED       BIT(0)
@@ -73,8 +76,6 @@
   */
 #define RK_IOMMU_PGSIZE_BITMAP 0x007ff000
 
-#define IOMMU_REG_POLL_COUNT_FAST 1000
-
 struct rk_iommu_domain {
 	struct list_head iommus;
 	struct platform_device *pdev;
@@ -109,27 +110,6 @@ static struct rk_iommu_domain *to_rk_domain(struct iommu_domain *dom)
 	return container_of(dom, struct rk_iommu_domain, domain);
 }
 
-/**
- * Inspired by _wait_for in intel_drv.h
- * This is NOT safe for use in interrupt context.
- *
- * Note that it's important that we check the condition again after having
- * timed out, since the timeout could be due to preemption or similar and
- * we've never had a chance to check the condition before the timeout.
- */
-#define rk_wait_for(COND, MS) ({ \
-	unsigned long timeout__ = jiffies + msecs_to_jiffies(MS) + 1;	\
-	int ret__ = 0;							\
-	while (!(COND)) {						\
-		if (time_after(jiffies, timeout__)) {			\
-			ret__ = (COND) ? 0 : -ETIMEDOUT;		\
-			break;						\
-		}							\
-		usleep_range(50, 100);					\
-	}								\
-	ret__;								\
-})
-
 /*
  * The Rockchip rk3288 iommu uses a 2-level page table.
  * The first level is the "Directory Table" (DT).
@@ -333,9 +313,21 @@ static bool rk_iommu_is_paging_enabled(struct rk_iommu *iommu)
 	return enable;
 }
 
+static bool rk_iommu_is_reset_done(struct rk_iommu *iommu)
+{
+	bool done = true;
+	int i;
+
+	for (i = 0; i < iommu->num_mmu; i++)
+		done &= rk_iommu_read(iommu->bases[i], RK_MMU_DTE_ADDR) == 0;
+
+	return done;
+}
+
 static int rk_iommu_enable_stall(struct rk_iommu *iommu)
 {
 	int ret, i;
+	bool val;
 
 	if (rk_iommu_is_stall_active(iommu))
 		return 0;
@@ -346,7 +338,9 @@ static int rk_iommu_enable_stall(struct rk_iommu *iommu)
 
 	rk_iommu_command(iommu, RK_MMU_CMD_ENABLE_STALL);
 
-	ret = rk_wait_for(rk_iommu_is_stall_active(iommu), 1);
+	ret = readx_poll_timeout(rk_iommu_is_stall_active, iommu, val,
+				 val, RK_MMU_POLL_PERIOD_US,
+				 RK_MMU_POLL_TIMEOUT_US);
 	if (ret)
 		for (i = 0; i < iommu->num_mmu; i++)
 			dev_err(iommu->dev, "Enable stall request timed out, status: %#08x\n",
@@ -358,13 +352,16 @@ static int rk_iommu_enable_stall(struct rk_iommu *iommu)
 static int rk_iommu_disable_stall(struct rk_iommu *iommu)
 {
 	int ret, i;
+	bool val;
 
 	if (!rk_iommu_is_stall_active(iommu))
 		return 0;
 
 	rk_iommu_command(iommu, RK_MMU_CMD_DISABLE_STALL);
 
-	ret = rk_wait_for(!rk_iommu_is_stall_active(iommu), 1);
+	ret = readx_poll_timeout(rk_iommu_is_stall_active, iommu, val,
+				 !val, RK_MMU_POLL_PERIOD_US,
+				 RK_MMU_POLL_TIMEOUT_US);
 	if (ret)
 		for (i = 0; i < iommu->num_mmu; i++)
 			dev_err(iommu->dev, "Disable stall request timed out, status: %#08x\n",
@@ -376,13 +373,16 @@ static int rk_iommu_disable_stall(struct rk_iommu *iommu)
 static int rk_iommu_enable_paging(struct rk_iommu *iommu)
 {
 	int ret, i;
+	bool val;
 
 	if (rk_iommu_is_paging_enabled(iommu))
 		return 0;
 
 	rk_iommu_command(iommu, RK_MMU_CMD_ENABLE_PAGING);
 
-	ret = rk_wait_for(rk_iommu_is_paging_enabled(iommu), 1);
+	ret = readx_poll_timeout(rk_iommu_is_paging_enabled, iommu, val,
+				 val, RK_MMU_POLL_PERIOD_US,
+				 RK_MMU_POLL_TIMEOUT_US);
 	if (ret)
 		for (i = 0; i < iommu->num_mmu; i++)
 			dev_err(iommu->dev, "Enable paging request timed out, status: %#08x\n",
@@ -394,13 +394,16 @@ static int rk_iommu_enable_paging(struct rk_iommu *iommu)
 static int rk_iommu_disable_paging(struct rk_iommu *iommu)
 {
 	int ret, i;
+	bool val;
 
 	if (!rk_iommu_is_paging_enabled(iommu))
 		return 0;
 
 	rk_iommu_command(iommu, RK_MMU_CMD_DISABLE_PAGING);
 
-	ret = rk_wait_for(!rk_iommu_is_paging_enabled(iommu), 1);
+	ret = readx_poll_timeout(rk_iommu_is_paging_enabled, iommu, val,
+				 !val, RK_MMU_POLL_PERIOD_US,
+				 RK_MMU_POLL_TIMEOUT_US);
 	if (ret)
 		for (i = 0; i < iommu->num_mmu; i++)
 			dev_err(iommu->dev, "Disable paging request timed out, status: %#08x\n",
@@ -413,6 +416,7 @@ static int rk_iommu_force_reset(struct rk_iommu *iommu)
 {
 	int ret, i;
 	u32 dte_addr;
+	bool val;
 
 	if (iommu->reset_disabled)
 		return 0;
@@ -433,13 +437,12 @@ static int rk_iommu_force_reset(struct rk_iommu *iommu)
 
 	rk_iommu_command(iommu, RK_MMU_CMD_FORCE_RESET);
 
-	for (i = 0; i < iommu->num_mmu; i++) {
-		ret = rk_wait_for(rk_iommu_read(iommu->bases[i], RK_MMU_DTE_ADDR) == 0x00000000,
-				  FORCE_RESET_TIMEOUT);
-		if (ret) {
-			dev_err(iommu->dev, "FORCE_RESET command timed out\n");
-			return ret;
-		}
+	ret = readx_poll_timeout(rk_iommu_is_reset_done, iommu, val,
+				 val, RK_MMU_FORCE_RESET_TIMEOUT_US,
+				 RK_MMU_POLL_TIMEOUT_US);
+	if (ret) {
+		dev_err(iommu->dev, "FORCE_RESET command timed out\n");
+		return ret;
 	}
 
 	return 0;
-- 
2.11.0

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

* [PATCH v8 06/14] iommu/rockchip: Fix TLB flush of secondary IOMMUs
  2018-03-23  7:38 [PATCH v8 00/14] iommu/rockchip: Use OF_IOMMU Jeffy Chen
                   ` (4 preceding siblings ...)
  2018-03-23  7:38 ` [PATCH v8 05/14] iommu/rockchip: Use iopoll helpers to wait for hardware Jeffy Chen
@ 2018-03-23  7:38 ` Jeffy Chen
  2018-03-23  7:38 ` [PATCH v8 07/14] ARM: dts: rockchip: add clocks in iommu nodes Jeffy Chen
                   ` (8 subsequent siblings)
  14 siblings, 0 replies; 27+ messages in thread
From: Jeffy Chen @ 2018-03-23  7:38 UTC (permalink / raw)
  To: linux-kernel
  Cc: jcliang, robin.murphy, xxm, tfiga, Jeffy Chen, Heiko Stuebner,
	linux-rockchip, iommu, Joerg Roedel, linux-arm-kernel

From: Tomasz Figa <tfiga@chromium.org>

Due to the bug in current code, only first IOMMU has the TLB lines
flushed in rk_iommu_zap_lines. This patch fixes the inner loop to
execute for all IOMMUs and properly flush the TLB.

Signed-off-by: Tomasz Figa <tfiga@chromium.org>
Signed-off-by: Jeffy Chen <jeffy.chen@rock-chips.com>
---

Changes in v8: None
Changes in v7: None
Changes in v6: None
Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2: None

 drivers/iommu/rockchip-iommu.c | 12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c
index 7130d92ff79c..c3df53e480ea 100644
--- a/drivers/iommu/rockchip-iommu.c
+++ b/drivers/iommu/rockchip-iommu.c
@@ -274,19 +274,21 @@ static void rk_iommu_base_command(void __iomem *base, u32 command)
 {
 	writel(command, base + RK_MMU_COMMAND);
 }
-static void rk_iommu_zap_lines(struct rk_iommu *iommu, dma_addr_t iova,
+static void rk_iommu_zap_lines(struct rk_iommu *iommu, dma_addr_t iova_start,
 			       size_t size)
 {
 	int i;
-
-	dma_addr_t iova_end = iova + size;
+	dma_addr_t iova_end = iova_start + size;
 	/*
 	 * TODO(djkurtz): Figure out when it is more efficient to shootdown the
 	 * entire iotlb rather than iterate over individual iovas.
 	 */
-	for (i = 0; i < iommu->num_mmu; i++)
-		for (; iova < iova_end; iova += SPAGE_SIZE)
+	for (i = 0; i < iommu->num_mmu; i++) {
+		dma_addr_t iova;
+
+		for (iova = iova_start; iova < iova_end; iova += SPAGE_SIZE)
 			rk_iommu_write(iommu->bases[i], RK_MMU_ZAP_ONE_LINE, iova);
+	}
 }
 
 static bool rk_iommu_is_stall_active(struct rk_iommu *iommu)
-- 
2.11.0

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

* [PATCH v8 07/14] ARM: dts: rockchip: add clocks in iommu nodes
  2018-03-23  7:38 [PATCH v8 00/14] iommu/rockchip: Use OF_IOMMU Jeffy Chen
                   ` (5 preceding siblings ...)
  2018-03-23  7:38 ` [PATCH v8 06/14] iommu/rockchip: Fix TLB flush of secondary IOMMUs Jeffy Chen
@ 2018-03-23  7:38 ` Jeffy Chen
  2018-04-09 14:41   ` Tomeu Vizoso
  2018-04-10 11:46   ` Heiko Stuebner
  2018-03-23  7:38 ` [PATCH v8 08/14] iommu/rockchip: Control clocks needed to access the IOMMU Jeffy Chen
                   ` (7 subsequent siblings)
  14 siblings, 2 replies; 27+ messages in thread
From: Jeffy Chen @ 2018-03-23  7:38 UTC (permalink / raw)
  To: linux-kernel
  Cc: jcliang, robin.murphy, xxm, tfiga, Jeffy Chen, Romain Perier,
	Yakir Yang, Arnd Bergmann, Liang Chen, Rob Herring, Shawn Lin,
	Catalin Marinas, David Wu, Finley Xiao, Enric Balletbo i Serra,
	Heiko Stuebner, Jacob Chen, Kever Yang, Brian Norris,
	linux-rockchip, Rocky Hao, Will Deacon, Nickey Yang, devicetree,
	Mark Yao, Russell King, linux-arm-kernel, Sugar Zhang,
	Caesar Wang, Mark Rutland

Add clocks in iommu nodes, since we are going to control clocks in
rockchip iommu driver.

Signed-off-by: Jeffy Chen <jeffy.chen@rock-chips.com>
---

Changes in v8: None
Changes in v7: None
Changes in v6:
Add clk names, and modify all iommu nodes in all existing rockchip dts

Changes in v5:
Remove clk names.

Changes in v4: None
Changes in v3: None
Changes in v2: None

 arch/arm/boot/dts/rk3036.dtsi            |  2 ++
 arch/arm/boot/dts/rk322x.dtsi            |  8 ++++++++
 arch/arm/boot/dts/rk3288.dtsi            | 12 ++++++++++++
 arch/arm64/boot/dts/rockchip/rk3328.dtsi | 10 ++++++++++
 arch/arm64/boot/dts/rockchip/rk3368.dtsi | 10 ++++++++++
 arch/arm64/boot/dts/rockchip/rk3399.dtsi | 14 ++++++++++++--
 6 files changed, 54 insertions(+), 2 deletions(-)

diff --git a/arch/arm/boot/dts/rk3036.dtsi b/arch/arm/boot/dts/rk3036.dtsi
index a97458112ff6..567a6a725f9c 100644
--- a/arch/arm/boot/dts/rk3036.dtsi
+++ b/arch/arm/boot/dts/rk3036.dtsi
@@ -197,6 +197,8 @@
 		reg = <0x10118300 0x100>;
 		interrupts = <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>;
 		interrupt-names = "vop_mmu";
+		clocks = <&cru ACLK_LCDC>, <&cru HCLK_LCDC>;
+		clock-names = "aclk", "iface";
 		#iommu-cells = <0>;
 		status = "disabled";
 	};
diff --git a/arch/arm/boot/dts/rk322x.dtsi b/arch/arm/boot/dts/rk322x.dtsi
index df1e47858675..be80e9a2c9af 100644
--- a/arch/arm/boot/dts/rk322x.dtsi
+++ b/arch/arm/boot/dts/rk322x.dtsi
@@ -584,6 +584,8 @@
 		reg = <0x20020800 0x100>;
 		interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
 		interrupt-names = "vpu_mmu";
+		clocks = <&cru ACLK_VPU>, <&cru HCLK_VPU>;
+		clock-names = "aclk", "iface";
 		iommu-cells = <0>;
 		status = "disabled";
 	};
@@ -593,6 +595,8 @@
 		reg = <0x20030480 0x40>, <0x200304c0 0x40>;
 		interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
 		interrupt-names = "vdec_mmu";
+		clocks = <&cru ACLK_RKVDEC>, <&cru HCLK_RKVDEC>;
+		clock-names = "aclk", "iface";
 		iommu-cells = <0>;
 		status = "disabled";
 	};
@@ -602,6 +606,8 @@
 		reg = <0x20053f00 0x100>;
 		interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
 		interrupt-names = "vop_mmu";
+		clocks = <&cru ACLK_VOP>, <&cru HCLK_VOP>;
+		clock-names = "aclk", "iface";
 		iommu-cells = <0>;
 		status = "disabled";
 	};
@@ -611,6 +617,8 @@
 		reg = <0x20070800 0x100>;
 		interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
 		interrupt-names = "iep_mmu";
+		clocks = <&cru ACLK_IEP>, <&cru HCLK_IEP>;
+		clock-names = "aclk", "iface";
 		iommu-cells = <0>;
 		status = "disabled";
 	};
diff --git a/arch/arm/boot/dts/rk3288.dtsi b/arch/arm/boot/dts/rk3288.dtsi
index be9acb6d28a1..d7e49d29ace5 100644
--- a/arch/arm/boot/dts/rk3288.dtsi
+++ b/arch/arm/boot/dts/rk3288.dtsi
@@ -959,6 +959,8 @@
 		reg = <0x0 0xff900800 0x0 0x40>;
 		interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
 		interrupt-names = "iep_mmu";
+		clocks = <&cru ACLK_IEP>, <&cru HCLK_IEP>;
+		clock-names = "aclk", "iface";
 		#iommu-cells = <0>;
 		status = "disabled";
 	};
@@ -968,6 +970,8 @@
 		reg = <0x0 0xff914000 0x0 0x100>, <0x0 0xff915000 0x0 0x100>;
 		interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
 		interrupt-names = "isp_mmu";
+		clocks = <&cru ACLK_ISP>, <&cru HCLK_ISP>;
+		clock-names = "aclk", "iface";
 		#iommu-cells = <0>;
 		rockchip,disable-mmu-reset;
 		status = "disabled";
@@ -1027,6 +1031,8 @@
 		reg = <0x0 0xff930300 0x0 0x100>;
 		interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>;
 		interrupt-names = "vopb_mmu";
+		clocks = <&cru ACLK_VOP0>, <&cru HCLK_VOP0>;
+		clock-names = "aclk", "iface";
 		power-domains = <&power RK3288_PD_VIO>;
 		#iommu-cells = <0>;
 		status = "disabled";
@@ -1075,6 +1081,8 @@
 		reg = <0x0 0xff940300 0x0 0x100>;
 		interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
 		interrupt-names = "vopl_mmu";
+		clocks = <&cru ACLK_VOP1>, <&cru HCLK_VOP1>;
+		clock-names = "aclk", "iface";
 		power-domains = <&power RK3288_PD_VIO>;
 		#iommu-cells = <0>;
 		status = "disabled";
@@ -1206,6 +1214,8 @@
 		reg = <0x0 0xff9a0800 0x0 0x100>;
 		interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
 		interrupt-names = "vpu_mmu";
+		clocks = <&cru ACLK_VCODEC>, <&cru HCLK_VCODEC>;
+		clock-names = "aclk", "iface";
 		#iommu-cells = <0>;
 		status = "disabled";
 	};
@@ -1215,6 +1225,8 @@
 		reg = <0x0 0xff9c0440 0x0 0x40>, <0x0 0xff9c0480 0x0 0x40>;
 		interrupts = <GIC_SPI 111 IRQ_TYPE_LEVEL_HIGH>;
 		interrupt-names = "hevc_mmu";
+		clocks = <&cru ACLK_HEVC>, <&cru HCLK_HEVC>;
+		clock-names = "aclk", "iface";
 		#iommu-cells = <0>;
 		status = "disabled";
 	};
diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi b/arch/arm64/boot/dts/rockchip/rk3328.dtsi
index be2bfbc6b483..b8e9da15e00c 100644
--- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi
@@ -595,6 +595,8 @@
 		reg = <0x0 0xff330200 0 0x100>;
 		interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>;
 		interrupt-names = "h265e_mmu";
+		clocks = <&cru ACLK_H265>, <&cru PCLK_H265>;
+		clock-names = "aclk", "iface";
 		#iommu-cells = <0>;
 		status = "disabled";
 	};
@@ -604,6 +606,8 @@
 		reg = <0x0 0xff340800 0x0 0x40>;
 		interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>;
 		interrupt-names = "vepu_mmu";
+		clocks = <&cru ACLK_VPU>, <&cru HCLK_VPU>;
+		clock-names = "aclk", "iface";
 		#iommu-cells = <0>;
 		status = "disabled";
 	};
@@ -613,6 +617,8 @@
 		reg = <0x0 0xff350800 0x0 0x40>;
 		interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
 		interrupt-names = "vpu_mmu";
+		clocks = <&cru ACLK_VPU>, <&cru HCLK_VPU>;
+		clock-names = "aclk", "iface";
 		#iommu-cells = <0>;
 		status = "disabled";
 	};
@@ -622,6 +628,8 @@
 		reg = <0x0 0xff360480 0x0 0x40>, <0x0 0xff3604c0 0x0 0x40>;
 		interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>;
 		interrupt-names = "rkvdec_mmu";
+		clocks = <&cru ACLK_RKVDEC>, <&cru HCLK_RKVDEC>;
+		clock-names = "aclk", "iface";
 		#iommu-cells = <0>;
 		status = "disabled";
 	};
@@ -631,6 +639,8 @@
 		reg = <0x0 0xff373f00 0x0 0x100>;
 		interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
 		interrupt-names = "vop_mmu";
+		clocks = <&cru ACLK_VOP>, <&cru HCLK_VOP>;
+		clock-names = "aclk", "iface";
 		#iommu-cells = <0>;
 		status = "disabled";
 	};
diff --git a/arch/arm64/boot/dts/rockchip/rk3368.dtsi b/arch/arm64/boot/dts/rockchip/rk3368.dtsi
index 03458ac44201..ad91ced78649 100644
--- a/arch/arm64/boot/dts/rockchip/rk3368.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3368.dtsi
@@ -742,6 +742,8 @@
 		reg = <0x0 0xff900800 0x0 0x100>;
 		interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
 		interrupt-names = "iep_mmu";
+		clocks = <&cru ACLK_IEP>, <&cru HCLK_IEP>;
+		clock-names = "aclk", "iface";
 		#iommu-cells = <0>;
 		status = "disabled";
 	};
@@ -752,6 +754,8 @@
 		      <0x0 0xff915000 0x0 0x100>;
 		interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
 		interrupt-names = "isp_mmu";
+		clocks = <&cru ACLK_ISP>, <&cru HCLK_ISP>;
+		clock-names = "aclk", "iface";
 		#iommu-cells = <0>;
 		rockchip,disable-mmu-reset;
 		status = "disabled";
@@ -762,6 +766,8 @@
 		reg = <0x0 0xff930300 0x0 0x100>;
 		interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>;
 		interrupt-names = "vop_mmu";
+		clocks = <&cru ACLK_VOP>, <&cru HCLK_VOP>;
+		clock-names = "aclk", "iface";
 		#iommu-cells = <0>;
 		status = "disabled";
 	};
@@ -772,6 +778,8 @@
 		      <0x0 0xff9a0480 0x0 0x40>;
 		interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>;
 		interrupt-names = "hevc_mmu";
+		clocks = <&cru ACLK_VIDEO>, <&cru HCLK_VIDEO>;
+		clock-names = "aclk", "iface";
 		#iommu-cells = <0>;
 		status = "disabled";
 	};
@@ -782,6 +790,8 @@
 		interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>,
 			     <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
 		interrupt-names = "vepu_mmu", "vdpu_mmu";
+		clocks = <&cru ACLK_VIDEO>, <&cru HCLK_VIDEO>;
+		clock-names = "aclk", "iface";
 		#iommu-cells = <0>;
 		status = "disabled";
 	};
diff --git a/arch/arm64/boot/dts/rockchip/rk3399.dtsi b/arch/arm64/boot/dts/rockchip/rk3399.dtsi
index 4550c0f82be9..56f6bb31b399 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3399.dtsi
@@ -1234,6 +1234,8 @@
 		reg = <0x0 0xff650800 0x0 0x40>;
 		interrupts = <GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH 0>;
 		interrupt-names = "vpu_mmu";
+		clocks = <&cru ACLK_VCODEC>, <&cru HCLK_VCODEC>;
+		clock-names = "aclk", "iface";
 		#iommu-cells = <0>;
 		status = "disabled";
 	};
@@ -1243,6 +1245,8 @@
 		reg = <0x0 0xff660480 0x0 0x40>, <0x0 0xff6604c0 0x0 0x40>;
 		interrupts = <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH 0>;
 		interrupt-names = "vdec_mmu";
+		clocks = <&cru ACLK_VDU>, <&cru HCLK_VDU>;
+		clock-names = "aclk", "iface";
 		#iommu-cells = <0>;
 		status = "disabled";
 	};
@@ -1252,6 +1256,8 @@
 		reg = <0x0 0xff670800 0x0 0x40>;
 		interrupts = <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH 0>;
 		interrupt-names = "iep_mmu";
+		clocks = <&cru ACLK_IEP>, <&cru HCLK_IEP>;
+		clock-names = "aclk", "iface";
 		#iommu-cells = <0>;
 		status = "disabled";
 	};
@@ -1599,7 +1605,7 @@
 		interrupts = <GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH 0>;
 		interrupt-names = "vopl_mmu";
 		clocks = <&cru ACLK_VOP1>, <&cru HCLK_VOP1>;
-		clock-names = "aclk", "hclk";
+		clock-names = "aclk", "iface";
 		power-domains = <&power RK3399_PD_VOPL>;
 		#iommu-cells = <0>;
 		status = "disabled";
@@ -1656,7 +1662,7 @@
 		interrupts = <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH 0>;
 		interrupt-names = "vopb_mmu";
 		clocks = <&cru ACLK_VOP0>, <&cru HCLK_VOP0>;
-		clock-names = "aclk", "hclk";
+		clock-names = "aclk", "iface";
 		power-domains = <&power RK3399_PD_VOPB>;
 		#iommu-cells = <0>;
 		status = "disabled";
@@ -1667,6 +1673,8 @@
 		reg = <0x0 0xff914000 0x0 0x100>, <0x0 0xff915000 0x0 0x100>;
 		interrupts = <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH 0>;
 		interrupt-names = "isp0_mmu";
+		clocks = <&cru ACLK_ISP0_NOC>, <&cru HCLK_ISP0_NOC>;
+		clock-names = "aclk", "iface";
 		#iommu-cells = <0>;
 		rockchip,disable-mmu-reset;
 		status = "disabled";
@@ -1677,6 +1685,8 @@
 		reg = <0x0 0xff924000 0x0 0x100>, <0x0 0xff925000 0x0 0x100>;
 		interrupts = <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH 0>;
 		interrupt-names = "isp1_mmu";
+		clocks = <&cru ACLK_ISP1_NOC>, <&cru HCLK_ISP1_NOC>;
+		clock-names = "aclk", "iface";
 		#iommu-cells = <0>;
 		rockchip,disable-mmu-reset;
 		status = "disabled";
-- 
2.11.0

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

* [PATCH v8 08/14] iommu/rockchip: Control clocks needed to access the IOMMU
  2018-03-23  7:38 [PATCH v8 00/14] iommu/rockchip: Use OF_IOMMU Jeffy Chen
                   ` (6 preceding siblings ...)
  2018-03-23  7:38 ` [PATCH v8 07/14] ARM: dts: rockchip: add clocks in iommu nodes Jeffy Chen
@ 2018-03-23  7:38 ` Jeffy Chen
  2018-03-23  7:38 ` [PATCH v8 09/14] dt-bindings: iommu/rockchip: Add clock property Jeffy Chen
                   ` (6 subsequent siblings)
  14 siblings, 0 replies; 27+ messages in thread
From: Jeffy Chen @ 2018-03-23  7:38 UTC (permalink / raw)
  To: linux-kernel
  Cc: jcliang, robin.murphy, xxm, tfiga, Jeffy Chen, Heiko Stuebner,
	linux-rockchip, iommu, Joerg Roedel, linux-arm-kernel

From: Tomasz Figa <tfiga@chromium.org>

Current code relies on master driver enabling necessary clocks before
IOMMU is accessed, however there are cases when the IOMMU should be
accessed while the master is not running yet, for example allocating
V4L2 videobuf2 buffers, which is done by the VB2 framework using DMA
mapping API and doesn't engage the master driver at all.

This patch fixes the problem by letting clocks needed for IOMMU
operation to be listed in Device Tree and making the driver enable them
for the time of accessing the hardware.

Signed-off-by: Tomasz Figa <tfiga@chromium.org>
Signed-off-by: Jeffy Chen <jeffy.chen@rock-chips.com>
Acked-by: Robin Murphy <robin.murphy@arm.com>
---

Changes in v8: None
Changes in v7: None
Changes in v6:
Fix dt-binding as Robin suggested.
Use aclk and iface clk as Rob and Robin suggested, and split binding
patch.

Changes in v5:
Use clk_bulk APIs.

Changes in v4: None
Changes in v3: None
Changes in v2: None

 drivers/iommu/rockchip-iommu.c | 50 +++++++++++++++++++++++++++++++++++++++---
 1 file changed, 47 insertions(+), 3 deletions(-)

diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c
index c3df53e480ea..50ab9fd4eeb0 100644
--- a/drivers/iommu/rockchip-iommu.c
+++ b/drivers/iommu/rockchip-iommu.c
@@ -4,6 +4,7 @@
  * published by the Free Software Foundation.
  */
 
+#include <linux/clk.h>
 #include <linux/compiler.h>
 #include <linux/delay.h>
 #include <linux/device.h>
@@ -87,10 +88,17 @@ struct rk_iommu_domain {
 	struct iommu_domain domain;
 };
 
+/* list of clocks required by IOMMU */
+static const char * const rk_iommu_clocks[] = {
+	"aclk", "iface",
+};
+
 struct rk_iommu {
 	struct device *dev;
 	void __iomem **bases;
 	int num_mmu;
+	struct clk_bulk_data *clocks;
+	int num_clocks;
 	bool reset_disabled;
 	struct iommu_device iommu;
 	struct list_head node; /* entry in rk_iommu_domain.iommus */
@@ -506,6 +514,8 @@ static irqreturn_t rk_iommu_irq(int irq, void *dev_id)
 	irqreturn_t ret = IRQ_NONE;
 	int i;
 
+	WARN_ON(clk_bulk_enable(iommu->num_clocks, iommu->clocks));
+
 	for (i = 0; i < iommu->num_mmu; i++) {
 		int_status = rk_iommu_read(iommu->bases[i], RK_MMU_INT_STATUS);
 		if (int_status == 0)
@@ -552,6 +562,8 @@ static irqreturn_t rk_iommu_irq(int irq, void *dev_id)
 		rk_iommu_write(iommu->bases[i], RK_MMU_INT_CLEAR, int_status);
 	}
 
+	clk_bulk_disable(iommu->num_clocks, iommu->clocks);
+
 	return ret;
 }
 
@@ -594,7 +606,9 @@ static void rk_iommu_zap_iova(struct rk_iommu_domain *rk_domain,
 	list_for_each(pos, &rk_domain->iommus) {
 		struct rk_iommu *iommu;
 		iommu = list_entry(pos, struct rk_iommu, node);
+		WARN_ON(clk_bulk_enable(iommu->num_clocks, iommu->clocks));
 		rk_iommu_zap_lines(iommu, iova, size);
+		clk_bulk_disable(iommu->num_clocks, iommu->clocks);
 	}
 	spin_unlock_irqrestore(&rk_domain->iommus_lock, flags);
 }
@@ -823,10 +837,14 @@ static int rk_iommu_attach_device(struct iommu_domain *domain,
 	if (!iommu)
 		return 0;
 
-	ret = rk_iommu_enable_stall(iommu);
+	ret = clk_bulk_enable(iommu->num_clocks, iommu->clocks);
 	if (ret)
 		return ret;
 
+	ret = rk_iommu_enable_stall(iommu);
+	if (ret)
+		goto out_disable_clocks;
+
 	ret = rk_iommu_force_reset(iommu);
 	if (ret)
 		goto out_disable_stall;
@@ -852,6 +870,8 @@ static int rk_iommu_attach_device(struct iommu_domain *domain,
 
 out_disable_stall:
 	rk_iommu_disable_stall(iommu);
+out_disable_clocks:
+	clk_bulk_disable(iommu->num_clocks, iommu->clocks);
 	return ret;
 }
 
@@ -873,6 +893,7 @@ static void rk_iommu_detach_device(struct iommu_domain *domain,
 	spin_unlock_irqrestore(&rk_domain->iommus_lock, flags);
 
 	/* Ignore error while disabling, just keep going */
+	WARN_ON(clk_bulk_enable(iommu->num_clocks, iommu->clocks));
 	rk_iommu_enable_stall(iommu);
 	rk_iommu_disable_paging(iommu);
 	for (i = 0; i < iommu->num_mmu; i++) {
@@ -880,6 +901,7 @@ static void rk_iommu_detach_device(struct iommu_domain *domain,
 		rk_iommu_write(iommu->bases[i], RK_MMU_DTE_ADDR, 0);
 	}
 	rk_iommu_disable_stall(iommu);
+	clk_bulk_disable(iommu->num_clocks, iommu->clocks);
 
 	iommu->domain = NULL;
 
@@ -1172,15 +1194,37 @@ static int rk_iommu_probe(struct platform_device *pdev)
 	iommu->reset_disabled = device_property_read_bool(dev,
 					"rockchip,disable-mmu-reset");
 
-	err = iommu_device_sysfs_add(&iommu->iommu, dev, NULL, dev_name(dev));
+	iommu->num_clocks = ARRAY_SIZE(rk_iommu_clocks);
+	iommu->clocks = devm_kcalloc(iommu->dev, iommu->num_clocks,
+				     sizeof(*iommu->clocks), GFP_KERNEL);
+	if (!iommu->clocks)
+		return -ENOMEM;
+
+	for (i = 0; i < iommu->num_clocks; ++i)
+		iommu->clocks[i].id = rk_iommu_clocks[i];
+
+	err = devm_clk_bulk_get(iommu->dev, iommu->num_clocks, iommu->clocks);
+	if (err)
+		return err;
+
+	err = clk_bulk_prepare(iommu->num_clocks, iommu->clocks);
 	if (err)
 		return err;
 
+	err = iommu_device_sysfs_add(&iommu->iommu, dev, NULL, dev_name(dev));
+	if (err)
+		goto err_unprepare_clocks;
+
 	iommu_device_set_ops(&iommu->iommu, &rk_iommu_ops);
 	err = iommu_device_register(&iommu->iommu);
 	if (err)
-		iommu_device_sysfs_remove(&iommu->iommu);
+		goto err_remove_sysfs;
 
+	return 0;
+err_remove_sysfs:
+	iommu_device_sysfs_remove(&iommu->iommu);
+err_unprepare_clocks:
+	clk_bulk_unprepare(iommu->num_clocks, iommu->clocks);
 	return err;
 }
 
-- 
2.11.0

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

* [PATCH v8 09/14] dt-bindings: iommu/rockchip: Add clock property
  2018-03-23  7:38 [PATCH v8 00/14] iommu/rockchip: Use OF_IOMMU Jeffy Chen
                   ` (7 preceding siblings ...)
  2018-03-23  7:38 ` [PATCH v8 08/14] iommu/rockchip: Control clocks needed to access the IOMMU Jeffy Chen
@ 2018-03-23  7:38 ` Jeffy Chen
  2018-03-25 23:52   ` Rob Herring
  2018-03-23  7:38 ` [PATCH v8 10/14] iommu/rockchip: Use IOMMU device for dma mapping operations Jeffy Chen
                   ` (5 subsequent siblings)
  14 siblings, 1 reply; 27+ messages in thread
From: Jeffy Chen @ 2018-03-23  7:38 UTC (permalink / raw)
  To: linux-kernel
  Cc: jcliang, robin.murphy, xxm, tfiga, Jeffy Chen, devicetree,
	Heiko Stuebner, linux-rockchip, iommu, Rob Herring, Mark Rutland,
	Joerg Roedel, linux-arm-kernel

Add clock property, since we are going to control clocks in rockchip
iommu driver.

Signed-off-by: Jeffy Chen <jeffy.chen@rock-chips.com>
Reviewed-by: Robin Murphy <robin.murphy@arm.com>
---

Changes in v8: None
Changes in v7: None
Changes in v6: None
Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2: None

 Documentation/devicetree/bindings/iommu/rockchip,iommu.txt | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/Documentation/devicetree/bindings/iommu/rockchip,iommu.txt b/Documentation/devicetree/bindings/iommu/rockchip,iommu.txt
index 2098f7732264..6ecefea1c6f9 100644
--- a/Documentation/devicetree/bindings/iommu/rockchip,iommu.txt
+++ b/Documentation/devicetree/bindings/iommu/rockchip,iommu.txt
@@ -14,6 +14,11 @@ Required properties:
                     "single-master" device, and needs no additional information
                     to associate with its master device.  See:
                     Documentation/devicetree/bindings/iommu/iommu.txt
+- clocks          : A list of clocks required for the IOMMU to be accessible by
+                    the host CPU.
+- clock-names     : Should contain the following:
+	"iface" - Main peripheral bus clock (PCLK/HCL) (required)
+	"aclk"  - AXI bus clock (required)
 
 Optional properties:
 - rockchip,disable-mmu-reset : Don't use the mmu reset operation.
@@ -27,5 +32,7 @@ Example:
 		reg = <0xff940300 0x100>;
 		interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
 		interrupt-names = "vopl_mmu";
+		clocks = <&cru ACLK_VOP1>, <&cru HCLK_VOP1>;
+		clock-names = "aclk", "iface";
 		#iommu-cells = <0>;
 	};
-- 
2.11.0

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

* [PATCH v8 10/14] iommu/rockchip: Use IOMMU device for dma mapping operations
  2018-03-23  7:38 [PATCH v8 00/14] iommu/rockchip: Use OF_IOMMU Jeffy Chen
                   ` (8 preceding siblings ...)
  2018-03-23  7:38 ` [PATCH v8 09/14] dt-bindings: iommu/rockchip: Add clock property Jeffy Chen
@ 2018-03-23  7:38 ` Jeffy Chen
  2018-03-23  7:38 ` [PATCH v8 11/14] iommu/rockchip: Use OF_IOMMU to attach devices automatically Jeffy Chen
                   ` (4 subsequent siblings)
  14 siblings, 0 replies; 27+ messages in thread
From: Jeffy Chen @ 2018-03-23  7:38 UTC (permalink / raw)
  To: linux-kernel
  Cc: jcliang, robin.murphy, xxm, tfiga, Jeffy Chen, Heiko Stuebner,
	linux-rockchip, iommu, Joerg Roedel, linux-arm-kernel

Use the first registered IOMMU device for dma mapping operations, and
drop the domain platform device.

This is similar to exynos iommu driver.

Signed-off-by: Jeffy Chen <jeffy.chen@rock-chips.com>
Reviewed-by: Tomasz Figa <tfiga@chromium.org>
Reviewed-by: Robin Murphy <robin.murphy@arm.com>
---

Changes in v8: None
Changes in v7: None
Changes in v6: None
Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2: None

 drivers/iommu/rockchip-iommu.c | 85 ++++++++++++------------------------------
 1 file changed, 24 insertions(+), 61 deletions(-)

diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c
index 50ab9fd4eeb0..7970d21b9858 100644
--- a/drivers/iommu/rockchip-iommu.c
+++ b/drivers/iommu/rockchip-iommu.c
@@ -79,7 +79,6 @@
 
 struct rk_iommu_domain {
 	struct list_head iommus;
-	struct platform_device *pdev;
 	u32 *dt; /* page directory table */
 	dma_addr_t dt_dma;
 	spinlock_t iommus_lock; /* lock for iommus list */
@@ -105,12 +104,14 @@ struct rk_iommu {
 	struct iommu_domain *domain; /* domain to which iommu is attached */
 };
 
+static struct device *dma_dev;
+
 static inline void rk_table_flush(struct rk_iommu_domain *dom, dma_addr_t dma,
 				  unsigned int count)
 {
 	size_t size = count * sizeof(u32); /* count of u32 entry */
 
-	dma_sync_single_for_device(&dom->pdev->dev, dma, size, DMA_TO_DEVICE);
+	dma_sync_single_for_device(dma_dev, dma, size, DMA_TO_DEVICE);
 }
 
 static struct rk_iommu_domain *to_rk_domain(struct iommu_domain *dom)
@@ -625,7 +626,6 @@ static void rk_iommu_zap_iova_first_last(struct rk_iommu_domain *rk_domain,
 static u32 *rk_dte_get_page_table(struct rk_iommu_domain *rk_domain,
 				  dma_addr_t iova)
 {
-	struct device *dev = &rk_domain->pdev->dev;
 	u32 *page_table, *dte_addr;
 	u32 dte_index, dte;
 	phys_addr_t pt_phys;
@@ -643,9 +643,9 @@ static u32 *rk_dte_get_page_table(struct rk_iommu_domain *rk_domain,
 	if (!page_table)
 		return ERR_PTR(-ENOMEM);
 
-	pt_dma = dma_map_single(dev, page_table, SPAGE_SIZE, DMA_TO_DEVICE);
-	if (dma_mapping_error(dev, pt_dma)) {
-		dev_err(dev, "DMA mapping error while allocating page table\n");
+	pt_dma = dma_map_single(dma_dev, page_table, SPAGE_SIZE, DMA_TO_DEVICE);
+	if (dma_mapping_error(dma_dev, pt_dma)) {
+		dev_err(dma_dev, "DMA mapping error while allocating page table\n");
 		free_page((unsigned long)page_table);
 		return ERR_PTR(-ENOMEM);
 	}
@@ -911,29 +911,20 @@ static void rk_iommu_detach_device(struct iommu_domain *domain,
 static struct iommu_domain *rk_iommu_domain_alloc(unsigned type)
 {
 	struct rk_iommu_domain *rk_domain;
-	struct platform_device *pdev;
-	struct device *iommu_dev;
 
 	if (type != IOMMU_DOMAIN_UNMANAGED && type != IOMMU_DOMAIN_DMA)
 		return NULL;
 
-	/* Register a pdev per domain, so DMA API can base on this *dev
-	 * even some virtual master doesn't have an iommu slave
-	 */
-	pdev = platform_device_register_simple("rk_iommu_domain",
-					       PLATFORM_DEVID_AUTO, NULL, 0);
-	if (IS_ERR(pdev))
+	if (!dma_dev)
 		return NULL;
 
-	rk_domain = devm_kzalloc(&pdev->dev, sizeof(*rk_domain), GFP_KERNEL);
+	rk_domain = devm_kzalloc(dma_dev, sizeof(*rk_domain), GFP_KERNEL);
 	if (!rk_domain)
-		goto err_unreg_pdev;
-
-	rk_domain->pdev = pdev;
+		return NULL;
 
 	if (type == IOMMU_DOMAIN_DMA &&
 	    iommu_get_dma_cookie(&rk_domain->domain))
-		goto err_unreg_pdev;
+		return NULL;
 
 	/*
 	 * rk32xx iommus use a 2 level pagetable.
@@ -944,11 +935,10 @@ static struct iommu_domain *rk_iommu_domain_alloc(unsigned type)
 	if (!rk_domain->dt)
 		goto err_put_cookie;
 
-	iommu_dev = &pdev->dev;
-	rk_domain->dt_dma = dma_map_single(iommu_dev, rk_domain->dt,
+	rk_domain->dt_dma = dma_map_single(dma_dev, rk_domain->dt,
 					   SPAGE_SIZE, DMA_TO_DEVICE);
-	if (dma_mapping_error(iommu_dev, rk_domain->dt_dma)) {
-		dev_err(iommu_dev, "DMA map error for DT\n");
+	if (dma_mapping_error(dma_dev, rk_domain->dt_dma)) {
+		dev_err(dma_dev, "DMA map error for DT\n");
 		goto err_free_dt;
 	}
 
@@ -969,8 +959,6 @@ static struct iommu_domain *rk_iommu_domain_alloc(unsigned type)
 err_put_cookie:
 	if (type == IOMMU_DOMAIN_DMA)
 		iommu_put_dma_cookie(&rk_domain->domain);
-err_unreg_pdev:
-	platform_device_unregister(pdev);
 
 	return NULL;
 }
@@ -987,20 +975,18 @@ static void rk_iommu_domain_free(struct iommu_domain *domain)
 		if (rk_dte_is_pt_valid(dte)) {
 			phys_addr_t pt_phys = rk_dte_pt_address(dte);
 			u32 *page_table = phys_to_virt(pt_phys);
-			dma_unmap_single(&rk_domain->pdev->dev, pt_phys,
+			dma_unmap_single(dma_dev, pt_phys,
 					 SPAGE_SIZE, DMA_TO_DEVICE);
 			free_page((unsigned long)page_table);
 		}
 	}
 
-	dma_unmap_single(&rk_domain->pdev->dev, rk_domain->dt_dma,
+	dma_unmap_single(dma_dev, rk_domain->dt_dma,
 			 SPAGE_SIZE, DMA_TO_DEVICE);
 	free_page((unsigned long)rk_domain->dt);
 
 	if (domain->type == IOMMU_DOMAIN_DMA)
 		iommu_put_dma_cookie(&rk_domain->domain);
-
-	platform_device_unregister(rk_domain->pdev);
 }
 
 static bool rk_iommu_is_dev_iommu_master(struct device *dev)
@@ -1123,30 +1109,6 @@ static const struct iommu_ops rk_iommu_ops = {
 	.pgsize_bitmap = RK_IOMMU_PGSIZE_BITMAP,
 };
 
-static int rk_iommu_domain_probe(struct platform_device *pdev)
-{
-	struct device *dev = &pdev->dev;
-
-	dev->dma_parms = devm_kzalloc(dev, sizeof(*dev->dma_parms), GFP_KERNEL);
-	if (!dev->dma_parms)
-		return -ENOMEM;
-
-	/* Set dma_ops for dev, otherwise it would be dummy_dma_ops */
-	arch_setup_dma_ops(dev, 0, DMA_BIT_MASK(32), NULL, false);
-
-	dma_set_max_seg_size(dev, DMA_BIT_MASK(32));
-	dma_coerce_mask_and_coherent(dev, DMA_BIT_MASK(32));
-
-	return 0;
-}
-
-static struct platform_driver rk_iommu_domain_driver = {
-	.probe = rk_iommu_domain_probe,
-	.driver = {
-		   .name = "rk_iommu_domain",
-	},
-};
-
 static int rk_iommu_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
@@ -1220,6 +1182,14 @@ static int rk_iommu_probe(struct platform_device *pdev)
 	if (err)
 		goto err_remove_sysfs;
 
+	/*
+	 * Use the first registered IOMMU device for domain to use with DMA
+	 * API, since a domain might not physically correspond to a single
+	 * IOMMU device..
+	 */
+	if (!dma_dev)
+		dma_dev = &pdev->dev;
+
 	return 0;
 err_remove_sysfs:
 	iommu_device_sysfs_remove(&iommu->iommu);
@@ -1276,14 +1246,7 @@ static int __init rk_iommu_init(void)
 	if (ret)
 		return ret;
 
-	ret = platform_driver_register(&rk_iommu_domain_driver);
-	if (ret)
-		return ret;
-
-	ret = platform_driver_register(&rk_iommu_driver);
-	if (ret)
-		platform_driver_unregister(&rk_iommu_domain_driver);
-	return ret;
+	return platform_driver_register(&rk_iommu_driver);
 }
 subsys_initcall(rk_iommu_init);
 
-- 
2.11.0

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

* [PATCH v8 11/14] iommu/rockchip: Use OF_IOMMU to attach devices automatically
  2018-03-23  7:38 [PATCH v8 00/14] iommu/rockchip: Use OF_IOMMU Jeffy Chen
                   ` (9 preceding siblings ...)
  2018-03-23  7:38 ` [PATCH v8 10/14] iommu/rockchip: Use IOMMU device for dma mapping operations Jeffy Chen
@ 2018-03-23  7:38 ` Jeffy Chen
  2018-03-26  6:31   ` Daniel Kurtz
  2018-03-23  7:38 ` [PATCH v8 12/14] iommu/rockchip: Fix error handling in init Jeffy Chen
                   ` (3 subsequent siblings)
  14 siblings, 1 reply; 27+ messages in thread
From: Jeffy Chen @ 2018-03-23  7:38 UTC (permalink / raw)
  To: linux-kernel
  Cc: jcliang, robin.murphy, xxm, tfiga, Jeffy Chen, Heiko Stuebner,
	linux-rockchip, iommu, Joerg Roedel, linux-arm-kernel

Converts the rockchip-iommu driver to use the OF_IOMMU infrastructure,
which allows attaching master devices to their IOMMUs automatically
according to DT properties.

Signed-off-by: Jeffy Chen <jeffy.chen@rock-chips.com>
Reviewed-by: Robin Murphy <robin.murphy@arm.com>
---

Changes in v8: None
Changes in v7: None
Changes in v6: None
Changes in v5: None
Changes in v4: None
Changes in v3:
Add struct rk_iommudata.
Squash iommu/rockchip: Use iommu_group_get_for_dev() for add_device

Changes in v2: None

 drivers/iommu/rockchip-iommu.c | 135 ++++++++++++-----------------------------
 1 file changed, 40 insertions(+), 95 deletions(-)

diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c
index 7970d21b9858..bd8580b897e9 100644
--- a/drivers/iommu/rockchip-iommu.c
+++ b/drivers/iommu/rockchip-iommu.c
@@ -19,6 +19,7 @@
 #include <linux/mm.h>
 #include <linux/module.h>
 #include <linux/of.h>
+#include <linux/of_iommu.h>
 #include <linux/of_platform.h>
 #include <linux/platform_device.h>
 #include <linux/slab.h>
@@ -104,6 +105,10 @@ struct rk_iommu {
 	struct iommu_domain *domain; /* domain to which iommu is attached */
 };
 
+struct rk_iommudata {
+	struct rk_iommu *iommu;
+};
+
 static struct device *dma_dev;
 
 static inline void rk_table_flush(struct rk_iommu_domain *dom, dma_addr_t dma,
@@ -807,18 +812,9 @@ static size_t rk_iommu_unmap(struct iommu_domain *domain, unsigned long _iova,
 
 static struct rk_iommu *rk_iommu_from_dev(struct device *dev)
 {
-	struct iommu_group *group;
-	struct device *iommu_dev;
-	struct rk_iommu *rk_iommu;
+	struct rk_iommudata *data = dev->archdata.iommu;
 
-	group = iommu_group_get(dev);
-	if (!group)
-		return NULL;
-	iommu_dev = iommu_group_get_iommudata(group);
-	rk_iommu = dev_get_drvdata(iommu_dev);
-	iommu_group_put(group);
-
-	return rk_iommu;
+	return data ? data->iommu : NULL;
 }
 
 static int rk_iommu_attach_device(struct iommu_domain *domain,
@@ -989,110 +985,53 @@ static void rk_iommu_domain_free(struct iommu_domain *domain)
 		iommu_put_dma_cookie(&rk_domain->domain);
 }
 
-static bool rk_iommu_is_dev_iommu_master(struct device *dev)
-{
-	struct device_node *np = dev->of_node;
-	int ret;
-
-	/*
-	 * An iommu master has an iommus property containing a list of phandles
-	 * to iommu nodes, each with an #iommu-cells property with value 0.
-	 */
-	ret = of_count_phandle_with_args(np, "iommus", "#iommu-cells");
-	return (ret > 0);
-}
-
-static int rk_iommu_group_set_iommudata(struct iommu_group *group,
-					struct device *dev)
+static int rk_iommu_add_device(struct device *dev)
 {
-	struct device_node *np = dev->of_node;
-	struct platform_device *pd;
-	int ret;
-	struct of_phandle_args args;
+	struct iommu_group *group;
+	struct rk_iommu *iommu;
 
-	/*
-	 * An iommu master has an iommus property containing a list of phandles
-	 * to iommu nodes, each with an #iommu-cells property with value 0.
-	 */
-	ret = of_parse_phandle_with_args(np, "iommus", "#iommu-cells", 0,
-					 &args);
-	if (ret) {
-		dev_err(dev, "of_parse_phandle_with_args(%pOF) => %d\n",
-			np, ret);
-		return ret;
-	}
-	if (args.args_count != 0) {
-		dev_err(dev, "incorrect number of iommu params found for %pOF (found %d, expected 0)\n",
-			args.np, args.args_count);
-		return -EINVAL;
-	}
+	iommu = rk_iommu_from_dev(dev);
+	if (!iommu)
+		return -ENODEV;
 
-	pd = of_find_device_by_node(args.np);
-	of_node_put(args.np);
-	if (!pd) {
-		dev_err(dev, "iommu %pOF not found\n", args.np);
-		return -EPROBE_DEFER;
-	}
+	group = iommu_group_get_for_dev(dev);
+	if (IS_ERR(group))
+		return PTR_ERR(group);
+	iommu_group_put(group);
 
-	/* TODO(djkurtz): handle multiple slave iommus for a single master */
-	iommu_group_set_iommudata(group, &pd->dev, NULL);
+	iommu_device_link(&iommu->iommu, dev);
 
 	return 0;
 }
 
-static int rk_iommu_add_device(struct device *dev)
+static void rk_iommu_remove_device(struct device *dev)
 {
-	struct iommu_group *group;
 	struct rk_iommu *iommu;
-	int ret;
-
-	if (!rk_iommu_is_dev_iommu_master(dev))
-		return -ENODEV;
-
-	group = iommu_group_get(dev);
-	if (!group) {
-		group = iommu_group_alloc();
-		if (IS_ERR(group)) {
-			dev_err(dev, "Failed to allocate IOMMU group\n");
-			return PTR_ERR(group);
-		}
-	}
-
-	ret = iommu_group_add_device(group, dev);
-	if (ret)
-		goto err_put_group;
-
-	ret = rk_iommu_group_set_iommudata(group, dev);
-	if (ret)
-		goto err_remove_device;
 
 	iommu = rk_iommu_from_dev(dev);
-	if (iommu)
-		iommu_device_link(&iommu->iommu, dev);
 
-	iommu_group_put(group);
-
-	return 0;
-
-err_remove_device:
+	iommu_device_unlink(&iommu->iommu, dev);
 	iommu_group_remove_device(dev);
-err_put_group:
-	iommu_group_put(group);
-	return ret;
 }
 
-static void rk_iommu_remove_device(struct device *dev)
+static int rk_iommu_of_xlate(struct device *dev,
+			     struct of_phandle_args *args)
 {
-	struct rk_iommu *iommu;
+	struct platform_device *iommu_dev;
+	struct rk_iommudata *data;
 
-	if (!rk_iommu_is_dev_iommu_master(dev))
-		return;
+	data = devm_kzalloc(dma_dev, sizeof(*data), GFP_KERNEL);
+	if (!data)
+		return -ENOMEM;
 
-	iommu = rk_iommu_from_dev(dev);
-	if (iommu)
-		iommu_device_unlink(&iommu->iommu, dev);
+	iommu_dev = of_find_device_by_node(args->np);
 
-	iommu_group_remove_device(dev);
+	data->iommu = platform_get_drvdata(iommu_dev);
+	dev->archdata.iommu = data;
+
+	of_dev_put(iommu_dev);
+
+	return 0;
 }
 
 static const struct iommu_ops rk_iommu_ops = {
@@ -1106,7 +1045,9 @@ static const struct iommu_ops rk_iommu_ops = {
 	.add_device = rk_iommu_add_device,
 	.remove_device = rk_iommu_remove_device,
 	.iova_to_phys = rk_iommu_iova_to_phys,
+	.device_group = generic_device_group,
 	.pgsize_bitmap = RK_IOMMU_PGSIZE_BITMAP,
+	.of_xlate = rk_iommu_of_xlate,
 };
 
 static int rk_iommu_probe(struct platform_device *pdev)
@@ -1178,6 +1119,8 @@ static int rk_iommu_probe(struct platform_device *pdev)
 		goto err_unprepare_clocks;
 
 	iommu_device_set_ops(&iommu->iommu, &rk_iommu_ops);
+	iommu_device_set_fwnode(&iommu->iommu, &dev->of_node->fwnode);
+
 	err = iommu_device_register(&iommu->iommu);
 	if (err)
 		goto err_remove_sysfs;
@@ -1250,6 +1193,8 @@ static int __init rk_iommu_init(void)
 }
 subsys_initcall(rk_iommu_init);
 
+IOMMU_OF_DECLARE(rk_iommu_of, "rockchip,iommu");
+
 MODULE_DESCRIPTION("IOMMU API for Rockchip");
 MODULE_AUTHOR("Simon Xue <xxm@rock-chips.com> and Daniel Kurtz <djkurtz@chromium.org>");
 MODULE_ALIAS("platform:rockchip-iommu");
-- 
2.11.0

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

* [PATCH v8 12/14] iommu/rockchip: Fix error handling in init
  2018-03-23  7:38 [PATCH v8 00/14] iommu/rockchip: Use OF_IOMMU Jeffy Chen
                   ` (10 preceding siblings ...)
  2018-03-23  7:38 ` [PATCH v8 11/14] iommu/rockchip: Use OF_IOMMU to attach devices automatically Jeffy Chen
@ 2018-03-23  7:38 ` Jeffy Chen
  2018-03-23  7:38 ` [PATCH v8 13/14] iommu/rockchip: Add runtime PM support Jeffy Chen
                   ` (2 subsequent siblings)
  14 siblings, 0 replies; 27+ messages in thread
From: Jeffy Chen @ 2018-03-23  7:38 UTC (permalink / raw)
  To: linux-kernel
  Cc: jcliang, robin.murphy, xxm, tfiga, Jeffy Chen, Heiko Stuebner,
	linux-rockchip, iommu, Joerg Roedel, linux-arm-kernel

It's hard to undo bus_set_iommu() in the error path, so move it to the
end of rk_iommu_probe().

Signed-off-by: Jeffy Chen <jeffy.chen@rock-chips.com>
Reviewed-by: Tomasz Figa <tfiga@chromium.org>
Reviewed-by: Robin Murphy <robin.murphy@arm.com>
---

Changes in v8: None
Changes in v7: None
Changes in v6: None
Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2:
Move bus_set_iommu() to rk_iommu_probe().

 drivers/iommu/rockchip-iommu.c | 15 ++-------------
 1 file changed, 2 insertions(+), 13 deletions(-)

diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c
index bd8580b897e9..0ce5e8a0658c 100644
--- a/drivers/iommu/rockchip-iommu.c
+++ b/drivers/iommu/rockchip-iommu.c
@@ -1133,6 +1133,8 @@ static int rk_iommu_probe(struct platform_device *pdev)
 	if (!dma_dev)
 		dma_dev = &pdev->dev;
 
+	bus_set_iommu(&platform_bus_type, &rk_iommu_ops);
+
 	return 0;
 err_remove_sysfs:
 	iommu_device_sysfs_remove(&iommu->iommu);
@@ -1176,19 +1178,6 @@ static struct platform_driver rk_iommu_driver = {
 
 static int __init rk_iommu_init(void)
 {
-	struct device_node *np;
-	int ret;
-
-	np = of_find_matching_node(NULL, rk_iommu_dt_ids);
-	if (!np)
-		return 0;
-
-	of_node_put(np);
-
-	ret = bus_set_iommu(&platform_bus_type, &rk_iommu_ops);
-	if (ret)
-		return ret;
-
 	return platform_driver_register(&rk_iommu_driver);
 }
 subsys_initcall(rk_iommu_init);
-- 
2.11.0

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

* [PATCH v8 13/14] iommu/rockchip: Add runtime PM support
  2018-03-23  7:38 [PATCH v8 00/14] iommu/rockchip: Use OF_IOMMU Jeffy Chen
                   ` (11 preceding siblings ...)
  2018-03-23  7:38 ` [PATCH v8 12/14] iommu/rockchip: Fix error handling in init Jeffy Chen
@ 2018-03-23  7:38 ` Jeffy Chen
  2018-03-23  7:38 ` [PATCH v8 14/14] iommu/rockchip: Support sharing IOMMU between masters Jeffy Chen
  2018-03-29 10:24 ` [PATCH v8 00/14] iommu/rockchip: Use OF_IOMMU Joerg Roedel
  14 siblings, 0 replies; 27+ messages in thread
From: Jeffy Chen @ 2018-03-23  7:38 UTC (permalink / raw)
  To: linux-kernel
  Cc: jcliang, robin.murphy, xxm, tfiga, Jeffy Chen, Heiko Stuebner,
	linux-rockchip, iommu, Joerg Roedel, linux-arm-kernel

When the power domain is powered off, the IOMMU cannot be accessed and
register programming must be deferred until the power domain becomes
enabled.

Add runtime PM support, and use runtime PM device link from IOMMU to
master to enable and disable IOMMU.

Signed-off-by: Jeffy Chen <jeffy.chen@rock-chips.com>
---

Changes in v8:
Rename startup()/shutdown() to enable()/disable().
Do runtime PM suspend in .shutdown().
Modify pm_runtime_get_if_in_use()/pm_runtime_put() as Tomasz suggested.

Changes in v7: None
Changes in v6: None
Changes in v5:
Avoid race about pm_runtime_get_if_in_use() and pm_runtime_enabled().

Changes in v4: None
Changes in v3:
Only call startup() and shutdown() when iommu attached.
Remove pm_mutex.
Check runtime PM disabled.
Check pm_runtime in rk_iommu_irq().

Changes in v2: None

 drivers/iommu/rockchip-iommu.c | 181 +++++++++++++++++++++++++++++------------
 1 file changed, 129 insertions(+), 52 deletions(-)

diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c
index 0ce5e8a0658c..9f6f74689464 100644
--- a/drivers/iommu/rockchip-iommu.c
+++ b/drivers/iommu/rockchip-iommu.c
@@ -22,6 +22,7 @@
 #include <linux/of_iommu.h>
 #include <linux/of_platform.h>
 #include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
 #include <linux/slab.h>
 #include <linux/spinlock.h>
 
@@ -106,6 +107,7 @@ struct rk_iommu {
 };
 
 struct rk_iommudata {
+	struct device_link *link; /* runtime PM link from IOMMU to master */
 	struct rk_iommu *iommu;
 };
 
@@ -520,7 +522,11 @@ static irqreturn_t rk_iommu_irq(int irq, void *dev_id)
 	irqreturn_t ret = IRQ_NONE;
 	int i;
 
-	WARN_ON(clk_bulk_enable(iommu->num_clocks, iommu->clocks));
+	if (WARN_ON(!pm_runtime_get_if_in_use(iommu->dev)))
+		return 0;
+
+	if (WARN_ON(clk_bulk_enable(iommu->num_clocks, iommu->clocks)))
+		goto out;
 
 	for (i = 0; i < iommu->num_mmu; i++) {
 		int_status = rk_iommu_read(iommu->bases[i], RK_MMU_INT_STATUS);
@@ -570,6 +576,8 @@ static irqreturn_t rk_iommu_irq(int irq, void *dev_id)
 
 	clk_bulk_disable(iommu->num_clocks, iommu->clocks);
 
+out:
+	pm_runtime_put(iommu->dev);
 	return ret;
 }
 
@@ -611,10 +619,17 @@ static void rk_iommu_zap_iova(struct rk_iommu_domain *rk_domain,
 	spin_lock_irqsave(&rk_domain->iommus_lock, flags);
 	list_for_each(pos, &rk_domain->iommus) {
 		struct rk_iommu *iommu;
+
 		iommu = list_entry(pos, struct rk_iommu, node);
-		WARN_ON(clk_bulk_enable(iommu->num_clocks, iommu->clocks));
-		rk_iommu_zap_lines(iommu, iova, size);
-		clk_bulk_disable(iommu->num_clocks, iommu->clocks);
+
+		/* Only zap TLBs of IOMMUs that are powered on. */
+		if (pm_runtime_get_if_in_use(iommu->dev)) {
+			WARN_ON(clk_bulk_enable(iommu->num_clocks,
+						iommu->clocks));
+			rk_iommu_zap_lines(iommu, iova, size);
+			clk_bulk_disable(iommu->num_clocks, iommu->clocks);
+			pm_runtime_put(iommu->dev);
+		}
 	}
 	spin_unlock_irqrestore(&rk_domain->iommus_lock, flags);
 }
@@ -817,22 +832,30 @@ static struct rk_iommu *rk_iommu_from_dev(struct device *dev)
 	return data ? data->iommu : NULL;
 }
 
-static int rk_iommu_attach_device(struct iommu_domain *domain,
-				  struct device *dev)
+/* Must be called with iommu powered on and attached */
+static void rk_iommu_disable(struct rk_iommu *iommu)
 {
-	struct rk_iommu *iommu;
+	int i;
+
+	/* Ignore error while disabling, just keep going */
+	WARN_ON(clk_bulk_enable(iommu->num_clocks, iommu->clocks));
+	rk_iommu_enable_stall(iommu);
+	rk_iommu_disable_paging(iommu);
+	for (i = 0; i < iommu->num_mmu; i++) {
+		rk_iommu_write(iommu->bases[i], RK_MMU_INT_MASK, 0);
+		rk_iommu_write(iommu->bases[i], RK_MMU_DTE_ADDR, 0);
+	}
+	rk_iommu_disable_stall(iommu);
+	clk_bulk_disable(iommu->num_clocks, iommu->clocks);
+}
+
+/* Must be called with iommu powered on and attached */
+static int rk_iommu_enable(struct rk_iommu *iommu)
+{
+	struct iommu_domain *domain = iommu->domain;
 	struct rk_iommu_domain *rk_domain = to_rk_domain(domain);
-	unsigned long flags;
 	int ret, i;
 
-	/*
-	 * Allow 'virtual devices' (e.g., drm) to attach to domain.
-	 * Such a device does not belong to an iommu group.
-	 */
-	iommu = rk_iommu_from_dev(dev);
-	if (!iommu)
-		return 0;
-
 	ret = clk_bulk_enable(iommu->num_clocks, iommu->clocks);
 	if (ret)
 		return ret;
@@ -845,8 +868,6 @@ static int rk_iommu_attach_device(struct iommu_domain *domain,
 	if (ret)
 		goto out_disable_stall;
 
-	iommu->domain = domain;
-
 	for (i = 0; i < iommu->num_mmu; i++) {
 		rk_iommu_write(iommu->bases[i], RK_MMU_DTE_ADDR,
 			       rk_domain->dt_dma);
@@ -855,14 +876,6 @@ static int rk_iommu_attach_device(struct iommu_domain *domain,
 	}
 
 	ret = rk_iommu_enable_paging(iommu);
-	if (ret)
-		goto out_disable_stall;
-
-	spin_lock_irqsave(&rk_domain->iommus_lock, flags);
-	list_add_tail(&iommu->node, &rk_domain->iommus);
-	spin_unlock_irqrestore(&rk_domain->iommus_lock, flags);
-
-	dev_dbg(dev, "Attached to iommu domain\n");
 
 out_disable_stall:
 	rk_iommu_disable_stall(iommu);
@@ -877,31 +890,71 @@ static void rk_iommu_detach_device(struct iommu_domain *domain,
 	struct rk_iommu *iommu;
 	struct rk_iommu_domain *rk_domain = to_rk_domain(domain);
 	unsigned long flags;
-	int i;
 
 	/* Allow 'virtual devices' (eg drm) to detach from domain */
 	iommu = rk_iommu_from_dev(dev);
 	if (!iommu)
 		return;
 
+	dev_dbg(dev, "Detaching from iommu domain\n");
+
+	/* iommu already detached */
+	if (iommu->domain != domain)
+		return;
+
+	iommu->domain = NULL;
+
 	spin_lock_irqsave(&rk_domain->iommus_lock, flags);
 	list_del_init(&iommu->node);
 	spin_unlock_irqrestore(&rk_domain->iommus_lock, flags);
 
-	/* Ignore error while disabling, just keep going */
-	WARN_ON(clk_bulk_enable(iommu->num_clocks, iommu->clocks));
-	rk_iommu_enable_stall(iommu);
-	rk_iommu_disable_paging(iommu);
-	for (i = 0; i < iommu->num_mmu; i++) {
-		rk_iommu_write(iommu->bases[i], RK_MMU_INT_MASK, 0);
-		rk_iommu_write(iommu->bases[i], RK_MMU_DTE_ADDR, 0);
+	if (pm_runtime_get_if_in_use(iommu->dev)) {
+		rk_iommu_disable(iommu);
+		pm_runtime_put(iommu->dev);
 	}
-	rk_iommu_disable_stall(iommu);
-	clk_bulk_disable(iommu->num_clocks, iommu->clocks);
+}
 
-	iommu->domain = NULL;
+static int rk_iommu_attach_device(struct iommu_domain *domain,
+		struct device *dev)
+{
+	struct rk_iommu *iommu;
+	struct rk_iommu_domain *rk_domain = to_rk_domain(domain);
+	unsigned long flags;
+	int ret;
 
-	dev_dbg(dev, "Detached from iommu domain\n");
+	/*
+	 * Allow 'virtual devices' (e.g., drm) to attach to domain.
+	 * Such a device does not belong to an iommu group.
+	 */
+	iommu = rk_iommu_from_dev(dev);
+	if (!iommu)
+		return 0;
+
+	dev_dbg(dev, "Attaching to iommu domain\n");
+
+	/* iommu already attached */
+	if (iommu->domain == domain)
+		return 0;
+
+	if (iommu->domain)
+		rk_iommu_detach_device(iommu->domain, dev);
+
+	iommu->domain = domain;
+
+	spin_lock_irqsave(&rk_domain->iommus_lock, flags);
+	list_add_tail(&iommu->node, &rk_domain->iommus);
+	spin_unlock_irqrestore(&rk_domain->iommus_lock, flags);
+
+	if (!pm_runtime_get_if_in_use(iommu->dev))
+		return 0;
+
+	ret = rk_iommu_enable(iommu);
+	if (ret)
+		rk_iommu_detach_device(iommu->domain, dev);
+
+	pm_runtime_put(iommu->dev);
+
+	return ret;
 }
 
 static struct iommu_domain *rk_iommu_domain_alloc(unsigned type)
@@ -989,17 +1042,21 @@ static int rk_iommu_add_device(struct device *dev)
 {
 	struct iommu_group *group;
 	struct rk_iommu *iommu;
+	struct rk_iommudata *data;
 
-	iommu = rk_iommu_from_dev(dev);
-	if (!iommu)
+	data = dev->archdata.iommu;
+	if (!data)
 		return -ENODEV;
 
+	iommu = rk_iommu_from_dev(dev);
+
 	group = iommu_group_get_for_dev(dev);
 	if (IS_ERR(group))
 		return PTR_ERR(group);
 	iommu_group_put(group);
 
 	iommu_device_link(&iommu->iommu, dev);
+	data->link = device_link_add(dev, iommu->dev, DL_FLAG_PM_RUNTIME);
 
 	return 0;
 }
@@ -1007,9 +1064,11 @@ static int rk_iommu_add_device(struct device *dev)
 static void rk_iommu_remove_device(struct device *dev)
 {
 	struct rk_iommu *iommu;
+	struct rk_iommudata *data = dev->archdata.iommu;
 
 	iommu = rk_iommu_from_dev(dev);
 
+	device_link_del(data->link);
 	iommu_device_unlink(&iommu->iommu, dev);
 	iommu_group_remove_device(dev);
 }
@@ -1135,6 +1194,8 @@ static int rk_iommu_probe(struct platform_device *pdev)
 
 	bus_set_iommu(&platform_bus_type, &rk_iommu_ops);
 
+	pm_runtime_enable(dev);
+
 	return 0;
 err_remove_sysfs:
 	iommu_device_sysfs_remove(&iommu->iommu);
@@ -1145,21 +1206,36 @@ static int rk_iommu_probe(struct platform_device *pdev)
 
 static void rk_iommu_shutdown(struct platform_device *pdev)
 {
-	struct rk_iommu *iommu = platform_get_drvdata(pdev);
+	pm_runtime_force_suspend(&pdev->dev);
+}
 
-	/*
-	 * Be careful not to try to shutdown an otherwise unused
-	 * IOMMU, as it is likely not to be clocked, and accessing it
-	 * would just block. An IOMMU without a domain is likely to be
-	 * unused, so let's use this as a (weak) guard.
-	 */
-	if (iommu && iommu->domain) {
-		rk_iommu_enable_stall(iommu);
-		rk_iommu_disable_paging(iommu);
-		rk_iommu_force_reset(iommu);
-	}
+static int __maybe_unused rk_iommu_suspend(struct device *dev)
+{
+	struct rk_iommu *iommu = dev_get_drvdata(dev);
+
+	if (!iommu->domain)
+		return 0;
+
+	rk_iommu_disable(iommu);
+	return 0;
+}
+
+static int __maybe_unused rk_iommu_resume(struct device *dev)
+{
+	struct rk_iommu *iommu = dev_get_drvdata(dev);
+
+	if (!iommu->domain)
+		return 0;
+
+	return rk_iommu_enable(iommu);
 }
 
+static const struct dev_pm_ops rk_iommu_pm_ops = {
+	SET_RUNTIME_PM_OPS(rk_iommu_suspend, rk_iommu_resume, NULL)
+	SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
+				pm_runtime_force_resume)
+};
+
 static const struct of_device_id rk_iommu_dt_ids[] = {
 	{ .compatible = "rockchip,iommu" },
 	{ /* sentinel */ }
@@ -1172,6 +1248,7 @@ static struct platform_driver rk_iommu_driver = {
 	.driver = {
 		   .name = "rk_iommu",
 		   .of_match_table = rk_iommu_dt_ids,
+		   .pm = &rk_iommu_pm_ops,
 		   .suppress_bind_attrs = true,
 	},
 };
-- 
2.11.0

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

* [PATCH v8 14/14] iommu/rockchip: Support sharing IOMMU between masters
  2018-03-23  7:38 [PATCH v8 00/14] iommu/rockchip: Use OF_IOMMU Jeffy Chen
                   ` (12 preceding siblings ...)
  2018-03-23  7:38 ` [PATCH v8 13/14] iommu/rockchip: Add runtime PM support Jeffy Chen
@ 2018-03-23  7:38 ` Jeffy Chen
  2018-03-29 10:24 ` [PATCH v8 00/14] iommu/rockchip: Use OF_IOMMU Joerg Roedel
  14 siblings, 0 replies; 27+ messages in thread
From: Jeffy Chen @ 2018-03-23  7:38 UTC (permalink / raw)
  To: linux-kernel
  Cc: jcliang, robin.murphy, xxm, tfiga, Jeffy Chen, Heiko Stuebner,
	linux-rockchip, iommu, Joerg Roedel, linux-arm-kernel

There would be some masters sharing the same IOMMU device. Put them in
the same iommu group and share the same iommu domain.

Signed-off-by: Jeffy Chen <jeffy.chen@rock-chips.com>
Reviewed-by: Robin Murphy <robin.murphy@arm.com>
---

Changes in v8: None
Changes in v7:
Use iommu_group_ref_get to avoid ref leak

Changes in v6: None
Changes in v5: None
Changes in v4: None
Changes in v3:
Remove rk_iommudata->domain.

Changes in v2: None

 drivers/iommu/rockchip-iommu.c | 22 ++++++++++++++++++++--
 1 file changed, 20 insertions(+), 2 deletions(-)

diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c
index 9f6f74689464..5fc8656c60f9 100644
--- a/drivers/iommu/rockchip-iommu.c
+++ b/drivers/iommu/rockchip-iommu.c
@@ -104,6 +104,7 @@ struct rk_iommu {
 	struct iommu_device iommu;
 	struct list_head node; /* entry in rk_iommu_domain.iommus */
 	struct iommu_domain *domain; /* domain to which iommu is attached */
+	struct iommu_group *group;
 };
 
 struct rk_iommudata {
@@ -1073,6 +1074,15 @@ static void rk_iommu_remove_device(struct device *dev)
 	iommu_group_remove_device(dev);
 }
 
+static struct iommu_group *rk_iommu_device_group(struct device *dev)
+{
+	struct rk_iommu *iommu;
+
+	iommu = rk_iommu_from_dev(dev);
+
+	return iommu_group_ref_get(iommu->group);
+}
+
 static int rk_iommu_of_xlate(struct device *dev,
 			     struct of_phandle_args *args)
 {
@@ -1104,7 +1114,7 @@ static const struct iommu_ops rk_iommu_ops = {
 	.add_device = rk_iommu_add_device,
 	.remove_device = rk_iommu_remove_device,
 	.iova_to_phys = rk_iommu_iova_to_phys,
-	.device_group = generic_device_group,
+	.device_group = rk_iommu_device_group,
 	.pgsize_bitmap = RK_IOMMU_PGSIZE_BITMAP,
 	.of_xlate = rk_iommu_of_xlate,
 };
@@ -1173,9 +1183,15 @@ static int rk_iommu_probe(struct platform_device *pdev)
 	if (err)
 		return err;
 
+	iommu->group = iommu_group_alloc();
+	if (IS_ERR(iommu->group)) {
+		err = PTR_ERR(iommu->group);
+		goto err_unprepare_clocks;
+	}
+
 	err = iommu_device_sysfs_add(&iommu->iommu, dev, NULL, dev_name(dev));
 	if (err)
-		goto err_unprepare_clocks;
+		goto err_put_group;
 
 	iommu_device_set_ops(&iommu->iommu, &rk_iommu_ops);
 	iommu_device_set_fwnode(&iommu->iommu, &dev->of_node->fwnode);
@@ -1199,6 +1215,8 @@ static int rk_iommu_probe(struct platform_device *pdev)
 	return 0;
 err_remove_sysfs:
 	iommu_device_sysfs_remove(&iommu->iommu);
+err_put_group:
+	iommu_group_put(iommu->group);
 err_unprepare_clocks:
 	clk_bulk_unprepare(iommu->num_clocks, iommu->clocks);
 	return err;
-- 
2.11.0

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

* Re: [PATCH v8 09/14] dt-bindings: iommu/rockchip: Add clock property
  2018-03-23  7:38 ` [PATCH v8 09/14] dt-bindings: iommu/rockchip: Add clock property Jeffy Chen
@ 2018-03-25 23:52   ` Rob Herring
  0 siblings, 0 replies; 27+ messages in thread
From: Rob Herring @ 2018-03-25 23:52 UTC (permalink / raw)
  To: Jeffy Chen
  Cc: linux-kernel, jcliang, robin.murphy, xxm, tfiga, devicetree,
	Heiko Stuebner, linux-rockchip, iommu, Mark Rutland,
	Joerg Roedel, linux-arm-kernel

On Fri, Mar 23, 2018 at 03:38:09PM +0800, Jeffy Chen wrote:
> Add clock property, since we are going to control clocks in rockchip
> iommu driver.
> 
> Signed-off-by: Jeffy Chen <jeffy.chen@rock-chips.com>
> Reviewed-by: Robin Murphy <robin.murphy@arm.com>
> ---

Reviewed-by: Rob Herring <robh@kernel.org>

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

* Re: [PATCH v8 11/14] iommu/rockchip: Use OF_IOMMU to attach devices automatically
  2018-03-23  7:38 ` [PATCH v8 11/14] iommu/rockchip: Use OF_IOMMU to attach devices automatically Jeffy Chen
@ 2018-03-26  6:31   ` Daniel Kurtz
       [not found]     ` <5AB8A7F0.1090305@rock-chips.com>
  0 siblings, 1 reply; 27+ messages in thread
From: Daniel Kurtz @ 2018-03-26  6:31 UTC (permalink / raw)
  To: Jeffy
  Cc: linux-kernel, Ricky Liang, Robin Murphy, xxm, Tomasz Figa,
	Heiko Stuebner, open list:ARM/Rockchip SoC...,
	open list:IOMMU DRIVERS, Joerg Roedel, linux-arm-kernel

On Fri, Mar 23, 2018 at 1:40 AM Jeffy Chen <jeffy.chen@rock-chips.com>
wrote:

> Converts the rockchip-iommu driver to use the OF_IOMMU infrastructure,
> which allows attaching master devices to their IOMMUs automatically
> according to DT properties.

> Signed-off-by: Jeffy Chen <jeffy.chen@rock-chips.com>
> Reviewed-by: Robin Murphy <robin.murphy@arm.com>
> ---

> Changes in v8: None
> Changes in v7: None
> Changes in v6: None
> Changes in v5: None
> Changes in v4: None
> Changes in v3:
> Add struct rk_iommudata.
> Squash iommu/rockchip: Use iommu_group_get_for_dev() for add_device

> Changes in v2: None

>   drivers/iommu/rockchip-iommu.c | 135
++++++++++++-----------------------------
>   1 file changed, 40 insertions(+), 95 deletions(-)

> diff --git a/drivers/iommu/rockchip-iommu.c
b/drivers/iommu/rockchip-iommu.c
> index 7970d21b9858..bd8580b897e9 100644
> --- a/drivers/iommu/rockchip-iommu.c
> +++ b/drivers/iommu/rockchip-iommu.c
> @@ -19,6 +19,7 @@
>   #include <linux/mm.h>
>   #include <linux/module.h>
>   #include <linux/of.h>
> +#include <linux/of_iommu.h>
>   #include <linux/of_platform.h>
>   #include <linux/platform_device.h>
>   #include <linux/slab.h>
> @@ -104,6 +105,10 @@ struct rk_iommu {
>          struct iommu_domain *domain; /* domain to which iommu is attached
*/
>   };

> +struct rk_iommudata {
> +       struct rk_iommu *iommu;
> +};

Why do we need this struct?  Can't we just assign a pointer to struct
rk_iommu directly to dev->archdata.iommu?


> +
>   static struct device *dma_dev;

>   static inline void rk_table_flush(struct rk_iommu_domain *dom,
dma_addr_t dma,
> @@ -807,18 +812,9 @@ static size_t rk_iommu_unmap(struct iommu_domain
*domain, unsigned long _iova,

>   static struct rk_iommu *rk_iommu_from_dev(struct device *dev)
>   {
> -       struct iommu_group *group;
> -       struct device *iommu_dev;
> -       struct rk_iommu *rk_iommu;
> +       struct rk_iommudata *data = dev->archdata.iommu;

> -       group = iommu_group_get(dev);
> -       if (!group)
> -               return NULL;
> -       iommu_dev = iommu_group_get_iommudata(group);
> -       rk_iommu = dev_get_drvdata(iommu_dev);
> -       iommu_group_put(group);
> -
> -       return rk_iommu;
> +       return data ? data->iommu : NULL;
>   }

>   static int rk_iommu_attach_device(struct iommu_domain *domain,
> @@ -989,110 +985,53 @@ static void rk_iommu_domain_free(struct
iommu_domain *domain)
>                  iommu_put_dma_cookie(&rk_domain->domain);
>   }

> -static bool rk_iommu_is_dev_iommu_master(struct device *dev)
> -{
> -       struct device_node *np = dev->of_node;
> -       int ret;
> -
> -       /*
> -        * An iommu master has an iommus property containing a list of
phandles
> -        * to iommu nodes, each with an #iommu-cells property with value
0.
> -        */
> -       ret = of_count_phandle_with_args(np, "iommus", "#iommu-cells");
> -       return (ret > 0);
> -}
> -
> -static int rk_iommu_group_set_iommudata(struct iommu_group *group,
> -                                       struct device *dev)
> +static int rk_iommu_add_device(struct device *dev)
>   {
> -       struct device_node *np = dev->of_node;
> -       struct platform_device *pd;
> -       int ret;
> -       struct of_phandle_args args;
> +       struct iommu_group *group;
> +       struct rk_iommu *iommu;

> -       /*
> -        * An iommu master has an iommus property containing a list of
phandles
> -        * to iommu nodes, each with an #iommu-cells property with value
0.
> -        */
> -       ret = of_parse_phandle_with_args(np, "iommus", "#iommu-cells", 0,
> -                                        &args);
> -       if (ret) {
> -               dev_err(dev, "of_parse_phandle_with_args(%pOF) => %d\n",
> -                       np, ret);
> -               return ret;
> -       }
> -       if (args.args_count != 0) {
> -               dev_err(dev, "incorrect number of iommu params found for
%pOF (found %d, expected 0)\n",
> -                       args.np, args.args_count);
> -               return -EINVAL;
> -       }
> +       iommu = rk_iommu_from_dev(dev);
> +       if (!iommu)
> +               return -ENODEV;

> -       pd = of_find_device_by_node(args.np);
> -       of_node_put(args.np);
> -       if (!pd) {
> -               dev_err(dev, "iommu %pOF not found\n", args.np);
> -               return -EPROBE_DEFER;
> -       }
> +       group = iommu_group_get_for_dev(dev);
> +       if (IS_ERR(group))
> +               return PTR_ERR(group);
> +       iommu_group_put(group);

> -       /* TODO(djkurtz): handle multiple slave iommus for a single
master */
> -       iommu_group_set_iommudata(group, &pd->dev, NULL);
> +       iommu_device_link(&iommu->iommu, dev);

>          return 0;
>   }

> -static int rk_iommu_add_device(struct device *dev)
> +static void rk_iommu_remove_device(struct device *dev)
>   {
> -       struct iommu_group *group;
>          struct rk_iommu *iommu;
> -       int ret;
> -
> -       if (!rk_iommu_is_dev_iommu_master(dev))
> -               return -ENODEV;
> -
> -       group = iommu_group_get(dev);
> -       if (!group) {
> -               group = iommu_group_alloc();
> -               if (IS_ERR(group)) {
> -                       dev_err(dev, "Failed to allocate IOMMU group\n");
> -                       return PTR_ERR(group);
> -               }
> -       }
> -
> -       ret = iommu_group_add_device(group, dev);
> -       if (ret)
> -               goto err_put_group;
> -
> -       ret = rk_iommu_group_set_iommudata(group, dev);
> -       if (ret)
> -               goto err_remove_device;

>          iommu = rk_iommu_from_dev(dev);
> -       if (iommu)
> -               iommu_device_link(&iommu->iommu, dev);

> -       iommu_group_put(group);
> -
> -       return 0;
> -
> -err_remove_device:
> +       iommu_device_unlink(&iommu->iommu, dev);
>          iommu_group_remove_device(dev);
> -err_put_group:
> -       iommu_group_put(group);
> -       return ret;
>   }

> -static void rk_iommu_remove_device(struct device *dev)
> +static int rk_iommu_of_xlate(struct device *dev,
> +                            struct of_phandle_args *args)
>   {
> -       struct rk_iommu *iommu;
> +       struct platform_device *iommu_dev;
> +       struct rk_iommudata *data;

> -       if (!rk_iommu_is_dev_iommu_master(dev))
> -               return;
> +       data = devm_kzalloc(dma_dev, sizeof(*data), GFP_KERNEL);
> +       if (!data)
> +               return -ENOMEM;

> -       iommu = rk_iommu_from_dev(dev);
> -       if (iommu)
> -               iommu_device_unlink(&iommu->iommu, dev);
> +       iommu_dev = of_find_device_by_node(args->np);

> -       iommu_group_remove_device(dev);
> +       data->iommu = platform_get_drvdata(iommu_dev);
> +       dev->archdata.iommu = data;
> +
> +       of_dev_put(iommu_dev);
> +
> +       return 0;
>   }

>   static const struct iommu_ops rk_iommu_ops = {
> @@ -1106,7 +1045,9 @@ static const struct iommu_ops rk_iommu_ops = {
>          .add_device = rk_iommu_add_device,
>          .remove_device = rk_iommu_remove_device,
>          .iova_to_phys = rk_iommu_iova_to_phys,
> +       .device_group = generic_device_group,
>          .pgsize_bitmap = RK_IOMMU_PGSIZE_BITMAP,
> +       .of_xlate = rk_iommu_of_xlate,
>   };

>   static int rk_iommu_probe(struct platform_device *pdev)
> @@ -1178,6 +1119,8 @@ static int rk_iommu_probe(struct platform_device
*pdev)
>                  goto err_unprepare_clocks;

>          iommu_device_set_ops(&iommu->iommu, &rk_iommu_ops);
> +       iommu_device_set_fwnode(&iommu->iommu, &dev->of_node->fwnode);
> +
>          err = iommu_device_register(&iommu->iommu);
>          if (err)
>                  goto err_remove_sysfs;
> @@ -1250,6 +1193,8 @@ static int __init rk_iommu_init(void)
>   }
>   subsys_initcall(rk_iommu_init);

> +IOMMU_OF_DECLARE(rk_iommu_of, "rockchip,iommu");
> +
>   MODULE_DESCRIPTION("IOMMU API for Rockchip");
>   MODULE_AUTHOR("Simon Xue <xxm@rock-chips.com> and Daniel Kurtz <
djkurtz@chromium.org>");
>   MODULE_ALIAS("platform:rockchip-iommu");
> --
> 2.11.0

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

* Re: [PATCH v8 00/14] iommu/rockchip: Use OF_IOMMU
  2018-03-23  7:38 [PATCH v8 00/14] iommu/rockchip: Use OF_IOMMU Jeffy Chen
                   ` (13 preceding siblings ...)
  2018-03-23  7:38 ` [PATCH v8 14/14] iommu/rockchip: Support sharing IOMMU between masters Jeffy Chen
@ 2018-03-29 10:24 ` Joerg Roedel
  14 siblings, 0 replies; 27+ messages in thread
From: Joerg Roedel @ 2018-03-29 10:24 UTC (permalink / raw)
  To: Jeffy Chen
  Cc: linux-kernel, jcliang, robin.murphy, xxm, tfiga, Romain Perier,
	Yakir Yang, Arnd Bergmann, Liang Chen, Rob Herring, Shawn Lin,
	Catalin Marinas, David Wu, Finley Xiao, Enric Balletbo i Serra,
	Heiko Stuebner, Jacob Chen, Kever Yang, Brian Norris,
	linux-rockchip, Rocky Hao, Will Deacon, Nickey Yang, devicetree,
	Mark Yao, Russell King, linux-arm-kernel, Sugar Zhang, iommu,
	Caesar Wang, Mark Rutland

On Fri, Mar 23, 2018 at 03:38:00PM +0800, Jeffy Chen wrote:
> 
> This series fixes some issues in rockchip iommu driver, and add of_iommu
> support in it.
> 
> Changes in v8:
> Rebase on newest for-next.
> Don't introduce the additional return.
> Rename startup()/shutdown() to enable()/disable().
> Do runtime PM suspend in .shutdown().
> Modify pm_runtime_get_if_in_use()/pm_runtime_put() as Tomasz suggested.

Applied, thanks.

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

* Re: [PATCH v8 11/14] iommu/rockchip: Use OF_IOMMU to attach devices automatically
       [not found]     ` <5AB8A7F0.1090305@rock-chips.com>
@ 2018-04-03 16:11       ` Daniel Kurtz
  2018-04-04 11:10         ` JeffyChen
  0 siblings, 1 reply; 27+ messages in thread
From: Daniel Kurtz @ 2018-04-03 16:11 UTC (permalink / raw)
  To: Jeffy
  Cc: linux-kernel, Ricky Liang, Robin Murphy, xxm, Tomasz Figa,
	Heiko Stuebner, open list:ARM/Rockchip SoC...,
	open, linux-arm-kernel

Hi Jeffy,

Sorry for delayed response.

On Mon, Mar 26, 2018 at 1:58 AM JeffyChen <jeffy.chen@rock-chips.com> wrote:

> Hi Daniel,

> Thanks for your reply.

> On 03/26/2018 02:31 PM, Daniel Kurtz wrote:
> >> >+struct rk_iommudata {
> >> >+       struct rk_iommu *iommu;
> >> >+};
> > Why do we need this struct?  Can't we just assign a pointer to struct
> > rk_iommu directly to dev->archdata.iommu?
> >
> hmmm, i was trying to add more device related data in patch[13]:

>    struct rk_iommudata {
> +       struct device_link *link; /* runtime PM link from IOMMU to master
*/
>          struct rk_iommu *iommu;
>    };
> >

Can't you just add link to rk_iommu directly?

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

* Re: [PATCH v8 11/14] iommu/rockchip: Use OF_IOMMU to attach devices automatically
  2018-04-03 16:11       ` Daniel Kurtz
@ 2018-04-04 11:10         ` JeffyChen
  0 siblings, 0 replies; 27+ messages in thread
From: JeffyChen @ 2018-04-04 11:10 UTC (permalink / raw)
  To: Daniel Kurtz
  Cc: linux-kernel, Ricky Liang, Robin Murphy, xxm, Tomasz Figa,
	Heiko Stuebner, open list:ARM/Rockchip SoC...,
	linux-arm-kernel

Hi Daniel,

Thanks for your reply.

On 04/04/2018 12:11 AM, Daniel Kurtz wrote:
> Hi Jeffy,
>
> Sorry for delayed response.
>
> On Mon, Mar 26, 2018 at 1:58 AM JeffyChen <jeffy.chen@rock-chips.com> wrote:
>
>> Hi Daniel,
>
>> Thanks for your reply.
>
>> On 03/26/2018 02:31 PM, Daniel Kurtz wrote:
>>>>> +struct rk_iommudata {
>>>>> +       struct rk_iommu *iommu;
>>>>> +};
>>> Why do we need this struct?  Can't we just assign a pointer to struct
>>> rk_iommu directly to dev->archdata.iommu?
>>>
>> hmmm, i was trying to add more device related data in patch[13]:
>
>>     struct rk_iommudata {
>> +       struct device_link *link; /* runtime PM link from IOMMU to master
> */
>>           struct rk_iommu *iommu;
>>     };
>>>
>
> Can't you just add link to rk_iommu directly?

adding link to rk_iommu would be fine if we only have one master device 
per rk_iommu.

but now we are supporting multiple master devices sharing a iommu device :)

>
>
>

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

* Re: [PATCH v8 07/14] ARM: dts: rockchip: add clocks in iommu nodes
  2018-03-23  7:38 ` [PATCH v8 07/14] ARM: dts: rockchip: add clocks in iommu nodes Jeffy Chen
@ 2018-04-09 14:41   ` Tomeu Vizoso
  2018-04-09 15:44     ` Heiko Stübner
  2018-04-10 11:46   ` Heiko Stuebner
  1 sibling, 1 reply; 27+ messages in thread
From: Tomeu Vizoso @ 2018-04-09 14:41 UTC (permalink / raw)
  To: Jeffy Chen
  Cc: open list, jcliang, robin.murphy, simon xue, tfiga,
	Romain Perier, Yakir Yang, Arnd Bergmann, Liang Chen,
	Rob Herring, Shawn Lin, Catalin Marinas, David Wu, Finley Xiao,
	Enric Balletbo i Serra, Heiko Stuebner, Jacob Chen, Kever Yang,
	Brian Norris, open list:ARM/Rockchip SoC...,
	Rocky Hao, Will Deacon, Nickey Yang, devicetree, Mark Yao,
	Russell King, linux-arm-kernel, Sugar Zhang, Caesar Wang,
	Mark Rutland

Hi there,

in today's linux-next, the DRM driver fails to probe because the iommu
driver fails to find the aclk. I need to apply this patch for things
to work again.

Thanks,

Tomeu

On 23 March 2018 at 08:38, Jeffy Chen <jeffy.chen@rock-chips.com> wrote:
> Add clocks in iommu nodes, since we are going to control clocks in
> rockchip iommu driver.
>
> Signed-off-by: Jeffy Chen <jeffy.chen@rock-chips.com>
> ---
>
> Changes in v8: None
> Changes in v7: None
> Changes in v6:
> Add clk names, and modify all iommu nodes in all existing rockchip dts
>
> Changes in v5:
> Remove clk names.
>
> Changes in v4: None
> Changes in v3: None
> Changes in v2: None
>
>  arch/arm/boot/dts/rk3036.dtsi            |  2 ++
>  arch/arm/boot/dts/rk322x.dtsi            |  8 ++++++++
>  arch/arm/boot/dts/rk3288.dtsi            | 12 ++++++++++++
>  arch/arm64/boot/dts/rockchip/rk3328.dtsi | 10 ++++++++++
>  arch/arm64/boot/dts/rockchip/rk3368.dtsi | 10 ++++++++++
>  arch/arm64/boot/dts/rockchip/rk3399.dtsi | 14 ++++++++++++--
>  6 files changed, 54 insertions(+), 2 deletions(-)
>
> diff --git a/arch/arm/boot/dts/rk3036.dtsi b/arch/arm/boot/dts/rk3036.dtsi
> index a97458112ff6..567a6a725f9c 100644
> --- a/arch/arm/boot/dts/rk3036.dtsi
> +++ b/arch/arm/boot/dts/rk3036.dtsi
> @@ -197,6 +197,8 @@
>                 reg = <0x10118300 0x100>;
>                 interrupts = <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>;
>                 interrupt-names = "vop_mmu";
> +               clocks = <&cru ACLK_LCDC>, <&cru HCLK_LCDC>;
> +               clock-names = "aclk", "iface";
>                 #iommu-cells = <0>;
>                 status = "disabled";
>         };
> diff --git a/arch/arm/boot/dts/rk322x.dtsi b/arch/arm/boot/dts/rk322x.dtsi
> index df1e47858675..be80e9a2c9af 100644
> --- a/arch/arm/boot/dts/rk322x.dtsi
> +++ b/arch/arm/boot/dts/rk322x.dtsi
> @@ -584,6 +584,8 @@
>                 reg = <0x20020800 0x100>;
>                 interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
>                 interrupt-names = "vpu_mmu";
> +               clocks = <&cru ACLK_VPU>, <&cru HCLK_VPU>;
> +               clock-names = "aclk", "iface";
>                 iommu-cells = <0>;
>                 status = "disabled";
>         };
> @@ -593,6 +595,8 @@
>                 reg = <0x20030480 0x40>, <0x200304c0 0x40>;
>                 interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
>                 interrupt-names = "vdec_mmu";
> +               clocks = <&cru ACLK_RKVDEC>, <&cru HCLK_RKVDEC>;
> +               clock-names = "aclk", "iface";
>                 iommu-cells = <0>;
>                 status = "disabled";
>         };
> @@ -602,6 +606,8 @@
>                 reg = <0x20053f00 0x100>;
>                 interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
>                 interrupt-names = "vop_mmu";
> +               clocks = <&cru ACLK_VOP>, <&cru HCLK_VOP>;
> +               clock-names = "aclk", "iface";
>                 iommu-cells = <0>;
>                 status = "disabled";
>         };
> @@ -611,6 +617,8 @@
>                 reg = <0x20070800 0x100>;
>                 interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
>                 interrupt-names = "iep_mmu";
> +               clocks = <&cru ACLK_IEP>, <&cru HCLK_IEP>;
> +               clock-names = "aclk", "iface";
>                 iommu-cells = <0>;
>                 status = "disabled";
>         };
> diff --git a/arch/arm/boot/dts/rk3288.dtsi b/arch/arm/boot/dts/rk3288.dtsi
> index be9acb6d28a1..d7e49d29ace5 100644
> --- a/arch/arm/boot/dts/rk3288.dtsi
> +++ b/arch/arm/boot/dts/rk3288.dtsi
> @@ -959,6 +959,8 @@
>                 reg = <0x0 0xff900800 0x0 0x40>;
>                 interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
>                 interrupt-names = "iep_mmu";
> +               clocks = <&cru ACLK_IEP>, <&cru HCLK_IEP>;
> +               clock-names = "aclk", "iface";
>                 #iommu-cells = <0>;
>                 status = "disabled";
>         };
> @@ -968,6 +970,8 @@
>                 reg = <0x0 0xff914000 0x0 0x100>, <0x0 0xff915000 0x0 0x100>;
>                 interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
>                 interrupt-names = "isp_mmu";
> +               clocks = <&cru ACLK_ISP>, <&cru HCLK_ISP>;
> +               clock-names = "aclk", "iface";
>                 #iommu-cells = <0>;
>                 rockchip,disable-mmu-reset;
>                 status = "disabled";
> @@ -1027,6 +1031,8 @@
>                 reg = <0x0 0xff930300 0x0 0x100>;
>                 interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>;
>                 interrupt-names = "vopb_mmu";
> +               clocks = <&cru ACLK_VOP0>, <&cru HCLK_VOP0>;
> +               clock-names = "aclk", "iface";
>                 power-domains = <&power RK3288_PD_VIO>;
>                 #iommu-cells = <0>;
>                 status = "disabled";
> @@ -1075,6 +1081,8 @@
>                 reg = <0x0 0xff940300 0x0 0x100>;
>                 interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
>                 interrupt-names = "vopl_mmu";
> +               clocks = <&cru ACLK_VOP1>, <&cru HCLK_VOP1>;
> +               clock-names = "aclk", "iface";
>                 power-domains = <&power RK3288_PD_VIO>;
>                 #iommu-cells = <0>;
>                 status = "disabled";
> @@ -1206,6 +1214,8 @@
>                 reg = <0x0 0xff9a0800 0x0 0x100>;
>                 interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
>                 interrupt-names = "vpu_mmu";
> +               clocks = <&cru ACLK_VCODEC>, <&cru HCLK_VCODEC>;
> +               clock-names = "aclk", "iface";
>                 #iommu-cells = <0>;
>                 status = "disabled";
>         };
> @@ -1215,6 +1225,8 @@
>                 reg = <0x0 0xff9c0440 0x0 0x40>, <0x0 0xff9c0480 0x0 0x40>;
>                 interrupts = <GIC_SPI 111 IRQ_TYPE_LEVEL_HIGH>;
>                 interrupt-names = "hevc_mmu";
> +               clocks = <&cru ACLK_HEVC>, <&cru HCLK_HEVC>;
> +               clock-names = "aclk", "iface";
>                 #iommu-cells = <0>;
>                 status = "disabled";
>         };
> diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi b/arch/arm64/boot/dts/rockchip/rk3328.dtsi
> index be2bfbc6b483..b8e9da15e00c 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi
> +++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi
> @@ -595,6 +595,8 @@
>                 reg = <0x0 0xff330200 0 0x100>;
>                 interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>;
>                 interrupt-names = "h265e_mmu";
> +               clocks = <&cru ACLK_H265>, <&cru PCLK_H265>;
> +               clock-names = "aclk", "iface";
>                 #iommu-cells = <0>;
>                 status = "disabled";
>         };
> @@ -604,6 +606,8 @@
>                 reg = <0x0 0xff340800 0x0 0x40>;
>                 interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>;
>                 interrupt-names = "vepu_mmu";
> +               clocks = <&cru ACLK_VPU>, <&cru HCLK_VPU>;
> +               clock-names = "aclk", "iface";
>                 #iommu-cells = <0>;
>                 status = "disabled";
>         };
> @@ -613,6 +617,8 @@
>                 reg = <0x0 0xff350800 0x0 0x40>;
>                 interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
>                 interrupt-names = "vpu_mmu";
> +               clocks = <&cru ACLK_VPU>, <&cru HCLK_VPU>;
> +               clock-names = "aclk", "iface";
>                 #iommu-cells = <0>;
>                 status = "disabled";
>         };
> @@ -622,6 +628,8 @@
>                 reg = <0x0 0xff360480 0x0 0x40>, <0x0 0xff3604c0 0x0 0x40>;
>                 interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>;
>                 interrupt-names = "rkvdec_mmu";
> +               clocks = <&cru ACLK_RKVDEC>, <&cru HCLK_RKVDEC>;
> +               clock-names = "aclk", "iface";
>                 #iommu-cells = <0>;
>                 status = "disabled";
>         };
> @@ -631,6 +639,8 @@
>                 reg = <0x0 0xff373f00 0x0 0x100>;
>                 interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
>                 interrupt-names = "vop_mmu";
> +               clocks = <&cru ACLK_VOP>, <&cru HCLK_VOP>;
> +               clock-names = "aclk", "iface";
>                 #iommu-cells = <0>;
>                 status = "disabled";
>         };
> diff --git a/arch/arm64/boot/dts/rockchip/rk3368.dtsi b/arch/arm64/boot/dts/rockchip/rk3368.dtsi
> index 03458ac44201..ad91ced78649 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3368.dtsi
> +++ b/arch/arm64/boot/dts/rockchip/rk3368.dtsi
> @@ -742,6 +742,8 @@
>                 reg = <0x0 0xff900800 0x0 0x100>;
>                 interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
>                 interrupt-names = "iep_mmu";
> +               clocks = <&cru ACLK_IEP>, <&cru HCLK_IEP>;
> +               clock-names = "aclk", "iface";
>                 #iommu-cells = <0>;
>                 status = "disabled";
>         };
> @@ -752,6 +754,8 @@
>                       <0x0 0xff915000 0x0 0x100>;
>                 interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
>                 interrupt-names = "isp_mmu";
> +               clocks = <&cru ACLK_ISP>, <&cru HCLK_ISP>;
> +               clock-names = "aclk", "iface";
>                 #iommu-cells = <0>;
>                 rockchip,disable-mmu-reset;
>                 status = "disabled";
> @@ -762,6 +766,8 @@
>                 reg = <0x0 0xff930300 0x0 0x100>;
>                 interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>;
>                 interrupt-names = "vop_mmu";
> +               clocks = <&cru ACLK_VOP>, <&cru HCLK_VOP>;
> +               clock-names = "aclk", "iface";
>                 #iommu-cells = <0>;
>                 status = "disabled";
>         };
> @@ -772,6 +778,8 @@
>                       <0x0 0xff9a0480 0x0 0x40>;
>                 interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>;
>                 interrupt-names = "hevc_mmu";
> +               clocks = <&cru ACLK_VIDEO>, <&cru HCLK_VIDEO>;
> +               clock-names = "aclk", "iface";
>                 #iommu-cells = <0>;
>                 status = "disabled";
>         };
> @@ -782,6 +790,8 @@
>                 interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>,
>                              <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
>                 interrupt-names = "vepu_mmu", "vdpu_mmu";
> +               clocks = <&cru ACLK_VIDEO>, <&cru HCLK_VIDEO>;
> +               clock-names = "aclk", "iface";
>                 #iommu-cells = <0>;
>                 status = "disabled";
>         };
> diff --git a/arch/arm64/boot/dts/rockchip/rk3399.dtsi b/arch/arm64/boot/dts/rockchip/rk3399.dtsi
> index 4550c0f82be9..56f6bb31b399 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3399.dtsi
> +++ b/arch/arm64/boot/dts/rockchip/rk3399.dtsi
> @@ -1234,6 +1234,8 @@
>                 reg = <0x0 0xff650800 0x0 0x40>;
>                 interrupts = <GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH 0>;
>                 interrupt-names = "vpu_mmu";
> +               clocks = <&cru ACLK_VCODEC>, <&cru HCLK_VCODEC>;
> +               clock-names = "aclk", "iface";
>                 #iommu-cells = <0>;
>                 status = "disabled";
>         };
> @@ -1243,6 +1245,8 @@
>                 reg = <0x0 0xff660480 0x0 0x40>, <0x0 0xff6604c0 0x0 0x40>;
>                 interrupts = <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH 0>;
>                 interrupt-names = "vdec_mmu";
> +               clocks = <&cru ACLK_VDU>, <&cru HCLK_VDU>;
> +               clock-names = "aclk", "iface";
>                 #iommu-cells = <0>;
>                 status = "disabled";
>         };
> @@ -1252,6 +1256,8 @@
>                 reg = <0x0 0xff670800 0x0 0x40>;
>                 interrupts = <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH 0>;
>                 interrupt-names = "iep_mmu";
> +               clocks = <&cru ACLK_IEP>, <&cru HCLK_IEP>;
> +               clock-names = "aclk", "iface";
>                 #iommu-cells = <0>;
>                 status = "disabled";
>         };
> @@ -1599,7 +1605,7 @@
>                 interrupts = <GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH 0>;
>                 interrupt-names = "vopl_mmu";
>                 clocks = <&cru ACLK_VOP1>, <&cru HCLK_VOP1>;
> -               clock-names = "aclk", "hclk";
> +               clock-names = "aclk", "iface";
>                 power-domains = <&power RK3399_PD_VOPL>;
>                 #iommu-cells = <0>;
>                 status = "disabled";
> @@ -1656,7 +1662,7 @@
>                 interrupts = <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH 0>;
>                 interrupt-names = "vopb_mmu";
>                 clocks = <&cru ACLK_VOP0>, <&cru HCLK_VOP0>;
> -               clock-names = "aclk", "hclk";
> +               clock-names = "aclk", "iface";
>                 power-domains = <&power RK3399_PD_VOPB>;
>                 #iommu-cells = <0>;
>                 status = "disabled";
> @@ -1667,6 +1673,8 @@
>                 reg = <0x0 0xff914000 0x0 0x100>, <0x0 0xff915000 0x0 0x100>;
>                 interrupts = <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH 0>;
>                 interrupt-names = "isp0_mmu";
> +               clocks = <&cru ACLK_ISP0_NOC>, <&cru HCLK_ISP0_NOC>;
> +               clock-names = "aclk", "iface";
>                 #iommu-cells = <0>;
>                 rockchip,disable-mmu-reset;
>                 status = "disabled";
> @@ -1677,6 +1685,8 @@
>                 reg = <0x0 0xff924000 0x0 0x100>, <0x0 0xff925000 0x0 0x100>;
>                 interrupts = <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH 0>;
>                 interrupt-names = "isp1_mmu";
> +               clocks = <&cru ACLK_ISP1_NOC>, <&cru HCLK_ISP1_NOC>;
> +               clock-names = "aclk", "iface";
>                 #iommu-cells = <0>;
>                 rockchip,disable-mmu-reset;
>                 status = "disabled";
> --
> 2.11.0
>
>

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

* Re: [PATCH v8 07/14] ARM: dts: rockchip: add clocks in iommu nodes
  2018-04-09 14:41   ` Tomeu Vizoso
@ 2018-04-09 15:44     ` Heiko Stübner
  2018-04-09 15:53       ` Robin Murphy
  0 siblings, 1 reply; 27+ messages in thread
From: Heiko Stübner @ 2018-04-09 15:44 UTC (permalink / raw)
  To: Tomeu Vizoso
  Cc: Jeffy Chen, open list, jcliang, robin.murphy, simon xue, tfiga,
	Romain Perier, Yakir Yang, Arnd Bergmann, Liang Chen,
	Rob Herring, Shawn Lin, Catalin Marinas, David Wu, Finley Xiao,
	Enric Balletbo i Serra, Jacob Chen, Kever Yang, Brian Norris,
	open list:ARM/Rockchip SoC...,
	Rocky Hao, Will Deacon, Nickey Yang, devicetree, Mark Yao,
	Russell King, linux-arm-kernel, Sugar Zhang, Caesar Wang,
	Mark Rutland

Hi Tomeu,

Am Montag, 9. April 2018, 16:41:56 CEST schrieb Tomeu Vizoso:
> in today's linux-next, the DRM driver fails to probe because the iommu
> driver fails to find the aclk. I need to apply this patch for things
> to work again.

Thanks for catching that issue.

This seems to expose a backwards-compatibility issue, as this breaks
all old devicetrees, so should get a proper fix, apart from me applying
the dt-patch I missed.

Looking at the iommu-clock-handling patch, I imagine this part as
the culprit:

+	iommu->num_clocks = ARRAY_SIZE(rk_iommu_clocks);
+	iommu->clocks = devm_kcalloc(iommu->dev, iommu->num_clocks,
+				     sizeof(*iommu->clocks), GFP_KERNEL);
+	if (!iommu->clocks)
+		return -ENOMEM;

The clk-bulk functions seem to work with simple for loops and
should (as the other standard clock functions) just work fine with
an empty struct, so I guess a simple

	if (!iommu->clocks && iommu->num_clocks > 0)
		return -ENOMEM;

should hopefully be enough. I'll try to give this a test later on
if nobody beats me to it :-)


Heiko

> 
> Thanks,
> 
> Tomeu
> 
> On 23 March 2018 at 08:38, Jeffy Chen <jeffy.chen@rock-chips.com> wrote:
> > Add clocks in iommu nodes, since we are going to control clocks in
> > rockchip iommu driver.
> > 
> > Signed-off-by: Jeffy Chen <jeffy.chen@rock-chips.com>
> > ---
> > 
> > Changes in v8: None
> > Changes in v7: None
> > Changes in v6:
> > Add clk names, and modify all iommu nodes in all existing rockchip dts
> > 
> > Changes in v5:
> > Remove clk names.
> > 
> > Changes in v4: None
> > Changes in v3: None
> > Changes in v2: None
> > 
> >  arch/arm/boot/dts/rk3036.dtsi            |  2 ++
> >  arch/arm/boot/dts/rk322x.dtsi            |  8 ++++++++
> >  arch/arm/boot/dts/rk3288.dtsi            | 12 ++++++++++++
> >  arch/arm64/boot/dts/rockchip/rk3328.dtsi | 10 ++++++++++
> >  arch/arm64/boot/dts/rockchip/rk3368.dtsi | 10 ++++++++++
> >  arch/arm64/boot/dts/rockchip/rk3399.dtsi | 14 ++++++++++++--
> >  6 files changed, 54 insertions(+), 2 deletions(-)
> > 
> > diff --git a/arch/arm/boot/dts/rk3036.dtsi b/arch/arm/boot/dts/rk3036.dtsi
> > index a97458112ff6..567a6a725f9c 100644
> > --- a/arch/arm/boot/dts/rk3036.dtsi
> > +++ b/arch/arm/boot/dts/rk3036.dtsi
> > @@ -197,6 +197,8 @@
> > 
> >                 reg = <0x10118300 0x100>;
> >                 interrupts = <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>;
> >                 interrupt-names = "vop_mmu";
> > 
> > +               clocks = <&cru ACLK_LCDC>, <&cru HCLK_LCDC>;
> > +               clock-names = "aclk", "iface";
> > 
> >                 #iommu-cells = <0>;
> >                 status = "disabled";
> >         
> >         };
> > 
> > diff --git a/arch/arm/boot/dts/rk322x.dtsi b/arch/arm/boot/dts/rk322x.dtsi
> > index df1e47858675..be80e9a2c9af 100644
> > --- a/arch/arm/boot/dts/rk322x.dtsi
> > +++ b/arch/arm/boot/dts/rk322x.dtsi
> > @@ -584,6 +584,8 @@
> > 
> >                 reg = <0x20020800 0x100>;
> >                 interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
> >                 interrupt-names = "vpu_mmu";
> > 
> > +               clocks = <&cru ACLK_VPU>, <&cru HCLK_VPU>;
> > +               clock-names = "aclk", "iface";
> > 
> >                 iommu-cells = <0>;
> >                 status = "disabled";
> >         
> >         };
> > 
> > @@ -593,6 +595,8 @@
> > 
> >                 reg = <0x20030480 0x40>, <0x200304c0 0x40>;
> >                 interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
> >                 interrupt-names = "vdec_mmu";
> > 
> > +               clocks = <&cru ACLK_RKVDEC>, <&cru HCLK_RKVDEC>;
> > +               clock-names = "aclk", "iface";
> > 
> >                 iommu-cells = <0>;
> >                 status = "disabled";
> >         
> >         };
> > 
> > @@ -602,6 +606,8 @@
> > 
> >                 reg = <0x20053f00 0x100>;
> >                 interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
> >                 interrupt-names = "vop_mmu";
> > 
> > +               clocks = <&cru ACLK_VOP>, <&cru HCLK_VOP>;
> > +               clock-names = "aclk", "iface";
> > 
> >                 iommu-cells = <0>;
> >                 status = "disabled";
> >         
> >         };
> > 
> > @@ -611,6 +617,8 @@
> > 
> >                 reg = <0x20070800 0x100>;
> >                 interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
> >                 interrupt-names = "iep_mmu";
> > 
> > +               clocks = <&cru ACLK_IEP>, <&cru HCLK_IEP>;
> > +               clock-names = "aclk", "iface";
> > 
> >                 iommu-cells = <0>;
> >                 status = "disabled";
> >         
> >         };
> > 
> > diff --git a/arch/arm/boot/dts/rk3288.dtsi b/arch/arm/boot/dts/rk3288.dtsi
> > index be9acb6d28a1..d7e49d29ace5 100644
> > --- a/arch/arm/boot/dts/rk3288.dtsi
> > +++ b/arch/arm/boot/dts/rk3288.dtsi
> > @@ -959,6 +959,8 @@
> > 
> >                 reg = <0x0 0xff900800 0x0 0x40>;
> >                 interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
> >                 interrupt-names = "iep_mmu";
> > 
> > +               clocks = <&cru ACLK_IEP>, <&cru HCLK_IEP>;
> > +               clock-names = "aclk", "iface";
> > 
> >                 #iommu-cells = <0>;
> >                 status = "disabled";
> >         
> >         };
> > 
> > @@ -968,6 +970,8 @@
> > 
> >                 reg = <0x0 0xff914000 0x0 0x100>, <0x0 0xff915000 0x0
> >                 0x100>;
> >                 interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
> >                 interrupt-names = "isp_mmu";
> > 
> > +               clocks = <&cru ACLK_ISP>, <&cru HCLK_ISP>;
> > +               clock-names = "aclk", "iface";
> > 
> >                 #iommu-cells = <0>;
> >                 rockchip,disable-mmu-reset;
> >                 status = "disabled";
> > 
> > @@ -1027,6 +1031,8 @@
> > 
> >                 reg = <0x0 0xff930300 0x0 0x100>;
> >                 interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>;
> >                 interrupt-names = "vopb_mmu";
> > 
> > +               clocks = <&cru ACLK_VOP0>, <&cru HCLK_VOP0>;
> > +               clock-names = "aclk", "iface";
> > 
> >                 power-domains = <&power RK3288_PD_VIO>;
> >                 #iommu-cells = <0>;
> >                 status = "disabled";
> > 
> > @@ -1075,6 +1081,8 @@
> > 
> >                 reg = <0x0 0xff940300 0x0 0x100>;
> >                 interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
> >                 interrupt-names = "vopl_mmu";
> > 
> > +               clocks = <&cru ACLK_VOP1>, <&cru HCLK_VOP1>;
> > +               clock-names = "aclk", "iface";
> > 
> >                 power-domains = <&power RK3288_PD_VIO>;
> >                 #iommu-cells = <0>;
> >                 status = "disabled";
> > 
> > @@ -1206,6 +1214,8 @@
> > 
> >                 reg = <0x0 0xff9a0800 0x0 0x100>;
> >                 interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
> >                 interrupt-names = "vpu_mmu";
> > 
> > +               clocks = <&cru ACLK_VCODEC>, <&cru HCLK_VCODEC>;
> > +               clock-names = "aclk", "iface";
> > 
> >                 #iommu-cells = <0>;
> >                 status = "disabled";
> >         
> >         };
> > 
> > @@ -1215,6 +1225,8 @@
> > 
> >                 reg = <0x0 0xff9c0440 0x0 0x40>, <0x0 0xff9c0480 0x0
> >                 0x40>;
> >                 interrupts = <GIC_SPI 111 IRQ_TYPE_LEVEL_HIGH>;
> >                 interrupt-names = "hevc_mmu";
> > 
> > +               clocks = <&cru ACLK_HEVC>, <&cru HCLK_HEVC>;
> > +               clock-names = "aclk", "iface";
> > 
> >                 #iommu-cells = <0>;
> >                 status = "disabled";
> >         
> >         };
> > 
> > diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi
> > b/arch/arm64/boot/dts/rockchip/rk3328.dtsi index
> > be2bfbc6b483..b8e9da15e00c 100644
> > --- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi
> > +++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi
> > @@ -595,6 +595,8 @@
> > 
> >                 reg = <0x0 0xff330200 0 0x100>;
> >                 interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>;
> >                 interrupt-names = "h265e_mmu";
> > 
> > +               clocks = <&cru ACLK_H265>, <&cru PCLK_H265>;
> > +               clock-names = "aclk", "iface";
> > 
> >                 #iommu-cells = <0>;
> >                 status = "disabled";
> >         
> >         };
> > 
> > @@ -604,6 +606,8 @@
> > 
> >                 reg = <0x0 0xff340800 0x0 0x40>;
> >                 interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>;
> >                 interrupt-names = "vepu_mmu";
> > 
> > +               clocks = <&cru ACLK_VPU>, <&cru HCLK_VPU>;
> > +               clock-names = "aclk", "iface";
> > 
> >                 #iommu-cells = <0>;
> >                 status = "disabled";
> >         
> >         };
> > 
> > @@ -613,6 +617,8 @@
> > 
> >                 reg = <0x0 0xff350800 0x0 0x40>;
> >                 interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
> >                 interrupt-names = "vpu_mmu";
> > 
> > +               clocks = <&cru ACLK_VPU>, <&cru HCLK_VPU>;
> > +               clock-names = "aclk", "iface";
> > 
> >                 #iommu-cells = <0>;
> >                 status = "disabled";
> >         
> >         };
> > 
> > @@ -622,6 +628,8 @@
> > 
> >                 reg = <0x0 0xff360480 0x0 0x40>, <0x0 0xff3604c0 0x0
> >                 0x40>;
> >                 interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>;
> >                 interrupt-names = "rkvdec_mmu";
> > 
> > +               clocks = <&cru ACLK_RKVDEC>, <&cru HCLK_RKVDEC>;
> > +               clock-names = "aclk", "iface";
> > 
> >                 #iommu-cells = <0>;
> >                 status = "disabled";
> >         
> >         };
> > 
> > @@ -631,6 +639,8 @@
> > 
> >                 reg = <0x0 0xff373f00 0x0 0x100>;
> >                 interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
> >                 interrupt-names = "vop_mmu";
> > 
> > +               clocks = <&cru ACLK_VOP>, <&cru HCLK_VOP>;
> > +               clock-names = "aclk", "iface";
> > 
> >                 #iommu-cells = <0>;
> >                 status = "disabled";
> >         
> >         };
> > 
> > diff --git a/arch/arm64/boot/dts/rockchip/rk3368.dtsi
> > b/arch/arm64/boot/dts/rockchip/rk3368.dtsi index
> > 03458ac44201..ad91ced78649 100644
> > --- a/arch/arm64/boot/dts/rockchip/rk3368.dtsi
> > +++ b/arch/arm64/boot/dts/rockchip/rk3368.dtsi
> > @@ -742,6 +742,8 @@
> > 
> >                 reg = <0x0 0xff900800 0x0 0x100>;
> >                 interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
> >                 interrupt-names = "iep_mmu";
> > 
> > +               clocks = <&cru ACLK_IEP>, <&cru HCLK_IEP>;
> > +               clock-names = "aclk", "iface";
> > 
> >                 #iommu-cells = <0>;
> >                 status = "disabled";
> >         
> >         };
> > 
> > @@ -752,6 +754,8 @@
> > 
> >                       <0x0 0xff915000 0x0 0x100>;
> >                 
> >                 interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
> >                 interrupt-names = "isp_mmu";
> > 
> > +               clocks = <&cru ACLK_ISP>, <&cru HCLK_ISP>;
> > +               clock-names = "aclk", "iface";
> > 
> >                 #iommu-cells = <0>;
> >                 rockchip,disable-mmu-reset;
> >                 status = "disabled";
> > 
> > @@ -762,6 +766,8 @@
> > 
> >                 reg = <0x0 0xff930300 0x0 0x100>;
> >                 interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>;
> >                 interrupt-names = "vop_mmu";
> > 
> > +               clocks = <&cru ACLK_VOP>, <&cru HCLK_VOP>;
> > +               clock-names = "aclk", "iface";
> > 
> >                 #iommu-cells = <0>;
> >                 status = "disabled";
> >         
> >         };
> > 
> > @@ -772,6 +778,8 @@
> > 
> >                       <0x0 0xff9a0480 0x0 0x40>;
> >                 
> >                 interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>;
> >                 interrupt-names = "hevc_mmu";
> > 
> > +               clocks = <&cru ACLK_VIDEO>, <&cru HCLK_VIDEO>;
> > +               clock-names = "aclk", "iface";
> > 
> >                 #iommu-cells = <0>;
> >                 status = "disabled";
> >         
> >         };
> > 
> > @@ -782,6 +790,8 @@
> > 
> >                 interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>,
> >                 
> >                              <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
> >                 
> >                 interrupt-names = "vepu_mmu", "vdpu_mmu";
> > 
> > +               clocks = <&cru ACLK_VIDEO>, <&cru HCLK_VIDEO>;
> > +               clock-names = "aclk", "iface";
> > 
> >                 #iommu-cells = <0>;
> >                 status = "disabled";
> >         
> >         };
> > 
> > diff --git a/arch/arm64/boot/dts/rockchip/rk3399.dtsi
> > b/arch/arm64/boot/dts/rockchip/rk3399.dtsi index
> > 4550c0f82be9..56f6bb31b399 100644
> > --- a/arch/arm64/boot/dts/rockchip/rk3399.dtsi
> > +++ b/arch/arm64/boot/dts/rockchip/rk3399.dtsi
> > @@ -1234,6 +1234,8 @@
> > 
> >                 reg = <0x0 0xff650800 0x0 0x40>;
> >                 interrupts = <GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH 0>;
> >                 interrupt-names = "vpu_mmu";
> > 
> > +               clocks = <&cru ACLK_VCODEC>, <&cru HCLK_VCODEC>;
> > +               clock-names = "aclk", "iface";
> > 
> >                 #iommu-cells = <0>;
> >                 status = "disabled";
> >         
> >         };
> > 
> > @@ -1243,6 +1245,8 @@
> > 
> >                 reg = <0x0 0xff660480 0x0 0x40>, <0x0 0xff6604c0 0x0
> >                 0x40>;
> >                 interrupts = <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH 0>;
> >                 interrupt-names = "vdec_mmu";
> > 
> > +               clocks = <&cru ACLK_VDU>, <&cru HCLK_VDU>;
> > +               clock-names = "aclk", "iface";
> > 
> >                 #iommu-cells = <0>;
> >                 status = "disabled";
> >         
> >         };
> > 
> > @@ -1252,6 +1256,8 @@
> > 
> >                 reg = <0x0 0xff670800 0x0 0x40>;
> >                 interrupts = <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH 0>;
> >                 interrupt-names = "iep_mmu";
> > 
> > +               clocks = <&cru ACLK_IEP>, <&cru HCLK_IEP>;
> > +               clock-names = "aclk", "iface";
> > 
> >                 #iommu-cells = <0>;
> >                 status = "disabled";
> >         
> >         };
> > 
> > @@ -1599,7 +1605,7 @@
> > 
> >                 interrupts = <GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH 0>;
> >                 interrupt-names = "vopl_mmu";
> >                 clocks = <&cru ACLK_VOP1>, <&cru HCLK_VOP1>;
> > 
> > -               clock-names = "aclk", "hclk";
> > +               clock-names = "aclk", "iface";
> > 
> >                 power-domains = <&power RK3399_PD_VOPL>;
> >                 #iommu-cells = <0>;
> >                 status = "disabled";
> > 
> > @@ -1656,7 +1662,7 @@
> > 
> >                 interrupts = <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH 0>;
> >                 interrupt-names = "vopb_mmu";
> >                 clocks = <&cru ACLK_VOP0>, <&cru HCLK_VOP0>;
> > 
> > -               clock-names = "aclk", "hclk";
> > +               clock-names = "aclk", "iface";
> > 
> >                 power-domains = <&power RK3399_PD_VOPB>;
> >                 #iommu-cells = <0>;
> >                 status = "disabled";
> > 
> > @@ -1667,6 +1673,8 @@
> > 
> >                 reg = <0x0 0xff914000 0x0 0x100>, <0x0 0xff915000 0x0
> >                 0x100>;
> >                 interrupts = <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH 0>;
> >                 interrupt-names = "isp0_mmu";
> > 
> > +               clocks = <&cru ACLK_ISP0_NOC>, <&cru HCLK_ISP0_NOC>;
> > +               clock-names = "aclk", "iface";
> > 
> >                 #iommu-cells = <0>;
> >                 rockchip,disable-mmu-reset;
> >                 status = "disabled";
> > 
> > @@ -1677,6 +1685,8 @@
> > 
> >                 reg = <0x0 0xff924000 0x0 0x100>, <0x0 0xff925000 0x0
> >                 0x100>;
> >                 interrupts = <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH 0>;
> >                 interrupt-names = "isp1_mmu";
> > 
> > +               clocks = <&cru ACLK_ISP1_NOC>, <&cru HCLK_ISP1_NOC>;
> > +               clock-names = "aclk", "iface";
> > 
> >                 #iommu-cells = <0>;
> >                 rockchip,disable-mmu-reset;
> >                 status = "disabled";
> > 
> > --
> > 2.11.0

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

* Re: [PATCH v8 07/14] ARM: dts: rockchip: add clocks in iommu nodes
  2018-04-09 15:44     ` Heiko Stübner
@ 2018-04-09 15:53       ` Robin Murphy
  2018-04-09 15:55         ` Heiko Stübner
  0 siblings, 1 reply; 27+ messages in thread
From: Robin Murphy @ 2018-04-09 15:53 UTC (permalink / raw)
  To: Heiko Stübner, Tomeu Vizoso
  Cc: Jeffy Chen, open list, jcliang, simon xue, tfiga, Romain Perier,
	Yakir Yang, Arnd Bergmann, Liang Chen, Rob Herring, Shawn Lin,
	Catalin Marinas, David Wu, Finley Xiao, Enric Balletbo i Serra,
	Jacob Chen, Kever Yang, Brian Norris,
	open list:ARM/Rockchip SoC...,
	Rocky Hao, Will Deacon, Nickey Yang, devicetree, Mark Yao,
	Russell King, linux-arm-kernel, Sugar Zhang, Caesar Wang,
	Mark Rutland

On 09/04/18 16:44, Heiko Stübner wrote:
> Hi Tomeu,
> 
> Am Montag, 9. April 2018, 16:41:56 CEST schrieb Tomeu Vizoso:
>> in today's linux-next, the DRM driver fails to probe because the iommu
>> driver fails to find the aclk. I need to apply this patch for things
>> to work again.
> 
> Thanks for catching that issue.
> 
> This seems to expose a backwards-compatibility issue, as this breaks
> all old devicetrees, so should get a proper fix, apart from me applying
> the dt-patch I missed.
> 
> Looking at the iommu-clock-handling patch, I imagine this part as
> the culprit:
> 
> +	iommu->num_clocks = ARRAY_SIZE(rk_iommu_clocks);
> +	iommu->clocks = devm_kcalloc(iommu->dev, iommu->num_clocks,
> +				     sizeof(*iommu->clocks), GFP_KERNEL);
> +	if (!iommu->clocks)
> +		return -ENOMEM;
> 
> The clk-bulk functions seem to work with simple for loops and
> should (as the other standard clock functions) just work fine with
> an empty struct, so I guess a simple
> 
> 	if (!iommu->clocks && iommu->num_clocks > 0)
> 		return -ENOMEM;
> 
> should hopefully be enough. I'll try to give this a test later on
> if nobody beats me to it :-)

But iommu->num_clocks is clearly set to a nonzero compile-time constant 
at this point ;)

I'd assume it's the return from devm_clk_bulk_get() which needs to 
special-case the "no clocks found" case from any other error, and *then* 
blat num_clocks to 0 if so.

Robin.

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

* Re: [PATCH v8 07/14] ARM: dts: rockchip: add clocks in iommu nodes
  2018-04-09 15:53       ` Robin Murphy
@ 2018-04-09 15:55         ` Heiko Stübner
  2018-04-09 21:49           ` Heiko Stübner
  0 siblings, 1 reply; 27+ messages in thread
From: Heiko Stübner @ 2018-04-09 15:55 UTC (permalink / raw)
  To: Robin Murphy
  Cc: Tomeu Vizoso, Jeffy Chen, open list, jcliang, simon xue, tfiga,
	Romain Perier, Yakir Yang, Arnd Bergmann, Liang Chen,
	Rob Herring, Shawn Lin, Catalin Marinas, David Wu, Finley Xiao,
	Enric Balletbo i Serra, Jacob Chen, Kever Yang, Brian Norris,
	open list:ARM/Rockchip SoC...,
	Rocky Hao, Will Deacon, Nickey Yang, devicetree, Mark Yao,
	Russell King, linux-arm-kernel, Sugar Zhang, Caesar Wang,
	Mark Rutland

Am Montag, 9. April 2018, 17:53:01 CEST schrieb Robin Murphy:
> On 09/04/18 16:44, Heiko Stübner wrote:
> > Hi Tomeu,
> > 
> > Am Montag, 9. April 2018, 16:41:56 CEST schrieb Tomeu Vizoso:
> >> in today's linux-next, the DRM driver fails to probe because the iommu
> >> driver fails to find the aclk. I need to apply this patch for things
> >> to work again.
> > 
> > Thanks for catching that issue.
> > 
> > This seems to expose a backwards-compatibility issue, as this breaks
> > all old devicetrees, so should get a proper fix, apart from me applying
> > the dt-patch I missed.
> > 
> > Looking at the iommu-clock-handling patch, I imagine this part as
> > the culprit:
> > 
> > +	iommu->num_clocks = ARRAY_SIZE(rk_iommu_clocks);
> > +	iommu->clocks = devm_kcalloc(iommu->dev, iommu->num_clocks,
> > +				     sizeof(*iommu->clocks), GFP_KERNEL);
> > +	if (!iommu->clocks)
> > +		return -ENOMEM;
> > 
> > The clk-bulk functions seem to work with simple for loops and
> > should (as the other standard clock functions) just work fine with
> > an empty struct, so I guess a simple
> > 
> > 	if (!iommu->clocks && iommu->num_clocks > 0)
> > 	
> > 		return -ENOMEM;
> > 
> > should hopefully be enough. I'll try to give this a test later on
> > if nobody beats me to it :-)
> 
> But iommu->num_clocks is clearly set to a nonzero compile-time constant
> at this point ;)
> 
> I'd assume it's the return from devm_clk_bulk_get() which needs to
> special-case the "no clocks found" case from any other error, and *then*
> blat num_clocks to 0 if so.

you're right of course. Looking at it again, I now clearly see the ARRAY_SIZE
and am wondering what made me think num_clocks would be runtime-read.

Must be those 25°C today ;-)

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

* Re: [PATCH v8 07/14] ARM: dts: rockchip: add clocks in iommu nodes
  2018-04-09 15:55         ` Heiko Stübner
@ 2018-04-09 21:49           ` Heiko Stübner
  2018-04-10 10:54             ` Heiko Stuebner
  0 siblings, 1 reply; 27+ messages in thread
From: Heiko Stübner @ 2018-04-09 21:49 UTC (permalink / raw)
  To: Robin Murphy
  Cc: Tomeu Vizoso, Jeffy Chen, open list, jcliang, simon xue, tfiga,
	Romain Perier, Yakir Yang, Arnd Bergmann, Liang Chen,
	Rob Herring, Shawn Lin, Catalin Marinas, David Wu, Finley Xiao,
	Enric Balletbo i Serra, Jacob Chen, Kever Yang, Brian Norris,
	open list:ARM/Rockchip SoC...,
	Rocky Hao, Will Deacon, Nickey Yang, devicetree, Mark Yao,
	Russell King, linux-arm-kernel, Sugar Zhang, Caesar Wang,
	Mark Rutland

Am Montag, 9. April 2018, 17:55:40 CEST schrieb Heiko Stübner:
> Am Montag, 9. April 2018, 17:53:01 CEST schrieb Robin Murphy:
> > On 09/04/18 16:44, Heiko Stübner wrote:
> > > Hi Tomeu,
> > > 
> > > Am Montag, 9. April 2018, 16:41:56 CEST schrieb Tomeu Vizoso:
> > >> in today's linux-next, the DRM driver fails to probe because the iommu
> > >> driver fails to find the aclk. I need to apply this patch for things
> > >> to work again.
> > > 
> > > Thanks for catching that issue.
> > > 
> > > This seems to expose a backwards-compatibility issue, as this breaks
> > > all old devicetrees, so should get a proper fix, apart from me applying
> > > the dt-patch I missed.
> > > 
> > > Looking at the iommu-clock-handling patch, I imagine this part as
> > > the culprit:
> > > 
> > > +	iommu->num_clocks = ARRAY_SIZE(rk_iommu_clocks);
> > > +	iommu->clocks = devm_kcalloc(iommu->dev, iommu->num_clocks,
> > > +				     sizeof(*iommu->clocks), GFP_KERNEL);
> > > +	if (!iommu->clocks)
> > > +		return -ENOMEM;
> > > 
> > > The clk-bulk functions seem to work with simple for loops and
> > > should (as the other standard clock functions) just work fine with
> > > an empty struct, so I guess a simple
> > > 
> > > 	if (!iommu->clocks && iommu->num_clocks > 0)
> > > 	
> > > 		return -ENOMEM;
> > > 
> > > should hopefully be enough. I'll try to give this a test later on
> > > if nobody beats me to it :-)
> > 
> > But iommu->num_clocks is clearly set to a nonzero compile-time constant
> > at this point ;)
> > 
> > I'd assume it's the return from devm_clk_bulk_get() which needs to
> > special-case the "no clocks found" case from any other error, and *then*
> > blat num_clocks to 0 if so.
> 
> you're right of course. Looking at it again, I now clearly see the
> ARRAY_SIZE and am wondering what made me think num_clocks would be
> runtime-read.
> 
> Must be those 25°C today ;-)

In any case, this does not seem to fully fix the issue ... or be more exact 
seems to be the only issue.

- With 4.16 both pinky and kevin have working displays.
- When I was merging display patches to drm-misc, I did boot-tests on
  both pinky and kevin, keeping their displays in a working state.

- With current torvalds head (iommu not merged yet)
e9092d0d9796 ("Fix subtle macro variable shadowing in min_not_zero()")

I get display output on rk3399-kevin (edp), but not on
rk3288-pinky (edp + hdmi). [components + hdmi device+modes get
recognized correctly though]

- With iommu changes merged I end up with the failing clock issue
  which can be countered by making the iommu-clocks optional.

- After that I get working display output again on kevin but not pinky.

Looks like this needs bisecting.

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

* Re: [PATCH v8 07/14] ARM: dts: rockchip: add clocks in iommu nodes
  2018-04-09 21:49           ` Heiko Stübner
@ 2018-04-10 10:54             ` Heiko Stuebner
  0 siblings, 0 replies; 27+ messages in thread
From: Heiko Stuebner @ 2018-04-10 10:54 UTC (permalink / raw)
  To: Robin Murphy
  Cc: Tomeu Vizoso, Jeffy Chen, open list, jcliang, simon xue, tfiga,
	Romain Perier, Yakir Yang, Arnd Bergmann, Liang Chen,
	Rob Herring, Shawn Lin, Catalin Marinas, David Wu, Finley Xiao,
	Enric Balletbo i Serra, Jacob Chen, Kever Yang, Brian Norris,
	open list:ARM/Rockchip SoC...,
	Rocky Hao, Will Deacon, Nickey Yang, devicetree, Mark Yao,
	Russell King, linux-arm-kernel, Sugar Zhang, Caesar Wang,
	Mark Rutland

Am Montag, 9. April 2018, 23:49:58 CEST schrieb Heiko Stübner:
> Am Montag, 9. April 2018, 17:55:40 CEST schrieb Heiko Stübner:
> > Am Montag, 9. April 2018, 17:53:01 CEST schrieb Robin Murphy:
> > > On 09/04/18 16:44, Heiko Stübner wrote:
> > > > Hi Tomeu,
> > > > 
> > > > Am Montag, 9. April 2018, 16:41:56 CEST schrieb Tomeu Vizoso:
> > > >> in today's linux-next, the DRM driver fails to probe because the iommu
> > > >> driver fails to find the aclk. I need to apply this patch for things
> > > >> to work again.
> > > > 
> > > > Thanks for catching that issue.
> > > > 
> > > > This seems to expose a backwards-compatibility issue, as this breaks
> > > > all old devicetrees, so should get a proper fix, apart from me applying
> > > > the dt-patch I missed.
> > > > 
> > > > Looking at the iommu-clock-handling patch, I imagine this part as
> > > > the culprit:
> > > > 
> > > > +	iommu->num_clocks = ARRAY_SIZE(rk_iommu_clocks);
> > > > +	iommu->clocks = devm_kcalloc(iommu->dev, iommu->num_clocks,
> > > > +				     sizeof(*iommu->clocks), GFP_KERNEL);
> > > > +	if (!iommu->clocks)
> > > > +		return -ENOMEM;
> > > > 
> > > > The clk-bulk functions seem to work with simple for loops and
> > > > should (as the other standard clock functions) just work fine with
> > > > an empty struct, so I guess a simple
> > > > 
> > > > 	if (!iommu->clocks && iommu->num_clocks > 0)
> > > > 	
> > > > 		return -ENOMEM;
> > > > 
> > > > should hopefully be enough. I'll try to give this a test later on
> > > > if nobody beats me to it :-)
> > > 
> > > But iommu->num_clocks is clearly set to a nonzero compile-time constant
> > > at this point ;)
> > > 
> > > I'd assume it's the return from devm_clk_bulk_get() which needs to
> > > special-case the "no clocks found" case from any other error, and *then*
> > > blat num_clocks to 0 if so.
> > 
> > you're right of course. Looking at it again, I now clearly see the
> > ARRAY_SIZE and am wondering what made me think num_clocks would be
> > runtime-read.
> > 
> > Must be those 25°C today ;-)
> 
> In any case, this does not seem to fully fix the issue ... or be more exact 
> seems to be the only issue.
> 
> - With 4.16 both pinky and kevin have working displays.
> - When I was merging display patches to drm-misc, I did boot-tests on
>   both pinky and kevin, keeping their displays in a working state.
> 
> - With current torvalds head (iommu not merged yet)
> e9092d0d9796 ("Fix subtle macro variable shadowing in min_not_zero()")
> 
> I get display output on rk3399-kevin (edp), but not on
> rk3288-pinky (edp + hdmi). [components + hdmi device+modes get
> recognized correctly though]
> 
> - With iommu changes merged I end up with the failing clock issue
>   which can be countered by making the iommu-clocks optional.
> 
> - After that I get working display output again on kevin but not pinky.
> 
> Looks like this needs bisecting.

And it seems the dwc2 vbus thingy was responsible for the other issue I saw.
With Tomeus fixup patch applied and the series I sent an hour ago, I now
get display output again on both kevin (rk3399) and pinky (rk3288).

Heiko

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

* Re: [PATCH v8 07/14] ARM: dts: rockchip: add clocks in iommu nodes
  2018-03-23  7:38 ` [PATCH v8 07/14] ARM: dts: rockchip: add clocks in iommu nodes Jeffy Chen
  2018-04-09 14:41   ` Tomeu Vizoso
@ 2018-04-10 11:46   ` Heiko Stuebner
  1 sibling, 0 replies; 27+ messages in thread
From: Heiko Stuebner @ 2018-04-10 11:46 UTC (permalink / raw)
  To: Jeffy Chen
  Cc: linux-kernel, jcliang, robin.murphy, xxm, tfiga, Romain Perier,
	Yakir Yang, Arnd Bergmann, Liang Chen, Rob Herring, Shawn Lin,
	Catalin Marinas, David Wu, Finley Xiao, Enric Balletbo i Serra,
	Jacob Chen, Kever Yang, Brian Norris, linux-rockchip, Rocky Hao,
	Will Deacon, Nickey Yang, devicetree, Mark Yao, Russell King,
	linux-arm-kernel, Sugar Zhang, Caesar Wang, Mark Rutland

Am Freitag, 23. März 2018, 08:38:07 CEST schrieb Jeffy Chen:
> Add clocks in iommu nodes, since we are going to control clocks in
> rockchip iommu driver.
> 
> Signed-off-by: Jeffy Chen <jeffy.chen@rock-chips.com>

applied for 4.18 after splitting arm32+arm64 parts into 2 patches
and adapting the subject for the arm64 variant.

Please don't mix arm32+arm64 devicetree patches in the future.


Thanks
Heiko

> ---
> 
> Changes in v8: None
> Changes in v7: None
> Changes in v6:
> Add clk names, and modify all iommu nodes in all existing rockchip dts
> 
> Changes in v5:
> Remove clk names.
> 
> Changes in v4: None
> Changes in v3: None
> Changes in v2: None
> 
>  arch/arm/boot/dts/rk3036.dtsi            |  2 ++
>  arch/arm/boot/dts/rk322x.dtsi            |  8 ++++++++
>  arch/arm/boot/dts/rk3288.dtsi            | 12 ++++++++++++
>  arch/arm64/boot/dts/rockchip/rk3328.dtsi | 10 ++++++++++
>  arch/arm64/boot/dts/rockchip/rk3368.dtsi | 10 ++++++++++
>  arch/arm64/boot/dts/rockchip/rk3399.dtsi | 14 ++++++++++++--
>  6 files changed, 54 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/arm/boot/dts/rk3036.dtsi b/arch/arm/boot/dts/rk3036.dtsi
> index a97458112ff6..567a6a725f9c 100644
> --- a/arch/arm/boot/dts/rk3036.dtsi
> +++ b/arch/arm/boot/dts/rk3036.dtsi
> @@ -197,6 +197,8 @@
>  		reg = <0x10118300 0x100>;
>  		interrupts = <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>;
>  		interrupt-names = "vop_mmu";
> +		clocks = <&cru ACLK_LCDC>, <&cru HCLK_LCDC>;
> +		clock-names = "aclk", "iface";
>  		#iommu-cells = <0>;
>  		status = "disabled";
>  	};
> diff --git a/arch/arm/boot/dts/rk322x.dtsi b/arch/arm/boot/dts/rk322x.dtsi
> index df1e47858675..be80e9a2c9af 100644
> --- a/arch/arm/boot/dts/rk322x.dtsi
> +++ b/arch/arm/boot/dts/rk322x.dtsi
> @@ -584,6 +584,8 @@
>  		reg = <0x20020800 0x100>;
>  		interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
>  		interrupt-names = "vpu_mmu";
> +		clocks = <&cru ACLK_VPU>, <&cru HCLK_VPU>;
> +		clock-names = "aclk", "iface";
>  		iommu-cells = <0>;
>  		status = "disabled";
>  	};
> @@ -593,6 +595,8 @@
>  		reg = <0x20030480 0x40>, <0x200304c0 0x40>;
>  		interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
>  		interrupt-names = "vdec_mmu";
> +		clocks = <&cru ACLK_RKVDEC>, <&cru HCLK_RKVDEC>;
> +		clock-names = "aclk", "iface";
>  		iommu-cells = <0>;
>  		status = "disabled";
>  	};
> @@ -602,6 +606,8 @@
>  		reg = <0x20053f00 0x100>;
>  		interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
>  		interrupt-names = "vop_mmu";
> +		clocks = <&cru ACLK_VOP>, <&cru HCLK_VOP>;
> +		clock-names = "aclk", "iface";
>  		iommu-cells = <0>;
>  		status = "disabled";
>  	};
> @@ -611,6 +617,8 @@
>  		reg = <0x20070800 0x100>;
>  		interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
>  		interrupt-names = "iep_mmu";
> +		clocks = <&cru ACLK_IEP>, <&cru HCLK_IEP>;
> +		clock-names = "aclk", "iface";
>  		iommu-cells = <0>;
>  		status = "disabled";
>  	};
> diff --git a/arch/arm/boot/dts/rk3288.dtsi b/arch/arm/boot/dts/rk3288.dtsi
> index be9acb6d28a1..d7e49d29ace5 100644
> --- a/arch/arm/boot/dts/rk3288.dtsi
> +++ b/arch/arm/boot/dts/rk3288.dtsi
> @@ -959,6 +959,8 @@
>  		reg = <0x0 0xff900800 0x0 0x40>;
>  		interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
>  		interrupt-names = "iep_mmu";
> +		clocks = <&cru ACLK_IEP>, <&cru HCLK_IEP>;
> +		clock-names = "aclk", "iface";
>  		#iommu-cells = <0>;
>  		status = "disabled";
>  	};
> @@ -968,6 +970,8 @@
>  		reg = <0x0 0xff914000 0x0 0x100>, <0x0 0xff915000 0x0 0x100>;
>  		interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
>  		interrupt-names = "isp_mmu";
> +		clocks = <&cru ACLK_ISP>, <&cru HCLK_ISP>;
> +		clock-names = "aclk", "iface";
>  		#iommu-cells = <0>;
>  		rockchip,disable-mmu-reset;
>  		status = "disabled";
> @@ -1027,6 +1031,8 @@
>  		reg = <0x0 0xff930300 0x0 0x100>;
>  		interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>;
>  		interrupt-names = "vopb_mmu";
> +		clocks = <&cru ACLK_VOP0>, <&cru HCLK_VOP0>;
> +		clock-names = "aclk", "iface";
>  		power-domains = <&power RK3288_PD_VIO>;
>  		#iommu-cells = <0>;
>  		status = "disabled";
> @@ -1075,6 +1081,8 @@
>  		reg = <0x0 0xff940300 0x0 0x100>;
>  		interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
>  		interrupt-names = "vopl_mmu";
> +		clocks = <&cru ACLK_VOP1>, <&cru HCLK_VOP1>;
> +		clock-names = "aclk", "iface";
>  		power-domains = <&power RK3288_PD_VIO>;
>  		#iommu-cells = <0>;
>  		status = "disabled";
> @@ -1206,6 +1214,8 @@
>  		reg = <0x0 0xff9a0800 0x0 0x100>;
>  		interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
>  		interrupt-names = "vpu_mmu";
> +		clocks = <&cru ACLK_VCODEC>, <&cru HCLK_VCODEC>;
> +		clock-names = "aclk", "iface";
>  		#iommu-cells = <0>;
>  		status = "disabled";
>  	};
> @@ -1215,6 +1225,8 @@
>  		reg = <0x0 0xff9c0440 0x0 0x40>, <0x0 0xff9c0480 0x0 0x40>;
>  		interrupts = <GIC_SPI 111 IRQ_TYPE_LEVEL_HIGH>;
>  		interrupt-names = "hevc_mmu";
> +		clocks = <&cru ACLK_HEVC>, <&cru HCLK_HEVC>;
> +		clock-names = "aclk", "iface";
>  		#iommu-cells = <0>;
>  		status = "disabled";
>  	};
> diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi b/arch/arm64/boot/dts/rockchip/rk3328.dtsi
> index be2bfbc6b483..b8e9da15e00c 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi
> +++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi
> @@ -595,6 +595,8 @@
>  		reg = <0x0 0xff330200 0 0x100>;
>  		interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>;
>  		interrupt-names = "h265e_mmu";
> +		clocks = <&cru ACLK_H265>, <&cru PCLK_H265>;
> +		clock-names = "aclk", "iface";
>  		#iommu-cells = <0>;
>  		status = "disabled";
>  	};
> @@ -604,6 +606,8 @@
>  		reg = <0x0 0xff340800 0x0 0x40>;
>  		interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>;
>  		interrupt-names = "vepu_mmu";
> +		clocks = <&cru ACLK_VPU>, <&cru HCLK_VPU>;
> +		clock-names = "aclk", "iface";
>  		#iommu-cells = <0>;
>  		status = "disabled";
>  	};
> @@ -613,6 +617,8 @@
>  		reg = <0x0 0xff350800 0x0 0x40>;
>  		interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
>  		interrupt-names = "vpu_mmu";
> +		clocks = <&cru ACLK_VPU>, <&cru HCLK_VPU>;
> +		clock-names = "aclk", "iface";
>  		#iommu-cells = <0>;
>  		status = "disabled";
>  	};
> @@ -622,6 +628,8 @@
>  		reg = <0x0 0xff360480 0x0 0x40>, <0x0 0xff3604c0 0x0 0x40>;
>  		interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>;
>  		interrupt-names = "rkvdec_mmu";
> +		clocks = <&cru ACLK_RKVDEC>, <&cru HCLK_RKVDEC>;
> +		clock-names = "aclk", "iface";
>  		#iommu-cells = <0>;
>  		status = "disabled";
>  	};
> @@ -631,6 +639,8 @@
>  		reg = <0x0 0xff373f00 0x0 0x100>;
>  		interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
>  		interrupt-names = "vop_mmu";
> +		clocks = <&cru ACLK_VOP>, <&cru HCLK_VOP>;
> +		clock-names = "aclk", "iface";
>  		#iommu-cells = <0>;
>  		status = "disabled";
>  	};
> diff --git a/arch/arm64/boot/dts/rockchip/rk3368.dtsi b/arch/arm64/boot/dts/rockchip/rk3368.dtsi
> index 03458ac44201..ad91ced78649 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3368.dtsi
> +++ b/arch/arm64/boot/dts/rockchip/rk3368.dtsi
> @@ -742,6 +742,8 @@
>  		reg = <0x0 0xff900800 0x0 0x100>;
>  		interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
>  		interrupt-names = "iep_mmu";
> +		clocks = <&cru ACLK_IEP>, <&cru HCLK_IEP>;
> +		clock-names = "aclk", "iface";
>  		#iommu-cells = <0>;
>  		status = "disabled";
>  	};
> @@ -752,6 +754,8 @@
>  		      <0x0 0xff915000 0x0 0x100>;
>  		interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
>  		interrupt-names = "isp_mmu";
> +		clocks = <&cru ACLK_ISP>, <&cru HCLK_ISP>;
> +		clock-names = "aclk", "iface";
>  		#iommu-cells = <0>;
>  		rockchip,disable-mmu-reset;
>  		status = "disabled";
> @@ -762,6 +766,8 @@
>  		reg = <0x0 0xff930300 0x0 0x100>;
>  		interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>;
>  		interrupt-names = "vop_mmu";
> +		clocks = <&cru ACLK_VOP>, <&cru HCLK_VOP>;
> +		clock-names = "aclk", "iface";
>  		#iommu-cells = <0>;
>  		status = "disabled";
>  	};
> @@ -772,6 +778,8 @@
>  		      <0x0 0xff9a0480 0x0 0x40>;
>  		interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>;
>  		interrupt-names = "hevc_mmu";
> +		clocks = <&cru ACLK_VIDEO>, <&cru HCLK_VIDEO>;
> +		clock-names = "aclk", "iface";
>  		#iommu-cells = <0>;
>  		status = "disabled";
>  	};
> @@ -782,6 +790,8 @@
>  		interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>,
>  			     <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
>  		interrupt-names = "vepu_mmu", "vdpu_mmu";
> +		clocks = <&cru ACLK_VIDEO>, <&cru HCLK_VIDEO>;
> +		clock-names = "aclk", "iface";
>  		#iommu-cells = <0>;
>  		status = "disabled";
>  	};
> diff --git a/arch/arm64/boot/dts/rockchip/rk3399.dtsi b/arch/arm64/boot/dts/rockchip/rk3399.dtsi
> index 4550c0f82be9..56f6bb31b399 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3399.dtsi
> +++ b/arch/arm64/boot/dts/rockchip/rk3399.dtsi
> @@ -1234,6 +1234,8 @@
>  		reg = <0x0 0xff650800 0x0 0x40>;
>  		interrupts = <GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH 0>;
>  		interrupt-names = "vpu_mmu";
> +		clocks = <&cru ACLK_VCODEC>, <&cru HCLK_VCODEC>;
> +		clock-names = "aclk", "iface";
>  		#iommu-cells = <0>;
>  		status = "disabled";
>  	};
> @@ -1243,6 +1245,8 @@
>  		reg = <0x0 0xff660480 0x0 0x40>, <0x0 0xff6604c0 0x0 0x40>;
>  		interrupts = <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH 0>;
>  		interrupt-names = "vdec_mmu";
> +		clocks = <&cru ACLK_VDU>, <&cru HCLK_VDU>;
> +		clock-names = "aclk", "iface";
>  		#iommu-cells = <0>;
>  		status = "disabled";
>  	};
> @@ -1252,6 +1256,8 @@
>  		reg = <0x0 0xff670800 0x0 0x40>;
>  		interrupts = <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH 0>;
>  		interrupt-names = "iep_mmu";
> +		clocks = <&cru ACLK_IEP>, <&cru HCLK_IEP>;
> +		clock-names = "aclk", "iface";
>  		#iommu-cells = <0>;
>  		status = "disabled";
>  	};
> @@ -1599,7 +1605,7 @@
>  		interrupts = <GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH 0>;
>  		interrupt-names = "vopl_mmu";
>  		clocks = <&cru ACLK_VOP1>, <&cru HCLK_VOP1>;
> -		clock-names = "aclk", "hclk";
> +		clock-names = "aclk", "iface";
>  		power-domains = <&power RK3399_PD_VOPL>;
>  		#iommu-cells = <0>;
>  		status = "disabled";
> @@ -1656,7 +1662,7 @@
>  		interrupts = <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH 0>;
>  		interrupt-names = "vopb_mmu";
>  		clocks = <&cru ACLK_VOP0>, <&cru HCLK_VOP0>;
> -		clock-names = "aclk", "hclk";
> +		clock-names = "aclk", "iface";
>  		power-domains = <&power RK3399_PD_VOPB>;
>  		#iommu-cells = <0>;
>  		status = "disabled";
> @@ -1667,6 +1673,8 @@
>  		reg = <0x0 0xff914000 0x0 0x100>, <0x0 0xff915000 0x0 0x100>;
>  		interrupts = <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH 0>;
>  		interrupt-names = "isp0_mmu";
> +		clocks = <&cru ACLK_ISP0_NOC>, <&cru HCLK_ISP0_NOC>;
> +		clock-names = "aclk", "iface";
>  		#iommu-cells = <0>;
>  		rockchip,disable-mmu-reset;
>  		status = "disabled";
> @@ -1677,6 +1685,8 @@
>  		reg = <0x0 0xff924000 0x0 0x100>, <0x0 0xff925000 0x0 0x100>;
>  		interrupts = <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH 0>;
>  		interrupt-names = "isp1_mmu";
> +		clocks = <&cru ACLK_ISP1_NOC>, <&cru HCLK_ISP1_NOC>;
> +		clock-names = "aclk", "iface";
>  		#iommu-cells = <0>;
>  		rockchip,disable-mmu-reset;
>  		status = "disabled";
> 

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

end of thread, other threads:[~2018-04-10 11:46 UTC | newest]

Thread overview: 27+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-03-23  7:38 [PATCH v8 00/14] iommu/rockchip: Use OF_IOMMU Jeffy Chen
2018-03-23  7:38 ` [PATCH v8 01/14] iommu/rockchip: Prohibit unbind and remove Jeffy Chen
2018-03-23  7:38 ` [PATCH v8 02/14] iommu/rockchip: Fix error handling in probe Jeffy Chen
2018-03-23  7:38 ` [PATCH v8 03/14] iommu/rockchip: Request irqs in rk_iommu_probe() Jeffy Chen
2018-03-23  7:38 ` [PATCH v8 04/14] iommu/rockchip: Fix error handling in attach Jeffy Chen
2018-03-23  7:38 ` [PATCH v8 05/14] iommu/rockchip: Use iopoll helpers to wait for hardware Jeffy Chen
2018-03-23  7:38 ` [PATCH v8 06/14] iommu/rockchip: Fix TLB flush of secondary IOMMUs Jeffy Chen
2018-03-23  7:38 ` [PATCH v8 07/14] ARM: dts: rockchip: add clocks in iommu nodes Jeffy Chen
2018-04-09 14:41   ` Tomeu Vizoso
2018-04-09 15:44     ` Heiko Stübner
2018-04-09 15:53       ` Robin Murphy
2018-04-09 15:55         ` Heiko Stübner
2018-04-09 21:49           ` Heiko Stübner
2018-04-10 10:54             ` Heiko Stuebner
2018-04-10 11:46   ` Heiko Stuebner
2018-03-23  7:38 ` [PATCH v8 08/14] iommu/rockchip: Control clocks needed to access the IOMMU Jeffy Chen
2018-03-23  7:38 ` [PATCH v8 09/14] dt-bindings: iommu/rockchip: Add clock property Jeffy Chen
2018-03-25 23:52   ` Rob Herring
2018-03-23  7:38 ` [PATCH v8 10/14] iommu/rockchip: Use IOMMU device for dma mapping operations Jeffy Chen
2018-03-23  7:38 ` [PATCH v8 11/14] iommu/rockchip: Use OF_IOMMU to attach devices automatically Jeffy Chen
2018-03-26  6:31   ` Daniel Kurtz
     [not found]     ` <5AB8A7F0.1090305@rock-chips.com>
2018-04-03 16:11       ` Daniel Kurtz
2018-04-04 11:10         ` JeffyChen
2018-03-23  7:38 ` [PATCH v8 12/14] iommu/rockchip: Fix error handling in init Jeffy Chen
2018-03-23  7:38 ` [PATCH v8 13/14] iommu/rockchip: Add runtime PM support Jeffy Chen
2018-03-23  7:38 ` [PATCH v8 14/14] iommu/rockchip: Support sharing IOMMU between masters Jeffy Chen
2018-03-29 10:24 ` [PATCH v8 00/14] iommu/rockchip: Use OF_IOMMU Joerg Roedel

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).