diff mbox

[RFC,PATCHv3+,1/2] driver/core: Add of_iommu_attach()

Message ID 20131106160623.2cb72f91cd071e555d0d4b9a@nvidia.com
State Not Applicable, archived
Headers show

Commit Message

Hiroshi Doyu Nov. 6, 2013, 2:06 p.m. UTC
Hi,

Experimentally I have implemented "of_iommu_attach()" called from
drvier/core to control the order of device instanciation.

In the Tegra SMMU PATCHv3, we've discussed how to control the order of
device instanciation. Thierry/Stephen proposed to insert a hook in
driver/core to control this order, depending on whether an iommu
device is ready or not."of_iommu_attach()" is implement for that
purpose now. Along with this patch, I attached DT part of modication
to this mail. I used the same iommu bindings which arm,smmu uses.

[RFC][PATCHv3+ 2/2] ARM: DT: tegra30: iommu: Add "stream-id-cells"/"mmu-masters"

"#stream-id-cells" is used to identify whether a device is IOMMU'able
or not. If a device is IOMMU'able, we'll defer to instanciate that
device till an iommu device is instanciated/ready. Once an iommu device
is instanciated, "dev->bus->iommu_ops" is set in the bus. After an
iommu device is instanciated, those defered devices are instanciated
as IOMMU'able with help of the iommu driver via iommu_ops->add_device().

We don't call bus_set_iommu() until an iommu device is instanciated
because we need to support 2 kind of IOMMU drivers, SMMU and GART so
that this bus_set_iommu() needs to be defered till an iommu device is
instanciated. So the single image can support 2 iommu drivers at once.

With this patch, the following HACK patches in v3[1] are not needed
anymore.

  patch 1: [HACK] of: dev_node has struct device pointer
  patch 2: [HACK] ARM: tegra: Populate AHB/IOMMU earlier than others
  patch 3: [HACK] amba: Move AHB to core_initcall
  patch 4: [HACK] iommu/tegra: smmu: Move IOMMU to core_initcall

Any comment would be really appreciated.

[1] Original v3:
http://lists.linuxfoundation.org/pipermail/iommu/2013-October/006724.html

[2]
http://lists.linuxfoundation.org/pipermail/iommu/2013-November/006864.html

Signed-off-by: Hiroshi Doyu <hdoyu@nvidia.com>
---
 drivers/base/dd.c        |  5 +++++
 drivers/iommu/of_iommu.c | 34 ++++++++++++++++++++++++++++++++++
 include/linux/iommu.h    |  7 +++++++
 3 files changed, 46 insertions(+)

Comments

Hiroshi Doyu Nov. 8, 2013, 1:14 p.m. UTC | #1
Hi Stephen,

Hiroshi Doyu <hdoyu@nvidia.com> wrote @ Wed, 6 Nov 2013 15:06:23 +0100:

> Experimentally I have implemented "of_iommu_attach()" called from
> drvier/core to control the order of device instanciation.
> 
> In the Tegra SMMU PATCHv3, we've discussed how to control the order of
> device instanciation. Thierry/Stephen proposed to insert a hook in
> driver/core to control this order, depending on whether an iommu
> device is ready or not."of_iommu_attach()" is implement for that
> purpose now. Along with this patch, I attached DT part of modication
> to this mail. I used the same iommu bindings which arm,smmu uses.
> 
> [RFC][PATCHv3+ 2/2] ARM: DT: tegra30: iommu: Add "stream-id-cells"/"mmu-masters"
> 
> "#stream-id-cells" is used to identify whether a device is IOMMU'able
> or not. If a device is IOMMU'able, we'll defer to instanciate that
> device till an iommu device is instanciated/ready. Once an iommu device
> is instanciated, "dev->bus->iommu_ops" is set in the bus. After an
> iommu device is instanciated, those defered devices are instanciated
> as IOMMU'able with help of the iommu driver via iommu_ops->add_device().
> 
> We don't call bus_set_iommu() until an iommu device is instanciated
> because we need to support 2 kind of IOMMU drivers, SMMU and GART so
> that this bus_set_iommu() needs to be defered till an iommu device is
> instanciated. So the single image can support 2 iommu drivers at once.
> 
> With this patch, the following HACK patches in v3[1] are not needed
> anymore.
> 
>   patch 1: [HACK] of: dev_node has struct device pointer
>   patch 2: [HACK] ARM: tegra: Populate AHB/IOMMU earlier than others
>   patch 3: [HACK] amba: Move AHB to core_initcall
>   patch 4: [HACK] iommu/tegra: smmu: Move IOMMU to core_initcall
> 
> Any comment would be really appreciated.

Have you had any chance to take a look at this one?

I plan to send version 4 of this series with the above design next
week. In v4, I use "mmu-masters" binding stolen from "arm,smmu" DT.
--
To unsubscribe from this list: send the line "unsubscribe linux-tegra" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

From fa49c864c1b05df6de16cfc2d12f74fcae843e55 Mon Sep 17 00:00:00 2001
From: Hiroshi Doyu <hdoyu@nvidia.com>
Date: Wed, 6 Nov 2013 15:27:03 +0200
Subject: [RFC][PATCHv3+ 2/2] ARM: DT: tegra30: iommu: Add
 "stream-id-cells"/"mmu-masters"

Follow the same syntax as arm,smmu.

FIXME: "nvidia,memory-clients" should be removed.

Signed-off-by: Hiroshi Doyu <hdoyu@nvidia.com>
---
 arch/arm/boot/dts/tegra30.dtsi | 63 +++++++++++++++++++++++++++++++++---------
 1 file changed, 50 insertions(+), 13 deletions(-)

diff --git a/arch/arm/boot/dts/tegra30.dtsi b/arch/arm/boot/dts/tegra30.dtsi
index 4c7f296..5913ec9 100644
--- a/arch/arm/boot/dts/tegra30.dtsi
+++ b/arch/arm/boot/dts/tegra30.dtsi
@@ -87,60 +87,66 @@ 
 		};
 	};
 
-	host1x {
+	host1x: host1x {
 		compatible = "nvidia,tegra30-host1x", "simple-bus";
 		reg = <0x50000000 0x00024000>;
 		interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>, /* syncpt */
 			     <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>; /* general */
 		clocks = <&tegra_car TEGRA30_CLK_HOST1X>;
 		nvidia,memory-clients = <&smmu TEGRA_SWGROUP_HC>;
+		#stream-id-cells = <1>;
 
 		#address-cells = <1>;
 		#size-cells = <1>;
 
 		ranges = <0x54000000 0x54000000 0x04000000>;
 
-		mpe {
+		mpe: mpe {
 			compatible = "nvidia,tegra30-mpe";
 			reg = <0x54040000 0x00040000>;
 			interrupts = <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>;
 			clocks = <&tegra_car TEGRA30_CLK_MPE>;
 			nvidia,memory-clients = <&smmu TEGRA_SWGROUP_MPE>;
+			#stream-id-cells = <1>;
 		};
 
-		vi {
+		vi: vi {
 			compatible = "nvidia,tegra30-vi";
 			reg = <0x54080000 0x00040000>;
 			interrupts = <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>;
 			clocks = <&tegra_car TEGRA30_CLK_VI>;
 			nvidia,memory-clients = <&smmu TEGRA_SWGROUP_VI>;
+			#stream-id-cells = <1>;
 		};
 
-		epp {
+		epp: epp {
 			compatible = "nvidia,tegra30-epp";
 			reg = <0x540c0000 0x00040000>;
 			interrupts = <GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>;
 			clocks = <&tegra_car TEGRA30_CLK_EPP>;
 			nvidia,memory-clients = <&smmu TEGRA_SWGROUP_EPP>;
+			#stream-id-cells = <1>;
 		};
 
-		isp {
+		isp: isp {
 			compatible = "nvidia,tegra30-isp";
 			reg = <0x54100000 0x00040000>;
 			interrupts = <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>;
 			clocks = <&tegra_car TEGRA30_CLK_ISP>;
 			nvidia,memory-clients = <&smmu TEGRA_SWGROUP_ISP>;
+			#stream-id-cells = <1>;
 		};
 
-		gr2d {
+		gr2d: gr2d {
 			compatible = "nvidia,tegra30-gr2d";
 			reg = <0x54140000 0x00040000>;
 			interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>;
 			clocks = <&tegra_car TEGRA30_CLK_GR2D>;
 			nvidia,memory-clients = <&smmu TEGRA_SWGROUP_G2>;
+			#stream-id-cells = <1>;
 		};
 
-		gr3d {
+		gr3d: gr3d {
 			compatible = "nvidia,tegra30-gr3d";
 			reg = <0x54180000 0x00040000>;
 			clocks = <&tegra_car TEGRA30_CLK_GR3D
@@ -148,9 +154,10 @@ 
 			clock-names = "3d", "3d2";
 			nvidia,memory-clients = <&smmu TEGRA_SWGROUP_NV
 						TEGRA_SWGROUP_NV2>;
+			#stream-id-cells = <2>;
 		};
 
-		dc@54200000 {
+		dc: dc@54200000 {
 			compatible = "nvidia,tegra30-dc", "nvidia,tegra20-dc";
 			reg = <0x54200000 0x00040000>;
 			interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
@@ -158,13 +165,14 @@ 
 				 <&tegra_car TEGRA30_CLK_PLL_P>;
 			clock-names = "disp1", "parent";
 			nvidia,memory-clients = <&smmu TEGRA_SWGROUP_DC>;
+			#stream-id-cells = <1>;
 
 			rgb {
 				status = "disabled";
 			};
 		};
 
-		dc@54240000 {
+		dcb: dc@54240000 {
 			compatible = "nvidia,tegra30-dc";
 			reg = <0x54240000 0x00040000>;
 			interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>;
@@ -172,6 +180,7 @@ 
 				 <&tegra_car TEGRA30_CLK_PLL_P>;
 			clock-names = "disp2", "parent";
 			nvidia,memory-clients = <&smmu TEGRA_SWGROUP_DCB>;
+			#stream-id-cells = <1>;
 
 			rgb {
 				status = "disabled";
@@ -329,6 +338,7 @@ 
 		nvidia,dma-request-selector = <&apbdma 8>;
 		clocks = <&tegra_car TEGRA30_CLK_UARTA>;
 		nvidia,memory-clients = <&smmu TEGRA_SWGROUP_PPCS>;
+		#stream-id-cells = <1>;
 		status = "disabled";
 	};
 
@@ -340,6 +350,7 @@ 
 		nvidia,dma-request-selector = <&apbdma 9>;
 		clocks = <&tegra_car TEGRA30_CLK_UARTB>;
 		nvidia,memory-clients = <&smmu TEGRA_SWGROUP_PPCS>;
+		#stream-id-cells = <1>;
 		status = "disabled";
 	};
 
@@ -351,6 +362,7 @@ 
 		nvidia,dma-request-selector = <&apbdma 10>;
 		clocks = <&tegra_car TEGRA30_CLK_UARTC>;
 		nvidia,memory-clients = <&smmu TEGRA_SWGROUP_PPCS>;
+		#stream-id-cells = <1>;
 		status = "disabled";
 	};
 
@@ -362,6 +374,7 @@ 
 		nvidia,dma-request-selector = <&apbdma 19>;
 		clocks = <&tegra_car TEGRA30_CLK_UARTD>;
 		nvidia,memory-clients = <&smmu TEGRA_SWGROUP_PPCS>;
+		#stream-id-cells = <1>;
 		status = "disabled";
 	};
 
@@ -373,6 +386,7 @@ 
 		nvidia,dma-request-selector = <&apbdma 20>;
 		clocks = <&tegra_car TEGRA30_CLK_UARTE>;
 		nvidia,memory-clients = <&smmu TEGRA_SWGROUP_PPCS>;
+		#stream-id-cells = <1>;
 		status = "disabled";
 	};
 
@@ -550,6 +564,25 @@ 
 		dma-window = <0 0x40000000>;	/* IOVA start & length */
 		nvidia,swgroups = <0x00000000 0x000779ff>;
 		nvidia,ahb = <&ahb>;
+
+		mmu-masters = <&host1x TEGRA_SWGROUP_HC>,
+			      <&mpe TEGRA_SWGROUP_MPE>,
+			      <&vi TEGRA_SWGROUP_VI>,
+			      <&epp TEGRA_SWGROUP_EPP>,
+			      <&isp TEGRA_SWGROUP_ISP>,
+			      <&gr2d TEGRA_SWGROUP_G2>,
+			      <&gr3d TEGRA_SWGROUP_NV TEGRA_SWGROUP_NV2>,
+			      <&dc TEGRA_SWGROUP_DC>,
+			      <&dcb TEGRA_SWGROUP_DCB>,
+			      <&uarta TEGRA_SWGROUP_PPCS>,
+			      <&uartb TEGRA_SWGROUP_PPCS>,
+			      <&uartc TEGRA_SWGROUP_PPCS>,
+			      <&uartd TEGRA_SWGROUP_PPCS>,
+			      <&uarte TEGRA_SWGROUP_PPCS>,
+			      <&sdhci0 TEGRA_SWGROUP_PPCS>,
+			      <&sdhci1 TEGRA_SWGROUP_PPCS>,
+			      <&sdhci2 TEGRA_SWGROUP_PPCS>,
+			      <&sdhci3 TEGRA_SWGROUP_PPCS>;
 	};
 
 	ahub {
@@ -617,39 +650,43 @@ 
 		};
 	};
 
-	sdhci@78000000 {
+	sdhci0: sdhci@78000000 {
 		compatible = "nvidia,tegra30-sdhci", "nvidia,tegra20-sdhci";
 		reg = <0x78000000 0x200>;
 		interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&tegra_car TEGRA30_CLK_SDMMC1>;
 		nvidia,memory-clients = <&smmu TEGRA_SWGROUP_PPCS>;
+		#stream-id-cells = <1>;
 		status = "disabled";
 	};
 
-	sdhci@78000200 {
+	sdhci1: sdhci@78000200 {
 		compatible = "nvidia,tegra30-sdhci", "nvidia,tegra20-sdhci";
 		reg = <0x78000200 0x200>;
 		interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&tegra_car TEGRA30_CLK_SDMMC2>;
 		nvidia,memory-clients = <&smmu TEGRA_SWGROUP_PPCS>;
+		#stream-id-cells = <1>;
 		status = "disabled";
 	};
 
-	sdhci@78000400 {
+	sdhci2: sdhci@78000400 {
 		compatible = "nvidia,tegra30-sdhci", "nvidia,tegra20-sdhci";
 		reg = <0x78000400 0x200>;
 		interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&tegra_car TEGRA30_CLK_SDMMC3>;
 		nvidia,memory-clients = <&smmu TEGRA_SWGROUP_PPCS>;
+		#stream-id-cells = <1>;
 		status = "disabled";
 	};
 
-	sdhci@78000600 {
+	sdhci3: sdhci@78000600 {
 		compatible = "nvidia,tegra30-sdhci", "nvidia,tegra20-sdhci";
 		reg = <0x78000600 0x200>;
 		interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&tegra_car TEGRA30_CLK_SDMMC4>;
 		nvidia,memory-clients = <&smmu TEGRA_SWGROUP_PPCS>;
+		#stream-id-cells = <1>;
 		status = "disabled";
 	};
 
-- 
1.8.1.5